Compare commits

...

10 Commits

Author SHA1 Message Date
KimLS b894d7ee3a update base character data repo 2024-10-12 12:52:07 -07:00
KimLS eecfce6514 update allocations table base repo 2024-10-12 12:41:38 -07:00
KimLS 2d6950149a Fix for server side everything showing as MR 2024-10-12 12:12:57 -07:00
KimLS 3945a8c0c0 Add titanium support 2024-10-12 12:02:40 -07:00
KimLS f27209a812 Add sof support 2024-10-12 11:27:37 -07:00
KimLS d4982743bf Add sod support 2024-10-12 11:23:59 -07:00
KimLS e2dd8f5f60 Add support to rof 2024-10-12 11:13:24 -07:00
KimLS bfc0cceecc Basics work for rof2 2024-10-12 11:06:36 -07:00
KimLS c9902881b7 Generate repo; create will save resists to db 2024-10-12 10:47:03 -07:00
KimLS 62bb426847 working on loading resists from character create. 2024-10-11 23:33:23 -07:00
20 changed files with 711 additions and 666 deletions
+6
View File
@@ -514,6 +514,12 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
c.raid_auto_consent = pp->raidAutoconsent; c.raid_auto_consent = pp->raidAutoconsent;
c.guild_auto_consent = pp->guildAutoconsent; c.guild_auto_consent = pp->guildAutoconsent;
c.RestTimer = pp->RestTimer; c.RestTimer = pp->RestTimer;
c.cold_resist = pp->cold_resist;
c.fire_resist = pp->fire_resist;
c.magic_resist = pp->magic_resist;
c.disease_resist = pp->disease_resist;
c.poison_resist = pp->poison_resist;
c.corruption_resist = pp->corruption_resist;
CharacterDataRepository::ReplaceOne(*this, c); CharacterDataRepository::ReplaceOne(*this, c);
+6
View File
@@ -1121,6 +1121,12 @@ struct PlayerProfile_Struct
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005) /*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
/*19564*/ uint32 RestTimer; /*19564*/ uint32 RestTimer;
/*19568*/ uint32 char_id; // Found as part of bazaar revamp (5/15/2024) /*19568*/ uint32 char_id; // Found as part of bazaar revamp (5/15/2024)
/*19572*/ uint32 cold_resist;
/*19576*/ uint32 fire_resist;
/*19580*/ uint32 magic_resist;
/*19584*/ uint32 disease_resist;
/*19588*/ uint32 poison_resist;
/*19592*/ uint32 corruption_resist;
// All player profile packets are translated and this overhead is ignored in out-bound packets // All player profile packets are translated and this overhead is ignored in out-bound packets
PlayerProfile_Struct() : m_player_profile_version(EQ::versions::MobVersion::Unknown) { } PlayerProfile_Struct() : m_player_profile_version(EQ::versions::MobVersion::Unknown) { }
+6 -6
View File
@@ -2288,13 +2288,13 @@ namespace RoF
outapp->WriteSInt32(345); // Mana Total ? outapp->WriteSInt32(345); // Mana Total ?
// these are needed to fix display bugs // these are needed to fix display bugs
outapp->WriteUInt32(0x19); // base CR outapp->WriteUInt32(emu->cold_resist); // base CR
outapp->WriteUInt32(0x19); // base FR outapp->WriteUInt32(emu->fire_resist); // base FR
outapp->WriteUInt32(0x19); // base MR outapp->WriteUInt32(emu->magic_resist); // base MR
outapp->WriteUInt32(0xf); // base DR outapp->WriteUInt32(emu->disease_resist); // base DR
outapp->WriteUInt32(0xf); // base PR outapp->WriteUInt32(emu->poison_resist); // base PR
outapp->WriteUInt32(0xf); // base PhR? outapp->WriteUInt32(0xf); // base PhR?
outapp->WriteUInt32(0xf); // base Corrup outapp->WriteUInt32(emu->corruption_resist); // base Corrup
outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown
+6 -6
View File
@@ -2806,13 +2806,13 @@ namespace RoF2
outapp->WriteSInt32(345); // Mana Total ? outapp->WriteSInt32(345); // Mana Total ?
// these are needed to fix display bugs // these are needed to fix display bugs
outapp->WriteUInt32(0x19); // base CR outapp->WriteUInt32(emu->cold_resist); // base CR
outapp->WriteUInt32(0x19); // base FR outapp->WriteUInt32(emu->fire_resist); // base FR
outapp->WriteUInt32(0x19); // base MR outapp->WriteUInt32(emu->magic_resist); // base MR
outapp->WriteUInt32(0xf); // base DR outapp->WriteUInt32(emu->disease_resist); // base DR
outapp->WriteUInt32(0xf); // base PR outapp->WriteUInt32(emu->poison_resist); // base PR
outapp->WriteUInt32(0xf); // base PhR? outapp->WriteUInt32(0xf); // base PhR?
outapp->WriteUInt32(0xf); // base Corrup outapp->WriteUInt32(emu->corruption_resist); // base Corrup
outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown
+19 -7
View File
@@ -1669,15 +1669,27 @@ namespace SoD
// OUT(unknown19584[4]); // OUT(unknown19584[4]);
// OUT(unknown19588); // OUT(unknown19588);
const uint8 bytes[] = { const uint8 unknown12864_bytes[] = {
0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F,
0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
memcpy(eq->unknown12864, bytes, sizeof(bytes)); memcpy(eq->unknown12864, unknown12864_bytes, sizeof(unknown12864_bytes));
eq->cold_resist = emu->cold_resist;
eq->fire_resist = emu->fire_resist;
eq->magic_resist = emu->magic_resist;
eq->disease_resist = emu->disease_resist;
eq->poison_resist = emu->poison_resist;
eq->physical_resist = 15;
eq->corruption_resist = emu->corruption_resist;
const uint8 unknown15112_bytes[] = {
0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
memcpy(eq->unknown15112, unknown15112_bytes, sizeof(unknown15112_bytes));
//set the checksum... //set the checksum...
CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4); CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4);
+9 -1
View File
@@ -944,7 +944,15 @@ struct PlayerProfile_Struct
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot /*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8]; /*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots; /*15068*/ uint32 available_slots;
/*15072*/ uint8 unknown12864[80]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80] /*15072*/ uint8 unknown12864[12]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80]
/*15084*/ uint32 cold_resist;
/*15088*/ uint32 fire_resist;
/*15092*/ uint32 magic_resist;
/*15096*/ uint32 disease_resist;
/*15100*/ uint32 poison_resist;
/*15104*/ uint32 physical_resist;
/*15108*/ uint32 corruption_resist;
/*15112*/ uint8 unknown15112[40];
//END SUB-STRUCT used for shrouding. //END SUB-STRUCT used for shrouding.
/*15152*/ char name[64]; // Name of player /*15152*/ char name[64]; // Name of player
/*15216*/ char last_name[32]; // Last name of player /*15216*/ char last_name[32]; // Last name of player
+19 -7
View File
@@ -1339,15 +1339,27 @@ namespace SoF
// OUT(unknown19584[4]); // OUT(unknown19584[4]);
// OUT(unknown19588); // OUT(unknown19588);
const uint8 bytes[] = { const uint8 unknown12864_bytes[] = {
0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F,
0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
memcpy(eq->unknown12864, bytes, sizeof(bytes)); memcpy(eq->unknown12864, unknown12864_bytes, sizeof(unknown12864_bytes));
eq->cold_resist = emu->cold_resist;
eq->fire_resist = emu->fire_resist;
eq->magic_resist = emu->magic_resist;
eq->disease_resist = emu->disease_resist;
eq->poison_resist = emu->poison_resist;
eq->physical_resist = 15;
eq->corruption_resist = emu->corruption_resist;
const uint8 unknown15112_bytes[] = {
0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
memcpy(eq->unknown15112, unknown15112_bytes, sizeof(unknown15112_bytes));
//set the checksum... //set the checksum...
CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4); CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4);
+10 -1
View File
@@ -944,7 +944,16 @@ struct PlayerProfile_Struct //23576 Octets
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot /*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8]; /*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots; /*15068*/ uint32 available_slots;
/*15072*/ uint8 unknown12864[80]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80] /*15072*/ uint8 unknown12864[12]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80]
/*15084*/ uint32 cold_resist;
/*15088*/ uint32 fire_resist;
/*15092*/ uint32 magic_resist;
/*15096*/ uint32 disease_resist;
/*15100*/ uint32 poison_resist;
/*15104*/ uint32 physical_resist;
/*15108*/ uint32 corruption_resist;
/*15112*/ uint8 unknown15112[40];
//END SUB-STRUCT used for shrouding. //END SUB-STRUCT used for shrouding.
/*15120*/ char name[64]; // Name of player /*15120*/ char name[64]; // Name of player
/*15184*/ char last_name[32]; // Last name of player /*15184*/ char last_name[32]; // Last name of player
+16 -5
View File
@@ -1600,14 +1600,25 @@ namespace Titanium
// OUT(unknown19584[4]); // OUT(unknown19584[4]);
// OUT(unknown19588); // OUT(unknown19588);
const uint8 unknown12864_bytes[] = {
0x78, 0x03, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00
};
const uint8 bytes[] = { memcpy(eq->unknown12864, unknown12864_bytes, sizeof(unknown12864_bytes));
0x78, 0x03, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, eq->cold_resist = emu->cold_resist;
0x0F, 0x00, 0x00, 0x00, 0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x09, 0x00, 0x00, 0x00, eq->fire_resist = emu->fire_resist;
eq->magic_resist = emu->magic_resist;
eq->disease_resist = emu->disease_resist;
eq->poison_resist = emu->poison_resist;
eq->physical_resist = 15;
const uint8 unknown12900_bytes[] = {
0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x09, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14
}; };
memcpy(eq->unknown12864, bytes, sizeof(bytes));
memcpy(eq->unknown12900, unknown12900_bytes, sizeof(unknown12900_bytes));
//set the checksum... //set the checksum...
CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4); CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4);
+8 -1
View File
@@ -879,7 +879,14 @@ struct PlayerProfile_Struct
/*12564*/ PotionBelt_Struct potionbelt; // potion belt /*12564*/ PotionBelt_Struct potionbelt; // potion belt
/*12852*/ uint8 unknown12852[8]; /*12852*/ uint8 unknown12852[8];
/*12860*/ uint32 available_slots; /*12860*/ uint32 available_slots;
/*12864*/ uint8 unknown12864[76]; /*12864*/ uint8 unknown12864[12];
/*12876*/ uint32 cold_resist;
/*12880*/ uint32 fire_resist;
/*12884*/ uint32 magic_resist;
/*12888*/ uint32 disease_resist;
/*12892*/ uint32 poison_resist;
/*12896*/ uint32 physical_resist;
/*12900*/ uint8 unknown12900[40];
/*12940*/ char name[64]; // Name of player /*12940*/ char name[64]; // Name of player
/*13004*/ char last_name[32]; // Last name of player /*13004*/ char last_name[32]; // Last name of player
/*13036*/ uint32 guild_id; // guildid /*13036*/ uint32 guild_id; // guildid
@@ -34,6 +34,12 @@ public:
uint32_t alloc_int; uint32_t alloc_int;
uint32_t alloc_wis; uint32_t alloc_wis;
uint32_t alloc_cha; uint32_t alloc_cha;
uint32_t base_cr;
uint32_t base_fr;
uint32_t base_mr;
uint32_t base_dr;
uint32_t base_pr;
uint32_t base_corrup;
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
@@ -59,6 +65,12 @@ public:
"alloc_int", "alloc_int",
"alloc_wis", "alloc_wis",
"alloc_cha", "alloc_cha",
"base_cr",
"base_fr",
"base_mr",
"base_dr",
"base_pr",
"base_corrup",
}; };
} }
@@ -80,6 +92,12 @@ public:
"alloc_int", "alloc_int",
"alloc_wis", "alloc_wis",
"alloc_cha", "alloc_cha",
"base_cr",
"base_fr",
"base_mr",
"base_dr",
"base_pr",
"base_corrup",
}; };
} }
@@ -135,6 +153,12 @@ public:
e.alloc_int = 0; e.alloc_int = 0;
e.alloc_wis = 0; e.alloc_wis = 0;
e.alloc_cha = 0; e.alloc_cha = 0;
e.base_cr = 0;
e.base_fr = 0;
e.base_mr = 0;
e.base_dr = 0;
e.base_pr = 0;
e.base_corrup = 0;
return e; return e;
} }
@@ -186,6 +210,12 @@ public:
e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0; e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0; e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0; e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.base_cr = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.base_fr = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 0;
e.base_mr = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 0;
e.base_dr = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.base_pr = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.base_corrup = row[20] ? static_cast<uint32_t>(strtoul(row[20], nullptr, 10)) : 0;
return e; return e;
} }
@@ -234,6 +264,12 @@ public:
v.push_back(columns[12] + " = " + std::to_string(e.alloc_int)); v.push_back(columns[12] + " = " + std::to_string(e.alloc_int));
v.push_back(columns[13] + " = " + std::to_string(e.alloc_wis)); v.push_back(columns[13] + " = " + std::to_string(e.alloc_wis));
v.push_back(columns[14] + " = " + std::to_string(e.alloc_cha)); v.push_back(columns[14] + " = " + std::to_string(e.alloc_cha));
v.push_back(columns[15] + " = " + std::to_string(e.base_cr));
v.push_back(columns[16] + " = " + std::to_string(e.base_fr));
v.push_back(columns[17] + " = " + std::to_string(e.base_mr));
v.push_back(columns[18] + " = " + std::to_string(e.base_dr));
v.push_back(columns[19] + " = " + std::to_string(e.base_pr));
v.push_back(columns[20] + " = " + std::to_string(e.base_corrup));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -270,6 +306,12 @@ public:
v.push_back(std::to_string(e.alloc_int)); v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis)); v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha)); v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -314,6 +356,12 @@ public:
v.push_back(std::to_string(e.alloc_int)); v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis)); v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha)); v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
@@ -362,6 +410,12 @@ public:
e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0; e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0; e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0; e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.base_cr = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.base_fr = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 0;
e.base_mr = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 0;
e.base_dr = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.base_pr = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.base_corrup = row[20] ? static_cast<uint32_t>(strtoul(row[20], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@@ -401,6 +455,12 @@ public:
e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0; e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0; e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0; e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.base_cr = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.base_fr = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 0;
e.base_mr = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 0;
e.base_dr = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.base_pr = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.base_corrup = row[20] ? static_cast<uint32_t>(strtoul(row[20], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@@ -490,6 +550,12 @@ public:
v.push_back(std::to_string(e.alloc_int)); v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis)); v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha)); v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -527,6 +593,12 @@ public:
v.push_back(std::to_string(e.alloc_int)); v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis)); v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha)); v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
@@ -123,6 +123,12 @@ public:
uint32_t aa_points_old; uint32_t aa_points_old;
uint32_t e_last_invsnapshot; uint32_t e_last_invsnapshot;
time_t deleted_at; time_t deleted_at;
uint32_t cold_resist;
uint32_t fire_resist;
uint32_t magic_resist;
uint32_t disease_resist;
uint32_t poison_resist;
uint32_t corruption_resist;
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
@@ -237,6 +243,12 @@ public:
"aa_points_old", "aa_points_old",
"e_last_invsnapshot", "e_last_invsnapshot",
"deleted_at", "deleted_at",
"cold_resist",
"fire_resist",
"magic_resist",
"disease_resist",
"poison_resist",
"corruption_resist",
}; };
} }
@@ -347,6 +359,12 @@ public:
"aa_points_old", "aa_points_old",
"e_last_invsnapshot", "e_last_invsnapshot",
"UNIX_TIMESTAMP(deleted_at)", "UNIX_TIMESTAMP(deleted_at)",
"cold_resist",
"fire_resist",
"magic_resist",
"disease_resist",
"poison_resist",
"corruption_resist",
}; };
} }
@@ -491,6 +509,12 @@ public:
e.aa_points_old = 0; e.aa_points_old = 0;
e.e_last_invsnapshot = 0; e.e_last_invsnapshot = 0;
e.deleted_at = 0; e.deleted_at = 0;
e.cold_resist = 0;
e.fire_resist = 0;
e.magic_resist = 0;
e.disease_resist = 0;
e.poison_resist = 0;
e.corruption_resist = 0;
return e; return e;
} }
@@ -631,6 +655,12 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0; e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0; e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10); e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.cold_resist = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.fire_resist = row[105] ? static_cast<uint32_t>(strtoul(row[105], nullptr, 10)) : 0;
e.magic_resist = row[106] ? static_cast<uint32_t>(strtoul(row[106], nullptr, 10)) : 0;
e.disease_resist = row[107] ? static_cast<uint32_t>(strtoul(row[107], nullptr, 10)) : 0;
e.poison_resist = row[108] ? static_cast<uint32_t>(strtoul(row[108], nullptr, 10)) : 0;
e.corruption_resist = row[109] ? static_cast<uint32_t>(strtoul(row[109], nullptr, 10)) : 0;
return e; return e;
} }
@@ -767,6 +797,12 @@ public:
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old)); v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old));
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot)); v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot));
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(columns[104] + " = " + std::to_string(e.cold_resist));
v.push_back(columns[105] + " = " + std::to_string(e.fire_resist));
v.push_back(columns[106] + " = " + std::to_string(e.magic_resist));
v.push_back(columns[107] + " = " + std::to_string(e.disease_resist));
v.push_back(columns[108] + " = " + std::to_string(e.poison_resist));
v.push_back(columns[109] + " = " + std::to_string(e.corruption_resist));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -892,6 +928,12 @@ public:
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -1025,6 +1067,12 @@ public:
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
@@ -1162,6 +1210,12 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0; e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0; e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10); e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.cold_resist = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.fire_resist = row[105] ? static_cast<uint32_t>(strtoul(row[105], nullptr, 10)) : 0;
e.magic_resist = row[106] ? static_cast<uint32_t>(strtoul(row[106], nullptr, 10)) : 0;
e.disease_resist = row[107] ? static_cast<uint32_t>(strtoul(row[107], nullptr, 10)) : 0;
e.poison_resist = row[108] ? static_cast<uint32_t>(strtoul(row[108], nullptr, 10)) : 0;
e.corruption_resist = row[109] ? static_cast<uint32_t>(strtoul(row[109], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@@ -1290,6 +1344,12 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0; e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0; e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10); e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.cold_resist = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.fire_resist = row[105] ? static_cast<uint32_t>(strtoul(row[105], nullptr, 10)) : 0;
e.magic_resist = row[106] ? static_cast<uint32_t>(strtoul(row[106], nullptr, 10)) : 0;
e.disease_resist = row[107] ? static_cast<uint32_t>(strtoul(row[107], nullptr, 10)) : 0;
e.poison_resist = row[108] ? static_cast<uint32_t>(strtoul(row[108], nullptr, 10)) : 0;
e.corruption_resist = row[109] ? static_cast<uint32_t>(strtoul(row[109], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@@ -1468,6 +1528,12 @@ public:
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -1594,6 +1660,12 @@ public:
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
+1
View File
@@ -56,6 +56,7 @@ SET(world_headers
login_server.h login_server.h
login_server_list.h login_server_list.h
queryserv.h queryserv.h
race_combos.h
shared_task_manager.h shared_task_manager.h
shared_task_world_messaging.h shared_task_world_messaging.h
sof_char_create_data.h sof_char_create_data.h
+354 -269
View File
@@ -47,6 +47,7 @@
#include "clientlist.h" #include "clientlist.h"
#include "wguild_mgr.h" #include "wguild_mgr.h"
#include "sof_char_create_data.h" #include "sof_char_create_data.h"
#include "race_combos.h"
#include "../common/zone_store.h" #include "../common/zone_store.h"
#include "../common/repositories/account_repository.h" #include "../common/repositories/account_repository.h"
#include "../common/repositories/player_event_logs_repository.h" #include "../common/repositories/player_event_logs_repository.h"
@@ -85,8 +86,8 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
std::vector<RaceClassAllocation> character_create_allocations; std::vector<CharCreatePointAllocation> character_create_allocations;
std::vector<RaceClassCombos> character_create_race_class_combos; std::vector<CharCreateCombination> character_create_race_class_combos;
extern ZSList zoneserver_list; extern ZSList zoneserver_list;
extern LoginServerList loginserverlist; extern LoginServerList loginserverlist;
@@ -1642,6 +1643,348 @@ void Client::SendApproveWorld()
safe_delete(outapp); safe_delete(outapp);
} }
// returns true if the request is ok, false if there's an error
bool CheckCharCreateInfoSoF(CharCreate_Struct* cc)
{
if (!cc)
return false;
LogInfo("Validating char creation info");
CharCreateCombination class_combo;
bool found = false;
int combos = character_create_race_class_combos.size();
for (int i = 0; i < combos; ++i) {
if (character_create_race_class_combos[i].Class == cc->class_ &&
character_create_race_class_combos[i].Race == cc->race &&
character_create_race_class_combos[i].Deity == cc->deity &&
character_create_race_class_combos[i].Zone == cc->start_zone) {
class_combo = character_create_race_class_combos[i];
found = true;
break;
}
}
if (!found) {
LogInfo("Could not find class/race/deity/start_zone combination");
return false;
}
uint32 allocs = character_create_allocations.size();
CharCreatePointAllocation allocation = { 0 };
found = false;
for (int i = 0; i < allocs; ++i) {
if (character_create_allocations[i].Index == class_combo.AllocationIndex) {
allocation = character_create_allocations[i];
found = true;
break;
}
}
if (!found) {
LogInfo("Could not find starting stats for selected character combo, cannot verify stats");
return false;
}
uint32 max_stats = allocation.DefaultPointAllocation[0] +
allocation.DefaultPointAllocation[1] +
allocation.DefaultPointAllocation[2] +
allocation.DefaultPointAllocation[3] +
allocation.DefaultPointAllocation[4] +
allocation.DefaultPointAllocation[5] +
allocation.DefaultPointAllocation[6];
if (cc->STR > allocation.BaseStats[0] + max_stats || cc->STR < allocation.BaseStats[0]) {
LogInfo("Strength out of range");
return false;
}
if (cc->DEX > allocation.BaseStats[1] + max_stats || cc->DEX < allocation.BaseStats[1]) {
LogInfo("Dexterity out of range");
return false;
}
if (cc->AGI > allocation.BaseStats[2] + max_stats || cc->AGI < allocation.BaseStats[2]) {
LogInfo("Agility out of range");
return false;
}
if (cc->STA > allocation.BaseStats[3] + max_stats || cc->STA < allocation.BaseStats[3]) {
LogInfo("Stamina out of range");
return false;
}
if (cc->INT > allocation.BaseStats[4] + max_stats || cc->INT < allocation.BaseStats[4]) {
LogInfo("Intelligence out of range");
return false;
}
if (cc->WIS > allocation.BaseStats[5] + max_stats || cc->WIS < allocation.BaseStats[5]) {
LogInfo("Wisdom out of range");
return false;
}
if (cc->CHA > allocation.BaseStats[6] + max_stats || cc->CHA < allocation.BaseStats[6]) {
LogInfo("Charisma out of range");
return false;
}
uint32 current_stats = 0;
current_stats += cc->STR - allocation.BaseStats[0];
current_stats += cc->DEX - allocation.BaseStats[1];
current_stats += cc->AGI - allocation.BaseStats[2];
current_stats += cc->STA - allocation.BaseStats[3];
current_stats += cc->INT - allocation.BaseStats[4];
current_stats += cc->WIS - allocation.BaseStats[5];
current_stats += cc->CHA - allocation.BaseStats[6];
if (current_stats > max_stats) {
LogInfo("Current Stats > Maximum Stats");
return false;
}
return true;
}
bool CheckCharCreateInfoTitanium(CharCreate_Struct* cc)
{
uint32 bSTR, bSTA, bAGI, bDEX, bWIS, bINT, bCHA, bTOTAL, cTOTAL, stat_points; //these are all uint32 in CharCreate_Struct, so we'll make them uint32 here to make the compiler shut up
int classtemp, racetemp;
int Charerrors = 0;
// if this is increased you'll have to add a column to the classrace
// table below
#define _TABLE_RACES 16
static const int BaseRace[_TABLE_RACES][7] =
{ /* STR STA AGI DEX WIS INT CHR */
{ /*Human*/ 75, 75, 75, 75, 75, 75, 75},
{ /*Barbarian*/ 103, 95, 82, 70, 70, 60, 55},
{ /*Erudite*/ 60, 70, 70, 70, 83, 107, 70},
{ /*Wood Elf*/ 65, 65, 95, 80, 80, 75, 75},
{ /*High Elf*/ 55, 65, 85, 70, 95, 92, 80},
{ /*Dark Elf*/ 60, 65, 90, 75, 83, 99, 60},
{ /*Half Elf*/ 70, 70, 90, 85, 60, 75, 75},
{ /*Dwarf*/ 90, 90, 70, 90, 83, 60, 45},
{ /*Troll*/ 108, 109, 83, 75, 60, 52, 40},
{ /*Ogre*/ 130, 122, 70, 70, 67, 60, 37},
{ /*Halfling*/ 70, 75, 95, 90, 80, 67, 50},
{ /*Gnome*/ 60, 70, 85, 85, 67, 98, 60},
{ /*Iksar*/ 70, 70, 90, 85, 80, 75, 55},
{ /*Vah Shir*/ 90, 75, 90, 70, 70, 65, 65},
{ /*Froglok*/ 70, 80, 100, 100, 75, 75, 50},
{ /*Drakkin*/ 70, 80, 85, 75, 80, 85, 75}
};
static const int BaseClass[Class::PLAYER_CLASS_COUNT][8] =
{ /* STR STA AGI DEX WIS INT CHR ADD*/
{ /*Warrior*/ 10, 10, 5, 0, 0, 0, 0, 25},
{ /*Cleric*/ 5, 5, 0, 0, 10, 0, 0, 30},
{ /*Paladin*/ 10, 5, 0, 0, 5, 0, 10, 20},
{ /*Ranger*/ 5, 10, 10, 0, 5, 0, 0, 20},
{ /*ShadowKnight*/ 10, 5, 0, 0, 0, 10, 5, 20},
{ /*Druid*/ 0, 10, 0, 0, 10, 0, 0, 30},
{ /*Monk*/ 5, 5, 10, 10, 0, 0, 0, 20},
{ /*Bard*/ 5, 0, 0, 10, 0, 0, 10, 25},
{ /*Rouge*/ 0, 0, 10, 10, 0, 0, 0, 30},
{ /*Shaman*/ 0, 5, 0, 0, 10, 0, 5, 30},
{ /*Necromancer*/ 0, 0, 0, 10, 0, 10, 0, 30},
{ /*Wizard*/ 0, 10, 0, 0, 0, 10, 0, 30},
{ /*Magician*/ 0, 10, 0, 0, 0, 10, 0, 30},
{ /*Enchanter*/ 0, 0, 0, 0, 0, 10, 10, 30},
{ /*Beastlord*/ 0, 10, 5, 0, 10, 0, 5, 20},
{ /*Berserker*/ 10, 5, 0, 10, 0, 0, 0, 25}
};
static const bool ClassRaceLookupTable[Class::PLAYER_CLASS_COUNT][_TABLE_RACES] =
{ /*Human Barbarian Erudite Woodelf Highelf Darkelf Halfelf Dwarf Troll Ogre Halfling Gnome Iksar Vahshir Froglok Drakkin*/
{ /*Warrior*/ true, true, false, true, false, true, true, true, true, true, true, true, true, true, true, true},
{ /*Cleric*/ true, false, true, false, true, true, true, true, false, false, true, true, false, false, true, true},
{ /*Paladin*/ true, false, true, false, true, false, true, true, false, false, true, true, false, false, true, true},
{ /*Ranger*/ true, false, false, true, false, false, true, false, false, false, true, false, false, false, false, true},
{ /*ShadowKnight*/ true, false, true, false, false, true, false, false, true, true, false, true, true, false, true, true},
{ /*Druid*/ true, false, false, true, false, false, true, false, false, false, true, false, false, false, false, true},
{ /*Monk*/ true, false, false, false, false, false, false, false, false, false, false, false, true, false, false, true},
{ /*Bard*/ true, false, false, true, false, false, true, false, false, false, false, false, false, true, false, true},
{ /*Rogue*/ true, true, false, true, false, true, true, true, false, false, true, true, false, true, true, true},
{ /*Shaman*/ false, true, false, false, false, false, false, false, true, true, false, false, true, true, true, false},
{ /*Necromancer*/ true, false, true, false, false, true, false, false, false, false, false, true, true, false, true, true},
{ /*Wizard*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, true, true},
{ /*Magician*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, false, true},
{ /*Enchanter*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, false, true},
{ /*Beastlord*/ false, true, false, false, false, false, false, false, true, true, false, false, true, true, false, false},
{ /*Berserker*/ false, true, false, false, false, false, false, true, true, true, false, false, false, true, false, false}
};
if (!cc)
return false;
LogInfo("Validating char creation info");
classtemp = cc->class_ - 1;
racetemp = cc->race - 1;
// these have non sequential race numbers so they need to be mapped
if (cc->race == FROGLOK) racetemp = 14;
if (cc->race == VAHSHIR) racetemp = 13;
if (cc->race == IKSAR) racetemp = 12;
if (cc->race == DRAKKIN) racetemp = 15;
// if out of range looking it up in the table would crash stuff
// so we return from these
if (classtemp >= Class::PLAYER_CLASS_COUNT) {
LogInfo(" class is out of range");
return false;
}
if (racetemp >= _TABLE_RACES) {
LogInfo(" race is out of range");
return false;
}
if (!ClassRaceLookupTable[classtemp][racetemp]) { //Lookup table better than a bunch of ifs?
LogInfo(" invalid race/class combination");
// we return from this one, since if it's an invalid combination our table
// doesn't have meaningful values for the stats
return false;
}
// add up the base values for this class/race
// this is what they start with, and they have stat_points more
// that can distributed
bSTR = BaseClass[classtemp][0] + BaseRace[racetemp][0];
bSTA = BaseClass[classtemp][1] + BaseRace[racetemp][1];
bAGI = BaseClass[classtemp][2] + BaseRace[racetemp][2];
bDEX = BaseClass[classtemp][3] + BaseRace[racetemp][3];
bWIS = BaseClass[classtemp][4] + BaseRace[racetemp][4];
bINT = BaseClass[classtemp][5] + BaseRace[racetemp][5];
bCHA = BaseClass[classtemp][6] + BaseRace[racetemp][6];
stat_points = BaseClass[classtemp][7];
bTOTAL = bSTR + bSTA + bAGI + bDEX + bWIS + bINT + bCHA;
cTOTAL = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;
// the first check makes sure the total is exactly what was expected.
// this will catch all the stat cheating, but there's still the issue
// of reducing CHA or INT or something, to use for STR, so we check
// that none are lower than the base or higher than base + stat_points
// NOTE: these could just be else if, but i want to see all the stats
// that are messed up not just the first hit
if (bTOTAL + stat_points != cTOTAL) {
LogInfo(" stat points total doesn't match expected value: expecting [{}] got [{}]", bTOTAL + stat_points, cTOTAL);
Charerrors++;
}
if (cc->STR > bSTR + stat_points || cc->STR < bSTR) {
LogInfo(" stat STR is out of range");
Charerrors++;
}
if (cc->STA > bSTA + stat_points || cc->STA < bSTA) {
LogInfo(" stat STA is out of range");
Charerrors++;
}
if (cc->AGI > bAGI + stat_points || cc->AGI < bAGI) {
LogInfo(" stat AGI is out of range");
Charerrors++;
}
if (cc->DEX > bDEX + stat_points || cc->DEX < bDEX) {
LogInfo(" stat DEX is out of range");
Charerrors++;
}
if (cc->WIS > bWIS + stat_points || cc->WIS < bWIS) {
LogInfo(" stat WIS is out of range");
Charerrors++;
}
if (cc->INT > bINT + stat_points || cc->INT < bINT) {
LogInfo(" stat INT is out of range");
Charerrors++;
}
if (cc->CHA > bCHA + stat_points || cc->CHA < bCHA) {
LogInfo(" stat CHA is out of range");
Charerrors++;
}
/*TODO: Check for deity/class/race.. it'd be nice, but probably of any real use to hack(faction, deity based items are all I can think of)
I am NOT writing those tables - kathgar*/
LogInfo("Found [{}] errors in character creation request", Charerrors);
return Charerrors == 0;
}
//TODO: these hard coded values should be settable somewhere somehow.
//Also they're not 100% accurate so if I don't make them settable somehow
//we need to go back and match them to the logic that was ripped out of zone
void GetResistsForCharacterCreate(CharCreate_Struct* cc,
bool sofAndLater,
uint32 &cold_resist,
uint32& fire_resist,
uint32& magic_resist,
uint32& disease_resist,
uint32& poison_resist,
uint32& corruption_resist)
{
if (!sofAndLater) {
cold_resist = 25;
fire_resist = 25;
magic_resist = 25;
disease_resist = 15;
poison_resist = 15;
corruption_resist = 15;
return;
}
CharCreateCombination class_combo;
bool found = false;
int combos = character_create_race_class_combos.size();
for (int i = 0; i < combos; ++i) {
if (character_create_race_class_combos[i].Class == cc->class_ &&
character_create_race_class_combos[i].Race == cc->race &&
character_create_race_class_combos[i].Deity == cc->deity &&
character_create_race_class_combos[i].Zone == cc->start_zone) {
class_combo = character_create_race_class_combos[i];
found = true;
break;
}
}
if (!found) {
cold_resist = 25;
fire_resist = 25;
magic_resist = 25;
disease_resist = 15;
poison_resist = 15;
corruption_resist = 15;
return;
}
CharCreatePointAllocation allocation;
found = false;
combos = character_create_allocations.size();
for (int i = 0; i < combos; ++i) {
if (character_create_allocations[i].Index == class_combo.AllocationIndex) {
allocation = character_create_allocations[i];
found = true;
break;
}
}
if (!found) {
cold_resist = 25;
fire_resist = 25;
magic_resist = 25;
disease_resist = 15;
poison_resist = 15;
corruption_resist = 15;
return;
}
cold_resist = allocation.BaseResists[0];
fire_resist = allocation.BaseResists[1];
magic_resist = allocation.BaseResists[2];
disease_resist = allocation.BaseResists[3];
poison_resist = allocation.BaseResists[4];
corruption_resist = allocation.BaseResists[5];
}
bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
{ {
PlayerProfile_Struct pp; PlayerProfile_Struct pp;
@@ -1745,6 +2088,15 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
pp.hunger_level = 6000; pp.hunger_level = 6000;
pp.thirst_level = 6000; pp.thirst_level = 6000;
GetResistsForCharacterCreate(cc,
m_ClientVersionBit & EQ::versions::maskSoFAndLater,
pp.cold_resist,
pp.fire_resist,
pp.magic_resist,
pp.disease_resist,
pp.poison_resist,
pp.corruption_resist);
/* Set default skills for everybody */ /* Set default skills for everybody */
pp.skills[EQ::skills::SkillSwimming] = RuleI(Skills, SwimmingStartValue); pp.skills[EQ::skills::SkillSwimming] = RuleI(Skills, SwimmingStartValue);
pp.skills[EQ::skills::SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue); pp.skills[EQ::skills::SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue);
@@ -1865,273 +2217,6 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
return success; return success;
} }
// returns true if the request is ok, false if there's an error
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
{
if (!cc)
return false;
LogInfo("Validating char creation info");
RaceClassCombos class_combo;
bool found = false;
int combos = character_create_race_class_combos.size();
for (int i = 0; i < combos; ++i) {
if (character_create_race_class_combos[i].Class == cc->class_ &&
character_create_race_class_combos[i].Race == cc->race &&
character_create_race_class_combos[i].Deity == cc->deity &&
character_create_race_class_combos[i].Zone == cc->start_zone) {
class_combo = character_create_race_class_combos[i];
found = true;
break;
}
}
if (!found) {
LogInfo("Could not find class/race/deity/start_zone combination");
return false;
}
uint32 allocs = character_create_allocations.size();
RaceClassAllocation allocation = {0};
found = false;
for (int i = 0; i < allocs; ++i) {
if (character_create_allocations[i].Index == class_combo.AllocationIndex) {
allocation = character_create_allocations[i];
found = true;
break;
}
}
if (!found) {
LogInfo("Could not find starting stats for selected character combo, cannot verify stats");
return false;
}
uint32 max_stats = allocation.DefaultPointAllocation[0] +
allocation.DefaultPointAllocation[1] +
allocation.DefaultPointAllocation[2] +
allocation.DefaultPointAllocation[3] +
allocation.DefaultPointAllocation[4] +
allocation.DefaultPointAllocation[5] +
allocation.DefaultPointAllocation[6];
if (cc->STR > allocation.BaseStats[0] + max_stats || cc->STR < allocation.BaseStats[0]) {
LogInfo("Strength out of range");
return false;
}
if (cc->DEX > allocation.BaseStats[1] + max_stats || cc->DEX < allocation.BaseStats[1]) {
LogInfo("Dexterity out of range");
return false;
}
if (cc->AGI > allocation.BaseStats[2] + max_stats || cc->AGI < allocation.BaseStats[2]) {
LogInfo("Agility out of range");
return false;
}
if (cc->STA > allocation.BaseStats[3] + max_stats || cc->STA < allocation.BaseStats[3]) {
LogInfo("Stamina out of range");
return false;
}
if (cc->INT > allocation.BaseStats[4] + max_stats || cc->INT < allocation.BaseStats[4]) {
LogInfo("Intelligence out of range");
return false;
}
if (cc->WIS > allocation.BaseStats[5] + max_stats || cc->WIS < allocation.BaseStats[5]) {
LogInfo("Wisdom out of range");
return false;
}
if (cc->CHA > allocation.BaseStats[6] + max_stats || cc->CHA < allocation.BaseStats[6]) {
LogInfo("Charisma out of range");
return false;
}
uint32 current_stats = 0;
current_stats += cc->STR - allocation.BaseStats[0];
current_stats += cc->DEX - allocation.BaseStats[1];
current_stats += cc->AGI - allocation.BaseStats[2];
current_stats += cc->STA - allocation.BaseStats[3];
current_stats += cc->INT - allocation.BaseStats[4];
current_stats += cc->WIS - allocation.BaseStats[5];
current_stats += cc->CHA - allocation.BaseStats[6];
if (current_stats > max_stats) {
LogInfo("Current Stats > Maximum Stats");
return false;
}
return true;
}
bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
{
uint32 bSTR, bSTA, bAGI, bDEX, bWIS, bINT, bCHA, bTOTAL, cTOTAL, stat_points; //these are all uint32 in CharCreate_Struct, so we'll make them uint32 here to make the compiler shut up
int classtemp, racetemp;
int Charerrors = 0;
// if this is increased you'll have to add a column to the classrace
// table below
#define _TABLE_RACES 16
static const int BaseRace[_TABLE_RACES][7] =
{ /* STR STA AGI DEX WIS INT CHR */
{ /*Human*/ 75, 75, 75, 75, 75, 75, 75},
{ /*Barbarian*/ 103, 95, 82, 70, 70, 60, 55},
{ /*Erudite*/ 60, 70, 70, 70, 83, 107, 70},
{ /*Wood Elf*/ 65, 65, 95, 80, 80, 75, 75},
{ /*High Elf*/ 55, 65, 85, 70, 95, 92, 80},
{ /*Dark Elf*/ 60, 65, 90, 75, 83, 99, 60},
{ /*Half Elf*/ 70, 70, 90, 85, 60, 75, 75},
{ /*Dwarf*/ 90, 90, 70, 90, 83, 60, 45},
{ /*Troll*/ 108, 109, 83, 75, 60, 52, 40},
{ /*Ogre*/ 130, 122, 70, 70, 67, 60, 37},
{ /*Halfling*/ 70, 75, 95, 90, 80, 67, 50},
{ /*Gnome*/ 60, 70, 85, 85, 67, 98, 60},
{ /*Iksar*/ 70, 70, 90, 85, 80, 75, 55},
{ /*Vah Shir*/ 90, 75, 90, 70, 70, 65, 65},
{ /*Froglok*/ 70, 80, 100, 100, 75, 75, 50},
{ /*Drakkin*/ 70, 80, 85, 75, 80, 85, 75}
};
static const int BaseClass[Class::PLAYER_CLASS_COUNT][8] =
{ /* STR STA AGI DEX WIS INT CHR ADD*/
{ /*Warrior*/ 10, 10, 5, 0, 0, 0, 0, 25},
{ /*Cleric*/ 5, 5, 0, 0, 10, 0, 0, 30},
{ /*Paladin*/ 10, 5, 0, 0, 5, 0, 10, 20},
{ /*Ranger*/ 5, 10, 10, 0, 5, 0, 0, 20},
{ /*ShadowKnight*/ 10, 5, 0, 0, 0, 10, 5, 20},
{ /*Druid*/ 0, 10, 0, 0, 10, 0, 0, 30},
{ /*Monk*/ 5, 5, 10, 10, 0, 0, 0, 20},
{ /*Bard*/ 5, 0, 0, 10, 0, 0, 10, 25},
{ /*Rouge*/ 0, 0, 10, 10, 0, 0, 0, 30},
{ /*Shaman*/ 0, 5, 0, 0, 10, 0, 5, 30},
{ /*Necromancer*/ 0, 0, 0, 10, 0, 10, 0, 30},
{ /*Wizard*/ 0, 10, 0, 0, 0, 10, 0, 30},
{ /*Magician*/ 0, 10, 0, 0, 0, 10, 0, 30},
{ /*Enchanter*/ 0, 0, 0, 0, 0, 10, 10, 30},
{ /*Beastlord*/ 0, 10, 5, 0, 10, 0, 5, 20},
{ /*Berserker*/ 10, 5, 0, 10, 0, 0, 0, 25}
};
static const bool ClassRaceLookupTable[Class::PLAYER_CLASS_COUNT][_TABLE_RACES]=
{ /*Human Barbarian Erudite Woodelf Highelf Darkelf Halfelf Dwarf Troll Ogre Halfling Gnome Iksar Vahshir Froglok Drakkin*/
{ /*Warrior*/ true, true, false, true, false, true, true, true, true, true, true, true, true, true, true, true},
{ /*Cleric*/ true, false, true, false, true, true, true, true, false, false, true, true, false, false, true, true},
{ /*Paladin*/ true, false, true, false, true, false, true, true, false, false, true, true, false, false, true, true},
{ /*Ranger*/ true, false, false, true, false, false, true, false, false, false, true, false, false, false, false, true},
{ /*ShadowKnight*/ true, false, true, false, false, true, false, false, true, true, false, true, true, false, true, true},
{ /*Druid*/ true, false, false, true, false, false, true, false, false, false, true, false, false, false, false, true},
{ /*Monk*/ true, false, false, false, false, false, false, false, false, false, false, false, true, false, false, true},
{ /*Bard*/ true, false, false, true, false, false, true, false, false, false, false, false, false, true, false, true},
{ /*Rogue*/ true, true, false, true, false, true, true, true, false, false, true, true, false, true, true, true},
{ /*Shaman*/ false, true, false, false, false, false, false, false, true, true, false, false, true, true, true, false},
{ /*Necromancer*/ true, false, true, false, false, true, false, false, false, false, false, true, true, false, true, true},
{ /*Wizard*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, true, true},
{ /*Magician*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, false, true},
{ /*Enchanter*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, false, true},
{ /*Beastlord*/ false, true, false, false, false, false, false, false, true, true, false, false, true, true, false, false},
{ /*Berserker*/ false, true, false, false, false, false, false, true, true, true, false, false, false, true, false, false}
};
if (!cc)
return false;
LogInfo("Validating char creation info");
classtemp = cc->class_ - 1;
racetemp = cc->race - 1;
// these have non sequential race numbers so they need to be mapped
if (cc->race == FROGLOK) racetemp = 14;
if (cc->race == VAHSHIR) racetemp = 13;
if (cc->race == IKSAR) racetemp = 12;
if (cc->race == DRAKKIN) racetemp = 15;
// if out of range looking it up in the table would crash stuff
// so we return from these
if (classtemp >= Class::PLAYER_CLASS_COUNT) {
LogInfo(" class is out of range");
return false;
}
if (racetemp >= _TABLE_RACES) {
LogInfo(" race is out of range");
return false;
}
if (!ClassRaceLookupTable[classtemp][racetemp]) { //Lookup table better than a bunch of ifs?
LogInfo(" invalid race/class combination");
// we return from this one, since if it's an invalid combination our table
// doesn't have meaningful values for the stats
return false;
}
// add up the base values for this class/race
// this is what they start with, and they have stat_points more
// that can distributed
bSTR = BaseClass[classtemp][0] + BaseRace[racetemp][0];
bSTA = BaseClass[classtemp][1] + BaseRace[racetemp][1];
bAGI = BaseClass[classtemp][2] + BaseRace[racetemp][2];
bDEX = BaseClass[classtemp][3] + BaseRace[racetemp][3];
bWIS = BaseClass[classtemp][4] + BaseRace[racetemp][4];
bINT = BaseClass[classtemp][5] + BaseRace[racetemp][5];
bCHA = BaseClass[classtemp][6] + BaseRace[racetemp][6];
stat_points = BaseClass[classtemp][7];
bTOTAL = bSTR + bSTA + bAGI + bDEX + bWIS + bINT + bCHA;
cTOTAL = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;
// the first check makes sure the total is exactly what was expected.
// this will catch all the stat cheating, but there's still the issue
// of reducing CHA or INT or something, to use for STR, so we check
// that none are lower than the base or higher than base + stat_points
// NOTE: these could just be else if, but i want to see all the stats
// that are messed up not just the first hit
if (bTOTAL + stat_points != cTOTAL) {
LogInfo(" stat points total doesn't match expected value: expecting [{}] got [{}]", bTOTAL + stat_points, cTOTAL);
Charerrors++;
}
if (cc->STR > bSTR + stat_points || cc->STR < bSTR) {
LogInfo(" stat STR is out of range");
Charerrors++;
}
if (cc->STA > bSTA + stat_points || cc->STA < bSTA) {
LogInfo(" stat STA is out of range");
Charerrors++;
}
if (cc->AGI > bAGI + stat_points || cc->AGI < bAGI) {
LogInfo(" stat AGI is out of range");
Charerrors++;
}
if (cc->DEX > bDEX + stat_points || cc->DEX < bDEX) {
LogInfo(" stat DEX is out of range");
Charerrors++;
}
if (cc->WIS > bWIS + stat_points || cc->WIS < bWIS) {
LogInfo(" stat WIS is out of range");
Charerrors++;
}
if (cc->INT > bINT + stat_points || cc->INT < bINT) {
LogInfo(" stat INT is out of range");
Charerrors++;
}
if (cc->CHA > bCHA + stat_points || cc->CHA < bCHA) {
LogInfo(" stat CHA is out of range");
Charerrors++;
}
/*TODO: Check for deity/class/race.. it'd be nice, but probably of any real use to hack(faction, deity based items are all I can think of)
I am NOT writing those tables - kathgar*/
LogInfo("Found [{}] errors in character creation request", Charerrors);
return Charerrors == 0;
}
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp) void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{ {
for (uint32 i = 0; i <= EQ::skills::HIGHEST_SKILL; ++i) { for (uint32 i = 0; i <= EQ::skills::HIGHEST_SKILL; ++i) {
-3
View File
@@ -122,7 +122,4 @@ private:
void RecordPossibleHack(const std::string& message); void RecordPossibleHack(const std::string& message);
}; };
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc);
bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc);
#endif #endif
+18
View File
@@ -0,0 +1,18 @@
#pragma once
struct CharCreatePointAllocation
{
unsigned int Index;
unsigned int BaseStats[7];
unsigned int DefaultPointAllocation[7];
unsigned int BaseResists[7];
};
struct CharCreateCombination {
unsigned int ExpansionRequired;
unsigned int Race;
unsigned int Class;
unsigned int Deity;
unsigned int AllocationIndex;
unsigned int Zone;
};
+11 -4
View File
@@ -25,14 +25,15 @@
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
#include "sof_char_create_data.h" #include "sof_char_create_data.h"
#include "race_combos.h"
#include "../common/repositories/character_instance_safereturns_repository.h" #include "../common/repositories/character_instance_safereturns_repository.h"
#include "../common/repositories/criteria/content_filter_criteria.h" #include "../common/repositories/criteria/content_filter_criteria.h"
#include "../common/zone_store.h" #include "../common/zone_store.h"
WorldDatabase database; WorldDatabase database;
WorldDatabase content_db; WorldDatabase content_db;
extern std::vector<RaceClassAllocation> character_create_allocations; extern std::vector<CharCreatePointAllocation> character_create_allocations;
extern std::vector<RaceClassCombos> character_create_race_class_combos; extern std::vector<CharCreateCombination> character_create_race_class_combos;
/** /**
@@ -807,7 +808,7 @@ bool WorldDatabase::LoadCharacterCreateAllocations()
return false; return false;
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
RaceClassAllocation allocate; CharCreatePointAllocation allocate;
allocate.Index = Strings::ToInt(row[0]); allocate.Index = Strings::ToInt(row[0]);
allocate.BaseStats[0] = Strings::ToInt(row[1]); allocate.BaseStats[0] = Strings::ToInt(row[1]);
allocate.BaseStats[3] = Strings::ToInt(row[2]); allocate.BaseStats[3] = Strings::ToInt(row[2]);
@@ -823,6 +824,12 @@ bool WorldDatabase::LoadCharacterCreateAllocations()
allocate.DefaultPointAllocation[4] = Strings::ToInt(row[12]); allocate.DefaultPointAllocation[4] = Strings::ToInt(row[12]);
allocate.DefaultPointAllocation[5] = Strings::ToInt(row[13]); allocate.DefaultPointAllocation[5] = Strings::ToInt(row[13]);
allocate.DefaultPointAllocation[6] = Strings::ToInt(row[14]); allocate.DefaultPointAllocation[6] = Strings::ToInt(row[14]);
allocate.BaseResists[0] = Strings::ToInt(row[15]);
allocate.BaseResists[1] = Strings::ToInt(row[16]);
allocate.BaseResists[2] = Strings::ToInt(row[17]);
allocate.BaseResists[3] = Strings::ToInt(row[18]);
allocate.BaseResists[4] = Strings::ToInt(row[19]);
allocate.BaseResists[5] = Strings::ToInt(row[20]);
character_create_allocations.push_back(allocate); character_create_allocations.push_back(allocate);
} }
@@ -840,7 +847,7 @@ bool WorldDatabase::LoadCharacterCreateCombos()
return false; return false;
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
RaceClassCombos combo; CharCreateCombination combo;
combo.AllocationIndex = Strings::ToInt(row[0]); combo.AllocationIndex = Strings::ToInt(row[0]);
combo.Race = Strings::ToInt(row[1]); combo.Race = Strings::ToInt(row[1]);
combo.Class = Strings::ToInt(row[2]); combo.Class = Strings::ToInt(row[2]);
+1 -1
View File
@@ -597,7 +597,7 @@ public:
inline uint8 GetBaseINT() const { return m_pp.INT; } inline uint8 GetBaseINT() const { return m_pp.INT; }
inline uint8 GetBaseAGI() const { return m_pp.AGI; } inline uint8 GetBaseAGI() const { return m_pp.AGI; }
inline uint8 GetBaseWIS() const { return m_pp.WIS; } inline uint8 GetBaseWIS() const { return m_pp.WIS; }
inline uint8 GetBaseCorrup() const { return 15; } // Same for all inline uint8 GetBaseCorrup() const { return m_pp.corruption_resist; }
inline uint8 GetBasePhR() const { return 0; } // Guessing at 0 as base inline uint8 GetBasePhR() const { return 0; } // Guessing at 0 as base
inline virtual int32 GetHeroicSTR() const { return itembonuses.HeroicSTR; } inline virtual int32 GetHeroicSTR() const { return itembonuses.HeroicSTR; }
+5 -295
View File
@@ -1009,65 +1009,7 @@ int Client::CalcHaste()
//in Mob::ResistSpell //in Mob::ResistSpell
int32 Client::CalcMR() int32 Client::CalcMR()
{ {
//racial bases MR = m_pp.magic_resist;
switch (GetBaseRace()) {
case HUMAN:
MR = 25;
break;
case BARBARIAN:
MR = 25;
break;
case ERUDITE:
MR = 30;
break;
case WOOD_ELF:
MR = 25;
break;
case HIGH_ELF:
MR = 25;
break;
case DARK_ELF:
MR = 25;
break;
case HALF_ELF:
MR = 25;
break;
case DWARF:
MR = 30;
break;
case TROLL:
MR = 25;
break;
case OGRE:
MR = 25;
break;
case HALFLING:
MR = 25;
break;
case GNOME:
MR = 25;
break;
case IKSAR:
MR = 25;
break;
case VAHSHIR:
MR = 25;
break;
case FROGLOK:
MR = 30;
break;
case DRAKKIN:
{
MR = 25;
if (GetDrakkinHeritage() == 2)
MR += 10;
else if (GetDrakkinHeritage() == 5)
MR += 2;
break;
}
default:
MR = 20;
}
MR += itembonuses.MR + spellbonuses.MR + aabonuses.MR; MR += itembonuses.MR + spellbonuses.MR + aabonuses.MR;
if (GetClass() == Class::Warrior || GetClass() == Class::Berserker) { if (GetClass() == Class::Warrior || GetClass() == Class::Berserker) {
MR += GetLevel() / 2; MR += GetLevel() / 2;
@@ -1083,65 +1025,7 @@ int32 Client::CalcMR()
int32 Client::CalcFR() int32 Client::CalcFR()
{ {
//racial bases FR = m_pp.fire_resist;
switch (GetBaseRace()) {
case HUMAN:
FR = 25;
break;
case BARBARIAN:
FR = 25;
break;
case ERUDITE:
FR = 25;
break;
case WOOD_ELF:
FR = 25;
break;
case HIGH_ELF:
FR = 25;
break;
case DARK_ELF:
FR = 25;
break;
case HALF_ELF:
FR = 25;
break;
case DWARF:
FR = 25;
break;
case TROLL:
FR = 5;
break;
case OGRE:
FR = 25;
break;
case HALFLING:
FR = 25;
break;
case GNOME:
FR = 25;
break;
case IKSAR:
FR = 30;
break;
case VAHSHIR:
FR = 25;
break;
case FROGLOK:
FR = 25;
break;
case DRAKKIN:
{
FR = 25;
if (GetDrakkinHeritage() == 0)
FR += 10;
else if (GetDrakkinHeritage() == 5)
FR += 2;
break;
}
default:
FR = 20;
}
int c = GetClass(); int c = GetClass();
if (c == Class::Ranger) { if (c == Class::Ranger) {
FR += 4; FR += 4;
@@ -1169,65 +1053,7 @@ int32 Client::CalcFR()
int32 Client::CalcDR() int32 Client::CalcDR()
{ {
//racial bases DR = m_pp.disease_resist;
switch (GetBaseRace()) {
case HUMAN:
DR = 15;
break;
case BARBARIAN:
DR = 15;
break;
case ERUDITE:
DR = 10;
break;
case WOOD_ELF:
DR = 15;
break;
case HIGH_ELF:
DR = 15;
break;
case DARK_ELF:
DR = 15;
break;
case HALF_ELF:
DR = 15;
break;
case DWARF:
DR = 15;
break;
case TROLL:
DR = 15;
break;
case OGRE:
DR = 15;
break;
case HALFLING:
DR = 20;
break;
case GNOME:
DR = 15;
break;
case IKSAR:
DR = 15;
break;
case VAHSHIR:
DR = 15;
break;
case FROGLOK:
DR = 15;
break;
case DRAKKIN:
{
DR = 15;
if (GetDrakkinHeritage() == 1)
DR += 10;
else if (GetDrakkinHeritage() == 5)
DR += 2;
break;
}
default:
DR = 15;
}
int c = GetClass(); int c = GetClass();
// the monk one is part of base resist // the monk one is part of base resist
if (c == Class::Monk) { if (c == Class::Monk) {
@@ -1261,65 +1087,7 @@ int32 Client::CalcDR()
int32 Client::CalcPR() int32 Client::CalcPR()
{ {
//racial bases PR = m_pp.poison_resist;
switch (GetBaseRace()) {
case HUMAN:
PR = 15;
break;
case BARBARIAN:
PR = 15;
break;
case ERUDITE:
PR = 15;
break;
case WOOD_ELF:
PR = 15;
break;
case HIGH_ELF:
PR = 15;
break;
case DARK_ELF:
PR = 15;
break;
case HALF_ELF:
PR = 15;
break;
case DWARF:
PR = 20;
break;
case TROLL:
PR = 15;
break;
case OGRE:
PR = 15;
break;
case HALFLING:
PR = 20;
break;
case GNOME:
PR = 15;
break;
case IKSAR:
PR = 15;
break;
case VAHSHIR:
PR = 15;
break;
case FROGLOK:
PR = 30;
break;
case DRAKKIN:
{
PR = 15;
if (GetDrakkinHeritage() == 3)
PR += 10;
else if (GetDrakkinHeritage() == 5)
PR += 2;
break;
}
default:
PR = 15;
}
int c = GetClass(); int c = GetClass();
// this monk bonus is part of the base // this monk bonus is part of the base
if (c == Class::Monk) { if (c == Class::Monk) {
@@ -1353,65 +1121,7 @@ int32 Client::CalcPR()
int32 Client::CalcCR() int32 Client::CalcCR()
{ {
//racial bases CR = m_pp.cold_resist;
switch (GetBaseRace()) {
case HUMAN:
CR = 25;
break;
case BARBARIAN:
CR = 35;
break;
case ERUDITE:
CR = 25;
break;
case WOOD_ELF:
CR = 25;
break;
case HIGH_ELF:
CR = 25;
break;
case DARK_ELF:
CR = 25;
break;
case HALF_ELF:
CR = 25;
break;
case DWARF:
CR = 25;
break;
case TROLL:
CR = 25;
break;
case OGRE:
CR = 25;
break;
case HALFLING:
CR = 25;
break;
case GNOME:
CR = 25;
break;
case IKSAR:
CR = 15;
break;
case VAHSHIR:
CR = 25;
break;
case FROGLOK:
CR = 25;
break;
case DRAKKIN:
{
CR = 25;
if (GetDrakkinHeritage() == 4)
CR += 10;
else if (GetDrakkinHeritage() == 5)
CR += 2;
break;
}
default:
CR = 25;
}
int c = GetClass(); int c = GetClass();
if (c == Class::Ranger || c == Class::Beastlord) { if (c == Class::Ranger || c == Class::Beastlord) {
CR += 4; CR += 4;
+12
View File
@@ -561,6 +561,12 @@ bool ZoneDatabase::LoadCharacterData(uint32 character_id, PlayerProfile_Struct*
m_epp->expended_aa = e.e_expended_aa_spent; m_epp->expended_aa = e.e_expended_aa_spent;
m_epp->last_invsnapshot_time = e.e_last_invsnapshot; m_epp->last_invsnapshot_time = e.e_last_invsnapshot;
m_epp->next_invsnapshot_time = m_epp->last_invsnapshot_time + (RuleI(Character, InvSnapshotMinIntervalM) * 60); m_epp->next_invsnapshot_time = m_epp->last_invsnapshot_time + (RuleI(Character, InvSnapshotMinIntervalM) * 60);
pp->cold_resist = e.cold_resist;
pp->fire_resist = e.fire_resist;
pp->magic_resist = e.magic_resist;
pp->disease_resist = e.disease_resist;
pp->poison_resist = e.poison_resist;
pp->corruption_resist = e.corruption_resist;
return true; return true;
} }
@@ -1158,6 +1164,12 @@ bool ZoneDatabase::SaveCharacterData(
e.e_expended_aa_spent = m_epp->expended_aa; e.e_expended_aa_spent = m_epp->expended_aa;
e.e_last_invsnapshot = m_epp->last_invsnapshot_time; e.e_last_invsnapshot = m_epp->last_invsnapshot_time;
e.mailkey = c->GetMailKeyFull(); e.mailkey = c->GetMailKeyFull();
e.cold_resist = pp->cold_resist;
e.fire_resist = pp->fire_resist;
e.magic_resist = pp->magic_resist;
e.disease_resist = pp->disease_resist;
e.poison_resist = pp->poison_resist;
e.corruption_resist = pp->corruption_resist;
const int replaced = CharacterDataRepository::ReplaceOne(database, e); const int replaced = CharacterDataRepository::ReplaceOne(database, e);