DN's D&D4e Character Sheet Framework

Framework(s) for D&D 4e, including Veggiesama's.

Moderators: Azhrei, dorpond, trevor, giliath, Gamerdude, jay, Mr.Ice

User avatar
PinkRose
Dragon
Posts: 732
Joined: Sat Nov 15, 2008 2:28 pm
Location: The City of Roses, Oregon

Re: DN's D&D4e Character Sheet Framework

Post by PinkRose »

File is there for me.
I am a special snowflake!

Cay
Cave Troll
Posts: 61
Joined: Sat Feb 18, 2012 5:23 am
Location: Hilden, Germany

Re: DN's D&D4e Character Sheet Framework

Post by Cay »

Angfiel wrote:I can't download the file because it says it doesn't excist.

Very strange. I just downloaded it without a problem. ???
Ready to play campaign: Kobold Hall - D&D4e LVL1

Angfiel
Kobold
Posts: 2
Joined: Sat Mar 17, 2012 9:41 am

Re: DN's D&D4e Character Sheet Framework

Post by Angfiel »

It works now for me now... maybe just some temporary problem :)


One thing I'm wondering after adding a bunch of characters is if you can change the surges? A lot of the characters are not getting the right amount of surges they should have (according to the character-maker on the D&D-homepage).

User avatar
z3n1st
Kobold
Posts: 6
Joined: Fri Mar 09, 2012 12:31 am

Re: DN's D&D4e Character Sheet Framework

Post by z3n1st »

Running into an odd issue with initiative. For some tokens it works fine, for others it provides a decimal value in addition.

example: 3 players roll initiative and get 14, 21, and 8. Three other players roll and it gives 11.04, 15.07, and 23.05.

Any ideas what is causing that?

EDIT: I have noticed one thing, is that the decimal value is the bonus to their initiative, although it is calculated into the number before the decimal. I guess my question becomes why is it included in a decimal format as well, in case of a tie or something?

User avatar
PinkRose
Dragon
Posts: 732
Joined: Sat Nov 15, 2008 2:28 pm
Location: The City of Roses, Oregon

Re: DN's D&D4e Character Sheet Framework

Post by PinkRose »

It is in case of a tie, yes.
Why some have it and some don't, I don't know.
I think I had to change some code to make it work and maybe it was updated to automatically include that later.
I am a special snowflake!

User avatar
Merkuri
Giant
Posts: 194
Joined: Sat Feb 28, 2009 3:20 pm
Location: Massachusetts, USA

Re: DN's D&D4e Character Sheet Framework

Post by Merkuri »

If the character has a +0 bonus to initiative they won't get a decimal. Or, rather, they do get one, but it's .00, so Maptool doesn't show it.
Adventure is not outside; it is within.
--Found in a fortune cookie on game night

MapTool Framework for Sufficiently Advanced

User avatar
PinkRose
Dragon
Posts: 732
Joined: Sat Nov 15, 2008 2:28 pm
Location: The City of Roses, Oregon

Re: DN's D&D4e Character Sheet Framework

Post by PinkRose »

That makes far too much sense.
Thanks Merkuri for jumping in.
I am a special snowflake!

Darakonis
Cave Troll
Posts: 98
Joined: Sun Apr 19, 2009 5:49 pm
Contact:

Re: DN's D&D4e Character Sheet Framework

Post by Darakonis »

I'd just like to, once again, thank DN and his contributors for such a fantastic framework, and the forumgoers for helping me out when I needed it. I've been running this framework for years now, and couldn't be happier with it.

If anyone would like to see a demonstration of this framework in action, I live-stream my D&D sessions, played through MapTool and voice chat, on Thursdays at 9:50 pm EDT/1:50 am GMT. It's a lighthearted, comedic campaign running through Thunderspire Labyrinth. You can catch the stream live here, or check out the archives.
Visit the D&D Digest for RPG tips & reviews.

Listen to the adventures of a live MapTool voice-chat group: Dungeons & Drogans

User avatar
Ferghis
Kobold
Posts: 5
Joined: Mon Oct 10, 2011 7:04 pm

Re: DN's D&D4e Character Sheet Framework

Post by Ferghis »

Hello, and thanks for the shiny framework. I've been getting to know it, and it's fantastic.

First, I want to check that I'm doing something right: a healing power that grants both temp and regular HP has to simply do two "attacks" which are then set to "none" and then, in the first one you put the regular and in the second attack you put the temporary HP. These attack results then produce clickable links in the dialogue that open up a character's healing/damage dialogue (which is prepopulated). Is this the most efficient way of doing this? Is there any way to combine both temp and regular HP into one clickable chat link?

Second, is there any way for my warforged not to accumulate failed death saves? A racial feature allows them to take the better of a regular death save or 10, and I'm wondering if there's a way to not die three times. I do want to roll, because (with Resilient Focus) I have 3/20 of just triggering a surge and standing up again (and our evil DM does knock me down frequently). Is there any way to disable the failed death save count for just my character?

User avatar
Ferghis
Kobold
Posts: 5
Joined: Mon Oct 10, 2011 7:04 pm

Re: DN's D&D4e Character Sheet Framework

Post by Ferghis »

Also, how much work is it to implement automatic condition expiration?

As levels go up, conditions become very numerous, and it would be nice if, at the end of each turn, a dialogue would display the conditions set to expire at the end of that turn (with the option of extending each condition's duration - leaving control firmly in the hand of the user).

When I used to track initiative and conditions with pen and paper, instead of noting that at the beginning or end of someone's turn such a condition would expire, I would just note the end of the initiative count at the end of which it died (since you can't extend the duration of conditions by delaying, this works very well). So, if Larry had a condition that expired at the beginning of Sally's turn, and Sally had initiative 12, Next to Larry on the initiative sheet I just noted [condition](13) - to indicate that when init 12 rolled around, the condition was over. Could something like this be implemented?

User avatar
Ferghis
Kobold
Posts: 5
Joined: Mon Oct 10, 2011 7:04 pm

Re: DN's D&D4e Character Sheet Framework

Post by Ferghis »

At the risk of posting too much, a tiny bug: the "Other" language never seems to save more than briefly.

Faz
Kobold
Posts: 2
Joined: Mon Oct 24, 2011 11:32 pm

Re: DN's D&D4e Character Sheet Framework

Post by Faz »

(and our evil DM does knock me down frequently)

That would be me and guilty as charged.

Also, how much work is it to implement automatic condition expiration?

As levels go up, conditions become very numerous, and it would be nice if, at the end of each turn, a dialogue would display the conditions set to expire at the end of that turn (with the option of extending each condition's duration - leaving control firmly in the hand of the user).

When I used to track initiative and conditions with pen and paper, instead of noting that at the beginning or end of someone's turn such a condition would expire, I would just note the end of the initiative count at the end of which it died (since you can't extend the duration of conditions by delaying, this works very well). So, if Larry had a condition that expired at the beginning of Sally's turn, and Sally had initiative 12, Next to Larry on the initiative sheet I just noted [condition](13) - to indicate that when init 12 rolled around, the condition was over. Could something like this be implemented?


I've read a few posts in this thread regarding conditions and it seems that condition duration is kept to a minimum so as to keep control with the DM and not the framework itself.

The only post I have seen so far is this one from MadJoker viewtopic.php?f=58&t=15969&p=205647#p205647
1. No, the conditions are not cleared automatically, you have to do that manually. But it is possible to implement this behavior through a custom initiative script. However, the automation in this FW is intentionally kept low, because in the end it is the DM and not the FW that should run the game. For example it could be that some state would end, but you as the DM have some effect that makes it stay. In this case the script would not behave correctly.
That said, I have written a custom set of initiative macros for sorting initiative (with automatic tie breaking) and for advancing initiative. This script checks for all conditions and ongoing damage and tells you when people have to make a saving throw, when they take ongoing damage, and when effects end. If you want I could provide that script to you.


Now I don't know how much of an authority he is on the subject so this may not actually be the case. I would agree with the sentiment that control should be with the DM. What interests me is a script that reminds you of when an effect expires so I'll be looking for that.

My only problem with the framework is as far as I can see is that there is no way to allow people to put effects on tokens they don't own, this may also be by design for similar reasons(say a monster cannot be dazed) but for me putting on conditions would be more annoying than taking them off. So is there a way to allow this without giving ownership of enemies to my PCs or at least without letting them see powers and defences and the like.

User avatar
Ferghis
Kobold
Posts: 5
Joined: Mon Oct 10, 2011 7:04 pm

Re: DN's D&D4e Character Sheet Framework

Post by Ferghis »

MadJoker wrote:I have written a custom set of initiative macros for sorting initiative (with automatic tie breaking) and for advancing initiative. This script checks for all conditions and ongoing damage and tells you when people have to make a saving throw, when they take ongoing damage, and when effects end. If you want I could provide that script to you.
Yep, that's exactly what I was talking about. I hope he posts his script.

User avatar
MadJoker
Cave Troll
Posts: 55
Joined: Sat Mar 28, 2009 3:43 pm

Re: DN's D&D4e Character Sheet Framework

Post by MadJoker »

Ferghis wrote:
MadJoker wrote:I have written a custom set of initiative macros for sorting initiative (with automatic tie breaking) and for advancing initiative. This script checks for all conditions and ongoing damage and tells you when people have to make a saving throw, when they take ongoing damage, and when effects end. If you want I could provide that script to you.
Yep, that's exactly what I was talking about. I hope he posts his script.

Hm, I have not checked this thread for far too long. Maybe the scripts can still be of help to someone.

Since my last post I have also added a turn timer functionality. So, first you need to add

Code: Select all

enableTurnTimer:0
CurrentTimer
printInitiative:0
to the property list of the Lib:Information token. If enableTurnTimer is 0 only the GM will get a message telling him how long a turn took (only for player characters). If you set it to 1 all players can see the time. CurrentTimer is just an internal variable used by the scripts. Lastly, printInitiative prints a custom "has received initiative" message together with the other info. This is an alternative to the standard message from MT. Now to the scripts.

I have these three scripts sitting in my Campaign frame. The usage should be self explanatory.

[spoiler=ClearInitiative]

Code: Select all

[IF(initiativeSize() == 0), CODE: {[H: removeAllFromInitiative()][H:abort(0)]};{};]

<!-- Check for states that end at the end of the encounter -->
[H: endEffect = 0]
[H: iniList = getInitiativeList()]
[H: tokenArr = json.get(iniList,"tokens")]
[foreach(token,tokenArr,""), CODE: {
[H: endEffects = checkInitiativeConditions(json.get(token,"tokenId"), 2)]
[H: saveEnd = json.get(endEffects,"saveEnd")]
[H: end = json.get(endEffects,"end")]
[H: endEffect = if(!json.isEmpty(saveEnd) || !json.isEmpty(end),1,endEffect)]
<span style="color: red">
[IF(!json.isEmpty(saveEnd)), CODE: {
<b>[r:getName(json.get(token,"tokenId"))]</b> must make a save against
};{}]
[foreach(condition,saveEnd," and "), CODE: {
[H: DNT_Condition = getProperty("DNA_Condition" + json.get(condition,"Slot"),json.get(token,"tokenId"))]
<b>[R: macroLink(json.get(DNT_Condition,"Name"), "[email protected]:Sheet", "none", json.set("", "WindowType", "Condition", "Name", json.get(DNT_Condition,"Name"), "Duration", json.get(DNT_Condition, "Duration"), "Damage", json.get(DNT_Condition, "Damage"), "Penalty", json.get(DNT_Condition, "Penalty"), "Notes", json.get(DNT_Condition, "Notes")), json.get(token,"tokenId"))]</b>
}]
[IF(!json.isEmpty(saveEnd)), CODE: {
[R: if(json.length(saveEnd) > 1," conditions."," condition.")]
};{}]
[IF(!json.isEmpty(end)), CODE: {
<b>[r:getName(json.get(token,"tokenId")) + "'s"]</b>
};{}]
[foreach(condition,end," and "), CODE: {
[H: DNT_Condition = getProperty("DNA_Condition" + json.get(condition,"Slot"),json.get(token,"tokenId"))]
<b>[R: macroLink(json.get(DNT_Condition,"Name"), "[email protected]:Sheet", "none", json.set("", "WindowType", "Condition", "Name", json.get(DNT_Condition,"Name"), "Duration", json.get(DNT_Condition, "Duration"), "Damage", json.get(DNT_Condition, "Damage"), "Penalty", json.get(DNT_Condition, "Penalty"), "Notes", json.get(DNT_Condition, "Notes")), json.get(token,"tokenId"))]</b>
}]
[IF(!json.isEmpty(end)), CODE: {
[R: if(json.length(end) > 1," conditions end."," condition ends.")]
};{}]
</span>
}]
[H: removeAllFromInitiative()]
[H:setLibProperty("CurrentTimer","","Lib:Information")]

[IF(!endEffect), CODE: {[H:abort(0)]};{}]
[/spoiler]
[spoiler=NextInitiative]

Code: Select all

[IF(initiativeSize() == 0), CODE: {[H:abort(0)]};{};]
[IF(getInitiativeRound() == -1), CODE: {[H:setInitiativeRound(-1)][H:setCurrentInitiative(-1)][H:setLibProperty("CurrentTimer",json.get(getInfo("server"),"timeInMs"),"Lib:Information")]};{};]
[H: enableTurnTimer = getLibProperty("enableTurnTimer","Lib:Information")]
[H: printInitiative = getLibProperty("printInitiative","Lib:Information")]
[H: enableTurnTimer = if(enableTurnTimer == "",0,enableTurnTimer)]

<!-- Check for states that end at the end of the turn -->
[H: endEffect = 0]
[H: tokenEffect = 0]
[H: prevTokenEffect = 0]
[H: iniList = getInitiativeList()]
[H: iniToken = getInitiativeToken()]
[H: tokenArr = if(getInitiativeRound() != -1 && iniToken != "" && iniToken != 0,json.get(iniList,"tokens"),"")]
[foreach(token,tokenArr,""), CODE: {
[H: tokenEffect = 0]
[H: endEffects = checkInitiativeConditions(json.get(token,"tokenId"), 0)]
[H: saveEnd = json.get(endEffects,"saveEnd")]
[H: end = json.get(endEffects,"end")]
[H: damage = json.get(endEffects,"damage")]
[H: tokenEffect = if(!json.isEmpty(saveEnd) || !json.isEmpty(end) || !json.isEmpty(damage),1,0)]
[H: endEffect = if(tokenEffect,1,endEffect)]
[R, If(tokenEffect && prevTokenEffect), CODE: {
[R: "<br>"]
};{}]
[H: prevTokenEffect = tokenEffect]
<span style="color: red">
[IF(!json.isEmpty(saveEnd)), CODE: {
<b>[r:getName(json.get(token,"tokenId"))]</b> must make a save against
};{}]
[foreach(condition,saveEnd," and "), CODE: {
[H: DNT_Condition = getProperty("DNA_Condition" + json.get(condition,"Slot"),json.get(token,"tokenId"))]
<b>[R: macroLink(json.get(DNT_Condition,"Name"), "[email protected]:Sheet", "none", json.set("", "WindowType", "Condition", "Name", json.get(DNT_Condition,"Name"), "Duration", json.get(DNT_Condition, "Duration"), "Damage", json.get(DNT_Condition, "Damage"), "Penalty", json.get(DNT_Condition, "Penalty"), "Notes", json.get(DNT_Condition, "Notes")), json.get(token,"tokenId"))]</b>
}]
[IF(!json.isEmpty(saveEnd)), CODE: {
[R: if(json.length(saveEnd) > 1," conditions."," condition.")]
};{}]
[IF(!json.isEmpty(end)), CODE: {
<b>[r:getName(json.get(token,"tokenId")) + "'s"]</b>
};{}]
[foreach(condition,end," and "), CODE: {
[H: DNT_Condition = getProperty("DNA_Condition" + json.get(condition,"Slot"),json.get(token,"tokenId"))]
<b>[R: macroLink(json.get(DNT_Condition,"Name"), "[email protected]:Sheet", "none", json.set("", "WindowType", "Condition", "Name", json.get(DNT_Condition,"Name"), "Duration", json.get(DNT_Condition, "Duration"), "Damage", json.get(DNT_Condition, "Damage"), "Penalty", json.get(DNT_Condition, "Penalty"), "Notes", json.get(DNT_Condition, "Notes")), json.get(token,"tokenId"))]</b>
}]
[IF(!json.isEmpty(end)), CODE: {
[R: if(json.length(end) > 1," conditions end."," condition ends.")]
};{}]
</span>
}]

[R, IF(iniToken != "" && iniToken != 0), CODE: {
[H: turnStartTime = getLibProperty("CurrentTimer","Lib:Information")]
[H: turnStartTime = if(turnStartTime != "",turnStartTime,json.get(getInfo("server"),"timeInMs"))]
[H: turnTime = json.get(getInfo("server"),"timeInMs") - turnStartTime]
[H, IF(isPC(iniToken)), CODE: {
[H: tSeconds = round(turnTime/1000)]
[H: tMinutes = floor(tSeconds/60)]
[H: tSeconds = tSeconds - floor( tSeconds / 60 ) * 60]
[H: broadcast("<span style='color: blue'><b>" + getName(iniToken) + "'s</b> turn took " + if(tMinutes > 0,tMinutes + " minute" + if(tMinutes > 1,"s","") + if(tSeconds > 0," and ",""),"") + if(tSeconds > 0 || tMinutes == 0, tSeconds + " second" + if(tSeconds > 1 || tSeconds == 0,"s",""),"") + ".</span>",if(enableTurnTimer,"all","gm"))]
};{}]
};{}]

<!-- Advance initiative until a token that is not dead is found -->
[H:nextInitiative()]
[H:isDead = getState("Dead",getInitiativeToken())]
[H:isDying = getState("Dying",getInitiativeToken())]
[H:isNPC = isNPC(getInitiativeToken())]
[WHILE(isDead || (isDying && isNPC),""), CODE: {
[H:nextInitiative()]
[H:isDead = getState("Dead",getInitiativeToken())]
[H:isDying = getState("Dying",getInitiativeToken())]
[H:isNPC = isNPC(getInitiativeToken())]
}]

[H: prevEndEffect = endEffect]
[H: received = 0]
[H: iniToken = getInitiativeToken()]
[R, IF(isPC(iniToken) && printInitiative), CODE:{
<span style="color:#3B9C9C">
[R: if(endEffect,"<br>","")]
<b>[r:getName(iniToken)]</b>
[R: " has received initiative."]
</span>
[H: received = 1]
};{}]

[H:setLibProperty("CurrentTimer",json.get(getInfo("server"),"timeInMs"),"Lib:Information")]

<!-- Check for states that end at the end of the turn -->
[H: endEffect = 0]
[H: tokenEffect = 0]
[H: prevTokenEffect = 0]
[H: iniList = getInitiativeList()]
[H: tokenArr = json.get(iniList,"tokens")]
[foreach(token,tokenArr,""), CODE: {
[H: tokenEffect = 0]
[H: endEffects = checkInitiativeConditions(json.get(token,"tokenId"), 1)]
[H: saveEnd = json.get(endEffects,"saveEnd")]
[H: end = json.get(endEffects,"end")]
[H: damage = json.get(endEffects,"damage")]
[H: tokenEffect = if(!json.isEmpty(saveEnd) || !json.isEmpty(end) || !json.isEmpty(damage),1,0)]
[H: endEffect = if(tokenEffect,1,endEffect)]
[R, If(tokenEffect && (received || prevEndEffect || prevTokenEffect)), CODE: {
[R: "<br>"]
};{}]
[H: prevTokenEffect = tokenEffect]
<span style="color: red">
[IF(!json.isEmpty(damage)), CODE: {
<b>[r:getName(json.get(token,"tokenId"))]</b> takes
};{}]
[foreach(condition,damage," and "), CODE: {
[r:condition]
}]
[IF(!json.isEmpty(damage)), CODE: {
.
};{}]
[IF(!json.isEmpty(end)), CODE: {
<b>[r:getName(json.get(token,"tokenId")) + "'s"]</b>
};{}]
[foreach(condition,end," and "), CODE: {
[H: DNT_Condition = getProperty("DNA_Condition" + json.get(condition,"Slot"),json.get(token,"tokenId"))]
<b>[R: macroLink(json.get(DNT_Condition,"Name"), "[email protected]:Sheet", "none", json.set("", "WindowType", "Condition", "Name", json.get(DNT_Condition,"Name"), "Duration", json.get(DNT_Condition, "Duration"), "Damage", json.get(DNT_Condition, "Damage"), "Penalty", json.get(DNT_Condition, "Penalty"), "Notes", json.get(DNT_Condition, "Notes")), json.get(token,"tokenId"))]</b>
}]
[IF(!json.isEmpty(end)), CODE: {
[R: if(json.length(end) > 1," conditions end."," condition ends.")]
};{}]
</span>
}]

[IF(!endEffect && !prevEndEffect && !received), CODE: {[H:abort(0)]};{}]
[/spoiler]
[spoiler=SortInitiative]

Code: Select all

/self

[H: iniList = getInitiativeList()]
[H: tokenArr = json.get(iniList,"tokens")]
[H: tokenArr2 = tokenArr]
[H: ties = '{}']
[H, foreach(token1,tokenArr), CODE:{
[H: tid1 = json.get(token1,"tokenId")]
[H: ini1 = json.get(token1,"initiative")]
[H, foreach(token2,tokenArr2), CODE:{
[H: tid2 = json.get(token2,"tokenId")]
[H: ini2 = json.get(token2,"initiative")]
[H: ties = if(tid1 != tid2 && ini1 == ini2,json.set(ties,ini1,json.append(json.get(ties,ini1),tid1,tid2)),ties)]
}]
[H: tokenArr2 = json.remove(tokenArr2,0)]
}]
<span style="color: red">
[IF(json.length(ties) > 0), CODE: {
<b>Initiative ties</b> must be broken:<br>
};{}]
[foreach(tie,json.fields(ties),"<br>"), CODE:{
[H: tokensInTie = json.sort(json.unique(json.get(ties,tie)))]
[foreach(token,tokensInTie," - "), CODE:{
[R: getName(token)]
}]
[H: tokensInTie = json.shuffle(tokensInTie)]
[H: nrTokens = json.length(tokensInTie)]
[foreach(token,tokensInTie,""), CODE:{
[H, token(token): setInitiative(tie+(nrTokens/1000))]
[H: nrTokens = nrTokens - 1]
}]
}]
</span>

[H: sortInitiative()]

[H, if(json.length(ties) < 1), CODE: {[H:abort(0)]};{}]
[H:abort(0)]
[/spoiler]

Then you need to add this script to the Lib:Execute token.

[spoiler=checkInitiativeConditions]

Code: Select all

<!--
arg(0) - token that conditions should checked on
arg(1) - which conditions to check (0 - End of Turn, 1 - Start of Turn, 2 - End of Encounter)
-->
[H: assert(argCount() == 2,"<br>in macro <b>checkInitiativeConditions</b><br>Invalid number of arguments " + argCount() + ", expected 2")]

[H: type = arg(1)]
[H: iniList = getInitiativeList() ]
[H: tokenList = json.get(inilist,"tokens")]
[H: iniTokens = '[]']
[H, FOREACH(t,tokenlist), CODE:{
[H: iniTokens = json.append(iniTokens,json.get(t,"tokenId"))]
}]
[H: iniRound = getInitiativeRound()]
[H: tid = arg(0)]
[H, if(type != 2), CODE: {
[H: iid = getInitiativeToken()]
[H: iName = getName(iid)]
};{
[H: iid = ""]
[H: iName = ""]
}]
[H: tidx = json.indexOf(iniTokens,tid)]
[H: iidx = json.indexOf(iniTokens,iid)]
[H: saveEnd = '[]']
[H: end = '[]']
[H: damage = '[]']

[H: DNT_DurationList = getLibProperty("ConditionDurations", "Lib:Information")]

[H: DNA_ConditionIndex = getProperty("DNA_ConditionIndex",tid)]
[H, forEach(DNT_ConditionSlot, DNA_ConditionIndex, ""), CODE: {
[H: DNT_Condition = getProperty("DNA_Condition" + DNT_ConditionSlot,tid)]
[H: DNT_ConditionName = json.get(DNT_Condition, "Name")]
[H: DNT_ConditionDuration = json.get(DNT_Condition, "Duration")]
[H: DNT_ConditionDamage = json.get(DNT_Condition, "Damage")]
[H: DNT_ConditionPenalty = json.get(DNT_Condition, "Penalty")]
[H: DNT_ConditionRound = json.get(DNT_Condition, "Round")]
[H: DNT_ConditionSetBy = json.get(DNT_Condition, "SetBy")]
[H: DNT_ConditionNotes = json.get(DNT_Condition, "Notes")]
[H: DNT_ConditionFailedSaves = json.get(DNT_Condition, "FailedSaves") + 0]
[H: DNT_ConditionDurationTag = json.get(DNT_DurationList, DNT_ConditionDuration)]
<!-- "1":"Save Ends","2":"End of my Turn","3":"Start of my next Turn","4":"End of my next Turn" -->
<!-- "5":"Start of target's Turn","6":"End of target's Turn","7":"Encounter","8":"Other" -->
[H: endEffect = 0]
[IF(type == 0 && (DNT_ConditionDuration == "1" || DNT_ConditionName == "Dying") && tid == iid), CODE: {
[H: saveEnd = json.append(saveEnd,json.set("","Name",DNT_ConditionName,"Slot",DNT_ConditionSlot))]
};{}]
[IF(type == 1 && DNT_ConditionDuration == "4" && iName == DNT_ConditionSetBy), CODE: {
[H: DNT_Condition = json.set(DNT_Condition,"Duration","2"))]
[H: setProperty("DNA_Condition" + DNT_ConditionSlot,DNT_Condition,tid)]
};{}]
[SWITCH(DNT_ConditionDuration), CODE:
case "2": {
[h: endEffect = if(type == 0 && iName == DNT_ConditionSetBy,1,0)]
};
case "3": {
[h: endEffect = if(type == 1 && iName == DNT_ConditionSetBy,1,0)]
};
case "4": {
[h: endEffect = if(type == 0 && iName == DNT_ConditionSetBy && DNT_ConditionRound == iniRound + 1,1,0)]
};
case "5": {
[h: endEffect = if(type == 1 && tid == iid,1,0)]
};
case "6": {
[h: endEffect = if(type == 0 && tid == iid,1,0)]
};
case "7": {
[h: endEffect = if(type == 2,1,0)]
};
default: {
}]

[IF(endEffect), CODE: {
[H: end = json.append(end,json.set("","Name",DNT_ConditionName,"Slot",DNT_ConditionSlot))]
};{}]

[H, IF(type == 1 && DNT_ConditionDamage != "" && tid == iid), CODE: {
[H: dmgName = if(DNT_ConditionName == "Damage","","<b>" + lower(DNT_ConditionName) + "</b> ")]
[H: dmgName = dmgName + "<span style='color:black'>" + macroLink("damage", "[email protected]:Execute", "none", json.set("", "Type", 0, "Amount", DNT_ConditionDamage), currentToken()) + "</span>"]
[H: damage = json.append(damage,"ongoing <b>" + DNT_ConditionDamage + "</b> " + dmgName)]
};{}]
}]

[H: dead = getState("Dead",tid)]
[H, IF(iniRound == -1 || dead), CODE:{
[H: macro.return = json.set("","saveEnd",'[]',"end",'[]',"damage",'[]')]
};{
[H: macro.return = json.set("","saveEnd",saveEnd,"end",end,"damage",damage)]
}]
[/spoiler]

Lastly, add

Code: Select all

[h: defineFunction("checkInitiativeConditions", "[email protected]:Execute")]
to the "onCampaignLoad" macro in the Lib:Sheet token.

Hopefully I haven't forgotten anything, and this should work.
,FailedSaves,1,endEffect
RDNA_ConditionIndex
Last edited by MadJoker on Fri Jul 06, 2012 1:35 am, edited 3 times in total.

Cay
Cave Troll
Posts: 61
Joined: Sat Feb 18, 2012 5:23 am
Location: Hilden, Germany

Re: DN's D&D4e Character Sheet Framework

Post by Cay »

@MadJoker
I would very much like to try your scripts. But I'm having some adding the timer.
I'm not sure where and how I am supposed to enter the timer functionality.
Ready to play campaign: Kobold Hall - D&D4e LVL1

Post Reply

Return to “D&D 4e Frameworks”