コード例 #1
0
        public void SetHealth(int hp, int hpmax)
        {
            if (HP <= 0 && hp > 0)
            {
                OnRevive?.Invoke(this);
            }

            BaseInst.SetHealth(hp, hpmax);
            if (hp <= 0)
            {
                if (IsSpawned && !IsPlayer)
                {
                    World.DespawnList_NPC.AddVob(this);
                }

                if (unconTimer != null && unconTimer.Started)
                {
                    unconTimer.Stop();
                }
            }

            if (hp <= 0)
            {
                _Uncon = Unconsciousness.None;
                OnDeath?.Invoke(this);
                sOnDeath?.Invoke(this);
            }
        }
コード例 #2
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);
        }
コード例 #3
0
        public void UnequipItem(ItemInst item)
        {
            BaseInst.UnequipItem(item.BaseInst);


            OnUnequip?.Invoke(item);
        }
コード例 #4
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);
        }
コード例 #5
0
        /*
         * basis -> item = iteminstance <- scripts
         * basis -> iteminstance = itemdefinition <- scripts
         */

        public void SetMovement(NPCMovement state)
        {
            if (state == this.Movement)
            {
                return;
            }

            BaseInst.SetMovement(state);
        }
コード例 #6
0
        public virtual void Despawn()
        {
            if (!this.IsSpawned)
            {
                return;
            }

            WorldInst oldWorld = this.World;

            BaseInst.Despawn();
            OnDespawn?.Invoke(this, oldWorld);
        }
コード例 #7
0
        public void EquipItem(NPCSlots slot, ItemInst item)
        {
            if (item.BaseInst.Slot == (int)slot)
            {
                return;
            }


            BaseInst.EquipItem((int)slot, item.BaseInst);


            OnEquip?.Invoke(item);
        }
コード例 #8
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);
        }
コード例 #9
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;
        }
コード例 #10
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);
        }
コード例 #11
0
 public ItemInst GetEquipmentBySlot(NPCSlots slotNum)
 {
     return(BaseInst.TryGetEquippedItem((int)slotNum, out Item item) ? (ItemInst)item.ScriptObject : null);
 }
コード例 #12
0
 public void SetFightMode(bool fightMode)
 {
     BaseInst.SetFightMode(fightMode);
 }
コード例 #13
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);
            }
        }