Spent a fair bit of the day mucking about with MapTool. Thanks to Randy’s better-than-mine code skills and knizia.fan’s skills at this tutorial, I had enough code to steal study and customize to finish a fairly complicated macro for determining damage effects in MapTool for GURPS. I haven’t plugged in any sort of crippling calculations yet, and not sure if I want to (GURPS is so complicated that it doesn’t make sense to try and automate every function, even if it wasn’t against the strange TOS at Steve Jackson games regarding play aids). I’m planning on being light and fast enough initially so that criplling can be figured out on the fly, and indicated with a simple state graphic if we need to.

In any case, here’s the damage calculation macro. The properties it affects on the token are customized for this campaign, and any GURPS campaign using MapTool is going to be unique enough that a generic framework wouldn’t work anyway. Here it is for others to study, and hopefully improve on, so I can steal it back when they do.

<!– Ask the user for input.

[DamageTaken = Damage]

Compute the correct word to use.

[Word = if(DamageTaken == 1, “point”, “points”)]

Take the damage

[OldHP = HP]

[NewHP = HP – DamageTaken]

[HP = NewHP]

Check for HP/2 major wounds

[MajorWoundThreshold = MaxHP / 2]

[MajorWound = if(DamageTaken > MajorWoundThreshold, 1, 0)]

Check for Reeling

[ReelingThreshold = MaxHP / 3]

[Reeling = if(NewHP < ReelingThreshold, 1, 0)]

Check for Collapse/Death State

[Death1 = 0 – MaxHP]

[Death2 = 0 – MaxHP * 2]

[Death3 = 0 – MaxHP * 3]

[Death4 = 0 – MaxHP * 4]

[Death5 = 0 – MaxHP * 5]

[Death6 = 0 – MaxHP * 10]

[Collapse = if(NewHP < 1, 1, 0)]

[DeathCheck1 = if(OldHP > Death1 && NewHP <= Death1, 1, 0)]

[DeathCheck2 = if(OldHP > Death2 && NewHP <= Death2, 1, 0)]

[DeathCheck3 = if(OldHP > Death3 && NewHP <= Death3, 1, 0)]

[DeathCheck4 = if(OldHP > Death4 && NewHP <= Death4, 1, 0)]

[DeathCheck5 = if(OldHP > Death5 && NewHP <= Death5, 1, 0)]

[DeathCheck6 = if(OldHP > Death6 && NewHP <= Death6, 1, 0)]

See how many death saves are necessary and determine word

[DeathChecks = DeathCheck1 + DeathCheck2 + DeathCheck3 + DeathCheck4]

[Word2 = if(DeathChecks > 1, “times”, “time”)]

–>

[r: token.name] takes {DamageTaken} {Word} of damage, dropping from {OldHP} to {NewHP} HP.

{if(MajorWound && !DeathCheck5 && !DeathCheck6, “<br><b>Major Wound</b> received! Roll vs HT to avoid knockdown/stun!”, “”)}

{if(Reeling && !DeathCheck5 && !DeathCheck6, “<br><b>Reeling</b> from damage! Halve your Move and Dodge (round up).”, “”)}

{if(Collapse && !DeathCheck5 && !DeathCheck6, “<br><b>Collapse</b> imminent! Roll vs HT every turn to stay conscious unless you Do Nothing.”, “”)}

{if(DeathChecks == 1 && !DeathCheck5 && !DeathCheck6, “<br><b>Death</b> possible! Roll vs HT to survive; missing by 1 or 2 is a Mortal Wound, otherwise die.”, “”)}

{if(DeathChecks == 2 && !DeathCheck5 && !DeathCheck6, “<br><b>Death</b> possible! Roll vs HT <b>twice</b> to survive; missing by 1 or 2 is a Mortal Wound, otherwise die.”, “”)}

{if(DeathChecks == 3 && !DeathCheck5 && !DeathCheck6, “<br><b>Death</b> possible! Roll vs HT <b>three times</b> to survive; missing by 1 or 2 is a Mortal Wound, otherwise die.”, “”)}

{if(DeathChecks == 4 && !DeathCheck5 && !DeathCheck6, “<br><b>Death</b> possible! Roll vs HT <b>four times</b> to survive; missing by 1 or 2 is a Mortal Wound, otherwise die.”, “”)}

{if(DeathCheck5 && !DeathCheck6, “<br><b>Dead</b>.”, “”)}

{if(DeathCheck6, “<br><b>Destroyed</b>!”, “”)}

A related macro, for fatigue loss (simpler), follows. I haven’t yet worked out how to pass the temporary value for damage when spending fatigue below 0FP to a second macro call.

<!–

Get amount of fatigue lost

[Fatigue = Fatigue_Lost]

[OldFP = FP]

[NewFP = OldFP – Fatigue]

[FP = NewFP]

Unconsciousness threshold

[MinFP = 0 – MaxFP]

Determine tiredness threshold

[TiredFP = MaxFP / 3]

[Tired = if(NewFP < TiredFP, 1, 0)]

Determine HP damage from exhaustion

[DamRed = if(OldFP > 0, OldFP, 0)]

[Dam = if(NewFP < 0, Fatigue, 0)]

[Damage = Dam – DamRed]

Determine total exhaustion

[Exhausted = if(NewFP <= MinFP, 1, 0)]

–>

[r: token.name] loses {Fatigue} points of fatigue, leaving {NewFP}.

{if(Tired && !Exhausted, “<br><b>Tired</b>! Halve your Move, Dodge, and ST (round up).”, “”)}

{if(Damage > 0, “<br><b>Damaged</b>! You take HP damage equal to FP loss below 0 FP. Any further FP expenditure requires a Will roll to avoid falling unconscious.”, “”)}

{if(Exhausted, “<br><b>Exhausted</b>! You are unconscious.”, “”)}