Jump to content

Can normal entities affect currently running scripts?


Recommended Posts

I'm trying to create a script which would wait for an input from normal entities (like func_door or anything with „target” parameter). I know that most scripts rely on something completely different – entities are adressing target_scriptrunner to start a script, script does what it does and it ends. The only input from standard entity in that scenario works as a starter, not as a variable somewhere in the middle of a script. In my case, I have a misc_turretg2 which can fire „target” after exploding and I want that event to be registered by script and counted. I know that I can approach that problem from different angle and not use scripts at all, but I want to reduce my entity count (multiple turrets, part of something bigger which would be optimised by scripts too).

 

I've tried using parm key and it didn't work. I made an additional script, which would be fired by entity only to do one thing - raise parm value of that entity. My main script had an „If” which would check value of that parm in a loop, waiting for correct value. The problem was that using „affect” on same entity in two different scripts would result in stopping my loop. Therefore, parm had a correct value, but main script wouldn't register that, because it was stopped earlier.

 

Icarus is poorly documented, so I would be grateful for any help or any examples of similar scripts. I can provide additional info or quote my scripts here, but this is a very broad question and exceeds way beyond that example.

 

Tl;dr: Can normal entities affect currently running scripts?

Link to comment

Yeah..... There's a lot of bad info regarding icarus out there. I don't have the time to give you a full reply right now, but I don't think you can use parms for counting in this instance, since the turret should respawn on death and I'm pretty sure that resets all the parms. Could be wrong on that. Not sure since I never really played with turrets. If they don't reset on death, this will be mega easy to do.

At the very least, i can tell you that you can increment and decrement global variables, just not parms - so that might help a bit. Could you be a little more specific about what exactly you're trying to do, though? There's several ways to go about this, and I don't want to go off on a long rabbit trail in the wrong direction.

Link to comment

Parm count stays even after turret is destroyed. I would have to reset it anyway, but I wanted to answer your question.

I'll try to explain what we're dealing here with, if that would help. I have a room with 4 turrets. Each turret is deactivated and hidden behind func_door shutter. After activating trigger by "use" key, player will start one of 4 different scenarios. Each scenario differs in amount of turrets that would activate - option number 3 activates 3 turrets, option number 1 activates only 1 turret, etc. Upon activation, shutters will move, revealing turrets to a player, and activating those turrets. Turrets have to be defeated by saber deflect. When dying, turrets sends a signal to it's shutter, which closes. Signal also leads to another func_door entity, which deactivates turret and lets it respawn silently. After defeating all turrets activated by selected program, AND gate is set true and it opens a door leading out of that room. After leaving the room, whole thing resets and another player can face the challenge.

Since I have a lot of combinations here (4 different programs and non specified order in which turrets can be destroyed), I had tu build AND gate manually. I made a slide with trigger on one end and npc spawner in the other. On that slide I put 4 different func_door, acting as barriers. When you activate i.e. program number 2, two of those barriers would move, blocking npc from reaching trigger. That provides a way to have multiple signals leading to the AND gate, which would work in every possible order, since NPC has to wait for every barrier to move to reach its target. Gate is being reset by another func_door, which kills npc shortly after reaching the trigger.

As you probably know right now, whole thing generates a lot of entities (80 or so). It's working, but I was trying to achieve something more efficient by using scripts. I need to find a way for my script to register func_door moving or turret dying.

Link to comment

This sounds awesome, actually. I think you can probably get this down to 22-ish entities total...It's probably going to be a long process for me to assist, especially since I'm extremely tired and I can't even run BehavED right now, but I'll give you what I can.

As far as entity reduction goes, none of your desired actions requires a target_scriptrunner. Instead of using those, put a useScript on your trigger_multiples. You only really need target_scriptrunner when you're running the script directly on a player (Like messing with players' parms, changing their height, making them invisible, etc).

For your turrets, since parms are kept between deaths, it sounds like deathScript might work too. It should run the specified script when the entity is destroyed, but not removed from the game. In the script that is run, if you increment a global variable each time a turret dies, it should make detecting turret deaths very easy. (The variable would need declared and initialized to 0 in a setup script, which can be done by adding a spawnScript on your worldspawn.) Incrementing global variables can be done by setting the value to "+1". (This does not work on parms, it is bugged.)

As far as checking whether the turrets are still alive or not, there are several ways to do that....I'm still hashing that out in my head. Keep in mind, though, that there needs to be a client detection mechanism to keep the players from being locked out if someone dies while the turrets are active.

 

So far, is any of this helpful? Or am I off on the wrong track?

Link to comment

Thanks, that's a lot of good info right here. Totally forgot about "usescript" key. I took some time to follow your advice and figured out how to make global variables and use deathScript to affect them. That part seems to be working good, but I failed at everything else. First, I spent hours to discover that affecting turrets with scripts unables them to be deactivated by func_door AFTER using a script. It just won't work, as long as there is a script affecting these turrets still running (even after passing that line of code which was connected to turrets). Next, I tried making a simplest possible trigger deactivator, using scripts, not entities. Failed again - don't know why, but it's not working. It is hard for me to decide if I'm more angry, frustrated, or just disappointed at the state of scripting in general. Too many strange quirks and unexplained dead-ends to call it even slightly useful... It blows my mind that logic gate made of jawas and func_door made more sense than this.

I have a trigger using script posted below. It should affect other triggers, but it does not. Any ideas?

flush (  );

affect ( "turrettrigger1", /*@AFFECT_TYPE*/ FLUSH )
{
	set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
}


affect ( "turrettrigger2", /*@AFFECT_TYPE*/ FLUSH )
{
	set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
}


affect ( "turrettrigger3", /*@AFFECT_TYPE*/ FLUSH )
{
	set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
}


affect ( "turrettrigger4", /*@AFFECT_TYPE*/ FLUSH )
{
	set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
}


 

Link to comment

Affect blocks look for a script_targetname, not a targetname. Make sure you're using the right one.

Also, unless there is more to that script that that loops or waits, you don't need that flush() block at the top. Flushing is only used when you need to stop all existing commands before running new ones.

To help with debugging, type /developer 1 in the console. You'll get a blue line in the console for everything your scripts do.

Yes, scripting truly is a disaster.... The functionality it adds is incredible, but it's very broken in many areas. Fortunately for you, though, I don't think you're using any of the broken stuff for this.

Link to comment

I'm using script_targetname and /developer 1 indeed helps a lot, fortunately I knew that before. I decided to ignore that issue with triggers and I'll use func_doors and geometry to physically separate triggers from players and block them that way. Everything would work right now if not for another issue - I wanted to use one global variable and operate it by adding value to it, step by step. I made a new variable, flagged is as a FLOAT, but for some reason it's ignoring math operators. Is this some kind of a bug, or am I doing something horribly wrong?

definition of a variable, used with spawnScript

//Generated by BehavEd

declare ( /*@DECLARE_TYPE*/ FLOAT, "turret1count" );
set ( "turret1count", $0$ );


script used after deathScript, should add +1 to global variable

//Generated by BehavEd

set ( "turret1count", $+1$ );

 


 

Link to comment

No, it looks like you're doing everything right...I would definitely verify that the deathScript on the turret is working, though. I've never used turret entities before so I have no idea how they work.

I can't tell much further without seeing the map, though, sorry. I don't mind taking a peek at it if you're up for it, but it will take me a day or two to do so.


Since this is undocumented territory - as a point of reference for incrementing variables, here's an old script I did for Taspir Power Complex V3 that runs when the map is loaded, continuously incrementing two timer variables for nefarious purposes:

Spoiler



//Generated by BehavEd

rem ( "This sets a timer and keeps it counting so that the game will know when new players have joined." );
declare ( /*@DECLARE_TYPE*/ FLOAT, "timer" );
declare ( /*@DECLARE_TYPE*/ FLOAT, "timer2" );
wait ( 1000.000 );
set ( "timer", "0" );
set ( "timer2", "25" );

loop ( -1 )
{
	use ( "DEFAULT" );
	use ( "DEFAULT" );
	wait ( 1000.000 );
	set ( "timer", "+1" );
	set ( "timer2", "+1" );
	use ( "DEFAULT" );
}

The use "DEFAULT" blocks are there for padding, because there is a loop rearrangement bug and without them things got out of order.

 

mjt likes this
Link to comment

I've used your script as a template and I've created very simple worldspawn timer, which would play a sound after each 15 seconds. By doing so I discovered that the source of my problems was the mod I was using. It seems that OJP for some reason won't recognise operators and treats "+1" just like "1". On basejka my counter worked flawlessly. Duh. It's disappointing, but I cannot change that without messing with source code of said modification, which would be an overkill at that point.

I had to find a clever alternative to initial idea and so I did. Instead of using one global variable, I had to use four, acting as a 0-1 switches, for each turret. Without the ability to sum values on one variable, I made a whole structure of IFs and ELSEs. Here is the code, for future readers:

 

//Generated by BehavEd

loop ( -1 )
{

	if ( $get( FLOAT, "turret1count")$, $=$, $1$ )
	{

		if ( $get( FLOAT, "turret2count")$, $=$, $1$ )
		{

			if ( $get( FLOAT, "turret3count")$, $=$, $1$ )
			{

				if ( $get( FLOAT, "turret4count")$, $=$, $1$ )
				{

					affect ( "turret1", /*@AFFECT_TYPE*/ INSERT )
					{
						set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
					}


					affect ( "turret2", /*@AFFECT_TYPE*/ INSERT )
					{
						set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
					}


					affect ( "turret3", /*@AFFECT_TYPE*/ INSERT )
					{
						set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
					}


					affect ( "turret4", /*@AFFECT_TYPE*/ INSERT )
					{
						set ( /*@SET_TYPES*/ "SET_INACTIVE", "true" );
					}

					set ( "turret1count", "0" );
					set ( "turret2count", "0" );
					set ( "turret3count", "0" );
					set ( "turret4count", "0" );
				}


				else (  )
				{
					wait ( 3000.000 );
					signal ( "endoftheloop" );
				}

			}


			else (  )
			{
				wait ( 3000.000 );
				signal ( "endoftheloop" );
			}

		}


		else (  )
		{
			wait ( 3000.000 );
			signal ( "endoftheloop" );
		}

	}


	else (  )
	{
		wait ( 3000.000 );
		signal ( "endoftheloop" );
	}

	waitsignal ( "endoftheloop" );
}

It works in every possible order in which you disable turrets. When all four turrets are destroyed, script deactivates them and resets all variables back to 0. I've also added some "signal" and "waitsignal" lines for loop to end when everything is done.

Thanks again NAB622 for your help. I've learned a few new aspects of coding during that little quest, that's for sure.

mjt likes this
Link to comment

 

52 minutes ago, kwenga said:

It seems that OJP for some reason won't recognise operators and treats "+1" just like "1". On basejka my counter worked flawlessly.

Ouch, I did not know that. Thanks for the info! Glad everything's working.

So the loop doesn't rearrange the first and last blocks on you? I had tons of issues with that years ago.

Link to comment
On 11/3/2020 at 8:34 PM, NAB622 said:

So the loop doesn't rearrange the first and last blocks on you? I had tons of issues with that years ago.

I've never had that problem until today. I wanted to save another 4 entities by deleting redundant target_scriptrunners and using "useScript" key instead. I had a simple script moving objects between ref tags, in specified order and with precise time intervals. For some reason, using "useScript" instead of target_scriptrunner messed up the order in which object had been moving prieviously. It is as you said, loop has somehow rearranged blocks here and there, for example moving "wait" line several blocks ahead, creating longer pause between moves and then speeding up other motions. Then, just to be sure I didn't do anything to my script or my ref tags, I placed target_scriptrunner once more and deleted "useScript" key from my entity. After that, whole thing works again, without any of previously mentioned issues.

tl;dr target_scriptrunner ftw, "useScript" might be broken in some specific cases. Be aware of that issue and use target_scriptrunner when designing your scripts, swap for "useScript" at the end, when you're sure that everything works correctly.

Link to comment

Ah, also very good to know. The only bug I was aware of was the loop rearrangement. Thanks for seeing it through and posting back, I'm learning from this.

You can save all the ref_tag entities by using move blocks, by the way. You can move any func_ entity to arbitrary coordinates at will.

Link to comment
11 minutes ago, NAB622 said:

You can save all the ref_tag entities by using move blocks, by the way. You can move any func_ entity to arbitrary coordinates at will.

Ref_tags are not counted towards entity limit AFAIK. At least they don't show up when using /entitylist command, so it shouldn't be a problem using them instead of vectors. It's easier to rearrange stuff when using visible entities in the editor, instead of changing numbers in script everytime. ?

Link to comment

If ref_tags don't count, then yeah, there's no entity advantage. 

There are two tiny editing advantages, though - ifyou use the script to move it, you only have to recompile the script (Not the map) when you make a change. This can help on very large maps. Second, if you do not use an origin brush on your mover, the coordinates are essentially relative to the starting point of the entity - meaning you can make a single script to use across many entities (Just don't rotate it or stuff will go crazy, since there's no origin). I don't think either of these apply to what you're doing, I'm just throwing them out there in case they're useful to you or someone in the future. You've obviously made great progress, and I'd love to see the finished product.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...