2020-07-04 19:36:27 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 1996 , 2003 - 3 D Realms Entertainment
2020-07-04 19:50:16 +00:00
Copyright 2020 Christoph Oelckers
2020-07-04 19:36:27 +00:00
This file is part of Duke Nukem 3 D version 1.5 - Atomic Edition
Duke Nukem 3 D is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
Original Source : 1996 - Todd Replogle
Prepared for public release : 03 / 21 / 2003 - Charlie Wiederhold , 3 D Realms
Modifications for JonoF ' s port by Jonathon Fowler ( jf @ jonof . id . au )
*/
//-------------------------------------------------------------------------
# include "ns.h"
# include "duke3d.h"
# include "sbar.h"
# include "mapinfo.h"
# include "cheathandler.h"
2020-07-14 12:00:27 +00:00
# include "c_dispatch.h"
2020-08-29 15:49:15 +00:00
# include "gamestate.h"
2020-07-04 19:36:27 +00:00
BEGIN_DUKE_NS
bool cheatGod ( cheatseq_t * ) ;
bool cheatClip ( cheatseq_t * ) ;
bool cheatWeapons ( cheatseq_t * s ) ;
bool cheatStuff ( cheatseq_t * s ) ;
bool cheatKeys ( cheatseq_t * s ) ;
bool cheatInventory ( cheatseq_t * s ) ;
2020-07-07 18:27:21 +00:00
static void dowarp ( MapRecord * map )
2020-07-04 19:36:27 +00:00
{
2020-07-20 21:21:27 +00:00
ud . m_monsters_off = ud . monsters_off = 0 ;
2020-07-04 19:36:27 +00:00
2020-07-20 21:21:27 +00:00
ud . m_respawn_items = 0 ;
ud . m_respawn_inventory = 0 ;
2020-07-04 19:36:27 +00:00
2020-07-20 21:21:27 +00:00
ud . multimode = 1 ;
2020-07-04 19:36:27 +00:00
2020-07-20 21:21:27 +00:00
if ( ps [ myconnectindex ] . gm & MODE_GAME )
{
ready2send = 0 ;
donewgame ( map , ud . m_player_skill ) ;
ps [ myconnectindex ] . gm = MODE_RESTART ;
}
else startnewgame ( map , ud . m_player_skill ) ;
2020-07-04 19:36:27 +00:00
}
static int ccmd_levelwarp ( CCmdFuncPtr parm )
{
2020-07-20 21:21:27 +00:00
if ( parm - > numparms ! = 2 )
return CCMD_SHOWHELP ;
int e = atoi ( parm - > parms [ 0 ] ) ;
int m = atoi ( parm - > parms [ 1 ] ) ;
if ( e = = 0 | | m = = 0 )
{
Printf ( TEXTCOLOR_RED " Invalid level!: E%sL%s \n " , parm - > parms [ 0 ] , parm - > parms [ 1 ] ) ;
return CCMD_OK ;
}
auto map = FindMapByLevelNum ( levelnum ( e - 1 , m - 1 ) ) ;
if ( ! map )
{
Printf ( TEXTCOLOR_RED " Level not found!: E%sL%s \n " , parm - > parms [ 0 ] , parm - > parms [ 1 ] ) ;
return CCMD_OK ;
}
dowarp ( map ) ;
return CCMD_OK ;
2020-07-04 19:36:27 +00:00
}
static int ccmd_map ( CCmdFuncPtr parm )
{
2020-07-20 21:21:27 +00:00
if ( parm - > numparms ! = 1 )
{
return CCMD_SHOWHELP ;
}
FString mapname = parm - > parms [ 0 ] ;
2020-07-26 21:59:29 +00:00
FString mapfilename = mapname ;
DefaultExtension ( mapfilename , " .map " ) ;
2020-07-20 21:21:27 +00:00
2020-08-21 05:11:02 +00:00
if ( ! fileSystem . FileExists ( mapfilename ) )
2020-07-20 21:21:27 +00:00
{
Printf ( TEXTCOLOR_RED " map: file \" %s \" not found. \n " , mapname . GetChars ( ) ) ;
return CCMD_OK ;
}
2020-07-04 19:36:27 +00:00
// Check if the map is already defined.
2020-07-20 21:21:27 +00:00
auto map = FindMapByName ( mapname ) ;
if ( map = = nullptr )
{
// got a user map
if ( VOLUMEONE )
{
Printf ( TEXTCOLOR_RED " Cannot use user maps in shareware. \n " ) ;
return CCMD_OK ;
}
2020-07-26 21:59:29 +00:00
if ( mapfilename [ 0 ] ! = ' / ' ) mapfilename . Insert ( 0 , " / " ) ;
map = SetupUserMap ( mapfilename , ! isRR ( ) ? " dethtoll.mid " : nullptr ) ;
2020-07-20 21:21:27 +00:00
}
if ( numplayers > 1 )
{
return CCMD_OK ;
}
dowarp ( map ) ;
return CCMD_OK ;
2020-07-04 19:36:27 +00:00
}
static int ccmd_god ( CCmdFuncPtr )
{
2020-07-20 21:21:27 +00:00
if ( numplayers = = 1 & & ps [ myconnectindex ] . gm & MODE_GAME )
cheatGod ( nullptr ) ;
else
Printf ( " god: Not in a single-player game. \n " ) ;
2020-07-04 19:36:27 +00:00
2020-07-20 21:21:27 +00:00
return CCMD_OK ;
2020-07-04 19:36:27 +00:00
}
static int ccmd_noclip ( CCmdFuncPtr )
{
2020-07-20 21:21:27 +00:00
if ( numplayers = = 1 & & ps [ myconnectindex ] . gm & MODE_GAME )
{
cheatClip ( nullptr ) ;
}
else
{
Printf ( " noclip: Not in a single-player game. \n " ) ;
}
return CCMD_OK ;
2020-07-04 19:36:27 +00:00
}
2020-07-04 19:50:16 +00:00
static int ccmd_restartmap ( CCmdFuncPtr )
2020-07-04 19:36:27 +00:00
{
2020-07-20 21:21:27 +00:00
if ( ps [ myconnectindex ] . gm & MODE_GAME & & ud . multimode = = 1 )
ps [ myconnectindex ] . gm = MODE_RESTART ;
2020-07-04 19:36:27 +00:00
2020-07-20 21:21:27 +00:00
return CCMD_OK ;
2020-07-04 19:36:27 +00:00
}
2020-07-15 10:34:42 +00:00
int getlabelvalue ( const char * text ) ;
2020-07-04 19:36:27 +00:00
static int ccmd_spawn ( CCmdFuncPtr parm )
{
2020-07-20 21:21:27 +00:00
int x = 0 , y = 0 , z = 0 ;
unsigned int cstat = 0 , picnum = 0 ;
unsigned int pal = 0 ;
int ang = 0 ;
int set = 0 , idx ;
if ( numplayers > 1 | | ! ( ps [ myconnectindex ] . gm & MODE_GAME ) ) {
Printf ( " spawn: Can't spawn sprites in multiplayer games or demos \n " ) ;
return CCMD_OK ;
}
switch ( parm - > numparms ) {
case 7 : // x,y,z
x = atol ( parm - > parms [ 4 ] ) ;
y = atol ( parm - > parms [ 5 ] ) ;
z = atol ( parm - > parms [ 6 ] ) ;
set | = 8 ;
case 4 : // ang
ang = atol ( parm - > parms [ 3 ] ) & 2047 ; set | = 4 ;
case 3 : // cstat
cstat = ( unsigned short ) atol ( parm - > parms [ 2 ] ) ; set | = 2 ;
case 2 : // pal
pal = ( unsigned char ) atol ( parm - > parms [ 1 ] ) ; set | = 1 ;
case 1 : // tile number
if ( isdigit ( parm - > parms [ 0 ] [ 0 ] ) ) {
picnum = ( unsigned short ) atol ( parm - > parms [ 0 ] ) ;
}
else {
picnum = getlabelvalue ( parm - > parms [ 0 ] ) ;
if ( picnum < 0 ) {
Printf ( " spawn: Invalid tile label given \n " ) ;
return CCMD_OK ;
}
}
if ( picnum > = MAXTILES ) {
Printf ( " spawn: Invalid tile number \n " ) ;
return CCMD_OK ;
}
break ;
default :
return CCMD_SHOWHELP ;
}
idx = fi . spawn ( ps [ myconnectindex ] . i , ( short ) picnum ) ;
if ( set & 1 ) sprite [ idx ] . pal = ( char ) pal ;
if ( set & 2 ) sprite [ idx ] . cstat = ( short ) cstat ;
if ( set & 4 ) sprite [ idx ] . ang = ang ;
if ( set & 8 ) {
if ( setsprite ( idx , x , y , z ) < 0 ) {
Printf ( " spawn: Sprite can't be spawned into null space \n " ) ;
deletesprite ( idx ) ;
}
}
return CCMD_OK ;
2020-07-04 19:36:27 +00:00
}
2020-07-04 19:50:16 +00:00
// Strangely enough JFDuke does not have a 'give' CCMD, so this is based on the version in EDuke32.
2020-07-04 19:36:27 +00:00
static int ccmd_give ( CCmdFuncPtr parm )
{
2020-07-20 21:21:27 +00:00
if ( numplayers ! = 1 | | ( ps [ myconnectindex ] . gm & MODE_GAME ) = = 0 | |
ps [ myconnectindex ] . dead_flag ! = 0 )
{
Printf ( " give: Cannot give while dead or not in a single-player game. \n " ) ;
return CCMD_OK ;
}
if ( parm - > numparms ! = 1 ) return CCMD_SHOWHELP ;
cheatseq_t * cs = ( cheatseq_t * ) ( intptr_t ) 1 ;
if ( ! stricmp ( parm - > parms [ 0 ] , " all " ) )
{
cheatStuff ( cs ) ;
}
else if ( ! stricmp ( parm - > parms [ 0 ] , " health " ) )
{
sprite [ ps [ myconnectindex ] . i ] . extra = max_player_health < < 1 ;
}
else if ( ! stricmp ( parm - > parms [ 0 ] , " weapons " ) )
{
cheatWeapons ( cs ) ;
}
else if ( ! stricmp ( parm - > parms [ 0 ] , " ammo " ) )
{
int maxw = VOLUMEONE ? SHRINKER_WEAPON : MAX_WEAPONS ;
for ( int i = maxw ; i > = PISTOL_WEAPON ; i - - )
addammo ( i , & ps [ myconnectindex ] , max_ammo_amount [ i ] ) ;
}
else if ( ! stricmp ( parm - > parms [ 0 ] , " armor " ) )
{
ps [ myconnectindex ] . shield_amount = 100 ;
}
else if ( ! stricmp ( parm - > parms [ 0 ] , " keys " ) )
{
cheatKeys ( cs ) ;
}
else if ( ! stricmp ( parm - > parms [ 0 ] , " inventory " ) )
{
cheatInventory ( cs ) ;
}
else return CCMD_SHOWHELP ;
return CCMD_OK ;
2020-07-04 19:36:27 +00:00
}
2020-08-04 08:03:47 +00:00
static int osdcmd_warptocoords ( CCmdFuncPtr parm )
{
2020-08-04 12:33:17 +00:00
if ( parm - > numparms < 3 | | parm - > numparms > 5 )
2020-08-04 08:03:47 +00:00
return CCMD_SHOWHELP ;
player_struct * p = & ps [ myconnectindex ] ;
2020-08-04 12:33:17 +00:00
p - > oposx = p - > posx = atoi ( parm - > parms [ 0 ] ) ;
p - > oposy = p - > posy = atoi ( parm - > parms [ 1 ] ) ;
p - > oposz = p - > posz = atoi ( parm - > parms [ 2 ] ) ;
2020-08-04 13:13:22 +00:00
if ( parm - > numparms > = 4 )
2020-08-04 12:33:17 +00:00
{
p - > oq16ang = p - > q16ang = fix16_from_int ( atoi ( parm - > parms [ 3 ] ) ) ;
}
if ( parm - > numparms = = 5 )
{
p - > oq16horiz = p - > q16horiz = fix16_from_int ( atoi ( parm - > parms [ 4 ] ) ) ;
}
2020-08-04 08:03:47 +00:00
return CCMD_OK ;
}
2020-08-29 15:49:15 +00:00
static int osdcmd_third_person_view ( CCmdFuncPtr parm )
{
if ( gamestate ! = GS_LEVEL | | System_WantGuiCapture ( ) ) return CCMD_OK ;
if ( ! isRRRA ( ) | | ( ! ps [ myconnectindex ] . OnMotorcycle & & ! ps [ myconnectindex ] . OnBoat ) )
{
if ( ps [ myconnectindex ] . over_shoulder_on )
ps [ myconnectindex ] . over_shoulder_on = 0 ;
else
{
ps [ myconnectindex ] . over_shoulder_on = 1 ;
cameradist = 0 ;
cameraclock = gameclock ;
}
FTA ( QUOTE_VIEW_MODE_OFF + ps [ myconnectindex ] . over_shoulder_on , & ps [ myconnectindex ] ) ;
}
return CCMD_OK ;
}
static int osdcmd_coop_view ( CCmdFuncPtr parm )
{
if ( gamestate ! = GS_LEVEL | | System_WantGuiCapture ( ) ) return CCMD_OK ;
if ( ud . coop | | ud . recstat = = 2 )
{
screenpeek = connectpoint2 [ screenpeek ] ;
if ( screenpeek = = - 1 ) screenpeek = 0 ;
}
return CCMD_OK ;
}
static int osdcmd_show_weapon ( CCmdFuncPtr parm )
{
if ( gamestate ! = GS_LEVEL | | System_WantGuiCapture ( ) ) return CCMD_OK ;
if ( ud . multimode > 1 )
{
ud . showweapons = 1 - ud . showweapons ;
cl_showweapon = ud . showweapons ;
FTA ( QUOTE_WEAPON_MODE_OFF - ud . showweapons , & ps [ screenpeek ] ) ;
}
return CCMD_OK ;
}
2020-07-04 19:36:27 +00:00
int registerosdcommands ( void )
{
C_RegisterFunction ( " map " , " map <mapname>: warp to the given map, identified by its name " , ccmd_map ) ;
2020-07-20 21:21:27 +00:00
C_RegisterFunction ( " levelwarp " , " levelwarp <e> <m>: warp to episode 'e' and map 'm' " , ccmd_levelwarp ) ;
C_RegisterFunction ( " give " , " give <all|health|weapons|ammo|armor|keys|inventory>: gives requested item " , ccmd_give ) ;
C_RegisterFunction ( " god " , " god: toggles god mode " , ccmd_god ) ;
C_RegisterFunction ( " noclip " , " noclip: toggles clipping mode " , ccmd_noclip ) ;
C_RegisterFunction ( " restartmap " , " restartmap: restarts the current map " , ccmd_restartmap ) ;
C_RegisterFunction ( " spawn " , " spawn <picnum> [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties " , ccmd_spawn ) ;
2020-08-04 12:33:17 +00:00
C_RegisterFunction ( " warptocoords " , " warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates " , osdcmd_warptocoords ) ;
2020-08-29 15:49:15 +00:00
C_RegisterFunction ( " third_person_view " , " Switch to third person view " , osdcmd_third_person_view ) ;
C_RegisterFunction ( " coop_view " , " Switch player to view from in coop " , osdcmd_coop_view ) ;
C_RegisterFunction ( " show_weapon " , " Show opponents' weapons " , osdcmd_show_weapon ) ;
2020-08-04 08:03:47 +00:00
2020-07-20 21:21:27 +00:00
return 0 ;
2020-07-04 19:36:27 +00:00
}
END_DUKE_NS