From 1fd279abaa98c72f0c1020fa6c69bc0d45f86a68 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Mon, 5 Dec 2016 21:32:24 +0100 Subject: [PATCH] Added func_door, func_door_rotating, env_glow. --- Source/Server/Entities.c | 153 +++++++++++++++++- Source/Server/EnvObjects.c | 4 + Source/Server/FuncDoor.c | 261 +++++++++++++++++++++++++++++++ Source/Server/FuncDoorRotating.c | 245 +++++++++++++++++++++++++++++ Source/Server/progs.src | 2 + 5 files changed, 661 insertions(+), 4 deletions(-) create mode 100644 Source/Server/FuncDoor.c create mode 100644 Source/Server/FuncDoorRotating.c diff --git a/Source/Server/Entities.c b/Source/Server/Entities.c index 73e81e9e..de502283 100644 --- a/Source/Server/Entities.c +++ b/Source/Server/Entities.c @@ -18,6 +18,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* +==================== +Entities_UseTargets +==================== +*/ void Entities_UseTargets( void ) { entity eFind = findchain( targetname, self.target ); @@ -30,6 +35,150 @@ void Entities_UseTargets( void ) { } } +/* +==================== +Entities_Remove +==================== +*/ +void Entities_Remove( void ) +{ + remove( self ); +} + +/* +==================== +Entities_SetMovedir + +Returns the movement direction based on angles +==================== +*/ +void Entities_SetMovementDirection( void ) +{ + if ( self.angles == '0 -1 0' ) { + self.movedir = '0 0 1'; + } else if ( self.angles == '0 -2 0' ) { + self.movedir = '0 0 -1'; + } else { + makevectors( self.angles ); + self.movedir = v_forward; + } + + self.angles = '0 0 0'; +} + +/* +==================== +Entities_InitTrigger + + Prepares an entity to have the properties of a TRIGGER +==================== +*/ +void Entities_InitTrigger( void ) { + if ( self.angles != '0 0 0' ) { + Entities_SetMovementDirection(); + } + self.solid = SOLID_TRIGGER; + setmodel ( self, self.model ); + self.movetype = MOVETYPE_NONE; + self.modelindex = 0; + self.model = ""; +} + +/* +==================== +Entities_MoveToDestination_End +==================== +*/ +.vector vFinalDestination; +.void() vThinkMove; +void Entities_MoveToDestination_End( void ) { + setorigin( self, self.vFinalDestination ); + self.velocity = '0 0 0'; + self.nextthink = -1; + self.vThinkMove(); +} + +/* +==================== +Entities_MoveToDestination + +Sets velocity of an ent to move to a destination at the desired speed +==================== +*/ +void Entities_MoveToDestination(vector vDestination, float fMoveSpeed, void() func) { + local vector vPositionDifference; + local float fTravelLength, fTravelTime; + + if ( !fMoveSpeed ) { + objerror("No speed defined for moving entity! Will not divide by zero."); + } + + self.vThinkMove = func; + self.vFinalDestination = vDestination; + self.think = Entities_MoveToDestination_End; + + if ( vDestination == self.origin ) { + self.velocity = '0 0 0'; + self.nextthink = ( self.ltime + 0.1 ); + return; + } + + vPositionDifference = ( vDestination - self.origin ); + fTravelLength = vlen( vPositionDifference ); + fTravelTime = ( fTravelLength / fMoveSpeed ); + + if ( fTravelTime < 0.1 ) { + self.velocity = '0 0 0'; + self.nextthink = self.ltime + 0.1; + return; + } + + self.nextthink = ( self.ltime + fTravelTime ); + self.velocity = ( vPositionDifference * ( 1 / fTravelTime ) ); +} + +/* +==================== +Entities_CalcAngleMoveDone +==================== +*/ +.vector vFinalAngle; +void Entities_RotateToDestination_End( void ) { + self.angles = self.vFinalAngle; + self.avelocity = '0 0 0'; + self.nextthink = -1; + self.vThinkMove(); +} + +/* +==================== +Entities_RotateToDestination +==================== +*/ +void Entities_RotateToDestination( vector vDestinationAngle, float fTravelSpeed, void() func ) { + local vector vAngleDifference; + local float fTravelLength, fTravelTime; + + if ( !fTravelSpeed ) { + objerror("No speed defined for moving entity! Will not divide by zero."); + } + + vAngleDifference = ( vDestinationAngle - self.angles ); + fTravelLength = vlen( vAngleDifference ); + fTravelTime = ( fTravelLength / fTravelSpeed ); + self.nextthink = ( self.ltime + fTravelTime ); + self.avelocity = ( vAngleDifference * ( 1 / fTravelTime ) ); + self.vFinalAngle = vDestinationAngle; + self.vThinkMove = func; + self.think = Entities_RotateToDestination_End; +} + + +/* +==================== +GOLDSRC-RENDERMODE STUFF +==================== +*/ enum { RENDERMODE_NORMAL = 0, RENDERMODE_COLOR, @@ -70,10 +219,6 @@ void func_wall( void ) { Entities_RenderSetup(); } -void func_door( void ) { - func_wall(); -} - void func_button( void ) { func_wall(); } diff --git a/Source/Server/EnvObjects.c b/Source/Server/EnvObjects.c index ed17b6f7..449f45dc 100644 --- a/Source/Server/EnvObjects.c +++ b/Source/Server/EnvObjects.c @@ -39,6 +39,10 @@ void cycler_sprite( void ) { Entities_RenderSetup(); } +void env_glow( void ) { + cycler_sprite(); +} + /* ================= env_render diff --git a/Source/Server/FuncDoor.c b/Source/Server/FuncDoor.c new file mode 100644 index 00000000..48c0af23 --- /dev/null +++ b/Source/Server/FuncDoor.c @@ -0,0 +1,261 @@ +/* +OpenCS Project +Copyright (C) 2015 Marco "eukara" Hladik + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* +================= +func_door Spawnflags +================= +*/ + +void() FuncDoor_MoveAway; +void() FuncDoor_MoveBack; +void() FuncDoor_Touch; + +// TODO: Finish these +#define SF_MOV_OPEN 1 +#define SF_MOV_UNLINK 4 +#define SF_MOV_PASSABLE 8 +#define SF_MOV_TOGGLE 32 +#define SF_MOV_USE 256 + +enum { + STATE_RAISED = 0, + STATE_LOWERED, + STATE_UP, + STATE_DOWN +}; + +.float speed; +.float lip; +.float dmg; +.float state; +.vector pos1, pos2; + +// Not all that customizable... +.float movesnd; +.float stopsnd; + +/* +==================== +FuncDoor_PrecacheSounds + +CS/HL have a lot of door sounds... +==================== +*/ +void FuncDoor_PrecacheSounds( void ) { + + if( self.movesnd > 0 && self.movesnd <= 10 ) { + precache_sound( sprintf( "doors/doormove%d.wav", self.movesnd ) ); + } else { + precache_sound( "common/null.wav" ); + } + + if( self.stopsnd > 0 && self.stopsnd <= 8 ) { + precache_sound( sprintf( "doors/doorstop%d.wav", self.stopsnd ) ); + } else { + precache_sound( "common/null.wav" ); + } +} + +/* +==================== +FuncDoor_Arrived +==================== +*/ +void FuncDoor_Arrived( void ) { + self.state = STATE_RAISED; + + if( self.stopsnd > 0 && self.stopsnd <= 8 ) { + sound( self, CHAN_VOICE, sprintf( "doors/doorstop%d.wav", self.stopsnd ), 1.0, ATTN_NORM ); + } else { + sound( self, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM ); + } + + if ( !( self.spawnflags & SF_MOV_USE ) ) { + self.touch = FuncDoor_Touch; + } + if ( self.wait < 0 ) { + return; + } + + self.think = FuncDoor_MoveBack; + self.nextthink = ( self.ltime + self.wait ); +} + +/* +==================== +FuncDoor_Returned +==================== +*/ +void FuncDoor_Returned( void ) { + if ( !( self.spawnflags & SF_MOV_USE ) ) { + self.touch = FuncDoor_Touch; + } + + self.state = STATE_LOWERED; +} + +/* +==================== +FuncDoor_MoveBack +==================== +*/ +void FuncDoor_MoveBack( void ) { + + if( self.movesnd > 0 && self.movesnd <= 8 ) { + sound( self, CHAN_VOICE, sprintf( "doors/doormove%d.wav", self.movesnd ), 1.0, ATTN_NORM ); + } else { + sound( self, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM ); + } + + if ( !( self.spawnflags & SF_MOV_USE ) ) { + self.touch = __NULL__; + } + + self.state = STATE_DOWN; + Entities_MoveToDestination ( self.pos1, self.speed, FuncDoor_Returned ); +} + +/* +==================== +FuncDoor_MoveAway +==================== +*/ +void FuncDoor_MoveAway( void ) { + if ( self.state == STATE_UP ) { + return; + } + + if( self.movesnd > 0 && self.movesnd <= 8 ) { + sound( self, CHAN_VOICE, sprintf( "doors/doormove%d.wav", self.movesnd ), 1.0, ATTN_NORM ); + } else { + sound( self, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM ); + } + + if ( self.state == STATE_RAISED ) { + self.nextthink = ( self.ltime + self.wait ); + return; + } + + self.state = STATE_UP; + Entities_MoveToDestination ( self.pos2, self.speed, FuncDoor_Arrived ); + Entities_UseTargets(); +} + +/* +==================== +FuncDoor_Trigger +==================== +*/ +void FuncDoor_Trigger( void ) { + if ( ( self.state == STATE_UP ) || ( self.state == STATE_RAISED ) ){ + FuncDoor_MoveBack(); + return; + } + + FuncDoor_MoveAway(); +} + +/* +==================== +FuncDoor_Touch +==================== +*/ +void FuncDoor_Touch( void ) { + if ( other.classname == "player" ) { + FuncDoor_Trigger(); + + if ( !( self.spawnflags & SF_MOV_USE ) ) { + self.touch = __NULL__; + } + } +} + +/* +==================== +FuncDoor_Blocked +==================== +*/ +void FuncDoor_Blocked( void ) { + if( self.dmg ) { + Damage_Apply( other, self, self.dmg, other.origin ); + } + + if ( self.wait >= 0 ) { + if ( self.state == STATE_DOWN ) { + FuncDoor_MoveAway (); + } else { + FuncDoor_MoveBack (); + } + } +} + +/* +==================== +func_door + +Spawn function of a moving door entity +==================== +*/ + +void func_door( void ) { + FuncDoor_PrecacheSounds(); + Entities_SetMovementDirection(); + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin( self, self.origin ); + setmodel( self, self.model ); + + self.blocked = FuncDoor_Blocked; + self.use = FuncDoor_Trigger; + + if ( !self.speed ) { + self.speed = 100; + } + if ( !self.wait ) { + self.wait = 2; + } + if ( !self.dmg ) { + self.dmg = 2; + } + if ( !self.style ) { + self.style = ATTN_NORM; + } + + if ( !( self.spawnflags & SF_MOV_TOGGLE ) ) { + if ( !( self.spawnflags & SF_MOV_USE ) ) { + self.touch = FuncDoor_Touch; + } + + self.iUsable = TRUE; + } + + self.pos1 = self.origin; + self.pos2 = ( self.pos1 + self.movedir * ( fabs( self.movedir * self.size ) - self.lip ) ); + + if ( self.spawnflags & SF_MOV_OPEN ) { + setorigin( self, self.pos2 ); + self.pos2 = self.pos1; + self.pos1 = self.origin; + } + + self.state = STATE_LOWERED; + Entities_RenderSetup(); +} diff --git a/Source/Server/FuncDoorRotating.c b/Source/Server/FuncDoorRotating.c new file mode 100644 index 00000000..a12986e5 --- /dev/null +++ b/Source/Server/FuncDoorRotating.c @@ -0,0 +1,245 @@ +/* +OpenCS Project +Copyright (C) 2015 Marco "eukara" Hladik + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* +================= +func_door_rotating Spawnflags +================= +*/ + +#define SF_ROT_OPEN 1 +#define SF_ROT_REVERSE 2 +#define SF_ROT_UNLINK 4 +#define SF_ROT_ONEWAY 16 +#define SF_ROT_TOGGLE 32 +#define SF_ROT_XAXIS 64 +#define SF_ROT_YAXIS 128 +#define SF_ROT_USE 256 + +void FuncDoorRotate_RotateAway( void ); +void FuncDoorRotate_RotateBack( void ); +void FuncDoorRotate_Touch( void ); + +.float distance; + +/* +================= +FuncDoorRotate_Arrived +================= +*/ +void FuncDoorRotate_Arrived( void ) { + self.state = STATE_RAISED; + + if( self.stopsnd > 0 && self.stopsnd <= 8 ) { + sound( self, CHAN_VOICE, sprintf( "doors/doorstop%d.wav", self.stopsnd ), 1.0, ATTN_NORM ); + } else { + sound( self, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM ); + } + + if ( !(self.spawnflags & SF_ROT_USE) ) { + self.touch = FuncDoorRotate_Touch; + } + if ( self.wait < 0 ) { + return; + } + + self.think = FuncDoorRotate_RotateBack; + self.nextthink = ( self.ltime + self.wait ); +} + +/* +================= +FuncDoorRotate_Returned +================= +*/ +void FuncDoorRotate_Returned( void ) { + if ( !(self.spawnflags & SF_ROT_USE) ) { + self.touch = FuncDoorRotate_Touch; + } + + self.state = STATE_LOWERED; +} + +/* +================= +FuncDoorRotate_RotateBack +================= +*/ +void FuncDoorRotate_RotateBack( void ) { + + if( self.movesnd > 0 && self.movesnd <= 8 ) { + sound( self, CHAN_VOICE, sprintf( "doors/doormove%d.wav", self.movesnd ), 1.0, ATTN_NORM ); + } else { + sound( self, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM ); + } + + if ( !(self.spawnflags & SF_ROT_USE) ) { + self.touch = __NULL__; + } + + self.state = STATE_DOWN; + Entities_RotateToDestination( self.pos1, self.speed, FuncDoorRotate_Returned ); +} + +/* +================= +FuncDoorRotate_Away +================= +*/ +void FuncDoorRotate_RotateAway( void ) { + float fDirection = 1.0; + + if ( self.state == STATE_UP ) { + return; + } + + if( self.movesnd > 0 && self.movesnd <= 8 ) { + sound( self, CHAN_VOICE, sprintf( "doors/doormove%d.wav", self.movesnd ), 1.0, ATTN_NORM ); + } else { + sound( self, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM ); + } + + if ( self.state == STATE_RAISED ) { + self.nextthink = ( self.ltime + self.wait ); + return; + } + + self.state = STATE_UP; + + if ( !( self.spawnflags & SF_ROT_ONEWAY ) ) { + vector vDifference = eActivator.origin - self.origin; + vector vAngles = eActivator.angles; + vAngles_x = vAngles_z = 0; + + makevectors( vAngles ); + + vector vNext = ( eActivator.origin + ( v_forward * 10 ) ) - self.origin; + + if ( ( ( vDifference_x * vNext_y ) - ( vDifference_y * vNext_x ) ) < 0 ) { + fDirection = -1.0; + } + } + + Entities_RotateToDestination( self.pos2 * fDirection, self.speed, FuncDoorRotate_Arrived ); +} + +/* +================= +brush_rotate_trigger - What happens when you +use the brush or trigger it +================= +*/ +void FuncDoorRotate_Trigger( void ) { + if ( ( self.state == STATE_UP ) || ( self.state == STATE_RAISED ) ) { + FuncDoorRotate_RotateBack(); + return; + } + + FuncDoorRotate_RotateAway(); +} + +/* +================= +FuncDoorRotate_Touch +================= +*/ +void FuncDoorRotate_Touch( void ) { + if ( other.classname == "player" ) { + FuncDoorRotate_Trigger(); + + if( !( self.spawnflags & SF_ROT_USE ) ) { + self.touch = __NULL__; + } + } +} + +/* +================= +FuncDoorRotate_Blocked +================= +*/ +void FuncDoorRotate_Blocked( void ) { + if( self.dmg ) { + Damage_Apply( other, self, self.dmg, other.origin ); + } + + if ( self.wait >= 0 ) { + if ( self.state == STATE_DOWN ) { + FuncDoorRotate_RotateAway (); + } else { + FuncDoorRotate_RotateBack (); + } + } +} + +/* +================= +BrushRotate + + Brush entity that rotates into a specific direction. Has the ability to trigger an object once touched, used or triggered otherwise. +================= +*/ +void func_door_rotating( void ) { + FuncDoor_PrecacheSounds(); + Entities_SetMovementDirection(); + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin( self, self.origin ); + setmodel( self, self.model ); + + self.blocked = FuncDoorRotate_Blocked; + self.vUse = FuncDoorRotate_Trigger; + + self.touch = FuncDoorRotate_Touch; + self.iUsable = TRUE; + + if ( !self.speed ) { + self.speed = 100; + } + + self.pos1 = self.angles; + + // Only do X + if ( self.spawnflags & SF_ROT_XAXIS ) { + self.pos2_x = self.pos1_x + self.distance; + + } + + // Only do Y + if ( self.spawnflags & SF_ROT_YAXIS ) { + self.pos2_y = self.pos1_y + self.distance; + + } + + // ...only do Y by default? + if ( !( self.spawnflags & SF_ROT_YAXIS ) && !( self.spawnflags & SF_ROT_XAXIS ) ) { + self.pos2_y = self.pos1_y + self.distance; + } + + if ( self.spawnflags & SF_ROT_OPEN ) { + vector vTemp = self.pos2; + self.pos2 = self.pos1; + self.pos1 = vTemp; + self.angles = self.pos1; + } + + self.state = STATE_LOWERED; + + Entities_RenderSetup(); +} diff --git a/Source/Server/progs.src b/Source/Server/progs.src index 562c07b9..ec71c022 100644 --- a/Source/Server/progs.src +++ b/Source/Server/progs.src @@ -51,6 +51,8 @@ FuncLadder.c FuncHostageRescue.c FuncBombTarget.c FuncBuyZone.c +FuncDoor.c +FuncDoorRotating.c Main.c Player.c