Monster Invocation spell

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
Khollik
Posts: 171
Joined: Tue Aug 29, 2017 6:44 pm
Location: France

Monster Invocation spell

Post by Khollik »

Hi everyone,

For a new mod I'm working on, I'd like to create an "invoke ally spell" to allow the party to call for a "friend" to fight for them a short time, but I'm not even sure it is possible. I'm good with the "spawn monster" part of the spell, but so far I see no way to make him target a foe. The closest I can see is using BrainComponent:performAction() to make it attack a "non-party" entity. But before diving into it (I'm still not very at ease with customizing monster brains...), I'm actually wondering if it's even feasible.

Has anyone ever tried something like that???

Thanks
Khollik
User avatar
Isaac
Posts: 3185
Joined: Fri Mar 02, 2012 10:02 pm

Re: Monster Invocation spell

Post by Isaac »

Khollik wrote: Thu Jun 14, 2018 9:45 pm Has anyone ever tried something like that???
I had been working on something like that for my ORRR3 room; it's backlogged, but I'd like to include it if I can.

*AFAIK, there is no supported way for a monster to attack another monster with melee. There are ways to spawn and control the movement of monsters, and play their animations on command. One can damage other monsters with a tile-damager or projectile attack. The spell will have to be a scripted illusory effect.
User avatar
Khollik
Posts: 171
Joined: Tue Aug 29, 2017 6:44 pm
Location: France

Re: Monster Invocation spell

Post by Khollik »

Hi Isaac

Thanks for your answer. So far, here what I can see :
- create a custom "ally" brainComponent
- implement an "onThink" hook with the following :
a] check if there is a monster in the vicinity of the party (say 3 or 4 squares). If not, then brain:follow() the party
b] if there is a monster, use brain:follow() or brain:pursuit() (although I'm not quite sure of the difference) to get the summoned ally to an adjacent tile of the monster threatening the party
- then performAction() to get the ally to attack the foe

Of course, that implies to also create a new "monster_ally" wich would be the same as a regular monster but with the modified brain. I'm ok with that, since I don't necessarily want the party to summon any kind of monster. I'm rather thinking of a "raise dead" spell actually...

What do you think of it ?
If I understand well, you seem to say that the game won't be able to apply the attack to the foe because it won't consider it as a legitimate target of the melee attack? So the last step shouldn't work?

K.
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Monster Invocation spell

Post by zimberzimber »

Since Grimrock was not built with allied monsters in mind, there are another two things you have to take into account:

- Blocking Paths:
Unless you plan on making the entire dungeon have two tile wide corridors, I can guarantee that the monster will always be blocking your path. It might also help the enemy cornering you thanks to bad positioning.

- Other Monsters:
Unless you plan on modifying all the brains for all the monsters, and all the melee attack components to damage monsters, enemy monsters will entirely ignore your allied monster.
My asset pack [v1.10]
Features a bit of everything! :D
User avatar
Isaac
Posts: 3185
Joined: Fri Mar 02, 2012 10:02 pm

Re: Monster Invocation spell

Post by Isaac »

Khollik wrote: Fri Jun 15, 2018 11:38 am If I understand well, you seem to say that the game won't be able to apply the attack to the foe because it won't consider it...
AFAIK, there is no way to have a monster damage anything with a melee attack, except the party. You can command the brain component to perform an attack on an occupied tile, but the monster only goes through the motions, and the target/victim does not react.

One would have to completely script the encounter to position the monster, play the attack, determine whether or not they hit, then play the target's reaction, and provide for damaging them; and presumably handle their retreat, and/or any return attacks they give—and the reactions of their targets, and the damage done to them.
Last edited by Isaac on Fri Jun 15, 2018 1:29 pm, edited 1 time in total.
User avatar
Zo Kath Ra
Posts: 937
Joined: Sat Apr 21, 2012 9:57 am
Location: Germany

Re: Monster Invocation spell

Post by Zo Kath Ra »

zimberzimber wrote: Fri Jun 15, 2018 12:07 pm - Blocking Paths:
Unless you plan on making the entire dungeon have two tile wide corridors, I can guarantee that the monster will always be blocking your path. It might also help the enemy cornering you thanks to bad positioning.
Or you could make the ally walkable, like rat packs.
And program its brain so it doesn't walk onto the party tile unless absolutely necessary.
Or maybe that's what you want, because the ally is like a dog that always wants to be close to its master.
User avatar
Khollik
Posts: 171
Joined: Tue Aug 29, 2017 6:44 pm
Location: France

Re: Monster Invocation spell

Post by Khollik »

Thanks everyone, it makes me feel I didn't go through every potential issue here... :?

OK, so far the easy part is done.

Raise dead spell

Code: Select all

defineSpell{
	name = "raise_dead",
	uiName = "Raise Dead",
	gesture = 78965,
	manaCost = 35,
	onCast = function(champion, skillLevel)
	  local ix,iy = getForward(party.facing)  	-- get coordinates of the tile in front of the party
	  ix = (ix) + party.x   	
	  iy = (iy) + party.y
		if findEntity("bodyguard") ~= nil then  -- check if there is already one bodyguard summoned
		hudPrint("You already control one ally")
		playSound("spell_fizzle")
		else
		if party.map:checkLineOfFire(party.x,party.y,ix,iy,party.elevation) == true then
			if not party.map:isBlocked(ix,iy,party.elevation)
			then
			spawn("timer",party.level,1,1,0,0,"bodyguard_timer")
			bodyguard_timer.timer:setTimerInterval(30)
			bodyguard_timer.timer:setDisableSelf(true)
			bodyguard_timer.timer:setTriggerOnStart(false)
			bodyguard_timer.timer:setCurrentLevelOnly(false)
			bodyguard_timer.timer:addConnector("onActivate","bodyguard_script","bodyguardcheck")
			spawn("bodyguard",party.level,ix,iy,party.facing,party.elevation,"bodyguard")
			bodyguard_timer.timer:start()
			else
			playSound("spell_fizzle")
			hudPrint("You can't cast that here")
			end
		else
			playSound("spell_fizzle")
			hudPrint("You can't cast that here")
		end
		end
	end,
	skill = "concentration",
	requirements = { "concentration", 1 },
	icon = 45,
	spellIcon = 15,
	description = "Bring out your dead !",
}
The spell checks if there is not already an ally summoned, and if the tile facing the party is within line of sight and not blocked. If so, it spawns an undead bodyguard with a timer connected to a script to destroy the ally after 30s (I don't want him to be permanent) :

Code: Select all

function bodyguardcheck()
playSound("spell_fizzle")
if findEntity("bodyguard") ~= nil then   -- it checks if by any chance the bodyguard was already killed
bodyguard.monster:die()
end
bodyguard_timer:destroy()
end
As for the bodyguard himself, brain:pursuit() works perfectly and now I have a nice little undead following my party :mrgreen:

Code: Select all

{
class = "Brain",
name = "brain",
sight = 7,      -- I boosted the sight to be sure it can follow the party. Not sure if it's very useful
morale = 100,
onThink = function(self)
	if self.partyOnLevel then
		if self.seesParty then self:pursuit()
		else self:moveTowardsParty() end
	else self:wait()
	end
end,
},
The only thing so far is that the bodyguard is quite slow :lol: :lol: but the player is not supposed to be that powerful in the arts of necromancy, I suppose.

Now for the thoughest part, I have to figure out how to make him attack other foes. I hope it's not too far beyond my scripting skills...

BTW, I don't mind if the bodyguard can be in the way of the party. Actually, those are pretty narrow corridors, it's up to the party to decide when to cast the spell :D But I might consider Zo Kath Ra's tip.


PS : I have to say Eburt's post on BrainComponent was quite useful to me
viewtopic.php?f=22&t=9720&p=93615&hilit ... ent#p93615
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Monster Invocation spell

Post by zimberzimber »

Zo Kath Ra wrote: Fri Jun 15, 2018 1:29 pm Or you could make the ally walkable, like rat packs.
And program its brain so it doesn't walk onto the party tile unless absolutely necessary.
Or maybe that's what you want, because the ally is like a dog that always wants to be close to its master.
Which then makes other monsters be able to walk over it, and block other swarm like monsters, so you couldn't get, lets say, an allied Herder because it'll look bad.
My asset pack [v1.10]
Features a bit of everything! :D
User avatar
Zo Kath Ra
Posts: 937
Joined: Sat Apr 21, 2012 9:57 am
Location: Germany

Re: Monster Invocation spell

Post by Zo Kath Ra »

zimberzimber wrote: Fri Jun 15, 2018 7:44 pm Which then makes other monsters be able to walk over it, and block other swarm like monsters, so you couldn't get, lets say, an allied Herder because it'll look bad.
Another solution would be to make the "undead bodyguard" (presumably a zombie) like the viper root.
If the player bumps into it, the zombie burrows back into the ground, and only resurfaces when the tile is free again.
(how much work would it be to create a reverse spawn animation?)
It would look strange if a zombie burrowed into/out of a stone floor, but that's exactly what happens in the lindworm boss battle in LoG2.
And if Almost Human does it, it's canon :)
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Monster Invocation spell

Post by zimberzimber »

Zo Kath Ra wrote: Fri Jun 15, 2018 8:19 pm Another solution would be to make the "undead bodyguard" (presumably a zombie) like the viper root.
If the player bumps into it, the zombie burrows back into the ground, and only resurfaces when the tile is free again.
(how much work would it be to create a reverse spawn animation?)
It would look strange if a zombie burrowed into/out of a stone floor, but that's exactly what happens in the lindworm boss battle in LoG2.
And if Almost Human does it, it's canon :)
Now thats just getting very complicated.

What you could do, is have "spirits" that aren't monsters at all, just objects with an attached model and an ethereal looking texture.
Said spirits would have a slight offset from the middle of the tile so they don't collide with monsters visually.
They would also be invulnerable, but either tied to a small radius, have a lifespan, or drain the summoners energy as long as its alive until there's no energy to drain and the spirit dies off.
The spirit, upon detecting a monster on the tile, does stuff. Spawn a tile damage, spawn a projectile, etc...
But this will require creating your own brain from scratch since you don't have a monster component on it.
My asset pack [v1.10]
Features a bit of everything! :D
Post Reply