ACS function: CheckActorInSector(tag, tid)

Post a reply

Smilies
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :geek: :ugeek: :!: :?: :idea: :arrow: :| :mrgreen: :3: :wub: >:( :blergh:
View more smilies

BBCode is OFF
Smilies are ON

Topic review
   

Expand view Topic review: ACS function: CheckActorInSector(tag, tid)

Re: ACS function: CheckActorInSector(tag, tid)

by ibm5155 » Sat Feb 01, 2014 3:53 pm

While I was trying to find a way to get a way to get a ceiling position from random places (I still not found) ;---;

So I saw the problem, So I did a rainfall script for zandronum, I wanted it to be as generic as pocible (Like you only call it and the scripts do the rest of the work :D)
It actually worked quite well, I can see the rainfall even if I'm inside a building, the rainfall doesn't summon inside 3D floors where the higher ceiling has a f_sky,...
But it's still not perfect '-'

I hope this code'll help with something :)

Code: Select all

int weather_quality=0;

script 47 (void) clientside{//Rainfall script
	int X_SPOT=0, Y_SPOT=0, X_MIN=0, X_MAX=0, Y_MIN=0, Y_MAX=0, VAR_SPOT=250.0;
	int z_heigh,y_heigh, x_heigh;
	int a=0,b=0,c=0;
	int MAX2;
	int tid=122;
	int x, y, z ;
	int tid2=unusedTID(1000,2000);
	int player_tid2;
	if(rain_sound==1)thing_activate(144);
	while(true){
   player_tid2=consoleplayernumber()+PLAYER_TID;
		a=getactorx(player_tid2);//getactorx(ConsolePlayerNumber());
		b=getactory(player_tid2);//getactory(ConsolePlayerNumber());
		c=getactorz(player_tid2);//getactorz(ConsolePlayerNumber());
   if(weather_quality==-1)      {X_MIN=-250.0; X_MAX=250.0; Y_MIN=-500.0; Y_MAX=250.0; VAR_SPOT=250.0;}  
		else if(weather_quality==0)      {X_MIN=-1000.0; X_MAX=1000.0; Y_MIN=-1000.0; Y_MAX=1000.0; VAR_SPOT=500.0;}
		else if(weather_quality==1) {X_MIN=-2000.0; X_MAX=2000.0; Y_MIN=-2000.0; Y_MAX=2000.0; VAR_SPOT=500.0;}
		else if(weather_quality==2) {X_MIN=-2500.0; X_MAX=2500.0; Y_MIN=-2500.0; Y_MAX=2500.0; VAR_SPOT=500.0;}
		else if(weather_quality==3) {X_MIN=-3000.0; X_MAX=3000.0; Y_MIN=-3000.0; Y_MAX=3000.0; VAR_SPOT=500.0;}
		else if(weather_quality==4) {X_MIN=-3500.0; X_MAX=3500.0; Y_MIN=-3500.0; Y_MAX=3500.0; VAR_SPOT=300.0;}
		X_SPOT=X_MIN; Y_SPOT=Y_MIN;
		while(Y_SPOT<=Y_MAX){
			while(X_SPOT<=X_MAX){
				x_heigh=random(a+X_SPOT,a+X_SPOT+VAR_SPOT); y_heigh=random(b+Y_SPOT,b+Y_SPOT+VAR_SPOT);
				z_heigh=GetActorCeilingZ(PLAYER_TID + PlayerNumber())-16.0;
				spawn("mapspot",x_heigh,y_heigh,z_heigh  ,tid,0);
				if (thingcount(t_none,tid)==0){ 
					spawn("mapspot",x_heigh,y_heigh,c+10.0  ,tid,0);
					if(thingcount(t_none,tid)==0){
						spawn("mapspot",x_heigh,y_heigh,GetSectorCeilingZ(0,x_heigh /1.0,y_heigh /1.0)-20.0,tid,0);
						if(thingcount(t_none,tid)==0){ 
							spawn("mapspot",x_heigh,y_heigh,c+74.0  ,tid,0);
								if(thingcount(t_none,tid)==0) spawn("mapspot",x_heigh,y_heigh,c+274.0  ,tid,0);
				}	}	}
				if (CheckActorCeilingTexture(tid, "F_SKY1")){    
					z_heigh=GetHigherCeiling(tid)-16.0;
					thing_remove(tid);
					spawn("mapspot",x_heigh,y_heigh,z_heigh,tid,0);
					if(rain_detail==0)spawnspot("raindrop",tid,0,0);
					else if(rain_detail==1)spawnspot("raindrop2",tid,0,0);
					else spawnspot("raindrop3",tid,0,0);
				}
				X_SPOT+=VAR_SPOT;
				thing_remove(tid);
      if(weather_quality==-1) delay(1);
			}
			X_SPOT=X_MIN;
			Y_SPOT+=VAR_SPOT;
		}
		delay(1);
	}
}

function int GetHigherCeiling(int tid2) {//THIS PART WAS CREATED BY Ijon Tichy and edited  by IBM5155
   int posx=getactorx(tid2);
    int posy=getactory(tid2);
    int posz=GetActorCeilingZ(tid2);//504
    int z=posz+25.0;
    int test=0;
    int tid=unusedTID(1000, 2000);
    spawn("mapspot",posx,posy,z,tid,0);
    while(GetActorCeilingZ(tid)!=0){
        z=z+25.0;//850.0
        thing_remove(tid);
        spawn("mapspot",posx,posy,z,tid,0);
        test++;
    }if(test==0){
        thing_remove(tid);
        z=posz;
    }else{
        thing_remove(tid);
        spawn("mapspot",posx,posy,z-27.0,tid,0);
        z=GetActorCeilingZ(tid);
        thing_remove(tid);
    }return z;
}

function int secret_in(int position){
    return secret[position];
}

function int unusedTID(int start, int end)//THIS PART WAS CREATED BY Ijon Tichy
{
    int ret = start - 1;
    int tidNum;
    if (start > end) { start ^= end; end ^= start; start ^= end; }
	while(ThingCount(0,ret++)!=0);
	return ret-1; 
}
Decorate part

Code: Select all

actor TOP_SKY{
    //$Category Ibm Stuff
	+NOINTERACTION
	+CEILINGHUGGER
    Radius 0
    Height 0
	States
	{
	Spawn: 
		IBWA A 12 A_SpawnItemEx("Raindrop3", random(-128, 128), random(-128, 128), random(-128, 128), 0, 0, 0, 0, 0, 0)
		Stop
	}
}
actor HeightIndicator
{
    //$Category Ibm Stuff
    +NOINTERACTION
    Radius 0
    Height 0
}

Actor ExplosionParticle2
{
  //$Category Ibm Stuff
Height 0
Radius 0
Mass 0
+Missile
+NoBlockMap
//+NoGravity
+DontSplash
+FORCEXYBILLBOARD
+CLIENTSIDEONLY
+THRUACTORS
RenderStyle Add
Scale 0.04
Speed 6
States
{
Spawn:
SPAK AAAAAAAAAAAAAAAAAAAAAAAA 1  A_FadeOut(0.02)
Stop
}
}

Actor Raindrop3HQ
 {
    //$Category Ibm Stuff
	+MISSILE
	+CLIENTSIDEONLY
	+SPAWNCEILING
	+ALLOWPARTICLES
	+DONTSPLASH
	DeathSound"IBRN"
	scale 0.1
	Height 0
	Alpha 0.6
 	States
	{
	Spawn: 
		IBWA A 9 A_JumpIf(waterlevel > 0, "Death")
		Loop
	Death:
		RAIN B 1
 		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		RAIN B 1
 		Stop
 	}
}

Actor Raindrop3
 {
    //$Category Ibm Stuff
	+MISSILE
	+CLIENTSIDEONLY
	+SPAWNCEILING
	+ALLOWPARTICLES
	+DONTSPLASH
	scale 0.1
	//Scale 0.9
	Height 0
	Alpha 0.6
 	States
	{
	Spawn: 
		IBWA A 9 A_JumpIf(waterlevel > 0, "Death")
		Loop
	Death:
 		RAIN B 1
 		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		RAIN B 1
 		Stop
 	}
}


Actor Raindrop2HQ
 {
    //$Category Ibm Stuff
	+MISSILE
	+CLIENTSIDEONLY
	+SPAWNCEILING
	+ALLOWPARTICLES
	+DONTSPLASH
	DeathSound"IBRN"
	scale 0.08
	Height 0
 	States
	{
	Spawn: 
		IBWA A 9 A_JumpIf(waterlevel > 0, "Death")
		Loop
	Death:
		RAIN B 1
 		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		RAIN B 1
 		Stop
 	}
}

Actor Raindrop2
 {
    //$Category Ibm Stuff
	+MISSILE
	+CLIENTSIDEONLY
	+SPAWNCEILING
	+ALLOWPARTICLES
	+DONTSPLASH
	scale 0.08
	//Scale 0.9
	Height 0
 	States
	{
	Spawn: 
		IBWA A 9 A_JumpIf(waterlevel > 0, "Death")
		Loop
	Death:
 		RAIN B 1
 		TNT1 A 0 A_CustomMissile ("ExplosionParticle2", 0, 0, random (0, 20), 2, random(0,120))
		RAIN B 1
 		Stop
 	}
}

Actor RaindropHQ
 {
    //$Category Ibm Stuff
	+MISSILE
	+CLIENTSIDEONLY
	+SPAWNCEILING
	+DONTSPLASH
	DeathSound"IBRN"
	Scale 0.9
	Height 0
	Alpha 0.3
 	States
	{
	Spawn: 
		RAIN A 9 A_JumpIf(waterlevel > 0, "Death")
		Loop
	Death:
 		RAIN B 10
 		Stop
 	}
}

and with that you win this :D

For making this guy perfect, I really need that this http://zdoom.org/wiki/GetSectorCeilingZ return a functional value, like there are 3 sectors with tag 0, each one with different ceiling heigh and both with sky, idk why it will only return the value of the higher ceiling and not the sector that I set ex: GetSectorCeilingZ(0,30,30);

EDIT:Actually this code is working really well O_o idk what I touched that it made not rain on sectors with transfer height but...

Re: ACS function: CheckActorInSector(tag, tid)

by StrikerMan780 » Sat Jan 25, 2014 4:32 pm

Xaser wrote:What if he has a room with a skylight and a window? Even barring that, he's going to have to litter the map with a bunch of extra lines anyway, which falls well within the the definition of "laborious things" as far as I'm concerned.

I'd normally say that this function would be a prime candidate for "zero means activator", but the "type" argument monkeywrenches that a bit. Would it be fair to have ThingCountSector(T_NONE, 0, tag) (i.e. zero-type, zero-tid) check for the activator, or would there be some sort of unforeseen consequence (can't imagine any)?

[If so, it's best to open a new thread for this anyway; suggestions in a Closed Feature Suggestions thread are going to get lost.]
Yes, that's a very good idea. So it only ever returns 1, meaning the activator is in the sector of said tag. 0 otherwise.

EDIT: Opened a suggestion thread - http://forum.zdoom.org/viewtopic.php?f=15&t=45154

Re: ACS function: CheckActorInSector(tag, tid)

by Xaser » Sat Jan 25, 2014 4:02 pm

What if he has a room with a skylight and a window? Even barring that, he's going to have to litter the map with a bunch of extra lines anyway, which falls well within the the definition of "laborious things" as far as I'm concerned.

I'd normally say that this function would be a prime candidate for "zero means activator", but the "type" argument monkeywrenches that a bit. Would it be fair to have ThingCountSector(T_NONE, 0, tag) (i.e. zero-type, zero-tid) check for the activator, or would there be some sort of unforeseen consequence (can't imagine any)?

[If so, it's best to open a new thread for this anyway; suggestions in a Closed Feature Suggestions thread are going to get lost.]

Re: ACS function: CheckActorInSector(tag, tid)

by Graf Zahl » Sat Jan 25, 2014 12:59 pm

StrikerMan780 wrote:
Graf Zahl wrote:Of course you are overthinking it, being focussed on this one single idea how to solve the problem.
There's a very simple solution, it just requires a bit of tinkering: Your script that gives the raindrop item to the player should only run when the player is outside the buildings. If it simply doesn't run when inside no rain will spawn in skylights so you should add some script suspend/execute actions to the building entries.
The downside to this, is if someone is point-blank to a window inside the building, they won't see the rain falling outdoors. It causes a bit of a disconnect in the effect.

Of course you need to place your triggers so that for all places where rain should be visible the script must be active.

Re: ACS function: CheckActorInSector(tag, tid)

by StrikerMan780 » Sat Jan 25, 2014 12:01 pm

Graf Zahl wrote:Of course you are overthinking it, being focussed on this one single idea how to solve the problem.
There's a very simple solution, it just requires a bit of tinkering: Your script that gives the raindrop item to the player should only run when the player is outside the buildings. If it simply doesn't run when inside no rain will spawn in skylights so you should add some script suspend/execute actions to the building entries.
The downside to this, is if someone is point-blank to a window inside the building, they won't see the rain falling outdoors. It causes a bit of a disconnect in the effect.

Would be easy to solve if I either had the ability to check the tag, or better yet, the ability to define different Sky textures (which could be universal - Anyone who wishes to make a map for my mod, could have areas with Rain, and without it by placing the specific sky texture where they want it to be, while having an ACS Library handle the rest.)

Re: ACS function: CheckActorInSector(tag, tid)

by Graf Zahl » Sat Jan 25, 2014 11:58 am

Of course you are overthinking it, being focussed on this one single idea how to solve the problem.
There's a very simple solution, it just requires a bit of tinkering: Your script that gives the raindrop item to the player should only run when the player is outside the buildings. If it simply doesn't run when inside no rain will spawn in skylights so you should add some script suspend/execute actions to the building entries.

Re: ACS function: CheckActorInSector(tag, tid)

by StrikerMan780 » Sat Jan 25, 2014 11:30 am

edward850 wrote:I'm not quite sure I follow. If the rain isn't going to come from the sky, where else is it going to come from, and why do you need to check what sector it's in therefore? It almost seems like you are over-thinking this.
Graf Zahl wrote:
edward850 wrote:It almost seems like you are over-thinking this.

Sounds about right. Which, btw, is the case for most 'I absolutely need this, otherwise I have to scrap my mod' suggestions.
No, I'm not over-thinking this. Also, I would appreciate it if someone stopped being condescending. I have map that has both indoor and outdoor areas that contain a sky. (For things like skylights/ceiling windows.) The general outdoors area of the map is tag 25.

A script gives an item to the player every few tics which spawns a few clientside raindrops at the ceiling in a radius around the player with A_SpawnItemEx. The raindrops check if the ceiling is F_SKY1, and if so, don't just disappear. Unfortunately, this makes it so raindrops end up coming through any indoor areas with skylights. Unless, by some means, I have a way to have multiple sky textures, like F_SKYRAIN and F_SKY1... I'm pretty much screwed. Raindrops coming through 3D Floor roofs isn't the problem in this case.
Nash wrote:
That's pretty impressive. Mind if I experiment with this code a bit? (I'll probably need to change it up to support Zan.)

Also, out of curiosity, how'd you get that lens flare working?

Re: ACS function: CheckActorInSector(tag, tid)

by Graf Zahl » Sat Jan 25, 2014 4:26 am

edward850 wrote:It almost seems like you are over-thinking this.

Sounds about right. Which, btw, is the case for most 'I absolutely need this, otherwise I have to scrap my mod' suggestions.

Re: ACS function: CheckActorInSector(tag, tid)

by Nash » Sat Jan 25, 2014 2:43 am

StrikerMan780:

Not sure how you've got your subsystems setup, but all I had to do to make sure rain doesn't spill indoors is by using CheckActorCeilingTexture. It does require a temporary TID to be assigned each tic for a rain drop though. Here's a snippet of the rain portion of my engine:

Code: Select all

#Define SPAWNRAIN_RADIUS 256.0
#Define SPAWNRAIN_HEIGHT 256.0
#Define SPAWNRAIN_RANDOMHEIGHT 16.0
Function void _W_SpawnRain(int tid, int densitymax)
{
    int playertid = TID_PLAYER + tid;
    
    if (!SetActivator(playertid))
    {
        return;
    }

    int x = GetActorX(0),
        y = GetActorY(0),
        z = GetActorZ(0);

    // pointer to player
    int ptr = AAPTR_PLAYER1 << tid;

    // for each rain drop...
    while (densitymax--)
    {
        // randomize offset
        int offsetx = random(-SPAWNRAIN_RADIUS, SPAWNRAIN_RADIUS),
            offsety = random(-SPAWNRAIN_RADIUS, SPAWNRAIN_RADIUS),
            offsetz = SPAWNRAIN_HEIGHT + random(-SPAWNRAIN_RANDOMHEIGHT, SPAWNRAIN_RANDOMHEIGHT);

        // spawn the rain drop and give it a temporary TID for the next step
        if (!Spawn("Z_RainDrop", x + offsetx,
                                 y + offsety,
                                 z + offsetz,
                                 TID_RAINTEMP))
        {
            // failed to spawn rain drop.
            continue;
        }
        
        // rain drop should only be spawned outdoors.
        if (!CheckActorCeilingTexture(TID_RAINTEMP, "F_SKY1"))
        {
            Thing_Remove(TID_RAINTEMP);
            continue;
        }
        
        // we're done with the player, switch the current activator to the rain drop
        SetActivator(TID_RAINTEMP);
        SetUserVariable(0, "user_offsetx", offsetx >> 16);
        SetUserVariable(0, "user_offsety", offsety >> 16);
        SetUserVariable(0, "user_offsetz", offsetz >> 16);
        
        // set pointer
        SetPointer(AAPTR_TRACER, 0, ptr);
        
        // done with everything, clear the TID!
        Thing_ChangeTID(TID_RAINTEMP, 0);
    }
}
 

Code: Select all

Actor Z_Raindrop
{
    Radius 1
    Height 2
    Gravity 1
    Scale 0.075
    XScale 0.05
    YScale 0.15
    RenderStyle Add
    Alpha 0.0 // initially invisible
    VSpeed -10
    +NOINTERACTION
    +DONTSPLASH
    -SOLID
    
    var int user_offsetx;
    var int user_offsety;
    var int user_offsetz;
    var int user_gravity;
    var int user_life;
    
    States
    {
        Spawn:
            TNT1 A 1
            TNT1 A 0 A_SetTranslucent (0.5, 1) // now make rain visible
        Spawn2:
            TNT1 A 0 A_JumpIf(waterlevel > 0, "CrashUnderwater")
            TNT1 A 0 A_JumpIf(z < floorz, "Crash")
            TNT1 A 0 A_JumpIf(user_life >= 35, "Destroy")
            TNT1 A 0 A_Warp(AAPTR_TRACER, user_offsetx, user_offsety, user_offsetz - user_gravity, 0, WARPF_ABSOLUTEOFFSET | WARPF_NOCHECKPOSITION | WARPF_INTERPOLATE)
            TNT1 A 0 A_SetUserVar(user_gravity, user_gravity + 10) // add to drop velocity
            TNT1 A 0 A_SetUserVar(user_life, user_life + 1) // add to life counter
            RNDR A 1 A_DrawRain // handle rain rendering
            Loop
        Crash:
            TNT1 A 0
            TNT1 A 0 A_SpawnItemEx("Z_RainSplash", 0, 0, 0, 0, 0, 0, 0, SXF_NOCHECKPOSITION | SXF_TRANSFERPOINTERS, 192)
            Stop
        CrashUnderwater:
            TNT1 A 0 A_SpawnItemEx("Z_RainSplash", 0, 0, 0, 0, 0, 0, 0, SXF_NOCHECKPOSITION | SXF_TRANSFERPOINTERS, 192)
            TNT1 A 0
            Stop
        Destroy:
            TNT1 A 0
            Stop
    }
}
 
The way my system works is each player has their own set of rain drops. Not very bandwidth efficient but I'm only limiting my game to 4 players, and there's a custom server CVAR for rain density to help with performance. Each drop will properly spawn and "attach" to their respective owner player with some A_Warp trickery.

To handle visibility overlapping issues (so that each player will only see THEIR copy of the rain drops and NOT of other players') I had to modify the EXE and add A_DrawRain which specifically deals with this issue, since it's not yet possible to do this natively in ZDoom.

It works fine, and works with 3D floors too! No "Bethesda rain" (rain falling through level geometry). :D

If you need any more help let me know.

Re: ACS function: CheckActorInSector(tag, tid)

by edward850 » Sat Jan 25, 2014 1:49 am

I'm not quite sure I follow. If the rain isn't going to come from the sky, where else is it going to come from, and why do you need to check what sector it's in therefore? It almost seems like you are over-thinking this.

Re: ACS function: CheckActorInSector(tag, tid)

by StrikerMan780 » Sat Jan 25, 2014 1:36 am

edward850 wrote:If you want to track players specifically, you can track "DoomPlayer" (or whatever the playerclass your map uses) using [wiki]ThingCountNameSector[/wiki].
Not trying to track players, but individual raindrops for a rain system. Which, while I know if too many are spawned will use up a lot of CPU (but I have come up with ways to handle this. There's only about 10 or so drops per 8 ticks spawned, in a radius around the player). The reason I want to check the drops, is because I want to make rain still come from the sky if the player is standing inside, but near a window, given that the outdoor area is still in the players' radius. (The map is in an urban setting with many houses you can go in and out of.)

Re: ACS function: CheckActorInSector(tag, tid)

by edward850 » Fri Jan 24, 2014 11:17 pm

If you want to track players specifically, you can track "DoomPlayer" (or whatever the playerclass your map uses) using [wiki]ThingCountNameSector[/wiki].

Re: ACS function: CheckActorInSector(tag, tid)

by StrikerMan780 » Fri Jan 24, 2014 10:47 pm

I need it on a per-activator basis. Nothing can share TIDs for what I'm trying to do. (Besides I want to avoid using TIDs in general in case of conflicts.)

Re: ACS function: CheckActorInSector(tag, tid)

by Xaser » Thu Jan 23, 2014 3:38 pm

Huh? Why wouldn't this work? :

Code: Select all

if (ThingCountSector(T_NONE, tid, tag) > 0)
{
    // do stuff
}
:shrug:

Re: ACS function: CheckActorInSector(tag, tid)

by StrikerMan780 » Thu Jan 23, 2014 1:55 pm

Bump from hell... I know the ThingCountSector command was implemented, but isn't what was in the first post (which is what I need.)

I'm currently working on a weather system for my map, however, I only want it to work for Sectors with a specific tag(s), instead of affecting *all* areas with f_sky in my map.

Top