Exemplo n.º 1
0
        public void Hit(NpcInst attacker, int damage, bool fromFront = true)
        {
            var strm = BaseInst.GetScriptVobStream();

            strm.Write((byte)ScriptVobMessageIDs.HitMessage);
            strm.Write((ushort)attacker.ID);
            BaseInst.SendScriptVobStream(strm);

            int protection = Protection;
            var armor      = GetArmor();

            if (armor != null)
            {
                protection += armor.Protection;
            }

            // two weapons
            ItemInst otherMelee;

            if ((otherMelee = GetLeftHand()) != null && otherMelee.ItemType == ItemTypes.Wep1H)
            {
                protection -= otherMelee.Damage / 4;
            }

            damage -= protection;


            if (damage <= 0)
            {
                damage = 1;
            }

            int resultingHP = GetHealth() - damage;

            if (DropUnconsciousOnDeath && resultingHP <= 1)
            {
                resultingHP = 1;
                DropUnconscious(UnconsciousDuration, !fromFront);
            }

            SetHealth(resultingHP);
            sOnHit?.Invoke(attacker, this, damage);
            OnHit?.Invoke(attacker, this, damage);
            LastHitMove = GameTime.Ticks;
        }
Exemplo n.º 2
0
        private void CalcHit()
        {
            try
            {
                if (IsDead || FightAnimation == null || IsUnconscious)
                {
                    return;
                }

                Vec3f  attPos = GetPosition();
                Angles attAng = GetAngles();

                int baseDamage = 5 + Damage;

                ItemInst weapon;
                if ((weapon = GetDrawnWeapon()) != null)
                {
                    baseDamage += weapon.Damage;
                }

                // two weapons
                if ((weapon = GetLeftHand()) != null && weapon.ItemType == ItemTypes.Wep1H)
                {
                    baseDamage += weapon.Damage / 4;
                }

                float weaponRange = GetFightRange();
                BaseInst.World.ForEachNPCRough(attPos, GUCScripts.BiggestNPCRadius + weaponRange,
                                               npc => // fixme: enemy model radius
                {
                    NpcInst target = (NpcInst)npc.ScriptObject;
                    if (target == this || target.IsDead || target.IsUnconscious)
                    {
                        return;
                    }

                    if (!AllowHitEvent.TrueForAll(this, target) ||
                        !AllowHitAttacker.TrueForAll(this, target) ||
                        !target.AllowHitTarget.TrueForAll(this, target))
                    {
                        return;
                    }

                    float realRange = weaponRange + target.ModelDef.Radius;
                    if (target.CurrentFightMove == FightMoves.Dodge)
                    {
                        realRange /= 3.0f;     // decrease radius if target is backing up
                    }

                    Vec3f targetPos = npc.Position + npc.GetAtVector() * target.ModelDef.CenterOffset;

                    if ((targetPos - attPos).GetLength() > realRange)
                    {
                        return;     // not in range
                    }

                    float hitHeight;
                    float hitYaw;
                    if (CurrentFightMove == FightMoves.Left || CurrentFightMove == FightMoves.Right)
                    {
                        hitHeight = target.ModelDef.HalfHeight;
                        hitYaw    = Angles.PI * 0.4f;
                    }
                    else
                    {
                        hitHeight = target.ModelDef.HalfHeight + ModelDef.HalfHeight;
                        hitYaw    = Angles.PI * 0.2f;
                    }

                    if (Math.Abs(targetPos.Y - attPos.Y) > hitHeight)
                    {
                        return;     // not same height
                    }

                    float yaw = Angles.GetYawFromAtVector(targetPos - attPos);
                    if (Math.Abs(Angles.Difference(yaw, attAng.Yaw)) > hitYaw)
                    {
                        return;     // target is not in front of attacker
                    }

                    float tdiff = Math.Abs(Angles.Difference(target.GetAngles().Yaw, yaw));
                    if (target.CurrentFightMove == FightMoves.Parry && tdiff > Angles.PI / 2)     // parry 180 degrees
                    {
                        var strm = BaseInst.GetScriptVobStream();
                        strm.Write((byte)ScriptVobMessageIDs.ParryMessage);
                        strm.Write((ushort)npc.ID);
                        BaseInst.SendScriptVobStream(strm);
                    }
                    else     // HIT
                    {
                        int damage = baseDamage;
                        if (CurrentFightMove == FightMoves.Left || CurrentFightMove == FightMoves.Right)
                        {
                            damage -= 2;
                        }
                        else if (CurrentFightMove == FightMoves.Fwd)
                        {
                            damage += (ComboNum - 1) * 2;
                        }
                        else if (CurrentFightMove == FightMoves.Run)
                        {
                            damage += 6;
                            if (Environment.InAir) // super jump attack
                            {
                                damage += 2;       // not too much because you can always jump
                            }

                            if (target.Environment.InAir)
                            {
                                damage += 2;
                            }
                        }

                        bool frontAttack;
                        if (tdiff < Angles.PI / 4)     // backstab
                        {
                            damage     += 4;
                            frontAttack = false;
                        }
                        else
                        {
                            frontAttack = true;
                        }

                        target.Hit(this, damage, frontAttack);
                    }
                });
            }
            catch (Exception e)
            {
                Logger.Log("CalcHit of npc " + ID + " " + BaseInst.HP + " " + e);
            }
        }