Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
baja blast rd.

*** The "ask a miscellaneous editing question" thread ***

Recommended Posts

Gez said:

"but if we change it to something that makes more sense now, it's going to break dozens of mods that depend on the not-perfectly-sensical behavior"

I never understood why ZDoom developers keep saying things like this to justify weird behavior being kept as default behavior. Why not make it a non-default behavior, possible to be enabled via a compatibility option? The relatively small finite amount of older mods relying on it will have to use this compatibility option to work properly, whereas the potentially infinite amount of future mods will have the benefit of taking "good" functionality for granted, whatever "good" means in the context of the respective feature (it certainly doesn't mean "only good for backwards compatibility with mods relying on a gimmick that this port once introduced by accident").

Share this post


Link to post

...yeah, but are you BAD enough to implement that yourself, or at least make a proper feature request instead of whining about it in random threads?

Share this post


Link to post

I'm just asking about the general principle now. What I suggested seems like a natural goal to follow to me, and yet in the long term, ZDoom developers seem to think differently. It doesn't seem like a result of lack of coders and/or awareness of the issues, it seems like they actually prefer inconveniencing the majority of wads and players (by unwanted behavior) over inconveniencing a minority of them (by mere selecting a special option for a special behavior to work). So, why is that? What am I missing?

Share this post


Link to post

So, I'm working on a fix for my mod, and I've already made this code:

Death:
SPOS H 5
SPOS H 0
{
user_spawn = 0;
while (user_spawn < 1){
A_SpawnItemEx("ZombieManSpawner",Random(-50, 50),Random(-50, 50),0,0,0,0,SXF_NOCHECKPOSITION);
}
{return state("SpawnItemEx";)}
}
SPOS I 5 A_Scream
SPOS J 5 A_NoBlocking
SPOS K 5
SPOS L -1
Stop

So, what I want to do is to check if the actor was sucesfully spawned, and then increment the variable to stop the loop. The problem is that I think I don't know how to use return, and even then GZDoom says this when I try to run:

Script error, "Hellspawn.wad:DECORATE" line 127:
Unexpected token '{'

And yes, this bracket is this one -> "{"return;}
What's the problem?

Share this post


Link to post
lwks said:

Script error, "Hellspawn.wad:DECORATE" line 127:
Unexpected token '{'

And yes, this bracket is this one -> "{"return;}
What's the problem?

I'm not seeing that line in your code.

That said, I believe the error is here: ("SpawnItemEx";)}
Which should be ("SpawnItemEx");}

Share this post


Link to post



It's funny because it says the "{" is on the line 127, but it actually is on the line 128...

Share this post


Link to post
lwks said:

It's funny because it says the "{" is on the line 127, but it actually is on the line 128...

Probably because the compiler started looking for a keyword on line 127 after the closing bracket, skipped all whitespaces, reached the opening bracket on line 128, detected an error in syntax, and reported the line where the looking for a keyword has started, 127. It's normal for compilers to report errors on not exactly the same lines where they need to be corrected, because the compiler only understands rules of syntax, not what the programmer wanted to achieve.

In C/C++, the superfluous brackets would have been OK, but apparently, they might not be OK in DECORATE.

Also, are you sure that you want the actor to jump into a state named "spawnitemex" after finishing the anonymous function, rather than simply continuing the animation with the next state immediately below the anonymous function?

Share this post


Link to post
lwks said:

https://s12.postimg.org/vbx0q7nbx/erro.png

It's funny because it says the "{" is on the line 127, but it actually is on the line 128...

It's probably just because SLADE numbers the lines starting from 1, while ZDoom counts them starting from 0.

Try writing some complete nonsense on the very first line, and see if ZDoom reports it as an error on line 0.

Share this post


Link to post
scifista42 said:

Also, are you sure that you want the actor to jump into a state named "spawnitemex" after finishing the anonymous function, rather than simply continuing the animation with the next state immediately below the anonymous function?



Well, I read in the ZDoom Wiki that I can use return to check if the A_SpawnItemEx successfully spawned an actor, and that's what I want to do, but I should have put the return inside the "while".
So...I have to use return without bracketsm cause on the ZDoom Wiki they're all with brackets? Can someone send me a exemple of return? I really have no ideia of how to use this to check if the A_SpawnItemEx was sucessful.

Share this post


Link to post

What do you want to happen if A_SpawnItemEx is not successful? You can't just loop it forever during a single tic, because it would never be successful and thus freeze the engine.

Share this post


Link to post

Actually I want to get rid of the SFX_NOCHECKPOSITION. This is causing the actors to spawn inside walls, but the problem is that without it the spawn is like, 5% chance of happening, even though the actor is in a flat and clean surface. That's why I need return, to check if the spawn was successfully and stop the loop (and also to play the Teleport animation but whatever).

Share this post


Link to post

The only reason why the spawn may fail is because something is blocking the destination. No randomness/probability is involved. If you call A_SpawnItemEx without SFX_NOCHECKPOSITION and the spawn fails, then if you immediately call it again, it would fail again (guaranteedly if you try to spawn it on the same place, or if you try multiple different places around the actor but none of the places is actually free), and again and again if you keep repeating it - so, if you program the while loop to never stop until success, then it will loop forever, and the engine will be unable to do anything else than repeating this loop, until it eventually freezes and crashes. So, in addition to the wrong syntax, what you're trying to do is also wrong out of principle. Perhaps you could try to use A_SpawnItemEx without SFX_NOCHECKPOSITION a couple times, and if all of them fail, call it finally with SFX_NOCHECKPOSITION as close to the calling actor's position as possible, so that it would be the least likely to spawn inside walls.

Share this post


Link to post

The problem is that the Spawn fail on a clean surface, I really can't believe that a loop won't solve the problem, u sure? I'm talking about a clean surface. Please, just let me test here, and even so, I'd need a return to check if the actor weren't spawned to spawn again using a SFX_NOCHECKPOSITION.
(The problem is that I NEED to get rid of SFX_NOCHECKPOSITION, cause it's causing the actors to spawn inside walls).

Share this post


Link to post
scifista42 said:

The only reason why the spawn may fail is because something is blocking the destination. No randomness/probability is involved.

I'm absolutely sure about this. So, looping A_SpawnItemEx only makes sense if you try different places each time. You're apparently doing that (the x and y positions are randomized), so that's OK - but if all places were occupied and you didn't limit the number of iterations of the loop, the loop would never end, which would be bad.

lwks said:

I'd need a return to check if the actor weren't spawned

You don't use "return" to "check" anything. A_SpawnItemEx itself "returns" true if successful and false if not - this doesn't mean you should use the "return" command anywhere. If you wanted a loop going forever until it's successful, you'd do it like this:

SPOS H 0 {
  while(!A_SpawnItemEx(...)) {}
}
But to avoid looping forever, you'd do it like this instead:
SPOS H 0 {
  user_spawn = 0;
  while(!A_SpawnItemEx(...) && user_spawn<10) { user_spawn++; }
}
The latter loop will abort after 10 unsuccessful attempts, for the benefit that the engine won't freeze forever, at the cost that nothing will be spawned.

You could also do it so that, after some unsuccessful attempts without SFX_NOCHECKPOSITION, finally give up and use SFX_NOCHECKPOSITION for the last attempt - such a code would have to be structured slightly differently than the above one, but it would certainly be possible.

Share this post


Link to post
lwks said:

The problem is that the Spawn fail on a clean surface, I really can't believe that a loop won't solve the problem, u sure?

A loop in the same state will not solve your problem because what you need is to move your actor before it tries spawning something again.

If you try to do that with a loop in an anonymous function, what will you get? The actor will try to spawn in the exact same place every time so it'll always fail and you'll freeze the game because the actor will never get to leave its state and let the game process the rest of the game world; or it'll succeed on the first try and then looping was useless, wasn't it?


What you need to do is set up a loop of several states where the actor moves, tries to spawn something, and if successfully spawned leaves the loop while if spawning failed it goes back to moving.

So basically you want this:

Death:
SPOS H 5
    {
       A_Wander; // Feel free to remove that if it makes it look too weird
                 // to have the corpse move around like this
       if (A_SpawnItemEx("ZombieManSpawner",Random(-50, 50),Random(-50, 50)))
       {
           return state("Death+1");
       }
       return state("Death");
    }
SPOS I 5 A_Scream
SPOS J 5 A_NoBlocking
SPOS K 5
SPOS L -1
Stop
That way it'll try and try again and again without freezing the game.

Share this post


Link to post

This is impossible, the Spawn occur during the death animation. If you want more, go check my mod on the ZDoom Forum, it's on the first page on the Projects.
It's "Hellspawn: Hell's Army"
The thing is, whenever an demon dies it spawns other demons. I used the SFX_NOCHECKPOSITION to fix the problem of not spawning, but it's causing the actors to spawn inside walls and stuff...now I sincerely don't know how to fix it...

Edit:
I'll just link here for the sake of lazyness.
https://forum.zdoom.org/viewtopic.php?f=19&t=54133

Edit2:
Gez, your code didn't work.

Edit3:
Tried this:
{
while(!A_SpawnItemEx("LookZombieMan",Random(-50, 50),Random(-50, 50),Random(-20,20),0,0,0)) {
A_SpawnItemEx("LookZombieMan",Random(-50, 50),Random(-50, 50),Random(-20,20),0,0,0);
}
}

Didn't work at all, sometimes it spawns 2, 3 or even 4 ZombieMans, and even, once inside a wall. is there a way for my fix this with advanced programming? (Which skills I do not have) Cuz it seems to me my mod is dead.

Share this post


Link to post

You shouldn't be trying to place the spawned monster further from the originating actor than the spawned monster's radius (or the spawned monster's radius + the originating actor's radius), otherwise there will always be a possibility of spawning into walls. Zombieman's radius is 20, so put "Random(-20,20)" into the x and y offset values (or "20 + the originating actor's radius" instead of 20).

Then the spawned monsters would tend to be blocked by the originating actor, though. Make the originating actor nonsolid first, by calling NoBlocking on him before the A_SpawnItemEx. Then you still won't be able to spawn more than 1 monster (once one is spawned, it will block the others), but at least one may spawn and be guaranteed to not spawn inside a wall.

lwks said:

Tried this:
{
while(!A_SpawnItemEx("LookZombieMan",Random(-50, 50),Random(-50, 50),Random(-20,20),0,0,0)) {
A_SpawnItemEx("LookZombieMan",Random(-50, 50),Random(-50, 50),Random(-20,20),0,0,0);
}
}

The A_SpawnItemEx inside the curly brackets is redundant. Even if it succeeds, the loop never finds out about it, therefore will continue looping. The A_SpawnItemEx inside the round brackets is supposed to both do the job of spawning as well as being checked for success.

The code still doesn't resolve the threat of an infinite loop, though.

Share this post


Link to post

Well, thank you sir, now it's working:

Death:
SPOS H 5
SPOS I 5 A_Scream
SPOS J 5 A_NoBlocking
SPOS J 0
{
user_spawn = 0;
while(!A_SpawnItemEx("ZombieManSpawner",0,0,0,0,0,0) && user_spawn<100) {
user_spawn++;
}
}
SPOS K 5
SPOS L -1
Stop

Thing is, the concept of the mod is to spawn two demons, not just one, I think I'll have to put a really good time difference between the two spawns, thing is IF an enemy come closer to the spawn point and block the second spawn? Any sugestions?
Also, I'll put your name big and bold on the credits, cause you totally solved the problem for me.

Also, this "&& user_spawn<100", what's its use? Is it just to prevent the game freezing? Cause I just deleted it and the mod didn't have any problem.

Share this post


Link to post
lwks said:

Also, this "&& user_spawn<100", what's its use?

It checks the current value of user_spawn and aborts the loop if the value is higher or equal 100. Since you are increasing the value of user_spawn by 1 (user_spawn++) in each iteration of the loop, this effectively limits the loop to 100 iterations at most. If A_SpawnItemEx fails 100 times, the loop will be aborted, spawning nothing. If the loop wasn't aborted, and if A_SpawnItemEx failed infinitely, the engine would freeze.

In fact, your current setup makes the loop completely redundant. If A_SpawnItemEx fails once, you don't need to try again, because you know it will never succeed if you retry spawning onto the very same place at the very same time, which is what you are doing here. You'd need something like what Gez suggested instead if you wanted to guarantee that something may get spawned even if the destination was blocked on the first attempt.

Share this post


Link to post

Ok, I know the basics of programming, I know what's happening, but I've never worked with returns, so I didn't know what was that, so it basically ensure that the game doesn't freeze, right?

Also, I'm using this now:

actor MinionShotgunGuy : ShotgunGuy replaces ShotgunGuy
{
var int user_spawn;
States
{
Death:
SPOS H 5
SPOS I 5 A_Scream
SPOS J 5 A_NoBlocking
SPOS J 0
{
user_spawn = 0;
while(!A_SpawnItemEx("ZombieManSpawner",0,0,0,0,0,0) && user_spawn<10) {
user_spawn++;
}
}
SPOS K 5
SPOS L -1
Stop
XDeath:
SPOS H 5
SPOS N 5 A_XScream
SPOS O 5 A_NoBlocking
SPOS PQRST 5
{
user_spawn = 0;
while(!A_SpawnItemEx("ZombieManSpawner",0,0,0,0,0,0) && user_spawn<10) {
user_spawn++;
}
}
SPOS U -1
Stop
}
}
actor ZombieManSpawner
{
Radius 20
Height 56
States{
Spawn:
TNT1 A 0
TNT1 A 0 A_SpawnItemEx("TeleportFog")
TNT1 A 0 A_SpawnItemEx("LookZombieMan",0,0,0,Random(-5, 5),Random(-5, 5),0,SXF_TELEFRAG)
TNT1 A 50
TNT1 A 0 A_SpawnItemEx("TeleportFog")
TNT1 A 0 A_SpawnItemEx("LookZombieMan",0,0,0,Random(-5, 5),Random(-5, 5),0,SXF_TELEFRAG)
Stop
}
}

Telefrag isn't working, wth? Why is that?
If the Telefrag don't work I'll need to use the user_spawn

Share this post


Link to post
lwks said:

actor ZombieManSpawner
{
  Radius 20
  Height 56
    States{
     Spawn:
     TNT1 A 0
     TNT1 A 0 A_SpawnItemEx("TeleportFog")
     TNT1 A 0 A_SpawnItemEx("LookZombieMan",0,0,0,Random(-5, 5),Random(-5, 5),0,SXF_TELEFRAG)
	 TNT1 A 50
	 TNT1 A 0 A_SpawnItemEx("TeleportFog")
     TNT1 A 0 A_SpawnItemEx("LookZombieMan",0,0,0,Random(-5, 5),Random(-5, 5),0,SXF_TELEFRAG)
     Stop
    }
}
Telefrag isn't working, wth? Why is that?
If the Telefrag don't work I'll need to use the user_spawn


Heh. It's simple, actually. Look at the function header on the wiki:

bool A_SpawnItemEx (string type [, float xoffset [, float yoffset [, float zoffset [, float xvelocity [, float yvelocity [, float zvelocity [, float angle [, int flags [, int chance [, int tid ]]]]]]]]])
Now let's count. You give the type. You give zeroes for the three offsets. Then you give two randoms for xvelocity and yvelocity and zero for zvelocity. So far so good, good job. Then you say that the angle of the thing should be SXF_TELEFRAG. Hm. That doesn't sound like a good angle to me, no sir.

Share this post


Link to post

LOL, I though I could just throw the SXF anywhere and the code would understant, cause I've actually done this, but with the SXF_NOCHECKPOSITION, and I didn't had any problem, but thanks, gonna try

Share this post


Link to post

Maybe in a smarter language you could, but DECORATE and ACS don't hold your hand too much. Also, be sure to check your code with SXF_NOCHECKPOSITION and fix it as well. Right now it might work, but who knows if that won't break things later on.

I hope zscript fixes that, making the compiler warn you when you're passing an integer / flag to where you should pass a float. I've spent time figuring out a similar error more than once. >_>

Share this post


Link to post

TY guys, your name will be on the credits, it worked here, and I'll rework the whole mod, then test and release as v1.1, many thanks strangers! You saved my lif...I mean, my mod! xD

Edit: Also, the actor that spawns the demons has Height and Radius, but it doesn't Block the player, is it because it doesn't have mass?

actor ZombieManSpawner
{
Radius 20
Height 56
States{
Spawn:
TNT1 A 0
TNT1 A 0 A_SpawnItemEx("TeleportFog")
TNT1 A 0 A_SpawnItemEx("LookZombieMan",0,0,0,Random(-5, 5),Random(-5, 5),0,0,SXF_TELEFRAG)
TNT1 A 50
TNT1 A 0 A_SpawnItemEx("TeleportFog")
TNT1 A 0 A_SpawnItemEx("LookZombieMan",0,0,0,Random(-5, 5),Random(-5, 5),0,0,SXF_TELEFRAG)
Stop
}
}

Share this post


Link to post

You might have to specifically add the +SOLID flag there (just add "+SOLID" on its own line under height and radius), as I'm pretty sure actors are passable by default.

Share this post


Link to post

Thank you, but that was just out of curiosit, I need them without collision. =)

Edit: Ok, just for the record I went to Doom ][ Map 13 and killed some of the Revenants on those Edges and I figured out that the "while (!A_SpawnItemEx)" where causing something very strange, demons killed by the telefrag didn't count as spawned and it seem cause enemies to spawn infinitely, in less than 15 seconds I got like 250 monsters killed, now the whole code follow this structure:

actor MinionShotgunGuy : ShotgunGuy replaces ShotgunGuy
{
States
{
Death:
SPOS H 5
SPOS I 5 A_Scream
SPOS J 5 A_NoBlocking
SPOS K 5
SPOS K 0 A_SpawnItemEx("ZombieManSpawner",0,0,0,0,0,0)
SPOS L -1
Stop
XDeath:
SPOS H 5
SPOS N 5 A_XScream
SPOS O 5 A_NoBlocking
SPOS PQRST 5
SPOS T 0 A_SpawnItemEx("ZombieManSpawner",0,0,0,0,0,0)
SPOS U -1
Stop
}
}

Yeah, like a normal code...
=) Ty anyways

Share this post


Link to post

Why can't floors/ceilings move if there is no open space between the two sectors to be moved? What I mean is, floor A and B are beside each other (like a joined sector beside a dummy sector) but the two sectors are separated in the vertical void, so the floor of one is all the way above the ceiling of the other.

Tested in-game, if they are separated with no open space, the script never runs. With some open space, it works just fine. Is the engine really that stupid that it can't see the floor and ceiling to move to is right beside it?

Share this post


Link to post

Showing your script would help here, and/or a quick screenshot of the area in question in a 3D view would help too. :)

Share this post


Link to post

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
×