mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-31 12:30:40 +00:00
- scriptified the World Tour's flamethrower#s fireball.
Also using a better method to mark the trailing balls than checking the owner.
This commit is contained in:
parent
26d9511087
commit
82515e1d76
3 changed files with 115 additions and 253 deletions
|
@ -746,253 +746,6 @@ void movestandables_d(void)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static bool movefireball(DDukeActor* actor)
|
||||
{
|
||||
auto Owner = actor->GetOwner();
|
||||
|
||||
if (actor->sector()->lotag == 2)
|
||||
{
|
||||
actor->Destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Owner || Owner->spr.picnum != FIREBALL)
|
||||
{
|
||||
if (actor->temp_data[0] >= 1 && actor->temp_data[0] < 6)
|
||||
{
|
||||
float siz = 1.0f - (actor->temp_data[0] * 0.2f);
|
||||
DDukeActor* trail = actor->temp_actor;
|
||||
auto ball = spawn(actor, FIREBALL);
|
||||
if (ball)
|
||||
{
|
||||
actor->temp_actor = ball;
|
||||
|
||||
ball->vel.X = actor->vel.X;
|
||||
ball->vel.Z = actor->vel.Z;
|
||||
if (actor->temp_data[0] > 1)
|
||||
{
|
||||
if (trail)
|
||||
{
|
||||
ball->spr.pos = trail->temp_pos;
|
||||
ball->vel = trail->temp_pos2;
|
||||
}
|
||||
}
|
||||
double scale = actor->spr.scale.X * siz;
|
||||
ball->spr.scale = DVector2(scale, scale);
|
||||
ball->spr.cstat = actor->spr.cstat;
|
||||
ball->spr.extra = 0;
|
||||
|
||||
ball->temp_pos = ball->spr.pos;
|
||||
ball->temp_pos2 = ball->vel;
|
||||
|
||||
ChangeActorStat(ball, STAT_PROJECTILE);
|
||||
}
|
||||
}
|
||||
actor->temp_data[0]++;
|
||||
}
|
||||
if (actor->vel.Z < 15000. / 256.)
|
||||
actor->vel.Z += 200 / 256.;
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static bool weaponhitsprite(DDukeActor* proj, DDukeActor *targ, bool fireball)
|
||||
{
|
||||
if (!isWorldTour() || proj->spr.picnum != FIREBALL || fireball)
|
||||
fi.checkhitsprite(targ, proj);
|
||||
|
||||
if (targ->isPlayer())
|
||||
{
|
||||
int p = targ->spr.yint;
|
||||
auto Owner = proj->GetOwner();
|
||||
|
||||
if (ud.multimode >= 2 && fireball && Owner && Owner->isPlayer())
|
||||
{
|
||||
ps[p].numloogs = -1 - proj->spr.yint;
|
||||
}
|
||||
|
||||
S_PlayActorSound(PISTOL_BODYHIT, targ);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static bool weaponhitwall(DDukeActor *proj, walltype* wal, const DVector3 &oldpos)
|
||||
{
|
||||
if (proj->spr.picnum != RPG && proj->spr.picnum != FREEZEBLAST && proj->spr.picnum != SPIT &&
|
||||
(!isWorldTour() || proj->spr.picnum != FIREBALL) &&
|
||||
(wal->overpicnum == MIRROR || wal->picnum == MIRROR))
|
||||
{
|
||||
DAngle k = wal->delta().Angle();
|
||||
proj->spr.Angles.Yaw = k * 2 - proj->spr.Angles.Yaw;
|
||||
proj->SetOwner(proj);
|
||||
spawn(proj, TRANSPORTERSTAR);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetActor(proj, oldpos);
|
||||
fi.checkhitwall(proj, wal, proj->spr.pos, proj->spr.picnum);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static bool weaponhitsector(DDukeActor* proj, const DVector3& oldpos, bool fireball)
|
||||
{
|
||||
SetActor(proj, oldpos);
|
||||
|
||||
if (proj->vel.Z < 0)
|
||||
{
|
||||
if (proj->sector()->ceilingstat & CSTAT_SECTOR_SKY)
|
||||
if (proj->sector()->ceilingpal == 0)
|
||||
{
|
||||
proj->Destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
fi.checkhitceiling(proj->sector());
|
||||
}
|
||||
else if (fireball)
|
||||
{
|
||||
auto spawned = spawn(proj, LAVAPOOL);
|
||||
if (spawned)
|
||||
{
|
||||
spawned->SetOwner(proj);
|
||||
spawned->SetHitOwner(proj);
|
||||
spawned->spr.yint = proj->spr.yint;
|
||||
}
|
||||
proj->Destroy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void weaponcommon_d(DDukeActor* proj)
|
||||
{
|
||||
double vel = proj->vel.X;
|
||||
double velz = proj->vel.Z;
|
||||
|
||||
int p = -1;
|
||||
|
||||
auto oldpos = proj->spr.pos;
|
||||
getglobalz(proj);
|
||||
|
||||
switch (proj->spr.picnum)
|
||||
{
|
||||
case FIREBALL:
|
||||
if (movefireball(proj)) return;
|
||||
break;
|
||||
}
|
||||
|
||||
Collision coll;
|
||||
movesprite_ex(proj, DVector3(proj->spr.Angles.Yaw.ToVector() * vel, velz), CLIPMASK1, coll);
|
||||
|
||||
|
||||
if (!proj->insector())
|
||||
{
|
||||
proj->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (coll.type != kHitSprite && proj->spr.picnum != FREEZEBLAST)
|
||||
{
|
||||
if (proj->spr.pos.Z < proj->ceilingz)
|
||||
{
|
||||
coll.setSector(proj->sector());
|
||||
proj->vel.Z -= 1/256.;
|
||||
}
|
||||
else
|
||||
if ((proj->spr.pos.Z > proj->floorz && proj->sector()->lotag != 1) ||
|
||||
(proj->spr.pos.Z > proj->floorz + 16 && proj->sector()->lotag == 1))
|
||||
{
|
||||
coll.setSector(proj->sector());
|
||||
if (proj->sector()->lotag != 1)
|
||||
proj->vel.Z += 1/256.;
|
||||
}
|
||||
}
|
||||
|
||||
if (coll.type != 0)
|
||||
{
|
||||
bool fireball = (isWorldTour() && proj->spr.picnum == FIREBALL && (!proj->GetOwner() || proj->GetOwner()->spr.picnum != FIREBALL));
|
||||
|
||||
if (coll.type == kHitSprite)
|
||||
{
|
||||
if (weaponhitsprite(proj, coll.actor(), fireball)) return;
|
||||
}
|
||||
else if (coll.type == kHitWall)
|
||||
{
|
||||
if (weaponhitwall(proj, coll.hitWall, oldpos)) return;
|
||||
}
|
||||
else if (coll.type == kHitSector)
|
||||
{
|
||||
if (weaponhitsector(proj, oldpos, fireball)) return;
|
||||
}
|
||||
|
||||
if (proj->spr.picnum != SPIT)
|
||||
{
|
||||
if (proj->spr.picnum != COOLEXPLOSION1 && proj->spr.picnum != FREEZEBLAST && (!isWorldTour() || proj->spr.picnum != FIREBALL))
|
||||
{
|
||||
auto spawned = spawn(proj, EXPLOSION2);
|
||||
if (spawned)
|
||||
{
|
||||
auto scale = proj->spr.scale.X * 0.5;
|
||||
spawned->spr.scale = DVector2(scale,scale);
|
||||
if (coll.type == kHitSector)
|
||||
{
|
||||
if (proj->vel.Z < 0)
|
||||
{
|
||||
spawned->spr.cstat |= CSTAT_SPRITE_YFLIP;
|
||||
spawned->spr.pos.Z += 72;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fireball)
|
||||
{
|
||||
auto spawned = spawn(proj, EXPLOSION2);
|
||||
if (spawned)
|
||||
{
|
||||
auto scale = proj->spr.scale.X * 0.5;
|
||||
spawned->spr.scale = DVector2(scale,scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (proj->spr.picnum != COOLEXPLOSION1)
|
||||
{
|
||||
proj->Destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void moveweapons_d(void)
|
||||
{
|
||||
DukeStatIterator it(STAT_PROJECTILE);
|
||||
|
@ -1012,12 +765,6 @@ void moveweapons_d(void)
|
|||
|
||||
switch(act->spr.picnum)
|
||||
{
|
||||
case FIREBALL:
|
||||
// Twentieth Anniversary World Tour
|
||||
if (act->spr.picnum == FIREBALL && !isWorldTour()) break;
|
||||
weaponcommon_d(act);
|
||||
break;
|
||||
|
||||
case SHOTSPARK1:
|
||||
{
|
||||
double x;
|
||||
|
|
6
wadsrc/static/filter/duke.worldtour/engine/engine.def
Normal file
6
wadsrc/static/filter/duke.worldtour/engine/engine.def
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
spawnclasses
|
||||
{
|
||||
5163 = DukeFireball
|
||||
}
|
||||
|
|
@ -583,3 +583,112 @@ class DukeCoolExplosion1 : DukeProjectile // octabrain shot.
|
|||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class DukeFireball : DukeProjectile // WorldTour only
|
||||
{
|
||||
default
|
||||
{
|
||||
pic "FIREBALL";
|
||||
}
|
||||
|
||||
override bool premoveeffect()
|
||||
{
|
||||
let Owner = self.ownerActor;
|
||||
|
||||
if (self.sector.lotag == 2)
|
||||
{
|
||||
self.Destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self.detail != 1)
|
||||
{
|
||||
if (self.temp_data[0] >= 1 && self.temp_data[0] < 6)
|
||||
{
|
||||
double siz = 1.0 - (self.temp_data[0] * 0.2);
|
||||
DukeActor trail = self.temp_actor;
|
||||
let ball = self.spawn('DukeFireball');
|
||||
if (ball)
|
||||
{
|
||||
self.temp_actor = ball;
|
||||
|
||||
ball.vel.X = self.vel.X;
|
||||
ball.vel.Z = self.vel.Z;
|
||||
ball.angle = self.angle;
|
||||
if (self.temp_data[0] > 1)
|
||||
{
|
||||
if (trail)
|
||||
{
|
||||
ball.pos = trail.temp_pos;
|
||||
ball.vel = trail.temp_pos2;
|
||||
}
|
||||
}
|
||||
double scale = self.scale.X * siz;
|
||||
ball.scale = (scale, scale);
|
||||
ball.cstat = self.cstat;
|
||||
ball.extra = 0;
|
||||
|
||||
ball.temp_pos = ball.pos;
|
||||
ball.temp_pos2 = ball.vel;
|
||||
ball.detail = 1;
|
||||
|
||||
ball.ChangeStat(STAT_PROJECTILE);
|
||||
}
|
||||
}
|
||||
self.temp_data[0]++;
|
||||
}
|
||||
if (self.vel.Z < 15000. / 256.)
|
||||
self.vel.Z += 200 / 256.;
|
||||
return false;
|
||||
}
|
||||
|
||||
override bool weaponhitsprite_pre(DukeActor targ)
|
||||
{
|
||||
if (self.detail != 1)
|
||||
return super.weaponhitsprite_pre(targ);
|
||||
return false;
|
||||
}
|
||||
|
||||
override bool weaponhitplayer(DukeActor targ)
|
||||
{
|
||||
let p = targ.GetPlayer();
|
||||
let Owner = self.ownerActor;
|
||||
|
||||
if (p && ud.multimode >= 2 && Owner && Owner.isPlayer())
|
||||
{
|
||||
p.numloogs = -1 - self.yint;
|
||||
}
|
||||
return Super.weaponhitplayer(targ);
|
||||
}
|
||||
|
||||
override bool weaponhitsector()
|
||||
{
|
||||
if (super.weaponhitsector()) return true;
|
||||
if (self.detail != 1)
|
||||
{
|
||||
let spawned = self.spawn('DukeLavapool');
|
||||
if (spawned)
|
||||
{
|
||||
spawned.ownerActor = self;
|
||||
spawned.hitOwnerActor = self;
|
||||
spawned.yint = self.yint;
|
||||
}
|
||||
self.Destroy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
override bool animate(tspritetype tspr)
|
||||
{
|
||||
tspr.shade = -127;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue