Page 1 of 1

[Spell] "manaCost" depending on "skill"

Posted: Tue May 27, 2014 6:39 pm
by MasterJoe
Hello people,
As the title says, I try the mana cost to adapt the skills (if the ability is high, then the spell be more expensive). The attack power is expected to increase as well (if possible...).

I've already tried some things:

Code: Select all

defineSpell{ 
	name = "fireburst",
	uiName = "Fireburst",
	skill = "fire_magic",
	level = 2,
	runes = "B",
	manaCost = 0,
	onCast = function(caster, skill)
	local champName = caster:getName()
		if caster:getStat("energy") < variable_storage.round(skill / 2 + 15) then
			hudPrint(champName .. " don't have enough energy to cast this spell.")
			return false
		else
			caster:modifyStat("energy", variable_storage.round(skill / 2 + 15))
			return "fireburst" --<----- how do I trigger this spell? 
		end
	end,
}

Works only conditionally ^ ^ (Mana is checked etc.. BUT ... no "spell" triggers)

Re: [Spell] "manaCost" depending on "skill"

Posted: Wed May 28, 2014 11:18 pm
by JohnWordsworth
Hi MasterJoe, I've got two solutions for you!

First of all, just a few things that aren't quite right with your understanding of how defineSpell works.

1. Your function definition for onCast is wrong, it should read... onCast = function(caster, x, y, direction, skill). You can't pick and choose the parameters that get passed, the given 5 parameters will always get passed - you just get to decide what name your code will use for them. As such, what you think is skill in your function is actually just using the first two parameters that are passed and calling them 'caster' and 'skill', although as you will notice above - the second parameter is the x coordinate of the party. This is probably what is causing the problem with it only sometimes working.

2. By defining your own fireburst spell, you are completely overriding the original fireburst spell description. This means that the original spell is essentially hidden away and cannot be accessed any more. However, the fireburst effect appears to still work if you call 'spawn("fireburst", level, x, y, facing)' in code - so I imagine that the spell definitions are different to the 'object' that is a fireburst in the game world.

3. onCast can only ever return true or false. True means the spell worked and false means it didn't. However, these return values have little effect on what happens next (apart from whether the mana cost of the spell should be deducted).

So, with this knowledge, we can build a simple version of your spell that will simply summon the original fireburst effect in front of the party and a more advanced version where you can emulate the fireburst effect but using your own damageTile call to actually define how much damage is caused by the spell. You probably want the second, but I include both for information.

Solution A - Spawn original FireBurst effect, but with custom mana cost.
SpoilerShow

Code: Select all

defineSpell{ 
	name = "fireburst",
	uiName = "Fireburst",
	skill = "fire_magic",
	level = 2,
	runes = "B",
	manaCost = 0,
	onCast = function(caster, x, y, direction, skill)
		local castingCost = 15 + math.ceil(skill / 2);
	
		if ( caster:getStat("energy") < castingCost ) then
			hudPrint(caster:getName() .. " doesn't have enough energy to cast this spell.");
			return false;
		end
		
		local dx, dy = getForward(party.facing);
		local targetX = party.x + dx;
		local targetY = party.y + dy;
		
		if ( isWall(party.level, targetX, targetY) ) then
			targetX = party.x;
			targetY = party.y;
		end
		
		caster:modifyStat("energy", -castingCost);
		spawn("fireburst", party.level, targetX, targetY, party.facing);
	end
}
Solution B - Fake the fireburst effect by creating the particle system and dealing damage yourself. The best thing about this is that you can determine how much damage is dealt. The bad thing is that it's a bit more complicated.
SpoilerShow

Code: Select all

defineSpell{ 
	name = "fireburst",
	uiName = "Fireburst",
	skill = "fire_magic",
	level = 2,
	runes = "B",
	manaCost = 0,
	onCast = function(caster, x, y, direction, skill)
		local castingCost = 15 + math.ceil(skill / 2);
		local spellPower = 15 + math.ceil(skill / 2);
		print(castingCost, spellPower);
	
		if ( caster:getStat("energy") < castingCost ) then
			hudPrint(caster:getName() .. " doesn't have enough energy to cast this spell.");
			return false;
		end
		
		local dx, dy = getForward(party.facing);
		local targetX = party.x + dx;
		local targetY = party.y + dy;
		
		local damageBitRecoil = 1;
		local damageBitChamp = {};
		damageBitChamp[1] = 4;
		damageBitChamp[2] = 8;
		damageBitChamp[3] = 16;
		damageBitChamp[4] = 32;
		
		local damageFlags = damageBitRecoil + damageBitChamp[caster:getOrdinal()];
		
		if ( isWall(party.level, targetX, targetY) ) then
			targetX = party.x;
			targetY = party.y;
		end
		
		caster:modifyStat("energy", -castingCost);
		spawn("fx", party.level, targetX, targetY, party.facing):setParticleSystem("fireburst"):translate(0, 1.5, 0);
		damageTile(party.level, targetX, targetY, party.facing, damageFlags, "fire", spellPower);
	end
}
Both of these spells currently suffer from a problem that they will work through a closed door. ie. Casting this on a closed door will still cause it to damage the other side. I'll leave it to you to fix that bug. It will likely require you to iterate through the entities in your space and the target space and look for a door entity that's in the way. If you get stuck with this, let me know - but I'll leave it with you for now!

Re: [Spell] "manaCost" depending on "skill"

Posted: Wed Jul 23, 2014 3:20 pm
by MasterJoe
Hmm... :?: didn't get it. Effect go through gates, secret doors, closed doors, etc..

Is there a command: "IsDoor"? :D

Re: [Spell] "manaCost" depending on "skill"

Posted: Wed Jul 23, 2014 6:53 pm
by Leki
Hahaha John - it was crazy party last night I gues :lol:

Sending this pour soul in "entitiesAt hell" when door class is not supported because of some kind of finlandian humor - is really not a good idea. He can detect door only by IsClosed(), but in that case he must ignore pits atd stuf like that (thx Diarmund - I really hate this in my SuperSpider scripts) 8-)

To damage cell just extend onCast with shootProjectile (add party in ignore attribute for sure), starting on party cell in hight = 3m, at border of party cell - and hit the cell in front of party under sharp angle (use gravity to damage farest border of the cell in front of you that) - game will calculate collisions. If you wanna use it for fireball leave gravity as 0 and height set to 1.2


Code: Select all

defineSpell{
   name = "fireburst",
   uiName = "Fireburst",
   skill = "fire_magic",
   level = 2,
   runes = "B",
   manaCost = 0,
   onCast = function(caster, x, y, direction, skill)
      local castingCost = 15 + math.ceil(skill / 2);
   
      if ( caster:getStat("energy") < castingCost ) then
         hudPrint(caster:getName() .. " doesn't have enough energy to cast this spell.")
         return false
      end
      
      aditionalDamage = 10 -- make your calculations here
      shootProjectile("my_custom_projectile", party.level, party.x, party.y, party.facing, 50, 20, 0, 0, 0, 3,  aditionalDamage, party, true, caster) --or smth like that, you have to test offset and gravity (you can replace "my_custom_projectile" with "rock" to see it during testing, if it's ok, then define invisible custom projectile)
      return true
end
}

Re: [Spell] "manaCost" depending on "skill"

Posted: Wed Jul 23, 2014 11:08 pm
by Chimera005ao
Why didn't I know shootProjectile was a thing?
I've been checking the direction the party was facing and using spawn...

Re: [Spell] "manaCost" depending on "skill"

Posted: Thu Jul 24, 2014 5:53 pm
by MasterJoe
And then, you "shoot" through closed doors, secret walls, etc. :D

Re: [Spell] "manaCost" depending on "skill"

Posted: Thu Jul 24, 2014 7:22 pm
by Chimera005ao
Is there a command: "IsDoor"?
To answer that, here is a block I have for one direction of my spell being cast...
I used "for e in entitiesAt()" to check all objects in the direction the party is facing. Objects of certain types were there, it won't cast.

Code: Select all

if direction == 0 then
			if isWall(party.level, party.x, party.y - 1) then
				blocked = 1
			end
			for e in entitiesAt(party.level, party.x, party.y - 1) do
				if e.class == "Monster" or e.class == "Altar" or e.class =="Blockage" or e.class == "Crystal" or e.class == nil then
					blocked = 1
				else
					blocked = 0
				end
			end
			if blocked == 0 then
				playSound("frostburst")
				spawn("ice_block", party.level, party.x, party.y -1, 0)
			else
				print("Spell obstructed")
			end	
		else
More specifically this part.

Code: Select all

for e in entitiesAt(party.level, party.x, party.y - 1) do
				if e.class == "Monster" or e.class == "Altar" or e.class =="Blockage" or e.class == "Crystal" or e.class == nil then
I'm sure it could be made prettier and more efficient, I'm still kinda newbish.
I had doors there for a little while, but I couldn't cast it through open doors.
I see no reason you couldn't just say 'if object e is a door, succeed if it is open, fail otherwise"
Just haven't got around to it yet. Have a monster that has a chance to spawn the ice block instead of moving. Quite annoying. :lol: