cyphesis/rulesets/basic/mind/Goal.py
Erik Ogenvik 44402e0f73 Send last processed goals in report.
Also don't send data if there's nothing in the collections or maps.
2013-06-01 23:17:16 +02:00

131 lines
5.1 KiB
Python

#This file is distributed under the terms of the GNU General Public license.
#Copyright (C) 1999 Aloril (See the file COPYING for details).
from types import *
from atlas import *
from common import log
## \defgroup PythonGoals Goal Classes
## \brief Base class for all goals
## \ingroup PythonGoals
class Goal:
def __init__(self,desc="some goal",fulfilled=None,subgoals=[],
time=None, debug=0):
self.desc=desc
#mind sets these:
#self.str
#self.key
if fulfilled: self.fulfilled=fulfilled
else: self.fulfilled=lambda me:0 #false
self.subgoals=subgoals[:]
self.time=time
self.debug=debug
self.vars=[]
#keeps track of whether the goal is fulfilled or not
#this is mainly of use for inspection and diagnosis
self.is_fulfilled=0
#any subgoal/function/method can set this and
#it's checked at start of check_goal_rec
#and NPCMind.py fulfill_goals uses it too to remove goals from list
self.irrelevant=0
#Tracks the number of errors this goal (or any of its subgoals) has produced.
#This is used by NPC code to remove troublesome goals from the processing
self.errors=0
#If an error has occurred, the description of the last one is stored here.
#This is mainly of use for debugging.
self.lastError=""
def __repr__(self):
return self.info()
def info(self):
name=self.__class__.__name__
if name=="Goal":
return name+"("+`self.desc`+")"
var=""
for v in self.vars:
if var: var=var+","
var=var+`getattr(self,v)`
return name+"("+var+")"
def check_goal(self, me, time):
"executes goal, see top of file"
if self.debug:
log.thinking("GOAL desc: "+self.str)
res,debugInfo=self.check_goal_rec(me,time,0,"")
if len(debugInfo)!=0:
#Keep a copy of the debug info for the "report" method.
self.lastProcessedGoals=debugInfo
if res!=None:
info_ent=Entity(op=res,description=debugInfo)
return res+Operation("goal_info",info_ent)
def check_goal_rec(self, me, time, depth, debugInfo):
"""check (sub)goal recursively.
This is done by iterating over all subgoals, breaking if any subgoal returns an operation."""
res=None
if self.irrelevant: return res,debugInfo
#is it right time range?
if self.time and not time.is_now(self.time): return res,debugInfo
if self.debug:
log.thinking("\t"*depth+"GOAL: bef fulfilled: "+self.desc+" "+`self.fulfilled`)
if self.fulfilled(me):
self.is_fulfilled = 1
if self.debug:
log.thinking("\t"*depth+"GOAL: is fulfilled: "+self.desc+" "+`self.fulfilled`)
return res,debugInfo
else:
if self.debug:
log.thinking("\t"*depth+"GOAL: is not fulfilled: "+self.desc+" "+`self.fulfilled`)
self.is_fulfilled = 0
debugInfo=debugInfo+"."+self.info()
#Iterate over all subgoals, but break if any goal returns an operation
for sg in self.subgoals:
if type(sg)==FunctionType or type(sg)==MethodType:
if self.debug:
log.thinking("\t"*depth+"GOAL: bef function: "+`sg`+" "+`res`)
res=sg(me)
if self.debug:
log.thinking("\t"*depth+"GOAL: aft function: "+`sg`+" "+`res`)
debugInfo=debugInfo+"."+sg.__name__+"()"
if res!=None:
#If the function generated an op, stop iterating here and return
return res,debugInfo
else:
if self.debug:
log.thinking("\t"*depth+"GOAL: bef sg: "+sg.desc)
res,debugInfo=sg.check_goal_rec(me,time,depth+1,debugInfo)
if self.debug:
log.thinking("\t"*depth+"GOAL: aft sg: "+sg.desc+", Result: "+str(res))
#If the subgoal generated an op, stop iterating here and return
if res!=None:
return res,debugInfo
return res,debugInfo
def report(self):
"""provides extended information about the goal,
as well as all subgoals"""
name=self.__class__.__name__
map={}
map["name"]=name
map["description"]=self.desc
map["fulfilled"]=self.is_fulfilled
if hasattr(self, "lastProcessedGoals"):
map["lastProcessedGoals"] = self.lastProcessedGoals
if len(self.subgoals) > 0:
subgoals=[]
for sg in self.subgoals:
if type(sg)!=FunctionType and type(sg)!=MethodType:
subgoals.append(sg.report())
map["subgoals"]=subgoals
if len(self.vars) > 0:
variables={}
for v in self.vars:
variables[v]=str(getattr(self,v))
map["variables"]=variables
if self.errors > 0:
map["errors"]=self.errors
map["lastError"]=self.lastError
return map