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!
minmay
Posts: 2484
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay » Thu Jan 10, 2019 11:48 pm

Did you remember to place a HeightmapComponent on the level?

Pompidom
Posts: 292
Joined: Sun May 06, 2018 9:42 pm

Re: Ask a simple question, get a simple answer

Post by Pompidom » Wed Jan 23, 2019 1:24 am

I need some help with a script. So I got my town, friendly npc characters are happily walking around entering/exiting shops and houses.

Now I want to create a script that when you attack them and you bring down their health under a certain threshold (static number or % value is fine) they will become hostile towards your party and attack your party.

For example, human knights have 400 hp in my mod and I want them to attack your party when their health drops below 200.

Something like this.

IF human_knight_4 <200 hp
THEN human_knight_4.basicattack:enable()

is this possible? I probably plan to link this script to a 1 second interval timer

User avatar
THOM
Posts: 997
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Ask a simple question, get a simple answer

Post by THOM » Wed Jan 23, 2019 2:05 am

Well - does that mean your knights never attack the party even if the party attacks them?

Or do they loose HP by another event?

Beside that: IMHO your way should work.

Code: Select all

if human_knight_4.monster:getHealth() <= 200 then
	human_knight_4.basicattack:enable()
end
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download

Pompidom
Posts: 292
Joined: Sun May 06, 2018 9:42 pm

Re: Ask a simple question, get a simple answer

Post by Pompidom » Wed Jan 23, 2019 2:15 am

For now all friendly npc's are basically just ordinary "monsters" walking around with their attacks disabled.

The only way they can lose health is when the party attacks them.
So basically attacking them accidentally will trigger a hudprint "Calm down" message where the npc will say random things like "please don't kill me" or "Is that all you got?".

When you continue attacking them and bring their health down to roughly 50% they will enable their .basicattack and attack the party.

I intend to give the player the choice to be helpful heroes or murderous evil bastards or basically anything in between.
The ending will be decided by a "doom" meter counting the amount of innocent people you have slain/helped and the amount of good/evil choices you have made.

I intend to make a map where you have to use stealth to infiltrate a hideout and npc's aren't allowed to detect you. if they do, they all become hostile and you will have to fight your way out increasing the doom meter forcing a less favourable ending.

I'll test out the script tomorrow.

Thanks Thom

User avatar
THOM
Posts: 997
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Ask a simple question, get a simple answer

Post by THOM » Wed Jan 23, 2019 2:51 am

Okay - so far, so good.

But I don't understand why someone should let you attack him until he is half dead. Especially if he is a knight.

Wouldn't it be enough if they never attack the party, even standing next to them? And then start fighting as soon as they got harmed? Would be the behaviour I would expect - and it still fits with your story.
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download

User avatar
Isaac
Posts: 2757
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac » Wed Jan 23, 2019 5:19 am

You might consider implementing an entity class (or a mixed set) based faction that allows the monster to check (and alter) the party's local reputation. That way each and every attack can (to anyone) can act as a mark against them, and cause any among the concerned faction to change their behavior towards them.

This could be as simple as counter that indicates the town as neutral/guarded/hostile—ie. three strikes and you're out... or complex; as in a shining reputation could see them treated well, and with any altercations causing colder treatment, and cautionary warnings, before outright hue & cry for their deaths. ;) Even looting containers (that they shouldn't) could give them a few strikes against their rep.

Pompidom
Posts: 292
Joined: Sun May 06, 2018 9:42 pm

Re: Ask a simple question, get a simple answer

Post by Pompidom » Wed Jan 23, 2019 11:52 am

THOM wrote:
Wed Jan 23, 2019 2:51 am
Okay - so far, so good.

But I don't understand why someone should let you attack him until he is half dead. Especially if he is a knight.

Wouldn't it be enough if they never attack the party, even standing next to them? And then start fighting as soon as they got harmed? Would be the behaviour I would expect - and it still fits with your story.
It's not that.

Npc's have way more health than regular monsters, So it's a big buffer in case you attacked them on accident. For example you let a rock fly on a pressure plate and some npc steps in and receives some throwing damage. That would be stupid.

Also, since it's not a hobo simulator you will have fairly quickly access to high damage weapons and spells.

They basically attack the party when they reach 100 % of their intended health as an aggressive enemy. And they simply start with 200% health.
The only way an npc becomes aggressive to the party would be if you attacked them multiple times. Intentional.

For example you're in some cold winter snow map slaying monsters, you enter a house, in that house lives a neutral mage you can talk to. But instead you accidentally attack him instantly because you didn't realize it was an npc.
A message pops up where he laughs at your "feeble" attacks as soon he is damaged in any way and he then tells you to take it easy and that you're welcome to warm yourself at his fireplace.

So in practice he will have for example 1200 health.
As soon you attack him even it is for 1 point of damage, he will "laugh" at your "feeble" attack and invite you to warm yourself up at his fireplace. (<1199 health script) which also instantly disables the "feeble attack response script"

At <900 health he will trigger the "calm down" response once and then the calm down response is disabled so he doesn't keep repeating himself.

At <600 health he will become aggressive and attack you.

leaving the house will reset all timers/scripts/triggers and reset his health pool in case he is still alive.
Killing him will disable everything and increase a doom counter towards a bad ending.

Plenty of practical solutions for that.

Basically I simply try to make my mod as immune as possible against player stupidity or missclicks.
And giving the player the choice to play as he/she wants.

Some npc gives you a quest to retrieve a magic item in some creepy dungeon. In return he will award you a key so you can progress the story. You do his crappy quest, or flat out kill the living shit out of him. It basically doesn't matter, in both cases you will get the key and you will be able to continue your story.

It also allows for multiple npc's to become hostile on the same map if you attack/kill 1 specific npc, or steal an item.
Last edited by Pompidom on Wed Jan 23, 2019 1:13 pm, edited 5 times in total.

Pompidom
Posts: 292
Joined: Sun May 06, 2018 9:42 pm

Re: Ask a simple question, get a simple answer

Post by Pompidom » Wed Jan 23, 2019 12:11 pm

Isaac wrote:
Wed Jan 23, 2019 5:19 am
You might consider implementing an entity class (or a mixed set) based faction that allows the monster to check (and alter) the party's local reputation. That way each and every attack can (to anyone) can act as a mark against them, and cause any among the concerned faction to change their behavior towards them.

This could be as simple as counter that indicates the town as neutral/guarded/hostile—ie. three strikes and you're out... or complex; as in a shining reputation could see them treated well, and with any altercations causing colder treatment, and cautionary warnings, before outright hue & cry for their deaths. ;) Even looting containers (that they shouldn't) could give them a few strikes against their rep.
But I have absolutely no idea how to do that, and my "buffer" health pools is basically a practical solution that simply works and offers protection against user stupidity at the same time.
Offering multiple playthroughs at the same time with different experiences and different endings.

Everything I want to achieve can basically be done with a bunch of timers/triggers/scripts that I understand.

Killcannon
Posts: 72
Joined: Sun Apr 12, 2015 2:57 pm

Re: Ask a simple question, get a simple answer

Post by Killcannon » Fri Jan 25, 2019 2:22 pm

Pompidom wrote:
Wed Jan 23, 2019 12:11 pm

But I have absolutely no idea how to do that, and my "buffer" health pools is basically a practical solution that simply works and offers protection against user stupidity at the same time.
Offering multiple playthroughs at the same time with different experiences and different endings.

Everything I want to achieve can basically be done with a bunch of timers/triggers/scripts that I understand.
One way to do this is to use a Boss entity, a counter, and then a script to 'increase' the counter when the player attacks an NPC and 'decrease' when they help via some means. You'll need to place a monster in some part of the map where the players can't reach as a 'token' and have set it's hp to the value you want for the players 'reputation' with the NPC's.

Here's some Sample code from one of my boss events modded a bit to fit what you're looking at doing.

Code: Select all


function NPCReputation()
	if Reputation_counter_1.counter:getValue() == 0 then
		Reputation_Monster.monster:setHealth(1000)
		human_knight_4.basicattack:disable()
	elseif Reputation_counter_1.counter:getValue() == 1 then
		Reputation_Monster.monster:setHealth(800)
	elseif Reputation_counter_1.counter:getValue() == 2 then
		Reputation_Monster.monster:setHealth(600)
	elseif Reputation_counter_1.counter:getValue() == 3 then
		Reputation_Monster.monster:setHealth(400)
	elseif Reputation_counter_1.counter:getValue() == 4 then
		Reputation_Monster.monster:setHealth(200)		
	elseif Reputation_counter_1.counter:getValue() == 5 then
		Reputation_Monster.monster:setHealth(0)
		ReputationMonsterboss.bossfight:deactivate()
		Reputation_Monster.monster:die(true)
		human_knight_4.basicattack:enable()
	end
end

How this works is that whenever the counter is triggered it counts up or counts down, setting the bosses hp to a specified amount. Once the bosses hp reaches 0 it kills the monster and ends the boss fight. For your purposes you'd want to add in a list of NPC's to enable their attack. You could even go as far as having specific NPCs become 'aggressive' at specific levels.

This is crude and ugly I know, and I'm sure the better coders here would have far better solutions; but this would work for what you need. Do note that while active the player will have a 'boss bar' at the top of the screen; and I'm not sure if this would reset if the player leaves the map with the party.

-edit-

As a secondary thought you may want to also include in the script a bit of a time saving technique. By using find_entity for your NPC's so you don't have to call them individually and just can call the group.

Code: Select all


	for i = 1, X do
		local NPC_Group = findEntity("NPC_"..i)

For this X = the last number of your NPC entities. So if you have 20 'NPC's' X would equal 20. Also you'll want to put NPC_ in front of the ID for every NPC on the map.

Zo Kath Ra
Posts: 682
Joined: Sat Apr 21, 2012 9:57 am
Location: Germany

Re: Ask a simple question, get a simple answer

Post by Zo Kath Ra » Sat Jan 26, 2019 1:28 am

Timer:
timerInterval = 5
triggerOnStart = true
currentLevelOnly = true

The timer is connected to a script that prints "test".

It should print "test" as soon as the game starts, but the first print happens after 5 seconds.
What am I doing wrong?

Post Reply