Lua Function creature:moveTo(position)

silveralol

Veteran OT User
Joined
Mar 16, 2010
Messages
1,461
Reaction score
184
i've already done that

void Monster::eek:nThink(uint32_t interval)

Code:
    if (!isInSpawnRange(_position)) {
        Creature* creature = this->getCreature()
        FindPathParams fpp;
        fpp.minTargetDist = 0;
        fpp.maxTargetDist = 1;
        fpp.fullPathSearch = true;
        fpp.clearSight = true;
        fpp.maxSearchDist = 150;
        std::forward_list<Direction> dirList;
            if (creature->getPathTo(masterPos, dirList, fpp)) {
                creature->hasFollowPath = true;
                creature->startAutoWalk(dirList);
            }
guess i didnt tested it

you could also create a Lua callback in this and then make your stuff inside the Lua env
cool for puzzles like "you have to pull all of these monsters from their spawns to get the key"


have you ever tested the lua function before?
i made this to a system, but I had a insight that it wasnt the best way
so I did just very basic tests and I cant assure that will work in every situation as intended

I have to mention that these monsters may be not idle after finishing the walk because its not a problem in my server
Hello bro, I test your function to move the monsters to own spawn pos, not get it working ...
seems that is too much limited, the beucase of getPathTo or something like it, then don't work to monsters walk to own pos :/
also I'm trying handle with it in Lua, see:
Code:
local function check(monster)
    if not monster:getTarget() then
        if monster then
            Creature(monster):moveTo(monster:getSpawnPosition())
        end
    else
        --target = monster:getTarget()
        --target:moveTo(monster:getSpawnPosition())-- just for test and it work 0.o
    end
end
function onThink(creature)
    if not creature:isMonster() then
        return true
    end
    local monster = creature:getMonster()
    local pos = monster:getSpawnPosition()
    if not pos then
        return true
    end
    addEvent(check, 1000, monster)
    if not monster:isInSpawnRange(monster:getPosition()) then
        if monster:getTarget() then
            monster:getPosition():sendMagicEffect(CONST_ME_POFF)
            monster:remove()
        else
            addEvent(check, 1000, monster)
        end
    end
    return true
end
also, I just comment the check in monster.cpp
Code:
/*if (!isInSpawnRange(_position)) {
        g_game.internalTeleport(this, masterPos);
        g_game.addMagicEffect(getPosition(), CONST_ME_POFF);
        setIdle(true);
    } else {*/
and another "}" above, to close all "{ } "
 
OP
Marcelo Druida

Marcelo Druida

Active Member
Joined
Nov 17, 2014
Messages
423
Reaction score
122
I did not get what is the point of the addEvent

Code:
function onThink(creature)
    local monster = creature:getMonster()
    local spawn = monster:getSpawnPosition()
    if not spawn then
        return true
    end
    if not monster:isInSpawnRange(monster:getPosition()) then
        if monster:getTarget() then
            monster:getPosition():sendMagicEffect(CONST_ME_POFF)
            monster:remove()
        else
            monster:moveTo(spawn)
        end
    end
    return true
end
this doesnt work?
 

Stigma

Veteran OT User
Joined
Feb 14, 2015
Messages
4,590
Reaction score
2,150
I did not get what is the point of the addEvent

Code:
function onThink(creature)
    local monster = creature:getMonster()
    local spawn = monster:getSpawnPosition()
    if not spawn then
        return true
    end
    if not monster:isInSpawnRange(monster:getPosition()) then
        if monster:getTarget() then
            monster:getPosition():sendMagicEffect(CONST_ME_POFF)
            monster:remove()
        else
            monster:moveTo(spawn)
        end
    end
    return true
end
this doesnt work?
because whitevo said onThink for creatures will not work if the creature does not have any targets
 
OP
Marcelo Druida

Marcelo Druida

Active Member
Joined
Nov 17, 2014
Messages
423
Reaction score
122
because whitevo said onThink for creatures will not work if the creature does not have any targets
I still dont get what is the addEvent for.

alright, maybe it wont work but the problem is in the source. The creature is set to IDLE while it doesnt have any targets. What can be done is removing this idle thing or creating a diff script
 
OP
Marcelo Druida

Marcelo Druida

Active Member
Joined
Nov 17, 2014
Messages
423
Reaction score
122
Code:
function onCreatureDisappear(self, creature)   
    if self == creature then
        return false
    end
    for k, v in pairs(self:getTargetList()) do
        if v ~= creature then
            return false
        end
    end
    
    local monster = self:getMonster()
    local spawn = monster:getSpawnPosition()
    if not spawn then
        return true
    end
    if not monster:isInSpawnRange(monster:getPosition()) then
        monster:moveTo(spawn)
    end
    return true
end
 

silveralol

Veteran OT User
Joined
Mar 16, 2010
Messages
1,461
Reaction score
184
Code:
function onCreatureDisappear(self, creature)  
    if self == creature then
        return false
    end
    for k, v in pairs(self:getTargetList()) do
        if v ~= creature then
            return false
        end
    end
   
    local monster = self:getMonster()
    local spawn = monster:getSpawnPosition()
    if not spawn then
        return true
    end
    if not monster:isInSpawnRange(monster:getPosition()) then
        monster:moveTo(spawn)
    end
    return true
end
could you test it? I can't right now :/
 

Homeslice

-anoyn/Rage the Mage
Joined
May 9, 2010
Messages
113
Reaction score
52
Location
Canada
By default this will only move 10~ squares max. If you want to move farther increase

static constexpr int32_t MAX_NODES = 512;

10000 will go 120 squares at most (straight there). Don't use moveTo for anything 50 steps or father otherwise your server will likely stutter.
 

Homeslice

-anoyn/Rage the Mage
Joined
May 9, 2010
Messages
113
Reaction score
52
Location
Canada
I've noticed a bug with this code.

Pushable creatures (centipede) wont be pushed when there is no room beside a target. Creatures with canpushcreatures (carniphila) will not push the centipede, but instead stack on top of them.
 

Homeslice

-anoyn/Rage the Mage
Joined
May 9, 2010
Messages
113
Reaction score
52
Location
Canada
You can fix the stacking bug with one line change.

Change:
C++:
bool Monster::getNextStep(Direction& dir, uint32_t& flags)
{
    if (getHealth() <= 0) {
        //we dont have anyone watching might aswell stop walking
        eventWalk = 0;
        return false;
    }

    bool result = false;
    if (hasFollowPath
        return Creature::getNextStep(dir, flags);
    else if ((!followCreature || !hasFollowPath) && !isSummon()) {
To:
C++:
bool Monster::getNextStep(Direction& dir, uint32_t& flags)
{
    if (getHealth() <= 0) {
        //we dont have anyone watching might aswell stop walking
        eventWalk = 0;
        return false;
    }

    bool result = false;
    if (hasFollowPath)
        result = Creature::getNextStep(dir, flags); //stacking creatures fix
    else if ((!followCreature || !hasFollowPath) && !isSummon()) {
 
Joined
Jul 18, 2014
Messages
193
Reaction score
14
I just compiled with this function and when i open the executable it closes inmediatly. Any idea?
 

Homeslice

-anoyn/Rage the Mage
Joined
May 9, 2010
Messages
113
Reaction score
52
Location
Canada
Also this code probably breaks:
Monsters randomly stepping when target on screen but not reachable
Monsters randomly stepping beside target
Monsters continue pathfinding even if target left

On my above post
if (hasFollowPath)
needs to have extra params like checking if walkDirList isnt empty and hasTargetCreature ect.
 
OP
Marcelo Druida

Marcelo Druida

Active Member
Joined
Nov 17, 2014
Messages
423
Reaction score
122
could you improve it?
it was a small chunk that i didnt even needed so bugs were expected
 

ckripz

Well-Known Member
Joined
May 30, 2013
Messages
59
Reaction score
6
the monster does not move if it has speed 0. can it be solved?
 
Top