Jump to content
The Dark Mod Forums

Extra triggers


VanishedOne
 Share

Recommended Posts

After writing a script to trigger 'spontaneous chit-chat' between AI in my w.i.p. mission I thought it would be nice to have something more convenient and portable.

 

trigger_sequencer triggers a successively different target each time it's triggered; trigger_random triggers one of its targets randomly when triggered. I've done some basic testing but no heavy usage, so please keep an eye out for bugs and let me know if you find any. Defs go in /def/whatever.def, scripts go in /script/tdm_custom_scripts.script (or better still #include them).

 

If you have similar things, or ideas for ones that could be useful, share them here! :smile:

 

trigger_sequencer

 

 

entityDef trigger_sequencer {
	"editor_color"					"1 0 0"
	"editor_displayFolder"			"Triggers"
	"editor_mins"					"-8 -8 -8"
	"editor_maxs"					"8 8 8"
	"inherit"						"atdm:entity_base"
	"scriptobject"					"sequencer"
	"spawnclass"					"idTarget"
	"loop"							"0"
	"editor_usage"					"Triggers target 0 when first activated, target 1 when next activated, etc."
	"editor_bool loop"				"Whether to start over after triggering the last target."
}
object sequencer {
    
    void init();
    void TriggerNextInSequence(entity me, float threadnum);
    
    float loop;
    float next;
    float last;
};


void sequencer::init() {
    ResponseAdd(STIM_TRIGGER);
    ResponseSetAction(STIM_TRIGGER,"TriggerNextInSequence");
    ResponseEnable(STIM_TRIGGER,1);
    
    loop = getFloatKey("loop");
    next = -1;
    last = numTargets() -1;

    if (last >= 0) next = 0;
}

void sequencer::TriggerNextInSequence(entity me, float threadnum) {
    if (next < 0) return;
    
    entity targetEntity = getTarget(next);
    sys.trigger(targetEntity);
    
    if (next == last) {
        if (!loop) next = -1;
        else next = 0;
    }
    else next++;
}

 

 

 

trigger_random

 

 

entityDef trigger_random {
	"editor_color"					"0 1 0"
	"editor_displayFolder"			"Triggers"
	"editor_mins"					"-8 -8 -8"
	"editor_maxs"					"8 8 8"
	"inherit"						"atdm:entity_base"
	"scriptobject"					"trigger_random"
	"spawnclass"					"idTarget"
	"chance_none"					"0"
	"editor_usage"					"When triggered, triggers one of its targets randomly with evenly weighted probability. (For weighted probability use S/R instead.)"
	"editor_bool chance_none"		"If 1, there is a chance no target will be triggered."
}
object trigger_random {
    void init();
    void TriggerRandomly(entity me, float threadnum);
    
    float targets;
    float chance_none;
};

void trigger_random::init() {
    ResponseAdd(STIM_TRIGGER);
    ResponseSetAction(STIM_TRIGGER,"TriggerRandomly");
    ResponseEnable(STIM_TRIGGER,1);
    
    chance_none = getFloatKey("chance_none");

    targets = numTargets();
}

void trigger_random::TriggerRandomly(entity me, float threadnum) {
    if (targets < 1) return;
    entity targetEntity;
    targetEntity = getTarget(sys.floor(sys.random(targets + chance_none)));
    if (targetEntity) sys.trigger(targetEntity);
}

 

 

Edited by VanishedOne
  • Like 3

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

So with trigger random you initiate the chit chat by randomly triggering one conversation partner to start and with the trigger sequencer you target the next possible conversation partner in the room?

"Einen giftigen Trank aus Kräutern und Wurzeln für die närrischen Städter wollen wir brauen." - Text aus einem verlassenen Heidenlager

Link to comment
Share on other sites

For 'chit-chat' what I have in mind is that you'd use the conversation system as normal: you make n conversations and n atdm:target_startconversation entities. Then you target your trigger_random or trigger_sequencer at the atdm:target_startconversation entities, and you trigger it with a trigger_timer or something. So if you have four conversations and you want to play a random one every so often, your set-up looks like this:

 

trigger_timer -> trigger_random -> [ atdm_target_startconversation_1, atdm_target_startconversation_2, atdm_target_startconversation_3, atdm_target_startconversation_4 ]

 

Edit: reading over what you said again, it occurs to me that you could set up randomly branching dialogue by having a conversation make one AI speak, then having it call ActivateTarget on a trigger_random which randomly selects another conversation to make another AI speak, etc.

Edited by VanishedOne

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

  • 1 year later...

Here's something I realised I hadn't made available yet:

 

entityDef trigger_inactivity {
	"editor_color"					"0 0 1"
	"editor_displayFolder"			"Triggers"
	"editor_mins"					"-8 -8 -8"
	"editor_maxs"					"8 8 8"
	"inherit"						"atdm:entity_base"
	"scriptobject"					"trigger_inactivity"
	"spawnclass"					"idTarget"
	"delay"							"10"
	"triggerOnStartTimer"			"0"
	"editor_usage"					"Once triggered, activates its targets if <delay> seconds pass in which it is NOT triggered again."
	"editor_float delay"			"Period during which the countdown to activating its targets can be reset by triggering this entity."
	"editor_bool triggerOnStartTimer"	"Whether to activate targets when the timer starts as well as when it reaches zero. (Use for e.g. toggling lights on and off.)"
object trigger_inactivity {
	
	void init();
	void countdown(entity me, float threadnum);
	
	float timer;
	float delay;
	boolean triggerOnStartTimer;
};

void trigger_inactivity::init() {
	ResponseAdd(STIM_TRIGGER);
	ResponseSetAction(STIM_TRIGGER,"countdown");
	ResponseEnable(STIM_TRIGGER,1);
	
	timer = 0;
	delay = getFloatKey("delay");
	triggerOnStartTimer = getBoolKey("triggerOnStartTimer");
}

void trigger_inactivity::countdown(entity me, float threadnum) {
	if (timer > 0) timer = delay;
	else {
		if (triggerOnStartTimer) activateTargets(self);
		timer = delay;
		while (timer > 0) {
			sys.wait(1);
			timer--;
		}
		activateTargets(self);
	}
}

 



You can use this for e.g. the kind of alarm system seen in Calendra's Cistern and one or two other Thief FMs, where a guard presses a button as part of his patrol route, and an alarm goes off if a certain length of time passes without the button being pressed.

 

I made it when setting up Lost City-style lights that are on for as long as the player or an AI is in the room. They don't work quite as intended: the player will activate a trigger_multiple just by being within its volume, but my experiments with setting "anyTouch" "1" on the trigger brush suggested that this lets AI activate it... but not while standing still. (There's probably a way to make a comprehensive motion detector using trigger_touch and a script, but whether it would be good for performance is another matter.)

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

Nice...
Have you thought about a motion-detector system that uses something similar to ping?

As in - if player hears the noise, then they are detected..?

The problem I've been running into is ANY movement causes a reaction if "ping/sound" is constant (delay=0) <--- hope that isn't a smiley
and it'd be nice to have the player / anyone have to "creep walk" in order to evade alarm / detection / silent "turrets of unseen-archer death".

Idk how to do that... Can't figure it out.

Atm, it's a case of playing, "what's the time mr. wolf" and only moving when, eg, a light is blinking, and timing the light or a mover/rotate (eg, "camera") to "see" when the delay is "on"... (which is kinda boring game play, but it works ok for camera w/turret or alarm AND the camera seems to be able to "see" outside of an FOV - idk how to set that..., it's literally only "on" when it's facing the corridor and "off" when it's not, turns on/off as player hits trigger once as pass through doorway it "guards".)

ugh, I wish I could explain myself better...

Anyway - thanks for the script - I can't click it because I've reached my quota.

Edited by teh_saccade
Link to comment
Share on other sites

There actually is a 'ping' stim in Thief, but it's for proximity. Offhand I don't know of a way to detect sounds made by the player, other than using an AI. (I wonder whether STIM_SOUND was intended to allow Responses to propogated sounds...)

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

That's the ping I was thinking of. Cool. You know it. Idk it was in TDM.

Only one way to find out about the sound - because that could be controlled easily using visportals or "tunnels" that bypass portals or whatever...
It'd mean that running is gonna set off the motion detector (due to noise) but creeping wouldn't, because it's quiet :)

Have to play with the stim_sound thing sometime, because it would be a good way to set up sound/motion detection devices, rather than have to use some silent AI that pushes a button, hidden behind a bunch of wall with a tiny hole in it so they can "hear"...

Edited by teh_saccade
Link to comment
Share on other sites

There isn't a ping stim in stock TDM, but mappers can add custom stims.

 

I don't know how/whether STIM_SOUND does work, not having got around to trying it; if it's like STIM_LIGHT it might need to be specially set on stimming entities. Good luck testing it.

  • Like 1

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

  • 1 month later...

In the immortal words of Simon the Sorcerer, "that doesn't work"... :`(

I'm using a room with a tiny gap (as in my soundpipe level, the maze with the sound coming from the opposite side of the object due to void tunnels - it had 2 downloads so someone must've dmapped it and had a look...) where a soundless AI is there to immediately throw a switch - it works as a "motion detector" in that the guy will hear the player and throw the switch as a result of alarm.

The other way I have found to do, using a rotating camera model (atm a block with a cylinder) it is to have a room set up with a "scrying mirror" - idk how to explain that... with a guy who is sitting in front of it, who also pushes a button on seeing the player, even though he is a billion miles away, in a small room outside of the level.

I guess the best way to explain that is with an old video - I'll find it:

https://www.youtube.com/watch?v=sJEBRrzpiCM

The camera doesn't actually see anything, it is merely a prop - the room in which the guard's mini-hidden room is actually moving in the background in relation to the orientation of the camera, so he sees the correct direction of the camera and not anything else.


Edited by teh_saccade
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recent Status Updates

    • jaxa

      Embracer Group is Buying Square Enix Montréal, Eidos, and Crystal Dynamics for “Only” 300 Million USD: https://wccftech.com/embracer-group-square-enix-montreal-eidos-crystal-dynamics/
      · 1 reply
    • duzenko

      Do we want fur in TDM? Like https://duzenko.github.io/webgl/
      · 6 replies
    • Epifire

      Sometimes life throws a curveball - other times it straight up tries to take you outta the game. Been one thing after another lately but I ain't goin without a fight!
      · 2 replies
    • duzenko

      My Uber rating (as a passenger) is 4.71. Is there still hope or should I just kill myself? What's yours?
      · 3 replies
    • kano

      Did I mention how absolutely grateful I am that TDM didn't get (and can never be) assimilated by a huge company like Microsoft, as is what happened to Minecraft?
      · 3 replies
×
×
  • Create New...