i am also working on a RPG (on and off) and here is one of my test that tries to accomplice the same thing that your example is.
(this example use class inheritance)
#----------------------------------------------------
# license goes here
#----------------------------------------------------
#
# description goes here
# (c) whatever
#----------------------------------------------------
from random import *
import time, hashlib
import json
import base64
#----------------------------------------------------
# function description goes here
#----------------------------------------------------
def genhash(val="default"):
gen = hashlib.md5(val.encode('utf-8'))
return gen.hexdigest()
def genkey():
combined = str( time.time() ) + str( randrange(1,10000) )
generated_id = hashlib.md5(combined.encode('utf-8'))
return generated_id.hexdigest()
#----------------------------------------------------
# function description goes here
#----------------------------------------------------
def encode(key, clear):
enc = []
for i in range(len(clear)):
key_c = key[i % len(key)]
enc_c = chr((ord(clear[i]) + ord(key_c)) % 256)
enc.append(enc_c)
return base64.urlsafe_b64encode("".join(enc).encode()).decode()
def encrypt(data):
key = encode(genkey(),"iMKjw5LCp8KewpXChMKPV1TCpMOVwpLDmMOWW2vCg8K0UsKYwprCl1fCnVZqYmddwoTChsOYwpHDhsKeVm7")[:42]
return key+encode(key,data)
def decrypt(data):
key = data[:42]
return decode(key,data[42:])
#----------------------------------------------------
# function description goes here
#----------------------------------------------------
def decode(key, enc):
dec = []
enc = base64.urlsafe_b64decode(enc).decode()
for i in range(len(enc)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
#----------------------------------------------------
# class description goes here
#----------------------------------------------------
class basicContainer:
def __init__(self):
self.name = "container"
self.items = {}
super().__init__()
def __getitem__(self, key):
return getattr(self, key)
def __setitem__(self, key, value):
setattr(self, key, value)
def __len__(self):
return len(self.items)
def __iter__(self):
for key in self.items:
yield self.items[key]
return self
def add(self,item):
if hasattr(item,"key"):
self.items[item["key"]] = item
else:
self.items[genkey()] = item
def remove(self,item):
if hasattr(item,"key"):
if item["key"] in self.items:
outobj = self.items[item["key"]]
del self.items[item["key"]]
return outobj
else:
for key in self.items.keys():
if item == self.items[key]:
outobj = self.items[key]
del self.items[key]
return outobj
if hasattr(item,"name"):
print("ERROR :",item.name,"Not in",self.name)
else:
print("ERROR : Item Not in",self.name)
return None
#----------------------------------------------------
# class description goes here
#----------------------------------------------------
class Characterlist(basicContainer):
def __init__(self, **kw):
super().__init__()
for arg in kw:
if arg in vars(self):
self[arg] = kw[arg]
def gettingOlder(self,value = 1):
for character in self.items.values():
character.stats["age"] += value
#----------------------------------------------------
# class description goes here
#----------------------------------------------------
class AI:
def __init__(self):
self.state = None
super().__init__()
def AI_update(self):
return self.state
#----------------------------------------------------
# class description goes here
#----------------------------------------------------
class Loot:
def __init__(self):
self.loot = {} # {"Bone":{"stats":{"dmg":4,"attack":8}}}
super().__init__()
def genLootFromTable(self,count=2,table=None):
if table:
tmp = []
out = []
for item in table:
itm = table[item]
t = [ item ] * itm
tmp += t
for c in range(count):
out += [choice(tmp)]
return out
#----------------------------------------------------
# class description goes here
#----------------------------------------------------
class GameObject:
def __init__(self):
self.key = genkey()
self.name = "noname"
super().__init__()
def __getitem__(self, key):
return getattr(self, key)
def __setitem__(self, key, value):
setattr(self, key, value)
#----------------------------------------------------
# class description goes here
#----------------------------------------------------
class Stats:
def __init__(self,**kw):
self.stats ={}
super().__init__()
#----------------------------------------------------
# class description goes here
#----------------------------------------------------
class Critter(GameObject,Stats,AI,Loot):
default ={"age":1,
"race":"unknown",
"level":1,
"mana":10,
"health":10,
"armor":10,
"attack":10,
"dmg":10,
"strength":10,
"demo":None}
def __init__(self,**kw):
super().__init__()
self.stats.update(Critter.default)
for arg in kw:
if arg in vars(self):
if type(kw[arg]) == dict:
self[arg].update(kw[arg])
else:
self[arg] = kw[arg]
def update(self):
print( self.stats["race"], self.name, self.AI_update() )
#----------------------------------------------------
#
# Default Data for Monsters
#
#----------------------------------------------------
critters = {}
critters["Orc"] = {"loot":{"axe":{"stats":{"dmg":14,"attack":8}}},"stats":{"race":"Orc" , "health":50 , "attack":15 , "dmg":12 , "armor": 7 , "strength" :15 } }
critters["Kobold"] = {"stats":{"age":1 ,"race":"Kobold" , "health":30 , "attack":14 , "dmg":13 , "armor": 8 , "strength" : 8 } }
critters["Kitten"] = {"stats":{"age":1 ,"race":"Kitten" , "health":40 , "attack":18 , "dmg":15 , "armor":10 , "strength" :20 }, "state" : "sleeping"}
critters["Spider"] = {"stats":{"age":1 ,"race":"Spider" , "health":34 , "attack":12 , "dmg":15 , "armor":11 , "strength" :15 } }
namelist = ["bob","fred","carla","sofie","lars","boba fett","lisa","sonja"]
table = {"Bone":5,"Sword":10,"Rock":5,"Staff":15,"Gun":15,"Stick":15,"Cup":15,"Vase":3,"Pipe":15,"Pot":5}
defaultstats = {}
defaultstats["Bone"] = {"dmg":5,"durability":8,"speed":4}
defaultstats["Sword"] = {"dmg":15,"durability":8,"speed":4}
defaultstats["Rock"] = {"dmg":6,"durability":8,"speed":4}
defaultstats["Staff"] = {"dmg":7,"durability":8,"speed":4}
defaultstats["Gun"] = {"dmg":25,"durability":8,"speed":4}
defaultstats["Stick"] = {"dmg":5,"durability":8,"speed":4}
defaultstats["Cup"] = {"dmg":1,"durability":8,"speed":4}
defaultstats["Vase"] = {"dmg":2,"durability":8,"speed":4}
defaultstats["Pipe"] = {"dmg":16,"durability":8,"speed":4}
defaultstats["Pot"] = {"dmg":3,"durability":8,"speed":4}
#----------------------------------------------------
# start of execution
#----------------------------------------------------
critterlist = list(critters)
characterlist = Characterlist( name = "Characterlist" )
for name in namelist:
data = critters[choice(critterlist)]
data["name"] = name
characterlist.add(Critter(**data))
print("number of characters in",characterlist.name,len(characterlist))
print("-----------------------------------------------\n")
characterlist.gettingOlder(99)
for character in characterlist:
character.update()
lootlist = character.genLootFromTable(4,table)
for loot in lootlist:
tmp = {}
tmp[loot]={}
tmp[loot]["stats"] = defaultstats[loot]
character.loot.update(tmp)
print( character.genLootFromTable(4,table) )
clist = {}
print("-----------------------------------------------\n")
for character in characterlist:
clist[character["key"]] = vars(character)
print(vars(character))
print("-----------------------------------------------\n")
print(encode(genhash("pass"),json.dumps(clist)),"\n-----------------------------------------------")