Crushing monsters by closing door

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Crushing monsters by closing door

Post by JKos »

Has anybody else tried to implement this yet?
I can't find an easy way to make this work nicely.

I think we need door:onClose hook and monster:movingDirection-method or property, then I could implement script which finds monsters moving through door when it is closing and does damage to them.
As a programmer I think those should be pretty easy to implement, just call door:onClose from door:close-method and there has to be moving direction calculation code already, because it is passed to monster:onMove-hook.
So Almost Humans, could you please implement these? ;)

Or maybe someone smarter than me has figured out how to do this with current features?
- 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
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: Crushing monsters by closing door

Post by JKos »

I was able to implement this after patch 1.2.8. I't not very nice solution, but works.

This example shows how you can make bashable spiders.
First you need to override the spider asset in init.lua (or in other lua file)

Code: Select all

cloneObject{
	name = "spider",
	baseObject = "spider",
	onMove = function(self, dir)
	   monsters.directions[self.id] = dir
	end,
	onAttack = function(self, attack)
	   monsters.directions[self.id] = self.facing
	end,	
	onDamage = function(self, attack)
	   -- to prevent continuous bashing with door
	   monsters.directions[self.id] = nil
	end,
}
Then you have to add a script entity named monsters and define table-property named directions there.

Code: Select all

directions = {}
monsters moving directions are stored there as you can see from previous code.

Then make another script entity named doors

Code: Select all

function close(door_name)

-- do some damage to monsters at same tile as the door and moving through it
	local door = findEntity(door_name)
	local monstersAtDoor = entitiesAt(door.level,door.x,door.y)
	
	for monst in monstersAtDoor do
		if door.facing == monsters.directions[monst.id] then
			damageTile(door.level,door.x,door.y,door.facing,1,"physical",5)
			print("door made damage to "..monst.id)
		end
	end

-- do some damage to monsters at other side of the door and moving through it	
	local door_x = door.x
	local door_y = door.y
	
	if (door.facing == 0) then
		door_y = door_y + 1
	elseif (door.facing == 2) then
		door_y = door_y - 1 
	elseif (door.facing == 1) then
		door_x = door_x + 1 	
	else
		door_x = door_x - 1 
	end	
	
	local monstersAtOtherSideOfDoor = entitiesAt(door.level,door_x,door_y)	
	if door.facing >= 2 then
	  door_opposite_facing = door.facing - 2
	else
	  door_opposite_facing = door.facing + 2
	end
	
	for monst in monstersAtOtherSideOfDoor do
	print("monter_found:"..monst.id)
		if door_opposite_facing == monsters.directions[monst.id] then
			damageTile(door.level,door_x,door_y,door_opposite_facing,1,"physical",5)
			print("door made damage to " ..monst.id)
		end
	end	
	
	door:close()
		
end

function toggle(door_name)
	local door = findEntity(door_name)
	if door:isOpen() then 
		self.close(door_name)
	else
		door:open()
	end
end

-- you have to make similar function for every door, if you want it to be able to deal damage to monsters :(
-- I wish there was door:onClose-hook or possibility to pass parameters to actions called by connectors
function toggleMetal1()
 self.toggle("dungeon_door_metal_1")
end
add dungeon_door_metal_1 and a wall button which triggers doors.toggleMetal1()

Spiders will receive damage when moving or attacking through dungeon_door_metal_1
Have fun crushing those nasty spiders :)
- 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
petri
Posts: 1917
Joined: Thu Mar 01, 2012 4:58 pm
Location: Finland

Re: Crushing monsters by closing door

Post by petri »

Neat! I'll add onOpen and onClose hooks for you in the next patch. Any other hooks that would be useful?
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: Crushing monsters by closing door

Post by Montis »

maybe onTeleport for teleporters? that would actually be really neat like you could teleport and instantly deactivate the teleporter "behind" you.

what I also would like to see is:
Teleporter:isActivated()
Timer:isActivated()
-> returns true or false if the teleporter or timer is activated/deactivated (for a timer that would mean: currently running).
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: Crushing monsters by closing door

Post by JKos »

Cool, thanks so much for adding that hook. Now it works like a charm. Here is an example how to make spiders and snails crushable by wooden and metal doors.


init.lua

Code: Select all


local MonstersList = {"crab","crowern","cube","snail","spider"}


for i=1,# MonstersList do 
	cloneObject{
		name = MonstersList[i],
		baseObject = MonstersList[i],
		onMove = function(self, dir)
			monsters.directions[self.id] = dir
		end,
		onAttack = function(self, attack)
			   monsters.directions[self.id] = self.facing
		end,
		onDamage = function(self, attack)
			-- to prevent continuous bashing with door
			 monsters.directions[self.id] = nil
		end,
		onDie = function(self)
		    -- clear dead monsters from directions table
			monsters.directions[self.id] = nil
		end,		
	}
end


cloneObject{
	name = "dungeon_door_metal",
	baseObject = "dungeon_door_metal",
	onClose = function(self)
		doors.crush(self,30)
	end,
}
cloneObject{
	name = "dungeon_door_wooden",
	baseObject = "dungeon_door_wooden",
	onClose = function(self)
		doors.crush(self,10)
	end,
}

monsters script-entity

Code: Select all

directions = {}
doors script-entity

Code: Select all

debug = false 

function crush(door, damagePower)
-- do some damage to monsters on same tile as the door and moving through it
	local monstersAtDoor = entitiesAt(door.level,door.x,door.y)
	
	for monst in monstersAtDoor do
		if door.facing == monsters.directions[monst.id] then
			damageTile(door.level,door.x,door.y,door.facing,1,"physical",damagePower)
			if self.debug then print("door made damage to "..monst.id) end
		end
	end

-- do some damage to monsters at other side of the door and moving through it	
	local door_x = door.x
	local door_y = door.y
	-- find a tile which is next to door to it's facing direction
	if (door.facing == 0) then
		door_y = door_y - 1
	elseif (door.facing == 2) then
		door_y = door_y + 1 
	elseif (door.facing == 1) then
		door_x = door_x + 1 	
	else
		door_x = door_x - 1 
	end	
    
	if door.facing >= 2 then
	  door_opposite_facing = door.facing - 2
	else
	  door_opposite_facing = door.facing + 2
	end
	
	local monstersAtOtherSideOfDoor = entitiesAt(door.level,door_x,door_y)	

	for monst in monstersAtOtherSideOfDoor do
		if door_opposite_facing == monsters.directions[monst.id] then
			damageTile(door.level,door_x,door_y,door_opposite_facing,1,"physical",damagePower)
			if self.debug then print("door made damage to " ..monst.id) end
		end
	end	
end
So now dungeon_door_metal and dungeon_door_wooden will deal damage to snails and spiders when they are moving or attacking through door when it's closing.
Metal door will make more damage than wooden door.
Last edited by JKos on Thu Sep 20, 2012 8:03 pm, edited 2 times in total.
- 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
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: Crushing monsters by closing door

Post by JKos »

I uploded a sample dungeon with damage dealing doors to my google-drive.

https://docs.google.com/open?id=0B7cR7s ... FFtWWJQcWs
just unzip it to your Documents\Almost Human\Legend of Grimrock\Dungeons
and open it with editor

Any feedback is welcome. And I hope to see this used in some mods too :) I'm better at writing scripts than designing dungeons.
- 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
petri
Posts: 1917
Joined: Thu Mar 01, 2012 4:58 pm
Location: Finland

Re: Crushing monsters by closing door

Post by petri »

Great! One thing still, I think it would be better to remove dead monsters from monsters.directions. As it is now the table gets bigger and bigger when new monsters are spawned which consumes memory and makes save games larger.
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: Crushing monsters by closing door

Post by JKos »

petri wrote:Great! One thing still, I think it would be better to remove dead monsters from monsters.directions. As it is now the table gets bigger and bigger when new monsters are spawned which consumes memory and makes save games larger.
Thanks, it's really nice to get feedback from you. But I think they are removed already because they are set to nil on onDamage-hook, which is of course always called just before onDie-hook. So I have accidentally implemented that already :) I just tested it.
- 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
petri
Posts: 1917
Joined: Thu Mar 01, 2012 4:58 pm
Location: Finland

Re: Crushing monsters by closing door

Post by petri »

Ah, ok, I missed that. OnDamage should cover all common cases. There might be some corner cases where monster is killed without being damaged. For instance telefragging.
User avatar
Darklord
Posts: 2001
Joined: Sat Mar 03, 2012 12:44 pm
Location: England

Re: Crushing monsters by closing door

Post by Darklord »

Hah this is awesome, I kinda of missed hitting enemies with doors! :lol:

Daniel.
A gently fried snail slice is absolutely delicious with a pat of butter...
Post Reply