RPTools.net

Discussion and Support

Skip to content

It is currently Thu Feb 22, 2018 11:57 am 






Reply to topic  [ 15 posts ] 

Previous topic | Next topic 

  Print view

Author Message
 Offline
Kobold
 
Joined: Wed Dec 14, 2016 1:30 pm
Posts: 8
 Post subject: Looking for input on macro
PostPosted: Thu Jan 19, 2017 2:59 pm 
I know this code is super sloppy, and I personally want to get better/more organized in my approach. I feel like knowing how to write advanced macros would really help me on this front. I need someone to help me out with this project and give me advice on where I could be better. Thank you!





Code:
[h:EnemyList = getSelectedNames()]
[h:Attacker = getImpersonated()]


<!--- Weapon Special Stack Effects --->
[h:AssignedStackNumber = 1]
[h:HasStackEffect = 0]
[h:MaxStackEffect = 4]
[h:StackExtraDamage = 0]
[h:StackExtraPercentDamage = 0]
[h:StackExtraHealing = 0]
[h:StackExtraPercentHealing = 0]
[h:StackEffectDiscription = "Insert a unique description or status effect here"]
[h:StackStrDamage = 0]
[h:StackDexDamage = 0]
[h:StackConDamage = 0]
[h:StackWisDamage = 0]
[h:StackIntDamage = 0]
[h:StackChaDamage = 0]
[h:StackResourceDrain = 0]
[h:StackResourceAbsorb = 0]
[h:StackArmorPiercing = 0]
[h:StackACReduction = 0]


<!--- Get Attacker Stats --->
[h:AttackerStrBonus = getProperty("StrMOD", Attacker)]
[h:AttackerDexBonus = getProperty("DexMOD", Attacker)]
[h:AttackerBAB = getProperty("BAB", Attacker)]
[h:AttackerCriticalTrue = getProperty("CriticalTrue", Attacker)]
[h:AttackerCriticalMult = getProperty("CriticalMult", Attacker)]
[h:AttackerCriticalAdd = getProperty("CriticalAdd", Attacker)]
[h:AttackerAP = getProperty("AP", Attacker)]
[h:AttackerResource = getProperty("Resource", Attacker)]
[h:AttackerResourceOnHit = getProperty("ResourceOnHit", Attacker)]
[h:AttackerMaxResource = getProperty("MaxResource", Attacker)]
[h:AttackerMinResource = getProperty("MinResource", Attacker)]
[h:AttackerResourceOnAttack = getProperty("ResourceOnAttack", Attacker)]
[h:AttackerStackCounter = getProperty("StackCounter"+AssignedStackNumber, Attacker)]
[h:AttackerHP = getProperty("HP", Attacker)]
[h:AttackerMaxHP = getProperty("MaxHP", Attacker)]
[h:AttackerMinHP = getProperty("MinHP", Attacker)]
[h:AttackerName = getImpersonatedName()]
[h:AttackerResourceName = getProperty("ResourceName", Attacker)]


<!--- Weapon Statistics --->
[h:WeaponDamage = 1d4]
[h:WeaponBonusAttackRoll = 0]
[h:WeaponAPCost = 0]
[h:WeaponElement = "Physical"]
[h:GravityPercentDamage = 0]
[h:FinesseWeapon = 0]
[h:WeaponCriticalRangeLow = 20 - AttackerCriticalAdd]
[h:WeaponCriticalMultiplier = 2 + AttackerCriticalMult]
[h:TwoHandedWeapon = 0]
[h:TrueDamageWeapon = 0]


<!--- Weapon Special Attacks and On-Hit effects --->
[h:SpecialAttackDamage = 0]
[h:OnHitEffectDamage = 0]
[h:WeaponEnchantmentDamage = 0]
[h:SneakAttackDamage = 0]
[h:ArmorPiercing = 0]
[h:ACReduction = 0]
[h:CriticalSpecialDamage = 0]
[h:CreateVulnurability = 0]
[h:VulnurabilityPercent = 0]
[h:VulnurabilityExtraDamage = 0]


<!--- Weapon Stat Damage --->
[h:StrDamage = 0]
[h:DexDamage = 0]
[h:ConDamage = 0]
[h:WisDamage = 0]
[h:IntDamage = 0]
[h:ChaDamage = 0]


<!--- Resource Draining and Lifesteal --->
[h:ResourceDrain = 0]
[h:ResourceAbsorb = 0]
[h:OnHitHealing = 0]
[h:OnHitHealingPercent = 0]



<!--- Weapon Finesse Feat Check --->
[h:AttackerWeaponFinesse = getProperty("WeaponFinesse", Attacker)]

<!--- Weapon Basic Calculation Properties --->
[h:Base1 = 1d20]
[h:Base2 = 1d20]


<!--- Weapon Basic Damage Calculation --->
[h, if(AttackerWeaponFinesse == 1), CODE: {
   [h:TotalWeaponDamage = WeaponDamage + DexMOD] }]

[h, if(TwoHandedWeapon == 1), CODE: {
   [h:TotalWeaponDamage = WeaponDamage + AttackerStrBonus*1.5] }]

[h, if(TwoHandedWeapon == 0 && AttackerWeaponFinesse == 0), CODE: {
   [h:TotalWeaponDamage = WeaponDamage + AttackerStrBonus] }]

[h:TotalWeaponDamage = TotalWeaponDamage + SpecialAttackDamage]
[h:TotalWeaponDamage = TotalWeaponDamage + OnHitEffectDamage]
[h:TotalWeaponDamage = TotalWeaponDamage + WeaponEnchantmentDamage]


<!--- Stack Weapon Check --->
[h, if(HasStackEffect == 1 && AttackerStackCounter == MaxStackEffect), CODE: {
   [h:TotalWeaponDamage = TotalWeaponDamage + StackExtraDamage]
   [h:GravityPercentDamage = GravityPercentDamage + StackExtraPercentDamage]
   [h: OnHitHealing = OnHitHealing + StackExtraHealing]
   [h: OnHitHealingPercent = OnHitHealingPercent + StackExtraPercentHealing]
   [h: StrDamage = StrDamage + StackStrDamage]
   [h: DexDamage = DexDamage + StackDexDamage]
   [h: ConDamage = ConDamage + StackConDamage]
   [h: WisDamage = WisDamage + StackWisDamage]
   [h: IntDamage = IntDamage + StackIntDamage]
   [h: ChaDamage = ChaDamage + StackChaDamage]
   [h: ResourceDrain = ResourceDrain + StackResourceDrain]
   [h: ResourceAbsorb = ResourceAbsorb + StackResourceAbsorb]
   [h: ArmorPiercing = ArmorPiercing + StackArmorPiercing]
   [h: ACReduction = ACReduction + StackACReduction]
   [h:setProperty("StackCounter"+AssignedStackNumber, 0, Attacker)]
}]
[h, if(HasStackEffect == 1 && AttackerStackCounter < MaxStackEffect), CODE: {
   [h:setProperty("StackCounter"+AssignedStackNumber, AttackerStackCounter + 1, Attacker)]
}]


<!--- Sneak Attack and Bonus Calculations --->
[h: ResourceDrainCheck = if(ResourceDrain != 0, "Resource Drained: " + ResourceDrain + "<br>", "")]
[h: ResourceAbsorbCheck = if(ResourceAbsorb != 0, "Resource Absorbed: " + ResourceAbsorb + "<br>", "")]
[h: VulnurabilityCheck = if(CreateVulnurability == 1 && VulnurabilityExtraDamage != 0, "Vulurability Created For: " + VulnurabilityExtraDamage + "<br>", "")]
[h: VulnurabilityCheck2 = if(CreateVulnurability == 1 && VulnurabilityPercent != 0, "Vulnurability Created For: " + VulnurabilityPercent + 100 + "%<br>", "")]
[h: APCheck = if(WeaponAPCost > AttackerAP, 0, 1)]
[h:StrDamageCheck = if(StrDamage != 0, "Str Damage: " + StrDamage + "<br>","")]
[h:DexDamageCheck = if(DexDamage != 0, "Dex Damage: " + DexDamage + "<br>","")]
[h:ConDamageCheck = if(ConDamage != 0, "Con Damage: " + ConDamage + "<br>","")]
[h:WisDamageCheck = if(WisDamage != 0, "Wis Damage: " + WisDamage + "<br>","")]
[h:IntDamageCheck = if(IntDamage != 0, "Int Damage: " + IntDamage + "<br>","")]
[h:ChaDamageCheck = if(ChaDamage != 0, "Cha Damage: " + ChaDamage + "<br>","")]
[h:ArmorPiercingCheck = if(ArmorPiercing != 0, "DR reduced by: " +ArmorPiercing + "<br>","")]
[h:ACReductionCheck = if(ACReduction != 0, "AC reduced by: " + ACReduction + "<br>","")]
[h, if(TrueDamageWeapon == 1), CODE: {
[h:FinalDamage = (TotalWeaponDamage)]
};{
[h:FinalDamage = (TotalWeaponDamage)]
}]
[h:ResourceOnHitCheck = if(AttackerResourceOnHit != 0, AttackerName + " gains " + AttackerResourceOnHit + " " + AttackerResourceName + ".<br>", "")]
[h:ResourceOnAttackCheck = if(AttackerResourceOnAttack != 0, AttackerName + " gains " + AttackerResourceOnAttack + " " + AttackerResourceName + ".<br>", "")]


<!--- Attack Roll Calculation--->
[h, if(FinesseWeapon == 0), CODE: {
   [h: AttackRoll = Base1 + AttackerBAB + AttackerStrBonus + WeaponBonusAttackRoll]
   [h:ConfirmationRoll = Base2 + AttackerBAB + AttackerStrBonus + WeaponBonusAttackRoll]
};{
   [h:AttackRoll = Base1 + AttackerBAB + AttackerDexBonus + WeaponBonusAttackRoll]
   [h:ConfirmationRoll = Base2 + AttackerBAB + AttackerDexBonus + WeaponBonusAttackRoll]
}]



<!--- Individual Token Mathematical Calculations --->
[r,foreach(enemy, EnemyList, "<br>"),CODE: {

   [h:switchToken(enemy)]
   <b>[r:token.name]</b><br>
   
   [r, if(ConfirmationRoll >= AC && Base1 >= WeaponCriticalRangeLow || CriticalTrue == 1), CODE: {
   Confirmed Critical ([r:Base1], [r:ConfirmationRoll]).<br>
   [h:HP_OLD = HP]
   [h:FinalDamage2 = round(max(1, ((FinalDamage*WeaponCriticalMultiplier) + CriticalSpecialDamage + SneakAttackDamage)*(1 + (DTakenPercent+getProperty("DMeleePercent", Attacker) + getProperty("DAllPercent", Attacker))/100) + (HP_OLD*(GravityPercentDamage/100))) - DamageReduction))]
   Damage: [r:FinalDamage2] // Healing: [r:round(OnHitHealing + (AttackerMaxHP*(OnHitHealingPercent/100)))]<br>
   [r:ResourceDrainCheck]
   [r:ResourceAbsorbCheck]
   [h:Resource = max(MinResource, min(MaxResource, Resource - ResourceAbsorb - ResourceDrain + ResourceOnDamage))]
   [r:VulnurabilityCheck]
   [r:VulnurabilityCheck2]
   [h:ExtraDamage = VulnurabilityExtraDamage]
   [h:DTakenPercent = VulnurabilityPercent]
   [r:ArmorPiercingCheck]
   [h:DamageReduction = DamageReduction - ArmorPiercing]
   [h:NaturalAC = NaturalAC - ACReduction]
   [r:ACReductionCheck]
   [r:StrDamageCheck]
   [h:Strength = Strength - StrDamage]
   [r:DexDamageCheck]
   [h:Dexterity = Dexterity - DexDamage]
   [r:ConDamageCheck]
   [h:Constitution = Constitution - ConDamage]
   [r:WisDamageCheck]
   [h:Wisdom = Wisdom - WisDamage]
   [r:IntDamageCheck]
   [h:Intelligence = Intelligence - IntDamage]
   [r:ChaDamageCheck]
   [h:Charisma = Charisma - ChaDamage]
   [h:HP = max(MinHP, min(MaxHP, HP - FinalDamage2))]
   [r:ResourceOnHitCheck]
   [r:ResourceOnAttackCheck]
   [h:Hit=1]
   [h:setProperty("HP", min(AttackerMaxHP, round(max(AttackerMinHP, (getProperty("HP", Attacker) + OnHitHealing + (AttackerMaxHP*(OnHitHealingPercent/100)))))), Attacker)]
   };{}]

   [r, if(ConfirmationRoll < AC && Base1 >= WeaponCriticalRangeLow), CODE: {
   Automatic Hit: ([r:Base1], [r:ConfirmationRoll]).<br>
   [h:HP_OLD = HP]
   [h:FinalDamage2 = round(max(1, ((FinalDamage + SneakAttackDamage)*(1 + (DTakenPercent+getProperty("DMeleePercent", Attacker) + getProperty("DAllPercent", Attacker))/100) + (HP_OLD*(GravityPercentDamage/100))) - DamageReduction))]
   Damage: [r:FinalDamage2] // Healing: [r:round(OnHitHealing + (AttackerMaxHP*(OnHitHealingPercent/100)))]<br>
   [r:ResourceDrainCheck]
   [r:ResourceAbsorbCheck]
   [h:Resource = max(MinResource, min(MaxResource, Resource - ResourceAbsorb - ResourceDrain + ResourceOnDamage))]
   [r:VulnurabilityCheck]
   [r:VulnurabilityCheck2]
   [h:ExtraDamage = VulnurabilityExtraDamage]
   [h:DTakenPercent = VulnurabilityPercent]
   [h:DamageReduction = DamageReduction - ArmorPiercing]
   [h:NaturalAC = NaturalAC - ACReduction]
   [r:ArmorPiercingCheck]
   [r:ACReductionCheck]
   [r:StrDamageCheck]
   [h:Strength = Strength - StrDamage]
   [r:DexDamageCheck]
   [h:Dexterity = Dexterity - DexDamage]
   [r:ConDamageCheck]
   [h:Constitution = Constitution - ConDamage]
   [r:WisDamageCheck]
   [h:Wisdom = Wisdom - WisDamage]
   [r:IntDamageCheck]
   [h:Intelligence = Intelligence - IntDamage]
   [r:ChaDamageCheck]
   [h:Charisma = Charisma - ChaDamage]
   [h:HP = max(MinHP, min(MaxHP, HP - FinalDamage2))]
   [r:ResourceOnHitCheck]
   [r:ResourceOnAttackCheck]
   [h:setProperty("HP", min(AttackerMaxHP, round(max(AttackerMinHP, (getProperty("HP", Attacker) + OnHitHealing + (AttackerMaxHP*(OnHitHealingPercent/100)))))), Attacker)]
   [h:Hit=1]
   };{}]

   [r, if(AttackRoll >= AC && Base1 < WeaponCriticalRangeLow), CODE: {
   Hit: ([r:AttackRoll]).<br>
   [h:HP_OLD = HP]
   [h:FinalDamage2 = round(max(1, (FinalDamage + SneakAttackDamage)*(1 + (DTakenPercent+getProperty("DMeleePercent", Attacker) + getProperty("DAllPercent", Attacker))/100) + (HP_OLD*(GravityPercentDamage/100)) - DamageReduction))]
   Damage: [r:FinalDamage2] // Healing: [r:round(OnHitHealing + (AttackerMaxHP*(OnHitHealingPercent/100)))]<br>
   [r:ResourceDrainCheck]
   [r:ResourceAbsorbCheck]
   [h:Resource = max(MinResource, min(MaxResource, Resource - ResourceAbsorb - ResourceDrain + ResourceOnDamage))]
   [r:VulnurabilityCheck]
   [r:VulnurabilityCheck2]
   [h:ExtraDamage = VulnurabilityExtraDamage]
   [h:DTakenPercent = VulnurabilityPercent]
   [h:DamageReduction = DamageReduction - ArmorPiercing]
   [h:NaturalAC = NaturalAC - ACReduction]
   [r:ArmorPiercingCheck]
   [r:ACReductionCheck]
   [r:StrDamageCheck]
   [h:Strength = Strength - StrDamage]
   [r:DexDamageCheck]
   [h:Dexterity = Dexterity - DexDamage]
   [r:ConDamageCheck]
   [h:Constitution = Constitution - ConDamage]
   [r:WisDamageCheck]
   [h:Wisdom = Wisdom - WisDamage]
   [r:IntDamageCheck]
   [h:Intelligence = Intelligence - IntDamage]
   [r:ChaDamageCheck]
   [h:Charisma = Charisma - ChaDamage]
   [h:HP = max(MinHP, min(MaxHP, HP - FinalDamage2))]
   [r:ResourceOnHitCheck]
   [r:ResourceOnAttackCheck]
   [h:setProperty("HP", min(AttackerMaxHP, round(max(AttackerMinHP, (getProperty("HP", Attacker) + OnHitHealing + (AttackerMaxHP*(OnHitHealingPercent/100)))))), Attacker)]
   [h:Hit=1]
   };{}]

   [r, if(AttackRoll < AC), CODE: {
   Miss! ([r:AttackRoll]).<br>
   [r:ResourceOnAttackCheck]
   [h:Hit=0]
   };{}]
   
   <!--- Resource Generation Check --->
   [h, if(Hit ==1 && SpecialAttackDamage == 0), CODE: {
   [h:setProperty("Resource", Max(AttackerMinResource, Min(AttackerMaxResource, AttackerResource + AttackerResourceOnAttack + AttackerResourceOnHit + ResourceAbsorb)), Attacker)]
   }]
   [h, if(Hit == 0 && SpecialAttackDamage == 0), CODE: {
   [h:setProperty("Resource", Max(AttackerMinResource, Min(AttackerMaxResource, AttackerResource + AttackerResourceOnAttack)), Attacker)]
   }]

}]


Last edited by aliasmask on Thu Jan 19, 2017 4:06 pm, edited 1 time in total.
added code tag


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Fri Mar 20, 2009 4:40 am
Posts: 9481
Location: Netherlands
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 3:27 am 
I had a quick look and its quite some code, but from what I saw I can give you some general advice that should help you get your code more structured:

core structuring of code (roughly) goes in 4 parts (or less if one is not required):

initialization
here you retrieve passed on parameters (arg(0),arg(1), etc), retrieve variables from tokens (getTokenProperty()) and do pre calculations required for input

input
here you ask the user for input, no more, no less

calculation/processing
here you do ALL processing, so the stuff you got from the initialization, combined with the processing, here you also (if required) create the output text:
Code:
[outputText = ""]
stuf 
[outputText = outputText + "Confirmed Critical" + Base1 + ", " + ConfirmationRoll + ").<br>"]
more stuf


output
Here you actually send stuff to the chat either with [r:outputText] or (my preference) [h:broadcast(outputText)]
so yes this is often one single line, sometimes with a couple of if's in there to get the syntax right (like he/she, or multiples).

This form of code structuring helps you a lot later on, and also if you post long pieces like hereabove 'we' can at least have a look per section to see if anything can be optimized.

one tiny optimization I noticed: next to [if:] there's also the Wiki: if(). This can help cleaning up this:
Code:
<!--- Attack Roll Calculation--->
[
h, if(FinesseWeapon == 0), CODE: {
   [
h:AttackRoll Base1 AttackerBAB AttackerStrBonus WeaponBonusAttackRoll]
   [
h:ConfirmationRoll Base2 AttackerBAB AttackerStrBonus WeaponBonusAttackRoll]
};{
   [
h:AttackRoll Base1 AttackerBAB AttackerDexBonus WeaponBonusAttackRoll]
   [
h:ConfirmationRoll Base2 AttackerBAB AttackerDexBonus WeaponBonusAttackRoll]
}] 

into this
Code:
<!--- Attack Roll Calculation--->
[
h:AttackRoll Base1 AttackerBAB + if(FinesseWeapon == 0AttackerStrBonus,AttackerDexBonus) + WeaponBonusAttackRoll]
[
h:ConfirmationRoll Base2 AttackerBAB + if(FinesseWeapon == 0AttackerStrBonusAttackerDexBonus) + WeaponBonusAttackRoll

_________________
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC

My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent and
DPI.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS


Top
 Profile  
 
 Offline
Kobold
 
Joined: Wed Dec 14, 2016 1:30 pm
Posts: 8
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 12:15 pm 
This was awesome. Thanks for the rundown. I especially enjoyed the last portion with the if() statements. I didn't think to use the code that way. That's so much easier.

One of the problems I am currently having is that Maptool will not allow me to drag the macro to any token, and when I try to copy/paste the code, I get an error message.

Another thing, is that I want to be able to understand macro argument and how to pass information back and forth between macros. This would help immensely when i need to call upon certain statuses or special damage cases. I don't really understand the advanced stuff all that much even though i've read every tutorial a ton of times.

One other problem is that macros like these (I wrote a far less complicated version of this awhile back), have to be recreated whenever a character gets a new equipment or equipment changes. Is there a better solution to this?

Thank you for the help btw. The system I'm using is fairly complicated. It involves individual character resources (Think like diablo 3), and an AP system, which is a measurement of how much a character can do in one round. Not sure how to make this system less complex than it is, because it involves a ton of different token property manipulations.

I need to get on the right track of thinking so that I can make better macros and improve the smoothness of my campaigns.
If anyone wants to help develop this or is open to giving me any advice on these subjects please let me know.
Thanks again.


Top
 Profile  
 
User avatar  Online
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 8011
Location: Bay Area
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 12:24 pm 
Guardian wrote:
One of the problems I am currently having is that Maptool will not allow me to drag the macro to any token, and when I try to copy/paste the code, I get an error message.

If you're the gm, this shouldn't be a problem. Also, if there is a macro that can be run on many tokens it's probably best to put the macro on a lib token and the call to the macro in the Campaign Macros.

_________________
Downloads:


Top
 Profile  
 
 Offline
Kobold
 
Joined: Wed Dec 14, 2016 1:30 pm
Posts: 8
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 1:07 pm 
aliasmask wrote:
Guardian wrote:
One of the problems I am currently having is that Maptool will not allow me to drag the macro to any token, and when I try to copy/paste the code, I get an error message.

If you're the gm, this shouldn't be a problem. Also, if there is a macro that can be run on many tokens it's probably best to put the macro on a lib token and the call to the macro in the Campaign Macros.


Never understood how that could ever be helpful though when people have multiple pieces of equipment. Do you have an example that could help clarify what I am missing?


Top
 Profile  
 
User avatar  Online
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 8011
Location: Bay Area
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 1:18 pm 
You need to define the equipment in to it's constituents parts (stat boost, damage, ...) and then all it is is changing the numbers with a new item and saving it in to a variable. Right now, it looks like you just hard code the changes in the macro.

A good example would be the 3.5/pathfinder framework by Lindsay. You edit your equipment and then equip it. I would look at some of his code.

_________________
Downloads:


Top
 Profile  
 
 Offline
Kobold
 
Joined: Wed Dec 14, 2016 1:30 pm
Posts: 8
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 1:45 pm 
A useful idea.
Does the framework support automated combat? If so, I can take inspiration from that as well.


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Fri Mar 20, 2009 4:40 am
Posts: 9481
Location: Netherlands
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 1:51 pm 
if you want to see automated combat through the roof you should take a look at my w40k framework :D (note that if I need to dig into that code I start crying...) I've automated the combat as far as maptools allows me to and the warhammer battle is insanely complex with user interactions and A LOT of exceptions, notwithstanding skills, talents and traits that influence the outcome....but you can have a look. I think though that AMs suggestion is better, lindsays framework is a little bit less complex

_________________
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC

My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent and
DPI.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS


Top
 Profile  
 
 Offline
Kobold
 
Joined: Wed Dec 14, 2016 1:30 pm
Posts: 8
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 1:55 pm 
wolph42 wrote:
if you want to see automated combat through the roof you should take a look at my w40k framework :D (note that if I need to dig into that code I start crying...) I've automated the combat as far as maptools allows me to and the warhammer battle is insanely complex with user interactions and A LOT of exceptions, notwithstanding skills, talents and traits that influence the outcome....but you can have a look. I think though that AMs suggestion is better, lindsays framework is a little bit less complex


Is there any way to modify the w40k framework to support a system like mine? E.G. resources, ap, custom made feats, etc?


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Fri Mar 20, 2009 4:40 am
Posts: 9481
Location: Netherlands
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 4:10 pm 
theoretically, yes. but youre better off starting from ground up...

_________________
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC

My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent and
DPI.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS


Top
 Profile  
 
 Offline
Kobold
 
Joined: Wed Dec 14, 2016 1:30 pm
Posts: 8
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 4:36 pm 
I mean, I already have some things in place. The macro that I presented does its intended job.

I need someone to teach me about the more advanced pieces of macro programming that I am failing to understand myself.

Ideally, I would like to build this framework myself or with the help of others.


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Fri Mar 20, 2009 4:40 am
Posts: 9481
Location: Netherlands
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 5:52 pm 
well, thats what this forum is for... post pieces of code, ask questions! What you coded doesn't look bad, just a bit unorganised and not very optimal, but that's what my framework looked like in the beginning...
The most important part is that you start (which you did) and along the way you will learn new tricks and rewrite parts of your code to be more efficient (which I did many many times).

edit: seeing the below post, concerning documentation: check the first link in my sig. And another thing make sure you have notepad++ with alias' plugin installed, its linked in his sig. Without it, coding is hell!

_________________
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC

My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent and
DPI.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS


Top
 Profile  
 
User avatar  Online
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 8011
Location: Bay Area
 Post subject: Re: Looking for input on macro
PostPosted: Fri Jan 20, 2017 5:56 pm 
Framework is just a name for an idea. Generally speaking you have 1 or more lib tokens holding all the macros, put macros that call the lib token macros in the Campaign Window for global access. You'll have special token properties, states and visions that are relevant to your game.

I have a starter token here: viewtopic.php?f=20&t=27010&p=265358#p265358

The notes in the macros will explain what they do. Also, in my signature is reference to RPEdit and notepad++. RPEdit is a token drop-in to help you edit your lib token macros. The notepad++ stuff you can download and then copy the files I created to aid in the MapTool macroscript with highlighting and tooltips. Also, the ctrl-shift-c to copy a macro block is useful.

The starter token includes 3 debugging macros and onCampaignLoad which will make all your macros in to user defined functions (UDFs) with a prefix. All these UDFs have the output suppressed so I also included a generic output macro.

I also have a generic best practices for programming in MapTool here: viewtopic.php?f=20&t=22886&p=233681#p233681

I'm sure wolph42 has some other documentation as well to help out.

_________________
Downloads:


Top
 Profile  
 
 Offline
Kobold
 
Joined: Wed Dec 14, 2016 1:30 pm
Posts: 8
 Post subject: Re: Looking for input on macro
PostPosted: Sat Jan 21, 2017 11:10 pm 
Took some advice on your guy's statements. Can't figure this one out though. Says Error in body of roll.
Code:
<!--- Initialization --->
[h: EnemyList = getSelectedNames()]
[h: SaveCheck = json.get(macro.args, "SaveCheck")]
[h: FortCheck = json.get(macro.args, "FortCheck")]
[h: RefCheck = json.get(macro.args, "RefCheck")]
[h: WillCheck = json.get(macro.args, "WillCheck")]
[h: HalfCheck = json.get(macro.args, "HalfCheck")]
[h: NegateCheck = json.get(macro.args, "NegateCheck")]
[h: Unsavable = json.get(macro.args, "Unsavable")]
[h: Vulnurabilty = json.get(macro.args, "Vulnurabilty")]
[h: RayAbility = json.get(macro.args, "RayAbility")]
[h: SlowingAbility = json.get(macro.args, "SlowingAbility")]
[h: HealingAbility = json.get(macro.args, "HealingAbility")]
[h: StatDamage = json.get(macro.args, "StatDamage")]
[h: NoPower = json.get(macro.args, "NoPower")]
[h: NoDamage = json.get(macro.args, "NoDamage")]
[h: Damage = json.get(macro.args, "Damage")]
[h: PercentDamage = json.get(macro.args, "PercentDamage")]
[h: TrueDamage = json.get(macro.args, "TrueDamage")]
[h: AttackBonus = json.get(macro.args, "AttackBonus")]
[h: Healing = json.get(macro.args, "Healing")]
[h: PercentHealing = json.get(macro.args, "PercentHealing")]
[h: ResourceCost = json.get(macro.args, "ResourceCost")]
[h: ResourceGain = json.get(macro.args, "ResourceGain")]
[h: VulnurabilityAmount = json.get(macro.args, "VulnurabilityAmount")]
[h: SlowingAmount = json.get(macro.args, "SlowingAmount")]
[h: StrDamage = json.get(macro.args, "StrDamage")]
[h: DexDamage = json.get(macro.args, "DexDamage")]
[h: ConDamage = json.get(macro.args, "ConDamage")]
[h: WisDamage = json.get(macro.args, "WisDamage")]
[h: IntDamage = json.get(macro.args, "IntDamage")]
[h: ChaDamage = json.get(macro.args, "ChaDamage")]

[r, if(RayAbility == 1), CODE: {
[MACRO("TouchAttackCalc@Lib:Combat"):SendData]
};{}]

[r,foreach(enemy, EnemyList, "<br>"),CODE: {

   [h:switchToken(enemy)]
   <b>[r:token.name]</b><br>
   [h:enemy = token.name]

   [h: SendData = json.set("{}", "Damage", Damage, "SaveCheck", SaveCheck, "Healing", Healing, "PercentHealing", PercentHealing, "ResourceCost", ResourceCost, "ResourceGain", ResourceGain, "APCost", APCost, "FortCheck", FortCheck, "RefCheck", RefCheck, "WillCheck", WillCheck, "HalfCheck", HalfCheck, "NegateCheck", NegateCheck, "Unsavable", Unsavable, "Vulnurabilty", Vulnurability, "VulnurabilityAmount", VulnurabilityAmount, "RayAbility", RayAbility, "AttackBonus", AttackBonus, "SlowingAbility", SlowingAbility, "SlowingAmount", SlowingAmount, "HealingAbility", HealingAbility, "StatDamage", StatDamage, "StrDamage", StrDamage, "DexDamage", DexDamage, "ConDamage", ConDamage, "WisDamage", WisDamage, "IntDamage", IntDamage, "ChaDamage", ChaDamage, "AttackType", AttackType, "NoPower", NoPower, "NoDamage", NoDamage, "CritThreat", CritThreat, "CriticalMultiplier", CriticalMultiplier, "PercentDamage", PercentDamage, "BasicDamage", BasicDamage, "TrueDamage", TrueDamage, "enemy", enemy)]


   [r, if(Unsavable == 1 && NoDamage == 0 && RayAbility == 0), CODE: {
   [MACRO("AttackDamageCalc@Lib:Combat"):SendData]
   };{}]

   [r, if(Unsavable == 1 && StatDamage == 0 && RayAbility == 0), CODE: {
   [MACRO("StatDamageCalc@Lib:Combat"):SendData]
   };{}]

   [r, if(SlowingAbility == 1 && Unsavable == 1), CODE: {
   [MACRO("SlowCalc@Lib:Combat"):SendData]
   };{}]
   
   [r, if(Vulnurabilty == 1 && Unsavable == 1), CODE: {
   [MACRO("VulnCalc@Lib:Combat"):SendData]
   };{}]
   
   [r, if(HealingAbility == 1), CODE: {
   [MACRO("HealCalc@Lib:Combat"):SendData]
   };{}]

   [r, if(HalfCheck == 1 && RefCheck == 1), CODE: {
   [MACRO("ReflexHalfCheck@Lib:Combat"):SendData]
   };{}]

   [r, if(HalfCheck == 1 && FortCheck == 1), CODE: {
   [MACRO("FortitudeHalfCheck@Lib:Combat"):SendData]
   };{}]

   [r, if(HalfCheck == 1 && WillCheck == 1), CODE: {
   [MACRO("WillHalfCheck@Lib:Combat"):SendData]
   };{}]

   [r, if(NegateCheck == 1 && RefCheck == 1), CODE: {
   [MACRO("ReflexNegateCheck@Lib:Combat"):SendData]
   };{}]

   [r, if(NegateCheck == 1 && FortCheck == 1), CODE: {
   [MACRO("FortitudeNegateCheck@Lib:Combat"):SendData]
   };{}]

   [r, if(NegateCheck == 1 && WillCheck == 1), CODE: {
   [MACRO("WillNegateCheck@Lib:Combat"):SendData]
   };{}]

};{}]


Any advice is appreciated

Edit: Found the spelling error in vulnurability. Things still dont work.


Top
 Profile  
 
User avatar  Online
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 8011
Location: Bay Area
 Post subject: Re: Looking for input on macro
PostPosted: Sat Jan 21, 2017 11:58 pm 
I notice in your first macro call you refer to SendData but it's not defined by that point. Also, if all your data you're defining is in macro.args you may be able to use this shortcut.

Code:
[H: props = json.toStrProp(macro.args)]
[H: varsFromStrProp(props)]


Btw, this is only good if you don't have any ; in your data.

I also recommend using
Code:
[h: EnemyList = getSelectedNames("json")]


I counted the variables in sendData and I count 36, but there are fewer variables defined above, so that could be something.

_________________
Downloads:


Top
 Profile  
 
Display posts from previous:  Sort by  
Reply to topic  [ 15 posts ] 

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:

Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 5 minutes)
Most users ever online was 243 on Sun Nov 04, 2012 6:14 am

Users browsing this forum: No registered users and 1 guest





Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

Style based on Andreas08 by Andreas Viklund

Style by Elizabeth Shulman