Some quest item and spell work, took out that stupid multiquesting code -> use your brains that's completely doable entirely in quests even perl

This commit is contained in:
KimLS 2013-05-17 17:10:38 -07:00
parent bec6acc01e
commit 7adcf6d3e5
26 changed files with 416 additions and 483 deletions

View File

@ -58,7 +58,7 @@ RDTSC_Timer::RDTSC_Timer(bool start_it) {
}
int64 RDTSC_Timer::rdtsc() {
int64 res;
int64 res = 0;
#ifdef USE_RDTSC
#ifndef WIN64
#ifdef WIN32

View File

@ -385,7 +385,6 @@ RULE_BOOL ( NPC, SmartLastFightingDelayMoving, true)
RULE_BOOL ( NPC, ReturnNonQuestNoDropItems, false) // Returns NO DROP items on NPCs that don't have an EVENT_TRADE sub in their script
RULE_INT ( NPC, StartEnrageValue, 9) // % HP that an NPC will begin to enrage
RULE_BOOL ( NPC, LiveLikeEnrage, false) // If set to true then only player controlled pets will enrage
RULE_BOOL (NPC, UseMultiQuest, false) // If true, NPC will remember items handed to them for classic multiquest support.
RULE_CATEGORY_END()
RULE_CATEGORY ( Aggro )

View File

@ -33,7 +33,9 @@ SET(zone_sources
loottables.cpp
lua_client.cpp
lua_entity.cpp
lua_hate_entry.cpp
lua_item.cpp
lua_iteminst.cpp
lua_mob.cpp
lua_npc.cpp
lua_parser.cpp
@ -133,6 +135,7 @@ SET(zone_headers
lua_client.h
lua_entity.h
lua_item.h
lua_iteminst.h
lua_mob.h
lua_npc.h
lua_parser.h

View File

@ -432,7 +432,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
iter++;
}
//third look for /quests/templates/npcid.ext (precedence)
//third look for /quests/global/npcid.ext (precedence)
filename = "quests/";
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
@ -453,7 +453,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
iter++;
}
//fourth look for /quests/templates/npcname.ext (precedence)
//fourth look for /quests/global/npcname.ext (precedence)
filename = "quests/";
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
@ -495,7 +495,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
iter++;
}
//last look for /quests/templates/default.ext (precedence)
//last look for /quests/global/default.ext (precedence)
filename = "quests/";
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
@ -571,7 +571,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
iter++;
}
//third look for /quests/templates/player.ext (precedence)
//third look for /quests/global/player.ext (precedence)
filename = "quests/";
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
@ -596,7 +596,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
}
QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filename) {
// simply look for templates/global_npc.pl
// simply look for quests/global/global_npc.pl
filename = "quests/";
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
@ -624,7 +624,7 @@ QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filena
}
QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &filename) {
//first look for /quests/templates/player.ext (precedence)
//first look for /quests/global/player.ext (precedence)
filename = "quests/";
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
@ -652,8 +652,10 @@ QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &fil
}
QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::string &filename) {
//first look for /quests/spells/spell_id.ext (precedence)
filename = "quests/spells/";
//first look for /quests/zone/spells/spell_id.ext (precedence)
filename = "quests/";
filename += zone->GetShortName();
filename += "/spells/";
filename += itoa(spell_id);
std::string tmp;
FILE *f = nullptr;
@ -674,12 +676,34 @@ QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
iter++;
}
//second look for /quests/spells/spell_id.ext (precedence)
filename = "quests/spells/";
filename += itoa(spell_id);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
std::map<uint32, std::string>::iterator ext = _extensions.find((*iter)->GetIdentifier());
tmp += ".";
tmp += ext->second;
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
iter++;
}
return nullptr;
}
QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string &filename) {
//first look for /quests/items/item_script.ext (precedence)
filename = "quests/items/";
//first look for /quests/zone/items/item_script.ext (precedence)
filename = "quests/";
filename += zone->GetShortName();
filename += "/items/";
filename += item_script;
std::string tmp;
FILE *f = nullptr;
@ -700,5 +724,25 @@ QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script,
iter++;
}
//second look for /quests/items/item_script.ext (precedence)
filename = "quests/items/";
filename += item_script;
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
std::map<uint32, std::string>::iterator ext = _extensions.find((*iter)->GetIdentifier());
tmp += ".";
tmp += ext->second;
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
iter++;
}
return nullptr;
}

View File

@ -1097,7 +1097,6 @@ public:
const char* GetClassPlural(Client* client);
void SendWebLink(const char* website);
bool StoreTurnInItems(Mob* with);
void DuplicateLoreMessage(uint32 ItemID);
void GarbleMessage(char *, uint8);

View File

@ -444,8 +444,6 @@ int command_init(void) {
command_add("picklock", "Analog for ldon pick lock for the newer clients since we still don't have it working.", 0, command_picklock) ||
command_add("mysql", "Mysql CLI, see 'help' for options.", 250, command_mysql) ||
command_add("xtargets", "Show your targets Extended Targets and optionally set how many xtargets they can have.", 250, command_xtargets) ||
command_add("printquestitems","Returns available quest items for multiquesting currently on the target npc.",200,command_printquestitems) ||
command_add("clearquestitems","Clears quest items for multiquesting currently on the target npc.",200,command_clearquestitems) ||
command_add("zopp", "Troubleshooting command - Sends a fake item packet to you. No server reference is created.", 250, command_zopp) ||
command_add("augmentitem", "Force augments an item. Must have the augment item window open.", 250, command_augmentitem)
)
@ -11374,35 +11372,6 @@ void command_xtargets(Client *c, const Seperator *sep)
t->ShowXTargets(c);
}
void command_printquestitems(Client *c, const Seperator *sep)
{
if (c->GetTarget() != 0)
{
if ( c->GetTarget()->IsNPC() )
c->GetTarget()->CastToNPC()->PrintOutQuestItems(c);
else
c->Message(13,"Pick a NPC target.");
}
else
c->Message(13,"Pick a NPC target.");
}
void command_clearquestitems(Client *c, const Seperator *sep)
{
if (c->GetTarget() != 0)
{
if ( c->GetTarget()->IsNPC() )
{
c->GetTarget()->CastToNPC()->ClearQuestLists();
c->Message(5,"Quest item list cleared.");
}
else
c->Message(13,"Pick a NPC target.");
}
else
c->Message(13,"Pick a NPC target.");
}
void command_zopp(Client *c, const Seperator *sep)
{ // - Owner only command..non-targetable to eliminate malicious or mischievious activities.
if (!c)

View File

@ -317,8 +317,6 @@ void command_picklock(Client *c, const Seperator *sep);
void command_qtest(Client *c, const Seperator *sep);
void command_mysql(Client *c, const Seperator *sep);
void command_xtargets(Client *c, const Seperator *sep);
void command_printquestitems(Client *c, const Seperator *sep);
void command_clearquestitems(Client *c, const Seperator *sep);
void command_zopp(Client *c, const Seperator *sep);
void command_augmentitem(Client *c, const Seperator *sep);

View File

@ -3253,58 +3253,6 @@ XS(XS__GetTimeSeconds)
XSRETURN_UV(seconds);
}
XS(XS__handleturnin); // prototype to pass -Wmissing-prototypes
XS(XS__handleturnin) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: handleturnin(itemid, itemcharges)");
int itemid = (int)SvIV(ST(0));
int charges = (int)SvIV(ST(1));
bool returnVal = quest_manager.TurnInItem(itemid,charges);
ST(0) = boolSV(returnVal);
sv_2mortal(ST(0));
XSRETURN(1);
}
XS(XS__completehandin); // prototype to pass -Wmissing-prototypes
XS(XS__completehandin) {
dXSARGS;
if (items != 0)
Perl_croak(aTHX_ "Usage: completehandin()");
quest_manager.CompleteHandIn();
XSRETURN_EMPTY;
}
XS(XS__resethandin); // prototype to pass -Wmissing-prototypes
XS(XS__resethandin) {
dXSARGS;
if (items != 0)
Perl_croak(aTHX_ "Usage: resethandin()");
quest_manager.ResetHandIn();
XSRETURN_EMPTY;
}
XS(XS__clearhandin); // prototype to pass -Wmissing-prototypes
XS(XS__clearhandin) {
dXSARGS;
if (items != 0)
Perl_croak(aTHX_ "Usage: clearhandin()");
quest_manager.ClearHandIn();
XSRETURN_EMPTY;
}
XS(XS__crosszonesignalclientbycharid);
XS(XS__crosszonesignalclientbycharid)
{
@ -3579,10 +3527,6 @@ EXTERN_C XS(boot_quest)
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
newXS(strcpy(buf, "handleturnin"), XS__handleturnin, file);
newXS(strcpy(buf, "completehandin"), XS__completehandin, file);
newXS(strcpy(buf, "resethandin"), XS__resethandin, file);
newXS(strcpy(buf, "clearhandin"), XS__clearhandin, file);
newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file);
newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file);
newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);

View File

@ -19,9 +19,8 @@
#ifndef HATELIST_H
#define HATELIST_H
class tHateEntry
struct tHateEntry
{
public:
Mob *ent;
int32 damage, hate;
bool bFrenzy;

View File

@ -28,7 +28,7 @@ struct Lua_HateList;
#define Lua_Safe_Call_Client() if(!d_) { return Lua_Client(); } NativeType *self = reinterpret_cast<NativeType*>(d_)
#define Lua_Safe_Call_HateList() if(!d_) { return Lua_HateList(); } NativeType *self = reinterpret_cast<NativeType*>(d_)
class Lua_Entity : public Lua_Ptr
class Lua_Entity : public Lua_Ptr<void>
{
typedef Entity NativeType;
public:

48
zone/lua_hate_entry.cpp Normal file
View File

@ -0,0 +1,48 @@
#ifdef LUA_EQEMU
#include "masterentity.h"
#include "hate_list.h"
#include "lua_mob.h"
#include "lua_hate_entry.h"
Lua_Mob Lua_HateEntry::GetEnt() {
Lua_Safe_Call_Mob();
return Lua_Mob(self->ent);
}
void Lua_HateEntry::SetEnt(Lua_Mob e) {
Lua_Safe_Call_Void();
self->ent = e;
}
int Lua_HateEntry::GetDamage() {
Lua_Safe_Call_Int();
return self->damage;
}
void Lua_HateEntry::SetDamage(int value) {
Lua_Safe_Call_Void();
self->damage = value;
}
int Lua_HateEntry::GetHate() {
Lua_Safe_Call_Int();
return self->hate;
}
void Lua_HateEntry::SetHate(int value) {
Lua_Safe_Call_Void();
self->hate = value;
}
int Lua_HateEntry::GetFrenzy() {
Lua_Safe_Call_Int();
return self->bFrenzy;
}
void Lua_HateEntry::SetFrenzy(bool value) {
Lua_Safe_Call_Void();
self->bFrenzy = value;
}
#endif

View File

@ -2,17 +2,27 @@
#define EQEMU_LUA_HATE_ENTRY_H
#ifdef LUA_EQEMU
class Lua_Mob;
#include "lua_ptr.h"
struct Lua_HateEntry
class Lua_Mob;
struct tHateEntry;
class Lua_HateEntry : public Lua_Ptr<void>
{
typedef tHateEntry NativeType;
public:
Lua_HateEntry() { }
Lua_HateEntry(tHateEntry *d) : Lua_Ptr(d) { }
virtual ~Lua_HateEntry() { }
Lua_Mob ent;
int damage;
int hate;
bool frenzy;
Lua_Mob GetEnt();
void SetEnt(Lua_Mob e);
int GetDamage();
void SetDamage(int value);
int GetHate();
void SetHate(int value);
int GetFrenzy();
void SetFrenzy(bool value);
};
#endif

View File

@ -4,20 +4,20 @@
#include "lua_ptr.h"
class ItemInst;
struct Item_Struct;
class Lua_Item : public Lua_Ptr
class Lua_Item : public Lua_Ptr<const void>
{
typedef ItemInst NativeType;
typedef Item_Struct NativeType;
public:
Lua_Item() { }
Lua_Item(ItemInst *d) : Lua_Ptr(d) { }
Lua_Item(const Item_Struct *d) : Lua_Ptr(d) { }
virtual ~Lua_Item() { }
operator ItemInst*() {
void *d = GetLuaPtrData();
operator const Item_Struct*() {
const void *d = GetLuaPtrData();
if(d) {
return reinterpret_cast<ItemInst*>(d);
return reinterpret_cast<const Item_Struct*>(d);
}
return nullptr;

6
zone/lua_iteminst.cpp Normal file
View File

@ -0,0 +1,6 @@
#ifdef LUA_EQEMU
#include "masterentity.h"
#include "lua_iteminst.h"
#endif

28
zone/lua_iteminst.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef EQEMU_LUA_ITEMINST_H
#define EQEMU_LUA_ITEMINST_H
#ifdef LUA_EQEMU
#include "lua_ptr.h"
class ItemInst;
class Lua_ItemInst : public Lua_Ptr<void>
{
typedef ItemInst NativeType;
public:
Lua_ItemInst() { }
Lua_ItemInst(ItemInst *d) : Lua_Ptr(d) { }
virtual ~Lua_ItemInst() { }
operator ItemInst*() {
void *d = GetLuaPtrData();
if(d) {
return reinterpret_cast<ItemInst*>(d);
}
return nullptr;
}
};
#endif
#endif

View File

@ -760,12 +760,7 @@ Lua_HateList Lua_Mob::GetHateList() {
auto h_list = self->GetHateList();
auto iter = h_list.begin();
while(iter != h_list.end()) {
tHateEntry *ent = (*iter);
Lua_HateEntry e;
e.ent = Lua_Mob(ent->ent);
e.damage = ent->damage;
e.hate = ent->hate;
e.frenzy = ent->bFrenzy;
Lua_HateEntry e(*iter);
ret.entries.push_back(e);
++iter;
}

View File

@ -19,6 +19,7 @@
#include "lua_client.h"
#include "lua_npc.h"
#include "lua_item.h"
#include "lua_iteminst.h"
#include "lua_spell.h"
#include "zone.h"
@ -259,95 +260,6 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
auto arg_function = PlayerArgumentDispatch[evt];
arg_function(this, L, client, data, extra_data);
/*switch(evt) {
case EVENT_DEATH: {
Seperator sep(data.c_str());
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_pushinteger(L, std::stoi(sep.arg[1]));
lua_pushinteger(L, std::stoi(sep.arg[2]));
lua_pushinteger(L, std::stoi(sep.arg[3]));
arg_count += 4;
break;
}
case EVENT_SAY: {
lua_pushstring(L, data.c_str());
lua_pushinteger(L, extra_data);
arg_count += 2;
break;
}
case EVENT_DISCOVER_ITEM:
case EVENT_FISH_SUCCESS:
case EVENT_FORAGE_SUCCESS: {
lua_pushinteger(L, extra_data);
arg_count += 1;
break;
}
case EVENT_CLICK_OBJECT:
case EVENT_CLICK_DOOR:
case EVENT_SIGNAL:
case EVENT_POPUP_RESPONSE:
case EVENT_PLAYER_PICKUP:
case EVENT_CAST:
case EVENT_TASK_FAIL:
case EVENT_ZONE: {
lua_pushinteger(L, std::stoi(data));
arg_count += 1;
break;
}
case EVENT_TIMER: {
lua_pushstring(L, data.c_str());
arg_count += 1;
break;
}
case EVENT_DUEL_WIN:
case EVENT_DUEL_LOSE: {
lua_pushstring(L, data.c_str());
lua_pushinteger(L, extra_data);
arg_count += 2;
break;
}
case EVENT_LOOT: {
Seperator sep(data.c_str());
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_pushinteger(L, std::stoi(sep.arg[1]));
lua_pushstring(L, sep.arg[2]);
arg_count += 3;
break;
}
case EVENT_TASK_STAGE_COMPLETE: {
Seperator sep(data.c_str());
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_pushinteger(L, std::stoi(sep.arg[1]));
arg_count += 2;
break;
}
case EVENT_TASK_COMPLETE: {
Seperator sep(data.c_str());
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_pushinteger(L, std::stoi(sep.arg[1]));
lua_pushinteger(L, std::stoi(sep.arg[2]));
arg_count += 3;
break;
}
}*/
if(lua_pcall(L, 1, 1, 0)) {
printf("Error: %s\n", lua_tostring(L, -1));
return 0;
@ -422,10 +334,10 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
lua_createtable(L, 0, 0);
//always push self
Lua_Item l_item(item);
Lua_ItemInst l_item(item);
luabind::object l_item_o = luabind::object(L, l_item);
l_item_o.push(L);
lua_setfield(L, -2, "item");
lua_setfield(L, -2, "self");
auto arg_function = ItemArgumentDispatch[evt];
arg_function(this, L, client, item, objid, extra_data);
@ -482,6 +394,12 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
lua_createtable(L, 0, 0);
//always push self
Lua_Spell l_spell(&spells[spell_id]);
luabind::object l_spell_o = luabind::object(L, l_spell);
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);
@ -631,11 +549,11 @@ void LuaParser::ReloadQuests() {
lua_pop(L, 1);
//load init
FILE *f = fopen("quests/templates/script_init.lua", "r");
FILE *f = fopen("quests/global/script_init.lua", "r");
if(f) {
fclose(f);
if(luaL_dofile(L, "quests/templates/script_init.lua")) {
if(luaL_dofile(L, "quests/global/script_init.lua")) {
printf("Lua Error in Global Init: %s\n", lua_tostring(L, -1));
lua_close(L);
return;
@ -673,6 +591,10 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
return;
}
//This makes an env table named: package_name
//And makes it so we can see the global table _G from it
//Then sets it so this script is called from that table as an env
lua_createtable(L, 0, 0); // anon table
lua_getglobal(L, "_G"); // get _G
lua_setfield(L, -2, "__index"); //anon table.__index = _G
@ -893,8 +815,7 @@ void LuaParser::MapFunctions(lua_State *L) {
.def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int,int,uint32,int))&Lua_Mob::SpellFinished)
.def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int,int,uint32,int,bool))&Lua_Mob::SpellFinished)
.def("SpellEffect", &Lua_Mob::SpellEffect)
.def("GetHateList", &Lua_Mob::GetHateList)
,
.def("GetHateList", &Lua_Mob::GetHateList),
luabind::class_<Lua_Client, Lua_Mob>("Client")
.def(luabind::constructor<>()),
@ -902,16 +823,28 @@ void LuaParser::MapFunctions(lua_State *L) {
luabind::class_<Lua_NPC, Lua_Mob>("NPC")
.def(luabind::constructor<>()),
luabind::class_<Lua_ItemInst>("ItemInst")
.def(luabind::constructor<>())
.property("null", &Lua_ItemInst::Null)
.property("valid", &Lua_ItemInst::Valid),
luabind::class_<Lua_Item>("Item")
.def(luabind::constructor<>())
.property("null", &Lua_Entity::Null)
.property("valid", &Lua_Entity::Valid),
.property("null", &Lua_Item::Null)
.property("valid", &Lua_Item::Valid),
luabind::class_<Lua_Spell>("Spell")
.def(luabind::constructor<>())
.property("null", &Lua_Spell::Null)
.property("valid", &Lua_Spell::Valid),
luabind::class_<Lua_HateEntry>("HateEntry")
.def_readwrite("ent", &Lua_HateEntry::ent)
.def_readwrite("damage", &Lua_HateEntry::damage)
.def_readwrite("hate", &Lua_HateEntry::hate)
.def_readwrite("frenzy", &Lua_HateEntry::frenzy),
.property("null", &Lua_HateEntry::Null)
.property("valid", &Lua_HateEntry::Valid)
.property("ent", &Lua_HateEntry::GetEnt, &Lua_HateEntry::SetEnt)
.property("damage", &Lua_HateEntry::GetDamage, &Lua_HateEntry::SetDamage)
.property("hate", &Lua_HateEntry::GetHate, &Lua_HateEntry::SetHate)
.property("frenzy", &Lua_HateEntry::GetFrenzy, &Lua_HateEntry::SetFrenzy),
luabind::class_<Lua_HateList>("HateList")
.def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator)

View File

@ -14,6 +14,8 @@
#include "lua_client.h"
#include "lua_npc.h"
#include "lua_item.h"
#include "lua_iteminst.h"
#include "lua_spell.h"
#include "zone.h"
#include "lua_parser_events.h"
@ -179,8 +181,18 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init,
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_setfield(L, -2, "damage");
lua_pushinteger(L, std::stoi(sep.arg[1]));
lua_setfield(L, -2, "spell_id");
int spell_id = std::stoi(sep.arg[1]);
if(IsValidSpell(spell_id)) {
Lua_Spell l_spell(&spells[spell_id]);
luabind::object l_spell_o = luabind::object(L, l_spell);
l_spell_o.push(L);
lua_setfield(L, -2, "spell");
} else {
Lua_Spell l_spell(nullptr);
luabind::object l_spell_o = luabind::object(L, l_spell);
l_spell_o.push(L);
lua_setfield(L, -2, "spell");
}
lua_pushinteger(L, std::stoi(sep.arg[2]));
lua_setfield(L, -2, "skill_id");
@ -189,7 +201,127 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init,
void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) {
}
/*switch(evt) {
case EVENT_FISH_SUCCESS:
case EVENT_FORAGE_SUCCESS: {
lua_pushinteger(L, extra_data);
arg_count += 1;
break;
}
case EVENT_CLICK_OBJECT:
case EVENT_CLICK_DOOR:
case EVENT_SIGNAL:
case EVENT_POPUP_RESPONSE:
case EVENT_PLAYER_PICKUP:
case EVENT_CAST:
case EVENT_TASK_FAIL:
case EVENT_ZONE: {
lua_pushinteger(L, std::stoi(data));
arg_count += 1;
break;
}
case EVENT_DUEL_WIN:
case EVENT_DUEL_LOSE: {
lua_pushstring(L, data.c_str());
lua_pushinteger(L, extra_data);
arg_count += 2;
break;
}
case EVENT_LOOT: {
Seperator sep(data.c_str());
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_pushinteger(L, std::stoi(sep.arg[1]));
lua_pushstring(L, sep.arg[2]);
arg_count += 3;
break;
}
case EVENT_TASK_STAGE_COMPLETE: {
Seperator sep(data.c_str());
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_pushinteger(L, std::stoi(sep.arg[1]));
arg_count += 2;
break;
}
case EVENT_TASK_COMPLETE: {
Seperator sep(data.c_str());
lua_pushinteger(L, std::stoi(sep.arg[0]));
lua_pushinteger(L, std::stoi(sep.arg[1]));
lua_pushinteger(L, std::stoi(sep.arg[2]));
arg_count += 3;
break;
}
}*/
//Player
void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) {
lua_pushstring(L, data.c_str());
lua_setfield(L, -2, "message");
lua_pushinteger(L, extra_data);
lua_setfield(L, -2, "language");
}
void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) {
Seperator sep(data.c_str());
Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0]));
Lua_Mob l_mob(o);
luabind::object l_mob_o = luabind::object(L, l_mob);
l_mob_o.push(L);
lua_setfield(L, -2, "other");
lua_pushinteger(L, std::stoi(sep.arg[1]));
lua_setfield(L, -2, "damage");
int spell_id = std::stoi(sep.arg[2]);
if(IsValidSpell(spell_id)) {
Lua_Spell l_spell(&spells[spell_id]);
luabind::object l_spell_o = luabind::object(L, l_spell);
l_spell_o.push(L);
lua_setfield(L, -2, "spell");
} else {
Lua_Spell l_spell(nullptr);
luabind::object l_spell_o = luabind::object(L, l_spell);
l_spell_o.push(L);
lua_setfield(L, -2, "spell");
}
lua_pushinteger(L, std::stoi(sep.arg[3]));
lua_setfield(L, -2, "skill_id");
}
void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) {
lua_pushstring(L, data.c_str());
lua_setfield(L, -2, "timer");
}
void handle_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) {
const Item_Struct *item = database.GetItem(extra_data);
if(item) {
Lua_Item l_item(item);
luabind::object l_item_o = luabind::object(L, l_item);
l_item_o.push(L);
lua_setfield(L, -2, "item");
} else {
Lua_Item l_item(nullptr);
luabind::object l_item_o = luabind::object(L, l_item);
l_item_o.push(L);
lua_setfield(L, -2, "item");
}
}
void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) {
}

View File

@ -2,23 +2,24 @@
#define EQEMU_LUA_PTR_H
#ifdef LUA_EQEMU
template<typename T>
class Lua_Ptr
{
public:
Lua_Ptr() {
}
Lua_Ptr(void *d) : d_(d) {
Lua_Ptr(T *d) : d_(d) {
}
~Lua_Ptr() {
}
void *GetLuaPtrData() {
T *GetLuaPtrData() {
return d_;
}
void SetLuaPtrData(void *d) {
void SetLuaPtrData(T *d) {
d_ = d;
}
@ -31,7 +32,7 @@ public:
}
protected:
void *d_;
T *d_;
};
#endif

View File

@ -1,23 +1,23 @@
#ifndef EQEMU_LUA_ITEM_H
#define EQEMU_LUA_ITEM_H
#ifndef EQEMU_LUA_SPELL_H
#define EQEMU_LUA_SPELL_H
#ifdef LUA_EQEMU
#include "lua_ptr.h"
struct SPDat_Spell_Struct;
class Lua_Spell : public Lua_Ptr
class Lua_Spell : public Lua_Ptr<const void>
{
typedef SPDat_Spell_Struct NativeType;
typedef const SPDat_Spell_Struct NativeType;
public:
Lua_Spell() { }
Lua_Spell(SPDat_Spell_Struct *d) : Lua_Ptr(d) { }
Lua_Spell(const SPDat_Spell_Struct *d) : Lua_Ptr(d) { }
virtual ~Lua_Spell() { }
operator SPDat_Spell_Struct*() {
void *d = GetLuaPtrData();
operator const SPDat_Spell_Struct*() {
const void *d = GetLuaPtrData();
if(d) {
return reinterpret_cast<SPDat_Spell_Struct*>(d);
return reinterpret_cast<const SPDat_Spell_Struct*>(d);
}
return nullptr;

View File

@ -284,17 +284,16 @@ int main(int argc, char** argv) {
}
parse = new QuestParserCollection();
#ifdef EMBPERL
//PerlXSParser *pxs = new PerlXSParser();
PerlembParser *perl_parser = new PerlembParser();
parse->RegisterQuestInterface(perl_parser, "pl");
#endif
#ifdef LUA_EQEMU
LuaParser *lua_parser = new LuaParser();
parse->RegisterQuestInterface(lua_parser, "lua");
#endif
#ifdef EMBPERL
PerlembParser *perl_parser = new PerlembParser();
parse->RegisterQuestInterface(perl_parser, "pl");
#endif
//now we have our parser, load the quests
_log(ZONE__INIT, "Loading quests");
parse->ReloadQuests();

View File

@ -357,7 +357,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
NPC::~NPC()
{
ClearQuestLists();
entity_list.RemoveNPC(GetID());
AI_Stop();
@ -2342,21 +2341,6 @@ bool NPC::CanTalk()
return false;
}
void NPC::PrintOutQuestItems(Client* c){
c->Message(4,"Quest Items currently awaiting completion on %s",GetName());
LinkedListIterator<ItemInst*> iterator(questItems);
iterator.Reset();
while(iterator.MoreElements())
{
c->Message(5,"ItemName: %s (%d) | Charges: %i",iterator.GetData()->GetItem()->Name,iterator.GetData()->GetItem()->ID,iterator.GetData()->GetCharges());
iterator.Advance();
}
c->Message(4,"End of quest items list.");
}
//this is called with 'this' as the mob being looked at, and
//iOther the mob who is doing the looking. It should figure out
//what iOther thinks about 'this'

View File

@ -349,111 +349,6 @@ public:
inline void SetHealScale(float amt) { healscale = amt; }
inline float GetHealScale() { return healscale; }
void AddQuestItem(ItemInst* inst) { questItems.Insert(inst); }
void ClearQuestLists()
{
ClearQuestItems(true);
ClearQuestDeleteItems(true);
}
void ResetQuestDeleteList()
{
ClearQuestDeleteItems(true);
}
void ClearQuestItems(bool delete_=false)
{
LinkedListIterator<ItemInst*> iterator(questItems);
iterator.Reset();
while(iterator.MoreElements())
{
iterator.RemoveCurrent(delete_);
}
questItems.Clear();
}
void ClearQuestDeleteItems(bool delete_=false)
{
LinkedListIterator<ItemInst*> iterator(questDeletionItems);
iterator.Reset();
while(iterator.MoreElements())
{
iterator.RemoveCurrent(delete_);
}
questDeletionItems.Clear();
}
ItemInst* FindQuestItemByID(uint32 itmID, int charges, bool flagItemForDeletion=false)
{
LinkedListIterator<ItemInst*> iterator(questItems);
iterator.Reset();
int totalCharges = 0;
while(iterator.MoreElements())
{
if ( iterator.GetData()->GetItem()->ID == itmID )
{
totalCharges += 1;
if ( flagItemForDeletion )
questDeletionItems.Insert(iterator.GetData()->Clone());
if ( charges > totalCharges )
{
iterator.Advance();
continue;
}
return iterator.GetData();
}
iterator.Advance();
}
return nullptr;
}
bool DoesQuestItemExist(uint32 itmID, int charges, bool flagItemForDeletion=false) {
ItemInst* inst = FindQuestItemByID(itmID,charges,flagItemForDeletion);
if ( inst != nullptr )
{
return true;
}
else
return false;
}
void ClearQuestItem(ItemInst* inst, bool delete_=true)
{
LinkedListIterator<ItemInst*> iterator(questItems);
iterator.Reset();
while(iterator.MoreElements())
{
if ( iterator.GetData ()->GetItem()->ID == inst->GetItem()->ID )
{
iterator.RemoveCurrent(delete_);
break;
}
iterator.Advance();
}
}
void RemoveQuestDeleteItems()
{
LinkedListIterator<ItemInst*> iterator(questDeletionItems);
iterator.Reset();
while(iterator.MoreElements())
{
ClearQuestItem(iterator.GetData(),true);
iterator.RemoveCurrent(true);
}
questDeletionItems.Clear();
}
void PrintOutQuestItems(Client* c);
uint32 GetSpawnKillCount();
int GetScore();
void mod_prespawn(Spawn2 *sp);
@ -552,9 +447,6 @@ protected:
QGlobalCache *qGlobals;
uint32 adventure_template_id;
LinkedList<ItemInst*> questItems;
LinkedList<ItemInst*> questDeletionItems;
//mercenary stuff
std::list<MercType> mercTypeList;
std::list<MercData> mercDataList;

View File

@ -2730,41 +2730,6 @@ const char* QuestManager::GetZoneLongName(const char *zone) {
return ln.c_str();
}
bool QuestManager::TurnInItem(uint32 itm, int charges)
{
if ( owner && owner->IsNPC() )
{
if ( owner->CastToNPC()->DoesQuestItemExist(itm, charges, true) )
return true;
}
return false;
}
void QuestManager::CompleteHandIn()
{
if ( owner && owner->IsNPC() )
{
owner->CastToNPC()->RemoveQuestDeleteItems();
}
}
void QuestManager::ResetHandIn()
{
if ( owner && owner->IsNPC() )
{
owner->CastToNPC()->ResetQuestDeleteList();
}
}
void QuestManager::ClearHandIn()
{
if ( owner && owner->IsNPC() )
{
owner->CastToNPC()->ClearQuestLists();
}
}
void QuestManager::CrossZoneSignalPlayerByCharID(int charid, uint32 data){
ServerPacket* pack = new ServerPacket(ServerOP_CZSignalClient, sizeof(CZClientSignal_Struct));
CZClientSignal_Struct* CZSC = (CZClientSignal_Struct*) pack->pBuffer;

View File

@ -238,10 +238,6 @@ public:
inline ItemInst *GetQuestItem() const {return questitem; }
inline bool ProximitySayInUse() { return HaveProximitySays; }
bool TurnInItem(uint32 itm, int charges);
void CompleteHandIn();
void ResetHandIn();
void ClearHandIn();
void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
void CrossZoneSignalPlayerByName(const char *CharName, uint32 data);
void CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message);

View File

@ -572,22 +572,25 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer)
if(parse->HasQuestSub(tradingWith->GetNPCTypeID(), "EVENT_TRADE")) {
// This is a quest NPC
quest_npc = true;
if(RuleB(NPC, UseMultiQuest)){
StoreTurnInItems(tradingWith);
}
}
uint32 items[4]={0};
uint8 charges[4]={0};
bool attuned[4]={0};
uint32 items[4] = { 0 };
uint8 charges[4] = { 0 };
bool attuned[4] = { 0 };
uint32 augments[4][5] = { 0 };
for (int16 i=3000; i<=3003; i++) {
for (int i = 3000; i < 3004; i++) {
const ItemInst* inst = m_inv[i];
if (inst) {
items[i-3000]=inst->GetItem()->ID;
charges[i-3000]=inst->GetCharges();
attuned[i-3000]=inst->IsInstNoDrop();
const Item_Struct* item2 = database.GetItem(items[i-3000]);
items[i - 3000] = inst->GetItem()->ID;
charges[i - 3000] = inst->GetCharges();
attuned[i - 3000] = inst->IsInstNoDrop();
for(int j = 0; j < 5; j++) {
augments[i][j] = inst->GetAugmentItemID(j);
}
const Item_Struct* item2 = database.GetItem(items[i - 3000]);
// Handle non-quest NPC trading
if (item2 && quest_npc == false) {
// if it was not a NO DROP or Attuned item (or if a GM is trading), let the NPC have it
@ -630,33 +633,37 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer)
//dont bother with this crap unless we have a quest...
//pets can have quests! (especially charmed NPCs)
if (quest_npc) {
char temp1[100];
memset(temp1,0x0,100);
char temp2[100];
memset(temp2,0x0,100);
char temp1[100] = { 0 };
char temp2[100] = { 0 };
for(int z = 0; z < 4; z++) {
snprintf(temp1, 100, "item%d.%d", z+1,tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%d",items[z]);
parse->AddVar(temp1,temp2);
snprintf(temp1, 100, "item%d.charges.%d", z+1,tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%d",charges[z]);
parse->AddVar(temp1,temp2);
snprintf(temp1, 100, "item%d.attuned.%d", z+1,tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%d",attuned[z]);
parse->AddVar(temp1,temp2);
snprintf(temp1, 100, "item%d.%d", z + 1, tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%d", items[z]);
parse->AddVar(temp1, temp2);
snprintf(temp1, 100, "item%d.charges.%d", z + 1, tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%d", charges[z]);
parse->AddVar(temp1, temp2);
snprintf(temp1, 100, "item%d.attuned.%d", z + 1, tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%d", attuned[z]);
parse->AddVar(temp1, temp2);
for(int y = 0; y < 5; y++) {
snprintf(temp1, 100, "item%d.augment.%d", z + 1, tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%d", augments[z][y]);
parse->AddVar(temp1, temp2);
}
}
snprintf(temp1, 100, "copper.%d",tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%i",trade->cp);
parse->AddVar(temp1,temp2);
snprintf(temp1, 100, "silver.%d",tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%i",trade->sp);
parse->AddVar(temp1,temp2);
snprintf(temp1, 100, "copper.%d", tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%u", trade->cp);
parse->AddVar(temp1, temp2);
snprintf(temp1, 100, "silver.%d", tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%u", trade->sp);
parse->AddVar(temp1, temp2);
snprintf(temp1, 100, "gold.%d", tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%i",trade->gp);
snprintf(temp2, 100, "%u", trade->gp);
parse->AddVar(temp1, temp2);
snprintf(temp1, 100, "platinum.%d", tradingWith->GetNPCTypeID());
snprintf(temp2, 100, "%i",trade->pp);
parse->AddVar(temp1,temp2);
snprintf(temp2, 100, "%u", trade->pp);
parse->AddVar(temp1, temp2);
if(tradingWith->GetAppearance() != eaDead) {
tradingWith->FaceTarget(this);
@ -2720,21 +2727,3 @@ void Client::BuyerItemSearch(const EQApplicationPacket *app) {
QueuePacket(outapp);
safe_delete(outapp);
}
bool Client::StoreTurnInItems(Mob* tradingWith) {
if ( !tradingWith || !tradingWith->IsNPC() )
return false;
for (int16 i=3000; i<=3003; i++) {
const ItemInst* inst = m_inv[i];
if (inst) {
database.logevents(AccountName(),AccountID(),admin,GetName(),tradingWith->GetName(),"Quest Turn In Attempt",inst->GetItem()->Name,22);
tradingWith->CastToNPC()->AddQuestItem(inst->Clone());
}
}
return true;
}