mirror of
https://github.com/evennia/evennia.git
synced 2026-04-02 14:07:16 +02:00
Remove PuzzlePartObject and typeclass dependency
This commit is contained in:
parent
2700b4409e
commit
e92e830f87
2 changed files with 90 additions and 48 deletions
|
|
@ -49,8 +49,8 @@ command). Once the recipe is created, all parts and result
|
|||
can be disposed (i.e. destroyed).
|
||||
|
||||
At a later time, a Builder or a Script can arm the puzzle
|
||||
and spawn all puzzle parts (PuzzlePartObject) in their
|
||||
respective locations (See @armpuzzle).
|
||||
and spawn all puzzle parts in their respective
|
||||
locations (See @armpuzzle).
|
||||
|
||||
A regular player can collect the puzzle parts and combine
|
||||
them (See use command). If player has specified
|
||||
|
|
@ -101,7 +101,7 @@ def proto_def(obj, with_tags=True):
|
|||
protodef = {
|
||||
# FIXME: Don't we need to honor ALL properties? attributes, contents, etc.
|
||||
'key': obj.key,
|
||||
'typeclass': 'evennia.contrib.puzzles.PuzzlePartObject', # FIXME: what if obj is another typeclass
|
||||
'typeclass': obj.typeclass_path,
|
||||
'desc': obj.db.desc,
|
||||
'location': obj.location,
|
||||
'home': obj.home,
|
||||
|
|
@ -129,20 +129,6 @@ _PUZZLE_DEFAULT_SUCCESS_USE_MESSAGE = _colorize_message(_PUZZLE_DEFAULT_SUCCESS_
|
|||
|
||||
# ------------------------------------------
|
||||
|
||||
class PuzzlePartObject(DefaultObject):
|
||||
"""
|
||||
Puzzle Part, typically used by @armpuzzle command
|
||||
"""
|
||||
|
||||
def mark_as_puzzle_member(self, puzzle_name):
|
||||
"""
|
||||
Marks this object as a member of puzzle named
|
||||
'puzzle_name'
|
||||
"""
|
||||
self.db.puzzle_name = puzzle_name
|
||||
self.tags.add(puzzle_name, category=_PUZZLES_TAG_CATEGORY)
|
||||
|
||||
|
||||
class PuzzleRecipe(DefaultScript):
|
||||
"""
|
||||
Definition of a Puzzle Recipe
|
||||
|
|
@ -161,12 +147,20 @@ class CmdCreatePuzzleRecipe(MuxCommand):
|
|||
"""
|
||||
Creates a puzzle recipe.
|
||||
|
||||
Each part and result must exist and be placed in their corresponding location.
|
||||
All parts and results are left intact. Caller must explicitly
|
||||
destroy them.
|
||||
Each part and result must exist and be placed in their
|
||||
corresponding location.
|
||||
|
||||
They are all left intact and Caller should explicitly destroy
|
||||
them. If the /arm switch is used, the specified objects become
|
||||
puzzle parts ready to be combined and spawn a new result.
|
||||
|
||||
Switches:
|
||||
arm - the specified objects become puzzle parts as if the puzzle
|
||||
had been armed explicitly. The results are left intact so
|
||||
they must be explicitly destroyed.
|
||||
|
||||
Usage:
|
||||
@puzzle name,<part1[,part2,...>] = <result1[,result2,...]>
|
||||
@puzzle[/arm] name,<part1[,part2,...>] = <result1[,result2,...]>
|
||||
"""
|
||||
|
||||
key = '@puzzle'
|
||||
|
|
@ -487,7 +481,8 @@ class CmdArmPuzzle(MuxCommand):
|
|||
for proto_part in puzzle.db.parts:
|
||||
part = spawn(proto_part)[0]
|
||||
caller.msg("Part %s(%s) spawned and placed at %s(%s)" % (part.name, part.dbref, part.location, part.location.dbref))
|
||||
part.mark_as_puzzle_member(puzzle.db.puzzle_name)
|
||||
part.tags.add(puzzle.db.puzzle_name, category=_PUZZLES_TAG_CATEGORY)
|
||||
part.db.puzzle_name = puzzle.db.puzzle_name
|
||||
|
||||
caller.msg("Puzzle armed |gsuccessfully|n.")
|
||||
|
||||
|
|
@ -536,8 +531,7 @@ class CmdUsePuzzleParts(MuxCommand):
|
|||
if not part:
|
||||
return
|
||||
|
||||
if not part.tags.get(_PUZZLES_TAG_MEMBER, category=_PUZZLES_TAG_CATEGORY) \
|
||||
or not inherits_from(part, PuzzlePartObject):
|
||||
if not part.tags.get(_PUZZLES_TAG_MEMBER, category=_PUZZLES_TAG_CATEGORY):
|
||||
|
||||
# not a puzzle part ... abort
|
||||
caller.msg('You have no idea how %s can be used' % (many))
|
||||
|
|
@ -629,7 +623,8 @@ class CmdUsePuzzleParts(MuxCommand):
|
|||
result_names = []
|
||||
for proto_result in puzzle.db.results:
|
||||
result = spawn(proto_result)[0]
|
||||
result.mark_as_puzzle_member(puzzle.db.puzzle_name)
|
||||
result.tags.add(puzzle.db.puzzle_name, category=_PUZZLES_TAG_CATEGORY)
|
||||
result.db.puzzle_name = puzzle.db.puzzle_name
|
||||
result_names.append(result.name)
|
||||
# FIXME: add 'ramdon' messages:
|
||||
# Hmmm ... did I search result.location?
|
||||
|
|
|
|||
|
|
@ -1183,9 +1183,15 @@ class TestPuzzles(CommandTest):
|
|||
|
||||
def setUp(self):
|
||||
super(TestPuzzles, self).setUp()
|
||||
self.stone = create_object(key='stone', location=self.char1.location)
|
||||
self.flint = create_object(key='flint', location=self.char1.location)
|
||||
self.fire = create_object(key='fire', location=self.char1.location)
|
||||
self.stone = create_object(
|
||||
self.object_typeclass,
|
||||
key='stone', location=self.char1.location)
|
||||
self.flint = create_object(
|
||||
self.object_typeclass,
|
||||
key='flint', location=self.char1.location)
|
||||
self.fire = create_object(
|
||||
self.object_typeclass,
|
||||
key='fire', location=self.char1.location)
|
||||
self.stone.tags.add('tag-stone')
|
||||
self.stone.tags.add('tag-stone', category='tagcat')
|
||||
self.flint.tags.add('tag-flint')
|
||||
|
|
@ -1397,7 +1403,10 @@ class TestPuzzles(CommandTest):
|
|||
self.assertEqual(1,
|
||||
len(list(filter(
|
||||
lambda o: o.key == 'fire' \
|
||||
and inherits_from(o,'evennia.contrib.puzzles.PuzzlePartObject'),
|
||||
and ('makefire', puzzles._PUZZLES_TAG_CATEGORY) \
|
||||
in o.tags.all(return_key_and_category=True) \
|
||||
and (puzzles._PUZZLES_TAG_MEMBER, puzzles._PUZZLES_TAG_CATEGORY) \
|
||||
in o.tags.all(return_key_and_category=True),
|
||||
self.room1.contents))))
|
||||
self._check_room_contents({'stone': 0, 'flint': 0, 'fire': 1}, check_test_tags=True)
|
||||
|
||||
|
|
@ -1494,15 +1503,21 @@ class TestPuzzles(CommandTest):
|
|||
caller=self.char1
|
||||
)
|
||||
|
||||
red_stone = create_object(key='red stone', location=self.char1.location)
|
||||
smoke = create_object(key='smoke', location=self.char1.location)
|
||||
red_stone = create_object(
|
||||
self.object_typeclass,
|
||||
key='red stone', location=self.char1.location)
|
||||
smoke = create_object(
|
||||
self.object_typeclass,
|
||||
key='smoke', location=self.char1.location)
|
||||
|
||||
_puzzleedit('/addresult', recipe_dbref, ['smoke'], 'smoke were added to results')
|
||||
_puzzleedit('/addpart', recipe_dbref, ['red stone', 'stone'], 'red stone, stone were added to parts')
|
||||
|
||||
# create a box so we can put all objects in
|
||||
# so that they can't be found during puzzle resolution
|
||||
self.box = create_object(key='box', location=self.char1.location)
|
||||
self.box = create_object(
|
||||
self.object_typeclass,
|
||||
key='box', location=self.char1.location)
|
||||
def _box_all():
|
||||
for o in self.room1.contents:
|
||||
if o not in [self.char1, self.char2, self.exit,
|
||||
|
|
@ -1634,12 +1649,24 @@ class TestPuzzles(CommandTest):
|
|||
|
||||
# parts don't survive resolution
|
||||
# but produce a large result set
|
||||
tree = create_object(key='tree', location=self.char1.location)
|
||||
axe = create_object(key='axe', location=self.char1.location)
|
||||
sweat = create_object(key='sweat', location=self.char1.location)
|
||||
dull_axe = create_object(key='dull axe', location=self.char1.location)
|
||||
timber = create_object(key='timber', location=self.char1.location)
|
||||
log = create_object(key='log', location=self.char1.location)
|
||||
tree = create_object(
|
||||
self.object_typeclass,
|
||||
key='tree', location=self.char1.location)
|
||||
axe = create_object(
|
||||
self.object_typeclass,
|
||||
key='axe', location=self.char1.location)
|
||||
sweat = create_object(
|
||||
self.object_typeclass,
|
||||
key='sweat', location=self.char1.location)
|
||||
dull_axe = create_object(
|
||||
self.object_typeclass,
|
||||
key='dull axe', location=self.char1.location)
|
||||
timber = create_object(
|
||||
self.object_typeclass,
|
||||
key='timber', location=self.char1.location)
|
||||
log = create_object(
|
||||
self.object_typeclass,
|
||||
key='log', location=self.char1.location)
|
||||
parts = ['tree', 'axe']
|
||||
results = (['sweat'] * 10) + ['dull axe'] + (['timber'] * 20) + (['log'] * 50)
|
||||
recipe_dbref = self._good_recipe(
|
||||
|
|
@ -1666,9 +1693,15 @@ class TestPuzzles(CommandTest):
|
|||
# parts also appear in results
|
||||
# causing a new puzzle to be armed 'automatically'
|
||||
# i.e. the puzzle is self-sustaining
|
||||
hole = create_object(key='hole', location=self.char1.location)
|
||||
shovel = create_object(key='shovel', location=self.char1.location)
|
||||
dirt = create_object(key='dirt', location=self.char1.location)
|
||||
hole = create_object(
|
||||
self.object_typeclass,
|
||||
key='hole', location=self.char1.location)
|
||||
shovel = create_object(
|
||||
self.object_typeclass,
|
||||
key='shovel', location=self.char1.location)
|
||||
dirt = create_object(
|
||||
self.object_typeclass,
|
||||
key='dirt', location=self.char1.location)
|
||||
|
||||
parts = ['shovel', 'hole']
|
||||
results = ['dirt', 'hole', 'shovel']
|
||||
|
|
@ -1706,12 +1739,24 @@ class TestPuzzles(CommandTest):
|
|||
|
||||
def test_e2e_interchangeable_parts_and_results(self):
|
||||
# Parts and Results can be used in multiple puzzles
|
||||
egg = create_object(key='egg', location=self.char1.location)
|
||||
flour = create_object(key='flour', location=self.char1.location)
|
||||
boiling_water = create_object(key='boiling water', location=self.char1.location)
|
||||
boiled_egg = create_object(key='boiled egg', location=self.char1.location)
|
||||
dough = create_object(key='dough', location=self.char1.location)
|
||||
pasta = create_object(key='pasta', location=self.char1.location)
|
||||
egg = create_object(
|
||||
self.object_typeclass,
|
||||
key='egg', location=self.char1.location)
|
||||
flour = create_object(
|
||||
self.object_typeclass,
|
||||
key='flour', location=self.char1.location)
|
||||
boiling_water = create_object(
|
||||
self.object_typeclass,
|
||||
key='boiling water', location=self.char1.location)
|
||||
boiled_egg = create_object(
|
||||
self.object_typeclass,
|
||||
key='boiled egg', location=self.char1.location)
|
||||
dough = create_object(
|
||||
self.object_typeclass,
|
||||
key='dough', location=self.char1.location)
|
||||
pasta = create_object(
|
||||
self.object_typeclass,
|
||||
key='pasta', location=self.char1.location)
|
||||
|
||||
# Three recipes:
|
||||
# 1. breakfast: egg + boiling water = boiled egg & boiling water
|
||||
|
|
@ -1755,7 +1800,9 @@ class TestPuzzles(CommandTest):
|
|||
|
||||
# create a box so we can put all objects in
|
||||
# so that they can't be found during puzzle resolution
|
||||
self.box = create_object(key='box', location=self.char1.location)
|
||||
self.box = create_object(
|
||||
self.object_typeclass,
|
||||
key='box', location=self.char1.location)
|
||||
def _box_all():
|
||||
# print "boxing all\n", "-"*20
|
||||
for o in self.room1.contents:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue