/// <summary> /// Process the monster's fight. /// </summary> /// <param name="monster"></param> private void ProcessMonsterFight(IMonsterEntity monster) { if (monster.Battle.Target.IsDead) { monster.Follow.Reset(); monster.Battle.Reset(); return; } if (monster.Follow.IsFollowing) { if (monster.Moves.SpeedFactor != 2f) { monster.Moves.SpeedFactor = 2; _moverPacketFactory.SendSpeedFactor(monster, monster.Moves.SpeedFactor); } if (monster.Object.Position.IsInCircle(monster.Follow.Target.Object.Position, monster.Follow.FollowDistance)) { if (monster.Timers.NextAttackTime <= Time.TimeInMilliseconds()) { _battleSystem.MeleeAttack(monster, monster.Battle.Target, ObjectMessageType.OBJMSG_ATK1, monster.Data.AttackSpeed); monster.Timers.NextAttackTime = (long)(Time.TimeInMilliseconds() + monster.Data.ReAttackDelay); } } else { _followSystem.Follow(monster, monster.Battle.Target); } } else { _followSystem.Follow(monster, monster.Battle.Target); } }
/// <summary> /// Update monster moves. /// </summary> /// <param name="monster"></param> private void ProcessMonsterMovements(IMonsterEntity monster) { if (monster.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_STAND)) { if (monster.Timers.NextMoveTime < Time.TimeInSeconds()) { monster.Object.MovingFlags &= ~ObjectState.OBJSTA_STAND; monster.Object.MovingFlags |= ObjectState.OBJSTA_FMOVE; monster.Moves.DestinationPosition.Copy(monster.Region.GetRandomPosition()); monster.Object.Angle = Vector3.AngleBetween(monster.Object.Position, monster.Moves.DestinationPosition); _moverPacketFactory.SendDestinationPosition(monster); _moverPacketFactory.SendDestinationAngle(monster, false); } else if (monster.Moves.ReturningToOriginalPosition) { monster.Attributes[DefineAttributes.HP] = monster.Data.AddHp; _moverPacketFactory.SendUpdateAttributes(monster, DefineAttributes.HP, monster.Attributes[DefineAttributes.HP]); monster.Moves.ReturningToOriginalPosition = false; } else if (monster.Moves.SpeedFactor >= 2f) { monster.Moves.SpeedFactor = 1f; _moverPacketFactory.SendSpeedFactor(monster, monster.Moves.SpeedFactor); } } }
/// <inheritdoc /> public IMapLayer CreateLayer(IMapInstance parentMapInstance, int layerId) { var mapLayer = ActivatorUtilities.CreateInstance <MapLayer>(_serviceProvider, parentMapInstance, layerId); foreach (IMapRegion region in parentMapInstance.Regions) { if (region is IMapRespawnRegion respawnRegion) { if (respawnRegion.ObjectType == WorldObjectType.Mover) { for (int i = 0; i < respawnRegion.Count; i++) { IMonsterEntity monster = _monsterFactory.CreateMonster(parentMapInstance, mapLayer, respawnRegion.ModelId, respawnRegion); mapLayer.AddEntity(monster); } } else if (respawnRegion.ObjectType == WorldObjectType.Item) { var item = _itemFactory.CreateItem(respawnRegion.ModelId, 0, 0, 0); for (int i = 0; i < respawnRegion.Count; ++i) { IItemEntity itemEntity = _itemFactory.CreateItemEntity(parentMapInstance, mapLayer, item); itemEntity.Object.Position = respawnRegion.GetRandomPosition(); itemEntity.Region = respawnRegion; mapLayer.AddEntity(itemEntity); } } } } return(mapLayer); }
private void ResetMonster(IMonsterEntity monster) { monster.Timers.NextMoveTime = Time.TimeInSeconds() + RandomHelper.LongRandom(5, 15); monster.Object.Spawned = true; monster.Object.Position = monster.Region.GetRandomPosition(); monster.Moves.DestinationPosition = monster.Object.Position.Clone(); monster.Moves.SpeedFactor = 1; monster.Health.Hp = monster.Data.AddHp; monster.Health.Mp = monster.Data.AddMp; }
/// <summary> /// Resets a monster. /// </summary> /// <param name="monster"></param> private void ResetMonster(IMonsterEntity monster) { monster.Timers.NextMoveTime = Time.TimeInSeconds() + RandomHelper.LongRandom(5, 15); monster.Object.Spawned = true; monster.Object.Position = monster.Region.GetRandomPosition(); monster.Object.MovingFlags = ObjectState.OBJSTA_STAND; monster.Moves.DestinationPosition.Reset(); monster.Moves.SpeedFactor = 1; monster.Battle.Reset(); monster.Follow.Reset(); monster.Attributes[DefineAttributes.HP] = monster.Data.AddHp; monster.Attributes[DefineAttributes.MP] = monster.Data.AddMp; }
public DefaultMonsterBehavior(IMonsterEntity monster, IOptions <WorldConfiguration> worldConfiguration, IGameResources gameResources, IMobilitySystem mobilitySystem, IBattleSystem battleSystem, IFollowSystem followSystem, IDropSystem dropSystem, IMoverPacketFactory moverPacketFactory) { _monster = monster; _worldConfiguration = worldConfiguration.Value; _gameResources = gameResources; _mobilitySystem = mobilitySystem; _battleSystem = battleSystem; _followSystem = followSystem; _dropSystem = dropSystem; _moverPacketFactory = moverPacketFactory; }
/// <inheritdoc /> public void Execute(IPlayerEntity player, object[] parameters) { if (parameters.Length <= 0 || parameters.Length > 2) { throw new ArgumentException($"Create monster command must have 1 or 2 parameters.", nameof(parameters)); } if (!int.TryParse((string)parameters[0], out int monsterId)) { throw new ArgumentException($"Cannot convert the first parameter in int.", nameof(parameters)); } int quantityToSpawn = 1; if (parameters.Length == 2) { if (!int.TryParse((string)parameters[1], out quantityToSpawn)) { throw new ArgumentException($"Cannot convert the second parameter in int.", nameof(parameters)); } } _logger.LogTrace($"{player.Object.Name} want to spawn {quantityToSpawn} mmonster"); const int sizeOfSpawnArea = 13; const int respawnTime = 65535; IMapInstance currentMap = player.Object.CurrentMap; IMapLayer currentMapLayer = currentMap.GetMapLayer(player.Object.LayerId); Vector3 currentPosition = player.Object.Position.Clone(); var respawnRegion = new MapRespawnRegion((int)currentPosition.X - sizeOfSpawnArea / 2, (int)currentPosition.Z - sizeOfSpawnArea / 2, sizeOfSpawnArea, sizeOfSpawnArea, respawnTime, WorldObjectType.Mover, monsterId, quantityToSpawn); for (int i = 0; i < quantityToSpawn; i++) { IMonsterEntity monsterToCreate = _monsterFactory.CreateMonster(currentMap, currentMapLayer, monsterId, respawnRegion, true); monsterToCreate.Object.Position = player.Object.Position.Clone(); currentMapLayer.AddEntity(monsterToCreate); } }
private static InPacket GenerateInMonster(IMonsterEntity monster) { NpcMonsterDto npcMonster = monster.NpcMonster; return(new InPacket { VisualType = VisualType.Monster, Name = npcMonster.Id.ToString(), TransportId = monster.MapMonster.Id.ToString(), PositionX = monster.Position.X, PositionY = monster.Position.Y, DirectionType = monster.DirectionType, InMonsterSubPacket = new InMonsterSubPacket { HpPercentage = monster.HpPercentage, MpPercentage = monster.MpPercentage, Unknown1 = 0, Unknown2 = 0, Unknown3 = 0, Unknown4 = -1, NoAggressiveIcon = npcMonster.NoAggresiveIcon, Unknown5 = 0, Unknown6 = -1, Unknown7 = "-", Unknown8 = 0, Unknown9 = -1, Unknown10 = 0, Unknown11 = 0, Unknown12 = 0, Unknown13 = 0, Unknown14 = 0, Unknown15 = 0, Unknown16 = 0, Unknown17 = 0 } }); }
/// <summary> /// Calculates the given monster defense. /// </summary> /// <param name="defenderMonster">Monster entity defending an attack.</param> /// <param name="attackFlags">Attack flags.</param> /// <returns>Monster's defense.</returns> private int GetMonsterDefense(IMonsterEntity defenderMonster, AttackFlags attackFlags) { var monsterDefenseArmor = attackFlags.HasFlag(AttackFlags.AF_MAGIC) ? defenderMonster.Data.MagicResitance : defenderMonster.Data.NaturalArmor; return((int)(monsterDefenseArmor / 7f + 1)); }