// GENERAL FTE NOTE! // Don't use 'extern' on method prototypes, it makes no difference and the compiler prints // a spammy warning "Only global functions may be defined as external (yet)" without a line // number when it sees it. // Or it happens anyway and I have no clue what I'm going on about. // Maybe even externing var's does it. // also, FTE needs a space after a preprocessor macro name for a slash to drop-down to the // rest of the definition, like "#define thing \". /////////////////////////////////////////////////////////////////////////// #define NULL __NULL__ #define BOOL float #define BOOLEAN float // plain printouts, no client/server tagging //#define printf(...) print(sprintf(__VA_ARGS__)) //#define printfline(s1, ...) print(sprintf(s1"\n" __VA_ARGS__)) //#define printlinef(s1, ...) print(sprintf(s1"\n" __VA_ARGS__)) //////////////////////////////////////////////////////// // TODO - let some easy constant, or even just "debug", specify whether to include // the CL or SV in front. But we don't know how many re-updates from modern files // will happen between now and then. // ALSO - Nuclide now provides printf, but without the ellipses parameter. // That means Nuclide's printf is only a shortener of print + sprintf for calls // without any other fill-ins (%d, etc.). // Undoing that here for now, compatible with original calls anytime. // And do we care about bprint (broadcast-print)? Example: // bprint(PRINT_HIGH, sprintf("SSQC: %s", sWow) ); // Probably not for debugging as printf is working fine for the typical rapid-fire // single player debug. #ifdef printf #undef printf #endif #ifdef CLIENT #define printf_starter print("CL") #define printf(s1, ...) print(sprintf(s1, ##__VA_ARGS__)) #define printfline(s1, ...) print(sprintf("CL: "s1"\n", ##__VA_ARGS__)) #define printlinef(s1, ...) print(sprintf("CL: "s1"\n", ##__VA_ARGS__)) #else #define printf_starter print("SV") #define printf(s1, ...) print(sprintf(s1, ##__VA_ARGS__)) #define printfline(s1, ...) print(sprintf("SV: "s1"\n", ##__VA_ARGS__)) #define printlinef(s1, ...) print(sprintf("SV: "s1"\n", ##__VA_ARGS__)) #endif // could dummy printouts by enabling this block instead of the above /* #define printf_starter #define printf(s1, ...) #define printfline(s1, ...) #define printlinef(s1, ...) */ // Safe way to declare an entity seen in FreeHL. Think of it as: // arg_dest = spawnfunc_ClassNameHere; // This lets the constructor invoked by 'spawnfunc_' have a 'self' set // to the place it will end up going to, and restores 'self' after the // call is over. // NOTE! Requires an entity to be declared called 'eold' first, like so: // entity eold; // Doing that in case of subsequent SPAWN_ENTITY_SAFE calls. // Would declaring 'eold' globally be okay for the entire game? Hard to say. // NOTE - if you do indeed want the current entity to become of the new type, // then moving around 'self' like this is unnecessary, just call the 'pawnfunc_' // as usual. // I'm fuzzy on the details between 'spawn(CLASSNAME)' and 'spawnfunc_CLASSNAME'. // If you don't know what you're doing just spawn a clean entity like the former // approach, this is actually for changing something already spawened into another // type. Parse functions may do this to turn a default entity they receive into // whatever their custom type is, as seen in ts_powerup #define SPAWN_ENTITY_SAFE(arg_dest, arg_class) \ eold = self;\ self = arg_dest;\ spawnfunc_##arg_class();\ self = eold; // will anywhere shared ever need this? #ifdef CLIENT #define GET_GAME_STATE getstatf(STAT_GAMESTATE) #else #define GET_GAME_STATE g_ts_gamestate #endif // !!! Other weapons-related macros //////////////////////////////////////////////////////// // OLD INPUT WAY // is setting gflags_net too a good idea? That applies to a whole host of other // things too. // use 1 for the closest to Nuclide defaults, 2 for a little extra frame tolerance for // clientside. #define INPUT_TAP_DETECT_CHOICE 1 #if INPUT_TAP_DETECT_CHOICE == 1 /////////////////////////////////////////////////////////////////////////////////////////// // Standard way. #define INPUT_PRIMARY_TAP_GATE \ if (pl.gflags & GF_SEMI_TOGGLED)\ return; #define INPUT_SECONDARY_TAP_GATE \ if (pl.gflags & GF_SEMI_SECONDARY_TOGGLED)\ return; #define INPUT_PRIMARY_TAP_CHECK(arg_pl) (!(pl.gflags & GF_SEMI_TOGGLED)) #define INPUT_SECONDARY_TAP_CHECK(arg_pl) (!(pl.gflags & GF_SEMI_SECONDARY_TOGGLED)) #define INPUT_PRIMARY_TAP_CHECK_NOT(arg_pl) (pl.gflags & GF_SEMI_TOGGLED) #define INPUT_SECONDARY_TAP_CHECK_NOT(arg_pl) (pl.gflags & GF_SEMI_SECONDARY_TOGGLED) #define INPUT_TAP_RESET(arg_pl) \ arg_pl.gflags |= GF_SEMI_TOGGLED; \ arg_pl.gflags |= GF_SEMI_SECONDARY_TOGGLED; #else /////////////////////////////////////////////////////////////////////////////////////////// // ALTERNATE WAY: check pl.inputTapFrameCount for primary/secondary. // Lets setting an extra frame for a little more tolerance work, these are // set to 1 on a fresh key press to work exactly like above or over 1 for // extra frames to let count as a tap. // ALSO - these assume the current player is available as a var called 'pl'. #define INPUT_PRIMARY_TAP_GATE \ if (pl.inputPrimaryTapFrameCount == 0)\ return; #define INPUT_SECONDARY_TAP_GATE \ if (pl.inputSecondaryTapFrameCount == 0)\ return; #define INPUT_PRIMARY_TAP_CHECK(arg_pl) (pl.inputPrimaryTapFrameCount > 0) #define INPUT_SECONDARY_TAP_CHECK(arg_pl) (pl.inputSecondaryTapFrameCount > 0) #define INPUT_PRIMARY_TAP_CHECK_NOT(arg_pl) (pl.inputPrimaryTapFrameCount == 0) #define INPUT_SECONDARY_TAP_CHECK_NOT(arg_pl) (pl.inputSecondaryTapFrameCount == 0) #define INPUT_TAP_RESET(arg_pl)\ arg_pl.inputPrimaryTapFrameCount = 0;\ arg_pl.inputSecondaryTapFrameCount = 0;\ arg_pl.inputPrimaryReleasedQueue = FALSE;\ arg_pl.inputSecondaryReleasedQueue = FALSE; /////////////////////////////////////////////////////////////////////////////////////////// #endif// INPUT_TAP_DETECT_CHOICE // OLD WAY TO DO CLICK SOUNDS /* // Let's make click sounds clientside-only for now #ifdef CLIENT #define PLAY_CLICK_SOUND \ sound(pl, CHAN_ITEM, "weapons/pistol-empty.wav", 1, ATTN_NONE);\ weapon_base_setWholeAttackDelay(pl, 0.22); #define PLAY_CLICK_SOUND_LEFT \ sound(pl, CHAN_ITEM, "weapons/pistol-empty.wav", 1, ATTN_NONE);\ weapon_base_setLeftAttackDelay(pl, 0.22); #define PLAY_CLICK_SOUND_RIGHT \ sound(pl, CHAN_ITEM, "weapons/pistol-empty.wav", 1, ATTN_NONE);\ weapon_base_setRightAttackDelay(pl, 0.22); #else // SERVER // (no sounds, just set delays) #define PLAY_CLICK_SOUND \ weapon_base_setWholeAttackDelay(pl, 0.22); #define PLAY_CLICK_SOUND_LEFT \ weapon_base_setLeftAttackDelay(pl, 0.22); #define PLAY_CLICK_SOUND_RIGHT \ weapon_base_setRightAttackDelay(pl, 0.22); #endif */ #define PLAY_CLICK_SOUND \ TS_Weapons_PlaySoundChannelDirect(pl, "weapons/pistol-empty.wav", CHAN_ITEM);\ weapon_base_setWholeAttackDelay(pl, 0.22); #define PLAY_CLICK_SOUND_LEFT \ TS_Weapons_PlaySoundChannelDirect(pl, "weapons/pistol-empty.wav", CHAN_ITEM);\ weapon_base_setLeftAttackDelay(pl, 0.22); #define PLAY_CLICK_SOUND_RIGHT \ TS_Weapons_PlaySoundChannelDirect(pl, "weapons/pistol-empty.wav", CHAN_ITEM);\ weapon_base_setRightAttackDelay(pl, 0.22); // For serverside, assumes the local player is a var named "pl"! #ifdef CLIENT #define GET_VIEW_ANGLES view_angles #else #define GET_VIEW_ANGLES pl.v_angle #endif #ifdef CLIENT #define GET_MY_VIEW_ANGLES view_angles #else #define GET_MY_VIEW_ANGLES this.v_angle #endif // OLD UNDERWATER CHECK. Using a new var for more accuracy. //#define WEAPON_UNDERWATER_CHECK pl.waterlevel >= 3 //#define WEAPON_UNDERWATER_CHECK_NOT pl.waterlevel < 3 #define WEAPON_UNDERWATER_CHECK !pl.bViewAboveWater #define WEAPON_UNDERWATER_CHECK_NOT pl.bViewAboveWater // be aware of the player class player; // extern? const vector g_vZero = [0,0,0]; #ifdef SERVER void centerprintToAll(string strSend); #endif int floor_proper(float arg); int ceil_proper(float arg); int round(float arg); float randomInRange_raw_f(float min, float max); float randomInRange_f(float min, float max); int randomInRange_raw_i(int min, int max); int randomInRange_i(int min, int max); float safeRandom(void); #ifdef SERVER void removeSelfDelayed(entity entTarget); #endif void entity_removeSelf(void); string floatToChar(float someFloat); // Unfortunately I don't know if default optional parameters (equals-sign in prototypes like this) // works reliably. I think so... kindof? sometimes? for integers maybe? It's weeeeird. //int count1Bits(int bitmask, optional int bitStart = 0x1, optional int bitEnd = 0x80000000); //int findFirst1Bit(int bitmask, optional int bitStart = 0x1, optional int bitEnd = 0x80000000‬); int count1Bits(int bitmask, optional int bitStart = 0x1i, optional int bitEnd = -2147483648i); int findFirst1Bit(int bitmask, optional int bitStart = 0x1i, optional int bitEnd = -2147483648i); void stopSound(entity e, float chan); void entity_beginCorpseFadeOut(void); void entity_corpseFadeOut(void); float getViewPitchRelativeRatio(float playerPitch); float getViewModelAnimExtraDuration(void); #ifdef SERVER class CBaseEntity; void entityRemoveRespawnFlag(CBaseEntity arg_this); #endif void TS_Weapons_ViewAnimation(int i, float fDuration); void TS_Weapons_ViewAnimation_noLaserLock(int i, float fDuration); void TS_Weapons_ViewAnimation_EndIdle(int i, float fDuration); void TS_Weapons_ViewAnimation_EndIdle_custom(int i, float fDuration, float fIdleEndOffset); #ifdef CLIENT void TS_View_PlayAnimation(int iSequence, float fDuration); void TS_View_PlayAnimation_noLaserLock(int iSequence, float fDuration); void TS_View_PlayAnimation_EndIdle(int iSequence, float fDuration); void TS_View_PlayAnimation_EndIdle_custom(int iSequence, float fDuration, float fIdleEndOffset); #endif void TS_Weapons_PlaySoundDirect(player pl, string samp); void TS_Weapons_PlaySoundChannelDirect(player pl, string samp, int chann);