- Added support for ST's QUARTERGRAVITY flag.

- Added a generalized version of Skulltag's A_CheckRailReload function.
- Fixed: DrawImage didn't take 0 as a valid image index.
- Added Gez's RandomSpawner submission with significant changes.
- Added optional blocks for MAPINFO map definitions. ZDoom doesn't use
  this feature itself but it allows other ports based on ZDoom
  to implement their own sets of options without making such a MAPINFO 
  unreadable by ZDoom.


SVN r1044 (trunk)
This commit is contained in:
Christoph Oelckers 2008-06-22 09:13:19 +00:00
commit 4ff07b68ee
16 changed files with 383 additions and 58 deletions

View file

@ -6,6 +6,7 @@
#include "s_sound.h"
#include "a_doomglobal.h"
#include "statnums.h"
#include "thingdef/thingdef.h"
void A_Fire (AActor *); // from m_archvile.cpp
@ -242,12 +243,18 @@ void A_BrainSpit (AActor *self)
if (targ != NULL)
{
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = RUNTIME_CLASS(ASpawnShot);
// spawn brain missile
spit = P_SpawnMissile (self, targ, RUNTIME_CLASS(ASpawnShot));
spit = P_SpawnMissile (self, targ, spawntype);
if (spit != NULL)
{
spit->target = targ;
spit->master = self;
// [RH] Do this correctly for any trajectory. Doom would divide by 0
// if the target had the same y coordinate as the spitter.
if ((spit->momx | spit->momy) == 0)
@ -265,7 +272,15 @@ void A_BrainSpit (AActor *self)
spit->reactiontime /= spit->state->GetTics();
}
S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE);
if (index >= 0)
{
S_Sound(self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NONE);
}
else
{
// compatibility fallback
S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE);
}
}
}
@ -275,51 +290,109 @@ void A_SpawnFly (AActor *self)
AActor *fog;
AActor *targ;
int r;
const char *type;
if (--self->reactiontime)
return; // still flying
targ = self->target;
// First spawn teleport fire.
fog = Spawn<ASpawnFire> (targ->x, targ->y, targ->z, ALLOW_REPLACE);
S_Sound (fog, CHAN_BODY, "brain/spawn", 1, ATTN_NORM);
// Randomly select monster to spawn.
r = pr_spawnfly ();
// Probability distribution (kind of :),
// decreasing likelihood.
if (r < 50) type = "DoomImp";
else if (r < 90) type = "Demon";
else if (r < 120) type = "Spectre";
else if (r < 130) type = "PainElemental";
else if (r < 160) type = "Cacodemon";
else if (r < 162) type = "Archvile";
else if (r < 172) type = "Revenant";
else if (r < 192) type = "Arachnotron";
else if (r < 222) type = "Fatso";
else if (r < 246) type = "HellKnight";
else type = "BaronOfHell";
newmobj = Spawn (type, targ->x, targ->y, targ->z, ALLOW_REPLACE);
if (newmobj != NULL)
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
// First spawn teleport fire.
if (index >= 0)
{
// Make the new monster hate what the boss eye hates
AActor *eye = self->target;
if (eye != NULL)
spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype != NULL)
{
newmobj->CopyFriendliness (eye, false);
fog = Spawn (spawntype, targ->x, targ->y, targ->z, ALLOW_REPLACE);
if (fog != NULL) S_Sound (fog, CHAN_BODY, fog->SeeSound, 1, ATTN_NORM);
}
if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true))
newmobj->SetState (newmobj->SeeState);
}
else
{
fog = Spawn<ASpawnFire> (targ->x, targ->y, targ->z, ALLOW_REPLACE);
if (fog != NULL) S_Sound (fog, CHAN_BODY, "brain/spawn", 1, ATTN_NORM);
}
if (!(newmobj->ObjectFlags & OF_EuthanizeMe))
FName SpawnName;
if (self->master != NULL)
{
FDropItem *di; // di will be our drop item list iterator
FDropItem *drop; // while drop stays as the reference point.
int n=0;
drop = di = GetDropItems(self->master->GetClass());
if (di != NULL)
{
// telefrag anything in this spot
P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true);
while (di != NULL)
{
if (di->Name != NAME_None)
{
if (di->amount < 0) di->amount = 1; // default value is -1, we need a positive value.
n += di->amount; // this is how we can weight the list.
di = di->Next;
}
}
di = drop;
n = pr_spawnfly(n);
while (n > 0)
{
if (di->Name != NAME_None)
{
n -= di->amount; // logically, none of the -1 values have survived by now.
if (n > -1) di = di->Next; // If we get into the negatives, a spawnfog could be spawned...
// It would mean we've reached the end of the list of monsters.
}
}
SpawnName = di->Name;
}
}
if (SpawnName == NAME_None)
{
const char *type;
// Randomly select monster to spawn.
r = pr_spawnfly ();
// Probability distribution (kind of :),
// decreasing likelihood.
if (r < 50) type = "DoomImp";
else if (r < 90) type = "Demon";
else if (r < 120) type = "Spectre";
else if (r < 130) type = "PainElemental";
else if (r < 160) type = "Cacodemon";
else if (r < 162) type = "Archvile";
else if (r < 172) type = "Revenant";
else if (r < 192) type = "Arachnotron";
else if (r < 222) type = "Fatso";
else if (r < 246) type = "HellKnight";
else type = "BaronOfHell";
SpawnName = type;
}
spawntype = PClass::FindClass(SpawnName);
if (spawntype != NULL)
{
newmobj = Spawn (spawntype, targ->x, targ->y, targ->z, ALLOW_REPLACE);
if (newmobj != NULL)
{
// Make the new monster hate what the boss eye hates
AActor *eye = self->target;
if (eye != NULL)
{
newmobj->CopyFriendliness (eye, false);
}
if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true))
newmobj->SetState (newmobj->SeeState);
if (!(newmobj->ObjectFlags & OF_EuthanizeMe))
{
// telefrag anything in this spot
P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true);
}
}
}
@ -375,3 +448,4 @@ void DBrainState::Serialize (FArchive &arc)
arc << SerialTarget;
}
}