From f4d3a4744824df7898d866db4ee3fb0172df9d42 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Mon, 14 Nov 2022 19:03:57 -0800 Subject: [PATCH] add trigger_teleport, trigger_changelevel and a few helper methods --- src/entities/info_null.qc | 10 ++++++ src/entities/info_player_start.qc | 4 +-- src/entities/sources.src | 8 +++-- src/entities/trigger_changelevel.qc | 27 ++++++++++++++++ src/entities/trigger_teleport.qc | 22 +++++++++++++ src/entities/worldspawn.qc | 13 +++----- src/system/idEngine.qh | 4 ++- src/system/idEntity.qc | 49 +++++++++++++++++++++++++++++ src/system/idEntity.qh | 11 +++++++ 9 files changed, 134 insertions(+), 14 deletions(-) create mode 100644 src/entities/info_null.qc create mode 100644 src/entities/trigger_changelevel.qc create mode 100644 src/entities/trigger_teleport.qc diff --git a/src/entities/info_null.qc b/src/entities/info_null.qc new file mode 100644 index 0000000..1007641 --- /dev/null +++ b/src/entities/info_null.qc @@ -0,0 +1,10 @@ +class idNull:idEntity { + void idNull( void ); +}; + +void idNull::idNull( void ) { + +} + +LINK_ENTITY_TO_CLASS(info_null, idNull) +LINK_ENTITY_TO_CLASS(info_teleport_destination, idNull) \ No newline at end of file diff --git a/src/entities/info_player_start.qc b/src/entities/info_player_start.qc index 3547021..00498e2 100644 --- a/src/entities/info_player_start.qc +++ b/src/entities/info_player_start.qc @@ -14,9 +14,7 @@ idEntity idPlayerStart::MovePlayerToStart( idPlayer player ) { idEntity point = g_idEngine.Find( world, ::classname, "idPlayerStart" ); if ( point ) { - player.SetOrigin( point.GetOrigin() ); - player.SetAngles( point.GetAngles() ); - player.ForceUpdateClientAngle(); + player.Transport( point.GetOrigin(), point.GetAngles() ); return point; } else { g_idEngine.Error( "Cannot find idPlayerStart on level." ); diff --git a/src/entities/sources.src b/src/entities/sources.src index eadda71..db4f809 100644 --- a/src/entities/sources.src +++ b/src/entities/sources.src @@ -1,5 +1,9 @@ #includelist -worldspawn.qc -info_player_start.qc func_wall.qc +info_null.qc +info_player_start.qc +light.qc +trigger_changelevel.qc +trigger_teleport.qc +worldspawn.qc #endlist diff --git a/src/entities/trigger_changelevel.qc b/src/entities/trigger_changelevel.qc new file mode 100644 index 0000000..1ebb1c8 --- /dev/null +++ b/src/entities/trigger_changelevel.qc @@ -0,0 +1,27 @@ +/* we need to register and track this entity field. */ +.string map; + +class idTriggerChangelevel:idEntity { + void idTriggerChangelevel( void ); + + nonvirtual string GetNextLevel( void ); + nonvirtual void ChangelevelTouched( idEntity ); +}; + +void idTriggerChangelevel::idTriggerChangelevel( void ) { + InitTrigger(); + SetTouchCallback( ChangelevelTouched ); +} + +string idTriggerChangelevel::GetNextLevel( void ) +{ + return map; +} + +void idTriggerChangelevel::ChangelevelTouched( idEntity toucher ) { + if ( toucher.IsPlayer() ) { + g_idEngine.ChangeLevel( GetNextLevel() ); + } +} + +LINK_ENTITY_TO_CLASS(trigger_changelevel, idTriggerChangelevel) \ No newline at end of file diff --git a/src/entities/trigger_teleport.qc b/src/entities/trigger_teleport.qc new file mode 100644 index 0000000..b046bc9 --- /dev/null +++ b/src/entities/trigger_teleport.qc @@ -0,0 +1,22 @@ +class idTriggerTeleport:idEntity { + void idTriggerTeleport( void ); + + nonvirtual void TeleporterTouched( idEntity ); +}; + +void idTriggerTeleport::idTriggerTeleport( void ) { + InitTrigger(); + SetTouchCallback(TeleporterTouched); +} + +void idTriggerTeleport::TeleporterTouched( idEntity toucher ) { + if ( toucher.IsPlayer() ) { + idEntity destination = FindFirstTarget(); + + if ( destination ) { + toucher.Transport( destination.GetOrigin(), destination.GetAngles() ); + } + } +} + +LINK_ENTITY_TO_CLASS(trigger_teleport, idTriggerTeleport) \ No newline at end of file diff --git a/src/entities/worldspawn.qc b/src/entities/worldspawn.qc index eb117da..ebc5f07 100644 --- a/src/entities/worldspawn.qc +++ b/src/entities/worldspawn.qc @@ -1,15 +1,15 @@ -class worldspawn { - void worldspawn( void ); +class idWorldspawn { + void idWorldspawn( void ); nonvirtual void InitLight( void ); }; -void worldspawn::worldspawn( void ) { +void idWorldspawn::idWorldspawn( void ) { g_idEngine.Precache_Model( "progs/player.mdl" ); InitLight(); } -void worldspawn::InitLight( void ) { +void idWorldspawn::InitLight( void ) { g_idEngine.LightStyle( 0, "m" ); g_idEngine.LightStyle( 1, "mmnmmommommnonmmonqnmmo" ); g_idEngine.LightStyle( 2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba" ); @@ -24,7 +24,4 @@ void worldspawn::InitLight( void ) { g_idEngine.LightStyle( 11, "abcdefghijklmnopqrrqponmlkjihgfedcba" ); } -void worldspawn( void ) -{ - spawnfunc_worldspawn(); -} \ No newline at end of file +LINK_ENTITY_TO_CLASS(worldspawn, idWorldspawn) \ No newline at end of file diff --git a/src/system/idEngine.qh b/src/system/idEngine.qh index 5a6d624..a8b5bae 100644 --- a/src/system/idEngine.qh +++ b/src/system/idEngine.qh @@ -65,4 +65,6 @@ class idEngine { idEngine g_idEngine; -#define LINK_ENTITY_TO_CLASS(cname,classa) void cname(void) { spawnfunc_##classa(); } \ No newline at end of file +#define LINK_ENTITY_TO_CLASS(cname,classa) void cname(void) { spawnfunc_##classa(); } + +.void( idEntity ) TouchCallback; \ No newline at end of file diff --git a/src/system/idEntity.qc b/src/system/idEntity.qc index 7fa7d22..a67a3bc 100644 --- a/src/system/idEntity.qc +++ b/src/system/idEntity.qc @@ -211,6 +211,17 @@ void idEntity::SetNoiseValue4( string value ) { noise3 = value; } +void idEntity::SetTouchCallback( void( idEntity ) callback ) { + /* give this entity a touch, this is for the engine only */ + touch = _TouchWrapper; + /* this is the touch function we'll be calling whenever the entity really gets touched */ + TouchCallback = callback; +} + +void idEntity::_TouchWrapper( void ) { + TouchCallback(other); +} + /* get functions */ float idEntity::GetModelindex( void ) { @@ -384,3 +395,41 @@ string idEntity::GetNoiseValue3( void ) { string idEntity::GetNoiseValue4( void ) { return noise3; } + +bool idEntity::IsPlayer( void ) { + return HasFlag(FL_CLIENT); +} + +bool idEntity::IsMonster( void ) { + return HasFlag(FL_MONSTER); +} + +bool idEntity::IsWorld( void ) { + if (this == world) + return TRUE; + else + return FALSE; +} + + +/* misc helper methods */ +void idEntity::InitTrigger( void ) { + SetSolid(SOLID_TRIGGER); + SetModel(GetModel()); + SetMovetype(MOVETYPE_NONE); + SetModelindex(0); +} + +void idEntity::Transport( vector new_pos, vector new_ang ) { + float flSpeed = vlen(this.GetVelocity()); + g_idEngine.MakeVectors(new_ang); + SetVelocity(v_forward * flSpeed); + + SetOrigin(new_pos); + SetAngles(new_ang); + ForceUpdateClientAngle(); +} + +idEntity idEntity::FindFirstTarget( void ) { + return g_idEngine.Find(world, ::targetname, target); +} \ No newline at end of file diff --git a/src/system/idEntity.qh b/src/system/idEntity.qh index bd811be..0c037eb 100644 --- a/src/system/idEntity.qh +++ b/src/system/idEntity.qh @@ -102,6 +102,9 @@ class idEntity { nonvirtual void SetNoiseValue3( string ); nonvirtual void SetNoiseValue4( string ); + nonvirtual void SetTouchCallback( void( idEntity ) callback ); + nonvirtual void _TouchWrapper( void ); + /** Returns the model id of the entity. */ nonvirtual float GetModelindex( void ); /** Returns the movetype of the entity. */ @@ -184,4 +187,12 @@ class idEntity { nonvirtual string GetNoiseValue2( void ); nonvirtual string GetNoiseValue3( void ); nonvirtual string GetNoiseValue4( void ); + + nonvirtual bool IsPlayer( void ); + nonvirtual bool IsMonster( void ); + nonvirtual bool IsWorld( void ); + + nonvirtual void InitTrigger( void ); + nonvirtual void Transport( vector, vector ); + nonvirtual idEntity FindFirstTarget( void ); };