This commit is contained in:
nashmuhandes 2017-02-25 03:19:36 +08:00
commit 4841b8793f
50 changed files with 3862 additions and 3706 deletions

View file

@ -714,7 +714,7 @@ public:
virtual bool UseInventory (AInventory *item);
// Tosses an item out of the inventory.
AInventory *DropInventory (AInventory *item);
AInventory *DropInventory (AInventory *item, int amt = -1);
// Removes all items from the inventory.
void ClearInventory();

View file

@ -56,7 +56,7 @@ struct event_t
};
typedef enum
enum gameaction_t : int
{
ga_nothing,
ga_loadlevel,
@ -76,7 +76,7 @@ typedef enum
ga_screenshot,
ga_togglemap,
ga_fullconsole,
} gameaction_t;
};

View file

@ -2272,6 +2272,9 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_INVDROP:
{
DWORD which = ReadLong (stream);
int amt = -1;
if (type == DEM_INVDROP) amt = ReadLong(stream);
if (gamestate == GS_LEVEL && !paused
&& players[player].playerstate != PST_DEAD)
@ -2289,7 +2292,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
}
else
{
players[player].mo->DropInventory (item);
players[player].mo->DropInventory (item, amt);
}
}
}
@ -2765,10 +2768,13 @@ void Net_SkipCommand (int type, BYTE **stream)
break;
case DEM_INVUSE:
case DEM_INVDROP:
skip = 4;
break;
case DEM_INVDROP:
skip = 8;
break;
case DEM_GENERICCHEAT:
case DEM_DROPPLAYER:
case DEM_FOV:

View file

@ -165,10 +165,11 @@ protected: \
_X_CONSTRUCTOR_##isabstract(cls) \
_IMP_PCLASS(cls, _X_POINTERS_##ptrs(cls), _X_ABSTRACT_##isabstract(cls))
// Taking the address of a field in an object at address 1 instead of
// Taking the address of a field in an object at address > 0 instead of
// address 0 keeps GCC from complaining about possible misuse of offsetof.
// Using 8 to avoid unaligned pointer use.
#define IMPLEMENT_POINTERS_START(cls) const size_t cls::PointerOffsets[] = {
#define IMPLEMENT_POINTER(field) (size_t)&((ThisClass*)1)->field - 1,
#define IMPLEMENT_POINTER(field) ((size_t)&((ThisClass*)8)->field) - 8,
#define IMPLEMENT_POINTERS_END ~(size_t)0 };
// Possible arguments for the IMPLEMENT_CLASS macro

View file

@ -78,6 +78,7 @@
#include "menu/menu.h"
#include "intermission/intermission.h"
#include "g_levellocals.h"
#include "events.h"
// MACROS ------------------------------------------------------------------
@ -331,6 +332,8 @@ static void MarkRoot()
DThinker::MarkRoots();
FCanvasTextureInfo::Mark();
Mark(DACSThinker::ActiveThinker);
Mark(E_FirstEventHandler);
Mark(E_LastEventHandler);
for (auto &s : level.sectorPortals)
{
Mark(s.mSkybox);
@ -544,7 +547,6 @@ void FullGC()
void Barrier(DObject *pointing, DObject *pointed)
{
assert(pointed->GetClass() != nullptr);
assert(pointing == NULL || (pointing->IsBlack() && !pointing->IsDead()));
assert(pointed->IsWhite() && !pointed->IsDead());
assert(State != GCS_Finalize && State != GCS_Pause);

View file

@ -501,7 +501,7 @@ PInt::PInt(unsigned int size, bool unsign, bool compatible)
MemberOnly = (size < 4);
if (!unsign)
{
int maxval = (1 << ((8 * size) - 1)) - 1;
int maxval = (1u << ((8 * size) - 1)) - 1; // compute as unsigned to prevent overflow before -1
int minval = -maxval - 1;
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, minval));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, maxval));
@ -509,7 +509,7 @@ PInt::PInt(unsigned int size, bool unsign, bool compatible)
else
{
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, 0u));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, (1u << (8 * size)) - 1));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, (1u << ((8 * size) - 1))));
}
SetOps();
}
@ -3219,16 +3219,24 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
const PClass *existclass = FindClass(name);
// This is a placeholder so fill it in
if (existclass != NULL && existclass->Size == (unsigned)-1)
if (existclass != nullptr)
{
type = const_cast<PClass*>(existclass);
if (!IsDescendantOf(type->ParentClass))
// This is a placeholder so fill it in
if (existclass->Size == TentativeClass)
{
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
type = const_cast<PClass*>(existclass);
if (!IsDescendantOf(type->ParentClass))
{
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
}
DPrintf(DMSG_SPAMMY, "Defining placeholder class %s\n", name.GetChars());
notnew = true;
}
else
{
// a different class with the same name already exists. Let the calling code deal with this.
return nullptr;
}
DPrintf(DMSG_SPAMMY, "Defining placeholder class %s\n", name.GetChars());
notnew = true;
}
else
{

View file

@ -65,7 +65,7 @@ typedef enum
// The current state of the game: whether we are
// playing, gazing at the intermission screen,
// the game final animation, or a demo.
typedef enum
enum gamestate_t : int
{
GS_LEVEL,
GS_INTERMISSION,
@ -80,7 +80,7 @@ typedef enum
GS_FORCEWIPEFADE = -2,
GS_FORCEWIPEBURN = -3,
GS_FORCEWIPEMELT = -4
} gamestate_t;
};
extern gamestate_t gamestate;

View file

@ -37,32 +37,42 @@ bool E_RegisterHandler(DStaticEventHandler* handler)
// 2. MyHandler3->2:
// E_FirstEventHandler = MyHandler2, E_LastEventHandler = MyHandler3
// (Yes, all those write barriers here are really needed!)
if (before != nullptr)
{
// if before is not null, link it before the existing handler.
// note that before can be first handler, check for this.
handler->next = before;
GC::WriteBarrier(handler, before);
handler->prev = before->prev;
GC::WriteBarrier(handler, before->prev);
before->prev = handler;
GC::WriteBarrier(before, handler);
if (before == E_FirstEventHandler)
{
E_FirstEventHandler = handler;
GC::WriteBarrier(handler);
}
}
else
{
// so if before is null, it means add last.
// it can also mean that we have no handlers at all yet.
handler->prev = E_LastEventHandler;
GC::WriteBarrier(handler, E_LastEventHandler);
handler->next = nullptr;
if (E_FirstEventHandler == nullptr)
E_FirstEventHandler = handler;
if (E_FirstEventHandler == nullptr) E_FirstEventHandler = handler;
E_LastEventHandler = handler;
GC::WriteBarrier(handler);
if (handler->prev != nullptr)
{
handler->prev->next = handler;
GC::WriteBarrier(handler->prev, handler);
}
}
if (handler->IsStatic())
{
handler->ObjectFlags |= OF_Fixed;
handler->ObjectFlags |= OF_Transient;
}
@ -80,16 +90,28 @@ bool E_UnregisterHandler(DStaticEventHandler* handler)
// link out of normal list
if (handler->prev)
{
handler->prev->next = handler->next;
GC::WriteBarrier(handler->prev, handler->next);
}
if (handler->next)
{
handler->next->prev = handler->prev;
GC::WriteBarrier(handler->next, handler->prev);
}
if (handler == E_FirstEventHandler)
{
E_FirstEventHandler = handler->next;
GC::WriteBarrier(handler->next);
}
if (handler == E_LastEventHandler)
{
E_LastEventHandler = handler->prev;
GC::WriteBarrier(handler->prev);
}
if (handler->IsStatic())
{
handler->ObjectFlags &= ~(OF_Fixed|OF_Transient);
handler->ObjectFlags &= ~OF_Transient;
handler->Destroy();
}
return true;

View file

@ -77,6 +77,7 @@ void E_SerializeEvents(FSerializer& arc);
class DStaticEventHandler : public DObject // make it a part of normal GC process
{
DECLARE_CLASS(DStaticEventHandler, DObject)
HAS_OBJECT_POINTERS
public:
DStaticEventHandler()
{
@ -99,6 +100,7 @@ public:
void Serialize(FSerializer& arc) override
{
Super::Serialize(arc);
/*
if (arc.isReading())
{
Printf("DStaticEventHandler::Serialize: reading object %s\n", GetClass()->TypeName.GetChars());
@ -107,6 +109,7 @@ public:
{
Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars());
}
*/
arc("Order", Order);
arc("IsUiProcessor", IsUiProcessor);
@ -155,6 +158,7 @@ public:
bool IsStatic() override { return false; }
};
extern DStaticEventHandler* E_FirstEventHandler;
extern DStaticEventHandler* E_LastEventHandler;
// we cannot call this DEvent because in ZScript, 'event' is a keyword
class DBaseEvent : public DObject

View file

@ -242,6 +242,7 @@ FString BackupSaveName;
bool SendLand;
const AInventory *SendItemUse, *SendItemDrop;
int SendItemDropAmount;
EXTERN_CVAR (Int, team)
@ -458,12 +459,14 @@ CCMD (invdrop)
if (players[consoleplayer].mo)
{
SendItemDrop = players[consoleplayer].mo->InvSel;
SendItemDropAmount = -1;
}
}
CCMD (weapdrop)
{
SendItemDrop = players[consoleplayer].ReadyWeapon;
SendItemDropAmount = -1;
}
CCMD (drop)
@ -471,6 +474,7 @@ CCMD (drop)
if (argv.argc() > 1 && who != NULL)
{
SendItemDrop = who->FindInventory(argv[1]);
SendItemDropAmount = argv.argc() > 2 ? atoi(argv[2]) : -1;
}
}
@ -763,6 +767,7 @@ void G_BuildTiccmd (ticcmd_t *cmd)
{
Net_WriteByte (DEM_INVDROP);
Net_WriteLong (SendItemDrop->InventoryID);
Net_WriteLong(SendItemDropAmount);
SendItemDrop = NULL;
}

View file

@ -95,6 +95,7 @@ extern AActor *bodyque[BODYQUESIZE];
extern int bodyqueslot;
class AInventory;
extern const AInventory *SendItemUse, *SendItemDrop;
extern int SendItemDropAmount;
#endif

View file

@ -154,8 +154,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, wbplayerstruct_t &h, w
{
if (arc.BeginObject(key))
{
arc("in", h.in)
("kills", h.skills)
arc("kills", h.skills)
("items", h.sitems)
("secrets", h.ssecret)
("time", h.stime)

View file

@ -776,7 +776,7 @@ void G_DoCompleted (void)
AM_Stop ();
wminfo.finished_ep = level.cluster - 1;
wminfo.LName0 = TexMan[TexMan.CheckForTexture(level.info->PName, FTexture::TEX_MiscPatch)];
wminfo.LName0 = TexMan.CheckForTexture(level.info->PName, FTexture::TEX_MiscPatch);
wminfo.current = level.MapName;
if (deathmatch &&
@ -792,12 +792,12 @@ void G_DoCompleted (void)
if (nextinfo == NULL || strncmp (nextlevel, "enDSeQ", 6) == 0)
{
wminfo.next = nextlevel;
wminfo.LName1 = NULL;
wminfo.LName1.SetInvalid();
}
else
{
wminfo.next = nextinfo->MapName;
wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->PName, FTexture::TEX_MiscPatch)];
wminfo.LName1 = TexMan.CheckForTexture(nextinfo->PName, FTexture::TEX_MiscPatch);
}
}
@ -816,7 +816,6 @@ void G_DoCompleted (void)
for (i=0 ; i<MAXPLAYERS ; i++)
{
wminfo.plyr[i].in = playeringame[i];
wminfo.plyr[i].skills = players[i].killcount;
wminfo.plyr[i].sitems = players[i].itemcount;
wminfo.plyr[i].ssecret = players[i].secretcount;

View file

@ -53,6 +53,9 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, gametype)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, norandomplayerclass)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, infoPages)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mBackButton)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mStatscreenMapNameFont)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mStatscreenEnteringFont)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mStatscreenFinishedFont)
const char *GameNames[17] =

View file

@ -411,6 +411,11 @@ void M_SetMenu(FName menu, int param)
C_DoCommand("menu_quit");
return;
case NAME_EndGameMenu:
// The separate menu class no longer exists but the name still needs support for existing mods.
void ActivateEndGameMenu();
ActivateEndGameMenu();
return;
}
// End of special checks
@ -491,7 +496,7 @@ DEFINE_ACTION_FUNCTION(DMenu, SetMenu)
{
PARAM_PROLOGUE;
PARAM_NAME(menu);
PARAM_INT(mparam);
PARAM_INT_DEF(mparam);
M_SetMenu(menu, mparam);
return 0;
}

View file

@ -407,7 +407,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
else if (args[i] == TypeTextureID)
{
auto f = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch);
if (!f.isValid())
if (!f.Exists())
{
sc.ScriptError("Unknown texture %s", sc.String);
}

View file

@ -125,17 +125,8 @@ CCMD (menu_quit)
//
//=============================================================================
CCMD (menu_endgame)
{ // F7
if (!usergame)
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/invalid", snd_menuvolume, ATTN_NONE);
return;
}
//M_StartControlPanel (true);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE);
void ActivateEndGameMenu()
{
FString tempstring = GStrings(netgame ? "NETEND" : "ENDGAME");
DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []()
{
@ -149,6 +140,20 @@ CCMD (menu_endgame)
M_ActivateMenu(newmenu);
}
CCMD (menu_endgame)
{ // F7
if (!usergame)
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/invalid", snd_menuvolume, ATTN_NONE);
return;
}
//M_StartControlPanel (true);
S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE);
ActivateEndGameMenu();
}
//=============================================================================
//
//
@ -262,7 +267,7 @@ DEFINE_ACTION_FUNCTION(DMenu, StartMessage)
{
PARAM_PROLOGUE;
PARAM_STRING(msg);
PARAM_INT(mode);
PARAM_INT_DEF(mode);
PARAM_NAME_DEF(action);
M_StartMessage(msg, mode, action);
return 0;

View file

@ -671,6 +671,7 @@ xx(Optionsmenu)
xx(Quitmenu)
xx(Savemenu)
xx(Playermenu)
xx(EndGameMenu)
xx(Playerbox)
xx(Team)

View file

@ -2821,6 +2821,8 @@ void FBehavior::StaticStartTypedScripts (WORD type, AActor *activator, bool alwa
"Unloading",
"Disconnect",
"Return",
"Event",
"Kill",
"Reopen"
};
DPrintf(DMSG_NOTIFY, "Starting all scripts of type %d (%s)\n", type,

View file

@ -3663,13 +3663,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_DropInventory)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_CLASS(drop, AInventory);
PARAM_INT_DEF(amount);
if (drop)
{
AInventory *inv = self->FindInventory(drop);
if (inv)
{
self->DropInventory(inv);
self->DropInventory(inv, amount);
}
}
return 0;

View file

@ -568,16 +568,6 @@ FStrifeDialogueNode::~FStrifeDialogueNode ()
}
}
//============================================================================
//
// FStrifeDialogueReply :: ~FStrifeDialogueReply
//
//============================================================================
FStrifeDialogueReply::~FStrifeDialogueReply ()
{
}
//============================================================================
//
// FindNode

View file

@ -20,19 +20,19 @@ struct FStrifeDialogueItemCheck
struct FStrifeDialogueNode
{
~FStrifeDialogueNode ();
PClassActor *DropType;
PClassActor *DropType = nullptr;
TArray<FStrifeDialogueItemCheck> ItemCheck;
int ThisNodeNum; // location of this node in StrifeDialogues
int ItemCheckNode; // index into StrifeDialogues
int ThisNodeNum = 0; // location of this node in StrifeDialogues
int ItemCheckNode = 0; // index into StrifeDialogues
PClassActor *SpeakerType;
PClassActor *SpeakerType = nullptr;
FString SpeakerName;
FSoundID SpeakerVoice;
FString Backdrop;
FString Dialogue;
FString Goodbye; // must init to null for binary scripts to work as intended
FStrifeDialogueReply *Children;
FStrifeDialogueReply *Children = nullptr;
FName MenuClassName;
FString UserData;
};
@ -40,13 +40,11 @@ struct FStrifeDialogueNode
// FStrifeDialogueReply holds responses the player can give to the NPC
struct FStrifeDialogueReply
{
~FStrifeDialogueReply ();
FStrifeDialogueReply *Next;
PClassActor *GiveType;
int ActionSpecial;
int Args[5];
int PrintAmount;
FStrifeDialogueReply *Next = nullptr;
PClassActor *GiveType = nullptr;
int ActionSpecial = 0;
int Args[5] = {};
int PrintAmount = 0;
TArray<FStrifeDialogueItemCheck> ItemCheck;
TArray<FStrifeDialogueItemCheck> ItemCheckRequire;
TArray<FStrifeDialogueItemCheck> ItemCheckExclude;
@ -54,9 +52,9 @@ struct FStrifeDialogueReply
FString QuickYes;
FString QuickNo;
FString LogString;
int NextNode; // index into StrifeDialogues
int LogNumber;
bool NeedsGold;
int NextNode = 0; // index into StrifeDialogues
int LogNumber = 0;
bool NeedsGold = false;
};
extern TArray<FStrifeDialogueNode *> StrifeDialogues;

View file

@ -1036,14 +1036,14 @@ DEFINE_ACTION_FUNCTION(AActor, UseInventory)
//
//===========================================================================
AInventory *AActor::DropInventory (AInventory *item)
AInventory *AActor::DropInventory (AInventory *item, int amt)
{
AInventory *drop = nullptr;
IFVIRTUALPTR(item, AInventory, CreateTossable)
{
VMValue params[1] = { (DObject*)item };
VMValue params[] = { (DObject*)item, amt };
VMReturn ret((void**)&drop);
GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr);
GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr);
}
if (drop == nullptr) return NULL;
drop->SetOrigin(PosPlusZ(10.), false);
@ -1060,7 +1060,8 @@ DEFINE_ACTION_FUNCTION(AActor, DropInventory)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(item, AInventory);
ACTION_RETURN_OBJECT(self->DropInventory(item));
PARAM_INT_DEF(amt);
ACTION_RETURN_OBJECT(self->DropInventory(item, amt));
}
//============================================================================

View file

@ -107,6 +107,7 @@ class SightCheck
bool P_SightCheckLine (line_t *ld);
int P_SightBlockLinesIterator (int x, int y);
bool P_SightTraverseIntercepts ();
bool LineBlocksSight(line_t *ld);
public:
bool P_SightPathTraverse ();
@ -211,7 +212,14 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
double trX = Trace.x + Trace.dx * in->frac;
double trY = Trace.y + Trace.dy * in->frac;
P_SightOpening (open, li, trX, trY);
P_SightOpening(open, li, trX, trY);
if (LineBlocksSight(in->d.line))
{
// This may not skip P_SightOpening, but only reduce the open range to 0.
open.range = 0;
open.bottom = open.top;
}
FLinePortal *lport = li->getPortal();
@ -362,6 +370,42 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
}
// performs trivial visibility checks.
bool SightCheck::LineBlocksSight(line_t *ld)
{
// try to early out the check
if (!ld->backsector || !(ld->flags & ML_TWOSIDED) || (ld->flags & ML_BLOCKSIGHT))
return true; // stop checking
// [RH] don't see past block everything lines
if (ld->flags & ML_BLOCKEVERYTHING)
{
if (!(Flags & SF_SEEPASTBLOCKEVERYTHING))
{
return true;
}
// Pretend the other side is invisible if this is not an impact line
// that runs a script on the current map. Used to prevent monsters
// from trying to attack through a block everything line unless
// there's a chance their attack will make it nonblocking.
if (!(Flags & SF_SEEPASTSHOOTABLELINES))
{
if (!(ld->activation & SPAC_Impact))
{
return true;
}
if (ld->special != ACS_Execute && ld->special != ACS_ExecuteAlways)
{
return true;
}
if (ld->args[1] != 0 && ld->args[1] != level.levelnum)
{
return true;
}
}
}
return false;
}
/*
==================
@ -392,36 +436,9 @@ bool SightCheck::P_SightCheckLine (line_t *ld)
return true; // line isn't crossed
}
// try to early out the check
if (!ld->backsector || !(ld->flags & ML_TWOSIDED) || (ld->flags & ML_BLOCKSIGHT))
return false; // stop checking
// [RH] don't see past block everything lines
if (ld->flags & ML_BLOCKEVERYTHING)
if (!portalfound) // when portals come into play, the quick-outs here may not be performed
{
if (!(Flags & SF_SEEPASTBLOCKEVERYTHING))
{
return false;
}
// Pretend the other side is invisible if this is not an impact line
// that runs a script on the current map. Used to prevent monsters
// from trying to attack through a block everything line unless
// there's a chance their attack will make it nonblocking.
if (!(Flags & SF_SEEPASTSHOOTABLELINES))
{
if (!(ld->activation & SPAC_Impact))
{
return false;
}
if (ld->special != ACS_Execute && ld->special != ACS_ExecuteAlways)
{
return false;
}
if (ld->args[1] != 0 && ld->args[1] != level.levelnum)
{
return false;
}
}
if (LineBlocksSight(ld)) return false;
}
sightcounts[3]++;

View file

@ -121,7 +121,6 @@ class USDFParser : public UDMFParserBase
bool ParseChoice(FStrifeDialogueReply **&replyptr)
{
FStrifeDialogueReply *reply = new FStrifeDialogueReply;
memset(reply, 0, sizeof(*reply));
reply->Next = *replyptr;
*replyptr = reply;
@ -293,8 +292,6 @@ class USDFParser : public UDMFParserBase
{
FStrifeDialogueNode *node = new FStrifeDialogueNode;
FStrifeDialogueReply **replyptr = &node->Children;
memset(node, 0, sizeof(*node));
//node->ItemCheckCount[0] = node->ItemCheckCount[1] = node->ItemCheckCount[2] = -1;
node->ThisNodeNum = StrifeDialogues.Push(node);
node->ItemCheckNode = -1;

View file

@ -6522,7 +6522,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
case CVAR_String:
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FStringCVar *>(CVar)->Value, ATAG_GENERIC));
build->Emit(OP_LS, dest.RegNum, addr.RegNum, nul);
build->Emit(OP_LCS, dest.RegNum, addr.RegNum, nul);
break;
case CVAR_DummyBool:

View file

@ -315,9 +315,7 @@ do_stop:
do
{
sc.MustGetString();
#ifdef DYNLIGHT
AddStateLight(&state, sc.String);
#endif
AddStateLight(&state, sc.String);
}
while (sc.CheckString(","));
sc.MustGetStringName(")");

View file

@ -851,7 +851,10 @@ void InitThingdef()
fieldptr = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction);
fieldptr = new PField("gameaction", TypeUInt32, VARF_Native | VARF_Static, (intptr_t)&gameaction);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("gamestate", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gamestate);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum);

View file

@ -197,6 +197,16 @@ begin:
GETADDR(PB,RC,X_READ_NIL);
reg.s[a] = *(FString *)ptr;
NEXTOP;
OP(LCS):
ASSERTS(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
reg.s[a] = *(const char **)ptr;
NEXTOP;
OP(LCS_R):
ASSERTS(a); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
reg.s[a] = *(const char **)ptr;
NEXTOP;
OP(LO):
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);

View file

@ -52,6 +52,8 @@ xx(LV2, lv2, RVRPKI, LV2_R, 4, REGT_INT), // load vector2
xx(LV2_R, lv2, RVRPRI, NOP, 0, 0),
xx(LV3, lv3, RVRPKI, LV3_R, 4, REGT_INT), // load vector3
xx(LV3_R, lv3, RVRPRI, NOP, 0, 0),
xx(LCS, lcs, RSRPKI, LCS_R, 4, REGT_INT), // load string from char ptr.
xx(LCS_R, lcs, RSRPRI, NOP, 0, 0),
xx(LBIT, lbit, RIRPI8, NOP, 0, 0), // rA = !!(*rB & C) -- *rB is a byte

View file

@ -2562,7 +2562,7 @@ void ZCCCompiler::CompileStates()
state.Misc1 = IntConstFromNode(sl->Offset, c->Type());
state.Misc2 = IntConstFromNode(static_cast<ZCC_Expression *>(sl->Offset->SiblingNext), c->Type());
}
#ifdef DYNLIGHT
if (sl->Lights != nullptr)
{
auto l = sl->Lights;
@ -2572,7 +2572,6 @@ void ZCCCompiler::CompileStates()
l = static_cast<decltype(l)>(l->SiblingNext);
} while (l != sl->Lights);
}
#endif
if (sl->Action != nullptr)
{

File diff suppressed because it is too large Load diff

View file

@ -87,8 +87,6 @@ const char *GetVersionString();
// SVN revision ever got.
#define SAVEVER 4550
#define DYNLIGHT
// This is so that derivates can use the same savegame versions without worrying about engine compatibility
#define GAMESIG "GZDOOM"
#define BASEWAD "gzdoom.pk3"

File diff suppressed because it is too large Load diff

View file

@ -33,8 +33,6 @@ class FTexture;
//
struct wbplayerstruct_t
{
bool in; // whether the player is in game
// Player stats, kills, collected items etc.
int skills;
int sitems;
@ -52,8 +50,8 @@ struct wbstartstruct_t
FString current; // [RH] Name of map just finished
FString next; // next level, [RH] actual map name
FTexture *LName0;
FTexture *LName1;
FTextureID LName0;
FTextureID LName1;
int maxkills;
int maxitems;

View file

@ -111,8 +111,6 @@ SPIDR0, 110, 111, iwad
SPIDS0, 98, 35, iwad
SPOSH0, 14, 60, iwad
SPOSL0, 24, 15, iwad
SSWVG0, 17, 55, iwad
SSWVH0, 17, 52, iwad
SSWVI0, 18, 54, iwad
SSWVJ0, 15, 44, iwad
SSWVK0, 15, 40, iwad

View file

@ -111,8 +111,6 @@ SPIDR0, 110, 111, iwad
SPIDS0, 98, 35, iwad
SPOSH0, 14, 60, iwad
SPOSL0, 24, 15, iwad
SSWVG0, 17, 55, iwad
SSWVH0, 17, 52, iwad
SSWVI0, 18, 54, iwad
SSWVJ0, 15, 44, iwad
SSWVK0, 15, 40, iwad

View file

@ -25,6 +25,8 @@
#include "zscript/menu/readthis.txt"
#include "zscript/menu/conversationmenu.txt"
#include "zscript/statscreen/types.txt"
#include "zscript/inventory/inventory.txt"
#include "zscript/inventory/inv_misc.txt"
#include "zscript/inventory/stateprovider.txt"

View file

@ -496,7 +496,7 @@ class Actor : Thinker native
native bool TakeInventory(class<Inventory> itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
native Inventory FindInventory(class<Inventory> itemtype, bool subclass = false);
native Inventory GiveInventoryType(class<Inventory> itemtype);
native Inventory DropInventory (Inventory item);
native Inventory DropInventory (Inventory item, int amt = -1);
native bool UseInventory(Inventory item);
native void ObtainInventory(Actor other);
native bool GiveAmmo (Class<Ammo> type, int amount);
@ -787,7 +787,7 @@ class Actor : Thinker native
native void A_SpawnDebris(class<Actor> spawntype, bool transfer_translation = false, double mult_h = 1, double mult_v = 1);
native void A_SpawnParticle(color color1, int flags = 0, int lifetime = 35, double size = 1, double angle = 0, double xoff = 0, double yoff = 0, double zoff = 0, double velx = 0, double vely = 0, double velz = 0, double accelx = 0, double accely = 0, double accelz = 0, double startalphaf = 1, double fadestepf = -1, double sizestep = 0);
native void A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false);
native void A_DropInventory(class<Inventory> itemtype);
native void A_DropInventory(class<Inventory> itemtype, int amount = -1);
native void A_SetBlend(color color1, double alpha, int tics, color color2 = 0);
deprecated native void A_ChangeFlag(string flagname, bool value);
native void A_ChangeCountFlags(int kill = FLAG_NO_CHANGE, int item = FLAG_NO_CHANGE, int secret = FLAG_NO_CHANGE);

View file

@ -290,6 +290,12 @@ struct CVar native
native int ResetToDefault();
}
struct GIFont
{
Name fontname;
Name color;
};
struct GameInfoStruct native
{
// will be extended as needed.
@ -301,6 +307,9 @@ struct GameInfoStruct native
native bool norandomplayerclass;
native Array<Name> infoPages;
native String mBackButton;
native GIFont mStatscreenMapNameFont;
native GIFont mStatscreenEnteringFont;
native GIFont mStatscreenFinishedFont;
}
class Object native

View file

@ -1029,6 +1029,18 @@ enum PaletteFlashFlags
PF_HAZARD = 8,
};
enum EGameState
{
GS_LEVEL,
GS_INTERMISSION,
GS_FINALE,
GS_DEMOSCREEN,
GS_FULLCONSOLE,
GS_HIDECONSOLE,
GS_STARTUP,
GS_TITLELEVEL,
}
enum EGameAction
{
ga_nothing,

View file

@ -173,9 +173,9 @@ class Ammo : Inventory
//
//===========================================================================
override Inventory CreateTossable()
override Inventory CreateTossable(int amt)
{
Inventory copy = Super.CreateTossable();
Inventory copy = Super.CreateTossable(amt);
if (copy != null)
{ // Do not increase ammo by dropping it and picking it back up at
// certain skill levels.
@ -306,9 +306,9 @@ class BackpackItem : Inventory
//
//===========================================================================
override Inventory CreateTossable ()
override Inventory CreateTossable (int amount)
{
let pack = BackpackItem(Super.CreateTossable());
let pack = BackpackItem(Super.CreateTossable(-1));
if (pack != NULL)
{
pack.bDepleted = true;

View file

@ -489,7 +489,7 @@ class HexenArmor : Armor
//
//===========================================================================
override Inventory CreateTossable ()
override Inventory CreateTossable (int amount)
{
return NULL;
}

View file

@ -120,9 +120,9 @@ class HealthPickup : Inventory
//
//===========================================================================
override Inventory CreateTossable ()
override Inventory CreateTossable (int amount)
{
Inventory copy = Super.CreateTossable ();
Inventory copy = Super.CreateTossable (-1);
if (copy != NULL)
{
copy.health = health;

View file

@ -440,7 +440,7 @@ class Inventory : Actor native
//
//===========================================================================
virtual Inventory CreateTossable ()
virtual Inventory CreateTossable (int amt = -1)
{
// If self actor lacks a SpawnState, don't drop it. (e.g. A base weapon
// like the fist can't be dropped because you'll never see it.)
@ -448,7 +448,7 @@ class Inventory : Actor native
{
return NULL;
}
if (bUndroppable || bUntossable || Owner == NULL || Amount <= 0)
if (bUndroppable || bUntossable || Owner == NULL || Amount <= 0 || amt == 0)
{
return NULL;
}
@ -462,11 +462,13 @@ class Inventory : Actor native
let copy = Inventory(Spawn (GetClass(), Owner.Pos, NO_REPLACE));
if (copy != NULL)
{
amt = clamp(amt, 1, Amount);
copy.MaxAmount = MaxAmount;
copy.Amount = 1;
copy.Amount = amt;
copy.DropTime = 30;
copy.bSpecial = copy.bSolid = false;
Amount--;
Amount -= amt;
}
return copy;
}

View file

@ -174,7 +174,7 @@ class Powerup : Inventory
//
//===========================================================================
override Inventory CreateTossable ()
override Inventory CreateTossable (int amount)
{
return NULL;
}

View file

@ -435,7 +435,7 @@ class Weapon : StateProvider native
//
//===========================================================================
override Inventory CreateTossable ()
override Inventory CreateTossable (int amt)
{
// Only drop the weapon that is meant to be placed in a level. That is,
// only drop the weapon that normally gives you ammo.
@ -443,9 +443,9 @@ class Weapon : StateProvider native
Default.AmmoGive1 == 0 && Default.AmmoGive2 == 0 &&
(SisterWeapon.Default.AmmoGive1 > 0 || SisterWeapon.Default.AmmoGive2 > 0))
{
return SisterWeapon.CreateTossable ();
return SisterWeapon.CreateTossable (amt);
}
let copy = Weapon(Super.CreateTossable ());
let copy = Weapon(Super.CreateTossable (-1));
if (copy != NULL)
{

View file

@ -0,0 +1,43 @@
//
// INTERMISSION
// Structure passed e.g. to WI_Start(wb)
//
struct WBPlayerStruct native
{
// Player stats, kills, collected items etc.
native int skills;
native int sitems;
native int ssecret;
native int stime;
native int frags[MAXPLAYERS];
native int fragcount; // [RH] Cumulative frags for this player
}
struct WBStartStruct native
{
native int finished_ep;
native int next_ep;
native String current; // [RH] Name of map just finished
native String next; // next level, [RH] actual map name
native TextureID LName0;
native TextureID LName1;
native int maxkills;
native int maxitems;
native int maxsecret;
native int maxfrags;
// the par time and sucktime
native int partime; // in tics
native int sucktime; // in minutes
// total time for the entire current game
native int totaltime;
// index of this player in game
native int pnum;
}

View file

@ -79,7 +79,7 @@ class Coin : Inventory
//
//===========================================================================
override Inventory CreateTossable ()
override Inventory CreateTossable (int amt)
{
Coin tossed;
@ -87,17 +87,20 @@ class Coin : Inventory
{
return NULL;
}
if (Amount >= 50)
if (amt == -1) amt = Amount >= 50? 50 : Amount >= 25? 25 : Amount >= 10? 10 : 1;
else if (amt > Amount) amt = Amount;
if (amt > 25)
{
Amount -= 50;
Amount -= amt;
tossed = Coin(Spawn("Gold50"));
tossed.Amount = amt;
}
else if (Amount >= 25)
else if (amt > 10)
{
Amount -= 25;
tossed = Coin(Spawn("Gold25"));
}
else if (Amount >= 10)
else if (amt > 1)
{
Amount -= 10;
tossed = Coin(Spawn("Gold10"));

View file

@ -2651,16 +2651,6 @@ flickerlight LGNTAIL
chance 0.8
}
object StrifeZap1
{
frame ZAP1A { light ARROWZAP1 }
frame ZAP1B { light ARROWZAP2 }
frame ZAP1C { light ARROWZAP3 }
frame ZAP1D { light ARROWZAP4 }
frame ZAP1E { light ARROWZAP5 }
frame ZAP1F { light ARROWZAP6 }
}
object SpectralLightningBase
{
frame ZAP1A { light ARROWZAP1 }
@ -2871,4 +2861,4 @@ object TeleportFog
frame TFOGD { light TFOG4 }
frame TFOGE { light TFOG5 }
frame TFOGF { light TFOG6 }
}
}