Larian Banner: Baldur's Gate Patch 9
Previous Thread
Next Thread
Print Thread
Joined: Oct 2017
Location: NH, USA
R
apprentice
OP Offline
apprentice
R
Joined: Oct 2017
Location: NH, USA
Hi guys,

name says it all. I would like to bring up a custom encounter where the players have to run (or duck and cover off to the side) a giant boulder rolling down a narrow hallway.

I think just starting up a turn order, adding in the boulder and consuming AP for movement should be fine, but I'm not quite sure how to implement it. All the stuff I see is about characters, and not items (which it is currently in my level).

Any advice would be much appreciated. Thanks.


Projects: Tomb of Horrors: Tomb of Horrors
Joined: Oct 2017
Location: NH, USA
R
apprentice
OP Offline
apprentice
R
Joined: Oct 2017
Location: NH, USA
UPDATE: This is what I have so far. Maybe someone knows a little more about scripting behaviours than I do, and can help with the final touches.

I have done a poor man's solution, of create new character template from the Spider, and changed the visual resource ID to that of a nice, hefty boulder item I picked out (I am fond of the slate ones - they look like death incarnate barreling towards you). However, as it still has the Spider AI, the boulder goes on a carnivorous rampage (funny in it's own right) but not what I would like for the level.

I was thinking of setting it on a predefined Spline patrol once a trigger is activated, and then set it offstage once it gets to the 'bottom' of the slope (another trigger), but two major things I still don't know how to work out:
1) I'd like it to start up combat turn order so players can try stuff, and
2) Collision detection on a character for damage

Any advice would be very welcome. Thanks in advance


Projects: Tomb of Horrors: Tomb of Horrors
Joined: Mar 2016
Location: Belgium
T
addict
Offline
addict
T
Joined: Mar 2016
Location: Belgium
First of all, both items and characters can join combat, so there is no inherent need to turn your boulder into a character. On the other hand, I'm not sure if items can move along splines, so if you want to do that, you indeed need a character.

There is one property that determines whether or not a character/item joins in the turn-based order of characters: the CanJoinCombat property. You can enable this in the side bar, and also change it from Osiris and behaviour script (search for SetCanJoinCombat on the latter page).

Making an item or character actually do something during combat should be done as much as possible in behaviour scripts (different link than the previous one). In a behaviour script, if you mark a REACTION as "USAGE COMBAT", it will only become active once the object is inside a combat. Anything you do inside that reaction, such as moving, will only happen during your turn in combat (as long as you joined the combat, see above; if you don't join combats, you keep acting in real time), and it will correctly consume action points.

The reactions that tell the AI to handle the object have a very low priority, so simply set your reaction's priority to 1000, and it will take priority over the default behaviour.

Checking whether anyone is near (within a certain range) from behaviour script can be done using the CharacterGet() query, which you can use as a CHECK condition for a reaction with an even higher priority than the one that moves your boulder, so that if the CharacterGet finds something, this attack reaction will execute instead). Next, finding everyone that is within a certain radius (rather than only the nearest character) can be done by calling IterateCharactersNear() from that reaction.

One thing to keep in mind: moving characters always use path finding, and you cannot disable this. That means if someone puts a barrel in the way of the boulder, the boulder will walk/roll around it (unless you also have a reaction with an ItemGet() CHECK that moves away/destroys items).

Joined: Oct 2017
Location: NH, USA
R
apprentice
OP Offline
apprentice
R
Joined: Oct 2017
Location: NH, USA
Thanks again Tinkerer. Let me buy you a drink sometime. This encounter is shaping up to be memorable.


Projects: Tomb of Horrors: Tomb of Horrors
Joined: Mar 2016
Location: Belgium
T
addict
Offline
addict
T
Joined: Mar 2016
Location: Belgium
You're welcome!

Joined: Jun 2014
veteran
Offline
veteran
Joined: Jun 2014
We want to see a video!

Joined: Oct 2017
Location: NH, USA
R
apprentice
OP Offline
apprentice
R
Joined: Oct 2017
Location: NH, USA
It's on my to-do list - I'm trying to get the main guts of my campaign together before I finish making that boulder. All in good time.



Projects: Tomb of Horrors: Tomb of Horrors
Joined: Oct 2017
Location: NH, USA
R
apprentice
OP Offline
apprentice
R
Joined: Oct 2017
Location: NH, USA
Hey all, this is long overdue, but here is my attempt at the .itemScript that I'll be attaching to the boulder, and then when I test it and it's squeaky clean, I'll post a video of it. The code may be infested with bugs (Like an itemScript with a CharacterAttack call).

Code
 
INIT
	ITEM:__Me
	EXTERN TRIGGER:S_BoulderMoveTowardsLocation	
	
	// Goal: If player found within range of 10, chase him. If item is blocking within range of 6, take priority and destroy it.
	//			If nobody in range, continue moving forward

BEHAVIOUR
REACTION BoulderChaseNotBlocked,2000
USAGE COMBAT
CHECK "(c1$!c2)" // if not blocked by items/pathing; c1=getclosestplayer, c2 = potential item in way
	CharacterGet(_ClosestChar, __Me, 10.0, Lowest, Distance)
	IsEqual(_ClosestChar, null)
ACTIONS
	CharacterAttack(_ClosestChar,1)

REACTION BoulderChaseBlocked,3000
USAGE COMBAT
VARS
	ITEM:_ClosestItem
CHECK "(c1&!c2)" // if not blocked by items/pathing; c1=getclosestplayer, c1 = item in way
	ItemGet(_ClosestItem, __Me, 6.0, Lowest, Distance)
	IsEqual(_ClosestItem, null)
ACTIONS
	CharacterMoveTo(_ClosestItem)
	ItemDestroy(_ClosestItem)
	CharacterUseActionPoints(__Me, 2)
	
REACTION BoulderChaseNobodyFound,1000
USAGE COMBAT
VARS
	ITEM:_ClosestItem
	CHARACTER:_ClosestChar
CHECK "(c1&c2&c3&c4)" // if not blocked by items/pathing; c1=getclosestplayer, c2 = item in way
	CharacterGet(_ClosestChar, __Me, 10.0, Lowest, Distance)
	IsEqual(_ClosestChar, null)
	ItemGet(_ClosestItem, __Me, 10.0, Lowest, Distance)
	IsEqual(_ClosestItem, null)
ACTIONS
	CharacterMoveTo(S_BoulderMoveTowardsLocation)
INTERRUPT
ON
    OnMovementFailed(_)
ACTIONS
    DelayReaction("BoulderChaseNobodyFound", 0.25)
 

Last edited by RestingLichFace; 26/01/18 09:42 PM.

Projects: Tomb of Horrors: Tomb of Horrors
Joined: Oct 2017
Location: NH, USA
R
apprentice
OP Offline
apprentice
R
Joined: Oct 2017
Location: NH, USA
Extra thicc sexy boulder, ready to roll
[Linked Image]


Projects: Tomb of Horrors: Tomb of Horrors
Joined: Nov 2017
L
member
Offline
member
L
Joined: Nov 2017
You seem to be well on your way, but you may risk Destroying items that aren't normally intended to be destroyed - e.g. the player may accidentally leave a teleport pyramid lying around, a crucial lever may cease to exist, et cetera.
ItemGetStat with Vitality should help you distinguish those things that have HP from those things that don't.


Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.5