mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
20d3a72307
18 changed files with 246 additions and 150 deletions
|
@ -661,6 +661,10 @@ public:
|
||||||
// Adds the item to this actor's inventory and sets its Owner.
|
// Adds the item to this actor's inventory and sets its Owner.
|
||||||
virtual void AddInventory (AInventory *item);
|
virtual void AddInventory (AInventory *item);
|
||||||
|
|
||||||
|
// Give an item to the actor and pick it up.
|
||||||
|
// Returns true if the item pickup succeeded.
|
||||||
|
virtual bool GiveInventory (PClassInventory *type, int amount, bool givecheat = false);
|
||||||
|
|
||||||
// Removes the item from the inventory list.
|
// Removes the item from the inventory list.
|
||||||
virtual void RemoveInventory (AInventory *item);
|
virtual void RemoveInventory (AInventory *item);
|
||||||
|
|
||||||
|
@ -961,6 +965,7 @@ public:
|
||||||
void CheckSectorTransition(sector_t *oldsec);
|
void CheckSectorTransition(sector_t *oldsec);
|
||||||
void UpdateRenderSectorList();
|
void UpdateRenderSectorList();
|
||||||
void ClearRenderSectorList();
|
void ClearRenderSectorList();
|
||||||
|
void ClearRenderLineList();
|
||||||
|
|
||||||
// info for drawing
|
// info for drawing
|
||||||
// NOTE: The first member variable *must* be snext.
|
// NOTE: The first member variable *must* be snext.
|
||||||
|
@ -1097,7 +1102,8 @@ public:
|
||||||
|
|
||||||
// a linked list of sectors where this object appears
|
// a linked list of sectors where this object appears
|
||||||
struct msecnode_t *touching_sectorlist; // phares 3/14/98
|
struct msecnode_t *touching_sectorlist; // phares 3/14/98
|
||||||
struct msecnode_t *render_sectorlist; // same for cross-portal rendering
|
struct msecnode_t *render_sectorlist; // same for cross-sectorportal rendering
|
||||||
|
struct portnode_t *render_portallist; // and for cross-lineportal
|
||||||
|
|
||||||
|
|
||||||
TObjPtr<AInventory> Inventory; // [RH] This actor's inventory
|
TObjPtr<AInventory> Inventory; // [RH] This actor's inventory
|
||||||
|
|
|
@ -2439,32 +2439,7 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AWeapon *savedPendingWeap = actor->player != NULL? actor->player->PendingWeapon : NULL;
|
actor->GiveInventory(info, amount);
|
||||||
bool hadweap = actor->player != NULL ? actor->player->ReadyWeapon != NULL : true;
|
|
||||||
|
|
||||||
AInventory *item = static_cast<AInventory *>(Spawn (info));
|
|
||||||
|
|
||||||
// This shouldn't count for the item statistics!
|
|
||||||
item->ClearCounters();
|
|
||||||
if (info->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup)) ||
|
|
||||||
info->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
|
|
||||||
{
|
|
||||||
static_cast<ABasicArmorPickup*>(item)->SaveAmount *= amount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->Amount = amount;
|
|
||||||
}
|
|
||||||
if (!item->CallTryPickup (actor))
|
|
||||||
{
|
|
||||||
item->Destroy ();
|
|
||||||
}
|
|
||||||
// If the item was a weapon, don't bring it up automatically
|
|
||||||
// unless the player was not already using a weapon.
|
|
||||||
if (savedPendingWeap != NULL && hadweap)
|
|
||||||
{
|
|
||||||
actor->player->PendingWeapon = savedPendingWeap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
|
@ -514,7 +514,7 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor
|
||||||
AActor *realme = actor->player->mo->tracer;
|
AActor *realme = actor->player->mo->tracer;
|
||||||
int realstyle = actor->player->MorphStyle;
|
int realstyle = actor->player->MorphStyle;
|
||||||
int realhealth = actor->health;
|
int realhealth = actor->health;
|
||||||
if (P_UndoPlayerMorph(actor->player, actor->player, !!(actor->player->MorphStyle & MORPH_UNDOBYDEATHFORCED)))
|
if (P_UndoPlayerMorph(actor->player, actor->player, 0, !!(actor->player->MorphStyle & MORPH_UNDOBYDEATHFORCED)))
|
||||||
{
|
{
|
||||||
*morphed = realme;
|
*morphed = realme;
|
||||||
*morphedstyle = realstyle;
|
*morphedstyle = realstyle;
|
||||||
|
|
|
@ -575,47 +575,6 @@ const char *cht_Morph (player_t *player, PClassPlayerPawn *morphclass, bool quic
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GiveSpawner (player_t *player, PClassInventory *type, int amount)
|
|
||||||
{
|
|
||||||
if (player->mo == NULL || player->health <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AInventory *item = static_cast<AInventory *>
|
|
||||||
(Spawn (type, player->mo->Pos(), NO_REPLACE));
|
|
||||||
if (item != NULL)
|
|
||||||
{
|
|
||||||
if (amount > 0)
|
|
||||||
{
|
|
||||||
if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup)))
|
|
||||||
{
|
|
||||||
if (static_cast<ABasicArmorPickup*>(item)->SaveAmount != 0)
|
|
||||||
{
|
|
||||||
static_cast<ABasicArmorPickup*>(item)->SaveAmount *= amount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static_cast<ABasicArmorPickup*>(item)->SaveAmount *= amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
|
|
||||||
{
|
|
||||||
static_cast<ABasicArmorBonus*>(item)->SaveAmount *= amount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->Amount = MIN (amount, item->MaxAmount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item->ClearCounters();
|
|
||||||
if (!item->CallTryPickup (player->mo))
|
|
||||||
{
|
|
||||||
item->Destroy ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cht_Give (player_t *player, const char *name, int amount)
|
void cht_Give (player_t *player, const char *name, int amount)
|
||||||
{
|
{
|
||||||
enum { ALL_NO, ALL_YES, ALL_YESYES } giveall;
|
enum { ALL_NO, ALL_YES, ALL_YESYES } giveall;
|
||||||
|
@ -643,28 +602,14 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
if (stricmp (name, "health") == 0)
|
if (stricmp (name, "health") == 0)
|
||||||
{
|
{
|
||||||
if (amount > 0)
|
if (amount > 0)
|
||||||
{
|
|
||||||
if (player->mo)
|
|
||||||
{
|
{
|
||||||
player->mo->health += amount;
|
player->mo->health += amount;
|
||||||
player->health = player->mo->health;
|
player->health = player->mo->health;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
player->health += amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (player->mo != NULL)
|
|
||||||
{
|
{
|
||||||
player->health = player->mo->health = player->mo->GetMaxHealth();
|
player->health = player->mo->health = player->mo->GetMaxHealth();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
player->health = deh.GodHealth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (giveall || stricmp (name, "backpack") == 0)
|
if (giveall || stricmp (name, "backpack") == 0)
|
||||||
|
@ -673,7 +618,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
type = PClass::FindActor(gameinfo.backpacktype);
|
type = PClass::FindActor(gameinfo.backpacktype);
|
||||||
if (type != NULL)
|
if (type != NULL)
|
||||||
{
|
{
|
||||||
GiveSpawner (player, static_cast<PClassInventory *>(type), 1);
|
player->mo->GiveInventory(static_cast<PClassInventory *>(type), 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!giveall)
|
if (!giveall)
|
||||||
|
@ -778,7 +723,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
AWeapon *def = (AWeapon*)GetDefaultByType (type);
|
AWeapon *def = (AWeapon*)GetDefaultByType (type);
|
||||||
if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
|
if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
|
||||||
{
|
{
|
||||||
GiveSpawner (player, static_cast<PClassInventory *>(type), 1);
|
player->mo->GiveInventory(static_cast<PClassInventory *>(type), 1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -805,7 +750,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
// Do not give replaced items unless using "give everything"
|
// Do not give replaced items unless using "give everything"
|
||||||
if (giveall == ALL_YESYES || type->GetReplacement() == type)
|
if (giveall == ALL_YESYES || type->GetReplacement() == type)
|
||||||
{
|
{
|
||||||
GiveSpawner (player, static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount);
|
player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -827,7 +772,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
// Do not give replaced items unless using "give everything"
|
// Do not give replaced items unless using "give everything"
|
||||||
if (giveall == ALL_YESYES || type->GetReplacement() == type)
|
if (giveall == ALL_YESYES || type->GetReplacement() == type)
|
||||||
{
|
{
|
||||||
GiveSpawner (player, static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount);
|
player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -847,7 +792,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GiveSpawner (player, static_cast<PClassInventory *>(type), amount);
|
player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount, true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -723,7 +723,7 @@ lightlist_t * P_GetPlaneLight(sector_t * sector, secplane_t * plane, bool unders
|
||||||
TArray<lightlist_t> &lightlist = sector->e->XFloor.lightlist;
|
TArray<lightlist_t> &lightlist = sector->e->XFloor.lightlist;
|
||||||
|
|
||||||
double planeheight=plane->ZatPoint(sector->centerspot);
|
double planeheight=plane->ZatPoint(sector->centerspot);
|
||||||
if(underside) planeheight--;
|
if(underside) planeheight-= EQUAL_EPSILON;
|
||||||
|
|
||||||
for(i = 1; i < lightlist.Size(); i++)
|
for(i = 1; i < lightlist.Size(); i++)
|
||||||
if (lightlist[i].plane.ZatPoint(sector->centerspot) <= planeheight)
|
if (lightlist[i].plane.ZatPoint(sector->centerspot) <= planeheight)
|
||||||
|
|
|
@ -1142,48 +1142,6 @@ static void ClearInventory (AActor *activator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// DoGiveInv
|
|
||||||
//
|
|
||||||
// Gives an item to a single actor.
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
static void DoGiveInv (AActor *actor, PClassActor *info, int amount)
|
|
||||||
{
|
|
||||||
AWeapon *savedPendingWeap = actor->player != NULL
|
|
||||||
? actor->player->PendingWeapon : NULL;
|
|
||||||
bool hadweap = actor->player != NULL ? actor->player->ReadyWeapon != NULL : true;
|
|
||||||
|
|
||||||
AInventory *item = static_cast<AInventory *>(Spawn (info));
|
|
||||||
|
|
||||||
// This shouldn't count for the item statistics!
|
|
||||||
item->ClearCounters();
|
|
||||||
if (info->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup)))
|
|
||||||
{
|
|
||||||
static_cast<ABasicArmorPickup*>(item)->SaveAmount *= amount;
|
|
||||||
}
|
|
||||||
else if (info->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
|
|
||||||
{
|
|
||||||
static_cast<ABasicArmorBonus*>(item)->SaveAmount *= amount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->Amount = amount;
|
|
||||||
}
|
|
||||||
if (!item->CallTryPickup (actor))
|
|
||||||
{
|
|
||||||
item->Destroy ();
|
|
||||||
}
|
|
||||||
// If the item was a weapon, don't bring it up automatically
|
|
||||||
// unless the player was not already using a weapon.
|
|
||||||
if (savedPendingWeap != NULL && hadweap && actor->player != NULL)
|
|
||||||
{
|
|
||||||
actor->player->PendingWeapon = savedPendingWeap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// GiveInventory
|
// GiveInventory
|
||||||
|
@ -1218,12 +1176,12 @@ static void GiveInventory (AActor *activator, const char *type, int amount)
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
DoGiveInv (players[i].mo, info, amount);
|
players[i].mo->GiveInventory(static_cast<PClassInventory *>(info), amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DoGiveInv (activator, info, amount);
|
activator->GiveInventory(static_cast<PClassInventory *>(info), amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9345,9 +9303,28 @@ scriptwait:
|
||||||
{
|
{
|
||||||
AActor *actor = SingleActorFromTID(STACK(1), activator);
|
AActor *actor = SingleActorFromTID(STACK(1), activator);
|
||||||
if (actor != NULL)
|
if (actor != NULL)
|
||||||
|
{
|
||||||
|
sector_t *sector = actor->Sector;
|
||||||
|
if (sector->e->XFloor.lightlist.Size())
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
TArray<lightlist_t> &lightlist = sector->e->XFloor.lightlist;
|
||||||
|
|
||||||
|
STACK(1) = *lightlist.Last().p_lightlevel;
|
||||||
|
for (i = 1; i < lightlist.Size(); i++)
|
||||||
|
{
|
||||||
|
if (lightlist[i].plane.ZatPoint(actor) <= actor->Z())
|
||||||
|
{
|
||||||
|
STACK(1) = *lightlist[i - 1].p_lightlevel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
STACK(1) = actor->Sector->lightlevel;
|
STACK(1) = actor->Sector->lightlevel;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else STACK(1) = 0;
|
else STACK(1) = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -9436,7 +9413,7 @@ scriptwait:
|
||||||
{
|
{
|
||||||
if (activator->player)
|
if (activator->player)
|
||||||
{
|
{
|
||||||
if (P_UndoPlayerMorph(activator->player, activator->player, force))
|
if (P_UndoPlayerMorph(activator->player, activator->player, 0, force))
|
||||||
{
|
{
|
||||||
changes++;
|
changes++;
|
||||||
}
|
}
|
||||||
|
@ -9462,7 +9439,7 @@ scriptwait:
|
||||||
{
|
{
|
||||||
if (actor->player)
|
if (actor->player)
|
||||||
{
|
{
|
||||||
if (P_UndoPlayerMorph(activator->player, actor->player, force))
|
if (P_UndoPlayerMorph(activator->player, actor->player, 0, force))
|
||||||
{
|
{
|
||||||
changes++;
|
changes++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,7 +253,7 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t
|
||||||
// if ceiling already moving, don't start a second function on it
|
// if ceiling already moving, don't start a second function on it
|
||||||
if (sec->PlaneMoving(sector_t::ceiling))
|
if (sec->PlaneMoving(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// new door thinker
|
// new door thinker
|
||||||
|
|
|
@ -102,8 +102,6 @@ struct TeaserSpeech
|
||||||
|
|
||||||
static FRandom pr_randomspeech("RandomSpeech");
|
static FRandom pr_randomspeech("RandomSpeech");
|
||||||
|
|
||||||
void GiveSpawner (player_t *player, PClassActor *type);
|
|
||||||
|
|
||||||
TArray<FStrifeDialogueNode *> StrifeDialogues;
|
TArray<FStrifeDialogueNode *> StrifeDialogues;
|
||||||
|
|
||||||
typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
|
typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
|
||||||
|
|
119
src/p_map.cpp
119
src/p_map.cpp
|
@ -44,6 +44,7 @@
|
||||||
#include "p_trace.h"
|
#include "p_trace.h"
|
||||||
#include "p_checkposition.h"
|
#include "p_checkposition.h"
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
|
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "decallib.h"
|
#include "decallib.h"
|
||||||
|
@ -5178,8 +5179,8 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
|
||||||
}
|
}
|
||||||
points *= thing->GetClass()->RDFactor;
|
points *= thing->GetClass()->RDFactor;
|
||||||
|
|
||||||
// points and bombdamage should be the same sign
|
// points and bombdamage should be the same sign (the double cast of 'points' is needed to prevent overflows and incorrect values slipping through.)
|
||||||
if (((int(points) * bombdamage) > 0) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
|
if ((((double)int(points) * bombdamage) > 0) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
|
||||||
{ // OK to damage; target is in direct path
|
{ // OK to damage; target is in direct path
|
||||||
double vz;
|
double vz;
|
||||||
double thrust;
|
double thrust;
|
||||||
|
@ -6238,6 +6239,91 @@ void P_CreateSecNodeList(AActor *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// P_DelPortalnode
|
||||||
|
//
|
||||||
|
// Same for line portal nodes
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
portnode_t *P_DelPortalnode(portnode_t *node)
|
||||||
|
{
|
||||||
|
portnode_t* tp; // prev node on thing thread
|
||||||
|
portnode_t* tn; // next node on thing thread
|
||||||
|
portnode_t* sp; // prev node on sector thread
|
||||||
|
portnode_t* sn; // next node on sector thread
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
// Unlink from the Thing thread. The Thing thread begins at
|
||||||
|
// sector_list and not from AActor->touching_sectorlist.
|
||||||
|
|
||||||
|
tp = node->m_tprev;
|
||||||
|
tn = node->m_tnext;
|
||||||
|
if (tp)
|
||||||
|
tp->m_tnext = tn;
|
||||||
|
if (tn)
|
||||||
|
tn->m_tprev = tp;
|
||||||
|
|
||||||
|
// Unlink from the sector thread. This thread begins at
|
||||||
|
// sector_t->touching_thinglist.
|
||||||
|
|
||||||
|
sp = node->m_sprev;
|
||||||
|
sn = node->m_snext;
|
||||||
|
if (sp)
|
||||||
|
sp->m_snext = sn;
|
||||||
|
else
|
||||||
|
node->m_portal->render_thinglist = sn;
|
||||||
|
if (sn)
|
||||||
|
sn->m_sprev = sp;
|
||||||
|
|
||||||
|
// Return this node to the freelist (use the same one as for msecnodes, since both types are the same size.)
|
||||||
|
P_PutSecnode(reinterpret_cast<msecnode_t *>(node));
|
||||||
|
return tn;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// P_AddPortalnode
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode)
|
||||||
|
{
|
||||||
|
portnode_t *node;
|
||||||
|
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
|
||||||
|
node = reinterpret_cast<portnode_t*>(P_GetSecnode());
|
||||||
|
|
||||||
|
// killough 4/4/98, 4/7/98: mark new nodes unvisited.
|
||||||
|
node->visited = 0;
|
||||||
|
|
||||||
|
node->m_portal = s; // portal
|
||||||
|
node->m_thing = thing; // mobj
|
||||||
|
node->m_tprev = NULL; // prev node on Thing thread
|
||||||
|
node->m_tnext = nextnode; // next node on Thing thread
|
||||||
|
if (nextnode)
|
||||||
|
nextnode->m_tprev = node; // set back link on Thing
|
||||||
|
|
||||||
|
// Add new node at head of portal thread starting at s->touching_thinglist
|
||||||
|
|
||||||
|
node->m_sprev = NULL; // prev node on portal thread
|
||||||
|
node->m_snext = s->render_thinglist; // next node on portal thread
|
||||||
|
if (s->render_thinglist)
|
||||||
|
node->m_snext->m_sprev = node;
|
||||||
|
s->render_thinglist = node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Handle the lists used to render actors from other portal areas
|
// Handle the lists used to render actors from other portal areas
|
||||||
|
@ -6249,6 +6335,27 @@ void AActor::UpdateRenderSectorList()
|
||||||
static const double SPRITE_SPACE = 64.;
|
static const double SPRITE_SPACE = 64.;
|
||||||
if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR))
|
if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR))
|
||||||
{
|
{
|
||||||
|
// Only check if the map contains line portals
|
||||||
|
ClearRenderLineList();
|
||||||
|
if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
|
||||||
|
{
|
||||||
|
int bx = GetBlockX(X());
|
||||||
|
int by = GetBlockX(Y());
|
||||||
|
FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors
|
||||||
|
// Are there any portals near the actor's position?
|
||||||
|
if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines)
|
||||||
|
{
|
||||||
|
// Go through the entire list. In most cases this is faster than setting up a blockmap iterator
|
||||||
|
for (auto &p : linePortals)
|
||||||
|
{
|
||||||
|
if (p.mType == PORTT_VISUAL) continue;
|
||||||
|
if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin))
|
||||||
|
{
|
||||||
|
render_portallist = P_AddPortalnode(&p, this, render_portallist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
sector_t *sec = Sector;
|
sector_t *sec = Sector;
|
||||||
double lasth = -FLT_MAX;
|
double lasth = -FLT_MAX;
|
||||||
ClearRenderSectorList();
|
ClearRenderSectorList();
|
||||||
|
@ -6284,6 +6391,14 @@ void AActor::ClearRenderSectorList()
|
||||||
render_sectorlist = NULL;
|
render_sectorlist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AActor::ClearRenderLineList()
|
||||||
|
{
|
||||||
|
portnode_t *node = render_portallist;
|
||||||
|
while (node)
|
||||||
|
node = P_DelPortalnode(node);
|
||||||
|
render_portallist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -612,6 +612,62 @@ void AActor::AddInventory (AInventory *item)
|
||||||
Inventory->InventoryID = InventoryID++;
|
Inventory->InventoryID = InventoryID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// AActor :: GiveInventory
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
bool AActor::GiveInventory(PClassInventory *type, int amount, bool givecheat)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
AWeapon *savedPendingWeap = player != NULL ? player->PendingWeapon : NULL;
|
||||||
|
bool hadweap = player != NULL ? player->ReadyWeapon != NULL : true;
|
||||||
|
|
||||||
|
AInventory *item;
|
||||||
|
if (!givecheat)
|
||||||
|
{
|
||||||
|
item = static_cast<AInventory *>(Spawn (type));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item = static_cast<AInventory *>(Spawn (type, Pos(), NO_REPLACE));
|
||||||
|
if (item == NULL) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This shouldn't count for the item statistics!
|
||||||
|
item->ClearCounters();
|
||||||
|
if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup)))
|
||||||
|
{
|
||||||
|
static_cast<ABasicArmorPickup*>(item)->SaveAmount *= amount;
|
||||||
|
}
|
||||||
|
else if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
|
||||||
|
{
|
||||||
|
static_cast<ABasicArmorBonus*>(item)->SaveAmount *= amount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!givecheat)
|
||||||
|
item->Amount = amount;
|
||||||
|
else
|
||||||
|
item->Amount = MIN (amount, item->MaxAmount);
|
||||||
|
}
|
||||||
|
if (!item->CallTryPickup (this))
|
||||||
|
{
|
||||||
|
item->Destroy ();
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
// If the item was a weapon, don't bring it up automatically
|
||||||
|
// unless the player was not already using a weapon.
|
||||||
|
// Don't bring it up automatically if this is called by the give cheat.
|
||||||
|
if (!givecheat && player != NULL && savedPendingWeap != NULL && hadweap)
|
||||||
|
{
|
||||||
|
player->PendingWeapon = savedPendingWeap;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// AActor :: RemoveInventory
|
// AActor :: RemoveInventory
|
||||||
|
|
|
@ -458,7 +458,7 @@ void P_SerializeWorld (FArchive &arc)
|
||||||
|
|
||||||
void P_SerializeWorldActors(FArchive &arc)
|
void P_SerializeWorldActors(FArchive &arc)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i;
|
||||||
sector_t *sec;
|
sector_t *sec;
|
||||||
|
|
||||||
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
|
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
|
||||||
|
|
|
@ -893,7 +893,7 @@ void P_SetupPortals()
|
||||||
{
|
{
|
||||||
if (ss.mType == PORTS_STACKEDSECTORTHING && ss.mSkybox == s.mSkybox->target)
|
if (ss.mType == PORTS_STACKEDSECTORTHING && ss.mSkybox == s.mSkybox->target)
|
||||||
{
|
{
|
||||||
s.mPartner = (&ss) - §orPortals[0];
|
s.mPartner = unsigned((&ss) - §orPortals[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,8 +119,8 @@ static void BuildBlockmap()
|
||||||
while (*list != -1)
|
while (*list != -1)
|
||||||
{
|
{
|
||||||
line_t *ld = &lines[*list++];
|
line_t *ld = &lines[*list++];
|
||||||
|
FLinePortal *port = ld->getPortal();
|
||||||
if (ld->isLinePortal())
|
if (port && port->mType != PORTT_VISUAL)
|
||||||
{
|
{
|
||||||
PortalBlockmap.containsLines = true;
|
PortalBlockmap.containsLines = true;
|
||||||
block.portallines.Push(ld);
|
block.portallines.Push(ld);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
struct FPortalGroupArray;
|
struct FPortalGroupArray;
|
||||||
class ASkyViewpoint;
|
class ASkyViewpoint;
|
||||||
|
struct portnode_t;
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// This table holds the offsets for the different parts of a map
|
// This table holds the offsets for the different parts of a map
|
||||||
|
@ -189,6 +190,7 @@ struct FLinePortal
|
||||||
DAngle mAngleDiff;
|
DAngle mAngleDiff;
|
||||||
double mSinRot;
|
double mSinRot;
|
||||||
double mCosRot;
|
double mCosRot;
|
||||||
|
portnode_t *render_thinglist;
|
||||||
void *mRenderData;
|
void *mRenderData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
12
src/r_defs.h
12
src/r_defs.h
|
@ -1481,6 +1481,18 @@ struct msecnode_t
|
||||||
bool visited; // killough 4/4/98, 4/7/98: used in search algorithms
|
bool visited; // killough 4/4/98, 4/7/98: used in search algorithms
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// use the same memory layout as msecnode_t so both can be used from the same freelist.
|
||||||
|
struct portnode_t
|
||||||
|
{
|
||||||
|
FLinePortal *m_portal; // a portal containing this object
|
||||||
|
AActor *m_thing; // this object
|
||||||
|
struct portnode_t *m_tprev; // prev msecnode_t for this thing
|
||||||
|
struct portnode_t *m_tnext; // next msecnode_t for this thing
|
||||||
|
struct portnode_t *m_sprev; // prev msecnode_t for this portal
|
||||||
|
struct portnode_t *m_snext; // next msecnode_t for this portal
|
||||||
|
bool visited;
|
||||||
|
};
|
||||||
|
|
||||||
struct FPolyNode;
|
struct FPolyNode;
|
||||||
struct FMiniBSP;
|
struct FMiniBSP;
|
||||||
|
|
||||||
|
|
|
@ -693,7 +693,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
fixed_t starty = viewy;
|
fixed_t starty = viewy;
|
||||||
fixed_t startz = viewz;
|
fixed_t startz = viewz;
|
||||||
DVector3 savedpath[2] = { ViewPath[0], ViewPath[1] };
|
DVector3 savedpath[2] = { ViewPath[0], ViewPath[1] };
|
||||||
int savedvisibility = camera? camera->renderflags & RF_INVISIBLE : 0;
|
ActorRenderFlags savedvisibility = camera? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0);
|
||||||
|
|
||||||
CurrentPortalUniq++;
|
CurrentPortalUniq++;
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,7 @@ ACTOR Actor native //: Thinker
|
||||||
native void A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
|
native void A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
|
||||||
action native A_PigPain ();
|
action native A_PigPain ();
|
||||||
native state A_MonsterRefire(int chance, state label);
|
native state A_MonsterRefire(int chance, state label);
|
||||||
native void A_SetAngle(float angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
action native A_SetAngle(float angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
native void A_SetPitch(float pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetPitch(float pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
native void A_SetRoll(float/*angle*/ roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetRoll(float/*angle*/ roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
native void A_ScaleVelocity(float scale, int ptr = AAPTR_DEFAULT);
|
native void A_ScaleVelocity(float scale, int ptr = AAPTR_DEFAULT);
|
||||||
|
|
|
@ -220,3 +220,13 @@ enum
|
||||||
433 = 0, Ceiling_CrushStop(0)
|
433 = 0, Ceiling_CrushStop(0)
|
||||||
434 = 0, Ceiling_CrushRaiseAndStay(0)
|
434 = 0, Ceiling_CrushRaiseAndStay(0)
|
||||||
435 = 0, Ceiling_LowerAndCrush(0)
|
435 = 0, Ceiling_LowerAndCrush(0)
|
||||||
|
436 = 0, Ceiling_LowerAndCrushDist(0)
|
||||||
|
437 = 0, Ceiling_CrushAndRaiseDist(0)
|
||||||
|
438 = 0, Ceiling_CrushRaiseAndStayA(0)
|
||||||
|
439 = 0, Ceiling_CrushAndRaiseA(0)
|
||||||
|
440 = 0, Ceiling_CrushAndRaiseSilentA(0)
|
||||||
|
441 = 0, Ceiling_CrushAndRaiseSilentDist(0)
|
||||||
|
442 = 0, Ceiling_CrushRaiseAndStaySilA(0)
|
||||||
|
443 = 0, Generic_Crusher(0)
|
||||||
|
444 = 0, Teleport(0)
|
||||||
|
445 = 0, Teleport_NoFog(0)
|
||||||
|
|
Loading…
Reference in a new issue