mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 23:01:30 +00:00
Implemented standardized zone controller scripts (Rule Zone, UseZoneController) Defaulted to true
- When a zone boots, it will spawn an invisible npc by the name of zone_controller - Lua and Perl scripts can be represented with this npc as zone_controller.pl/lua - This NPC's ID is ruled be define ZONE_CONTROLLER_NPC_ID 10 - Two EVENT's uniquely are handled with this NPC/controller (They only work with the zone_controller NPC) - EVENT_SPAWN_ZONE :: All NPC spawns in the zone trigger the controller and pass the following variables: $spawned_entity_id $spawned_npc_id - EVENT_DEATH_ZONE :: All NPC deaths in the zone trigger the controller event and pass the following variables: $killer_id $killer_damage $killer_spell $killer_skill $killed_npc_id
This commit is contained in:
parent
f25246e1a0
commit
8425607460
@ -1,5 +1,21 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 12/29/2015 ==
|
||||||
|
Akkadius: Implemented standardized zone controller scripts (Rule Zone, UseZoneController) Defaulted to true
|
||||||
|
- When a zone boots, it will spawn an invisible npc by the name of zone_controller
|
||||||
|
- Lua and Perl scripts can be represented with this npc as zone_controller.pl/lua
|
||||||
|
- This NPC's ID is ruled be define ZONE_CONTROLLER_NPC_ID 10
|
||||||
|
- Two EVENT's uniquely are handled with this NPC/controller (They only work with the zone_controller NPC)
|
||||||
|
- EVENT_SPAWN_ZONE :: All NPC spawns in the zone trigger the controller and pass the following variables:
|
||||||
|
$spawned_entity_id
|
||||||
|
$spawned_npc_id
|
||||||
|
- EVENT_DEATH_ZONE :: All NPC deaths in the zone trigger the controller event and pass the following variables:
|
||||||
|
$killer_id
|
||||||
|
$killer_damage
|
||||||
|
$killer_spell
|
||||||
|
$killer_skill
|
||||||
|
$killed_npc_id
|
||||||
|
|
||||||
== 12/28/2015 ==
|
== 12/28/2015 ==
|
||||||
Kinglykrab: Added GetInstanceTimer() to Perl and Lua.
|
Kinglykrab: Added GetInstanceTimer() to Perl and Lua.
|
||||||
- Added GetInstanceTimerByID(instance_id) to Perl and Lua.
|
- Added GetInstanceTimerByID(instance_id) to Perl and Lua.
|
||||||
|
|||||||
@ -233,6 +233,8 @@ enum { //some random constants
|
|||||||
#define GROUP_EXP_PER_POINT 1000
|
#define GROUP_EXP_PER_POINT 1000
|
||||||
#define RAID_EXP_PER_POINT 2000
|
#define RAID_EXP_PER_POINT 2000
|
||||||
|
|
||||||
|
#define ZONE_CONTROLLER_NPC_ID 10
|
||||||
|
|
||||||
//Some hard coded statuses from commands and other places:
|
//Some hard coded statuses from commands and other places:
|
||||||
enum {
|
enum {
|
||||||
minStatusToBeGM = 40,
|
minStatusToBeGM = 40,
|
||||||
|
|||||||
@ -233,6 +233,7 @@ RULE_BOOL(Zone, LevelBasedEXPMods, false) // Allows you to use the level_exp_mod
|
|||||||
RULE_INT(Zone, WeatherTimer, 600) // Weather timer when no duration is available
|
RULE_INT(Zone, WeatherTimer, 600) // Weather timer when no duration is available
|
||||||
RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
|
RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
|
||||||
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
||||||
|
RULE_BOOL(Zone, UseZoneController, true) // Enables the ability to use persistent quest based zone controllers (zone_controller.pl/lua)
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Map)
|
RULE_CATEGORY(Map)
|
||||||
|
|||||||
@ -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 9093
|
#define CURRENT_BINARY_DATABASE_VERSION 9094
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -347,6 +347,7 @@
|
|||||||
9091|2015_12_07_command_settings.sql|SHOW TABLES LIKE 'command_settings'|empty|
|
9091|2015_12_07_command_settings.sql|SHOW TABLES LIKE 'command_settings'|empty|
|
||||||
9092|2015_12_17_eqtime.sql|SHOW TABLES LIKE 'eqtime'|empty|
|
9092|2015_12_17_eqtime.sql|SHOW TABLES LIKE 'eqtime'|empty|
|
||||||
9093|2015_12_21_items_updates_evoitem.sql|SHOW COLUMNS FROM `items` LIKE 'evoitem'|empty|
|
9093|2015_12_21_items_updates_evoitem.sql|SHOW COLUMNS FROM `items` LIKE 'evoitem'|empty|
|
||||||
|
9094|2015_12_29_quest_zone_events.sql|SELECT * FROM perl_event_export_settings WHERE event_description = 'EVENT_SPAWN_ZONE'|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/2015_12_29_quest_zone_events.sql
Normal file
4
utils/sql/git/required/2015_12_29_quest_zone_events.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
INSERT INTO `perl_event_export_settings` (`event_id`, `event_description`, `export_qglobals`, `export_mob`, `export_zone`, `export_item`, `export_event`) VALUES (81, 'EVENT_SPAWN_ZONE', 0, 0, 0, 0, 1);
|
||||||
|
INSERT INTO `perl_event_export_settings` (`event_id`, `event_description`, `export_qglobals`, `export_mob`, `export_zone`, `export_item`, `export_event`) VALUES (82, 'EVENT_DEATH_ZONE', 0, 0, 0, 0, 1);
|
||||||
|
ALTER TABLE `rule_values`
|
||||||
|
MODIFY COLUMN `notes` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL AFTER `rule_value`;
|
||||||
@ -2009,15 +2009,15 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes attack
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack_skill) {
|
bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attack_skill) {
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob->GetName(), damage, spell, attack_skill);
|
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killer_mob->GetName(), damage, spell, attack_skill);
|
||||||
|
|
||||||
Mob *oos = nullptr;
|
Mob *oos = nullptr;
|
||||||
if(killerMob) {
|
if(killer_mob) {
|
||||||
oos = killerMob->GetOwnerOrSelf();
|
oos = killer_mob->GetOwnerOrSelf();
|
||||||
|
|
||||||
char buffer[48] = { 0 };
|
char buffer[48] = { 0 };
|
||||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||||
if(parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0)
|
if(parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0)
|
||||||
{
|
{
|
||||||
if(GetHP() < 0) {
|
if(GetHP() < 0) {
|
||||||
@ -2026,15 +2026,15 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(killerMob && killerMob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) {
|
if(killer_mob && killer_mob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) {
|
||||||
char val1[20]={0};
|
char val1[20]={0};
|
||||||
entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE,
|
entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE,
|
||||||
killerMob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1));
|
killer_mob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
char buffer[48] = { 0 };
|
char buffer[48] = { 0 };
|
||||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||||
if(parse->EventNPC(EVENT_DEATH, this, nullptr, buffer, 0) != 0)
|
if(parse->EventNPC(EVENT_DEATH, this, nullptr, buffer, 0) != 0)
|
||||||
{
|
{
|
||||||
if(GetHP() < 0) {
|
if(GetHP() < 0) {
|
||||||
@ -2072,21 +2072,21 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
EQApplicationPacket* app= new EQApplicationPacket(OP_Death,sizeof(Death_Struct));
|
EQApplicationPacket* app= new EQApplicationPacket(OP_Death,sizeof(Death_Struct));
|
||||||
Death_Struct* d = (Death_Struct*)app->pBuffer;
|
Death_Struct* d = (Death_Struct*)app->pBuffer;
|
||||||
d->spawn_id = GetID();
|
d->spawn_id = GetID();
|
||||||
d->killer_id = killerMob ? killerMob->GetID() : 0;
|
d->killer_id = killer_mob ? killer_mob->GetID() : 0;
|
||||||
d->bindzoneid = 0;
|
d->bindzoneid = 0;
|
||||||
d->spell_id = spell == SPELL_UNKNOWN ? 0xffffffff : spell;
|
d->spell_id = spell == SPELL_UNKNOWN ? 0xffffffff : spell;
|
||||||
d->attack_skill = SkillDamageTypes[attack_skill];
|
d->attack_skill = SkillDamageTypes[attack_skill];
|
||||||
d->damage = damage;
|
d->damage = damage;
|
||||||
app->priority = 6;
|
app->priority = 6;
|
||||||
entity_list.QueueClients(killerMob, app, false);
|
entity_list.QueueClients(killer_mob, app, false);
|
||||||
|
|
||||||
if(respawn2) {
|
if(respawn2) {
|
||||||
respawn2->DeathReset(1);
|
respawn2->DeathReset(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killerMob) {
|
if (killer_mob) {
|
||||||
if(GetClass() != LDON_TREASURE)
|
if(GetClass() != LDON_TREASURE)
|
||||||
hate_list.AddEntToHateList(killerMob, damage);
|
hate_list.AddEntToHateList(killer_mob, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete(app);
|
safe_delete(app);
|
||||||
@ -2148,8 +2148,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
{
|
{
|
||||||
if(!IsLdonTreasure && MerchantType == 0) {
|
if(!IsLdonTreasure && MerchantType == 0) {
|
||||||
kr->SplitExp((finalxp), this);
|
kr->SplitExp((finalxp), this);
|
||||||
if(killerMob && (kr->IsRaidMember(killerMob->GetName()) || kr->IsRaidMember(killerMob->GetUltimateOwner()->GetName())))
|
if(killer_mob && (kr->IsRaidMember(killer_mob->GetName()) || kr->IsRaidMember(killer_mob->GetUltimateOwner()->GetName())))
|
||||||
killerMob->TrySpellOnKill(killed_level,spell);
|
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||||
}
|
}
|
||||||
/* Send the EVENT_KILLED_MERIT event for all raid members */
|
/* Send the EVENT_KILLED_MERIT event for all raid members */
|
||||||
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
|
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
|
||||||
@ -2193,8 +2193,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
{
|
{
|
||||||
if(!IsLdonTreasure && MerchantType == 0) {
|
if(!IsLdonTreasure && MerchantType == 0) {
|
||||||
kg->SplitExp((finalxp), this);
|
kg->SplitExp((finalxp), this);
|
||||||
if(killerMob && (kg->IsGroupMember(killerMob->GetName()) || kg->IsGroupMember(killerMob->GetUltimateOwner()->GetName())))
|
if(killer_mob && (kg->IsGroupMember(killer_mob->GetName()) || kg->IsGroupMember(killer_mob->GetUltimateOwner()->GetName())))
|
||||||
killerMob->TrySpellOnKill(killed_level,spell);
|
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||||
}
|
}
|
||||||
/* Send the EVENT_KILLED_MERIT event and update kill tasks
|
/* Send the EVENT_KILLED_MERIT event and update kill tasks
|
||||||
* for all group members */
|
* for all group members */
|
||||||
@ -2244,8 +2244,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
if(!GetOwner() || (GetOwner() && !GetOwner()->IsClient()))
|
if(!GetOwner() || (GetOwner() && !GetOwner()->IsClient()))
|
||||||
{
|
{
|
||||||
give_exp_client->AddEXP((finalxp), conlevel);
|
give_exp_client->AddEXP((finalxp), conlevel);
|
||||||
if(killerMob && (killerMob->GetID() == give_exp_client->GetID() || killerMob->GetUltimateOwner()->GetID() == give_exp_client->GetID()))
|
if(killer_mob && (killer_mob->GetID() == give_exp_client->GetID() || killer_mob->GetUltimateOwner()->GetID() == give_exp_client->GetID()))
|
||||||
killerMob->TrySpellOnKill(killed_level,spell);
|
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2393,20 +2393,30 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
uint16 emoteid = oos->GetEmoteID();
|
uint16 emoteid = oos->GetEmoteID();
|
||||||
if(emoteid != 0)
|
if(emoteid != 0)
|
||||||
oos->CastToNPC()->DoNPCEmote(KILLEDNPC, emoteid);
|
oos->CastToNPC()->DoNPCEmote(KILLEDNPC, emoteid);
|
||||||
killerMob->TrySpellOnKill(killed_level, spell);
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WipeHateList();
|
WipeHateList();
|
||||||
p_depop = true;
|
p_depop = true;
|
||||||
if(killerMob && killerMob->GetTarget() == this) //we can kill things without having them targeted
|
if(killer_mob && killer_mob->GetTarget() == this) //we can kill things without having them targeted
|
||||||
killerMob->SetTarget(nullptr); //via AE effects and such..
|
killer_mob->SetTarget(nullptr); //via AE effects and such..
|
||||||
|
|
||||||
entity_list.UpdateFindableNPCState(this, true);
|
entity_list.UpdateFindableNPCState(this, true);
|
||||||
|
|
||||||
char buffer[48] = { 0 };
|
char buffer[48] = { 0 };
|
||||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, buffer, 0);
|
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, buffer, 0);
|
||||||
|
|
||||||
|
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
||||||
|
if (RuleB(Zone, UseZoneController)) {
|
||||||
|
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && this->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){
|
||||||
|
char data_pass[100] = { 0 };
|
||||||
|
snprintf(data_pass, 99, "%d %d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill), this->GetNPCTypeID());
|
||||||
|
parse->EventNPC(EVENT_DEATH_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -114,7 +114,9 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
|||||||
"EVENT_RESPAWN",
|
"EVENT_RESPAWN",
|
||||||
"EVENT_DEATH_COMPLETE",
|
"EVENT_DEATH_COMPLETE",
|
||||||
"EVENT_UNHANDLED_OPCODE",
|
"EVENT_UNHANDLED_OPCODE",
|
||||||
"EVENT_TICK"
|
"EVENT_TICK",
|
||||||
|
"EVENT_SPAWN_ZONE",
|
||||||
|
"EVENT_DEATH_ZONE",
|
||||||
};
|
};
|
||||||
|
|
||||||
PerlembParser::PerlembParser() : perl(nullptr) {
|
PerlembParser::PerlembParser() : perl(nullptr) {
|
||||||
@ -1424,6 +1426,21 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
|||||||
ExportVar(package_name.c_str(), "slotid", extradata);
|
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EVENT_SPAWN_ZONE: {
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "spawned_entity_id", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "spawned_npc_id", sep.arg[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EVENT_DEATH_ZONE: {
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "killer_id", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
|
||||||
|
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
|
||||||
|
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||||
|
ExportVar(package_name.c_str(), "killed_npc_id", sep.arg[4]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -641,8 +641,18 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
|||||||
{
|
{
|
||||||
npc->SetID(GetFreeID());
|
npc->SetID(GetFreeID());
|
||||||
npc->SetMerchantProbability((uint8) zone->random.Int(0, 99));
|
npc->SetMerchantProbability((uint8) zone->random.Int(0, 99));
|
||||||
|
|
||||||
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
||||||
|
|
||||||
|
/* Zone controller process EVENT_SPAWN_ZONE */
|
||||||
|
if (RuleB(Zone, UseZoneController)) {
|
||||||
|
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){
|
||||||
|
char data_pass[100] = { 0 };
|
||||||
|
snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID());
|
||||||
|
parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint16 emoteid = npc->GetEmoteID();
|
uint16 emoteid = npc->GetEmoteID();
|
||||||
if (emoteid != 0)
|
if (emoteid != 0)
|
||||||
npc->DoNPCEmote(ONSPAWN, emoteid);
|
npc->DoNPCEmote(ONSPAWN, emoteid);
|
||||||
|
|||||||
@ -83,7 +83,8 @@ typedef enum {
|
|||||||
EVENT_DEATH_COMPLETE,
|
EVENT_DEATH_COMPLETE,
|
||||||
EVENT_UNHANDLED_OPCODE,
|
EVENT_UNHANDLED_OPCODE,
|
||||||
EVENT_TICK,
|
EVENT_TICK,
|
||||||
|
EVENT_SPAWN_ZONE,
|
||||||
|
EVENT_DEATH_ZONE,
|
||||||
_LargestEventID
|
_LargestEventID
|
||||||
} QuestEventID;
|
} QuestEventID;
|
||||||
|
|
||||||
|
|||||||
@ -1731,7 +1731,9 @@ luabind::scope lua_register_events() {
|
|||||||
luabind::value("leave_area", static_cast<int>(EVENT_LEAVE_AREA)),
|
luabind::value("leave_area", static_cast<int>(EVENT_LEAVE_AREA)),
|
||||||
luabind::value("death_complete", static_cast<int>(EVENT_DEATH_COMPLETE)),
|
luabind::value("death_complete", static_cast<int>(EVENT_DEATH_COMPLETE)),
|
||||||
luabind::value("unhandled_opcode", static_cast<int>(EVENT_UNHANDLED_OPCODE)),
|
luabind::value("unhandled_opcode", static_cast<int>(EVENT_UNHANDLED_OPCODE)),
|
||||||
luabind::value("tick", static_cast<int>(EVENT_TICK))
|
luabind::value("tick", static_cast<int>(EVENT_TICK)),
|
||||||
|
luabind::value("spawn_zone", static_cast<int>(EVENT_SPAWN_ZONE)),
|
||||||
|
luabind::value("death_zone", static_cast<int>(EVENT_DEATH_ZONE))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -117,7 +117,9 @@ const char *LuaEvents[_LargestEventID] = {
|
|||||||
"event_respawn",
|
"event_respawn",
|
||||||
"event_death_complete",
|
"event_death_complete",
|
||||||
"event_unhandled_opcode",
|
"event_unhandled_opcode",
|
||||||
"event_tick"
|
"event_tick",
|
||||||
|
"event_spawn_zone",
|
||||||
|
"event_death_zone"
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Zone *zone;
|
extern Zone *zone;
|
||||||
|
|||||||
11
zone/npc.cpp
11
zone/npc.cpp
@ -845,18 +845,22 @@ bool NPC::DatabaseCastAccepted(int spell_id) {
|
|||||||
|
|
||||||
bool NPC::SpawnZoneController(){
|
bool NPC::SpawnZoneController(){
|
||||||
|
|
||||||
|
if (!RuleB(Zone, UseZoneController))
|
||||||
|
return false;
|
||||||
|
|
||||||
NPCType* npc_type = new NPCType;
|
NPCType* npc_type = new NPCType;
|
||||||
memset(npc_type, 0, sizeof(NPCType));
|
memset(npc_type, 0, sizeof(NPCType));
|
||||||
|
|
||||||
strncpy(npc_type->name, "zone_controller", 60);
|
strncpy(npc_type->name, "zone_controller", 60);
|
||||||
npc_type->cur_hp = 2000000000;
|
npc_type->cur_hp = 2000000000;
|
||||||
npc_type->max_hp = 2000000000;
|
npc_type->max_hp = 2000000000;
|
||||||
|
npc_type->hp_regen = 100000000;
|
||||||
npc_type->race = 240;
|
npc_type->race = 240;
|
||||||
npc_type->gender = 0;
|
npc_type->gender = 2;
|
||||||
npc_type->class_ = 1;
|
npc_type->class_ = 1;
|
||||||
npc_type->deity = 1;
|
npc_type->deity = 1;
|
||||||
npc_type->level = 200;
|
npc_type->level = 200;
|
||||||
npc_type->npc_id = 0;
|
npc_type->npc_id = ZONE_CONTROLLER_NPC_ID;
|
||||||
npc_type->loottable_id = 0;
|
npc_type->loottable_id = 0;
|
||||||
npc_type->texture = 3;
|
npc_type->texture = 3;
|
||||||
npc_type->runspeed = 0;
|
npc_type->runspeed = 0;
|
||||||
@ -868,6 +872,9 @@ bool NPC::SpawnZoneController(){
|
|||||||
npc_type->prim_melee_type = 28;
|
npc_type->prim_melee_type = 28;
|
||||||
npc_type->sec_melee_type = 28;
|
npc_type->sec_melee_type = 28;
|
||||||
|
|
||||||
|
npc_type->findable = 0;
|
||||||
|
npc_type->trackable = 0;
|
||||||
|
|
||||||
strcpy(npc_type->special_abilities, "12,1^13,1^14,1^15,1^16,1^17,1^19,1^22,1^24,1^25,1^28,1^31,1^35,1^39,1^42,1");
|
strcpy(npc_type->special_abilities, "12,1^13,1^14,1^15,1^16,1^17,1^19,1^22,1^24,1^25,1^28,1^31,1^35,1^39,1^42,1");
|
||||||
|
|
||||||
glm::vec4 point;
|
glm::vec4 point;
|
||||||
|
|||||||
@ -484,10 +484,17 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
|
|||||||
|
|
||||||
//second look for /quests/zone/npcname.ext (precedence)
|
//second look for /quests/zone/npcname.ext (precedence)
|
||||||
const NPCType *npc_type = database.LoadNPCTypesData(npcid);
|
const NPCType *npc_type = database.LoadNPCTypesData(npcid);
|
||||||
if(!npc_type) {
|
if (!npc_type && npcid != ZONE_CONTROLLER_NPC_ID) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::string npc_name = npc_type->name;
|
|
||||||
|
std::string npc_name;
|
||||||
|
if (npcid == ZONE_CONTROLLER_NPC_ID){
|
||||||
|
npc_name = "zone_controller";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
npc_name = npc_type->name;
|
||||||
|
}
|
||||||
int sz = static_cast<int>(npc_name.length());
|
int sz = static_cast<int>(npc_name.length());
|
||||||
for(int i = 0; i < sz; ++i) {
|
for(int i = 0; i < sz; ++i) {
|
||||||
if(npc_name[i] == '`') {
|
if(npc_name[i] == '`') {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user