Пример #1
0
 public ChestBonusRoomObj()
 {
     this.m_chestList = new List<ChestObj>();
     this.m_elf = new NpcObj("Elf_Character");
     this.m_elf.Scale = new Vector2(2f, 2f);
     this.m_gate = new PhysicsObj("CastleEntranceGate_Sprite", null);
     this.m_gate.IsWeighted = false;
     this.m_gate.IsCollidable = true;
     this.m_gate.CollisionTypeTag = 1;
     this.m_gate.Layer = -1f;
 }
Пример #2
0
 public override void Dispose()
 {
     if (!base.IsDisposed)
     {
         this.m_elf = null;
         this.m_gate = null;
         this.m_chestList.Clear();
         this.m_chestList = null;
         base.Dispose();
     }
 }
Пример #3
0
 public CastleEntranceRoomObj()
 {
     this.m_castleGate = new PhysicsObj("CastleEntranceGate_Sprite", null);
     this.m_castleGate.IsWeighted = false;
     this.m_castleGate.IsCollidable = true;
     this.m_castleGate.CollisionTypeTag = 1;
     this.m_castleGate.Layer = -1f;
     this.m_castleGate.OutlineWidth = 2;
     base.GameObjList.Add(this.m_castleGate);
     this.m_teleporter = new TeleporterObj();
     base.GameObjList.Add(this.m_teleporter);
 }
Пример #4
0
    public static bool TestCollision(PhysicsObj a, PhysicsObj b, out Vector3 normal, out float penetration)
    {
        normal = Vector3.zero;
        penetration = 0;

        Vector3 diff = a.position - b.position;
        //diff.y = 0;
        normal = diff.normalized;
        if (diff.sqrMagnitude == 0)
            return false;

        float distance = diff.magnitude;
        penetration = b.HalfSize + a.HalfSize - distance;
        if (penetration > 0)
            return true;

        return false;
    }
Пример #5
0
        public void SwitchToMeleeAttack()
        {
            if (IsDead)
            {
                return;
            }

            var weapon = GetEquippedMissileWeapon();
            var ammo   = GetEquippedAmmo();

            if (weapon == null && ammo == null)
            {
                return;
            }

            var actionChain = new ActionChain();

            EnqueueMotion_Force(actionChain, MotionStance.NonCombat, MotionCommand.Ready, (MotionCommand)CurrentMotionState.Stance);

            EnqueueMotion_Force(actionChain, MotionStance.HandCombat, MotionCommand.Ready, MotionCommand.NonCombat);

            actionChain.AddAction(this, () =>
            {
                if (IsDead)
                {
                    return;
                }

                // actually destroys the missile weapon + ammo here,
                // to ensure they can't be re-selected from inventory
                if (weapon != null)
                {
                    TryUnwieldObjectWithBroadcasting(weapon.Guid, out _, out _);
                    weapon.Destroy();
                }

                if (ammo != null)
                {
                    TryUnwieldObjectWithBroadcasting(ammo.Guid, out _, out _);
                    ammo.Destroy();
                }

                EquipInventoryItems(true);

                var innerChain = new ActionChain();

                EnqueueMotion_Force(innerChain, MotionStance.NonCombat, MotionCommand.Ready, (MotionCommand)CurrentMotionState.Stance);

                innerChain.AddAction(this, () =>
                {
                    if (IsDead)
                    {
                        return;
                    }

                    //DoAttackStance();

                    // inlined DoAttackStance() / slightly modified -- do not rely on SetCombatMode() for stance swapping time in 1 action,
                    // as it doesn't support that anymore

                    var newStanceTime = SetCombatMode(CombatMode.Melee);

                    NextMoveTime = NextAttackTime = Timers.RunningTime + newStanceTime;

                    PrevAttackTime = NextMoveTime - (AiUseMagicDelay ?? 3.0f);

                    PhysicsObj.StartTimer();

                    // end inline

                    ResetAttack();

                    SwitchWeaponsPending = false;

                    // this is an unfortunate hack to fix the following scenario:

                    // since this function can be called at any point in time now,
                    // including when LaunchMissile -> EnqueueMotion is in the middle of an action queue,
                    // CurrentMotionState.Stance can get reset to the previous combat stance if that happens

                    var newStance = CurrentMotionState.Stance;

                    var swapChain = new ActionChain();
                    swapChain.AddDelaySeconds(2.0f);
                    swapChain.AddAction(this, () => CurrentMotionState.Stance = newStance);
                    swapChain.EnqueueChain();
                });
                innerChain.EnqueueChain();
            });
            actionChain.EnqueueChain();
        }
Пример #6
0
 public void add_static_object(PhysicsObj obj)
 {
     StaticObjects.Add(obj);
 }
Пример #7
0
 public static void ParseRooms(string filePath, ContentManager contentManager = null, bool isDLCMap = false)
 {
     CultureInfo cultureInfo = (CultureInfo)CultureInfo.CurrentCulture.Clone();
     cultureInfo.NumberFormat.CurrencyDecimalSeparator = ".";
     XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
     xmlReaderSettings.IgnoreComments = true;
     xmlReaderSettings.IgnoreWhitespace = true;
     XmlReader xmlReader;
     if (contentManager == null)
     {
         xmlReader = XmlReader.Create(filePath, xmlReaderSettings);
     }
     else
     {
         xmlReader = XmlReader.Create(contentManager.RootDirectory + "\\Levels\\" + filePath + ".xml", xmlReaderSettings);
     }
     RoomObj roomObj = null;
     RoomObj roomObj2 = null;
     RoomObj roomObj3 = null;
     RoomObj roomObj4 = null;
     RoomObj roomObj5 = null;
     while (xmlReader.Read())
     {
         if (xmlReader.NodeType == XmlNodeType.Element)
         {
             if (xmlReader.Name == "RoomObject")
             {
                 roomObj = new RoomObj();
                 LevelParser.ParseGenericXML(xmlReader, roomObj);
                 if (isDLCMap)
                 {
                     roomObj.IsDLCMap = true;
                 }
                 roomObj2 = (roomObj.Clone() as RoomObj);
                 roomObj3 = (roomObj.Clone() as RoomObj);
                 roomObj4 = (roomObj.Clone() as RoomObj);
                 roomObj5 = (roomObj.Clone() as RoomObj);
             }
             if (xmlReader.Name == "GameObject")
             {
                 xmlReader.MoveToAttribute("Type");
                 string value = xmlReader.Value;
                 GameObj gameObj = null;
                 string key;
                 switch (key = value)
                 {
                 case "CollHullObj":
                     gameObj = new TerrainObj(0, 0);
                     break;
                 case "DoorObj":
                     gameObj = new DoorObj(roomObj, 0, 0, GameTypes.DoorType.OPEN);
                     break;
                 case "ChestObj":
                     if (xmlReader.MoveToAttribute("Fairy"))
                     {
                         if (bool.Parse(xmlReader.Value))
                         {
                             gameObj = new FairyChestObj(null);
                             (gameObj as ChestObj).ChestType = 4;
                         }
                         else
                         {
                             gameObj = new ChestObj(null);
                         }
                     }
                     else
                     {
                         gameObj = new ChestObj(null);
                     }
                     break;
                 case "HazardObj":
                     gameObj = new HazardObj(0, 0);
                     break;
                 case "BorderObj":
                     gameObj = new BorderObj();
                     break;
                 case "EnemyObj":
                     xmlReader.MoveToAttribute("Procedural");
                     if (!bool.Parse(xmlReader.Value))
                     {
                         xmlReader.MoveToAttribute("EnemyType");
                         byte enemyType = byte.Parse(xmlReader.Value, NumberStyles.Any, cultureInfo);
                         xmlReader.MoveToAttribute("Difficulty");
                         GameTypes.EnemyDifficulty difficulty = (GameTypes.EnemyDifficulty)Enum.Parse(typeof(GameTypes.EnemyDifficulty), xmlReader.Value, true);
                         gameObj = EnemyBuilder.BuildEnemy((int)enemyType, null, null, null, difficulty, false);
                         if (xmlReader.MoveToAttribute("Flip") && bool.Parse(xmlReader.Value))
                         {
                             gameObj.Flip = SpriteEffects.FlipHorizontally;
                         }
                         if (xmlReader.MoveToAttribute("InitialDelay"))
                         {
                             (gameObj as EnemyObj).InitialLogicDelay = float.Parse(xmlReader.Value, NumberStyles.Any, cultureInfo);
                         }
                     }
                     else
                     {
                         xmlReader.MoveToAttribute("EnemyType");
                         string value2 = xmlReader.Value;
                         gameObj = new EnemyTagObj();
                         (gameObj as EnemyTagObj).EnemyType = value2;
                     }
                     break;
                 case "EnemyOrbObj":
                 {
                     xmlReader.MoveToAttribute("OrbType");
                     int orbType = int.Parse(xmlReader.Value, NumberStyles.Any, cultureInfo);
                     bool flag = false;
                     if (xmlReader.MoveToAttribute("IsWaypoint"))
                     {
                         flag = bool.Parse(xmlReader.Value);
                     }
                     if (flag)
                     {
                         gameObj = new WaypointObj();
                         (gameObj as WaypointObj).OrbType = orbType;
                     }
                     else
                     {
                         gameObj = new EnemyOrbObj();
                         (gameObj as EnemyOrbObj).OrbType = orbType;
                         if (xmlReader.MoveToAttribute("ForceFlying"))
                         {
                             (gameObj as EnemyOrbObj).ForceFlying = bool.Parse(xmlReader.Value);
                         }
                     }
                     break;
                 }
                 case "SpriteObj":
                     xmlReader.MoveToAttribute("SpriteName");
                     if (xmlReader.Value == "LightSource_Sprite")
                     {
                         gameObj = new LightSourceObj();
                     }
                     else
                     {
                         gameObj = new SpriteObj(xmlReader.Value);
                     }
                     break;
                 case "PhysicsObj":
                 {
                     xmlReader.MoveToAttribute("SpriteName");
                     gameObj = new PhysicsObj(xmlReader.Value, null);
                     PhysicsObj physicsObj = gameObj as PhysicsObj;
                     physicsObj.CollisionTypeTag = 5;
                     physicsObj.CollidesBottom = false;
                     physicsObj.CollidesLeft = false;
                     physicsObj.CollidesRight = false;
                     break;
                 }
                 case "PhysicsObjContainer":
                 {
                     bool flag2 = false;
                     if (xmlReader.MoveToAttribute("Breakable"))
                     {
                         flag2 = bool.Parse(xmlReader.Value);
                     }
                     xmlReader.MoveToAttribute("SpriteName");
                     if (flag2)
                     {
                         gameObj = new BreakableObj(xmlReader.Value);
                     }
                     else
                     {
                         gameObj = new PhysicsObjContainer(xmlReader.Value, null);
                     }
                     break;
                 }
                 case "ObjContainer":
                     xmlReader.MoveToAttribute("SpriteName");
                     gameObj = new ObjContainer(xmlReader.Value);
                     break;
                 case "PlayerStartObj":
                     gameObj = new PlayerStartObj();
                     break;
                 }
                 LevelParser.ParseGenericXML(xmlReader, gameObj);
                 GameTypes.LevelType levelType = GameTypes.LevelType.NONE;
                 if (xmlReader.MoveToAttribute("LevelType"))
                 {
                     levelType = (GameTypes.LevelType)int.Parse(xmlReader.Value, NumberStyles.Any, cultureInfo);
                 }
                 if (levelType == GameTypes.LevelType.CASTLE)
                 {
                     LevelParser.StoreObj(gameObj, roomObj2);
                     LevelParser.StoreSwappedObj(gameObj, GameTypes.LevelType.DUNGEON, roomObj3);
                     LevelParser.StoreSwappedObj(gameObj, GameTypes.LevelType.TOWER, roomObj5);
                     LevelParser.StoreSwappedObj(gameObj, GameTypes.LevelType.GARDEN, roomObj4);
                     SpriteObj spriteObj = gameObj as SpriteObj;
                     if (spriteObj != null && spriteObj.SpriteName == "CastleAssetFrame_Sprite")
                     {
                         spriteObj.ChangeSprite("FramePicture" + CDGMath.RandomInt(1, 16) + "_Sprite");
                     }
                 }
                 else if (levelType == GameTypes.LevelType.DUNGEON)
                 {
                     LevelParser.StoreObj(gameObj, roomObj3);
                 }
                 else if (levelType == GameTypes.LevelType.TOWER)
                 {
                     LevelParser.StoreObj(gameObj, roomObj5);
                 }
                 else if (levelType == GameTypes.LevelType.GARDEN)
                 {
                     LevelParser.StoreObj(gameObj, roomObj4);
                 }
                 else
                 {
                     LevelParser.StoreObj(gameObj, roomObj2);
                     LevelParser.StoreObj(gameObj, roomObj3);
                     LevelParser.StoreObj(gameObj, roomObj5);
                     LevelParser.StoreObj(gameObj, roomObj4);
                     LevelParser.StoreObj(gameObj, roomObj);
                 }
                 if (LevelEV.RUN_TESTROOM && (levelType == LevelEV.TESTROOM_LEVELTYPE || levelType == GameTypes.LevelType.CASTLE))
                 {
                     if (levelType == LevelEV.TESTROOM_LEVELTYPE)
                     {
                         LevelParser.StoreObj(gameObj, roomObj);
                     }
                     else if (levelType == GameTypes.LevelType.CASTLE)
                     {
                         LevelParser.StoreSwappedObj(gameObj, LevelEV.TESTROOM_LEVELTYPE, roomObj);
                     }
                 }
                 if (gameObj is PlayerStartObj)
                 {
                     RoomObj expr_65E = roomObj;
                     expr_65E.Name += "DEBUG_ROOM";
                 }
             }
         }
         else if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "RoomObject")
         {
             if (roomObj.X < 10000f && roomObj.Name != "Boss" && roomObj.Name != "ChallengeBoss")
             {
                 if (!roomObj.Name.Contains("DEBUG_ROOM"))
                 {
                     if (roomObj.AddToCastlePool)
                     {
                         LevelBuilder2.StoreRoom(roomObj2, GameTypes.LevelType.CASTLE);
                         LevelBuilder2.StoreSpecialRoom(roomObj2, GameTypes.LevelType.CASTLE, false);
                     }
                     if (roomObj.AddToDungeonPool)
                     {
                         LevelBuilder2.StoreRoom(roomObj3, GameTypes.LevelType.DUNGEON);
                         LevelBuilder2.StoreSpecialRoom(roomObj3, GameTypes.LevelType.DUNGEON, false);
                     }
                     if (roomObj.AddToGardenPool)
                     {
                         LevelBuilder2.StoreRoom(roomObj4, GameTypes.LevelType.GARDEN);
                         LevelBuilder2.StoreSpecialRoom(roomObj4, GameTypes.LevelType.GARDEN, false);
                     }
                     if (roomObj.AddToTowerPool)
                     {
                         LevelBuilder2.StoreRoom(roomObj5, GameTypes.LevelType.TOWER);
                         LevelBuilder2.StoreSpecialRoom(roomObj5, GameTypes.LevelType.TOWER, false);
                     }
                 }
                 if (roomObj.Name.Contains("DEBUG_ROOM"))
                 {
                     roomObj.Name = roomObj.Name.Replace("DEBUG_ROOM", "");
                     if (LevelEV.TESTROOM_LEVELTYPE != GameTypes.LevelType.CASTLE)
                     {
                         LevelBuilder2.StoreSpecialRoom(roomObj, GameTypes.LevelType.CASTLE, true);
                     }
                     LevelBuilder2.StoreSpecialRoom(roomObj, LevelEV.TESTROOM_LEVELTYPE, true);
                 }
             }
             if (roomObj.X < 10000f && (roomObj.Name == "Boss" || roomObj.Name == "ChallengeBoss"))
             {
                 LevelBuilder2.StoreSpecialRoom(roomObj, GameTypes.LevelType.CASTLE, false);
             }
         }
     }
 }
Пример #8
0
 public ShadowObj(PhysicsObj physObj, ObjCell cell)
 {
     PhysObj = physObj;
     Cell    = cell;
 }
Пример #9
0
 public void InitObject(PhysicsObj obj, ObjectInfoState objectState)
 {
     ObjectInfo.Init(obj, objectState);
 }
Пример #10
0
        public static MoveToManager Create(PhysicsObj obj, WeenieObject wobj)
        {
            var moveToManager = new MoveToManager(obj, wobj);

            return(moveToManager);
        }
Пример #11
0
 public void SetObject(PhysicsObj physObj)
 {
 }
Пример #12
0
 public static StickyManager Create(PhysicsObj obj)
 {
     return(new StickyManager(obj));
 }
Пример #13
0
 public bool CreateParticleEmitter(PhysicsObj obj, int emitterInfoID, int partIdx, AFrame offset, int emitterID)
 {
     return(false);
 }
Пример #14
0
        /// <summary>
        /// For monster and CombatPet FindNextTarget
        /// - for monsters, contains players and combat pets
        /// - for combat pets, contains monsters
        /// </summary>
        private bool AddVisibleTarget(PhysicsObj obj, bool clamp = true, bool foeType = false)
        {
            if (PhysicsObj.WeenieObj.IsCombatPet)
            {
                // only tracking monsters
                if (!obj.WeenieObj.IsMonster)
                {
                    Console.WriteLine($"{PhysicsObj.Name}.ObjectMaint.AddVisibleTarget({obj.Name}): tried to add a non-monster");
                    return(false);
                }
            }
            else if (PhysicsObj.WeenieObj.IsFactionMob)
            {
                // only tracking players, combat pets, and monsters of differing faction
                if (!obj.IsPlayer && !obj.WeenieObj.IsCombatPet && (!obj.WeenieObj.IsMonster || PhysicsObj.WeenieObj.SameFaction(obj)))
                {
                    Console.WriteLine($"{PhysicsObj.Name}.ObjectMaint.AddVisibleTarget({obj.Name}): tried to add a non-player / non-combat pet / non-opposing faction mob");
                    return(false);
                }
            }
            else
            {
                // handle special case:
                // we want to select faction mobs for monsters inverse targets,
                // but not add to the original monster
                if (obj.WeenieObj.IsFactionMob)
                {
                    obj.ObjMaint.AddVisibleTarget(PhysicsObj);
                    return(false);
                }

                // handle special case:
                // if obj has a FoeType of this creature, and this creature doesn't have a FoeType for obj,
                // we only want to perform the inverse
                if (obj.WeenieObj.FoeType != null && obj.WeenieObj.FoeType == PhysicsObj.WeenieObj.WorldObject?.CreatureType &&
                    (PhysicsObj.WeenieObj.FoeType == null || obj.WeenieObj.WorldObject != null && PhysicsObj.WeenieObj.FoeType != obj.WeenieObj.WorldObject.CreatureType))
                {
                    obj.ObjMaint.AddVisibleTarget(PhysicsObj);
                    return(false);
                }

                // only tracking players and combat pets
                if (!obj.IsPlayer && !obj.WeenieObj.IsCombatPet && PhysicsObj.WeenieObj.FoeType == null)
                {
                    Console.WriteLine($"{PhysicsObj.Name}.ObjectMaint.AddVisibleTarget({obj.Name}): tried to add a non-player / non-combat pet");
                    return(false);
                }
            }
            if (PhysicsObj.DatObject)
            {
                Console.WriteLine($"{PhysicsObj.Name}.ObjectMaint.AddVisibleTarget({obj.Name}): tried to add player for dat object");
                return(false);
            }

            if (clamp && InitialClamp && obj.IsPlayer && !obj.ObjMaint.KnownObjects.ContainsKey(obj.ID))
            {
                var distSq = PhysicsObj.Position.Distance2DSquared(obj.Position);

                if (distSq > InitialClamp_DistSq)
                {
                    return(false);
                }
            }

            // TryAdd for existing keys still modifies collection?
            if (VisibleTargets.ContainsKey(obj.ID))
            {
                return(false);
            }

            //Console.WriteLine($"{PhysicsObj.Name} ({PhysicsObj.ID:X8}).ObjectMaint.AddVisibleTarget({obj.Name})");

            VisibleTargets.Add(obj.ID, obj);

            // maintain inverse for monsters / combat pets
            if (!obj.IsPlayer)
            {
                obj.ObjMaint.AddVisibleTarget(PhysicsObj);
            }

            return(true);
        }
Пример #15
0
 public StickyManager(PhysicsObj obj)
 {
     Init();
     SetPhysicsObject(obj);
 }
Пример #16
0
 private bool RemoveRetaliateTarget(PhysicsObj obj)
 {
     return(RetaliateTargets.Remove(obj.ID));
 }
Пример #17
0
 private bool RemoveVisibleTarget(PhysicsObj obj)
 {
     //Console.WriteLine($"{PhysicsObj.Name} ({PhysicsObj.ID:X8}).ObjectMaint.RemoveVisibleTarget({obj.Name})");
     return(VisibleTargets.Remove(obj.ID));
 }
Пример #18
0
 public ObjectMaint(PhysicsObj obj)
 {
     PhysicsObj = obj;
 }
Пример #19
0
 public static void AddStaticAnimatingObject(PhysicsObj obj)
 {
     StaticAnimatingObjects.Add(obj);
 }
Пример #20
0
        public void HandleActionEnterPkLite()
        {
            // ensure permanent npk
            if (PlayerKillerStatus != PlayerKillerStatus.NPK || MinimumTimeSincePk != null)
            {
                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.OnlyNonPKsMayEnterPKLite));
                return;
            }

            if (TooBusyToRecall)
            {
                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.YoureTooBusy));
                return;
            }

            EnqueueBroadcast(new GameMessageSystemChat($"{Name} is looking for a fight!", ChatMessageType.Broadcast), LocalBroadcastRange);

            // perform pk lite entry motion / effect

            IsBusy = true;

            var prevStance = CurrentMotionState.Stance;

            var actionChain = new ActionChain();

            var animTime = 0.0f;

            animTime += EnqueueMotion_Force(actionChain, MotionStance.NonCombat, MotionCommand.EnterPKLite);

            actionChain.AddAction(this, () =>
            {
                if (PropertyManager.GetBool("allow_pkl_bump").Item)
                {
                    // check for collisions
                    PlayerKillerStatus = PlayerKillerStatus.PKLite;

                    var colliding = PhysicsObj.ethereal_check_for_collisions();

                    if (colliding)
                    {
                        // try initial placement
                        var result = PhysicsObj.SetPositionSimple(PhysicsObj.Position, true);

                        if (result == SetPositionError.OK)
                        {
                            // handle landblock update?
                            SyncLocation();

                            // force broadcast
                            Sequences.GetNextSequence(SequenceType.ObjectForcePosition);
                            SendUpdatePosition();
                        }
                    }
                }
                UpdateProperty(this, PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.PKLite, true);

                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.YouAreNowPKLite));
            });

            // return to previous stance, if applicable
            if (prevStance != MotionStance.NonCombat)
            {
                animTime += EnqueueMotion_Force(actionChain, prevStance, MotionCommand.Ready, MotionCommand.NonCombat);
            }

            actionChain.AddAction(this, () => IsBusy = false);

            actionChain.EnqueueChain();
        }
Пример #21
0
 public static void RemoveStaticAnimatingObject(PhysicsObj obj)
 {
     StaticAnimatingObjects.Remove(obj);
 }
Пример #22
0
        public void HandleActionJump(JumpPack jump)
        {
            StartJump = new ACE.Entity.Position(Location);
            //Console.WriteLine($"JumpPack: Velocity: {jump.Velocity}, Extent: {jump.Extent}");

            var strength = Strength.Current;
            var capacity = EncumbranceSystem.EncumbranceCapacity((int)strength, AugmentationIncreasedCarryingCapacity);
            var burden   = EncumbranceSystem.GetBurden(capacity, EncumbranceVal ?? 0);

            // calculate stamina cost for this jump
            var extent      = Math.Clamp(jump.Extent, 0.0f, 1.0f);
            var staminaCost = MovementSystem.JumpStaminaCost(extent, burden, PKTimerActive);

            //Console.WriteLine($"Strength: {strength}, Capacity: {capacity}, Encumbrance: {EncumbranceVal ?? 0}, Burden: {burden}, StaminaCost: {staminaCost}");

            // ensure player has enough stamina to jump

            /*if (staminaCost > Stamina.Current)
             * {
             *  // get adjusted power
             *  extent = MovementSystem.GetJumpPower(Stamina.Current, burden, false);
             *
             *  staminaCost = (int)Stamina.Current;
             *
             *  // adjust jump velocity
             *  var velocityZ = MovementSystem.GetJumpHeight(burden, GetCreatureSkill(Skill.Jump).Current, extent, 1.0f);
             *
             *  jump.Velocity.Z = velocityZ;
             * }*/

            LastJumpTime = DateTime.UtcNow;

            UpdateVitalDelta(Stamina, -staminaCost);

            //Console.WriteLine($"Jump velocity: {jump.Velocity}");

            // TODO: have server verify / scale magnitude
            if (FastTick)
            {
                if (!PhysicsObj.IsMovingOrAnimating)
                {
                    //PhysicsObj.UpdateTime = PhysicsTimer.CurrentTime - Physics.PhysicsGlobals.MinQuantum;
                    PhysicsObj.UpdateTime = PhysicsTimer.CurrentTime;
                }

                // perform jump in physics engine
                PhysicsObj.TransientState &= ~(Physics.TransientStateFlags.Contact | Physics.TransientStateFlags.WaterContact);
                PhysicsObj.calc_acceleration();
                PhysicsObj.set_on_walkable(false);
                PhysicsObj.set_local_velocity(jump.Velocity, false);

                if (CombatMode == CombatMode.Magic && MagicState.IsCasting)
                {
                    FailCast();
                }
            }
            else
            {
                PhysicsObj.UpdateTime = PhysicsTimer.CurrentTime;

                // set jump velocity
                //var glob_velocity = Vector3.Transform(jump.Velocity, Location.Rotation);
                //PhysicsObj.set_velocity(glob_velocity, true);

                // perform jump in physics engine
                PhysicsObj.TransientState &= ~(Physics.TransientStateFlags.Contact | Physics.TransientStateFlags.WaterContact);
                PhysicsObj.calc_acceleration();
                PhysicsObj.set_on_walkable(false);
                PhysicsObj.set_local_velocity(jump.Velocity, false);
            }

            // this shouldn't be needed, but without sending this update motion / simulated movement event beforehand,
            // running forward and then performing a charged jump does an uncharged shallow arc jump instead
            // this hack fixes that...
            var movementData = new MovementData(this);

            movementData.IsAutonomous = true;
            movementData.MovementType = MovementType.Invalid;
            movementData.Invalid      = new MovementInvalid(movementData);
            EnqueueBroadcast(new GameMessageUpdateMotion(this, movementData));

            // broadcast jump
            EnqueueBroadcast(new GameMessageVectorUpdate(this));

            if (MagicState.IsCasting && RecordCast.Enabled)
            {
                RecordCast.OnJump(jump);
            }
        }
Пример #23
0
 public void SetPhysicsObject(PhysicsObj obj)
 {
     PhysicsObj = obj;
 }
Пример #24
0
        public void OnMoveToState_ClientMethod(MoveToState moveToState)
        {
            var rawState  = moveToState.RawMotionState;
            var prevState = LastMoveToState?.RawMotionState ?? RawMotionState.None;

            var mvp = new Physics.Animation.MovementParameters();

            mvp.HoldKeyToApply = rawState.CurrentHoldKey;

            if (!PhysicsObj.IsMovingOrAnimating)
            {
                PhysicsObj.UpdateTime = PhysicsTimer.CurrentTime;
            }

            // ForwardCommand
            if (rawState.ForwardCommand != MotionCommand.Invalid)
            {
                // press new key
                if (prevState.ForwardCommand == MotionCommand.Invalid)
                {
                    PhysicsObj.DoMotion((uint)MotionCommand.Ready, mvp);
                    PhysicsObj.DoMotion((uint)rawState.ForwardCommand, mvp);
                }
                // press alternate key
                else if (prevState.ForwardCommand != rawState.ForwardCommand)
                {
                    PhysicsObj.DoMotion((uint)rawState.ForwardCommand, mvp);
                }
            }
            else if (prevState.ForwardCommand != MotionCommand.Invalid)
            {
                // release key
                PhysicsObj.StopMotion((uint)prevState.ForwardCommand, mvp, true);
            }

            // StrafeCommand
            if (rawState.SidestepCommand != MotionCommand.Invalid)
            {
                // press new key
                if (prevState.SidestepCommand == MotionCommand.Invalid)
                {
                    PhysicsObj.DoMotion((uint)rawState.SidestepCommand, mvp);
                }
                // press alternate key
                else if (prevState.SidestepCommand != rawState.SidestepCommand)
                {
                    PhysicsObj.DoMotion((uint)rawState.SidestepCommand, mvp);
                }
            }
            else if (prevState.SidestepCommand != MotionCommand.Invalid)
            {
                // release key
                PhysicsObj.StopMotion((uint)prevState.SidestepCommand, mvp, true);
            }

            // TurnCommand
            if (rawState.TurnCommand != MotionCommand.Invalid)
            {
                // press new key
                if (prevState.TurnCommand == MotionCommand.Invalid)
                {
                    PhysicsObj.DoMotion((uint)rawState.TurnCommand, mvp);
                }
                // press alternate key
                else if (prevState.TurnCommand != rawState.TurnCommand)
                {
                    PhysicsObj.DoMotion((uint)rawState.TurnCommand, mvp);
                }
            }
            else if (prevState.TurnCommand != MotionCommand.Invalid)
            {
                // release key
                PhysicsObj.StopMotion((uint)prevState.TurnCommand, mvp, true);
            }
        }
Пример #25
0
 public bool Execute(PhysicsObj obj)
 {
     return(false);
 }
Пример #26
0
        /// <summary>
        /// Used by physics engine to actually update a player position
        /// Automatically notifies clients of updated position
        /// </summary>
        /// <param name="newPosition">The new position being requested, before verification through physics engine</param>
        /// <returns>TRUE if object moves to a different landblock</returns>
        public bool UpdatePlayerPosition(ACE.Entity.Position newPosition, bool forceUpdate = false)
        {
            //Console.WriteLine($"{Name}.UpdatePlayerPhysics({newPosition}, {forceUpdate}, {Teleporting})");
            bool verifyContact = false;

            // possible bug: while teleporting, client can still send AutoPos packets from old landblock
            if (Teleporting && !forceUpdate)
            {
                return(false);
            }

            // pre-validate movement
            if (!ValidateMovement(newPosition))
            {
                log.Error($"{Name}.UpdatePlayerPosition() - movement pre-validation failed from {Location} to {newPosition}");
                return(false);
            }

            try
            {
                if (!forceUpdate) // This is needed beacuse this function might be called recursively
                {
                    stopwatch.Restart();
                }

                var success = true;

                if (PhysicsObj != null)
                {
                    var distSq = Location.SquaredDistanceTo(newPosition);

                    if (distSq > PhysicsGlobals.EpsilonSq)
                    {
                        /*var p = new Physics.Common.Position(newPosition);
                         * var dist = PhysicsObj.Position.Distance(p);
                         * Console.WriteLine($"Dist: {dist}");*/

                        if (newPosition.Landblock == 0x18A && Location.Landblock != 0x18A)
                        {
                            log.Info($"{Name} is getting swanky");
                        }

                        if (!Teleporting)
                        {
                            var blockDist = PhysicsObj.GetBlockDist(Location.Cell, newPosition.Cell);

                            // verify movement
                            if (distSq > MaxSpeedSq && blockDist > 1)
                            {
                                //Session.Network.EnqueueSend(new GameMessageSystemChat("Movement error", ChatMessageType.Broadcast));
                                log.Warn($"MOVEMENT SPEED: {Name} trying to move from {Location} to {newPosition}, speed: {Math.Sqrt(distSq)}");
                                return(false);
                            }

                            // verify z-pos
                            if (blockDist == 0 && LastGroundPos != null && newPosition.PositionZ - LastGroundPos.PositionZ > 10 && DateTime.UtcNow - LastJumpTime > TimeSpan.FromSeconds(1) && GetCreatureSkill(Skill.Jump).Current < 1000)
                            {
                                verifyContact = true;
                            }
                        }

                        var curCell = LScape.get_landcell(newPosition.Cell);
                        if (curCell != null)
                        {
                            //if (PhysicsObj.CurCell == null || curCell.ID != PhysicsObj.CurCell.ID)
                            //PhysicsObj.change_cell_server(curCell);

                            PhysicsObj.set_request_pos(newPosition.Pos, newPosition.Rotation, curCell, Location.LandblockId.Raw);
                            if (FastTick)
                            {
                                success = PhysicsObj.update_object_server_new();
                            }
                            else
                            {
                                success = PhysicsObj.update_object_server();
                            }

                            if (PhysicsObj.CurCell == null && curCell.ID >> 16 != 0x18A)
                            {
                                PhysicsObj.CurCell = curCell;
                            }

                            if (verifyContact && !PhysicsObj.TransientState.HasFlag(TransientStateFlags.OnWalkable))
                            {
                                log.Warn($"z-pos hacking detected for {Name}, lastGroundPos: {LastGroundPos.ToLOCString()} - requestPos: {newPosition.ToLOCString()}");
                                Location = new ACE.Entity.Position(LastGroundPos);
                                Sequences.GetNextSequence(SequenceType.ObjectForcePosition);
                                SendUpdatePosition();
                                return(false);
                            }

                            CheckMonsters();
                        }
                    }
                    else
                    {
                        PhysicsObj.Position.Frame.Orientation = newPosition.Rotation;
                    }
                }

                // double update path: landblock physics update -> updateplayerphysics() -> update_object_server() -> Teleport() -> updateplayerphysics() -> return to end of original branch
                if (Teleporting && !forceUpdate)
                {
                    return(true);
                }

                if (!success)
                {
                    return(false);
                }

                var landblockUpdate = Location.Cell >> 16 != newPosition.Cell >> 16;

                Location = newPosition;

                if (RecordCast.Enabled)
                {
                    RecordCast.Log($"CurPos: {Location.ToLOCString()}");
                }

                if (RequestedLocationBroadcast || DateTime.UtcNow - LastUpdatePosition >= MoveToState_UpdatePosition_Threshold)
                {
                    SendUpdatePosition();
                }
                else
                {
                    Session.Network.EnqueueSend(new GameMessageUpdatePosition(this));
                }

                if (!InUpdate)
                {
                    LandblockManager.RelocateObjectForPhysics(this, true);
                }

                return(landblockUpdate);
            }
            finally
            {
                if (!forceUpdate) // This is needed beacuse this function might be called recursively
                {
                    var elapsedSeconds = stopwatch.Elapsed.TotalSeconds;
                    ServerPerformanceMonitor.AddToCumulativeEvent(ServerPerformanceMonitor.CumulativeEventHistoryType.Player_Tick_UpdateObjectPhysics, elapsedSeconds);
                    if (elapsedSeconds >= 0.100) // Yea, that ain't good....
                    {
                        log.Warn($"[PERFORMANCE][PHYSICS] {Guid}:{Name} took {(elapsedSeconds * 1000):N1} ms to process UpdatePlayerPosition() at loc: {Location}");
                    }
                    else if (elapsedSeconds >= 0.010)
                    {
                        log.Debug($"[PERFORMANCE][PHYSICS] {Guid}:{Name} took {(elapsedSeconds * 1000):N1} ms to process UpdatePlayerPosition() at loc: {Location}");
                    }
                }
            }
        }
Пример #27
0
 public void SetPlayer(PhysicsObj player)
 {
     Player = player;
 }
Пример #28
0
        /// <summary>
        /// Sets the corpse to the final position
        /// </summary>
        public void SetFinalPosition()
        {
            if (AttackTarget == null)
            {
                return;
            }

            var playerDir = AttackTarget.Location.GetCurrentDir();

            Location.Pos = AttackTarget.Location.Pos + playerDir * (AttackTarget.PhysicsObj.GetRadius() + PhysicsObj.GetRadius());
            SendUpdatePosition();
        }
Пример #29
0
        public void get_land_scenes()
        {
            // ported from Scenery
            Scenery = new List <PhysicsObj>();

            // get the landblock cell offsets
            var blockX = (ID >> 24) * 8;
            var blockY = (ID >> 16 & 0xFF) * 8;

            for (var i = 0; i < Terrain.Count; i++)
            {
                var terrain = Terrain[(int)i];

                var terrainType = terrain >> 2 & 0x1F;      // TerrainTypes table size = 32 (grass, desert, volcano, etc.)
                var sceneType   = terrain >> 11;            // SceneTypes table size = 89 total, 32 which can be indexed for each terrain type

                var sceneInfo = (int)DatManager.PortalDat.RegionDesc.TerrainInfo.TerrainTypes[terrainType].SceneTypes[sceneType];
                var scenes    = DatManager.PortalDat.RegionDesc.SceneInfo.SceneTypes[sceneInfo].Scenes;
                if (scenes.Count == 0)
                {
                    continue;
                }

                var cellX = i / LandDefs.VertexDim;
                var cellY = i % LandDefs.VertexDim;

                var globalCellX = (uint)(cellX + blockX);
                var globalCellY = (uint)(cellY + blockY);

                var cellMat   = globalCellY * (712977289 * globalCellX + 1813693831) - 1109124029 * globalCellX + 2139937281;
                var offset    = cellMat * 2.3283064e-10;
                var scene_idx = (int)(scenes.Count * offset);
                if (scene_idx >= scenes.Count)
                {
                    scene_idx = 0;
                }

                var sceneId = scenes[scene_idx];

                var scene = DatManager.PortalDat.ReadFromDat <Scene>(sceneId);

                var cellXMat = -1109124029 * globalCellX;
                var cellYMat = 1813693831 * globalCellY;
                cellMat = 1360117743 * globalCellX * globalCellY + 1888038839;

                for (uint j = 0; j < scene.Objects.Count; j++)
                {
                    var obj   = scene.Objects[(int)j];
                    var noise = (uint)(cellXMat + cellYMat - cellMat * (23399 + j)) * 2.3283064e-10;

                    if (noise < obj.Freq && obj.WeenieObj == 0)
                    {
                        var position = Displace(obj, globalCellX, globalCellY, j);

                        // ensure within landblock range, and not near road
                        var lx = cellX * LandDefs.CellLength + position.X;
                        var ly = cellY * LandDefs.CellLength + position.Y;

                        // TODO: ensure walkable slope
                        if (lx < 0 || ly < 0 || lx >= LandDefs.BlockLength || ly >= LandDefs.BlockLength || OnRoad(obj, lx, ly))
                        {
                            continue;
                        }

                        // load scenery
                        var pos = new Position(ID);
                        pos.Frame.Origin      = new Vector3(lx, ly, 0);
                        pos.Frame.Orientation = Quaternion.CreateFromYawPitchRoll(0, 0, RotateObj(obj, globalCellX, globalCellY, j));
                        var outside = LandDefs.AdjustToOutside(pos);
                        var cell    = get_landcell(pos.ObjCellID);
                        //if (cell == null) continue;

                        Polygon walkable    = null;
                        var     terrainPoly = cell.find_terrain_poly(pos.Frame.Origin, ref walkable);
                        walkable.Plane.set_height(ref pos.Frame.Origin);

                        // todo: collision detection
                        var physicsObj = PhysicsObj.makeObject(obj.ObjId, 0, false);
                        //physicsObj.set_initial_frame(pos.Frame);
                        physicsObj.add_obj_to_cell(cell, pos.Frame);
                        Scenery.Add(physicsObj);
                    }
                }
            }
            //Console.WriteLine("Landblock " + ID.ToString("X8") + " scenery count: " + Scenery.Count);
        }
Пример #30
0
        /// <summary>
        /// Returns the destination position the monster is attempting to move to
        /// to perform a melee attack
        /// </summary>
        public Vector3 GetDestination()
        {
            var dir = Vector3.Normalize(Location.ToGlobal() - AttackTarget.Location.ToGlobal());

            return(AttackTarget.Location.Pos + dir * (AttackTarget.PhysicsObj.GetRadius() + PhysicsObj.GetRadius()));
        }
Пример #31
0
 public void hide_object(PhysicsObj obj)
 {
     update_all_voyeur(obj, DetectionType.LeftDetection);
 }
Пример #32
0
 public override void Initialize()
 {
     this.m_gate = new PhysicsObj("CastleEntranceGate_Sprite", null);
     this.m_gate.IsWeighted = false;
     this.m_gate.IsCollidable = true;
     this.m_gate.CollisionTypeTag = 1;
     this.m_gate.Layer = -1f;
     this.m_gate.OutlineWidth = 2;
     base.GameObjList.Add(this.m_gate);
     Rectangle rectangle = default(Rectangle);
     Color[] array = new Color[]
     {
         Color.Red,
         Color.Blue,
         Color.Green,
         Color.Yellow,
         Color.Orange,
         Color.Purple,
         Color.Pink,
         Color.MediumTurquoise,
         Color.CornflowerBlue
     };
     foreach (GameObj current in base.GameObjList)
     {
         if (current is WaypointObj)
         {
             this.m_elf.X = current.X;
         }
         if (current.Name == "Balloon")
         {
             this.m_balloonList.Add(current as ObjContainer);
             (current as ObjContainer).GetChildAt(1).TextureColor = array[CDGMath.RandomInt(0, array.Length - 1)];
         }
     }
     foreach (TerrainObj current2 in base.TerrainObjList)
     {
         if (current2.Name == "Floor")
         {
             this.m_elf.Y = current2.Y - ((float)this.m_elf.Bounds.Bottom - this.m_elf.Y) - 2f;
         }
         if (current2.Name == "GatePosition")
         {
             rectangle = current2.Bounds;
         }
     }
     this.m_gate.X = (float)rectangle.X;
     this.m_gate.Y = (float)rectangle.Bottom;
     if (!base.IsReversed)
     {
         this.m_elf.Flip = SpriteEffects.FlipHorizontally;
     }
     base.GameObjList.Add(this.m_elf);
     foreach (TerrainObj current3 in base.TerrainObjList)
     {
         if (current3.Name == "Boundary")
         {
             current3.Visible = false;
             this.m_targetBounds = current3.Bounds;
             break;
         }
     }
     float num = 10f;
     float num2 = (float)(this.m_targetBounds.X + 40);
     float num3 = (float)this.m_targetBounds.Y;
     float num4 = (float)this.m_targetBounds.Width / num;
     float num5 = (float)this.m_targetBounds.Height / num;
     int num6 = 0;
     while ((float)num6 < num * num)
     {
         BreakableObj breakableObj = new BreakableObj("Target2_Character");
         breakableObj.X = num2;
         breakableObj.Y = num3;
         breakableObj.Scale = new Vector2(1.6f, 1.6f);
         breakableObj.OutlineWidth = 2;
         breakableObj.HitBySpellsOnly = true;
         breakableObj.IsWeighted = false;
         this.m_targetList.Add(breakableObj);
         breakableObj.SameTypesCollide = false;
         breakableObj.DropItem = false;
         base.GameObjList.Add(breakableObj);
         num2 += num4;
         if ((float)(num6 + 1) % num == 0f)
         {
             num2 = (float)(this.m_targetBounds.X + 40);
             num3 += num5;
         }
         num6++;
     }
     this.m_rewardChest = new ChestObj(null);
     this.m_rewardChest.ChestType = 3;
     if (!base.IsReversed)
     {
         this.m_rewardChest.Flip = SpriteEffects.FlipHorizontally;
         this.m_rewardChest.Position = new Vector2(this.m_elf.X + 100f, (float)(this.m_elf.Bounds.Bottom - this.m_rewardChest.Height - 8));
     }
     else
     {
         this.m_rewardChest.Position = new Vector2(this.m_elf.X - 150f, (float)(this.m_elf.Bounds.Bottom - this.m_rewardChest.Height - 8));
     }
     this.m_rewardChest.Visible = false;
     base.GameObjList.Add(this.m_rewardChest);
     base.Initialize();
 }
Пример #33
0
 public void SetPhysicsObject(PhysicsObj obj)
 {
     PhysicsObj = obj;
     apply_current_movement(true, true);
 }
Пример #34
0
        /// <summary>
        /// Starts the process of monster turning towards target
        /// </summary>
        public void StartTurn()
        {
            //if (Timers.RunningTime < NextMoveTime)
            //return;
            if (!MoveReady())
            {
                return;
            }

            if (DebugMove)
            {
                Console.WriteLine($"{Name} ({Guid}) - StartTurn, ranged={IsRanged}");
            }

            if (MoveSpeed == 0.0f)
            {
                GetMovementSpeed();
            }

            //Console.WriteLine($"[{Timers.RunningTime}] - {Name} ({Guid}) - starting turn");

            IsTurning = true;

            // send network actions
            var targetDist = GetDistanceToTarget();
            var turnTo     = IsRanged || (CurrentAttack == CombatType.Magic && targetDist <= GetSpellMaxRange());

            if (turnTo)
            {
                TurnTo(AttackTarget);
            }
            else
            {
                MoveTo(AttackTarget, RunRate);
            }

            // need turning listener?
            IsTurning      = false;
            IsMoving       = true;
            LastMoveTime   = Timers.RunningTime;
            NextCancelTime = LastMoveTime + ThreadSafeRandom.Next(2, 4);

            var mvp = GetMovementParameters();

            if (turnTo)
            {
                PhysicsObj.TurnToObject(AttackTarget.PhysicsObj.ID, mvp);
            }
            else
            {
                PhysicsObj.MoveToObject(AttackTarget.PhysicsObj, mvp);
            }

            if (!InitSticky)
            {
                PhysicsObj.add_moveto_listener(OnMoveComplete);

                PhysicsObj.add_sticky_listener(OnSticky);
                PhysicsObj.add_unsticky_listener(OnUnsticky);
                InitSticky = true;
            }
        }
Пример #35
0
        public static MotionInterp Create(PhysicsObj obj, WeenieObject wobj)
        {
            var motionInterp = new MotionInterp(obj, wobj);

            return(motionInterp);
        }
Пример #36
0
        /// <summary>
        /// Primary dispatch for monster think
        /// </summary>
        public void Monster_Tick(double currentUnixTime)
        {
            if (IsChessPiece && this is GamePiece gamePiece)
            {
                // faster than vtable?
                gamePiece.Tick(currentUnixTime);
                return;
            }

            if (IsPassivePet && this is Pet pet)
            {
                pet.Tick(currentUnixTime);
                return;
            }

            NextMonsterTickTime = currentUnixTime + monsterTickInterval;

            if (!IsAwake)
            {
                if (MonsterState == State.Return)
                {
                    MonsterState = State.Idle;
                }

                if (IsFactionMob)
                {
                    FactionMob_CheckMonsters();
                }

                return;
            }

            if (IsDead)
            {
                return;
            }

            HandleFindTarget();

            CheckMissHome();    // tickrate?

            if (AttackTarget == null && MonsterState != State.Return)
            {
                Sleep();
                return;
            }

            if (MonsterState == State.Return)
            {
                Movement();
                return;
            }

            var combatPet = this as CombatPet;

            var creatureTarget = AttackTarget as Creature;

            if (creatureTarget != null && (creatureTarget.IsDead || (combatPet == null && !IsVisibleTarget(creatureTarget))))
            {
                FindNextTarget();
                return;
            }

            if (firstUpdate)
            {
                if (CurrentMotionState.Stance == MotionStance.NonCombat)
                {
                    DoAttackStance();
                }

                if (IsAnimating)
                {
                    //PhysicsObj.ShowPendingMotions();
                    PhysicsObj.update_object();
                    return;
                }

                firstUpdate = false;
            }

            // select a new weapon if missile launcher is out of ammo
            var weapon = GetEquippedWeapon();

            /*if (weapon != null && weapon.IsAmmoLauncher)
             * {
             *  var ammo = GetEquippedAmmo();
             *  if (ammo == null)
             *      SwitchToMeleeAttack();
             * }*/

            if (weapon == null && CurrentAttack != null && CurrentAttack == CombatType.Missile)
            {
                EquipInventoryItems(true);
                DoAttackStance();
                CurrentAttack = null;
            }

            // decide current type of attack
            if (CurrentAttack == null)
            {
                CurrentAttack = GetNextAttackType();
                MaxRange      = GetMaxRange();

                //if (CurrentAttack == AttackType.Magic)
                //MaxRange = MaxMeleeRange;   // FIXME: server position sync
            }

            if (PhysicsObj.IsSticky)
            {
                UpdatePosition();
            }

            // get distance to target
            var targetDist = GetDistanceToTarget();

            //Console.WriteLine($"{Name} ({Guid}) - Dist: {targetDist}");

            if (CurrentAttack != CombatType.Missile)
            {
                if (targetDist > MaxRange || (!IsFacing(AttackTarget) && !IsSelfCast()))
                {
                    // turn / move towards
                    if (!IsTurning && !IsMoving)
                    {
                        StartTurn();
                    }
                    else
                    {
                        Movement();
                    }
                }
                else
                {
                    // perform attack
                    if (AttackReady())
                    {
                        Attack();
                    }
                }
            }
            else
            {
                if (IsTurning || IsMoving)
                {
                    Movement();
                    return;
                }

                if (!IsFacing(AttackTarget))
                {
                    StartTurn();
                }
                else if (targetDist <= MaxRange)
                {
                    // perform attack
                    if (AttackReady())
                    {
                        Attack();
                    }
                }
                else
                {
                    // monster switches to melee combat immediately,
                    // if target is beyond max range?

                    // should ranged mobs only get CurrentTargets within MaxRange?
                    //Console.WriteLine($"{Name}.MissileAttack({AttackTarget.Name}): targetDist={targetDist}, MaxRange={MaxRange}, switching to melee");
                    TrySwitchToMeleeAttack();
                }
            }

            // pets drawing aggro
            if (combatPet != null)
            {
                combatPet.PetCheckMonsters();
            }
        }
Пример #37
0
 public override void Dispose()
 {
     if (!base.IsDisposed)
     {
         this.m_castleGate = null;
         this.m_teleporter = null;
         this.m_bossDoor = null;
         this.m_bossDoorSprite = null;
         this.m_diary = null;
         this.m_speechBubble = null;
         this.m_mapText = null;
         this.m_mapIcon = null;
         base.Dispose();
     }
 }
Пример #38
0
 public override void Dispose()
 {
     if (!base.IsDisposed)
     {
         this.m_targetList.Clear();
         this.m_targetList = null;
         this.m_elf = null;
         this.m_axeIcons = null;
         this.m_gate = null;
         for (int i = 0; i < this.m_targetText.Count; i++)
         {
             this.m_targetText[i].Dispose();
             this.m_targetDataText[i].Dispose();
         }
         this.m_targetText.Clear();
         this.m_targetText = null;
         this.m_targetDataText.Clear();
         this.m_targetDataText = null;
         this.m_balloonList.Clear();
         this.m_balloonList = null;
         this.m_rewardChest = null;
         base.Dispose();
     }
 }