diff --git a/evennia/contrib/game_systems/containers/README.md b/evennia/contrib/game_systems/containers/README.md index e27f7af1d8..e9e3d91c67 100644 --- a/evennia/contrib/game_systems/containers/README.md +++ b/evennia/contrib/game_systems/containers/README.md @@ -1,5 +1,5 @@ # Containers -*Contribution by InspectorCaracal (2023)* +Contribution by InspectorCaracal (2023) Adds the ability to put objects into other container objects by providing a container typeclass and extending certain base commands. @@ -22,11 +22,11 @@ This will replace the default `look` and `get` commands with the container-frien ## Usage -The contrib includes a `ContainerObject` typeclass which has all of the set-up necessary to be used as a container. To use, all you need to do is create an object in-game with that typeclass - it will automatically inherit anything you implemented in your base Object typeclass as well. +The contrib includes a `ContribContainer` typeclass which has all of the set-up necessary to be used as a container. To use, all you need to do is create an object in-game with that typeclass - it will automatically inherit anything you implemented in your base Object typeclass as well. - create bag:game_systems.containers.ContainerObject + create bag:game_systems.containers.ContribContainer -The contrib's `ContainerObject` comes with a capacity limit of a maximum number of items it can hold. This can be changed per individual object. +The contrib's `ContribContainer` comes with a capacity limit of a maximum number of items it can hold. This can be changed per individual object. In code: ```py @@ -42,14 +42,14 @@ You can also make any other objects usable as containers by setting the `get_fro ## Extending -The `ContainerObject` class is intended to be usable as-is, but you can also inherit from it for your own container classes to extend its functionality. Aside from having the container lock pre-set on object creation, it comes with three main additions: +The `ContribContainer` class is intended to be usable as-is, but you can also inherit from it for your own container classes to extend its functionality. Aside from having the container lock pre-set on object creation, it comes with three main additions: ### `capacity` property -`ContainerObject.capacity` is an `AttributeProperty` - meaning you can access it in code with `obj.capacity` and also set it in game with `set obj/capacity = 5` - which represents the capacity of the container as an integer. You can override this with a more complex representation of capacity on your own container classes. +`ContribContainer.capacity` is an `AttributeProperty` - meaning you can access it in code with `obj.capacity` and also set it in game with `set obj/capacity = 5` - which represents the capacity of the container as an integer. You can override this with a more complex representation of capacity on your own container classes. ### `at_pre_get_from` and `at_pre_put_in` methods -These two methods on `ContainerObject` are called as extra checks when attempting to either get an object from, or put an object in, a container. The contrib's `ContainerObject.at_pre_get_from` doesn't do any additional validation by default, while `ContainerObject.at_pre_put_in` does a simple capacity check. +These two methods on `ContribContainer` are called as extra checks when attempting to either get an object from, or put an object in, a container. The contrib's `ContribContainer.at_pre_get_from` doesn't do any additional validation by default, while `ContribContainer.at_pre_put_in` does a simple capacity check. You can override these methods on your own child class to do any additional capacity or access checks. \ No newline at end of file diff --git a/evennia/contrib/game_systems/containers/__init__.py b/evennia/contrib/game_systems/containers/__init__.py index ef7887ea31..ccfcf28afa 100644 --- a/evennia/contrib/game_systems/containers/__init__.py +++ b/evennia/contrib/game_systems/containers/__init__.py @@ -1 +1 @@ -from .containers import ContainerCmdSet, ContainerObject +from .containers import ContainerCmdSet, ContribContainer # noqa diff --git a/evennia/contrib/game_systems/containers/containers.py b/evennia/contrib/game_systems/containers/containers.py index 46e6eee449..19cbcf76bb 100644 --- a/evennia/contrib/game_systems/containers/containers.py +++ b/evennia/contrib/game_systems/containers/containers.py @@ -22,10 +22,10 @@ The ContainerCmdSet includes: - a modified `get` command to get objects from your location or inside objects - a new `put` command to put objects from your inventory into other objects -Create objects with the `ContainerObject` typeclass to easily create containers, +Create objects with the `ContribContainer` typeclass to easily create containers, or implement the same locks/hooks in your own typeclasses. -`ContainerObject` implements the following new methods: +`ContribContainer` implements the following new methods: at_pre_get_from(getter, target, **kwargs) - called with the pre-get hooks at_pre_put_in(putter, target, **kwargs) - called with the pre-put hooks @@ -40,7 +40,7 @@ from evennia.utils import class_from_module _BASE_OBJECT_TYPECLASS = class_from_module(settings.BASE_OBJECT_TYPECLASS, DefaultObject) -class ContainerObject(_BASE_OBJECT_TYPECLASS): +class ContribContainer(_BASE_OBJECT_TYPECLASS): """ A type of Object which can be used as a container. @@ -51,10 +51,15 @@ class ContainerObject(_BASE_OBJECT_TYPECLASS): capacity = AttributeProperty(default=20) def at_object_creation(self): + """ + Extends the base object `at_object_creation` method by setting the "get_from" lock to "true", + allowing other objects to be put inside and removed from this object. + + By default, a lock type not being explicitly set will fail access checks, so objects without + the new "get_from" access lock will fail the access checks and continue behaving as + non-container objects. + """ super().at_object_creation() - # adds a lock permission to allow items to be put inside or taken out - # by default, a lock type not being explicitly set will fail access checks, so normal - # objects without the get_from type set will fail get_from access checks self.locks.add("get_from:true()") def at_pre_get_from(self, getter, target, **kwargs): @@ -65,6 +70,9 @@ class ContainerObject(_BASE_OBJECT_TYPECLASS): Args: getter (Object): The actor attempting to take something from this object. target (Object): The thing this object contains that is being removed. + + Returns: + boolean: Whether the object `target` should be gotten or not. """ return True @@ -76,7 +84,10 @@ class ContainerObject(_BASE_OBJECT_TYPECLASS): putter (Object): The actor attempting to put something in this object. target (Object): The thing being put into this object. - NOTE: + Returns: + boolean: Whether the object `target` should be put down or not. + + Note: To add more complex capacity checks, modify this method on your child typeclass. """ # check if we're already at capacity diff --git a/evennia/contrib/game_systems/containers/tests.py b/evennia/contrib/game_systems/containers/tests.py index 8d34582215..5057c7695b 100644 --- a/evennia/contrib/game_systems/containers/tests.py +++ b/evennia/contrib/game_systems/containers/tests.py @@ -1,13 +1,13 @@ from evennia import create_object from evennia.utils.test_resources import BaseEvenniaTest, BaseEvenniaCommandTest # noqa -from .containers import ContainerObject, CmdContainerGet, CmdContainerLook, CmdPut +from .containers import ContribContainer, CmdContainerGet, CmdContainerLook, CmdPut class TestContainer(BaseEvenniaTest): def setUp(self): super().setUp() # create a container to test with - self.container = create_object(key="Box", typeclass=ContainerObject, location=self.room1) + self.container = create_object(key="Box", typeclass=ContribContainer, location=self.room1) def test_capacity(self): # limit capacity to 1 @@ -22,7 +22,7 @@ class TestContainerCmds(BaseEvenniaCommandTest): def setUp(self): super().setUp() # create a container to test with - self.container = create_object(key="Box", typeclass=ContainerObject, location=self.room1) + self.container = create_object(key="Box", typeclass=ContribContainer, location=self.room1) def test_look_in(self): # make sure the object is in the container so we can look at it