def targetedWeaponHit(self,
                          skillId,
                          ammoSkillId,
                          skillResult,
                          targetEffects,
                          attacker,
                          pos,
                          charge=0,
                          delay=None,
                          multihit=0,
                          itemEffects=[]):
        if self == attacker:
            if not targetEffects[0] and targetEffects[1] and targetEffects[
                    2] and targetEffects[3] > 0:
                pass
            if not targetEffects[4] and not WeaponGlobals.isSelfUseSkill(
                    skillId):
                return None

        if not delay:
            (targetPos, time,
             impactT) = self.getProjectileInfo(skillId, attacker)
            if impactT:
                delay = impactT
            else:
                delay = WeaponGlobals.getAttackReactionDelay(
                    skillId, ammoSkillId)

        if WeaponGlobals.getIsDollAttackSkill(skillId):
            delay += random.uniform(0.0, 0.5)

        if attacker and attacker.isLocal():
            self.localAttackedMe()
            centerEffect = WeaponGlobals.getCenterEffect(skillId, ammoSkillId)
            if self.hasNetPythonTag('MonstrousObject'):
                pass
            elif not centerEffect == 2:
                if not self.avatarType.isA(
                        AvatarTypes.Stump) and self.avatarType.isA(
                            AvatarTypes.FlyTrap) and self.avatarType.isA(
                                AvatarTypes.GiantCrab):
                    pass
                if not self.avatarType.isA(AvatarTypes.CrusherCrab):
                    mult = 0.66600000000000004
                    if self.avatarType.isA(
                            AvatarTypes.GiantCrab) or self.avatarType.isA(
                                AvatarTypes.CrusherCrab):
                        mult = 0.10000000000000001
                    elif self.avatarType.isA(AvatarTypes.RockCrab):
                        mult = 0.20000000000000001

                    pos = Vec3(0, 0, self.height * mult)
                elif centerEffect == 1:
                    newZ = attacker.getZ(self)
                    pos = Vec3(0, 0,
                               newZ + attacker.height * 0.66600000000000004)
                else:
                    newPos = self.cr.targetMgr.getAimHitPos(attacker)
                    if newPos:
                        pos = Vec3(newPos[0], newPos[1], newPos[2] + 1.5)

            else:
                centerEffect = WeaponGlobals.getCenterEffect(
                    skillId, ammoSkillId)
                if centerEffect >= 1:
                    pos = Vec3(0, 0, self.height * 0.66600000000000004)

        weaponSubType = None
        if attacker and attacker.currentWeapon:
            weaponType = ItemGlobals.getType(attacker.currentWeapon.itemId)
            if weaponType in [ItemGlobals.SWORD]:
                weaponSubType = ItemGlobals.getSubtype(
                    attacker.currentWeapon.itemId)
            elif attacker.currentWeapon.getName() in ['sword']:
                weaponSubType = ItemGlobals.CUTLASS

        if delay > 0.0:
            taskMgr.doMethodLater(
                delay,
                self.playHitSound,
                self.taskName('playHitSoundTask'),
                extraArgs=[skillId, ammoSkillId, skillResult, weaponSubType])
        else:
            self.playHitSound(skillId, ammoSkillId, skillResult, weaponSubType)
        if skillResult in [
                WeaponGlobals.RESULT_HIT, WeaponGlobals.RESULT_MISTIMED_HIT,
                WeaponGlobals.RESULT_REFLECTED
        ]:
            bonus = 0
            if bonus:
                targetEffects[0] -= bonus

            if skillResult == WeaponGlobals.RESULT_MISTIMED_HIT:
                if type(targetEffects) is types.TupleType:
                    targetEffects = (int(
                        targetEffects[0] *
                        WeaponGlobals.MISTIME_PENALTY), ) + targetEffects[1:]
                else:
                    targetEffects[0] = int(targetEffects[0] *
                                           WeaponGlobals.MISTIME_PENALTY)

            if delay > 0.0:
                taskMgr.doMethodLater(delay,
                                      self.playOuch,
                                      self.taskName('playOuchTask'),
                                      extraArgs=[
                                          skillId, ammoSkillId, targetEffects,
                                          attacker, pos, itemEffects, multihit,
                                          0, skillResult
                                      ])
            else:
                self.playOuch(skillId,
                              ammoSkillId,
                              targetEffects,
                              attacker,
                              pos,
                              itemEffects,
                              multihit,
                              skillResult=skillResult)
            if bonus:
                taskMgr.doMethodLater(WeaponGlobals.COMBO_DAMAGE_DELAY,
                                      self.playOuch,
                                      self.taskName('playBonusOuchTask'),
                                      extraArgs=[
                                          skillId, ammoSkillId,
                                          [bonus, 0, 0, 0, 0], attacker, pos,
                                          itemEffects, multihit, 1
                                      ])

            if skillId in WeaponGlobals.BackstabSkills and charge:
                if attacker and attacker.isLocal() and ItemGlobals.getSubtype(
                        attacker.currentWeaponId
                ) == ItemGlobals.DAGGER_SUBTYPE:
                    messenger.send(''.join(['trackBackstab-', str(self.doId)]))

        elif skillResult == WeaponGlobals.RESULT_MISS and skillResult == WeaponGlobals.RESULT_MISTIMED_MISS and skillResult == WeaponGlobals.RESULT_DODGE and skillResult == WeaponGlobals.RESULT_PARRY and skillResult == WeaponGlobals.RESULT_RESIST or skillResult == WeaponGlobals.RESULT_PROTECT:
            resultString = WeaponGlobals.getSkillResultName(skillResult)
            delay = WeaponGlobals.getAttackReactionDelay(skillId, ammoSkillId)
            if delay > 0.0:
                taskMgr.doMethodLater(delay,
                                      self.showHpString,
                                      self.taskName('showMissTask'),
                                      extraArgs=[resultString, pos])
            else:
                self.showHpString(resultString, pos)
        elif skillResult == WeaponGlobals.RESULT_OUT_OF_RANGE or skillResult == WeaponGlobals.RESULT_BLOCKED:
            pass
        elif skillResult == WeaponGlobals.RESULT_AGAINST_PIRATE_CODE:
            if attacker and attacker.isLocal():
                resultString = WeaponGlobals.getSkillResultName(skillResult)
                self.showHpString(resultString, pos)

        elif skillResult == WeaponGlobals.RESULT_NOT_AVAILABLE:
            self.notify.warning('WeaponGlobals.RESULT_NOT_AVAILABLE')
        else:
            self.notify.error('unknown skillResult: %d' % skillResult)
    def useTargetedSkill(self,
                         skillId,
                         ammoSkillId,
                         skillResult,
                         targetId,
                         areaIdList,
                         attackerEffects,
                         targetEffects,
                         areaIdEffects,
                         itemEffects,
                         timestamp,
                         pos,
                         charge=0,
                         localSignal=0):
        if WeaponGlobals.isSelfUseSkill(skillId) and not localSignal:
            selfUse = True
        else:
            selfUse = False
        if localSignal:
            target = self.cr.doId2do.get(targetId)
            if target and target != self and WeaponGlobals.isBreakAttackComboSkill(
                    skillId) and skillResult == WeaponGlobals.RESULT_HIT:
                levelGrade = self.cr.battleMgr.getModifiedExperienceGrade(
                    self, target)
                self.guiMgr.combatTray.updateSkillCharges(levelGrade)

        if not self.isLocal() and localSignal and WeaponGlobals.getSkillTrack(
                skillId) == WeaponGlobals.DEFENSE_SKILL_INDEX or selfUse:
            multiHits = []
            numHits = WeaponGlobals.getNumHits(skillId)
            hitTiming = WeaponGlobals.getMultiHitAttacks(skillId)
            if hitTiming:
                multiHits += hitTiming

            if ammoSkillId:
                numHits += WeaponGlobals.getNumHits(ammoSkillId) - 1
                hitTiming = WeaponGlobals.getMultiHitAttacks(ammoSkillId)
                if hitTiming:
                    multiHits += hitTiming

            if not selfUse or self.isNpc:
                if not targetId and areaIdList:
                    self.playSkillMovie(skillId, ammoSkillId, skillResult,
                                        charge, areaIdList[0], areaIdList)
                else:
                    self.playSkillMovie(skillId, ammoSkillId, skillResult,
                                        charge, targetId, areaIdList)

            if skillResult == WeaponGlobals.RESULT_REFLECTED or selfUse:
                target = self
                targetId = self.getDoId()
            elif skillResult == WeaponGlobals.RESULT_BLOCKED:
                target = None
            else:
                target = self.currentTarget
            if target and targetId:
                if multiHits and numHits:
                    multiHitEffects = self.packMultiHitEffects(
                        targetEffects, numHits)
                    for i in range(numHits):
                        target.targetedWeaponHit(skillId,
                                                 ammoSkillId,
                                                 skillResult,
                                                 multiHitEffects[i],
                                                 self,
                                                 pos,
                                                 charge,
                                                 multiHits[i],
                                                 i,
                                                 itemEffects=itemEffects)

                else:
                    target.targetedWeaponHit(skillId,
                                             ammoSkillId,
                                             skillResult,
                                             targetEffects,
                                             self,
                                             pos,
                                             charge,
                                             itemEffects=itemEffects)

            for (targetId, areaEffects) in zip(areaIdList, areaIdEffects):
                target = self.cr.doId2do.get(targetId)
                if target:
                    if multiHits and numHits:
                        multiHitEffects = self.packMultiHitEffects(
                            areaEffects, numHits)
                        for i in range(numHits):
                            target.targetedWeaponHit(skillId,
                                                     ammoSkillId,
                                                     skillResult,
                                                     multiHitEffects[i],
                                                     self,
                                                     pos,
                                                     charge,
                                                     multiHits[i],
                                                     i,
                                                     itemEffects=itemEffects)

                    else:
                        target.targetedWeaponHit(skillId,
                                                 ammoSkillId,
                                                 skillResult,
                                                 areaEffects,
                                                 self,
                                                 pos,
                                                 charge,
                                                 itemEffects=itemEffects)

            if not (self.currentTarget) and not areaIdList:
                self.playHitSound(skillId, ammoSkillId,
                                  WeaponGlobals.RESULT_MISS)
    def playOuch(self,
                 skillId,
                 ammoSkillId,
                 targetEffects,
                 attacker,
                 pos,
                 itemEffects=[],
                 multihit=0,
                 targetBonus=0,
                 skillResult=0):
        (targetHp, targetPower, targetEffect, targetMojo,
         targetSwiftness) = targetEffects
        if self.gameFSM.state in ('Injured', ):
            return None

        if not targetBonus:
            if ammoSkillId:
                effectId = WeaponGlobals.getHitEffect(ammoSkillId)
                skillEffectId = WeaponGlobals.getSkillEffectFlag(ammoSkillId)
            else:
                effectId = WeaponGlobals.getHitEffect(skillId)
                skillEffectId = WeaponGlobals.getSkillEffectFlag(skillId)

        if attacker:
            self.addCombo(attacker.getDoId(), attacker.currentWeaponId,
                          skillId, -targetHp, skillResult)

        if WeaponGlobals.C_KNOCKDOWN not in self.getSkillEffects(
        ) or skillEffectId == WeaponGlobals.C_KNOCKDOWN:
            self.cleanupOuchIval()

        if not targetBonus and not (self.NoPain) and not (
                self.noIntervals) and targetEffects[0] < 0:
            if self.gameFSM.state not in (
                    'Ensnared', 'Knockdown', 'Stunned', 'Rooted',
                    'NPCInteract', 'ShipBoarding', 'Injured', 'Dying', 'Death'
            ) or WeaponGlobals.C_KNOCKDOWN in self.getSkillEffects(
            ) or self.gameFSM.state not in ('ShipBoarding', 'Injured', 'Dying',
                                            'Death'):
                if WeaponGlobals.C_KNOCKDOWN not in self.getSkillEffects(
                ) or skillEffectId == WeaponGlobals.C_KNOCKDOWN:
                    ouchSfx = None
                    if self.currentWeapon:
                        if not self.avatarType.isA(
                                AvatarTypes.Creature
                        ) and skillEffectId == WeaponGlobals.C_KNOCKDOWN and not ItemGlobals.getWeaponAttributes(
                                self.currentWeaponId, ItemGlobals.SURE_FOOTED):
                            if self.isLocal():
                                actorIval = Sequence(
                                    self.actorInterval('injured_fall',
                                                       playRate=1.5,
                                                       blendOutT=0),
                                    self.actorInterval('injured_standup',
                                                       playRate=1.5,
                                                       blendInT=0),
                                    Func(messenger.send, 'skillFinished'))
                            else:
                                actorIval = Sequence(
                                    self.actorInterval('injured_fall',
                                                       playRate=1.5,
                                                       blendOutT=0),
                                    self.actorInterval('injured_standup',
                                                       playRate=1.5,
                                                       blendInT=0))
                        elif not self.avatarType.isA(
                                AvatarTypes.Creature
                        ) and effectId == WeaponGlobals.VFX_BLIND:
                            actorIval = self.actorInterval(
                                'sand_in_eyes_holdweapon_noswing',
                                playRate=random.uniform(
                                    0.69999999999999996, 1.5))
                        else:
                            actorIval = self.actorInterval(
                                self.currentWeapon.painAnim,
                                playRate=random.uniform(
                                    0.69999999999999996, 1.5))
                            if WeaponGlobals.getIsStaffAttackSkill(skillId):
                                skillInfo = WeaponGlobals.getSkillAnimInfo(
                                    skillId)
                                getOuchSfxFunc = skillInfo[
                                    WeaponGlobals.OUCH_SFX_INDEX]
                                if getOuchSfxFunc:
                                    ouchSfx = getOuchSfxFunc()

                            else:
                                ouchSfx = self.getSfx('pain')
                    elif not self.avatarType.isA(
                            AvatarTypes.Creature
                    ) and skillEffectId == WeaponGlobals.C_KNOCKDOWN:
                        actorIval = Sequence(
                            self.actorInterval('injured_fall',
                                               playRate=1.5,
                                               blendOutT=0),
                            self.actorInterval('injured_standup',
                                               playRate=1.5,
                                               blendInT=0))
                    elif not self.avatarType.isA(
                            AvatarTypes.Creature
                    ) and effectId == WeaponGlobals.VFX_BLIND:
                        actorIval = self.actorInterval('sand_in_eyes',
                                                       playRate=random.uniform(
                                                           0.69999999999999996,
                                                           1.5))
                    else:
                        actorIval = self.actorInterval('idle_hit',
                                                       playRate=random.uniform(
                                                           0.69999999999999996,
                                                           1.5))
                    if ouchSfx:
                        self.ouchAnim = Sequence(
                            Func(base.playSfx, ouchSfx, node=self, cutoff=75),
                            actorIval)
                    else:
                        self.ouchAnim = actorIval
                    self.ouchAnim.start()

            skillEffectId == WeaponGlobals.C_KNOCKDOWN

        if self.combatEffect:
            self.combatEffect.destroy()
            self.combatEffect = None

        self.combatEffect = CombatEffect.CombatEffect(effectId, multihit,
                                                      attacker, skillResult)
        self.combatEffect.reparentTo(self)
        self.combatEffect.setPos(self, pos[0], pos[1], pos[2])
        if not WeaponGlobals.getIsDollAttackSkill(
                skillId) and not WeaponGlobals.getIsStaffAttackSkill(skillId):
            if not WeaponGlobals.isSelfUseSkill(skillId):
                if attacker and not attacker.isEmpty():
                    self.combatEffect.lookAt(attacker)

                self.combatEffect.setH(self.combatEffect, 180)

        skillEffects = self.getSkillEffects()
        if WeaponGlobals.C_MELEE_SHIELD in skillEffects:
            if WeaponGlobals.getAttackClass(
                    skillId) == WeaponGlobals.AC_COMBAT:
                self.pulseGhostGuardEffect(attacker,
                                           Vec4(0, 0, 0, 1),
                                           wantBlending=False)

        elif WeaponGlobals.C_MISSILE_SHIELD in skillEffects:
            if WeaponGlobals.getAttackClass(
                    skillId) == WeaponGlobals.AC_MISSILE:
                self.pulseGhostGuardEffect(attacker,
                                           Vec4(1, 1, 1, 1),
                                           wantBlending=True)

        elif WeaponGlobals.C_MAGIC_SHIELD in skillEffects:
            if WeaponGlobals.getAttackClass(skillId) == WeaponGlobals.AC_MAGIC:
                self.pulseGhostGuardEffect(attacker,
                                           Vec4(0.5, 0.29999999999999999, 1,
                                                1),
                                           wantBlending=True)

        self.combatEffect.play()
        if WeaponGlobals.getIsDollAttackSkill(skillId):
            self.voodooSmokeEffect2 = AttuneSmoke.getEffect()
            if self.voodooSmokeEffect2:
                self.voodooSmokeEffect2.reparentTo(self)
                self.voodooSmokeEffect2.setPos(0, 0, 0.20000000000000001)
                self.voodooSmokeEffect2.play()
 def targetedWeaponHit(self, skillId, ammoSkillId, skillResult, targetEffects, attacker, pos, charge = 0, delay = None, multihit = 0, itemEffects = []):
     if self == attacker:
         if not targetEffects[0] and targetEffects[1] and targetEffects[2] and targetEffects[3] > 0:
             pass
         if not targetEffects[4] and not WeaponGlobals.isSelfUseSkill(skillId):
             return None
         
     if not delay:
         (targetPos, time, impactT) = self.getProjectileInfo(skillId, attacker)
         if impactT:
             delay = impactT
         else:
             delay = WeaponGlobals.getAttackReactionDelay(skillId, ammoSkillId)
     
     if WeaponGlobals.getIsDollAttackSkill(skillId):
         delay += random.uniform(0.0, 0.5)
     
     if attacker and attacker.isLocal():
         self.localAttackedMe()
         centerEffect = WeaponGlobals.getCenterEffect(skillId, ammoSkillId)
         if self.hasNetPythonTag('MonstrousObject'):
             pass
         elif not centerEffect == 2:
             if not self.avatarType.isA(AvatarTypes.Stump) and self.avatarType.isA(AvatarTypes.FlyTrap) and self.avatarType.isA(AvatarTypes.GiantCrab):
                 pass
             if not self.avatarType.isA(AvatarTypes.CrusherCrab):
                 mult = 0.66600000000000004
                 if self.avatarType.isA(AvatarTypes.GiantCrab) or self.avatarType.isA(AvatarTypes.CrusherCrab):
                     mult = 0.10000000000000001
                 elif self.avatarType.isA(AvatarTypes.RockCrab):
                     mult = 0.20000000000000001
                 
                 pos = Vec3(0, 0, self.height * mult)
             elif centerEffect == 1:
                 newZ = attacker.getZ(self)
                 pos = Vec3(0, 0, newZ + attacker.height * 0.66600000000000004)
             else:
                 newPos = self.cr.targetMgr.getAimHitPos(attacker)
                 if newPos:
                     pos = Vec3(newPos[0], newPos[1], newPos[2] + 1.5)
                 
         else:
             centerEffect = WeaponGlobals.getCenterEffect(skillId, ammoSkillId)
             if centerEffect >= 1:
                 pos = Vec3(0, 0, self.height * 0.66600000000000004)
             
     weaponSubType = None
     if attacker and attacker.currentWeapon:
         weaponType = ItemGlobals.getType(attacker.currentWeapon.itemId)
         if weaponType in [
             ItemGlobals.SWORD]:
             weaponSubType = ItemGlobals.getSubtype(attacker.currentWeapon.itemId)
         elif attacker.currentWeapon.getName() in [
             'sword']:
             weaponSubType = ItemGlobals.CUTLASS
         
     
     if delay > 0.0:
         taskMgr.doMethodLater(delay, self.playHitSound, self.taskName('playHitSoundTask'), extraArgs = [
             skillId,
             ammoSkillId,
             skillResult,
             weaponSubType])
     else:
         self.playHitSound(skillId, ammoSkillId, skillResult, weaponSubType)
     if skillResult in [
         WeaponGlobals.RESULT_HIT,
         WeaponGlobals.RESULT_MISTIMED_HIT,
         WeaponGlobals.RESULT_REFLECTED]:
         bonus = 0
         if bonus:
             targetEffects[0] -= bonus
         
         if skillResult == WeaponGlobals.RESULT_MISTIMED_HIT:
             if type(targetEffects) is types.TupleType:
                 targetEffects = (int(targetEffects[0] * WeaponGlobals.MISTIME_PENALTY),) + targetEffects[1:]
             else:
                 targetEffects[0] = int(targetEffects[0] * WeaponGlobals.MISTIME_PENALTY)
         
         if delay > 0.0:
             taskMgr.doMethodLater(delay, self.playOuch, self.taskName('playOuchTask'), extraArgs = [
                 skillId,
                 ammoSkillId,
                 targetEffects,
                 attacker,
                 pos,
                 itemEffects,
                 multihit,
                 0,
                 skillResult])
         else:
             self.playOuch(skillId, ammoSkillId, targetEffects, attacker, pos, itemEffects, multihit, skillResult = skillResult)
         if bonus:
             taskMgr.doMethodLater(WeaponGlobals.COMBO_DAMAGE_DELAY, self.playOuch, self.taskName('playBonusOuchTask'), extraArgs = [
                 skillId,
                 ammoSkillId,
                 [
                     bonus,
                     0,
                     0,
                     0,
                     0],
                 attacker,
                 pos,
                 itemEffects,
                 multihit,
                 1])
         
         if skillId in WeaponGlobals.BackstabSkills and charge:
             if attacker and attacker.isLocal() and ItemGlobals.getSubtype(attacker.currentWeaponId) == ItemGlobals.DAGGER_SUBTYPE:
                 messenger.send(''.join([
                     'trackBackstab-',
                     str(self.doId)]))
             
         
     elif skillResult == WeaponGlobals.RESULT_MISS and skillResult == WeaponGlobals.RESULT_MISTIMED_MISS and skillResult == WeaponGlobals.RESULT_DODGE and skillResult == WeaponGlobals.RESULT_PARRY and skillResult == WeaponGlobals.RESULT_RESIST or skillResult == WeaponGlobals.RESULT_PROTECT:
         resultString = WeaponGlobals.getSkillResultName(skillResult)
         delay = WeaponGlobals.getAttackReactionDelay(skillId, ammoSkillId)
         if delay > 0.0:
             taskMgr.doMethodLater(delay, self.showHpString, self.taskName('showMissTask'), extraArgs = [
                 resultString,
                 pos])
         else:
             self.showHpString(resultString, pos)
     elif skillResult == WeaponGlobals.RESULT_OUT_OF_RANGE or skillResult == WeaponGlobals.RESULT_BLOCKED:
         pass
     elif skillResult == WeaponGlobals.RESULT_AGAINST_PIRATE_CODE:
         if attacker and attacker.isLocal():
             resultString = WeaponGlobals.getSkillResultName(skillResult)
             self.showHpString(resultString, pos)
         
     elif skillResult == WeaponGlobals.RESULT_NOT_AVAILABLE:
         self.notify.warning('WeaponGlobals.RESULT_NOT_AVAILABLE')
     else:
         self.notify.error('unknown skillResult: %d' % skillResult)
 def useTargetedSkill(self, skillId, ammoSkillId, skillResult, targetId, areaIdList, attackerEffects, targetEffects, areaIdEffects, itemEffects, timestamp, pos, charge = 0, localSignal = 0):
     if WeaponGlobals.isSelfUseSkill(skillId) and not localSignal:
         selfUse = True
     else:
         selfUse = False
     if localSignal:
         target = self.cr.doId2do.get(targetId)
         if target and target != self and WeaponGlobals.isBreakAttackComboSkill(skillId) and skillResult == WeaponGlobals.RESULT_HIT:
             levelGrade = self.cr.battleMgr.getModifiedExperienceGrade(self, target)
             self.guiMgr.combatTray.updateSkillCharges(levelGrade)
         
     
     if not self.isLocal() and localSignal and WeaponGlobals.getSkillTrack(skillId) == WeaponGlobals.DEFENSE_SKILL_INDEX or selfUse:
         multiHits = []
         numHits = WeaponGlobals.getNumHits(skillId)
         hitTiming = WeaponGlobals.getMultiHitAttacks(skillId)
         if hitTiming:
             multiHits += hitTiming
         
         if ammoSkillId:
             numHits += WeaponGlobals.getNumHits(ammoSkillId) - 1
             hitTiming = WeaponGlobals.getMultiHitAttacks(ammoSkillId)
             if hitTiming:
                 multiHits += hitTiming
             
         
         if not selfUse or self.isNpc:
             if not targetId and areaIdList:
                 self.playSkillMovie(skillId, ammoSkillId, skillResult, charge, areaIdList[0], areaIdList)
             else:
                 self.playSkillMovie(skillId, ammoSkillId, skillResult, charge, targetId, areaIdList)
         
         if skillResult == WeaponGlobals.RESULT_REFLECTED or selfUse:
             target = self
             targetId = self.getDoId()
         elif skillResult == WeaponGlobals.RESULT_BLOCKED:
             target = None
         else:
             target = self.currentTarget
         if target and targetId:
             if multiHits and numHits:
                 multiHitEffects = self.packMultiHitEffects(targetEffects, numHits)
                 for i in range(numHits):
                     target.targetedWeaponHit(skillId, ammoSkillId, skillResult, multiHitEffects[i], self, pos, charge, multiHits[i], i, itemEffects = itemEffects)
                 
             else:
                 target.targetedWeaponHit(skillId, ammoSkillId, skillResult, targetEffects, self, pos, charge, itemEffects = itemEffects)
         
         for (targetId, areaEffects) in zip(areaIdList, areaIdEffects):
             target = self.cr.doId2do.get(targetId)
             if target:
                 if multiHits and numHits:
                     multiHitEffects = self.packMultiHitEffects(areaEffects, numHits)
                     for i in range(numHits):
                         target.targetedWeaponHit(skillId, ammoSkillId, skillResult, multiHitEffects[i], self, pos, charge, multiHits[i], i, itemEffects = itemEffects)
                     
                 else:
                     target.targetedWeaponHit(skillId, ammoSkillId, skillResult, areaEffects, self, pos, charge, itemEffects = itemEffects)
         
         if not (self.currentTarget) and not areaIdList:
             self.playHitSound(skillId, ammoSkillId, WeaponGlobals.RESULT_MISS)
 def playOuch(self, skillId, ammoSkillId, targetEffects, attacker, pos, itemEffects = [], multihit = 0, targetBonus = 0, skillResult = 0):
     (targetHp, targetPower, targetEffect, targetMojo, targetSwiftness) = targetEffects
     if self.gameFSM.state in ('Injured',):
         return None
     
     if not targetBonus:
         if ammoSkillId:
             effectId = WeaponGlobals.getHitEffect(ammoSkillId)
             skillEffectId = WeaponGlobals.getSkillEffectFlag(ammoSkillId)
         else:
             effectId = WeaponGlobals.getHitEffect(skillId)
             skillEffectId = WeaponGlobals.getSkillEffectFlag(skillId)
     
     if attacker:
         self.addCombo(attacker.getDoId(), attacker.currentWeaponId, skillId, -targetHp, skillResult)
     
     if WeaponGlobals.C_KNOCKDOWN not in self.getSkillEffects() or skillEffectId == WeaponGlobals.C_KNOCKDOWN:
         self.cleanupOuchIval()
     
     if not targetBonus and not (self.NoPain) and not (self.noIntervals) and targetEffects[0] < 0:
         if self.gameFSM.state not in ('Ensnared', 'Knockdown', 'Stunned', 'Rooted', 'NPCInteract', 'ShipBoarding', 'Injured', 'Dying', 'Death') or WeaponGlobals.C_KNOCKDOWN in self.getSkillEffects() or self.gameFSM.state not in ('ShipBoarding', 'Injured', 'Dying', 'Death'):
             if WeaponGlobals.C_KNOCKDOWN not in self.getSkillEffects() or skillEffectId == WeaponGlobals.C_KNOCKDOWN:
                 ouchSfx = None
                 if self.currentWeapon:
                     if not self.avatarType.isA(AvatarTypes.Creature) and skillEffectId == WeaponGlobals.C_KNOCKDOWN and not ItemGlobals.getWeaponAttributes(self.currentWeaponId, ItemGlobals.SURE_FOOTED):
                         if self.isLocal():
                             actorIval = Sequence(self.actorInterval('injured_fall', playRate = 1.5, blendOutT = 0), self.actorInterval('injured_standup', playRate = 1.5, blendInT = 0), Func(messenger.send, 'skillFinished'))
                         else:
                             actorIval = Sequence(self.actorInterval('injured_fall', playRate = 1.5, blendOutT = 0), self.actorInterval('injured_standup', playRate = 1.5, blendInT = 0))
                     elif not self.avatarType.isA(AvatarTypes.Creature) and effectId == WeaponGlobals.VFX_BLIND:
                         actorIval = self.actorInterval('sand_in_eyes_holdweapon_noswing', playRate = random.uniform(0.69999999999999996, 1.5))
                     else:
                         actorIval = self.actorInterval(self.currentWeapon.painAnim, playRate = random.uniform(0.69999999999999996, 1.5))
                         if WeaponGlobals.getIsStaffAttackSkill(skillId):
                             skillInfo = WeaponGlobals.getSkillAnimInfo(skillId)
                             getOuchSfxFunc = skillInfo[WeaponGlobals.OUCH_SFX_INDEX]
                             if getOuchSfxFunc:
                                 ouchSfx = getOuchSfxFunc()
                             
                         else:
                             ouchSfx = self.getSfx('pain')
                 elif not self.avatarType.isA(AvatarTypes.Creature) and skillEffectId == WeaponGlobals.C_KNOCKDOWN:
                     actorIval = Sequence(self.actorInterval('injured_fall', playRate = 1.5, blendOutT = 0), self.actorInterval('injured_standup', playRate = 1.5, blendInT = 0))
                 elif not self.avatarType.isA(AvatarTypes.Creature) and effectId == WeaponGlobals.VFX_BLIND:
                     actorIval = self.actorInterval('sand_in_eyes', playRate = random.uniform(0.69999999999999996, 1.5))
                 else:
                     actorIval = self.actorInterval('idle_hit', playRate = random.uniform(0.69999999999999996, 1.5))
                 if ouchSfx:
                     self.ouchAnim = Sequence(Func(base.playSfx, ouchSfx, node = self, cutoff = 75), actorIval)
                 else:
                     self.ouchAnim = actorIval
                 self.ouchAnim.start()
             
         skillEffectId == WeaponGlobals.C_KNOCKDOWN
     
     if self.combatEffect:
         self.combatEffect.destroy()
         self.combatEffect = None
     
     self.combatEffect = CombatEffect.CombatEffect(effectId, multihit, attacker, skillResult)
     self.combatEffect.reparentTo(self)
     self.combatEffect.setPos(self, pos[0], pos[1], pos[2])
     if not WeaponGlobals.getIsDollAttackSkill(skillId) and not WeaponGlobals.getIsStaffAttackSkill(skillId):
         if not WeaponGlobals.isSelfUseSkill(skillId):
             if attacker and not attacker.isEmpty():
                 self.combatEffect.lookAt(attacker)
             
             self.combatEffect.setH(self.combatEffect, 180)
         
     
     skillEffects = self.getSkillEffects()
     if WeaponGlobals.C_MELEE_SHIELD in skillEffects:
         if WeaponGlobals.getAttackClass(skillId) == WeaponGlobals.AC_COMBAT:
             self.pulseGhostGuardEffect(attacker, Vec4(0, 0, 0, 1), wantBlending = False)
         
     elif WeaponGlobals.C_MISSILE_SHIELD in skillEffects:
         if WeaponGlobals.getAttackClass(skillId) == WeaponGlobals.AC_MISSILE:
             self.pulseGhostGuardEffect(attacker, Vec4(1, 1, 1, 1), wantBlending = True)
         
     elif WeaponGlobals.C_MAGIC_SHIELD in skillEffects:
         if WeaponGlobals.getAttackClass(skillId) == WeaponGlobals.AC_MAGIC:
             self.pulseGhostGuardEffect(attacker, Vec4(0.5, 0.29999999999999999, 1, 1), wantBlending = True)
         
     
     self.combatEffect.play()
     if WeaponGlobals.getIsDollAttackSkill(skillId):
         self.voodooSmokeEffect2 = AttuneSmoke.getEffect()
         if self.voodooSmokeEffect2:
             self.voodooSmokeEffect2.reparentTo(self)
             self.voodooSmokeEffect2.setPos(0, 0, 0.20000000000000001)
             self.voodooSmokeEffect2.play()