Isweartogodiamlosingit Posted August 30, 2023 This is probably a Newbie Question and all, but at this point i don't care, so il'l just explain my problem and hope someone could perhaps give me the answer i'm looking for. Anyways so I've been working on a doom wad for quite a bit, and came up with the idea of making a monster-battling arena, and well the map part of this is finished, though sadly the death counter seems to have an issue, though first il'l explain how it works. Basically your'e supposed to fight 4 waves of demons, with each wave dead lowering the height of the acid, and the final miniboss lowering the gates leading to a path further. This gate is below the acid if it helps. The death tally almost works perfectly. Each time you kill a monster, the monster count gets printed on the screen (i will make this a bit more detailed later), and when it reaches the needed count the acid does lower and the next wave teleports in. All fine and dandy. Well i came into a tad bit of a problem, this problem being that if you kill two monsters at once it registers the double-kill as one single point, not two. I'm pretty sure the solution for this just flew over my head considering i'm quite new to scripting in zdoom ACS, or hell, any other coding language. Here's the script btw script 6 (void) { points = points + 1; print(i:points); if (points == 9) { Ceiling_RaiseByValueTimes8 (145, 8, 20); Ceiling_LowerByValue (147, 2, 20); } } script 7 (void) { points = points + 1; print(i:points); if (points == 18) { Ceiling_RaiseByValueTimes8 (150, 8, 16); Ceiling_LowerByValue (147, 2, 20); } } script 8 (void) { points = points + 1; print(i:points); if (points == 27) { Ceiling_RaiseByValueTimes8 (151, 8, 16); Ceiling_LowerByValue (147, 2, 20); } } script 9 (void) { points = points + 1; print(i:points); if (points == 36) { Ceiling_RaiseByValueTimes8 (152, 8, 20); Ceiling_LowerByValue (147, 2, 40); Floor_LowerByValueTimes8 (153, 2, 12); } } each script is used for a new wave of monsters. The miniboss thing isn't set up yet due to this problem making it near-impossible to even get to that point if you don't give it attention. The ceiling raise by value is simply for the doors in my monster spawner closets. The ceiling lower by value is for the acid pit, and the floor lower by value at the end is for that gate. I will make sure to also add some pictures as a reference. 0 Quote Share this post Link to post
Kan3 Posted August 30, 2023 Pretty "heavy" way to deal with this thing x) You have several solutions: If you want to stick to this way: if you use ACS_ExecuteAlways on the monsters (I believe you're calling the script from each monster for every wave), should fix the problem. Otherwise, if you want cleaner way to do things: Just give the monsters a different tid for each wave (for example: monsters of the 1st wave with tid of 1, monsters of 2nd wave tid of 2 etc.), then you could just call a script with multiple loops like this: script "Waves" (void) { //You can let the player activate the script by crossing a line or whatever int points = 0; while (ThingCount(T_NONE, 1) > 0) { //until there are at least 1 monster with a tid of 1 alive points++; //better than points = points + 1; Print(i:points); Delay(35); //wait and repeat every second (change the tcs to whatever you like) } Ceiling_RaiseByValueTimes8(....); //when everyone's dead, do your stuff //Fall straight through the next wave loop while (ThingCount(T_NONE, 2) > 0) { //until there are at least 1 monster with a tid of 2 alive points++; Print(i:points); Delay(35); //wait and repeat every second } ...etc. } Just use the Doom monster counter: script "Waves" (void) { int points = GetLevelInfo(LEVELINFO_KILLED_MONSTERS); //it directly retrieves the monster count while(points < GetLevelInfo(LEVELINFO_TOTAL_MONSTERS)) { //while points is lower than the total number of monsters in the map Print(i:points); if(points == X) { //with X being the number of dead monsters of your choice Ceiling_LowerByValueTimes8(); //do your stuff; } if(points == Y) { Ceiling_LowerByValueTimes8(); //do more stuff; } etc. } Floor_LowerByValueTimes8(); //When everyone's dead, do the end stuff } 0 Quote Share this post Link to post
Isweartogodiamlosingit Posted August 31, 2023 Thanks a lot for responding! Though sorry for bothering you again... i ran into a problem. Again somehow. The script compiles, and i keep getting the runaway script error message when setting it off, but i got the runaway script error. So i added the delay, the error message doesen't pop up, but sadly none of the if statements run. Here's the code script 6 (void) { int points = GetLevelInfo(LEVELINFO_KILLED_MONSTERS); //it directly retrieves the monster count while(points < GetLevelInfo(LEVELINFO_TOTAL_MONSTERS)) delay (1); { if(points == 9) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(145, 8, 20); } if(points == 18) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(150, 2, 20); } if(points == 27) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(151, 2, 20); } } } Thanks a lot again for helping. 0 Quote Share this post Link to post
Kan3 Posted August 31, 2023 Delay() needs to be called inside the while loop, you can't "open" the loop if you call stuff before opening the brackets. Also, sorry, I made a mistake in the scripts, dumb me. You also have to set the points value inside the while loop or it won't update. So something like this: script 6 (void) { int points = 0; while(points < GetLevelInfo(LEVELINFO_TOTAL_MONSTERS)) { points = GetLevelInfo(LEVELINFO_KILLED_MONSTERS); if(points == 9) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(145, 8, 20); } if(points == 18) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(150, 2, 20); } if(points == 27) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(151, 2, 20); } Delay(35); //No need to call it every tic. } } Untested again, I hope I didn't write something else wrong D: 0 Quote Share this post Link to post
Worst Posted September 1, 2023 18 hours ago, Kan3 said: script 6 (void) { int points = 0; while(points < GetLevelInfo(LEVELINFO_TOTAL_MONSTERS)) { points = GetLevelInfo(LEVELINFO_KILLED_MONSTERS); if(points == 9) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(145, 8, 20); } if(points == 18) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(150, 2, 20); } if(points == 27) { Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(151, 2, 20); } Delay(35); //No need to call it every tic. } } Untested again, I hope I didn't write something else wrong D: This script has a couple of potential problems: The points conditions have to match the exact amount for the actions to take place. So if for example 8 monsters are killed, and then before the next check (after 35 tics) two more are killed, points will be 10, and the condition for 9 points will never happen. The actions will trigger multiple times if the points amount stays valid. So if for example 9 monsters have been killed, and the player does not kill any more, then the actions for points 9 condition will keep repeating every second. In case any Arch-viles or Pain Elementals are used, then revived monsters or spawned lost souls could make these kill counts get reached sooner than planned. I think it would be safer to use a script with ThingCount and tagged monsters, like this for example: Spoiler // Monster tags/tids for each wave. #define TID_WAVE_1 1 #define TID_WAVE_2 2 #define TID_WAVE_3 3 script 6 OPEN // Wave script { // Wait for 1. Wave to die while(ThingCount(T_NONE, TID_WAVE_1) > 0) Delay(35); Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(145, 8, 20); // Wait for 2. Wave to die while(ThingCount(T_NONE, TID_WAVE_2) > 0) Delay(35); Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(150, 2, 20); // Wait for 3. Wave to die while(ThingCount(T_NONE, TID_WAVE_3) > 0) Delay(35); Ceiling_LowerByValueTimes8(147, 2, 20); Ceiling_RaiseByValueTimes8(151, 2, 20); } script 7 OPEN //Death tally script - Change this from OPEN to (void) if you don't want the tally to display from the beginning of the map. { bool w1done = FALSE; bool w2done = FALSE; bool w3done = FALSE; int previous_points = 0; int points = 0; while(TRUE) { points = GetLevelInfo(LEVELINFO_KILLED_MONSTERS); if (points != previous_points) // If points have changed { previous_points = points; // Update previous_points if ((w1done == FALSE) && (ThingCount(T_NONE, TID_WAVE_1) == 0)) { w1done = TRUE; PrintBold(s:"Wave 1 Clear!\n", s:"Points: ", d:points); } else if ((w2done == FALSE) && (ThingCount(T_NONE, TID_WAVE_2) == 0)) { w2done = TRUE; PrintBold(s:"Wave 2 Clear!\n", s:"Points: ", d:points); } else if ((w3done == FALSE) && (ThingCount(T_NONE, TID_WAVE_3) == 0)) { w3done = TRUE; PrintBold(s:"Wave 3 Clear!\n", s:"Points: ", d:points); } else { PrintBold(s:"Points: ", d:points); } } Delay(35); } } 0 Quote Share this post Link to post
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.