What it says in the title. I want to make a monster with an attack that calls down lightning for example, but can only be used if the target is outdoors. Is that possible?
There are ways to check if the target is underwater by checking waterlevel, but is there a way to check if a monster is outdoors or indoors, as in, under a ceiling or exposed to the sky?
Making a weapon/monster with an outdoors only attack
Moderator: GZDoom Developers
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Making a weapon/monster with an outdoors only attack
Last edited by mrspeaker on Tue Nov 09, 2021 1:26 pm, edited 1 time in total.
Re: Making a weapon/monster that with an outdoors only attac
Are you willing to use ZScript? You can grab the target's current sector and check its ceiling texture, I believe. I'm not in a good spot to try it myself right now (I actually need to do something similar for my project at some point), but I am fairly sure it's possible.
Re: Making a weapon/monster that with an outdoors only attac
Just a quick note, if Zandronum compatibilty is required ACS can be used for that (I did that in my project, both an air strike and thunderstorm). The base gist is the same, to check an actor's ceiling texture.
Re: Making a weapon/monster that with an outdoors only attac
Unfortunately I only know how to use decorate. I have zero scripting/coding experience.nova++ wrote:Are you willing to use ZScript? You can grab the target's current sector and check its ceiling texture, I believe. I'm not in a good spot to try it myself right now (I actually need to do something similar for my project at some point), but I am fairly sure it's possible.
How did you manage to do it, if you don't mind me asking? I'm very interested especially in the airstrike since my idea was for a monster that could call an artillery strike on bosses.Virathas wrote:Just a quick note, if Zandronum compatibilty is required ACS can be used for that (I did that in my project, both an air strike and thunderstorm). The base gist is the same, to check an actor's ceiling texture.
Re: Making a weapon/monster with an outdoors only attack
Well, copying straight from my mod the scripts:
DECORATE
ACS
What it does in short: A beacon after a short while summons a few hundred missiles from sky in a significant radius.
What it does in long: The script is called from the decorate actor once, and only once.
The script first sets a TID to the actor, to be able to reference it easily.
The timepast variable is used to count how many missiles have been already spawned
The failcount is a safety variable, in case there are no valid places to spawn a missile, it will eventually terminate the script.
"if (!(Spawn("Airstrikemissile", x, y, z, MissileID)))" <- this both spawns a missile as well as checks for success. It adds a TID to the missile to reference it later.
The latter large "if" block is the thing you want the most - this tests if the location where missile spawns has the sky. If not, the missile is removed.
In your case the "beacon" should be spawned at the player's location, and then a similar script should be ran.
Hope it isn't too confusing
DECORATE
Code: Select all
Actor AirStrikeBeacon
{
Radius 16
Height 16
Mass 10
Speed 4
BounceFactor 0.0
-SHOOTABLE
-CANBLAST
States
{
Spawn:
MINE A 0 A_Gravity
BEAC ABABA 35
BEAC A 0 ACS_NamedExecuteAlways("AirStrikeTest",0)
goto idle
Idle:
BEAC AB 10
Loop
Death:
BEAC A 1 A_FadeOut(0.015)
Loop
}
}
Code: Select all
script "AirStrikeTest" (void)
{
int CenterTID = ActivatorTID();
int MissileID = UniqueTID();
int timepast = 0;
int failcount = 0 ;
while ( timepast < 400 )
{
if (failcount >= 100)
{
failcount = 0;
delay(5);
timepast++;
}
int x = GetActorX(CenterTID) + random(-768.0, 768.0);
int y = GetActorY(CenterTID) + random(-768.0, 768.0);
int z = GetActorCeilingZ(CenterTID);
if (!(Spawn("Airstrikemissile", x, y, z, MissileID)))
{
failcount++;
continue;
}
else
{
if ((CheckActorCeilingTexture(MissileID,"F_SKY1")) || (CheckActorCeilingTexture(MissileID,"F_SKY2")) || (CheckActorCeilingTexture(MissileID,"F_SKY3")) || (CheckActorCeilingTexture(MissileID,"F_SKY4")) || (CheckActorCeilingTexture(MissileID,"SKY1")) || (CheckActorCeilingTexture(MissileID,"SKY2")) || (CheckActorCeilingTexture(MissileID,"SKY3")) || (CheckActorCeilingTexture(MissileID,"SKY2A")) || (CheckActorCeilingTexture(MissileID,"SKYFOG")) || (CheckActorCeilingTexture(MissileID,"SKYFOG2")) || (CheckActorCeilingTexture(MissileID,"SKY")) || (CheckActorCeilingTexture(MissileID,"F_SKY")))
{
if ((GetActorCeilingZ (MissileID) - GetActorFloorZ (MissileID)) < 16)
{
Thing_Remove(MissileID);
failcount++;
Continue;
}
else
{
SetActorPosition(MissileID, x,y,GetActorCeilingZ(MissileID) - 4.0, 0);
}
}
else
{
Thing_Remove(MissileID);
failcount++;
Continue;
}
Thing_ChangeTID(MissileID, 0);
delay(5);
timepast++;
}
}
Thing_Remove(CenterTID);
}
What it does in long: The script is called from the decorate actor once, and only once.
The script first sets a TID to the actor, to be able to reference it easily.
The timepast variable is used to count how many missiles have been already spawned
The failcount is a safety variable, in case there are no valid places to spawn a missile, it will eventually terminate the script.
"if (!(Spawn("Airstrikemissile", x, y, z, MissileID)))" <- this both spawns a missile as well as checks for success. It adds a TID to the missile to reference it later.
The latter large "if" block is the thing you want the most - this tests if the location where missile spawns has the sky. If not, the missile is removed.
In your case the "beacon" should be spawned at the player's location, and then a similar script should be ran.
Hope it isn't too confusing

- Matt
- Posts: 9696
- Joined: Sun Jan 04, 2004 5:37 pm
- Preferred Pronouns: They/Them
- Operating System Version (Optional): Debian Bullseye
- Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
- Contact:
Re: Making a weapon/monster with an outdoors only attack
If you want to avoid both ACS and Zscript, one more option is to shoot an invisible, zero-damage, no-blood ripper projectile straight up really fast. If it explodes, it's hit a ceiling and should give the shooter an item marking the shooter as being under a ceiling; if it hits sky, it just disappears without doing anything further.
The weapon can then be set to, upon any shot:
1. Delete the item from the user's inventory
2. Shoot the invisible projectile
3. Wait a moment
4. Jump to an abort state if the item is found
That said, if you're willing to convert the weapon code to ZScript (basically just add a bunch of semicolons, add a version number, change a few formatting things for damage and put the properties/flags in a "default" block), you can basically skip to step 4 with something like
The weapon can then be set to, upon any shot:
1. Delete the item from the user's inventory
2. Shoot the invisible projectile
3. Wait a moment
4. Jump to an abort state if the item is found
That said, if you're willing to convert the weapon code to ZScript (basically just add a bunch of semicolons, add a version number, change a few formatting things for damage and put the properties/flags in a "default" block), you can basically skip to step 4 with something like
Code: Select all
MJOG A 0 A_JumpIf(CurSector.GetTexture(CurSector.ceiling)==SkyFlatNum,"summonlightning");
goto fail;
Re: Making a weapon/monster with an outdoors only attack
Thanks for the help! Your posts gave me an idea and I think I found an easy way to do this.
Monster shoots an invisible non-damaging missile on another valid monster (A_CheckLOF is called before to ensure he doesn't shoot something else). Upon hitting the target, it spawns another missile that has the +SKYEXPLODE flag, is also invisible and non-damaning, ripping, goes straight up and has both a Death and a Death.Sky states. So if it hits a ceiling, nothing happens and if it hits the sky, it works normally. What do you think? Will it work?
EDIT: It works. Now I just need to fine-tune it and I'll have a spotter marine that calls in artillery strikes on bosses.
Monster shoots an invisible non-damaging missile on another valid monster (A_CheckLOF is called before to ensure he doesn't shoot something else). Upon hitting the target, it spawns another missile that has the +SKYEXPLODE flag, is also invisible and non-damaning, ripping, goes straight up and has both a Death and a Death.Sky states. So if it hits a ceiling, nothing happens and if it hits the sky, it works normally. What do you think? Will it work?
EDIT: It works. Now I just need to fine-tune it and I'll have a spotter marine that calls in artillery strikes on bosses.