Esempio n. 1
0
        public void DropUnconscious(long duration = -1, bool toFront = true)
        {
            var          cat = AniCatalog.Unconscious;
            ScriptAniJob job = toFront ? cat.DropFront : cat.DropBack;

            if (job != null)
            {
                ModelInst.StartAniJob(job);
            }

            _Uncon = toFront ? Unconsciousness.Front : Unconsciousness.Back;

            var strm = BaseInst.GetScriptVobStream();

            strm.Write((byte)ScriptVobMessageIDs.Uncon);
            strm.Write((byte)_Uncon);
            BaseInst.SendScriptVobStream(strm);

            if (duration >= 0)
            {
                if (unconTimer == null)
                {
                    unconTimer = new GUCTimer(LiftUnconsciousness);
                }

                unconTimer.SetInterval(duration);
                unconTimer.Start();
            }

            OnUnconChange?.Invoke(this);
        }
Esempio n. 2
0
        public void DoVoice(VoiceCmd cmd, bool shout = false)
        {
            var strm = BaseInst.GetScriptVobStream();

            strm.Write((byte)(shout ? ScriptVobMessageIDs.VoiceShout : ScriptVobMessageIDs.Voice));
            strm.Write((byte)cmd);
            BaseInst.SendScriptVobStream(strm);
        }
Esempio n. 3
0
        private void DoLiftUncon()
        {
            _Uncon = Unconsciousness.None;
            var strm = BaseInst.GetScriptVobStream();

            strm.Write((byte)ScriptVobMessageIDs.Uncon);
            strm.Write((byte)_Uncon);
            BaseInst.SendScriptVobStream(strm);

            int hp = HP + 25;

            SetHealth(hp > HPMax ? HPMax : hp);
            OnUnconChange?.Invoke(this);
        }
Esempio n. 4
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;
        }
Esempio n. 5
0
        public void DoClimb(ClimbMoves move, NPC.ClimbingLedge ledge)
        {
            ScriptAniJob job;

            switch (move)
            {
            case ClimbMoves.High:
                job = AniCatalog.Climbs.High;
                break;

            case ClimbMoves.Mid:
                job = AniCatalog.Climbs.Mid;
                break;

            case ClimbMoves.Low:
                job = AniCatalog.Climbs.Low;
                break;

            default:
                Logger.Log("Not existing climb move: " + move);
                return;
            }

            if (job == null)
            {
                return;
            }


            var stream = BaseInst.GetScriptVobStream();

            stream.Write((byte)ScriptVobMessageIDs.Climb);
            ledge.WriteStream(stream);
            BaseInst.SendScriptVobStream(stream);

            IsClimbing = true;
            ModelInst.StartAniJob(job, () => IsClimbing = false);
        }
Esempio n. 6
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);
            }
        }