protected override void InsertItem(int index, Character user) { try { if (user.Party != null) { foreach (var buff in user.Buffs) { if (buff.dwCharFromId != user.dwId) { continue; } if (buff.StatType != SecondaryStatFlag.BlueAura && buff.StatType != SecondaryStatFlag.DarkAura && buff.StatType != SecondaryStatFlag.YellowAura) { continue; } ForEachPartyMember(user.Party.PartyID, member => member.Buffs .AddAura(buff.StatType, buff.dwCharFromId, buff.nSkillID, buff.nSLV)); break; } } //Spawn the player being added to everyone in the room { var pPacketEnter = user.MakeEnterFieldPacket(); Field.EncodeFieldSpecificData(pPacketEnter, user); Field.Broadcast(pPacketEnter); } //So i need to fix a bug where when u change map - u dont receive ur own dmg skin lol //Spawn [other players + ext data] in room to person entering foreach (var c in this) { var pPacketEnter = c.MakeEnterFieldPacket(); Field.EncodeFieldSpecificData(pPacketEnter, c); user.SendPacket(pPacketEnter); //var pPacketEnterExt = CPacket.Custom.UserEnter(c.dwId, c.nDamageSkin); //user.SendPacket(pPacketEnterExt); } Field.Drops.Update(); // remove expired drops (required cuz map might be empty and thus not removing drops) //This must be here !!!! base.InsertItem(index, user); //Spawn entering person's extension data to everyone on map { //var pPacketEnterExt = CPacket.Custom.UserEnter(user.dwId, user.nDamageSkin); //Field.Broadcast(pPacketEnterExt); } //Spawn entering person's entities to everyone on map if (JobLogic.IsEvan(user.Stats.nJob) && user.Stats.nJob != 2001) { user.Dragon = new CDragon(user); user.Dragon.SpawnDragonToMap(); } user.Pets.SpawnPetsToMap(); //Spawn field entities to person entering Field.SendSpawnDragons(user); // pets are handled in UserEnterField packet Field.SendSpawnSummons(user); Field.Summons.InsertFromStorage(user); // needs to be after SendSpawnSummons Field.SendSpawnMobs(user); Field.SendSpawnNpcs(user); Field.SendSpawnReactors(user); Field.SendSpawnAffectedAreas(user); Field.SendSpawnMinirooms(user); Field.SendSpawnKites(user); Field.SendSpawnTownPortals(user); Field.SendSpawnOpenGates(user); Field.SendSpawnDrops(user); Field.SendActiveWeatherEffect(user); Field.AssignControllerMobs(); Field.AssignControllerNpcs(); if (Field.tFieldTimerExpiration.SecondsUntilEnd() > 0) { user.SendPacket(CPacket.CreateClock((int)Field.tFieldTimerExpiration.SecondsUntilEnd())); } if (Field.nFieldDeathCount > -1) { //user.SendPacket(CPacket.Custom.FieldDeathCount(Field.nFieldDeathCount)); } if (user.Party != null) { foreach (var c in this) { if (c.Party?.PartyID != user.Party.PartyID) { continue; } foreach (var buff in c.Buffs) { if (buff.dwCharFromId != c.dwId) { continue; } if (buff.StatType == SecondaryStatFlag.BlueAura || buff.StatType == SecondaryStatFlag.DarkAura || buff.StatType == SecondaryStatFlag.YellowAura) { user.Buffs.AddAura(buff.StatType, buff.dwCharFromId, buff.nSkillID, buff.nSLV); break; } } } } } catch (Exception ex) { Log.Error(ex); user?.Socket?.Disconnect(); } }
public void Stats(Action <StatModifier> action, bool bExclRequest = true) { var ctx = new StatModifier(Parent); action?.Invoke(ctx); if ((ctx.Flag & ModifyStatFlags.EXP) > 0) { if (ctx.EXP < 0) { ctx.EXP = 0; } var nExpSurplus = ctx.EXP - NextLevel.get_next_level_exp(ctx.Level - 1); // make sure this is before levelup func var levels = 0; var jobLevels = 0; int beforesp = ctx.SP; while (nExpSurplus >= 0) // while has more exp than required to reach next level { ctx.EXP = nExpSurplus; if (!ctx.try_process_levelup()) { break; } nExpSurplus = ctx.EXP - NextLevel.get_next_level_exp(ctx.Level - 1); levels += 1; Parent.NotifySocialChannels(SocialNotiflag.ChangeLevel); var job = ctx.Job; ctx.AutoJobAdvanceEvent(Parent); if (job != ctx.Job) { jobLevels += 1; } } if (levels > 0) { if (ctx.HP > 0) { ctx.HP = Parent.BasicStats.nMHP; ctx.MP = Parent.BasicStats.nMMP; } var effect = new UserEffectPacket(UserEffect.LevelUp); effect.BroadcastEffect(Parent); ctx.SP += (short)(jobLevels * 1); var aftersp = ctx.SP - beforesp; Parent.SendPacket(CPacket.IncSPMessage((byte)aftersp, ctx.Job)); // send sp gain message Parent.ValidateStat(); } } if ((ctx.Flag & ModifyStatFlags.Money) != 0) { ctx.Money = Math.Max(0, ctx.Money); } if ((ctx.Flag & ModifyStatFlags.POP) != 0) { ctx.POP = Math.Max((short)0, ctx.POP); } if ((ctx.Flag & ModifyStatFlags.Job) != 0) { Parent.Skills.SetMasterLevels(); var effect = new UserEffectPacket(UserEffect.JobChanged); effect.BroadcastEffect(Parent); if (JobLogic.IsEvan(ctx.Job)) { if (ctx.Job == 2200 && Parent.Dragon is null) { Parent.Dragon = new CDragon(Parent); Parent.Quests.OnCompleteQuest(null, 22100, 0, true); } Parent.Dragon.SpawnDragonToMap(); // update visuals } else { Parent.Modify.Skills(mod => { switch (ctx.Job) { // hacking aran skills together for now. TODO add a ForceVisible field or something to the skill class case 2100: mod.AddEntry(21000000, entry => entry.CurMastery = entry.MaxLevel); mod.AddEntry(21001003, entry => entry.CurMastery = entry.MaxLevel); break; case 2110: mod.AddEntry(21100000, entry => entry.CurMastery = entry.MaxLevel); mod.AddEntry(21100002, entry => entry.CurMastery = entry.MaxLevel); mod.AddEntry(21100004, entry => entry.CurMastery = entry.MaxLevel); mod.AddEntry(21100005, entry => entry.CurMastery = entry.MaxLevel); break; case 2111: mod.AddEntry(21110002, entry => entry.CurMastery = entry.MaxLevel); break; case 3300: mod.AddEntry(30001061, entry => entry.nSLV = 1); mod.AddEntry(30001062, entry => entry.nSLV = 1); break; case 3500: mod.AddEntry(30001068, entry => entry.nSLV = 1); break; } foreach (var skill in MasterManager.SkillTemplates.GetJobSkills(ctx.Job)) { var template = MasterManager.SkillTemplates[skill]; if (template.MasterLevel > 0) { mod.AddEntry(skill, entry => entry.CurMastery = (byte)template.MasterLevel); } } }); } // notify correct channels Parent.NotifySocialChannels(SocialNotiflag.ChangeJob); } if ((ctx.Flag & ModifyStatFlags.HP) > 0 || (ctx.Flag & ModifyStatFlags.MaxHP) > 0) { if (ctx.HP <= 0) // TODO move death exp loss (and safety charm) handling here { Parent.Field.Summons.RemoveCharSummons(Parent.dwId, SummonLeaveType.LEAVE_TYPE_USER_DEAD); } if (ctx.Job == 132) // dark knight { Parent.Skills.ProcessDarkKnightDarkForce(Parent.BasicStats.nMHP); } } if (((ctx.Flag & ModifyStatFlags.MP) > 0 || (ctx.Flag & ModifyStatFlags.MaxMP) > 0) && ctx.Job >= 2216 && ctx.Job <= 2218) // evan { Parent.Skills.CheckDragonFury(Parent.BasicStats.nMMP); } if ((ctx.Flag & ModifyStatFlags.BasicStat) != 0) { Parent.ValidateStat(); } if (ctx.Flag > 0) { Parent.SendPacket(CPacket.StatChanged(ctx, bExclRequest)); } }