2015-05-19 21:54:34 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 1997 , 2005 - 3 D Realms Entertainment
This file is part of Shadow Warrior version 1.2
Shadow Warrior 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 . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
Original Source : 1997 - Frank Maddin and Jim Norwood
Prepared for public release : 03 / 28 / 2005 - Charlie Wiederhold , 3 D Realms
*/
//-------------------------------------------------------------------------
2019-10-09 16:09:05 +00:00
# include "ns.h"
2015-05-19 21:54:34 +00:00
# include "build.h"
# include "names2.h"
# include "panel.h"
# include "tags.h"
# include "sector.h"
# include "ai.h"
# include "player.h"
# include "game.h"
2020-05-01 11:29:12 +00:00
# include "interpso.h"
2019-03-21 02:24:19 +00:00
# include "network.h"
2015-05-19 21:54:34 +00:00
# include "sprite.h"
2020-08-05 22:18:45 +00:00
# include "misc.h"
2015-05-19 21:54:34 +00:00
# include "weapon.h"
2019-10-09 16:09:05 +00:00
BEGIN_SW_NS
2015-05-19 21:54:34 +00:00
2021-12-31 14:50:44 +00:00
void DoTrack ( SECTOR_OBJECT * sop , short locktics , int * nx , int * ny ) ;
void DoAutoTurretObject ( SECTOR_OBJECT * sop ) ;
void DoTornadoObject ( SECTOR_OBJECT * sop ) ;
2021-11-02 17:56:26 +00:00
int PickJumpSpeed ( DSWActor * , int pix_height ) ;
2021-11-01 20:14:05 +00:00
DSWActor * FindNearSprite ( DSWActor , short ) ;
2019-10-09 17:58:09 +00:00
ANIMATOR NinjaJumpActionFunc ;
2015-05-19 21:54:34 +00:00
# define ACTOR_STD_JUMP (-384)
2022-08-27 10:51:50 +00:00
DAngle GlobSpeedSO ;
2015-05-19 21:54:34 +00:00
// determine if moving down the track will get you closer to the player
2021-12-31 14:13:05 +00:00
short TrackTowardPlayer ( DSWActor * actor , TRACK * t , TRACK_POINT * start_point )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:13:05 +00:00
TRACK_POINT * end_point ;
2015-05-19 21:54:34 +00:00
// determine which end of the Track we are starting from
if ( start_point = = t - > TrackPoint )
{
end_point = t - > TrackPoint + t - > NumPoints - 1 ;
}
else
{
end_point = t - > TrackPoint ;
}
2022-08-21 20:37:46 +00:00
auto end_dist = ( end_point - > pos . XY ( ) - actor - > spr . pos . XY ( ) ) . Length ( ) ;
auto start_dist = ( start_point - > pos . XY ( ) - actor - > spr . pos . XY ( ) ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
2022-08-21 20:37:46 +00:00
return ( end_dist < start_dist ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:13:05 +00:00
short TrackStartCloserThanEnd ( DSWActor * actor , TRACK * t , TRACK_POINT * start_point )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:13:05 +00:00
TRACK_POINT * end_point ;
2015-05-19 21:54:34 +00:00
// determine which end of the Track we are starting from
if ( start_point = = t - > TrackPoint )
{
end_point = t - > TrackPoint + t - > NumPoints - 1 ;
}
else
{
end_point = t - > TrackPoint ;
}
2022-08-21 20:37:46 +00:00
auto end_dist = ( end_point - > pos . XY ( ) - actor - > spr . pos . XY ( ) ) . Length ( ) ;
auto start_dist = ( start_point - > pos . XY ( ) - actor - > spr . pos . XY ( ) ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
2022-08-21 20:37:46 +00:00
return ( start_dist < end_dist ) ;
2015-05-19 21:54:34 +00:00
}
/*
! AIC - Looks at endpoints to figure direction of the track and the closest
point to the sprite .
*/
2021-11-25 17:16:56 +00:00
short ActorFindTrack ( DSWActor * actor , int8_t player_dir , int track_type , int * track_point_num , int * track_dir )
2015-05-19 21:54:34 +00:00
{
2022-08-21 20:37:46 +00:00
const double threshold = 15000 * maptoworld ;
double near_dist = 999999 ;
2015-05-19 21:54:34 +00:00
2021-11-21 20:45:12 +00:00
int i ;
2021-11-25 17:16:56 +00:00
short end_point [ 2 ] = { 0 , 0 } ;
2015-05-19 21:54:34 +00:00
2021-12-31 14:13:05 +00:00
TRACK * t , * near_track = nullptr ;
TRACK_POINT * tp , * near_tp = nullptr ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:37:16 +00:00
enum
{
TOWARD_PLAYER = 1 ,
AWAY_FROM_PLAYER = - 1
} ;
2015-05-19 21:54:34 +00:00
// look at all tracks finding the closest endpoint
for ( t = & Track [ 0 ] ; t < & Track [ MAX_TRACKS ] ; t + + )
{
tp = t - > TrackPoint ;
// Skip if high tag is not ONE of the track type we are looking for
2021-12-29 05:13:28 +00:00
if ( ! ( t - > ttflags & track_type ) )
2015-05-19 21:54:34 +00:00
continue ;
// Skip if already someone on this track
2021-12-29 05:53:36 +00:00
if ( ( t - > flags & TF_TRACK_OCCUPIED ) )
2015-05-19 21:54:34 +00:00
{
continue ;
}
switch ( track_type )
{
case BIT ( TT_DUCK_N_SHOOT ) :
{
2021-12-26 00:30:29 +00:00
if ( ! actor - > user . ActorActionSet - > Duck )
2015-05-19 21:54:34 +00:00
return - 1 ;
end_point [ 1 ] = 0 ;
break ;
}
// for ladders only look at first track point
case BIT ( TT_LADDER ) :
{
2021-12-26 00:30:29 +00:00
if ( ! actor - > user . ActorActionSet - > Climb )
2015-05-19 21:54:34 +00:00
return - 1 ;
end_point [ 1 ] = 0 ;
break ;
}
case BIT ( TT_JUMP_UP ) :
case BIT ( TT_JUMP_DOWN ) :
{
2021-12-26 00:30:29 +00:00
if ( ! actor - > user . ActorActionSet - > Jump )
2015-05-19 21:54:34 +00:00
return - 1 ;
end_point [ 1 ] = 0 ;
break ;
}
case BIT ( TT_TRAVERSE ) :
{
2021-12-26 00:30:29 +00:00
if ( ! actor - > user . ActorActionSet - > Crawl | | ! actor - > user . ActorActionSet - > Jump )
2015-05-19 21:54:34 +00:00
return - 1 ;
break ;
}
// look at end point also
default :
end_point [ 1 ] = t - > NumPoints - 1 ;
break ;
}
2022-08-21 20:37:46 +00:00
double zdiff = 16 ;
2015-05-19 21:54:34 +00:00
// Look at both track end points to see wich is closer
for ( i = 0 ; i < 2 ; i + + )
{
tp = t - > TrackPoint + end_point [ i ] ;
2022-08-21 20:37:46 +00:00
double dist = ( tp - > pos . XY ( ) - actor - > spr . pos . XY ( ) ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
2022-08-21 20:37:46 +00:00
if ( dist < threshold & & dist < near_dist )
2015-05-19 21:54:34 +00:00
{
// make sure track start is on approximate z level - skip if
// not
2022-08-21 20:37:46 +00:00
if ( abs ( actor - > spr . pos . Z - tp - > pos . Z ) > zdiff )
2015-05-19 21:54:34 +00:00
{
continue ;
}
// determine if the track leads in the direction we want it
// to
if ( player_dir = = TOWARD_PLAYER )
{
2021-12-26 00:30:29 +00:00
if ( ! TrackTowardPlayer ( actor - > user . targetActor , t , tp ) )
2015-05-19 21:54:34 +00:00
{
continue ;
}
}
else if ( player_dir = = AWAY_FROM_PLAYER )
{
2021-12-26 00:30:29 +00:00
if ( TrackTowardPlayer ( actor - > user . targetActor , t , tp ) )
2015-05-19 21:54:34 +00:00
{
continue ;
}
}
// make sure the start distance is closer than the end
// distance
2021-11-05 23:37:16 +00:00
if ( ! TrackStartCloserThanEnd ( actor , t , tp ) )
2015-05-19 21:54:34 +00:00
{
continue ;
}
near_dist = dist ;
near_track = t ;
near_tp = tp ;
* track_point_num = end_point [ i ] ;
* track_dir = i ? - 1 : 1 ;
}
}
}
2021-11-25 17:16:56 +00:00
auto track_sect = & sector [ 0 ] ;
2022-08-21 20:37:46 +00:00
if ( near_dist < threshold )
2015-05-19 21:54:34 +00:00
{
// get the sector number of the point
2022-08-21 20:37:46 +00:00
updatesector ( near_tp - > pos , & track_sect ) ;
2015-05-19 21:54:34 +00:00
// if can see the point, return the track number
2022-08-21 20:37:46 +00:00
if ( track_sect & & FAFcansee ( actor - > spr . pos . plusZ ( - 16 ) , actor - > sector ( ) , DVector3 ( near_tp - > pos . XY ( ) , track_sect - > floorz - 32 ) , track_sect ) )
2015-05-19 21:54:34 +00:00
{
2021-05-12 14:50:20 +00:00
return short ( near_track - & Track [ 0 ] ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-11-25 17:16:56 +00:00
return - 1 ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:50:44 +00:00
void NextTrackPoint ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
sop - > point + = sop - > dir ;
if ( sop - > point > Track [ sop - > track ] . NumPoints - 1 )
sop - > point = 0 ;
if ( sop - > point < 0 )
sop - > point = Track [ sop - > track ] . NumPoints - 1 ;
}
2021-11-05 23:37:16 +00:00
void NextActorTrackPoint ( DSWActor * actor )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . point + = actor - > user . track_dir ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
if ( actor - > user . point > Track [ actor - > user . track ] . NumPoints - 1 )
actor - > user . point = 0 ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
if ( actor - > user . point < 0 )
actor - > user . point = Track [ actor - > user . track ] . NumPoints - 1 ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:13:05 +00:00
void TrackAddPoint ( TRACK * t , TRACK_POINT * tp , DSWActor * actor )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:13:05 +00:00
TRACK_POINT * tpoint = ( tp + t - > NumPoints ) ;
2015-05-19 21:54:34 +00:00
2022-08-21 20:14:04 +00:00
tpoint - > pos = actor - > spr . pos ;
tpoint - > angle = actor - > spr . angle ;
2021-12-25 00:25:07 +00:00
tpoint - > tag_low = actor - > spr . lotag ;
tpoint - > tag_high = actor - > spr . hitag ;
2015-05-19 21:54:34 +00:00
t - > NumPoints + + ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
}
2021-11-05 23:20:27 +00:00
DSWActor * TrackClonePoint ( DSWActor * actor )
2015-05-19 21:54:34 +00:00
{
2021-12-30 15:51:56 +00:00
auto actorNew = insertActor ( actor - > sector ( ) , actor - > spr . statnum ) ;
2015-05-19 21:54:34 +00:00
2021-12-24 18:41:29 +00:00
actorNew - > spr . cstat = 0 ;
actorNew - > spr . extra = 0 ;
2022-02-07 07:47:18 +00:00
actorNew - > spr . pos = actor - > spr . pos ;
2022-08-28 03:15:31 +00:00
actorNew - > spr . angle = actor - > spr . angle ;
2021-12-25 00:25:07 +00:00
actorNew - > spr . lotag = actor - > spr . lotag ;
actorNew - > spr . hitag = actor - > spr . hitag ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:20:27 +00:00
return actorNew ;
2015-05-19 21:54:34 +00:00
}
void QuickJumpSetup ( short stat , short lotag , short type )
{
2021-11-05 23:20:27 +00:00
int ndx ;
2021-12-31 14:13:05 +00:00
TRACK_POINT * tp ;
TRACK * t ;
2021-11-05 23:20:27 +00:00
DSWActor * start_sprite , * end_sprite ;
2015-05-19 21:54:34 +00:00
// make short quick jump tracks
2021-11-05 23:20:27 +00:00
SWStatIterator it ( stat ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
// find an open track
for ( ndx = 0 ; ndx < MAX_TRACKS ; ndx + + )
{
if ( Track [ ndx ] . NumPoints = = 0 )
break ;
}
ASSERT ( ndx < MAX_TRACKS ) ;
2020-12-01 15:53:29 +00:00
Track [ ndx ] . SetTrackSize ( 4 ) ;
2015-05-19 21:54:34 +00:00
tp = Track [ ndx ] . TrackPoint ;
t = & Track [ ndx ] ;
// set track type
2021-12-27 16:43:00 +00:00
t - > ttflags | = ( BIT ( type ) ) ;
2015-05-19 21:54:34 +00:00
t - > flags = 0 ;
// clone point
2021-11-05 23:20:27 +00:00
end_sprite = TrackClonePoint ( actor ) ;
start_sprite = TrackClonePoint ( actor ) ;
2015-05-19 21:54:34 +00:00
// add start point
2021-12-25 00:07:58 +00:00
start_sprite - > spr . lotag = TRACK_START ;
start_sprite - > spr . hitag = 0 ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , start_sprite ) ;
// add jump point
2022-08-16 21:17:01 +00:00
actor - > add_int_pos ( { MulScale ( 64 , bcos ( actor - > int_ang ( ) ) , 14 ) , MulScale ( 64 , bsin ( actor - > int_ang ( ) ) , 14 ) , 0 } ) ;
2021-12-25 00:07:58 +00:00
actor - > spr . lotag = lotag ;
2021-11-05 23:20:27 +00:00
TrackAddPoint ( t , tp , actor ) ;
2015-05-19 21:54:34 +00:00
// add end point
2022-08-16 21:17:01 +00:00
end_sprite - > add_int_pos ( { MulScale ( 2048 , bcos ( end_sprite - > int_ang ( ) ) , 14 ) , MulScale ( 2048 , bsin ( end_sprite - > int_ang ( ) ) , 14 ) , 0 } ) ;
2021-12-25 00:07:58 +00:00
end_sprite - > spr . lotag = TRACK_END ;
end_sprite - > spr . hitag = 0 ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , end_sprite ) ;
}
}
void QuickScanSetup ( short stat , short lotag , short type )
{
2021-11-05 23:20:27 +00:00
int ndx ;
2021-12-31 14:13:05 +00:00
TRACK_POINT * tp ;
TRACK * t ;
2021-11-05 23:20:27 +00:00
DSWActor * start_sprite , * end_sprite ;
2015-05-19 21:54:34 +00:00
// make short quick jump tracks
2021-11-05 23:20:27 +00:00
SWStatIterator it ( stat ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
// find an open track
for ( ndx = 0 ; ndx < MAX_TRACKS ; ndx + + )
{
if ( Track [ ndx ] . NumPoints = = 0 )
break ;
}
ASSERT ( ndx < MAX_TRACKS ) ;
// save space for 3 points
2020-12-01 15:53:29 +00:00
Track [ ndx ] . SetTrackSize ( 4 ) ;
2015-05-19 21:54:34 +00:00
2021-07-10 12:25:18 +00:00
ASSERT ( Track [ ndx ] . TrackPoint ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
tp = Track [ ndx ] . TrackPoint ;
t = & Track [ ndx ] ;
// set track type
2021-12-27 16:43:00 +00:00
t - > ttflags | = ( BIT ( type ) ) ;
2015-05-19 21:54:34 +00:00
t - > flags = 0 ;
// clone point
2021-11-05 23:20:27 +00:00
end_sprite = TrackClonePoint ( actor ) ;
start_sprite = TrackClonePoint ( actor ) ;
2015-05-19 21:54:34 +00:00
// add start point
2021-12-25 00:07:58 +00:00
start_sprite - > spr . lotag = TRACK_START ;
start_sprite - > spr . hitag = 0 ;
2022-08-16 21:17:01 +00:00
start_sprite - > add_int_pos ( { MulScale ( 64 , - bcos ( start_sprite - > int_ang ( ) ) , 14 ) , MulScale ( 64 , - bsin ( start_sprite - > int_ang ( ) ) , 14 ) , 0 } ) ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , start_sprite ) ;
// add jump point
2021-12-25 00:07:58 +00:00
actor - > spr . lotag = lotag ;
2021-11-05 23:20:27 +00:00
TrackAddPoint ( t , tp , actor ) ;
2015-05-19 21:54:34 +00:00
// add end point
2022-08-16 21:17:01 +00:00
end_sprite - > add_int_pos ( { MulScale ( 64 , bcos ( end_sprite - > int_ang ( ) ) , 14 ) , MulScale ( 64 , bsin ( end_sprite - > int_ang ( ) ) , 14 ) , 0 } ) ;
2021-12-25 00:07:58 +00:00
end_sprite - > spr . lotag = TRACK_END ;
end_sprite - > spr . hitag = 0 ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , end_sprite ) ;
}
}
void QuickExitSetup ( short stat , short type )
{
2021-11-05 23:20:27 +00:00
int ndx ;
2021-12-31 14:13:05 +00:00
TRACK_POINT * tp ;
TRACK * t ;
2021-11-05 23:20:27 +00:00
DSWActor * start_sprite , * end_sprite ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:20:27 +00:00
SWStatIterator it ( stat ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
// find an open track
for ( ndx = 0 ; ndx < MAX_TRACKS ; ndx + + )
{
if ( Track [ ndx ] . NumPoints = = 0 )
break ;
}
ASSERT ( ndx < MAX_TRACKS ) ;
// save space for 3 points
2020-12-01 15:53:29 +00:00
Track [ ndx ] . SetTrackSize ( 4 ) ;
2015-05-19 21:54:34 +00:00
2021-07-10 12:25:18 +00:00
ASSERT ( Track [ ndx ] . TrackPoint ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
tp = Track [ ndx ] . TrackPoint ;
t = & Track [ ndx ] ;
// set track type
2021-12-27 16:43:00 +00:00
t - > ttflags | = ( BIT ( type ) ) ;
2015-05-19 21:54:34 +00:00
t - > flags = 0 ;
// clone point
2021-11-05 23:20:27 +00:00
end_sprite = TrackClonePoint ( actor ) ;
start_sprite = TrackClonePoint ( actor ) ;
2015-05-19 21:54:34 +00:00
// add start point
2021-12-25 00:07:58 +00:00
start_sprite - > spr . lotag = TRACK_START ;
start_sprite - > spr . hitag = 0 ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , start_sprite ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
// add end point
2022-08-16 21:17:01 +00:00
end_sprite - > add_int_pos ( { MulScale ( 1024 , bcos ( end_sprite - > int_ang ( ) ) , 14 ) , MulScale ( 1024 , bsin ( end_sprite - > int_ang ( ) ) , 14 ) , 0 } ) ;
2021-12-25 00:07:58 +00:00
end_sprite - > spr . lotag = TRACK_END ;
end_sprite - > spr . hitag = 0 ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , end_sprite ) ;
}
}
void QuickLadderSetup ( short stat , short lotag , short type )
{
2021-11-05 23:20:27 +00:00
int ndx ;
2021-12-31 14:13:05 +00:00
TRACK_POINT * tp ;
TRACK * t ;
2021-11-05 23:20:27 +00:00
DSWActor * start_sprite , * end_sprite ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:20:27 +00:00
SWStatIterator it ( stat ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
// find an open track
for ( ndx = 0 ; ndx < MAX_TRACKS ; ndx + + )
{
if ( Track [ ndx ] . NumPoints = = 0 )
break ;
}
ASSERT ( ndx < MAX_TRACKS ) ;
// save space for 3 points
2020-12-01 15:53:29 +00:00
Track [ ndx ] . SetTrackSize ( 4 ) ;
2015-05-19 21:54:34 +00:00
2021-07-10 12:25:18 +00:00
ASSERT ( Track [ ndx ] . TrackPoint ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
tp = Track [ ndx ] . TrackPoint ;
t = & Track [ ndx ] ;
// set track type
2021-12-27 16:43:00 +00:00
t - > ttflags | = ( BIT ( type ) ) ;
2015-05-19 21:54:34 +00:00
t - > flags = 0 ;
// clone point
2021-11-05 23:20:27 +00:00
end_sprite = TrackClonePoint ( actor ) ;
start_sprite = TrackClonePoint ( actor ) ;
2015-05-19 21:54:34 +00:00
// add start point
2021-12-25 00:07:58 +00:00
start_sprite - > spr . lotag = TRACK_START ;
start_sprite - > spr . hitag = 0 ;
2022-08-16 21:15:49 +00:00
start_sprite - > add_int_pos ( { MOVEx ( 256 , start_sprite - > int_ang ( ) + 1024 ) , MOVEy ( 256 , start_sprite - > int_ang ( ) + 1024 ) , 0 } ) ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , start_sprite ) ;
// add climb point
2021-12-25 00:07:58 +00:00
actor - > spr . lotag = lotag ;
2021-11-05 23:20:27 +00:00
TrackAddPoint ( t , tp , actor ) ;
2015-05-19 21:54:34 +00:00
// add end point
2022-08-16 21:17:01 +00:00
end_sprite - > add_int_pos ( { MOVEx ( 512 , end_sprite - > int_ang ( ) ) , MOVEy ( 512 , end_sprite - > int_ang ( ) ) , 0 } ) ;
2021-12-25 00:07:58 +00:00
end_sprite - > spr . lotag = TRACK_END ;
end_sprite - > spr . hitag = 0 ;
2015-05-19 21:54:34 +00:00
TrackAddPoint ( t , tp , end_sprite ) ;
}
}
2021-11-05 23:10:04 +00:00
void TrackSetup ( void )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
int ndx ;
2021-12-31 14:13:05 +00:00
TRACK_POINT * tp ;
TRACK * t ;
TRACK_POINT * New ;
2015-05-19 21:54:34 +00:00
int size ;
// put points on track
for ( ndx = 0 ; ndx < MAX_TRACKS ; ndx + + )
{
2021-11-05 23:10:04 +00:00
SWStatIterator it ( STAT_TRACK + ndx ) ;
if ( ! it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
// for some reason I need at least one record allocated
// can't remember why at this point
2021-12-31 14:13:05 +00:00
Track [ ndx ] . TrackPoint = ( TRACK_POINT * ) CallocMem ( sizeof ( TRACK_POINT ) * 1 , 1 ) ;
2015-05-19 21:54:34 +00:00
continue ;
}
2021-07-10 12:25:18 +00:00
ASSERT ( Track [ ndx ] . TrackPoint = = nullptr ) ;
2015-05-19 21:54:34 +00:00
// make the track array rather large. I'll resize it to correct size
// later.
2021-12-31 14:13:05 +00:00
Track [ ndx ] . TrackPoint = ( TRACK_POINT * ) CallocMem ( sizeof ( TRACK_POINT ) * 500 , 1 ) ;
2015-05-19 21:54:34 +00:00
2021-07-10 12:25:18 +00:00
ASSERT ( Track [ ndx ] . TrackPoint ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
tp = Track [ ndx ] . TrackPoint ;
t = & Track [ ndx ] ;
// find the first point and save it
2021-11-05 23:10:04 +00:00
it . Reset ( STAT_TRACK + ndx ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-21 22:18:23 +00:00
if ( actor - > spr . lotag = = TRACK_START )
2015-05-19 21:54:34 +00:00
{
ASSERT ( t - > NumPoints = = 0 ) ;
2021-11-05 23:20:27 +00:00
TrackAddPoint ( t , tp , actor ) ;
2015-05-19 21:54:34 +00:00
break ;
}
}
// didn't find the start point of the track
if ( t - > NumPoints = = 0 )
{
2020-10-15 15:45:07 +00:00
int i ;
2021-11-05 23:10:04 +00:00
it . Reset ( STAT_TRACK + ndx ) ;
auto itActor = it . Next ( ) ;
2022-02-01 23:08:21 +00:00
Printf ( " WARNING: Did not find first point of Track Number %d, x %d, y %d \n " , ndx , itActor - > int_pos ( ) . X , itActor - > int_pos ( ) . Y ) ;
2021-11-05 23:10:04 +00:00
it . Reset ( STAT_TRACK + ndx ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
// neuter the track's sprite list
2021-11-05 23:20:27 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
}
continue ;
}
// set up flags for track types
if ( tp - > tag_low = = TRACK_START & & tp - > tag_high )
2021-12-27 16:43:00 +00:00
t - > ttflags | = ( BIT ( tp - > tag_high ) ) ;
2015-05-19 21:54:34 +00:00
// while there are still sprites on this status list
2021-11-05 23:10:04 +00:00
while ( it . Reset ( STAT_TRACK + ndx ) , it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:10:04 +00:00
DSWActor * next_actor = nullptr ;
2022-08-21 20:51:03 +00:00
double dist , low_dist = 999999 ;
2015-05-19 21:54:34 +00:00
// find the closest point to the last point
2021-11-05 23:10:04 +00:00
it . Reset ( STAT_TRACK + ndx ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2022-08-21 20:51:03 +00:00
dist = ( ( tp + t - > NumPoints - 1 ) - > pos - actor - > spr . pos ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
if ( dist < low_dist )
{
2021-11-05 23:10:04 +00:00
next_actor = actor ;
2015-05-19 21:54:34 +00:00
low_dist = dist ;
}
}
// save the closest one off and kill it
2021-11-05 23:10:04 +00:00
if ( next_actor ! = nullptr )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:20:27 +00:00
TrackAddPoint ( t , tp , next_actor ) ;
2015-05-19 21:54:34 +00:00
}
}
size = ( Track [ ndx ] . NumPoints + 1 ) * sizeof ( TRACK_POINT ) ;
2021-12-31 14:13:05 +00:00
New = ( TRACK_POINT * ) CallocMem ( size , 1 ) ;
2017-01-23 11:21:32 +00:00
memcpy ( New , Track [ ndx ] . TrackPoint , size ) ;
2015-05-19 21:54:34 +00:00
FreeMem ( Track [ ndx ] . TrackPoint ) ;
2017-01-23 11:21:32 +00:00
Track [ ndx ] . TrackPoint = New ;
2015-05-19 21:54:34 +00:00
2021-07-10 12:25:18 +00:00
ASSERT ( Track [ ndx ] . TrackPoint ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
}
QuickJumpSetup ( STAT_QUICK_JUMP , TRACK_ACTOR_QUICK_JUMP , TT_JUMP_UP ) ;
QuickJumpSetup ( STAT_QUICK_JUMP_DOWN , TRACK_ACTOR_QUICK_JUMP_DOWN , TT_JUMP_DOWN ) ;
QuickJumpSetup ( STAT_QUICK_SUPER_JUMP , TRACK_ACTOR_QUICK_SUPER_JUMP , TT_SUPER_JUMP_UP ) ;
QuickScanSetup ( STAT_QUICK_SCAN , TRACK_ACTOR_QUICK_SCAN , TT_SCAN ) ;
QuickLadderSetup ( STAT_QUICK_LADDER , TRACK_ACTOR_CLIMB_LADDER , TT_LADDER ) ;
QuickExitSetup ( STAT_QUICK_EXIT , TT_EXIT ) ;
QuickJumpSetup ( STAT_QUICK_OPERATE , TRACK_ACTOR_QUICK_OPERATE , TT_OPERATE ) ;
QuickJumpSetup ( STAT_QUICK_DUCK , TRACK_ACTOR_QUICK_DUCK , TT_DUCK_N_SHOOT ) ;
QuickJumpSetup ( STAT_QUICK_DEFEND , TRACK_ACTOR_QUICK_DEFEND , TT_HIDE_N_SHOOT ) ;
}
2021-11-05 22:59:45 +00:00
DSWActor * FindBoundSprite ( int tag )
2015-05-19 21:54:34 +00:00
{
2021-11-05 22:59:45 +00:00
SWStatIterator it ( STAT_ST1 ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-21 22:18:23 +00:00
if ( actor - > spr . hitag = = tag )
2015-05-19 21:54:34 +00:00
{
2021-11-05 22:59:45 +00:00
return actor ;
2015-05-19 21:54:34 +00:00
}
}
2021-07-10 12:25:18 +00:00
return nullptr ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:50:44 +00:00
void SectorObjectSetupBounds ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
int xlow , ylow , xhigh , yhigh ;
2021-11-02 18:07:05 +00:00
int startwall , endwall ;
2015-05-19 21:54:34 +00:00
int i , k , j ;
2021-11-05 22:59:45 +00:00
DSWActor * BoundActor = nullptr ;
2020-09-09 18:32:24 +00:00
bool FoundOutsideLoop = false ;
bool SectorInBounds ;
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2021-12-26 00:22:41 +00:00
DSWActor * child = sop - > sp_child ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:37:16 +00:00
static const uint8_t StatList [ ] =
2015-05-19 21:54:34 +00:00
{
STAT_DEFAULT , STAT_MISC , STAT_ITEM , STAT_TRAP ,
STAT_SPAWN_SPOT , STAT_SOUND_SPOT , STAT_WALL_MOVE ,
STAT_WALLBLOOD_QUEUE ,
STAT_SPRITE_HIT_MATCH ,
STAT_AMBIENT ,
STAT_DELETE_SPRITE ,
STAT_SPAWN_TRIGGER , // spawing monster trigger - for Randy's bullet train.
//STAT_FLOOR_PAN, STAT_CEILING_PAN
} ;
// search for 2 sprite bounding tags
2021-11-05 22:59:45 +00:00
BoundActor = FindBoundSprite ( 500 + ( int ( sop - SectorObject ) * 5 ) ) ;
if ( BoundActor = = nullptr )
{
I_Error ( " SOP bound sprite with hitag %d not found " , 500 + ( int ( sop - SectorObject ) * 5 ) ) ;
}
2015-05-19 21:54:34 +00:00
2022-02-01 23:08:21 +00:00
xlow = BoundActor - > int_pos ( ) . X ;
ylow = BoundActor - > int_pos ( ) . Y ;
2015-05-19 21:54:34 +00:00
2021-11-05 22:59:45 +00:00
KillActor ( BoundActor ) ;
BoundActor = FindBoundSprite ( 501 + ( int ( sop - SectorObject ) * 5 ) ) ;
if ( BoundActor = = nullptr )
{
I_Error ( " SOP bound sprite with hitag %d not found " , 501 + ( int ( sop - SectorObject ) * 5 ) ) ;
}
2022-02-01 23:08:21 +00:00
xhigh = BoundActor - > int_pos ( ) . X ;
yhigh = BoundActor - > int_pos ( ) . Y ;
2015-05-19 21:54:34 +00:00
2021-11-05 22:59:45 +00:00
KillActor ( BoundActor ) ;
2015-05-19 21:54:34 +00:00
// set radius for explosion checking - based on bounding box
2021-12-26 00:22:41 +00:00
child - > user . Radius = ( ( xhigh - xlow ) + ( yhigh - ylow ) ) > > 2 ;
child - > user . Radius - = ( child - > user . Radius > > 2 ) ; // trying to get it a good size
2015-05-19 21:54:34 +00:00
// search for center sprite if it exists
2021-11-05 22:59:45 +00:00
BoundActor = FindBoundSprite ( SECT_SO_CENTER ) ;
if ( BoundActor )
2015-05-19 21:54:34 +00:00
{
2022-08-18 17:14:50 +00:00
sop - > pmid = BoundActor - > spr . pos ;
2021-11-05 22:59:45 +00:00
KillActor ( BoundActor ) ;
2015-05-19 21:54:34 +00:00
}
#if 0
// look for players on sector object
2021-12-31 14:59:11 +00:00
PLAYER * pp ;
2020-03-06 15:49:55 +00:00
short pnum ;
2015-05-19 21:54:34 +00:00
TRAVERSE_CONNECT ( pnum )
{
pp = & Player [ pnum ] ;
if ( pp - > posx > xlow & & pp - > posx < xhigh & & pp - > posy > ylow & & pp - > posy < yhigh )
{
2022-08-27 13:09:22 +00:00
pp - > RevolveAng = pp - > angle . ang ;
2021-12-30 06:42:34 +00:00
pp - > Revolve . X = pp - > pos . X ;
2021-12-30 06:37:47 +00:00
pp - > Revolve . Y = pp - > pos . Y ;
2022-08-28 00:40:50 +00:00
pp - > RevolveDeltaAng = nullAngle ;
2021-12-27 16:22:41 +00:00
pp - > Flags | = ( PF_PLAYER_RIDING ) ;
2015-05-19 21:54:34 +00:00
pp - > sop_riding = sop ;
}
}
# endif
// look through all sectors for whole sectors that are IN bounds
2021-12-21 08:23:39 +00:00
for ( auto & sec : sector )
2015-05-19 21:54:34 +00:00
{
2021-11-25 16:27:41 +00:00
auto sect = & sec ;
2020-09-09 17:52:52 +00:00
SectorInBounds = true ;
2015-05-19 21:54:34 +00:00
2021-11-25 16:27:41 +00:00
for ( auto & wal : wallsofsector ( sect ) )
2015-05-19 21:54:34 +00:00
{
// all walls have to be in bounds to be in sector object
2022-01-27 16:41:10 +00:00
if ( ! ( wal . wall_int_pos ( ) . X > xlow & & wal . wall_int_pos ( ) . X < xhigh & & wal . wall_int_pos ( ) . Y > ylow & & wal . wall_int_pos ( ) . Y < yhigh ) )
2015-05-19 21:54:34 +00:00
{
2020-09-09 17:52:52 +00:00
SectorInBounds = false ;
2015-05-19 21:54:34 +00:00
break ;
}
}
if ( SectorInBounds )
{
2021-11-19 22:20:58 +00:00
sop - > sectp [ sop - > num_sectors ] = sect ;
2021-11-24 22:01:43 +00:00
sop - > sectp [ sop - > num_sectors + 1 ] = nullptr ;
2015-05-19 21:54:34 +00:00
// all sectors in sector object have this flag set - for colision
// detection and recognition
2021-12-27 17:07:45 +00:00
sect - > extra | = SECTFX_SECTOR_OBJECT ;
2015-05-19 21:54:34 +00:00
2022-02-02 23:46:04 +00:00
sop - > zorig_floor [ sop - > num_sectors ] = sect - > int_floorz ( ) ;
sop - > zorig_ceiling [ sop - > num_sectors ] = sect - > int_ceilingz ( ) ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( sect - > extra & SECTFX_SINK ) )
2021-11-20 22:20:43 +00:00
sop - > zorig_floor [ sop - > num_sectors ] + = Z ( FixedToInt ( sect - > depth_fixed ) ) ;
2015-05-19 21:54:34 +00:00
2022-02-02 23:59:12 +00:00
// lowest and highest floor z's
2022-02-02 23:46:04 +00:00
if ( sect - > int_floorz ( ) > sop - > floor_loz )
sop - > floor_loz = sect - > int_floorz ( ) ;
2015-05-19 21:54:34 +00:00
2022-02-02 23:46:04 +00:00
if ( sect - > int_floorz ( ) < sop - > floor_hiz )
sop - > floor_hiz = sect - > int_floorz ( ) ;
2015-05-19 21:54:34 +00:00
sop - > num_sectors + + ;
}
2021-11-24 22:01:43 +00:00
ASSERT ( ( uint16_t ) sop - > num_sectors < SIZ ( SectorObject [ 0 ] . sectp ) ) ;
2015-05-19 21:54:34 +00:00
}
//
// Make sure every sector object has an outer loop tagged - important
//
2020-09-09 17:52:52 +00:00
FoundOutsideLoop = false ;
2015-05-19 21:54:34 +00:00
for ( sectp = sop - > sectp , j = 0 ; * sectp ; sectp + + , j + + )
{
// move all walls in sectors
2021-11-24 19:59:19 +00:00
for ( auto & wal : wallsofsector ( * sectp ) )
2015-05-19 21:54:34 +00:00
{
// for morph point - tornado style
2021-11-24 19:59:19 +00:00
if ( wal . lotag = = TAG_WALL_ALIGN_SLOPE_TO_POINT )
2021-11-25 17:16:56 +00:00
sop - > morph_wall_point = & wal ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( wal . extra & & ( wal . extra & WALLFX_LOOP_OUTER ) )
2020-09-09 17:52:52 +00:00
FoundOutsideLoop = true ;
2015-05-19 21:54:34 +00:00
// each wall has this set - for collision detection
2021-12-27 17:07:45 +00:00
wal . extra | = WALLFX_SECTOR_OBJECT | WALLFX_DONT_STICK ;
2021-11-24 19:59:19 +00:00
if ( wal . twoSided ( ) )
2021-12-27 17:07:45 +00:00
wal . nextWall ( ) - > extra | = WALLFX_SECTOR_OBJECT | WALLFX_DONT_STICK ;
2015-05-19 21:54:34 +00:00
}
}
if ( ! FoundOutsideLoop )
{
2019-12-25 10:26:19 +00:00
I_Error ( " Forgot to tag outer loop for Sector Object #%d " , ( int ) ( sop - SectorObject ) ) ;
2015-05-19 21:54:34 +00:00
}
2020-05-01 11:29:12 +00:00
so_addinterpolation ( sop ) ;
2020-04-15 10:21:11 +00:00
2015-05-19 21:54:34 +00:00
for ( i = 0 ; i < ( int ) SIZ ( StatList ) ; i + + )
{
2021-11-02 17:42:25 +00:00
SWStatIterator it ( StatList [ i ] ) ;
while ( auto itActor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2022-02-01 23:08:21 +00:00
if ( itActor - > int_pos ( ) . X > xlow & & itActor - > int_pos ( ) . X < xhigh & & itActor - > int_pos ( ) . Y > ylow & & itActor - > int_pos ( ) . Y < yhigh )
2015-05-19 21:54:34 +00:00
{
// some delete sprites ride others don't
2021-12-25 00:07:58 +00:00
if ( itActor - > spr . statnum = = STAT_DELETE_SPRITE )
2015-05-19 21:54:34 +00:00
{
2021-12-25 00:02:25 +00:00
if ( ! TEST_BOOL2 ( itActor ) )
2015-05-19 21:54:34 +00:00
continue ;
}
2021-11-02 17:42:25 +00:00
if ( ! itActor - > hasU ( ) )
2021-12-26 00:22:41 +00:00
SpawnUser ( itActor , 0 , nullptr ) ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:22:41 +00:00
itActor - > user . RotNum = 0 ;
2015-05-19 21:54:34 +00:00
2021-12-30 16:10:08 +00:00
itActor - > backuppos ( ) ;
2022-08-20 20:31:35 +00:00
itActor - > user . oz = itActor - > opos . Z ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:07:58 +00:00
switch ( itActor - > spr . statnum )
2015-05-19 21:54:34 +00:00
{
case STAT_WALL_MOVE :
break ;
case STAT_DEFAULT :
2021-12-25 00:07:58 +00:00
switch ( itActor - > spr . hitag )
2015-05-19 21:54:34 +00:00
{
case SO_CLIP_BOX :
{
short ang2 ;
sop - > clipdist = 0 ;
2021-12-25 00:07:58 +00:00
sop - > clipbox_dist [ sop - > clipbox_num ] = itActor - > spr . lotag ;
2022-08-18 16:27:31 +00:00
sop - > clipbox_xoff [ sop - > clipbox_num ] = sop - > int_pmid ( ) . X - itActor - > int_pos ( ) . X ;
sop - > clipbox_yoff [ sop - > clipbox_num ] = sop - > int_pmid ( ) . Y - itActor - > int_pos ( ) . Y ;
2015-05-19 21:54:34 +00:00
2022-08-18 16:27:31 +00:00
sop - > clipbox_vdist [ sop - > clipbox_num ] = ksqrt ( SQ ( sop - > int_pmid ( ) . X - itActor - > int_pos ( ) . X ) + SQ ( sop - > int_pmid ( ) . Y - itActor - > int_pos ( ) . Y ) ) ;
2015-05-19 21:54:34 +00:00
2022-08-18 16:27:31 +00:00
ang2 = getangle ( itActor - > int_pos ( ) . X - sop - > int_pmid ( ) . X , itActor - > int_pos ( ) . Y - sop - > int_pmid ( ) . Y ) ;
2020-09-16 11:46:03 +00:00
sop - > clipbox_ang [ sop - > clipbox_num ] = getincangle ( ang2 , sop - > ang ) ;
2015-05-19 21:54:34 +00:00
sop - > clipbox_num + + ;
2021-11-02 17:42:25 +00:00
KillActor ( itActor ) ;
2015-05-19 21:54:34 +00:00
goto cont ;
}
case SO_SHOOT_POINT :
2021-11-02 17:42:25 +00:00
ClearOwner ( itActor ) ;
change_actor_stat ( itActor , STAT_SO_SHOOT_POINT ) ;
2021-12-27 18:07:39 +00:00
itActor - > spr . cstat & = ~ ( CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
2015-05-19 21:54:34 +00:00
break ;
default :
break ;
}
break ;
}
2022-08-21 07:25:15 +00:00
itActor - > user . pos . XY ( ) = sop - > pmid . XY ( ) - itActor - > spr . pos . XY ( ) ;
itActor - > user . pos . Z = sop - > mid_sector - > floorz - itActor - > spr . pos . Z ;
2015-05-19 21:54:34 +00:00
2021-12-27 17:07:45 +00:00
itActor - > user . Flags | = ( SPR_SO_ATTACHED ) ;
2015-05-19 21:54:34 +00:00
2022-08-16 21:17:01 +00:00
itActor - > user . sang = itActor - > int_ang ( ) ;
2021-12-26 00:22:41 +00:00
itActor - > user . spal = itActor - > spr . pal ;
2015-05-19 21:54:34 +00:00
// search SO's sectors to make sure that it is not on a
// sector
// place all sprites on list
2020-02-10 19:33:48 +00:00
int sn ;
2021-11-02 17:45:21 +00:00
for ( sn = 0 ; sn < ( int ) SIZ ( sop - > so_actors ) ; sn + + )
2015-05-19 21:54:34 +00:00
{
2021-11-02 17:45:21 +00:00
if ( sop - > so_actors [ sn ] = = nullptr )
2015-05-19 21:54:34 +00:00
break ;
}
2021-11-02 17:45:21 +00:00
sop - > so_actors [ sn ] = itActor ;
2021-11-02 17:42:25 +00:00
so_setspriteinterpolation ( sop , itActor ) ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:13:28 +00:00
if ( ! ( sop - > flags & SOBJ_SPRITE_OBJ ) )
2015-05-19 21:54:34 +00:00
{
// determine if sprite is on a SO sector - set flag if
// true
for ( j = 0 ; j < sop - > num_sectors ; j + + )
{
2021-12-30 15:51:56 +00:00
if ( sop - > sectp [ j ] = = itActor - > sector ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-27 17:07:45 +00:00
itActor - > user . Flags | = ( SPR_ON_SO_SECTOR ) ;
2022-08-21 07:25:15 +00:00
itActor - > user . pos . Z = itActor - > sector ( ) - > floorz - itActor - > spr . pos . Z ;
2015-05-19 21:54:34 +00:00
break ;
}
}
}
}
cont :
continue ;
}
}
2021-12-26 00:30:29 +00:00
// for SPRITE OBJECT sprites, set the actor->user.sz value to the difference
2021-12-25 00:25:07 +00:00
// between the zmid and the actor->spr.z
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_SPRITE_OBJ ) )
2015-05-19 21:54:34 +00:00
{
int zmid = - 9999999 ;
// choose the lowest sprite for the zmid
2021-11-02 17:45:21 +00:00
for ( i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
2015-05-19 21:54:34 +00:00
{
2021-12-24 23:45:19 +00:00
auto actor = sop - > so_actors [ i ] ;
2015-05-19 21:54:34 +00:00
2022-02-01 23:08:21 +00:00
if ( actor - > int_pos ( ) . Z > zmid )
zmid = actor - > int_pos ( ) . Z ;
2015-05-19 21:54:34 +00:00
}
ASSERT ( zmid ! = - 9999999 ) ;
2022-08-18 17:14:50 +00:00
sop - > pmid . Z = zmid * inttoworld ;
2015-05-19 21:54:34 +00:00
2021-11-02 17:45:21 +00:00
for ( i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
{
2021-12-24 23:45:19 +00:00
auto actor = sop - > so_actors [ i ] ;
2022-08-21 07:25:15 +00:00
actor - > user . pos . Z = sop - > pmid . Z - actor - > spr . pos . Z ;
2015-05-19 21:54:34 +00:00
}
}
}
2021-11-24 21:39:01 +00:00
void SetupSectorObject ( sectortype * sectp , short tag )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * sop ;
2021-10-30 18:00:02 +00:00
int object_num ;
2020-03-06 15:49:49 +00:00
short j ;
2015-05-19 21:54:34 +00:00
tag - = ( TAG_OBJECT_CENTER - 1 ) ;
object_num = tag / 5 ;
sop = & SectorObject [ object_num ] ;
// initialize stuff first time through
if ( sop - > num_sectors = = - 1 )
{
2021-12-31 14:50:44 +00:00
void DoTornadoObject ( SECTOR_OBJECT * sop ) ;
void MorphTornado ( SECTOR_OBJECT * sop ) ;
void MorphFloor ( SECTOR_OBJECT * sop ) ;
void ScaleSectorObject ( SECTOR_OBJECT * sop ) ;
void DoAutoTurretObject ( SECTOR_OBJECT * sop ) ;
2015-05-19 21:54:34 +00:00
memset ( sop - > sectp , 0 , sizeof ( sop - > sectp ) ) ;
2021-11-02 17:45:21 +00:00
memset ( sop - > so_actors , 0 , sizeof ( sop - > so_actors ) ) ;
2021-11-25 17:16:56 +00:00
sop - > morph_wall_point = nullptr ;
sop - > op_main_sector = nullptr ;
2021-11-24 22:07:02 +00:00
sop - > scratch = nullptr ; // this is a guard field for sectp, because several loops do not test the end properly.
2021-11-02 17:52:59 +00:00
sop - > match_event_actor = nullptr ;
2015-05-19 21:54:34 +00:00
sop - > crush_z = 0 ;
sop - > drive_angspeed = 0 ;
sop - > drive_angslide = 0 ;
sop - > drive_slide = 0 ;
sop - > drive_speed = 0 ;
sop - > num_sectors = 0 ;
sop - > update = 15000 ;
sop - > flags = 0 ;
sop - > clipbox_num = 0 ;
sop - > bob_amt = 0 ;
sop - > vel_rate = 6 ;
sop - > z_rate = 256 ;
2022-08-21 21:10:51 +00:00
sop - > z_tgt = 0 ;
sop - > zdelta = 0 ;
2015-05-19 21:54:34 +00:00
sop - > wait_tics = 0 ;
sop - > spin_speed = 0 ;
sop - > spin_ang = 0 ;
sop - > ang_orig = 0 ;
sop - > clipdist = 1024 ;
sop - > target_dist = 0 ;
sop - > turn_speed = 4 ;
sop - > floor_loz = - 9999999 ;
sop - > floor_hiz = 9999999 ;
sop - > player_xoff = sop - > player_yoff = 0 ;
sop - > ang_tgt = sop - > ang = sop - > ang_moving = 0 ;
2021-11-24 22:07:02 +00:00
sop - > op_main_sector = nullptr ;
2015-05-19 21:54:34 +00:00
sop - > ram_damage = 0 ;
sop - > max_damage = - 9999 ;
sop - > scale_type = SO_SCALE_NONE ;
sop - > scale_dist = 0 ;
sop - > scale_speed = 20 ;
sop - > scale_dist_min = - 1024 ;
sop - > scale_dist_max = 1024 ;
sop - > scale_rand_freq = 64 > > 3 ;
sop - > scale_x_mult = 256 ;
sop - > scale_y_mult = 256 ;
sop - > morph_ang = RANDOM_P2 ( 2048 ) ;
sop - > morph_z_speed = 20 ;
sop - > morph_speed = 32 ;
sop - > morph_dist_max = 1024 ;
sop - > morph_rand_freq = 64 ;
sop - > morph_dist = 0 ;
sop - > morph_xoff = 0 ;
sop - > morph_yoff = 0 ;
2021-07-10 12:25:18 +00:00
sop - > PreMoveAnimator = nullptr ;
sop - > PostMoveAnimator = nullptr ;
sop - > Animator = nullptr ;
2015-05-19 21:54:34 +00:00
}
switch ( tag % 5 )
{
case TAG_OBJECT_CENTER - 500 :
2021-11-24 21:49:00 +00:00
sop - > mid_sector = sectp ;
2022-08-18 17:14:50 +00:00
sop - > pmid = SectorMidPoint ( sectp ) ;
2015-05-19 21:54:34 +00:00
sop - > dir = 1 ;
2021-11-24 21:39:01 +00:00
sop - > track = sectp - > hitag ;
2015-05-19 21:54:34 +00:00
// spawn a sprite to make it easier to integrate with sprite routines
2022-08-22 16:43:10 +00:00
auto actorNew = SpawnActor ( STAT_SO_SP_CHILD , 0 , nullptr , sectp , sop - > pmid , nullAngle , 0 ) ;
2021-11-01 19:07:53 +00:00
sop - > sp_child = actorNew ;
2021-12-26 00:22:41 +00:00
actorNew - > user . sop_parent = sop ;
2021-12-27 16:43:00 +00:00
actorNew - > user . Flags2 | = ( SPR2_SPRITE_FAKE_BLOCK ) ; // for damage test
2015-05-19 21:54:34 +00:00
// check for any ST1 sprites laying on the center sector
2021-11-24 21:39:01 +00:00
SWSectIterator it ( sectp ) ;
2021-10-30 18:00:02 +00:00
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-25 00:25:07 +00:00
if ( actor - > spr . statnum = = STAT_ST1 )
2015-05-19 21:54:34 +00:00
{
2021-12-25 00:25:07 +00:00
switch ( actor - > spr . hitag )
2015-05-19 21:54:34 +00:00
{
case SO_SCALE_XY_MULT :
2021-12-25 00:20:36 +00:00
if ( SP_TAG5 ( actor ) )
sop - > scale_x_mult = SP_TAG5 ( actor ) ;
if ( SP_TAG6 ( actor ) )
sop - > scale_y_mult = SP_TAG6 ( actor ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SCALE_POINT_INFO :
memset ( sop - > scale_point_dist , 0 , sizeof ( sop - > scale_point_dist ) ) ;
2021-12-24 13:12:21 +00:00
sop - > scale_point_base_speed = SP_TAG2 ( actor ) ;
2015-05-19 21:54:34 +00:00
for ( j = 0 ; j < ( int ) SIZ ( sop - > scale_point_speed ) ; j + + )
{
2021-12-24 13:12:21 +00:00
sop - > scale_point_speed [ j ] = SP_TAG2 ( actor ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-25 00:20:36 +00:00
if ( SP_TAG4 ( actor ) )
sop - > scale_point_rand_freq = ( uint8_t ) SP_TAG4 ( actor ) ;
2015-05-19 21:54:34 +00:00
else
sop - > scale_point_rand_freq = 64 ;
2021-12-25 00:20:36 +00:00
sop - > scale_point_dist_min = - SP_TAG5 ( actor ) ;
sop - > scale_point_dist_max = SP_TAG6 ( actor ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SCALE_INFO :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_DYNAMIC ) ;
2021-12-24 13:12:21 +00:00
sop - > scale_speed = SP_TAG2 ( actor ) ;
2021-12-25 00:20:36 +00:00
sop - > scale_dist_min = - SP_TAG5 ( actor ) ;
sop - > scale_dist_max = SP_TAG6 ( actor ) ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:20:36 +00:00
sop - > scale_type = SP_TAG4 ( actor ) ;
sop - > scale_active_type = SP_TAG7 ( actor ) ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:20:36 +00:00
if ( SP_TAG8 ( actor ) )
sop - > scale_rand_freq = ( uint8_t ) SP_TAG8 ( actor ) ;
2015-05-19 21:54:34 +00:00
else
sop - > scale_rand_freq = 64 > > 3 ;
2021-12-25 00:20:36 +00:00
if ( SP_TAG3 ( actor ) = = 0 )
2015-05-19 21:54:34 +00:00
sop - > scale_dist = sop - > scale_dist_min ;
2021-12-25 00:20:36 +00:00
else if ( SP_TAG3 ( actor ) = = 1 )
2015-05-19 21:54:34 +00:00
sop - > scale_dist = sop - > scale_dist_max ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SPAWN_SPOT :
2021-12-25 00:25:07 +00:00
if ( actor - > spr . clipdist = = 3 )
2015-05-19 21:54:34 +00:00
{
2021-10-30 18:00:02 +00:00
change_actor_stat ( actor , STAT_NO_STATE ) ;
2021-12-26 00:22:41 +00:00
SpawnUser ( actor , 0 , nullptr ) ;
actor - > user . ActorActionFunc = nullptr ;
2015-05-19 21:54:34 +00:00
}
break ;
case SO_AUTO_TURRET :
sop - > Animator = DoAutoTurretObject ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_TORNADO :
if ( SW_SHAREWARE ) break ;
sop - > vel = 120 ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_DYNAMIC ) ;
2015-05-19 21:54:34 +00:00
sop - > scale_type = SO_SCALE_CYCLE ;
// spin stuff
sop - > spin_speed = 16 ;
sop - > last_ang = sop - > ang ;
// animators
sop - > Animator = DoTornadoObject ;
sop - > PreMoveAnimator = ScaleSectorObject ;
sop - > PostMoveAnimator = MorphTornado ;
// clip
sop - > clipdist = 2500 ;
// morph point
sop - > morph_speed = 16 ;
sop - > morph_z_speed = 6 ;
sop - > morph_dist_max = 1024 ;
sop - > morph_rand_freq = 8 ;
sop - > scale_dist_min = - 768 ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_FLOOR_MORPH :
if ( SW_SHAREWARE ) break ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_DYNAMIC ) ;
2015-05-19 21:54:34 +00:00
sop - > scale_type = SO_SCALE_NONE ;
sop - > morph_speed = 120 ;
sop - > morph_z_speed = 7 ;
sop - > PostMoveAnimator = MorphFloor ;
sop - > morph_dist_max = 4000 ;
sop - > morph_rand_freq = 8 ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_AMOEBA :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_DYNAMIC ) ;
2015-05-19 21:54:34 +00:00
//sop->scale_type = SO_SCALE_CYCLE;
sop - > scale_type = SO_SCALE_RANDOM_POINT ;
sop - > PreMoveAnimator = ScaleSectorObject ;
memset ( sop - > scale_point_dist , 0 , sizeof ( sop - > scale_point_dist ) ) ; ;
sop - > scale_point_base_speed = SCALE_POINT_SPEED ;
for ( j = 0 ; j < ( int ) SIZ ( sop - > scale_point_speed ) ; j + + )
sop - > scale_point_speed [ j ] = SCALE_POINT_SPEED ;
sop - > scale_point_dist_min = - 256 ;
sop - > scale_point_dist_max = 256 ;
sop - > scale_point_rand_freq = 32 ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_MAX_DAMAGE :
2021-12-26 00:22:41 +00:00
actorNew - > user . MaxHealth = SP_TAG2 ( actor ) ;
2021-12-25 00:20:36 +00:00
if ( SP_TAG5 ( actor ) ! = 0 )
sop - > max_damage = SP_TAG5 ( actor ) ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:22:41 +00:00
sop - > max_damage = actorNew - > user . MaxHealth ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:25:07 +00:00
switch ( actor - > spr . clipdist )
2015-05-19 21:54:34 +00:00
{
case 0 :
break ;
case 1 :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_DIE_HARD ) ;
2015-05-19 21:54:34 +00:00
break ;
}
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_DRIVABLE_ATTRIB :
2021-12-24 13:12:21 +00:00
sop - > drive_angspeed = SP_TAG2 ( actor ) ;
2020-09-08 10:48:01 +00:00
sop - > drive_angspeed < < = 5 ;
2021-12-25 00:02:25 +00:00
sop - > drive_angslide = SP_TAG3 ( actor ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > drive_angslide < = 0 | | sop - > drive_angslide = = 32 )
sop - > drive_angslide = 1 ;
2021-12-25 00:02:25 +00:00
sop - > drive_speed = SP_TAG6 ( actor ) ;
2015-05-19 21:54:34 +00:00
sop - > drive_speed < < = 5 ;
2021-12-25 00:02:25 +00:00
sop - > drive_slide = SP_TAG7 ( actor ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > drive_slide < = 0 )
sop - > drive_slide = 1 ;
2021-12-25 00:02:25 +00:00
if ( TEST_BOOL1 ( actor ) )
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_NO_QUAKE ) ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:02:25 +00:00
if ( TEST_BOOL3 ( actor ) )
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_REMOTE_ONLY ) ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:02:25 +00:00
if ( TEST_BOOL4 ( actor ) )
2015-05-19 21:54:34 +00:00
{
2022-02-01 23:08:21 +00:00
sop - > crush_z = actor - > int_pos ( ) . Z ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_RECT_CLIP ) ;
2015-05-19 21:54:34 +00:00
}
2021-10-30 20:53:24 +00:00
//KillActor(actor);
2015-05-19 21:54:34 +00:00
break ;
case SO_RAM_DAMAGE :
2021-12-25 00:25:07 +00:00
sop - > ram_damage = actor - > spr . lotag ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SECT_SO_CLIP_DIST :
2021-12-25 00:25:07 +00:00
sop - > clipdist = actor - > spr . lotag ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SECT_SO_SPRITE_OBJ :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_SPRITE_OBJ ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SECT_SO_DONT_ROTATE :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_DONT_ROTATE ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_LIMIT_TURN :
2022-08-28 03:15:31 +00:00
sop - > limit_ang_center = actor - > spr . angle ;
2022-08-27 06:04:55 +00:00
sop - > limit_ang_delta = DAngle : : fromBuild ( actor - > spr . lotag ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_MATCH_EVENT :
2021-12-25 00:25:07 +00:00
sop - > match_event = actor - > spr . lotag ;
2021-11-02 17:52:59 +00:00
sop - > match_event_actor = actor ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SET_SPEED :
2021-12-25 00:25:07 +00:00
sop - > vel = actor - > spr . lotag * 256 ;
2015-05-19 21:54:34 +00:00
sop - > vel_tgt = sop - > vel ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SPIN :
if ( sop - > spin_speed )
break ;
2021-12-25 00:25:07 +00:00
sop - > spin_speed = actor - > spr . lotag ;
2015-05-19 21:54:34 +00:00
sop - > last_ang = sop - > ang ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_ANGLE :
2022-08-16 21:17:01 +00:00
sop - > ang = sop - > ang_moving = actor - > int_ang ( ) ;
2015-05-19 21:54:34 +00:00
sop - > last_ang = sop - > ang_orig = sop - > ang ;
sop - > spin_ang = 0 ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SPIN_REVERSE :
2021-12-25 00:25:07 +00:00
sop - > spin_speed = actor - > spr . lotag ;
2015-05-19 21:54:34 +00:00
sop - > last_ang = sop - > ang ;
if ( sop - > spin_speed > = 0 )
sop - > spin_speed = - sop - > spin_speed ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_BOB_START :
2021-12-25 00:25:07 +00:00
sop - > bob_amt = Z ( actor - > spr . lotag ) ;
2015-05-19 21:54:34 +00:00
sop - > bob_sine_ndx = 0 ;
sop - > bob_speed = 4 ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_TURN_SPEED :
2021-12-25 00:25:07 +00:00
sop - > turn_speed = actor - > spr . lotag ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SYNC1 :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_SYNC1 ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SYNC2 :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_SYNC2 ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_KILLABLE :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_KILLABLE ) ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
}
}
}
if ( sop - > vel = = - 1 )
sop - > vel = sop - > vel_tgt = 8 * 256 ;
SectorObjectSetupBounds ( sop ) ;
if ( sop - > track > = SO_OPERATE_TRACK_START )
{
switch ( sop - > track )
{
case SO_TURRET_MGUN :
case SO_TURRET :
2020-09-08 11:54:48 +00:00
case SO_VEHICLE :
2015-05-19 21:54:34 +00:00
sop - > vel = 0 ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_OPERATIONAL ) ;
2015-05-19 21:54:34 +00:00
break ;
2020-09-08 11:40:20 +00:00
#if 0
2015-05-19 21:54:34 +00:00
case SO_SPEED_BOAT :
sop - > vel = 0 ;
sop - > bob_amt = Z ( 2 ) ;
sop - > bob_speed = 4 ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_OPERATIONAL ) ;
2015-05-19 21:54:34 +00:00
break ;
2020-09-08 11:40:20 +00:00
# endif
2015-05-19 21:54:34 +00:00
default :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_OPERATIONAL ) ;
2015-05-19 21:54:34 +00:00
break ;
}
}
2021-11-24 21:39:01 +00:00
sectp - > lotag = 0 ;
sectp - > hitag = 0 ;
2015-05-19 21:54:34 +00:00
if ( sop - > max_damage < = 0 )
VehicleSetSmoke ( sop , SpawnVehicleSmoke ) ;
break ;
}
}
2021-11-05 23:37:16 +00:00
void PostSetupSectorObject ( void )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * sop ;
2015-05-19 21:54:34 +00:00
for ( sop = SectorObject ; sop < & SectorObject [ MAX_SECTOR_OBJECTS ] ; sop + + )
{
2020-05-22 12:11:03 +00:00
if ( SO_EMPTY ( sop ) )
2015-05-19 21:54:34 +00:00
continue ;
FindMainSector ( sop ) ;
}
}
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * PlayerOnObject ( sectortype * match )
2015-05-19 21:54:34 +00:00
{
short i , j ;
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * sop ;
2015-05-19 21:54:34 +00:00
// place each sector object on the track
2020-05-22 12:11:03 +00:00
//for (i = 0; !SO_EMPTY(&SectorObject[i]) && (i < MAX_SECTOR_OBJECTS); i++)
2015-05-19 21:54:34 +00:00
for ( i = 0 ; ( i < MAX_SECTOR_OBJECTS ) ; i + + )
{
sop = & SectorObject [ i ] ;
if ( sop - > track < SO_OPERATE_TRACK_START )
continue ;
for ( j = 0 ; j < sop - > num_sectors ; j + + )
{
2021-12-29 05:53:36 +00:00
if ( sop - > sectp [ j ] = = match & & ( match - > extra & SECTFX_OPERATIONAL ) )
2015-05-19 21:54:34 +00:00
{
return sop ;
}
}
}
2021-07-10 12:25:18 +00:00
return nullptr ;
2015-05-19 21:54:34 +00:00
}
2021-11-05 23:37:16 +00:00
void PlaceSectorObjectsOnTracks ( void )
2015-05-19 21:54:34 +00:00
{
short i , j , k , startwall , endwall ;
2020-09-09 18:32:24 +00:00
bool found ;
2015-05-19 21:54:34 +00:00
// place each sector object on the track
for ( i = 0 ; i < MAX_SECTOR_OBJECTS ; i + + )
{
2022-08-21 20:51:03 +00:00
double low_dist = 999999 , dist ;
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * sop = & SectorObject [ i ] ;
2021-12-31 14:13:05 +00:00
TRACK_POINT * tpoint = nullptr ;
2015-05-19 21:54:34 +00:00
2020-05-22 12:11:03 +00:00
if ( SO_EMPTY ( sop ) )
2015-05-19 21:54:34 +00:00
continue ;
// save off the original x and y locations of the walls AND sprites
sop - > num_walls = 0 ;
2021-11-24 22:01:43 +00:00
for ( j = 0 ; sop - > sectp [ j ] ! = nullptr ; j + + )
2015-05-19 21:54:34 +00:00
{
// move all walls in sectors
2021-11-24 22:01:43 +00:00
for ( auto & wal : wallsofsector ( sop - > sectp [ j ] ) )
2015-05-19 21:54:34 +00:00
{
2022-08-18 16:27:31 +00:00
sop - > xorig [ sop - > num_walls ] = sop - > int_pmid ( ) . X - wal . wall_int_pos ( ) . X ;
sop - > yorig [ sop - > num_walls ] = sop - > int_pmid ( ) . Y - wal . wall_int_pos ( ) . Y ;
2015-05-19 21:54:34 +00:00
sop - > num_walls + + ;
}
}
2019-12-03 09:44:56 +00:00
ASSERT ( ( uint16_t ) sop - > num_walls < SIZ ( sop - > xorig ) ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > track < = - 1 )
continue ;
if ( sop - > track > = SO_OPERATE_TRACK_START )
continue ;
2020-09-09 17:52:52 +00:00
found = false ;
2015-05-19 21:54:34 +00:00
// find the closest point on the track and put SOBJ on it
for ( j = 0 ; j < Track [ sop - > track ] . NumPoints ; j + + )
{
tpoint = Track [ sop - > track ] . TrackPoint ;
2022-08-21 20:51:03 +00:00
dist = ( ( tpoint + j ) - > pos - sop - > pmid ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
if ( dist < low_dist )
{
low_dist = dist ;
sop - > point = j ;
2020-09-09 17:52:52 +00:00
found = true ;
2015-05-19 21:54:34 +00:00
}
}
if ( ! found )
{
sop - > track = - 1 ;
continue ;
}
NextTrackPoint ( sop ) ;
2022-08-21 20:51:03 +00:00
sop - > ang = getangle ( ( tpoint + sop - > point ) - > pos - sop - > pmid ) ;
2015-05-19 21:54:34 +00:00
sop - > ang_moving = sop - > ang_tgt = sop - > ang ;
}
}
2021-11-05 23:37:16 +00:00
void PlaceActorsOnTracks ( void )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
short j , tag ;
2021-12-31 14:13:05 +00:00
TRACK_POINT * tpoint = nullptr ;
2015-05-19 21:54:34 +00:00
// place each actor on the track
2021-11-05 23:37:16 +00:00
SWStatIterator it ( STAT_ENEMY ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2022-08-21 20:51:03 +00:00
double low_dist = 999999 , dist ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:25:07 +00:00
tag = actor - > spr . lotag ;
2015-05-19 21:54:34 +00:00
if ( tag < TAG_ACTOR_TRACK_BEGIN | | tag > TAG_ACTOR_TRACK_END )
continue ;
// setup sprite track defaults
2021-12-26 00:30:29 +00:00
actor - > user . track = tag - TAG_ACTOR_TRACK_BEGIN ;
2015-05-19 21:54:34 +00:00
// if facing left go backward
2022-08-16 21:25:11 +00:00
if ( actor - > int_ang ( ) > = 513 & & actor - > int_ang ( ) < = 1535 )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . track_dir = - 1 ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-26 00:30:29 +00:00
actor - > user . track_dir = 1 ;
2015-05-19 21:54:34 +00:00
}
2021-12-26 00:30:29 +00:00
actor - > user . track_vel = actor - > spr . xvel * 256 ;
actor - > user . vel_tgt = actor - > user . track_vel ;
actor - > user . vel_rate = 6 ;
2015-05-19 21:54:34 +00:00
// find the closest point on the track and put SOBJ on it
2021-12-26 00:30:29 +00:00
for ( j = 0 ; j < Track [ actor - > user . track ] . NumPoints ; j + + )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
tpoint = Track [ actor - > user . track ] . TrackPoint ;
2015-05-19 21:54:34 +00:00
2022-08-21 20:51:03 +00:00
dist = ( ( tpoint + j ) - > pos - actor - > spr . pos ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
if ( dist < low_dist )
{
low_dist = dist ;
2021-12-26 00:30:29 +00:00
actor - > user . point = j ;
2015-05-19 21:54:34 +00:00
}
}
2021-11-05 23:37:16 +00:00
NextActorTrackPoint ( actor ) ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
if ( Track [ actor - > user . track ] . NumPoints = = 0 )
2019-12-22 10:21:22 +00:00
{
2022-08-21 20:51:03 +00:00
Printf ( " WARNING: Sprite %d (%2.2f, %2.2f) placed on track %d with no points! \n " , actor - > GetIndex ( ) , actor - > spr . pos . X , actor - > spr . pos . Y , actor - > user . track ) ;
2019-12-22 10:21:22 +00:00
continue ;
}
2015-05-19 21:54:34 +00:00
// check angle in the "forward" direction
2022-08-21 20:51:03 +00:00
actor - > spr . angle = VecToAngle ( ( tpoint + actor - > user . point ) - > pos - actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-12-31 14:59:11 +00:00
void MovePlayer ( PLAYER * pp , SECTOR_OBJECT * sop , int nx , int ny )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:59:11 +00:00
void DoPlayerZrange ( PLAYER * pp ) ;
2015-05-19 21:54:34 +00:00
// make sure your standing on the so
2021-12-27 18:34:06 +00:00
if ( pp - > Flags & ( PF_JUMPING | PF_FALLING | PF_FLYING ) )
2015-05-19 21:54:34 +00:00
return ;
pp - > sop_riding = sop ;
// if player has NOT moved and player is NOT riding
// set up the player for riding
2021-12-29 05:13:28 +00:00
if ( ! ( pp - > Flags & PF_PLAYER_MOVED ) & & ! ( pp - > Flags & PF_PLAYER_RIDING ) )
2015-05-19 21:54:34 +00:00
{
2021-12-27 16:22:41 +00:00
pp - > Flags | = ( PF_PLAYER_RIDING ) ;
2015-05-19 21:54:34 +00:00
2022-08-27 13:09:22 +00:00
pp - > RevolveAng = pp - > angle . ang ;
2022-08-20 10:11:15 +00:00
pp - > Revolve . X = pp - > int_ppos ( ) . X ;
pp - > Revolve . Y = pp - > int_ppos ( ) . Y ;
2015-05-19 21:54:34 +00:00
// set the delta angle to 0 when moving
2022-08-28 00:40:50 +00:00
pp - > RevolveDeltaAng = nullAngle ;
2015-05-19 21:54:34 +00:00
}
2022-08-20 10:57:02 +00:00
pp - > add_int_ppos_XY ( { nx , ny } ) ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_DONT_ROTATE ) )
2015-05-19 21:54:34 +00:00
{
UpdatePlayerSprite ( pp ) ;
return ;
}
2021-12-27 18:34:06 +00:00
if ( pp - > Flags & ( PF_PLAYER_MOVED ) )
2015-05-19 21:54:34 +00:00
{
// Player is moving
// save the current information so when Player stops
// moving then you
// know where he was last
2022-08-27 13:09:22 +00:00
pp - > RevolveAng = pp - > angle . ang ;
2022-08-20 10:11:15 +00:00
pp - > Revolve . X = pp - > int_ppos ( ) . X ;
pp - > Revolve . Y = pp - > int_ppos ( ) . Y ;
2015-05-19 21:54:34 +00:00
// set the delta angle to 0 when moving
2022-08-28 00:40:50 +00:00
pp - > RevolveDeltaAng = nullAngle ;
2015-05-19 21:54:34 +00:00
}
else
{
// Player is NOT moving
// Move saved x&y variables
2021-12-30 06:42:34 +00:00
pp - > Revolve . X + = nx ;
2021-12-30 06:37:47 +00:00
pp - > Revolve . Y + = ny ;
2015-05-19 21:54:34 +00:00
// Last known angle is now adjusted by the delta angle
2022-08-27 13:09:22 +00:00
pp - > RevolveAng = deltaangle ( pp - > RevolveDeltaAng , pp - > angle . ang ) ;
2015-05-19 21:54:34 +00:00
}
// increment Players delta angle
2022-08-29 06:58:06 +00:00
pp - > RevolveDeltaAng + = GlobSpeedSO ;
2015-05-19 21:54:34 +00:00
2022-08-20 11:38:48 +00:00
pp - > pos . XY ( ) = rotatepoint ( sop - > pmid . XY ( ) , { pp - > Revolve . X * inttoworld , pp - > Revolve . Y * inttoworld } , pp - > RevolveDeltaAng ) ;
2015-05-19 21:54:34 +00:00
// THIS WAS CAUSING PROLEMS!!!!
// Sectors are still being manipulated so you can end up in a void (-1) sector
// New angle is formed by taking last known angle and
// adjusting by the delta angle
2022-08-27 13:09:22 +00:00
pp - > angle . addadjustment ( deltaangle ( pp - > RevolveAng + pp - > RevolveDeltaAng , pp - > angle . ang ) ) ;
2020-04-15 11:45:19 +00:00
2015-05-19 21:54:34 +00:00
UpdatePlayerSprite ( pp ) ;
}
2021-12-31 14:50:44 +00:00
void MovePoints ( SECTOR_OBJECT * sop , short delta_ang , int nx , int ny )
2015-05-19 21:54:34 +00:00
{
2022-08-20 08:26:39 +00:00
auto deltaangle = DAngle : : fromBuild ( delta_ang ) ;
2021-11-24 21:04:11 +00:00
int j ;
2016-05-23 04:46:30 +00:00
vec2_t rxy ;
2021-11-24 21:04:11 +00:00
int pnum ;
2021-12-31 14:59:11 +00:00
PLAYER * pp ;
2022-02-01 18:41:58 +00:00
sectortype * * sectp ;
2021-11-24 21:04:11 +00:00
int i , rot_ang ;
2020-09-09 18:32:24 +00:00
bool PlayerMove = true ;
2015-05-19 21:54:34 +00:00
2022-08-18 17:14:50 +00:00
if ( SO_EMPTY ( sop ) )
2020-09-09 17:52:52 +00:00
PlayerMove = false ;
2015-05-19 21:54:34 +00:00
// move along little midpoint
2022-08-18 17:14:50 +00:00
sop - > pmid . X + = nx * inttoworld ;
sop - > pmid . Y + = ny * inttoworld ;
2015-05-19 21:54:34 +00:00
2022-08-18 17:14:50 +00:00
if ( SO_EMPTY ( sop ) )
2020-09-09 17:52:52 +00:00
PlayerMove = false ;
2015-05-19 21:54:34 +00:00
// move child sprite along also
2022-08-18 17:14:50 +00:00
sop - > sp_child - > spr . pos . XY ( ) = sop - > pmid . XY ( ) ;
2015-05-19 21:54:34 +00:00
2022-02-02 23:59:12 +00:00
// setting floor z if need be
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_ZMID_FLOOR ) )
2022-08-18 17:14:50 +00:00
sop - > pmid . Z = sop - > mid_sector - > floorz ;
2015-05-19 21:54:34 +00:00
2022-08-18 17:14:50 +00:00
DVector2 pivot = sop - > pmid . XY ( ) ;
2022-01-28 17:47:53 +00:00
DVector2 move = { nx * inttoworld , ny * inttoworld } ;
2015-05-19 21:54:34 +00:00
for ( sectp = sop - > sectp , j = 0 ; * sectp ; sectp + + , j + + )
{
2021-12-29 05:25:37 +00:00
if ( ( sop - > flags & ( SOBJ_SPRITE_OBJ | SOBJ_DONT_ROTATE ) ) )
2015-05-19 21:54:34 +00:00
goto PlayerPart ;
// move all walls in sectors
2021-11-24 21:04:11 +00:00
for ( auto & wal : wallsofsector ( * sectp ) )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:25:37 +00:00
if ( ( wal . extra & ( WALLFX_LOOP_DONT_SPIN | WALLFX_DONT_MOVE ) ) )
2015-05-19 21:54:34 +00:00
continue ;
2021-12-29 05:53:36 +00:00
if ( wal . extra & & ( wal . extra & WALLFX_LOOP_OUTER ) )
2015-05-19 21:54:34 +00:00
{
2022-01-27 19:40:44 +00:00
dragpoint ( & wal , wal . pos + move ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-01-27 19:40:44 +00:00
wal . move ( wal . pos + move ) ;
2015-05-19 21:54:34 +00:00
}
rot_ang = delta_ang ;
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_LOOP_REVERSE_SPIN ) )
2015-05-19 21:54:34 +00:00
rot_ang = - delta_ang ;
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_LOOP_SPIN_2X ) )
2015-05-19 21:54:34 +00:00
rot_ang = NORM_ANGLE ( rot_ang * 2 ) ;
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_LOOP_SPIN_4X ) )
2015-05-19 21:54:34 +00:00
rot_ang = NORM_ANGLE ( rot_ang * 4 ) ;
2022-08-27 08:53:34 +00:00
auto vec = rotatepoint ( pivot , wal . pos , DAngle : : fromBuild ( rot_ang ) ) ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( wal . extra & & ( wal . extra & WALLFX_LOOP_OUTER ) )
2015-05-19 21:54:34 +00:00
{
2022-01-27 19:40:44 +00:00
dragpoint ( & wal , vec ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-01-27 19:40:44 +00:00
wal . move ( vec ) ;
2015-05-19 21:54:34 +00:00
}
}
PlayerPart :
TRAVERSE_CONNECT ( pnum )
{
pp = Player + pnum ;
// if controlling a sector object
if ( pp - > sop )
continue ;
if ( ! pp - > lo_sectp )
continue ;
2021-12-29 05:53:36 +00:00
if ( ( pp - > lo_sectp - > extra & SECTFX_NO_RIDE ) )
2015-05-19 21:54:34 +00:00
{
continue ;
}
// move the player
2021-11-24 22:01:43 +00:00
if ( pp - > lo_sectp = = sop - > sectp [ j ] )
2015-05-19 21:54:34 +00:00
{
if ( PlayerMove )
MovePlayer ( pp , sop , nx , ny ) ;
}
}
}
2021-11-02 17:45:21 +00:00
for ( i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
{
2021-12-07 18:22:30 +00:00
DSWActor * actor = sop - > so_actors [ i ] ;
if ( ! actor ) continue ;
2015-05-19 21:54:34 +00:00
// if its a player sprite || NOT attached
2021-12-29 05:13:28 +00:00
if ( ! actor - > hasU ( ) | | actor - > user . PlayerP | | ! ( actor - > user . Flags & SPR_SO_ATTACHED ) )
2015-05-19 21:54:34 +00:00
continue ;
// move the player
TRAVERSE_CONNECT ( pnum )
{
pp = Player + pnum ;
2021-10-30 22:29:54 +00:00
if ( pp - > lowActor & & pp - > lowActor = = actor )
2015-05-19 21:54:34 +00:00
{
if ( PlayerMove )
MovePlayer ( pp , sop , nx , ny ) ;
}
}
2022-08-21 08:40:45 +00:00
actor - > spr . pos . XY ( ) = sop - > pmid . XY ( ) - actor - > user . pos . XY ( ) ;
2015-05-19 21:54:34 +00:00
// sprites z update
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_SPRITE_OBJ ) )
2015-05-19 21:54:34 +00:00
{
// Sprite Objects follow zmid
2022-08-21 08:40:45 +00:00
actor - > spr . pos . Z = sop - > pmid . Z - actor - > user . pos . Z ;
2015-05-19 21:54:34 +00:00
}
else
{
// Sector Objects can either have sprites ON or OFF of the sector
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_ON_SO_SECTOR ) )
2015-05-19 21:54:34 +00:00
{
// move with sector its on
2022-08-21 08:40:45 +00:00
actor - > spr . pos . Z = actor - > sector ( ) - > floorz - actor - > user . pos . Z ;
2015-05-19 21:54:34 +00:00
}
else
{
// move with the mid sector
2022-08-21 08:40:45 +00:00
actor - > spr . pos . Z = sop - > mid_sector - > floorz - actor - > user . pos . Z ;
2015-05-19 21:54:34 +00:00
}
}
2022-08-16 21:17:01 +00:00
int16_t oldang = actor - > int_ang ( ) ;
2022-08-16 21:23:42 +00:00
actor - > set_int_ang ( actor - > user . sang ) ;
2015-05-19 21:54:34 +00:00
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_ON_SO_SECTOR ) )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_DONT_ROTATE ) )
2015-05-19 21:54:34 +00:00
continue ;
2021-11-04 23:03:08 +00:00
// IS part of a sector, sprite can do things based on the
2015-05-19 21:54:34 +00:00
// current sector it is in
2021-12-30 15:51:56 +00:00
if ( ( actor - > sector ( ) - > firstWall ( ) - > extra & WALLFX_LOOP_DONT_SPIN ) )
2015-05-19 21:54:34 +00:00
continue ;
2021-12-30 15:51:56 +00:00
if ( ( actor - > sector ( ) - > firstWall ( ) - > extra & WALLFX_LOOP_REVERSE_SPIN ) )
2015-05-19 21:54:34 +00:00
{
2022-08-20 08:26:39 +00:00
actor - > spr . pos . XY ( ) = rotatepoint ( sop - > pmid . XY ( ) , actor - > spr . pos . XY ( ) , - deltaangle ) ;
actor - > spr . angle - = deltaangle ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-08-20 08:26:39 +00:00
actor - > spr . pos . XY ( ) = rotatepoint ( sop - > pmid . XY ( ) , actor - > spr . pos . XY ( ) , deltaangle ) ;
actor - > spr . angle + = deltaangle ;
2015-05-19 21:54:34 +00:00
}
2022-08-20 08:26:39 +00:00
actor - > norm_ang ( ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-29 05:13:28 +00:00
if ( ! ( sop - > flags & SOBJ_DONT_ROTATE ) )
2015-05-19 21:54:34 +00:00
{
// NOT part of a sector - independant of any sector
2022-08-20 08:26:39 +00:00
actor - > spr . pos . XY ( ) = rotatepoint ( sop - > pmid . XY ( ) , actor - > spr . pos . XY ( ) , deltaangle ) ;
actor - > spr . angle + = deltaangle ;
actor - > norm_ang ( ) ;
2015-05-19 21:54:34 +00:00
}
// Does not necessarily move with the sector so must accout for
// moving across sectors
2022-08-18 17:14:50 +00:00
if ( ! SO_EMPTY ( sop ) ) // special case for operating SO's
2022-08-22 16:34:43 +00:00
SetActorZ ( sop - > so_actors [ i ] , actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
}
2022-08-16 21:15:49 +00:00
actor - > user . oangdiff + = getincangle ( oldang , actor - > int_ang ( ) ) ;
2020-04-30 21:56:26 +00:00
2021-12-29 05:53:36 +00:00
if ( ( actor - > spr . extra & SPRX_BLADE ) )
2015-05-19 21:54:34 +00:00
{
2021-11-04 20:26:08 +00:00
DoBladeDamage ( sop - > so_actors [ i ] ) ;
2015-05-19 21:54:34 +00:00
}
}
TRAVERSE_CONNECT ( pnum )
{
pp = Player + pnum ;
// if player was on a sector object
if ( pp - > sop_riding )
{
// update here AFTER sectors/player has been manipulated
// prevents you from falling into map HOLEs created by moving
// Sectors and sprites around.
2022-08-18 17:14:50 +00:00
//if (!SO_EMPTY(sop))
2022-08-20 10:11:15 +00:00
updatesector ( pp - > int_ppos ( ) . X , pp - > int_ppos ( ) . Y , & pp - > cursector ) ;
2015-05-19 21:54:34 +00:00
// in case you are in a whirlpool
// move perfectly with the ride in the z direction
2021-12-29 05:53:36 +00:00
if ( pp - > Flags & PF_CRAWLING )
2015-05-19 21:54:34 +00:00
{
// move up some for really fast moving plats
DoPlayerZrange ( pp ) ;
2022-08-21 12:42:28 +00:00
pp - > pos . Z = pp - > loz - PLAYER_CRAWL_HEIGHTF ;
pp - > actor - > spr . pos . Z = pp - > loz ;
2015-05-19 21:54:34 +00:00
}
else
{
// move up some for really fast moving plats
DoPlayerZrange ( pp ) ;
2021-12-29 05:18:25 +00:00
if ( ! ( pp - > Flags & ( PF_JUMPING | PF_FALLING | PF_FLYING ) ) )
2015-05-19 21:54:34 +00:00
{
2022-08-21 12:42:28 +00:00
pp - > pos . Z = pp - > loz - PLAYER_HEIGHTF ;
pp - > actor - > spr . pos . Z = pp - > loz ;
2015-05-19 21:54:34 +00:00
}
}
}
else
{
// if player was not on any sector object set Riding flag to false
2021-12-27 17:58:15 +00:00
pp - > Flags & = ~ ( PF_PLAYER_RIDING ) ;
2015-05-19 21:54:34 +00:00
}
}
}
2021-12-31 14:50:44 +00:00
void RefreshPoints ( SECTOR_OBJECT * sop , int nx , int ny , bool dynamic )
2015-05-19 21:54:34 +00:00
{
2021-11-24 21:04:11 +00:00
short wallcount = 0 , delta_ang_from_orig ;
2015-05-19 21:54:34 +00:00
short ang ;
int dx , dy , x , y ;
// do scaling
if ( dynamic & & sop - > PreMoveAnimator )
( * sop - > PreMoveAnimator ) ( sop ) ;
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2021-11-24 21:04:11 +00:00
int j ;
2015-05-19 21:54:34 +00:00
for ( sectp = sop - > sectp , j = 0 ; * sectp ; sectp + + , j + + )
{
2021-12-29 05:13:28 +00:00
if ( ! ( sop - > flags & SOBJ_SPRITE_OBJ ) )
2015-05-19 21:54:34 +00:00
{
// move all walls in sectors back to the original position
2021-11-24 21:04:11 +00:00
for ( auto & wal : wallsofsector ( * sectp ) )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:53:36 +00:00
if ( ! ( wal . extra & & ( wal . extra & WALLFX_DONT_MOVE ) ) )
2015-05-19 21:54:34 +00:00
{
2022-08-18 16:27:31 +00:00
dx = x = sop - > int_pmid ( ) . X - sop - > xorig [ wallcount ] ;
dy = y = sop - > int_pmid ( ) . Y - sop - > yorig [ wallcount ] ;
2015-05-19 21:54:34 +00:00
if ( dynamic & & sop - > scale_type )
{
2021-12-29 05:13:28 +00:00
if ( ! ( wal . extra & WALLFX_DONT_SCALE ) )
2015-05-19 21:54:34 +00:00
{
2022-08-18 16:27:31 +00:00
ang = NORM_ANGLE ( getangle ( x - sop - > int_pmid ( ) . X , y - sop - > int_pmid ( ) . Y ) ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > scale_type = = SO_SCALE_RANDOM_POINT )
{
// was causing memory overwrites
//ScaleRandomPoint(sop, k, ang, x, y, &dx, &dy);
ScaleRandomPoint ( sop , wallcount , ang , x , y , & dx , & dy ) ;
}
else
{
int xmul = ( sop - > scale_dist * sop - > scale_x_mult ) > > 8 ;
int ymul = ( sop - > scale_dist * sop - > scale_y_mult ) > > 8 ;
2021-01-04 11:36:54 +00:00
dx = x + MulScale ( xmul , bcos ( ang ) , 14 ) ;
dy = y + MulScale ( ymul , bsin ( ang ) , 14 ) ;
2015-05-19 21:54:34 +00:00
}
}
}
2022-08-20 08:03:21 +00:00
if ( wal . extra & WALLFX_LOOP_OUTER )
2015-05-19 21:54:34 +00:00
{
2021-11-24 21:04:11 +00:00
dragpoint ( & wal , dx , dy ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-01-27 19:40:44 +00:00
wal . movexy ( dx , dy ) ;
2015-05-19 21:54:34 +00:00
}
}
wallcount + + ;
}
}
}
if ( sop - > spin_speed )
{
// same as below - ignore the objects angle
// last_ang is the last true angle before SO started spinning
delta_ang_from_orig = NORM_ANGLE ( sop - > last_ang + sop - > spin_ang - sop - > ang_orig ) ;
}
else
{
// angle traveling + the new spin angle all offset from the original
// angle
delta_ang_from_orig = NORM_ANGLE ( sop - > ang + sop - > spin_ang - sop - > ang_orig ) ;
}
// Note that this delta angle is from the original angle
// nx,ny are 0 so the points are not moved, just rotated
MovePoints ( sop , delta_ang_from_orig , nx , ny ) ;
// do morphing - angle independent
if ( dynamic & & sop - > PostMoveAnimator )
( * sop - > PostMoveAnimator ) ( sop ) ;
}
2021-12-31 14:50:44 +00:00
void KillSectorObjectSprites ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
int i ;
2021-11-02 17:45:21 +00:00
for ( i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
2015-05-19 21:54:34 +00:00
{
2021-12-07 18:22:30 +00:00
DSWActor * actor = sop - > so_actors [ i ] ;
if ( ! actor ) continue ;
2021-12-30 09:30:21 +00:00
2015-05-19 21:54:34 +00:00
// not a part of the so anymore
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_SO_ATTACHED ) ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:25:07 +00:00
if ( actor - > spr . picnum = = ST1 & & actor - > spr . hitag = = SPAWN_SPOT )
2015-05-19 21:54:34 +00:00
continue ;
2021-11-02 17:42:25 +00:00
so_stopspriteinterpolation ( sop , actor ) ;
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
}
// clear the list
2021-11-02 17:45:21 +00:00
sop - > so_actors [ 0 ] = nullptr ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:50:44 +00:00
void UpdateSectorObjectSprites ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
int i ;
2021-11-02 17:45:21 +00:00
for ( i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
{
2021-12-07 18:22:30 +00:00
DSWActor * actor = sop - > so_actors [ i ] ;
if ( ! actor ) continue ;
2015-05-19 21:54:34 +00:00
2022-08-22 16:34:43 +00:00
SetActorZ ( actor , actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * DetectSectorObject ( sectortype * sectph )
2015-05-19 21:54:34 +00:00
{
short j ;
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * sop ;
2015-05-19 21:54:34 +00:00
// collapse the SO to a single point
// move all points to nx,ny
for ( sop = SectorObject ; sop < & SectorObject [ MAX_SECTOR_OBJECTS ] ; sop + + )
{
2020-05-22 12:11:03 +00:00
if ( SO_EMPTY ( sop ) )
2015-05-19 21:54:34 +00:00
continue ;
for ( sectp = sop - > sectp , j = 0 ; * sectp ; sectp + + , j + + )
{
if ( sectph = = * sectp )
return sop ;
}
}
2021-07-10 12:25:18 +00:00
return nullptr ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * DetectSectorObjectByWall ( walltype * wph )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * sop ;
2015-05-19 21:54:34 +00:00
// collapse the SO to a single point
// move all points to nx,ny
for ( sop = SectorObject ; sop < & SectorObject [ MAX_SECTOR_OBJECTS ] ; sop + + )
{
2020-05-22 12:11:03 +00:00
if ( SO_EMPTY ( sop ) )
2015-05-19 21:54:34 +00:00
continue ;
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2021-11-24 21:04:11 +00:00
int j ;
2015-05-19 21:54:34 +00:00
for ( sectp = sop - > sectp , j = 0 ; * sectp ; sectp + + , j + + )
{
2021-11-24 21:04:11 +00:00
for ( auto & wal : wallsofsector ( * sectp ) )
2015-05-19 21:54:34 +00:00
{
// if outer wall check the NEXTWALL also
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_LOOP_OUTER ) )
2015-05-19 21:54:34 +00:00
{
2021-11-24 21:04:11 +00:00
if ( wal . twoSided ( ) & & wph = = wal . nextWall ( ) )
2015-05-19 21:54:34 +00:00
return sop ;
}
2021-11-24 21:04:11 +00:00
if ( wph = = & wal )
2015-05-19 21:54:34 +00:00
return sop ;
}
}
}
2021-07-10 12:25:18 +00:00
return nullptr ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:50:44 +00:00
void CollapseSectorObject ( SECTOR_OBJECT * sop , int nx , int ny )
2015-05-19 21:54:34 +00:00
{
2021-11-24 21:04:11 +00:00
int j ;
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2015-05-19 21:54:34 +00:00
// collapse the SO to a single point
// move all points to nx,ny
for ( sectp = sop - > sectp , j = 0 ; * sectp ; sectp + + , j + + )
{
2021-12-29 05:13:28 +00:00
if ( ! ( sop - > flags & SOBJ_SPRITE_OBJ ) )
2015-05-19 21:54:34 +00:00
{
// move all walls in sectors back to the original position
2021-11-24 21:04:11 +00:00
for ( auto & wal : wallsofsector ( * sectp ) )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_DONT_MOVE ) )
2015-05-19 21:54:34 +00:00
continue ;
2021-12-29 05:53:36 +00:00
if ( wal . extra & & ( wal . extra & WALLFX_LOOP_OUTER ) )
2015-05-19 21:54:34 +00:00
{
2021-11-24 21:04:11 +00:00
dragpoint ( & wal , nx , ny ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-01-27 19:40:44 +00:00
wal . movexy ( nx , ny ) ;
2015-05-19 21:54:34 +00:00
}
}
}
}
}
2021-12-31 14:50:44 +00:00
void MoveZ ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
short i ;
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2015-05-19 21:54:34 +00:00
if ( sop - > bob_amt )
{
2020-09-02 18:56:09 +00:00
sop - > bob_sine_ndx = ( PlayClock < < sop - > bob_speed ) & 2047 ;
2021-01-04 11:36:54 +00:00
sop - > bob_diff = MulScale ( sop - > bob_amt , bsin ( sop - > bob_sine_ndx ) , 14 ) ;
2015-05-19 21:54:34 +00:00
// for all sectors
for ( i = 0 , sectp = & sop - > sectp [ 0 ] ; * sectp ; sectp + + , i + + )
{
2021-12-29 05:53:36 +00:00
if ( sop - > sectp [ i ] - > hasU ( ) & & ( sop - > sectp [ i ] - > flags & SECTFU_SO_DONT_BOB ) )
2015-05-19 21:54:34 +00:00
continue ;
2022-02-02 23:35:12 +00:00
( * sectp ) - > set_int_floorz ( sop - > zorig_floor [ i ] + sop - > bob_diff ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_MOVE_VERTICAL ) )
2015-05-19 21:54:34 +00:00
{
2021-11-02 17:39:27 +00:00
i = AnimGetGoal ( ANIM_SopZ , int ( sop - SectorObject ) , nullptr ) ;
2015-05-19 21:54:34 +00:00
if ( i < 0 )
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_MOVE_VERTICAL ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_ZDIFF_MODE ) )
2015-05-19 21:54:34 +00:00
{
return ;
}
// move all floors
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_ZDOWN ) )
2015-05-19 21:54:34 +00:00
{
for ( i = 0 , sectp = & sop - > sectp [ 0 ] ; * sectp ; sectp + + , i + + )
{
2022-08-21 14:42:38 +00:00
AnimSet ( ANIM_Floorz , * sectp , ( sop - > zorig_floor [ i ] + sop - > z_tgt ) * zinttoworld , sop - > z_rate ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_ZDOWN ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-29 05:53:36 +00:00
else if ( ( sop - > flags & SOBJ_ZUP ) )
2015-05-19 21:54:34 +00:00
{
for ( i = 0 , sectp = & sop - > sectp [ 0 ] ; * sectp ; sectp + + , i + + )
{
2022-08-21 14:42:38 +00:00
AnimSet ( ANIM_Floorz , * sectp , ( sop - > zorig_floor [ i ] + sop - > z_tgt ) * zinttoworld , sop - > z_rate ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_ZUP ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-12-31 14:49:07 +00:00
void CallbackSOsink ( ANIM * ap , void * data )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:50:44 +00:00
SECTOR_OBJECT * sop ;
2021-11-16 17:53:40 +00:00
int i , ndx ;
bool found = false ;
2015-05-19 21:54:34 +00:00
int tgt_depth ;
2021-11-24 22:01:43 +00:00
sectortype * srcsect = nullptr ;
sectortype * destsect = nullptr ;
2015-05-19 21:54:34 +00:00
2021-12-31 14:50:44 +00:00
sop = ( SECTOR_OBJECT * ) data ;
2015-05-19 21:54:34 +00:00
2021-11-24 22:01:43 +00:00
for ( i = 0 ; sop - > sectp [ i ] ! = nullptr ; i + + )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:53:36 +00:00
if ( sop - > sectp [ i ] - > hasU ( ) & & ( sop - > sectp [ i ] - > flags & SECTFU_SO_SINK_DEST ) )
2015-05-19 21:54:34 +00:00
{
2021-11-24 22:01:43 +00:00
srcsect = sop - > sectp [ i ] ;
2015-05-19 21:54:34 +00:00
break ;
}
}
2021-11-24 22:01:43 +00:00
ASSERT ( srcsect ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
2021-11-24 22:01:43 +00:00
for ( i = 0 ; sop - > sectp [ i ] ! = nullptr ; i + + )
2015-05-19 21:54:34 +00:00
{
2021-11-24 22:01:43 +00:00
if ( ap - > animtype = = ANIM_Floorz & & ap - > animindex = = sectnum ( sop - > sectp [ i ] ) )
2015-05-19 21:54:34 +00:00
{
2021-11-24 22:01:43 +00:00
destsect = sop - > sectp [ i ] ;
2015-05-19 21:54:34 +00:00
break ;
}
}
2021-11-24 22:01:43 +00:00
ASSERT ( destsect ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
2021-11-24 21:04:11 +00:00
destsect - > floorpicnum = srcsect - > floorpicnum ;
destsect - > floorshade = srcsect - > floorshade ;
2015-05-19 21:54:34 +00:00
2021-12-27 18:07:39 +00:00
destsect - > floorstat & = ~ ( CSTAT_SECTOR_ALIGN ) ;
2021-12-20 17:17:04 +00:00
destsect - > u_defined = true ;
ASSERT ( srcsect - > hasU ( ) ) ;
2015-05-19 21:54:34 +00:00
2021-11-24 21:04:11 +00:00
tgt_depth = FixedToInt ( srcsect - > depth_fixed ) ;
2015-05-19 21:54:34 +00:00
2021-12-21 08:23:39 +00:00
for ( auto & sect : sector )
2015-05-19 21:54:34 +00:00
{
2021-11-24 22:01:43 +00:00
if ( & sect = = destsect )
2015-05-19 21:54:34 +00:00
{
2022-08-21 14:42:38 +00:00
ndx = AnimSet ( ANIM_SUdepth , destsect , IntToFixed ( tgt_depth ) , ap - > vel ) ;
2015-05-19 21:54:34 +00:00
AnimSetVelAdj ( ndx , ap - > vel_adj ) ;
2020-09-09 17:52:52 +00:00
found = true ;
2015-05-19 21:54:34 +00:00
break ;
}
}
ASSERT ( found ) ;
2021-11-24 22:01:43 +00:00
SWSectIterator it ( destsect ) ;
2021-11-02 17:39:27 +00:00
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:13:28 +00:00
if ( ! actor - > hasU ( ) | | actor - > user . PlayerP | | ! ( actor - > user . Flags & SPR_SO_ATTACHED ) )
2015-05-19 21:54:34 +00:00
continue ;
// move sprite WAY down in water
2022-08-21 14:42:38 +00:00
ndx = AnimSet ( ANIM_Userz , 0 , actor , - actor - > user . pos . Z - ActorSizeZ ( actor ) - 100 , ap - > vel / 256 ) ;
2015-05-19 21:54:34 +00:00
AnimSetVelAdj ( ndx , ap - > vel_adj ) ;
}
// Take out any blocking walls
2021-11-24 21:04:11 +00:00
for ( auto & wal : wallsofsector ( destsect ) )
2015-05-19 21:54:34 +00:00
{
2021-12-27 18:07:39 +00:00
wal . cstat & = ~ ( CSTAT_WALL_BLOCK ) ;
2015-05-19 21:54:34 +00:00
}
return ;
}
2021-12-31 14:50:44 +00:00
void MoveSectorObjects ( SECTOR_OBJECT * sop , short locktics )
2015-05-19 21:54:34 +00:00
{
2020-03-06 15:49:49 +00:00
int nx , ny ;
2015-05-19 21:54:34 +00:00
short speed ;
short delta_ang ;
2020-05-01 11:29:12 +00:00
so_setinterpolationtics ( sop , locktics ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > track > = SO_OPERATE_TRACK_START )
{
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_UPDATE_ONCE ) )
2015-05-19 21:54:34 +00:00
{
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_UPDATE_ONCE ) ;
2020-09-09 17:52:52 +00:00
RefreshPoints ( sop , 0 , 0 , false ) ;
2015-05-19 21:54:34 +00:00
}
return ;
}
nx = 0 ;
ny = 0 ;
// if pausing the return
if ( sop - > wait_tics )
{
sop - > wait_tics - = locktics ;
if ( sop - > wait_tics < = 0 )
sop - > wait_tics = 0 ;
return ;
}
delta_ang = 0 ;
if ( sop - > track > - 1 )
DoTrack ( sop , locktics , & nx , & ny ) ;
// get delta to target angle
2020-09-16 11:46:03 +00:00
delta_ang = getincangle ( sop - > ang , sop - > ang_tgt ) ;
2015-05-19 21:54:34 +00:00
sop - > ang = NORM_ANGLE ( sop - > ang + ( delta_ang > > sop - > turn_speed ) ) ;
delta_ang = delta_ang > > sop - > turn_speed ;
// move z values
MoveZ ( sop ) ;
// calculate the spin speed
speed = sop - > spin_speed * locktics ;
// spin_ang is incremented by the spin_speed
sop - > spin_ang = NORM_ANGLE ( sop - > spin_ang + speed ) ;
if ( sop - > spin_speed )
{
// ignore delta angle if spinning
2022-08-27 10:51:50 +00:00
GlobSpeedSO = DAngle : : fromBuild ( speed ) ;
2015-05-19 21:54:34 +00:00
}
else
{
// The actual delta from the last frame
2022-08-27 10:51:50 +00:00
GlobSpeedSO = DAngle : : fromBuild ( speed + delta_ang ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_DYNAMIC ) )
2015-05-19 21:54:34 +00:00
{
// trick tricks
2020-09-09 17:52:52 +00:00
RefreshPoints ( sop , nx , ny , true ) ;
2015-05-19 21:54:34 +00:00
}
else
{
// Update the points so there will be no warping
2021-12-29 05:25:37 +00:00
if ( ( sop - > flags & ( SOBJ_UPDATE | SOBJ_UPDATE_ONCE ) ) | |
2015-05-19 21:54:34 +00:00
sop - > vel | |
( sop - > ang ! = sop - > ang_tgt ) | |
2022-08-27 10:51:50 +00:00
GlobSpeedSO . Degrees ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_UPDATE_ONCE ) ;
2020-09-09 17:52:52 +00:00
RefreshPoints ( sop , nx , ny , false ) ;
2015-05-19 21:54:34 +00:00
}
}
}
2021-12-31 14:50:44 +00:00
void DoTrack ( SECTOR_OBJECT * sop , short locktics , int * nx , int * ny )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:13:05 +00:00
TRACK_POINT * tpoint ;
2015-05-19 21:54:34 +00:00
tpoint = Track [ sop - > track ] . TrackPoint + sop - > point ;
// calculate an angle to the target
if ( sop - > vel )
2022-08-21 20:51:03 +00:00
sop - > ang_moving = sop - > ang_tgt = getangle ( tpoint - > pos - sop - > pmid ) ;
2015-05-19 21:54:34 +00:00
// NOTE: Jittery ride - try new value out here
// NOTE: Put a loop around this (locktics) to make it more acuruate
2021-11-05 23:37:16 +00:00
const int TRACK_POINT_SIZE = 200 ;
2022-08-21 21:13:53 +00:00
if ( sop - > target_dist < 100 * maptoworld )
2015-05-19 21:54:34 +00:00
{
switch ( tpoint - > tag_low )
{
case TRACK_MATCH_EVERYTHING :
2021-07-10 12:25:18 +00:00
DoMatchEverything ( nullptr , tpoint - > tag_high , - 1 ) ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_MATCH_EVERYTHING_ONCE :
2021-07-10 12:25:18 +00:00
DoMatchEverything ( nullptr , tpoint - > tag_high , - 1 ) ;
2015-05-19 21:54:34 +00:00
tpoint - > tag_low = 0 ;
tpoint - > tag_high = 0 ;
break ;
case TRACK_SPIN :
if ( sop - > spin_speed )
break ;
sop - > spin_speed = tpoint - > tag_high ;
sop - > last_ang = sop - > ang ;
break ;
case TRACK_SPIN_REVERSE :
{
if ( ! sop - > spin_speed )
break ;
if ( sop - > spin_speed > = 0 )
{
sop - > spin_speed = - sop - > spin_speed ;
}
}
break ;
case TRACK_SPIN_STOP :
if ( ! sop - > spin_speed )
break ;
sop - > spin_speed = 0 ;
break ;
case TRACK_BOB_START :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZMID_FLOOR ) ;
2015-05-19 21:54:34 +00:00
sop - > bob_amt = Z ( tpoint - > tag_high ) ;
sop - > bob_sine_ndx = 0 ;
sop - > bob_speed = 4 ;
break ;
case TRACK_BOB_STOP :
sop - > bob_speed = 0 ;
sop - > bob_sine_ndx = 0 ;
sop - > bob_amt = 0 ;
break ;
case TRACK_BOB_SPEED :
sop - > bob_speed = tpoint - > tag_high ;
break ;
case TRACK_REVERSE :
sop - > dir * = - 1 ;
break ;
case TRACK_STOP :
sop - > vel = 0 ;
sop - > wait_tics = tpoint - > tag_high * 128 ;
break ;
case TRACK_SET_SPEED :
sop - > vel = tpoint - > tag_high * 256 ;
sop - > vel_tgt = sop - > vel ;
break ;
//
// Controls the velocity
//
case TRACK_VEL_RATE :
sop - > vel_rate = tpoint - > tag_high ;
break ;
case TRACK_SPEED_UP :
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_SLOW_DOWN | SOBJ_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > dir < 0 )
{
// set target to new slower target
sop - > vel_tgt = sop - > vel_tgt - ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_SLOW_DOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
sop - > vel_tgt = sop - > vel_tgt + ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_SLOW_DOWN :
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_SLOW_DOWN | SOBJ_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > dir > 0 )
{
sop - > vel_tgt = sop - > vel_tgt - ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_SLOW_DOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
sop - > vel_tgt = sop - > vel_tgt + ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
}
break ;
//
// Controls z
//
case TRACK_SO_SINK :
{
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2021-11-24 22:01:43 +00:00
sectortype * dest_sector = nullptr ;
2015-05-19 21:54:34 +00:00
short i , ndx ;
2021-11-24 22:01:43 +00:00
for ( i = 0 ; sop - > sectp [ i ] ! = nullptr ; i + + )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:53:36 +00:00
if ( sop - > sectp [ i ] - > hasU ( ) & & ( sop - > sectp [ i ] - > flags & SECTFU_SO_SINK_DEST ) )
2015-05-19 21:54:34 +00:00
{
2021-11-24 22:01:43 +00:00
dest_sector = sop - > sectp [ i ] ;
2015-05-19 21:54:34 +00:00
break ;
}
}
2021-11-24 22:01:43 +00:00
ASSERT ( dest_sector ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
sop - > bob_speed = 0 ;
sop - > bob_sine_ndx = 0 ;
sop - > bob_amt = 0 ;
for ( i = 0 , sectp = & sop - > sectp [ 0 ] ; * sectp ; sectp + + , i + + )
{
2021-12-29 05:53:36 +00:00
if ( sop - > sectp [ i ] - > hasU ( ) & & ( sop - > sectp [ i ] - > flags & SECTFU_SO_DONT_SINK ) )
2015-05-19 21:54:34 +00:00
continue ;
2022-08-21 14:42:38 +00:00
ndx = AnimSet ( ANIM_Floorz , * sectp , dest_sector - > floorz , tpoint - > tag_high ) ;
2015-05-19 21:54:34 +00:00
AnimSetCallback ( ndx , CallbackSOsink , sop ) ;
2022-08-21 14:42:38 +00:00
AnimSetVelAdj ( ndx , 6 * zmaptoworld ) ;
2015-05-19 21:54:34 +00:00
}
break ;
}
case TRACK_SO_FORM_WHIRLPOOL :
{
// for lowering the whirlpool in level 1
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2021-11-20 22:35:14 +00:00
int i ;
2021-12-30 09:30:21 +00:00
2015-05-19 21:54:34 +00:00
for ( i = 0 , sectp = & sop - > sectp [ 0 ] ; * sectp ; sectp + + , i + + )
{
2021-11-19 22:20:58 +00:00
if ( ( * sectp ) - > hasU ( ) )
2015-05-19 21:54:34 +00:00
{
2021-11-20 22:20:43 +00:00
if ( ( * sectp ) & & ( * sectp ) - > stag = = SECT_SO_FORM_WHIRLPOOL )
2021-11-19 22:20:58 +00:00
{
2022-08-21 14:42:38 +00:00
AnimSet ( ANIM_Floorz , * sectp , ( * sectp ) - > floorz + ( * sectp ) - > height , 128 ) ;
2021-11-20 22:20:43 +00:00
( * sectp ) - > floorshade + = ( * sectp ) - > height / 6 ;
2015-05-19 21:54:34 +00:00
2021-12-27 18:07:39 +00:00
( * sectp ) - > extra & = ~ ( SECTFX_NO_RIDE ) ;
2021-11-19 22:20:58 +00:00
}
2015-05-19 21:54:34 +00:00
}
}
break ;
}
case TRACK_MOVE_VERTICAL :
{
int zr ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_MOVE_VERTICAL ) ;
2015-05-19 21:54:34 +00:00
if ( tpoint - > tag_high > 0 )
zr = tpoint - > tag_high ;
else
zr = 256 ;
// look at the next point
NextTrackPoint ( sop ) ;
tpoint = Track [ sop - > track ] . TrackPoint + sop - > point ;
// set anim
2022-08-21 20:51:03 +00:00
AnimSet ( ANIM_SopZ , int ( sop - SectorObject ) , nullptr , tpoint - > pos . Z , zr ) ;
2015-05-19 21:54:34 +00:00
// move back to current point by reversing direction
sop - > dir * = - 1 ;
NextTrackPoint ( sop ) ;
tpoint = Track [ sop - > track ] . TrackPoint + sop - > point ;
sop - > dir * = - 1 ;
break ;
}
case TRACK_WAIT_FOR_EVENT :
{
if ( tpoint - > tag_high = = - 1 )
break ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_WAIT_FOR_EVENT ) ;
2015-05-19 21:54:34 +00:00
sop - > save_vel = sop - > vel ;
sop - > save_spin_speed = sop - > spin_speed ;
sop - > vel = sop - > spin_speed = 0 ;
// only set event if non-zero
if ( tpoint - > tag_high )
sop - > match_event = tpoint - > tag_high ;
tpoint - > tag_high = - 1 ;
break ;
}
case TRACK_ZDIFF_MODE :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZDIFF_MODE ) ;
2022-08-21 21:10:51 +00:00
sop - > zdelta = tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_ZRATE :
sop - > z_rate = Z ( tpoint - > tag_high ) ;
break ;
case TRACK_ZUP :
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_ZDOWN | SOBJ_ZUP ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > dir < 0 )
{
sop - > z_tgt = sop - > z_tgt + Z ( tpoint - > tag_high ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZDOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
sop - > z_tgt = sop - > z_tgt - Z ( tpoint - > tag_high ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZUP ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ZDOWN :
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_ZDOWN | SOBJ_ZUP ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > dir > 0 )
{
sop - > z_tgt = sop - > z_tgt + Z ( tpoint - > tag_high ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZDOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
sop - > z_tgt = sop - > z_tgt - Z ( tpoint - > tag_high ) ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZUP ) ;
2015-05-19 21:54:34 +00:00
}
break ;
}
// get the next point
NextTrackPoint ( sop ) ;
tpoint = Track [ sop - > track ] . TrackPoint + sop - > point ;
2022-08-21 21:13:53 +00:00
// calculate distance to target point
sop - > target_dist = ( sop - > pmid . XY ( ) - tpoint - > pos . XY ( ) ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
// calculate a new angle to the target
2022-08-21 20:51:03 +00:00
sop - > ang_moving = sop - > ang_tgt = getangle ( tpoint - > pos - sop - > pmid ) ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_ZDIFF_MODE ) )
2015-05-19 21:54:34 +00:00
{
// set dx,dy,dz up for finding the z magnitude
2022-08-21 21:10:51 +00:00
auto pos = tpoint - > pos . plusZ ( - sop - > zdelta ) ;
2015-05-19 21:54:34 +00:00
// find the distance to the target (player)
2022-08-21 21:10:51 +00:00
double dist = ( pos . XY ( ) - sop - > pmid . XY ( ) ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
// (velocity * difference between the target and the object)
2022-08-21 21:10:51 +00:00
// take absolute value
sop - > z_rate = ( int ) abs ( ( sop - > vel * zinttoworld * ( sop - > pmid . Z - pos . Z ) ) / dist ) ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_SPRITE_OBJ ) )
2015-05-19 21:54:34 +00:00
{
// only modify zmid for sprite_objects
2022-08-21 21:10:51 +00:00
AnimSet ( ANIM_SopZ , int ( sop - SectorObject ) , nullptr , pos . Z , sop - > z_rate ) ;
2015-05-19 21:54:34 +00:00
}
else
{
// churn through sectors setting their new z values
2022-08-21 21:10:51 +00:00
for ( int i = 0 ; sop - > sectp [ i ] ! = nullptr ; i + + )
2015-05-19 21:54:34 +00:00
{
2022-08-21 21:10:51 +00:00
AnimSet ( ANIM_Floorz , sop - > sectp [ i ] , pos . Z - ( sop - > mid_sector - > floorz - sop - > sectp [ i ] - > floorz ) , sop - > z_rate ) ;
2015-05-19 21:54:34 +00:00
}
}
}
}
else
{
// make velocity approach the target velocity
2021-12-29 05:53:36 +00:00
if ( ( sop - > flags & SOBJ_SPEED_UP ) )
2015-05-19 21:54:34 +00:00
{
if ( ( sop - > vel + = ( locktics < < sop - > vel_rate ) ) > = sop - > vel_tgt )
{
sop - > vel = sop - > vel_tgt ;
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-12-29 05:53:36 +00:00
else if ( ( sop - > flags & SOBJ_SLOW_DOWN ) )
2015-05-19 21:54:34 +00:00
{
if ( ( sop - > vel - = ( locktics < < sop - > vel_rate ) ) < = sop - > vel_tgt )
{
sop - > vel = sop - > vel_tgt ;
2021-12-27 17:58:15 +00:00
sop - > flags & = ~ ( SOBJ_SLOW_DOWN ) ;
2015-05-19 21:54:34 +00:00
}
}
}
// calculate a new x and y
2021-12-29 05:13:28 +00:00
if ( sop - > vel & & ! ( sop - > flags & SOBJ_MOVE_VERTICAL ) )
2015-05-19 21:54:34 +00:00
{
2021-11-19 20:47:04 +00:00
* nx = ( ( sop - > vel ) > > 8 ) * locktics * bcos ( sop - > ang_moving ) > > 14 ;
* ny = ( ( sop - > vel ) > > 8 ) * locktics * bsin ( sop - > ang_moving ) > > 14 ;
2015-05-19 21:54:34 +00:00
2022-08-21 21:13:53 +00:00
auto dist = Distance ( 0 , 0 , * nx , * ny ) * inttoworld ;
2015-05-19 21:54:34 +00:00
sop - > target_dist - = dist ;
}
}
2022-08-20 08:03:21 +00:00
void OperateSectorObjectForTics ( SECTOR_OBJECT * sop , short newang , const DVector2 & pos , short locktics )
2015-05-19 21:54:34 +00:00
{
2020-03-06 15:49:49 +00:00
int i ;
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2015-05-19 21:54:34 +00:00
if ( Prediction )
return ;
if ( sop - > track < SO_OPERATE_TRACK_START )
return ;
2020-05-01 11:29:12 +00:00
so_setinterpolationtics ( sop , locktics ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > bob_amt )
{
2020-09-02 18:56:09 +00:00
sop - > bob_sine_ndx = ( PlayClock < < sop - > bob_speed ) & 2047 ;
2021-01-04 11:36:54 +00:00
sop - > bob_diff = MulScale ( sop - > bob_amt , bsin ( sop - > bob_sine_ndx ) , 14 ) ;
2015-05-19 21:54:34 +00:00
// for all sectors
for ( i = 0 , sectp = & sop - > sectp [ 0 ] ; * sectp ; sectp + + , i + + )
{
2021-12-29 05:53:36 +00:00
if ( sop - > sectp [ i ] - > hasU ( ) & & ( sop - > sectp [ i ] - > flags & SECTFU_SO_DONT_BOB ) )
2015-05-19 21:54:34 +00:00
continue ;
2022-02-02 23:35:12 +00:00
( * sectp ) - > set_int_floorz ( sop - > zorig_floor [ i ] + sop - > bob_diff ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-08-28 00:40:50 +00:00
GlobSpeedSO = nullAngle ;
2015-05-19 21:54:34 +00:00
//sop->ang_tgt = newang;
sop - > ang_moving = newang ;
sop - > spin_ang = 0 ;
sop - > ang = newang ;
2022-08-20 08:03:21 +00:00
RefreshPoints ( sop , int ( ( pos . X - sop - > pmid . X ) * worldtoint ) , int ( ( pos . Y - sop - > pmid . Y ) * worldtoint ) , false ) ;
2015-05-19 21:54:34 +00:00
}
2022-08-20 08:03:21 +00:00
void OperateSectorObject ( SECTOR_OBJECT * sop , short newang , const DVector2 & pos )
2020-05-01 11:29:12 +00:00
{
2022-08-20 08:03:21 +00:00
OperateSectorObjectForTics ( sop , newang , pos , synctics ) ;
2020-05-01 11:29:12 +00:00
}
2022-08-20 08:03:21 +00:00
void PlaceSectorObject ( SECTOR_OBJECT * sop , const DVector2 & pos )
2015-05-19 21:54:34 +00:00
{
2020-05-01 11:29:12 +00:00
so_setinterpolationtics ( sop , synctics ) ;
2022-08-20 08:03:21 +00:00
RefreshPoints ( sop , int ( ( pos . X - sop - > pmid . X ) * worldtoint ) , int ( ( pos . Y - sop - > pmid . Y ) * worldtoint ) , false ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 22:09:34 +00:00
void VehicleSetSmoke ( SECTOR_OBJECT * sop , ANIMATOR * animator )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:43:47 +00:00
sectortype * * sectp ;
2015-05-19 21:54:34 +00:00
for ( sectp = sop - > sectp ; * sectp ; sectp + + )
{
2021-11-11 19:20:00 +00:00
SWSectIterator it ( * sectp ) ;
2021-10-30 18:00:02 +00:00
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-25 00:25:07 +00:00
switch ( actor - > spr . hitag )
2015-05-19 21:54:34 +00:00
{
case SPAWN_SPOT :
2021-12-25 00:25:07 +00:00
if ( actor - > spr . clipdist = = 3 )
2015-05-19 21:54:34 +00:00
{
if ( animator )
{
2021-12-25 00:25:07 +00:00
if ( actor - > spr . statnum = = STAT_NO_STATE )
2015-05-19 21:54:34 +00:00
break ;
2021-10-30 18:00:02 +00:00
change_actor_stat ( actor , STAT_NO_STATE ) ;
2021-12-25 00:25:07 +00:00
DoSoundSpotMatch ( actor - > spr . lotag , 1 , 0 ) ;
DoSpawnSpotsForDamage ( actor - > spr . lotag ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-10-30 18:00:02 +00:00
change_actor_stat ( actor , STAT_SPAWN_SPOT ) ;
2021-12-25 00:25:07 +00:00
DoSoundSpotStopSound ( actor - > spr . lotag ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-26 00:30:29 +00:00
actor - > user . ActorActionFunc = animator ;
2015-05-19 21:54:34 +00:00
}
break ;
}
}
}
}
2021-12-31 14:50:44 +00:00
void TornadoSpin ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
short delta_ang , speed ;
short locktics = synctics ;
// get delta to target angle
2020-09-16 11:46:03 +00:00
delta_ang = getincangle ( sop - > ang , sop - > ang_tgt ) ;
2015-05-19 21:54:34 +00:00
sop - > ang = NORM_ANGLE ( sop - > ang + ( delta_ang > > sop - > turn_speed ) ) ;
delta_ang = delta_ang > > sop - > turn_speed ;
// move z values
MoveZ ( sop ) ;
// calculate the spin speed
speed = sop - > spin_speed * locktics ;
// spin_ang is incremented by the spin_speed
sop - > spin_ang = NORM_ANGLE ( sop - > spin_ang + speed ) ;
if ( sop - > spin_speed )
{
// ignore delta angle if spinning
2022-08-27 10:51:50 +00:00
GlobSpeedSO = DAngle : : fromBuild ( speed ) ;
2015-05-19 21:54:34 +00:00
}
else
{
// The actual delta from the last frame
2022-08-27 10:51:50 +00:00
GlobSpeedSO = DAngle : : fromBuild ( speed + delta_ang ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-12-31 14:50:44 +00:00
void DoTornadoObject ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
int xvect , yvect ;
// this made them move together more or less - cool!
//static short ang = 1024;
int floor_dist ;
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
vec3_t pos ;
2015-05-19 21:54:34 +00:00
int ret ;
short * ang = & sop - > ang_moving ;
2020-11-15 10:37:20 +00:00
xvect = sop - > vel * bcos ( * ang ) ;
yvect = sop - > vel * bcos ( * ang ) ;
2015-05-19 21:54:34 +00:00
2021-11-24 22:07:02 +00:00
auto cursect = sop - > op_main_sector ; // for sop->vel
2022-02-02 23:46:04 +00:00
floor_dist = ( abs ( cursect - > int_ceilingz ( ) - cursect - > int_floorz ( ) ) ) > > 2 ;
2022-08-18 16:27:31 +00:00
pos . X = sop - > int_pmid ( ) . X ;
pos . Y = sop - > int_pmid ( ) . Y ;
2021-12-22 09:41:47 +00:00
pos . Z = floor_dist ;
2015-05-19 21:54:34 +00:00
2022-08-20 08:03:21 +00:00
PlaceSectorObject ( sop , { MAXSO , MAXSO } ) ;
2021-11-26 15:08:12 +00:00
Collision coll ;
clipmove ( pos , & cursect , xvect , yvect , ( int ) sop - > clipdist , Z ( 0 ) , floor_dist , CLIPMASK_ACTOR , coll ) ;
2015-05-19 21:54:34 +00:00
2021-11-26 15:08:12 +00:00
if ( coll . type ! = kHitNone )
2015-05-19 21:54:34 +00:00
{
* ang = NORM_ANGLE ( * ang + 1024 + RANDOM_P2 ( 512 ) - 256 ) ;
}
TornadoSpin ( sop ) ;
2022-08-18 16:27:31 +00:00
RefreshPoints ( sop , pos . X - sop - > int_pmid ( ) . X , pos . Y - sop - > int_pmid ( ) . Y , true ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:50:44 +00:00
void DoAutoTurretObject ( SECTOR_OBJECT * sop )
2015-05-19 21:54:34 +00:00
{
2021-12-07 18:22:30 +00:00
DSWActor * actor = sop - > sp_child ;
if ( ! actor ) return ;
2015-05-19 21:54:34 +00:00
short delta_ang ;
2022-08-27 06:04:55 +00:00
DAngle diff ;
2015-05-19 21:54:34 +00:00
short i ;
2021-12-26 00:32:40 +00:00
if ( ( sop - > max_damage ! = - 9999 & & sop - > max_damage < = 0 ) | | ! actor - > hasU ( ) )
2015-05-19 21:54:34 +00:00
return ;
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics - = synctics ;
2015-05-19 21:54:34 +00:00
// check for new player if doesn't have a target or time limit expired
2021-12-26 00:30:29 +00:00
if ( ! actor - > user . targetActor | | actor - > user . WaitTics < 0 )
2015-05-19 21:54:34 +00:00
{
// 4 seconds
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 4 * 120 ;
2021-10-30 11:05:07 +00:00
DoActorPickClosePlayer ( actor ) ;
2015-05-19 21:54:34 +00:00
}
if ( MoveSkip2 = = 0 )
{
2021-11-02 17:45:21 +00:00
for ( i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
2015-05-19 21:54:34 +00:00
{
2021-12-07 18:22:30 +00:00
DSWActor * sActor = sop - > so_actors [ i ] ;
if ( ! sActor ) continue ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:35:54 +00:00
if ( sActor - > spr . statnum = = STAT_SO_SHOOT_POINT )
2021-11-02 17:45:21 +00:00
{
2022-08-21 15:48:15 +00:00
if ( ! FAFcansee ( sActor - > spr . pos . plusZ ( - 4 ) , sActor - > sector ( ) , ActorUpperVect ( actor - > user . targetActor ) , actor - > user . targetActor - > sector ( ) ) )
2015-05-19 21:54:34 +00:00
{
return ;
}
}
}
// FirePausing
2021-12-26 00:30:29 +00:00
if ( actor - > user . Counter > 0 )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . Counter - = synctics * 2 ;
if ( actor - > user . Counter < = 0 )
actor - > user . Counter = 0 ;
2015-05-19 21:54:34 +00:00
}
2021-12-26 00:30:29 +00:00
if ( actor - > user . Counter = = 0 )
2015-05-19 21:54:34 +00:00
{
2021-11-02 17:45:21 +00:00
for ( i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
{
2021-12-07 18:22:30 +00:00
DSWActor * sActor = sop - > so_actors [ i ] ;
if ( ! sActor ) continue ;
2021-12-25 00:20:36 +00:00
if ( sActor - > spr . statnum = = STAT_SO_SHOOT_POINT )
2021-11-02 17:45:21 +00:00
{
2021-12-25 00:20:36 +00:00
if ( SP_TAG5 ( sActor ) )
2021-12-26 00:30:29 +00:00
actor - > user . Counter = SP_TAG5 ( sActor ) ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . Counter = 12 ;
2015-05-19 21:54:34 +00:00
InitTurretMgun ( sop ) ;
}
}
}
2022-08-18 16:27:31 +00:00
sop - > ang_tgt = getangle ( actor - > user . targetActor - > int_pos ( ) . X - sop - > int_pmid ( ) . X , actor - > user . targetActor - > int_pos ( ) . Y - sop - > int_pmid ( ) . Y ) ;
2015-05-19 21:54:34 +00:00
// get delta to target angle
2020-09-16 11:46:03 +00:00
delta_ang = getincangle ( sop - > ang , sop - > ang_tgt ) ;
2015-05-19 21:54:34 +00:00
//sop->ang += delta_ang >> 4;
sop - > ang = NORM_ANGLE ( sop - > ang + ( delta_ang > > 3 ) ) ;
//sop->ang += delta_ang >> 2;
2022-08-27 06:04:55 +00:00
if ( sop - > limit_ang_center > = nullAngle )
2015-05-19 21:54:34 +00:00
{
2022-08-27 12:00:58 +00:00
diff = deltaangle ( sop - > limit_ang_center , DAngle : : fromBuild ( sop - > ang ) ) ;
2015-05-19 21:54:34 +00:00
2022-08-27 06:04:55 +00:00
if ( abs ( diff ) > = sop - > limit_ang_delta )
2015-05-19 21:54:34 +00:00
{
2022-08-27 06:04:55 +00:00
if ( diff < nullAngle )
sop - > ang = ( sop - > limit_ang_center - sop - > limit_ang_delta ) . Buildang ( ) ;
2015-05-19 21:54:34 +00:00
else
2022-08-27 06:04:55 +00:00
sop - > ang = ( sop - > limit_ang_center + sop - > limit_ang_delta ) . Buildang ( ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-08-20 08:03:21 +00:00
OperateSectorObjectForTics ( sop , sop - > ang , sop - > pmid , 2 * synctics ) ;
2015-05-19 21:54:34 +00:00
}
}
2021-11-05 23:37:16 +00:00
void DoActorHitTrackEndPoint ( DSWActor * actor )
2015-05-19 21:54:34 +00:00
{
2021-12-27 18:07:39 +00:00
Track [ actor - > user . track ] . flags & = ~ ( TF_TRACK_OCCUPIED ) ;
2015-05-19 21:54:34 +00:00
// jump the current track & determine if you should go to another
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_RUN_AWAY ) )
2015-05-19 21:54:34 +00:00
{
// look for another track leading away from the player
2021-12-26 00:30:29 +00:00
actor - > user . track = FindTrackAwayFromPlayer ( actor ) ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
if ( actor - > user . track > = 0 )
2015-05-19 21:54:34 +00:00
{
2022-08-21 20:51:03 +00:00
auto tp = Track [ actor - > user . track ] . TrackPoint + actor - > user . point ;
actor - > spr . angle = VecToAngle ( tp - > pos - actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_RUN_AWAY ) ;
2021-10-30 10:09:34 +00:00
DoActorSetSpeed ( actor , NORM_SPEED ) ;
2021-12-26 00:30:29 +00:00
actor - > user . track = - 1 ;
2015-05-19 21:54:34 +00:00
}
}
2021-12-27 18:34:06 +00:00
else if ( actor - > user . Flags & ( SPR_FIND_PLAYER ) )
2015-05-19 21:54:34 +00:00
{
// look for another track leading away from the player
2021-12-26 00:30:29 +00:00
actor - > user . track = FindTrackToPlayer ( actor ) ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
if ( actor - > user . track > = 0 )
2015-05-19 21:54:34 +00:00
{
2022-08-21 20:51:03 +00:00
auto tp = Track [ actor - > user . track ] . TrackPoint + actor - > user . point ;
actor - > spr . angle = VecToAngle ( tp - > pos - actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_FIND_PLAYER ) ;
2021-10-30 10:09:34 +00:00
DoActorSetSpeed ( actor , NORM_SPEED ) ;
2021-12-26 00:30:29 +00:00
actor - > user . track = - 1 ;
2015-05-19 21:54:34 +00:00
}
}
else
{
2021-12-26 00:30:29 +00:00
actor - > user . track = - 1 ;
2015-05-19 21:54:34 +00:00
}
}
2021-11-05 23:37:16 +00:00
void ActorLeaveTrack ( DSWActor * actor )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
if ( actor - > user . track = = - 1 )
2015-05-19 21:54:34 +00:00
return ;
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_FIND_PLAYER | SPR_RUN_AWAY | SPR_CLIMBING ) ;
2021-12-27 18:07:39 +00:00
Track [ actor - > user . track ] . flags & = ~ ( TF_TRACK_OCCUPIED ) ;
2021-12-26 00:30:29 +00:00
actor - > user . track = - 1 ;
2015-05-19 21:54:34 +00:00
}
2021-12-31 14:13:05 +00:00
bool ActorTrackDecide ( TRACK_POINT * tpoint , DSWActor * actor )
2015-05-19 21:54:34 +00:00
{
switch ( tpoint - > tag_low )
{
case TRACK_START :
// if track has a type and actor is going the right direction jump
// the track
2021-12-26 00:30:29 +00:00
if ( Track [ actor - > user . track ] . ttflags )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
if ( actor - > user . track_dir = = - 1 )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
DoActorHitTrackEndPoint ( actor ) ;
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
}
break ;
case TRACK_END :
// if track has a type and actor is going to right direction jump the
// track
2021-12-26 00:30:29 +00:00
if ( Track [ actor - > user . track ] . ttflags )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
if ( actor - > user . track_dir = = 1 )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
DoActorHitTrackEndPoint ( actor ) ;
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
}
break ;
case TRACK_ACTOR_WAIT_FOR_PLAYER :
{
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_WAIT_FOR_PLAYER ) ;
2021-12-26 00:30:29 +00:00
actor - > user . Dist = tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
break ;
}
case TRACK_ACTOR_WAIT_FOR_TRIGGER :
{
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_WAIT_FOR_TRIGGER ) ;
2021-12-26 00:30:29 +00:00
actor - > user . Dist = tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
break ;
}
//
// Controls the velocity
//
case TRACK_ACTOR_VEL_RATE :
2021-12-26 00:30:29 +00:00
actor - > user . vel_rate = tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_ACTOR_SPEED_UP :
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_SLOW_DOWN | SPR_SPEED_UP ) ;
2021-12-26 00:30:29 +00:00
if ( actor - > user . track_dir < 0 )
2015-05-19 21:54:34 +00:00
{
// set target to new slower target
2021-12-26 00:30:29 +00:00
actor - > user . vel_tgt = actor - > user . vel_tgt - ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_SLOW_DOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-26 00:30:29 +00:00
actor - > user . vel_tgt = actor - > user . vel_tgt + ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_SLOW_DOWN :
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_SLOW_DOWN | SPR_SPEED_UP ) ;
2021-12-26 00:30:29 +00:00
if ( actor - > user . track_dir > 0 )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . vel_tgt = actor - > user . vel_tgt - ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_SLOW_DOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-26 00:30:29 +00:00
actor - > user . vel_tgt = actor - > user . vel_tgt + ( tpoint - > tag_high * 256 ) ;
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
}
break ;
// Reverse it
case TRACK_ACTOR_REVERSE :
2021-12-26 00:30:29 +00:00
actor - > user . track_dir * = - 1 ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_ACTOR_STAND :
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Stand ) ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_ACTOR_JUMP :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Jump )
2015-05-19 21:54:34 +00:00
{
2022-08-21 21:10:51 +00:00
actor - > spr . angle = tpoint - > angle ;
2015-05-19 21:54:34 +00:00
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = ACTOR_STD_JUMP ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
2021-10-29 18:49:57 +00:00
DoActorBeginJump ( actor ) ;
2021-12-26 00:30:29 +00:00
actor - > user . ActorActionFunc = DoActorMoveJump ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_QUICK_JUMP :
case TRACK_ACTOR_QUICK_SUPER_JUMP :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Jump )
2015-05-19 21:54:34 +00:00
{
2015-05-19 22:01:22 +00:00
int zdiff ;
2021-12-06 11:24:22 +00:00
HitInfo hit { } ;
2015-05-19 21:54:34 +00:00
2022-08-21 21:10:51 +00:00
actor - > spr . angle = tpoint - > angle ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2015-05-19 21:54:34 +00:00
if ( tpoint - > tag_high )
{
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-27 17:58:15 +00:00
actor - > spr . cstat & = ~ ( CSTAT_SPRITE_BLOCK ) ;
2015-05-19 21:54:34 +00:00
2022-02-01 23:08:21 +00:00
FAFhitscan ( actor - > int_pos ( ) . X , actor - > int_pos ( ) . Y , actor - > int_pos ( ) . Z - Z ( 24 ) , actor - > sector ( ) , // Start position
2022-08-16 21:17:01 +00:00
bcos ( actor - > int_ang ( ) ) , // X vector of 3D ang
bsin ( actor - > int_ang ( ) ) , // Y vector of 3D ang
2020-11-15 10:37:20 +00:00
0 , // Z vector of 3D ang
2021-11-26 00:27:44 +00:00
hit , CLIPMASK_MISSILE ) ;
2015-05-19 21:54:34 +00:00
2021-12-27 16:13:47 +00:00
actor - > spr . cstat | = ( CSTAT_SPRITE_BLOCK ) ;
2015-05-19 21:54:34 +00:00
2021-11-26 00:27:44 +00:00
ASSERT ( hit . hitSector ! = nullptr ) ;
2015-05-19 21:54:34 +00:00
2021-11-26 00:27:44 +00:00
if ( hit . actor ( ) ! = nullptr )
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
2021-11-26 00:27:44 +00:00
if ( hit . hitWall = = nullptr )
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
2021-12-05 20:31:19 +00:00
if ( ! hit . hitWall - > twoSided ( ) )
2021-12-05 06:21:28 +00:00
return false ;
2022-02-02 23:46:04 +00:00
zdiff = labs ( actor - > int_pos ( ) . Z - hit . hitWall - > nextSector ( ) - > int_floorz ( ) ) > > 8 ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = PickJumpSpeed ( actor , zdiff ) ;
2015-05-19 21:54:34 +00:00
}
2021-10-29 18:49:57 +00:00
DoActorBeginJump ( actor ) ;
2021-12-26 00:30:29 +00:00
actor - > user . ActorActionFunc = DoActorMoveJump ;
2015-05-19 21:54:34 +00:00
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_QUICK_JUMP_DOWN :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Jump )
2015-05-19 21:54:34 +00:00
{
2022-08-21 21:10:51 +00:00
actor - > spr . angle = tpoint - > angle ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2015-05-19 21:54:34 +00:00
if ( tpoint - > tag_high )
{
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - 350 ;
2015-05-19 21:54:34 +00:00
}
2021-10-29 18:49:57 +00:00
DoActorBeginJump ( actor ) ;
2021-12-26 00:30:29 +00:00
actor - > user . ActorActionFunc = DoActorMoveJump ;
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_QUICK_SCAN :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Jump )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_QUICK_DUCK :
2021-12-26 00:30:29 +00:00
if ( actor - > user . Rot ! = actor - > user . ActorActionSet - > Duck )
2015-05-19 21:54:34 +00:00
{
2022-08-21 21:10:51 +00:00
actor - > spr . angle = tpoint - > angle ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2015-05-19 21:54:34 +00:00
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 4 * 120 ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = tpoint - > tag_high * 128 ;
2015-05-19 21:54:34 +00:00
2021-10-29 18:49:57 +00:00
InitActorDuck ( actor ) ;
2021-12-26 00:30:29 +00:00
actor - > user . ActorActionFunc = DoActorDuck ;
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_OPERATE :
case TRACK_ACTOR_QUICK_OPERATE :
{
2021-11-26 18:30:32 +00:00
HitInfo near ;
2015-05-19 21:54:34 +00:00
int z [ 2 ] ;
int i ;
2021-12-26 00:30:29 +00:00
if ( actor - > user . Rot = = actor - > user . ActorActionSet - > Sit | | actor - > user . Rot = = actor - > user . ActorActionSet - > Stand )
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
2022-08-21 21:10:51 +00:00
actor - > spr . angle = tpoint - > angle ;
2015-05-19 21:54:34 +00:00
2022-08-21 08:00:08 +00:00
z [ 0 ] = actor - > int_pos ( ) . Z - int_ActorSizeZ ( actor ) + Z ( 5 ) ;
z [ 1 ] = actor - > int_pos ( ) . Z - ( int_ActorSizeZ ( actor ) > > 1 ) ;
2015-05-19 21:54:34 +00:00
for ( i = 0 ; i < ( int ) SIZ ( z ) ; i + + )
{
2022-08-16 21:17:01 +00:00
neartag ( { actor - > int_pos ( ) . X , actor - > int_pos ( ) . Y , z [ i ] } , actor - > sector ( ) , actor - > int_ang ( ) , near , 1024 , NTAG_SEARCH_LO_HI ) ;
2015-05-19 21:54:34 +00:00
2022-08-16 22:59:32 +00:00
if ( near . actor ( ) ! = nullptr & & near . int_hitpos ( ) . X < 1024 )
2015-05-19 21:54:34 +00:00
{
2021-11-26 18:30:32 +00:00
if ( OperateSprite ( near . actor ( ) , false ) )
2015-05-19 21:54:34 +00:00
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 2 * 120 ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = tpoint - > tag_high * 128 ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Stand ) ;
2015-05-19 21:54:34 +00:00
}
}
}
2022-08-16 22:59:32 +00:00
if ( near . hitSector ! = nullptr & & near . int_hitpos ( ) . X < 1024 )
2015-05-19 21:54:34 +00:00
{
2021-11-26 18:30:32 +00:00
if ( OperateSector ( near . hitSector , false ) )
2015-05-19 21:54:34 +00:00
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 2 * 120 ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = tpoint - > tag_high * 128 ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Sit ) ;
2015-05-19 21:54:34 +00:00
}
}
break ;
}
case TRACK_ACTOR_JUMP_IF_FORWARD :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Jump & & actor - > user . track_dir = = 1 )
2015-05-19 21:54:34 +00:00
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = ACTOR_STD_JUMP ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
2021-10-29 18:49:57 +00:00
DoActorBeginJump ( actor ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_JUMP_IF_REVERSE :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Jump & & actor - > user . track_dir = = - 1 )
2015-05-19 21:54:34 +00:00
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = ACTOR_STD_JUMP ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
2021-10-29 18:49:57 +00:00
DoActorBeginJump ( actor ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_CRAWL :
2021-12-26 00:30:29 +00:00
if ( actor - > user . Rot ! = actor - > user . ActorActionSet - > Crawl )
NewStateGroup ( actor , actor - > user . ActorActionSet - > Crawl ) ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Rise ) ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_ACTOR_SWIM :
2021-12-26 00:30:29 +00:00
if ( actor - > user . Rot ! = actor - > user . ActorActionSet - > Swim )
NewStateGroup ( actor , actor - > user . ActorActionSet - > Swim ) ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Rise ) ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_ACTOR_FLY :
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Fly ) ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_ACTOR_SIT :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Sit )
2015-05-19 21:54:34 +00:00
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 3 * 120 ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = tpoint - > tag_high * 128 ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Sit ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_DEATH1 :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Death2 )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 4 * 120 ;
NewStateGroup ( actor , actor - > user . ActorActionSet - > Death1 ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_DEATH2 :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Death2 )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 4 * 120 ;
NewStateGroup ( actor , actor - > user . ActorActionSet - > Death2 ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_DEATH_JUMP :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > DeathJump )
2015-05-19 21:54:34 +00:00
{
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_DEAD ) ;
2021-12-25 00:25:07 +00:00
actor - > spr . xvel < < = 1 ;
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - 495 ;
2021-10-29 18:49:57 +00:00
DoActorBeginJump ( actor ) ;
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > DeathJump ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_CLOSE_ATTACK1 :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > CloseAttack [ 0 ] )
2015-05-19 21:54:34 +00:00
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 2 * 120 ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = tpoint - > tag_high * 128 ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > CloseAttack [ 0 ] ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_CLOSE_ATTACK2 :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > CloseAttack [ 1 ] )
2015-05-19 21:54:34 +00:00
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 4 * 120 ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = tpoint - > tag_high * 128 ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > CloseAttack [ 1 ] ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_ATTACK1 :
case TRACK_ACTOR_ATTACK2 :
case TRACK_ACTOR_ATTACK3 :
case TRACK_ACTOR_ATTACK4 :
case TRACK_ACTOR_ATTACK5 :
case TRACK_ACTOR_ATTACK6 :
{
2021-12-31 15:00:14 +00:00
STATE * * * ap = & actor - > user . ActorActionSet - > Attack [ 0 ] + ( tpoint - > tag_low - TRACK_ACTOR_ATTACK1 ) ;
2015-05-19 21:54:34 +00:00
if ( * ap )
{
if ( ! tpoint - > tag_high )
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = 4 * 120 ;
2015-05-19 21:54:34 +00:00
else
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics = tpoint - > tag_high * 128 ;
2015-05-19 21:54:34 +00:00
2021-10-30 21:12:31 +00:00
NewStateGroup ( actor , * ap ) ;
2015-05-19 21:54:34 +00:00
}
break ;
}
case TRACK_ACTOR_ZDIFF_MODE :
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_ZDIFF_MODE ) )
2015-05-19 21:54:34 +00:00
{
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_ZDIFF_MODE ) ;
2022-08-20 18:43:32 +00:00
actor - > spr . pos . Z = actor - > sector ( ) - > floorz ;
2021-12-25 00:25:07 +00:00
actor - > spr . zvel = 0 ;
2015-05-19 21:54:34 +00:00
}
else
{
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_ZDIFF_MODE ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_CLIMB_LADDER :
2021-12-26 00:30:29 +00:00
if ( actor - > user . ActorActionSet - > Jump )
2015-05-19 21:54:34 +00:00
{
2022-08-21 07:25:15 +00:00
int nx , ny ;
2021-11-26 18:30:32 +00:00
HitInfo near ;
2015-05-19 21:54:34 +00:00
//
// Get angle and x,y pos from CLIMB_MARKER
//
2021-11-01 20:14:05 +00:00
auto lActor = FindNearSprite ( actor , STAT_CLIMB_MARKER ) ;
2015-05-19 21:54:34 +00:00
2021-11-01 20:14:05 +00:00
if ( ! lActor )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
// determine where the player is supposed to be in relation to the ladder
// move out in front of the ladder
2022-08-16 21:15:49 +00:00
nx = MOVEx ( 100 , lActor - > int_ang ( ) ) ;
ny = MOVEy ( 100 , lActor - > int_ang ( ) ) ;
2015-05-19 21:54:34 +00:00
2022-02-01 23:08:21 +00:00
actor - > set_int_xy ( lActor - > int_pos ( ) . X + nx , lActor - > int_pos ( ) . Y + ny ) ;
2015-05-19 21:54:34 +00:00
2022-08-16 21:23:42 +00:00
actor - > set_int_ang ( NORM_ANGLE ( lActor - > int_ang ( ) + 1024 ) ) ;
2015-05-19 21:54:34 +00:00
//
// Get the z height to climb
//
2022-08-21 08:00:08 +00:00
neartag ( { actor - > int_pos ( ) . X , actor - > int_pos ( ) . Y , int_ActorZOfTop ( actor ) - ( int_ActorSizeZ ( actor ) > > 1 ) } , actor - > sector ( ) , actor - > int_ang ( ) , near , 600 , NTAG_SEARCH_LO_HI ) ;
2015-05-19 21:54:34 +00:00
2021-11-26 18:30:32 +00:00
if ( near . hitWall = = nullptr )
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
2021-11-26 18:30:32 +00:00
auto wal = near . hitWall ;
2015-05-19 21:54:34 +00:00
2021-12-27 20:13:00 +00:00
#if 0
2021-11-24 20:39:35 +00:00
if ( ! wal - > twoSided ( ) )
2015-05-19 21:54:34 +00:00
{
2021-11-24 20:20:22 +00:00
I_Error ( " Take out white wall ladder x = %d, y = %d " , wal - > x , wal - > y ) ;
2015-05-19 21:54:34 +00:00
}
# endif
// destination z for climbing
2021-11-24 20:20:22 +00:00
if ( wal - > twoSided ( ) )
2022-08-21 07:25:15 +00:00
actor - > user . pos . Z = wal - > nextSector ( ) - > floorz ;
2021-11-24 20:20:22 +00:00
else
2022-08-21 07:25:15 +00:00
actor - > user . pos . Z = wal - > sectorp ( ) - > ceilingz ; // don't crash on bad setups.
2015-05-19 21:54:34 +00:00
2021-11-03 16:47:13 +00:00
DoActorZrange ( actor ) ;
2015-05-19 21:54:34 +00:00
//
// Adjust for YCENTERING
//
2021-12-27 16:13:47 +00:00
actor - > spr . cstat | = ( CSTAT_SPRITE_YCENTER ) ;
2022-08-21 07:49:25 +00:00
double bos_z = ActorZOfBottom ( actor ) ;
2022-08-21 07:25:15 +00:00
if ( bos_z > actor - > user . loz )
2015-05-19 21:54:34 +00:00
{
2022-08-21 07:25:15 +00:00
actor - > user . pos . Y = ( bos_z - actor - > spr . pos . Z ) ;
actor - > spr . pos . Z - = actor - > user . pos . Y ;
2015-05-19 21:54:34 +00:00
}
//
// Misc climb setup
//
2021-12-27 16:13:47 +00:00
actor - > user . Flags | = ( SPR_CLIMBING ) ;
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Climb ) ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:25:07 +00:00
actor - > spr . zvel = - Z ( 1 ) ;
2015-05-19 21:54:34 +00:00
}
break ;
case TRACK_ACTOR_SET_JUMP :
2021-12-26 00:30:29 +00:00
actor - > user . jump_speed = - tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
break ;
}
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
}
/*
! AIC - This is where actors follow tracks . Its massy , hard to read , and more
complex than it needs to be . It was taken from sector object track movement
code . The routine above ActorTrackDecide ( ) is where a track tag is recognized
and acted upon . There are quite a few of these that are not useful to us at
present time .
*/
2021-11-01 13:36:46 +00:00
int ActorFollowTrack ( DSWActor * actor , short locktics )
2015-05-19 21:54:34 +00:00
{
2021-12-31 14:59:11 +00:00
PLAYER * pp ;
2015-05-19 21:54:34 +00:00
2021-12-31 14:13:05 +00:00
TRACK_POINT * tpoint ;
2015-05-19 21:54:34 +00:00
short pnum ;
2022-08-21 21:10:51 +00:00
int nx = 0 , ny = 0 , nz = 0 ;
2015-05-19 21:54:34 +00:00
// if not on a track then better not go here
2021-12-26 00:30:29 +00:00
if ( actor - > user . track = = - 1 )
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
// if lying in wait for player
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_WAIT_FOR_PLAYER | SPR_WAIT_FOR_TRIGGER ) )
2015-05-19 21:54:34 +00:00
{
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_WAIT_FOR_PLAYER ) )
2015-05-19 21:54:34 +00:00
{
TRAVERSE_CONNECT ( pnum )
{
pp = & Player [ pnum ] ;
2022-08-20 10:21:41 +00:00
if ( Distance ( actor - > int_pos ( ) . X , actor - > int_pos ( ) . Y , pp - > int_ppos ( ) . X , pp - > int_ppos ( ) . Y ) < actor - > user . Dist )
2015-05-19 21:54:34 +00:00
{
2021-12-26 07:44:18 +00:00
actor - > user . targetActor = pp - > actor ;
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_WAIT_FOR_PLAYER ) ;
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
}
}
}
2021-12-26 00:30:29 +00:00
actor - > user . Tics = 0 ;
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
}
// if pausing the return
2021-12-26 00:30:29 +00:00
if ( actor - > user . WaitTics )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . WaitTics - = locktics ;
if ( actor - > user . WaitTics < = 0 )
2015-05-19 21:54:34 +00:00
{
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_DONT_UPDATE_ANG ) ;
2021-12-26 00:30:29 +00:00
NewStateGroup ( actor , actor - > user . ActorActionSet - > Run ) ;
actor - > user . WaitTics = 0 ;
2015-05-19 21:54:34 +00:00
}
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
}
2021-12-26 00:30:29 +00:00
tpoint = Track [ actor - > user . track ] . TrackPoint + actor - > user . point ;
2015-05-19 21:54:34 +00:00
2021-12-27 18:34:06 +00:00
if ( ! ( actor - > user . Flags & ( SPR_CLIMBING | SPR_DONT_UPDATE_ANG ) ) )
2015-05-19 21:54:34 +00:00
{
2022-08-21 20:51:03 +00:00
actor - > spr . angle = VecToAngle ( tpoint - > pos - actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
}
2022-08-21 21:10:51 +00:00
double dist = ( actor - > spr . pos . XY ( ) - tpoint - > pos . XY ( ) ) . Length ( ) ;
if ( dist < 200 * maptoworld ) // 64
2015-05-19 21:54:34 +00:00
{
2021-11-05 23:37:16 +00:00
if ( ! ActorTrackDecide ( tpoint , actor ) )
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
// get the next point
2021-11-05 23:37:16 +00:00
NextActorTrackPoint ( actor ) ;
2021-12-26 00:30:29 +00:00
tpoint = Track [ actor - > user . track ] . TrackPoint + actor - > user . point ;
2015-05-19 21:54:34 +00:00
2021-12-27 18:34:06 +00:00
if ( ! ( actor - > user . Flags & ( SPR_CLIMBING | SPR_DONT_UPDATE_ANG ) ) )
2015-05-19 21:54:34 +00:00
{
// calculate a new angle to the target
2022-08-21 20:51:03 +00:00
actor - > spr . angle = VecToAngle ( tpoint - > pos - actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_ZDIFF_MODE ) )
2015-05-19 21:54:34 +00:00
{
// find the distance to the target (player)
2022-08-21 21:10:51 +00:00
dist = ( tpoint - > pos . XY ( ) - actor - > spr . pos . XY ( ) ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
// (velocity * difference between the target and the object) /
// distance
2022-08-21 21:10:51 +00:00
actor - > spr . zvel = ( int ) - ( ( actor - > spr . xvel * ( actor - > spr . pos . Z - tpoint - > pos . Z ) ) / dist ) ;
2015-05-19 21:54:34 +00:00
}
}
else
{
// make velocity approach the target velocity
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_SPEED_UP ) )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
if ( ( actor - > user . track_vel + = ( locktics < < actor - > user . vel_rate ) ) > = actor - > user . vel_tgt )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . track_vel = actor - > user . vel_tgt ;
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_SPEED_UP ) ;
2015-05-19 21:54:34 +00:00
}
// update the real velocity
2021-12-26 00:30:29 +00:00
actor - > spr . xvel = ( actor - > user . track_vel ) > > 8 ;
2015-05-19 21:54:34 +00:00
}
2021-12-27 18:34:06 +00:00
else if ( actor - > user . Flags & ( SPR_SLOW_DOWN ) )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
if ( ( actor - > user . track_vel - = ( locktics < < actor - > user . vel_rate ) ) < = actor - > user . vel_tgt )
2015-05-19 21:54:34 +00:00
{
2021-12-26 00:30:29 +00:00
actor - > user . track_vel = actor - > user . vel_tgt ;
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SOBJ_SLOW_DOWN ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-26 00:30:29 +00:00
actor - > spr . xvel = ( actor - > user . track_vel ) > > 8 ;
2015-05-19 21:54:34 +00:00
}
nx = 0 ;
ny = 0 ;
2021-12-27 18:34:06 +00:00
if ( actor - > user . Flags & ( SPR_CLIMBING ) )
2015-05-19 21:54:34 +00:00
{
2022-08-21 08:40:45 +00:00
if ( ActorZOfTop ( actor ) + ( ActorSizeZ ( actor ) * 0.25 ) < actor - > user . pos . Z )
2015-05-19 21:54:34 +00:00
{
2021-12-27 17:58:15 +00:00
actor - > user . Flags & = ~ ( SPR_CLIMBING ) ;
2015-05-19 21:54:34 +00:00
2021-12-25 00:25:07 +00:00
actor - > spr . zvel = 0 ;
2015-05-19 21:54:34 +00:00
2022-08-21 20:51:03 +00:00
actor - > spr . angle = VecToAngle ( tpoint - > pos - actor - > spr . pos ) ;
2015-05-19 21:54:34 +00:00
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2021-12-27 17:58:15 +00:00
actor - > spr . cstat & = ~ ( CSTAT_SPRITE_YCENTER ) ;
2022-08-21 07:25:15 +00:00
actor - > spr . pos . Z + = actor - > user . pos . Y ;
2015-05-19 21:54:34 +00:00
2021-10-30 10:09:34 +00:00
DoActorSetSpeed ( actor , SLOW_SPEED ) ;
2021-12-26 00:30:29 +00:00
actor - > user . ActorActionFunc = NinjaJumpActionFunc ;
actor - > user . jump_speed = - 650 ;
2021-10-29 18:49:57 +00:00
DoActorBeginJump ( actor ) ;
2015-05-19 21:54:34 +00:00
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
}
}
else
{
// calculate a new x and y
2022-08-16 21:17:01 +00:00
nx = MulScale ( actor - > spr . xvel , bcos ( actor - > int_ang ( ) ) , 14 ) ;
ny = MulScale ( actor - > spr . xvel , bsin ( actor - > int_ang ( ) ) , 14 ) ;
2015-05-19 21:54:34 +00:00
}
nz = 0 ;
2021-12-25 00:25:07 +00:00
if ( actor - > spr . zvel )
nz = actor - > spr . zvel * locktics ;
2015-05-19 21:54:34 +00:00
}
2022-08-20 21:30:18 +00:00
actor - > user . coll = move_sprite ( actor , nx , ny , nz , actor - > user . int_ceiling_dist ( ) , actor - > user . int_floor_dist ( ) , 0 , locktics ) ;
2015-05-19 21:54:34 +00:00
2021-12-26 00:30:29 +00:00
if ( actor - > user . coll . type ! = kHitNone )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:18:25 +00:00
if ( ! ( actor - > user . Flags & ( SPR_JUMPING | SPR_FALLING ) ) )
2021-11-05 23:37:16 +00:00
ActorLeaveTrack ( actor ) ;
2015-05-19 21:54:34 +00:00
}
2020-09-09 17:52:52 +00:00
return true ;
2015-05-19 21:54:34 +00:00
}
# include "saveable.h"
static saveable_code saveable_track_code [ ] =
{
SAVE_CODE ( DoTornadoObject ) ,
SAVE_CODE ( DoAutoTurretObject ) ,
} ;
saveable_module saveable_track =
{
// code
saveable_track_code ,
SIZ ( saveable_track_code ) ,
// data
2021-07-10 12:25:18 +00:00
nullptr , 0
2015-05-19 21:54:34 +00:00
} ;
2019-10-09 16:09:05 +00:00
END_SW_NS