• 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;
}
 

Nekiro

Legendary OT User
TFS Developer
Joined
Sep 7, 2015
Messages
2,495
Solutions
113
Reaction score
1,744
This is not achievable with cip client, you have to make custom packet for this if you use otc. You are using server to set the target, client does not get any info that he is attacking the target.
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
Ok, i gonna use OTC...

@Sarah Wesker you mean this?
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 = {
    {1, 1, 1, 1, 1},
    {1, 1, 1, 1, 1},
    {1, 1, 2, 1, 1},
    {1, 1, 1, 1, 1},
    {1, 1, 1, 1, 1},
}
local area = createCombatArea(arr)

setCombatArea(combat, area)

-- 
function onCastSpell(cid, var)
    local mySkull = getCreatureSkullType(cid)
    if mySkull ~= SKULL_WHITE and mySkull ~= SKULL_RED and mySkull ~= SKULL_BLACK then
        doPlayerSendCancel(cid, "You do not have a skull.")
        return false
    end
    -- 
    for i, tid in ipairs(getSpectators(getCreaturePosition(cid), 2, 2, false)) do
        if(isPlayer(tid) and tid ~= cid) then
            local targetSkull = getCreatureSkullType(tid)
            if targetSkull == SKULL_WHITE or targetSkull == SKULL_RED or targetSkull == SKULL_BLACK then
                local targetTarget = getCreatureTarget(tid)
                if targetTarget ~= 0 then
                    doCreatureSetTarget(tid, 0)
                    doCreatureSetTarget(tid, cid)
                    onExtendedOpcode(cid, 55, tostring(cid::getId()))
                end
            end
        end
    end
    return doCombat(cid, combat, var)
end

(im using 0.4)

Code:
[21:59:37.812] [Error - LuaInterface::loadFile] data/spells/scripts/exeta_player.lua:33: '<name>' expected near ':'
[21:59:37.812] [Warning - Event::loadScript] Cannot load script (data/spells/scripts/exeta_player.lua)
[21:59:37.812] data/spells/scripts/exeta_player.lua:33: '<name>' expected near ':'
 

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
Ok, i gonna use OTC...


Code:
[21:59:37.812] [Error - LuaInterface::loadFile] data/spells/scripts/exeta_player.lua:33: '<name>' expected near ':'
[21:59:37.812] [Warning - Event::loadScript] Cannot load script (data/spells/scripts/exeta_player.lua)
[21:59:37.812] data/spells/scripts/exeta_player.lua:33: '<name>' expected near ':'
Code:
onExtendedOpcode(cid, 55, tostring(cid::getId()))
Parameters should be:
Code:
OTHER_FUNCTION_NAME(tid, 55, tostring(cid))
As we want to set 'tid' target to 'cid' (spell caster).
Also you must use other function, 'onExtendedOpcode' is for handling packets from OTC to TFS. There must be function like 'sendExtendedOpcode' to send packet from TFS to OTC, but it was not available in official 0.4.
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
@Gesior.pl @Sarah Wesker

Just the function in my script, right?
Or do i need to change something in otclient too?

There is a function with the name u told in 0.4:


@Sarah Wesker @Gesior.pl halp
 

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
On server side put script you posted above, just change:
Code:
onExtendedOpcode(cid, 55, tostring(cid::getId()))
with:
Code:
doPlayerSendExtendedOpcode(tid, 55, tostring(cid))

On client side, you need code that handle extended opcode with ID 55, reads string from network packet, finds creature with given name on screen and mark it as attacked. Someone must write it. There are many threads with 'free scripting service', try to find someone.
 
OP
OP
M

maikons

Member
Joined
Aug 1, 2015
Messages
227
Reaction score
16
On server side put script you posted above, just change:
Code:
onExtendedOpcode(cid, 55, tostring(cid::getId()))
with:
Code:
doPlayerSendExtendedOpcode(tid, 55, tostring(cid))

On client side, you need code that handle extended opcode with ID 55, reads string from network packet, finds creature with given name on screen and mark it as attacked. Someone must write it. There are many threads with 'free scripting service', try to find someone.

TY @Gesior.pl
@Sarah Wesker could u share to us how did u do on otc side?
 

Sarah Wesker

ค∂vαηcε รүηтαx ❤
Support Team
Joined
Mar 16, 2017
Messages
997
Solutions
100
Reaction score
1,033
Location
London
GitHub
MillhioreBT
TY @Gesior.pl
@Sarah Wesker could u share to us how did u do on otc side?
Lua:
-- Register
ProtocolGame.registerExtendedOpcode(55, onRecvOpcode)

-- Functions
local getCreatureById = function (id)
    local localPlayer = g_game.getLocalPlayer()
    if not localPlayer or localPlayer:getId() == id then
        return
    end

    for i, spec in ipairs(g_map.getSpectators(localPlayer:getPosition(), false)) do
     if spec:getId() == id then
        return spec
     end
  end
end

function onRecvOpcode(protocol, opcode, packet)
    local creature = getCreatureById(tonumber(packet))
    if creature then
        g_game.cancelAttack()
        g_game.attack(creature)
    end
end
 

oen432

Legendary OT User
Joined
Oct 3, 2014
Messages
1,425
Solutions
49
Reaction score
1,519
Location
Poland
GitHub
Oen44
Lua:
-- Register
ProtocolGame.registerExtendedOpcode(55, onRecvOpcode)

-- Functions
local getCreatureById = function (id)
    local localPlayer = g_game.getLocalPlayer()
    if not localPlayer or localPlayer:getId() == id then
        return
    end

    for i, spec in ipairs(g_map.getSpectators(localPlayer:getPosition(), false)) do
     if spec:getId() == id then
        return spec
     end
  end
end

function onRecvOpcode(protocol, opcode, packet)
    local creature = getCreatureById(tonumber(packet))
    if creature then
        g_game.cancelAttack()
        g_game.attack(creature)
    end
end
FYI g_map.getCreatureById(id)
 

Itutorial

Premium User
Premium User
Joined
Dec 23, 2014
Messages
1,950
Solutions
52
Reaction score
641
There is a function like: updateCreatureTarget(cid)... if you can find that add it to the sources for doCreatureSetTarget()
 
Top