mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-05-28 05:54:29 +02:00
introduce offline training scripts
This commit is contained in:
parent
093ac51d31
commit
33d9dd7dcd
@ -1,6 +1,6 @@
|
||||
-- Custom
|
||||
knightCloseAttackDamageIncreasePercent = 50
|
||||
paladinRangeAttackDamageIncreasePercent = 40
|
||||
knightCloseAttackDamageIncreasePercent = 20
|
||||
paladinRangeAttackDamageIncreasePercent = 15
|
||||
|
||||
-- Combat settings
|
||||
-- NOTE: valid values for worldType are: "pvp", "no-pvp" and "pvp-enforced"
|
||||
|
@ -239,6 +239,7 @@
|
||||
<action itemid="3031" script="misc/changegold.lua" />
|
||||
<action itemid="3035" script="misc/changegold.lua" />
|
||||
<action itemid="3043" script="misc/changegold.lua" />
|
||||
<action fromid="2032" toid="2032" script="misc/skill_trainer.lua" />
|
||||
|
||||
<!-- Chests -->
|
||||
<action itemid="2479" script="misc/chests.lua" />
|
||||
|
23
data/actions/scripts/misc/skill_trainer.lua
Normal file
23
data/actions/scripts/misc/skill_trainer.lua
Normal file
@ -0,0 +1,23 @@
|
||||
local statues = {
|
||||
[2032] = SKILL_SWORD,
|
||||
[18489] = SKILL_AXE,
|
||||
[18490] = SKILL_CLUB,
|
||||
[18491] = SKILL_DISTANCE,
|
||||
[18492] = SKILL_MAGLEVEL
|
||||
}
|
||||
|
||||
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
|
||||
local skill = statues[item:getId()]
|
||||
if not player:isPremium() then
|
||||
player:sendCancelMessage(RETURNVALUE_YOUNEEDPREMIUMACCOUNT)
|
||||
return true
|
||||
end
|
||||
|
||||
if player:isPzLocked() then
|
||||
return false
|
||||
end
|
||||
|
||||
player:setOfflineTrainingSkill(skill)
|
||||
player:remove()
|
||||
return true
|
||||
end
|
@ -6,7 +6,8 @@
|
||||
<event type="login" name="FirstItems" script="firstitems.lua"/>
|
||||
<event type="login" name="RegenerateStamina" script="regeneratestamina.lua" />
|
||||
<event type="death" name="PlayerDeath" script="playerdeath.lua"/>
|
||||
|
||||
<event type="login" name="OfflineTraining" script="offlinetraining.lua" />
|
||||
|
||||
<!-- Killing In The Name Of Quest -->
|
||||
<event type="kill" name="KillingInTheNameOfKills" script="killing_in_the_name_of.lua" />
|
||||
</creaturescripts>
|
||||
|
75
data/creaturescripts/scripts/offlinetraining.lua
Normal file
75
data/creaturescripts/scripts/offlinetraining.lua
Normal file
@ -0,0 +1,75 @@
|
||||
function onLogin(player)
|
||||
local lastLogout = player:getLastLogout()
|
||||
local offlineTime = lastLogout ~= 0 and math.min(os.time() - lastLogout, 86400 * 21) or 0
|
||||
local offlineTrainingSkill = player:getOfflineTrainingSkill()
|
||||
if offlineTrainingSkill == -1 then
|
||||
player:addOfflineTrainingTime(offlineTime * 1000)
|
||||
return true
|
||||
end
|
||||
|
||||
player:setOfflineTrainingSkill(-1)
|
||||
|
||||
if offlineTime < 600 then
|
||||
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You must be logged out for more than 10 minutes to start offline training.")
|
||||
return true
|
||||
end
|
||||
|
||||
local trainingTime = math.max(0, math.min(offlineTime, math.min(43200, player:getOfflineTrainingTime() / 1000)))
|
||||
player:removeOfflineTrainingTime(trainingTime * 1000)
|
||||
|
||||
local remainder = offlineTime - trainingTime
|
||||
if remainder > 0 then
|
||||
player:addOfflineTrainingTime(remainder * 1000)
|
||||
end
|
||||
|
||||
if trainingTime < 60 then
|
||||
return true
|
||||
end
|
||||
|
||||
local text = "During your absence you trained for"
|
||||
local hours = math.floor(trainingTime / 3600)
|
||||
if hours > 1 then
|
||||
text = string.format("%s %d hours", text, hours)
|
||||
elseif hours == 1 then
|
||||
text = string.format("%s 1 hour", text)
|
||||
end
|
||||
|
||||
local minutes = math.floor((trainingTime % 3600) / 60)
|
||||
if minutes ~= 0 then
|
||||
if hours ~= 0 then
|
||||
text = string.format("%s and", text)
|
||||
end
|
||||
|
||||
if minutes > 1 then
|
||||
text = string.format("%s %d minutes", text, minutes)
|
||||
else
|
||||
text = string.format("%s 1 minute", text)
|
||||
end
|
||||
end
|
||||
|
||||
text = string.format("%s.", text)
|
||||
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, text)
|
||||
|
||||
local vocation = player:getVocation()
|
||||
local promotion = vocation:getPromotion()
|
||||
local topVocation = not promotion and vocation or promotion
|
||||
|
||||
local updateSkills = false
|
||||
if table.contains({SKILL_CLUB, SKILL_SWORD, SKILL_AXE, SKILL_DISTANCE}, offlineTrainingSkill) then
|
||||
local modifier = topVocation:getAttackSpeed() / 1000
|
||||
updateSkills = player:addOfflineTrainingTries(offlineTrainingSkill, (trainingTime / modifier) / (offlineTrainingSkill == SKILL_DISTANCE and 4 or 2))
|
||||
elseif offlineTrainingSkill == SKILL_MAGLEVEL then
|
||||
local gainTicks = topVocation:getManaGainTicks() * 2
|
||||
if gainTicks == 0 then
|
||||
gainTicks = 1
|
||||
end
|
||||
|
||||
updateSkills = player:addOfflineTrainingTries(SKILL_MAGLEVEL, trainingTime * (vocation:getManaGainAmount() / gainTicks))
|
||||
end
|
||||
|
||||
if updateSkills then
|
||||
player:addOfflineTrainingTries(SKILL_SHIELD, trainingTime / 4)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
@ -372,6 +372,7 @@ function setPlayerGroupId(cid, groupId) local p = Player(cid) return p ~= nil an
|
||||
function doPlayerSetSex(cid, sex) local p = Player(cid) return p ~= nil and p:setSex(sex) or false end
|
||||
function doPlayerSetGuildLevel(cid, level) local p = Player(cid) return p ~= nil and p:setGuildLevel(level) or false end
|
||||
function doPlayerSetGuildNick(cid, nick) local p = Player(cid) return p ~= nil and p:setGuildNick(nick) or false end
|
||||
function doPlayerSetOfflineTrainingSkill(cid, skillId) local p = Player(cid) return p and p:setOfflineTrainingSkill(skillId) or false end
|
||||
function doShowTextDialog(cid, itemId, text) local p = Player(cid) return p ~= nil and p:showTextDialog(itemId, text) or false end
|
||||
function doPlayerAddItemEx(cid, uid, ...) local p = Player(cid) return p ~= nil and p:addItemEx(Item(uid), ...) or false end
|
||||
function doPlayerRemoveItem(cid, itemid, count, ...) local p = Player(cid) return p ~= nil and p:removeItem(itemid, count, ...) or false end
|
||||
|
@ -1138,6 +1138,8 @@ CREATE TABLE `players` (
|
||||
`onlinetime` int(11) NOT NULL DEFAULT '0',
|
||||
`deletion` bigint(15) NOT NULL DEFAULT '0',
|
||||
`balance` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`offlinetraining_time` smallint(5) unsigned NOT NULL DEFAULT '43200',
|
||||
`offlinetraining_skill` int(11) NOT NULL DEFAULT '-1',
|
||||
`stamina` smallint(5) NOT NULL DEFAULT '3360',
|
||||
`skill_fist` int(10) UNSIGNED NOT NULL DEFAULT '10',
|
||||
`skill_fist_tries` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
|
||||
|
@ -190,7 +190,7 @@ bool IOLoginData::preloadPlayer(Player* player, const std::string& name)
|
||||
bool IOLoginData::loadPlayerById(Player* player, uint32_t id)
|
||||
{
|
||||
std::ostringstream query;
|
||||
query << "SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `blessings`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `skulltime`, `skull`, `town_id`, `balance`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries` FROM `players` WHERE `id` = " << id;
|
||||
query << "SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `blessings`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `skulltime`, `skull`, `town_id`, `balance`, `offlinetraining_time`, `offlinetraining_skill`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries` FROM `players` WHERE `id` = " << id;
|
||||
return loadPlayer(player, Database::getInstance()->storeQuery(query.str()));
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ bool IOLoginData::loadPlayerByName(Player* player, const std::string& name)
|
||||
{
|
||||
Database* db = Database::getInstance();
|
||||
std::ostringstream query;
|
||||
query << "SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `blessings`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `skulltime`, `skull`, `town_id`, `balance`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries` FROM `players` WHERE `name` = " << db->escapeString(name);
|
||||
query << "SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `blessings`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `skulltime`, `skull`, `town_id`, `balance`, `offlinetraining_time`, `offlinetraining_skill`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries` FROM `players` WHERE `name` = " << db->escapeString(name);
|
||||
return loadPlayer(player, db->storeQuery(query.str()));
|
||||
}
|
||||
|
||||
@ -321,6 +321,9 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result)
|
||||
player->lastLoginSaved = result->getNumber<time_t>("lastlogin");
|
||||
player->lastLogout = result->getNumber<time_t>("lastlogout");
|
||||
|
||||
player->offlineTrainingTime = result->getNumber<int32_t>("offlinetraining_time") * 1000;
|
||||
player->offlineTrainingSkill = result->getNumber<int32_t>("offlinetraining_skill");
|
||||
|
||||
Town* town = g_game.map.towns.getTown(result->getNumber<uint32_t>("town_id"));
|
||||
if (!town) {
|
||||
std::cout << "[Error - IOLoginData::loadPlayer] " << player->name << " has Town ID " << result->getNumber<uint32_t>("town_id") << " which doesn't exist" << std::endl;
|
||||
@ -660,6 +663,8 @@ bool IOLoginData::savePlayer(Player* player)
|
||||
|
||||
query << "`lastlogout` = " << player->getLastLogout() << ',';
|
||||
query << "`balance` = " << player->bankBalance << ',';
|
||||
query << "`offlinetraining_time` = " << player->getOfflineTrainingTime() / 1000 << ',';
|
||||
query << "`offlinetraining_skill` = " << player->getOfflineTrainingSkill() << ',';
|
||||
query << "`stamina` = " << player->getStaminaMinutes() << ',';
|
||||
|
||||
query << "`skill_fist` = " << player->skills[SKILL_FIST].level << ',';
|
||||
|
@ -2008,6 +2008,15 @@ void LuaScriptInterface::registerFunctions()
|
||||
registerMethod("Player", "getSkillTries", LuaScriptInterface::luaPlayerGetSkillTries);
|
||||
registerMethod("Player", "addSkillTries", LuaScriptInterface::luaPlayerAddSkillTries);
|
||||
|
||||
registerMethod("Player", "addOfflineTrainingTime", LuaScriptInterface::luaPlayerAddOfflineTrainingTime);
|
||||
registerMethod("Player", "getOfflineTrainingTime", LuaScriptInterface::luaPlayerGetOfflineTrainingTime);
|
||||
registerMethod("Player", "removeOfflineTrainingTime", LuaScriptInterface::luaPlayerRemoveOfflineTrainingTime);
|
||||
|
||||
registerMethod("Player", "addOfflineTrainingTries", LuaScriptInterface::luaPlayerAddOfflineTrainingTries);
|
||||
|
||||
registerMethod("Player", "getOfflineTrainingSkill", LuaScriptInterface::luaPlayerGetOfflineTrainingSkill);
|
||||
registerMethod("Player", "setOfflineTrainingSkill", LuaScriptInterface::luaPlayerSetOfflineTrainingSkill);
|
||||
|
||||
registerMethod("Player", "getItemCount", LuaScriptInterface::luaPlayerGetItemCount);
|
||||
registerMethod("Player", "getItemById", LuaScriptInterface::luaPlayerGetItemById);
|
||||
|
||||
@ -7530,6 +7539,95 @@ int LuaScriptInterface::luaPlayerAddSkillTries(lua_State* L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::luaPlayerAddOfflineTrainingTime(lua_State* L)
|
||||
{
|
||||
// player:addOfflineTrainingTime(time)
|
||||
Player* player = getUserdata<Player>(L, 1);
|
||||
if (player) {
|
||||
int32_t time = getNumber<int32_t>(L, 2);
|
||||
player->addOfflineTrainingTime(time);
|
||||
player->sendStats();
|
||||
pushBoolean(L, true);
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int LuaScriptInterface::luaPlayerGetOfflineTrainingTime(lua_State* L)
|
||||
{
|
||||
// player:getOfflineTrainingTime()
|
||||
Player* player = getUserdata<Player>(L, 1);
|
||||
if (player) {
|
||||
lua_pushnumber(L, player->getOfflineTrainingTime());
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::luaPlayerRemoveOfflineTrainingTime(lua_State* L)
|
||||
{
|
||||
// player:removeOfflineTrainingTime(time)
|
||||
Player* player = getUserdata<Player>(L, 1);
|
||||
if (player) {
|
||||
int32_t time = getNumber<int32_t>(L, 2);
|
||||
player->removeOfflineTrainingTime(time);
|
||||
player->sendStats();
|
||||
pushBoolean(L, true);
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::luaPlayerAddOfflineTrainingTries(lua_State* L)
|
||||
{
|
||||
// player:addOfflineTrainingTries(skillType, tries)
|
||||
Player* player = getUserdata<Player>(L, 1);
|
||||
if (player) {
|
||||
skills_t skillType = getNumber<skills_t>(L, 2);
|
||||
uint64_t tries = getNumber<uint64_t>(L, 3);
|
||||
pushBoolean(L, player->addOfflineTrainingTries(skillType, tries));
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::luaPlayerGetOfflineTrainingSkill(lua_State* L)
|
||||
{
|
||||
// player:getOfflineTrainingSkill()
|
||||
Player* player = getUserdata<Player>(L, 1);
|
||||
if (player) {
|
||||
lua_pushnumber(L, player->getOfflineTrainingSkill());
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::luaPlayerSetOfflineTrainingSkill(lua_State* L)
|
||||
{
|
||||
// player:setOfflineTrainingSkill(skillId)
|
||||
Player* player = getUserdata<Player>(L, 1);
|
||||
if (player) {
|
||||
uint32_t skillId = getNumber<uint32_t>(L, 2);
|
||||
player->setOfflineTrainingSkill(skillId);
|
||||
pushBoolean(L, true);
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::luaPlayerGetItemCount(lua_State* L)
|
||||
{
|
||||
// player:getItemCount(itemId[, subType = -1])
|
||||
|
@ -833,6 +833,15 @@ class LuaScriptInterface
|
||||
static int luaPlayerGetSkillTries(lua_State* L);
|
||||
static int luaPlayerAddSkillTries(lua_State* L);
|
||||
|
||||
static int luaPlayerAddOfflineTrainingTime(lua_State* L);
|
||||
static int luaPlayerGetOfflineTrainingTime(lua_State* L);
|
||||
static int luaPlayerRemoveOfflineTrainingTime(lua_State* L);
|
||||
|
||||
static int luaPlayerAddOfflineTrainingTries(lua_State* L);
|
||||
|
||||
static int luaPlayerGetOfflineTrainingSkill(lua_State* L);
|
||||
static int luaPlayerSetOfflineTrainingSkill(lua_State* L);
|
||||
|
||||
static int luaPlayerGetItemCount(lua_State* L);
|
||||
static int luaPlayerGetItemById(lua_State* L);
|
||||
|
||||
|
137
src/player.cpp
137
src/player.cpp
@ -1194,6 +1194,8 @@ void Player::onThink(uint32_t interval)
|
||||
if (g_game.getWorldType() != WORLD_TYPE_PVP_ENFORCED) {
|
||||
checkSkullTicks();
|
||||
}
|
||||
|
||||
addOfflineTrainingTime(interval);
|
||||
}
|
||||
|
||||
uint32_t Player::isMuted() const
|
||||
@ -3737,6 +3739,141 @@ void Player::sendClosePrivate(uint16_t channelId)
|
||||
}
|
||||
}
|
||||
|
||||
bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries)
|
||||
{
|
||||
if (tries == 0 || skill == SKILL_LEVEL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sendUpdate = false;
|
||||
uint32_t oldSkillValue, newSkillValue;
|
||||
long double oldPercentToNextLevel, newPercentToNextLevel;
|
||||
|
||||
if (skill == SKILL_MAGLEVEL) {
|
||||
uint64_t currReqMana = vocation->getReqMana(magLevel);
|
||||
uint64_t nextReqMana = vocation->getReqMana(magLevel + 1);
|
||||
|
||||
if (currReqMana >= nextReqMana) {
|
||||
return false;
|
||||
}
|
||||
|
||||
oldSkillValue = magLevel;
|
||||
oldPercentToNextLevel = static_cast<long double>(manaSpent * 100) / nextReqMana;
|
||||
|
||||
g_events->eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, tries);
|
||||
uint32_t currMagLevel = magLevel;
|
||||
|
||||
while ((manaSpent + tries) >= nextReqMana) {
|
||||
tries -= nextReqMana - manaSpent;
|
||||
|
||||
magLevel++;
|
||||
manaSpent = 0;
|
||||
|
||||
g_creatureEvents->playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel);
|
||||
|
||||
sendUpdate = true;
|
||||
currReqMana = nextReqMana;
|
||||
nextReqMana = vocation->getReqMana(magLevel + 1);
|
||||
|
||||
if (currReqMana >= nextReqMana) {
|
||||
tries = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
manaSpent += tries;
|
||||
|
||||
if (magLevel != currMagLevel) {
|
||||
std::ostringstream ss;
|
||||
ss << "You advanced to magic level " << magLevel << '.';
|
||||
sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str());
|
||||
}
|
||||
|
||||
uint8_t newPercent;
|
||||
if (nextReqMana > currReqMana) {
|
||||
newPercent = Player::getPercentLevel(manaSpent, nextReqMana);
|
||||
newPercentToNextLevel = static_cast<long double>(manaSpent * 100) / nextReqMana;
|
||||
}
|
||||
else {
|
||||
newPercent = 0;
|
||||
newPercentToNextLevel = 0;
|
||||
}
|
||||
|
||||
if (newPercent != magLevelPercent) {
|
||||
magLevelPercent = newPercent;
|
||||
sendUpdate = true;
|
||||
}
|
||||
|
||||
newSkillValue = magLevel;
|
||||
}
|
||||
else {
|
||||
uint64_t currReqTries = vocation->getReqSkillTries(skill, skills[skill].level);
|
||||
uint64_t nextReqTries = vocation->getReqSkillTries(skill, skills[skill].level + 1);
|
||||
if (currReqTries >= nextReqTries) {
|
||||
return false;
|
||||
}
|
||||
|
||||
oldSkillValue = skills[skill].level;
|
||||
oldPercentToNextLevel = static_cast<long double>(skills[skill].tries * 100) / nextReqTries;
|
||||
|
||||
g_events->eventPlayerOnGainSkillTries(this, skill, tries);
|
||||
uint32_t currSkillLevel = skills[skill].level;
|
||||
|
||||
while ((skills[skill].tries + tries) >= nextReqTries) {
|
||||
tries -= nextReqTries - skills[skill].tries;
|
||||
|
||||
skills[skill].level++;
|
||||
skills[skill].tries = 0;
|
||||
skills[skill].percent = 0;
|
||||
|
||||
g_creatureEvents->playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level);
|
||||
|
||||
sendUpdate = true;
|
||||
currReqTries = nextReqTries;
|
||||
nextReqTries = vocation->getReqSkillTries(skill, skills[skill].level + 1);
|
||||
|
||||
if (currReqTries >= nextReqTries) {
|
||||
tries = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
skills[skill].tries += tries;
|
||||
|
||||
if (currSkillLevel != skills[skill].level) {
|
||||
std::ostringstream ss;
|
||||
ss << "You advanced to " << getSkillName(skill) << " level " << skills[skill].level << '.';
|
||||
sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str());
|
||||
}
|
||||
|
||||
uint8_t newPercent;
|
||||
if (nextReqTries > currReqTries) {
|
||||
newPercent = Player::getPercentLevel(skills[skill].tries, nextReqTries);
|
||||
newPercentToNextLevel = static_cast<long double>(skills[skill].tries * 100) / nextReqTries;
|
||||
}
|
||||
else {
|
||||
newPercent = 0;
|
||||
newPercentToNextLevel = 0;
|
||||
}
|
||||
|
||||
if (skills[skill].percent != newPercent) {
|
||||
skills[skill].percent = newPercent;
|
||||
sendUpdate = true;
|
||||
}
|
||||
|
||||
newSkillValue = skills[skill].level;
|
||||
}
|
||||
|
||||
if (sendUpdate) {
|
||||
sendSkills();
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << std::fixed << std::setprecision(2) << "Your " << ucwords(getSkillName(skill)) << " skill changed from level " << oldSkillValue << " (with " << oldPercentToNextLevel << "% progress towards level " << (oldSkillValue + 1) << ") to level " << newSkillValue << " (with " << newPercentToNextLevel << "% progress towards level " << (newSkillValue + 1) << ')';
|
||||
sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str());
|
||||
return sendUpdate;
|
||||
}
|
||||
|
||||
uint64_t Player::getMoney() const
|
||||
{
|
||||
std::vector<const Container*> containers;
|
||||
|
21
src/player.h
21
src/player.h
@ -154,6 +154,25 @@ class Player final : public Creature, public Cylinder
|
||||
return staminaMinutes;
|
||||
}
|
||||
|
||||
bool addOfflineTrainingTries(skills_t skill, uint64_t tries);
|
||||
|
||||
void addOfflineTrainingTime(int32_t addTime) {
|
||||
offlineTrainingTime = std::min<int32_t>(12 * 3600 * 1000, offlineTrainingTime + addTime);
|
||||
}
|
||||
void removeOfflineTrainingTime(int32_t removeTime) {
|
||||
offlineTrainingTime = std::max<int32_t>(0, offlineTrainingTime - removeTime);
|
||||
}
|
||||
int32_t getOfflineTrainingTime() const {
|
||||
return offlineTrainingTime;
|
||||
}
|
||||
|
||||
int32_t getOfflineTrainingSkill() const {
|
||||
return offlineTrainingSkill;
|
||||
}
|
||||
void setOfflineTrainingSkill(int32_t skill) {
|
||||
offlineTrainingSkill = skill;
|
||||
}
|
||||
|
||||
uint64_t getBankBalance() const {
|
||||
return bankBalance;
|
||||
}
|
||||
@ -1069,6 +1088,8 @@ class Player final : public Creature, public Cylinder
|
||||
int32_t premiumDays = 0;
|
||||
int32_t bloodHitCount = 0;
|
||||
int32_t shieldBlockCount = 0;
|
||||
int32_t offlineTrainingSkill = -1;
|
||||
int32_t offlineTrainingTime = 0;
|
||||
int32_t idleTime = 0;
|
||||
int32_t lastWalkingTime = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user