2020-05-15 20:59:13 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 1996 , 2003 - 3 D Realms Entertainment
Copyright ( C ) 2000 , 2003 - Matt Saettler ( EDuke Enhancements )
Copyright ( C ) 2020 - Christoph Oelckers
This file is part of Enhanced Duke Nukem 3 D version 1.5 - Atomic Edition
Duke Nukem 3 D is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
Original Source : 1996 - Todd Replogle
Prepared for public release : 03 / 21 / 2003 - Charlie Wiederhold , 3 D Realms
EDuke enhancements integrated : 04 / 13 / 2003 - Matt Saettler
Note : EDuke source was in transition . Changes are in - progress in the
source as it is released .
*/
//-------------------------------------------------------------------------
# include <utility>
# include "ns.h"
# include "global.h"
2020-06-24 19:21:02 +00:00
# include "sounds.h"
2020-09-06 10:44:58 +00:00
# include "automap.h"
2020-10-21 17:38:53 +00:00
# include "dukeactor.h"
2020-11-26 15:03:40 +00:00
# include "interpolate.h"
2022-12-17 14:55:01 +00:00
# include "vm.h"
2020-05-15 20:59:13 +00:00
BEGIN_DUKE_NS
2020-10-24 07:40:10 +00:00
2022-11-24 06:42:17 +00:00
void setFromSpawnRec ( DDukeActor * act , SpawnRec * info )
{
2022-12-21 12:32:00 +00:00
act - > curMove = & moves [ 0 ] ;
2022-12-21 12:20:14 +00:00
act - > curAction = & actions [ 0 ] ;
2022-11-24 06:42:17 +00:00
if ( info )
{
2022-12-31 16:58:14 +00:00
if ( info - > basetex . isValid ( ) & & act - > IsKindOf ( DukeGenericDestructibleClass ) )
2022-11-24 06:42:17 +00:00
{
// allow defining simple destructibles without actual actor definitions.
2022-12-31 16:58:14 +00:00
act - > IntVar ( NAME_spawnstate ) = info - > basetex . GetIndex ( ) ;
act - > IntVar ( NAME_brokenstate ) = info - > brokentex . GetIndex ( ) ;
2022-12-04 12:09:47 +00:00
act - > IntVar ( NAME_breaksound ) = info - > breaksound . index ( ) ;
2022-11-25 19:54:51 +00:00
act - > IntVar ( NAME_fullbright ) = info - > fullbright ;
2022-11-24 06:43:05 +00:00
act - > spr . inittype = info - > flags ;
if ( info - > clipdist > 0 ) act - > spr . clipdist = info - > clipdist ;
2022-11-24 06:42:17 +00:00
}
2022-12-03 14:01:21 +00:00
else
{
2022-12-21 12:20:14 +00:00
// same for simple sprite replacements with existing implementations.
2022-12-31 16:58:14 +00:00
if ( info - > basetex . isValid ( ) ) act - > spr . setspritetexture ( info - > basetex ) ;
2022-12-03 14:01:21 +00:00
if ( info - > fullbright & 1 ) act - > spr . cstat2 | = CSTAT2_SPRITE_FULLBRIGHT ;
}
2022-11-24 06:42:17 +00:00
}
}
2020-05-15 21:46:18 +00:00
//---------------------------------------------------------------------------
//
2022-02-12 11:37:27 +00:00
// this creates a new actor but does not run any init code on it
// direct calls should only be done for very simple things.
2020-05-15 21:46:18 +00:00
//
//---------------------------------------------------------------------------
2022-12-30 20:53:46 +00:00
DDukeActor * CreateActor ( sectortype * whatsectp , const DVector3 & pos , PClassActor * clstype , int8_t s_shd , const DVector2 & scale , DAngle s_ang , double s_vel , double s_zvel , DDukeActor * s_ow , int8_t s_stat )
2020-05-15 21:46:18 +00:00
{
2021-11-19 08:47:17 +00:00
// sector pointer must be strictly validated here or the engine will crash.
2022-11-15 11:03:44 +00:00
if ( whatsectp = = nullptr | | ! validSectorIndex ( sectindex ( whatsectp ) ) ) return nullptr ;
2022-08-26 18:05:28 +00:00
// spawning out of range sprites will also crash.
2022-12-30 20:53:46 +00:00
if ( clstype = = nullptr ) return nullptr ;
2022-11-14 09:30:59 +00:00
2022-12-21 09:54:02 +00:00
if ( s_stat < 0 ) s_stat = clstype ? GetDefaultByType ( clstype ) - > spr . statnum : 0 ;
2022-01-16 23:51:40 +00:00
2022-11-14 09:30:59 +00:00
auto act = static_cast < DDukeActor * > ( InsertActor ( clstype ? clstype : RUNTIME_CLASS ( DDukeActor ) , whatsectp , s_stat ) ) ;
2021-12-04 21:04:16 +00:00
if ( act = = nullptr ) return nullptr ;
2021-12-05 12:43:31 +00:00
SetupGameVarsForActor ( act ) ;
2022-12-31 18:56:41 +00:00
setFromSpawnRec ( act , nullptr ) ;
2022-11-24 06:42:17 +00:00
act - > spr . pos = pos ;
2022-09-14 18:10:41 +00:00
act - > spr . shade = s_shd ;
2022-11-15 09:17:23 +00:00
if ( ! scale . isZero ( ) ) act - > spr . scale = DVector2 ( scale . X , scale . Y ) ;
2021-12-21 20:57:23 +00:00
2022-11-25 12:13:50 +00:00
act - > spr . Angles . Yaw = s_ang ;
2022-09-14 18:10:41 +00:00
act - > vel . X = s_vel ;
act - > vel . Z = s_zvel ;
2021-12-30 16:10:08 +00:00
act - > backuploc ( ) ;
2020-05-15 21:46:18 +00:00
2022-01-23 23:10:25 +00:00
act - > hitextra = - 1 ;
2020-11-02 20:21:52 +00:00
act - > SetHitOwner ( s_ow ) ;
act - > SetOwner ( s_ow ) ;
if ( s_ow )
{
2022-12-16 15:56:47 +00:00
act - > attackertype = static_cast < PClassActor * > ( s_ow - > GetClass ( ) ) ;
2022-02-03 23:44:13 +00:00
act - > floorz = s_ow - > floorz ;
act - > ceilingz = s_ow - > ceilingz ;
2020-11-02 20:21:52 +00:00
}
2020-11-02 20:37:37 +00:00
else
{
}
2020-11-02 20:21:52 +00:00
2020-10-24 05:34:54 +00:00
memset ( act - > temp_data , 0 , sizeof ( act - > temp_data ) ) ;
2022-12-21 21:36:15 +00:00
auto coninf = act - > conInfo ( ) ;
if ( coninf )
2020-05-15 21:46:18 +00:00
{
2022-12-21 21:36:15 +00:00
auto sa = & ScriptCode [ coninf - > scriptaddress ] ;
2022-12-21 12:20:14 +00:00
act - > curAction = & actions [ sa [ 1 ] ] ;
2022-12-21 12:32:00 +00:00
act - > curMove = & moves [ sa [ 2 ] ] ;
2021-12-21 20:57:23 +00:00
act - > spr . hitag = sa [ 3 ] ;
2022-12-23 09:36:07 +00:00
// remove script info if it is completely empty and no animation is set.
if ( act - > curAction - > name = = NAME_Name & & act - > curMove - > name = = NAME_Name & & * sa = = concmd_enda )
{
sa = nullptr ;
}
2020-05-15 21:46:18 +00:00
}
else
{
2021-12-21 20:57:23 +00:00
act - > spr . hitag = 0 ;
2020-05-15 21:46:18 +00:00
}
2022-12-21 21:06:34 +00:00
act - > spr . extra = act - > IntVar ( NAME_strength ) ;
2020-05-15 21:46:18 +00:00
2021-12-30 15:39:43 +00:00
if ( show2dsector [ act - > sectno ( ) ] ) act - > spr . cstat2 | = CSTAT2_SPRITE_MAPPED ;
2021-12-21 17:19:45 +00:00
else act - > spr . cstat2 & = ~ CSTAT2_SPRITE_MAPPED ;
2020-05-15 21:46:18 +00:00
2020-11-02 20:21:52 +00:00
return act ;
2022-11-13 17:55:32 +00:00
2020-05-15 21:46:18 +00:00
}
2022-11-15 09:17:23 +00:00
DDukeActor * SpawnActor ( sectortype * whatsectp , const DVector3 & pos , PClassActor * cls , int8_t s_shd , const DVector2 & scale , DAngle s_ang , double s_vel , double s_zvel , DDukeActor * s_ow , int8_t s_stat )
2022-01-16 23:51:40 +00:00
{
2022-11-15 09:17:23 +00:00
auto actor = CreateActor ( whatsectp , pos , cls , s_shd , scale , s_ang , s_vel , s_zvel , s_ow , s_stat ) ;
2022-12-23 09:36:07 +00:00
if ( actor )
{
actor - > flags3 | = SFLAG3_SIMPLEINIT ; // at this point we only want to run custom Initialize code, but not the default for scripted actors, even if this one has scripts.
spawninit ( s_ow , actor , nullptr ) ;
actor - > flags3 & = ~ SFLAG3_SIMPLEINIT ; // from now on act normally.
}
2022-01-16 23:51:40 +00:00
return actor ;
}
2020-05-15 20:59:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-01-19 08:41:48 +00:00
bool initspriteforspawn ( DDukeActor * act )
2020-05-15 20:59:13 +00:00
{
2022-01-24 22:05:22 +00:00
SetupGameVarsForActor ( act ) ;
2022-12-16 15:56:47 +00:00
act - > attackertype = static_cast < PClassActor * > ( act - > GetClass ( ) ) ;
2022-01-23 23:10:25 +00:00
act - > hitextra = - 1 ;
2020-10-24 05:34:54 +00:00
2021-12-30 16:10:08 +00:00
act - > backuppos ( ) ;
2020-10-24 05:34:54 +00:00
2021-11-19 09:41:50 +00:00
act - > SetOwner ( act ) ;
act - > SetHitOwner ( act ) ;
2022-02-03 23:44:13 +00:00
act - > floorz = act - > sector ( ) - > floorz ;
act - > ceilingz = act - > sector ( ) - > ceilingz ;
2020-10-24 05:34:54 +00:00
2022-12-10 19:14:39 +00:00
auto ext = GetExtInfo ( act - > spr . spritetexture ( ) ) ;
2022-12-10 22:40:58 +00:00
bool overrideswitch = false ;
2022-12-10 19:14:39 +00:00
2022-12-10 22:40:58 +00:00
// The STAT_FALLER code below would render any switch actor inoperable so we must also include everything that overrides TriggerSwitch,
// even if it got no other hint for being a switch. A bit dirty but it makes it unnecessary to explicitly mark such switches.
IFVIRTUALPTR ( act , DDukeActor , TriggerSwitch )
{
if ( func - > PrintableName . CompareNoCase ( " DukeActor.TriggerSwitch " ) ! = 0 )
overrideswitch = true ;
}
if ( act - > spr . cstat & CSTAT_SPRITE_ALIGNMENT_WALL & & ( wallswitchcheck ( act ) | | ext . switchindex > 0 | | overrideswitch ) )
2022-01-19 08:41:48 +00:00
{
2022-12-10 19:14:39 +00:00
// this is a bit more complicated than needed thanks to some bugs in the original code that must be retained for the multiplayer filter.
// Not all switches were properly included here.
bool shouldfilter = wallswitchcheck ( act ) | | ! ( switches [ ext . switchindex ] . flags & SwitchDef : : nofilter ) ;
if ( shouldfilter & & act - > spr . pal > 0 )
2021-11-19 09:41:50 +00:00
{
2022-01-19 08:41:48 +00:00
if ( ( ud . multimode < 2 ) | | ( ud . multimode > 1 & & ud . coop = = 1 ) )
2020-05-15 20:59:13 +00:00
{
2022-10-07 21:52:29 +00:00
act - > spr . scale = DVector2 ( 0 , 0 ) ;
2022-01-19 08:41:48 +00:00
act - > spr . cstat = 0 ;
act - > spr . lotag = act - > spr . hitag = 0 ;
2021-12-04 12:02:38 +00:00
return false ;
2021-11-19 09:41:50 +00:00
}
2022-12-10 19:14:39 +00:00
act - > spr . pal = 0 ;
2022-01-19 08:41:48 +00:00
}
act - > spr . cstat | = CSTAT_SPRITE_BLOCK_ALL ;
2022-12-10 22:40:58 +00:00
return true ;
2022-12-10 19:14:39 +00:00
2022-01-19 08:41:48 +00:00
}
2020-05-15 20:59:13 +00:00
2022-12-20 21:25:48 +00:00
if ( ! ( act - > flags1 & SFLAG_NOFALLER ) & & ( act - > spr . cstat & CSTAT_SPRITE_ALIGNMENT_MASK ) )
2022-01-19 08:41:48 +00:00
{
if ( act - > spr . shade = = 127 ) return false ;
if ( act - > spr . hitag )
{
ChangeActorStat ( act , STAT_FALLER ) ;
act - > spr . cstat | = CSTAT_SPRITE_BLOCK_ALL ;
act - > spr . extra = gs . impact_damage ;
return false ;
2021-11-19 09:41:50 +00:00
}
2022-01-19 08:41:48 +00:00
}
2021-11-19 09:41:50 +00:00
2021-12-21 20:57:23 +00:00
if ( act - > spr . cstat & CSTAT_SPRITE_BLOCK ) act - > spr . cstat | = CSTAT_SPRITE_BLOCK_HITSCAN ;
2020-05-15 20:59:13 +00:00
2022-12-21 21:06:34 +00:00
act - > spr . extra = act - > IntVar ( NAME_strength ) ;
2022-12-21 21:36:15 +00:00
auto coninf = act - > conInfo ( ) ;
if ( coninf )
2021-11-19 09:41:50 +00:00
{
2022-12-21 21:36:15 +00:00
auto sa = & ScriptCode [ coninf - > scriptaddress ] ;
act - > curAction = & actions [ sa [ 1 ] ] ;
act - > curMove = & moves [ sa [ 2 ] ] ;
2023-04-15 17:53:04 +00:00
int s3 = sa [ 3 ] ;
2021-12-21 20:57:23 +00:00
if ( s3 & & act - > spr . hitag = = 0 )
act - > spr . hitag = s3 ;
2021-11-19 09:41:50 +00:00
}
2021-12-04 12:02:38 +00:00
return true ;
2021-11-19 09:41:50 +00:00
}
2020-05-15 20:59:13 +00:00
2021-11-19 09:41:50 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-01-17 23:30:43 +00:00
DDukeActor * spawn ( DDukeActor * actj , PClassActor * cls )
{
2022-11-14 09:30:59 +00:00
if ( actj & & cls )
2022-01-17 23:30:43 +00:00
{
2022-11-14 09:30:59 +00:00
auto spawned = CreateActor ( actj - > sector ( ) , actj - > spr . pos , cls , 0 , DVector2 ( 0 , 0 ) , nullAngle , 0. , 0. , actj , 0 ) ;
2022-01-17 23:30:43 +00:00
if ( spawned )
{
2022-12-16 15:56:47 +00:00
spawned - > attackertype = static_cast < PClassActor * > ( actj - > GetClass ( ) ) ;
2022-12-15 09:46:41 +00:00
return spawninit ( actj , spawned , nullptr ) ;
2022-01-17 23:30:43 +00:00
}
}
return nullptr ;
}
2022-12-31 18:56:41 +00:00
//---------------------------------------------------------------------------
//
// This spawns an actor from a spawnclasses type ID.
//
//---------------------------------------------------------------------------
DDukeActor * spawnsprite ( DDukeActor * origin , int typeId )
{
auto srec = spawnMap . CheckKey ( typeId ) ;
if ( srec & & ! srec - > basetex . isValid ( ) ) return spawn ( origin , srec - > cls ) ;
PClassActor * cls = srec ? srec - > cls : ( PClassActor * ) RUNTIME_CLASS ( DDukeActor ) ;
auto spawned = spawn ( origin , cls ) ;
if ( ! spawned ) return nullptr ;
setFromSpawnRec ( spawned , srec ) ;
if ( ! srec ) spawned - > spr . setspritetexture ( tileGetTextureID ( typeId ) ) ;
return spawned ;
}
2022-12-19 17:45:27 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2023-04-12 18:06:25 +00:00
static void commonEnemySetup ( DDukeActor * self , DDukeActor * owner )
2022-12-19 17:45:27 +00:00
{
if ( ! self - > mapSpawned ) self - > spr . lotag = 0 ;
2023-04-10 14:48:08 +00:00
if ( gs . actorinfo [ self - > spr . picnum ] . scriptaddress ) // default scale only applies to actors with a CON part. Note: needs fixing later!
2022-12-19 17:45:27 +00:00
{
2023-04-10 14:48:08 +00:00
// Init the size. This is different for internal and user enemies.
self - > clipdist = 20 ;
if ( self - > flags1 & SFLAG_INTERNAL_BADGUY )
{
self - > spr . scale = DVector2 ( 0.625 , 0.625 ) ;
}
else if ( self - > spr . scale . X = = 0 | | self - > spr . scale . Y = = 0 )
{
self - > spr . scale = DVector2 ( REPEAT_SCALE , REPEAT_SCALE ) ;
}
2022-12-19 17:45:27 +00:00
}
2023-04-12 18:06:25 +00:00
makeitfall ( self ) ;
2022-12-19 17:45:27 +00:00
2023-04-12 18:06:25 +00:00
self - > spr . cstat | = CSTAT_SPRITE_BLOCK_ALL ;
2022-12-19 17:45:27 +00:00
2023-04-12 18:06:25 +00:00
addtokills ( self ) ;
2022-12-19 17:45:27 +00:00
2023-04-12 18:06:25 +00:00
self - > timetosleep = 0 ;
if ( ! self - > mapSpawned )
{
CallPlayFTASound ( self ) ;
ChangeActorStat ( self , STAT_ACTOR ) ;
if ( owner & & ! ( self - > flags1 & SFLAG_INTERNAL_BADGUY ) ) self - > spr . Angles . Yaw = owner - > spr . Angles . Yaw ;
2022-12-19 17:45:27 +00:00
}
2023-04-12 18:06:25 +00:00
else ChangeActorStat ( self , STAT_ZOMBIEACTOR ) ;
2022-12-19 17:45:27 +00:00
}
2020-05-15 20:59:13 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-12-04 12:02:38 +00:00
void spawneffector ( DDukeActor * actor , TArray < DDukeActor * > * actors )
2020-05-15 20:59:13 +00:00
{
2021-12-30 15:51:56 +00:00
auto sectp = actor - > sector ( ) ;
2022-09-11 22:56:23 +00:00
int clostest = 0 ;
2020-05-15 20:59:13 +00:00
2022-09-01 16:15:52 +00:00
actor - > spr . yint = sectp - > extra ;
2021-12-21 20:57:23 +00:00
actor - > spr . cstat | = CSTAT_SPRITE_INVISIBLE ;
2022-10-07 21:52:29 +00:00
actor - > spr . scale = DVector2 ( 0 , 0 ) ;
2020-05-15 20:59:13 +00:00
2021-12-21 20:57:23 +00:00
switch ( actor - > spr . lotag )
2020-05-15 20:59:13 +00:00
{
2020-11-01 08:00:16 +00:00
case SE_28_LIGHTNING :
2022-12-22 08:49:42 +00:00
if ( ! isRR ( ) ) actor - > temp_data [ 0 ] = 65 ; // Delay for lightning
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_7_TELEPORT : // Transporters!!!!
case SE_23_ONE_WAY_TELEPORT : // XPTR END
2021-12-21 20:57:23 +00:00
if ( actor - > spr . lotag ! = SE_23_ONE_WAY_TELEPORT & & actors )
2020-05-15 20:59:13 +00:00
{
2021-12-30 09:30:21 +00:00
2021-12-04 12:02:38 +00:00
for ( auto act2 : * actors )
{
2022-12-01 19:54:41 +00:00
if ( act2 - > spr . statnum < MAXSTATUS & & iseffector ( act2 ) & & ( act2 - > spr . lotag = = SE_7_TELEPORT | | act2 - > spr . lotag = = SE_23_ONE_WAY_TELEPORT ) & &
2021-12-21 20:57:23 +00:00
actor ! = act2 & & act2 - > spr . hitag = = actor - > spr . hitag )
2020-11-02 21:20:41 +00:00
{
actor - > SetOwner ( act2 ) ;
2020-05-15 20:59:13 +00:00
break ;
}
2021-12-04 12:02:38 +00:00
}
2020-11-02 21:20:41 +00:00
}
else actor - > SetOwner ( actor ) ;
2020-05-15 20:59:13 +00:00
2022-08-28 09:35:03 +00:00
actor - > temp_data [ 4 ] = sectp - > floorz = = actor - > spr . pos . Z ;
2021-12-21 20:57:23 +00:00
actor - > spr . cstat = 0 ;
2021-11-26 20:52:01 +00:00
ChangeActorStat ( actor , STAT_TRANSPORT ) ;
2020-05-15 20:59:13 +00:00
return ;
2020-11-01 08:00:16 +00:00
case SE_1_PIVOT :
2020-11-02 21:26:32 +00:00
actor - > SetOwner ( nullptr ) ;
2022-12-22 08:49:42 +00:00
actor - > counter = 1 ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_18_INCREMENTAL_SECTOR_RISE_FALL :
2020-05-15 20:59:13 +00:00
2022-08-22 17:32:51 +00:00
if ( actor - > spr . intangle = = 512 )
2020-05-15 20:59:13 +00:00
{
2022-08-22 17:32:51 +00:00
actor - > temp_data [ 1 ] = FloatToFixed < 8 > ( sectp - > ceilingz ) ;
2021-12-21 20:57:23 +00:00
if ( actor - > spr . pal )
2022-02-07 07:59:20 +00:00
sectp - > setceilingz ( actor - > spr . pos . Z ) ;
2020-05-15 20:59:13 +00:00
}
else
{
2022-08-22 17:32:51 +00:00
actor - > temp_data [ 1 ] = FloatToFixed < 8 > ( sectp - > floorz ) ;
2021-12-21 20:57:23 +00:00
if ( actor - > spr . pal )
2022-02-07 07:59:20 +00:00
sectp - > setfloorz ( actor - > spr . pos . Z ) ;
2020-05-15 20:59:13 +00:00
}
2021-12-21 20:57:23 +00:00
actor - > spr . hitag < < = 2 ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_19_EXPLOSION_LOWERS_CEILING :
2020-11-02 21:26:32 +00:00
actor - > SetOwner ( nullptr ) ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_25_PISTON : // Pistons
2022-09-12 21:35:48 +00:00
actor - > temp_pos . Z = sectp - > ceilingz ;
actor - > temp_data [ 4 ] = 1 ;
2022-02-07 07:59:20 +00:00
sectp - > setceilingz ( actor - > spr . pos . Z ) ;
2021-11-18 15:56:40 +00:00
StartInterpolation ( sectp , Interp_Sect_Ceilingz ) ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_35 :
2022-02-07 07:59:20 +00:00
sectp - > setceilingz ( actor - > spr . pos . Z ) ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_27_DEMO_CAM :
2020-05-15 20:59:13 +00:00
if ( ud . recstat = = 1 )
{
2022-10-07 21:52:29 +00:00
actor - > spr . scale = DVector2 ( 1 , 1 ) ;
2021-12-21 20:57:23 +00:00
actor - > spr . cstat & = ~ CSTAT_SPRITE_INVISIBLE ;
2020-05-15 20:59:13 +00:00
}
break ;
2020-11-01 08:00:16 +00:00
case SE_47_LIGHT_SWITCH :
case SE_48_LIGHT_SWITCH :
2020-05-15 20:59:13 +00:00
if ( ! isRRRA ( ) ) break ;
2021-11-14 11:25:25 +00:00
[[fallthrough]] ;
2020-11-01 08:00:16 +00:00
case SE_12_LIGHT_SWITCH :
2020-05-15 20:59:13 +00:00
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 1 ] = sectp - > floorshade ;
actor - > temp_data [ 2 ] = sectp - > ceilingshade ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_13_EXPLOSIVE :
2020-11-02 21:26:32 +00:00
{
2022-09-11 20:28:05 +00:00
actor - > temp_pos . Y = sectp - > ceilingz ;
actor - > temp_pos . Z = sectp - > floorz ;
2020-05-15 20:59:13 +00:00
2022-09-11 20:28:05 +00:00
bool ceiling = ( abs ( sectp - > ceilingz - actor - > spr . pos . Z ) < abs ( sectp - > floorz - actor - > spr . pos . Z ) ) ;
2020-11-02 21:39:41 +00:00
actor - > spriteextra = ceiling ;
2020-05-15 20:59:13 +00:00
2022-09-11 20:28:05 +00:00
if ( actor - > spr . intangle = = 512 )
2020-05-15 20:59:13 +00:00
{
2020-11-02 21:26:32 +00:00
if ( ceiling )
2022-02-07 07:59:20 +00:00
sectp - > setceilingz ( actor - > spr . pos . Z ) ;
2020-05-15 20:59:13 +00:00
else
2022-02-07 07:59:20 +00:00
sectp - > setfloorz ( actor - > spr . pos . Z ) ;
2020-05-15 20:59:13 +00:00
}
else
2021-12-27 21:32:26 +00:00
{
2022-02-07 07:59:20 +00:00
sectp - > setceilingz ( actor - > spr . pos . Z ) ;
sectp - > setfloorz ( actor - > spr . pos . Z ) ;
2021-12-27 21:32:26 +00:00
}
2020-05-15 20:59:13 +00:00
2021-12-18 12:14:56 +00:00
if ( sectp - > ceilingstat & CSTAT_SECTOR_SKY )
2020-05-15 20:59:13 +00:00
{
2021-12-18 12:23:08 +00:00
sectp - > ceilingstat ^ = CSTAT_SECTOR_SKY ;
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 3 ] = 1 ;
2020-05-15 20:59:13 +00:00
2022-09-11 20:28:05 +00:00
if ( ! ceiling & & actor - > spr . intangle = = 512 )
2020-05-15 20:59:13 +00:00
{
2021-12-18 12:23:08 +00:00
sectp - > ceilingstat ^ = CSTAT_SECTOR_SKY ;
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 3 ] = 0 ;
2020-05-15 20:59:13 +00:00
}
2021-11-06 23:11:17 +00:00
sectp - > ceilingshade =
sectp - > floorshade ;
2020-05-15 20:59:13 +00:00
2022-09-11 20:28:05 +00:00
if ( actor - > spr . intangle = = 512 )
2020-05-15 20:59:13 +00:00
{
2022-11-15 14:24:17 +00:00
for ( auto & wl : sectp - > walls )
2020-05-15 20:59:13 +00:00
{
2021-11-21 07:42:36 +00:00
if ( wl . twoSided ( ) )
2021-11-17 23:42:52 +00:00
{
auto nsec = wl . nextSector ( ) ;
2021-12-18 12:14:56 +00:00
if ( ! ( nsec - > ceilingstat & CSTAT_SECTOR_SKY ) )
2020-05-15 20:59:13 +00:00
{
2022-12-09 09:48:47 +00:00
sectp - > setceilingtexture ( nsec - > ceilingtexture ) ;
2021-11-17 23:42:52 +00:00
sectp - > ceilingshade = nsec - > ceilingshade ;
break ; //Leave early
2020-05-15 20:59:13 +00:00
}
2021-11-17 23:42:52 +00:00
}
2020-05-15 20:59:13 +00:00
}
}
}
break ;
2020-11-02 21:26:32 +00:00
}
2020-11-01 08:00:16 +00:00
case SE_17_WARP_ELEVATOR :
2020-11-02 21:20:41 +00:00
{
2022-09-14 19:04:07 +00:00
actor - > temp_pos . X = sectp - > floorz ; //Stopping loc
actor - > temp_pos . Y = nextsectorneighborzptr ( sectp , sectp - > floorz , Find_CeilingUp | Find_Safe ) - > ceilingz ;
actor - > temp_pos . Z = nextsectorneighborzptr ( sectp , sectp - > ceilingz , Find_FloorDown | Find_Safe ) - > floorz ;
2020-05-15 20:59:13 +00:00
if ( numplayers < 2 )
{
2021-11-18 15:56:40 +00:00
StartInterpolation ( sectp , Interp_Sect_Floorz ) ;
StartInterpolation ( sectp , Interp_Sect_Ceilingz ) ;
2020-05-15 20:59:13 +00:00
}
break ;
2020-11-02 21:20:41 +00:00
}
2020-11-26 15:03:40 +00:00
case 156 :
2021-04-07 16:12:25 +00:00
break ;
2020-11-26 15:03:40 +00:00
case 34 :
2021-11-18 15:56:40 +00:00
StartInterpolation ( sectp , Interp_Sect_FloorPanX ) ;
2020-11-26 15:03:40 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_24_CONVEYOR :
2021-11-18 15:56:40 +00:00
StartInterpolation ( sectp , Interp_Sect_FloorPanX ) ;
2022-09-01 16:15:52 +00:00
actor - > spr . yint < < = 1 ;
2020-11-01 08:00:16 +00:00
case SE_36_PROJ_SHOOTER :
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_20_STRETCH_BRIDGE :
2020-05-15 20:59:13 +00:00
{
2022-11-26 14:58:55 +00:00
auto FindDistance2D = [ ] ( int x , int y )
{
x = abs ( x ) ;
y = abs ( y ) ;
if ( x < y )
std : : swap ( x , y ) ;
int t = y + ( y > > 1 ) ;
return ( x - ( x > > 5 ) - ( x > > 7 ) + ( t > > 2 ) + ( t > > 6 ) ) ;
} ;
//find the two most closest wall x's and y's
2022-10-07 11:50:29 +00:00
for ( unsigned i = 0 ; i < 2 ; i + + )
2020-05-15 20:59:13 +00:00
{
2022-10-07 11:50:29 +00:00
walltype * closewall = nullptr ;
2022-11-26 14:58:55 +00:00
int maxdist = 0x7fffffff ;
2022-10-07 11:50:29 +00:00
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2020-05-15 20:59:13 +00:00
{
2022-11-26 14:58:55 +00:00
int x = int ( actor - > spr . pos . X - wal . pos . X ) * 16 ;
int y = int ( actor - > spr . pos . Y - wal . pos . Y ) * 16 ;
int dist = FindDistance2D ( x , y ) ;
2022-10-07 11:50:29 +00:00
if ( dist < maxdist & & & wal ! = actor - > temp_walls [ 0 ] )
{
maxdist = dist ;
closewall = & wal ;
}
2020-05-15 20:59:13 +00:00
}
2022-10-07 11:50:29 +00:00
actor - > temp_walls [ i ] = closewall ;
2020-05-15 20:59:13 +00:00
2022-10-07 13:26:41 +00:00
vertexscan ( actor - > temp_walls [ i ] , [ = ] ( walltype * w )
2022-10-07 11:50:29 +00:00
{
2022-10-07 13:26:41 +00:00
StartInterpolation ( w , Interp_Wall_X ) ;
StartInterpolation ( w , Interp_Wall_Y ) ;
} ) ;
2020-05-15 20:59:13 +00:00
}
break ;
}
2020-11-01 08:00:16 +00:00
case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT :
2020-05-15 20:59:13 +00:00
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 3 ] = sectp - > floorshade ;
2020-05-15 20:59:13 +00:00
2021-12-21 20:57:23 +00:00
sectp - > floorshade = actor - > spr . shade ;
sectp - > ceilingshade = actor - > spr . shade ;
2020-05-15 20:59:13 +00:00
2021-11-06 23:11:17 +00:00
actor - > palvals = ( sectp - > ceilingpal < < 8 ) | sectp - > floorpal ;
2020-05-15 20:59:13 +00:00
//fix all the walls;
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2020-05-15 20:59:13 +00:00
{
2021-11-17 22:31:08 +00:00
if ( ! ( wal . hitag & 1 ) )
2021-12-21 20:57:23 +00:00
wal . shade = actor - > spr . shade ;
2021-12-18 14:11:21 +00:00
if ( ( wal . cstat & CSTAT_WALL_BOTTOM_SWAP ) & & wal . twoSided ( ) )
2021-12-21 20:57:23 +00:00
wal . nextWall ( ) - > shade = actor - > spr . shade ;
2020-05-15 20:59:13 +00:00
}
break ;
2020-11-01 08:00:16 +00:00
case SE_31_FLOOR_RISE_FALL :
2022-09-09 17:30:18 +00:00
actor - > temp_pos . Z = actor - > spr . yint * zmaptoworld ;
actor - > temp_pos . Y = sectp - > floorz ;
2021-12-23 15:24:11 +00:00
// actor->temp_data[2] = actor->spr.hitag;
2022-09-09 17:30:18 +00:00
if ( actor - > spr . intangle ! = 1536 ) sectp - > setfloorz ( actor - > spr . pos . Z ) ;
2020-05-15 20:59:13 +00:00
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2021-11-17 22:31:08 +00:00
if ( wal . hitag = = 0 ) wal . hitag = 9999 ;
2020-05-15 20:59:13 +00:00
2021-11-18 15:56:40 +00:00
StartInterpolation ( sectp , Interp_Sect_Floorz ) ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_32_CEILING_RISE_FALL :
2022-09-12 19:52:47 +00:00
actor - > temp_pos . Z = sectp - > ceilingz ;
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 2 ] = actor - > spr . hitag ;
2022-09-12 19:52:47 +00:00
if ( actor - > spr . intangle ! = 1536 ) sectp - > setceilingz ( actor - > spr . pos . Z ) ;
2020-05-15 20:59:13 +00:00
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2021-11-17 22:31:08 +00:00
if ( wal . hitag = = 0 ) wal . hitag = 9999 ;
2020-05-15 20:59:13 +00:00
2021-11-18 15:56:40 +00:00
StartInterpolation ( sectp , Interp_Sect_Ceilingz ) ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_4_RANDOM_LIGHTS : //Flashing lights
2020-05-15 20:59:13 +00:00
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 2 ] = sectp - > floorshade ;
2020-05-15 20:59:13 +00:00
2021-11-06 23:11:17 +00:00
actor - > palvals = ( sectp - > ceilingpal < < 8 ) | sectp - > floorpal ;
2020-05-15 20:59:13 +00:00
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2021-12-23 15:24:11 +00:00
if ( wal . shade > actor - > temp_data [ 3 ] )
actor - > temp_data [ 3 ] = wal . shade ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_9_DOWN_OPEN_DOOR_LIGHTS :
2021-11-06 23:11:17 +00:00
if ( sectp - > lotag & &
2022-09-02 22:00:28 +00:00
abs ( sectp - > ceilingz - actor - > spr . pos . Z ) > 4 )
2021-11-06 23:11:17 +00:00
sectp - > lotag | = 32768 ; //If its open
2021-11-14 11:25:25 +00:00
[[fallthrough]] ;
2020-11-01 08:00:16 +00:00
case SE_8_UP_OPEN_DOOR_LIGHTS :
2020-05-15 20:59:13 +00:00
//First, get the ceiling-floor shade
2022-12-22 08:49:42 +00:00
actor - > counter = sectp - > floorshade ;
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 1 ] = sectp - > ceilingshade ;
2020-05-15 20:59:13 +00:00
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2021-12-23 15:24:11 +00:00
if ( wal . shade > actor - > temp_data [ 2 ] )
actor - > temp_data [ 2 ] = wal . shade ;
2020-05-15 20:59:13 +00:00
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 3 ] = 1 ; //Take Out;
2020-05-15 20:59:13 +00:00
break ;
case 88 :
//First, get the ceiling-floor shade
if ( ! isRR ( ) ) break ;
2022-12-22 08:49:42 +00:00
actor - > counter = sectp - > floorshade ;
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 1 ] = sectp - > ceilingshade ;
2020-05-15 20:59:13 +00:00
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2021-12-23 15:24:11 +00:00
if ( wal . shade > actor - > temp_data [ 2 ] )
actor - > temp_data [ 2 ] = wal . shade ;
2020-05-15 20:59:13 +00:00
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 3 ] = 1 ; //Take Out;
2020-05-15 20:59:13 +00:00
break ;
2020-11-01 08:00:16 +00:00
case SE_11_SWINGING_DOOR : //Pivitor rotater
2022-09-14 20:57:42 +00:00
if ( actor - > spr . intangle > 1024 ) actor - > temp_data [ 3 ] = 2 ;
2021-12-23 15:24:11 +00:00
else actor - > temp_data [ 3 ] = - 2 ;
2021-11-14 11:25:25 +00:00
[[fallthrough]] ;
2020-11-01 08:00:16 +00:00
case SE_0_ROTATING_SECTOR :
case SE_2_EARTHQUAKE : //Earthquakemakers
case SE_5_BOSS : //Boss Creature
case SE_6_SUBWAY : //Subway
case SE_14_SUBWAY_CAR : //Caboos
case SE_15_SLIDING_DOOR : //Subwaytype sliding door
case SE_16_REACTOR : //That rotating blocker reactor thing
case SE_26 : //ESCELATOR
case SE_30_TWO_WAY_TRAIN : //No rotational subways
2022-01-07 15:36:02 +00:00
{
2022-09-11 18:18:33 +00:00
if ( actor - > spr . lotag = = SE_0_ROTATING_SECTOR )
2020-05-15 20:59:13 +00:00
{
2022-09-11 18:18:33 +00:00
if ( sectp - > lotag = = 30 )
2020-05-15 20:59:13 +00:00
{
2022-11-19 18:01:17 +00:00
if ( actor - > spr . pal ) actor - > spr . detail = 1 ;
else actor - > spr . detail = 0 ;
2022-09-11 18:18:33 +00:00
actor - > temp_pos . Z = sectp - > floorz ;
2021-12-05 16:35:23 +00:00
sectp - > hitagactor = actor ;
2020-05-15 20:59:13 +00:00
}
2021-12-30 09:30:21 +00:00
2020-11-02 21:20:41 +00:00
bool found = false ;
2022-01-07 15:36:02 +00:00
if ( actors ) for ( auto act2 : * actors )
2020-05-15 20:59:13 +00:00
{
2021-12-21 20:57:23 +00:00
if ( act2 - > spr . statnum < MAXSTATUS )
2022-12-01 19:54:41 +00:00
if ( iseffector ( act2 ) & &
2021-12-21 20:57:23 +00:00
act2 - > spr . lotag = = SE_1_PIVOT & &
act2 - > spr . hitag = = actor - > spr . hitag )
2020-05-15 20:59:13 +00:00
{
2022-11-25 12:13:50 +00:00
if ( actor - > spr . Angles . Yaw = = DAngle90 )
2020-05-15 20:59:13 +00:00
{
2022-08-29 17:27:52 +00:00
actor - > spr . pos . XY ( ) = act2 - > spr . pos . XY ( ) ;
2020-05-15 20:59:13 +00:00
}
2020-11-02 21:20:41 +00:00
found = true ;
actor - > SetOwner ( act2 ) ;
2020-05-15 20:59:13 +00:00
break ;
}
}
2020-11-02 21:20:41 +00:00
if ( ! found )
2020-05-15 20:59:13 +00:00
{
2022-12-31 16:16:11 +00:00
actor - > spr . setspritetexture ( FNullTextureID ( ) ) ;
2021-12-21 20:57:23 +00:00
actor - > spr . cstat2 = CSTAT2_SPRITE_NOFIND ;
actor - > spr . cstat = CSTAT_SPRITE_INVISIBLE ;
2021-11-26 20:52:01 +00:00
ChangeActorStat ( actor , STAT_REMOVED ) ;
2022-09-11 16:41:52 +00:00
Printf ( " Found lonely Sector Effector (lotag 0) at (%d,%d) \n " , int ( actor - > spr . pos . X ) , int ( actor - > spr . pos . Y ) ) ;
2021-05-08 13:41:49 +00:00
return ;
2020-05-15 20:59:13 +00:00
}
}
2022-09-11 14:41:17 +00:00
actor - > temp_data [ 1 ] = mspos . Size ( ) ;
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2020-05-15 20:59:13 +00:00
{
2022-09-11 14:41:17 +00:00
mspos . Push ( wal . pos - actor - > spr . pos ) ;
2020-05-15 20:59:13 +00:00
}
2021-12-21 20:57:23 +00:00
if ( actor - > spr . lotag = = SE_30_TWO_WAY_TRAIN | | actor - > spr . lotag = = SE_6_SUBWAY | | actor - > spr . lotag = = SE_14_SUBWAY_CAR | | actor - > spr . lotag = = SE_5_BOSS )
2020-05-15 20:59:13 +00:00
{
2021-11-06 23:11:17 +00:00
if ( sectp - > hitag = = - 1 )
2021-12-21 20:57:23 +00:00
actor - > spr . extra = 0 ;
else actor - > spr . extra = 1 ;
2020-05-15 20:59:13 +00:00
2021-12-05 16:35:23 +00:00
sectp - > hitagactor = actor ;
2020-05-15 20:59:13 +00:00
2021-11-18 19:51:09 +00:00
sectortype * s = nullptr ;
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2020-05-15 20:59:13 +00:00
{
2021-11-21 07:42:36 +00:00
if ( wal . twoSided ( ) & &
2021-11-17 22:35:20 +00:00
wal . nextSector ( ) - > hitag = = 0 & &
2022-12-30 13:05:39 +00:00
( wal . nextSector ( ) - > lotag < 3 | | ( ( ud . mapflags & MFLAG_ALLSECTORTYPES ) & & wal . nextSector ( ) - > lotag = = ST_160_FLOOR_TELEPORT ) ) )
2020-05-15 20:59:13 +00:00
{
2021-11-18 19:51:09 +00:00
s = wal . nextSector ( ) ;
2020-05-15 20:59:13 +00:00
break ;
}
}
2021-11-18 19:51:09 +00:00
if ( s = = nullptr )
2020-05-15 20:59:13 +00:00
{
2022-08-23 20:52:22 +00:00
I_Error ( " Subway found no zero'd sectors with locators \n at (%d,%d). \n " , int ( actor - > spr . pos . X ) , int ( actor - > spr . pos . Y ) ) ;
2020-05-15 20:59:13 +00:00
}
2020-11-02 21:26:32 +00:00
actor - > SetOwner ( nullptr ) ;
2022-12-22 08:49:42 +00:00
actor - > counter = sectindex ( s ) ;
2020-05-15 20:59:13 +00:00
2021-12-21 20:57:23 +00:00
if ( actor - > spr . lotag ! = SE_30_TWO_WAY_TRAIN )
2021-12-23 15:24:11 +00:00
actor - > temp_data [ 3 ] = actor - > spr . hitag ;
2020-05-15 20:59:13 +00:00
}
2021-12-21 20:57:23 +00:00
else if ( actor - > spr . lotag = = SE_16_REACTOR )
2022-09-14 19:08:27 +00:00
actor - > temp_pos . Z = sectp - > ceilingz ;
2020-05-15 20:59:13 +00:00
2021-12-21 20:57:23 +00:00
else if ( actor - > spr . lotag = = SE_26 )
2020-05-15 20:59:13 +00:00
{
2022-08-29 21:13:54 +00:00
actor - > temp_pos . XY ( ) = actor - > spr . pos . XY ( ) ;
2021-12-21 20:57:23 +00:00
if ( actor - > spr . shade = = sectp - > floorshade ) //UP
2022-09-03 08:05:20 +00:00
actor - > vel . Z = - 1 ;
2020-05-15 20:59:13 +00:00
else
2022-09-03 08:04:16 +00:00
actor - > vel . Z = 1 ;
2020-05-15 20:59:13 +00:00
2021-12-21 20:57:23 +00:00
actor - > spr . shade = 0 ;
2020-05-15 20:59:13 +00:00
}
2021-12-21 20:57:23 +00:00
else if ( actor - > spr . lotag = = SE_2_EARTHQUAKE )
2020-05-15 20:59:13 +00:00
{
2022-12-22 08:49:42 +00:00
actor - > temp_data [ 0 ] = actor - > sector ( ) - > getfloorslope ( ) ;
2021-12-30 15:51:56 +00:00
actor - > sector ( ) - > setfloorslope ( 0 ) ;
2020-05-15 20:59:13 +00:00
}
2022-01-07 15:36:02 +00:00
break ;
}
case SE_49_POINT_LIGHT :
case SE_50_SPOT_LIGHT :
{
DukeSectIterator it ( actor - > sector ( ) ) ;
while ( auto itActor = it . Next ( ) )
{
2022-11-20 11:43:24 +00:00
if ( isactivator ( itActor ) | | islockedactivator ( itActor ) )
2022-01-23 23:10:25 +00:00
actor - > flags2 | = SFLAG2_USEACTIVATOR ;
2022-01-07 15:36:02 +00:00
}
ChangeActorStat ( actor , STAT_LIGHT ) ;
break ;
}
2020-05-15 20:59:13 +00:00
}
2021-12-21 20:57:23 +00:00
switch ( actor - > spr . lotag )
2020-05-15 20:59:13 +00:00
{
2020-11-01 08:00:16 +00:00
case SE_6_SUBWAY :
case SE_14_SUBWAY_CAR :
2020-11-02 21:20:41 +00:00
{
2021-11-18 20:00:54 +00:00
int j = callsound ( sectp , actor ) ;
2020-05-15 20:59:13 +00:00
if ( j = = - 1 )
{
if ( ! isRR ( ) ) j = SUBWAY ; // Duke
2021-12-30 15:51:56 +00:00
else if ( actor - > sector ( ) - > floorpal = = 7 ) j = 456 ;
2020-05-15 20:59:13 +00:00
else j = 75 ;
}
2022-02-06 21:59:30 +00:00
actor - > tempsound = j ;
2020-11-02 21:20:41 +00:00
}
2021-11-14 11:25:25 +00:00
[[fallthrough]] ;
2020-11-01 08:00:16 +00:00
case SE_30_TWO_WAY_TRAIN :
2020-05-15 20:59:13 +00:00
if ( numplayers > 1 ) break ;
2021-11-14 11:25:25 +00:00
[[fallthrough]] ;
2020-11-01 08:00:16 +00:00
case SE_0_ROTATING_SECTOR :
case SE_1_PIVOT :
case SE_5_BOSS :
case SE_11_SWINGING_DOOR :
case SE_15_SLIDING_DOOR :
case SE_16_REACTOR :
case SE_26 :
2022-12-13 12:46:30 +00:00
if ( actor - > spr . lotag = = SE_0_ROTATING_SECTOR ) StartInterpolation ( actor - > sector ( ) , Interp_Sect_Floorz ) ;
2021-12-30 15:51:56 +00:00
setsectinterpolate ( actor - > sector ( ) ) ;
2020-05-15 20:59:13 +00:00
break ;
2020-11-27 19:06:38 +00:00
case SE_29_WAVES :
2021-12-30 15:51:56 +00:00
StartInterpolation ( actor - > sector ( ) , Interp_Sect_Floorheinum ) ;
StartInterpolation ( actor - > sector ( ) , Interp_Sect_Floorz ) ;
2020-11-27 19:06:38 +00:00
break ;
2020-05-15 20:59:13 +00:00
}
2021-12-21 17:19:45 +00:00
if ( ( ! isRR ( ) & & actor - > spr . lotag > = 40 & & actor - > spr . lotag < = 45 ) | |
( isRRRA ( ) & & actor - > spr . lotag > = 150 & & actor - > spr . lotag < = 155 ) )
2021-11-26 20:52:01 +00:00
ChangeActorStat ( actor , STAT_RAROR ) ;
2020-05-15 20:59:13 +00:00
else
2021-11-26 20:52:01 +00:00
ChangeActorStat ( actor , STAT_EFFECTOR ) ;
2020-05-15 20:59:13 +00:00
}
2022-12-15 09:46:41 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
DDukeActor * spawninit ( DDukeActor * actj , DDukeActor * act , TArray < DDukeActor * > * actors )
{
2022-12-20 21:25:48 +00:00
if ( ( act - > flags2 & SFLAG2_TRIGGERRESPAWN ) )
2022-12-15 09:46:41 +00:00
{
act - > spr . yint = act - > spr . hitag ;
act - > spr . hitag = - 1 ;
}
if ( iseffector ( act ) )
{
// for in-game spawned SE's the init code must not run. The only type ever being spawned that way is SE128 -
// but we cannot check that here as the number has not been set yet.
if ( actj = = 0 ) spawneffector ( act , actors ) ;
}
else if ( ! act - > isPlayer ( ) )
{
2023-04-12 18:06:25 +00:00
if ( act - > flags1 & SFLAG_SKILLFILTER )
2023-04-11 18:14:02 +00:00
{
if ( act - > spr . lotag > ud . player_skill )
{
act - > spr . scale . Zero ( ) ;
ChangeActorStat ( act , STAT_MISC ) ;
return nullptr ;
}
}
2023-04-12 18:06:25 +00:00
if ( badguy ( act ) )
{
if ( ud . monsters_off = = 1 )
{
act - > spr . scale . Zero ( ) ;
ChangeActorStat ( act , STAT_MISC ) ;
return nullptr ;
}
commonEnemySetup ( act , actj ) ;
}
CallInitialize ( act ) ;
2022-12-15 09:46:41 +00:00
}
else
{
act - > spr . scale = DVector2 ( 0 , 0 ) ;
int j = ud . coop ;
if ( j = = 2 ) j = 0 ;
if ( ud . multimode < 2 | | ( ud . multimode > 1 & & j ! = act - > spr . lotag ) )
ChangeActorStat ( act , STAT_MISC ) ;
else
ChangeActorStat ( act , STAT_PLAYER ) ;
2023-04-09 06:15:02 +00:00
//CallInitialize(act);
2022-12-15 09:46:41 +00:00
}
return act ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void spriteinit ( DDukeActor * actor , TArray < DDukeActor * > & actors )
{
actor - > mapSpawned = true ;
bool res = initspriteforspawn ( actor ) ;
if ( res ) spawninit ( nullptr , actor , & actors ) ;
}
2020-05-16 10:47:01 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-12-01 19:11:38 +00:00
inline PClassActor * GlassClass ( int j )
{
2022-12-29 08:56:14 +00:00
static PClassActor * const * glasses [ ] = { & DukeGlassPiecesClass , & DukeGlassPieces1Class , & DukeGlassPieces2Class } ;
return * glasses [ j % 3 ] ;
2022-12-01 19:11:38 +00:00
}
2021-11-17 23:38:20 +00:00
void lotsofglass ( DDukeActor * actor , walltype * wal , int n )
2020-05-16 10:47:01 +00:00
{
2022-10-12 17:00:43 +00:00
int j ;
2021-11-17 23:47:46 +00:00
sectortype * sect = nullptr ;
2020-05-16 10:47:01 +00:00
2021-11-17 23:38:20 +00:00
if ( wal = = nullptr )
2020-05-16 10:47:01 +00:00
{
for ( j = n - 1 ; j > = 0 ; j - - )
{
2022-11-25 12:13:50 +00:00
auto a = actor - > spr . Angles . Yaw - DAngle45 + DAngle180 + randomAngle ( 90 ) ;
2022-09-14 18:53:34 +00:00
auto vel = krandf ( 4 ) + 2 ;
auto zvel = 4 - krandf ( 4 ) ;
2022-12-01 19:11:38 +00:00
CreateActor ( actor - > sector ( ) , actor - > spr . pos , GlassClass ( j ) , - 32 , DVector2 ( 0.5625 , 0.5625 ) , a , vel , zvel , actor , 5 ) ;
2020-05-16 10:47:01 +00:00
}
return ;
}
2022-09-13 18:25:33 +00:00
2020-05-16 10:47:01 +00:00
2022-09-13 18:25:33 +00:00
auto pos = wal - > pos ;
auto delta = wal - > delta ( ) / ( n + 1 ) ;
2020-05-16 10:47:01 +00:00
2022-09-13 18:25:33 +00:00
pos . X - = Sgn ( delta . Y ) * maptoworld ;
pos . Y + = Sgn ( delta . X ) * maptoworld ;
2020-05-16 10:47:01 +00:00
for ( j = n ; j > 0 ; j - - )
{
2022-09-13 18:25:33 +00:00
pos + = delta ;
sect = wal - > sectorp ( ) ;
updatesector ( DVector3 ( pos , sect - > floorz ) , & sect ) ;
2021-11-17 23:47:46 +00:00
if ( sect )
2020-05-16 10:47:01 +00:00
{
2022-10-12 17:00:43 +00:00
double z = sect - > floorz - krandf ( abs ( sect - > ceilingz - sect - > floorz ) ) ;
2022-09-13 18:25:33 +00:00
if ( fabs ( z ) > 32 )
z = actor - > spr . pos . Z - 32 + krandf ( 64 ) ;
2022-11-25 12:13:50 +00:00
DAngle angl = actor - > spr . Angles . Yaw - DAngle180 ;
2022-09-14 18:53:34 +00:00
auto vel = krandf ( 4 ) + 2 ;
auto zvel = 4 - krandf ( 4 ) ;
2022-12-01 19:11:38 +00:00
CreateActor ( actor - > sector ( ) , DVector3 ( pos , z ) , GlassClass ( j ) , - 32 , DVector2 ( 0.5625 , 0.5625 ) , angl , vel , zvel , actor , 5 ) ;
2020-05-16 10:47:01 +00:00
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-10-25 05:40:05 +00:00
void spriteglass ( DDukeActor * actor , int n )
2020-05-16 10:47:01 +00:00
{
2020-10-25 05:40:05 +00:00
for ( int j = n ; j > 0 ; j - - )
2020-05-16 10:47:01 +00:00
{
2022-09-14 18:53:34 +00:00
auto a = randomAngle ( ) ;
auto vel = krandf ( 4 ) + 2 ;
auto zvel = - 2 - krandf ( 8 ) ;
2022-12-01 19:11:38 +00:00
auto k = CreateActor ( actor - > sector ( ) , actor - > spr . pos . plusZ ( - ( krand ( ) & 16 ) ) , GlassClass ( j ) , krand ( ) & 15 , DVector2 ( 0.5625 , 0.5625 ) , a , vel , zvel , actor , 5 ) ;
2021-12-21 20:57:23 +00:00
if ( k ) k - > spr . pal = actor - > spr . pal ;
2020-05-16 10:47:01 +00:00
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-18 16:55:08 +00:00
void ceilingglass ( DDukeActor * actor , sectortype * sectp , int n )
2020-05-16 10:47:01 +00:00
{
2022-11-15 14:24:17 +00:00
for ( auto & wal : sectp - > walls )
2020-05-16 10:47:01 +00:00
{
2022-09-13 18:25:33 +00:00
auto pos = wal . pos ;
auto delta = wal . delta ( ) / ( n + 1 ) ;
2020-05-16 10:47:01 +00:00
2022-09-13 18:25:33 +00:00
for ( int j = n ; j > 0 ; j - - )
2020-05-16 10:47:01 +00:00
{
2022-09-13 18:25:33 +00:00
pos + = delta ;
DAngle a = randomAngle ( ) ;
2022-09-14 18:53:34 +00:00
auto vel = krandf ( 2 ) ;
2022-09-13 18:25:33 +00:00
double z = sectp - > ceilingz + krandf ( 16 ) ;
2022-12-01 19:11:38 +00:00
CreateActor ( sectp , DVector3 ( pos , z ) , GlassClass ( j ) , - 32 , DVector2 ( 0.5625 , 0.5625 ) , a , vel , 0 , actor , 5 ) ;
2020-05-16 10:47:01 +00:00
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-17 23:38:20 +00:00
void lotsofcolourglass ( DDukeActor * actor , walltype * wal , int n )
2020-05-16 10:47:01 +00:00
{
2022-09-13 18:25:33 +00:00
int j ;
2021-11-17 23:47:46 +00:00
sectortype * sect = nullptr ;
2020-05-16 10:47:01 +00:00
2021-11-17 23:38:20 +00:00
if ( wal = = nullptr )
2020-05-16 10:47:01 +00:00
{
for ( j = n - 1 ; j > = 0 ; j - - )
{
2022-09-13 18:25:33 +00:00
DAngle a = randomAngle ( ) ;
2022-09-14 18:53:34 +00:00
auto vel = krandf ( 4 ) + 2 ;
auto zvel = 4 - krandf ( 4 ) ;
2022-12-01 19:11:38 +00:00
auto k = CreateActor ( actor - > sector ( ) , actor - > spr . pos . plusZ ( - ( krand ( ) & 63 ) ) , GlassClass ( j ) , - 32 , DVector2 ( 0.5625 , 0.5625 ) , a , vel , zvel , actor , 5 ) ;
2021-12-21 17:19:45 +00:00
if ( k ) k - > spr . pal = krand ( ) & 15 ;
2020-05-16 10:47:01 +00:00
}
return ;
}
2021-12-30 09:30:21 +00:00
2022-09-13 18:25:33 +00:00
auto pos = wal - > pos ;
auto delta = wal - > delta ( ) / ( n + 1 ) ;
2020-05-16 10:47:01 +00:00
for ( j = n ; j > 0 ; j - - )
{
2022-09-13 18:25:33 +00:00
pos + = delta ;
sect = wal - > sectorp ( ) ;
updatesector ( DVector3 ( pos , sect - > floorz ) , & sect ) ;
if ( ! sect ) continue ;
double z = sect - > floorz - krandf ( abs ( sect - > ceilingz - sect - > floorz ) ) ;
if ( abs ( z ) > 32 )
z = actor - > spr . pos . Z - 32 + krandf ( 64 ) ;
2022-11-25 12:13:50 +00:00
DAngle a = actor - > spr . Angles . Yaw - DAngle180 ;
2022-09-14 18:53:34 +00:00
auto vel = krandf ( 4 ) + 2 ;
auto zvel = - krandf ( 8 ) ;
2022-12-01 19:11:38 +00:00
auto k = CreateActor ( actor - > sector ( ) , DVector3 ( pos , z ) , GlassClass ( j ) , - 32 , DVector2 ( 0.5625 , 0.5625 ) , a , vel , zvel , actor , 5 ) ;
2021-12-21 17:19:45 +00:00
if ( k ) k - > spr . pal = krand ( ) & 7 ;
2020-05-16 10:47:01 +00:00
}
}
2020-05-15 20:59:13 +00:00
END_DUKE_NS