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

Lua Rain Arrow tfs 1.5 7.72

dewral

Veteran OT User
Joined
Dec 4, 2019
Messages
345
Solutions
10
Reaction score
371
Hello guys how you doing?
Do maybe someone know how to or have a script something like this? :p
Any hints could be usefull too :D
 
Solution
Thanks for sharing my video.

Here's the original script from 0.3 TFS, also it works on my 1.3, maybe it will work on 1.5 too.
Lua:
--local cfg = {
--	time = 120,		-- cooldown in seconds
--	id = 60947
--}

local arrows = {1, 2}
local arr = {
 
{0, 1, 1, 1, 0},
{1, 1, 1, 1, 1},
{1, 1, 3, 1, 1},
{1, 1, 1, 1, 1},
{0, 1, 1, 1, 0}
}
 
local combat = createCombatObject()
setCombatArea(combat, createCombatArea(arr))
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
 
local function arrowRain(p)
    if p.check > 0 or math.random(0, 1) == 1 then
		local dist = getPlayerSkillLevel(p.cid, 4)
        doSendDistanceShoot({ x = p.pos.x - 7, y = p.pos.y - 7, z = p.pos.z}, p.pos, math.random(1,#arrows))
		doAreaCombatHealth(p.cid...
For the target area you can use spell areas and CALLBACK_PARAM_TARGETTILE function to get all tile positions (store in table)
So you can easily change areas (between) spells

Lua:
local combat = Combat()
combat:setArea(createCombatArea(AREA_CIRCLE2X2))

local userdata = {}
function onTargetTile(caster, position)
    local positions = userdata[caster:getId()]
    positions[#positions + 1] = position
end
combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile")

local spell = Spell("instant")
function spell.onCastSpell(creature, variant)

    if not userdata[creature:getId()] then
        userdata[creature:getId()] = {}
    end

    -- retrieve positions
    combat:execute(creature, variant)

    local positions = userdata[creature:getId()]
    for i = 1, #positions do
        local tile = Tile(positions[math.random(1, #positions)])
        if tile then
            local target = tile:getTopCreature()
            if target then
                -- code
            end
        end
    end

    userdata[creature:getId()] = nil
    return true
end

You will have to use doTargetCombatHealth to deal damage tho

You can make your own damage formula or... you can do the same as on positions by using CALLBACK_PARAM_SKILLVALUE/CALLBACK_PARAM_LEVELMAGICVALUE and store the min-max damage in the table instead of returning it
 
Last edited:
Thanks for sharing my video.

Here's the original script from 0.3 TFS, also it works on my 1.3, maybe it will work on 1.5 too.
Lua:
--local cfg = {
--	time = 120,		-- cooldown in seconds
--	id = 60947
--}

local arrows = {1, 2}
local arr = {
 
{0, 1, 1, 1, 0},
{1, 1, 1, 1, 1},
{1, 1, 3, 1, 1},
{1, 1, 1, 1, 1},
{0, 1, 1, 1, 0}
}
 
local combat = createCombatObject()
setCombatArea(combat, createCombatArea(arr))
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
 
local function arrowRain(p)
    if p.check > 0 or math.random(0, 1) == 1 then
		local dist = getPlayerSkillLevel(p.cid, 4)
        doSendDistanceShoot({ x = p.pos.x - 7, y = p.pos.y - 7, z = p.pos.z}, p.pos, math.random(1,#arrows))
		doAreaCombatHealth(p.cid, COMBAT_PHYSICALDAMAGE, p.pos, 0, -5, -dist*8, CONST_ME_HITAREA)
    end
 
    if(p.check < 3) then
        p.check = p.check + 1
        addEvent(arrowRain, math.random(0, 2500), p)
    end
end
 
function onTargetTile(cid, pos)
    local p = {}
    p.cid, p.pos, p.check = cid, pos, 0
    arrowRain(p)
	return true
end

setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile")
 
function onCastSpell(cid, var)
--	if getPlayerCd(cid, cfg.id) > 0 then
--		doPlayerSayCd(cid, cfg.id)
--		return false
--	else
--		setPlayerCd(cid, cfg.id, cfg.time)
		doCombat(cid, combat, var)
--	end
    return true
end
 
Solution
Thank you guys for replying!
Thanks for sharing my video.

Here's the original script from 0.3 TFS, also it works on my 1.3, maybe it will work on 1.5 too.
Lua:
--local cfg = {
--    time = 120,        -- cooldown in seconds
--    id = 60947
--}

local arrows = {1, 2}
local arr = {
 
{0, 1, 1, 1, 0},
{1, 1, 1, 1, 1},
{1, 1, 3, 1, 1},
{1, 1, 1, 1, 1},
{0, 1, 1, 1, 0}
}
 
local combat = createCombatObject()
setCombatArea(combat, createCombatArea(arr))
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
 
local function arrowRain(p)
    if p.check > 0 or math.random(0, 1) == 1 then
        local dist = getPlayerSkillLevel(p.cid, 4)
        doSendDistanceShoot({ x = p.pos.x - 7, y = p.pos.y - 7, z = p.pos.z}, p.pos, math.random(1,#arrows))
        doAreaCombatHealth(p.cid, COMBAT_PHYSICALDAMAGE, p.pos, 0, -5, -dist*8, CONST_ME_HITAREA)
    end
 
    if(p.check < 3) then
        p.check = p.check + 1
        addEvent(arrowRain, math.random(0, 2500), p)
    end
end
 
function onTargetTile(cid, pos)
    local p = {}
    p.cid, p.pos, p.check = cid, pos, 0
    arrowRain(p)
    return true
end

setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile")
 
function onCastSpell(cid, var)
--    if getPlayerCd(cid, cfg.id) > 0 then
--        doPlayerSayCd(cid, cfg.id)
--        return false
--    else
--        setPlayerCd(cid, cfg.id, cfg.time)
        doCombat(cid, combat, var)
--    end
    return true
end
The only problem i have here that it doesn't detect arrows
Sending me an error like this
lyiIZnd.png

So i assume the problem is here then
Lua:
doSendDistanceShoot({ x = p.pos.x - 7, y = p.pos.y - 7, z = p.pos.z}, p.pos, math.random(1,#arrows))
I tried just add it like this
Lua:
        doSendDistanceShoot({ x = p.pos.x - 7, y = p.pos.y - 7, z = p.pos.z}, p.pos, CONST_ME_ARROW)
And the script is working without errors but not sending and distance shot :(

Edit:
Just made a noob mistake instead CONST_ANI_ARROW i put there CONT_ME_ARROW xD
It works now but how to make it that it detects the arrow you're using?
It's probably working now like this on your 1.3? :p
 
Last edited:
It works now but how to make it that it detects the arrow you're using?
CONST_ANI_ARROW is a number 2
You can find all in data/lib/constant.lua

Lua:
local arrows = {1, 2}

Original script is using randomly arrows or bolts per shot. 1 is bolt, 2 is arrow.
You can change 1, 2 to CONST_ANI_BOLT, CONST_ANI_ARROW.

Also that line should be fixed to:
Lua:
doSendDistanceShoot({ x = p.pos.x - 7, y = p.pos.y - 7, z = p.pos.z}, p.pos, arrows[math.random(1,#arrows))]
 
CONST_ANI_ARROW is a number 2
You can find all in data/lib/constant.lua

Lua:
local arrows = {1, 2}

Original script is using randomly arrows or bolts per shot. 1 is bolt, 2 is arrow.
You can change 1, 2 to CONST_ANI_BOLT, CONST_ANI_ARROW.

Also that line should be fixed to:
Lua:
doSendDistanceShoot({ x = p.pos.x - 7, y = p.pos.y - 7, z = p.pos.z}, p.pos, arrows[math.random(1,#arrows))]
Yea i already figured it out haha, i was told that i can do it with something like this but didnt have time yet to check it :p

Lua:
local ammo = player:getSlotItem(CONST_SLOT_AMMO)
if ammo then
ammo:getId()
end
 
You can make an associative table for that
Lua:
local t = {
    [arrow_id] = CONST_ANI_ARROW,
    [bolt_id] = CONST_ANI_BOLT
}

local slotItem = player:getSlotItem(CONST_SLOT_AMMO)
if slotItem then
    local shootType = t[slotItem:getId()] or CONST_ANI_ARROW
end
 
Very good spell, but it crashes on logout/death. I tried to repairt it with this guide, but couldn't get it to work. Maybe anyone else has a solution?
 
Back
Top