• 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 1.x] Monster pick up item and throw

Aled

Active Member (probably)
Joined
Mar 30, 2017
Messages
215
Solutions
17
Reaction score
130
Just a little fun:
giphy.gif

Monster picks up item from ground and throws it at the player.
Put
XML:
<script>
<event name="rockthrow"/>
</script>
in the monster xml
and in creaturescripts.xml
XML:
<event type="think" name="rockthrow" script="rockthrow.lua" />
and in rockthrow.lua
Lua:
local rockid = 1285
function itemnear(pos,itemid)
    local tiles
    local n = 1
    for i=-1,1 do
        for j=-1,1 do
            tile = Tile(pos.x+i,pos.y+j,pos.z)
            n=n+1
            local item = tile:getItemById(itemid) or false
            if item then
                return item
            end
        end
    end
    return false
end   
function onThink(cid, interval)
    local rock = itemnear(cid:getPosition(),rockid)
    local target = cid:getTarget()
    if rock and target and not hasrock then
        local pos =    cid:getPosition()
        rock:remove()
        local hasrock = true
        addEvent(function()
            if cid:getTarget() then
                cid:getPosition():sendDistanceEffect(cid:getTarget():getPosition(), CONST_ANI_LARGEROCK)
                doTargetCombatHealth(cid, cid:getTarget(), COMBAT_PHYSICALDAMAGE, -10, -70, CONST_ME_DRAWBLOOD)
                Game.createItem(rockid,1,target:getPosition())
            else
                Game.createItem(rockid,1,cid:getPosition())
            end
        end,math.random(100,2000))
    end
end
Nice little function itemnear in there too
Can be done with any item but rock works well cause there is an appropriate distance effect and they cannot be removed from the hunting ground. For the same reason it is very abusable because you cannot walk over them so players can effectively make their own physical walls.
Have fun!
 
Made some adjustments:
fixed some things that might have caused console errors and what I believe might crash the server if monster dies with a rock
wrote awesome new config
monsters slows down while holding a rock
monster no longer picks up or drops rock if there is already a rock under the player

giphy.gif


Lua:
local c = {
itemid = 1285, -- itemid of object to be thrown
delaymin = 100, -- in milliseconds, set to 0 to throw instantly
delaymax = 2000, -- in milliseconds, set to 0 to throw instantly
damagemin = 10,
damagemax = 70,
damagetype = COMBAT_PHYSICALDAMAGE,
disteffect = CONST_ANI_LARGEROCK,
effect = CONST_ME_DRAWBLOOD,
speed = 180 -- speed reduction while holding item (0 for no speed change, high value to make monster stop moving to throw item)
}
function itemnear(pos,itemid)
    local tiles = {}
    local n = 1
    for i=-1,1 do
        for j=-1,1 do
            tiles[n] = Tile(pos.x+i,pos.y+j,pos.z)
            local item = tiles[n]:getItemById(c.itemid) or false
            n=n+1
            if item then
                return item
            end
        end
    end
    return false
end       
local hasrock = false
local alreadyrock = false
function onThink(cid, interval)
    local rock = itemnear(cid:getPosition(),c.itemid)
    if cid:getTarget() then
        if Tile(cid:getTarget():getPosition()):getItemById(c.itemid) then
            alreadyrock = true
        else
            alreadyrock = false
        end
    end
    if rock and cid:getTarget() and not hasrock and not alreadyrock then
        local pos =    cid:getPosition()
        rock:remove()
        hasrock = true
        cid:changeSpeed(-c.speed)
        addEvent(function()
            if cid then
            local nowpos = cid:getPosition()
                if cid:getTarget() and not alreadyrock then
                    cid:getPosition():sendDistanceEffect(cid:getTarget():getPosition(), c.disteffect)
                    doTargetCombatHealth(cid, cid:getTarget(), c.damagetype, -c.damagemin, -c.damagemax, c.effect)
                    Game.createItem(c.itemid,1,cid:getTarget():getPosition())
                else
                    Game.createItem(c.itemid,1,cid:getPosition())
                end
                cid:changeSpeed(c.speed)
            else
                Game.createItem(c.itemid,1,nowpos)
            end
            hasrock = false
        end,math.random(c.delaymin,c.delaymax))
    end
end
 
I tried this out it worked but gave errors. Sorry I did not save the errors. Nicely done tho :)
 
seems like stones can be thrown trough walls
 
seems like stones can be thrown trough walls
Yes it seems so, thanks :p
All that is needed is change
Lua:
                if cid:getTarget() and not alreadyrock then
                    cid:getPosition():sendDistanceEffect(cid:getTarget():getPosition(), c.disteffect)
                    doTargetCombatHealth(cid, cid:getTarget(), c.damagetype, -c.damagemin, -c.damagemax, c.effect)
                    Game.createItem(c.itemid,1,cid:getTarget():getPosition())
                else
                    Game.createItem(c.itemid,1,cid:getPosition())
                end
to
Lua:
               if cid:getTarget() and not alreadyrock then
                    if cid:getPosition():isSightClear(cid:getTarget():getPosition()) then
                        cid:getPosition():sendDistanceEffect(cid:getTarget():getPosition(), c.disteffect)
                        doTargetCombatHealth(cid, cid:getTarget(), c.damagetype, -c.damagemin, -c.damagemax, c.effect)
                    else
                        Game.createItem(c.itemid,1,cid:getTarget():getPosition())
                    end
                else
                    Game.createItem(c.itemid,1,cid:getPosition())
                end
again, you should be conservative and considerate with where you employ this monster behaviour because it can be abused, it is better reserved for a boss creature
I tried this out it worked but gave errors. Sorry I did not save the errors. Nicely done tho :)
I would very much like to know what console errors you get
 
Yes it seems so, thanks :p
All that is needed is change
Lua:
                if cid:getTarget() and not alreadyrock then
                    cid:getPosition():sendDistanceEffect(cid:getTarget():getPosition(), c.disteffect)
                    doTargetCombatHealth(cid, cid:getTarget(), c.damagetype, -c.damagemin, -c.damagemax, c.effect)
                    Game.createItem(c.itemid,1,cid:getTarget():getPosition())
                else
                    Game.createItem(c.itemid,1,cid:getPosition())
                end
to
Lua:
               if cid:getTarget() and not alreadyrock then
                    if cid:getPosition():isSightClear(cid:getTarget():getPosition()) then
                        cid:getPosition():sendDistanceEffect(cid:getTarget():getPosition(), c.disteffect)
                        doTargetCombatHealth(cid, cid:getTarget(), c.damagetype, -c.damagemin, -c.damagemax, c.effect)
                    else
                        Game.createItem(c.itemid,1,cid:getTarget():getPosition())
                    end
                else
                    Game.createItem(c.itemid,1,cid:getPosition())
                end
again, you should be conservative and considerate with where you employ this monster behaviour because it can be abused, it is better reserved for a boss creature

I would very much like to know what console errors you get
Changing this part makes the stones not appear at all anymore under the player after the monster throw them, can someone fix? :)
 
Changing this part makes the stones not appear at all anymore under the player after the monster throw them, can someone fix? :)
Wow sorry I made a mistake!
Lua:
               if cid:getTarget() and not alreadyrock then
                    if cid:getPosition():isSightClear(cid:getTarget():getPosition()) then
                        cid:getPosition():sendDistanceEffect(cid:getTarget():getPosition(), c.disteffect)
                        doTargetCombatHealth(cid, cid:getTarget(), c.damagetype, -c.damagemin, -c.damagemax, c.effect)                        Game.createItem(c.itemid,1,cid:getTarget():getPosition())
                    else
                        Game.createItem(c.itemid,1,cid:getPosition())
                    end
                else
                    Game.createItem(c.itemid,1,cid:getPosition())
                end
It's not the cleanest code but that should work at least
 
Back
Top