mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Add stack support for object.search
This commit is contained in:
parent
7015b4992d
commit
42612c92a7
4 changed files with 57 additions and 13 deletions
|
|
@ -11,13 +11,15 @@
|
|||
- Using `lunr` search indexing for better `help` matching and suggestions. Also improve
|
||||
the main help command's default listing output.
|
||||
- Added `content_types` indexing to DefaultObject's ContentsHandler. (volund)
|
||||
- Made most of the networking classes such as Protocols and the SessionHandlers
|
||||
- Made most of the networking classes such as Protocols and the SessionHandlers
|
||||
replaceable via `settings.py` for modding enthusiasts. (volund)
|
||||
- The `initial_setup.py` file can now be substituted in `settings.py` to customize
|
||||
- The `initial_setup.py` file can now be substituted in `settings.py` to customize
|
||||
initial game database state. (volund)
|
||||
- Added new Traits contrib, converted and expanded from Ainneve project.
|
||||
- Added new `requirements_extra.txt` file for easily getting all optional dependencies.
|
||||
- Change default multimatch syntax from 1-obj, 2-obj to obj-1, obj-2.
|
||||
- Change default multimatch syntax from 1-obj, 2-obj to obj-1, obj-2.
|
||||
- Make `object.search` support 'stacks=0' keyword - if ``>0``, the method will return
|
||||
N identical matches instead of triggering a multi-match error.
|
||||
|
||||
### Already in master
|
||||
- Renamed Tutorial classes "Weapon" and "WeaponRack" to "TutorialWeapon" and
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ bulletin boards.
|
|||
#### How will the world be built?
|
||||
|
||||
There are two main ways to handle this:
|
||||
- Traditionally, from in-game with build-commands: This pretty means builders creating content in their game
|
||||
- Traditionally, from in-game with build-commands: This means builders creating content in their game
|
||||
client. This has the advantage of not requiring Python skills nor server access. This can often be a quite
|
||||
intuitive way to build since you are sort-of walking around in your creation as you build it. However, the
|
||||
developer (you) must make sure to provide build-commands that are flexible enough for builders to be able to
|
||||
|
|
@ -119,13 +119,13 @@ code (such as what you can do with the `py` command). You can
|
|||
it's suggested that this is accomplished by adding more powerful build-commands for them to use.
|
||||
|
||||
For our tutorial-game, we will only allow privileged builders to modify the world. The exception is crafting,
|
||||
where we will allow players to to use in-game commands to create specific, prescribed objects from recipes.
|
||||
which we will limit to repairing broken items by combining them with other repair-related items.
|
||||
|
||||
### Systems
|
||||
|
||||
#### Do you base your game off an existing RPG system or make up your own?
|
||||
|
||||
We will make use of [Open Adventure](http://www.geekguild.com/openadventure/), an 'old school' RRG-system
|
||||
We will make use of [Open Adventure](http://www.geekguild.com/openadventure/), a simple 'old school' RPG-system
|
||||
that is available for free under the Creative Commons license. We'll only use a subset of the rules from
|
||||
the blue "basic" book. For the sake of keeping down the length of this tutorial we will limit what features
|
||||
we will include:
|
||||
|
|
@ -140,12 +140,11 @@ we will include:
|
|||
#### What are the game mechanics? How do you decide if an action succeeds or fails?
|
||||
|
||||
Open Adventure's conflict resolution is based on adding a trait (such as Strength) with a random number in
|
||||
order beat a target. We will emulate this in code.
|
||||
order to beat a target. We will emulate this in code.
|
||||
|
||||
There are no pre-set "skills", all resolution is based on using suitable traits in different combinations.
|
||||
The computer can't do this decision on-the-fly like a GM could, so we need to encode what is needed
|
||||
to achieve a certain effect - this will be a set of 'skills'. We will only make the minimum amount of skills
|
||||
needed to accomplish the actions we want to support. This will mean custom Commands.
|
||||
Having a "skill" means getting a bonus to that roll for a more narrow action.
|
||||
Since the computer will need to know exactly what those skills are, we will add them more explicitly than
|
||||
in the rules, but we will only add the minimum to show off the functionality we need.
|
||||
|
||||
#### Does the flow of time matter in your game - does night and day change? What about seasons?
|
||||
|
||||
|
|
|
|||
|
|
@ -375,6 +375,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
nofound_string=None,
|
||||
multimatch_string=None,
|
||||
use_dbref=None,
|
||||
stacked=0,
|
||||
):
|
||||
"""
|
||||
Returns an Object matching a search string/condition
|
||||
|
|
@ -430,10 +431,19 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
will be treated like a normal string. If `None` (default), the ability to query by
|
||||
#dbref is turned on if `self` has the permission 'Builder' and is turned off
|
||||
otherwise.
|
||||
stacked (int, optional): If > 0, multimatches will be analyzed to determine if they
|
||||
only contains identical objects; these are then assumed 'stacked' and no multi-match
|
||||
error will be generated, instead `stacked` number of matches will be returned. If
|
||||
`stacked` is larger than number of matches, returns that number of matches. If
|
||||
the found stack is a mix of objects, return None and handle the multi-match
|
||||
error depending on the value of `quiet`.
|
||||
|
||||
Returns:
|
||||
match (Object, None or list): will return an Object/None if `quiet=False`,
|
||||
otherwise it will return a list of 0, 1 or more matches.
|
||||
Object: If finding a match an `quiet=False`
|
||||
None: If not finding a unique match and `quiet=False`.
|
||||
list: With 0, 1 or more matching objects if `quiet=True`
|
||||
list: With 2 or more matching objects if `stacked` is a positive integer and
|
||||
the matched stack has only object-copies.
|
||||
|
||||
Notes:
|
||||
To find Accounts, use eg. `evennia.account_search`. If
|
||||
|
|
@ -501,8 +511,29 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
use_dbref=use_dbref,
|
||||
)
|
||||
|
||||
nresults = len(results)
|
||||
if stacked > 0 and nresults > 1:
|
||||
# handle stacks, disable multimatch errors
|
||||
nstack = nresults
|
||||
if not exact:
|
||||
# we re-run exact match agains one of the matches to
|
||||
# make sure we were not catching partial matches not belonging
|
||||
# to the stack
|
||||
nstack = len(ObjectDB.objects.get_objs_with_key_or_alias(
|
||||
results[0].key,
|
||||
exact=True,
|
||||
candidates=list(results),
|
||||
typeclasses=[typeclass] if typeclass else None
|
||||
))
|
||||
if nstack == nresults:
|
||||
# a valid stack, return multiple results
|
||||
return list(results)[:stacked]
|
||||
|
||||
if quiet:
|
||||
# don't auto-handle error messaging
|
||||
return list(results)
|
||||
|
||||
# handle error messages
|
||||
return _AT_SEARCH_RESULT(
|
||||
results,
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -74,6 +74,18 @@ class DefaultObjectTest(EvenniaTest):
|
|||
self.assertTrue(self.room1.get_absolute_url())
|
||||
self.assertTrue("admin" in self.room1.web_get_admin_url())
|
||||
|
||||
def test_search_stacked(self):
|
||||
"Test searching stacks"
|
||||
coin1 = DefaultObject.create("coin", location=self.room1)[0]
|
||||
coin2 = DefaultObject.create("coin", location=self.room1)[0]
|
||||
colon = DefaultObject.create("colon", location=self.room1)[0]
|
||||
|
||||
# stack
|
||||
self.assertEqual(self.char1.search("coin", stacked=2), [coin1, coin2])
|
||||
self.assertEqual(self.char1.search("coin", stacked=5), [coin1, coin2])
|
||||
# partial match to 'colon' - multimatch error since stack is not homogenous
|
||||
self.assertEqual(self.char1.search("co", stacked=2), None)
|
||||
|
||||
|
||||
class TestObjectManager(EvenniaTest):
|
||||
"Test object manager methods"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue