diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d37514f2..0771f712c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,20 +117,21 @@ set(SRB2_SDL2_EXE_NAME ringracers CACHE STRING "Executable binary output name") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) -add_subdirectory(src) -if(NOT ${SRB2_CONFIG_DEV_BUILD}) - add_subdirectory(assets) -endif() - ## config.h generation set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary") include(GitUtilities) git_latest_commit(SRB2_COMP_COMMIT "${CMAKE_SOURCE_DIR}") git_current_branch(SRB2_GIT_BRANCH "${CMAKE_SOURCE_DIR}") +git_working_tree_dirty(SRB2_COMP_UNCOMMITTED "${CMAKE_SOURCE_DIR}") set(SRB2_COMP_BRANCH "${SRB2_GIT_BRANCH}") set(SRB2_COMP_REVISION "${SRB2_COMP_COMMIT}") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h) +add_subdirectory(src) +if(NOT ${SRB2_CONFIG_DEV_BUILD}) + add_subdirectory(assets) +endif() + ##### PACKAGE CONFIGURATION ##### set(SRB2_CPACK_GENERATOR "" CACHE STRING "Generator to use for making a package. E.g., ZIP, TGZ, DragNDrop (OSX only). Leave blank for default generator.") diff --git a/cmake/Modules/GitUtilities.cmake b/cmake/Modules/GitUtilities.cmake index d29e6b509..4a94b5b5c 100644 --- a/cmake/Modules/GitUtilities.cmake +++ b/cmake/Modules/GitUtilities.cmake @@ -40,4 +40,20 @@ function(git_latest_commit variable path) ) set(${variable} "${output}" PARENT_SCOPE) +endfunction() + +function(git_working_tree_dirty variable path) + execute_process(COMMAND ${GIT_EXECUTABLE} "status" "--porcelain" "-uno" + WORKING_DIRECTORY "${path}" + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if(output STREQUAL "") + set(${variable} FALSE PARENT_SCOPE) + else() + set(${variable} TRUE PARENT_SCOPE) + endif() endfunction() \ No newline at end of file diff --git a/extras/conf/D3R-Config.cfg b/extras/conf/D3R-Config.cfg index 0482dc439..dac4b0135 100644 --- a/extras/conf/D3R-Config.cfg +++ b/extras/conf/D3R-Config.cfg @@ -139,7 +139,7 @@ skins // Gametypes gametypes { - -1 = "Single Player"; + -1 = "Grand Prix"; 0 = "Race"; 1 = "Battle"; } @@ -5113,6 +5113,7 @@ thingtypes height = 92; } } + waypoints { color = 4; // Red @@ -5161,6 +5162,80 @@ thingtypes fixedrotation = 1; } } + + duel + { + color = 4; // Red + arrow = 0; + title = "Duel Objects"; + sprite = "SPBMA2A8"; + flags1text = "[1] Spawn in all modes"; + + 2050 + { + title = "Duel Bomb"; + width = 24; + height = 48; + arrow = 1; + flags8text = "[8] Flip strafe"; + } + + 2051 + { + title = "Banana"; + sprite = "BANAA2A8"; + width = 16; + height = 32; + } + + 2052 + { + title = "Eggman Item"; + sprite = "FITMA0"; + width = 24; + height = 32; + } + + 2053 + { + title = "Proximity Mine"; + sprite = "SSMNA0"; + width = 16; + height = 24; + } + + 2054 + { + title = "Land Mine"; + sprite = "LNDMALAR"; + width = 24; + height = 32; + } + + 2055 + { + title = "Hyudoro"; + sprite = "HYUUA2A8"; + width = 32; + height = 24; + } + + 2056 + { + title = "Drop Target"; + sprite = "DTRGALAR"; + width = 45; + height = 32; + } + + 2057 + { + title = "Pogo Spring"; + sprite = "POGSA0"; + width = 48; + height = 32; + } + } } //Default things filters @@ -5183,24 +5258,6 @@ thingsfilters } filter2 - { - name = "Enemies"; - category = "enemies"; - type = -1; - - } - - - filter3 - { - name = "NiGHTS Track"; - category = "nightstrk"; - type = -1; - - } - - - filter4 { name = "Normal Gravity"; category = ""; @@ -5213,8 +5270,7 @@ thingsfilters } - - filter5 + filter3 { name = "Reverse Gravity"; category = ""; @@ -5226,11 +5282,4 @@ thingsfilters } } - - filter6 - { - name = "Boss Waypoints"; - category = ""; - type = 292; - } } diff --git a/src/comptime.c b/src/comptime.c index 81b5ec7d6..2baef79d6 100644 --- a/src/comptime.c +++ b/src/comptime.c @@ -15,6 +15,12 @@ const char *comprevision = SRB2_COMP_REVISION; #elif (defined(COMPVERSION)) #include "comptime.h" +#else +const char *compbranch = "Unknown"; +const char *comprevision = "illegal"; + +#endif + const int compuncommitted = #if (defined(COMPVERSION_UNCOMMITTED)) 1; @@ -22,11 +28,5 @@ const int compuncommitted = 0; #endif -#else -const char *compbranch = "Unknown"; -const char *comprevision = "illegal"; - -#endif - const char *compdate = __DATE__; const char *comptime = __TIME__; diff --git a/src/config.h.in b/src/config.h.in index 1636a6731..c27628ffd 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -22,6 +22,12 @@ #define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}" #define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}" +// This is done with configure_file instead of defines in order to avoid +// recompiling the whole target whenever the working directory state changes +#cmakedefine SRB2_COMP_UNCOMMITTED +#ifdef SRB2_COMP_UNCOMMITTED +#define COMPVERSION_UNCOMMITTED +#endif #define CMAKE_ASSETS_DIR "${CMAKE_SOURCE_DIR}/assets" diff --git a/src/d_main.c b/src/d_main.c index 5d83c783b..f0f016ca7 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -875,7 +875,8 @@ void D_SRB2Loop(void) // consoleplayer -> displayplayers (hear sounds from viewpoint) S_UpdateSounds(); // move positional sounds - S_UpdateClosedCaptions(); + if (realtics > 0 || singletics) + S_UpdateClosedCaptions(); #ifdef HW3SOUND HW3S_EndFrameUpdate(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3473432e5..1d7a2db4f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -83,7 +83,6 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum); static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum); static void Got_PickVotecmd(UINT8 **cp, INT32 playernum); -static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); static void Got_Addfilecmd(UINT8 **cp, INT32 playernum); static void Got_Pause(UINT8 **cp, INT32 playernum); @@ -445,10 +444,10 @@ consvar_t cv_kartdebughuddrop = CVAR_INIT ("debugitemdrop", "Off", CV_NETVAR|CV_ static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}}; consvar_t cv_kartdebugwaypoints = CVAR_INIT ("debugwaypoints", "Off", CV_NETVAR|CV_CHEAT, kartdebugwaypoint_cons_t, NULL); consvar_t cv_kartdebugbotpredict = CVAR_INIT ("debugbotpredict", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); - consvar_t cv_kartdebugnodes = CVAR_INIT ("debugnodes", "Off", CV_CHEAT, CV_OnOff, NULL); consvar_t cv_kartdebugcolorize = CVAR_INIT ("debugcolorize", "Off", CV_CHEAT, CV_OnOff, NULL); consvar_t cv_kartdebugdirector = CVAR_INIT ("debugdirector", "Off", CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_spbtest = CVAR_INIT ("spbtest", "Off", CV_CHEAT|CV_NETVAR, CV_OnOff, NULL); static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL); @@ -613,14 +612,13 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "ACCEPTPARTYINVITE", // XD_ACCEPTPARTYINVITE "LEAVEPARTY", // XD_LEAVEPARTY "CANCELPARTYINVITE", // XD_CANCELPARTYINVITE - "GIVEITEM", // XD_GIVEITEM + "CHEAT", // XD_CHEAT "ADDBOT", // XD_ADDBOT "DISCORD", // XD_DISCORD "PLAYSOUND", // XD_PLAYSOUND "SCHEDULETASK", // XD_SCHEDULETASK "SCHEDULECLEAR", // XD_SCHEDULECLEAR "AUTOMATE", // XD_AUTOMATE - "CHEAT", // XD_CHEAT }; // ========================================================================= @@ -667,8 +665,6 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_MODIFYVOTE, Got_ModifyVotecmd); RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd); - RegisterNetXCmd(XD_GIVEITEM, Got_GiveItemcmd); - RegisterNetXCmd(XD_SCHEDULETASK, Got_ScheduleTaskcmd); RegisterNetXCmd(XD_SCHEDULECLEAR, Got_ScheduleClearcmd); RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd); @@ -729,7 +725,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("downloads", Command_Downloads_f); - COM_AddCommand("kartgiveitem", Command_KartGiveItem_f); + COM_AddCommand("give", Command_KartGiveItem_f); COM_AddCommand("schedule_add", Command_Schedule_Add); COM_AddCommand("schedule_clear", Command_Schedule_Clear); @@ -2062,6 +2058,11 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...) case CHEAT_DEVMODE: COPY(WRITEUINT32, UINT32); break; + + case CHEAT_GIVEITEM: + COPY(WRITESINT8, int); + COPY(WRITEUINT8, unsigned int); + break; } #undef COPY @@ -5382,41 +5383,6 @@ static void Got_PickVotecmd(UINT8 **cp, INT32 playernum) Y_SetupVoteFinish(pick, level); } -static void Got_GiveItemcmd(UINT8 **cp, INT32 playernum) -{ - int item; - int amt; - - item = READSINT8 (*cp); - amt = READUINT8 (*cp); - - if ( - ( !CV_CheatsEnabled() ) || - ( item < KITEM_SAD || item >= NUMKARTITEMS ) - ) - { - CONS_Alert(CONS_WARNING, - M_GetText ("Illegal give item received from %s\n"), - player_names[playernum]); - if (server) - SendKick(playernum, KICK_MSG_CON_FAIL); - return; - } - - K_StripItems(&players[playernum]); - players[playernum].itemroulette = 0; - - players[playernum].itemtype = item; - players[playernum].itemamount = amt; - - CV_CheaterWarning( - playernum, - (amt != 1) // FIXME: we should have actual KITEM_ name array - ? va("kartgiveitem %s %d", cv_kartdebugitem.PossibleValue[item+1].strvalue, amt) - : va("kartgiveitem %s", cv_kartdebugitem.PossibleValue[item+1].strvalue) - ); -} - static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum) { char command[MAXTEXTCMD]; @@ -5676,6 +5642,35 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) break; } + case CHEAT_GIVEITEM: { + SINT8 item = READSINT8(*cp); + UINT8 amt = READUINT8(*cp); + + item = max(item, KITEM_SAD); + item = min(item, NUMKARTITEMS - 1); + + K_StripItems(player); + + // Cancel roulette if rolling + player->itemroulette = 0; + + player->itemtype = item; + player->itemamount = amt; + + if (amt == 0) + { + CV_CheaterWarning(playernum, "delete my items"); + } + else + { + // FIXME: we should have actual KITEM_ name array + const char *itemname = cv_kartdebugitem.PossibleValue[1 + item].strvalue; + + CV_CheaterWarning(playernum, va("give item %s x%d", itemname, amt)); + } + break; + } + case NUMBER_OF_CHEATS: break; } @@ -5837,11 +5832,9 @@ static void Command_Archivetest_f(void) */ static void Command_KartGiveItem_f(void) { - char buf[2]; - int ac; const char *name; - int item; + INT32 item; const char * str; @@ -5853,7 +5846,7 @@ static void Command_KartGiveItem_f(void) if (ac < 2) { CONS_Printf( -"kartgiveitem [amount]: Give yourself an item\n" +"give [amount]: Give yourself an item\n" ); } else @@ -5868,26 +5861,33 @@ static void Command_KartGiveItem_f(void) } else { - for (i = 0; ( str = kartdebugitem_cons_t[i].strvalue ); ++i) + /* first check exact match */ + if (!CV_CompleteValue(&cv_kartdebugitem, &name, &item)) { - if (strcasecmp(name, str) == 0) + CONS_Printf("\x83" "Autocomplete:\n"); + + /* then do very loose partial matching */ + for (i = 0; ( str = kartdebugitem_cons_t[i].strvalue ); ++i) { - item = kartdebugitem_cons_t[i].value; - break; + if (strcasestr(str, name) != NULL) + { + CONS_Printf("\x83\t%s\n", str); + item = kartdebugitem_cons_t[i].value; + } } } } if (item < NUMKARTITEMS) { - buf[0] = item; + INT32 amt; if (ac > 2) - buf[1] = atoi(COM_Argv(2)); + amt = atoi(COM_Argv(2)); else - buf[1] = 1;/* default to one quantity */ + amt = (item != KITEM_NONE);/* default to one quantity, or zero, if KITEM_NONE */ - SendNetXCmd(XD_GIVEITEM, buf, 2); + D_Cheat(consoleplayer, CHEAT_GIVEITEM, item, amt); } else { diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7fb6c4c53..0355722d6 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -120,7 +120,7 @@ extern consvar_t cv_kartusepwrlv; extern consvar_t cv_votetime; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop; -extern consvar_t cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector; +extern consvar_t cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector, cv_spbtest; extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict; extern consvar_t cv_itemfinder; @@ -193,14 +193,13 @@ typedef enum XD_ACCEPTPARTYINVITE, // 29 XD_LEAVEPARTY, // 30 XD_CANCELPARTYINVITE, // 31 - XD_GIVEITEM, // 32 + XD_CHEAT, // 32 XD_ADDBOT, // 33 XD_DISCORD, // 34 XD_PLAYSOUND, // 35 XD_SCHEDULETASK, // 36 XD_SCHEDULECLEAR, // 37 XD_AUTOMATE, // 38 - XD_CHEAT, // 39 MAXNETXCMD } netxcmd_t; diff --git a/src/deh_tables.c b/src/deh_tables.c index eda614fb6..2025d4f03 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5372,6 +5372,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SINK_SHIELD", "MT_SINKTRAIL", + "MT_DUELBOMB", // Duel mode bombs + "MT_BATTLEBUMPER", // Battle Mode bumper "MT_BATTLEBUMPER_DEBRIS", "MT_BATTLEBUMPER_BLAST", diff --git a/src/doomstat.h b/src/doomstat.h index 216a76038..f7c7f08ff 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -668,6 +668,7 @@ extern boolean thwompsactive; extern UINT8 lastLowestLap; extern SINT8 spbplace; extern boolean rainbowstartavailable; +extern boolean inDuel; extern tic_t bombflashtimer; // Used to avoid causing seizures if multiple mines explode close to you :) extern boolean legitimateexit; diff --git a/src/g_game.c b/src/g_game.c index e4be3962e..0363373f4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -311,6 +311,7 @@ boolean thwompsactive; // Thwomps activate on lap 2 UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors SINT8 spbplace; // SPB exists, give the person behind better items boolean rainbowstartavailable; // Boolean, keeps track of if the rainbow start was gotten +boolean inDuel; // Boolean, keeps track of if it is a 1v1 // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) tic_t bombflashtimer = 0; // Cooldown before another FlashPal can be intialized by a bomb exploding near a displayplayer. Avoids seizures. diff --git a/src/info.c b/src/info.c index 42abd5b2e..ee71d9972 100644 --- a/src/info.c +++ b/src/info.c @@ -8315,7 +8315,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_POGOSPRING - -1, // doomednum + 2057, // doomednum S_POGOSPRING1, // spawnstate 1000, // spawnhealth S_POGOSPRING2B, // seestate @@ -23317,7 +23317,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_EGGMANITEM - -1, // doomednum + 2052, // doomednum S_EGGMANITEM1, // spawnstate 2, // spawnhealth S_NULL, // seestate @@ -23371,7 +23371,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BANANA - -1, // doomednum + 2051, // doomednum S_BANANA, // spawnstate 2, // spawnhealth S_NULL, // seestate @@ -23560,7 +23560,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SSMINE - -1, // doomednum + 2053, // doomednum S_SSMINE_AIR1, // spawnstate 1, // spawnhealth S_NULL, // seestate @@ -23695,7 +23695,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_LANDMINE - -1, // doomednum + 2054, // doomednum S_LANDMINE, // spawnstate 2, // spawnhealth S_NULL, // seestate @@ -23722,7 +23722,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_DROPTARGET - -1, // doomednum + 2056, // doomednum S_DROPTARGET, // spawnstate 3, // spawnhealth S_NULL, // seestate @@ -24154,7 +24154,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_HYUDORO_CENTER - -1, // doomednum + 2055, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -24423,6 +24423,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_DUELBOMB + 2050, // doomednum + S_SPB1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 64*FRACUNIT, // speed + 24*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags + S_NULL // raisestate + }, + { // MT_BATTLEBUMPER -1, // doomednum S_BATTLEBUMPER1,// spawnstate diff --git a/src/info.h b/src/info.h index 48850f5d0..975122946 100644 --- a/src/info.h +++ b/src/info.h @@ -6418,6 +6418,8 @@ typedef enum mobj_type MT_SINK_SHIELD, MT_SINKTRAIL, + MT_DUELBOMB, // Duel mode bombs + MT_BATTLEBUMPER, // Battle Mode bumpers MT_BATTLEBUMPER_DEBRIS, MT_BATTLEBUMPER_BLAST, diff --git a/src/k_battle.c b/src/k_battle.c index cc0f7b711..c918daec7 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -267,7 +267,7 @@ mobj_t *K_SpawnSphereBox(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 f { mobj_t *drop = P_SpawnMobj(x, y, z, MT_SPHEREBOX); - P_InitAngle(drop, angle); + drop->angle = angle; P_Thrust(drop, FixedAngle(P_RandomFixed(PR_ITEM_ROULETTE) * 180) + angle, P_RandomRange(PR_ITEM_ROULETTE, 4, 12) * mapobjectscale); @@ -605,7 +605,7 @@ static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale) mo->eflags |= MFE_VERTICALFLIP; } - P_InitAngle(mo, R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90); + mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; mo->renderflags |= (RF_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player))); P_SetScale(mo, scale); diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 5b6f1ccca..48c5745fd 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -422,6 +422,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing) case MT_BALLHOG: case MT_SPB: case MT_BUBBLESHIELDTRAP: + case MT_DUELBOMB: K_AddDodgeObject(thing, side, 20); break; case MT_SHRINK_GUN: diff --git a/src/k_collide.c b/src/k_collide.c index 978993339..b03cdfdec 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -479,7 +479,7 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2) if (t2deflect < ANG10) P_InstaThrust(t2, t2angle, t2speed); - P_InitAngle(t1, R_PointToAngle2(0, 0, t1->momx, t1->momy)); + t1->angle = t1->old_angle = R_PointToAngle2(0, 0, t1->momx, t1->momy); t1->reactiontime = 7*(t1speed+t2speed)/FRACUNIT; if (t1->reactiontime < 10) @@ -526,7 +526,6 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2) { blast->angle += ANGLE_90; } - P_InitAngle(blast, blast->angle); blast->destscale *= 10; } diff --git a/src/k_follower.c b/src/k_follower.c index 17be8c749..63ebda167 100644 --- a/src/k_follower.c +++ b/src/k_follower.c @@ -330,7 +330,7 @@ void K_HandleFollower(player_t *player) K_UpdateFollowerState(player->follower, fl.idlestate, FOLLOWERSTATE_IDLE); P_SetTarget(&player->follower->target, player->mo); // we need that to know when we need to disappear - P_InitAngle(player->follower, player->mo->angle); + player->follower->angle = player->follower->old_angle = player->mo->angle; // This is safe to only spawn it here, the follower is removed then respawned when switched. if (bubble) diff --git a/src/k_kart.c b/src/k_kart.c index 7978c97fc..4b1480eb9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -49,10 +49,53 @@ // battlewanted is an array of the WANTED player nums, -1 for no player in that slot // mapreset is set when enough players fill an empty server +boolean K_IsDuelItem(mobjtype_t type) +{ + switch (type) + { + case MT_DUELBOMB: + case MT_BANANA: + case MT_EGGMANITEM: + case MT_SSMINE: + case MT_LANDMINE: + case MT_HYUDORO_CENTER: + case MT_DROPTARGET: + case MT_POGOSPRING: + return true; + + default: + return false; + } +} + +boolean K_DuelItemAlwaysSpawns(mapthing_t *mt) +{ + return (mt->options & MTF_EXTRA); +} + +static void K_SpawnDuelOnlyItems(void) +{ + mapthing_t *mt = NULL; + size_t i; + + mt = mapthings; + for (i = 0; i < nummapthings; i++, mt++) + { + mobjtype_t type = P_GetMobjtype(mt->type); + + if (K_IsDuelItem(type) == true + && K_DuelItemAlwaysSpawns(mt) == false) + { + P_SpawnMapThing(mt); + } + } +} + void K_TimerReset(void) { starttime = introtime = 3; numbulbs = 1; + inDuel = false; } void K_TimerInit(void) @@ -78,6 +121,9 @@ void K_TimerInit(void) numPlayers++; } + // 1v1 activates DUEL rules! + inDuel = (numPlayers == 2); + if (numPlayers >= 2) { rainbowstartavailable = true; @@ -106,6 +152,12 @@ void K_TimerInit(void) // NOW you can try to spawn in the Battle capsules, if there's not enough players for a match K_BattleInit(); + + if (inDuel == true) + { + K_SpawnDuelOnlyItems(); + } + //CONS_Printf("numbulbs set to %d (%d players, %d spectators) on tic %d\n", numbulbs, numPlayers, numspec, leveltime); } @@ -263,6 +315,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdebugnodes); CV_RegisterVar(&cv_kartdebugcolorize); CV_RegisterVar(&cv_kartdebugdirector); + CV_RegisterVar(&cv_spbtest); } //} @@ -1433,6 +1486,7 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) break; case MT_ORBINAUT: case MT_ORBINAUT_SHIELD: + case MT_DUELBOMB: if (against->player) weight = K_PlayerWeight(against, NULL); break; @@ -2272,7 +2326,7 @@ void K_SpawnDashDustRelease(player_t *player) dust = P_SpawnMobj(newx, newy, player->mo->z, MT_FASTDUST); P_SetTarget(&dust->target, player->mo); - P_InitAngle(dust, travelangle - ((i&1) ? -1 : 1) * ANGLE_45); + dust->angle = travelangle - (((i&1) ? -1 : 1) * ANGLE_45); dust->destscale = player->mo->scale; P_SetScale(dust, player->mo->scale); @@ -2444,7 +2498,7 @@ static void K_SpawnGenericSpeedLines(player_t *player, boolean top) if (top) { - P_InitAngle(fast, player->mo->angle); + fast->angle = player->mo->angle; P_SetScale(fast, (fast->destscale = 3 * fast->destscale / 2)); @@ -2452,7 +2506,7 @@ static void K_SpawnGenericSpeedLines(player_t *player, boolean top) } else { - P_InitAngle(fast, K_MomentumAngle(player->mo)); + fast->angle = K_MomentumAngle(player->mo); if (player->tripwireLeniency) { @@ -2517,7 +2571,7 @@ void K_SpawnInvincibilitySpeedLines(mobj_t *mo) P_SetMobjState(fast, S_KARTINVLINES1); P_SetTarget(&fast->target, mo); - P_InitAngle(fast, K_MomentumAngle(mo)); + fast->angle = K_MomentumAngle(mo); fast->momx = 3*mo->momx/4; fast->momy = 3*mo->momy/4; @@ -3515,7 +3569,7 @@ void K_SpawnWaterRunParticles(mobj_t *mobj) // underlay water = P_SpawnMobj(x1, y1, ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY); - P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h); + water->angle = forwardangle - ANGLE_180 - ANGLE_22h; water->destscale = trailScale; water->momx = mobj->momx; water->momy = mobj->momy; @@ -3526,7 +3580,7 @@ void K_SpawnWaterRunParticles(mobj_t *mobj) // overlay water = P_SpawnMobj(x1, y1, ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL); - P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h); + water->angle = forwardangle - ANGLE_180 - ANGLE_22h; water->destscale = trailScale; water->momx = mobj->momx; water->momy = mobj->momy; @@ -3538,7 +3592,7 @@ void K_SpawnWaterRunParticles(mobj_t *mobj) // Underlay water = P_SpawnMobj(x2, y2, ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY); - P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h); + water->angle = forwardangle - ANGLE_180 + ANGLE_22h; water->destscale = trailScale; water->momx = mobj->momx; water->momy = mobj->momy; @@ -3549,7 +3603,7 @@ void K_SpawnWaterRunParticles(mobj_t *mobj) // Overlay water = P_SpawnMobj(x2, y2, ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL); - P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h); + water->angle = forwardangle - ANGLE_180 + ANGLE_22h; water->destscale = trailScale; water->momx = mobj->momx; water->momy = mobj->momy; @@ -4885,7 +4939,7 @@ void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount) P_SetTarget(&newmo->tracer, victim->mo); P_SetTarget(&newmo->target, player->mo); - P_InitAngle(newmo, (diff * (newbumper-1))); + newmo->angle = (diff * (newbumper-1)); newmo->color = victim->skincolor; if (newbumper+1 < 2) @@ -4973,7 +5027,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) { dust = P_SpawnMobj(source->x, source->y, source->z, MT_SMOKE); P_SetMobjState(dust, S_OPAQUESMOKE1); - P_InitAngle(dust, (ANGLE_180/16) * i); + dust->angle = (ANGLE_180/16) * i; P_SetScale(dust, source->scale); dust->destscale = source->scale*10; dust->scalespeed = source->scale/12; @@ -5141,7 +5195,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I th->z = th->floorz; } - P_InitAngle(th, an); + th->angle = an; th->momx = FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); @@ -5302,7 +5356,7 @@ static void K_SpawnDriftElectricity(player_t *player) y = P_ReturnThrustY(mo, verticalangle, verticalradius) + P_ReturnThrustY(mo, horizonatalangle, horizontalradius); spark = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRIFTELECTRICITY); - P_InitAngle(spark, sparkangle); + spark->angle = sparkangle; spark->momx = mo->momx; spark->momy = mo->momy; spark->momz = mo->momz; @@ -5343,7 +5397,7 @@ void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave) fixed_t yoff = P_ReturnThrustY(mo, sparkangle, sparkradius); mobj_t *spark = P_SpawnMobjFromMobj(mo, x + xoff, y + yoff, z, MT_DRIFTELECTRICSPARK); - P_InitAngle(spark, sparkangle); + spark->angle = sparkangle; spark->color = color; P_InstaThrust(spark, mo->angle + ANGLE_90, hspeed); P_SetObjectMomZ(spark, vspeed, false); @@ -5399,7 +5453,7 @@ static void K_SpawnDriftSparks(player_t *player) spark = P_SpawnMobj(newx, newy, player->mo->z, MT_DRIFTSPARK); P_SetTarget(&spark->target, player->mo); - P_InitAngle(spark, travelangle-(ANGLE_45/5)*player->drift); + spark->angle = travelangle-((ANGLE_45/5)*player->drift); spark->destscale = player->mo->scale; P_SetScale(spark, player->mo->scale); @@ -5543,7 +5597,7 @@ static void K_SpawnAIZDust(player_t *player) newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle - (player->aizdriftstrat*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale)); spark = P_SpawnMobj(newx, newy, player->mo->z, MT_AIZDRIFTSTRAT); - P_InitAngle(spark, travelangle+(player->aizdriftstrat*ANGLE_90)); + spark->angle = travelangle+(player->aizdriftstrat*ANGLE_90); P_SetScale(spark, (spark->destscale = (3*player->mo->scale)>>2)); spark->momx = (6*player->mo->momx)/5; @@ -5595,7 +5649,7 @@ void K_SpawnBoostTrail(player_t *player) flame = P_SpawnMobj(newx, newy, ground, MT_SNEAKERTRAIL); P_SetTarget(&flame->target, player->mo); - P_InitAngle(flame, travelangle); + flame->angle = travelangle; flame->fuse = TICRATE*2; flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale); @@ -5642,7 +5696,7 @@ void K_SpawnSparkleTrail(mobj_t *mo) sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL); - P_InitAngle(sparkle, R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y)); + sparkle->angle = R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y); sparkle->movefactor = R_PointToDist2(mo->x, mo->y, sparkle->x, sparkle->y); // Save the distance we spawned away from the player. //CONS_Printf("movefactor: %d\n", sparkle->movefactor/FRACUNIT); @@ -5692,7 +5746,7 @@ void K_SpawnWipeoutTrail(mobj_t *mo) mo->z, MT_WIPEOUTTRAIL); P_SetTarget(&dust->target, mo); - P_InitAngle(dust, K_MomentumAngle(mo)); + dust->angle = K_MomentumAngle(mo); dust->destscale = mo->scale; P_SetScale(dust, mo->scale); K_FlipFromObject(dust, mo); @@ -5758,7 +5812,7 @@ void K_SpawnDraftDust(mobj_t *mo) P_SetMobjState(dust, S_DRAFTDUST1 + foff); P_SetTarget(&dust->target, mo); - P_InitAngle(dust, ang - (ANGLE_90 * sign)); // point completely perpendicular from the player + dust->angle = ang - (ANGLE_90 * sign); // point completely perpendicular from the player dust->destscale = mo->scale; P_SetScale(dust, mo->scale); K_FlipFromObject(dust, mo); @@ -6272,7 +6326,7 @@ static void K_DoLightningShield(player_t *player) for (i=0; i<7; i++) { mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK); - P_InitAngle(mo, P_RandomRange(PR_DECORATION, 0, 359)*ANG1); + mo->angle = P_RandomRange(PR_DECORATION, 0, 359)*ANG1; mo->fuse = P_RandomRange(PR_DECORATION, 20, 50); P_SetTarget(&mo->target, player->mo); P_SetMobjState(mo, S_KLIT1); @@ -6285,7 +6339,7 @@ static void K_DoLightningShield(player_t *player) sx = player->mo->x + FixedMul((player->mo->scale*THUNDERRADIUS), FINECOSINE((an*i)>>ANGLETOFINESHIFT)); sy = player->mo->y + FixedMul((player->mo->scale*THUNDERRADIUS), FINESINE((an*i)>>ANGLETOFINESHIFT)); mo = P_SpawnMobj(sx, sy, player->mo->z, MT_THOK); - P_InitAngle(mo, an*i); + mo->angle = an*i; mo->extravalue1 = THUNDERRADIUS; // Used to know whether we should teleport by radius or something. mo->scale = player->mo->scale*3; P_SetTarget(&mo->target, player->mo); @@ -6495,7 +6549,7 @@ static void K_ThrowLandMine(player_t *player) P_SetScale(landMine, player->mo->scale); landMine->destscale = player->mo->destscale; - P_InitAngle(landMine, player->mo->angle); + landMine->angle = player->mo->angle; landMine->momz = (30 * mapobjectscale * P_MobjFlip(player->mo)) + player->mo->momz; landMine->color = player->skincolor; @@ -6821,7 +6875,7 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 P_SetScale(drop, drop->scale>>4); drop->destscale = (3*drop->destscale)/2; - P_InitAngle(drop, angle); + drop->angle = angle; P_Thrust(drop, FixedAngle(P_RandomFixed(PR_ITEM_ROULETTE) * 180) + angle, 16*mapobjectscale); @@ -8316,7 +8370,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING); ring->extravalue1 = 1; // Ring collect animation timer - P_InitAngle(ring, player->mo->angle); // animation angle + ring->angle = player->mo->angle; // animation angle P_SetTarget(&ring->target, player->mo); // toucher for thinker player->pickuprings++; if (player->superring <= 3) @@ -9351,7 +9405,7 @@ void K_SpawnDriftBoostExplosion(player_t *player, int stage) { mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_DRIFTEXPLODE); - P_InitAngle(overlay, K_MomentumAngle(player->mo)); + overlay->angle = K_MomentumAngle(player->mo); P_SetTarget(&overlay->target, player->mo); P_SetScale(overlay, (overlay->destscale = player->mo->scale)); K_FlipFromObject(overlay, player->mo); @@ -10059,9 +10113,9 @@ static void K_KartSpindashWind(mobj_t *parent) P_SetTarget(&wind->target, parent); if (parent->momx || parent->momy) - P_InitAngle(wind, R_PointToAngle2(0, 0, parent->momx, parent->momy)); + wind->angle = R_PointToAngle2(0, 0, parent->momx, parent->momy); else - P_InitAngle(wind, parent->player->drawangle); + wind->angle = parent->player->drawangle; wind->momx = 3 * parent->momx / 4; wind->momy = 3 * parent->momy / 4; @@ -10111,7 +10165,7 @@ static void K_KartSpindash(player_t *player) mobj_t *grease; grease = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_TIREGREASE); P_SetTarget(&grease->target, player->mo); - P_InitAngle(grease, K_MomentumAngle(player->mo)); + grease->angle = K_MomentumAngle(player->mo); grease->extravalue1 = i; } } @@ -10595,7 +10649,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ROCKETSNEAKER); K_MatchGenericExtraFlags(mo, player->mo); mo->flags |= MF_NOCLIPTHING; - P_InitAngle(mo, player->mo->angle); + mo->angle = player->mo->angle; mo->threshold = 10; mo->movecount = moloop%2; mo->movedir = mo->lastlook = moloop+1; @@ -10695,7 +10749,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) break; } mo->flags |= MF_NOCLIPTHING; - P_InitAngle(mo, newangle); + mo->angle = newangle; mo->threshold = 10; mo->movecount = player->itemamount; mo->movedir = mo->lastlook = moloop+1; @@ -10737,7 +10791,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) break; } mo->flags |= MF_NOCLIPTHING; - P_InitAngle(mo, newangle); + mo->angle = newangle; mo->threshold = 10; mo->movecount = player->itemamount; mo->movedir = mo->lastlook = moloop+1; @@ -11273,7 +11327,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) spdl = P_SpawnMobj(sx, sy, sz, MT_FASTLINE); P_SetTarget(&spdl->target, player->mo); - P_InitAngle(spdl, R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y)); + spdl->angle = R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y); spdl->rollangle = -ANG1*90*P_MobjFlip(player->mo); // angle them downwards relative to the player's gravity... spdl->spriteyscale = player->trickboostpower+FRACUNIT; spdl->momx = player->mo->momx; diff --git a/src/k_kart.h b/src/k_kart.h index 7973a236c..a5d2b0185 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -38,6 +38,9 @@ angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t void K_RegisterKartStuff(void); +boolean K_IsDuelItem(mobjtype_t type); +boolean K_DuelItemAlwaysSpawns(mapthing_t *mt); + void K_TimerReset(void); void K_TimerInit(void); UINT32 K_GetPlayerDontDrawFlag(player_t *player); diff --git a/src/k_objects.h b/src/k_objects.h index b5b58b800..96e0fa2b5 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -3,6 +3,7 @@ #define k_objects_H /* Hyudoro */ +void Obj_InitHyudoroCenter(mobj_t *center, mobj_t *master); void Obj_HyudoroDeploy(mobj_t *master); void Obj_HyudoroThink(mobj_t *actor); void Obj_HyudoroCenterThink(mobj_t *actor); @@ -47,4 +48,10 @@ void Obj_OrbinautJawzMoveHeld(player_t *player); void Obj_JawzThink(mobj_t *th); void Obj_JawzThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir); +/* Duel Bomb */ +void Obj_DuelBombThink(mobj_t *bomb); +void Obj_DuelBombReverse(mobj_t *bomb); +void Obj_DuelBombTouch(mobj_t *bomb, mobj_t *toucher); +void Obj_DuelBombInit(mobj_t *bomb); + #endif/*k_objects_H*/ diff --git a/src/k_race.c b/src/k_race.c index fde4c9be2..1354b9d56 100644 --- a/src/k_race.c +++ b/src/k_race.c @@ -370,7 +370,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t * P_SetMobjState(end1, S_FINISHBEAMEND1); end1->renderflags = RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); - P_InitAngle(end1, lineangle); + end1->angle = lineangle; end2 = P_SpawnMobj( v->x + (8*sx), @@ -381,7 +381,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t * P_SetMobjState(end2, S_FINISHBEAMEND2); end2->renderflags = RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); - P_InitAngle(end2, lineangle); + end2->angle = lineangle; P_SetTarget(&end2->tracer, end1); end2->flags2 |= MF2_LINKDRAW; diff --git a/src/k_respawn.c b/src/k_respawn.c index 227cf221f..0b4c02ccf 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -582,7 +582,7 @@ static void K_MovePlayerToRespawnPoint(player_t *player) P_SetTarget(&lasermo->target, player->mo); - P_InitAngle(lasermo, stepha + ANGLE_90); + lasermo->angle = stepha + ANGLE_90; P_SetScale(lasermo, (lasermo->destscale = player->mo->scale)); } } @@ -645,7 +645,7 @@ static void K_DropDashWait(player_t *player) P_SetTarget(&laser->target, player->mo); - P_InitAngle(laser, newangle + ANGLE_90); + laser->angle = newangle + ANGLE_90; laser->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo); P_SetScale(laser, (laser->destscale = player->mo->scale)); } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7a72b31dc..045ff3020 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1483,6 +1483,46 @@ static int lib_pMoveOrigin(lua_State *L) return 2; } +static int lib_pSetAngle(lua_State *L) +{ + mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + angle_t newValue = luaL_checkangle(L, 2); + NOHUD + INLEVEL + + if (!thing) + return LUA_ErrInvalid(L, "mobj_t"); + //P_SetAngle(thing, newValue); + thing->angle = thing->old_angle = newValue; + return 0; +} + +static int lib_pSetPitch(lua_State *L) +{ + mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + angle_t newValue = luaL_checkangle(L, 2); + NOHUD + INLEVEL + if (!thing) + return LUA_ErrInvalid(L, "mobj_t"); + //P_SetPitch(thing, newValue); + thing->pitch = thing->old_pitch = newValue; + return 0; +} + +static int lib_pSetRoll(lua_State *L) +{ + mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + angle_t newValue = luaL_checkangle(L, 2); + NOHUD + INLEVEL + if (!thing) + return LUA_ErrInvalid(L, "mobj_t"); + //P_SetRoll(thing, newValue); + thing->roll = thing->old_roll = newValue; + return 0; +} + static int lib_pSlideMove(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -3914,6 +3954,9 @@ static luaL_Reg lib[] = { {"P_TeleportMove",lib_pTeleportMove}, {"P_SetOrigin",lib_pSetOrigin}, {"P_MoveOrigin",lib_pMoveOrigin}, + {"P_SetAngle",lib_pSetAngle}, + {"P_SetPitch",lib_pSetPitch}, + {"P_SetRoll",lib_pSetRoll}, {"P_SlideMove",lib_pSlideMove}, {"P_BounceMove",lib_pBounceMove}, {"P_CheckSight", lib_pCheckSight}, diff --git a/src/m_cheat.h b/src/m_cheat.h index b5e018afc..c84f3e8f2 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -30,6 +30,7 @@ typedef enum { CHEAT_HURT, CHEAT_RELATIVE_TELEPORT, CHEAT_DEVMODE, + CHEAT_GIVEITEM, NUMBER_OF_CHEATS } cheat_t; diff --git a/src/objects/Sourcefile b/src/objects/Sourcefile index 044c9b576..b8cb63b1f 100644 --- a/src/objects/Sourcefile +++ b/src/objects/Sourcefile @@ -6,3 +6,4 @@ spb.c manta-ring.c orbinaut.c jawz.c +duel-bomb.c diff --git a/src/objects/duel-bomb.c b/src/objects/duel-bomb.c new file mode 100644 index 000000000..173efb933 --- /dev/null +++ b/src/objects/duel-bomb.c @@ -0,0 +1,97 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2022 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file duel-bomb.c +/// \brief Duel mode bombs. + +#include "../doomdef.h" +#include "../doomstat.h" +#include "../info.h" +#include "../k_kart.h" +#include "../k_objects.h" +#include "../m_random.h" +#include "../p_local.h" +#include "../r_main.h" +#include "../s_sound.h" +#include "../g_game.h" +#include "../z_zone.h" +#include "../k_waypoint.h" +#include "../k_respawn.h" +#include "../k_collide.h" + +#define bomb_dir(o) ((o)->movedir) + +static fixed_t GetBombSpeed(mobj_t *bomb) +{ + return FixedMul(bomb->info->speed, bomb->scale); +} + +static void UpdateBombMovement(mobj_t *bomb) +{ + const fixed_t spd = GetBombSpeed(bomb); + bomb->momx = FixedMul(spd, FINECOSINE(bomb_dir(bomb) >> ANGLETOFINESHIFT)); + bomb->momy = FixedMul(spd, FINESINE(bomb_dir(bomb) >> ANGLETOFINESHIFT)); +} + +void Obj_DuelBombThink(mobj_t *bomb) +{ + boolean grounded = P_IsObjectOnGround(bomb); + + if (grounded == true) + { + UpdateBombMovement(bomb); + } +} + +void Obj_DuelBombReverse(mobj_t *bomb) +{ + bomb_dir(bomb) += ANGLE_180; + UpdateBombMovement(bomb); +} + +void Obj_DuelBombTouch(mobj_t *bomb, mobj_t *toucher) +{ + player_t *player = toucher->player; + mobj_t *boom = NULL; + + if (bomb->health <= 0 || toucher->health <= 0) + { + return; + } + + if (player->flashing > 0 || player->hyudorotimer > 0 || P_PlayerInPain(player)) + { + // No interaction + return; + } + + // Create explosion + boom = P_SpawnMobjFromMobj(bomb, 0, 0, 0, MT_BOOMEXPLODE); + boom->momz = 5 * boom->scale; + boom->color = SKINCOLOR_KETCHUP; + S_StartSound(boom, bomb->info->attacksound); + + if (player->invincibilitytimer > 0 + || K_IsBigger(toucher, bomb) == true + || player->flamedash > 0) + { + // Kill without damaging. + P_KillMobj(bomb, toucher, toucher, DMG_NORMAL); + return; + } + + P_DamageMobj(toucher, bomb, bomb, 1, DMG_TUMBLE); + P_KillMobj(bomb, toucher, toucher, DMG_NORMAL); +} + +void Obj_DuelBombInit(mobj_t *bomb) +{ + bomb_dir(bomb) = bomb->angle + ANGLE_90; + UpdateBombMovement(bomb); +} diff --git a/src/objects/hyudoro.c b/src/objects/hyudoro.c index 0a362aa89..2b6d8cf1a 100644 --- a/src/objects/hyudoro.c +++ b/src/objects/hyudoro.c @@ -1,3 +1,15 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by James R. +// Copyright (C) 2022 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file hyudoro.c +/// \brief Hyudoro item code. + #include "../doomdef.h" #include "../doomstat.h" #include "../info.h" @@ -7,6 +19,7 @@ #include "../p_local.h" #include "../r_main.h" #include "../s_sound.h" +#include "../g_game.h" enum { HYU_PATROL, @@ -39,11 +52,14 @@ K_ChangePlayerItem #define hyudoro_hover_stack(o) ((o)->threshold) #define hyudoro_next(o) ((o)->tracer) #define hyudoro_stackpos(o) ((o)->reactiontime) +#define hyudoro_delivered(o) (hyudoro_itemtype(o) == KITEM_NONE) // cannot be combined #define hyudoro_center(o) ((o)->target) #define hyudoro_target(o) ((o)->target) +#define hyudoro_stolefrom(o) ((o)->hnext) + #define hyudoro_center_max_radius(o) ((o)->threshold) #define hyudoro_center_master(o) ((o)->target) @@ -101,6 +117,16 @@ sine_bob sineofs + FINESINE(a >> ANGLETOFINESHIFT)); } +static void +bob_in_place +( mobj_t * hyu, + INT32 bob_speed) +{ + sine_bob(hyu, + (leveltime & (bob_speed - 1)) * + (ANGLE_MAX / bob_speed), -(3*FRACUNIT/4)); +} + static void project_hyudoro (mobj_t *hyu) { @@ -127,8 +153,6 @@ project_hyudoro (mobj_t *hyu) static void project_hyudoro_hover (mobj_t *hyu) { - const INT32 bob_speed = 64; - mobj_t *target = hyudoro_target(hyu); // Turns a bit toward its target @@ -154,9 +178,7 @@ project_hyudoro_hover (mobj_t *hyu) hyu->pitch = target->pitch; hyu->roll = target->roll; - sine_bob(hyu, - (leveltime & (bob_speed - 1)) * - (ANGLE_MAX / bob_speed), -(3*FRACUNIT/4)); + bob_in_place(hyu, 64); } static void @@ -173,6 +195,79 @@ spawn_hyudoro_shadow (mobj_t *hyu) P_SetTarget(&shadow->tracer, hyu); } +static mobj_t * +find_duel_target (mobj_t *ignore) +{ + mobj_t *ret = NULL; + UINT8 bestPosition = UINT8_MAX; + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + player_t *player = NULL; + + if (playeringame[i] == false) + { + continue; + } + + player = &players[i]; + if (player->spectator || player->exiting) + { + continue; + } + + if (!player->mo || P_MobjWasRemoved(player->mo)) + { + continue; + } + + if (ignore != NULL && player->mo == ignore) + { + continue; + } + + if (player->position < bestPosition) + { + ret = player->mo; + bestPosition = player->position; + + if (bestPosition <= 1) + { + // Can't get any lower + break; + } + } + } + + return ret; +} + +static void +do_confused (mobj_t *hyu) +{ + // Hyudoro is confused. + // Spin around, try to find a new target. + + if (hyudoro_delivered(hyu)) + { + // Already delivered, not confused + return; + } + + // Try to find new target + P_SetTarget(&hyudoro_target(hyu), + find_duel_target(hyudoro_stolefrom(hyu))); + + // Spin in circles + hyu->angle += ANGLE_45; + + // Bob very fast + bob_in_place(hyu, 32); + + hyu->sprzoff += hyu->height; +} + static void move_to_player (mobj_t *hyu) { @@ -181,8 +276,11 @@ move_to_player (mobj_t *hyu) angle_t angle; fixed_t speed; - if (!target) + if (!target || P_MobjWasRemoved(target)) + { + do_confused(hyu); return; + } angle = R_PointToAngle2( hyu->x, hyu->y, target->x, target->y); @@ -232,6 +330,9 @@ deliver_item (mobj_t *hyu) hyu->destscale = target->scale / 4; hyu->scalespeed = abs(hyu->scale - hyu->destscale) / hyu->tics; + + // sets as already delivered + hyudoro_itemtype(hyu) = KITEM_NONE; } static void @@ -287,11 +388,14 @@ hyudoro_patrol_hit_player mobj_t *center = hyudoro_center(hyu); + mobj_t *master = NULL; + if (!player) return false; // Cannot hit its master - if (toucher == get_hyudoro_master(hyu)) + master = get_hyudoro_master(hyu); + if (toucher == master) return false; // Don't punish a punished player @@ -313,8 +417,15 @@ hyudoro_patrol_hit_player player->hyudorotimer = hyudorotime; player->stealingtimer = hyudorotime; - P_SetTarget(&hyudoro_target(hyu), - hyudoro_center_master(center)); + P_SetTarget(&hyudoro_stolefrom(hyu), toucher); + + if (master == NULL || P_MobjWasRemoved(master)) + { + // if master is NULL, it is probably a DUEL + master = find_duel_target(toucher); + } + + P_SetTarget(&hyudoro_target(hyu), master); if (center) P_RemoveMobj(center); @@ -388,11 +499,8 @@ hyudoro_hover_await_stack (mobj_t *hyu) } void -Obj_HyudoroDeploy (mobj_t *master) +Obj_InitHyudoroCenter (mobj_t * center, mobj_t * master) { - mobj_t *center = P_SpawnMobjFromMobj( - master, 0, 0, 0, MT_HYUDORO_CENTER); - mobj_t *hyu = P_SpawnMobjFromMobj( center, 0, 0, 0, MT_HYUDORO); @@ -405,20 +513,30 @@ Obj_HyudoroDeploy (mobj_t *master) center->radius = hyu->radius; - P_InitAngle(hyu, master->angle); + hyu->angle = center->angle; P_SetTarget(&hyudoro_center(hyu), center); P_SetTarget(&hyudoro_center_master(center), master); hyudoro_mode(hyu) = HYU_PATROL; // Set splitscreen player visibility - if (master->player) + hyu->renderflags |= RF_DONTDRAW; + if (master && !P_MobjWasRemoved(master) && master->player) { - hyu->renderflags |= RF_DONTDRAW & - ~(K_GetPlayerDontDrawFlag(master->player)); + hyu->renderflags &= ~(K_GetPlayerDontDrawFlag(master->player)); } spawn_hyudoro_shadow(hyu); // this sucks btw +} + +void +Obj_HyudoroDeploy (mobj_t *master) +{ + mobj_t *center = P_SpawnMobjFromMobj( + master, 0, 0, 0, MT_HYUDORO_CENTER); + + center->angle = master->angle; + Obj_InitHyudoroCenter(center, master); S_StartSound(master, sfx_s3k92); // scary ghost noise } diff --git a/src/objects/item-debris.c b/src/objects/item-debris.c index 6e810a3ad..886fd89c0 100644 --- a/src/objects/item-debris.c +++ b/src/objects/item-debris.c @@ -109,11 +109,11 @@ spawn_cloud puff->momz = puff->scale * P_MobjFlip(puff); - P_InitAngle(puff, R_PointToAngle2( + puff->angle = R_PointToAngle2( collectible->x, collectible->y, puff->x, - puff->y)); + puff->y); P_Thrust(puff, puff->angle, 3 * puff->scale); diff --git a/src/objects/spb.c b/src/objects/spb.c index 0ea565e45..32cb0e12d 100644 --- a/src/objects/spb.c +++ b/src/objects/spb.c @@ -24,8 +24,6 @@ #include "../k_waypoint.h" #include "../k_respawn.h" -// #define SPB_SEEKTEST - #define SPB_SLIPTIDEDELTA (ANG1 * 3) #define SPB_STEERDELTA (ANGLE_90 - ANG10) #define SPB_DEFAULTSPEED (FixedMul(mapobjectscale, K_GetKartSpeedFromStat(9) * 2)) @@ -107,11 +105,7 @@ static void SPBMantaRings(mobj_t *spb) Obj_MantaRingCreate( spb, spb_owner(spb), -#ifdef SPB_SEEKTEST - NULL -#else - spb_chase(spb) -#endif + cv_spbtest.value ? NULL : spb_chase(spb) ); } } @@ -360,8 +354,7 @@ static void SPBSeek(mobj_t *spb, player_t *bestPlayer) spb->fuse = 2*TICRATE; } } -#ifndef SPB_SEEKTEST // Easy debug switch - else + else if (!cv_spbtest.value) { if (dist <= activeDist) { @@ -378,7 +371,6 @@ static void SPBSeek(mobj_t *spb, player_t *bestPlayer) return; } } -#endif if (SPBSeekSoundPlaying(spb) == false) { @@ -441,64 +433,65 @@ static void SPBSeek(mobj_t *spb, player_t *bestPlayer) if (pathfindsuccess == true) { -#ifdef SPB_SEEKTEST - if (pathtoplayer.numnodes > 1) - { - // Go to the next waypoint. - curWaypoint = (waypoint_t *)pathtoplayer.array[1].nodedata; - } - else if (destWaypoint->numnextwaypoints > 0) - { - // Run ahead. - curWaypoint = destWaypoint->nextwaypoints[0]; + if (cv_spbtest.value) { + if (pathtoplayer.numnodes > 1) + { + // Go to the next waypoint. + curWaypoint = (waypoint_t *)pathtoplayer.array[1].nodedata; + } + else if (destWaypoint->numnextwaypoints > 0) + { + // Run ahead. + curWaypoint = destWaypoint->nextwaypoints[0]; + } + else + { + // Sort of wait at the player's dest waypoint. + circling = true; + curWaypoint = destWaypoint; + } } else { - // Sort of wait at the player's dest waypoint. - circling = true; - curWaypoint = destWaypoint; - } -#else - path_t reversepath = {0}; - boolean reversesuccess = false; + path_t reversepath = {0}; + boolean reversesuccess = false; - huntbackwards = true; - reversesuccess = K_PathfindToWaypoint( - curWaypoint, destWaypoint, - &reversepath, - useshortcuts, huntbackwards - ); + huntbackwards = true; + reversesuccess = K_PathfindToWaypoint( + curWaypoint, destWaypoint, + &reversepath, + useshortcuts, huntbackwards + ); - if (reversesuccess == true - && reversepath.totaldist < pathtoplayer.totaldist) - { - // It's faster to go backwards than to chase forward. - // Keep curWaypoint the same, so the SPB waits around for them. - circling = true; - } - else if (pathtoplayer.numnodes > 1) - { - // Go to the next waypoint. - curWaypoint = (waypoint_t *)pathtoplayer.array[1].nodedata; - } - else if (spb->fuse > 0 && destWaypoint->numnextwaypoints > 0) - { - // Run ahead. - curWaypoint = destWaypoint->nextwaypoints[0]; - } - else - { - // Sort of wait at the player's dest waypoint. - circling = true; - curWaypoint = destWaypoint; - } + if (reversesuccess == true + && reversepath.totaldist < pathtoplayer.totaldist) + { + // It's faster to go backwards than to chase forward. + // Keep curWaypoint the same, so the SPB waits around for them. + circling = true; + } + else if (pathtoplayer.numnodes > 1) + { + // Go to the next waypoint. + curWaypoint = (waypoint_t *)pathtoplayer.array[1].nodedata; + } + else if (spb->fuse > 0 && destWaypoint->numnextwaypoints > 0) + { + // Run ahead. + curWaypoint = destWaypoint->nextwaypoints[0]; + } + else + { + // Sort of wait at the player's dest waypoint. + circling = true; + curWaypoint = destWaypoint; + } - if (reversesuccess == true) - { - Z_Free(reversepath.array); + if (reversesuccess == true) + { + Z_Free(reversepath.array); + } } -#endif - Z_Free(pathtoplayer.array); } } diff --git a/src/p_enemy.c b/src/p_enemy.c index 55ea6de81..827e42c8e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1221,7 +1221,7 @@ void A_StatueBurst(mobj_t *actor) if (!locvar1 || !(new = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1))) return; - P_InitAngle(new, actor->angle); + new->angle = actor->angle; P_SetTarget(&new->target, actor->target); if (locvar2) P_SetMobjState(new, (statenum_t)locvar2); @@ -2504,7 +2504,7 @@ void A_LobShot(mobj_t *actor) P_SetTarget(&shot->target, actor); // where it came from - P_InitAngle(shot, actor->angle); + shot->angle = actor->angle; an = actor->angle >> ANGLETOFINESHIFT; dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y); @@ -2871,7 +2871,7 @@ void A_Boss1Laser(mobj_t *actor) S_StartSound(actor, mobjinfo[locvar1].seesound); point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); - P_InitAngle(point, actor->angle); + point->angle = actor->angle; point->fuse = dur+1; P_SetTarget(&point->target, actor->target); P_SetTarget(&actor->target, point); @@ -2881,7 +2881,7 @@ void A_Boss1Laser(mobj_t *actor) point = P_SpawnMobj(x, y, z, locvar1); P_SetTarget(&point->target, actor); - P_InitAngle(point, actor->angle); + point->angle = actor->angle; speed = point->radius; point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed); point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed)); @@ -2890,7 +2890,7 @@ void A_Boss1Laser(mobj_t *actor) for (i = 0; i < 256; i++) { mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); - P_InitAngle(mo, point->angle); + mo->angle = point->angle; mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; @@ -2922,7 +2922,7 @@ void A_Boss1Laser(mobj_t *actor) if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1) { point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE); - P_InitAngle(point, actor->angle); + point->angle = actor->angle; point->destscale = actor->scale; P_SetScale(point, point->destscale); P_SetTarget(&point->target, actor); @@ -3479,7 +3479,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle); + mo2->angle = mo->angle; P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSEGLZ1); @@ -3488,7 +3488,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle); + mo2->angle = mo->angle; P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSEGLZ2); @@ -3500,7 +3500,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle); + mo2->angle = mo->angle; P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSTANK1); @@ -3509,7 +3509,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle); + mo2->angle = mo->angle; P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSTANK2); @@ -3517,7 +3517,7 @@ bossjustdie: mo2 = P_SpawnMobjFromMobj(mo, 0, 0, mobjinfo[MT_EGGMOBILE2].height + (32<angle); + mo2->angle = mo->angle; P_SetObjectMomZ(mo2, 4*FRACUNIT, false); mo2->momz += mo->momz; P_SetMobjState(mo2, S_BOSSSPIGOT); @@ -3526,7 +3526,7 @@ bossjustdie: case MT_EGGMOBILE3: { mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK); - P_InitAngle(mo2, mo->angle); + mo2->angle = mo->angle; P_SetMobjState(mo2, S_BOSSSEBH1); } break; @@ -3578,8 +3578,8 @@ bossjustdie: pole->tracer->flags |= MF_NOCLIPTHING; P_SetScale(pole, (pole->destscale = 2*FRACUNIT)); P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT)); - P_InitAngle(pole, mo->tracer->angle); - P_InitAngle(pole->tracer, mo->tracer->angle); + pole->angle = mo->tracer->angle; + pole->tracer->angle = mo->tracer->angle; pole->tracer->tracer->angle = pole->angle - ANGLE_90; pole->momx = P_ReturnThrustX(pole, pole->angle, speed); pole->momy = P_ReturnThrustY(pole, pole->angle, speed); @@ -3948,7 +3948,7 @@ void A_AttractChase(mobj_t *actor) sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS); P_SetTarget(&sparkle->target, actor->target); - P_InitAngle(sparkle, (actor->target->angle + (offset>>1)) + (offset * actor->target->player->sparkleanim)); + sparkle->angle = (actor->target->angle + (offset>>1)) + (offset * actor->target->player->sparkleanim); actor->target->player->sparkleanim = (actor->target->player->sparkleanim+1) % 20; P_KillMobj(actor, actor->target, actor->target, DMG_NORMAL); @@ -5232,7 +5232,7 @@ void A_RockSpawn(mobj_t *actor) mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FALLINGROCK); P_SetMobjState(mo, mobjinfo[type].spawnstate); - P_InitAngle(mo, R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y)); + mo->angle = R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y); P_InstaThrust(mo, mo->angle, dist + randomoomph); mo->momz = dist + randomoomph; @@ -6978,7 +6978,7 @@ void A_Boss3ShockThink(mobj_t *actor) snew->momx = (actor->momx + snext->momx) >> 1; snew->momy = (actor->momy + snext->momy) >> 1; snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed? - P_InitAngle(snew, (actor->angle + snext->angle) >> 1); + snew->angle = (actor->angle + snext->angle) >> 1; P_SetTarget(&snew->target, actor->target); snew->fuse = actor->fuse; @@ -7134,7 +7134,7 @@ void A_SpawnObjectAbsolute(mobj_t *actor) mo = P_SpawnMobj(x<angle); + mo->angle = actor->angle; if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; @@ -7176,7 +7176,7 @@ void A_SpawnObjectRelative(mobj_t *actor) (actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[type].height) - FixedMul(z<scale)) : (actor->z + FixedMul(z<scale)), type); // Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn - P_InitAngle(mo, actor->angle); + mo->angle = actor->angle; if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; @@ -7886,7 +7886,7 @@ void A_BossJetFume(mobj_t *actor) P_SetScale(filler, filler->destscale); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; - P_InitAngle(filler, actor->angle - ANGLE_180); + filler->angle = actor->angle - ANGLE_180; P_SetTarget(&actor->tracer, filler); }*/ @@ -9639,7 +9639,7 @@ void A_TrapShot(mobj_t *actor) S_StartSound(missile, missile->info->seesound); P_SetTarget(&missile->target, actor); - P_InitAngle(missile, actor->angle); + missile->angle = actor->angle; speed = FixedMul(missile->info->speed, missile->scale); @@ -10216,7 +10216,7 @@ void A_BrakLobShot(mobj_t *actor) S_StartSound(shot, shot->info->seesound); P_SetTarget(&shot->target, actor); // where it came from - P_InitAngle(shot, actor->angle); + shot->angle = actor->angle; // Horizontal axes first. First parameter is initial horizontal impulse, second is to correct its angle. shot->momx = FixedMul(FixedMul(v, FINECOSINE(theta >> ANGLETOFINESHIFT)), FINECOSINE(shot->angle >> ANGLETOFINESHIFT)); @@ -10283,7 +10283,7 @@ void A_NapalmScatter(mobj_t *actor) mo = P_SpawnMobj(actor->x, actor->y, actor->z, typeOfShot); P_SetTarget(&mo->target, actor->target); // Transfer target so Brak doesn't hit himself like an idiot - P_InitAngle(mo, fa << ANGLETOFINESHIFT); + mo->angle = fa << ANGLETOFINESHIFT; mo->momx = FixedMul(FINECOSINE(fa),vx); mo->momy = FixedMul(FINESINE(fa),vx); mo->momz = vy; @@ -10307,7 +10307,7 @@ void A_SpawnFreshCopy(mobj_t *actor) newObject = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->type); newObject->flags2 = actor->flags2 & MF2_AMBUSH; - P_InitAngle(newObject, actor->angle); + newObject->angle = actor->angle; newObject->color = actor->color; P_SetTarget(&newObject->target, actor->target); P_SetTarget(&newObject->tracer, actor->tracer); @@ -10343,7 +10343,7 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz } flicky = P_SpawnMobjFromMobj(actor, offsx, offsy, 0, flickytype); - P_InitAngle(flicky, actor->angle); + flicky->angle = actor->angle; if (flickytype == MT_SEED) flicky->z += P_MobjFlip(actor)*(actor->height - flicky->height)/2; @@ -10493,7 +10493,7 @@ void A_FlickyCenter(mobj_t *actor) else if (actor->flags & MF_SLIDEME) // aimless { actor->tracer->fuse = 0; // less than 2*TICRATE means move aimlessly. - P_InitAngle(actor->tracer, P_RandomKey(PR_UNDEFINED, 180)*ANG2); + actor->tracer->angle = P_RandomKey(PR_UNDEFINED, 180)*ANG2; } else //orbit actor->tracer->fuse = FRACUNIT; @@ -11190,7 +11190,7 @@ void A_ConnectToGround(mobj_t *actor) { work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1); if (work) - P_InitAngle(work, ang); + work->angle = ang; ang += ANGLE_90; workz += workh; } @@ -11236,7 +11236,7 @@ void A_SpawnParticleRelative(mobj_t *actor) (actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[MT_PARTICLE].height) - FixedMul(z<scale)) : (actor->z + FixedMul(z<scale)), MT_PARTICLE); // Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn - P_InitAngle(mo, actor->angle); + mo->angle = actor->angle; if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; @@ -11983,7 +11983,7 @@ void A_Boss5MakeJunk(mobj_t *actor) broked->fuse = TICRATE; else broked->fuse = (((locvar2 & 1) ? 4 : 2)*TICRATE)/3; - P_InitAngle(broked, ang); + broked->angle = ang; P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale); P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(PR_UNDEFINED, 2, 5))< 0) @@ -12062,7 +12062,7 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi mobjtype ); - P_InitAngle(dust, ang*i + ANGLE_90); + dust->angle = ang*i + ANGLE_90; P_SetScale(dust, FixedMul(initscale, scale)); dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(PR_UNDEFINED), scale); dust->scalespeed = scale/24; @@ -12267,7 +12267,7 @@ static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t s->fuse = 16*TICRATE; s->sprite = spr; s->frame = frame|FF_PAPERSPRITE; - P_InitAngle(s, ang); + s->angle = ang; P_Thrust(s, src->angle, 7*FRACUNIT); return s; } @@ -12639,7 +12639,7 @@ void A_SaloonDoorSpawn(mobj_t *actor) // One door... if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return; - P_InitAngle(door, ang + ANGLE_180); + door->angle = ang + ANGLE_180; door->extravalue1 = AngleFixed(door->angle); // Origin angle door->extravalue2 = 0; // Angular speed P_SetTarget(&door->tracer, actor); // Origin door @@ -12647,7 +12647,7 @@ void A_SaloonDoorSpawn(mobj_t *actor) // ...two door! if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return; - P_InitAngle(door, ang); + door->angle = ang; door->extravalue1 = AngleFixed(door->angle); // Origin angle door->extravalue2 = 0; // Angular speed P_SetTarget(&door->tracer, actor); // Origin door @@ -12843,7 +12843,7 @@ void A_SpawnPterabytes(mobj_t *actor) c = FINECOSINE(fa); s = FINESINE(fa); waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT); - P_InitAngle(waypoint, ang + ANGLE_90); + waypoint->angle = ang + ANGLE_90; P_SetTarget(&waypoint->tracer, actor); ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE); ptera->angle = waypoint->angle; @@ -13017,7 +13017,7 @@ void A_DragonbomberSpawn(mobj_t *actor) segment = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRAGONTAIL); P_SetTarget(&segment->target, mo); P_SetTarget(&mo->tracer, segment); - P_InitAngle(segment, mo->angle); + segment->angle = mo->angle; mo = segment; } for (i = 0; i < 2; i++) // spawn wings @@ -13403,7 +13403,7 @@ void A_RandomShadowFrame(mobj_t *actor) P_SetScale(fake, FRACUNIT*3/2); fake->scale = FRACUNIT*3/2; fake->destscale = FRACUNIT*3/2; - P_InitAngle(fake, actor->angle); + fake->angle = actor->angle; fake->tics = -1; actor->renderflags |= RF_DONTDRAW; actor->extravalue1 = 1; @@ -13791,8 +13791,6 @@ void A_FlameShieldPaper(mobj_t *actor) paper->frame |= framea; } - P_InitAngle(paper, paper->angle); - paper->extravalue1 = i; } } @@ -13892,11 +13890,11 @@ A_SpawnItemDebrisCloud (mobj_t *actor) puff->momz = puff->scale * P_MobjFlip(puff); - P_InitAngle(puff, R_PointToAngle2( + puff->angle = R_PointToAngle2( target->x, target->y, puff->x, - puff->y)); + puff->y); P_Thrust(puff, puff->angle, 3 * puff->scale); diff --git a/src/p_inter.c b/src/p_inter.c index ac7b17976..b7e26d63a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -356,6 +356,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) Obj_SPBTouch(special, toucher); return; } + case MT_DUELBOMB: + { + Obj_DuelBombTouch(special, toucher); + return; + } case MT_EMERALD: if (!P_CanPickupItem(player, 0)) return; @@ -1012,7 +1017,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget { target->fuse = 2; } - else + else if (inDuel == false) { UINT8 i; @@ -1184,7 +1189,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mo->angle = FixedAngle((P_RandomKey(PR_UNDEFINED, 36)*10)<angle); + mo2->angle = mo->angle; P_SetMobjState(mo2, S_BOSSSEBH2); if (++i == 2) // we've already removed 2 of these, let's stop now @@ -1328,7 +1333,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget for (i = 0; i < 2; i++) { mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST); - P_InitAngle(blast, angle + i*ANGLE_90); + blast->angle = angle + i*ANGLE_90; P_SetScale(blast, 2*blast->scale/3); blast->destscale = 2*blast->scale; } @@ -1558,7 +1563,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\ P_SetMobjState(chunk, target->info->xdeathstate);\ chunk->health = 0;\ - P_InitAngle(chunk, angtweak);\ + chunk->angle = angtweak;\ P_UnsetThingPosition(chunk);\ chunk->flags = MF_NOCLIP;\ chunk->x += xmov;\ @@ -1580,7 +1585,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE); P_SetMobjState(chunk, target->info->deathstate); chunk->health = 0; - P_InitAngle(chunk, ang + ANGLE_180); + chunk->angle = ang + ANGLE_180; P_UnsetThingPosition(chunk); chunk->flags = MF_NOCLIP; chunk->x -= xoffs; @@ -1626,7 +1631,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\ P_SetMobjState(chunk, target->info->xdeathstate);\ chunk->health = 0;\ - P_InitAngle(chunk, target->angle);\ + chunk->angle = target->angle;\ P_UnsetThingPosition(chunk);\ chunk->flags = MF_NOCLIP;\ chunk->x += xmov - forwardxoffs;\ @@ -1652,7 +1657,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_SetMobjState(chunk, target->info->deathstate); chunk->health = 0; - P_InitAngle(chunk, target->angle); + chunk->angle = target->angle; P_UnsetThingPosition(chunk); chunk->flags = MF_NOCLIP; chunk->x += forwardxoffs - xoffs; @@ -1776,7 +1781,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM); boom->scale = player->mo->scale; - P_InitAngle(boom, player->mo->angle); + boom->angle = player->mo->angle; P_SetTarget(&boom->target, player->mo); } diff --git a/src/p_local.h b/src/p_local.h index c6671b9ae..18ff574fb 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -419,9 +419,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); -void P_InitAngle(mobj_t *thing, angle_t newValue); -void P_InitPitch(mobj_t *thing, angle_t newValue); -void P_InitRoll(mobj_t *thing, angle_t newValue); void P_SlideMove(mobj_t *mo); void P_BouncePlayerMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index 8c804d7dd..297f0cbe7 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -159,31 +159,6 @@ boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) return P_TeleportMove(thing, x, y, z); } -// -// P_InitAngle - Change an object's angle, including interp values. -// -void P_InitAngle(mobj_t *thing, angle_t newValue) -{ - thing->angle = thing->old_angle = newValue; -} - -// -// P_InitPitch - Change an object's pitch, including interp values. -// -void P_InitPitch(mobj_t *thing, angle_t newValue) -{ - thing->pitch = thing->old_pitch = newValue; -} - -// -// P_InitRoll - Change an object's roll, including interp values. -// -void P_InitRoll(mobj_t *thing, angle_t newValue) -{ - thing->roll = thing->old_roll = newValue; -} - - // ========================================================================= // MOVEMENT ITERATOR FUNCTIONS // ========================================================================= @@ -433,7 +408,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) mobj_t *grease; grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE); P_SetTarget(&grease->target, object); - P_InitAngle(grease, K_MomentumAngle(object)); + grease->angle = K_MomentumAngle(object); grease->extravalue1 = i; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 0dc332b54..6df9b921c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1707,7 +1707,13 @@ void P_XYMovement(mobj_t *mo) if (walltransferred == false) { - if (mo->flags & MF_SLIDEME) + if (mo->type == MT_DUELBOMB) + { + P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BUMP); + Obj_DuelBombReverse(mo); + xmove = ymove = 0; + } + else if (mo->flags & MF_SLIDEME) { P_SlideMove(mo); if (P_MobjWasRemoved(mo)) @@ -1759,13 +1765,13 @@ void P_XYMovement(mobj_t *mo) } break; + case MT_BUBBLESHIELDTRAP: + S_StartSound(mo, sfx_s3k44); // Bubble bounce + break; + default: break; } - - // Bubble bounce - if (mo->type == MT_BUBBLESHIELDTRAP) - S_StartSound(mo, sfx_s3k44); } } } @@ -2466,7 +2472,7 @@ boolean P_ZMovement(mobj_t *mo) MT_KART_TIRE ); - P_InitAngle(tire, mo->angle); + tire->angle = mo->angle; tire->fuse = 3*TICRATE; P_InstaThrust(tire, tireAngle, 4 * mo->scale); P_SetObjectMomZ(tire, 4*FRACUNIT, false); @@ -2486,7 +2492,7 @@ boolean P_ZMovement(mobj_t *mo) MT_KART_TIRE ); - P_InitAngle(tire, mo->angle); + tire->angle = mo->angle; tire->fuse = 3*TICRATE; P_InstaThrust(tire, tireAngle, 4 * mo->scale); P_SetObjectMomZ(tire, 4*FRACUNIT, false); @@ -4404,7 +4410,7 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj) part = part->hnext; P_SetTarget(&part->target, mobj); P_SetMobjState(part, buttState); - P_InitAngle(part, i * ANG_CAPSULE); + part->angle = i * ANG_CAPSULE; part->movedir = spin; // rotation speed part->movefactor = 0; // z offset part->extravalue1 = buttScale; // relative scale @@ -4415,7 +4421,7 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj) part = part->hnext; P_SetTarget(&part->target, mobj); P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE); - P_InitAngle(part, i * ANG_CAPSULE); + part->angle = i * ANG_CAPSULE; part->movedir = spin; // rotation speed part->movefactor = mobj->info->height - part->info->height; // z offset } @@ -4743,7 +4749,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb mobj->z -= mobj->height>>1; // change angle - P_InitAngle(mobj, R_PointToAngle2(mobj->x, mobj->y, x, y)); + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, x, y); // change slope dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z); @@ -5132,6 +5138,7 @@ boolean P_IsKartFieldItem(INT32 type) case MT_POGOSPRING: case MT_SINK: case MT_DROPTARGET: + case MT_DUELBOMB: return true; default: @@ -5470,7 +5477,7 @@ static void P_FlameJetSceneryThink(mobj_t *mobj) flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); P_SetMobjState(flame, S_FLAMEJETFLAME4); - P_InitAngle(flame, mobj->angle); + flame->angle = mobj->angle; if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side flame->momz = mobj->fuse << (FRACBITS - 2); @@ -5959,7 +5966,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) blast->angle += ANGLE_90; S_StartSound(blast, sfx_cdfm64); } - P_InitAngle(blast, blast->angle); + blast->angle = blast->angle; blast->destscale *= 4; } @@ -6104,7 +6111,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->x = mobj->target->x; mobj->y = mobj->target->y; - P_InitAngle (mobj, R_PointToAngle(mobj->x, mobj->y) + ANGLE_90); // literally only happened because i wanted to ^L^R the SPR_ITEM's + mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's if (!r_splitscreen && players[displayplayers[0]].mo) { @@ -7008,6 +7015,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_LANDMINE: mobj->friction = ORIG_FRICTION/4; + if (mobj->target && mobj->target->player) + mobj->color = mobj->target->player->skincolor; + else + mobj->color = SKINCOLOR_SAPPHIRE; + if (mobj->momx || mobj->momy || mobj->momz) { mobj_t *ghost = P_SpawnGhostMobj(mobj); @@ -7066,6 +7078,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_SPBEXPLOSION: mobj->health--; break; + case MT_DUELBOMB: + { + Obj_DuelBombThink(mobj); + break; + } case MT_EMERALD: { if (battleovertime.enabled >= 10*TICRATE) @@ -7799,7 +7816,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->z + (mobj->height/2) + (P_RandomRange(PR_ITEM_BOOST, -20,20) * mobj->scale), MT_FASTLINE); - P_InitAngle(fast, mobj->angle); + fast->angle = mobj->angle; fast->momx = 3*mobj->target->momx/4; fast->momy = 3*mobj->target->momy/4; fast->momz = 3*P_GetMobjZMovement(mobj->target)/4; @@ -7861,7 +7878,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (underlayst != S_NULL) { mobj_t *underlay = P_SpawnMobj(mobj->target->x, mobj->target->y, mobj->target->z, MT_FLAMESHIELDUNDERLAY); - P_InitAngle(underlay, mobj->angle); + underlay->angle = mobj->angle; P_SetMobjState(underlay, underlayst); } break; @@ -9307,7 +9324,7 @@ static boolean P_FuseThink(mobj_t *mobj) for (i = 0; i < 5; i++) { mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS); - P_InitAngle(debris, FixedAngle(P_RandomRange(PR_DECORATION, 0,360)<angle = FixedAngle(P_RandomRange(PR_DECORATION, 0,360)<angle, P_RandomRange(PR_DECORATION, 3,18)*(FRACUNIT/4)); debris->momz = P_RandomRange(PR_DECORATION, 4,8)<shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: @@ -10138,7 +10156,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_CRUSHSTACEAN: { mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CRUSHCLAW); - P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270)); + bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); P_SetTarget(&mobj->tracer, bigmeatyclaw); P_SetTarget(&bigmeatyclaw->tracer, mobj); mobj->reactiontime >>= 1; @@ -10147,7 +10165,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BANPYURA: { mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING); - P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270)); + bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); P_SetTarget(&mobj->tracer, bigmeatyclaw); P_SetTarget(&bigmeatyclaw->tracer, mobj); mobj->reactiontime >>= 1; @@ -10283,7 +10301,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_MINECARTEND: P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID)); - P_InitAngle(mobj->tracer, mobj->angle + ANGLE_90); + mobj->tracer->angle = mobj->angle + ANGLE_90; break; case MT_TORCHFLOWER: { @@ -10405,7 +10423,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) angle_t ang = i * diff; mobj_t *side = P_SpawnMobj(mobj->x + FINECOSINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_DAYTONAPINETREE_SIDE); - P_InitAngle(side, ang); + side->angle = ang; P_SetTarget(&side->target, mobj); side->threshold = i; } @@ -10422,7 +10440,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) cur = P_SpawnMobj(mobj->x + FINECOSINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK), mobj->y + FINESINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_EZZPROPELLER_BLADE); - P_InitAngle(cur, mobj->angle); + cur->angle = mobj->angle; P_SetTarget(&cur->hprev, prev); P_SetTarget(&prev->hnext, cur); @@ -10488,7 +10506,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) cur->threshold = i; P_MoveOrigin(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<>ANGLETOFINESHIFT) & FINEMASK)), cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<>ANGLETOFINESHIFT) & FINEMASK)), cur->z); - P_InitAngle(cur, ANGLE_90*(cur->threshold+1)); + cur->angle = ANGLE_90*(cur->threshold+1); P_SetTarget(&cur->hprev, prev); P_SetTarget(&prev->hnext, cur); @@ -11741,10 +11759,22 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) break; } + if (inDuel == false) + { + if (K_IsDuelItem(i) == true + && K_DuelItemAlwaysSpawns(mthing) == false) + { + // Only spawns in Duels. + return false; + } + } + // No bosses outside of a combat situation. // (just in case we want boss arenas to do double duty as battle maps) if (!bossinfo.boss && (mobjinfo[i].flags & MF_BOSS)) + { return false; + } if (metalrecording) // Metal Sonic can't use these things. { @@ -12016,7 +12046,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) spawnee->friction = mroll;\ spawnee->movefactor = mwidthset;\ spawnee->movecount = dist;\ - P_InitAngle(spawnee, myaw);\ + spawnee->angle = myaw;\ spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ spawnee->flags2 |= (mflags2apply|moreflags2);\ spawnee->eflags |= meflagsapply;\ @@ -12215,29 +12245,29 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong) statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER; mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); - P_InitAngle(seg, angle - ANGLE_90); + seg->angle = angle - ANGLE_90; P_SetMobjState(seg, facestate); seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); - P_InitAngle(seg, angle + ANGLE_90); + seg->angle = angle + ANGLE_90; P_SetMobjState(seg, facestate); seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); - P_InitAngle(seg, angle); + seg->angle = angle; P_SetMobjState(seg, leftstate); seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); - P_InitAngle(seg, angle); + seg->angle = angle; P_SetMobjState(seg, rightstate); seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER); - P_InitAngle(seg, angle); + seg->angle = angle; P_SetMobjState(seg, rollerstate); seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER); - P_InitAngle(seg, angle); + seg->angle = angle; P_SetMobjState(seg, rollerstate); seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER); - P_InitAngle(seg, angle); + seg->angle = angle; P_SetMobjState(seg, rollerstate); seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER); - P_InitAngle(seg, angle); + seg->angle = angle; P_SetMobjState(seg, rollerstate); return true; @@ -12414,19 +12444,19 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_THZTREE: { // Spawn the branches angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS); - P_InitAngle(P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_22h); - P_InitAngle(P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_157h); - P_InitAngle(P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_270); + P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h; + P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h; + P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; } break; case MT_CEZPOLE1: case MT_CEZPOLE2: { // Spawn the banner angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); - P_InitAngle(P_SpawnMobjFromMobj(mobj, + P_SpawnMobjFromMobj(mobj, P_ReturnThrustX(mobj, mobjangle, 4 << FRACBITS), P_ReturnThrustY(mobj, mobjangle, 4 << FRACBITS), - 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2)), mobjangle + ANGLE_90); + 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90; } break; case MT_HHZTREE_TOP: @@ -12435,7 +12465,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj_t* leaf; #define doleaf(x, y) \ leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\ - P_InitAngle(leaf, mobjangle);\ + leaf->angle = mobjangle;\ P_SetMobjState(leaf, leaf->info->seestate);\ mobjangle += ANGLE_90 doleaf(FRACUNIT, 0); @@ -12459,7 +12489,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean fixed_t xoffs = FINECOSINE(fa); fixed_t yoffs = FINESINE(fa); mobj_t* leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF); - P_InitAngle(leaf, angle); + leaf->angle = angle; angle += ANGLE_45; } break; @@ -12569,7 +12599,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), mobj->z, MT_WALLSPIKEBASE); - P_InitAngle(base, mobjangle + ANGLE_90); + base->angle = mobjangle + ANGLE_90; base->destscale = mobj->destscale; P_SetScale(base, mobj->scale); P_SetTarget(&base->target, mobj); @@ -12771,7 +12801,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean leaf = P_SpawnMobj(mobj->x + FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK), mobj->y + FINESINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK), top, MT_AAZTREE_LEAF); - P_InitAngle(leaf, mobj->angle); + leaf->angle = mobj->angle; // Small coconut for each leaf P_SpawnMobj(mobj->x + (32 * FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK)), @@ -12903,6 +12933,33 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean // Increment no. of capsules on the map counter maptargets++; + break; + } + case MT_DUELBOMB: + { + // Duel Bomb needs init to match real map thing's angle + mobj->angle = FixedAngle(mthing->angle << FRACBITS); + Obj_DuelBombInit(mobj); + *doangle = false; + break; + } + case MT_BANANA: + { + // Give Duel bananas a random angle + mobj->angle = FixedMul(P_RandomFixed(PR_DECORATION), ANGLE_MAX); + *doangle = false; + break; + } + case MT_HYUDORO_CENTER: + { + Obj_InitHyudoroCenter(mobj, NULL); + break; + } + case MT_POGOSPRING: + { + // Start as tumble version. + mobj->reactiontime++; + break; } default: break; @@ -12943,6 +13000,11 @@ static void P_SetAmbush(mobj_t *mobj) mobj->type != MT_NIGHTSBUMPER && mobj->type != MT_STARPOST) mobj->flags2 |= MF2_AMBUSH; + + if (mobj->type == MT_DUELBOMB) + { + Obj_DuelBombReverse(mobj); + } } static void P_SetObjectSpecial(mobj_t *mobj) @@ -12980,7 +13042,7 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, if (doangle) { - P_InitAngle(mobj, FixedAngle(mthing->angle << FRACBITS)); + mobj->angle = FixedAngle(mthing->angle << FRACBITS); } if ((mobj->flags & MF_SPRING) @@ -12993,8 +13055,8 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, mobj->spryoff = FixedMul(mobj->radius, FINESINE(a >> ANGLETOFINESHIFT)); } - P_InitPitch(mobj, FixedAngle(mthing->pitch << FRACBITS)); - P_InitRoll(mobj, FixedAngle(mthing->roll << FRACBITS)); + mobj->pitch = FixedAngle(mthing->pitch << FRACBITS); + mobj->roll = FixedAngle(mthing->roll << FRACBITS); mthing->mobj = mobj; @@ -13397,7 +13459,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, P_SetTarget(&th->target, source); // where it came from an = R_PointToAngle2(x, y, dest->x, dest->y); - P_InitAngle(th, an); + th->angle = an; an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13459,7 +13521,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t P_SetTarget(&th->target, source->target); // where it came from an = R_PointToAngle2(0, 0, source->momx, source->momy) + (ANG1*shiftingAngle); - P_InitAngle(th, an); + th->angle = an; an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13524,7 +13586,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, P_SetTarget(&th->target, source); // where it came from an = R_PointToAngle2(x, y, xa, ya); - P_InitAngle(th, an); + th->angle = an; an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13603,7 +13665,7 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type) else an = R_PointToAngle2(source->x, source->y, dest->x, dest->y); - P_InitAngle(th, an); + th->angle = an; an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13691,7 +13753,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai speed = th->info->speed; - P_InitAngle(th, an); + th->angle = an; th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT)); th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT)); diff --git a/src/p_saveg.c b/src/p_saveg.c index 85e5dc1d9..3f3828051 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4590,6 +4590,7 @@ static void P_NetArchiveMisc(boolean resending) WRITEUINT8(save_p, lastLowestLap); WRITESINT8(save_p, spbplace); WRITEUINT8(save_p, rainbowstartavailable); + WRITEUINT8(save_p, inDuel); WRITEUINT32(save_p, introtime); WRITEUINT32(save_p, starttime); @@ -4748,6 +4749,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) lastLowestLap = READUINT8(save_p); spbplace = READSINT8(save_p); rainbowstartavailable = (boolean)READUINT8(save_p); + inDuel = (boolean)READUINT8(save_p); introtime = READUINT32(save_p); starttime = READUINT32(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index 3934e56c9..d0ae292a0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3705,7 +3705,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (mobj) { if (line->flags & ML_EFFECT1) - P_InitAngle(mobj, R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y)); + mobj->angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow. } else @@ -3999,7 +3999,7 @@ void P_SetupSignExit(player_t *player) if (player->mo && !P_MobjWasRemoved(player->mo)) { thing = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->floorz, MT_SIGN); - P_InitAngle(thing, player->mo->angle); + thing->angle = player->mo->angle; P_SetupSignObject(thing, player->mo, true); // Use :youfuckedup: sign face } } diff --git a/src/p_telept.c b/src/p_telept.c index 530830ad3..c3e36f3c7 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -97,7 +97,8 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, P_FlashPal(thing->player, PAL_MIXUP, 10); } - P_InitAngle(thing, angle); + thing->old_angle += (angle-thing->angle); + thing->angle = angle; thing->momx = thing->momy = thing->momz = 0; diff --git a/src/p_user.c b/src/p_user.c index 2217b399d..090346bea 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -388,7 +388,7 @@ void P_GiveFinishFlags(player_t *player) fixed_t xoffs = FINECOSINE(fa); fixed_t yoffs = FINESINE(fa); mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG); - P_InitAngle(flag, angle); + flag->angle = angle; angle += FixedAngle(120*FRACUNIT); P_SetTarget(&flag->target, player->mo); diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index 65550906e..60921b587 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -78,13 +78,7 @@ if(${SDL2_FOUND}) ) endif() - if(${CMAKE_SYSTEM} MATCHES Windows) - set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2kart) - elseif(${CMAKE_SYSTEM} MATCHES Linux) - set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME lsdlsrb2kart) - else() - set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2kart) - endif() + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ringracers) if(${CMAKE_SYSTEM} MATCHES Darwin) find_library(CORE_LIB CoreFoundation)