def _change_sun_state(self, sun_np, task): """Change Sun color and angle with a small step. Args: sun_np (panda3d.core.NodePath): Sun node path. """ if self._color_step == self._day_part_duration: self._color_step = 0 self._color = self._next_color self._next_color = copy.deepcopy(next(SUN_COLORS)) self._color_vec = self._calc_color_vec(self._color, self._next_color, self._day_part_duration) # start Sun movement interval if self._color["name"] == "night": self._arch_int = MopathInterval( self._path, sun_np, duration=self._day_part_duration * self._step_duration * 3, name="sun_interval", ) self._arch_int.start() # do color changing step for field in ("dir", "amb"): for i in range(3): self._color[field][i] += self._color_vec[field][i] self._dir_light.setColor(self._color["dir"]) self._amb_light.setColor(self._color["amb"]) self._color_step += 1 return task.again
def _set_day_night_cycle(self, sun_np, day_time): """Set intervals and methods for day-night cycle. Args: sun_np (panda3d.core.NodePath): Sun node path. day_time (dict): Day time description. """ taskMgr.doMethodLater( # noqa: F821 self._step_duration, self._change_sun_state, "change_sun_color", extraArgs=[sun_np], appendTask=True, ) self._arch_int = MopathInterval( self._path, sun_np, duration=day_time["time"]["duration"] if day_time else self._day_part_duration * self._step_duration * 2, name="sun_interval", ) self._arch_int.start( startT=day_time["time"]["current"] if day_time else 0) taskMgr.doMethodLater( # noqa: F821 0.01, self._sun_look_at_train, "sun_look_at_train", extraArgs=[sun_np], appendTask=True, )
def _jump_and_explode(self, task): """Jump to the Adjutant and self-explode.""" if self.current_part is None: return task.done for char in base.world.enemy.active_units.values(): # noqa: F821 if type(char ) == Kamikaze and char.id != self.id and char.is_jumping: return task.again self.is_jumping = True self._stop_tasks("_float_move") self._move_int.pause() Sequence( LerpPosInterval(self.node, 2.5, (self._y_pos, -0.5, 0), blendType="easeInOut"), Func(self._ignite_the_wick), LerpPosInterval( self.node, 4.5, (-0.45 if self._y_pos < 0 else 0.45, -0.8, 0), blendType="easeInOut", ), Func(self._jump_snd.play), MopathInterval(self._jump_path, self.model, duration=0.8, name=self.id + "_jump"), Func(self._die, True), ).start() return task.done
def _jump_and_brake(self, task): """Jump over the railway and drop a brake shoe.""" if not self._brakes or self.current_part is None: return task.done for char in base.world.enemy.active_units.values(): # noqa: F821 # if someone is jumping now, don't jump if (type(char) == BrakeThrower and char.id != self.id and char.is_jumping) or (base.train.l_brake and base.train.r_brake # noqa: F821 ): return task.again y_target = round(abs(self._y_pos) - 0.55, 2) if self._y_pos < 0: y_target = -y_target if y_target not in self._y_positions: return task.again self._y_positions.remove(y_target) self.is_jumping = True self._stop_tasks("_float_move") self._move_int.pause() taskMgr.doMethodLater( # noqa: F821 0.15, self._jump_snd.play, self.id + "_jump_sound", extraArgs=[]) taskMgr.doMethodLater( # noqa: F821 1.5, self._fall_snd.play, self.id + "_fall_sound", extraArgs=[]) taskMgr.doMethodLater( # noqa: F821 1, self._drop_brake, self.id + "_drop_brake", extraArgs=[take_random(self._brakes)], ) self._jump_int = Sequence( MopathInterval( self._r_mopath if self._y_pos < 0 else self._l_mopath, self.model, duration=2.5, name=self.id + "_low_jump", blendType="easeOut", ), Func(self._finish_jump), ) self._jump_int.start() self._y_positions.append(self._y_pos) self._y_pos = y_target
def move_along_block(self, block, train_np, do_turn): """Start the locomotive move intervals for the given block. There are two intervals: the locomotive movement and synchronous camera movement. Args: block (world.block.Block): The World block to move along. train_np (panda3d.core.NodePath): Train node. do_turn (int): 0 if default direction was chosen, 1 if a turn is needed. """ self.on_et = block.enemy_territory self._outing_available = block.outing_available # use speed value from the last block rate = self._move_par.getPlayRate() if self._move_par else 1 is_fork = block.name in ("r_fork", "l_fork", "exit_from_fork") self._move_par = Parallel( MopathInterval( # locomotive movement block.path[do_turn] if is_fork else block.path, self._model, duration=4.4, name="current_path", ), MopathInterval( # camera movement block.cam_path[do_turn] if is_fork else block.cam_path, train_np, duration=4.4, name="current_camera_path", ), ) self._move_par.setDoneEvent("block_finished") self._move_par.start() self._move_par.setPlayRate(rate)
def __init__(self): x_coor, side = random.choice( ((0.553, "left"), (-0.553, "right"), (0, "top"))) self._model = Actor(address("rocket1")) self._model.reparentTo(base.train.model) # noqa: F821 self._model.setPos(x_coor, -7, 0.5) self._smoke = ParticleEffect() self._smoke.loadConfig("effects/smoke_tail.ptf") self._smoke.start(self._model, render) # noqa: F821 path = Mopath.Mopath(objectToLoad=loader.loadModel( # noqa: F821 address("rocket_{}_path".format(side)))) path.fFaceForward = True self._hiss_snd = base.sound_mgr.loadSfx( "sounds/rocket_fly.ogg") # noqa: F821 base.sound_mgr.attachSoundToObject(self._hiss_snd, self._model) # noqa: F821 self._hiss_snd2 = base.sound_mgr.loadSfx( "sounds/rocket_hiss.ogg") # noqa: F821 base.sound_mgr.attachSoundToObject(self._hiss_snd2, self._model) # noqa: F821 self._hiss_snd.play() seq = Sequence( LerpPosInterval(self._model, 7, (x_coor, -0.627, 0.561), blendType="easeOut"), Wait(0.7), Parallel( SoundInterval(self._hiss_snd2), MopathInterval(path, self._model, duration=0.5, name="rocket_current_path"), ), Func(self._explode, side), ) seq.start()
class Sun: """The game Sun. Includes ambient and directional lights. Sun changes its color according to game day time. Simulates real Sun movement as well. Args: day_part_desc (dict): Day part description. """ def __init__(self, day_part_desc): self._path = Mopath.Mopath(objectToLoad=address("sun_path")) self._color = copy.deepcopy(next(SUN_COLORS)) self._next_color = copy.deepcopy(next(SUN_COLORS)) self._color_step = 0 if day_part_desc: while self._color["name"] != day_part_desc["name"]: self._color = self._next_color self._next_color = copy.deepcopy(next(SUN_COLORS)) self._color = day_part_desc["time"]["color"] self._color_step = day_part_desc["time"]["step"] # day duration = 90 steps * 10 sec/step = 15 min/part # 15 min/part * 4 parts = 1 hour/day self._day_part_duration = 90 self._step_duration = 9 self._arch_int = None self._color_vec = self._calc_color_vec(self._color, self._next_color, self._day_part_duration) self._amb_light, self._dir_light, sun_np = self._set_general_lights( base.train.node # noqa: F821 ) self._set_day_night_cycle(sun_np, day_part_desc) @property def day_part(self): """Day part name. Returns: str: day part name. """ return self._color["name"] @property def day_part_time(self): """Exact day part step. Returns: int: Day part step. """ return { "step": self._color_step, "duration": self._arch_int.getDuration(), "current": self._arch_int.getT(), "color": self._color, } @property def is_dark(self): """Returns True if it's too dark to shoot.""" if self.day_part == "evening" and self._color_step > 45: return True if self.day_part == "night" and self._color_step < 45: return True return False def _set_general_lights(self, train_np): """Set initial Sun lights. Args: train_np (panda3d.core.NodePath): Train node. Returns: panda3d.core.AmbientLight: Sun ambient light. panda3d.core.DirectionalLight: Sun directional light. panda3d.core.NodePath: NodePath of the Sun. """ amb_light = AmbientLight("sun_amb") amb_light.setColor(self._color["amb"]) render.setLight(render.attachNewNode(amb_light)) # noqa: F821 lens = PerspectiveLens() lens.setNearFar(1, 100) lens.setFov(20, 20) sun_light = Spotlight("sun_dir") sun_light.setColor(self._color["dir"]) sun_light.setShadowCaster(True, 8192, 8192, sort=-2000) sun_light.setLens(lens) sun_light.setExponent(0.5) sun_light.setCameraMask(0b0001) sun_np = train_np.attachNewNode(sun_light) render.setLight(sun_np) # noqa: F821 return amb_light, sun_light, sun_np def _set_day_night_cycle(self, sun_np, day_time): """Set intervals and methods for day-night cycle. Args: sun_np (panda3d.core.NodePath): Sun node path. day_time (dict): Day time description. """ taskMgr.doMethodLater( # noqa: F821 self._step_duration, self._change_sun_state, "change_sun_color", extraArgs=[sun_np], appendTask=True, ) self._arch_int = MopathInterval( self._path, sun_np, duration=day_time["time"]["duration"] if day_time else self._day_part_duration * self._step_duration * 2, name="sun_interval", ) self._arch_int.start( startT=day_time["time"]["current"] if day_time else 0) taskMgr.doMethodLater( # noqa: F821 0.01, self._sun_look_at_train, "sun_look_at_train", extraArgs=[sun_np], appendTask=True, ) def _sun_look_at_train(self, sun_np, task): sun_np.lookAt(base.train.model) # noqa: F821 return task.again def _change_sun_state(self, sun_np, task): """Change Sun color and angle with a small step. Args: sun_np (panda3d.core.NodePath): Sun node path. """ if self._color_step == self._day_part_duration: self._color_step = 0 self._color = self._next_color self._next_color = copy.deepcopy(next(SUN_COLORS)) self._color_vec = self._calc_color_vec(self._color, self._next_color, self._day_part_duration) # start Sun movement interval if self._color["name"] == "night": self._arch_int = MopathInterval( self._path, sun_np, duration=self._day_part_duration * self._step_duration * 3, name="sun_interval", ) self._arch_int.start() # do color changing step for field in ("dir", "amb"): for i in range(3): self._color[field][i] += self._color_vec[field][i] self._dir_light.setColor(self._color["dir"]) self._amb_light.setColor(self._color["amb"]) self._color_step += 1 return task.again def _calc_color_vec(self, color, next_color, steps): """Calculate vector to change color in given steps number. Args: color (dict): Ambient and directional current colors. next_color (Vec4): Next ambient and directional colors. steps (int): Number of steps to change color. Returns: dict: Directonal and ambient lights change vector. """ vects = {} for field in ("dir", "amb"): vects[field] = Vec4( (next_color[field][0] - color[field][0]) / steps, (next_color[field][1] - color[field][1]) / steps, (next_color[field][2] - color[field][2]) / steps, 1, ) return vects def ignore_shadows(self, model): """Don't cast shadow of the given model. Args: model (panda3d.core.NodePath): Model, which shadow must be hidden. """ model.hide(self._dir_light.getCameraMask())