• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Feature Creatureevent OnGainExp

knightxd

Member
Joined
Feb 21, 2009
Messages
211
Reaction score
16
Location
Rio de Janeiro
well, its a creature event that activates when player gets exp, also you can set
Lua:
 return false
so the player will not get exp...

well lets stop talking, open creatureevent.h
after
[cpp]
CREATURE_EVENT_OUTFIT,
[/cpp]
Add
[cpp]
CREATURE_EVENT_GAINEXP,
[/cpp]

now after
[cpp]
uint32_t executeOutfit(Creature* creature, const Outfit_t& old, const Outfit_t& current);
[/cpp]
add
[cpp]
uint32_t executeGainExp(Player* player, int32_t value);
[/cpp]

now open your creatureevent.cpp and find
[cpp]
else if(tmpStr == "outfit")
m_type = CREATURE_EVENT_OUTFIT;
[/cpp]
after it put
[cpp]
else if(tmpStr == "gainexp")
m_type = CREATURE_EVENT_GAINEXP;
[/cpp]

now look for
[cpp]
case CREATURE_EVENT_OUTFIT:
return "onOutfit";
[/cpp]
after it put
[cpp]
case CREATURE_EVENT_GAINEXP:
return "onGainExp";
[/cpp]

then search for
[cpp]
case CREATURE_EVENT_OUTFIT:
return "cid, old, current";
[/cpp]
and add next to it
[cpp]
case CREATURE_EVENT_GAINEXP:
return "cid, value";
[/cpp]

after that, find
[cpp]
uint32_t CreatureEvent::executeStatsChange
[/cpp]
before it put
[cpp]
uint32_t CreatureEvent::executeGainExp(Player* player, int32_t value)
{
//onGainExp(cid, value)
if(m_interface->reserveEnv())
{
ScriptEnviroment* env = m_interface->getEnv();
if(m_scripted == EVENT_SCRIPT_BUFFER)
{
env->setRealPos(player->getPosition());
std::stringstream scriptstream;

scriptstream << "local cid = " << env->addThing(player) << std::endl;
scriptstream << "local value = " << value << std::endl;

scriptstream << m_scriptData;
bool result = true;
if(m_interface->loadBuffer(scriptstream.str()))
{
lua_State* L = m_interface->getState();
result = m_interface->getGlobalBool(L, "_result", true);
}

m_interface->releaseEnv();
return result;
}
else
{
#ifdef __DEBUG_LUASCRIPTS__
char desc[35];
sprintf(desc, "%s", player->getName().c_str());
env->setEvent(desc);
#endif

env->setScriptId(m_scriptId, m_interface);
env->setRealPos(player->getPosition());

lua_State* L = m_interface->getState();
m_interface->pushFunction(m_scriptId);

lua_pushnumber(L, env->addThing(player));
lua_pushnumber(L, value);

bool result = m_interface->callFunction(2);
m_interface->releaseEnv();
return result;
}
}
else
{
std::clog << "[Error - CreatureEvent::executeGainExp] Call stack overflow." << std::endl;
return 0;
}
}
[/cpp]

now go to players.cpp and find
[cpp]
bool Player::gainExperience(double& gainExp, Creature* target)
[/cpp]

changes the hole for this
[cpp]
bool Player::gainExperience(double& gainExp, Creature* target)
{
if(!rateExperience(gainExp, target))
return false;

if(gainExp >= 1)
{
bool deny = false;
CreatureEventList gainExpEvents = this->getCreatureEvents(CREATURE_EVENT_GAINEXP);
for(CreatureEventList::iterator it = gainExpEvents.begin(); it != gainExpEvents.end(); ++it)
{
if(!(*it)->executeGainExp(this, gainExp))
deny = true;
}
if(deny)
return false;
if(gainExp >= level)
{
if(Condition* condition = Condition::createCondition(
CONDITIONID_DEFAULT, CONDITION_SOUL, 4 * 60 * 1000))
{
condition->setParam(CONDITIONPARAM_SOULGAIN,
vocation->getGainAmount(GAIN_SOUL));
condition->setParam(CONDITIONPARAM_SOULTICKS,
(vocation->getGainTicks(GAIN_SOUL) * 1000));
addCondition(condition);
}
}

addExperience((uint64_t)gainExp);
}
}[/cpp]


..
Lua:
function onGainExp(cid, value)
friend = "name"
if getDistanceBetween(cid,getPlayerGUIDByName(friend) <= 5 then
doPlayerAddExp(cid, math.floor(value*1.2)) -- friend players hunting togheter gain 20% more exp from monsters..
end
return true
end

Lua:
function onGainExp(cid, value)
local k,x = storage, value
if getPlayerStorageValue(cid,k) > x then
return false --will not gain exp
end
return true
end
 
Last edited:
you don't need this btw
Code:
case CREATURE_EVENT_GAINEXP:
return "cid, value";
EDIT: Ops, you do need it, for mods :p
 
Last edited:
@up
k.. i'll take a look and add a tag for summons :D

.. creature.cpp
[cpp]void Creature::eek:nGainSharedExperience(double& gainExp, Creature* target, bool multiplied)[/cpp]
change into
[cpp]
void Creature::eek:nGainSharedExperience(double& gainExp, Creature* target, bool multiplied)
{
if(gainExp <= 0)
return;

if(master)
{
gainExp = gainExp / 2;
master->onGainSharedExperience(gainExp, target, multiplied);
}
else if(!multiplied)
{
bool deny = false;
CreatureEventList gainExpEvents = this->getCreatureEvents(CREATURE_EVENT_GAINEXP);
for(CreatureEventList::iterator it = gainExpEvents.begin(); it != gainExpEvents.end(); ++it)
{
if(!(*it)->executeGainExp(this, gainExp))
deny = true;
}
if(deny)
return false;
gainExp *= g_config.getDouble(ConfigManager::RATE_EXPERIENCE);


int16_t color = g_config.getNumber(ConfigManager::EXPERIENCE_COLOR);
if(color < 0)
color = random_range(0, 255);

std::stringstream ss;
ss << (uint64_t)gainExp;
g_game.addAnimatedText(getPosition(), (uint8_t)color, ss.str());
}
}
[/cpp]
also
[cpp]
void Creature::eek:nGainExperience(double& gainExp, Creature* target, bool multiplied)
[/cpp]
into
[cpp]
void Creature::eek:nGainExperience(double& gainExp, Creature* target, bool multiplied)
{
if(gainExp <= 0)
return;

if(master)
{
gainExp = gainExp / 2;
master->onGainExperience(gainExp, target, multiplied);
}
else if(!multiplied)
{
bool deny = false;
CreatureEventList gainExpEvents = this->getCreatureEvents(CREATURE_EVENT_GAINEXP);
for(CreatureEventList::iterator it = gainExpEvents.begin(); it != gainExpEvents.end(); ++it)
{
if(!(*it)->executeGainExp(this, gainExp))
deny = true;
}
if(deny)
return false;
gainExp *= g_config.getDouble(ConfigManager::RATE_EXPERIENCE);

int16_t color = g_config.getNumber(ConfigManager::EXPERIENCE_COLOR);
if(color < 0)
color = random_range(0, 255);

std::stringstream ss;
ss << (uint64_t)gainExp;
g_game.addAnimatedText(getPosition(), (uint8_t)color, ss.str());
}
}
[/cpp]

and the last ones are on creatureevent.cpp & .h

on .cpp changes the hole ongainexp into
[cpp]
uint32_t CreatureEvent::executeGainExp(Creature* creature, int32_t value)
{
//onGainExp(cid, value)
if(m_interface->reserveEnv())
{
ScriptEnviroment* env = m_interface->getEnv();
if(m_scripted == EVENT_SCRIPT_BUFFER)
{
env->setRealPos(creature->getPosition());
std::stringstream scriptstream;

scriptstream << "local cid = " << env->addThing(creature) << std::endl;
scriptstream << "local value = " << value << std::endl;

if(m_scriptData)
scriptstream << *m_scriptData;
bool result = true;
if(m_interface->loadBuffer(scriptstream.str()))
{
lua_State* L = m_interface->getState();
result = m_interface->getGlobalBool(L, "_result", true);
}

m_interface->releaseEnv();
return result;
}
else
{
#ifdef __DEBUG_LUASCRIPTS__
char desc[35];
sprintf(desc, "%s", creature->getName().c_str());
env->setEvent(desc);
#endif

env->setScriptId(m_scriptId, m_interface);
env->setRealPos(creature->getPosition());

lua_State* L = m_interface->getState();
m_interface->pushFunction(m_scriptId);

lua_pushnumber(L, env->addThing(creature));
lua_pushnumber(L, value);

bool result = m_interface->callFunction(2);
m_interface->releaseEnv();
return result;
}
}
else
{
std::clog << "[Error - CreatureEvent::executeGainExp] Call stack overflow." << std::endl;
return 0;
}
}[/cpp]

and also on .h this
[cpp]uint32_t executeGainExp(Creature* creature, int32_t value);[/cpp]
 
Last edited:
@up
k.. i'll take a look and add a tag for summons :D

.. creature.cpp
[cpp]void Creature::eek:nGainSharedExperience(double& gainExp, Creature* target, bool multiplied)[/cpp]
change into
[cpp]
void Creature::eek:nGainSharedExperience(double& gainExp, Creature* target, bool multiplied)
{
if(gainExp <= 0)
return;

if(master)
{
gainExp = gainExp / 2;
master->onGainSharedExperience(gainExp, target, multiplied);
}
else if(!multiplied)
{
bool deny = false;
CreatureEventList gainExpEvents = this->getCreatureEvents(CREATURE_EVENT_GAINEXP);
for(CreatureEventList::iterator it = gainExpEvents.begin(); it != gainExpEvents.end(); ++it)
{
if(!(*it)->executeGainExp(this, gainExp))
deny = true;
}
if(deny)
return false;
gainExp *= g_config.getDouble(ConfigManager::RATE_EXPERIENCE);


int16_t color = g_config.getNumber(ConfigManager::EXPERIENCE_COLOR);
if(color < 0)
color = random_range(0, 255);

std::stringstream ss;
ss << (uint64_t)gainExp;
g_game.addAnimatedText(getPosition(), (uint8_t)color, ss.str());
}
}
[/cpp]
also
[cpp]
void Creature::eek:nGainExperience(double& gainExp, Creature* target, bool multiplied)
[/cpp]
into
[cpp]
void Creature::eek:nGainExperience(double& gainExp, Creature* target, bool multiplied)
{
if(gainExp <= 0)
return;

if(master)
{
gainExp = gainExp / 2;
master->onGainExperience(gainExp, target, multiplied);
}
else if(!multiplied)
{
bool deny = false;
CreatureEventList gainExpEvents = this->getCreatureEvents(CREATURE_EVENT_GAINEXP);
for(CreatureEventList::iterator it = gainExpEvents.begin(); it != gainExpEvents.end(); ++it)
{
if(!(*it)->executeGainExp(this, gainExp))
deny = true;
}
if(deny)
return false;
gainExp *= g_config.getDouble(ConfigManager::RATE_EXPERIENCE);

int16_t color = g_config.getNumber(ConfigManager::EXPERIENCE_COLOR);
if(color < 0)
color = random_range(0, 255);

std::stringstream ss;
ss << (uint64_t)gainExp;
g_game.addAnimatedText(getPosition(), (uint8_t)color, ss.str());
}
}
[/cpp]

and the last ones are on creatureevent.cpp & .h

on .cpp changes the hole ongainexp into
[cpp]
uint32_t CreatureEvent::executeGainExp(Creature* creature, int32_t value)
{
//onGainExp(cid, value)
if(m_interface->reserveEnv())
{
ScriptEnviroment* env = m_interface->getEnv();
if(m_scripted == EVENT_SCRIPT_BUFFER)
{
env->setRealPos(creature->getPosition());
std::stringstream scriptstream;

scriptstream << "local cid = " << env->addThing(creature) << std::endl;
scriptstream << "local value = " << value << std::endl;

if(m_scriptData)
scriptstream << *m_scriptData;
bool result = true;
if(m_interface->loadBuffer(scriptstream.str()))
{
lua_State* L = m_interface->getState();
result = m_interface->getGlobalBool(L, "_result", true);
}

m_interface->releaseEnv();
return result;
}
else
{
#ifdef __DEBUG_LUASCRIPTS__
char desc[35];
sprintf(desc, "%s", creature->getName().c_str());
env->setEvent(desc);
#endif

env->setScriptId(m_scriptId, m_interface);
env->setRealPos(creature->getPosition());

lua_State* L = m_interface->getState();
m_interface->pushFunction(m_scriptId);

lua_pushnumber(L, env->addThing(creature));
lua_pushnumber(L, value);

bool result = m_interface->callFunction(2);
m_interface->releaseEnv();
return result;
}
}
else
{
std::clog << "[Error - CreatureEvent::executeGainExp] Call stack overflow." << std::endl;
return 0;
}
}[/cpp]

and also on .h this
[cpp]uint32_t executeGainExp(Creature* creature, int32_t value);[/cpp]
void functions can't return values, it will throw an error
btw nice release, thanks for sharing
 
that function make player logout when take a hit

=(

i use 0.3.6 version

Help please i have this bug too.
 
Back
Top