[Cleanup/Feature] Add support for bots to #showstats/#mystats (#3427)

* Initial Push

* Update classes.cpp

* Update mob.cpp

* Update mob.cpp

* Update showstats.cpp

* Update mystats.cpp

* Remove unused variables.

* Update mob.cpp

* Update class.cpp

* Update race.cpp

* Update mob.h
This commit is contained in:
Alex King
2023-07-01 19:47:54 -04:00
committed by GitHub
parent 927d379e75
commit a1f2764978
16 changed files with 1544 additions and 855 deletions
+30 -568
View File
@@ -3958,32 +3958,32 @@ void Client::SendFullPopup(
}
void Client::SendWindow(
uint32 PopupID,
uint32 NegativeID,
uint32 Buttons,
const char *ButtonName0,
const char *ButtonName1,
uint32 Duration,
uint32 button_one_id,
uint32 button_two_id,
uint32 button_type,
const char* button_one_text,
const char* button_two_text,
uint32 duration,
int title_type,
Client *target,
const char *Title,
const char *Text,
Mob* target,
const char* title,
const char* text,
...
)
{
va_list argptr;
char buffer[4096];
va_start(argptr, Text);
vsnprintf(buffer, sizeof(buffer), Text, argptr);
va_start(argptr, text);
vsnprintf(buffer, sizeof(buffer), text, argptr);
va_end(argptr);
size_t len = strlen(buffer);
auto app = new EQApplicationPacket(OP_OnLevelMessage, sizeof(OnLevelMessage_Struct));
OnLevelMessage_Struct *olms = (OnLevelMessage_Struct *) app->pBuffer;
auto app = new EQApplicationPacket(OP_OnLevelMessage, sizeof(OnLevelMessage_Struct));
auto* olms = (OnLevelMessage_Struct *) app->pBuffer;
if (strlen(Text) > (sizeof(olms->Text) - 1)) {
if (strlen(text) > (sizeof(olms->Text) - 1)) {
safe_delete(app);
return;
}
@@ -3996,47 +3996,47 @@ void Client::SendWindow(
case 1: {
char name[64] = "";
strcpy(name, target->GetName());
if (strlen(target->GetLastName()) > 0) {
char last_name[64] = "";
strcpy(last_name, target->GetLastName());
strcat(name, " ");
strcat(name, last_name);
}
strcpy(olms->Title, name);
break;
}
case 2: {
if (target->GuildID()) {
char *guild_name = (char *) guild_mgr.GetGuildName(target->GuildID());
strcpy(olms->Title, guild_name);
}
else {
if (target->IsClient() && target->CastToClient()->GuildID()) {
auto guild_name = guild_mgr.GetGuildName(target->CastToClient()->GuildID());
strn0cpy(olms->Title, guild_name, sizeof(olms->Title));
} else {
strcpy(olms->Title, "No Guild");
}
break;
}
default: {
strcpy(olms->Title, Title);
strcpy(olms->Title, title);
break;
}
}
memcpy(olms->Text, buffer, len + 1);
olms->Buttons = Buttons;
olms->Buttons = button_type;
sprintf(olms->ButtonName0, "%s", ButtonName0);
sprintf(olms->ButtonName1, "%s", ButtonName1);
strn0cpy(olms->ButtonName0, button_one_text, sizeof(olms->ButtonName0));
strn0cpy(olms->ButtonName1, button_two_text, sizeof(olms->ButtonName1));
if (Duration > 0) {
olms->Duration = Duration * 1000;
}
else {
olms->Duration = 0xffffffff;
if (duration > 0) {
olms->Duration = duration * 1000;
} else {
olms->Duration = UINT32_MAX;
}
olms->PopupID = PopupID;
olms->NegativeID = NegativeID;
olms->PopupID = button_one_id;
olms->NegativeID = button_two_id;
FastQueuePacket(&app);
}
@@ -6365,544 +6365,6 @@ void Client::RemoveFromInstance(uint16 instance_id)
database.RemoveClientFromInstance(instance_id, CharacterID());
}
void Client::SendStatsWindow(Client* client, bool use_window)
{
// Define the types of page breaks we need
std::string indP = " ";
std::string indS = "          ";
std::string indM = "                          ";
std::string indL = "                                 ";
std::string div = " | ";
std::string color_red = "<c \"#993333\">";
std::string color_blue = "<c \"#9999FF\">";
std::string color_green = "<c \"#33FF99\">";
std::string bright_green = "<c \"#7CFC00\">";
std::string bright_red = "<c \"#FF0000\">";
std::string heroic_color = "<c \"#d6b228\"> +";
// Set Class
std::string class_Name = itoa(GetClass());
std::string class_List[] = { "WAR", "CLR", "PAL", "RNG", "SHD", "DRU", "MNK", "BRD", "ROG", "SHM", "NEC", "WIZ", "MAG", "ENC", "BST", "BER" };
if (GetClass() < 17 && GetClass() > 0) {
class_Name = class_List[GetClass() - 1];
}
// Race
std::string race_name = GetRaceIDName(GetRace());
/*##########################################################
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
H/M/E String
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
##########################################################*/
std::string HME_row = "";
//Loop Variables
/*===========================*/
std::string cur_field = "";
std::string total_field = "";
std::string cur_name = "";
std::string cur_spacing = "";
std::string cur_color = "";
int hme_rows = 3; // Rows in display
int max_HME_value_len = 9; // 9 digits in the displayed value
for(int hme_row_counter = 0; hme_row_counter < hme_rows; hme_row_counter++)
{
switch(hme_row_counter) {
case 0: {
cur_name = " H: ";
cur_field = itoa(GetHP());
total_field = itoa(GetMaxHP());
break;
}
case 1: {
if(CalcMaxMana() > 0) {
cur_name = " M: ";
cur_field = itoa(GetMana());
total_field = itoa(GetMaxMana());
}
else { continue; }
break;
}
case 2: {
cur_name = " E: ";
cur_field = itoa(GetEndurance());
total_field = itoa(GetMaxEndurance());
break;
}
default: { break; }
}
if(cur_field.compare(total_field) == 0) { cur_color = bright_green; }
else { cur_color = bright_red; }
cur_spacing.clear();
for(int a = cur_field.size(); a < max_HME_value_len; a++) { cur_spacing += " ."; }
HME_row += indM + cur_name + cur_spacing + cur_color + cur_field + "</c> / " + total_field + "<br>";
}
/*##########################################################
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Regen String
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
##########################################################*/
std::string regen_string;
//Loop Variables
/*===========================*/
std::string regen_row_header = "";
std::string regen_row_color = "";
std::string base_regen_field = "";
std::string base_regen_spacing = "";
std::string item_regen_field = "";
std::string item_regen_spacing = "";
std::string cap_regen_field = "";
std::string cap_regen_spacing = "";
std::string spell_regen_field = "";
std::string spell_regen_spacing = "";
std::string aa_regen_field = "";
std::string aa_regen_spacing = "";
std::string total_regen_field = "";
int regen_rows = 3; // Number of rows
int max_regen_value_len = 5; // 5 digits in the displayed value(larger values will not get cut off, this is just a baseline)
for(int regen_row_counter = 0; regen_row_counter < regen_rows; regen_row_counter++)
{
switch(regen_row_counter)
{
case 0: {
regen_row_header = "H: ";
regen_row_color = color_red;
base_regen_field = itoa(LevelRegen());
item_regen_field = itoa(itembonuses.HPRegen + itembonuses.heroic_hp_regen);
cap_regen_field = itoa(CalcHPRegenCap());
spell_regen_field = itoa(spellbonuses.HPRegen);
aa_regen_field = itoa(aabonuses.HPRegen);
total_regen_field = itoa(CalcHPRegen(true));
break;
}
case 1: {
if(GetMaxMana() > 0) {
regen_row_header = "M: ";
regen_row_color = color_blue;
base_regen_field = itoa(CalcBaseManaRegen());
int32 heroic_mana_regen = itembonuses.heroic_mana_regen;
item_regen_field = itoa(itembonuses.ManaRegen + heroic_mana_regen);
cap_regen_field = itoa(CalcManaRegenCap());
spell_regen_field = itoa(spellbonuses.ManaRegen);
aa_regen_field = itoa(aabonuses.ManaRegen);
total_regen_field = itoa(CalcManaRegen(true));
}
else { continue; }
break;
}
case 2: {
regen_row_header = "E: ";
regen_row_color = color_green;
base_regen_field = itoa(((GetLevel() * 4 / 10) + 2));
item_regen_field = itoa(itembonuses.EnduranceRegen + itembonuses.heroic_end_regen);
cap_regen_field = itoa(CalcEnduranceRegenCap());
spell_regen_field = itoa(spellbonuses.EnduranceRegen);
aa_regen_field = itoa(aabonuses.EnduranceRegen);
total_regen_field = itoa(CalcEnduranceRegen(true));
break;
}
default: { break; }
}
base_regen_spacing.clear();
item_regen_spacing.clear();
cap_regen_spacing.clear();
spell_regen_spacing.clear();
aa_regen_spacing.clear();
for(int b = base_regen_field.size(); b < max_regen_value_len; b++) { base_regen_spacing += " ."; }
for(int b = item_regen_field.size(); b < max_regen_value_len; b++) { item_regen_spacing += " ."; }
for(int b = cap_regen_field.size(); b < max_regen_value_len; b++) { cap_regen_spacing += " ."; }
for(int b = spell_regen_field.size(); b < max_regen_value_len; b++) { spell_regen_spacing += " ."; }
for(int b = aa_regen_field.size(); b < max_regen_value_len; b++) { aa_regen_spacing += " ."; }
regen_string += indS + regen_row_color + regen_row_header + base_regen_spacing + base_regen_field;
regen_string += div + item_regen_spacing + item_regen_field + " (" + cap_regen_field;
regen_string += ") " + cap_regen_spacing + div + spell_regen_spacing + spell_regen_field;
regen_string += div + aa_regen_spacing + aa_regen_field + div + total_regen_field + "</c><br>";
}
/*##########################################################
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Stat String
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
##########################################################*/
std::string stat_field = "";
//Loop Variables
/*===========================*/
//first field(stat)
std::string a_stat = "";;
std::string a_stat_name = "";
std::string a_stat_spacing = "";
//second field(heroic stat)
std::string h_stat = "";
std::string h_stat_spacing = "";
//third field(resist)
std::string a_resist = "";
std::string a_resist_name = "";
std::string a_resist_spacing = "";
//fourth field(heroic resist)
std::string h_resist_field = "";
int stat_rows = 7; // Number of rows
int max_stat_value_len = 3; // 3 digits in the displayed value
for(int stat_row_counter = 0; stat_row_counter < stat_rows; stat_row_counter++)
{
switch(stat_row_counter) {
case 0: {
a_stat_name = " STR: ";
a_resist_name = "MR: ";
a_stat = itoa(GetSTR());
h_stat = itoa(GetHeroicSTR());
a_resist = itoa(GetMR());
h_resist_field = itoa(GetHeroicMR());
break;
}
case 1: {
a_stat_name = " STA: ";
a_resist_name = "CR: ";
a_stat = itoa(GetSTA());
h_stat = itoa(GetHeroicSTA());
a_resist = itoa(GetCR());
h_resist_field = itoa(GetHeroicCR());
break;
}
case 2: {
a_stat_name = " AGI : ";
a_resist_name = "FR: ";
a_stat = itoa(GetAGI());
h_stat = itoa(GetHeroicAGI());
a_resist = itoa(GetFR());
h_resist_field = itoa(GetHeroicFR());
break;
}
case 3: {
a_stat_name = " DEX: ";
a_resist_name = "PR: ";
a_stat = itoa(GetDEX());
h_stat = itoa(GetHeroicDEX());
a_resist = itoa(GetPR());
h_resist_field = itoa(GetHeroicPR());
break;
}
case 4: {
a_stat_name = " INT : ";
a_resist_name = "DR: ";
a_stat = itoa(GetINT());
h_stat = itoa(GetHeroicINT());
a_resist = itoa(GetDR());
h_resist_field = itoa(GetHeroicDR());
break;
}
case 5: {
a_stat_name = " WIS: ";
a_resist_name = "Cp: ";
a_stat = itoa(GetWIS());
h_stat = itoa(GetHeroicWIS());
a_resist = itoa(GetCorrup());
h_resist_field = itoa(GetHeroicCorrup());
break;
}
case 6: {
a_stat_name = " CHA: ";
a_resist_name = "PhR: "; // Not implemented for clients yet
a_stat = itoa(GetCHA());
h_stat = itoa(GetHeroicCHA());
a_resist = itoa(GetPhR());
h_resist_field = itoa(GetHeroicPhR());
break;
}
default: { break; }
}
a_stat_spacing.clear();
h_stat_spacing.clear();
a_resist_spacing.clear();
for(int a = a_stat.size(); a < max_stat_value_len; a++) { a_stat_spacing += " . "; }
for(int h = h_stat.size(); h < 20; h++) { h_stat_spacing += " . "; }
for(int h = a_resist.size(); h < max_stat_value_len; h++) { a_resist_spacing += " . "; }
stat_field += indP + a_stat_name + a_stat_spacing + a_stat + heroic_color + h_stat + "</c>";
stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + "</c>";
if(stat_row_counter < 6) {
stat_field += "<br>";
}
}
/*##########################################################
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mod2 String
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
##########################################################*/
std::string mod2_field = "";
//Loop Variables
/*===========================*/
std::string mod2a = "";
std::string mod2a_name = "";
std::string mod2a_spacing = "";
std::string mod2a_cap = "";
std::string mod_row_spacing = "";
std::string mod2b = "";
std::string mod2b_name = "";
std::string mod2b_spacing = "";
std::string mod2b_cap = "";
int mod2a_space_count;
int mod2b_space_count;
int mod2_rows = 4;
int max_mod2_value_len = 3; // 3 digits in the displayed value
for(int mod2_row_counter = 0; mod2_row_counter < mod2_rows; mod2_row_counter++)
{
switch (mod2_row_counter)
{
case 0: {
mod2a_name = "Avoidance: ";
mod2b_name = "Combat Effects: ";
mod2a = itoa(GetAvoidance());
mod2a_cap = itoa(RuleI(Character, ItemAvoidanceCap));
mod2b = itoa(GetCombatEffects());
mod2b_cap = itoa(RuleI(Character, ItemCombatEffectsCap));
mod2a_space_count = 2;
mod2b_space_count = 0;
break;
}
case 1: {
mod2a_name = "Accuracy: ";
mod2b_name = "Strike Through: ";
mod2a = itoa(GetAccuracy());
mod2a_cap = itoa(RuleI(Character, ItemAccuracyCap));
mod2b = itoa(GetStrikeThrough());
mod2b_cap = itoa(RuleI(Character, ItemStrikethroughCap));
mod2a_space_count = 3;
mod2b_space_count = 1;
break;
}
case 2: {
mod2a_name = "Shielding: ";
mod2b_name = "Spell Shielding: ";
mod2a = itoa(GetShielding());
mod2a_cap = itoa(RuleI(Character, ItemShieldingCap));
mod2b = itoa(GetSpellShield());
mod2b_cap = itoa(RuleI(Character, ItemSpellShieldingCap));
mod2a_space_count = 2;
mod2b_space_count = 1;
break;
}
case 3: {
mod2a_name = "Stun Resist: ";
mod2b_name = "DoT Shielding: ";
mod2a = itoa(GetStunResist());
mod2a_cap = itoa(RuleI(Character, ItemStunResistCap));
mod2b = itoa(GetDoTShield());
mod2b_cap = itoa(RuleI(Character, ItemDoTShieldingCap));
mod2a_space_count = 0;
mod2b_space_count = 2;
break;
}
}
mod2a_spacing.clear();
mod_row_spacing.clear();
mod2b_spacing.clear();
for(int a = mod2a.size(); a < (max_mod2_value_len + mod2a_space_count); a++) { mod2a_spacing += " . "; }
for(int a = mod2a_cap.size(); a < 6 ; a++) { mod_row_spacing += " . "; }
for(int a = mod2b.size(); a < (max_mod2_value_len + mod2b_space_count); a++) { mod2b_spacing += " . "; }
mod2_field += indP + mod2a_name + mod2a_spacing + mod2a + " / " + mod2a_cap + mod_row_spacing;
mod2_field += mod2b_name + mod2b_spacing + mod2b + " / " + mod2b_cap + "<br>";
}
uint32 rune_number = 0;
uint32 magic_rune_number = 0;
uint32 buff_count = GetMaxTotalSlots();
for (int i=0; i < buff_count; i++) {
if (IsValidSpell(buffs[i].spellid)) {
if (buffs[i].melee_rune > 0) { rune_number += buffs[i].melee_rune; }
if (buffs[i].magic_rune > 0) { magic_rune_number += buffs[i].magic_rune; }
}
}
int shield_ac = 0;
GetRawACNoShield(shield_ac);
std::string skill_list[] = {
"1H Blunt","1H Slashing","2H Blunt","2H Slashing","Abjuration",
"Alteration","Apply Poison","Archery","Backstab","Bind Wound",
"Bash","Block","Brass Instruments","Channeling","Conjuration",
"Defense","Disarm","Disarm Traps","Divination","Dodge",
"Double Attack","Dragon Punch","Dual Wield","Eagle Strike","Evocation",
"Feign Death","Flying Kick","Forage","Hand To Hand","Hide",
"Kick","Meditate","Mend","Offense","Parry",
"Pick Lock","1H Piercing","Riposte","Round Kick","Safe Fall",
"Sense Heading","Singing","Sneak","Specialize Abjuration","Specialize Alteration",
"Specialize Conjuration","Specialize Divination","Specialize Evocation","Pick Pockets","Stringed Instruments",
"Swimming","Throwing","Tiger Claw","Tracking","Wind Instruments",
"Fishing","Make Poison","Tinkering","Research","Alchemy",
"Baking","Tailoring","Sense Traps","Blacksmithing","Fletching",
"Brewing","Alcohol_Tolerance","Begging","Jewelry Making","Pottery",
"Percussion Instruments","Intimidation","Berserking","Taunt","Frenzy",
"Remove Traps","Triple Attack","2H Piercing"
};
std::string skill_mods = "";
for (int j = 0; j <= EQ::skills::HIGHEST_SKILL; j++) {
if(itembonuses.skillmod[j] > 0)
skill_mods += indP + skill_list[j] + " : +" + itoa(itembonuses.skillmod[j]) + "%<br>";
else if(itembonuses.skillmod[j] < 0)
skill_mods += indP + skill_list[j] + " : -" + itoa(itembonuses.skillmod[j]) + "%<br>";
}
std::string skill_dmgs = "";
for (int j = 0; j <= EQ::skills::HIGHEST_SKILL; j++) {
if((itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) > 0)
skill_dmgs += indP + skill_list[j] + " : +" + itoa(itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) + "<br>";
else if((itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) < 0)
skill_dmgs += indP + skill_list[j] + " : -" + itoa(itembonuses.SkillDamageAmount[j] + spellbonuses.SkillDamageAmount[j]) + "<br>";
}
std::string faction_item_string = "";
char faction_buf[256];
for (auto iter = item_faction_bonuses.begin(); iter != item_faction_bonuses.end(); ++iter) {
memset(&faction_buf, 0, sizeof(faction_buf));
if(!content_db.GetFactionName((int)((*iter).first), faction_buf, sizeof(faction_buf)))
strcpy(faction_buf, "Not in DB");
if((*iter).second > 0) {
faction_item_string += indP + faction_buf + " : +" + itoa((*iter).second) + "<br>";
}
else if((*iter).second < 0) {
faction_item_string += indP + faction_buf + " : -" + itoa((*iter).second) + "<br>";
}
}
std::string bard_info = "";
if(GetClass() == BARD) {
bard_info = indP + "Singing: " + itoa(GetSingMod()) + "<br>" +
indP + "Brass: " + itoa(GetBrassMod()) + "<br>" +
indP + "String: " + itoa(GetStringMod()) + "<br>" +
indP + "Percussion: " + itoa(GetPercMod()) + "<br>" +
indP + "Wind: " + itoa(GetWindMod()) + "<br>";
}
EQ::skills::SkillType skill = EQ::skills::SkillHandtoHand;
auto *inst = GetInv().GetItem(EQ::invslot::slotPrimary);
if (inst && inst->IsClassCommon()) {
switch (inst->GetItem()->ItemType) {
case EQ::item::ItemType1HSlash:
skill = EQ::skills::Skill1HSlashing;
break;
case EQ::item::ItemType2HSlash:
skill = EQ::skills::Skill2HSlashing;
break;
case EQ::item::ItemType1HPiercing:
skill = EQ::skills::Skill1HPiercing;
break;
case EQ::item::ItemType1HBlunt:
skill = EQ::skills::Skill1HBlunt;
break;
case EQ::item::ItemType2HBlunt:
skill = EQ::skills::Skill2HBlunt;
break;
case EQ::item::ItemType2HPiercing:
if (ClientVersion() < EQ::versions::ClientVersion::RoF2)
skill = EQ::skills::Skill1HPiercing;
else
skill = EQ::skills::Skill2HPiercing;
break;
default:
break;
}
}
std::ostringstream final_string;
final_string <<
/* C/L/R */ indP << "Class: " << class_Name << indS << "Level: " << static_cast<int>(GetLevel()) << indS << "Race: " << race_name << "<br>" <<
/* Runes */ indP << "Rune: " << rune_number << indL << indS << "Spell Rune: " << magic_rune_number << "<br>" <<
/* HP/M/E */ HME_row <<
/* DS */ indP << "DS: " << (itembonuses.DamageShield + spellbonuses.DamageShield*-1) << " (Spell: " << (spellbonuses.DamageShield*-1) << " + Item: " << itembonuses.DamageShield << " / " << RuleI(Character, ItemDamageShieldCap) << ")<br>" <<
/* Atk */ indP << "<c \"#CCFF00\">tohit: " << compute_tohit(skill) << " / " << GetTotalToHit(skill, 0) << "</c><br>" <<
/* Atk2 */ indP << "- Offense: " << offense(skill) << " | Item: " << itembonuses.ATK << " (" << RuleI(Character, ItemATKCap) << ")~Used: " << (itembonuses.ATK * 1.342) << " | Spell: " << spellbonuses.ATK << "<br>" <<
/* AC */ indP << "<c \"#CCFF00\">mitigation AC: " << GetMitigationAC() << "</c><br>" <<
/* AC2 */ indP << "- defense: " << compute_defense() << " / " << GetTotalDefense() << " | Spell: " << spellbonuses.AC << " | Shield: " << shield_ac << "<br>" <<
/* Haste */ indP << "<c \"#CCFF00\">Haste: " << GetHaste() << "</c><br>" <<
/* Haste2 */ indP << " - Item: " << itembonuses.haste << " + Spell: " << (spellbonuses.haste + spellbonuses.hastetype2) << " (Cap: " << RuleI(Character, HasteCap) << ") | Over: " << (spellbonuses.hastetype3 + ExtraHaste) << "<br>" <<
/* RunSpeed*/ indP << "<c \"#CCFF00\">Runspeed: " << GetRunspeed() << "</c><br>" <<
/* RegenLbl */ indL << indS << "Regen<br>" << indS << indP << indP << " Base | Items (Cap) " << indP << " | Spell | A.A.s | Total<br>" <<
/* Regen */ regen_string << "<br>" <<
/* Stats */ stat_field << "<br><br>" <<
/* Mod2s */ mod2_field << "<br>" <<
/* HealAmt */ indP << "Heal Amount: " << GetHealAmt() << " / " << RuleI(Character, ItemHealAmtCap) << "<br>" <<
/* SpellDmg*/ indP << "Spell Dmg: " << GetSpellDmg() << " / " << RuleI(Character, ItemSpellDmgCap) << "<br>" <<
/* Clair */ indP << "Clairvoyance: " << GetClair() << " / " << RuleI(Character, ItemClairvoyanceCap) << "<br>" <<
/* DSMit */ indP << "Dmg Shld Mit: " << GetDSMit() << " / " << RuleI(Character, ItemDSMitigationCap) << "<br><br>";
if(GetClass() == BARD)
final_string << bard_info << "<br>";
if(skill_mods.size() > 0)
final_string << skill_mods << "<br>";
if(skill_dmgs.size() > 0)
final_string << skill_dmgs << "<br>";
if(faction_item_string.size() > 0)
final_string << faction_item_string;
std::string final_stats = final_string.str();
if(use_window) {
if(final_stats.size() < 4096)
{
uint32 Buttons = (client->ClientVersion() < EQ::versions::ClientVersion::SoD) ? 0 : 1;
client->SendWindow(0, POPUPID_UPDATE_SHOWSTATSWINDOW, Buttons, "Cancel", "Update", 0, 1, this, "", "%s", final_stats.c_str());
goto Extra_Info;
}
else {
client->Message(Chat::Yellow, "The window has exceeded its character limit, displaying stats to chat window:");
}
}
client->Message(Chat::Yellow, "~~~~~ %s %s ~~~~~", GetCleanName(), GetLastName());
client->Message(Chat::White, " Level: %i Class: %i Race: %i DS: %i/%i Size: %1.1f Weight: %.1f/%d ", GetLevel(), GetClass(), GetRace(), GetDS(), RuleI(Character, ItemDamageShieldCap), GetSize(), (float)CalcCurrentWeight() / 10.0f, GetSTR());
client->Message(Chat::White, " HP: %i/%i HP Regen: %i/%i",GetHP(), GetMaxHP(), CalcHPRegen(), CalcHPRegenCap());
client->Message(Chat::White, " compute_tohit: %i TotalToHit: %i", compute_tohit(skill), GetTotalToHit(skill, 0));
client->Message(Chat::White, " compute_defense: %i TotalDefense: %i", compute_defense(), GetTotalDefense());
client->Message(Chat::White, " offense: %i mitigation ac: %i", offense(skill), GetMitigationAC());
client->Message(Chat::White, " AFK: %i LFG: %i Anon: %i PVP: %i GM: %i Flymode: %i GMSpeed: %i Hideme: %i GMInvul: %d LD: %i ClientVersion: %i TellsOff: %i", AFK, LFG, GetAnon(), GetPVP(), GetGM(), flymode, GetGMSpeed(), GetHideMe(), GetGMInvul(), IsLD(), ClientVersionBit(), tellsoff);
if(CalcMaxMana() > 0)
client->Message(Chat::White, " Mana: %i/%i Mana Regen: %i/%i", GetMana(), GetMaxMana(), CalcManaRegen(), CalcManaRegenCap());
client->Message(Chat::White, " End.: %i/%i End. Regen: %i/%i",GetEndurance(), GetMaxEndurance(), CalcEnduranceRegen(), CalcEnduranceRegenCap());
client->Message(Chat::White, " ATK: %i Worn/Spell ATK %i/%i Server Side ATK: %i", GetTotalATK(), RuleI(Character, ItemATKCap), GetATKBonus(), GetATK());
client->Message(Chat::White, " Haste: %i / %i (Item: %i + Spell: %i + Over: %i) Run speed: %i", GetHaste(), RuleI(Character, HasteCap), itembonuses.haste, spellbonuses.haste + spellbonuses.hastetype2, spellbonuses.hastetype3 + ExtraHaste, GetRunspeed());
client->Message(Chat::White, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA());
client->Message(Chat::White, " hSTR: %i hSTA: %i hDEX: %i hAGI: %i hINT: %i hWIS: %i hCHA: %i", GetHeroicSTR(), GetHeroicSTA(), GetHeroicDEX(), GetHeroicAGI(), GetHeroicINT(), GetHeroicWIS(), GetHeroicCHA());
client->Message(Chat::White, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR());
client->Message(Chat::White, " hMR: %i hPR: %i hFR: %i hCR: %i hDR: %i hCorruption: %i", GetHeroicMR(), GetHeroicPR(), GetHeroicFR(), GetHeroicCR(), GetHeroicDR(), GetHeroicCorrup());
client->Message(Chat::White, " Shielding: %i Spell Shield: %i DoT Shielding: %i Stun Resist: %i Strikethrough: %i Avoidance: %i Accuracy: %i Combat Effects: %i", GetShielding(), GetSpellShield(), GetDoTShield(), GetStunResist(), GetStrikeThrough(), GetAvoidance(), GetAccuracy(), GetCombatEffects());
client->Message(Chat::White, " Heal Amt.: %i Spell Dmg.: %i Clairvoyance: %i DS Mitigation: %i", GetHealAmt(), GetSpellDmg(), GetClair(), GetDSMit());
if(GetClass() == BARD)
client->Message(Chat::White, " Singing: %i Brass: %i String: %i Percussion: %i Wind: %i", GetSingMod(), GetBrassMod(), GetStringMod(), GetPercMod(), GetWindMod());
Extra_Info:
client->Message(Chat::White, " BaseRace: %i Gender: %i BaseGender: %i Texture: %i HelmTexture: %i", GetBaseRace(), GetGender(), GetBaseGender(), GetTexture(), GetHelmTexture());
if (client->Admin() >= AccountStatus::GMAdmin) {
client->Message(Chat::White, " CharID: %i EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", CharacterID(), GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted);
}
}
void Client::SendAltCurrencies() {
if (ClientVersion() >= EQ::versions::ClientVersion::SoF) {
uint32 count = zone->AlternateCurrencies.size();