Not just a ripper projectile, but a projectile that deals a specific ammount of damage to a specific ammount of enemies upon contact, and then dissapears
I'm currently trying for the life of me to make a shuriken. The shuriken is supposed to be able to go through one enemy, hitting two total. Its not a homing projectile, so if it hits a wall before hitting both monsters itll just count as a miss.
I want to be able to shoot it at a group of really weak enemies (10 hp each) and two of them die, because the shuriken deals 15 damage to its two targets. Only two enemies are supposed to die.
I'm running a bit on the desperate side here. Pls hlp
DECORATE Projectile that goes through multiple actors?
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!)
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: DECORATE Projectile that goes through multiple actors?
In DECORATE you won't be able to do it. You'll need ZScript and override the SpecialMissileHit method which allows you to fine tune the behavior of your projectile when it hits a target.
Re: DECORATE Projectile that goes through multiple actors?
It is possible by using multiple projectiles that gets fired at the same time. That's how I achieved multiple target piercing effect on my mod, and yes this method worked before I made the conversion to ZScript. The downside of it that it the projectile must be shot with 100% accuracy, in my case I made the damaging projectile almost invisible save for when it hits a target and a dummy projectile that gets fired last which does the more fancier fake particle effects at 0 damage, I tested it a lot and it meet to my exceptions. It also still works when the projectile inherits FastProjectile actor.Graf Zahl wrote:In DECORATE you won't be able to do it. You'll need ZScript and override the SpecialMissileHit method which allows you to fine tune the behavior of your projectile when it hits a target.
So for example when those the main projectile does 60 damage and the weapon fires 5 of it then it will be able to pierce 5 doomimps and the faux projectile "detonates" at the last target.
I did this because the +ripper flag does not represent the behavior of how a average AP shot works in real life.
Code: Select all
APHE_Fire:
"####" A 0 A_TakeInventory("MT_75x500mmAP",1)
"####" A 0 A_Jumpifinventory("MTU_APShot_2",2, "APHE3_Fire")
"####" A 0 A_Jumpifinventory("MTU_APShot_2",1, "APHE2_Fire")
"####" AAAAAAA 0 A_Firecustommissile("MT_105mmAPHEshell",0,0) //Damaging Projectile
"####" A 0 A_FireCustomMissile("MT_105mmAPHEshell_Dummy",0,1) //Faux Projectile
Goto MuzzleFlash_Default
Code: Select all
//----Armor Piercing High Explosive Shell
//AP is shot 7x times.
const int p105mmAPHE_ttd = 55;
const int p105mmAPHE_dd = 100;
const int p105mmAPHE_sdmg = 50;
const int p105mmAPHE_srad = 90;
const int p105mmAPHE_sfullrad = 80;
//UPG1
const int p105mmAPHE_2_dd = 120;
const int p105mmAPHE_2_sdmg = 72;
const int p105mmAPHE_2_srad = 108;
const int p105mmAPHE_2_sfullrad = 90;
//UPG2
const int p105mmAPHE_3_dd = 144;
const int p105mmAPHE_3_sdmg = 87;
const int p105mmAPHE_3_srad = 130;
const int p105mmAPHE_3_sfullrad = 120;
ACTOR MT_105mmAPHEshell : MTP_ShellBase_Fast
{
Speed 95
DamageType Piercing
damage (p105mmAPHE_dd)
Obituary "%o <105mm APHE] %k"
+BLOODSPLATTER
States
{
Setter:
TNT1 A 0 A_SetUserVar("user_ttl", p105mmAPHE_ttd)
TNT1 A 0 A_SetUserVar("user_mode", 1)
TNT1 A 0 A_Jump(256, "Jumper")
Goto Jumper
Drop:
TNT1 A 0 A_CustomMissile("MT_105mmAPHEshell_Drop", 0, 0, 0, CMF_AIMDIRECTION, velz / 2)
Stop
Death:
TNT1 A 0 A_Spawnitem("MTCEG_MediumExplosion_APHEFlash_EX")
TNT1 A 0 A_PlaySound("Medium/APExplosion")
FDeath:
TNT1 A 1 A_Explode(p105mmAPHE_sdmg,p105mmAPHE_srad,0,0,p105mmAPHE_sfullrad)
Stop
XDeath:
TNT1 A 0 A_spawnitemex("MT_CEG_75mm_OrganHit_Trail",0,0,0,+frandom(-12,12),+frandom(-12,12),+frandom(-12,12))
TNT1 AAAA 0 A_spawnitemex("MT_CEG_75mm_OrganHit",0,0,0,+frandom(-3,3),+frandom(-3,3),+frandom(-3,3))
TNT1 A 0 A_PlaySound("MeaHit3")
FXDeath:
TNT1 A 1 A_Explode(p105mmAPHE_sdmg,p105mmAPHE_srad,0,0,p105mmAPHE_sfullrad)
Stop
Crash:
TNT1 A 0 A_Spawnitem("MTCEG_MediumExplosion_APHEFlash_EX")
TNT1 A 0 A_PlaySound("MetHit3")
FCrash:
TNT1 A 1 A_Explode(p105mmAPHE_sdmg,p105mmAPHE_srad,0,0,p105mmAPHE_sfullrad)
Stop
}
}
ACTOR MT_105mmAPHEshell_Drop : MTP_ShellBase
{
Speed 60
Gravity 0.25
DamageType Piercing
damage (p105mmAPHE_dd)
Obituary "%o <105mm APHE] %k"
+BLOODSPLATTER
States
{
Setter:
TNT1 A 0 A_SetUserVar("user_ttl", 9999)
TNT1 A 0 A_SetUserVar("user_mode", 1)
TNT1 A 0 A_Jump(256, "Jumper")
Goto Jumper
Death:
TNT1 A 0 A_Spawnitem("MTCEG_MediumExplosion_APHEFlash_EX")
TNT1 A 0 A_PlaySound("Medium/APExplosion")
FDeath:
TNT1 A 1 A_Explode(p105mmAPHE_sdmg,p105mmAPHE_srad,0,0,p105mmAPHE_sfullrad)
Stop
XDeath:
TNT1 A 0 A_spawnitemex("MT_CEG_75mm_OrganHit_Trail",0,0,0,+frandom(-12,12),+frandom(-12,12),+frandom(-12,12))
TNT1 AAAA 0 A_spawnitemex("MT_CEG_75mm_OrganHit",0,0,0,+frandom(-3,3),+frandom(-3,3),+frandom(-3,3))
TNT1 A 0 A_PlaySound("MeaHit3")
FXDeath:
TNT1 A 1 A_Explode(p105mmAPHE_sdmg,p105mmAPHE_srad,0,0,p105mmAPHE_sfullrad)
Stop
Crash:
TNT1 A 0 A_Spawnitem("MTCEG_MediumExplosion_APHEFlash_EX")
TNT1 A 0 A_PlaySound("MetHit3")
FCrash:
TNT1 A 1 A_Explode(p105mmAPHE_sdmg,p105mmAPHE_srad,0,0,p105mmAPHE_sfullrad)
Stop
}
}
ACTOR MT_105mmAPHEshell_2 : MT_105mmAPHEshell
{
States
{
Drop:
TNT1 A 0 A_CustomMissile("MT_105mmAPHEshell_2_Drop", 0, 0, 0, CMF_AIMDIRECTION, velz / 2)
Stop
FDeath:
TNT1 A 1 A_Explode(p105mmAPHE_2_sdmg,p105mmAPHE_2_srad,0,0,p105mmAPHE_2_sfullrad)
Stop
FXDeath:
TNT1 A 1 A_Explode(p105mmAPHE_2_sdmg,p105mmAPHE_2_srad,0,0,p105mmAPHE_2_sfullrad)
Stop
FCrash:
TNT1 A 1 A_Explode(p105mmAPHE_2_sdmg,p105mmAPHE_2_srad,0,0,p105mmAPHE_2_sfullrad)
Stop
}
}
ACTOR MT_105mmAPHEshell_2_Drop : MT_105mmAPHEshell_Drop
{
States
{
FDeath:
TNT1 A 1 A_Explode(p105mmAPHE_2_sdmg,p105mmAPHE_2_srad,0,0,p105mmAPHE_2_sfullrad)
Stop
FXDeath:
TNT1 A 1 A_Explode(p105mmAPHE_2_sdmg,p105mmAPHE_2_srad,0,0,p105mmAPHE_2_sfullrad)
Stop
FCrash:
TNT1 A 1 A_Explode(p105mmAPHE_2_sdmg,p105mmAPHE_2_srad,0,0,p105mmAPHE_2_sfullrad)
Stop
}
}
ACTOR MT_105mmAPHEshell_3 : MT_105mmAPHEshell
{
States
{
Drop:
TNT1 A 0 A_CustomMissile("MT_105mmAPHEshell_3_Drop", 0, 0, 0, CMF_AIMDIRECTION, velz / 2)
Stop
FDeath:
TNT1 A 1 A_Explode(p105mmAPHE_3_sdmg,p105mmAPHE_3_srad,0,0,p105mmAPHE_3_sfullrad)
Stop
FXDeath:
TNT1 A 1 A_Explode(p105mmAPHE_3_sdmg,p105mmAPHE_3_srad,0,0,p105mmAPHE_3_sfullrad)
Stop
FCrash:
TNT1 A 1 A_Explode(p105mmAPHE_3_sdmg,p105mmAPHE_3_srad,0,0,p105mmAPHE_3_sfullrad)
Stop
}
}
ACTOR MT_105mmAPHEshell_3_Drop : MT_105mmAPHEshell_Drop
{
States
{
FDeath:
TNT1 A 1 A_Explode(p105mmAPHE_3_sdmg,p105mmAPHE_3_srad,0,0,p105mmAPHE_3_sfullrad)
Stop
FXDeath:
TNT1 A 1 A_Explode(p105mmAPHE_3_sdmg,p105mmAPHE_3_srad,0,0,p105mmAPHE_3_sfullrad)
Stop
FCrash:
TNT1 A 1 A_Explode(p105mmAPHE_3_sdmg,p105mmAPHE_3_srad,0,0,p105mmAPHE_3_sfullrad)
Stop
}
}
ACTOR MT_105mmAPHEshell_Dummy : MTP_ShellBase_Fast
{
Speed 95
Damagetype Piercing
damage (0)
DeathSound "Medium/APExplosion"
Obituary "%o <105mm APHE] %k"
+BLOODSPLATTER
decal MT_LargeAPHit
States
{
Setter:
TNT1 A 0 A_SetUserVar("user_ttl", p105mmAPHE_ttd)
TNT1 A 0 A_SetUserVar("user_mode", 1)
TNT1 A 0 A_Jump(256, "Jumper")
Goto Jumper
Drop:
TNT1 A 0 A_CustomMissile("MT_105mmAPHEshell_Drop_Dummy", 0, 0, 0, CMF_AIMDIRECTION, velz / 2)
Stop
Death:
TNT1 A 0 A_Spawnitem("MTCEG_MediumExplosion_APHE")
TNT1 A 0 A_PlaySound("Medium/APExplosion")
TNT1 A 1
Stop
}
}
ACTOR MT_105mmAPHEshell_Drop_Dummy : MTP_ShellBase
{
Speed 60
Damagetype Piercing
gravity 0.25
damage (0)
DeathSound "Medium/APExplosion"
Obituary "%o <105mm APHE] %k"
+BLOODSPLATTER
decal MT_LargeAPHit
States
{
Setter:
TNT1 A 0 A_SetUserVar("user_ttl", 9999)
TNT1 A 0 A_SetUserVar("user_mode", 1)
TNT1 A 0 A_Jump(256, "Jumper")
Goto Jumper
Death:
TNT1 A 0 A_Spawnitem("MTCEG_MediumExplosion_APHE")
TNT1 A 0 A_PlaySound("Medium/APExplosion")
TNT1 A 1
Stop
}
}
Re: DECORATE Projectile that goes through multiple actors?
So you simply spawn a bunch of different projectiles at the exact same time with the exact same hitbox? I tried this with only one projectile type and it does not seem to work...[]Dot wrote: It is possible by using multiple projectiles that gets fired at the same time. That's how I achieved multiple target piercing effect on my mod, and yes this method worked before I made the conversion to ZScript. The downside of it that it the projectile must be shot with 100% accuracy, in my case I made the damaging projectile almost invisible save for when it hits a target and a dummy projectile that gets fired last which does the more fancier fake particle effects at 0 damage, I tested it a lot and it meet to my exceptions. It also still works when the projectile inherits FastProjectile actor.
So for example when those the main projectile does 60 damage and the weapon fires 5 of it then it will be able to pierce 5 doomimps and the faux projectile "detonates" at the last target.
I did this because the +ripper flag does not represent the behavior of how a average AP shot works in real life.
Re: DECORATE Projectile that goes through multiple actors?
Pretty much, how did you performed your test? Did you tried using your weapon against multiple doom imps that are standing in multiple lines? There is some certain enemy type which I forget that can negate this effect if I am not mistaken if you try to hit it against monster types like cacodemons that have long lasting corpse blocking during their death state then this effect wont work, the monster needs to be modified so that upon death they start losing their collision box on the first frame.Mini--Joe wrote:So you simply spawn a bunch of different projectiles at the exact same time with the exact same hitbox? I tried this with only one projectile type and it does not seem to work...
I have a damage based ZScript code that achieves the same effect which has the advance it scales dynamically depending how strong the projectile is:
Code: Select all
Mixin Class Common_Proj
{
int Dmg;
}
//Hit multiple targets.
Mixin Class MultiPiercing
{
/*
First get the victim health. If the victim health is greater
than the current projectile damage then just do normal damage and
kill the projectile, else kill the victim and proceed with normal
trajectory.
*/
//Requires Common_Proj to work!
//Mixin Common_Proj;
Override void BeginPlay()
{
Dmg = GetMissileDamage(0, 0, AAPTR_DEFAULT);
Super.BeginPlay();
}
Override int SpecialMissileHit (Actor victim)
{
int Victim_HP = victim.health;
if (!victim.player && Dmg > 0)
{
victim.DamageMobj(self, target, Dmg, damagetype, 0);
Dmg -= Victim_HP;
}
if (Dmg <= 0)
{
//Using -1 here results in double damage.
return 0;
}
return 1;
}
}