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!
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 »

Lorial wrote: Fri Aug 09, 2019 6:03 am For a custom tile damaging spell (similar to fireburst and shockburst), how can I prevent casting in front of the party if the tile is blocked?
Apparently, this can lead to a CTD at the edge of a level and allows cheating by casting through grates and even solid walls.

Code: Select all

defineSpell{ 
	name = "fireburst",
	uiName = "Fireburst",
	gesture = 1,
	manaCost = 25,
	skill = "fire_magic",
	requirements = { "fire_magic", 1 },
	icon = 60,
	spellIcon = 1,
	description = "Conjures a blast of fire that deals fire damage to all foes directly in front of you.",
	onCast = function(champion) 
			local dX, dY = getForward(party.facing)
			local X,Y = dX+party.x, dY+party.y 
			local obCheck = party.map:checkObstacle(party, party.facing)
			if obCheck == "door" or obCheck == "wall" then
				champion:showAttackResult("Fizzle", "SpellFizzle")
				playSound("spell_fizzle")
				return false
			end
			spawn("fireburst",party.level,X,Y,party.facing,party.elevation).tiledamager:setCastByChampion(champion:getOrdinal())
			return true
		end
}
User avatar
Lorial
Posts: 91
Joined: Sat Dec 29, 2018 12:27 pm

Re: Ask a simple question, get a simple answer

Post by Lorial »

Works like a charm, thanks for the quick response, Isaac.
Since I wanted to use the backfire option of the original game, I did some testing on my own and this seems to work just fine. I am certain there is a "shorter" version. Tiledamagers now blow up in the party's faces.

Code: Select all

	onCast = function(champion)
		local dx,dy = getForward(party.facing)
			local X,Y = dx+party.x, dy+party.y 
			local obCheck = party.map:checkObstacle(party, party.facing)
			if obCheck == "door" or obCheck == "wall" then
			spawn("fireburst", party.level, party.x, party.y, party.facing, party.elevation).tiledamager:setCastByChampion(champion:getOrdinal())
			return false
			end
	spawn("frostburst", party.level, X, Y, party.facing, party.elevation).tiledamager:setCastByChampion(champion:getOrdinal())
        end,
minmay wrote: Fri Aug 09, 2019 6:38 am
Lorial wrote: Fri Aug 09, 2019 5:47 amIn the Grimrock Asset Pack all the "pedestals" use the minimalaveState, so I am not sure.
This is not true. There is only one pedestal in the asset pack and it does not have minimalSaveState. Objects that have SurfaceComponents or SocketComponents, including the object you posted, will break if you give them minimalSaveState.
I see, guess I mixed things up this morning when quickly skimming through the list before getting this post out. So I assume removing the minimalSaveState will leave the interactive alcove intact and its items accessible. Thanks for the correction.
kelly1111
Posts: 349
Joined: Sun Jan 20, 2013 6:28 pm

Re: Ask a simple question, get a simple answer

Post by kelly1111 »

Question about using external scripts. If I make use of alot of external scripts (for instance for all my in dungeon script functions)
Is there a limit to this? In the sense of it hurting performance, or improving performance... or is it neglegible?

I am asking this becouse I have also hit the mark of to many constants in my mod. And when I push all the scripts into external scripts I can save some room.

Another thing bites me in the back right now is that I am using to many levels of a big grid size. 64*64 ... when you use them and add height difference, reflections... that adds up quickly in the dungeon.lua.

So I think I'll be toning them down to 32*32 again...
hmmm.. come to think on it... 32*64 would not be a problem script line wise... and 64*32 will ...

Anyway, I keep bumping into this stuborness I have of wanting to make a mega dungeon with a bigger grid / map size.
Perhaps It's time to let it go , and go for the normal grid size :D
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

kelly1111 wrote: Sun Aug 11, 2019 4:56 pmQuestion about using external scripts. If I make use of alot of external scripts (for instance for all my in dungeon script functions)
Is there a limit to this? In the sense of it hurting performance, or improving performance... or is it neglegible?

I am asking this becouse I have also hit the mark of to many constants in my mod. And when I push all the scripts into external scripts I can save some room.
The performance difference between making a ScriptComponent embedded or external is totally negligible. The only potentially significant difference is that embedded ScriptComponents save their entire source code in the savegame whereas external ones save the path to the file, but this would only be significant in the case of an extremely large script, like hundreds of thousands of lines of code large.
Changing a ScriptComponent from embedded to external will not change the number of constants in your dungeon.lua. You just replace one constant (the source code string) with another constant (the file path string).
I suppose if you make ALL your scripts external or ALL your scripts embedded, then you avoid having the "setSource" or "loadFile" constant respectively, saving a whopping one (1) constant from your 65,536 slots...

So, for the fourth time: My recommendation for getting around the constant limit is to pick out groups of decorative objects that you're unlikely to change, and cut and paste their spawn() calls from your dungeon.lua to an external script file, then have a ScriptComponent load that file. You'll need to add the level to the spawn() calls though, and will want to get rid of editor-generated IDs like "forest_oak_1" (otherwise the next time you place a forest_oak in the editor it will collide with the id in the script).
Or you could start the script with a replacement for the spawn() function. For example:

Code: Select all

-- add level and strip id
local currentLevel = 1
local spawn = function(name,x,y,facing,elevation,id)
  spawn(name,currentLevel,x,y,facing,elevation)
end
-- code directly pasted from dungeon.lua level 1 with no changes 
spawn("forest_border_rocks_01",6,13,1,0,"forest_border_rocks_01_126")
spawn("forest_border_rocks_01",6,14,1,0,"forest_border_rocks_01_127")
spawn("forest_border_rocks_01",6,15,1,0,"forest_border_rocks_01_128")
spawn("forest_border_rocks_01",7,16,0,0,"forest_border_rocks_01_129")
spawn("forest_border_rocks_01",7,16,1,0,"forest_border_rocks_01_130")
spawn("forest_border_rocks_01",8,17,0,0,"forest_border_rocks_01_131")
spawn("forest_border_rocks_01",8,17,1,0,"forest_border_rocks_01_132")
spawn("forest_border_rocks_01",8,18,1,0,"forest_border_rocks_01_133")
spawn("forest_border_rocks_01",8,19,1,0,"forest_border_rocks_01_134")
spawn("forest_border_rocks_01",8,20,1,0,"forest_border_rocks_01_135")
spawn("forest_border_rocks_01",8,21,1,0,"forest_border_rocks_01_136")
spawn("forest_border_rocks_01",6,9,1,0,"forest_border_rocks_01_137")
spawn("forest_border_rocks_01",6,8,1,0,"forest_border_rocks_01_138")
spawn("forest_border_rocks_01",6,8,0,0,"forest_border_rocks_01_139")
spawn("forest_border_rocks_01",5,7,1,0,"forest_border_rocks_01_140")
spawn("forest_border_rocks_01",5,6,1,0,"forest_border_rocks_01_141")
spawn("forest_border_rocks_01",5,7,3,0,"forest_border_rocks_01_142")
spawn("forest_border_rocks_01",5,6,3,0,"forest_border_rocks_01_143")
spawn("forest_border_rocks_01",5,5,3,0,"forest_border_rocks_01_144")
spawn("forest_border_rocks_01",5,5,0,0,"forest_border_rocks_01_145")
spawn("forest_border_rocks_01",6,4,3,0,"forest_border_rocks_01_146")
spawn("forest_border_rocks_01",5,3,2,0,"forest_border_rocks_01_147")

-- set up for next level
currentLevel = 2

-- more code pasted directly from dungeon.lua level 2 with no changes
spawn("temple_pillar",4,18,3,0,"temple_pillar_81")
spawn("temple_pillar",5,18,3,0,"temple_pillar_82")
spawn("temple_pillar",6,18,3,0,"temple_pillar_83")
spawn("temple_pillar",9,18,0,0,"temple_pillar_86")
spawn("temple_pillar",10,19,2,0,"temple_pillar_88")
spawn("temple_pillar",10,21,3,0,"temple_pillar_90")
spawn("temple_pillar",10,22,0,0,"temple_pillar_91")
spawn("temple_pillar",10,23,2,0,"temple_pillar_92")
spawn("temple_pillar",10,24,1,0,"temple_pillar_93")
spawn("temple_pillar",9,25,3,0,"temple_pillar_95")
spawn("temple_pillar",8,25,2,0,"temple_pillar_96")
spawn("temple_pillar",5,25,0,0,"temple_pillar_99")
spawn("temple_pillar",4,25,2,0,"temple_pillar_100")
spawn("temple_pillar",3,24,1,0,"temple_pillar_102")
spawn("temple_pillar",3,21,1,0,"temple_pillar_105")
spawn("temple_pillar",3,20,2,0,"temple_pillar_106")
spawn("temple_pillar",3,19,0,0,"temple_pillar_107")
kelly1111 wrote: Sun Aug 11, 2019 4:56 pmAnother thing bites me in the back right now is that I am using to many levels of a big grid size. 64*64 ... when you use them and add height difference, reflections... that adds up quickly in the dungeon.lua.
Tile/height/reflection/noise maps are stored very efficiently, this really isn't a problem. In fact splitting a 64x64 level into four 32x32 levels will use slightly more space in the dungeon.lua and in memory (but will obviously greatly improve framerate in the actual game!).
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.
User avatar
7Soul
Posts: 209
Joined: Sun Oct 19, 2014 1:56 am
Location: Brazil

Re: Ask a simple question, get a simple answer

Post by 7Soul »

minmay wrote: Sun Aug 11, 2019 9:37 pmconstant limit
Constant limit? What constant limit?
Join the LoG discord server: https://discord.gg/ArgAgNN :D

My Mods
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

Functions in Lua are limited to 65536 constants at compile time. Because dungeon.lua uses a string constant for every GameObject id and GameObject ids are unique, every GameObject placed in your dungeon corresponds to at least one constant (more if one of its name, or one of its x,y,facing,elevation,level values has not appeared previously).
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.
User avatar
vanblam
Posts: 243
Joined: Sun Nov 09, 2014 12:15 am

Re: Ask a simple question, get a simple answer

Post by vanblam »

Silly question, can you spread items across a surface, instead of it all being clumped in one spot? Or would you have to create multiple surfaces?

Oh one more question, I saw a video where someone set up a transition between 2 areas, but you could see what was on the other side, does anyone know how to set that up?
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

Yes, use GameObject:setWorldPosition() or GameObject:setSubtileOffset() to adjust the positions of the items.
vanblam wrote: Mon Aug 12, 2019 5:56 pmOh one more question, I saw a video where someone set up a transition between 2 areas, but you could see what was on the other side, does anyone know how to set that up?
It isn't really showing what's on the other side, they just duplicated the objects on both levels so that it looks like it's showing the other side.
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.
User avatar
7Soul
Posts: 209
Joined: Sun Oct 19, 2014 1:56 am
Location: Brazil

Re: Ask a simple question, get a simple answer

Post by 7Soul »

Does any of the hooks (onDamage, etc) let you reduce how much damage was taken by the party or by a monster
Like say

Code: Select all

onDamage = function(self, champion, damage, damageType)
return damage * 0.5
end
Join the LoG discord server: https://discord.gg/ArgAgNN :D

My Mods
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

For champions, you can effectively reduce (or increase) damage taken by using the onDamage hook. For example, if you want to reduce all damage by the champion's level, to a minimum of 1:

Code: Select all

onDamage = function(self, champion, damage, damageType)
	if GameMode.damageRecurse then
		GameMode.damageRecurse = nil
		return true
	elseif damage > 1 then
		damage = math.max(1,damage-champion:getLevel())
		GameMode.damageRecurse = true
		champion:damage(damage,"pure")
		return false
	end
end
For monsters, it's a lot harder, because you'd have to manually call showDamageText() (which wouldn't be a problem except that it requires you to determine whether the attack was a critical hit, which is NOT easy to determine), recreate the animation, the hit particle effect, and so on.
I suggest that you just give your monsters more or less health if you want them to be faster or slower to kill.
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