Ask a simple question, get a simple answer

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!
Pompidom
Posts: 497
Joined: Sun May 06, 2018 9:42 pm

Re: Ask a simple question, get a simple answer

Post by Pompidom »

In that case simply redirect your efforts to something completely else. Until you have gained more knowledge.

You can always implement a placeholder mechanic in the meanwhile that accomplishes the same thing. In this particular case you can simply activate a timer that sets your party members energy levels to 0 whenever you're in the area where you are not supposed to use magic and then later change it when you have created a working script.
NolanDaneworth
Posts: 21
Joined: Thu Feb 28, 2019 5:55 pm

Re: Ask a simple question, get a simple answer

Post by NolanDaneworth »

Thats the problem, i simply dont know where to gain this expierence and knowledge of lua.
I dont do programming in my life at all, but i really want to recreate something in LOG2
Pompidom
Posts: 497
Joined: Sun May 06, 2018 9:42 pm

Re: Ask a simple question, get a simple answer

Post by Pompidom »

There are lots of things you can do besides waiting for an answer to your specific problems. Sometimes it can take days before someone decides to give you a helping hand, so patience.

1. I already gave you the links, and more importantly,
2. I already gave you the advice of downloading every single LoG2 editor dungeon file out there. For example Minmay's DM Artifacts of Might is a gold mine of usable lua scripts to learn from.
3. You can search specific keywords on this forum.
4. The forum is full with scripts everywhere if you can specify your search terms more narrowly.

I'm in the same boat, I have 0 coding knowledge/lua scripting knowledge. I ask my question once, and then I simply wait while searching patiently for the solution myself by doing the things above. Sometimes it takes several weeks before I can implement a working solution. And sometimes I get handed the solution instantly on a silver platter. That's modding for you if you lack scripting knowledge.

Also by playing the mods you will encounter mechanics you will want to expand upon, then you can send a PM to the creator to ask if they want to share their script so you make something with it yourself.

In this case:

Code: Select all

function energydown()
party.party:getChampion(1):setEnergy(0)
party.party:getChampion(2):setEnergy(0)
party.party:getChampion(3):setEnergy(0)
party.party:getChampion(4):setEnergy(0)
end
link this to a timer that will call this function over and over again until you leave the area.
the timer can be enabled/disabled with floor triggers.

You now have a placeholder mechanic that basically solves your issue. Your party has no more energy to cast spells.
When someone finally gives you the proper script, then you can implement something better.
User avatar
Isaac
Posts: 3185
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

NolanDaneworth wrote: Mon Mar 04, 2019 5:07 pm And i have my own question again.
Is there a way to script floor, that whenever party stays on it - no magic can be used ?
It really hurts to not know lua, because so many ideas, so little capabilities.

As in references, i only see .onCastSpell, but how to write the "fizzle" part ?
The 'Fizzle' part isn't very intuitive at first.

Here is a script with minimal functionality that goes in the object.lua file, in the scripts folder. This minimally does the job of restricting magic, and drawing the Fizzle effect. Once in place, you should have a new asset called "anti_magic_tile". You just place it where you want it, and the party cannot cast spells on that tile. The effect can be deactivated via script.
MinimalShow

Code: Select all

defineObject{
	name = "party",
	baseObject = "party",
	components = {
		{
			class = "Party",
			onCastSpell = function(self, champion, spell)
				local tile = nil
				for antiMagic in party.map:allEntities() do
					if antiMagic.name == "anti_magic_tile" and antiMagic.elevation == antiMagic.elevation and antiMagic.x == party.x and antiMagic.y == party.y then -- checks if the Party is on the same tile location as the script_entity  then
						return antiMagic.script:tileCheck(champion, spell)
					end
				end	
			end,

		}
	}
}



defineObject{
	name = "anti_magic_tile",
	baseObject = "base_floor_decoration",
	components = {
		{
			class = "Script",
			source = [[
					effectEnabled = true

					--Call the setEffectsEnabled function to turn the anti-magic effect on or off.
					--Example:  anti_magic_tile_1.script:setEffectEnabled(false)

					function setEffectEnabled(bool)                               
						if type(bool) == "boolean" then effectEnabled = bool end
					end

					function tileCheck(self, champion, spell)
						if effectEnabled then
							if self.go.elevation == party.elevation and self.go.x == party.x and self.go.y == party.y then -- checks if the Party is on the same tile location as the script_entity 
		
							 	  --anti-magic failure effect
							 	champion:showAttackResult("Fizzle", "SpellFizzle")
								party:spawn('blob')
								playSound("spell_fizzle")  	
							
								--optional hudPrinted message
								local showText = true 					--[ change true to false to disable the text ]============<<
								if showText then
									hudPrint("The ground here interferes with "..champion:getName().."\'s spellcasting!")
								end

								return false
							end 
							return true 	-- confirms off-tile casting for the rest of the map (as opposed to canceling it).
						end
					end
				]]
		},
	
	},
	placement = "floor",
	tags = { "scripting", "magic" },
	editorIcon = 284,
}
Alternatively, here is the same script with some cosmetic improvements:
Deluxe ;)Show
Image

Code: Select all

defineObject{
	name = "party",
	baseObject = "party",
	components = {
		{
			class = "Party",
			onCastSpell = function(self, champion, spell)
				local tile = nil
				for antiMagic in party.map:allEntities() do
					if antiMagic.name == "anti_magic_tile" and antiMagic.elevation == antiMagic.elevation and antiMagic.x == party.x and antiMagic.y == party.y then -- checks if the Party is on the same tile location as the script_entity  then
						return antiMagic.script:tileCheck(champion, spell)
					end
				end	
			end,

		}
	}
}



defineObject{
	name = "anti_magic_tile",
	baseObject = "base_floor_decoration",
	components = {
		{
			class = "Script",
			source = [[
					effectEnabled = true

					particleEffect = true  --Change true to false to disable any of these three effects.
					floorDecoration = true
					soundEffect = true

					function setEffectEnabled(bool)
						if type(bool) == "boolean" then effectEnabled = bool end
					end

					function tileCheck(self, champion, spell) print(self.go:getName(), self.go.x, self.go.y, self.go.elevation)
						if effectEnabled then
							 	  --anti-magic failure effect
							 	champion:showAttackResult("Fizzle", "SpellFizzle")
								party:spawn('blob')
								playSound("spell_fizzle")  	
							
								--optional hudPrinted message
								local showText = true 					--[ change true to false to disable the text ]============<<
								if showText then
									hudPrint("The ground here interferes with "..champion:getName().."\'s spellcasting!")
								end

								return false
							end 
							return true 	-- confirms off-tile casting for the rest of the map (as opposed to canceling it).
					end
				]]
		},
		{
			class = "Model",
			model = "assets/models/effects/trap_rune.fbx",
			offset = vec(0, 0.1, 0),
			emissiveColor = vec(0,-1,-1),
			onInit = function(self) self[iff(self.go.script.floorDecoration,"enable", "disable")](self) end
		},
		{
			class = "Particle",
			particleSystem = "castle_wall_text_long",
			offset = vec(0,0.1,1.5),
			rotation = vec(90),
			onInit = function(self) self[iff(self.go.script.particleEffect,"enable", "disable")](self) end
		},
		{
			class = "Sound",
			sound = "anti_magic_tile",
			pitch = .15,
			onInit = function(self) self[iff(self.go.script.soundEffect,"enable", "disable")](self) end
		},
		{
			class = "Controller", 
			onActivate = function(self) --Used to activate Anti-Magic Effect
							if self.go.script.floorDecoration then self.go.model:enable() end
							if self.go.script.floorDecoration then self.go.particle:enable() end
							if self.go.script.floorDecoration then self.go.sound:enable() end

							self.go.script.setEffectEnabled(true)
							self.go:spawn("teleportation_effect")
						end, 
			onDeactivate = function(self)  --Used to deactivate Anti-Magic Effect
							 self.go.model:disable()
							 self.go.particle:disable()
							 self.go.sound:disable()

							 self.go.script.setEffectEnabled(false)
							 self.go:spawn("teleportation_effect")
						end,
			onToggle = function(self) 
						if not self.go.script.effectEnabled then 
							self.go.controller:activate()
						 else self.go.controller:deactivate()						 			
						end	
					end,			
		},
	},
	placement = "floor",
	tags = { "scripting", "magic" },
	editorIcon = 284,
}

defineSound{
	name = "anti_magic_tile",
	filename = "assets/samples/magic/fizzle_01.wav",
	loop = true,
	volume = 0.20,
	minDistance = 1, 
	maxDistance = 2,
}
* I should mention that once you start incorporating 3rd party mod assets, you need to keep in mind that pieces of them might overwrite each other; last one defined wins out. In this case, the anti-magic-tile adds a Party hook to onCastSpell. If you add another mod asset that redefines the party object without modification to merge the changes, it will most likely break the anti_magic_tile—or the other way around.
Last edited by Isaac on Tue Mar 05, 2019 5:27 pm, edited 2 times in total.
NolanDaneworth
Posts: 21
Joined: Thu Feb 28, 2019 5:55 pm

Re: Ask a simple question, get a simple answer

Post by NolanDaneworth »

Ah, thats where the problem was.
I was trying to do all the stuff in editor script entities with mere function.
A big thank you from me.

Still dont understand when to write the stuff in base lua files and not ingame
NolanDaneworth
Posts: 21
Joined: Thu Feb 28, 2019 5:55 pm

Re: Ask a simple question, get a simple answer

Post by NolanDaneworth »

Hmmm, interesting, it appears whenever i place more than one of this tiles they stop working.
Wonder where the tile check failures now. My goal was to fill the whole room
User avatar
Zo Kath Ra
Posts: 937
Joined: Sat Apr 21, 2012 9:57 am
Location: Germany

Re: Ask a simple question, get a simple answer

Post by Zo Kath Ra »

Isaac wrote: Tue Mar 05, 2019 9:11 am for antiMagic in party.map:allEntities() do
Shouldn't this line be
for antiMagic in party.map:entitiesAt(party.x, party.y) do
User avatar
Isaac
Posts: 3185
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

Zo Kath Ra wrote: Tue Mar 05, 2019 2:06 pm
Isaac wrote: Tue Mar 05, 2019 9:11 am for antiMagic in party.map:allEntities() do
Shouldn't this line be
for antiMagic in party.map:entitiesAt(party.x, party.y) do
Perhaps, but using allEntities is deliberate for two reasons. First, my impression has been that entitiesAt is a slower function than allEntities, and second the loop to is made such that it runs through all antimagic tiles on the given level, and quits on the first one found to be underfoot.
NolanDaneworth wrote: Tue Mar 05, 2019 1:33 pm Hmmm, interesting, it appears whenever i place more than one of this tiles they stop working.
Wonder where the tile check failures now. My goal was to fill the whole room
That might be a bug—because it's intended that you can use more than one. I will look at it again.

Edit: It is a bug, and I know why. This script started out intended as a script_entity that returned boolean to the onCastSpell hook, that simply (and only) returned the result. I later changed the design, and moved all of it to object.lua as a full asset, and for whatever reason forgot to move the location test. It works now, as intended [afaik]. ;)

I have updated both versions in the original post.
NolanDaneworth
Posts: 21
Joined: Thu Feb 28, 2019 5:55 pm

Re: Ask a simple question, get a simple answer

Post by NolanDaneworth »

Big thank you, wish i could repay the favor
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

Isaac wrote: Tue Mar 05, 2019 5:17 pmFirst, my impression has been that entitiesAt is a slower function than allEntities
While a call to allEntities() alone is potentially faster than a call to entitiesAt() alone, allEntities() is way slower if you're actually using the returned iterator, because you're iterating over 1024 squares worth of entities instead of one square worth of entities. It's much better to use entitiesAt().
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Post Reply