From e92e830f8740e2b45b9312f070480600ff4ac3ee Mon Sep 17 00:00:00 2001 From: Henddher Pedroza Date: Tue, 2 Oct 2018 15:17:15 +0100 Subject: [PATCH] Remove PuzzlePartObject and typeclass dependency --- evennia/contrib/puzzles.py | 45 ++++++++---------- evennia/contrib/tests.py | 93 ++++++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 48 deletions(-) diff --git a/evennia/contrib/puzzles.py b/evennia/contrib/puzzles.py index 1738954066..c4654483ca 100644 --- a/evennia/contrib/puzzles.py +++ b/evennia/contrib/puzzles.py @@ -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,] = + @puzzle[/arm] name,] = """ 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? diff --git a/evennia/contrib/tests.py b/evennia/contrib/tests.py index 6eca07289b..62d5dc81ae 100644 --- a/evennia/contrib/tests.py +++ b/evennia/contrib/tests.py @@ -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: