- Added flags SXF_CLEARCALLERTID, SXF_MULTIPLYSPEED, and SXF_TRANSFERSCALE for A_SpawnItemEx.

SVN r4188 (trunk)
This commit is contained in:
Randy Heit 2013-03-20 03:07:45 +00:00
parent de20936b13
commit 277d59b2bb
3 changed files with 133 additions and 91 deletions

View file

@ -1716,102 +1716,127 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_TakeFromTarget)
// Common code for A_SpawnItem and A_SpawnItemEx // Common code for A_SpawnItem and A_SpawnItemEx
// //
//=========================================================================== //===========================================================================
enum SIX_Flags enum SIX_Flags
{ {
SIXF_TRANSFERTRANSLATION=1, SIXF_TRANSFERTRANSLATION = 1 << 0,
SIXF_ABSOLUTEPOSITION=2, SIXF_ABSOLUTEPOSITION = 1 << 1,
SIXF_ABSOLUTEANGLE=4, SIXF_ABSOLUTEANGLE = 1 << 2,
SIXF_ABSOLUTEVELOCITY=8, SIXF_ABSOLUTEVELOCITY = 1 << 3,
SIXF_SETMASTER=16, SIXF_SETMASTER = 1 << 4,
SIXF_NOCHECKPOSITION=32, SIXF_NOCHECKPOSITION = 1 << 5,
SIXF_TELEFRAG=64, SIXF_TELEFRAG = 1 << 6,
// 128 is used by Skulltag! SIXF_CLIENTSIDE = 1 << 7, // only used by Skulldronum
SIXF_TRANSFERAMBUSHFLAG=256, SIXF_TRANSFERAMBUSHFLAG = 1 << 8,
SIXF_TRANSFERPITCH=512, SIXF_TRANSFERPITCH = 1 << 9,
SIXF_TRANSFERPOINTERS=1024, SIXF_TRANSFERPOINTERS = 1 << 10,
SIXF_USEBLOODCOLOR=2048, SIXF_USEBLOODCOLOR = 1 << 11,
SIXF_CLEARCALLERTID = 1 << 12,
SIXF_MULTIPLYSPEED = 1 << 13,
SIXF_TRANSFERSCALE = 1 << 14,
}; };
static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
{ {
if (mo) if (mo == NULL)
{ {
AActor * originator = self; return false;
}
AActor *originator = self;
if (!(mo->flags2 & MF2_DONTTRANSLATE)) if (!(mo->flags2 & MF2_DONTTRANSLATE))
{
if (flags & SIXF_TRANSFERTRANSLATION)
{ {
if (flags & SIXF_TRANSFERTRANSLATION) mo->Translation = self->Translation;
{
mo->Translation = self->Translation;
}
else if (flags & SIXF_USEBLOODCOLOR)
{
// [XA] Use the spawning actor's BloodColor to translate the newly-spawned object.
PalEntry bloodcolor = self->GetBloodColor();
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
}
} }
if (flags & SIXF_TRANSFERPOINTERS) else if (flags & SIXF_USEBLOODCOLOR)
{ {
mo->target = self->target; // [XA] Use the spawning actor's BloodColor to translate the newly-spawned object.
mo->master = self->master; // This will be overridden later if SIXF_SETMASTER is set PalEntry bloodcolor = self->GetBloodColor();
mo->tracer = self->tracer; mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
} }
}
if (flags & SIXF_TRANSFERPOINTERS)
{
mo->target = self->target;
mo->master = self->master; // This will be overridden later if SIXF_SETMASTER is set
mo->tracer = self->tracer;
}
mo->angle=self->angle; mo->angle = self->angle;
if (flags & SIXF_TRANSFERPITCH) mo->pitch = self->pitch; if (flags & SIXF_TRANSFERPITCH)
while (originator && originator->isMissile()) originator = originator->target; {
mo->pitch = self->pitch;
}
while (originator && originator->isMissile())
{
originator = originator->target;
}
if (flags & SIXF_TELEFRAG) if (flags & SIXF_TELEFRAG)
{
P_TeleportMove(mo, mo->x, mo->y, mo->z, true);
// This is needed to ensure consistent behavior.
// Otherwise it will only spawn if nothing gets telefragged
flags |= SIXF_NOCHECKPOSITION;
}
if (mo->flags3 & MF3_ISMONSTER)
{
if (!(flags & SIXF_NOCHECKPOSITION) && !P_TestMobjLocation(mo))
{ {
P_TeleportMove(mo, mo->x, mo->y, mo->z, true); // The monster is blocked so don't spawn it at all!
// This is needed to ensure consistent behavior. mo->ClearCounters();
// Otherwise it will only spawn if nothing gets telefragged mo->Destroy();
flags |= SIXF_NOCHECKPOSITION; return false;
} }
if (mo->flags3&MF3_ISMONSTER) else if (originator)
{ {
if (!(flags&SIXF_NOCHECKPOSITION) && !P_TestMobjLocation(mo)) if (originator->flags3 & MF3_ISMONSTER)
{ {
// The monster is blocked so don't spawn it at all! // If this is a monster transfer all friendliness information
mo->ClearCounters(); mo->CopyFriendliness(originator, true);
mo->Destroy(); if (flags & SIXF_SETMASTER) mo->master = originator; // don't let it attack you (optional)!
return false;
} }
else if (originator) else if (originator->player)
{ {
if (originator->flags3&MF3_ISMONSTER) // A player always spawns a monster friendly to him
mo->flags |= MF_FRIENDLY;
mo->SetFriendPlayer(originator->player);
AActor * attacker=originator->player->attacker;
if (attacker)
{ {
// If this is a monster transfer all friendliness information if (!(attacker->flags&MF_FRIENDLY) ||
mo->CopyFriendliness(originator, true); (deathmatch && attacker->FriendPlayer!=0 && attacker->FriendPlayer!=mo->FriendPlayer))
if (flags&SIXF_SETMASTER) mo->master = originator; // don't let it attack you (optional)!
}
else if (originator->player)
{
// A player always spawns a monster friendly to him
mo->flags |= MF_FRIENDLY;
mo->SetFriendPlayer(originator->player);
AActor * attacker=originator->player->attacker;
if (attacker)
{ {
if (!(attacker->flags&MF_FRIENDLY) || // Target the monster which last attacked the player
(deathmatch && attacker->FriendPlayer!=0 && attacker->FriendPlayer!=mo->FriendPlayer)) mo->LastHeard = mo->target = attacker;
{
// Target the monster which last attacked the player
mo->LastHeard = mo->target = attacker;
}
} }
} }
} }
} }
else if (!(flags & SIXF_TRANSFERPOINTERS))
{
// If this is a missile or something else set the target to the originator
mo->target=originator? originator : self;
}
} }
else if (!(flags & SIXF_TRANSFERPOINTERS))
{
// If this is a missile or something else set the target to the originator
mo->target = originator ? originator : self;
}
if (flags & SIXF_TRANSFERSCALE)
{
mo->scaleX = self->scaleX;
mo->scaleY = self->scaleY;
}
if (flags & SIXF_TRANSFERAMBUSHFLAG)
{
mo->flags = (mo->flags & ~MF_AMBUSH) | (self->flags & MF_AMBUSH);
}
if (flags & SIXF_CLEARCALLERTID)
{
self->RemoveFromHash();
self->tid = 0;
}
return true; return true;
} }
@ -1861,7 +1886,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
self->y + FixedMul(distance, finesine[self->angle>>ANGLETOFINESHIFT]), self->y + FixedMul(distance, finesine[self->angle>>ANGLETOFINESHIFT]),
self->z - self->floorclip + self->GetBobOffset() + zheight, ALLOW_REPLACE); self->z - self->floorclip + self->GetBobOffset() + zheight, ALLOW_REPLACE);
int flags = (transfer_translation? SIXF_TRANSFERTRANSLATION:0) + (useammo? SIXF_SETMASTER:0); int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0);
bool res = InitSpawnedItem(self, mo, flags); bool res = InitSpawnedItem(self, mo, flags);
ACTION_SET_RESULT(res); // for an inventory item's use state ACTION_SET_RESULT(res); // for an inventory item's use state
} }
@ -1875,7 +1900,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
//=========================================================================== //===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
{ {
ACTION_PARAM_START(10); ACTION_PARAM_START(11);
ACTION_PARAM_CLASS(missile, 0); ACTION_PARAM_CLASS(missile, 0);
ACTION_PARAM_FIXED(xofs, 1); ACTION_PARAM_FIXED(xofs, 1);
ACTION_PARAM_FIXED(yofs, 2); ACTION_PARAM_FIXED(yofs, 2);
@ -1886,6 +1911,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
ACTION_PARAM_ANGLE(Angle, 7); ACTION_PARAM_ANGLE(Angle, 7);
ACTION_PARAM_INT(flags, 8); ACTION_PARAM_INT(flags, 8);
ACTION_PARAM_INT(chance, 9); ACTION_PARAM_INT(chance, 9);
ACTION_PARAM_INT(tid, 10);
if (!missile) if (!missile)
{ {
@ -1928,17 +1954,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
xvel = newxvel; xvel = newxvel;
} }
AActor * mo = Spawn(missile, x, y, self->z - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE); AActor *mo = Spawn(missile, x, y, self->z - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE);
bool res = InitSpawnedItem(self, mo, flags); bool res = InitSpawnedItem(self, mo, flags);
ACTION_SET_RESULT(res); // for an inventory item's use state ACTION_SET_RESULT(res); // for an inventory item's use state
if (mo) if (res)
{ {
mo->velx = xvel; if (tid != 0)
mo->vely = yvel; {
mo->velz = zvel; assert(mo->tid == 0);
mo->tid = tid;
mo->AddToHash();
}
if (flags & SIXF_MULTIPLYSPEED)
{
mo->velx = FixedMul(xvel, mo->Speed);
mo->vely = FixedMul(yvel, mo->Speed);
mo->velz = FixedMul(zvel, mo->Speed);
}
else
{
mo->velx = xvel;
mo->vely = yvel;
mo->velz = zvel;
}
mo->angle = Angle; mo->angle = Angle;
if (flags & SIXF_TRANSFERAMBUSHFLAG)
mo->flags = (mo->flags&~MF_AMBUSH) | (self->flags & MF_AMBUSH);
} }
} }

View file

@ -210,7 +210,7 @@ ACTOR Actor native //: Thinker
action native A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT); action native A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT);
action native A_TakeInventory(class<Inventory> itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT); action native A_TakeInventory(class<Inventory> itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT);
action native A_SpawnItem(class<Actor> itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false); action native A_SpawnItem(class<Actor> itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
action native A_SpawnItemEx(class<Actor> itemtype, float xofs = 0, float yofs = 0, float zofs = 0, float xvel = 0, float yvel = 0, float zvel = 0, float angle = 0, int flags = 0, int failchance = 0); action native A_SpawnItemEx(class<Actor> itemtype, float xofs = 0, float yofs = 0, float zofs = 0, float xvel = 0, float yvel = 0, float zvel = 0, float angle = 0, int flags = 0, int failchance = 0, int tid=0);
action native A_Print(string whattoprint, float time = 0, string fontname = ""); action native A_Print(string whattoprint, float time = 0, string fontname = "");
action native A_PrintBold(string whattoprint, float time = 0, string fontname = ""); action native A_PrintBold(string whattoprint, float time = 0, string fontname = "");
action native A_Log(string whattoprint); action native A_Log(string whattoprint);

View file

@ -41,19 +41,22 @@ const int FBF_NOFLASH = 16;
const int FBF_NORANDOMPUFFZ = 32; const int FBF_NORANDOMPUFFZ = 32;
// Flags for A_SpawnItemEx // Flags for A_SpawnItemEx
const int SXF_TRANSFERTRANSLATION=1; const int SXF_TRANSFERTRANSLATION = 1;
const int SXF_ABSOLUTEPOSITION=2; const int SXF_ABSOLUTEPOSITION = 2;
const int SXF_ABSOLUTEANGLE=4; const int SXF_ABSOLUTEANGLE = 4;
const int SXF_ABSOLUTEMOMENTUM=8; const int SXF_ABSOLUTEMOMENTUM = 8;
const int SXF_ABSOLUTEVELOCITY=8; const int SXF_ABSOLUTEVELOCITY = 8;
const int SXF_SETMASTER=16; const int SXF_SETMASTER = 16;
const int SXF_NOCHECKPOSITION = 32; const int SXF_NOCHECKPOSITION = 32;
const int SXF_TELEFRAG=64; const int SXF_TELEFRAG = 64;
const int SXF_CLIENTSIDE=128; // only used by Skulltag const int SXF_CLIENTSIDE = 128; // only used by Skulltag
const int SXF_TRANSFERAMBUSHFLAG=256; const int SXF_TRANSFERAMBUSHFLAG = 256;
const int SXF_TRANSFERPITCH=512; const int SXF_TRANSFERPITCH = 512;
const int SXF_TRANSFERPOINTERS=1024; const int SXF_TRANSFERPOINTERS = 1024;
const int SXF_USEBLOODCOLOR=2048; const int SXF_USEBLOODCOLOR = 2048;
const int SXF_CLEARCALLERTID = 4096;
const int SXF_MULTIPLYSPEED = 8192;
const int SXF_TRANSFERSCALE = 16384;
// Flags for A_Chase // Flags for A_Chase
const int CHF_FASTCHASE = 1; const int CHF_FASTCHASE = 1;