mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
Add EVENT_TICK for NPCs
This event fires at the start of the tick processing so we can script on the actual tick.
This commit is contained in:
parent
1fc23beb78
commit
fe0758c984
@ -113,7 +113,8 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_LEAVE_AREA",
|
||||
"EVENT_RESPAWN",
|
||||
"EVENT_DEATH_COMPLETE",
|
||||
"EVENT_UNHANDLED_OPCODE"
|
||||
"EVENT_UNHANDLED_OPCODE",
|
||||
"EVENT_TICK"
|
||||
};
|
||||
|
||||
PerlembParser::PerlembParser() : perl(nullptr) {
|
||||
@ -154,7 +155,7 @@ void PerlembParser::ReloadQuests() {
|
||||
spell_quest_status_.clear();
|
||||
}
|
||||
|
||||
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
||||
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
||||
uint32 extradata, bool global, std::vector<EQEmu::Any> *extra_pointers)
|
||||
{
|
||||
if(!perl)
|
||||
@ -186,7 +187,7 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
|
||||
package_name, npcmob, mob, char_id);
|
||||
|
||||
//ExportGenericVariables();
|
||||
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
package_name, mob, npcmob);
|
||||
ExportZoneVariables(package_name);
|
||||
ExportItemVariables(package_name, mob);
|
||||
@ -459,15 +460,15 @@ void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) {
|
||||
|
||||
std::stringstream package_name;
|
||||
package_name << "qst_item_" << item->GetID();
|
||||
|
||||
|
||||
if(!perl)
|
||||
return;
|
||||
|
||||
|
||||
auto iter = item_quest_status_.find(item->GetID());
|
||||
if(iter != item_quest_status_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
perl->eval_file(package_name.str().c_str(), filename.c_str());
|
||||
}
|
||||
@ -480,7 +481,7 @@ void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) {
|
||||
item_quest_status_[item->GetID()] = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
item_quest_status_[item->GetID()] = questLoaded;
|
||||
}
|
||||
|
||||
@ -821,10 +822,10 @@ void PerlembParser::MapFunctions() {
|
||||
);
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
bool &isSpellQuest, QuestEventID event, NPC* npcmob, ItemInst* iteminst, Mob* mob, bool global)
|
||||
{
|
||||
if(event == EVENT_SPELL_EFFECT_CLIENT ||
|
||||
if(event == EVENT_SPELL_EFFECT_CLIENT ||
|
||||
event == EVENT_SPELL_EFFECT_NPC ||
|
||||
event == EVENT_SPELL_BUFF_TIC_CLIENT ||
|
||||
event == EVENT_SPELL_BUFF_TIC_NPC ||
|
||||
@ -843,14 +844,14 @@ void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest
|
||||
isPlayerQuest = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
isItemQuest = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
bool &isSpellQuest, std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
bool &isSpellQuest, std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
NPC* npcmob, ItemInst* iteminst, bool global)
|
||||
{
|
||||
if(!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest) {
|
||||
@ -897,7 +898,7 @@ void PerlembParser::ExportCharID(const std::string &package_name, int &char_id,
|
||||
ExportVar(package_name.c_str(), "charid", char_id);
|
||||
}
|
||||
|
||||
void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, NPC *npcmob, Mob *mob, int char_id) {
|
||||
//NPC quest
|
||||
if(!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest)
|
||||
@ -953,7 +954,7 @@ void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest,
|
||||
{
|
||||
QGlobalCache::Combine(globalMap, zone_c->GetBucket(), npcmob->GetNPCTypeID(), char_id, zone->GetZoneID());
|
||||
}
|
||||
|
||||
|
||||
std::list<QGlobal>::iterator iter = globalMap.begin();
|
||||
while(iter != globalMap.end())
|
||||
{
|
||||
@ -1013,8 +1014,8 @@ void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest,
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, Mob *mob, NPC *npcmob)
|
||||
void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, Mob *mob, NPC *npcmob)
|
||||
{
|
||||
uint8 fac = 0;
|
||||
if (mob && mob->IsClient()) {
|
||||
@ -1027,7 +1028,7 @@ void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQu
|
||||
if (mob && npcmob && mob->IsClient()) {
|
||||
Client* client = mob->CastToClient();
|
||||
|
||||
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetRace(),
|
||||
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetRace(),
|
||||
client->GetClass(), client->GetDeity(), npcmob->GetPrimaryFaction(), npcmob);
|
||||
}
|
||||
}
|
||||
@ -1122,8 +1123,8 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) {
|
||||
#undef HASITEM_LAST
|
||||
#undef HASITEM_ISNULLITEM
|
||||
|
||||
void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers)
|
||||
void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers)
|
||||
{
|
||||
switch (event) {
|
||||
case EVENT_SAY: {
|
||||
@ -1240,7 +1241,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
ExportVar(package_name.c_str(), "target_zone_id", data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EVENT_CAST_ON:
|
||||
case EVENT_CAST:
|
||||
case EVENT_CAST_BEGIN: {
|
||||
@ -1278,7 +1279,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
case EVENT_PLAYER_PICKUP:{
|
||||
ExportVar(package_name.c_str(), "picked_up_id", data);
|
||||
ExportVar(package_name.c_str(), "picked_up_entity_id", extradata);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_AGGRO_SAY: {
|
||||
@ -1359,12 +1360,12 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
|
||||
case EVENT_FORAGE_SUCCESS: {
|
||||
ExportVar(package_name.c_str(), "foraged_item", extradata);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_FISH_SUCCESS: {
|
||||
ExportVar(package_name.c_str(), "fished_item", extradata);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_CLICK_OBJECT: {
|
||||
|
||||
@ -82,6 +82,7 @@ typedef enum {
|
||||
EVENT_RESPAWN,
|
||||
EVENT_DEATH_COMPLETE,
|
||||
EVENT_UNHANDLED_OPCODE,
|
||||
EVENT_TICK,
|
||||
|
||||
_LargestEventID
|
||||
} QuestEventID;
|
||||
|
||||
@ -1713,7 +1713,8 @@ luabind::scope lua_register_events() {
|
||||
luabind::value("enter_area", static_cast<int>(EVENT_ENTER_AREA)),
|
||||
luabind::value("leave_area", static_cast<int>(EVENT_LEAVE_AREA)),
|
||||
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))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -116,7 +116,8 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_leave_area",
|
||||
"event_respawn",
|
||||
"event_death_complete",
|
||||
"event_unhandled_opcode"
|
||||
"event_unhandled_opcode",
|
||||
"event_tick"
|
||||
};
|
||||
|
||||
extern Zone *zone;
|
||||
@ -281,7 +282,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
||||
lua_getfield(L, -1, sub_name);
|
||||
npop = 2;
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
//always push self
|
||||
Lua_NPC l_npc(npc);
|
||||
@ -292,7 +293,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
||||
auto arg_function = NPCArgumentDispatch[evt];
|
||||
arg_function(this, L, npc, init, data, extra_data, extra_pointers);
|
||||
Client *c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
|
||||
|
||||
|
||||
quest_manager.StartQuest(npc, c, nullptr);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@ -301,13 +302,13 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@ -375,17 +376,17 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
|
||||
lua_getfield(L, -1, sub_name);
|
||||
npop = 2;
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
//push self
|
||||
Lua_Client l_client(client);
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "self");
|
||||
|
||||
|
||||
auto arg_function = PlayerArgumentDispatch[evt];
|
||||
arg_function(this, L, client, data, extra_data, extra_pointers);
|
||||
|
||||
|
||||
quest_manager.StartQuest(client, client, nullptr);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@ -394,13 +395,13 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@ -424,15 +425,15 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *
|
||||
if(evt >= _LargestEventID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!item) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!ItemHasQuestSub(item, evt)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(item->GetID());
|
||||
return _EventItem(package_name, evt, client, item, mob, data, extra_data, extra_pointers);
|
||||
@ -452,7 +453,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
|
||||
lua_getfield(L, -1, sub_name);
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
//always push self
|
||||
Lua_ItemInst l_item(item);
|
||||
@ -468,7 +469,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
||||
//redo this arg function
|
||||
auto arg_function = ItemArgumentDispatch[evt];
|
||||
arg_function(this, L, client, item, mob, data, extra_data, extra_pointers);
|
||||
|
||||
|
||||
quest_manager.StartQuest(client, client, item);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@ -477,13 +478,13 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@ -520,7 +521,7 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe
|
||||
int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) {
|
||||
const char *sub_name = LuaEvents[evt];
|
||||
|
||||
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
@ -532,7 +533,7 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
||||
lua_getfield(L, -1, sub_name);
|
||||
npop = 2;
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
|
||||
//always push self even if invalid
|
||||
@ -546,10 +547,10 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
||||
l_spell_o.push(L);
|
||||
}
|
||||
lua_setfield(L, -2, "self");
|
||||
|
||||
|
||||
auto arg_function = SpellArgumentDispatch[evt];
|
||||
arg_function(this, L, npc, client, spell_id, extra_data, extra_pointers);
|
||||
|
||||
|
||||
quest_manager.StartQuest(npc, client, nullptr);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@ -558,13 +559,13 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@ -593,20 +594,20 @@ int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, std:
|
||||
if(!EncounterHasQuestSub(encounter_name, evt)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return _EventEncounter(package_name, evt, encounter_name, data, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
const char *sub_name = LuaEvents[evt];
|
||||
|
||||
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
|
||||
lua_getfield(L, -1, sub_name);
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
lua_pushstring(L, encounter_name.c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
@ -624,13 +625,13 @@ int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, 2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, 2);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@ -864,13 +865,13 @@ void LuaParser::ReloadQuests() {
|
||||
FILE *f = fopen(path.c_str(), "r");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
|
||||
|
||||
if(luaL_dofile(L, path.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//zone init - always loads after global
|
||||
if(zone) {
|
||||
std::string zone_script = "quests/";
|
||||
@ -881,7 +882,7 @@ void LuaParser::ReloadQuests() {
|
||||
f = fopen(zone_script.c_str(), "r");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
|
||||
|
||||
if(luaL_dofile(L, zone_script.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -910,7 +911,7 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
|
||||
if(iter != loaded_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(luaL_loadfile(L, filename.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -1008,7 +1009,7 @@ void LuaParser::MapFunctions(lua_State *L) {
|
||||
lua_register_packet(),
|
||||
lua_register_packet_opcodes()
|
||||
];
|
||||
|
||||
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = ex.what();
|
||||
AddError(error);
|
||||
@ -1122,7 +1123,7 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *ite
|
||||
if(iter == lua_encounter_events_registered.end()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
auto riter = iter->second.begin();
|
||||
while(riter != iter->second.end()) {
|
||||
if(riter->event_id == evt) {
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#include "string_ids.h"
|
||||
#include "spawn2.h"
|
||||
#include "zone.h"
|
||||
#include "quest_parser_collection.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <stdio.h>
|
||||
@ -601,6 +602,7 @@ bool NPC::Process()
|
||||
|
||||
if(tic_timer.Check())
|
||||
{
|
||||
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
|
||||
BuffProcess();
|
||||
|
||||
if(curfp)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user