MT1.3b86.03 Campaign Framework (Old Version)

Discussion concerning lmarkus' campaign framework for D&D3.x and Pathfinder.

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

Forum rules
Discussion regarding lmarkus001's framework only. Other posts deleted without notice! :)
Post Reply
User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

MT1.3b86.03 Campaign Framework (Old Version)

Post by lmarkus001 »

RELEASED!
MT1.3.86.03_DnD35_Pathfinder.cmpgn


1.3b86_03
=========
  • Support for Hex and Gridless Maps. Previously token sizes were not managed so you could only use a Hex grid map with tokens that were Medium sized. Now sizes are managed and even gridless maps should be supported. The Black Tentacles macro will likely only work on Square grid maps.
  • Resolved dual output for GMs.
  • PF Fly Skill: updated the Globals data so Pathfinder Fly skill now has size modifiers. Added a campaign macro you can run that will update your Globals token so it preserves your current data.
  • Vulnerable damage. You can now enter a negative number in the DR/ER dialog that is presented when a token takes damage. Negative values will INCREASE the damage taken. This is to provide a place to put Vulnerable damage.
  • PF Channel Energy. Clarified the tooltip (it is still ugly), and clarified the target of healing/damage in the heal/damage dialog.
  • D&D Channel Energy. Does a cleaner job of handling tokens that have no ChannelEnergy string property.
  • Invisible mod-set. The macro Invis Move removed as now the object layer marker is automatically moved for you.
  • Black Tentacles: performance boost!
  • Lots of tool-tips on the Campaign Macros to help clarify functionality.
  • PF Combat Maneuver: Corrected CM rolls for creatures sized Tiny and smaller (they get Dex instead of Str for the roll).
  • Change GM only Auras to OWNER as this makes them more flexible but still preserves GM functionality.

    OTHER's TOOLS
  • Upgraded to Wolf42 Bag of Tricks 6.5d -- CUSTOMIZED to support my UDF Wiki: setSize() and to support the automatic movement of the "shadow" invisible token.
  • Upgraded Aliasmask's Impersonate library to 1.1
  • Upgraded Aliasmask's 2.1 change to TokenManager
Specific Areas Modified
Campaign Properties: Changed Weapon default settings, tweaked a light
Lib:libDnD35Pathfinder
Lib:GlobalsSRDPF - SysSkills
Campaign Macros
Table - SysVars, Critical Hits/Misses
Last edited by lmarkus001 on Tue Jun 19, 2012 1:38 pm, edited 13 times in total.

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

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by aliasmask »

Here's a fix for the mod report. When empty there is an error.
||| ConditionReport |||

Code: Select all

@@ @ConditionReport
[H: output = "[]" ]
[H: gTok = "Lib:GlobalsSRDPF" ]
[H: jTM = getLibProperty( "TempModToggleSets", gTok ) ]
[H: atms = json.get( PrivateJSON, "ActiveTempModSets" ) ]
[H, IF( json.isEmpty( atms ) ): activeMSList = ""; activeMSList = json.toList( json.unique( atms ) ) ]
[H: jPTM= json.get( PrivateJSON, "CustomModSetValues") ]

[H, FOREACH( m, activeMSList ), CODE: {
   [IF( json.isEmpty( jPTM ) ): jPM = ""; jPM = json.get( jPTM, m ) ]
   [IF( json.isEmpty( jPM ) ): tTip = json.get( json.get( jTM, m ), "tip" );tTip = json.get( jPM, "tip" ) ]
   [ tCat = json.get( json.get( jTM, m ), "cat" )]
   [ tState = json.get( json.get( jTM, m), "state")]
   [H, if(tState != "NA"), code: {
      [H: setState(tState,1)]
      [H: stateImage = strformat("<img src='%s' width=50 height=50>",getStateImage(tState))]
   };{
      [H: stateImage = " "]
   }]     
   [IF(tCat == ""): tCat = "Mod"]
   [H: tTip = strformat('<span title="<html><table><tr valign=top><td>%{stateImage}</td><td>%{tTip}</td></tr></table></html>">%{m}</span>')]
   [H: output = json.append(output,strformat('<tr id="%s"><td style="padding: 0px 2px 0px 5px;text-align:right"><b>%{tCat}:</b></td><td style="padding-right: 5px">%{tTip}</td></tr>',lower(tCat+" "+m)))]
}]
[H: aitems = json.get( PrivateJSON, "ActiveItems" ) ]
[H, IF( json.isEmpty( aitems ) ): activeMSList = ""; activeMSList = json.toList( json.unique( aitems ) ) ]

[H, FOREACH( m, activeMSList ), CODE: {
   [IF( json.isEmpty( jPTM ) ): jPM = ""; jPM = json.get( jPTM, m ) ]
   [IF( json.isEmpty( jPM ) ): tTip = json.get( json.get( BonusTypedItems, m ), "tip" );tTip = json.get( jPM, "tip" ) ]
   [ tCat = json.get( json.get( BonusTypedItems, m ), "cat" )]
   [ tState = json.get( json.get( BonusTypedItems, m), "state")]
   [H, if(tState != "NA"), code: {
      [H: setState(tState,1)]
      [H: stateImage = strformat("<img src='%s' width=50 height=50>",getStateImage(tState))]
   };{
      [H: stateImage = " "]
   }]     
   [IF(tCat == "" || tCat == "Misc"): tCat = "Item"]
   [H: tTip = strformat('<span title="<html><table><tr valign=top><td>%{stateImage}</td><td>%{tTip}</td></tr></table></html>">%{m}</span>')]
   [H: output = json.append(output,strformat('<tr id="%s"><td style="padding: 0px 2px 0px 5px;text-align:right"><b>%{tCat}:</b></td><td style="padding-right: 5px">%{tTip}</td></tr>',lower(tCat+" "+m)))]
}]

[H: numConditions = tbl("Conditions",0)]
[H, for(i,0,numConditions), code: {
   [H: conditionStr = tbl("Conditions",i + 1)]
   [H: curState = listGet(conditionStr,0,";")]
   [H, if(getState(curState)), code: {
      [H: conditionText = replace(listGet(conditionStr,1,";"),"%","%%")]
      [H: stateImage = "'"+getStateImage(curState)+"'"]
      [H: tTip = strformat('<span title="<html><table><tr valign=top><td><img src=%{stateImage} width=50 height=50></td><td>%{conditionText}</td></tr></table></html>">%{curState}</span>')]
      [H: output = json.append(output,strformat('<tr id=" %s"><td style="padding: 0px 2px 0px 5px;text-align:right"><b>Condition:</b></td><td style="padding-right: 5px">%{tTip}</td></tr>',lower(curState)))]
   };{}]
}]

[H: output = json.sort(output,"a")]
[R,S, if(! json.isEmpty(output)): '<table style="background-color:black"><tr><td style="padding:1pt"><table style="background-color:white"><tr><th colspan=2 style="color:blue;text-align:center">Mod Report</th></tr>' + json.toList(output,"") + "</table></td></tr></table>"; "<b>Mod Report: No mods to report.</b>"]

!! 
Also, this is a handy update to the Campaign Macro "Edit Char" where it will change a token who is going to be edited to the correct token type.
||| Edit Char |||

Code: Select all

[H: ids = getSelected()]
[H: abort(if(ids == "", 0, 1))]

[H: tLib = "Lib:libDnD35Pathfinder" ]
[H: tokenType = getPropertyType(ids)]
[H: system = getLibProperty("system","Lib:GlobalsSRDPF")]
[H, if(system == "D&D3.5"): system = "DnD35"]
[H, if(system != tokenType):  setPropertyType(system,ids)]

[H: cancel = input(
   "tChoice|Core (Level; Stats; BAB; Saves; DR/ER; Race; Feats), Speed/Movement, Skills, Weapons, Activate Mods (toggle effects), Equip Items, Edit Items, Clear All Mods, Armor (Legacy: It is better to use Worn Items), Temp Mods (Legacy: It is better to use Active Mods), Plothos Spell Manager, Wrathgon Spell Manager|Elements to Edit|RADIO|ORIENT=V"
)]
[H: abort( cancel ) ]

[SWITCH( tChoice ), CODE:
   case 0: { [MACRO("editMain@"+tLib): "Page=Main"] [H: abort(0)] };
   case 1: { [MACRO("editSpeed@"+tLib): "Page=Speed"] };
   case 2: { [MACRO("editSkills@"+tLib): "Page=Skills"] };
   case 3: { [MACRO("editWeapons@"+tLib): "Page=Weapons"] [H: abort(0)] };
   case 4: { [MACRO( "subMultiModToggle@"+tLib ): "" ] };
   case 5: { [MACRO( "subCheckMods@"+tLib ): json.set( "{}", "modType", 1 ) ] };
   case 6: { [MACRO( "subModEdit@"+tLib ): json.set( "{}", "modType", 1 ) ] };
   case 7: { [MACRO("subClearAllMods@"+tLib): ""] };
   case 8: { [MACRO("editArmor@"+tLib): "Page=Armor"] };
   case 9: { [MACRO("editTempMods@"+tLib): "Page=Main"] };
   case 10: { [H, MACRO("Spell Main@Lib:spells"): ""] };
   case 11: { [H, MACRO("Spell Main@Lib:Magic"): ""] };
   default: {}
] 
There was a minor bug when adding and removing channel ability from a token. Here's the fix:
||| TurnUndeadDnD35 |||

Code: Select all

@@ @TurnUndeadDnD35
[H, if(! json.isEmpty(macro.args)), code: {
   [H: id = json.get(macro.args,0)]
   [H, if(id == 0): targs = "[]"; targs = macro.args]
   [H: numArgs = json.length(targs)]
   [H, if(numArgs >= 2): energyAmount = json.get(targs,1);energyAmount = 1]
   [H, if(numArgs >= 3): turnUndead = json.get(targs,2); turnUndead = 0]   
   [H: skipInput = 1]
   [H: ttip = ""]
   [H: tout = "No channeling available"]
};{
   [H: assert(0,"<b>Channel: Must have at least 1 argument passed.</b>",0)]
}]
[H, if(json.isEmpty(targs)), code: {
   [H: id = if(json.isEmpty(currentToken()),getSelected(),currentToken())]
   [H: skipInput = 0]
};{}]
[H, if(json.isEmpty(id)): abort(0)]
[H: switchToken(id)]
[H: TurnLevel = getStrProp(Levels, "TurnLevel")]
[H: TurnLevel = if(TurnLevel == "", 0, eval("0+" + TurnLevel))]
[H: currentTurns = number("0"+getStrProp(Daily, "ChannelEnergy"))]
[H, if(ChannelEnergy): MaxTurns = ChannelEnergy + ChaB; MaxTurns = 0]
[H: turnsRemaining = MaxTurns - currentTurns]

[H, if(! skipInput), code: {
   [H, if(TurnLevel), code: {
      [H: turnUndead = 1]
      [H: energyAmount = 0]
      [H, if(currentTurns < MaxTurns): abort(input("turnUndead|Channel Energy,Turn Undead|Pick One or Cancel|RADIO|SPAN=TRUE ORIENT=H SELECT=1",
         "energyAmount|1|Energy/Turns Used|TEXT|WIDTH=6"))]
   };{
      [H: turnUndead = 0]
      [H: energyAmount = 0]
      [H, if(currentTurns < MaxTurns): abort(input("energyAmount|1|Energy Channelled|TEXT|WIDTH=6"))]
   }] 
}]
[H, if(! isNumber(energyAmount)): energyAmount = 0]

[H, if(turnUndead && energyAmount && turnsRemaining), code: {
   [H: energyAmount = 1]
   [H: KnowledgeReligion = 0]
   [H: religionID = json.get(table("SysLocale", 0), "religion")]
   [H: numSkills = json.length(SkillsJ)]
   [H, FOR(i, 0, numSkills), CODE: {
      [cSkill = json.get(SkillsJ, i)]
      [H, IF(json.contains(cSkill, "fullname")): skN = json.get(cSkill, "fullname"); skN = json.get(cSkill, "name")]
      [IF(json.contains(cSkill, "subcat")): subcat = json.get(cSkill, "subcat"); subcat = ""]
      [IF(skN == "Knowledge" && isNumber(subcat)): foundKR = if(subcat == religionID, 1, 0); foundKR = if(lower(subcat) == lower(table("SysLocale", religionID)), 1, 0)]
      [IF(skN != "Knowledge"): foundKR = 0]
      [IF(foundKR): KnowledgeReligion = json.get(cSkill, "rank")]
   }]
   [H: turnBonus = if(KnowledgeReligion > 4, 2, 0)]
   [H: TurnRoll = 1d20]
   [H: DamageRoll = 2d6]
   [H: ttres = TurnRoll + ChaB + turnBonus]
   [H: mhd = tbl("TurnUndead", ttres)]
   [H: mhd = eval(mhd)]
   [H: tableBonus = mhd - TurnLevel]
   [H: turnDamage = DamageRoll + TurnLevel + ChaB]

   [H: tout = strformat("<b>Turn Undead: </b>Turned <b>%{turnDamage} HD</b> (max %{mhd} HD each)")]
   [H: ttip = strformat("<table><tr><td>Turn Check (table lookup):</td><td>Roll (%{TurnRoll}) + ChaB(%{ChaB}) + Bonus(%{turnBonus}) = %{ttres}</td></tr>
      <tr><td>Max Turn Level:</td><td>Turn Level (%{TurnLevel}) + Table Bonus (%{tableBonus}) = %{mhd} HD each</td></tr>
      <tr><td>Turn Damage:</td><td>Turn Level (%{TurnLevel}) + 2d6 (%{DamageRoll}) + ChaB(%{ChaB}) = %{turnDamage} HD turned</td></tr>
      <tr><td>&nbsp</td></tr>")]
   [H: currentTurns = currentTurns + energyAmount]
};{}]

[H, if(! turnUndead && energyAmount), code: {
   [H, if(energyAmount <= turnsRemaining), code: {
      [H: tout = strformat("<b>Channel Energy:</b> %{energyAmount} Turn(s) used")]
      [H: currentTurns = currentTurns + energyAmount]
   };{
      [H: tout = "<b>Channel Energy:</b> Not enough Energy"]
      [H: energyAmount = 0]
   }]
   [H: ttip = "<table>"]
};{}]

[H, if( turnUndead && turnsRemaining <= 0), code: {
   [H: tout = "<b>Turn Undead:</b> Out of Turns."]
   [H: ttip = "<table>"]
};{}]

[H: ttip = ttip + strformat("<tr><td>Turn Level:</td><td>%{TurnLevel}</td></tr>
   <tr><td>Energy/Turns Used:</td><td>%{energyAmount}</td></tr>
   <tr><td>Total Used Today:</td><td>%{currentTurns}</td></tr>
   <tr><td>Max Energy/Turns:</td><td>%{MaxTurns}</td></tr></table>")]
[R: strformat('<span title="<html>%{ttip}</html>">%{tout}</span>')]
[H: Daily = setStrProp(Daily, "ChannelEnergy", currentTurns )]

!! 
Here's a quick simple update to handle Invis Move. As a side note, you could keep the original image instead of copying the blank image since we now have Visible to Owners Only. The only non-functional thing about using an object and the notes for the stats is if a seen token is on top... can't click for the notes below. I haven't thought of a good solution for that though.
||| onTokenMove |||

Code: Select all

@@ @onTokenMove
@PROPS@ fontColor=white ; autoExecute=true ; fontSize=11pt ; sortBy= ; color=red ; playerEditable=true ; applyToSelected=false ; group= ; tooltip= ; minWidth= ; 
[H, token(currentToken()), if(isNPC() && getState("Invisible")), code: {
   [H, MACRO("InvisibleMove@Lib:libDnD35Pathfinder"): ""]
}; {}]

!! 

User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by lmarkus001 »

darn YOUR EYES! :wink: (Interestingly, what is written is not what is shown here...)

Good changes those, I will work them in for this next release (why is soon always later?)

neofax
Great Wyrm
Posts: 1694
Joined: Tue May 26, 2009 8:51 pm
Location: Philadelphia, PA
Contact:

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by neofax »

@Lindsay: Would it be possible to add the type of weapon to the weapon input dialog? i.e. Natural, Magic, Bludgeoning, Piercing, Slashing, Ranged... This way I can connect into the attack dialog and have a Fumble roll on the fumble deck. Also, to verify if DR is needed to be applied.
Image
Time-Zone information UTC -5

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

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by aliasmask »

neofax wrote:@Lindsay: Would it be possible to add the type of weapon to the weapon input dialog? i.e. Natural, Magic, Bludgeoning, Piercing, Slashing, Ranged... This way I can connect into the attack dialog and have a Fumble roll on the fumble deck. Also, to verify if DR is needed to be applied.
That's a can-o-worms.

Code: Select all

dmgType(slash,pierce,blunt,spell), material(steel, cold iron, adamantine, mithral, force, fire, acid, sonic, cold, electricity, death, negative, positive, good, evil, law, chaos, bane, light, magic, other)

neofax
Great Wyrm
Posts: 1694
Joined: Tue May 26, 2009 8:51 pm
Location: Philadelphia, PA
Contact:

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by neofax »

True, but I am not asking to auto adjudicate the damage. I am just looking for something similar to how the extra damage is done now. Granted, I could probably do it how I do it now by placing a "(P)" in the description of the weapon. I was trying to make it easier on me later when I try to code the fumble and critical rolls.
Image
Time-Zone information UTC -5

User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by lmarkus001 »

neofax wrote:@Lindsay: Would it be possible to add the type of weapon to the weapon input dialog? i.e. Natural, Magic, Bludgeoning, Piercing, Slashing, Ranged... This way I can connect into the attack dialog and have a Fumble roll on the fumble deck. Also, to verify if DR is needed to be applied.
This is the kind of thing that would be part of a major overhaul of the weapons, equip-sets, combat dialogs. I am VERY loathe to continue overloading my original combat mechanics (I keep adding in stupid feats even with this loathing).

As an aside, the list you gave contains differing parameters for a weapon or attack. This gets further complicated with the fact that weapons need mod-sets and attack-sets need mod-sets (you could have an enchantment that gives a weapon +1 to hit and damage, or you could have an enchantment that makes you bigger so some weapons might need to be size adjusted).

Damage Type: Bludgeoning, Piercing, Slashing
Magic Type: Bane, Light, Magic, Wounding
Material Type: Adamantine, Cold Iron, Force, Silver
Energy Type: Acid, Cold, Fire, Lightning, Negative, Positive, Sonic
Alignment Type: Law, Chaos, Good, Evil
Alchemical Type: Disease, Poison
Size Type: Fine, Diminutive, Tiny, Small, Medium, Large, Huge, Gargantuan, Colossal


These 2 are already available:
Proximity Type: Melee, Ranged
But this would be further modified by the equip-set or attack dialog as a dagger can be melee or ranged but the actual attack would define if you are stabbing or tossing.

Manufactured: Natural, Manufactured

User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by lmarkus001 »

Oh yeah, and the Weapon0 entries are not JSONs so it gets really messy having and array within a list-array. So at a coding level this is a fair bit of effort or compromise for limited return.

User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by lmarkus001 »

aliasmask wrote:
Also, this is a handy update to the Campaign Macro "Edit Char" where it will change a token who is going to be edited to the correct token type.
||| Edit Char |||

Code: Select all

[H: ids = getSelected()]
[H: abort(if(ids == "", 0, 1))]

[H: tLib = "Lib:libDnD35Pathfinder" ]
[H: tokenType = getPropertyType(ids)]
[H: system = getLibProperty("system","Lib:GlobalsSRDPF")]
[H, if(system == "D&D3.5"): system = "DnD35"]
[H, if(system != tokenType):  setPropertyType(system,ids)]

[H: cancel = input(
   "tChoice|Core (Level; Stats; BAB; Saves; DR/ER; Race; Feats), Speed/Movement, Skills, Weapons, Activate Mods (toggle effects), Equip Items, Edit Items, Clear All Mods, Armor (Legacy: It is better to use Worn Items), Temp Mods (Legacy: It is better to use Active Mods), Plothos Spell Manager, Wrathgon Spell Manager|Elements to Edit|RADIO|ORIENT=V"
)]
[H: abort( cancel ) ]

[SWITCH( tChoice ), CODE:
   case 0: { [MACRO("editMain@"+tLib): "Page=Main"] [H: abort(0)] };
   case 1: { [MACRO("editSpeed@"+tLib): "Page=Speed"] };
   case 2: { [MACRO("editSkills@"+tLib): "Page=Skills"] };
   case 3: { [MACRO("editWeapons@"+tLib): "Page=Weapons"] [H: abort(0)] };
   case 4: { [MACRO( "subMultiModToggle@"+tLib ): "" ] };
   case 5: { [MACRO( "subCheckMods@"+tLib ): json.set( "{}", "modType", 1 ) ] };
   case 6: { [MACRO( "subModEdit@"+tLib ): json.set( "{}", "modType", 1 ) ] };
   case 7: { [MACRO("subClearAllMods@"+tLib): ""] };
   case 8: { [MACRO("editArmor@"+tLib): "Page=Armor"] };
   case 9: { [MACRO("editTempMods@"+tLib): "Page=Main"] };
   case 10: { [H, MACRO("Spell Main@Lib:spells"): ""] };
   case 11: { [H, MACRO("Spell Main@Lib:Magic"): ""] };
   default: {}
] 
This is only so-so ok. I will add in a dialog asking if the person really means to do this, and if so it will REBUILD the skills on the token.

The reason is, when I coded the skills, they were system specific. If you swap systems, the list of skills will still be based on the system you swapped from. So the undesired ones need to be removed from the JSON and the desired ones need to be added in. This approach would still require the skills to be edited, but would preserve those skills that the systems have in common.

This will take a bit to code up so am not certain it will make this release.

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

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by aliasmask »

I use this mostly for new tokens rather than converting a token. New tokens drop as basic and need to be changed before being edited. You can skip the dialog and conversion and just check the type for "basic" if you want some error checking added.

User avatar
Azhrei
Site Admin
Posts: 12086
Joined: Mon Jun 12, 2006 1:20 pm
Location: Tampa, FL

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by Azhrei »

lmarkus001 wrote:darn YOUR EYES! :wink: (Interestingly, what is written is not what is shown here...)
Heh, I know how that is. I spend hours updating my course material only to have a student spot a typo in the first 15 minutes of class. (Sigh.)

If you're doing cleanup, I could use the following:

1. Ensure that tooltips never contain the same kind of quote used in the title attribute. While the Java library seems to deal with it okay somehow (?), a web browser won't. So if the final HTML will be <span title="..."> then the tooltip should only use single quotes, and a double quote should be represented as " (I think that's the right one).

2. Set the nesting of HTML elements to be consistent. Again, this doesn't matter for the display in the chat window, but I'm interested in processing the chat log's HTML for display in a web browser. In this case, I'd like to be able to search for text by using the nested elements as a pattern, such as the CSS selector td b font span. But the nesting is different in different places and that complicates things. Technically the title attribute shouldn't contain < and >, but < and >. But man, that would look ugly!

3. As an alternative to #2, add a class attribute on all <span> elements to identify what it contains. I've noticed, for example, that the string "Primary Target:" of the attack field has a separate (but identical) tooltip as the actual attack output itself. This bulks up the HTML unnecessarily, but more importantly it means I can't just scan the HTML looking for title attributes to identify pieces. If those elements had class attributes I could scan for that and ignore everything else. I'm thinking of classes like class="player secret attack" or class="gm secret skillcheck". It might be easiest to use player/gm and then the name of the macro that generated it. This would let me strip out GM tooltips that I don't want players to see when I post my chat log on a web site somewhere. ;) (I currently do this now with a convoluted JavaScript function that has a lot of "special cases" in it.)

4. Only use an id with a particular value once. There are spots in the Mod Report (I think) that contain <tr id="..."> where the id can be duplicated, if not in the same mod report then in the next mod report when it gets printed. That's a no-no in HTML terms. If they were changed to class="..." that would solve the validation error and could still be useful in other ways. (Note that having an id is not currently useful at all within MT.)

But I'll use whatever you put out! It's a great FW and saves me a huge amount of time! Thanks, Lindsay!

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

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by aliasmask »

Azhrei wrote:1. Ensure that tooltips never contain the same kind of quote used in the title attribute. While the Java library seems to deal with it okay somehow (?), a web browser won't. So if the final HTML will be <span title="..."> then the tooltip should only use single quotes, and a double quote should be represented as " (I think that's the right one).
For tooltip text, before inserting in between the quotes I just replace quotes with " Works well for me. I never put code strings in the html, I'll process those before hand and maybe do this [r: varName], but not this [r: "string"+varName].
Azhrei wrote:4. Only use an id with a particular value once. There are spots in the Mod Report (I think) that contain <tr id="..."> where the id can be duplicated, if not in the same mod report then in the next mod report when it gets printed. That's a no-no in HTML terms. If they were changed to class="..." that would solve the validation error and could still be useful in other ways. (Note that having an id is not currently useful at all within MT.)
Id is something I added for use with the sort. I believe the ids will be unique because I put the "type" of mod at the beginning. Before, a condition may appear twice, but the id would be different for the second because "state" was added to the beginning of id name. I did this for grouping with the sort. But... using class would have the same effect as using id.

User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by lmarkus001 »

@Azhrei

Oh sure, and next you will want documentation!

This is good input. A lot of what I did was just trying to get MapTools to output something close to what I desired. Once I got there I tended to stop fiddling and did not do cleanup.

I want to get the current lot out (as it resolves issues with r02 and adds major new functionality) but I will keep this list about for future modifications.

User avatar
Azhrei
Site Admin
Posts: 12086
Joined: Mon Jun 12, 2006 1:20 pm
Location: Tampa, FL

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by Azhrei »

Oh yeah, this is by no means important! I've got my Perl script tweaked to take all this into account so I've got it automated as-is.

Thought of another one:

5. Ensure all attributes have some type of quotes (require by HTML 4 Strict and XML) and no spaces around the equals sign. I bring this one up because there are a couple spots with "font size= 5" and again, that messes up the display in a browser. (At least, in a standards compliant browser. :))

And no, I don't need no stinkin' documentation! :mrgreen:

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

Re: MT1.3b86.03 Campaign Framework (COMING SOON)

Post by aliasmask »

Small request. Can you update the weapon default values for OHLight to 2. Many beginning players and GMs leave that value at 0 configuring the weapon incorrectly and wonder why they have a -6 to attack. This was a source of great confusion for some people in recent weeks and they assumed the macros didn't work right.

Post Reply

Return to “D&D 3.5/Pathfinder 1e Campaign Macros”