diff --git a/docs/source/Howtos/Beginner-Tutorial/Part3/Beginner-Tutorial-Combat-Twitch.md b/docs/source/Howtos/Beginner-Tutorial/Part3/Beginner-Tutorial-Combat-Twitch.md index 78720b40e0..ddf0123702 100644 --- a/docs/source/Howtos/Beginner-Tutorial/Part3/Beginner-Tutorial-Combat-Twitch.md +++ b/docs/source/Howtos/Beginner-Tutorial/Part3/Beginner-Tutorial-Combat-Twitch.md @@ -1 +1,62 @@ -# Twitch Combat \ No newline at end of file +# Twitch Combat + +In this lesson we will build upon the basic combat framework we devised [in the previous lesson](./Beginner-Tutorial-Combat-Base.md). + +```shell +> attack troll + You attack the Troll! + +The Troll roars! + +You attack the Troll with Sword: Roll vs armor(11): + rolled 3 on d20 + strength(+1) vs 11 -> Fail + +Troll attacks you with Terrible claws: Roll vs armor(12): + rolled 13 on d20 + strength(+3) vs 12 -> Success + Troll hits you for 5 damage! + +You attack the Troll with Sword: Roll vs armor(11): + rolled 14 on d20 + strength(+1) vs 11 -> Success + You hit the Troll for 2 damage! + +> look + A dark cave + + Water is dripping from the ceiling. + + Exits: south and west + Enemies: The Troll + --------- Combat Status ---------- + You (Wounded) vs Troll (Scraped) + +> use potion + You prepare to use a healing potion! + +Troll attacks you with Terrible claws: Roll vs armor(12): + rolled 2 on d20 + strength(+3) vs 12 -> Fail + +You use a healing potion. + You heal 4 damage. + +Troll attacks you with Terrible claws: Roll vs armor(12): + rolled 8 on d20 + strength(+3) vs 12 -> Fail + +You attack the troll with Sword: Roll vs armor(11): + rolled 20 on d20 + strength(+1) vs 11 -> Success (critical success) + You critically hit the Troll for 8 damage! + The Troll falls to the ground, dead. + +The battle is over. You are still standing. +``` +> Documentation doesn't show colors. + +With "Twitch" combat, we refer to a type of combat system that runs without any clear divisions of 'turns' (the opposite of [Turn-based combat](./Beginner-Tutorial-Combat-Turnbased.md)). It is inspired by the way combat worked in the old [DikuMUD](https://en.wikipedia.org/wiki/DikuMUD) codebase, but is more flexible. + +```{sidebar} Differences to DIKU combat +In DIKU, all actions in combat happen on a _global_ 'tick' of, say 3 seconds. In our system, each combatant have their own 'tick' which is completely independent of each other. Now, in Evadventure, each combatant will tick at the same rate and thus mimic DIKU ... but they don't _have_ to. +``` + +Basically, a user enters an action and after a certain time that action will execute (normally an attack). If they don't do anything, the attack will repeat over and over (with a random result) until the enemy or you is defeated. + +You can change up your strategy by performing other actions (like drinking a potion or cast a spell). You can also simply move to another room to 'flee' the combat (but the enemy may of course follow you) + diff --git a/docs/source/_static/nature.css b/docs/source/_static/nature.css index 71225f8e97..e4b87de34d 100644 --- a/docs/source/_static/nature.css +++ b/docs/source/_static/nature.css @@ -250,10 +250,22 @@ div.highlight { border-radius: 5px; } -div.highlight-shell.notranslate > div.highlight .nb { - color: #79ecff !important; +/* Shell code style (for in-game blocks) */ +div.highlight-shell.notranslate > div.highlight .nb{ + color: white !important; +} +div.highlight-shell.notranslate > div.highlight .m{ + color: white !important; + font-weight: normal !important; +} +div.highlight-shell.notranslate > div.highlight .k{ + color: white !important; + font-weight: normal !important; +} +div.highlight-shell.notranslate > div.highlight .o{ + color: white !important; + font-weight: normal !important; } - div.note { background-color: #eee; diff --git a/evennia/contrib/tutorials/evadventure/combat_twitch.py b/evennia/contrib/tutorials/evadventure/combat_twitch.py index a5be284c06..db749da934 100644 --- a/evennia/contrib/tutorials/evadventure/combat_twitch.py +++ b/evennia/contrib/tutorials/evadventure/combat_twitch.py @@ -70,6 +70,9 @@ class EvAdventureCombatTwitchHandler(EvAdventureCombatHandlerBase): """ super().msg(message, combatant=self.obj, broadcast=broadcast, location=self.obj.location) + def at_init(self): + self.obj.cmdset.add(TwitchLookCmdSet, persistent=False) + def get_sides(self, combatant): """ Get a listing of the two 'sides' of this combat, from the perspective of the provided @@ -165,7 +168,6 @@ class EvAdventureCombatTwitchHandler(EvAdventureCombatHandlerBase): action_dict (dict): The new action-dict to initialize. """ - if action_dict["key"] not in self.action_classes: self.obj.msg("This is an unkown action!") return @@ -240,6 +242,8 @@ class EvAdventureCombatTwitchHandler(EvAdventureCombatHandlerBase): Stop combat immediately. """ self.queue_action({"key": "hold", "dt": 0}) # make sure ticker is killed + del self.obj.ndb.combathandler + self.obj.cmdset.remove(TwitchLookCmdSet) self.delete() @@ -546,8 +550,16 @@ class TwitchAttackCmdSet(CmdSet): def at_cmdset_creation(self): self.add(CmdAttack()) - self.add(CmdLook()) self.add(CmdHold()) self.add(CmdStunt()) self.add(CmdUseItem()) self.add(CmdWield()) + + +class TwitchLookCmdSet(CmdSet): + """ + This will be added/removed dynamically when in combat. + """ + + def at_cmdset_creation(self): + self.add(CmdLook()) diff --git a/evennia/contrib/tutorials/evadventure/npcs.py b/evennia/contrib/tutorials/evadventure/npcs.py index 2e68612577..3bcfd518c2 100644 --- a/evennia/contrib/tutorials/evadventure/npcs.py +++ b/evennia/contrib/tutorials/evadventure/npcs.py @@ -12,7 +12,7 @@ from evennia.utils.utils import make_iter from .characters import LivingMixin from .enums import Ability, WieldLocation -from .objects import WeaponEmptyHand +from .objects import BARE_HANDS from .rules import dice @@ -51,7 +51,7 @@ class EvAdventureNPC(LivingMixin, DefaultCharacter): is_idle = AttributeProperty(default=False, autocreate=False) - weapon = AttributeProperty(default=WeaponEmptyHand, autocreate=False) # instead of inventory + weapon = AttributeProperty(default=BARE_HANDS, autocreate=False) # instead of inventory coins = AttributeProperty(default=1, autocreate=False) # coin loot # if this npc is attacked, everyone with the same tag in the current location will also be pulled into combat. diff --git a/evennia/contrib/tutorials/evadventure/objects.py b/evennia/contrib/tutorials/evadventure/objects.py index aef8aa1596..78d84467ba 100644 --- a/evennia/contrib/tutorials/evadventure/objects.py +++ b/evennia/contrib/tutorials/evadventure/objects.py @@ -355,6 +355,6 @@ class WeaponBareHands(EvAdventureWeapon): quality = 100000 # let's assume fists are always available ... -BARE_HANDS = search_object("Bare hands", typeclass=WeaponBareHands) +BARE_HANDS = search_object("Bare hands", typeclass=WeaponBareHands).first() if not BARE_HANDS: BARE_HANDS = create_object(WeaponBareHands, key="Bare hands")