[SCRIPT] New spells (heal related mostly)

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
User avatar
Jhaelen
Posts: 74
Joined: Fri Oct 19, 2012 10:49 am
Location: Paris, France

[SCRIPT] New spells (heal related mostly)

Post by Jhaelen »

Hi,

I'm releasing to the community the healing spells (with their scrolls) I'm using in my WIP mod. It's not a big deal (no stunning revelation) but I think it could be of use for some people here. I also added an Enchant Arrow spell in the middle ;) (I used the one made for Grimrock 1 by Blichew as a base for this last one).

Copy/paste the following code into any lua file you want, and voilà ! It's done. These scripts could be upgraded / optimised by testing alive status and others things, but I think you get the idea ;).

Resurrection
SpoilerShow

Code: Select all

defineSpell{
	name = "resurrection",
	uiName = "Resurrection",
	skill = "earth_magic",
	requirements = {"earth_magic", 5, "concentration", 5},
	gesture = 789654,
	manaCost = 150,
	icon = 72,
	spellIcon = 13,
	description = "Resurrect a dead champion with full health.",
	onCast =
		function(champion, x, y, direction, elevation, skillLevel)
			local difference = 0
			local championToRaise = nil
			local deadChampions = {}
			local healthToGive
			
			for i = 1, 4, 1 do
				if party.party:getChampion(i):getConditionValue("dead") ~= 0 then
					deadChampions[#deadChampions + 1] = party.party:getChampion(i)
				end
			end

			if #deadChampions >= 1 then
				championToRaise = deadChampions[1]
				
				championToRaise:playHealingIndicator()
				championToRaise:setHealth(championToRaise:getMaxHealth())
				playSound("heal_party")
			else
				if #deadChampions == 0 then
					hudPrint("Nobody is dead")
					playSound("spell_fizzle")
					return false
				end
			end	
		end
}

defineObject{
	name = "scroll_resurrection",
	baseObject = "scroll_light",
	components = {
		{
			class = "Item",
			uiName = "Scroll of Resurrection",
			
			gfxAtlas = "assets/textures/gui/items.tga",
			gfxIndex = 113,
			weight = 0.3,
		},
		{
			class = "SpellScrollItem",
			spell = "resurrection",
		}
	},
}
Antidote
SpoilerShow

Code: Select all

defineSpell{
	name = "antidote",
	uiName = "Antidote",
	skill = "earth_magic",
	requirements = {"earth_magic", 3},
	gesture = 65874,
	manaCost = 40,
	icon = 72,
	spellIcon = 13,
	description = "Cure disease on the more wounded champion.",
	onCast =
		function(champion, x, y, direction, elevation, skillLevel)
			local difference = 0
			local championToHeal = nil
			local sickChampions = {}
			
			for i = 1, 4, 1 do
				if party.party:getChampion(i):getConditionValue("diseased") ~= 0 then
					sickChampions[#sickChampions + 1] = party.party:getChampion(i)
				end
			end
			
			if #sickChampions >= 1 then
				championToHeal = sickChampions[1]
		
				if #sickChampions > 1 then
					for i = 1, #sickChampions, 1 do
						if (sickChampions[i]:getMaxHealth() - sickChampions[i]:getHealth()) > difference then
							difference = sickChampions[i]:getMaxHealth() - sickChampions[i]:getHealth()
							championToHeal = sickChampions[i]
						end
					end
				end
					
				championToHeal:playHealingIndicator()
				championToHeal:setConditionValue("diseased", 0)
				playSound("heal_party")
				
			else
				if #sickChampions == 0 then
					hudPrint("Nobody is diseased")
					playSound("spell_fizzle")
					return false
				end
			end
		end
}

defineObject{
	name = "scroll_antidote",
	baseObject = "scroll_light",
	components = {
		{
			class = "Item",
			uiName = "Scroll of Antidote",
			
			gfxAtlas = "assets/textures/gui/items.tga",
			gfxIndex = 113,
			weight = 0.3,
		},
		{
			class = "SpellScrollItem",
			spell = "antidote",
		}
	},
}
Antivenom
SpoilerShow

Code: Select all

defineSpell{
	name = "antivenom",
	uiName = "Antivenom",
	skill = "earth_magic",
	requirements = {"earth_magic", 2},
	gesture = 6587,
	manaCost = 30,
	icon = 72,
	spellIcon = 13,
	description = "Cure poison on the more wounded champion.",
	onCast =
		function(champion, x, y, direction, elevation, skillLevel)
			local difference = 0
			local championToHeal = nil
			local poisonedChampions = {}
			
			for i = 1, 4, 1 do
				if party.party:getChampion(i):getConditionValue("poison") > 0 then
					poisonedChampions[#poisonedChampions + 1] = party.party:getChampion(i)
				end
			end
			
			if #poisonedChampions >= 1 then
				championToHeal = poisonedChampions[1]
			
				if #poisonedChampions > 1 then
					for i = 1, #poisonedChampions, 1 do
						if (poisonedChampions[i]:getMaxHealth() - poisonedChampions[i]:getHealth()) > difference then
							difference = poisonedChampions[i]:getMaxHealth() - poisonedChampions[i]:getHealth()
							championToHeal = poisonedChampions[i]
						end
					end
				end
						
				championToHeal:playHealingIndicator()
				championToHeal:setConditionValue("poison", 0)
				playSound("heal_party")
				
			else
				if #poisonedChampions == 0 then
					hudPrint("Nobody is poisoned")
					playSound("spell_fizzle")
					return false
				end
			end
		end,
}

defineObject{
	name = "scroll_antivenom",
	baseObject = "scroll_light",
	components = {
		{
			class = "Item",
			uiName = "Scroll of Antivenom",
			
			gfxAtlas = "assets/textures/gui/items.tga",
			gfxIndex = 113,
			weight = 0.3,
		},
		{
			class = "SpellScrollItem",
			spell = "antivenom",
		}
	},
}
Enchant Arrow
SpoilerShow

Code: Select all

defineSpell{
	name = "enchant_arrow",
	uiName = "Enchant Arrow",
	skill = "water_magic",
	requirements = {"water_magic", 4},
	gesture = 123698745,
	manaCost = 0,
	icon = 72,
	spellIcon = 13,
	description = "Enchant arrows with a frost damage modifier.",
	onCast = 
		function(champion, x, y, direction, elevation, skillLevel)
			local size = 0
			local itmSpawned = nil
			local enchantBaseCost = 0			
			
			if getMouseItem() == nil or (getMouseItem() ~= nil and getMouseItem().go.name ~= "arrow") then
				hudPrint("You must cast this spell while holding arrows")
			else
				size = getMouseItem():getStackSize()
				
				enchantBaseCost = size * 20
				
				if champion:getEnergy() >= enchantBaseCost then
					champion:regainEnergy(-enchantBaseCost)
					
					itmSpawned = spawn("cold_arrow")
					itmSpawned.item:setStackSize(size)
					setMouseItem(itmSpawned.item)
					playSound("generic_spell")
				else
					hudPrint("Not enough energy")
					playSound("spell_fizzle")
				end
				
				
			end
		end,
}

defineObject{
	name = "scroll_enchant_arrow",
	baseObject = "scroll_light",
	components = {
		{
			class = "Item",
			uiName = "Scroll of Enchant Arrow",
			
			gfxAtlas = "assets/textures/gui/items.tga",
			gfxIndex = 113,
			weight = 0.3,
		},
		{
			class = "SpellScrollItem",
			spell = "enchant_arrow",
		}
	},
}
Recovery
SpoilerShow

Code: Select all

defineSpell{
	name = "recovery",
	uiName = "Recovery",
	skill = "earth_magic",
	requirements = {"earth_magic", 4, "concentration", 3},
	gesture = 587,
	manaCost = 0,
	icon = 72,
	spellIcon = 13,
	description = "Heals a champion which has one or more limb wounds.",
	onCast =
		function(champion, x, y, direction, elevation, skillLevel)
			local difference = 0
			local championToHeal = nil
			local nbrWounds = 0
			local healBaseCost = 0
			
			for i = 1, 4, 1 do
				if party.party:getChampion(i):getConditionValue("left_hand_wound") ~= 0 then
					nbrWounds = nbrWounds + 1
				end
				if party.party:getChampion(i):getConditionValue("right_hand_wound") ~= 0 then
					nbrWounds = nbrWounds + 1
				end
				if party.party:getChampion(i):getConditionValue("leg_wound") ~= 0 then
					nbrWounds = nbrWounds + 1
				end
				if party.party:getChampion(i):getConditionValue("feet_wound") ~= 0 then
					nbrWounds = nbrWounds + 1
				end
				if party.party:getChampion(i):getConditionValue("head_wound") ~= 0 then
					nbrWounds = nbrWounds + 1
				end
					
				if nbrWounds > 0 then
					championToHeal = party.party:getChampion(i)
					break
				end
			end
			
			if championToHeal == nil then
				hudPrint("Nobody has a limb wound")
				playSound("spell_fizzle")
				return false
			end
			
			healBaseCost = nbrWounds * 15
			
			if champion:getEnergy() >= healBaseCost then
				champion:regainEnergy(-healBaseCost)
				
				championToHeal:playHealingIndicator()
				championToHeal:setConditionValue("left_hand_wound", 0)
				championToHeal:setConditionValue("right_hand_wound", 0)
				championToHeal:setConditionValue("leg_wound", 0)
				championToHeal:setConditionValue("feet_wound", 0)
				championToHeal:setConditionValue("head_wound", 0)
				playSound("heal_party")
			else
				hudPrint("Not enough energy")
				playSound("spell_fizzle")
			end
					
			
		end
}

defineObject{
	name = "scroll_recovery",
	baseObject = "scroll_light",
	components = {
		{
			class = "Item",
			uiName = "Scroll of Recovery",
			
			gfxAtlas = "assets/textures/gui/items.tga",
			gfxIndex = 113,
			weight = 0.3,
		},
		{
			class = "SpellScrollItem",
			spell = "recovery",
		}
	},
}
Healing
SpoilerShow

Code: Select all

defineSpell{
	name = "heal",
	uiName = "Healing",
	skill = "earth_magic",
	requirements = {"earth_magic", 2, "concentration", 1},
	gesture = 7456,
	manaCost = 0,
	icon = 72,
	spellIcon = 13,
	description = "Heals the most wounded champion (this spell has no effect on limb wounds). If you don't have enough energy, the spell is cast but the healing is decreased proportionally. The healing depends on your skills :\n- Earth Magic 2 : Concentration x 5\n- Earth Magic 3 : Concentration x 10\n- Earth Magic 4 : Concentration x 20\n- Earth Magic 5 : Concentration x 30",
	onCast =
		function(champion, x, y, direction, elevation, skillLevel)
			local difference = 0
			local indexMostWounded = 0
			local healValue = 0
			local healCoefficient = 1
			local healBaseCost = 0
			local healPower = ""
			
			for i = 1, 4, 1 do
				if (party.party:getChampion(i):getMaxHealth() - party.party:getChampion(i):getHealth()) > difference then
					difference = party.party:getChampion(i):getMaxHealth() - party.party:getChampion(i):getHealth()
					indexMostWounded = i
				end
			end
			
			if indexMostWounded > 0 then
				healBaseCost = champion:getSkillLevel("concentration") * 10 + champion:getSkillLevel("earth_magic") * 5
				
				if champion:getEnergy() >= healBaseCost then
					champion:regainEnergy(-healBaseCost)
				else
					healCoefficient = champion:getEnergy() / healBaseCost
					champion:regainEnergy(-champion:getEnergy())
				end
				
				if champion:getSkillLevel("earth_magic") == 2 then
					healValue = champion:getSkillLevel("concentration") * 5 * healCoefficient --Soigne entre 5 et 25
					healPower = "light"
				end
				if champion:getSkillLevel("earth_magic") == 3 then
					healValue = champion:getSkillLevel("concentration") * 10 * healCoefficient --Soigne entre 10 et 50
					healPower = "light"
				end
				if champion:getSkillLevel("earth_magic") == 4 then
					healValue = champion:getSkillLevel("concentration") * 20 * healCoefficient --Soigne entre 20 et 100
					healPower = "medium"
				end 
				if champion:getSkillLevel("earth_magic") == 5 then
					healValue = champion:getSkillLevel("concentration") * 30 * healCoefficient --Soigne entre 30 et 150
					healPower = "strong"
				end
				
				party.party:getChampion(indexMostWounded):playHealingIndicator()
				party.party:getChampion(indexMostWounded):regainHealth(healValue)
				playSound("heal_party")
			else
				hudPrint("Nobody is wounded")
				playSound("spell_fizzle")
			end
		end
}

defineObject{
	name = "scroll_heal",
	baseObject = "scroll_light",
	components = {
		{
			class = "Item",
			uiName = "Scroll of Healing",
			
			gfxAtlas = "assets/textures/gui/items.tga",
			gfxIndex = 113,
			weight = 0.3,
		},
		{
			class = "SpellScrollItem",
			spell = "heal",
		}
	},
}
Mass Healing
SpoilerShow

Code: Select all

defineSpell{
	name = "mass_heal",
	uiName = "Mass Healing",
	skill = "earth_magic",
	requirements = {"earth_magic", 3, "concentration", 2},
	gesture = 74569,
	manaCost = 0,
	icon = 72,
	spellIcon = 13,
	description = "Heals yourself and your comrades (this spell has no effect on limb wounds). If you don't have enough energy, the spell is cast but the healing is decreased proportionally. The healing depends on your skills :\n- Earth Magic 3 : Concentration x 5\n- Earth Magic 4 : Concentration x 10\n- Earth Magic 5 : Concentration x 15",
	onCast =
		function(champion, x, y, direction, elevation, skillLevel)
			local partyIsWounded = false
			local indexMostWounded = 0
			local healValue = 0
			local healCoefficient = 1
			local healBaseCost = 0
			local healPower = ""
			
			for i = 1, 4, 1 do
				if (party.party:getChampion(i):getMaxHealth() - party.party:getChampion(i):getHealth()) > 0 then
					partyIsWounded = true
				end
			end
			
			if partyIsWounded then
				healBaseCost = champion:getSkillLevel("concentration") * 15 + champion:getSkillLevel("earth_magic") * 5
				
				if champion:getEnergy() >= healBaseCost then
					champion:regainEnergy(-healBaseCost)
				else
					healCoefficient = champion:getEnergy() / healBaseCost
					champion:regainEnergy(-champion:getEnergy())
				end
				
				if champion:getSkillLevel("earth_magic") == 3 then
					healValue = champion:getSkillLevel("concentration") * 5 * healCoefficient --Soigne entre 10 et 25
					healPower = "medium"
				end 
				if champion:getSkillLevel("earth_magic") == 4 then
					healValue = champion:getSkillLevel("concentration") * 10 * healCoefficient --Soigne entre 20 et 50
					healPower = "medium"
				end 
				if champion:getSkillLevel("earth_magic") == 5 then
					healValue = champion:getSkillLevel("concentration") * 15 * healCoefficient --Soigne entre 30 et 75
					healPower = "strong"
				end
				
				playSound("heal_party")
				for i = 1, 4, 1 do
					party.party:getChampion(i):playHealingIndicator()
					party.party:getChampion(i):regainHealth(healValue)
				end
			else
				hudPrint("Nobody is wounded")
				playSound("spell_fizzle")
			end
		end
}

defineObject{
	name = "scroll_mass_heal",
	baseObject = "scroll_light",
	components = {
		{
			class = "Item",
			uiName = "Scroll of Mass Healing",
			
			gfxAtlas = "assets/textures/gui/items.tga",
			gfxIndex = 113,
			weight = 0.3,
		},
		{
			class = "SpellScrollItem",
			spell = "mass_heal",
		}
	},
}
Last edited by Jhaelen on Fri Nov 14, 2014 8:29 pm, edited 3 times in total.
User avatar
QuintinStone
Posts: 72
Joined: Sat Nov 01, 2014 9:58 pm

Re: New spells (heal related mostly)

Post by QuintinStone »

Very cool!
Crypt of Zulfar
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: New spells (heal related mostly)

Post by Drakkan »

wonderfull, I am going to try some ! Thanks for sharing
btw I have noticed in your mod --- A champion needs to have the spell scroll either in his inventory or in his hands to be able to cast it.
have you already managed to script this ? I am quite interesting using something similar in my mod (preferably character need to learn the scroll from spell to be able to cast it)
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
Jhaelen
Posts: 74
Joined: Fri Oct 19, 2012 10:49 am
Location: Paris, France

Re: New spells (heal related mostly)

Post by Jhaelen »

Yes I managed to create this script, I will share it soon ! These spells above are usable as is.

EDIT : done, message here.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [SCRIPT] New spells (heal related mostly)

Post by akroma222 »

Nice work Jhaelen!!
Im about to convert a few spells over from LoG1 to LoG2, these were all on the list!
I will give them a test run soon n let you know if there are any issues ;)
Grimfan
Posts: 369
Joined: Wed Jan 02, 2013 7:48 am

Re: [SCRIPT] New spells (heal related mostly)

Post by Grimfan »

Fantastic work Jhaelen!

I'm always unsure of putting healing spells into the game (some people think it makes LOG too easy) but you have balanced this nicely with your scroll restrictions.

Now I'm just patiently waiting for the Akroma onslaught. ;)
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [SCRIPT] New spells (heal related mostly)

Post by akroma222 »

Tested them all briefly, seems to be all good!
Thanks for these :D
Grimfan
Posts: 369
Joined: Wed Jan 02, 2013 7:48 am

Re: [SCRIPT] New spells (heal related mostly)

Post by Grimfan »

And here are two more spells to add to the list based on Jhaelen's. One for paralysis and one for petrifaction/petrification.

Code: Select all

defineSpell{
   name = "cure_paralysis",
   uiName = "Cure Paralysis",
   skill = "water_magic",
   requirements = {"water_magic", 4, "concentration", 2},
   gesture = 25698,
   manaCost = 50,
   icon = 72,
   spellIcon = 13,
   description = "Cure a paralyzed party member.",
   onCast =
      function(champion, x, y, direction, elevation, skillLevel)
         local difference = 0
         local championToHeal = nil
         local sickChampions = {}
         
         for i = 1, 4, 1 do
            if party.party:getChampion(i):getConditionValue("paralyzed") ~= 0 then
               sickChampions[#sickChampions + 1] = party.party:getChampion(i)
            end
         end
         
         if #sickChampions >= 1 then
            championToHeal = sickChampions[1]
      
            if #sickChampions > 1 then
               for i = 1, #sickChampions, 1 do
                  if (sickChampions[i]:getMaxHealth() - sickChampions[i]:getHealth()) > difference then
                     difference = sickChampions[i]:getMaxHealth() - sickChampions[i]:getHealth()
                     championToHeal = sickChampions[i]
                  end
               end
            end
               
            championToHeal:playHealingIndicator()
            championToHeal:setConditionValue("paralyzed", 0)
            playSound("heal_party")
            
         else
            if #sickChampions == 0 then
               hudPrint("Nobody is paralyzed")
               playSound("spell_fizzle")
               return false
            end
         end
      end
}

defineSpell{
   name = "remove_petrification",
   uiName = "Remove Petrification",
   skill = "earth_magic",
   requirements = {"earth_magic", 5, "concentration", 3},
   gesture = 125478,
   manaCost = 70,
   icon = 72,
   spellIcon = 13,
   description = "Remove petrification from a party member.",
   onCast =
      function(champion, x, y, direction, elevation, skillLevel)
         local difference = 0
         local championToHeal = nil
         local sickChampions = {}
         
         for i = 1, 4, 1 do
            if party.party:getChampion(i):getConditionValue("petrified") ~= 0 then
               sickChampions[#sickChampions + 1] = party.party:getChampion(i)
            end
         end
         
         if #sickChampions >= 1 then
            championToHeal = sickChampions[1]
      
            if #sickChampions > 1 then
               for i = 1, #sickChampions, 1 do
                  if (sickChampions[i]:getMaxHealth() - sickChampions[i]:getHealth()) > difference then
                     difference = sickChampions[i]:getMaxHealth() - sickChampions[i]:getHealth()
                     championToHeal = sickChampions[i]
                  end
               end
            end
               
            championToHeal:playHealingIndicator()
            championToHeal:setConditionValue("petrified", 0)
            playSound("heal_party")
            
         else
            if #sickChampions == 0 then
               hudPrint("Nobody is petrified")
               playSound("spell_fizzle")
               return false
            end
         end
      end
}
These work for me at least.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [SCRIPT] New spells (heal related mostly)

Post by akroma222 »

bear form can be given/taken away using the same script :D
User avatar
Jhaelen
Posts: 74
Joined: Fri Oct 19, 2012 10:49 am
Location: Paris, France

Re: [SCRIPT] New spells (heal related mostly)

Post by Jhaelen »

Glad you like it, and Grimfan I will definitely use yours !
Post Reply