mirror of
https://github.com/evennia/evennia.git
synced 2026-03-27 02:06:32 +01:00
new unit tests for the new getters/remove methods. general test case improvement (+47 squashed commit)
Squashed commit: [da8f778e1] fixed issue with buff instancing saving previous cache information [50e381135] fixing clear to use new private method [523196876] added new removal methods, spun boilerplate into private method [ab2fe7a1b] misc [4a2c2e887] added get_by_cachevalue, for arbitrary cache value comparison [4e9199fd9] fix expired property [cc6411eb2] added option to trigger buffs at the same time you check them [eb112c12f] added get_by_source method to slice cache by source [5d880d4f9] added "clear" method to remove all buffs [49997e724] extended "expired" logic to include buffs with no stacks [7ef357ade] docstring fixes [306801d02] Added a little docstring bit for disconnecting autopause from signals and moving it to object puppet hooks [7a120a2f8] fixed the sample buff for poison to demonstrate how playtime buff pause hooks happen (as at_pause fires after the object is moved to None, you can't message the None-room's contents) [ada4457d1] made the pause variable assignments more verbose [d64369908] nomenclature change: uid -> buffkey [e5dd9a352] fixing places where the handler property name change from "db" to "buffcache" broke stuff on the buff class [553d12b4b] lots of docstring updates and comments; also made conditional hook work with ticking [b8d79583f] ran black autoformatter [d5550f331] changing all the default dictionary assignments to None instead [88c9a4889] sample buff of stat customizer [72323a19e] added sample buff which allows stat customization, and unit test to cover it [02453a79f] adding procgen ids for non-unique, non-refresh (ie, each time the buff is applied, it is as a full instance with a separate key) [c72e5f2d7] added to_filter argument to slice methods, letting you slice an arbitrary dictionary as well as the main cache [d8996f3a3] stress test for batch read/trigger [f06f74463] last bit of cacheing, docstring update [538afc676] fixing tests to not use __getattr__ on the handler [905cfd6bb] removing __getattr__ [e588742ea] hooking caching into the buff instancing process [7555ebae9] added method to instance entire cache, refactored dict-comprehension properties to use new method. should be more efficient? [45f15fc46] fix to reapply logic; stacking and old cache [d2460c9e6] docstring support for to_cache arg [62f3f27d8] added to_cache arg for buff application, allows you to store arbitrary info in the buff cache [6c2046497] general cleanup [357945459] forgot to finish the mod for the "sated" moodlet sample buff [b4b3ac48a] clamp minimum multiplier to 0 [da3e67fa6] allowing multiple stacks, cruft cleanup [62110fd00] sample buffs [77f6a56e8] fixing tests to work with new naming [a9202f67c] misc cleanup [887d9734b] allow infinite stacks [887fb4b29] change duration setter [da4277e2c] add at_pre_check [6009469bc] fix pickling errors with handler properties [89a2d02ee] allo ticking buffs to autopause [a77bded93] fix flavor return [60fcaa36f] swapping on_ to at_ for hooks to match evennia style [130e600ea] import cleanup
This commit is contained in:
parent
f340d4c6e4
commit
3a52913bbb
3 changed files with 1088 additions and 522 deletions
File diff suppressed because it is too large
Load diff
141
evennia/contrib/game_systems/buffs/samplebuffs.py
Normal file
141
evennia/contrib/game_systems/buffs/samplebuffs.py
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
import random
|
||||
from .buff import BaseBuff, Mod
|
||||
|
||||
|
||||
class Exploit(BaseBuff):
|
||||
key = "exploit"
|
||||
name = "Exploit"
|
||||
flavor = "You are learning your opponent's weaknesses."
|
||||
|
||||
duration = -1
|
||||
maxstacks = 20
|
||||
|
||||
triggers = ["hit"]
|
||||
|
||||
stack_msg = {
|
||||
1: "You begin to notice flaws in your opponent's defense.",
|
||||
10: "You've begun to match the battle's rhythm.",
|
||||
20: "You've found a gap in the guard!",
|
||||
}
|
||||
|
||||
def conditional(self, *args, **kwargs):
|
||||
if self.handler.get_by_type(Exploited):
|
||||
return False
|
||||
return True
|
||||
|
||||
def at_trigger(self, trigger: str, *args, **kwargs):
|
||||
chance = self.stacks / 20
|
||||
roll = random.random()
|
||||
|
||||
if chance > roll:
|
||||
self.handler.add(Exploited)
|
||||
self.owner.msg("An opportunity presents itself!")
|
||||
elif chance < roll:
|
||||
self.handler.add(Exploit)
|
||||
|
||||
if self.stacks in self.stack_msg:
|
||||
self.owner.msg(self.stack_msg[self.stacks])
|
||||
|
||||
|
||||
class Exploited(BaseBuff):
|
||||
key = "exploited"
|
||||
name = "Exploited"
|
||||
flavor = "You have sensed your target's vulnerability, and are poised to strike."
|
||||
|
||||
duration = 30
|
||||
|
||||
mods = [Mod("damage", "add", 100)]
|
||||
|
||||
def at_post_check(self, *args, **kwargs):
|
||||
self.owner.msg("You ruthlessly exploit your target's weakness!")
|
||||
self.remove(quiet=True)
|
||||
|
||||
def at_remove(self, *args, **kwargs):
|
||||
self.owner.msg("You have waited too long; the opportunity passes.")
|
||||
|
||||
|
||||
class Leeching(BaseBuff):
|
||||
key = "leeching"
|
||||
name = "Leeching"
|
||||
flavor = "Attacking this target fills you with vigor."
|
||||
|
||||
duration = 30
|
||||
|
||||
triggers = ["taken_damage"]
|
||||
|
||||
def at_trigger(self, trigger: str, attacker=None, damage=None, *args, **kwargs):
|
||||
if not attacker or not damage:
|
||||
return
|
||||
attacker.msg("You have been healed for {heal} life!".format(heal=damage * 0.1))
|
||||
|
||||
|
||||
class Poison(BaseBuff):
|
||||
key = "poison"
|
||||
name = "Poison"
|
||||
flavor = "A poison wracks this body with painful spasms."
|
||||
|
||||
duration = 120
|
||||
|
||||
maxstacks = 5
|
||||
tickrate = 5
|
||||
dmg = 5
|
||||
|
||||
playtime = True
|
||||
|
||||
def at_pause(self, *args, **kwargs):
|
||||
self.owner.db.prelogout_location.msg_contents(
|
||||
"{actor} stops twitching, their flesh a deathly pallor.".format(actor=self.owner.named)
|
||||
)
|
||||
|
||||
def at_unpause(self, *args, **kwargs):
|
||||
self.owner.location.msg_contents(
|
||||
"{actor} begins to twitch again, their cheeks flushing red with blood.".format(
|
||||
actor=self.owner.named
|
||||
)
|
||||
)
|
||||
|
||||
def at_tick(self, initial=True, *args, **kwargs):
|
||||
_dmg = self.dmg * self.stacks
|
||||
if not initial:
|
||||
self.owner.location.msg_contents(
|
||||
"Poison courses through {actor}'s body, dealing {damage} damage.".format(
|
||||
actor=self.owner.named, damage=_dmg
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class Sated(BaseBuff):
|
||||
key = "sated"
|
||||
name = "Sated"
|
||||
flavor = "You have eaten a great meal!"
|
||||
|
||||
duration = 180
|
||||
maxstacks = 3
|
||||
|
||||
mods = [Mod("mood", "add", 15)]
|
||||
|
||||
|
||||
class StatBuff(BaseBuff):
|
||||
"""Customize the stat this buff affects by feeding a list in the order [stat, mod, base, perstack] to the cache argument when added"""
|
||||
|
||||
key = "statbuff"
|
||||
name = "statbuff"
|
||||
flavor = "This buff affects the following stats: {stats}"
|
||||
|
||||
maxstacks = 0
|
||||
refresh = True
|
||||
unique = False
|
||||
|
||||
cache = {"modgen": ["foo", "add", 0, 0]}
|
||||
|
||||
def __init__(self, handler, buffkey, cache={}) -> None:
|
||||
super().__init__(handler, buffkey, cache)
|
||||
# Finds our "modgen" cache value, which we pass on application
|
||||
modgen = list(self.cache["modgen"])
|
||||
if modgen:
|
||||
self.mods = [Mod(*modgen)]
|
||||
msg = ""
|
||||
_msg = [mod.stat for mod in self.mods]
|
||||
for stat in _msg:
|
||||
msg += stat
|
||||
self.flavor = self.flavor.format(stats=msg)
|
||||
|
|
@ -3,87 +3,95 @@ from unittest.mock import Mock, patch
|
|||
from evennia import DefaultObject, create_object
|
||||
from evennia.utils import create
|
||||
from evennia.utils.utils import lazy_property
|
||||
from .samplebuffs import StatBuff
|
||||
|
||||
# the function we want to test
|
||||
from .buff import BaseBuff, Mod, BuffHandler, BuffableProperty
|
||||
from evennia.utils.test_resources import EvenniaTest
|
||||
|
||||
|
||||
class _EmptyBuff(BaseBuff):
|
||||
pass
|
||||
|
||||
|
||||
class _TestModBuff(BaseBuff):
|
||||
key = 'tmb'
|
||||
name = 'tmb'
|
||||
flavor = 'modderbuff'
|
||||
key = "tmb"
|
||||
name = "tmb"
|
||||
flavor = "modderbuff"
|
||||
maxstacks = 5
|
||||
mods = [
|
||||
Mod('stat1', 'add', 10, 5),
|
||||
Mod('stat2', 'mult', 0.5)
|
||||
]
|
||||
mods = [Mod("stat1", "add", 10, 5), Mod("stat2", "mult", 0.5)]
|
||||
|
||||
|
||||
class _TestModBuff2(BaseBuff):
|
||||
key = 'tmb2'
|
||||
name = 'tmb2'
|
||||
flavor = 'modderbuff2'
|
||||
key = "tmb2"
|
||||
name = "tmb2"
|
||||
flavor = "modderbuff2"
|
||||
maxstacks = 1
|
||||
mods = [
|
||||
Mod('stat1', 'mult', 1.0),
|
||||
Mod('stat1', 'add', 10)
|
||||
]
|
||||
mods = [Mod("stat1", "mult", 1.0), Mod("stat1", "add", 10)]
|
||||
|
||||
|
||||
class _TestTrigBuff(BaseBuff):
|
||||
key = 'ttb'
|
||||
name = 'ttb'
|
||||
flavor = 'triggerbuff'
|
||||
triggers = ['test1', 'test2']
|
||||
key = "ttb"
|
||||
name = "ttb"
|
||||
flavor = "triggerbuff"
|
||||
triggers = ["test1", "test2"]
|
||||
|
||||
def at_trigger(self, trigger: str, *args, **kwargs):
|
||||
if trigger == "test1":
|
||||
self.owner.db.triggertest1 = True
|
||||
if trigger == "test2":
|
||||
self.owner.db.triggertest2 = True
|
||||
|
||||
def on_trigger(self, trigger: str, *args, **kwargs):
|
||||
if trigger == 'test1': self.owner.db.triggertest1 = True
|
||||
if trigger == 'test2': self.owner.db.triggertest2 = True
|
||||
|
||||
class _TestConBuff(BaseBuff):
|
||||
key = 'tcb'
|
||||
name = 'tcb'
|
||||
flavor = 'condbuff'
|
||||
triggers = ['condtest']
|
||||
key = "tcb"
|
||||
name = "tcb"
|
||||
flavor = "condbuff"
|
||||
triggers = ["condtest"]
|
||||
|
||||
def conditional(self, *args, **kwargs):
|
||||
return self.owner.db.cond1
|
||||
|
||||
def on_trigger(self, trigger: str, attacker=None, defender=None, damage=0, *args, **kwargs):
|
||||
def at_trigger(self, trigger: str, attacker=None, defender=None, damage=0, *args, **kwargs):
|
||||
defender.db.att, defender.db.dmg = attacker, damage
|
||||
|
||||
|
||||
class _TestComplexBuff(BaseBuff):
|
||||
key = 'tcomb'
|
||||
name = 'complex'
|
||||
flavor = 'combuff'
|
||||
triggers = ['comtest', 'complextest']
|
||||
key = "tcomb"
|
||||
name = "complex"
|
||||
flavor = "combuff"
|
||||
triggers = ["comtest", "complextest"]
|
||||
|
||||
mods = [
|
||||
Mod('com1', 'add', 0, 10),
|
||||
Mod('com1', 'add', 15),
|
||||
Mod('com1', 'mult', 2.0),
|
||||
Mod('com2', 'add', 100)
|
||||
Mod("com1", "add", 0, 10),
|
||||
Mod("com1", "add", 15),
|
||||
Mod("com1", "mult", 2.0),
|
||||
Mod("com2", "add", 100),
|
||||
]
|
||||
|
||||
def conditional(self, cond=False, *args, **kwargs):
|
||||
return not cond
|
||||
|
||||
def on_trigger(self, trigger: str, *args, **kwargs):
|
||||
if trigger == 'comtest': self.owner.db.comtext = {'cond': True}
|
||||
else: self.owner.db.comtext = {}
|
||||
def at_trigger(self, trigger: str, *args, **kwargs):
|
||||
if trigger == "comtest":
|
||||
self.owner.db.comtext = {"cond": True}
|
||||
else:
|
||||
self.owner.db.comtext = {}
|
||||
|
||||
|
||||
class _TestTimeBuff(BaseBuff):
|
||||
key = 'ttib'
|
||||
name = 'ttib'
|
||||
flavor = 'timerbuff'
|
||||
key = "ttib"
|
||||
name = "ttib"
|
||||
flavor = "timerbuff"
|
||||
maxstacks = 1
|
||||
tickrate = 1
|
||||
duration = 5
|
||||
mods = [Mod('timetest', 'add', 665)]
|
||||
mods = [Mod("timetest", "add", 665)]
|
||||
|
||||
def on_tick(self, initial=True, *args, **kwargs):
|
||||
def at_tick(self, initial=True, *args, **kwargs):
|
||||
self.owner.db.ticktest = True
|
||||
|
||||
|
||||
class BuffableObject(DefaultObject):
|
||||
stat1 = BuffableProperty(10)
|
||||
|
||||
|
|
@ -95,181 +103,258 @@ class BuffableObject(DefaultObject):
|
|||
self.stat1, self.buffs
|
||||
return super().at_init()
|
||||
|
||||
|
||||
class TestBuffsAndHandler(EvenniaTest):
|
||||
"This tests a number of things about buffs."
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.obj1.handler = BuffHandler(self.obj1, 'buffs')
|
||||
|
||||
self.testobj = create.create_object(BuffableObject, key="testobj")
|
||||
|
||||
def tearDown(self):
|
||||
"""done after every test_* method below """
|
||||
"""done after every test_* method below"""
|
||||
self.testobj.buffs.clear()
|
||||
del self.testobj
|
||||
super().tearDown()
|
||||
|
||||
def test_addremove(self):
|
||||
'''tests adding and removing buffs'''
|
||||
"""tests adding and removing buffs"""
|
||||
# setup
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
# add
|
||||
handler.add(_TestModBuff)
|
||||
self.assertEqual( self.obj1.db.buffs['tmb']['ref'], _TestModBuff)
|
||||
handler.add(_TestModBuff, to_cache={"cachetest": True})
|
||||
handler.add(_TestTrigBuff)
|
||||
self.assertEqual(self.testobj.db.buffs["tmb"]["ref"], _TestModBuff)
|
||||
self.assertTrue(self.testobj.db.buffs["tmb"].get("cachetest"))
|
||||
self.assertFalse(self.testobj.db.buffs["ttb"].get("cachetest"))
|
||||
# remove
|
||||
handler.remove('tmb')
|
||||
self.assertEqual( self.obj1.db.buffs.get('tmb'), None)
|
||||
handler.remove("tmb")
|
||||
self.assertFalse(self.testobj.db.buffs.get("tmb"))
|
||||
# remove by type
|
||||
handler.add(_TestModBuff)
|
||||
handler.remove_by_type(_TestModBuff)
|
||||
self.assertEqual( self.obj1.db.buffs.get('tmb'), None)
|
||||
self.assertFalse(self.testobj.db.buffs.get("tmb"))
|
||||
# remove by buff instance
|
||||
handler.add(_TestModBuff)
|
||||
handler.all['tmb'].remove()
|
||||
self.assertEqual( self.obj1.db.buffs.get('tmb'), None)
|
||||
handler.all["tmb"].remove()
|
||||
self.assertFalse(self.testobj.db.buffs.get("tmb"))
|
||||
# remove by source
|
||||
handler.add(_TestModBuff)
|
||||
handler.remove_by_source(None)
|
||||
self.assertFalse(self.testobj.db.buffs.get("tmb"))
|
||||
# remove by cachevalue
|
||||
handler.add(_TestModBuff)
|
||||
handler.remove_by_cachevalue("failure", True)
|
||||
self.assertTrue(self.testobj.db.buffs.get("tmb"))
|
||||
# remove all
|
||||
handler.add(_TestModBuff)
|
||||
handler.clear()
|
||||
self.assertFalse(self.testobj.db.buffs.get("tmb"))
|
||||
|
||||
def test_getters(self):
|
||||
'''tests all built-in getters'''
|
||||
"""tests all built-in getters"""
|
||||
# setup
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
handler.add(_TestModBuff)
|
||||
handler.add(_TestTrigBuff)
|
||||
# normal getters
|
||||
self.assertEqual(isinstance(handler.tmb, _TestModBuff), True)
|
||||
self.assertEqual(isinstance(handler.get('tmb'),_TestModBuff), True)
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
handler.add(_TestModBuff, source=self.obj2)
|
||||
handler.add(_TestTrigBuff, to_cache={"ttbcache": True})
|
||||
# normal getter
|
||||
self.assertTrue(isinstance(handler.get("tmb"), _TestModBuff))
|
||||
# stat getters
|
||||
self.assertEqual(isinstance(handler.get_by_stat('stat1')['tmb'], _TestModBuff), True)
|
||||
self.assertEqual(handler.get_by_stat('nullstat'), {})
|
||||
self.assertTrue(isinstance(handler.get_by_stat("stat1")["tmb"], _TestModBuff))
|
||||
self.assertFalse(handler.get_by_stat("nullstat"))
|
||||
# trigger getters
|
||||
self.assertEqual('ttb' in handler.get_by_trigger('test1').keys(), True)
|
||||
self.assertEqual('ttb' in handler.get_by_trigger('nulltrig').keys(), False)
|
||||
self.assertTrue("ttb" in handler.get_by_trigger("test1").keys())
|
||||
self.assertFalse("ttb" in handler.get_by_trigger("nulltrig").keys())
|
||||
# type getters
|
||||
self.assertEqual('tmb' in handler.get_by_type(_TestModBuff), True)
|
||||
self.assertEqual('tmb' in handler.get_by_type(_EmptyBuff), False)
|
||||
|
||||
self.assertTrue("tmb" in handler.get_by_type(_TestModBuff))
|
||||
self.assertFalse("tmb" in handler.get_by_type(_EmptyBuff))
|
||||
# source getter
|
||||
self.assertTrue("tmb" in handler.get_by_source(self.obj2))
|
||||
self.assertFalse("ttb" in handler.get_by_source(self.obj2))
|
||||
# cachevalue getter
|
||||
self.assertFalse(handler.get("tmb").cache.get("ttbcache"))
|
||||
self.assertFalse(handler.get("ttb").cache.get("testfalse"))
|
||||
self.assertFalse("tmb" in handler.get_by_cachevalue("ttbcache"))
|
||||
self.assertTrue("ttb" in handler.get_by_cachevalue("ttbcache"))
|
||||
self.assertTrue("ttb" in handler.get_by_cachevalue("ttbcache", True))
|
||||
|
||||
def test_details(self):
|
||||
'''tests that buff details like name and flavor are correct'''
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
"""tests that buff details like name and flavor are correct"""
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
handler.add(_TestModBuff)
|
||||
handler.add(_TestTrigBuff)
|
||||
self.assertEqual(handler.tmb.flavor, 'modderbuff')
|
||||
self.assertEqual(handler.ttb.name, 'ttb')
|
||||
|
||||
self.assertEqual(handler.get("tmb").flavor, "modderbuff")
|
||||
self.assertEqual(handler.get("ttb").name, "ttb")
|
||||
|
||||
def test_modify(self):
|
||||
'''tests to ensure that values are modified correctly, and stack across mods'''
|
||||
"""tests to ensure that values are modified correctly, and stack across mods"""
|
||||
# setup
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
_stat1, _stat2 = 0, 10
|
||||
handler.add(_TestModBuff)
|
||||
# stat1 and 2 basic mods
|
||||
self.assertEqual(handler.check(_stat1, 'stat1'), 15)
|
||||
self.assertEqual(handler.check(_stat2, 'stat2'), 15)
|
||||
self.assertEqual(handler.check(_stat1, "stat1"), 15)
|
||||
self.assertEqual(handler.check(_stat2, "stat2"), 15)
|
||||
# checks can take any base value
|
||||
self.assertEqual(handler.check(_stat1, 'stat2'), 0)
|
||||
self.assertEqual(handler.check(_stat2, 'stat1'), 25)
|
||||
self.assertEqual(handler.check(_stat1, "stat2"), 0)
|
||||
self.assertEqual(handler.check(_stat2, "stat1"), 25)
|
||||
# change to base stat reflected in check
|
||||
_stat1 += 5
|
||||
self.assertEqual(handler.check(_stat1, 'stat1'), 20)
|
||||
self.assertEqual(handler.check(_stat1, "stat1"), 20)
|
||||
_stat2 += 10
|
||||
self.assertEqual(handler.check(_stat2, 'stat2'), 30)
|
||||
self.assertEqual(handler.check(_stat2, "stat2"), 30)
|
||||
# test stacking; single stack, multiple stack, max stacks
|
||||
handler.add(_TestModBuff)
|
||||
self.assertEqual(handler.check(_stat1, 'stat1'), 25)
|
||||
self.assertEqual(handler.check(_stat1, "stat1"), 25)
|
||||
handler.add(_TestModBuff, stacks=3)
|
||||
self.assertEqual(handler.check(_stat1, 'stat1'), 40)
|
||||
self.assertEqual(handler.check(_stat1, "stat1"), 40)
|
||||
handler.add(_TestModBuff, stacks=5)
|
||||
self.assertEqual(handler.check(_stat1, 'stat1'), 40)
|
||||
self.assertEqual(handler.check(_stat1, "stat1"), 40)
|
||||
# stat2 mod doesn't stack
|
||||
self.assertEqual(handler.check(_stat2, 'stat2'), 30)
|
||||
self.assertEqual(handler.check(_stat2, "stat2"), 30)
|
||||
# layers with second mod
|
||||
handler.add(_TestModBuff2)
|
||||
self.assertEqual(handler.check(_stat1, 'stat1'), 100)
|
||||
self.assertEqual(handler.check(_stat2, 'stat2'), 30)
|
||||
self.assertEqual(handler.check(_stat1, "stat1"), 100)
|
||||
self.assertEqual(handler.check(_stat2, "stat2"), 30)
|
||||
handler.remove_by_type(_TestModBuff)
|
||||
self.assertEqual(handler.check(_stat1, 'stat1'), 30)
|
||||
self.assertEqual(handler.check(_stat2, 'stat2'), 20)
|
||||
|
||||
self.assertEqual(handler.check(_stat1, "stat1"), 30)
|
||||
self.assertEqual(handler.check(_stat2, "stat2"), 20)
|
||||
|
||||
def test_trigger(self):
|
||||
'''tests to ensure triggers correctly fire'''
|
||||
"""tests to ensure triggers correctly fire"""
|
||||
# setup
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
handler.add(_TestTrigBuff)
|
||||
# trigger buffs
|
||||
handler.trigger('nulltest')
|
||||
self.assertEqual(self.obj1.db.triggertest1, None)
|
||||
self.assertEqual(self.obj1.db.triggertest2, None)
|
||||
handler.trigger('test1')
|
||||
self.assertEqual(self.obj1.db.triggertest1, True)
|
||||
self.assertEqual(self.obj1.db.triggertest2, None)
|
||||
handler.trigger('test2')
|
||||
self.assertEqual(self.obj1.db.triggertest1, True)
|
||||
self.assertEqual(self.obj1.db.triggertest2, True)
|
||||
handler.trigger("nulltest")
|
||||
self.assertFalse(self.testobj.db.triggertest1)
|
||||
self.assertFalse(self.testobj.db.triggertest2)
|
||||
handler.trigger("test1")
|
||||
self.assertTrue(self.testobj.db.triggertest1)
|
||||
self.assertFalse(self.testobj.db.triggertest2)
|
||||
handler.trigger("test2")
|
||||
self.assertTrue(self.testobj.db.triggertest1)
|
||||
self.assertTrue(self.testobj.db.triggertest2)
|
||||
|
||||
def test_context_conditional(self):
|
||||
'''tests to ensure context is passed to buffs, and also tests conditionals'''
|
||||
"""tests to ensure context is passed to buffs, and also tests conditionals"""
|
||||
# setup
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
handler.add(_TestConBuff)
|
||||
self.obj1.db.cond1, self.obj1.db.att, self.obj1.db.dmg = False, None, 0
|
||||
self.testobj.db.cond1, self.testobj.db.att, self.testobj.db.dmg = False, None, 0
|
||||
# context to pass, containing basic event data and a little extra to be ignored
|
||||
_testcontext = {'attacker':self.obj2, 'defender':self.obj1, 'damage':5, 'overflow':10}
|
||||
_testcontext = {
|
||||
"attacker": self.obj2,
|
||||
"defender": self.testobj,
|
||||
"damage": 5,
|
||||
"overflow": 10,
|
||||
}
|
||||
# test negative conditional
|
||||
self.assertEqual(handler.get_by_type(_TestConBuff)['tcb'].conditional(**_testcontext), False)
|
||||
handler.trigger('condtest', _testcontext)
|
||||
self.assertEqual(self.obj1.db.att, None)
|
||||
self.assertEqual(self.obj1.db.dmg, 0)
|
||||
self.assertEqual(
|
||||
handler.get_by_type(_TestConBuff)["tcb"].conditional(**_testcontext), False
|
||||
)
|
||||
handler.trigger("condtest", _testcontext)
|
||||
self.assertEqual(self.testobj.db.att, None)
|
||||
self.assertEqual(self.testobj.db.dmg, 0)
|
||||
# test positive conditional + context passing
|
||||
self.obj1.db.cond1 = True
|
||||
self.assertEqual(handler.get_by_type(_TestConBuff)['tcb'].conditional(**_testcontext), True)
|
||||
handler.trigger('condtest', _testcontext)
|
||||
self.assertEqual(self.obj1.db.att, self.obj2)
|
||||
self.assertEqual(self.obj1.db.dmg, 5)
|
||||
|
||||
self.testobj.db.cond1 = True
|
||||
self.assertEqual(handler.get_by_type(_TestConBuff)["tcb"].conditional(**_testcontext), True)
|
||||
handler.trigger("condtest", _testcontext)
|
||||
self.assertEqual(self.testobj.db.att, self.obj2)
|
||||
self.assertEqual(self.testobj.db.dmg, 5)
|
||||
|
||||
def test_complex(self):
|
||||
'''tests a complex mod (conditionals, multiple triggers/mods)'''
|
||||
"""tests a complex mod (conditionals, multiple triggers/mods)"""
|
||||
# setup
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
self.obj1.db.comone, self.obj1.db.comtwo, self.obj1.db.comtext = 10, 0, {}
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
self.testobj.db.comone, self.testobj.db.comtwo, self.testobj.db.comtext = 10, 0, {}
|
||||
handler.add(_TestComplexBuff)
|
||||
# stat checks work correctly and separately
|
||||
self.assertEqual(self.obj1.db.comtext, {})
|
||||
self.assertEqual(handler.check(self.obj1.db.comone, 'com1'), 105)
|
||||
self.assertEqual(handler.check(self.obj1.db.comtwo, 'com2'), 100)
|
||||
self.assertEqual(self.testobj.db.comtext, {})
|
||||
self.assertEqual(handler.check(self.testobj.db.comone, "com1"), 105)
|
||||
self.assertEqual(handler.check(self.testobj.db.comtwo, "com2"), 100)
|
||||
# stat checks don't happen if the conditional is true
|
||||
handler.trigger('comtest', self.obj1.db.comtext)
|
||||
self.assertEqual(self.obj1.db.comtext, {'cond': True})
|
||||
self.assertEqual(handler.get_by_type(_TestComplexBuff)['tcomb'].conditional(**self.obj1.db.comtext), False)
|
||||
self.assertEqual(handler.check(self.obj1.db.comone, 'com1', context=self.obj1.db.comtext), 10)
|
||||
self.assertEqual(handler.check(self.obj1.db.comtwo, 'com2', context=self.obj1.db.comtext), 0)
|
||||
handler.trigger('complextest', self.obj1.db.comtext)
|
||||
self.assertEqual(handler.check(self.obj1.db.comone, 'com1', context=self.obj1.db.comtext), 10)
|
||||
self.assertEqual(handler.check(self.obj1.db.comtwo, 'com2', context=self.obj1.db.comtext), 0)
|
||||
handler.trigger("comtest", self.testobj.db.comtext)
|
||||
self.assertEqual(self.testobj.db.comtext, {"cond": True})
|
||||
self.assertEqual(
|
||||
handler.get_by_type(_TestComplexBuff)["tcomb"].conditional(**self.testobj.db.comtext),
|
||||
False,
|
||||
)
|
||||
self.assertEqual(
|
||||
handler.check(self.testobj.db.comone, "com1", context=self.testobj.db.comtext), 10
|
||||
)
|
||||
self.assertEqual(
|
||||
handler.check(self.testobj.db.comtwo, "com2", context=self.testobj.db.comtext), 0
|
||||
)
|
||||
handler.trigger("complextest", self.testobj.db.comtext)
|
||||
self.assertEqual(
|
||||
handler.check(self.testobj.db.comone, "com1", context=self.testobj.db.comtext), 10
|
||||
)
|
||||
self.assertEqual(
|
||||
handler.check(self.testobj.db.comtwo, "com2", context=self.testobj.db.comtext), 0
|
||||
)
|
||||
# separate trigger follows different codepath
|
||||
self.obj1.db.comtext = {'cond': False}
|
||||
handler.trigger('complextest', self.obj1.db.comtext)
|
||||
self.assertEqual(self.obj1.db.comtext, {})
|
||||
self.assertEqual(handler.check(self.obj1.db.comone, 'com1', context=self.obj1.db.comtext), 105)
|
||||
self.assertEqual(handler.check(self.obj1.db.comtwo, 'com2', context=self.obj1.db.comtext), 100)
|
||||
self.testobj.db.comtext = {"cond": False}
|
||||
handler.trigger("complextest", self.testobj.db.comtext)
|
||||
self.assertEqual(self.testobj.db.comtext, {})
|
||||
self.assertEqual(
|
||||
handler.check(self.testobj.db.comone, "com1", context=self.testobj.db.comtext), 105
|
||||
)
|
||||
self.assertEqual(
|
||||
handler.check(self.testobj.db.comtwo, "com2", context=self.testobj.db.comtext), 100
|
||||
)
|
||||
|
||||
def test_timing(self):
|
||||
'''tests timing-related features, such as ticking and duration'''
|
||||
"""tests timing-related features, such as ticking and duration"""
|
||||
# setup
|
||||
handler: BuffHandler = self.obj1.handler
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
handler.add(_TestTimeBuff)
|
||||
self.obj1.db.timetest, self.obj1.db.ticktest = 1, False
|
||||
self.testobj.db.timetest, self.testobj.db.ticktest = 1, False
|
||||
# test duration and ticking
|
||||
self.assertTrue(handler.ttib.ticking)
|
||||
self.assertEqual(handler.get('ttib').duration, 5)
|
||||
handler.get('ttib').on_tick()
|
||||
self.assertTrue(self.obj1.db.ticktest)
|
||||
_instance = handler.get("ttib")
|
||||
self.assertTrue(_instance.ticking)
|
||||
self.assertEqual(_instance.duration, 5)
|
||||
_instance.at_tick()
|
||||
self.assertTrue(self.testobj.db.ticktest)
|
||||
# test duration modification and cleanup
|
||||
handler.modify_duration('ttib', 0, set=True)
|
||||
self.assertEqual(handler.get('ttib').duration, 0)
|
||||
handler.set_duration("ttib", 0)
|
||||
self.assertEqual(handler.get("ttib").duration, 0)
|
||||
handler.cleanup()
|
||||
self.assertFalse(handler.get('ttib'), None)
|
||||
|
||||
self.assertFalse(handler.get("ttib"), None)
|
||||
|
||||
def test_buffableproperty(self):
|
||||
'''tests buffable properties'''
|
||||
"""tests buffable properties"""
|
||||
# setup
|
||||
self.propobj = create.create_object(BuffableObject, key='testobj')
|
||||
self.propobj.buffs.add(_TestModBuff)
|
||||
self.assertEqual(self.propobj.stat1, 25)
|
||||
self.propobj.buffs.remove('tmb')
|
||||
self.assertEqual(self.propobj.stat1, 10)
|
||||
self.testobj.buffs.add(_TestModBuff)
|
||||
self.assertEqual(self.testobj.stat1, 25)
|
||||
self.testobj.buffs.remove("tmb")
|
||||
self.assertEqual(self.testobj.stat1, 10)
|
||||
|
||||
def test_stresstest(self):
|
||||
"""tests large amounts of buffs, and related removal methods"""
|
||||
# setup
|
||||
for x in range(1, 20):
|
||||
self.testobj.buffs.add(_TestModBuff, key="test" + str(x))
|
||||
self.testobj.buffs.add(_TestTrigBuff, key="trig" + str(x))
|
||||
self.assertEqual(self.testobj.stat1, 295)
|
||||
self.testobj.buffs.trigger("test1")
|
||||
self.testobj.buffs.remove_by_type(_TestModBuff)
|
||||
self.assertEqual(self.testobj.stat1, 10)
|
||||
self.testobj.buffs.clear()
|
||||
self.assertFalse(self.testobj.buffs.all)
|
||||
|
||||
def test_modgen(self):
|
||||
"""test generating mods on the fly"""
|
||||
# setup
|
||||
handler: BuffHandler = self.testobj.buffs
|
||||
self.testobj.db.gentest = 5
|
||||
self.assertEqual(self.testobj.db.gentest, 5)
|
||||
tc = {"modgen": ["gentest", "add", 5, 0]}
|
||||
handler.add(StatBuff, key="gentest", to_cache=tc)
|
||||
self.assertEqual(handler.check(self.testobj.db.gentest, "gentest"), 10)
|
||||
tc = {"modgen": ["gentest", "add", 10, 0]}
|
||||
handler.add(StatBuff, key="gentest", to_cache=tc)
|
||||
self.assertEqual(handler.check(self.testobj.db.gentest, "gentest"), 15)
|
||||
self.assertEqual(
|
||||
handler.get("gentest").flavor, "This buff affects the following stats: gentest"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue