rance/decos.py

55 lines
2.2 KiB
Python
Raw Permalink Normal View History

#DECO BEEEEEEEEEENCH
# We in it bois
import functools
import random as ra
import json as j
from os.path import dirname,join
with open(join(dirname(__file__),'data.json')) as d:
data=j.load(d)
classlist=data['classes']
# This is useful
class RanceException(Exception):
# This doesn't actually need any particular content. I just need the type to exist.
pass
def target(ranged=None,ally=False):
def owrap(func):
@functools.wraps(func)
def wrap(self,other,*args,**kwargs):
if not other: raise RanceException(f"You must target a unit with {func.__name__}")
if ranged==None:
if ally: rangeda=True # If it's an ally-targeting ability, assume it's ranged. It'd be really weird to have a melee-range ally-targeting ability.
else: rangeda='tranged' in classlist[self.cls]['attrs'] # We have to figure out if this unit is ranged or melee
else: rangeda=ranged # Assigning a local variable at any point in the function causes that name to refer to it at all points in the function.
# The line above this was throwing a "can't read unassigned variable" error because of this, until I just changed the name internally.
if not rangeda and not (3<=self.code<=8 and 3<=other.code<=8): raise RanceException(f"{self.name} can't reach {other.name} for melee {func.__name__}")
if not (self.code<6)^(other.code<6)^ally:
raise RanceException(f"Unit {self.name} can't {func.__name__} {'enemy' if ally else 'allied'} unit {other.name}")
return func(self,other,*args,**kwargs)
return wrap
return owrap
# This will return a function now.
def guardcheck(func):
@functools.wraps(func)
def wrap(self,other,*args,**kwargs):
strong=[]
guards=self.board.getunits(*list(range(other.code//3*3,other.code//3*3+3)),codes=True)
for i in guards:
if i.code==other.code or 'guard' not in i.status: continue
if ra.random()<i.status['guard']:
other=i
strong.append(f"{i.name} guards the attack")
break
else: strong.append(f"{i.name} fails to guard")
if 'guard' in other.status:
other.status['guard']-=0.4
if other.status['guard']<=0.001:
other.status.pop('guard')
out=', '.join(strong)+'. ' if strong else ''
a,b,c=func(self,other,*args,**kwargs)
return a,b,out+c
return wrap