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

CreatureEvent onTarget Interact with Npc

Joe Rod

Discord: joerod1
Joined
Mar 16, 2011
Messages
499
Solutions
2
Reaction score
172
GitHub
joerod1
Hi guys, with this you would greet the npc and open its shop (if has) only target it!


Tested on OTX3, it will work on TFS 1.x i guess

combat.cpp
find:
Code:
if (player->hasFlag(PlayerFlag_CannotUseCombat) || !target->isAttackable()) {

now go to a line who look like this (4 lines below):
Code:
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;

and replace it with this:
Code:
            if (!target->getNpc())
                return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE;


data/events/scripts/creature.lua

find:
Code:
function Creature:onTargetCombat(target)

now find something who look like this
Code:
    if not self then
        return true
    end

below that paste this:
Code:
    if (self:isPlayer() and target:isNpc()) then
        self:say("hi", TALKTYPE_PRIVATE_PN, false, target)
        self:say("trade", TALKTYPE_PRIVATE_PN, false, target)
        return RETURNVALUE_NOTPOSSIBLE   
    end

If you liked it you could give a feedback ;)
 
this is really nice, but what about the distance?
you have to add this function and variable (maybe at the beginning of file)
Code:
function getDistanceBetween(fromPosition, toPosition)
   local x, y = math.abs(fromPosition.x - toPosition.x), math.abs(fromPosition.y - toPosition.y)
   local diff = math.max(x, y)
   if(fromPosition.z ~= toPosition.z) then
     diff = diff + 9 + 6
   end
   return diff
end
local minDist = 3

now replace this:
Code:
 if (self:isPlayer() and target:isNpc()) then
    self:say("hi", TALKTYPE_PRIVATE_PN, false, target)
    self:say("trade", TALKTYPE_PRIVATE_PN, false, target)
    return RETURNVALUE_NOTPOSSIBLE
end

with this:
Code:
local distance = getDistanceBetween(self:getPosition(), target:getPosition())
if (distance > minDist) then
   self:sendTextMessage(MESSAGE_STATUS_SMALL, "Get closer to talk to NPC.")
   return false
else
    self:say(distance, TALKTYPE_MONSTER_SAY)
    self:say("hi", TALKTYPE_PRIVATE_PN, false, target)
    self:say("trade", TALKTYPE_PRIVATE_PN, false, target)
end
 
Here's some changes I made, I have an NPC that attacks monsters so I had to add the check, also I added the MESSAGE_INFO_DESCR because the return NOTPOSSIBLE will remove the "Get closer to talk to NPC", it would be really nice if we could make player stop attacking NPC on first attack, and without having to show or use the "Sorry, not possible" message return type!

Code:
    if (distance > minDist) and not self:isMonster() and not self:isNpc() and target:isNpc() then
      self:sendTextMessage(MESSAGE_INFO_DESCR, "Get closer to talk to NPC.")
      return RETURNVALUE_NOTPOSSIBLE
    elseif (distance <= minDist) and not self:isMonster() and not self:isNpc() and target:isNpc() then
      self:say("hi", TALKTYPE_PRIVATE_PN, false, target)
      self:say("trade", TALKTYPE_PRIVATE_PN, false, target)
      return RETURNVALUE_NOTPOSSIBLE
    end
 
ah, i forgot to add npc check
Code:
    if (self:isPlayer() and target:isNpc()) then
        local distance = getDistanceBetween(self:getPosition(), target:getPosition())
        if (distance > minDist) then
           self:sendTextMessage(MESSAGE_STATUS_SMALL, "Get closer to talk to NPC.")
           return false
        else
            self:say(distance, TALKTYPE_MONSTER_SAY)
            self:say("hi", TALKTYPE_PRIVATE_PN, false, target)
            self:say("trade", TALKTYPE_PRIVATE_PN, false, target)
        end
        return RETURNVALUE_NOTPOSSIBLE   
    end
 
a comment about this, what if the npc is in pz? you cant attack him so event is not executed :)
 
a comment about this, what if the npc is in pz? you cant attack him so event is not executed :)
i was waiting for this, but anyone reported xD

remove this:
Code:
if (!target->getNpc())

and after
Code:
if (player == target) {
    return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER;
}

paste this:
Code:
if (target->getNpc())
{
    return Combat::canDoCombat(player, target);
}

i'll try to contact a moderator to edit main post
 
Im using all you posted bro :) So if I got any problems I gotta report them.
Thanks again.
 
I found this line of code in npc.cpp source file, not sure if this exists in all tfs 1.x versions.

C++:
attackable = npcNode.attribute("attackable").as_bool();

You can make any npc to be attackable by adding

Code:
Attackable = 1

In their xml file, so with this i believe u may skip the source edits entirely... I think...
 
I found this line of code in npc.cpp source file, not sure if this exists in all tfs 1.x versions.

C++:
attackable = npcNode.attribute("attackable").as_bool();

You can make any npc to be attackable by adding

Code:
Attackable = 1

In their xml file, so with this i believe u may skip the source edits entirely... I think...
Yep, it makes NPC attackable.
But, you still need an edit to make it work in PZ.
 
Yep, it makes NPC attackable.
But, you still need an edit to make it work in PZ.
What a shame, i personally hate doing c++ edits as i will always have to redo them each time TFS updates.

Oh well xD
 
Script for TFS 0.3.6 is something like this:

Code:
function onTarget(cid, target)

    if isPlayer(cid) and isNpc(target) then
        doPlayerSay(cid,"hi", 1)
        addEvent(doPlayerSay, 500, cid, "trade", 4)
    else
        return true
    end
end

But trade dont work! (Dont know why :s)
Enjoy it ;)
 
Back
Top