mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-07-31 09:31:45 +03:00
Merge Mapbase v8.0 into the MP branch
This commit is contained in:
commit
0d7c5b4fd3
20
README.md
20
README.md
@ -52,6 +52,7 @@ Mapbase uses content from the following non-Source SDK 2013 Valve games or SDKs:
|
|||||||
-- Alien Swarm (Used to port assets from the aforementioned SDK code features, e.g. game instructor icons)
|
-- Alien Swarm (Used to port assets from the aforementioned SDK code features, e.g. game instructor icons)
|
||||||
-- Left 4 Dead (Used to port certain animations as well as assets from the aforementioned SDK code features, e.g. particle rain)
|
-- Left 4 Dead (Used to port certain animations as well as assets from the aforementioned SDK code features, e.g. particle rain)
|
||||||
-- Half-Life: Source (Used to port friction tool textures)
|
-- Half-Life: Source (Used to port friction tool textures)
|
||||||
|
-- Half-Life 2: Survivor (Used to port Gordon Freeman model)
|
||||||
|
|
||||||
Valve allows assets from these titles to be distributed for modding purposes. Note that ported assets are only used in the release build, not the code repository.
|
Valve allows assets from these titles to be distributed for modding purposes. Note that ported assets are only used in the release build, not the code repository.
|
||||||
|
|
||||||
@ -118,6 +119,7 @@ Direct contributions:
|
|||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/245 (ViewPunch random fix by Mr0maks)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/245 (ViewPunch random fix by Mr0maks)
|
||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/248 (soundlevel_t conversation warning fix by Mechami)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/248 (soundlevel_t conversation warning fix by Mechami)
|
||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/266 ("OnPhysGunPull" output in CPhysicsProp by rlenhub)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/266 ("OnPhysGunPull" output in CPhysicsProp by rlenhub)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/281 (npc_combinedropship DropStrider input by Bronzehawk75)
|
||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/292 (env_headcrabcanister random spawn type by arbabf)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/292 (env_headcrabcanister random spawn type by arbabf)
|
||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/293 (Restore text selection code by SanyaSho)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/293 (Restore text selection code by SanyaSho)
|
||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/294 (SDK_LightmappedGeneric editor blend swap fix by azzyr)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/294 (SDK_LightmappedGeneric editor blend swap fix by azzyr)
|
||||||
@ -133,17 +135,27 @@ Direct contributions:
|
|||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/391 (VRAD -extrapasses command by Unusuario2)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/391 (VRAD -extrapasses command by Unusuario2)
|
||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/393 (Additional VBSP options doc by Unusuario2)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/393 (Additional VBSP options doc by Unusuario2)
|
||||||
- https://github.com/mapbase-source/source-sdk-2013/pull/397 (Viewmodel camera bone by Nbc66)
|
- https://github.com/mapbase-source/source-sdk-2013/pull/397 (Viewmodel camera bone by Nbc66)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/412 (Compile tool negative threads support by Unusuario2)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/414 (VRAD %alphatexture by SirYodaJedi)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/415 (Parallax corrected cubemaps optimization and fix by Zeldaboy14 and White_Red_Dragons)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/418 (Server ragdoll death poses by AnOldLady)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/419 (npc_helicopter removal crash fix by Wikot235)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/420 (sk_combine_head_dmg_multiplier cvar by Wikot235)
|
||||||
|
- https://github.com/mapbase-source/source-sdk-2013/pull/422 (Expanded HL2 NPC custom model support by Maestra Fenix [committed by Blixibon])
|
||||||
- https://github.com/mapbase-source/mapbase-game-src/pull/1 (Advanced video options duplicate field name fix by arbabf; This is asset-based and not reflected in the code)
|
- https://github.com/mapbase-source/mapbase-game-src/pull/1 (Advanced video options duplicate field name fix by arbabf; This is asset-based and not reflected in the code)
|
||||||
- https://github.com/mapbase-source/mapbase-game-src/pull/2 (gameinfo.txt typo fix by CarePackage17; This is asset-based and not reflected in the code)
|
- https://github.com/mapbase-source/mapbase-game-src/pull/2 (gameinfo.txt typo fix by CarePackage17; This is asset-based and not reflected in the code)
|
||||||
- https://github.com/mapbase-source/mapbase-game-src/pull/3 (HudMessage cutoff fix by arbabf; This is asset-based and not reflected in the code)
|
- https://github.com/mapbase-source/mapbase-game-src/pull/3 (HudMessage cutoff fix by arbabf; This is asset-based and not reflected in the code)
|
||||||
- Demo autorecord code provided by Klems
|
- Demo autorecord code provided by Klems
|
||||||
- cc_emit crash fix provided by 1upD
|
- cc_emit crash fix provided by 1upD
|
||||||
|
- npc_barnacle poison zombie crash fix provided by Agrimar
|
||||||
- Custom HL2 ammo crate models created by Rykah (Textures created by Blixibon; This is asset-based and, aside from the SLAM crate, not reflected in the code)
|
- Custom HL2 ammo crate models created by Rykah (Textures created by Blixibon; This is asset-based and, aside from the SLAM crate, not reflected in the code)
|
||||||
- Combine lock hardware on door01_left.mdl created by Kralich (This is asset-based and not reflected in the code)
|
- Combine lock hardware on door01_left.mdl created by Kralich (This is asset-based and not reflected in the code)
|
||||||
- npc_vehicledriver fixes provided by CrAzY
|
- npc_vehicledriver fixes provided by CrAzY
|
||||||
- npc_combine cover behavior patches provided by iohnnyboy
|
- npc_combine cover behavior patches provided by iohnnyboy
|
||||||
- logic_playmovie icon created by URAKOLOUY5 (This is asset-based and not reflected in the code)
|
- logic_playmovie icon created by URAKOLOUY5 (This is asset-based and not reflected in the code)
|
||||||
- Dropship APC save/load fix provided by Cvoxulary
|
- Dropship APC save/load fix provided by Cvoxulary
|
||||||
|
- c_arms support on HL2 viewmodels by Inaki and ReverendV92 (This is asset-based and not reflected in the code)
|
||||||
|
- Custom c_arms for HL2 characters by Notewell (This is asset-based and not reflected in the code)
|
||||||
|
|
||||||
== Contributions from samisalreadytaken:
|
== Contributions from samisalreadytaken:
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/47 (VScript utility/consistency changes)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/47 (VScript utility/consistency changes)
|
||||||
@ -166,8 +178,14 @@ Direct contributions:
|
|||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/260 (CScriptNetPropManager rewrite)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/260 (CScriptNetPropManager rewrite)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/261 (Misc VScript additions)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/261 (Misc VScript additions)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/279 (weapon_custom_scripted fixes)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/279 (weapon_custom_scripted fixes)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/302 (VScript debugger)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/331 (VScript leak fixes)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/331 (VScript leak fixes)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/332 (Fix OOB access)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/332 (Fix OOB access)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/411 (VScript debugger cleanup)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/423 (GetPropFloatArray Vector indexing fix)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/431 (VScript save/restore and debugger fixes)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/441 (VScript instance helper fallback)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/447 (Update VScript sqdbg)
|
||||||
|
|
||||||
== Contributions from z33ky:
|
== Contributions from z33ky:
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/21 (Various GCC/Linux compilation fixes)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/21 (Various GCC/Linux compilation fixes)
|
||||||
@ -184,6 +202,7 @@ Direct contributions:
|
|||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/320 (Fix ScriptHook_t initialization order)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/320 (Fix ScriptHook_t initialization order)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/321 (Prevent return of dangling Vector/QAngle to VScript)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/321 (Prevent return of dangling Vector/QAngle to VScript)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/322 (Small Mapbase fixes)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/322 (Small Mapbase fixes)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/436 (VScript member function call safety)
|
||||||
|
|
||||||
== Contributions from Petercov:
|
== Contributions from Petercov:
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/182 (NPCs load dynamic interactions from all animation MDLs)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/182 (NPCs load dynamic interactions from all animation MDLs)
|
||||||
@ -194,6 +213,7 @@ Direct contributions:
|
|||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/230 (Caption fixes)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/230 (Caption fixes)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/231 (Sentence source bug fix)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/231 (Sentence source bug fix)
|
||||||
=-- https://github.com/mapbase-source/source-sdk-2013/pull/264 (Outputs for vgui_screen)
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/264 (Outputs for vgui_screen)
|
||||||
|
=-- https://github.com/mapbase-source/source-sdk-2013/pull/427 (CBaseCombatWeapon::WeaponClassFromString typo fix [committed by vizzys])
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ $Project
|
|||||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
||||||
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
|
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
|
||||||
$File "$SRCDIR\game\shared\mapbase\matchers.h"
|
$File "$SRCDIR\game\shared\mapbase\matchers.h"
|
||||||
|
$File "$SRCDIR\game\shared\mapbase\game_timer.cpp"
|
||||||
|
$File "$SRCDIR\game\shared\mapbase\game_timer.h"
|
||||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
|
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
|
||||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
|
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
|
||||||
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]
|
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]
|
||||||
|
@ -16,6 +16,7 @@ $Project
|
|||||||
$File "$SRCDIR\game\shared\mapbase\protagonist_system.h"
|
$File "$SRCDIR\game\shared\mapbase\protagonist_system.h"
|
||||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT]
|
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT]
|
||||||
$File "mapbase\c_weapon_custom_hl2.cpp"
|
$File "mapbase\c_weapon_custom_hl2.cpp"
|
||||||
|
$File "mapbase\hud_generic_timer.cpp"
|
||||||
}
|
}
|
||||||
|
|
||||||
$Folder "HL2 DLL"
|
$Folder "HL2 DLL"
|
||||||
|
511
src/game/client/mapbase/hud_generic_timer.cpp
Normal file
511
src/game/client/mapbase/hud_generic_timer.cpp
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
|
||||||
|
//
|
||||||
|
// Purpose: Generic timer HUD element for HL2-based mods
|
||||||
|
//
|
||||||
|
// Author: Blixibon
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "hud.h"
|
||||||
|
#include "hud_macros.h"
|
||||||
|
#include "hudelement.h"
|
||||||
|
#include "hud_numericdisplay.h"
|
||||||
|
#include "iclientmode.h"
|
||||||
|
#include <vgui/ILocalize.h>
|
||||||
|
#include <vgui/ISurface.h>
|
||||||
|
#include <vgui_controls/AnimationController.h>
|
||||||
|
#include <vgui_controls/EditablePanel.h>
|
||||||
|
#include "baseviewport.h"
|
||||||
|
#include "mapbase/game_timer.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
extern bool g_bAnyGameTimerActive;
|
||||||
|
|
||||||
|
ConVar hud_timer_max_bars( "hud_timer_max_bars", "15" );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Timer panel
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CHudGenericGameTimer : public CHudElement, public vgui::Panel
|
||||||
|
{
|
||||||
|
DECLARE_CLASS_SIMPLE( CHudGenericGameTimer, vgui::Panel );
|
||||||
|
|
||||||
|
public:
|
||||||
|
CHudGenericGameTimer( const char *pElementName );
|
||||||
|
virtual void Init( void );
|
||||||
|
virtual void VidInit( void );
|
||||||
|
virtual void Reset( void );
|
||||||
|
virtual void OnThink();
|
||||||
|
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||||||
|
virtual bool ShouldDraw( void );
|
||||||
|
virtual void Paint();
|
||||||
|
|
||||||
|
C_GameTimer *GetTimer();
|
||||||
|
bool FindTimer();
|
||||||
|
|
||||||
|
void SetDisplayValue( int value ) { m_iValue = value; }
|
||||||
|
void SetLabelText( const wchar_t *text );
|
||||||
|
|
||||||
|
virtual void PaintNumbers( vgui::HFont font, int xpos, int ypos );
|
||||||
|
virtual void PaintBars( int xpos, int ypos, int wide );
|
||||||
|
|
||||||
|
int GetTimerIndex() const { return m_iTimerIndex; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetTimerLabel( void );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int m_iTimerIndex;
|
||||||
|
|
||||||
|
bool m_bTimerDisplayed;
|
||||||
|
bool m_bPlayingFadeout;
|
||||||
|
float m_flShutoffTime;
|
||||||
|
|
||||||
|
bool m_bTimerPaused;
|
||||||
|
bool m_bTimerWarned;
|
||||||
|
|
||||||
|
int m_iValue;
|
||||||
|
int m_iTimerMaxLength;
|
||||||
|
bool m_bShowTimeRemaining;
|
||||||
|
int m_nProgressBarMax;
|
||||||
|
int m_nProgressBarOverride;
|
||||||
|
float m_flOverrideX, m_flOverrideY;
|
||||||
|
wchar_t m_LabelText[32];
|
||||||
|
|
||||||
|
int m_nLabelWidth, m_nLabelHeight;
|
||||||
|
int m_nTimerWidth, m_nTimerHeight;
|
||||||
|
|
||||||
|
CPanelAnimationVarAliasType( float, m_flMinWidth, "MinWidth", "100", "proportional_float" );
|
||||||
|
CPanelAnimationVarAliasType( float, m_flBorder, "Border", "24", "proportional_float" );
|
||||||
|
CPanelAnimationVarAliasType( float, m_flLabelTimerSpacing, "LabelTimerSpacing", "2", "proportional_float" );
|
||||||
|
|
||||||
|
CPanelAnimationVarAliasType( float, m_flBarHeight, "BarHeight", "5", "proportional_float" );
|
||||||
|
CPanelAnimationVarAliasType( float, m_flBarChunkGap, "BarChunkGap", "3", "proportional_float" );
|
||||||
|
CPanelAnimationVarAliasType( float, m_flBarVerticalGap, "BarVerticalGap", "8", "proportional_float" );
|
||||||
|
CPanelAnimationVar( int, m_iBarDisabledAlpha, "BarDisabledAlpha", "70" );
|
||||||
|
|
||||||
|
CPanelAnimationVar( float, m_flBlur, "Blur", "0" );
|
||||||
|
|
||||||
|
CPanelAnimationVar( vgui::HFont, m_hNumberFont, "NumberFont", "HudHintTextLarge" );
|
||||||
|
CPanelAnimationVar( vgui::HFont, m_hNumberGlowFont, "NumberGlowFont", "HudHintTextLarge" );
|
||||||
|
CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "HudHintTextSmall" );
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_HUDELEMENT( CHudGenericGameTimer );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Constructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CHudGenericGameTimer::CHudGenericGameTimer( const char *pElementName )
|
||||||
|
: CHudElement( pElementName ),
|
||||||
|
BaseClass( NULL, "HudGenericGameTimer" )
|
||||||
|
{
|
||||||
|
Panel *pParent = g_pClientMode->GetViewport();
|
||||||
|
SetParent( pParent );
|
||||||
|
|
||||||
|
SetHiddenBits( HIDEHUD_MISCSTATUS );
|
||||||
|
|
||||||
|
m_iTimerIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::Init()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::Reset()
|
||||||
|
{
|
||||||
|
SetDisplayValue( 0 );
|
||||||
|
SetAlpha( 0 );
|
||||||
|
|
||||||
|
m_flShutoffTime = 0.0f;
|
||||||
|
m_bTimerDisplayed = false;
|
||||||
|
m_iTimerIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::VidInit()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::OnThink()
|
||||||
|
{
|
||||||
|
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if ( !local )
|
||||||
|
{
|
||||||
|
// Not ready to init!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If our timer has been disabled, close the menu
|
||||||
|
C_GameTimer *pTimer = GetTimer();
|
||||||
|
if ( !pTimer || pTimer->IsDisabled() || pTimer->IsMarkedForDeletion() )
|
||||||
|
{
|
||||||
|
if ( m_flShutoffTime == 0.0f )
|
||||||
|
{
|
||||||
|
m_flShutoffTime = gpGlobals->curtime + 1.0f;
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "GenericGameTimerClose" );
|
||||||
|
}
|
||||||
|
m_iTimerIndex = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check pause state
|
||||||
|
if ( m_bTimerPaused && !pTimer->IsTimerPaused() )
|
||||||
|
{
|
||||||
|
m_bTimerPaused = false;
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "GenericGameTimerPulse" );
|
||||||
|
}
|
||||||
|
else if ( pTimer->IsTimerPaused() )
|
||||||
|
{
|
||||||
|
m_bTimerPaused = true;
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "GenericGameTimerPulseOnce" );
|
||||||
|
}
|
||||||
|
|
||||||
|
float flTimeRemaining = floorf( pTimer->GetTimeRemaining() );
|
||||||
|
|
||||||
|
// Check warn state
|
||||||
|
float flWarnTime = pTimer->GetWarnTime();
|
||||||
|
|
||||||
|
if (flWarnTime > 0.0f)
|
||||||
|
{
|
||||||
|
if ( m_bTimerWarned && flTimeRemaining > flWarnTime )
|
||||||
|
{
|
||||||
|
// Turn back to normal
|
||||||
|
m_bTimerWarned = false;
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "GenericGameTimerUnwarn" );
|
||||||
|
}
|
||||||
|
else if ( flTimeRemaining <= flWarnTime )
|
||||||
|
{
|
||||||
|
// Turn red
|
||||||
|
m_bTimerWarned = true;
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "GenericGameTimerWarn" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDisplayValue( flTimeRemaining );
|
||||||
|
|
||||||
|
m_iTimerMaxLength = pTimer->GetTimerMaxLength();
|
||||||
|
m_bShowTimeRemaining = pTimer->ShowTimeRemaining();
|
||||||
|
|
||||||
|
m_nProgressBarMax = pTimer->GetProgressBarMaxSegments();
|
||||||
|
if (m_nProgressBarMax == -1)
|
||||||
|
{
|
||||||
|
// Default to timer max length
|
||||||
|
m_nProgressBarMax = min( m_iTimerMaxLength, hud_timer_max_bars.GetInt() );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nProgressBarOverride = pTimer->GetProgressBarOverride();
|
||||||
|
|
||||||
|
pTimer->GetPositionOverride( m_flOverrideX, m_flOverrideY );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: hud scheme settings
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||||
|
{
|
||||||
|
BaseClass::ApplySchemeSettings( pScheme );
|
||||||
|
|
||||||
|
SetPaintBackgroundEnabled( false );
|
||||||
|
|
||||||
|
// set our size
|
||||||
|
int screenWide, screenTall;
|
||||||
|
int x, y;
|
||||||
|
GetPos( x, y );
|
||||||
|
GetHudSize( screenWide, screenTall );
|
||||||
|
SetBounds( 0, y, screenWide, screenTall - y );
|
||||||
|
|
||||||
|
// Start with a 0:00 timer
|
||||||
|
m_nTimerWidth = (vgui::surface()->GetCharacterWidth( m_hNumberFont, '0' ) * 3);
|
||||||
|
m_nTimerWidth += vgui::surface()->GetCharacterWidth( m_hNumberFont, ':' );
|
||||||
|
|
||||||
|
m_nTimerHeight = vgui::surface()->GetFontTall( m_hNumberFont );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CHudGenericGameTimer::ShouldDraw( void )
|
||||||
|
{
|
||||||
|
if ( !CHudElement::ShouldDraw() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !m_bTimerDisplayed )
|
||||||
|
{
|
||||||
|
// Check if we should find a new timer
|
||||||
|
if ( g_bAnyGameTimerActive )
|
||||||
|
{
|
||||||
|
if ( FindTimer() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for if menu is set to disappear
|
||||||
|
if ( m_flShutoffTime > 0 && m_flShutoffTime <= gpGlobals->curtime )
|
||||||
|
{
|
||||||
|
// times up, shutoff
|
||||||
|
m_bTimerDisplayed = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_flOverrideX == -1.0f && m_flOverrideY == -1.0f )
|
||||||
|
{
|
||||||
|
// Don't overlap with the weapon selection HUD
|
||||||
|
vgui::Panel *pWeaponSelection = GetParent()->FindChildByName( "HudWeaponSelection" );
|
||||||
|
if ( pWeaponSelection && pWeaponSelection->IsVisible() )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline C_GameTimer *CHudGenericGameTimer::GetTimer()
|
||||||
|
{
|
||||||
|
if (m_iTimerIndex <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Need to do a dynamic_cast because this entity index could've been replaced since it was last used
|
||||||
|
return dynamic_cast<C_GameTimer*>(C_BaseEntity::Instance( m_iTimerIndex ));
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CHudGenericGameTimer::FindTimer()
|
||||||
|
{
|
||||||
|
// Find a new timer
|
||||||
|
for ( int i = 0; i < IGameTimerAutoList::AutoList().Count(); i++ )
|
||||||
|
{
|
||||||
|
C_GameTimer *pTimer = static_cast<C_GameTimer *>( IGameTimerAutoList::AutoList()[i] );
|
||||||
|
if ( !pTimer->IsDisabled() && !pTimer->IsMarkedForDeletion() )
|
||||||
|
{
|
||||||
|
m_iTimerIndex = pTimer->entindex();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
C_GameTimer *pTimer = GetTimer();
|
||||||
|
if ( pTimer )
|
||||||
|
{
|
||||||
|
// New timer selected, set the caption
|
||||||
|
wchar_t wszLabelText[128];
|
||||||
|
const wchar_t *wLocalizedItem = g_pVGuiLocalize->Find( pTimer->GetTimerCaption() );
|
||||||
|
if (wLocalizedItem)
|
||||||
|
{
|
||||||
|
V_wcsncpy( wszLabelText, wLocalizedItem, sizeof( wszLabelText ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_pVGuiLocalize->ConvertANSIToUnicode( pTimer->GetTimerCaption(), wszLabelText, sizeof( wszLabelText ) );
|
||||||
|
}
|
||||||
|
SetLabelText( wszLabelText );
|
||||||
|
|
||||||
|
m_flShutoffTime = 0;
|
||||||
|
m_bTimerDisplayed = true;
|
||||||
|
m_bTimerPaused = pTimer->IsTimerPaused();
|
||||||
|
m_bTimerWarned = false;
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_bTimerPaused ? "GenericGameTimerShow" : "GenericGameTimerShowFlash" );
|
||||||
|
|
||||||
|
SetDisplayValue( ceil( pTimer->GetTimeRemaining() ) );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: data accessor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::SetLabelText( const wchar_t *text )
|
||||||
|
{
|
||||||
|
wcsncpy( m_LabelText, text, sizeof( m_LabelText ) / sizeof( wchar_t ) );
|
||||||
|
m_LabelText[(sizeof( m_LabelText ) / sizeof( wchar_t )) - 1] = 0;
|
||||||
|
|
||||||
|
m_nLabelWidth = 0;
|
||||||
|
m_nLabelHeight = 0;
|
||||||
|
|
||||||
|
if (m_LabelText[0] != '\0')
|
||||||
|
{
|
||||||
|
int nLabelLen = V_wcslen( m_LabelText );
|
||||||
|
for (int ch = 0; ch < nLabelLen; ch++)
|
||||||
|
{
|
||||||
|
m_nLabelWidth += vgui::surface()->GetCharacterWidth( m_hTextFont, m_LabelText[ch] );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nLabelHeight = vgui::surface()->GetFontTall( m_hTextFont );
|
||||||
|
m_nLabelHeight += m_flLabelTimerSpacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: paints a number at the specified position
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::PaintNumbers( vgui::HFont font, int xpos, int ypos )
|
||||||
|
{
|
||||||
|
vgui::surface()->DrawSetTextFont(font);
|
||||||
|
|
||||||
|
int nTimeToDisplay = m_iValue;
|
||||||
|
|
||||||
|
if ( !m_bShowTimeRemaining )
|
||||||
|
{
|
||||||
|
nTimeToDisplay = m_iTimerMaxLength - nTimeToDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nMinutes = 0;
|
||||||
|
int nSeconds = 0;
|
||||||
|
wchar_t unicode[6];
|
||||||
|
|
||||||
|
if (nTimeToDisplay <= 0)
|
||||||
|
{
|
||||||
|
nMinutes = 0;
|
||||||
|
nSeconds = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nMinutes = nTimeToDisplay / 60;
|
||||||
|
nSeconds = nTimeToDisplay % 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
V_snwprintf( unicode, ARRAYSIZE(unicode), L"%d:%02d", nMinutes, nSeconds );
|
||||||
|
|
||||||
|
vgui::surface()->DrawSetTextPos( xpos, ypos );
|
||||||
|
vgui::surface()->DrawUnicodeString( unicode );
|
||||||
|
|
||||||
|
// draw the overbright blur
|
||||||
|
for (float fl = m_flBlur; fl > 0.0f; fl -= 1.0f)
|
||||||
|
{
|
||||||
|
if (fl >= 1.0f)
|
||||||
|
{
|
||||||
|
vgui::surface()->DrawSetTextPos( xpos, ypos );
|
||||||
|
vgui::surface()->DrawUnicodeString( unicode );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// draw a percentage of the last one
|
||||||
|
Color col = GetFgColor();
|
||||||
|
col[3] *= fl;
|
||||||
|
vgui::surface()->DrawSetTextColor( col );
|
||||||
|
vgui::surface()->DrawSetTextPos( xpos, ypos );
|
||||||
|
vgui::surface()->DrawUnicodeString( unicode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: paints bars at the specified position
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::PaintBars( int xpos, int ypos, int wide )
|
||||||
|
{
|
||||||
|
// get bar chunks
|
||||||
|
int barChunkWidth = (wide / m_nProgressBarMax) - m_flBarChunkGap;
|
||||||
|
|
||||||
|
int enabledChunks;
|
||||||
|
if (m_nProgressBarOverride > -1)
|
||||||
|
enabledChunks = m_nProgressBarOverride;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enabledChunks = (int)floorf( ((float)m_iValue / (float)m_iTimerMaxLength) * (float)m_nProgressBarMax );
|
||||||
|
if (!m_bShowTimeRemaining)
|
||||||
|
{
|
||||||
|
enabledChunks = m_nProgressBarMax - enabledChunks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the suit power bar
|
||||||
|
vgui::surface()->DrawSetColor( GetFgColor() );
|
||||||
|
for (int i = 0; i < enabledChunks; i++)
|
||||||
|
{
|
||||||
|
vgui::surface()->DrawFilledRect( xpos, ypos, xpos + barChunkWidth, ypos + m_flBarHeight );
|
||||||
|
xpos += (barChunkWidth + m_flBarChunkGap);
|
||||||
|
}
|
||||||
|
// draw the exhausted portion of the bar.
|
||||||
|
Color clrExhausted = GetFgColor();
|
||||||
|
clrExhausted[3] = ((float)clrExhausted[3] / 255.0f) * m_iBarDisabledAlpha;
|
||||||
|
vgui::surface()->DrawSetColor( clrExhausted );
|
||||||
|
for (int i = enabledChunks; i < m_nProgressBarMax; i++)
|
||||||
|
{
|
||||||
|
vgui::surface()->DrawFilledRect( xpos, ypos, xpos + barChunkWidth, ypos + m_flBarHeight );
|
||||||
|
xpos += (barChunkWidth + m_flBarChunkGap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: renders the vgui panel
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudGenericGameTimer::Paint()
|
||||||
|
{
|
||||||
|
// Check for 00:00 timer
|
||||||
|
int nTimerWidth = m_nTimerWidth;
|
||||||
|
if (m_iValue > 600)
|
||||||
|
nTimerWidth += vgui::surface()->GetCharacterWidth( m_hNumberFont, '0' );
|
||||||
|
|
||||||
|
// draw the background
|
||||||
|
int wide = max( nTimerWidth, m_nLabelWidth ) + m_flBorder;
|
||||||
|
if (m_flMinWidth > wide)
|
||||||
|
wide = m_flMinWidth;
|
||||||
|
|
||||||
|
int tall = m_nTimerHeight + m_nLabelHeight + (m_flBorder/2);
|
||||||
|
if (m_nProgressBarMax > 0)
|
||||||
|
tall += m_flBarHeight + m_flBarVerticalGap;
|
||||||
|
else
|
||||||
|
tall += (m_flBorder/2);
|
||||||
|
|
||||||
|
int screenW, screenH;
|
||||||
|
GetHudSize( screenW, screenH );
|
||||||
|
|
||||||
|
float flScalarX = (m_flOverrideX != -1.0f ? m_flOverrideX : 0.5f);
|
||||||
|
float flScalarY = (m_flOverrideY != -1.0f ? m_flOverrideY : 0.05f);
|
||||||
|
|
||||||
|
int x = (screenW - wide) * flScalarX;
|
||||||
|
int y = (screenH - tall) * flScalarY;
|
||||||
|
|
||||||
|
DrawBox( x, y, wide, tall, GetBgColor(), 1.0f);
|
||||||
|
|
||||||
|
y += (m_flBorder/2);
|
||||||
|
|
||||||
|
// draw our bars
|
||||||
|
if (m_nProgressBarMax > 0)
|
||||||
|
{
|
||||||
|
int barX = x + (m_flBorder/2);
|
||||||
|
PaintBars( barX, y, wide - m_flBorder );
|
||||||
|
y += m_flBarVerticalGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_nLabelHeight > 0)
|
||||||
|
{
|
||||||
|
vgui::surface()->DrawSetTextFont( m_hTextFont );
|
||||||
|
vgui::surface()->DrawSetTextColor( GetFgColor() );
|
||||||
|
vgui::surface()->DrawSetTextPos( x + ((wide - m_nLabelWidth) * 0.5f), y );
|
||||||
|
vgui::surface()->DrawUnicodeString( m_LabelText );
|
||||||
|
y += m_nLabelHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw our numbers
|
||||||
|
vgui::surface()->DrawSetTextColor( GetFgColor() );
|
||||||
|
|
||||||
|
int digitX = x + ((wide - nTimerWidth) * 0.5f);
|
||||||
|
int digitY = y;
|
||||||
|
PaintNumbers( m_hNumberFont, digitX, digitY );
|
||||||
|
}
|
@ -37,6 +37,9 @@ char g_szPrelocalisedMenuString[MAX_MENU_STRING];
|
|||||||
|
|
||||||
DECLARE_HUDELEMENT( CHudMenu );
|
DECLARE_HUDELEMENT( CHudMenu );
|
||||||
DECLARE_HUD_MESSAGE( CHudMenu, ShowMenu );
|
DECLARE_HUD_MESSAGE( CHudMenu, ShowMenu );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
DECLARE_HUD_MESSAGE( CHudMenu, ShowMenuComplex );
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
@ -71,6 +74,9 @@ CHudMenu::CHudMenu( const char *pElementName ) :
|
|||||||
void CHudMenu::Init( void )
|
void CHudMenu::Init( void )
|
||||||
{
|
{
|
||||||
HOOK_HUD_MESSAGE( CHudMenu, ShowMenu );
|
HOOK_HUD_MESSAGE( CHudMenu, ShowMenu );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
HOOK_HUD_MESSAGE( CHudMenu, ShowMenuComplex );
|
||||||
|
#endif
|
||||||
|
|
||||||
m_bMenuTakesInput = false;
|
m_bMenuTakesInput = false;
|
||||||
m_bMenuDisplayed = false;
|
m_bMenuDisplayed = false;
|
||||||
@ -81,6 +87,24 @@ void CHudMenu::Init( void )
|
|||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudMenu::LevelInit()
|
||||||
|
{
|
||||||
|
CHudElement::LevelInit();
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if (m_bMapDefinedMenu)
|
||||||
|
{
|
||||||
|
// Fixes menu retaining on level change/reload
|
||||||
|
// TODO: Would non-map menus benefit from this as well?
|
||||||
|
m_bMenuTakesInput = false;
|
||||||
|
m_bMenuDisplayed = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose:
|
// Purpose:
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -114,7 +138,11 @@ void CHudMenu::OnThink()
|
|||||||
float flSelectionTimeout = MENU_SELECTION_TIMEOUT;
|
float flSelectionTimeout = MENU_SELECTION_TIMEOUT;
|
||||||
|
|
||||||
// If we've been open for a while without input, hide
|
// If we've been open for a while without input, hide
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( m_bMenuDisplayed && ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout && !m_bMapDefinedMenu ) )
|
||||||
|
#else
|
||||||
if ( m_bMenuDisplayed && ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout ) )
|
if ( m_bMenuDisplayed && ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
m_bMenuDisplayed = false;
|
m_bMenuDisplayed = false;
|
||||||
}
|
}
|
||||||
@ -130,11 +158,24 @@ bool CHudMenu::ShouldDraw( void )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check for if menu is set to disappear
|
// check for if menu is set to disappear
|
||||||
if ( m_flShutoffTime > 0 && m_flShutoffTime <= gpGlobals->realtime )
|
if ( m_flShutoffTime > 0 )
|
||||||
{
|
{
|
||||||
// times up, shutoff
|
#ifdef MAPBASE
|
||||||
m_bMenuDisplayed = false;
|
if ( m_bMapDefinedMenu && !m_bPlayingFadeout && (m_flShutoffTime - m_flOpenCloseTime) <= GetMenuTime() )
|
||||||
return false;
|
{
|
||||||
|
// Begin closing the menu
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MenuClose" );
|
||||||
|
m_bMenuTakesInput = false;
|
||||||
|
m_bPlayingFadeout = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if ( m_flShutoffTime <= GetMenuTime() )
|
||||||
|
{
|
||||||
|
// times up, shutoff
|
||||||
|
m_bMenuDisplayed = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return draw;
|
return draw;
|
||||||
@ -169,23 +210,21 @@ void CHudMenu::Paint()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// center it
|
// center it
|
||||||
int x = 20;
|
int x = m_nBorder;
|
||||||
|
|
||||||
Color menuColor = m_MenuColor;
|
Color menuColor = m_MenuColor;
|
||||||
Color itemColor = m_ItemColor;
|
Color itemColor = m_ItemColor;
|
||||||
|
|
||||||
int c = m_Processed.Count();
|
int c = m_Processed.Count();
|
||||||
|
|
||||||
int border = 20;
|
int wide = m_nMaxPixels + m_nBorder;
|
||||||
|
int tall = m_nHeight + m_nBorder;
|
||||||
int wide = m_nMaxPixels + border;
|
|
||||||
int tall = m_nHeight + border;
|
|
||||||
|
|
||||||
int y = ( ScreenHeight() - tall ) * 0.5f;
|
int y = ( ScreenHeight() - tall ) * 0.5f;
|
||||||
|
|
||||||
DrawBox( x - border/2, y - border/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
DrawBox( x - m_nBorder/2, y - m_nBorder/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
||||||
|
|
||||||
//DrawTexturedBox( x - border/2, y - border/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
//DrawTexturedBox( x - m_nBorder/2, y - m_nBorder/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
||||||
|
|
||||||
menuColor[3] = menuColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
menuColor[3] = menuColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
||||||
itemColor[3] = itemColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
itemColor[3] = itemColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
||||||
@ -195,7 +234,18 @@ void CHudMenu::Paint()
|
|||||||
ProcessedLine *line = &m_Processed[ i ];
|
ProcessedLine *line = &m_Processed[ i ];
|
||||||
Assert( line );
|
Assert( line );
|
||||||
|
|
||||||
Color clr = line->menuitem != 0 ? itemColor : menuColor;
|
#ifdef MAPBASE
|
||||||
|
bool isItem = true;
|
||||||
|
if (line->menuitem == 0 && line->startchar < (MAX_MENU_STRING-1) && g_szMenuString[ line->startchar ] != L'0' && g_szMenuString[ line->startchar+1 ] != L'.')
|
||||||
|
{
|
||||||
|
// Can't use 0 directly because it gets conflated with the cancel item
|
||||||
|
isItem = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool isItem = line->menuitem != 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Color clr = isItem ? itemColor : menuColor;
|
||||||
|
|
||||||
bool canblur = false;
|
bool canblur = false;
|
||||||
if ( line->menuitem != 0 &&
|
if ( line->menuitem != 0 &&
|
||||||
@ -208,15 +258,15 @@ void CHudMenu::Paint()
|
|||||||
vgui::surface()->DrawSetTextColor( clr );
|
vgui::surface()->DrawSetTextColor( clr );
|
||||||
|
|
||||||
int drawLen = line->length;
|
int drawLen = line->length;
|
||||||
if ( line->menuitem != 0 )
|
if (isItem)
|
||||||
{
|
{
|
||||||
drawLen *= m_flTextScan;
|
drawLen *= m_flTextScan;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgui::surface()->DrawSetTextFont( line->menuitem != 0 ? m_hItemFont : m_hTextFont );
|
vgui::surface()->DrawSetTextFont( isItem ? m_hItemFont : m_hTextFont );
|
||||||
|
|
||||||
PaintString( &g_szMenuString[ line->startchar ], drawLen,
|
PaintString( &g_szMenuString[ line->startchar ], drawLen,
|
||||||
line->menuitem != 0 ? m_hItemFont : m_hTextFont, x, y );
|
isItem ? m_hItemFont : m_hTextFont, x, y );
|
||||||
|
|
||||||
if ( canblur )
|
if ( canblur )
|
||||||
{
|
{
|
||||||
@ -242,6 +292,20 @@ void CHudMenu::Paint()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline float CHudMenu::GetMenuTime( void )
|
||||||
|
{
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// In singleplayer, use the curtime instead. This fixes issues with menus disappearing after pausing
|
||||||
|
if (gpGlobals->maxClients <= 1)
|
||||||
|
return gpGlobals->curtime;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return gpGlobals->realtime;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: selects an item from the menu
|
// Purpose: selects an item from the menu
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -260,7 +324,7 @@ void CHudMenu::SelectMenuItem( int menu_item )
|
|||||||
|
|
||||||
// remove the menu quickly
|
// remove the menu quickly
|
||||||
m_bMenuTakesInput = false;
|
m_bMenuTakesInput = false;
|
||||||
m_flShutoffTime = gpGlobals->realtime + m_flOpenCloseTime;
|
m_flShutoffTime = GetMenuTime() + m_flOpenCloseTime;
|
||||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,9 +403,20 @@ void CHudMenu::ProcessText( void )
|
|||||||
{
|
{
|
||||||
ProcessedLine *l = &m_Processed[ i ];
|
ProcessedLine *l = &m_Processed[ i ];
|
||||||
Assert( l );
|
Assert( l );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
bool isItem = true;
|
||||||
|
if (l->menuitem == 0 && l->startchar < (MAX_MENU_STRING-1) && g_szMenuString[ l->startchar ] != L'0' && g_szMenuString[ l->startchar+1 ] != L'.')
|
||||||
|
{
|
||||||
|
// Can't use 0 directly because it gets conflated with the cancel item
|
||||||
|
isItem = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool isItem = l->menuitem != 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
int pixels = 0;
|
int pixels = 0;
|
||||||
vgui::HFont font = l->menuitem != 0 ? m_hItemFont : m_hTextFont;
|
vgui::HFont font = isItem ? m_hItemFont : m_hTextFont;
|
||||||
|
|
||||||
for ( int ch = 0; ch < l->length; ch++ )
|
for ( int ch = 0; ch < l->length; ch++ )
|
||||||
{
|
{
|
||||||
@ -364,7 +439,7 @@ void CHudMenu::ProcessText( void )
|
|||||||
void CHudMenu::HideMenu( void )
|
void CHudMenu::HideMenu( void )
|
||||||
{
|
{
|
||||||
m_bMenuTakesInput = false;
|
m_bMenuTakesInput = false;
|
||||||
m_flShutoffTime = gpGlobals->realtime + m_flOpenCloseTime;
|
m_flShutoffTime = GetMenuTime() + m_flOpenCloseTime;
|
||||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,6 +456,11 @@ void CHudMenu::ShowMenu( const char * menuName, int validSlots )
|
|||||||
m_flShutoffTime = -1;
|
m_flShutoffTime = -1;
|
||||||
m_bitsValidSlots = validSlots;
|
m_bitsValidSlots = validSlots;
|
||||||
m_fWaitingForMore = 0;
|
m_fWaitingForMore = 0;
|
||||||
|
m_nBorder = 20;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
m_bMapDefinedMenu = false;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
Q_strncpy( g_szPrelocalisedMenuString, menuName, sizeof( g_szPrelocalisedMenuString ) );
|
Q_strncpy( g_szPrelocalisedMenuString, menuName, sizeof( g_szPrelocalisedMenuString ) );
|
||||||
|
|
||||||
@ -408,6 +488,11 @@ void CHudMenu::ShowMenu_KeyValueItems( KeyValues *pKV )
|
|||||||
m_flShutoffTime = -1;
|
m_flShutoffTime = -1;
|
||||||
m_fWaitingForMore = 0;
|
m_fWaitingForMore = 0;
|
||||||
m_bitsValidSlots = 0;
|
m_bitsValidSlots = 0;
|
||||||
|
m_nBorder = 20;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
m_bMapDefinedMenu = false;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuOpen");
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuOpen");
|
||||||
m_nSelectedItem = -1;
|
m_nSelectedItem = -1;
|
||||||
@ -426,7 +511,11 @@ void CHudMenu::ShowMenu_KeyValueItems( KeyValues *pKV )
|
|||||||
const char *pszItem = item->GetName();
|
const char *pszItem = item->GetName();
|
||||||
const wchar_t *wLocalizedItem = g_pVGuiLocalize->Find( pszItem );
|
const wchar_t *wLocalizedItem = g_pVGuiLocalize->Find( pszItem );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"->%d. %ls\n", i+1, wLocalizedItem );
|
||||||
|
#else
|
||||||
nCount = _snwprintf( pWritePosition, nRemaining, L"%d. %ls\n", i+1, wLocalizedItem );
|
nCount = _snwprintf( pWritePosition, nRemaining, L"%d. %ls\n", i+1, wLocalizedItem );
|
||||||
|
#endif
|
||||||
nRemaining -= nCount;
|
nRemaining -= nCount;
|
||||||
pWritePosition += nCount;
|
pWritePosition += nCount;
|
||||||
|
|
||||||
@ -436,7 +525,11 @@ void CHudMenu::ShowMenu_KeyValueItems( KeyValues *pKV )
|
|||||||
// put a cancel on the end
|
// put a cancel on the end
|
||||||
m_bitsValidSlots |= (1<<9);
|
m_bitsValidSlots |= (1<<9);
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"->0. %ls\n", g_pVGuiLocalize->Find( "#Cancel" ) );
|
||||||
|
#else
|
||||||
nCount = _snwprintf( pWritePosition, nRemaining, L"0. %ls\n", g_pVGuiLocalize->Find( "#Cancel" ) );
|
nCount = _snwprintf( pWritePosition, nRemaining, L"0. %ls\n", g_pVGuiLocalize->Find( "#Cancel" ) );
|
||||||
|
#endif
|
||||||
nRemaining -= nCount;
|
nRemaining -= nCount;
|
||||||
pWritePosition += nCount;
|
pWritePosition += nCount;
|
||||||
|
|
||||||
@ -465,8 +558,7 @@ void CHudMenu::MsgFunc_ShowMenu( bf_read &msg)
|
|||||||
|
|
||||||
if ( DisplayTime > 0 )
|
if ( DisplayTime > 0 )
|
||||||
{
|
{
|
||||||
m_flShutoffTime = m_flOpenCloseTime + DisplayTime + gpGlobals->realtime;
|
m_flShutoffTime = m_flOpenCloseTime + DisplayTime + GetMenuTime();
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -511,8 +603,131 @@ void CHudMenu::MsgFunc_ShowMenu( bf_read &msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_fWaitingForMore = NeedMore;
|
m_fWaitingForMore = NeedMore;
|
||||||
|
m_nBorder = 20;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
m_bMapDefinedMenu = false;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
ConVar hud_menu_complex_border( "hud_menu_complex_border", "30" );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Message handler for ShowMenu message with more options for game_menu
|
||||||
|
// takes four values:
|
||||||
|
// short : a bitfield of keys that are valid input
|
||||||
|
// float : the duration, in seconds, the menu should stay up. -1 means it stays until something is chosen.
|
||||||
|
// byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, false if it's the last string
|
||||||
|
// string: menu string to display
|
||||||
|
// if this message is never received, then scores will simply be the combined totals of the players.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudMenu::MsgFunc_ShowMenuComplex( bf_read &msg)
|
||||||
|
{
|
||||||
|
m_bitsValidSlots = (short)msg.ReadWord();
|
||||||
|
float DisplayTime = msg.ReadFloat();
|
||||||
|
int NeedMore = msg.ReadByte();
|
||||||
|
|
||||||
|
m_nBorder = hud_menu_complex_border.GetInt();
|
||||||
|
m_bMapDefinedMenu = true;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
|
||||||
|
if ( DisplayTime > 0 )
|
||||||
|
{
|
||||||
|
m_flShutoffTime = m_flOpenCloseTime + DisplayTime + GetMenuTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_flShutoffTime = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_bitsValidSlots > -1 )
|
||||||
|
{
|
||||||
|
char szString[2048];
|
||||||
|
msg.ReadString( szString, sizeof(szString) );
|
||||||
|
|
||||||
|
if ( !m_fWaitingForMore ) // this is the start of a new menu
|
||||||
|
{
|
||||||
|
Q_strncpy( g_szPrelocalisedMenuString, szString, sizeof( g_szPrelocalisedMenuString ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // append to the current menu string
|
||||||
|
Q_strncat( g_szPrelocalisedMenuString, szString, sizeof( g_szPrelocalisedMenuString ), COPY_ALL_CHARACTERS );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !NeedMore )
|
||||||
|
{
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuOpenFlash");
|
||||||
|
m_nSelectedItem = -1;
|
||||||
|
|
||||||
|
// we have the whole string, so we can localise it now
|
||||||
|
wchar_t *pWritePosition = g_szMenuString;
|
||||||
|
int nRemaining = sizeof( g_szMenuString ) / sizeof( wchar_t );
|
||||||
|
int nCount;
|
||||||
|
|
||||||
|
char *pszToken = strtok( szString, "\n" );
|
||||||
|
int nCurItem = 0;
|
||||||
|
for (; pszToken != NULL; pszToken = strtok( NULL, "\n" ), nCurItem++)
|
||||||
|
{
|
||||||
|
if (!*pszToken || *pszToken == ' ')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wchar_t wszMenuItem[128];
|
||||||
|
|
||||||
|
const wchar_t *wLocalizedItem = g_pVGuiLocalize->Find( pszToken );
|
||||||
|
if (wLocalizedItem)
|
||||||
|
{
|
||||||
|
V_wcsncpy( wszMenuItem, wLocalizedItem, sizeof( wszMenuItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszToken, wszMenuItem, sizeof( wszMenuItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCurItem == 0)
|
||||||
|
{
|
||||||
|
// First item is title
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"%ls\n", wszMenuItem );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If this item isn't valid, skip until it is
|
||||||
|
//while (!(m_bitsValidSlots & (1 << nCurItem)) && nCurItem < 10)
|
||||||
|
//{
|
||||||
|
// nCurItem++;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (nCurItem == 10)
|
||||||
|
nCurItem = 0;
|
||||||
|
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"->%d. %ls\n", nCurItem, wszMenuItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
nRemaining -= nCount;
|
||||||
|
pWritePosition += nCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessText();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bMenuDisplayed = true;
|
||||||
|
|
||||||
|
if (m_bitsValidSlots > 0)
|
||||||
|
m_bMenuTakesInput = true;
|
||||||
|
else
|
||||||
|
m_bMenuTakesInput = false;
|
||||||
|
|
||||||
|
m_flSelectionTime = gpGlobals->curtime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HideMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fWaitingForMore = NeedMore;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: hud scheme settings
|
// Purpose: hud scheme settings
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -26,10 +26,14 @@ class CHudMenu : public CHudElement, public vgui::Panel
|
|||||||
public:
|
public:
|
||||||
CHudMenu( const char *pElementName );
|
CHudMenu( const char *pElementName );
|
||||||
void Init( void );
|
void Init( void );
|
||||||
|
void LevelInit( void );
|
||||||
void VidInit( void );
|
void VidInit( void );
|
||||||
void Reset( void );
|
void Reset( void );
|
||||||
virtual bool ShouldDraw( void );
|
virtual bool ShouldDraw( void );
|
||||||
void MsgFunc_ShowMenu( bf_read &msg );
|
void MsgFunc_ShowMenu( bf_read &msg );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
void MsgFunc_ShowMenuComplex( bf_read &msg );
|
||||||
|
#endif
|
||||||
void HideMenu( void );
|
void HideMenu( void );
|
||||||
void ShowMenu( const char * menuName, int keySlot );
|
void ShowMenu( const char * menuName, int keySlot );
|
||||||
void ShowMenu_KeyValueItems( KeyValues *pKV );
|
void ShowMenu_KeyValueItems( KeyValues *pKV );
|
||||||
@ -42,6 +46,8 @@ private:
|
|||||||
virtual void Paint();
|
virtual void Paint();
|
||||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||||
private:
|
private:
|
||||||
|
float GetMenuTime( void );
|
||||||
|
|
||||||
void ProcessText( void );
|
void ProcessText( void );
|
||||||
|
|
||||||
void PaintString( const wchar_t *text, int textlen, vgui::HFont& font, int x, int y );
|
void PaintString( const wchar_t *text, int textlen, vgui::HFont& font, int x, int y );
|
||||||
@ -59,6 +65,7 @@ private:
|
|||||||
|
|
||||||
int m_nMaxPixels;
|
int m_nMaxPixels;
|
||||||
int m_nHeight;
|
int m_nHeight;
|
||||||
|
int m_nBorder;
|
||||||
|
|
||||||
bool m_bMenuDisplayed;
|
bool m_bMenuDisplayed;
|
||||||
int m_bitsValidSlots;
|
int m_bitsValidSlots;
|
||||||
@ -69,6 +76,12 @@ private:
|
|||||||
|
|
||||||
float m_flSelectionTime;
|
float m_flSelectionTime;
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// Indicates this menu is defined by game_menu
|
||||||
|
bool m_bMapDefinedMenu;
|
||||||
|
bool m_bPlayingFadeout;
|
||||||
|
#endif
|
||||||
|
|
||||||
CPanelAnimationVar( float, m_flOpenCloseTime, "OpenCloseTime", "1" );
|
CPanelAnimationVar( float, m_flOpenCloseTime, "OpenCloseTime", "1" );
|
||||||
|
|
||||||
CPanelAnimationVar( float, m_flBlur, "Blur", "0" );
|
CPanelAnimationVar( float, m_flBlur, "Blur", "0" );
|
||||||
|
@ -45,7 +45,7 @@ extern IScriptManager *scriptmanager;
|
|||||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
extern int vscript_debugger_port;
|
ConVar script_connect_debugger_on_mapspawn_client( "script_connect_debugger_on_mapspawn_client", "0" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #define VMPROFILE 1
|
// #define VMPROFILE 1
|
||||||
@ -765,10 +765,13 @@ bool VScriptClientInit()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
if ( vscript_debugger_port )
|
if ( script_connect_debugger_on_mapspawn_client.GetInt() == 2 )
|
||||||
|
{
|
||||||
|
g_pScriptVM->ConnectDebugger( vscript_debugger_port, 10.0f );
|
||||||
|
}
|
||||||
|
else if ( script_connect_debugger_on_mapspawn_client.GetInt() != 0 )
|
||||||
{
|
{
|
||||||
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
||||||
vscript_debugger_port = 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3045,7 +3045,7 @@ void CAI_BaseNPC::SetHeadDirection( const Vector &vTargetPos, float flInterval)
|
|||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
// Set head yaw
|
// Set head yaw
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
float flDesiredYaw = VecToYaw(vTargetPos - GetLocalOrigin()) - GetLocalAngles().y;
|
float flDesiredYaw = VecToYaw(vTargetPos - GetAbsOrigin()) - GetAbsAngles().y;
|
||||||
if (flDesiredYaw > 180)
|
if (flDesiredYaw > 180)
|
||||||
flDesiredYaw -= 360;
|
flDesiredYaw -= 360;
|
||||||
if (flDesiredYaw < -180)
|
if (flDesiredYaw < -180)
|
||||||
@ -8005,7 +8005,7 @@ void CAI_BaseNPC::NPCInit ( void )
|
|||||||
|
|
||||||
SetGravity(1.0); // Don't change
|
SetGravity(1.0); // Don't change
|
||||||
m_takedamage = DAMAGE_YES;
|
m_takedamage = DAMAGE_YES;
|
||||||
GetMotor()->SetIdealYaw( GetLocalAngles().y );
|
GetMotor()->SetIdealYaw( GetAbsAngles().y );
|
||||||
m_iMaxHealth = m_iHealth;
|
m_iMaxHealth = m_iHealth;
|
||||||
m_lifeState = LIFE_ALIVE;
|
m_lifeState = LIFE_ALIVE;
|
||||||
SetIdealState( NPC_STATE_IDLE );// Assume npc will be idle, until proven otherwise
|
SetIdealState( NPC_STATE_IDLE );// Assume npc will be idle, until proven otherwise
|
||||||
@ -9657,7 +9657,7 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget )
|
|||||||
vecProjection.y = vecTarget.x;
|
vecProjection.y = vecTarget.x;
|
||||||
vecProjection.z = 0;
|
vecProjection.z = 0;
|
||||||
|
|
||||||
return UTIL_VecToYaw( vecProjection - GetLocalOrigin() );
|
return UTIL_VecToYaw( vecProjection - GetAbsOrigin() );
|
||||||
}
|
}
|
||||||
else if ( GetNavigator()->GetMovementActivity() == ACT_STRAFE_RIGHT )
|
else if ( GetNavigator()->GetMovementActivity() == ACT_STRAFE_RIGHT )
|
||||||
{
|
{
|
||||||
@ -9665,7 +9665,7 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget )
|
|||||||
vecProjection.y = vecTarget.x;
|
vecProjection.y = vecTarget.x;
|
||||||
vecProjection.z = 0;
|
vecProjection.z = 0;
|
||||||
|
|
||||||
return UTIL_VecToYaw( vecProjection - GetLocalOrigin() );
|
return UTIL_VecToYaw( vecProjection - GetAbsOrigin() );
|
||||||
}
|
}
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
// Allow hint nodes to override the yaw without needing to control AI
|
// Allow hint nodes to override the yaw without needing to control AI
|
||||||
@ -9676,7 +9676,7 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget )
|
|||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return UTIL_VecToYaw ( vecTarget - GetLocalOrigin() );
|
return UTIL_VecToYaw ( vecTarget - GetAbsOrigin() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9876,7 +9876,7 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent )
|
|||||||
//DevMsg( "Turned!\n" );
|
//DevMsg( "Turned!\n" );
|
||||||
SetIdealActivity( ACT_IDLE );
|
SetIdealActivity( ACT_IDLE );
|
||||||
Forget( bits_MEMORY_TURNING );
|
Forget( bits_MEMORY_TURNING );
|
||||||
SetBoneController( 0, GetLocalAngles().y );
|
SetBoneController( 0, GetAbsAngles().y );
|
||||||
IncrementInterpolationFrame();
|
IncrementInterpolationFrame();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -11155,7 +11155,7 @@ Vector CAI_BaseNPC::GetShootEnemyDir( const Vector &shootOrigin, bool bNoisy )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector forward;
|
Vector forward;
|
||||||
AngleVectors( GetLocalAngles(), &forward );
|
AngleVectors( GetAbsAngles(), &forward );
|
||||||
return forward;
|
return forward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14193,7 +14193,7 @@ bool CAI_BaseNPC::OverrideMove( float flInterval )
|
|||||||
float CAI_BaseNPC::VecToYaw( const Vector &vecDir )
|
float CAI_BaseNPC::VecToYaw( const Vector &vecDir )
|
||||||
{
|
{
|
||||||
if (vecDir.x == 0 && vecDir.y == 0 && vecDir.z == 0)
|
if (vecDir.x == 0 && vecDir.y == 0 && vecDir.z == 0)
|
||||||
return GetLocalAngles().y;
|
return GetAbsAngles().y;
|
||||||
|
|
||||||
return UTIL_VecToYaw( vecDir );
|
return UTIL_VecToYaw( vecDir );
|
||||||
}
|
}
|
||||||
|
@ -1180,6 +1180,11 @@ public:
|
|||||||
|
|
||||||
void SetDeathPose( const int &iDeathPose ) { m_iDeathPose = iDeathPose; }
|
void SetDeathPose( const int &iDeathPose ) { m_iDeathPose = iDeathPose; }
|
||||||
void SetDeathPoseFrame( const int &iDeathPoseFrame ) { m_iDeathFrame = iDeathPoseFrame; }
|
void SetDeathPoseFrame( const int &iDeathPoseFrame ) { m_iDeathFrame = iDeathPoseFrame; }
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
int GetDeathPose() { return m_iDeathPose; }
|
||||||
|
int GetDeathPoseFrame() { return m_iDeathFrame; }
|
||||||
|
#endif
|
||||||
|
|
||||||
void SelectDeathPose( const CTakeDamageInfo &info );
|
void SelectDeathPose( const CTakeDamageInfo &info );
|
||||||
virtual bool ShouldPickADeathPose( void ) { return true; }
|
virtual bool ShouldPickADeathPose( void ) { return true; }
|
||||||
|
@ -964,7 +964,7 @@ void CAI_BaseNPC::StartTurn( float flDeltaYaw )
|
|||||||
{
|
{
|
||||||
float flCurrentYaw;
|
float flCurrentYaw;
|
||||||
|
|
||||||
flCurrentYaw = UTIL_AngleMod( GetLocalAngles().y );
|
flCurrentYaw = UTIL_AngleMod( GetAbsAngles().y );
|
||||||
GetMotor()->SetIdealYaw( UTIL_AngleMod( flCurrentYaw + flDeltaYaw ) );
|
GetMotor()->SetIdealYaw( UTIL_AngleMod( flCurrentYaw + flDeltaYaw ) );
|
||||||
SetTurnActivity();
|
SetTurnActivity();
|
||||||
}
|
}
|
||||||
@ -1157,7 +1157,7 @@ void CAI_BaseNPC::StartScriptMoveToTargetTask( int task )
|
|||||||
{
|
{
|
||||||
TaskFail(FAIL_NO_TARGET);
|
TaskFail(FAIL_NO_TARGET);
|
||||||
}
|
}
|
||||||
else if ( (m_hTargetEnt->GetAbsOrigin() - GetLocalOrigin()).Length() < 1 )
|
else if ( (m_hTargetEnt->GetAbsOrigin() - GetAbsOrigin()).Length() < 1 )
|
||||||
{
|
{
|
||||||
TaskComplete();
|
TaskComplete();
|
||||||
}
|
}
|
||||||
@ -1622,7 +1622,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TASK_SET_IDEAL_YAW_TO_CURRENT:
|
case TASK_SET_IDEAL_YAW_TO_CURRENT:
|
||||||
GetMotor()->SetIdealYaw( UTIL_AngleMod( GetLocalAngles().y ) );
|
GetMotor()->SetIdealYaw( UTIL_AngleMod( GetAbsAngles().y ) );
|
||||||
TaskComplete();
|
TaskComplete();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1776,7 +1776,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask )
|
|||||||
{
|
{
|
||||||
TaskFail(FAIL_NO_TARGET);
|
TaskFail(FAIL_NO_TARGET);
|
||||||
}
|
}
|
||||||
else if ( (pTarget->GetAbsOrigin() - GetLocalOrigin()).Length() < 1 )
|
else if ( (pTarget->GetAbsOrigin() - GetAbsOrigin()).Length() < 1 )
|
||||||
{
|
{
|
||||||
TaskComplete();
|
TaskComplete();
|
||||||
}
|
}
|
||||||
@ -3021,7 +3021,7 @@ void CAI_BaseNPC::StartTask( const Task_t *pTask )
|
|||||||
{
|
{
|
||||||
if ( m_hTargetEnt != NULL )
|
if ( m_hTargetEnt != NULL )
|
||||||
{
|
{
|
||||||
GetMotor()->SetIdealYaw( UTIL_AngleMod( m_hTargetEnt->GetLocalAngles().y ) );
|
GetMotor()->SetIdealYaw( UTIL_AngleMod( m_hTargetEnt->GetAbsAngles().y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_scriptState != SCRIPT_CUSTOM_MOVE_TO_MARK )
|
if ( m_scriptState != SCRIPT_CUSTOM_MOVE_TO_MARK )
|
||||||
@ -3350,7 +3350,7 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask )
|
|||||||
pTarget = GetEnemy();
|
pTarget = GetEnemy();
|
||||||
if ( pTarget )
|
if ( pTarget )
|
||||||
{
|
{
|
||||||
GetMotor()->SetIdealYawAndUpdate( pTarget->GetAbsOrigin() - GetLocalOrigin() , AI_KEEP_YAW_SPEED );
|
GetMotor()->SetIdealYawAndUpdate( pTarget->GetAbsOrigin() - GetAbsOrigin(), AI_KEEP_YAW_SPEED );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( IsActivityFinished() )
|
if ( IsActivityFinished() )
|
||||||
|
@ -1624,6 +1624,9 @@ void CHL2_Player::Spawn(void)
|
|||||||
|
|
||||||
if (m_iszProtagonistName == NULL_STRING && *g_szDefaultProtagonist)
|
if (m_iszProtagonistName == NULL_STRING && *g_szDefaultProtagonist)
|
||||||
m_iszProtagonistName = MAKE_STRING( g_szDefaultProtagonist );
|
m_iszProtagonistName = MAKE_STRING( g_szDefaultProtagonist );
|
||||||
|
|
||||||
|
if (m_iszProtagonistName != NULL_STRING)
|
||||||
|
SetProtagonist( STRING( m_iszProtagonistName ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -256,7 +256,7 @@ END_DATADESC()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CNPC_PoisonZombie::Precache( void )
|
void CNPC_PoisonZombie::Precache( void )
|
||||||
{
|
{
|
||||||
PrecacheModel("models/zombie/poison.mdl");
|
PrecacheModel( DefaultOrCustomModel( "models/zombie/poison.mdl" ) );
|
||||||
|
|
||||||
PrecacheScriptSound( "NPC_PoisonZombie.Die" );
|
PrecacheScriptSound( "NPC_PoisonZombie.Die" );
|
||||||
PrecacheScriptSound( "NPC_PoisonZombie.ThrowWarn" );
|
PrecacheScriptSound( "NPC_PoisonZombie.ThrowWarn" );
|
||||||
@ -509,7 +509,7 @@ void CNPC_PoisonZombie::SetZombieModel( void )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetModel( "models/zombie/poison.mdl" );
|
SetModel( DefaultOrCustomModel( "models/zombie/poison.mdl" ) );
|
||||||
SetHullType(HULL_HUMAN);
|
SetHullType(HULL_HUMAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,8 +472,8 @@ void CNPC_Antlion::Precache( void )
|
|||||||
#ifdef HL2_EPISODIC
|
#ifdef HL2_EPISODIC
|
||||||
if ( IsWorker() )
|
if ( IsWorker() )
|
||||||
{
|
{
|
||||||
PrecacheModel( ANTLION_WORKER_MODEL );
|
PrecacheModel( DefaultOrCustomModel( ANTLION_WORKER_MODEL ) );
|
||||||
PropBreakablePrecacheAll( MAKE_STRING( ANTLION_WORKER_MODEL ) );
|
PropBreakablePrecacheAll( MAKE_STRING( DefaultOrCustomModel( ANTLION_WORKER_MODEL ) ) );
|
||||||
UTIL_PrecacheOther( "grenade_spit" );
|
UTIL_PrecacheOther( "grenade_spit" );
|
||||||
PrecacheParticleSystem( "blood_impact_antlion_worker_01" );
|
PrecacheParticleSystem( "blood_impact_antlion_worker_01" );
|
||||||
PrecacheParticleSystem( "antlion_gib_02" );
|
PrecacheParticleSystem( "antlion_gib_02" );
|
||||||
@ -482,8 +482,8 @@ void CNPC_Antlion::Precache( void )
|
|||||||
else
|
else
|
||||||
#endif // HL2_EPISODIC
|
#endif // HL2_EPISODIC
|
||||||
{
|
{
|
||||||
PrecacheModel( ANTLION_MODEL );
|
PrecacheModel( DefaultOrCustomModel( ANTLION_MODEL ) );
|
||||||
PropBreakablePrecacheAll( MAKE_STRING( ANTLION_MODEL ) );
|
PropBreakablePrecacheAll( MAKE_STRING( DefaultOrCustomModel( ANTLION_MODEL ) ) );
|
||||||
PrecacheParticleSystem( "blood_impact_antlion_01" );
|
PrecacheParticleSystem( "blood_impact_antlion_01" );
|
||||||
PrecacheParticleSystem( "AntlionGib" );
|
PrecacheParticleSystem( "AntlionGib" );
|
||||||
}
|
}
|
||||||
|
@ -4055,9 +4055,12 @@ void CNPC_AttackHelicopter::Event_Killed( const CTakeDamageInfo &info )
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_lifeState = LIFE_DYING;
|
m_lifeState = LIFE_DYING;
|
||||||
|
|
||||||
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
|
if ( GetSleepState() != AISS_WAITING_FOR_INPUT )
|
||||||
controller.SoundChangeVolume( m_pGunFiringSound, 0.0, 0.1f );
|
{
|
||||||
|
CSoundEnvelopeController& controller = CSoundEnvelopeController::GetController();
|
||||||
|
controller.SoundChangeVolume( m_pGunFiringSound, 0.0, 0.1f );
|
||||||
|
}
|
||||||
|
|
||||||
if( GetCrashPoint() == NULL )
|
if( GetCrashPoint() == NULL )
|
||||||
{
|
{
|
||||||
|
@ -839,6 +839,9 @@ void CNPC_Citizen::SelectModel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Models selected this way must be unique to avoid conflicts in save/restore
|
||||||
|
m_Type = CT_UNIQUE;
|
||||||
|
|
||||||
// Just set the model right here
|
// Just set the model right here
|
||||||
SetModelName( AllocPooledString( returnValue.m_pszString ) );
|
SetModelName( AllocPooledString( returnValue.m_pszString ) );
|
||||||
return;
|
return;
|
||||||
|
@ -275,7 +275,7 @@ CNPC_CombineCamera::~CNPC_CombineCamera()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CNPC_CombineCamera::Precache()
|
void CNPC_CombineCamera::Precache()
|
||||||
{
|
{
|
||||||
PrecacheModel(COMBINE_CAMERA_MODEL);
|
PrecacheModel( DefaultOrCustomModel( COMBINE_CAMERA_MODEL ) );
|
||||||
PrecacheModel(COMBINE_CAMERA_GLOW_SPRITE);
|
PrecacheModel(COMBINE_CAMERA_GLOW_SPRITE);
|
||||||
PrecacheModel(COMBINE_CAMERA_FLASH_SPRITE);
|
PrecacheModel(COMBINE_CAMERA_FLASH_SPRITE);
|
||||||
|
|
||||||
@ -304,8 +304,7 @@ void CNPC_CombineCamera::Precache()
|
|||||||
void CNPC_CombineCamera::Spawn()
|
void CNPC_CombineCamera::Spawn()
|
||||||
{
|
{
|
||||||
Precache();
|
Precache();
|
||||||
|
SetModel( DefaultOrCustomModel( COMBINE_CAMERA_MODEL ) );
|
||||||
SetModel(COMBINE_CAMERA_MODEL);
|
|
||||||
|
|
||||||
m_pEyeFlash = CSprite::SpriteCreate(COMBINE_CAMERA_FLASH_SPRITE, GetLocalOrigin(), FALSE);
|
m_pEyeFlash = CSprite::SpriteCreate(COMBINE_CAMERA_FLASH_SPRITE, GetLocalOrigin(), FALSE);
|
||||||
m_pEyeFlash->SetTransparency(kRenderGlow, 255, 255, 255, 0, kRenderFxNoDissipation);
|
m_pEyeFlash->SetTransparency(kRenderGlow, 255, 255, 255, 0, kRenderFxNoDissipation);
|
||||||
|
@ -1110,7 +1110,7 @@ void CNPC_CombineDropship::Spawn( void )
|
|||||||
|
|
||||||
// moving this after we've created m_hContainer so we can properly setup the
|
// moving this after we've created m_hContainer so we can properly setup the
|
||||||
// weapon_pitch and weapon_yaw pose parameter indexes in PopulatePoseParameters()
|
// weapon_pitch and weapon_yaw pose parameter indexes in PopulatePoseParameters()
|
||||||
SetModel( "models/combine_dropship.mdl" );
|
SetModel( DefaultOrCustomModel( "models/combine_dropship.mdl" ) );
|
||||||
|
|
||||||
// Setup our bbox
|
// Setup our bbox
|
||||||
if ( m_hContainer )
|
if ( m_hContainer )
|
||||||
@ -1191,7 +1191,7 @@ void CNPC_CombineDropship::Activate( void )
|
|||||||
void CNPC_CombineDropship::Precache( void )
|
void CNPC_CombineDropship::Precache( void )
|
||||||
{
|
{
|
||||||
// Models
|
// Models
|
||||||
PrecacheModel("models/combine_dropship.mdl");
|
PrecacheModel( DefaultOrCustomModel( "models/combine_dropship.mdl" ) );
|
||||||
switch ( m_iCrateType )
|
switch ( m_iCrateType )
|
||||||
{
|
{
|
||||||
case CRATE_SOLDIER:
|
case CRATE_SOLDIER:
|
||||||
|
@ -564,11 +564,11 @@ void CNPC_CombineGunship::Spawn( void )
|
|||||||
|
|
||||||
if ( HasSpawnFlags( SF_GUNSHIP_USE_CHOPPER_MODEL ) )
|
if ( HasSpawnFlags( SF_GUNSHIP_USE_CHOPPER_MODEL ) )
|
||||||
{
|
{
|
||||||
SetModel( "models/combine_helicopter.mdl" );
|
SetModel( DefaultOrCustomModel( "models/combine_helicopter.mdl" ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetModel( "models/gunship.mdl" );
|
SetModel( DefaultOrCustomModel( "models/gunship.mdl" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtractBbox( SelectHeaviestSequence( ACT_GUNSHIP_PATROL ), m_cullBoxMins, m_cullBoxMaxs );
|
ExtractBbox( SelectHeaviestSequence( ACT_GUNSHIP_PATROL ), m_cullBoxMins, m_cullBoxMaxs );
|
||||||
@ -690,12 +690,12 @@ void CNPC_CombineGunship::Precache( void )
|
|||||||
{
|
{
|
||||||
if ( HasSpawnFlags( SF_GUNSHIP_USE_CHOPPER_MODEL ) )
|
if ( HasSpawnFlags( SF_GUNSHIP_USE_CHOPPER_MODEL ) )
|
||||||
{
|
{
|
||||||
PrecacheModel( "models/combine_helicopter.mdl" );
|
PrecacheModel( DefaultOrCustomModel( "models/combine_helicopter.mdl" ) );
|
||||||
Chopper_PrecacheChunks( this );
|
Chopper_PrecacheChunks( this );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrecacheModel("models/gunship.mdl");
|
PrecacheModel( DefaultOrCustomModel( "models/gunship.mdl" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
PrecacheModel("sprites/lgtning.vmt");
|
PrecacheModel("sprites/lgtning.vmt");
|
||||||
@ -725,7 +725,7 @@ void CNPC_CombineGunship::Precache( void )
|
|||||||
g_iGunshipEffectIndex = PrecacheModel( "sprites/physbeam.vmt" );
|
g_iGunshipEffectIndex = PrecacheModel( "sprites/physbeam.vmt" );
|
||||||
}
|
}
|
||||||
|
|
||||||
PropBreakablePrecacheAll( MAKE_STRING("models/gunship.mdl") );
|
PropBreakablePrecacheAll( MAKE_STRING( DefaultOrCustomModel( "models/gunship.mdl" ) ) );
|
||||||
|
|
||||||
BaseClass::Precache();
|
BaseClass::Precache();
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,11 @@ ConVar sk_combine_guard_kick( "sk_combine_guard_kick", "0");
|
|||||||
ConVar combine_guard_spawn_health( "combine_guard_spawn_health", "1" );
|
ConVar combine_guard_spawn_health( "combine_guard_spawn_health", "1" );
|
||||||
|
|
||||||
extern ConVar sk_plr_dmg_buckshot;
|
extern ConVar sk_plr_dmg_buckshot;
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
ConVar sk_combine_head_dmg_multiplier( "sk_combine_head_dmg_multiplier", "2" );
|
||||||
|
#endif
|
||||||
|
|
||||||
extern ConVar sk_plr_num_shotgun_pellets;
|
extern ConVar sk_plr_num_shotgun_pellets;
|
||||||
|
|
||||||
//Whether or not the combine should spawn health on death
|
//Whether or not the combine should spawn health on death
|
||||||
@ -222,8 +227,14 @@ float CNPC_CombineS::GetHitgroupDamageMultiplier( int iHitGroup, const CTakeDama
|
|||||||
{
|
{
|
||||||
case HITGROUP_HEAD:
|
case HITGROUP_HEAD:
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// Now you can change the multiplier of headshot damage in console!
|
||||||
|
return sk_combine_head_dmg_multiplier.GetFloat();
|
||||||
|
#else
|
||||||
// Soldiers take double headshot damage
|
// Soldiers take double headshot damage
|
||||||
return 2.0f;
|
return 2.0f;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ void CNPC_Dog::Spawn( void )
|
|||||||
|
|
||||||
BaseClass::Spawn();
|
BaseClass::Spawn();
|
||||||
|
|
||||||
SetModel( "models/dog.mdl" );
|
SetModel( DefaultOrCustomModel( "models/dog.mdl" ) );
|
||||||
|
|
||||||
SetHullType( HULL_WIDE_HUMAN );
|
SetHullType( HULL_WIDE_HUMAN );
|
||||||
SetHullSizeNormal();
|
SetHullSizeNormal();
|
||||||
@ -638,7 +638,7 @@ void CNPC_Dog::PullObject( bool bMantain )
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CNPC_Dog::Precache( void )
|
void CNPC_Dog::Precache( void )
|
||||||
{
|
{
|
||||||
PrecacheModel( "models/dog.mdl" );
|
PrecacheModel( DefaultOrCustomModel( "models/dog.mdl" ) );
|
||||||
|
|
||||||
PrecacheScriptSound( "Weapon_PhysCannon.Launch" );
|
PrecacheScriptSound( "Weapon_PhysCannon.Launch" );
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ static const char *s_pLegsModel = "models/gibs/fast_zombie_legs.mdl";
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CFastZombie::Precache( void )
|
void CFastZombie::Precache( void )
|
||||||
{
|
{
|
||||||
PrecacheModel("models/zombie/fast.mdl");
|
PrecacheModel( DefaultOrCustomModel( "models/zombie/fast.mdl" ) );
|
||||||
#ifdef HL2_EPISODIC
|
#ifdef HL2_EPISODIC
|
||||||
PrecacheModel("models/zombie/Fast_torso.mdl");
|
PrecacheModel("models/zombie/Fast_torso.mdl");
|
||||||
PrecacheScriptSound( "NPC_FastZombie.CarEnter1" );
|
PrecacheScriptSound( "NPC_FastZombie.CarEnter1" );
|
||||||
@ -773,7 +773,7 @@ void CFastZombie::SetZombieModel( void )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetModel( "models/zombie/fast.mdl" );
|
SetModel( DefaultOrCustomModel( "models/zombie/fast.mdl" ) );
|
||||||
SetHullType(HULL_HUMAN);
|
SetHullType(HULL_HUMAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ END_DATADESC()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CNPC_Fisherman::SelectModel()
|
void CNPC_Fisherman::SelectModel()
|
||||||
{
|
{
|
||||||
SetModelName( AllocPooledString( FISHERMAN_MODEL ) );
|
SetModelName( AllocPooledString( DefaultOrCustomModel( FISHERMAN_MODEL ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -97,7 +97,7 @@ void CNPC_GMan::Spawn()
|
|||||||
|
|
||||||
BaseClass::Spawn();
|
BaseClass::Spawn();
|
||||||
|
|
||||||
SetModel( "models/gman.mdl" );
|
SetModel( DefaultOrCustomModel( "models/gman.mdl" ) );
|
||||||
|
|
||||||
SetHullType(HULL_HUMAN);
|
SetHullType(HULL_HUMAN);
|
||||||
SetHullSizeNormal();
|
SetHullSizeNormal();
|
||||||
@ -123,7 +123,7 @@ void CNPC_GMan::Spawn()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CNPC_GMan::Precache()
|
void CNPC_GMan::Precache()
|
||||||
{
|
{
|
||||||
PrecacheModel( "models/gman.mdl" );
|
PrecacheModel( DefaultOrCustomModel( "models/gman.mdl" ) );
|
||||||
|
|
||||||
BaseClass::Precache();
|
BaseClass::Precache();
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ Activity CNPC_Monk::NPC_TranslateActivity( Activity eNewActivity )
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CNPC_Monk::Precache()
|
void CNPC_Monk::Precache()
|
||||||
{
|
{
|
||||||
PrecacheModel( "models/Monk.mdl" );
|
PrecacheModel( DefaultOrCustomModel( "models/Monk.mdl" ) );
|
||||||
|
|
||||||
PrecacheScriptSound( "NPC_Citizen.FootstepLeft" );
|
PrecacheScriptSound( "NPC_Citizen.FootstepLeft" );
|
||||||
PrecacheScriptSound( "NPC_Citizen.FootstepRight" );
|
PrecacheScriptSound( "NPC_Citizen.FootstepRight" );
|
||||||
@ -317,7 +317,7 @@ void CNPC_Monk::Spawn()
|
|||||||
|
|
||||||
BaseClass::Spawn();
|
BaseClass::Spawn();
|
||||||
|
|
||||||
SetModel( "models/Monk.mdl" );
|
SetModel( DefaultOrCustomModel( "models/Monk.mdl" ) );
|
||||||
|
|
||||||
SetHullType(HULL_HUMAN);
|
SetHullType(HULL_HUMAN);
|
||||||
SetHullSizeNormal();
|
SetHullSizeNormal();
|
||||||
|
@ -99,7 +99,7 @@ void CNPC_Mossman::Spawn()
|
|||||||
|
|
||||||
BaseClass::Spawn();
|
BaseClass::Spawn();
|
||||||
|
|
||||||
SetModel( "models/mossman.mdl" );
|
SetModel( DefaultOrCustomModel( "models/mossman.mdl" ) );
|
||||||
|
|
||||||
SetHullType(HULL_HUMAN);
|
SetHullType(HULL_HUMAN);
|
||||||
SetHullSizeNormal();
|
SetHullSizeNormal();
|
||||||
@ -124,7 +124,7 @@ void CNPC_Mossman::Spawn()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CNPC_Mossman::Precache()
|
void CNPC_Mossman::Precache()
|
||||||
{
|
{
|
||||||
PrecacheModel( "models/mossman.mdl" );
|
PrecacheModel( DefaultOrCustomModel( "models/mossman.mdl" ) );
|
||||||
|
|
||||||
BaseClass::Precache();
|
BaseClass::Precache();
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ void CZombie::Precache( void )
|
|||||||
{
|
{
|
||||||
BaseClass::Precache();
|
BaseClass::Precache();
|
||||||
|
|
||||||
PrecacheModel( "models/zombie/classic.mdl" );
|
PrecacheModel( DefaultOrCustomModel( "models/zombie/classic.mdl" ) );
|
||||||
PrecacheModel( "models/zombie/classic_torso.mdl" );
|
PrecacheModel( "models/zombie/classic_torso.mdl" );
|
||||||
PrecacheModel( "models/zombie/classic_legs.mdl" );
|
PrecacheModel( "models/zombie/classic_legs.mdl" );
|
||||||
|
|
||||||
@ -515,7 +515,7 @@ void CZombie::SetZombieModel( void )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetModel( "models/zombie/classic.mdl" );
|
SetModel( DefaultOrCustomModel( "models/zombie/classic.mdl" ) );
|
||||||
SetHullType( HULL_HUMAN );
|
SetHullType( HULL_HUMAN );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ void CNPC_Zombine::Precache( void )
|
|||||||
{
|
{
|
||||||
BaseClass::Precache();
|
BaseClass::Precache();
|
||||||
|
|
||||||
PrecacheModel( "models/zombie/zombie_soldier.mdl" );
|
PrecacheModel( DefaultOrCustomModel( "models/zombie/zombie_soldier.mdl" ) );
|
||||||
|
|
||||||
PrecacheScriptSound( "Zombie.FootstepRight" );
|
PrecacheScriptSound( "Zombie.FootstepRight" );
|
||||||
PrecacheScriptSound( "Zombie.FootstepLeft" );
|
PrecacheScriptSound( "Zombie.FootstepLeft" );
|
||||||
@ -270,7 +270,7 @@ void CNPC_Zombine::Precache( void )
|
|||||||
|
|
||||||
void CNPC_Zombine::SetZombieModel( void )
|
void CNPC_Zombine::SetZombieModel( void )
|
||||||
{
|
{
|
||||||
SetModel( "models/zombie/zombie_soldier.mdl" );
|
SetModel( DefaultOrCustomModel( "models/zombie/zombie_soldier.mdl" ) );
|
||||||
SetHullType( HULL_HUMAN );
|
SetHullType( HULL_HUMAN );
|
||||||
|
|
||||||
SetBodygroup( ZOMBIE_BODYGROUP_HEADCRAB, !m_fIsHeadless );
|
SetBodygroup( ZOMBIE_BODYGROUP_HEADCRAB, !m_fIsHeadless );
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "entityoutput.h"
|
#include "entityoutput.h"
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
#include "eventqueue.h"
|
#include "eventqueue.h"
|
||||||
|
#include "saverestore_utlvector.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// memdbgon must be the last include file in a .cpp file!!!
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
@ -824,3 +825,449 @@ void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Displays a custom number menu for player(s)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
LINK_ENTITY_TO_CLASS( game_menu, CGameMenu );
|
||||||
|
|
||||||
|
BEGIN_DATADESC( CGameMenu )
|
||||||
|
|
||||||
|
DEFINE_UTLVECTOR( m_ActivePlayers, FIELD_EHANDLE ),
|
||||||
|
DEFINE_UTLVECTOR( m_ActivePlayerTimes, FIELD_TIME ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_flDisplayTime, FIELD_FLOAT, "holdtime" ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_iszTitle, FIELD_STRING, "Title" ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[0], FIELD_STRING, "Case01" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[1], FIELD_STRING, "Case02" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[2], FIELD_STRING, "Case03" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[3], FIELD_STRING, "Case04" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[4], FIELD_STRING, "Case05" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[5], FIELD_STRING, "Case06" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[6], FIELD_STRING, "Case07" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[7], FIELD_STRING, "Case08" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[8], FIELD_STRING, "Case09" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[9], FIELD_STRING, "Case10" ),
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "ShowMenu", InputShowMenu ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "HideMenu", InputHideMenu ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "__DoRestore", InputDoRestore ),
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
DEFINE_OUTPUT( m_OnCase[0], "OnCase01" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[1], "OnCase02" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[2], "OnCase03" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[3], "OnCase04" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[4], "OnCase05" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[5], "OnCase06" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[6], "OnCase07" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[7], "OnCase08" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[8], "OnCase09" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[9], "OnCase10" ),
|
||||||
|
DEFINE_OUTPUT( m_OutValue, "OutValue" ),
|
||||||
|
DEFINE_OUTPUT( m_OnTimeout, "OnTimeout" ),
|
||||||
|
|
||||||
|
DEFINE_THINKFUNC( TimeoutThink ),
|
||||||
|
|
||||||
|
END_DATADESC()
|
||||||
|
|
||||||
|
IMPLEMENT_AUTO_LIST( IGameMenuAutoList );
|
||||||
|
|
||||||
|
static const char *s_pTimeoutContext = "TimeoutContext";
|
||||||
|
|
||||||
|
#define MENU_INFINITE_TIME -1.0f
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CGameMenu::CGameMenu()
|
||||||
|
{
|
||||||
|
m_flDisplayTime = 5.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::OnRestore()
|
||||||
|
{
|
||||||
|
BaseClass::OnRestore();
|
||||||
|
|
||||||
|
// Do this a bit after we restore since the HUD might not be ready yet
|
||||||
|
g_EventQueue.AddEvent( this, "__DoRestore", 0.4f, this, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::InputDoRestore( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
// Check if we should restore the menu on anyone
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get())
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
filter.AddRecipient( static_cast<CBasePlayer*>( m_ActivePlayers[i].Get() ) );
|
||||||
|
|
||||||
|
ShowMenu( filter, m_ActivePlayerTimes[i] - gpGlobals->curtime );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::TimeoutThink()
|
||||||
|
{
|
||||||
|
float flNextLowestTime = FLT_MAX;
|
||||||
|
FOR_EACH_VEC( m_ActivePlayerTimes, i )
|
||||||
|
{
|
||||||
|
// If the player is still in our list, then they must not have selected an option
|
||||||
|
if (m_ActivePlayerTimes[i] != MENU_INFINITE_TIME)
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] <= gpGlobals->curtime)
|
||||||
|
{
|
||||||
|
m_OnTimeout.FireOutput( m_ActivePlayers[i], this );
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (m_ActivePlayerTimes[i] < flNextLowestTime)
|
||||||
|
{
|
||||||
|
flNextLowestTime = m_ActivePlayerTimes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flNextLowestTime < FLT_MAX)
|
||||||
|
{
|
||||||
|
SetNextThink( flNextLowestTime, s_pTimeoutContext );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetContextThink( NULL, TICK_NEVER_THINK, s_pTimeoutContext );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::ShowMenu( CRecipientFilter &filter, float flDisplayTime )
|
||||||
|
{
|
||||||
|
// Before showing the menu, check each menu to see if there's already one being shown to one of our recipients
|
||||||
|
for ( int i = 0; i < IGameMenuAutoList::AutoList().Count(); i++ )
|
||||||
|
{
|
||||||
|
CGameMenu *pMenu = static_cast<CGameMenu*>( IGameMenuAutoList::AutoList()[i] );
|
||||||
|
if ( pMenu != this && pMenu->IsActive() )
|
||||||
|
{
|
||||||
|
for ( int j = 0; j < filter.GetRecipientCount(); j++ )
|
||||||
|
{
|
||||||
|
CBaseEntity *ent = CBaseEntity::Instance( filter.GetRecipientIndex( j ) );
|
||||||
|
if ( pMenu->IsActiveOnTarget( ent ) )
|
||||||
|
{
|
||||||
|
Msg( "%s overriding menu %s for player %i\n", GetDebugName(), pMenu->GetDebugName(), j );
|
||||||
|
pMenu->RemoveTarget( ent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flDisplayTime == 0.0f)
|
||||||
|
{
|
||||||
|
flDisplayTime = m_flDisplayTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
char szString[512] = { 0 };
|
||||||
|
int nBitsValidSlots = 0;
|
||||||
|
|
||||||
|
if (m_iszTitle != NULL_STRING)
|
||||||
|
{
|
||||||
|
V_strncat( szString, STRING( m_iszTitle ), sizeof( szString ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert space to tell menu code to skip
|
||||||
|
V_strncat( szString, " ", sizeof( szString ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert newline even if there's no string
|
||||||
|
V_strncat( szString, "\n", sizeof( szString ) );
|
||||||
|
|
||||||
|
// Populate the options
|
||||||
|
for (int i = 0; i < MAX_MENU_OPTIONS; i++)
|
||||||
|
{
|
||||||
|
if (m_iszOption[i] != NULL_STRING)
|
||||||
|
{
|
||||||
|
nBitsValidSlots |= (1 << i);
|
||||||
|
|
||||||
|
V_strncat( szString, STRING( m_iszOption[i] ), sizeof( szString ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert space to tell menu code to skip
|
||||||
|
V_strncat( szString, " ", sizeof( szString ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert newline even if there's no string
|
||||||
|
V_strncat( szString, "\n", sizeof( szString ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nBitsValidSlots <= 0 && m_iszTitle == NULL_STRING)
|
||||||
|
{
|
||||||
|
Warning( "%s ShowMenu: Can't show menu with no options or title\n", GetDebugName() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserMessageBegin( filter, "ShowMenuComplex" );
|
||||||
|
WRITE_WORD( nBitsValidSlots );
|
||||||
|
WRITE_FLOAT( flDisplayTime );
|
||||||
|
WRITE_BYTE( 0 );
|
||||||
|
WRITE_STRING( szString );
|
||||||
|
MessageEnd();
|
||||||
|
|
||||||
|
float flMenuTime;
|
||||||
|
if (flDisplayTime <= 0.0f)
|
||||||
|
{
|
||||||
|
flMenuTime = MENU_INFINITE_TIME;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flMenuTime = gpGlobals->curtime + flDisplayTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int j = 0; j < filter.GetRecipientCount(); j++ )
|
||||||
|
{
|
||||||
|
CBaseEntity *ent = CBaseEntity::Instance( filter.GetRecipientIndex( j ) );
|
||||||
|
|
||||||
|
// Check if we already track this player. If not, make a new one
|
||||||
|
bool bFound = false;
|
||||||
|
FOR_EACH_VEC( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == ent)
|
||||||
|
{
|
||||||
|
m_ActivePlayerTimes[i] = flMenuTime;
|
||||||
|
bFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bFound)
|
||||||
|
{
|
||||||
|
m_ActivePlayers.AddToTail( ent );
|
||||||
|
m_ActivePlayerTimes.AddToTail( flMenuTime );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetNextThink( s_pTimeoutContext ) == TICK_NEVER_THINK)
|
||||||
|
{
|
||||||
|
SetContextThink( &CGameMenu::TimeoutThink, gpGlobals->curtime + flDisplayTime, s_pTimeoutContext );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::HideMenu( CRecipientFilter &filter )
|
||||||
|
{
|
||||||
|
UserMessageBegin( filter, "ShowMenuComplex" );
|
||||||
|
WRITE_WORD( -1 );
|
||||||
|
WRITE_FLOAT( 0.0f );
|
||||||
|
WRITE_BYTE( 0 );
|
||||||
|
WRITE_STRING( "" );
|
||||||
|
MessageEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::MenuSelected( int nSlot, CBaseEntity *pActivator )
|
||||||
|
{
|
||||||
|
if (nSlot <= 0 || nSlot > MAX_MENU_OPTIONS)
|
||||||
|
{
|
||||||
|
Warning( "%s: Invalid slot %i\n", GetDebugName(), nSlot );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_OnCase[nSlot-1].FireOutput( pActivator, this );
|
||||||
|
m_OutValue.Set( nSlot, pActivator, this );
|
||||||
|
|
||||||
|
RemoveTarget( pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CGameMenu::IsActive()
|
||||||
|
{
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get())
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CGameMenu::IsActiveOnTarget( CBaseEntity *pPlayer )
|
||||||
|
{
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == pPlayer)
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::RemoveTarget( CBaseEntity *pPlayer )
|
||||||
|
{
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == pPlayer)
|
||||||
|
{
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::InputShowMenu( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
if (HasSpawnFlags( SF_GAMEMENU_ALLPLAYERS ))
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
filter.AddAllPlayers();
|
||||||
|
|
||||||
|
ShowMenu( filter );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBasePlayer *pPlayer = NULL;
|
||||||
|
|
||||||
|
// If we're in singleplayer, show the message to the player.
|
||||||
|
if ( gpGlobals->maxClients == 1 )
|
||||||
|
{
|
||||||
|
pPlayer = UTIL_GetLocalPlayer();
|
||||||
|
}
|
||||||
|
// Otherwise show the message to the player that triggered us.
|
||||||
|
else if ( inputdata.pActivator && inputdata.pActivator->IsNetClient() )
|
||||||
|
{
|
||||||
|
pPlayer = ToBasePlayer( inputdata.pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPlayer)
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
filter.AddRecipient( pPlayer );
|
||||||
|
|
||||||
|
ShowMenu( filter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::InputHideMenu( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
if (HasSpawnFlags( SF_GAMEMENU_ALLPLAYERS ))
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
// Select all players in our list who are still active, and remove them
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
{
|
||||||
|
filter.AddRecipient( static_cast<CBasePlayer*>(m_ActivePlayers[i].Get()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.GetRecipientCount() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HideMenu( filter );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBasePlayer *pPlayer = NULL;
|
||||||
|
|
||||||
|
// If we're in singleplayer, show the message to the player.
|
||||||
|
if ( gpGlobals->maxClients == 1 )
|
||||||
|
{
|
||||||
|
pPlayer = UTIL_GetLocalPlayer();
|
||||||
|
}
|
||||||
|
// Otherwise show the message to the player that triggered us.
|
||||||
|
else if ( inputdata.pActivator && inputdata.pActivator->IsNetClient() )
|
||||||
|
{
|
||||||
|
pPlayer = ToBasePlayer( inputdata.pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pPlayer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Verify that this player is in our list
|
||||||
|
CRecipientFilter filter;
|
||||||
|
FOR_EACH_VEC( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == pPlayer && (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME))
|
||||||
|
{
|
||||||
|
filter.AddRecipient( pPlayer );
|
||||||
|
|
||||||
|
// Remove since the player won't have the menu anymore
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.GetRecipientCount() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HideMenu( filter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,55 @@
|
|||||||
#ifndef MAPRULES_H
|
#ifndef MAPRULES_H
|
||||||
#define MAPRULES_H
|
#define MAPRULES_H
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
#define MAX_MENU_OPTIONS 10
|
||||||
|
|
||||||
|
#define SF_GAMEMENU_ALLPLAYERS 0x0001
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Displays a custom number menu for player(s)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
DECLARE_AUTO_LIST( IGameMenuAutoList );
|
||||||
|
class CGameMenu : public CLogicalEntity, public IGameMenuAutoList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( CGameMenu, CLogicalEntity );
|
||||||
|
DECLARE_DATADESC();
|
||||||
|
CGameMenu();
|
||||||
|
|
||||||
|
void OnRestore();
|
||||||
|
void InputDoRestore( inputdata_t &inputdata );
|
||||||
|
|
||||||
|
void TimeoutThink();
|
||||||
|
|
||||||
|
void ShowMenu( CRecipientFilter &filter, float flDisplayTime = 0.0f );
|
||||||
|
void HideMenu( CRecipientFilter &filter );
|
||||||
|
void MenuSelected( int nSlot, CBaseEntity *pActivator );
|
||||||
|
|
||||||
|
bool IsActive();
|
||||||
|
bool IsActiveOnTarget( CBaseEntity *pPlayer );
|
||||||
|
void RemoveTarget( CBaseEntity *pPlayer );
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
void InputShowMenu( inputdata_t &inputdata );
|
||||||
|
void InputHideMenu( inputdata_t &inputdata );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CUtlVector<EHANDLE> m_ActivePlayers;
|
||||||
|
CUtlVector<float> m_ActivePlayerTimes;
|
||||||
|
|
||||||
|
float m_flDisplayTime;
|
||||||
|
|
||||||
|
string_t m_iszTitle;
|
||||||
|
string_t m_iszOption[MAX_MENU_OPTIONS];
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
COutputEvent m_OnCase[MAX_MENU_OPTIONS]; // Fired for the option chosen
|
||||||
|
COutputInt m_OutValue; // Outputs the option chosen
|
||||||
|
COutputEvent m_OnTimeout; // Fires when no option was chosen in time
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // MAPRULES_H
|
#endif // MAPRULES_H
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "hierarchy.h"
|
#include "hierarchy.h"
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
#include "decals.h"
|
#include "decals.h"
|
||||||
|
#include "death_pose.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// memdbgon must be the last include file in a .cpp file!!!
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
ConVar ragdoll_autointeractions("ragdoll_autointeractions", "1", FCVAR_NONE, "Controls whether we should rely on hardcoded keyvalues or automatic flesh checks for ragdoll physgun interactions.");
|
ConVar ragdoll_autointeractions("ragdoll_autointeractions", "1", FCVAR_NONE, "Controls whether we should rely on hardcoded keyvalues or automatic flesh checks for ragdoll physgun interactions.");
|
||||||
|
ConVar ai_death_pose_server_enabled("ai_death_pose_server_enabled", "1", FCVAR_NONE, "Toggles the death pose fix code, but for server ragdolls.");
|
||||||
#define IsBody() VPhysicsIsFlesh()
|
#define IsBody() VPhysicsIsFlesh()
|
||||||
|
|
||||||
ConVar ragdoll_always_allow_use( "ragdoll_always_allow_use", "0", FCVAR_NONE, "Allows all ragdolls to be used and, if they aren't explicitly set to prevent pickup, picked up." );
|
ConVar ragdoll_always_allow_use( "ragdoll_always_allow_use", "0", FCVAR_NONE, "Allows all ragdolls to be used and, if they aren't explicitly set to prevent pickup, picked up." );
|
||||||
@ -788,7 +790,11 @@ void CRagdollProp::SetOverlaySequence( Activity activity )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
void CRagdollProp::InitRagdoll( const Vector& forceVector, int forceBone, const Vector& forcePos, matrix3x4_t* pPrevBones, matrix3x4_t* pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll, bool bDeathPose )
|
||||||
|
#else
|
||||||
void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll )
|
void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
SetCollisionGroup( collisionGroup );
|
SetCollisionGroup( collisionGroup );
|
||||||
|
|
||||||
@ -811,7 +817,11 @@ void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const
|
|||||||
params.forceVector = forceVector;
|
params.forceVector = forceVector;
|
||||||
params.forceBoneIndex = forceBone;
|
params.forceBoneIndex = forceBone;
|
||||||
params.forcePosition = forcePos;
|
params.forcePosition = forcePos;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
params.pCurrentBones = bDeathPose ? pPrevBones : pBoneToWorld;
|
||||||
|
#else
|
||||||
params.pCurrentBones = pBoneToWorld;
|
params.pCurrentBones = pBoneToWorld;
|
||||||
|
#endif
|
||||||
params.jointFrictionScale = 1.0;
|
params.jointFrictionScale = 1.0;
|
||||||
params.allowStretch = HasSpawnFlags(SF_RAGDOLLPROP_ALLOW_STRETCH);
|
params.allowStretch = HasSpawnFlags(SF_RAGDOLLPROP_ALLOW_STRETCH);
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
@ -1492,6 +1502,43 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con
|
|||||||
|
|
||||||
float fPreviousCycle = clamp(pAnimating->GetCycle()-( dt * ( 1 / fSequenceDuration ) ),0.f,1.f);
|
float fPreviousCycle = clamp(pAnimating->GetCycle()-( dt * ( 1 / fSequenceDuration ) ),0.f,1.f);
|
||||||
float fCurCycle = pAnimating->GetCycle();
|
float fCurCycle = pAnimating->GetCycle();
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
int deathpose = ACT_INVALID;
|
||||||
|
int deathframe = 0;
|
||||||
|
if (ai_death_pose_server_enabled.GetBool() && pAnimating->IsNPC()) {
|
||||||
|
CAI_BaseNPC* npc = (CAI_BaseNPC*)pAnimating;
|
||||||
|
if (npc) {
|
||||||
|
deathpose = Activity(npc->GetDeathPose());
|
||||||
|
deathframe = npc->GetDeathPoseFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deathpose != ACT_INVALID) {
|
||||||
|
int currentSequence = pAnimating->GetSequence();
|
||||||
|
|
||||||
|
//Force pAnimating to position the deathpose
|
||||||
|
pAnimating->SetSequence(deathpose);
|
||||||
|
pAnimating->SetCycle((float)deathframe / MAX_DEATHPOSE_FRAMES);
|
||||||
|
|
||||||
|
//Store the position
|
||||||
|
pAnimating->SetupBones(pBoneToWorldNext, BONE_USED_BY_ANYTHING);
|
||||||
|
|
||||||
|
//Restore the current sequence and cycle
|
||||||
|
pAnimating->SetSequence(currentSequence);
|
||||||
|
|
||||||
|
pAnimating->SetCycle(fCurCycle);
|
||||||
|
pAnimating->SetupBones(pBoneToWorld, BONE_USED_BY_ANYTHING);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Get current bones positions
|
||||||
|
pAnimating->SetupBones(pBoneToWorldNext, BONE_USED_BY_ANYTHING);
|
||||||
|
// Get previous bones positions
|
||||||
|
pAnimating->SetCycle(fPreviousCycle);
|
||||||
|
pAnimating->SetupBones(pBoneToWorld, BONE_USED_BY_ANYTHING);
|
||||||
|
// Restore current cycle
|
||||||
|
pAnimating->SetCycle(fCurCycle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
// Get current bones positions
|
// Get current bones positions
|
||||||
pAnimating->SetupBones( pBoneToWorldNext, BONE_USED_BY_ANYTHING );
|
pAnimating->SetupBones( pBoneToWorldNext, BONE_USED_BY_ANYTHING );
|
||||||
// Get previous bones positions
|
// Get previous bones positions
|
||||||
@ -1499,6 +1546,7 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con
|
|||||||
pAnimating->SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING );
|
pAnimating->SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING );
|
||||||
// Restore current cycle
|
// Restore current cycle
|
||||||
pAnimating->SetCycle( fCurCycle );
|
pAnimating->SetCycle( fCurCycle );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Reset previous bone flags
|
// Reset previous bone flags
|
||||||
pAnimating->ClearBoneCacheFlags( BCF_NO_ANIMATION_SKIP );
|
pAnimating->ClearBoneCacheFlags( BCF_NO_ANIMATION_SKIP );
|
||||||
@ -1573,7 +1621,11 @@ CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, con
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef MAPBASE
|
||||||
|
pRagdoll->InitRagdoll(info.GetDamageForce(), forceBone, info.GetDamagePosition(), pBoneToWorld, pBoneToWorldNext, dt, collisionGroup, true, true, deathpose != ACT_INVALID);
|
||||||
|
#else
|
||||||
pRagdoll->InitRagdoll( info.GetDamageForce(), forceBone, info.GetDamagePosition(), pBoneToWorld, pBoneToWorldNext, dt, collisionGroup, true );
|
pRagdoll->InitRagdoll( info.GetDamageForce(), forceBone, info.GetDamagePosition(), pBoneToWorld, pBoneToWorldNext, dt, collisionGroup, true );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we dissolving?
|
// Are we dissolving?
|
||||||
|
@ -75,7 +75,11 @@ public:
|
|||||||
|
|
||||||
// locals
|
// locals
|
||||||
void InitRagdollAnimation( void );
|
void InitRagdollAnimation( void );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
void InitRagdoll( const Vector& forceVector, int forceBone, const Vector& forcePos, matrix3x4_t* pPrevBones, matrix3x4_t* pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll = true, bool bDeathPose = false );
|
||||||
|
#else
|
||||||
void InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll = true );
|
void InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll, bool bWakeRagdoll = true );
|
||||||
|
#endif
|
||||||
|
|
||||||
void RecheckCollisionFilter( void );
|
void RecheckCollisionFilter( void );
|
||||||
void SetDebrisThink();
|
void SetDebrisThink();
|
||||||
|
@ -48,6 +48,8 @@ $Project
|
|||||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
||||||
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
|
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
|
||||||
$File "$SRCDIR\game\shared\mapbase\matchers.h"
|
$File "$SRCDIR\game\shared\mapbase\matchers.h"
|
||||||
|
$File "$SRCDIR\game\shared\mapbase\game_timer.cpp"
|
||||||
|
$File "$SRCDIR\game\shared\mapbase\game_timer.h"
|
||||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
|
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
|
||||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
|
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
|
||||||
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]
|
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]
|
||||||
|
@ -60,10 +60,6 @@ extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
|||||||
|
|
||||||
extern CServerGameDLL g_ServerGameDLL;
|
extern CServerGameDLL g_ServerGameDLL;
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
|
||||||
extern int vscript_debugger_port;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// #define VMPROFILE 1
|
// #define VMPROFILE 1
|
||||||
|
|
||||||
#ifdef VMPROFILE
|
#ifdef VMPROFILE
|
||||||
@ -3769,10 +3765,13 @@ REGISTER_SCRIPT_CONST_TABLE( Server )
|
|||||||
g_pScriptVM->SetValue( "Constants", vConstantsTable );
|
g_pScriptVM->SetValue( "Constants", vConstantsTable );
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
if ( vscript_debugger_port )
|
if ( script_connect_debugger_on_mapspawn.GetInt() == 2 )
|
||||||
|
{
|
||||||
|
g_pScriptVM->ConnectDebugger( vscript_debugger_port, 10.0f );
|
||||||
|
}
|
||||||
|
else if ( script_connect_debugger_on_mapspawn.GetInt() != 0 )
|
||||||
{
|
{
|
||||||
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
||||||
vscript_debugger_port = 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3793,10 +3792,12 @@ REGISTER_SCRIPT_CONST_TABLE( Server )
|
|||||||
GetWorldEntity()->RunVScripts();
|
GetWorldEntity()->RunVScripts();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAPBASE_VSCRIPT
|
||||||
if ( script_connect_debugger_on_mapspawn.GetBool() )
|
if ( script_connect_debugger_on_mapspawn.GetBool() )
|
||||||
{
|
{
|
||||||
g_pScriptVM->ConnectDebugger();
|
g_pScriptVM->ConnectDebugger();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
|
VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
|
||||||
|
|
||||||
|
@ -1149,7 +1149,7 @@ WeaponClass_t CBaseCombatWeapon::WeaponClassFromString(const char *str)
|
|||||||
return WEPCLASS_RIFLE;
|
return WEPCLASS_RIFLE;
|
||||||
else if (FStrEq(str, "WEPCLASS_SHOTGUN"))
|
else if (FStrEq(str, "WEPCLASS_SHOTGUN"))
|
||||||
return WEPCLASS_SHOTGUN;
|
return WEPCLASS_SHOTGUN;
|
||||||
else if (FStrEq(str, "WEPCLASS_HEAY"))
|
else if (FStrEq(str, "WEPCLASS_HEAVY"))
|
||||||
return WEPCLASS_HEAVY;
|
return WEPCLASS_HEAVY;
|
||||||
|
|
||||||
else if (FStrEq(str, "WEPCLASS_MELEE"))
|
else if (FStrEq(str, "WEPCLASS_MELEE"))
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
#include "player_resource.h"
|
#include "player_resource.h"
|
||||||
#include "tactical_mission.h"
|
#include "tactical_mission.h"
|
||||||
#include "gamestats.h"
|
#include "gamestats.h"
|
||||||
|
#ifdef MAPBASE
|
||||||
|
#include "maprules.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -621,6 +624,27 @@ bool CGameRules::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
|
|||||||
{
|
{
|
||||||
if( GetVoiceGameMgr()->ClientCommand( static_cast<CBasePlayer*>(pEdict), args ) )
|
if( GetVoiceGameMgr()->ClientCommand( static_cast<CBasePlayer*>(pEdict), args ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( FStrEq( args[0], "menuselect" ) )
|
||||||
|
{
|
||||||
|
if ( args.ArgC() >= 2 )
|
||||||
|
{
|
||||||
|
int slot = atoi( args[1] );
|
||||||
|
|
||||||
|
// See if this is from a game_menu
|
||||||
|
for ( int i = 0; i < IGameMenuAutoList::AutoList().Count(); i++ )
|
||||||
|
{
|
||||||
|
CGameMenu *pMenu = static_cast<CGameMenu*>( IGameMenuAutoList::AutoList()[i] );
|
||||||
|
if ( pMenu->IsActiveOnTarget( pEdict ) )
|
||||||
|
{
|
||||||
|
pMenu->MenuSelected( slot, pEdict );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
658
src/game/shared/mapbase/game_timer.cpp
Normal file
658
src/game/shared/mapbase/game_timer.cpp
Normal file
@ -0,0 +1,658 @@
|
|||||||
|
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
|
||||||
|
//
|
||||||
|
// Purpose: Generic custom timer entity
|
||||||
|
//
|
||||||
|
// Author: Blixibon
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "game_timer.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
extern bool IsInCommentaryMode( void );
|
||||||
|
|
||||||
|
ConVar sv_game_menu_default_warn_frac( "sv_game_menu_default_warn_frac", "0.25", FCVAR_REPLICATED );
|
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( game_timer, CGameTimer );
|
||||||
|
|
||||||
|
IMPLEMENT_NETWORKCLASS_ALIASED( GameTimer, DT_GameTimer )
|
||||||
|
|
||||||
|
BEGIN_NETWORK_TABLE_NOBASE( CGameTimer, DT_GameTimer )
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
|
||||||
|
RecvPropBool( RECVINFO( m_bTimerPaused ) ),
|
||||||
|
RecvPropTime( RECVINFO( m_flTimerInitialLength ) ),
|
||||||
|
RecvPropTime( RECVINFO( m_flTimerMaxLength ) ),
|
||||||
|
RecvPropTime( RECVINFO( m_flTimeRemaining ) ),
|
||||||
|
RecvPropTime( RECVINFO( m_flTimerEndTime ) ),
|
||||||
|
RecvPropTime( RECVINFO( m_flWarnTime ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bIsDisabled ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bStartPaused ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bShowTimeRemaining ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nProgressBarMaxSegments ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nProgressBarOverride ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_flOverrideX ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_flOverrideY ) ),
|
||||||
|
RecvPropString( RECVINFO( m_szTimerCaption ) ),
|
||||||
|
|
||||||
|
RecvPropInt( RECVINFO( m_iTeamNum ) ),
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SendPropBool( SENDINFO( m_bTimerPaused ) ),
|
||||||
|
SendPropTime( SENDINFO( m_flTimerInitialLength ) ),
|
||||||
|
SendPropTime( SENDINFO( m_flTimerMaxLength ) ),
|
||||||
|
SendPropTime( SENDINFO( m_flTimeRemaining ) ),
|
||||||
|
SendPropTime( SENDINFO( m_flTimerEndTime ) ),
|
||||||
|
SendPropTime( SENDINFO( m_flWarnTime ) ),
|
||||||
|
SendPropBool( SENDINFO( m_bIsDisabled ) ),
|
||||||
|
SendPropBool( SENDINFO( m_bStartPaused ) ),
|
||||||
|
SendPropBool( SENDINFO( m_bShowTimeRemaining ) ),
|
||||||
|
SendPropInt( SENDINFO( m_nProgressBarMaxSegments ) ),
|
||||||
|
SendPropInt( SENDINFO( m_nProgressBarOverride ) ),
|
||||||
|
SendPropFloat( SENDINFO( m_flOverrideX ) ),
|
||||||
|
SendPropFloat( SENDINFO( m_flOverrideY ) ),
|
||||||
|
SendPropString( SENDINFO( m_szTimerCaption ) ),
|
||||||
|
|
||||||
|
SendPropInt( SENDINFO( m_iTeamNum ), TEAMNUM_NUM_BITS, 0 ),
|
||||||
|
|
||||||
|
#endif
|
||||||
|
END_NETWORK_TABLE()
|
||||||
|
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
BEGIN_DATADESC( CGameTimer )
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_flTimerInitialLength, FIELD_FLOAT, "timer_length" ),
|
||||||
|
DEFINE_KEYFIELD( m_flTimerMaxLength, FIELD_FLOAT, "max_length" ),
|
||||||
|
DEFINE_KEYFIELD( m_flWarnTime, FIELD_FLOAT, "warn_time" ),
|
||||||
|
DEFINE_KEYFIELD( m_bIsDisabled, FIELD_BOOLEAN, "StartDisabled" ),
|
||||||
|
DEFINE_KEYFIELD( m_bStartPaused, FIELD_BOOLEAN, "start_paused" ),
|
||||||
|
DEFINE_KEYFIELD( m_bShowTimeRemaining, FIELD_BOOLEAN, "show_time_remaining" ),
|
||||||
|
DEFINE_KEYFIELD( m_bDisableOnFinish, FIELD_BOOLEAN, "disable_on_finish" ),
|
||||||
|
DEFINE_KEYFIELD( m_bShowInHUD, FIELD_BOOLEAN, "show_in_hud" ),
|
||||||
|
DEFINE_KEYFIELD( m_nProgressBarMaxSegments, FIELD_INTEGER, "progress_bar_max" ),
|
||||||
|
DEFINE_KEYFIELD( m_nProgressBarOverride, FIELD_INTEGER, "progress_bar_override" ),
|
||||||
|
DEFINE_KEYFIELD( m_flOverrideX, FIELD_FLOAT, "x" ),
|
||||||
|
DEFINE_KEYFIELD( m_flOverrideY, FIELD_FLOAT, "y" ),
|
||||||
|
DEFINE_AUTO_ARRAY( m_szTimerCaption, FIELD_CHARACTER ),
|
||||||
|
DEFINE_KEYFIELD( m_iszPlayerFilterName, FIELD_STRING, "PlayerFilter" ),
|
||||||
|
DEFINE_FIELD( m_hPlayerFilter, FIELD_EHANDLE ),
|
||||||
|
|
||||||
|
DEFINE_FIELD( m_flTimerEndTime, FIELD_TIME ),
|
||||||
|
DEFINE_FIELD( m_flTimeRemaining, FIELD_FLOAT ),
|
||||||
|
DEFINE_FIELD( m_bTimerPaused, FIELD_BOOLEAN ),
|
||||||
|
DEFINE_FIELD( m_bStartedWarn, FIELD_BOOLEAN ),
|
||||||
|
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "Pause", InputPause ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "Resume", InputResume ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetTime", InputSetTime ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "AddTime", InputAddTime ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "RemoveTime", InputRemoveTime ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "Restart", InputRestart ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxTime", InputSetMaxTime ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_STRING, "SetTimerCaption", InputSetTimerCaption ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetProgressBarMaxSegments", InputSetProgressBarMaxSegments ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetProgressBarOverride", InputSetProgressBarOverride ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetX", InputSetX ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetY", InputSetY ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "GetTimeRemaining", InputGetTimeRemaining ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_STRING, "SetPlayerFilter", InputSetPlayerFilter ),
|
||||||
|
|
||||||
|
DEFINE_OUTPUT( m_OnFinished, "OnFinished" ),
|
||||||
|
DEFINE_OUTPUT( m_OnPaused, "OnPaused" ),
|
||||||
|
DEFINE_OUTPUT( m_OnResumed, "OnResumed" ),
|
||||||
|
DEFINE_OUTPUT( m_OnWarned, "OnWarned" ),
|
||||||
|
DEFINE_OUTPUT( m_OnTick, "OnTick" ),
|
||||||
|
DEFINE_OUTPUT( m_OnGetTimeRemaining, "OnGetTimeRemaining" ),
|
||||||
|
|
||||||
|
DEFINE_THINKFUNC( TimerThink ),
|
||||||
|
|
||||||
|
END_DATADESC();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
IMPLEMENT_AUTO_LIST( IGameTimerAutoList );
|
||||||
|
#else
|
||||||
|
#define TIMER_THINK "GameTimerThink"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: constructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CGameTimer::CGameTimer( void )
|
||||||
|
{
|
||||||
|
m_bIsDisabled = true;
|
||||||
|
m_bTimerPaused = true;
|
||||||
|
m_flTimeRemaining = 0;
|
||||||
|
m_flTimerEndTime = 0;
|
||||||
|
m_flWarnTime = -1.0f;
|
||||||
|
m_bStartPaused = false;
|
||||||
|
m_bShowTimeRemaining = true;
|
||||||
|
m_flTimerInitialLength = 0;
|
||||||
|
m_flTimerMaxLength = 0;
|
||||||
|
m_nProgressBarMaxSegments = -1;
|
||||||
|
m_nProgressBarOverride = -1;
|
||||||
|
m_flOverrideX = m_flOverrideY = -1.0f;
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
m_bDisableOnFinish = true;
|
||||||
|
m_bShowInHUD = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: destructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CGameTimer::~CGameTimer( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::Spawn( void )
|
||||||
|
{
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
if ( IsDisabled() ) // we need to get the data initialized before actually become disabled
|
||||||
|
{
|
||||||
|
m_bIsDisabled = false;
|
||||||
|
SetTimeRemaining( m_flTimerInitialLength );
|
||||||
|
m_bIsDisabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetTimeRemaining( m_flTimerInitialLength );
|
||||||
|
if ( !m_bStartPaused )
|
||||||
|
ResumeTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_iszPlayerFilterName != NULL_STRING )
|
||||||
|
{
|
||||||
|
m_hPlayerFilter = dynamic_cast<CBaseFilter *>(gEntList.FindEntityByName( NULL, m_iszPlayerFilterName, this ));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BaseClass::Spawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
|
||||||
|
bool CGameTimer::KeyValue( const char *szKeyName, const char *szValue )
|
||||||
|
{
|
||||||
|
if ( FStrEq( szKeyName, "timer_caption" ) )
|
||||||
|
{
|
||||||
|
Q_strncpy( m_szTimerCaption.GetForModify(), szValue, MAX_GAME_TIMER_CAPTION );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BaseClass::KeyValue( szKeyName, szValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGameTimer::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen )
|
||||||
|
{
|
||||||
|
if ( FStrEq( szKeyName, "timer_caption" ) )
|
||||||
|
{
|
||||||
|
Q_snprintf( szValue, iMaxLen, "%s", m_szTimerCaption.Get() );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Gets the seconds left on the timer, paused or not.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float CGameTimer::GetTimeRemaining( void )
|
||||||
|
{
|
||||||
|
float flSecondsRemaining;
|
||||||
|
|
||||||
|
if ( m_bTimerPaused )
|
||||||
|
{
|
||||||
|
flSecondsRemaining = m_flTimeRemaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flSecondsRemaining = m_flTimerEndTime - gpGlobals->curtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flSecondsRemaining < 0 )
|
||||||
|
{
|
||||||
|
flSecondsRemaining = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flSecondsRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Gets the timer's warning time
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float CGameTimer::GetWarnTime( void )
|
||||||
|
{
|
||||||
|
if ( m_flWarnTime < 0 )
|
||||||
|
{
|
||||||
|
// TODO: All of the default warning stuff is on the client!!!
|
||||||
|
return GetTimerMaxLength() * sv_game_menu_default_warn_frac.GetFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_flWarnTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float CGameTimer::GetTimerMaxLength( void )
|
||||||
|
{
|
||||||
|
if ( m_flTimerMaxLength )
|
||||||
|
return m_flTimerMaxLength;
|
||||||
|
|
||||||
|
return m_flTimerInitialLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
|
||||||
|
bool g_bAnyGameTimerActive = false;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_GameTimer::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
|
||||||
|
if ( !m_bIsDisabled )
|
||||||
|
{
|
||||||
|
g_bAnyGameTimerActive = true;
|
||||||
|
}
|
||||||
|
else if ( !m_bOldDisabled )
|
||||||
|
{
|
||||||
|
// Go through all of the timers and mark when one is active
|
||||||
|
g_bAnyGameTimerActive = false;
|
||||||
|
for ( int i = 0; i < IGameTimerAutoList::AutoList().Count(); i++ )
|
||||||
|
{
|
||||||
|
C_GameTimer *pTimer = static_cast<C_GameTimer *>( IGameTimerAutoList::AutoList()[i] );
|
||||||
|
if ( !pTimer->IsDisabled() && !pTimer->IsMarkedForDeletion() )
|
||||||
|
{
|
||||||
|
g_bAnyGameTimerActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bOldDisabled = m_bIsDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_GameTimer::UpdateOnRemove( void )
|
||||||
|
{
|
||||||
|
BaseClass::UpdateOnRemove();
|
||||||
|
|
||||||
|
// Update timer presence state
|
||||||
|
g_bAnyGameTimerActive = false;
|
||||||
|
for ( int i = 0; i < IGameTimerAutoList::AutoList().Count(); i++ )
|
||||||
|
{
|
||||||
|
C_GameTimer *pTimer = static_cast<C_GameTimer *>( IGameTimerAutoList::AutoList()[i] );
|
||||||
|
if ( pTimer != this && !pTimer->IsDisabled() && !pTimer->IsMarkedForDeletion() )
|
||||||
|
{
|
||||||
|
g_bAnyGameTimerActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::TimerThink( void )
|
||||||
|
{
|
||||||
|
if ( IsDisabled() /*|| IsInCommentaryMode() || gpGlobals->eLoadType == MapLoad_Background*/ )
|
||||||
|
{
|
||||||
|
SetContextThink( &CGameTimer::TimerThink, gpGlobals->curtime + 0.05, TIMER_THINK );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float flTime = GetTimeRemaining();
|
||||||
|
|
||||||
|
int nTick = (int)floorf( flTime );
|
||||||
|
if (nTick != m_OnTick.Get())
|
||||||
|
{
|
||||||
|
m_OnTick.Set( nTick, this, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flTime <= 0.0f )
|
||||||
|
{
|
||||||
|
OnTimerFinished();
|
||||||
|
PauseTimer();
|
||||||
|
if (m_bDisableOnFinish)
|
||||||
|
m_bIsDisabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ( flTime <= GetWarnTime() && !m_bStartedWarn)
|
||||||
|
{
|
||||||
|
OnTimerWarned();
|
||||||
|
m_bStartedWarn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetContextThink( &CGameTimer::TimerThink, gpGlobals->curtime + 0.05, TIMER_THINK );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: To set the initial timer duration
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::SetTimeRemaining( float flTime )
|
||||||
|
{
|
||||||
|
// make sure we don't go over our max length
|
||||||
|
flTime = m_flTimerMaxLength > 0 ? MIN( flTime, m_flTimerMaxLength ) : flTime;
|
||||||
|
|
||||||
|
m_flTimeRemaining = flTime;
|
||||||
|
m_flTimerEndTime = gpGlobals->curtime + m_flTimeRemaining;
|
||||||
|
|
||||||
|
if ( m_flTimeRemaining > m_flWarnTime )
|
||||||
|
{
|
||||||
|
m_bStartedWarn = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::OnTimerFinished()
|
||||||
|
{
|
||||||
|
m_OnFinished.FireOutput( this, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::OnTimerWarned()
|
||||||
|
{
|
||||||
|
m_OnWarned.FireOutput( this, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Timer is paused at round end, stops the countdown
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::PauseTimer( CBaseEntity *pActivator )
|
||||||
|
{
|
||||||
|
if ( IsDisabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( m_bTimerPaused == false )
|
||||||
|
{
|
||||||
|
m_bTimerPaused = true;
|
||||||
|
m_flTimeRemaining = m_flTimerEndTime - gpGlobals->curtime;
|
||||||
|
|
||||||
|
m_OnPaused.FireOutput( pActivator ? pActivator : this, this );
|
||||||
|
|
||||||
|
SetContextThink( NULL, TICK_NEVER_THINK, TIMER_THINK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: To start or re-start the timer after a pause
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::ResumeTimer( CBaseEntity *pActivator )
|
||||||
|
{
|
||||||
|
if ( IsDisabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( m_bTimerPaused == true )
|
||||||
|
{
|
||||||
|
m_bTimerPaused = false;
|
||||||
|
m_flTimerEndTime = gpGlobals->curtime + m_flTimeRemaining;
|
||||||
|
|
||||||
|
m_OnResumed.FireOutput( pActivator ? pActivator : this, this );
|
||||||
|
|
||||||
|
TimerThink();
|
||||||
|
|
||||||
|
SetContextThink( &CGameTimer::TimerThink, gpGlobals->curtime + 0.05, TIMER_THINK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Add seconds to the timer while it is running or paused
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::AddTimerSeconds( float flTimeToAdd )
|
||||||
|
{
|
||||||
|
if ( IsDisabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( m_flTimerMaxLength > 0 )
|
||||||
|
{
|
||||||
|
// will adding this many seconds push us over our max length?
|
||||||
|
if ( GetTimeRemaining() + flTimeToAdd > m_flTimerMaxLength)
|
||||||
|
{
|
||||||
|
// adjust to only add up to our max length
|
||||||
|
flTimeToAdd = m_flTimerMaxLength - GetTimeRemaining();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_bTimerPaused )
|
||||||
|
{
|
||||||
|
m_flTimeRemaining += flTimeToAdd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_flTimerEndTime += flTimeToAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Should we transmit it to the client?
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int CGameTimer::UpdateTransmitState()
|
||||||
|
{
|
||||||
|
if ( !m_bShowInHUD )
|
||||||
|
{
|
||||||
|
return SetTransmitState( FL_EDICT_DONTSEND );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_hPlayerFilter || GetTeamNumber() > TEAM_UNASSIGNED )
|
||||||
|
{
|
||||||
|
return SetTransmitState( FL_EDICT_FULLCHECK );
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetTransmitState( FL_EDICT_ALWAYS );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Which clients should we be transmitting to?
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int CGameTimer::ShouldTransmit( const CCheckTransmitInfo *pInfo )
|
||||||
|
{
|
||||||
|
int result = BaseClass::ShouldTransmit( pInfo );
|
||||||
|
|
||||||
|
if ( result != FL_EDICT_DONTSEND )
|
||||||
|
{
|
||||||
|
CBaseEntity *pClient = (CBaseEntity *)(pInfo->m_pClientEnt->GetUnknown());
|
||||||
|
if ( pClient )
|
||||||
|
{
|
||||||
|
if ( m_hPlayerFilter )
|
||||||
|
{
|
||||||
|
// Don't send to players who don't pass our filter
|
||||||
|
if ( !m_hPlayerFilter->PassesFilter( this, pClient ) )
|
||||||
|
return FL_EDICT_DONTSEND;
|
||||||
|
}
|
||||||
|
else if ( GetTeamNumber() > TEAM_UNASSIGNED )
|
||||||
|
{
|
||||||
|
// If we don't have an explicit filter, then just check if it's on the same team as us
|
||||||
|
if ( pClient->GetTeamNumber() != GetTeamNumber() )
|
||||||
|
return FL_EDICT_DONTSEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FL_EDICT_ALWAYS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputPause( inputdata_t &input )
|
||||||
|
{
|
||||||
|
PauseTimer( input.pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputResume( inputdata_t &input )
|
||||||
|
{
|
||||||
|
ResumeTimer( input.pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetTime( inputdata_t &input )
|
||||||
|
{
|
||||||
|
float flTime = input.value.Float();
|
||||||
|
SetTimeRemaining( flTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputAddTime( inputdata_t &input )
|
||||||
|
{
|
||||||
|
float flTime = input.value.Float();
|
||||||
|
AddTimerSeconds( flTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputRemoveTime( inputdata_t &input )
|
||||||
|
{
|
||||||
|
float flTime = input.value.Float();
|
||||||
|
AddTimerSeconds( -flTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetMaxTime( inputdata_t &input )
|
||||||
|
{
|
||||||
|
float flTime = input.value.Float();
|
||||||
|
m_flTimerMaxLength = flTime;
|
||||||
|
|
||||||
|
if (m_flTimerMaxLength > 0)
|
||||||
|
{
|
||||||
|
// make sure our current time is not above the max length
|
||||||
|
if (GetTimeRemaining() > m_flTimerMaxLength)
|
||||||
|
{
|
||||||
|
SetTimeRemaining( m_flTimerMaxLength );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetTimerCaption( inputdata_t &input )
|
||||||
|
{
|
||||||
|
Q_strncpy( m_szTimerCaption.GetForModify(), input.value.String(), MAX_GAME_TIMER_CAPTION );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetProgressBarMaxSegments( inputdata_t &input )
|
||||||
|
{
|
||||||
|
m_nProgressBarMaxSegments = input.value.Int();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetProgressBarOverride( inputdata_t &input )
|
||||||
|
{
|
||||||
|
m_nProgressBarOverride = input.value.Int();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetX( inputdata_t &input )
|
||||||
|
{
|
||||||
|
m_flOverrideX = input.value.Float();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetY( inputdata_t &input )
|
||||||
|
{
|
||||||
|
m_flOverrideY = input.value.Float();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputRestart( inputdata_t &input )
|
||||||
|
{
|
||||||
|
SetTimeRemaining( m_flTimerInitialLength );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputGetTimeRemaining( inputdata_t &input )
|
||||||
|
{
|
||||||
|
m_OnGetTimeRemaining.Set( GetTimeRemaining(), input.pActivator, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputEnable( inputdata_t &input )
|
||||||
|
{
|
||||||
|
if (GetTimeRemaining() == 0.0f)
|
||||||
|
SetTimeRemaining( m_flTimerInitialLength );
|
||||||
|
|
||||||
|
m_bIsDisabled = false;
|
||||||
|
if ( !m_bStartPaused )
|
||||||
|
ResumeTimer( input.pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputDisable( inputdata_t &input )
|
||||||
|
{
|
||||||
|
PauseTimer( input.pActivator );
|
||||||
|
m_bIsDisabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameTimer::InputSetPlayerFilter( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
m_iszPlayerFilterName = inputdata.value.StringID();
|
||||||
|
if ( m_iszPlayerFilterName != NULL_STRING )
|
||||||
|
{
|
||||||
|
m_hPlayerFilter = dynamic_cast<CBaseFilter *>(gEntList.FindEntityByName( NULL, m_iszPlayerFilterName, this ));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_hPlayerFilter = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
145
src/game/shared/mapbase/game_timer.h
Normal file
145
src/game/shared/mapbase/game_timer.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
|
||||||
|
//
|
||||||
|
// Purpose: Generic custom timer entity
|
||||||
|
//
|
||||||
|
// Author: Blixibon
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
#include "c_baseentity.h"
|
||||||
|
#else
|
||||||
|
#include "filters.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
DECLARE_AUTO_LIST( IGameTimerAutoList );
|
||||||
|
|
||||||
|
#define CGameTimer C_GameTimer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_GAME_TIMER_CAPTION 32
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Displays a custom timer
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CGameTimer : public CBaseEntity
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
, public IGameTimerAutoList
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( CGameTimer, CBaseEntity );
|
||||||
|
DECLARE_NETWORKCLASS();
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
DECLARE_DATADESC();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CGameTimer();
|
||||||
|
~CGameTimer();
|
||||||
|
|
||||||
|
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
||||||
|
|
||||||
|
void Spawn();
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
bool KeyValue( const char *szKeyName, const char *szValue );
|
||||||
|
virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Based on teamplay_round_timer
|
||||||
|
virtual float GetTimeRemaining( void );
|
||||||
|
virtual float GetTimerMaxLength( void );
|
||||||
|
virtual bool StartPaused( void ) { return m_bStartPaused; }
|
||||||
|
bool ShowTimeRemaining( void ) { return m_bShowTimeRemaining; }
|
||||||
|
float GetWarnTime( void );
|
||||||
|
|
||||||
|
const char *GetTimerCaption( void ) { return m_szTimerCaption.Get(); }
|
||||||
|
|
||||||
|
int GetProgressBarMaxSegments( void ) { return m_nProgressBarMaxSegments; }
|
||||||
|
int GetProgressBarOverride( void ) { return m_nProgressBarOverride; }
|
||||||
|
|
||||||
|
bool OverridesPosition( void ) { return m_flOverrideX != -1.0f || m_flOverrideY != -1.0f; }
|
||||||
|
void GetPositionOverride( float &flX, float &flY ) { flX = m_flOverrideX; flY = m_flOverrideY; }
|
||||||
|
|
||||||
|
bool IsDisabled( void ) { return m_bIsDisabled; }
|
||||||
|
bool IsTimerPaused( void ) { return m_bTimerPaused; }
|
||||||
|
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
virtual void SetTimeRemaining( float flTime ); // Set the initial length of the timer
|
||||||
|
virtual void AddTimerSeconds( float flTimeToAdd ); // Add time to an already running ( or paused ) timer
|
||||||
|
virtual void OnTimerFinished();
|
||||||
|
virtual void OnTimerWarned();
|
||||||
|
virtual void PauseTimer( CBaseEntity *pActivator = NULL );
|
||||||
|
virtual void ResumeTimer( CBaseEntity *pActivator = NULL );
|
||||||
|
|
||||||
|
void SetProgressBarMaxSegments( int nSegments ) { m_nProgressBarMaxSegments = nSegments; }
|
||||||
|
void SetProgressBarOverride( int nSegments ) { m_nProgressBarOverride = nSegments; }
|
||||||
|
|
||||||
|
int UpdateTransmitState();
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
void InputEnable( inputdata_t &input );
|
||||||
|
void InputDisable( inputdata_t &input );
|
||||||
|
void InputPause( inputdata_t &input );
|
||||||
|
void InputResume( inputdata_t &input );
|
||||||
|
void InputSetTime( inputdata_t &input );
|
||||||
|
void InputAddTime( inputdata_t &input );
|
||||||
|
void InputRemoveTime( inputdata_t &input );
|
||||||
|
void InputRestart( inputdata_t &input );
|
||||||
|
void InputSetMaxTime( inputdata_t &input );
|
||||||
|
void InputSetTimerCaption( inputdata_t &input );
|
||||||
|
void InputSetProgressBarMaxSegments( inputdata_t &input );
|
||||||
|
void InputSetProgressBarOverride( inputdata_t &input );
|
||||||
|
void InputSetX( inputdata_t &input );
|
||||||
|
void InputSetY( inputdata_t &input );
|
||||||
|
void InputGetTimeRemaining( inputdata_t &input );
|
||||||
|
void InputSetPlayerFilter( inputdata_t &inputdata );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
void UpdateOnRemove( void );
|
||||||
|
#else
|
||||||
|
int ShouldTransmit( const CCheckTransmitInfo *pInfo );
|
||||||
|
void TimerThink( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CNetworkVar( bool, m_bIsDisabled );
|
||||||
|
CNetworkVar( float, m_flTimerInitialLength );
|
||||||
|
CNetworkVar( float, m_flTimerMaxLength );
|
||||||
|
CNetworkVar( float, m_flTimerEndTime );
|
||||||
|
CNetworkVar( float, m_flTimeRemaining );
|
||||||
|
CNetworkVar( float, m_flWarnTime ); // Time at which timer turns red, starts ticking loudly, etc.
|
||||||
|
CNetworkVar( int, m_nProgressBarMaxSegments ); // Overrides maximum segments in progress bar if greater than -1
|
||||||
|
CNetworkVar( int, m_nProgressBarOverride ); // Overrides progress bar value if greater than -1
|
||||||
|
CNetworkVar( float, m_flOverrideX );
|
||||||
|
CNetworkVar( float, m_flOverrideY );
|
||||||
|
CNetworkVar( bool, m_bTimerPaused );
|
||||||
|
CNetworkVar( bool, m_bStartPaused );
|
||||||
|
CNetworkVar( bool, m_bShowTimeRemaining );
|
||||||
|
CNetworkString( m_szTimerCaption, MAX_GAME_TIMER_CAPTION );
|
||||||
|
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
bool m_bOldDisabled;
|
||||||
|
#else
|
||||||
|
bool m_bStartedWarn;
|
||||||
|
bool m_bDisableOnFinish;
|
||||||
|
bool m_bShowInHUD; // TODO: ShowInHUD input? Would require client to know it shouldn't show the timer anymore
|
||||||
|
|
||||||
|
string_t m_iszPlayerFilterName;
|
||||||
|
CHandle<CBaseFilter> m_hPlayerFilter;
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
COutputEvent m_OnFinished;
|
||||||
|
COutputEvent m_OnPaused;
|
||||||
|
COutputEvent m_OnResumed;
|
||||||
|
COutputEvent m_OnWarned;
|
||||||
|
COutputInt m_OnTick;
|
||||||
|
COutputFloat m_OnGetTimeRemaining;
|
||||||
|
#endif
|
||||||
|
};
|
@ -27,6 +27,9 @@
|
|||||||
#include "datacache/imdlcache.h"
|
#include "datacache/imdlcache.h"
|
||||||
#ifdef CLIENT_DLL
|
#ifdef CLIENT_DLL
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#ifdef HL2MP
|
||||||
|
#include "c_hl2mp_player.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern ConVar mp_facefronttime, mp_feetyawrate;
|
extern ConVar mp_facefronttime, mp_feetyawrate;
|
||||||
@ -76,6 +79,13 @@ extern ConVar mp_facefronttime;
|
|||||||
|
|
||||||
CMapbasePlayerAnimState::CMapbasePlayerAnimState( CBasePlayer *pPlayer ): m_pPlayer( pPlayer )
|
CMapbasePlayerAnimState::CMapbasePlayerAnimState( CBasePlayer *pPlayer ): m_pPlayer( pPlayer )
|
||||||
{
|
{
|
||||||
|
if (pPlayer)
|
||||||
|
{
|
||||||
|
m_nPoseAimYaw = pPlayer->LookupPoseParameter( "aim_yaw" );
|
||||||
|
m_nPoseAimPitch = pPlayer->LookupPoseParameter( "aim_pitch" );
|
||||||
|
m_nPoseHeadPitch = pPlayer->LookupPoseParameter( "head_pitch" );
|
||||||
|
m_nPoseWeaponLower = pPlayer->LookupPoseParameter( "weapon_lower" );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -288,6 +298,14 @@ void CMapbasePlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr )
|
|||||||
ComputeReloadSequence();
|
ComputeReloadSequence();
|
||||||
ComputeWeaponSwitchSequence();
|
ComputeWeaponSwitchSequence();
|
||||||
ComputeRelaxSequence();
|
ComputeRelaxSequence();
|
||||||
|
|
||||||
|
#if defined(HL2MP) && defined(CLIENT_DLL)
|
||||||
|
C_HL2MP_Player *pHL2MPPlayer = static_cast<C_HL2MP_Player*>(GetOuter());
|
||||||
|
if (pHL2MPPlayer)
|
||||||
|
{
|
||||||
|
pHL2MPPlayer->UpdateLookAt();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -343,6 +361,7 @@ void CMapbasePlayerAnimState::ClearAnimationState()
|
|||||||
m_bReloading = false;
|
m_bReloading = false;
|
||||||
m_bWeaponSwitching = false;
|
m_bWeaponSwitching = false;
|
||||||
m_bWeaponRelaxing = false;
|
m_bWeaponRelaxing = false;
|
||||||
|
m_flWeaponRelaxAmount = 0.0f;
|
||||||
m_bPlayingMisc = false;
|
m_bPlayingMisc = false;
|
||||||
m_flReloadBlendIn = 0.0f;
|
m_flReloadBlendIn = 0.0f;
|
||||||
m_flReloadBlendOut = 0.0f;
|
m_flReloadBlendOut = 0.0f;
|
||||||
@ -527,7 +546,7 @@ void CMapbasePlayerAnimState::ComputeRelaxSequence()
|
|||||||
|
|
||||||
m_flWeaponRelaxAmount = clamp( m_flWeaponRelaxAmount, 0.0f, 1.0f );
|
m_flWeaponRelaxAmount = clamp( m_flWeaponRelaxAmount, 0.0f, 1.0f );
|
||||||
|
|
||||||
GetOuter()->SetPoseParameter( GetOuter()->LookupPoseParameter( "weapon_lower" ), m_flWeaponRelaxAmount );
|
GetOuter()->SetPoseParameter( m_nPoseWeaponLower, m_flWeaponRelaxAmount );
|
||||||
|
|
||||||
/*int nPose = GetOuter()->LookupPoseParameter( "weapon_lower" );
|
/*int nPose = GetOuter()->LookupPoseParameter( "weapon_lower" );
|
||||||
if (nPose != -1)
|
if (nPose != -1)
|
||||||
@ -548,7 +567,7 @@ void CMapbasePlayerAnimState::ComputeRelaxSequence()
|
|||||||
}
|
}
|
||||||
else if (bRelaxing)
|
else if (bRelaxing)
|
||||||
{
|
{
|
||||||
GetOuter()->SetPoseParameter( GetOuter()->LookupPoseParameter( "weapon_lower" ), 1.0f );
|
GetOuter()->SetPoseParameter( m_nPoseWeaponLower, 1.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*bool bEnabled = m_bWeaponRelaxing;
|
/*bool bEnabled = m_bWeaponRelaxing;
|
||||||
@ -646,7 +665,7 @@ float CMapbasePlayerAnimState::SetOuterBodyYaw( float flValue )
|
|||||||
{
|
{
|
||||||
float flAimPoseBlend = GetAimPoseBlend();
|
float flAimPoseBlend = GetAimPoseBlend();
|
||||||
|
|
||||||
GetOuter()->SetPoseParameter( GetOuter()->LookupPoseParameter( "aim_yaw" ), flValue * flAimPoseBlend );
|
GetOuter()->SetPoseParameter( m_nPoseAimYaw, flValue * flAimPoseBlend );
|
||||||
return CBasePlayerAnimState::SetOuterBodyYaw( flValue * (1.0f - flAimPoseBlend) );
|
return CBasePlayerAnimState::SetOuterBodyYaw( flValue * (1.0f - flAimPoseBlend) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,7 +686,7 @@ void CMapbasePlayerAnimState::ComputePoseParam_BodyYaw( void )
|
|||||||
void CMapbasePlayerAnimState::ComputePoseParam_BodyLookYaw( void )
|
void CMapbasePlayerAnimState::ComputePoseParam_BodyLookYaw( void )
|
||||||
{
|
{
|
||||||
// See if we even have a blender for pitch
|
// See if we even have a blender for pitch
|
||||||
int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" );
|
int upper_body_yaw = m_nPoseAimYaw;
|
||||||
if ( upper_body_yaw < 0 )
|
if ( upper_body_yaw < 0 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -815,8 +834,10 @@ void CMapbasePlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr
|
|||||||
//float flAimPoseBlend = GetAimPoseBlend();
|
//float flAimPoseBlend = GetAimPoseBlend();
|
||||||
|
|
||||||
// See if we have a blender for pitch
|
// See if we have a blender for pitch
|
||||||
GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch );
|
if (m_nPoseAimPitch >= 0)
|
||||||
GetOuter()->SetPoseParameter( pStudioHdr, "head_pitch", flPitch );
|
GetOuter()->SetPoseParameter( pStudioHdr, m_nPoseAimPitch, flPitch );
|
||||||
|
if (m_nPoseHeadPitch >= 0)
|
||||||
|
GetOuter()->SetPoseParameter( pStudioHdr, m_nPoseHeadPitch, flPitch );
|
||||||
|
|
||||||
//ComputePoseParam_HeadPitch( pStudioHdr );
|
//ComputePoseParam_HeadPitch( pStudioHdr );
|
||||||
}
|
}
|
||||||
@ -826,9 +847,6 @@ void CMapbasePlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CMapbasePlayerAnimState::ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr )
|
void CMapbasePlayerAnimState::ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr )
|
||||||
{
|
{
|
||||||
// Get pitch from v_angle
|
|
||||||
int iHeadPitch = GetOuter()->LookupPoseParameter("head_pitch");
|
|
||||||
|
|
||||||
float flPitch = m_flEyePitch;
|
float flPitch = m_flEyePitch;
|
||||||
|
|
||||||
if ( flPitch > 180.0f )
|
if ( flPitch > 180.0f )
|
||||||
@ -837,5 +855,5 @@ void CMapbasePlayerAnimState::ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr
|
|||||||
}
|
}
|
||||||
flPitch = clamp( flPitch, -90, 90 );
|
flPitch = clamp( flPitch, -90, 90 );
|
||||||
|
|
||||||
GetOuter()->SetPoseParameter( pStudioHdr, iHeadPitch, flPitch );
|
GetOuter()->SetPoseParameter( pStudioHdr, m_nPoseHeadPitch, flPitch );
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,8 @@ private:
|
|||||||
// until it completes.
|
// until it completes.
|
||||||
int m_iFireSequence; // (For any sequences in the fire layer, including grenade throw).
|
int m_iFireSequence; // (For any sequences in the fire layer, including grenade throw).
|
||||||
float m_flFireCycle;
|
float m_flFireCycle;
|
||||||
|
|
||||||
|
int m_nPoseAimYaw, m_nPoseAimPitch, m_nPoseHeadPitch, m_nPoseWeaponLower;
|
||||||
};
|
};
|
||||||
|
|
||||||
CMapbasePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer );
|
CMapbasePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer );
|
||||||
|
@ -20,6 +20,8 @@ void HookMapbaseUserMessages( void )
|
|||||||
{
|
{
|
||||||
// VScript
|
// VScript
|
||||||
//HOOK_MESSAGE( ScriptMsg ); // Hooked in CNetMsgScriptHelper
|
//HOOK_MESSAGE( ScriptMsg ); // Hooked in CNetMsgScriptHelper
|
||||||
|
|
||||||
|
//HOOK_MESSAGE( ShowMenuComplex ); // Hooked in CHudMenu
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -28,6 +30,8 @@ void RegisterMapbaseUserMessages( void )
|
|||||||
// VScript
|
// VScript
|
||||||
usermessages->Register( "ScriptMsg", -1 ); // CNetMsgScriptHelper
|
usermessages->Register( "ScriptMsg", -1 ); // CNetMsgScriptHelper
|
||||||
|
|
||||||
|
usermessages->Register( "ShowMenuComplex", -1 ); // CHudMenu
|
||||||
|
|
||||||
#ifdef CLIENT_DLL
|
#ifdef CLIENT_DLL
|
||||||
// TODO: Better placement?
|
// TODO: Better placement?
|
||||||
HookMapbaseUserMessages();
|
HookMapbaseUserMessages();
|
||||||
|
@ -176,11 +176,11 @@ void CProtagonistSystem::LoadProtagonistFile( const char *pszFile )
|
|||||||
else if (FStrEq( pszSubKeyName, "team" ))
|
else if (FStrEq( pszSubKeyName, "team" ))
|
||||||
{
|
{
|
||||||
#ifdef HL2MP
|
#ifdef HL2MP
|
||||||
if (FStrEq( pszSubKeyName, "combine" ))
|
if (FStrEq( pSubKey->GetString(), "combine" ))
|
||||||
{
|
{
|
||||||
pProtag->nTeam = TEAM_COMBINE;
|
pProtag->nTeam = TEAM_COMBINE;
|
||||||
}
|
}
|
||||||
else if (FStrEq( pszSubKeyName, "rebels" ))
|
else if (FStrEq( pSubKey->GetString(), "rebels" ))
|
||||||
{
|
{
|
||||||
pProtag->nTeam = TEAM_REBELS;
|
pProtag->nTeam = TEAM_REBELS;
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ void CProtagonistSystem::LoadProtagonistFile( const char *pszFile )
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Try to get a direct integer
|
// Try to get a direct integer
|
||||||
pProtag->nTeam = atoi( pszSubKeyName );
|
pProtag->nTeam = atoi( pSubKey->GetString() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -335,6 +335,12 @@ void CProtagonistSystem::PrecacheProtagonist( CBaseEntity *pSource, int nIdx )
|
|||||||
|
|
||||||
ProtagonistData_t &pProtag = m_Protagonists[nIdx];
|
ProtagonistData_t &pProtag = m_Protagonists[nIdx];
|
||||||
|
|
||||||
|
// Don't if it's already precached
|
||||||
|
if (pProtag.bPrecached)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CBaseEntity::SetAllowPrecache( true );
|
||||||
|
|
||||||
// Playermodel
|
// Playermodel
|
||||||
if (pProtag.pszPlayerModel)
|
if (pProtag.pszPlayerModel)
|
||||||
{
|
{
|
||||||
@ -358,6 +364,16 @@ void CProtagonistSystem::PrecacheProtagonist( CBaseEntity *pSource, int nIdx )
|
|||||||
pSource->PrecacheModel( pProtag.dictWpnData[i].pszVM );
|
pSource->PrecacheModel( pProtag.dictWpnData[i].pszVM );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CBaseEntity::SetAllowPrecache( false );
|
||||||
|
|
||||||
|
// Precache parents
|
||||||
|
FOR_EACH_VEC( pProtag.vecParents, i )
|
||||||
|
{
|
||||||
|
PrecacheProtagonist( pSource, pProtag.vecParents[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
pProtag.bPrecached = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +432,6 @@ GetProtagParamBody( ResponseContexts, bool, GetProtagParamInner( ResponseConte
|
|||||||
int nLast = V_strlen( pszContexts )-1;
|
int nLast = V_strlen( pszContexts )-1;
|
||||||
if (pszContexts[nLast] == ',')
|
if (pszContexts[nLast] == ',')
|
||||||
{
|
{
|
||||||
Msg( "Removing trailing comma from \"%s\"\n", pszContexts );
|
|
||||||
pszContexts[nLast] = '\0';
|
pszContexts[nLast] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,6 +696,11 @@ void CProtagonistSystem::PrintProtagonistData()
|
|||||||
if (pProtag.pszPlayerModel)
|
if (pProtag.pszPlayerModel)
|
||||||
Msg( "\t\tPlayer model: \"%s\" (%i, %i)\n", pProtag.pszPlayerModel, pProtag.nPlayerSkin, pProtag.nPlayerBody );
|
Msg( "\t\tPlayer model: \"%s\" (%i, %i)\n", pProtag.pszPlayerModel, pProtag.nPlayerSkin, pProtag.nPlayerBody );
|
||||||
|
|
||||||
|
#ifdef HL2MP
|
||||||
|
if ( pProtag.nTeam != TEAM_ANY )
|
||||||
|
Msg( "\t\tTeam: %i\n", pProtag.nTeam );
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int j = 0; j < NUM_HAND_RIG_TYPES; j++)
|
for (int j = 0; j < NUM_HAND_RIG_TYPES; j++)
|
||||||
{
|
{
|
||||||
extern const char *pHandRigs[NUM_HAND_RIG_TYPES];
|
extern const char *pHandRigs[NUM_HAND_RIG_TYPES];
|
||||||
|
@ -61,6 +61,9 @@ private:
|
|||||||
|
|
||||||
// Multiplayer
|
// Multiplayer
|
||||||
int nTeam = TEAM_ANY;
|
int nTeam = TEAM_ANY;
|
||||||
|
|
||||||
|
// Precached (used by system, not actual data)
|
||||||
|
bool bPrecached = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Weapon Data
|
// Weapon Data
|
||||||
|
@ -1244,17 +1244,20 @@ public:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pInfo->datatype == types::_VEC3 )
|
unsigned int arraysize = pInfo->arraysize;
|
||||||
index /= 3;
|
|
||||||
|
|
||||||
if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
|
if ( pInfo->datatype == types::_VEC3 )
|
||||||
|
arraysize *= 3;
|
||||||
|
|
||||||
|
if ( index < 0 || (unsigned int)index >= arraysize )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
switch ( pInfo->datatype )
|
switch ( pInfo->datatype )
|
||||||
{
|
{
|
||||||
case types::_VEC3:
|
|
||||||
case types::_FLOAT:
|
case types::_FLOAT:
|
||||||
return *(float*)((char*)pEnt + pInfo->GetOffset( index ));
|
return *(float*)((char*)pEnt + pInfo->GetOffset( index ));
|
||||||
|
case types::_VEC3:
|
||||||
|
return ((float*)((char*)pEnt + pInfo->GetOffset( index / 3 )))[ index % 3 ];
|
||||||
#ifdef GAME_DLL
|
#ifdef GAME_DLL
|
||||||
case types::_DAR_FLOAT:
|
case types::_DAR_FLOAT:
|
||||||
{
|
{
|
||||||
@ -1286,19 +1289,24 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pInfo->datatype == types::_VEC3 )
|
unsigned int arraysize = pInfo->arraysize;
|
||||||
index /= 3;
|
|
||||||
|
|
||||||
if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
|
if ( pInfo->datatype == types::_VEC3 )
|
||||||
|
arraysize *= 3;
|
||||||
|
|
||||||
|
if ( index < 0 || (unsigned int)index >= arraysize )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch ( pInfo->datatype )
|
switch ( pInfo->datatype )
|
||||||
{
|
{
|
||||||
case types::_VEC3:
|
|
||||||
case types::_FLOAT:
|
case types::_FLOAT:
|
||||||
*(float*)((char*)pEnt + pInfo->GetOffset( index )) = value;
|
*(float*)((char*)pEnt + pInfo->GetOffset( index )) = value;
|
||||||
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
|
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
|
||||||
break;
|
break;
|
||||||
|
case types::_VEC3:
|
||||||
|
((float*)((char*)pEnt + pInfo->GetOffset( index / 3 )))[ index % 3 ] = value;
|
||||||
|
NetworkStateChanged( pEnt, pInfo->GetOffset( index / 3 ) );
|
||||||
|
break;
|
||||||
#ifdef GAME_DLL
|
#ifdef GAME_DLL
|
||||||
case types::_DAR_FLOAT:
|
case types::_DAR_FLOAT:
|
||||||
{
|
{
|
||||||
@ -5138,6 +5146,11 @@ bool CScriptConvarAccessor::Init()
|
|||||||
AddBlockedConVar( "cl_allowdownload" );
|
AddBlockedConVar( "cl_allowdownload" );
|
||||||
AddBlockedConVar( "cl_allowupload" );
|
AddBlockedConVar( "cl_allowupload" );
|
||||||
AddBlockedConVar( "cl_downloadfilter" );
|
AddBlockedConVar( "cl_downloadfilter" );
|
||||||
|
#ifdef GAME_DLL
|
||||||
|
AddBlockedConVar( "script_connect_debugger_on_mapspawn" );
|
||||||
|
#else
|
||||||
|
AddBlockedConVar( "script_connect_debugger_on_mapspawn_client" );
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,6 @@ private:
|
|||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
// This is to ensure a dependency exists between the vscript library and the game DLLs
|
// This is to ensure a dependency exists between the vscript library and the game DLLs
|
||||||
extern int vscript_token;
|
extern int vscript_token;
|
||||||
extern int vscript_debugger_port;
|
|
||||||
int vscript_token_hack = vscript_token;
|
int vscript_token_hack = vscript_token;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -454,27 +453,14 @@ CON_COMMAND( script_debug, "Connect the vscript VM to the script debugger" )
|
|||||||
if ( !IsCommandIssuedByServerAdmin() )
|
if ( !IsCommandIssuedByServerAdmin() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
|
||||||
#ifdef GAME_DLL
|
|
||||||
int port = 1212;
|
|
||||||
#else
|
|
||||||
int port = 1213;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( !g_pScriptVM )
|
if ( !g_pScriptVM )
|
||||||
{
|
{
|
||||||
#ifdef MAPBASE_VSCRIPT
|
|
||||||
vscript_debugger_port = port;
|
|
||||||
CGMsg( 0, CON_GROUP_VSCRIPT, "VScript VM is not running, waiting for it to attach the debugger to port %d...\n", port );
|
|
||||||
#else
|
|
||||||
Log_Warning( LOG_VScript, "Scripting disabled or no server running\n" );
|
Log_Warning( LOG_VScript, "Scripting disabled or no server running\n" );
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
g_pScriptVM->ConnectDebugger( port );
|
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
||||||
#else
|
#else
|
||||||
g_pScriptVM->ConnectDebugger();
|
g_pScriptVM->ConnectDebugger();
|
||||||
#endif
|
#endif
|
||||||
|
@ -191,6 +191,12 @@ class CBaseEntityScriptInstanceHelper : public IScriptInstanceHelper
|
|||||||
extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
|
#ifdef GAME_DLL
|
||||||
|
const int vscript_debugger_port = 1212;
|
||||||
|
#else
|
||||||
|
const int vscript_debugger_port = 1213;
|
||||||
|
#endif
|
||||||
|
|
||||||
void RegisterSharedScriptConstants();
|
void RegisterSharedScriptConstants();
|
||||||
void RegisterSharedScriptFunctions();
|
void RegisterSharedScriptFunctions();
|
||||||
|
|
||||||
|
@ -811,8 +811,8 @@ void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar**
|
|||||||
(params[info.m_nBlendModulateTexture]->IsTexture() );
|
(params[info.m_nBlendModulateTexture]->IsTexture() );
|
||||||
bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
|
bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
|
||||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||||
// Parallax cubemaps
|
// Parallax cubemaps. Check for envmap because if we don't, white splotchs can appear at certain viewing angles when mat_specular is 0.
|
||||||
bool hasParallaxCorrection = params[info.m_nEnvmapParallax]->GetIntValue() > 0;
|
bool hasParallaxCorrection = params[info.m_nEnvmap]->IsDefined() && params[info.m_nEnvmapParallax]->GetIntValue() > 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( hasFlashlight && !IsX360() )
|
if ( hasFlashlight && !IsX360() )
|
||||||
|
@ -229,6 +229,8 @@ union ScriptVariantTemporaryStorage_t
|
|||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
struct ScriptClassDesc_t;
|
||||||
|
|
||||||
struct ScriptFuncDescriptor_t
|
struct ScriptFuncDescriptor_t
|
||||||
{
|
{
|
||||||
ScriptFuncDescriptor_t()
|
ScriptFuncDescriptor_t()
|
||||||
@ -237,11 +239,13 @@ struct ScriptFuncDescriptor_t
|
|||||||
m_pszFunction = NULL;
|
m_pszFunction = NULL;
|
||||||
m_ReturnType = FIELD_TYPEUNKNOWN;
|
m_ReturnType = FIELD_TYPEUNKNOWN;
|
||||||
m_pszDescription = NULL;
|
m_pszDescription = NULL;
|
||||||
|
m_pScriptClassDesc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *m_pszScriptName;
|
const char *m_pszScriptName;
|
||||||
const char *m_pszFunction;
|
const char *m_pszFunction;
|
||||||
const char *m_pszDescription;
|
const char *m_pszDescription;
|
||||||
|
ScriptClassDesc_t *m_pScriptClassDesc;
|
||||||
ScriptDataType_t m_ReturnType;
|
ScriptDataType_t m_ReturnType;
|
||||||
CUtlVector<ScriptDataType_t> m_Parameters;
|
CUtlVector<ScriptDataType_t> m_Parameters;
|
||||||
};
|
};
|
||||||
@ -751,7 +755,7 @@ public:
|
|||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
virtual bool ConnectDebugger( int port = 0 ) = 0;
|
virtual bool ConnectDebugger( int port = 0, float timeout = 0.0f ) = 0;
|
||||||
#else
|
#else
|
||||||
virtual bool ConnectDebugger() = 0;
|
virtual bool ConnectDebugger() = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,7 +61,7 @@ FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_TYPE_DEDUCER );
|
|||||||
|
|
||||||
FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER );
|
FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER );
|
||||||
|
|
||||||
#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); }
|
#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); (pDesc)->m_pScriptClassDesc = GetScriptDesc<class>(nullptr); }
|
||||||
|
|
||||||
#define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); }
|
#define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); }
|
||||||
#define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func )
|
#define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func )
|
||||||
|
@ -112,7 +112,11 @@ WIN32
|
|||||||
===================================================================
|
===================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
int numthreads = -(MAX_TOOL_THREADS + 1);
|
||||||
|
#else
|
||||||
int numthreads = -1;
|
int numthreads = -1;
|
||||||
|
#endif
|
||||||
CRITICAL_SECTION crit;
|
CRITICAL_SECTION crit;
|
||||||
static int enter;
|
static int enter;
|
||||||
|
|
||||||
@ -133,19 +137,37 @@ void SetLowPriority()
|
|||||||
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
|
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Threads can be negative; if so, they will be subtracted from the total thread count.
|
||||||
void ThreadSetDefault (void)
|
void ThreadSetDefault (void)
|
||||||
{
|
{
|
||||||
SYSTEM_INFO info;
|
SYSTEM_INFO info;
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if (numthreads == -(MAX_TOOL_THREADS + 1)) // not set manually
|
||||||
|
#else
|
||||||
if (numthreads == -1) // not set manually
|
if (numthreads == -1) // not set manually
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
GetSystemInfo (&info);
|
GetSystemInfo (&info);
|
||||||
numthreads = info.dwNumberOfProcessors;
|
numthreads = info.dwNumberOfProcessors;
|
||||||
if (numthreads < 1 || numthreads > 32)
|
#ifdef MAPBASE
|
||||||
|
if (numthreads > 32)
|
||||||
|
#else
|
||||||
|
if (numthreads < 1 ||numthreads > 32)
|
||||||
|
#endif
|
||||||
numthreads = 1;
|
numthreads = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if (numthreads <= 0)
|
||||||
|
{
|
||||||
|
GetSystemInfo(&info);
|
||||||
|
numthreads = info.dwNumberOfProcessors + numthreads;
|
||||||
|
if (numthreads <= 0)
|
||||||
|
Error("\nIncrease the number of threads! Threads: %i, they cannot be negative or 0.\n", numthreads);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Msg ("%i threads\n", numthreads);
|
Msg ("%i threads\n", numthreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "fgdlib/fgdlib.h"
|
#include "fgdlib/fgdlib.h"
|
||||||
#include "manifest.h"
|
#include "manifest.h"
|
||||||
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
#ifdef PARALLAX_CORRECTED_CUBEMAPS
|
||||||
#include "matrixinvert.h"
|
#include "mathlib/vmatrix.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
#include "vscript_vbsp.h"
|
#include "vscript_vbsp.h"
|
||||||
@ -1657,9 +1657,11 @@ ChunkFileResult_t CMapFile::LoadEntityCallback(CChunkFile *pFile, int nParam)
|
|||||||
//
|
//
|
||||||
if (!strcmp("parallax_obb", pClassName))
|
if (!strcmp("parallax_obb", pClassName))
|
||||||
{
|
{
|
||||||
matrix3x4_t obbMatrix, invObbMatrix;
|
//Originally was matrix3x2. Now we use built-in functions to the engine instead of a custom invert matrix
|
||||||
SetIdentityMatrix(obbMatrix);
|
VMatrix obbMatrix, invObbMatrix;
|
||||||
SetIdentityMatrix(invObbMatrix);
|
MatrixSetIdentity(obbMatrix);
|
||||||
|
MatrixSetIdentity(invObbMatrix);
|
||||||
|
|
||||||
|
|
||||||
// Get corner and its 3 edges (scaled, local x, y, and z axes)
|
// Get corner and its 3 edges (scaled, local x, y, and z axes)
|
||||||
mapbrush_t *brush = &mapbrushes[mapent->firstbrush];
|
mapbrush_t *brush = &mapbrushes[mapent->firstbrush];
|
||||||
@ -1714,13 +1716,15 @@ ChunkFileResult_t CMapFile::LoadEntityCallback(CChunkFile *pFile, int nParam)
|
|||||||
x *= abs(DotProduct(diag, x));
|
x *= abs(DotProduct(diag, x));
|
||||||
|
|
||||||
// Build transformation matrix (what is needed to turn a [0,0,0] - [1,1,1] cube into this brush)
|
// Build transformation matrix (what is needed to turn a [0,0,0] - [1,1,1] cube into this brush)
|
||||||
MatrixSetColumn(x, 0, obbMatrix);
|
//Originally was MatrixSetColum. Since we use VMatrix now, changed to obbMatrix
|
||||||
MatrixSetColumn(y, 1, obbMatrix);
|
obbMatrix.SetForward(x);
|
||||||
MatrixSetColumn(z, 2, obbMatrix);
|
obbMatrix.SetLeft(y);
|
||||||
MatrixSetColumn(corner, 3, obbMatrix);
|
obbMatrix.SetUp(z);
|
||||||
|
obbMatrix.SetTranslation(corner);
|
||||||
|
|
||||||
//find inverse (we need the world to local matrix, "transformationmatrix" is kind of a misnomer)
|
//find inverse (we need the world to local matrix, "transformationmatrix" is kind of a misnomer)
|
||||||
MatrixInversion(obbMatrix, invObbMatrix);
|
//Originally was MatrixInversion. This is now using the built in functions, not relying on MatrixInversion and matrixinvert.h anymore
|
||||||
|
MatrixInverseGeneral(obbMatrix, invObbMatrix);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
// By Jason Yu-Tseh Chi
|
|
||||||
// From http://chi3x10.wordpress.com/2008/05/28/calculate-matrix-inversion-in-c/
|
|
||||||
// Modified to work with valve's matrix_3x4_t
|
|
||||||
|
|
||||||
#include "mathlib\mathlib.h"
|
|
||||||
|
|
||||||
// Calculate the cofactor of element (row,col)
|
|
||||||
int GetMatrixMinor(float **src, float **dest, int row, int col, int order)
|
|
||||||
{
|
|
||||||
// Indicate which col and row is being copied to dest
|
|
||||||
int colCount = 0, rowCount = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < order; i++)
|
|
||||||
{
|
|
||||||
if (i != row)
|
|
||||||
{
|
|
||||||
colCount = 0;
|
|
||||||
for (int j = 0; j < order; j++)
|
|
||||||
{
|
|
||||||
// When j is not the element
|
|
||||||
if (j != col)
|
|
||||||
{
|
|
||||||
dest[rowCount][colCount] = src[i][j];
|
|
||||||
colCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rowCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the determinant recursively.
|
|
||||||
double CalcMatrixDeterminant(float **mat, int order)
|
|
||||||
{
|
|
||||||
// Order must be >= 0
|
|
||||||
// Stop the recursion when matrix is a single element
|
|
||||||
if (order == 1)
|
|
||||||
return mat[0][0];
|
|
||||||
|
|
||||||
// The determinant value
|
|
||||||
float det = 0;
|
|
||||||
|
|
||||||
// Allocate the cofactor matrix
|
|
||||||
float **minor;
|
|
||||||
minor = new float*[order - 1];
|
|
||||||
for (int i = 0; i<order - 1; i++)
|
|
||||||
minor[i] = new float[order - 1];
|
|
||||||
|
|
||||||
for (int i = 0; i < order; i++)
|
|
||||||
{
|
|
||||||
// Get minor of element (0,i)
|
|
||||||
GetMatrixMinor(mat, minor, 0, i, order);
|
|
||||||
// The recusion is here!
|
|
||||||
|
|
||||||
det += (i % 2 == 1 ? -1.0 : 1.0) * mat[0][i] * CalcMatrixDeterminant(minor, order - 1);
|
|
||||||
//det += pow( -1.0, i ) * mat[0][i] * CalcMatrixDeterminant( minor,order-1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release memory
|
|
||||||
for (int i = 0; i<order - 1; i++)
|
|
||||||
delete[] minor[i];
|
|
||||||
delete[] minor;
|
|
||||||
|
|
||||||
return det;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matrix inversion
|
|
||||||
void MatrixInversion(matrix3x4_t &in, matrix3x4_t &out)
|
|
||||||
{
|
|
||||||
float **A;
|
|
||||||
A = new float*[4];
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
A[i] = new float[4];
|
|
||||||
int order = 4;
|
|
||||||
|
|
||||||
// Load in into A
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 4; j++)
|
|
||||||
{
|
|
||||||
A[i][j] = in[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
A[3][0] = A[3][1] = A[3][2] = 0;
|
|
||||||
A[3][3] = 1;
|
|
||||||
|
|
||||||
// Get the determinant of a
|
|
||||||
double det = 1.0 / CalcMatrixDeterminant((float**)A, order);
|
|
||||||
|
|
||||||
// Memory allocation
|
|
||||||
float *temp = new float[(order - 1)*(order - 1)];
|
|
||||||
float **minor = new float*[order - 1];
|
|
||||||
for (int i = 0; i<order - 1; i++)
|
|
||||||
minor[i] = temp + (i*(order - 1));
|
|
||||||
|
|
||||||
for (int j = 0; j<order; j++)
|
|
||||||
{
|
|
||||||
for (int i = 0; i<order; i++)
|
|
||||||
{
|
|
||||||
// Get the co-factor (matrix) of A(j,i)
|
|
||||||
GetMatrixMinor((float**)A, minor, j, i, order);
|
|
||||||
out[i][j] = det*CalcMatrixDeterminant(minor, order - 1);
|
|
||||||
if ((i + j) % 2 == 1)
|
|
||||||
out[i][j] = -out[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release memory
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
delete A[i];
|
|
||||||
delete A;
|
|
||||||
//delete [] minor[0];
|
|
||||||
delete[] temp;
|
|
||||||
delete[] minor;
|
|
||||||
}
|
|
@ -65,6 +65,7 @@ bool g_NodrawTriggers = false;
|
|||||||
bool g_DisableWaterLighting = false;
|
bool g_DisableWaterLighting = false;
|
||||||
bool g_bAllowDetailCracks = false;
|
bool g_bAllowDetailCracks = false;
|
||||||
bool g_bNoVirtualMesh = false;
|
bool g_bNoVirtualMesh = false;
|
||||||
|
bool g_bNoHiddenManifestMaps = false;
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
bool g_bNoDefaultCubemaps = true;
|
bool g_bNoDefaultCubemaps = true;
|
||||||
bool g_bSkyboxCubemaps = false;
|
bool g_bSkyboxCubemaps = false;
|
||||||
@ -1175,6 +1176,10 @@ int RunVBSP( int argc, char **argv )
|
|||||||
{
|
{
|
||||||
EnableFullMinidumps( true );
|
EnableFullMinidumps( true );
|
||||||
}
|
}
|
||||||
|
else if ( !Q_stricmp( argv[i], "-nohiddenmaps" ) )
|
||||||
|
{
|
||||||
|
g_bNoHiddenManifestMaps = true;
|
||||||
|
}
|
||||||
else if ( !Q_stricmp( argv[i], "-embed" ) && i < argc - 1 )
|
else if ( !Q_stricmp( argv[i], "-embed" ) && i < argc - 1 )
|
||||||
{
|
{
|
||||||
V_MakeAbsolutePath( g_szEmbedDir, sizeof( g_szEmbedDir ), argv[++i], "." );
|
V_MakeAbsolutePath( g_szEmbedDir, sizeof( g_szEmbedDir ), argv[++i], "." );
|
||||||
@ -1285,6 +1290,7 @@ int RunVBSP( int argc, char **argv )
|
|||||||
CmdLib_Cleanup();
|
CmdLib_Cleanup();
|
||||||
CmdLib_Exit( 1 );
|
CmdLib_Exit( 1 );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (argv[i][0] == '-')
|
else if (argv[i][0] == '-')
|
||||||
{
|
{
|
||||||
Warning("VBSP: Unknown option \"%s\"\n\n", argv[i]);
|
Warning("VBSP: Unknown option \"%s\"\n\n", argv[i]);
|
||||||
@ -1331,8 +1337,9 @@ int RunVBSP( int argc, char **argv )
|
|||||||
Warning(
|
Warning(
|
||||||
"Other options :\n"
|
"Other options :\n"
|
||||||
" -novconfig : Don't bring up graphical UI on vproject errors.\n"
|
" -novconfig : Don't bring up graphical UI on vproject errors.\n"
|
||||||
" -threads : Control the number of threads vbsp uses (defaults to the # of\n"
|
" -threads # : Control the number of threads vbsp uses (defaults to the #\n"
|
||||||
" processors on your machine).\n"
|
" or processors on your machine).\n"
|
||||||
|
" Threads can be negative; if so, they will be subtracted from the total thread count.\n"
|
||||||
" -verboseentities: If -v is on, this disables verbose output for submodels.\n"
|
" -verboseentities: If -v is on, this disables verbose output for submodels.\n"
|
||||||
" -noweld : Don't join face vertices together.\n"
|
" -noweld : Don't join face vertices together.\n"
|
||||||
" -nocsg : Don't chop out intersecting brush areas.\n"
|
" -nocsg : Don't chop out intersecting brush areas.\n"
|
||||||
|
@ -2467,11 +2467,13 @@ int ParseCommandLine( int argc, char **argv, bool *onlydetail )
|
|||||||
if ( ++i < argc )
|
if ( ++i < argc )
|
||||||
{
|
{
|
||||||
numthreads = atoi (argv[i]);
|
numthreads = atoi (argv[i]);
|
||||||
|
#ifndef MAPBASE //Mapbase allows threads to be negative, go to ThreadSetDefault(void) in threads.cpp for a explanation.
|
||||||
if ( numthreads <= 0 )
|
if ( numthreads <= 0 )
|
||||||
{
|
{
|
||||||
Warning("Error: expected positive value after '-threads'\n" );
|
Warning("Error: expected positive value after '-threads'\n" );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2871,8 +2873,9 @@ void PrintUsage( int argc, char **argv )
|
|||||||
" -dump : Write debugging .txt files.\n"
|
" -dump : Write debugging .txt files.\n"
|
||||||
" -dumpnormals : Write normals to debug files.\n"
|
" -dumpnormals : Write normals to debug files.\n"
|
||||||
" -dumptrace : Write ray-tracing environment to debug files.\n"
|
" -dumptrace : Write ray-tracing environment to debug files.\n"
|
||||||
" -threads : Control the number of threads vbsp uses (defaults to the #\n"
|
" -threads # : Control the number of threads vrad uses (defaults to the #\n"
|
||||||
" or processors on your machine).\n"
|
" or processors on your machine).\n"
|
||||||
|
" Threads can be negative; if so, they will be subtracted from the total thread count.\n"
|
||||||
" -lights <file> : Load a lights file in addition to lights.rad and the\n"
|
" -lights <file> : Load a lights file in addition to lights.rad and the\n"
|
||||||
" level lights file.\n"
|
" level lights file.\n"
|
||||||
" -noextra : Disable supersampling.\n"
|
" -noextra : Disable supersampling.\n"
|
||||||
|
@ -703,9 +703,13 @@ public:
|
|||||||
if ( pVMT->LoadFromBuffer( pMaterialName, buf ) )
|
if ( pVMT->LoadFromBuffer( pMaterialName, buf ) )
|
||||||
{
|
{
|
||||||
bFound = true;
|
bFound = true;
|
||||||
if ( pVMT->FindKey("$translucent") || pVMT->FindKey("$alphatest") )
|
KeyValues *pBaseTexture = pVMT->FindKey("%alphatexture");
|
||||||
|
if ( pBaseTexture || pVMT->FindKey("$alphatest") || pVMT->FindKey("$translucent") )
|
||||||
{
|
{
|
||||||
KeyValues *pBaseTexture = pVMT->FindKey("$basetexture");
|
if ( !pBaseTexture )
|
||||||
|
{
|
||||||
|
pBaseTexture = pVMT->FindKey("$basetexture");
|
||||||
|
}
|
||||||
if ( pBaseTexture )
|
if ( pBaseTexture )
|
||||||
{
|
{
|
||||||
const char *pBaseTextureName = pBaseTexture->GetString();
|
const char *pBaseTextureName = pBaseTexture->GetString();
|
||||||
|
@ -1039,8 +1039,9 @@ void PrintUsage( int argc, char **argv )
|
|||||||
#ifdef MPI
|
#ifdef MPI
|
||||||
" -mpi_pw <pw> : Use a password to choose a specific set of VMPI workers.\n"
|
" -mpi_pw <pw> : Use a password to choose a specific set of VMPI workers.\n"
|
||||||
#endif
|
#endif
|
||||||
" -threads : Control the number of threads vbsp uses (defaults to the #\n"
|
" -threads # : Control the number of threads vvis uses (defaults to the #\n"
|
||||||
" or processors on your machine).\n"
|
" or processors on your machine).\n"
|
||||||
|
" Threads can be negative; if so, they will be subtracted from the total thread count.\n"
|
||||||
" -nosort : Don't sort portals (sorting is an optimization).\n"
|
" -nosort : Don't sort portals (sorting is an optimization).\n"
|
||||||
" -tmpin : Make portals come from \\tmp\\<mapname>.\n"
|
" -tmpin : Make portals come from \\tmp\\<mapname>.\n"
|
||||||
" -tmpout : Make portals come from \\tmp\\<mapname>.\n"
|
" -tmpout : Make portals come from \\tmp\\<mapname>.\n"
|
||||||
|
19
src/vscript/sqdbg/LICENSE
Normal file
19
src/vscript/sqdbg/LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) samisalreadytaken
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@ -60,9 +60,14 @@ SQDBG_API int sqdbg_listen_socket( HSQDEBUGSERVER dbg, unsigned short port );
|
|||||||
SQDBG_API void sqdbg_frame( HSQDEBUGSERVER dbg );
|
SQDBG_API void sqdbg_frame( HSQDEBUGSERVER dbg );
|
||||||
|
|
||||||
// Copies the script to be able to source it to debugger clients
|
// Copies the script to be able to source it to debugger clients
|
||||||
SQDBG_API void sqdbg_on_script_compile( HSQDEBUGSERVER dbg, const SQChar *script, SQInteger size,
|
SQDBG_API void sqdbg_on_script_compile( HSQDEBUGSERVER dbg,
|
||||||
|
const SQChar *script, SQInteger scriptlen,
|
||||||
const SQChar *sourcename, SQInteger sourcenamelen );
|
const SQChar *sourcename, SQInteger sourcenamelen );
|
||||||
|
|
||||||
|
// Check if a client is connected to the debugger
|
||||||
|
// Returns 0 if there is no client connected
|
||||||
|
SQDBG_API int sqdbg_is_client_connected( HSQDEBUGSERVER dbg );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
} while(0)
|
} while(0)
|
||||||
#endif
|
#endif
|
||||||
#define Verify( x ) Assert(x)
|
#define Verify( x ) Assert(x)
|
||||||
|
#define STATIC_ASSERT( x ) static_assert( x, #x )
|
||||||
#else
|
#else
|
||||||
#define DebuggerBreak() ((void)0)
|
#define DebuggerBreak() ((void)0)
|
||||||
#define Assert( x ) ((void)0)
|
#define Assert( x ) ((void)0)
|
||||||
@ -113,12 +114,15 @@
|
|||||||
#define AssertMsg1( x, msg, a1 ) ((void)0)
|
#define AssertMsg1( x, msg, a1 ) ((void)0)
|
||||||
#define AssertMsg2( x, msg, a1, a2 ) ((void)0)
|
#define AssertMsg2( x, msg, a1, a2 ) ((void)0)
|
||||||
#define Verify( x ) x
|
#define Verify( x ) x
|
||||||
|
#define STATIC_ASSERT( x )
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <tier0/dbg.h>
|
#include <tier0/dbg.h>
|
||||||
|
|
||||||
|
#define STATIC_ASSERT COMPILE_TIME_ASSERT
|
||||||
|
|
||||||
// Misdefined for GCC in platform.h
|
// Misdefined for GCC in platform.h
|
||||||
#undef UNREACHABLE
|
#undef UNREACHABLE
|
||||||
|
|
||||||
|
@ -62,12 +62,12 @@ class json_array_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const char *m_pBase;
|
const char *m_pBase;
|
||||||
CScratch< JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||||
int *m_Elements;
|
int *m_Elements;
|
||||||
unsigned short m_nElementCount;
|
unsigned short m_nElementCount;
|
||||||
unsigned short m_nElementsSize;
|
unsigned short m_nElementsSize;
|
||||||
|
|
||||||
void Init( const char *base, CScratch< JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
void Init( const char *base, CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
||||||
{
|
{
|
||||||
m_pBase = base;
|
m_pBase = base;
|
||||||
m_Allocator = allocator;
|
m_Allocator = allocator;
|
||||||
@ -96,7 +96,7 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size() const
|
int Size() const
|
||||||
{
|
{
|
||||||
return m_nElementCount;
|
return m_nElementCount;
|
||||||
}
|
}
|
||||||
@ -138,12 +138,12 @@ class json_table_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const char *m_pBase;
|
const char *m_pBase;
|
||||||
CScratch< JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||||
int *m_Elements;
|
int *m_Elements;
|
||||||
unsigned short m_nElementCount;
|
unsigned short m_nElementCount;
|
||||||
unsigned short m_nElementsSize;
|
unsigned short m_nElementsSize;
|
||||||
|
|
||||||
void Init( const char *base, CScratch< JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
void Init( const char *base, CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
||||||
{
|
{
|
||||||
m_pBase = base;
|
m_pBase = base;
|
||||||
m_Allocator = allocator;
|
m_Allocator = allocator;
|
||||||
@ -266,11 +266,24 @@ public:
|
|||||||
bool Get( const string_t &key, json_array_t **out ) const { return GetArray( key, out ); }
|
bool Get( const string_t &key, json_array_t **out ) const { return GetArray( key, out ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void PutStrL( CBuffer *buffer, const string_t &str )
|
static inline void PutStr( CBuffer *buffer, const string_t &str )
|
||||||
{
|
{
|
||||||
buffer->_base.Ensure( buffer->size() + str.len );
|
buffer->base.Ensure( buffer->Size() + str.len );
|
||||||
memcpy( buffer->base() + buffer->size(), str.ptr, str.len );
|
memcpy( buffer->Base() + buffer->Size(), str.ptr, str.len );
|
||||||
buffer->_size += str.len;
|
buffer->size += str.len;
|
||||||
|
|
||||||
|
#ifdef SQDBG_VALIDATE_SENT_MSG
|
||||||
|
for ( unsigned int i = 0; i < str.len; i++ )
|
||||||
|
{
|
||||||
|
if ( str.ptr[i] == '\\' && ( str.ptr[i+1] == '\\' || str.ptr[i+1] == '\"' ) )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertMsg( str.ptr[i] != '\\' && IN_RANGE_CHAR( str.ptr[i], 0x20, 0x7E ), "control char in json string" );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||||
@ -278,7 +291,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
const char *c = str.ptr;
|
const char *c = str.ptr;
|
||||||
unsigned int i = str.len;
|
unsigned int i = str.len;
|
||||||
|
|
||||||
unsigned int len = 2 + i;
|
unsigned int len = i;
|
||||||
|
|
||||||
if ( quote )
|
if ( quote )
|
||||||
len += 4;
|
len += 4;
|
||||||
@ -287,18 +300,19 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
{
|
{
|
||||||
switch ( *c )
|
switch ( *c )
|
||||||
{
|
{
|
||||||
case '\"': case '\\': case '\b':
|
case '\\': case '\"':
|
||||||
case '\f': case '\n': case '\r': case '\t':
|
case '\a': case '\b': case '\f':
|
||||||
|
case '\n': case '\r': case '\t': case '\v':
|
||||||
len++;
|
len++;
|
||||||
if ( quote )
|
if ( quote )
|
||||||
{
|
{
|
||||||
len++;
|
len++;
|
||||||
if ( *c == '\"' || *c == '\\' )
|
if ( *c == '\\' || *c == '\"' )
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if ( !IN_RANGE_CHAR( *(unsigned char*)c, 0x20, 0x7E ) )
|
if ( !IN_RANGE_CHAR( *c, 0x20, 0x7E ) )
|
||||||
{
|
{
|
||||||
int ret = IsValidUTF8( (unsigned char*)c, i + 1 );
|
int ret = IsValidUTF8( (unsigned char*)c, i + 1 );
|
||||||
if ( ret != 0 )
|
if ( ret != 0 )
|
||||||
@ -321,16 +335,14 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->_base.Ensure( buffer->size() + len );
|
buffer->base.Ensure( buffer->Size() + len );
|
||||||
|
|
||||||
char *mem = buffer->base();
|
char *mem = buffer->Base();
|
||||||
unsigned int idx = buffer->size();
|
unsigned int idx = buffer->Size();
|
||||||
|
|
||||||
c = str.ptr;
|
c = str.ptr;
|
||||||
i = str.len;
|
i = str.len;
|
||||||
|
|
||||||
mem[idx++] = '\"';
|
|
||||||
|
|
||||||
if ( quote )
|
if ( quote )
|
||||||
{
|
{
|
||||||
mem[idx++] = '\\';
|
mem[idx++] = '\\';
|
||||||
@ -343,6 +355,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
|
|
||||||
switch ( *c )
|
switch ( *c )
|
||||||
{
|
{
|
||||||
|
case '\\':
|
||||||
case '\"':
|
case '\"':
|
||||||
mem[idx-1] = '\\';
|
mem[idx-1] = '\\';
|
||||||
if ( quote )
|
if ( quote )
|
||||||
@ -350,15 +363,13 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
mem[idx++] = '\\';
|
mem[idx++] = '\\';
|
||||||
mem[idx++] = '\\';
|
mem[idx++] = '\\';
|
||||||
}
|
}
|
||||||
mem[idx++] = '\"';
|
mem[idx++] = *c;
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\a':
|
||||||
|
mem[idx-1] = '\\';
|
||||||
if ( quote )
|
if ( quote )
|
||||||
{
|
|
||||||
mem[idx++] = '\\';
|
mem[idx++] = '\\';
|
||||||
mem[idx++] = '\\';
|
mem[idx++] = 'a';
|
||||||
}
|
|
||||||
mem[idx++] = '\\';
|
|
||||||
break;
|
break;
|
||||||
case '\b':
|
case '\b':
|
||||||
mem[idx-1] = '\\';
|
mem[idx-1] = '\\';
|
||||||
@ -390,8 +401,14 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
mem[idx++] = '\\';
|
mem[idx++] = '\\';
|
||||||
mem[idx++] = 't';
|
mem[idx++] = 't';
|
||||||
break;
|
break;
|
||||||
|
case '\v':
|
||||||
|
mem[idx-1] = '\\';
|
||||||
|
if ( quote )
|
||||||
|
mem[idx++] = '\\';
|
||||||
|
mem[idx++] = 'v';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if ( !IN_RANGE_CHAR( *(unsigned char*)c, 0x20, 0x7E ) )
|
if ( !IN_RANGE_CHAR( *c, 0x20, 0x7E ) )
|
||||||
{
|
{
|
||||||
int ret = IsValidUTF8( (unsigned char*)c, i + 1 );
|
int ret = IsValidUTF8( (unsigned char*)c, i + 1 );
|
||||||
if ( ret != 0 )
|
if ( ret != 0 )
|
||||||
@ -410,7 +427,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
mem[idx++] = 'u';
|
mem[idx++] = 'u';
|
||||||
idx += printhex< true, false >(
|
idx += printhex< true, false >(
|
||||||
mem + idx,
|
mem + idx,
|
||||||
buffer->capacity() - idx,
|
buffer->Capacity() - idx,
|
||||||
(uint16_t)*(unsigned char*)c );
|
(uint16_t)*(unsigned char*)c );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -419,8 +436,8 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
mem[idx++] = 'x';
|
mem[idx++] = 'x';
|
||||||
idx += printhex< true, false >(
|
idx += printhex< true, false >(
|
||||||
mem + idx,
|
mem + idx,
|
||||||
buffer->capacity() - idx,
|
buffer->Capacity() - idx,
|
||||||
(SQChar)*(unsigned char*)c );
|
(SQUnsignedChar)*(unsigned char*)c );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,9 +450,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
|||||||
mem[idx++] = '\"';
|
mem[idx++] = '\"';
|
||||||
}
|
}
|
||||||
|
|
||||||
mem[idx++] = '\"';
|
buffer->size = idx;
|
||||||
|
|
||||||
buffer->_size = idx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SQUNICODE
|
#ifdef SQUNICODE
|
||||||
@ -445,64 +460,127 @@ static inline void PutStr( CBuffer *buffer, const sqstring_t &str, bool quote )
|
|||||||
|
|
||||||
if ( !quote )
|
if ( !quote )
|
||||||
{
|
{
|
||||||
len = 2 + UTF8Length< kUTFEscapeJSON >( str.ptr, str.len );
|
len = UTF8Length< kUTFEscapeJSON >( str.ptr, str.len );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = 2 + UTF8Length< kUTFEscapeQuoted >( str.ptr, str.len );
|
len = UTF8Length< kUTFEscapeQuoted >( str.ptr, str.len );
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->_base.Ensure( buffer->size() + len );
|
buffer->base.Ensure( buffer->Size() + len );
|
||||||
buffer->base()[buffer->_size++] = '\"';
|
|
||||||
|
|
||||||
if ( !quote )
|
if ( !quote )
|
||||||
{
|
{
|
||||||
len = SQUnicodeToUTF8< kUTFEscapeJSON >(
|
len = SQUnicodeToUTF8< kUTFEscapeJSON >(
|
||||||
buffer->base() + buffer->size(),
|
buffer->Base() + buffer->Size(),
|
||||||
buffer->capacity() - buffer->size(),
|
buffer->Capacity() - buffer->Size(),
|
||||||
str.ptr,
|
str.ptr,
|
||||||
str.len );
|
str.len );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = SQUnicodeToUTF8< kUTFEscapeQuoted >(
|
len = SQUnicodeToUTF8< kUTFEscapeQuoted >(
|
||||||
buffer->base() + buffer->size(),
|
buffer->Base() + buffer->Size(),
|
||||||
buffer->capacity() - buffer->size(),
|
buffer->Capacity() - buffer->Size(),
|
||||||
str.ptr,
|
str.ptr,
|
||||||
str.len );
|
str.len );
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->_size += len;
|
buffer->size += len;
|
||||||
buffer->base()[buffer->_size++] = '\"';
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void PutChar( CBuffer *buffer, char c )
|
static inline void PutChar( CBuffer *buffer, char c )
|
||||||
{
|
{
|
||||||
buffer->_base.Ensure( buffer->size() + 1 );
|
buffer->base.Ensure( buffer->Size() + 1 );
|
||||||
buffer->base()[buffer->_size++] = c;
|
buffer->Base()[buffer->size++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename I >
|
template < typename I >
|
||||||
static inline void PutInt( CBuffer *buffer, I val, bool hex = false )
|
static inline void PutInt( CBuffer *buffer, I val )
|
||||||
{
|
{
|
||||||
int len;
|
buffer->base.Ensure( buffer->Size() + countdigits( val ) + 1 );
|
||||||
buffer->_base.Ensure( buffer->size() + countdigits( val ) + 1 );
|
int len = printint( buffer->Base() + buffer->Size(), buffer->Capacity() - buffer->Size(), val );
|
||||||
|
buffer->size += len;
|
||||||
if ( !hex )
|
|
||||||
{
|
|
||||||
len = printint( buffer->base() + buffer->size(), buffer->capacity() - buffer->size(), val );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
len = printhex< false >( buffer->base() + buffer->size(), buffer->capacity() - buffer->size(), val );
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->_size += len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class wjson_table_t;
|
template < bool padding, typename I >
|
||||||
class wjson_array_t;
|
static inline void PutHex( CBuffer *buffer, I val )
|
||||||
|
{
|
||||||
|
STATIC_ASSERT( IS_UNSIGNED( I ) );
|
||||||
|
buffer->base.Ensure( buffer->Size() + countdigits<16>( val ) + 1 );
|
||||||
|
int len = printhex< padding >( buffer->Base() + buffer->Size(), buffer->Capacity() - buffer->Size(), val );
|
||||||
|
buffer->size += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct jstringbuf_t
|
||||||
|
{
|
||||||
|
CBuffer *m_pBuffer;
|
||||||
|
|
||||||
|
jstringbuf_t( CBuffer *b ) : m_pBuffer(b)
|
||||||
|
{
|
||||||
|
::PutChar( m_pBuffer, '\"' );
|
||||||
|
}
|
||||||
|
|
||||||
|
~jstringbuf_t()
|
||||||
|
{
|
||||||
|
::PutChar( m_pBuffer, '\"' );
|
||||||
|
}
|
||||||
|
|
||||||
|
jstringbuf_t( const jstringbuf_t &src );
|
||||||
|
|
||||||
|
void Seek( int i )
|
||||||
|
{
|
||||||
|
m_pBuffer->size += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < int SIZE >
|
||||||
|
void Puts( const char (&str)[SIZE] )
|
||||||
|
{
|
||||||
|
::PutStr( m_pBuffer, str );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Puts( const conststring_t &str )
|
||||||
|
{
|
||||||
|
::PutStr( m_pBuffer, str );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Puts( const string_t &str, bool quote = false )
|
||||||
|
{
|
||||||
|
::PutStr( m_pBuffer, str, quote );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SQUNICODE
|
||||||
|
void Puts( const sqstring_t &str, bool quote = false )
|
||||||
|
{
|
||||||
|
::PutStr( m_pBuffer, str, quote );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Put( char c )
|
||||||
|
{
|
||||||
|
::PutChar( m_pBuffer, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename I >
|
||||||
|
void PutInt( I val )
|
||||||
|
{
|
||||||
|
::PutInt( m_pBuffer, val );
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename I >
|
||||||
|
void PutHex( I val, bool padding = true )
|
||||||
|
{
|
||||||
|
if ( padding )
|
||||||
|
{
|
||||||
|
::PutHex< true >( m_pBuffer, val );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::PutHex< false >( m_pBuffer, val );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class wjson_t
|
class wjson_t
|
||||||
{
|
{
|
||||||
@ -542,7 +620,7 @@ public:
|
|||||||
PutChar( m_pBuffer, ',' );
|
PutChar( m_pBuffer, ',' );
|
||||||
|
|
||||||
PutChar( m_pBuffer, '\"' );
|
PutChar( m_pBuffer, '\"' );
|
||||||
PutStrL( m_pBuffer, key );
|
PutStr( m_pBuffer, key );
|
||||||
PutChar( m_pBuffer, '\"' );
|
PutChar( m_pBuffer, '\"' );
|
||||||
PutChar( m_pBuffer, ':' );
|
PutChar( m_pBuffer, ':' );
|
||||||
}
|
}
|
||||||
@ -556,26 +634,53 @@ public:
|
|||||||
void SetNull( const string_t &key )
|
void SetNull( const string_t &key )
|
||||||
{
|
{
|
||||||
PutKey( key );
|
PutKey( key );
|
||||||
PutStrL( m_pBuffer, "null" );
|
PutStr( m_pBuffer, "null" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBool( const string_t &key, bool val )
|
void SetBool( const string_t &key, bool val )
|
||||||
{
|
{
|
||||||
PutKey( key );
|
PutKey( key );
|
||||||
PutStrL( m_pBuffer, val ? string_t("true") : string_t("false") );
|
PutStr( m_pBuffer, val ? string_t("true") : string_t("false") );
|
||||||
|
}
|
||||||
|
|
||||||
|
jstringbuf_t SetStringAsBuf( const string_t &key )
|
||||||
|
{
|
||||||
|
PutKey( key );
|
||||||
|
return { m_pBuffer };
|
||||||
|
}
|
||||||
|
|
||||||
|
template < int SIZE >
|
||||||
|
void SetString( const string_t &key, const char (&val)[SIZE] )
|
||||||
|
{
|
||||||
|
PutKey( key );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
|
PutStr( m_pBuffer, val );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetString( const string_t &key, const conststring_t &val )
|
||||||
|
{
|
||||||
|
PutKey( key );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
|
PutStr( m_pBuffer, val );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetString( const string_t &key, const string_t &val, bool quote = false )
|
void SetString( const string_t &key, const string_t &val, bool quote = false )
|
||||||
{
|
{
|
||||||
PutKey( key );
|
PutKey( key );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
PutStr( m_pBuffer, val, quote );
|
PutStr( m_pBuffer, val, quote );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SQUNICODE
|
#ifdef SQUNICODE
|
||||||
void SetString( const string_t &key, const sqstring_t &val, bool quote = false )
|
void SetString( const string_t &key, const sqstring_t &val, bool quote = false )
|
||||||
{
|
{
|
||||||
PutKey( key );
|
PutKey( key );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
PutStr( m_pBuffer, val, quote );
|
PutStr( m_pBuffer, val, quote );
|
||||||
|
PutChar( m_pBuffer, '\"' );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -593,7 +698,14 @@ public:
|
|||||||
PutKey( key );
|
PutKey( key );
|
||||||
PutChar( m_pBuffer, '\"' );
|
PutChar( m_pBuffer, '\"' );
|
||||||
PutChar( m_pBuffer, '[' );
|
PutChar( m_pBuffer, '[' );
|
||||||
PutInt( m_pBuffer, val, hex );
|
if ( !hex )
|
||||||
|
{
|
||||||
|
PutInt( m_pBuffer, val );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PutHex< false >( m_pBuffer, cast_unsigned( I, val ) );
|
||||||
|
}
|
||||||
PutChar( m_pBuffer, ']' );
|
PutChar( m_pBuffer, ']' );
|
||||||
PutChar( m_pBuffer, '\"' );
|
PutChar( m_pBuffer, '\"' );
|
||||||
}
|
}
|
||||||
@ -637,7 +749,7 @@ public:
|
|||||||
|
|
||||||
wjson_array_t( const wjson_array_t &src );
|
wjson_array_t( const wjson_array_t &src );
|
||||||
|
|
||||||
int size()
|
int Size()
|
||||||
{
|
{
|
||||||
return m_nElementCount;
|
return m_nElementCount;
|
||||||
}
|
}
|
||||||
@ -665,7 +777,7 @@ public:
|
|||||||
PutChar( m_pBuffer, ',' );
|
PutChar( m_pBuffer, ',' );
|
||||||
|
|
||||||
PutChar( m_pBuffer, '\"' );
|
PutChar( m_pBuffer, '\"' );
|
||||||
PutStrL( m_pBuffer, val );
|
PutStr( m_pBuffer, val );
|
||||||
PutChar( m_pBuffer, '\"' );
|
PutChar( m_pBuffer, '\"' );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -676,7 +788,7 @@ private:
|
|||||||
char *m_cur;
|
char *m_cur;
|
||||||
char *m_end;
|
char *m_end;
|
||||||
char *m_start;
|
char *m_start;
|
||||||
CScratch< JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||||
char *m_error;
|
char *m_error;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -693,7 +805,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JSONParser( CScratch< JSON_SCRATCH_CHUNK_SIZE > *allocator, char *ptr, int len, json_table_t *pTable ) :
|
JSONParser( CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *allocator, char *ptr, int len, json_table_t *pTable ) :
|
||||||
m_cur( ptr ),
|
m_cur( ptr ),
|
||||||
m_end( ptr + len + 1 ),
|
m_end( ptr + len + 1 ),
|
||||||
m_start( ptr ),
|
m_start( ptr ),
|
||||||
@ -710,7 +822,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetError( "expected '%c', got '0x%02x' @ %i", '{', Char(type), Index() );
|
SetError( "expected '%c', got %s @ %i", '{', Char(type), Index() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,12 +837,30 @@ private:
|
|||||||
return m_cur - m_start;
|
return m_cur - m_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char Char( char token )
|
char *Char( char token )
|
||||||
{
|
{
|
||||||
if ( token != Token_Error )
|
char *buf;
|
||||||
return (unsigned char)token;
|
|
||||||
|
|
||||||
return *(unsigned char*)m_cur;
|
if ( token == Token_Error )
|
||||||
|
token = *m_cur;
|
||||||
|
|
||||||
|
if ( IN_RANGE_CHAR( token, 0x20, 0x7E ) )
|
||||||
|
{
|
||||||
|
buf = m_Allocator->Alloc(4);
|
||||||
|
buf[0] = '\'';
|
||||||
|
buf[1] = token;
|
||||||
|
buf[2] = '\'';
|
||||||
|
buf[3] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = m_Allocator->Alloc(5);
|
||||||
|
int i = printhex< true, true, false >( buf, 5, (unsigned char)token );
|
||||||
|
Assert( i == 4 );
|
||||||
|
buf[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetError( const char *fmt, ... )
|
void SetError( const char *fmt, ... )
|
||||||
@ -752,6 +882,24 @@ private:
|
|||||||
m_error[len] = 0;
|
m_error[len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsValue( char token )
|
||||||
|
{
|
||||||
|
switch ( token )
|
||||||
|
{
|
||||||
|
case Token_String:
|
||||||
|
case Token_Integer:
|
||||||
|
case Token_Float:
|
||||||
|
case Token_False:
|
||||||
|
case Token_True:
|
||||||
|
case Token_Null:
|
||||||
|
case Token_Table:
|
||||||
|
case Token_Array:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char NextToken( string_t &token )
|
char NextToken( string_t &token )
|
||||||
{
|
{
|
||||||
while ( m_cur < m_end )
|
while ( m_cur < m_end )
|
||||||
@ -776,37 +924,37 @@ private:
|
|||||||
return *m_cur++;
|
return *m_cur++;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
if ( m_cur + 4 >= m_end ||
|
if ( m_cur + 4 < m_end &&
|
||||||
m_cur[1] != 'r' || m_cur[2] != 'u' || m_cur[3] != 'e' )
|
m_cur[1] == 'r' && m_cur[2] == 'u' && m_cur[3] == 'e' )
|
||||||
{
|
{
|
||||||
SetError( "expected %s @ %i", "\"true\"", Index() );
|
m_cur += 4;
|
||||||
return Token_Error;
|
return Token_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cur += 4;
|
SetError( "expected %s @ %i", "\"true\"", Index() );
|
||||||
return Token_True;
|
return Token_Error;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if ( m_cur + 5 >= m_end ||
|
if ( m_cur + 5 < m_end &&
|
||||||
m_cur[1] != 'a' || m_cur[2] != 'l' || m_cur[3] != 's' || m_cur[4] != 'e' )
|
m_cur[1] == 'a' && m_cur[2] == 'l' && m_cur[3] == 's' && m_cur[4] == 'e' )
|
||||||
{
|
{
|
||||||
SetError( "expected %s @ %i", "\"false\"", Index() );
|
m_cur += 5;
|
||||||
return Token_Error;
|
return Token_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cur += 5;
|
SetError( "expected %s @ %i", "\"false\"", Index() );
|
||||||
return Token_False;
|
return Token_Error;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
if ( m_cur + 4 >= m_end ||
|
if ( m_cur + 4 < m_end &&
|
||||||
m_cur[1] != 'u' || m_cur[2] != 'l' || m_cur[3] != 'l' )
|
m_cur[1] == 'u' && m_cur[2] == 'l' && m_cur[3] == 'l' )
|
||||||
{
|
{
|
||||||
SetError( "expected %s @ %i", "\"null\"", Index() );
|
m_cur += 4;
|
||||||
return Token_Error;
|
return Token_Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cur += 4;
|
SetError( "expected %s @ %i", "\"null\"", Index() );
|
||||||
return Token_Null;
|
return Token_Error;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
@ -829,12 +977,10 @@ private:
|
|||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end
|
|
||||||
if ( *m_cur == '\"' )
|
if ( *m_cur == '\"' )
|
||||||
{
|
{
|
||||||
*m_cur = 0;
|
|
||||||
token.Assign( pStart, m_cur - pStart );
|
token.Assign( pStart, m_cur - pStart );
|
||||||
m_cur++;
|
*m_cur++ = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,7 +1003,7 @@ private:
|
|||||||
// Defer unescape until the end of the string is found
|
// Defer unescape until the end of the string is found
|
||||||
switch ( *m_cur )
|
switch ( *m_cur )
|
||||||
{
|
{
|
||||||
case '\"': case '\\': case '/':
|
case '\\': case '\"': case '/':
|
||||||
case 'b': case 'f':
|
case 'b': case 'f':
|
||||||
case 'n': case 'r': case 't':
|
case 'n': case 'r': case 't':
|
||||||
m_cur++;
|
m_cur++;
|
||||||
@ -876,7 +1022,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SetError( "invalid escape char '0x%02x' @ %i", *(unsigned char*)m_cur, Index() );
|
SetError( "invalid escape char 0x%02x @ %i", *(unsigned char*)m_cur, Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -895,6 +1041,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define _shift( bytesWritten, bytesRead ) \
|
#define _shift( bytesWritten, bytesRead ) \
|
||||||
|
Assert( (bytesWritten) < (bytesRead) ); \
|
||||||
memmove( cur + (bytesWritten), cur + (bytesRead), end - ( cur + (bytesRead) ) ); \
|
memmove( cur + (bytesWritten), cur + (bytesRead), end - ( cur + (bytesRead) ) ); \
|
||||||
cur += (bytesWritten); \
|
cur += (bytesWritten); \
|
||||||
end -= (bytesRead) - (bytesWritten);
|
end -= (bytesRead) - (bytesWritten);
|
||||||
@ -903,22 +1050,21 @@ private:
|
|||||||
{
|
{
|
||||||
case '\\':
|
case '\\':
|
||||||
shift_one:
|
shift_one:
|
||||||
_shift( 0, 1 );
|
_shift( 1, 2 );
|
||||||
cur++;
|
|
||||||
break;
|
break;
|
||||||
case '\"': goto shift_one;
|
case '\"': cur[0] = '\"'; goto shift_one;
|
||||||
case '/': goto shift_one;
|
case '/': cur[0] = '/'; goto shift_one;
|
||||||
case 'b': cur[1] = '\b'; goto shift_one;
|
case 'b': cur[0] = '\b'; goto shift_one;
|
||||||
case 'f': cur[1] = '\f'; goto shift_one;
|
case 'f': cur[0] = '\f'; goto shift_one;
|
||||||
case 'n': cur[1] = '\n'; goto shift_one;
|
case 'n': cur[0] = '\n'; goto shift_one;
|
||||||
case 'r': cur[1] = '\r'; goto shift_one;
|
case 'r': cur[0] = '\r'; goto shift_one;
|
||||||
case 't': cur[1] = '\t'; goto shift_one;
|
case 't': cur[0] = '\t'; goto shift_one;
|
||||||
case 'u':
|
case 'u':
|
||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
Verify( atox( { cur + 2, 4 }, &val ) );
|
Verify( atox( { cur + 2, 4 }, &val ) );
|
||||||
|
|
||||||
if ( val <= 0xFF )
|
if ( val <= 0x7F )
|
||||||
{
|
{
|
||||||
cur[0] = (char)val;
|
cur[0] = (char)val;
|
||||||
|
|
||||||
@ -993,7 +1139,7 @@ shift_one:
|
|||||||
if ( m_cur >= m_end )
|
if ( m_cur >= m_end )
|
||||||
goto err_eof;
|
goto err_eof;
|
||||||
}
|
}
|
||||||
else if ( IN_RANGE_CHAR( *(unsigned char*)m_cur, '1', '9' ) )
|
else if ( IN_RANGE_CHAR( *m_cur, '1', '9' ) )
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -1001,11 +1147,11 @@ shift_one:
|
|||||||
if ( m_cur >= m_end )
|
if ( m_cur >= m_end )
|
||||||
goto err_eof;
|
goto err_eof;
|
||||||
}
|
}
|
||||||
while ( IN_RANGE_CHAR( *(unsigned char*)m_cur, '0', '9' ) );
|
while ( IN_RANGE_CHAR( *m_cur, '0', '9' ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetError( "unexpected char '0x%02x' in number @ %i", *(unsigned char*)m_cur, Index() );
|
SetError( "unexpected char 0x%02x in number @ %i", *(unsigned char*)m_cur, Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,7 +1162,7 @@ shift_one:
|
|||||||
type = Token_Float;
|
type = Token_Float;
|
||||||
m_cur++;
|
m_cur++;
|
||||||
|
|
||||||
while ( m_cur < m_end && IN_RANGE_CHAR( *(unsigned char*)m_cur, '0', '9' ) )
|
while ( m_cur < m_end && IN_RANGE_CHAR( *m_cur, '0', '9' ) )
|
||||||
m_cur++;
|
m_cur++;
|
||||||
|
|
||||||
if ( m_cur >= m_end )
|
if ( m_cur >= m_end )
|
||||||
@ -1039,7 +1185,7 @@ shift_one:
|
|||||||
goto err_eof;
|
goto err_eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( m_cur < m_end && IN_RANGE_CHAR( *(unsigned char*)m_cur, '0', '9' ) )
|
while ( m_cur < m_end && IN_RANGE_CHAR( *m_cur, '0', '9' ) )
|
||||||
m_cur++;
|
m_cur++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1062,7 +1208,7 @@ err_eof:
|
|||||||
{
|
{
|
||||||
if ( type != Token_String )
|
if ( type != Token_String )
|
||||||
{
|
{
|
||||||
SetError( "expected %s, got '0x%02x' @ %i", "string", Char(type), Index() );
|
SetError( "expected '%c', got %s @ %i", '\"', Char(type), Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,7 +1216,7 @@ err_eof:
|
|||||||
|
|
||||||
if ( type != ':' )
|
if ( type != ':' )
|
||||||
{
|
{
|
||||||
SetError( "expected '%c', got '0x%02x' @ %i", ':', Char(type), Index() );
|
SetError( "expected '%c', got %s @ %i", ':', Char(type), Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1083,9 +1229,9 @@ err_eof:
|
|||||||
type = NextToken( token );
|
type = NextToken( token );
|
||||||
type = ParseValue( type, token, &kv->val );
|
type = ParseValue( type, token, &kv->val );
|
||||||
|
|
||||||
if ( type == Token_Error )
|
if ( !IsValue( type ) )
|
||||||
{
|
{
|
||||||
SetError( "invalid token '0x%02x' @ %i", Char(type), Index() );
|
SetError( "invalid token %s @ %i", Char(type), Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,7 +1247,7 @@ err_eof:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetError( "expected '%c', got '0x%02x' @ %i", '}', Char(type), Index() );
|
SetError( "expected '%c', got %s @ %i", '}', Char(type), Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1116,9 +1262,9 @@ err_eof:
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if ( type == Token_Error )
|
if ( !IsValue( type ) )
|
||||||
{
|
{
|
||||||
SetError( "expected '%c', got '0x%02x' @ %i", ']', Char(type), Index() );
|
SetError( "expected '%c', got %s @ %i", ']', Char(type), Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,7 +1273,7 @@ err_eof:
|
|||||||
|
|
||||||
if ( type == Token_Error )
|
if ( type == Token_Error )
|
||||||
{
|
{
|
||||||
SetError( "invalid token '0x%02x' @ %i", Char(type), Index() );
|
SetError( "invalid token %s @ %i", Char(type), Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,7 +1289,7 @@ err_eof:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetError( "expected '%c', got '0x%02x' @ %i", ']', Char(type), Index() );
|
SetError( "expected '%c', got %s @ %i", ']', Char(type), Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1154,7 +1300,7 @@ err_eof:
|
|||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
case Token_Integer:
|
case Token_Integer:
|
||||||
if ( token.len > FMT_INT_LEN )
|
if ( token.len > FMT_UINT32_LEN + 1 )
|
||||||
{
|
{
|
||||||
SetError( "invalid integer literal @ %i", Index() );
|
SetError( "invalid integer literal @ %i", Index() );
|
||||||
return Token_Error;
|
return Token_Error;
|
||||||
@ -1192,7 +1338,7 @@ err_eof:
|
|||||||
value->type = JSON_NULL;
|
value->type = JSON_NULL;
|
||||||
return type;
|
return type;
|
||||||
default:
|
default:
|
||||||
return type;
|
return Token_Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -602,6 +602,9 @@ public:
|
|||||||
|
|
||||||
bool Listen()
|
bool Listen()
|
||||||
{
|
{
|
||||||
|
if ( m_ServerSocket == INVALID_SOCKET )
|
||||||
|
return false;
|
||||||
|
|
||||||
timeval tv;
|
timeval tv;
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
@ -839,7 +842,7 @@ public:
|
|||||||
m_pRecvBufPtr( m_pRecvBuf ),
|
m_pRecvBufPtr( m_pRecvBuf ),
|
||||||
m_bWSAInit( false )
|
m_bWSAInit( false )
|
||||||
{
|
{
|
||||||
Assert( sizeof(m_pRecvBuf) <= ( 1 << ( sizeof(CMessagePool::message_t::len) * 8 ) ) );
|
STATIC_ASSERT( sizeof(m_pRecvBuf) <= ( 1 << ( sizeof(CMessagePool::message_t::len) * 8 ) ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
inline void DAP_Serialise( CBuffer *buffer )
|
inline void DAP_Serialise( CBuffer *buffer )
|
||||||
{
|
{
|
||||||
Assert( buffer->size() > 0 && buffer->size() < INT_MAX );
|
Assert( buffer->Size() > 0 && buffer->Size() < INT_MAX );
|
||||||
|
|
||||||
char *mem = buffer->base();
|
char *mem = buffer->Base();
|
||||||
int contentSize = buffer->size() - DAP_HEADER_MAXSIZE;
|
int contentSize = buffer->Size() - DAP_HEADER_MAXSIZE;
|
||||||
int digits = countdigits( contentSize );
|
int digits = countdigits( contentSize );
|
||||||
int padding = FMT_UINT32_LEN - digits;
|
int padding = FMT_UINT32_LEN - digits;
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ inline void DAP_Serialise( CBuffer *buffer )
|
|||||||
// add padding in the end to match
|
// add padding in the end to match
|
||||||
padding--;
|
padding--;
|
||||||
digits++;
|
digits++;
|
||||||
buffer->_base.Ensure( buffer->size() + 1 );
|
buffer->base.Ensure( buffer->Size() + 1 );
|
||||||
mem[buffer->_size++] = ' ';
|
mem[buffer->size++] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy( mem, DAP_HEADER_CONTENTLENGTH ": ", STRLEN(DAP_HEADER_CONTENTLENGTH ": ") );
|
memcpy( mem, DAP_HEADER_CONTENTLENGTH ": ", STRLEN(DAP_HEADER_CONTENTLENGTH ": ") );
|
||||||
@ -53,10 +53,10 @@ inline void DAP_Serialise( CBuffer *buffer )
|
|||||||
|
|
||||||
inline void DAP_Free( CBuffer *buffer )
|
inline void DAP_Free( CBuffer *buffer )
|
||||||
{
|
{
|
||||||
buffer->_size = 0;
|
buffer->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ParseFieldName( const char *pMemEnd, char *pStart, int *len )
|
static inline int ParseFieldName( const char *pMemEnd, char *pStart )
|
||||||
{
|
{
|
||||||
char *c = pStart;
|
char *c = pStart;
|
||||||
|
|
||||||
@ -65,56 +65,39 @@ static inline void ParseFieldName( const char *pMemEnd, char *pStart, int *len )
|
|||||||
if ( IN_RANGE_CHAR( ((unsigned char*)c)[0], 0x20, 0x7E ) )
|
if ( IN_RANGE_CHAR( ((unsigned char*)c)[0], 0x20, 0x7E ) )
|
||||||
{
|
{
|
||||||
if ( c + 1 >= pMemEnd )
|
if ( c + 1 >= pMemEnd )
|
||||||
{
|
return -1;
|
||||||
*len = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( c[0] == ':' )
|
if ( c[0] == ':' )
|
||||||
{
|
{
|
||||||
if ( c[1] == ' ' )
|
if ( c[1] == ' ' )
|
||||||
{
|
return c - pStart;
|
||||||
*len = c - pStart;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*len = 0;
|
return 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*len = 0;
|
return 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ParseFieldValue( const char *pMemEnd, char *pStart, int *len )
|
static inline int ParseFieldValue( const char *pMemEnd, char *pStart )
|
||||||
{
|
{
|
||||||
char *c = pStart;
|
char *c = pStart;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if ( c + 1 >= pMemEnd )
|
if ( c + 1 >= pMemEnd )
|
||||||
{
|
return -1;
|
||||||
*len = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( c[0] == '\n' )
|
if ( c[0] == '\n' )
|
||||||
{
|
return 0;
|
||||||
*len = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( c[0] == '\r' && c[1] == '\n' )
|
if ( c[0] == '\r' && c[1] == '\n' )
|
||||||
{
|
return c - pStart;
|
||||||
*len = c - pStart;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
@ -128,8 +111,7 @@ inline bool DAP_ReadHeader( char **ppMsg, int *pLength )
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
int len;
|
int len = ParseFieldName( pMemEnd, pMsg );
|
||||||
ParseFieldName( pMemEnd, pMsg, &len );
|
|
||||||
|
|
||||||
if ( len == 0 )
|
if ( len == 0 )
|
||||||
goto invalid;
|
goto invalid;
|
||||||
@ -151,7 +133,7 @@ inline bool DAP_ReadHeader( char **ppMsg, int *pLength )
|
|||||||
if ( pMsg >= pMemEnd )
|
if ( pMsg >= pMemEnd )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( IN_RANGE_CHAR( *(unsigned char*)pMsg, '0', '9' ) )
|
if ( IN_RANGE_CHAR( *pMsg, '0', '9' ) )
|
||||||
{
|
{
|
||||||
nContentLength = nContentLength * 10 + *pMsg - '0';
|
nContentLength = nContentLength * 10 + *pMsg - '0';
|
||||||
pMsg++;
|
pMsg++;
|
||||||
@ -187,7 +169,7 @@ inline bool DAP_ReadHeader( char **ppMsg, int *pLength )
|
|||||||
ignore:
|
ignore:
|
||||||
pMsg += len + 2;
|
pMsg += len + 2;
|
||||||
|
|
||||||
ParseFieldValue( pMemEnd, pMsg, &len );
|
len = ParseFieldValue( pMemEnd, pMsg );
|
||||||
|
|
||||||
if ( len == 0 )
|
if ( len == 0 )
|
||||||
goto invalid;
|
goto invalid;
|
||||||
@ -216,13 +198,13 @@ invalid:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SQDBG_VALIDATE_SENT_MSG
|
#ifdef SQDBG_VALIDATE_SENT_MSG
|
||||||
inline void DAP_Test( CScratch< JSON_SCRATCH_CHUNK_SIZE > *scratch, CBuffer *buffer )
|
inline void DAP_Test( CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *scratch, CBuffer *buffer )
|
||||||
{
|
{
|
||||||
char *pMsg = buffer->base();
|
char *pMsg = buffer->Base();
|
||||||
int nLength = buffer->size();
|
int nLength = buffer->Size();
|
||||||
|
|
||||||
bool res = DAP_ReadHeader( &pMsg, &nLength );
|
bool res = DAP_ReadHeader( &pMsg, &nLength );
|
||||||
Assert( res && nLength < buffer->size() );
|
Assert( res && nLength < buffer->Size() );
|
||||||
|
|
||||||
if ( res )
|
if ( res )
|
||||||
{
|
{
|
||||||
@ -238,7 +220,7 @@ inline void DAP_Test( CScratch< JSON_SCRATCH_CHUNK_SIZE > *scratch, CBuffer *buf
|
|||||||
|
|
||||||
#define _DAP_INIT_BUF( _buf ) \
|
#define _DAP_INIT_BUF( _buf ) \
|
||||||
CBufTmpCache _bufcache( (_buf) ); \
|
CBufTmpCache _bufcache( (_buf) ); \
|
||||||
(_buf)->_size = DAP_HEADER_MAXSIZE; \
|
(_buf)->size = DAP_HEADER_MAXSIZE; \
|
||||||
(void)0
|
(void)0
|
||||||
|
|
||||||
#define DAP_START_REQUEST( _seq, _cmd ) \
|
#define DAP_START_REQUEST( _seq, _cmd ) \
|
||||||
@ -262,10 +244,10 @@ if ( IsClientConnected() ) \
|
|||||||
packet.SetBool( "success", _suc );
|
packet.SetBool( "success", _suc );
|
||||||
|
|
||||||
#define DAP_START_RESPONSE( _seq, _cmd ) \
|
#define DAP_START_RESPONSE( _seq, _cmd ) \
|
||||||
_DAP_START_RESPONSE( _seq, _cmd, true );
|
_DAP_START_RESPONSE( _seq, _cmd, true )
|
||||||
|
|
||||||
#define DAP_ERROR_RESPONSE( _seq, _cmd ) \
|
#define DAP_ERROR_RESPONSE( _seq, _cmd ) \
|
||||||
_DAP_START_RESPONSE( _seq, _cmd, false );
|
_DAP_START_RESPONSE( _seq, _cmd, false )
|
||||||
|
|
||||||
#define DAP_ERROR_BODY( _id, _fmt ) \
|
#define DAP_ERROR_BODY( _id, _fmt ) \
|
||||||
wjson_table_t body = packet.SetTable( "body" ); \
|
wjson_table_t body = packet.SetTable( "body" ); \
|
||||||
@ -292,7 +274,7 @@ if ( IsClientConnected() ) \
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
DAP_Serialise( &m_SendBuf ); \
|
DAP_Serialise( &m_SendBuf ); \
|
||||||
Send( m_SendBuf.base(), m_SendBuf.size() ); \
|
Send( m_SendBuf.Base(), m_SendBuf.Size() ); \
|
||||||
DAP_Test( &m_ReadBuf, &m_SendBuf ); \
|
DAP_Test( &m_ReadBuf, &m_SendBuf ); \
|
||||||
DAP_Free( &m_SendBuf ); \
|
DAP_Free( &m_SendBuf ); \
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -75,13 +75,35 @@ bool atox( string_t str, I *out );
|
|||||||
template < typename I >
|
template < typename I >
|
||||||
bool atoo( string_t str, I *out );
|
bool atoo( string_t str, I *out );
|
||||||
|
|
||||||
|
template < typename I >
|
||||||
|
struct _as_unsigned { typedef I T; };
|
||||||
|
|
||||||
#ifdef SQUNICODE
|
template <>
|
||||||
void CopyString( const string_t &src, sqstring_t *dst );
|
struct _as_unsigned< int > { typedef unsigned int T; };
|
||||||
void CopyString( const sqstring_t &src, string_t *dst );
|
|
||||||
|
#ifdef _SQ64
|
||||||
|
template <>
|
||||||
|
struct _as_unsigned< SQInteger > { typedef SQUnsignedInteger T; };
|
||||||
#endif
|
#endif
|
||||||
template < typename T > void CopyString( const T &src, T *dst );
|
|
||||||
template < typename T > void FreeString( T *dst );
|
#define as_unsigned_type( I ) typename _as_unsigned<I>::T
|
||||||
|
#define cast_unsigned( I, v ) (as_unsigned_type(I)(v))
|
||||||
|
#define IS_UNSIGNED( I ) ((I)0 < (I)-1)
|
||||||
|
|
||||||
|
|
||||||
|
#define _isdigit( c ) \
|
||||||
|
IN_RANGE_CHAR( c, '0', '9' )
|
||||||
|
|
||||||
|
#define _isxdigit( c ) \
|
||||||
|
( IN_RANGE_CHAR( c, '0', '9' ) || \
|
||||||
|
IN_RANGE_CHAR( c, 'A', 'F' ) || \
|
||||||
|
IN_RANGE_CHAR( c, 'a', 'f' ) )
|
||||||
|
|
||||||
|
#define _isalpha( c ) \
|
||||||
|
( IN_RANGE_CHAR( c, 'A', 'Z' ) || IN_RANGE_CHAR( c, 'a', 'z' ) )
|
||||||
|
|
||||||
|
#define _isalnum( c ) \
|
||||||
|
( _isalpha(c) || _isdigit(c) )
|
||||||
|
|
||||||
#define IN_RANGE(c, min, max) \
|
#define IN_RANGE(c, min, max) \
|
||||||
((uint32_t)((uint32_t)(c) - (uint32_t)(min)) <= (uint32_t)((max)-(min)))
|
((uint32_t)((uint32_t)(c) - (uint32_t)(min)) <= (uint32_t)((max)-(min)))
|
||||||
@ -249,51 +271,21 @@ struct string_t
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template < int size >
|
template < int SIZE >
|
||||||
string_t( const char (&src)[size] ) :
|
string_t( const char (&src)[SIZE] ) :
|
||||||
ptr((char*)src),
|
ptr((char*)src),
|
||||||
len(size-1)
|
len(SIZE-1)
|
||||||
{
|
{
|
||||||
// input wasn't a string literal,
|
// input wasn't a string literal,
|
||||||
// call ( src, size ) constructor instead
|
// call ( src, size ) constructor instead
|
||||||
Assert( strlen(src) == len );
|
Assert( strlen(src) == len );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Strip()
|
template < int SIZE >
|
||||||
|
bool StartsWith( const char (&other)[SIZE] ) const
|
||||||
{
|
{
|
||||||
char *end = ptr + len;
|
if ( SIZE-1 <= len && *ptr == *other )
|
||||||
|
return !memcmp( ptr, other, SIZE-1 );
|
||||||
for ( char *c = ptr; c < end; c++ )
|
|
||||||
{
|
|
||||||
if ( *c == ' ' || *c == '\t' || *c == '\n' )
|
|
||||||
{
|
|
||||||
ptr++;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( char *c = end - 1; c >= ptr; c-- )
|
|
||||||
{
|
|
||||||
if ( *c == ' ' || *c == '\t' || *c == '\n' )
|
|
||||||
{
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < int size >
|
|
||||||
bool StartsWith( const char (&other)[size] ) const
|
|
||||||
{
|
|
||||||
if ( size-1 <= len && *ptr == *other )
|
|
||||||
return !memcmp( ptr, other, size-1 );
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -306,11 +298,11 @@ struct string_t
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < int size >
|
template < int SIZE >
|
||||||
bool IsEqualTo( const char (&other)[size] ) const
|
bool IsEqualTo( const char (&other)[SIZE] ) const
|
||||||
{
|
{
|
||||||
if ( size-1 == len && *ptr == *other )
|
if ( SIZE-1 == len && *ptr == *other )
|
||||||
return !memcmp( ptr, other, size-1 );
|
return !memcmp( ptr, other, SIZE-1 );
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -333,6 +325,14 @@ struct string_t
|
|||||||
|
|
||||||
#ifdef SQUNICODE
|
#ifdef SQUNICODE
|
||||||
bool IsEqualTo( const sqstring_t &other ) const;
|
bool IsEqualTo( const sqstring_t &other ) const;
|
||||||
|
#else
|
||||||
|
bool IsEqualTo( const SQString *other ) const
|
||||||
|
{
|
||||||
|
if ( (SQUnsignedInteger)len == (SQUnsignedInteger)other->_len && *ptr == *other->_val )
|
||||||
|
return !memcmp( ptr, other->_val, sq_rsl(len) );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool IsEmpty() const
|
bool IsEmpty() const
|
||||||
@ -345,11 +345,11 @@ struct string_t
|
|||||||
return ( memchr( ptr, ch, len ) != NULL );
|
return ( memchr( ptr, ch, len ) != NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
template < int size >
|
template < int SIZE >
|
||||||
void Assign( const char (&src)[size] )
|
void Assign( const char (&src)[SIZE] )
|
||||||
{
|
{
|
||||||
ptr = (char*)src;
|
ptr = (char*)src;
|
||||||
len = size - 1;
|
len = SIZE - 1;
|
||||||
Assert( strlen(src) == len );
|
Assert( strlen(src) == len );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +373,14 @@ private:
|
|||||||
string_t &operator=( const char *src );
|
string_t &operator=( const char *src );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct conststring_t : string_t
|
||||||
|
{
|
||||||
|
template < int SIZE >
|
||||||
|
conststring_t( const char (&src)[SIZE] ) : string_t(src) {}
|
||||||
|
|
||||||
|
conststring_t() {}
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef SQUNICODE
|
#ifdef SQUNICODE
|
||||||
struct sqstring_t
|
struct sqstring_t
|
||||||
{
|
{
|
||||||
@ -393,10 +401,10 @@ struct sqstring_t
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template < int size >
|
template < int SIZE >
|
||||||
sqstring_t( const SQChar (&src)[size] ) :
|
sqstring_t( const SQChar (&src)[SIZE] ) :
|
||||||
ptr((SQChar*)src),
|
ptr((SQChar*)src),
|
||||||
len(size-1)
|
len(SIZE-1)
|
||||||
{
|
{
|
||||||
Assert( scstrlen(src) == len );
|
Assert( scstrlen(src) == len );
|
||||||
}
|
}
|
||||||
@ -410,9 +418,10 @@ struct sqstring_t
|
|||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ( ptr[i] > 0x7E || other.ptr[i] != (char)ptr[i] )
|
if ( (SQUnsignedChar)ptr[i] > 0x7E || other.ptr[i] != (char)ptr[i] )
|
||||||
{
|
{
|
||||||
AssertMsg( ptr[i] <= 0x7E, "not implemented" );
|
// > 0x7E can be reached through completions request
|
||||||
|
// unicode identifiers are not supported, ignore them
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,7 +443,7 @@ struct sqstring_t
|
|||||||
|
|
||||||
bool IsEqualTo( const SQString *other ) const
|
bool IsEqualTo( const SQString *other ) const
|
||||||
{
|
{
|
||||||
if ( len == other->_len && *ptr == *other->_val )
|
if ( (SQUnsignedInteger)len == (SQUnsignedInteger)other->_len && *ptr == *other->_val )
|
||||||
return !memcmp( ptr, other->_val, sq_rsl(len) );
|
return !memcmp( ptr, other->_val, sq_rsl(len) );
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -445,11 +454,11 @@ struct sqstring_t
|
|||||||
return !len;
|
return !len;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < int size >
|
template < int SIZE >
|
||||||
void Assign( const SQChar (&src)[size] )
|
void Assign( const SQChar (&src)[SIZE] )
|
||||||
{
|
{
|
||||||
ptr = (SQChar*)src;
|
ptr = (SQChar*)src;
|
||||||
len = size - 1;
|
len = SIZE - 1;
|
||||||
Assert( scstrlen(src) == len );
|
Assert( scstrlen(src) == len );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,12 +480,12 @@ struct stringbufbase_t
|
|||||||
{
|
{
|
||||||
char *ptr;
|
char *ptr;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
const int size;
|
const unsigned int size;
|
||||||
|
|
||||||
stringbufbase_t( char *src, unsigned int size ) :
|
stringbufbase_t( char *src, unsigned int nSize ) :
|
||||||
ptr(src),
|
ptr(src),
|
||||||
len(0),
|
len(0),
|
||||||
size(size)
|
size(nSize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,6 +572,8 @@ struct stringbufbase_t
|
|||||||
template < typename I >
|
template < typename I >
|
||||||
void PutHex( I value, bool padding = true )
|
void PutHex( I value, bool padding = true )
|
||||||
{
|
{
|
||||||
|
STATIC_ASSERT( IS_UNSIGNED( I ) );
|
||||||
|
|
||||||
int space = BytesLeft();
|
int space = BytesLeft();
|
||||||
|
|
||||||
if ( space < 3 )
|
if ( space < 3 )
|
||||||
@ -597,9 +608,9 @@ bool string_t::IsEqualTo( const sqstring_t &other ) const
|
|||||||
{
|
{
|
||||||
// Used for comparing against locals and outers,
|
// Used for comparing against locals and outers,
|
||||||
// implement unicode conversion if locals can have unicode characters
|
// implement unicode conversion if locals can have unicode characters
|
||||||
if ( other.ptr[i] > 0x7E || (char)other.ptr[i] != ptr[i] )
|
if ( (SQUnsignedChar)other.ptr[i] > 0x7E || (char)other.ptr[i] != ptr[i] )
|
||||||
{
|
{
|
||||||
AssertMsg( other.ptr[i] <= 0x7E, "not implemented" );
|
AssertMsg( (SQUnsignedChar)other.ptr[i] <= 0x7E, "not implemented" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,20 +633,6 @@ struct stringbuf_t : stringbufbase_t
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define _isdigit( c ) \
|
|
||||||
IN_RANGE_CHAR(c, '0', '9')
|
|
||||||
|
|
||||||
#define _isxdigit( c ) \
|
|
||||||
( IN_RANGE_CHAR(c, '0', '9') || \
|
|
||||||
IN_RANGE_CHAR(c, 'A', 'F') || \
|
|
||||||
IN_RANGE_CHAR(c, 'a', 'f') )
|
|
||||||
|
|
||||||
#define _isalpha( c ) \
|
|
||||||
( IN_RANGE_CHAR(c, 'A', 'Z') || IN_RANGE_CHAR(c, 'a', 'z') )
|
|
||||||
|
|
||||||
#define _isalnum( c ) \
|
|
||||||
( _isalpha(c) || _isdigit(c) )
|
|
||||||
|
|
||||||
template < int BASE = 10, typename I >
|
template < int BASE = 10, typename I >
|
||||||
inline int countdigits( I input )
|
inline int countdigits( I input )
|
||||||
{
|
{
|
||||||
@ -696,7 +693,7 @@ inline int printint( C *buf, int size, I value )
|
|||||||
value /= 10;
|
value /= 10;
|
||||||
buf[i--] = !neg ? ( '0' + c ) : ( '0' - c );
|
buf[i--] = !neg ? ( '0' + c ) : ( '0' - c );
|
||||||
}
|
}
|
||||||
while ( value && i >= 0 );
|
while ( value );
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -704,10 +701,11 @@ inline int printint( C *buf, int size, I value )
|
|||||||
template < bool padding, bool prefix, bool uppercase, typename C, typename I >
|
template < bool padding, bool prefix, bool uppercase, typename C, typename I >
|
||||||
inline int printhex( C *buf, int size, I value )
|
inline int printhex( C *buf, int size, I value )
|
||||||
{
|
{
|
||||||
|
STATIC_ASSERT( IS_UNSIGNED( as_unsigned_type( I ) ) );
|
||||||
Assert( buf );
|
Assert( buf );
|
||||||
Assert( size > 0 );
|
Assert( size > 0 );
|
||||||
|
|
||||||
int len = ( prefix ? 2 : 0 ) + ( padding ? sizeof(I) * 2 : countdigits<16>( value ) );
|
int len = ( prefix ? 2 : 0 ) + ( padding ? sizeof(I) * 2 : countdigits<16>( cast_unsigned( I, value ) ) );
|
||||||
|
|
||||||
if ( len > size )
|
if ( len > size )
|
||||||
len = size;
|
len = size;
|
||||||
@ -716,11 +714,11 @@ inline int printhex( C *buf, int size, I value )
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
C c = value & 0xf;
|
C c = cast_unsigned( I, value ) & 0xf;
|
||||||
value >>= 4;
|
*(as_unsigned_type(I)*)&value >>= 4;
|
||||||
buf[i--] = c + ( ( c < 10 ) ? '0' : ( ( uppercase ? 'A' : 'a' ) - 10 ) );
|
buf[i--] = c + ( ( c < 10 ) ? '0' : ( ( uppercase ? 'A' : 'a' ) - 10 ) );
|
||||||
}
|
}
|
||||||
while ( value && i >= 0 );
|
while ( value );
|
||||||
|
|
||||||
if ( padding )
|
if ( padding )
|
||||||
{
|
{
|
||||||
@ -746,6 +744,7 @@ inline int printhex( C *buf, int size, I value )
|
|||||||
template < typename C, typename I >
|
template < typename C, typename I >
|
||||||
inline int printoct( C *buf, int size, I value )
|
inline int printoct( C *buf, int size, I value )
|
||||||
{
|
{
|
||||||
|
STATIC_ASSERT( IS_UNSIGNED( I ) );
|
||||||
Assert( buf );
|
Assert( buf );
|
||||||
Assert( size > 0 );
|
Assert( size > 0 );
|
||||||
|
|
||||||
@ -762,7 +761,7 @@ inline int printoct( C *buf, int size, I value )
|
|||||||
value >>= 3;
|
value >>= 3;
|
||||||
buf[i--] = '0' + c;
|
buf[i--] = '0' + c;
|
||||||
}
|
}
|
||||||
while ( value && i >= 0 );
|
while ( value );
|
||||||
|
|
||||||
if ( i >= 0 )
|
if ( i >= 0 )
|
||||||
buf[i--] = '0';
|
buf[i--] = '0';
|
||||||
@ -789,7 +788,7 @@ inline bool atoi( string_t str, I *out )
|
|||||||
{
|
{
|
||||||
unsigned char ch = *str.ptr;
|
unsigned char ch = *str.ptr;
|
||||||
|
|
||||||
if ( IN_RANGE_CHAR(ch, '0', '9') )
|
if ( IN_RANGE_CHAR( ch, '0', '9' ) )
|
||||||
{
|
{
|
||||||
val *= 10;
|
val *= 10;
|
||||||
val += ch - '0';
|
val += ch - '0';
|
||||||
@ -820,17 +819,17 @@ inline bool atox( string_t str, I *out )
|
|||||||
{
|
{
|
||||||
unsigned char ch = *str.ptr;
|
unsigned char ch = *str.ptr;
|
||||||
|
|
||||||
if ( IN_RANGE_CHAR(ch, '0', '9') )
|
if ( IN_RANGE_CHAR( ch, '0', '9' ) )
|
||||||
{
|
{
|
||||||
val <<= 4;
|
val <<= 4;
|
||||||
val += ch - '0';
|
val += ch - '0';
|
||||||
}
|
}
|
||||||
else if ( IN_RANGE_CHAR(ch, 'A', 'F') )
|
else if ( IN_RANGE_CHAR( ch, 'A', 'F' ) )
|
||||||
{
|
{
|
||||||
val <<= 4;
|
val <<= 4;
|
||||||
val += ch - 'A' + 10;
|
val += ch - 'A' + 10;
|
||||||
}
|
}
|
||||||
else if ( IN_RANGE_CHAR(ch, 'a', 'f') )
|
else if ( IN_RANGE_CHAR( ch, 'a', 'f' ) )
|
||||||
{
|
{
|
||||||
val <<= 4;
|
val <<= 4;
|
||||||
val += ch - 'a' + 10;
|
val += ch - 'a' + 10;
|
||||||
@ -855,7 +854,7 @@ inline bool atoo( string_t str, I *out )
|
|||||||
{
|
{
|
||||||
unsigned char ch = *str.ptr;
|
unsigned char ch = *str.ptr;
|
||||||
|
|
||||||
if ( IN_RANGE_CHAR(ch, '0', '7') )
|
if ( IN_RANGE_CHAR( ch, '0', '7' ) )
|
||||||
{
|
{
|
||||||
val <<= 3;
|
val <<= 3;
|
||||||
val += ch - '0';
|
val += ch - '0';
|
||||||
@ -898,7 +897,7 @@ inline int IsValidUTF8( unsigned char *src, unsigned int srclen )
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if ( IN_RANGE_CHAR(cp, 0xC2, 0xF4) )
|
else if ( IN_RANGE_CHAR( cp, 0xC2, 0xF4 ) )
|
||||||
{
|
{
|
||||||
if ( UTF8_2_LEAD(cp) )
|
if ( UTF8_2_LEAD(cp) )
|
||||||
{
|
{
|
||||||
@ -938,7 +937,7 @@ inline int IsValidUTF8( unsigned char *src, unsigned int srclen )
|
|||||||
|
|
||||||
if ( !UTF8_TRAIL(cp) )
|
if ( !UTF8_TRAIL(cp) )
|
||||||
{
|
{
|
||||||
if ( IN_RANGE_CHAR(cp, 0xC2, 0xF4) )
|
if ( IN_RANGE_CHAR( cp, 0xC2, 0xF4 ) )
|
||||||
goto check;
|
goto check;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -967,34 +966,8 @@ inline int IsValidUnicode( const SQChar *src, unsigned int srclen )
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if ( cp <= 0xFF )
|
else if ( cp < 0xA0 )
|
||||||
{
|
{
|
||||||
if ( IN_RANGE(cp, 0xC2, 0xF4) )
|
|
||||||
{
|
|
||||||
if ( UTF8_2_LEAD(cp) )
|
|
||||||
{
|
|
||||||
if ( UTF8_2( srclen, cp, src ) )
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( UTF8_3_LEAD(cp) )
|
|
||||||
{
|
|
||||||
if ( UTF8_3( srclen, cp, src ) )
|
|
||||||
{
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( UTF8_4_LEAD(cp) )
|
|
||||||
{
|
|
||||||
if ( UTF8_4( srclen, cp, src ) )
|
|
||||||
{
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else [0x7F, 0xC2) & (0xF4, 0xFF]
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1041,18 +1014,21 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
|||||||
{
|
{
|
||||||
switch ( ((unsigned char*)src)[1] )
|
switch ( ((unsigned char*)src)[1] )
|
||||||
{
|
{
|
||||||
case '\"': cp = '\"'; src++; break;
|
|
||||||
case '\\': src++; break;
|
case '\\': src++; break;
|
||||||
|
case '\"': cp = '\"'; src++; break;
|
||||||
|
case '\'': cp = '\''; src++; break;
|
||||||
|
case 'a': cp = '\a'; src++; break;
|
||||||
case 'b': cp = '\b'; src++; break;
|
case 'b': cp = '\b'; src++; break;
|
||||||
case 'f': cp = '\f'; src++; break;
|
case 'f': cp = '\f'; src++; break;
|
||||||
case 'n': cp = '\n'; src++; break;
|
case 'n': cp = '\n'; src++; break;
|
||||||
case 'r': cp = '\r'; src++; break;
|
case 'r': cp = '\r'; src++; break;
|
||||||
case 't': cp = '\t'; src++; break;
|
case 't': cp = '\t'; src++; break;
|
||||||
|
case 'v': cp = '\v'; src++; break;
|
||||||
case 'x':
|
case 'x':
|
||||||
{
|
{
|
||||||
if ( src + sizeof(SQChar) * 2 + 1 < end )
|
if ( src + sizeof(SQChar) * 2 + 1 < end )
|
||||||
{
|
{
|
||||||
Verify( atox( { src + 2, sizeof(SQChar) * 2 }, &cp ) );
|
atox( { src + 2, sizeof(SQChar) * 2 }, &cp );
|
||||||
src += sizeof(SQChar) * 2 + 1;
|
src += sizeof(SQChar) * 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1062,7 +1038,7 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
|||||||
{
|
{
|
||||||
if ( src + sizeof(uint16_t) * 2 + 1 < end )
|
if ( src + sizeof(uint16_t) * 2 + 1 < end )
|
||||||
{
|
{
|
||||||
Verify( atox( { src + 2, sizeof(uint16_t) * 2 }, &cp ) );
|
atox( { src + 2, sizeof(uint16_t) * 2 }, &cp );
|
||||||
src += sizeof(uint16_t) * 2 + 1;
|
src += sizeof(uint16_t) * 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,7 +1050,7 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
|||||||
|
|
||||||
goto xffff;
|
goto xffff;
|
||||||
}
|
}
|
||||||
else if ( IN_RANGE(cp, 0xC2, 0xF4) )
|
else if ( IN_RANGE( cp, 0xC2, 0xF4 ) )
|
||||||
{
|
{
|
||||||
if ( UTF8_2_LEAD(cp) )
|
if ( UTF8_2_LEAD(cp) )
|
||||||
{
|
{
|
||||||
@ -1111,34 +1087,13 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
|||||||
goto xffff;
|
goto xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xffff:
|
||||||
#if WCHAR_SIZE == 4
|
#if WCHAR_SIZE == 4
|
||||||
xffff:
|
|
||||||
supplementary:
|
supplementary:
|
||||||
|
#endif
|
||||||
if ( dst )
|
if ( dst )
|
||||||
{
|
{
|
||||||
if ( destSize >= sizeof(SQChar) )
|
if ( sizeof(SQChar) <= destSize )
|
||||||
{
|
|
||||||
*dst++ = cp;
|
|
||||||
destSize -= sizeof(SQChar);
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// out of space
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
#else // WCHAR_SIZE == 2
|
|
||||||
xffff:
|
|
||||||
if ( dst )
|
|
||||||
{
|
|
||||||
if ( destSize >= sizeof(SQChar) )
|
|
||||||
{
|
{
|
||||||
*dst++ = (SQChar)cp;
|
*dst++ = (SQChar)cp;
|
||||||
destSize -= sizeof(SQChar);
|
destSize -= sizeof(SQChar);
|
||||||
@ -1157,14 +1112,15 @@ xffff:
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#if WCHAR_SIZE == 2
|
||||||
supplementary:
|
supplementary:
|
||||||
if ( dst )
|
if ( dst )
|
||||||
{
|
{
|
||||||
if ( destSize > sizeof(SQChar) )
|
if ( sizeof(SQChar) * 2 <= destSize )
|
||||||
{
|
{
|
||||||
UTF16_SURROGATE_FROM_UTF32( dst, cp );
|
UTF16_SURROGATE_FROM_UTF32( dst, cp );
|
||||||
dst += 2;
|
dst += 2;
|
||||||
destSize -= 2 * sizeof(SQChar);
|
destSize -= sizeof(SQChar) * 2;
|
||||||
count += 2;
|
count += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1241,6 +1197,7 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
|||||||
|
|
||||||
switch ( cp )
|
switch ( cp )
|
||||||
{
|
{
|
||||||
|
case '\\':
|
||||||
case '\"':
|
case '\"':
|
||||||
if ( escape == kUTFEscapeQuoted )
|
if ( escape == kUTFEscapeQuoted )
|
||||||
{
|
{
|
||||||
@ -1248,16 +1205,15 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
|||||||
mbc[bytes++] = '\\';
|
mbc[bytes++] = '\\';
|
||||||
}
|
}
|
||||||
mbc[bytes++] = '\\';
|
mbc[bytes++] = '\\';
|
||||||
mbc[bytes++] = '\"';
|
mbc[bytes++] = (unsigned char)cp;
|
||||||
goto write;
|
goto write;
|
||||||
case '\\':
|
case '\a':
|
||||||
|
if ( escape == kUTFEscapeJSON )
|
||||||
|
goto doescape;
|
||||||
if ( escape == kUTFEscapeQuoted )
|
if ( escape == kUTFEscapeQuoted )
|
||||||
{
|
|
||||||
mbc[bytes++] = '\\';
|
mbc[bytes++] = '\\';
|
||||||
mbc[bytes++] = '\\';
|
|
||||||
}
|
|
||||||
mbc[bytes++] = '\\';
|
|
||||||
mbc[bytes++] = '\\';
|
mbc[bytes++] = '\\';
|
||||||
|
mbc[bytes++] = 'a';
|
||||||
goto write;
|
goto write;
|
||||||
case '\b':
|
case '\b':
|
||||||
if ( escape == kUTFEscapeQuoted )
|
if ( escape == kUTFEscapeQuoted )
|
||||||
@ -1289,15 +1245,25 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
|||||||
mbc[bytes++] = '\\';
|
mbc[bytes++] = '\\';
|
||||||
mbc[bytes++] = 't';
|
mbc[bytes++] = 't';
|
||||||
goto write;
|
goto write;
|
||||||
|
case '\v':
|
||||||
|
if ( escape == kUTFEscapeJSON )
|
||||||
|
goto doescape;
|
||||||
|
if ( escape == kUTFEscapeQuoted )
|
||||||
|
mbc[bytes++] = '\\';
|
||||||
|
mbc[bytes++] = '\\';
|
||||||
|
mbc[bytes++] = 'v';
|
||||||
|
goto write;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if ( !IN_RANGE_CHAR( cp, 0x20, 0x7E ) )
|
||||||
if ( !IN_RANGE_CHAR(cp, 0x20, 0x7E) )
|
|
||||||
{
|
{
|
||||||
// While UTF8 bytes are valid UTF16, converting them will
|
// Convert UTF8 bytes in UTF16 by default with the assumption of
|
||||||
// make distinct SQ strings indistinguishable to the client
|
// most editors using UTF8 without BOM,
|
||||||
#ifndef SQDBG_ESCAPE_UTF8_BYTES_IN_UTF16
|
// and files being likely read plain (no conversion/ISO 8859-1)
|
||||||
if ( IN_RANGE(cp, 0xC2, 0xF4) )
|
// However, this will make certain distinct SQ strings (e.g. "\xC3\xBC", "\xFC")
|
||||||
|
// indistinguishable to the client
|
||||||
|
#ifndef SQDBG_DONT_CONVERT_UTF8_BYTES_IN_UTF16
|
||||||
|
if ( IN_RANGE( cp, 0xC2, 0xF4 ) )
|
||||||
{
|
{
|
||||||
if ( UTF8_2_LEAD(cp) )
|
if ( UTF8_2_LEAD(cp) )
|
||||||
{
|
{
|
||||||
@ -1337,7 +1303,12 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// [0x7F, 0xC2) & (0xF4, 0xFF]
|
|
||||||
|
if ( cp >= 0xA0 ) // [0xA0, 0xFF]
|
||||||
|
goto x7ff;
|
||||||
|
|
||||||
|
doescape:
|
||||||
|
// [0x00, 0x20) & (0x7E, 0xA0)
|
||||||
if ( escape == kUTFEscapeQuoted )
|
if ( escape == kUTFEscapeQuoted )
|
||||||
mbc[bytes++] = '\\';
|
mbc[bytes++] = '\\';
|
||||||
|
|
||||||
@ -1351,7 +1322,7 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
mbc[bytes++] = 'x';
|
mbc[bytes++] = 'x';
|
||||||
bytes += printhex< true, false >( mbc + bytes, sizeof(mbc) - bytes, (SQChar)cp );
|
bytes += printhex< true, false >( mbc + bytes, sizeof(mbc) - bytes, (SQUnsignedChar)cp );
|
||||||
}
|
}
|
||||||
|
|
||||||
goto write;
|
goto write;
|
||||||
@ -1364,6 +1335,7 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
|||||||
}
|
}
|
||||||
else if ( cp <= 0x7FF )
|
else if ( cp <= 0x7FF )
|
||||||
{
|
{
|
||||||
|
x7ff:
|
||||||
UTF8_2_FROM_UTF32( mbc, cp );
|
UTF8_2_FROM_UTF32( mbc, cp );
|
||||||
bytes = 2;
|
bytes = 2;
|
||||||
}
|
}
|
||||||
@ -1387,7 +1359,7 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
|||||||
|
|
||||||
mbc[bytes++] = '\\';
|
mbc[bytes++] = '\\';
|
||||||
mbc[bytes++] = 'x';
|
mbc[bytes++] = 'x';
|
||||||
bytes = bytes + printhex< true, false >( mbc + bytes, sizeof(mbc) - bytes, (SQChar)cp );
|
bytes = bytes + printhex< true, false >( mbc + bytes, sizeof(mbc) - bytes, (SQUnsignedChar)cp );
|
||||||
goto write;
|
goto write;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1478,4 +1450,33 @@ write:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SQUNICODE) && !defined(_WIN32)
|
||||||
|
// Do case insensitive comparison for ASCII characters, ignore the rest
|
||||||
|
inline int sqdbg_wcsicmp( const SQChar *s1, const SQChar *s2 )
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
SQChar c1 = *s1++;
|
||||||
|
SQChar c2 = *s2++;
|
||||||
|
|
||||||
|
if ( !c1 || !c2 )
|
||||||
|
return c1 - c2;
|
||||||
|
|
||||||
|
if ( c1 == c2 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( c1 >= 'A' && c1 <= 'Z' )
|
||||||
|
c1 |= 0x20;
|
||||||
|
|
||||||
|
if ( c2 >= 'A' && c2 <= 'Z' )
|
||||||
|
c2 |= 0x20;
|
||||||
|
|
||||||
|
if ( c1 == c2 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return c1 - c2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // SQDBG_STRING_H
|
#endif // SQDBG_STRING_H
|
||||||
|
@ -111,7 +111,44 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template< int MEM_CACHE_CHUNKS_ALIGN = 2048 >
|
// GCC requires this to be outside of the class
|
||||||
|
template < bool S >
|
||||||
|
struct _CScratch_members;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct _CScratch_members< true >
|
||||||
|
{
|
||||||
|
int m_LastFreeChunk;
|
||||||
|
int m_LastFreeIndex;
|
||||||
|
int m_PrevChunk;
|
||||||
|
int m_PrevIndex;
|
||||||
|
|
||||||
|
int LastFreeChunk() { return m_LastFreeChunk; }
|
||||||
|
int LastFreeIndex() { return m_LastFreeIndex; }
|
||||||
|
int PrevChunk() { return m_PrevChunk; }
|
||||||
|
int PrevIndex() { return m_PrevIndex; }
|
||||||
|
|
||||||
|
void SetLastFreeChunk( int i ) { m_LastFreeChunk = i; }
|
||||||
|
void SetLastFreeIndex( int i ) { m_LastFreeIndex = i; }
|
||||||
|
void SetPrevChunk( int i ) { m_PrevChunk = i; }
|
||||||
|
void SetPrevIndex( int i ) { m_PrevIndex = i; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct _CScratch_members< false >
|
||||||
|
{
|
||||||
|
int LastFreeChunk() { return 0; }
|
||||||
|
int LastFreeIndex() { return 0; }
|
||||||
|
int PrevChunk() { return 0; }
|
||||||
|
int PrevIndex() { return 0; }
|
||||||
|
|
||||||
|
void SetLastFreeChunk( int ) {}
|
||||||
|
void SetLastFreeIndex( int ) {}
|
||||||
|
void SetPrevChunk( int ) {}
|
||||||
|
void SetPrevIndex( int ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< bool SEQUENTIAL, int MEM_CACHE_CHUNKS_ALIGN = 2048 >
|
||||||
class CScratch
|
class CScratch
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -126,8 +163,7 @@ public:
|
|||||||
|
|
||||||
chunk_t *m_Memory;
|
chunk_t *m_Memory;
|
||||||
int m_MemChunkCount;
|
int m_MemChunkCount;
|
||||||
int m_LastFreeChunk;
|
_CScratch_members< SEQUENTIAL > m;
|
||||||
int m_LastFreeIndex;
|
|
||||||
|
|
||||||
char *Get( int index )
|
char *Get( int index )
|
||||||
{
|
{
|
||||||
@ -145,7 +181,7 @@ public:
|
|||||||
return &chunk->ptr[ msgIdx * MEM_CACHE_CHUNKSIZE ];
|
return &chunk->ptr[ msgIdx * MEM_CACHE_CHUNKSIZE ];
|
||||||
}
|
}
|
||||||
|
|
||||||
char *Alloc( int size, int *index = NULL, bool sequential = true )
|
char *Alloc( int size, int *index = NULL )
|
||||||
{
|
{
|
||||||
if ( !m_Memory )
|
if ( !m_Memory )
|
||||||
{
|
{
|
||||||
@ -166,11 +202,11 @@ public:
|
|||||||
int chunkIdx;
|
int chunkIdx;
|
||||||
int matchedChunks = 0;
|
int matchedChunks = 0;
|
||||||
|
|
||||||
if ( sequential )
|
if ( SEQUENTIAL )
|
||||||
{
|
{
|
||||||
requiredChunks = ( size - 1 ) / MEM_CACHE_CHUNKSIZE + 1;
|
requiredChunks = ( size - 1 ) / MEM_CACHE_CHUNKSIZE + 1;
|
||||||
msgIdx = m_LastFreeIndex;
|
msgIdx = m.LastFreeIndex();
|
||||||
chunkIdx = m_LastFreeChunk;
|
chunkIdx = m.LastFreeChunk();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -184,14 +220,17 @@ public:
|
|||||||
chunk_t *chunk = &m_Memory[ chunkIdx ];
|
chunk_t *chunk = &m_Memory[ chunkIdx ];
|
||||||
Assert( chunk->count && chunk->ptr );
|
Assert( chunk->count && chunk->ptr );
|
||||||
|
|
||||||
if ( sequential )
|
if ( SEQUENTIAL )
|
||||||
{
|
{
|
||||||
int remainingChunks = chunk->count - msgIdx;
|
int remainingChunks = chunk->count - msgIdx;
|
||||||
|
|
||||||
if ( remainingChunks >= requiredChunks )
|
if ( remainingChunks >= requiredChunks )
|
||||||
{
|
{
|
||||||
m_LastFreeIndex = msgIdx + requiredChunks;
|
m.SetPrevChunk( m.LastFreeChunk() );
|
||||||
m_LastFreeChunk = chunkIdx;
|
m.SetPrevIndex( m.LastFreeIndex() );
|
||||||
|
|
||||||
|
m.SetLastFreeIndex( msgIdx + requiredChunks );
|
||||||
|
m.SetLastFreeChunk( chunkIdx );
|
||||||
|
|
||||||
if ( index )
|
if ( index )
|
||||||
{
|
{
|
||||||
@ -267,6 +306,7 @@ public:
|
|||||||
|
|
||||||
void Free( void *ptr )
|
void Free( void *ptr )
|
||||||
{
|
{
|
||||||
|
STATIC_ASSERT( !SEQUENTIAL );
|
||||||
Assert( m_Memory );
|
Assert( m_Memory );
|
||||||
Assert( ptr );
|
Assert( ptr );
|
||||||
|
|
||||||
@ -290,7 +330,8 @@ public:
|
|||||||
|
|
||||||
Assert( found );
|
Assert( found );
|
||||||
|
|
||||||
(*(unsigned char**)&ptr)[ *(int*)ptr + sizeof(int) - 1 ] = 0xdd;
|
if ( *(int*)ptr )
|
||||||
|
(*(unsigned char**)&ptr)[ *(int*)ptr + sizeof(int) - 1 ] = 0xdd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset( (char*)ptr, 0, *(int*)ptr + sizeof(int) );
|
memset( (char*)ptr, 0, *(int*)ptr + sizeof(int) );
|
||||||
@ -315,12 +356,16 @@ public:
|
|||||||
|
|
||||||
m_Memory = NULL;
|
m_Memory = NULL;
|
||||||
m_MemChunkCount = 4;
|
m_MemChunkCount = 4;
|
||||||
m_LastFreeChunk = 0;
|
m.SetLastFreeChunk( 0 );
|
||||||
m_LastFreeIndex = 0;
|
m.SetLastFreeIndex( 0 );
|
||||||
|
m.SetPrevChunk( 0 );
|
||||||
|
m.SetPrevIndex( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReleaseShrink()
|
void ReleaseShrink()
|
||||||
{
|
{
|
||||||
|
STATIC_ASSERT( SEQUENTIAL );
|
||||||
|
|
||||||
if ( !m_Memory )
|
if ( !m_Memory )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -359,13 +404,17 @@ public:
|
|||||||
AssertOOM( m_Memory, m_MemChunkCount * sizeof(chunk_t) );
|
AssertOOM( m_Memory, m_MemChunkCount * sizeof(chunk_t) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LastFreeChunk = 0;
|
m.SetLastFreeChunk( 0 );
|
||||||
m_LastFreeIndex = 0;
|
m.SetLastFreeIndex( 0 );
|
||||||
|
m.SetPrevChunk( 0 );
|
||||||
|
m.SetPrevIndex( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Release()
|
void Release()
|
||||||
{
|
{
|
||||||
if ( !m_Memory || ( !m_LastFreeChunk && !m_LastFreeIndex ) )
|
STATIC_ASSERT( SEQUENTIAL );
|
||||||
|
|
||||||
|
if ( !m_Memory || ( !m.LastFreeChunk() && !m.LastFreeIndex() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -380,8 +429,18 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_LastFreeChunk = 0;
|
m.SetLastFreeChunk( 0 );
|
||||||
m_LastFreeIndex = 0;
|
m.SetLastFreeIndex( 0 );
|
||||||
|
m.SetPrevChunk( 0 );
|
||||||
|
m.SetPrevIndex( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReleaseTop()
|
||||||
|
{
|
||||||
|
STATIC_ASSERT( SEQUENTIAL );
|
||||||
|
|
||||||
|
m.SetLastFreeChunk( m.PrevChunk() );
|
||||||
|
m.SetLastFreeIndex( m.PrevIndex() );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -391,212 +450,212 @@ class vector
|
|||||||
public:
|
public:
|
||||||
typedef unsigned int I;
|
typedef unsigned int I;
|
||||||
|
|
||||||
CAllocator _base;
|
CAllocator base;
|
||||||
I _size;
|
I size;
|
||||||
|
|
||||||
vector() : _base(), _size(0)
|
vector() : base(), size(0)
|
||||||
{
|
{
|
||||||
Assert( !bExternalMem );
|
STATIC_ASSERT( !bExternalMem );
|
||||||
}
|
}
|
||||||
|
|
||||||
vector( CAllocator &a ) : _base(a), _size(0)
|
vector( CAllocator &a ) : base(a), size(0)
|
||||||
{
|
{
|
||||||
Assert( bExternalMem );
|
STATIC_ASSERT( bExternalMem );
|
||||||
}
|
}
|
||||||
|
|
||||||
vector( I count ) : _base(), _size(0)
|
vector( I count ) : base(), size(0)
|
||||||
{
|
{
|
||||||
Assert( !bExternalMem );
|
STATIC_ASSERT( !bExternalMem );
|
||||||
_base.Alloc( count * sizeof(T) );
|
base.Alloc( count * sizeof(T) );
|
||||||
}
|
}
|
||||||
|
|
||||||
vector( const vector< T > &src ) : _base()
|
vector( const vector< T > &src ) : base()
|
||||||
{
|
{
|
||||||
Assert( !bExternalMem );
|
STATIC_ASSERT( !bExternalMem );
|
||||||
_base.Alloc( src._base.Size() );
|
base.Alloc( src.base.Size() );
|
||||||
_size = src._size;
|
size = src.size;
|
||||||
|
|
||||||
for ( I i = 0; i < _size; i++ )
|
for ( I i = 0; i < size; i++ )
|
||||||
new( &_base[ i * sizeof(T) ] ) T( (T&)src._base[ i * sizeof(T) ] );
|
new( &base[ i * sizeof(T) ] ) T( (T&)src.base[ i * sizeof(T) ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
~vector()
|
~vector()
|
||||||
{
|
{
|
||||||
Assert( (unsigned int)_size <= _base.Size() );
|
Assert( (unsigned int)size <= base.Size() );
|
||||||
|
|
||||||
for ( I i = 0; i < _size; i++ )
|
for ( I i = 0; i < size; i++ )
|
||||||
((T&)(_base[ i * sizeof(T) ])).~T();
|
((T&)(base[ i * sizeof(T) ])).~T();
|
||||||
|
|
||||||
if ( !bExternalMem )
|
if ( !bExternalMem )
|
||||||
_base.Free();
|
base.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator[]( I i ) const
|
T &operator[]( I i ) const
|
||||||
{
|
{
|
||||||
Assert( _size > 0 );
|
Assert( size > 0 );
|
||||||
Assert( i >= 0 && i < _size );
|
Assert( i >= 0 && i < size );
|
||||||
Assert( _size * sizeof(T) <= _base.Size() );
|
Assert( size * sizeof(T) <= base.Size() );
|
||||||
return (T&)_base[ i * sizeof(T) ];
|
return (T&)base[ i * sizeof(T) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *base()
|
T *Base()
|
||||||
{
|
{
|
||||||
return _base.Base();
|
return base.Base();
|
||||||
}
|
}
|
||||||
|
|
||||||
I size() const
|
I Size() const
|
||||||
{
|
{
|
||||||
return _size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
I capacity() const
|
I Capacity() const
|
||||||
{
|
{
|
||||||
return _base.Size() / sizeof(T);
|
return base.Size() / sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
T &top() const
|
T &Top() const
|
||||||
{
|
{
|
||||||
Assert( _size > 0 );
|
Assert( size > 0 );
|
||||||
return (T&)_base[ ( _size - 1 ) * sizeof(T) ];
|
return (T&)base[ ( size - 1 ) * sizeof(T) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop()
|
void Pop()
|
||||||
{
|
{
|
||||||
Assert( _size > 0 );
|
Assert( size > 0 );
|
||||||
((T&)_base[ --_size * sizeof(T) ]).~T();
|
((T&)base[ --size * sizeof(T) ]).~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
T &append()
|
T &Append()
|
||||||
{
|
{
|
||||||
_base.Ensure( ++_size * sizeof(T) );
|
base.Ensure( ++size * sizeof(T) );
|
||||||
Assert( _size * sizeof(T) <= _base.Size() );
|
Assert( size * sizeof(T) <= base.Size() );
|
||||||
return *( new( &_base[ ( _size - 1 ) * sizeof(T) ] ) T() );
|
return *( new( &base[ ( size - 1 ) * sizeof(T) ] ) T() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void append( const T &src )
|
void Append( const T &src )
|
||||||
{
|
{
|
||||||
_base.Ensure( ++_size * sizeof(T) );
|
base.Ensure( ++size * sizeof(T) );
|
||||||
Assert( _size * sizeof(T) <= _base.Size() );
|
Assert( size * sizeof(T) <= base.Size() );
|
||||||
new( &_base[ ( _size - 1 ) * sizeof(T) ] ) T( src );
|
new( &base[ ( size - 1 ) * sizeof(T) ] ) T( src );
|
||||||
}
|
}
|
||||||
|
|
||||||
T &insert( I i )
|
T &Insert( I i )
|
||||||
{
|
{
|
||||||
Assert( i >= 0 && i <= _size );
|
Assert( i >= 0 && i <= size );
|
||||||
|
|
||||||
_base.Ensure( ++_size * sizeof(T) );
|
base.Ensure( ++size * sizeof(T) );
|
||||||
Assert( _size * sizeof(T) <= _base.Size() );
|
Assert( size * sizeof(T) <= base.Size() );
|
||||||
|
|
||||||
if ( i != _size - 1 )
|
if ( i != size - 1 )
|
||||||
{
|
{
|
||||||
memmove( &_base[ ( i + 1 ) * sizeof(T) ],
|
memmove( &base[ ( i + 1 ) * sizeof(T) ],
|
||||||
&_base[ i * sizeof(T) ],
|
&base[ i * sizeof(T) ],
|
||||||
( _size - ( i + 1 ) ) * sizeof(T) );
|
( size - ( i + 1 ) ) * sizeof(T) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return *( new( &_base[ i * sizeof(T) ] ) T() );
|
return *( new( &base[ i * sizeof(T) ] ) T() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove( I i )
|
void Remove( I i )
|
||||||
{
|
{
|
||||||
Assert( _size > 0 );
|
Assert( size > 0 );
|
||||||
Assert( i >= 0 && i < _size );
|
Assert( i >= 0 && i < size );
|
||||||
|
|
||||||
((T&)_base[ i * sizeof(T) ]).~T();
|
((T&)base[ i * sizeof(T) ]).~T();
|
||||||
|
|
||||||
if ( i != _size - 1 )
|
if ( i != size - 1 )
|
||||||
{
|
{
|
||||||
memmove( &_base[ i * sizeof(T) ],
|
memmove( &base[ i * sizeof(T) ],
|
||||||
&_base[ ( i + 1 ) * sizeof(T) ],
|
&base[ ( i + 1 ) * sizeof(T) ],
|
||||||
( _size - ( i + 1 ) ) * sizeof(T) );
|
( size - ( i + 1 ) ) * sizeof(T) );
|
||||||
}
|
}
|
||||||
|
|
||||||
_size--;
|
size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
for ( I i = 0; i < _size; i++ )
|
for ( I i = 0; i < size; i++ )
|
||||||
((T&)_base[ i * sizeof(T) ]).~T();
|
((T&)base[ i * sizeof(T) ]).~T();
|
||||||
|
|
||||||
_size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sort( int (*fn)(const T *, const T *) )
|
void Sort( int (*fn)(const T *, const T *) )
|
||||||
{
|
{
|
||||||
Assert( _size * sizeof(T) <= _base.Size() );
|
Assert( size * sizeof(T) <= base.Size() );
|
||||||
|
|
||||||
if ( _size > 1 )
|
if ( size > 1 )
|
||||||
{
|
{
|
||||||
qsort( _base.Base(), _size, sizeof(T), (int (*)(const void *, const void *))fn );
|
qsort( base.Base(), size, sizeof(T), (int (*)(const void *, const void *))fn );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve( I count )
|
void Reserve( I count )
|
||||||
{
|
{
|
||||||
Assert( (unsigned int)_size <= _base.Size() );
|
Assert( (unsigned int)size <= base.Size() );
|
||||||
|
|
||||||
if ( count == 0 )
|
if ( count == 0 )
|
||||||
count = 4;
|
count = 4;
|
||||||
|
|
||||||
if ( (unsigned int)count == _base.Size() )
|
if ( (unsigned int)count == base.Size() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for ( I i = count; i < _size; i++ )
|
for ( I i = count; i < size; i++ )
|
||||||
((T&)_base[ i * sizeof(T) ]).~T();
|
((T&)base[ i * sizeof(T) ]).~T();
|
||||||
|
|
||||||
_base.Alloc( count * sizeof(T) );
|
base.Alloc( count * sizeof(T) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void purge()
|
void Purge()
|
||||||
{
|
{
|
||||||
Assert( _size * sizeof(T) <= _base.Size() );
|
Assert( size * sizeof(T) <= base.Size() );
|
||||||
|
|
||||||
for ( I i = 0; i < _size; i++ )
|
for ( I i = 0; i < size; i++ )
|
||||||
((T&)_base[ i * sizeof(T) ]).~T();
|
((T&)base[ i * sizeof(T) ]).~T();
|
||||||
|
|
||||||
_base.Free();
|
base.Free();
|
||||||
_size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBuffer
|
class CBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMemory _base;
|
CMemory base;
|
||||||
int _size;
|
int size;
|
||||||
int _offset;
|
int offset;
|
||||||
|
|
||||||
char *base()
|
char *Base()
|
||||||
{
|
{
|
||||||
return _base.Base() + _offset;
|
return base.Base() + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size() const
|
int Size() const
|
||||||
{
|
{
|
||||||
return _size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int capacity() const
|
int Capacity() const
|
||||||
{
|
{
|
||||||
return _base.Size();
|
return base.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve( int count )
|
void Reserve( int count )
|
||||||
{
|
{
|
||||||
Assert( (unsigned int)_size <= _base.Size() );
|
Assert( (unsigned int)size <= base.Size() );
|
||||||
|
|
||||||
if ( (unsigned int)count == _base.Size() )
|
if ( (unsigned int)count == base.Size() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_base.Alloc( count );
|
base.Alloc( count );
|
||||||
}
|
}
|
||||||
|
|
||||||
void purge()
|
void Purge()
|
||||||
{
|
{
|
||||||
_base.Free();
|
base.Free();
|
||||||
_size = 0;
|
size = 0;
|
||||||
_offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -608,16 +667,16 @@ public:
|
|||||||
|
|
||||||
CBufTmpCache( CBuffer *b ) :
|
CBufTmpCache( CBuffer *b ) :
|
||||||
buffer(b),
|
buffer(b),
|
||||||
size(buffer->_size)
|
size(buffer->size)
|
||||||
{
|
{
|
||||||
buffer->_offset += buffer->_size;
|
buffer->offset += buffer->size;
|
||||||
buffer->_size = 0;
|
buffer->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
~CBufTmpCache()
|
~CBufTmpCache()
|
||||||
{
|
{
|
||||||
buffer->_offset -= size;
|
buffer->offset -= size;
|
||||||
buffer->_size = size;
|
buffer->size = size;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
IScriptVM* makeSquirrelVM();
|
IScriptVM* makeSquirrelVM();
|
||||||
|
|
||||||
int vscript_token = 0;
|
int vscript_token = 0;
|
||||||
int vscript_debugger_port = 0;
|
|
||||||
|
|
||||||
class CScriptManager : public CTier1AppSystem<IScriptManager>
|
class CScriptManager : public CTier1AppSystem<IScriptManager>
|
||||||
{
|
{
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
virtual bool Init() override;
|
virtual bool Init() override;
|
||||||
virtual void Shutdown() override;
|
virtual void Shutdown() override;
|
||||||
|
|
||||||
virtual bool ConnectDebugger( int port = 0 ) override;
|
virtual bool ConnectDebugger( int port = 0, float timeout = 0.0f ) override;
|
||||||
virtual void DisconnectDebugger() override;
|
virtual void DisconnectDebugger() override;
|
||||||
|
|
||||||
virtual ScriptLanguage_t GetLanguage() override;
|
virtual ScriptLanguage_t GetLanguage() override;
|
||||||
@ -284,6 +284,14 @@ public:
|
|||||||
WriteObject( (const SQObjectPtr&)obj, pBuffer, writeState );
|
WriteObject( (const SQObjectPtr&)obj, pBuffer, writeState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteObject( SQGenerator *pObj, CUtlBuffer* pBuffer, WriteStateMap& writeState )
|
||||||
|
{
|
||||||
|
SQObject obj;
|
||||||
|
obj._type = OT_GENERATOR;
|
||||||
|
obj._unVal.pUserPointer = pObj;
|
||||||
|
WriteObject( (const SQObjectPtr&)obj, pBuffer, writeState );
|
||||||
|
}
|
||||||
|
|
||||||
void ReadObject( SQObjectPtr &obj, CUtlBuffer* pBuffer, ReadStateMap& readState );
|
void ReadObject( SQObjectPtr &obj, CUtlBuffer* pBuffer, ReadStateMap& readState );
|
||||||
|
|
||||||
// Do not implicity add/remove ref
|
// Do not implicity add/remove ref
|
||||||
@ -327,7 +335,16 @@ namespace SQVector
|
|||||||
}
|
}
|
||||||
|
|
||||||
SQUserPointer p;
|
SQUserPointer p;
|
||||||
sq_getinstanceup(vm, 1, &p, 0);
|
if (SQ_FAILED(sq_getinstanceup(vm, 1, &p, 0)))
|
||||||
|
{
|
||||||
|
return SQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Accessed null instance");
|
||||||
|
}
|
||||||
|
|
||||||
new (p) Vector(x, y, z);
|
new (p) Vector(x, y, z);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -343,7 +360,7 @@ namespace SQVector
|
|||||||
return sq_throwerror(vm, "Expected Vector._get(string)");
|
return sq_throwerror(vm, "Expected Vector._get(string)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key[0] < 'x' || key['0'] > 'z' || key[1] != '\0')
|
if (key[0] < 'x' || key[0] > 'z' || key[1] != '\0')
|
||||||
{
|
{
|
||||||
return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
||||||
}
|
}
|
||||||
@ -369,7 +386,7 @@ namespace SQVector
|
|||||||
return sq_throwerror(vm, "Expected Vector._set(string)");
|
return sq_throwerror(vm, "Expected Vector._set(string)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key[0] < 'x' || key['0'] > 'z' || key[1] != '\0')
|
if (key[0] < 'x' || key[0] > 'z' || key[1] != '\0')
|
||||||
{
|
{
|
||||||
return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
||||||
}
|
}
|
||||||
@ -1315,10 +1332,7 @@ bool getVariant(HSQUIRRELVM vm, SQInteger idx, ScriptVariant_t& variant)
|
|||||||
case OT_INSTANCE:
|
case OT_INSTANCE:
|
||||||
{
|
{
|
||||||
Vector* v = nullptr;
|
Vector* v = nullptr;
|
||||||
SQUserPointer tag;
|
if (SQ_SUCCEEDED(sq_getinstanceup(vm, idx, (SQUserPointer*)&v, TYPETAG_VECTOR)))
|
||||||
if (SQ_SUCCEEDED(sq_gettypetag(vm, idx, &tag)) &&
|
|
||||||
tag == TYPETAG_VECTOR &&
|
|
||||||
SQ_SUCCEEDED(sq_getinstanceup(vm, idx, (SQUserPointer*)&v, TYPETAG_VECTOR)))
|
|
||||||
{
|
{
|
||||||
variant.Free();
|
variant.Free();
|
||||||
variant = (Vector*)malloc(sizeof(Vector));
|
variant = (Vector*)malloc(sizeof(Vector));
|
||||||
@ -1347,12 +1361,10 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
|||||||
{
|
{
|
||||||
SQInteger top = sq_gettop(vm);
|
SQInteger top = sq_gettop(vm);
|
||||||
|
|
||||||
SQUserPointer userptr = nullptr;
|
ScriptFunctionBinding_t* pFunc = nullptr;
|
||||||
sq_getuserpointer(vm, top, &userptr);
|
sq_getuserpointer(vm, top, (SQUserPointer*)&pFunc);
|
||||||
|
|
||||||
Assert(userptr);
|
Assert(pFunc);
|
||||||
|
|
||||||
ScriptFunctionBinding_t* pFunc = (ScriptFunctionBinding_t*)userptr;
|
|
||||||
|
|
||||||
int nargs = pFunc->m_desc.m_Parameters.Count();
|
int nargs = pFunc->m_desc.m_Parameters.Count();
|
||||||
int nLastHScriptIdx = -1;
|
int nLastHScriptIdx = -1;
|
||||||
@ -1449,15 +1461,30 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
|||||||
|
|
||||||
if (pFunc->m_flags & SF_MEMBER_FUNC)
|
if (pFunc->m_flags & SF_MEMBER_FUNC)
|
||||||
{
|
{
|
||||||
SQUserPointer self;
|
ClassInstanceData* classInstanceData;
|
||||||
sq_getinstanceup(vm, 1, &self, nullptr);
|
if (SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0)))
|
||||||
|
{
|
||||||
|
return SQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!self)
|
if (!classInstanceData)
|
||||||
{
|
{
|
||||||
return sq_throwerror(vm, "Accessed null instance");
|
return sq_throwerror(vm, "Accessed null instance");
|
||||||
}
|
}
|
||||||
|
|
||||||
instance = ((ClassInstanceData*)self)->instance;
|
// check that the type of self, or any basetype, matches the function description
|
||||||
|
ScriptClassDesc_t *selfType = classInstanceData->desc;
|
||||||
|
while (selfType != pFunc->m_desc.m_pScriptClassDesc)
|
||||||
|
{
|
||||||
|
if (!selfType)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Mismatched instance type");
|
||||||
|
}
|
||||||
|
selfType = selfType->m_pBaseDesc;
|
||||||
|
Assert(selfType != classInstanceData->desc); // there should be no infinite loop
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = classInstanceData->instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptVariant_t script_retval;
|
ScriptVariant_t script_retval;
|
||||||
@ -1466,8 +1493,6 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
|||||||
SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr(vm);
|
SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr(vm);
|
||||||
Assert(pSquirrelVM);
|
Assert(pSquirrelVM);
|
||||||
|
|
||||||
sq_resetobject(&pSquirrelVM->lastError_);
|
|
||||||
|
|
||||||
bool call_success = (*pFunc->m_pfnBinding)(pFunc->m_pFunction, instance, params.Base(), nargs,
|
bool call_success = (*pFunc->m_pfnBinding)(pFunc->m_pFunction, instance, params.Base(), nargs,
|
||||||
pFunc->m_desc.m_ReturnType == FIELD_VOID ? nullptr : &script_retval, script_retval_storage);
|
pFunc->m_desc.m_ReturnType == FIELD_VOID ? nullptr : &script_retval, script_retval_storage);
|
||||||
Assert(call_success);
|
Assert(call_success);
|
||||||
@ -1477,6 +1502,7 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
|||||||
if (!sq_isnull(pSquirrelVM->lastError_))
|
if (!sq_isnull(pSquirrelVM->lastError_))
|
||||||
{
|
{
|
||||||
sq_pushobject(vm, pSquirrelVM->lastError_);
|
sq_pushobject(vm, pSquirrelVM->lastError_);
|
||||||
|
sq_release(vm, &pSquirrelVM->lastError_);
|
||||||
sq_resetobject(&pSquirrelVM->lastError_);
|
sq_resetobject(&pSquirrelVM->lastError_);
|
||||||
sq_retval = sq_throwobject(vm);
|
sq_retval = sq_throwobject(vm);
|
||||||
}
|
}
|
||||||
@ -1546,28 +1572,42 @@ SQInteger destructor_stub_instance(SQUserPointer p, SQInteger size)
|
|||||||
SQInteger constructor_stub(HSQUIRRELVM vm)
|
SQInteger constructor_stub(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
ScriptClassDesc_t* pClassDesc = nullptr;
|
ScriptClassDesc_t* pClassDesc = nullptr;
|
||||||
sq_gettypetag(vm, 1, (SQUserPointer*)&pClassDesc);
|
if (SQ_FAILED(sq_gettypetag(vm, 1, (SQUserPointer*)&pClassDesc)))
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Expected native class");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pClassDesc || (void*)pClassDesc == TYPETAG_VECTOR)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Unable to obtain native class description");
|
||||||
|
}
|
||||||
|
|
||||||
if (!pClassDesc->m_pfnConstruct)
|
if (!pClassDesc->m_pfnConstruct)
|
||||||
{
|
{
|
||||||
return sqstd_throwerrorf(vm, "Unable to construct instances of %s", pClassDesc->m_pszScriptName);
|
return sqstd_throwerrorf(vm, "Unable to construct instances of %s", pClassDesc->m_pszScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr(vm);
|
SQUserPointer p;
|
||||||
Assert(pSquirrelVM);
|
if (SQ_FAILED(sq_getinstanceup(vm, 1, &p, 0)))
|
||||||
|
{
|
||||||
|
return SQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
sq_resetobject(&pSquirrelVM->lastError_);
|
if (!p)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Accessed null instance");
|
||||||
|
}
|
||||||
|
|
||||||
void* instance = pClassDesc->m_pfnConstruct();
|
void* instance = pClassDesc->m_pfnConstruct();
|
||||||
|
|
||||||
|
#ifdef DBGFLAG_ASSERT
|
||||||
|
SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr(vm);
|
||||||
|
Assert(pSquirrelVM);
|
||||||
// expect construction to always succeed
|
// expect construction to always succeed
|
||||||
Assert(sq_isnull(pSquirrelVM->lastError_));
|
Assert(sq_isnull(pSquirrelVM->lastError_));
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
new(p) ClassInstanceData(instance, pClassDesc, nullptr, true);
|
||||||
SQUserPointer p;
|
|
||||||
sq_getinstanceup(vm, 1, &p, 0);
|
|
||||||
new(p) ClassInstanceData(instance, pClassDesc, nullptr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
sq_setreleasehook(vm, 1, &destructor_stub);
|
sq_setreleasehook(vm, 1, &destructor_stub);
|
||||||
|
|
||||||
@ -1577,7 +1617,10 @@ SQInteger constructor_stub(HSQUIRRELVM vm)
|
|||||||
SQInteger tostring_stub(HSQUIRRELVM vm)
|
SQInteger tostring_stub(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
ClassInstanceData* classInstanceData = nullptr;
|
ClassInstanceData* classInstanceData = nullptr;
|
||||||
sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0);
|
if (SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0)))
|
||||||
|
{
|
||||||
|
return SQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
char buffer[128] = "";
|
char buffer[128] = "";
|
||||||
|
|
||||||
@ -1607,7 +1650,10 @@ SQInteger tostring_stub(HSQUIRRELVM vm)
|
|||||||
SQInteger get_stub(HSQUIRRELVM vm)
|
SQInteger get_stub(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
ClassInstanceData* classInstanceData = nullptr;
|
ClassInstanceData* classInstanceData = nullptr;
|
||||||
sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0);
|
if (SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0)))
|
||||||
|
{
|
||||||
|
return SQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
const char* key = nullptr;
|
const char* key = nullptr;
|
||||||
sq_getstring(vm, 2, &key);
|
sq_getstring(vm, 2, &key);
|
||||||
@ -1629,7 +1675,19 @@ SQInteger get_stub(HSQUIRRELVM vm)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sq_retval = sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
// Fallback
|
||||||
|
// Extra stack variables don't need to be popped, they are cleaned up on exit
|
||||||
|
sq_pushroottable(vm);
|
||||||
|
sq_push(vm, -2);
|
||||||
|
|
||||||
|
if ( SQ_SUCCEEDED( sq_rawget(vm, -2) ) )
|
||||||
|
{
|
||||||
|
sq_retval = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sq_retval = sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var.Free();
|
var.Free();
|
||||||
@ -1639,7 +1697,10 @@ SQInteger get_stub(HSQUIRRELVM vm)
|
|||||||
SQInteger set_stub(HSQUIRRELVM vm)
|
SQInteger set_stub(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
ClassInstanceData* classInstanceData = nullptr;
|
ClassInstanceData* classInstanceData = nullptr;
|
||||||
sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0);
|
if (SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0)))
|
||||||
|
{
|
||||||
|
return SQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
const char* key = nullptr;
|
const char* key = nullptr;
|
||||||
sq_getstring(vm, 2, &key);
|
sq_getstring(vm, 2, &key);
|
||||||
@ -1660,11 +1721,24 @@ SQInteger set_stub(HSQUIRRELVM vm)
|
|||||||
classInstanceData->desc->pHelper->Set(classInstanceData->instance, key, var)
|
classInstanceData->desc->pHelper->Set(classInstanceData->instance, key, var)
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
sq_retval = sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
// Fallback
|
||||||
|
sq_pushroottable(vm);
|
||||||
|
sq_push(vm, -3);
|
||||||
|
sq_push(vm, -3);
|
||||||
|
|
||||||
|
if ( SQ_SUCCEEDED( sq_rawset(vm, -3) ) )
|
||||||
|
{
|
||||||
|
// rawset doesn't return correctly, pop env to return val
|
||||||
|
sq_pop(vm, 1);
|
||||||
|
sq_retval = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sq_retval = sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var.Free();
|
var.Free();
|
||||||
sq_pop(vm, 1);
|
|
||||||
return sq_retval;
|
return sq_retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2058,17 +2132,26 @@ void SquirrelVM::Shutdown()
|
|||||||
|
|
||||||
bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing );
|
bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing );
|
||||||
|
|
||||||
bool SquirrelVM::ConnectDebugger( int port )
|
bool SquirrelVM::ConnectDebugger( int port, float timeout )
|
||||||
{
|
{
|
||||||
if ( !debugger_ )
|
if ( !debugger_ )
|
||||||
{
|
{
|
||||||
debugger_ = sqdbg_attach_debugger( vm_ );
|
debugger_ = sqdbg_attach_debugger( vm_ );
|
||||||
|
|
||||||
if ( sqdbg_listen_socket( debugger_, port ) != 0 )
|
if ( sqdbg_listen_socket( debugger_, port ) == 0 && timeout )
|
||||||
{
|
{
|
||||||
sqdbg_destroy_debugger( vm_ );
|
float startTime = Plat_FloatTime();
|
||||||
debugger_ = nullptr;
|
|
||||||
return false;
|
while ( !sqdbg_is_client_connected( debugger_ ) )
|
||||||
|
{
|
||||||
|
float time = Plat_FloatTime();
|
||||||
|
if ( time - startTime > timeout )
|
||||||
|
break;
|
||||||
|
|
||||||
|
ThreadSleep( 50 );
|
||||||
|
|
||||||
|
sqdbg_frame( debugger_ );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2514,13 +2597,16 @@ bool SquirrelVM::RegisterClass(ScriptClassDesc_t* pClassDesc)
|
|||||||
sq_newclosure(vm_, tostring_stub, 0);
|
sq_newclosure(vm_, tostring_stub, 0);
|
||||||
sq_newslot(vm_, -3, SQFalse);
|
sq_newslot(vm_, -3, SQFalse);
|
||||||
|
|
||||||
sq_pushstring(vm_, "_get", -1);
|
if ( pClassDesc->pHelper )
|
||||||
sq_newclosure(vm_, get_stub, 0);
|
{
|
||||||
sq_newslot(vm_, -3, SQFalse);
|
sq_pushstring(vm_, "_get", -1);
|
||||||
|
sq_newclosure(vm_, get_stub, 0);
|
||||||
|
sq_newslot(vm_, -3, SQFalse);
|
||||||
|
|
||||||
sq_pushstring(vm_, "_set", -1);
|
sq_pushstring(vm_, "_set", -1);
|
||||||
sq_newclosure(vm_, set_stub, 0);
|
sq_newclosure(vm_, set_stub, 0);
|
||||||
sq_newslot(vm_, -3, SQFalse);
|
sq_newslot(vm_, -3, SQFalse);
|
||||||
|
}
|
||||||
|
|
||||||
sq_pushstring(vm_, "IsValid", -1);
|
sq_pushstring(vm_, "IsValid", -1);
|
||||||
sq_newclosure(vm_, IsValid_stub, 0);
|
sq_newclosure(vm_, IsValid_stub, 0);
|
||||||
@ -2709,10 +2795,8 @@ void SquirrelVM::SetInstanceUniqeId(HSCRIPT hInstance, const char* pszId)
|
|||||||
HSQOBJECT* obj = (HSQOBJECT*)hInstance;
|
HSQOBJECT* obj = (HSQOBJECT*)hInstance;
|
||||||
sq_pushobject(vm_, *obj);
|
sq_pushobject(vm_, *obj);
|
||||||
|
|
||||||
SQUserPointer self;
|
ClassInstanceData* classInstanceData;
|
||||||
sq_getinstanceup(vm_, -1, &self, nullptr);
|
sq_getinstanceup(vm_, -1, (SQUserPointer*)&classInstanceData, nullptr);
|
||||||
|
|
||||||
auto classInstanceData = (ClassInstanceData*)self;
|
|
||||||
|
|
||||||
classInstanceData->instanceId = pszId;
|
classInstanceData->instanceId = pszId;
|
||||||
|
|
||||||
@ -2770,11 +2854,10 @@ void* SquirrelVM::GetInstanceValue(HSCRIPT hInstance, ScriptClassDesc_t* pExpect
|
|||||||
}
|
}
|
||||||
|
|
||||||
sq_pushobject(vm_, *obj);
|
sq_pushobject(vm_, *obj);
|
||||||
SQUserPointer self;
|
ClassInstanceData* classInstanceData;
|
||||||
sq_getinstanceup(vm_, -1, &self, nullptr);
|
sq_getinstanceup(vm_, -1, (SQUserPointer*)&classInstanceData, nullptr);
|
||||||
sq_pop(vm_, 1);
|
sq_pop(vm_, 1);
|
||||||
|
|
||||||
auto classInstanceData = (ClassInstanceData*)self;
|
|
||||||
|
|
||||||
if (!classInstanceData)
|
if (!classInstanceData)
|
||||||
{
|
{
|
||||||
@ -3366,7 +3449,8 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
|
|||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
bool bAsserted = false;
|
bool bAsserted = false;
|
||||||
|
|
||||||
if ( pThis->_noutervalues && pThis->_name._type == OT_STRING && pThis->_name._unVal.pString )
|
if ( pThis->_noutervalues && pThis->_name._type == OT_STRING && pThis->_name._unVal.pString &&
|
||||||
|
pThis->_outervalues[0]._type == OT_USERPOINTER )
|
||||||
{
|
{
|
||||||
Assert( pThis->_noutervalues == 1 );
|
Assert( pThis->_noutervalues == 1 );
|
||||||
Assert( pThis->_outervalues[0]._type == OT_USERPOINTER );
|
Assert( pThis->_outervalues[0]._type == OT_USERPOINTER );
|
||||||
@ -3669,23 +3753,25 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
|
|||||||
|
|
||||||
if ( pThis->_callsstacksize )
|
if ( pThis->_callsstacksize )
|
||||||
{
|
{
|
||||||
int stackidx = -1;
|
for ( int i = 0; i < pThis->_callsstacksize; i++ )
|
||||||
|
|
||||||
for ( int i = pThis->_callsstacksize; i--; )
|
|
||||||
{
|
{
|
||||||
const SQVM::CallInfo *ci = &pThis->_callsstack[i];
|
const SQVM::CallInfo *ci = &pThis->_callsstack[i];
|
||||||
|
|
||||||
if ( pThis->ci == ci )
|
Assert( ci->_ip >= ci->_closure._unVal.pClosure->_function->_instructions &&
|
||||||
stackidx = i;
|
ci->_ip < ci->_closure._unVal.pClosure->_function->_instructions +
|
||||||
|
ci->_closure._unVal.pClosure->_function->_ninstructions );
|
||||||
Assert( !ci->_generator );
|
|
||||||
Assert( ci->_ip && ci->_ip >= ci->_closure._unVal.pClosure->_function->_instructions );
|
|
||||||
Assert( pThis->_etraps.size() >= (SQUnsignedInteger)ci->_etraps );
|
Assert( pThis->_etraps.size() >= (SQUnsignedInteger)ci->_etraps );
|
||||||
Assert( ci->_closure._type == OT_CLOSURE && ci->_closure._unVal.pClosure );
|
Assert( ci->_closure._type == OT_CLOSURE && ci->_closure._unVal.pClosure );
|
||||||
|
|
||||||
WriteObject( ci->_closure, pBuffer, writeState );
|
WriteObject( ci->_closure, pBuffer, writeState );
|
||||||
|
|
||||||
int offset = (intp)ci->_ip - (intp)ci->_closure._unVal.pClosure->_function->_instructions;
|
Assert( ci->_ip - ci->_closure._unVal.pClosure->_function->_instructions <= INT_MAX );
|
||||||
|
|
||||||
|
pBuffer->PutChar( ci->_generator != 0 );
|
||||||
|
if ( ci->_generator )
|
||||||
|
WriteObject( ci->_generator, pBuffer, writeState );
|
||||||
|
|
||||||
|
int offset = ci->_ip - ci->_closure._unVal.pClosure->_function->_instructions;
|
||||||
pBuffer->PutInt( offset );
|
pBuffer->PutInt( offset );
|
||||||
pBuffer->PutInt( ci->_etraps );
|
pBuffer->PutInt( ci->_etraps );
|
||||||
pBuffer->PutInt( ci->_prevstkbase );
|
pBuffer->PutInt( ci->_prevstkbase );
|
||||||
@ -3694,16 +3780,18 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
|
|||||||
pBuffer->PutInt( ci->_ncalls );
|
pBuffer->PutInt( ci->_ncalls );
|
||||||
pBuffer->PutChar( ci->_root );
|
pBuffer->PutChar( ci->_root );
|
||||||
|
|
||||||
for ( int j = ci->_etraps; j--; )
|
for ( int j = 0; j < ci->_etraps; j++ )
|
||||||
{
|
{
|
||||||
const SQExceptionTrap &et = pThis->_etraps[j];
|
const SQExceptionTrap &et = pThis->_etraps[j];
|
||||||
pBuffer->PutInt( et._extarget );
|
|
||||||
pBuffer->PutInt( et._stackbase );
|
|
||||||
pBuffer->PutInt( et._stacksize );
|
pBuffer->PutInt( et._stacksize );
|
||||||
Assert( et._ip == ci->_ip );
|
pBuffer->PutInt( et._stackbase );
|
||||||
|
Assert( et._ip - ci->_ip <= INT_MAX );
|
||||||
|
pBuffer->PutInt( et._ip - ci->_ip );
|
||||||
|
pBuffer->PutInt( et._extarget );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stackidx = pThis->ci - pThis->_callsstack;
|
||||||
Assert( stackidx >= 0 && stackidx < pThis->_callsstacksize );
|
Assert( stackidx >= 0 && stackidx < pThis->_callsstacksize );
|
||||||
pBuffer->PutInt( stackidx );
|
pBuffer->PutInt( stackidx );
|
||||||
}
|
}
|
||||||
@ -3734,29 +3822,37 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
|
|||||||
|
|
||||||
WriteObject( pThis->_closure, pBuffer, writeState );
|
WriteObject( pThis->_closure, pBuffer, writeState );
|
||||||
|
|
||||||
const SQVM::CallInfo &ci = pThis->_ci;
|
const SQVM::CallInfo *ci = &pThis->_ci;
|
||||||
|
|
||||||
Assert( !ci._generator );
|
Assert( pThis->_closure._unVal.pClosure == ci->_closure._unVal.pClosure );
|
||||||
Assert( pThis->_closure._unVal.pClosure == ci._closure._unVal.pClosure );
|
Assert( ci->_ip >= ci->_closure._unVal.pClosure->_function->_instructions &&
|
||||||
Assert( ci._ip && ci._ip >= ci._closure._unVal.pClosure->_function->_instructions );
|
ci->_ip < ci->_closure._unVal.pClosure->_function->_instructions +
|
||||||
Assert( pThis->_etraps.size() >= (SQUnsignedInteger)ci._etraps );
|
ci->_closure._unVal.pClosure->_function->_ninstructions );
|
||||||
|
Assert( pThis->_etraps.size() >= (SQUnsignedInteger)ci->_etraps );
|
||||||
|
|
||||||
int offset = (intp)ci._ip - (intp)ci._closure._unVal.pClosure->_function->_instructions;
|
Assert( ci->_ip - ci->_closure._unVal.pClosure->_function->_instructions <= INT_MAX );
|
||||||
|
|
||||||
|
pBuffer->PutChar( ci->_generator != 0 );
|
||||||
|
if ( ci->_generator )
|
||||||
|
WriteObject( ci->_generator, pBuffer, writeState );
|
||||||
|
|
||||||
|
int offset = ci->_ip - ci->_closure._unVal.pClosure->_function->_instructions;
|
||||||
pBuffer->PutInt( offset );
|
pBuffer->PutInt( offset );
|
||||||
pBuffer->PutInt( ci._etraps );
|
pBuffer->PutInt( ci->_etraps );
|
||||||
pBuffer->PutInt( ci._prevstkbase );
|
pBuffer->PutInt( ci->_prevstkbase );
|
||||||
pBuffer->PutInt( ci._prevtop );
|
pBuffer->PutInt( ci->_prevtop );
|
||||||
pBuffer->PutInt( ci._target );
|
pBuffer->PutInt( ci->_target );
|
||||||
pBuffer->PutInt( ci._ncalls );
|
pBuffer->PutInt( ci->_ncalls );
|
||||||
pBuffer->PutChar( ci._root );
|
pBuffer->PutChar( ci->_root );
|
||||||
|
|
||||||
for ( int j = ci._etraps; j--; )
|
for ( int j = 0; j < ci->_etraps; j++ )
|
||||||
{
|
{
|
||||||
const SQExceptionTrap &et = pThis->_etraps[j];
|
const SQExceptionTrap &et = pThis->_etraps[j];
|
||||||
pBuffer->PutInt( et._extarget );
|
|
||||||
pBuffer->PutInt( et._stackbase );
|
|
||||||
pBuffer->PutInt( et._stacksize );
|
pBuffer->PutInt( et._stacksize );
|
||||||
Assert( et._ip == ci._ip );
|
pBuffer->PutInt( et._stackbase );
|
||||||
|
Assert( et._ip - ci->_ip <= INT_MAX );
|
||||||
|
pBuffer->PutInt( et._ip - ci->_ip );
|
||||||
|
pBuffer->PutInt( et._extarget );
|
||||||
}
|
}
|
||||||
|
|
||||||
int stacksize = pThis->_stack.size();
|
int stacksize = pThis->_stack.size();
|
||||||
@ -3770,7 +3866,6 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
|
|||||||
}
|
}
|
||||||
case OT_USERDATA:
|
case OT_USERDATA:
|
||||||
case OT_USERPOINTER:
|
case OT_USERPOINTER:
|
||||||
Assert(0);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AssertMsgAlways( 0, "SquirrelVM::WriteObject: unknown type" );
|
AssertMsgAlways( 0, "SquirrelVM::WriteObject: unknown type" );
|
||||||
@ -3814,26 +3909,10 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
|||||||
case OT_STRING:
|
case OT_STRING:
|
||||||
{
|
{
|
||||||
int len = pBuffer->GetInt();
|
int len = pBuffer->GetInt();
|
||||||
char *psz;
|
char *psz = (char*)pBuffer->PeekGet( 0 );
|
||||||
|
pBuffer->SeekGet( CUtlBuffer::SEEK_CURRENT, len );
|
||||||
if ( len < 1024 )
|
Assert( pBuffer->IsValid() );
|
||||||
{
|
|
||||||
psz = (char*)stackalloc( len );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
psz = (char*)malloc( len );
|
|
||||||
}
|
|
||||||
|
|
||||||
pBuffer->Get( psz, len );
|
|
||||||
|
|
||||||
obj._unVal.pString = SQString::Create( _ss(vm_), psz, len );
|
obj._unVal.pString = SQString::Create( _ss(vm_), psz, len );
|
||||||
|
|
||||||
if ( len >= 1024 )
|
|
||||||
{
|
|
||||||
free( psz );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OT_TABLE:
|
case OT_TABLE:
|
||||||
@ -4319,10 +4398,10 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
|||||||
|
|
||||||
if ( pThis->_callsstacksize )
|
if ( pThis->_callsstacksize )
|
||||||
{
|
{
|
||||||
if ( pThis->_callsstacksize >= pThis->_alloccallsstacksize )
|
while ( pThis->_callsstacksize >= pThis->_alloccallsstacksize )
|
||||||
pThis->GrowCallStack();
|
pThis->GrowCallStack();
|
||||||
|
|
||||||
for ( int i = pThis->_callsstacksize; i--; )
|
for ( int i = 0; i < pThis->_callsstacksize; i++ )
|
||||||
{
|
{
|
||||||
SQVM::CallInfo *ci = &pThis->_callsstack[i];
|
SQVM::CallInfo *ci = &pThis->_callsstack[i];
|
||||||
|
|
||||||
@ -4330,23 +4409,31 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
|||||||
ReadObject( closure, pBuffer, readState );
|
ReadObject( closure, pBuffer, readState );
|
||||||
Assert( closure._type == OT_CLOSURE && closure._unVal.pClosure );
|
Assert( closure._type == OT_CLOSURE && closure._unVal.pClosure );
|
||||||
|
|
||||||
int offset = pBuffer->GetInt();
|
if ( pBuffer->GetChar() )
|
||||||
int funcsize = sizeof(SQInstruction) * closure._unVal.pClosure->_function->_ninstructions;
|
|
||||||
int start = (intp)(closure._unVal.pClosure->_function->_instructions);
|
|
||||||
int pos = start + offset;
|
|
||||||
ci->_ip = (SQInstruction*)pos;
|
|
||||||
|
|
||||||
Assert( pos < (start + funcsize) );
|
|
||||||
|
|
||||||
// don't read past boundary
|
|
||||||
if ( pos >= (start + funcsize) )
|
|
||||||
{
|
{
|
||||||
ci->_ip = (SQInstruction*)start;
|
SQObject generator;
|
||||||
|
ReadObject( generator, pBuffer, readState );
|
||||||
|
Assert( generator._type == OT_GENERATOR && generator._unVal.pGenerator );
|
||||||
|
ci->_generator = generator._unVal.pGenerator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ci->_generator = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int offset = pBuffer->GetInt();
|
||||||
|
SQInstruction *start = closure._unVal.pClosure->_function->_instructions;
|
||||||
|
SQInstruction *end = start + closure._unVal.pClosure->_function->_ninstructions;
|
||||||
|
SQInstruction *pos = start + offset;
|
||||||
|
|
||||||
|
Assert( pos >= start && pos < end );
|
||||||
|
|
||||||
|
if ( pos < start || pos >= end )
|
||||||
|
pos = start;
|
||||||
|
|
||||||
|
ci->_ip = pos;
|
||||||
ci->_literals = closure._unVal.pClosure->_function->_literals;
|
ci->_literals = closure._unVal.pClosure->_function->_literals;
|
||||||
ci->_closure = closure;
|
ci->_closure = closure;
|
||||||
ci->_generator = NULL;
|
|
||||||
ci->_etraps = pBuffer->GetInt();
|
ci->_etraps = pBuffer->GetInt();
|
||||||
ci->_prevstkbase = pBuffer->GetInt();
|
ci->_prevstkbase = pBuffer->GetInt();
|
||||||
ci->_prevtop = pBuffer->GetInt();
|
ci->_prevtop = pBuffer->GetInt();
|
||||||
@ -4356,13 +4443,13 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
|||||||
|
|
||||||
pThis->_etraps.resize( ci->_etraps );
|
pThis->_etraps.resize( ci->_etraps );
|
||||||
|
|
||||||
for ( int j = ci->_etraps; j--; )
|
for ( int j = 0; j < ci->_etraps; j++ )
|
||||||
{
|
{
|
||||||
SQExceptionTrap &et = pThis->_etraps[j];
|
SQExceptionTrap &et = pThis->_etraps[j];
|
||||||
et._extarget = pBuffer->GetInt();
|
|
||||||
et._stackbase = pBuffer->GetInt();
|
|
||||||
et._stacksize = pBuffer->GetInt();
|
et._stacksize = pBuffer->GetInt();
|
||||||
et._ip = ci->_ip;
|
et._stackbase = pBuffer->GetInt();
|
||||||
|
et._ip = ci->_ip + pBuffer->GetInt();
|
||||||
|
et._extarget = pBuffer->GetInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4409,41 +4496,49 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
|||||||
|
|
||||||
pThis->_state = (SQGenerator::SQGeneratorState)state;
|
pThis->_state = (SQGenerator::SQGeneratorState)state;
|
||||||
|
|
||||||
SQVM::CallInfo &ci = pThis->_ci;
|
SQVM::CallInfo *ci = &pThis->_ci;
|
||||||
|
|
||||||
int offset = pBuffer->GetInt();
|
if ( pBuffer->GetChar() )
|
||||||
int funcsize = sizeof(SQInstruction) * closure._unVal.pClosure->_function->_ninstructions;
|
|
||||||
int start = (intp)(closure._unVal.pClosure->_function->_instructions);
|
|
||||||
int pos = start + offset;
|
|
||||||
ci._ip = (SQInstruction*)pos;
|
|
||||||
|
|
||||||
Assert( pos < (start + funcsize) );
|
|
||||||
|
|
||||||
// don't read past boundary
|
|
||||||
if ( pos >= (start + funcsize) )
|
|
||||||
{
|
{
|
||||||
ci._ip = (SQInstruction*)start;
|
SQObject generator;
|
||||||
|
ReadObject( generator, pBuffer, readState );
|
||||||
|
Assert( generator._type == OT_GENERATOR && generator._unVal.pGenerator );
|
||||||
|
ci->_generator = generator._unVal.pGenerator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ci->_generator = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ci._literals = closure._unVal.pClosure->_function->_literals;
|
int offset = pBuffer->GetInt();
|
||||||
ci._closure = closure;
|
SQInstruction *start = closure._unVal.pClosure->_function->_instructions;
|
||||||
ci._generator = NULL;
|
SQInstruction *end = start + closure._unVal.pClosure->_function->_ninstructions;
|
||||||
ci._etraps = pBuffer->GetInt();
|
SQInstruction *pos = start + offset;
|
||||||
ci._prevstkbase = pBuffer->GetInt();
|
|
||||||
ci._prevtop = pBuffer->GetInt();
|
|
||||||
ci._target = pBuffer->GetInt();
|
|
||||||
ci._ncalls = pBuffer->GetInt();
|
|
||||||
ci._root = pBuffer->GetChar();
|
|
||||||
|
|
||||||
pThis->_etraps.resize( ci._etraps );
|
Assert( pos >= start && pos < end );
|
||||||
|
|
||||||
for ( int j = ci._etraps; j--; )
|
if ( pos < start || pos >= end )
|
||||||
|
pos = start;
|
||||||
|
|
||||||
|
ci->_ip = pos;
|
||||||
|
ci->_literals = closure._unVal.pClosure->_function->_literals;
|
||||||
|
ci->_closure = closure;
|
||||||
|
ci->_etraps = pBuffer->GetInt();
|
||||||
|
ci->_prevstkbase = pBuffer->GetInt();
|
||||||
|
ci->_prevtop = pBuffer->GetInt();
|
||||||
|
ci->_target = pBuffer->GetInt();
|
||||||
|
ci->_ncalls = pBuffer->GetInt();
|
||||||
|
ci->_root = pBuffer->GetChar();
|
||||||
|
|
||||||
|
pThis->_etraps.resize( ci->_etraps );
|
||||||
|
|
||||||
|
for ( int j = 0; j < ci->_etraps; j++ )
|
||||||
{
|
{
|
||||||
SQExceptionTrap &et = pThis->_etraps[j];
|
SQExceptionTrap &et = pThis->_etraps[j];
|
||||||
et._extarget = pBuffer->GetInt();
|
|
||||||
et._stackbase = pBuffer->GetInt();
|
|
||||||
et._stacksize = pBuffer->GetInt();
|
et._stacksize = pBuffer->GetInt();
|
||||||
et._ip = ci._ip;
|
et._stackbase = pBuffer->GetInt();
|
||||||
|
et._ip = ci->_ip + pBuffer->GetInt();
|
||||||
|
et._extarget = pBuffer->GetInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
int stacksize = pBuffer->GetInt();
|
int stacksize = pBuffer->GetInt();
|
||||||
@ -4457,10 +4552,7 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
|||||||
}
|
}
|
||||||
case OT_USERDATA:
|
case OT_USERDATA:
|
||||||
case OT_USERPOINTER:
|
case OT_USERPOINTER:
|
||||||
{
|
|
||||||
Assert(0);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
AssertMsgAlways( 0, "SquirrelVM::ReadObject: serialisation error" );
|
AssertMsgAlways( 0, "SquirrelVM::ReadObject: serialisation error" );
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user