Shuvit game master repo. http://shuvit.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

StatesWalker.py 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. import utils
  2. import bge
  3. import random
  4. from mathutils import Vector
  5. #====================================
  6. def mark_path(path, y):
  7. iter_ = 0
  8. for x in path:
  9. pm = bge.logic.getCurrentScene().addObject('path_marker', y.obj, 0)
  10. pm.worldPosition = path[iter_]
  11. iter_ += 1
  12. if iter_ == 1:
  13. pm.color = [0,1,0,.4]
  14. if iter_ == (len(path) ):
  15. pm.color = [1,0,0,.4]
  16. if iter_ == (len(path) +1):
  17. pm.color = [1,0,1,.4]
  18. y.path_display.append(pm)
  19. def clear_markers(self):
  20. for x in self.FSM.owner.path_display:
  21. try:
  22. x.endObject()
  23. except:
  24. pass
  25. def get_ground_ray(self):
  26. Axis = 2
  27. Distance = -10
  28. end = self.obj.worldPosition + (self.obj.worldOrientation.col[Axis]*Distance)
  29. start = self.obj.worldPosition.copy()
  30. ground_ray = self.obj.rayCast(end, start, 6,'', 1, 0)
  31. return ground_ray
  32. def set_height(self):
  33. ground_ray = get_ground_ray(self)
  34. target_height = 0.9
  35. hitpoint = ground_ray[1]
  36. try:
  37. dist = self.obj.getDistanceTo(hitpoint)
  38. if dist < target_height:
  39. self.obj.worldPosition.z += target_height - dist
  40. self.obj.linearVelocity.z = 0
  41. self.obj.linearVelocity.y *= .1
  42. except:
  43. pass
  44. def align_to_road(self):
  45. ground_ray = get_ground_ray(self)
  46. try:
  47. self.obj.alignAxisToVect(ground_ray[2], 2, .15)
  48. except:
  49. pass
  50. def find_new_parking(self):
  51. potentials = []
  52. for x in self.manager.idle_spots:
  53. if x.status == 'available':
  54. potentials.append(x)
  55. for x in potentials:
  56. min_dist = 45
  57. dist = self.obj.getDistanceTo(x.obj)
  58. if dist < min_dist:
  59. potentials.remove(x)
  60. if len(potentials) > 0:
  61. new_parking = random.choice(potentials)
  62. path2 = self.manager.navmesh2.queue_path(self.start_empty.obj.worldPosition, new_parking.obj.worldPosition, self)
  63. return new_parking, path2
  64. else:
  65. self.FSM.FSM.ToTransition('toEnterParallelPark')
  66. def get_lane_point(self):
  67. self.point = self.path[self.path_index]
  68. if self.point != self.last_lane_point:
  69. v = Vector([self.last_lane_point.x - self.point.x, self.last_lane_point.y - self.point.y, 0])
  70. tv = v.normalized()
  71. nv = Vector([-tv.y, tv.x, 0]) #rotate 90 degrees
  72. self.last_lane_point = self.lane_point
  73. self.lane_point = self.point + self.manager.lane_position * nv
  74. else:
  75. pass
  76. def goal_reached(self):
  77. print(self.target.type, 'type')
  78. if self.target.type == 'corner':
  79. print('this is a corner')
  80. self.FSM.FSM.ToTransition('toDance1')
  81. else:
  82. self.FSM.FSM.ToTransition('toEnterParallelPark')
  83. def update_point(self):
  84. if self.path_index >= (len(self.path)): #at the end
  85. goal_reached(self)
  86. #self.FSM.FSM.ToTransition('toEnterParallelPark')
  87. else: #do normal path
  88. check_dist = 2.5
  89. if self.path_index == len(self.path) - 1:
  90. check_dist = 1.0
  91. dist = self.obj.getDistanceTo(self.lane_point)
  92. self.point = self.path[self.path_index]
  93. if dist < check_dist:
  94. get_lane_point(self)
  95. if self.path_index > (len(self.path)):
  96. pass
  97. else:
  98. self.path_index += 1
  99. def align_to_point(self):
  100. v = self.obj.getVectTo(self.lane_point)[1]
  101. v.z = 0
  102. self.obj.alignAxisToVect(v, 0, .1)
  103. def delta_to_vect(self):
  104. v = self.obj.getVectTo(self.lane_point)[1]
  105. delta = self.last_lane_point - self.lane_point
  106. delta = delta.cross(v)
  107. delta_mult = -.1
  108. mult = 1.0
  109. deltamove = delta[2] * delta_mult
  110. #check if in front
  111. local = self.obj.worldOrientation.inverted() * (self.lane_point - self.obj.worldPosition)
  112. f = deltamove * 50
  113. if local < 0:
  114. f *= -1
  115. self.obj.applyForce([0, f, 0], True)
  116. def apply_gas(self):
  117. if self.obj.linearVelocity.x < self.speed_targ:
  118. self.obj.applyForce([self.speed_inc, 0, 0], True)
  119. def walk_anim(self):
  120. if self.obj.linearVelocity.x > .5:
  121. arm = self.obj.children['npc']
  122. #arm.playAction('g_walk2', 1,62, layer=1, play_mode=0, speed=.5)
  123. arm.playAction('npc_walk', 1,30, layer=1, play_mode=0, speed=.5, blendin=10)
  124. def starting_mod(self):
  125. path2 = self.path
  126. path2.append(self.target.obj.worldPosition)
  127. path2.append(self.target.obj.worldPosition)
  128. #====================================
  129. State = type("State", (object,), {})
  130. #====================================
  131. class State(object):
  132. def __init__(self, FSM):
  133. self.FSM = FSM
  134. self.timer = 0
  135. self.startTime = 0
  136. def Enter(self):
  137. self.timer = 0
  138. self.startTime = 0
  139. def Execute(self):
  140. print('Executing')
  141. def Exit(self):
  142. print('Exiting')
  143. #====================================
  144. class Example(State):
  145. def __init__(self,FSM):
  146. super(Example, self).__init__(FSM)
  147. def Enter(self):
  148. self.FSM.stateLife = 1
  149. #self.FSM.owner.obj.worldPosition = self.FSM.owner.start_empty.obj.worldPosition
  150. #print('physics resumed')
  151. super(Example, self).Enter()
  152. def Execute(self):
  153. self.FSM.stateLife += 1
  154. #print('doing example')
  155. def Exit(self):
  156. pass
  157. class ExitParallelPark(State):
  158. def __init__(self,FSM):
  159. super(ExitParallelPark, self).__init__(FSM)
  160. def Enter(self):
  161. self.FSM.stateLife = 1
  162. set_height(self.FSM.owner)
  163. #self.FSM.owner.obj.restorePhysics()
  164. #self.FSM.owner.obj.restoreDynamics()
  165. self.FSM.owner.obj.linearVelocity = [0,0,0]
  166. self.FSM.owner.path_index = 0
  167. try:
  168. self.FSM.owner.point = self.FSM.owner.path[self.FSM.owner.path_index]
  169. except:
  170. self.FSM.ToTransition('toEnterParallelPark')
  171. self.FSM.owner.target.status = 'targetted'
  172. self.FSM.owner.start_empty.status = 'available'
  173. if self.FSM.owner.start_empty.type == 'corner':
  174. self.FSM.owner.obj.children['npc'].stopAction(1)
  175. else:
  176. self.FSM.owner.obj.children['npc'].playAction('npc_sit', 90,1, layer=1, play_mode=0, speed=.5, blendin=10)
  177. starting_mod(self.FSM.owner)
  178. print('physics resumed')
  179. super(ExitParallelPark, self).Enter()
  180. def Execute(self):
  181. set_height(self.FSM.owner)
  182. self.FSM.stateLife += 1
  183. if self.FSM.stateLife > 30:
  184. v = self.FSM.owner.obj.getVectTo(self.FSM.owner.path[0])
  185. self.FSM.owner.obj.alignAxisToVect(v[1], 0, .01)
  186. self.FSM.owner.obj.alignAxisToVect([0,0,1], 2, 1)
  187. if self.FSM.stateLife > 220:
  188. self.FSM.ToTransition('toNavigateToTarget')
  189. def Exit(self):
  190. pass
  191. #====================================
  192. class EnterParallelPark(State):
  193. def __init__(self,FSM):
  194. super(EnterParallelPark, self).__init__(FSM)
  195. def Enter(self):
  196. self.FSM.stateLife = 1
  197. #self.FSM.owner.obj.worldPosition = self.FSM.owner.target.obj.worldPosition.copy()
  198. #self.FSM.owner.obj.worldOrientation = self.FSM.owner.target.obj.worldOrientation.copy()
  199. #self.FSM.owner.obj.applyMovement([0, 0, 0], True)
  200. self.FSM.owner.target.status = 'in_use'
  201. #self.FSM.owner.obj.worldPosition.z += .9
  202. self.FSM.owner.active = False
  203. self.FSM.owner.start_empty = self.FSM.owner.target
  204. self.FSM.owner.last_point = self.FSM.owner.target.obj.worldPosition.copy()
  205. self.FSM.owner.lane_point = self.FSM.owner.target.obj.worldPosition.copy()
  206. self.FSM.owner.last_lane_point = self.FSM.owner.target.obj.worldPosition.copy()
  207. self.FSM.owner.point = self.FSM.owner.target.obj.worldPosition.copy()
  208. self.FSM.owner.path_index = 0
  209. self.FSM.owner.path = None
  210. self.lerp_len = 90
  211. self.s_p = self.FSM.owner.obj.worldPosition.copy()
  212. self.s_o = self.FSM.owner.obj.worldOrientation.copy()
  213. self.FSM.owner.obj.linearVelocity = [0, 0, 0]
  214. self.e_p = self.FSM.owner.target.obj.worldPosition.copy()
  215. self.e_o = self.FSM.owner.target.obj.worldOrientation.copy()
  216. #self.FSM.owner.obj.children['npc'].playAction('npc_sit', 1,90, layer=1, play_mode=0, speed=.5, blendin=10)
  217. set_height(self.FSM.owner)
  218. super(EnterParallelPark, self).Enter()
  219. def Execute(self):
  220. self.FSM.stateLife += 1
  221. if self.FSM.stateLife > self.lerp_len:
  222. #pass
  223. self.FSM.owner.manager.walkers_active.remove(self.FSM.owner)
  224. if self.FSM.owner.start_empty.type == 'corner':
  225. self.FSM.owner.obj.children['npc'].stopAction(1)
  226. else:
  227. self.FSM.owner.obj.children['npc'].playAction('npc_sit', 1,90, layer=1, play_mode=0, speed=.5, blendin=10)
  228. else:
  229. l = self.s_p.lerp(self.e_p, (self.FSM.stateLife / self.lerp_len))
  230. o = self.s_o.lerp(self.e_o, (self.FSM.stateLife / self.lerp_len))
  231. #self.FSM.owner.obj.worldPosition.x = lerp()
  232. self.FSM.owner.obj.worldPosition.x = l.x
  233. self.FSM.owner.obj.worldPosition.y = l.y
  234. self.FSM.owner.obj.worldOrientation = o
  235. # v = self.FSM.owner.obj.getVectTo(self.FSM.owner.target.obj.worldPosition)[1]
  236. # v.z = 0
  237. # self.FSM.owner.obj.alignAxisToVect(v, 0, .15)
  238. # align_to_road(self.FSM.owner)
  239. # print('linvel', self.FSM.owner.obj.linearVelocity)
  240. # if self.FSM.owner.obj.linearVelocity.x < self.FSM.owner.speed_targ:
  241. # self.FSM.owner.obj.applyForce([self.FSM.owner.speed_inc, 0, 0], True)
  242. # if self.FSM.stateLife == 360:
  243. # #self.FSM.owner.manager.walkers_active.remove(self.FSM.owner)
  244. # pass
  245. # #self.FSM.owner.obj.suspendDynamics()
  246. # #self.FSM.owner.obj.suspendPhysics()
  247. def Exit(self):
  248. pass
  249. #====================================
  250. class NavigateToTarget(State):
  251. def __init__(self,FSM):
  252. super(NavigateToTarget, self).__init__(FSM)
  253. def Enter(self):
  254. self.FSM.stateLife = 1
  255. super(NavigateToTarget, self).Enter()
  256. def Execute(self):
  257. self.FSM.stateLife += 1
  258. update_point(self.FSM.owner)
  259. align_to_point(self.FSM.owner)
  260. align_to_road(self.FSM.owner)
  261. set_height(self.FSM.owner)
  262. delta_to_vect(self.FSM.owner)
  263. apply_gas(self.FSM.owner)
  264. walk_anim(self.FSM.owner)
  265. if self.FSM.stateLife > 30 * 180 * 2:
  266. self.FSM.ToTransition('toEnterParallelPark')
  267. def Exit(self):
  268. pass
  269. #====================================
  270. class Activate(State):
  271. def __init__(self,FSM):
  272. super(Activate, self).__init__(FSM)
  273. def Enter(self):
  274. self.FSM.stateLife = 1
  275. super(Activate, self).Enter()
  276. def find_target(self):
  277. pass
  278. def drive_to_point(self):
  279. pass
  280. def Execute(self):
  281. self.FSM.stateLife += 1
  282. def Exit(self):
  283. pass
  284. #====================================
  285. class RequestPath(State):
  286. def __init__(self,FSM):
  287. super(RequestPath, self).__init__(FSM)
  288. def Enter(self):
  289. self.FSM.stateLife = 1
  290. self.FSM.owner.target, self.FSM.owner.path = find_new_parking(self.FSM.owner)
  291. self.FSM.owner.path_index = 0
  292. super(RequestPath, self).Enter()
  293. def Execute(self):
  294. self.FSM.stateLife += 1
  295. def Exit(self):
  296. pass
  297. #====================================
  298. class HitBySkater(State):
  299. def __init__(self,FSM):
  300. super(HitBySkater, self).__init__(FSM)
  301. def Enter(self):
  302. self.FSM.stateLife = 1
  303. #self.FSM.owner.target, self.FSM.owner.path = find_new_parking(self.FSM.owner)
  304. #self.FSM.owner.path_index = 0
  305. self.FSM.owner.obj.children['npc'].playAction('npc_ran_into', 1,50, layer=1, play_mode=0, speed=.5, blendin=10)
  306. super(HitBySkater, self).Enter()
  307. def Execute(self):
  308. self.FSM.stateLife += 1
  309. #print('doing hit state')
  310. dict = bge.logic.globalDict
  311. v = self.FSM.owner.obj.getVectTo(dict['cc'])[1]
  312. v.z = 0
  313. self.FSM.owner.obj.alignAxisToVect(v, 0, .05)
  314. if self.FSM.stateLife == (50 * 2):
  315. self.FSM.owner.obj.children['npc'].playAction('npc_argue', 1,210, layer=1, play_mode=1, speed=.5, blendin=10)
  316. if self.FSM.stateLife > ((50 + 210) * 2):
  317. self.FSM.ToTransition('toEnterParallelPark')
  318. self.FSM.owner.obj.children['npc'].playAction('npc_walk', 1,30, layer=1, play_mode=1, speed=.5, blendin=10)
  319. def Exit(self):
  320. pass
  321. #====================================
  322. class WalkingHitBySkater(State):
  323. def __init__(self,FSM):
  324. super(WalkingHitBySkater, self).__init__(FSM)
  325. def Enter(self):
  326. self.FSM.stateLife = 1
  327. #self.FSM.owner.target, self.FSM.owner.path = find_new_parking(self.FSM.owner)
  328. #self.FSM.owner.path_index = 0
  329. self.FSM.owner.obj.children['npc'].playAction('npc_ran_into', 1,50, layer=1, play_mode=0, speed=.5, blendin=10)
  330. super(WalkingHitBySkater, self).Enter()
  331. def Execute(self):
  332. self.FSM.stateLife += 1
  333. #print('doing hit state')
  334. #self.FSM.owner.arm.playAction('npc_walk', 1,30, layer=1, play_mode=0, speed=.5)
  335. dict = bge.logic.globalDict
  336. v = self.FSM.owner.obj.getVectTo(dict['cc'])[1]
  337. v.z = 0
  338. self.FSM.owner.obj.alignAxisToVect(v, 0, .05)
  339. if self.FSM.stateLife == (50 * 2):
  340. self.FSM.owner.obj.children['npc'].playAction('npc_argue', 1,210, layer=1, play_mode=1, speed=.5, blendin=10)
  341. if self.FSM.stateLife > ((50 + 210) * 2):
  342. print('resume path')
  343. self.FSM.ToTransition('toNavigateToTarget')
  344. def Exit(self):
  345. pass
  346. #====================================
  347. class Dance1(State):
  348. def __init__(self,FSM):
  349. super(Dance1, self).__init__(FSM)
  350. def Enter(self):
  351. self.FSM.stateLife = 1
  352. #self.FSM.owner.target, self.FSM.owner.path = find_new_parking(self.FSM.owner)
  353. #self.FSM.owner.path_index = 0
  354. self.FSM.owner.obj.children['npc'].playAction('npc_dance_1', 10,110, layer=1, play_mode=1, speed=.5, blendin=10)
  355. super(Dance1, self).Enter()
  356. def Execute(self):
  357. self.FSM.stateLife += 1
  358. if self.FSM.stateLife > 1200:
  359. #self.FSM.owner.obj.worldPosition = self.FSM.owner.target.obj.worldPosition
  360. self.FSM.owner.start_empty = self.FSM.owner.target
  361. self.FSM.ToTransition('toGoToSleep')
  362. #self.FSM.ToTransition('toEnterParallelPark')
  363. def Exit(self):
  364. pass
  365. #====================================
  366. class GoToSleep(State):
  367. def __init__(self,FSM):
  368. super(GoToSleep, self).__init__(FSM)
  369. def Enter(self):
  370. self.FSM.stateLife = 1
  371. self.FSM.owner.obj.children['npc'].playAction('npc_dance_1', 10,110, layer=1, play_mode=1, speed=.5, blendin=10)
  372. super(GoToSleep, self).Enter()
  373. def Execute(self):
  374. self.FSM.stateLife += 1
  375. if self.FSM.owner.start_empty.type == 'corner':
  376. self.FSM.owner.obj.children['npc'].playAction('npc_dance_1', 1,1, layer=1, play_mode=1, speed=.5, blendin=20)
  377. if self.FSM.stateLife > 30:
  378. self.FSM.ToTransition('toRequestPath')
  379. if self.FSM.owner.start_empty.type == 'bench':
  380. pass
  381. def Exit(self):
  382. pass