mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +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
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9178
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9179
|
||||
|
||||
#ifdef BOTS
|
||||
#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|
|
||||
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|
|
||||
9179|2022_04_30_hp_regen_per_second.sql|SHOW COLUMNS FROM `npc_types` LIKE 'hp_regen_per_second'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# 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 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 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 loottable - Sets an NPC's Loottable 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
c->Message(
|
||||
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
|
||||
base_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet
|
||||
hp_regen = npc_type->hp_regen;
|
||||
hp_regen_per_second = npc_type->hp_regen_per_second;
|
||||
mana_regen = npc_type->mana_regen;
|
||||
max_dmg = npc_type->max_dmg;
|
||||
min_dmg = npc_type->min_dmg;
|
||||
|
||||
@ -96,11 +96,13 @@ Mob::Mob(
|
||||
uint8 in_legtexture,
|
||||
uint8 in_feettexture,
|
||||
uint16 in_usemodel,
|
||||
bool in_always_aggro
|
||||
bool in_always_aggro,
|
||||
int64 in_hp_regen_per_second
|
||||
) :
|
||||
attack_timer(2000),
|
||||
attack_dw_timer(2000),
|
||||
ranged_timer(2000),
|
||||
hp_regen_per_second_timer(1000),
|
||||
tic_timer(6000),
|
||||
mana_timer(2000),
|
||||
spellend_timer(0),
|
||||
@ -264,6 +266,7 @@ Mob::Mob(
|
||||
current_mana = 0;
|
||||
max_mana = 0;
|
||||
hp_regen = in_hp_regen;
|
||||
hp_regen_per_second = in_hp_regen_per_second;
|
||||
mana_regen = in_mana_regen;
|
||||
ooc_regen = RuleI(NPC, OOCRegen); //default Out of Combat Regen
|
||||
maxlevel = in_maxlevel;
|
||||
|
||||
@ -162,7 +162,8 @@ public:
|
||||
uint8 in_legtexture,
|
||||
uint8 in_feettexture,
|
||||
uint16 in_usemodel,
|
||||
bool in_always_aggros_foes
|
||||
bool in_always_aggros_foes,
|
||||
int64 in_hp_regen_per_second = 0
|
||||
);
|
||||
virtual ~Mob();
|
||||
|
||||
@ -1424,6 +1425,7 @@ protected:
|
||||
int32 current_mana;
|
||||
int32 max_mana;
|
||||
int32 hp_regen;
|
||||
int64 hp_regen_per_second;
|
||||
int32 mana_regen;
|
||||
int32 ooc_regen;
|
||||
uint8 maxlevel;
|
||||
@ -1542,6 +1544,7 @@ protected:
|
||||
int attack_delay; //delay between attacks in 10ths of seconds
|
||||
bool always_aggro;
|
||||
int16 slow_mitigation; // Allows for a slow mitigation (100 = 100%, 50% = 50%)
|
||||
Timer hp_regen_per_second_timer;
|
||||
Timer tic_timer;
|
||||
Timer mana_timer;
|
||||
int32 dw_same_delay;
|
||||
|
||||
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->feettexture,
|
||||
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),
|
||||
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()) {
|
||||
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
|
||||
BuffProcess();
|
||||
@ -2594,6 +2601,10 @@ void NPC::ModifyNPCStat(const char *identifier, const char *new_value)
|
||||
hp_regen = atoi(val.c_str());
|
||||
return;
|
||||
}
|
||||
else if (id == "hp_regen_per_second") {
|
||||
hp_regen_per_second = strtoll(val.c_str(), nullptr, 10);
|
||||
return;
|
||||
}
|
||||
else if (id == "mana_regen") {
|
||||
mana_regen = atoi(val.c_str());
|
||||
return;
|
||||
@ -2741,6 +2752,9 @@ float NPC::GetNPCStat(const char *identifier)
|
||||
else if (id == "hp_regen") {
|
||||
return hp_regen;
|
||||
}
|
||||
else if (id == "hp_regen_per_second") {
|
||||
return hp_regen_per_second;
|
||||
}
|
||||
else if (id == "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.flymode, "
|
||||
"npc_types.always_aggro, "
|
||||
"npc_types.exp_mod "
|
||||
"npc_types.exp_mod, "
|
||||
"npc_types.hp_regen_per_second "
|
||||
|
||||
"FROM npc_types %s",
|
||||
where_condition.c_str()
|
||||
);
|
||||
@ -2680,6 +2682,7 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
temp_npctype_data->flymode = atoi(row[111]);
|
||||
temp_npctype_data->always_aggro = atoi(row[112]);
|
||||
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
|
||||
|
||||
|
||||
@ -105,6 +105,7 @@ struct NPCType
|
||||
uint8 sec_melee_type;
|
||||
uint8 ranged_type;
|
||||
int32 hp_regen;
|
||||
int64 hp_regen_per_second;
|
||||
int32 mana_regen;
|
||||
int32 aggroradius; // added for AI improvement - neotokyo
|
||||
int32 assistradius; // assist radius, defaults to aggroradis if not set
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user