Ejemplo n.º 1
0
        /// <inheritdoc />
        public void CalculatePosition(ILivingEntity entity)
        {
            if (!entity.Object.Spawned)
            {
                return;
            }

            if (entity.Moves.DestinationPosition.IsZero() || entity.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_STAND))
            {
                return;
            }

            if (entity.Follow.IsFollowing)
            {
                if (entity.Object.Position.IsInCircle(entity.Follow.Target.Object.Position, entity.Follow.FollowDistance))
                {
                    entity.Moves.DestinationPosition.Reset();
                    entity.Object.MovingFlags &= ~ObjectState.OBJSTA_FMOVE;
                    entity.Object.MovingFlags |= ObjectState.OBJSTA_STAND;
                    entity.Behavior?.OnArrived();
                }
                else
                {
                    entity.Moves.DestinationPosition.Copy(entity.Follow.Target.Object.Position);
                    entity.Object.MovingFlags &= ~ObjectState.OBJSTA_STAND;
                    entity.Object.MovingFlags |= ObjectState.OBJSTA_FMOVE;
                }
            }

            Walk(entity);
        }
Ejemplo n.º 2
0
        public void Su_Lethal_Test()
        {
            using (GameContext context = CreateContext())
            {
                ICharacter    character = context.Character;
                ILivingEntity target    = TestFactory.CreateMonster();

                IMap map = TestFactory.CreateMap(character, target);

                context.Process(new Su
                {
                    CasterType    = character.EntityType,
                    CasterId      = character.Id,
                    TargetType    = target.EntityType,
                    TargetId      = target.Id,
                    SkillKey      = 254,
                    Damage        = 1000,
                    IsTargetAlive = false,
                    HpPercentage  = 0
                });

                Check.That(target.Map).IsNull();
                Check.That(map.Entities).Not.Contains(target);
                Check.That(target.HpPercentage).IsEqualTo(0);

                context.IsEventEmitted <EntityDamageEvent>(x => x.Caster.Equals(character) && x.Target.Equals(target) && x.Damage == 1000 && x.SkillKey == 254);
                context.IsEventEmitted <EntityDeathEvent>(x => x.Killer.Equals(character) && x.Entity.Equals(target));
            }
        }
Ejemplo n.º 3
0
        private void UpdatePosition(ILivingEntity entity, float x, float z)
        {
            if (entity is IPlayerEntity && entity.Moves.IsMovingWithKeyboard)
            {
                float angle     = entity.Object.Angle;
                var   movementX = (float)(Math.Sin(angle * (Math.PI / 180)) * Math.Sqrt(x * x + z * z));
                var   movementZ = (float)(Math.Cos(angle * (Math.PI / 180)) * Math.Sqrt(x * x + z * z));

                if (entity.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_FMOVE))
                {
                    entity.Object.Position.X += movementX;
                    entity.Object.Position.Z -= movementZ;
                }
                else if (entity.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_BMOVE))
                {
                    entity.Object.Position.X -= movementX;
                    entity.Object.Position.Z += movementZ;
                }
            }
            else
            {
                entity.Object.Position.X += x;
                entity.Object.Position.Z += z;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Sends a "name query" reply to the client.
        /// </summary>
        /// <param name="client">the client to send to</param>
        /// <param name="entity">the character information to be sent</param>
        public static void SendNameQueryReply(IPacketReceiver client, ILivingEntity entity)
        {
            using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_NAME_QUERY_RESPONSE))
            {
                entity.EntityId.WritePacked(packet);
                packet.Write((byte)0);                 // new in 3.1.0 - this is a type, ranging from 0-3
                packet.WriteCString(entity.Name);
                packet.Write((byte)0);                 // cross realm bg name? (256 bytes max)
                packet.Write((byte)entity.Race);
                packet.Write((byte)entity.Gender);
                packet.Write((byte)entity.Class);

                packet.Write((byte)0);                 // hasDeclinedNames

                //if (hasDeclinedNames)
                //{
                //    for (int i=0;i<4;i++)
                //    {
                //        packet.WriteCString("");
                //    }
                //}


                client.Send(packet, addEnd: false);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the magic skill factor based on the equiped weapon element type and skill element type.
        /// </summary>
        /// <param name="entity">Living entity.</param>
        /// <param name="skill">Skill.</param>
        /// <returns>Magic skill factor.</returns>
        private float GetMagicSkillFactor(ILivingEntity entity, SkillInfo skill)
        {
            const float DefaultMagicSkillFactor = 1.0f;

            if (entity is IPlayerEntity player)
            {
                Item        weapon            = player.Inventory.GetEquipedItem(ItemPartType.RightWeapon) ?? player.Hand;
                ElementType weaponElementType = weapon.Id != -1 ? weapon.Data.Element : ElementType.None;
                ElementType skillElementType  = skill.Data.Element.GetValueOrDefault(ElementType.None);

                if (skillElementType == weaponElementType)
                {
                    return(1.1f);
                }
                else if (
                    skillElementType == ElementType.Fire && weaponElementType == ElementType.Water ||
                    skillElementType == ElementType.Water && weaponElementType == ElementType.Electricity ||
                    skillElementType == ElementType.Electricity && weaponElementType == ElementType.Earth ||
                    skillElementType == ElementType.Wind && weaponElementType == ElementType.Fire
                    )
                {
                    return(0.9f);
                }
            }

            return(DefaultMagicSkillFactor);
        }
Ejemplo n.º 6
0
        /// <summary>Handles an incoming name query.</summary>
        /// <param name="client">the Session the incoming packet belongs to</param>
        /// <param name="packet">the full packet</param>
        public static void NameQueryRequest(IRealmClient client, RealmPacketIn packet)
        {
            EntityId      id     = packet.ReadEntityId();
            ILivingEntity entity = (ILivingEntity)client.ActiveCharacter;

            if ((int)entity.EntityId.Low != (int)id.Low)
            {
                entity = World.GetNamedEntity(id.Low) as ILivingEntity;
            }
            if (entity != null)
            {
                QueryHandler.SendNameQueryReply((IPacketReceiver)client, entity);
            }
            else
            {
                ServerApp <WCell.RealmServer.RealmServer> .IOQueue.AddMessage((IMessage) new Message((Action)(() =>
                {
                    CharacterRecord characterRecord = CharacterRecord.LoadRecordByEntityId(id.Low);
                    if (characterRecord == null)
                    {
                        QueryHandler.s_log.Warn("{0} queried name of non-existing Character: " + (object)id,
                                                (object)client);
                    }
                    else
                    {
                        QueryHandler.SendNameQueryReply((IPacketReceiver)client, (ILivingEntity)characterRecord);
                    }
                })));
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Handles an incoming name query.
        /// </summary>
        /// <param name="client">the Session the incoming packet belongs to</param>
        /// <param name="packet">the full packet</param>
        //[ClientPacketHandler((RealmServerOpCode.CMSG_NAME_QUERY)]
        public static void NameQueryRequest(IRealmClient client, RealmPacketIn packet)
        {
            var id = packet.ReadEntityId();

            ILivingEntity entity = client.ActiveCharacter;

            if (entity.EntityId.Low != id.Low)
            {
                entity = World.GetNamedEntity(id.Low) as ILivingEntity;
            }

            if (entity != null)
            {
                SendNameQueryReply(client, entity);
            }
            else
            {
                RealmServer.IOQueue.AddMessage(new Message(() =>
                {
                    var record = CharacterRecord.LoadRecordByEntityId(id.Low);
                    if (record == null)
                    {
                        s_log.Warn("{0} queried name of non-existing Character: " + id, client);
                    }
                    else
                    {
                        SendNameQueryReply(client, record);
                    }
                }));
            }
        }
Ejemplo n.º 8
0
 public AIBehaviorTree(AIGetToTargetActions aiToTarget, AIWeaponActions aiWA, ILivingEntity entity, ProjectileDetector projectileDetector)
 {
     this.aiToTarget         = aiToTarget;
     this.aiWeapon           = aiWA;
     this.entity             = entity;
     this.projectileDetector = projectileDetector;
 }
Ejemplo n.º 9
0
 public MeleeAttackEventArgs(ObjectMessageType attackType, ILivingEntity target, float attackSpeed, int unknownParameter)
 {
     this.AttackType       = attackType;
     this.Target           = target;
     this.AttackSpeed      = attackSpeed;
     this.UnknownParameter = unknownParameter;
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Executes a melee or magic skill and inflicts the damages to the target.
        /// </summary>
        /// <param name="caster">Living entity casting a skill.</param>
        /// <param name="target">Living target entity touched by the skill.</param>
        /// <param name="skill">Skill to be casted.</param>
        /// <param name="reduceCasterPoints">Value that indicates if it should reduce caster points or not.</param>
        private void ExecuteSkill(ILivingEntity caster, ILivingEntity target, SkillInfo skill, bool reduceCasterPoints = true)
        {
            ObjectMessageType skillMessageType = ObjectMessageType.OBJMSG_NONE;
            IAttackArbiter    attackArbiter    = null;

            switch (skill.Data.Type)
            {
            case SkillType.Magic:
                attackArbiter    = new MagicSkillAttackArbiter(caster, target, skill);
                skillMessageType = ObjectMessageType.OBJMSG_MAGICSKILL;
                break;

            case SkillType.Skill:
                attackArbiter    = new MeleeSkillAttackArbiter(caster, target, skill);
                skillMessageType = ObjectMessageType.OBJMSG_MELEESKILL;
                break;
            }

            _battleSystem.DamageTarget(caster, target, attackArbiter, skillMessageType);

            if (skill.LevelData.CooldownTime > 0)
            {
                skill.SetCoolTime(skill.LevelData.CooldownTime);
            }

            if (reduceCasterPoints)
            {
                ReduceCasterPoints(caster, skill);
            }
        }
Ejemplo n.º 11
0
        public void CMode_Unwear_Test()
        {
            using (GameContext context = CreateContext())
            {
                ICharacter    character = context.Character;
                ILivingEntity entity    = TestFactory.CreatePlayer();

                IMap map = TestFactory.CreateMap(character, entity);

                context.Process(new CMode
                {
                    EntityType   = entity.EntityType,
                    EntityId     = entity.Id,
                    MorphId      = 0,
                    MorphUpgrade = 13,
                    MorphDesign  = 11,
                    MorphBonus   = 0,
                    Size         = 10
                });

                Check.That(map.Entities).Contains(entity);
                Check.That(entity.MorphId).IsEqualTo(0);

                context.IsEventEmitted <SpecialistUnwearEvent>(x => x.Entity.Equals(entity));
            }
        }
Ejemplo n.º 12
0
        /// <inheritdoc />
        public AttackResult DamageTarget(ILivingEntity attacker, ILivingEntity defender, IAttackArbiter attackArbiter, ObjectMessageType attackType)
        {
            if (!CanAttack(attacker, defender))
            {
                ClearBattleTargets(defender);
                ClearBattleTargets(attacker);
                return(null);
            }

            if (defender is IPlayerEntity undyingPlayer)
            {
                if (undyingPlayer.PlayerData.Mode == ModeType.MATCHLESS_MODE)
                {
                    _logger.LogDebug($"{attacker.Object.Name} wasn't able to inflict any damages to {defender.Object.Name} because he is in undying mode");
                    return(null);
                }
            }

            AttackResult attackResult;

            if (attacker is IPlayerEntity player && player.PlayerData.Mode.HasFlag(ModeType.ONEKILL_MODE))
            {
                attackResult = new AttackResult
                {
                    Damages = defender.Attributes[DefineAttributes.HP],
                    Flags   = AttackFlags.AF_GENERIC
                };
            }
Ejemplo n.º 13
0
        /// <inheritdoc />
        public void OnKilled(ILivingEntity killerEntity)
        {
            _monster.Timers.DespawnTime = Time.TimeInSeconds() + 5; // TODO: Configure this timer on world configuration

            // Drop items
            int itemCount = 0;

            foreach (DropItemData dropItem in _monster.Data.DropItems)
            {
                if (itemCount >= _monster.Data.MaxDropItem)
                {
                    break;
                }

                long dropChance = RandomHelper.LongRandom(0, DropSystem.MaxDropChance);

                if (dropItem.Probability * _worldConfiguration.Rates.Drop >= dropChance)
                {
                    var item = new Item(dropItem.ItemId, 1, -1, -1, -1, (byte)RandomHelper.Random(0, dropItem.ItemMaxRefine));

                    _dropSystem.DropItem(_monster, item, killerEntity);
                    itemCount++;
                }
            }

            // Drop item kinds
            foreach (DropItemKindData dropItemKind in _monster.Data.DropItemsKind)
            {
                var itemsDataByItemKind = _gameResources.Items.Values.Where(x => x.ItemKind3 == dropItemKind.ItemKind && x.Rare >= dropItemKind.UniqueMin && x.Rare <= dropItemKind.UniqueMax);

                if (!itemsDataByItemKind.Any())
                {
                    continue;
                }

                var itemData = itemsDataByItemKind.ElementAt(RandomHelper.Random(0, itemsDataByItemKind.Count() - 1));

                int itemRefine = RandomHelper.Random(0, 10);

                for (int i = itemRefine; i >= 0; i--)
                {
                    long itemDropProbability = (long)(_gameResources.ExpTables.GetDropLuck(itemData.Level > 120 ? 119 : itemData.Level, itemRefine) * (_monster.Data.CorrectionValue / 100f));
                    long dropChance          = RandomHelper.LongRandom(0, DropSystem.MaxDropChance);

                    if (dropChance < itemDropProbability * _worldConfiguration.Rates.Drop)
                    {
                        var item = new Item(itemData.Id, 1, -1, -1, -1, (byte)itemRefine);

                        _dropSystem.DropItem(_monster, item, killerEntity);
                        break;
                    }
                }
            }

            // Drop gold
            int goldDropped = RandomHelper.Random(_monster.Data.DropGoldMin, _monster.Data.DropGoldMax);

            _dropSystem.DropGold(_monster, goldDropped, killerEntity);
        }
Ejemplo n.º 14
0
 public EntityDamageEvent(IClient client, ILivingEntity caster, ILivingEntity target, int skillKey, int damage)
 {
     Client   = client;
     Caster   = caster;
     Target   = target;
     SkillKey = skillKey;
     Damage   = damage;
 }
Ejemplo n.º 15
0
 public override void Attack(ILivingEntity target)
 {
     if (target == null)
     {
         return;
     }
     target.Damage(DamageCause.EntityAttack, AttackStrength, this);
 }
Ejemplo n.º 16
0
        /// <inheritdoc />
        public int CreateProjectile(ProjectileInfo projectile)
        {
            ILivingEntity livingEntity = projectile.Owner;
            int           projectileId = livingEntity.Battle.LastProjectileId++;

            livingEntity.Battle.Projectiles.Add(projectileId, projectile);

            return(projectileId);
        }
Ejemplo n.º 17
0
    private void OnTriggerEnter2D(Collider2D collision)
    {
        ILivingEntity other = collision.GetComponent <ILivingEntity>();

        if (other != null)
        {
            other.TakeDamage(other.health);
        }
    }
Ejemplo n.º 18
0
        /// <inheritdoc />
        public void Follow(ILivingEntity livingEntity, IWorldEntity targetEntity, float distance = 1f)
        {
            livingEntity.Follow.Target = targetEntity;
            livingEntity.Moves.DestinationPosition.Copy(targetEntity.Object.Position);
            livingEntity.Object.MovingFlags &= ~ObjectState.OBJSTA_STAND;
            livingEntity.Object.MovingFlags |= ObjectState.OBJSTA_FMOVE;

            _moverPacketFactory.SendFollowTarget(livingEntity, targetEntity, distance);
        }
Ejemplo n.º 19
0
        /// <inheritdoc />
        public void SendDie(IPlayerEntity player, ILivingEntity deadEntity, ILivingEntity killerEntity, ObjectMessageType motion)
        {
            using var packet = new FFPacket();

            packet.StartNewMergedPacket(deadEntity.Id, SnapshotType.MOVERDEATH);
            packet.Write((int)motion);
            packet.Write(killerEntity.Id);

            SendToVisible(packet, player, sendToPlayer: true);
        }
Ejemplo n.º 20
0
        /// <inheritdoc />
        public void Follow(ILivingEntity livingEntity, uint targetId, float distance = 1f)
        {
            var entityToFollow = livingEntity.FindEntity <IWorldEntity>(targetId);

            if (entityToFollow == null)
            {
                throw new ArgumentNullException(nameof(entityToFollow), $"Cannot find entity with object id: {targetId} around {livingEntity.Object.Name}");
            }

            Follow(livingEntity, entityToFollow, distance);
        }
Ejemplo n.º 21
0
        /// <inheritdoc />
        public void OnTargetKilled(ILivingEntity killedEntity)
        {
            if (killedEntity is IMonsterEntity deadMonster)
            {
                // Give experience
                _experienceSystem.GiveExeperience(_player, deadMonster.Data.Experience * _worldConfiguration.Rates.Experience);

                // Quest check
                _questSystem.UpdateQuestDiary(_player, QuestActionType.KillMonster, deadMonster.Data.Id, 1);
            }
        }
Ejemplo n.º 22
0
        public void Attack(ILivingEntity entity)
        {
            ISkill skill = Skills.FirstOrDefault();

            if (skill == null)
            {
                Logger.Warn("Can't found first skill");
                return;
            }

            Attack(skill, entity);
        }
Ejemplo n.º 23
0
        /// <inheritdoc />
        public void SendMeleeAttack(ILivingEntity attacker, ObjectMessageType motion, uint targetId, int unknwonParam, AttackFlags attackFlags)
        {
            using var packet = new FFPacket();

            packet.StartNewMergedPacket(attacker.Id, SnapshotType.MELEE_ATTACK);
            packet.Write((int)motion);
            packet.Write(targetId);
            packet.Write(unknwonParam);
            packet.Write((int)attackFlags);

            SendToVisible(packet, attacker);
        }
Ejemplo n.º 24
0
        public int DealDamageTo(ILivingEntity enemy)
        {
            if (!CanDealDamageTo(enemy))
            {
                return(0);
            }

            int damageDone = stats.GetRandomDamage() - enemy.Stats.Defence;

            damageDone = (damageDone < 0) ? 0 : damageDone;
            enemy.Stats.UpdateHealth(-damageDone);
            return(damageDone);
        }
Ejemplo n.º 25
0
        private float GetEntitySpeed(ILivingEntity entity)
        {
            float entitySpeed = entity.Moves.Speed * entity.Moves.SpeedFactor; // TODO: Add speed bonuses

            if (entity.Type == WorldEntityType.Monster)
            {
                entitySpeed /= 2f;
            }

            entitySpeed *= _updateRate;

            return(entitySpeed);
        }
Ejemplo n.º 26
0
        /// <inheritdoc />
        public void SendUseSkill(ILivingEntity player, IWorldEntity target, SkillInfo skill, int castingTime, SkillUseType skillUseType)
        {
            using var packet = new FFPacket();

            packet.StartNewMergedPacket(player.Id, SnapshotType.USESKILL);
            packet.Write(skill.SkillId);
            packet.Write(skill.Level);
            packet.Write(target.Id);
            packet.Write((int)skillUseType);
            packet.Write(castingTime);

            SendToVisible(packet, player, sendToPlayer: true);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Gets the hit rating of an entity.
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <returns></returns>
        private int GetHitRating(ILivingEntity entity)
        {
            if (entity is IPlayerEntity player)
            {
                return(player.Attributes[DefineAttributes.DEX]); // TODO: add dex bonus
            }
            else if (entity is IMonsterEntity monster)
            {
                return(monster.Data.HitRating);
            }

            return(0);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Gets the hit rating of an entity.
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <returns></returns>
        private int GetHitRating(ILivingEntity entity)
        {
            if (entity is IPlayerEntity player)
            {
                return(player.Statistics.Dexterity); // TODO: add dex bonus
            }
            else if (entity is IMonsterEntity monster)
            {
                return(monster.Data.HitRating);
            }

            return(0);
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Gets the escape rating of an entity.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int GetEspaceRating(ILivingEntity entity)
        {
            if (entity is IPlayerEntity player)
            {
                return((int)(player.Statistics.Dexterity * 0.5f)); // TODO: add dex bonus and DST_PARRY
            }
            else if (entity is IMonsterEntity monster)
            {
                return(monster.Data.EscapeRating);
            }

            return(0);
        }
Ejemplo n.º 30
0
        /// <inheritdoc />
        public void SendRangeAttack(ILivingEntity attacker, ObjectMessageType motion, uint targetId, int power, int projectileId)
        {
            using var packet = new FFPacket();

            packet.StartNewMergedPacket(attacker.Id, SnapshotType.RANGE_ATTACK);
            packet.Write((int)motion);
            packet.Write(targetId);
            packet.Write(power);
            packet.Write(0); // unused parameter, always 0
            packet.Write(projectileId);

            SendToVisible(packet, attacker);
        }
Ejemplo n.º 31
0
        public override void Attack(ILivingEntity target)
        {
            if (target == null)
                return;
            short weaponDmg = Inventory.ActiveItem.GetDamage();

            //Start Event
            EntityAttackEventArgs e = new EntityAttackEventArgs(this, weaponDmg, target);
            Server.PluginManager.CallEvent(Event.EntityAttack, e);
            if(e.EventCanceled) return;
            target = (LivingEntity)e.EntityToAttack;
            weaponDmg = e.Damage;
            //End Event

            Exhaustion += 300;
            
            target.Damage(DamageCause.EntityAttack, weaponDmg, this);
        }
Ejemplo n.º 32
0
 public abstract void Attack(ILivingEntity target);
Ejemplo n.º 33
0
 /// <summary>
 /// Determines whether this instance can see the specified entity.
 /// </summary>
 /// <returns>
 /// <c>true</c> if this instance can see the specified entity; otherwise, <c>false</c>.
 /// </returns>
 /// <param name='entity'>
 /// The entity to check for line of sight to.
 /// </param>
 public bool CanSee(ILivingEntity entity)
 {
     return this.World.RayTraceBlocks(new AbsWorldCoords(this.Position.X, this.Position.Y + this.EyeHeight, this.Position.Z), new AbsWorldCoords(entity.Position.X, entity.Position.Y + entity.EyeHeight, entity.Position.Z)) == null;
 }
Ejemplo n.º 34
0
Archivo: Mob.cs Proyecto: TheaP/c-raft
 public override void Attack(ILivingEntity target)
 {
     if (target == null)
         return;
     target.Damage(DamageCause.EntityAttack, AttackStrength, this);
 }
Ejemplo n.º 35
0
		/// <summary>
		/// Sends a "name query" reply to the client.
		/// </summary>
		/// <param name="client">the client to send to</param>
		/// <param name="entity">the character information to be sent</param>
		public static void SendNameQueryReply(IPacketReceiver client, ILivingEntity entity)
		{
			using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_NAME_QUERY_RESPONSE))
			{
				entity.EntityId.WritePacked(packet);
				packet.Write((byte)0);         // new in 3.1.0 - this is a type, ranging from 0-3
				packet.WriteCString(entity.Name);
				packet.Write((byte)0); // cross realm bg name? (256 bytes max)
				packet.Write((byte)entity.Race);
				packet.Write((byte)entity.Gender);
				packet.Write((byte)entity.Class);

				packet.Write((byte)0); // hasDeclinedNames

				//if (hasDeclinedNames)
				//{
				//    for (int i=0;i<4;i++)
				//    {
				//        packet.WriteCString("");
				//    }
				//}


				client.Send(packet);
			}
		}