def _startMoveIval(self, entranceId, startT): self._stopMoveIval() unitVecs = (PM.Vec3(1, 0, 0), PM.Vec3(0, 1, 0), PM.Vec3(-1, 0, 0), PM.Vec3(0, -1, 0)) machineDistance = 4 entranceDistance = 60 startPos = unitVecs[entranceId] * entranceDistance endPos = unitVecs[entranceId] * machineDistance walkDur = (endPos - startPos ).length() / GameConsts.CogSettings.CogWalkSpeed.get() sceneRoot = self.getGame().getSceneRoot() moveIval = IG.Sequence( IG.Func(self.reparentTo, sceneRoot), IG.Func(self.setPos, startPos), IG.Func(self.lookAt, sceneRoot), IG.Func(self.loop, 'walk'), IG.LerpPosInterval(self, walkDur, endPos, startPos=startPos)) interactIval = IG.Sequence( IG.Func(self.loop, 'neutral'), IG.Wait(GameConsts.CogSettings.CogMachineInteractDuration.get())) flyIval = IG.Sequence( IG.Func(self.pose, 'landing', 0), IG.LerpPosInterval(self, GameConsts.CogSettings.CogFlyAwayDuration.get(), self._getFlyAwayDest, blendType='easeIn')) self._moveIval = IG.Sequence(moveIval, interactIval, flyIval) self._moveIval.start(globalClock.getFrameTime() - startT)
def template_simple(self, target, parameters): sequence = intervals.Sequence() if 'stat' not in parameters: parameters['stat'] = 'current_hp' if 'start_range' in parameters: parameters['range'] = parameters['start_range'] sequence.append(self.move_to_range(self.combatant, parameters)) if 'animation_name' not in parameters and self.ability.type == 'magical': parameters['animation_name'] = 'magic' if 'vfx' not in parameters and self.ability.type == 'magical': parameters['vfx'] = ['dust'] elif 'vfx' not in parameters: parameters['vfx'] = ['sparks'] sequence.extend( intervals.Sequence( self.play_animation(self.combatant, parameters), self.play_vfx(target, parameters), self.change_stat(target, parameters), )) if 'start_range' in parameters: if 'end_range' in parameters: parameters['range_index'] = parameters['end_range'] else: parameters['range_index'] = parameters['start_range'] sequence.append(self.move_to_range(self.combatant, parameters)) return sequence
def __init__(self, rendernp, combatant, ability, combat): self.rendernp = rendernp self.combatant = combatant self.ability = ability self.combat = combat hit_chance = calculate_hit_chance(combatant, combatant.target, ability) roll = random.randrange(0, 99) self.is_hit = hit_chance > roll #print(hit, hit_chance, die) crit_chance = calculate_crit_chance(combatant, combatant.target, ability) roll = random.randrange(0, 99) self.is_crit = crit_chance > roll self.strength = calculate_strength(combatant, ability) if self.is_crit: self.strength = round(self.strength * 1.5) self.sequence = intervals.Sequence() self.initial_self_position = combatant.tile_position self.initial_other_position = combatant.target.tile_position self.initial_position = None for effect in ability.effects: self.sequence.extend(self.parse_effect(effect)) self.sequence.append( intervals.Func(combatant.play_anim, 'idle', loop=True), )
def play_vfx(self, target, parameters): vfxnames = parameters.get('vfx', []) duration = parameters.get('duration', 1.0) if isinstance(vfxnames, str): vfxnames = [vfxnames] def create_vfx(vfxname): particles = ParticleEffect() if pman.is_frozen(): vfxpath = f'assets/vfx/{vfxname}.ptf' else: vfxpath = f'.built_assets/vfx/{vfxname}.ptf' particles.loadConfig(vfxpath) particles.set_shader_auto(True) return particles vfx = [create_vfx(i) for i in vfxnames] def start_particle(effect): effect.start(parent=target.as_nodepath) return intervals.Parallel(*[ intervals.Sequence( intervals.Func(start_particle, i), intervals.Wait(duration), intervals.Func(i.cleanup), ) for i in vfx ])
def _removeRepairSpotHoles(self): for locIndex in PVPGlobals.ShipClass2repairLocators[self.modelClass].getValue(): self._removeRepairSpotModel(locIndex) if self._repairSpotHoleFixed: self._placeRepairSpotModel(locIndex, self._repairSpotHoleFixed) self._fadeOutRepairSpotModel(locIndex) self._repairSpotIvals[locIndex] = IG.Sequence(self._repairSpotIvals[locIndex], IG.Func(self._removeRepairSpotModel, locIndex)) continue
def _fadeOutRepairSpotModel(self, locIndex): if locIndex in self._repairSpotIvals: self._repairSpotIvals[locIndex].pause() self._repairSpotHoles[locIndex].setTransparency(1, 100) ival = IG.Sequence(IG.Wait(DistributedPlayerSimpleShip.RepairSpotFadeAfter), IG.LerpColorScaleInterval(self._repairSpotHoles[locIndex], DistributedPlayerSimpleShip.RepairSpotFadeDur, Vec4(1.0, 1.0, 1.0, 0.0), blendType = 'easeInOut')) ival.start() self._repairSpotIvals[locIndex] = ival
def func(): textnp.set_pos(target.as_nodepath, 0, 0, 2) intervals.Sequence( intervals.Func(textnp.show), intervals.LerpPosInterval( textnp, 1.0, textnp.get_pos() + p3d.LVector3(0, 0, 0.5)), intervals.Func(textnp.remove_node), ).start()
def move_to_range(self, target, parameters): target_range = parameters['range'] hit_required = parameters.get('is_hit_dependent', False) if hit_required and not self.is_hit: return intervals.Sequence() seq = self.combat.move_combatant_to_range(target, target.target, target_range) return seq
def use_ability(self, ability, target, controller, effect_node): self.target = target target.target = self return intervals.Sequence( intervals.Func( controller.display_message, f'{self.name} is using {ability.name} ' f'on {target.name}'), effects.sequence_from_ability(effect_node, self, ability, controller))
def accept_move(): selection = self.combatant_in_tile(self.selected_tile) if selection == combatant: selection = None in_range = self.arena.tile_in_range(self.selected_tile, self.starting_tile_position, 0, combatant.movement) if selection is None and in_range: intervals.Sequence( self.move_combatant_to_tile(combatant, self.selected_tile), intervals.Func(self.set_input_state, 'ACTION', combatant)).start()
def move_combatant_to_tile(self, combatant, tile_pos, immediate=False): if immediate: duration = 0 else: duration = self.arena.tile_distance(combatant.tile_position, tile_pos) * 0.2 combatant.tile_position = tile_pos newpos = self.arena.tile_coord_to_world(tile_pos) sequence = intervals.Sequence( intervals.Func(combatant.play_anim, 'walk', loop=True), intervals.LerpPosInterval(combatant.as_nodepath, duration, newpos), intervals.Func(combatant.play_anim, 'idle', loop=True)) if immediate: sequence.start() return sequence
def parse_effect(self, effect): sequence = intervals.Sequence() target = effect.get('target', 'other') if target == 'self': target = self.combatant self.initial_position = self.initial_self_position elif target == 'other': target = self.combatant.target self.initial_position = self.initial_other_position else: raise RuntimeError("Unkown effect target: {}".format(target)) parameters = effect.get('parameters', {}) etype = effect['type'] if etype not in self.ALLOWED_EFFECTS: raise RuntimeError("Unknown effect type: {}".format(etype)) sequence.append(getattr(self, etype)(target, parameters)) return sequence
def change_stat(self, target, parameters): stat = parameters['stat'] local_str_fac = parameters.get('strength_factor', 1) seq = intervals.Sequence() strength = self.strength * local_str_fac if parameters.get('show_result', True): if self.is_hit: result = self.CHANGE_STATE_PREFIX.get( stat, '') + f'{strength * -1:+}' if self.is_crit: result += ' (CRIT!)' else: result = 'Miss' seq.append(self.show_result(target, result)) def func(): if self.is_hit: setattr(target, stat, getattr(target, stat) - strength) seq.append(intervals.Func(func)) return seq
def actor_interval(self, anim): mapped_anim = self.get_anim(anim) if mapped_anim is None: self._anim_warning(anim) return intervals.Sequence() return self._path.actor_interval(mapped_anim)
def update_combatant(self, combatant, enemy_combatants): sequence = intervals.Sequence() # Find a target target = self.targets.get(combatant, None) if target is None or target.is_dead(): target = random.choice(enemy_combatants) for enemy in enemy_combatants: dist_to_closest = self.arena.tile_distance(combatant.tile_position, target.tile_position) dist_to_current = self.arena.tile_distance(combatant.tile_position, enemy.tile_position) if dist_to_current < dist_to_closest: target = enemy # Pick an ability available_abilities = [ ability for ability in combatant.abilities if combatant.can_use_ability(ability) ] if not available_abilities: return sequence ability = random.choice(available_abilities) # Update facing sequence.append( intervals.Func(self.controller.face_combatant_at_tile, combatant, target.tile_position)) # Find a tile to move to tiles = self.arena.find_tiles_in_range(combatant.tile_position, 0, combatant.movement) tiles = [ tile for tile in tiles if self.controller.combatant_in_tile(tile) is None ] target_tile = None dist_to_target = self.arena.tile_distance(combatant.tile_position, target.tile_position) range_min, range_max = self.controller.get_ability_range( combatant, ability) for tile in tiles: tile_dist = self.arena.tile_distance(tile, target.tile_position) if range_min <= tile_dist <= range_max: target_tile = tile dist_to_target = tile_dist break elif tile_dist < dist_to_target: target_tile = tile dist_to_target = tile_dist if target_tile: self.controller.selected_tile = target_tile sequence.extend([ self.controller.move_combatant_to_tile(combatant, target_tile), ]) # Update facing sequence.append( intervals.Func(self.controller.face_combatant_at_tile, combatant, target.tile_position)) # Use an ability if able if range_min <= dist_to_target <= range_max: sequence.extend([ intervals.WaitInterval(0.25), combatant.use_ability(ability, target, self.controller, self.effects_root), intervals.WaitInterval(1), ]) return sequence
def move_combatant_to_range(self, *_args, **_kwargs): return intervals.Sequence()