• 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!

TFS 1.X+ TFS 1.5 Nekiro Dead player, drop loot and lose bless

bpm91

Intermediate OT User
Joined
May 23, 2019
Messages
879
Solutions
7
Reaction score
122
Location
Brazil
YouTube
caruniawikibr
hello, I recently started using nekiro's tfs 1.5 7.72, but I realized that there are some bugs to be fixed, one of them is death, the player with bless dies and doesn't lose bless,
I also noticed that the loot drop of the player who dies is buggy, sometimes it drops the bag and sometimes it doesn't,
I also realized that after he dies until lvl 7 he doesn't you lose more xp, so you can't go back to rookgard, the other defect is the configlua function.
hotkeyAimbotEnabled = false
this configuration doesn't work, at the moment we talk about 7.72 we can't use hotkey for items, so if anyone knows how to solve this problem I would appreciate it.

I would also like to know how I can change the color of energy from purple to lighter blue. (in source)
I would also like to know how to add the gm outfits, as I have made several attempts but have not had success.

Lua:
worldType = "pvp"
hotkeyAimbotEnabled = false
protectionLevel = 1
killsToRedSkull = 3
killsToBlackSkull = 6
pzLocked = 60000
removeChargesFromRunes = true
removeChargesFromPotions = true
removeWeaponAmmunition = true
removeWeaponCharges = true
timeToDecreaseFrags = 24 * 60 * 60
whiteSkullTime = 15 * 60
stairJumpExhaustion = 2000
experienceByKillingPlayers = false
expFromPlayersLevelRange = 75

-- Connection Config
-- NOTE: maxPlayers set to 0 means no limit
-- NOTE: allowWalkthrough is only applicable to players
ip = "127.0.0.1"
bindOnlyGlobalAddress = false
loginProtocolPort = 7171
gameProtocolPort = 7172
statusProtocolPort = 7171
maxPlayers = 0
motd = "Welcome to The Camora Server!"
onePlayerOnlinePerAccount = true
allowClones = false
allowWalkthrough = true
serverName = "Camora"
statusTimeout = 5000
replaceKickOnLogin = true
maxPacketsPerSecond = 25

-- Deaths
-- NOTE: Leave deathLosePercent as -1 if you want to use the default
-- death penalty formula. For the old formula, set it to 10. For
-- no skill/experience loss, set it to 0.
deathLosePercent = 10

-- Houses
-- NOTE: set housePriceEachSQM to -1 to disable the ingame buy house functionality
-- NOTE: valid values for houseRentPeriod are: "daily", "weekly", "monthly", "yearly"
-- use any other value to disable the rent system
housePriceEachSQM = 1000
houseRentPeriod = "never"
houseOwnedByAccount = false
houseDoorShowPrice = true
onlyInvitedCanMoveHouseItems = true

-- Item Usage
timeBetweenActions = 200
timeBetweenExActions = 1000

-- Map
-- NOTE: set mapName WITHOUT .otbm at the end
mapName = "world"
mapAuthor = "Nekiro"

-- Market
marketOfferDuration = 30 * 24 * 60 * 60
premiumToCreateMarketOffer = true
checkExpiredMarketOffersEachMinutes = 60
maxMarketOffersAtATimePerPlayer = 100

-- MySQL
mysqlHost = "127.0.0.1"
mysqlUser = "root"
mysqlPass = ""
mysqlDatabase = "otserver"
mysqlPort = 3306
mysqlSock = ""

-- Misc.
-- NOTE: classicAttackSpeed set to true makes players constantly attack at regular
-- intervals regardless of other actions such as item (potion) use. This setting
-- may cause high CPU usage with many players and potentially affect performance!
-- NOTE: forceMonsterTypesOnLoad loads all monster types on startup to validate them.
-- You can disable it to save some memory if you don't see any errors at startup.
allowChangeOutfit = true
freePremium = false
kickIdlePlayerAfterMinutes = 15
maxMessageBuffer = 4
emoteSpells = false
classicEquipmentSlots = true
classicAttackSpeed = false
showScriptsLogInConsole = false
showOnlineStatusInCharlist = false
yellMinimumLevel = 2
yellAlwaysAllowPremium = false
minimumLevelToSendPrivate = 1
premiumToSendPrivate = false
forceMonsterTypesOnLoad = true
cleanProtectionZones = false
luaItemDesc = false
showPlayerLogInConsole = true

-- VIP and Depot limits
-- NOTE: you can set custom limits per group in data/XML/groups.xml
vipFreeLimit = 20
vipPremiumLimit = 100
depotFreeLimit = 2000
depotPremiumLimit = 10000

-- World Light
-- NOTE: if defaultWorldLight is set to true the world light algorithm will
-- be handled in the sources. set it to false to avoid conflicts if you wish
-- to make use of the function setWorldLight(level, color)
defaultWorldLight = true

-- Server Save
-- NOTE: serverSaveNotifyDuration in minutes
serverSaveNotifyMessage = true
serverSaveNotifyDuration = 5
serverSaveCleanMap = false
serverSaveClose = false
serverSaveShutdown = true

-- Experience stages
-- NOTE: to use a flat experience multiplier, set experienceStages to nil
-- minlevel and multiplier are MANDATORY
-- maxlevel is OPTIONAL, but is considered infinite by default
-- to disable stages, create a stage with minlevel 1 and no maxlevel
experienceStages = {
    { minlevel = 1, maxlevel = 8, multiplier = 7 },
    { minlevel = 9, maxlevel = 20, multiplier = 6 },
    { minlevel = 21, maxlevel = 50, multiplier = 5 },
    { minlevel = 51, maxlevel = 100, multiplier = 4 },
    { minlevel = 101, multiplier = 3 }
}

-- Rates
-- NOTE: rateExp is not used if you have enabled stages above
rateExp = 5
rateSkill = 3
rateLoot = 2
rateMagic = 300
rateSpawn = 1

-- Monster Despawn Config
-- despawnRange is the amount of floors a monster can be from its spawn position
-- despawnRadius is how many tiles away it can be from its spawn position
-- removeOnDespawn will remove the monster if true or teleport it back to its spawn position if false
-- walkToSpawnRadius is the allowed distance that the monster will stay away from spawn position when left with no targets, 0 to disable
deSpawnRange = 2
deSpawnRadius = 50
removeOnDespawn = true
walkToSpawnRadius = 15

-- Stamina
staminaSystem = false

-- Scripts
warnUnsafeScripts = true
convertUnsafeScripts = true

-- Startup
-- NOTE: defaultPriority only works on Windows and sets process
-- priority, valid values are: "normal", "above-normal", "high"
defaultPriority = "high"
startupDatabaseOptimization = false

-- Status Server Information
ownerName = ""
ownerEmail = ""
url = "https://otland.net/"
location = "Sweden"
 
Solution
bless always existed friend. but now it's a problem to fix it.
@Itutorial showed me this

go player.cpp

change this

C++:
/* if (blessings.test(5)) {
            if (lastHitPlayer) {
                blessings.reset(5);
            } else {
                blessings.reset();
                blessings.set(5);
            }
        } else {
            blessings.reset();
        }*/

to this

C++:
        if (blessings.test(5)) {
            if (lastHitIsPlayer) {
                blessings.reset(5);
            } else {
                blessings.reset();
                blessings.set(5);
            }
        } else {
            blessings.reset();
        }
I have the same issue with blessings in this engine, they are working but they are not reseting in database after dead.
I'm using something like this for custom aol edited by @Itutorial :D

Lua:
local AOL = 2138
local maleCorpse = 3058
local femaleCorpse = 3065
local bloodSplat = 1903

function onPrepareDeath(creature)
    local player = Player(creature)
    if not player then return true end

    local amulet = player:getSlotItem(CONST_SLOT_NECKLACE)
    if not amulet then return true end
    
    if amulet.itemid == AOL then
        local oldPos = player:getPosition()
        player:addHealth(player:getMaxHealth())
        player:addMana(player:getMaxMana())
        player:teleportTo(player:getTown():getTemplePosition())
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Protection amulet saved your life!")
        player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
        amulet:remove()
        
        local blood = Game.createItem(bloodSplat, 1, oldPos)
        blood:decay()
        
        local corpse
        if player:getSex() == 0 then
            corpse = Game.createItem(femaleCorpse, 1, oldPos)
        else
            corpse = Game.createItem(maleCorpse, 1, oldPos)
        end
        corpse:decay()
        return false
    end
    return true
end
 
I have the same issue with blessings in this engine, they are working but they are not reseting in database after dead.
I'm using something like this for custom aol edited by @Itutorial :D

Lua:
local AOL = 2138
local maleCorpse = 3058
local femaleCorpse = 3065
local bloodSplat = 1903

function onPrepareDeath(creature)
    local player = Player(creature)
    if not player then return true end

    local amulet = player:getSlotItem(CONST_SLOT_NECKLACE)
    if not amulet then return true end
   
    if amulet.itemid == AOL then
        local oldPos = player:getPosition()
        player:addHealth(player:getMaxHealth())
        player:addMana(player:getMaxMana())
        player:teleportTo(player:getTown():getTemplePosition())
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Protection amulet saved your life!")
        player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
        amulet:remove()
       
        local blood = Game.createItem(bloodSplat, 1, oldPos)
        blood:decay()
       
        local corpse
        if player:getSex() == 0 then
            corpse = Game.createItem(femaleCorpse, 1, oldPos)
        else
            corpse = Game.createItem(maleCorpse, 1, oldPos)
        end
        corpse:decay()
        return false
    end
    return true
end


in this mechanism, the aol player loses aol, loses bless and when there is no bless, what does he lose?
Post automatically merged:

rooking system is not implemented in any tfs 1.x
how do i implement this system? would you like to do a job?
 
in this mechanism, the aol player loses aol, loses bless and when there is no bless, what does he lose?
Post automatically merged:


how do i implement this system? would you like to do a job?
With you are not losing anyting at all :p
 
I have the same issue with blessings in this engine, they are working but they are not reseting in database after dead.
I'm using something like this for custom aol edited by @Itutorial :D

Lua:
local AOL = 2138
local maleCorpse = 3058
local femaleCorpse = 3065
local bloodSplat = 1903

function onPrepareDeath(creature)
    local player = Player(creature)
    if not player then return true end

    local amulet = player:getSlotItem(CONST_SLOT_NECKLACE)
    if not amulet then return true end
   
    if amulet.itemid == AOL then
        local oldPos = player:getPosition()
        player:addHealth(player:getMaxHealth())
        player:addMana(player:getMaxMana())
        player:teleportTo(player:getTown():getTemplePosition())
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Protection amulet saved your life!")
        player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
        amulet:remove()
       
        local blood = Game.createItem(bloodSplat, 1, oldPos)
        blood:decay()
       
        local corpse
        if player:getSex() == 0 then
            corpse = Game.createItem(femaleCorpse, 1, oldPos)
        else
            corpse = Game.createItem(maleCorpse, 1, oldPos)
        end
        corpse:decay()
        return false
    end
    return true
end

I already discovered the problem, above level 8 it drops things normally, the problem is at lvl 7, I also realized that it doesn't lose blessings regardless of level
 
Its not a problem. He removed blessing code because it didn't exist in 7.72. Just go uncomment it everywhere in the source code to "fix" it.
 
Last edited:
bless always existed friend. but now it's a problem to fix it.
@Itutorial showed me this

go player.cpp

change this

C++:
/* if (blessings.test(5)) {
            if (lastHitPlayer) {
                blessings.reset(5);
            } else {
                blessings.reset();
                blessings.set(5);
            }
        } else {
            blessings.reset();
        }*/

to this

C++:
        if (blessings.test(5)) {
            if (lastHitIsPlayer) {
                blessings.reset(5);
            } else {
                blessings.reset();
                blessings.set(5);
            }
        } else {
            blessings.reset();
        }
 
Solution
@Itutorial showed me this

go player.cpp

change this

C++:
/* if (blessings.test(5)) {
            if (lastHitPlayer) {
                blessings.reset(5);
            } else {
                blessings.reset();
                blessings.set(5);
            }
        } else {
            blessings.reset();
        }*/

to this

C++:
        if (blessings.test(5)) {
            if (lastHitIsPlayer) {
                blessings.reset(5);
            } else {
                blessings.reset();
                blessings.set(5);
            }
        } else {
            blessings.reset();
        }

u are the best :)
 
\player.cpp(2139,8): error C2065: 'lastHitPlayer': not definied if anybody is having problem with this is because you need to declare last hit player and that not the whole code
in order to fix everything change
the code to this. Don't know how to make PR in github so im gonna post the fix here
Lua:
void Player::death(Creature* lastHitCreature)
{
    loginPosition = town->getTemplePosition();

    if (skillLoss) {
        uint8_t unfairFightReduction = 100;
        bool lastHitPlayer = Player::lastHitIsPlayer(lastHitCreature);

        if (lastHitPlayer) {
            uint32_t sumLevels = 0;
            uint32_t inFightTicks = g_config.getNumber(ConfigManager::PZ_LOCKED);
            for (const auto& it : damageMap) {
                CountBlock_t cb = it.second;
                if ((OTSYS_TIME() - cb.ticks) <= inFightTicks) {
                    Player* damageDealer = g_game.getPlayerByID(it.first);
                    if (damageDealer) {
                        sumLevels += damageDealer->getLevel();
                    }
                }
            }

            if (sumLevels > level) {
                double reduce = level / static_cast<double>(sumLevels);
                unfairFightReduction = std::max<uint8_t>(20, std::floor((reduce * 100) + 0.5));
            }
        }

        //Magic level loss
        uint64_t sumMana = 0;
        for (uint32_t i = 1; i <= magLevel; ++i) {
            sumMana += vocation->getReqMana(i);
        }

        //double deathLossPercent = getLostPercent() * (unfairFightReduction / 100.);
        double deathLossPercent = getLostPercent();
        removeManaSpent(static_cast<uint64_t>((sumMana + manaSpent) * deathLossPercent), false);

        //Skill loss
        for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { //for each skill
            uint64_t sumSkillTries = 0;
            for (uint16_t c = MINIMUM_SKILL_LEVEL + 1; c <= skills[i].level; ++c) { //sum up all required tries for all skill levels
                sumSkillTries += vocation->getReqSkillTries(i, c);
            }

            sumSkillTries += skills[i].tries;

            removeSkillTries(static_cast<skills_t>(i), sumSkillTries * deathLossPercent, false);
        }

        //Level loss
        uint64_t expLoss = static_cast<uint64_t>(experience * deathLossPercent);
        g_events->eventPlayerOnLoseExperience(this, expLoss);

        if (expLoss != 0) {
            uint32_t oldLevel = level;

            if (vocation->getId() == VOCATION_NONE || level > 7) {
                experience -= expLoss;
            }

            while (level > 1 && experience < Player::getExpForLevel(level)) {
                --level;
                healthMax = std::max<int32_t>(0, healthMax - vocation->getHPGain());
                manaMax = std::max<int32_t>(0, manaMax - vocation->getManaGain());
                capacity = std::max<int32_t>(0, capacity - vocation->getCapGain());
            }

            if (oldLevel != level) {
                sendTextMessage(MESSAGE_EVENT_ADVANCE, fmt::format("You were downgraded from Level {:d} to Level {:d}.", oldLevel, level));
            }

            uint64_t currLevelExp = Player::getExpForLevel(level);
            uint64_t nextLevelExp = Player::getExpForLevel(level + 1);
            if (nextLevelExp > currLevelExp) {
                levelPercent = Player::getPercentLevel(experience - currLevelExp, nextLevelExp - currLevelExp);
            } else {
                levelPercent = 0;
            }
        }

         if (blessings.test(5)) {
            if (lastHitPlayer) {
                blessings.reset(5);
            } else {
                blessings.reset();
                blessings.set(5);
            }
        } else {
            blessings.reset();
        }

        sendStats();
        sendSkills();
        //sendReLoginWindow(unfairFightReduction);

        /*if (getSkull() == SKULL_BLACK) {
            health = 40;
            mana = 0;
        } else {
            health = healthMax;
            mana = manaMax;
        }*/

        health = healthMax;
        mana = manaMax;

        auto it = conditions.begin(), end = conditions.end();
        while (it != end) {
            Condition* condition = *it;
            if (condition->isPersistent()) {
                it = conditions.erase(it);

                condition->endCondition(this);
                onEndCondition(condition->getType());
                delete condition;
            } else {
                ++it;
            }
        }
    } else {
        setSkillLoss(true);

        auto it = conditions.begin(), end = conditions.end();
        while (it != end) {
            Condition* condition = *it;
            if (condition->isPersistent()) {
                it = conditions.erase(it);

                condition->endCondition(this);
                onEndCondition(condition->getType());
                delete condition;
            } else {
                ++it;
            }
        }

        health = healthMax;
        g_game.internalTeleport(this, getTemplePosition(), true);
        g_game.addCreatureHealth(this);
        onThink(EVENT_CREATURE_THINK_INTERVAL);
        onIdleStatus();
        sendStats();
    }
}
 
Back
Top