class Object native { native bool bDestroyed; // These really should be global functions... native static int G_SkillPropertyInt(int p); native static double G_SkillPropertyFloat(int p); native static vector3, int G_PickDeathmatchStart(); native static vector3, int G_PickPlayerStart(int pnum, int flags = 0); native static int GameType(); native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM); native static void S_PauseSound (bool notmusic, bool notsfx); native static void S_ResumeSound (bool notsfx); native static bool S_ChangeMusic(String music_name, int order = 0, bool looping = true, bool force = false); native static void C_MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable. native static uint BAM(double angle); native static void SetMusicVolume(float vol); native Name GetClassName(); native void Destroy(); // This does not call into the native method of the same name to avoid problems with objects that get garbage collected late on shutdown. virtual void OnDestroy() {} } class Thinker : Object native { enum EStatnums { // Thinkers that don't actually think STAT_INFO, // An info queue STAT_DECAL, // A decal STAT_AUTODECAL, // A decal that can be automatically deleted STAT_CORPSEPOINTER, // An entry in Hexen's corpse queue STAT_TRAVELLING, // An actor temporarily travelling to a new map // Thinkers that do think STAT_FIRST_THINKING=32, STAT_SCROLLER=STAT_FIRST_THINKING, // A DScroller thinker STAT_PLAYER, // A player actor STAT_BOSSTARGET, // A boss brain target STAT_LIGHTNING, // The lightning thinker STAT_DECALTHINKER, // An object that thinks for a decal STAT_INVENTORY, // An inventory item STAT_LIGHT, // A sector light effect STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects. STAT_EARTHQUAKE, // Earthquake actors STAT_MAPMARKER, // Map marker actors STAT_DEFAULT = 100, // Thinkers go here unless specified otherwise. STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement STAT_ACTORMOVER, // actor movers STAT_SCRIPTS, // The ACS thinker. This is to ensure that it can't tick before all actors called PostBeginPlay STAT_BOT, // Bot thinker MAX_STATNUM = 127 } const TICRATE = 35; virtual native void Tick(); virtual native void PostBeginPlay(); virtual native void ChangeStatNum(int stat); } class ThinkerIterator : Object native { native static ThinkerIterator Create(class<Object> type = "Actor", int statnum=Thinker.MAX_STATNUM+1); native Thinker Next(bool exact = false); native void Reinit(); } class ActorIterator : Object native { native static ActorIterator Create(int tid, class<Actor> type = "Actor"); native Actor Next(); native void Reinit(); } class BlockThingsIterator : Object native { native Actor thing; native Vector3 position; native int portalflags; native static BlockThingsIterator Create(Actor origin, double checkradius = -1, bool ignorerestricted = false); native static BlockThingsIterator CreateFromPos(double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted); native bool Next(); } class DropItem : Object native { native readonly DropItem Next; native readonly name Name; native readonly int Probability; native int Amount; } class SpotState : Object native { native static SpotState GetSpotState(); native SpecialSpot GetNextInList(class<Actor> type, int skipcounter); native SpecialSpot GetSpotWithMinMaxDistance(Class<Actor> type, double x, double y, double mindist, double maxdist); } struct LevelLocals native { native readonly int time; native readonly int maptime; native readonly int totaltime; native readonly int starttime; native readonly int partime; native readonly int sucktime; native readonly int cluster; native readonly int clusterflags; native readonly int levelnum; native readonly String LevelName; native readonly String MapName; native String NextMap; native String NextSecretMap; native readonly int maptype; native readonly String Music; native readonly int musicorder; native int total_secrets; native int found_secrets; native int total_items; native int found_items; native int total_monsters; native int killed_monsters; native double gravity; native double aircontrol; native double airfriction; native int airsupply; native double teamdamage; native bool monsterstelefrag; native bool actownspecial; native bool sndseqtotalctrl; native bool allmap; native bool missilesactivateimpact; native bool monsterfallingdamage; native bool checkswitchrange; native bool polygrind; native bool nomonsters; native bool frozen; // level_info_t *info cannot be done yet. } struct StringTable native { native static String Localize(String val); } // a few values of this need to be readable by the play code. // Most are handled at load time and are omitted here. struct DehInfo native { native int MaxSoulsphere; native uint8 ExplosionStyle; native double ExplosionAlpha; native int NoAutofreeze; native int BFGCells; } struct State native { native State NextState; native int sprite; native int16 Tics; native uint16 TicRange; native uint8 Frame; native uint8 UseFlags; native int Misc1; native int Misc2; native uint16 bSlow; native uint16 bFast; native bool bFullbright; native bool bNoDelay; native bool bSameFrame; native bool bCanRaise; native bool bDehacked; native int DistanceTo(state other); } struct F3DFloor native { } struct Vertex native { native readonly Vector2 p; } struct Side { enum ETexpart { top=0, mid=1, bottom=2 }; enum EWallFlags { WALLF_ABSLIGHTING = 1, // Light is absolute instead of relative WALLF_NOAUTODECALS = 2, // Do not attach impact decals to this wall WALLF_NOFAKECONTRAST = 4, // Don't do fake contrast for this wall in side_t::GetLightLevel WALLF_SMOOTHLIGHTING = 8, // Similar to autocontrast but applies to all angles. WALLF_CLIP_MIDTEX = 16, // Like the line counterpart, but only for this side. WALLF_WRAP_MIDTEX = 32, // Like the line counterpart, but only for this side. WALLF_POLYOBJ = 64, // This wall belongs to a polyobject. WALLF_LIGHT_FOG = 128, // This wall's Light is used even in fog. }; native Sector sector; // Sector the SideDef is facing. //DBaseDecal* AttachedDecals; // [RH] Decals bound to the wall native Line linedef; native int16 Light; native uint8 Flags; native TextureID GetTexture(int which); native void SetTexture(int which, TextureID tex); native void SetTextureXOffset(int which, double offset); native double GetTextureXOffset(int which); native void AddTextureXOffset(int which, double delta); native void SetTextureYOffset(int which, double offset); native double GetTextureYOffset(int which); native void AddTextureYOffset(int which, double delta); native void SetTextureXScale(int which, double scale); native double GetTextureXScale(int which); native void MultiplyTextureXScale(int which, double delta); native void SetTextureYScale(int which, double scale); native double GetTextureYScale(int which); native void MultiplyTextureYScale(int which, double delta); //native DInterpolation *SetInterpolation(int position); //native void StopInterpolation(int position); native Vertex V1(); native Vertex V2(); native int Index(); }; struct Line native { enum ELineFlags { ML_BLOCKING =0x00000001, // solid, is an obstacle ML_BLOCKMONSTERS =0x00000002, // blocks monsters only ML_TWOSIDED =0x00000004, // backside will not be present at all if not two sided ML_DONTPEGTOP = 0x00000008, // upper texture unpegged ML_DONTPEGBOTTOM = 0x00000010, // lower texture unpegged ML_SECRET = 0x00000020, // don't map as two sided: IT'S A SECRET! ML_SOUNDBLOCK = 0x00000040, // don't let sound cross two of these ML_DONTDRAW = 0x00000080, // don't draw on the automap ML_MAPPED = 0x00000100, // set if already drawn in automap ML_REPEAT_SPECIAL = 0x00000200, // special is repeatable ML_ADDTRANS = 0x00000400, // additive translucency (can only be set internally) // Extended flags ML_MONSTERSCANACTIVATE = 0x00002000, // [RH] Monsters (as well as players) can activate the line ML_BLOCK_PLAYERS = 0x00004000, ML_BLOCKEVERYTHING = 0x00008000, // [RH] Line blocks everything ML_ZONEBOUNDARY = 0x00010000, ML_RAILING = 0x00020000, ML_BLOCK_FLOATERS = 0x00040000, ML_CLIP_MIDTEX = 0x00080000, // Automatic for every Strife line ML_WRAP_MIDTEX = 0x00100000, ML_3DMIDTEX = 0x00200000, ML_CHECKSWITCHRANGE = 0x00400000, ML_FIRSTSIDEONLY = 0x00800000, // activated only when crossed from front side ML_BLOCKPROJECTILE = 0x01000000, ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks ML_3DMIDTEX_IMPASS = 0x10000000, // [TP] if 3D midtex, behaves like a height-restricted ML_BLOCKING }; native readonly vertex v1, v2; // vertices, from v1 to v2 native readonly Vector2 delta; // precalculated v2 - v1 for side checking native uint flags; native uint activation; // activation type native int special; native int args[5]; // <--- hexen-style arguments (expanded to ZDoom's full width) native double alpha; // <--- translucency (0=invisibile, FRACUNIT=opaque) //native Side sidedef[2]; native readonly double bbox[4]; // bounding box, for the extent of the LineDef. native readonly Sector frontsector, backsector; native int validcount; // if == validcount, already checked native int locknumber; // [Dusk] lock number for special native readonly uint portalindex; native readonly uint portaltransferred; native bool isLinePortal(); native bool isVisualPortal(); native Line getPortalDestination(); native int getPortalAlignment(); native int Index(); } struct SecPlane native { native Vector3 Normal; native double D; native double negiC; native bool isSlope(); native int PointOnSide(Vector3 pos); native double ZatPoint (Vector2 v); native double ZatPointDist(Vector2 v, double dist); native bool isEqual(Secplane other); native void ChangeHeight(double hdiff); native double GetChangedHeight(double hdiff); native double HeightDiff(double oldd, double newd = 0.0); native double PointToDist(Vector2 xy, double z); } // This encapsulates all info Doom's original 'special' field contained - for saving and transferring. struct SecSpecial { Name damagetype; int damageamount; short special; short damageinterval; short leakydamage; int Flags; } struct Sector native { //secplane_t floorplane, ceilingplane; // defined internally //FDynamicColormap *ColorMap; native Actor SoundTarget; native int16 special; native int16 lightlevel; native int16 seqType; native int sky; native Name SeqName; native readonly Vector2 centerspot; native int validcount; native Actor thinglist; native double friction, movefactor; native int terrainnum[2]; // thinker_t for reversable actions //SectorEffect floordata; //SectorEffect ceilingdata; //SectorEffect lightingdata; enum EPlane { floor, ceiling }; enum EInterpolationType { CeilingMove, FloorMove, CeilingScroll, FloorScroll }; //Interpolation interpolations[4]; native uint8 soundtraversed; native int8 stairlock; native int prevsec; native int nextsec; //TStaticPointedArray<line_t *> Lines; // this is defined internally to avoid exposing some overly complicated type to the parser native readonly Sector heightsec; native uint bottommap, midmap, topmap; //struct msecnode_t *touching_thinglist; //struct msecnode_t *sectorportal_thinglist; native double gravity; native Name damagetype; native int damageamount; native int16 damageinterval; native int16 leakydamage; native uint16 ZoneNumber; enum ESectorMoreFlags { SECMF_FAKEFLOORONLY = 2, // when used as heightsec in R_FakeFlat, only copies floor SECMF_CLIPFAKEPLANES = 4, // as a heightsec, clip planes to target sector's planes SECMF_NOFAKELIGHT = 8, // heightsec does not change lighting SECMF_IGNOREHEIGHTSEC= 16, // heightsec is only for triggering sector actions SECMF_UNDERWATER = 32, // sector is underwater SECMF_FORCEDUNDERWATER= 64, // sector is forced to be underwater SECMF_UNDERWATERMASK = 32+64, SECMF_DRAWN = 128, // sector has been drawn at least once SECMF_HIDDEN = 256, // Do not draw on textured automap } native uint16 MoreFlags; enum ESectorFlags { SECF_SILENT = 1, // actors in sector make no noise SECF_NOFALLINGDAMAGE= 2, // No falling damage in this sector SECF_FLOORDROP = 4, // all actors standing on this floor will remain on it when it lowers very fast. SECF_NORESPAWN = 8, // players can not respawn in this sector SECF_FRICTION = 16, // sector has friction enabled SECF_PUSH = 32, // pushers enabled SECF_SILENTMOVE = 64, // Sector movement makes mo sound (Eternity got this so this may be useful for an extended cross-port standard.) SECF_DMGTERRAINFX = 128, // spawns terrain splash when inflicting damage SECF_ENDGODMODE = 256, // getting damaged by this sector ends god mode SECF_ENDLEVEL = 512, // ends level when health goes below 10 SECF_HAZARD = 1024, // Change to Strife's delayed damage handling. SECF_WASSECRET = 1 << 30, // a secret that was discovered SECF_SECRET = 1 << 31, // a secret sector SECF_DAMAGEFLAGS = SECF_ENDGODMODE|SECF_ENDLEVEL|SECF_DMGTERRAINFX|SECF_HAZARD, SECF_NOMODIFY = SECF_SECRET|SECF_WASSECRET, // not modifiable by Sector_ChangeFlags SECF_SPECIALFLAGS = SECF_DAMAGEFLAGS|SECF_FRICTION|SECF_PUSH, // these flags originate from 'special and must be transferrable by floor thinkers } enum EMoveResult { MOVE_OK, MOVE_CRUSHED, MOVE_PASTDEST }; native uint Flags; native SectorAction SecActTarget; native readonly uint Portals[2]; native readonly int PortalGroup; native readonly int sectornum; native int Index(); native double, Sector, F3DFloor NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags = 0); native double, Sector, F3DFloor NextLowestFloorAt(double x, double y, double z, int flags = 0, double steph = 0); native void RemoveForceField(); native static Sector PointInSector(Vector2 pt); native void SetColor(color c, int desat = 0); native void SetFade(color c); native bool PlaneMoving(int pos); native int GetFloorLight(); native int GetCeilingLight(); native Sector GetHeightSec(); native void TransferSpecial(Sector model); native void GetSpecial(out SecSpecial spec); native void SetSpecial( SecSpecial spec); native int GetTerrain(int pos); native void CheckPortalPlane(int plane); native double, Sector HighestCeilingAt(Vector2 a); native double, Sector LowestFloorAt(Vector2 a); native double, double GetFriction(int plane); native void SetXOffset(int pos, double o); native void AddXOffset(int pos, double o); native double GetXOffset(int pos); native void SetYOffset(int pos, double o); native void AddYOffset(int pos, double o); native double GetYOffset(int pos, bool addbase = true); native void SetXScale(int pos, double o); native double GetXScale(int pos); native void SetYScale(int pos, double o); native double GetYScale(int pos); native void SetAngle(int pos, double o); native double GetAngle(int pos, bool addbase = true); native void SetBase(int pos, double y, double o); native void SetAlpha(int pos, double o); native double GetAlpha(int pos); native int GetFlags(int pos); native int GetVisFlags(int pos); native void ChangeFlags(int pos, int And, int Or); native int GetPlaneLight(int pos); native void SetPlaneLight(int pos, int level); native TextureID GetTexture(int pos); native void SetTexture(int pos, TextureID tex, bool floorclip = true); native double GetPlaneTexZ(int pos); native void SetPlaneTexZ(int pos, double val, bool dirtify = false); // This mainly gets used by init code. The only place where it must set the vertex to dirty is the interpolation code. native void ChangeLightLevel(int newval); native void SetLightLevel(int newval); native int GetLightLevel(); native void AdjustFloorClip(); native bool IsLinked(Sector other, bool ceiling); native bool PortalBlocksView(int plane); native bool PortalBlocksSight(int plane); native bool PortalBlocksMovement(int plane); native bool PortalBlocksSound(int plane); native bool PortalIsLinked(int plane); native void ClearPortal(int plane); native double GetPortalPlaneZ(int plane); native Vector2 GetPortalDisplacement(int plane); native int GetPortalType(int plane); native int GetOppositePortalGroup(int plane); native double CenterFloor(); native double CenterCeiling(); native bool TriggerSectorActions(Actor thing, int activation); native int MoveFloor(double speed, double dest, int crush, int direction, bool hexencrush, bool instant = false); native int MoveCeiling(double speed, double dest, int crush, int direction, bool hexencrush); native Sector NextSpecialSector(int type, Sector prev); native double, Vertex FindLowestFloorSurrounding(); native double, Vertex FindHighestFloorSurrounding(); native double, Vertex FindNextHighestFloor(); native double, Vertex FindNextLowestFloor(); native double, Vertex FindLowestCeilingSurrounding(); native double, Vertex FindHighestCeilingSurrounding(); native double, Vertex FindNextLowestCeiling(); native double, Vertex FindNextHighestCeiling(); native double FindShortestTextureAround(); native double FindShortestUpperAround(); native Sector FindModelFloorSector(double floordestheight); native Sector FindModelCeilingSector(double floordestheight); native int FindMinSurroundingLight(int max); native double, Vertex FindLowestCeilingPoint(); native double, Vertex FindHighestFloorPoint(); bool isSecret() { return !!(Flags & SECF_SECRET); } bool wasSecret() { return !!(Flags & SECF_WASSECRET); } void ClearSecret() { Flags &= ~SECF_SECRET; } } struct Wads { enum WadNamespace { ns_hidden = -1, ns_global = 0, ns_sprites, ns_flats, ns_colormaps, ns_acslibrary, ns_newtextures, ns_bloodraw, ns_bloodsfx, ns_bloodmisc, ns_strifevoices, ns_hires, ns_voxels, ns_specialzipdirectory, ns_sounds, ns_patches, ns_graphics, ns_music, ns_firstskin, } native static int CheckNumForName(string name, int ns, int wadnum = -1, bool exact = false); } struct TerrainDef native { native Name TerrainName; native int Splash; native int DamageAmount; native Name DamageMOD; native int DamageTimeMask; native double FootClip; native float StepVolume; native int WalkStepTics; native int RunStepTics; native Sound LeftStepSound; native Sound RightStepSound; native bool IsLiquid; native bool AllowProtection; native double Friction; native double MoveFactor; }; enum EPickStart { PPS_FORCERANDOM = 1, PPS_NOBLOCKINGCHECK = 2, } // Although String is a builtin type, this is a convenient way to attach methods to it. struct String native { native void Replace(String pattern, String replacement); } class Floor : Thinker native { // only here so that some constants and functions can be added. Not directly usable yet. enum EFloor { floorLowerToLowest, floorLowerToNearest, floorLowerToHighest, floorLowerByValue, floorRaiseByValue, floorRaiseToHighest, floorRaiseToNearest, floorRaiseAndCrush, floorRaiseAndCrushDoom, floorCrushStop, floorLowerInstant, floorRaiseInstant, floorMoveToValue, floorRaiseToLowestCeiling, floorRaiseByTexture, floorLowerAndChange, floorRaiseAndChange, floorRaiseToLowest, floorRaiseToCeiling, floorLowerToLowestCeiling, floorLowerByTexture, floorLowerToCeiling, donutRaise, buildStair, waitStair, resetStair, // Not to be used as parameters to EV_DoFloor() genFloorChg0, genFloorChgT, genFloorChg }; native static bool CreateFloor(sector sec, EFloor floortype, line ln, double speed, double height = 0, int crush = -1, int change = 0, bool crushmode = false, bool hereticlower = false); } class Ceiling : Thinker native { enum ECeiling { ceilLowerByValue, ceilRaiseByValue, ceilMoveToValue, ceilLowerToHighestFloor, ceilLowerInstant, ceilRaiseInstant, ceilCrushAndRaise, ceilLowerAndCrush, ceil_placeholder, ceilCrushRaiseAndStay, ceilRaiseToNearest, ceilLowerToLowest, ceilLowerToFloor, // The following are only used by Generic_Ceiling ceilRaiseToHighest, ceilLowerToHighest, ceilRaiseToLowest, ceilLowerToNearest, ceilRaiseToHighestFloor, ceilRaiseToFloor, ceilRaiseByTexture, ceilLowerByTexture, genCeilingChg0, genCeilingChgT, genCeilingChg } enum ECrushMode { crushDoom = 0, crushHexen = 1, crushSlowdown = 2 } native bool CreateCeiling(sector sec, int type, line ln, double speed, double speed2, double height = 0, int crush = -1, int silent = 0, int change = 0, int crushmode = crushDoom); } struct LookExParams { double Fov; double minDist; double maxDist; double maxHeardist; int flags; State seestate; };