import functools import math import warnings from pandac.PandaModules import * from direct.task import TaskManagerGlobal from types import ClassType from zc.logic.logicnode import LogicNode from zc.shaders import shader_manipulator from zc.ai.empty import EmptyAi def strict_callback(callback): @functools.wraps(callback) def wrapper(self, event, issuer, target, *args, **kwargs): if (issuer != "logic") and (issuer != self._name): return if (target != self._name): return callback(self, event, issuer, target, *args, **kwargs) return wrapper def higher_callback(callback): @functools.wraps(callback) def wrapper(self, event, issuer, target, *args, **kwargs): if (issuer != "logic"): return if (target != self._name): return callback(self, event, issuer, target, *args, **kwargs) return wrapper def loose_callback(callback): # this one is just for the sake of having decorator @functools.wraps(callback) def wrapper(self, event, target, *args, **kwargs): if (target != self._name): return callback(self, event, target, *args, **kwargs) return wrapper class BaseUnit(LogicNode): def __init__(self, game, renderer, x, y, controller, Ai=None, name=None): LogicNode.__init__(self) self._game = game self._panda = renderer self._controller = controller self._name = self._generate_name(name) self._posx = x self._posy = y self._orient = 0 self._siz = 0 self.__taskname = "t" + self._name self._game.game_values["used_names"].append(self._name) # semaphores self._moving = False self._angle = [None, None] if Ai is None: self._ai = EmptyAi(self) else: self._ai = Ai(self) def _getheight(self, x, y): return self._game._map.get_c_height(x, y) self._actor = shader_manipulator.new_instance(self._game._map.f, self._name, self._model, self.__save_model) def update(self, **what): warnings.warn("No need for this when shaders are working!", DeprecationWarning) if len(what) > 0: if "all" in what: self.__update_task_tex() elif "size" in what: self.__update_task_size() else: self.__update_task() else: self.__update_task() def update_anim(self, anim): warnings.warn("No need for this when shaders are working!", DeprecationWarning) self._actor = self._actor.loop(anim) def __update_task(self): self._actor.setPos(self._posx, self._posy, self._getheight(self._posx, self._posy)) self._actor.setHpr(self._orient, 0.0, 0.0) def __update_task_size(self): self._actor.setScale(self._siz, self._siz, self._siz) self.__update_task() def _generate_name(self, name): if name is None: id = "10000000" while id in self._game.game_values["used_names"]: id = str(self._game.game_values["static_random"].randint(10000000, 99999999)) return id else: if name in self._game.game_values["used_names"]: raise KeyError("Name already used!") else: return name def _get_next_position(self, cx, cy, tx, ty): if self._angle[0] is None: deltax = tx - cx deltay = ty - cy self._angle[0] = math.atan2(deltax,deltay) self._angle[1] = self._angle[0]*180.0/math.pi if cx > tx: nx = cx - 1 elif cx < tx: nx = cx + 1 else: nx = cx if cy > ty: ny = cy - 1 elif cy < ty: ny = cy + 1 else: ny = cy return nx, ny, self._angle[1]