[SCRIPT] Force a champion to own the scroll before casting

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] Force a champion to own the scroll before casting

Post by Jhaelen »

Hi,

Like I said in my thread about new spells, here is the script I use to force a champion to have the scroll of a spell in his inventory or in his hand to be able to cast it. You can throw it in the file "init.lua" or anywhere you want, and normally it enough. Nothing more is required.

As usual some fine tuning can be doing if you want. Obviously you have to had a "if" bloc for each new spell if you had some custom ones. For now the variable spellUiName isn't used but you can use it to create a contextual message if you want.
SpoilerShow

Code: Select all

defineObject{
	name = "party",
	baseObject = "party",
	components = {
		{
			class = "Party",  
			onCastSpell =
				function(party,champion,spellName)			
					local itmName = ""
					local spellUiName = ""
					
					if spellName == "water_breathing" then
						itmName = "scroll_water_breathing"
						spellUiName = "Water Breathing"
					end
					if spellName == "resurrection" then
						itmName = "scroll_resurrection"
						spellUiName = "Resurrection"
					end
					if spellName == "antidote" then
						itmName = "scroll_antidote"
						spellUiName = "Antidote"
					end
					if spellName == "recovery" then
						itmName = "scroll_recovery"
						spellUiName = "Recovery"
					end
					if spellName == "antivenom" then
						itmName = "scroll_antivenom"
						spellUiName = "Antivenom"
					end
					if spellName == "enchant_arrow" then
						itmName = "scroll_enchant_arrow"
						spellUiName = "Enchant Arrow"
					end
					if spellName == "heal" then
						itmName = "scroll_heal"
						spellUiName = "Healing"
					end
					if spellName == "mass_heal" then
						itmName = "scroll_mass_heal"
						spellUiName = "Mass Healing"
					end
					if spellName == "shield" then
						itmName = "scroll_shield"
						spellUiName = "Shield"
					end
					if spellName == "force_field" then
						itmName = "scroll_force_field"
						spellUiName = "Force Field"
					end
					if spellName == "fireburst" then
						itmName = "scroll_fireburst"
						spellUiName = "Fireburst"
					end
					if spellName == "light" then
						itmName = "scroll_light"
						spellUiName = "Light"
					end
					if spellName == "darkness" then
						itmName = "scroll_darkness"
						spellUiName = "Darkness"
					end
					if spellName == "darkbolt" then
						itmName = "scroll_darkbolt"
						spellUiName = "Darkbolt"
					end
					if spellName == "fireball" then
						itmName = "scroll_fireball"
						spellUiName = "Fireball"
					end
					if spellName == "meteor_storm" then
						itmName = "scroll_meteor_storm"
						spellUiName = "Meteor Storm"
					end
					if spellName == "shock" then
						itmName = "scroll_shock"
						spellUiName = "Shock"
					end
					if spellName == "invisibility" then
						itmName = "scroll_invisibility"
						spellUiName = "Invisibility"
					end
					if spellName == "lightning_bolt" then
						itmName = "scroll_lightning_bolt"
						spellUiName = "Lightning Bolt"
					end
					if spellName == "poison_cloud" then
						itmName = "scroll_poison_cloud"
						spellUiName = "Poison Cloud"
					end
					if spellName == "poison_bolt" then
						itmName = "scroll_poison_bolt"
						spellUiName = "Poison Bolt"
					end
					if spellName == "ice_shards" then
						itmName = "scroll_ice_shards"
						spellUiName = "Ice Shards"
					end
					if spellName == "dispel" then
						itmName = "scroll_dispel"
						spellUiName = "Dispel"
					end
					if spellName == "frostbolt" then
						itmName = "scroll_frostbolt"
						spellUiName = "Frostbolt"
					end
					if spellName == "fire_shield" then
						itmName = "scroll_fire_shield"
						spellUiName = "Fire Shield"
					end
					if spellName == "shock_shield" then
						itmName = "scroll_shock_shield"
						spellUiName = "Shock Shield"
					end
					if spellName == "poison_shield" then
						itmName = "scroll_poison_shield"
						spellUiName = "Poison Shield"
					end
					if spellName == "frost_shield" then
						itmName = "scroll_frost_shield"
						spellUiName = "Frost Shield"
					end
										
					for i = 1, 32, 1 do
						if champion:getItem(i) ~= nil and champion:getItem(i).go.name == itmName then
							return true
						end
					end

					hudPrint(champion:getName().." needs to have the spell scroll on him to be able to cast it")
					return false  
				end
		}
	},
}
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by Drakkan »

This is cool. Just by any chance in case you will like this idea, here is link for LOG1 script , where you need to learn spell before casting it. I think it is working very similar way and it should be even quite better than just owning the script in the inventory. However it need to be converted into Log2 and my scripting knowledge is not so high :/
viewtopic.php?f=14&t=4629&hilit=learn+s ... g&start=10
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by JKos »

Code: Select all

defineObject{
   name = "party",
   baseObject = "party",
   components = {
      {
         class = "Party", 
         onCastSpell =
            function(party,champion,spellName) 
	               local itemName = "scroll_"..spellName        
	               for i = 1, 32, 1 do
	                      if champion:getItem(i) ~= nil and champion:getItem(i).go.name == itemName then
	                          return true
	                     end
	               end
	               hudPrint(champion:getName().." needs to have the spell scroll on him to be able to cast it")
	               return false 
           end
      }
}
Should do the same thing and it works for custom spells too. One of the base rules of programming is DRY "Don't repeat yourself". I know it's hard at first, but try to think that way :)
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
User avatar
Jhaelen
Posts: 74
Joined: Fri Oct 19, 2012 10:49 am
Location: Paris, France

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by Jhaelen »

Thank for the improvement !
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by akroma222 »

Drakkan wrote:This is cool. Just by any chance in case you will like this idea, here is link for LOG1 script , where you need to learn spell before casting it. I think it is working very similar way and it should be even quite better than just owning the script in the inventory. However it need to be converted into Log2 and my scripting knowledge is not so high :/
viewtopic.php?f=14&t=4629&hilit=learn+s ... g&start=10
I used this method too, champ needs to own the scroll but also have sufficient skill to "use" the consumable scroll >> turns into a read scroll in inventory with all the spell info that was hiding otherwise.
I will convert this script over soon and post back here...
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by akroma222 »

Drakkan wrote:This is cool. Just by any chance in case you will like this idea, here is link for LOG1 script , where you need to learn spell before casting it. I think it is working very similar way and it should be even quite better than just owning the script in the inventory. However it need to be converted into Log2 and my scripting knowledge is not so high :/
viewtopic.php?f=14&t=4629&hilit=learn+s ... g&start=10
Credits to Ixnatifual and Grimwold from the above link
To impliment this system to LoG2
init.lua
SpoilerShow

Code: Select all

defineObject{
       name = "party",
       baseObject = "party",
       components = {
        {
        class = "Party",
	onCastSpell = function(party,champion,spellName) 
		return spellScripts.script.onCastSpell(party,champion,spellName)
	end,
	}
}
}
Then in a script entity 'spellScripts" put this
SpoilerShow

Code: Select all

spellbook = {fireburst = 0}

spellNames = {fireburst = "Fire Burst"}

function learnSpell(champ, spell, skill, reqSkill)
  	if champ:getSkillLevel(skill) >= reqSkill then
    	if (spellbook[spell] == 0) then
      		if spellNames[spell] ~= nil then
        		spellbook[spell] = 1
        		playSound("level_up")
				hudPrint(champ:getName() .. " scribes the spell \"" .. spellNames[spell] .. ".\"")
				return true
       		else
         		hudPrint(champ:getName() .. " does not know what the spell " .. spell .. " is.")
				return true
       		end
    	else
      		hudPrint(champ:getName() .. " already knows that spell.")
    		return false
		end
  	else
    	hudPrint(champ:getName() .. " isn't skilled enough to learn that spell.")
  		return true
	end
end

function onCastSpell(party,champion,spellName)

	if spellbook[spellName] == 0 then
    	hudPrint(champion:getName() .. " must learn that spell before casting it.")
    	playSound("spellfizzle1")
		return false
  	
	elseif spellbook[spellName] == 1 then
		hudPrint("you can cast this now")
		return true
	end
end
And 2 scrolls per spell (1 unlearned, 1 learned)
SpoilerShow

Code: Select all

---------------------------------------------------------------SCROLLS
defineObject{
       	name = "scroll_fireburst_tolearn",
       	baseObject = "base_item",
       	components = {
	{
      		class = "Model",
      		model = "assets/models/items/scroll.fbx",
    	},
        {
             	class = "Item",
             	uiName = "Scroll of Fireburst",
            	gfxAtlas = "assets/textures/gui/items.tga",
             	gfxIndex = 113,
             	weight = 0.3,
        },
	{
		class = "UsableItem",
		emptyItem = "scroll_fireburst_learned",
       		sound = "level_up",
		requirements = {"fire_magic", 2},
       		onUseItem = function(self,champion)
			if champion:getSkillLevel("fire_magic") >= 2 then
   				return spellScripts.script.learnSpell(champion, "fireburst", "fire_magic", 2)
			else
				hudPrint(champion:getName() .. " isn't skilled enough to learn that spell.")
				return false
			end
  		end,
         },
       }
}

defineObject{
       	name = "scroll_fireburst_learned",
       	baseObject = "scroll_fireburst",
       	components = {
       	{
             	class = "Item",
             	uiName = "Scroll of Fireburst",
             	--gfxAtlas = "mod_assets/textures/akroma_icons.tga",
		--gfxIndex = 54,
                gfxAtlas = "assets/textures/gui/items.tga",
             	gfxIndex = 113,
		gameEffect = "Game effect in bold up top",
		description = "Description in italics down the bottom",	
             	weight = 0.3,
        },
	{
             	class = "SpellScrollItem",
             	spell = "fireburst",
         },
       }
}
*there is a --icon ref for the learned scroll from akroma_icons1
*I dont know why the unlearned scroll list Fire Magic requirements twice ..??
I have only listed fireburst in the spell tables, you will need add spells as you go to spellbook and spellNames
Grimfan
Posts: 369
Joined: Wed Jan 02, 2013 7:48 am

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by Grimfan »

I believe that the game engine automatically generates scrolls for spells without needing to script the spell scrolls. Perhaps because you have done this the scroll has listed it twice?
User avatar
TSotP
Posts: 74
Joined: Tue Oct 15, 2013 8:42 am

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by TSotP »

JKos wrote:

Code: Select all

defineObject{
   name = "party",
   baseObject = "party",
   components = {
      {
         class = "Party", 
         onCastSpell =
            function(party,champion,spellName) 
	               local itemName = "scroll_"..spellName        
	               for i = 1, 32, 1 do
	                      if champion:getItem(i) ~= nil and champion:getItem(i).go.name == itemName then
	                          return true
	                     end
	               end
	               hudPrint(champion:getName().." needs to have the spell scroll on him to be able to cast it")
	               return false 
           end
      }
}
Should do the same thing and it works for custom spells too. One of the base rules of programming is DRY "Don't repeat yourself". I know it's hard at first, but try to think that way :)

so, if i already have some custom spells (Jhaelen's excellent healing spells) in my spell.lua, and i add this code in there as well, for any and all spells, players will need the scroll to cast them, custom ones too?
User avatar
Jhaelen
Posts: 74
Joined: Fri Oct 19, 2012 10:49 am
Location: Paris, France

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by Jhaelen »

Yes, but you have to be certain that the scrolls are always named like this : scroll_healing or scroll_fireburst for example.
User avatar
TSotP
Posts: 74
Joined: Tue Oct 15, 2013 8:42 am

Re: [SCRIPT] Force a champion to own the scroll before casti

Post by TSotP »

that's awesome, thanks guys.

i do have another related question.

would that script return true if the spell scroll was in a container? The reason i ask, is i wonder if i could make a modified 'wooden box' or 'sack' as a spellbook for the scrolls Nevermind, the answer is no.
Post Reply