Start writing the twitch combat tutorial

This commit is contained in:
Griatch 2023-05-04 00:50:54 +02:00
parent b2142f23da
commit 7bb2f55434
5 changed files with 94 additions and 9 deletions

View file

@ -1 +1,62 @@
# Twitch Combat
# 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)

View file

@ -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;

View file

@ -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())

View file

@ -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.

View file

@ -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")