aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2022-08-09 16:57:53 -0400
committerYour Name <you@example.com>2022-08-09 16:57:53 -0400
commit5937d893da5656be3f486c863ae54e08bbe66579 (patch)
tree15aedaf0753fcf73fe85e90e88a7d0af33036eca
parent947d83c59ea86615e3a81a2ec122d843b5eceee9 (diff)
downloaddmtool-5937d893da5656be3f486c863ae54e08bbe66579.tar.gz
dmtool-5937d893da5656be3f486c863ae54e08bbe66579.tar.bz2
dmtool-5937d893da5656be3f486c863ae54e08bbe66579.zip
Added generic items, worked on features
-rw-r--r--Makefile127
-rwxr-xr-xconfigure56
-rw-r--r--features/aberrant_ground.json23
-rw-r--r--features/acid_spray.json17
-rw-r--r--features/adhesive.json6
-rw-r--r--features/air_form.json4
-rw-r--r--features/amorphous.json2
-rw-r--r--features/amphibious.json4
-rw-r--r--features/animate_chains.json15
-rw-r--r--features/antennae.json22
-rw-r--r--features/antimagic_susceptibility.json4
-rw-r--r--features/attack.json15
-rw-r--r--features/attack_tarrasque.json22
-rw-r--r--features/aversion_of_fire.json4
-rw-r--r--features/beast_of_burden.json2
-rw-r--r--features/berserk.json8
-rw-r--r--features/blasphemous_word.json10
-rw-r--r--features/blind_senses.json11
-rw-r--r--features/blinding_breath.json9
-rw-r--r--features/blinding_dust.json14
-rw-r--r--features/blinding_gaze.json19
-rw-r--r--features/blinding_spittle.json22
-rw-r--r--features/blood_frenzy.json16
-rw-r--r--features/brave.json13
-rw-r--r--features/breath_attack.json2
-rw-r--r--features/brute.json13
-rw-r--r--features/cantrip.json11
-rw-r--r--features/cast_a_spell.json11
-rw-r--r--features/change_shape.json12
-rw-r--r--features/channel_negative_energy.json13
-rw-r--r--features/charge.json24
-rw-r--r--features/charm.json15
-rw-r--r--features/readme.md292
-rw-r--r--features/wip/0blank.json (renamed from features/0blank.json)0
-rw-r--r--features/wip/TYPE_absorption.json (renamed from features/TYPE_absorption.json)0
-rw-r--r--features/wip/animate_chains.json16
-rw-r--r--features/wip/animate_trees.json (renamed from features/animate_trees.json)0
-rw-r--r--features/wip/bound.json (renamed from features/bound.json)2
-rw-r--r--features/wip/breath_weapons.json (renamed from features/breath_weapons.json)0
-rw-r--r--features/wip/charm.json15
-rw-r--r--features/wip/children_of_the_night.json (renamed from features/children_of_the_night.json)0
-rw-r--r--features/wip/chomp.json (renamed from features/chomp.json)0
-rw-r--r--features/wip/claw_attack.json (renamed from features/claw_attack.json)0
-rw-r--r--features/wip/cold_breath.json (renamed from features/cold_breath.json)0
-rw-r--r--features/wip/confer_fire_resistance.json (renamed from features/confer_fire_resistance.json)0
-rw-r--r--features/wip/consume_life.json (renamed from features/consume_life.json)0
-rw-r--r--features/wip/corrode_metal.json (renamed from features/corrode_metal.json)0
-rw-r--r--features/wip/corrosive_form.json (renamed from features/corrosive_form.json)0
-rw-r--r--features/wip/create_specter.json (renamed from features/create_specter.json)0
-rw-r--r--features/wip/create_whirlwind.json (renamed from features/create_whirlwind.json)0
-rw-r--r--features/wip/cunning_action.json (renamed from features/cunning_action.json)0
-rw-r--r--features/wip/damage_transfer.json (renamed from features/damage_transfer.json)0
-rw-r--r--features/wip/dark_devotion.json (renamed from features/dark_devotion.json)0
-rw-r--r--features/wip/darkness_aura.json (renamed from features/darkness_aura.json)0
-rw-r--r--features/wip/deadly_leap.json (renamed from features/deadly_leap.json)0
-rw-r--r--features/wip/death_burst.json (renamed from features/death_burst.json)0
-rw-r--r--features/wip/death_glare.json (renamed from features/death_glare.json)0
-rw-r--r--features/wip/death_throes.json (renamed from features/death_throes.json)0
-rw-r--r--features/wip/detect.json (renamed from features/detect.json)0
-rw-r--r--features/wip/devil's_sight.json (renamed from features/devil's_sight.json)0
-rw-r--r--features/wip/disrupt_life.json (renamed from features/disrupt_life.json)0
-rw-r--r--features/wip/divine_awareness.json (renamed from features/divine_awareness.json)0
-rw-r--r--features/wip/divine_eminence.json (renamed from features/divine_eminence.json)0
-rw-r--r--features/wip/draining_kiss.json (renamed from features/draining_kiss.json)0
-rw-r--r--features/wip/dreadful_glare.json (renamed from features/dreadful_glare.json)0
-rw-r--r--features/wip/duergar_resilience.json (renamed from features/duergar_resilience.json)0
-rw-r--r--features/wip/earth_glide.json (renamed from features/earth_glide.json)0
-rw-r--r--features/wip/echolocation.json (renamed from features/echolocation.json)0
-rw-r--r--features/wip/elemental_demise.json (renamed from features/elemental_demise.json)0
-rw-r--r--features/wip/engulf.json (renamed from features/engulf.json)0
-rw-r--r--features/wip/enlarge.json (renamed from features/enlarge.json)0
-rw-r--r--features/wip/enslave.json (renamed from features/enslave.json)0
-rw-r--r--features/wip/ephemeral.json (renamed from features/ephemeral.json)0
-rw-r--r--features/wip/ethereal_jaunt.json (renamed from features/ethereal_jaunt.json)0
-rw-r--r--features/wip/ethereal_sight.json (renamed from features/ethereal_sight.json)0
-rw-r--r--features/wip/ethereal_stride.json (renamed from features/ethereal_stride.json)0
-rw-r--r--features/wip/etherealness.json (renamed from features/etherealness.json)0
-rw-r--r--features/wip/evasion.json (renamed from features/evasion.json)0
-rw-r--r--features/wip/false_appearance.json (renamed from features/false_appearance.json)0
-rw-r--r--features/wip/faultless_tracker.json (renamed from features/faultless_tracker.json)0
-rw-r--r--features/wip/fear_aura.json (renamed from features/fear_aura.json)0
-rw-r--r--features/wip/fetid_cloud.json (renamed from features/fetid_cloud.json)0
-rw-r--r--features/wip/fey_ancestry.json (renamed from features/fey_ancestry.json)0
-rw-r--r--features/wip/fey_charm.json (renamed from features/fey_charm.json)0
-rw-r--r--features/wip/fire_absorption.json (renamed from features/fire_absorption.json)0
-rw-r--r--features/wip/fire_aura.json (renamed from features/fire_aura.json)0
-rw-r--r--features/wip/fire_breath.json (renamed from features/fire_breath.json)0
-rw-r--r--features/wip/fire_form.json (renamed from features/fire_form.json)0
-rw-r--r--features/wip/first_roar.json (renamed from features/first_roar.json)0
-rw-r--r--features/wip/fling.json (renamed from features/fling.json)0
-rw-r--r--features/wip/flyby.json (renamed from features/flyby.json)0
-rw-r--r--features/wip/flying_sword.json (renamed from features/flying_sword.json)0
-rw-r--r--features/wip/freedom_of_movement.json (renamed from features/freedom_of_movement.json)0
-rw-r--r--features/wip/freeze.json (renamed from features/freeze.json)0
-rw-r--r--features/wip/frightening_gaze.json (renamed from features/frightening_gaze.json)0
-rw-r--r--features/wip/frightful_presence.json (renamed from features/frightful_presence.json)0
-rw-r--r--features/wip/frost_breath.json (renamed from features/frost_breath.json)0
-rw-r--r--features/wip/gibbering.json (renamed from features/gibbering.json)0
-rw-r--r--features/wip/gnome_cunning.json (renamed from features/gnome_cunning.json)0
-rw-r--r--features/wip/grappler.json (renamed from features/grappler.json)0
-rw-r--r--features/wip/grasping_tendrils.json (renamed from features/grasping_tendrils.json)0
-rw-r--r--features/wip/haste.json (renamed from features/haste.json)0
-rw-r--r--features/wip/heal_self.json (renamed from features/heal_self.json)0
-rw-r--r--features/wip/healing_touch.json (renamed from features/healing_touch.json)0
-rw-r--r--features/wip/heart_sight.json (renamed from features/heart_sight.json)0
-rw-r--r--features/wip/heated_body.json (renamed from features/heated_body.json)0
-rw-r--r--features/wip/heated_weapons.json (renamed from features/heated_weapons.json)0
-rw-r--r--features/wip/hellish_rejuvenation.json (renamed from features/hellish_rejuvenation.json)0
-rw-r--r--features/wip/hellish_weapons.json (renamed from features/hellish_weapons.json)0
-rw-r--r--features/wip/hold_breath.json (renamed from features/hold_breath.json)0
-rw-r--r--features/wip/hooves.json (renamed from features/hooves.json)0
-rw-r--r--features/wip/horrific_appearance.json (renamed from features/horrific_appearance.json)0
-rw-r--r--features/wip/horrifying_visage.json (renamed from features/horrifying_visage.json)0
-rw-r--r--features/wip/horror_nimbus.json (renamed from features/horror_nimbus.json)0
-rw-r--r--features/wip/hurl_flame.json (renamed from features/hurl_flame.json)0
-rw-r--r--features/wip/ice_walk.json (renamed from features/ice_walk.json)0
-rw-r--r--features/wip/ignited_illumination.json (renamed from features/ignited_illumination.json)0
-rw-r--r--features/wip/illumination.json (renamed from features/illumination.json)0
-rw-r--r--features/wip/illusory_appearance.json (renamed from features/illusory_appearance.json)0
-rw-r--r--features/wip/immutable_form.json (renamed from features/immutable_form.json)0
-rw-r--r--features/wip/incorporeal_movement.json (renamed from features/incorporeal_movement.json)0
-rw-r--r--features/wip/ink_cloud.json (renamed from features/ink_cloud.json)0
-rw-r--r--features/wip/inscrutable.json (renamed from features/inscrutable.json)0
-rw-r--r--features/wip/intoxicating_touch.json (renamed from features/intoxicating_touch.json)0
-rw-r--r--features/wip/invisibility.json (renamed from features/invisibility.json)0
-rw-r--r--features/wip/invisible_passage.json (renamed from features/invisible_passage.json)0
-rw-r--r--features/wip/iron_scent.json (renamed from features/iron_scent.json)0
-rw-r--r--features/wip/keen_hearing.json (renamed from features/keen_hearing.json)0
-rw-r--r--features/wip/keen_hearing_and_sight.json (renamed from features/keen_hearing_and_sight.json)0
-rw-r--r--features/wip/keen_hearing_and_smell.json (renamed from features/keen_hearing_and_smell.json)0
-rw-r--r--features/wip/keen_sight.json (renamed from features/keen_sight.json)0
-rw-r--r--features/wip/keen_sight_and_smell.json (renamed from features/keen_sight_and_smell.json)0
-rw-r--r--features/wip/keen_smell.json (renamed from features/keen_smell.json)0
-rw-r--r--features/wip/labyrinthine_recall.json (renamed from features/labyrinthine_recall.json)0
-rw-r--r--features/wip/leadership.json (renamed from features/leadership.json)0
-rw-r--r--features/wip/legendary_attack.json (renamed from features/legendary_attack.json)0
-rw-r--r--features/wip/legendary_resistance.json (renamed from features/legendary_resistance.json)0
-rw-r--r--features/wip/life_drain.json (renamed from features/life_drain.json)0
-rw-r--r--features/wip/light_sensitivity.json (renamed from features/light_sensitivity.json)0
-rw-r--r--features/wip/lightning_absorption.json (renamed from features/lightning_absorption.json)0
-rw-r--r--features/wip/lightning_breath.json (renamed from features/lightning_breath.json)0
-rw-r--r--features/wip/lightning_storm.json (renamed from features/lightning_storm.json)0
-rw-r--r--features/wip/lightning_strike.json (renamed from features/lightning_strike.json)0
-rw-r--r--features/wip/limited_amphibiousess.json (renamed from features/limited_amphibiousess.json)0
-rw-r--r--features/wip/limited_magic_immunity.json (renamed from features/limited_magic_immunity.json)0
-rw-r--r--features/wip/limited_telepathy.json (renamed from features/limited_telepathy.json)0
-rw-r--r--features/wip/luring_song.json (renamed from features/luring_song.json)0
-rw-r--r--features/wip/magic_resistance.json (renamed from features/magic_resistance.json)0
-rw-r--r--features/wip/magic_weapons.json (renamed from features/magic_weapons.json)0
-rw-r--r--features/wip/martial_advantage.json (renamed from features/martial_advantage.json)0
-rw-r--r--features/wip/mimicry.json (renamed from features/mimicry.json)0
-rw-r--r--features/wip/misty_escape.json (renamed from features/misty_escape.json)0
-rw-r--r--features/wip/moan.json (renamed from features/moan.json)0
-rw-r--r--features/wip/move.json (renamed from features/move.json)0
-rw-r--r--features/wip/mucous_cloud.json (renamed from features/mucous_cloud.json)0
-rw-r--r--features/wip/multiattack..json (renamed from features/multiattack..json)0
-rw-r--r--features/wip/multiattack.json (renamed from features/multiattack.json)0
-rw-r--r--features/wip/multiple_heads.json (renamed from features/multiple_heads.json)0
-rw-r--r--features/wip/nightmare_haunting.json (renamed from features/nightmare_haunting.json)0
-rw-r--r--features/wip/nimble_escape.json (renamed from features/nimble_escape.json)0
-rw-r--r--features/wip/ooze_cube.json (renamed from features/ooze_cube.json)0
-rw-r--r--features/wip/pack_tactics.json (renamed from features/pack_tactics.json)0
-rw-r--r--features/wip/paralyzing_breath.json (renamed from features/paralyzing_breath.json)0
-rw-r--r--features/wip/paralyzing_touch.json (renamed from features/paralyzing_touch.json)0
-rw-r--r--features/wip/parry.json (renamed from features/parry.json)0
-rw-r--r--features/wip/petrifying_breath.json (renamed from features/petrifying_breath.json)0
-rw-r--r--features/wip/petrifying_gaze.json (renamed from features/petrifying_gaze.json)0
-rw-r--r--features/wip/phantasms.json (renamed from features/phantasms.json)0
-rw-r--r--features/wip/poison_breath.json (renamed from features/poison_breath.json)0
-rw-r--r--features/wip/possession.json (renamed from features/possession.json)0
-rw-r--r--features/wip/pounce.json (renamed from features/pounce.json)0
-rw-r--r--features/wip/probing_telepathy.json (renamed from features/probing_telepathy.json)0
-rw-r--r--features/wip/psychic_drain.json (renamed from features/psychic_drain.json)0
-rw-r--r--features/wip/rampage.json (renamed from features/rampage.json)0
-rw-r--r--features/wip/reactive.json (renamed from features/reactive.json)0
-rw-r--r--features/wip/reactive_heads.json (renamed from features/reactive_heads.json)0
-rw-r--r--features/wip/read_thoughts.json (renamed from features/read_thoughts.json)0
-rw-r--r--features/wip/reckless.json (renamed from features/reckless.json)0
-rw-r--r--features/wip/reel.json (renamed from features/reel.json)0
-rw-r--r--features/wip/reflective_carapace.json (renamed from features/reflective_carapace.json)0
-rw-r--r--features/wip/regeneration.json (renamed from features/regeneration.json)0
-rw-r--r--features/wip/rejuvenation.json (renamed from features/rejuvenation.json)0
-rw-r--r--features/wip/relentless.json (renamed from features/relentless.json)0
-rw-r--r--features/wip/repulsion_breath.json (renamed from features/repulsion_breath.json)0
-rw-r--r--features/wip/roar.json (renamed from features/roar.json)0
-rw-r--r--features/wip/rock_catching.json (renamed from features/rock_catching.json)0
-rw-r--r--features/wip/running_leap.json (renamed from features/running_leap.json)0
-rw-r--r--features/wip/rust_metal.json (renamed from features/rust_metal.json)0
-rw-r--r--features/wip/scare.json (renamed from features/scare.json)0
-rw-r--r--features/wip/searing_burst.json (renamed from features/searing_burst.json)0
-rw-r--r--features/wip/second_roar.json (renamed from features/second_roar.json)0
-rw-r--r--features/wip/sense_magic.json (renamed from features/sense_magic.json)0
-rw-r--r--features/wip/senses.json (renamed from features/senses.json)0
-rw-r--r--features/wip/shadow_stealth.json (renamed from features/shadow_stealth.json)0
-rw-r--r--features/wip/shapechanger.json (renamed from features/shapechanger.json)0
-rw-r--r--features/wip/shark_telepathy.json (renamed from features/shark_telepathy.json)0
-rw-r--r--features/wip/shield.json (renamed from features/shield.json)0
-rw-r--r--features/wip/shielded_mind.json (renamed from features/shielded_mind.json)0
-rw-r--r--features/wip/shimmering_shield.json (renamed from features/shimmering_shield.json)0
-rw-r--r--features/wip/shock.json (renamed from features/shock.json)0
-rw-r--r--features/wip/shriek.json (renamed from features/shriek.json)0
-rw-r--r--features/wip/siege_monster.json (renamed from features/siege_monster.json)0
-rw-r--r--features/wip/sleep_breath.json (renamed from features/sleep_breath.json)0
-rw-r--r--features/wip/slow.json (renamed from features/slow.json)0
-rw-r--r--features/wip/slowing_breath.json (renamed from features/slowing_breath.json)0
-rw-r--r--features/wip/sneak_attack.json (renamed from features/sneak_attack.json)0
-rw-r--r--features/wip/snow_camouflage.json (renamed from features/snow_camouflage.json)0
-rw-r--r--features/wip/speak_with_beasts_and_plants.json (renamed from features/speak_with_beasts_and_plants.json)0
-rw-r--r--features/wip/spell_storing.json (renamed from features/spell_storing.json)0
-rw-r--r--features/wip/spider_climb.json (renamed from features/spider_climb.json)0
-rw-r--r--features/wip/split.json (renamed from features/split.json)0
-rw-r--r--features/wip/spores.json (renamed from features/spores.json)0
-rw-r--r--features/wip/standing_leap.json (renamed from features/standing_leap.json)0
-rw-r--r--features/wip/steadfast.json (renamed from features/steadfast.json)0
-rw-r--r--features/wip/steam_breath.json (renamed from features/steam_breath.json)0
-rw-r--r--features/wip/stench.json (renamed from features/stench.json)0
-rw-r--r--features/wip/stone_camouflage.json (renamed from features/stone_camouflage.json)0
-rw-r--r--features/wip/stunning_screech.json (renamed from features/stunning_screech.json)0
-rw-r--r--features/wip/sunlight_sensitivity.json (renamed from features/sunlight_sensitivity.json)0
-rw-r--r--features/wip/sunlight_weakness.json (renamed from features/sunlight_weakness.json)0
-rw-r--r--features/wip/sure-footed.json (renamed from features/sure-footed.json)0
-rw-r--r--features/wip/surprise_attack.json (renamed from features/surprise_attack.json)0
-rw-r--r--features/wip/swallow.json (renamed from features/swallow.json)0
-rw-r--r--features/wip/swarm.json (renamed from features/swarm.json)0
-rw-r--r--features/wip/tail_attack.json (renamed from features/tail_attack.json)0
-rw-r--r--features/wip/tail_spike_regrowth.json (renamed from features/tail_spike_regrowth.json)0
-rw-r--r--features/wip/tail_swipe.json (renamed from features/tail_swipe.json)0
-rw-r--r--features/wip/telepathic_bond.json (renamed from features/telepathic_bond.json)0
-rw-r--r--features/wip/teleport.json (renamed from features/teleport.json)0
-rw-r--r--features/wip/tentacle_attack_or_fling.json (renamed from features/tentacle_attack_or_fling.json)0
-rw-r--r--features/wip/tentacle_slam.json (renamed from features/tentacle_slam.json)0
-rw-r--r--features/wip/tentacles.json (renamed from features/tentacles.json)0
-rw-r--r--features/wip/third_roar.json (renamed from features/third_roar.json)0
-rw-r--r--features/wip/trampling_charge.json (renamed from features/trampling_charge.json)0
-rw-r--r--features/wip/transparent.json (renamed from features/transparent.json)0
-rw-r--r--features/wip/treasure_sense.json (renamed from features/treasure_sense.json)0
-rw-r--r--features/wip/tree_stride.json (renamed from features/tree_stride.json)0
-rw-r--r--features/wip/tunneler.json (renamed from features/tunneler.json)0
-rw-r--r--features/wip/turn_resistance.json (renamed from features/turn_resistance.json)0
-rw-r--r--features/wip/turning_defiance.json (renamed from features/turning_defiance.json)0
-rw-r--r--features/wip/two-headed.json (renamed from features/two-headed.json)0
-rw-r--r--features/wip/two_heads.json (renamed from features/two_heads.json)0
-rw-r--r--features/wip/unarmed_strike.json (renamed from features/unarmed_strike.json)0
-rw-r--r--features/wip/undead_fortitude.json (renamed from features/undead_fortitude.json)0
-rw-r--r--features/wip/underwater_camouflage.json (renamed from features/underwater_camouflage.json)0
-rw-r--r--features/wip/unnerving_mask.json (renamed from features/unnerving_mask.json)0
-rw-r--r--features/wip/vampire_weaknesses.json (renamed from features/vampire_weaknesses.json)0
-rw-r--r--features/wip/variable_illumination.json (renamed from features/variable_illumination.json)0
-rw-r--r--features/wip/wakeful.json (renamed from features/wakeful.json)0
-rw-r--r--features/wip/wall_of_ice.json (renamed from features/wall_of_ice.json)0
-rw-r--r--features/wip/water_breathing.json (renamed from features/water_breathing.json)0
-rw-r--r--features/wip/water_form.json (renamed from features/water_form.json)0
-rw-r--r--features/wip/water_susceptibility.json (renamed from features/water_susceptibility.json)0
-rw-r--r--features/wip/weakening_breath.json (renamed from features/weakening_breath.json)0
-rw-r--r--features/wip/web_sense.json (renamed from features/web_sense.json)0
-rw-r--r--features/wip/web_walker.json (renamed from features/web_walker.json)0
-rw-r--r--features/wip/whelm.json (renamed from features/whelm.json)0
-rw-r--r--features/wip/whirlwind.json (renamed from features/whirlwind.json)0
-rw-r--r--features/wip/whirlwind_of_sand.json (renamed from features/whirlwind_of_sand.json)0
-rw-r--r--features/wip/wing_attack.json (renamed from features/wing_attack.json)0
-rw-r--r--featuresNotes.txt126
-rw-r--r--propertiesNotes.txt46
-rw-r--r--src/armor.cc8
-rw-r--r--src/armor.h4
-rw-r--r--src/battlescape/battlescape.h50
-rw-r--r--src/features/feature.cc2
-rw-r--r--src/item.cc26
-rw-r--r--src/item.h18
-rw-r--r--src/settings.cc1
-rw-r--r--src/utils.h2
-rw-r--r--src/weapon.cc10
-rw-r--r--src/weapon.h4
272 files changed, 584 insertions, 584 deletions
diff --git a/Makefile b/Makefile
index 401c43b..f2f5416 100644
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,12 @@
-CC=g++
LIBS=libconfuse nlohmann_json
-CFLAGS=-c -Wall -fPIC -std=c++20
-LDFLAGS=
-SOURCES=src/dmtool.cc src/item.cc src/creature.cc src/spellcasting.cc src/weapon.cc src/dice.cc src/settings.cc src/spell.cc src/features/feature.cc src/utils.cc src/rules.cc src/armor.cc src/cmd/cmd.cc src/cmd/cmd_usage.cc src/cmd/cmd_query.cc src/cmd/cmd_fsops.cc src/cmd/cmd_manipulate.cc src/entry.cc
+override CXXFLAGS += -Wall -fPIC -std=c++20 `pkg-config $(LIBS) --cflags`
+override LDFLAGS += `pkg-config $(LIBS) --libs`
+CC=$(CXX)
+SOURCES=src/armor.cc src/cmd/cmd.cc src/cmd/cmd_fsops.cc src/cmd/cmd_manipulate.cc src/cmd/cmd_query.cc src/cmd/cmd_usage.cc src/creature.cc src/dice.cc src/dmtool.cc src/entry.cc src/features/feature.cc src/item.cc src/rules.cc src/settings.cc src/spell.cc src/spellcasting.cc src/utils.cc src/weapon.cc
OBJECTS=$(SOURCES:.cc=.o)
LIBRARY=
EXECUTABLE=dmtool
-ifeq ($(PREFIX),)
- PREFIX := /usr
-endif
+PREFIX := /usr
all: $(SOURCES) $(EXECUTABLE)
@@ -16,105 +14,70 @@ parsed: parser/scrapeToJson.py parser/utils.py parser/verified.txt
python parser/scrapeToJson.py
touch parsed/
-install: $(EXECUTABLE) parsed
+install: $(EXECUTABLE)
install -d $(DESTDIR)$(PREFIX)/share/dmtool/
- cp -r parsed/* $(DESTDIR)$(PREFIX)/share/dmtool/
+ #cp -r parsed/* $(DESTDIR)$(PREFIX)/share/dmtool/
install -d $(DESTDIR)$(PREFIX)/bin/
install -m 755 $(EXECUTABLE) $(DESTDIR)$(PREFIX)/bin/
- install -m 644 files/dmtool.bash $(DESTDIR)/usr/share/bash-completion/completions/dmtool
+ install -m 644 files/dmtool.bash $(DESTDIR)`pkg-config --variable=completionsdir bash-completion`/dmtool
install -m 644 files/dmtool.conf $(DESTDIR)/etc/dmtool.conf
$(EXECUTABLE): $(OBJECTS)
- $(CC) $(OBJECTS) -o $@ $(LDFLAGS) `pkg-config $(LIBS) --libs`
+ $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) $(LDLIBS)
-src/dmtool.o: src/dmtool.cc src/cmd/cmd.h src/cmd/../rules.h \
- src/cmd/../utils.h src/cmd/../entry.h src/cmd/../defines.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/item.o: src/item.cc src/item.h src/entry.h src/defines.h src/weapon.h \
- src/rules.h src/utils.h src/armor.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/creature.o: src/creature.cc src/creature.h src/rules.h src/utils.h \
- src/entry.h src/defines.h src/features/feature.h src/item.h src/dice.h \
- src/weapon.h src/armor.h src/attack.h src/spellcasting.h src/spell.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/spellcasting.o: src/spellcasting.cc src/spellcasting.h \
- src/features/feature.h src/features/../entry.h src/features/../defines.h \
- src/spell.h src/rules.h src/utils.h src/defines.h src/creature.h \
- src/item.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/weapon.o: src/weapon.cc src/weapon.h src/item.h src/entry.h \
- src/defines.h src/rules.h src/utils.h src/creature.h \
- src/features/feature.h src/dice.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/dice.o: src/dice.cc src/dice.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/settings.o: src/settings.cc src/settings.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/spell.o: src/spell.cc src/spell.h src/entry.h src/defines.h \
- src/utils.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/features/feature.o: src/features/feature.cc src/features/feature.h \
- src/features/../entry.h src/features/../defines.h \
- src/features/../spellcasting.h src/features/../spell.h \
- src/features/../rules.h src/features/../utils.h src/features/../attack.h \
- src/features/../weapon.h src/features/../item.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/utils.o: src/utils.cc src/utils.h src/entry.h src/defines.h \
- src/settings.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/rules.o: src/rules.cc src/rules.h src/utils.h src/entry.h \
- src/defines.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
src/armor.o: src/armor.cc src/armor.h src/item.h src/entry.h \
src/defines.h src/creature.h src/rules.h src/utils.h \
src/features/feature.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
src/cmd/cmd.o: src/cmd/cmd.cc src/cmd/cmd.h src/cmd/../rules.h \
src/cmd/../utils.h src/cmd/../entry.h src/cmd/../defines.h \
src/cmd/../settings.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/cmd/cmd_usage.o: src/cmd/cmd_usage.cc src/cmd/cmd.h \
- src/cmd/../rules.h src/cmd/../utils.h src/cmd/../entry.h \
- src/cmd/../defines.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
-src/cmd/cmd_query.o: src/cmd/cmd_query.cc src/cmd/cmd.h \
- src/cmd/../rules.h src/cmd/../utils.h src/cmd/../entry.h \
- src/cmd/../defines.h src/cmd/../creature.h src/cmd/../features/feature.h \
- src/cmd/../item.h src/cmd/../dice.h src/cmd/../weapon.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
src/cmd/cmd_fsops.o: src/cmd/cmd_fsops.cc src/cmd/cmd.h \
src/cmd/../rules.h src/cmd/../utils.h src/cmd/../entry.h \
src/cmd/../defines.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
src/cmd/cmd_manipulate.o: src/cmd/cmd_manipulate.cc src/cmd/cmd.h \
src/cmd/../rules.h src/cmd/../utils.h src/cmd/../entry.h \
src/cmd/../defines.h src/cmd/../creature.h src/cmd/../features/feature.h \
src/cmd/../item.h src/cmd/../spellcasting.h src/cmd/../spell.h \
src/cmd/../settings.h src/cmd/../weapon.h src/cmd/../dice.h \
src/cmd/../armor.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
-
+src/cmd/cmd_query.o: src/cmd/cmd_query.cc src/cmd/cmd.h \
+ src/cmd/../rules.h src/cmd/../utils.h src/cmd/../entry.h \
+ src/cmd/../defines.h src/cmd/../creature.h src/cmd/../features/feature.h \
+ src/cmd/../item.h src/cmd/../dice.h src/cmd/../weapon.h
+src/cmd/cmd_usage.o: src/cmd/cmd_usage.cc src/cmd/cmd.h \
+ src/cmd/../rules.h src/cmd/../utils.h src/cmd/../entry.h \
+ src/cmd/../defines.h
+src/creature.o: src/creature.cc src/creature.h src/rules.h src/utils.h \
+ src/entry.h src/defines.h src/features/feature.h src/item.h src/dice.h \
+ src/weapon.h src/armor.h src/attack.h src/spellcasting.h src/spell.h
+src/dice.o: src/dice.cc src/dice.h
+src/dmtool.o: src/dmtool.cc src/cmd/cmd.h src/cmd/../rules.h \
+ src/cmd/../utils.h src/cmd/../entry.h src/cmd/../defines.h
src/entry.o: src/entry.cc src/entry.h src/defines.h src/utils.h \
src/features/feature.h src/item.h src/spell.h src/creature.h src/rules.h
- $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags`
+src/features/feature.o: src/features/feature.cc src/features/feature.h \
+ src/features/../entry.h src/features/../defines.h \
+ src/features/../spellcasting.h src/features/../spell.h \
+ src/features/../rules.h src/features/../utils.h src/features/../attack.h \
+ src/features/../weapon.h src/features/../item.h \
+ src/features/../creature.h
+src/item.o: src/item.cc src/item.h src/entry.h src/defines.h src/weapon.h \
+ src/rules.h src/utils.h src/armor.h
+src/rules.o: src/rules.cc src/rules.h src/utils.h src/entry.h \
+ src/defines.h
+src/settings.o: src/settings.cc src/settings.h
+src/spell.o: src/spell.cc src/spell.h src/entry.h src/defines.h \
+ src/utils.h
+src/spellcasting.o: src/spellcasting.cc src/spellcasting.h \
+ src/features/feature.h src/features/../entry.h src/features/../defines.h \
+ src/spell.h src/rules.h src/utils.h src/defines.h src/creature.h \
+ src/item.h
+src/utils.o: src/utils.cc src/utils.h src/entry.h src/defines.h \
+ src/settings.h
+src/weapon.o: src/weapon.cc src/weapon.h src/item.h src/entry.h \
+ src/defines.h src/rules.h src/utils.h src/creature.h \
+ src/features/feature.h src/dice.h
clean:
- rm -f $(LIBRARY) $(EXECUTABLE)
- find . | grep .o$ | xargs rm -f
+ $(RM) $(LIBRARY) $(EXECUTABLE) $(TEST) $(OBJECTS)
diff --git a/configure b/configure
index b6488b4..61c60b2 100755
--- a/configure
+++ b/configure
@@ -7,10 +7,12 @@ EXECUTABLE="dmtool"
# e.g., foo.so
LIBRARY=
+TEST=
+
# List of libs as given to pkg-config
LIBS="libconfuse nlohmann_json"
-CFLAGS="-c -Wall -fPIC -std=c++20"
+CXXFLAGS="-Wall -fPIC -std=c++20"
LDFLAGS=
@@ -22,15 +24,15 @@ parsed: parser/scrapeToJson.py parser/utils.py parser/verified.txt
touch parsed/
"
-INSTALL="
-install: \$(EXECUTABLE) parsed
- install -d \$(DESTDIR)\$(PREFIX)/share/dmtool/
- cp -r parsed/* \$(DESTDIR)\$(PREFIX)/share/dmtool/
- install -d \$(DESTDIR)\$(PREFIX)/bin/
- install -m 755 \$(EXECUTABLE) \$(DESTDIR)\$(PREFIX)/bin/
- install -m 644 files/dmtool.bash \$(DESTDIR)`pkg-config --variable=completionsdir bash-completion`/dmtool
- install -m 644 files/dmtool.conf \$(DESTDIR)/etc/dmtool.conf
-"
+INSTALL='
+install: $(EXECUTABLE) parsed
+ install -d $(DESTDIR)$(PREFIX)/share/dmtool/
+ cp -r parsed/* $(DESTDIR)$(PREFIX)/share/dmtool/
+ install -d $(DESTDIR)$(PREFIX)/bin/
+ install -m 755 $(EXECUTABLE) $(DESTDIR)$(PREFIX)/bin/
+ install -m 644 files/dmtool.bash $(DESTDIR)`pkg-config --variable=completionsdir bash-completion`/dmtool
+ install -m 644 files/dmtool.conf $(DESTDIR)/etc/dmtool.conf
+'
# Below here shouldn't need editing
@@ -49,7 +51,7 @@ LIBRULE=
if [ -n "$LIBRARY" ]; then
LIBRULE="
\$(LIBRARY): \$(OBJECTS)
- \$(CC) \$(OBJECTS) -shared -o \$@ \$(LDFLAGS) $PKG_CONFIG_LIBS
+ \$(CXX) \$(OBJECTS) -shared -o \$@ \$(LDFLAGS) \$(LDLIBS)
"
ALL="$ALL \$(LIBRARY)"
fi
@@ -58,32 +60,42 @@ EXERULE=
if [ -n "$EXECUTABLE" ]; then
EXERULE="
\$(EXECUTABLE): \$(OBJECTS)
- \$(CC) \$(OBJECTS) -o \$@ \$(LDFLAGS) $PKG_CONFIG_LIBS
+ \$(CXX) \$(OBJECTS) -o \$@ \$(LDFLAGS) \$(LDLIBS)
"
ALL="$ALL \$(EXECUTABLE)"
fi
-ORULES=$(for cc in `find $SOURCE_DIR | grep .cc$`; do g++ -MM -MT `cut -d'.' -f-1 <<< $cc`.o $cc; echo -e "\t"'$(CC) $(CFLAGS) $< -o $@ '"$PKG_CONFIG_CFLAGS\n"; done)
+TESTRULE=
+if [ -n "$TEST" ]; then
+ TESTRULE="
+\$(TEST): \$(OBJECTS)
+ \$(CXX) \$(OBJECTS) -o \$@ \$(LDFLAGS) \$(LDLIBS) -lcppunit
+
+test: \$(TEST)
+ ./\$(TEST)
+"
+ ALL="$ALL \$(TEST)"
+fi
+
+
+ORULES=$(for cc in `find $SOURCE_DIR | grep .cc$`; do g++ -MM -MT `cut -d'.' -f-1 <<< $cc`.o $cc; done)
cat << EOF > Makefile
-CC=g++
LIBS=$LIBS
-CFLAGS=$CFLAGS
-LDFLAGS=$LDFLAGS
+override CXXFLAGS += $CXXFLAGS $PKG_CONFIG_CFLAGS
+override LDFLAGS += $LDFLAGS $PKG_CONFIG_LIBS
+CC=\$(CXX)
SOURCES=$SOURCES
OBJECTS=\$(SOURCES:.cc=.o)
LIBRARY=$LIBRARY
EXECUTABLE=$EXECUTABLE
-ifeq (\$(PREFIX),)
- PREFIX := /usr
-endif
+PREFIX := /usr
$ALL
-$EXTRAS$INSTALL$LIBRULE$EXERULE
+$EXTRAS$INSTALL$LIBRULE$EXERULE$TESTRULE
$ORULES
clean:
- rm -f \$(LIBRARY) \$(EXECUTABLE)
- find . | grep .o\$ | xargs rm -f
+ \$(RM) \$(LIBRARY) \$(EXECUTABLE) \$(TEST) \$(OBJECTS)
EOF
diff --git a/features/aberrant_ground.json b/features/aberrant_ground.json
index 4e72225..dc5f1f9 100644
--- a/features/aberrant_ground.json
+++ b/features/aberrant_ground.json
@@ -1,26 +1,23 @@
{
"name": "aberrant ground",
- "text": "The ground in a 10-foot radius around the {NAME} is doughlike difficult terrain. Each creature that starts its turn in that area must succeed on a DC {(8,PROF,STR,+,+)} Strength saving throw or have its speed reduced to 0 until the start of its next turn.",
+ "text": "The ground in a 10-foot radius around the {NAME} is doughlike difficult terrain. Each creature that starts its turn in that area must succeed on a DC {8,PROF,STR,+,+} Strength saving throw or have its speed reduced to 0 until the start of its next turn.",
"subfeatures": [
{
- "trigger": [ "N end of turn", "self" ],
- "conditions": [],
+ "trigger": "self,turnend",
"effects": [{
- "target": "self",
- "effect": [ "Terrain in X ft radius is difficult", 10 ],
- "duration": "Start of next turn"
+ "target": "terrain",
+ "condition": "terrain,self,distance,10,<=",
+ "effect": "1,terrain.TERRAIN_IS_DIFFICULT,store",
+ "duration": "self,turnstart"
}]
},
{
- "trigger": [ "N start of turn", "creature" ],
- "conditions": [
- [ "N is within radius X of N", "creature", 10, "self" ],
- [ "N succeeds dc X ABILITY save by at least X", "creature", "(8,PROF,STR,+,+)", "STR", 0 ]
- ],
+ "trigger": "creature,turnstart",
+ "condition": "creature,self,distance,10,<=,creature,strength,roll,8,PROF,STR,+,+,>=,&",
"effects": [{
"target": "creature",
- "effect": [ "Set movement speed to X", 0 ],
- "duration": "Start of next turn"
+ "effect": "0,creature.MOVESPEED,store",
+ "duration": "creature,turnstart"
}]
}
]
diff --git a/features/acid_spray.json b/features/acid_spray.json
index a24905a..78cd8cc 100644
--- a/features/acid_spray.json
+++ b/features/acid_spray.json
@@ -1,15 +1,16 @@
{
- "name": "acid spray (recharge 6) (action)",
- "text": "The ankheg spits acid in a line that is 30 feet long and 5 feet wide, provided that it has no creature grappled. Each creature in that line must make a DC 13 Dexterity saving throw, taking 10 (3d6) acid damage on a failed save, or half as much damage on a successful one.",
+ "name": "acid spray",
+ "text": "The {NAME} spits acid in a line that is {V0} feet long and {V1} feet wide, provided that it has no creature grappled. Each creature in that line must make a DC {8,STR,PROF,+,+} Dexterity saving throw, taking {V2}d{V3} acid damage on a failed save, or half as much damage on a successful one.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": "action",
+ "condition": "self.GRAPPLED,!",
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
- }]
+ "target": "creatures",
+ "effect conditions": [[ "N is in AOE", "creature", "line {V0} {V1}" ]],
+ "effect": [ "Inflict XdX TYPE damage, dc X ABILITY save halves", "V2", "V3", "acid", "(8,STR,PROF,+,+)", "dexterity" ]
+ }],
+ "recharge": [ 1, "6-6" ]
}
]
}
diff --git a/features/adhesive.json b/features/adhesive.json
index f432534..60a772e 100644
--- a/features/adhesive.json
+++ b/features/adhesive.json
@@ -5,12 +5,12 @@
{
"trigger": [ "N touches N", "creature", "self" ],
"conditions": [
- [ "N has property PROPERTY = VALUE", "self", "Form", "Object" ],
- [ "not N has property Property", "other", "Size", "Gargantuan" ]
+ [ "(FORM_STATE,0,>)" ],
+ [ "(creature.SIZE,15,<=)" ]
],
"effects": [{
"target": "creature",
- "effect": [ "Acquire condition CONDITION", "grappled" ]
+ "effect": [ "set N = N", "creature.GRAPPLED", 1 ]
}]
},
{
diff --git a/features/air_form.json b/features/air_form.json
index 6d47718..030c8ac 100644
--- a/features/air_form.json
+++ b/features/air_form.json
@@ -7,11 +7,11 @@
"conditions": [],
"effects": [{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Can stop in hostile space", "True" ]
+ "effect" : [ "Set N = N", "CAN_STOP_IN_HOSTILE_SPACE", 1 ]
},
{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Minimum space to move without squeezing", "1\"" ]
+ "effect" : [ "Set N = N", "MIN_SPACE_WITHOUT_SQUEEZING", "1\"" ]
}]
}
]
diff --git a/features/amorphous.json b/features/amorphous.json
index 1b0392b..098bf52 100644
--- a/features/amorphous.json
+++ b/features/amorphous.json
@@ -7,7 +7,7 @@
"conditions": [],
"effects": [{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Minimum space to move without squeezing", "1\"" ]
+ "effect" : [ "Set N = N", "MIN_SPACE_WITHOUT_SQUEEZING", "1\"" ]
}]
}
]
diff --git a/features/amphibious.json b/features/amphibious.json
index 5aef528..0ef1b5f 100644
--- a/features/amphibious.json
+++ b/features/amphibious.json
@@ -7,11 +7,11 @@
"conditions": [],
"effects": [{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Can breathe air", "True" ]
+ "effect" : [ "Set N = N", "BREATHES_AIR", 1 ]
},
{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Can breathe water", "True" ]
+ "effect" : [ "Set N = N", "BREATHES_WATER", 1 ]
}]
}
]
diff --git a/features/animate_chains.json b/features/animate_chains.json
deleted file mode 100644
index 1f42da1..0000000
--- a/features/animate_chains.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "animate chains (recharges after a short or long rest) (action)",
- "text": "Up to four chains the devil can see within 60 feet of it magically sprout razor-­edged barbs and animate under the devil's control, provided that the chains aren't being worn or carried.",
- "subfeatures": [
- {
- "trigger": [],
- "conditions": [],
- "effects": [{
- "target": "",
- "effect": [],
- "duration": ""
- }]
- }
- ]
-}
diff --git a/features/antennae.json b/features/antennae.json
index 12739a4..3945752 100644
--- a/features/antennae.json
+++ b/features/antennae.json
@@ -1,14 +1,22 @@
{
- "name": "antennae (action)",
- "text": "The rust monster corrodes a nonmagical ferrous metal object it can see within 5 feet of it. If the object isn't being worn or carried, the touch destroys a 1-foot cube of it. If the object is being worn or carried by a creature, the creature can make a DC 11 Dexterity saving throw to avoid the rust monster's touch.",
+ "name": "antennae",
+ "text": "The {NAME} corrodes a nonmagical ferrous metal object it can see within 5 feet of it. If the object isn't being worn or carried, the touch destroys a 1-foot cube of it. If the object is being worn or carried by a creature, the creature can make a DC {(8,PROF,STR,+,+)} Dexterity saving throw to avoid the rust monster's touch. If the object touched is either metal armor or a metal shield being worn or carried, its takes a permanent and cumulative −1 penalty to the AC it offers. Armor reduced to an AC of 10 or a shield that drops to a +0 bonus is destroyed. If the object touched is a held metal weapon, it rusts as described in the Rust Metal trait.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": [ "action" ],
+ "conditions": [
+ [ "N is within radius X of N", "object", "5'", "self" ],
+ [ "N is made of metal", "object" ],
+ [ "N is worn or carried by N", "object", "creature" ],
+ [ "N fails dc X ABILITY save by at least X", "creature", "(8,PROF,STR,+,+)", "dexterity", 0 ]
+ ],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "object",
+ "effect": [ "Set N = N", "object.RUST", "(object.RUST,1,+)" ]
+ }, {
+ "target": "object",
+ "effect conditions": [[ "(object.OBJECT_TYPE,1,==,object.RUST,5,>=,&,object.OBJECT_TYPE,2,==,object.RUST,object.OBJECT_AC,-,10,<=,&,object.OBJECT_TYPE,3,==,object.RUST,object.OBJECT_AC,-,0,<=,&,|,|)" ]],
+ "effect": [ "Destroyed" ]
}]
}
]
diff --git a/features/antimagic_susceptibility.json b/features/antimagic_susceptibility.json
index 7e8b0c8..73c1785 100644
--- a/features/antimagic_susceptibility.json
+++ b/features/antimagic_susceptibility.json
@@ -7,7 +7,7 @@
"conditions": [],
"effects": [{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Is incapacitated by antimagic field", "True" ]
+ "effect" : [ "Set N = N", "ANTIMAGIC_INCAPACITATES", 1 ]
}]
},
{
@@ -18,7 +18,7 @@
],
"effects": [{
"target": "self",
- "effect": [ "Acquire condition CONDITION", "unconscious" ],
+ "effect": [ "Set N = N", "UNCONSCIOUS", 1 ],
"duration": "1 min"
}]
}
diff --git a/features/attack.json b/features/attack.json
deleted file mode 100644
index 49879e0..0000000
--- a/features/attack.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "attack (legendary_action)",
- "text": "The tarrasque makes one claw attack or tail attack.",
- "subfeatures": [
- {
- "trigger": [],
- "conditions": [],
- "effects": [{
- "target": "",
- "effect": [],
- "duration": ""
- }]
- }
- ]
-}
diff --git a/features/attack_tarrasque.json b/features/attack_tarrasque.json
new file mode 100644
index 0000000..7974904
--- /dev/null
+++ b/features/attack_tarrasque.json
@@ -0,0 +1,22 @@
+{
+ "name": "attack",
+ "text": "The {NAME} makes one claw attack or tail attack.",
+ "subfeatures": [
+ {
+ "trigger": [ "legendary action costing X", 1 ],
+ "conditions": [],
+ "effects": [{
+ "target": "self",
+ "effect": [ "Take action ACTION", "claw" ]
+ }]
+ },
+ {
+ "trigger": [ "legendary action costing X", 1 ],
+ "conditions": [],
+ "effects": [{
+ "target": "self",
+ "effect": [ "Take action ACTION", "tail" ]
+ }]
+ }
+ ]
+}
diff --git a/features/aversion_of_fire.json b/features/aversion_of_fire.json
index 2072454..d4d4c96 100644
--- a/features/aversion_of_fire.json
+++ b/features/aversion_of_fire.json
@@ -8,12 +8,12 @@
"effects": [{
"target": "self",
"effect": [ "Impose disadvantage on TYPE", "attack rolls" ],
- "duration": "End of next turn"
+ "duration": "End of target next turn"
},
{
"target": "self",
"effect": [ "Impose disadvantage on TYPE", "ability checks" ],
- "duration": "End of next turn"
+ "duration": "End of target next turn"
}]
}
]
diff --git a/features/beast_of_burden.json b/features/beast_of_burden.json
index 3e6c9b1..c3f6509 100644
--- a/features/beast_of_burden.json
+++ b/features/beast_of_burden.json
@@ -7,7 +7,7 @@
"conditions": [],
"effects": [{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Carrying capacity size is X", "Large" ]
+ "effect": [ "Set N = N", "CARRY_CAPACITY", "(30,STR,*)" ]
}]
}
]
diff --git a/features/berserk.json b/features/berserk.json
index c0f0c8b..0042a7b 100644
--- a/features/berserk.json
+++ b/features/berserk.json
@@ -4,18 +4,18 @@
"subfeatures": [
{
"trigger": [ "N start of turn", "self" ],
- "conditions": [ "N has COND X hp", "self", "<=", "V0" ],
+ "conditions": [ "(HP,V0,<=)" ],
"effects": [{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Is berserk", "True" ]
+ "effect": [ "Set N = N", "BERSERK", 1 ]
}]
},
{
"trigger": [ "N start of turn", "self" ],
- "conditions": [ "N has COND X hp", "self", "==", "MAXHP" ],
+ "conditions": [ "(HP,MAXHP,==)" ],
"effects": [{
"target": "self",
- "effect": [ "Set property PROPERTY to X", "Is berserk", "False" ]
+ "effect": [ "Set N = N", "BERSERK", 0 ]
}]
}
]
diff --git a/features/blasphemous_word.json b/features/blasphemous_word.json
index feca4c9..010492f 100644
--- a/features/blasphemous_word.json
+++ b/features/blasphemous_word.json
@@ -6,14 +6,14 @@
"trigger": [ "legendary action costing X", "V0" ],
"conditions": [],
"effects": [{
- "target": "creature",
+ "target": "creatures",
"effect conditions": [
- [ "N has property PROPERTY = VALUE", "creature", "Is alive", "True" ],
+ [ "creature.ALIVE" ],
[ "N is within radius X of N", "creature", "self", "10'" ],
- [ ]
+ [ "N fails dc X ABILITY save by at least X", "creature", "(8,PROF,CON,+,+)", "constitution", 0 ]
],
- "effect": [],
- "duration": ""
+ "effect": [ "set N = N", "creature.STUNNED", 1 ],
+ "duration": "End of self next turn"
}]
}
]
diff --git a/features/blind_senses.json b/features/blind_senses.json
index eb8b5a2..ebf114a 100644
--- a/features/blind_senses.json
+++ b/features/blind_senses.json
@@ -1,14 +1,13 @@
{
- "name": "blind senses (feature)",
- "text": ". The grimlock can't use its blindsight while deafened and unable to smell.",
+ "name": "blind senses",
+ "text": "The {NAME} can't use its blindsight while deafened and unable to smell.",
"subfeatures": [
{
- "trigger": [],
+ "trigger": [ "passive" ],
"conditions": [],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "self",
+ "effect": [ "Set N = N", "BLINDSIGHT", "(30,BLINDED,!,CAN_SMELL,&,&)" ]
}]
}
]
diff --git a/features/blinding_breath.json b/features/blinding_breath.json
index e7e6d89..dd26a79 100644
--- a/features/blinding_breath.json
+++ b/features/blinding_breath.json
@@ -1,19 +1,20 @@
{
- "name": "blinding breath (recharge 6)",
+ "name": "blinding breath",
"text": "The {NAME} exhales a {V0}-foot cone of blinding dust. Each creature in that area must succeed on a DC {(8,PROF,CON,+,+)} Dexterity saving throw or be blinded for 1 minute. A creature can repeat the saving throw at the end of each of its turns, ending the effect on itself on a success.",
"subfeatures": [
{
"trigger": [ "action" ],
"conditions": [],
"effects": [{
- "target": "creature",
+ "target": "creatures",
"effect conditions": [
[ "N is in AOE", "creature", "cone {V0}" ],
[ "N fails dc X ABILITY save by at least X", "creature", "(8,PROF,CON,+,+)", "dexterity", "0" ]
],
- "effect": [ "Acquire condition CONDITION", "blinded" ],
+ "effect": [ "set N = N", "creature.BLINDED", 1 ],
"duration": "1 min"
- }]
+ }],
+ "recharge": [ 1, "6-6" ]
}
]
}
diff --git a/features/blinding_dust.json b/features/blinding_dust.json
index a8e0403..658c7f1 100644
--- a/features/blinding_dust.json
+++ b/features/blinding_dust.json
@@ -1,14 +1,18 @@
{
"name": "blinding dust (legendary_action)",
- "text": "Blinding dust and sand swirls magically around the mummy lord. Each creature within 5 feet of the mummy lord must succeed on a DC 16 Constitution saving throw or be blinded until the end of the creature's next turn.",
+ "text": "Blinding dust and sand swirls magically around the {NAME}. Each creature within 5 feet of the {NAME} must succeed on a DC {(8,PROF,CON,+,+)} Constitution saving throw or be blinded until the end of the creature's next turn.",
"subfeatures": [
{
- "trigger": [],
+ "trigger": [ "legendary action costing X", 1 ],
"conditions": [],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "creatures",
+ "effect conditions": [
+ [ "N is within radius X of N", "creature", "5'", "self" ],
+ [ "N fails dc X ABILITY save by at least X", "creature", "(8,PROF,CON,+,+)", "constitution", 0 ]
+ ],
+ "effect": [ "set N = N", "creature.BLINDED", 1 ],
+ "duration": "End of target next turn"
}]
}
]
diff --git a/features/blinding_gaze.json b/features/blinding_gaze.json
index 77a1d37..a3b2d3b 100644
--- a/features/blinding_gaze.json
+++ b/features/blinding_gaze.json
@@ -1,14 +1,19 @@
{
- "name": "blinding gaze (costs 3 actions) (legendary_action)",
- "text": "The solar targets one creature it can see within 30 feet of it. If the target can see it, the target must succeed on a DC 15 Constitution saving throw or be blinded until magic such as the lesser restoration spell removes the blindness.",
+ "name": "blinding gaze",
+ "text": "The {NAME} targets one creature it can see within 30 feet of it. If the target can see it, the target must succeed on a DC {(8,PROF,+)} Constitution saving throw or be blinded until magic such as the lesser restoration spell removes the blindness.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": [ "legendary action costing X", 3 ],
+ "conditions": [
+ [ "N can see N", "self", "creature" ],
+ [ "N is within radius X of N", "creature", "30'", "self" ],
+ [ "N can see N", "creature", "self" ],
+ [ "N fails dc X ABILITY save by at least X", "creature", "(8,PROF,+)", "constitution", 0 ]
+ ],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "creature",
+ "effect": [ "set N = N", "creature.BLINDED", 1 ],
+ "duration": "Until lesser restoration is cast"
}]
}
]
diff --git a/features/blinding_spittle.json b/features/blinding_spittle.json
index c282651..93b0bc9 100644
--- a/features/blinding_spittle.json
+++ b/features/blinding_spittle.json
@@ -1,14 +1,22 @@
{
- "name": "blinding spittle (recharge 5–6) (action)",
- "text": "The mouther spits a chemical glob at a point it can see within 15 feet of it. The glob explodes in a blinding flash of light on impact. Each creature within 5 feet of the flash must succeed on a DC 13 Dexterity saving throw or be blinded until the end of the mouther's next turn.",
+ "name": "blinding spittle",
+ "text": "The {NAME} spits a chemical glob at a point it can see within 15 feet of it. The glob explodes in a blinding flash of light on impact. Each creature within 5 feet of the flash must succeed on a DC {(8,PROF,CON,+,+)} Dexterity saving throw or be blinded until the end of the {NAME}'s next turn.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": [ "action" ],
+ "conditions": [
+ [ "N is within radius X of N", "point in space", "15'", "self" ],
+ [ "N can see N", "self", "point in space" ]
+ ],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "creatures",
+ "effect conditions": [
+ [ "N is within radius X of N", "point in space", "5'", "creature" ],
+ [ "N fails dc X ABILITY save by at least X", "creature", "(8,PROF,CON,+,+)", "dexterity", 0 ]
+ ],
+ "effect": [ "set N = N", "creature.BLINDED", 1 ],
+ "duration": "End of self next turn",
+ "recharge": "5-6"
}]
}
]
diff --git a/features/blood_frenzy.json b/features/blood_frenzy.json
index ebea84c..b6f9f87 100644
--- a/features/blood_frenzy.json
+++ b/features/blood_frenzy.json
@@ -1,14 +1,16 @@
{
- "name": "blood frenzy (feature)",
- "text": "The sahuagin has advantage on melee attack rolls against any creature that doesn't have all its hit points.",
+ "name": "blood frenzy",
+ "text": "The {NAME} has advantage on melee attack rolls against any creature that doesn't have all its hit points.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": [ "N attacks N", "self", "creature" ],
+ "conditions": [
+ ["N made melee attack", "self" ],
+ [ "(creature.HP,creature.MAXHP,<)" ]
+ ],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "self",
+ "effect": [ "Grant advantage" ]
}]
}
]
diff --git a/features/brave.json b/features/brave.json
index adf3d43..2c2584a 100644
--- a/features/brave.json
+++ b/features/brave.json
@@ -1,14 +1,13 @@
{
- "name": "brave (feature)",
- "text": "The gladiator has advantage on saving throws against being frightened.",
+ "name": "brave",
+ "text": "The {NAME} has advantage on saving throws against being frightened.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": [ "N forces N to save", "any", "self" ],
+ "conditions": [ "N == N", "V0", "frightened" ],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "self",
+ "effect": [ "Grant advantage" ]
}]
}
]
diff --git a/features/breath_attack.json b/features/breath_attack.json
index 26f90a5..dfb7fa4 100644
--- a/features/breath_attack.json
+++ b/features/breath_attack.json
@@ -6,7 +6,7 @@
"trigger": [ "action" ],
"conditions": [],
"effects": [{
- "target": "creature",
+ "target": "creatures",
"effect conditions": [[ "N is in AOE", "creature", "line {V1} {V2}" ]],
"effect": [ "Inflict XdX TYPE damage, dc X ABILITY save halves", "V3", "V4", "V0", "(8,CON,PROF,+,+)", "dexterity" ]
}],
diff --git a/features/brute.json b/features/brute.json
index b1a6808..7657d39 100644
--- a/features/brute.json
+++ b/features/brute.json
@@ -1,14 +1,13 @@
{
- "name": "brute (feature)",
- "text": "A melee weapon deals one extra die of its damage when the gladiator hits with it (included in the attack).",
+ "name": "brute",
+ "text": "A melee weapon deals one extra die of its damage when the {NAME} hits with it.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": [ "N hits N", "self", "any" ],
+ "conditions": [ "N made melee attack", "self" ],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "any",
+ "effect": [ "Deal +X weapon die damage", 1 ]
}]
}
]
diff --git a/features/cantrip.json b/features/cantrip.json
index 904d3f3..993f0bb 100644
--- a/features/cantrip.json
+++ b/features/cantrip.json
@@ -1,14 +1,13 @@
{
- "name": "cantrip (legendary_action)",
- "text": "The lich casts a cantrip.",
+ "name": "cantrip",
+ "text": "The {NAME} casts a cantrip.",
"subfeatures": [
{
- "trigger": [],
+ "trigger": [ "legendary action costing X", 1 ],
"conditions": [],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "self",
+ "effect": [ "Take action ACTION", "cantrip" ]
}]
}
]
diff --git a/features/cast_a_spell.json b/features/cast_a_spell.json
index 3155c67..d154b92 100644
--- a/features/cast_a_spell.json
+++ b/features/cast_a_spell.json
@@ -1,14 +1,13 @@
{
- "name": "cast a spell (costs 3 actions) (legendary_action)",
- "text": "The sphinx casts a spell from its list of prepared spells, using a spell slot as normal.",
+ "name": "cast a spell",
+ "text": "The {NAME} casts a spell from its list of prepared spells, using a spell slot as normal.",
"subfeatures": [
{
- "trigger": [],
+ "trigger": [ "legendary action costing X", 3 ],
"conditions": [],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "self",
+ "effect": [ "Take action ACTION", "cast spell" ]
}]
}
]
diff --git a/features/change_shape.json b/features/change_shape.json
index 77fc0fb..e7c05f5 100644
--- a/features/change_shape.json
+++ b/features/change_shape.json
@@ -1,14 +1,14 @@
{
- "name": "change shape (action)",
- "text": "The dragon magically polymorphs into a humanoid or beast that has a challenge rating no higher than its own, or back into its true form. It reverts to its true form if it dies. Any equipment it is wearing or carrying is absorbed or borne by the new form (the dragon's choice).",
+ "name": "change shape",
+ "text": "The {NAME} magically polymorphs into a humanoid or beast that has a challenge rating no higher than its own, or back into its true form. It reverts to its true form if it dies. Any equipment it is wearing or carrying is absorbed or borne by the new form (the {NAME}'s choice).",
"subfeatures": [
{
- "trigger": [],
+ "trigger": [ "action" ],
"conditions": [],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "self",
+ "effect": [ "Polymorph N into creature <= X cr", "self", "(CR)" ],
+ "duration": "Until overridden or dead"
}]
}
]
diff --git a/features/channel_negative_energy.json b/features/channel_negative_energy.json
index 42e216b..311d43c 100644
--- a/features/channel_negative_energy.json
+++ b/features/channel_negative_energy.json
@@ -1,14 +1,15 @@
{
- "name": "channel negative energy (costs 2 actions) (legendary_action)",
- "text": "The mummy lord magically unleashes negative energy. Creatures within 60 feet of the mummy lord, including ones behind barriers and around corners, can't regain hit points until the end of the mummy lord's next turn.",
+ "name": "channel negative energy",
+ "text": "The {NAME} magically unleashes negative energy. Creatures within 60 feet of the {NAME}, including ones behind barriers and around corners, can't regain hit points until the end of the {NAME}'s next turn.",
"subfeatures": [
{
- "trigger": [],
+ "trigger": [ "legendary action costing X", 2 ],
"conditions": [],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "creatures",
+ "effect conditions": [[ "N is within radius X of N", "creature", "60'", "self" ]],
+ "effect": [ "set N = N", "creature.REGAINS_HP", 0 ],
+ "duration": "End of self next turn"
}]
}
]
diff --git a/features/charge.json b/features/charge.json
index 646de65..2941fa3 100644
--- a/features/charge.json
+++ b/features/charge.json
@@ -1,14 +1,24 @@
{
- "name": "charge (feature)",
- "text": "If the unicorn moves at least 20 feet straight toward a target and then hits it with a horn attack on the same turn, the target takes an extra 9 (2d8) piercing damage. If the target is a creature, it must succeed on a DC 15 Strength saving throw or be knocked prone.",
+ "name": "charge",
+ "text": "If the {NAME} moves at least {V0} feet straight toward a target and then hits it with a {V1} attack on the same turn, the target takes an extra {V2}d{V3} {V4} damage. If the target is a creature, it must succeed on a DC {(8,PROF,STR,+,+)} Strength saving throw or be knocked prone.",
"subfeatures": [
{
- "trigger": [],
- "conditions": [],
+ "trigger": [ "N hits N", "self", "any" ],
+ "conditions": [
+ ["N moved X distance straight toward N", "self", "(V0)", "any" ],
+ [ "N made attack ATTACK", "(V1)" ]
+ ],
"effects": [{
- "target": "",
- "effect": [],
- "duration": ""
+ "target": "any",
+ "effect": [ "Inflict XdX TYPE damage", "(V2)", "(V3)", "(V4)" ]
+ },
+ {
+ "target": "any",
+ "effect conditions": [
+ [ "N == N", "any.OBJECT_TYPE", -1 ],
+ [ "N fails dc X ABILITY save by at least X", "any", "(8,PROF,STR,+,+)", "strength", 0 ]
+ ],
+ "effect": [ "set N = N", "any.PRONE", 1 ]
}]
}
]
diff --git a/features/charm.json b/features/charm.json
deleted file mode 100644
index 9f6ffe0..0000000
--- a/features/charm.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "charm (action)",
- "text": "The vampire targets one humanoid it can see within 30 feet of it. If the target can see the vampire, the target must succeed on a DC 17 Wisdom saving throw against this magic or be charmed by the vampire. The charmed target regards the vampire as a trusted friend to be heeded and protected. Although the target isn't under the vampire's control, it takes the vampire's requests or actions in the most favorable way it can, and it is a willing target for the vampire's bite attack.",
- "subfeatures": [
- {
- "trigger": [],
- "conditions": [],
- "effects": [{
- "target": "",
- "effect": [],
- "duration": ""
- }]
- }
- ]
-}
diff --git a/features/readme.md b/features/readme.md
index fda276b..73fbdec 100644
--- a/features/readme.md
+++ b/features/readme.md
@@ -10,6 +10,22 @@ The overall structure of a feature is a dictionary as follows:
In addition to the hardcoded data provided in the feature, certain variables may be given at runtime.
+## NOUNS
+
+Nouns embedded into subfeature elements may be any of:
+
+ * "self"
+ * "creature"
+ * "creatures" (i.e., all creatures for whom "effect conditions" are true)
+ * "object"
+ * "structure"
+ * "point in space"
+ * "any"
+ * "terrain"
+ * NAME
+
+Where NAME is interpreted by the game as a specific creature or object with a matching name.
+
## Variables
Many features are very similar between creatures except for certain variables. When instantiated programatically, the feature is given the following:
@@ -19,7 +35,7 @@ Many features are very similar between creatures except for certain variables. W
Certain portions of features accept these as parameters, either inline as in TEXT, or in the place of hardcoded variables for conditions or effects.
-In addition to these, certain attributes of the creature having this feature may be probed such as:
+In addition to these, certain attributes of the creature having this feature may be probed (as they are intrinsic, modifications are reverted at the end of a duration) such as:
* STR
* DEX
* CON
@@ -28,12 +44,127 @@ In addition to these, certain attributes of the creature having this feature may
* CHA
* PROF
* MAXHP
+ * HP
* MOVESPEED
+ * MOVEREMAIN
* SPELLDC
+ * SIZE (stored as a scalar, e.g., 5 for Medium or 2.5 for Tiny)
+ * OBJECT\_TYPE (-1: creature, 0: misc item, 1: weapon, 2: armor, 3: shield)
+ * OBJECT\_AC
+ * CR
+ * PLANE = 0 (each value is a different plane)
+ * DAMAGE (Returns a damage object regarding the most recent time this was hit):
+ * AMOUNT
+ * CRITICAL
+ * TYPE
+ * ATTACK (Returns an attack object regarding the most recent attack this made):
+ * MELEE
+ * ADVANTAGE
+ * DISADVANTAGE
+ * WEAPON (0 is none, else weapon ID)
+ * TURNS (number of completed turns since rolling initiative)
+ * FLYING
+ * TERRAIN (current terain)
+ * LIGHTING (i.e., sunlight, dim light, darkness, magical darkness)
+ * LANGUAGECOUNT
+ * SURPRISED
+ * METAL (i.e., made of metal)
+ * TERRAIN\_IS\_DIFFICULT (only applies to terrain)
+
+Furthermore, this list is expanded with the following properties and conditions (default values provided) (note: for conditions other than EXHAUSTED, e.g., GRAPPLED, the value is the ID of the source of the condition):
+ * BLINDED = 0
+ * CHARMED = 0
+ * DEAFENED = 0
+ * FRIGHTENED = 0
+ * GRAPPLED = 0
+ * INCAPACITATED = 0
+ * INVISIBLE = 0
+ * PARALYZED = 0
+ * PETRIFIED = 0
+ * POISONED = 0
+ * PRONE = 0
+ * RESTRAINED = 0
+ * STUNNED = 0
+ * UNCONSCIOUS = 0
+ * EXHAUSTED = 0 (ranges up to 6)
+ * REGAINS\_HP = 1
+ * CAN\_STOP\_IN\_HOSTILE\_SPACE = 0
+ * MIN\_SPACE\_WITHOUT\_SQUEEZING = SIZE
+ * BREATHES\_AIR = 1
+ * BREATHES\_WATER = 0
+ * BREATH\_HOLD\_MINUTES = (1,CON,+,.5,max)
+ * CARRY\_CAPACITY = (2,SIZE,2.5,-,SIZE,0,ifelse,5,-,5,/,^,15,\*,STR,\*)
+ * BERSERK = 0
+ * TELEPATHIC = 0 (0 = no, 1 = yes, .5 = one-way)
+ * DASH = 0 (0 = action, 1 = bns action)
+ * DISENGAGE = 0
+ * HIDE = 0
+ * SEES\_MAGICAL\_DARKNESS = 0
+ * SEES\_ETHEREAL = 0
+ * DETECTS\_LIES = 0
+ * LEAVES\_CORPSE = 1
+ * HOLDS\_INVENTORY = 1
+ * PROVOKES\_OPPORTUNITY\_ATTACKS = 1
+ * IGNORES\_DIFFICULT\_TERRAIN = 0
+ * PASSES\_THROUGH\_CREATURES\_AS\_DIFFICULT\_TERRAIN = 0
+ * IGNORES\_WEBS = 0
+ * REACTIONS = 1
+ * BRIGHT\_LIGHT = 0
+ * DIM\_LIGHT = 0
+ * PERFECT\_MAP\_RECALL = 0
+ * MIMIC\_SOUNDS\_VOICES\_INSIGHT\_DC = (PERFORMANCE,DECEPTION,max)
+ * SPEAKS\_WITH\_BEASTS = 0
+ * SPEAKS\_WITH\_PLANTS = 0
+ * SPIDER\_CLIMB = 0
+ * BOILS\_WATER = 0
+ * FORM\_STATE = 0 (0 is true form, others are defined in features)
+ * MUNDANE\_OBJECT\_WHEN\_STILL = 0
+ * CAN\_SMELL = 1
+ * ALIGNMENT = 11 (00: LG, 11: NN, 22: CE, etc.)
+ * ANTIMAGIC\_INCAPACITATES = 0
+ * ALIVE = 1
+ * BLINDSIGHT = 0
+ * RUST = 0
+ * EXPOSED = 0 (underside is exposed)
+ * HEADS = 1
+ * SPELLSLOTS = 0 (num remaining)
+ * NV1, NV2, ... (variables saved to N private only to this feature, all initially 0)
The above attributes by default apply to self (i.e., self.STR), however, they may also be used for another creature (i.e., creature.STR).
-Finally, simple math can be provided in postfix notation surounded by parentheses. For example, to set a save DC equal to 8+int+prof: (8,INT,PROF,+,+).
+Simple math can be provided in postfix notation surounded by parentheses. For example, to set a save DC equal to 8+int+prof: (8,INT,PROF,+,+), or to set breath time to max(.5, 1+CON): (1,CON,+,.5,max). Additionally, boolean expressions may be imbedded, using "|" for "or", "&" for "and", "!" for not (which only consumes one operand), comparitors (i.e., "<", ">", "<=", ">=", "=="), and an "ifelse" expresion, with 0 being false and any else being true. The following rules are respected; note order matters:
+
+ * (X,Y,&) -> 0 if Y == 0, else X
+ * (X,Y,|) -> Y if X == 0, else X
+ * (X,!) -> 1 if X == 0, else 0
+ * (X,Y,<) -> 1 if X < Y, else 0
+ * (X,Y,Z,ifelse) -> if X != 0 then Y, else Z
+ * (X,consume) -> removes X from the stack
+ * (X,duplicate) -> X, X
+ * (X,Y,store) -> X, and stores X to variable Y
+
+More complex conditions are below, potentially resulting in complex "types":
+
+ * bool: 0 is false, 1 is true
+ * creature: stored as creature ID
+ * TYPE: various constants for skills, abilities, damage types, etc.
+
+Syntax is "operator": operand1, operand2,... -> resultType; description (if necessary)
+
+ * "hostile": N1, N2 -> bool; N1 is hostile to N2 (one-directional)
+ * "allied": N1, N2; N1 is allied to N2 (one-directional)
+ * "approves": N; N agrees to the effect
+ * "roll": N, TYPE -> int; TYPE is an ability or skill
+ * "distance": N1, N2 -> int; units of feet
+ * "sees": N1, N2 -> bool; N1 can see N2
+ * "movedto": N1, N2 -> int; distance (feet) N1 moved directly toward N2 this turn
+ * "underspell": N, SPELL -> bool; N is currently under the effects of SPELL; SPELL can alternatively be of school SCHOOL
+ * "N is in lighting LIGHTING" (sunlight, dim light, darkness, magical darkness)
+ * "understand": N1, N2 -> bool; N1 and N2 share a language
+ * "bound": N1, N2 -> bool; N1 is bound by N2
+ * "aware": N1, N2 -> bool; N1 as aware of N2
+ * "webshare": N1, N2 -> bool; N1 and N2 are in the same web
+ * "carried": N1, N2 -> bool; N1 is worn or carried by N2
## TEXT
@@ -54,93 +185,45 @@ Each subfeature is a dictionary with the following elements:
Several of the elements accept various nouns.
-## NOUNS
-
-Nouns embedded into subfeature elements may be any of:
-
- * "self"
- * "creature"
- * "object"
- * "structure"
- * "target"
- * "point in space"
- * NAME
-
-Where NAME is interpreted by the game as a specific creature or object with a matching name.
-
### TRIGGER
TRIGGER is a list containing any of the following followed by nouns corresponding to instances of N:
- * "passive" (evaluated on initialization)
- * "action"
- * "bonus action"
- * "free action"
- * "legendary action costing X"
- * "N start of turn"
- * "N end of turn"
- * "N takes damage" (pushes damage amount, damage type to variables list)
- * "N moves"
- * "N makes check against N" (pushes ROLLCLASS to variables list)
- * "N forces N to save" (pushes ROLLCLASS to variables list)
- * "N rolls a d20" (pushes ROLLCLASS to variables list)
- * "N targets N by a spell" (pushes spell name to variables list)
- * "N attacks N"
- * "N hits N"
- * "N touches N"
+The subfeature activates when TRIGGER is true. The TRIGGER uses any condition, with the following exclusive conditions:
+
+ * "passive": -> bool; evaluated on initialization
+ * "action": -> bool; taken by creature on turn
+ * "bonus": -> bool; bonus action
+ * "free": -> bool; free action
+ * "legendary": X -> bool; legendary action costing X
+ * "turnstart": N -> bool; N start of turn
+ * "turnend": N -> bool; N end of turn
+ * "damaged": N -> bool; N takes damage
+ * "moves": N -> bool; N moves
+ * "checkagainst": N1, N2 -> ROLLCLASS; N1 makes check against N2
+ * "forcesave": N1, N2 -> ROLLCLASS; N1 forces N2 to save
+ * "rolls": N, X -> bool; N rolls a dX
+ * "targetspell": N1, N2 -> SPELL; N1 targets N2 by a spell
+ * "attacks": N1, N2 -> ATTACK; N1 attacks N2
+ * "hits": N1, N2 -> DAMAGE; N1 hits N2
+ * "touches": N1, N2 -> bool; N1 touches N2
Where ROLLCLASS is any of:
* "attack"
* "grapple"
* "escape grapple"
* "shove"
+ * "frightened"
...
-### CONDITIONS
-
-CONDITIONS is a list of lists, all of which must evaluate True for effects to be applied. Each condition list is formatted [ CONDITION, variables ] where CONDITION is any of the following, prepend "not " to invert:
-
- * "N has property PROPERTY = VALUE"
- * "N is hostile to N"
- * "N is allied to N"
- * "N wishes it to be so"
- * "N succeeds dc X ABILITY save by at least X" (0 is a success)
- * "N fails dc X ABILITY save by at least X" (0 is a fail)
- * "N is within radius X of N"
- * "N can see N"
- * "N has completed >= X turns"
- * "N has COND X hp" (COND any of ">=", ">", "<=", "<", "==")
- * "Damage received >= X"
- * "Damage received was a critical hit"
- * "Damage received was type TYPE"
- * "N has condition CONDITION"
- * "N has condition CONDITION given by N"
- * "N and N are on same plane of existence"
- * "N is on plane PLANE"
- * "N moved X distance straight toward N"
- * "N has X movement remaining"
- * "N made attack ATTACK"
- * "N has underside exposed"
- * "First time N uses feature on N during turn"
- * "N is flying"
- * "N is under effects of spell SPELL"
- * "N has spell from school SCHOOL cast on it"
- * "N is on terrain TERRAIN"
- * "N is inside an object"
- * "N is in lighting LIGHTING" (sunlight, dim light, darkness, magical darkness)
- * "N can understand >= X languages"
- * "N and N share a language"
- * "N has >= X heads"
- * "N has X spell slots remaining"
- * "N had advantage"
- * "N had disadvantage"
- * "N used a weapon"
- * "N is surprised"
- * "N is bound by N"
- * "N is aware of N"
- * "N and N are in the same web"
- * "N == N"
- * "N is in AOE" where AOE is denoted in any of the following:
+### CONDITION
+
+CONDITION is a string containing the conditional which, if it evaluates to true (i.e., not 0), then the effect occurs.
+
+### AOE
+
+AOE is
+ * "in": N, AOE -> bool; N is in an AOE
* "line LENGTH WIDTH"
* "cone LENGTH"
@@ -149,44 +232,48 @@ CONDITIONS is a list of lists, all of which must evaluate True for effects to be
EFFECTS is a list of dictionaries containing the following:
* "target": NOUN
+ * "condition": CONDITION
* "effect": [EFFECT, variables]
- * "effect conditions": [[ CONDITION, variables ]]
* "duration": DURATION
+(Note: Unlike subfeature conditions, effect conditions apply to each target individually, i.e., for target = creatures, we can apply condition on each creature.)
+
Where EFFECT is any of the following (UNDER CONSTRUCTION DENOTED BY x):
- * Terrain in X ft radius is difficult
- * Set movement speed to X
- * Move up to X ft toward N
+ * "Move up to X ft toward N"
x * Increase movement speed by X
x * Increase jump distance by X
x * Increase jump height by X
- * Acquire condition CONDITION
-x * End condition CONDITION
- * Set property PROPERTY to X
+ * "Set N = N"
+ * "Destroyed"
x * Death
x * Surprised
x * Pushed X feet in DIRECTION direction
x * Immune to feature FEATURE
x * Immune to spells with trait SPELL\_TRAIT
- * Impose disadvantage
+ * "Impose disadvantage"
* "Impose disadvantage on TYPE" (any of "attack rolls", "ability checks", "saving throws")
- * Grant advantage
- * Grant critical hit
+ * "Grant advantage"
+ * "Grant critical hit"
x * Advantage on rolls ROLL\_CLASS
x * Automatic fail on rolls ROLL\_CLASS
x * Automatic succeed on rolls ROLL\_CLASS
x * Move X distance
x * Deal X damage
- * Inflict XdX TYPE damage
- * Inflict XdX TYPE damage, dc X ABILITY save halves
- * Deal +X weapon die damage
- * Damage dealt is magical
- * Take action ACTION
+ * "Inflict XdX TYPE damage"
+ * "Inflict XdX TYPE damage, dc X ABILITY save halves"
+ * "Deal +X weapon die damage"
+ * "Damage dealt is magical"
+ * "Take action ACTION"
+ * "cantrip"
+ * "cast spell"
+ * "attack"
+ * specific feature
x * Disable other feature
x * Know distance/direction to creature/object within X distance
- * Reduce incoming damage by X
- * Regain X hp
+ * "Reduce incoming damage by X"
+ * "Regain X hp"
+ * "Polymorph N into creature <= X cr"
x * Weapon/armor corrodes
x * Ignite flammable objects
x * Expend spell slot
@@ -205,13 +292,16 @@ x * Creates X diameter tunnel
The conditions on an effect may be omitted if not applicable, and are the same as conditions for a trigger.
-The duration of an effect may be omitted for instantaneous effects and is any of the following:
+The duration of an effect may be omitted for instantaneous effects and is a condition, including the contents of TRIGGER, plus the following:
- * "End of turn"
- * "Start of next turn"
- * "End of next turn"
- * "Until action is taken to end"
- * TIME (formatted "X units", where units is any of sec, min, hr, day, month, year)
+x * "End of turn"
+x * "Start of next turn"
+x * "End of self next turn"
+x * "End of target next turn"
+x * "Until action is taken to end"
+x * TIME (formatted "X units", where units is any of sec, min, hr, day, month, year)
+x * "Until lesser restoration is cast" (implies at least lesser)
+x * "Until overridden or dead"
x * Repeated saves???
x * Repeated saves at advantage/disadvantage with condition???
x * Until certain spell is cast???
@@ -222,4 +312,4 @@ x * Until other effect expires???
The recharge of a feature may be omitted to indicate that it is unlimited. Otherwise, it is a list of the following two items:
* Integer indicating number of times the feature can be used
- * Any of "turn", "long rest", "short rest", "X-Y" (for integers X and Y) indicating when spent uses are restored
+ * Any of "turn", "long rest", "short rest", "X-Y" (for integers X and Y) indicating range on a d6 where spent uses are restored
diff --git a/features/0blank.json b/features/wip/0blank.json
index 80aaf8e..80aaf8e 100644
--- a/features/0blank.json
+++ b/features/wip/0blank.json
diff --git a/features/TYPE_absorption.json b/features/wip/TYPE_absorption.json
index 58c1018..58c1018 100644
--- a/features/TYPE_absorption.json
+++ b/features/wip/TYPE_absorption.json
diff --git a/features/wip/animate_chains.json b/features/wip/animate_chains.json
new file mode 100644
index 0000000..7677e3b
--- /dev/null
+++ b/features/wip/animate_chains.json
@@ -0,0 +1,16 @@
+{
+ "name": "animate chains",
+ "text": "Up to four chains the {NAME} can see within 60 feet of it magically sprout razor-­edged barbs and animate under the {NAME}'s control, provided that the chains aren't being worn or carried. Each animated chain is an object with AC 20, 20 hit points, resistance to piercing damage, and immunity to psychic and thunder damage. When the {NAME} uses multiattack on its turn, it can use each animated chain to make one additional chain attack. An animated chain can grapple one creature of its own but can't make attacks while grappling. An animated chain reverts to its inanimate state if reduced to 0 hit points or if the {NAME} is incapacitated or dies.",
+ "subfeatures": [
+ {
+ "trigger": [ "action" ],
+ "conditions": [],
+ "effects": [{
+ "target": "",
+ "effect": [],
+ "duration": ""
+ }],
+ "recharge": [ 1, "short rest" ]
+ }
+ ]
+}
diff --git a/features/animate_trees.json b/features/wip/animate_trees.json
index e69de29..e69de29 100644
--- a/features/animate_trees.json
+++ b/features/wip/animate_trees.json
diff --git a/features/bound.json b/features/wip/bound.json
index 84a1dbe..2d69c62 100644
--- a/features/bound.json
+++ b/features/wip/bound.json
@@ -1,5 +1,5 @@
{
- "name": "bound (feature)",
+ "name": "bound",
"text": "The shield guardian is magically bound to an amulet. As long as the guardian and its amulet are on the same plane of existence, the amulet's wearer can telepathically call the guardian to travel to it, and the guardian knows the distance and direction to the amulet. If the guardian is within 60 feet of the amulet's wearer, half of any damage the wearer takes (rounded up) is transferred to the guardian.",
"subfeatures": [
{
diff --git a/features/breath_weapons.json b/features/wip/breath_weapons.json
index b020604..b020604 100644
--- a/features/breath_weapons.json
+++ b/features/wip/breath_weapons.json
diff --git a/features/wip/charm.json b/features/wip/charm.json
new file mode 100644
index 0000000..b6d895f
--- /dev/null
+++ b/features/wip/charm.json
@@ -0,0 +1,15 @@
+{
+ "name": "charm",
+ "text": "The {NAME} targets one humanoid it can see within 30 feet of it. If the target can see the {NAME}, the target must succeed on a DC {(8,PROF,CHA,+,+)} Wisdom saving throw against this magic or be charmed by the {NAME}. The charmed target regards the {NAME} as a trusted friend to be heeded and protected. Although the target isn't under the {NAME}'s control, it takes the {NAME}'s requests or actions in the most favorable way it can, and it is a willing target for the {NAME}'s bite attack. Each time the {NAME} or the {NAME}'s companions do anything harmful to the target, it can repeat the saving throw, ending the effect on itself on a success. Otherwise, the effect lasts 24 hours or until the {NAME} is destroyed, is on a different plane of existence than the target, or takes a bonus action to end the effect.",
+ "subfeatures": [
+ {
+ "trigger": [ "action" ],
+ "conditions": [],
+ "effects": [{
+ "target": "",
+ "effect": [],
+ "duration": ""
+ }]
+ }
+ ]
+}
diff --git a/features/children_of_the_night.json b/features/wip/children_of_the_night.json
index e69de29..e69de29 100644
--- a/features/children_of_the_night.json
+++ b/features/wip/children_of_the_night.json
diff --git a/features/chomp.json b/features/wip/chomp.json
index d72b5de..d72b5de 100644
--- a/features/chomp.json
+++ b/features/wip/chomp.json
diff --git a/features/claw_attack.json b/features/wip/claw_attack.json
index 0d300bb..0d300bb 100644
--- a/features/claw_attack.json
+++ b/features/wip/claw_attack.json
diff --git a/features/cold_breath.json b/features/wip/cold_breath.json
index ceafca7..ceafca7 100644
--- a/features/cold_breath.json
+++ b/features/wip/cold_breath.json
diff --git a/features/confer_fire_resistance.json b/features/wip/confer_fire_resistance.json
index 978aef2..978aef2 100644
--- a/features/confer_fire_resistance.json
+++ b/features/wip/confer_fire_resistance.json
diff --git a/features/consume_life.json b/features/wip/consume_life.json
index 60ec347..60ec347 100644
--- a/features/consume_life.json
+++ b/features/wip/consume_life.json
diff --git a/features/corrode_metal.json b/features/wip/corrode_metal.json
index 7d38de5..7d38de5 100644
--- a/features/corrode_metal.json
+++ b/features/wip/corrode_metal.json
diff --git a/features/corrosive_form.json b/features/wip/corrosive_form.json
index 902ad57..902ad57 100644
--- a/features/corrosive_form.json
+++ b/features/wip/corrosive_form.json
diff --git a/features/create_specter.json b/features/wip/create_specter.json
index 09074d4..09074d4 100644
--- a/features/create_specter.json
+++ b/features/wip/create_specter.json
diff --git a/features/create_whirlwind.json b/features/wip/create_whirlwind.json
index bf45c7f..bf45c7f 100644
--- a/features/create_whirlwind.json
+++ b/features/wip/create_whirlwind.json
diff --git a/features/cunning_action.json b/features/wip/cunning_action.json
index 7940d67..7940d67 100644
--- a/features/cunning_action.json
+++ b/features/wip/cunning_action.json
diff --git a/features/damage_transfer.json b/features/wip/damage_transfer.json
index 1290953..1290953 100644
--- a/features/damage_transfer.json
+++ b/features/wip/damage_transfer.json
diff --git a/features/dark_devotion.json b/features/wip/dark_devotion.json
index 8607755..8607755 100644
--- a/features/dark_devotion.json
+++ b/features/wip/dark_devotion.json
diff --git a/features/darkness_aura.json b/features/wip/darkness_aura.json
index e69de29..e69de29 100644
--- a/features/darkness_aura.json
+++ b/features/wip/darkness_aura.json
diff --git a/features/deadly_leap.json b/features/wip/deadly_leap.json
index a8c0a6e..a8c0a6e 100644
--- a/features/deadly_leap.json
+++ b/features/wip/deadly_leap.json
diff --git a/features/death_burst.json b/features/wip/death_burst.json
index ea6fa45..ea6fa45 100644
--- a/features/death_burst.json
+++ b/features/wip/death_burst.json
diff --git a/features/death_glare.json b/features/wip/death_glare.json
index 707c92f..707c92f 100644
--- a/features/death_glare.json
+++ b/features/wip/death_glare.json
diff --git a/features/death_throes.json b/features/wip/death_throes.json
index d85633a..d85633a 100644
--- a/features/death_throes.json
+++ b/features/wip/death_throes.json
diff --git a/features/detect.json b/features/wip/detect.json
index 7c2d2a6..7c2d2a6 100644
--- a/features/detect.json
+++ b/features/wip/detect.json
diff --git a/features/devil's_sight.json b/features/wip/devil's_sight.json
index 26f0c34..26f0c34 100644
--- a/features/devil's_sight.json
+++ b/features/wip/devil's_sight.json
diff --git a/features/disrupt_life.json b/features/wip/disrupt_life.json
index 7632a36..7632a36 100644
--- a/features/disrupt_life.json
+++ b/features/wip/disrupt_life.json
diff --git a/features/divine_awareness.json b/features/wip/divine_awareness.json
index 57d2e97..57d2e97 100644
--- a/features/divine_awareness.json
+++ b/features/wip/divine_awareness.json
diff --git a/features/divine_eminence.json b/features/wip/divine_eminence.json
index 916ac36..916ac36 100644
--- a/features/divine_eminence.json
+++ b/features/wip/divine_eminence.json
diff --git a/features/draining_kiss.json b/features/wip/draining_kiss.json
index 777b82e..777b82e 100644
--- a/features/draining_kiss.json
+++ b/features/wip/draining_kiss.json
diff --git a/features/dreadful_glare.json b/features/wip/dreadful_glare.json
index 63f16ad..63f16ad 100644
--- a/features/dreadful_glare.json
+++ b/features/wip/dreadful_glare.json
diff --git a/features/duergar_resilience.json b/features/wip/duergar_resilience.json
index cb0efa0..cb0efa0 100644
--- a/features/duergar_resilience.json
+++ b/features/wip/duergar_resilience.json
diff --git a/features/earth_glide.json b/features/wip/earth_glide.json
index a9601f3..a9601f3 100644
--- a/features/earth_glide.json
+++ b/features/wip/earth_glide.json
diff --git a/features/echolocation.json b/features/wip/echolocation.json
index 295a403..295a403 100644
--- a/features/echolocation.json
+++ b/features/wip/echolocation.json
diff --git a/features/elemental_demise.json b/features/wip/elemental_demise.json
index a486cb6..a486cb6 100644
--- a/features/elemental_demise.json
+++ b/features/wip/elemental_demise.json
diff --git a/features/engulf.json b/features/wip/engulf.json
index c8a1692..c8a1692 100644
--- a/features/engulf.json
+++ b/features/wip/engulf.json
diff --git a/features/enlarge.json b/features/wip/enlarge.json
index f9fbd86..f9fbd86 100644
--- a/features/enlarge.json
+++ b/features/wip/enlarge.json
diff --git a/features/enslave.json b/features/wip/enslave.json
index e69de29..e69de29 100644
--- a/features/enslave.json
+++ b/features/wip/enslave.json
diff --git a/features/ephemeral.json b/features/wip/ephemeral.json
index 55ec3ca..55ec3ca 100644
--- a/features/ephemeral.json
+++ b/features/wip/ephemeral.json
diff --git a/features/ethereal_jaunt.json b/features/wip/ethereal_jaunt.json
index 51838d3..51838d3 100644
--- a/features/ethereal_jaunt.json
+++ b/features/wip/ethereal_jaunt.json
diff --git a/features/ethereal_sight.json b/features/wip/ethereal_sight.json
index 8731e80..8731e80 100644
--- a/features/ethereal_sight.json
+++ b/features/wip/ethereal_sight.json
diff --git a/features/ethereal_stride.json b/features/wip/ethereal_stride.json
index 915aa0d..915aa0d 100644
--- a/features/ethereal_stride.json
+++ b/features/wip/ethereal_stride.json
diff --git a/features/etherealness.json b/features/wip/etherealness.json
index 3b67efa..3b67efa 100644
--- a/features/etherealness.json
+++ b/features/wip/etherealness.json
diff --git a/features/evasion.json b/features/wip/evasion.json
index 1dfff45..1dfff45 100644
--- a/features/evasion.json
+++ b/features/wip/evasion.json
diff --git a/features/false_appearance.json b/features/wip/false_appearance.json
index fcdd655..fcdd655 100644
--- a/features/false_appearance.json
+++ b/features/wip/false_appearance.json
diff --git a/features/faultless_tracker.json b/features/wip/faultless_tracker.json
index ed235ab..ed235ab 100644
--- a/features/faultless_tracker.json
+++ b/features/wip/faultless_tracker.json
diff --git a/features/fear_aura.json b/features/wip/fear_aura.json
index e6ad68f..e6ad68f 100644
--- a/features/fear_aura.json
+++ b/features/wip/fear_aura.json
diff --git a/features/fetid_cloud.json b/features/wip/fetid_cloud.json
index e69de29..e69de29 100644
--- a/features/fetid_cloud.json
+++ b/features/wip/fetid_cloud.json
diff --git a/features/fey_ancestry.json b/features/wip/fey_ancestry.json
index 0680b74..0680b74 100644
--- a/features/fey_ancestry.json
+++ b/features/wip/fey_ancestry.json
diff --git a/features/fey_charm.json b/features/wip/fey_charm.json
index 39f0e5e..39f0e5e 100644
--- a/features/fey_charm.json
+++ b/features/wip/fey_charm.json
diff --git a/features/fire_absorption.json b/features/wip/fire_absorption.json
index c2724b0..c2724b0 100644
--- a/features/fire_absorption.json
+++ b/features/wip/fire_absorption.json
diff --git a/features/fire_aura.json b/features/wip/fire_aura.json
index 6fe6d2d..6fe6d2d 100644
--- a/features/fire_aura.json
+++ b/features/wip/fire_aura.json
diff --git a/features/fire_breath.json b/features/wip/fire_breath.json
index 58646f4..58646f4 100644
--- a/features/fire_breath.json
+++ b/features/wip/fire_breath.json
diff --git a/features/fire_form.json b/features/wip/fire_form.json
index cef7dba..cef7dba 100644
--- a/features/fire_form.json
+++ b/features/wip/fire_form.json
diff --git a/features/first_roar.json b/features/wip/first_roar.json
index 9966c2a..9966c2a 100644
--- a/features/first_roar.json
+++ b/features/wip/first_roar.json
diff --git a/features/fling.json b/features/wip/fling.json
index 56c3b0a..56c3b0a 100644
--- a/features/fling.json
+++ b/features/wip/fling.json
diff --git a/features/flyby.json b/features/wip/flyby.json
index 1ca973a..1ca973a 100644
--- a/features/flyby.json
+++ b/features/wip/flyby.json
diff --git a/features/flying_sword.json b/features/wip/flying_sword.json
index 05656a5..05656a5 100644
--- a/features/flying_sword.json
+++ b/features/wip/flying_sword.json
diff --git a/features/freedom_of_movement.json b/features/wip/freedom_of_movement.json
index daeeef4..daeeef4 100644
--- a/features/freedom_of_movement.json
+++ b/features/wip/freedom_of_movement.json
diff --git a/features/freeze.json b/features/wip/freeze.json
index 1f91eac..1f91eac 100644
--- a/features/freeze.json
+++ b/features/wip/freeze.json
diff --git a/features/frightening_gaze.json b/features/wip/frightening_gaze.json
index 5cc19b6..5cc19b6 100644
--- a/features/frightening_gaze.json
+++ b/features/wip/frightening_gaze.json
diff --git a/features/frightful_presence.json b/features/wip/frightful_presence.json
index 64e63c3..64e63c3 100644
--- a/features/frightful_presence.json
+++ b/features/wip/frightful_presence.json
diff --git a/features/frost_breath.json b/features/wip/frost_breath.json
index 55d64ce..55d64ce 100644
--- a/features/frost_breath.json
+++ b/features/wip/frost_breath.json
diff --git a/features/gibbering.json b/features/wip/gibbering.json
index 28d5896..28d5896 100644
--- a/features/gibbering.json
+++ b/features/wip/gibbering.json
diff --git a/features/gnome_cunning.json b/features/wip/gnome_cunning.json
index 37e6907..37e6907 100644
--- a/features/gnome_cunning.json
+++ b/features/wip/gnome_cunning.json
diff --git a/features/grappler.json b/features/wip/grappler.json
index 0d23a01..0d23a01 100644
--- a/features/grappler.json
+++ b/features/wip/grappler.json
diff --git a/features/grasping_tendrils.json b/features/wip/grasping_tendrils.json
index d0efc05..d0efc05 100644
--- a/features/grasping_tendrils.json
+++ b/features/wip/grasping_tendrils.json
diff --git a/features/haste.json b/features/wip/haste.json
index fe98a49..fe98a49 100644
--- a/features/haste.json
+++ b/features/wip/haste.json
diff --git a/features/heal_self.json b/features/wip/heal_self.json
index 398026c..398026c 100644
--- a/features/heal_self.json
+++ b/features/wip/heal_self.json
diff --git a/features/healing_touch.json b/features/wip/healing_touch.json
index e69de29..e69de29 100644
--- a/features/healing_touch.json
+++ b/features/wip/healing_touch.json
diff --git a/features/heart_sight.json b/features/wip/heart_sight.json
index d8d82bd..d8d82bd 100644
--- a/features/heart_sight.json
+++ b/features/wip/heart_sight.json
diff --git a/features/heated_body.json b/features/wip/heated_body.json
index 0076162..0076162 100644
--- a/features/heated_body.json
+++ b/features/wip/heated_body.json
diff --git a/features/heated_weapons.json b/features/wip/heated_weapons.json
index 32d67fd..32d67fd 100644
--- a/features/heated_weapons.json
+++ b/features/wip/heated_weapons.json
diff --git a/features/hellish_rejuvenation.json b/features/wip/hellish_rejuvenation.json
index badf56e..badf56e 100644
--- a/features/hellish_rejuvenation.json
+++ b/features/wip/hellish_rejuvenation.json
diff --git a/features/hellish_weapons.json b/features/wip/hellish_weapons.json
index fcd37f7..fcd37f7 100644
--- a/features/hellish_weapons.json
+++ b/features/wip/hellish_weapons.json
diff --git a/features/hold_breath.json b/features/wip/hold_breath.json
index b57b9b8..b57b9b8 100644
--- a/features/hold_breath.json
+++ b/features/wip/hold_breath.json
diff --git a/features/hooves.json b/features/wip/hooves.json
index 4e95f5f..4e95f5f 100644
--- a/features/hooves.json
+++ b/features/wip/hooves.json
diff --git a/features/horrific_appearance.json b/features/wip/horrific_appearance.json
index ba3d57e..ba3d57e 100644
--- a/features/horrific_appearance.json
+++ b/features/wip/horrific_appearance.json
diff --git a/features/horrifying_visage.json b/features/wip/horrifying_visage.json
index 9a7b8a0..9a7b8a0 100644
--- a/features/horrifying_visage.json
+++ b/features/wip/horrifying_visage.json
diff --git a/features/horror_nimbus.json b/features/wip/horror_nimbus.json
index c0dcb62..c0dcb62 100644
--- a/features/horror_nimbus.json
+++ b/features/wip/horror_nimbus.json
diff --git a/features/hurl_flame.json b/features/wip/hurl_flame.json
index e69de29..e69de29 100644
--- a/features/hurl_flame.json
+++ b/features/wip/hurl_flame.json
diff --git a/features/ice_walk.json b/features/wip/ice_walk.json
index b3f033b..b3f033b 100644
--- a/features/ice_walk.json
+++ b/features/wip/ice_walk.json
diff --git a/features/ignited_illumination.json b/features/wip/ignited_illumination.json
index ab78e2d..ab78e2d 100644
--- a/features/ignited_illumination.json
+++ b/features/wip/ignited_illumination.json
diff --git a/features/illumination.json b/features/wip/illumination.json
index 46aa99a..46aa99a 100644
--- a/features/illumination.json
+++ b/features/wip/illumination.json
diff --git a/features/illusory_appearance.json b/features/wip/illusory_appearance.json
index fd6f73d..fd6f73d 100644
--- a/features/illusory_appearance.json
+++ b/features/wip/illusory_appearance.json
diff --git a/features/immutable_form.json b/features/wip/immutable_form.json
index fe48fd3..fe48fd3 100644
--- a/features/immutable_form.json
+++ b/features/wip/immutable_form.json
diff --git a/features/incorporeal_movement.json b/features/wip/incorporeal_movement.json
index 6cdc08a..6cdc08a 100644
--- a/features/incorporeal_movement.json
+++ b/features/wip/incorporeal_movement.json
diff --git a/features/ink_cloud.json b/features/wip/ink_cloud.json
index ce92045..ce92045 100644
--- a/features/ink_cloud.json
+++ b/features/wip/ink_cloud.json
diff --git a/features/inscrutable.json b/features/wip/inscrutable.json
index 56a9409..56a9409 100644
--- a/features/inscrutable.json
+++ b/features/wip/inscrutable.json
diff --git a/features/intoxicating_touch.json b/features/wip/intoxicating_touch.json
index 8ac0e4e..8ac0e4e 100644
--- a/features/intoxicating_touch.json
+++ b/features/wip/intoxicating_touch.json
diff --git a/features/invisibility.json b/features/wip/invisibility.json
index d670d9a..d670d9a 100644
--- a/features/invisibility.json
+++ b/features/wip/invisibility.json
diff --git a/features/invisible_passage.json b/features/wip/invisible_passage.json
index 4924f35..4924f35 100644
--- a/features/invisible_passage.json
+++ b/features/wip/invisible_passage.json
diff --git a/features/iron_scent.json b/features/wip/iron_scent.json
index 2767bb8..2767bb8 100644
--- a/features/iron_scent.json
+++ b/features/wip/iron_scent.json
diff --git a/features/keen_hearing.json b/features/wip/keen_hearing.json
index 0f386ad..0f386ad 100644
--- a/features/keen_hearing.json
+++ b/features/wip/keen_hearing.json
diff --git a/features/keen_hearing_and_sight.json b/features/wip/keen_hearing_and_sight.json
index 84a511e..84a511e 100644
--- a/features/keen_hearing_and_sight.json
+++ b/features/wip/keen_hearing_and_sight.json
diff --git a/features/keen_hearing_and_smell.json b/features/wip/keen_hearing_and_smell.json
index e3bf77a..e3bf77a 100644
--- a/features/keen_hearing_and_smell.json
+++ b/features/wip/keen_hearing_and_smell.json
diff --git a/features/keen_sight.json b/features/wip/keen_sight.json
index bcf1aa6..bcf1aa6 100644
--- a/features/keen_sight.json
+++ b/features/wip/keen_sight.json
diff --git a/features/keen_sight_and_smell.json b/features/wip/keen_sight_and_smell.json
index 53ec530..53ec530 100644
--- a/features/keen_sight_and_smell.json
+++ b/features/wip/keen_sight_and_smell.json
diff --git a/features/keen_smell.json b/features/wip/keen_smell.json
index 8504b20..8504b20 100644
--- a/features/keen_smell.json
+++ b/features/wip/keen_smell.json
diff --git a/features/labyrinthine_recall.json b/features/wip/labyrinthine_recall.json
index 90d789e..90d789e 100644
--- a/features/labyrinthine_recall.json
+++ b/features/wip/labyrinthine_recall.json
diff --git a/features/leadership.json b/features/wip/leadership.json
index 39aa51a..39aa51a 100644
--- a/features/leadership.json
+++ b/features/wip/leadership.json
diff --git a/features/legendary_attack.json b/features/wip/legendary_attack.json
index 2b17f1c..2b17f1c 100644
--- a/features/legendary_attack.json
+++ b/features/wip/legendary_attack.json
diff --git a/features/legendary_resistance.json b/features/wip/legendary_resistance.json
index e69de29..e69de29 100644
--- a/features/legendary_resistance.json
+++ b/features/wip/legendary_resistance.json
diff --git a/features/life_drain.json b/features/wip/life_drain.json
index 4f5743f..4f5743f 100644
--- a/features/life_drain.json
+++ b/features/wip/life_drain.json
diff --git a/features/light_sensitivity.json b/features/wip/light_sensitivity.json
index 387e288..387e288 100644
--- a/features/light_sensitivity.json
+++ b/features/wip/light_sensitivity.json
diff --git a/features/lightning_absorption.json b/features/wip/lightning_absorption.json
index a901c31..a901c31 100644
--- a/features/lightning_absorption.json
+++ b/features/wip/lightning_absorption.json
diff --git a/features/lightning_breath.json b/features/wip/lightning_breath.json
index 4329863..4329863 100644
--- a/features/lightning_breath.json
+++ b/features/wip/lightning_breath.json
diff --git a/features/lightning_storm.json b/features/wip/lightning_storm.json
index f92e486..f92e486 100644
--- a/features/lightning_storm.json
+++ b/features/wip/lightning_storm.json
diff --git a/features/lightning_strike.json b/features/wip/lightning_strike.json
index 920f0c8..920f0c8 100644
--- a/features/lightning_strike.json
+++ b/features/wip/lightning_strike.json
diff --git a/features/limited_amphibiousess.json b/features/wip/limited_amphibiousess.json
index 483c17e..483c17e 100644
--- a/features/limited_amphibiousess.json
+++ b/features/wip/limited_amphibiousess.json
diff --git a/features/limited_magic_immunity.json b/features/wip/limited_magic_immunity.json
index 45eac17..45eac17 100644
--- a/features/limited_magic_immunity.json
+++ b/features/wip/limited_magic_immunity.json
diff --git a/features/limited_telepathy.json b/features/wip/limited_telepathy.json
index 3ed0c1f..3ed0c1f 100644
--- a/features/limited_telepathy.json
+++ b/features/wip/limited_telepathy.json
diff --git a/features/luring_song.json b/features/wip/luring_song.json
index b7c0206..b7c0206 100644
--- a/features/luring_song.json
+++ b/features/wip/luring_song.json
diff --git a/features/magic_resistance.json b/features/wip/magic_resistance.json
index 2717e38..2717e38 100644
--- a/features/magic_resistance.json
+++ b/features/wip/magic_resistance.json
diff --git a/features/magic_weapons.json b/features/wip/magic_weapons.json
index b71c784..b71c784 100644
--- a/features/magic_weapons.json
+++ b/features/wip/magic_weapons.json
diff --git a/features/martial_advantage.json b/features/wip/martial_advantage.json
index 6677521..6677521 100644
--- a/features/martial_advantage.json
+++ b/features/wip/martial_advantage.json
diff --git a/features/mimicry.json b/features/wip/mimicry.json
index 84fab6e..84fab6e 100644
--- a/features/mimicry.json
+++ b/features/wip/mimicry.json
diff --git a/features/misty_escape.json b/features/wip/misty_escape.json
index 0433d1e..0433d1e 100644
--- a/features/misty_escape.json
+++ b/features/wip/misty_escape.json
diff --git a/features/moan.json b/features/wip/moan.json
index d78a097..d78a097 100644
--- a/features/moan.json
+++ b/features/wip/moan.json
diff --git a/features/move.json b/features/wip/move.json
index bd45f58..bd45f58 100644
--- a/features/move.json
+++ b/features/wip/move.json
diff --git a/features/mucous_cloud.json b/features/wip/mucous_cloud.json
index 069425a..069425a 100644
--- a/features/mucous_cloud.json
+++ b/features/wip/mucous_cloud.json
diff --git a/features/multiattack..json b/features/wip/multiattack..json
index 8e9b93f..8e9b93f 100644
--- a/features/multiattack..json
+++ b/features/wip/multiattack..json
diff --git a/features/multiattack.json b/features/wip/multiattack.json
index 0c17ce9..0c17ce9 100644
--- a/features/multiattack.json
+++ b/features/wip/multiattack.json
diff --git a/features/multiple_heads.json b/features/wip/multiple_heads.json
index ddf4173..ddf4173 100644
--- a/features/multiple_heads.json
+++ b/features/wip/multiple_heads.json
diff --git a/features/nightmare_haunting.json b/features/wip/nightmare_haunting.json
index e69de29..e69de29 100644
--- a/features/nightmare_haunting.json
+++ b/features/wip/nightmare_haunting.json
diff --git a/features/nimble_escape.json b/features/wip/nimble_escape.json
index 69218e2..69218e2 100644
--- a/features/nimble_escape.json
+++ b/features/wip/nimble_escape.json
diff --git a/features/ooze_cube.json b/features/wip/ooze_cube.json
index fee2d89..fee2d89 100644
--- a/features/ooze_cube.json
+++ b/features/wip/ooze_cube.json
diff --git a/features/pack_tactics.json b/features/wip/pack_tactics.json
index 0d35128..0d35128 100644
--- a/features/pack_tactics.json
+++ b/features/wip/pack_tactics.json
diff --git a/features/paralyzing_breath.json b/features/wip/paralyzing_breath.json
index d0e5328..d0e5328 100644
--- a/features/paralyzing_breath.json
+++ b/features/wip/paralyzing_breath.json
diff --git a/features/paralyzing_touch.json b/features/wip/paralyzing_touch.json
index cd7004b..cd7004b 100644
--- a/features/paralyzing_touch.json
+++ b/features/wip/paralyzing_touch.json
diff --git a/features/parry.json b/features/wip/parry.json
index 382b4bb..382b4bb 100644
--- a/features/parry.json
+++ b/features/wip/parry.json
diff --git a/features/petrifying_breath.json b/features/wip/petrifying_breath.json
index 3a9f636..3a9f636 100644
--- a/features/petrifying_breath.json
+++ b/features/wip/petrifying_breath.json
diff --git a/features/petrifying_gaze.json b/features/wip/petrifying_gaze.json
index 7c15a88..7c15a88 100644
--- a/features/petrifying_gaze.json
+++ b/features/wip/petrifying_gaze.json
diff --git a/features/phantasms.json b/features/wip/phantasms.json
index c5ed88e..c5ed88e 100644
--- a/features/phantasms.json
+++ b/features/wip/phantasms.json
diff --git a/features/poison_breath.json b/features/wip/poison_breath.json
index fcb96f5..fcb96f5 100644
--- a/features/poison_breath.json
+++ b/features/wip/poison_breath.json
diff --git a/features/possession.json b/features/wip/possession.json
index c644567..c644567 100644
--- a/features/possession.json
+++ b/features/wip/possession.json
diff --git a/features/pounce.json b/features/wip/pounce.json
index cbc492b..cbc492b 100644
--- a/features/pounce.json
+++ b/features/wip/pounce.json
diff --git a/features/probing_telepathy.json b/features/wip/probing_telepathy.json
index fc55177..fc55177 100644
--- a/features/probing_telepathy.json
+++ b/features/wip/probing_telepathy.json
diff --git a/features/psychic_drain.json b/features/wip/psychic_drain.json
index ed2750b..ed2750b 100644
--- a/features/psychic_drain.json
+++ b/features/wip/psychic_drain.json
diff --git a/features/rampage.json b/features/wip/rampage.json
index 9f340ba..9f340ba 100644
--- a/features/rampage.json
+++ b/features/wip/rampage.json
diff --git a/features/reactive.json b/features/wip/reactive.json
index 14f8ae1..14f8ae1 100644
--- a/features/reactive.json
+++ b/features/wip/reactive.json
diff --git a/features/reactive_heads.json b/features/wip/reactive_heads.json
index 8cf453e..8cf453e 100644
--- a/features/reactive_heads.json
+++ b/features/wip/reactive_heads.json
diff --git a/features/read_thoughts.json b/features/wip/read_thoughts.json
index 56bcf34..56bcf34 100644
--- a/features/read_thoughts.json
+++ b/features/wip/read_thoughts.json
diff --git a/features/reckless.json b/features/wip/reckless.json
index d50eb69..d50eb69 100644
--- a/features/reckless.json
+++ b/features/wip/reckless.json
diff --git a/features/reel.json b/features/wip/reel.json
index 462bb3d..462bb3d 100644
--- a/features/reel.json
+++ b/features/wip/reel.json
diff --git a/features/reflective_carapace.json b/features/wip/reflective_carapace.json
index 8504fcd..8504fcd 100644
--- a/features/reflective_carapace.json
+++ b/features/wip/reflective_carapace.json
diff --git a/features/regeneration.json b/features/wip/regeneration.json
index f6f1a25..f6f1a25 100644
--- a/features/regeneration.json
+++ b/features/wip/regeneration.json
diff --git a/features/rejuvenation.json b/features/wip/rejuvenation.json
index ec888d6..ec888d6 100644
--- a/features/rejuvenation.json
+++ b/features/wip/rejuvenation.json
diff --git a/features/relentless.json b/features/wip/relentless.json
index 02b32eb..02b32eb 100644
--- a/features/relentless.json
+++ b/features/wip/relentless.json
diff --git a/features/repulsion_breath.json b/features/wip/repulsion_breath.json
index 17f6259..17f6259 100644
--- a/features/repulsion_breath.json
+++ b/features/wip/repulsion_breath.json
diff --git a/features/roar.json b/features/wip/roar.json
index e69de29..e69de29 100644
--- a/features/roar.json
+++ b/features/wip/roar.json
diff --git a/features/rock_catching.json b/features/wip/rock_catching.json
index 4e16005..4e16005 100644
--- a/features/rock_catching.json
+++ b/features/wip/rock_catching.json
diff --git a/features/running_leap.json b/features/wip/running_leap.json
index d9e5b22..d9e5b22 100644
--- a/features/running_leap.json
+++ b/features/wip/running_leap.json
diff --git a/features/rust_metal.json b/features/wip/rust_metal.json
index ac2abf6..ac2abf6 100644
--- a/features/rust_metal.json
+++ b/features/wip/rust_metal.json
diff --git a/features/scare.json b/features/wip/scare.json
index e69de29..e69de29 100644
--- a/features/scare.json
+++ b/features/wip/scare.json
diff --git a/features/searing_burst.json b/features/wip/searing_burst.json
index 77c3baa..77c3baa 100644
--- a/features/searing_burst.json
+++ b/features/wip/searing_burst.json
diff --git a/features/second_roar.json b/features/wip/second_roar.json
index 0084451..0084451 100644
--- a/features/second_roar.json
+++ b/features/wip/second_roar.json
diff --git a/features/sense_magic.json b/features/wip/sense_magic.json
index 2a3084a..2a3084a 100644
--- a/features/sense_magic.json
+++ b/features/wip/sense_magic.json
diff --git a/features/senses.json b/features/wip/senses.json
index 4150c7e..4150c7e 100644
--- a/features/senses.json
+++ b/features/wip/senses.json
diff --git a/features/shadow_stealth.json b/features/wip/shadow_stealth.json
index df3d476..df3d476 100644
--- a/features/shadow_stealth.json
+++ b/features/wip/shadow_stealth.json
diff --git a/features/shapechanger.json b/features/wip/shapechanger.json
index 745cc7c..745cc7c 100644
--- a/features/shapechanger.json
+++ b/features/wip/shapechanger.json
diff --git a/features/shark_telepathy.json b/features/wip/shark_telepathy.json
index 48e4bb1..48e4bb1 100644
--- a/features/shark_telepathy.json
+++ b/features/wip/shark_telepathy.json
diff --git a/features/shield.json b/features/wip/shield.json
index 6d6eeed..6d6eeed 100644
--- a/features/shield.json
+++ b/features/wip/shield.json
diff --git a/features/shielded_mind.json b/features/wip/shielded_mind.json
index e613ea6..e613ea6 100644
--- a/features/shielded_mind.json
+++ b/features/wip/shielded_mind.json
diff --git a/features/shimmering_shield.json b/features/wip/shimmering_shield.json
index b148b7f..b148b7f 100644
--- a/features/shimmering_shield.json
+++ b/features/wip/shimmering_shield.json
diff --git a/features/shock.json b/features/wip/shock.json
index 0174364..0174364 100644
--- a/features/shock.json
+++ b/features/wip/shock.json
diff --git a/features/shriek.json b/features/wip/shriek.json
index ef14bab..ef14bab 100644
--- a/features/shriek.json
+++ b/features/wip/shriek.json
diff --git a/features/siege_monster.json b/features/wip/siege_monster.json
index 37d911d..37d911d 100644
--- a/features/siege_monster.json
+++ b/features/wip/siege_monster.json
diff --git a/features/sleep_breath.json b/features/wip/sleep_breath.json
index f5d26f8..f5d26f8 100644
--- a/features/sleep_breath.json
+++ b/features/wip/sleep_breath.json
diff --git a/features/slow.json b/features/wip/slow.json
index 7ae57dd..7ae57dd 100644
--- a/features/slow.json
+++ b/features/wip/slow.json
diff --git a/features/slowing_breath.json b/features/wip/slowing_breath.json
index f63fb95..f63fb95 100644
--- a/features/slowing_breath.json
+++ b/features/wip/slowing_breath.json
diff --git a/features/sneak_attack.json b/features/wip/sneak_attack.json
index 975a47f..975a47f 100644
--- a/features/sneak_attack.json
+++ b/features/wip/sneak_attack.json
diff --git a/features/snow_camouflage.json b/features/wip/snow_camouflage.json
index 937bae5..937bae5 100644
--- a/features/snow_camouflage.json
+++ b/features/wip/snow_camouflage.json
diff --git a/features/speak_with_beasts_and_plants.json b/features/wip/speak_with_beasts_and_plants.json
index ac0be3a..ac0be3a 100644
--- a/features/speak_with_beasts_and_plants.json
+++ b/features/wip/speak_with_beasts_and_plants.json
diff --git a/features/spell_storing.json b/features/wip/spell_storing.json
index 21a794d..21a794d 100644
--- a/features/spell_storing.json
+++ b/features/wip/spell_storing.json
diff --git a/features/spider_climb.json b/features/wip/spider_climb.json
index f692e30..f692e30 100644
--- a/features/spider_climb.json
+++ b/features/wip/spider_climb.json
diff --git a/features/split.json b/features/wip/split.json
index 05e9db2..05e9db2 100644
--- a/features/split.json
+++ b/features/wip/split.json
diff --git a/features/spores.json b/features/wip/spores.json
index 2c9fa10..2c9fa10 100644
--- a/features/spores.json
+++ b/features/wip/spores.json
diff --git a/features/standing_leap.json b/features/wip/standing_leap.json
index 8e96b76..8e96b76 100644
--- a/features/standing_leap.json
+++ b/features/wip/standing_leap.json
diff --git a/features/steadfast.json b/features/wip/steadfast.json
index 674288e..674288e 100644
--- a/features/steadfast.json
+++ b/features/wip/steadfast.json
diff --git a/features/steam_breath.json b/features/wip/steam_breath.json
index 0f43f54..0f43f54 100644
--- a/features/steam_breath.json
+++ b/features/wip/steam_breath.json
diff --git a/features/stench.json b/features/wip/stench.json
index da9d30b..da9d30b 100644
--- a/features/stench.json
+++ b/features/wip/stench.json
diff --git a/features/stone_camouflage.json b/features/wip/stone_camouflage.json
index b7ca35b..b7ca35b 100644
--- a/features/stone_camouflage.json
+++ b/features/wip/stone_camouflage.json
diff --git a/features/stunning_screech.json b/features/wip/stunning_screech.json
index e69de29..e69de29 100644
--- a/features/stunning_screech.json
+++ b/features/wip/stunning_screech.json
diff --git a/features/sunlight_sensitivity.json b/features/wip/sunlight_sensitivity.json
index 334ef9e..334ef9e 100644
--- a/features/sunlight_sensitivity.json
+++ b/features/wip/sunlight_sensitivity.json
diff --git a/features/sunlight_weakness.json b/features/wip/sunlight_weakness.json
index e3c1fae..e3c1fae 100644
--- a/features/sunlight_weakness.json
+++ b/features/wip/sunlight_weakness.json
diff --git a/features/sure-footed.json b/features/wip/sure-footed.json
index f964d16..f964d16 100644
--- a/features/sure-footed.json
+++ b/features/wip/sure-footed.json
diff --git a/features/surprise_attack.json b/features/wip/surprise_attack.json
index 84a97f2..84a97f2 100644
--- a/features/surprise_attack.json
+++ b/features/wip/surprise_attack.json
diff --git a/features/swallow.json b/features/wip/swallow.json
index 48727ec..48727ec 100644
--- a/features/swallow.json
+++ b/features/wip/swallow.json
diff --git a/features/swarm.json b/features/wip/swarm.json
index 86da157..86da157 100644
--- a/features/swarm.json
+++ b/features/wip/swarm.json
diff --git a/features/tail_attack.json b/features/wip/tail_attack.json
index f3cadb0..f3cadb0 100644
--- a/features/tail_attack.json
+++ b/features/wip/tail_attack.json
diff --git a/features/tail_spike_regrowth.json b/features/wip/tail_spike_regrowth.json
index d9c4a75..d9c4a75 100644
--- a/features/tail_spike_regrowth.json
+++ b/features/wip/tail_spike_regrowth.json
diff --git a/features/tail_swipe.json b/features/wip/tail_swipe.json
index 27dfc25..27dfc25 100644
--- a/features/tail_swipe.json
+++ b/features/wip/tail_swipe.json
diff --git a/features/telepathic_bond.json b/features/wip/telepathic_bond.json
index 035952f..035952f 100644
--- a/features/telepathic_bond.json
+++ b/features/wip/telepathic_bond.json
diff --git a/features/teleport.json b/features/wip/teleport.json
index 900bc68..900bc68 100644
--- a/features/teleport.json
+++ b/features/wip/teleport.json
diff --git a/features/tentacle_attack_or_fling.json b/features/wip/tentacle_attack_or_fling.json
index 5044187..5044187 100644
--- a/features/tentacle_attack_or_fling.json
+++ b/features/wip/tentacle_attack_or_fling.json
diff --git a/features/tentacle_slam.json b/features/wip/tentacle_slam.json
index 00cef67..00cef67 100644
--- a/features/tentacle_slam.json
+++ b/features/wip/tentacle_slam.json
diff --git a/features/tentacles.json b/features/wip/tentacles.json
index 04c5b73..04c5b73 100644
--- a/features/tentacles.json
+++ b/features/wip/tentacles.json
diff --git a/features/third_roar.json b/features/wip/third_roar.json
index 1da7e85..1da7e85 100644
--- a/features/third_roar.json
+++ b/features/wip/third_roar.json
diff --git a/features/trampling_charge.json b/features/wip/trampling_charge.json
index 32d35e5..32d35e5 100644
--- a/features/trampling_charge.json
+++ b/features/wip/trampling_charge.json
diff --git a/features/transparent.json b/features/wip/transparent.json
index 942835b..942835b 100644
--- a/features/transparent.json
+++ b/features/wip/transparent.json
diff --git a/features/treasure_sense.json b/features/wip/treasure_sense.json
index 7a18bb7..7a18bb7 100644
--- a/features/treasure_sense.json
+++ b/features/wip/treasure_sense.json
diff --git a/features/tree_stride.json b/features/wip/tree_stride.json
index e78186a..e78186a 100644
--- a/features/tree_stride.json
+++ b/features/wip/tree_stride.json
diff --git a/features/tunneler.json b/features/wip/tunneler.json
index a1dd416..a1dd416 100644
--- a/features/tunneler.json
+++ b/features/wip/tunneler.json
diff --git a/features/turn_resistance.json b/features/wip/turn_resistance.json
index e191cf8..e191cf8 100644
--- a/features/turn_resistance.json
+++ b/features/wip/turn_resistance.json
diff --git a/features/turning_defiance.json b/features/wip/turning_defiance.json
index 286fc8f..286fc8f 100644
--- a/features/turning_defiance.json
+++ b/features/wip/turning_defiance.json
diff --git a/features/two-headed.json b/features/wip/two-headed.json
index 92f8b25..92f8b25 100644
--- a/features/two-headed.json
+++ b/features/wip/two-headed.json
diff --git a/features/two_heads.json b/features/wip/two_heads.json
index d93a87f..d93a87f 100644
--- a/features/two_heads.json
+++ b/features/wip/two_heads.json
diff --git a/features/unarmed_strike.json b/features/wip/unarmed_strike.json
index ddba1c5..ddba1c5 100644
--- a/features/unarmed_strike.json
+++ b/features/wip/unarmed_strike.json
diff --git a/features/undead_fortitude.json b/features/wip/undead_fortitude.json
index e840ab3..e840ab3 100644
--- a/features/undead_fortitude.json
+++ b/features/wip/undead_fortitude.json
diff --git a/features/underwater_camouflage.json b/features/wip/underwater_camouflage.json
index 4990715..4990715 100644
--- a/features/underwater_camouflage.json
+++ b/features/wip/underwater_camouflage.json
diff --git a/features/unnerving_mask.json b/features/wip/unnerving_mask.json
index c8958e1..c8958e1 100644
--- a/features/unnerving_mask.json
+++ b/features/wip/unnerving_mask.json
diff --git a/features/vampire_weaknesses.json b/features/wip/vampire_weaknesses.json
index a60bd30..a60bd30 100644
--- a/features/vampire_weaknesses.json
+++ b/features/wip/vampire_weaknesses.json
diff --git a/features/variable_illumination.json b/features/wip/variable_illumination.json
index f11b9cb..f11b9cb 100644
--- a/features/variable_illumination.json
+++ b/features/wip/variable_illumination.json
diff --git a/features/wakeful.json b/features/wip/wakeful.json
index 627c491..627c491 100644
--- a/features/wakeful.json
+++ b/features/wip/wakeful.json
diff --git a/features/wall_of_ice.json b/features/wip/wall_of_ice.json
index 65565f0..65565f0 100644
--- a/features/wall_of_ice.json
+++ b/features/wip/wall_of_ice.json
diff --git a/features/water_breathing.json b/features/wip/water_breathing.json
index 3167210..3167210 100644
--- a/features/water_breathing.json
+++ b/features/wip/water_breathing.json
diff --git a/features/water_form.json b/features/wip/water_form.json
index 7686901..7686901 100644
--- a/features/water_form.json
+++ b/features/wip/water_form.json
diff --git a/features/water_susceptibility.json b/features/wip/water_susceptibility.json
index cb16f42..cb16f42 100644
--- a/features/water_susceptibility.json
+++ b/features/wip/water_susceptibility.json
diff --git a/features/weakening_breath.json b/features/wip/weakening_breath.json
index 281d302..281d302 100644
--- a/features/weakening_breath.json
+++ b/features/wip/weakening_breath.json
diff --git a/features/web_sense.json b/features/wip/web_sense.json
index 9767c9a..9767c9a 100644
--- a/features/web_sense.json
+++ b/features/wip/web_sense.json
diff --git a/features/web_walker.json b/features/wip/web_walker.json
index 7764955..7764955 100644
--- a/features/web_walker.json
+++ b/features/wip/web_walker.json
diff --git a/features/whelm.json b/features/wip/whelm.json
index 78532ea..78532ea 100644
--- a/features/whelm.json
+++ b/features/wip/whelm.json
diff --git a/features/whirlwind.json b/features/wip/whirlwind.json
index e1e676f..e1e676f 100644
--- a/features/whirlwind.json
+++ b/features/wip/whirlwind.json
diff --git a/features/whirlwind_of_sand.json b/features/wip/whirlwind_of_sand.json
index 094ea48..094ea48 100644
--- a/features/whirlwind_of_sand.json
+++ b/features/wip/whirlwind_of_sand.json
diff --git a/features/wing_attack.json b/features/wip/wing_attack.json
index 2807e91..2807e91 100644
--- a/features/wing_attack.json
+++ b/features/wip/wing_attack.json
diff --git a/featuresNotes.txt b/featuresNotes.txt
deleted file mode 100644
index 2424e81..0000000
--- a/featuresNotes.txt
+++ /dev/null
@@ -1,126 +0,0 @@
-Features can do various things, both passively and actively.
-
-Nouns:
- * Self
- * Any creature
- * Single target
- * All in AOE
- * Any object
- * Any structure
- * Specific object
- * Point in space
-
-Triggers by Noun (N):
- * Passive (always acting)
- * N takes special action / bns action / free action (granted by feature)
- * N start of turn
- * N takes damage
- * N makes check against N
- * N forces N to save
- * N rolls a d20
- * N targets N by spell
- * N attacks N
- * N hits N
- * N moves
- * N dies
- * N touches N
-
-Conditions on some number of Nouns (N) (can be negated):
- * N has property PROPERTY
- * N is hostile to N
- * N is allied to N
- * N wishes it to be so
- * N succeeds roll by at least X
- * N fails roll by at least X
- * N is within radius of N
- * N can see N
- * N in antimagic field
- * N has completed >= X turns
- * N doesn't have full hp
- * N has >= X hp
- * Damage received by N >= X
- * Damage received by N was a critical hit
- * Damage received by N was type X
- * N is alive
- * N has condition X (given by N)
- * N and N are on same plane of existence
- * N on specific plane
- * N moved X distance straight toward N
- * N has X movement remaining
- * N made specific attack
- * N without underside exposed
- * First time N uses feature on N during turn
- * N is flying
- * N has X spell cast on it
- * N has spell with X property on it
- * N is on X terrain/surface
- * N is inside an object
- * N is in X lighting (sunlight, dim light, darkness, magical darkness)
- * N can understand at least 1 language
- * N and N share a language
- * N has >= X heads
- * N is intact
- * N has spell slots remaining
- * N had advantage
- * N had disadvantage
- * N used a weapon
- * N is surprised
- * N is bound by N (aka, N is N's master)
- * N is aware of N
- * N is in same web as N
-
-Effects for given N:
- * Delayed effect (effect takes place after a duration)
- * Modify movement speed
- * Modify jump distance
- * Modify jump height
- * Acquire condition CONDITION
- * Ends condition CONDITION
- * Acquire/override property PROPERTY (see propertiesNotes.txt)
- * Death
- * Surprised
- * Pushed X feet in DIRECTION direction
- * Immune to feature FEATURE
- * Immune to spells with trait SPELL_TRAIT
- * Make terrain difficult
- * Disadvantage on rolls ROLL_CLASS
- * Advantage on rolls ROLL_CLASS
- * Automatic fail on rolls ROLL_CLASS
- * Automatic succeed on rolls ROLL_CLASS
- * Automatic critical hit
- * Move X distance
- * Can move through creatures/objects as difficult terrain
- * Deal X damage
- * Disable other feature
- * Know distance/direction to creature/object within X distance
- * Reduce incoming damage by X
- * Regain X hp
- * Weapon/armor corrodes
- * Ignite flammable objects
- * Expend spell slot
- * Special movement
- * Plane shift
- * Grant spell effect
- * Transparency (perpetual hidenness?)
- * Prescribed actions (randomized), any of:
- - Nothing
- - Moves in random direction
- - Attacks random creature within reach
- * Telepathic command
- * Learns creature's desires
- * Spell storing
- * Creates X diameter tunnel
-
-Effect duration:
- * Set time (e.g., end of turn, start of next turn, end of next turn, 1 min...)
- * Repeated saves
- * Repeated saves at advantage/disadvantage with condition
- * Until action is taken to douse
- * Until certain spell is cast
- * Until other effect expires
-
-Feature recharge:
- * Permenant
- * X/turn
- * X/lr
- * X/sr
diff --git a/propertiesNotes.txt b/propertiesNotes.txt
deleted file mode 100644
index 4d9f117..0000000
--- a/propertiesNotes.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-There are some "features" that we reorganize into "properties".
-
-Properties inherited from other rules:
- * Damage immunities, resistances, vulnerabilities
- * Condition immunities
-
-Other properties:
- * Can regain HP (default=True)
- * Can stop in hostile space (default=False)
- * Minimum space to move without squeezing (default=calc based on size)
- * Can breathe air (default=True)
- * Can breathe water (default=False)
- * Can hold breath for X time (default=calc based on constitution)
- * Carrying capacity size is X (default=creature size)
- * Berserk (default=False)
- * Is telepathic (default=False)
- * Is one-way telepathic (default=False)
- * Dash action type (default=action)
- * Disengage action type (default=action)
- * Hide action type (default=action)
- * Can see in magical darkness (default=False)
- * Can see ethereal (default=False)
- * Autodetects lies (default=False)
- * Leaves a corpse (default=True)
- * Can hold inventory (default=True)
- * Appears as mundane object OBJECT when still (default=False)
- * Immune to spell tag TAG
- * Does not provoke opportunity attacks (default=False)
- * Ignores difficult terrain (default=False)
- * Can pass through creatures/objects as difficult terrain (default=False)
- * Ignores webs (default=False)
- * Reactions/round (default=1)
- * Sheds bright light radius X and dim light radius Y (default=0,0)
- * Has perfect map recall (default=False)
- * Mimic sounds/voices insight DC (default=Performance/Deception)
- * Can speak with beasts (default=False)
- * Can speak with plants (default=False)
- * Can spider climb (default=False)
- * Is hot (water boils/evaporates) (default=False)
- * Form (default=True Form)
- * Size (default=read from statblock)
- * Can smell (default=True)
- * Alignment (default=NN)
- * Is incapacitated by antimagic field (default=False)
- * Is alive (default=True)
- * Is berserk (default=False)
diff --git a/src/armor.cc b/src/armor.cc
index 3a429b3..cb73cb1 100644
--- a/src/armor.cc
+++ b/src/armor.cc
@@ -13,10 +13,8 @@ namespace entry{
std::string armor_type;
int strength;
bool disadvantage;
- int cost;
- double weight;
};
- NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(armorImpl, ac, armor_type, strength, disadvantage, cost, weight);
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(armorImpl, ac, armor_type, strength, disadvantage);
NLOHMANN_FRIEND_DEFS(Item, Armor, data);
@@ -26,8 +24,6 @@ namespace entry{
std::string Armor::getArmorType(void) const {return data->armor_type;}
int Armor::getStrRequirement(void) const {return data->strength;}
bool Armor::stealthDisadvantage(void) const {return data->disadvantage;}
- int Armor::getCost(void) const {return data->cost;}
- double Armor::getWeight(void) const {return data->weight;}
string getTextHelper(const Armor& a, string dexBonusLight, string dexBonusMedium) {
stringstream text;
@@ -43,7 +39,7 @@ namespace entry{
if(a.stealthDisadvantage()) {
text << ", Imposes stealth disadvantage";
}
- text << ". " << a.Substantial::getText();
+ text << ". " << a.getCostWeightText();
return text.str();
}
diff --git a/src/armor.h b/src/armor.h
index c8bdb87..43bd002 100644
--- a/src/armor.h
+++ b/src/armor.h
@@ -5,15 +5,13 @@
namespace entry {
struct armorImpl;
- class Armor : public Item , public Substantial {
+ class Armor : public Item {
public:
Armor();
int getACBonus(void) const;
std::string getArmorType(void) const;
int getStrRequirement(void) const;
bool stealthDisadvantage(void) const;
- int getCost(void) const;
- double getWeight(void) const;
virtual std::string getText() const override;
virtual std::string getText(const creature::Creature& c) const override;
diff --git a/src/battlescape/battlescape.h b/src/battlescape/battlescape.h
new file mode 100644
index 0000000..a170ad3
--- /dev/null
+++ b/src/battlescape/battlescape.h
@@ -0,0 +1,50 @@
+#pragma once
+#include <vector>
+#include <memory>
+#include <string>
+#include <nlohmann/json.hpp>
+#include <tuple>
+#include <cstddef> // size_t
+#include "../entry.h"
+
+namespace battlescape {
+ struct battlescapeImpl;
+
+ struct Tile {
+ std::string name;
+ std::string description;
+ char look;
+ int color;
+ };
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Tile, name, description, look, color);
+
+ typedef std::tuple<std::size_t,std::size_t,std::size_t> coord3d;
+
+ class Battlescape {
+ public:
+ Battlescape();
+ // Also can be created programmatically
+ Battlescape(std::vector<std::vector<std::vector<Tile>>> terrain);
+
+ // Getters
+ std::map<std::shared_ptr<entry::Entry>, coord3d> getContents(void) const;
+
+ // Setters
+ bool place(std::shared_ptr<entry::Entry> thing, const coord3d& position);
+ bool remove(std::shared_ptr<entry::Entry> thing, const coord3d& position);
+ bool move(std::shared_ptr<entry::Entry> thing, const coord3d& from, const coord3d& to) {
+ if(place(thing, to)) {
+ if(remove(thing, from)) {
+ return true;
+ }
+ remove(thing, to);
+ }
+ return false;
+ }
+
+ NLOHMANN_FRIEND_DECLARES(Battlescape);
+
+ private:
+ std::shared_ptr<battlescapeImpl> data;
+ };
+}
diff --git a/src/features/feature.cc b/src/features/feature.cc
index 0fd2d6c..a941ecf 100644
--- a/src/features/feature.cc
+++ b/src/features/feature.cc
@@ -2,8 +2,10 @@
#include "../spellcasting.h"
#include "../attack.h"
#include "../utils.h"
+#include "../creature.h"
#include <nlohmann/json.hpp>
#include <memory>
+#include <string>
using namespace std;
diff --git a/src/item.cc b/src/item.cc
index 5ecdb0c..24498db 100644
--- a/src/item.cc
+++ b/src/item.cc
@@ -20,10 +20,24 @@ namespace entry {
} else if(data["type"] == "armor") {
return utils::loadDFromJson<Item, Armor>(data);
}
- return shared_ptr<Item>(new Item(data));
+ return utils::loadDFromJson<Item, Item>(data);
}
- string Substantial::getText() const {
+ struct itemImpl {
+ int cost;
+ double weight;
+ };
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(itemImpl, cost, weight);
+
+ NLOHMANN_FRIEND_DEFS(Entry, Item, data);
+
+ Item::Item() : data(new itemImpl()) {}
+
+ int Item::getCost() const {return data->cost;}
+
+ double Item::getWeight() const {return data->weight;}
+
+ string Item::getCostWeightText() const {
stringstream text;
if(getCost() >= 0) {
text << "Cost: ";
@@ -39,4 +53,12 @@ namespace entry {
}
return text.str();
}
+
+ string Item::getText() const {
+ return Entry::getText() + " " + getCostWeightText();
+ }
+
+ string Item::getText(const creature::Creature& c) const {
+ return getText();
+ }
}
diff --git a/src/item.h b/src/item.h
index fc43a40..e8a40b9 100644
--- a/src/item.h
+++ b/src/item.h
@@ -4,17 +4,21 @@
#include <memory>
namespace entry {
+ struct itemImpl;
+
class Item : public Entry {
public:
+ Item();
static std::shared_ptr<Item> create(const nlohmann::json& data);
virtual ~Item() {}
- };
+ virtual int getCost(void) const;
+ virtual double getWeight(void) const;
+ virtual std::string getCostWeightText() const;
+ virtual std::string getText() const override;
+ virtual std::string getText(const creature::Creature& c) const override;
- class Substantial {
- public:
- virtual int getCost(void) const = 0;
- virtual double getWeight(void) const = 0;
- std::string getText() const;
- virtual ~Substantial() {}
+ NLOHMANN_FRIEND_DECLARES(Item);
+ private:
+ std::shared_ptr<itemImpl> data;
};
}
diff --git a/src/settings.cc b/src/settings.cc
index ba15945..f8bc8b5 100644
--- a/src/settings.cc
+++ b/src/settings.cc
@@ -5,6 +5,7 @@
#include <stdexcept>
#include <confuse.h>
#include <errno.h>
+#include <cstring>
namespace settings {
std::string getString(const std::string& key) {
diff --git a/src/utils.h b/src/utils.h
index 2998704..9d22a66 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -67,7 +67,7 @@ namespace utils {
ent = entry::Entry::create(loadJson(path));
} catch(std::exception& e) {
if(std::filesystem::directory_entry(path).exists()) {
- throw std::runtime_error("Invalid json: " + path.string());
+ throw std::runtime_error("Invalid json: " + path.string() + ": " + e.what());
} else {
throw std::runtime_error("No such file nor directory: " + path.string());
}
diff --git a/src/weapon.cc b/src/weapon.cc
index e5f04f2..4c47d8b 100644
--- a/src/weapon.cc
+++ b/src/weapon.cc
@@ -16,14 +16,12 @@ namespace entry {
std::string weapon_type;
std::pair<int, int> range;
int reach;
- int cost;
- double weight;
std::optional<int> toHitOverride;
std::optional<int> dmgBonusOverride;
std::optional<rules::Ability> abilityOverride;
};
- NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(weaponImpl, damage, properties, weapon_type, range, reach, cost, weight, toHitOverride, dmgBonusOverride, abilityOverride);
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(weaponImpl, damage, properties, weapon_type, range, reach, toHitOverride, dmgBonusOverride, abilityOverride);
NLOHMANN_FRIEND_DEFS(Item, Weapon, data);
@@ -34,8 +32,6 @@ namespace entry {
std::string Weapon::getWeaponType(void) const {return data->weapon_type;}
std::pair<int, int> Weapon::getRange(void) const {return data->range;}
int Weapon::getReach(void) const {return data->reach;}
- int Weapon::getCost(void) const {return data->cost;}
- double Weapon::getWeight(void) const {return data->weight;}
string getTextHelper(const Weapon& w, string toHitBonus, string damageBonus) {
stringstream text;
@@ -99,8 +95,8 @@ namespace entry {
if(! props.empty()) {
text << " Additional properties: " << utils::join(props, ", ") << ".";
}
- if(! w.Substantial::getText().empty()) {
- text << " " << w.Substantial::getText();
+ if(! w.getCostWeightText().empty()) {
+ text << " " << w.getCostWeightText();
}
return text.str();
}
diff --git a/src/weapon.h b/src/weapon.h
index 49de396..dc81689 100644
--- a/src/weapon.h
+++ b/src/weapon.h
@@ -29,7 +29,7 @@ namespace entry {
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Damage, dmg_die_count, dmg_die_sides, dmg_type, is_or);
- class Weapon : public Item, public Substantial {
+ class Weapon : public Item {
public:
Weapon();
@@ -38,8 +38,6 @@ namespace entry {
std::string getWeaponType(void) const;
std::pair<int, int> getRange(void) const;
int getReach(void) const;
- int getCost(void) const;
- double getWeight(void) const;
int getToHitBonus(const creature::Creature& c) const;
int getDamageBonus(const creature::Creature& c) const;