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, npcFSM): self.npcFSM = npcFSM 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,npcFSM): super(Target1, self).__init__(npcFSM) def Enter(self): #print('Preparing to walk towards target 1.') self.cont = bge.logic.getCurrentController() self.npcFSM.stateLife = 1 self.own = self.cont.owner self.target = 'larryTarget' self.npcArm = self.own.children['npc'] self.scene = bge.logic.getCurrentScene() nm = self.own['navMesh'] self.pt = nm.findPath(self.own.worldPosition, self.scene.objects[self.target].worldPosition) print('target1') super(Target1, self).Enter() def Execute(self): #print('Tracking target 1.', self.npcFSM.stateLife) self.npcFSM.stateLife += 1 duration = 50000 #print('path', self.pt) if len(self.pt) > 0: target = self.pt[0] vg = self.own.getVectTo(target) dist = vg[0] v = vg[1] self.own.alignAxisToVect(v, 0, .5) self.own.alignAxisToVect([0,0,1], 2, 1) #print(dist) if dist > 1.5: x = 10 max_vel = 1.5 if self.own.linearVelocity.x < max_vel: self.own.applyForce([x, 0, 5], True) else: self.pt.remove(self.pt[0]) else: print('goal reached') self.npcFSM.ToTransition('toTarget2') if self.npcFSM.stateLife > duration: num = randint(1,2) # if num == 1: # self.npcFSM.ToTransition('toTarget2') # elif num ==2: # self.npcFSM.ToTransition('toTarget2') # else: # self.npcFSM.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) pass class Target2(State): def __init__(self,npcFSM): super(Target2, self).__init__(npcFSM) def Enter(self): #print('Preparing to walk towards target 2.') self.cont = bge.logic.getCurrentController() self.npcFSM.stateLife = 1 self.own = self.cont.owner self.target = 'larryTarget.001' self.npcArm = self.own.children['npc'] self.scene = bge.logic.getCurrentScene() nm = self.own['navMesh'] self.pt = nm.findPath(self.own.worldPosition, self.scene.objects[self.target].worldPosition) print('target2') super(Target2, self).Enter() def Execute(self): #print('Tracking target 2.', self.npcFSM.stateLife) self.npcFSM.stateLife += 1 duration = 10000 if len(self.pt) > 0: target = self.pt[0] vg = self.own.getVectTo(target) dist = vg[0] v = vg[1] self.own.alignAxisToVect(v, 0, .5) self.own.alignAxisToVect([0,0,1], 2, 1) #print(dist) if dist > 1.5: x = 10 max_vel = 1.5 if self.own.linearVelocity.x < max_vel: self.own.applyForce([x, 0, 5], True) else: self.pt.remove(self.pt[0]) else: print('goal reached') self.npcFSM.ToTransition('toTarget3') if self.npcFSM.stateLife > duration: num = randint(1,3) # if num == 1: # self.npcFSM.ToTransition('toTarget3') # elif num ==2: # self.npcFSM.ToTransition('toTarget3') # else: # self.npcFSM.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) pass class Target3(State): def __init__(self,npcFSM): super(Target3, self).__init__(npcFSM) def Enter(self): #print('Preparing to walk towards target 3.') self.cont = bge.logic.getCurrentController() self.npcFSM.stateLife = 1 self.own = self.cont.owner self.target = 'larryTarget.002' self.npcArm = self.own.children['npc'] self.scene = bge.logic.getCurrentScene() nm = self.own['navMesh'] self.pt = nm.findPath(self.own.worldPosition, self.scene.objects[self.target].worldPosition) print('target3') super(Target3, self).Enter() def Execute(self): self.npcFSM.stateLife += 1 duration = 12000 if len(self.pt) > 0: target = self.pt[0] vg = self.own.getVectTo(target) dist = vg[0] v = vg[1] self.own.alignAxisToVect(v, 0, .5) self.own.alignAxisToVect([0,0,1], 2, 1) #print(dist) if dist > 1.5: x = 10 max_vel = 1.5 if self.own.linearVelocity.x < max_vel: self.own.applyForce([x, 0, 5], True) else: self.pt.remove(self.pt[0]) else: print('goal reached') self.npcFSM.ToTransition('toTarget1') if self.npcFSM.stateLife > duration: self.npcFSM.ToTransition('toTarget1') 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) def Exit(self): #print('Finished target 3') #self.cont.deactivate(self.actu) pass class Idle(State): def __init__(self,npcFSM): super(Idle, self).__init__(npcFSM) def Enter(self): #print('Starting to idle.') self.cont = bge.logic.getCurrentController() self.own = self.cont.owner self.npcArm = self.own.children['npc'] self.npcFSM.stateLife = 1 super(Idle, self).Enter() def Execute(self): #print('Idleing.', self.npcFSM.stateLife) self.npcFSM.stateLife += 1 duration = 300 if self.npcFSM.stateLife > duration: num = randint(1,4) #self.npcFSM.ToTransition('toImpatient') self.npcFSM.ToTransition('toTarget1') # if num == 1: # self.npcFSM.ToTransition('toTarget1') # elif num == 2: # self.npcFSM.ToTransition('toTarget2') # elif num == 3: # self.npcFSM.ToTransition('toTarget3') # elif num == 4 or num == 5 or num == 6: # self.npcFSM.ToTransition('toImpatient') # else: # self.npcFSM.ToTransition('toIdle') else: #pass #print(self.own.children) #print('idling') self.npcArm.playAction('g_idle', 1,201, layer=2, play_mode=0, speed=.5) def Exit(self): pass ##print('Waking up from idle.') class Startup(State): def __init__(self,npcFSM): super(Startup, self).__init__(npcFSM) def Enter(self): self.npcFSM.stateLife = 1 print('npc startup enter') super(Startup, self).Enter() def Execute(self): self.npcFSM.stateLife += 1 duration = 4 #print('executing', self.npcFSM.stateLife) if self.npcFSM.stateLife > duration: self.npcFSM.ToTransition('toIdle') def Exit(self): #pass print('Exiting npc startup.') class Impatient(State): def __init__(self,npcFSM): super(Impatient, self).__init__(npcFSM) def Enter(self): #print('Starting to idle.') self.npcFSM.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.npcFSM.stateLife) self.npcFSM.stateLife += 1 duration = 300 if self.npcFSM.stateLife > duration: self.npcFSM.ToTransition('toIdle') else: #pass self.npcArm.playAction('npcImpatient', 1,201, layer=2, play_mode=0, speed=.5) def Exit(self): pass #print('stopping bening impatient.') #=================================== class npcFSM(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.npcFSM = npcFSM(self) #cont = bge.logic.getCurrentController() #own = cont.owner #self.LightOn = own['state'] ##STATES self.npcFSM.AddState("Startup", Startup(self.npcFSM)) self.npcFSM.AddState("Idle", Idle(self.npcFSM)) self.npcFSM.AddState("Impatient", Impatient(self.npcFSM)) self.npcFSM.AddState('Target1', Target1(self.npcFSM)) self.npcFSM.AddState('Target3', Target3(self.npcFSM)) self.npcFSM.AddState('Target2', Target2(self.npcFSM)) #TRANSITIONS self.npcFSM.AddTransition('toStartup', Transition('Startup')) self.npcFSM.AddTransition('toIdle', Transition('Idle')) self.npcFSM.AddTransition('toImpatient', Transition('Impatient')) self.npcFSM.AddTransition('toTarget3', Transition('Target3')) self.npcFSM.AddTransition('toTarget1', Transition('Target1')) self.npcFSM.AddTransition('toTarget2', Transition('Target2')) if self.npcFSM.curState == None: self.npcFSM.SetState('Startup') #self.npcFSM.ToTransition('toIdle') #print('setting npc state to startup') def Execute(self): self.npcFSM.Execute() #print('executing machine') #==================================== 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' own['navMesh'] = None for x in scene.objects: if 'npcNavmesh' in x: own['navMesh'] = x #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.worldOrientation = to.worldOrientation #own.worldPosition.z += 50 r.Execute() #print(r.npcFSM.curState) own['frame'] += 1 yvel = own.linearVelocity.y yvel = yvel *.05 if own.linearVelocity.y > .01 or own.linearVelocity.y < -.01: own.applyRotation([0,0,yvel], True)