예제 #1
0
    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
        ])
예제 #2
0
    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
예제 #3
0
    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 _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
예제 #5
0
 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 _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))
예제 #7
0
    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))
예제 #8
0
 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()
예제 #9
0
 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
예제 #10
0
 def set_camera_x(self, newx):
     campos = base.camera.get_pos()
     campos.x = newx
     intervals.LerpPosInterval(base.camera,
                               0.1,
                               campos,
                               blendType='easeInOut').start()
예제 #11
0
    def enter_end_turn(self):
        combatants_by_ct = sorted(list(self.combatants),
                                  reverse=True,
                                  key=lambda x: x.current_ct)
        next_combatant = combatants_by_ct[0]
        ctdiff = 100 - next_combatant.current_ct
        if ctdiff > 0:
            for combatant in self.combatants:
                combatant.current_ct += ctdiff
        next_combatant.current_ct = 0
        self.selected_tile = next_combatant.tile_position
        self.starting_tile_position = next_combatant.tile_position

        if next_combatant in self.player_combatants:
            self.set_input_state('ACTION', next_combatant)
        else:
            sequence = self.aicontroller.update_combatant(
                next_combatant, self.get_remaining_player_combatants())

            def cleanup():
                if self.input_state != 'END_COMBAT':
                    self.input_state = 'END_TURN'

            sequence.extend([
                intervals.Func(cleanup),
            ])
            sequence.start()
예제 #12
0
    def show_result(self, target, value):
        textnode = p3d.TextNode('effect result')
        textnode.set_align(p3d.TextNode.ACenter)
        textnode.set_text(value)

        textnp = self.rendernp.attach_new_node(textnode)
        textnp.set_billboard_point_eye()
        textnp.set_bin("fixed", 0)
        textnp.set_depth_test(False)
        textnp.set_depth_write(False)
        textnp.set_shader_auto(True)
        textnp.set_color_scale((0, 0, 0, 1))
        textnp.set_light_off()
        textnp.hide()

        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()

        return intervals.Func(func)
예제 #13
0
 def _startMoveIval(self, entranceId, startT):
     self._stopMoveIval()
     unitVecs = (Vec3(1, 0, 0),
      Vec3(0, 1, 0),
      Vec3(-1, 0, 0),
      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)
예제 #14
0
    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
예제 #15
0
    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
예제 #16
0
        def accept_target():
            selection = self.combatant_in_tile(self.selected_tile)
            in_range = self.arena.tile_in_range(
                self.selected_tile, combatant.tile_position,
                *self.get_ability_range(combatant, ability))
            if selection is not None and in_range:
                sequence = combatant.use_ability(ability, selection, self,
                                                 self.root_node)

                def cleanup():
                    self.selected_tile = combatant.tile_position
                    if self.input_state != 'END_COMBAT':
                        self.set_input_state('END_TURN')

                sequence.append(intervals.Func(cleanup))
                sequence.start()
예제 #17
0
    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
예제 #18
0
    def update(self, statedata):
        if not self.stats_box.is_hidden():
            self._stats_menu.update(statedata)
            statedata.pop('show_menu', None)
        super().update(statedata)

        if 'num_form_abilities' in statedata:
            self._stats_num_fabilities = statedata['num_form_abilities']

        if 'num_weapon_abilities' in statedata:
            self._stats_num_wabilities = statedata['num_weapon_abilities']

        if 'num_golems' in statedata or 'max_golems' in statedata:
            self.num_golems_label['text'] = (
                f'Golems: {statedata["num_golems"]}/{statedata["max_golems"]}')

        if 'num_power_gems' in statedata:
            self.num_gems_label['text'] = (
                f'Power Gems: {statedata["num_power_gems"]}')

        if 'monster' in statedata:
            self.rebuild_stats(statedata['monster'])

        if 'show_stats' in statedata:
            show = statedata['show_stats']
            if show and self.stats_box.is_hidden():
                intervals.LerpPosInterval(self.stats_box,
                                          0.1,
                                          self.stats_box.get_pos(),
                                          startPos=(-1, 0,
                                                    self.stats_box.get_z()),
                                          blendType='easeInOut').start()
                self.stats_box.show()
                self.menu.hide()
                self.num_golems_label.hide()
            elif not show:
                self.stats_box.hide()
                self.menu.show()
                self.num_golems_label.show()
예제 #19
0
 def move_combatant_to_range(self, *_args, **_kwargs):
     return intervals.Sequence()
예제 #20
0
 def change_to_previous_state(self, skip_fade=False):
     ival = intervals.Func(self.gman.change_to_previous)
     if skip_fade:
         ival.start()
     else:
         self.transitions.fadeOut(finishIval=ival)
예제 #21
0
 def change_state(self, next_state, skip_fade=False):
     ival = intervals.Func(self.gman.change, next_state)
     if skip_fade:
         ival.start()
     else:
         self.transitions.fadeOut(finishIval=ival)
예제 #22
0
    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
예제 #23
0
 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)