Make sure it is the party that kills a monster

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!
Post Reply
User avatar
cromcrom
Posts: 549
Joined: Tue Sep 11, 2012 7:16 am
Location: Chateauroux in a socialist s#!$*&% formerly known as "France"

Make sure it is the party that kills a monster

Post by cromcrom »

In my mod, the party gains XPS, general, and skill xps, or loot, suposedly when it kills a monster.

However, there are times when a monster will get stuck in a damaging tile, and die out of "natural" causes. In this case, the onDie is called, and the party receives the benefits, even tho it never touched the monster.

How to make sure it is the party that killed the monster ?

I thought of creating "cadaver" objects, that would be spawned onDie, and would need party pick up to give the benefits of the death to the party.
Maybe something easier/different could be done ?
A trip of a thousand leagues starts with a step.
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: Make sure it is the party that kills a monster

Post by Isaac »

The easiest way to not have monster's die on a damage tile, is to not have them trigger the plate ~if you are using plates to trigger damageTile.
(If appearance matters, then you can use floor_triggers (set to not activate on monsters) and cosmetic pressure plates (connected to nothing, or connected just to the damage audio/visual effects), in the same locations. That way monsters appear to trigger the plate when they step on it.)

Alternatively:
You could allow the damageTile to hurt them until their health is below 50% (or other amount).
Example: Connect plates to this script. Monsters that step on the plates get hurt ~unless below a certain percentage of health.
SpoilerShow

Code: Select all

function hurt(caller)
	local threshold = 50 
	local damage = threshold/3
	
	for entity in caller.go.map:entitiesAt(caller.go.x, caller.go.y) do
			if entity.monster then
				local health, maxHealth = entity.monster:getHealth() , entity.monster:getMaxHealth()
				if health < threshold then
				 entity.monster:setHealth(health+threshold) --Optional healing to allow future damage.
				 delayedCall(self.go.id, .9, "blast" ,caller, damage)
				 return
				end		
			end
	end

	delayedCall(self.go.id, .9, "blast" ,caller, damage)
end

function blast(caller, damage)
	caller.go:createComponent("Particle")
	caller.go.particle:setParticleSystem("fireburst")
	caller.go.particle:setOffset(vec(0,1.5,0))
	caller.go.particle:setDestroySelf(true)
	playSound("fireburst")
	damageTile(caller.go.level, caller.go.x, caller.go.y, caller.go.facing, caller.go.elevation, 1, "fire", damage)
end
https://www.dropbox.com/s/m8gm8t4gvmfow ... e.dat?dl=1
User avatar
cromcrom
Posts: 549
Joined: Tue Sep 11, 2012 7:16 am
Location: Chateauroux in a socialist s#!$*&% formerly known as "France"

Re: Make sure it is the party that kills a monster

Post by cromcrom »

Thanks a lot. I LOVE you guys scripts and stuff :-)
A trip of a thousand leagues starts with a step.
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: Make sure it is the party that kills a monster

Post by Isaac »

Image

A third alternative is to use normal pressure plates, and dynamically decide if they damage the target at all. In this method, monsters take no damage from triggering the plate, but the party does.
SpoilerShow

Code: Select all

delay = 0.9
damage = 20
function hurt(caller)
	for entity in caller.go.map:entitiesAt(caller.go.x, caller.go.y) do
			if entity.monster or entity.monstergroup then
				 delayedCall(self.go.id, delay, "blast" ,caller, damage ,false)
				 return	
			end
	end
	delayedCall(self.go.id, delay, "blast" ,caller, damage, true)
end

function blast(caller, damage, attack)
	caller.go:createComponent("Particle")
	caller.go.particle:setParticleSystem("fireburst")
	caller.go.particle:setOffset(vec(0,1.5,0))
	caller.go.particle:setDestroySelf(true)
	playSound("fireburst")
	if attack then
		damageTile(caller.go.level, caller.go.x, caller.go.y, caller.go.facing, caller.go.elevation, 1, "fire", damage)
	end
end
Post Reply