Ir para conteúdo
Entre para seguir isso  
Lwkass

Lib Spell (POO) !

Recommended Posts

Lwkass    1
Lwkass

┌───────────────────────────────────────────────┐

Nome: Spell System

Versão do script: 1.0.0

Tipo do script: System/Lib

Servidor Testado: The Forgotten Server 0.4.0 Crying Damson

Autor: Lwkass

───────────────────────────────────────────────┘

 

 

Bem, é uma lib que criei para criação de spells, também para mostrar um sistema com "POO" em lua, já vou dizendo que não é super super útil (talvez seja para alguns), mas como eu estava com vontade de fazer pode acabar ajudando a diminuir codes também.

 

 

Caracteristicas:

- Tiles com Delay e Condition independentes

- Verificações e Mensagens próprias

- Suporte a magias de area, direção, com target, de cura e/ou com condition

 

Script:

Apenas um script, crie um arquivo Lua com o nome de Spell-class.lua na pasta data/lib:

--[[

@	Spell System By Lwkass form OTServerBrasil !
@	Version: 1.0.0

-	Any questions (msn): [email protected]
]]

----------===================-------------
----		CONFIGURATIONS
----------===================-------------
SpellOptions = {
sendCastSay = true, -- true = Vai mandar uma mensagem sempre que usar uma spell
showAnimatedValues = true, -- true = Ativa efeito animado
onlySpellOwnerSeeAnimation = true -- true = Apenas o usuario da spell ve a animacao
}

---- Constantes
SPELL_TYPE_DIRECTION = 0
SPELL_TYPE_AREA = 1

----------===================-------------
----	   GENERAL FUNCTIONS
----------===================-------------

function getPosByArea(area, topleftpos)
arr = {}

for y, a in pairs(area) do
	arr[y] = {}
	for x, tile in pairs(a) do
		arr[y][x] = {x=(x-1)+topleftpos.x, y=(y-1)+topleftpos.y, z=topleftpos.z}
	end
end
return arr
end

function rotateArea(area, angle)
final = {}
angle = math.rad(angle)

for y, a in pairs(area) do
	for x, tile in pairs(a) do
		temp = {x = (x * math.cos(angle) + y * math.sin(angle)), y = (x * (-math.sin(angle)) + y * math.cos(angle))}
		e_x, e_y = (temp.x < 0 and #a + (temp.x) + 1 or temp.x), ((temp.y < 0 and #area + (temp.y) + 1 or temp.y))
		final[e_y] = final[e_y] or {}
		table.insert(final[e_y], e_x, tile or 0)
	end
end	
return final
end

----------===================-------------


SpellTile = {}

function SpellTile:create(combat, effect, damage)
--[[
	- Cria uma SpellTile

	Param:
		#1 (combat) = combat para o tile, válido todos os combats do tibia (exemplo: COMBAT_PHYSICALDAMAGE, COMBAT_ENERGYDAMAGE, COMBAT_MANADRAIN, etc...)
		#2 (effect) = efeito para o tile, válido todos os efeitos do tibia (exemplo: CONST_ME_DRAWBLOOD, CONST_ME_LOSEENERGY, CONST_ME_POOF, etc...)
		#3 (damage) = tabela de dano, que deve seguir esse modelo: {min = -dano_minimo, max = -dano_maximo}
]]
return setmetatable({
	combat = combat,
	effect = effect,
	damage = damage
}, {
	__index = self
})
end

function SpellTile:setCondition(condition)
--[[
	- Define uma condição para o SpellTile e retorna uma cópia do próprio SpellTile

	Param:
		#1 (condition) = Precisa ser uma condition válida do tibia, exemplo:
				condition = createConditionObject(CONDITION_POISON)
				setConditionParam(condition, CONDITION_PARAM_DELAYED, 1)
				addDamageCondition(condition, 10, 2000, -10)
]]
copy = SpellTile:create(self.combat, self.effect, self.damage)
copy.delay = self.delay
copy.center = self.center
copy.condition = condition
return copy
end

function SpellTile:setSpellCenter()
--[[
	- Define que esse SpellTile é o centro da magia e retorna uma cópia do próprio SpellTile
]]

copy = SpellTile:create(self.combat, self.effect, self.damage)
copy.delay = self.delay
copy.center = true
return copy
end

function SpellTile:delay(mili)
--[[
	- Define um delay para lançar o spelltile e retorna uma cópia do próprio SpellTile

	Param:
		#1 (mili) = Tempo em milisegundos até lançar o spelltile
]]

copy = SpellTile:create(self.combat, self.effect, self.damage)
copy.delay = mili
return copy
end


----------===================-------------
--[[

@	Spell System By Lwkass form OTServerBrasil !
@	Version: 1.0.0

-	Any questions (msn): [email protected]
]]
----------===================-------------

Spell = {}


-- Construtor
function Spell:create(spellwords, spelltype, options)
--[[ 
	- Cria uma nova spell

	Param:
		#1 (spellwords) = Palavras mágicas da spell
		#2 (spelltype) = Tipo da spell, é necessário utilizar os valores que estão no Spell-class.lua, por exemplo: SPELL_TYPE_DIRECTION (para spell com direção) ou SPELL_TYPE_AREA (para spell com area)
		#3 (options) = uma tabela com opções da spell, pode possuir esses valores (não é necessário colocar todos !):
			options = {
				level = 1, -- Level necessario
				maglevel = 1, -- Magic Level necessario
				mana = 100, -- Mana necessaria
				maxDistance = 3, -- Distancia máxima
				needWeapon = true, -- Se precisa estar usando alguma arma
				vocation = {1,2,3,4,5}, -- Vocações que podem usar a magia
				sex = 0, -- Sexo que pode usar a magia
				group = 2 -- Group minimo para usar a magia
			}
]]

return setmetatable({
	spellwords = spellwords, 
	spelltype = spelltype,
	level = options and options.level or 0, 
	maglevel = options and options.maglevel or 0,
	mana = options and options.mana or 0,
	options = options or {}
}, { 
	__index = self
})
end



-- Setters & Getters
function Spell:setArea(area)
--[[
	- Define a area da spell

	Param:
		#1 (area) = Uma tabela que segue o modelo padrão de magias (exemplo: {{1,1,1},{1,1,1},{0,3,1}})
]]
self.area = area
end

function Spell:setOption(option, value)
--[[
	- Define as opções

	Param:
		#1 (option) = opção (exemplo: mana, level...)
		#2 (value) = valor ou novo valor
]]
self.options = self.options or {}
self.options[option] = value
end


function Spell:setMaxDistance(n)
--[[
	- Define a distancia máxima para usar a spell, pode-se definir direto através da tabela options também (maxDistance = distancia)

	Param:
		#1 (n) = Distancia máxima
]]
self:setOption("maxDistance", n)
end


function Spell:setDefaultTile(tile)
--[[
	- Define a spellTile padrão para a spell (usa-se a marcação 1 na area)

	Param:
		#1 (tile) = precisa ser um spellTile
]]
self.dftTile = tile
end



-- Others
function Spell:getCreatureMark()
--[[
	- Procura e retorna a posição do tile que seja igual a 3 ou que esteja com a marcação tile.center = true
]]

for y, b in pairs(self.area) do
	for x, d in pairs( do
		if ((type(d) == "table" and d.center) or d == 3) then
			return {x = x,y = y}
		end
	end
end
end



-- Main Function
function Spell:cast(cid, target)
--[[
	- Lança a magia

	Param:
		#1 (cid) = usuario da magia
		#2 (target) = alvo da magia (se necessário)
]]

if (not isCreature(cid)) then
	return print('[spellClass - Warning / "'.. self.spellwords ..'"]: The cid must be a creature !')
end


-- Target checks
if (target) then
	if (not isCreature(target)) then -- Target is not selected
		return doPlayerSendCancel(cid, "You need a target.")
	end

	if (self.spelltype == SPELL_TYPE_DIRECTION) then
		return print('[spellClass - Warning / "'.. self.spellwords ..'"]: Set the spelltype to SPELL_TYPE_AREA or remove the param target from the method \'cast\' !')
	end
end

-- Options
for option, value in pairs(self.options) do
	if (target and option == "maxDistance" and type(value) == "number") then
		if (getDistanceBetween(getThingPos(cid), getThingPos(target)) > value) then
			return doPlayerSendCancel(cid, "Target too far.")
		end
	elseif (option == "needWeapon" and value) then
		if (getPlayerWeapon(cid).uid == 0) then
			return doPlayerSendCancel(cid, "You need be using a weapon.")
		end
	elseif (option == "vocation" and type(value) == "table") then
		if (not isInArray(value, getPlayerVocation(cid))) then
			return doPlayerSendCancel(cid, "Your vocation can't use this spell.")
		end
	elseif (option == "sex" and type(value) == "number") then
		if (not getPlayerSex(cid) == value) then
			return doPlayerSendCancel(cid, "Your sex can't use this spell.")
		end
	elseif (option == "group" and type(value) == "number") then
		if (not getPlayerGroupId(cid) >= value) then
			return doPlayerSendCancel(cid, "You can't use this spell.")
		end
	end
end

-- Cid checks
if (isPlayer(cid)) then
	if (getPlayerLevel(cid) >= self.level) then
		if (getPlayerMagLevel(cid) >= self.maglevel) then
			if (getCreatureMana(cid) >= self.mana) then
				doCreatureAddMana(cid, -(self.mana))
				if (SpellOptions.showAnimatedValues) then
					doSendAnimatedText(getThingPos(cid), self.mana, COLOR_PURPLE, (SpellOptions.onlySpellOwnerSeeAnimation and cid or false))
				end
			else
				return doPlayerSendCancel(cid, "You need " .. self.mana .. " of mana to use this spell.")
			end
		else
			return doPlayerSendCancel(cid, "You need magic level " .. self.maglevel .. " or greater to use this spell.")
		end
	else
		return doPlayerSendCancel(cid, "You need level " .. self.level .. " or greater to use this spell.")
	end
end


-- Direction change
if (self.spelltype == SPELL_TYPE_DIRECTION) then 
	local dir = {[0] = 0, [1] = 270, [2] = 180, [3] = 90}
	self:setArea(rotateArea(self.area, dir[getCreatureLookDirection(cid)]))
end


-- Main
local playerPos, player = getThingPos((target or cid)), self:getCreatureMark()
local theArea = getPosByArea(self.area, {x=playerPos.x - player.x + 1, y=playerPos.y - player.y + 1, z=playerPos.z})

if (SpellOptions.sendCastSay) then
	doCreatureSay(cid, getCreatureName(cid) .. " casts " .. self.spellwords .. " !", TALKTYPE_MONSTER)
end

for y, b in pairs(self.area) do
	for x, _tile in pairs( do
		local tilePos = theArea[y][x]
		local tile = ((_tile == 1) and self.dftTile or _tile)

		if (tile ~= 0 and tile ~= 3) then
			if (tile.condition) then
				doAreaCombatCondition(cid, tilePos, {1}, tile.condition, tile.conditionEffect or CONST_ME_NONE)
			end
			addEvent(doAreaCombatHealth, tile.delay or -1, cid, tile.combat, tilePos, {1}, tile.damage.min, tile.damage.max, tile.effect)
		end
	end
end

return true
end

--[[

@	Spell System By Lwkass form OTServerBrasil !
@	Version: 1.0.0

-	Any questions (msn): [email protected]
]]

 

Caso seu server não carregue automaticamente o script, tente adicionar essa linha a qualquer outro arquivo lua da pasta lib:

dofile('data/lib/Spell-class.lua')

 

Pronto !

 

Aqui um exemplo de spell com esse sistema:

function onCastSpell(cid, var)
spell = Spell:create("spell", SPELL_TYPE_DIRECTION, {mana = 100, level = 10, maglevel = 5})
tile = SpellTile:create(COMBAT_PHYSICALDAMAGE, 15, {min = -1, max = -2}):delay(500)

spell:setArea({
	{tile, tile, tile},
	{0, tile, 0},
	{0, tile, 0},
	{0, 3, 0}
})

spell:cast(cid)
end

 

Usos:

Você pode usar assim também a area se quiser:

	spell:setArea({
	{tile:delay(10), tile, tile:delay(620)},
	{0, tile:delay(100), 0},
	{0, tile, 0},
	{0, 3, 0}
})

Cada spelltile vai aparecer no delay que estiver ali marcado e os que não estiverem aparecerão no delay = 500 (que está definido em 'tile').

 

----

 

Para adicionar conditions pode ser feito assim:


local condition = createConditionObject(CONDITION_FIRE)
setConditionParam(condition, CONDITION_PARAM_DELAYED, 1)
addDamageCondition(condition, 10, 2000, -10)

spell:setArea({
{tile:delay(10), tile, tile:delay(620)},
{0, tile:delay(100):setCondition(condition), 0},
{0, tile, 0},
{0, 3, 0}
})

Apenas o tile que está com o setCondition vai receber a condition !

 

----

 

Para uma spell de area que é lançada em um alvo é necessário deixar a spell dessa maneira:

function onCastSpell(cid, var)
spell = Spell:create("spell", SPELL_TYPE_AREA, {mana = 100, level = 10, maglevel = 5})
tile = SpellTile:create(COMBAT_PHYSICALDAMAGE, 15, {min = -1, max = -2}):delay(500)

spell:setArea({
	{tile, tile, tile},
	{0, tile, 0},
	{0, tile:setSpellCenter(), 0}
})

spell:cast(cid, getCreatureTarget(cid))
end

 

----

 

Mas caso você queira definir um spelltile como padrão para a spell (Sempre que usar o 1 na area esse spelltile será chamado), você pode fazer assim:

 

function onCastSpell(cid, var)
spell = Spell:create("spell", SPELL_TYPE_DIRECTION, {mana = 100, level = 10, maglevel = 5})
spell:setDefaultTile(SpellTile:create(COMBAT_ENERGYDAMAGE, 30, {min = -1, max = -2})) -- Define o tile padrão
tile = SpellTile:create(COMBAT_PHYSICALDAMAGE, 15, {min = -1, max = -2}):delay(500)

spell:setArea({
	{tile, tile, tile},
	{1, 1, 1},
	{1, tile, 1},
	{0, 3, 0}
})

spell:cast(cid)
end

Então sempre que usar o numero 1 na area ele será substituido pelo spelltile padrão !

 

 

Todas as funções estão comentadas, em caso de dúvida sobre como usar uma função, leia o código-fonte ou pergunte aqui mesmo

Editado por Lwkass
tinha esquecido 2 funções riarairairia

Compartilhar este post


Link para o post
Majesty    1755
Majesty

Obrigado pela sua contribuição, Aprovado.

 

Remuneração: Biblioteca - 40 V$.

Compartilhar este post


Link para o post
dalvorsn    46
dalvorsn

Lwkass como sempre humilhando nos scripts ._.

Quando eu crescer quero ser igual a vocẽ HEIEH' :D

Cara muito foda essa lib, e tu mostra também formas de usar OO em lua de maneira útil

 

#Majesty

Sugestão, porque não convida o Lwkass para ser sub-mod da seção de scripts?

O cara ta contribuindo pacas com a OTBr, além de ter muito conhecimento na área :D

Compartilhar este post


Link para o post
Rules Violations    0
Rules Violations

@lwkass

mt maneirinha essa lib, gtz.

 

@dalvorsn

o bixinhu paga pau dos infernos o.O ... sem ofenssas ^^

Compartilhar este post


Link para o post
dalvorsn    46
dalvorsn
@lwkass

mt maneirinha essa lib, gtz.

 

@dalvorsn

o bixinhu paga pau dos infernos o.O ... sem ofenssas ^^

 

Brother fica na sua, quem é você para falar de mim?

Existe uma coisa que chama merecimento, e o lwkass faz por merecer os elogios.

Compartilhar este post


Link para o post
Geovani    0
Geovani

@topic

Antes de você trazer essa lib para o forum, tem alguma função para adicionar delay na spell - ex : exevo vis lux, efeito sobre o player - 3seg depois spell sai?

 

 

@ToTopic

Sem ofenças \o/?

nem que seja ofença paga pal .....

não se fala mal até por que você não sabe "nada" sobre o @Dalvorsn e nem sequer sobre o @Lwkass

o Dalvo tem todo direito de falar até por que ele é o cara que ta trazendo "tudo" TUDO de pokemon pro forum, novos systems tem feito por ele sem dizer que ele traz e simplismente não fala "Há cria isso.lua adicionar essa tag lá.. e deu ta feito so editar a seu gosto" ele traz com intuito de ensinar "copia isso e apartir disso faça do seu jeito.. para isso faça isso.. para mais adicione isso.."

Ele tem direito sim de pedir sub-mod até por que ele e um cara que aprendeu de script e aprendeu muito rapido (sendo que ele fala que é intermediario) se ele é intermediario eu queria ver um advanced \o

 

@lwkass cara que ta inovando o jeito POO e trazendo diversas maneiras de se ver editar tibiaot - No comments

 

K.ISSO não é ser paga pal e sim "admitir que tem gente querendo sempre melhorar e claro com a melhora vem o "destaque" oque faz com que as pessoas se destaquem ainda mais,diferente de outras que vêem simples ato de bajulação essas não tem metade do cerebro de quem ta simplismente "pedindo para sub-mod" e nem 0,25 de quem ta inovando.

 

Existe uma coisa que chama merecimento, e o lwkass faz por merecer os elogios.
²

Totalmente Correto- seja lwkass,raposão,urso,iuniX,Dalvorsn e todos do forum que tão ajudando.

Compartilhar este post


Link para o post
Lwkass    1
Lwkass

Sem mais discussões no tópico.

 

@Geovani:

Para adicionar um delay pra sumir depois de um certo tempo, é só adicionar isso na spell:

addEvent(doRemoveCondition, 3000, cid, CONDITION_LIGHT)

Depois de 3 segundos vai remover a luz

Mas vou ver se quando eu for modificar eu adiciono algo desse tipo direto na lib

Compartilhar este post


Link para o post
Geovani    0
Geovani

Thanks

REP+

Pela lib e pela duvida

^^

Compartilhar este post


Link para o post
Rômulo Souza    14
Rômulo Souza
Caramba, to revivendo um tópico extremo antigo. Mas creio que as regras do forum aceita reviver com dúvidas, né? enfim:

Eu usando essa lib em talkaction, ele reconhece como mérito de tentativa de subir skill? de ml por exemplo.

Compartilhar este post


Link para o post
Lwkass    1
Lwkass

Rômulo Souza:

Mesmo sendo uma duvida de quase um mes atrás.

Não, quando fiz essa lib não coloquei pra upar skill, se quiser, infelizmente, vai ter que adicionar uma linha pra upar ml.

Compartilhar este post


Link para o post
Merfolk    0
Merfolk

gastou um tempão fazendo uma parada inútil, fico imaginando o tempo que você gasta fazendo coisas uteis! xD

Compartilhar este post


Link para o post
Lwkass    1
Lwkass

Merfolk:

um carro pode ser inútil se você não souber dirigir, muito menos como ligar ou trocar uma marcha. fica ai a dica

e ah, qualquer coisinha que eu programe já me é útil :]

Compartilhar este post


Link para o post
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  
  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×