/// <summary> /// Gets the player's max origin HP. /// </summary> /// <param name="player">Player.</param> /// <returns>Max Origin HP.</returns> public static int GetMaxOriginHp(IPlayerEntity player) { return(HealthFormulas.GetMaxOriginHp( player.Object.Level, player.Attributes[DefineAttributes.STA], player.PlayerData.JobData.MaxHpFactor)); }
/// <inheritdoc /> public void Execute(IEntity entity, SystemEventArgs args) { if (!(entity is IPlayerEntity player)) { this._logger.LogError($"Cannot execute DeathSystem. {entity.Object.Name} is not a player."); return; } IMapRevivalRegion revivalRegion = player.Object.CurrentMap.GetNearRevivalRegion(player.Object.Position); if (revivalRegion == null) { this._logger.LogError($"Cannot find any revival region for map '{player.Object.CurrentMap.Name}'."); return; } decimal recoveryRate = GameResources.Instance.Penalities.GetRevivalPenality(player.Object.Level) / 100; var jobData = player.PlayerData.JobData; int strength = player.Attributes[DefineAttributes.STR]; int stamina = player.Attributes[DefineAttributes.STA]; int dexterity = player.Attributes[DefineAttributes.DEX]; int intelligence = player.Attributes[DefineAttributes.INT]; player.Health.Hp = (int)(HealthFormulas.GetMaxOriginHp(player.Object.Level, stamina, jobData.MaxHpFactor) * recoveryRate); player.Health.Mp = (int)(HealthFormulas.GetMaxOriginMp(player.Object.Level, intelligence, jobData.MaxMpFactor, true) * recoveryRate); player.Health.Fp = (int)(HealthFormulas.GetMaxOriginFp(player.Object.Level, stamina, dexterity, strength, jobData.MaxFpFactor, true) * recoveryRate); if (player.Object.MapId != revivalRegion.MapId) { IMapInstance revivalMap = this._mapLoader.GetMapById(revivalRegion.MapId); if (revivalMap == null) { this._logger.LogError($"Cannot find revival map with id '{revivalRegion.MapId}'."); player.Connection.Server.DisconnectClient(player.Connection.Id); return; } revivalRegion = revivalMap.GetRevivalRegion(revivalRegion.Key); } var teleportEvent = new TeleportEventArgs(revivalRegion.MapId, revivalRegion.RevivalPosition.X, revivalRegion.RevivalPosition.Z); player.NotifySystem <TeleportSystem>(teleportEvent); WorldPacketFactory.SendMotion(player, ObjectMessageType.OBJMSG_ACC_STOP | ObjectMessageType.OBJMSG_STOP_TURN | ObjectMessageType.OBJMSG_STAND); WorldPacketFactory.SendPlayerRevival(player); WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.HP, player.Health.Hp); WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.MP, player.Health.Mp); WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.FP, player.Health.Fp); this.ProcessDeathPenality(player); }
/// <inheritdoc /> public void ResurectLodelight(IPlayerEntity player) { IMapRevivalRegion revivalRegion = player.Object.CurrentMap.GetNearRevivalRegion(player.Object.Position); if (revivalRegion == null) { _logger.LogError($"Cannot find any revival region for map '{player.Object.CurrentMap.Name}'."); return; } decimal recoveryRate = _gameResources.Penalities.GetRevivalPenality(player.Object.Level) / 100; var jobData = player.PlayerData.JobData; int strength = player.Attributes[DefineAttributes.STR]; int stamina = player.Attributes[DefineAttributes.STA]; int dexterity = player.Attributes[DefineAttributes.DEX]; int intelligence = player.Attributes[DefineAttributes.INT]; player.Attributes[DefineAttributes.HP] = (int)(HealthFormulas.GetMaxOriginHp(player.Object.Level, stamina, jobData.MaxHpFactor) * recoveryRate); player.Attributes[DefineAttributes.MP] = (int)(HealthFormulas.GetMaxOriginMp(player.Object.Level, intelligence, jobData.MaxMpFactor, true) * recoveryRate); player.Attributes[DefineAttributes.FP] = (int)(HealthFormulas.GetMaxOriginFp(player.Object.Level, stamina, dexterity, strength, jobData.MaxFpFactor, true) * recoveryRate); if (player.Object.MapId != revivalRegion.MapId) { IMapInstance revivalMap = _mapManager.GetMap(revivalRegion.MapId); if (revivalMap == null) { _logger.LogError($"Cannot find revival map with id '{revivalRegion.MapId}'."); // TODO: disconnect client //player.Connection.Server.DisconnectClient(player.Connection.Id); return; } revivalRegion = revivalMap.GetRevivalRegion(revivalRegion.Key); } _teleportSystem.Teleport(player, revivalRegion.MapId, revivalRegion.RevivalPosition.X, null, revivalRegion.RevivalPosition.Z); _moverPacketFactory.SendMotion(player, ObjectMessageType.OBJMSG_ACC_STOP | ObjectMessageType.OBJMSG_STOP_TURN | ObjectMessageType.OBJMSG_STAND); _playerPacketFactory.SendPlayerRevival(player); _moverPacketFactory.SendUpdateAttributes(player, DefineAttributes.HP, player.Attributes[DefineAttributes.HP]); _moverPacketFactory.SendUpdateAttributes(player, DefineAttributes.MP, player.Attributes[DefineAttributes.MP]); _moverPacketFactory.SendUpdateAttributes(player, DefineAttributes.FP, player.Attributes[DefineAttributes.FP]); ProcessDeathPenality(player); }
/// <summary> /// Process the idle heal. /// </summary> /// <param name="player">Player entity.</param> /// <param name="e">Idle recovery event args.</param> private void IdleHeal(IPlayerEntity player, IdleRecoveryEventArgs e) { int nextHealDelay = e.IsSitted ? NextIdleHealSit : NextIdleHealStand; player.Timers.NextHealTime = Time.TimeInSeconds() + nextHealDelay; if (player.Health.IsDead) { return; } int strength = player.Attributes[DefineAttributes.STR]; int stamina = player.Attributes[DefineAttributes.STA]; int dexterity = player.Attributes[DefineAttributes.DEX]; int intelligence = player.Attributes[DefineAttributes.INT]; int maxHp = HealthFormulas.GetMaxOriginHp(player.Object.Level, stamina, player.PlayerData.JobData.MaxHpFactor); int maxMp = HealthFormulas.GetMaxOriginMp(player.Object.Level, intelligence, player.PlayerData.JobData.MaxMpFactor, true); int maxFp = HealthFormulas.GetMaxOriginFp(player.Object.Level, stamina, dexterity, strength, player.PlayerData.JobData.MaxFpFactor, true); int recoveryHp = HealthFormulas.GetHpRecovery(maxHp, player.Object.Level, stamina, player.PlayerData.JobData.HpRecoveryFactor); int recoveryMp = HealthFormulas.GetMpRecovery(maxMp, player.Object.Level, intelligence, player.PlayerData.JobData.MpRecoveryFactor); int recoveryFp = HealthFormulas.GetFpRecovery(maxFp, player.Object.Level, stamina, player.PlayerData.JobData.FpRecoveryFactor); player.Health.Hp += recoveryHp; player.Health.Mp += recoveryMp; player.Health.Fp += recoveryFp; if (player.Health.Hp > maxHp) { player.Health.Hp = maxHp; } if (player.Health.Mp > maxMp) { player.Health.Mp = maxMp; } if (player.Health.Fp > maxFp) { player.Health.Fp = maxFp; } WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.HP, player.Health.Hp); WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.MP, player.Health.Mp); WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.FP, player.Health.Fp); }
/// <summary> /// Process the level up logic and reward attribution. /// </summary> /// <param name="player">Player entity.</param> /// <param name="statPoints">Statistics points.</param> private void ProcessLevelUp(IPlayerEntity player, ushort statPoints) { player.Object.Level += 1; if (player.Object.Level != player.PlayerData.DeathLevel) { player.Statistics.SkillPoints += (ushort)((player.Object.Level - 1) / 20 + 2); player.Statistics.StatPoints += statPoints; } var strength = player.Attributes[DefineAttributes.STR]; var stamina = player.Attributes[DefineAttributes.STA]; var dexterity = player.Attributes[DefineAttributes.DEX]; var intelligence = player.Attributes[DefineAttributes.INT]; player.PlayerData.Experience = 0; player.Attributes[DefineAttributes.HP] = HealthFormulas.GetMaxOriginHp(player.Object.Level, stamina, player.PlayerData.JobData.MaxHpFactor); player.Attributes[DefineAttributes.MP] = HealthFormulas.GetMaxOriginMp(player.Object.Level, intelligence, player.PlayerData.JobData.MaxMpFactor, true); player.Attributes[DefineAttributes.FP] = HealthFormulas.GetMaxOriginFp(player.Object.Level, stamina, dexterity, strength, player.PlayerData.JobData.MaxFpFactor, true); }
public void OnCreatePlayer(IClusterClient client, CreatePlayerPacket packet) { DbUser dbUser = _database.Users.FirstOrDefault(x => x.Username == packet.Username && x.Password == packet.Password); if (dbUser == null) { _logger.LogWarning($"[SECURITY] Unable to create new character for user '{packet.Username}' from {client.Socket.RemoteEndPoint}. " + "Reason: bad presented credentials compared to the database."); client.Disconnect(); return; } if (_database.Characters.Any(x => x.Name == packet.CharacterName)) { _logger.LogWarning( $"Unable to create new character for user '{packet.Username}' from {client.Socket.RemoteEndPoint}. " + $"Reason: character name '{packet.CharacterName}' already exists."); _clusterPacketFactory.SendClusterError(client, ErrorType.USER_EXISTS); return; } DefaultCharacter defaultCharacter = _clusterServer.ClusterConfiguration.DefaultCharacter; DefaultStartItems defaultEquipment = packet.Gender == 0 ? defaultCharacter.Man : defaultCharacter.Woman; if (!_gameResources.Jobs.TryGetValue(packet.Job, out JobData jobData)) { _logger.LogError($"Cannot find job data for job '{packet.Job}' for user '{dbUser.Username}'."); client.Disconnect(); return; } var newCharacter = new DbCharacter() { UserId = dbUser.Id, Name = packet.CharacterName, Slot = (byte)packet.Slot, SkinSetId = packet.SkinSet, HairColor = (int)packet.HairColor, FaceId = packet.HeadMesh, HairId = packet.HairMeshId, BankCode = packet.BankPassword, Gender = packet.Gender, JobId = (int)packet.Job, Hp = HealthFormulas.GetMaxOriginHp(defaultCharacter.Level, defaultCharacter.Stamina, jobData.MaxHpFactor), Mp = HealthFormulas.GetMaxOriginMp(defaultCharacter.Level, defaultCharacter.Intelligence, jobData.MaxMpFactor, true), Fp = HealthFormulas.GetMaxOriginFp(defaultCharacter.Level, defaultCharacter.Stamina, defaultCharacter.Dexterity, defaultCharacter.Strength, jobData.MaxFpFactor, true), Strength = defaultCharacter.Strength, Stamina = defaultCharacter.Stamina, Dexterity = defaultCharacter.Dexterity, Intelligence = defaultCharacter.Intelligence, MapId = defaultCharacter.MapId, PosX = defaultCharacter.PosX, PosY = defaultCharacter.PosY, PosZ = defaultCharacter.PosZ, Level = defaultCharacter.Level, Gold = defaultCharacter.Gold, StatPoints = 0, //TODO: create default stat point constant. SkillPoints = 0, //TODO: create default skill point constant. Experience = 0, }; //TODO: create game constants for slot. newCharacter.Items.Add(new DbItem(defaultEquipment.StartSuit, 44)); newCharacter.Items.Add(new DbItem(defaultEquipment.StartHand, 46)); newCharacter.Items.Add(new DbItem(defaultEquipment.StartShoes, 47)); newCharacter.Items.Add(new DbItem(defaultEquipment.StartWeapon, 52)); _database.Characters.Add(newCharacter); _database.SaveChanges(); _logger.LogInformation($"Character '{newCharacter.Name}' has been created successfully for user '{dbUser.Username}' from {client.Socket.RemoteEndPoint}."); IEnumerable <DbCharacter> dbCharacters = GetCharacters(dbUser.Id); _clusterPacketFactory.SendPlayerList(client, packet.AuthenticationKey, dbCharacters); }
public static void OnCreatePlayer(ClusterClient client, INetPacketStream packet) { var pak = new CreatePlayerPacket(packet); var clusterConfiguration = DependencyContainer.Instance.Resolve <ClusterConfiguration>(); var jobs = DependencyContainer.Instance.Resolve <JobLoader>(); DbUser dbUser = null; DbCharacter dbCharacter = null; using (var database = DependencyContainer.Instance.Resolve <IDatabase>()) { dbUser = database.Users.Get(x => x.Username.Equals(pak.Username, StringComparison.OrdinalIgnoreCase) && x.Password.Equals(pak.Password, StringComparison.OrdinalIgnoreCase)); // Check if user exist and with good password in database. if (dbUser == null) { Logger.LogWarning( $"[SECURITY] Unable to create new character for user '{pak.Username}' from {client.RemoteEndPoint}. " + "Reason: bad presented credentials compared to the database."); client.Disconnect(); return; } dbCharacter = database.Characters.Get(x => x.Name == pak.Name); // Check if character name is not already used. if (dbCharacter != null) { Logger.LogWarning( $"Unable to create new character for user '{pak.Username}' from {client.RemoteEndPoint}. " + $"Reason: character name '{pak.Name}' already exists."); ClusterPacketFactory.SendError(client, ErrorType.USER_EXISTS); return; } DefaultCharacter defaultCharacter = clusterConfiguration.DefaultCharacter; DefaultStartItems defaultEquipment = pak.Gender == 0 ? defaultCharacter.Man : defaultCharacter.Woman; JobData jobData = jobs[pak.Job]; dbCharacter = new DbCharacter() { UserId = dbUser.Id, Name = pak.Name, Slot = pak.Slot, SkinSetId = pak.SkinSet, HairColor = (int)pak.HairColor, FaceId = pak.HeadMesh, HairId = pak.HairMeshId, BankCode = pak.BankPassword, Gender = pak.Gender, ClassId = pak.Job, Hp = HealthFormulas.GetMaxOriginHp(defaultCharacter.Level, defaultCharacter.Stamina, jobData.MaxHpFactor), Mp = HealthFormulas.GetMaxOriginMp(defaultCharacter.Level, defaultCharacter.Intelligence, jobData.MaxMpFactor, true), Fp = HealthFormulas.GetMaxOriginFp(defaultCharacter.Level, defaultCharacter.Stamina, defaultCharacter.Dexterity, defaultCharacter.Strength, jobData.MaxFpFactor, true), Strength = defaultCharacter.Strength, Stamina = defaultCharacter.Stamina, Dexterity = defaultCharacter.Dexterity, Intelligence = defaultCharacter.Intelligence, MapId = defaultCharacter.MapId, PosX = defaultCharacter.PosX, PosY = defaultCharacter.PosY, PosZ = defaultCharacter.PosZ, Level = defaultCharacter.Level, Gold = defaultCharacter.Gold, StatPoints = 0, //TODO: create game constants. SkillPoints = 0, //TODO: create game constants. Experience = 0, }; //TODO: create game constants for slot. dbCharacter.Items.Add(new DbItem(defaultEquipment.StartSuit, 44)); dbCharacter.Items.Add(new DbItem(defaultEquipment.StartHand, 46)); dbCharacter.Items.Add(new DbItem(defaultEquipment.StartShoes, 47)); dbCharacter.Items.Add(new DbItem(defaultEquipment.StartWeapon, 52)); database.Characters.Create(dbCharacter); database.Complete(); } Logger.LogInformation("Character '{0}' has been created successfully for user '{1}' from {2}.", dbCharacter.Name, pak.Username, client.RemoteEndPoint); ClusterPacketFactory.SendPlayerList(client, pak.AuthenticationKey, dbUser.Characters); }
public void MaxHpFormulaTest(int level, int stamina, float factor, int expected) { var hp = HealthFormulas.GetMaxOriginHp(level, stamina, factor); Assert.Equal(expected, hp); }