// NPCLoader.StrikeNPC doesn't specify which player dealt the damage. public override bool HijackGetData(ref byte messageType, ref BinaryReader reader, int playerNumber) { try { if (messageType == MessageID.StrikeNPC && Main.netMode == NetmodeID.Server) { int npcIndex = reader.ReadInt16(); int damage = reader.ReadInt16(); //ErrorLogger.Log("HijackGetData StrikeNPC: " + npcIndex + " " + damage + " " + playerNumber); //System.Console.WriteLine("HijackGetData StrikeNPC: " + npcIndex + " " + damage + " " + playerNumber); NPC damagedNPC = Main.npc[npcIndex]; if (damagedNPC.realLife >= 0) { damagedNPC = Main.npc[damagedNPC.realLife]; } DPSExtremeGlobalNPC info = damagedNPC.GetGlobalNPC <DPSExtremeGlobalNPC>(); info.damageDone[playerNumber] += damage; // TODO: Reimplement DPS with ring buffer for accurate? !!! or send 0? // TODO: Verify real life adjustment } } catch (Exception e) { //ErrorLogger.Log("HijackGetData StrikeNPC " + e.Message); } return(false); }
// Things like townNPC and I think traps will trigger this in Server. In SP, all is done here. public override void OnHitByItem(NPC npc, Player player, Item item, int damage, float knockback, bool crit) { try { //System.Console.WriteLine("OnHitByItem " + player.whoAmI); NPC damagedNPC = npc; if (npc.realLife >= 0) { damagedNPC = Main.npc[damagedNPC.realLife]; } DPSExtremeGlobalNPC info = damagedNPC.GetGlobalNPC <DPSExtremeGlobalNPC>(); info.damageDone[player.whoAmI] += damage; if (info.onDeathBed) // oh wait, is this the same as .active in this case? probably not. { info.SendStats(damagedNPC); info.onDeathBed = false; // multiple things can hit while on deathbed. } //damageDone[player.whoAmI] += damage; //if (onDeathBed) //{ // SendStats(npc); //} } catch (Exception e) { //ErrorLogger.Log("OnHitByItem" + e.Message); } }
// Things like townNPC and I think traps will trigger this in Server. In SP, all is done here. public override void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit) { //TODO, owner could be -1? try { //System.Console.WriteLine("OnHitByProjectile " + projectile.owner); NPC damagedNPC = npc; if (npc.realLife >= 0) { damagedNPC = Main.npc[damagedNPC.realLife]; } DPSExtremeGlobalNPC info = damagedNPC.GetGlobalNPC <DPSExtremeGlobalNPC>(); info.damageDone[projectile.owner] += damage; if (info.onDeathBed) { info.SendStats(damagedNPC); info.onDeathBed = false; } //damageDone[projectile.owner] += damage; //if (onDeathBed) //{ // SendStats(npc); //} } catch (Exception e) { //ErrorLogger.Log("OnHitByProjectile" + e.Message); } }
void SendStats(NPC npc) { try { //System.Console.WriteLine("SendStats"); StringBuilder sb = new StringBuilder(); sb.Append("Damage stats for " + Lang.GetNPCNameValue(npc.type) + ": "); for (int i = 0; i < 256; i++) { int playerDamage = damageDone[i]; if (playerDamage > 0) { if (i == 255) { sb.Append($"Traps/TownNPC: {playerDamage}, "); } else { sb.Append($"{Main.player[i].name}: {playerDamage}, "); } } } sb.Length -= 2; // removes last , Color messageColor = Color.Orange; if (Main.netMode == NetmodeID.Server) { NetMessage.BroadcastChatMessage(NetworkText.FromLiteral(sb.ToString()), messageColor); var netMessage = mod.GetPacket(); netMessage.Write((byte)DPSExtremeMessageType.InformClientsCurrentBossTotals); netMessage.Write(true); netMessage.Write((byte)npc.whoAmI); DPSExtremeGlobalNPC bossGlobalNPC = npc.GetGlobalNPC <DPSExtremeGlobalNPC>(); byte count = 0; for (int i = 0; i < 256; i++) { if (bossGlobalNPC.damageDone[i] > 0) { count++; } } netMessage.Write(count); for (int i = 0; i < 256; i++) { if (bossGlobalNPC.damageDone[i] > 0) { netMessage.Write((byte)i); netMessage.Write(bossGlobalNPC.damageDone[i]); } } netMessage.Send(); Dictionary <byte, int> stats = new Dictionary <byte, int>(); for (int i = 0; i < 256; i++) { if (bossGlobalNPC.damageDone[i] > -1) { stats[(byte)i] = bossGlobalNPC.damageDone[i]; } } DPSExtreme.instance.InvokeOnSimpleBossStats(stats); } else if (Main.netMode == NetmodeID.SinglePlayer) { Main.NewText(sb.ToString(), messageColor); } else if (Main.netMode == NetmodeID.MultiplayerClient) { // MP clients should just wait for message. } } catch (Exception e) { //ErrorLogger.Log("SendStats" + e.Message); } }
public override void PostUpdate() { if (Main.netMode == 2 && Main.GameUpdateCount % DPSExtreme.UPDATEDELAY == 0) { var netMessage = mod.GetPacket(); netMessage.Write((byte)DPSExtremeMessageType.InformClientsCurrentDPSs); byte count = 0; for (int i = 0; i < 256; i++) { if (Main.player[i].active && Main.player[i].accDreamCatcher) { count++; } } netMessage.Write(count); for (int i = 0; i < 256; i++) { if (Main.player[i].active && Main.player[i].accDreamCatcher) { netMessage.Write((byte)i); netMessage.Write(DPSExtreme.dpss[i]); } } netMessage.Send(); byte bossIndex = 255; float maxProgress = -1f; for (byte i = 0; i < 200; i++) { NPC npc = Main.npc[i]; if (npc.active && npc.boss && (npc.realLife == -1 || npc.realLife == npc.whoAmI)) { //NPC realNPC = npc.realLife >= 0 ? Main.npc[npc.realLife] : npc; float deathProgress = 1f - ((float)npc.life / npc.lifeMax); if (deathProgress > maxProgress) { maxProgress = deathProgress; bossIndex = i; } } } if (bossIndex != 255) { netMessage = mod.GetPacket(); netMessage.Write((byte)DPSExtremeMessageType.InformClientsCurrentBossTotals); netMessage.Write(true); netMessage.Write(bossIndex); DPSExtremeGlobalNPC bossGlobalNPC = Main.npc[bossIndex].GetGlobalNPC <DPSExtremeGlobalNPC>(); count = 0; for (int i = 0; i < 256; i++) { if (bossGlobalNPC.damageDone[i] > 0) { count++; } } netMessage.Write(count); for (int i = 0; i < 256; i++) { if (bossGlobalNPC.damageDone[i] > 0) { netMessage.Write((byte)i); netMessage.Write(bossGlobalNPC.damageDone[i]); } } netMessage.Send(); } } }