diff options
author | Your Name <you@example.com> | 2022-01-16 21:32:01 -0500 |
---|---|---|
committer | Your Name <you@example.com> | 2022-01-16 21:32:01 -0500 |
commit | d0e356d09e30a11c1e072415a5088f829d5c0a04 (patch) | |
tree | 1e64d37b9b424cd74c30ad4c8225828c7a76874e | |
parent | 3f78a7e1647ba94129236bd2bf4fc855c109628a (diff) | |
download | dmtool-d0e356d09e30a11c1e072415a5088f829d5c0a04.tar.gz dmtool-d0e356d09e30a11c1e072415a5088f829d5c0a04.tar.bz2 dmtool-d0e356d09e30a11c1e072415a5088f829d5c0a04.zip |
Worked on features
-rw-r--r-- | Makefile | 94 | ||||
-rwxr-xr-x | configure | 7 | ||||
-rw-r--r-- | features/aberrant_ground.json | 30 | ||||
-rw-r--r-- | features/acid_absorption.json | 14 | ||||
-rw-r--r-- | features/adhesive.json | 18 | ||||
-rw-r--r-- | features/readme.md | 170 | ||||
-rw-r--r-- | featuresNotes.txt | 3 | ||||
-rw-r--r-- | propertiesNotes.txt | 6 | ||||
-rw-r--r-- | src/attack.h | 2 | ||||
-rw-r--r-- | src/cmd/cmd.cc (renamed from src/cmd.cc) | 2 | ||||
-rw-r--r-- | src/cmd/cmd.h (renamed from src/cmd.h) | 2 | ||||
-rw-r--r-- | src/cmd/cmd_fsops.cc (renamed from src/cmd_fsops.cc) | 4 | ||||
-rw-r--r-- | src/cmd/cmd_manipulate.cc (renamed from src/cmd_manipulate.cc) | 16 | ||||
-rw-r--r-- | src/cmd/cmd_query.cc (renamed from src/cmd_query.cc) | 8 | ||||
-rw-r--r-- | src/cmd/cmd_usage.cc (renamed from src/cmd_usage.cc) | 0 | ||||
-rw-r--r-- | src/creature.cc | 1 | ||||
-rw-r--r-- | src/creature.h | 2 | ||||
-rw-r--r-- | src/dmtool.cc | 2 | ||||
-rw-r--r-- | src/entry.cc | 2 | ||||
-rw-r--r-- | src/features/feature.cc (renamed from src/feature.cc) | 6 | ||||
-rw-r--r-- | src/features/feature.h (renamed from src/feature.h) | 2 | ||||
-rw-r--r-- | src/rules.cc | 7 | ||||
-rw-r--r-- | src/rules.h | 44 | ||||
-rw-r--r-- | src/spellcasting.h | 2 | ||||
-rw-r--r-- | src/utils.h | 2 |
25 files changed, 338 insertions, 108 deletions
@@ -2,7 +2,7 @@ CC=g++ LIBS=libconfuse nlohmann_json CFLAGS=-c -Wall -fPIC -std=c++20 LDFLAGS= -SOURCES=src/armor.cc src/cmd.cc src/cmd_fsops.cc src/cmd_manipulate.cc src/cmd_query.cc src/cmd_usage.cc src/creature.cc src/dice.cc src/dmtool.cc src/entry.cc src/feature.cc src/item.cc src/rules.cc src/settings.cc src/spellcasting.cc src/spell.cc src/utils.cc src/weapon.cc +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 OBJECTS=$(SOURCES:.cc=.o) LIBRARY= EXECUTABLE=dmtool @@ -28,79 +28,93 @@ $(EXECUTABLE): $(OBJECTS) $(CC) $(OBJECTS) -o $@ $(LDFLAGS) `pkg-config $(LIBS) --libs` -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/feature.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 $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags` -src/cmd.o: src/cmd.cc src/cmd.h src/settings.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 $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags` -src/cmd_fsops.o: src/cmd_fsops.cc src/cmd.h src/utils.h src/entry.h \ - src/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 $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags` -src/cmd_manipulate.o: src/cmd_manipulate.cc src/cmd.h src/utils.h \ - src/entry.h src/defines.h src/creature.h src/rules.h src/feature.h \ - src/item.h src/spellcasting.h src/spell.h src/settings.h src/weapon.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 $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags` -src/cmd_query.o: src/cmd_query.cc src/cmd.h src/utils.h src/entry.h \ - src/defines.h src/creature.h src/rules.h src/feature.h src/item.h \ - src/dice.h src/weapon.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 $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags` -src/cmd_usage.o: src/cmd_usage.cc src/cmd.h +src/dice.o: src/dice.cc src/dice.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/feature.h src/item.h src/dice.h \ - src/weapon.h src/armor.h src/attack.h src/spellcasting.h src/spell.h +src/settings.o: src/settings.cc src/settings.h $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags` -src/dice.o: src/dice.cc src/dice.h +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/dmtool.o: src/dmtool.cc src/cmd.h src/utils.h src/entry.h \ - src/defines.h +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/entry.o: src/entry.cc src/entry.h src/defines.h src/utils.h \ - src/feature.h src/item.h src/spell.h src/creature.h src/rules.h +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/feature.o: src/feature.cc src/feature.h src/entry.h src/defines.h \ - src/spellcasting.h src/spell.h src/rules.h src/utils.h src/attack.h \ - src/weapon.h src/item.h +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/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/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/rules.o: src/rules.cc src/rules.h src/utils.h src/entry.h \ - src/defines.h +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/settings.o: src/settings.cc src/settings.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 $(CC) $(CFLAGS) $< -o $@ `pkg-config $(LIBS) --cflags` -src/spellcasting.o: src/spellcasting.cc src/spellcasting.h src/feature.h \ - src/entry.h src/defines.h src/spell.h src/rules.h src/utils.h \ - src/creature.h src/item.h +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/spell.o: src/spell.cc src/spell.h src/entry.h src/defines.h \ - src/utils.h +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/utils.o: src/utils.cc src/utils.h src/entry.h src/defines.h \ - src/settings.h +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/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/feature.h \ - src/dice.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` clean: - rm -f src/*.o $(LIBRARY) $(EXECUTABLE) + rm -f $(LIBRARY) $(EXECUTABLE) + find . | grep .o$ | xargs rm -f @@ -34,7 +34,7 @@ install: \$(EXECUTABLE) parsed # Below here shouldn't need editing -SOURCES=`ls $SOURCE_DIR/*.cc | tr '\n' ' '` +SOURCES=`find $SOURCE_DIR | grep .cc$ | tr '\n' ' '` PKG_CONFIG_CFLAGS= PKG_CONFIG_LIBS= @@ -63,7 +63,7 @@ if [ -n "$EXECUTABLE" ]; then ALL="$ALL \$(EXECUTABLE)" fi -ORULES=$(for cc in `ls $SOURCE_DIR/*.cc`; do g++ -MM -MT `cut -d'.' -f-1 <<< $cc`.o $cc; echo -e "\t"'$(CC) $(CFLAGS) $< -o $@ '"$PKG_CONFIG_CFLAGS\n"; done) +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) cat << EOF > Makefile CC=g++ @@ -84,5 +84,6 @@ $EXTRAS$INSTALL$LIBRULE$EXERULE $ORULES clean: - rm -f $SOURCE_DIR/*.o \$(LIBRARY) \$(EXECUTABLE) + rm -f \$(LIBRARY) \$(EXECUTABLE) + find . | grep .o\$ | xargs rm -f EOF diff --git a/features/aberrant_ground.json b/features/aberrant_ground.json index a7f99de..4e72225 100644 --- a/features/aberrant_ground.json +++ b/features/aberrant_ground.json @@ -1,3 +1,27 @@ -[ - -] +{ + "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.", + "subfeatures": [ + { + "trigger": [ "N end of turn", "self" ], + "conditions": [], + "effects": [{ + "target": "self", + "effect": [ "Terrain in X ft radius is difficult", 10 ], + "duration": "Start of next turn" + }] + }, + { + "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 ] + ], + "effects": [{ + "target": "creature", + "effect": [ "Set movement speed to X", 0 ], + "duration": "Start of next turn" + }] + } + ] +} diff --git a/features/acid_absorption.json b/features/acid_absorption.json new file mode 100644 index 0000000..52eb2b7 --- /dev/null +++ b/features/acid_absorption.json @@ -0,0 +1,14 @@ +{ + "name": "acid absorption", + "text": "Whenever the {NAME} is subjected to acid damage, it takes no damage and instead regains a number of hit points equal to the acid damage dealt.", + "subfeatures": [ + { + "trigger": [ "N takes damage", "self" ], + "conditions": [[ "Damage received was type TYPE", "acid" ]], + "effects": [{ + "target": "self", + "effect": [ "Regain X hp", "V0" ] + }] + } + ] +} diff --git a/features/adhesive.json b/features/adhesive.json new file mode 100644 index 0000000..19c39e9 --- /dev/null +++ b/features/adhesive.json @@ -0,0 +1,18 @@ +{ + "name": "adhesive", + "text": "(Object form only) The {NAME} adheres to anything that touches it. A Huge or smaller creature adhered to the {NAME} is also grappled by it (escape DC {(8,STR,PROF,+,+)}). Ability checks made to escape this grapple have disadvantage.", + "subfeatures": [ + { + "trigger": [ "N touches N", "creature", "self" ], + "conditions": [ + [ "N has property PROPERTY", "self", "Form", "Object" ], + [ "not N has property Property", "other", "Size", "Gargantuan" ] + ] + "effects": [ + "target": "creature", + "effect": [ "Acquire condition CONDITION", "grappled" ] + ] + } + ] + +} diff --git a/features/readme.md b/features/readme.md index 6c90a31..ebc16cc 100644 --- a/features/readme.md +++ b/features/readme.md @@ -2,9 +2,32 @@ Many features are complex. Here we lay out the format used when writing a feature. +The overall structure of a feature is a dictionary as follows: + + * "name": NAME + * "text": TEXT + * "subfeatures": SUBFEATURES + +In addition to the hardcoded data provided in the feature, certain variables may be given at runtime. + ## Variables -Many features are very similar between creatures except for certain variables. The feature reads, as parameters, NAME as the creature's name, and V1, V2, ... VN for each numeric variable that is a parameter to the feature. +Many features are very similar between creatures except for certain variables. When instantiated programatically, the feature is given the following: + + * NAME: The name of the creature with this feature + * V0, V1, ... VN: Zero-indexed list of integer variables + +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 STR, DEX, CON, INT, WIS, CHA, or PROF. + +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,+,+). + +## TEXT + +This is explanatory text. It accepts embedded variables in the form {VARNAME}. For example, the text "The {NAME}'s weapon attacks are magical. When the {NAME} hits with any weapon, the weapon deals an extra {V0}d{V1} radiant damage.", when applied to a "deva" with runtime variables (4, 8), we get: + +"The deva's weapon attacks are magical. When the deva hits with any weapon, the weapon deals an extra 4d8 radiant damage." ## Subfeatures @@ -12,30 +35,16 @@ Each feature consists of a list of "subfeatures", which are treated as independe Each subfeature is a dictionary with the following elements: - * "name": NAME - * "text": TEXT - * "nouns": NOUNS * "trigger": TRIGGER * "conditions": CONDITIONS * "effects": EFFECTS - * "duration": DURATION * "recharge": RECHARGE -We detail the values below. - -### NAME - -This is the name of the feature - -### TEXT +Several of the elements accept various nouns. -This is explanatory text. It accepts embedded variables in the form {VARNAME}. For example, the text "The {NAME}'s weapon attacks are magical. When the {NAME} hits with any weapon, the weapon deals an extra {V1}d{V2} radiant damage.", when applied with (deva, 4, 8), we get: +## NOUNS -"The deva's weapon attacks are magical. When the deva hits with any weapon, the weapon deals an extra 4d8 radiant damage." - -### NOUNS - -The nouns involved are any entities this feature affects. NOUNS is a list containing any of: +Nouns embedded into subfeature elements may be any of: * "self" * "creature" @@ -45,18 +54,19 @@ The nouns involved are any entities this feature affects. NOUNS is a list contai * "point in space" * NAME -Where NAME is interpreted by the game as a specific creature or object. These are N1, N2, etc. for all N in the array. Index starts at 1. +Where NAME is interpreted by the game as a specific creature or object with a matching name. ### TRIGGER -TRIGGER is any of the following: +TRIGGER is a list containing any of the following followed by nouns corresponding to instances of N: - * "passive" + * "on init" * "action" * "bonus action" * "free action" - * "{} start of turn" - * "N takes damage" + * "N start of turn" + * "N end of turn" + * "N takes damage" (pushes damage amount to variables list) * "N moves" * "N makes check against N" * "N forces N to save" @@ -65,3 +75,117 @@ TRIGGER is any of the following: * "N attacks N" * "N hits N" * "N touches N" + +### 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" + * "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" + * "N fails dc X ABILITY save by at least X" + * "N is within radius X of N" + * "N can see N" + * "N has completed >= X turns" + * "N is at full hp" + * "N has >= X hp" + * "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 on most recent die roll" + * "N had disadvantage on most recent die roll" + * "N used a weapon on most recent attack" + * "N is surprised" + * "N is bound by N" + * "N is aware of N" + * "N and N are in the same web" + +### EFFECTS + +EFFECTS is a list of dictionaries containing the following: + + * "target": NOUN + * "effect": [EFFECT, variables] + * "duration": DURATION + +Where EFFECT is any of the following (UNDER CONSTRUCTION DENOTED BY x): + + * Terrain in X ft radius is difficult + * Set movement speed to X +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 +x * Acquire/override property PROPERTY +x * Death +x * Surprised +x * Pushed X feet in DIRECTION direction +x * Immune to feature FEATURE +x * Immune to spells with trait SPELL\_TRAIT +x * Disadvantage on rolls ROLL\_CLASS +x * Advantage on rolls ROLL\_CLASS +x * Automatic fail on rolls ROLL\_CLASS +x * Automatic succeed on rolls ROLL\_CLASS +x * Automatic critical hit +x * Move X distance +x * Deal X damage +x * Disable other feature +x * Know distance/direction to creature/object within X distance +x * Reduce incoming damage by X + * Regain X hp +x * Weapon/armor corrodes +x * Ignite flammable objects +x * Expend spell slot +x * Special movement +x * Plane shift +x * Grant spell effect +x * Transparency (perpetual hidenness?) +x * Prescribed actions (randomized), any of: +x - Nothing +x - Moves in random direction +x - Attacks random creature within reach +x * Telepathic command +x * Learns creature's desires +x * Spell storing +x * Creates X diameter tunnel + +The duration of an effect may be omitted for instantaneous effects and is any of the following: + + * "End of turn" + * "Start of next turn" + * "End of next turn" + * Until action is taken to end +x * TIME??? +x * Repeated saves??? +x * Repeated saves at advantage/disadvantage with condition??? +x * Until certain spell is cast??? +x * Until other effect expires??? + +### RECHARGE + +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" indicating when spent uses are restored diff --git a/featuresNotes.txt b/featuresNotes.txt index 733d356..2424e81 100644 --- a/featuresNotes.txt +++ b/featuresNotes.txt @@ -30,7 +30,8 @@ Conditions on some number of Nouns (N) (can be negated): * N is hostile to N * N is allied to N * N wishes it to be so - * N fails/succeeds roll by at least X (0 is straight fail/success) + * 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 diff --git a/propertiesNotes.txt b/propertiesNotes.txt index fcc083a..ad1fca8 100644 --- a/propertiesNotes.txt +++ b/propertiesNotes.txt @@ -14,7 +14,7 @@ Other properties: * Weapons are magical (default=False) * Weapons deal +X damage (default=0) * Weapons deal +XdY damage (default=0,0) - * Weapons deal +Xd{WEAPON_DIE_SIZE} damage (default=0) + * Weapons deal +X weapon damage die damage (default=0) * Carrying capacity is X (default=calc based on size) * Berserk (default=False) * Is telepathic (default=False) @@ -31,6 +31,7 @@ Other properties: * 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) @@ -41,5 +42,8 @@ Other properties: * 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 in antimagic field (default=False) + * Is alive (default=True) diff --git a/src/attack.h b/src/attack.h index 2e4125b..e00eb25 100644 --- a/src/attack.h +++ b/src/attack.h @@ -1,5 +1,5 @@ #pragma once -#include "feature.h" +#include "features/feature.h" #include "weapon.h" namespace creature { diff --git a/src/cmd.cc b/src/cmd/cmd.cc index d84c55b..a1fd760 100644 --- a/src/cmd.cc +++ b/src/cmd/cmd.cc @@ -1,5 +1,5 @@ #include "cmd.h" -#include "settings.h" +#include "../settings.h" #include <vector> #include <string> #include <filesystem> diff --git a/src/cmd.h b/src/cmd/cmd.h index 978f6db..ff96b32 100644 --- a/src/cmd.h +++ b/src/cmd/cmd.h @@ -3,7 +3,7 @@ #include <map> #include <string> #include <filesystem> -#include "rules.h" +#include "../rules.h" namespace cmd { // Corresponds to commands diff --git a/src/cmd_fsops.cc b/src/cmd/cmd_fsops.cc index ac4bdef..e638b96 100644 --- a/src/cmd_fsops.cc +++ b/src/cmd/cmd_fsops.cc @@ -1,6 +1,6 @@ #include "cmd.h" -#include "utils.h" -#include "entry.h" +#include "../utils.h" +#include "../entry.h" #include <filesystem> #include <sstream> diff --git a/src/cmd_manipulate.cc b/src/cmd/cmd_manipulate.cc index aa6407d..18df098 100644 --- a/src/cmd_manipulate.cc +++ b/src/cmd/cmd_manipulate.cc @@ -1,12 +1,12 @@ #include "cmd.h" -#include "utils.h" -#include "creature.h" -#include "item.h" -#include "spellcasting.h" -#include "settings.h" -#include "weapon.h" -#include "dice.h" -#include "armor.h" +#include "../utils.h" +#include "../creature.h" +#include "../item.h" +#include "../spellcasting.h" +#include "../settings.h" +#include "../weapon.h" +#include "../dice.h" +#include "../armor.h" #include <sstream> #include <memory> #include <cstdlib> diff --git a/src/cmd_query.cc b/src/cmd/cmd_query.cc index e13876f..9c2dae6 100644 --- a/src/cmd_query.cc +++ b/src/cmd/cmd_query.cc @@ -1,8 +1,8 @@ #include "cmd.h" -#include "utils.h" -#include "creature.h" -#include "dice.h" -#include "weapon.h" +#include "../utils.h" +#include "../creature.h" +#include "../dice.h" +#include "../weapon.h" #include <sstream> namespace cmd { diff --git a/src/cmd_usage.cc b/src/cmd/cmd_usage.cc index 44daca4..44daca4 100644 --- a/src/cmd_usage.cc +++ b/src/cmd/cmd_usage.cc diff --git a/src/creature.cc b/src/creature.cc index 6491024..ea8ef30 100644 --- a/src/creature.cc +++ b/src/creature.cc @@ -1,7 +1,6 @@ #include "creature.h" #include "dice.h" #include "rules.h" -#include "feature.h" #include "weapon.h" #include "armor.h" #include "attack.h" diff --git a/src/creature.h b/src/creature.h index 09760e3..de93b0e 100644 --- a/src/creature.h +++ b/src/creature.h @@ -2,7 +2,7 @@ #include "rules.h" #include "utils.h" #include "entry.h" -#include "feature.h" +#include "features/feature.h" #include "item.h" #include <nlohmann/json.hpp> diff --git a/src/dmtool.cc b/src/dmtool.cc index 6ae096f..3aec8b2 100644 --- a/src/dmtool.cc +++ b/src/dmtool.cc @@ -1,4 +1,4 @@ -#include "cmd.h" +#include "cmd/cmd.h" #include "utils.h" #include <iostream> #include <exception> diff --git a/src/entry.cc b/src/entry.cc index 663a40a..9c9b3da 100644 --- a/src/entry.cc +++ b/src/entry.cc @@ -1,6 +1,6 @@ #include "entry.h" #include "utils.h" -#include "feature.h" +#include "features/feature.h" #include "item.h" #include "spell.h" #include "creature.h" diff --git a/src/feature.cc b/src/features/feature.cc index 941de4e..0fd2d6c 100644 --- a/src/feature.cc +++ b/src/features/feature.cc @@ -1,7 +1,7 @@ #include "feature.h" -#include "spellcasting.h" -#include "attack.h" -#include "utils.h" +#include "../spellcasting.h" +#include "../attack.h" +#include "../utils.h" #include <nlohmann/json.hpp> #include <memory> diff --git a/src/feature.h b/src/features/feature.h index e3c8bdf..209a30a 100644 --- a/src/feature.h +++ b/src/features/feature.h @@ -1,6 +1,6 @@ #pragma once #include <nlohmann/json.hpp> -#include "entry.h" +#include "../entry.h" #include <memory> namespace entry { diff --git a/src/rules.cc b/src/rules.cc index 96d9a51..900d023 100644 --- a/src/rules.cc +++ b/src/rules.cc @@ -37,6 +37,8 @@ namespace rules { {"non-adamantine", "adamantine"} }; + const std::set<std::string> Condition::conditions {"blinded", "charmed", "deafened", "frightened", "grappled", "incapacitated", "invisible", "paralyzed", "petrified", "poisoned", "prone", "restrained", "stunned", "unconscious", "exhausted1", "exhausted2", "exhausted3", "exhausted4", "exhausted5", "exhausted6"}; + std::ostream& operator<<(std::ostream& os, const Ability& a) { os << std::string(a); return os; @@ -51,4 +53,9 @@ namespace rules { os << std::string(q); return os; } + + std::ostream& operator<<(std::ostream& os, const Condition& c) { + os << std::string(c); + return os; + } } diff --git a/src/rules.h b/src/rules.h index 2894947..30464a8 100644 --- a/src/rules.h +++ b/src/rules.h @@ -2,6 +2,7 @@ #include "utils.h" #include <vector> #include <map> +#include <set> #include <string> #include <iostream> #include <algorithm> @@ -18,6 +19,10 @@ namespace rules { ri.payload = j; } std::string getPayload(void) const {return payload;} + bool operator==(const RuleItem& rhs) const {return getPayload() == rhs.getPayload();} + bool operator<(const RuleItem& rhs) const {return getPayload() < rhs.getPayload();} + operator std::string() const {return getPayload();} + operator bool() const {return ! getPayload().empty();} protected: std::string payload; }; @@ -26,10 +31,6 @@ namespace rules { public: std::string getFull() const {return abilities.at(getAbbrev());} std::string getAbbrev() const {return getPayload();} - operator std::string() const {return getAbbrev();} - bool operator<(const Ability& rhs) const {return getAbbrev() < rhs.getAbbrev();} - bool operator==(const Ability& rhs) const {return getAbbrev() == rhs.getAbbrev();} - operator bool() const {return ! getAbbrev().empty();} Ability() {} Ability(const std::string& abbrev) { @@ -67,10 +68,6 @@ namespace rules { public: std::string getName() const {return getPayload();} Ability getAbility() const {return Ability(skill2ability.at(getName()));} - operator std::string() const {return getName();} - bool operator<(const Skill& rhs) const {return getName() < rhs.getName();} - bool operator==(const Skill& rhs) const {return getName() == rhs.getName();} - operator bool() const {return ! getName().empty();} virtual ~Skill() {} @@ -128,9 +125,7 @@ namespace rules { } std::string getNegative() const {return getPayload();} std::string getPositive() const {return negative2positive.at(getNegative());} - operator std::string() const {return getNegative();} virtual ~Qualifier() {} - bool operator==(const Qualifier& rhs) const {return getNegative() == rhs.getNegative();} static Qualifier Magical() {return Qualifier("nonmagical");} static Qualifier Silvered() {return Qualifier("non-silvered");} @@ -140,9 +135,38 @@ namespace rules { static const std::map<std::string, std::string> negative2positive; }; + class Condition : public RuleItem { + public: + Condition() {} + Condition(std::string name) { + utils::lower(name); + if(conditions.count(name) == 0) { + throw std::invalid_argument("No such condition: " + name); + } + payload = name; + } + + virtual ~Condition() {} + + void incExhaustion() { + if(payload.find("exhausted") == std::string::npos) { + throw std::invalid_argument("Cannot increment exhaustion on condition " + payload); + } + int exhLvl = utils::parseInt(std::string(1, payload.back())); + if(exhLvl >= 6) { + throw std::invalid_argument("Cannot increment exhaustion beyond level 6"); + } + payload.back() = '0'+exhLvl+1; + } + + private: + static const std::set<std::string> conditions; + }; + std::ostream& operator<<(std::ostream& os, const Ability& a); std::ostream& operator<<(std::ostream& os, const Skill& s); std::ostream& operator<<(std::ostream& os, const Qualifier& q); + std::ostream& operator<<(std::ostream& os, const Condition& c); template<typename T> T tryGetAbilityOrSkill(std::string src) { try { diff --git a/src/spellcasting.h b/src/spellcasting.h index 902f860..46d4ba8 100644 --- a/src/spellcasting.h +++ b/src/spellcasting.h @@ -1,5 +1,5 @@ #pragma once -#include "feature.h" +#include "features/feature.h" #include "spell.h" #include "rules.h" #include "utils.h" diff --git a/src/utils.h b/src/utils.h index 77096e7..2998704 100644 --- a/src/utils.h +++ b/src/utils.h @@ -98,7 +98,7 @@ namespace utils { template<typename F, typename T> std::vector<std::shared_ptr<T>> castPtrs(std::vector<std::shared_ptr<F>> from) { std::vector<std::shared_ptr<T>> Ts; for(std::shared_ptr<F> f : from) { - std::shared_ptr<T> t = dynamic_pointer_cast<T>(f); + std::shared_ptr<T> t = std::dynamic_pointer_cast<T>(f); if(t) { Ts.push_back(t); } |