So my skill macro seems to be working.
Not that these two macros need to have their setting changed so that players cannot edit them. Or at least the first one does unless you want to manually delete the old macro, I am not sure if creating new macros requires this... Seems it is only required for creating macros on other tokens.
But anyway, I got errors trying to run this first one while players were permitted to edit it. But I think only when there was already a Skill_Data macro for it to try to remove...
Anyway, you can skip this one and use the pre-prepared Skill_Data beneath it.
[h:abilities="Strength,Dexterity,Constitution,Intelligence,Wisdom,Charisma"]
[h:status=input("null|"+getName()+"|Are you certain that you want to delete any old Skill_Data macros on|LABEL")]
[h:abort(status)]
[h,if(hasMacro("Skill_Data")==1),FOREACH(macro_index,getMacroIndexes("Skill_Data")):removeMacro(macro_index)]
[h:status=input("number_skills|0|Number of skills that you will be using.")]
[h:abort(status)]
[h:macro_content='[h:"***The individual skills, change this as your skill bonuses change.***"]
[h:skill_number='+number_skills+']']
[h,for(i,0,number_skills,1),CODE:{
[h:status=input(
"skill_name|Skill "+(i+1)+"'s name",
"skill_ability|"+abilities+"|Relevant ability|LIST|VALUE=STRING",
"skill_bonus|0|Any additional bonus or ranks that you have to rolls with this skill.",
"conditions|0|The number of conditional effects")]
[h:abort(status)]
[h:macro_content=macro_content+'
[h:skill'+i+'_name="'+skill_name+'"]
[h:skill'+i+'_ability="'+skill_ability+'"]
[h:skill'+i+'_bonus='+skill_bonus+']
[h:skill'+i+'_conditions='+conditions+']']
[h,for(ii,0,conditions,1),CODE:{
[h:status=input("condition|Plus when .|describe conditional number "+ii+1)]
[h:abort(status)]
[h:macro_content=macro_content+'
[h:skill'+i+'_condition'+ii+'="'+condition+'"]']
}]
}]
[h:macro_content_2='[h:input_text="No input,No input"]
[h:input_text=macro.args]
[h:chosen_skill=listGet(input_text,0)]
[h,if(input_text!="number"),CODE:{
[h:chosen_value=listGet(input_text,1)]
[h:output_text="error "+chosen_skill+" "+chosen_value]
}]
[h,if(input_text=="number"),CODE:{
[h:output_text=skill_number]
[h:skill_number=0]
}]
[h,if(isNumber(chosen_skill)),CODE:{
[h:output_text="invalid skill number"]
[h,if(skill_number>chosen_skill&&chosen_skill>=0):output_text=eval("skill"+chosen_skill+"_"+chosen_value)]
[h,if(skill_number>chosen_skill&&chosen_skill>=0):skill_number=0]
}]
[h:i=0]
[h,while(skill_number>i&&chosen_skill!=eval("skill"+i+"_name")):i=i+1]
[h,if(chosen_skill==eval("skill"+i+"_name")):output_text=eval("skill"+i+"_"+chosen_value)]
[h:macro.return=output_text]
[h:"***arguments:
("number") returns the number of skills
(name,quality) returns the requested quality of the named skill
(number,quality) returns the requested quality of the numbered skill***"]']
[createMacro("Skill_Data",macro_content+"
"+macro_content_2,"color=black;fontColor=lime;group=under")]
And here is one I prepared earlier, for my own character, so you will need to go through it and change the values to suit your own. It should all be fairly self-explanatory. "skill#_name" is the skill's name, the names can be used as a reference point, so changing them will probably break any macros that roll them for you. "ability" is which ability score the skill uses, change the ability score on your token and you change the skill bonuses accordingly... "bonus" is for permanent bonuses, such as racial or size modifies, and skill ranks obviously. "conditions" is how many conditions it will look for, if this is too high, it will probably ask for them manually, if it is too low, it won't see the later conditions. "condition#" is each condition, this is just a bit of text that is printed after the skill roll, for things like favoured enemy bonuses and such. You should be able to add them manually later so try not to go overboard. If you want to add more conditions, just add in a new condition line, get the skill number and condition number right, and increase the conditions entry to suit. Oh, "skill_number" is important, if you change the number of skills, make sure to correct it. On that note, the counts start at 1 "there is one skill" and the indexes start at 0 "this is skill zero" so the counts should be one higher than the highest index, or lower if you are ignoring the later indexes for some reason...
[h:"***The individual skills, change this as your skill bonuses change.***"]
[h:skill_number=48]
[h:skill0_name="Appraise"]
[h:skill0_ability="Intelligence"]
[h:skill0_bonus=0]
[h:skill0_conditions=2]
[h:skill0_condition0="No tools"]
[h:skill0_condition1="No crafts"]
[h:skill1_name="Balance"]
[h:skill1_ability="Dexterity"]
[h:skill1_bonus=0]
[h:skill1_conditions=0]
[h:skill2_name="Bluff"]
[h:skill2_ability="Charisma"]
[h:skill2_bonus=0]
[h:skill2_conditions=0]
[h:skill3_name="Climb"]
[h:skill3_ability="Strength"]
[h:skill3_bonus=0]
[h:skill3_conditions=1]
[h:skill3_condition0="-5 if moving at half speed"]
[h:skill4_name="Concentration"]
[h:skill4_ability="Constitution"]
[h:skill4_bonus=5]
[h:skill4_conditions=1]
[h:skill4_condition0=""]
[h:skill5_name="Craft(Traps)"]
[h:skill5_ability="Intelligence"]
[h:skill5_bonus=2]
[h:skill5_conditions=1]
[h:skill5_condition0="No tools"]
[h:skill6_name="Craft(Spare)"]
[h:skill6_ability="Intelligence"]
[h:skill6_bonus=0]
[h:skill6_conditions=1]
[h:skill6_condition0="Backup"]
[h:skill7_name="Decipher Script"]
[h:skill7_ability="Intelligence"]
[h:skill7_bonus=0]
[h:skill7_conditions=1]
[h:skill7_condition0="Untrained"]
[h:skill8_name="Diplomacy"]
[h:skill8_ability="Charisma"]
[h:skill8_bonus=0]
[h:skill8_conditions=0]
[h:skill9_name="Disable Device"]
[h:skill9_ability="Intelligence"]
[h:skill9_bonus=0]
[h:skill9_conditions=1]
[h:skill9_condition0="Untrained"]
[h:skill10_name="Disguise"]
[h:skill10_ability="Charisma"]
[h:skill10_bonus=0]
[h:skill10_conditions=1]
[h:skill10_condition0="Plus 0 when acting in character."]
[h:skill11_name="Escape Artist"]
[h:skill11_ability="Dexterity"]
[h:skill11_bonus=0]
[h:skill11_conditions=1]
[h:skill11_condition0="No rope skills"]
[h:skill12_name="Forgery"]
[h:skill12_ability="Intelligence"]
[h:skill12_bonus=0]
[h:skill12_conditions=0]
[h:skill13_name="Gather Information"]
[h:skill13_ability="Charisma"]
[h:skill13_bonus=0]
[h:skill13_conditions=0]
[h:skill14_name="Handle Animal"]
[h:skill14_ability="Charisma"]
[h:skill14_bonus=1]
[h:skill14_conditions=1]
[h:skill14_condition0="Trained"]
[h:skill15_name="Heal"]
[h:skill15_ability="Wisdom"]
[h:skill15_bonus=0]
[h:skill15_conditions=0]
[h:skill16_name="Hide"]
[h:skill16_ability="Dexterity"]
[h:skill16_bonus=4]
[h:skill16_conditions=0]
[h:skill17_name="Intimidate"]
[h:skill17_ability="Charisma"]
[h:skill17_bonus=0]
[h:skill17_conditions=0]
[h:skill18_name="Jump"]
[h:skill18_ability="Strength"]
[h:skill18_bonus=0]
[h:skill18_conditions=1]
[h:skill18_condition0="4ft. reach"]
[h:skill19_name="Knowledge(Arcana)"]
[h:skill19_ability="Intelligence"]
[h:skill19_bonus=0]
[h:skill19_conditions=1]
[h:skill19_condition0="Untrained"]
[h:skill20_name="Knowledge(Architecture and Engineering)"]
[h:skill20_ability="Intelligence"]
[h:skill20_bonus=0]
[h:skill20_conditions=1]
[h:skill20_condition0="Untrained"]
[h:skill21_name="Knowledge(Dungeoneering)"]
[h:skill21_ability="Intelligence"]
[h:skill21_bonus=0]
[h:skill21_conditions=1]
[h:skill21_condition0="Untrained"]
[h:skill22_name="Knowledge(Geography)"]
[h:skill22_ability="Intelligence"]
[h:skill22_bonus=0]
[h:skill22_conditions=1]
[h:skill22_condition0="Untrained"]
[h:skill23_name="Knowledge(History)"]
[h:skill23_ability="Intelligence"]
[h:skill23_bonus=0]
[h:skill23_conditions=1]
[h:skill23_condition0="Untrained"]
[h:skill24_name="Knowledge(Local)"]
[h:skill24_ability="Intelligence"]
[h:skill24_bonus=0]
[h:skill24_conditions=1]
[h:skill24_condition0="Untrained"]
[h:skill25_name="Knowledge(Nature)"]
[h:skill25_ability="Intelligence"]
[h:skill25_bonus=0]
[h:skill25_conditions=1]
[h:skill25_condition0="Untrained"]
[h:skill26_name="Knowledge(Nobility and Royalty)"]
[h:skill26_ability="Intelligence"]
[h:skill26_bonus=0]
[h:skill26_conditions=1]
[h:skill26_condition0="Untrained"]
[h:skill27_name="Knowledge(Religion)"]
[h:skill27_ability="Intelligence"]
[h:skill27_bonus=2]
[h:skill27_conditions=1]
[h:skill27_condition0="Trained"]
[h:skill28_name="Knowledge(The Planes)"]
[h:skill28_ability="Intelligence"]
[h:skill28_bonus=1]
[h:skill28_conditions=1]
[h:skill28_condition0="Trained"]
[h:skill29_name="Listen"]
[h:skill29_ability="Wisdom"]
[h:skill29_bonus=0]
[h:skill29_conditions=1]
[h:skill29_condition0="Plus 2 when with familiar."]
[h:skill30_name="Move Silently"]
[h:skill30_ability="Dexterity"]
[h:skill30_bonus=0]
[h:skill30_conditions=0]
[h:skill31_name="Open Lock"]
[h:skill31_ability="Dexterity"]
[h:skill31_bonus=0]
[h:skill31_conditions=1]
[h:skill31_condition0="Untrained"]
[h:skill32_name="Perform(Act)"]
[h:skill32_ability="Charisma"]
[h:skill32_bonus=0]
[h:skill32_conditions=0]
[h:skill33_name="Perform(Oratory)"]
[h:skill33_ability="Charisma"]
[h:skill33_bonus=0]
[h:skill33_conditions=0]
[h:skill34_name="Profession(Miner)"]
[h:skill34_ability="Wisdom"]
[h:skill34_bonus=2]
[h:skill34_conditions=1]
[h:skill34_condition0="Untrained"]
[h:skill35_name="Profession(second)"]
[h:skill35_ability="Wisdom"]
[h:skill35_bonus=0]
[h:skill35_conditions=1]
[h:skill35_condition0="Spare skill"]
[h:skill36_name="Ride"]
[h:skill36_ability="Dexterity"]
[h:skill36_bonus=0]
[h:skill36_conditions=0]
[h:skill37_name="Search"]
[h:skill37_ability="Intelligence"]
[h:skill37_bonus=2]
[h:skill37_conditions=1]
[h:skill37_condition0="-1 when in bright sunlight or Daylight."]
[h:skill38_name="Sense Motive"]
[h:skill38_ability="Wisdom"]
[h:skill38_bonus=0]
[h:skill38_conditions=1]
[h:skill38_condition0="Plus when ."]
[h:skill39_name="Sleight of Hand"]
[h:skill39_ability="Dexterity"]
[h:skill39_bonus=0]
[h:skill39_conditions=1]
[h:skill39_condition0="Untrained"]
[h:skill40_name="Speak Language"]
[h:skill40_ability="Intelligence"]
[h:skill40_bonus=0]
[h:skill40_conditions=1]
[h:skill40_condition0="Languages..."]
[h:skill41_name="Spellcraft"]
[h:skill41_ability="Intelligence"]
[h:skill41_bonus=5]
[h:skill41_conditions=0]
[h:skill41_condition0="Plus when ."]
[h:skill42_name="Spot"]
[h:skill42_ability="Wisdom"]
[h:skill42_bonus=0]
[h:skill42_conditions=1]
[h:skill42_condition0="-1 when in bright sunlight or Daylight."]
[h:skill43_name="Survival"]
[h:skill43_ability="Wisdom"]
[h:skill43_bonus=0]
[h:skill43_conditions=0]
[h:skill43_condition0="Plus when ."]
[h:skill43_condition1="Plus when ."]
[h:skill44_name="Swim"]
[h:skill44_ability="Strength"]
[h:skill44_bonus=0]
[h:skill44_conditions=0]
[h:skill45_name="Tumble"]
[h:skill45_ability="Dexterity"]
[h:skill45_bonus=0]
[h:skill45_conditions=1]
[h:skill45_condition0="Untrained"]
[h:skill46_name="Use Magic Device"]
[h:skill46_ability="Charisma"]
[h:skill46_bonus=2]
[h:skill46_conditions=1]
[h:skill46_condition0="Plus 2 versus scrolls ."]
[h:skill47_name="Use Rope"]
[h:skill47_ability="Dexterity"]
[h:skill47_bonus=0]
[h:skill47_conditions=1]
[h:skill47_condition0="No escape skills"]
[h:input_text="No input,No input"]
[h:input_text=macro.args]
[h:chosen_skill=listGet(input_text,0)]
[h,if(input_text!="number"),CODE:{
[h:chosen_value=listGet(input_text,1)]
[h:output_text="error "+chosen_skill+" "+chosen_value]
}]
[h,if(input_text=="number"),CODE:{
[h:output_text=skill_number]
[h:skill_number=0]
}]
[h,if(isNumber(chosen_skill)),CODE:{
[h:output_text="invalid skill number"]
[h,if(skill_number>chosen_skill&&chosen_skill>=0):output_text=eval("skill"+chosen_skill+"_"+chosen_value)]
[h,if(skill_number>chosen_skill&&chosen_skill>=0):skill_number=0]
}]
[h:i=0]
[h,while(skill_number>i&&chosen_skill!=eval("skill"+i+"_name")):i=i+1]
[h,if(chosen_skill==eval("skill"+i+"_name")):output_text=eval("skill"+i+"_"+chosen_value)]
[h:macro.return=output_text]
[h:"***arguments:
("number") returns the number of skills
(name,quality) returns the requested quality of the named skill
(number,quality) returns the requested quality of the numbered skill***"]
Finally, this one makes skill macros with the selected skills. you could, I assume, make one big macro with all your skills, but it would be awkward to use, make one for combat skills and one for social skills and one for common skills and one for rare skills. Putting a single skill in one should make it almost as convenient to use as just pressing the button. The macros that this creates should open a box with a scroll-box to select skills from a list, a panel to enter temporary bonuses, such as from prayer or aid another or such, and a panel to enter any additional commentary, which will appear at the start of the list of comments and can be used for temporary comments, like the target of the skill, or if you are tumbling at half speed, or how sad you are about the penalties you take to perform(olfactory) when you are polymorphed out of being an awakened dire ant...
[h,macro("Skill_Data@TOKEN"):"number"]
[h:skill_number=macro.return]
[h:abort(skill_number)]
[h,macro("Skill_Data@TOKEN"):"0,name"]
[h:input_statement='status=input("macro_name|My brain is excrementally superior to all else combined!|Name of macro","skill_0|0|'+macro.return+'|CHECK"']
[h,for(i,1,skill_number,1),CODE:{
[h:input_statement=input_statement+',"skill_'+i+'|0|']
[h,macro("Skill_Data@TOKEN"):i+",name"]
[h:input_statement=input_statement+macro.return+'|CHECK"']
}]
[h:input_statement=input_statement+')']
[h:eval(input_statement)]
[h:abort(status)]
[h:number_skills=0]
[h:skill_list=""]
[h:i=0]
[h,while(1 > number_skills && skill_number >= i),CODE:{
[h,macro("Skill_Data@TOKEN"):i+",name"]
[h,if(eval('skill_'+i)):skill_list=skill_list+macro.return]
[h,if(eval('skill_'+i)):number_skills=number_skills+1]
[h:i=i+1]
}]
[h:transition=i]
[h,for(i,transition,skill_number,1),CODE:{
[h,macro("Skill_Data@TOKEN"):i+",name"]
[h,if(eval('skill_'+i)):skill_list=skill_list+','+macro.return]
[h,if(eval('skill_'+i)):number_skills=number_skills+1]
}]
[h:abort(number_skills)]
[h:macro_content='[h:skill_list="'+skill_list+'"]
[h:status=input("used_skill|"+skill_list+"|Select skill|LIST|VALUE=STRING"
,"temp_bonus|0|temporary bonuses or penalties."
,"commentary|_|Commentary")]
[h:abort(status)]
[h,while(isNumber(temp_bonus)==0&&status==1):status=input("temp_bonus|0|temporary bonuses or penalties was nonnumerical, please enter temporary bonuses as a numerical value.")]
[h,if(isNumber(temp_bonus)==0):temp_bonus=0][h,macro("Skill_Data@TOKEN"):used_skill+",ability"]
[h:ability=macro.return]
[h,macro("Skill_Data@TOKEN"):used_skill+",bonus"]
[h:bonus=macro.return]
[h,macro("Skill_Data@TOKEN"):used_skill+",conditions"]
[h:conditions=macro.return]
Using [r:used_skill]: [t:1d20+floor(eval(ability)/2-5)+bonus+temp_bonus]
[r,if(commentary!="_"):"<br>"+commentary]
[r,for(i,0,conditions,1,""),CODE:{
<br>
[h,macro("Skill_Data@TOKEN"):used_skill+",condition"+i]
[r:macro.return]
}]']
[h:createMacro(macro_name,macro_content,"color=purple;fontColor=yellow;group=general")]
These have been tested, not extensively, but they have been tested. I know of at least one bug, but it isn't my fault and it shouldn't come up and even if it does it should be fairly obvious what has happened and easy enough to deakl with without interrupting anything.
An alternative universal skill macro is:
Rolling [r:skill_name]: [t:1d20+bonus]
Which is a touch less fancy, but also ever so slightly simpler...
And hey, while I am here, lets see Gurk's old attack macro. It may have had some issues, I do not recall ever being entirely certain that it was reliable, maybe it used to fail the first time it was used in a session or something like that... Also, it tended to be a bit voluminous in its output. But hey, no better way to spend an afternoon than reviving the dead and forgotten...
[h:"***Stuff that you may wish to set***"]
[h:weapon_name="+4 shocking adamantine greatsword"]
[h:damage_type="slashing, magic, adamantine"][h:"***anything relevant to damage reduction***"]
[h:weapon_die_number="2"] [h:"***A 1d3 unarmed strike would have one die.***"]
[h:weapon_die_sides="6"][h:"***The dice on a 1d3 unarmed strike would have three sides.***"]
[h:crit_multiplier=2]
[h:crit_range=19][h:"***lowest die roll that threatens a critical hit***"]
[h:other_attack_modifiers=4][h:"***things like masterwork and weapon focus that don't fit anywhere else***"]
[h:other_damage_modifiers=4][h:"***once again, things like weapon specialisation and enhancement bonuses***"]
[h:attack_ability="Strength"]
[h:damage_ability="Strength"]
[h:ability_damage_multiplier=1.5]
[h:power_attack_multiplier=2][h:"***combat expertise support disabled***"]
[h:power_attack=Defense]
[h:"combat expertise=memory01"]
[h:base_attack_bonus=16]
[h:"***the following are for things like sneak attack or shocking weapons that have separate damage types and/or don't multiply with a critical hit. If extra_dice=[quote]0[unquote] then it will be ignored. Extra dice from bane goes here.***"]
[h:extra_dice_0="0"]
[h:extra_type_0="fire"]
[h:extra_dice_1="0"]
[h:extra_type_1="cold"]
[h:extra_dice_2="1d6"]
[h:extra_type_2="electric"]
[h:extra_dice_3="0"]
[h:extra_type_3="physical"]
[h:extra_dice_4="0"]
[h:extra_type_4="sneak attack"]
[h:"***Extra damage that occurs only on a critical hit. Please match identical damage types to identical numbers.***"]
[h:crit_dice_0="0"]
[h:crit_type_0="fire"]
[h:crit_dice_1="0"]
[h:crit_type_1="cold"]
[h:crit_dice_2="0"]
[h:crit_type_2="electric"]
[h:crit_dice_3="0"]
[h:crit_type_3="sonic"]
[h:"***Conditional effects that multiply on a critical hit such as bane or favoured enemy. A setting of 0 will have the entry ignored. Enhancement bonuses from bane go here.***"]
[h:conditional_attack_0=0]
[h:conditional_damage_0=0]
[h:conditional_reason_0="if it is an Evil outsider"]
[h:conditional_attack_1=-1]
[h:conditional_damage_1=0]
[h:conditional_reason_1="if I am in direct sunlight"]
[h:conditional_attack_2=0]
[h:conditional_damage_2=0]
[h:conditional_reason_2=""]
[h:conditional_attack_3=0]
[h:conditional_damage_3=0]
[h:conditional_reason_3=""]
[h:conditional_attack_4=0]
[h:conditional_damage_4=0]
[h:conditional_reason_4=""]
[h:conditional_attack_5=0]
[h:conditional_damage_5=0]
[h:conditional_reason_5=""]
[h:macro.return=json.set("{}","weapon_name",weapon_name,"damage_type",damage_type,"weapon_die_number",weapon_die_number,"weapon_die_sides",weapon_die_sides,"crit_multiplier",crit_multiplier,"crit_range",crit_range,"other_attack_modifiers",other_attack_modifiers,"other_damage_modifiers",other_damage_modifiers,"attack_ability",attack_ability,"damage_ability",damage_ability,"ability_damage_multiplier",ability_damage_multiplier,"power_attack_multiplier",power_attack_multiplier,"power_attack",power_attack,"base_attack_bonus",base_attack_bonus)]
[h,for(i,0,5,1):macro.return=json.set(macro.return,"extra_dice_"+i,eval("extra_dice_"+i),"extra_type_"+i,eval("extra_type_"+i))]
[h,for(i,0,4,1):macro.return=json.set(macro.return,"crit_dice_"+i,eval("crit_dice_"+i),"crit_type_"+i,eval("crit_type_"+i))]
[h,for(i,0,6,1):macro.return=json.set(macro.return,"conditional_attack_"+i,eval("conditional_attack_"+i),"conditional_damage_"+i,eval("conditional_damage_"+i),"conditional_reason_"+i,eval("conditional_reason_"+i))]
[h:"***Stuff that you may wish to set***"]
[h:"***Change the name of the macro below to match the macro with the relevant data. I recommend [this macro name]Data so that you know which macro matches which data. Obviously having two macros with the same name would confuse this sort of thing and is a generally bad idea.***"]
[MACRO("4GreatData@TOKEN"):""]
[h:weapon_name=json.get(macro.return,"weapon_name")]
[h:damage_type=json.get(macro.return,"damage_type")][h:"***anything relevant to damage reduction***"]
[h:weapon_die_number=json.get(macro.return,"weapon_die_number")] [h:"***A 1d3 unarmed strike would have one die.***"]
[h:weapon_die_sides=json.get(macro.return,"weapon_die_sides")][h:"***The dice on a 1d3 unarmed strike would have three sides.***"]
[h:crit_multiplier=json.get(macro.return,"crit_multiplier")]
[h:crit_range=json.get(macro.return,"crit_range")][h:"***lowest die roll that threatens a critical hit***"]
[h:other_attack_modifiers=json.get(macro.return,"other_attack_modifiers")][h:"***things like masterwork and weapon focus that don't fit anywhere else***"]
[h:other_damage_modifiers=json.get(macro.return,"other_damage_modifiers")][h:"***once again, things like weapon specialisation and enhancement bonuses***"]
[h:attack_ability=json.get(macro.return,"attack_ability")]
[h:damage_ability=json.get(macro.return,"damage_ability")]
[h:ability_damage_multiplier=json.get(macro.return,"ability_damage_multiplier")]
[h:power_attack_multiplier=json.get(macro.return,"power_attack_multiplier")][h:"***combat expertise support disabled***"]
[h:power_attack=json.get(macro.return,"power_attack")]
[h:"combat expertise=json.get(macro.return,"")"]
[h:base_attack_bonus=json.get(macro.return,"base_attack_bonus")]
[h:"***the following are for things like sneak attack or shocking weapons that have separate damage types and/or don't multiply with a critical hit. If extra_dice=[quote]0[unquote] then it will be ignored. Extra dice from bane goes here.***"]
[h:extra_dice_0=json.get(macro.return,"extra_dice_0")]
[h:extra_type_0=json.get(macro.return,"extra_type_0")]
[h:extra_dice_1=json.get(macro.return,"extra_dice_1")]
[h:extra_type_1=json.get(macro.return,"extra_type_1")]
[h:extra_dice_2=json.get(macro.return,"extra_dice_2")]
[h:extra_type_2=json.get(macro.return,"extra_type_2")]
[h:extra_dice_3=json.get(macro.return,"extra_dice_3")]
[h:extra_type_3=json.get(macro.return,"extra_type_3")]
[h:extra_dice_4=json.get(macro.return,"extra_dice_4")]
[h:extra_type_4=json.get(macro.return,"extra_type_4")]
[h:"***Extra damage that occurs only on a critical hit. Please match identical damage types to identical numbers.***"]
[h:crit_dice_0=json.get(macro.return,"crit_dice_0")]
[h:crit_type_0=json.get(macro.return,"crit_type_0")]
[h:crit_dice_1=json.get(macro.return,"crit_dice_1")]
[h:crit_type_1=json.get(macro.return,"crit_type_1")]
[h:crit_dice_2=json.get(macro.return,"crit_dice_2")]
[h:crit_type_2=json.get(macro.return,"crit_type_2")]
[h:crit_dice_3=json.get(macro.return,"crit_dice_3")]
[h:crit_type_3=json.get(macro.return,"crit_type_3")]
[h:"***Conditional effects that multiply on a critical hit such as bane or favoured enemy. A setting of 0 will have the entry ignored. Enhancement bonuses from bane go here.***"]
[h:conditional_attack_0=json.get(macro.return,"conditional_attack_0")]
[h:conditional_damage_0=json.get(macro.return,"conditional_damage_0")]
[h:conditional_reason_0=json.get(macro.return,"conditional_reason_0")]
[h:conditional_attack_1=json.get(macro.return,"conditional_attack_1")]
[h:conditional_damage_1=json.get(macro.return,"conditional_damage_1")]
[h:conditional_reason_1=json.get(macro.return,"conditional_reason_1")]
[h:conditional_attack_2=json.get(macro.return,"conditional_attack_2")]
[h:conditional_damage_2=json.get(macro.return,"conditional_damage_2")]
[h:conditional_reason_2=json.get(macro.return,"conditional_reason_2")]
[h:conditional_attack_3=json.get(macro.return,"conditional_attack_3")]
[h:conditional_damage_3=json.get(macro.return,"conditional_damage_3")]
[h:conditional_reason_3=json.get(macro.return,"conditional_reason_3")]
[h:conditional_attack_4=json.get(macro.return,"conditional_attack_4")]
[h:conditional_damage_4=json.get(macro.return,"conditional_damage_4")]
[h:conditional_reason_4=json.get(macro.return,"conditional_reason_4")]
[h:conditional_attack_5=json.get(macro.return,"conditional_attack_5")]
[h:conditional_damage_5=json.get(macro.return,"conditional_damage_5")]
[h:conditional_reason_5=json.get(macro.return,"conditional_reason_5")]
[h:"***This is where it asks for more information every time it is run. If these get annoying, consider making separate macros that assume these details. Maybe one where victim=nearest enemy(with quotes) or temporary_attack_bonuses=2, temporary_damage_bonuses=0, and attack_number=0 for charge attacks***"]
[h:attack_list="0"]
[h,if(base_attack_bonus>5):attack_list=(attack_list+",5")]
[h,if(base_attack_bonus>10):attack_list=(attack_list+",10")]
[h,if(base_attack_bonus>15):attack_list=(attack_list+",15")]
[h:status=input(
"victim|"+getVisibleTokenNames()+"|Select target|LIST|VALUE=STRING",
"attack_number|"+attack_list+"|BAB lost from position in attack sequence|LIST|VALUE=NUMBER",
"temporary_ab|0|Temporary attack bonuses",
"temporary_damage|0|Temporary damage bonuses")]
[h:abort(status)]
[h:"***Obvious alternatives to the above, delete the relevant line above and remove the quotes below, after making a backup macro...***"]
[h:"victim=""obvious choice"][h:"***D.M. chooses your target according to their whims***"]
[h:"attack_number=0"] [h:"***Every attack is your main attack***"]
[h:"attack_number=1"] [h:"***This is a secondary attack macro and always at -5***"]
[h:"temporary_ab=2"][h:"***+2 to hit for charging or flanking, +2 is common..."]
[h:"temporary_damage=1"][h:"***The bard always wins initiative and sings that same boring +1 song...***"]
[h:"***Old input disabled, though it may be faster to use***"]
[h:"victim=Please_input_target"]
[h:"***Ask the user for the target of the attack***"]
[h:"temporary_attack_bonuses=Please_input_conditional_Attack_modifiers"]
[h:"***Ask the user for any temporary changes to attack rolls, such as flanking, bless spell, attacking while prone...***"]
[h:"temporary_damage_bonuses=Please_input_conditional_Damage_modifiers"]
[h:"***As above, but relevant to damage rolls, things like favoured enemy, prayer spell, smite...***"]
[h:"attack_number=(Please_input_attack_number__Start_at_zero)"]
[h:"***The multiple of the modifier to apply due to position in the progression, the first attack is the default of 0 so you can skip it quickly, second attack will be 1 and at -5 to hit...***"]
[h:"***a 3.0 monk would want to change this to *3.***"]
[h:"***Extrapolating unknown values***"]
[h:temp_ability=eval(attack_ability)]
[h:ability_ab=floor(temp_ability/2-5)]
[h:temp_ability=eval(damage_ability)]
[h:temp_ability=floor(temp_ability/2-5)]
[h,if(temp_ability>0):ability_damage=floor(temp_ability*ability_damage_multiplier);ability_damage=temp_ability]
[h:base_dice=weapon_die_number+"d"+weapon_die_sides]
[h:crit_dice=weapon_die_number*(crit_multiplier-1)+"d"+weapon_die_sides]
[h:base_attack=(base_attack_bonus-attack_number*5)]
[h,if(power_attack>=100),CODE:
{[h:PA_ab=0]
[h:PA_damage=(power_attack-100)*power_attack_multiplier]
[h:power_attack=power_attack-100]
};{[h:PA_ab=power_attack]
[h:PA_damage=power_attack*power_attack_multiplier]
}]
[h:"***The macro proper starts here, hopefully you won't need to worry about this***"]
[h:"***Quick reference for the bonuses so people can see if you remembered the penalty for shooting into melee or the bonus from their buff spell***"]
Temporary Modifiers: attack:[r:temporary_ab]; Damage: [r:temporary_damage]; Power Attack: [r:power_attack][h:"; Combat Expertise [r:combat_expertise]"].<br>
[h:"***Calling the attack, just descriptive text.***"]
[r,if(attack_number == 0):"First"][r,if(attack_number == 1):"Second"][r,if(attack_number == 2):"Third"][r,if(attack_number == 3):"Fourth"]
attack with [r:weapon_name].<br>
Attacking <b>[r:victim]</b> with <i>[r:damage_type]</i> damage:<br><br>
[h:"***The attack roll.***"]
Would hit 1d20([t:AttackRoll=1d20][r,if(AttackRoll==20):"<b>!!!</b>"]) + [t:bonus=base_attack+ability_ab+temporary_ab+other_attack_modifiers-PA_ab] = [t:AttackRoll+bonus]<b>AC</b>
[t,if(conditional_attack_0!=0),CODE:{<br><i>or [t:AttackRoll+bonus+conditional_attack_0] AC [r:conditional_reason_0]</i>};{}]
[t,if(conditional_attack_1!=0),CODE:{<br><i>or [t:AttackRoll+bonus+conditional_attack_1] AC [r:conditional_reason_1]</i>};{}]
[t,if(conditional_attack_2!=0),CODE:{<br><i>or [t:AttackRoll+bonus+conditional_attack_2] AC [r:conditional_reason_2]</i>};{}]
[t,if(conditional_attack_3!=0),CODE:{<br><i>or [t:AttackRoll+bonus+conditional_attack_3] AC [r:conditional_reason_3]</i>};{}]
[t,if(conditional_attack_4!=0),CODE:{<br><i>or [t:AttackRoll+bonus+conditional_attack_4] AC [r:conditional_reason_4]</i>};{}]
[t,if(conditional_attack_5!=0),CODE:{<br><i>or [t:AttackRoll+bonus+conditional_attack_5] AC [r:conditional_reason_5]</i>};{}]
[h:"***Critical hit confirmation roll, if any***"]
[h:CritRoll=0]
[r,if(AttackRoll>=crit_range),CODE:
{<br><br><b>Critical hit confirmation roll hits 1d20([t:CritRoll=1d20][r,if(CritRoll==20):"</b>!!!<b>"]) + [t:bonus] = [t:CritRoll+bonus]AC.
[t,if(conditional_attack_0!=0),CODE:{<br><i>or [t:CritRoll+bonus+conditional_attack_0] AC [r:conditional_reason_0]</i>};{}]
[t,if(conditional_attack_1!=0),CODE:{<br><i>or [t:CritRoll+bonus+conditional_attack_1] AC [r:conditional_reason_1]</i>};{}]
[t,if(conditional_attack_2!=0),CODE:{<br><i>or [t:CrittRoll+bonus+conditional_attack_2] AC [r:conditional_reason_2]</i>};{}]
[t,if(conditional_attack_3!=0),CODE:{<br><i>or [t:CritRoll+bonus+conditional_attack_3] AC [r:conditional_reason_3]</i>};{}]
[t,if(conditional_attack_4!=0),CODE:{<br><i>or [t:CritRoll+bonus+conditional_attack_4] AC [r:conditional_reason_4]</i>};{}]
[t,if(conditional_attack_5!=0),CODE:{<br><i>or [t:CritRoll+bonus+conditional_attack_5] AC [r:conditional_reason_5]</i>};{}]
</b>};{}]
[h:"***Damage roll***"]
<br><br>For [r:base_dice]([t:damage_roll=eval(base_dice)]) + [t:bonus=ability_damage+other_damage_modifiers+temporary_damage+PA_damage] = [t,if(damage_roll+bonus>=1):damage=damage_roll+bonus;damage=1][r,if(extra_dice_0!="0"||extra_dice_1!="0"||extra_dice_2!="0"||extra_dice_3!="0"||extra_dice_4!="0"):" <b>damage</b><br>"]
[h:"***Extra damage dice take a lot of checking***"]
[h:extra_damage_0=0]
[r,if(extra_dice_0!="0"),CODE:{ +[t:extra_damage_0=eval(extra_dice_0)][r:extra_type_0]};{}]
[h:extra_damage_1=0]
[r,if(extra_dice_1!="0"),CODE:{ +[t:extra_damage_1=eval(extra_dice_1)][r:extra_type_1]};{}]
[h:extra_damage_2=0]
[r,if(extra_dice_2!="0"),CODE:{ +[t:extra_damage_2=eval(extra_dice_2)][r:extra_type_2]};{}]
[h:extra_damage_3=0]
[r,if(extra_dice_3!="0"),CODE:{ +[t:extra_damage_3=eval(extra_dice_3)][r:extra_type_3]};{}]
[h:extra_damage_4=0]
[r,if(extra_dice_4!="0"),CODE:{ +[t:extra_damage_4=eval(extra_dice_4)][r:extra_type_4]};{}]
[r,if(extra_dice_0!="0"||extra_dice_1!="0"||extra_dice_2!="0"||extra_dice_3!="0"||extra_dice_4!="0"),CODE:{ = [t:damage+extra_damage_0+extra_damage_1+extra_damage_2+extra_damage_3+extra_damage_4]};{}]
<b>damage</b> if it hits.
[h:"***Critical hit damage***"]
[r,if(AttackRoll>=crit_range),CODE:
{<br><br><b>Or [r:weapon_die_number*crit_multiplier+"d"+weapon_die_sides]([t:damage_roll=(damage_roll+eval(crit_dice))]) + [t:bonus*crit_multiplier] = [t,if(damage_roll+bonus*crit_multiplier>=crit_multiplier):damage=damage_roll+bonus*crit_multiplier;damage=crit_multiplier][h:extra=0] [h,if(extra_dice_0!="0"||extra_dice_1!="0"||extra_dice_2!="0"||extra_dice_3!="0"||extra_dice_4!="0"):extra=1]
[r,if(extra==1||crit_dice_0!="0"||crit_dice_1!="0"||crit_dice_2!="0"||crit_dice_3!="0"):" damage<br>"]
};{}]
[h:"***The dreaded return of the extra damage dice!!!***"]
[r,if(AttackRoll>=crit_range&&extra_dice_0!="0"),CODE:{ +[t,if(extra_type_0==crit_type_0):extra_damage_0=extra_damage_0+eval(crit_dice_0+"+0");extra_damage_0][r:extra_type_0]};{}]
[r,if(AttackRoll>=crit_range&&extra_dice_1!="0"),CODE:{ +[t,if(extra_type_1==crit_type_1):extra_damage_1=extra_damage_1+eval(crit_dice_1+"+0");extra_damage_1][r:extra_type_1]};{}]
[r,if(AttackRoll>=crit_range&&extra_dice_2!="0"),CODE:{ +[t,if(extra_type_2==crit_type_2):extra_damage_2=extra_damage_2+eval(crit_dice_2+"+0");extra_damage_2][r:extra_type_2]};{}]
[r,if(AttackRoll>=crit_range&&extra_dice_3!="0"),CODE:{ +[t,if(extra_type_3==crit_type_3):extra_damage_3=extra_damage_3+eval(crit_dice_3+"+0");extra_damage_3][r:extra_type_3]};{}]
[h:crit_damage_0=0]
[h:crit_damage_1=0]
[h:crit_damage_2=0]
[h:crit_damage_3=0]
[r,if(AttackRoll>=crit_range),CODE:
{[r,if(extra_dice_4!="0"),CODE:{ +[t:extra_damage_4][r:extra_type_4]};{}]
[r,if(crit_dice_0!="0"&&extra_type_0!=crit_type_0),CODE:{ +[t:crit_damage_0=eval(crit_dice_0)][r:crit_type_0]};{}]
[r,if(crit_dice_1!="0"&&extra_type_1!=crit_type_1),CODE:{ +[t:crit_damage_1=eval(crit_dice_1)][r:crit_type_1]};{}]
[r,if(crit_dice_2!="0"&&extra_type_2!=crit_type_2),CODE:{ +[t:crit_damage_2=eval(crit_dice_2)][r:crit_type_2]};{}]
[r,if(crit_dice_3!="0"&&extra_type_3!=crit_type_3),CODE:{ +[t:crit_damage_3=eval(crit_dice_3)][r:crit_type_3]};{}]
[h,if(extra_dice_0!="0"||extra_dice_1!="0"||extra_dice_2!="0"||extra_dice_3!="0"||extra_dice_4!="0"):extra=1]
[r,if(extra==1||crit_dice_0!="0"||crit_dice_1!="0"||crit_dice_2!="0"||crit_dice_3!="0"),CODE:
{ = [t:damage+extra_damage_0+extra_damage_1+extra_damage_2+extra_damage_3+extra_damage_4+crit_damage_0+crit_damage_1+crit_damage_2+crit_damage_3]
};{}]
damage if the critical hit is confirmed.</b>
};{}]
[h:"***Checks if you rolled a 1 on an attack roll and mentions the failure. If your game doesn't have autofail on confirmations then this is still mostly harmless, but should be easy to change***"]
[r,if(AttackRoll==1||CritRoll==1):"<br> But the natural 1 would make that difficult."]
[t,if(conditional_damage_0!=0),CODE:{<br><i>Add [t:conditional_damage_0][r,if(AttackRoll>=crit_range),CODE:
{<b>(or [t:conditional_damage_0*crit_multiplier])</b>};{}] damage [r:conditional_reason_0]</i>};{}]
[t,if(conditional_damage_1!=0),CODE:{<br><i>Add [t:conditional_damage_1][r,if(AttackRoll>=crit_range),CODE:
{<b>(or [t:conditional_damage_1*crit_multiplier])</b>};{}] damage [r:conditional_reason_1]</i>};{}]
[t,if(conditional_damage_2!=0),CODE:{<br><i>Add [t:conditional_damage_2][r,if(AttackRoll>=crit_range),CODE:
{<b>(or [t:conditional_damage_2*crit_multiplier])</b>};{}] damage [r:conditional_reason_2]</i>};{}]
[t,if(conditional_damage_3!=0),CODE:{<br><i>Add [t:conditional_damage_3][r,if(AttackRoll>=crit_range),CODE:
{<b>(or [t:conditional_damage_3*crit_multiplier])</b>};{}] damage [r:conditional_reason_3]</i>};{}]
[t,if(conditional_damage_4!=0),CODE:{<br><i>Add [t:conditional_damage_4][r,if(AttackRoll>=crit_range),CODE:
{<b>(or [t:conditional_damage_4*crit_multiplier])</b>};{}] damage [r:conditional_reason_4]</i>};{}]
[t,if(conditional_damage_5!=0),CODE:{<br><i>Add [t:conditional_damage_5][r,if(AttackRoll>=crit_range),CODE:
{<b>(or [t:conditional_damage_5*crit_multiplier])</b>};{}] damage [r:conditional_reason_5]</i>};{}]
And finally, I have definately not tested this post, so copy/past errors are totally a thing that could have happened...