mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-30 13:32:26 +00:00
Merge pull request #668 from regneq/master
Trap overhaul ported from takp
This commit is contained in:
commit
bc348dadad
@ -89,6 +89,7 @@ enum LogCategory {
|
|||||||
HP_Update,
|
HP_Update,
|
||||||
FixZ,
|
FixZ,
|
||||||
Food,
|
Food,
|
||||||
|
Traps,
|
||||||
MaxCategoryID /* Don't Remove this*/
|
MaxCategoryID /* Don't Remove this*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +143,8 @@ static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
|
|||||||
"Headless Client",
|
"Headless Client",
|
||||||
"HP Update",
|
"HP Update",
|
||||||
"FixZ",
|
"FixZ",
|
||||||
"Food"
|
"Food",
|
||||||
|
"Traps"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 9114
|
#define CURRENT_BINARY_DATABASE_VERSION 9115
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -368,6 +368,7 @@
|
|||||||
9112|2017_06_24_rule_values_expand.sql|SHOW COLUMNS FROM rule_values WHERE Field = 'rule_value' and Type = 'varchar(30)'|empty|
|
9112|2017_06_24_rule_values_expand.sql|SHOW COLUMNS FROM rule_values WHERE Field = 'rule_value' and Type = 'varchar(30)'|empty|
|
||||||
9113|2017_07_19_show_name.sql|SHOW COLUMNS FROM `npc_types` LIKE 'show_name'|empty|
|
9113|2017_07_19_show_name.sql|SHOW COLUMNS FROM `npc_types` LIKE 'show_name'|empty|
|
||||||
9114|2017_07_22_aura.sql|SHOW TABLES LIKE 'auras'|empty|
|
9114|2017_07_22_aura.sql|SHOW TABLES LIKE 'auras'|empty|
|
||||||
|
9115|2017_10_28_traps.sql|SHOW COLUMNS FROM `traps` LIKE 'triggered_number'|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
|
||||||
|
|||||||
4
utils/sql/git/required/2017_10_28_traps.sql
Normal file
4
utils/sql/git/required/2017_10_28_traps.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
alter table `traps` add column `triggered_number` tinyint(4) not null default 0;
|
||||||
|
alter table `traps` add column `group` tinyint(4) not null default 0;
|
||||||
|
alter table `traps` add column `despawn_when_triggered` tinyint(4) not null default 0;
|
||||||
|
alter table `traps` add column `undetectable` tinyint(4) not null default 0;
|
||||||
@ -2533,6 +2533,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
|||||||
if (other == this)
|
if (other == this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (other->IsTrap())
|
||||||
|
return;
|
||||||
|
|
||||||
if (damage < 0) {
|
if (damage < 0) {
|
||||||
hate = 1;
|
hate = 1;
|
||||||
}
|
}
|
||||||
@ -3364,7 +3367,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
|||||||
// pets that have GHold will never automatically add NPCs
|
// pets that have GHold will never automatically add NPCs
|
||||||
// pets that have Hold and no Focus will add NPCs if they're engaged
|
// pets that have Hold and no Focus will add NPCs if they're engaged
|
||||||
// pets that have Hold and Focus will not add NPCs
|
// pets that have Hold and Focus will not add NPCs
|
||||||
if (pet && !pet->IsFamiliar() && !pet->GetSpecialAbility(IMMUNE_AGGRO) && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse() && !pet->IsGHeld())
|
if (pet && !pet->IsFamiliar() && !pet->GetSpecialAbility(IMMUNE_AGGRO) && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse() && !pet->IsGHeld() && !attacker->IsTrap())
|
||||||
{
|
{
|
||||||
if (!pet->IsHeld()) {
|
if (!pet->IsHeld()) {
|
||||||
Log(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName());
|
Log(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName());
|
||||||
|
|||||||
@ -331,6 +331,8 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
|
|
||||||
interrogateinv_flag = false;
|
interrogateinv_flag = false;
|
||||||
|
|
||||||
|
trapid = 0;
|
||||||
|
|
||||||
for (int i = 0; i < InnateSkillMax; ++i)
|
for (int i = 0; i < InnateSkillMax; ++i)
|
||||||
m_pp.InnateSkills[i] = InnateDisabled;
|
m_pp.InnateSkills[i] = InnateDisabled;
|
||||||
|
|
||||||
|
|||||||
@ -1302,6 +1302,8 @@ public:
|
|||||||
|
|
||||||
int32 CalcATK();
|
int32 CalcATK();
|
||||||
|
|
||||||
|
uint32 trapid; //ID of trap player has triggered. This is cleared when the player leaves the trap's radius, or it despawns.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Mob;
|
friend class Mob;
|
||||||
void CalcItemBonuses(StatBonuses* newbon);
|
void CalcItemBonuses(StatBonuses* newbon);
|
||||||
|
|||||||
@ -5329,31 +5329,44 @@ void Client::Handle_OP_DisarmTraps(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
p_timers.Start(pTimerDisarmTraps, reuse - 1);
|
p_timers.Start(pTimerDisarmTraps, reuse - 1);
|
||||||
|
|
||||||
Trap* trap = entity_list.FindNearbyTrap(this, 60);
|
uint8 success = SKILLUP_FAILURE;
|
||||||
|
float curdist = 0;
|
||||||
|
Trap* trap = entity_list.FindNearbyTrap(this, 250, curdist, true);
|
||||||
if (trap && trap->detected)
|
if (trap && trap->detected)
|
||||||
|
{
|
||||||
|
float max_radius = (trap->radius * 2) * (trap->radius * 2); // radius is used to trigger trap, so disarm radius should be a bit bigger.
|
||||||
|
Log(Logs::General, Logs::Traps, "%s is attempting to disarm trap %d. Curdist is %0.2f maxdist is %0.2f", GetName(), trap->trap_id, curdist, max_radius);
|
||||||
|
if (curdist <= max_radius)
|
||||||
{
|
{
|
||||||
int uskill = GetSkill(EQEmu::skills::SkillDisarmTraps);
|
int uskill = GetSkill(EQEmu::skills::SkillDisarmTraps);
|
||||||
if ((zone->random.Int(0, 49) + uskill) >= (zone->random.Int(0, 49) + trap->skill))
|
if ((zone->random.Int(0, 49) + uskill) >= (zone->random.Int(0, 49) + trap->skill))
|
||||||
{
|
{
|
||||||
Message(MT_Skills, "You disarm a trap.");
|
success = SKILLUP_SUCCESS;
|
||||||
|
Message_StringID(MT_Skills, DISARMED_TRAP);
|
||||||
trap->disarmed = true;
|
trap->disarmed = true;
|
||||||
trap->chkarea_timer.Disable();
|
Log(Logs::General, Logs::Traps, "Trap %d is disarmed.", trap->trap_id);
|
||||||
trap->respawn_timer.Start((trap->respawn_time + zone->random.Int(0, trap->respawn_var)) * 1000);
|
trap->UpdateTrap();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Message_StringID(MT_Skills, FAIL_DISARM_DETECTED_TRAP);
|
||||||
if (zone->random.Int(0, 99) < 25) {
|
if (zone->random.Int(0, 99) < 25) {
|
||||||
Message(MT_Skills, "You set off the trap while trying to disarm it!");
|
|
||||||
trap->Trigger(this);
|
trap->Trigger(this);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Message(MT_Skills, "You failed to disarm a trap.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CheckIncreaseSkill(EQEmu::skills::SkillDisarmTraps, nullptr);
|
CheckIncreaseSkill(EQEmu::skills::SkillDisarmTraps, nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Message(MT_Skills, "You did not find any traps close enough to disarm.");
|
else
|
||||||
|
{
|
||||||
|
Message_StringID(MT_Skills, TRAP_TOO_FAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message_StringID(MT_Skills, LDON_SENSE_TRAP2);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12107,7 +12120,8 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
p_timers.Start(pTimerSenseTraps, reuse - 1);
|
p_timers.Start(pTimerSenseTraps, reuse - 1);
|
||||||
|
|
||||||
Trap* trap = entity_list.FindNearbyTrap(this, 800);
|
float trap_curdist = 0;
|
||||||
|
Trap* trap = entity_list.FindNearbyTrap(this, 800, trap_curdist);
|
||||||
|
|
||||||
CheckIncreaseSkill(EQEmu::skills::SkillSenseTraps, nullptr);
|
CheckIncreaseSkill(EQEmu::skills::SkillSenseTraps, nullptr);
|
||||||
|
|
||||||
|
|||||||
@ -321,6 +321,7 @@ int command_init(void)
|
|||||||
command_add("reloadqst", " - Clear quest cache (any argument causes it to also stop all timers)", 150, command_reloadqst) ||
|
command_add("reloadqst", " - Clear quest cache (any argument causes it to also stop all timers)", 150, command_reloadqst) ||
|
||||||
command_add("reloadrulesworld", "Executes a reload of all rules in world specifically.", 80, command_reloadworldrules) ||
|
command_add("reloadrulesworld", "Executes a reload of all rules in world specifically.", 80, command_reloadworldrules) ||
|
||||||
command_add("reloadstatic", "- Reload Static Zone Data", 150, command_reloadstatic) ||
|
command_add("reloadstatic", "- Reload Static Zone Data", 150, command_reloadstatic) ||
|
||||||
|
command_add("reloadtraps", "- Repops all traps in the current zone.", 80, command_reloadtraps) ||
|
||||||
command_add("reloadtitles", "- Reload player titles from the database", 150, command_reloadtitles) ||
|
command_add("reloadtitles", "- Reload player titles from the database", 150, command_reloadtitles) ||
|
||||||
command_add("reloadworld", "[0|1] - Clear quest cache (0 - no repop, 1 - repop)", 255, command_reloadworld) ||
|
command_add("reloadworld", "[0|1] - Clear quest cache (0 - no repop, 1 - repop)", 255, command_reloadworld) ||
|
||||||
command_add("reloadzps", "- Reload zone points from database", 150, command_reloadzps) ||
|
command_add("reloadzps", "- Reload zone points from database", 150, command_reloadzps) ||
|
||||||
@ -382,6 +383,7 @@ int command_init(void)
|
|||||||
command_add("title", "[text] [1 = create title table row] - Set your or your player target's title", 50, command_title) ||
|
command_add("title", "[text] [1 = create title table row] - Set your or your player target's title", 50, command_title) ||
|
||||||
command_add("titlesuffix", "[text] [1 = create title table row] - Set your or your player target's title suffix", 50, command_titlesuffix) ||
|
command_add("titlesuffix", "[text] [1 = create title table row] - Set your or your player target's title suffix", 50, command_titlesuffix) ||
|
||||||
command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", 150, command_traindisc) ||
|
command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", 150, command_traindisc) ||
|
||||||
|
command_add("trapinfo", "- Gets infomation about the traps currently spawned in the zone.", 81, command_trapinfo) ||
|
||||||
command_add("tune", "Calculate ideal statical values related to combat.", 100, command_tune) ||
|
command_add("tune", "Calculate ideal statical values related to combat.", 100, command_tune) ||
|
||||||
command_add("undyeme", "- Remove dye from all of your armor slots", 0, command_undyeme) ||
|
command_add("undyeme", "- Remove dye from all of your armor slots", 0, command_undyeme) ||
|
||||||
command_add("unfreeze", "- Unfreeze your target", 80, command_unfreeze) ||
|
command_add("unfreeze", "- Unfreeze your target", 80, command_unfreeze) ||
|
||||||
@ -10851,6 +10853,16 @@ void command_reloadperlexportsettings(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void command_trapinfo(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
entity_list.GetTrapInfo(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_reloadtraps(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
entity_list.UpdateAllTraps(true, true);
|
||||||
|
c->Message(CC_Default, "Traps reloaded for %s.", zone->GetShortName());
|
||||||
|
}
|
||||||
|
|
||||||
// All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block.
|
// All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block.
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
|
|||||||
@ -228,6 +228,7 @@ void command_reloadperlexportsettings(Client *c, const Seperator *sep);
|
|||||||
void command_reloadqst(Client *c, const Seperator *sep);
|
void command_reloadqst(Client *c, const Seperator *sep);
|
||||||
void command_reloadstatic(Client *c, const Seperator *sep);
|
void command_reloadstatic(Client *c, const Seperator *sep);
|
||||||
void command_reloadtitles(Client *c, const Seperator *sep);
|
void command_reloadtitles(Client *c, const Seperator *sep);
|
||||||
|
void command_reloadtraps(Client* c, const Seperator *sep);
|
||||||
void command_reloadworld(Client *c, const Seperator *sep);
|
void command_reloadworld(Client *c, const Seperator *sep);
|
||||||
void command_reloadworldrules(Client *c, const Seperator *sep);
|
void command_reloadworldrules(Client *c, const Seperator *sep);
|
||||||
void command_reloadzps(Client *c, const Seperator *sep);
|
void command_reloadzps(Client *c, const Seperator *sep);
|
||||||
@ -295,6 +296,7 @@ void command_timezone(Client *c, const Seperator *sep);
|
|||||||
void command_title(Client *c, const Seperator *sep);
|
void command_title(Client *c, const Seperator *sep);
|
||||||
void command_titlesuffix(Client *c, const Seperator *sep);
|
void command_titlesuffix(Client *c, const Seperator *sep);
|
||||||
void command_traindisc(Client *c, const Seperator *sep);
|
void command_traindisc(Client *c, const Seperator *sep);
|
||||||
|
void command_trapinfo(Client* c, const Seperator *sep);
|
||||||
void command_tune(Client *c, const Seperator *sep);
|
void command_tune(Client *c, const Seperator *sep);
|
||||||
void command_undye(Client *c, const Seperator *sep);
|
void command_undye(Client *c, const Seperator *sep);
|
||||||
void command_undyeme(Client *c, const Seperator *sep);
|
void command_undyeme(Client *c, const Seperator *sep);
|
||||||
|
|||||||
@ -604,6 +604,11 @@ enum { //type arguments to DoAnim
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SKILLUP_UNKNOWN = 0,
|
||||||
|
SKILLUP_SUCCESS = 1,
|
||||||
|
SKILLUP_FAILURE = 2
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
petFamiliar, //only listens to /pet get lost
|
petFamiliar, //only listens to /pet get lost
|
||||||
|
|||||||
@ -365,7 +365,7 @@ public:
|
|||||||
//trap stuff
|
//trap stuff
|
||||||
Mob* GetTrapTrigger(Trap* trap);
|
Mob* GetTrapTrigger(Trap* trap);
|
||||||
void SendAlarm(Trap* trap, Mob* currenttarget, uint8 kos);
|
void SendAlarm(Trap* trap, Mob* currenttarget, uint8 kos);
|
||||||
Trap* FindNearbyTrap(Mob* searcher, float max_dist);
|
Trap* FindNearbyTrap(Mob* searcher, float max_dist, float &curdist, bool detected = false);
|
||||||
|
|
||||||
void AddHealAggro(Mob* target, Mob* caster, uint16 hate);
|
void AddHealAggro(Mob* target, Mob* caster, uint16 hate);
|
||||||
Mob* FindDefenseNPC(uint32 npcid);
|
Mob* FindDefenseNPC(uint32 npcid);
|
||||||
@ -473,6 +473,10 @@ public:
|
|||||||
void RefreshClientXTargets(Client *c);
|
void RefreshClientXTargets(Client *c);
|
||||||
void SendAlternateAdvancementStats();
|
void SendAlternateAdvancementStats();
|
||||||
|
|
||||||
|
void GetTrapInfo(Client* client);
|
||||||
|
bool IsTrapGroupSpawned(uint32 trap_id, uint8 group);
|
||||||
|
void UpdateAllTraps(bool respawn, bool repopnow = false);
|
||||||
|
void ClearTrapPointers();
|
||||||
protected:
|
protected:
|
||||||
friend class Zone;
|
friend class Zone;
|
||||||
void Depop(bool StartSpawnTimer = false);
|
void Depop(bool StartSpawnTimer = false);
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#define PROC_TOOLOW 126 //Your will is not sufficient to command this weapon.
|
#define PROC_TOOLOW 126 //Your will is not sufficient to command this weapon.
|
||||||
#define PROC_PETTOOLOW 127 //Your pet's will is not sufficient to command its weapon.
|
#define PROC_PETTOOLOW 127 //Your pet's will is not sufficient to command its weapon.
|
||||||
#define YOU_FLURRY 128 //You unleash a flurry of attacks.
|
#define YOU_FLURRY 128 //You unleash a flurry of attacks.
|
||||||
|
#define FAILED_DISARM_TRAP 129 //You failed to disarm the trap.
|
||||||
#define DOORS_LOCKED 130 //It's locked and you're not holding the key.
|
#define DOORS_LOCKED 130 //It's locked and you're not holding the key.
|
||||||
#define DOORS_CANT_PICK 131 //This lock cannot be picked.
|
#define DOORS_CANT_PICK 131 //This lock cannot be picked.
|
||||||
#define DOORS_INSUFFICIENT_SKILL 132 //You are not sufficiently skilled to pick this lock.
|
#define DOORS_INSUFFICIENT_SKILL 132 //You are not sufficiently skilled to pick this lock.
|
||||||
@ -98,6 +99,7 @@
|
|||||||
#define DUP_LORE 290 //Duplicate lore items are not allowed.
|
#define DUP_LORE 290 //Duplicate lore items are not allowed.
|
||||||
#define TGB_ON 293 //Target other group buff is *ON*.
|
#define TGB_ON 293 //Target other group buff is *ON*.
|
||||||
#define TGB_OFF 294 //Target other group buff is *OFF*.
|
#define TGB_OFF 294 //Target other group buff is *OFF*.
|
||||||
|
#define DISARMED_TRAP 305 //You have disarmed the trap.
|
||||||
#define LDON_SENSE_TRAP1 306 //You do not Sense any traps.
|
#define LDON_SENSE_TRAP1 306 //You do not Sense any traps.
|
||||||
#define TRADESKILL_NOCOMBINE 334 //You cannot combine these items in this container type!
|
#define TRADESKILL_NOCOMBINE 334 //You cannot combine these items in this container type!
|
||||||
#define TRADESKILL_FAILED 336 //You lacked the skills to fashion the items together.
|
#define TRADESKILL_FAILED 336 //You lacked the skills to fashion the items together.
|
||||||
@ -114,6 +116,8 @@
|
|||||||
#define MEND_WORSEN 351 //You have worsened your wounds!
|
#define MEND_WORSEN 351 //You have worsened your wounds!
|
||||||
#define MEND_FAIL 352 //You have failed to mend your wounds.
|
#define MEND_FAIL 352 //You have failed to mend your wounds.
|
||||||
#define LDON_SENSE_TRAP2 367 //You have not detected any traps.
|
#define LDON_SENSE_TRAP2 367 //You have not detected any traps.
|
||||||
|
#define TRAP_TOO_FAR 368 //You are too far away from that trap to affect it.
|
||||||
|
#define FAIL_DISARM_DETECTED_TRAP 370 //You fail to disarm the detected trap.
|
||||||
#define LOOT_LORE_ERROR 371 //You cannot loot this Lore Item. You already have one.
|
#define LOOT_LORE_ERROR 371 //You cannot loot this Lore Item. You already have one.
|
||||||
#define PICK_LORE 379 //You cannot pick up a lore item you already possess.
|
#define PICK_LORE 379 //You cannot pick up a lore item you already possess.
|
||||||
#define CONSENT_DENIED 390 //You do not have consent to summon that corpse.
|
#define CONSENT_DENIED 390 //You do not have consent to summon that corpse.
|
||||||
@ -421,6 +425,7 @@
|
|||||||
#define SENSE_ANIMAL 12472 //You sense an animal in this direction.
|
#define SENSE_ANIMAL 12472 //You sense an animal in this direction.
|
||||||
#define SENSE_SUMMONED 12473 //You sense a summoned being in this direction.
|
#define SENSE_SUMMONED 12473 //You sense a summoned being in this direction.
|
||||||
#define SENSE_NOTHING 12474 //You don't sense anything.
|
#define SENSE_NOTHING 12474 //You don't sense anything.
|
||||||
|
#define SENSE_TRAP 12475 //You sense a trap in this direction.
|
||||||
#define LDON_SENSE_TRAP3 12476 //You don't sense any traps.
|
#define LDON_SENSE_TRAP3 12476 //You don't sense any traps.
|
||||||
#define INTERRUPT_SPELL_OTHER 12478 //%1's casting is interrupted!
|
#define INTERRUPT_SPELL_OTHER 12478 //%1's casting is interrupted!
|
||||||
#define YOU_HIT_NONMELEE 12481 //You were hit by non-melee for %1 damage.
|
#define YOU_HIT_NONMELEE 12481 //You were hit by non-melee for %1 damage.
|
||||||
|
|||||||
286
zone/trap.cpp
286
zone/trap.cpp
@ -52,10 +52,12 @@ CREATE TABLE traps (
|
|||||||
Trap::Trap() :
|
Trap::Trap() :
|
||||||
Entity(),
|
Entity(),
|
||||||
respawn_timer(600000),
|
respawn_timer(600000),
|
||||||
chkarea_timer(500),
|
chkarea_timer(1000),
|
||||||
|
reset_timer(5000),
|
||||||
m_Position(glm::vec3())
|
m_Position(glm::vec3())
|
||||||
{
|
{
|
||||||
trap_id = 0;
|
trap_id = 0;
|
||||||
|
db_id = 0;
|
||||||
maxzdiff = 0;
|
maxzdiff = 0;
|
||||||
radius = 0;
|
radius = 0;
|
||||||
effect = 0;
|
effect = 0;
|
||||||
@ -64,12 +66,20 @@ Trap::Trap() :
|
|||||||
skill = 0;
|
skill = 0;
|
||||||
level = 0;
|
level = 0;
|
||||||
respawn_timer.Disable();
|
respawn_timer.Disable();
|
||||||
|
reset_timer.Disable();
|
||||||
detected = false;
|
detected = false;
|
||||||
disarmed = false;
|
disarmed = false;
|
||||||
respawn_time = 0;
|
respawn_time = 0;
|
||||||
respawn_var = 0;
|
respawn_var = 0;
|
||||||
hiddenTrigger = nullptr;
|
hiddenTrigger = nullptr;
|
||||||
ownHiddenTrigger = false;
|
ownHiddenTrigger = false;
|
||||||
|
chance = 0;
|
||||||
|
triggered_number = 0;
|
||||||
|
times_triggered = 0;
|
||||||
|
group = 0;
|
||||||
|
despawn_when_triggered = false;
|
||||||
|
charid = 0;
|
||||||
|
undetectable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Trap::~Trap()
|
Trap::~Trap()
|
||||||
@ -80,8 +90,7 @@ Trap::~Trap()
|
|||||||
|
|
||||||
bool Trap::Process()
|
bool Trap::Process()
|
||||||
{
|
{
|
||||||
if (chkarea_timer.Enabled() && chkarea_timer.Check()
|
if (chkarea_timer.Enabled() && chkarea_timer.Check() && !reset_timer.Enabled())
|
||||||
/*&& zone->GetClientCount() > 0*/ )
|
|
||||||
{
|
{
|
||||||
Mob* trigger = entity_list.GetTrapTrigger(this);
|
Mob* trigger = entity_list.GetTrapTrigger(this);
|
||||||
if (trigger && !(trigger->IsClient() && trigger->CastToClient()->GetGM()))
|
if (trigger && !(trigger->IsClient() && trigger->CastToClient()->GetGM()))
|
||||||
@ -89,6 +98,13 @@ bool Trap::Process()
|
|||||||
Trigger(trigger);
|
Trigger(trigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (reset_timer.Enabled() && reset_timer.Check())
|
||||||
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "Reset timer disabled in Reset Check Process for trap %d.", trap_id);
|
||||||
|
reset_timer.Disable();
|
||||||
|
charid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (respawn_timer.Enabled() && respawn_timer.Check())
|
if (respawn_timer.Enabled() && respawn_timer.Check())
|
||||||
{
|
{
|
||||||
detected = false;
|
detected = false;
|
||||||
@ -96,11 +112,15 @@ bool Trap::Process()
|
|||||||
chkarea_timer.Enable();
|
chkarea_timer.Enable();
|
||||||
respawn_timer.Disable();
|
respawn_timer.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trap::Trigger(Mob* trigger)
|
void Trap::Trigger(Mob* trigger)
|
||||||
{
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "Trap %d triggered by %s for the %d time!", trap_id, trigger->GetName(), times_triggered + 1);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const NPCType* tmp = 0;
|
const NPCType* tmp = 0;
|
||||||
switch (effect)
|
switch (effect)
|
||||||
@ -128,7 +148,7 @@ void Trap::Trigger(Mob* trigger)
|
|||||||
entity_list.MessageClose(trigger,false,effectvalue,13,"%s",message.c_str());
|
entity_list.MessageClose(trigger,false,effectvalue,13,"%s",message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_list.SendAlarm(this,trigger,effectvalue);
|
entity_list.SendAlarm(this,trigger, effectvalue2);
|
||||||
break;
|
break;
|
||||||
case trapTypeMysticSpawn:
|
case trapTypeMysticSpawn:
|
||||||
if (message.empty())
|
if (message.empty())
|
||||||
@ -201,12 +221,41 @@ void Trap::Trigger(Mob* trigger)
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
respawn_timer.Start((respawn_time + zone->random.Int(0, respawn_var)) * 1000);
|
|
||||||
chkarea_timer.Disable();
|
if (trigger && trigger->IsClient())
|
||||||
disarmed = true;
|
{
|
||||||
|
trigger->CastToClient()->trapid = trap_id;
|
||||||
|
charid = trigger->CastToClient()->CharacterID();
|
||||||
}
|
}
|
||||||
|
|
||||||
Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist) {
|
bool update = false;
|
||||||
|
if (despawn_when_triggered)
|
||||||
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "Trap %d is despawning after being triggered.", trap_id);
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reset_timer.Start(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggered_number > 0)
|
||||||
|
++times_triggered;
|
||||||
|
|
||||||
|
if (triggered_number > 0 && triggered_number <= times_triggered)
|
||||||
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "Triggered number for trap %d reached. %d/%d", trap_id, times_triggered, triggered_number);
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
UpdateTrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist, float &trap_curdist, bool detected)
|
||||||
|
{
|
||||||
float dist = 999999;
|
float dist = 999999;
|
||||||
Trap* current_trap = nullptr;
|
Trap* current_trap = nullptr;
|
||||||
|
|
||||||
@ -215,61 +264,161 @@ Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist) {
|
|||||||
|
|
||||||
for (auto it = trap_list.begin(); it != trap_list.end(); ++it) {
|
for (auto it = trap_list.begin(); it != trap_list.end(); ++it) {
|
||||||
cur = it->second;
|
cur = it->second;
|
||||||
if(cur->disarmed)
|
if(cur->disarmed || (detected && !cur->detected) || cur->undetectable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto diff = glm::vec3(searcher->GetPosition()) - cur->m_Position;
|
auto diff = glm::vec3(searcher->GetPosition()) - cur->m_Position;
|
||||||
float curdist = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
|
float curdist = diff.x*diff.x + diff.y*diff.y;
|
||||||
|
diff.z = std::abs(diff.z);
|
||||||
|
|
||||||
if (curdist < max_dist2 && curdist < dist)
|
if (curdist < max_dist2 && curdist < dist && diff.z <= cur->maxzdiff)
|
||||||
{
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "Trap %d is curdist %0.1f", cur->db_id, curdist);
|
||||||
dist = curdist;
|
dist = curdist;
|
||||||
current_trap = cur;
|
current_trap = cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_trap != nullptr)
|
||||||
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "Trap %d is the closest trap.", current_trap->db_id);
|
||||||
|
trap_curdist = dist;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
trap_curdist = INVALID_INDEX;
|
||||||
|
|
||||||
return current_trap;
|
return current_trap;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob* EntityList::GetTrapTrigger(Trap* trap) {
|
Mob* EntityList::GetTrapTrigger(Trap* trap)
|
||||||
Mob* savemob = 0;
|
{
|
||||||
|
|
||||||
float maxdist = trap->radius * trap->radius;
|
float maxdist = trap->radius * trap->radius;
|
||||||
|
for (auto it = client_list.begin(); it != client_list.end(); ++it)
|
||||||
for (auto it = client_list.begin(); it != client_list.end(); ++it) {
|
{
|
||||||
Client* cur = it->second;
|
Client* cur = it->second;
|
||||||
|
|
||||||
auto diff = glm::vec3(cur->GetPosition()) - trap->m_Position;
|
auto diff = glm::vec3(cur->GetPosition()) - trap->m_Position;
|
||||||
diff.z = std::abs(diff.z);
|
diff.z = std::abs(diff.z);
|
||||||
|
|
||||||
if ((diff.x*diff.x + diff.y*diff.y) <= maxdist
|
if ((diff.x*diff.x + diff.y*diff.y) <= maxdist
|
||||||
&& diff.z < trap->maxzdiff)
|
&& diff.z <= trap->maxzdiff)
|
||||||
{
|
{
|
||||||
if (zone->random.Roll(trap->chance))
|
//This prevents the trap from triggering on players while zoning.
|
||||||
return(cur);
|
if (strcmp(cur->GetName(), "No name") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cur->trapid == 0 && !cur->GetGM() && (trap->chance == 0 || zone->random.Roll(trap->chance)))
|
||||||
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "%s is about to trigger trap %d of chance %d. diff: %0.2f maxdist: %0.2f zdiff: %0.2f maxzdiff: %0.2f", cur->GetName(), trap->trap_id, trap->chance, (diff.x*diff.x + diff.y*diff.y), maxdist, diff.z, trap->maxzdiff);
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
savemob = cur;
|
{
|
||||||
|
if (cur->trapid == trap->trap_id)
|
||||||
|
{
|
||||||
|
Log(Logs::General, Logs::Traps, "%s is clearing trapid for trap %d", cur->GetName(), trap->trap_id);
|
||||||
|
cur->trapid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return savemob;
|
bool EntityList::IsTrapGroupSpawned(uint32 trap_id, uint8 group)
|
||||||
|
{
|
||||||
|
auto it = trap_list.begin();
|
||||||
|
while (it != trap_list.end())
|
||||||
|
{
|
||||||
|
Trap* cur = it->second;
|
||||||
|
if (cur->IsTrap() && cur->group == group && cur->trap_id != trap_id)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: rewrite this to not need direct access to trap members.
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityList::UpdateAllTraps(bool respawn, bool repopnow)
|
||||||
|
{
|
||||||
|
auto it = trap_list.begin();
|
||||||
|
while (it != trap_list.end())
|
||||||
|
{
|
||||||
|
Trap* cur = it->second;
|
||||||
|
if (cur->IsTrap())
|
||||||
|
{
|
||||||
|
cur->UpdateTrap(respawn, repopnow);
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(Logs::General, Logs::Traps, "All traps updated.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityList::GetTrapInfo(Client* client)
|
||||||
|
{
|
||||||
|
uint8 count = 0;
|
||||||
|
auto it = trap_list.begin();
|
||||||
|
while (it != trap_list.end())
|
||||||
|
{
|
||||||
|
Trap* cur = it->second;
|
||||||
|
if (cur->IsTrap())
|
||||||
|
{
|
||||||
|
bool isset = (cur->chkarea_timer.Enabled() && !cur->reset_timer.Enabled());
|
||||||
|
client->Message(CC_Default, " Trap: (%d) found at %0.2f,%0.2f,%0.2f. Times Triggered: %d Is Active: %d Group: %d Message: %s", cur->trap_id, cur->m_Position.x, cur->m_Position.y, cur->m_Position.z, cur->times_triggered, isset, cur->group, cur->message.c_str());
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->Message(CC_Default, "%d traps found.", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityList::ClearTrapPointers()
|
||||||
|
{
|
||||||
|
auto it = trap_list.begin();
|
||||||
|
while (it != trap_list.end())
|
||||||
|
{
|
||||||
|
Trap* cur = it->second;
|
||||||
|
if (cur->IsTrap())
|
||||||
|
{
|
||||||
|
cur->DestroyHiddenTrigger();
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
|
bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
|
std::string query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
|
||||||
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level "
|
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level, "
|
||||||
"FROM traps WHERE zone='%s' AND version=%u", zonename, version);
|
"`group`, triggered_number, despawn_when_triggered, undetectable FROM traps WHERE zone='%s' AND version=%u", zonename, version);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
uint32 tid = atoi(row[0]);
|
||||||
|
uint8 grp = atoi(row[15]);
|
||||||
|
|
||||||
|
if (grp > 0)
|
||||||
|
{
|
||||||
|
// If a member of our group is already spawned skip loading this trap.
|
||||||
|
if (entity_list.IsTrapGroupSpawned(tid, grp))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
auto trap = new Trap();
|
auto trap = new Trap();
|
||||||
trap->trap_id = atoi(row[0]);
|
trap->trap_id = tid;
|
||||||
|
trap->db_id = tid;
|
||||||
trap->m_Position = glm::vec3(atof(row[1]), atof(row[2]), atof(row[3]));
|
trap->m_Position = glm::vec3(atof(row[1]), atof(row[2]), atof(row[3]));
|
||||||
trap->effect = atoi(row[4]);
|
trap->effect = atoi(row[4]);
|
||||||
trap->effectvalue = atoi(row[5]);
|
trap->effectvalue = atoi(row[5]);
|
||||||
@ -282,8 +431,13 @@ bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
|
|||||||
trap->respawn_time = atoi(row[12]);
|
trap->respawn_time = atoi(row[12]);
|
||||||
trap->respawn_var = atoi(row[13]);
|
trap->respawn_var = atoi(row[13]);
|
||||||
trap->level = atoi(row[14]);
|
trap->level = atoi(row[14]);
|
||||||
|
trap->group = grp;
|
||||||
|
trap->triggered_number = atoi(row[16]);
|
||||||
|
trap->despawn_when_triggered = atobool(row[17]);
|
||||||
|
trap->undetectable = atobool(row[18]);
|
||||||
entity_list.AddTrap(trap);
|
entity_list.AddTrap(trap);
|
||||||
trap->CreateHiddenTrigger();
|
trap->CreateHiddenTrigger();
|
||||||
|
Log(Logs::General, Logs::Traps, "Trap %d successfully loaded.", trap->trap_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -318,3 +472,87 @@ void Trap::CreateHiddenTrigger()
|
|||||||
hiddenTrigger = npca;
|
hiddenTrigger = npca;
|
||||||
ownHiddenTrigger = true;
|
ownHiddenTrigger = true;
|
||||||
}
|
}
|
||||||
|
bool ZoneDatabase::SetTrapData(Trap* trap, bool repopnow) {
|
||||||
|
|
||||||
|
uint32 dbid = trap->db_id;
|
||||||
|
std::string query;
|
||||||
|
|
||||||
|
if (trap->group > 0)
|
||||||
|
{
|
||||||
|
query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
|
||||||
|
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level, "
|
||||||
|
"triggered_number, despawn_when_triggered, undetectable FROM traps WHERE zone='%s' AND `group`=%d AND id != %d ORDER BY RAND() LIMIT 1", zone->GetShortName(), trap->group, dbid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We could just use the existing data here, but querying the DB is not expensive, and allows content developers to change traps without rebooting.
|
||||||
|
query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
|
||||||
|
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level, "
|
||||||
|
"triggered_number, despawn_when_triggered, undetectable FROM traps WHERE zone='%s' AND id = %d", zone->GetShortName(), dbid);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
|
||||||
|
trap->db_id = atoi(row[0]);
|
||||||
|
trap->m_Position = glm::vec3(atof(row[1]), atof(row[2]), atof(row[3]));
|
||||||
|
trap->effect = atoi(row[4]);
|
||||||
|
trap->effectvalue = atoi(row[5]);
|
||||||
|
trap->effectvalue2 = atoi(row[6]);
|
||||||
|
trap->skill = atoi(row[7]);
|
||||||
|
trap->maxzdiff = atof(row[8]);
|
||||||
|
trap->radius = atof(row[9]);
|
||||||
|
trap->chance = atoi(row[10]);
|
||||||
|
trap->message = row[11];
|
||||||
|
trap->respawn_time = atoi(row[12]);
|
||||||
|
trap->respawn_var = atoi(row[13]);
|
||||||
|
trap->level = atoi(row[14]);
|
||||||
|
trap->triggered_number = atoi(row[15]);
|
||||||
|
trap->despawn_when_triggered = atobool(row[16]);
|
||||||
|
trap->undetectable = atobool(row[17]);
|
||||||
|
trap->CreateHiddenTrigger();
|
||||||
|
|
||||||
|
if (repopnow)
|
||||||
|
{
|
||||||
|
trap->chkarea_timer.Enable();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trap->respawn_timer.Start((trap->respawn_time + zone->random.Int(0, trap->respawn_var)) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trap->trap_id != trap->db_id)
|
||||||
|
Log(Logs::General, Logs::Traps, "Trap (%d) DBID has changed from %d to %d", trap->trap_id, dbid, trap->db_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Trap::UpdateTrap(bool respawn, bool repopnow)
|
||||||
|
{
|
||||||
|
respawn_timer.Disable();
|
||||||
|
chkarea_timer.Disable();
|
||||||
|
reset_timer.Disable();
|
||||||
|
if (hiddenTrigger)
|
||||||
|
{
|
||||||
|
hiddenTrigger->Depop();
|
||||||
|
hiddenTrigger = nullptr;
|
||||||
|
}
|
||||||
|
times_triggered = 0;
|
||||||
|
Client* trigger = entity_list.GetClientByCharID(charid);
|
||||||
|
if (trigger)
|
||||||
|
{
|
||||||
|
trigger->trapid = 0;
|
||||||
|
}
|
||||||
|
charid = 0;
|
||||||
|
if (respawn)
|
||||||
|
{
|
||||||
|
database.SetTrapData(this, repopnow);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
zone/trap.h
13
zone/trap.h
@ -49,11 +49,14 @@ public:
|
|||||||
NPC * GetHiddenTrigger() { return hiddenTrigger; }
|
NPC * GetHiddenTrigger() { return hiddenTrigger; }
|
||||||
void SetHiddenTrigger(NPC* n) { hiddenTrigger = n; }
|
void SetHiddenTrigger(NPC* n) { hiddenTrigger = n; }
|
||||||
void CreateHiddenTrigger();
|
void CreateHiddenTrigger();
|
||||||
|
void DestroyHiddenTrigger() { hiddenTrigger = nullptr; }
|
||||||
|
void UpdateTrap(bool respawn = true, bool repopnow = false);
|
||||||
//Trap data, leave this unprotected
|
//Trap data, leave this unprotected
|
||||||
Timer respawn_timer; //Respawn Time when Trap's been disarmed
|
Timer respawn_timer; //Respawn Time when Trap's been disarmed
|
||||||
Timer chkarea_timer;
|
Timer chkarea_timer;
|
||||||
uint32 trap_id; //Database ID of trap
|
Timer reset_timer; //How long a trap takes to reset before triggering again.
|
||||||
|
uint32 trap_id; //Original ID of the trap from DB. This value never changes.
|
||||||
|
uint32 db_id; //The DB ID of the trap that currently is spawned.
|
||||||
glm::vec3 m_Position;
|
glm::vec3 m_Position;
|
||||||
float maxzdiff; //maximum z diff to be triggerable
|
float maxzdiff; //maximum z diff to be triggerable
|
||||||
float radius; //radius around trap to be triggerable
|
float radius; //radius around trap to be triggerable
|
||||||
@ -67,6 +70,12 @@ public:
|
|||||||
bool disarmed;
|
bool disarmed;
|
||||||
uint32 respawn_time;
|
uint32 respawn_time;
|
||||||
uint32 respawn_var;
|
uint32 respawn_var;
|
||||||
|
uint8 triggered_number;
|
||||||
|
uint8 times_triggered;
|
||||||
|
uint8 group;
|
||||||
|
bool despawn_when_triggered;
|
||||||
|
uint32 charid; //ID of character that triggered trap. This is cleared when the trap despawns are resets.
|
||||||
|
bool undetectable;
|
||||||
|
|
||||||
std::string message;
|
std::string message;
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -1428,7 +1428,8 @@ void Zone::StartShutdownTimer(uint32 set_time) {
|
|||||||
bool Zone::Depop(bool StartSpawnTimer) {
|
bool Zone::Depop(bool StartSpawnTimer) {
|
||||||
std::map<uint32,NPCType *>::iterator itr;
|
std::map<uint32,NPCType *>::iterator itr;
|
||||||
entity_list.Depop(StartSpawnTimer);
|
entity_list.Depop(StartSpawnTimer);
|
||||||
|
entity_list.ClearTrapPointers();
|
||||||
|
entity_list.UpdateAllTraps(false);
|
||||||
/* Refresh npctable (cache), getting current info from database. */
|
/* Refresh npctable (cache), getting current info from database. */
|
||||||
while(!npctable.empty()) {
|
while(!npctable.empty()) {
|
||||||
itr = npctable.begin();
|
itr = npctable.begin();
|
||||||
@ -1496,6 +1497,8 @@ void Zone::Repop(uint32 delay) {
|
|||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity_list.ClearTrapPointers();
|
||||||
|
|
||||||
quest_manager.ClearAllTimers();
|
quest_manager.ClearAllTimers();
|
||||||
|
|
||||||
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay))
|
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay))
|
||||||
@ -1503,6 +1506,8 @@ void Zone::Repop(uint32 delay) {
|
|||||||
|
|
||||||
initgrids_timer.Start();
|
initgrids_timer.Start();
|
||||||
|
|
||||||
|
entity_list.UpdateAllTraps(true, true);
|
||||||
|
|
||||||
//MODDING HOOK FOR REPOP
|
//MODDING HOOK FOR REPOP
|
||||||
mod_repop();
|
mod_repop();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ class NPC;
|
|||||||
class Petition;
|
class Petition;
|
||||||
class Spawn2;
|
class Spawn2;
|
||||||
class SpawnGroupList;
|
class SpawnGroupList;
|
||||||
|
class Trap;
|
||||||
struct CharacterEventLog_Struct;
|
struct CharacterEventLog_Struct;
|
||||||
struct Door;
|
struct Door;
|
||||||
struct ExtendedProfile_Struct;
|
struct ExtendedProfile_Struct;
|
||||||
@ -478,7 +479,7 @@ public:
|
|||||||
|
|
||||||
/* Traps */
|
/* Traps */
|
||||||
bool LoadTraps(const char* zonename, int16 version);
|
bool LoadTraps(const char* zonename, int16 version);
|
||||||
char* GetTrapMessage(uint32 trap_id);
|
bool SetTrapData(Trap* trap, bool repopnow = false);
|
||||||
|
|
||||||
/* Time */
|
/* Time */
|
||||||
uint32 GetZoneTZ(uint32 zoneid, uint32 version);
|
uint32 GetZoneTZ(uint32 zoneid, uint32 version);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user