Brainstorm input request: mapping coordinates
Moderators: dorpond, trevor, Azhrei
Forum rules
PLEASE don't post images of your entire desktop, attach entire campaign files when only a single file is needed, or generally act in some other anti-social behavior.
PLEASE don't post images of your entire desktop, attach entire campaign files when only a single file is needed, or generally act in some other anti-social behavior.
Re: Brainstorm input request: mapping coordinates
Despite all the decorating I've been doing this weekend, I have posted the first version I feel is good enough for the public
Re: Brainstorm input request: mapping coordinates
bloody hell, that took me quite a bit longer than expected. I finally can say that I'm done (for now). The editor was still a pain, even though the UI is great (the code behind not so much). And it turned out that there were still many bugs in my roborally version, with double shooting lasers, conveyers pushing bots through a wall etc, pushers not functioning in their active round, etc.
I think I at least now have the obvious ones. After playing with it it actually corresponded as it should. Its got full animation AND an extensive logging feature, so you can read back what happened. The one thing I haven't tested extensively (but did so in the passed) are colliding/pushing bots. Since the code changed A LOT over the last few weeks it might be that that part is not working correctly anymore.
I'm first gonna make a short tutorial tonight and then I'll release it.
And I think you're really gonna like the map editor
here a pre-look: https://www.dropbox.com/s/l0job9xb8wjpi ... ally.cmpgn
I think I at least now have the obvious ones. After playing with it it actually corresponded as it should. Its got full animation AND an extensive logging feature, so you can read back what happened. The one thing I haven't tested extensively (but did so in the passed) are colliding/pushing bots. Since the code changed A LOT over the last few weeks it might be that that part is not working correctly anymore.
I'm first gonna make a short tutorial tonight and then I'll release it.
And I think you're really gonna like the map editor
here a pre-look: https://www.dropbox.com/s/l0job9xb8wjpi ... ally.cmpgn
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
Re: Brainstorm input request: mapping coordinates
I will take a look at that as soon as I can
While playing some games we found another "Edge Case" I hadn't previously considered: What happens when everyone dies before the end of the round?
My code wasn't handling the empty list of Bots very well, and certainly wasn't jumping forward to the start of the next round.
While playing some games we found another "Edge Case" I hadn't previously considered: What happens when everyone dies before the end of the round?
My code wasn't handling the empty list of Bots very well, and certainly wasn't jumping forward to the start of the next round.
Re: Brainstorm input request: mapping coordinates
They end up on the last checkpoint they've set foot on. My code should not have a problem with thatJagged wrote:I will take a look at that as soon as I can
While playing some games we found another "Edge Case" I hadn't previously considered: What happens when everyone dies before the end of the round?
My code wasn't handling the empty list of Bots very well, and certainly wasn't jumping forward to the start of the next round.
O and I created a tutorial vid
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
Re: Brainstorm input request: mapping coordinates
That wasn't the bit where I had the problem. The problem I had was that everyone died on card 2 and my code still wanted to run through cards 3,4 & 5wolph42 wrote: They end up on the last checkpoint they've set foot on.
Re: Brainstorm input request: mapping coordinates
yup as I said, no trouble there. As soon as a bot is destroyed the 'isDead' is flagged and the rest of the cards are negated.
Here's the Robo rally tutorial:
Tutorial Map Editor - Quickly create a map filled with different tokens.
(its also a tutorial for a general map editor, hence the titel)
couple of bugs left to fix before release.
Here's the Robo rally tutorial:
Tutorial Map Editor - Quickly create a map filled with different tokens.
(its also a tutorial for a general map editor, hence the titel)
couple of bugs left to fix before release.
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
Re: Brainstorm input request: mapping coordinates
and here's finally my release: http://forums.rptools.net/viewtopic.php ... 38#p253538
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
Re: Brainstorm input request: mapping coordinates
So currently working on the other tiles from the expansion. Those are easy enough to do as everything is there (save one which I decided not to do: randomizer)
I did run into some questions once more though: pushing into:
-Water: the first move 'when in water' (so not when moving into) is negated, but what if you're pushed??
--> so moving from F(loor) --> W(ater): takes one move
--> moving W-->W takes 2-move and
--> moving W-->W-->W takes 3-move
hence a 1-move while in water is negated.
Now we have bot A (on Floor) pushing bot B (in water) with a 1-move. Does bot B move or not?
Dito Oil slick. When your drive over oil nothing happens, HOWEVER if you stop on oil, you continue until you hit either an obstacle (wall or bot) or none-oil floor. But what happens when you are pushed onto the oil?
I did run into some questions once more though: pushing into:
-Water: the first move 'when in water' (so not when moving into) is negated, but what if you're pushed??
--> so moving from F(loor) --> W(ater): takes one move
--> moving W-->W takes 2-move and
--> moving W-->W-->W takes 3-move
hence a 1-move while in water is negated.
Now we have bot A (on Floor) pushing bot B (in water) with a 1-move. Does bot B move or not?
Dito Oil slick. When your drive over oil nothing happens, HOWEVER if you stop on oil, you continue until you hit either an obstacle (wall or bot) or none-oil floor. But what happens when you are pushed onto the oil?
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
Re: Brainstorm input request: mapping coordinates
WOOOOOT
After 3 fn days of debugging and struggling with insanely complex code I've FINALLY managed to get in the water, ramp and oil tiles (and working).
Water: when in water the first move is negated (but when driving into water not, just the NEXT move is negated and all moves after that not). When pushed into water again the same rules but these need to be send back to the pusher.
Oil: that REALLY was a pain.
- when driving onto oil nothing happens. When stopping you start sliding until you either hit something or are not on oil anymore
so far 'easy'.
- now the pushing... when you push a bot on oil it starts sliding (and as I use recursive loops to check multiple pushing bots I thus need to check EVERY recurse whether they're sliding or not).
- when you are sliding you cannot push BUT when you start driving on oil (first move negates) and THEN push a bot (also on oil) it does start sliding etc.
a real pain to get it programmed but it WORKS.
For the fun of it here the recursive loop:
After 3 fn days of debugging and struggling with insanely complex code I've FINALLY managed to get in the water, ramp and oil tiles (and working).
Water: when in water the first move is negated (but when driving into water not, just the NEXT move is negated and all moves after that not). When pushed into water again the same rules but these need to be send back to the pusher.
Oil: that REALLY was a pain.
- when driving onto oil nothing happens. When stopping you start sliding until you either hit something or are not on oil anymore
so far 'easy'.
- now the pushing... when you push a bot on oil it starts sliding (and as I use recursive loops to check multiple pushing bots I thus need to check EVERY recurse whether they're sliding or not).
- when you are sliding you cannot push BUT when you start driving on oil (first move negates) and THEN push a bot (also on oil) it does start sliding etc.
a real pain to get it programmed but it WORKS.
For the fun of it here the recursive loop:
urgh
Code: Select all
[h:'<!-- ------------------------ calcMoveBot(currentBot, pDirection, pushBot, nRobots, moveLeft, debugIntern) ------------------------ -->']
[h:debug=1]
<!-- is called by itself and moveBot -->
<!-- returns the amount that the robot can move (and thus 0 == false) -->
<!-- 3 CODE LEVELS -->
<!-- -------------------------------------------------------------------------------------- -->
<!-- --------------------------------INITIALIZATION------------------------------------------- -->
<!-- -------------------------------------------------------------------------------------- -->
[varsFromStrProp(getLibProperty("currentGameBoard","lib:roboRally"))]
[h:currentBot = arg(0)]
<!-- pDirection is passed on as argument when the robot is pushed in a certain direction (which is not necessarily the same as its facing) -->
[h:pDirection = arg(1)]
<!-- When a bot is moved by a conveyer it does NOT push another bot. In short then it does not move. -->
[h:pushBot = arg(2)]
[h:nRobots = arg(3)]
<!-- When a bot moves onto oil then it DRIVES #moveLeft and then SLIDES the rest of the oil path. This in case of collision. Driving bots CAN push a bot, Sliding bots not-->
[h:moveLeft = arg(4)]
[h,if(argCount()>5):debugIntern = arg(5) ; debugIntern = 0]
<!-- get current virtual position and status-->
[h:xBot = getProperty("xCurrent", currentBot)]
[h:yBot = getProperty("yCurrent", currentBot)]
[h:onHamper = getProperty("onHamper", currentBot)]
[h:wasOnHamper = getProperty("wasOnHamper", currentBot)]
<!-- the tricky part about ramps and water
if bot was !onwater and isonwater than 1 move is negated
if bot was onwater and isonwater (or not on water) than nothing happens
however if it was on a steep ramp (which takes 2 moves) then its once again hampered this move!
The real tricky part is that with water movement is AGAIN hampered on the next card, so wasOnwater needs to be reset in moveBot!!
This is NOT the case for ramps or steep ramps
-->
[h:hampered = if(onHamper && !wasOnHamper || onHamper == 2, 1, 0)]
[h:nMove = !hampered]
[h,if(onHamper == 2):onHamper = 1]
[h:setProperty("wasOnHamper", onHamper, currentBot)]
[h:isDead = getProperty("isDead", currentBot)]
[h:xMin = getLibProperty("currentXMin", "lib:roboRally")]
[h:yMin = getLibProperty("currentYMin", "lib:roboRally")]
[h:xMax = getLibProperty("currentXMax", "lib:roboRally")]
[h:yMax = getLibProperty("currentYMax", "lib:roboRally")]
[h:currentRound = getLibProperty("currentRound", "lib:roboRally")]
<!--
a bot pushed on an oil slick keeps travelling forward, which needs to be done for pushed bots as well, hence it must be done here.
as you want to enter the while loop you initially set it to 1
The start-driving-on-oil hamper is handled in moveBot
-->
[onOil = 1]
[while(onOil && nMove), CODE:{
<!--
the bot starts sliding as soon as it STOPS driving. As I cannot check here how far it drives I have to deduct the total (extra) moved value first from nMove in moveBot.
Note that roll.count starts at 0 so only if it returns a higher value the deduction needs to be done.
-->
[extraMove = roll.count]
<!-- -------------------------------------------------------------------------------------- -->
<!-- --------------------------------CALC NEW POSITION------------------------------------- -->
<!-- -------------------------------------------------------------------------------------- -->
<!-- move in what direction results in which coordinate change
0 x+1
1 y+1
2 x-1
3 y-1
-->
<!-- bot cannot move when standing on a wall token facing in the pdirection -->
[foreach(tile, eval("c"+xBot+"_"+yBot)), if(json.get(tile, "type") == "Wall"): nMove = if(json.get(tile, "bDirection") == pDirection, 0, nMove)]
[if(debug):bot_debugInfo("c"+xBot+"_"+yBot+", xBot, yBot, currentBot,pDirection, nMove, onHamper, wasOnHamper, extraMove, moveLeft, currentRound", 1, 0, 0, getMacroName(), getMacroLocation())]
[if(nMove), CODE:{
[switch(pDirection):
case 0: xBot = xBot + 1;
case 1: yBot = yBot + 1;
case 2: xBot = xBot - 1;
case 3: yBot = yBot - 1;
default:assert(0,"pDirection: "+pDirection+" unknown in macro calcMoveBot",0);
]
''
};{}]
<!-- -------------------------------------------------------------------------------------- -->
<!-- --------------------------------BOUNDARY CHECK------------------------------------------- -->
<!-- -------------------------------------------------------------------------------------- -->
<!-- boundary check to prevent errors later on when trying to request undefined variables -->
<!-- check not to fall of board -->
[xmBot = xBot]
[ymBot = yBot]
[if(xBot < xMin || xBot > xMax || yBot < yMin || yBot > yMax), CODE:{
[xBot = max(xMin,min(xMax,xBot))]
[yBot = max(yMin,min(yMax,yBot))]
[isDead = 1]
[broadcast(strformat("<i>...%{currentBot} drives from the board."))]
''
};{}]
[if(debugIntern): pause("xmBot","ymBot","xBot","yBot","nMove","isDead","pDirection","currentBot")]
<!-- -------------------------------------------------------------------------------------- -->
<!-- --------------------------------WALL CHECK ------------------------------------------- -->
<!-- -------------------------------------------------------------------------------------- -->
<!-- bot cannot move when the activation direction of the wall equals pDirection -->
<!-- the activation direction is the direction a bot moves when it moves onto the tile. If its true then the tile is activated, which is this case means blocked -->
[wall = 0]
[foreach(tile, eval("c"+xBot+"_"+yBot)), CODE:{
[type = json.get(tile, "type")]
[if(startsWith(type, "Wall")), CODE:{
[nMove = if(json.get(tile, "activationDirection") == pDirection, 0, nMove)]
[if(indexOf(type, "Wall Gate")+1): teleport(json.get(tile, "name"))]
[if(indexOf(type, "Wall Spiked")+1): damageBot(1, "Spike", currentBot)]
[if(indexOf(type, "Wall Ledge")+1): damageBot(2, "'Falling Of ledge'", currentBot)]
[wall = !nMove]
''
}]
''
}]
[if(wall): broadcast(strformat("<i>...%{currentBot} drives into a wall"))]
<!-- -------------------------------------------------------------------------------------- -->
<!-- --------------------------------COLLISION CHECK--------------------------------------- -->
<!-- -------------------------------------------------------------------------------------- -->
<!-- in case of running into another robot, check if that one can move! -->
<!-- note that during the board fase tokens can be standing on an active tile. In that case they do NOT collide!!! Instead the bot is blocked!! -->
[sliding = if(getProperty("onOil", currentBot) && extraMove > moveLeft, 1,0)]
[count(nRobots), if("Robot "+(roll.count+1) != currentBot), CODE:{
[collisionBot = "Robot "+(roll.count+1)]
[if(getProperty("xCurrent", collisionBot) == xBot && getProperty("yCurrent", collisionBot) == yBot && !getProperty("onActiveTile", collisionBot)), CODE:{
<!-- calcMoveBot returns 0 (cannot move) or !0 (can move) -->
<!-- when your sliding you cannot push a bot -->
[if(pushBot && !sliding), CODE:{
[if(!calcMoveBot(collisionBot, pDirection, pushBot, nRobots, moveLeft)): nMove = 0]
''
};{
<!-- apparently bot CANNOT push in this fase and thus nMove returns 0 -->
[nMove = 0]
''
}]
''
}]
''
}]
<!-- -------------------------------------------------------------------------------------- -->
<!-- ------------------------RAMP, WATER, OIL and DAMAGE CHECK----------------------------- -->
<!-- -------------------------------------------------------------------------------------- -->
[onWater = 0]
[onHamper = 0]
[onOil = 0]
[if(nMove && !isDead), CODE:{
<!-- check where the bot drove onto -->
[foreach(tile, eval("c"+xBot+"_"+yBot)), CODE:{
[type = json.get(tile, "type")]
<!-- check if token drove into a pit -->
[if(type == "Pit"): isDead = 1]
<!-- check if token drove (or is pushed) onto oil -->
[if(type == "Oil"): onOil = 1]
<!-- check if bot is hampered by the environment -->
[if(type == "Water" || type == "Ramp" && json.get(tile, "bDirection") == pDirection): onHamper = 1]
[if(type == "Steep Ramp" && json.get(tile, "bDirection") == pDirection): onHamper = 2]
<!-- check if token is on water and existinguish any flames -->
[if(type == "Puddle" || type == "Water"), CODE:{
[onWater = 1]
[if(getProperty("onFire", currentBot)==1): broadcast(strformat("<i>...%{currentBot} drives through a puddle which extinguishes the flames."))]
[setProperty("onFire", 0, currentBot)]
''
}]
<!-- check if token is driving on a damaging element -->
[if(type == "Damage"), CODE:{
[name = json.get(tile, "name")]
<!-- damage when driving through napalm or flamer and onFire if napalm -->
[if(name == "Flamer"): damageBot(1, "'Running into Flame'", currentBot)]
[if(name == "Napalm"), CODE:{
[damageBot(1, "'Running into Napalm'", currentBot)]
[setProperty("onFire", 1, currentBot)]
''
}]
''
}]
''
}]
[setProperty("onOil", onOil, currentBot)]
[setProperty("onHamper", onHamper, currentBot)]
<!-- output -->
[if(isDead): broadcast(strformat("<i>...%{currentBot} falls in a pit."))]
[if(onHamper): broadcast(strformat("<i>...%{currentBot} drives onto a move hampering element (water or ramp)."))]
[if(onOil): broadcast(strformat("<i>...%{currentBot} drives onto an oil slick."))]
[if(onWater), CODE:{
[if(getProperty("onFire", currentBot)):
[broadcast(strformat("<i>...%{currentBot} drives in the water, which extinguishes the flames."))]
;
[broadcast(strformat("<i>...%{currentBot} drives in the water."))]
]
[setProperty("onFire", 0, currentBot)]
''
}]
''
};{}]
<!-- -------------------------------------------------------------------------------------- -->
<!-- --------------------------------MOVE BOT ------------------------------------------- -->
<!-- -------------------------------------------------------------------------------------- -->
[if(nMove), CODE:{
<!-- move token, even if its destroyed, cause it may just have been moved off board.-->
[currentAnimation = strformat("currentBot=%{currentBot} ; turn=%{currentRound} ; x=%{xmBot} ; y=%{ymBot} ; degrees=0 ; teleport=0")]
[moveArray = json.append(getLibProperty("moveArray", "lib:roboRally"), currentAnimation)]
[setLibProperty("moveArray", moveArray,"lib:roboRally")]
<!-- movement is now only done in memory. After this function is finished, ALL robots are checked and if start!=current then their movement is animated. -->
['moveToken(xmBot,ymBot,0,currentBot)']
[setProperty("xCurrent", xmBot,currentBot)]
[setProperty("yCurrent", ymBot,currentBot)]
[if(debug):bot_debugInfo("moveArray, currentAnimation, xmBot, ymBot, currentBot,pDirection, nMove, onHamper, wasOnHamper, onOil, extraMove, moveLeft, sliding, currentRound", 1, 0, 0, getMacroName(), getMacroLocation())]
[if(!isDead):broadcast(strformat("<i>...%{currentBot} moves one %s.", if(abs(getProperty("bDirection", currentBot)-pDirection)==0, "Forward",if(abs(getProperty("bDirection", currentBot)-pDirection)==2, "Backwards","Sideways")) ))]
''
};{
[if(!wall && !hampered):broadcast(strformat("<i>...%{currentBot} collides with another bot."))]
''
}]
[if(isDead):destroyBot(currentBot)]
[propOnOil = getProperty("onOil", currentBot)]
[pause("onOil","propOnOil","extraMove", "sliding", "moveLeft","nMove")]
''
}]
<!-- -------------------------------------------------------------------------------------- -->
<!-- --------------------------------RETURN VALUE------------------------------------------ -->
<!-- -------------------------------------------------------------------------------------- -->
<!--
nMove is default 1
will ONLY be set to 0 under the following conditions:
- running into a wall (this tile or next tile)
- running into an unmoveable robot (either that bot is against a wall or your pushing from a conveyer during the table fase)
isDead is default 0 and will ONLY be set to 1 under the following conditions:
- driving off board
- driving over a pit
the return value (canMove = 0, 1 or higher (in case of oil slick) is used for
- pushing in calcMoveBot only 0 and !0 are used
- extra move on oil needs to be deducted from the total nMove
-->
['pause("wall", "nMove")']
[macro.return = if(!wall, nMove + extraMove, 0)]
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS