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

Otclient runes target behaviour in stack (uh trap)

Terotrificy

Veteran OT User
Joined
Oct 18, 2020
Messages
401
Solutions
13
Reaction score
254
Location
Santiago, Chile.
I'm working in uh trap for 7.4 mechanics server (7.72 server). I tried with two different otclients on my server and every otclient have different behaviour when hitting creatures or players stacked in the same tile.
The 7.72 otclient hits the whole players in the stack when using hmm i.e, but when i use the Mehah 1.0 otclient i hit only the player on top of the stack.
The behaviour standing in the stack with uh or ih runes is totally different too.
I tried changing the modules for both clients but it maintain the behaviour so it's not a module issue but a source issue. Anyone know where can i modify this behaviour? Thanks.
 
Solution
Well so far nobody answered so here i go:

I couldn't handle things from otclient so i did it in server-side.
In order to fix the problem of hitting the first creature in the stack (on bottom) instead of the last creature on stack (on top, how it is supposed to be in 7.4) i just reversed the result of this iterator in tile.cpp


Code:
Creature* Tile::getTopCreature()
{
    if(CreatureVector* creatures = getCreatures()){
        if(!creatures->empty()){
            return *creatures->rbegin(); // Here i changed "begin()" for "rbegin()".
        }
    }


    return NULL;
}


After this change, you can heal-damage anyone on top of the stack, but only the runes in scripts that have the
setCombatParam(combat...
Thank for the help but thats not what i am asking for, i want to keep my client but edit the sources to the behaviour i want, no clue what file in the sources does the job tho.
 
Well so far nobody answered so here i go:

I couldn't handle things from otclient so i did it in server-side.
In order to fix the problem of hitting the first creature in the stack (on bottom) instead of the last creature on stack (on top, how it is supposed to be in 7.4) i just reversed the result of this iterator in tile.cpp


Code:
Creature* Tile::getTopCreature()
{
    if(CreatureVector* creatures = getCreatures()){
        if(!creatures->empty()){
            return *creatures->rbegin(); // Here i changed "begin()" for "rbegin()".
        }
    }


    return NULL;
}


After this change, you can heal-damage anyone on top of the stack, but only the runes in scripts that have the
setCombatParam(combat, COMBAT_PARAM_TARGETCASTERORTOPMOST, 1) (any number above 0 enables this feature) makes you heal/damage the creature on top on the stack, the rest of the runes that doesn't have this combat param in the script just hit everyone on the stack.

It works fine if you're not in the stack, but the problem with this feature is regardness of being on bottom or top of the stack, if you're in the stack you heal yourself no matter what. To change this to the 7.4 behaviour (heal yourself only if you're the one in the top), you need commit this lines in combat.cpp:


Lua:
if(params.targetCasterOrTopMost){
/*                         if(caster && caster->getTile() == iter_tile){  -- Commented lines to disable priority of caster in stack for healing purposes.
                            if(*cit == caster){
                                bContinue = false;
                            }
                        } 
                         else  */if(*cit == iter_tile->getTopCreature()){
                            bContinue = false;
                        }

In that way, you have most of your 7.4 uh trap working.

What is left: At the momment you can use any rune that doesn't have that parameter in the script in a stack and you hit everyone, but if you use any other rune without that param, you hit everyone in the stack regardness of your position inside the stack. If you set all runes with that parameter (i.e hmm or sd) you will hit only the person on top of the stack (back then in 7.4 you could hit everyone with 1 shoot, but you couldn't shot if you were on top of the stack).

That's all, i hope someone can help me out with the other parameter or figure out how to fix what is left. I'm using Othire 1.0 and 7.72 client from here:
 
Last edited:
Solution
Well so far nobody answered so here i go:

I couldn't handle things from otclient so i did it in server-side.
In order to fix the problem of hitting the first creature in the stack (on bottom) instead of the last creature on stack (on top, how it is supposed to be in 7.4) i just reversed the result of this iterator in tile.cpp


Code:
Creature* Tile::getTopCreature()
{
    if(CreatureVector* creatures = getCreatures()){
        if(!creatures->empty()){
            return *creatures->rbegin(); // Here i changed "begin()" for "rbegin()".
        }
    }


    return NULL;
}


After this change, you can heal-damage anyone on top of the stack, but only the runes in scripts that have the
setCombatParam(combat, COMBAT_PARAM_TARGETCASTERORTOPMOST, 1) (any number above 0 enables this feature) makes you heal/damage the creature on top on the stack, the rest of the runes that doesn't have this combat param in the script just hit everyone on the stack.

It works fine if you're not in the stack, but the problem with this feature is regardness of being on bottom or top of the stack, if you're in the stack you heal yourself no matter what. To change this to the 7.4 behaviour (heal yourself only if you're the one in the top), you need commit this lines in combat.cpp:


Lua:
if(params.targetCasterOrTopMost){
/*                         if(caster && caster->getTile() == iter_tile){  -- Commented lines to disable priority of caster in stack for healing purposes.
                            if(*cit == caster){
                                bContinue = false;
                            }
                        }
                         else  */if(*cit == iter_tile->getTopCreature()){
                            bContinue = false;
                        }

In that way, you have most of your 7.4 uh trap working.

What is left: At the momment you can use any rune that doesn't have that parameter in the script in a stack and you hit everyone, but if you use any other rune without that param, you hit everyone in the stack regardness of your position inside the stack. If you set all runes with that parameter (i.e hmm or sd) you will hit only the person on top of the stack (back then in 7.4 you could hit everyone with 1 shoot, but you couldn't shot if you were on top of the stack).

That's all, i hope someone can help me out with the other parameter or figure out how to fix what is left. I'm using Othire 1.0 and 7.72 client from here:
do you have parcel block height stack block code ( code to block two stacked parcel or boxes etc )
 
Well so far nobody answered so here i go:

I couldn't handle things from otclient so i did it in server-side.
In order to fix the problem of hitting the first creature in the stack (on bottom) instead of the last creature on stack (on top, how it is supposed to be in 7.4) i just reversed the result of this iterator in tile.cpp


Code:
Creature* Tile::getTopCreature()
{
    if(CreatureVector* creatures = getCreatures()){
        if(!creatures->empty()){
            return *creatures->rbegin(); // Here i changed "begin()" for "rbegin()".
        }
    }


    return NULL;
}


After this change, you can heal-damage anyone on top of the stack, but only the runes in scripts that have the
setCombatParam(combat, COMBAT_PARAM_TARGETCASTERORTOPMOST, 1) (any number above 0 enables this feature) makes you heal/damage the creature on top on the stack, the rest of the runes that doesn't have this combat param in the script just hit everyone on the stack.

It works fine if you're not in the stack, but the problem with this feature is regardness of being on bottom or top of the stack, if you're in the stack you heal yourself no matter what. To change this to the 7.4 behaviour (heal yourself only if you're the one in the top), you need commit this lines in combat.cpp:


Lua:
if(params.targetCasterOrTopMost){
/*                         if(caster && caster->getTile() == iter_tile){  -- Commented lines to disable priority of caster in stack for healing purposes.
                            if(*cit == caster){
                                bContinue = false;
                            }
                        }
                         else  */if(*cit == iter_tile->getTopCreature()){
                            bContinue = false;
                        }

In that way, you have most of your 7.4 uh trap working.

What is left: At the momment you can use any rune that doesn't have that parameter in the script in a stack and you hit everyone, but if you use any other rune without that param, you hit everyone in the stack regardness of your position inside the stack. If you set all runes with that parameter (i.e hmm or sd) you will hit only the person on top of the stack (back then in 7.4 you could hit everyone with 1 shoot, but you couldn't shot if you were on top of the stack).

That's all, i hope someone can help me out with the other parameter or figure out how to fix what is left. I'm using Othire 1.0 and 7.72 client from here:
Thanks gonna check if this is ok in nekiro's 7.72
 
Well so far nobody answered so here i go:

I couldn't handle things from otclient so i did it in server-side.
In order to fix the problem of hitting the first creature in the stack (on bottom) instead of the last creature on stack (on top, how it is supposed to be in 7.4) i just reversed the result of this iterator in tile.cpp


Code:
Creature* Tile::getTopCreature()
{
    if(CreatureVector* creatures = getCreatures()){
        if(!creatures->empty()){
            return *creatures->rbegin(); // Here i changed "begin()" for "rbegin()".
        }
    }


    return NULL;
}


After this change, you can heal-damage anyone on top of the stack, but only the runes in scripts that have the
setCombatParam(combat, COMBAT_PARAM_TARGETCASTERORTOPMOST, 1) (any number above 0 enables this feature) makes you heal/damage the creature on top on the stack, the rest of the runes that doesn't have this combat param in the script just hit everyone on the stack.

It works fine if you're not in the stack, but the problem with this feature is regardness of being on bottom or top of the stack, if you're in the stack you heal yourself no matter what. To change this to the 7.4 behaviour (heal yourself only if you're the one in the top), you need commit this lines in combat.cpp:


Lua:
if(params.targetCasterOrTopMost){
/*                         if(caster && caster->getTile() == iter_tile){  -- Commented lines to disable priority of caster in stack for healing purposes.
                            if(*cit == caster){
                                bContinue = false;
                            }
                        }
                         else  */if(*cit == iter_tile->getTopCreature()){
                            bContinue = false;
                        }

In that way, you have most of your 7.4 uh trap working.

What is left: At the momment you can use any rune that doesn't have that parameter in the script in a stack and you hit everyone, but if you use any other rune without that param, you hit everyone in the stack regardness of your position inside the stack. If you set all runes with that parameter (i.e hmm or sd) you will hit only the person on top of the stack (back then in 7.4 you could hit everyone with 1 shoot, but you couldn't shot if you were on top of the stack).

That's all, i hope someone can help me out with the other parameter or figure out how to fix what is left. I'm using Othire 1.0 and 7.72 client from here:
very helpful topic. thanks!

I would like to know if you know how to ignore the GHOST mode.

because making these uh trap changes, if I teleport to a player and he uses uh the instant I'm on top of him, even in ghost mode, his uh doesn't work.
 
very helpful topic. thanks!

I would like to know if you know how to ignore the GHOST mode.

because making these uh trap changes, if I teleport to a player and he uses uh the instant I'm on top of him, even in ghost mode, his uh doesn't work.
It's been a while I haven't worked this deep but I would simply use some other function instead of getTopCreature() or modify this function to receive parameters and ignore players with ghost mode.

You can look at the luaGetAllCreatures lua function as a guidance that receives flags in order to check for that already.


C++:
int LuaScriptInterface::luaGetAllCreatures(lua_State *L)
{
    //getAllCreatures(pos, <optional> flag)
    //bits for flag:
    //32 = GET NPCS
    //16 = GET INVISIBLE MONSTERS
    //8 = GET VISIBLE MONSTERS
    //4 = GET GMs AT INVISIBLE STATE
    //2 = GET PLAYERS WITH INVISIBILITY FLAG
    //1 = GET REGULAR PLAYERS (THOSE WITHOUT ANY KIND OF INVISIBILITY FLAG)

    uint32_t flag = 9; //by default shows visible monsters and players without any kind of invisibility flag

    uint32_t parameters = lua_gettop(L);
    if (parameters >= 2)
        flag = popNumber(L);

    PositionEx pos;
    popPosition(L, pos);

    ScriptEnviroment* env = getScriptEnv();

    Tile* tile = g_game.getTile(pos.x, pos.y, pos.z);
    if(!tile){
        reportErrorFunc(getErrorDesc(LUA_ERROR_TILE_NOT_FOUND));
        lua_pushnil(L);
        return 1;
    }

    lua_newtable(L);
    uint32_t index = 1;
    CreatureVector* creatures = tile->getCreatures();
    if (creatures){
    for(CreatureVector::const_iterator cit = creatures->begin(); cit != creatures->end(); ++cit){
        bool add = false;
        if(Player *p = (*cit)->getPlayer()) {
            if(((flag & 1) == 1 && !p->hasFlag(PlayerFlag_CannotBeSeen) && !p->isGmInvisible())||
                ((flag & 2) == 2 && p->hasFlag(PlayerFlag_CannotBeSeen))||
                ((flag & 4) == 4 && p->isGmInvisible())){
                add = true;
            }
        }
        else if (Monster *m = (*cit)->getMonster()){
            if (((flag & 8) == 8 && !m->hasCondition(CONDITION_INVISIBLE)) || (flag & 16) == 16){
                add = true;
            }
        }
        else if ((*cit)->getNpc() && (flag & 32) == 32){
            add = true;
        }

        if(add){
            lua_pushnumber(L, index);
            env->addThing(*cit);
            lua_pushnumber(L, (*cit)->getID());
            lua_settable(L, -3);
            index++;
        }
    }
    }
    return 1;
}
 
Back
Top