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
2022-09-03 21:21:36 +00:00
DVector2 DoTrack ( SECTOR_OBJECT * sop , short locktics ) ;
2021-12-31 14:50:44 +00:00
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
2022-10-19 15:41:50 +00:00
double Distance ( DVector2 p1 , DVector2 p2 )
{
double min ;
if ( ( p2 . X = p2 . X - p1 . X ) < 0 )
p2 . X = - p2 . X ;
if ( ( p2 . Y = p2 . Y - p1 . Y ) < 0 )
p2 . Y = - p2 . Y ;
if ( p2 . X > p2 . Y )
min = p2 . Y ;
else
min = p2 . X ;
return p2 . X + p2 . Y - ( min * 0.5 ) ;
}
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-10-19 15:41:50 +00:00
auto end_dist = Distance ( end_point - > pos . XY ( ) , actor - > spr . pos . XY ( ) ) ;
auto start_dist = Distance ( start_point - > pos . XY ( ) , actor - > spr . pos . XY ( ) ) ;
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-10-19 15:41:50 +00:00
auto end_dist = Distance ( end_point - > pos . XY ( ) , actor - > spr . pos . XY ( ) ) ;
auto start_dist = Distance ( start_point - > pos . XY ( ) , actor - > spr . pos . XY ( ) ) ;
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-10-19 15:41:50 +00:00
double dist = Distance ( tp - > pos . XY ( ) , actor - > spr . pos . XY ( ) ) ;
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-09-03 21:53:39 +00:00
actor - > spr . pos + = actor - > spr . angle . ToVector ( ) * 4 ;
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-09-03 21:53:39 +00:00
end_sprite - > spr . pos + = end_sprite - > spr . angle . ToVector ( ) * 128 ;
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-09-03 21:53:39 +00:00
start_sprite - > spr . pos + = start_sprite - > spr . angle . ToVector ( ) * 4 ;
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-09-03 21:53:39 +00:00
end_sprite - > spr . pos + = end_sprite - > spr . angle . ToVector ( ) * 4 ;
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-09-03 21:53:39 +00:00
end_sprite - > spr . pos + = end_sprite - > spr . angle . ToVector ( ) * 64 ;
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-09-03 21:53:39 +00:00
start_sprite - > spr . pos + = ( start_sprite - > spr . angle + DAngle180 ) . ToVector ( ) * 16 ;
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-09-03 21:53:39 +00:00
end_sprite - > spr . pos + = end_sprite - > spr . angle . ToVector ( ) * 32 ;
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-09-03 21:53:39 +00:00
Printf ( " WARNING: Did not find first point of Track Number %d, x %d, y %d \n " , ndx , int ( itActor - > spr . pos . X ) , int ( itActor - > spr . 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-10-19 15:41:50 +00:00
dist = Distance ( ( tp + t - > NumPoints - 1 ) - > pos , actor - > spr . pos ) ;
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
{
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-09-03 21:53:39 +00:00
DVector2 vlow = BoundActor - > spr . pos ;
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-09-03 21:53:39 +00:00
DVector2 vhigh = BoundActor - > spr . pos ;
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
2022-09-03 21:53:39 +00:00
child - > user . Radius = ( ( vhigh . X - vlow . X ) + ( vhigh . Y - vlow . Y ) ) * ( 0.75 * 0.25 ) * worldtoint ; // 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
}
// 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-09-03 21:53:39 +00:00
if ( ! ( wal . pos . X > vlow . X & & wal . pos . X < vhigh . X & & wal . pos . Y > vlow . Y & & wal . pos . Y < vhigh . Y ) )
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-09-03 21:56:48 +00:00
sop - > zorig_floor [ sop - > num_sectors ] = sect - > floorz ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( sect - > extra & SECTFX_SINK ) )
2022-09-03 21:56:48 +00:00
sop - > zorig_floor [ sop - > num_sectors ] + = 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-09-03 21:32:26 +00:00
if ( sect - > floorz > sop - > floor_loz )
sop - > floor_loz = sect - > floorz ;
2015-05-19 21:54:34 +00:00
2022-09-03 21:32:26 +00:00
if ( sect - > floorz < sop - > floor_hiz )
sop - > floor_hiz = sect - > 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-09-03 21:53:39 +00:00
if ( itActor - > spr . pos . X > vlow . X & & itActor - > spr . pos . X < vhigh . X & & itActor - > spr . pos . Y > vlow . Y & & itActor - > spr . pos . Y < vhigh . Y )
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 :
{
sop - > clipdist = 0 ;
2021-12-25 00:07:58 +00:00
sop - > clipbox_dist [ sop - > clipbox_num ] = itActor - > spr . lotag ;
2015-05-19 21:54:34 +00:00
2022-09-03 20:12:32 +00:00
sop - > clipbox_vdist [ sop - > clipbox_num ] = ( sop - > pmid . XY ( ) - itActor - > spr . pos . XY ( ) ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
2022-09-30 11:38:21 +00:00
auto ang2 = ( itActor - > spr . pos . XY ( ) - sop - > pmid . XY ( ) ) . Angle ( ) ;
2022-10-03 19:49:08 +00:00
sop - > clipbox_ang [ sop - > clipbox_num ] = deltaangle ( 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-09-01 17:28:33 +00:00
itActor - > user . sang = itActor - > spr . angle ;
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
{
2022-09-03 21:53:39 +00:00
double zmid = - 9999999 ;
2015-05-19 21:54:34 +00:00
// 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-09-03 21:53:39 +00:00
if ( actor - > spr . pos . Z > zmid )
zmid = actor - > spr . pos . Z ;
2015-05-19 21:54:34 +00:00
}
ASSERT ( zmid ! = - 9999999 ) ;
2022-09-03 21:53:39 +00:00
sop - > pmid . Z = zmid ;
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 ;
2022-10-03 19:49:08 +00:00
sop - > spin_speed = nullAngle ;
sop - > spin_ang = nullAngle ;
sop - > ang_orig = nullAngle ;
2015-05-19 21:54:34 +00:00
sop - > clipdist = 1024 ;
sop - > target_dist = 0 ;
sop - > turn_speed = 4 ;
2022-09-03 21:32:26 +00:00
sop - > floor_loz = - 9999999 ;
sop - > floor_hiz = 9999999 ;
2022-10-03 19:49:08 +00:00
sop - > ang_tgt = sop - > ang = sop - > ang_moving = nullAngle ;
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 ;
2022-09-03 18:40:57 +00:00
sop - > scale_dist = 0 ;
sop - > scale_speed = 1.25 ;
sop - > scale_dist_min = - 64 ;
sop - > scale_dist_max = 64 ;
2015-05-19 21:54:34 +00:00
sop - > scale_rand_freq = 64 > > 3 ;
sop - > scale_x_mult = 256 ;
sop - > scale_y_mult = 256 ;
2022-09-04 22:04:29 +00:00
sop - > morph_ang = RandomAngle ( ) ;
2022-09-03 18:23:41 +00:00
sop - > morph_z_speed = 20 ;
sop - > morph_speed = 2 ;
sop - > morph_dist_max = 64 ;
2015-05-19 21:54:34 +00:00
sop - > morph_rand_freq = 64 ;
2022-09-03 18:23:41 +00:00
sop - > morph_dist = 0 ;
sop - > morph_off = { 0 , 0 } ;
2015-05-19 21:54:34 +00:00
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-09-06 16:24:49 +00:00
auto actorNew = SpawnActor ( STAT_SO_SP_CHILD , 0 , nullptr , sectp , sop - > pmid , nullAngle ) ;
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 :
2022-09-03 20:57:07 +00:00
memset ( sop - > scale_point_dist , 0 , sizeof ( sop - > scale_point_dist ) ) ;
sop - > scale_point_base_speed = SP_TAG2 ( actor ) * maptoworld ;
for ( j = 0 ; j < ( int ) SIZ ( sop - > scale_point_speed ) ; j + + )
2015-05-19 21:54:34 +00:00
{
2022-09-03 20:57:07 +00:00
sop - > scale_point_speed [ j ] = SP_TAG2 ( actor ) * maptoworld ;
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 ;
2022-09-03 20:57:07 +00:00
sop - > scale_point_dist_min = - SP_TAG5 ( actor ) * maptoworld ;
sop - > scale_point_dist_max = SP_TAG6 ( actor ) * maptoworld ;
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 ) ;
2022-09-03 18:40:57 +00:00
sop - > scale_speed = SP_TAG2 ( actor ) * maptoworld ;
sop - > scale_dist_min = - SP_TAG5 ( actor ) * maptoworld ;
sop - > scale_dist_max = SP_TAG6 ( actor ) * maptoworld ;
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 )
2022-09-03 18:40:57 +00:00
sop - > scale_dist = sop - > scale_dist_min ;
2021-12-25 00:20:36 +00:00
else if ( SP_TAG3 ( actor ) = = 1 )
2022-09-03 18:40:57 +00:00
sop - > scale_dist = sop - > scale_dist_max ;
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 SPAWN_SPOT :
2022-09-09 16:32:42 +00:00
if ( actor - > native_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
2022-10-03 20:18:48 +00:00
sop - > spin_speed = DAngle22_5 * ( 1. / 16 ) ;
2022-10-03 19:49:08 +00:00
sop - > last_ang = sop - > ang ;
2015-05-19 21:54:34 +00:00
// animators
sop - > Animator = DoTornadoObject ;
sop - > PreMoveAnimator = ScaleSectorObject ;
sop - > PostMoveAnimator = MorphTornado ;
// clip
sop - > clipdist = 2500 ;
// morph point
2022-09-03 18:23:41 +00:00
sop - > morph_speed = 1 ;
sop - > morph_z_speed = 6 ;
sop - > morph_dist_max = 64 ;
2015-05-19 21:54:34 +00:00
sop - > morph_rand_freq = 8 ;
2022-09-03 18:40:57 +00:00
sop - > scale_dist_min = - 48 ;
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 ;
2022-09-03 18:23:41 +00:00
sop - > morph_speed = 7.5 ;
sop - > morph_z_speed = 7 ;
2015-05-19 21:54:34 +00:00
sop - > PostMoveAnimator = MorphFloor ;
2022-09-03 18:23:41 +00:00
sop - > morph_dist_max = 250 ;
2015-05-19 21:54:34 +00:00
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 ;
2022-09-03 20:57:07 +00:00
memset ( sop - > scale_point_dist , 0 , sizeof ( sop - > scale_point_dist ) ) ; ;
sop - > scale_point_base_speed = 0.25 + RandomRangeF ( 0.5 ) ;
for ( j = 0 ; j < ( int ) SIZ ( sop - > scale_point_speed ) ; j + + )
sop - > scale_point_speed [ j ] = 0.25 + RandomRangeF ( 0.5 ) ;
2015-05-19 21:54:34 +00:00
2022-09-03 20:57:07 +00:00
sop - > scale_point_dist_min = - 16 ;
sop - > scale_point_dist_max = 16 ;
2015-05-19 21:54:34 +00:00
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
2022-09-09 16:32:42 +00:00
switch ( actor - > native_clipdist ( ) ) // notreallyclipdist
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 :
2022-09-30 10:51:50 +00:00
sop - > drive_angspeed = FixedToFloat < 11 > ( SP_TAG2 ( actor ) ) ;
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-09-05 15:35:08 +00:00
sop - > crush_z = actor - > spr . 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-09-11 11:47:47 +00:00
sop - > limit_ang_delta = mapangle ( 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 :
2022-10-03 19:49:08 +00:00
if ( sop - > spin_speed ! = nullAngle )
2015-05-19 21:54:34 +00:00
break ;
2022-09-11 11:47:47 +00:00
sop - > spin_speed = mapangle ( actor - > spr . lotag ) ;
2022-10-03 19:49:08 +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-10-03 19:49:08 +00:00
sop - > ang = sop - > ang_moving = actor - > spr . angle ;
sop - > last_ang = sop - > ang_orig = sop - > ang ;
sop - > spin_ang = nullAngle ;
2021-10-30 20:53:24 +00:00
KillActor ( actor ) ;
2015-05-19 21:54:34 +00:00
break ;
case SO_SPIN_REVERSE :
2022-09-11 11:47:47 +00:00
sop - > spin_speed = mapangle ( actor - > spr . lotag ) ;
2022-10-03 19:49:08 +00:00
sop - > last_ang = sop - > ang ;
2015-05-19 21:54:34 +00:00
2022-10-03 19:49:08 +00:00
if ( sop - > spin_speed > = nullAngle )
sop - > spin_speed = - sop - > spin_speed ;
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_BOB_START :
2022-09-03 22:08:01 +00:00
sop - > bob_amt = 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 ;
2022-09-03 22:08:01 +00:00
sop - > bob_amt = 2 ;
2015-05-19 21:54:34 +00:00
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-09-03 19:36:47 +00:00
sop - > orig [ sop - > num_walls ] = sop - > pmid - wal . pos ;
2015-05-19 21:54:34 +00:00
sop - > num_walls + + ;
}
}
2022-09-03 19:36:47 +00:00
ASSERT ( ( uint16_t ) sop - > num_walls < SIZ ( sop - > orig ) ) ;
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-10-19 15:41:50 +00:00
dist = Distance ( ( tpoint + j ) - > pos , sop - > pmid ) ;
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-09-30 11:51:37 +00:00
sop - > ang = ( ( tpoint + sop - > point ) - > pos - sop - > pmid ) . Angle ( ) ;
2022-10-03 20:18:48 +00:00
sop - > ang_moving = sop - > ang_tgt = sop - > ang ;
2015-05-19 21:54:34 +00:00
}
}
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 ;
2022-09-03 22:12:57 +00:00
actor - > norm_ang ( ) ;
2015-05-19 21:54:34 +00:00
// if facing left go backward
2022-09-03 22:12:57 +00:00
if ( actor - > spr . angle > DAngle90 & & actor - > spr . angle < DAngle270 )
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
}
2022-09-03 22:12:57 +00:00
actor - > user . track_vel = int ( actor - > vel . X * 4096 ) ;
2021-12-26 00:30:29 +00:00
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-10-19 15:41:50 +00:00
dist = Distance ( ( tpoint + j ) - > pos , actor - > spr . pos ) ;
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-09-30 11:51:37 +00:00
actor - > spr . angle = ( ( tpoint + actor - > user . point ) - > pos - actor - > spr . pos ) . Angle ( ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-03 21:21:36 +00:00
void MovePlayer ( PLAYER * pp , SECTOR_OBJECT * sop , const DVector2 & move )
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-09-01 16:50:28 +00:00
pp - > Revolve . XY ( ) = pp - > pos . XY ( ) ;
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-09-03 21:21:36 +00:00
pp - > pos + = move ;
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-09-01 16:50:28 +00:00
pp - > Revolve . XY ( ) = pp - > pos . XY ( ) ;
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
2022-09-03 21:21:36 +00:00
pp - > Revolve + = move ;
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-09-01 16:50:28 +00:00
pp - > pos . XY ( ) = rotatepoint ( sop - > pmid . XY ( ) , pp - > Revolve . XY ( ) , 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 ) ;
}
2022-10-03 20:21:41 +00:00
void MovePoints ( SECTOR_OBJECT * sop , DAngle deltaangle , const DVector2 & move )
2015-05-19 21:54:34 +00:00
{
2021-11-24 21:04:11 +00:00
int j ;
int pnum ;
2021-12-31 14:59:11 +00:00
PLAYER * pp ;
2022-02-01 18:41:58 +00:00
sectortype * * sectp ;
2022-10-03 20:21:41 +00:00
int i ;
DAngle 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-09-03 21:21:36 +00:00
sop - > pmid + = move ;
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 ( ) ;
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
}
2022-10-03 20:21:41 +00:00
rot_ang = deltaangle ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_LOOP_REVERSE_SPIN ) )
2022-10-03 20:21:41 +00:00
rot_ang = - deltaangle ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_LOOP_SPIN_2X ) )
2022-10-03 20:21:41 +00:00
rot_ang = ( rot_ang * 2 ) . Normalized360 ( ) ;
2015-05-19 21:54:34 +00:00
2021-12-29 05:53:36 +00:00
if ( ( wal . extra & WALLFX_LOOP_SPIN_4X ) )
2022-10-03 20:21:41 +00:00
rot_ang = ( rot_ang * 4 ) . Normalized360 ( ) ;
2015-05-19 21:54:34 +00:00
2022-10-03 20:21:41 +00:00
auto vec = rotatepoint ( pivot , wal . pos , 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 )
2022-09-03 21:21:36 +00:00
MovePlayer ( pp , sop , move ) ;
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 * 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 )
2022-09-03 21:21:36 +00:00
MovePlayer ( pp , sop , move ) ;
2015-05-19 21:54:34 +00:00
}
}
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-09-01 17:28:33 +00:00
auto oldang = actor - > spr . angle ;
actor - > spr . angle = 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-09-01 17:28:33 +00:00
actor - > user . oangdiff + = : : deltaangle ( oldang , actor - > spr . angle ) ;
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-09-03 22:12:57 +00:00
updatesector ( pp - > pos , & 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
}
}
}
2022-09-03 21:21:36 +00:00
void RefreshPoints ( SECTOR_OBJECT * sop , const DVector2 & move , bool dynamic )
2015-05-19 21:54:34 +00:00
{
2022-10-03 20:28:37 +00:00
short wallcount = 0 ;
DAngle delta_ang_from_orig ;
2015-05-19 21:54:34 +00:00
// 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-09-03 20:32:29 +00:00
DVector2 pos = sop - > pmid . XY ( ) - sop - > orig [ wallcount ] ;
DVector2 dpos = pos ;
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-09-30 11:51:37 +00:00
auto ang = ( pos - sop - > pmid ) . Angle ( ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > scale_type = = SO_SCALE_RANDOM_POINT )
{
// was causing memory overwrites
2022-09-03 20:32:29 +00:00
dpos = ScaleRandomPoint ( sop , wallcount , ang , pos ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-09-03 20:57:07 +00:00
double xmul = ( sop - > scale_dist * sop - > scale_x_mult ) * ( 1 / 256. ) ;
double ymul = ( sop - > scale_dist * sop - > scale_y_mult ) * ( 1 / 256. ) ;
2015-05-19 21:54:34 +00:00
2022-09-03 20:37:18 +00:00
dpos . X = pos . X + xmul * ang . Cos ( ) ;
dpos . Y = pos . Y + ymul * ang . Sin ( ) ;
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
{
2022-09-03 20:32:29 +00:00
dragpoint ( & wal , dpos ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-09-03 20:32:29 +00:00
wal . move ( dpos ) ;
2015-05-19 21:54:34 +00:00
}
}
wallcount + + ;
}
}
}
2022-10-03 20:28:37 +00:00
if ( sop - > spin_speed ! = nullAngle )
2015-05-19 21:54:34 +00:00
{
// same as below - ignore the objects angle
// last_ang is the last true angle before SO started spinning
2022-10-03 20:28:37 +00:00
delta_ang_from_orig = ( sop - > last_ang + sop - > spin_ang - sop - > ang_orig ) . Normalized360 ( ) ;
2015-05-19 21:54:34 +00:00
}
else
{
// angle traveling + the new spin angle all offset from the original
// angle
2022-10-03 20:28:37 +00:00
delta_ang_from_orig = ( sop - > ang + sop - > spin_ang - sop - > ang_orig ) . Normalized360 ( ) ;
2015-05-19 21:54:34 +00:00
}
// Note that this delta angle is from the original angle
// nx,ny are 0 so the points are not moved, just rotated
2022-09-03 21:21:36 +00:00
2022-10-03 20:28:37 +00:00
MovePoints ( sop , delta_ang_from_orig , move ) ;
2015-05-19 21:54:34 +00:00
// 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
}
2022-09-03 22:12:57 +00:00
void CollapseSectorObject ( SECTOR_OBJECT * sop , const DVector2 & pos )
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
{
2022-09-03 22:12:57 +00:00
dragpoint ( & wal , pos ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-09-03 22:12:57 +00:00
wal . move ( pos ) ;
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 ;
2022-09-03 22:08:01 +00:00
sop - > bob_diff = sop - > bob_amt * BobVal ( sop - > bob_sine_ndx ) ;
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-09-03 22:08:01 +00:00
( * sectp ) - > setfloorz ( 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-09-03 22:00:53 +00:00
AnimSet ( ANIM_Floorz , * sectp , sop - > zorig_floor [ i ] + sop - > z_tgt , 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-09-03 22:00:53 +00:00
AnimSet ( ANIM_Floorz , * sectp , sop - > zorig_floor [ i ] + sop - > z_tgt , 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-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 ) ;
2022-09-03 21:21:36 +00:00
RefreshPoints ( sop , DVector2 ( 0 , 0 ) , false ) ;
2015-05-19 21:54:34 +00:00
}
return ;
}
// if pausing the return
if ( sop - > wait_tics )
{
sop - > wait_tics - = locktics ;
if ( sop - > wait_tics < = 0 )
sop - > wait_tics = 0 ;
return ;
}
2022-10-03 20:12:16 +00:00
auto delta_ang = nullAngle ;
2015-05-19 21:54:34 +00:00
2022-09-03 21:21:36 +00:00
DVector2 npos ( 0 , 0 ) ;
2015-05-19 21:54:34 +00:00
if ( sop - > track > - 1 )
2022-09-03 21:21:36 +00:00
npos = DoTrack ( sop , locktics ) ;
2015-05-19 21:54:34 +00:00
// get delta to target angle
2022-10-03 20:12:16 +00:00
delta_ang = deltaangle ( sop - > ang , sop - > ang_tgt ) ;
// If we do not truncate precision here, some SOs will misbehave, most notably the boat in MAP 5.
delta_ang = DAngle : : fromBuild ( ( delta_ang . Buildang ( ) > > sop - > turn_speed ) ) ;
sop - > ang = ( sop - > ang + delta_ang ) . Normalized360 ( ) ;
2015-05-19 21:54:34 +00:00
// move z values
MoveZ ( sop ) ;
// calculate the spin speed
2022-10-03 20:12:16 +00:00
auto speed = sop - > spin_speed * locktics ;
2015-05-19 21:54:34 +00:00
// spin_ang is incremented by the spin_speed
2022-10-03 20:12:16 +00:00
sop - > spin_ang = ( sop - > spin_ang + speed ) . Normalized360 ( ) ;
2015-05-19 21:54:34 +00:00
2022-10-03 20:12:16 +00:00
if ( sop - > spin_speed ! = nullAngle )
2015-05-19 21:54:34 +00:00
{
// ignore delta angle if spinning
2022-10-03 20:12:16 +00:00
GlobSpeedSO = speed ;
2015-05-19 21:54:34 +00:00
}
else
{
// The actual delta from the last frame
2022-10-03 20:12:16 +00:00
GlobSpeedSO = 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
2022-09-03 21:21:36 +00:00
RefreshPoints ( sop , npos , 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 | |
2022-10-03 20:12:16 +00:00
( 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 ) ;
2022-09-03 21:21:36 +00:00
RefreshPoints ( sop , npos , false ) ;
2015-05-19 21:54:34 +00:00
}
}
}
2022-09-03 21:21:36 +00:00
DVector2 DoTrack ( SECTOR_OBJECT * sop , short locktics )
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-09-30 11:51:37 +00:00
sop - > ang_moving = sop - > ang_tgt = ( tpoint - > pos - sop - > pmid ) . Angle ( ) ;
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 :
2022-10-03 20:08:14 +00:00
if ( sop - > spin_speed ! = nullAngle )
2015-05-19 21:54:34 +00:00
break ;
2022-09-11 11:47:47 +00:00
sop - > spin_speed = mapangle ( tpoint - > tag_high ) ;
2022-10-03 20:08:14 +00:00
sop - > last_ang = sop - > ang ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_SPIN_REVERSE :
{
2022-10-03 20:08:14 +00:00
if ( sop - > spin_speed = = nullAngle )
2015-05-19 21:54:34 +00:00
break ;
2022-10-03 20:08:14 +00:00
if ( sop - > spin_speed > = nullAngle )
2015-05-19 21:54:34 +00:00
{
2022-10-03 20:08:14 +00:00
sop - > spin_speed = - sop - > spin_speed ;
2015-05-19 21:54:34 +00:00
}
}
break ;
case TRACK_SPIN_STOP :
2022-10-03 20:08:14 +00:00
if ( sop - > spin_speed = = nullAngle )
2015-05-19 21:54:34 +00:00
break ;
2022-10-03 20:08:14 +00:00
sop - > spin_speed = nullAngle ;
2015-05-19 21:54:34 +00:00
break ;
case TRACK_BOB_START :
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZMID_FLOOR ) ;
2022-09-03 22:08:01 +00:00
sop - > bob_amt = tpoint - > tag_high ;
2015-05-19 21:54:34 +00:00
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 ;
2022-10-03 19:43:55 +00:00
sop - > save_spin_speed = sop - > spin_speed ;
2015-05-19 21:54:34 +00:00
2022-10-03 19:00:26 +00:00
sop - > vel = 0 ;
2022-10-03 20:12:16 +00:00
sop - > spin_speed = nullAngle ;
2015-05-19 21:54:34 +00:00
// 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 :
2022-09-03 22:02:00 +00:00
sop - > z_rate = Z ( tpoint - > tag_high ) ; // looks like a bug. z_rate is pixel based.
2015-05-19 21:54:34 +00:00
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 )
{
2022-09-03 22:00:53 +00:00
sop - > z_tgt + = tpoint - > tag_high ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZDOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-09-03 22:00:53 +00:00
sop - > z_tgt - = 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 )
{
2022-09-03 22:00:53 +00:00
sop - > z_tgt + = tpoint - > tag_high ;
2021-12-27 16:22:41 +00:00
sop - > flags | = ( SOBJ_ZDOWN ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2022-09-03 22:00:53 +00:00
sop - > z_tgt - = 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-09-30 11:51:37 +00:00
sop - > ang_moving = sop - > ang_tgt = ( tpoint - > pos - sop - > pmid ) . Angle ( ) ;
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
2022-10-19 15:41:50 +00:00
sop - > z_rate = ( int ) abs ( ( sop - > vel * maptoworld * ( 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
{
2022-09-03 21:21:36 +00:00
DVector2 n ;
2022-10-03 20:12:16 +00:00
// The truncation here is needed. There still seems to be code that depends on integers for these
n . X = int ( ( ( sop - > vel ) > > 8 ) * locktics * sop - > ang_moving . Cos ( ) ) * inttoworld ;
n . Y = int ( ( ( sop - > vel ) > > 8 ) * locktics * sop - > ang_moving . Sin ( ) ) * inttoworld ;
2015-05-19 21:54:34 +00:00
2022-09-03 21:21:36 +00:00
sop - > target_dist - = n . Length ( ) ;
return n ;
2015-05-19 21:54:34 +00:00
}
2022-09-03 21:21:36 +00:00
return { 0 , 0 } ;
2015-05-19 21:54:34 +00:00
}
2022-10-03 20:18:48 +00:00
void OperateSectorObjectForTics ( SECTOR_OBJECT * sop , DAngle newang , const DVector2 & pos , int 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 ;
2022-09-03 22:08:01 +00:00
sop - > bob_diff = sop - > bob_amt * BobVal ( sop - > bob_sine_ndx ) ;
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-09-03 22:08:01 +00:00
( * sectp ) - > setfloorz ( 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
2022-10-03 20:18:48 +00:00
//sop->ang_tgt = newang;
sop - > ang_moving = newang ;
2015-05-19 21:54:34 +00:00
2022-10-03 20:12:16 +00:00
sop - > spin_ang = nullAngle ;
2022-10-03 20:18:48 +00:00
sop - > ang = newang ;
2015-05-19 21:54:34 +00:00
2022-09-03 21:21:36 +00:00
RefreshPoints ( sop , pos - sop - > pmid . XY ( ) , false ) ;
2015-05-19 21:54:34 +00:00
}
2022-09-03 21:41:31 +00:00
void OperateSectorObject ( SECTOR_OBJECT * sop , DAngle newang , const DVector2 & pos )
2020-05-01 11:29:12 +00:00
{
2022-10-03 20:18:48 +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-09-03 21:21:36 +00:00
RefreshPoints ( sop , pos - sop - > pmid . XY ( ) , 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 :
2022-09-09 16:32:42 +00:00
if ( actor - > native_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
{
2022-10-03 20:05:33 +00:00
DAngle delta_ang , speed ;
2015-05-19 21:54:34 +00:00
short locktics = synctics ;
// get delta to target angle
2022-10-03 20:05:33 +00:00
delta_ang = deltaangle ( sop - > ang , sop - > ang_tgt ) ;
2015-05-19 21:54:34 +00:00
2022-10-03 20:05:33 +00:00
sop - > ang = ( sop - > ang + ( delta_ang / ( 1 < < sop - > turn_speed ) ) ) . Normalized360 ( ) ;
delta_ang / = 1 < < sop - > turn_speed ;
2015-05-19 21:54:34 +00:00
// move z values
MoveZ ( sop ) ;
// calculate the spin speed
2022-10-03 20:05:33 +00:00
speed = sop - > spin_speed * locktics ;
2015-05-19 21:54:34 +00:00
// spin_ang is incremented by the spin_speed
2022-10-03 20:05:33 +00:00
sop - > spin_ang = sop - > spin_ang + speed ;
2015-05-19 21:54:34 +00:00
2022-10-03 20:05:33 +00:00
if ( sop - > spin_speed ! = nullAngle )
2015-05-19 21:54:34 +00:00
{
// ignore delta angle if spinning
2022-10-03 20:05:33 +00:00
GlobSpeedSO = speed ;
2015-05-19 21:54:34 +00:00
}
else
{
// The actual delta from the last frame
2022-10-03 20:05:33 +00:00
GlobSpeedSO = 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 ret ;
2022-10-03 20:05:33 +00:00
DAngle & ang = sop - > ang_moving ;
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-09-03 21:21:36 +00:00
double floor_dist = ( abs ( cursect - > ceilingz - cursect - > floorz ) ) * 0.25 ;
DVector3 pos ( sop - > pmid . XY ( ) , 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 ;
2022-10-03 20:05:33 +00:00
auto vect = ang . ToVector ( ) * sop - > vel ; // vel is still in Build coordinates.
int xvect = vect . X * 16384 ;
int yvect = vect . Y * 16384 ;
2022-09-08 14:42:55 +00:00
clipmove ( pos , & cursect , xvect , yvect , ( int ) sop - > clipdist , 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
{
2022-09-04 22:04:29 +00:00
ang = ang + DAngle180 - DAngle45 + RandomAngle ( 90 ) ;
2015-05-19 21:54:34 +00:00
}
TornadoSpin ( sop ) ;
2022-09-03 21:21:36 +00:00
RefreshPoints ( sop , pos - sop - > pmid . XY ( ) , 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 ;
2022-10-03 20:08:14 +00:00
DAngle delta_ang ;
2022-08-27 06:04:55 +00:00
DAngle diff ;
2015-05-19 21:54:34 +00:00
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 )
{
2022-10-03 20:08:14 +00:00
for ( int 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
{
2022-10-03 20:08:14 +00:00
for ( int i = 0 ; sop - > so_actors [ i ] ! = nullptr ; i + + )
2021-11-02 17:45:21 +00:00
{
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-09-30 11:51:37 +00:00
sop - > ang_tgt = ( actor - > user . targetActor - > spr . pos - sop - > pmid ) . Angle ( ) ;
2015-05-19 21:54:34 +00:00
// get delta to target angle
2022-10-03 20:08:14 +00:00
delta_ang = deltaangle ( sop - > ang , sop - > ang_tgt ) ;
2015-05-19 21:54:34 +00:00
2022-10-03 20:08:14 +00:00
sop - > ang + = delta_ang * 0.125 ;
2015-05-19 21:54:34 +00:00
2022-08-27 06:04:55 +00:00
if ( sop - > limit_ang_center > = nullAngle )
2015-05-19 21:54:34 +00:00
{
2022-10-03 20:08:14 +00:00
diff = deltaangle ( sop - > limit_ang_center , 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 )
2022-10-03 20:08:14 +00:00
sop - > ang = ( sop - > limit_ang_center - sop - > limit_ang_delta ) ;
2015-05-19 21:54:34 +00:00
else
2022-10-03 20:08:14 +00:00
sop - > ang = ( sop - > limit_ang_center + sop - > limit_ang_delta ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-10-03 20:18:48 +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 ;
2022-09-30 11:51:37 +00:00
actor - > spr . angle = ( tp - > pos - actor - > spr . pos ) . Angle ( ) ;
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 ;
2022-09-30 11:51:37 +00:00
actor - > spr . angle = ( tp - > pos - actor - > spr . pos ) . Angle ( ) ;
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 ) ;
2022-09-04 15:23:34 +00:00
actor - > user . Dist = tpoint - > tag_high * maptoworld ;
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 ) ;
2022-09-04 15:23:34 +00:00
actor - > user . Dist = tpoint - > tag_high * maptoworld ;
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-09-03 22:12:57 +00:00
FAFhitscan ( actor - > spr . pos . plusZ ( - 24 ) , actor - > sector ( ) , DVector3 ( actor - > spr . angle . ToVector ( ) * 1024 , 0 ) , 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-09-03 22:12:57 +00:00
zdiff = ( int ) abs ( actor - > spr . pos . Z - hit . hitWall - > nextSector ( ) - > floorz ) ;
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 :
{
2022-09-01 21:21:26 +00:00
HitInfo near { } ;
2022-08-31 17:18:21 +00:00
double z [ 2 ] ;
2015-05-19 21:54:34 +00:00
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-31 17:18:21 +00:00
z [ 0 ] = actor - > spr . pos . Z - ActorSizeZ ( actor ) + 5 ;
z [ 1 ] = actor - > spr . pos . Z - ( ActorSizeZ ( actor ) * 0.5 ) ;
2015-05-19 21:54:34 +00:00
2022-08-31 17:18:21 +00:00
for ( auto & zz : z )
2015-05-19 21:54:34 +00:00
{
2022-09-25 08:57:46 +00:00
neartag ( DVector3 ( actor - > spr . pos . XY ( ) , zz ) , actor - > sector ( ) , actor - > spr . angle , near , 64. , NT_Lotag | NT_Hitag ) ;
2015-05-19 21:54:34 +00:00
2022-09-25 08:57:46 +00:00
if ( near . actor ( ) ! = nullptr )
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-09-25 08:57:46 +00:00
if ( near . hitSector ! = nullptr )
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 ) ;
2022-09-03 08:04:16 +00:00
actor - > vel . X * = 2 ;
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 ;
2022-09-03 08:02:25 +00:00
actor - > vel . Z = 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
{
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-09-03 22:12:57 +00:00
auto vec = lActor - > spr . angle . ToVector ( ) * 6.25 ;
2015-05-19 21:54:34 +00:00
2022-09-03 22:12:57 +00:00
actor - > spr . pos . XY ( ) = lActor - > spr . pos . XY ( ) + vec ;
2015-05-19 21:54:34 +00:00
2022-08-29 17:34:34 +00:00
actor - > spr . angle + = DAngle180 ;
2015-05-19 21:54:34 +00:00
//
// Get the z height to climb
//
2022-08-29 17:34:34 +00:00
double z = ActorZOfTop ( actor ) - ( ActorSizeZ ( actor ) * 0.5 ) ;
2022-09-25 08:57:46 +00:00
neartag ( DVector3 ( actor - > spr . pos . XY ( ) , z ) , actor - > sector ( ) , actor - > spr . angle , near , 37.5 , NT_Lotag | NT_Hitag | NT_NoSpriteCheck ) ;
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
2022-09-08 14:42:55 +00:00
actor - > vel . 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-30 22:47:02 +00:00
DVector3 vec ( 0 , 0 , 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-09-04 15:23:34 +00:00
if ( ( actor - > spr . pos . XY ( ) - pp - > pos . XY ( ) ) . Length ( ) < 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-09-30 11:51:37 +00:00
actor - > spr . angle = ( tpoint - > pos - actor - > spr . pos ) . Angle ( ) ;
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-09-30 11:51:37 +00:00
actor - > spr . angle = ( tpoint - > pos - actor - > spr . pos ) . Angle ( ) ;
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-09-03 22:12:57 +00:00
actor - > vel . Z = - ( ( actor - > vel . Z * ( 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
2022-09-03 22:12:57 +00:00
actor - > vel . X = actor - > user . track_vel / 4096. ;
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
}
2022-09-03 22:12:57 +00:00
actor - > vel . X = actor - > user . track_vel / 4096. ;
2015-05-19 21:54:34 +00:00
}
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
2022-09-03 08:02:25 +00:00
actor - > vel . Z = 0 ;
2015-05-19 21:54:34 +00:00
2022-09-30 11:51:37 +00:00
actor - > spr . angle = ( tpoint - > pos - actor - > spr . pos ) . Angle ( ) ;
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-09-03 08:03:30 +00:00
vec . XY ( ) = actor - > spr . angle . ToVector ( ) * actor - > vel . X ;
2015-05-19 21:54:34 +00:00
}
2022-09-03 08:03:30 +00:00
if ( actor - > vel . Z ! = 0 )
vec . Z = actor - > vel . Z * locktics ;
2015-05-19 21:54:34 +00:00
}
2022-08-30 22:47:02 +00:00
actor - > user . coll = move_sprite ( actor , vec , actor - > user . ceiling_dist , actor - > user . 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