mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-06 10:22:26 +00:00
[Regen] Implement Per Second HP Regen for NPCs (#2086)
* Implement NPC per second regen * Add hp_regen_per_second to ModifyNPCStat * Take per second regen the rest of the way * Add #npcedit hp_regen_per_second * Add db migration
This commit is contained in:
parent
5b4aeaa457
commit
90da136b7a
@ -34,7 +34,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 9178
|
#define CURRENT_BINARY_DATABASE_VERSION 9179
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028
|
||||||
|
|||||||
@ -432,6 +432,7 @@
|
|||||||
9176|2022_01_10_checksum_verification.sql|SHOW COLUMNS FROM `account` LIKE 'crc_eqgame'|empty|
|
9176|2022_01_10_checksum_verification.sql|SHOW COLUMNS FROM `account` LIKE 'crc_eqgame'|empty|
|
||||||
9177|2022_03_06_table_structure_changes.sql|SHOW COLUMNS FROM `pets` LIKE 'id'|empty|
|
9177|2022_03_06_table_structure_changes.sql|SHOW COLUMNS FROM `pets` LIKE 'id'|empty|
|
||||||
9178|2022_03_07_saylink_collation.sql|SELECT * FROM db_version WHERE version >= 9178|empty|
|
9178|2022_03_07_saylink_collation.sql|SELECT * FROM db_version WHERE version >= 9178|empty|
|
||||||
|
9179|2022_04_30_hp_regen_per_second.sql|SHOW COLUMNS FROM `npc_types` LIKE 'hp_regen_per_second'|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
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE npc_types ADD COLUMN hp_regen_per_second bigint(11) DEFAULT 0 AFTER hp_regen_rate;
|
||||||
@ -28,6 +28,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
c->Message(Chat::White, "#npcedit herosforgemodel - Sets an NPC's Hero's Forge Model");
|
c->Message(Chat::White, "#npcedit herosforgemodel - Sets an NPC's Hero's Forge Model");
|
||||||
c->Message(Chat::White, "#npcedit size - Sets an NPC's Size");
|
c->Message(Chat::White, "#npcedit size - Sets an NPC's Size");
|
||||||
c->Message(Chat::White, "#npcedit hpregen - Sets an NPC's Hitpoints Regeneration Rate Per Tick");
|
c->Message(Chat::White, "#npcedit hpregen - Sets an NPC's Hitpoints Regeneration Rate Per Tick");
|
||||||
|
c->Message(Chat::White, "#npcedit hp_regen_per_second - Sets an NPC's HP regeneration per second");
|
||||||
c->Message(Chat::White, "#npcedit manaregen - Sets an NPC's Mana Regeneration Rate Per Tick");
|
c->Message(Chat::White, "#npcedit manaregen - Sets an NPC's Mana Regeneration Rate Per Tick");
|
||||||
c->Message(Chat::White, "#npcedit loottable - Sets an NPC's Loottable ID");
|
c->Message(Chat::White, "#npcedit loottable - Sets an NPC's Loottable ID");
|
||||||
c->Message(Chat::White, "#npcedit merchantid - Sets an NPC's Merchant ID");
|
c->Message(Chat::White, "#npcedit merchantid - Sets an NPC's Merchant ID");
|
||||||
@ -308,6 +309,23 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(sep->arg[1], "hp_regen_per_second") == 0) {
|
||||||
|
c->Message(
|
||||||
|
Chat::Yellow,
|
||||||
|
fmt::format(
|
||||||
|
"NPC ID {} now regenerates {} HP per second.",
|
||||||
|
npc_id,
|
||||||
|
atoi(sep->arg[2])).c_str()
|
||||||
|
);
|
||||||
|
std::string query = fmt::format(
|
||||||
|
"UPDATE npc_types SET hp_regen_per_second = {} WHERE id = {}",
|
||||||
|
atoi(sep->arg[2]),
|
||||||
|
npc_id
|
||||||
|
);
|
||||||
|
content_db.QueryDatabase(query);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcasecmp(sep->arg[1], "manaregen") == 0) {
|
if (strcasecmp(sep->arg[1], "manaregen") == 0) {
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::Yellow,
|
Chat::Yellow,
|
||||||
|
|||||||
@ -4880,6 +4880,7 @@ void Merc::UpdateMercStats(Client *c, bool setmax)
|
|||||||
max_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet
|
max_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet
|
||||||
base_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet
|
base_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet
|
||||||
hp_regen = npc_type->hp_regen;
|
hp_regen = npc_type->hp_regen;
|
||||||
|
hp_regen_per_second = npc_type->hp_regen_per_second;
|
||||||
mana_regen = npc_type->mana_regen;
|
mana_regen = npc_type->mana_regen;
|
||||||
max_dmg = npc_type->max_dmg;
|
max_dmg = npc_type->max_dmg;
|
||||||
min_dmg = npc_type->min_dmg;
|
min_dmg = npc_type->min_dmg;
|
||||||
|
|||||||
67
zone/mob.cpp
67
zone/mob.cpp
@ -96,11 +96,13 @@ Mob::Mob(
|
|||||||
uint8 in_legtexture,
|
uint8 in_legtexture,
|
||||||
uint8 in_feettexture,
|
uint8 in_feettexture,
|
||||||
uint16 in_usemodel,
|
uint16 in_usemodel,
|
||||||
bool in_always_aggro
|
bool in_always_aggro,
|
||||||
|
int64 in_hp_regen_per_second
|
||||||
) :
|
) :
|
||||||
attack_timer(2000),
|
attack_timer(2000),
|
||||||
attack_dw_timer(2000),
|
attack_dw_timer(2000),
|
||||||
ranged_timer(2000),
|
ranged_timer(2000),
|
||||||
|
hp_regen_per_second_timer(1000),
|
||||||
tic_timer(6000),
|
tic_timer(6000),
|
||||||
mana_timer(2000),
|
mana_timer(2000),
|
||||||
spellend_timer(0),
|
spellend_timer(0),
|
||||||
@ -249,37 +251,38 @@ Mob::Mob(
|
|||||||
aa_title = 0xFF;
|
aa_title = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
AC = in_ac;
|
AC = in_ac;
|
||||||
ATK = in_atk;
|
ATK = in_atk;
|
||||||
STR = in_str;
|
STR = in_str;
|
||||||
STA = in_sta;
|
STA = in_sta;
|
||||||
DEX = in_dex;
|
DEX = in_dex;
|
||||||
AGI = in_agi;
|
AGI = in_agi;
|
||||||
INT = in_int;
|
INT = in_int;
|
||||||
WIS = in_wis;
|
WIS = in_wis;
|
||||||
CHA = in_cha;
|
CHA = in_cha;
|
||||||
MR = CR = FR = DR = PR = Corrup = PhR = 0;
|
MR = CR = FR = DR = PR = Corrup = PhR = 0;
|
||||||
ExtraHaste = 0;
|
ExtraHaste = 0;
|
||||||
bEnraged = false;
|
bEnraged = false;
|
||||||
current_mana = 0;
|
current_mana = 0;
|
||||||
max_mana = 0;
|
max_mana = 0;
|
||||||
hp_regen = in_hp_regen;
|
hp_regen = in_hp_regen;
|
||||||
mana_regen = in_mana_regen;
|
hp_regen_per_second = in_hp_regen_per_second;
|
||||||
ooc_regen = RuleI(NPC, OOCRegen); //default Out of Combat Regen
|
mana_regen = in_mana_regen;
|
||||||
maxlevel = in_maxlevel;
|
ooc_regen = RuleI(NPC, OOCRegen); //default Out of Combat Regen
|
||||||
scalerate = in_scalerate;
|
maxlevel = in_maxlevel;
|
||||||
invisible = 0;
|
scalerate = in_scalerate;
|
||||||
invisible_undead = 0;
|
invisible = 0;
|
||||||
invisible_animals = 0;
|
invisible_undead = 0;
|
||||||
sneaking = false;
|
invisible_animals = 0;
|
||||||
hidden = false;
|
sneaking = false;
|
||||||
improved_hidden = false;
|
hidden = false;
|
||||||
invulnerable = false;
|
improved_hidden = false;
|
||||||
IsFullHP = (current_hp == max_hp);
|
invulnerable = false;
|
||||||
qglobal = 0;
|
IsFullHP = (current_hp == max_hp);
|
||||||
spawned = false;
|
qglobal = 0;
|
||||||
rare_spawn = false;
|
spawned = false;
|
||||||
always_aggro = in_always_aggro;
|
rare_spawn = false;
|
||||||
|
always_aggro = in_always_aggro;
|
||||||
|
|
||||||
InitializeBuffSlots();
|
InitializeBuffSlots();
|
||||||
|
|
||||||
|
|||||||
23
zone/mob.h
23
zone/mob.h
@ -162,7 +162,8 @@ public:
|
|||||||
uint8 in_legtexture,
|
uint8 in_legtexture,
|
||||||
uint8 in_feettexture,
|
uint8 in_feettexture,
|
||||||
uint16 in_usemodel,
|
uint16 in_usemodel,
|
||||||
bool in_always_aggros_foes
|
bool in_always_aggros_foes,
|
||||||
|
int64 in_hp_regen_per_second = 0
|
||||||
);
|
);
|
||||||
virtual ~Mob();
|
virtual ~Mob();
|
||||||
|
|
||||||
@ -245,11 +246,11 @@ public:
|
|||||||
//Invisible
|
//Invisible
|
||||||
bool IsInvisible(Mob* other = 0) const;
|
bool IsInvisible(Mob* other = 0) const;
|
||||||
void SetInvisible(uint8 state, bool set_on_bonus_calc = false);
|
void SetInvisible(uint8 state, bool set_on_bonus_calc = false);
|
||||||
|
|
||||||
void CalcSeeInvisibleLevel();
|
void CalcSeeInvisibleLevel();
|
||||||
void CalcInvisibleLevel();
|
void CalcInvisibleLevel();
|
||||||
void ZeroInvisibleVars(uint8 invisible_type);
|
void ZeroInvisibleVars(uint8 invisible_type);
|
||||||
|
|
||||||
inline uint8 GetSeeInvisibleLevelFromNPCStat(uint16 in_see_invis);
|
inline uint8 GetSeeInvisibleLevelFromNPCStat(uint16 in_see_invis);
|
||||||
|
|
||||||
void BreakInvisibleSpells();
|
void BreakInvisibleSpells();
|
||||||
@ -269,7 +270,7 @@ public:
|
|||||||
inline void SetSeeInvisibleUndead(uint8 val) { see_invis_undead = val; }
|
inline void SetSeeInvisibleUndead(uint8 val) { see_invis_undead = val; }
|
||||||
|
|
||||||
uint32 tmHidden; // timestamp of hide, only valid while hidden == true
|
uint32 tmHidden; // timestamp of hide, only valid while hidden == true
|
||||||
uint8 invisible, nobuff_invisible, invisible_undead, invisible_animals;
|
uint8 invisible, nobuff_invisible, invisible_undead, invisible_animals;
|
||||||
uint8 see_invis, innate_see_invis, see_invis_undead; //TODO: do we need a see_invis_animal ?
|
uint8 see_invis, innate_see_invis, see_invis_undead; //TODO: do we need a see_invis_animal ?
|
||||||
|
|
||||||
bool sneaking, hidden, improved_hidden;
|
bool sneaking, hidden, improved_hidden;
|
||||||
@ -298,7 +299,7 @@ public:
|
|||||||
void ChangeSize(float in_size, bool bNoRestriction = false);
|
void ChangeSize(float in_size, bool bNoRestriction = false);
|
||||||
void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone);
|
void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone);
|
||||||
void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0, float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, EQ::skills::SkillType skillInUse = EQ::skills::SkillArchery);
|
void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0, float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, EQ::skills::SkillType skillInUse = EQ::skills::SkillArchery);
|
||||||
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target=nullptr, uint32 value1slot = 1, uint32 value1ground = 1, uint32 value2slot = 1, uint32 value2ground = 1,
|
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target=nullptr, uint32 value1slot = 1, uint32 value1ground = 1, uint32 value2slot = 1, uint32 value2ground = 1,
|
||||||
uint32 value3slot = 1, uint32 value3ground = 1, uint32 value4slot = 1, uint32 value4ground = 1, uint32 value5slot = 1, uint32 value5ground = 1);
|
uint32 value3slot = 1, uint32 value3ground = 1, uint32 value4slot = 1, uint32 value4ground = 1, uint32 value5slot = 1, uint32 value5ground = 1);
|
||||||
void SendLevelAppearance();
|
void SendLevelAppearance();
|
||||||
void SendStunAppearance();
|
void SendStunAppearance();
|
||||||
@ -380,13 +381,13 @@ public:
|
|||||||
int16 GetItemSlotToConsumeCharge(int32 spell_id, uint32 inventory_slot);
|
int16 GetItemSlotToConsumeCharge(int32 spell_id, uint32 inventory_slot);
|
||||||
bool CheckItemRaceClassDietyRestrictionsOnCast(uint32 inventory_slot);
|
bool CheckItemRaceClassDietyRestrictionsOnCast(uint32 inventory_slot);
|
||||||
bool IsFromTriggeredSpell(EQ::spells::CastingSlot slot, uint32 item_slot = 0xFFFFFFFF);
|
bool IsFromTriggeredSpell(EQ::spells::CastingSlot slot, uint32 item_slot = 0xFFFFFFFF);
|
||||||
|
|
||||||
//Bard
|
//Bard
|
||||||
bool ApplyBardPulse(int32 spell_id, Mob *spell_target, EQ::spells::CastingSlot slot);
|
bool ApplyBardPulse(int32 spell_id, Mob *spell_target, EQ::spells::CastingSlot slot);
|
||||||
bool IsActiveBardSong(int32 spell_id);
|
bool IsActiveBardSong(int32 spell_id);
|
||||||
bool HasActiveSong() const { return(bardsong != 0); }
|
bool HasActiveSong() const { return(bardsong != 0); }
|
||||||
void ZeroBardPulseVars();
|
void ZeroBardPulseVars();
|
||||||
void DoBardCastingFromItemClick(bool is_casting_bard_song, uint32 cast_time, int32 spell_id, uint16 target_id, EQ::spells::CastingSlot slot, uint32 item_slot,
|
void DoBardCastingFromItemClick(bool is_casting_bard_song, uint32 cast_time, int32 spell_id, uint16 target_id, EQ::spells::CastingSlot slot, uint32 item_slot,
|
||||||
uint32 recast_type , uint32 recast_delay);
|
uint32 recast_type , uint32 recast_delay);
|
||||||
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
|
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
|
||||||
|
|
||||||
@ -1424,6 +1425,7 @@ protected:
|
|||||||
int32 current_mana;
|
int32 current_mana;
|
||||||
int32 max_mana;
|
int32 max_mana;
|
||||||
int32 hp_regen;
|
int32 hp_regen;
|
||||||
|
int64 hp_regen_per_second;
|
||||||
int32 mana_regen;
|
int32 mana_regen;
|
||||||
int32 ooc_regen;
|
int32 ooc_regen;
|
||||||
uint8 maxlevel;
|
uint8 maxlevel;
|
||||||
@ -1542,6 +1544,7 @@ protected:
|
|||||||
int attack_delay; //delay between attacks in 10ths of seconds
|
int attack_delay; //delay between attacks in 10ths of seconds
|
||||||
bool always_aggro;
|
bool always_aggro;
|
||||||
int16 slow_mitigation; // Allows for a slow mitigation (100 = 100%, 50% = 50%)
|
int16 slow_mitigation; // Allows for a slow mitigation (100 = 100%, 50% = 50%)
|
||||||
|
Timer hp_regen_per_second_timer;
|
||||||
Timer tic_timer;
|
Timer tic_timer;
|
||||||
Timer mana_timer;
|
Timer mana_timer;
|
||||||
int32 dw_same_delay;
|
int32 dw_same_delay;
|
||||||
@ -1558,7 +1561,7 @@ protected:
|
|||||||
|
|
||||||
int32 appearance_effects_id[MAX_APPEARANCE_EFFECTS];
|
int32 appearance_effects_id[MAX_APPEARANCE_EFFECTS];
|
||||||
int32 appearance_effects_slot[MAX_APPEARANCE_EFFECTS];
|
int32 appearance_effects_slot[MAX_APPEARANCE_EFFECTS];
|
||||||
|
|
||||||
int queue_wearchange_slot;
|
int queue_wearchange_slot;
|
||||||
|
|
||||||
Timer shield_timer;
|
Timer shield_timer;
|
||||||
@ -1766,7 +1769,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Mob* target;
|
Mob* target;
|
||||||
|
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
std::shared_ptr<HealRotation> m_target_of_heal_rotation;
|
std::shared_ptr<HealRotation> m_target_of_heal_rotation;
|
||||||
|
|||||||
16
zone/npc.cpp
16
zone/npc.cpp
@ -114,7 +114,8 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
npc_type_data->legtexture,
|
npc_type_data->legtexture,
|
||||||
npc_type_data->feettexture,
|
npc_type_data->feettexture,
|
||||||
npc_type_data->use_model,
|
npc_type_data->use_model,
|
||||||
npc_type_data->always_aggro
|
npc_type_data->always_aggro,
|
||||||
|
npc_type_data->hp_regen_per_second
|
||||||
),
|
),
|
||||||
attacked_timer(CombatEventTimer_expire),
|
attacked_timer(CombatEventTimer_expire),
|
||||||
swarm_timer(100),
|
swarm_timer(100),
|
||||||
@ -870,6 +871,12 @@ bool NPC::Process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hp_regen_per_second > 0 && hp_regen_per_second_timer.Check()) {
|
||||||
|
if (GetHP() < GetMaxHP()) {
|
||||||
|
SetHP(GetHP() + hp_regen_per_second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tic_timer.Check()) {
|
if (tic_timer.Check()) {
|
||||||
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
|
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
|
||||||
BuffProcess();
|
BuffProcess();
|
||||||
@ -2594,6 +2601,10 @@ void NPC::ModifyNPCStat(const char *identifier, const char *new_value)
|
|||||||
hp_regen = atoi(val.c_str());
|
hp_regen = atoi(val.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (id == "hp_regen_per_second") {
|
||||||
|
hp_regen_per_second = strtoll(val.c_str(), nullptr, 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (id == "mana_regen") {
|
else if (id == "mana_regen") {
|
||||||
mana_regen = atoi(val.c_str());
|
mana_regen = atoi(val.c_str());
|
||||||
return;
|
return;
|
||||||
@ -2741,6 +2752,9 @@ float NPC::GetNPCStat(const char *identifier)
|
|||||||
else if (id == "hp_regen") {
|
else if (id == "hp_regen") {
|
||||||
return hp_regen;
|
return hp_regen;
|
||||||
}
|
}
|
||||||
|
else if (id == "hp_regen_per_second") {
|
||||||
|
return hp_regen_per_second;
|
||||||
|
}
|
||||||
else if (id == "mana_regen") {
|
else if (id == "mana_regen") {
|
||||||
return mana_regen;
|
return mana_regen;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2476,7 +2476,9 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
|||||||
"npc_types.model, "
|
"npc_types.model, "
|
||||||
"npc_types.flymode, "
|
"npc_types.flymode, "
|
||||||
"npc_types.always_aggro, "
|
"npc_types.always_aggro, "
|
||||||
"npc_types.exp_mod "
|
"npc_types.exp_mod, "
|
||||||
|
"npc_types.hp_regen_per_second "
|
||||||
|
|
||||||
"FROM npc_types %s",
|
"FROM npc_types %s",
|
||||||
where_condition.c_str()
|
where_condition.c_str()
|
||||||
);
|
);
|
||||||
@ -2542,14 +2544,14 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
|||||||
temp_npctype_data->d_melee_texture1 = atoi(row[38]);
|
temp_npctype_data->d_melee_texture1 = atoi(row[38]);
|
||||||
temp_npctype_data->d_melee_texture2 = atoi(row[39]);
|
temp_npctype_data->d_melee_texture2 = atoi(row[39]);
|
||||||
strn0cpy(temp_npctype_data->ammo_idfile, row[40], 30);
|
strn0cpy(temp_npctype_data->ammo_idfile, row[40], 30);
|
||||||
temp_npctype_data->prim_melee_type = atoi(row[41]);
|
temp_npctype_data->prim_melee_type = atoi(row[41]);
|
||||||
temp_npctype_data->sec_melee_type = atoi(row[42]);
|
temp_npctype_data->sec_melee_type = atoi(row[42]);
|
||||||
temp_npctype_data->ranged_type = atoi(row[43]);
|
temp_npctype_data->ranged_type = atoi(row[43]);
|
||||||
temp_npctype_data->runspeed = atof(row[44]);
|
temp_npctype_data->runspeed = atof(row[44]);
|
||||||
temp_npctype_data->findable = atoi(row[45]) == 0 ? false : true;
|
temp_npctype_data->findable = atoi(row[45]) == 0 ? false : true;
|
||||||
temp_npctype_data->trackable = atoi(row[46]) == 0 ? false : true;
|
temp_npctype_data->trackable = atoi(row[46]) == 0 ? false : true;
|
||||||
temp_npctype_data->hp_regen = atoi(row[47]);
|
temp_npctype_data->hp_regen = atoi(row[47]);
|
||||||
temp_npctype_data->mana_regen = atoi(row[48]);
|
temp_npctype_data->mana_regen = atoi(row[48]);
|
||||||
|
|
||||||
// set default value for aggroradius
|
// set default value for aggroradius
|
||||||
temp_npctype_data->aggroradius = (int32) atoi(row[49]);
|
temp_npctype_data->aggroradius = (int32) atoi(row[49]);
|
||||||
@ -2673,13 +2675,14 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
|||||||
temp_npctype_data->charm_avoidance_rating = atoi(row[105]);
|
temp_npctype_data->charm_avoidance_rating = atoi(row[105]);
|
||||||
temp_npctype_data->charm_atk = atoi(row[106]);
|
temp_npctype_data->charm_atk = atoi(row[106]);
|
||||||
|
|
||||||
temp_npctype_data->skip_global_loot = atoi(row[107]) != 0;
|
temp_npctype_data->skip_global_loot = atoi(row[107]) != 0;
|
||||||
temp_npctype_data->rare_spawn = atoi(row[108]) != 0;
|
temp_npctype_data->rare_spawn = atoi(row[108]) != 0;
|
||||||
temp_npctype_data->stuck_behavior = atoi(row[109]);
|
temp_npctype_data->stuck_behavior = atoi(row[109]);
|
||||||
temp_npctype_data->use_model = atoi(row[110]);
|
temp_npctype_data->use_model = atoi(row[110]);
|
||||||
temp_npctype_data->flymode = atoi(row[111]);
|
temp_npctype_data->flymode = atoi(row[111]);
|
||||||
temp_npctype_data->always_aggro = atoi(row[112]);
|
temp_npctype_data->always_aggro = atoi(row[112]);
|
||||||
temp_npctype_data->exp_mod = atoi(row[113]);
|
temp_npctype_data->exp_mod = atoi(row[113]);
|
||||||
|
temp_npctype_data->hp_regen_per_second = strtoll(row[114], nullptr, 10);
|
||||||
|
|
||||||
temp_npctype_data->skip_auto_scale = false; // hardcoded here for now
|
temp_npctype_data->skip_auto_scale = false; // hardcoded here for now
|
||||||
|
|
||||||
@ -3588,7 +3591,7 @@ void ZoneDatabase::ListAllInstances(Client* client, uint32 character_id)
|
|||||||
remaining_time_string = "Already Expired";
|
remaining_time_string = "Already Expired";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client->Message(
|
client->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format("Instance {} | Zone: {} ({}){}",
|
fmt::format("Instance {} | Zone: {} ({}){}",
|
||||||
@ -3860,7 +3863,7 @@ void ZoneDatabase::SavePetInfo(Client *client)
|
|||||||
"ON DUPLICATE KEY UPDATE `petname` = '%s', `petpower` = %i, `spell_id` = %u, "
|
"ON DUPLICATE KEY UPDATE `petname` = '%s', `petpower` = %i, `spell_id` = %u, "
|
||||||
"`hp` = %u, `mana` = %u, `size` = %f, `taunting` = %u",
|
"`hp` = %u, `mana` = %u, `size` = %f, `taunting` = %u",
|
||||||
client->CharacterID(), pet, petinfo->Name, petinfo->petpower, petinfo->SpellID,
|
client->CharacterID(), pet, petinfo->Name, petinfo->petpower, petinfo->SpellID,
|
||||||
petinfo->HP, petinfo->Mana, petinfo->size, (petinfo->taunting) ? 1 : 0,
|
petinfo->HP, petinfo->Mana, petinfo->size, (petinfo->taunting) ? 1 : 0,
|
||||||
// and now the ON DUPLICATE ENTRIES
|
// and now the ON DUPLICATE ENTRIES
|
||||||
petinfo->Name, petinfo->petpower, petinfo->SpellID, petinfo->HP, petinfo->Mana, petinfo->size, (petinfo->taunting) ? 1 : 0);
|
petinfo->Name, petinfo->petpower, petinfo->SpellID, petinfo->HP, petinfo->Mana, petinfo->size, (petinfo->taunting) ? 1 : 0);
|
||||||
results = database.QueryDatabase(query);
|
results = database.QueryDatabase(query);
|
||||||
|
|||||||
@ -35,9 +35,9 @@ spawn2 mediumblob, npcs mediumblob, npc_loot mediumblob, gmspawntype mediumblob,
|
|||||||
struct NPCType
|
struct NPCType
|
||||||
{
|
{
|
||||||
char name[64];
|
char name[64];
|
||||||
char lastname[70];
|
char lastname[70];
|
||||||
int32 current_hp;
|
int32 current_hp;
|
||||||
int32 max_hp;
|
int32 max_hp;
|
||||||
float size;
|
float size;
|
||||||
float runspeed;
|
float runspeed;
|
||||||
uint8 gender;
|
uint8 gender;
|
||||||
@ -105,6 +105,7 @@ struct NPCType
|
|||||||
uint8 sec_melee_type;
|
uint8 sec_melee_type;
|
||||||
uint8 ranged_type;
|
uint8 ranged_type;
|
||||||
int32 hp_regen;
|
int32 hp_regen;
|
||||||
|
int64 hp_regen_per_second;
|
||||||
int32 mana_regen;
|
int32 mana_regen;
|
||||||
int32 aggroradius; // added for AI improvement - neotokyo
|
int32 aggroradius; // added for AI improvement - neotokyo
|
||||||
int32 assistradius; // assist radius, defaults to aggroradis if not set
|
int32 assistradius; // assist radius, defaults to aggroradis if not set
|
||||||
@ -122,7 +123,7 @@ struct NPCType
|
|||||||
int avoidance_rating; // flat bonus before mods
|
int avoidance_rating; // flat bonus before mods
|
||||||
bool findable; //can be found with find command
|
bool findable; //can be found with find command
|
||||||
bool trackable;
|
bool trackable;
|
||||||
int16 slow_mitigation;
|
int16 slow_mitigation;
|
||||||
uint8 maxlevel;
|
uint8 maxlevel;
|
||||||
uint32 scalerate;
|
uint32 scalerate;
|
||||||
bool private_corpse;
|
bool private_corpse;
|
||||||
@ -164,8 +165,8 @@ namespace player_lootitem {
|
|||||||
uint32 aug_5;
|
uint32 aug_5;
|
||||||
uint32 aug_6;
|
uint32 aug_6;
|
||||||
int8 attuned;
|
int8 attuned;
|
||||||
uint8 min_level; //
|
uint8 min_level; //
|
||||||
uint8 max_level; //
|
uint8 max_level; //
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user