- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior.
This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior.
What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the
Weapon
class and the dictionary. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipment at every
on_turn
call but it sounded like such a waste;The
_class
variable holds a character class (such as Cleric, Rogue, etc.), not a Python class.
What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the Weapon
class and the dictionary.
3. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipment at every on_turn
call but it sounded like such a waste;
4. The _class
variable holds a character class (such as Cleric, Rogue, etc.), not a Python class.
- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior.
What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the Weapon
class and the dictionary.
3. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipment at every on_turn
call but it sounded like such a waste;
4. The _class
variable holds a character class (such as Cleric, Rogue, etc.), not a Python class.
As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior.
What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the
Weapon
class and the dictionary.The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipment at every
on_turn
call but it sounded like such a waste;The
_class
variable holds a character class (such as Cleric, Rogue, etc.), not a Python class.
In aan RPG game I'm developing, after building a base Weapon
class, instead of having many subclasses of Weapon
, I want the weapons to be built upon dictionary parameters. Many of them will be simple static information (weight, value, etc.), but others will have conditionally definedconditionally defined parameters, with not only numeric/textual values: they may have to call external methodsexternal methods, such as spell-like effect, feat, skill, combat maneuvers, etc.).
The number of items (that will share most of this Weapon example's design, once I'm done with it), eventually, should reach the hundredshundreds (the PRD rules I'm adapting to this game already provide a few hundred "basic items"), and allow the player to build new ones, both at runtime based on existing models (crafting) and pre-runtime (modding).
One weapon, for example, should change its stats and associated functions (spell-like effects) when equipped according to the wielder's class.
One weapon, for example, should change its stats and associated functions (spell-like effects) when equipped according to the wielder's class. But many more different conditions should be needed/used as I add fancy magic weapons, armors and items.
Below is a piece of code showing kind of how it works so far (a simplified, working version of my logic). Currently itThis currently relies on a few setattr
and eval
calls to handle strings from the dictionary.
I would like to hear suggestions on preferable approachespreferable approaches, concerning performance, security, etc.. Can it be significantly improvedsignificantly improved somehow? Readability (always) matters, any pythonist's approach, perhaps?.
- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior. What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the
Weapon
class and the dictionary. - The
item.owner = self
doen't look too good, as cat said , but there are (many) cases where a component (item, ai, etc.) interact 'backwards' with its owner. The action "unholy area"This code does not reflect the actual main structure of the weapongame but tries to illustrate, in this specificthrough a working example, would affect every neighbor square of the "owner"an approach specifically on how could weapons (I don't update the item position after someone picks it up, only when the item is dropped);and other passive effects would do the same (heal the owner every turn, etc.items). I be created based on dictionaries in a way that this data could pass the ownerprovide conditional verifications and actions to its equipments at everyon_turn
call but it sounded like such a waste; - The
_class
variable holds a character class (such as cleric, rogue, etc.), notinteract dynamically with a python classhuge combinations of race x attributes x features x classes behavior.
What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the Weapon
class and the dictionary.
3. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipment at every on_turn
call but it sounded like such a waste;
4. The _class
variable holds a character class (such as Cleric, Rogue, etc.), not a Python class.
In a RPG game I'm developing, after building a base Weapon
class, instead of having many subclasses of Weapon
, I want the weapons to be built upon dictionary parameters. Many of them will be simple static information (weight, value, etc.), but others will have conditionally defined parameters, with not only numeric/textual values: they may have to call external methods, such as spell-like effect, feat, skill, combat maneuvers, etc.).
The number of items (that will share most of this Weapon example's design, once I'm done with it), eventually, should reach the hundreds (the PRD rules I'm adapting to this game already provide a few hundred "basic items"), and allow the player to build new ones, both at runtime based on existing models (crafting) and pre-runtime (modding).
One weapon, for example, should change its stats and associated functions (spell-like effects) when equipped according to the wielder's class.
But many more different conditions should be needed/used as I add fancy magic weapons, armors and items.
Below is a piece of code showing kind of how it works so far (a simplified, working version of my logic). Currently it relies on a few setattr
and eval
calls to handle strings from the dictionary.
I would like to hear suggestions on preferable approaches, concerning performance, security, etc.. Can it be significantly improved somehow? Readability (always) matters, any pythonist's approach, perhaps?
- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior. What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the
Weapon
class and the dictionary. - The
item.owner = self
doen't look too good, as cat said , but there are (many) cases where a component (item, ai, etc.) interact 'backwards' with its owner. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipments at everyon_turn
call but it sounded like such a waste; - The
_class
variable holds a character class (such as cleric, rogue, etc.), not a python class.
In an RPG game I'm developing, after building a base Weapon
class, instead of having many subclasses of Weapon
, I want the weapons to be built upon dictionary parameters. Many of them will be simple static information (weight, value, etc.), but others will have conditionally defined parameters, with not only numeric/textual values: they may have to call external methods, such as spell-like effect, feat, skill, combat maneuvers, etc.).
The number of items (that will share most of this Weapon example's design, once I'm done with it), eventually, should reach the hundreds (the PRD rules I'm adapting to this game already provide a few hundred "basic items"), and allow the player to build new ones, both at runtime based on existing models (crafting) and pre-runtime (modding).
One weapon, for example, should change its stats and associated functions (spell-like effects) when equipped according to the wielder's class. But many more different conditions should be needed/used as I add fancy magic weapons, armors and items.
This currently relies on a few setattr
and eval
calls to handle strings from the dictionary. I would like to hear suggestions on preferable approaches, concerning performance, security, etc.. Can it be significantly improved somehow? Readability (always) matters.
- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior.
What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the Weapon
class and the dictionary.
3. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipment at every on_turn
call but it sounded like such a waste;
4. The _class
variable holds a character class (such as Cleric, Rogue, etc.), not a Python class.
The code belowBelow is the result of some editing based on the suggestions/answers received, a piece of code showing kind of how it works so far (a simplified, working version of my logic). Currently it relies on a specific part offew setattr
and eval
calls to handle strings from the game logicdictionary.
I would like to hear suggestions on Suggestions concerning the dictionary handling and the conditional setting of the Weapon
class parameters could still be usedpreferable approaches, concerning performance, security, etc.. Can it be significantly improved somehow? Readability (always) matters, any pythonist's approach, perhaps?
"""A# A design test for dynamic class building."""
# > attributes and conditional logic are readed from a dictionary.
# This dictionary will actually reside in another file, maybe a json or
# gzipped pickled json...
# Attributes and conditional logic relative to the items are readed from it.
WEAPONS = {
"bastard's sting": {
"equipped": False,
"magic": 2,
"on_turn_actions": [],
"on_hit_actions": [],
"on_equip": [
{
"type": "check",
"condition": {
'object': 'owner',(
'attribute': 'char_class'"self.owner.is_of_class",
'value': "antipaladin"["antipaladin"]
}),
True: [
{
"type": "action",
"action": "add_to""self.add_on_hit",
"args": {
"category": "on_hit",
"actions": ["unholy"]
}
},
{
"type": "action",
"action": "add_to""self.add_on_turn",
"args": {
"category": "on_turn",
"actions": ["unholy aurea"]
}
},
{
"type": "action",
"action": "set_attribute""self.set_attribute",
"args": {
"field": "magic"["magic", "value": 5
}5]
}
],
False: [
{
"type": "action",
"action": "set_attribute""self.set_attribute",
"args": {
"field": "magic"["magic", "value": 2
}2]
}
]
}
],
"on_unequip": [
{
"type": "action",
"action": "remove_from""self.rem_on_hit",
"args": {
"category": "on_hit",
"actions": ["unholy"]
},
},
{
"type": "action",
"action": "remove_from""self.rem_on_turn",
"args": {
"category": "on_turn",
"actions": ["unholy aurea"]
},["unholy_aurea"]
},
{
"type": "action",
"action": "set_attribute""self.set_attribute",
"args": ["magic"["self.magic", 2]
}
]
}
}
class Player:
"""Represents the player character."""
inventory = []
def __init__(self, char_class_class):
"""For this example, we just store the class on the instance."""
self.char_class_class = char_class_class
def pick_up(self, item):
"""Pick an object, put in inventory, set its owner."""
self.inventory.append(item)
item.owner = self
def is_of_class(self, _class):
"""Checks for the Character _class, not a python `class`"""
return self._class == _class
class Weapon:
"""An type of item that can be equipped/used to attack."""
equipped = False
action_lists = {
"on_hit": "on_hit_actions",
"on_turn": "on_turn_actions",
}
def __init__(self, template):
"""Set the parameters based on a template."""
self.__dict__.update(WEAPONS[template])
def toggle_equipequip(self):
"""Set item status and call its on equip/unequip functions."""
if self.equipped:
= True
for action in self.equipped = Falseon_equip:
actionsif =action['type'] self.on_unequip== "check":
else: self.check(action)
self.equippedelif =action['type'] True== "action":
actions = self.on_equipaction(action)
def unequip(self):
"""Unset item dynamic status, call its on unequip functions."""
self.equipped = False
for action in actionsself.on_unequip:
if action['type'] == "check":
self.check(action)
elif action['type'] == "action":
self.action(action)
def check(self, dic):
"""Check a condition and call an action according to it."""
obj = getattr(self, dic['condition']['object'])
compared_attcheck_act = getattreval(obj, dic['condition']['attribute']dic['condition'][0])
valueargs = dic['condition']['value']dic['condition'][1]
result = compared_att == valuecheck_act(*args)
self.action(*dic[result])
def action(self, *dicts):
"""Perform action with args, both specified on dicts."""
for dic in dicts:
act = getattreval(self, dic['action'])
args = dic['args']
if isinstance(args, list):
act(*args)
elif isinstance(args, dict):
act(**args)
def set_attribute(self, field, value):
"""Set the specified field with the given value."""
setattr(self, field, valuedic['args'])
def add_toset_attribute(self, category, actionsargs):
"""Add one or more actions toname, thevalue category's= list."""args
action_list = getattrsetattr(self, self.action_lists[category]name, value)
def add_on_hit(self, actions):
for action in actions:
if action not in action_listself.on_hit_actions:
action_listself.on_hit_actions.append(action)
def remove_fromadd_on_turn(self, category, actions):
"""Remove onefor oraction morein actions:
from the category's list if action not in self."""on_turn_actions:
action_list = self.action_lists[category]on_turn_actions.append(action)
def rem_on_hit(self, actions):
for action in actions:
if action in action_listtry:
action_listself.on_hit_actions.remove(action)
except ValueError:
# We never had that but unequip tries to clean it anyway.
pass
def rem_on_turn(self, actions):
for action in actions:
try:
self.on_turn_actions.remove(action)
except ValueError:
pass
defif test()__name__ == '__main__':
"""A simple"""Let's test. it!"""
Item features should be printed differently for each player.
"""
weapon = Weapon("bastard's sting")
player1 = Player("paladin")
player1.pick_up(weapon)
weapon.toggle_equipequip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
weapon.toggle_equipunequip()
player2 = Player("antipaladin")
player2.pick_up(weapon)
weapon.toggle_equipequip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
if __name__ == '__main__':
test()
- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) could be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior. What is a weapon here is actually a component of a game object in the main code, and so areis the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the
Weapon
class and the dictionary. - The
item.owner = self
doen't look too good, as cat said, but there are (many) cases where a component (item, ai, etc.) interact 'backwards' with its owner. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipments at everyon_turn
call but it sounded like such a wastewaste; - The
_class
variable holds a character class (such as cleric, rogue, etc.), not a python class.
Edited to reflect most of cat's suggestions / accepted answer.
The code below is the result of some editing based on the suggestions/answers received, a simplified, working version of a specific part of the game logic.
Suggestions concerning the dictionary handling and the conditional setting of the Weapon
class parameters could still be used.
"""A design test for dynamic class building."""
# This dictionary will actually reside in another file, maybe a json or
# gzipped pickled json...
# Attributes and conditional logic relative to the items are readed from it.
WEAPONS = {
"bastard's sting": {
"magic": 2,
"on_turn_actions": [],
"on_hit_actions": [],
"on_equip": [
{
"type": "check",
"condition": {
'object': 'owner',
'attribute': 'char_class',
'value': "antipaladin"
},
True: [
{
"type": "action",
"action": "add_to",
"args": {
"category": "on_hit",
"actions": ["unholy"]
}
},
{
"type": "action",
"action": "add_to",
"args": {
"category": "on_turn",
"actions": ["unholy aurea"]
}
},
{
"type": "action",
"action": "set_attribute",
"args": {
"field": "magic", "value": 5
}
}
],
False: [
{
"type": "action",
"action": "set_attribute",
"args": {
"field": "magic", "value": 2
}
}
]
}
],
"on_unequip": [
{
"type": "action",
"action": "remove_from",
"args": {
"category": "on_hit",
"actions": ["unholy"]
},
},
{
"type": "action",
"action": "remove_from",
"args": {
"category": "on_turn",
"actions": ["unholy aurea"]
},
},
{
"type": "action",
"action": "set_attribute",
"args": ["magic", 2]
}
]
}
}
class Player:
"""Represents the player character."""
inventory = []
def __init__(self, char_class):
"""For this example, we just store the class on the instance."""
self.char_class = char_class
def pick_up(self, item):
"""Pick an object, put in inventory, set its owner."""
self.inventory.append(item)
item.owner = self
class Weapon:
"""An type of item that can be equipped/used to attack."""
equipped = False
action_lists = {
"on_hit": "on_hit_actions",
"on_turn": "on_turn_actions",
}
def __init__(self, template):
"""Set the parameters based on a template."""
self.__dict__.update(WEAPONS[template])
def toggle_equip(self):
"""Set item status and call its equip/unequip functions."""
if self.equipped:
self.equipped = False
actions = self.on_unequip
else:
self.equipped = True
actions = self.on_equip
for action in actions:
if action['type'] == "check":
self.check(action)
elif action['type'] == "action":
self.action(action)
def check(self, dic):
"""Check a condition and call an action according to it."""
obj = getattr(self, dic['condition']['object'])
compared_att = getattr(obj, dic['condition']['attribute'])
value = dic['condition']['value']
result = compared_att == value
self.action(*dic[result])
def action(self, *dicts):
"""Perform action with args, both specified on dicts."""
for dic in dicts:
act = getattr(self, dic['action'])
args = dic['args']
if isinstance(args, list):
act(*args)
elif isinstance(args, dict):
act(**args)
def set_attribute(self, field, value):
"""Set the specified field with the given value."""
setattr(self, field, value)
def add_to(self, category, actions):
"""Add one or more actions to the category's list."""
action_list = getattr(self, self.action_lists[category])
for action in actions:
if action not in action_list:
action_list.append(action)
def remove_from(self, category, actions):
"""Remove one or more actions from the category's list."""
action_list = self.action_lists[category]
for action in actions:
if action in action_list:
action_list.remove(action)
def test():
"""A simple test.
Item features should be printed differently for each player.
"""
weapon = Weapon("bastard's sting")
player1 = Player("paladin")
player1.pick_up(weapon)
weapon.toggle_equip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
weapon.toggle_equip()
player2 = Player("antipaladin")
player2.pick_up(weapon)
weapon.toggle_equip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
if __name__ == '__main__':
test()
- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how weapons (and other items) could be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior. What is a weapon here is actually a component of a game object in the main code, and so are the player and other creatures.
- The
item.owner = self
doen't look too good, as cat said, but there are (many) cases where a component (item, ai, etc.) interact 'backwards' with its owner. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipments at everyon_turn
call but it sounded like such a waste.
Edited to reflect most of cat's suggestions / accepted answer.
Below is a piece of code showing kind of how it works so far (a simplified, working version of my logic). Currently it relies on a few setattr
and eval
calls to handle strings from the dictionary.
I would like to hear suggestions on preferable approaches, concerning performance, security, etc.. Can it be significantly improved somehow? Readability (always) matters, any pythonist's approach, perhaps?
# A design test for dynamic class building.
# > attributes and conditional logic are readed from a dictionary.
# This dictionary will actually reside in another file, maybe a json or
# gzipped pickled json...
WEAPONS = {
"bastard's sting": {
"equipped": False,
"magic": 2,
"on_turn_actions": [],
"on_hit_actions": [],
"on_equip": [
{
"type": "check",
"condition": (
"self.owner.is_of_class",
["antipaladin"]
),
True: [
{
"type": "action",
"action": "self.add_on_hit",
"args": ["unholy"]
},
{
"type": "action",
"action": "self.add_on_turn",
"args": ["unholy aurea"]
},
{
"type": "action",
"action": "self.set_attribute",
"args": ["magic", 5]
}
],
False: [
{
"type": "action",
"action": "self.set_attribute",
"args": ["magic", 2]
}
]
}
],
"on_unequip": [
{
"type": "action",
"action": "self.rem_on_hit",
"args": ["unholy"]
},
{
"type": "action",
"action": "self.rem_on_turn",
"args": ["unholy_aurea"]
},
{
"type": "action",
"action": "self.set_attribute",
"args": ["self.magic", 2]
}
]
}
}
class Player:
inventory = []
def __init__(self, _class):
self._class = _class
def pick_up(self, item):
"""Pick an object, put in inventory, set its owner."""
self.inventory.append(item)
item.owner = self
def is_of_class(self, _class):
"""Checks for the Character _class, not a python `class`"""
return self._class == _class
class Weapon:
"""An type of item that can be equipped/used to attack."""
def __init__(self, template):
"""Set the parameters based on a template."""
self.__dict__.update(WEAPONS[template])
def equip(self):
"""Set item status and call its on equip functions."""
self.equipped = True
for action in self.on_equip:
if action['type'] == "check":
self.check(action)
elif action['type'] == "action":
self.action(action)
def unequip(self):
"""Unset item dynamic status, call its on unequip functions."""
self.equipped = False
for action in self.on_unequip:
if action['type'] == "check":
self.check(action)
elif action['type'] == "action":
self.action(action)
def check(self, dic):
"""Check a condition and call an action according to it."""
check_act = eval(dic['condition'][0])
args = dic['condition'][1]
result = check_act(*args)
self.action(*dic[result])
def action(self, *dicts):
"""Perform action with args, both specified on dicts."""
for dic in dicts:
act = eval(dic['action'])
act(dic['args'])
def set_attribute(self, args):
name, value = args
setattr(self, name, value)
def add_on_hit(self, actions):
for action in actions:
if action not in self.on_hit_actions:
self.on_hit_actions.append(action)
def add_on_turn(self, actions):
for action in actions:
if action not in self.on_turn_actions:
self.on_turn_actions.append(action)
def rem_on_hit(self, actions):
for action in actions:
try:
self.on_hit_actions.remove(action)
except ValueError:
# We never had that but unequip tries to clean it anyway.
pass
def rem_on_turn(self, actions):
for action in actions:
try:
self.on_turn_actions.remove(action)
except ValueError:
pass
if __name__ == '__main__':
"""Let's test it!"""
weapon = Weapon("bastard's sting")
player1 = Player("paladin")
player1.pick_up(weapon)
weapon.equip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
weapon.unequip()
player2 = Player("antipaladin")
player2.pick_up(weapon)
weapon.equip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
- As the size of the dictionary grows I intend to keep use a bzipped and pickled version of it, created once and updated in case of changes to the JSON/dictionary.
- This code does not reflect the actual main structure of the game but tries to illustrate, through a working example, an approach specifically on how could weapons (and other items) be created based on dictionaries in a way that this data could provide conditional verifications and actions to interact dynamically with a huge combinations of race x attributes x features x classes behavior. What is a weapon here is actually a component of a game object in the main code, and so is the player and other creatures. With that said, any specific comment on the main structure is still appreciated, but the main focus should be in the interaction between the
Weapon
class and the dictionary. - The
item.owner = self
doen't look too good, as cat said, but there are (many) cases where a component (item, ai, etc.) interact 'backwards' with its owner. The action "unholy area" of the weapon, in this specific example, would affect every neighbor square of the "owner" (I don't update the item position after someone picks it up, only when the item is dropped); other passive effects would do the same (heal the owner every turn, etc.). I could pass the owner to its equipments at everyon_turn
call but it sounded like such a waste; - The
_class
variable holds a character class (such as cleric, rogue, etc.), not a python class.
- 178
- 1
- 10
- 178
- 1
- 10