feat(ConVar): Portal exit velocitys are no longer hard coded.

fix(Physgun): Rotation works now.
I think i took it from SourceBox or whatever it was called.

feat(Portal 2): I don't remember what i did but i did something.
A lot of that something was taken from:
https://github.com/RocketLauncher21/Portal2ASW

chore(ImGui): Updated ImGui to latest.
chore(Polyhedron): Changed a lot i don't remember where i took it from.
This commit is contained in:
tupoy-ya 2024-03-10 17:41:38 +05:00
parent d3c09196ba
commit e8525babd1
No known key found for this signature in database
GPG Key ID: 3541E2B1B448A2DB
21 changed files with 3208 additions and 1023 deletions

View File

@ -3591,6 +3591,10 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
if ( bIsInvisible && !clienttools->IsInRecordingMode() )
return;
#if !defined( CSTRIKE15 )
// We already handle muzzle flash events in CSTRIKE15.
// Also this code has a bug in that it always uses attachment 1 instead of by name.
// add in muzzleflash effect
if ( ShouldMuzzleFlash() )
{
@ -3599,6 +3603,8 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
ProcessMuzzleFlashEvent();
}
#endif
// If we're invisible, don't process animation events.
if ( bIsInvisible )
return;
@ -3616,7 +3622,7 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
if ( nSeqNum >= nStudioNumSeq )
{
// This can happen e.g. while reloading Heavy's shotgun, switch to the minigun.
Warning( "%s[%d]: Playing sequence %d but there's only %d in total?\n", GetDebugName(), entindex(), nSeqNum, nStudioNumSeq );
//Warning( "%s[%d]: Playing sequence %d but there's only %d in total?\n", GetDebugName(), entindex(), nSeqNum, nStudioNumSeq );
return;
}
@ -3717,8 +3723,8 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
if (ScriptHookFireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ) == false)
continue;
#endif
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() );
}
@ -3740,14 +3746,16 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
{
if ( watch )
{
Msg( "%i (seq: %d) FE %i Normal cycle %f, prev %f ev %f (time %.3f)\n",
Msg( "%i (seq: %d/%s) FE %i Normal cycle %f, prev %f ev %f (time %.3f) (options %s)\n",
gpGlobals->tickcount,
GetSequence(),
GetSequenceActivityName( GetSequence() ),
pevent[i].event,
pevent[i].cycle,
m_flPrevEventCycle,
flEventCycle,
gpGlobals->curtime );
gpGlobals->curtime,
pevent[ i ].pszOptions() );
}
#ifdef MAPBASE_VSCRIPT
@ -3759,7 +3767,7 @@ void C_BaseAnimating::DoAnimationEvents( CStudioHdr *pStudioHdr )
}
}
m_flPrevEventCycle = flEventCycle;
m_flPrevEventCycle = GetCycle();
}
#ifdef MAPBASE_VSCRIPT

View File

@ -27,6 +27,8 @@ $Project "Client (Portal)"
$File "c_team_objectiveresource.cpp"
$File "c_team_objectiveresource.h"
$File "imgui\test_window.cpp"
$Folder "HL2 DLL"
{
$File "episodic\flesh_internal_material_proxy.cpp"
@ -196,6 +198,7 @@ $Project "Client (Portal)"
$Folder "Portal re2"
{
$File "portal\remake\c_env_portal_laser.cpp"
$File "portal\remake\c_prop_waightedcube.cpp"
$File "portal2\c_prop_floor_button.cpp"
$File "vgui_movie_display.cpp"

View File

@ -205,6 +205,7 @@ static bool ImGui_ImplSource_CreateFontsTexture()
// Create a material for the texture
ITexture *fonttex = g_pMaterialSystem->CreateProceduralTexture( "imgui_font", TEXTURE_GROUP_OTHER, width, height, IMAGE_FORMAT_RGBA8888, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_POINTSAMPLE | TEXTUREFLAGS_PROCEDURAL | TEXTUREFLAGS_SINGLECOPY | TEXTUREFLAGS_NOLOD );
fonttex->SetTextureRegenerator( new CDearImGuiFontTextureRegenerator );
fonttex->Download();
KeyValues *vmt = new KeyValues( "UnlitGeneric" );
vmt->SetString( "$basetexture", "imgui_font" );

View File

@ -140,7 +140,7 @@ public:
CDummyOverlayPanel()
{
SetVisible( false );
SetParent( enginevgui->GetPanel( PANEL_GAMEUIDLL ) );
SetParent( enginevgui->GetPanel( PANEL_CLIENTDLL ) );
SetPaintEnabled( true );
SetCursor( vgui::dc_arrow );
@ -188,18 +188,17 @@ public:
io.AddInputCharacter( code );
}
// always pass keycodes to imgui, WantCaptureKeyboard should NOT affect whether or not we do this
void OnKeyCodePressed( vgui::KeyCode code ) override
{
auto& io = ImGui::GetIO();
if ( io.WantCaptureKeyboard )
io.AddKeyEvent( IMGUI_KEY_TABLE[code], true );
io.AddKeyEvent( IMGUI_KEY_TABLE[code], true );
}
void OnKeyCodeReleased( vgui::KeyCode code ) override
{
auto& io = ImGui::GetIO();
if ( io.WantCaptureKeyboard )
io.AddKeyEvent( IMGUI_KEY_TABLE[code], false );
io.AddKeyEvent( IMGUI_KEY_TABLE[code], false );
}
void Paint() override
@ -231,6 +230,11 @@ bool CDearImGuiSystem::Init()
ImGui::SetAllocatorFunctions( ImGui_MemAlloc, ImGui_MemFree, nullptr );
ImFontAtlas *atlas = new ImFontAtlas();
ImGui::CreateContext( atlas );
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
ImGui_ImplSource_Init();
SetStyle();
@ -379,7 +383,8 @@ void CDearImGuiSystem::UnregisterWindowFactories( IImguiWindow **ppWindows, int
//---------------------------------------------------------------------------------------//
IImguiWindow *CDearImGuiSystem::FindWindow( const char *szName )
{
if ( auto it = m_ImGuiWindows.Find( szName ); it != m_ImGuiWindows.InvalidIndex() )
int it = m_ImGuiWindows.Find( szName );
if ( it != m_ImGuiWindows.InvalidIndex() )
return m_ImGuiWindows[it];
return nullptr;
}
@ -606,7 +611,7 @@ static ConCommand imgui_input_end(
CON_COMMAND_F( imgui_toggle_menu, "Toggles the imgui menu bar", FCVAR_CLIENTDLL )
{
g_ImguiSystem.ToggleMenuBar();
if ( g_ImguiSystem.IsDrawingMenuBar() )
if ( g_ImguiSystem.IsDrawingMenuBar() )
g_ImguiSystem.PushInputContext();
else
g_ImguiSystem.PopInputContext();
@ -616,7 +621,7 @@ template <bool ON>
void CC_ToggleMenu( const CCommand &args )
{
g_ImguiSystem.SetDrawMenuBar( ON );
if constexpr ( ON )
if ( ON )
g_ImguiSystem.PushInputContext();
else
g_ImguiSystem.PopInputContext();

View File

@ -0,0 +1,25 @@
/**
* @file test_window.cpp
* @brief A demo window for reference.
*/
#include "cdll_client_int.h"
#include "convar.h"
#include "imgui_window.h"
DECLARE_IMGUI_WINDOW(test_window, "Test window")
{
ImGui::Text("Demo text");
if (ImGui::Button("Print"))
{
Msg("Hello ImGui!\n");
}
if (ImGui::Button("Impulse 101"))
{
engine->ClientCmd("impulse 101");
}
return false;
}

View File

@ -80,8 +80,8 @@ void CInput::ApplyTouch( QAngle &viewangles, CUserCmd *cmd, float dx, float dy )
{
viewangles[YAW] -= dx;
viewangles[PITCH] += dy;
cmd->mousedx = dx;
cmd->mousedy = dy;
cmd->mousedx += dx;
cmd->mousedy += dy;
}
void CInput::TouchMove( CUserCmd *cmd )

View File

@ -111,10 +111,6 @@ void C_PortalLaser::LaserOn()
return;
}
Vector vecMuzzle;
QAngle angMuzzleDir;
GetAttachment( m_iAttachmentId, vecMuzzle, angMuzzleDir );
QAngle angAimDir = GetAbsAngles();
Vector vecAimDir;
AngleVectors ( angAimDir, &vecAimDir );
@ -136,7 +132,7 @@ void C_PortalLaser::LaserOn()
m_pBeam->SetHaloScale( 5.5f );
m_pBeam->SetBeamFlag( FBEAM_REVERSED );
m_pBeam->SetCollisionGroup( COLLISION_GROUP_NONE );
m_pBeam->PointsInit( vecMuzzle + vecAimDir, vecMuzzle );
m_pBeam->PointsInit( m_vStartPoint + vecAimDir, m_vEndPoint );
m_pBeam->SetStartEntity( this );
}
else
@ -148,12 +144,12 @@ void C_PortalLaser::LaserOn()
Vector vEndPoint;
float fEndFraction;
Ray_t rayPath;
rayPath.Init( vecMuzzle, vecMuzzle + vecAimDir * 8192 );
rayPath.Init( m_vStartPoint, m_vStartPoint + vecAimDir * 8192 );
if ( UTIL_Portal_TraceRay_Beam( rayPath, MASK_SHOT, &m_filterBeams, &fEndFraction ) )
vEndPoint = vecMuzzle + vecAimDir * 8192; // Trace went through portal and endpoint is unknown
vEndPoint = m_vStartPoint + vecAimDir * 8192; // Trace went through portal and endpoint is unknown
else
vEndPoint = vecMuzzle + vecAimDir * 8192 * fEndFraction; // Trace hit a wall
vEndPoint = m_vStartPoint + vecAimDir * 8192 * fEndFraction; // Trace hit a wall
m_pBeam->PointsInit( vEndPoint, vecMuzzle );
m_pBeam->PointsInit( vEndPoint, m_vStartPoint );
}

View File

@ -0,0 +1,143 @@
/**
* @file c_env_portal_laser.cpp
* @brief Adds lasers from Portal 2
*
* Mostly just copypasted from the rocket turret
*
* @bug Laser can be blocked by a player when laser goes through a portal.
*/
#include "cbase.h"
#include "c_physicsprop.h"
#include "beam_shared.h"
#include "mathlib/vector.h"
#include "portal_util_shared.h"
class C_PropWeightedCube : public C_PhysicsProp
{
public:
DECLARE_CLASS( C_PropWeightedCube, C_PhysicsProp );
DECLARE_CLIENTCLASS();
C_PropWeightedCube( void );
~C_PropWeightedCube( void );
void Spawn( void );
void ClientThink( void );
void LaserOff( void );
void LaserOn( void );
float LaserEndPointSize( void );
private:
CBeam *m_pBeam;
CTraceFilterSkipTwoEntities m_filterBeams;
int m_nSiteHalo;
int m_iAttachmentId;
////////////
//CNewParticleEffect m_pSparkEffect;
bool m_bLaserOn;
bool m_bIsLethal;
////////////
};
LINK_ENTITY_TO_CLASS( prop_weighted_cube, C_PropWeightedCube );
IMPLEMENT_CLIENTCLASS_DT( C_PropWeightedCube, DT_PropWeightedCube, CPropWeightedCube )
RecvPropBool( RECVINFO( m_bLaserOn ) ),
RecvPropBool( RECVINFO( m_bIsLethal ) ),
END_RECV_TABLE()
C_PropWeightedCube::C_PropWeightedCube( void )
: m_filterBeams( this, UTIL_PlayerByIndex( 1 ), COLLISION_GROUP_DEBRIS )
//m_pSparkEffect()
{
}
C_PropWeightedCube::~C_PropWeightedCube( void )
{
LaserOff();
if( m_pBeam )
m_pBeam->Remove();
}
void C_PropWeightedCube::Spawn()
{
SetThink( &C_PropWeightedCube::ClientThink );
SetNextClientThink( CLIENT_THINK_ALWAYS );
m_pBeam = NULL;
BaseClass::Spawn();
}
void C_PropWeightedCube::ClientThink()
{
if( m_bLaserOn )
LaserOn();
else
LaserOff();
}
void C_PropWeightedCube::LaserOff()
{
if( m_pBeam )
m_pBeam->AddEffects( EF_NODRAW );
}
void C_PropWeightedCube::LaserOn()
{
if ( !IsBoneAccessAllowed() )
{
LaserOff();
return;
}
Vector vecMuzzle;
QAngle angMuzzleDir;
GetAttachment( m_iAttachmentId, vecMuzzle, angMuzzleDir );
QAngle angAimDir = GetAbsAngles();
Vector vecAimDir;
AngleVectors ( angAimDir, &vecAimDir );
if(!m_pBeam)
{
if(m_bIsLethal)
m_pBeam = CBeam::BeamCreate("sprites/laserbeam.vmt", 2);
else
m_pBeam = CBeam::BeamCreate("sprites/purplelaser1.vmt", 32);;
m_pBeam->SetHaloTexture( m_nSiteHalo );
m_pBeam->SetColor( 255, 255, 255 );
m_pBeam->SetBrightness( 255 );
m_pBeam->SetNoise( 0 );
m_pBeam->SetWidth( 2 );
m_pBeam->SetEndWidth( 0 );
m_pBeam->SetScrollRate( 0 );
m_pBeam->SetFadeLength( 0 );
m_pBeam->SetHaloScale( 5.5f );
m_pBeam->SetBeamFlag( FBEAM_REVERSED );
m_pBeam->SetCollisionGroup( COLLISION_GROUP_NONE );
m_pBeam->PointsInit( vecMuzzle + vecAimDir, vecMuzzle );
m_pBeam->SetStartEntity( this );
}
else
{
m_pBeam->RemoveEffects( EF_NODRAW );
}
// Trace to find an endpoint (so the beam draws through portals)
Vector vEndPoint;
float fEndFraction;
Ray_t rayPath;
rayPath.Init( vecMuzzle, vecMuzzle + vecAimDir * 8192 );
if ( UTIL_Portal_TraceRay_Beam( rayPath, MASK_SHOT, &m_filterBeams, &fEndFraction ) )
vEndPoint = vecMuzzle + vecAimDir * 8192; // Trace went through portal and endpoint is unknown
else
vEndPoint = vecMuzzle + vecAimDir * 8192 * fEndFraction; // Trace hit a wall
m_pBeam->PointsInit( vEndPoint, vecMuzzle );
}

View File

@ -1913,6 +1913,9 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
m_CurrentView = view;
if ( building_cubemaps.GetBool() )
m_CurrentView.fov = RAD2DEG( 2.0f * atanf( 64.0f / ( 64 - 0.5f ) ) );
C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, true );
VPROF( "CViewRender::RenderView" );
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ );
@ -4380,6 +4383,9 @@ void CRendering3dView::DrawTranslucentRenderables( bool bInSkybox, bool bShadowD
return;
}
if( !m_pWorldListInfo )
return;
VPROF_BUDGET( "CViewRender::DrawTranslucentRenderables", "DrawTranslucentRenderables" );
int iPrevLeaf = info.m_LeafCount - 1;
int nDetailLeafCount = 0;

View File

@ -14,6 +14,7 @@
*/
#include "cbase.h"
#include "convar.h"
#include "portal_player.h"
#include "portal_gamerules.h"
#include "gamerules.h"
@ -121,11 +122,11 @@ void ClientGamePrecache( void )
CBaseEntity::PrecacheModel( "models/portals/portal2.mdl" );
}
ConVar sv_respawn_in_sp( "sv_respawn_in_sp", "0" );
// called by ClientKill and DeadThink
void respawn( CBaseEntity *pEdict, bool fCopyCorpse )
{
if (gpGlobals->coop || gpGlobals->deathmatch)
if (sv_respawn_in_sp.GetBool() || gpGlobals->coop || gpGlobals->deathmatch)
{
if ( fCopyCorpse )
{

View File

@ -35,15 +35,14 @@
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define MINIMUM_FLOOR_PORTAL_EXIT_VELOCITY 50.0f
#define MINIMUM_FLOOR_TO_FLOOR_PORTAL_EXIT_VELOCITY 225.0f
#define MINIMUM_FLOOR_PORTAL_EXIT_VELOCITY_PLAYER 300.0f
#define MAXIMUM_PORTAL_EXIT_VELOCITY 1000.0f
CCallQueue *GetPortalCallQueue();
ConVar sv_portal_minimum_floor_exit_velocity("sv_portal_minimum_floor_exit_velocity", "50.0", FCVAR_REPLICATED );
ConVar sv_portal_minimum_floor_to_floor_exit_velocity("sv_portal_minimum_floor_to_floor_exit_velocity", "225.0", FCVAR_REPLICATED );
ConVar sv_portal_minimum_floor_exit_velocity_player("sv_portal_minimum_floor_exit_velocity_player", "300.0", FCVAR_REPLICATED );
ConVar sv_portal_maximum_exit_velocity("sv_portal_maximum_exit_velocity", "1000.0", FCVAR_REPLICATED );
ConVar sv_portal_debug_touch("sv_portal_debug_touch", "0", FCVAR_REPLICATED );
ConVar sv_portal_placement_never_fail("sv_portal_placement_never_fail", "0", FCVAR_REPLICATED | FCVAR_CHEAT );
ConVar sv_portal_new_velocity_check("sv_portal_new_velocity_check", "1", FCVAR_CHEAT );
@ -1133,27 +1132,27 @@ void CProp_Portal::TeleportTouchingEntity( CBaseEntity *pOther )
{
if ( bPlayer )
{
if( vNewVelocity.z < MINIMUM_FLOOR_PORTAL_EXIT_VELOCITY_PLAYER )
vNewVelocity.z = MINIMUM_FLOOR_PORTAL_EXIT_VELOCITY_PLAYER;
if( vNewVelocity.z < sv_portal_minimum_floor_exit_velocity_player.GetFloat() )
vNewVelocity.z = sv_portal_minimum_floor_exit_velocity_player.GetFloat();
}
else
{
if( LocalPortalDataAccess.Placement.vForward.z > 0.7071f )
{
if( vNewVelocity.z < MINIMUM_FLOOR_TO_FLOOR_PORTAL_EXIT_VELOCITY )
vNewVelocity.z = MINIMUM_FLOOR_TO_FLOOR_PORTAL_EXIT_VELOCITY;
if( vNewVelocity.z < sv_portal_minimum_floor_to_floor_exit_velocity.GetFloat() )
vNewVelocity.z = sv_portal_minimum_floor_to_floor_exit_velocity.GetFloat();
}
else
{
if( vNewVelocity.z < MINIMUM_FLOOR_PORTAL_EXIT_VELOCITY )
vNewVelocity.z = MINIMUM_FLOOR_PORTAL_EXIT_VELOCITY;
if( vNewVelocity.z < sv_portal_minimum_floor_exit_velocity.GetFloat() )
vNewVelocity.z = sv_portal_minimum_floor_exit_velocity.GetFloat();
}
}
}
if ( vNewVelocity.LengthSqr() > (MAXIMUM_PORTAL_EXIT_VELOCITY * MAXIMUM_PORTAL_EXIT_VELOCITY) )
vNewVelocity *= (MAXIMUM_PORTAL_EXIT_VELOCITY / vNewVelocity.Length());
if ( vNewVelocity.LengthSqr() > (sv_portal_maximum_exit_velocity.GetFloat() * sv_portal_maximum_exit_velocity.GetFloat()) )
vNewVelocity *= (sv_portal_maximum_exit_velocity.GetFloat() / vNewVelocity.Length());
}
//untouch the portal(s), will force a touch on destination after the teleport

View File

@ -66,6 +66,9 @@ private:
CNetworkVar( bool, m_bUseParentDir );
CNetworkVector( m_angParentAngles );
QAngle m_angPortalExitAngles;
// Custom fields
CBaseEntity* m_LastEntity;
};
// Start of our data description for the class
@ -229,9 +232,14 @@ void CPortalLaser::StrikeThink( void )
{
Ray_t rayDmg;
Vector vForward;
AngleVectors( GetAbsAngles(), &vForward, NULL, NULL );
Vector vEndPoint = EyePosition() + vForward*8192;
rayDmg.Init( EyePosition(), vEndPoint );
Vector vStartPoint;
GetAttachment(m_iLaserAttachment, vStartPoint, &vForward);
// Source.
m_vStartPoint = vStartPoint;
m_vEndPoint = m_vStartPoint + vForward*8192;
rayDmg.Init( m_vStartPoint, m_vEndPoint );
rayDmg.m_IsRay = true;
trace_t traceDmg;
@ -242,6 +250,27 @@ void CPortalLaser::StrikeThink( void )
CProp_Portal* pFirstPortal = UTIL_Portal_FirstAlongRay( rayDmg, flRequiredParameter );
UTIL_Portal_TraceRay_Bullets( pFirstPortal, rayDmg, MASK_VISIBLE_AND_NPCS, &filter, &traceDmg, false );
if ( m_LastEntity && traceDmg.m_pEnt != m_LastEntity )
{
if( FClassnameIs( m_LastEntity, "prop_weighted_cube" ) && UTIL_IsReflectiveCube( m_LastEntity ) )
{
//Set the cube to activate
CPropWeightedCube* pCube = assert_cast<CPropWeightedCube*>( m_LastEntity );
if( pCube )
{
pCube->SetActivated( false );
}
}
else if( FClassnameIs( m_LastEntity, "prop_laser_catcher" ))
{
CPropLaserCatcher* pCatcher = assert_cast<CPropLaserCatcher*>( m_LastEntity );
if( pCatcher )
{
pCatcher->SetActivated( false );
}
}
}
if ( traceDmg.m_pEnt )
{
if ( traceDmg.m_pEnt->IsPlayer() )
@ -254,11 +283,11 @@ void CPortalLaser::StrikeThink( void )
else if( FClassnameIs( traceDmg.m_pEnt, "prop_weighted_cube" ) && UTIL_IsReflectiveCube( traceDmg.m_pEnt ) )
{
//Set the cube to activate
// TODO: Make lasers come from cubes
CPropWeightedCube* pCube = assert_cast<CPropWeightedCube*>( traceDmg.m_pEnt );
if( pCube )
{
pCube->SetActivated( true );
m_LastEntity = traceDmg.m_pEnt;
}
}
else if( FClassnameIs( traceDmg.m_pEnt, "prop_laser_catcher" ))
@ -267,6 +296,7 @@ void CPortalLaser::StrikeThink( void )
if( pCatcher )
{
pCatcher->SetActivated( true );
m_LastEntity = traceDmg.m_pEnt;
}
}
}

View File

@ -24,7 +24,6 @@ BEGIN_DATADESC( CPropLaserCatcher )
END_DATADESC()
CPropLaserCatcher::CPropLaserCatcher()
: m_bAlreadyActivated( false )
{
}
@ -91,17 +90,12 @@ void CPropLaserCatcher::Spawn( void )
void CPropLaserCatcher::SetActivated( bool bActivate )
{
m_bActivated = bActivate;
}
/**
* @brief Updates the laser catcher
*/
void CPropLaserCatcher::CatcherThink( void )
{
if( m_bActivated )
if( m_bActivated != bActivate )
{
if( !m_bAlreadyActivated )
m_bActivated = bActivate;
SetCatcherSkin();
if( bActivate )
{
m_OnPowered.FireOutput( this, this );
@ -111,17 +105,11 @@ void CPropLaserCatcher::CatcherThink( void )
EmitSound("prop_laser_catcher.powerloop");
StopSound("prop_laser_catcher.poweroff");
SetCatcherSkin();
SetSequence( m_PowerOnSequence );
SetPlaybackRate( 1.0f );
UseClientSideAnimation();
}
m_bAlreadyActivated = true;
m_bActivated = false; // This is a dumb way of making the catcher power off.
}
else
{
if( m_bAlreadyActivated )
else
{
m_OnUnpowered.FireOutput( this, this );
@ -130,13 +118,17 @@ void CPropLaserCatcher::CatcherThink( void )
EmitSound("prop_laser_catcher.poweroff");
StopSound("prop_laser_catcher.powerloop");
SetCatcherSkin();
SetSequence( m_IdleSequence );
SetPlaybackRate( 1.0f );
UseClientSideAnimation();
}
m_bAlreadyActivated = false;
}
}
/**
* @brief Updates the laser catcher
*/
void CPropLaserCatcher::CatcherThink( void )
{
SetNextThink( gpGlobals->curtime + 0.2f );
}

View File

@ -31,6 +31,5 @@ private:
int m_iTargetAttachment;
bool m_bActivated;
bool m_bAlreadyActivated;
bool m_bRusted;
};

View File

@ -11,9 +11,11 @@
#include "datacache/imdlcache.h"
#include "portal_util_shared.h"
#include <cstddef>
// Laser implementation.
#include "prop_laser_catcher.h"
#include "physicsshadowclone.h"
LINK_ENTITY_TO_CLASS( prop_weighted_cube, CPropWeightedCube );
#include <cstddef>
BEGIN_DATADESC( CPropWeightedCube )
@ -28,9 +30,17 @@ BEGIN_DATADESC( CPropWeightedCube )
DEFINE_INPUTFUNC( FIELD_VOID, "Dissolve", InputDissolve ),
DEFINE_INPUTFUNC( FIELD_VOID, "SilentDissolve", InputDissolve ), // InputSilentDissolve
DEFINE_THINKFUNC( StrikeThink ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST(CPropWeightedCube, DT_PropWeightedCube)
SendPropBool( SENDINFO( m_bLaserOn ) ),
SendPropBool( SENDINFO( m_bIsLethal ) ),
END_SEND_TABLE()
LINK_ENTITY_TO_CLASS( prop_weighted_cube, CPropWeightedCube );
const char *CUBE_MODEL = "models/props/metal_box.mdl";
const char *CUBE_REFLECT_MODEL = "models/props/reflection_cube.mdl";
const char *CUBE_SPHERE_MODEL = "models/props_gameplay/mp_ball.mdl";
@ -231,8 +241,23 @@ void CPropWeightedCube::SetCubeType( void )
//-----------------------------------------------------------------------------
void CPropWeightedCube::SetActivated( bool bActivate )
{
if(m_bActivated == bActivate)
return;
m_bActivated = bActivate;
if(bActivate && m_nCubeType == CUBE_REFLECTIVE)
{
m_bLaserOn = true;
SetThink(&CPropWeightedCube::StrikeThink);
SetNextThink( gpGlobals->curtime );
}
else
{
m_bLaserOn = false;
SetThink(nullptr);
}
SetCubeSkin();
}
@ -548,6 +573,92 @@ void CPropWeightedCube::Spawn( void )
SetFadeDistance( -1.0f, 0.0f );
}
extern ConVar sv_portal_laser_normal_update;
extern ConVar sv_portal_laser_high_precision_update;
//-----------------------------------------------------------------------------
// Purpose: Toggle the laser on and off
// TODO: Not how it should be implemented!
//-----------------------------------------------------------------------------
void CPropWeightedCube::StrikeThink( void )
{
Ray_t rayDmg;
Vector vForward;
AngleVectors( GetAbsAngles(), &vForward, NULL, NULL );
Vector vEndPoint = EyePosition() + vForward*8192;
rayDmg.Init( EyePosition(), vEndPoint );
rayDmg.m_IsRay = true;
trace_t traceDmg;
// This version reorients through portals
CTraceFilterSimple subfilter( this, COLLISION_GROUP_NONE );
CTraceFilterTranslateClones filter ( &subfilter );
float flRequiredParameter = 2.0f;
CProp_Portal* pFirstPortal = UTIL_Portal_FirstAlongRay( rayDmg, flRequiredParameter );
UTIL_Portal_TraceRay_Bullets( pFirstPortal, rayDmg, MASK_VISIBLE_AND_NPCS, &filter, &traceDmg, false );
if ( m_LastEntity && traceDmg.m_pEnt != m_LastEntity )
{
if( FClassnameIs( m_LastEntity, "prop_weighted_cube" ) && UTIL_IsReflectiveCube( m_LastEntity ) )
{
//Set the cube to activate
CPropWeightedCube* pCube = assert_cast<CPropWeightedCube*>( m_LastEntity );
if( pCube )
{
pCube->SetActivated( false );
}
}
else if( FClassnameIs( m_LastEntity, "prop_laser_catcher" ))
{
CPropLaserCatcher* pCatcher = assert_cast<CPropLaserCatcher*>( m_LastEntity );
if( pCatcher )
{
pCatcher->SetActivated( false );
}
}
}
if ( traceDmg.m_pEnt )
{
if ( traceDmg.m_pEnt->IsPlayer() )
{
CTakeDamageInfo dmgInfo;
dmgInfo.SetDamage( 1 );
dmgInfo.SetDamageType( DMG_ENERGYBEAM );
traceDmg.m_pEnt->TakeDamage( dmgInfo );
}
else if( FClassnameIs( traceDmg.m_pEnt, "prop_weighted_cube" ) && UTIL_IsReflectiveCube( traceDmg.m_pEnt ) )
{
//Set the cube to activate
CPropWeightedCube* pCube = assert_cast<CPropWeightedCube*>( traceDmg.m_pEnt );
if( pCube )
{
pCube->SetActivated( true );
m_LastEntity = traceDmg.m_pEnt;
}
}
else if( FClassnameIs( traceDmg.m_pEnt, "prop_laser_catcher" ))
{
CPropLaserCatcher* pCatcher = assert_cast<CPropLaserCatcher*>( traceDmg.m_pEnt );
if( pCatcher )
{
pCatcher->SetActivated( true );
m_LastEntity = traceDmg.m_pEnt;
}
}
}
// FIXME:
bool m_bFromReflectedCube = false;
float fTime;
if(m_bFromReflectedCube)
fTime = sv_portal_laser_normal_update.GetFloat();
else
fTime = sv_portal_laser_high_precision_update.GetFloat();
SetNextThink(gpGlobals->curtime + fTime);
}
//-----------------------------------------------------------------------------
// Creates a weighted cube of a specific type
//-----------------------------------------------------------------------------

View File

@ -86,6 +86,7 @@ class CPropWeightedCube : public CPhysicsProp
{
public:
DECLARE_CLASS( CPropWeightedCube, CPhysicsProp );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
CPropWeightedCube();
@ -116,6 +117,8 @@ public:
return m_hLaser.Get() != NULL;
}
void StrikeThink( void );
static void CreatePortalWeightedCube( WeightedCubeType_e objectType, bool bAtCursorPosition = true, const Vector &position = vec3_origin );
private:
@ -137,6 +140,14 @@ private:
bool m_bNewSkins;
EHANDLE m_hLaser;
// TODO: Laser vars don't belong here, remove.
CNetworkVar( bool, m_bLaserOn );
CNetworkVar( bool, m_bIsLethal );
CBaseEntity* m_LastEntity;
//
};
bool UTIL_IsReflectiveCube( CBaseEntity *pEntity );

View File

@ -0,0 +1,186 @@
/**
* @file indicator_panel.cpp
* @brief
* @date 2023-10-22
*/
#include "cbase.h"
#include "entitylist.h"
#include "util.h"
// Name of our entity's model
#define ENTITY_MODEL "models/gibs/airboat_broken_engine.mdl"
class CPropIndicatorPanel : public CBaseAnimating
{
public:
DECLARE_CLASS( CPropIndicatorPanel, CBaseAnimating );
DECLARE_DATADESC();
CPropIndicatorPanel()
{
}
void Spawn( void );
void Precache( void );
void CreateIndicatorPanel( void );
void SetTimerDuration( float fDuration);
// Input function
void InputCheck( inputdata_t &inputData );
void InputUncheck( inputdata_t &inputData );
void InputStart( inputdata_t &inputData );
void InputStop( inputdata_t &inputData );
void InputReset( inputdata_t &inputData );
void ToggleThink( void );
void StartTimer( void );
void ResetTimer( void );
void ToggleIndicatorLights( bool bLightsOn );
private:
bool m_bEnabled;
bool m_bStopped;
bool m_bCountingDown;
bool m_bIsCountdownTimer;
bool m_bIsChecked;
string_t m_strIndicatorLights;
float m_flTimerDuration;
float m_flTimerStart;
// CHandle<CLabIndicatorPanel> m_hIndicatorPanel;
};
LINK_ENTITY_TO_CLASS( prop_indicator_panel, CPropIndicatorPanel );
// Start of our data description for the class
BEGIN_DATADESC( CPropIndicatorPanel )
DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bStopped, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bCountingDown, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bIsCountdownTimer, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bIsChecked, FIELD_BOOLEAN ),
DEFINE_FIELD( m_flTimerDuration, FIELD_TIME ),
DEFINE_FIELD( m_flTimerStart, FIELD_TIME ),
DEFINE_INPUTFUNC( FIELD_VOID, "Check", InputCheck ),
DEFINE_INPUTFUNC( FIELD_VOID, "Uncheck", InputUncheck ),
DEFINE_INPUTFUNC( FIELD_VOID, "Start", InputStart ),
DEFINE_INPUTFUNC( FIELD_VOID, "Stop", InputStop ),
DEFINE_INPUTFUNC( FIELD_VOID, "Reset", InputReset ),
// Declare our think function
DEFINE_THINKFUNC( ToggleThink ),
END_DATADESC()
//-----------------------------------------------------------------------------
// Purpose: Precache assets used by the entity
//-----------------------------------------------------------------------------
void CPropIndicatorPanel::Precache( void )
{
PrecacheModel( ENTITY_MODEL );
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose: Sets up the entity's initial state
//-----------------------------------------------------------------------------
void CPropIndicatorPanel::Spawn( void )
{
Precache();
SetModel( ENTITY_MODEL );
SetSolid( SOLID_VPHYSICS );
SetMoveType(MOVETYPE_NONE);
CreateIndicatorPanel();
}
void CPropIndicatorPanel::CreateIndicatorPanel( void )
{
// TODO
}
void CPropIndicatorPanel::InputCheck( inputdata_t &inputData )
{
// TODO: Implement vgui indecator.
{
}
SetThink( NULL );
ToggleIndicatorLights( true );
}
void CPropIndicatorPanel::InputUncheck( inputdata_t &inputData )
{
// TODO: Implement vgui indecator.
{
}
SetThink( NULL );
ToggleIndicatorLights( false );
}
void CPropIndicatorPanel::InputStart( inputdata_t &inputData )
{
StartTimer();
}
void CPropIndicatorPanel::InputReset( inputdata_t &inputData )
{
ResetTimer();
}
// Does nothing.
void CPropIndicatorPanel::InputStop( inputdata_t &inputData )
{
return;
}
void CPropIndicatorPanel::StartTimer( void )
{
return;
}
void CPropIndicatorPanel::ResetTimer( void )
{
return;
}
void CPropIndicatorPanel::ToggleThink( void )
{
return;
}
void CPropIndicatorPanel::ToggleIndicatorLights( bool bLightsOn )
{
CBaseEntity* pStartEntity = NULL;
const char* indicator_lights = m_strIndicatorLights.ToCStr();
while( true )
{
if(indicator_lights == NULL || *indicator_lights == '\0')
indicator_lights = "";
pStartEntity = gEntList.FindEntityByName( pStartEntity, indicator_lights );
if (pStartEntity == NULL)
break;
}
return;
}
void CPropIndicatorPanel::SetTimerDuration( float fDuration )
{
m_flTimerDuration = fDuration;
}

View File

@ -1,3 +1,10 @@
/**
* @file npc_personality_core.cpp
* @brief Placeholder code for personality cores.
*
* @author RocketLauncher21 https://github.com/RocketLauncher21/Portal2ASW
*/
#include "cbase.h"
#include "ai_baseactor.h"
#include "ai_basenpc.h"

View File

@ -0,0 +1,60 @@
/**
* @file npc_wheatly_boss.cpp
* @brief Placeholder code for wheatley boss.
*
* @author RocketLauncher21 https://github.com/RocketLauncher21/Portal2ASW
*/
#include "cbase.h"
#include "ai_baseactor.h"
#include "ai_basenpc.h"
#include "props.h"
#define BOSS_MODEL "models/npcs/glados/glados_wheatley_boss.mdl"
class CNPCWheatleyBoss : public CAI_BaseActor
{
public:
DECLARE_CLASS(CNPCWheatleyBoss, CAI_BaseActor);
DECLARE_DATADESC();
CNPCWheatleyBoss()
{
}
bool CreateVPhysics(void)
{
VPhysicsInitNormal(SOLID_VPHYSICS, 0, false);
return true;
}
void Spawn(void);
void Precache(void);
private:
CHandle<CBasePlayer> m_hPhysicsAttacker;
COutputEvent m_OnPlayerPickup;
COutputEvent m_OnPhysGunDrop;
};
LINK_ENTITY_TO_CLASS(npc_wheatley_boss, CNPCWheatleyBoss);
BEGIN_DATADESC(CNPCWheatleyBoss)
END_DATADESC()
void CNPCWheatleyBoss::Precache(void)
{
PrecacheModel(BOSS_MODEL);
BaseClass::Precache();
}
void CNPCWheatleyBoss::Spawn(void)
{
Precache();
SetModel(BOSS_MODEL);
SetSolid(SOLID_VPHYSICS);
CreateVPhysics();
BaseClass::Spawn();
}

View File

@ -366,6 +366,8 @@ $Project "Server (Portal)"
$File "portal2\prop_button.cpp"
$File "portal2\point_changelevel.cpp"
$File "portal2\npc_personality_core.cpp"
$File "portal2\npc_wheatley_boss.cpp"
$File "portal2\indicator_panel.cpp"
$File "movie_display.cpp"

File diff suppressed because it is too large Load Diff