Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Spell wave help me pls


Nowix93

Rekomendowane odpowiedzi

Opublikowano

Witam wszystkich serdecznie.
Tworze skrypcik spell w lua [TFS 1.3]  ale że dopiero raczkuje (bardziej znam c++) to nie mogę sobie za bardzo poradzić.
chodzi o (gif przed większymi zmianami w lua bez areax)

83647270_798773963940740_6734052358377963520_n.gif

chce aby był to spell dynamiczny bez potrzeby zaznaczania targetu i mam problem bo nie wiem jak to zrobić ~moj spell
 

Spoiler

-- Delay between animations.
local animationDelay = 200
local combat = {}


-- Frames (1 = Area, 2 = Player, 3 = Player + Self Damaging)
local area = {}
local area0 = {
    {
        {1, 0, 0},
        {0, 2, 0},
        {0, 0, 0}
    },
    {
        {0, 1, 0},
        {0, 2, 0},
        {0, 0, 0}
    },
    {
        {0, 0, 1},
        {0, 2, 0},
        {0, 0, 0}
    }
}

local area1 = {
    {
        {0, 0, 1},
        {0, 2, 0},
        {0, 0, 0}
    },
    {
        {0, 0, 0},
        {0, 2, 1},
        {0, 0, 0}
    },
    {
        {0, 0, 0},
        {0, 2, 0},
        {0, 0, 1}
    }
}

local area2 = {
    {
        {0, 0, 0},
        {0, 2, 0},
        {0, 0, 1}
    },
    {
        {0, 0, 0},
        {0, 2, 0},
        {0, 1, 0}
    },
    {
        {0, 0, 0},
        {0, 2, 0},
        {1, 0, 0}
    }
}

local area3 = {
    {
        {0, 0, 0},
        {0, 2, 0},
        {1, 0, 0}
    },
    {
        {0, 0, 0},
        {1, 2, 0},
        {0, 0, 0}
    },
    {
        {1, 0, 0},
        {0, 2, 0},
        {0, 0, 0}
    }
}

	local north = 0
	local east = 1
	local south = 2
	local west = 3
	--local creature = creature:getid()
	
	function gd()
	
	--local creature = player(cid)
	local creature = creature:getid()
	local cDir = creature:getDirection()
	local cPos = creature:getPosition ()
	local pos = (Position(0,0,0))
	if 	cDir == north then
		if not getTileInfo(cPos).house and not getTilePzInfo(cPos) then
		for i, _ in ipairs(area0) do
			area[i] = area0[i]
		end	
		end
	elseif cDir == east then
		if not getTileInfo(cPos).house and not getTilePzInfo(cPos) then
			for i, _ in ipairs(area1) do
			area[i] = area1[i]
		end
		end
	elseif cDir == south then
		if not getTileInfo(cPos).house and not getTilePzInfo(cPos) then
			for i, _ in ipairs(area2) do
			area[i] = area2[i]
		end
		end
	elseif cDir == west then
		if not getTileInfo(cPos).house and not getTilePzInfo(cPos) then
		for i, _ in ipairs(area3) do
			area[i] = area3[i]
		end
		end
		end
		return area
		end
		
		local area = gd()
		--local creature = player(cid)
		--local creature:getDirection()
		--local area = cDir(creature:getDirection())
		--local area = creature:getPosition():creature:getDirection()

for i = 1, #area do
    combat[i] = Combat()
    combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE)
    combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA)
end

for x, _ in ipairs(area) do
    combat[x]:setArea(createCombatArea(area[x]))
end

function executeCombat(p, i)
    if not p.player then
        return false
    end
    if not p.player:isPlayer() then
            return false
    end
    p.combat[i]:execute(p.player, p.var)
end

function onCastSpell(player, var)

    local p = {player = player, var = var, combat = combat}

    -- Damage formula
    local level = player:getLevel()
    local maglevel = player:getMagicLevel()
    local min = (level / 5) + (maglevel * 1.4) + 8
    local max = (level / 5) + (maglevel * 2.2) + 14

    for i = 1, #area do
        combat[i]:setFormula(COMBAT_FORMULA_LEVELMAGIC, 0, -min, 0, -max)
        if i == 1 then
            combat[i]:execute(player, var)
        else
            addEvent(executeCombat, (animationDelay * i) - animationDelay, p, i)
        end
    end

    return true
end

 

chce przepisać po prostu odpowiednią tablice bo nie mam pomysłu jak to inaczej napisać ale i tak mam większy problem bo nie wiem jak używać funkcji z silnika tibi więc nie wiem jak na to zareagować.

a mianowicie chodzi o ten komunikat z konsoli
attempt to index global 'creature' (a nil value)

jak mam to ustawić aby pobrało jakaś wartość ?

przez funkcje konkretna? próbowałem np creature = creature:getid() 
ale to nie trybi wiec to zły trop ;/
mecze się z tym już dobre parę dni i nic nie mogę ruszyć 
macie może jakiś pomysł?

Opublikowano

Używając spella wywołujesz funkcję  

function onCastSpell(player, var)

a nie cały skrypt z pliku, więc jeśli chcesz wykonać jakąś funkcję tak jak w twoim przypadku np.

function gd()

musisz przekazać jej odpowiednie argumenty takie jak np. creature

Tylko, że co miało by oznaczać to creature w przypadku twojego skryptu ? Trafiony cel przez twój spell czy gracza wykonującego spell ?

Jeśli gracza to sprawa jest prosta bo do funkcji gd przekazujesz playera z onCastSpell

function gd(player)

Jeśli trafionego gracza a czar jest targetem można pobrać go używając funkcji:

target = getCreatureTarget(player)	-- nie wiem czy ta funkcja występuje w TFS 1.0+

Można też użyć zmiennej var 

Cytat

- number = CID of target creature/player (selected on battle window)
- position = position of target creature/player OR position in front of casting player if it's wave spell
- string = name of target player (for spells like 'exura sio "gesior')


number = variantToNumber(var) // returns 0, if not set
string = variantToString(var) // returns empty string, if not set
position = luaVariantToPosition(var) // returns {x=0, y=0, z=0, stackpos=0}, if not set

 

Jeśli chodzi o obszar to sprawdzał bym pozycje na których ten obszar działa i pobierał wtedy creature.

 

Nie wiem czy chodziło ci dokładnie o to ale polecam ci poprzeglądać jakieś gotowe spelle na np. otlandzie i powinieneś szybko zaczaić z czym to sie je.

Link do Otland: https://otland.net/forums/globalevents-spells-creatureevents.82/

 

PS: Chodziło ci aby spell uderzał zawsze przed siebie ?

W spells.xml dodaj

direction="1"

 

Opublikowano

Dzięki wielkie za odpowiedz trochę się różnią funkcje ale sprawdzam tu są aktualne pod 1.3 chyba 😄
Trochę rozjaśniłeś mi sytuacje metodą prób i błędów udało mi się zrobić aby to działało czyli po dziesiątkach godzin dodałem direction="1" 😄
i za pomocą magicznej rożczki działa xd przeglądam sporo otlanda ale nie widziałem tam komentarza aby zwrócić na to uwagę  ahh 
no nic w każdym razie jeszcze raz dzięki 😄
mam jeszcze 2 pytania jak byś był w stanie mi pomoc było by super 🙂

skrypcik
 

Spoiler

-- Delay between animations.
local animationDelay = 100
local combat = {}

-- Frames (1 = Area, 2 = Player, 3 = Player + Self Damaging)
local area = {
    {
        {0, 0, 0},
        {1, 2, 0},
        {0, 0, 0}
    },
    {
        {0, 0, 0},
        {0, 0, 0},
        {0, 3, 0}
    },
    {
        {0, 0, 0},
        {0, 2, 1},
        {0, 0, 0}
    }
}
-- bleeding
	local bleeding = Condition(CONDITION_BLEEDING)
	bleeding:setTicks(9000)
	bleeding:setParameter(CONDITION_PARAM_DELAYED, 1)
	bleeding:setParameter(CONDITION_PARAM_TICKINTERVAL, 3000)

for i = 1, #area do
    combat[i] = Combat()
	combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
    combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA)
	combat[i]:addCondition(bleeding)
end

for x, _ in ipairs(area) do
    combat[x]:setArea(createCombatArea(area[x]))
end

function executeCombat(p, i)
    if not p.player then
        return false
    end
    if not p.player:isPlayer() then
            return false
    end
    p.combat[i]:execute(p.player, p.var)
end


	
	function CastSpell(p, var)
	local var = var.var
    local player = p.player
	local combat = combat.combat
    local level = player:getLevel()
    local maglevel = player:getMagicLevel()
    min = -((level / 5) + (maglevel * 6) + 50)
    max = -((level / 5) + (maglevel * 12) + 75)
    bleeding:setParameter(CONDITION_PARAM_PERIODICDAMAGE, math.random(min,max))
    end

function onCastSpell(player, var)
	
    local p = {player = player, var = var, combat = combat}	

    -- Damage formula
    local level = player:getLevel()
    local maglevel = player:getMagicLevel()
    local min = (level / 5) + (maglevel * 1.4) + 8
    local max = (level / 5) + (maglevel * 2.2) + 14

    for i = 1, #area do
        combat[i]:setFormula(COMBAT_FORMULA_LEVELMAGIC, 0, -min, 0, -max)
        if i == 1 then
			CastSpell(p, var)
            combat[i]:execute(player, var)
        else
            addEvent(executeCombat, (animationDelay * i) - animationDelay, p, i)
			end
    end

    return true
end

 


mianowicie dodałem krwawienie prawiłem niby wszystko, błędów nie ma ale nie działa nie narzuca efektu albo formuła jest zła chociaż wygląda dobrze.
i pytanko 2 czy znasz sposób aby przed spellem dodać jakieś daley? z tego co widzę chyba tylko addevent ma opcje daleyu ;x

Opublikowano

Tak, opóźnienia robisz głównie w addEvent tylko, że z nim jest taki problem, że gracz wykonujący albo target może zniknąć (zginąc) w trakcie jego wykonywania i zmieni sie jego CID przez co wysypie błędy w konsoli.

Opublikowano

W nowszych silnikach tez występuje? nie spotkałem się jeszcze z tym ale dzięki na pewno zworce na to uwagę

Opublikowano

Witam ponownie mam pytanko czy wiesz może jak dodać jeden czar do drugiego głownie mi chodzi o dodanie niewidzialności na mnie gdzie używam wave,
próbuje rożne mozliowsci ale coś mi nie wychodzi

 

GIF.gif

a tutaj kod może widzisz co robię nie tak ;/

dodałem drugi combat myślałem ze to może być powodem i pewnie po części miałem racje ale i tak nie działa jak powinno ;x

btw var = variant oznacza coś konkretnego ?

 

Spoiler

 


-- Delay between animations.
local animationDelay = 150
local combat = {}
local combat2 = Combat()
--local combat2 = ()

-- Frames (1 = Area, 2 = Player, 3 = Player + Self Damaging)
local area = {
     {
        {0, 0, 0},
        {0, 2, 0},
        {0, 0, 0}
    },
	{
        {0, 0, 0},
        {1, 2, 0},
        {0, 0, 0}
    },
    {
        {0, 0, 0},
        {0, 0, 0},
        {0, 3, 0}
    },
    {
        {0, 0, 0},
        {0, 2, 1},
        {0, 0, 0}
    }
}
-- cast
local cast = Condition(CONDITION_CAST)
--stun:setParameter(CONDITION_PARAM_TICKS, stunDuration)
--combat:addCondition(cast)
--invisible
function invisible(p)
local creature = p.player
local variant = p.var
local combat = p.combat2
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local invisible = Condition(CONDITION_INVISIBLE)
invisible:setParameter(CONDITION_PARAM_TICKS, 600)
combat:addCondition(invisible)
	return combat:execute(creature, variant)
end
-- bleeding
local bleeding = Condition(CONDITION_BLEEDING)
bleeding:setParameter(CONDITION_PARAM_DELAYED, 10)
bleeding:addDamage(15, 1000, -50)

for i = 1, #area do
    combat[i] = Combat()
	combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
    combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA)
	if math.random(1, 100) > 70 then
	combat[i]:addCondition(bleeding)
	end
end

for x, _ in ipairs(area) do
    combat[x]:setArea(createCombatArea(area[x]))
end

function executeCombat(p, i)
    if not p.player then
        return false
    end
    if not p.player:isPlayer() then
            return false
    end
    p.combat[i]:execute(p.player, p.var)
end

function onCastSpell(player, var)
	
    local p = {player = player, var = var, combat = combat, combat2 = combat2}	

    -- Damage formula
    local level = player:getLevel()
    local maglevel = player:getMagicLevel()
    local min = (level / 5) + (maglevel * 1.4) + 8
    local max = (level / 5) + (maglevel * 2.2) + 14

	invisible(p)
    for i = 1, #area do
        combat[i]:setFormula(COMBAT_FORMULA_LEVELMAGIC, 0, -min, 0, -max)
        if i == 1 then
            combat[i]:execute(player, var)
        else
            addEvent(executeCombat, (animationDelay * i) - animationDelay, p, i)
			end
    end

    return true
end
Opublikowano

dodajesz na gorze condition od niewidzialności i potem go wywołujesz przed returnem (albo przed damage) na tfs 0.3.6:

doAddCondition(cid, condition)

nie musisz go dodawać do combatu

 

a o var napisałem w 1 poscie

Opublikowano

Wielkie dzięki pomoc działa 🙂
jak będę miał więcej pytań (a na pewno będę miał) napisze je w tym temacie żeby burdelu nie robić ;x

Opublikowano

 

Mam kolejne 2 pytania bo mimo że wszystko działa to jednak nie wiem do końca dlaczego tak jest a mianowicie w kodzie
 

Spoiler

-- Delay between animations.
local animationDelay = 200
local stunDuration = 4000
local combat = {}

-- cast
local 	cast = Condition(CONDITION_CAST)
		cast:setParameter(CONDITION_PARAM_TICKS, 400)
		cast:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE)

-- invisible
local 	invisible = Condition(CONDITION_INVISIBLE)
		invisible:setParameter(CONDITION_PARAM_TICKS, 400)
		--invisible:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
		--invisible:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

-- bleeding
local 	bleeding = Condition(CONDITION_BLEEDING)
		bleeding:setParameter(CONDITION_PARAM_DELAYED, 5)
		bleeding:addDamage(5, 1000, 10)

-- stun
local 	stun = Condition(CONDITION_STUN)
		stun:setParameter(CONDITION_PARAM_TICKS, stunDuration)
		stun:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BUBBLES)


-- Frames (1 = Area, 2 = Player, 3 = Player + Self Damaging)
local area = {
     {
        {0, 0, 0},
        {0, 2, 0},
        {0, 0, 0}
    },
	{
        {0, 0, 0},
        {0, 3, 0},
        {0, 0, 0}
    }
}

function bleedmath(p, i)
math.randomseed(os.time())
local bleed = math.random(100)
--print(bleed)
	if bleed < 30 then
	p.combat[i]:addCondition(bleeding)
end
end

 -- if Player then /2
function stuns(p)
	
	for i, _ in ipairs(area) do
		p.combat[i]:addCondition(stun)	
		if 	p.var:isPlayer() then
			stunDuration = stunDuration / 2 	
		end
	end
end

for i = 1, #area do
    combat[i] = Combat()
	combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
    combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA)
	--combat[i]:addCondition(stun)
end

for x, _ in ipairs(area) do
    combat[x]:setArea(createCombatArea(area[x]))
end

function executeCombat(p, i)
    if not p.player then
        return false
    end
    if not p.player:isPlayer() then
            return false
    end	
    p.combat[i]:execute(p.player, p.var)
end

function onCastSpell(player, var)

	
    local p = {player = player, var = var, combat = combat}	
	
    -- Damage formula
    local level = player:getLevel()
    local maglevel = player:getMagicLevel()
    local min = (level / 5) + (maglevel * 1.4) + 8
    local max = (level / 5) + (maglevel * 2.2) + 14
	
	doAddCondition(p.player, invisible)
	doAddCondition(p.player, cast)
	stuns(p)
	
	
    for i = 1, #area do
        combat[i]:setFormula(COMBAT_FORMULA_LEVELMAGIC, 0, -min, 0, -max)
        if i == 1 then
            combat[i]:execute(player, var)
        else
			--bleedmath(p, i)
            addEvent(executeCombat, (animationDelay * i) - animationDelay, p, i)
			end
    end

    return true
end

 

w ostatniej funkcji onCastSpell jest wywołanie player i var 
widać ewidentnie ze player to player chociażby po getlevel wiec var oznacza potworka ewentualnie gracza który będzie w zasięgu tak?
ale w funkcji stuns jak próbuje odnieść się do p.var konsola wywala błąd
 

attempt to call method 'isPlayer' (a nil value)

za to z p.player wszystko działa ;o
wiesz może dlaczego tak jest?
pytanie drugie chodzi o area spella bo gdy ustawie normalnie
 

{0, 1, 0}
{0, 2, 0}
{0, 0, 0}

to zamiast uderzać kratke przede mną uderza
GIF.gif

muszę użyć 3 i oczywiście da się to i tak poustawiać ale zastanawiam się dlaczego tak jest

@edit:

jednak nie działa ten if dodałem getposition ale nadal isPlayer bez wartosci ;/

Spoiler

function stuns(p)
	for i = 1, #area do
		p.combat[i]:addCondition(stun)
		--local creature = p.combat[i]:getCreatures()
		local pla = p.combat[i]:getPosition()
		if 	pla:isPlayer() then
			stunDuration = 10000	
		end
	end
end

 

albo

Spoiler

 


-- if Player then /2
function stuns(p)
	for i = 1, #area do
		p.combat[i]:addCondition(stun)
		--local creature = p.combat[i]:getCreatures()
		--local pla = area[i]:getPosition()
		if 	area[i]:isPlayer() then
			stunDuration = 10000	
		end
	end
end

próbuje mniej więcej coś takiego ale cały czas isplayer bez wartości ;/  

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...