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

[OTC & TFS 1.0+] Working Creature Jump function with jumpStraight feature.

Fresh

Quack!
Joined
Oct 21, 2009
Messages
1,837
Solutions
18
Reaction score
615
Location
Poland
Working unused OTC function of creature:jump()
Creature Jump with jumpStraight feature
tested and used on TFS >= 1.0
🎬 P R E V I E W👇
Click to Watch Video!

  • Function:
Lua:
JumpCreature(self, creatureID, jumpHeight, jumpDuration, jumpStraight)
jumpHeight - how many px creature should "jump" up.
jumpDuration - kinda like "speed" of jumping "animation".
jumpStraight - true (1) or false (0) - by default is false, creature will jump isometric ("to north-west"). If you set it to true, creature will jump straightly up (flat). You can see preview of this bool in above video (below thread title).

  • Description:
There's an function (that is unused and a little defective) in default (stock) OTC called creature->jump(jumpHeight, jumpDuration).
I bet that, huge amount of people don't even know that this function already exists. It's needed to be slightly improved by sending and receiving packets server <-> client.
So I done that, added extra "jumpStraight feature" and want to share it with OT community.
Have fun! Hope to see any cool ideas on custom servers with it.




INSTALLATION

Client (OTC) :
protocolcodes.h :: need to order packet for receiving informations from server, my packet there is 54 (0x36), so you need to change it to your "unused" packet.
C++:
ServerCreatureJump             = 54, // 0x36
protocolgame.h :: declaration of packet parsing
C++:
void parseCreatureJump(const InputMessagePtr& msg);
protocolgameparse.cpp :: declaration, paste it somewhere between other "case proto" things:
C++:
            case Proto::ServerCreatureJump:
                parseCreatureJump(msg);
                break;
protocolgameparse.cpp :: function, paste it somewhere between void ProtocolGame functions:
C++:
void ProtocolGame::parseCreatureJump(const InputMessagePtr& msg)
{
    // JumpCreature(self, creatureID, jumpHeight, jumpDuration, jumpStraight (0 (false) / 1 (true)))
    uint id = msg->getU32();
    uint32 jumpHeight = msg->getU32();
    uint32 jumpDuration = msg->getU32();
    bool jumpStraight = msg->getU8();
    CreaturePtr creature = g_map.getCreatureById(id);
    if (creature)
        creature->jump(jumpHeight, jumpDuration, jumpStraight);
    else
        g_logger.traceError(stdext::format("[ParseJumpCreature] :: Could not get creature with id %d", id));
}
creature.cpp :: find existing unused void Creature::jump(int, height, int duration) function and replace it:
C++:
void Creature::jump(int height, int duration, bool jumpStraight)
{
    if(!m_jumpOffset.isNull())
        return;

    m_jumpTimer.restart();
    m_jumpHeight = height;
    m_jumpDuration = duration;
    m_jumpStraight = jumpStraight;

    updateJump();
}
creature.cpp :: find function void Creature::updateJump() and replace it:
C++:
void Creature::updateJump()
{
    int t = m_jumpTimer.ticksElapsed();
    double a = -4 * m_jumpHeight / (m_jumpDuration * m_jumpDuration);
    double b = +4 * m_jumpHeight / (m_jumpDuration);

    double height = a*t*t + b*t;
    int roundHeight = stdext::round(height);
    int halfJumpDuration = m_jumpDuration / 2;

    // schedules next update
    if(m_jumpTimer.ticksElapsed() < m_jumpDuration) {
        if (m_jumpStraight) {
        m_jumpOffset = PointF(0, height);
        } else {
        m_jumpOffset = PointF(height, height);
        }

        int diff = 0;
        if(m_jumpTimer.ticksElapsed() < halfJumpDuration)
            diff = 1;
        else if(m_jumpTimer.ticksElapsed() > halfJumpDuration)
            diff = -1;

        int nextT, i = 1;
        do {
            nextT = stdext::round((-b + std::sqrt(std::max<double>(b*b + 4*a*(roundHeight+diff*i), 0.0)) * diff) / (2*a));
            ++i;

            if(nextT < halfJumpDuration)
                diff = 1;
            else if(nextT > halfJumpDuration)
                diff = -1;
        } while(nextT - m_jumpTimer.ticksElapsed() == 0 && i < 3);

        auto self = static_self_cast<Creature>();
        g_dispatcher.scheduleEvent([self] {
            self->updateJump();
        }, nextT - m_jumpTimer.ticksElapsed());
    }
    else
        m_jumpOffset = PointF(0, 0);
}
creature.h :: Declare m_jumpStraight , add it somewhere between "jump related" declarations, for example under: Timer m_jumpTimer
C++:
stdext::boolean<true> m_jumpStraight;

Server Side :
If you have TFS that can handle packet sending in LUA (data/lib/core/player.lua) you can add it there in
data/lib/core/player.lua :
Lua:
function Player.JumpCreature(self, creatureID, jumpHeight, jumpDuration, jumpStraight)
    local networkMessage = NetworkMessage()
    networkMessage:addByte(0x36) -- 54 : OTC
    networkMessage:addU32(creatureID)
    networkMessage:addU32(jumpHeight)
    networkMessage:addU32(jumpDuration)
    networkMessage:addByte(jumpStraight)
    networkMessage:sendToPlayer(self)
    networkMessage:delete()
    return true
end
otherwise you need to do it in sources, protocolgame etc.




Example Usage : ( for testing purposes talkaction ) :: Preview 👉 Click to Watch Video!

Lua:
function onSay(player, words, param)

    local AreaX = 13 -- X range who will receive "jump packet" (all players in X range)
    local AreaY = 8 -- Y range who will receive "jump packet" (all players in Y range)

    -- getting Spectators around person who used jump
    local spectators = Game.getSpectators(player:getPosition(), false, true, AreaX, AreaX, AreaY, AreaY)
    if #spectators == 0 then
        return nil
    end

    -- Release of function // JumpCreature (self, creatureID, jumpHeight, jumpDuration, jumpStraight(true or false))
    for index, spectator in ipairs(spectators) do
        if spectator:getId() ~= player then
            playerID = player:getId()
            spectator:JumpCreature(playerID,100,1000,1)
        end
    end

    return true
end
 
Last edited:
Thanks, an little idea for what this function can be ;)
[ If not playing automatically -> Click on image to play/watch ]
This is exactly what i was gonna use it for (knockup), maybe there is even more stuff to do with it but i cant think about anything else for now case im tunneled for the knockup now ;p

But again thank you for sharing that code u are awesome !
 
Nice release. I like it, nice math too btw XD
 
Worked like a charm, thanks. Missed
replacing void Creature::jump(int height, int duration)
for void Creature::jump(int height, int duration, bool jumpStraight)
on creature.cpp.
 
Back
Top