Skip to content

Commit 58445de

Browse files
committed
adding spells to stories and tests
1 parent d7a868e commit 58445de

File tree

10 files changed

+141
-62
lines changed

10 files changed

+141
-62
lines changed

llm_config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ CHARACTER_TEMPLATE: '{"name":"", "description": "50 words", "appearance": "25 wo
1717
FOLLOW_TEMPLATE: '{{"response":"yes or no", "reason":"50 words"}}'
1818
ITEM_TYPES: ["Weapon", "Wearable", "Health", "Money", "Trash", "Food", "Drink", "Key"]
1919
PRE_PROMPT: 'You are a creative game keeper for a role playing game (RPG). You craft detailed worlds and interesting characters with unique and deep personalities for the player to interact with. Do not acknowledge the task or speak directly to the user, just perform it.'
20-
BASE_PROMPT: '<context>{context}</context>\n[USER_START]Rewrite [{input_text}] in your own words using the information found inside the <context> tags to create a background for your text. Use about {max_words} words.'
20+
BASE_PROMPT: '<context>{context}</context>\n[USER_START] Rewrite [{input_text}] in your own words. The information inside the <context> tags should be used to ensure it fits the story. Use about {max_words} words.'
2121
DIALOGUE_PROMPT: '<context>{context}</context>\nThe following is a conversation between {character1} and {character2}; {character2}s sentiment towards {character1}: {sentiment}. Write a single response as {character2} in third person pov, using {character2} description and other information found inside the <context> tags. If {character2} has a quest active, they will discuss it based on its status. Respond in JSON using this template: """{dialogue_template}""". [USER_START]Continue the following conversation as {character2}: {previous_conversation}'
2222
COMBAT_PROMPT: '<context>{context}</context>\nThe following is a combat scene between {attackers} and {defenders} in {location}. [USER_START] Describe the following combat result in about 150 words in vivid language, using the characters weapons and their health status: 1.0 is highest, 0.0 is lowest. Combat Result: {input_text}'
2323
PRE_JSON_PROMPT: 'Below is an instruction that describes a task, paired with an input that provides further context. Write a response in valid JSON format that appropriately completes the request.'

stories/anything/story.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from tale import parse_utils
99
from tale.driver import Driver
1010
from tale.json_story import JsonStory
11+
from tale.magic import MagicType
1112
from tale.main import run_from_cmdline
1213
from tale.player import Player, PlayerConnection
1314
from tale.charbuilder import PlayerNaming
@@ -33,6 +34,10 @@ def init_player(self, player: Player) -> None:
3334
player.stats.set_weapon_skill(weapon_type=WeaponType.ONE_HANDED, value=random.randint(10, 30))
3435
player.stats.set_weapon_skill(weapon_type=WeaponType.TWO_HANDED, value=random.randint(10, 30))
3536
player.stats.set_weapon_skill(weapon_type=WeaponType.UNARMED, value=random.randint(20, 30))
37+
player.stats.magic_skills[MagicType.HEAL] = 30
38+
player.stats.magic_skills[MagicType.BOLT] = 30
39+
player.stats.magic_skills[MagicType.DRAIN] = 30
40+
player.stats.magic_skills[MagicType.REJUVENATE] = 30
3641
pass
3742

3843
def create_account_dialog(self, playerconnection: PlayerConnection, playernaming: PlayerNaming) -> Generator:

stories/dungeon/story.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from tale.dungeon.dungeon_generator import ItemPopulator, Layout, LayoutGenerator, MobPopulator
1212
from tale.items.basic import Money
1313
from tale.json_story import JsonStory
14+
from tale.magic import MagicType
1415
from tale.main import run_from_cmdline
1516
from tale.npc_defs import RoamingMob
1617
from tale.player import Player, PlayerConnection
@@ -44,6 +45,10 @@ def init_player(self, player: Player) -> None:
4445
player.stats.set_weapon_skill(weapon_type=WeaponType.ONE_HANDED, value=random.randint(10, 30))
4546
player.stats.set_weapon_skill(weapon_type=WeaponType.TWO_HANDED, value=random.randint(10, 30))
4647
player.stats.set_weapon_skill(weapon_type=WeaponType.UNARMED, value=random.randint(20, 30))
48+
player.stats.magic_skills[MagicType.HEAL] = 30
49+
player.stats.magic_skills[MagicType.BOLT] = 30
50+
player.stats.magic_skills[MagicType.DRAIN] = 30
51+
player.stats.magic_skills[MagicType.REJUVENATE] = 30
4752
pass
4853

4954
def create_account_dialog(self, playerconnection: PlayerConnection, playernaming: PlayerNaming) -> Generator:

stories/prancingllama/story.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
import tale
66
from tale.base import Location
7+
from tale.cmds import spells
78
from tale.driver import Driver
89
from tale.llm.llm_ext import DynamicStory
10+
from tale.magic import MagicType
911
from tale.main import run_from_cmdline
1012
from tale.player import Player, PlayerConnection
1113
from tale.charbuilder import PlayerNaming
@@ -55,6 +57,7 @@ def init_player(self, player: Player) -> None:
5557
player.stats.set_weapon_skill(weapon_type=WeaponType.ONE_HANDED, value=25)
5658
player.stats.set_weapon_skill(weapon_type=WeaponType.TWO_HANDED, value=15)
5759
player.stats.set_weapon_skill(weapon_type=WeaponType.UNARMED, value=35)
60+
player.stats.magic_skills[MagicType.HEAL] = 50
5861

5962
def create_account_dialog(self, playerconnection: PlayerConnection, playernaming: PlayerNaming) -> Generator:
6063
"""

stories/prancingllama/zones/prancingllama.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import random
22

3-
from tale.base import Location, Item, Exit, Door, Key, Living, ParseResult, Weapon
3+
from tale.base import Location, Item, Exit, Weapon
44
from tale.errors import StoryCompleted
55
from tale.items.basic import Note
6-
from tale.lang import capital
7-
from tale.player import Player
86
from tale.util import Context, call_periodically
97
from tale.verbdefs import AGGRESSIVE_VERBS
108
from tale.verbdefs import VERBS

tale/accounts.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,11 @@ def _create_database(self) -> None:
110110
strength integer NOT NULL,
111111
dexterity integer NOT NULL,
112112
weapon_skills varchar NOT NULL,
113+
magic_skills varchar NOT NULL,
113114
combat_points integer NOT NULL,
114115
max_combat_points integer NOT NULL,
116+
magic_points integer NOT NULL,
117+
max_magic_points integer NOT NULL,
115118
FOREIGN KEY(account) REFERENCES Account(id)
116119
);
117120
""")

tale/cmds/spells.py

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,31 @@
22
import random
33
from typing import Optional
44
from tale import base, util, cmds
5+
from tale import magic
56
from tale.cmds import cmd
67
from tale.errors import ActionRefused, ParseError
7-
from tale.magic import MagicType, MagicSkill
8+
from tale.magic import MagicType, MagicSkill, Spell
89
from tale.player import Player
910

1011

1112
@cmd("heal")
1213
def do_heal(player: Player, parsed: base.ParseResult, ctx: util.Context) -> None:
1314
""" Heal someone or something """
1415

15-
skill = player.stats.magic_skills.get(MagicType.HEAL) # type: MagicSkill
16-
if not skill:
16+
skillValue = player.stats.magic_skills.get(MagicType.HEAL, None)
17+
if not skillValue:
1718
raise ActionRefused("You don't know how to heal")
19+
spell = magic.spells[MagicType.HEAL] # type: Spell
1820

19-
if not skill.spell.check_cost(player, level):
21+
num_args = len(parsed.args)
22+
23+
level = player.stats.level
24+
if num_args == 2:
25+
level = int(parsed.args[1])
26+
27+
if not spell.check_cost(player.stats.magic_points, level):
2028
raise ActionRefused("You don't have enough magic points")
2129

22-
num_args = len(parsed.args)
2330
if num_args < 1:
2431
raise ParseError("You need to specify who or what to heal")
2532
try:
@@ -31,33 +38,37 @@ def do_heal(player: Player, parsed: base.ParseResult, ctx: util.Context) -> None
3138
if not result or not isinstance(result, base.Living):
3239
raise ActionRefused("Can't heal that")
3340

34-
level = player.stats.level
35-
if num_args == 2:
36-
level = int(parsed.args[1])
3741

38-
player.stats.magic_points -= skill.spell.base_cost * level
42+
player.stats.magic_points -= spell.base_cost * level
3943

40-
if random.randint(1, 100) > skill.skill:
41-
player.tell("Your healing spell fizzles out", evoke=True)
44+
if random.randint(1, 100) > skillValue:
45+
player.tell("Your healing spell fizzles out", evoke=True, short_len=True)
4246
return
4347

4448
result.stats.replenish_hp(5 * level)
45-
player.tell("You heal %s for %d hit points" % (result.name, 5 * level), evoke=True)
46-
player.tell_others("%s heals %s" % (player.name, result.name), evoke=True)
49+
player.tell("You cast a healing spell that heals %s for %d hit points" % (result.name, 5 * level), evoke=True)
50+
player.tell_others("%s casts a healing spell that heals %s" % (player.name, result.name), evoke=True)
4751

4852

4953
@cmd("bolt")
5054
def do_bolt(player: Player, parsed: base.ParseResult, ctx: util.Context) -> None:
5155
""" Cast a bolt of energy """
5256

53-
skill = player.stats.magic_skills.get(MagicType.BOLT) # type: MagicSkill
54-
if not skill:
57+
skillValue = player.stats.magic_skills.get(MagicType.BOLT, None)
58+
if not skillValue:
5559
raise ActionRefused("You don't know how to cast a bolt")
5660

57-
if not skill.spell.check_cost(player, level):
61+
spell = magic.spells[MagicType.BOLT] # type: Spell
62+
63+
num_args = len(parsed.args)
64+
65+
level = player.stats.level
66+
if num_args == 2:
67+
level = int(parsed.args[1])
68+
69+
if not spell.check_cost(player.stats.magic_points, level):
5870
raise ActionRefused("You don't have enough magic points")
5971

60-
num_args = len(parsed.args)
6172
if num_args < 1:
6273
raise ParseError("You need to specify who or what to attack")
6374

@@ -69,35 +80,37 @@ def do_bolt(player: Player, parsed: base.ParseResult, ctx: util.Context) -> None
6980
result = player.location.search_living(entity) # type: Optional[base.Living]
7081
if not result or not isinstance(result, base.Living):
7182
raise ActionRefused("Can't attack that")
72-
73-
level = player.stats.level
74-
if num_args == 2:
75-
level = int(parsed.args[1])
7683

77-
78-
player.stats.magic_points -= skill.spell.base_cost * level
84+
player.stats.magic_points -= spell.base_cost * level
7985

80-
if random.randint(1, 100) > skill.skill:
81-
player.tell("Your bolt spell fizzles out", evoke=True)
86+
if random.randint(1, 100) > skillValue:
87+
player.tell("Your bolt spell fizzles out", evoke=True, short_len=True)
8288
return
8389

84-
hp = random.randrange(1, level)
90+
hp = random.randint(1, level)
8591
result.stats.hp -= hp
86-
player.tell("Your energy bolt hits %s for %d damage" % (result.name, hp), evoke=True)
87-
player.tell_others("%s's energy bolt hits %s for %d damage" % (player.name, result.name, hp), evoke=True)
92+
player.tell("You cast an energy bolt that hits %s for %d damage" % (result.name, hp), evoke=True)
93+
player.tell_others("%s casts an energy bolt that hits %s for %d damage" % (player.name, result.name, hp), evoke=True)
8894

8995
@cmd("drain")
9096
def do_drain(player: Player, parsed: base.ParseResult, ctx: util.Context) -> None:
9197
""" Drain energy from someone or something """
9298

93-
skill = player.stats.magic_skills.get(MagicType.DRAIN)
94-
if not skill:
99+
skillValue = player.stats.magic_skills.get(MagicType.DRAIN, None)
100+
if not skillValue:
95101
raise ActionRefused("You don't know how to drain")
96102

97-
if not skill.spell.check_cost(player, level):
103+
spell = magic.spells[MagicType.DRAIN] # type: Spell
104+
105+
num_args = len(parsed.args)
106+
107+
level = player.stats.level
108+
if num_args == 2:
109+
level = int(parsed.args[1])
110+
111+
if not spell.check_cost(player.stats.magic_points, level):
98112
raise ActionRefused("You don't have enough magic points")
99113

100-
num_args = len(parsed.args)
101114
if num_args < 1:
102115
raise ParseError("You need to specify who or what to drain")
103116

@@ -110,24 +123,19 @@ def do_drain(player: Player, parsed: base.ParseResult, ctx: util.Context) -> Non
110123
if not result or not isinstance(result, base.Living):
111124
raise ActionRefused("Can't drain that")
112125

113-
level = player.stats.level
114-
if num_args == 2:
115-
level = int(parsed.args[1])
116-
117-
118-
player.stats.magic_points -= skill.spell.base_cost * level
126+
player.stats.magic_points -= spell.base_cost * level
119127

120-
if random.randint(1, 100) > skill.skill:
121-
player.tell("Your drain spell fizzles out", evoke=True)
128+
if random.randint(1, 100) > skillValue:
129+
player.tell("Your drain spell fizzles out", evoke=True, short_len=True)
122130
return
123131

124-
points = random.randrange(1, level)
132+
points = random.randint(1, level)
125133
result.stats.combat_points -= points
126134
result.stats.magic_points -= points
127135

128136
player.stats.magic_points += points
129137

130-
player.tell("Your drain spell drains %s of %d combat and magic points" % (result.name, points), evoke=True)
131-
player.tell_others("%s casts a drain spell that drains energy from %s" % (player.name, result.name), evoke=True)
138+
player.tell("You cast a 'drain' spell that drains %s of %d combat and magic points" % (result.name, points), evoke=True)
139+
player.tell_others("%s casts a 'drain' spell that drains energy from %s" % (player.name, result.name), evoke=True)
132140

133141

tale/driver.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -961,8 +961,9 @@ def build_location(self, targetLocation: base.Location, zone: Zone, player: play
961961
def do_on_player_death(self, player: player.Player) -> None:
962962
pass
963963

964-
@util.call_periodically(10)
964+
@util.call_periodically(20)
965965
def replenish(self):
966966
for player in self.all_players.values():
967967
player.player.stats.replenish_hp(1)
968-
player.player.stats.replenish_combat_points(1)
968+
player.player.stats.replenish_combat_points(1)
969+
player.player.stats.replenish_magic_points(1)

tale/magic.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from abc import ABC
22
from enum import Enum
33

4-
from tale.player import Player
5-
64

75
class MagicType(Enum):
86
HEAL = 1
@@ -19,17 +17,13 @@ def __init__(self, name: str, base_cost: int, base_value: int = 1, max_level: in
1917
self.base_cost = base_cost
2018
self.max_level = max_level
2119

22-
def do_cast(self, player, target, level):
23-
pass
24-
25-
def check_cost(self, player: Player, level: int) -> bool:
26-
return player.stats.magic_points >= self.base_cost * level
20+
def check_cost(self, magic_points: int, level: int) -> bool:
21+
return magic_points >= self.base_cost * level
2722

2823
spells = {
2924
MagicType.HEAL: Spell('heal', base_cost=2, base_value=5),
3025
MagicType.BOLT: Spell('bolt', base_cost=3, base_value=5),
31-
MagicType.DRAIN: Spell('drain', base_cost=3, base_value=5),
32-
MagicType.REJUVENATE: Spell('rejuvenate', base_cost=3, base_value=5)
26+
MagicType.DRAIN: Spell('drain', base_cost=3, base_value=5)
3327
}
3428

3529
class MagicSkill:

0 commit comments

Comments
 (0)