• 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 0.X luaDoCreatureSetTarget not creating red square

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
I want to create a spell that make a player atk other player, like exeta res to pvp
It looks like work, it is opeing PK, but it is not creating the red square...

Why?

What do i doing wrong?

spell:
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_HEALING)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false)
local arr = {
    {0, 0, 0, 0, 0},
    {0, 1, 1, 1, 0},
    {0, 1, 2, 1, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 0, 0},
}
local area = createCombatArea(arr)

setCombatArea(combat, area)

function onCastSpell(cid, var)
    for i, tid in ipairs(getSpectators(getCreaturePosition(cid), 1, 1, false)) do
        if(isPlayer(tid) and tid ~= cid) then
            doCreatureSetTarget(tid, cid)
        end
    end
    return doCombat(cid, combat, var)
end

source code:
Code:
int32_t LuaInterface::luaDoCreatureSetTarget(lua_State* L)
{
    //doCreatureSetTarget(cid, target)
    uint32_t targetId = popNumber(L);
    ScriptEnviroment* env = getEnv();

    Creature* creature = env->getCreatureByUID(popNumber(L));
    if(!creature)
    {
        errorEx(getError(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    Creature* target = env->getCreatureByUID(targetId);
    if(!target && targetId != 0)
    {
        errorEx(getError(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }


    bool attackedCreatureChanged = creature->setAttackedCreature(target);
    
    // Remove red square in client if setting target to NULL
    Player *player = creature->getPlayer();
    if(player != NULL && targetId == 0 && attackedCreatureChanged) {
        player->sendCancelTarget();
    } else {
        player->sendCreatureSquare(target, 112);
    }

    lua_pushboolean(L, attackedCreatureChanged);

    return 1;
}
 

Xikini

I whore myself out for likes
Support Team
Joined
Nov 17, 2010
Messages
5,610
Solutions
395
Reaction score
3,724
I want to create a spell that make a player atk other player, like exeta res to pvp
It looks like work, it is opeing PK, but it is not creating the red square...

Why?

What do i doing wrong?

spell:
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_HEALING)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false)
local arr = {
    {0, 0, 0, 0, 0},
    {0, 1, 1, 1, 0},
    {0, 1, 2, 1, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 0, 0},
}
local area = createCombatArea(arr)

setCombatArea(combat, area)

function onCastSpell(cid, var)
    for i, tid in ipairs(getSpectators(getCreaturePosition(cid), 1, 1, false)) do
        if(isPlayer(tid) and tid ~= cid) then
            doCreatureSetTarget(tid, cid)
        end
    end
    return doCombat(cid, combat, var)
end

source code:
Code:
int32_t LuaInterface::luaDoCreatureSetTarget(lua_State* L)
{
    //doCreatureSetTarget(cid, target)
    uint32_t targetId = popNumber(L);
    ScriptEnviroment* env = getEnv();

    Creature* creature = env->getCreatureByUID(popNumber(L));
    if(!creature)
    {
        errorEx(getError(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    Creature* target = env->getCreatureByUID(targetId);
    if(!target && targetId != 0)
    {
        errorEx(getError(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }


    bool attackedCreatureChanged = creature->setAttackedCreature(target);
    
    // Remove red square in client if setting target to NULL
    Player *player = creature->getPlayer();
    if(player != NULL && targetId == 0 && attackedCreatureChanged) {
        player->sendCancelTarget();
    } else {
        player->sendCreatureSquare(target, 112);
    }

    lua_pushboolean(L, attackedCreatureChanged);

    return 1;
}
I've seen this issue in the past, but don't know the direct solution, only the answer.

You need to send extra byte information to the client along with the exeta res spell, so that the client knows that the attack square has been called.

Normally the only way to 'attack' something is via input from the client to the server, so you basically need to flip that and send that same information from the server to the client, to force the action to show up on the clients side.
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
If the player have a target, the attack change, it make the damage, everything looks work, but the red square still in the old target :(

I thought that else
Code:
    } else {
        player->sendCreatureSquare(target, 112);
    }
Would fix this :(
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
So the only Part which is not working is the effect yes?

yeah, everything works just do not add the tibia atk red square

this red square:
hqdefault.jpg
 

Elgenady

Veteran OT User
Joined
Aug 5, 2011
Messages
1,606
Solutions
34
Reaction score
303
if i understand right you want all player get hit from spell add red square
go to game.cpp
Game::combatChangeHealth
add
Lua:
Player* pTarget = NULL;

if(target)

pTarget = target->getPlayer();



Player* pCaster = NULL;

if(attacker)

pCaster = attacker->getPlayer();





if (pCaster && pTarget)

{

if (damage >= 1)

addCreatureSquare(pTarget, COLOR_RED);

}
under
int32_t damage = -healthChange;
 

kennyubuntu

Member
Joined
May 20, 2016
Messages
150
Reaction score
13
if i understand right you want all player get hit from spell add red square
go to game.cpp
Game::combatChangeHealth
add
Lua:
Player* pTarget = NULL;

if(target)

pTarget = target->getPlayer();



Player* pCaster = NULL;

if(attacker)

pCaster = attacker->getPlayer();





if (pCaster && pTarget)

{

if (damage >= 1)

addCreatureSquare(pTarget, COLOR_RED);

}
under
int32_t damage = -healthChange;

i've test here and there are 2 problems
1- it not stop the old red square
2- it is not a fixed red square, it is not normal as normal attack, it is stranging blinking
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
I've seen this issue in the past, but don't know the direct solution, only the answer.

You need to send extra byte information to the client along with the exeta res spell, so that the client knows that the attack square has been called.

Normally the only way to 'attack' something is via input from the client to the server, so you basically need to flip that and send that same information from the server to the client, to force the action to show up on the clients side.

@Xikini u saw this issue in this forum?
i couldn't found anything :(
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
I've seen this issue in the past, but don't know the direct solution, only the answer.

You need to send extra byte information to the client along with the exeta res spell, so that the client knows that the attack square has been called.

Normally the only way to 'attack' something is via input from the client to the server, so you basically need to flip that and send that same information from the server to the client, to force the action to show up on the clients side.

Do u know anything i could use as base to try to do it?
An example, someone doing something like that...
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
I've seen this issue in the past, but don't know the direct solution, only the answer.

You need to send extra byte information to the client along with the exeta res spell, so that the client knows that the attack square has been called.

Normally the only way to 'attack' something is via input from the client to the server, so you basically need to flip that and send that same information from the server to the client, to force the action to show up on the clients side.
@Xikini could u give more information about that?
A light...
Any other example sending extra byte to the client or something like that?
 

Gesior.pl

Mega Noob&LOL 2012
Senator
Premium User
Joined
Sep 18, 2007
Messages
2,368
Solutions
44
Reaction score
1,823
Location
Poland
GitHub
gesior
I want to create a spell that make a player atk other player, like exeta res to pvp
It looks like work, it is opeing PK, but it is not creating the red square...
You just can't do it. There is no such spell on real tibia, so Tibia client was not designed to get information about attacked creature from server.
You can cancel current attacked creature (remove red mark from current target). Replace:
Code:
doCreatureSetTarget(tid, cid)
with:
Code:
doCreatureSetTarget(tid, 0)
doCreatureSetTarget(tid, cid)
Setting target to 0 send packet 'cancel attack' to client, like when attacked player run into PZ.

This problem was discussed on otland few times over last 10 years.
 
Last edited:
Top