Editable Character Sheet For Token Owners Only - Solved

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

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

User avatar
Oriet
Cave Troll
Posts: 30
Joined: Mon Dec 05, 2011 10:58 am
Location: Somewhere that's not there, but not really here.
Contact:

Editable Character Sheet For Token Owners Only - Solved

Post by Oriet »

I've been really kicking up the complexity of my macros the last couple weeks, as I find I can do more with them and keep things more streamlined for ease of use to players (I have two people new to gaming in my campaign, so that's of definite consideration) and to speed up combat results. I'm fairly satisfied with my attack macros (especially since I've gotten help to have a stack size that can handle all of the options) and have since been working on making a character sheet.

I've been using [wiki]Forms_tutorial[/wiki] and [wiki]Introduction_to_Dialogs_and_Frames[/wiki] quite a bit for this, and I now have a nice looking character sheet with editable fields and 3 tabs (at least so far, need to do something for armour and weapons still) using a [wroll]frame[/wroll]. However, I want to make it so that only those who have ownership of a token can view and edit the character sheet for the token.

I've been able to fanangle things in so that it won't let you open the character sheet when you don't have ownership of the selected token, however the [wiki]onChangeSelection[/wiki] seems to go around that as when the character sheet frame is open and another token is selected it updates with that token's data, and changes to take effect, even when they do not have ownership of the token. Or at least I think I managed to do that... it might be something unrelated to what I did as I didn't test as a player until I tried implementing it.

Obviously I won't be able to get assistance if I don't include the macros, so here they are.
[spoiler=openCharacterSheet]

Code: Select all

[h: link = macroLinkText("[email protected]:Combat", "none")]   
[frame("CharacterSheet"): {
   [h: page = getStrProp(macro.args, "Page")]
   [h,if(page==""): page="Main"]
   <html>
   <head>
      <link rel="onChangeSelection" type="macro" href="[r:link]">
      <link rel="stylesheet" type="text/css" href="[email protected]:Combat"></link>
   </head>
   <body>
      [r,macro("[email protected]:Combat"): page]
      <br>
      [r,macro("characterSheet"+page+"@Lib:Combat"): getSelected()]
   </body>
   </html>
}]
[/spoiler]
[spoiler=charSheetcss]

Code: Select all

.odd { background-color: #FFFFFF }
.even { background-color: #EEEEAA }
th { background-color: #113311; color: #FFFFFF }
.page a {
   background-color: #5555CC;
   color: white;
}
.currentPage a {
   background-color: #7777FF;
   color: white;
}
[/spoiler]
[spoiler=charSheetHeader]

Code: Select all

[h: currentPage = macro.args]
[h: pages = "Main,GeneralSkills,SpecialisedSkills"]
<table>
   <tr>
   [foreach(page, pages,""), code: {
      [h,if (page == currentPage): class="currentPage" ; class="page"]
      [h: callback = "[email protected]:Combat"]
      <td class="[r: class]">
         [r: macroLink(page, callback, "none", "Page="+page)]
      </td>
      }]
   </tr>
</table>
[/spoiler]
[spoiler=characterSheetMain]

Code: Select all

[h: id = macro.args]
[r, if(listCount(id)!=1), code: {};{
   [h: link = macroLinkText("[email protected]:Combat", "all")]
   <form action="[r:link]" method="json">
   <input type="hidden" name="id" value="[r:id]">
   <table>
      <td>
         <img src='[r,token(id): getTokenImage(75)]'></img>
      </td>
      <td>
         <h1> [r:getName(id)]</h1>
      </td>
   </table>

<table>
   <tr>
   <table>
   <td>
      <table>
         <tr>
            <th colspan="*">Attribute</th>
            <th colspan="*">Score</th>
            <th colspan="*">Mod</th>
         </tr>

         [h: attributes = "Str, Dex, Con, Int, Wis, Cha"]
         [h: row = "odd"]
         [h: abilScores = getProperty("AbilityScores", id)]
         [r,foreach(attrib, attributes, ""),code: {
            <tr class="[r:row]">
               <td><b>[r:attrib]</b></td>
               <td><input type="text" name="[r:attrib]" value="[r:getStrProp(abilScores, attrib)]" size="3" align="right"></td>
               <td>[r:getStrProp(getProperty("AbilityModifiers", id), attrib)]</td>
            </tr>
            [h: row = if(row=="odd", "even", "odd")]
         }]
      
         [h: savey = getProperty("SaveBonuses", id)]
         [h: fort1 = getStrProp(savey, "Fort")]
         [h: fort2 = fort1 + getStrProp(getProperty("AbilityModifiers", id), "Con")]
         [h: ref1 = getStrProp(savey, "Ref")]
         [h: ref2 = ref1 + getStrProp(getProperty("AbilityModifiers", id), "Dex")]
         [h: will1 = getStrProp(savey, "Will")]
         [h: will2 = will1 + getStrProp(getProperty("AbilityModifiers", id), "Wis")]
         <th colspan="*">Save</th>
         <th colspan="*">Total</th>
         <th colspan="*">Mod</th>
         <tr class="even">
            <td><b>Fortitude</b></td>
            <td>[r: fort2]</td>
            <td><input type="text" name="reflexSave" value="[r: fort1]" size="3" align="right"></td>
         </tr>
         <tr class="odd">
            <td><b>Reflex</b></td>
            <td>[r: ref2]</td>
            <td><input type="text" name="reflexSave" value="[r: ref1]" size="3" align="right"></td>
         </tr>
         <tr class="even">
            <td><b>Will</b></td>
            <td>[r: will2]</td>
            <td><input type="text" name="reflexSave" value="[r: will1]" size="3" align="right"></td>
         </tr>
      </table>
   </td>
   
   <td>
      <table>
      <tr>
         [h: hpVar = getStrProp(getProperty("HP", id), "Base")]
         <th colspan="3">Secondary Attributes</th>
         <tr class="even">
            <td><b>Max Hit Points</b></td>
            <td><input type="text" name="health" value="[r:hpVar]" size="3" align="right"><td>
         </tr>
         
         [h: forcey = getProperty("MaxFP", id)]
         <tr class="odd">
            <td><b>Max Force Points</b></td>
            <td><input type="text" name="force" value="[r:forcey]" size="3" align="right"><td>
         </tr>
      </tr>
         
      <tr>
         [h: baseDef = getStrProp(getProperty("Defence", id), "Base")]
         [h: flatDef = getStrProp(getProperty("Defence", id), "Flat")]
         <th colspan="3">Defence</th>
         <tr class="odd">
            <td><b>Base</b></td>
            <td><input type="text" name="baseDefence" value="[r:baseDef]" size="3" align="right"></td>
         </tr>
         <tr class="even">
            <td><b>Flat-footed</b></td>
            <td><input type="text" name="baseDefence" value="[r:flatDef]" size="3" align="right"></td>
         </tr>
         
         <tr>
            [h: baseAB = getProperty("BAB", id)]
            [h: numHD = getProperty("HitDiceCount", id)]
            [h: forceLvl = getProperty("ForceLevel", id)]
            [h: auraVal = getProperty("ForceAuraValue", id)]
            <th colspan="3">Misc</th>
            <tr class="even">
               <td><b>Num. of Hit Dice</b></td>
               <td><input type="text" name="charHD" value="[r:numHD]" size="3" align="right"></td>
            </tr>
            <tr class="odd">
               <td><b>Base Attack Bonus</b></td>
               <td><input type="text" name="baseAttack" value="[r:baseAB]" size="3" align="right"></td>
            </tr>
            <tr class="even">
               <td><b>Force User Level</b></td>
               <td><input type="text" name="forceHD" value="[r:forceLvl]" size="3" align="right"></td>
            </tr>
            <tr class="odd">
               <td><b>Force Aura Value</b></td>
               <td><input type="text" name="ForceAura" value="[r: auraVal]" size="3" align="right"></td>
            </tr>
         </tr>
      </tr>
   </td>
   </table>
</table>

   <input type="submit" name="edit_btn" value="Submit changes">
   </form>
}]
[/spoiler]
I think that's all of the macros in the set needed for figuring out how to get it so only token owners can view and thus edit the character sheet for a token. If not I'll post the rest of it, but I don't think it'll have any influence on the aspect I want.

Oh, and here are the token properties being used:
[spoiler=properties]

Code: Select all

AbilityScores:Str=10 ; Dex=10 ; Con=10 ; Int=10 ; Wis=10 ; Cha=10 ;
AbilityModifiers:Str=0 ; Dex=0 ; Con=0 ; Int=0 ; Wis=0 ; Cha=0 ;
Experience
• Combat •
InitiativeModifiers:0
*@Def:{getStrProp(Defence, "Base")}, Flat {getStrProp(Defence, "Flat")}, CMD {CMD}
Defence:Base=13 ; Flat=13 ;
*@Hardness:0
ArmourCheckPenalty:0
HitDiceCount:1
*@HitPoints:{getStrProp(HP, "Current")}/{getStrProp(HP, "Base")}, nonlethal {getStrProp(HP, "NL")}
HP:Base=10 ; Current=10 ; NL=0 ;
CMD:10
CMB:0
ForceLevel
MaxFP
FP
*@ForcePoints:{FP}{if(MaxFP != "", "/", "")}{MaxFP}
SaveBonuses:Fort=0 ; Ref=0 ; Will=0 ;
DefensiveAbilities
BAB:0
*@Movement:Walk {getStrProp(Move, "Base")}, Run {getStrProp(Move, "Max")}
Move:Base=30; Max=120
*ForceAura:Neutral
ForceAuraValue:0
• Skill Modifiers Excluding Ability & Armour Mods •
Acrobatics:0
Appraise:0
Astrogate:0
Bluff:0
Climb:0
ComputerUse:0
Craft1:Mod=0 ; Speciality= ;
Craft2:Mod=0 ; Speciality= ;
Craft3:Mod=0 ; Speciality= ;
Craft4:Mod=0 ; Speciality= ;
Demolitions:0
Diplomacy:0
DisableDevice:0
Disguise:0
Enertain1:Mod=0 ; Speciality= ;
Enertain2:Mod=0 ; Speciality= ;
EscapeArtist:0
Gamble:0
HandleAnimal:0
Intimidate:0
Knowledge1:Mod=0 ; Speciality= ;
Knowledge2:Mod=0 ; Speciality= ;
Knowledge3:Mod=0 ; Speciality= ;
Knowledge4:Mod=0 ; Speciality= ;
Linguistics:0
Perception:0
Repair:0
Ride:0
SenseMotive:0
SleightOfHand:0
Stealth:0
Survival:0
Swim:0
TreatInjury:0
VehicleOperation:0
• Miscellaneous •
MaxShieldPoints
*@ShieldPoints
*@ShieldResistance
DeadlyAim:no
RapidShot:no
PointBlankShot:no
PreciseShot:no
Multishot:no
PowerAttack:no
Flurry:no
[/spoiler]

(Any suspicions about it looking like a Pathfinder based Star Wars game are correct, utilising a rules set I created and am beta-ing.)
Last edited by Oriet on Fri Mar 02, 2012 1:16 pm, edited 1 time in total.
Kill them all, and let the Game Master grant the exp!

ImageImage

User avatar
aliasmask
Deity
Posts: 8667
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Editable Character Sheet For Token Owners Only

Post by aliasmask »

Your onChangeSelection should call another macro that will determine if the character sheet frame should be updated. Take a look at this thread: viewtopic.php?f=20&t=19911#p213389 It may have the tools you're looking for. The macro openSelectFrame I'm thinking of making it a toolbar which will have player info, but doesn't update anything. It'll just be there as a monitor of data and provide buttons to run certain things, like opening and editing character sheets.

User avatar
jfrazierjr
Deity
Posts: 5176
Joined: Tue Sep 11, 2007 7:31 pm

Re: Editable Character Sheet For Token Owners Only

Post by jfrazierjr »

My one suggestion (this is really for any macro writer)... if you plan to or thing you might ever possibly add in someone else's framework to your own, I would highly suggest making your variable names use some type of pre/post fix. That way, if someone else's framework you are using does something with a variable named HP(just for example), then it won't clobber your character data!!!(and even worse, it may take you hours or days of time figuring out why)
I save all my Campaign Files to DropBox. Not only can I access a campaign file from pretty much any OS that will run Maptool(Win,OSX, linux), but each file is versioned, so if something goes crazy wild, I can always roll back to a previous version of the same file.

Get your Dropbox 2GB via my referral link, and as a bonus, I get an extra 250 MB of space. Even if you don't don't use my link, I still enthusiastically recommend Dropbox..

User avatar
aliasmask
Deity
Posts: 8667
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Editable Character Sheet For Token Owners Only

Post by aliasmask »

jfrazierjr wrote:My one suggestion (this is really for any macro writer)... if you plan to or thing you might ever possibly add in someone else's framework to your own, I would highly suggest making your variable names use some type of pre/post fix. That way, if someone else's framework you are using does something with a variable named HP(just for example), then it won't clobber your character data!!!(and even worse, it may take you hours or days of time figuring out why)

I kind of do the exact opposite of what you suggest, but it's the same concept. I make my visible token properties have prefixes, like stat.strength or sheet.hp. I do give the stat sheet properties alias's though so players don't see the dot notation. I only use the token properties in the token type for things to be visible on the stat sheet. I just got used to using getProperty, setProperty instead of directly referring to a token property. That way I never have to rely on a token having the correct token type.

User avatar
wolph42
Deity
Posts: 9852
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Editable Character Sheet For Token Owners Only

Post by wolph42 »

jfrazierjr wrote:My one suggestion (this is really for any macro writer)... if you plan to or thing you might ever possibly add in someone else's framework to your own, I would highly suggest making your variable names use some type of pre/post fix. That way, if someone else's framework you are using does something with a variable named HP(just for example), then it won't clobber your character data!!!(and even worse, it may take you hours or days of time figuring out why)


wise words!

Oriet wrote:I've been able to fanangle things in so that it won't let you open the character sheet when you don't have ownership of the selected token, however the [wiki]onChangeSelection[/wiki] seems to go around that as when the character sheet frame is open and another token is selected it updates with that token's data, and changes to take effect, even when they do not have ownership of the token. Or at least I think I managed to do that... it might be something unrelated to what I did as I didn't test as a player until I tried implementing it.


I use a macro frame in my framework that shows macro buttons that are related to the token currently selected. If you do NOT own the token, the sheet draws a blank with a small message explaining why. I guess thats what you're looking for.

You can have a look. Link in my sig (FW), select the 'Dark heresy' token on the selection panel at the top there is a macro 'macrobuttonscombat' which gets called by the onchangeselection. check that one out. Ill post that code here, the related macros is calls can be found in the same section of the panel.

[spoiler=here's the code]

Code: Select all

[h:'<!-- MacroButtonsCombat (rebuild, token.name) -->']
[
h, if(argCount() > 1): me = arg(1); me = getSelectedNames()]

[
h:'<!-- Check if only one token is selected -->']
[
h,if(listCount(me) != 1), CODE:{
    [emptyFrame()]
    [abort(0)]
};{
    [switchToken(me)]
}]

[
h:'<!-- Check if token is a vehicle if so switch to other macro panel -->']
[
h: proptype = getPropertyType()]

[
h:'<!-- Check strict token ownership and if turned on if the user owns the token -->']
[
H: '<!-- retrieve setting: strictTokenOwnership -->']
[
h:varsFromStrProp(getLibProperty('fwSettings','lib:DH'))]

[
h, if(strictTokenOwnership && !isGM()), CODE:{
      [if(!isOwner() && (proptype == "Character" || proptype == "Horde" || proptype == "Vehicle")): proptype = "notOwner"]
};{}]

[
h,if(proptype=="Character" || proptype =="Horde"), CODE:{
    [h, if(argCount() > 0): rebuild = arg(0); rebuild = 0]
    [h, if(json.type(macroFrameCache)!="OBJECT" || rebuild), CODE:{
        [macroFrameCache = json.set("{}", me, encode(createMacroButtonsCombat(me)))]
    };{
        [if(json.fields(macroFrameCache) != me): macroFrameCache = json.set("{}", me, encode(createMacroButtonsCombat(me)))]
        [managementTab = ""] 
    
}]

    [frame("Macros", "width=300; height=420; temporary=0"): {
        [r:decode(json.get(macroFrameCache, me))]
    }]
};{
    [h,switch(proptype), CODE:
        case "Basic"    : {
            [updateToken()]
        };
        case "Vehicle"    : {
            [MacroButtonsVCombat()]
        };
        case "Ship"        : {
            [MacroButtonsSCombat()]
        };
        case "Grenade"    : {
            [MacroButtonsGrenade()]
        };
        case "notOwner"    : {
            [notAllowed()]
        };
        default        : {
            [emptyFrame()]
        }
    ]
}]
 
[/spoiler]

here the macros called 'MacroButtons..', 'notAllowed' and 'emptyFrame' are all different frames that are shown when appropriate. They all again contain an onchangeselection call which points back to macrobuttonscombat(). So when another token is selected the above routine runs again.

What the routine in general does is make a couple of checks (like only one token selected, which property type and isGM and who the owner and based on that through a switch picks the right routine.
I've build an if() statement around that to speed things up (as switch statements are slow) cause in most cases people will only select the 'right' token, which builds the panel faster.

User avatar
jfrazierjr
Deity
Posts: 5176
Joined: Tue Sep 11, 2007 7:31 pm

Re: Editable Character Sheet For Token Owners Only

Post by jfrazierjr »

aliasmask wrote:I kind of do the exact opposite of what you suggest, but it's the same concept. I make my visible token properties have prefixes, like stat.strength or sheet.hp. I do give the stat sheet properties alias's though so players don't see the dot notation. I only use the token properties in the token type for things to be visible on the stat sheet. I just got used to using getProperty, setProperty instead of directly referring to a token property. That way I never have to rely on a token having the correct token type.


wolph42 wrote:wise words!


So, is there anything on the wiki about using this approach? With the sheer number of frameworks, this could really bite the heck out of someone...while we can't force the old guard to fix their frameworks, it would be at least nice to warn new framework builders. Ultimately, the people who create the frameworks are the ones who will be getting the questions and complaints, so in the long run, it's likely well worth it to spend a few extra minutes up front doing this.

Honestly, though I don't do many macro's myself at all, I think rumble and aliasmask are the two people who I have seen use this approach fairly reliably, and that's where the thought's came from.

Ditto local variables.. as AM said.. he uses getProperty which would go very well with local variable prefixes(assuming a property named "HP"):

Code: Select all

[hloc_HP getProperty("HP)]
<!-- do some stuff with loc_HP, such as deal with temp HP, or whatever -->
[h: setProperty("
HP", loc_HP)]
I save all my Campaign Files to DropBox. Not only can I access a campaign file from pretty much any OS that will run Maptool(Win,OSX, linux), but each file is versioned, so if something goes crazy wild, I can always roll back to a previous version of the same file.

Get your Dropbox 2GB via my referral link, and as a bonus, I get an extra 250 MB of space. Even if you don't don't use my link, I still enthusiastically recommend Dropbox..

User avatar
Oriet
Cave Troll
Posts: 30
Joined: Mon Dec 05, 2011 10:58 am
Location: Somewhere that's not there, but not really here.
Contact:

Re: Editable Character Sheet For Token Owners Only

Post by Oriet »

First off, I have to admit I'm curious as to just what all a framework is. I've inferred that it's a (generally complex) campaign save to be used for running campaigns within those rules-sets, including macros, library tokens, properties, tables, and lots of other cool gadgets and doohickeys, so I will be using it to mean that in this post. Please correct me on it if I'm wrong (and it might be good to get the definition in the glossary of the Wiki).



jfrazierjr wrote:My one suggestion (this is really for any macro writer)... if you plan to or thing you might ever possibly add in someone else's framework to your own, I would highly suggest making your variable names use some type of pre/post fix. That way, if someone else's framework you are using does something with a variable named HP(just for example), then it won't clobber your character data!!!(and even worse, it may take you hours or days of time figuring out why)

I highly doubt I'll incorporate someone else's framework into this campaign, as I am using a lot of custom rules (custom criticals using a table of effects instead of multiplying damage, treating armour as hardness instead of a bonus to AC, custom classes though some are extremely influenced from KotOR, same with Force powers, and many other things) which means I'd have to customise anything I try to add in.

I will, however, take this into consideration for future frameworks for different systems, as my boyfriend is planning on running a Dark Heresy game for me and my room-mates utilising a bunch of rules customisation I had come up with, and he's having me make the framework as I understand it much better than him, have more patience for getting it to look nice and automate things, and generally have more time than him to do such as well. (Vulk, that's a run on sentence!) I'll try to incorporate doing that for that framework, and for future frameworks as well (including ones made for completely homebrewed systems I make), as it will also help ensure variable names are unique (found out the hard way that MapTool is not case sensitive).



aliasmask wrote:I kind of do the exact opposite of what you suggest, but it's the same concept. I make my visible token properties have prefixes, like stat.strength or sheet.hp. I do give the stat sheet properties alias's though so players don't see the dot notation. I only use the token properties in the token type for things to be visible on the stat sheet. I just got used to using getProperty, setProperty instead of directly referring to a token property. That way I never have to rely on a token having the correct token type.

I don't know if I'll do that for the hover over statsheet visible token properties, but that does sound like a good idea for other properties on tokens, even if just to keep track of what the property is for and how and where to use it. If I was to start using alias tokens I'd include it for visible properties as well, but I'm A)not sure how to use aliases, B)not having token file sizes large enough that it would speed things up much (especially as no one has reported noticeable lag), and C)don't think I'm putting in enough complexity (yet) for that.



wolph42 wrote:I use a macro frame in my framework that shows macro buttons that are related to the token currently selected. If you do NOT own the token, the sheet draws a blank with a small message explaining why. I guess thats what you're looking for.

You can have a look. Link in my sig (FW), select the 'Dark heresy' token on the selection panel at the top there is a macro 'macrobuttonscombat' which gets called by the onchangeselection. check that one out. Ill post that code here, the related macros is calls can be found in the same section of the panel.

[spoiler=here's the code]

Code: Select all

[h:'<!-- MacroButtonsCombat (rebuild, token.name) -->']
[
h, if(argCount() > 1): me = arg(1); me = getSelectedNames()]

[
h:'<!-- Check if only one token is selected -->']
[
h,if(listCount(me) != 1), CODE:{
    [emptyFrame()]
    [abort(0)]
};{
    [switchToken(me)]
}]

[
h:'<!-- Check if token is a vehicle if so switch to other macro panel -->']
[
h: proptype = getPropertyType()]

[
h:'<!-- Check strict token ownership and if turned on if the user owns the token -->']
[
H: '<!-- retrieve setting: strictTokenOwnership -->']
[
h:varsFromStrProp(getLibProperty('fwSettings','lib:DH'))]

[
h, if(strictTokenOwnership && !isGM()), CODE:{
      [if(!isOwner() && (proptype == "Character" || proptype == "Horde" || proptype == "Vehicle")): proptype = "notOwner"]
};{}]

[
h,if(proptype=="Character" || proptype =="Horde"), CODE:{
    [h, if(argCount() > 0): rebuild = arg(0); rebuild = 0]
    [h, if(json.type(macroFrameCache)!="OBJECT" || rebuild), CODE:{
        [macroFrameCache = json.set("{}", me, encode(createMacroButtonsCombat(me)))]
    };{
        [if(json.fields(macroFrameCache) != me): macroFrameCache = json.set("{}", me, encode(createMacroButtonsCombat(me)))]
        [managementTab = ""] 
    
}]

    [frame("Macros", "width=300; height=420; temporary=0"): {
        [r:decode(json.get(macroFrameCache, me))]
    }]
};{
    [h,switch(proptype), CODE:
        case "Basic"    : {
            [updateToken()]
        };
        case "Vehicle"    : {
            [MacroButtonsVCombat()]
        };
        case "Ship"        : {
            [MacroButtonsSCombat()]
        };
        case "Grenade"    : {
            [MacroButtonsGrenade()]
        };
        case "notOwner"    : {
            [notAllowed()]
        };
        default        : {
            [emptyFrame()]
        }
    ]
}]
  
[/spoiler]

here the macros called 'MacroButtons..', 'notAllowed' and 'emptyFrame' are all different frames that are shown when appropriate. They all again contain an onchangeselection call which points back to macrobuttonscombat(). So when another token is selected the above routine runs again.

What the routine in general does is make a couple of checks (like only one token selected, which property type and isGM and who the owner and based on that through a switch picks the right routine.
I've build an if() statement around that to speed things up (as switch statements are slow) cause in most cases people will only select the 'right' token, which builds the panel faster.

Thanks for the code! I'm gonna have to pour over that for a while and see what I can throw in. I don't think I'm going to have it populate a frame with macros, as I'd then have to go over how to utilise such a frame to everyone (the more advanced MapTool users in my group do barely more than simple dice rolls with macros, with the most complex thing being a variant of a still fairly simple d20 attack roll macro I made a while back), but I might do that later on. I'll keep it in consideration.

(Oh, and now I know I can use "code=php" to make my code boxes have clearer formatting on the forum. Awesome.)
Kill them all, and let the Game Master grant the exp!

ImageImage

User avatar
aliasmask
Deity
Posts: 8667
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Editable Character Sheet For Token Owners Only

Post by aliasmask »

Oriet wrote:
aliasmask wrote:I kind of do the exact opposite of what you suggest, but it's the same concept. I make my visible token properties have prefixes, like stat.strength or sheet.hp. I do give the stat sheet properties alias's though so players don't see the dot notation. I only use the token properties in the token type for things to be visible on the stat sheet. I just got used to using getProperty, setProperty instead of directly referring to a token property. That way I never have to rely on a token having the correct token type.

I don't know if I'll do that for the hover over statsheet visible token properties, but that does sound like a good idea for other properties on tokens, even if just to keep track of what the property is for and how and where to use it. If I was to start using alias tokens I'd include it for visible properties as well, but I'm A)not sure how to use aliases, B)not having token file sizes large enough that it would speed things up much (especially as no one has reported noticeable lag), and C)don't think I'm putting in enough complexity (yet) for that.


Here's an example of the token properties I use in a framework I created.

Code: Select all

*@sheet.life (Life):[r: sheet.life = strformat("%{life.lifepoints} / %{damage.awareness} - %{life.status}")]]
*@sheet.damage (Damage):[r: sheet.damage = strformat("Wounds/Burn (%{damage.wounds}/%{damage.burn}); Stun/Shock (%{damage.stun}/%{damage.shock})")]
*@sheet.armor (Armor):[r: sheet.armor = strformat("Armor (%{armor.armor}/%{armor.padding}/%{armor.plating}); Helmet (%{armor.helmet}/%{armor.lining}/%{armor.hardening})")]
*@sheet.resistance (Resists):[r: sheet.resistance = if(resistance.chemical,"Chemical "+resistance.chemical+"; ","")+if(resistance.energy,"Energy "+resistance.energy+"; ","")+if(resistance.fire,"Fire "+resistance.fire+"; ","")+if(resistance.psi,"Psi "+resistance.psi+"; ","")]
*@sheet.radiation (Radiation):[r: sheet.radiation = "Exposure "+floor(damage.exposure * 100)+"%"]
*@sheet.body (Body):[r: sheet.body = strformat("Strength %{stat.strength}, Agility %{stat.agility}, Vitality %{stat.vitality}")]
*@sheet.mind (Mind):[r: sheet.mind = strformat("Alertness {stat.alertness}, Intelligence {stat.intelligence}, Willpower {stat.willpower}")]
*@sheet.initiative (Initiative)
*sheet.fof:[H, if(isNPC()): setState("Foe",!state.Friend); setState("Friend",1) + setState("Foe",0)][r: sheet.fof = ""]
*@sheet.plot (Plot Points):[r: sheet.plot = points.plotpoints]
points.plotpoints:0
stat.strength (Strength):0
stat.agility (Agility):0
stat.vitality (Vitality):0
stat.intelligence (Intelligence):0
stat.alertness (Alertness):0
stat.willpower (Willpower):0
life.lifepoints:0
life.status:"Awake"
damage.awareness:0
damage.wounds:0
damage.burn:0
damage.stun:0
damage.shock:0
damage.exposure:0
damage.radiation:0
armor.armor:0
armor.padding:0
armor.plating:0
armor.helmet:0
armor.lining:0
armor.hardening:0
resistance.chemical:0
resistance.energy:0
resistance.fire:0
resistance.psi:0
resistance.radiation:0

Anything with "sheet." in front appears on the stat sheet. All the other properties are not on stat sheet, but are used by the "sheet." properties. The alias's in the properties are in the ()'s. So, the stat sheet doesn't show stat.strength but "Strength".

I have a more detailed post here: viewtopic.php?f=3&t=19168#p202212

User avatar
Oriet
Cave Troll
Posts: 30
Joined: Mon Dec 05, 2011 10:58 am
Location: Somewhere that's not there, but not really here.
Contact:

Re: Editable Character Sheet For Token Owners Only

Post by Oriet »

Wait, so all that's meant by alias is the parenthetical display name for a property? I've already been doing that pretty much since I started using MapTool. I thought by alias you were meaning a secondary token with only bare-bones info on it so that when states and such are changed in combat it has a smaller token to resend instead of the larger one with complete stats.

Or am I somehow misunderstanding things?
Kill them all, and let the Game Master grant the exp!

ImageImage

User avatar
jfrazierjr
Deity
Posts: 5176
Joined: Tue Sep 11, 2007 7:31 pm

Re: Editable Character Sheet For Token Owners Only

Post by jfrazierjr »

Oriet wrote:
jfrazierjr wrote:My one suggestion (this is really for any macro writer)... if you plan to or thing you might ever possibly add in someone else's framework to your own, I would highly suggest making your variable names use some type of pre/post fix. That way, if someone else's framework you are using does something with a variable named HP(just for example), then it won't clobber your character data!!!(and even worse, it may take you hours or days of time figuring out why)

I highly doubt I'll incorporate someone else's framework into this campaign, as I am using a lot of custom rules (custom criticals using a table of effects instead of multiplying damage, treating armour as hardness instead of a bonus to AC, custom classes though some are extremely influenced from KotOR, same with Force powers, and many other things) which means I'd have to customise anything I try to add in.


Ah, but what if you decide to release YOUR framework for others to enjoy and they try to merge with other stuff? :wink:
I save all my Campaign Files to DropBox. Not only can I access a campaign file from pretty much any OS that will run Maptool(Win,OSX, linux), but each file is versioned, so if something goes crazy wild, I can always roll back to a previous version of the same file.

Get your Dropbox 2GB via my referral link, and as a bonus, I get an extra 250 MB of space. Even if you don't don't use my link, I still enthusiastically recommend Dropbox..

User avatar
aliasmask
Deity
Posts: 8667
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Editable Character Sheet For Token Owners Only

Post by aliasmask »

Oriet wrote:Wait, so all that's meant by alias is the parenthetical display name for a property? I've already been doing that pretty much since I started using MapTool. I thought by alias you were meaning a secondary token with only bare-bones info on it so that when states and such are changed in combat it has a smaller token to resend instead of the larger one with complete stats.

Or am I somehow misunderstanding things?

In my previous post, alias was used to describe the name in parenthesis. What you describe is what I strive for a regular token. Generally speaking when handling token data, I read once at the beginning and write once at the end. I also tend to do all my processing at one time and pass along the results back to the calling macro for all my updates including sending output to chat, changing states and saving properties. It doesn't always work out that way, but I try.

You mentioned in another post that once a client sends a token to the server you have to send that token to all the other clients... I'm not sure if that's true. Since the clients have the list of other players, they could send updates direct to them. I'm not sure how MT is networked to be honest.

Other things that can bog down a server is a mouse over event that updates a token continuously. If people without slow uploads will notice a difference with that one.

User avatar
Oriet
Cave Troll
Posts: 30
Joined: Mon Dec 05, 2011 10:58 am
Location: Somewhere that's not there, but not really here.
Contact:

Re: Editable Character Sheet For Token Owners Only

Post by Oriet »

jfrazierjr wrote:Ah, but what if you decide to release YOUR framework for others to enjoy and they try to merge with other stuff? :wink:

Well, in that case I would want to change the variable names. It's actually something I'm likely to do (at least changing the names, not as sure about releasing the framework, though if I was I'd release it alongside the pdf of the custom game rules), as I am not satisfied with how I'm currently handling some things. My attack macro set especially needs some streamlining, and I need to split up and integrate a few other macros and macro chains, create an armoury (that allows for selection and changing of weapons and armour, possibly some other gear as well, most likely storing needed data in properties somewhere), make it so vehicles have their own set of properties (and create the critical damage table for them), create a macro-set for Force powers, possibly radically change how the properties are kept on the tokens, and other things that aren't at the top of my head. All of that will likely be done in the next few months, though after I get this interactive character sheet working I need to work on creating a simple Dark Heresy framework for my boyfriend's campaign.


------------------

Well, I've spent the day so far pouring over that code; not only what you provided in the thread but also some from your Dark Heresy framework. (As a note, I saw that the equipment description for Combi-Tools has the description for Demolitions Kits embedded in it.) It looks to be an excellent and robust framework, though my boyfriend doesn't plan to use it for this campaign as it has far more options and complexity than he's wanting. I will, however, use it as inspiration and might grab some elements of it, and I may use it at some point down the line.

Unfortunately, the scripting/coding (not sure which term is accurate) is going right over my head. I think it's in good part because there are functions and roll options I am unfamiliar with, and that I am not a programmer is also factoring in (though I have poked at introductory stuff to C++ and Python in the past). As such I don't even know how to begin integrating aspects into my macro-set.

Instead of just going "gimme coad naow!" (or a more polite version thereof) I'll instead ask for guidance on how to approach the task, including an explanation of any functions and roll options either required or useful for doing it. (I'm also fine if you leave it up to me to ask about specific functions and roll options for further exposition.) I know it's asking a bit, but I want to be able to understand what I'm using so I can fix anything that might break, tweak it if I change something, and be able to use similar techniques in other circumstances.

You guys have already been of enormous help, and are making me love MapTool more than I already did. ♥


aliasmask wrote:In my previous post, alias was used to describe the name in parenthesis. What you describe is what I strive for a regular token. Generally speaking when handling token data, I read once at the beginning and write once at the end. I also tend to do all my processing at one time and pass along the results back to the calling macro for all my updates including sending output to chat, changing states and saving properties. It doesn't always work out that way, but I try.

You mentioned in another post that once a client sends a token to the server you have to send that token to all the other clients... I'm not sure if that's true. Since the clients have the list of other players, they could send updates direct to them. I'm not sure how MT is networked to be honest.

Other things that can bog down a server is a mouse over event that updates a token continuously. If people without slow uploads will notice a difference with that one.

Ah, okay then. I'll definitely have to keep an eye on where I update token properties and states and where chat output is so that it's more condensed into one macro from a chain. With the networking I know I'd read that any time a token changes it has to resend that token in full to everyone, but I think it just sends from the computer that initiated the change instead of sending to the host then back out to everyone. Either way it can take up more bandwidth if there's a lot of changes at different times, so I would like to make sure I don't accidentally hog anyone's bandwidth from tokens or macros. (I already have my maps sized to 50 pixels per grid cell to keep their size down, and make sure the token images and profiles are not overly large either.)
Kill them all, and let the Game Master grant the exp!

ImageImage

User avatar
aliasmask
Deity
Posts: 8667
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Editable Character Sheet For Token Owners Only

Post by aliasmask »

Here's an interesting note on token updates. None of your changes are sent to the other clients until the very end of your macro chain. There are ways to break that chain, like using [wfunc]execLink[/wfunc] deferral feature and some of the functions that causes a redraw of the token. When you start modifying a token, you create a local copy of it and when you're all done, you write those changes to your shared copy. What will happen is you can start your macro, another client can updated the shared copy, but when you're done you write your copy to the shared copy which doesn't include the other clients changes.

That's why it's good to send data to the owner of a token to update it because that update becomes a part of his execution chain. That way, only one person is writing to the token and there will be no overwriting of data. Input also breaks the execution chain allowing deferred macros to run, but resumes the original execution once the input is complete. Any changes made are made to the local copy and not the shared copy during that break.

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

Re: Editable Character Sheet For Token Owners Only

Post by CoveredInFish »

Oriet wrote:Instead of just going "gimme coad naow!" (or a more polite version thereof) I'll instead ask for guidance on how to approach the task, including an explanation of any functions and roll options either required or useful for doing it.


Maybe i'm to late on the train but I miss the subject you still need guidance on. :) is the OP solved and you are futher on your task? This has got a pretty advanced and theoretic macro concept thread and maybe you have still a not theoretic problem. ?

User avatar
Oriet
Cave Troll
Posts: 30
Joined: Mon Dec 05, 2011 10:58 am
Location: Somewhere that's not there, but not really here.
Contact:

Re: Editable Character Sheet For Token Owners Only

Post by Oriet »

aliasmask wrote:Here's an interesting note on token updates. None of your changes are sent to the other clients until the very end of your macro chain. There are ways to break that chain, like using [wfunc]execLink[/wfunc] deferral feature and some of the functions that causes a redraw of the token. When you start modifying a token, you create a local copy of it and when you're all done, you write those changes to your shared copy. What will happen is you can start your macro, another client can updated the shared copy, but when you're done you write your copy to the shared copy which doesn't include the other clients changes.

That's why it's good to send data to the owner of a token to update it because that update becomes a part of his execution chain. That way, only one person is writing to the token and there will be no overwriting of data. Input also breaks the execution chain allowing deferred macros to run, but resumes the original execution once the input is complete. Any changes made are made to the local copy and not the shared copy during that break.

That is good to know, and something I'll keep in mind for how the processes go. I had also noticed the issues of using [wfunc]input[/wfunc], and plan on changing my attack macros to use either [wfunc]dialog[/wfunc] or [wroll]frame[/wroll], as hopefully those won't undue any changes from when the window was brought up to when they actually execute their attack (or whatever else the dialog/frame will be doing).

Now for another related question. How do I send the data to the owner for it to update the token on their end? It's not really vital for messing with a character sheet, as changing the info generally only happens when they level up, but I might throw the eventual armoury functions onto the character sheet which would make more important to ensure there's not an "overlap" of token updating, especially while my older macros that are utilising [wfunc]input[/wfunc] are still in use.



CoveredInFish wrote:Maybe i'm to late on the train but I miss the subject you still need guidance on. :) is the OP solved and you are futher on your task? This has got a pretty advanced and theoretic macro concept thread and maybe you have still a not theoretic problem. ?

I still have not been able to get it so that the character sheet only displays (and allows updating) for its owners. Part of why I'm asking for the conceptual instead of copy&paste way of solving the problem is because I want to make sure I understand what the macro is doing, both to fix eventual problems that'll arise as I change other bits and so that I can utilise the functions and roll options in other applications. Another part, though quite a bit smaller, is so that anyone else who has similar issues can benefit even if their code or approach is radically different from my own.
Kill them all, and let the Game Master grant the exp!

ImageImage

Post Reply

Return to “Macros”