Implement NPC Charm Stats

These combat stats an NPC will change to while charmed
This commit is contained in:
Michael Cook (mackal) 2018-02-04 16:30:16 -05:00
parent c5c93bb2e6
commit f720e51585
8 changed files with 112 additions and 2 deletions

View File

@ -30,7 +30,7 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/ */
#define CURRENT_BINARY_DATABASE_VERSION 9117 #define CURRENT_BINARY_DATABASE_VERSION 9118
#ifdef BOTS #ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018
#else #else

View File

@ -371,6 +371,7 @@
9115|2017_10_28_traps.sql|SHOW COLUMNS FROM `traps` LIKE 'triggered_number'|empty| 9115|2017_10_28_traps.sql|SHOW COLUMNS FROM `traps` LIKE 'triggered_number'|empty|
9116|2017_12_16_GroundSpawn_Respawn_Timer.sql|SHOW COLUMNS FROM `ground_spawns` WHERE Field = 'respawn_timer' AND Type = 'int(11) unsigned'|empty| 9116|2017_12_16_GroundSpawn_Respawn_Timer.sql|SHOW COLUMNS FROM `ground_spawns` WHERE Field = 'respawn_timer' AND Type = 'int(11) unsigned'|empty|
9117|2018_02_01_NPC_Spells_Min_Max_HP.sql|SHOW COLUMNS FROM `npc_spells_entries` LIKE 'min_hp'|empty| 9117|2018_02_01_NPC_Spells_Min_Max_HP.sql|SHOW COLUMNS FROM `npc_spells_entries` LIKE 'min_hp'|empty|
9118|2018_02_04_Charm_Stats.sql|SHOW COLUMNS FROM `npc_types` LIKE 'charm_ac'|empty|
# Upgrade conditions: # Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not # This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,7 @@
ALTER TABLE `npc_types` ADD `charm_ac` SMALLINT(5) DEFAULT '0';
ALTER TABLE `npc_types` ADD `charm_min_dmg` INT(10) DEFAULT '0';
ALTER TABLE `npc_types` ADD `charm_max_dmg` INT(10) DEFAULT '0';
ALTER TABLE `npc_types` ADD `charm_attack_delay` TINYINT(3) DEFAULT '0';
ALTER TABLE `npc_types` ADD `charm_accuracy_rating` MEDIUMINT(9) DEFAULT '0';
ALTER TABLE `npc_types` ADD `charm_avoidance_rating` MEDIUMINT(9) DEFAULT '0';
ALTER TABLE `npc_types` ADD `charm_atk` MEDIUMINT(9) DEFAULT '0';

View File

@ -208,6 +208,24 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
avoidance_rating = d->avoidance_rating; avoidance_rating = d->avoidance_rating;
ATK = d->ATK; ATK = d->ATK;
// used for when switch back to charm
default_ac = d->AC;
default_min_dmg = min_dmg;
default_max_dmg = max_dmg;
default_attack_delay = d->attack_delay;
default_accuracy_rating = d->accuracy_rating;
default_avoidance_rating = d->avoidance_rating;
default_atk = d->ATK;
// used for when getting charmed, if 0, doesn't swap
charm_ac = d->charm_ac;
charm_min_dmg = d->charm_min_dmg;
charm_max_dmg = d->charm_max_dmg;
charm_attack_delay = d->charm_attack_delay;
charm_accuracy_rating = d->charm_accuracy_rating;
charm_avoidance_rating = d->charm_avoidance_rating;
charm_atk = d->charm_atk;
CalcMaxMana(); CalcMaxMana();
SetMana(GetMaxMana()); SetMana(GetMaxMana());
@ -2636,3 +2654,42 @@ void NPC::DepopSwarmPets()
} }
} }
} }
void NPC::ModifyStatsOnCharm(bool bRemoved)
{
if (bRemoved) {
if (charm_ac)
AC = default_ac;
if (charm_attack_delay)
attack_delay = default_attack_delay;
if (charm_accuracy_rating)
accuracy_rating = default_accuracy_rating;
if (charm_avoidance_rating)
avoidance_rating = default_avoidance_rating;
if (charm_atk)
ATK = default_atk;
if (charm_min_dmg || charm_max_dmg) {
base_damage = round((default_max_dmg - default_min_dmg) / 1.9);
min_damage = default_min_dmg - round(base_damage / 10.0);
}
} else {
if (charm_ac)
AC = charm_ac;
if (charm_attack_delay)
attack_delay = charm_attack_delay;
if (charm_accuracy_rating)
accuracy_rating = charm_accuracy_rating;
if (charm_avoidance_rating)
avoidance_rating = charm_avoidance_rating;
if (charm_atk)
ATK = charm_atk;
if (charm_min_dmg || charm_max_dmg) {
base_damage = round((charm_max_dmg - charm_min_dmg) / 1.9);
min_damage = charm_min_dmg - round(base_damage / 10.0);
}
}
// the rest of the stats aren't cached, so lets just do these two instead of full CalcBonuses()
SetAttackTimer();
CalcAC();
}

View File

@ -282,6 +282,8 @@ public:
int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; } int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
inline const char* GetAmmoIDfile() const { return ammo_idfile; } inline const char* GetAmmoIDfile() const { return ammo_idfile; }
void ModifyStatsOnCharm(bool bRemoved);
//waypoint crap //waypoint crap
int GetMaxWp() const { return max_wp; } int GetMaxWp() const { return max_wp; }
void DisplayWaypointInfo(Client *to); void DisplayWaypointInfo(Client *to);
@ -482,6 +484,25 @@ protected:
int32 SpellFocusDMG; int32 SpellFocusDMG;
int32 SpellFocusHeal; int32 SpellFocusHeal;
// stats to switch back to after charm wears off
// could probably pick a better name, but these probably aren't taken so ...
int default_ac;
int default_min_dmg;
int default_max_dmg;
int default_attack_delay;
int default_accuracy_rating;
int default_avoidance_rating;
int default_atk;
// when charmed, switch to these
int charm_ac;
int charm_min_dmg;
int charm_max_dmg;
int charm_attack_delay;
int charm_accuracy_rating;
int charm_avoidance_rating;
int charm_atk;
//pet crap: //pet crap:
uint16 pet_spell_id; uint16 pet_spell_id;
bool taunting; bool taunting;

View File

@ -790,6 +790,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
CastToClient()->AI_Start(); CastToClient()->AI_Start();
} else if(IsNPC()) { } else if(IsNPC()) {
CastToNPC()->SetPetSpellID(0); //not a pet spell. CastToNPC()->SetPetSpellID(0); //not a pet spell.
CastToNPC()->ModifyStatsOnCharm(false);
} }
bool bBreak = false; bool bBreak = false;
@ -3966,6 +3967,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
if(IsNPC()) if(IsNPC())
{ {
CastToNPC()->RestoreGuardSpotCharm(); CastToNPC()->RestoreGuardSpotCharm();
CastToNPC()->ModifyStatsOnCharm(true);
} }
SendAppearancePacket(AT_Pet, 0, true, true); SendAppearancePacket(AT_Pet, 0, true, true);

View File

@ -1962,7 +1962,14 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
"npc_types.feettexture, " "npc_types.feettexture, "
"npc_types.ignore_despawn, " "npc_types.ignore_despawn, "
"npc_types.show_name, " "npc_types.show_name, "
"npc_types.untargetable " "npc_types.untargetable, "
"npc_types.charm_ac, "
"npc_types.charm_min_dmg, "
"npc_types.charm_max_dmg, "
"npc_types.charm_attack_delay, "
"npc_types.charm_accuracy_rating, "
"npc_types.charm_avoidance_rating, "
"npc_types.charm_atk "
"FROM npc_types %s", "FROM npc_types %s",
where_condition.c_str() where_condition.c_str()
); );
@ -2141,6 +2148,14 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
temp_npctype_data->show_name = atoi(row[98]) != 0 ? true : false; temp_npctype_data->show_name = atoi(row[98]) != 0 ? true : false;
temp_npctype_data->untargetable = atoi(row[99]) != 0 ? true : false; temp_npctype_data->untargetable = atoi(row[99]) != 0 ? true : false;
temp_npctype_data->charm_ac = atoi(row[100]);
temp_npctype_data->charm_min_dmg = atoi(row[101]);
temp_npctype_data->charm_max_dmg = atoi(row[102]);
temp_npctype_data->charm_attack_delay = atoi(row[103]) * 100; // TODO: fix DB
temp_npctype_data->charm_accuracy_rating = atoi(row[104]);
temp_npctype_data->charm_avoidance_rating = atoi(row[105]);
temp_npctype_data->charm_atk = atoi(row[106]);
// If NPC with duplicate NPC id already in table, // If NPC with duplicate NPC id already in table,
// free item we attempted to add. // free item we attempted to add.
if (zone->npctable.find(temp_npctype_data->npc_id) != zone->npctable.end()) { if (zone->npctable.find(temp_npctype_data->npc_id) != zone->npctable.end()) {

View File

@ -89,6 +89,13 @@ struct NPCType
EQEmu::TintProfile armor_tint; EQEmu::TintProfile armor_tint;
uint32 min_dmg; uint32 min_dmg;
uint32 max_dmg; uint32 max_dmg;
uint32 charm_ac;
uint32 charm_min_dmg;
uint32 charm_max_dmg;
int charm_attack_delay;
int charm_accuracy_rating;
int charm_avoidance_rating;
int charm_atk;
int16 attack_count; int16 attack_count;
char special_abilities[512]; char special_abilities[512];
uint16 d_melee_texture1; uint16 d_melee_texture1;