import bge from random import randint from time import clock #==================================== class Transition(object): def __init__(self, toState): self.toState = toState def Execute(self): #print('Transitioning ...', self.toState) pass #==================================== State = type("State", (object,), {}) class State(object): def __init__(self, FSM): self.FSM = FSM self.timer = 0 self.startTime = 0 def Enter(self): pass #print('entering') def Execute(self): pass #print('Executing') def Exit(self): pass #print('Exiting') class Target1(State): def __init__(self,FSM): super(Target1, self).__init__(FSM) def Enter(self): #print('Preparing to walk towards target 1.') self.cont = bge.logic.getCurrentController() self.FSM.stateLife = 1 self.own = self.cont.owner self.target = 'larryTarget' self.npcArm = self.own.children['npc'] self.scene = bge.logic.getCurrentScene() self.actu = self.cont.actuators['Steering'] if 'larryTarget' in self.scene.objects: self.actu.target = self.target self.actu.velocity = 1.5 self.actu.turnspeed = 100 self.actu.facingMode = True self.cont.activate(self.actu) super(Target1, self).Enter() def Execute(self): #print('Tracking target 1.', self.FSM.stateLife) self.FSM.stateLife += 1 duration = 1000 if self.FSM.stateLife > duration: num = randint(1,3) if num == 1: self.FSM.ToTransition('toTarget2') elif num ==2: self.FSM.ToTransition('toTarget3') else: self.FSM.ToTransition('toIdle') else: self.cont.activate(self.actu) self.npcArm.playAction('g_walk2', 1,62, layer=2, play_mode=0, speed=.5) def Exit(self): #print('Finished target 1') self.cont.deactivate(self.actu) class Target2(State): def __init__(self,FSM): super(Target2, self).__init__(FSM) def Enter(self): #print('Preparing to walk towards target 2.') self.cont = bge.logic.getCurrentController() self.FSM.stateLife = 1 self.own = self.cont.owner self.target = 'larryTarget.001' self.npcArm = self.own.children['npc'] self.scene = bge.logic.getCurrentScene() self.actu = self.cont.actuators['Steering'] if 'larryTarget.001' in self.scene.objects: self.actu.target = self.target self.actu.velocity = 1.5 self.actu.turnspeed = 100 self.actu.facingMode = True self.cont.activate(self.actu) super(Target2, self).Enter() def Execute(self): #print('Tracking target 2.', self.FSM.stateLife) self.FSM.stateLife += 1 duration = 1000 if self.FSM.stateLife > duration: num = randint(1,3) if num == 1: self.FSM.ToTransition('toTarget1') elif num ==2: self.FSM.ToTransition('toTarget3') else: self.FSM.ToTransition('toIdle') else: self.cont.activate(self.actu) self.npcArm.playAction('g_walk2', 1,62, layer=2, play_mode=0, speed=.5) def Exit(self): #print('Finished target 2') self.cont.deactivate(self.actu) class Target3(State): def __init__(self,FSM): super(Target3, self).__init__(FSM) def Enter(self): #print('Preparing to walk towards target 3.') self.cont = bge.logic.getCurrentController() self.FSM.stateLife = 1 self.own = self.cont.owner self.target = 'larryTarget.002' self.npcArm = self.own.children['npc'] self.scene = bge.logic.getCurrentScene() self.actu = self.cont.actuators['Steering'] if 'larryTarget.002' in self.scene.objects: self.actu.target = self.target self.actu.velocity = 1.5 self.actu.turnspeed = 100 self.actu.facingMode = True self.cont.activate(self.actu) super(Target3, self).Enter() def Execute(self): #print('Vacumming.', self.FSM.stateLife) self.FSM.stateLife += 1 duration = 1200 if self.FSM.stateLife > duration: if not (randint(1,3) % 2): self.FSM.ToTransition('toTarget1') else: self.FSM.ToTransition('toIdle') else: cont = bge.logic.getCurrentController() own = cont.owner npcArm = own.children['npc'] npcArm.playAction('g_walk2', 1,62, layer=2, play_mode=0, speed=.5) #npcArm.playAction('npcImpatient', 2,135, layer=2, play_mode=0, speed=.25) def Exit(self): #print('Finished target 3') self.cont.deactivate(self.actu) class Idle(State): def __init__(self,FSM): super(Idle, self).__init__(FSM) def Enter(self): #print('Starting to idle.') self.cont = bge.logic.getCurrentController() self.FSM.stateLife = 1 self.own = self.cont.owner self.npcArm = self.own.children['npc'] super(Idle, self).Enter() def Execute(self): #print('Idleing.', self.FSM.stateLife) self.FSM.stateLife += 1 duration = 600 if self.FSM.stateLife > duration: num = randint(1,4) if num == 1: self.FSM.ToTransition('toTarget1') elif num == 2: self.FSM.ToTransition('toTarget2') elif num == 3: self.FSM.ToTransition('toTarget3') elif num == 4 or num == 5 or num == 6: self.FSM.ToTransition('toImpatient') else: self.FSM.ToTransition('toIdle') else: #pass self.npcArm.playAction('g_idle', 1,201, layer=2, play_mode=0, speed=.5) def Exit(self): pass ##print('Waking up from idle.') class Impatient(State): def __init__(self,FSM): super(Impatient, self).__init__(FSM) def Enter(self): #print('Starting to idle.') self.FSM.stateLife = 1 self.cont = bge.logic.getCurrentController() self.own = self.cont.owner self.npcArm = self.own.children['npc'] super(Impatient, self).Enter() def Execute(self): ##print('being Impatient.', self.FSM.stateLife) self.FSM.stateLife += 1 duration = 600 if self.FSM.stateLife > duration: self.FSM.ToTransition('toIdle') else: self.npcArm.playAction('npcImpatient', 1,201, layer=2, play_mode=0, speed=.5) def Exit(self): pass #print('stopping bening impatient.') #=================================== class FSM(object): def __init__ (self, character): self.char = character self.states = {} self.transitions = {} self.curState = None self.prevState = None self.trans = None self.stateLife = 0 def AddTransition(self, transName, transition): self.transitions[transName] = transition def AddState(self, stateName, state): self.states[stateName] = state def SetState(self, stateName): self.prevState = self.curState self.curState = self.states[stateName] def ToTransition(self, toTrans): self.trans = self.transitions[toTrans] def Execute(self): if (self.trans): self.curState.Exit() self.trans.Execute() self.SetState(self.trans.toState) self.curState.Enter() self.trans = None self.curState.Execute() #==================================== Char = type("Char",(object,),{}) class Walker(Char): def __init__(self): self.FSM = FSM(self) #cont = bge.logic.getCurrentController() #own = cont.owner #self.LightOn = own['state'] ##STATES self.FSM.AddState("Idle", Idle(self.FSM)) self.FSM.AddState("Impatient", Impatient(self.FSM)) self.FSM.AddState('Target1', Target1(self.FSM)) self.FSM.AddState('Target3', Target3(self.FSM)) self.FSM.AddState('Target2', Target2(self.FSM)) #TRANSITIONS self.FSM.AddTransition('toIdle', Transition('Idle')) self.FSM.AddTransition('toImpatient', Transition('Impatient')) self.FSM.AddTransition('toTarget3', Transition('Target3')) self.FSM.AddTransition('toTarget1', Transition('Target1')) self.FSM.AddTransition('toTarget2', Transition('Target2')) if self.FSM.curState == None: self.FSM.SetState('Idle') #print('setting none') def Execute(self): self.FSM.Execute() #==================================== r = Walker() def main(cont): own = cont.owner scene = bge.logic.getCurrentScene() if 'inited' not in own: own['inited'] = True own['frame'] = 0 own['state'] = 'On' #print('initing') if own['frame'] == 40: own.worldPosition = [0,0,50] ln = own['cName'] + '_loader' if ln in scene.objects: to = scene.objects[ln] own.worldPosition = to.worldPosition own.worldPosition.z += 50 r.Execute() ##print(r.FSM.curState) own['frame'] += 1