diff --git a/src/DiIiS-NA/BGS-Server/Toons/Toon.cs b/src/DiIiS-NA/BGS-Server/Toons/Toon.cs index 852bdc8..091c11a 100644 --- a/src/DiIiS-NA/BGS-Server/Toons/Toon.cs +++ b/src/DiIiS-NA/BGS-Server/Toons/Toon.cs @@ -25,7 +25,7 @@ namespace DiIiS_NA.LoginServer.Toons { public class Toon : PersistentRPCObject { - #region Косметика + #region Cosmetics public int Cosmetic1 { get { return this.DBToon.Cosmetic1; } set { lock (this.DBToon) { var dbToon = this.DBToon; dbToon.Cosmetic1 = value; DBSessions.SessionUpdate(dbToon); } } } public int Cosmetic2 { get { return this.DBToon.Cosmetic2; } set { lock (this.DBToon) { var dbToon = this.DBToon; dbToon.Cosmetic2 = value; DBSessions.SessionUpdate(dbToon); } } } public int Cosmetic3 { get { return this.DBToon.Cosmetic3; } set { lock (this.DBToon) { var dbToon = this.DBToon; dbToon.Cosmetic3 = value; DBSessions.SessionUpdate(dbToon); } } } diff --git a/src/DiIiS-NA/BGS-Server/Toons/ToonManager.cs b/src/DiIiS-NA/BGS-Server/Toons/ToonManager.cs index 5b68158..44ada51 100644 --- a/src/DiIiS-NA/BGS-Server/Toons/ToonManager.cs +++ b/src/DiIiS-NA/BGS-Server/Toons/ToonManager.cs @@ -270,7 +270,7 @@ namespace DiIiS_NA.LoginServer.Toons isSeasoned = Season == 0 ? false : true, CreatedSeason = Season, Level = level, - ParagonBonuses = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + ParagonBonuses = new ushort[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, Experience = 280, CurrentQuestId = 87700, CurrentQuestStepId = -1, diff --git a/src/DiIiS-NA/Core/Storage/AccountDataBase/Entities/DBToon.cs b/src/DiIiS-NA/Core/Storage/AccountDataBase/Entities/DBToon.cs index d690727..e04b7ad 100644 --- a/src/DiIiS-NA/Core/Storage/AccountDataBase/Entities/DBToon.cs +++ b/src/DiIiS-NA/Core/Storage/AccountDataBase/Entities/DBToon.cs @@ -21,7 +21,7 @@ namespace DiIiS_NA.Core.Storage.AccountDataBase.Entities public virtual int TimeDeadHarcode { get; set; } public virtual long Experience { get; set; } - public virtual byte[] ParagonBonuses { get; set; } + public virtual ushort[] ParagonBonuses { get; set; } public virtual int PvERating { get; set; } public virtual int ChestsOpened { get; set; } public virtual int EventsCompleted { get; set; } diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs index b5fbc4c..aec9731 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs @@ -337,7 +337,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem public int KilledSeasonalTempCount = 0; public int KilledElitesTempCount = 0; public int BuffStreakKill = 0; - private byte[] ParagonBonuses; + private ushort[] ParagonBonuses; public int? HirelingId = null; public bool IsCasting = false; private Action CastResult = null; @@ -629,21 +629,32 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem public void SetAttributesByParagon() { - this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, 0] = 0; - this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, 1] = 0; - this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, 2] = 0; - this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, 3] = 0; - int level = Math.Min(this.Toon.ParagonLevel, 800); - for (int i = 0; i < level; i++) + // Until the Paragon 800 should be distributed on the 4 tabs, + // after that only in the first Core tab. + var baseParagonPoints = Math.Min(this.Toon.ParagonLevel, 800); + var extraParagonPoints = Math.Max(0, this.Toon.ParagonLevel - 800); + for (int i = 0; i < 4; i++) { - this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, (i % 4)]++; + this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, i] = baseParagonPoints / 4; + // Process remainder only for base points. + if (i < baseParagonPoints % 4) + { + this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, i]++; + } } + // First tab of Paragon (Core) - pos 0. + this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, 0] += extraParagonPoints; + var assigned_bonuses = this.ParagonBonuses; + var bonus_ids = ItemGenerator.GetParagonBonusTable(this.Toon.Class); + foreach (var bonus in bonus_ids) { int slot_index = (bonus.Category * 4) + bonus.Index - 1; - this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, bonus.Category] -= assigned_bonuses[slot_index]; + + this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, bonus.Category] -= assigned_bonuses[slot_index]; + this.Attributes[GameAttribute.Paragon_Bonus, bonus.Hash] = assigned_bonuses[slot_index]; float result; @@ -659,7 +670,9 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem else { if (bonus.AttributeSpecifiers[0].AttributeId == 133) result = 33f; //Hitpoints_Regen_Per_Second + if (bonus.AttributeSpecifiers[0].AttributeId == 342) result = 16.5f; //Hitpoints_On_Hit + if (GameAttribute.Attributes[bonus.AttributeSpecifiers[0].AttributeId] is GameAttributeF) { var attr = GameAttribute.Attributes[bonus.AttributeSpecifiers[0].AttributeId] as GameAttributeF; @@ -670,6 +683,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem } else if (GameAttribute.Attributes[bonus.AttributeSpecifiers[0].AttributeId] is GameAttributeI) { + var attr = GameAttribute.Attributes[bonus.AttributeSpecifiers[0].AttributeId] as GameAttributeI; if (bonus.AttributeSpecifiers[0].SNOParam != -1) this.Attributes[attr, bonus.AttributeSpecifiers[0].SNOParam] += (int)(result * assigned_bonuses[slot_index]); @@ -1337,7 +1351,6 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem this.Attributes[GameAttribute.Hitpoints_Cur] = this.Attributes[GameAttribute.Hitpoints_Max_Total]; this.Attributes[GameAttribute.Corpse_Resurrection_Charges] = 3; - //TestOutPutItemAttributes(); //Activate this only for finding item stats. this.Attributes.BroadcastChangedIfRevealed(); @@ -1990,11 +2003,12 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem { var bonus = ItemGenerator.GetParagonBonusTable(this.Toon.Class).Where(b => b.Hash == message.BonusGBID).FirstOrDefault(); - if (bonus == null) return; + if (bonus == null) return; if (message.Amount > this.Attributes[GameAttribute.Paragon_Bonus_Points_Available, bonus.Category]) return; //if (this.ParagonBonuses[(bonus.Category * 4) + bonus.Index - 1] + (byte)message.Amount > bonus.Limit) return; - this.ParagonBonuses[(bonus.Category * 4) + bonus.Index - 1] += (byte)message.Amount; + // message.Amount have the value send to add on attr of Paragon tabs. + this.ParagonBonuses[(bonus.Category * 4) + bonus.Index - 1] += (ushort)message.Amount; var dbToon = this.Toon.DBToon; dbToon.ParagonBonuses = this.ParagonBonuses; @@ -2012,7 +2026,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem } private void OnResetParagonPointsMessage(GameClient client, ResetParagonPointsMessage message) { - this.ParagonBonuses = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + this.ParagonBonuses = new ushort[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; var dbToon = this.Toon.DBToon; dbToon.ParagonBonuses = this.ParagonBonuses; this.World.Game.GameDBSession.SessionUpdate(dbToon); @@ -2464,6 +2478,8 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem } } + this.Attributes[GameAttribute.Corpse_Resurrection_Charges] = 3; // Reset resurrection charges on zone change (TODO: do not reset charges on reentering the same zone) + #if DEBUG Logger.Warn("Местоположение игрока {0}, Scene: {1} SNO: {2} LevelArea: {3}", this.Toon.Name, this.CurrentScene.SceneSNO.Name, this.CurrentScene.SceneSNO.Id, this.CurrentScene.Specification.SNOLevelAreas[0]); #else @@ -5958,7 +5974,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PlayerSystem minion.SetVisible(true); minion.Hidden = false; - if (minion.ActorSNO.Id == 4580) // Act I Leah + if (minion.ActorSNO.Id == 4580) // Act I Leah { (minion.Brain as MinionBrain).PresetPowers.Clear(); (minion.Brain as MinionBrain).AddPresetPower(30599);