Partial perl parser rewrite, want to make it cleaner and have it match the interface

This commit is contained in:
KimLS 2013-05-08 20:18:39 -07:00
parent ac1d931b5e
commit bcf9546b2d
14 changed files with 5712 additions and 5598 deletions

View File

@ -118,11 +118,6 @@ OPTION(EQEMU_BUILD_LUA "Build Lua parser." OFF)
#C++11 stuff
IF(NOT MSVC)
ADD_DEFINITIONS(-std=c++0x)
#Rvalue-Move - todo: auto set this based on gcc version
OPTION(EQEMU_ENABLE_RVALUE_MOVE "Enable EQEmu RValue References (Enable if GCC 4.3 or higher)" OFF)
ELSE(NOT MSVC)
#Rvalue-Move - todo: auto set this based on msvc version
OPTION(EQEMU_ENABLE_RVALUE_MOVE "Enable EQEmu RValue References (Enable if Visual Studio 2010 or higher)" OFF)
ENDIF(NOT MSVC)
IF(EQEMU_ENABLE_RVALUE_MOVE)

View File

@ -54,9 +54,6 @@ Core Zone features
//enable perl-based in-game command, pretty useless without EMBPERL_XS_CLASSES
#define EMBPERL_COMMANDS
//enable #plugin and #peval, which requires IO::Stringy
//#define EMBPERL_EVAL_COMMANDS
#endif
/*

View File

@ -25,15 +25,16 @@ public:
virtual bool ItemHasQuestSub(ItemInst *itm, const char *subname) { return false; }
virtual void LoadNPCScript(std::string filename, int npc_id) { }
//virtual void LoadGlobalNPCScript(std::string filename) { }
virtual void LoadGlobalNPCScript(std::string filename) { }
virtual void LoadPlayerScript(std::string filename) { }
//virtual void LoadGlobalPlayerScript(std::string filename) { }
virtual void LoadGlobalPlayerScript(std::string filename) { }
virtual void LoadItemScript(std::string filename, std::string item_script) { }
virtual void LoadSpellScript(std::string filename, uint32 spell_id) { }
virtual void AddVar(std::string name, std::string val) { }
virtual void ReloadQuests(bool reset_timers = true) { }
virtual uint32 GetIdentifier() { return 0; }
virtual std::string GetVar(std::string name) { return std::string(); }
virtual void ReloadQuests() { }
virtual uint32 GetIdentifier() = 0;
};
#endif

View File

@ -1,10 +1,11 @@
#include "../common/debug.h"
#include "../common/MiscFunctions.h"
#include "../common/features.h"
#include "QuestParserCollection.h"
#include "QuestInterface.h"
#include "zone.h"
#include "zonedb.h"
#include "../common/features.h"
#include "questmgr.h"
#include <stdio.h>
#include <stdlib.h>
@ -14,8 +15,8 @@ extern Zone* zone;
QuestParserCollection::QuestParserCollection() {
_player_quest_status = QuestUnloaded;
//_global_player_quest_status = QuestUnloaded;
//_global_npc_quest_status = QuestUnloaded;
_global_player_quest_status = QuestUnloaded;
_global_npc_quest_status = QuestUnloaded;
}
QuestParserCollection::~QuestParserCollection() {
@ -36,20 +37,28 @@ void QuestParserCollection::AddVar(std::string name, std::string val) {
}
void QuestParserCollection::ReloadQuests(bool reset_timers) {
if(reset_timers) {
quest_manager.ClearAllTimers();
}
_npc_quest_status.clear();
_player_quest_status = QuestUnloaded;
//_global_player_quest_status = QuestUnloaded;
//_global_npc_quest_status = QuestUnloaded;
_global_player_quest_status = QuestUnloaded;
_global_npc_quest_status = QuestUnloaded;
_spell_quest_status.clear();
_item_quest_status.clear();
std::list<QuestInterface*>::iterator iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
(*iter)->ReloadQuests(reset_timers);
(*iter)->ReloadQuests();
iter++;
}
}
bool QuestParserCollection::HasQuestSub(uint32 npcid, const char *subname) {
return HasQuestSubLocal(npcid, subname) || HasQuestSubGlobal(subname);
}
bool QuestParserCollection::HasQuestSubLocal(uint32 npcid, const char *subname) {
std::map<uint32, uint32>::iterator iter = _npc_quest_status.find(npcid);
if(iter != _npc_quest_status.end()) {
@ -74,46 +83,63 @@ bool QuestParserCollection::HasQuestSub(uint32 npcid, const char *subname) {
_npc_quest_status[npcid] = QuestFailedToLoad;
}
}
return false;
}
//if(_global_npc_quest_status == QuestUnloaded){
// std::string filename;
// QuestInterface *qi = GetQIByGlobalNPCQuest(filename);
// if(qi) {
// qi->LoadGlobalNPCScript(filename);
// _global_npc_quest_status = qi->GetIdentifier();
// if(qi->HasGlobalQuestSub(subname)) {
// return true;
// }
// }
//} else {
// if(_global_npc_quest_status != QuestFailedToLoad) {
// std::map<uint32, QuestInterface*>::iterator qiter = _interfaces.find(_global_npc_quest_status);
// if(qiter->second->HasGlobalQuestSub(subname)) {
// return true;
// }
// }
//}
bool QuestParserCollection::HasQuestSubGlobal(const char *subname) {
if(_global_npc_quest_status == QuestUnloaded) {
std::string filename;
QuestInterface *qi = GetQIByGlobalNPCQuest(filename);
if(qi) {
qi->LoadGlobalNPCScript(filename);
_global_npc_quest_status = qi->GetIdentifier();
if(qi->HasGlobalQuestSub(subname)) {
return true;
}
}
} else {
if(_global_npc_quest_status != QuestFailedToLoad) {
std::map<uint32, QuestInterface*>::iterator qiter = _interfaces.find(_global_npc_quest_status);
if(qiter->second->HasGlobalQuestSub(subname)) {
return true;
}
}
}
return false;
}
bool QuestParserCollection::PlayerHasQuestSub(const char *subname) {
return PlayerHasQuestSubLocal(subname) || PlayerHasQuestSubGlobal(subname);
}
bool QuestParserCollection::PlayerHasQuestSubLocal(const char *subname) {
if(_player_quest_status == QuestUnloaded) {
std::string filename;
//QuestInterface *qi = GetQIByGlobalPlayerQuest(filename);
//if(qi) {
// _global_player_quest_status = qi->GetIdentifier();
// qi->LoadGlobalPlayerScript(filename);
//}
std::string filename;
QuestInterface *qi = GetQIByPlayerQuest(filename);
if(qi) {
_player_quest_status = qi->GetIdentifier();
qi->LoadPlayerScript(filename);
return qi->PlayerHasQuestSub(subname); // || qi->GlobalPlayerHasQuestSub(subname);
return qi->PlayerHasQuestSub(subname);
}
} else if(_player_quest_status != QuestFailedToLoad) {
std::map<uint32, QuestInterface*>::iterator iter = _interfaces.find(_player_quest_status);
return iter->second->PlayerHasQuestSub(subname); // || iter->second->GlobalPlayerHasQuestSub(subname);
return iter->second->PlayerHasQuestSub(subname);
}
return false;
}
bool QuestParserCollection::PlayerHasQuestSubGlobal(const char *subname) {
if(_global_player_quest_status == QuestUnloaded) {
std::string filename;
QuestInterface *qi = GetQIByPlayerQuest(filename);
if(qi) {
_global_player_quest_status = qi->GetIdentifier();
qi->LoadPlayerScript(filename);
return qi->GlobalPlayerHasQuestSub(subname);
}
} else if(_global_player_quest_status != QuestFailedToLoad) {
std::map<uint32, QuestInterface*>::iterator iter = _interfaces.find(_global_player_quest_status);
return iter->second->GlobalPlayerHasQuestSub(subname);
}
return false;
}
@ -172,9 +198,14 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, const char *subname)
return false;
}
void QuestParserCollection::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) {
std::map<uint32, uint32>::iterator iter = _npc_quest_status.find(npc->GetNPCTypeID());
if(iter != _npc_quest_status.end()) {
void QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data) {
EventNPCLocal(evt, npc, init, data, extra_data);
EventNPCGlobal(evt, npc, init, data, extra_data);
}
void QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) {
std::map<uint32, uint32>::iterator iter = _npc_quest_status.find(npc->GetNPCTypeID());
if(iter != _npc_quest_status.end()) {
//loaded or failed to load
if(iter->second != QuestFailedToLoad) {
std::map<uint32, QuestInterface*>::iterator qiter = _interfaces.find(iter->second);
@ -191,48 +222,40 @@ void QuestParserCollection::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std:
_npc_quest_status[npc->GetNPCTypeID()] = QuestFailedToLoad;
}
}
}
//// K, lets also parse templates/global_npc.pl
//if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) {
// std::map<uint32, QuestInterface*>::iterator qiter = _interfaces.find(_global_npc_quest_status);
// qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data);
//} else {
// std::string filename;
// QuestInterface *qi = GetQIByGlobalNPCQuest(filename);
// if(qi) {
// _global_npc_quest_status = qi->GetIdentifier();
// qi->LoadGlobalNPCScript(filename);
// qi->EventGlobalNPC(evt, npc, init, data, extra_data);
// } else {
// _global_npc_quest_status = QuestFailedToLoad;
// }
//}
void QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) {
if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) {
std::map<uint32, QuestInterface*>::iterator qiter = _interfaces.find(_global_npc_quest_status);
qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data);
} else {
std::string filename;
QuestInterface *qi = GetQIByGlobalNPCQuest(filename);
if(qi) {
_global_npc_quest_status = qi->GetIdentifier();
qi->LoadGlobalNPCScript(filename);
qi->EventGlobalNPC(evt, npc, init, data, extra_data);
} else {
_global_npc_quest_status = QuestFailedToLoad;
}
}
}
void QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) {
EventPlayerLocal(evt, client, data, extra_data);
EventPlayerGlobal(evt, client, data, extra_data);
}
void QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data) {
if(_player_quest_status == QuestUnloaded) {
std::string filename;
//QuestInterface *qi = GetQIByGlobalPlayerQuest(filename);
//if(qi) {
// _global_player_quest_status = qi->GetIdentifier();
// qi->LoadGlobalPlayerScript(filename);
// qi->EventGlobalPlayer(evt, client, data, extra_data);
//}
QuestInterface *qi = GetQIByPlayerQuest(filename);
if(qi) {
_player_quest_status = qi->GetIdentifier();
qi->LoadPlayerScript(filename);
qi->EventPlayer(evt, client, data, extra_data);
}
} else {
//if(_global_player_quest_status != QuestFailedToLoad) {
// std::map<uint32, QuestInterface*>::iterator iter = _interfaces.find(_global_player_quest_status);
// if(iter != _interfaces.end())
// iter->second->EventGlobalPlayer(evt, client, data, extra_data);
//}
if(_player_quest_status != QuestFailedToLoad) {
std::map<uint32, QuestInterface*>::iterator iter = _interfaces.find(_player_quest_status);
iter->second->EventPlayer(evt, client, data, extra_data);
@ -240,6 +263,23 @@ void QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::s
}
}
void QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data) {
if(_global_player_quest_status == QuestUnloaded) {
std::string filename;
QuestInterface *qi = GetQIByGlobalPlayerQuest(filename);
if(qi) {
_global_player_quest_status = qi->GetIdentifier();
qi->LoadGlobalPlayerScript(filename);
qi->EventGlobalPlayer(evt, client, data, extra_data);
}
} else {
if(_global_player_quest_status != QuestFailedToLoad) {
std::map<uint32, QuestInterface*>::iterator iter = _interfaces.find(_global_player_quest_status);
iter->second->EventGlobalPlayer(evt, client, data, extra_data);
}
}
}
void QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) {
std::string item_script;
if(evt == EVENT_SCALE_CALC || evt == EVENT_ITEM_ENTERZONE) {
@ -310,6 +350,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -343,33 +384,14 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
iter++;
}
//third look for /quests/zone/default.ext (precedence)
filename = "quests/";
filename += zone->GetShortName();
filename += "/";
filename += "default";
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);
return (*iter);
}
iter++;
}
//fourth look for /quests/templates/npcid.ext (precedence)
//third look for /quests/templates/npcid.ext (precedence)
filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY;
filename += "/";
@ -383,13 +405,14 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
iter++;
}
//fifth look for /quests/templates/npcname.ext (precedence)
//fourth look for /quests/templates/npcname.ext (precedence)
filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY;
filename += "/";
@ -403,13 +426,35 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
iter++;
}
//fifth look for /quests/templates/default.ext (precedence)
//fifth look for /quests/zone/default.ext (precedence)
filename = "quests/";
filename += zone->GetShortName();
filename += "/";
filename += "default";
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++;
}
//last look for /quests/templates/default.ext (precedence)
filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY;
filename += "/";
@ -423,6 +468,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -455,6 +501,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -476,6 +523,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -496,6 +544,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -523,6 +572,7 @@ QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filena
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -550,6 +600,7 @@ QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &fil
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -575,6 +626,7 @@ QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}
@ -600,6 +652,7 @@ QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script,
f = fopen(tmp.c_str(), "r");
if(f) {
fclose(f);
filename = tmp;
return (*iter);
}

View File

@ -35,6 +35,16 @@ public:
void EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data);
private:
bool HasQuestSubLocal(uint32 npcid, const char *subname);
bool HasQuestSubGlobal(const char *subname);
bool PlayerHasQuestSubLocal(const char *subname);
bool PlayerHasQuestSubGlobal(const char *subname);
void EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
void EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
void EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
void EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename);
QuestInterface *GetQIByGlobalNPCQuest(std::string &filename);
QuestInterface *GetQIByPlayerQuest(std::string &filename);

View File

@ -325,12 +325,6 @@ int command_init(void) {
command_add("qglobal","[on/off/view] - Toggles qglobal functionality on an NPC",100,command_qglobal) ||
command_add("loc","- Print out your or your target's current location and heading",0,command_loc) ||
command_add("goto","[x] [y] [z] - Teleport to the provided coordinates or to your target",10,command_goto) ||
#ifdef EMBPERL_PLUGIN
#ifdef EMBPERL_EVAL_COMMANDS
command_add("plugin","(sub) [args] - execute a plugin",PERL_PRIVS,command_embperl_plugin) ||
command_add("peval","(expression) - execute some perl",PERL_PRIVS,command_embperl_eval) ||
#endif //EMBPERL_EVAL_COMMANDS
#endif //EMBPERL_PLUGIN
command_add("iteminfo","- Get information about the item on your cursor",10,command_iteminfo) ||
command_add("uptime","[zone server id] - Get uptime of worldserver, or zone server if argument provided",10,command_uptime) ||
command_add("flag","[status] [acctname] - Refresh your admin status, or set an account's admin status if arguments provided",0,command_flag) ||
@ -6400,101 +6394,6 @@ void command_stun(Client *c, const Seperator *sep)
c->Message(0, "Usage: #stun [duration]");
}
#ifdef EMBPERL_PLUGIN
#ifdef EMBPERL_EVAL_COMMANDS
void command_embperl_plugin(Client *c, const Seperator *sep)
{
if(sep->arg[1][0] == 0)
{
c->Message(0, "Usage: #plugin (subname) [arguments]");
return;
}
Embperl * perl;
if(!parse || !(perl = ((PerlembParser *)parse)->getperl()))
{
c->Message(0, "Error: Perl module not loaded");
return;
}
std::string exports = "$plugin::printbuff='';$plugin::ip='";
struct in_addr ip; ip.s_addr = c->GetIP();
exports += inet_ntoa(ip);
exports += "';$plugin::name=qq(";
exports += c->GetName();
exports += ");package plugin;";
perl->eval(exports.c_str());
std::string fqsubname("plugin::");
fqsubname.append(sep->arg[1]);
//convert args into a vector of strings.
std::vector<std::string> args;
for(int i = 2; i < sep->argnum; ++i)
{
args.push_back(sep->arg[i]);
}
try
{
perl->dosub(fqsubname.c_str(), &args);
std::string output = perl->getstr("$plugin::printbuff");
if(output.length())
c->Message(0, "%s", output.c_str());
}
catch(const char * err)
{
c->Message(0, "Error executing plugin: %s", perl->lasterr().c_str());
}
perl->eval("package main;");
}
void command_embperl_eval(Client *c, const Seperator *sep)
{
if(sep->arg[1][0] == 0)
{
c->Message(0, "Usage: #peval (expr)");
return;
}
Embperl * perl;
if(!parse || !(perl = ((PerlembParser *)parse)->getperl()))
{
c->Message(0, "Error: Perl module not loaded");
return;
}
std::string exports = "$plugin::printbuff='';$plugin::ip='";
struct in_addr ip; ip.s_addr = c->GetIP();
exports += inet_ntoa(ip);
exports += "';$plugin::name=qq(";
exports += c->GetName();
exports += ");";
perl->eval(exports.c_str());
try
{
std::string cmd = std::string("package plugin;") + std::string(sep->msg + sizeof("peval "));
perl->eval(cmd.c_str());
std::string output = perl->getstr("$plugin::printbuff");
if(output.length())
c->Message(0, "%s", output.c_str());
}
catch(const char * err)
{
c->Message(0, "Error: %s", perl->lasterr().c_str());
}
perl->eval("package main;");
}
#endif //EMBPERL_PLUGIN
#endif //EMBPERL_EVAL_COMMANDS
void command_ban(Client *c, const Seperator *sep)
{
char errbuf[MYSQL_ERRMSG_SIZE];

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +1,42 @@
//extends the parser to include perl
//Eglin
#ifndef EMBPARSER_H
#define EMBPARSER_H
#ifndef EQEMU_EMBPARSER_H
#define EQMEU_EMBPARSER_H
#ifdef EMBPERL
#include "client.h"
#include "parser.h"
#include "embperl.h"
#include "../common/features.h"
#include "QuestParserCollection.h"
#include "QuestInterface.h"
#include <string>
#include <map>
#include <queue>
using namespace std;
#include "embperl.h"
class Seperator;
typedef enum {
questDefault = 1,
questDefaultByZone,
questByName,
questTemplate,
questTemplateByID,
questByID
} questMode;
typedef enum {
itemQuestUnloaded = 1,
itemQuestScale,
itemQuestLore,
itemQuestID,
itemScriptFileID
} itemQuestMode;
typedef enum {
pQuestLoaded = 1,
pQuestUnloaded,
pQuestEventCast, // player.pl loaded, has an EVENT_CAST sub
pQuestReadyToLoad
} playerQuestMode;
typedef enum {
nQuestLoaded = 1,
nQuestUnloaded,
nQuestReadyToLoad
} GlobalNPCQuestMode;
typedef enum {
spellQuestUnloaded = 1,
spellQuestFullyLoaded,
spellQuestFailed
} spellQuestMode;
struct EventRecord {
QuestEventID event;
uint32 objid;
string data;
NPC* npcmob;
ItemInst* iteminst;
Mob* mob;
uint32 extradata;
bool global;
};
class PerlembParser : public Parser
typedef enum
{
protected:
//could prolly get rid of this map now, since I check for the
//actual subroutine in the quest package as opposed to just seeing
//if they do not have a quest or the default.
map<uint32, questMode> hasQuests; //npcid -> questMode
map<std::string, playerQuestMode> playerQuestLoaded; //zone shortname -> playerQuestMode
playerQuestMode globalPlayerQuestLoaded;
GlobalNPCQuestMode globalNPCQuestLoaded;
map<std::string, itemQuestMode> itemQuestLoaded; // package name - > itemQuestMode
map<uint32, spellQuestMode> spellQuestLoaded;
questUnloaded,
questLoaded,
questFailedToLoad
} PerlQuestStatus;
queue<EventRecord> eventQueue; //for events that happen when perl is in use.
bool eventQueueProcessing;
void HandleQueue();
void EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, bool global = false);
Embperl * perl;
//export a symbol table of sorts
virtual void map_funs();
class PerlembParser : public QuestInterface {
public:
PerlembParser(void);
PerlembParser();
~PerlembParser();
Embperl * getperl(void) { return perl; };
//todo, consider making the following two methods static (need to check for perl!=null, first, then)
bool isloaded(const char *packagename) const;
//interface stuff
virtual void EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
virtual void EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
virtual void EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
virtual void EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
virtual void EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
virtual void EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data);
virtual void EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data);
virtual bool HasQuestSub(uint32 npcid, const char *subname);
virtual bool HasQuestSub(uint32 npcid, const char *subname);
virtual bool HasGlobalQuestSub(const char *subname);
virtual bool PlayerHasQuestSub(const char *subname);
virtual bool GlobalPlayerHasQuestSub(const char *subname);
virtual bool SpellHasQuestSub(uint32 spell_id, const char *subname);
virtual bool ItemHasQuestSub(ItemInst *itm, const char *subname);
virtual void ReloadQuests(bool with_timers = false);
virtual void AddVar(std::string name, std::string val) { Parser::AddVar(name, val); };
virtual uint32 GetIdentifier() { return 0xf8b05c11; }
virtual bool ItemHasQuestSub(ItemInst *itm, const char *subname);
virtual void LoadNPCScript(std::string filename, int npc_id);
virtual void LoadGlobalNPCScript(std::string filename);
@ -125,39 +45,200 @@ public:
virtual void LoadItemScript(std::string filename, std::string item_script);
virtual void LoadSpellScript(std::string filename, uint32 spell_id);
//int LoadScript(int npcid, const char * zone, Mob* activater=0);
//int LoadGlobalNPCScript();
//int LoadPlayerScript(const char *zone);
//int LoadGlobalPlayerScript();
//int LoadItemScript(ItemInst* iteminst, string packagename, itemQuestMode Qtype);
//int LoadSpellScript(uint32 id);
virtual void AddVar(std::string name, std::string val);
virtual std::string GetVar(std::string name);
virtual void ReloadQuests();
virtual uint32 GetIdentifier() { return 0xf8b05c11; }
private:
Embperl *perl;
//expose a var to the script (probably parallels addvar))
//i.e. exportvar("qst1234", "name", "somemob");
//would expose the variable $name='somemob' to the script that handles npc1234
void ExportHash(const char *pkgprefix, const char *hashname, std::map<string,string> &vals);
void ExportVar(const char * pkgprefix, const char * varname, const char * value) const;
void ExportVar(const char * pkgprefix, const char * varname, int value) const;
void ExportVar(const char * pkgprefix, const char * varname, unsigned int value) const;
void ExportVar(const char * pkgprefix, const char * varname, float value) const;
//I don't escape the strings, so use caution!!
//Same as export var, except value is not quoted, and is evaluated as perl
void ExportVarComplex(const char * pkgprefix, const char * varname, const char * value) const;
//get an appropriate namespage/packagename from an npcid
std::string GetPkgPrefix(uint32 npcid, bool defaultOK = true);
//call the appropriate perl handler. afterwards, parse and dispatch the command queue
//SendCommands("qst1234", "EVENT_SAY") would trigger sub EVENT_SAY() from the qst1234.pl file
virtual void SendCommands(const char * pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst);
int HasQuestFile(uint32 npcid);
void ExportHash(const char *pkgprefix, const char *hashname, std::map<std::string, std::string> &vals);
void ExportVar(const char *pkgprefix, const char *varname, const char *value) const;
void ExportVar(const char *pkgprefix, const char *varname, int32 value) const;
void ExportVar(const char *pkgprefix, const char *varname, uint32 value) const;
void ExportVar(const char *pkgprefix, const char *varname, float value) const;
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value) const;
#ifdef EMBPERL_COMMANDS
void ExecCommand(Client *c, Seperator *sep);
#endif
void EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
uint32 extradata, bool global);
void SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst);
void MapFunctions();
std::map<uint32, PerlQuestStatus> npc_quest_status_;
PerlQuestStatus global_npc_quest_status_;
PerlQuestStatus player_quest_status_;
PerlQuestStatus global_player_quest_status_;
std::map<std::string, PerlQuestStatus> item_quest_status_;
std::map<uint32, PerlQuestStatus> spell_quest_status_;
};
#endif //EMBPERL
#endif
#endif
#endif //EMBPARSER_H
////extends the parser to include perl
////Eglin
//
//#ifndef EMBPARSER_H
//#define EMBPARSER_H
//
//#ifdef EMBPERL
//
//#include "client.h"
//#include "parser.h"
//#include "embperl.h"
//#include "../common/features.h"
//#include "QuestParserCollection.h"
//#include "QuestInterface.h"
//
//#include <string>
//#include <map>
//#include <queue>
//using namespace std;
//
//class Seperator;
//
//typedef enum {
// questDefault = 1,
// questDefaultByZone,
// questByName,
// questTemplate,
// questTemplateByID,
// questByID
//} questMode;
//
//typedef enum {
// itemQuestUnloaded = 1,
// itemQuestScale,
// itemQuestLore,
// itemQuestID,
// itemScriptFileID
//} itemQuestMode;
//
//typedef enum {
// pQuestLoaded = 1,
// pQuestUnloaded,
// pQuestEventCast, // player.pl loaded, has an EVENT_CAST sub
// pQuestReadyToLoad
//} playerQuestMode;
//
//typedef enum {
// nQuestLoaded = 1,
// nQuestUnloaded,
// nQuestReadyToLoad
//} GlobalNPCQuestMode;
//
//typedef enum {
// spellQuestUnloaded = 1,
// spellQuestFullyLoaded,
// spellQuestFailed
//} spellQuestMode;
//
//
//struct EventRecord {
// QuestEventID event;
// uint32 objid;
// string data;
// NPC* npcmob;
// ItemInst* iteminst;
// Mob* mob;
// uint32 extradata;
// bool global;
//};
//
//class PerlembParser : public Parser
//{
//protected:
//
// //could prolly get rid of this map now, since I check for the
// //actual subroutine in the quest package as opposed to just seeing
// //if they do not have a quest or the default.
// map<uint32, questMode> hasQuests; //npcid -> questMode
// map<std::string, playerQuestMode> playerQuestLoaded; //zone shortname -> playerQuestMode
// playerQuestMode globalPlayerQuestLoaded;
// GlobalNPCQuestMode globalNPCQuestLoaded;
// map<std::string, itemQuestMode> itemQuestLoaded; // package name - > itemQuestMode
// map<uint32, spellQuestMode> spellQuestLoaded;
//
// queue<EventRecord> eventQueue; //for events that happen when perl is in use.
// bool eventQueueProcessing;
//
// void HandleQueue();
//
// void EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, bool global = false);
//
// Embperl * perl;
// //export a symbol table of sorts
// virtual void map_funs();
//public:
// PerlembParser(void);
// ~PerlembParser();
// Embperl * getperl(void) { return perl; };
// //todo, consider making the following two methods static (need to check for perl!=null, first, then)
// bool isloaded(const char *packagename) const;
//
// //interface stuff
// virtual void EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
// virtual void EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
// virtual void EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
// virtual void EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
// virtual void EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data);
// virtual void EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data);
//
// virtual bool HasQuestSub(uint32 npcid, const char *subname);
// virtual bool HasGlobalQuestSub(const char *subname);
// virtual bool PlayerHasQuestSub(const char *subname);
// virtual bool GlobalPlayerHasQuestSub(const char *subname);
// virtual bool SpellHasQuestSub(uint32 spell_id, const char *subname);
// virtual bool ItemHasQuestSub(ItemInst *itm, const char *subname);
//
// virtual void ReloadQuests(bool with_timers = false);
// virtual void AddVar(std::string name, std::string val) { Parser::AddVar(name, val); };
// virtual uint32 GetIdentifier() { return 0xf8b05c11; }
//
// virtual void LoadNPCScript(std::string filename, int npc_id);
// virtual void LoadGlobalNPCScript(std::string filename);
// virtual void LoadPlayerScript(std::string filename);
// virtual void LoadGlobalPlayerScript(std::string filename);
// virtual void LoadItemScript(std::string filename, std::string item_script);
// virtual void LoadSpellScript(std::string filename, uint32 spell_id);
//
// //int LoadScript(int npcid, const char * zone, Mob* activater=0);
// //int LoadGlobalNPCScript();
// //int LoadPlayerScript(const char *zone);
// //int LoadGlobalPlayerScript();
// //int LoadItemScript(ItemInst* iteminst, string packagename, itemQuestMode Qtype);
// //int LoadSpellScript(uint32 id);
//
// //expose a var to the script (probably parallels addvar))
// //i.e. exportvar("qst1234", "name", "somemob");
// //would expose the variable $name='somemob' to the script that handles npc1234
// void ExportHash(const char *pkgprefix, const char *hashname, std::map<string,string> &vals);
// void ExportVar(const char * pkgprefix, const char * varname, const char * value) const;
// void ExportVar(const char * pkgprefix, const char * varname, int value) const;
// void ExportVar(const char * pkgprefix, const char * varname, unsigned int value) const;
// void ExportVar(const char * pkgprefix, const char * varname, float value) const;
// //I don't escape the strings, so use caution!!
// //Same as export var, except value is not quoted, and is evaluated as perl
// void ExportVarComplex(const char * pkgprefix, const char * varname, const char * value) const;
//
// //get an appropriate namespage/packagename from an npcid
// std::string GetPkgPrefix(uint32 npcid, bool defaultOK = true);
// //call the appropriate perl handler. afterwards, parse and dispatch the command queue
// //SendCommands("qst1234", "EVENT_SAY") would trigger sub EVENT_SAY() from the qst1234.pl file
// virtual void SendCommands(const char * pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst);
//
// int HasQuestFile(uint32 npcid);
//
//#ifdef EMBPERL_COMMANDS
// void ExecCommand(Client *c, Seperator *sep);
//#endif
//
//};
//
//#endif //EMBPERL
//
//#endif //EMBPARSER_H

View File

@ -21,29 +21,24 @@ Eglin
#define GvCV_set(gv,cv) (GvCV(gv) = (cv))
#endif
#ifdef EMBPERL_XS
EXTERN_C XS(boot_quest);
#ifdef EMBPERL_XS_CLASSES
EXTERN_C XS(boot_Mob);
EXTERN_C XS(boot_NPC);
EXTERN_C XS(boot_Client);
EXTERN_C XS(boot_Corpse);
EXTERN_C XS(boot_EntityList);
EXTERN_C XS(boot_Group);
EXTERN_C XS(boot_Raid);
EXTERN_C XS(boot_QuestItem);
EXTERN_C XS(boot_HateEntry);
EXTERN_C XS(boot_Object);
EXTERN_C XS(boot_Doors);
EXTERN_C XS(boot_PerlPacket);
/*XS(XS_Client_new);
//XS(XS_Mob_new);
XS(XS_NPC_new);
//XS(XS_Corpse_new);
XS(XS_EntityList_new);
//XS(XS_Group_new);*/
#endif
#endif
//PERL_TODO:
//#ifdef EMBPERL_XS
//EXTERN_C XS(boot_quest);
//#ifdef EMBPERL_XS_CLASSES
//EXTERN_C XS(boot_Mob);
//EXTERN_C XS(boot_NPC);
//EXTERN_C XS(boot_Client);
//EXTERN_C XS(boot_Corpse);
//EXTERN_C XS(boot_EntityList);
//EXTERN_C XS(boot_Group);
//EXTERN_C XS(boot_Raid);
//EXTERN_C XS(boot_QuestItem);
//EXTERN_C XS(boot_HateEntry);
//EXTERN_C XS(boot_Object);
//EXTERN_C XS(boot_Doors);
//EXTERN_C XS(boot_PerlPacket);
//#endif
//#endif
#ifdef EMBPERL_COMMANDS
XS(XS_command_add);
#endif
@ -66,30 +61,31 @@ EXTERN_C void xs_init(pTHX)
newXS(strcpy(buf, "DynaLoader::boot_DynaLoader"), boot_DynaLoader, file);
newXS(strcpy(buf, "quest::boot_qc"), boot_qc, file);
#ifdef EMBPERL_XS
newXS(strcpy(buf, "quest::boot_quest"), boot_quest, file);
#ifdef EMBPERL_XS_CLASSES
newXS(strcpy(buf, "Mob::boot_Mob"), boot_Mob, file);
newXS(strcpy(buf, "NPC::boot_Mob"), boot_Mob, file);
newXS(strcpy(buf, "NPC::boot_NPC"), boot_NPC, file);
/// newXS(strcpy(buf, "NPC::new"), XS_NPC_new, file);
newXS(strcpy(buf, "Corpse::boot_Mob"), boot_Mob, file);
newXS(strcpy(buf, "Corpse::boot_Corpse"), boot_Corpse, file);
newXS(strcpy(buf, "Client::boot_Mob"), boot_Mob, file);
newXS(strcpy(buf, "Client::boot_Client"), boot_Client, file);
// newXS(strcpy(buf, "Client::new"), XS_Client_new, file);
newXS(strcpy(buf, "EntityList::boot_EntityList"), boot_EntityList, file);
// newXS(strcpy(buf, "EntityList::new"), XS_EntityList_new, file);
newXS(strcpy(buf, "PerlPacket::boot_PerlPacket"), boot_PerlPacket, file);
newXS(strcpy(buf, "Group::boot_Group"), boot_Group, file);
newXS(strcpy(buf, "Raid::boot_Raid"), boot_Raid, file);
newXS(strcpy(buf, "QuestItem::boot_QuestItem"), boot_QuestItem, file);
newXS(strcpy(buf, "HateEntry::boot_HateEntry"), boot_HateEntry, file);
newXS(strcpy(buf, "Object::boot_Object"), boot_Object, file);
newXS(strcpy(buf, "Doors::boot_Doors"), boot_Doors, file);
;
#endif
#endif
//PERL_TODO:
//#ifdef EMBPERL_XS
// newXS(strcpy(buf, "quest::boot_quest"), boot_quest, file);
//#ifdef EMBPERL_XS_CLASSES
// newXS(strcpy(buf, "Mob::boot_Mob"), boot_Mob, file);
// newXS(strcpy(buf, "NPC::boot_Mob"), boot_Mob, file);
// newXS(strcpy(buf, "NPC::boot_NPC"), boot_NPC, file);
///// newXS(strcpy(buf, "NPC::new"), XS_NPC_new, file);
// newXS(strcpy(buf, "Corpse::boot_Mob"), boot_Mob, file);
// newXS(strcpy(buf, "Corpse::boot_Corpse"), boot_Corpse, file);
// newXS(strcpy(buf, "Client::boot_Mob"), boot_Mob, file);
// newXS(strcpy(buf, "Client::boot_Client"), boot_Client, file);
//// newXS(strcpy(buf, "Client::new"), XS_Client_new, file);
// newXS(strcpy(buf, "EntityList::boot_EntityList"), boot_EntityList, file);
//// newXS(strcpy(buf, "EntityList::new"), XS_EntityList_new, file);
// newXS(strcpy(buf, "PerlPacket::boot_PerlPacket"), boot_PerlPacket, file);
// newXS(strcpy(buf, "Group::boot_Group"), boot_Group, file);
// newXS(strcpy(buf, "Raid::boot_Raid"), boot_Raid, file);
// newXS(strcpy(buf, "QuestItem::boot_QuestItem"), boot_QuestItem, file);
// newXS(strcpy(buf, "HateEntry::boot_HateEntry"), boot_HateEntry, file);
// newXS(strcpy(buf, "Object::boot_Object"), boot_Object, file);
// newXS(strcpy(buf, "Doors::boot_Doors"), boot_Doors, file);
//;
//#endif
//#endif
#ifdef EMBPERL_COMMANDS
newXS(strcpy(buf, "commands::command_add"), XS_command_add, file);
#endif
@ -186,18 +182,6 @@ void Embperl::DoInit() {
"package plugin; "
,FALSE
);
#ifdef EMBPERL_EVAL_COMMANDS
try {
eval_pv(
"use IO::Scalar;"
"$plugin::printbuff='';"
"tie *PLUGIN,'IO::Scalar',\\$plugin::printbuff;"
,FALSE);
}
catch(const char *err) {
throw "failed to install plugin printhook, do you lack IO::Scalar?";
}
#endif
LogFile->write(EQEMuLog::Quest, "Loading perlemb plugins.");
try

View File

@ -11,24 +11,31 @@ class ItemInst;
class Client;
class NPC;
class LuaParser {
class LuaParser : public QuestInterface {
public:
virtual void EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
virtual void EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
virtual void EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
virtual void EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
virtual void EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data);
virtual void EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data);
virtual bool HasQuestSub(uint32 npcid, const char *subname);
virtual bool HasGlobalQuestSub(const char *subname);
virtual bool PlayerHasQuestSub(const char *subname);
virtual bool GlobalPlayerHasQuestSub(const char *subname);
virtual bool SpellHasQuestSub(uint32 spell_id, const char *subname);
virtual bool ItemHasQuestSub(ItemInst *itm, const char *subname);
virtual void AddVar(std::string name, std::string val);
virtual void ReloadQuests(bool reset_timers = true);
//virtual void EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
//virtual void EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data);
//virtual void EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
//virtual void EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data);
//virtual void EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data);
//virtual void EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data);
//
//virtual bool HasQuestSub(uint32 npcid, const char *subname);
//virtual bool HasGlobalQuestSub(const char *subname);
//virtual bool PlayerHasQuestSub(const char *subname);
//virtual bool GlobalPlayerHasQuestSub(const char *subname);
//virtual bool SpellHasQuestSub(uint32 spell_id, const char *subname);
//virtual bool ItemHasQuestSub(ItemInst *itm, const char *subname);
//
//virtual void LoadNPCScript(std::string filename, int npc_id) { }
////virtual void LoadGlobalNPCScript(std::string filename) { }
//virtual void LoadPlayerScript(std::string filename) { }
////virtual void LoadGlobalPlayerScript(std::string filename) { }
//virtual void LoadItemScript(std::string filename, std::string item_script) { }
//virtual void LoadSpellScript(std::string filename, uint32 spell_id) { }
//
//virtual void AddVar(std::string name, std::string val);
//virtual void ReloadQuests(bool reset_timers = true);
virtual uint32 GetIdentifier() { return 0xb0712acc; }
private:
lua_State* L;

View File

@ -74,7 +74,6 @@ extern volatile bool ZoneLoaded;
#include "../common/spdat.h"
#include "zone.h"
#include "command.h"
#include "parser.h"
#include "embparser.h"
#include "perlparser.h"
#include "lua_parser.h"
@ -286,8 +285,9 @@ int main(int argc, char** argv) {
parse = new QuestParserCollection();
#ifdef EMBPERL
PerlXSParser *pxs = new PerlXSParser();
parse->RegisterQuestInterface(pxs, "pl");
//PerlXSParser *pxs = new PerlXSParser();
PerlembParser *perl_parser = new PerlembParser();
parse->RegisterQuestInterface(perl_parser, "pl");
#endif
#ifdef LUA_EQEMU
@ -295,10 +295,6 @@ int main(int argc, char** argv) {
parse->RegisterQuestInterface(lua_parser, "lua");
#endif
Parser *ps = new Parser();
//parse->RegisterQuestInterface(ps, "qst");
//now we have our parser, load the quests
_log(ZONE__INIT, "Loading quests");
parse->ReloadQuests();
@ -481,16 +477,14 @@ int main(int argc, char** argv) {
entity_list.Clear();
safe_delete(parse);
#ifdef EMBPERL
safe_delete(pxs);
safe_delete(perl_parser);
#endif
#ifdef LUA_EQEMU
safe_delete(lua_parser);
#endif
safe_delete(ps);
safe_delete(mmf);
if (zone != 0)

File diff suppressed because it is too large Load Diff

View File

@ -19,28 +19,28 @@
//extends the perl parser to use C methods
//instead of the command queue.
#ifndef PERLPARSER_H
#define PERLPARSER_H
#ifdef EMBPERL
#ifdef EMBPERL_XS
#include "embparser.h"
class PerlXSParser : public PerlembParser {
public:
PerlXSParser();
// ~PerlXSParser();
virtual void SendCommands(const char * pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst);
protected:
void map_funs();
SV *_empty_sv;
};
#endif //EMBPERL_XS
#endif //EMBPERL
#endif //PERLPARSER_H
//#ifndef PERLPARSER_H
//#define PERLPARSER_H
//
//#ifdef EMBPERL
//#ifdef EMBPERL_XS
//
//#include "embparser.h"
//
//class PerlXSParser : public PerlembParser {
//public:
// PerlXSParser();
//// ~PerlXSParser();
//
// virtual void SendCommands(const char * pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst);
//protected:
// void map_funs();
//
// SV *_empty_sv;
//};
//
//
//#endif //EMBPERL_XS
//#endif //EMBPERL
//
//#endif //PERLPARSER_H

View File

@ -77,10 +77,6 @@ public:
void settarget(const char *type, int target_id);
void follow(int entity_id, int distance);
void sfollow();
// void cumflag();
// void flagnpc(uint32 flag_num, uint8 flag_value);
// void flagcheck(uint32 flag_to_check, uint32 flag_to_set);
// bool isflagset(int flag_num);
void changedeity(int diety_id);
void exp(int amt);
void level(int newlevel);