Skip to content

Commit a4ea2d0

Browse files
authored
Merge pull request #65 from neph1/update-v0.24.0
Update v0.24.0
2 parents 6ca6330 + d4df0db commit a4ea2d0

File tree

13 files changed

+211
-41
lines changed

13 files changed

+211
-41
lines changed

generic_items.json

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
{
2+
"generic_weapons": [
3+
{
4+
"name": "Dagger",
5+
"weapon_type": "ONE_HANDED",
6+
"short_descr": "A steel dagger",
7+
"base_damage": 1,
8+
"weight": 0.5,
9+
"type": "Weapon"
10+
},
11+
{
12+
"name": "Club",
13+
"weapon_type": "ONE_HANDED",
14+
"short_descr": "A wooden club",
15+
"base_damage": 1,
16+
"weight": 1,
17+
"type": "Weapon"
18+
}
19+
],
20+
"fantasy_weapons": [
21+
{
22+
"name": "Sword",
23+
"weapon_type": "ONE_HANDED",
24+
"short_descr": "A plain sword",
25+
"base_damage": 2,
26+
"weight": 3,
27+
"value": 20,
28+
"type": "Weapon"
29+
},
30+
{
31+
"name": "Spear",
32+
"weapon_type": "TWO_HANDED",
33+
"short_descr": "A spear",
34+
"base_damage": 3,
35+
"weight": 4,
36+
"value": 10,
37+
"type": "Weapon"
38+
},
39+
{
40+
"name": "Crossbow",
41+
"weapon_type": "TWO_HANDED_RANGED",
42+
"short_descr": "A simple crossbow",
43+
"base_damage": 2,
44+
"weight": 5,
45+
"value": 50,
46+
"type": "Weapon"
47+
}
48+
],
49+
"modern_weapons": [
50+
{
51+
"name": "Rusty pipe",
52+
"weapon_type": "ONE_HANDED",
53+
"short_descr": "A left-over piece of plumbing",
54+
"base_damage": 1,
55+
"weight": 3,
56+
"value": 1
57+
},
58+
{
59+
"name": "Semi-automatic pistol",
60+
"weapon_type": "ONE_HANDED_RANGED",
61+
"short_descr": "A pistol that has seen better days.",
62+
"base_damage": 2,
63+
"weight": 2,
64+
"value": 100
65+
}
66+
],
67+
"fantasy_items": [
68+
{
69+
"name": "Potion of healing",
70+
"short_descr": "A potion of healing",
71+
"weight": 0.5,
72+
"value": 50,
73+
"effect": 10,
74+
"type": "Health"
75+
}
76+
],
77+
"generic_various": [
78+
{
79+
"name": "Note",
80+
"weight": 0.1,
81+
"type": "Note"
82+
},
83+
{
84+
"name": "Bread",
85+
"weight": 0.5,
86+
"short_descr": "A loaf of bread",
87+
"effect": 10,
88+
"type": "Food"
89+
}
90+
]
91+
}

stories/prancingllama/zones/prancingllama.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def init(self):
2020
def spawn_rat(self, ctx: Context) -> None:
2121
rat_skull = Item("rat_skull", "giant rat skull", descr="It's a giant rat's bloody skull.")
2222
if not self.rat or self.rat.alive == False:
23-
self.rat = Rat("giant rat", random.choice("m"), descr="A vicious looking, giant, rat", race="giant rat")
23+
self.rat = Rat("giant rat", random.choice("m"), descr="A vicious looking, giant rat", race="giant rat")
24+
self.rat.should_produce_remains = True
2425
self.rat.init_inventory([rat_skull])
2526
self.rat.move(self)
2627

tale/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,11 +1569,11 @@ def get_worn_items(self) -> Iterable[Wearable]:
15691569

15701570
def do_on_death(self, ctx: util.Context) -> 'Container':
15711571
"""Called when the living dies."""
1572-
if not self.should_produce_remains:
1573-
return None
1574-
remains = Container(f"remains of {self.title}")
1575-
remains.init_inventory(self.inventory)
1576-
self.location.insert(remains, None)
1572+
remains = None
1573+
if self.should_produce_remains:
1574+
remains = Container(f"remains of {self.title}")
1575+
remains.init_inventory(self.inventory)
1576+
self.location.insert(remains, None)
15771577
self.destroy(ctx)
15781578
return remains
15791579

tale/driver.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -652,11 +652,6 @@ def go_through_exit(self, player: player.Player, direction: str, evoke: bool=Tru
652652
if zone and zone.name != new_zone.name:
653653
player.tell(f"You're entering {new_zone.name}:{new_zone.description}")
654654

655-
if self.story.config.custom_resources and not target_location.avatar:
656-
result = self.llm_util.generate_image(target_location.name, target_location.description)
657-
if result:
658-
target_location.avatar = target_location.name
659-
660655
if xt.enter_msg:
661656
player.tell(xt.enter_msg, end=True, evoke=False, short_len=True)
662657
player.tell("\n")

tale/items/generic.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,35 @@
33
"""
44

55

6+
import json
7+
import os
8+
from tale import parse_utils
69
from tale.base import Item, Weapon
710
from tale.items.basic import Note
811
from tale.weapon_type import WeaponType
912

10-
generic_weapons = [
11-
Weapon(name="Dagger", weapon_type=WeaponType.ONE_HANDED, short_descr='A steel dagger', base_damage=1).to_dict(),
12-
Weapon(name="Club", weapon_type=WeaponType.ONE_HANDED, short_descr='A wooden club', base_damage=1).to_dict(),
13-
]
13+
def load() -> dict:
14+
items = dict()
15+
with open(os.path.realpath(os.path.join(os.path.dirname(__file__), "../../generic_items.json")), "r") as file:
16+
items = json.load(file, strict=False)
17+
return items
1418

15-
fantasy_weapons = [
16-
Weapon(name="Sword", weapon_type=WeaponType.ONE_HANDED, short_descr='A plain sword', base_damage=2).to_dict(),
17-
Weapon(name="Spear", weapon_type=WeaponType.TWO_HANDED, short_descr='A spear', base_damage=3).to_dict(),
18-
Weapon(name='Crossbow', weapon_type=WeaponType.TWO_HANDED_RANGED, short_descr='A simple crossbow', base_damage=2).to_dict(),
19-
]
20-
21-
modern_weapons = [
22-
Weapon(name="Rusty pipe", weapon_type=WeaponType.ONE_HANDED, short_descr='A left-over piece of plumbing', base_damage=1).to_dict(),
23-
Weapon(name='Semi-automatic pistol', weapon_type=WeaponType.ONE_HANDED_RANGED, short_descr='A pistol that has seen better days.', base_damage=2).to_dict(),
24-
]
25-
26-
generic_various = [
27-
Note(name="Note", weight=0.1).to_dict()
28-
]
19+
items = load()
2920

21+
generic_weapons = items.get('generic_weapons', [])
22+
fantasy_weapons = items.get('fantasy_weapons', [])
23+
modern_weapons = items.get('modern_weapons', [])
24+
scifi_weapons = items.get('scifi_weapons', [])
25+
fantasy_items = items.get('fantasy_items', [])
26+
modern_items = items.get('modern_items', [])
27+
scifi_items = items.get('scifi_items', [])
28+
generic_various = items.get('generic_various', [])
3029

3130
generic_items = {
32-
'fantasy': [*generic_weapons, *fantasy_weapons, *generic_various],
33-
'modern': [*generic_weapons, *modern_weapons, *generic_various],
34-
'postapoc': [*generic_weapons, *modern_weapons, *generic_various],
31+
'fantasy': [*generic_weapons, *fantasy_weapons, *fantasy_items, *generic_various],
32+
'modern': [*generic_weapons, *modern_weapons, *modern_items, *generic_various],
33+
'postapoc': [*generic_weapons, *modern_weapons, *modern_items, *generic_various],
34+
'scifi': [*generic_weapons, *scifi_weapons, *scifi_items, *modern_weapons, *modern_items, *generic_various],
3535
'': [*generic_weapons, *generic_various],
3636
}
3737

tale/llm/llm_cache.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ def generate_hash(item: str) -> int:
1212
def cache_event(event: str, event_hash: int = -1) -> int:
1313
""" Adds an event to the cache.
1414
Generates a hash if none supplied"""
15+
if not isinstance(event, str):
16+
print('cache_look received non-string look: ' + str(event) + ' of type ' + str(type(event)) + '. Converting to string.')
17+
event = str(event)
1518
if event_hash == -1:
1619
event_hash = generate_hash(event)
1720
if event_cache.get(event_hash) == None:
@@ -25,6 +28,9 @@ def get_events(event_hashes: [int]) -> str:
2528
def cache_look(look: str, look_hash: int = -1) -> int:
2629
""" Adds an event to the cache.
2730
Generates a hash if none supplied"""
31+
if not isinstance(look, str):
32+
print('cache_look received non-string look: ' + str(look) + ' of type ' + str(type(look)) + '. Converting to string.')
33+
look = str(look)
2834
if look_hash == -1:
2935
look_hash = generate_hash(look)
3036
if look_cache.get(look_hash) == None:

tale/llm/llm_io.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ def __init__(self, config: dict = None, backend_config: dict = None):
2828

2929
def synchronous_request(self, request_body: dict, prompt: str, context: str = '') -> str:
3030
""" Send request to backend and return the result """
31-
if request_body.get('grammar', None) and 'openai' in self.url:
31+
if request_body.get('grammar', None) and self.backend == 'openai':
3232
# TODO: temp fix for openai
33-
request_body.pop('grammar')
33+
request_body['grammar_string'] = request_body.pop('grammar')
3434
request_body['response_format'] = self.openai_json_format
3535
request_body = self.io_adapter.set_prompt(request_body, prompt, context)
3636
response = requests.post(self.url + self.endpoint, headers=self.headers, data=json.dumps(request_body))

tale/llm/llm_utils.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def evoke(self, message: str, short_len: bool=False, rolling_prompt: str = '', a
8888
if cached_look:
8989
return output_template.format(message=message, text=cached_look), rolling_prompt
9090
trimmed_message = parse_utils.remove_special_chars(str(message))
91-
story_context = EvokeContext(story_context=self.__story_context, history=rolling_prompt if not skip_history or alt_prompt else '', extra_context=extra_context)
91+
story_context = EvokeContext(story_context=self.__story_context, history=rolling_prompt if not (skip_history or alt_prompt) else '', extra_context=extra_context)
9292
prompt = self.pre_prompt
9393
prompt += alt_prompt or (self.evoke_prompt.format(
9494
context = '{context}',
@@ -149,13 +149,20 @@ def build_location(self, location: Location, exit_location_name: str, zone_info:
149149
story_type=self.__story_type,
150150
world_info=self.__world_info,
151151
world_mood=self.__story.config.world_mood)
152-
return self._world_building.build_location(location,
152+
new_locations, exits, npcs = self._world_building.build_location(location,
153153
exit_location_name,
154154
zone_info,
155155
context=world_generation_context,
156156
world_creatures=world_creatures,
157157
world_items=world_items,
158158
neighbors=neighbors)
159+
160+
if not location.avatar and self.__story.config.image_gen:
161+
result = self.generate_image(location.name, location.description)
162+
if result:
163+
location.avatar = location.name + '.jpg'
164+
return new_locations, exits, npcs
165+
159166

160167
def perform_idle_action(self, character_name: str, location: Location, character_card: str = '', sentiments: dict = {}, last_action: str = '', event_history: str = '') -> list:
161168
return self._character.perform_idle_action(character_name, location, self.__story_context, character_card, sentiments, last_action, event_history=event_history)
@@ -220,7 +227,7 @@ def generate_note_quest(self, zone_info: dict) -> Quest:
220227
def generate_note_lore(self, zone_info: dict) -> str:
221228
return self._world_building.generate_note_lore(context=self._get_world_context(),
222229
zone_info=zone_info)
223-
230+
# visible for testing
224231
def generate_image(self, character_name: str, character_appearance: dict = '', save_path: str = "./resources", copy_file: bool = True) -> bool:
225232
if not self._image_gen:
226233
return False

tale/parse_utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,16 @@ def load_items(json_items: [], locations = {}) -> dict:
9999
new_item = _init_money(item)
100100
elif item_type == 'Health':
101101
new_item = _init_health(item)
102-
new_item.healing_effect=item.get('value', 10)
102+
new_item.healing_effect=item.get('effect', 10)
103103
elif item_type == 'Food':
104104
new_item = _init_food(item)
105-
new_item.affect_fullness=item.get('value', 10)
105+
new_item.affect_fullness=item.get('effect', 10)
106106
new_item.poisoned=item.get('poisoned', False)
107107
elif item_type == 'Weapon':
108108
new_item = _init_weapon(item)
109109
elif item_type == 'Drink':
110110
new_item = _init_drink(item)
111-
new_item.affect_thirst=item.get('value', 10)
111+
new_item.affect_thirst=item.get('effect', 10)
112112
new_item.poisoned=item.get('poisoned', False)
113113
elif item_type == 'Container' or item_type == 'Boxlike':
114114
new_item = _init_boxlike(item)
@@ -319,7 +319,7 @@ def _init_wearable(item: dict):
319319
value=item.get('value', 1))
320320

321321
def set_note(note: Note, item: dict):
322-
note.text = item['text']
322+
note.text = item.get('text', '')
323323

324324
def remove_special_chars(message: str):
325325
re.sub('[^A-Za-z0-9 .,_\-\'\"]+', '', message)

tests/test_combat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def test_produce_remains(self):
7474
rat.should_produce_remains = True
7575
remains = rat.do_on_death(ctx)
7676
assert(remains)
77+
assert(remains.location == rat.location)
7778
remains.location.remove(remains, None)
7879

7980
def test_not_produce_remains(self):

0 commit comments

Comments
 (0)