Virenerus' T³ - Update 6: Own Website & 0.3.0

Progress reports and musings from the developers on the current gaming tools.

Moderators: dorpond, trevor, Azhrei

Virenerus
Cave Troll
Posts: 36
Joined: Fri Jan 17, 2014 9:13 pm

Virenerus' T³ - Update 6: Own Website & 0.3.0

Post by Virenerus »

Hey,
a dicussion in another thread inspired me to writing status reports here about the work on my MapTools version.
Me:
I am a 22 years old Computer Science student from Germany. My passions are RPGs. I play mostly Pathfinder and GURPS, but also did smaller campaigns in many other systems.

T³ - Tabletop Tool:
As there is no built atm I will post here what I did and will do. I hope to create a new base for MapTool. A system from which an open source group could develop the next MapTool. Because of that my big picture goals are to overhaul the scripting system and make MapTool a plug-in based software.

I am currently not thinking about backwards compatibility. The backwardscompatibility part of maptools also needs to be overhauled. So atm every release here is probably not compatible with 1.3 or everything else relesed here.

So lets get to the goodies^^
What I do right now:
I am currently totally removing the old macro system and replacing it with Groovy. Groovy is a cool language very similar to Java or Javascript. It is fast and easily works with java. Most javascript or java code will also be viable code in Groovy.

I am currently overhauling the old macro functions into a Java API that is then used by the Groovy scripts. The API itself is object oriented. That means that you no longer have to juggle with token ids and map names. The new API lets you directly access objects that represent a token or a map (TokenView & MapView respectively).


This project moved to its own website. We would be honored if you join us there.
Website: http://tabletoptool.com
Last edited by Virenerus on Wed Apr 09, 2014 5:07 am, edited 21 times in total.

User avatar
CoveredInFish
Demigod
Posts: 3104
Joined: Mon Jun 29, 2009 10:37 am
Location: Germany
Contact:

Re: Virenerus' MapTools

Post by CoveredInFish »

Looks great and promising. Will keep an eye on this.

I think it would be better if you use a different name than MT2 since this might cause confusion with the official MapTool 2.0 (thats somewhat in development).

badsequel
Giant
Posts: 115
Joined: Thu May 31, 2012 3:13 am

Re: Virenerus' MapTools

Post by badsequel »

Cool! I have to check this out!

If only official MT could get this kind of love.. :(
My shared rpg stuff:
(exe)TokenNameChanger3: https://www.dropbox.com/s/cqsof54v3dl2k ... 3.zip?dl=0
Tiddly Spell Wiki: https://www.dropbox.com/s/53pya4k68mnvc ... ddly01.htm

Stuff to check out:
Mote Kickstarter(back it): https://www.kickstarter.com/projects/74 ... abletop-ev

Virenerus
Cave Troll
Posts: 36
Joined: Fri Jan 17, 2014 9:13 pm

Re: Virenerus' MapTools

Post by Virenerus »

CoveredInFish wrote:Looks great and promising. Will keep an eye on this.

I think it would be better if you use a different name than MT2 since this might cause confusion with the official MapTool 2.0 (thats somewhat in development).
Good Point. What would be a appropriat name? I want something short to keep the coding easy. I will probably change it so that you don't need the MT2.XXXXX in the scripts anymore. But I would still need a good name for package names and everything else.
Next Map Tool?

User avatar
aliasmask
RPTools Team
Posts: 9024
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Virenerus' MapTools

Post by aliasmask »

Virenerus wrote:
CoveredInFish wrote:Looks great and promising. Will keep an eye on this.

I think it would be better if you use a different name than MT2 since this might cause confusion with the official MapTool 2.0 (thats somewhat in development).
Good Point. What would be a appropriat name? I want something short to keep the coding easy. I will probably change it so that you don't need the MT2.XXXXX in the scripts anymore. But I would still need a good name for package names and everything else.
Next Map Tool?
I would go vain. MTV.

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: Virenerus' MapTools

Post by JamzTheMan »

Cool, looks good.

Question, will "non-programmers" be able to pick up Groovy ok? And what are your plans for "Vision" overhaul, if any?

And I would probably just completely rename your project away from Map Tool (ie take Map Tool out of the name). Lets face it, with a new macro language and no backwards compatibility, I'd hate to see people confusedly wonder what your project and MT 1.x have in common. You will need new frameworks, etc. Lets face it, with the scope of change, you really will need your own website/forums to track/support new frameworks/macros/etc.
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Virenerus' MapTools

Post by wolph42 »

JamzTheMan wrote:Cool, looks good.


And I would probably just completely rename your project away from Map Tool (ie take Map Tool out of the name). Lets face it, with a new macro language and no backwards compatibility, I'd hate to see people confusedly wonder what your project and MT 1.x have in common. You will need new frameworks, etc. Lets face it, with the scope of change, you really will need your own website/forums to track/support new frameworks/macros/etc.
TPFNAMT :mrgreen:

Petty you're loosing the old script. That's a not going there for me. But cool that you're picking this up.

Germany eh :) we're neighbours!

Lee
Dragon
Posts: 958
Joined: Wed Oct 19, 2011 2:07 am

Re: Virenerus' MapTools

Post by Lee »

To answer your first question, put it in a spoiler tag.

The only thing I would suggest is to at least try to reach out the 3 RPTools' devs, even if it's to say you'll be using the MapTool name, and what your (design) plans are for your fork. Several super-users have made this suggestion, and even I said the same thing. You don't need permission to do this, of course, it just seems the right thing to do. I'm pretty sure you haven't spoke with any of them yet, did you?

It was evident, at least to me, from the start that this is something you wanted to head yourself, and honestly, it IS the only way to get things done. But I have huge respect for Azhrei, Craig, and JFJ. If they sacrificed enough time to do so and bring their A-game, they'd probably blow every other VTT out there. The sanest parts of the MT source are of their contributions, I don't believe MT'd be this easy to fork if it weren't so. It's just customary, every dev that passed through here nodded their heads in their direction, before starting on anything.

Playing the devil's advocate, I do have to ask: Why didn't you just start out with the plugin architecture instead of working with the 1.3 source code? If it's ever finished before RPTools' makes one, don't you think that it would make the greatest impact of all, on both the official 1.3 and 2.0 projects? I did look at the branch on your git repo, so I do have a basis for the question.

(Still the DA) To be honest, unless you do a real refactor, keeping the macro function names (with or without the enclosing brackets) and their forms while making it all run on Groovy, asking the niche community to make the switch, will likely meet the same resistance as JS has met when it was brought up. Again,you might end up with a great tool with no one to use it. If writing script were easy, regardless of what forms the functions in an API look like, there'd be a LOT of macro scripters. But this isn't the case. If it didn't happen to MT macro script, how better would your Groovy-based API fare, even if it's all very nice under the hood?

The greatest thing about what you're doing, however, is bringing much needed energy to the community. Kudos man!

I wish the best of luck with your efforts. Let's make this (MT as #1) happen.

Virenerus
Cave Troll
Posts: 36
Joined: Fri Jan 17, 2014 9:13 pm

Re: Virenerus' MapTools

Post by Virenerus »

Okay, I finishing rewriting the api as a collection of methods. Now nearly all the old macro functions should work from within Groovy. Now to the next step!

Concerning a name, you are probably right about giving it a name not containing Maptool. But I probably won't make any final decisions until I have something you can actually use.
JamzTheMan wrote: Question, will "non-programmers" be able to pick up Groovy ok?
I think they will. Of course they have to learn it a bit, but I think with some examples it won't be harder than the old macro language. In the contrary for me a clean language is a lot easier than the old mix of macro and function calls. And if there are any problems I will be happy to help with everything^^
JamzTheMan wrote: And what are your plans for "Vision" overhaul, if any?
At the moment there are no plans. I want to do one feature/overhaul at a time and then a release. I am starting with the macro system. The next big step will probably be a modularization. After that we see. I will probably just discuss with you what needs some love next. But the general idea is not to do everything at once and certainly not to make a thousand year plan. That never works out.
wolph42 wrote: Petty you're loosing the old script. That's a not going there for me.
I gave this a lot of thought in the past week. I definately won't be able to maintain the old macro language through everything I am doing. But maybe I could create a little tool that will help you translate your old macros into groovy? WOuld that help? It would be far from perfect, as writing a real source2source compiler is very hard. But it could at least be a starting point with which it would be a lot faster/easier to translate your macros to groovy. What do you think?
Lee wrote: Why didn't you just start out with the plugin architecture instead of working with the 1.3 source code?
That easy to answer. Because to modularize the code you have to know it very very good. I wanted to do some other stuff first to get to know the inner workings of MT.

Lee wrote: The only thing I would suggest is to at least try to reach out the 3 RPTools' devs
You are right. I do that right now



Otherwise thanks for the support guys^^

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Virenerus' MapTools

Post by wolph42 »

I gave this a lot of thought in the past week. I definately won't be able to maintain the old macro language through everything I am doing. But maybe I could create a little tool that will help you translate your old macros into groovy? WOuld that help? It would be far from perfect, as writing a real source2source compiler is very hard. But it could at least be a starting point with which it would be a lot faster/easier to translate your macros to groovy. What do you think?
I can imagine that a s2s compiler is insanely difficult to build especially with such a messy script as with maptool.

The core dev have mentioned this as well (as a potential solution). What I fear will be the biggest issue is the fact that I've been scripting in MT for 4 years now and apart from the 80k lines of code, I've rewritten most of it to optimize it. The latter means that I've been using increasingly more complex methods to get things done. That means some dirty tricks, nested functions etc. But also quite a bit of use of the Wiki: set(), wfunc]eval[/wfunc] and Wiki: evalMacro() functions.

E.g. large repeating slaps of code I've created large loops that build the code from scratch and then execute them using the above functions.

In other words, for such a tool to be of at least some worth to me, means that it already will require to be quite a bit more complex.

Virenerus
Cave Troll
Posts: 36
Joined: Fri Jan 17, 2014 9:13 pm

Re: Virenerus' MapTools - Update 3: Typed Properties

Post by Virenerus »

:cry: This makes it really hard. More or less impossible. Sorry. I would have loved to help you.

On a brighter side I have a new update. WHile refactoring the API I finished making Token Properties typed. This allows for a clearer use and hopefully cool custom property type addons in the future. ATM there are four types. Text, Integer and Float more or less as normal. New is the Capped Propertytype. This one allows you to write a current, maximum und minimum value into one property. I attached some screenshot of how this looks. I really like this feature because it will enable a lot easier use in the future. Bars could be directly linked to capped properties without needing any macros. There could be a property type that allows the GM to define a certain format that can be filled by the players. hat would make campaign specific weapon properties a lot easier to use than using json strings.

What do you think of it?
Next up is finishing the API and implementing scripts calling other scripts to get a alpha on the way.
Attachments
The new property manager with typed properties.
The new property manager with typed properties.
b.jpg (156.88 KiB) Viewed 8454 times
Editing a capped property
Editing a capped property
a2.jpg (142.96 KiB) Viewed 8454 times
A capped property in the token edit view.
A capped property in the token edit view.
a.jpg (145.84 KiB) Viewed 8454 times

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Virenerus' MapTools - Update 3: Typed Properties

Post by wolph42 »

I guessed so much.
more or less impossible
. Do you mean the compiler or are Wiki: eval ()and Wiki: evalMacro ()in groovy not possible? (or both).

About the cap. Pretty cool and definitely a very useful addition. Do I gather from the screenshot that in your version you need to declare your property types up front (so no typecasting)? Not really an issue with that as it promotes cleaner and more understandable code.

Does however your new property system allow for script (and other types like jons objects/arrays) as well?

to give you an idea what is currently possible:

This is my default property set for a character in my games:
(note that the primary stats are automatically rolled when the token is dragged on the map. The secondary stats are derived/calculated based on the primary stats. So the first part is executed once, while the second are executed on each mouseover.)

Code: Select all

--------------|PRIMARY CHARACTERISTICS|------------
WS:[h:WS=20+2d10]
BS:[h:BS=20+2d10]
S:[h:S=20+2d10]
T:[h:T=20+2d10]
Ag:[h:Ag=20+2d10]
Int:[h:Int=20+2d10]
Per:[h:Per=20+2d10]
WP:[h:WP=20+2d10]
Fel:[h:Fel=20+2d10]
Inf
--------------|SECONDARY CHARACTERISTICS|------------
WSB:{1*floor(WS/10)+0}
BSB:{1*floor(BS/10)+0}
SB:{1*floor(S/10)+0}
TB:{1*floor(T/10)+0}
AB:{1*floor(Ag/10)+0}
IB:{1*floor(Int/10)+0}
PB:{1*floor(Per/10)+0}
WB:{1*floor(Wp/10)+0}
FB:{1*floor(Fel/10)+0}
InfB
--------------|CALCULATED CHARACTERISTICS|------------
W:[h:W=eval("10+1d3")]
SW (Starting Wounds):{SW=W}
M:{1*floor(Ag/10)+0}
Fatigue:{TB}
FatePoints:0
FatePool:0
InfPoints:0
InfPool:0
InsanityPoints:0
CorruptionPoints:0
CB:{1*floor(CorruptionPoints/10)+0}
--------------|OTHER CHARACTERISTICS|------------
Skills:{}
Talents:{}
Traits:{}
Deeds:""
Distinctions:""
PsychicPowers:{}
FaithPowers:{}
PsyRating:0
SpecialProperties:PsyClass=0; Navigator=0; Apotheker=0; SuddenDeath=0
Advancements:{}
States:{}
Recharging:{}
tmpStats:[]
tmpSkillBonus:{}
WoundLevel:Healthy
OnBoard
--------------|EQUIPMENT|------------
Weapons:{"Unarmed":{"Category":"Melee","Group":"Primitive","Class":"Natural","Range":0,"SingleShot":0,"SemiBurst":0,"FullBurst":0,"WpnDamDice":1,"WpnDamDiceType":5,"WpnDamMod":-3,"DamType":"Impact","Penetration":0,"Clip":0,"ClipSize":0,"WpnAttMod":0,"NumClips":0,"ClipType":"-","RldTime":"","numHands":1,"Special":"Primitive, Grapple, Unwieldy","SpecialText":"","Weight":0,"Cost":"-","Availability":"-","Page":197,"Source":"DH-CR"}}
Armour:{}
Gear:{}
CurrentlyEquippedArmour:{}
ArmourWearing
PrimaryWeapon:Unarmed
SecondaryWeapon:Unarmed
MountedWeapon
UnarmedWeapon:Unarmed
ReloadingMountedWeapon
--------------|ARMOUR STATS|------------
HeadAP:0
BodyAP:0
ArmPAP:0
ArmSAP:0
LegPAP:0
LegSAP:0
HeadAType:None
BodyAType:None
ArmPAType:None
ArmSAType:None
LegPAType:None
LegSAType:None
Deflector:{}
Cover:{"Type":0,"Head":0,"ArmP":0,"ArmS":0,"Body":1,"LegP":1,"LegS":1,"AP":0}
--------------|DISPLAY INFO|------------
*@Embarked:{OnBoard}
*@WS|BS:{WS}|{BS} ({WSB}|{BSB})
*@S|T:{S}|{T} ({SB}|{TB})
*@Ag|Int|WP:{Ag}|{Int}|{WP} ({AB}|{IB}|{WB})
*@Per|Fel:{Per}|{Fel} ({PB}|{FB})
*@Infamy
*@W|SW:{W}|{SW}
*@M|Chrg|Run:{M}|{M*3}|{M*6}
*@Fat|SFat:{Fatigue}|{TB}
*@IP|CP|FPool|FPoints
*@CP|IPool|IPoints
*@PR:{PsyRating}
*@AP-H|B|A P-S|L P-S:{HeadAP}|{BodyAP}|{ArmPAP}-{ArmSAP}|{LegPAP}-{LegSAP}
*Wearing:[r, if(length(ArmourWearing) > 30): substring(ArmourWearing, 0, 30) + "..." ; ArmourWearing]
*Hands P|S:[r, if(length(PrimaryWeapon) > 30): substring(PrimaryWeapon, 0, 30) + "..." ; PrimaryWeapon]|[r, if(length(SecondaryWeapon) > 30): substring(SecondaryWeapon, 0, 30) + "..." ; SecondaryWeapon]
*Mount:[r, if(length(MountedWeapon) > 30): substring(MountedWeapon, 0, 30) + "..." ; MountedWeapon]
*Dodge|Parry:[h:dodge = json.get(States, "Dodged")][h:parry=json.get(States, "Parried")][r:if(dodge == "" && parry != "", 0, dodge)][r:if(dodge != "" || parry != "", "|","")][r:if(dodge != "" && parry == "", 0, parry)]
*Condition:[r:getStates("Cover")]
*sheet.distance (Distance):[r: distanceStatSheet(currentToken())]
---------------|CREATE TOKEN MACROS AND SYSTEM|---------------
LastMeleeAttack:wpnUsed={PrimaryWeapon} ; action=Standard ; secondaryUsed=0 ; exoticTrained=0 ; attackRollResult=0 ; targetDefensive=0 ; targetProne=0 ; calledShot=0 ; logis=0 ; sureStrike=0 ; assStrike=0 ; targetSurprised=0 ; stunned=0 ; higherGround=0 ; hatred=0 ; allowRighteousFury=0 ; autoRF=0 ; charge=0 ; weaponTech=0 ; calledShotPenalty=-20 ; jumpCharge=0 ; jumpChargeTxt= ; wpnMounted=0 ; bonusHordeDmgDice=0 ; miscHordeDmg=0 ; miscOneTimeHordeDmg=0 ; addCritDmg=0 ; action=Standard ; aim=0 ; outNumbered=0 ; bonusHordeDmgDice=0 ; miscHordeDmg=0 ; miscOneTimeHordeDmg=0 ; terrain=0 ; visibility=0 ; vehicleLocation=0 ; allowRighteousFury=1 ; penMod=0 ; bonusDoS=0 ; addCritDmg=0 ; miscModDam=0 ; miscMod=0 ; token= ; vehicleToken= ;
LastRangedAttack:action= ; move=0 ; aim=0 ; wpnUsed=Autopistol ; exoticTrained=0 ; attackRollResult=0 ; targetSurprised=0 ; stunned=0 ; targetProne=0 ; shootInMelee=0 ; concealed=0 ; calledShot=0 ; logis=0 ; ricochet=0 ; noCohesion=0 ; allowRighteousFury=0 ; autoRF=0 ; noAmmo=0 ; bcTLOption=-1 ; weaponTech=0 ; calledShotPenalty=-20 ; wpnMounted=0 ; ocMode=0 ; bonusHordeDmgDice=0 ; miscHordeDmg=0 ; miscOneTimeHordeDmg=0 ; addCritDmg=0 ; shell= ; indirect=0 ; action=Standard ; aim=0 ; distance=0 ; visibility=0 ; bonusHordeDmgDice=0 ; miscHordeDmg=0 ; miscOneTimeHordeDmg=0 ; sizeTarget=0 ; vehicleLocation=0 ; allowRighteousFury=1 ; penMod=0 ; bonusDoS=0 ; addCritDmg=0 ; miscModDam=0 ; miscMod=0 ; token= ; vehicleToken= ;
LastAutoAttack:wpnUsed= ; targets= ; whichArm=PrimaryWeapon ;
LastPsychicAttack:selPower= ; numDice=1 ; mods=0 ; extraFocusMod=0 ; extraPowerMod=0 ; extraPPMod=0 ;
LastRange:0
globalPenalty:{}
checkForModifiers:1
evasionAction:0
evasionModifier:0
evasionWpn
modifier:0
manualRolls:0
DHFWVersion
macroFrameCache
macroFrameCache2
quickSheetCache
quickSheet2Cache
quickSheet3Cache
fullSheetCache
initiative:0
favour:Fate
---------------|TEMPLATES|---------------
templates:{}
Overall I have 15 or so property types of which the most mental (this was an experiment to see how far I could stretch maptool and it works surprisingly well), used for space ships:
(The idea behind this one is that ship OWNERS can see the stats of the ship and the status of its components. NON-OWNERS see nothing unless they scan the ship. After the scan they can see none,some or all of the ships components. This is reflected in the mouseover statsheet. Now the tricky part is that the scan is done by other ships. So when a user hovers over an enemy ship he sees what his own ship scanned. Thus the code stores the ship ID's of the ships that successfully scanned it and then checks whether the current user owns one of those ships. If so: show the scanned components by the ship owned by the user.)

Code: Select all

--------------| STATS|------------
ShipClass
Hull
Captain
Explorers
numExplorers:4
-------------------------
Speed:0
Man:0
Detection:0
BSMod:0
--------------------------
numShields:0
tmpShields:{numShields}
Armour:0
HI (Hull Integrity):0
SHI (Starting HI):0
CrewPercentage:100
MoralePercentage:100
Components:{"Bridge":{},"PlasmaDrive":{},"WarpDrive":{},"GellerField":{},"VoidShield":{},"LifeSustainer":{},"CrewQuarters":{},"AugurArray":{},"Cargo":{},"Passenger":{},"Augments":{},"Facilities":{},"Upgrades":{},"Macrobattery":{},"Lance":{},"Launcher":{},"Nova":{}}
Weapons:{}
MountedWeapon:[r:MountedWeapon		= json.fields(Weapons)]
------------------------------
wcProw:0
wcPort:0
wcStarboard:0
wcDorsal:0
wcKeel:0
TR (Turret Rating):0
TotalPower:0
UsedPower:0
TotalSpace:0
UsedSpace:0
CrewRating:0
States:{}
-----------------------------
currentPlayer:{getPlayerName()}
owned:[r:getPlayerOwned(currentPlayer)]
tokenID:{currentToken()}
owner:{isOwner(currentPlayer)}
classHull:{strformat("%{ShipClass} Class %{Hull}")}
--------------|DISPLAY PROPERTIES SELF|------------
*Class Hull:[r,if(owner):classHull]
Used Power:({UsedPower}\{TotalPower})
complicationsList
------
*Speed|Manouvr.|Detection:[r,if(owner):strformat("%{Speed}VU|%{Man}|%{Detection}")]
*Hull Integrity:[r,if(owner):strformat("(%{HI}|%{SHI})")]
*Crew Number|Morale|Rating:[r,if(owner):strformat("(%{CrewPercentage}|%{MoralePercentage}|%{CrewRating})")]
*Wpn Cap. (Prow| Port| Starb.|Dorsal|Keel):[r,if(owner):strformat("%{wcProw}|%{wcPort}|%{wcStarboard}|%{wcDorsal}|%{wcKeel}")]
*Complications:[r,if(owner):complicationsList]
*Turret Rating|Detection:[r,if(owner):strformat("%{TR}|%{Detection}")]
*Void Shields tmp/full | Armour:[r,if(owner):strformat("(%{tmpShields}/%{numShields})|%{Armour}")]
--------------|get status of components|------------
BridgeStatus:[h:TMPJSON			= json.get(Components, "Bridge")]		[h:tmpPropLst = ""][h,foreach(tmpProp, BridgeList):			tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:BridgeStatus			= tmpPropLst]
PlasmaDriveStatus:[h:TMPJSON	= json.get(Components, "PlasmaDrive")]	[h:tmpPropLst = ""][h,foreach(tmpProp, PlasmaDriveList):	tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:PlasmaDriveStatus	= tmpPropLst]
WarpDriveStatus:[h:TMPJSON		= json.get(Components, "WarpDrive")]	[h:tmpPropLst = ""][h,foreach(tmpProp, WarpDriveList):		tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:WarpDriveStatus		= tmpPropLst]
LifeSustainerStatus:[h:TMPJSON	= json.get(Components, "LifeSustainer")][h:tmpPropLst = ""][h,foreach(tmpProp, LifeSustainerList):	tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:LifeSustainerStatus	= tmpPropLst]
CrewQuartersStatus:[h:TMPJSON	= json.get(Components, "CrewQuarters")]	[h:tmpPropLst = ""][h,foreach(tmpProp, CrewQuartersList):	tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:CrewQuartersStatus	= tmpPropLst]
GellerFieldStatus:[h:TMPJSON	= json.get(Components, "GellerField")]	[h:tmpPropLst = ""][h,foreach(tmpProp, GellerFieldList):	tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:GellerFieldStatus	= tmpPropLst]
VoidShieldStatus:[h:TMPJSON		= json.get(Components, "VoidShield")]	[h:tmpPropLst = ""][h,foreach(tmpProp, VoidShieldList):		tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:VoidShieldStatus		= tmpPropLst]
AugurArrayStatus:[h:TMPJSON		= json.get(Components, "AugurArray")]	[h:tmpPropLst = ""][h,foreach(tmpProp, AugurList):			tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:AugurArrayStatus		= tmpPropLst]
MacrobatteryStatus:[h:TMPJSON	= json.get(Components, "Macrobattery")]	[h:tmpPropLst = ""][h,foreach(tmpProp, MacrobatteryList):	tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:MacrobatteryStatus	= tmpPropLst]
LanceStatus:[h:TMPJSON			= json.get(Components, "Lance")]		[h:tmpPropLst = ""][h,foreach(tmpProp, LanceList):			tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:LanceStatus			= tmpPropLst]
LauncherStatus:[h:TMPJSON		= json.get(Components, "Launcher")]		[h:tmpPropLst = ""][h,foreach(tmpProp, LauncherList):		tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:LauncherStatus		= tmpPropLst]
NovaStatus:[h:TMPJSON			= json.get(Components, "Nova")]			[h:tmpPropLst = ""][h,foreach(tmpProp, NovaList):			tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:NovaStatus			= tmpPropLst]
CargoStatus:[h:TMPJSON			= json.get(Components, "Cargo")]		[h:tmpPropLst = ""][h,foreach(tmpProp, CargoList):			tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:CargoStatus			= tmpPropLst]
PassengerStatus:[h:TMPJSON		= json.get(Components, "Passenger")]	[h:tmpPropLst = ""][h,foreach(tmpProp, PassengerList):		tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:PassengerStatus		= tmpPropLst]
AugmentsStatus:[h:TMPJSON		= json.get(Components, "Augments")]		[h:tmpPropLst = ""][h,foreach(tmpProp, AugmentsList):		tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:AugmentsStatus		= tmpPropLst]
FacilitiesStatus:[h:TMPJSON		= json.get(Components, "Facilities")]	[h:tmpPropLst = ""][h,foreach(tmpProp, FacilitiesList):		tmpPropLst = listAppend(tmpPropLst, json.get(TMPJSON, tmpProp))]	[r:FacilitiesStatus		= tmpPropLst]
--------------|show status of components to owner|------------
*-Bridge-:[r,if (owner && BridgeStatus != "intact"):BridgeStatus]
*-PlasmaDrive-:[r,if (owner && PlasmaDriveStatus != "intact"):PlasmaDriveStatus]
*-WarpDrive-:[r,if (owner && WarpDriveStatus != "intact"):WarpDriveStatus]
*-LifeSustainer-:[r,if (owner && LifeSustainerStatus != "intact"):LifeSustainerStatus]
*-CrewQuarters-:[r,if (owner && CrewQuartersStatus != "intact"):CrewQuartersStatus]
*-GellerField-:[r,if (owner && GellerFieldStatus != "intact"):GellerFieldStatus]
*-VoidShield-:[r,if (owner && VoidShieldStatus != "intact"):VoidShieldStatus]
*-AugurArray-:[r,if (owner && AugurArrayStatus != "intact"):AugurArrayStatus]
*-Macrobattery-:[r,if (owner && MacrobatteryStatus != "intact"):MacrobatteryStatus]
*-Lance-:[r,if (owner && LanceStatus != "intact"):LanceStatus]
*-Launcher-:[r,if (owner && LauncherStatus != "intact"):LauncherStatus]
*-Nova-:[r,if (owner && NovaStatus != "intact"):NovaStatus]
*-Cargo-:[r,if (owner && CargoStatus != "intact"):CargoStatus]
*-Passenger-:[r,if (owner && PassengerStatus != "intact"):PassengerStatus]
*-Augments-:[r,if (owner && AugmentsStatus != "intact"):AugmentsStatus]
*-Facilities-:[r,if (owner && FacilitiesStatus != "intact"):FacilitiesStatus]
--------------|DISPLAY PROPERTIES OTHERS|------------
--------------|this creates a list of components per comp. category|------------
PlasmaDriveList:[r:PlasmaDriveList		= json.fields(json.get(Components,"PlasmaDrive"))]
WarpDriveList:[r:WarpDriveList			= json.fields(json.get(Components,"WarpDrive"))]
LifeSustainerList:[r:LifeSustainerList	= json.fields(json.get(Components,"LifeSustainer"))]
CrewQuartersList:[r:CrewQuartersList	= json.fields(json.get(Components,"CrewQuarters"))]
GellerFieldList:[r:GellerFieldList		= json.fields(json.get(Components,"GellerField"))]
VoidShieldList:[r:VoidShieldList		= json.fields(json.get(Components,"VoidShield"))]
CargoList:[r:CargoList					= json.fields(json.get(Components,"Cargo"))]
PassengerList:[r:PassengerList			= json.fields(json.get(Components,"Passenger"))]
---
BridgeList:[r:BridgeList				= json.fields(json.get(Components, "Bridge"))]
PropulsionList:[r:PropulsionList		= listAppend(PlasmaDriveList, WarpDriveList)]
PersonnelList:[r:PersonnelList			= listAppend(LifeSustainerList, CrewQuartersList)]
FieldsList:[r:FieldsList				= listAppend(GellerFieldList, VoidShieldList)]
AugurList:[r:AugurList					= json.fields(json.get(Components, "AugurArray"))]
MacrobatteryList:[r:MacrobatteryList	= json.fields(json.get(Components, "Macrobattery"))]
LanceList:[r:LanceList					= json.fields(json.get(Components, "Lance"))]
LauncherList:[r:LauncherList			= json.fields(json.get(Components, "Launcher"))]
NovaList:[r:NovaList					= json.fields(json.get(Components, "Nova"))]
AugmentsList:[r:AugmentsList			= json.fields(json.get(Components, "Augments"))]
CargoPassList:[r:CargoPassList			= listAppend(CargoList, PassengerList)]
FacilitiesList:[r:FacilitiesList		= json.fields(json.get(Components, "Facilities"))]
-------------|This list is updated with shipIDs that succesfully scanned this ship|----------------------
classDetected:[]
BridgeDetected:[]
PropulsionDetected:[]
PersonnelDetected:[]
FieldsDetected:[]
AugurDetected:[]
MacrobatteryDetected:[]
LanceDetected:[]
LauncherDetected:[]
NovaDetected:[]
AugmentsDetected:[]
CargoDetected:[]
FacilitiesDetected:[]
--------------|This checks whether the current player owns a ship that has succesfully scanned this ship|----------------------
ClassDetectedOwned:{!json.isEmpty(json.intersection(owned,classDetected ))}
BridgeDetectedOwned:{!json.isEmpty(json.intersection(owned,BridgeDetected ))}
PropulsionDetectedOwned:{!json.isEmpty(json.intersection(owned,PropulsionDetected ))}
PersonnelDetectedOwned:{!json.isEmpty(json.intersection(owned,PersonnelDetected ))}
FieldsDetectedOwned:{!json.isEmpty(json.intersection(owned,FieldsDetected ))}
AugurDetectedOwned:{!json.isEmpty(json.intersection(owned,AugurDetected ))}
MacrobatteryDetectedOwned:{!json.isEmpty(json.intersection(owned,MacrobatteryDetected ))}
LanceDetectedOwned:{!json.isEmpty(json.intersection(owned,LanceDetected ))}
LauncherDetectedOwned:{!json.isEmpty(json.intersection(owned,LauncherDetected ))}
NovaDetectedOwned:{!json.isEmpty(json.intersection(owned,NovaDetected ))}
AugmentsDetectedOwned:{!json.isEmpty(json.intersection(owned,AugmentsDetected ))}
CargoDetectedOwned:{!json.isEmpty(json.intersection(owned,CargoDetected ))}
FacilitiesDetectedOwned:{!json.isEmpty(json.intersection(owned,FacilitiesDetected ))}
--------------|show components ONLY to players that own a ship that succesfully scanned this ship AND NOT own this ship|------------
*Class-:[r,if (ClassDetectedOwned && !owner):classHull]
*Bridge-:[r,if (BridgeDetectedOwned && !owner):BridgeList]
*Propulsion-:[r,if (PropulsionDetectedOwned && !owner):PropulsionList]
*Personnel-:[r,if (PersonnelDetectedOwned && !owner):PersonnelList]
*Fields-:[r,if (FieldsDetectedOwned && !owner):FieldsList]
*Augur-:[r,if (AugurDetectedOwned && !owner):AugurList]
*Macrobattery-:[r,if (MacrobatteryDetectedOwned && !owner):MacrobatteryList]
*Lances-:[r,if (LanceDetectedOwned && !owner):LanceList]
*Launcheres-:[r,if (LauncherDetectedOwned && !owner):LauncherList]
*Nova Cannons-:[r,if (NovaDetectedOwned && !owner):NovaList]
*Augments-:[r,if (AugmentsDetectedOwned && !owner):AugmentsList]
*Cargo space-:[r,if (CargoDetectedOwned && !owner):CargoPassList]
*Facilities-:[r,if (FacilitiesDetectedOwned && !owner):FacilitiesList]
*sheet.distance (Distance):[r: distanceStatSheet(currentToken())]
-------------|SYSTEM|-------------
DHFWVersion
checkForModifiers:1
macroFrameCache
attackResolve:{"wpnsUsed":"{}", operator:""}
tmpStats:[]
LastRange:0
-------------|Redundant but needed for initiative check|-------------
Recharging:{}
onBoard

Virenerus
Cave Troll
Posts: 36
Joined: Fri Jan 17, 2014 9:13 pm

Re: Virenerus' MapTools - Update 3: Typed Properties

Post by Virenerus »

I meant writing a compiler for that. If you build macros on the fly or use eval that much, it won't be possible / will be too hard.

Eval and calling other macros will of course be possible. Thats what I am working on next. Then I will also create a property type for macros.

Json properties are atm only usable if you declare them as text and then parse them. But that is ok for the moment, because in the old maptools they were only text the whole time. Every macro function working with json started by parsing the values from a json array for example. That was very slow and so it is already better than in the old version.

I will however create a new property type that allows for direct input of structured data. But for that we need a new Campaignpropertyeditor. This then will allow you to create property lists, trees and maps without writing json thus eleminating the need for json completely.

Ps: very impressive and cool idea with the scanners.

Virenerus
Cave Troll
Posts: 36
Joined: Fri Jan 17, 2014 9:13 pm

Re: Virenerus' MapTools - Update 3: Typed Properties

Post by Virenerus »

Just a little thing: Just benchmarked calling another macro on the same token. It is around 300 times faster with the groovy api than the old scripting language.

old macro:

Code: Select all

[count(1000,""),CODE:
{
[h,MACRO("return5@TOKEN"):0]
}]
finished

Code: Select all

for(int i=0;i<300000;i++)
	token.executeMacro("return5");
print("finished")
The called macro simply returned the number 5.

Virenerus
Cave Troll
Posts: 36
Joined: Fri Jan 17, 2014 9:13 pm

Re: Virenerus' MapTools - Update 4: MacroEditor & calling ma

Post by Virenerus »

Writing more or less on my own here :lol: Hope that is ok with the admins, but this is more of a thread to document my work.

I finished the possibility for macros to call other macros. Also the macro editor really got on my nerve while working, so I replaced it with a real code editor. Looks cool, supports groovy syntax highlighting, autocompletion (later with help text) AND undo/redo.
Attachments
the new macro editor
the new macro editor
macroeditor.jpg (152.68 KiB) Viewed 8420 times

Post Reply

Return to “Developer Notes”