mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-29 15:12:11 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
# Conflicts: # src/r_main.cpp # src/r_things.cpp
This commit is contained in:
commit
43550742d5
64 changed files with 2349 additions and 107 deletions
|
@ -1033,6 +1033,7 @@ set (PCH_SOURCES
|
|||
scripting/zscript/zcc_compile.cpp
|
||||
scripting/zscript/zcc_parser.cpp
|
||||
sfmt/SFMT.cpp
|
||||
events.cpp
|
||||
)
|
||||
enable_precompiled_headers( g_pch.h PCH_SOURCES )
|
||||
|
||||
|
|
|
@ -626,6 +626,9 @@ public:
|
|||
virtual void BeginPlay(); // Called immediately after the actor is created
|
||||
void CallBeginPlay();
|
||||
|
||||
// [ZZ] custom postbeginplay (calls E_WorldThingSpawned)
|
||||
void CallPostBeginPlay() override;
|
||||
|
||||
void LevelSpawned(); // Called after BeginPlay if this actor was spawned by the world
|
||||
void HandleSpawnFlags(); // Translates SpawnFlags into in-game flags.
|
||||
|
||||
|
@ -1228,6 +1231,7 @@ public:
|
|||
bool InStateSequence(FState * newstate, FState * basestate);
|
||||
int GetTics(FState * newstate);
|
||||
bool SetState (FState *newstate, bool nofunction=false);
|
||||
virtual void SplashCheck();
|
||||
virtual bool UpdateWaterLevel (bool splash=true);
|
||||
bool isFast();
|
||||
bool isSlow();
|
||||
|
|
|
@ -61,6 +61,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC"
|
|||
#include "d_netinf.h"
|
||||
#include "d_player.h"
|
||||
#include "doomerrors.h"
|
||||
#include "events.h"
|
||||
|
||||
static FRandom pr_botspawn ("BotSpawn");
|
||||
|
||||
|
@ -418,6 +419,9 @@ void FCajunMaster::RemoveAllBots (bool fromlist)
|
|||
}
|
||||
}
|
||||
}
|
||||
// [ZZ] run event hook
|
||||
E_PlayerDisconnected(i);
|
||||
//
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Disconnect, players[i].mo, true, i, true);
|
||||
ClearPlayer (i, !fromlist);
|
||||
}
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
#include "c_consolebuffer.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
FString FStringFormat(VM_ARGS); // extern from thingdef_data.cpp
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
#define LEFTMARGIN 8
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
#include "autosegs.h"
|
||||
#include "fragglescript/t_fs.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
EXTERN_CVAR(Bool, hud_althud)
|
||||
void DrawHUD();
|
||||
|
@ -287,6 +288,9 @@ void D_ProcessEvents (void)
|
|||
continue; // console ate the event
|
||||
if (M_Responder (ev))
|
||||
continue; // menu ate the event
|
||||
// check events
|
||||
if (E_Responder(ev)) // [ZZ] ZScript ate the event
|
||||
continue;
|
||||
G_Responder (ev);
|
||||
}
|
||||
}
|
||||
|
@ -307,8 +311,7 @@ void D_PostEvent (const event_t *ev)
|
|||
return;
|
||||
}
|
||||
events[eventhead] = *ev;
|
||||
if (ev->type == EV_Mouse && !paused && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling
|
||||
)
|
||||
if (ev->type == EV_Mouse && !paused && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling && !E_CheckUiProcessors())
|
||||
{
|
||||
if (Button_Mlook.bDown || freelook)
|
||||
{
|
||||
|
@ -776,6 +779,9 @@ void D_Display ()
|
|||
screen->SetBlendingRect(viewwindowx, viewwindowy,
|
||||
viewwindowx + viewwidth, viewwindowy + viewheight);
|
||||
|
||||
// [ZZ] execute event hook that we just started the frame
|
||||
E_RenderFrame();
|
||||
//
|
||||
Renderer->RenderView(&players[consoleplayer]);
|
||||
|
||||
if ((hw2d = screen->Begin2D(viewactive)))
|
||||
|
@ -894,6 +900,8 @@ void D_Display ()
|
|||
{
|
||||
NetUpdate (); // send out any new accumulation
|
||||
// normal update
|
||||
// draw ZScript UI stuff
|
||||
E_RenderOverlay();
|
||||
C_DrawConsole (hw2d); // draw console
|
||||
M_Drawer (); // menu is drawn even on top of everything
|
||||
FStat::PrintStat ();
|
||||
|
@ -2831,10 +2839,10 @@ void FStartupScreen::NetMessage(char const *,...) {}
|
|||
void FStartupScreen::NetDone(void) {}
|
||||
bool FStartupScreen::NetLoop(bool (*)(void *),void *) { return false; }
|
||||
|
||||
DEFINE_FIELD_X(InputEvent, event_t, type)
|
||||
DEFINE_FIELD_X(InputEvent, event_t, subtype)
|
||||
DEFINE_FIELD_X(InputEvent, event_t, data1)
|
||||
DEFINE_FIELD_X(InputEvent, event_t, data2)
|
||||
DEFINE_FIELD_X(InputEvent, event_t, data3)
|
||||
DEFINE_FIELD_X(InputEvent, event_t, x)
|
||||
DEFINE_FIELD_X(InputEvent, event_t, y)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, type)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, subtype)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, data1)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, data2)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, data3)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, x)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, y)
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "a_keys.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
EXTERN_CVAR (Int, disableautosave)
|
||||
EXTERN_CVAR (Int, autosavecount)
|
||||
|
@ -2679,6 +2680,17 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
G_ChangeLevel(NULL, 0, 0);
|
||||
break;
|
||||
|
||||
case DEM_NETEVENT:
|
||||
{
|
||||
FString ename = ReadString(stream);
|
||||
int argn = ReadByte(stream);
|
||||
int arg[3] = { 0, 0, 0 };
|
||||
for (int i = 0; i < argn; i++)
|
||||
arg[i] = ReadLong(stream);
|
||||
E_Console(player, ename, arg[0], arg[1], arg[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
I_Error ("Unknown net command: %d", type);
|
||||
break;
|
||||
|
|
|
@ -159,6 +159,7 @@ enum EDemoCommand
|
|||
DEM_SETSLOTPNUM, // 67 Byte: player number, the rest is the same as DEM_SETSLOT
|
||||
DEM_REMOVE, // 68
|
||||
DEM_FINISHGAME, // 69
|
||||
DEM_NETEVENT // 70 String: Event name, Byte: Arg count; each arg is a 4-byte int
|
||||
};
|
||||
|
||||
// The following are implemented by cht_DoCheat in m_cheat.cpp
|
||||
|
|
|
@ -203,8 +203,9 @@ enum EObjectFlags
|
|||
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
|
||||
OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list
|
||||
OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk)
|
||||
OF_Released = 1 << 12, // Object was released from the GC system and should not be processed by GC function
|
||||
OF_Abstract = 1 << 13, // Marks a class that cannot be created with CreateNew
|
||||
OF_Spawned = 1 << 12, // Thinker was spawned at all (some thinkers get deleted before spawning)
|
||||
OF_Released = 1 << 13, // Object was released from the GC system and should not be processed by GC function
|
||||
OF_Abstract = 1 << 14, // Marks a class that cannot be created with CreateNew
|
||||
};
|
||||
|
||||
template<class T> class TObjPtr;
|
||||
|
|
|
@ -309,6 +309,7 @@ DEFINE_ACTION_FUNCTION(DThinker, PostBeginPlay)
|
|||
|
||||
void DThinker::CallPostBeginPlay()
|
||||
{
|
||||
ObjectFlags |= OF_Spawned;
|
||||
IFVIRTUAL(DThinker, PostBeginPlay)
|
||||
{
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
virtual void Tick ();
|
||||
void CallTick();
|
||||
virtual void PostBeginPlay (); // Called just before the first tick
|
||||
void CallPostBeginPlay();
|
||||
virtual void CallPostBeginPlay(); // different in actor.
|
||||
virtual void PostSerialize();
|
||||
size_t PropagateMark();
|
||||
|
||||
|
|
1117
src/events.cpp
Executable file
1117
src/events.cpp
Executable file
File diff suppressed because it is too large
Load diff
303
src/events.h
Executable file
303
src/events.h
Executable file
|
@ -0,0 +1,303 @@
|
|||
#ifndef EVENTS_H
|
||||
#define EVENTS_H
|
||||
|
||||
#include "dobject.h"
|
||||
#include "serializer.h"
|
||||
#include "d_event.h"
|
||||
#include "d_gui.h"
|
||||
|
||||
class DStaticEventHandler;
|
||||
|
||||
// register
|
||||
bool E_RegisterHandler(DStaticEventHandler* handler);
|
||||
// unregister
|
||||
bool E_UnregisterHandler(DStaticEventHandler* handler);
|
||||
// find
|
||||
bool E_CheckHandler(DStaticEventHandler* handler);
|
||||
// check type
|
||||
bool E_IsStaticType(PClass* type);
|
||||
// init static handlers
|
||||
void E_InitStaticHandlers(bool map);
|
||||
// shutdown handlers
|
||||
void E_Shutdown(bool map);
|
||||
|
||||
// called right after the map has loaded (approximately same time as OPEN ACS scripts)
|
||||
void E_WorldLoaded();
|
||||
// called when the map is about to unload (approximately same time as UNLOADING ACS scripts)
|
||||
void E_WorldUnloaded();
|
||||
// called right after the map has loaded (every time, UNSAFE VERSION)
|
||||
void E_WorldLoadedUnsafe();
|
||||
// called right before the map is unloaded (every time, UNSAFE VERSION)
|
||||
void E_WorldUnloadedUnsafe();
|
||||
// called around PostBeginPlay of each actor.
|
||||
void E_WorldThingSpawned(AActor* actor);
|
||||
// called after AActor::Die of each actor.
|
||||
void E_WorldThingDied(AActor* actor, AActor* inflictor);
|
||||
// called after AActor::Revive.
|
||||
void E_WorldThingRevived(AActor* actor);
|
||||
// called before P_DamageMobj and before AActor::DamageMobj virtuals.
|
||||
void E_WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle);
|
||||
// called before AActor::Destroy of each actor.
|
||||
void E_WorldThingDestroyed(AActor* actor);
|
||||
// same as ACS SCRIPT_Lightning
|
||||
void E_WorldLightning();
|
||||
// this executes on every tick, before everything
|
||||
void E_WorldTick();
|
||||
// called on each render frame once.
|
||||
void E_RenderFrame();
|
||||
// called after everything's been rendered, but before console/menus
|
||||
void E_RenderOverlay();
|
||||
// this executes when a player enters the level (once). PlayerEnter+inhub = RETURN
|
||||
void E_PlayerEntered(int num, bool fromhub);
|
||||
// this executes when a player respawns. includes resurrect cheat.
|
||||
void E_PlayerRespawned(int num);
|
||||
// this executes when a player dies (partially duplicating worldthingdied, but whatever)
|
||||
void E_PlayerDied(int num);
|
||||
// this executes when a player leaves the game
|
||||
void E_PlayerDisconnected(int num);
|
||||
// this executes on events.
|
||||
bool E_Responder(event_t* ev); // splits events into InputProcess and UiProcess
|
||||
// this executes on console/net events.
|
||||
void E_Console(int player, FString name, int arg1, int arg2, int arg3);
|
||||
|
||||
// check if there is anything that should receive GUI events
|
||||
bool E_CheckUiProcessors();
|
||||
// check if we need native mouse due to UiProcessors
|
||||
bool E_CheckRequireMouse();
|
||||
|
||||
// serialization stuff
|
||||
void E_SerializeEvents(FSerializer& arc);
|
||||
|
||||
// ==============================================
|
||||
//
|
||||
// EventHandler - base class
|
||||
//
|
||||
// ==============================================
|
||||
|
||||
class DStaticEventHandler : public DObject // make it a part of normal GC process
|
||||
{
|
||||
DECLARE_CLASS(DStaticEventHandler, DObject)
|
||||
public:
|
||||
DStaticEventHandler()
|
||||
{
|
||||
prev = 0;
|
||||
next = 0;
|
||||
Order = 0;
|
||||
IsUiProcessor = false;
|
||||
}
|
||||
|
||||
DStaticEventHandler* prev;
|
||||
DStaticEventHandler* next;
|
||||
virtual bool IsStatic() { return true; }
|
||||
|
||||
//
|
||||
int Order;
|
||||
bool IsUiProcessor;
|
||||
bool RequireMouse;
|
||||
|
||||
// serialization handler. let's keep it here so that I don't get lost in serialized/not serialized fields
|
||||
void Serialize(FSerializer& arc) override
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
if (arc.isReading())
|
||||
{
|
||||
Printf("DStaticEventHandler::Serialize: reading object %s\n", GetClass()->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars());
|
||||
}
|
||||
|
||||
arc("Order", Order);
|
||||
arc("IsUiProcessor", IsUiProcessor);
|
||||
arc("RequireMouse", RequireMouse);
|
||||
}
|
||||
|
||||
// destroy handler. this unlinks EventHandler from the list automatically.
|
||||
void OnDestroy() override;
|
||||
|
||||
//
|
||||
void OnRegister(); // you can set order and IsUi here.
|
||||
void OnUnregister();
|
||||
|
||||
//
|
||||
void WorldLoaded();
|
||||
void WorldUnloaded();
|
||||
void WorldThingSpawned(AActor*);
|
||||
void WorldThingDied(AActor*, AActor*);
|
||||
void WorldThingRevived(AActor*);
|
||||
void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle);
|
||||
void WorldThingDestroyed(AActor*);
|
||||
void WorldLightning();
|
||||
void WorldTick();
|
||||
|
||||
//
|
||||
void RenderFrame();
|
||||
void RenderOverlay();
|
||||
|
||||
//
|
||||
void PlayerEntered(int num, bool fromhub);
|
||||
void PlayerRespawned(int num);
|
||||
void PlayerDied(int num);
|
||||
void PlayerDisconnected(int num);
|
||||
|
||||
// return true if handled.
|
||||
bool InputProcess(event_t* ev);
|
||||
bool UiProcess(event_t* ev);
|
||||
|
||||
//
|
||||
void ConsoleProcess(int player, FString name, int arg1, int arg2, int arg3);
|
||||
};
|
||||
class DEventHandler : public DStaticEventHandler
|
||||
{
|
||||
DECLARE_CLASS(DEventHandler, DStaticEventHandler) // TODO: make sure this does not horribly break anything
|
||||
public:
|
||||
bool IsStatic() override { return false; }
|
||||
};
|
||||
extern DStaticEventHandler* E_FirstEventHandler;
|
||||
|
||||
// we cannot call this DEvent because in ZScript, 'event' is a keyword
|
||||
class DBaseEvent : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DBaseEvent, DObject)
|
||||
public:
|
||||
|
||||
DBaseEvent()
|
||||
{
|
||||
// each type of event is created only once to avoid new/delete hell
|
||||
// since from what I remember object creation and deletion results in a lot of GC processing
|
||||
// (and we aren't supposed to pass event objects around anyway)
|
||||
this->ObjectFlags |= OF_Fixed;
|
||||
// we don't want to store events into the savegames because they are global.
|
||||
this->ObjectFlags |= OF_Transient;
|
||||
}
|
||||
};
|
||||
|
||||
class DRenderEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DRenderEvent, DBaseEvent)
|
||||
public:
|
||||
// these are for all render events
|
||||
DVector3 ViewPos;
|
||||
DAngle ViewAngle;
|
||||
DAngle ViewPitch;
|
||||
DAngle ViewRoll;
|
||||
double FracTic; // 0..1 value that describes where we are inside the current gametic, render-wise.
|
||||
AActor* Camera;
|
||||
|
||||
DRenderEvent()
|
||||
{
|
||||
FracTic = 0;
|
||||
Camera = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class DWorldEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DWorldEvent, DBaseEvent)
|
||||
public:
|
||||
// for loaded/unloaded
|
||||
bool IsSaveGame;
|
||||
bool IsReopen;
|
||||
// for thingspawned, thingdied, thingdestroyed
|
||||
AActor* Thing;
|
||||
// for thingdied
|
||||
AActor* Inflictor; // can be null
|
||||
// for damagemobj
|
||||
int Damage;
|
||||
AActor* DamageSource; // can be null
|
||||
FName DamageType;
|
||||
int DamageFlags;
|
||||
DAngle DamageAngle;
|
||||
|
||||
DWorldEvent()
|
||||
{
|
||||
IsSaveGame = false;
|
||||
IsReopen = false;
|
||||
Thing = nullptr;
|
||||
Inflictor = nullptr;
|
||||
Damage = 0;
|
||||
DamageSource = nullptr;
|
||||
DamageFlags = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class DPlayerEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DPlayerEvent, DBaseEvent)
|
||||
public:
|
||||
// we currently have only one member: player index
|
||||
// in ZScript, we have global players[] array from which we can
|
||||
// get both the player itself and player's body,
|
||||
// so no need to pass it here.
|
||||
int PlayerNumber;
|
||||
// we set this to true if level was reopened (RETURN scripts)
|
||||
bool IsReturn;
|
||||
|
||||
DPlayerEvent()
|
||||
{
|
||||
PlayerNumber = -1;
|
||||
IsReturn = false;
|
||||
}
|
||||
};
|
||||
|
||||
class DUiEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DUiEvent, DBaseEvent)
|
||||
public:
|
||||
// this essentially translates event_t UI events to ZScript.
|
||||
EGUIEvent Type;
|
||||
// for keys/chars/whatever
|
||||
FString KeyString;
|
||||
int KeyChar;
|
||||
// for mouse
|
||||
int MouseX;
|
||||
int MouseY;
|
||||
// global (?)
|
||||
bool IsShift;
|
||||
bool IsCtrl;
|
||||
bool IsAlt;
|
||||
|
||||
DUiEvent()
|
||||
{
|
||||
Type = EV_GUI_None;
|
||||
}
|
||||
};
|
||||
|
||||
class DInputEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DInputEvent, DBaseEvent)
|
||||
public:
|
||||
// this translates regular event_t events to ZScript (not UI, UI events are sent via DUiEvent and only if requested!)
|
||||
EGenericEvent Type;
|
||||
// for keys
|
||||
int KeyScan;
|
||||
FString KeyString;
|
||||
int KeyChar;
|
||||
// for mouse
|
||||
int MouseX;
|
||||
int MouseY;
|
||||
|
||||
DInputEvent()
|
||||
{
|
||||
Type = EV_None;
|
||||
}
|
||||
};
|
||||
|
||||
class DConsoleEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DConsoleEvent, DBaseEvent)
|
||||
public:
|
||||
// player that activated this event. note that it's always -1 for non-playsim events (i.e. these not called with netevent)
|
||||
int Player;
|
||||
//
|
||||
FString Name;
|
||||
int Args[3];
|
||||
|
||||
DConsoleEvent()
|
||||
{
|
||||
Player = -1;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -92,6 +92,7 @@
|
|||
|
||||
#include "g_hub.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
|
||||
static FRandom pr_dmspawn ("DMSpawn");
|
||||
|
@ -1792,6 +1793,8 @@ void G_DoPlayerPop(int playernum)
|
|||
|
||||
// [RH] Make the player disappear
|
||||
FBehavior::StaticStopMyScripts(players[playernum].mo);
|
||||
// [ZZ] fire player disconnect hook
|
||||
E_PlayerDisconnected(playernum);
|
||||
// [RH] Let the scripts know the player left
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Disconnect, players[playernum].mo, true, playernum, true);
|
||||
if (players[playernum].mo != NULL)
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#include "p_spec.h"
|
||||
#include "serializer.h"
|
||||
#include "virtual.h"
|
||||
#include "events.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
@ -406,6 +407,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
bool wantFast;
|
||||
int i;
|
||||
|
||||
// did we have any level before?
|
||||
if (level.info != nullptr)
|
||||
E_WorldUnloadedUnsafe();
|
||||
|
||||
if (!savegamerestore)
|
||||
{
|
||||
G_ClearHubInfo();
|
||||
|
@ -655,6 +660,10 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
|
|||
// [RH] Give scripts a chance to do something
|
||||
unloading = true;
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true);
|
||||
// [ZZ] safe world unload
|
||||
E_WorldUnloaded();
|
||||
// [ZZ] unsafe world unload (changemap != map)
|
||||
E_WorldUnloadedUnsafe();
|
||||
unloading = false;
|
||||
|
||||
STAT_ChangeLevel(nextlevel);
|
||||
|
@ -1012,6 +1021,7 @@ void G_DoLoadLevel (int position, bool autosave)
|
|||
}
|
||||
|
||||
level.maptime = 0;
|
||||
|
||||
P_SetupLevel (level.MapName, position);
|
||||
|
||||
AM_LevelInit();
|
||||
|
@ -1053,6 +1063,7 @@ void G_DoLoadLevel (int position, bool autosave)
|
|||
}
|
||||
|
||||
level.starttime = gametic;
|
||||
|
||||
G_UnSnapshotLevel (!savegamerestore); // [RH] Restore the state of the level.
|
||||
G_FinishTravel ();
|
||||
// For each player, if they are viewing through a player, make sure it is themselves.
|
||||
|
@ -1064,6 +1075,10 @@ void G_DoLoadLevel (int position, bool autosave)
|
|||
}
|
||||
}
|
||||
StatusBar->AttachToPlayer (&players[consoleplayer]);
|
||||
// unsafe world load
|
||||
E_WorldLoadedUnsafe();
|
||||
// regular world load (savegames are handled internally)
|
||||
E_WorldLoaded();
|
||||
P_DoDeferedScripts (); // [RH] Do script actions that were triggered on another map.
|
||||
|
||||
if (demoplayback || oldgs == GS_STARTUP || oldgs == GS_TITLELEVEL)
|
||||
|
@ -1241,6 +1256,10 @@ void G_FinishTravel ()
|
|||
FPlayerStart *start;
|
||||
int pnum;
|
||||
|
||||
//
|
||||
APlayerPawn* pawns[MAXPLAYERS];
|
||||
int pawnsnum = 0;
|
||||
|
||||
next = it.Next ();
|
||||
while ( (pawn = next) != NULL)
|
||||
{
|
||||
|
@ -1332,12 +1351,23 @@ void G_FinishTravel ()
|
|||
{
|
||||
pawn->Speed = pawn->GetDefault()->Speed;
|
||||
}
|
||||
if (level.FromSnapshot)
|
||||
{
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Return, pawn, true);
|
||||
// [ZZ] we probably don't want to fire any scripts before all players are in, especially with runNow = true.
|
||||
pawns[pawnsnum++] = pawn;
|
||||
}
|
||||
|
||||
// [Nash] run REOPEN scripts upon map re-entry
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Reopen, NULL, false);
|
||||
// [ZZ] fire the reopen hook.
|
||||
// if level is loaded from snapshot, and we don't have savegamerestore, this means we returned from a hub.
|
||||
if (level.FromSnapshot)
|
||||
{
|
||||
// [Nash] run REOPEN scripts upon map re-entry
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Reopen, NULL, false);
|
||||
|
||||
for (int i = 0; i < pawnsnum; i++)
|
||||
{
|
||||
// [ZZ] fire the enter hook.
|
||||
E_PlayerEntered(pawns[i]->player - players, true);
|
||||
//
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Return, pawns[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -338,6 +338,8 @@ struct level_info_t
|
|||
TArray<FSoundID> PrecacheSounds;
|
||||
TArray<FString> PrecacheTextures;
|
||||
TArray<FName> PrecacheClasses;
|
||||
|
||||
TArray<FString> EventHandlers;
|
||||
|
||||
level_info_t()
|
||||
{
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "version.h"
|
||||
#include "v_text.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
TArray<cluster_info_t> wadclusterinfos;
|
||||
TArray<level_info_t> wadlevelinfos;
|
||||
|
@ -1046,6 +1047,17 @@ DEFINE_MAP_OPTION(PrecacheSounds, true)
|
|||
} while (parse.sc.CheckString(","));
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(EventHandlers, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
|
||||
do
|
||||
{
|
||||
parse.sc.MustGetString();
|
||||
info->EventHandlers.Push(parse.sc.String);
|
||||
} while (parse.sc.CheckString(","));
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(PrecacheTextures, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "r_state.h"
|
||||
#include "serializer.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
static FRandom pr_lightning ("Lightning");
|
||||
|
||||
|
@ -129,6 +130,9 @@ void DLightningThinker::LightningFlash ()
|
|||
|
||||
level.flags |= LEVEL_SWAPSKIES; // set alternate sky
|
||||
S_Sound (CHAN_AUTO, "world/thunder", 1.0, ATTN_NONE);
|
||||
// [ZZ] just in case
|
||||
E_WorldLightning();
|
||||
// start LIGHTNING scripts
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Lightning, NULL, false); // [RH] Run lightning scripts
|
||||
|
||||
// Calculate the next lighting flash
|
||||
|
|
|
@ -1442,7 +1442,7 @@ class CommandDrawNumber : public CommandDrawString
|
|||
int retv;
|
||||
VMReturn ret(&retv);
|
||||
GlobalVMStack.Call(func, params, 2, &ret, 1);
|
||||
num = retv / TICRATE + 1;
|
||||
num = retv < 0? 0 : retv / TICRATE + 1;
|
||||
break;
|
||||
}
|
||||
case INVENTORY:
|
||||
|
|
|
@ -317,6 +317,8 @@ void FMapInfoParser::ParseGameInfo()
|
|||
GAMEINFOKEY_STRINGARRAY(PrecachedClasses, "precacheclasses", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(PrecachedTextures, "precachetextures", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(PrecachedSounds, "precachesounds", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(EventHandlers, "addeventhandlers", 0, true)
|
||||
GAMEINFOKEY_STRINGARRAY(EventHandlers, "eventhandlers", 0, false)
|
||||
GAMEINFOKEY_STRING(PauseSign, "pausesign")
|
||||
GAMEINFOKEY_STRING(quitSound, "quitSound")
|
||||
GAMEINFOKEY_STRING(BorderFlat, "borderFlat")
|
||||
|
|
1
src/gi.h
1
src/gi.h
|
@ -124,6 +124,7 @@ struct gameinfo_t
|
|||
TArray<FName> PrecachedClasses;
|
||||
TArray<FString> PrecachedTextures;
|
||||
TArray<FSoundID> PrecachedSounds;
|
||||
TArray<FString> EventHandlers;
|
||||
|
||||
FString titleMusic;
|
||||
int titleOrder;
|
||||
|
|
|
@ -97,6 +97,28 @@ void gl_CreateSections();
|
|||
void AdjustSpriteOffsets()
|
||||
{
|
||||
int lump, lastlump = 0;
|
||||
int sprid;
|
||||
TMap<int, bool> donotprocess;
|
||||
|
||||
int numtex = Wads.GetNumLumps();
|
||||
|
||||
for (int i = 0; i < numtex; i++)
|
||||
{
|
||||
if (Wads.GetLumpFile(i) > 1) break; // we are past the IWAD
|
||||
if (Wads.GetLumpNamespace(i) == ns_sprites && Wads.GetLumpFile(i) == FWadCollection::IWAD_FILENUM)
|
||||
{
|
||||
char str[9];
|
||||
Wads.GetLumpName(str, i);
|
||||
FTextureID texid = TexMan.CheckForTexture(str, FTexture::TEX_Sprite, 0);
|
||||
if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > FWadCollection::IWAD_FILENUM)
|
||||
{
|
||||
// This texture has been replaced by some PWAD.
|
||||
memcpy(&sprid, str, 4);
|
||||
donotprocess[sprid] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((lump = Wads.FindLump("SPROFS", &lastlump, false)) != -1)
|
||||
{
|
||||
FScanner sc;
|
||||
|
@ -108,6 +130,7 @@ void AdjustSpriteOffsets()
|
|||
{
|
||||
int x,y;
|
||||
bool iwadonly = false;
|
||||
bool forced = false;
|
||||
FTextureID texno = TexMan.CheckForTexture(sc.String, FTexture::TEX_Sprite);
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
|
@ -119,6 +142,7 @@ void AdjustSpriteOffsets()
|
|||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("iwad")) iwadonly = true;
|
||||
if (sc.Compare("iwadforced")) forced = iwadonly = true;
|
||||
}
|
||||
if (texno.isValid())
|
||||
{
|
||||
|
@ -131,6 +155,11 @@ void AdjustSpriteOffsets()
|
|||
int wadno = Wads.GetLumpFile(lumpnum);
|
||||
if ((iwadonly && wadno==FWadCollection::IWAD_FILENUM) || (!iwadonly && wadno == ofslumpno))
|
||||
{
|
||||
if (wadno == FWadCollection::IWAD_FILENUM && !forced && iwadonly)
|
||||
{
|
||||
memcpy(&sprid, &tex->Name[0], 4);
|
||||
if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced.
|
||||
}
|
||||
tex->LeftOffset=x;
|
||||
tex->TopOffset=y;
|
||||
tex->KillNative();
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "gl/gl_functions.h"
|
||||
#include "serializer.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "a_pickups.h"
|
||||
#include "d_player.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
|
|
|
@ -192,7 +192,7 @@ private:
|
|||
bool PutWallCompat(int passflag);
|
||||
void PutWall(bool translucent);
|
||||
void PutPortal(int ptype);
|
||||
void CheckTexturePosition();
|
||||
void CheckTexturePosition(FTexCoordInfo *tci);
|
||||
|
||||
void RenderFogBoundaryCompat();
|
||||
void RenderLightsCompat(int pass);
|
||||
|
|
|
@ -626,7 +626,7 @@ bool GLWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::CheckTexturePosition()
|
||||
void GLWall::CheckTexturePosition(FTexCoordInfo *tci)
|
||||
{
|
||||
float sub;
|
||||
|
||||
|
@ -634,23 +634,47 @@ void GLWall::CheckTexturePosition()
|
|||
|
||||
// clamp texture coordinates to a reasonable range.
|
||||
// Extremely large values can cause visual problems
|
||||
if (tcs[UPLFT].v < tcs[UPRGT].v)
|
||||
if (tci->mScale.Y > 0)
|
||||
{
|
||||
sub = float(xs_FloorToInt(tcs[UPLFT].v));
|
||||
if (tcs[UPLFT].v < tcs[UPRGT].v)
|
||||
{
|
||||
sub = float(xs_FloorToInt(tcs[UPLFT].v));
|
||||
}
|
||||
else
|
||||
{
|
||||
sub = float(xs_FloorToInt(tcs[UPRGT].v));
|
||||
}
|
||||
tcs[UPLFT].v -= sub;
|
||||
tcs[UPRGT].v -= sub;
|
||||
tcs[LOLFT].v -= sub;
|
||||
tcs[LORGT].v -= sub;
|
||||
|
||||
if ((tcs[UPLFT].v == 0.f && tcs[UPRGT].v == 0.f && tcs[LOLFT].v <= 1.f && tcs[LORGT].v <= 1.f) ||
|
||||
(tcs[UPLFT].v >= 0.f && tcs[UPRGT].v >= 0.f && tcs[LOLFT].v == 1.f && tcs[LORGT].v == 1.f))
|
||||
{
|
||||
flags |= GLT_CLAMPY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sub = float(xs_FloorToInt(tcs[UPRGT].v));
|
||||
}
|
||||
tcs[UPLFT].v -= sub;
|
||||
tcs[UPRGT].v -= sub;
|
||||
tcs[LOLFT].v -= sub;
|
||||
tcs[LORGT].v -= sub;
|
||||
if (tcs[LOLFT].v < tcs[LORGT].v)
|
||||
{
|
||||
sub = float(xs_FloorToInt(tcs[LOLFT].v));
|
||||
}
|
||||
else
|
||||
{
|
||||
sub = float(xs_FloorToInt(tcs[LORGT].v));
|
||||
}
|
||||
tcs[UPLFT].v -= sub;
|
||||
tcs[UPRGT].v -= sub;
|
||||
tcs[LOLFT].v -= sub;
|
||||
tcs[LORGT].v -= sub;
|
||||
|
||||
if ((tcs[UPLFT].v == 0.f && tcs[UPRGT].v == 0.f && tcs[LOLFT].v <= 1.f && tcs[LORGT].v <= 1.f) ||
|
||||
(tcs[UPLFT].v >= 0.f && tcs[UPRGT].v >= 0.f && tcs[LOLFT].v == 1.f && tcs[LORGT].v == 1.f))
|
||||
{
|
||||
flags |= GLT_CLAMPY;
|
||||
if ((tcs[LOLFT].v == 0.f && tcs[LORGT].v == 0.f && tcs[UPLFT].v <= 1.f && tcs[UPRGT].v <= 1.f) ||
|
||||
(tcs[LOLFT].v >= 0.f && tcs[LORGT].v >= 0.f && tcs[UPLFT].v == 1.f && tcs[UPRGT].v == 1.f))
|
||||
{
|
||||
flags |= GLT_CLAMPY;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is marked as a skybox and if so, do the same for x.
|
||||
|
@ -721,7 +745,7 @@ void GLWall::DoTexture(int _type,seg_t * seg, int peg,
|
|||
else
|
||||
{
|
||||
|
||||
CheckTexturePosition();
|
||||
CheckTexturePosition(&tci);
|
||||
|
||||
// Add this wall to the render list
|
||||
sector_t * sec = sub ? sub->sector : seg->frontsector;
|
||||
|
@ -1139,7 +1163,7 @@ void GLWall::BuildFFBlock(seg_t * seg, F3DFloor * rover,
|
|||
tcs[LOLFT].v = tci.FloatToTexV(to - ff_bottomleft);
|
||||
tcs[LORGT].v = tci.FloatToTexV(to - ff_bottomright);
|
||||
type = RENDERWALL_FFBLOCK;
|
||||
CheckTexturePosition();
|
||||
CheckTexturePosition(&tci);
|
||||
}
|
||||
|
||||
ztop[0] = ff_topleft;
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "thingdef.h"
|
||||
#include "d_player.h"
|
||||
#include "doomerrors.h"
|
||||
#include "events.h"
|
||||
|
||||
extern void LoadActors ();
|
||||
extern void InitBotStuff();
|
||||
|
@ -210,6 +211,9 @@ void PClassActor::StaticInit()
|
|||
ClearStrifeTypes();
|
||||
LoadActors ();
|
||||
InitBotStuff();
|
||||
|
||||
// reinit GLOBAL static stuff from gameinfo, once classes are loaded.
|
||||
E_InitStaticHandlers(false);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "a_morph.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "virtual.h"
|
||||
#include "events.h"
|
||||
|
||||
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
||||
// writes some bytes to the network data stream, and the network code
|
||||
|
@ -348,6 +349,12 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
P_UndoPlayerMorph(player, player);
|
||||
}
|
||||
|
||||
// player is now alive.
|
||||
// fire E_PlayerRespawned and start the ACS SCRIPT_Respawn.
|
||||
E_PlayerRespawned(player - players);
|
||||
//
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Respawn, player->mo, true);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -381,7 +381,7 @@ void DMenu::Ticker ()
|
|||
DEFINE_ACTION_FUNCTION(DMenu, Ticker)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DMenu);
|
||||
self->Drawer();
|
||||
self->Ticker();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ void DMenu::CallTicker()
|
|||
VMValue params[] = { (DObject*)this };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
|
||||
}
|
||||
else Drawer();
|
||||
else Ticker();
|
||||
}
|
||||
|
||||
|
||||
|
@ -448,6 +448,12 @@ DEFINE_ACTION_FUNCTION(DMenu, GetItem)
|
|||
ACTION_RETURN_OBJECT(self->GetItem(name));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DOptionMenuDescriptor, GetItem)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DOptionMenuDescriptor);
|
||||
PARAM_NAME(name);
|
||||
ACTION_RETURN_OBJECT(self->GetItem(name));
|
||||
}
|
||||
|
||||
|
||||
bool DMenu::DimAllowed()
|
||||
|
|
|
@ -1021,7 +1021,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlaySound)
|
|||
|
||||
if (!looping)
|
||||
{
|
||||
S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local);
|
||||
if (!(channel & CHAN_NOSTOP) || !S_IsActorPlayingSomething(self, channel & 7, soundid))
|
||||
{
|
||||
S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "a_morph.h"
|
||||
#include "virtual.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
static FRandom pr_obituary ("Obituary");
|
||||
static FRandom pr_botrespawn ("BotRespawn");
|
||||
|
@ -385,6 +386,9 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
|
|||
target = source;
|
||||
}
|
||||
|
||||
// [ZZ] Fire WorldThingDied script hook.
|
||||
E_WorldThingDied(this, inflictor);
|
||||
|
||||
// [JM] Fire KILL type scripts for actor. Not needed for players, since they have the "DEATH" script type.
|
||||
if (!player && !(flags7 & MF7_NOKILLSCRIPTS) && ((flags7 & MF7_USEKILLSCRIPTS) || gameinfo.forcekillscripts))
|
||||
{
|
||||
|
@ -607,6 +611,9 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
|
|||
// [RH] Death messages
|
||||
ClientObituary (this, inflictor, source, dmgflags);
|
||||
|
||||
// [ZZ] fire player death hook
|
||||
E_PlayerDied(player - players);
|
||||
|
||||
// Death script execution, care of Skull Tag
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Death, this, true);
|
||||
|
||||
|
@ -1594,7 +1601,12 @@ DEFINE_ACTION_FUNCTION(AActor, DamageMobj)
|
|||
PARAM_NAME(mod);
|
||||
PARAM_INT_DEF(flags);
|
||||
PARAM_FLOAT_DEF(angle);
|
||||
ACTION_RETURN_INT(DamageMobj(self, inflictor, source, damage, mod, flags, angle));
|
||||
|
||||
// [ZZ] event handlers need the result.
|
||||
int realdamage = DamageMobj(self, inflictor, source, damage, mod, flags, angle);
|
||||
if (!realdamage) ACTION_RETURN_INT(0);
|
||||
E_WorldThingDamaged(self, inflictor, source, realdamage, mod, flags, angle);
|
||||
ACTION_RETURN_INT(realdamage);
|
||||
}
|
||||
|
||||
int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle)
|
||||
|
@ -1608,7 +1620,14 @@ int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
GlobalVMStack.Call(func, params, 7, &ret, 1, nullptr);
|
||||
return retval;
|
||||
}
|
||||
else return DamageMobj(target, inflictor, source, damage, mod, flags, angle);
|
||||
else
|
||||
{
|
||||
int realdamage = DamageMobj(target, inflictor, source, damage, mod, flags, angle);
|
||||
if (!realdamage) return 0;
|
||||
// [ZZ] event handlers only need the resultant damage (they can't do anything about it anyway)
|
||||
E_WorldThingDamaged(target, inflictor, source, realdamage, mod, flags, angle);
|
||||
return realdamage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5288,6 +5288,14 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end,
|
|||
if (P_ActivateThingSpecial(in->d.thing, usething))
|
||||
return true;
|
||||
}
|
||||
IFVIRTUALPTR(usething, AActor, Used)
|
||||
{
|
||||
VMValue params[] = { usething, in->d.thing };
|
||||
int ret;
|
||||
VMReturn vret(&ret);
|
||||
GlobalVMStack.Call(func, params, 2, &vret, 1);
|
||||
if (ret) return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
149
src/p_mobj.cpp
149
src/p_mobj.cpp
|
@ -72,6 +72,7 @@
|
|||
#include "virtual.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "a_morph.h"
|
||||
#include "events.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -4540,23 +4541,22 @@ void AActor::CheckSectorTransition(sector_t *oldsec)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// AActor::UpdateWaterLevel
|
||||
// AActor::SplashCheck
|
||||
//
|
||||
// Returns true if actor should splash
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool AActor::UpdateWaterLevel (bool dosplash)
|
||||
void AActor::SplashCheck()
|
||||
{
|
||||
BYTE lastwaterlevel = waterlevel;
|
||||
double fh = -FLT_MAX;
|
||||
bool reset=false;
|
||||
bool reset = false;
|
||||
|
||||
waterlevel = 0;
|
||||
|
||||
if (Sector == NULL)
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Sector->MoreFlags & SECF_UNDERWATER) // intentionally not SECF_UNDERWATERMASK
|
||||
|
@ -4568,7 +4568,7 @@ bool AActor::UpdateWaterLevel (bool dosplash)
|
|||
const sector_t *hsec = Sector->GetHeightSec();
|
||||
if (hsec != NULL)
|
||||
{
|
||||
fh = hsec->floorplane.ZatPoint (this);
|
||||
fh = hsec->floorplane.ZatPoint(this);
|
||||
//if (hsec->MoreFlags & SECF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors
|
||||
{
|
||||
if (Z() < fh)
|
||||
|
@ -4584,7 +4584,7 @@ bool AActor::UpdateWaterLevel (bool dosplash)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint (this)))
|
||||
else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this)))
|
||||
{
|
||||
waterlevel = 3;
|
||||
}
|
||||
|
@ -4593,29 +4593,23 @@ bool AActor::UpdateWaterLevel (bool dosplash)
|
|||
waterlevel = 0;
|
||||
}
|
||||
}
|
||||
// even non-swimmable deep water must be checked here to do the splashes correctly
|
||||
// But the water level must be reset when this function returns
|
||||
if (!(hsec->MoreFlags&SECF_UNDERWATERMASK))
|
||||
{
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check 3D floors as well!
|
||||
for(auto rover : Sector->e->XFloor.ffloors)
|
||||
for (auto rover : Sector->e->XFloor.ffloors)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS)) continue;
|
||||
if (rover->flags & FF_SOLID) continue;
|
||||
|
||||
reset = !(rover->flags & FF_SWIMMABLE);
|
||||
bool reset = !(rover->flags & FF_SWIMMABLE);
|
||||
if (reset && rover->alpha == 0) continue;
|
||||
double ff_bottom=rover->bottom.plane->ZatPoint(this);
|
||||
double ff_top=rover->top.plane->ZatPoint(this);
|
||||
double ff_bottom = rover->bottom.plane->ZatPoint(this);
|
||||
double ff_top = rover->top.plane->ZatPoint(this);
|
||||
|
||||
if(ff_top <= Z() || ff_bottom > (Center())) continue;
|
||||
|
||||
fh=ff_top;
|
||||
if (ff_top <= Z() || ff_bottom > (Center())) continue;
|
||||
|
||||
fh = ff_top;
|
||||
if (Z() < fh)
|
||||
{
|
||||
waterlevel = 1;
|
||||
|
@ -4634,17 +4628,106 @@ bool AActor::UpdateWaterLevel (bool dosplash)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// some additional checks to make deep sectors like Boom's splash without setting
|
||||
// the water flags.
|
||||
if (boomwaterlevel == 0 && waterlevel != 0 && dosplash)
|
||||
if (boomwaterlevel == 0 && waterlevel != 0)
|
||||
{
|
||||
P_HitWater(this, Sector, PosAtZ(fh), true);
|
||||
}
|
||||
boomwaterlevel = waterlevel;
|
||||
if (reset)
|
||||
return;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AActor::UpdateWaterLevel
|
||||
//
|
||||
// Returns true if actor should splash
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool AActor::UpdateWaterLevel(bool dosplash)
|
||||
{
|
||||
if (dosplash) SplashCheck();
|
||||
|
||||
double fh = -FLT_MAX;
|
||||
bool reset = false;
|
||||
|
||||
waterlevel = 0;
|
||||
|
||||
if (Sector == NULL)
|
||||
{
|
||||
waterlevel = lastwaterlevel;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Sector->MoreFlags & SECF_UNDERWATER) // intentionally not SECF_UNDERWATERMASK
|
||||
{
|
||||
waterlevel = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
const sector_t *hsec = Sector->GetHeightSec();
|
||||
if (hsec != NULL)
|
||||
{
|
||||
fh = hsec->floorplane.ZatPoint(this);
|
||||
if (hsec->MoreFlags & SECF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors
|
||||
{
|
||||
if (Z() < fh)
|
||||
{
|
||||
waterlevel = 1;
|
||||
if (Center() < fh)
|
||||
{
|
||||
waterlevel = 2;
|
||||
if ((player && Z() + player->viewheight <= fh) ||
|
||||
(Top() <= fh))
|
||||
{
|
||||
waterlevel = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this)))
|
||||
{
|
||||
waterlevel = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
waterlevel = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check 3D floors as well!
|
||||
for (auto rover : Sector->e->XFloor.ffloors)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS)) continue;
|
||||
if (rover->flags & FF_SOLID) continue;
|
||||
if (!(rover->flags & FF_SWIMMABLE)) continue;
|
||||
|
||||
double ff_bottom = rover->bottom.plane->ZatPoint(this);
|
||||
double ff_top = rover->top.plane->ZatPoint(this);
|
||||
|
||||
if (ff_top <= Z() || ff_bottom > (Center())) continue;
|
||||
|
||||
fh = ff_top;
|
||||
if (Z() < fh)
|
||||
{
|
||||
waterlevel = 1;
|
||||
if (Center() < fh)
|
||||
{
|
||||
waterlevel = 2;
|
||||
if ((player && Z() + player->viewheight <= fh) ||
|
||||
(Top() <= fh))
|
||||
{
|
||||
waterlevel = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false; // we did the splash ourselves
|
||||
}
|
||||
|
@ -4974,6 +5057,12 @@ void AActor::PostBeginPlay ()
|
|||
flags7 |= MF7_HANDLENODELAY;
|
||||
}
|
||||
|
||||
void AActor::CallPostBeginPlay()
|
||||
{
|
||||
Super::CallPostBeginPlay();
|
||||
E_WorldThingSpawned(this);
|
||||
}
|
||||
|
||||
void AActor::MarkPrecacheSounds() const
|
||||
{
|
||||
SeeSound.MarkUsed();
|
||||
|
@ -5105,6 +5194,12 @@ void AActor::CallDeactivate(AActor *activator)
|
|||
|
||||
void AActor::OnDestroy ()
|
||||
{
|
||||
// [ZZ] call destroy event hook.
|
||||
// note that this differs from ThingSpawned in that you can actually override OnDestroy to avoid calling the hook.
|
||||
// but you can't really do that without utterly breaking the game, so it's ok.
|
||||
// note: if OnDestroy is ever made optional, E_WorldThingDestroyed should still be called for ANY thing.
|
||||
E_WorldThingDestroyed(this);
|
||||
|
||||
ClearRenderSectorList();
|
||||
ClearRenderLineList();
|
||||
|
||||
|
@ -5417,6 +5512,9 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
|
|||
{
|
||||
if (state == PST_ENTER || (state == PST_LIVE && !savegamerestore))
|
||||
{
|
||||
// [ZZ] fire non-hub ENTER event
|
||||
// level.time is a hack to make sure that we don't call it on dummy player initialization during hub return.
|
||||
if (!level.time) E_PlayerEntered(p - players, false);
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Enter, p->mo, true);
|
||||
}
|
||||
else if (state == PST_REBORN)
|
||||
|
@ -7463,6 +7561,9 @@ void AActor::Revive()
|
|||
{
|
||||
level.total_monsters++;
|
||||
}
|
||||
|
||||
// [ZZ] resurrect hook
|
||||
E_WorldThingRevived(this);
|
||||
}
|
||||
|
||||
int AActor::GetGibHealth() const
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "r_renderer.h"
|
||||
#include "serializer.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
static TStaticArray<sector_t> loadsectors;
|
||||
static TStaticArray<line_t> loadlines;
|
||||
|
@ -968,6 +969,8 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
|
|||
arc("sectorportals", level.sectorPortals);
|
||||
if (arc.isReading()) P_CollectLinkedPortals();
|
||||
|
||||
// [ZZ] serialize events
|
||||
E_SerializeEvents(arc);
|
||||
DThinker::SerializeThinkers(arc, !hubload);
|
||||
arc.Array("polyobjs", polyobjs, po_NumPolyobjs);
|
||||
arc("subsectors", subsectors);
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#ifndef NO_EDATA
|
||||
#include "edata.h"
|
||||
#endif
|
||||
#include "events.h"
|
||||
|
||||
#include "fragglescript/t_fs.h"
|
||||
|
||||
|
@ -3433,6 +3434,8 @@ extern polyblock_t **PolyBlockMap;
|
|||
|
||||
void P_FreeLevelData ()
|
||||
{
|
||||
// [ZZ] delete per-map event handlers
|
||||
E_Shutdown(true);
|
||||
MapThingsConverted.Clear();
|
||||
MapThingsUserDataIndex.Clear();
|
||||
MapThingsUserData.Clear();
|
||||
|
@ -3638,6 +3641,10 @@ void P_SetupLevel (const char *lumpname, int position)
|
|||
I_Error("Unable to open map '%s'\n", lumpname);
|
||||
}
|
||||
|
||||
// [ZZ] init per-map static handlers. we need to call this before everything is set up because otherwise scripts don't receive PlayerEntered event
|
||||
// (which happens at god-knows-what stage in this function, but definitely not the last part, because otherwise it'd work to put E_InitStaticHandlers before the player spawning)
|
||||
E_InitStaticHandlers(true);
|
||||
|
||||
// generate a checksum for the level, to be included and checked with savegames.
|
||||
map->GetChecksum(level.md5);
|
||||
// find map num
|
||||
|
@ -4195,6 +4202,8 @@ void P_Init ()
|
|||
|
||||
static void P_Shutdown ()
|
||||
{
|
||||
// [ZZ] delete global event handlers
|
||||
E_Shutdown(false);
|
||||
R_DeinitSpriteData ();
|
||||
P_DeinitKeyMessages ();
|
||||
P_FreeLevelData ();
|
||||
|
|
|
@ -119,8 +119,8 @@ void P_LoadTranslator(const char *lumpname);
|
|||
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid = -1);
|
||||
int P_TranslateSectorSpecial (int);
|
||||
|
||||
int GetUDMFInt(int type, int index, const char *key);
|
||||
double GetUDMFFloat(int type, int index, const char *key);
|
||||
int GetUDMFInt(int type, int index, FName key);
|
||||
double GetUDMFFloat(int type, int index, FName key);
|
||||
|
||||
bool P_LoadGLNodes(MapData * map);
|
||||
bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "d_event.h"
|
||||
#include "g_level.h"
|
||||
#include "gstrings.h"
|
||||
#include "events.h"
|
||||
|
||||
#include "i_system.h"
|
||||
#include "m_argv.h"
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
extern gamestate_t wipegamestate;
|
||||
|
||||
|
@ -126,6 +127,8 @@ void P_Ticker (void)
|
|||
/*Added by MC: Freeze mode.*/!(bglobal.freeze && players[i].Bot != NULL))
|
||||
P_PlayerThink (&players[i]);
|
||||
|
||||
// [ZZ] call the WorldTick hook
|
||||
E_WorldTick();
|
||||
StatusBar->Tick (); // [RH] moved this here
|
||||
level.Tick (); // [RH] let the level tick
|
||||
DThinker::RunThinkers ();
|
||||
|
|
|
@ -342,7 +342,7 @@ FUDMFKey *FUDMFKeys::Find(FName key)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
int GetUDMFInt(int type, int index, const char *key)
|
||||
int GetUDMFInt(int type, int index, FName key)
|
||||
{
|
||||
assert(type >=0 && type <=3);
|
||||
|
||||
|
@ -359,7 +359,16 @@ int GetUDMFInt(int type, int index, const char *key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
double GetUDMFFloat(int type, int index, const char *key)
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, GetUDMFInt)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(type);
|
||||
PARAM_INT(index);
|
||||
PARAM_NAME(key);
|
||||
ACTION_RETURN_INT(GetUDMFInt(type, index, key));
|
||||
}
|
||||
|
||||
double GetUDMFFloat(int type, int index, FName key)
|
||||
{
|
||||
assert(type >=0 && type <=3);
|
||||
|
||||
|
@ -376,6 +385,41 @@ double GetUDMFFloat(int type, int index, const char *key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, GetUDMFFloat)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(type);
|
||||
PARAM_INT(index);
|
||||
PARAM_NAME(key);
|
||||
ACTION_RETURN_FLOAT(GetUDMFFloat(type, index, key));
|
||||
}
|
||||
|
||||
FString GetUDMFString(int type, int index, FName key)
|
||||
{
|
||||
assert(type >= 0 && type <= 3);
|
||||
|
||||
FUDMFKeys *pKeys = UDMFKeys[type].CheckKey(index);
|
||||
|
||||
if (pKeys != NULL)
|
||||
{
|
||||
FUDMFKey *pKey = pKeys->Find(key);
|
||||
if (pKey != NULL)
|
||||
{
|
||||
return pKey->StringVal;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, GetUDMFString)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(type);
|
||||
PARAM_INT(index);
|
||||
PARAM_NAME(key);
|
||||
ACTION_RETURN_STRING(GetUDMFString(type, index, key));
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
@ -225,7 +225,7 @@ static line_t *FindDestination(line_t *src, int tag)
|
|||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -275,7 +275,7 @@ static void SetRotation(FLinePortal *port)
|
|||
void P_SpawnLinePortal(line_t* line)
|
||||
{
|
||||
// portal destination is special argument #0
|
||||
line_t* dst = NULL;
|
||||
line_t* dst = nullptr;
|
||||
|
||||
if (line->args[2] >= PORTT_VISUAL && line->args[2] <= PORTT_LINKED)
|
||||
{
|
||||
|
@ -304,7 +304,7 @@ void P_SpawnLinePortal(line_t* line)
|
|||
port->mType = PORTT_TELEPORT;
|
||||
}
|
||||
}
|
||||
if (port->mDestination != NULL)
|
||||
if (port->mDestination != nullptr)
|
||||
{
|
||||
port->mDefFlags = port->mType == PORTT_VISUAL ? PORTF_VISIBLE : port->mType == PORTT_TELEPORT ? PORTF_TYPETELEPORT : PORTF_TYPEINTERACTIVE;
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ void P_SpawnLinePortal(line_t* line)
|
|||
|
||||
void P_UpdatePortal(FLinePortal *port)
|
||||
{
|
||||
if (port->mDestination == NULL)
|
||||
if (port->mDestination == nullptr)
|
||||
{
|
||||
// Portal has no destination: switch it off
|
||||
port->mFlags = 0;
|
||||
|
@ -442,16 +442,16 @@ static bool ChangePortalLine(line_t *line, int destid)
|
|||
if (line->portalindex >= linePortals.Size()) return false;
|
||||
FLinePortal *port = &linePortals[line->portalindex];
|
||||
if (port->mType == PORTT_LINKED) return false; // linked portals cannot be changed.
|
||||
if (destid == 0) port->mDestination = NULL;
|
||||
if (destid == 0) port->mDestination = nullptr;
|
||||
port->mDestination = FindDestination(line, destid);
|
||||
if (port->mDestination == NULL)
|
||||
if (port->mDestination == nullptr)
|
||||
{
|
||||
port->mFlags = 0;
|
||||
}
|
||||
else if (port->mType == PORTT_INTERACTIVE)
|
||||
{
|
||||
FLinePortal *portd = &linePortals[port->mDestination->portalindex];
|
||||
if (portd != NULL && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line)
|
||||
FLinePortal *portd = port->mDestination->portalindex < linePortals.Size()? &linePortals[port->mDestination->portalindex] : nullptr;
|
||||
if (portd != nullptr && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line)
|
||||
{
|
||||
// this is a 2-way interactive portal
|
||||
port->mFlags = port->mDefFlags | PORTF_INTERACTIVE;
|
||||
|
@ -662,7 +662,7 @@ void P_TranslatePortalZ(line_t* src, double& z)
|
|||
|
||||
unsigned P_GetSkyboxPortal(AActor *actor)
|
||||
{
|
||||
if (actor == NULL) return 1; // this means a regular sky.
|
||||
if (actor == nullptr) return 1; // this means a regular sky.
|
||||
for (unsigned i = 0;i<level.sectorPortals.Size();i++)
|
||||
{
|
||||
if (level.sectorPortals[i].mSkybox == actor) return i;
|
||||
|
@ -820,7 +820,7 @@ static bool CollectSectors(int groupid, sector_t *origin)
|
|||
for (auto line : sec->Lines)
|
||||
{
|
||||
sector_t *other = line->frontsector == sec ? line->backsector : line->frontsector;
|
||||
if (other != NULL && other != sec && other->PortalGroup != groupid)
|
||||
if (other != nullptr && other != sec && other->PortalGroup != groupid)
|
||||
{
|
||||
other->PortalGroup = groupid;
|
||||
list.Push(other);
|
||||
|
@ -1098,10 +1098,10 @@ void P_CreateLinkedPortals()
|
|||
}
|
||||
|
||||
// reject would just get in the way when checking sight through portals.
|
||||
if (Displacements.size > 1 && rejectmatrix != NULL)
|
||||
if (Displacements.size > 1 && rejectmatrix != nullptr)
|
||||
{
|
||||
delete[] rejectmatrix;
|
||||
rejectmatrix = NULL;
|
||||
rejectmatrix = nullptr;
|
||||
}
|
||||
// finally we must flag all planes which are obstructed by the sector's own ceiling or floor.
|
||||
for (auto &sec : level.sectors)
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "v_video.h"
|
||||
#include "events.h"
|
||||
|
||||
#undef Class
|
||||
|
||||
|
@ -90,10 +91,16 @@ size_t s_skipMouseMoves;
|
|||
|
||||
void CheckGUICapture()
|
||||
{
|
||||
const bool wantCapture = (MENU_Off == menuactive)
|
||||
bool wantCapture = (MENU_Off == menuactive)
|
||||
? (c_down == ConsoleState || c_falling == ConsoleState || chatmodeon)
|
||||
: (MENU_On == menuactive || MENU_OnNoPause == menuactive);
|
||||
|
||||
// [ZZ] check active event handlers that want the UI processing
|
||||
if (!wantCapture && E_CheckUiProcessors())
|
||||
{
|
||||
wantCapture = true;
|
||||
}
|
||||
|
||||
if (wantCapture != GUICapture)
|
||||
{
|
||||
GUICapture = wantCapture;
|
||||
|
@ -181,6 +188,9 @@ void CheckNativeMouse()
|
|||
&& (MENU_On == menuactive || MENU_OnNoPause == menuactive);
|
||||
}
|
||||
|
||||
if (!wantNative && E_CheckRequireMouse())
|
||||
wantNative = true;
|
||||
|
||||
I_SetNativeMouse(wantNative);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "dikeys.h"
|
||||
#include "templates.h"
|
||||
#include "s_sound.h"
|
||||
#include "events.h"
|
||||
|
||||
static void I_CheckGUICapture ();
|
||||
static void I_CheckNativeMouse ();
|
||||
|
@ -154,6 +155,10 @@ static void I_CheckGUICapture ()
|
|||
wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause);
|
||||
}
|
||||
|
||||
// [ZZ] check active event handlers that want the UI processing
|
||||
if (!wantCapt && E_CheckUiProcessors())
|
||||
wantCapt = true;
|
||||
|
||||
if (wantCapt != GUICapture)
|
||||
{
|
||||
GUICapture = wantCapt;
|
||||
|
@ -331,6 +336,12 @@ void MessagePump (const SDL_Event &sev)
|
|||
event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp;
|
||||
event.subtype += (sev.button.button - 1) * 3;
|
||||
}
|
||||
|
||||
SDL_Keymod kmod = SDL_GetModState();
|
||||
event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((kmod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((kmod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
break;
|
||||
|
@ -340,6 +351,10 @@ void MessagePump (const SDL_Event &sev)
|
|||
{
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = sev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown;
|
||||
SDL_Keymod kmod = SDL_GetModState();
|
||||
event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((kmod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((kmod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "v_palette.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4244)
|
||||
|
|
|
@ -2046,11 +2046,11 @@ void PrepWall(float *vstep, fixed_t *upos, double walxrepeat, int x1, int x2)
|
|||
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - CenterX);
|
||||
float uGradient = WallT.UoverZstep;
|
||||
float zGradient = WallT.InvZstep;
|
||||
float xrepeat = (float)walxrepeat;
|
||||
float xrepeat = (float)fabs(walxrepeat);
|
||||
float depthScale = (float)(WallT.InvZstep * WallTMapScale2);
|
||||
float depthOrg = (float)(-WallT.UoverZstep * WallTMapScale2);
|
||||
|
||||
if (xrepeat < 0.0f)
|
||||
if (walxrepeat < 0.0)
|
||||
{
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
|
@ -2084,9 +2084,9 @@ void PrepLWall(fixed_t *upos, double walxrepeat, int x1, int x2)
|
|||
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - CenterX);
|
||||
float uGradient = WallT.UoverZstep;
|
||||
float zGradient = WallT.InvZstep;
|
||||
float xrepeat = (float)walxrepeat;
|
||||
float xrepeat = (float)fabs(walxrepeat);
|
||||
|
||||
if (xrepeat < 0.0f)
|
||||
if (walxrepeat < 0.0f)
|
||||
{
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
|
|
|
@ -1261,6 +1261,7 @@ DEFINE_ACTION_FUNCTION(DObject, S_Sound)
|
|||
PARAM_INT(channel);
|
||||
PARAM_FLOAT_DEF(volume);
|
||||
PARAM_FLOAT_DEF(attn);
|
||||
S_Sound(channel, id, volume, attn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -285,6 +285,7 @@ void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool
|
|||
#define CHAN_JUSTSTARTED 512 // internal: Sound has not been updated yet.
|
||||
#define CHAN_ABSTIME 1024// internal: Start time is absolute and does not depend on current time.
|
||||
#define CHAN_VIRTUAL 2048// internal: Channel is currently virtual
|
||||
#define CHAN_NOSTOP 4096// only for A_PlaySound. Does not start if channel is playing something.
|
||||
|
||||
// sound attenuation values
|
||||
#define ATTN_NONE 0.f // full volume the entire level
|
||||
|
|
|
@ -8368,9 +8368,9 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (x)
|
||||
{
|
||||
if (x->ValueType == TypeName ||
|
||||
x->ValueType == TypeSound)
|
||||
x->ValueType == TypeSound) // spriteID can be a string too.
|
||||
{
|
||||
x = new FxStringCast(ArgList[i]);
|
||||
x = new FxStringCast(x);
|
||||
x = x->Resolve(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -840,6 +840,21 @@ static void DispatchScriptProperty(FScanner &sc, PProperty *prop, AActor *defaul
|
|||
bool val = sc.CheckNumber() ? !!sc.Number : true;
|
||||
static_cast<PBool*>(f->Type)->SetValue(addr, !!val);
|
||||
}
|
||||
else if (f->Type == TypeName)
|
||||
{
|
||||
sc.MustGetString();
|
||||
*(FName*)addr = sc.String;
|
||||
}
|
||||
else if (f->Type == TypeSound)
|
||||
{
|
||||
sc.MustGetString();
|
||||
*(FSoundID*)addr = sc.String;
|
||||
}
|
||||
else if (f->Type == TypeColor)
|
||||
{
|
||||
if (sc.CheckNumber()) *(int*)addr = sc.Number;
|
||||
else *(PalEntry*)addr = V_GetColor(nullptr, sc);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
|
|
|
@ -1720,7 +1720,19 @@ void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *prop
|
|||
{
|
||||
static_cast<PBool*>(f->Type)->SetValue(addr, !!GetIntConst(ex, ctx));
|
||||
}
|
||||
if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
else if (f->Type == TypeName)
|
||||
{
|
||||
*(FName*)addr = GetStringConst(ex, ctx);
|
||||
}
|
||||
else if (f->Type == TypeSound)
|
||||
{
|
||||
*(FSoundID*)addr = GetStringConst(ex, ctx);
|
||||
}
|
||||
else if (f->Type == TypeColor && ex->ValueType == TypeString) // colors can also be specified as ints.
|
||||
{
|
||||
*(PalEntry*)addr = V_GetColor(nullptr, GetStringConst(ex, ctx).GetChars(), &ex->ScriptPosition);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
{
|
||||
static_cast<PInt*>(f->Type)->SetValue(addr, GetIntConst(ex, ctx));
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ const char *GetVersionString();
|
|||
// Protocol version used in demos.
|
||||
// Bump it if you change existing DEM_ commands or add new ones.
|
||||
// Otherwise, it should be safe to leave it alone.
|
||||
#define DEMOGAMEVERSION 0x21E
|
||||
#define DEMOGAMEVERSION 0x21F
|
||||
|
||||
// Minimum demo version we can play.
|
||||
// Bump it whenever you change or remove existing DEM_ commands.
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
#include "d_event.h"
|
||||
#include "v_text.h"
|
||||
#include "version.h"
|
||||
#include "events.h"
|
||||
|
||||
// Prototypes and declarations.
|
||||
#include "rawinput.h"
|
||||
|
@ -187,6 +188,10 @@ static void I_CheckGUICapture ()
|
|||
wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause);
|
||||
}
|
||||
|
||||
// [ZZ] check active event handlers that want the UI processing
|
||||
if (!wantCapt && E_CheckUiProcessors())
|
||||
wantCapt = true;
|
||||
|
||||
if (wantCapt != GUICapture)
|
||||
{
|
||||
GUICapture = wantCapt;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "win32iface.h"
|
||||
#include "rawinput.h"
|
||||
#include "menu/menu.h"
|
||||
#include "events.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -282,6 +283,9 @@ void I_CheckNativeMouse(bool preferNative)
|
|||
}
|
||||
}
|
||||
|
||||
if (!want_native && E_CheckRequireMouse())
|
||||
want_native = true;
|
||||
|
||||
//Printf ("%d %d %d\n", wantNative, preferNative, NativeMouse);
|
||||
|
||||
if (want_native != NativeMouse)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "zscript/constants.txt"
|
||||
#include "zscript/actor.txt"
|
||||
#include "zscript/actor_checks.txt"
|
||||
#include "zscript/events.txt"
|
||||
|
||||
#include "zscript/menu/menuitembase.txt"
|
||||
#include "zscript/menu/menu.txt"
|
||||
|
|
|
@ -329,7 +329,12 @@ class Actor : Thinker native
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Called when the player presses 'use' and an actor is found
|
||||
virtual bool Used(Actor user)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
native static class<Actor> GetReplacement(class<Actor> cls);
|
||||
native static class<Actor> GetReplacee(class<Actor> cls);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
struct InputEvent native
|
||||
struct InputEventData native
|
||||
{
|
||||
native uint8 type;
|
||||
native uint8 subtype;
|
||||
|
@ -418,6 +418,14 @@ class SpotState : Object native
|
|||
|
||||
struct LevelLocals native
|
||||
{
|
||||
enum EUDMF
|
||||
{
|
||||
UDMF_Line,
|
||||
UDMF_Side,
|
||||
UDMF_Sector,
|
||||
//UDMF_Thing // not implemented
|
||||
};
|
||||
|
||||
native readonly int time;
|
||||
native readonly int maptime;
|
||||
native readonly int totaltime;
|
||||
|
@ -457,6 +465,11 @@ struct LevelLocals native
|
|||
native bool frozen;
|
||||
native bool infinite_flight;
|
||||
// level_info_t *info cannot be done yet.
|
||||
|
||||
native String GetUDMFString(int type, int index, Name key);
|
||||
native int GetUDMFInt(int type, int index, Name key);
|
||||
native double GetUDMFFloat(int type, int index, Name key);
|
||||
|
||||
}
|
||||
|
||||
struct StringTable native
|
||||
|
|
|
@ -413,7 +413,8 @@ enum ESoundFlags
|
|||
CHAN_MAYBE_LOCAL = 16,
|
||||
CHAN_UI = 32,
|
||||
CHAN_NOPAUSE = 64,
|
||||
CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL)
|
||||
CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL),
|
||||
CHAN_NOSTOP = 4096
|
||||
|
||||
};
|
||||
|
||||
|
|
345
wadsrc/static/zscript/events.txt
Executable file
345
wadsrc/static/zscript/events.txt
Executable file
|
@ -0,0 +1,345 @@
|
|||
class BaseEvent native { } // just a base class. it doesn't inherit from Object on the scripting side so you can't call Destroy() on it and break everything.
|
||||
|
||||
class RenderEvent : BaseEvent native
|
||||
{
|
||||
native readonly Vector3 ViewPos;
|
||||
native readonly double ViewAngle;
|
||||
native readonly double ViewPitch;
|
||||
native readonly double ViewRoll;
|
||||
native readonly double FracTic;
|
||||
native readonly Actor Camera;
|
||||
}
|
||||
|
||||
class WorldEvent : BaseEvent native
|
||||
{
|
||||
// for loaded/unloaded
|
||||
native readonly bool IsSaveGame;
|
||||
// this will be true if we are re-entering the hub level.
|
||||
native readonly bool IsReopen;
|
||||
// for thingspawned/thingdied/thingdestroyed
|
||||
native readonly Actor Thing;
|
||||
// for thingdied. can be null
|
||||
native readonly Actor Inflictor;
|
||||
// for thingdamaged.
|
||||
native readonly int Damage;
|
||||
native readonly Actor DamageSource;
|
||||
native readonly Name DamageType;
|
||||
native readonly EDmgFlags DamageFlags;
|
||||
native readonly double DamageAngle;
|
||||
}
|
||||
|
||||
class PlayerEvent : BaseEvent native
|
||||
{
|
||||
// this is the player number that caused the event.
|
||||
// note: you can get player struct from this by using players[e.PlayerNumber]
|
||||
native readonly int PlayerNumber;
|
||||
// this will be true if we are re-entering the hub level.
|
||||
native readonly bool IsReturn;
|
||||
}
|
||||
|
||||
class UiEvent : BaseEvent native
|
||||
{
|
||||
// d_gui.h
|
||||
enum EGUIEvent
|
||||
{
|
||||
Type_None,
|
||||
Type_KeyDown,
|
||||
Type_KeyRepeat,
|
||||
Type_KeyUp,
|
||||
Type_Char,
|
||||
Type_FirstMouseEvent, // ?
|
||||
Type_MouseMove,
|
||||
Type_LButtonDown,
|
||||
Type_LButtonUp,
|
||||
Type_LButtonClick,
|
||||
Type_MButtonDown,
|
||||
Type_MButtonUp,
|
||||
Type_MButtonClick,
|
||||
Type_RButtonDown,
|
||||
Type_RButtonUp,
|
||||
Type_RButtonClick,
|
||||
Type_WheelUp,
|
||||
Type_WheelDown,
|
||||
Type_WheelRight, // ???
|
||||
Type_WheelLeft, // ???
|
||||
Type_BackButtonDown, // ???
|
||||
Type_BackButtonUp, // ???
|
||||
Type_FwdButtonDown, // ???
|
||||
Type_FwdButtonUp, // ???
|
||||
Type_LastMouseEvent
|
||||
}
|
||||
|
||||
// for KeyDown, KeyRepeat, KeyUp
|
||||
enum ESpecialGUIKeys
|
||||
{
|
||||
Key_PgDn = 1,
|
||||
Key_PgUp = 2,
|
||||
Key_Home = 3,
|
||||
Key_End = 4,
|
||||
Key_Left = 5,
|
||||
Key_Right = 6,
|
||||
Key_Alert = 7, // ASCII bell
|
||||
Key_Backspace = 8, // ASCII
|
||||
Key_Tab = 9, // ASCII
|
||||
Key_LineFeed = 10, // ASCII
|
||||
Key_Down = 10,
|
||||
Key_VTab = 11, // ASCII
|
||||
Key_Up = 11,
|
||||
Key_FormFeed = 12, // ASCII
|
||||
Key_Return = 13, // ASCII
|
||||
Key_F1 = 14,
|
||||
Key_F2 = 15,
|
||||
Key_F3 = 16,
|
||||
Key_F4 = 17,
|
||||
Key_F5 = 18,
|
||||
Key_F6 = 19,
|
||||
Key_F7 = 20,
|
||||
Key_F8 = 21,
|
||||
Key_F9 = 22,
|
||||
Key_F10 = 23,
|
||||
Key_F11 = 24,
|
||||
Key_F12 = 25,
|
||||
Key_Del = 26,
|
||||
Key_Escape = 27, // ASCII
|
||||
Key_Free1 = 28,
|
||||
Key_Free2 = 29,
|
||||
Key_Back = 30, // browser back key
|
||||
Key_CEscape = 31 // color escape
|
||||
}
|
||||
|
||||
//
|
||||
native readonly EGUIEvent Type;
|
||||
//
|
||||
native readonly String KeyString;
|
||||
native readonly int KeyChar;
|
||||
//
|
||||
native readonly int MouseX;
|
||||
native readonly int MouseY;
|
||||
//
|
||||
native readonly bool IsShift;
|
||||
native readonly bool IsCtrl;
|
||||
native readonly bool IsAlt;
|
||||
}
|
||||
|
||||
class InputEvent : BaseEvent native
|
||||
{
|
||||
enum EGenericEvent
|
||||
{
|
||||
Type_None,
|
||||
Type_KeyDown,
|
||||
Type_KeyUp,
|
||||
Type_Mouse,
|
||||
Type_GUI, // unused, kept for completeness
|
||||
Type_DeviceChange
|
||||
}
|
||||
|
||||
// ew.
|
||||
enum EDoomInputKeys
|
||||
{
|
||||
Key_Pause = 0xc5, // DIK_PAUSE
|
||||
Key_RightArrow = 0xcd, // DIK_RIGHT
|
||||
Key_LeftArrow = 0xcb, // DIK_LEFT
|
||||
Key_UpArrow = 0xc8, // DIK_UP
|
||||
Key_DownArrow = 0xd0, // DIK_DOWN
|
||||
Key_Escape = 0x01, // DIK_ESCAPE
|
||||
Key_Enter = 0x1c, // DIK_RETURN
|
||||
Key_Space = 0x39, // DIK_SPACE
|
||||
Key_Tab = 0x0f, // DIK_TAB
|
||||
Key_F1 = 0x3b, // DIK_F1
|
||||
Key_F2 = 0x3c, // DIK_F2
|
||||
Key_F3 = 0x3d, // DIK_F3
|
||||
Key_F4 = 0x3e, // DIK_F4
|
||||
Key_F5 = 0x3f, // DIK_F5
|
||||
Key_F6 = 0x40, // DIK_F6
|
||||
Key_F7 = 0x41, // DIK_F7
|
||||
Key_F8 = 0x42, // DIK_F8
|
||||
Key_F9 = 0x43, // DIK_F9
|
||||
Key_F10 = 0x44, // DIK_F10
|
||||
Key_F11 = 0x57, // DIK_F11
|
||||
Key_F12 = 0x58, // DIK_F12
|
||||
Key_Grave = 0x29, // DIK_GRAVE
|
||||
|
||||
Key_Backspace = 0x0e, // DIK_BACK
|
||||
|
||||
Key_Equals = 0x0d, // DIK_EQUALS
|
||||
Key_Minus = 0x0c, // DIK_MINUS
|
||||
|
||||
Key_LShift = 0x2A, // DIK_LSHIFT
|
||||
Key_LCtrl = 0x1d, // DIK_LCONTROL
|
||||
Key_LAlt = 0x38, // DIK_LMENU
|
||||
|
||||
Key_RShift = Key_LSHIFT,
|
||||
Key_RCtrl = Key_LCTRL,
|
||||
Key_RAlt = Key_LALT,
|
||||
|
||||
Key_Ins = 0xd2, // DIK_INSERT
|
||||
Key_Del = 0xd3, // DIK_DELETE
|
||||
Key_End = 0xcf, // DIK_END
|
||||
Key_Home = 0xc7, // DIK_HOME
|
||||
Key_PgUp = 0xc9, // DIK_PRIOR
|
||||
Key_PgDn = 0xd1, // DIK_NEXT
|
||||
|
||||
Key_Mouse1 = 0x100,
|
||||
Key_Mouse2 = 0x101,
|
||||
Key_Mouse3 = 0x102,
|
||||
Key_Mouse4 = 0x103,
|
||||
Key_Mouse5 = 0x104,
|
||||
Key_Mouse6 = 0x105,
|
||||
Key_Mouse7 = 0x106,
|
||||
Key_Mouse8 = 0x107,
|
||||
|
||||
Key_FirstJoyButton = 0x108,
|
||||
Key_Joy1 = (Key_FirstJoyButton+0),
|
||||
Key_Joy2 = (Key_FirstJoyButton+1),
|
||||
Key_Joy3 = (Key_FirstJoyButton+2),
|
||||
Key_Joy4 = (Key_FirstJoyButton+3),
|
||||
Key_Joy5 = (Key_FirstJoyButton+4),
|
||||
Key_Joy6 = (Key_FirstJoyButton+5),
|
||||
Key_Joy7 = (Key_FirstJoyButton+6),
|
||||
Key_Joy8 = (Key_FirstJoyButton+7),
|
||||
Key_LastJoyButton = 0x187,
|
||||
Key_JoyPOV1_Up = 0x188,
|
||||
Key_JoyPOV1_Right = 0x189,
|
||||
Key_JoyPOV1_Down = 0x18a,
|
||||
Key_JoyPOV1_Left = 0x18b,
|
||||
Key_JoyPOV2_Up = 0x18c,
|
||||
Key_JoyPOV3_Up = 0x190,
|
||||
Key_JoyPOV4_Up = 0x194,
|
||||
|
||||
Key_MWheelUp = 0x198,
|
||||
Key_MWheelDown = 0x199,
|
||||
Key_MWheelRight = 0x19A,
|
||||
Key_MWheelLeft = 0x19B,
|
||||
|
||||
Key_JoyAxis1Plus = 0x19C,
|
||||
Key_JoyAxis1Minus = 0x19D,
|
||||
Key_JoyAxis2Plus = 0x19E,
|
||||
Key_JoyAxis2Minus = 0x19F,
|
||||
Key_JoyAxis3Plus = 0x1A0,
|
||||
Key_JoyAxis3Minus = 0x1A1,
|
||||
Key_JoyAxis4Plus = 0x1A2,
|
||||
Key_JoyAxis4Minus = 0x1A3,
|
||||
Key_JoyAxis5Plus = 0x1A4,
|
||||
Key_JoyAxis5Minus = 0x1A5,
|
||||
Key_JoyAxis6Plus = 0x1A6,
|
||||
Key_JoyAxis6Minus = 0x1A7,
|
||||
Key_JoyAxis7Plus = 0x1A8,
|
||||
Key_JoyAxis7Minus = 0x1A9,
|
||||
Key_JoyAxis8Plus = 0x1AA,
|
||||
Key_JoyAxis8Minus = 0x1AB,
|
||||
Num_JoyAxisButtons = 8,
|
||||
|
||||
Key_Pad_LThumb_Right = 0x1AC,
|
||||
Key_Pad_LThumb_Left = 0x1AD,
|
||||
Key_Pad_LThumb_Down = 0x1AE,
|
||||
Key_Pad_LThumb_Up = 0x1AF,
|
||||
|
||||
Key_Pad_RThumb_Right = 0x1B0,
|
||||
Key_Pad_RThumb_Left = 0x1B1,
|
||||
Key_Pad_RThumb_Down = 0x1B2,
|
||||
Key_Pad_RThumb_Up = 0x1B3,
|
||||
|
||||
Key_Pad_DPad_Up = 0x1B4,
|
||||
Key_Pad_DPad_Down = 0x1B5,
|
||||
Key_Pad_DPad_Left = 0x1B6,
|
||||
Key_Pad_DPad_Right = 0x1B7,
|
||||
Key_Pad_Start = 0x1B8,
|
||||
Key_Pad_Back = 0x1B9,
|
||||
Key_Pad_LThumb = 0x1BA,
|
||||
Key_Pad_RThumb = 0x1BB,
|
||||
Key_Pad_LShoulder = 0x1BC,
|
||||
Key_Pad_RShoulder = 0x1BD,
|
||||
Key_Pad_LTrigger = 0x1BE,
|
||||
Key_Pad_RTrigger = 0x1BF,
|
||||
Key_Pad_A = 0x1C0,
|
||||
Key_Pad_B = 0x1C1,
|
||||
Key_Pad_X = 0x1C2,
|
||||
Key_Pad_Y = 0x1C3,
|
||||
|
||||
Num_Keys = 0x1C4
|
||||
}
|
||||
|
||||
//
|
||||
native readonly EGenericEvent Type;
|
||||
//
|
||||
native readonly int KeyScan; // as in EDoomInputKeys enum
|
||||
native readonly String KeyString;
|
||||
native readonly int KeyChar; // ASCII char (if any)
|
||||
//
|
||||
native readonly int MouseX;
|
||||
native readonly int MouseY;
|
||||
}
|
||||
|
||||
class ConsoleEvent : BaseEvent native
|
||||
{
|
||||
// for net events, this will be the activator.
|
||||
// for UI events, this is always -1, and you need to check if level is loaded and use players[consoleplayer].
|
||||
native readonly int Player;
|
||||
native readonly String Name;
|
||||
native readonly int Args[3];
|
||||
}
|
||||
|
||||
class StaticEventHandler : Object native
|
||||
{
|
||||
// static event handlers CAN register other static event handlers.
|
||||
// unlike EventHandler.Create that will not create them.
|
||||
protected static native StaticEventHandler Create(class<StaticEventHandler> type);
|
||||
protected static native StaticEventHandler CreateOnce(class<StaticEventHandler> type);
|
||||
protected static native StaticEventHandler Find(Class<StaticEventHandler> type); // just for convenience. who knows.
|
||||
|
||||
protected static native bool Register(StaticEventHandler handler);
|
||||
protected static native bool Unregister(StaticEventHandler handler);
|
||||
|
||||
// these are called when the handler gets registered or unregistered
|
||||
// you can set Order/IsUiProcessor here.
|
||||
virtual native void OnRegister();
|
||||
virtual native void OnUnregister();
|
||||
|
||||
// actual handlers are here
|
||||
virtual native void WorldLoaded(WorldEvent e);
|
||||
virtual native void WorldUnloaded(WorldEvent e);
|
||||
virtual native void WorldThingSpawned(WorldEvent e);
|
||||
virtual native void WorldThingDied(WorldEvent e);
|
||||
virtual native void WorldThingRevived(WorldEvent e);
|
||||
virtual native void WorldThingDamaged(WorldEvent e);
|
||||
virtual native void WorldThingDestroyed(WorldEvent e);
|
||||
virtual native void WorldLightning(WorldEvent e); // for the sake of completeness.
|
||||
virtual native void WorldTick(WorldEvent e);
|
||||
|
||||
//
|
||||
virtual native void RenderFrame(RenderEvent e);
|
||||
virtual native void RenderOverlay(RenderEvent e);
|
||||
|
||||
//
|
||||
virtual native void PlayerEntered(PlayerEvent e);
|
||||
virtual native void PlayerRespawned(PlayerEvent e);
|
||||
virtual native void PlayerDied(PlayerEvent e);
|
||||
virtual native void PlayerDisconnected(PlayerEvent e);
|
||||
|
||||
//
|
||||
virtual native bool UiProcess(UiEvent e);
|
||||
virtual native bool InputProcess(InputEvent e);
|
||||
|
||||
//
|
||||
virtual native void ConsoleProcess(ConsoleEvent e);
|
||||
|
||||
// this value will be queried on Register() to decide the relative order of this handler to every other.
|
||||
// this is most useful in UI systems.
|
||||
// default is 0.
|
||||
native readonly int Order;
|
||||
native void SetOrder(int order);
|
||||
// this value will be queried on user input to decide whether to send UiProcess to this handler.
|
||||
native bool IsUiProcessor;
|
||||
// this value determines whether mouse input is required.
|
||||
native bool RequireMouse;
|
||||
}
|
||||
|
||||
class EventHandler : StaticEventHandler native
|
||||
{
|
||||
static native StaticEventHandler Create(class<StaticEventHandler> type);
|
||||
static native StaticEventHandler CreateOnce(class<StaticEventHandler> type);
|
||||
static native StaticEventHandler Find(class<StaticEventHandler> type);
|
||||
|
||||
static native bool Register(StaticEventHandler handler);
|
||||
static native bool Unregister(StaticEventHandler handler);
|
||||
}
|
|
@ -124,7 +124,7 @@ class Lightning : Actor
|
|||
if ((!thing.player && !thing.bBoss) || !(level.time&1))
|
||||
{
|
||||
thing.DamageMobj(self, target, 3, 'Electric');
|
||||
A_PlaySound(AttackSound, CHAN_WEAPON, 1, true);
|
||||
A_PlaySound(AttackSound, CHAN_WEAPON|CHAN_NOSTOP, 1, false);
|
||||
if (thing.bIsMonster && random[LightningHit]() < 64)
|
||||
{
|
||||
thing.Howl ();
|
||||
|
|
|
@ -84,6 +84,20 @@ struct Side native
|
|||
native Vertex V2();
|
||||
|
||||
native int Index();
|
||||
|
||||
int GetUDMFInt(Name nm)
|
||||
{
|
||||
return Level.GetUDMFInt(LevelLocals.UDMF_Side, Index(), nm);
|
||||
}
|
||||
double GetUDMFFloat(Name nm)
|
||||
{
|
||||
return Level.GetUDMFFloat(LevelLocals.UDMF_Side, Index(), nm);
|
||||
}
|
||||
String GetUDMFString(Name nm)
|
||||
{
|
||||
return Level.GetUDMFString(LevelLocals.UDMF_Side, Index(), nm);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Line native
|
||||
|
@ -142,6 +156,19 @@ struct Line native
|
|||
native Line getPortalDestination();
|
||||
native int getPortalAlignment();
|
||||
native int Index();
|
||||
|
||||
int GetUDMFInt(Name nm)
|
||||
{
|
||||
return Level.GetUDMFInt(LevelLocals.UDMF_Line, Index(), nm);
|
||||
}
|
||||
double GetUDMFFloat(Name nm)
|
||||
{
|
||||
return Level.GetUDMFFloat(LevelLocals.UDMF_Line, Index(), nm);
|
||||
}
|
||||
String GetUDMFString(Name nm)
|
||||
{
|
||||
return Level.GetUDMFString(LevelLocals.UDMF_Line, Index(), nm);
|
||||
}
|
||||
}
|
||||
|
||||
struct SecPlane native
|
||||
|
@ -398,4 +425,18 @@ struct Sector native
|
|||
{
|
||||
Flags &= ~SECF_SECRET;
|
||||
}
|
||||
|
||||
int GetUDMFInt(Name nm)
|
||||
{
|
||||
return Level.GetUDMFInt(LevelLocals.UDMF_Sector, Index(), nm);
|
||||
}
|
||||
double GetUDMFFloat(Name nm)
|
||||
{
|
||||
return Level.GetUDMFFloat(LevelLocals.UDMF_Sector, Index(), nm);
|
||||
}
|
||||
String GetUDMFString(Name nm)
|
||||
{
|
||||
return Level.GetUDMFString(LevelLocals.UDMF_Sector, Index(), nm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ class ListMenu : Menu native
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//bool Responder (InputEvent ev);
|
||||
//bool Responder (InputEventData ev);
|
||||
//bool MenuEvent (int mkey, bool fromcontroller);
|
||||
//bool MouseEvent(int type, int x, int y);
|
||||
//void Ticker ();
|
||||
|
|
|
@ -105,7 +105,7 @@ class Menu : Object native
|
|||
virtual void ReleaseFocus() {}
|
||||
virtual void ResetColor() {}
|
||||
|
||||
native virtual bool Responder(InputEvent ev);
|
||||
native virtual bool Responder(InputEventData ev);
|
||||
native virtual bool MenuEvent (int mkey, bool fromcontroller);
|
||||
native virtual bool MouseEvent(int type, int mx, int my);
|
||||
native virtual void Ticker();
|
||||
|
|
|
@ -57,7 +57,7 @@ class OptionMenuDescriptor : MenuDescriptor native
|
|||
native bool mDontDim;
|
||||
|
||||
native void CalcIndent();
|
||||
//native OptionMenuItem GetItem(Name iname);
|
||||
native OptionMenuItem GetItem(Name iname);
|
||||
void Reset()
|
||||
{
|
||||
// Reset the default settings (ignore all other values in the struct)
|
||||
|
@ -120,17 +120,17 @@ class OptionMenu : Menu
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool Responder (InputEvent ev)
|
||||
override bool Responder (InputEventData ev)
|
||||
{
|
||||
if (ev.type == InputEvent.GUI_Event)
|
||||
if (ev.type == InputEventData.GUI_Event)
|
||||
{
|
||||
if (ev.subtype == InputEvent.GUI_WheelUp)
|
||||
if (ev.subtype == InputEventData.GUI_WheelUp)
|
||||
{
|
||||
int scrollamt = MIN(2, mDesc.mScrollPos);
|
||||
mDesc.mScrollPos -= scrollamt;
|
||||
return true;
|
||||
}
|
||||
else if (ev.subtype == InputEvent.GUI_WheelDown)
|
||||
else if (ev.subtype == InputEventData.GUI_WheelDown)
|
||||
{
|
||||
if (CanScrollDown)
|
||||
{
|
||||
|
|
|
@ -132,11 +132,11 @@ class OptionMenuItemCommand : OptionMenuItemSubmenu
|
|||
override bool Activate()
|
||||
{
|
||||
// This needs to perform a few checks to prevent abuse by malicious modders.
|
||||
let m = Menu.GetCurrentMenu();
|
||||
let m = OptionMenu(Menu.GetCurrentMenu());
|
||||
// don't execute if no menu is active
|
||||
if (m == null) return false;
|
||||
// don't execute if this item cannot be found in the current menu.
|
||||
if (m.GetItem(mAction) != self) return false;
|
||||
if (m.mDesc.GetItem(mAction) != self) return false;
|
||||
Menu.MenuSound("menu/choose");
|
||||
DoCommand(mAction);
|
||||
return true;
|
||||
|
@ -396,16 +396,16 @@ class EnterKey : Menu
|
|||
}
|
||||
}
|
||||
|
||||
override bool Responder(InputEvent ev)
|
||||
override bool Responder(InputEventData ev)
|
||||
{
|
||||
// This checks raw keys, not GUI keys.
|
||||
if (ev.type == InputEvent.KeyDown)
|
||||
if (ev.type == InputEventData.KeyDown)
|
||||
{
|
||||
mOwner.SendKey(ev.data1);
|
||||
menuactive = Menu.On;
|
||||
SetMenuMessage(0);
|
||||
Close();
|
||||
mParentMenu.MenuEvent((ev.data1 == InputEvent.KEY_ESCAPE)? Menu.MKEY_Abort : Menu.MKEY_Input, 0);
|
||||
mParentMenu.MenuEvent((ev.data1 == InputEventData.KEY_ESCAPE)? Menu.MKEY_Abort : Menu.MKEY_Input, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1197,6 +1197,7 @@ class OptionMenuItemNumberField : OptionMenuFieldBase
|
|||
mCVar.SetFloat(value);
|
||||
Menu.MenuSound("menu/change");
|
||||
}
|
||||
else return Super.MenuEvent(mkey, fromcontroller);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -57,9 +57,9 @@ class VideoModeMenu : OptionMenu
|
|||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
|
||||
override bool Responder(InputEvent ev)
|
||||
override bool Responder(InputEventData ev)
|
||||
{
|
||||
if (ev.type == InputEvent.GUI_Event && ev.subtype == InputEvent.GUI_KeyDown && (ev.data1 == 0x54 || ev.data1 == 0x74))
|
||||
if (ev.type == InputEventData.GUI_Event && ev.subtype == InputEventData.GUI_KeyDown && (ev.data1 == 0x54 || ev.data1 == 0x74))
|
||||
{
|
||||
if (SetSelectedSize())
|
||||
{
|
||||
|
|
|
@ -130,7 +130,7 @@ class PlayerPawn : Actor native
|
|||
return powerup.EffectTics, maxtics;
|
||||
}
|
||||
}
|
||||
return 0, 0;
|
||||
return -1, -1;
|
||||
}
|
||||
|
||||
native int GetMaxHealth();
|
||||
|
|
Loading…
Reference in a new issue