Page 1 of 1

Breakable Obstacles triggering other things

Posted: Thu Jul 21, 2016 4:04 pm
by Mortis_of_Midian
Yet another question from me because things don't work quite the way I'd expect

The basic aim here is to have a room full of breakable obstacles (example: terracotta_jars_block) and have the player break them all to open a door (via a counter). I also like elsewhere in my dungeon to have breakable objects that trigger other things when broken.

The initial problem here is that breakable obstacles don't have connectors

My first experiment involved putting the Jars on Floor Triggers - this of course did not work because floor triggers don't detect obstacles / obstacles don't count as Items

So my first thought was to use the Jar's Heath reaching 0 and it seemed simple enough. Note because this was a experiment I wired one directly to the door rather than to a counter.

Code: Select all

 if terracotta_jars_block_3.health:getHealth() == 0 then dungeon_secret_door_50.door:open() 
this however doesn’t work, because (I think) the 'terracotta_jars_block' object is replaced with a 'terracotta_jars_block_damaged' object and eventually a 'terracotta_jars_block_broken_1' - so I get a Nil Value error.

So I decided on a different approach using what I learned about spawning Monsters with connectors

Code: Select all

 spawn("terracotta_jars_block", 8, 14, 17, 1, 0)health:addConnector("onDie", dungeon_secret_door_50.door:open() ) 
this also gives me a Nil Value error, but this time on the Health Component for reasons I don't understand (according to the scripting reference page the Health Component does have an onDie)


So what next? Do I really need to go about making custom versions of the Breakable Obstacles with added Connectors? (and if so, how? I'm going to need pointing to a good tutorial)

Re: Breakable Obstacles triggering other things

Posted: Thu Jul 21, 2016 5:09 pm
by THOM
Do you have the LoG2 Asset Pack?

You can look there at the definitions of the breakable object. It will show you: You can add to the Health-Component a line like:

Code: Select all

			onDie = function(self)
				counterXY.counter:increment()
			end,

Re: Breakable Obstacles triggering other things

Posted: Thu Jul 21, 2016 7:56 pm
by minmay
You wanted this:

Code: Select all

spawn("terracotta_jars_block", 8, 14, 17, 1, 0).health:addConnector("onDie","dungeon_secret_door_50","open")

Re: Breakable Obstacles triggering other things

Posted: Thu Jul 21, 2016 9:17 pm
by Zo Kath Ra
Mortis_of_Midian wrote:this however doesn’t work, because (I think) the 'terracotta_jars_block' object is replaced with a 'terracotta_jars_block_damaged' object and eventually a 'terracotta_jars_block_broken_1' - so I get a Nil Value error.

So what next? Do I really need to go about making custom versions of the Breakable Obstacles with added Connectors? (and if so, how? I'm going to need pointing to a good tutorial)
You're right, when a "terracotta_jars_block" dies, it spawns a "terracotta_jars_block_damaged".
And when a "terracotta_jars_block_damaged" dies, it spawns a "terracotta_jars_block_broken".

You need to create new versions of these objects, like this:

Code: Select all

defineObject{
	name = "terracotta_jars_block_new",
	baseObject = "base_obstacle",
	components = {
		{
			class = "Model",
			model = "assets/models/env/terracotta_jars_block.fbx",
		},
		{
			class = "Obstacle",
			hitSound = "terracotta_jar_hit",
			hitEffect = "hit_terracotta_jar",
		},
		{
			class = "Health",
			health = 15,
			immunities = { "poison" },
			spawnOnDeath = "terracotta_jars_block_damaged_new",
		},
	},
	editorIcon = 260,
}

defineObject{
	name = "terracotta_jars_block_damaged_new",
	baseObject = "base_obstacle",
	components = {
		{
			class = "Model",
			model = "assets/models/env/terracotta_jars_block_damaged.fbx",
		},
		{ 
			class = "Obstacle",
			hitSound = "terracotta_jar_hit",
			hitEffect = "hit_terracotta_jar",
		},
		{
			class = "Health",
			health = 15,
			immunities = { "poison" },
			spawnOnDeath = "terracotta_jars_block_broken_new",
			onDie = function(self)
				self.go:playSound("terracotta_jar_die")
				
				for entity in self.go.map:entitiesAt(self.go.x, self.go.y) do
				    if (entity.counter) then
				        entity.counter:decrement()
				    end
				end
			end,
		},
	},
	editorIcon = 260,
}


defineObject{
	name = "terracotta_jars_block_broken_new",
	baseObject = "base_floor_decoration",
	components = {
		{
			class = "Model",
			model = "assets/models/env/terracotta_jars_block_broken.fbx",
		},
	},
}
When a "terracotta_jars_block_damaged_new" dies, it decrements all counters on the same square.
Put a counter on the same square as the "terracotta_jars_block_new", set the counter's value to 1, and connect the counter to anything you want. You can connect it to another counter to implement the kind of room you described.

Re: Breakable Obstacles triggering other things

Posted: Thu Jul 21, 2016 11:07 pm
by Mortis_of_Midian
Thanks guys :)

Minmay's correction to my code worked, but triggered the door when the original object died.

So … it looks like I'm treading into the territory of defining new objects

and here come my next (newbie) question:

where do I enter the defineObject code that Zo Kath Ra has kindly worked out for me?

And since I'm now headed that was I also have further questions about custom objects which will follow if that's ok :)

Re: Breakable Obstacles triggering other things

Posted: Thu Jul 21, 2016 11:15 pm
by Isaac
Try this script. Place it on the map and edit the breakable_set table to contain the object ids of all of the breakable objects you will use.
Edit the trigger action to suit your purpose.

Code: Select all

--Works with most breakable objects

breakable_puzzle_count = 0  --==========================[ In-script counter, (no need for a counter object) ]
breakable_set = { --==[ Add the id below for each breakable object in the puzzle; change names to suit ]
				"terracotta_jars_block_1",
				"barrel_crate_block_1",
				"forest_thorn_blocker_1",
				"beach_thicket_01_1",
				"spider_eggs_1",
				"beach_cattail_blocker_1",
				}
				
--==[ Adds the 'onDie' connector to all breakable objects; when they die, they call getDamageId() ]				
for x = 1, #breakable_set do findEntity(breakable_set[x]).health:addConnector("onDie", self.go.id, "getDamageId") end			



function increment() --==[ increments and then checks the value of breakable_puzzle_count; triggers action when all objects are broken]
		breakable_puzzle_count = breakable_puzzle_count +1
		if breakable_puzzle_count >= #breakable_set then
		
		-----------------------------------------------------trigger action; change actions to suit	
			
			dungeon_door_wooden_1.door:open()

		-----------------------------------------------------	
			self.go:destroyDelayed()  --deletes script after it completes
		end
end

--============================[ Derives the damaged object ID from the dying object, and calls updateDamaged() ]
function getDamageId(object)
	if object.go.health then 
		for each in object.go.map:entitiesAt(object.go.x, object.go.y) do
			if each.name == object.go.health:getSpawnOnDeath() then
				updateDamaged(each.id)
				return
			end
		end
	end	
end

--============================[ Adds 'onDie' connector to newly spawned damage object; calls increment() ]
function updateDamaged(damageId)
		if findEntity(damageId) and findEntity(damageId).health then
			findEntity(damageId).health:addConnector("onDie", self.go.id, "increment")
		 else increment()	
		end	
end
Demo project: https://www.dropbox.com/s/xhjd5ncbhmz39 ... g.zip?dl=0
Mortis_of_Midian wrote:where do I enter the defineObject code that Zo Kath Ra has kindly worked out for me?
Usually in the object.lua file; found in the project folder for your map.
*On Windows OS [vista/7+?] this is commonly: c:\Users\%username%\Documents\Almost Human\Legend of Grimrock 2\Dungeons\ (the name of your map) \mod_assets\scripts\object.lua

Check your documents folder for "Almost Human".

Re: Breakable Obstacles triggering other things

Posted: Fri Jul 22, 2016 11:20 pm
by Mortis_of_Midian
Isaac, excellent! Thank you, I was hoping there was a solution that didn't involve custom objects as I don't want to get into that just yet. :-)

Having said that I'm starting to feel the need for 2 Custom objects, both based on the Fire Trap Rune - an arrow marked on the floor and a magic circle - should prove simple enough?

Anyway the script worked perfectly :-)