mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 13:41:31 +00:00
Implement NPC Charm Stats
These combat stats an NPC will change to while charmed
This commit is contained in:
parent
c5c93bb2e6
commit
f720e51585
@ -30,7 +30,7 @@
|
||||
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
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018
|
||||
#else
|
||||
|
||||
@ -371,6 +371,7 @@
|
||||
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|
|
||||
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:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
7
utils/sql/git/required/2018_02_04_Charm_Stats.sql
Normal file
7
utils/sql/git/required/2018_02_04_Charm_Stats.sql
Normal 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';
|
||||
57
zone/npc.cpp
57
zone/npc.cpp
@ -208,6 +208,24 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
avoidance_rating = d->avoidance_rating;
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
21
zone/npc.h
21
zone/npc.h
@ -282,6 +282,8 @@ public:
|
||||
int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
|
||||
inline const char* GetAmmoIDfile() const { return ammo_idfile; }
|
||||
|
||||
void ModifyStatsOnCharm(bool bRemoved);
|
||||
|
||||
//waypoint crap
|
||||
int GetMaxWp() const { return max_wp; }
|
||||
void DisplayWaypointInfo(Client *to);
|
||||
@ -482,6 +484,25 @@ protected:
|
||||
int32 SpellFocusDMG;
|
||||
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:
|
||||
uint16 pet_spell_id;
|
||||
bool taunting;
|
||||
|
||||
@ -790,6 +790,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
CastToClient()->AI_Start();
|
||||
} else if(IsNPC()) {
|
||||
CastToNPC()->SetPetSpellID(0); //not a pet spell.
|
||||
CastToNPC()->ModifyStatsOnCharm(false);
|
||||
}
|
||||
|
||||
bool bBreak = false;
|
||||
@ -3966,6 +3967,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
if(IsNPC())
|
||||
{
|
||||
CastToNPC()->RestoreGuardSpotCharm();
|
||||
CastToNPC()->ModifyStatsOnCharm(true);
|
||||
}
|
||||
|
||||
SendAppearancePacket(AT_Pet, 0, true, true);
|
||||
|
||||
@ -1962,7 +1962,14 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
"npc_types.feettexture, "
|
||||
"npc_types.ignore_despawn, "
|
||||
"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",
|
||||
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->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,
|
||||
// free item we attempted to add.
|
||||
if (zone->npctable.find(temp_npctype_data->npc_id) != zone->npctable.end()) {
|
||||
|
||||
@ -89,6 +89,13 @@ struct NPCType
|
||||
EQEmu::TintProfile armor_tint;
|
||||
uint32 min_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;
|
||||
char special_abilities[512];
|
||||
uint16 d_melee_texture1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user