import warnings from types import ClassType from pandac.PandaModules import * from zc.units.baseunit import BaseUnit, strict_callback, higher_callback, loose_callback from zc.ai.empty import EmptyAi from zc.ai.pathfinder import STATE_QUEUED, STATE_FOUND, STATE_NOT_FOUND from zc.shaders import shader_manipulator NODE_MOVE_SPEED = 0.5/16 # Unitstats VIEW_RADIUS = 320 class ZombieFemale(BaseUnit): """ Basic zombie, female variant basic unit controller without any ai to govern it will move and do stuff according to the orders depending on the issuer and type of callback (strict, higher, loose) Accepts events: on_unit_move_order_issued parameters: issuer, target, wherex, wherey on_unit_teleport_order_issued parameters: issuer, target on_unit_stop_order_issued parameters: issuer, target Sends events: on_unit_moved Sends: self on_unit_teleported Sends: self on_unit_stopped Sends: self """ Models = [ "models/mod.egg", ] Textures = [ "textures/text.png", ] Animations = { "idle":("idle01", "idle02"), "walking-slow":("walkslow01",), } def __init__(self, game, renderer, x, y, controller, Ai=None, name=None): BaseUnit.__init__(self, game, renderer, x, y, controller, Ai, name) # consts self.VIEW_RADIUS = VIEW_RADIUS # semaphors self._moving = False self._behaviour = "zombie" self._type = "zombie_female" self._actor = False while self._actor is False: self._model = self._game.game_values["static_random"].choice(ZombieFemale.Models) self._texture = self._game._map.f(self._game.game_values["static_random"].choice(ZombieFemale.Textures), "t") self._actor = None self._siz = 6.0 self._actor = shader_manipulator.new_instance_with_shaders(self, self._game._map.f, self._name, self._model, self._game.game_values["static_random"].choice(ZombieFemale.Animations["idle"]), self._texture, self._siz) self.update(all=True) # base behaviour event registration: self.regEv("on_unit_move_order_issued", self._move) self.regEv("on_unit_teleport_order_issued", self._teleport) @strict_callback def _move(self, event, issuer, target, wherex, wherey): if (wherex == self._posx) and (wherey == self._posy): return True if self._moving: self.unschedEv(self._move_unit) fpath = self._game._pathfinder.find_path(self._move_callback, (int(self._posx / 16), int(self._posy / 16)), (int(wherex / 16), int(wherey / 16)), True ) fpath._store_x = wherex fpath._store_y = wherey if fpath.get_state() != STATE_QUEUED: if fpath.get_state() == STATE_NOT_FOUND: self._stop(event, issuer, target) return True else: self._move_command(fpath) return True else: # TODO: Nastavit zombie na dumanie... return True def _move_callback(self, fpath, *args): if fpath.get_state() == STATE_FOUND: self._move_command(fpath) else: self._stop(None, None, None) def _move_command(self, fpath, wtype="walking-slow"): self.trigEv("on_unit_move", self) anim = self._game.game_values["game_random"].choice(ZombieFemale.Animations[wtype]) self.update_anim(anim) class CT(object): def __init__(inself): inself.x = None inself.y = None inself.w = None inself.targetx = fpath._store_x inself.targety = fpath._store_y inself.final = False current_target = CT() target_list = iter(fpath.get_path()) cnode = target_list.next() current_target.x, current_target.y = cnode.get_position() current_target.w = cnode.get_weight() # TODO: Pridat pametanie si weight... alebo nieco podobne... delay = 0 if current_target.w > 0: delay = NODE_MOVE_SPEED * ((1/256.0) * (256-current_target.w)) elif current_target.w < 0: delay = NODE_MOVE_SPEED / ((1/256.0) * (256-current_target.w)) else: delay = NODE_MOVE_SPEED self._angle = [None, None] self._moving = True # we set up semaphore self.schedEv(self._move_unit, d=delay, p_kwargs={"current_target":current_target, "target_list":target_list}) def _move_unit(self, dt, current_target, target_list): cposx = int(self._posx) cposy = int(self._posy) if current_target.final: if (cposx == current_target.targetx) and (cposy == current_target.targety): # we have arrived at final node! self._angle = [None, None] self._stop(None, self._name, None) # we clear semaphore self._moving = False return True modx, mody, orient = self._get_next_position(cposx, cposy, current_target.targetx, current_target.y) self._posx = modx self._posy = mody self._orient = orient self.update() return if (cposx == current_target.x*16) and (cposy == current_target.y*16): # we have arrived at the node self._ai.arrived_at_new_position() cnode = None try: cnode = target_list.next() # we set up new target coordinates except StopIteration: current_target.final = True return else: current_target.x, current_target.y = cnode.get_position() w = cnode.get_weight() if w != current_target.w: # TODO: Vylepsit, ale asi tazko, leda animacne! delay = 0 d = (w + current_target.w) / 2 if d > 0: delay = NODE_MOVE_SPEED * ((1/256.0) * (256-d)) elif d < 0: delay = NODE_MOVE_SPEED / ((1/256.0) * (256-d)) else: delay = NODE_MOVE_SPEED self._angle = [None, None] current_target.w = w self.unschedEv(self._move_unit) self.schedEv(self._move_unit, d=delay, p_kwargs={"current_target":current_target, "target_list":target_list}) self._angle = [None, None] modx, mody, orient = self._get_next_position(cposx, cposy, current_target.x*16, current_target.y*16) self._posx = modx self._posy = mody self._orient = orient self.update() @strict_callback def _teleport(self, event, issuer, target, wherex, wherey): self._actor.setPos(wherex, wherey, self._getheight(wherex, wherey)) self._posx = wherex self._posy = wherey self.trigEv("on_unit_teleport", self) self._ai.arrived_at_new_position() self._stop(event, issuer, target) @loose_callback def _stop(self, event, issuer, target): self.trigEv("on_unit_stop", self) anim = self._game.game_values["game_random"].choice(ZombieFemale.Animations["idle"]) self.update_anim(anim) self.unschedEv("all") # unscheduling any events pending # we clear semaphores self._moving = False