Classes:FastProjectile
Note: Wait! Stop! You do not need to copy this actor's code into your project! Here's why:
|
Fast projectile | |||
---|---|---|---|
Actor type | Internal | Game | (ZDoom) |
DoomEd Number | None | Class Name | FastProjectile |
Classes: FastProjectile
→BlasterFX1
→CFlameMissile
→MageWandMissile
A base class for all fast projectiles, with special movement code. Standard missile code doesn't manage speeds greater than about 60 very well. To create a fast-moving projectile, inherit from this class or one of its children classes.
The MissileType property has a special use for fast projectiles. When one is specified, several (at least eight) are spawned every tic in the projectile's wake, as a trail. The greater the speed, and the smaller (yet non-null) the radius, the more numerous the steps. See MageWandMissile for an example of use, and MageWandSmoke for how a trail actor might be defined.
The MissileHeight property also has a special use for fast projectiles. Normally, trails are spawned 8 map units lower than the projectile itself. Using this property, the trail's height can be adjusted to different heights. To spawn the trail at the same height as the projectile, use a MissileHeight of 8.
Ripper projectiles will also cause a lot of bloodshed, which can slow down a game's FPS quite considerably, so use with caution.
Trails spawned by FastProjectile inherit their pitch and set the projectile as their target. To get the owner (for explosions, ownership, etc), use the GETOWNER flag.
Specific features
FastProjectile is not entirely identical to regular projectiles; aside from special handling of collision for high velocities and the ability to spawn trails, they also have a few quirks authors should be aware of:
- Fast projectiles can't be subjected to gravity; the gravity property and the NOGRAVITY flag values are ignored.
- Due to the movement code, fast projectiles are destroyed if they are incapable of moving or hit any plane. Hence, bounce properties that imply losing momentum (such as Bouncetype "Doom") or other plane-related flags don't work.
- Fast projectiles ignore the Death.Sky state sequence and always disappear when hitting a sky.
ZScript definition
Note: The ZScript definition below is for reference and may be different in the current version of GZDoom.The most up-to-date version of this code can be found on GZDoom GitHub. |
class FastProjectile : Actor { Default { Projectile; MissileHeight 0; } virtual void Effect() { class<Actor> trail = MissileName; if (trail != null) { double hitz = pos.z - 8; if (hitz < floorz) { hitz = floorz; } // Do not clip this offset to the floor. hitz += MissileHeight; Actor act = Spawn (trail, (pos.xy, hitz), ALLOW_REPLACE); if (act != null) { if (bGetOwner && target != null) act.target = target; else act.target = self; act.angle = angle; act.pitch = pitch; } } } //---------------------------------------------------------------------------- // // AFastProjectile :: Tick // // Thinker for the ultra-fast projectiles used by Heretic and Hexen // //---------------------------------------------------------------------------- override void Tick () { ClearInterpolation(); double oldz = pos.Z; if (isFrozen()) return; // [RH] Ripping is a little different than it was in Hexen FCheckPosition tm; tm.DoRipping = bRipper; int count = 8; if (radius > 0) { while (abs(Vel.X) >= radius * count || abs(Vel.Y) >= radius * count) { // we need to take smaller steps. count += count; } } if (height > 0) { while (abs(Vel.Z) >= height * count) { count += count; } } // Handle movement bool ismoved = Vel != (0, 0, 0) // Check Z position set during previous tick. // It should be strictly equal to the argument of SetZ() function. || ( (pos.Z != floorz ) /* Did it hit the floor? */ && (pos.Z != ceilingz - Height) /* Did it hit the ceiling? */ ); if (ismoved) { // force some lateral movement so that collision detection works as intended. if (bMissile && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage()) { VelFromAngle(MinVel); } Vector3 frac = Vel / count; int changexy = frac.X != 0 || frac.Y != 0; int ripcount = count / 8; for (int i = 0; i < count; i++) { if (changexy) { if (--ripcount <= 0) { tm.ClearLastRipped(); // [RH] Do rip damage each step, like Hexen } if (!TryMove (Pos.XY + frac.XY, true, false, tm)) { // Blocked move if (!bSkyExplode) { let l = tm.ceilingline; if (l && l.backsector && l.backsector.GetTexture(sector.ceiling) == skyflatnum) { let posr = PosRelative(l.backsector); if (pos.Z >= l.backsector.ceilingplane.ZatPoint(posr.XY)) { // Hack to prevent missiles exploding against the sky. // Does not handle sky floors. Destroy (); return; } } // [RH] Don't explode on horizon lines. if (BlockingLine != NULL && BlockingLine.special == Line_Horizon) { Destroy (); return; } } ExplodeMissile (BlockingLine, BlockingMobj); return; } } AddZ(frac.Z); UpdateWaterLevel (); oldz = pos.Z; if (oldz <= floorz) { // Hit the floor if (floorpic == skyflatnum && !bSkyExplode) { // [RH] Just remove the missile without exploding it // if this is a sky floor. Destroy (); return; } SetZ(floorz); HitFloor (); Destructible.ProjectileHitPlane(self, SECPART_Floor); ExplodeMissile (NULL, NULL); return; } if (pos.Z + height > ceilingz) { // Hit the ceiling if (ceilingpic == skyflatnum && !bSkyExplode) { Destroy (); return; } SetZ(ceilingz - Height); Destructible.ProjectileHitPlane(self, SECPART_Ceiling); ExplodeMissile (NULL, NULL); return; } CheckPortalTransition(); if (changexy && ripcount <= 0) { ripcount = count >> 3; // call the 'Effect' method. Effect(); } } } if (!CheckNoDelay()) return; // freed itself // Advance the state if (tics != -1) { if (tics > 0) tics--; while (!tics) { if (!SetState (CurState.NextState)) { // mobj was removed return; } } } } }
DECORATE definition
Note: This is legacy code, kept for archival purposes only. DECORATE is deprecated in GZDoom and is completely superseded by ZScript. GZDoom internally uses the ZScript definition above. |
Actor FastProjectile native { Projectile MissileHeight 0 }
- Chex Quest actors
- Chex Quest internal actors
- Chex Quest 3 actors
- Chex Quest 3 internal actors
- Doom actors
- Doom internal actors
- Doom II actors
- Doom II internal actors
- Heretic actors
- Heretic internal actors
- Hexen actors
- Hexen internal actors
- Strife actors
- Strife internal actors
- ZDoom actors
- ZDoom internal actors
- Internal