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"
2020-08-05 22:18:45 +00:00
# include "misc.h"
2015-05-19 21:54:34 +00:00
# include "tags.h"
# include "ai.h"
# include "light.h"
# include "break.h"
2019-03-21 02:24:19 +00:00
# include "network.h"
2015-05-19 21:54:34 +00:00
# include "pal.h"
# include "sounds.h"
# include "interp.h"
2020-05-01 11:29:12 +00:00
# include "interpso.h"
2015-05-19 21:54:34 +00:00
# include "sprite.h"
# include "weapon.h"
# include "jsector.h"
2020-08-05 22:18:45 +00:00
# include "misc.h"
2015-05-19 21:54:34 +00:00
# include "player.h"
2019-12-09 17:40:07 +00:00
# include "quotemgr.h"
# include "v_text.h"
2020-03-08 19:53:04 +00:00
# include "gamecontrol.h"
2015-05-19 21:54:34 +00:00
2019-10-09 16:09:05 +00:00
BEGIN_SW_NS
2015-05-19 21:54:34 +00:00
2019-10-09 17:58:09 +00:00
ANIMATOR SetupCoolie ;
ANIMATOR SetupNinja ;
ANIMATOR SetupGoro ;
ANIMATOR SetupCoolg ;
ANIMATOR SetupEel ;
ANIMATOR SetupSumo ;
ANIMATOR SetupZilla ;
ANIMATOR SetupToiletGirl ;
ANIMATOR SetupWashGirl ;
ANIMATOR SetupCarGirl ;
ANIMATOR SetupMechanicGirl ;
ANIMATOR SetupSailorGirl ;
ANIMATOR SetupPruneGirl ;
ANIMATOR SetupTrashCan ;
ANIMATOR SetupBunny ;
ANIMATOR SetupRipper ;
ANIMATOR SetupRipper2 ;
ANIMATOR SetupSerp ;
ANIMATOR SetupLava ;
ANIMATOR SetupSkel ;
ANIMATOR SetupHornet ;
ANIMATOR SetupSkull ;
ANIMATOR SetupBetty ;
ANIMATOR SetupPachinkoLight ;
ANIMATOR SetupPachinko1 ;
ANIMATOR SetupPachinko2 ;
ANIMATOR SetupPachinko3 ;
ANIMATOR SetupPachinko4 ;
ANIMATOR SetupGirlNinja ;
ANIMATOR DoVator , DoVatorAuto ;
ANIMATOR DoRotator ;
ANIMATOR DoSlidor ;
ANIMATOR DoSpike , DoSpikeAuto ;
ANIMATOR DoLavaErupt ;
int DoSlidorInstantClose ( short SpriteNum ) ;
void InitWeaponRocket ( PLAYERp ) ;
void InitWeaponUzi ( PLAYERp ) ;
2015-05-19 21:58:29 +00:00
SWBOOL FAF_Sector ( short sectnum ) ;
SWBOOL MoveSkip4 , MoveSkip2 , MoveSkip8 ;
2015-05-19 21:54:34 +00:00
extern STATE s_CarryFlag [ ] ;
extern STATE s_CarryFlagNoDet [ ] ;
static int globhiz , globloz , globhihit , globlohit ;
short wait_active_check_offset ;
int PlaxCeilGlobZadjust , PlaxFloorGlobZadjust ;
2015-05-19 21:58:29 +00:00
void SetSectorWallBits ( short sectnum , int bit_mask , SWBOOL set_sectwall , SWBOOL set_nextwall ) ;
2015-05-19 21:54:34 +00:00
int DoActorDebris ( short SpriteNum ) ;
void ActorWarpUpdatePos ( short SpriteNum , short sectnum ) ;
2015-05-19 21:58:29 +00:00
void ActorWarpType ( SPRITEp sp , SPRITEp sp_warp ) ;
2015-05-19 21:54:34 +00:00
int MissileZrange ( short SpriteNum ) ;
# define ACTIVE_CHECK_TIME (3*120)
/*
short GetDeltaAngle ( short ang1 , short ang2 ) ;
short GetRotation ( short sn ) ;
2015-05-19 21:58:29 +00:00
int StateControl ( int16_t SpriteNum ) ;
2015-05-19 21:54:34 +00:00
void PreCacheRange ( short , short ) ;
*/
TRACK Track [ MAX_TRACKS ] ;
SECTOR_OBJECT SectorObject [ MAX_SECTOR_OBJECTS ] ;
int DirArr [ ] = { NORTH , NE , EAST , SE , SOUTH , SW , WEST , NW , NORTH , NE , EAST , SE , SOUTH , SW , WEST , NW } ;
# define SCROLL_RATE 20
# define SCROLL_FIRE_RATE 20
STATE s_DebrisNinja [ ] =
{
{ NINJA_DIE + 3 , 100 , DoActorDebris , & s_DebrisNinja [ 0 ] } ,
} ;
STATE s_DebrisRat [ ] =
{
{ 750 , 100 , DoActorDebris , & s_DebrisRat [ 0 ] } ,
} ;
STATE s_DebrisCrab [ ] =
{
{ 423 , 100 , DoActorDebris , & s_DebrisCrab [ 0 ] } ,
} ;
STATE s_DebrisStarFish [ ] =
{
{ 426 , 100 , DoActorDebris , & s_DebrisStarFish [ 0 ] } ,
} ;
2015-05-19 21:58:29 +00:00
extern SWBOOL DebugActor ;
2015-05-19 21:54:34 +00:00
extern int score ;
ANIMATOR DoGet , DoKey , DoSpriteFade ;
// temporary
# define ICON_REPAIR_KIT 1813
# define REPAIR_KIT_RATE 1100
STATE s_RepairKit [ ] =
{
{ ICON_REPAIR_KIT + 0 , REPAIR_KIT_RATE , DoGet , & s_RepairKit [ 0 ] }
} ;
STATE s_GoldSkelKey [ ] =
{
{ GOLD_SKELKEY , 100 , DoGet , & s_GoldSkelKey [ 0 ] }
} ;
STATE s_BlueKey [ ] =
{
{ BLUE_KEY , 100 , DoGet , & s_BlueKey [ 0 ] }
} ;
STATE s_BlueCard [ ] =
{
{ BLUE_CARD , 100 , DoGet , & s_BlueCard [ 0 ] }
} ;
STATE s_SilverSkelKey [ ] =
{
{ SILVER_SKELKEY , 100 , DoGet , & s_SilverSkelKey [ 0 ] }
} ;
STATE s_RedKey [ ] =
{
{ RED_KEY , 100 , DoGet , & s_RedKey [ 0 ] }
} ;
STATE s_RedCard [ ] =
{
{ RED_CARD , 100 , DoGet , & s_RedCard [ 0 ] }
} ;
STATE s_BronzeSkelKey [ ] =
{
{ BRONZE_SKELKEY , 100 , DoGet , & s_BronzeSkelKey [ 0 ] }
} ;
STATE s_GreenKey [ ] =
{
{ GREEN_KEY , 100 , DoGet , & s_GreenKey [ 0 ] }
} ;
STATE s_GreenCard [ ] =
{
{ GREEN_CARD , 100 , DoGet , & s_GreenCard [ 0 ] }
} ;
STATE s_RedSkelKey [ ] =
{
{ RED_SKELKEY , 100 , DoGet , & s_RedSkelKey [ 0 ] }
} ;
STATE s_YellowKey [ ] =
{
{ YELLOW_KEY , 100 , DoGet , & s_YellowKey [ 0 ] }
} ;
STATE s_YellowCard [ ] =
{
{ YELLOW_CARD , 100 , DoGet , & s_YellowCard [ 0 ] }
} ;
STATEp s_Key [ ] =
{
s_RedKey ,
s_BlueKey ,
s_GreenKey ,
s_YellowKey ,
s_RedCard ,
s_BlueCard ,
s_GreenCard ,
s_YellowCard ,
s_GoldSkelKey ,
s_SilverSkelKey ,
s_BronzeSkelKey ,
s_RedSkelKey
} ;
# define KEY_RATE 25
#if 0
STATE s_BlueKey [ ] =
{
{ BLUE_KEY + 0 , KEY_RATE , DoKey , & s_BlueKey [ 0 ] }
} ;
STATE s_RedKey [ ] =
{
{ RED_KEY + 0 , KEY_RATE , DoKey , & s_RedKey [ 0 ] }
} ;
STATE s_GreenKey [ ] =
{
{ GREEN_KEY + 0 , KEY_RATE , DoKey , & s_GreenKey [ 0 ] }
} ;
STATE s_YellowKey [ ] =
{
{ YELLOW_KEY + 0 , KEY_RATE , DoKey , & s_YellowKey [ 0 ] }
} ;
STATEp s_Key [ ] =
{
s_RedKey ,
s_BlueKey ,
s_GreenKey ,
s_YellowKey ,
s_RedCard ,
s_BlueCard ,
s_GreenCard ,
s_YellowCard ,
s_GoldSkelKey ,
s_SilverSkelKey ,
s_BronzeSkelKey ,
s_RedSkelKey
} ;
# endif
#if 0
STATE s_BlueKeyStatue [ ] =
{
{ BLUE_KEY_STATUE + 0 , KEY_RATE , DoSpriteFade , & s_BlueKeyStatue [ 0 ] }
} ;
STATE s_RedKeyStatue [ ] =
{
{ RED_KEY_STATUE + 0 , KEY_RATE , DoSpriteFade , & s_RedKeyStatue [ 0 ] }
} ;
STATE s_GreenKeyStatue [ ] =
{
{ GREEN_KEY_STATUE + 0 , KEY_RATE , DoSpriteFade , & s_GreenKeyStatue [ 0 ] }
} ;
STATE s_YellowKeyStatue [ ] =
{
{ YELLOW_KEY_STATUE + 0 , KEY_RATE , DoSpriteFade , & s_YellowKeyStatue [ 0 ] }
} ;
STATEp s_KeyStatue [ ] =
{
s_RedKeyStatue ,
s_BlueKeyStatue ,
s_GreenKeyStatue ,
s_YellowKeyStatue ,
} ;
# endif
# define Red_COIN 2440
# define Yellow_COIN 2450
# define Green_COIN 2460
# define RED_COIN_RATE 10
# define YELLOW_COIN_RATE 8
# define GREEN_COIN_RATE 6
ANIMATOR DoCoin ;
STATE s_RedCoin [ ] =
{
{ Red_COIN + 0 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 1 ] } ,
{ Red_COIN + 1 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 2 ] } ,
{ Red_COIN + 2 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 3 ] } ,
{ Red_COIN + 3 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 4 ] } ,
{ Red_COIN + 4 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 5 ] } ,
{ Red_COIN + 5 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 6 ] } ,
{ Red_COIN + 6 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 7 ] } ,
{ Red_COIN + 7 , RED_COIN_RATE , DoCoin , & s_RedCoin [ 0 ] } ,
} ;
// !JIM! Frank, I made coins go progressively faster
STATE s_YellowCoin [ ] =
{
{ Yellow_COIN + 0 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 1 ] } ,
{ Yellow_COIN + 1 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 2 ] } ,
{ Yellow_COIN + 2 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 3 ] } ,
{ Yellow_COIN + 3 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 4 ] } ,
{ Yellow_COIN + 4 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 5 ] } ,
{ Yellow_COIN + 5 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 6 ] } ,
{ Yellow_COIN + 6 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 7 ] } ,
{ Yellow_COIN + 7 , YELLOW_COIN_RATE , DoCoin , & s_YellowCoin [ 0 ] } ,
} ;
STATE s_GreenCoin [ ] =
{
{ Green_COIN + 0 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 1 ] } ,
{ Green_COIN + 1 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 2 ] } ,
{ Green_COIN + 2 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 3 ] } ,
{ Green_COIN + 3 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 4 ] } ,
{ Green_COIN + 4 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 5 ] } ,
{ Green_COIN + 5 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 6 ] } ,
{ Green_COIN + 6 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 7 ] } ,
{ Green_COIN + 7 , GREEN_COIN_RATE , DoCoin , & s_GreenCoin [ 0 ] } ,
} ;
ANIMATOR DoFireFly ;
#if 0
STATE s_FireFly [ ] =
{
{ FIRE_FLY0 , 120 * 3 , DoFireFly , & s_FireFly [ 1 ] } ,
{ FIRE_FLY1 , 20 , DoFireFly , & s_FireFly [ 2 ] } ,
{ FIRE_FLY2 , 20 , DoFireFly , & s_FireFly [ 3 ] } ,
{ FIRE_FLY3 , 20 , DoFireFly , & s_FireFly [ 4 ] } ,
{ FIRE_FLY4 , 60 , DoFireFly , & s_FireFly [ 0 ] } ,
} ;
# else
STATE s_FireFly [ ] =
{
{ FIRE_FLY0 , FIRE_FLY_RATE * 4 , DoFireFly , & s_FireFly [ 0 ] }
} ;
# endif
STATE s_IconStar [ ] =
{
{ ICON_STAR , 100 , DoGet , & s_IconStar [ 0 ] }
} ;
STATE s_IconUzi [ ] =
{
{ ICON_UZI , 100 , DoGet , & s_IconUzi [ 0 ] }
} ;
STATE s_IconLgUziAmmo [ ] =
{
{ ICON_LG_UZI_AMMO , 100 , DoGet , & s_IconLgUziAmmo [ 0 ] }
} ;
STATE s_IconUziFloor [ ] =
{
{ ICON_UZIFLOOR , 100 , DoGet , & s_IconUziFloor [ 0 ] }
} ;
STATE s_IconRocket [ ] =
{
{ ICON_ROCKET , 100 , DoGet , & s_IconRocket [ 0 ] }
} ;
STATE s_IconLgRocket [ ] =
{
{ ICON_LG_ROCKET , 100 , DoGet , & s_IconLgRocket [ 0 ] }
} ;
STATE s_IconShotgun [ ] =
{
{ ICON_SHOTGUN , 100 , DoGet , & s_IconShotgun [ 0 ] }
} ;
STATE s_IconLgShotshell [ ] =
{
{ ICON_LG_SHOTSHELL , 100 , DoGet , & s_IconLgShotshell [ 0 ] }
} ;
STATE s_IconAutoRiot [ ] =
{
{ ICON_AUTORIOT , 100 , DoGet , & s_IconAutoRiot [ 0 ] }
} ;
STATE s_IconGrenadeLauncher [ ] =
{
{ ICON_GRENADE_LAUNCHER , 100 , DoGet , & s_IconGrenadeLauncher [ 0 ] }
} ;
STATE s_IconLgGrenade [ ] =
{
{ ICON_LG_GRENADE , 100 , DoGet , & s_IconLgGrenade [ 0 ] }
} ;
STATE s_IconLgMine [ ] =
{
{ ICON_LG_MINE , 100 , DoGet , & s_IconLgMine [ 0 ] }
} ;
STATE s_IconGuardHead [ ] =
{
{ ICON_GUARD_HEAD + 0 , 15 , DoGet , & s_IconGuardHead [ 0 ] } ,
// {ICON_GUARD_HEAD + 1, 15, DoGet, &s_IconGuardHead[2]},
// {ICON_GUARD_HEAD + 2, 15, DoGet, &s_IconGuardHead[0]}
} ;
# define FIREBALL_LG_AMMO_RATE 12
STATE s_IconFireballLgAmmo [ ] =
{
{ ICON_FIREBALL_LG_AMMO + 0 , FIREBALL_LG_AMMO_RATE , DoGet , & s_IconFireballLgAmmo [ 1 ] } ,
{ ICON_FIREBALL_LG_AMMO + 1 , FIREBALL_LG_AMMO_RATE , DoGet , & s_IconFireballLgAmmo [ 2 ] } ,
{ ICON_FIREBALL_LG_AMMO + 2 , FIREBALL_LG_AMMO_RATE , DoGet , & s_IconFireballLgAmmo [ 0 ] } ,
} ;
STATE s_IconHeart [ ] =
{
{ ICON_HEART + 0 , 25 , DoGet , & s_IconHeart [ 1 ] } ,
{ ICON_HEART + 1 , 25 , DoGet , & s_IconHeart [ 0 ] } ,
} ;
# define HEART_LG_AMMO_RATE 12
STATE s_IconHeartLgAmmo [ ] =
{
{ ICON_HEART_LG_AMMO + 0 , HEART_LG_AMMO_RATE , DoGet , & s_IconHeartLgAmmo [ 1 ] } ,
{ ICON_HEART_LG_AMMO + 1 , HEART_LG_AMMO_RATE , DoGet , & s_IconHeartLgAmmo [ 0 ] } ,
} ;
STATE s_IconMicroGun [ ] =
{
{ ICON_MICRO_GUN , 100 , DoGet , & s_IconMicroGun [ 0 ] }
} ;
STATE s_IconMicroBattery [ ] =
{
{ ICON_MICRO_BATTERY , 100 , DoGet , & s_IconMicroBattery [ 0 ] }
} ;
// !JIM! Added rail crap
STATE s_IconRailGun [ ] =
{
{ ICON_RAIL_GUN , 100 , DoGet , & s_IconRailGun [ 0 ] }
} ;
STATE s_IconRailAmmo [ ] =
{
{ ICON_RAIL_AMMO , 100 , DoGet , & s_IconRailAmmo [ 0 ] }
} ;
STATE s_IconElectro [ ] =
{
{ ICON_ELECTRO + 0 , 25 , DoGet , & s_IconElectro [ 1 ] } ,
{ ICON_ELECTRO + 1 , 25 , DoGet , & s_IconElectro [ 0 ] } ,
} ;
# define ICON_SPELL_RATE 8
STATE s_IconSpell [ ] =
{
{ ICON_SPELL + 0 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 1 ] } ,
{ ICON_SPELL + 1 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 2 ] } ,
{ ICON_SPELL + 2 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 3 ] } ,
{ ICON_SPELL + 3 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 4 ] } ,
{ ICON_SPELL + 4 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 5 ] } ,
{ ICON_SPELL + 5 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 6 ] } ,
{ ICON_SPELL + 6 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 7 ] } ,
{ ICON_SPELL + 7 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 8 ] } ,
{ ICON_SPELL + 8 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 9 ] } ,
{ ICON_SPELL + 9 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 10 ] } ,
{ ICON_SPELL + 10 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 11 ] } ,
{ ICON_SPELL + 11 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 12 ] } ,
{ ICON_SPELL + 12 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 13 ] } ,
{ ICON_SPELL + 13 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 14 ] } ,
{ ICON_SPELL + 14 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 15 ] } ,
{ ICON_SPELL + 15 , ICON_SPELL_RATE , DoGet , & s_IconSpell [ 0 ] } ,
} ;
STATE s_IconArmor [ ] =
{
{ ICON_ARMOR + 0 , 15 , DoGet , & s_IconArmor [ 0 ] } ,
} ;
STATE s_IconMedkit [ ] =
{
{ ICON_MEDKIT + 0 , 15 , DoGet , & s_IconMedkit [ 0 ] } ,
} ;
STATE s_IconChemBomb [ ] =
{
{ ICON_CHEMBOMB , 15 , DoGet , & s_IconChemBomb [ 0 ] } ,
} ;
STATE s_IconFlashBomb [ ] =
{
{ ICON_FLASHBOMB , 15 , DoGet , & s_IconFlashBomb [ 0 ] } ,
} ;
STATE s_IconNuke [ ] =
{
{ ICON_NUKE , 15 , DoGet , & s_IconNuke [ 0 ] } ,
} ;
STATE s_IconCaltrops [ ] =
{
{ ICON_CALTROPS , 15 , DoGet , & s_IconCaltrops [ 0 ] } ,
} ;
# define ICON_SM_MEDKIT 1802
STATE s_IconSmMedkit [ ] =
{
{ ICON_SM_MEDKIT + 0 , 15 , DoGet , & s_IconSmMedkit [ 0 ] } ,
} ;
# define ICON_BOOSTER 1810
STATE s_IconBooster [ ] =
{
{ ICON_BOOSTER + 0 , 15 , DoGet , & s_IconBooster [ 0 ] } ,
} ;
# define ICON_HEAT_CARD 1819
STATE s_IconHeatCard [ ] =
{
{ ICON_HEAT_CARD + 0 , 15 , DoGet , & s_IconHeatCard [ 0 ] } ,
} ;
#if 0
STATE s_IconEnvironSuit [ ] =
{
{ ICON_ENVIRON_SUIT + 0 , 20 , DoGet , & s_IconEnvironSuit [ 0 ] } ,
} ;
# endif
STATE s_IconCloak [ ] =
{
// {ICON_CLOAK + 0, 20, DoGet, &s_IconCloak[1]},
// {ICON_CLOAK + 1, 20, DoGet, &s_IconCloak[2]},
{ ICON_CLOAK + 0 , 20 , DoGet , & s_IconCloak [ 0 ] } ,
} ;
STATE s_IconFly [ ] =
{
{ ICON_FLY + 0 , 20 , DoGet , & s_IconFly [ 1 ] } ,
{ ICON_FLY + 1 , 20 , DoGet , & s_IconFly [ 2 ] } ,
{ ICON_FLY + 2 , 20 , DoGet , & s_IconFly [ 3 ] } ,
{ ICON_FLY + 3 , 20 , DoGet , & s_IconFly [ 4 ] } ,
{ ICON_FLY + 4 , 20 , DoGet , & s_IconFly [ 5 ] } ,
{ ICON_FLY + 5 , 20 , DoGet , & s_IconFly [ 6 ] } ,
{ ICON_FLY + 6 , 20 , DoGet , & s_IconFly [ 7 ] } ,
{ ICON_FLY + 7 , 20 , DoGet , & s_IconFly [ 0 ] }
} ;
STATE s_IconNightVision [ ] =
{
{ ICON_NIGHT_VISION + 0 , 20 , DoGet , & s_IconNightVision [ 0 ] } ,
} ;
STATE s_IconFlag [ ] =
{
{ ICON_FLAG + 0 , 32 , DoGet , & s_IconFlag [ 1 ] } ,
{ ICON_FLAG + 1 , 32 , DoGet , & s_IconFlag [ 2 ] } ,
{ ICON_FLAG + 2 , 32 , DoGet , & s_IconFlag [ 0 ] }
} ;
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
SetOwner ( short owner , short child )
{
SPRITEp cp = & sprite [ child ] ;
if ( owner = = 0 )
{
////DSPRINTF(ds, "Set Owner possible problem - owner is 0, child %d", child);
//MONO_PRINT(ds);
}
if ( owner > = 0 )
{
ASSERT ( User [ owner ] ) ;
SET ( User [ owner ] - > Flags2 , SPR2_CHILDREN ) ;
}
else
{
////DSPRINTF(ds,"Owner is -1 !!!!!!!!!!!!!!!!!!!!!");
//MONO_PRINT(ds);
}
cp - > owner = owner ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
SetAttach ( short owner , short child )
{
USERp cu = User [ child ] ;
ASSERT ( cu ) ;
ASSERT ( User [ owner ] ) ;
SET ( User [ owner ] - > Flags2 , SPR2_CHILDREN ) ;
cu - > Attach = owner ;
}
2015-05-19 21:58:29 +00:00
void
KillSprite ( int16_t SpriteNum )
2015-05-19 21:54:34 +00:00
{
SPRITEp sp = & sprite [ SpriteNum ] ;
USERp u = User [ SpriteNum ] ;
short i , nexti ;
unsigned stat ;
short statnum , sectnum ;
//extern short Zombies;
ASSERT ( ! Prediction ) ;
ASSERT ( sp - > statnum < MAXSTATUS ) ;
//////////////////////////////////////////////
// Check sounds list to kill attached sounds
DeleteNoSoundOwner ( SpriteNum ) ;
DeleteNoFollowSoundOwner ( SpriteNum ) ;
//////////////////////////////////////////////
if ( u )
{
PLAYERp pp ;
short pnum ;
if ( u - > WallShade )
{
FreeMem ( u - > WallShade ) ;
u - > WallShade = NULL ;
}
// doing a MissileSetPos - don't allow killing
if ( TEST ( u - > Flags , SPR_SET_POS_DONT_KILL ) )
return ;
// for attached sprites that are getable make sure they don't have
// any Anims attached
AnimDelete ( & u - > sz ) ;
AnimDelete ( & sp - > z ) ;
stopinterpolation ( & sp - > x ) ;
stopinterpolation ( & sp - > y ) ;
stopinterpolation ( & sp - > z ) ;
//if (TEST(u->Flags2, SPR2_DONT_TARGET_OWNER))
// Zombies--;
// adjust sprites attached to sector objects
if ( TEST ( u - > Flags , SPR_SO_ATTACHED ) )
{
SECTOR_OBJECTp sop ;
short sn , FoundSpriteNdx = - 1 ;
for ( sop = SectorObject ; sop < & SectorObject [ MAX_SECTOR_OBJECTS ] ; sop + + )
{
for ( sn = 0 ; sop - > sp_num [ sn ] ! = - 1 ; sn + + )
{
if ( sop - > sp_num [ sn ] = = SpriteNum )
{
FoundSpriteNdx = sn ;
}
}
if ( FoundSpriteNdx > = 0 )
{
// back up sn so it points to the last valid sprite num
sn - - ;
ASSERT ( sop - > sp_num [ sn ] > = 0 ) ;
2020-05-01 11:29:12 +00:00
so_stopspriteinterpolation ( sop , sp ) ;
2015-05-19 21:54:34 +00:00
// replace the one to be deleted with the last ndx
sop - > sp_num [ FoundSpriteNdx ] = sop - > sp_num [ sn ] ;
// the last ndx is not -1
sop - > sp_num [ sn ] = - 1 ;
break ;
}
}
ASSERT ( FoundSpriteNdx > = 0 ) ;
}
// if a player is dead and watching this sprite
// reset it.
TRAVERSE_CONNECT ( pnum )
{
pp = Player + pnum ;
if ( pp - > Killer > - 1 )
{
if ( pp - > Killer = = SpriteNum )
{
pp - > Killer = - 1 ;
}
}
}
// if on a track and died reset the track to non-occupied
if ( sp - > statnum = = STAT_ENEMY )
{
if ( u - > track ! = - 1 )
{
if ( Track [ u - > track ] . flags )
RESET ( Track [ u - > track ] . flags , TF_TRACK_OCCUPIED ) ;
}
}
// if missile is heading for the sprite, the missile need to know
// that it is already dead
if ( TEST ( sp - > extra , SPRX_PLAYER_OR_ENEMY ) )
{
USERp mu ;
static short MissileStats [ ] = { STAT_MISSILE , STAT_MISSILE_SKIP4 } ;
for ( stat = 0 ; stat < SIZ ( MissileStats ) ; stat + + )
{
TRAVERSE_SPRITE_STAT ( headspritestat [ MissileStats [ stat ] ] , i , nexti )
{
mu = User [ i ] ;
2020-01-21 22:36:54 +00:00
if ( mu & & mu - > WpnGoal = = SpriteNum )
2015-05-19 21:54:34 +00:00
{
mu - > WpnGoal = - 1 ;
}
}
}
}
// much faster
if ( TEST ( u - > Flags2 , SPR2_CHILDREN ) )
//if (TEST(sp->extra, SPRX_CHILDREN))
{
// check for children and allert them that the owner is dead
// don't bother th check if you've never had children
for ( stat = 0 ; stat < STAT_DONT_DRAW ; stat + + )
{
TRAVERSE_SPRITE_STAT ( headspritestat [ stat ] , i , nexti )
{
if ( sprite [ i ] . owner = = SpriteNum )
{
sprite [ i ] . owner = - 1 ;
}
if ( User [ i ] & & User [ i ] - > Attach = = SpriteNum )
{
User [ i ] - > Attach = - 1 ;
}
}
}
}
if ( sp - > statnum = = STAT_ENEMY )
{
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_ENEMY ] , i , nexti )
{
2019-11-17 17:02:17 +00:00
if ( ( unsigned ) i < MAXSPRITES & & User [ i ] ! = NULL & & User [ i ] - > tgt_sp = = sp )
2015-05-19 21:54:34 +00:00
{
DoActorPickClosePlayer ( i ) ;
}
}
}
if ( u - > flame > = 0 )
{
SetSuicide ( u - > flame ) ;
}
if ( u - > rotator )
{
if ( u - > rotator - > origx )
FreeMem ( u - > rotator - > origx ) ;
if ( u - > rotator - > origy )
FreeMem ( u - > rotator - > origy ) ;
FreeMem ( u - > rotator ) ;
}
FreeMem ( User [ SpriteNum ] ) ;
User [ SpriteNum ] = 0 ;
}
deletesprite ( SpriteNum ) ;
// shred your garbage - but not statnum
statnum = sp - > statnum ;
sectnum = sp - > sectnum ;
memset ( sp , 0xCC , sizeof ( SPRITE ) ) ;
sp - > statnum = statnum ;
sp - > sectnum = sectnum ;
2020-02-14 20:44:59 +00:00
// Kill references in all users - slow but unavoidable if we don't want the game to crash on stale pointers.
for ( auto u : User )
{
if ( u )
{
if ( u - > hi_sp = = sp ) u - > hi_sp = nullptr ;
if ( u - > lo_sp = = sp ) u - > lo_sp = nullptr ;
if ( u - > tgt_sp = = sp ) u - > tgt_sp = nullptr ;
}
}
2015-05-19 21:54:34 +00:00
}
2015-05-19 21:58:29 +00:00
void ChangeState ( short SpriteNum , STATEp statep )
2015-05-19 21:54:34 +00:00
{
USERp u = User [ SpriteNum ] ;
2019-12-22 10:21:22 +00:00
if ( u = = nullptr )
return ;
2015-05-19 21:54:34 +00:00
u - > Tics = 0 ;
u - > State = u - > StateStart = statep ;
// Just in case
PicAnimOff ( u - > State - > Pic ) ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
change_sprite_stat ( short SpriteNum , short stat )
{
USERp u = User [ SpriteNum ] ;
changespritestat ( SpriteNum , stat ) ;
if ( u )
{
RESET ( u - > Flags , SPR_SKIP2 | SPR_SKIP4 ) ;
if ( stat > = STAT_SKIP4_START & & stat < = STAT_SKIP4_END )
SET ( u - > Flags , SPR_SKIP4 ) ;
if ( stat > = STAT_SKIP2_START & & stat < = STAT_SKIP2_END )
SET ( u - > Flags , SPR_SKIP2 ) ;
switch ( stat )
{
//case STAT_DEAD_ACTOR:
//case STAT_ITEM:
//case STAT_SKIP4:
#if 0
case STAT_PLAYER0 :
case STAT_PLAYER1 :
case STAT_PLAYER2 :
case STAT_PLAYER3 :
case STAT_PLAYER4 :
case STAT_PLAYER5 :
case STAT_PLAYER6 :
case STAT_PLAYER7 :
# endif
case STAT_ENEMY_SKIP4 :
case STAT_ENEMY :
// for enemys - create offsets so all enemys don't call FAFcansee at once
wait_active_check_offset + = ACTORMOVETICS * 3 ;
if ( wait_active_check_offset > ACTIVE_CHECK_TIME )
wait_active_check_offset = 0 ;
u - > wait_active_check = wait_active_check_offset ;
// don't do a break here
SET ( u - > Flags , SPR_SHADOW ) ;
break ;
}
}
}
USERp
SpawnUser ( short SpriteNum , short id , STATEp state )
{
SPRITEp sp = & sprite [ SpriteNum ] ;
USERp u ;
ASSERT ( ! Prediction ) ;
User [ SpriteNum ] = u = ( USERp ) CallocMem ( sizeof ( USER ) , 1 ) ;
PRODUCTION_ASSERT ( u ! = NULL ) ;
// be careful State can be NULL
u - > State = u - > StateStart = state ;
change_sprite_stat ( SpriteNum , sp - > statnum ) ;
u - > ID = id ;
u - > Health = 100 ;
u - > WpnGoal = - 1 ; // for weapons
u - > Attach = - 1 ;
u - > track = - 1 ;
u - > tgt_sp = Player [ 0 ] . SpriteP ;
u - > Radius = 220 ;
u - > Sibling = - 1 ;
u - > flame = - 1 ;
u - > SpriteP = & sprite [ SpriteNum ] ;
u - > SpriteNum = SpriteNum ;
u - > WaitTics = 0 ;
u - > OverlapZ = Z ( 4 ) ;
u - > WallShade = NULL ;
u - > rotator = NULL ;
u - > bounce = 0 ;
u - > motion_blur_num = 0 ;
u - > motion_blur_dist = 256 ;
u - > ox = sp - > x ;
u - > oy = sp - > y ;
u - > oz = sp - > z ;
u - > active_range = MIN_ACTIVE_RANGE ;
// default
// based on clipmove z of 48 pixels off the floor
u - > floor_dist = Z ( 48 ) - Z ( 28 ) ;
u - > ceiling_dist = Z ( 8 ) ;
// Problem with sprites spawned really close to white sector walls
// cant do a getzrange there
// Just put in some valid starting values
#if 0
DoActorZrange ( SpriteNum ) ;
# else
u - > loz = sector [ sp - > sectnum ] . floorz ;
u - > hiz = sector [ sp - > sectnum ] . ceilingz ;
u - > lo_sp = NULL ;
u - > hi_sp = NULL ;
u - > lo_sectp = & sector [ sp - > sectnum ] ;
u - > hi_sectp = & sector [ sp - > sectnum ] ;
# endif
return u ;
}
SECT_USERp
GetSectUser ( short sectnum )
{
SECT_USERp sectu ;
if ( SectUser [ sectnum ] )
return SectUser [ sectnum ] ;
sectu = SectUser [ sectnum ] = ( SECT_USERp ) CallocMem ( sizeof ( SECT_USER ) , 1 ) ;
ASSERT ( sectu ! = NULL ) ;
return sectu ;
}
2015-05-19 21:58:29 +00:00
int16_t
2015-05-19 21:54:34 +00:00
SpawnSprite ( short stat , short id , STATEp state , short sectnum , int x , int y , int z , int init_ang , int vel )
{
SPRITEp sp ;
2015-05-19 21:58:29 +00:00
int16_t SpriteNum ;
2015-05-19 21:54:34 +00:00
USERp u ;
2019-11-17 17:02:17 +00:00
if ( sectnum < 0 )
return - 1 ;
2015-05-19 21:54:34 +00:00
ASSERT ( ! Prediction ) ;
2019-12-03 09:44:51 +00:00
// PRODUCTION_ASSERT(sectnum >= 0 && sectnum < MAXSECTORS);
2015-05-19 21:54:34 +00:00
SpriteNum = COVERinsertsprite ( sectnum , stat ) ;
ASSERT ( SpriteNum > = 0 & & SpriteNum < = MAXSPRITES ) ;
sp = & sprite [ SpriteNum ] ;
sp - > pal = 0 ;
sp - > x = x ;
sp - > y = y ;
sp - > z = z ;
sp - > cstat = 0 ;
User [ SpriteNum ] = u = SpawnUser ( SpriteNum , id , state ) ;
// be careful State can be NULL
if ( u - > State )
{
sp - > picnum = u - > State - > Pic ;
PicAnimOff ( sp - > picnum ) ;
}
sp - > shade = 0 ;
sp - > xrepeat = 64 ;
sp - > yrepeat = 64 ;
sp - > ang = NORM_ANGLE ( init_ang ) ;
sp - > xvel = vel ;
sp - > zvel = 0 ;
sp - > owner = - 1 ;
sp - > lotag = 0L ;
sp - > hitag = 0L ;
sp - > extra = 0 ;
sp - > xoffset = 0 ;
sp - > yoffset = 0 ;
sp - > clipdist = 0 ;
return SpriteNum ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
PicAnimOff ( short picnum )
{
2015-05-19 22:01:44 +00:00
short anim_type = TEST ( picanm [ picnum ] . sf , PICANM_ANIMTYPE_MASK ) > > PICANM_ANIMTYPE_SHIFT ;
2015-05-19 21:54:34 +00:00
ASSERT ( picnum > = 0 & & picnum < MAXTILES ) ;
if ( ! anim_type )
return ;
/*
2020-03-06 15:49:55 +00:00
int i ;
short num ;
2015-05-19 22:01:44 +00:00
num = picanm [ picnum ] . num ;
2015-05-19 21:54:34 +00:00
ASSERT ( num < 20 ) ;
for ( i = 0 ; i < num ; i + + )
{
2015-05-19 22:01:44 +00:00
RESET ( picanm [ picnum + i ] . sf , PICANM_ANIMTYPE_MASK ) ;
2015-05-19 21:54:34 +00:00
}
*/
2015-05-19 22:01:44 +00:00
RESET ( picanm [ picnum ] . sf , PICANM_ANIMTYPE_MASK ) ;
2015-05-19 21:54:34 +00:00
}
2015-05-19 21:58:29 +00:00
SWBOOL
2015-05-19 21:54:34 +00:00
IconSpawn ( SPRITEp sp )
{
// if multi item and not a modem game
if ( TEST ( sp - > extra , SPRX_MULTI_ITEM ) )
{
if ( numplayers < = 1 | | gNet . MultiGameType = = MULTI_GAME_COOPERATIVE )
return FALSE ;
}
return TRUE ;
}
2015-05-19 21:58:29 +00:00
SWBOOL
2015-05-19 21:54:34 +00:00
ActorTestSpawn ( SPRITEp sp )
{
if ( sp - > statnum = = STAT_DEFAULT & & sp - > lotag = = TAG_SPAWN_ACTOR )
{
2017-01-23 11:21:32 +00:00
short New ;
New = COVERinsertsprite ( sp - > sectnum , STAT_DEFAULT ) ;
memcpy ( & sprite [ New ] , sp , sizeof ( SPRITE ) ) ;
change_sprite_stat ( New , STAT_SPAWN_TRIGGER ) ;
RESET ( sprite [ New ] . cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
2015-05-19 21:54:34 +00:00
return FALSE ;
}
# if 1
if ( DebugActor )
return FALSE ;
# else
if ( DebugActor & & ! TEST ( sp - > extra , SPRX_BLOCK ) )
{
RESET ( sp - > extra , SPRX_BLOCK ) ; //reset so it can be used elsewhere
return FALSE ;
}
# endif
// Skill ranges from -1 (No Monsters) to 3
if ( TEST ( sp - > extra , SPRX_SKILL ) > Skill )
{
// JBF: hack to fix Wanton Destruction's missing Sumos, Serpents, and Zilla on Skill < 2
if ( ( ( sp - > picnum = = SERP_RUN_R0 | | sp - > picnum = = SUMO_RUN_R0 ) & & sp - > lotag > 0 & &
sp - > lotag ! = TAG_SPAWN_ACTOR & & sp - > extra > 0 ) | | sp - > picnum = = ZILLA_RUN_R0 )
{
const char * c ;
// NOTE: Wanton's $boat.map has two sumos, neither of which actually activate
// anything but are spawned in, and one of them has a skill level 2 mask. This
// hack however forces both sumos to appear on the easy levels. Bummer.
switch ( sp - > picnum )
{
case SERP_RUN_R0 : c = " serpent " ; break ;
case SUMO_RUN_R0 : c = " sumo " ; break ;
case ZILLA_RUN_R0 : c = " zilla " ; break ;
default : c = " ? " ; break ;
}
2020-04-11 21:45:45 +00:00
Printf ( " WARNING: skill-masked %s at %d,%d,%d not being killed because it "
2019-04-08 06:27:39 +00:00
" activates something \n " , c , TrackerCast ( sp - > x ) , TrackerCast ( sp - > y ) , TrackerCast ( sp - > z ) ) ;
2015-05-19 21:54:34 +00:00
return TRUE ;
}
2020-03-08 19:53:04 +00:00
//always spawn girls in addons
if ( ( sp - > picnum = = TOILETGIRL_R0 | |
sp - > picnum = = WASHGIRL_R0 | |
sp - > picnum = = MECHANICGIRL_R0 | |
sp - > picnum = = CARGIRL_R0 | |
sp - > picnum = = PRUNEGIRL_R0 | |
sp - > picnum = = SAILORGIRL_R0 ) & & ( g_gameType & GAMEFLAG_ADDON ) ) return TRUE ;
// spawn Bouncing Betty (mine) in TD Level 09 Warehouse
#if 0 // needs to be done smarter.
if ( sp - > picnum = = 817 & & swGetAddon ( ) = = 2 & & Level = = 9 )
return TRUE ;
# endif
2015-05-19 21:54:34 +00:00
return FALSE ;
}
return TRUE ;
}
2015-05-19 21:58:29 +00:00
void PreCacheRipper ( void ) ;
void PreCacheRipper2 ( void ) ;
void PreCacheCoolie ( void ) ;
void PreCacheSerpent ( void ) ;
void PreCacheGuardian ( void ) ;
void PreCacheNinja ( void ) ;
void PreCacheSumo ( void ) ;
void PreCacheEel ( void ) ;
void PreCacheToiletGirl ( void ) ;
void PreCacheWashGirl ( void ) ;
void PreCacheTrash ( void ) ;
void PreCacheBunny ( void ) ;
void PreCacheSkel ( void ) ;
void PreCacheHornet ( void ) ;
void PreCacheSkull ( void ) ;
void PreCacheBetty ( void ) ;
void PreCachePachinko ( void ) ;
SWBOOL
2015-05-19 21:54:34 +00:00
ActorSpawn ( SPRITEp sp )
{
int ret = TRUE ;
short SpriteNum = sp - sprite ;
switch ( sp - > picnum )
{
case COOLIE_RUN_R0 :
{
//PreCacheCoolie();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupCoolie ( SpriteNum ) ;
break ;
}
case NINJA_RUN_R0 :
case NINJA_CRAWL_R0 :
{
//PreCacheNinja();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupNinja ( SpriteNum ) ;
break ;
}
case GORO_RUN_R0 :
{
//PreCacheGuardian();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupGoro ( SpriteNum ) ;
break ;
}
case 1441 :
case COOLG_RUN_R0 :
{
//PreCacheGhost();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupCoolg ( SpriteNum ) ;
break ;
}
case EEL_RUN_R0 :
{
//PreCacheEel();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupEel ( SpriteNum ) ;
break ;
}
case SUMO_RUN_R0 :
{
//PreCacheSumo();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupSumo ( SpriteNum ) ;
break ;
}
case ZILLA_RUN_R0 :
{
//PreCacheSumo();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupZilla ( SpriteNum ) ;
break ;
}
case TOILETGIRL_R0 :
{
//PreCacheToiletGirl();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupToiletGirl ( SpriteNum ) ;
break ;
}
case WASHGIRL_R0 :
{
//PreCacheWashGirl();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupWashGirl ( SpriteNum ) ;
break ;
}
case CARGIRL_R0 :
{
//PreCacheCarGirl();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupCarGirl ( SpriteNum ) ;
break ;
}
case MECHANICGIRL_R0 :
{
//PreCacheMechanicGirl();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupMechanicGirl ( SpriteNum ) ;
break ;
}
case SAILORGIRL_R0 :
{
//PreCacheSailorGirl();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupSailorGirl ( SpriteNum ) ;
break ;
}
case PRUNEGIRL_R0 :
{
//PreCachePruneGirl();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupPruneGirl ( SpriteNum ) ;
break ;
}
case TRASHCAN :
{
//PreCacheTrash();
PicAnimOff ( sp - > picnum ) ;
SetupTrashCan ( SpriteNum ) ;
break ;
}
case BUNNY_RUN_R0 :
{
//PreCacheBunny();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupBunny ( SpriteNum ) ;
break ;
}
case RIPPER_RUN_R0 :
{
//PreCacheRipper();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupRipper ( SpriteNum ) ;
break ;
}
case RIPPER2_RUN_R0 :
{
//PreCacheRipper2();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupRipper2 ( SpriteNum ) ;
break ;
}
case SERP_RUN_R0 :
{
//PreCacheSerpent();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupSerp ( SpriteNum ) ;
break ;
}
case LAVA_RUN_R0 :
{
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupLava ( SpriteNum ) ;
break ;
}
case SKEL_RUN_R0 :
{
//PreCacheSkel();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupSkel ( SpriteNum ) ;
break ;
}
case HORNET_RUN_R0 :
{
//PreCacheHornet();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupHornet ( SpriteNum ) ;
break ;
}
case SKULL_R0 :
{
//PreCacheSkull();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupSkull ( SpriteNum ) ;
break ;
}
case BETTY_R0 :
{
//PreCacheBetty();
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupBetty ( SpriteNum ) ;
break ;
}
case 623 : // Pachinko win light
{
//PreCachePachinko();
PicAnimOff ( sp - > picnum ) ;
SetupPachinkoLight ( SpriteNum ) ;
break ;
}
case PACHINKO1 :
{
//PreCachePachinko();
PicAnimOff ( sp - > picnum ) ;
SetupPachinko1 ( SpriteNum ) ;
break ;
}
case PACHINKO2 :
{
//PreCachePachinko();
PicAnimOff ( sp - > picnum ) ;
SetupPachinko2 ( SpriteNum ) ;
break ;
}
case PACHINKO3 :
{
//PreCachePachinko();
PicAnimOff ( sp - > picnum ) ;
SetupPachinko3 ( SpriteNum ) ;
break ;
}
case PACHINKO4 :
{
//PreCachePachinko();
PicAnimOff ( sp - > picnum ) ;
SetupPachinko4 ( SpriteNum ) ;
break ;
}
case GIRLNINJA_RUN_R0 :
{
if ( ! ActorTestSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
return FALSE ;
}
PicAnimOff ( sp - > picnum ) ;
SetupGirlNinja ( SpriteNum ) ;
break ;
}
default :
ret = FALSE ;
break ;
}
return ret ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
IconDefault ( short SpriteNum )
{
SPRITEp sp = & sprite [ SpriteNum ] ;
USERp u = User [ SpriteNum ] ;
//if (sp->statnum == STAT_ITEM)
change_sprite_stat ( SpriteNum , STAT_ITEM ) ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
u - > Radius = 650 ;
DoActorZrange ( SpriteNum ) ;
}
2015-05-19 21:58:29 +00:00
void PreMapCombineFloors ( void )
2015-05-19 21:54:34 +00:00
{
# define MAX_FLOORS 32
SPRITEp sp ;
int i , j , k ;
2015-05-19 21:58:29 +00:00
int16_t SpriteNum , NextSprite ;
2015-05-19 21:54:34 +00:00
int base_offset ;
int dx , dy ;
short sectlist [ MAXSECTORS ] ;
short sectlistplc , sectlistend , dasect , startwall , endwall , nextsector ;
short pnum ;
typedef struct
{
SPRITEp offset ;
} BOUND_LIST ;
BOUND_LIST BoundList [ MAX_FLOORS ] ;
memset ( BoundList , 0 , MAX_FLOORS * sizeof ( BOUND_LIST ) ) ;
TRAVERSE_SPRITE_STAT ( headspritestat [ 0 ] , SpriteNum , NextSprite )
{
sp = & sprite [ SpriteNum ] ;
if ( sp - > picnum ! = ST1 )
continue ;
if ( sp - > hitag = = BOUND_FLOOR_OFFSET | | sp - > hitag = = BOUND_FLOOR_BASE_OFFSET )
{
ASSERT ( sp - > lotag < MAX_FLOORS ) ;
BoundList [ sp - > lotag ] . offset = sp ;
change_sprite_stat ( SpriteNum , STAT_FAF ) ;
}
}
for ( i = base_offset = 0 ; i < MAX_FLOORS ; i + + )
{
// blank so continue
if ( ! BoundList [ i ] . offset )
continue ;
if ( BoundList [ i ] . offset - > hitag = = BOUND_FLOOR_BASE_OFFSET )
{
base_offset = i ;
continue ;
}
dx = BoundList [ base_offset ] . offset - > x - BoundList [ i ] . offset - > x ;
dy = BoundList [ base_offset ] . offset - > y - BoundList [ i ] . offset - > y ;
sectlist [ 0 ] = BoundList [ i ] . offset - > sectnum ;
sectlistplc = 0 ; sectlistend = 1 ;
while ( sectlistplc < sectlistend )
{
dasect = sectlist [ sectlistplc + + ] ;
for ( j = headspritesect [ dasect ] ; j > = 0 ; j = nextspritesect [ j ] )
{
sprite [ j ] . x + = dx ;
sprite [ j ] . y + = dy ;
}
startwall = sector [ dasect ] . wallptr ;
endwall = startwall + sector [ dasect ] . wallnum ;
for ( j = startwall ; j < endwall ; j + + )
{
wall [ j ] . x + = dx ;
wall [ j ] . y + = dy ;
nextsector = wall [ j ] . nextsector ;
if ( nextsector < 0 ) continue ;
for ( k = sectlistend - 1 ; k > = 0 ; k - - )
if ( sectlist [ k ] = = nextsector )
break ;
if ( k < 0 )
sectlist [ sectlistend + + ] = nextsector ;
}
}
TRAVERSE_CONNECT ( pnum )
{
PLAYERp pp = & Player [ pnum ] ;
dasect = pp - > cursectnum ;
for ( j = 0 ; j < sectlistend ; j + + )
{
if ( sectlist [ j ] = = dasect )
{
pp - > posx + = dx ;
pp - > posy + = dy ;
pp - > oposx = pp - > oldposx = pp - > posx ;
pp - > oposy = pp - > oldposy = pp - > posy ;
break ;
}
}
}
}
// get rid of the sprites used
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_FAF ] , SpriteNum , NextSprite )
{
KillSprite ( SpriteNum ) ;
}
}
#if 0
// example of way to traverse through sectors from closest to farthest
2015-05-19 21:58:29 +00:00
void TraverseSectors ( short start_sect )
2015-05-19 21:54:34 +00:00
{
int i , j , k ;
short sectlist [ MAXSECTORS ] ;
short sectlistplc , sectlistend , sect , startwall , endwall , nextsector ;
sectlist [ 0 ] = start_sect ;
sectlistplc = 0 ; sectlistend = 1 ;
while ( sectlistplc < sectlistend )
{
sect = sectlist [ sectlistplc + + ] ;
startwall = sector [ sect ] . wallptr ;
endwall = startwall + sector [ sect ] . wallnum ;
for ( j = startwall ; j < endwall ; j + + )
{
nextsector = wall [ j ] . nextsector ;
if ( nextsector < 0 )
continue ;
// make sure its not on the list
for ( k = sectlistend - 1 ; k > = 0 ; k - - )
{
if ( sectlist [ k ] = = nextsector )
break ;
}
// if its not on the list add it to the end
if ( k < 0 )
sectlist [ sectlistend + + ] = nextsector ;
}
}
// list is finished - can now traverse it
#if 0
sect = pp - > cursectnum ;
for ( j = 0 ; j < sectlistend ; j + + )
{
if ( sectlist [ j ] = = sect )
{
break ;
}
}
# endif
}
# endif
2015-05-19 21:58:29 +00:00
void
SpriteSetupPost ( void )
2015-05-19 21:54:34 +00:00
{
SPRITEp ds ;
USERp u ;
short SpriteNum , NextSprite ;
short i , nexti ;
int cz , fz ;
// Post processing of some sprites after gone through the main SpriteSetup()
// routine
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_FLOOR_PAN ] , SpriteNum , NextSprite )
{
TRAVERSE_SPRITE_SECT ( headspritesect [ sprite [ SpriteNum ] . sectnum ] , i , nexti )
{
ds = & sprite [ i ] ;
if ( ds - > picnum = = ST1 )
continue ;
2018-02-16 06:38:31 +00:00
if ( TEST ( ds - > cstat , CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR ) )
2015-05-19 21:54:34 +00:00
continue ;
if ( User [ i ] )
continue ;
getzsofslope ( ds - > sectnum , ds - > x , ds - > y , & cz , & fz ) ;
if ( labs ( ds - > z - fz ) > Z ( 4 ) )
continue ;
u = SpawnUser ( i , 0 , NULL ) ;
change_sprite_stat ( i , STAT_NO_STATE ) ;
u - > ceiling_dist = Z ( 4 ) ;
u - > floor_dist = - Z ( 2 ) ;
u - > ActorActionFunc = DoActorDebris ;
SET ( ds - > cstat , CSTAT_SPRITE_BREAKABLE ) ;
SET ( ds - > extra , SPRX_BREAKABLE ) ;
}
}
}
2015-05-19 21:58:29 +00:00
void
SpriteSetup ( void )
2015-05-19 21:54:34 +00:00
{
SPRITEp sp ;
2020-03-06 15:49:49 +00:00
short SpriteNum = 0 , NextSprite ;
2015-05-19 21:54:34 +00:00
USERp u ;
short i , num ;
int cz , fz ;
// special case for player
PicAnimOff ( PLAYER_NINJA_RUN_R0 ) ;
// Clear Sprite Extension structure
memset ( & SectUser [ 0 ] , 0 , sizeof ( SectUser ) ) ;
// Clear all extra bits - they are set by sprites
for ( i = 0 ; i < numsectors ; i + + )
{
sector [ i ] . extra = 0 ;
}
2015-05-19 22:05:20 +00:00
// Clear PARALLAX_LEVEL overrides
parallaxyscale_override = 0 ;
pskybits_override = - 1 ;
2015-05-19 21:54:34 +00:00
// Call my little sprite setup routine first
JS_SpriteSetup ( ) ;
TRAVERSE_SPRITE_STAT ( headspritestat [ 0 ] , SpriteNum , NextSprite )
{
sp = & sprite [ SpriteNum ] ;
// not used yetv
getzsofslope ( sp - > sectnum , sp - > x , sp - > y , & cz , & fz ) ;
if ( sp - > z > DIV2 ( cz + fz ) )
{
// closer to a floor
SET ( sp - > cstat , CSTAT_SPRITE_CLOSE_FLOOR ) ;
}
// CSTAT_SPIN is insupported - get rid of it
2018-02-16 06:38:31 +00:00
if ( TEST ( sp - > cstat , CSTAT_SPRITE_ALIGNMENT ) = = CSTAT_SPRITE_ALIGNMENT_SLAB )
RESET ( sp - > cstat , CSTAT_SPRITE_ALIGNMENT_SLAB ) ;
2015-05-19 21:54:34 +00:00
// if BLOCK is set set BLOCK_HITSCAN
// Hope this doesn't screw up anything
if ( TEST ( sp - > cstat , CSTAT_SPRITE_BLOCK ) )
SET ( sp - > cstat , CSTAT_SPRITE_BLOCK_HITSCAN ) ;
////////////////////////////////////////////
//
// BREAKABLE CHECK
//
////////////////////////////////////////////
// USER SETUP - TAGGED BY USER
// Non ST1 sprites that are tagged like them
if ( TEST_BOOL1 ( sp ) & & sp - > picnum ! = ST1 )
{
RESET ( sp - > extra ,
SPRX_BOOL4 |
SPRX_BOOL5 |
SPRX_BOOL6 |
SPRX_BOOL7 |
SPRX_BOOL8 |
SPRX_BOOL9 |
SPRX_BOOL10 ) ;
switch ( sp - > hitag )
{
case BREAKABLE :
// need something that tells missiles to hit them
// but allows actors to move through them
sp - > clipdist = SPRITEp_SIZE_X ( sp ) ;
SET ( sp - > extra , SPRX_BREAKABLE ) ;
SET ( sp - > cstat , CSTAT_SPRITE_BREAKABLE ) ;
break ;
}
}
else
{
// BREAK SETUP TABLE AUTOMATED
SetupSpriteForBreak ( sp ) ;
}
if ( sp - > lotag = = TAG_SPRITE_HIT_MATCH )
{
// if multi item and not a modem game
if ( TEST ( sp - > extra , SPRX_MULTI_ITEM ) )
{
if ( numplayers < = 1 | | gNet . MultiGameType = = MULTI_GAME_COOPERATIVE )
{
KillSprite ( SpriteNum ) ;
continue ;
}
}
// crack sprite
if ( sp - > picnum = = 80 )
{
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
SET ( sp - > cstat , CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_BLOCK_MISSILE ) ; ;
}
else
{
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
SET ( sp - > cstat , CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_BLOCK_MISSILE ) ; ;
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ; ;
}
if ( TEST ( SP_TAG8 ( sp ) , BIT ( 0 ) ) )
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ; ;
if ( TEST ( SP_TAG8 ( sp ) , BIT ( 1 ) ) )
RESET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
change_sprite_stat ( SpriteNum , STAT_SPRITE_HIT_MATCH ) ;
continue ;
}
if ( sprite [ SpriteNum ] . picnum > = TRACK_SPRITE & &
sprite [ SpriteNum ] . picnum < = TRACK_SPRITE + MAX_TRACKS )
{
short track_num ;
// skip this sprite, just for numbering walls/sectors
2018-02-16 06:38:31 +00:00
if ( TEST ( sprite [ SpriteNum ] . cstat , CSTAT_SPRITE_ALIGNMENT_WALL ) )
2015-05-19 21:54:34 +00:00
continue ;
track_num = sprite [ SpriteNum ] . picnum - TRACK_SPRITE + 0 ;
change_sprite_stat ( SpriteNum , STAT_TRACK + track_num ) ;
continue ;
}
if ( ActorSpawn ( sp ) )
continue ;
switch ( sprite [ SpriteNum ] . picnum )
{
case ST_QUICK_JUMP :
change_sprite_stat ( SpriteNum , STAT_QUICK_JUMP ) ;
break ;
case ST_QUICK_JUMP_DOWN :
change_sprite_stat ( SpriteNum , STAT_QUICK_JUMP_DOWN ) ;
break ;
case ST_QUICK_SUPER_JUMP :
change_sprite_stat ( SpriteNum , STAT_QUICK_SUPER_JUMP ) ;
break ;
case ST_QUICK_SCAN :
change_sprite_stat ( SpriteNum , STAT_QUICK_SCAN ) ;
break ;
case ST_QUICK_EXIT :
change_sprite_stat ( SpriteNum , STAT_QUICK_EXIT ) ;
break ;
case ST_QUICK_OPERATE :
change_sprite_stat ( SpriteNum , STAT_QUICK_OPERATE ) ;
break ;
case ST_QUICK_DUCK :
change_sprite_stat ( SpriteNum , STAT_QUICK_DUCK ) ;
break ;
case ST_QUICK_DEFEND :
change_sprite_stat ( SpriteNum , STAT_QUICK_DEFEND ) ;
break ;
case ST1 :
{
SPRITEp sp = & sprite [ SpriteNum ] ;
SECT_USERp sectu ;
short tag ;
short bit ;
// get rid of defaults
if ( SP_TAG3 ( sp ) = = 32 )
SP_TAG3 ( sp ) = 0 ;
tag = sp - > hitag ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
// for bounding sector objects
if ( ( tag > = 500 & & tag < 600 ) | | tag = = SECT_SO_CENTER )
{
// NOTE: These will get deleted by the sector object
// setup code
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
break ;
}
if ( tag < 16 )
{
bit = 1 < < ( tag ) ;
SET ( sector [ sp - > sectnum ] . extra , bit ) ;
if ( TEST ( bit , SECTFX_SINK ) )
{
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > depth = sp - > lotag ;
KillSprite ( SpriteNum ) ;
}
else if ( TEST ( bit , SECTFX_OPERATIONAL ) )
{
KillSprite ( SpriteNum ) ;
}
else if ( TEST ( bit , SECTFX_CURRENT ) )
{
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > speed = sp - > lotag ;
sectu - > ang = sp - > ang ;
KillSprite ( SpriteNum ) ;
}
else if ( TEST ( bit , SECTFX_NO_RIDE ) )
{
change_sprite_stat ( SpriteNum , STAT_NO_RIDE ) ;
}
else if ( TEST ( bit , SECTFX_DIVE_AREA ) )
{
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > number = sp - > lotag ;
change_sprite_stat ( SpriteNum , STAT_DIVE_AREA ) ;
}
else if ( TEST ( bit , SECTFX_UNDERWATER ) )
{
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > number = sp - > lotag ;
change_sprite_stat ( SpriteNum , STAT_UNDERWATER ) ;
}
else if ( TEST ( bit , SECTFX_UNDERWATER2 ) )
{
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > number = sp - > lotag ;
if ( sp - > clipdist = = 1 )
SET ( sectu - > flags , SECTFU_CANT_SURFACE ) ;
change_sprite_stat ( SpriteNum , STAT_UNDERWATER2 ) ;
}
}
else
{
switch ( tag )
{
#if 0
case MULTI_PLAYER_START :
change_sprite_stat ( SpriteNum , STAT_MULTI_START + sp - > lotag ) ;
break ;
case MULTI_COOPERATIVE_START :
change_sprite_stat ( SpriteNum , STAT_CO_OP_START + sp - > lotag ) ;
break ;
# endif
case SECT_MATCH :
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > number = sp - > lotag ;
KillSprite ( SpriteNum ) ;
break ;
case SLIDE_SECTOR :
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_SLIDE_SECTOR ) ;
sectu - > speed = SP_TAG2 ( sp ) ;
KillSprite ( SpriteNum ) ;
break ;
case SECT_DAMAGE :
{
sectu = GetSectUser ( sp - > sectnum ) ;
if ( TEST_BOOL1 ( sp ) )
SET ( sectu - > flags , SECTFU_DAMAGE_ABOVE_SECTOR ) ;
sectu - > damage = sp - > lotag ;
KillSprite ( SpriteNum ) ;
break ;
}
case PARALLAX_LEVEL :
{
2015-05-19 22:05:20 +00:00
parallaxyscale_override = 8192 ;
pskybits_override = sp - > lotag ;
2015-05-19 21:54:34 +00:00
if ( SP_TAG4 ( sp ) > 2048 )
2015-05-19 22:05:20 +00:00
parallaxyscale_override = SP_TAG4 ( sp ) ;
2015-05-19 21:54:34 +00:00
KillSprite ( SpriteNum ) ;
break ;
}
case BREAKABLE :
// used for wall info
change_sprite_stat ( SpriteNum , STAT_BREAKABLE ) ;
break ;
case SECT_DONT_COPY_PALETTE :
{
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_DONT_COPY_PALETTE ) ;
KillSprite ( SpriteNum ) ;
break ;
}
case SECT_FLOOR_PAN :
{
// if moves with SO
if ( TEST_BOOL1 ( sp ) )
sp - > xvel = 0 ;
else
sp - > xvel = sp - > lotag ;
change_sprite_stat ( SpriteNum , STAT_FLOOR_PAN ) ;
break ;
}
case SECT_CEILING_PAN :
{
// if moves with SO
if ( TEST_BOOL1 ( sp ) )
sp - > xvel = 0 ;
else
sp - > xvel = sp - > lotag ;
change_sprite_stat ( SpriteNum , STAT_CEILING_PAN ) ;
break ;
}
case SECT_WALL_PAN_SPEED :
{
2015-05-19 22:01:22 +00:00
vec3_t hit_pos = { sp - > x , sp - > y , sp - > z - Z ( 8 ) } ;
hitdata_t hitinfo ;
2015-05-19 21:54:34 +00:00
2015-05-19 22:01:22 +00:00
hitscan ( & hit_pos , sp - > sectnum , // Start position
2015-05-19 21:54:34 +00:00
sintable [ NORM_ANGLE ( sp - > ang + 512 ) ] , // X vector of 3D ang
sintable [ sp - > ang ] , // Y vector of 3D ang
0 , // Z vector of 3D ang
2015-05-19 22:01:22 +00:00
& hitinfo , CLIPMASK_MISSILE ) ;
2015-05-19 21:54:34 +00:00
2015-05-19 22:01:22 +00:00
if ( hitinfo . wall = = - 1 )
2015-05-19 21:54:34 +00:00
{
KillSprite ( SpriteNum ) ;
break ;
}
2015-05-19 22:01:22 +00:00
sp - > owner = hitinfo . wall ;
2015-05-19 21:54:34 +00:00
// if moves with SO
if ( TEST_BOOL1 ( sp ) )
sp - > xvel = 0 ;
else
sp - > xvel = sp - > lotag ;
sp - > ang = SP_TAG6 ( sp ) ;
// attach to the sector that contains the wall
2015-05-19 22:01:22 +00:00
changespritesect ( SpriteNum , hitinfo . sect ) ;
2015-05-19 21:54:34 +00:00
change_sprite_stat ( SpriteNum , STAT_WALL_PAN ) ;
break ;
}
case WALL_DONT_STICK :
{
2015-05-19 22:01:22 +00:00
vec3_t hit_pos = { sp - > x , sp - > y , sp - > z - Z ( 8 ) } ;
hitdata_t hitinfo ;
2015-05-19 21:54:34 +00:00
2015-05-19 22:01:22 +00:00
hitscan ( & hit_pos , sp - > sectnum , // Start position
2015-05-19 21:54:34 +00:00
sintable [ NORM_ANGLE ( sp - > ang + 512 ) ] , // X vector of 3D ang
sintable [ sp - > ang ] , // Y vector of 3D ang
0 , // Z vector of 3D ang
2015-05-19 22:01:22 +00:00
& hitinfo , CLIPMASK_MISSILE ) ;
2015-05-19 21:54:34 +00:00
2015-05-19 22:01:22 +00:00
if ( hitinfo . wall = = - 1 )
2015-05-19 21:54:34 +00:00
{
KillSprite ( SpriteNum ) ;
break ;
}
2015-05-19 22:01:22 +00:00
SET ( wall [ hitinfo . wall ] . extra , WALLFX_DONT_STICK ) ;
2015-05-19 21:54:34 +00:00
KillSprite ( SpriteNum ) ;
break ;
}
case TRIGGER_SECTOR :
{
SET ( sector [ sp - > sectnum ] . extra , SECTFX_TRIGGER ) ;
change_sprite_stat ( SpriteNum , STAT_TRIGGER ) ;
break ;
}
case DELETE_SPRITE :
{
change_sprite_stat ( SpriteNum , STAT_DELETE_SPRITE ) ;
break ;
}
case SPAWN_ITEMS :
{
if ( TEST ( sp - > extra , SPRX_MULTI_ITEM ) )
{
if ( numplayers < = 1 | | gNet . MultiGameType = = MULTI_GAME_COOPERATIVE )
{
KillSprite ( SpriteNum ) ;
break ;
}
}
change_sprite_stat ( SpriteNum , STAT_SPAWN_ITEMS ) ;
break ;
}
case CEILING_FLOOR_PIC_OVERRIDE :
{
// block hitscans depending on translucency
if ( SP_TAG7 ( sp ) = = 0 | | SP_TAG7 ( sp ) = = 1 )
{
if ( SP_TAG3 ( sp ) = = 0 )
SET ( sector [ sp - > sectnum ] . ceilingstat , CEILING_STAT_FAF_BLOCK_HITSCAN ) ;
else
SET ( sector [ sp - > sectnum ] . floorstat , FLOOR_STAT_FAF_BLOCK_HITSCAN ) ;
}
else if ( TEST_BOOL1 ( sp ) )
{
if ( SP_TAG3 ( sp ) = = 0 )
SET ( sector [ sp - > sectnum ] . ceilingstat , CEILING_STAT_FAF_BLOCK_HITSCAN ) ;
else
SET ( sector [ sp - > sectnum ] . floorstat , FLOOR_STAT_FAF_BLOCK_HITSCAN ) ;
}
// copy tag 7 to tag 6 and pre-shift it
SP_TAG6 ( sp ) = SP_TAG7 ( sp ) ;
SP_TAG6 ( sp ) < < = 7 ;
change_sprite_stat ( SpriteNum , STAT_CEILING_FLOOR_PIC_OVERRIDE ) ;
break ;
}
case QUAKE_SPOT :
{
change_sprite_stat ( SpriteNum , STAT_QUAKE_SPOT ) ;
//SP_TAG13(sp) = (SP_TAG6(sp)*10L) * 120L;
SET_SP_TAG13 ( sp , ( ( SP_TAG6 ( sp ) * 10L ) * 120L ) ) ;
break ;
}
case SECT_CHANGOR :
{
change_sprite_stat ( SpriteNum , STAT_CHANGOR ) ;
break ;
}
#if 0
case SECT_DEBRIS_SEWER :
{
ANIMATOR DoGenerateSewerDebris ;
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
ASSERT ( u ! = NULL ) ;
u - > RotNum = 0 ;
u - > WaitTics = sp - > lotag * 120 ;
u - > ActorActionFunc = DoGenerateSewerDebris ;
change_sprite_stat ( SpriteNum , STAT_NO_STATE ) ;
break ;
}
# endif
case SECT_VATOR :
{
SECTORp sectp = & sector [ sp - > sectnum ] ;
SECT_USERp sectu ;
short speed , vel , time , type , start_on , floor_vator ;
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
// vator already set - ceiling AND floor vator
if ( TEST ( sectp - > extra , SECTFX_VATOR ) )
{
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_VATOR_BOTH ) ;
}
SET ( sectp - > extra , SECTFX_VATOR ) ;
SetSectorWallBits ( sp - > sectnum , WALLFX_DONT_STICK , TRUE , TRUE ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_DYNAMIC_AREA ) ;
// don't step on toes of other sector settings
if ( sectp - > lotag = = 0 & & sectp - > hitag = = 0 )
sectp - > lotag = TAG_VATOR ;
type = SP_TAG3 ( sp ) ;
speed = SP_TAG4 ( sp ) ;
vel = SP_TAG5 ( sp ) ;
time = SP_TAG9 ( sp ) ;
start_on = ! ! TEST_BOOL1 ( sp ) ;
floor_vator = TRUE ;
if ( TEST ( sp - > cstat , CSTAT_SPRITE_YFLIP ) )
floor_vator = FALSE ;
u - > jump_speed = u - > vel_tgt = speed ;
u - > vel_rate = vel ;
u - > WaitTics = time * 15 ; // 1/8 of a sec
u - > Tics = 0 ;
SET ( u - > Flags , SPR_ACTIVE ) ;
switch ( type )
{
case 0 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoVator ;
break ;
case 1 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoVator ;
break ;
case 2 :
u - > ActorActionFunc = DoVatorAuto ;
break ;
case 3 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoVatorAuto ;
break ;
}
if ( floor_vator )
{
// start off
u - > sz = sectp - > floorz ;
u - > z_tgt = sp - > z ;
if ( start_on )
{
int amt ;
amt = sp - > z - sectp - > floorz ;
// start in the on position
//sectp->floorz = sp->z;
sectp - > floorz + = amt ;
u - > z_tgt = u - > sz ;
MoveSpritesWithSector ( sp - > sectnum , amt , 0 ) ; // floor
}
// set orig z
u - > oz = sectp - > floorz ;
}
else
{
// start off
u - > sz = sectp - > ceilingz ;
u - > z_tgt = sp - > z ;
if ( start_on )
{
int amt ;
amt = sp - > z - sectp - > ceilingz ;
// starting in the on position
//sectp->ceilingz = sp->z;
sectp - > ceilingz + = amt ;
u - > z_tgt = u - > sz ;
MoveSpritesWithSector ( sp - > sectnum , amt , 1 ) ; // ceiling
}
// set orig z
u - > oz = sectp - > ceilingz ;
}
change_sprite_stat ( SpriteNum , STAT_VATOR ) ;
break ;
}
case SECT_ROTATOR_PIVOT :
{
change_sprite_stat ( SpriteNum , STAT_ROTATOR_PIVOT ) ;
break ;
}
case SECT_ROTATOR :
{
2019-10-09 17:58:09 +00:00
SECTORp sectp = & sector [ sp - > sectnum ] ;
2015-05-19 21:54:34 +00:00
short time , type ;
short wallcount , startwall , endwall , w ;
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
SetSectorWallBits ( sp - > sectnum , WALLFX_DONT_STICK , TRUE , TRUE ) ;
// need something for this
sectp - > lotag = TAG_ROTATOR ;
sectp - > hitag = sp - > lotag ;
type = SP_TAG3 ( sp ) ;
time = SP_TAG9 ( sp ) ;
u - > WaitTics = time * 15 ; // 1/8 of a sec
u - > Tics = 0 ;
startwall = sector [ sp - > sectnum ] . wallptr ;
endwall = startwall + sector [ sp - > sectnum ] . wallnum - 1 ;
// count walls of sector
for ( w = startwall , wallcount = 0 ; w < = endwall ; w + + )
wallcount + + ;
2019-04-08 06:25:59 +00:00
u - > rotator = ( ROTATORp ) CallocMem ( sizeof ( ROTATOR ) , 1 ) ;
2015-05-19 21:54:34 +00:00
u - > rotator - > num_walls = wallcount ;
u - > rotator - > open_dest = SP_TAG5 ( sp ) ;
u - > rotator - > speed = SP_TAG7 ( sp ) ;
u - > rotator - > vel = SP_TAG8 ( sp ) ;
u - > rotator - > pos = 0 ; // closed
u - > rotator - > tgt = u - > rotator - > open_dest ; // closed
2019-04-08 06:25:59 +00:00
u - > rotator - > origx = ( int * ) CallocMem ( sizeof ( u - > rotator - > origx ) * wallcount , 1 ) ;
u - > rotator - > origy = ( int * ) CallocMem ( sizeof ( u - > rotator - > origy ) * wallcount , 1 ) ;
2015-05-19 21:54:34 +00:00
u - > rotator - > orig_speed = u - > rotator - > speed ;
for ( w = startwall , wallcount = 0 ; w < = endwall ; w + + )
{
u - > rotator - > origx [ wallcount ] = wall [ w ] . x ;
u - > rotator - > origy [ wallcount ] = wall [ w ] . y ;
wallcount + + ;
}
SET ( u - > Flags , SPR_ACTIVE ) ;
switch ( type )
{
case 0 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoRotator ;
break ;
case 1 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoRotator ;
break ;
}
change_sprite_stat ( SpriteNum , STAT_ROTATOR ) ;
break ;
}
case SECT_SLIDOR :
{
SECTORp sectp = & sector [ sp - > sectnum ] ;
short time , type ;
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
SetSectorWallBits ( sp - > sectnum , WALLFX_DONT_STICK , TRUE , TRUE ) ;
// need something for this
sectp - > lotag = TAG_SLIDOR ;
sectp - > hitag = sp - > lotag ;
type = SP_TAG3 ( sp ) ;
time = SP_TAG9 ( sp ) ;
u - > WaitTics = time * 15 ; // 1/8 of a sec
u - > Tics = 0 ;
2019-04-08 06:25:59 +00:00
u - > rotator = ( ROTATORp ) CallocMem ( sizeof ( ROTATOR ) , 1 ) ;
2015-05-19 21:54:34 +00:00
u - > rotator - > open_dest = SP_TAG5 ( sp ) ;
u - > rotator - > speed = SP_TAG7 ( sp ) ;
u - > rotator - > vel = SP_TAG8 ( sp ) ;
u - > rotator - > pos = 0 ; // closed
u - > rotator - > tgt = u - > rotator - > open_dest ; // closed
u - > rotator - > num_walls = 0 ;
u - > rotator - > orig_speed = u - > rotator - > speed ;
SET ( u - > Flags , SPR_ACTIVE ) ;
switch ( type )
{
case 0 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoSlidor ;
break ;
case 1 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoSlidor ;
break ;
}
if ( TEST_BOOL5 ( sp ) )
{
DoSlidorInstantClose ( SpriteNum ) ;
}
change_sprite_stat ( SpriteNum , STAT_SLIDOR ) ;
break ;
}
case SECT_SPIKE :
{
short speed , vel , time , type , start_on , floor_vator ;
int floorz , ceilingz , trash ;
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
SetSectorWallBits ( sp - > sectnum , WALLFX_DONT_STICK , FALSE , TRUE ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_DYNAMIC_AREA ) ;
type = SP_TAG3 ( sp ) ;
speed = SP_TAG4 ( sp ) ;
vel = SP_TAG5 ( sp ) ;
time = SP_TAG9 ( sp ) ;
start_on = ! ! TEST_BOOL1 ( sp ) ;
floor_vator = TRUE ;
if ( TEST ( sp - > cstat , CSTAT_SPRITE_YFLIP ) )
floor_vator = FALSE ;
u - > jump_speed = u - > vel_tgt = speed ;
u - > vel_rate = vel ;
u - > WaitTics = time * 15 ; // 1/8 of a sec
u - > Tics = 0 ;
SET ( u - > Flags , SPR_ACTIVE ) ;
switch ( type )
{
case 0 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoSpike ;
break ;
case 1 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoSpike ;
break ;
case 2 :
u - > ActorActionFunc = DoSpikeAuto ;
break ;
case 3 :
RESET ( u - > Flags , SPR_ACTIVE ) ;
u - > ActorActionFunc = DoSpikeAuto ;
break ;
}
getzrangepoint ( sp - > x , sp - > y , sp - > z , sp - > sectnum , & ceilingz , & trash , & floorz , & trash ) ;
if ( floor_vator )
{
u - > zclip = floorz ;
// start off
u - > sz = u - > zclip ;
u - > z_tgt = sp - > z ;
if ( start_on )
{
// start in the on position
u - > zclip = sp - > z ;
u - > z_tgt = u - > sz ;
SpikeAlign ( SpriteNum ) ;
}
// set orig z
u - > oz = u - > zclip ;
}
else
{
u - > zclip = ceilingz ;
// start off
u - > sz = u - > zclip ;
u - > z_tgt = sp - > z ;
if ( start_on )
{
// starting in the on position
u - > zclip = sp - > z ;
u - > z_tgt = u - > sz ;
SpikeAlign ( SpriteNum ) ;
}
// set orig z
u - > oz = u - > zclip ;
}
change_sprite_stat ( SpriteNum , STAT_SPIKE ) ;
break ;
}
case LIGHTING :
{
short w , startwall , endwall ;
short wallcount ;
2015-05-19 21:58:29 +00:00
int8_t * wall_shade ;
2015-05-19 21:54:34 +00:00
USERp u ;
LIGHT_Tics ( sp ) = 0 ;
if ( LIGHT_ShadeInc ( sp ) = = 0 )
LIGHT_ShadeInc ( sp ) = 1 ;
// save off original floor and ceil shades
LIGHT_FloorShade ( sp ) = sector [ sp - > sectnum ] . floorshade ;
LIGHT_CeilingShade ( sp ) = sector [ sp - > sectnum ] . ceilingshade ;
startwall = sector [ sp - > sectnum ] . wallptr ;
endwall = startwall + sector [ sp - > sectnum ] . wallnum - 1 ;
// count walls of sector
for ( w = startwall , wallcount = 0 ; w < = endwall ; w + + )
{
wallcount + + ;
if ( TEST_BOOL5 ( sp ) )
{
if ( wall [ w ] . nextwall > = 0 )
wallcount + + ;
}
}
User [ SpriteNum ] = u = SpawnUser ( SpriteNum , 0 , NULL ) ;
u - > WallCount = wallcount ;
2019-04-08 06:25:59 +00:00
wall_shade = u - > WallShade = ( int8_t * ) CallocMem ( u - > WallCount * sizeof ( * u - > WallShade ) , 1 ) ;
2015-05-19 21:54:34 +00:00
// save off original wall shades
for ( w = startwall , wallcount = 0 ; w < = endwall ; w + + )
{
wall_shade [ wallcount ] = wall [ w ] . shade ;
wallcount + + ;
if ( TEST_BOOL5 ( sp ) )
{
2019-11-27 07:33:34 +00:00
uint16_t const nextwall = wall [ w ] . nextwall ;
if ( nextwall < MAXWALLS )
2015-05-19 21:54:34 +00:00
{
wall_shade [ wallcount ] = wall [ wall [ w ] . nextwall ] . shade ;
wallcount + + ;
}
}
}
u - > spal = sp - > pal ;
// DON'T USE COVER function
changespritestat ( SpriteNum , STAT_LIGHTING ) ;
break ;
}
case LIGHTING_DIFFUSE :
{
short w , startwall , endwall ;
short wallcount ;
2015-05-19 21:58:29 +00:00
int8_t * wall_shade ;
2015-05-19 21:54:34 +00:00
USERp u ;
LIGHT_Tics ( sp ) = 0 ;
// save off original floor and ceil shades
LIGHT_FloorShade ( sp ) = sector [ sp - > sectnum ] . floorshade ;
LIGHT_CeilingShade ( sp ) = sector [ sp - > sectnum ] . ceilingshade ;
startwall = sector [ sp - > sectnum ] . wallptr ;
endwall = startwall + sector [ sp - > sectnum ] . wallnum - 1 ;
// count walls of sector
for ( w = startwall , wallcount = 0 ; w < = endwall ; w + + )
{
wallcount + + ;
if ( TEST_BOOL5 ( sp ) )
{
if ( wall [ w ] . nextwall > = 0 )
wallcount + + ;
}
}
// !LIGHT
// make an wall_shade array and put it in User
User [ SpriteNum ] = u = SpawnUser ( SpriteNum , 0 , NULL ) ;
u - > WallCount = wallcount ;
2019-04-08 06:25:59 +00:00
wall_shade = u - > WallShade = ( int8_t * ) CallocMem ( u - > WallCount * sizeof ( * u - > WallShade ) , 1 ) ;
2015-05-19 21:54:34 +00:00
// save off original wall shades
for ( w = startwall , wallcount = 0 ; w < = endwall ; w + + )
{
wall_shade [ wallcount ] = wall [ w ] . shade ;
wallcount + + ;
if ( TEST_BOOL5 ( sp ) )
{
2019-11-27 07:33:34 +00:00
uint16_t const nextwall = wall [ w ] . nextwall ;
if ( nextwall < MAXWALLS )
2015-05-19 21:54:34 +00:00
{
wall_shade [ wallcount ] = wall [ wall [ w ] . nextwall ] . shade ;
wallcount + + ;
}
}
}
// DON'T USE COVER function
changespritestat ( SpriteNum , STAT_LIGHTING_DIFFUSE ) ;
break ;
}
case SECT_VATOR_DEST :
change_sprite_stat ( SpriteNum , STAT_VATOR ) ;
break ;
case SO_WALL_DONT_MOVE_UPPER :
change_sprite_stat ( SpriteNum , STAT_WALL_DONT_MOVE_UPPER ) ;
break ;
case SO_WALL_DONT_MOVE_LOWER :
change_sprite_stat ( SpriteNum , STAT_WALL_DONT_MOVE_LOWER ) ;
break ;
case FLOOR_SLOPE_DONT_DRAW :
change_sprite_stat ( SpriteNum , STAT_FLOOR_SLOPE_DONT_DRAW ) ;
break ;
case DEMO_CAMERA :
sp - > yvel = sp - > zvel = 100 ; //attempt horiz control
change_sprite_stat ( SpriteNum , STAT_DEMO_CAMERA ) ;
break ;
case LAVA_ERUPT :
{
u = SpawnUser ( SpriteNum , ST1 , NULL ) ;
change_sprite_stat ( SpriteNum , STAT_NO_STATE ) ;
u - > ActorActionFunc = DoLavaErupt ;
// interval between erupts
if ( SP_TAG10 ( sp ) = = 0 )
SP_TAG10 ( sp ) = 20 ;
// interval in seconds
u - > WaitTics = RANDOM_RANGE ( SP_TAG10 ( sp ) ) * 120 ;
// time to erupt
if ( SP_TAG9 ( sp ) = = 0 )
SP_TAG9 ( sp ) = 10 ;
sp - > z + = Z ( 30 ) ;
break ;
}
case SECT_EXPLODING_CEIL_FLOOR :
{
SECTORp sectp = & sector [ sp - > sectnum ] ;
SetSectorWallBits ( sp - > sectnum , WALLFX_DONT_STICK , FALSE , TRUE ) ;
if ( TEST ( sectp - > floorstat , FLOOR_STAT_SLOPE ) )
{
SP_TAG5 ( sp ) = sectp - > floorheinum ;
RESET ( sectp - > floorstat , FLOOR_STAT_SLOPE ) ;
sectp - > floorheinum = 0 ;
}
if ( TEST ( sectp - > ceilingstat , CEILING_STAT_SLOPE ) )
{
SP_TAG6 ( sp ) = sectp - > ceilingheinum ;
RESET ( sectp - > ceilingstat , CEILING_STAT_SLOPE ) ;
sectp - > ceilingheinum = 0 ;
}
SP_TAG4 ( sp ) = abs ( sectp - > ceilingz - sectp - > floorz ) > > 8 ;
sectp - > ceilingz = sectp - > floorz ;
change_sprite_stat ( SpriteNum , STAT_EXPLODING_CEIL_FLOOR ) ;
break ;
}
case SECT_COPY_SOURCE :
change_sprite_stat ( SpriteNum , STAT_COPY_SOURCE ) ;
break ;
case SECT_COPY_DEST :
{
SetSectorWallBits ( sp - > sectnum , WALLFX_DONT_STICK , FALSE , TRUE ) ;
change_sprite_stat ( SpriteNum , STAT_COPY_DEST ) ;
break ;
}
case SECT_WALL_MOVE :
change_sprite_stat ( SpriteNum , STAT_WALL_MOVE ) ;
break ;
case SECT_WALL_MOVE_CANSEE :
change_sprite_stat ( SpriteNum , STAT_WALL_MOVE_CANSEE ) ;
break ;
case SPRI_CLIMB_MARKER :
{
short ns ;
SPRITEp np ;
// setup climb marker
change_sprite_stat ( SpriteNum , STAT_CLIMB_MARKER ) ;
// make a QUICK_LADDER sprite automatically
ns = COVERinsertsprite ( sp - > sectnum , STAT_QUICK_LADDER ) ;
np = & sprite [ ns ] ;
np - > cstat = 0 ;
np - > extra = 0 ;
np - > x = sp - > x ;
np - > y = sp - > y ;
np - > z = sp - > z ;
np - > ang = NORM_ANGLE ( sp - > ang + 1024 ) ;
np - > picnum = sp - > picnum ;
np - > x + = MOVEx ( 256 + 128 , sp - > ang ) ;
np - > y + = MOVEy ( 256 + 128 , sp - > ang ) ;
break ;
}
case SO_AUTO_TURRET :
#if 0
switch ( gNet . MultiGameType )
{
case MULTI_GAME_NONE :
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
break ;
case MULTI_GAME_COMMBAT :
KillSprite ( SpriteNum ) ;
break ;
case MULTI_GAME_COOPERATIVE :
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
break ;
}
# else
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
# endif
break ;
case SO_DRIVABLE_ATTRIB :
case SO_SCALE_XY_MULT :
case SO_SCALE_INFO :
case SO_SCALE_POINT_INFO :
case SO_TORNADO :
case SO_FLOOR_MORPH :
case SO_AMOEBA :
case SO_SET_SPEED :
case SO_ANGLE :
case SO_SPIN :
case SO_SPIN_REVERSE :
case SO_BOB_START :
case SO_BOB_SPEED :
case SO_TURN_SPEED :
case SO_SYNC1 :
case SO_SYNC2 :
case SO_LIMIT_TURN :
case SO_MATCH_EVENT :
case SO_MAX_DAMAGE :
case SO_RAM_DAMAGE :
case SO_SLIDE :
case SO_KILLABLE :
case SECT_SO_SPRITE_OBJ :
case SECT_SO_DONT_ROTATE :
case SECT_SO_CLIP_DIST :
{
// NOTE: These will get deleted by the sector
// object
// setup code
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
break ;
}
case SOUND_SPOT :
//SP_TAG13(sp) = SP_TAG4(sp);
SET_SP_TAG13 ( sp , SP_TAG4 ( sp ) ) ;
change_sprite_stat ( SpriteNum , STAT_SOUND_SPOT ) ;
break ;
case STOP_SOUND_SPOT :
change_sprite_stat ( SpriteNum , STAT_STOP_SOUND_SPOT ) ;
break ;
case SPAWN_SPOT :
if ( ! User [ SpriteNum ] )
u = SpawnUser ( SpriteNum , ST1 , NULL ) ;
if ( SP_TAG14 ( sp ) = = ( ( 64 < < 8 ) | 64 ) )
//SP_TAG14(sp) = 0;
SET_SP_TAG14 ( sp , 0 ) ;
change_sprite_stat ( SpriteNum , STAT_SPAWN_SPOT ) ;
break ;
case VIEW_THRU_CEILING :
case VIEW_THRU_FLOOR :
{
int i , nexti ;
// make sure there is only one set per level of these
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_FAF ] , i , nexti )
{
if ( sprite [ i ] . hitag = = sp - > hitag & & sprite [ i ] . lotag = = sp - > lotag )
{
2019-12-25 10:26:19 +00:00
I_Error ( " Two VIEW_THRU_ tags with same match found on level \n 1: x %d, y %d \n 2: x %d, y %d " , TrackerCast ( sp - > x ) , TrackerCast ( sp - > y ) , TrackerCast ( sprite [ i ] . x ) , TrackerCast ( sprite [ i ] . y ) ) ;
2015-05-19 21:54:34 +00:00
}
}
change_sprite_stat ( SpriteNum , STAT_FAF ) ;
break ;
}
case VIEW_LEVEL1 :
case VIEW_LEVEL2 :
case VIEW_LEVEL3 :
case VIEW_LEVEL4 :
case VIEW_LEVEL5 :
case VIEW_LEVEL6 :
{
change_sprite_stat ( SpriteNum , STAT_FAF ) ;
break ;
}
case PLAX_GLOB_Z_ADJUST :
{
SET ( sector [ sp - > sectnum ] . extra , SECTFX_Z_ADJUST ) ;
PlaxCeilGlobZadjust = SP_TAG2 ( sp ) ;
PlaxFloorGlobZadjust = SP_TAG3 ( sp ) ;
KillSprite ( SpriteNum ) ;
break ;
}
case CEILING_Z_ADJUST :
{
//SET(sector[sp->sectnum].ceilingstat, CEILING_STAT_FAF_BLOCK_HITSCAN);
SET ( sector [ sp - > sectnum ] . extra , SECTFX_Z_ADJUST ) ;
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
break ;
}
case FLOOR_Z_ADJUST :
{
//SET(sector[sp->sectnum].floorstat, FLOOR_STAT_FAF_BLOCK_HITSCAN);
SET ( sector [ sp - > sectnum ] . extra , SECTFX_Z_ADJUST ) ;
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
break ;
}
case WARP_TELEPORTER :
{
short start_wall , wall_num ;
short sectnum = sp - > sectnum ;
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_WARP_SECTOR ) ;
change_sprite_stat ( SpriteNum , STAT_WARP ) ;
// if just a destination teleporter
// don't set up flags
if ( SP_TAG10 ( sp ) = = 1 )
break ;
// move the the next wall
wall_num = start_wall = sector [ sectnum ] . wallptr ;
// Travel all the way around loop setting wall bits
do
{
// DO NOT TAG WHITE WALLS!
2019-11-27 07:33:34 +00:00
if ( ( uint16_t ) wall [ wall_num ] . nextwall < MAXWALLS )
2015-05-19 21:54:34 +00:00
{
SET ( wall [ wall_num ] . cstat , CSTAT_WALL_WARP_HITSCAN ) ;
}
wall_num = wall [ wall_num ] . point2 ;
}
while ( wall_num ! = start_wall ) ;
break ;
}
case WARP_CEILING_PLANE :
case WARP_FLOOR_PLANE :
{
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_WARP_SECTOR ) ;
change_sprite_stat ( SpriteNum , STAT_WARP ) ;
break ;
}
case WARP_COPY_SPRITE1 :
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_WARP_SECTOR ) ;
change_sprite_stat ( SpriteNum , STAT_WARP_COPY_SPRITE1 ) ;
break ;
case WARP_COPY_SPRITE2 :
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_WARP_SECTOR ) ;
change_sprite_stat ( SpriteNum , STAT_WARP_COPY_SPRITE2 ) ;
break ;
case FIREBALL_TRAP :
case BOLT_TRAP :
case SPEAR_TRAP :
{
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
sp - > owner = - 1 ;
change_sprite_stat ( SpriteNum , STAT_TRAP ) ;
break ;
}
case SECT_SO_DONT_BOB :
{
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_SO_DONT_BOB ) ;
KillSprite ( SpriteNum ) ;
break ;
}
case SECT_LOCK_DOOR :
{
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > number = sp - > lotag ;
sectu - > stag = SECT_LOCK_DOOR ;
KillSprite ( SpriteNum ) ;
break ;
}
case SECT_SO_SINK_DEST :
{
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_SO_SINK_DEST ) ;
sectu - > number = sp - > lotag ; // acually the offset Z
// value
KillSprite ( SpriteNum ) ;
break ;
}
case SECT_SO_DONT_SINK :
{
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_SO_DONT_SINK ) ;
KillSprite ( SpriteNum ) ;
break ;
}
case SO_SLOPE_FLOOR_TO_POINT :
{
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_SO_SLOPE_FLOOR_TO_POINT ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_DYNAMIC_AREA ) ;
KillSprite ( SpriteNum ) ;
break ;
}
case SO_SLOPE_CEILING_TO_POINT :
{
sectu = GetSectUser ( sp - > sectnum ) ;
SET ( sectu - > flags , SECTFU_SO_SLOPE_CEILING_TO_POINT ) ;
SET ( sector [ sp - > sectnum ] . extra , SECTFX_DYNAMIC_AREA ) ;
KillSprite ( SpriteNum ) ;
break ;
}
case SECT_SO_FORM_WHIRLPOOL :
{
sectu = GetSectUser ( sp - > sectnum ) ;
sectu - > stag = SECT_SO_FORM_WHIRLPOOL ;
sectu - > height = sp - > lotag ;
KillSprite ( SpriteNum ) ;
break ;
}
case SECT_ACTOR_BLOCK :
{
short start_wall , wall_num ;
short sectnum = sp - > sectnum ;
// move the the next wall
wall_num = start_wall = sector [ sectnum ] . wallptr ;
// Travel all the way around loop setting wall bits
do
{
SET ( wall [ wall_num ] . cstat , CSTAT_WALL_BLOCK_ACTOR ) ;
2019-11-27 07:33:34 +00:00
uint16_t const nextwall = wall [ wall_num ] . nextwall ;
if ( nextwall < MAXWALLS )
SET ( wall [ nextwall ] . cstat , CSTAT_WALL_BLOCK_ACTOR ) ;
2015-05-19 21:54:34 +00:00
wall_num = wall [ wall_num ] . point2 ;
}
while ( wall_num ! = start_wall ) ;
KillSprite ( SpriteNum ) ;
break ;
}
}
}
}
break ;
case RED_CARD :
num = 4 ;
goto KeyMain ;
case RED_KEY :
num = 0 ;
goto KeyMain ;
case BLUE_CARD :
num = 5 ;
goto KeyMain ;
case BLUE_KEY :
num = 1 ;
goto KeyMain ;
case GREEN_CARD :
num = 6 ;
goto KeyMain ;
case GREEN_KEY :
num = 2 ;
goto KeyMain ;
case YELLOW_CARD :
num = 7 ;
goto KeyMain ;
case YELLOW_KEY :
num = 3 ;
goto KeyMain ;
case GOLD_SKELKEY :
num = 8 ;
goto KeyMain ;
case SILVER_SKELKEY :
num = 9 ;
goto KeyMain ;
case BRONZE_SKELKEY :
num = 10 ;
goto KeyMain ;
case RED_SKELKEY :
num = 11 ;
KeyMain :
{
if ( gNet . MultiGameType = = MULTI_GAME_COMMBAT | | gNet . MultiGameType = = MULTI_GAME_AI_BOTS )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
ASSERT ( u ! = NULL ) ;
sprite [ SpriteNum ] . picnum = u - > ID = sprite [ SpriteNum ] . picnum ;
u - > spal = sprite [ SpriteNum ] . pal ; // Set the palette from build
2018-02-16 06:38:31 +00:00
//SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL);
2015-05-19 21:54:34 +00:00
ChangeState ( SpriteNum , s_Key [ num ] ) ;
2015-05-19 22:01:44 +00:00
RESET ( picanm [ sp - > picnum ] . sf , PICANM_ANIMTYPE_MASK ) ;
RESET ( picanm [ sp - > picnum + 1 ] . sf , PICANM_ANIMTYPE_MASK ) ;
2015-05-19 21:54:34 +00:00
change_sprite_stat ( SpriteNum , STAT_ITEM ) ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
u - > Radius = 500 ;
sp - > hitag = LUMINOUS ; //Set so keys over ride colored lighting
DoActorZrange ( SpriteNum ) ;
}
break ;
#if 0
case RED_KEY_STATUE :
num = 0 ;
goto KeyStatueMain ;
case BLUE_KEY_STATUE :
num = 1 ;
goto KeyStatueMain ;
case GREEN_KEY_STATUE :
num = 2 ;
goto KeyStatueMain ;
case YELLOW_KEY_STATUE :
num = 3 ;
KeyStatueMain :
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
ASSERT ( u ! = NULL ) ;
sprite [ SpriteNum ] . picnum = u - > ID = sprite [ SpriteNum ] . picnum ;
u - > spal = sp - > pal ;
ChangeState ( SpriteNum , s_KeyStatue [ num ] ) ;
2015-05-19 22:01:44 +00:00
RESET ( picanm [ sp - > picnum ] . sf , PICANM_ANIMTYPE_MASK ) ;
RESET ( picanm [ sp - > picnum + 1 ] . sf , PICANM_ANIMTYPE_MASK ) ;
2015-05-19 21:54:34 +00:00
change_sprite_stat ( SpriteNum , STAT_ITEM ) ;
DoActorZrange ( SpriteNum ) ;
break ;
# endif
// Used for multiplayer locks
case 1846 :
case 1850 :
case 1852 :
case 2470 :
if ( TEST ( sprite [ SpriteNum ] . extra , SPRX_MULTI_ITEM ) )
if ( numplayers < = 1 | | gNet . MultiGameType = = MULTI_GAME_COOPERATIVE )
{
KillSprite ( SpriteNum ) ;
}
break ;
case FIRE_FLY0 :
/*
* u = SpawnUser ( SpriteNum , FIRE_FLY0 , NULL ) ;
*
* u - > State = u - > StateStart = & s_FireFly [ 0 ] ; u - > RotNum = 0 ;
*
* sp - > ang = 0 ; sp - > xvel = 4 ;
*
* if ( labs ( sp - > z - sector [ sp - > sectnum ] . floorz ) < Z ( 32 ) ) sp - > z =
* sector [ sp - > sectnum ] . floorz - Z ( 32 ) ;
*
* u - > sz = sp - > z ;
*
* change_sprite_stat ( SpriteNum , STAT_MISC ) ;
*/
break ;
case ICON_REPAIR_KIT :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_REPAIR_KIT , s_RepairKit ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_STAR :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_STAR , s_IconStar ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_LG_MINE :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_LG_MINE , s_IconLgMine ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_MICRO_GUN :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_MICRO_GUN , s_IconMicroGun ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_MICRO_BATTERY :
NUKE_REPLACEMENT :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_MICRO_BATTERY , s_IconMicroBattery ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_UZI :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_UZI , s_IconUzi ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_UZIFLOOR :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_UZIFLOOR , s_IconUziFloor ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_LG_UZI_AMMO :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_LG_UZI_AMMO , s_IconLgUziAmmo ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_GRENADE_LAUNCHER :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_GRENADE_LAUNCHER , s_IconGrenadeLauncher ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_LG_GRENADE :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_LG_GRENADE , s_IconLgGrenade ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_RAIL_GUN :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_RAIL_GUN , s_IconRailGun ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_RAIL_AMMO :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_RAIL_AMMO , s_IconRailAmmo ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_ROCKET :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_ROCKET , s_IconRocket ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_LG_ROCKET :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_LG_ROCKET , s_IconLgRocket ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_SHOTGUN :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_SHOTGUN , s_IconShotgun ) ;
u - > Radius = 350 ; // Shotgun is hard to pick up for some reason.
IconDefault ( SpriteNum ) ;
break ;
case ICON_LG_SHOTSHELL :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_LG_SHOTSHELL , s_IconLgShotshell ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_AUTORIOT :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_AUTORIOT , s_IconAutoRiot ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_GUARD_HEAD :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_GUARD_HEAD , s_IconGuardHead ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_FIREBALL_LG_AMMO :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_FIREBALL_LG_AMMO , s_IconFireballLgAmmo ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_HEART :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_HEART , s_IconHeart ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_HEART_LG_AMMO :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_HEART_LG_AMMO , s_IconHeartLgAmmo ) ;
IconDefault ( SpriteNum ) ;
break ;
#if 0
case ICON_ELECTRO :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_ELECTRO , s_IconElectro ) ;
IconDefault ( SpriteNum ) ;
break ;
# endif
case ICON_SPELL :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_SPELL , s_IconSpell ) ;
IconDefault ( SpriteNum ) ;
PicAnimOff ( sp - > picnum ) ;
break ;
case ICON_ARMOR :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_ARMOR , s_IconArmor ) ;
if ( sp - > pal ! = PALETTE_PLAYER3 )
sp - > pal = u - > spal = PALETTE_PLAYER1 ;
else
sp - > pal = u - > spal = PALETTE_PLAYER3 ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_MEDKIT :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_MEDKIT , s_IconMedkit ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_SM_MEDKIT :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_SM_MEDKIT , s_IconSmMedkit ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_CHEMBOMB :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_CHEMBOMB , s_IconChemBomb ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_FLASHBOMB :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_FLASHBOMB , s_IconFlashBomb ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_NUKE :
if ( gNet . MultiGameType )
{
if ( ! gNet . Nuke )
{
goto NUKE_REPLACEMENT ;
break ;
}
}
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_NUKE , s_IconNuke ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_CALTROPS :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_CALTROPS , s_IconCaltrops ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_BOOSTER :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_BOOSTER , s_IconBooster ) ;
IconDefault ( SpriteNum ) ;
break ;
case ICON_HEAT_CARD :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_HEAT_CARD , s_IconHeatCard ) ;
IconDefault ( SpriteNum ) ;
break ;
#if 0
case ICON_ENVIRON_SUIT :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_ENVIRON_SUIT , s_IconEnvironSuit ) ;
IconDefault ( SpriteNum ) ;
PicAnimOff ( sp - > picnum ) ;
break ;
# endif
case ICON_CLOAK :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_CLOAK , s_IconCloak ) ;
IconDefault ( SpriteNum ) ;
PicAnimOff ( sp - > picnum ) ;
break ;
case ICON_FLY :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_FLY , s_IconFly ) ;
IconDefault ( SpriteNum ) ;
PicAnimOff ( sp - > picnum ) ;
break ;
case ICON_NIGHT_VISION :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_NIGHT_VISION , s_IconNightVision ) ;
IconDefault ( SpriteNum ) ;
PicAnimOff ( sp - > picnum ) ;
break ;
case ICON_FLAG :
if ( ! IconSpawn ( sp ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u = SpawnUser ( SpriteNum , ICON_FLAG , s_IconFlag ) ;
u - > spal = sp - > pal ;
sector [ sp - > sectnum ] . hitag = 9000 ; // Put flag's color in sect containing it
sector [ sp - > sectnum ] . lotag = u - > spal ;
IconDefault ( SpriteNum ) ;
PicAnimOff ( sp - > picnum ) ;
break ;
#if 0
case 380 :
case 396 :
case 430 :
case 512 :
case 521 :
case 541 :
case 2720 :
# endif
case 3143 :
case 3157 :
{
u = SpawnUser ( SpriteNum , sp - > picnum , NULL ) ;
change_sprite_stat ( SpriteNum , STAT_STATIC_FIRE ) ;
u - > ID = FIREBALL_FLAMES ;
u - > Radius = 200 ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK_HITSCAN ) ;
sp - > hitag = LUMINOUS ; //Always full brightness
sp - > shade = - 40 ;
break ;
}
// blades
case BLADE1 :
case BLADE2 :
case BLADE3 :
case 5011 :
{
u = SpawnUser ( SpriteNum , sp - > picnum , NULL ) ;
change_sprite_stat ( SpriteNum , STAT_DEFAULT ) ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
SET ( sp - > cstat , CSTAT_SPRITE_BLOCK_HITSCAN ) ;
SET ( sp - > extra , SPRX_BLADE ) ;
break ;
}
case BREAK_LIGHT :
case BREAK_BARREL :
case BREAK_PEDISTAL :
case BREAK_BOTTLE1 :
case BREAK_BOTTLE2 :
case BREAK_MUSHROOM :
//if (TEST(sp->extra, SPRX_BREAKABLE))
// break;
u = SpawnUser ( SpriteNum , sp - > picnum , NULL ) ;
sp - > clipdist = SPRITEp_SIZE_X ( sp ) ;
SET ( sp - > cstat , CSTAT_SPRITE_BREAKABLE ) ;
SET ( sp - > extra , SPRX_BREAKABLE ) ;
break ;
// switches
case 581 :
case 582 :
case 558 :
case 559 :
case 560 :
case 561 :
case 562 :
case 563 :
case 564 :
case 565 :
case 566 :
case 567 :
case 568 :
case 569 :
case 570 :
case 571 :
case 572 :
case 573 :
case 574 :
case 551 :
case 552 :
case 575 :
case 576 :
case 577 :
case 578 :
case 579 :
case 589 :
case 583 :
case 584 :
case 553 :
case 554 :
{
if ( TEST ( sp - > extra , SPRX_MULTI_ITEM ) )
{
if ( numplayers < = 1 | | gNet . MultiGameType = = MULTI_GAME_COOPERATIVE )
{
KillSprite ( SpriteNum ) ;
break ;
}
}
SET ( sp - > cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
break ;
}
}
}
}
2015-05-19 21:58:29 +00:00
SWBOOL ItemSpotClear ( SPRITEp sip , short statnum , short id )
2015-05-19 21:54:34 +00:00
{
2015-05-19 21:58:29 +00:00
SWBOOL found = FALSE ;
2015-05-19 21:54:34 +00:00
short i , nexti ;
if ( TEST_BOOL2 ( sip ) )
{
TRAVERSE_SPRITE_SECT ( headspritesect [ sip - > sectnum ] , i , nexti )
{
if ( sprite [ i ] . statnum = = statnum & & User [ i ] - > ID = = id )
{
found = TRUE ;
break ;
}
}
}
return ! found ;
}
2015-05-19 21:58:29 +00:00
void SetupItemForJump ( SPRITEp sip , short SpriteNum )
2015-05-19 21:54:34 +00:00
{
SPRITEp sp = & sprite [ SpriteNum ] ;
USERp u = User [ SpriteNum ] ;
// setup item for jumping
if ( SP_TAG7 ( sip ) )
{
change_sprite_stat ( SpriteNum , STAT_SKIP4 ) ;
u - > ceiling_dist = Z ( 6 ) ;
u - > floor_dist = Z ( 0 ) ;
u - > Counter = 0 ;
sp - > xvel = ( int ) SP_TAG7 ( sip ) < < 2 ;
sp - > zvel = - ( ( ( int ) SP_TAG8 ( sip ) ) < < 5 ) ;
u - > xchange = MOVEx ( sp - > xvel , sp - > ang ) ;
u - > ychange = MOVEy ( sp - > xvel , sp - > ang ) ;
u - > zchange = sp - > zvel ;
}
}
int ActorCoughItem ( short SpriteNum )
{
SPRITEp sp = & sprite [ SpriteNum ] ;
USERp u = User [ SpriteNum ] ;
2017-01-23 11:21:32 +00:00
short New , choose ;
2015-05-19 21:54:34 +00:00
SPRITEp np ;
switch ( u - > ID )
{
case SAILORGIRL_R0 :
ASSERT ( sp - > sectnum > = 0 ) ;
2017-01-23 11:21:32 +00:00
New = COVERinsertsprite ( sp - > sectnum , STAT_SPAWN_ITEMS ) ;
ASSERT ( New > = 0 ) ;
np = & sprite [ New ] ;
2015-05-19 21:54:34 +00:00
np - > cstat = np - > extra = 0 ;
np - > x = sp - > x ;
np - > y = sp - > y ;
np - > z = SPRITEp_MID ( sp ) ;
np - > ang = 0 ;
np - > extra = 0 ;
// vel
SP_TAG7 ( np ) = 1 ;
// zvel
SP_TAG8 ( np ) = 40 ;
choose = RANDOM_P2 ( 1024 ) ;
if ( choose > 854 )
SP_TAG3 ( np ) = 91 ; // Match number
else if ( choose > 684 )
SP_TAG3 ( np ) = 48 ; // Match number
else if ( choose > 514 )
SP_TAG3 ( np ) = 58 ; // Match number
else if ( choose > 344 )
SP_TAG3 ( np ) = 60 ; // Match number
else if ( choose > 174 )
SP_TAG3 ( np ) = 62 ; // Match number
else
SP_TAG3 ( np ) = 68 ; // Match number
// match
SP_TAG2 ( np ) = - 1 ;
// kill
RESET_BOOL1 ( np ) ;
SpawnItemsMatch ( - 1 ) ;
break ;
case GORO_RUN_R0 :
if ( RANDOM_P2 ( 1024 ) < 700 )
return 0 ;
ASSERT ( sp - > sectnum > = 0 ) ;
2017-01-23 11:21:32 +00:00
New = COVERinsertsprite ( sp - > sectnum , STAT_SPAWN_ITEMS ) ;
ASSERT ( New > = 0 ) ;
np = & sprite [ New ] ;
2015-05-19 21:54:34 +00:00
np - > cstat = np - > extra = 0 ;
np - > x = sp - > x ;
np - > y = sp - > y ;
np - > z = SPRITEp_MID ( sp ) ;
np - > ang = 0 ;
np - > extra = 0 ;
// vel
SP_TAG7 ( np ) = 1 ;
// zvel
SP_TAG8 ( np ) = 40 ;
SP_TAG3 ( np ) = 69 ; // Match number
// match
SP_TAG2 ( np ) = - 1 ;
// kill
RESET_BOOL1 ( np ) ;
SpawnItemsMatch ( - 1 ) ;
break ;
case RIPPER2_RUN_R0 :
if ( RANDOM_P2 ( 1024 ) < 700 )
return 0 ;
ASSERT ( sp - > sectnum > = 0 ) ;
2017-01-23 11:21:32 +00:00
New = COVERinsertsprite ( sp - > sectnum , STAT_SPAWN_ITEMS ) ;
ASSERT ( New > = 0 ) ;
np = & sprite [ New ] ;
2015-05-19 21:54:34 +00:00
np - > cstat = np - > extra = 0 ;
np - > x = sp - > x ;
np - > y = sp - > y ;
np - > z = SPRITEp_MID ( sp ) ;
np - > ang = 0 ;
np - > extra = 0 ;
// vel
SP_TAG7 ( np ) = 1 ;
// zvel
SP_TAG8 ( np ) = 40 ;
SP_TAG3 ( np ) = 70 ; // Match number
// match
SP_TAG2 ( np ) = - 1 ;
// kill
RESET_BOOL1 ( np ) ;
SpawnItemsMatch ( - 1 ) ;
break ;
case NINJA_RUN_R0 :
if ( u - > PlayerP )
{
if ( RANDOM_P2 ( 1024 ) > 200 )
return 0 ;
ASSERT ( sp - > sectnum > = 0 ) ;
2017-01-23 11:21:32 +00:00
New = COVERinsertsprite ( sp - > sectnum , STAT_SPAWN_ITEMS ) ;
ASSERT ( New > = 0 ) ;
np = & sprite [ New ] ;
2015-05-19 21:54:34 +00:00
np - > cstat = 0 ;
np - > extra = 0 ;
np - > x = sp - > x ;
np - > y = sp - > y ;
np - > z = SPRITEp_MID ( sp ) ;
np - > ang = 0 ;
np - > extra = 0 ;
// vel
SP_TAG7 ( np ) = 1 ;
// zvel
SP_TAG8 ( np ) = 40 ;
switch ( u - > WeaponNum )
{
case WPN_UZI :
SP_TAG3 ( np ) = 0 ;
break ;
case WPN_SHOTGUN :
SP_TAG3 ( np ) = 51 ;
break ;
case WPN_STAR :
if ( u - > PlayerP - > WpnAmmo [ WPN_STAR ] < 9 )
break ;
SP_TAG3 ( np ) = 41 ;
break ;
case WPN_MINE :
if ( u - > PlayerP - > WpnAmmo [ WPN_MINE ] < 5 )
break ;
SP_TAG3 ( np ) = 42 ;
break ;
case WPN_MICRO :
case WPN_ROCKET :
SP_TAG3 ( np ) = 43 ;
break ;
case WPN_GRENADE :
SP_TAG3 ( np ) = 45 ;
break ;
case WPN_RAIL :
SP_TAG3 ( np ) = 47 ;
break ;
case WPN_HEART :
SP_TAG3 ( np ) = 55 ;
break ;
case WPN_HOTHEAD :
SP_TAG3 ( np ) = 53 ;
break ;
}
// match
SP_TAG2 ( np ) = - 1 ;
// kill
RESET_BOOL1 ( np ) ;
SpawnItemsMatch ( - 1 ) ;
break ;
}
if ( RANDOM_P2 ( 1024 ) < 512 )
return 0 ;
ASSERT ( sp - > sectnum > = 0 ) ;
2017-01-23 11:21:32 +00:00
New = COVERinsertsprite ( sp - > sectnum , STAT_SPAWN_ITEMS ) ;
ASSERT ( New > = 0 ) ;
np = & sprite [ New ] ;
2015-05-19 21:54:34 +00:00
np - > cstat = np - > extra = 0 ;
np - > x = sp - > x ;
np - > y = sp - > y ;
np - > z = SPRITEp_MID ( sp ) ;
np - > ang = 0 ;
np - > extra = 0 ;
// vel
SP_TAG7 ( np ) = 1 ;
// zvel
SP_TAG8 ( np ) = 40 ;
if ( u - > spal = = PAL_XLAT_LT_TAN )
{
SP_TAG3 ( np ) = 44 ;
}
else if ( u - > spal = = PAL_XLAT_LT_GREY )
{
SP_TAG3 ( np ) = 46 ;
}
else if ( u - > spal = = PALETTE_PLAYER5 ) // Green Ninja
{
if ( RANDOM_P2 ( 1024 ) < 700 )
SP_TAG3 ( np ) = 61 ;
else
SP_TAG3 ( np ) = 60 ;
}
else if ( u - > spal = = PALETTE_PLAYER3 ) // Red Ninja
{
// type
if ( RANDOM_P2 ( 1024 ) < 800 )
SP_TAG3 ( np ) = 68 ;
else
SP_TAG3 ( np ) = 44 ;
}
else
{
if ( RANDOM_P2 ( 1024 ) < 512 )
SP_TAG3 ( np ) = 41 ;
else
SP_TAG3 ( np ) = 68 ;
}
// match
SP_TAG2 ( np ) = - 1 ;
// kill
RESET_BOOL1 ( np ) ;
SpawnItemsMatch ( - 1 ) ;
break ;
case PACHINKO1 :
case PACHINKO2 :
case PACHINKO3 :
case PACHINKO4 :
ASSERT ( sp - > sectnum > = 0 ) ;
2017-01-23 11:21:32 +00:00
New = COVERinsertsprite ( sp - > sectnum , STAT_SPAWN_ITEMS ) ;
ASSERT ( New > = 0 ) ;
np = & sprite [ New ] ;
2015-05-19 21:54:34 +00:00
np - > cstat = np - > extra = 0 ;
np - > x = sp - > x ;
np - > y = sp - > y ;
np - > z = SPRITEp_LOWER ( sp ) + Z ( 10 ) ;
np - > ang = sp - > ang ;
// vel
SP_TAG7 ( np ) = 10 ;
// zvel
SP_TAG8 ( np ) = 10 ;
if ( u - > ID = = PACHINKO1 )
{
if ( RANDOM_P2 ( 1024 ) < 600 )
SP_TAG3 ( np ) = 64 ; // Small MedKit
else
SP_TAG3 ( np ) = 59 ; // Fortune Cookie
}
else if ( u - > ID = = PACHINKO2 )
{
if ( RANDOM_P2 ( 1024 ) < 600 )
SP_TAG3 ( np ) = 52 ; // Lg Shot Shell
else
SP_TAG3 ( np ) = 68 ; // Uzi clip
}
else if ( u - > ID = = PACHINKO3 )
{
if ( RANDOM_P2 ( 1024 ) < 600 )
SP_TAG3 ( np ) = 57 ;
else
SP_TAG3 ( np ) = 63 ;
}
else if ( u - > ID = = PACHINKO4 )
{
if ( RANDOM_P2 ( 1024 ) < 600 )
SP_TAG3 ( np ) = 60 ;
else
SP_TAG3 ( np ) = 61 ;
}
// match
SP_TAG2 ( np ) = - 1 ;
// kill
RESET_BOOL1 ( np ) ;
SpawnItemsMatch ( - 1 ) ;
break ;
}
return 0 ;
}
int SpawnItemsMatch ( short match )
{
short SpriteNum ;
short si , nextsi ;
SPRITEp sp , sip ;
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_SPAWN_ITEMS ] , si , nextsi )
{
sip = & sprite [ si ] ;
if ( SP_TAG2 ( sip ) ! = match )
continue ;
switch ( SP_TAG3 ( sip ) )
{
case 90 :
SpriteNum = BunnyHatch2 ( si ) ;
sp = & sprite [ SpriteNum ] ;
User [ SpriteNum ] - > spal = sp - > pal = PALETTE_PLAYER8 ; // Boy
sp - > ang = sip - > ang ;
break ;
case 91 :
SpriteNum = BunnyHatch2 ( si ) ;
sp = & sprite [ SpriteNum ] ;
User [ SpriteNum ] - > spal = sp - > pal = PALETTE_PLAYER0 ; // Girl
sp - > ang = sip - > ang ;
break ;
case 92 :
SpriteNum = BunnyHatch2 ( si ) ;
sp = & sprite [ SpriteNum ] ;
sp - > ang = sip - > ang ;
break ;
case 40 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_REPAIR_KIT ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_REPAIR_KIT , s_RepairKit , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 41 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_STAR ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_STAR , s_IconStar , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 42 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_LG_MINE ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_LG_MINE , s_IconLgMine , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 43 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_MICRO_GUN ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_MICRO_GUN , s_IconMicroGun , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 44 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_MICRO_BATTERY ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_MICRO_BATTERY , s_IconMicroBattery , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 45 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_GRENADE_LAUNCHER ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_GRENADE_LAUNCHER , s_IconGrenadeLauncher , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 46 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_LG_GRENADE ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_LG_GRENADE , s_IconLgGrenade , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 47 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_RAIL_GUN ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_RAIL_GUN , s_IconRailGun , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 48 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_RAIL_AMMO ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_RAIL_AMMO , s_IconRailAmmo , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 49 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_ROCKET ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_ROCKET , s_IconRocket , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 51 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_SHOTGUN ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_SHOTGUN , s_IconShotgun , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 52 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_LG_SHOTSHELL ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_LG_SHOTSHELL , s_IconLgShotshell , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 53 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_GUARD_HEAD ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_GUARD_HEAD , s_IconGuardHead , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 54 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_FIREBALL_LG_AMMO ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_FIREBALL_LG_AMMO , s_IconFireballLgAmmo , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 55 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_HEART ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_HEART , s_IconHeart , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 56 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_HEART_LG_AMMO ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_HEART_LG_AMMO , s_IconHeartLgAmmo , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 57 :
{
USERp u ;
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_ARMOR ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_ARMOR , s_IconArmor , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
sp = & sprite [ SpriteNum ] ;
u = User [ SpriteNum ] ;
SET ( u - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
if ( sp - > pal ! = PALETTE_PLAYER3 )
sp - > pal = u - > spal = PALETTE_PLAYER1 ;
else
sp - > pal = u - > spal = PALETTE_PLAYER3 ;
break ;
}
case 58 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_MEDKIT ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_MEDKIT , s_IconMedkit , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 59 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_SM_MEDKIT ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_SM_MEDKIT , s_IconSmMedkit , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 60 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_CHEMBOMB ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_CHEMBOMB , s_IconChemBomb , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 61 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_FLASHBOMB ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_FLASHBOMB , s_IconFlashBomb , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 62 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_NUKE ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_NUKE , s_IconNuke , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 63 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_CALTROPS ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_CALTROPS , s_IconCaltrops , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 64 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_BOOSTER ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_BOOSTER , s_IconBooster , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 65 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_HEAT_CARD ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_HEAT_CARD , s_IconHeatCard , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 66 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_CLOAK ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_CLOAK , s_IconCloak , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 67 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_NIGHT_VISION ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_NIGHT_VISION , s_IconNightVision , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 68 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_LG_UZI_AMMO ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_LG_UZI_AMMO , s_IconLgUziAmmo , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 69 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_GUARD_HEAD ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_GUARD_HEAD , s_IconGuardHead , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 70 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_HEART ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_HEART , s_IconHeart , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 20 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_UZIFLOOR ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_UZIFLOOR , s_IconUziFloor , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 32 :
case 0 :
if ( ! ItemSpotClear ( sip , STAT_ITEM , ICON_UZI ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , ICON_UZI , s_IconUzi , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
SET ( User [ SpriteNum ] - > Flags2 , SPR2_NEVER_RESPAWN ) ;
IconDefault ( SpriteNum ) ;
SetupItemForJump ( sip , SpriteNum ) ;
break ;
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :
case 10 :
case 11 :
case 12 :
{
short num ;
USERp u ;
2015-05-19 21:58:29 +00:00
uint8_t KeyPal [ ] =
2015-05-19 21:54:34 +00:00
{
PALETTE_PLAYER9 ,
PALETTE_PLAYER7 ,
PALETTE_PLAYER6 ,
PALETTE_PLAYER4 ,
PALETTE_PLAYER9 ,
PALETTE_PLAYER7 ,
PALETTE_PLAYER6 ,
PALETTE_PLAYER4 ,
PALETTE_PLAYER4 ,
PALETTE_PLAYER1 ,
PALETTE_PLAYER8 ,
PALETTE_PLAYER9
} ;
if ( gNet . MultiGameType = = MULTI_GAME_COMMBAT | | gNet . MultiGameType = = MULTI_GAME_AI_BOTS )
break ;
num = SP_TAG3 ( sip ) - 1 ;
if ( ! ItemSpotClear ( sip , STAT_ITEM , s_Key [ num ] - > Pic ) )
break ;
SpriteNum = SpawnSprite ( STAT_ITEM , s_Key [ num ] - > Pic , s_Key [ num ] , sip - > sectnum , sip - > x , sip - > y , sip - > z , sip - > ang , 0 ) ;
u = User [ SpriteNum ] ;
sp = & sprite [ SpriteNum ] ;
ASSERT ( u ! = NULL ) ;
sprite [ SpriteNum ] . picnum = u - > ID = s_Key [ num ] - > Pic ;
// need to set the palette here - suggest table lookup
u - > spal = sprite [ SpriteNum ] . pal = KeyPal [ num ] ;
2018-02-16 06:38:31 +00:00
//SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL);
2015-05-19 21:54:34 +00:00
ChangeState ( SpriteNum , s_Key [ num ] ) ;
2015-05-19 22:01:44 +00:00
RESET ( picanm [ sp - > picnum ] . sf , PICANM_ANIMTYPE_MASK ) ;
RESET ( picanm [ sp - > picnum + 1 ] . sf , PICANM_ANIMTYPE_MASK ) ;
2015-05-19 21:54:34 +00:00
SetupItemForJump ( sip , SpriteNum ) ;
break ;
}
}
if ( ! TEST_BOOL1 ( sip ) )
KillSprite ( si ) ;
}
return 0 ;
}
// CTW MODIFICATION
2015-05-19 21:58:29 +00:00
//void
2015-05-19 21:54:34 +00:00
int
// CTW MODIFICATION END
NewStateGroup ( short SpriteNum , STATEp StateGroup [ ] )
{
USERp u = User [ SpriteNum ] ;
//if (Prediction)
// return;
if ( ! StateGroup )
return 0 ;
ASSERT ( u ) ;
// Kind of a goofy check, but it should catch alot of invalid states!
// BTW, 6144 is the max tile number allowed in editart.
if ( u - > State & & ( u - > State - > Pic < 0 | | u - > State - > Pic > 6144 ) ) // JBF: verify this!
return 0 ;
u - > Rot = StateGroup ;
u - > State = u - > StateStart = StateGroup [ 0 ] ;
//sprite[SpriteNum].picnum = u->State->Pic;
u - > Tics = 0 ;
// turn anims off because people keep setting them in the
// art file
2015-05-19 22:01:44 +00:00
RESET ( picanm [ sprite [ SpriteNum ] . picnum ] . sf , PICANM_ANIMTYPE_MASK ) ;
2015-05-19 21:54:34 +00:00
return 0 ;
}
2015-05-19 21:58:29 +00:00
SWBOOL
SpriteOverlap ( int16_t spritenum_a , int16_t spritenum_b )
2015-05-19 21:54:34 +00:00
{
SPRITEp spa = & sprite [ spritenum_a ] , spb = & sprite [ spritenum_b ] ;
USERp ua = User [ spritenum_a ] ;
USERp ub = User [ spritenum_b ] ;
int spa_tos , spa_bos , spb_tos , spb_bos , overlap_z ;
if ( ! ua | | ! ub ) return FALSE ;
if ( ( unsigned ) Distance ( spa - > x , spa - > y , spb - > x , spb - > y ) > ua - > Radius + ub - > Radius )
{
return FALSE ;
}
spa_tos = SPRITEp_TOS ( spa ) ;
spa_bos = SPRITEp_BOS ( spa ) ;
spb_tos = SPRITEp_TOS ( spb ) ;
spb_bos = SPRITEp_BOS ( spb ) ;
overlap_z = ua - > OverlapZ + ub - > OverlapZ ;
// if the top of sprite a is below the bottom of b
if ( spa_tos - overlap_z > spb_bos )
{
return FALSE ;
}
// if the top of sprite b is is below the bottom of a
if ( spb_tos - overlap_z > spa_bos )
{
return FALSE ;
}
return TRUE ;
}
2015-05-19 21:58:29 +00:00
SWBOOL
SpriteOverlapZ ( int16_t spritenum_a , int16_t spritenum_b , int z_overlap )
2015-05-19 21:54:34 +00:00
{
SPRITEp spa = & sprite [ spritenum_a ] , spb = & sprite [ spritenum_b ] ;
int spa_tos , spa_bos , spb_tos , spb_bos ;
spa_tos = SPRITEp_TOS ( spa ) ;
spa_bos = SPRITEp_BOS ( spa ) ;
spb_tos = SPRITEp_TOS ( spb ) ;
spb_bos = SPRITEp_BOS ( spb ) ;
// if the top of sprite a is below the bottom of b
if ( spa_tos + z_overlap > spb_bos )
{
return FALSE ;
}
// if the top of sprite b is is below the bottom of a
if ( spb_tos + z_overlap > spa_bos )
{
return FALSE ;
}
return TRUE ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
getzrangepoint ( int x , int y , int z , short sectnum ,
2015-05-19 21:58:29 +00:00
int32_t * ceilz , int32_t * ceilhit , int32_t * florz , int32_t * florhit )
2015-05-19 21:54:34 +00:00
{
spritetype * spr ;
2020-03-06 15:49:49 +00:00
int j , k , l , dax , day , daz , xspan , yspan , xoff , yoff ;
2015-05-19 21:54:34 +00:00
int x1 , y1 , x2 , y2 , x3 , y3 , x4 , y4 , cosang , sinang , tilenum ;
short cstat ;
char clipyou ;
if ( sectnum < 0 )
{
* ceilz = 0x80000000 ;
* ceilhit = - 1 ;
* florz = 0x7fffffff ;
* florhit = - 1 ;
return ;
}
// Initialize z's and hits to the current sector's top&bottom
getzsofslope ( sectnum , x , y , ceilz , florz ) ;
* ceilhit = sectnum + 16384 ;
* florhit = sectnum + 16384 ;
// Go through sprites of only the current sector
for ( j = headspritesect [ sectnum ] ; j > = 0 ; j = nextspritesect [ j ] )
{
spr = & sprite [ j ] ;
cstat = spr - > cstat ;
if ( ( cstat & 49 ) ! = 33 )
continue ; // Only check blocking floor sprites
daz = spr - > z ;
// Only check if sprite's 2-sided or your on the 1-sided side
if ( ( ( cstat & 64 ) ! = 0 ) & & ( ( z > daz ) = = ( ( cstat & 8 ) = = 0 ) ) )
continue ;
// Calculate and store centering offset information into xoff&yoff
tilenum = spr - > picnum ;
2020-05-24 10:31:38 +00:00
xoff = ( int ) tileLeftOffset ( tilenum ) + ( int ) spr - > xoffset ;
yoff = ( int ) tileTopOffset ( tilenum ) + ( int ) spr - > yoffset ;
2015-05-19 21:54:34 +00:00
if ( cstat & 4 )
xoff = - xoff ;
if ( cstat & 8 )
yoff = - yoff ;
// Calculate all 4 points of the floor sprite.
// (x1,y1),(x2,y2),(x3,y3),(x4,y4)
// These points will already have (x,y) subtracted from them
cosang = sintable [ NORM_ANGLE ( spr - > ang + 512 ) ] ;
sinang = sintable [ spr - > ang ] ;
2015-05-19 22:02:25 +00:00
xspan = tilesiz [ tilenum ] . x ;
2015-05-19 21:54:34 +00:00
dax = ( ( xspan > > 1 ) + xoff ) * spr - > xrepeat ;
2015-05-19 22:02:25 +00:00
yspan = tilesiz [ tilenum ] . y ;
2015-05-19 21:54:34 +00:00
day = ( ( yspan > > 1 ) + yoff ) * spr - > yrepeat ;
x1 = spr - > x + dmulscale16 ( sinang , dax , cosang , day ) - x ;
y1 = spr - > y + dmulscale16 ( sinang , day , - cosang , dax ) - y ;
l = xspan * spr - > xrepeat ;
2017-06-24 09:20:21 +00:00
x2 = x1 - mulscale16 ( sinang , l ) ;
y2 = y1 + mulscale16 ( cosang , l ) ;
2015-05-19 21:54:34 +00:00
l = yspan * spr - > yrepeat ;
2017-06-24 09:20:21 +00:00
k = - mulscale16 ( cosang , l ) ;
2015-05-19 21:54:34 +00:00
x3 = x2 + k ;
x4 = x1 + k ;
2017-06-24 09:20:21 +00:00
k = - mulscale16 ( sinang , l ) ;
2015-05-19 21:54:34 +00:00
y3 = y2 + k ;
y4 = y1 + k ;
// Check to see if point (0,0) is inside the 4 points by seeing if
// the number of lines crossed as a line is shot outward is odd
clipyou = 0 ;
if ( ( y1 ^ y2 ) < 0 ) // If y1 and y2 have different signs
// (- / +)
{
if ( ( x1 ^ x2 ) < 0 )
clipyou ^ = ( x1 * y2 < x2 * y1 ) ^ ( y1 < y2 ) ;
else if ( x1 > = 0 )
clipyou ^ = 1 ;
}
if ( ( y2 ^ y3 ) < 0 )
{
if ( ( x2 ^ x3 ) < 0 )
clipyou ^ = ( x2 * y3 < x3 * y2 ) ^ ( y2 < y3 ) ;
else if ( x2 > = 0 )
clipyou ^ = 1 ;
}
if ( ( y3 ^ y4 ) < 0 )
{
if ( ( x3 ^ x4 ) < 0 )
clipyou ^ = ( x3 * y4 < x4 * y3 ) ^ ( y3 < y4 ) ;
else if ( x3 > = 0 )
clipyou ^ = 1 ;
}
if ( ( y4 ^ y1 ) < 0 )
{
if ( ( x4 ^ x1 ) < 0 )
clipyou ^ = ( x4 * y1 < x1 * y4 ) ^ ( y4 < y1 ) ;
else if ( x4 > = 0 )
clipyou ^ = 1 ;
}
if ( clipyou = = 0 )
continue ; // Point is not inside, don't clip
// Clipping time!
if ( z > daz )
{
if ( daz > * ceilz )
{
* ceilz = daz ;
* ceilhit = j + 49152 ;
}
}
else
{
if ( daz < * florz )
{
* florz = daz ;
* florhit = j + 49152 ;
}
}
}
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
DoActorZrange ( short SpriteNum )
{
SPRITEp sp = & sprite [ SpriteNum ] ;
USERp u = User [ SpriteNum ] ;
int ceilhit , florhit ;
short save_cstat ;
save_cstat = TEST ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
FAFgetzrange ( sp - > x , sp - > y , sp - > z - DIV2 ( SPRITEp_SIZE_Z ( sp ) ) , sp - > sectnum , & u - > hiz , & ceilhit , & u - > loz , & florhit , ( ( ( int ) sp - > clipdist ) < < 2 ) - GETZRANGE_CLIP_ADJ , CLIPMASK_ACTOR ) ;
SET ( sp - > cstat , save_cstat ) ;
u - > lo_sectp = u - > hi_sectp = NULL ;
u - > lo_sp = u - > hi_sp = NULL ;
switch ( TEST ( ceilhit , HIT_MASK ) )
{
case HIT_SPRITE :
u - > hi_sp = & sprite [ NORM_SPRITE ( ceilhit ) ] ;
break ;
case HIT_SECTOR :
u - > hi_sectp = & sector [ NORM_SECTOR ( ceilhit ) ] ;
break ;
default :
ASSERT ( TRUE = = FALSE ) ;
break ;
}
switch ( TEST ( florhit , HIT_MASK ) )
{
case HIT_SPRITE :
u - > lo_sp = & sprite [ NORM_SPRITE ( florhit ) ] ;
break ;
case HIT_SECTOR :
u - > lo_sectp = & sector [ NORM_SECTOR ( florhit ) ] ;
break ;
default :
ASSERT ( TRUE = = FALSE ) ;
break ;
}
}
// !AIC - puts getzrange results into USER varaible u->loz, u->hiz, u->lo_sectp, u->hi_sectp, etc.
// The loz and hiz are used a lot.
int
DoActorGlobZ ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
u - > loz = globloz ;
u - > hiz = globhiz ;
u - > lo_sectp = u - > hi_sectp = NULL ;
u - > lo_sp = u - > hi_sp = NULL ;
switch ( TEST ( globhihit , HIT_MASK ) )
{
case HIT_SPRITE :
u - > hi_sp = & sprite [ globhihit & 4095 ] ;
break ;
default :
u - > hi_sectp = & sector [ globhihit & 4095 ] ;
break ;
}
switch ( TEST ( globlohit , HIT_MASK ) )
{
case HIT_SPRITE :
u - > lo_sp = & sprite [ globlohit & 4095 ] ;
break ;
default :
u - > lo_sectp = & sector [ globlohit & 4095 ] ;
break ;
}
return 0 ;
}
2015-05-19 21:58:29 +00:00
SWBOOL
2015-05-19 21:54:34 +00:00
ActorDrop ( short SpriteNum , int x , int y , int z , short new_sector , short min_height )
{
SPRITEp sp = & sprite [ SpriteNum ] ;
int ceilhit , florhit , hiz , loz ;
short save_cstat ;
// look only at the center point for a floor sprite
save_cstat = TEST ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
FAFgetzrangepoint ( x , y , z - DIV2 ( SPRITEp_SIZE_Z ( sp ) ) , new_sector , & hiz , & ceilhit , & loz , & florhit ) ;
SET ( sp - > cstat , save_cstat ) ;
#if 0
if ( florhit < 0 | | ceilhit < 0 )
{
2019-12-25 10:26:19 +00:00
Printf ( " ERROR: FAFgetzrange() returned -1 for floor or ceiling check. \n " ) ;
Printf ( " Most likely a sprite has been placed too close to a white wall. \n " ) ;
Printf ( " spnum %d, sect %d, x %d, y %d, z %d, florhit %d, pic %d \n " , SpriteNum , sp - > sectnum , sp - > x , sp - > y , z - DIV2 ( SPRITEp_SIZE_Z ( sp ) ) , florhit , sp - > picnum ) ;
2015-05-19 21:54:34 +00:00
TerminateGame ( ) ;
}
# else
if ( florhit < 0 | | ceilhit < 0 )
{
//SetSuicide(SpriteNum);
return TRUE ;
}
# endif
// ASSERT(florhit >= 0);
// ASSERT(ceilhit >= 0);
switch ( TEST ( florhit , HIT_MASK ) )
{
case HIT_SPRITE :
{
SPRITEp hsp = & sprite [ florhit & 4095 ] ;
// if its a floor sprite and not too far down
2018-02-16 06:38:31 +00:00
if ( TEST ( hsp - > cstat , CSTAT_SPRITE_ALIGNMENT_FLOOR ) & &
2015-05-19 21:54:34 +00:00
( labs ( loz - z ) < = min_height ) )
{
return FALSE ;
}
break ;
}
case HIT_SECTOR :
{
if ( labs ( loz - z ) < = min_height )
{
return FALSE ;
}
break ;
}
default :
ASSERT ( TRUE = = FALSE ) ;
break ;
}
return TRUE ;
}
// Primarily used in ai.c for now - need to get rid of
2015-05-19 21:58:29 +00:00
SWBOOL
2015-05-19 21:54:34 +00:00
DropAhead ( short SpriteNum , short min_height )
{
SPRITEp sp = & sprite [ SpriteNum ] ;
int dax , day ;
short newsector ;
// dax = sp->x + MOVEx(128, sp->ang);
// day = sp->y + MOVEy(128, sp->ang);
dax = sp - > x + MOVEx ( 256 , sp - > ang ) ;
day = sp - > y + MOVEy ( 256 , sp - > ang ) ;
newsector = sp - > sectnum ;
COVERupdatesector ( dax , day , & newsector ) ;
// look straight down for a drop
if ( ActorDrop ( SpriteNum , dax , day , sp - > z , newsector , min_height ) )
return TRUE ;
return FALSE ;
}
/*
! AIC KEY - Called by ai . c routines . Calls move_sprite which calls clipmove .
This incapulates move_sprite and makes sure that actors don ' t walk off of
ledges . If it finds itself in mid air then it restores the last good
position . This is a hack because Ken had no good way of doing this from his
code . ActorDrop ( ) is called from here .
*/
int
move_actor ( short SpriteNum , int xchange , int ychange , int zchange )
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP ;
int x , y , z , loz , hiz ;
SPRITEp lo_sp , hi_sp ;
SECTORp lo_sectp , hi_sectp ;
2020-03-06 15:49:49 +00:00
short sectnum ;
2015-05-19 21:54:34 +00:00
short dist ;
int cliptype = CLIPMASK_ACTOR ;
if ( TEST ( u - > Flags , SPR_NO_SCAREDZ ) )
{
// For COOLG & HORNETS
// set to actual z before you move
sp - > z = u - > sz ;
}
// save off x,y values
x = sp - > x ;
y = sp - > y ;
z = sp - > z ;
loz = u - > loz ;
hiz = u - > hiz ;
lo_sp = u - > lo_sp ;
hi_sp = u - > hi_sp ;
lo_sectp = u - > lo_sectp ;
hi_sectp = u - > hi_sectp ;
sectnum = sp - > sectnum ;
clipmoveboxtracenum = 1 ;
u - > ret = move_sprite ( SpriteNum , xchange , ychange , zchange ,
u - > ceiling_dist , u - > floor_dist , cliptype , ACTORMOVETICS ) ;
clipmoveboxtracenum = 3 ;
ASSERT ( sp - > sectnum > = 0 ) ;
// try and determine whether you moved > lo_step in the z direction
if ( ! TEST ( u - > Flags , SPR_NO_SCAREDZ | SPR_JUMPING | SPR_CLIMBING | SPR_FALLING | SPR_DEAD | SPR_SWIMMING ) )
{
if ( labs ( sp - > z - globloz ) > u - > lo_step )
{
// cancel move
sp - > x = x ;
sp - > y = y ;
sp - > z = z ;
//sp->z = u->loz; // place on ground in case you are in the air
u - > loz = loz ;
u - > hiz = hiz ;
u - > lo_sp = lo_sp ;
u - > hi_sp = hi_sp ;
u - > lo_sectp = lo_sectp ;
u - > hi_sectp = hi_sectp ;
u - > ret = - 1 ;
changespritesect ( SpriteNum , sectnum ) ;
return FALSE ;
}
if ( ActorDrop ( SpriteNum , sp - > x , sp - > y , sp - > z , sp - > sectnum , u - > lo_step ) )
{
//printf("cancel move 2\n", sp->z, u->loz);
// cancel move
sp - > x = x ;
sp - > y = y ;
sp - > z = z ;
//sp->z = u->loz; // place on ground in case you are in the air
u - > loz = loz ;
u - > hiz = hiz ;
u - > lo_sp = lo_sp ;
u - > hi_sp = hi_sp ;
u - > lo_sectp = lo_sectp ;
u - > hi_sectp = hi_sectp ;
u - > ret = - 1 ;
changespritesect ( SpriteNum , sectnum ) ;
return FALSE ;
}
}
SET ( u - > Flags , SPR_MOVED ) ;
if ( ! u - > ret )
{
// Keep track of how far sprite has moved
dist = Distance ( x , y , sp - > x , sp - > y ) ;
u - > TargetDist - = dist ;
u - > Dist + = dist ;
u - > DistCheck + = dist ;
return TRUE ;
}
else
{
return FALSE ;
}
}
int
DoStayOnFloor ( short SpriteNum )
{
sprite [ SpriteNum ] . z = sector [ sprite [ SpriteNum ] . sectnum ] . floorz ;
//sprite[SpriteNum].z = getflorzofslope(sprite[SpriteNum].sectnum, sprite[SpriteNum].x, sprite[SpriteNum].y);
return 0 ;
}
int
DoGrating ( short SpriteNum )
{
SPRITEp sp = User [ SpriteNum ] - > SpriteP ;
int dir ;
# define GRATE_FACTOR 3
// reduce to 0 to 3 value
dir = sp - > ang > > 9 ;
if ( MOD2 ( dir ) = = 0 )
{
if ( dir = = 0 )
sp - > x + = 2 * GRATE_FACTOR ;
else
sp - > x - = 2 * GRATE_FACTOR ;
}
else
{
if ( dir = = 1 )
sp - > y + = 2 * GRATE_FACTOR ;
else
sp - > y - = 2 * GRATE_FACTOR ;
}
sp - > hitag - = GRATE_FACTOR ;
if ( sp - > hitag < = 0 )
{
change_sprite_stat ( SpriteNum , STAT_DEFAULT ) ;
if ( User [ SpriteNum ] )
{
FreeMem ( User [ SpriteNum ] ) ;
User [ SpriteNum ] = 0 ;
}
}
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
setspritez ( SpriteNum , ( vec3_t * ) sp ) ;
2015-05-19 21:54:34 +00:00
return 0 ;
}
#if 0
int
DoSpriteFade ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP ;
short i ;
// adjust Shade based on clock
for ( i = 0 ; i < ACTORMOVETICS ; i + + )
{
if ( TEST ( u - > Flags , SPR_SHADE_DIR ) )
{
sp - > shade + + ;
if ( sp - > shade > = 10 )
RESET ( u - > Flags , SPR_SHADE_DIR ) ;
}
else
{
sp - > shade - - ;
if ( sp - > shade < = - 40 )
SET ( u - > Flags , SPR_SHADE_DIR ) ;
}
}
return 0 ;
}
# endif
int
SpearOnFloor ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP ;
if ( ! TEST ( u - > Flags , SPR_SO_ATTACHED ) )
{
// if on a sprite bridge, stay with the sprite otherwize stay with
// the floor
if ( u - > lo_sp )
sp - > z = u - > loz ;
else
sp - > z = sector [ sp - > sectnum ] . floorz + u - > sz ;
}
return 0 ;
}
int
SpearOnCeiling ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP ;
if ( ! TEST ( u - > Flags , SPR_SO_ATTACHED ) )
{
// if on a sprite bridge, stay with the sprite otherwize stay with
// the floor
if ( u - > hi_sp )
sp - > z = u - > hiz ;
else
sp - > z = sector [ sp - > sectnum ] . ceilingz + u - > sz ;
}
return 0 ;
}
int
DoKey ( short SpriteNum )
{
SPRITEp sp = User [ SpriteNum ] - > SpriteP ;
sp - > ang = NORM_ANGLE ( sp - > ang + ( 14 * ACTORMOVETICS ) ) ;
//DoSpriteFade(SpriteNum);
DoGet ( SpriteNum ) ;
return 0 ;
}
int
DoCoin ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
int offset ;
u - > WaitTics - = ACTORMOVETICS * 2 ;
if ( u - > WaitTics < = 0 )
{
KillSprite ( SpriteNum ) ;
return 0 ;
}
if ( u - > WaitTics < 10 * 120 )
{
if ( u - > StateStart ! = s_GreenCoin )
{
offset = u - > State - u - > StateStart ;
ChangeState ( SpriteNum , s_GreenCoin ) ;
u - > State = u - > StateStart + offset ;
}
}
else if ( u - > WaitTics < 20 * 120 )
{
if ( u - > StateStart ! = s_YellowCoin )
{
offset = u - > State - u - > StateStart ;
ChangeState ( SpriteNum , s_YellowCoin ) ;
u - > State = u - > StateStart + offset ;
}
}
return 0 ;
}
int
KillGet ( short SpriteNum )
{
USERp u = User [ SpriteNum ] , nu ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP , np ;
2017-01-23 11:21:32 +00:00
short New ;
2015-05-19 21:54:34 +00:00
switch ( gNet . MultiGameType )
{
case MULTI_GAME_NONE :
case MULTI_GAME_COOPERATIVE :
KillSprite ( SpriteNum ) ;
break ;
case MULTI_GAME_COMMBAT :
case MULTI_GAME_AI_BOTS :
if ( TEST ( u - > Flags2 , SPR2_NEVER_RESPAWN ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
u - > WaitTics = 30 * 120 ;
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
// respawn markers
if ( ! gNet . SpawnMarkers | | sp - > hitag = = TAG_NORESPAWN_FLAG ) // No coin if it's a special flag
break ;
2017-01-23 11:21:32 +00:00
New = SpawnSprite ( STAT_ITEM , Red_COIN , s_RedCoin , sp - > sectnum ,
2015-05-19 21:54:34 +00:00
sp - > x , sp - > y , sp - > z , 0 , 0 ) ;
2017-01-23 11:21:32 +00:00
np = & sprite [ New ] ;
nu = User [ New ] ;
2015-05-19 21:54:34 +00:00
np - > shade = - 20 ;
nu - > WaitTics = u - > WaitTics - 12 ;
break ;
}
return 0 ;
}
int
KillGetAmmo ( short SpriteNum )
{
USERp u = User [ SpriteNum ] , nu ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP , np ;
2017-01-23 11:21:32 +00:00
short New ;
2015-05-19 21:54:34 +00:00
switch ( gNet . MultiGameType )
{
case MULTI_GAME_NONE :
case MULTI_GAME_COOPERATIVE :
KillSprite ( SpriteNum ) ;
break ;
case MULTI_GAME_COMMBAT :
case MULTI_GAME_AI_BOTS :
if ( TEST ( u - > Flags2 , SPR2_NEVER_RESPAWN ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
// No Respawn mode - all ammo goes away
if ( gNet . NoRespawn )
{
KillSprite ( SpriteNum ) ;
break ;
}
u - > WaitTics = 30 * 120 ;
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
// respawn markers
if ( ! gNet . SpawnMarkers )
break ;
2017-01-23 11:21:32 +00:00
New = SpawnSprite ( STAT_ITEM , Red_COIN , s_RedCoin , sp - > sectnum ,
2015-05-19 21:54:34 +00:00
sp - > x , sp - > y , sp - > z , 0 , 0 ) ;
2017-01-23 11:21:32 +00:00
np = & sprite [ New ] ;
nu = User [ New ] ;
2015-05-19 21:54:34 +00:00
np - > shade = - 20 ;
nu - > WaitTics = u - > WaitTics - 12 ;
break ;
}
return 0 ;
}
int
KillGetWeapon ( short SpriteNum )
{
USERp u = User [ SpriteNum ] , nu ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP , np ;
2017-01-23 11:21:32 +00:00
short New ;
2015-05-19 21:54:34 +00:00
switch ( gNet . MultiGameType )
{
case MULTI_GAME_NONE :
KillSprite ( SpriteNum ) ;
break ;
case MULTI_GAME_COOPERATIVE :
// don't kill weapons in coop
// unless told too :)
if ( TEST ( u - > Flags2 , SPR2_NEVER_RESPAWN ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
break ;
case MULTI_GAME_COMMBAT :
case MULTI_GAME_AI_BOTS :
if ( TEST ( u - > Flags2 , SPR2_NEVER_RESPAWN ) )
{
KillSprite ( SpriteNum ) ;
break ;
}
// No Respawn mode - all weapons stay
// but can only get once
if ( gNet . NoRespawn )
break ;
u - > WaitTics = 30 * 120 ;
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
// respawn markers
if ( ! gNet . SpawnMarkers )
break ;
2017-01-23 11:21:32 +00:00
New = SpawnSprite ( STAT_ITEM , Red_COIN , s_RedCoin , sp - > sectnum ,
2015-05-19 21:54:34 +00:00
sp - > x , sp - > y , sp - > z , 0 , 0 ) ;
2017-01-23 11:21:32 +00:00
np = & sprite [ New ] ;
nu = User [ New ] ;
2015-05-19 21:54:34 +00:00
np - > shade = - 20 ;
nu - > WaitTics = u - > WaitTics - 12 ;
break ;
}
return 0 ;
}
int
DoSpawnItemTeleporterEffect ( SPRITEp sp )
{
extern STATE s_TeleportEffect [ ] ;
short effect ;
SPRITEp ep ;
effect = SpawnSprite ( STAT_MISSILE , 0 , s_TeleportEffect , sp - > sectnum ,
sp - > x , sp - > y , sp - > z - Z ( 12 ) ,
sp - > ang , 0 ) ;
ep = & sprite [ effect ] ;
ep - > shade = - 40 ;
ep - > xrepeat = ep - > yrepeat = 36 ;
SET ( ep - > cstat , CSTAT_SPRITE_YCENTER ) ;
RESET ( ep - > cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
return 0 ;
}
void ChoosePlayerGetSound ( PLAYERp pp )
{
int choose_snd = 0 ;
if ( pp ! = Player + myconnectindex ) return ;
choose_snd = STD_RANDOM_RANGE ( ( MAX_GETSOUNDS - 1 ) < < 8 ) > > 8 ;
2019-12-18 10:09:01 +00:00
PlayerSound ( PlayerGetItemVocs [ choose_snd ] , v3df_follow | v3df_dontpan , pp ) ;
2015-05-19 21:54:34 +00:00
}
2015-05-19 21:58:29 +00:00
SWBOOL CanGetWeapon ( PLAYERp pp , short SpriteNum , int WPN )
2015-05-19 21:54:34 +00:00
{
2020-03-06 15:49:49 +00:00
USERp u = User [ SpriteNum ] ;
2015-05-19 21:54:34 +00:00
switch ( gNet . MultiGameType )
{
case MULTI_GAME_NONE :
return TRUE ;
case MULTI_GAME_COOPERATIVE :
if ( TEST ( u - > Flags2 , SPR2_NEVER_RESPAWN ) )
return TRUE ;
if ( TEST ( pp - > WpnGotOnceFlags , BIT ( WPN ) ) )
return FALSE ;
return TRUE ;
case MULTI_GAME_COMMBAT :
case MULTI_GAME_AI_BOTS :
if ( TEST ( u - > Flags2 , SPR2_NEVER_RESPAWN ) )
return TRUE ;
// No Respawn - can't get a weapon again if you already got it
if ( gNet . NoRespawn & & TEST ( pp - > WpnGotOnceFlags , BIT ( WPN ) ) )
return FALSE ;
return TRUE ;
}
return TRUE ;
}
struct InventoryDecl_t InventoryDecls [ InvDecl_TOTAL ] =
{
2019-12-09 18:00:30 +00:00
{ 50 } ,
{ 100 } ,
{ 20 } ,
{ 50 } ,
{ 100 } ,
{ 1 } ,
{ 2 } ,
{ 3 } ,
{ 100 } ,
{ 100 } ,
{ 100 } ,
2015-05-19 21:54:34 +00:00
} ;
# define ITEMFLASHAMT -8
# define ITEMFLASHCLR 144
int
DoGet ( short SpriteNum )
{
USERp u = User [ SpriteNum ] , pu ;
SPRITEp sp = User [ SpriteNum ] - > SpriteP ;
PLAYERp pp ;
short pnum , key_num ;
int dist , a , b , c ;
2015-05-19 21:58:29 +00:00
SWBOOL can_see ;
2015-05-19 21:54:34 +00:00
int cstat_bak ;
// For flag stuff
USERp nu ;
SPRITEp np ;
2017-01-23 11:21:32 +00:00
short New ;
2015-05-19 21:54:34 +00:00
// Invisiblility is only used for DeathMatch type games
// Sprites stays invisible for a period of time and is un-gettable
// then "Re-Spawns" by becomming visible. Its never actually killed.
if ( TEST ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) )
{
u - > WaitTics - = ACTORMOVETICS * 2 ;
if ( u - > WaitTics < = 0 )
{
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM_SPAWN , sp , v3df_none ) ;
2015-05-19 21:54:34 +00:00
DoSpawnItemTeleporterEffect ( sp ) ;
RESET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
}
return 0 ;
}
if ( sp - > xvel )
{
if ( ! DoItemFly ( SpriteNum ) )
{
sp - > xvel = 0 ;
change_sprite_stat ( SpriteNum , STAT_ITEM ) ;
}
}
TRAVERSE_CONNECT ( pnum )
{
pp = & Player [ pnum ] ;
//pu = User[pp->PlayerSprite];
pu = User [ pp - > SpriteP - sprite ] ;
if ( TEST ( pp - > Flags , PF_DEAD ) )
continue ;
DISTANCE ( pp - > posx , pp - > posy , sp - > x , sp - > y , dist , a , b , c ) ;
if ( ( unsigned ) dist > ( pu - > Radius + u - > Radius ) )
{
continue ;
}
if ( ! SpriteOverlap ( SpriteNum , pp - > SpriteP - sprite ) )
{
continue ;
}
cstat_bak = sp - > cstat ;
SET ( sp - > cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
can_see = FAFcansee ( sp - > x , sp - > y , sp - > z , sp - > sectnum ,
pp - > posx , pp - > posy , pp - > posz , pp - > cursectnum ) ;
sp - > cstat = cstat_bak ;
if ( ! can_see )
{
continue ;
}
switch ( u - > ID )
{
//
// Keys
//
case RED_CARD :
case RED_KEY :
key_num = 0 ;
goto KeyMain ;
case BLUE_CARD :
case BLUE_KEY :
key_num = 1 ;
goto KeyMain ;
case GREEN_CARD :
case GREEN_KEY :
key_num = 2 ;
goto KeyMain ;
case YELLOW_CARD :
case YELLOW_KEY :
key_num = 3 ;
goto KeyMain ;
case GOLD_SKELKEY :
key_num = 4 ;
goto KeyMain ;
case SILVER_SKELKEY :
key_num = 5 ;
goto KeyMain ;
case BRONZE_SKELKEY :
key_num = 6 ;
goto KeyMain ;
case RED_SKELKEY :
key_num = 7 ;
KeyMain :
if ( pp - > HasKey [ key_num ] )
break ;
2019-12-09 17:40:07 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_KEYMSG + key_num ) ) ;
2015-05-19 21:54:34 +00:00
pp - > HasKey [ key_num ] = TRUE ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_KEY , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
// don't kill keys in coop
if ( gNet . MultiGameType = = MULTI_GAME_COOPERATIVE )
break ;
KillSprite ( SpriteNum ) ;
break ;
case ICON_ARMOR :
if ( pp - > Armor < InventoryDecls [ InvDecl_Kevlar ] . amount )
{
if ( u - > spal = = PALETTE_PLAYER3 )
{
PlayerUpdateArmor ( pp , 1000 + InventoryDecls [ InvDecl_Kevlar ] . amount ) ;
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_Kevlar ) ) ;
2015-05-19 21:54:34 +00:00
}
else
{
if ( pp - > Armor < InventoryDecls [ InvDecl_Armor ] . amount )
{
PlayerUpdateArmor ( pp , 1000 + InventoryDecls [ InvDecl_Armor ] . amount ) ;
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_Armor ) ) ;
2015-05-19 21:54:34 +00:00
}
else
break ;
}
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_BIGITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
// override for respawn mode
if ( gNet . MultiGameType = = MULTI_GAME_COMMBAT & & gNet . NoRespawn )
{
KillSprite ( SpriteNum ) ;
break ;
}
KillGet ( SpriteNum ) ;
}
break ;
//
// Health - Instant Use
//
case ICON_SM_MEDKIT :
if ( pu - > Health < 100 )
{
2015-05-19 21:58:29 +00:00
SWBOOL putbackmax = FALSE ;
2015-05-19 21:54:34 +00:00
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_SmMedkit ) ) ;
2015-05-19 21:54:34 +00:00
if ( pp - > MaxHealth = = 200 )
{
pp - > MaxHealth = 100 ;
putbackmax = TRUE ;
}
PlayerUpdateHealth ( pp , InventoryDecls [ InvDecl_SmMedkit ] . amount ) ;
if ( putbackmax ) pp - > MaxHealth = 200 ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
// override for respawn mode
if ( gNet . MultiGameType = = MULTI_GAME_COMMBAT & & gNet . NoRespawn )
{
KillSprite ( SpriteNum ) ;
break ;
}
KillGet ( SpriteNum ) ;
}
break ;
case ICON_BOOSTER : // Fortune cookie
pp - > MaxHealth = 200 ;
if ( pu - > Health < 200 )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_Booster ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateHealth ( pp , InventoryDecls [ InvDecl_Booster ] . amount ) ; // This is for health
// over 100%
// Say something witty
2019-10-27 15:53:00 +00:00
if ( pp = = Player + myconnectindex & & hud_messages )
2015-05-19 21:54:34 +00:00
{
2019-12-09 17:40:07 +00:00
int cookie = ( adult_lockout | | Global_PLock ) ? STD_RANDOM_RANGE ( 10 ) : STD_RANDOM_RANGE ( MAX_FORTUNES ) ;
2020-02-25 20:03:38 +00:00
// print to the console, and the user quote display.
FStringf msg ( " %s %s " , GStrings ( " TXTS_FORTUNE " ) , quoteMgr . GetQuote ( QUOTE_COOKIE + cookie ) ) ;
Printf ( TEXTCOLOR_SAPPHIRE " %s \n " , msg . GetChars ( ) ) ;
2020-01-24 18:50:44 +00:00
adduserquote ( msg . GetChars ( ) ) ;
2015-05-19 21:54:34 +00:00
}
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_BIGITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
// override for respawn mode
if ( gNet . MultiGameType = = MULTI_GAME_COMMBAT & & gNet . NoRespawn )
{
KillSprite ( SpriteNum ) ;
break ;
}
KillGet ( SpriteNum ) ;
}
break ;
//
// Inventory
//
case ICON_MEDKIT :
if ( ! pp - > InventoryAmount [ INVENTORY_MEDKIT ] | | pp - > InventoryPercent [ INVENTORY_MEDKIT ] < InventoryDecls [ InvDecl_Medkit ] . amount )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_Medkit ) ) ;
2015-05-19 21:54:34 +00:00
pp - > InventoryPercent [ INVENTORY_MEDKIT ] = InventoryDecls [ InvDecl_Medkit ] . amount ;
pp - > InventoryAmount [ INVENTORY_MEDKIT ] = 1 ;
PlayerUpdateInventory ( pp , INVENTORY_MEDKIT ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
// override for respawn mode
if ( gNet . MultiGameType = = MULTI_GAME_COMMBAT & & gNet . NoRespawn )
{
KillSprite ( SpriteNum ) ;
break ;
}
KillGet ( SpriteNum ) ;
}
break ;
case ICON_CHEMBOMB :
if ( pp - > InventoryAmount [ INVENTORY_CHEMBOMB ] < InventoryDecls [ InvDecl_ChemBomb ] . amount )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_ChemBomb ) ) ;
2015-05-19 21:54:34 +00:00
pp - > InventoryPercent [ INVENTORY_CHEMBOMB ] = 0 ;
pp - > InventoryAmount [ INVENTORY_CHEMBOMB ] + + ;
PlayerUpdateInventory ( pp , INVENTORY_CHEMBOMB ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
}
break ;
case ICON_FLASHBOMB :
if ( pp - > InventoryAmount [ INVENTORY_FLASHBOMB ] < InventoryDecls [ InvDecl_FlashBomb ] . amount )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_FlashBomb ) ) ;
2015-05-19 21:54:34 +00:00
pp - > InventoryPercent [ INVENTORY_FLASHBOMB ] = 0 ;
pp - > InventoryAmount [ INVENTORY_FLASHBOMB ] + + ;
PlayerUpdateInventory ( pp , INVENTORY_FLASHBOMB ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
}
break ;
case ICON_CALTROPS :
if ( pp - > InventoryAmount [ INVENTORY_CALTROPS ] < InventoryDecls [ InvDecl_Caltrops ] . amount )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_Caltrops ) ) ;
2015-05-19 21:54:34 +00:00
pp - > InventoryPercent [ INVENTORY_CALTROPS ] = 0 ;
pp - > InventoryAmount [ INVENTORY_CALTROPS ] + = 3 ;
if ( pp - > InventoryAmount [ INVENTORY_CALTROPS ] > InventoryDecls [ InvDecl_Caltrops ] . amount )
pp - > InventoryAmount [ INVENTORY_CALTROPS ] = InventoryDecls [ InvDecl_Caltrops ] . amount ;
PlayerUpdateInventory ( pp , INVENTORY_CALTROPS ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
}
break ;
case ICON_NIGHT_VISION :
if ( ! pp - > InventoryAmount [ INVENTORY_NIGHT_VISION ] | | pp - > InventoryPercent [ INVENTORY_NIGHT_VISION ] < InventoryDecls [ InvDecl_NightVision ] . amount )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_NightVision ) ) ;
2015-05-19 21:54:34 +00:00
pp - > InventoryPercent [ INVENTORY_NIGHT_VISION ] = InventoryDecls [ InvDecl_NightVision ] . amount ;
pp - > InventoryAmount [ INVENTORY_NIGHT_VISION ] = 1 ;
PlayerUpdateInventory ( pp , INVENTORY_NIGHT_VISION ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
}
break ;
case ICON_REPAIR_KIT :
if ( ! pp - > InventoryAmount [ INVENTORY_REPAIR_KIT ] | | pp - > InventoryPercent [ INVENTORY_REPAIR_KIT ] < InventoryDecls [ InvDecl_RepairKit ] . amount )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_RepairKit ) ) ;
2015-05-19 21:54:34 +00:00
pp - > InventoryPercent [ INVENTORY_REPAIR_KIT ] = InventoryDecls [ InvDecl_RepairKit ] . amount ;
pp - > InventoryAmount [ INVENTORY_REPAIR_KIT ] = 1 ;
PlayerUpdateInventory ( pp , INVENTORY_REPAIR_KIT ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
// don't kill repair kit in coop
if ( gNet . MultiGameType = = MULTI_GAME_COOPERATIVE )
break ;
KillGet ( SpriteNum ) ;
}
break ;
#if 0
case ICON_ENVIRON_SUIT :
if ( ! pp - > InventoryAmount [ INVENTORY_ENVIRON_SUIT ] | | pp - > InventoryPercent [ INVENTORY_ENVIRON_SUIT ] < 100 )
{
pp - > InventoryPercent [ INVENTORY_ENVIRON_SUIT ] = 100 ;
pp - > InventoryAmount [ INVENTORY_ENVIRON_SUIT ] = 1 ;
PlayerUpdateInventory ( pp , INVENTORY_ENVIRON_SUIT ) ;
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
}
break ;
# endif
case ICON_CLOAK :
if ( ! pp - > InventoryAmount [ INVENTORY_CLOAK ] | | pp - > InventoryPercent [ INVENTORY_CLOAK ] < InventoryDecls [ InvDecl_Cloak ] . amount )
{
2019-12-09 18:00:30 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_INVENTORY + InvDecl_Cloak ) ) ;
2015-05-19 21:54:34 +00:00
pp - > InventoryPercent [ INVENTORY_CLOAK ] = InventoryDecls [ InvDecl_Cloak ] . amount ;
pp - > InventoryAmount [ INVENTORY_CLOAK ] = 1 ;
PlayerUpdateInventory ( pp , INVENTORY_CLOAK ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
}
break ;
//
// Weapon
//
case ICON_STAR :
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_STAR ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_STAR ) ) ;
if ( pp - > WpnAmmo [ WPN_STAR ] > = DamageData [ WPN_STAR ] . max_ammo )
break ;
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , sw_darts ? GStrings ( " TXTS_DARTS " ) : quoteMgr . GetQuote ( QUOTE_WPNSHURIKEN ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_STAR , DamageData [ WPN_STAR ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_STAR ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_STAR ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum < = WPN_STAR & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponStar ( pp ) ;
break ;
case ICON_LG_MINE :
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_MINE ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_MINE ) ) ;
if ( pp - > WpnAmmo [ WPN_MINE ] > = DamageData [ WPN_MINE ] . max_ammo )
break ;
//sprintf(ds,"Sticky Bombs");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNSTICKY ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_MINE , DamageData [ WPN_MINE ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
ChoosePlayerGetSound ( pp ) ;
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_MINE ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_MINE ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_MINE & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponMine ( pp ) ;
break ;
case ICON_UZI :
case ICON_UZIFLOOR :
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_UZI ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_UZI ) ) ;
if ( TEST ( pp - > Flags , PF_TWO_UZI ) & & pp - > WpnAmmo [ WPN_UZI ] > = DamageData [ WPN_UZI ] . max_ammo )
break ;
//sprintf(ds,"UZI Submachine Gun");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNUZI ) ) ;
2015-05-19 21:54:34 +00:00
// pp->WpnAmmo[WPN_UZI] += 50;
PlayerUpdateAmmo ( pp , WPN_UZI , DamageData [ WPN_UZI ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_UZI ) ) & & TEST ( pp - > Flags , PF_TWO_UZI ) )
break ;
// flag to help with double uzi powerup - simpler but kludgy
SET ( pp - > Flags , PF_PICKED_UP_AN_UZI ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_UZI ) ) )
{
SET ( pp - > Flags , PF_TWO_UZI ) ;
pp - > WpnUziType = 0 ; // Let it come up
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlayerSound ( DIGI_DOUBLEUZI , v3df_dontpan | v3df_follow , pp ) ;
2015-05-19 21:54:34 +00:00
}
else
{
SET ( pp - > WpnFlags , BIT ( WPN_UZI ) ) ;
ChoosePlayerGetSound ( pp ) ;
}
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_UZI & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponUzi ( pp ) ;
break ;
case ICON_LG_UZI_AMMO :
if ( pp - > WpnAmmo [ WPN_UZI ] > = DamageData [ WPN_UZI ] . max_ammo )
break ;
//sprintf(ds,"UZI Clip");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMOUZI ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_UZI , DamageData [ WPN_UZI ] . ammo_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetAmmo ( SpriteNum ) ;
break ;
case ICON_MICRO_GUN :
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_MICRO ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_MICRO ) ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_MICRO ) ) & & pp - > WpnAmmo [ WPN_MICRO ] > = DamageData [ WPN_MICRO ] . max_ammo )
break ;
//sprintf(ds,"Missile Launcher");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNLAUNCH ) ) ;
2015-05-19 21:54:34 +00:00
// pp->WpnAmmo[WPN_MICRO] += 5;
PlayerUpdateAmmo ( pp , WPN_MICRO , DamageData [ WPN_MICRO ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
ChoosePlayerGetSound ( pp ) ;
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_MICRO ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_MICRO ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_MICRO & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponMicro ( pp ) ;
break ;
case ICON_MICRO_BATTERY :
if ( pp - > WpnAmmo [ WPN_MICRO ] > = DamageData [ WPN_MICRO ] . max_ammo )
break ;
//sprintf(ds,"Missiles");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMOLAUNCH ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_MICRO , DamageData [ WPN_MICRO ] . ammo_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetAmmo ( SpriteNum ) ;
break ;
case ICON_NUKE :
if ( pp - > WpnRocketNuke ! = 1 )
{
//sprintf(ds,"Nuclear Warhead");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNNUKE ) ) ;
2015-05-19 21:54:34 +00:00
pp - > WpnRocketNuke = DamageData [ DMG_NUCLEAR_EXP ] . weapon_pickup ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
if ( STD_RANDOM_RANGE ( 1000 ) > 800 & & pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlayerSound ( DIGI_ILIKENUKES , v3df_dontpan | v3df_doppler | v3df_follow , pp ) ;
2015-05-19 21:54:34 +00:00
if ( pp - > CurWpn = = pp - > Wpn [ WPN_MICRO ] )
{
if ( pp - > WpnRocketType ! = 2 )
{
extern PANEL_STATE ps_MicroNukeFlash [ ] ;
pp - > CurWpn - > over [ MICRO_SHOT_NUM ] . tics = 0 ;
pp - > CurWpn - > over [ MICRO_SHOT_NUM ] . State = ps_MicroNukeFlash ;
// Play Nuke available sound here!
}
}
KillGetAmmo ( SpriteNum ) ;
}
break ;
case ICON_GRENADE_LAUNCHER :
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_GRENADE ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_GRENADE ) ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_GRENADE ) ) & & pp - > WpnAmmo [ WPN_GRENADE ] > = DamageData [ WPN_GRENADE ] . max_ammo )
break ;
//sprintf(ds,"Grenade Launcher");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNGRENADE ) ) ;
2015-05-19 21:54:34 +00:00
// pp->WpnAmmo[WPN_GRENADE] += 6;
PlayerUpdateAmmo ( pp , WPN_GRENADE , DamageData [ WPN_GRENADE ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
//ChoosePlayerGetSound(pp);
if ( STD_RANDOM_RANGE ( 1000 ) > 800 & & pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlayerSound ( DIGI_LIKEBIGWEAPONS , v3df_dontpan | v3df_doppler | v3df_follow , pp ) ;
2015-05-19 21:54:34 +00:00
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_GRENADE ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_GRENADE ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_GRENADE & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponGrenade ( pp ) ;
break ;
case ICON_LG_GRENADE :
if ( pp - > WpnAmmo [ WPN_GRENADE ] > = DamageData [ WPN_GRENADE ] . max_ammo )
break ;
//sprintf(ds,"Grenade Shells");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMOGRENADE ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_GRENADE , DamageData [ WPN_GRENADE ] . ammo_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetAmmo ( SpriteNum ) ;
break ;
#if 0
case ICON_ROCKET :
pp - > WpnAmmo [ WPN_ROCKET ] + = 15 ;
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_ROCKET ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_ROCKET ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
InitWeaponRocket ( pp ) ;
break ;
case ICON_LG_ROCKET :
sprintf ( ds , " 20 Missiles " ) ;
PutStringInfo ( Player + pnum , ds ) ;
PlayerUpdateAmmo ( pp , WPN_ROCKET , 20 ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
break ;
# endif
case ICON_RAIL_GUN :
if ( SW_SHAREWARE ) { KillSprite ( SpriteNum ) ; break ; }
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_RAIL ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_RAIL ) ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_RAIL ) ) & & pp - > WpnAmmo [ WPN_RAIL ] > = DamageData [ WPN_RAIL ] . max_ammo )
break ;
//sprintf(ds,"Rail Gun");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNRAILGUN ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_RAIL , DamageData [ WPN_RAIL ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
if ( pp = = Player + myconnectindex )
{
if ( STD_RANDOM_RANGE ( 1000 ) > 700 )
2019-12-18 10:09:01 +00:00
PlayerSound ( DIGI_LIKEBIGWEAPONS , v3df_dontpan | v3df_doppler | v3df_follow , pp ) ;
2015-05-19 21:54:34 +00:00
else
2019-12-18 10:09:01 +00:00
PlayerSound ( DIGI_GOTRAILGUN , v3df_dontpan | v3df_doppler | v3df_follow , pp ) ;
2015-05-19 21:54:34 +00:00
}
//ChoosePlayerGetSound(pp);
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_RAIL ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_RAIL ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_RAIL & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponRail ( pp ) ;
break ;
case ICON_RAIL_AMMO :
if ( SW_SHAREWARE ) { KillSprite ( SpriteNum ) ; break ; }
if ( pp - > WpnAmmo [ WPN_RAIL ] > = DamageData [ WPN_RAIL ] . max_ammo )
break ;
//sprintf(ds,"Rail Gun Rods");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMORAILGUN ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_RAIL , DamageData [ WPN_RAIL ] . ammo_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetAmmo ( SpriteNum ) ;
break ;
case ICON_SHOTGUN :
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_SHOTGUN ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_SHOTGUN ) ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_SHOTGUN ) ) & & pp - > WpnAmmo [ WPN_SHOTGUN ] > = DamageData [ WPN_SHOTGUN ] . max_ammo )
break ;
//sprintf(ds,"Riot Gun");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNRIOT ) ) ;
2015-05-19 21:54:34 +00:00
// pp->WpnAmmo[WPN_SHOTGUN] += 10;
PlayerUpdateAmmo ( pp , WPN_SHOTGUN , DamageData [ WPN_SHOTGUN ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
ChoosePlayerGetSound ( pp ) ;
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_SHOTGUN ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_SHOTGUN ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_SHOTGUN & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponShotgun ( pp ) ;
break ;
case ICON_LG_SHOTSHELL :
if ( pp - > WpnAmmo [ WPN_SHOTGUN ] > = DamageData [ WPN_SHOTGUN ] . max_ammo )
break ;
//sprintf(ds,"Shotshells");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMORIOT ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_SHOTGUN , DamageData [ WPN_SHOTGUN ] . ammo_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetAmmo ( SpriteNum ) ;
break ;
#if 0
case ICON_AUTORIOT :
if ( pp - > WpnShotgunAuto ! = 50 )
{
sprintf ( ds , " Riot Gun TurboDrive, +50 12-Gauge Slugs " ) ;
PutStringInfo ( Player + pnum , ds ) ;
pp - > WpnShotgunAuto = 50 ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
if ( pp - > CurWpn = = pp - > Wpn [ WPN_SHOTGUN ] )
{
if ( pp - > WpnShotgunType ! = 1 )
{
extern PANEL_STATE ps_ShotgunFlash [ ] ;
pp - > CurWpn - > over [ SHOTGUN_AUTO_NUM ] . tics = 0 ;
pp - > CurWpn - > over [ SHOTGUN_AUTO_NUM ] . State = ps_ShotgunFlash ;
}
}
}
break ;
# endif
case ICON_GUARD_HEAD :
if ( SW_SHAREWARE ) { KillSprite ( SpriteNum ) ; break ; }
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_HOTHEAD ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_HOTHEAD ) ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_HOTHEAD ) ) & & pp - > WpnAmmo [ WPN_HOTHEAD ] > = DamageData [ WPN_HOTHEAD ] . max_ammo )
break ;
//sprintf(ds,"Guardian Head");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNHEAD ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_HOTHEAD , DamageData [ WPN_HOTHEAD ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
//ChoosePlayerGetSound(pp);
if ( STD_RANDOM_RANGE ( 1000 ) > 800 & & pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlayerSound ( DIGI_LIKEBIGWEAPONS , v3df_dontpan | v3df_doppler | v3df_follow , pp ) ;
2015-05-19 21:54:34 +00:00
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_HOTHEAD ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_NAPALM ) | BIT ( WPN_RING ) | BIT ( WPN_HOTHEAD ) ) ;
2019-11-30 06:10:40 +00:00
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_HOTHEAD & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponHothead ( pp ) ;
break ;
case ICON_FIREBALL_LG_AMMO :
if ( SW_SHAREWARE ) { KillSprite ( SpriteNum ) ; break ; }
if ( pp - > WpnAmmo [ WPN_HOTHEAD ] > = DamageData [ WPN_HOTHEAD ] . max_ammo )
break ;
//sprintf(ds,"Firebursts");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMOHEAD ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_HOTHEAD , DamageData [ WPN_HOTHEAD ] . ammo_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetAmmo ( SpriteNum ) ;
break ;
case ICON_HEART :
if ( SW_SHAREWARE ) { KillSprite ( SpriteNum ) ; break ; }
if ( ! CanGetWeapon ( pp , SpriteNum , WPN_HEART ) )
break ;
SET ( pp - > WpnGotOnceFlags , BIT ( WPN_HEART ) ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_HEART ) ) & & pp - > WpnAmmo [ WPN_HEART ] > = DamageData [ WPN_HEART ] . max_ammo )
break ;
//sprintf(ds,"Ripper Heart");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_WPNRIPPER ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_HEART , DamageData [ WPN_HEART ] . weapon_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
//ChoosePlayerGetSound(pp);
if ( STD_RANDOM_RANGE ( 1000 ) > 800 & & pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlayerSound ( DIGI_LIKEBIGWEAPONS , v3df_dontpan | v3df_doppler | v3df_follow , pp ) ;
2015-05-19 21:54:34 +00:00
KillGetWeapon ( SpriteNum ) ;
if ( TEST ( pp - > WpnFlags , BIT ( WPN_HEART ) ) )
break ;
SET ( pp - > WpnFlags , BIT ( WPN_HEART ) ) ;
2019-12-07 19:48:16 +00:00
if ( ! cl_weaponswitch )
2019-11-30 06:10:40 +00:00
break ;
2015-05-19 21:54:34 +00:00
if ( User [ pp - > PlayerSprite ] - > WeaponNum > WPN_HEART & & User [ pp - > PlayerSprite ] - > WeaponNum ! = WPN_SWORD )
break ;
InitWeaponHeart ( pp ) ;
break ;
case ICON_HEART_LG_AMMO :
if ( SW_SHAREWARE ) { KillSprite ( SpriteNum ) ; break ; }
if ( pp - > WpnAmmo [ WPN_HEART ] > = DamageData [ WPN_HEART ] . max_ammo )
break ;
//sprintf(ds,"Deathcoils");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMORIPPER ) ) ;
2015-05-19 21:54:34 +00:00
PlayerUpdateAmmo ( pp , WPN_HEART , DamageData [ WPN_HEART ] . ammo_pickup ) ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGetAmmo ( SpriteNum ) ;
break ;
case ICON_HEAT_CARD :
if ( pp - > WpnRocketHeat ! = 5 )
{
//sprintf(ds,"Heat Seeker Card");
2019-12-09 18:49:36 +00:00
PutStringInfo ( Player + pnum , quoteMgr . GetQuote ( QUOTE_AMMONUKE ) ) ;
2015-05-19 21:54:34 +00:00
pp - > WpnRocketHeat = DamageData [ DMG_NUCLEAR_EXP ] . ammo_pickup ;
SetFadeAmt ( pp , ITEMFLASHAMT , ITEMFLASHCLR ) ; // Flash blue on item pickup
if ( pp = = Player + myconnectindex )
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
KillGet ( SpriteNum ) ;
if ( pp - > CurWpn = = pp - > Wpn [ WPN_MICRO ] )
{
if ( pp - > WpnRocketType = = 0 )
{
pp - > WpnRocketType = 1 ;
}
else if ( pp - > WpnRocketType = = 2 )
{
extern PANEL_STATE ps_MicroHeatFlash [ ] ;
pp - > CurWpn - > over [ MICRO_HEAT_NUM ] . tics = 0 ;
pp - > CurWpn - > over [ MICRO_HEAT_NUM ] . State = ps_MicroHeatFlash ;
}
}
}
break ;
case ICON_FLAG :
if ( sp - > pal = = sprite [ pp - > PlayerSprite ] . pal ) break ; // Can't pick up your own flag!
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM , sp , v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
if ( sp - > hitag = = TAG_NORESPAWN_FLAG )
2017-01-23 11:21:32 +00:00
New = SpawnSprite ( STAT_ITEM , ICON_FLAG , s_CarryFlagNoDet , sp - > sectnum ,
2015-05-19 21:54:34 +00:00
sp - > x , sp - > y , sp - > z , 0 , 0 ) ;
else
2017-01-23 11:21:32 +00:00
New = SpawnSprite ( STAT_ITEM , ICON_FLAG , s_CarryFlag , sp - > sectnum ,
2015-05-19 21:54:34 +00:00
sp - > x , sp - > y , sp - > z , 0 , 0 ) ;
2017-01-23 11:21:32 +00:00
np = & sprite [ New ] ;
nu = User [ New ] ;
2015-05-19 21:54:34 +00:00
np - > shade = - 20 ;
// Attach flag to player
nu - > Counter = 0 ;
RESET ( np - > cstat , CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN ) ;
2018-02-16 06:38:31 +00:00
SET ( np - > cstat , CSTAT_SPRITE_ALIGNMENT_WALL ) ;
2017-01-23 11:21:32 +00:00
SetAttach ( pp - > PlayerSprite , New ) ;
2015-05-19 21:54:34 +00:00
nu - > sz = SPRITEp_MID ( & sprite [ pp - > PlayerSprite ] ) ; // Set mid way up who it hit
nu - > spal = np - > pal = sp - > pal ; // Set the palette of the flag
2017-01-23 11:21:32 +00:00
SetOwner ( pp - > PlayerSprite , New ) ; // Player now owns the flag
2015-05-19 21:54:34 +00:00
nu - > FlagOwner = SpriteNum ; // Tell carried flag who owns it
KillGet ( SpriteNum ) ; // Set up for flag respawning
break ;
default :
KillSprite ( SpriteNum ) ;
}
}
return 0 ;
}
/*
! AIC KEY - Set Active and Inactive code is here . It was tough to make this
fast . Just know that the main flag is SPR_ACTIVE . Should not need to be
changed except for possibly the u - > active_range settings in the future .
*/
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
SetEnemyActive ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
SET ( u - > Flags , SPR_ACTIVE ) ;
u - > inactive_time = 0 ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
SetEnemyInactive ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
RESET ( u - > Flags , SPR_ACTIVE ) ;
}
// This function mostly only adjust the active_range field
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
ProcessActiveVars ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
# define TIME_TILL_INACTIVE (4*120)
if ( ! TEST ( u - > Flags , SPR_ACTIVE ) )
{
// if actor has been unaware for more than a few seconds
u - > inactive_time + = ACTORMOVETICS ;
if ( u - > inactive_time > TIME_TILL_INACTIVE )
{
// reset to min update range
u - > active_range = MIN_ACTIVE_RANGE ;
// keep time low so it doesn't roll over
u - > inactive_time = TIME_TILL_INACTIVE ;
}
}
u - > wait_active_check + = ACTORMOVETICS ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
AdjustActiveRange ( PLAYERp pp , short SpriteNum , int dist )
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = u - > SpriteP ;
SPRITEp psp = pp - > SpriteP ;
int look_height ;
// do no FAFcansee before it is time
if ( u - > wait_active_check < ACTIVE_CHECK_TIME )
return ;
u - > wait_active_check = 0 ;
// check aboslute max
if ( dist > MAX_ACTIVE_RANGE )
return ;
// do not do a FAFcansee if your already active
// Actor only becomes INACTIVE in DoActorDecision
if ( TEST ( u - > Flags , SPR_ACTIVE ) )
return ;
//
// From this point on Actor is INACTIVE
//
// if actor can still see the player
look_height = SPRITEp_TOS ( sp ) ;
if ( FAFcansee ( sp - > x , sp - > y , look_height , sp - > sectnum , psp - > x , psp - > y , SPRITEp_UPPER ( psp ) , psp - > sectnum ) )
{
// Player is visible
// adjust update range of this sprite
// some huge distance
u - > active_range = 75000 ;
// sprite is AWARE
SetEnemyActive ( SpriteNum ) ;
}
}
/*
! AIC KEY - Main processing loop for sprites . Sprites are separated and
traversed by STAT lists . Note the STAT_MISC , STAT_ENEMY , STAT_VATOR below .
Most everything here calls StateControl ( ) .
*/
# if DEBUG
# define INLINE_STATE 0
# else
# define INLINE_STATE 1
# endif
# define STATE_CONTROL(SpriteNum, sp, u, StateTics) \
if ( ! ( u ) - > State ) \
{ \
ASSERT ( ( u ) - > ActorActionFunc ) ; \
( ( u ) - > ActorActionFunc ) ( ( SpriteNum ) ) ; \
} \
else \
{ \
if ( ( sp ) - > statnum > = STAT_SKIP4_START & & ( sp ) - > statnum < = STAT_SKIP4_END ) \
( u ) - > Tics + = ACTORMOVETICS * 2 ; \
else \
( u ) - > Tics + = ACTORMOVETICS ; \
\
while ( ( u ) - > Tics > = TEST ( ( u ) - > State - > Tics , SF_TICS_MASK ) ) \
{ \
( StateTics ) = TEST ( ( u ) - > State - > Tics , SF_TICS_MASK ) ; \
\
if ( TEST ( ( u ) - > State - > Tics , SF_TIC_ADJUST ) ) \
{ \
ASSERT ( ( u ) - > Attrib ) ; \
ASSERT ( ( u ) - > speed < MAX_SPEED ) ; \
ASSERT ( ( StateTics ) > - ( u ) - > Attrib - > TicAdjust [ ( u ) - > speed ] ) ; \
\
( StateTics ) + = ( u ) - > Attrib - > TicAdjust [ ( u ) - > speed ] ; \
} \
\
( u ) - > Tics - = ( StateTics ) ; \
\
( u ) - > State = ( u ) - > State - > NextState ; \
\
while ( TEST ( ( u ) - > State - > Tics , SF_QUICK_CALL ) ) \
{ \
( * ( u ) - > State - > Animator ) ( ( SpriteNum ) ) ; \
ASSERT ( u ) ; \
\
if ( ! ( u ) ) \
break ; \
\
if ( TEST ( ( u ) - > State - > Tics , SF_QUICK_CALL ) ) \
( u ) - > State = ( u ) - > State - > NextState ; \
} \
\
if ( ! ( u ) ) \
break ; \
\
if ( ! ( u ) - > State - > Pic ) \
{ \
NewStateGroup ( ( SpriteNum ) , ( STATEp * ) ( u ) - > State - > NextState ) ; \
} \
} \
\
if ( u ) \
{ \
if ( TEST ( ( u ) - > State - > Tics , SF_WALL_STATE ) ) \
{ \
ASSERT ( ( u ) - > WallP ) ; \
( u ) - > WallP - > picnum = ( u ) - > State - > Pic ; \
} \
else \
{ \
if ( ( u ) - > RotNum > 1 ) \
( sp ) - > picnum = ( u ) - > Rot [ 0 ] - > Pic ; \
else \
( sp ) - > picnum = ( u ) - > State - > Pic ; \
} \
\
if ( ( u ) - > State - > Animator & & ( u ) - > State - > Animator ! = NullAnimator ) \
( * ( u ) - > State - > Animator ) ( ( SpriteNum ) ) ; \
} \
}
/*
! AIC KEY - Reads state tables for animation frame transitions and handles
calling animators , QUICK_CALLS , etc . This is handled for many types of
sprites not just actors .
*/
int
2015-05-19 21:58:29 +00:00
StateControl ( int16_t SpriteNum )
2015-05-19 21:54:34 +00:00
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = & sprite [ SpriteNum ] ;
short StateTics ;
if ( ! u - > State )
{
ASSERT ( u - > ActorActionFunc ) ;
( u - > ActorActionFunc ) ( SpriteNum ) ;
return 0 ;
}
if ( sp - > statnum > = STAT_SKIP4_START & & sp - > statnum < = STAT_SKIP4_END )
u - > Tics + = ACTORMOVETICS * 2 ;
else
u - > Tics + = ACTORMOVETICS ;
// Skip states if too much time has passed
while ( u - > Tics > = TEST ( u - > State - > Tics , SF_TICS_MASK ) )
{
StateTics = TEST ( u - > State - > Tics , SF_TICS_MASK ) ;
if ( TEST ( u - > State - > Tics , SF_TIC_ADJUST ) )
{
ASSERT ( u - > Attrib ) ;
ASSERT ( u - > speed < MAX_SPEED ) ;
ASSERT ( StateTics > - u - > Attrib - > TicAdjust [ u - > speed ] ) ;
StateTics + = u - > Attrib - > TicAdjust [ u - > speed ] ;
}
// Set Tics
u - > Tics - = StateTics ;
// Transition to the next state
u - > State = u - > State - > NextState ;
// Look for flags embedded into the Tics variable
while ( TEST ( u - > State - > Tics , SF_QUICK_CALL ) )
{
// Call it once and go to the next state
( * u - > State - > Animator ) ( SpriteNum ) ;
ASSERT ( u ) ; //put this in to see if actor was getting killed with in his QUICK_CALL state
if ( ! u )
break ;
// if still on the same QUICK_CALL should you
// go to the next state.
if ( TEST ( u - > State - > Tics , SF_QUICK_CALL ) )
u - > State = u - > State - > NextState ;
}
if ( ! u )
break ;
if ( ! u - > State - > Pic )
{
NewStateGroup ( SpriteNum , ( STATEp * ) u - > State - > NextState ) ;
}
}
if ( u )
{
ASSERT ( u - > State ) ;
// Set picnum to the correct pic
if ( TEST ( u - > State - > Tics , SF_WALL_STATE ) )
{
ASSERT ( u - > WallP ) ;
u - > WallP - > picnum = u - > State - > Pic ;
}
else
{
//u->SpriteP->picnum = u->State->Pic;
if ( u - > RotNum > 1 )
sp - > picnum = u - > Rot [ 0 ] - > Pic ;
else
sp - > picnum = u - > State - > Pic ;
}
// Call the correct animator
if ( u - > State - > Animator & & u - > State - > Animator ! = NullAnimator )
( * u - > State - > Animator ) ( SpriteNum ) ;
}
return 0 ;
}
2015-05-19 21:58:29 +00:00
void
SpriteControl ( void )
2015-05-19 21:54:34 +00:00
{
2015-05-19 21:58:29 +00:00
int32_t i , nexti , stat ;
2015-05-19 21:54:34 +00:00
SPRITEp sp ;
USERp u ;
short pnum , CloseToPlayer ;
PLAYERp pp ;
int tx , ty , tmin , dist ;
2015-05-19 21:58:29 +00:00
extern SWBOOL DebugActorFreeze ;
2015-05-19 21:54:34 +00:00
short StateTics ;
if ( DebugActorFreeze )
return ;
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_MISC ] , i , nexti )
{
# if INLINE_STATE
ASSERT ( User [ i ] ) ;
u = User [ i ] ;
sp = User [ i ] - > SpriteP ;
STATE_CONTROL ( i , sp , u , StateTics )
2019-12-03 09:44:56 +00:00
// ASSERT(nexti >= 0 ? User[nexti] != NULL : TRUE);
2015-05-19 21:54:34 +00:00
# else
ASSERT ( User [ i ] ) ;
StateControl ( i ) ;
2019-12-03 09:44:56 +00:00
// ASSERT(nexti >= 0 ? User[nexti] != NULL : TRUE);
2015-05-19 21:54:34 +00:00
# endif
}
// Items and skip2 things
if ( MoveSkip2 = = 0 )
{
for ( stat = STAT_SKIP2_START + 1 ; stat < = STAT_SKIP2_END ; stat + + )
{
TRAVERSE_SPRITE_STAT ( headspritestat [ stat ] , i , nexti )
{
# if INLINE_STATE
ASSERT ( User [ i ] ) ;
u = User [ i ] ;
sp = User [ i ] - > SpriteP ;
STATE_CONTROL ( i , sp , u , StateTics )
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# else
ASSERT ( User [ i ] ) ;
StateControl ( i ) ;
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# endif
}
}
}
if ( MoveSkip2 = = 0 ) // limit to 20 times a second
{
// move bad guys around
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_ENEMY ] , i , nexti )
{
ASSERT ( User [ i ] ) ;
u = User [ i ] ;
sp = u - > SpriteP ;
CloseToPlayer = FALSE ;
ProcessActiveVars ( i ) ;
TRAVERSE_CONNECT ( pnum )
{
pp = & Player [ pnum ] ;
// Only update the ones closest
DISTANCE ( pp - > posx , pp - > posy , sp - > x , sp - > y , dist , tx , ty , tmin ) ;
AdjustActiveRange ( pp , i , dist ) ;
if ( dist < u - > active_range )
{
CloseToPlayer = TRUE ;
}
}
RESET ( u - > Flags , SPR_MOVED ) ;
// Only update the ones close to ANY player
if ( CloseToPlayer )
{
# if INLINE_STATE
u = User [ i ] ;
sp = User [ i ] - > SpriteP ;
STATE_CONTROL ( i , sp , u , StateTics )
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# else
StateControl ( i ) ;
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# endif
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
}
else
{
// to far away to be attacked
RESET ( u - > Flags , SPR_ATTACKED ) ;
}
}
}
// Skip4 things
if ( MoveSkip4 = = 0 ) // limit to 10 times a second
{
for ( stat = STAT_SKIP4_START ; stat < = STAT_SKIP4_END ; stat + + )
{
TRAVERSE_SPRITE_STAT ( headspritestat [ stat ] , i , nexti )
{
# if INLINE_STATE
ASSERT ( User [ i ] ) ;
u = User [ i ] ;
sp = User [ i ] - > SpriteP ;
STATE_CONTROL ( i , sp , u , StateTics )
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# else
ASSERT ( User [ i ] ) ;
StateControl ( i ) ;
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# endif
}
}
}
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_NO_STATE ] , i , nexti )
{
if ( User [ i ] & & User [ i ] - > ActorActionFunc )
( * User [ i ] - > ActorActionFunc ) ( i ) ;
ASSERT ( nexti > = 0 ? sprite [ nexti ] . statnum ! = MAXSTATUS : TRUE ) ;
}
if ( MoveSkip8 = = 0 )
{
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_STATIC_FIRE ] , i , nexti )
{
extern int DoStaticFlamesDamage ( short SpriteNum ) ;
ASSERT ( User [ i ] ) ;
DoStaticFlamesDamage ( i ) ;
}
}
if ( MoveSkip4 = = 0 ) // limit to 10 times a second
{
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_WALLBLOOD_QUEUE ] , i , nexti )
{
# if INLINE_STATE
ASSERT ( User [ i ] ) ;
u = User [ i ] ;
sp = User [ i ] - > SpriteP ;
STATE_CONTROL ( i , sp , u , StateTics )
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# else
ASSERT ( User [ i ] ) ;
StateControl ( i ) ;
ASSERT ( nexti > = 0 ? User [ nexti ] ! = NULL : TRUE ) ;
# endif
}
}
// vator/rotator/spike/slidor all have some code to
// prevent calling of the action func()
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_VATOR ] , i , nexti )
{
u = User [ i ] ;
2019-11-17 17:02:17 +00:00
if ( u = = 0 )
continue ;
2015-05-19 21:54:34 +00:00
if ( u - > Tics )
{
if ( ( u - > Tics - = synctics ) < = 0 )
SetVatorActive ( i ) ;
else
continue ;
}
if ( ! TEST ( u - > Flags , SPR_ACTIVE ) )
continue ;
( * User [ i ] - > ActorActionFunc ) ( i ) ;
}
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_SPIKE ] , i , nexti )
{
u = User [ i ] ;
if ( u - > Tics )
{
if ( ( u - > Tics - = synctics ) < = 0 )
SetSpikeActive ( i ) ;
else
continue ;
}
if ( ! TEST ( u - > Flags , SPR_ACTIVE ) )
continue ;
2019-11-17 17:02:17 +00:00
if ( i = = 69 & & nexti = = - 1 )
continue ;
2015-05-19 21:54:34 +00:00
( * User [ i ] - > ActorActionFunc ) ( i ) ;
}
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_ROTATOR ] , i , nexti )
{
u = User [ i ] ;
if ( u - > Tics )
{
if ( ( u - > Tics - = synctics ) < = 0 )
SetRotatorActive ( i ) ;
else
continue ;
}
if ( ! TEST ( u - > Flags , SPR_ACTIVE ) )
continue ;
( * User [ i ] - > ActorActionFunc ) ( i ) ;
}
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_SLIDOR ] , i , nexti )
{
u = User [ i ] ;
if ( u - > Tics )
{
if ( ( u - > Tics - = synctics ) < = 0 )
SetSlidorActive ( i ) ;
else
continue ;
}
if ( ! TEST ( u - > Flags , SPR_ACTIVE ) )
continue ;
( * User [ i ] - > ActorActionFunc ) ( i ) ;
}
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_SUICIDE ] , i , nexti )
{
KillSprite ( i ) ;
}
}
//
// This moves an actor about with FAFgetzrange clip adjustment
//
/*
! AIC KEY - calls clipmove - Look through and try to understatnd Should
hopefully never have to change this . Its very delicate .
*/
int
2015-05-19 21:58:29 +00:00
move_sprite ( short spritenum , int xchange , int ychange , int zchange , int ceildist , int flordist , uint32_t cliptype , int numtics )
2015-05-19 21:54:34 +00:00
{
int daz ;
int retval = 0 , zh ;
short dasectnum , tempshort ;
SPRITEp spr ;
USERp u = User [ spritenum ] ;
short lastsectnum ;
spr = & sprite [ spritenum ] ;
ASSERT ( u ) ;
// Can't modify sprite sectors
// directly becuase of linked lists
dasectnum = lastsectnum = spr - > sectnum ;
// Must do this if not using the new
// centered centering (of course)
daz = spr - > z ;
if ( TEST ( spr - > cstat , CSTAT_SPRITE_YCENTER ) )
{
zh = 0 ;
}
else
{
// move the center point up for moving
zh = u - > zclip ;
daz - = zh ;
}
// ASSERT(inside(spr->x,spr->y,dasectnum));
clipmoveboxtracenum = 1 ;
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
retval = clipmove_old ( & spr - > x , & spr - > y , & daz , & dasectnum ,
2015-05-19 21:54:34 +00:00
( ( xchange * numtics ) < < 11 ) , ( ( ychange * numtics ) < < 11 ) ,
( ( ( int ) spr - > clipdist ) < < 2 ) , ceildist , flordist , cliptype ) ;
clipmoveboxtracenum = 3 ;
//if (TEST(retval, HIT_MASK) == HIT_WALL)
// {
// CON_Message("retval = %ld",NORM_WALL(retval));
// CON_Message("clipdist = %d",spr->clipdist);
// }
if ( dasectnum < 0 )
{
retval = HIT_WALL ;
//ASSERT(TRUE == FALSE);
return retval ;
}
if ( ( dasectnum ! = spr - > sectnum ) & & ( dasectnum > = 0 ) )
changespritesect ( spritenum , dasectnum ) ;
// took this out - may not be to relevant anymore
//ASSERT(inside(spr->x,spr->y,dasectnum));
// Set the blocking bit to 0 temporarly so FAFgetzrange doesn't pick
// up its own sprite
tempshort = spr - > cstat ;
spr - > cstat = 0 ;
//RESET(spr->cstat, CSTAT_SPRITE_BLOCK);
// I subtracted 8 from the clipdist because actors kept going up on
// ledges they were not supposed to go up on. Did the same for the
// player. Seems to work ok!
FAFgetzrange ( spr - > x , spr - > y , spr - > z - zh - 1 , spr - > sectnum ,
& globhiz , & globhihit , & globloz , & globlohit ,
( ( ( int ) spr - > clipdist ) < < 2 ) - GETZRANGE_CLIP_ADJ , cliptype ) ;
spr - > cstat = tempshort ;
// !AIC - puts getzrange results into USER varaible u->loz, u->hiz, u->lo_sectp, u->hi_sectp, etc.
// Takes info from global variables
DoActorGlobZ ( spritenum ) ;
daz = spr - > z + ( ( zchange * numtics ) > > 3 ) ;
// test for hitting ceiling or floor
if ( ( daz - zh < = globhiz ) | | ( daz - zh > globloz ) )
{
if ( retval = = 0 )
{
if ( TEST ( u - > Flags , SPR_CLIMBING ) )
{
spr - > z = daz ;
return 0 ;
}
retval = HIT_SECTOR | dasectnum ;
}
}
else
{
spr - > z = daz ;
}
// extra processing for Stacks and warping
if ( FAF_ConnectArea ( spr - > sectnum ) )
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
setspritez ( spritenum , ( vec3_t * ) spr ) ;
2015-05-19 21:54:34 +00:00
if ( TEST ( sector [ spr - > sectnum ] . extra , SECTFX_WARP_SECTOR ) )
{
SPRITEp sp_warp ;
if ( ( sp_warp = WarpPlane ( & spr - > x , & spr - > y , & spr - > z , & dasectnum ) ) )
{
ActorWarpUpdatePos ( spritenum , dasectnum ) ;
ActorWarpType ( spr , sp_warp ) ;
}
if ( spr - > sectnum ! = lastsectnum )
{
if ( ( sp_warp = Warp ( & spr - > x , & spr - > y , & spr - > z , & dasectnum ) ) )
{
ActorWarpUpdatePos ( spritenum , dasectnum ) ;
ActorWarpType ( spr , sp_warp ) ;
}
}
}
return retval ;
}
// not used - SLOW!
int pushmove_sprite ( short SpriteNum )
{
SPRITEp sp = & sprite [ SpriteNum ] ;
USERp u = User [ SpriteNum ] ;
short sectnum , ret ;
int daz ;
daz = sp - > z - u - > zclip ;
sectnum = sp - > sectnum ;
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
ret = pushmove_old ( & sp - > x , & sp - > y , & daz , & sectnum ,
2015-05-19 21:54:34 +00:00
( ( ( int ) sp - > clipdist ) < < 2 ) - GETZRANGE_CLIP_ADJ , u - > ceiling_dist , u - > floor_dist , CLIPMASK_ACTOR ) ;
if ( sectnum ! = sp - > sectnum & & sectnum > = 0 )
changespritesect ( SpriteNum , sectnum ) ;
if ( ret < 0 )
{
//DSPRINTF(ds,"Pushed out!!!!! sp->sectnum %d", sp->sectnum);
MONO_PRINT ( ds ) ;
}
sp - > z = daz + u - > zclip ;
return 0 ;
}
2015-05-19 21:58:29 +00:00
void MissileWarpUpdatePos ( short SpriteNum , short sectnum )
2015-05-19 21:54:34 +00:00
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = u - > SpriteP ;
u - > ox = sp - > x ;
u - > oy = sp - > y ;
u - > oz = sp - > z ;
changespritesect ( SpriteNum , sectnum ) ;
MissileZrange ( SpriteNum ) ;
}
2015-05-19 21:58:29 +00:00
void ActorWarpUpdatePos ( short SpriteNum , short sectnum )
2015-05-19 21:54:34 +00:00
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = u - > SpriteP ;
u - > ox = sp - > x ;
u - > oy = sp - > y ;
u - > oz = sp - > z ;
changespritesect ( SpriteNum , sectnum ) ;
DoActorZrange ( SpriteNum ) ;
}
2015-05-19 21:58:29 +00:00
void MissileWarpType ( SPRITEp sp , SPRITEp sp_warp )
2015-05-19 21:54:34 +00:00
{
switch ( SP_TAG1 ( sp_warp ) )
{
case WARP_CEILING_PLANE :
case WARP_FLOOR_PLANE :
return ;
}
switch ( SP_TAG3 ( sp_warp ) )
{
case 1 :
break ;
default :
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM_SPAWN , sp , v3df_none ) ;
2015-05-19 21:54:34 +00:00
//DoSpawnTeleporterEffectPlace(sp);
DoSpawnItemTeleporterEffect ( sp ) ;
break ;
}
}
2015-05-19 21:58:29 +00:00
void ActorWarpType ( SPRITEp sp , SPRITEp sp_warp )
2015-05-19 21:54:34 +00:00
{
switch ( SP_TAG3 ( sp_warp ) )
{
case 1 :
break ;
default :
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_ITEM_SPAWN , sp , v3df_none ) ;
2015-05-19 21:54:34 +00:00
DoSpawnTeleporterEffectPlace ( sp ) ;
break ;
}
}
//
// This moves a small projectile with FAFgetzrangepoint
//
int
MissileWaterAdjust ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
if ( u - > lo_sectp )
{
SECT_USERp sectu = SectUser [ u - > lo_sectp - sector ] ;
if ( sectu & & sectu - > depth )
u - > loz - = Z ( sectu - > depth ) ;
}
return 0 ;
}
int
MissileZrange ( short SpriteNum )
{
USERp u = User [ SpriteNum ] ;
SPRITEp sp = u - > SpriteP ;
short tempshort ;
// Set the blocking bit to 0 temporarly so FAFgetzrange doesn't pick
// up its own sprite
tempshort = sp - > cstat ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
FAFgetzrangepoint ( sp - > x , sp - > y , sp - > z - 1 , sp - > sectnum ,
& globhiz , & globhihit , & globloz , & globlohit ) ;
sp - > cstat = tempshort ;
DoActorGlobZ ( SpriteNum ) ;
return 0 ;
}
int
2015-05-19 21:58:29 +00:00
move_missile ( short spritenum , int xchange , int ychange , int zchange , int ceildist , int flordist , uint32_t cliptype , int numtics )
2015-05-19 21:54:34 +00:00
{
int daz ;
int retval , zh ;
short dasectnum , tempshort ;
SPRITEp sp ;
USERp u = User [ spritenum ] ;
short lastsectnum ;
sp = & sprite [ spritenum ] ;
ASSERT ( u ) ;
// Can't modify sprite sectors
// directly becuase of linked lists
dasectnum = lastsectnum = sp - > sectnum ;
// Can't modify sprite sectors
// directly becuase of linked lists
daz = sp - > z ;
if ( TEST ( sp - > cstat , CSTAT_SPRITE_YCENTER ) )
{
zh = 0 ;
}
else
{
zh = u - > zclip ;
daz - = zh ;
}
// ASSERT(inside(sp->x,sp->y,dasectnum));
clipmoveboxtracenum = 1 ;
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
retval = clipmove_old ( & sp - > x , & sp - > y , & daz , & dasectnum ,
2015-05-19 21:54:34 +00:00
( ( xchange * numtics ) < < 11 ) , ( ( ychange * numtics ) < < 11 ) ,
( ( ( int ) sp - > clipdist ) < < 2 ) , ceildist , flordist , cliptype ) ;
clipmoveboxtracenum = 3 ;
if ( dasectnum < 0 )
{
// we've gone beyond a white wall - kill it
retval = 0 ;
SET ( retval , HIT_PLAX_WALL ) ;
return retval ;
}
// took this out - may not be to relevant anymore
//ASSERT(inside(sp->x,sp->y,dasectnum));
if ( ( dasectnum ! = sp - > sectnum ) & & ( dasectnum > = 0 ) )
changespritesect ( spritenum , dasectnum ) ;
// Set the blocking bit to 0 temporarly so FAFgetzrange doesn't pick
// up its own sprite
tempshort = sp - > cstat ;
RESET ( sp - > cstat , CSTAT_SPRITE_BLOCK ) ;
FAFgetzrangepoint ( sp - > x , sp - > y , sp - > z - 1 , sp - > sectnum ,
& globhiz , & globhihit , & globloz , & globlohit ) ;
sp - > cstat = tempshort ;
DoActorGlobZ ( spritenum ) ;
// getzrangepoint moves water down
// missiles don't need the water to be down
MissileWaterAdjust ( spritenum ) ;
daz = sp - > z + ( ( zchange * numtics ) > > 3 ) ;
// NOTE: this does not tell you when you hit a floor sprite
// this case is currently treated like it hit a sector
// test for hitting ceiling or floor
if ( daz - zh < = u - > hiz + ceildist )
{
// normal code
sp - > z = u - > hiz + zh + ceildist ;
if ( retval = = 0 )
retval = dasectnum | HIT_SECTOR ;
}
else if ( daz - zh > u - > loz - flordist )
{
sp - > z = u - > loz + zh - flordist ;
if ( retval = = 0 )
retval = dasectnum | HIT_SECTOR ;
}
else
{
sp - > z = daz ;
}
if ( FAF_ConnectArea ( sp - > sectnum ) )
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
setspritez ( spritenum , ( vec3_t * ) sp ) ;
2015-05-19 21:54:34 +00:00
if ( TEST ( sector [ sp - > sectnum ] . extra , SECTFX_WARP_SECTOR ) )
{
SPRITEp sp_warp ;
if ( ( sp_warp = WarpPlane ( & sp - > x , & sp - > y , & sp - > z , & dasectnum ) ) )
{
MissileWarpUpdatePos ( spritenum , dasectnum ) ;
MissileWarpType ( sp , sp_warp ) ;
}
if ( sp - > sectnum ! = lastsectnum )
{
if ( ( sp_warp = Warp ( & sp - > x , & sp - > y , & sp - > z , & dasectnum ) ) )
{
MissileWarpUpdatePos ( spritenum , dasectnum ) ;
MissileWarpType ( sp , sp_warp ) ;
}
}
}
if ( retval & & TEST ( sector [ sp - > sectnum ] . ceilingstat , CEILING_STAT_PLAX ) )
{
if ( sp - > z < sector [ sp - > sectnum ] . ceilingz )
{
RESET ( retval , HIT_WALL | HIT_SECTOR ) ;
SET ( retval , HIT_PLAX_WALL ) ;
}
}
if ( retval & & TEST ( sector [ sp - > sectnum ] . floorstat , FLOOR_STAT_PLAX ) )
{
if ( sp - > z > sector [ sp - > sectnum ] . floorz )
{
RESET ( retval , HIT_WALL | HIT_SECTOR ) ;
SET ( retval , HIT_PLAX_WALL ) ;
}
}
return retval ;
}
int
2020-03-07 13:51:49 +00:00
move_ground_missile ( short spritenum , int xchange , int ychange , int ceildist , int flordist , uint32_t cliptype , int numtics )
2015-05-19 21:54:34 +00:00
{
int daz ;
2020-03-06 15:49:49 +00:00
int retval = 0 ;
short dasectnum ;
2015-05-19 21:54:34 +00:00
SPRITEp sp ;
USERp u = User [ spritenum ] ;
short lastsectnum ;
int ox , oy ;
sp = & sprite [ spritenum ] ;
ASSERT ( u ) ;
// Can't modify sprite sectors
// directly becuase of linked lists
dasectnum = lastsectnum = sp - > sectnum ;
daz = sp - > z ;
// climbing a wall
if ( u - > z_tgt )
{
if ( labs ( u - > z_tgt - sp - > z ) > Z ( 40 ) )
{
if ( u - > z_tgt > sp - > z )
{
sp - > z + = Z ( 30 ) ;
return retval ;
}
else
{
sp - > z - = Z ( 30 ) ;
return retval ;
}
}
else
u - > z_tgt = 0 ;
}
ox = sp - > x ;
oy = sp - > y ;
sp - > x + = xchange / 2 ;
sp - > y + = ychange / 2 ;
updatesector ( sp - > x , sp - > y , & dasectnum ) ;
if ( dasectnum < 0 )
{
// back up and try again
dasectnum = lastsectnum = sp - > sectnum ;
sp - > x = ox ;
sp - > y = oy ;
clipmoveboxtracenum = 1 ;
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
retval = clipmove_old ( & sp - > x , & sp - > y , & daz , & dasectnum ,
2015-05-19 21:54:34 +00:00
( ( xchange * numtics ) < < 11 ) , ( ( ychange * numtics ) < < 11 ) ,
( ( ( int ) sp - > clipdist ) < < 2 ) , ceildist , flordist , cliptype ) ;
clipmoveboxtracenum = 3 ;
}
if ( dasectnum < 0 )
{
// we've gone beyond a white wall - kill it
retval = 0 ;
SET ( retval , HIT_PLAX_WALL ) ;
return retval ;
}
if ( retval ) // ran into a white wall
{
2020-03-06 15:49:55 +00:00
//int new_loz,new_hiz;
2015-05-19 21:54:34 +00:00
// back up and try to clip UP
//dasectnum = lastsectnum = sp->sectnum;
//sp->x = ox;
//sp->y = oy;
#if 0
getzsofslope ( dasectnum , sp - > x , sp - > y , & new_hiz , & new_loz ) ;
if ( labs ( sp - > z - new_hiz ) > Z ( 40 ) )
{
u - > z_tgt = new_hiz ;
retval = 0 ;
return retval ;
}
else
# endif
return retval ;
}
u - > z_tgt = 0 ;
if ( ( dasectnum ! = sp - > sectnum ) & & ( dasectnum > = 0 ) )
{
int new_loz , new_hiz ;
getzsofslope ( dasectnum , sp - > x , sp - > y , & new_hiz , & new_loz ) ;
sp - > z = new_loz ;
#if 0
if ( labs ( sp - > z - new_loz ) > Z ( 40 ) )
{
if ( new_loz > sp - > z )
{
// travelling DOWN
u - > z_tgt = new_loz ;
changespritesect ( spritenum , dasectnum ) ;
getzsofslope ( sp - > sectnum , sp - > x , sp - > y , & u - > hiz , & u - > loz ) ;
u - > hi_sectp = u - > lo_sectp = & sector [ sp - > sectnum ] ;
u - > hi_sp = u - > lo_sp = NULL ;
return retval ;
}
else
{
// travelling UP
u - > z_tgt = new_loz ;
// back up and climb wall
dasectnum = lastsectnum = sp - > sectnum ;
sp - > x = ox ;
sp - > y = oy ;
return retval ;
}
}
else
{
u - > z_tgt = 0 ;
}
# endif
changespritesect ( spritenum , dasectnum ) ;
}
getzsofslope ( sp - > sectnum , sp - > x , sp - > y , & u - > hiz , & u - > loz ) ;
u - > hi_sectp = u - > lo_sectp = & sector [ sp - > sectnum ] ;
u - > hi_sp = u - > lo_sp = NULL ;
sp - > z = u - > loz - Z ( 8 ) ;
if ( labs ( u - > hiz - u - > loz ) < Z ( 12 ) )
{
// we've gone into a very small place - kill it
retval = 0 ;
SET ( retval , HIT_PLAX_WALL ) ;
return retval ;
}
// getzrangepoint moves water down
// missiles don't need the water to be down
//MissileWaterAdjust(spritenum);
//if (FAF_ConnectArea(sp->sectnum))
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
// setspritez(spritenum, (vec3_t *)sp);
2015-05-19 21:54:34 +00:00
if ( TEST ( sector [ sp - > sectnum ] . extra , SECTFX_WARP_SECTOR ) )
{
SPRITEp sp_warp ;
if ( ( sp_warp = WarpPlane ( & sp - > x , & sp - > y , & sp - > z , & dasectnum ) ) )
{
MissileWarpUpdatePos ( spritenum , dasectnum ) ;
MissileWarpType ( sp , sp_warp ) ;
}
if ( sp - > sectnum ! = lastsectnum )
{
if ( ( sp_warp = Warp ( & sp - > x , & sp - > y , & sp - > z , & dasectnum ) ) )
{
MissileWarpUpdatePos ( spritenum , dasectnum ) ;
MissileWarpType ( sp , sp_warp ) ;
}
}
}
return retval ;
}
/*
int push_check ( short SpriteNum )
{
switch ( sprite [ SpriteNum ] . lotag )
{
case TAG_DOOR_S , LIDING :
{
SPRITEp sp ;
USERp u ;
short i , nexti , sect ;
//DSPRINTF(ds,"Door Closing %d",sectnum);
MONO_PRINT ( ds ) ;
TRAVERSE_SPRITE_SECT ( headspritesect [ sectnum ] , i , nexti )
{
sp = & sprite [ i ] ;
u = User [ i ] ;
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
sect = pushmove ( ( vec3_t * ) sp , & sp - > sectnum , ( ( ( int ) sp - > clipdist ) < < 2 ) - 8 , u - > ceiling_dist , u - > floor_dist , CLIPMASK0 ) ;
2015-05-19 21:54:34 +00:00
if ( sect = = - 1 )
{
KillSprite ( i ) ;
}
}
}
}
}
*/
# include "saveable.h"
static saveable_code saveable_sprite_code [ ] =
{
SAVE_CODE ( DoActorZrange ) ,
SAVE_CODE ( DoActorGlobZ ) ,
SAVE_CODE ( DoStayOnFloor ) ,
SAVE_CODE ( DoGrating ) ,
SAVE_CODE ( SpearOnFloor ) ,
SAVE_CODE ( SpearOnCeiling ) ,
SAVE_CODE ( DoKey ) ,
SAVE_CODE ( DoCoin ) ,
SAVE_CODE ( KillGet ) ,
SAVE_CODE ( KillGetAmmo ) ,
SAVE_CODE ( KillGetWeapon ) ,
SAVE_CODE ( DoSpawnItemTeleporterEffect ) ,
SAVE_CODE ( DoGet ) ,
SAVE_CODE ( SetEnemyActive ) ,
SAVE_CODE ( SetEnemyInactive ) ,
SAVE_CODE ( ProcessActiveVars ) ,
SAVE_CODE ( StateControl ) ,
SAVE_CODE ( SpriteControl ) ,
} ;
static saveable_data saveable_sprite_data [ ] =
{
SAVE_DATA ( Track ) ,
SAVE_DATA ( SectorObject ) ,
SAVE_DATA ( s_DebrisNinja ) ,
SAVE_DATA ( s_DebrisRat ) ,
SAVE_DATA ( s_DebrisCrab ) ,
SAVE_DATA ( s_DebrisStarFish ) ,
SAVE_DATA ( s_RepairKit ) ,
SAVE_DATA ( s_GoldSkelKey ) ,
SAVE_DATA ( s_BlueKey ) ,
SAVE_DATA ( s_BlueCard ) ,
SAVE_DATA ( s_SilverSkelKey ) ,
SAVE_DATA ( s_RedKey ) ,
SAVE_DATA ( s_RedCard ) ,
SAVE_DATA ( s_BronzeSkelKey ) ,
SAVE_DATA ( s_GreenKey ) ,
SAVE_DATA ( s_GreenCard ) ,
SAVE_DATA ( s_RedSkelKey ) ,
SAVE_DATA ( s_YellowKey ) ,
SAVE_DATA ( s_YellowCard ) ,
SAVE_DATA ( s_Key ) ,
SAVE_DATA ( s_BlueKey ) ,
SAVE_DATA ( s_RedKey ) ,
SAVE_DATA ( s_GreenKey ) ,
SAVE_DATA ( s_YellowKey ) ,
SAVE_DATA ( s_Key ) ,
/*
SAVE_DATA ( s_BlueKeyStatue ) ,
SAVE_DATA ( s_RedKeyStatue ) ,
SAVE_DATA ( s_GreenKeyStatue ) ,
SAVE_DATA ( s_YellowKeyStatue ) ,
SAVE_DATA ( s_KeyStatue ) ,
*/
SAVE_DATA ( s_RedCoin ) ,
SAVE_DATA ( s_YellowCoin ) ,
SAVE_DATA ( s_GreenCoin ) ,
SAVE_DATA ( s_FireFly ) ,
SAVE_DATA ( s_IconStar ) ,
SAVE_DATA ( s_IconUzi ) ,
SAVE_DATA ( s_IconLgUziAmmo ) ,
SAVE_DATA ( s_IconUziFloor ) ,
SAVE_DATA ( s_IconRocket ) ,
SAVE_DATA ( s_IconLgRocket ) ,
SAVE_DATA ( s_IconShotgun ) ,
SAVE_DATA ( s_IconLgShotshell ) ,
SAVE_DATA ( s_IconAutoRiot ) ,
SAVE_DATA ( s_IconGrenadeLauncher ) ,
SAVE_DATA ( s_IconLgGrenade ) ,
SAVE_DATA ( s_IconLgMine ) ,
SAVE_DATA ( s_IconGuardHead ) ,
SAVE_DATA ( s_IconFireballLgAmmo ) ,
SAVE_DATA ( s_IconHeart ) ,
SAVE_DATA ( s_IconHeartLgAmmo ) ,
SAVE_DATA ( s_IconMicroGun ) ,
SAVE_DATA ( s_IconMicroBattery ) ,
SAVE_DATA ( s_IconRailGun ) ,
SAVE_DATA ( s_IconRailAmmo ) ,
SAVE_DATA ( s_IconElectro ) ,
SAVE_DATA ( s_IconSpell ) ,
SAVE_DATA ( s_IconArmor ) ,
SAVE_DATA ( s_IconMedkit ) ,
SAVE_DATA ( s_IconChemBomb ) ,
SAVE_DATA ( s_IconFlashBomb ) ,
SAVE_DATA ( s_IconNuke ) ,
SAVE_DATA ( s_IconCaltrops ) ,
SAVE_DATA ( s_IconSmMedkit ) ,
SAVE_DATA ( s_IconBooster ) ,
SAVE_DATA ( s_IconHeatCard ) ,
//SAVE_DATA(s_IconEnvironSuit),
SAVE_DATA ( s_IconCloak ) ,
SAVE_DATA ( s_IconFly ) ,
SAVE_DATA ( s_IconNightVision ) ,
SAVE_DATA ( s_IconFlag ) ,
} ;
saveable_module saveable_sprite =
{
// code
saveable_sprite_code ,
SIZ ( saveable_sprite_code ) ,
// data
saveable_sprite_data ,
SIZ ( saveable_sprite_data )
} ;
2019-10-09 16:09:05 +00:00
END_SW_NS