mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
Fix acceptmessages, added exp hooks to luamods
This commit is contained in:
parent
c83810be36
commit
31d8336b4b
@ -25,6 +25,23 @@ void EQ::Net::ConsoleServer::RegisterLogin(ConsoleServerLoginCallback fn)
|
||||
m_login = fn;
|
||||
}
|
||||
|
||||
EQ::Net::ConsoleServerConnection *EQ::Net::ConsoleServer::FindByAccountName(const std::string &acct_name) {
|
||||
for (auto &iter : m_connections) {
|
||||
if (iter.second->UserName().compare(acct_name) == 0) {
|
||||
return iter.second.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void EQ::Net::ConsoleServer::SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell) {
|
||||
for (auto &iter : m_connections) {
|
||||
iter.second->SendChannelMessage(scm, onTell);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::ConsoleServer::ConnectionDisconnected(ConsoleServerConnection *c)
|
||||
{
|
||||
auto iter = m_connections.find(c->GetUUID());
|
||||
|
||||
@ -25,7 +25,8 @@ namespace EQ
|
||||
|
||||
void RegisterCall(const std::string& command, int status_required, const std::string& help_definition, ConsoleServerCallback fn);
|
||||
void RegisterLogin(ConsoleServerLoginCallback fn);
|
||||
|
||||
ConsoleServerConnection *FindByAccountName(const std::string &acct_name);
|
||||
void SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell);
|
||||
private:
|
||||
void ConnectionDisconnected(ConsoleServerConnection *c);
|
||||
void ProcessCommand(ConsoleServerConnection *c, const std::string& cmd);
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
#include "../common/util/uuid.h"
|
||||
#include "../common/net/packet.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/rulesys.h"
|
||||
|
||||
EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent, std::shared_ptr<TCPConnection> connection)
|
||||
{
|
||||
@ -107,6 +109,53 @@ void EQ::Net::ConsoleServerConnection::QueueMessage(const std::string &msg)
|
||||
}
|
||||
}
|
||||
|
||||
bool EQ::Net::ConsoleServerConnection::SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell) {
|
||||
if (!m_accept_messages) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (scm->chan_num) {
|
||||
if (RuleB(Chat, ServerWideAuction)) {
|
||||
case 4: {
|
||||
QueueMessage(fmt::format("{0} auctions, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (RuleB(Chat, ServerWideOOC)) {
|
||||
case 5: {
|
||||
QueueMessage(fmt::format("{0} says ooc, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 6: {
|
||||
QueueMessage(fmt::format("{0} BROADCASTS, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: {
|
||||
QueueMessage(fmt::format("[{0}] tells you, '{1}'", scm->from, scm->message));
|
||||
if (onTell) {
|
||||
onTell();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 11: {
|
||||
QueueMessage(fmt::format("{0} GMSAYS, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EQ::Net::ConsoleServerConnection::OnRead(TCPConnection *c, const unsigned char *data, size_t sz)
|
||||
{
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
struct ServerChannelMessage_Struct;
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
@ -42,6 +44,7 @@ namespace EQ
|
||||
bool AcceptMessages() const { return m_accept_messages; }
|
||||
void SetAcceptMessages(bool v) { m_accept_messages = v; }
|
||||
void QueueMessage(const std::string &msg);
|
||||
bool SendChannelMessage(const ServerChannelMessage_Struct* scm, std::function<void(void)> onTell);
|
||||
private:
|
||||
void OnRead(TCPConnection* c, const unsigned char* data, size_t sz);
|
||||
void OnDisconnect(TCPConnection* c);
|
||||
|
||||
159
utils/mods/classic_wow_experience.lua
Normal file
159
utils/mods/classic_wow_experience.lua
Normal file
@ -0,0 +1,159 @@
|
||||
--Mod file to demo changing the experience tables
|
||||
--In this case I used some old wow tables (roughly it's not 100%)
|
||||
|
||||
function GetRequiredAAExperience(e)
|
||||
e.level = 51;
|
||||
return GetEXPForLevel(e);
|
||||
end
|
||||
|
||||
function GetExperienceForKill(e)
|
||||
local ML = e.other:GetLevel();
|
||||
local CL = e.self:GetLevel();
|
||||
|
||||
if(ML > CL) then
|
||||
local lmod = (ML - CL) * 0.05;
|
||||
if(lmod > 1.0) then
|
||||
lmod = 1.0;
|
||||
end
|
||||
e.ReturnValue = BaseXP(ML) * (1 + lmod);
|
||||
elseif(ML < CL) then
|
||||
local lmod = (CL - ML) * 0.05;
|
||||
if(lmod > 1.0) then
|
||||
lmod = 1.0;
|
||||
end
|
||||
e.ReturnValue = BaseXP(ML) * (1 - lmod);
|
||||
else
|
||||
e.ReturnValue = BaseXP(ML);
|
||||
end
|
||||
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
function BaseXP(L)
|
||||
local base = L * 5;
|
||||
|
||||
if(L < 60) then
|
||||
base = base + 45;
|
||||
elseif(L < 70) then
|
||||
base = base + 235;
|
||||
elseif(L < 80) then
|
||||
base = base + 580;
|
||||
else
|
||||
base = base + 1875;
|
||||
end
|
||||
|
||||
return base;
|
||||
end
|
||||
|
||||
function GetEXPForLevel(e)
|
||||
local exp_table = {
|
||||
0,
|
||||
400,
|
||||
900,
|
||||
1400,
|
||||
2100,
|
||||
2800,
|
||||
3600,
|
||||
4500,
|
||||
5400,
|
||||
6500,
|
||||
7600,
|
||||
8700,
|
||||
9800,
|
||||
11000,
|
||||
12300,
|
||||
13600,
|
||||
15000,
|
||||
16400,
|
||||
17800,
|
||||
19300,
|
||||
20800,
|
||||
22400,
|
||||
24000,
|
||||
25500,
|
||||
27200,
|
||||
28900,
|
||||
30500,
|
||||
32200,
|
||||
33900,
|
||||
36300,
|
||||
38800,
|
||||
41600,
|
||||
44600,
|
||||
48000,
|
||||
51400,
|
||||
55000,
|
||||
58700,
|
||||
62400,
|
||||
66200,
|
||||
70200,
|
||||
74300,
|
||||
78500,
|
||||
82800,
|
||||
87100,
|
||||
91600,
|
||||
96300,
|
||||
101000,
|
||||
105800,
|
||||
110700,
|
||||
115700,
|
||||
120900,
|
||||
126100,
|
||||
131500,
|
||||
137000,
|
||||
142500,
|
||||
148200,
|
||||
154000,
|
||||
159900,
|
||||
165800,
|
||||
172000,
|
||||
290000,
|
||||
317000,
|
||||
349000,
|
||||
386000,
|
||||
428000,
|
||||
475000,
|
||||
527000,
|
||||
585000,
|
||||
648000,
|
||||
717000,
|
||||
1523800,
|
||||
1539000,
|
||||
1555700,
|
||||
1571800,
|
||||
1587900,
|
||||
1604200,
|
||||
1620700,
|
||||
1637400,
|
||||
1653900,
|
||||
1670800,
|
||||
1670800,
|
||||
1670800,
|
||||
2121500,
|
||||
2669000,
|
||||
3469000,
|
||||
4583000,
|
||||
13000000,
|
||||
15080000,
|
||||
22600000,
|
||||
27300000,
|
||||
32800000
|
||||
};
|
||||
|
||||
if(e.level < 1) then
|
||||
e.ReturnValue = 0;
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
if(e.level > 91) then
|
||||
e.ReturnValue = exp_table[91];
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
|
||||
e.ReturnValue = exp_table[e.level];
|
||||
e.IgnoreDefault = true;
|
||||
return e;
|
||||
end
|
||||
@ -392,12 +392,12 @@ int main(int argc, char** argv) {
|
||||
server_connection->Listen(server_opts);
|
||||
Log(Logs::General, Logs::World_Server, "Server (TCP) listener started.");
|
||||
|
||||
server_connection->OnConnectionIdentified("Zone", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
server_connection->OnConnectionIdentified("Zone", [&console](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
LogF(Logs::General, Logs::World_Server, "New Zone Server connection from {2} at {0}:{1}",
|
||||
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
|
||||
|
||||
numzones++;
|
||||
zoneserver_list.Add(new ZoneServer(connection));
|
||||
zoneserver_list.Add(new ZoneServer(connection, console.get()));
|
||||
});
|
||||
|
||||
server_connection->OnConnectionRemoved("Zone", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
|
||||
@ -46,7 +46,7 @@ extern UCSConnection UCSLink;
|
||||
extern QueryServConnection QSLink;
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
ZoneServer::ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection)
|
||||
ZoneServer::ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection, EQ::Net::ConsoleServer *console)
|
||||
: tcpc(connection), zone_boot_timer(5000) {
|
||||
|
||||
/* Set Process tracking variable defaults */
|
||||
@ -73,6 +73,8 @@ ZoneServer::ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> conn
|
||||
zone_boot_timer.Disable();
|
||||
}
|
||||
}));
|
||||
|
||||
this->console = console;
|
||||
}
|
||||
|
||||
ZoneServer::~ZoneServer() {
|
||||
@ -412,6 +414,27 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
break;
|
||||
}
|
||||
if (scm->chan_num == 7 || scm->chan_num == 14) {
|
||||
if (scm->deliverto[0] == '*') {
|
||||
|
||||
if (console) {
|
||||
auto con = console->FindByAccountName(&scm->deliverto[1]);
|
||||
if (((!con) || (!con->SendChannelMessage(scm, [&scm]() {
|
||||
auto pack = new ServerPacket(ServerOP_ChannelMessage,
|
||||
sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
|
||||
memcpy(pack->pBuffer, scm, pack->size);
|
||||
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*)pack->pBuffer;
|
||||
strcpy(scm2->deliverto, scm2->from);
|
||||
scm2->noreply = true;
|
||||
client_list.SendPacket(scm->from, pack);
|
||||
safe_delete(pack);
|
||||
}))) && (!scm->noreply))
|
||||
{
|
||||
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "%s is not online at this time.", scm->to);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ClientListEntry* cle = client_list.FindCharacter(scm->deliverto);
|
||||
if (cle == 0 || cle->Online() < CLE_Status_Zoning ||
|
||||
(cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) {
|
||||
@ -462,6 +485,20 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
cle->Server()->SendPacket(pack);
|
||||
}
|
||||
else {
|
||||
if (scm->chan_num == 5 || scm->chan_num == 6 || scm->chan_num == 11) {
|
||||
if (console) {
|
||||
console->SendChannelMessage(scm, [&scm]() {
|
||||
auto pack = new ServerPacket(ServerOP_ChannelMessage,
|
||||
sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
|
||||
memcpy(pack->pBuffer, scm, pack->size);
|
||||
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*)pack->pBuffer;
|
||||
strcpy(scm2->deliverto, scm2->from);
|
||||
scm2->noreply = true;
|
||||
client_list.SendPacket(scm->from, pack);
|
||||
safe_delete(pack);
|
||||
});
|
||||
}
|
||||
}
|
||||
zoneserver_list.SendPacket(pack);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "../net/servertalk_server.h"
|
||||
#include "../event/timer.h"
|
||||
#include "../timer.h"
|
||||
#include "console.h"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
@ -31,7 +32,7 @@ class ServerPacket;
|
||||
|
||||
class ZoneServer : public WorldTCPConnection {
|
||||
public:
|
||||
ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection);
|
||||
ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection, EQ::Net::ConsoleServer *console);
|
||||
~ZoneServer();
|
||||
virtual inline bool IsZoneServer() { return true; }
|
||||
|
||||
@ -97,6 +98,7 @@ private:
|
||||
uint32 zone_os_process_id;
|
||||
std::string launcher_name; //the launcher which started us
|
||||
std::string launched_name; //the name of the zone we launched.
|
||||
EQ::Net::ConsoleServer *console;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -916,7 +916,7 @@ void Client::SendAlternateAdvancementRank(int aa_id, int level) {
|
||||
void Client::SendAlternateAdvancementStats() {
|
||||
auto outapp = new EQApplicationPacket(OP_AAExpUpdate, sizeof(AltAdvStats_Struct));
|
||||
AltAdvStats_Struct *aps = (AltAdvStats_Struct *)outapp->pBuffer;
|
||||
aps->experience = (uint32)(((float)330.0f * (float)m_pp.expAA) / (float)max_AAXP);
|
||||
aps->experience = (uint32)(((float)330.0f * (float)m_pp.expAA) / (float)GetRequiredAAExperience());
|
||||
aps->unspent = m_pp.aapoints;
|
||||
aps->percentage = m_epp.perAA;
|
||||
QueuePacket(outapp);
|
||||
|
||||
@ -2222,7 +2222,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
||||
Group *kg = entity_list.GetGroupByClient(give_exp_client);
|
||||
Raid *kr = entity_list.GetRaidByClient(give_exp_client);
|
||||
|
||||
int32 finalxp = EXP_FORMULA;
|
||||
int32 finalxp = give_exp_client->GetExperienceForKill(this);
|
||||
finalxp = give_exp_client->mod_client_xp(finalxp, this);
|
||||
|
||||
if (kr) {
|
||||
|
||||
@ -571,6 +571,7 @@ public:
|
||||
void AddCrystals(uint32 Radiant, uint32 Ebon);
|
||||
void SendCrystalCounts();
|
||||
|
||||
uint32 GetExperienceForKill(Mob *against);
|
||||
void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
|
||||
uint32 CalcEXP(uint8 conlevel = 0xFF);
|
||||
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
|
||||
@ -796,12 +797,12 @@ public:
|
||||
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAlternateAdvancementStats(); }
|
||||
int GetAAPoints() { return m_pp.aapoints; }
|
||||
int GetSpentAA() { return m_pp.aapoints_spent; }
|
||||
uint32 GetRequiredAAExperience();
|
||||
|
||||
//old AA methods that we still use
|
||||
void ResetAA();
|
||||
void RefundAA();
|
||||
void SendClearAA();
|
||||
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
||||
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
||||
inline uint32 GetAAPercent() const { return m_epp.perAA; }
|
||||
int16 CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id);
|
||||
@ -1493,7 +1494,6 @@ private:
|
||||
|
||||
uint32 tribute_master_id;
|
||||
|
||||
uint32 max_AAXP;
|
||||
bool npcflag;
|
||||
uint8 npclevel;
|
||||
bool feigned;
|
||||
|
||||
@ -1355,8 +1355,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
|
||||
/* Set Total Seconds Played */
|
||||
TotalSecondsPlayed = m_pp.timePlayedMin * 60;
|
||||
/* Set Max AA XP */
|
||||
max_AAXP = RuleI(AA, ExpPerPoint);
|
||||
|
||||
/* If we can maintain intoxication across zones, check for it */
|
||||
if (!RuleB(Character, MaintainIntoxicationAcrossZones))
|
||||
m_pp.intoxication = 0;
|
||||
|
||||
54
zone/exp.cpp
54
zone/exp.cpp
@ -28,6 +28,7 @@
|
||||
|
||||
#include "queryserv.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "lua_parser.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
#ifdef BOTS
|
||||
@ -153,6 +154,26 @@ uint32 Client::CalcEXP(uint8 conlevel) {
|
||||
return in_add_exp;
|
||||
}
|
||||
|
||||
uint32 Client::GetExperienceForKill(Mob *against)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
uint32 lua_ret = 0;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->GetExperienceForKill(this, against, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (against && against->IsNPC()) {
|
||||
uint32 level = (uint32)against->GetLevel();
|
||||
return EXP_FORMULA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
|
||||
this->EVENT_ITEM_ScriptStopReturn();
|
||||
@ -339,8 +360,8 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
|
||||
void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
Log(Logs::Detail, Logs::None, "Attempting to Set Exp for %s (XP: %u, AAXP: %u, Rez: %s)", this->GetCleanName(), set_exp, set_aaxp, isrezzexp ? "true" : "false");
|
||||
//max_AAXP = GetEXPForLevel(52) - GetEXPForLevel(51); //GetEXPForLevel() doesn't depend on class/race, just level, so it shouldn't change between Clients
|
||||
max_AAXP = RuleI(AA, ExpPerPoint); //this may be redundant since we're doing this in Client::FinishConnState2()
|
||||
|
||||
auto max_AAXP = GetRequiredAAExperience();
|
||||
if (max_AAXP == 0 || GetEXPForLevel(GetLevel()) == 0xFFFFFFFF) {
|
||||
Message(13, "Error in Client::SetEXP. EXP not set.");
|
||||
return; // Must be invalid class/race
|
||||
@ -460,14 +481,13 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
|
||||
//add in how many points we had
|
||||
m_pp.aapoints += last_unspentAA;
|
||||
//set_aaxp = m_pp.expAA % max_AAXP;
|
||||
|
||||
//figure out how many points were actually gained
|
||||
/*uint32 gained = m_pp.aapoints - last_unspentAA;*/ //unused
|
||||
|
||||
//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
|
||||
char val1[20]={0};
|
||||
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
||||
Message_StringID(MT_Experience, GAIN_ABILITY_POINT, ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
||||
|
||||
/* QS: PlayerLogAARate */
|
||||
if (RuleB(QueryServ, PlayerLogAARate)){
|
||||
@ -571,8 +591,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
char val1[20]={0};
|
||||
char val2[20]={0};
|
||||
char val3[20]={0};
|
||||
Message_StringID(MT_Experience, GM_GAINXP,ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3).
|
||||
//Message(15, "[GM] You now have %d / %d EXP and %d / %d AA exp.", set_exp, GetEXPForLevel(GetLevel()+1), set_aaxp, max_AAXP);
|
||||
Message_StringID(MT_Experience, GM_GAINXP, ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3).
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,6 +683,15 @@ void Client::SetLevel(uint8 set_level, bool command)
|
||||
// Add: You can set the values you want now, client will be always sync :) - Merkur
|
||||
uint32 Client::GetEXPForLevel(uint16 check_level)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
uint32 lua_ret = 0;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->GetEXPForLevel(this, check_level, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16 check_levelm1 = check_level-1;
|
||||
float mod;
|
||||
@ -933,3 +961,17 @@ uint32 Client::GetCharMaxLevelFromQGlobal() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 Client::GetRequiredAAExperience() {
|
||||
#ifdef LUA_EQEMU
|
||||
uint32 lua_ret = 0;
|
||||
bool ignoreDefault = false;
|
||||
lua_ret = LuaParser::Instance()->GetRequiredAAExperience(this, ignoreDefault);
|
||||
|
||||
if (ignoreDefault) {
|
||||
return lua_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return RuleI(AA, ExpPerPoint);
|
||||
}
|
||||
|
||||
163
zone/lua_mod.cpp
163
zone/lua_mod.cpp
@ -39,6 +39,9 @@ void LuaMod::Init()
|
||||
m_has_avoid_damage = parser_->HasFunction("AvoidDamage", package_name_);
|
||||
m_has_check_hit_chance = parser_->HasFunction("CheckHitChance", package_name_);
|
||||
m_has_try_critical_hit = parser_->HasFunction("TryCriticalHit", package_name_);
|
||||
m_has_get_required_aa_experience = parser_->HasFunction("GetRequiredAAExperience", package_name_);
|
||||
m_has_get_exp_for_level = parser_->HasFunction("GetEXPForLevel", package_name_);
|
||||
m_has_get_experience_for_kill = parser_->HasFunction("GetExperienceForKill", package_name_);
|
||||
}
|
||||
|
||||
void PutDamageHitInfo(lua_State *L, luabind::adl::object &e, DamageHitInfo &hit) {
|
||||
@ -388,8 +391,6 @@ bool LuaMod::CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ign
|
||||
return retval;
|
||||
}
|
||||
|
||||
//void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
|
||||
void LuaMod::TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
ignoreDefault = false;
|
||||
@ -440,3 +441,161 @@ void LuaMod::TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraA
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 LuaMod::GetRequiredAAExperience(Client *self, bool &ignoreDefault)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
ignoreDefault = false;
|
||||
uint32 retval = 0;
|
||||
|
||||
try {
|
||||
if (!m_has_get_required_aa_experience) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "GetRequiredAAExperience");
|
||||
|
||||
Lua_Client l_self(self);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TNUMBER) {
|
||||
retval = luabind::object_cast<uint32>(returnValueObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32 LuaMod::GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault) {
|
||||
int start = lua_gettop(L);
|
||||
ignoreDefault = false;
|
||||
uint32 retval = 0;
|
||||
|
||||
try {
|
||||
if (!m_has_get_exp_for_level) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "GetEXPForLevel");
|
||||
|
||||
Lua_Client l_self(self);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["level"] = level;
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TNUMBER) {
|
||||
retval = luabind::object_cast<uint32>(returnValueObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32 LuaMod::GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
ignoreDefault = false;
|
||||
uint32 retval = 0;
|
||||
|
||||
try {
|
||||
if (!m_has_get_experience_for_kill) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "GetExperienceForKill");
|
||||
|
||||
Lua_Client l_self(self);
|
||||
Lua_Mob l_other(against);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["other"] = l_other;
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto IgnoreDefaultObj = ret["IgnoreDefault"];
|
||||
if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) {
|
||||
ignoreDefault = ignoreDefault || luabind::object_cast<bool>(IgnoreDefaultObj);
|
||||
}
|
||||
|
||||
auto returnValueObj = ret["ReturnValue"];
|
||||
if (luabind::type(returnValueObj) == LUA_TNUMBER) {
|
||||
retval = luabind::object_cast<uint32>(returnValueObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -22,7 +22,9 @@ public:
|
||||
bool AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
bool CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
|
||||
uint32 GetRequiredAAExperience(Client *self, bool &ignoreDefault);
|
||||
uint32 GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault);
|
||||
uint32 GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault);
|
||||
private:
|
||||
LuaParser *parser_;
|
||||
lua_State *L;
|
||||
@ -33,4 +35,7 @@ private:
|
||||
bool m_has_avoid_damage;
|
||||
bool m_has_check_hit_chance;
|
||||
bool m_has_try_critical_hit;
|
||||
bool m_has_get_required_aa_experience;
|
||||
bool m_has_get_exp_for_level;
|
||||
bool m_has_get_experience_for_kill;
|
||||
};
|
||||
|
||||
@ -959,6 +959,13 @@ void LuaParser::ReloadQuests() {
|
||||
if (load_order) {
|
||||
char file_name[256] = { 0 };
|
||||
while (fgets(file_name, 256, load_order) != nullptr) {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
if (file_name[i] == '\n') {
|
||||
file_name[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LoadScript("mods/" + std::string(file_name), file_name);
|
||||
mods_.push_back(LuaMod(L, this, file_name));
|
||||
}
|
||||
@ -1324,3 +1331,30 @@ void LuaParser::TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, Ext
|
||||
mod.TryCriticalHit(self, defender, hit, opts, ignoreDefault);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 LuaParser::GetRequiredAAExperience(Client *self, bool &ignoreDefault)
|
||||
{
|
||||
uint32 retval = false;
|
||||
for (auto &mod : mods_) {
|
||||
retval = mod.GetRequiredAAExperience(self, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32 LuaParser::GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault)
|
||||
{
|
||||
uint32 retval = false;
|
||||
for (auto &mod : mods_) {
|
||||
retval = mod.GetEXPForLevel(self, level, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32 LuaParser::GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault)
|
||||
{
|
||||
uint32 retval = false;
|
||||
for (auto &mod : mods_) {
|
||||
retval = mod.GetExperienceForKill(self, against, ignoreDefault);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -95,6 +95,9 @@ public:
|
||||
bool AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
bool CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||
void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||
uint32 GetRequiredAAExperience(Client *self, bool &ignoreDefault);
|
||||
uint32 GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault);
|
||||
uint32 GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault);
|
||||
|
||||
private:
|
||||
LuaParser();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user