2016-08-12 01:42:11 +00:00
// SONIC ROBO BLAST 2 KART ~ ZarroTsu
//-----------------------------------------------------------------------------
/// \file k_kart.c
/// \brief SRB2kart general.
/// All of the SRB2kart-unique stuff.
# include "doomdef.h"
2016-08-15 03:51:08 +00:00
# include "hu_stuff.h"
# include "g_game.h"
# include "m_random.h"
# include "p_local.h"
2017-02-07 22:19:04 +00:00
# include "p_slopes.h"
2016-08-12 01:42:11 +00:00
# include "r_draw.h"
# include "r_local.h"
2016-08-15 03:51:08 +00:00
# include "s_sound.h"
# include "st_stuff.h"
# include "v_video.h"
# include "z_zone.h"
2017-02-17 20:14:55 +00:00
# include "m_misc.h"
2018-07-15 22:13:36 +00:00
# include "m_cond.h"
2017-03-04 22:13:19 +00:00
# include "k_kart.h"
2017-11-14 01:45:57 +00:00
# include "f_finale.h"
2016-08-12 01:42:11 +00:00
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
// franticitems is Frantic Mode items, bool
// mirrormode is Mirror Mode (duh), bool
// comeback is Battle Mode's karma comeback, also bool
2018-07-01 08:36:09 +00:00
// battlewanted is an array of the WANTED player nums, -1 for no player in that slot
2018-06-11 05:51:50 +00:00
// indirectitemcooldown is timer before anyone's allowed another Shrink/SPB
2018-06-07 23:39:45 +00:00
// spbincoming is the timer before k_deathsentence is cast on the player in 1st
2018-06-11 05:51:50 +00:00
// spbplayer is the last player who fired a SPB
2018-07-21 19:54:05 +00:00
// mapreset is set when enough players fill an empty server
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
2016-08-12 01:42:11 +00:00
//{ SRB2kart Color Code
# define SKIN_RAMP_LENGTH 16
# define DEFAULT_STARTTRANSCOLOR 160
# define NUM_PALETTE_ENTRIES 256
2017-10-21 17:22:54 +00:00
// These should be within 14 characters to fit on the character select screen
2016-08-12 01:42:11 +00:00
const char * KartColor_Names [ MAXSKINCOLORS ] =
{
2017-10-21 17:22:54 +00:00
" None " , // 00 // SKINCOLOR_NONE
" Ivory " , // 01 // SKINCOLOR_IVORY
" White " , // 02 // SKINCOLOR_WHITE
" Silver " , // 03 // SKINCOLOR_SILVER
" Cloudy " , // 04 // SKINCOLOR_CLOUDY
" Grey " , // 05 // SKINCOLOR_GREY
2018-07-02 18:05:09 +00:00
" Nickel " , // 06 // SKINCOLOR_NICKEL
2017-10-21 17:22:54 +00:00
" Black " , // 07 // SKINCOLOR_BLACK
" Salmon " , // 08 // SKINCOLOR_SALMON
" Pink " , // 09 // SKINCOLOR_PINK
2018-07-11 02:59:19 +00:00
" Rose " , // 10 // SKINCOLOR_ROSE
" Raspberry " , // 11 // SKINCOLOR_RASPBERRY
2017-10-21 17:22:54 +00:00
" Red " , // 12 // SKINCOLOR_RED
2018-07-11 02:59:19 +00:00
" Ruby " , // 13 // SKINCOLOR_RUBY
2018-07-02 07:30:33 +00:00
" Crimson " , // 14 // SKINCOLOR_CRIMSON
2017-10-21 17:22:54 +00:00
" Dawn " , // 15 // SKINCOLOR_DAWN
2018-07-11 02:59:19 +00:00
" Creamsicle " , // 16 // SKINCOLOR_CREAMSICLE
" Orange " , // 17 // SKINCOLOR_ORANGE
2018-07-02 07:30:33 +00:00
" Pumpkin " , // 18 // SKINCOLOR_PUMPKIN
2018-07-11 02:59:19 +00:00
" Rosewood " , // 19 // SKINCOLOR_ROSEWOOD
" Burgundy " , // 20 // SKINCOLOR_BURGUNDY
" Bronze " , // 21 // SKINCOLOR_BRONZE
2017-10-21 17:22:54 +00:00
" Sepia " , // 22 // SKINCOLOR_SEPIA
" Beige " , // 23 // SKINCOLOR_BEIGE
" Brown " , // 24 // SKINCOLOR_BROWN
" Leather " , // 25 // SKINCOLOR_LEATHER
2018-07-11 02:59:19 +00:00
" Peach " , // 26 // SKINCOLOR_PEACH
" Caramel " , // 27 // SKINCOLOR_CARAMEL
" Tangerine " , // 28 // SKINCOLOR_TANGERINE
" Gold " , // 29 // SKINCOLOR_GOLD
" Vomit " , // 30 // SKINCOLOR_VOMIT
" Yellow " , // 31 // SKINCOLOR_YELLOW
" Canary " , // 32 // SKINCOLOR_CANARY
" Olive " , // 33 // SKINCOLOR_OLIVE
2018-07-02 17:54:01 +00:00
" Garden " , // 34 // SKINCOLOR_GARDEN
2018-07-11 02:59:19 +00:00
" Lime " , // 35 // SKINCOLOR_LIME
" Tea " , // 36 // SKINCOLOR_TEA
" Army " , // 37 // SKINCOLOR_ARMY
" Pistachio " , // 38 // SKINCOLOR_PISTACHIO
" Moss " , // 39 // SKINCOLOR_MOSS
2018-07-02 07:30:33 +00:00
" Mint " , // 40 // SKINCOLOR_MINT
2018-07-11 02:59:19 +00:00
" Green " , // 41 // SKINCOLOR_GREEN
" Robo-Hood " , // 42 // SKINCOLOR_ROBOHOOD
" Pinetree " , // 43 // SKINCOLOR_PINETREE
" Emerald " , // 44 // SKINCOLOR_EMERALD
2017-10-21 17:22:54 +00:00
" Swamp " , // 45 // SKINCOLOR_SWAMP
2018-07-11 02:59:19 +00:00
" Aqua " , // 46 // SKINCOLOR_AQUA
" Teal " , // 47 // SKINCOLOR_TEAL
2018-07-02 12:20:04 +00:00
" Cyan " , // 48 // SKINCOLOR_CYAN
" Cerulean " , // 49 // SKINCOLOR_CERULEAN
2018-07-11 02:59:19 +00:00
" Slate " , // 50 // SKINCOLOR_SLATE
" Steel " , // 51 // SKINCOLOR_STEEL
" Periwinkle " , // 52 // SKINCOLOR_PERIWINKLE
2018-07-02 12:20:04 +00:00
" Blue " , // 53 // SKINCOLOR_BLUE
" Sapphire " , // 54 // SKINCOLOR_SAPPHIRE
2018-07-11 02:59:19 +00:00
" Blueberry " , // 55 // SKINCOLOR_BLUEBERRY
" Navy " , // 56 // SKINCOLOR_NAVY
2018-07-02 12:20:04 +00:00
" Jet " , // 57 // SKINCOLOR_JET
2018-07-11 02:59:19 +00:00
" Dusk " , // 58 // SKINCOLOR_DUSK
" Purple " , // 59 // SKINCOLOR_PURPLE
" Lavender " , // 60 // SKINCOLOR_LAVENDER
" Indigo " , // 61 // SKINCOLOR_INDIGO
2017-10-21 17:22:54 +00:00
" Byzantium " , // 62 // SKINCOLOR_BYZANTIUM
2018-07-11 02:59:19 +00:00
" Lilac " // 63 // SKINCOLOR_LILAC
2016-08-12 01:42:11 +00:00
} ;
2018-06-20 00:20:06 +00:00
// Color_Opposite replacement; frame setting has not been changed from 8 for most, should be done later
const UINT8 KartColor_Opposite [ MAXSKINCOLORS * 2 ] =
{
SKINCOLOR_NONE , 8 , // 00 // SKINCOLOR_NONE
SKINCOLOR_BLACK , 8 , // 01 // SKINCOLOR_IVORY
2018-07-06 18:22:48 +00:00
SKINCOLOR_NICKEL , 8 , // 02 // SKINCOLOR_WHITE
SKINCOLOR_GREY , 8 , // 03 // SKINCOLOR_SILVER
2018-06-20 00:20:06 +00:00
SKINCOLOR_CLOUDY , 8 , // 04 // SKINCOLOR_CLOUDY
2018-07-06 18:22:48 +00:00
SKINCOLOR_SILVER , 8 , // 05 // SKINCOLOR_GREY
SKINCOLOR_WHITE , 8 , // 06 // SKINCOLOR_NICKEL
SKINCOLOR_IVORY , 8 , // 07 // SKINCOLOR_BLACK
SKINCOLOR_TEA , 8 , // 08 // SKINCOLOR_SALMON
2018-06-20 00:20:06 +00:00
SKINCOLOR_ARMY , 8 , // 09 // SKINCOLOR_PINK
2018-07-11 02:59:19 +00:00
SKINCOLOR_MOSS , 8 , // 10 // SKINCOLOR_ROSE
SKINCOLOR_MINT , 10 , // 11 // SKINCOLOR_RASPBERRY
2018-06-20 00:20:06 +00:00
SKINCOLOR_GREEN , 8 , // 12 // SKINCOLOR_RED
2018-07-11 02:59:19 +00:00
SKINCOLOR_EMERALD , 6 , // 13 // SKINCOLOR_RUBY
2018-07-06 18:22:48 +00:00
SKINCOLOR_PINETREE , 6 , // 14 // SKINCOLOR_CRIMSON
SKINCOLOR_DUSK , 8 , // 15 // SKINCOLOR_DAWN
2018-07-11 02:59:19 +00:00
SKINCOLOR_PERIWINKLE , 8 , // 16 // SKINCOLOR_CREAMSICLE
SKINCOLOR_BLUE , 8 , // 17 // SKINCOLOR_ORANGE
SKINCOLOR_BLUEBERRY , 8 , // 18 // SKINCOLOR_PUMPKIN
2018-07-06 18:22:48 +00:00
SKINCOLOR_NAVY , 8 , // 19 // SKINCOLOR_ROSEWOOD
SKINCOLOR_JET , 8 , // 20 // SKINCOLOR_BURGUNDY
2018-07-11 02:59:19 +00:00
SKINCOLOR_STEEL , 8 , // 21 // SKINCOLOR_BRONZE
SKINCOLOR_LEATHER , 6 , // 22 // SKINCOLOR_SEPIA
SKINCOLOR_BROWN , 2 , // 23 // SKINCOLOR_BEIGE
SKINCOLOR_BEIGE , 8 , // 24 // SKINCOLOR_BROWN
SKINCOLOR_SEPIA , 8 , // 25 // SKINCOLOR_LEATHER
SKINCOLOR_SLATE , 8 , // 26 // SKINCOLOR_PEACH
SKINCOLOR_TEAL , 8 , // 27 // SKINCOLOR_CARAMEL
SKINCOLOR_LIME , 8 , // 28 // SKINCOLOR_TANGERINE
SKINCOLOR_LAVENDER , 6 , // 29 // SKINCOLOR_GOLD
SKINCOLOR_ROBOHOOD , 8 , // 30 // SKINCOLOR_VOMIT
SKINCOLOR_BYZANTIUM , 8 , // 31 // SKINCOLOR_YELLOW
SKINCOLOR_PURPLE , 8 , // 32 // SKINCOLOR_CANARY
SKINCOLOR_INDIGO , 8 , // 33 // SKINCOLOR_OLIVE
2018-07-06 18:22:48 +00:00
SKINCOLOR_AQUA , 8 , // 34 // SKINCOLOR_GARDEN
2018-07-11 02:59:19 +00:00
SKINCOLOR_TANGERINE , 8 , // 35 // SKINCOLOR_LIME
SKINCOLOR_SALMON , 8 , // 36 // SKINCOLOR_TEA
SKINCOLOR_PINK , 6 , // 37 // SKINCOLOR_ARMY
SKINCOLOR_CYAN , 8 , // 38 // SKINCOLOR_PISTACHIO
SKINCOLOR_ROSE , 8 , // 39 // SKINCOLOR_MOSS
SKINCOLOR_RASPBERRY , 6 , // 40 // SKINCOLOR_MINT
SKINCOLOR_RED , 8 , // 41 // SKINCOLOR_GREEN
SKINCOLOR_VOMIT , 8 , // 42 // SKINCOLOR_ROBOHOOD
SKINCOLOR_CRIMSON , 8 , // 43 // SKINCOLOR_PINETREE
SKINCOLOR_RUBY , 8 , // 44 // SKINCOLOR_EMERALD
2018-07-06 18:22:48 +00:00
SKINCOLOR_SAPPHIRE , 8 , // 45 // SKINCOLOR_SWAMP
2018-07-11 02:59:19 +00:00
SKINCOLOR_GARDEN , 10 , // 46 // SKINCOLOR_AQUA
SKINCOLOR_CARAMEL , 8 , // 47 // SKINCOLOR_TEAL
2018-07-06 18:22:48 +00:00
SKINCOLOR_PISTACHIO , 6 , // 48 // SKINCOLOR_CYAN
SKINCOLOR_LILAC , 8 , // 49 // SKINCOLOR_CERULEAN
2018-07-11 02:59:19 +00:00
SKINCOLOR_PEACH , 8 , // 50 // SKINCOLOR_SLATE
SKINCOLOR_BRONZE , 10 , // 51 // SKINCOLOR_STEEL
SKINCOLOR_CREAMSICLE , 8 , // 52 // SKINCOLOR_PERIWINKLE
2018-07-02 07:30:33 +00:00
SKINCOLOR_ORANGE , 8 , // 53 // SKINCOLOR_BLUE
2018-07-06 18:22:48 +00:00
SKINCOLOR_SWAMP , 8 , // 54 // SKINCOLOR_SAPPHIRE
2018-07-11 02:59:19 +00:00
SKINCOLOR_PUMPKIN , 8 , // 55 // SKINCOLOR_BLUEBERRY
SKINCOLOR_ROSEWOOD , 8 , // 56 // SKINCOLOR_NAVY
2018-07-06 18:22:48 +00:00
SKINCOLOR_BURGUNDY , 6 , // 57 // SKINCOLOR_JET
2018-07-11 02:59:19 +00:00
SKINCOLOR_DAWN , 8 , // 58 // SKINCOLOR_DUSK
SKINCOLOR_CANARY , 8 , // 59 // SKINCOLOR_PURPLE
SKINCOLOR_GOLD , 10 , // 60 // SKINCOLOR_LAVENDER
SKINCOLOR_OLIVE , 8 , // 61 // SKINCOLOR_INDIGO
2018-07-06 18:22:48 +00:00
SKINCOLOR_YELLOW , 8 , // 62 // SKINCOLOR_BYZANTIUM
2018-07-11 02:59:19 +00:00
SKINCOLOR_CERULEAN , 8 // 63 // SKINCOLOR_LILAC
2018-06-20 00:20:06 +00:00
} ;
2017-10-26 19:04:05 +00:00
UINT8 colortranslations [ MAXSKINCOLORS ] [ 16 ] = {
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , // SKINCOLOR_NONE
2018-07-11 02:59:19 +00:00
{ 120 , 120 , 120 , 120 , 0 , 1 , 3 , 4 , 6 , 7 , 10 , 14 , 18 , 22 , 25 , 28 } , // SKINCOLOR_IVORY
{ 120 , 120 , 0 , 1 , 3 , 4 , 6 , 7 , 9 , 11 , 13 , 16 , 19 , 23 , 26 , 29 } , // SKINCOLOR_WHITE
{ 0 , 1 , 3 , 5 , 6 , 8 , 10 , 11 , 13 , 15 , 16 , 18 , 20 , 24 , 27 , 30 } , // SKINCOLOR_SILVER
2017-10-26 19:04:05 +00:00
{ 1 , 3 , 5 , 7 , 9 , 11 , 13 , 15 , 17 , 19 , 21 , 23 , 25 , 27 , 29 , 31 } , // SKINCOLOR_CLOUDY
2018-07-11 02:59:19 +00:00
{ 8 , 9 , 10 , 12 , 13 , 15 , 16 , 19 , 19 , 20 , 21 , 23 , 25 , 27 , 29 , 31 } , // SKINCOLOR_GREY
{ 16 , 16 , 17 , 18 , 19 , 20 , 21 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 } , // SKINCOLOR_NICKEL
2018-07-02 07:30:33 +00:00
{ 16 , 17 , 19 , 21 , 22 , 24 , 26 , 27 , 27 , 28 , 28 , 29 , 29 , 30 , 30 , 31 } , // SKINCOLOR_BLACK
{ 120 , 120 , 120 , 121 , 121 , 122 , 122 , 123 , 124 , 125 , 126 , 128 , 129 , 131 , 133 , 135 } , // SKINCOLOR_SALMON
{ 121 , 121 , 121 , 121 , 121 , 122 , 144 , 145 , 146 , 147 , 148 , 149 , 150 , 150 , 150 , 151 } , // SKINCOLOR_PINK
2018-07-11 02:59:19 +00:00
{ 144 , 145 , 146 , 147 , 148 , 149 , 150 , 151 , 134 , 135 , 136 , 137 , 138 , 139 , 140 , 141 } , // SKINCOLOR_ROSE
2018-07-02 07:30:33 +00:00
{ 120 , 121 , 122 , 123 , 124 , 125 , 126 , 127 , 128 , 130 , 131 , 133 , 134 , 136 , 137 , 139 } , // SKINCOLOR_RASPBERRY
2017-10-26 19:04:05 +00:00
{ 125 , 126 , 127 , 128 , 129 , 130 , 131 , 132 , 133 , 134 , 135 , 136 , 137 , 138 , 139 , 140 } , // SKINCOLOR_RED
2018-07-11 02:59:19 +00:00
{ 120 , 121 , 144 , 146 , 149 , 132 , 132 , 133 , 134 , 135 , 197 , 197 , 198 , 198 , 199 , 255 } , // SKINCOLOR_RUBY
2018-07-02 07:30:33 +00:00
{ 130 , 131 , 132 , 133 , 134 , 136 , 137 , 138 , 139 , 139 , 140 , 140 , 141 , 141 , 142 , 143 } , // SKINCOLOR_CRIMSON
{ 120 , 121 , 122 , 123 , 124 , 147 , 147 , 148 , 90 , 91 , 92 , 93 , 94 , 95 , 152 , 154 } , // SKINCOLOR_DAWN
2018-07-11 02:59:19 +00:00
{ 120 , 120 , 80 , 80 , 81 , 82 , 83 , 83 , 84 , 85 , 86 , 88 , 89 , 91 , 93 , 95 } , // SKINCOLOR_CREAMSICLE
2018-07-02 07:30:33 +00:00
{ 80 , 81 , 82 , 83 , 84 , 85 , 86 , 88 , 89 , 91 , 94 , 95 , 154 , 156 , 158 , 159 } , // SKINCOLOR_ORANGE
{ 84 , 85 , 86 , 87 , 88 , 90 , 92 , 93 , 94 , 95 , 152 , 153 , 154 , 156 , 157 , 159 } , // SKINCOLOR_PUMPKIN
{ 90 , 91 , 92 , 93 , 94 , 152 , 153 , 154 , 155 , 156 , 157 , 158 , 159 , 139 , 141 , 143 } , // SKINCOLOR_ROSEWOOD
{ 94 , 95 , 152 , 153 , 154 , 156 , 157 , 159 , 141 , 141 , 141 , 142 , 142 , 143 , 143 , 31 } , // SKINCOLOR_BURGUNDY
2018-07-11 02:59:19 +00:00
{ 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 156 , 157 , 158 , 159 , 141 , 141 , 142 , 143 } , // SKINCOLOR_BRONZE
2018-07-06 18:22:48 +00:00
{ 0 , 1 , 3 , 5 , 7 , 9 , 34 , 36 , 38 , 40 , 42 , 44 , 60 , 61 , 62 , 63 } , // SKINCOLOR_SEPIA
2017-10-26 19:04:05 +00:00
{ 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 } , // SKINCOLOR_BEIGE
{ 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 } , // SKINCOLOR_BROWN
2018-07-02 07:30:33 +00:00
{ 51 , 52 , 53 , 55 , 56 , 57 , 58 , 60 , 61 , 63 , 28 , 28 , 29 , 29 , 30 , 31 } , // SKINCOLOR_LEATHER
{ 64 , 65 , 67 , 68 , 70 , 71 , 73 , 74 , 76 , 77 , 79 , 48 , 50 , 53 , 56 , 59 } , // SKINCOLOR_PEACH
{ 64 , 66 , 68 , 70 , 72 , 74 , 76 , 78 , 48 , 50 , 52 , 54 , 56 , 58 , 60 , 62 } , // SKINCOLOR_CARAMEL
2018-07-11 02:59:19 +00:00
{ 98 , 98 , 112 , 112 , 113 , 113 , 84 , 85 , 87 , 89 , 91 , 93 , 95 , 153 , 156 , 159 } , // SKINCOLOR_TANGERINE
{ 112 , 112 , 112 , 113 , 113 , 114 , 114 , 115 , 115 , 116 , 116 , 117 , 117 , 118 , 118 , 119 } , // SKINCOLOR_GOLD
2017-10-26 19:04:05 +00:00
{ 121 , 144 , 145 , 72 , 73 , 84 , 114 , 115 , 107 , 108 , 109 , 183 , 223 , 207 , 30 , 246 } , // SKINCOLOR_VOMIT
2018-07-11 02:59:19 +00:00
{ 96 , 97 , 98 , 100 , 101 , 102 , 104 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 156 , 159 } , // SKINCOLOR_YELLOW
{ 96 , 97 , 99 , 100 , 102 , 104 , 105 , 105 , 106 , 107 , 107 , 108 , 109 , 109 , 110 , 111 } , // SKINCOLOR_CANARY
{ 105 , 105 , 105 , 106 , 106 , 107 , 107 , 108 , 108 , 109 , 109 , 110 , 110 , 111 , 111 , 31 } , // SKINCOLOR_OLIVE
2018-07-02 07:30:33 +00:00
{ 98 , 99 , 112 , 101 , 113 , 114 , 106 , 179 , 180 , 180 , 181 , 182 , 183 , 173 , 174 , 175 } , // SKINCOLOR_GARDEN
2018-07-11 02:59:19 +00:00
{ 96 , 97 , 99 , 100 , 102 , 104 , 160 , 162 , 164 , 166 , 168 , 171 , 223 , 223 , 207 , 31 } , // SKINCOLOR_LIME
2018-07-02 07:30:33 +00:00
{ 120 , 120 , 176 , 176 , 176 , 177 , 177 , 178 , 178 , 179 , 180 , 180 , 181 , 181 , 182 , 183 } , // SKINCOLOR_TEA
{ 176 , 176 , 176 , 177 , 177 , 178 , 178 , 179 , 179 , 180 , 180 , 181 , 181 , 182 , 182 , 183 } , // SKINCOLOR_ARMY
{ 120 , 120 , 176 , 176 , 177 , 177 , 178 , 179 , 165 , 166 , 167 , 168 , 169 , 170 , 171 , 172 } , // SKINCOLOR_PISTACHIO
{ 178 , 178 , 178 , 179 , 179 , 180 , 181 , 182 , 183 , 172 , 172 , 173 , 173 , 174 , 174 , 175 } , // SKINCOLOR_MOSS
2018-07-02 17:54:01 +00:00
{ 120 , 176 , 176 , 176 , 177 , 163 , 164 , 165 , 167 , 221 , 221 , 222 , 223 , 207 , 207 , 31 } , // SKINCOLOR_MINT
2017-10-26 19:04:05 +00:00
{ 160 , 161 , 162 , 163 , 164 , 165 , 166 , 167 , 168 , 169 , 170 , 171 , 172 , 173 , 174 , 175 } , // SKINCOLOR_GREEN
2018-07-11 02:59:19 +00:00
{ 176 , 176 , 177 , 178 , 165 , 166 , 167 , 167 , 168 , 169 , 182 , 182 , 182 , 183 , 183 , 183 } , // SKINCOLOR_ROBOHOOD
2018-07-02 07:30:33 +00:00
{ 160 , 161 , 162 , 164 , 165 , 167 , 169 , 170 , 171 , 171 , 172 , 173 , 174 , 175 , 30 , 31 } , // SKINCOLOR_PINETREE
2018-07-11 02:59:19 +00:00
{ 160 , 184 , 184 , 185 , 185 , 186 , 186 , 187 , 187 , 188 , 188 , 189 , 189 , 190 , 191 , 175 } , // SKINCOLOR_EMERALD
2018-07-02 07:30:33 +00:00
{ 186 , 187 , 188 , 188 , 188 , 189 , 189 , 190 , 190 , 191 , 175 , 175 , 30 , 30 , 31 , 31 } , // SKINCOLOR_SWAMP
2018-07-02 12:20:04 +00:00
{ 120 , 208 , 208 , 210 , 212 , 214 , 220 , 220 , 220 , 221 , 221 , 222 , 222 , 223 , 223 , 191 } , // SKINCOLOR_AQUA
2018-07-02 07:30:33 +00:00
{ 210 , 213 , 220 , 220 , 220 , 221 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 191 , 31 } , // SKINCOLOR_TEAL
2018-07-11 02:59:19 +00:00
{ 120 , 208 , 209 , 210 , 211 , 212 , 213 , 215 , 216 , 216 , 216 , 217 , 217 , 218 , 218 , 219 } , // SKINCOLOR_CYAN
{ 208 , 209 , 211 , 213 , 215 , 216 , 216 , 217 , 217 , 218 , 218 , 219 , 205 , 206 , 207 , 207 } , // SKINCOLOR_CERULEAN
{ 120 , 120 , 200 , 200 , 200 , 201 , 201 , 201 , 202 , 202 , 202 , 203 , 204 , 205 , 206 , 207 } , // SKINCOLOR_SLATE
2018-07-02 07:30:33 +00:00
{ 120 , 200 , 200 , 201 , 201 , 202 , 202 , 203 , 203 , 204 , 204 , 205 , 205 , 206 , 207 , 31 } , // SKINCOLOR_STEEL
2018-07-11 02:59:19 +00:00
{ 120 , 224 , 225 , 226 , 226 , 227 , 228 , 228 , 229 , 230 , 231 , 234 , 235 , 237 , 239 , 241 } , // SKINCOLOR_PERIWINKLE
2017-10-26 19:04:05 +00:00
{ 224 , 225 , 226 , 227 , 228 , 229 , 230 , 231 , 232 , 233 , 234 , 235 , 236 , 237 , 238 , 239 } , // SKINCOLOR_BLUE
2018-07-06 18:22:48 +00:00
{ 208 , 209 , 211 , 213 , 215 , 217 , 229 , 230 , 232 , 234 , 236 , 238 , 240 , 242 , 244 , 246 } , // SKINCOLOR_SAPPHIRE
2018-07-02 17:54:01 +00:00
{ 228 , 229 , 230 , 231 , 232 , 233 , 234 , 235 , 237 , 238 , 239 , 240 , 242 , 243 , 244 , 245 } , // SKINCOLOR_BLUEBERRY
2018-07-11 02:59:19 +00:00
{ 215 , 216 , 217 , 218 , 204 , 205 , 206 , 237 , 238 , 239 , 240 , 241 , 242 , 243 , 244 , 245 } , // SKINCOLOR_NAVY
2018-07-02 07:30:33 +00:00
{ 200 , 201 , 202 , 203 , 204 , 205 , 206 , 207 , 28 , 28 , 29 , 29 , 30 , 30 , 31 , 31 } , // SKINCOLOR_JET
{ 192 , 192 , 248 , 249 , 250 , 251 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 29 , 30 , 31 } , // SKINCOLOR_DUSK
{ 192 , 192 , 192 , 193 , 193 , 194 , 194 , 195 , 195 , 196 , 196 , 197 , 197 , 198 , 198 , 199 } , // SKINCOLOR_PURPLE
{ 248 , 248 , 248 , 249 , 249 , 250 , 250 , 251 , 251 , 252 , 252 , 253 , 253 , 254 , 254 , 255 } , // SKINCOLOR_LAVENDER
2017-10-26 19:04:05 +00:00
{ 192 , 193 , 194 , 195 , 196 , 197 , 198 , 199 , 255 , 255 , 29 , 29 , 30 , 30 , 31 , 31 } , // SKINCOLOR_INDIGO
2018-07-11 02:59:19 +00:00
{ 192 , 248 , 249 , 250 , 251 , 252 , 253 , 254 , 255 , 255 , 29 , 29 , 30 , 30 , 31 , 31 } , // SKINCOLOR_BYZANTIUM
{ 120 , 120 , 120 , 121 , 121 , 122 , 122 , 123 , 192 , 248 , 249 , 250 , 251 , 252 , 253 , 254 } , // SKINCOLOR_LILAC
2017-10-26 19:04:05 +00:00
/* Removed Colours
2018-07-02 17:54:01 +00:00
{ 120 , 121 , 123 , 124 , 126 , 127 , 129 , 130 , 132 , 133 , 135 , 136 , 138 , 139 , 141 , 143 } , // SKINCOLOR_RUBY, removed for other colors
{ 80 , 81 , 83 , 85 , 86 , 88 , 90 , 91 , 93 , 95 , 152 , 153 , 154 , 156 , 157 , 159 } , // SKINCOLOR_AMBER, removed for other colors
{ 224 , 225 , 226 , 228 , 229 , 231 , 232 , 234 , 235 , 237 , 238 , 240 , 241 , 243 , 244 , 246 } , // SKINCOLOR_SAPPHIRE, removed for other colors
{ 160 , 160 , 160 , 184 , 184 , 184 , 185 , 185 , 185 , 186 , 187 , 187 , 188 , 188 , 189 , 190 } , // SKINCOLOR_JADE, removed for other colors
{ 224 , 225 , 226 , 212 , 213 , 213 , 214 , 215 , 220 , 221 , 172 , 222 , 173 , 223 , 174 , 175 } , // SKINCOLOR_FROST, merged into Aqua
2018-07-04 21:25:38 +00:00
{ 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 } , // SKINCOLOR_CARAMEL, new Caramel was previously Shiny Caramel
2018-07-02 07:30:33 +00:00
{ 1 , 145 , 125 , 73 , 83 , 114 , 106 , 180 , 187 , 168 , 219 , 205 , 236 , 206 , 199 , 255 } , // SKINCOLOR_RAINBOW, is Vomit 2.0
2017-10-26 19:04:05 +00:00
*/
} ;
2016-08-12 01:42:11 +00:00
2018-02-05 23:55:52 +00:00
/** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power
2016-08-12 01:42:11 +00:00
2017-10-26 19:04:05 +00:00
\ param dest_colormap colormap to populate
\ param skincolor translation color
2016-08-12 01:42:11 +00:00
*/
2018-02-05 23:55:52 +00:00
void K_RainbowColormap ( UINT8 * dest_colormap , UINT8 skincolor )
2016-08-12 01:42:11 +00:00
{
2017-10-26 19:04:05 +00:00
INT32 i , j ;
RGBA_t color ;
UINT8 colorbrightnesses [ 16 ] ;
UINT8 brightness ;
UINT16 brightdif ;
INT32 temp ;
2017-02-17 20:14:55 +00:00
2017-10-26 19:04:05 +00:00
// first generate the brightness of all the colours of that skincolour
for ( i = 0 ; i < 16 ; i + + )
2016-08-12 01:42:11 +00:00
{
2017-10-26 19:04:05 +00:00
color = V_GetColor ( colortranslations [ skincolor ] [ i ] ) ;
colorbrightnesses [ i ] = ( UINT8 ) ( ( ( UINT16 ) color . s . red + ( UINT16 ) color . s . green + ( UINT16 ) color . s . blue ) / 3 ) ;
2017-02-17 20:14:55 +00:00
}
2017-10-26 19:04:05 +00:00
// next, for every colour in the palette, choose the transcolor that has the closest brightness
for ( i = 0 ; i < NUM_PALETTE_ENTRIES ; i + + )
2016-08-12 01:42:11 +00:00
{
2018-02-05 02:53:55 +00:00
if ( i = = 0 | | i = = 31 | | i = = 120 ) // pure black and pure white don't change
{
dest_colormap [ i ] = ( UINT8 ) i ;
continue ;
}
2017-10-26 19:04:05 +00:00
color = V_GetColor ( i ) ;
brightness = ( UINT8 ) ( ( ( UINT16 ) color . s . red + ( UINT16 ) color . s . green + ( UINT16 ) color . s . blue ) / 3 ) ;
brightdif = 256 ;
for ( j = 0 ; j < 16 ; j + + )
{
temp = abs ( ( INT16 ) brightness - ( INT16 ) colorbrightnesses [ j ] ) ;
if ( temp < brightdif )
{
brightdif = ( UINT16 ) temp ;
dest_colormap [ i ] = colortranslations [ skincolor ] [ j ] ;
}
}
}
2016-08-12 01:42:11 +00:00
}
/** \brief Generates a translation colormap for Kart, to replace R_GenerateTranslationColormap in r_draw.c
\ param dest_colormap colormap to populate
\ param skinnum number of skin , TC_DEFAULT or TC_BOSS
\ param color translation color
\ return void
*/
void K_GenerateKartColormap ( UINT8 * dest_colormap , INT32 skinnum , UINT8 color )
{
INT32 i ;
INT32 starttranscolor ;
// Handle a couple of simple special cases
if ( skinnum = = TC_BOSS | | skinnum = = TC_ALLWHITE | | skinnum = = TC_METALSONIC | | color = = SKINCOLOR_NONE )
{
for ( i = 0 ; i < NUM_PALETTE_ENTRIES ; i + + )
{
if ( skinnum = = TC_ALLWHITE ) dest_colormap [ i ] = 0 ;
else dest_colormap [ i ] = ( UINT8 ) i ;
}
// White!
if ( skinnum = = TC_BOSS )
dest_colormap [ 31 ] = 0 ;
else if ( skinnum = = TC_METALSONIC )
dest_colormap [ 239 ] = 0 ;
return ;
}
2018-02-05 23:55:52 +00:00
else if ( skinnum = = TC_RAINBOW )
2017-10-26 19:04:05 +00:00
{
2018-02-05 23:55:52 +00:00
K_RainbowColormap ( dest_colormap , color ) ;
2017-10-26 19:04:05 +00:00
return ;
}
2016-08-12 01:42:11 +00:00
starttranscolor = ( skinnum ! = TC_DEFAULT ) ? skins [ skinnum ] . starttranscolor : DEFAULT_STARTTRANSCOLOR ;
// Fill in the entries of the palette that are fixed
for ( i = 0 ; i < starttranscolor ; i + + )
dest_colormap [ i ] = ( UINT8 ) i ;
for ( i = ( UINT8 ) ( starttranscolor + 16 ) ; i < NUM_PALETTE_ENTRIES ; i + + )
dest_colormap [ i ] = ( UINT8 ) i ;
// Build the translated ramp
for ( i = 0 ; i < SKIN_RAMP_LENGTH ; i + + )
2017-10-26 19:04:05 +00:00
{
// Sryder 2017-10-26: What was here before was most definitely not particularly readable, check above for new color translation table
dest_colormap [ starttranscolor + i ] = colortranslations [ color ] [ i ] ;
}
2016-08-12 01:42:11 +00:00
}
/** \brief Pulls kart color by name, to replace R_GetColorByName in r_draw.c
\ param name color name
\ return 0
*/
UINT8 K_GetKartColorByName ( const char * name )
{
UINT8 color = ( UINT8 ) atoi ( name ) ;
if ( color > 0 & & color < MAXSKINCOLORS )
return color ;
for ( color = 1 ; color < MAXSKINCOLORS ; color + + )
if ( ! stricmp ( KartColor_Names [ color ] , name ) )
return color ;
return 0 ;
}
//}
2016-08-15 03:51:08 +00:00
//{ SRB2kart Net Variables
2016-08-12 01:42:11 +00:00
2016-08-15 03:51:08 +00:00
void K_RegisterKartStuff ( void )
{
2018-02-05 23:55:52 +00:00
CV_RegisterVar ( & cv_sneaker ) ;
CV_RegisterVar ( & cv_rocketsneaker ) ;
CV_RegisterVar ( & cv_invincibility ) ;
2016-08-15 03:51:08 +00:00
CV_RegisterVar ( & cv_banana ) ;
2018-03-14 01:07:08 +00:00
CV_RegisterVar ( & cv_eggmanmonitor ) ;
2018-02-05 23:55:52 +00:00
CV_RegisterVar ( & cv_orbinaut ) ;
CV_RegisterVar ( & cv_jawz ) ;
CV_RegisterVar ( & cv_mine ) ;
CV_RegisterVar ( & cv_ballhog ) ;
CV_RegisterVar ( & cv_selfpropelledbomb ) ;
2018-02-10 06:19:33 +00:00
CV_RegisterVar ( & cv_grow ) ;
CV_RegisterVar ( & cv_shrink ) ;
2018-08-04 19:48:31 +00:00
CV_RegisterVar ( & cv_thundershield ) ;
2018-02-05 23:55:52 +00:00
CV_RegisterVar ( & cv_hyudoro ) ;
CV_RegisterVar ( & cv_pogospring ) ;
2018-08-31 17:18:19 +00:00
CV_RegisterVar ( & cv_kitchensink ) ;
2018-02-05 23:55:52 +00:00
CV_RegisterVar ( & cv_triplesneaker ) ;
CV_RegisterVar ( & cv_triplebanana ) ;
2018-08-31 17:18:19 +00:00
CV_RegisterVar ( & cv_decabanana ) ;
2018-02-05 23:55:52 +00:00
CV_RegisterVar ( & cv_tripleorbinaut ) ;
2018-08-31 17:18:19 +00:00
CV_RegisterVar ( & cv_quadorbinaut ) ;
2018-02-05 23:55:52 +00:00
CV_RegisterVar ( & cv_dualjawz ) ;
2017-02-13 04:24:49 +00:00
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
CV_RegisterVar ( & cv_kartminimap ) ;
2017-11-02 04:35:10 +00:00
CV_RegisterVar ( & cv_kartcheck ) ;
2018-06-15 00:18:29 +00:00
CV_RegisterVar ( & cv_kartinvinsfx ) ;
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
CV_RegisterVar ( & cv_kartspeed ) ;
2018-07-03 19:14:47 +00:00
CV_RegisterVar ( & cv_kartbumpers ) ;
2017-11-01 22:46:35 +00:00
CV_RegisterVar ( & cv_kartfrantic ) ;
2017-11-14 01:45:57 +00:00
CV_RegisterVar ( & cv_kartcomeback ) ;
2017-12-12 05:07:14 +00:00
CV_RegisterVar ( & cv_kartmirror ) ;
2018-06-15 00:18:29 +00:00
CV_RegisterVar ( & cv_kartspeedometer ) ;
2018-07-29 17:35:56 +00:00
CV_RegisterVar ( & cv_kartvoices ) ;
2018-07-25 20:33:03 +00:00
CV_RegisterVar ( & cv_karteliminatelast ) ;
2018-01-28 04:52:01 +00:00
CV_RegisterVar ( & cv_votetime ) ;
2018-02-05 23:55:52 +00:00
CV_RegisterVar ( & cv_kartdebugitem ) ;
CV_RegisterVar ( & cv_kartdebugamount ) ;
2018-07-12 05:31:33 +00:00
CV_RegisterVar ( & cv_kartdebugshrink ) ;
2018-08-29 18:28:28 +00:00
CV_RegisterVar ( & cv_kartdebugdistribution ) ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
CV_RegisterVar ( & cv_kartdebughuddrop ) ;
2018-08-29 18:28:28 +00:00
CV_RegisterVar ( & cv_kartdebugcheckpoint ) ;
2016-08-15 03:51:08 +00:00
}
//}
Winning positions scale with number of players
Anyone in the top 50% gets winning music & blue position, everyone below
gets the losing music & red position. For odd numbers, it rounds up.
2p: 1st wins, 2nd loses
3p: 1-2 win, 3rd loses
4p: 1-2 win, 3-4 lose
5p: 1-3 win, 4-5 lose
6p: 1-3 win, 4-6 lose
7p: 1-4 win, 5-7 lose
8p: 1-4 win, 5-8 lose (SMK)
12p: 1-6 win, 7-12 lose (modern MK)
16p: 1-8 win, 9-16 lose (max player count)
In big netgames you won't just hear the losing music all of the time now
:V
2018-02-21 00:11:09 +00:00
boolean K_IsPlayerLosing ( player_t * player )
{
INT32 winningpos = 1 ;
UINT8 i , pcount = 0 ;
if ( player - > kartstuff [ k_position ] = = 1 )
return false ;
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-07-12 23:04:37 +00:00
if ( ! playeringame [ i ] | | players [ i ] . spectator )
continue ;
if ( players [ i ] . kartstuff [ k_position ] > pcount )
pcount = players [ i ] . kartstuff [ k_position ] ;
Winning positions scale with number of players
Anyone in the top 50% gets winning music & blue position, everyone below
gets the losing music & red position. For odd numbers, it rounds up.
2p: 1st wins, 2nd loses
3p: 1-2 win, 3rd loses
4p: 1-2 win, 3-4 lose
5p: 1-3 win, 4-5 lose
6p: 1-3 win, 4-6 lose
7p: 1-4 win, 5-7 lose
8p: 1-4 win, 5-8 lose (SMK)
12p: 1-6 win, 7-12 lose (modern MK)
16p: 1-8 win, 9-16 lose (max player count)
In big netgames you won't just hear the losing music all of the time now
:V
2018-02-21 00:11:09 +00:00
}
if ( pcount < = 1 )
return false ;
winningpos = pcount / 2 ;
if ( pcount % 2 ) // any remainder?
winningpos + + ;
return ( player - > kartstuff [ k_position ] > winningpos ) ;
}
2018-07-01 08:36:09 +00:00
boolean K_IsPlayerWanted ( player_t * player )
{
UINT8 i ;
if ( ! ( G_BattleGametype ( ) ) )
return false ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( battlewanted [ i ] = = - 1 )
break ;
if ( player = = & players [ battlewanted [ i ] ] )
return true ;
}
return false ;
}
2017-05-07 23:08:03 +00:00
//{ SRB2kart Roulette Code - Position Based
2016-08-15 03:51:08 +00:00
2018-07-19 07:31:14 +00:00
# define NUMKARTODDS 80
2016-08-15 03:51:08 +00:00
2017-05-07 23:08:03 +00:00
// Less ugly 2D arrays
2018-06-07 23:39:45 +00:00
static INT32 K_KartItemOddsRace [ NUMKARTRESULTS ] [ 9 ] =
2017-05-07 23:08:03 +00:00
{
2017-11-23 02:40:17 +00:00
//P-Odds 0 1 2 3 4 5 6 7 8
2018-09-08 02:17:38 +00:00
/*Sneaker*/ { 20 , 0 , 0 , 3 , 6 , 5 , 0 , 0 , 0 } , // Sneaker
/*Rocket Sneaker*/ { 0 , 0 , 0 , 0 , 0 , 2 , 6 , 5 , 0 } , // Rocket Sneaker
2018-07-27 21:56:10 +00:00
/*Invincibility*/ { 0 , 0 , 0 , 0 , 0 , 1 , 5 , 6 , 16 } , // Invincibility
2018-09-08 02:17:38 +00:00
/*Banana*/ { 0 , 9 , 3 , 2 , 1 , 0 , 0 , 0 , 0 } , // Banana
2018-06-19 01:52:26 +00:00
/*Eggman Monitor*/ { 0 , 4 , 3 , 2 , 0 , 0 , 0 , 0 , 0 } , // Eggman Monitor
2018-09-08 02:17:38 +00:00
/*Orbinaut*/ { 0 , 6 , 3 , 4 , 2 , 0 , 0 , 0 , 0 } , // Orbinaut
2018-02-05 23:55:52 +00:00
/*Jawz*/ { 0 , 0 , 3 , 2 , 2 , 1 , 0 , 0 , 0 } , // Jawz
2018-06-25 14:18:29 +00:00
/*Mine*/ { 0 , 0 , 1 , 2 , 1 , 0 , 0 , 0 , 0 } , // Mine
2018-09-08 02:17:38 +00:00
/*Ballhog*/ { 0 , 0 , 2 , 2 , 1 , 0 , 0 , 0 , 0 } , // Ballhog
2018-07-05 04:38:23 +00:00
/*Self-Propelled Bomb*/ { 0 , 0 , 1 , 1 , 1 , 2 , 2 , 3 , 2 } , // Self-Propelled Bomb
2018-08-10 02:52:22 +00:00
/*Grow*/ { 0 , 0 , 0 , 0 , 0 , 1 , 3 , 6 , 4 } , // Grow
2018-09-08 02:17:38 +00:00
/*Shrink*/ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 0 } , // Shrink
2018-08-04 19:48:31 +00:00
/*Thunder Shield*/ { 0 , 1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 } , // Thunder Shield
2018-06-19 01:52:26 +00:00
/*Hyudoro*/ { 0 , 0 , 0 , 0 , 1 , 2 , 1 , 0 , 0 } , // Hyudoro
2018-02-05 23:55:52 +00:00
/*Pogo Spring*/ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , // Pogo Spring
/*Kitchen Sink*/ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , // Kitchen Sink
2018-09-08 02:17:38 +00:00
/*Sneaker x3*/ { 0 , 0 , 0 , 0 , 3 , 8 , 5 , 2 , 0 } , // Sneaker x3
/*Banana x3*/ { 0 , 0 , 2 , 1 , 0 , 0 , 0 , 0 , 0 } , // Banana x3
2018-06-17 00:01:25 +00:00
/*Banana x10*/ { 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 } , // Banana x10
2018-09-08 02:17:38 +00:00
/*Orbinaut x3*/ { 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 } , // Orbinaut x3
/*Orbinaut x4*/ { 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 } , // Orbinaut x4
/*Jawz x2*/ { 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 } // Jawz x2
2017-11-23 02:40:17 +00:00
} ;
2018-06-07 23:39:45 +00:00
static INT32 K_KartItemOddsBattle [ NUMKARTRESULTS ] [ 6 ] =
2017-11-23 02:40:17 +00:00
{
2018-08-26 18:58:21 +00:00
//P-Odds 0 1 2 3 4 5
2018-08-26 23:55:31 +00:00
/*Sneaker*/ { 3 , 2 , 2 , 2 , 0 , 2 } , // Sneaker
2018-08-26 18:58:21 +00:00
/*Rocket Sneaker*/ { 0 , 0 , 0 , 0 , 0 , 0 } , // Rocket Sneaker
2018-08-26 23:55:31 +00:00
/*Invincibility*/ { 0 , 1 , 2 , 3 , 4 , 2 } , // Invincibility
2018-08-26 18:58:21 +00:00
/*Banana*/ { 2 , 1 , 0 , 0 , 0 , 0 } , // Banana
2018-08-26 23:55:31 +00:00
/*Eggman Monitor*/ { 1 , 1 , 0 , 0 , 0 , 0 } , // Eggman Monitor
/*Orbinaut*/ { 6 , 2 , 1 , 0 , 0 , 0 } , // Orbinaut
/*Jawz*/ { 3 , 3 , 3 , 2 , 0 , 2 } , // Jawz
/*Mine*/ { 2 , 3 , 3 , 1 , 0 , 2 } , // Mine
/*Ballhog*/ { 0 , 1 , 2 , 1 , 0 , 2 } , // Ballhog
2018-08-26 18:58:21 +00:00
/*Self-Propelled Bomb*/ { 0 , 0 , 0 , 0 , 0 , 0 } , // Self-Propelled Bomb
2018-08-26 23:55:31 +00:00
/*Grow*/ { 0 , 0 , 1 , 2 , 4 , 2 } , // Grow
2018-08-26 18:58:21 +00:00
/*Shrink*/ { 0 , 0 , 0 , 0 , 0 , 0 } , // Shrink
/*Thunder Shield*/ { 0 , 0 , 0 , 0 , 0 , 0 } , // Thunder Shield
/*Hyudoro*/ { 1 , 1 , 0 , 0 , 0 , 0 } , // Hyudoro
/*Pogo Spring*/ { 1 , 1 , 0 , 0 , 0 , 0 } , // Pogo Spring
/*Kitchen Sink*/ { 0 , 0 , 0 , 0 , 0 , 0 } , // Kitchen Sink
/*Sneaker x3*/ { 0 , 0 , 0 , 2 , 4 , 2 } , // Sneaker x3
2018-08-26 23:55:31 +00:00
/*Banana x3*/ { 1 , 2 , 1 , 0 , 0 , 0 } , // Banana x3
2018-08-26 18:58:21 +00:00
/*Banana x10*/ { 0 , 0 , 1 , 1 , 0 , 2 } , // Banana x10
2018-08-26 23:55:31 +00:00
/*Orbinaut x3*/ { 0 , 1 , 2 , 1 , 0 , 0 } , // Orbinaut x3
2018-08-26 18:58:21 +00:00
/*Orbinaut x4*/ { 0 , 0 , 1 , 3 , 4 , 2 } , // Orbinaut x4
/*Jawz x2*/ { 0 , 0 , 1 , 2 , 4 , 2 } // Jawz x2
2017-05-07 23:08:03 +00:00
} ;
2016-08-15 03:51:08 +00:00
/** \brief Item Roulette for Kart
\ param player player
\ param getitem what item we ' re looking for
\ return void
*/
2018-06-07 23:39:45 +00:00
static void K_KartGetItemResult ( player_t * player , SINT8 getitem )
2016-08-15 03:51:08 +00:00
{
switch ( getitem )
{
2018-06-07 23:39:45 +00:00
// Special roulettes first, then the generic ones are handled by default
2018-02-05 23:55:52 +00:00
case KRITEM_TRIPLESNEAKER : // Sneaker x3
player - > kartstuff [ k_itemtype ] = KITEM_SNEAKER ;
player - > kartstuff [ k_itemamount ] = 3 ;
2016-08-15 03:51:08 +00:00
break ;
2018-02-05 23:55:52 +00:00
case KRITEM_TRIPLEBANANA : // Banana x3
player - > kartstuff [ k_itemtype ] = KITEM_BANANA ;
player - > kartstuff [ k_itemamount ] = 3 ;
2016-08-15 03:51:08 +00:00
break ;
2018-06-17 00:01:25 +00:00
case KRITEM_TENFOLDBANANA : // Banana x10
player - > kartstuff [ k_itemtype ] = KITEM_BANANA ;
player - > kartstuff [ k_itemamount ] = 10 ;
break ;
2018-02-05 23:55:52 +00:00
case KRITEM_TRIPLEORBINAUT : // Orbinaut x3
player - > kartstuff [ k_itemtype ] = KITEM_ORBINAUT ;
player - > kartstuff [ k_itemamount ] = 3 ;
2016-08-15 03:51:08 +00:00
break ;
2018-08-10 02:52:22 +00:00
case KRITEM_QUADORBINAUT : // Orbinaut x4
player - > kartstuff [ k_itemtype ] = KITEM_ORBINAUT ;
player - > kartstuff [ k_itemamount ] = 4 ;
break ;
2018-02-05 23:55:52 +00:00
case KRITEM_DUALJAWZ : // Jawz x2
player - > kartstuff [ k_itemtype ] = KITEM_JAWZ ;
player - > kartstuff [ k_itemamount ] = 2 ;
2016-08-15 03:51:08 +00:00
break ;
2018-02-05 23:55:52 +00:00
default :
if ( getitem < = 0 | | getitem > = NUMKARTRESULTS ) // Sad (Fallback)
{
if ( getitem ! = 0 )
CONS_Printf ( " ERROR: P_KartGetItemResult - Item roulette gave bad item (%d) :( \n " , getitem ) ;
player - > kartstuff [ k_itemtype ] = KITEM_SAD ;
}
2016-08-15 03:51:08 +00:00
else
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemtype ] = getitem ;
player - > kartstuff [ k_itemamount ] = 1 ;
2016-08-15 03:51:08 +00:00
break ;
}
}
/** \brief Item Roulette for Kart
\ param player player object passed from P_KartPlayerThink
\ return void
Winning positions scale with number of players
Anyone in the top 50% gets winning music & blue position, everyone below
gets the losing music & red position. For odd numbers, it rounds up.
2p: 1st wins, 2nd loses
3p: 1-2 win, 3rd loses
4p: 1-2 win, 3-4 lose
5p: 1-3 win, 4-5 lose
6p: 1-3 win, 4-6 lose
7p: 1-4 win, 5-7 lose
8p: 1-4 win, 5-8 lose (SMK)
12p: 1-6 win, 7-12 lose (modern MK)
16p: 1-8 win, 9-16 lose (max player count)
In big netgames you won't just hear the losing music all of the time now
:V
2018-02-21 00:11:09 +00:00
*/
2017-03-06 02:38:35 +00:00
2018-07-19 07:31:14 +00:00
static INT32 K_KartGetItemOdds ( UINT8 pos , SINT8 item , fixed_t mashed )
2016-08-15 03:51:08 +00:00
{
2018-06-11 05:51:50 +00:00
const INT32 distvar = ( 64 * 14 ) ;
2018-02-05 23:55:52 +00:00
INT32 newodds ;
2017-03-04 22:13:19 +00:00
INT32 i ;
2018-06-20 00:20:06 +00:00
UINT8 pingame = 0 , pexiting = 0 , pinvin = 0 ;
2018-07-10 22:37:46 +00:00
SINT8 first = - 1 , second = - 1 ;
2018-06-08 04:02:28 +00:00
INT32 secondist = 0 ;
2017-03-04 22:13:19 +00:00
2018-03-12 04:58:13 +00:00
if ( G_BattleGametype ( ) )
2018-06-07 23:39:45 +00:00
newodds = K_KartItemOddsBattle [ item - 1 ] [ pos ] ;
2016-08-15 03:51:08 +00:00
else
2018-06-07 23:39:45 +00:00
newodds = K_KartItemOddsRace [ item - 1 ] [ pos ] ;
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-06-20 00:20:06 +00:00
if ( ! playeringame [ i ] | | players [ i ] . spectator )
continue ;
pingame + + ;
2016-08-15 03:51:08 +00:00
if ( players [ i ] . exiting )
pexiting + + ;
2018-06-20 00:20:06 +00:00
if ( players [ i ] . mo )
{
if ( players [ i ] . kartstuff [ k_position ] = = 1 & & first = = - 1 )
first = i ;
if ( players [ i ] . kartstuff [ k_position ] = = 2 & & second = = - 1 )
second = i ;
if ( players [ i ] . kartstuff [ k_itemtype ] = = KITEM_INVINCIBILITY
| | players [ i ] . kartstuff [ k_itemtype ] = = KITEM_GROW
| | players [ i ] . kartstuff [ k_invincibilitytimer ]
| | players [ i ] . kartstuff [ k_growshrinktimer ] > 0 )
pinvin + + ;
}
2016-08-15 03:51:08 +00:00
}
2017-02-17 20:14:55 +00:00
2018-06-08 04:02:28 +00:00
if ( first ! = - 1 & & second ! = - 1 ) // calculate 2nd's distance from 1st, for SPB
{
secondist = P_AproxDistance ( P_AproxDistance ( players [ first ] . mo - > x - players [ second ] . mo - > x ,
players [ first ] . mo - > y - players [ second ] . mo - > y ) ,
2018-07-05 04:38:23 +00:00
players [ first ] . mo - > z - players [ second ] . mo - > z ) / mapheaderinfo [ gamemap - 1 ] - > mobj_scale ;
2018-06-08 04:02:28 +00:00
if ( franticitems )
secondist = ( 15 * secondist / 14 ) ;
2018-08-29 03:06:31 +00:00
if ( pingame < 8 & & ! G_BattleGametype ( ) )
secondist = ( ( 28 + ( 8 - pingame ) ) * secondist / 28 ) ;
2018-06-08 04:02:28 +00:00
}
2018-07-19 07:31:14 +00:00
// POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items.
// First, it multiplies it by 2 if franticitems is true; easy-peasy.
// Then, it multiplies it further if there's less than 5 players in game.
// This is done to make low player count races more fair & interesting. (1v1s are basically the same as franticitems false in a normal race)
// Lastly, it *divides* it by your mashed value, which was determined in K_KartItemRoulette, to punish those who are impatient.
// The last two are very fractional and complicated, very sorry!
# define POWERITEMODDS(odds) \
if ( franticitems ) \
odds * = 2 ; \
2018-08-29 03:06:31 +00:00
if ( pingame < 8 & & ! G_BattleGametype ( ) ) \
odds = FixedMul ( odds * FRACUNIT , FRACUNIT + min ( ( 8 - pingame ) * ( FRACUNIT / 25 ) , FRACUNIT ) ) / FRACUNIT ; \
2018-07-19 07:31:14 +00:00
if ( mashed > 0 ) \
odds = FixedDiv ( odds * FRACUNIT , mashed + FRACUNIT ) / FRACUNIT \
2018-02-05 23:55:52 +00:00
switch ( item )
2016-08-15 03:51:08 +00:00
{
2018-02-05 23:55:52 +00:00
case KITEM_SNEAKER :
2018-06-11 05:51:50 +00:00
if ( ( ! cv_sneaker . value ) & & ( ! modeattacking ) ) newodds = 0 ;
2018-02-05 23:55:52 +00:00
break ;
case KITEM_ROCKETSNEAKER :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_rocketsneaker . value ) newodds = 0 ;
break ;
case KITEM_INVINCIBILITY :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-06-20 00:20:06 +00:00
if ( ( ! cv_invincibility . value ) | | ( pinvin > 2 ) ) newodds = 0 ;
2018-02-05 23:55:52 +00:00
break ;
case KITEM_BANANA :
if ( ! cv_banana . value ) newodds = 0 ;
break ;
2018-03-14 01:07:08 +00:00
case KITEM_EGGMAN :
if ( ! cv_eggmanmonitor . value ) newodds = 0 ;
2018-02-05 23:55:52 +00:00
break ;
case KITEM_ORBINAUT :
if ( ! cv_orbinaut . value ) newodds = 0 ;
break ;
case KITEM_JAWZ :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_jawz . value ) newodds = 0 ;
break ;
case KITEM_MINE :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_mine . value ) newodds = 0 ;
break ;
case KITEM_BALLHOG :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_ballhog . value ) newodds = 0 ;
break ;
case KITEM_SPB :
2018-08-26 23:55:31 +00:00
//POWERITEMODDS(newodds);
2018-06-11 05:51:50 +00:00
if ( ( ! cv_selfpropelledbomb . value )
| | ( indirectitemcooldown > 0 )
| | ( pexiting > 0 )
2018-07-19 07:31:14 +00:00
| | ( secondist / distvar < ( 4 + gamespeed ) ) )
2018-06-20 00:20:06 +00:00
newodds = 0 ;
2018-07-19 07:31:14 +00:00
newodds * = min ( ( secondist / distvar ) - ( 3 + gamespeed ) , 3 ) ;
2018-02-05 23:55:52 +00:00
break ;
2018-02-10 06:19:33 +00:00
case KITEM_GROW :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-06-20 00:20:06 +00:00
if ( ( ! cv_grow . value ) | | ( pinvin > 2 ) ) newodds = 0 ;
2018-02-05 23:55:52 +00:00
break ;
2018-02-10 06:19:33 +00:00
case KITEM_SHRINK :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-06-11 05:51:50 +00:00
if ( ( ! cv_shrink . value )
| | ( indirectitemcooldown > 0 )
| | ( pingame - 1 < = pexiting ) ) newodds = 0 ;
2018-02-05 23:55:52 +00:00
break ;
2018-08-04 19:48:31 +00:00
case KITEM_THUNDERSHIELD :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-08-04 19:48:31 +00:00
if ( ! cv_thundershield . value ) newodds = 0 ;
2018-02-05 23:55:52 +00:00
break ;
case KITEM_HYUDORO :
if ( ! cv_hyudoro . value ) newodds = 0 ;
break ;
case KITEM_POGOSPRING :
if ( ! cv_pogospring . value ) newodds = 0 ;
break ;
2018-06-25 05:36:21 +00:00
case KITEM_KITCHENSINK :
newodds = 0 ; // Not obtained via normal means.
break ;
2018-02-05 23:55:52 +00:00
case KRITEM_TRIPLESNEAKER :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_triplesneaker . value ) newodds = 0 ;
break ;
case KRITEM_TRIPLEBANANA :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_triplebanana . value ) newodds = 0 ;
break ;
2018-06-17 00:01:25 +00:00
case KRITEM_TENFOLDBANANA :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-08-31 17:18:19 +00:00
if ( ! cv_decabanana . value ) newodds = 0 ;
2018-06-17 00:01:25 +00:00
break ;
2018-02-05 23:55:52 +00:00
case KRITEM_TRIPLEORBINAUT :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_tripleorbinaut . value ) newodds = 0 ;
break ;
2018-08-10 02:52:22 +00:00
case KRITEM_QUADORBINAUT :
POWERITEMODDS ( newodds ) ;
2018-08-31 17:18:19 +00:00
if ( ! cv_quadorbinaut . value ) newodds = 0 ;
2018-08-10 02:52:22 +00:00
break ;
2018-02-05 23:55:52 +00:00
case KRITEM_DUALJAWZ :
2018-07-19 07:31:14 +00:00
POWERITEMODDS ( newodds ) ;
2018-02-05 23:55:52 +00:00
if ( ! cv_dualjawz . value ) newodds = 0 ;
break ;
default :
break ;
2016-08-15 03:51:08 +00:00
}
2018-07-19 07:31:14 +00:00
# undef POWERITEMODDS
2017-11-24 03:34:36 +00:00
2017-11-07 20:04:21 +00:00
return newodds ;
}
2017-05-07 23:08:03 +00:00
//{ SRB2kart Roulette Code - Distance Based, no waypoints
2018-08-29 18:28:28 +00:00
static INT32 K_FindUseodds ( player_t * player , fixed_t mashed , INT32 pingame , INT32 bestbumper )
2017-05-07 23:08:03 +00:00
{
2018-02-05 23:55:52 +00:00
const INT32 distvar = ( 64 * 14 ) ;
2017-05-07 23:08:03 +00:00
INT32 i ;
INT32 pdis = 0 , useodds = 0 ;
2018-02-05 23:55:52 +00:00
UINT8 disttable [ 14 ] ;
UINT8 distlen = 0 ;
2018-08-29 18:28:28 +00:00
boolean oddsvalid [ 9 ] ;
2017-05-07 23:08:03 +00:00
2018-02-05 23:55:52 +00:00
for ( i = 0 ; i < 9 ; i + + )
2017-05-07 23:08:03 +00:00
{
2018-02-05 23:55:52 +00:00
INT32 j ;
2018-06-25 14:18:29 +00:00
boolean available = false ;
2017-11-23 02:40:17 +00:00
2018-06-14 01:32:33 +00:00
if ( G_BattleGametype ( ) & & i > 5 )
2018-02-05 23:55:52 +00:00
{
2018-06-25 14:18:29 +00:00
oddsvalid [ i ] = false ;
2018-02-05 23:55:52 +00:00
break ;
}
for ( j = 0 ; j < NUMKARTRESULTS ; j + + )
{
2018-06-25 13:18:30 +00:00
if ( K_KartGetItemOdds ( i , j , mashed ) > 0 )
2018-02-05 23:55:52 +00:00
{
2018-06-25 14:18:29 +00:00
available = true ;
2018-02-05 23:55:52 +00:00
break ;
}
}
oddsvalid [ i ] = available ;
}
2017-11-23 02:40:17 +00:00
2017-11-24 03:34:36 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
2017-11-23 02:40:17 +00:00
{
2018-06-08 04:02:28 +00:00
if ( playeringame [ i ] & & ! players [ i ] . spectator & & players [ i ] . mo
& & players [ i ] . kartstuff [ k_position ] < player - > kartstuff [ k_position ] )
pdis + = P_AproxDistance ( P_AproxDistance ( players [ i ] . mo - > x - player - > mo - > x ,
players [ i ] . mo - > y - player - > mo - > y ) ,
players [ i ] . mo - > z - player - > mo - > z ) / mapheaderinfo [ gamemap - 1 ] - > mobj_scale
* ( pingame - players [ i ] . kartstuff [ k_position ] )
2018-06-06 22:36:39 +00:00
/ ( ( pingame - 1 ) * ( pingame + 1 ) / 3 ) ;
2018-06-08 04:02:28 +00:00
}
2018-06-06 22:36:39 +00:00
2018-02-05 23:55:52 +00:00
# define SETUPDISTTABLE(odds, num) \
for ( i = num ; i ; - - i ) disttable [ distlen + + ] = odds
2017-05-07 23:08:03 +00:00
2018-03-04 20:27:52 +00:00
if ( G_BattleGametype ( ) ) // Battle Mode
2017-11-23 02:40:17 +00:00
{
2018-02-05 23:55:52 +00:00
if ( oddsvalid [ 0 ] ) SETUPDISTTABLE ( 0 , 1 ) ;
if ( oddsvalid [ 1 ] ) SETUPDISTTABLE ( 1 , 1 ) ;
if ( oddsvalid [ 2 ] ) SETUPDISTTABLE ( 2 , 1 ) ;
2018-08-26 18:58:21 +00:00
if ( oddsvalid [ 3 ] ) SETUPDISTTABLE ( 3 , 1 ) ;
if ( oddsvalid [ 4 ] ) SETUPDISTTABLE ( 4 , 1 ) ;
2018-02-05 23:55:52 +00:00
2018-08-26 18:58:21 +00:00
if ( player - > kartstuff [ k_roulettetype ] = = 1 & & oddsvalid [ 5 ] ) // 5 is the extreme odds of player-controlled "Karma" items
useodds = 5 ;
2018-06-04 00:58:52 +00:00
else
{
2018-08-26 18:58:21 +00:00
SINT8 wantedpos = ( bestbumper - player - > kartstuff [ k_bumper ] ) ; // 0 is the best player's bumper count, 1 is a bumper below best, 2 is two bumpers below, etc
2018-08-06 17:37:03 +00:00
if ( K_IsPlayerWanted ( player ) )
2018-08-26 19:17:55 +00:00
wantedpos + + ;
2018-08-26 18:58:21 +00:00
if ( wantedpos > 4 ) // Don't run off into karma items
wantedpos = 4 ;
if ( wantedpos < 0 ) // Don't go below somehow
2018-07-02 22:23:18 +00:00
wantedpos = 0 ;
2018-08-26 18:58:21 +00:00
useodds = disttable [ ( wantedpos * distlen ) / 5 ] ;
2018-06-04 00:58:52 +00:00
}
2017-11-23 02:40:17 +00:00
}
else
{
2018-02-05 23:55:52 +00:00
if ( oddsvalid [ 1 ] ) SETUPDISTTABLE ( 1 , 1 ) ;
if ( oddsvalid [ 2 ] ) SETUPDISTTABLE ( 2 , 1 ) ;
if ( oddsvalid [ 3 ] ) SETUPDISTTABLE ( 3 , 1 ) ;
if ( oddsvalid [ 4 ] ) SETUPDISTTABLE ( 4 , 2 ) ;
if ( oddsvalid [ 5 ] ) SETUPDISTTABLE ( 5 , 2 ) ;
if ( oddsvalid [ 6 ] ) SETUPDISTTABLE ( 6 , 3 ) ;
if ( oddsvalid [ 7 ] ) SETUPDISTTABLE ( 7 , 3 ) ;
if ( oddsvalid [ 8 ] ) SETUPDISTTABLE ( 8 , 1 ) ;
2018-06-07 23:39:45 +00:00
if ( franticitems ) // Frantic items make the distances between everyone artifically higher, for crazier items
2018-01-30 00:15:25 +00:00
pdis = ( 15 * pdis / 14 ) ;
2018-08-29 03:06:31 +00:00
if ( pingame < 8 & & ! G_BattleGametype ( ) )
pdis = ( ( 28 + ( 8 - pingame ) ) * pdis / 28 ) ;
2018-02-05 23:55:52 +00:00
if ( pingame = = 1 & & oddsvalid [ 0 ] ) // Record Attack, or just alone
useodds = 0 ;
else if ( pdis < = 0 ) // (64*14) * 0 = 0
2018-07-04 21:25:38 +00:00
useodds = disttable [ 0 ] ;
2018-02-05 23:55:52 +00:00
else if ( pdis > distvar * ( ( 12 * distlen ) / 14 ) ) // (64*14) * 12 = 10752
useodds = disttable [ distlen - 1 ] ;
else
{
2018-08-29 18:28:28 +00:00
for ( i = 1 ; i < 13 ; i + + )
2018-06-11 01:05:09 +00:00
{
if ( pdis < = distvar * ( ( i * distlen ) / 14 ) )
{
useodds = disttable [ ( ( i * distlen ) / 14 ) ] ;
break ;
}
}
2018-02-05 23:55:52 +00:00
}
2017-11-23 02:40:17 +00:00
}
2017-05-07 23:08:03 +00:00
2018-02-05 23:55:52 +00:00
# undef SETUPDISTTABLE
2018-06-11 01:05:09 +00:00
//CONS_Printf("Got useodds %d. (position: %d, distance: %d)\n", useodds, player->kartstuff[k_position], pdis);
2018-06-06 22:36:39 +00:00
2018-08-29 18:28:28 +00:00
return useodds ;
}
static void K_KartItemRoulette ( player_t * player , ticcmd_t * cmd )
{
INT32 i ;
UINT8 pingame = 0 ;
UINT8 roulettestop ;
INT32 useodds = 0 ;
INT32 spawnchance [ NUMKARTRESULTS * NUMKARTODDS ] ;
INT32 chance = 0 , numchoices = 0 ;
INT32 bestbumper = 0 ;
fixed_t mashed = 0 ;
// This makes the roulette cycle through items - if this is 0, you shouldn't be here.
if ( player - > kartstuff [ k_itemroulette ] )
player - > kartstuff [ k_itemroulette ] + + ;
else
return ;
// Gotta check how many players are active at this moment.
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( ! playeringame [ i ] | | players [ i ] . spectator )
continue ;
pingame + + ;
if ( players [ i ] . kartstuff [ k_bumper ] > bestbumper )
bestbumper = players [ i ] . kartstuff [ k_bumper ] ;
}
// This makes the roulette produce the random noises.
if ( ( player - > kartstuff [ k_itemroulette ] % 3 ) = = 1 & & P_IsLocalPlayer ( player ) )
S_StartSound ( NULL , sfx_mkitm1 + ( ( player - > kartstuff [ k_itemroulette ] / 3 ) % 8 ) ) ;
roulettestop = ( TICRATE * 1 ) + ( 3 * ( pingame - player - > kartstuff [ k_position ] ) ) ;
// If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item.
// I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think.
// Finally, if you get past this check, now you can actually start calculating what item you get.
if ( ( cmd - > buttons & BT_ATTACK ) & & ! ( player - > kartstuff [ k_eggmanheld ] | | player - > kartstuff [ k_itemheld ] ) & & player - > kartstuff [ k_itemroulette ] > = roulettestop )
{
// Mashing reduces your chances for the good items
mashed = FixedDiv ( ( player - > kartstuff [ k_itemroulette ] ) * FRACUNIT , ( ( TICRATE * 3 ) + roulettestop ) * FRACUNIT ) - FRACUNIT ;
}
else if ( ! ( player - > kartstuff [ k_itemroulette ] > = ( TICRATE * 3 ) ) )
return ;
if ( cmd - > buttons & BT_ATTACK )
player - > pflags | = PF_ATTACKDOWN ;
if ( player - > kartstuff [ k_roulettetype ] = = 2 ) // Fake items
{
player - > kartstuff [ k_eggmanexplode ] = 4 * TICRATE ;
player - > kartstuff [ k_itemroulette ] = 0 ;
player - > kartstuff [ k_roulettetype ] = 0 ;
if ( P_IsLocalPlayer ( player ) )
S_StartSound ( NULL , sfx_mkitmE ) ;
return ;
}
if ( cv_kartdebugitem . value ! = 0 )
{
K_KartGetItemResult ( player , cv_kartdebugitem . value ) ;
player - > kartstuff [ k_itemamount ] = cv_kartdebugamount . value ;
player - > kartstuff [ k_itemroulette ] = 0 ;
player - > kartstuff [ k_roulettetype ] = 0 ;
if ( P_IsLocalPlayer ( player ) )
S_StartSound ( NULL , sfx_dbgsal ) ;
return ;
}
// Initializes existing spawnchance values
for ( i = 0 ; i < ( NUMKARTRESULTS * NUMKARTODDS ) ; i + + )
spawnchance [ i ] = 0 ;
// Split into another function for a debug function below
useodds = K_FindUseodds ( player , mashed , pingame , bestbumper ) ;
# define SETITEMRESULT(itemnum) \
for ( chance = 0 ; chance < K_KartGetItemOdds ( useodds , itemnum , mashed ) ; chance + + ) \
2017-11-07 20:04:21 +00:00
spawnchance [ numchoices + + ] = itemnum
2017-05-07 23:08:03 +00:00
2018-08-29 18:28:28 +00:00
for ( i = 1 ; i < NUMKARTRESULTS ; i + + )
SETITEMRESULT ( i ) ;
2017-05-07 23:08:03 +00:00
# undef SETITEMRESULT
2018-02-05 23:55:52 +00:00
// Award the player whatever power is rolled
if ( numchoices > 0 )
K_KartGetItemResult ( player , spawnchance [ P_RandomKey ( numchoices ) ] ) ;
else
{
player - > kartstuff [ k_itemtype ] = KITEM_SAD ;
player - > kartstuff [ k_itemamount ] = 1 ;
}
2017-05-07 23:08:03 +00:00
player - > kartstuff [ k_itemroulette ] = 0 ; // Since we're done, clear the roulette number
2018-06-04 04:29:31 +00:00
player - > kartstuff [ k_roulettetype ] = 0 ; // This too
2017-05-07 23:08:03 +00:00
if ( P_IsLocalPlayer ( player ) )
S_StartSound ( NULL , sfx_mkitmF ) ;
}
//}
2017-03-06 02:38:35 +00:00
//{ SRB2kart p_user.c Stuff
2018-07-20 20:13:02 +00:00
static fixed_t K_GetMobjWeight ( mobj_t * mobj , mobj_t * against )
{
fixed_t weight = 5 < < FRACBITS ;
switch ( mobj - > type )
{
case MT_PLAYER :
if ( ! mobj - > player )
break ;
if ( against - > player & & ! against - > player - > kartstuff [ k_spinouttimer ] & & mobj - > player - > kartstuff [ k_spinouttimer ] )
weight = 0 ; // Do not bump
else
2018-09-08 08:04:10 +00:00
{
2018-07-20 20:13:02 +00:00
weight = ( mobj - > player - > kartweight ) < < FRACBITS ;
2018-09-08 08:04:10 +00:00
if ( mobj - > player - > speed > K_GetKartSpeed ( mobj - > player , false ) )
weight + = ( mobj - > player - > speed - K_GetKartSpeed ( mobj - > player , false ) ) / 8 ;
}
2018-07-20 20:13:02 +00:00
break ;
2018-09-06 23:31:28 +00:00
case MT_FALLINGROCK :
if ( against - > player )
{
if ( against - > player - > kartstuff [ k_invincibilitytimer ]
| | against - > player - > kartstuff [ k_growshrinktimer ] > 0 )
weight = 0 ;
else
weight = ( against - > player - > kartweight ) < < FRACBITS ;
}
break ;
2018-07-23 00:55:18 +00:00
case MT_ORBINAUT :
case MT_ORBINAUT_SHIELD :
2018-07-20 20:13:02 +00:00
if ( against - > player )
weight = ( against - > player - > kartweight ) < < FRACBITS ;
break ;
case MT_JAWZ :
case MT_JAWZ_DUD :
case MT_JAWZ_SHIELD :
if ( against - > player )
weight = ( against - > player - > kartweight + 3 ) < < FRACBITS ;
else
2018-07-20 20:13:41 +00:00
weight = 8 < < FRACBITS ;
2018-07-20 20:13:02 +00:00
break ;
default :
break ;
}
return weight ;
}
2018-09-06 23:27:07 +00:00
void K_KartBouncing ( mobj_t * mobj1 , mobj_t * mobj2 , boolean bounce , boolean solid )
2017-04-17 17:18:51 +00:00
{
2017-10-24 04:42:06 +00:00
mobj_t * fx ;
2017-11-04 13:19:06 +00:00
fixed_t momdifx , momdify ;
fixed_t distx , disty ;
2018-07-20 02:37:32 +00:00
//fixed_t nobumpx = 0, nobumpy = 0;
2017-11-04 13:19:06 +00:00
fixed_t dot , p ;
2017-11-03 00:43:51 +00:00
fixed_t mass1 , mass2 ;
2017-04-19 01:04:54 +00:00
2017-11-03 00:43:51 +00:00
if ( ! mobj1 | | ! mobj2 )
2017-04-17 17:18:51 +00:00
return ;
2017-04-19 01:04:54 +00:00
2017-11-11 01:17:42 +00:00
// Don't bump when you're being reborn
if ( ( mobj1 - > player & & mobj1 - > player - > playerstate ! = PST_LIVE )
| | ( mobj2 - > player & & mobj2 - > player - > playerstate ! = PST_LIVE ) )
return ;
2018-06-25 02:15:22 +00:00
if ( ( mobj1 - > player & & mobj1 - > player - > kartstuff [ k_respawn ] )
| | ( mobj2 - > player & & mobj2 - > player - > kartstuff [ k_respawn ] ) )
2018-06-07 00:41:23 +00:00
return ;
2017-12-28 23:37:25 +00:00
// Don't bump if you've recently bumped
2018-07-20 02:37:32 +00:00
if ( mobj1 - > player & & mobj1 - > player - > kartstuff [ k_justbumped ] )
2017-12-28 23:37:25 +00:00
{
2018-07-20 02:37:32 +00:00
mobj1 - > player - > kartstuff [ k_justbumped ] = bumptime ;
2017-12-28 23:37:25 +00:00
return ;
}
2018-07-20 02:37:32 +00:00
if ( mobj2 - > player & & mobj2 - > player - > kartstuff [ k_justbumped ] )
2017-11-05 21:33:22 +00:00
{
2018-07-20 02:37:32 +00:00
mobj2 - > player - > kartstuff [ k_justbumped ] = bumptime ;
return ;
2017-11-05 21:33:22 +00:00
}
2018-07-20 20:13:02 +00:00
mass1 = K_GetMobjWeight ( mobj1 , mobj2 ) ;
2018-09-06 23:27:07 +00:00
if ( solid = = true & & mass1 > 0 )
mass2 = mass1 ;
else
mass2 = K_GetMobjWeight ( mobj2 , mobj1 ) ;
2017-11-04 13:19:06 +00:00
momdifx = mobj1 - > momx - mobj2 - > momx ;
momdify = mobj1 - > momy - mobj2 - > momy ;
2017-11-05 16:46:26 +00:00
// if the speed difference is less than this let's assume they're going proportionately faster from each other
2018-01-15 21:14:45 +00:00
if ( P_AproxDistance ( momdifx , momdify ) < ( 25 * mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) )
2017-11-05 16:46:26 +00:00
{
fixed_t momdiflength = P_AproxDistance ( momdifx , momdify ) ;
fixed_t normalisedx = FixedDiv ( momdifx , momdiflength ) ;
fixed_t normalisedy = FixedDiv ( momdify , momdiflength ) ;
2018-01-15 21:14:45 +00:00
momdifx = FixedMul ( ( 25 * mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) , normalisedx ) ;
momdify = FixedMul ( ( 25 * mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) , normalisedy ) ;
2017-11-05 16:46:26 +00:00
}
2018-07-20 02:37:32 +00:00
/*if (mass1 == 0 && mass2 > 0)
{
nobumpx = mobj2 - > momx ;
nobumpy = mobj2 - > momy ;
}
else if ( mass2 = = 0 & & mass1 > 0 )
{
nobumpx = mobj1 - > momx ;
nobumpy = mobj1 - > momy ;
} */
2018-08-09 21:59:52 +00:00
2018-07-20 02:37:32 +00:00
distx = ( mobj1 - > x + mobj2 - > momx ) - ( mobj2 - > x + mobj1 - > momx ) ;
disty = ( mobj1 - > y + mobj2 - > momy ) - ( mobj2 - > y + mobj1 - > momy ) ;
2017-11-05 21:33:22 +00:00
if ( distx = = 0 & & disty = = 0 )
{
// if there's no distance between the 2, they're directly on top of each other, don't run this
return ;
}
2017-11-04 13:19:06 +00:00
dot = FixedMul ( momdifx , distx ) + FixedMul ( momdify , disty ) ;
2017-11-05 21:33:22 +00:00
if ( dot > = 0 )
{
// They're moving away from each other
return ;
}
2017-11-04 13:19:06 +00:00
p = FixedDiv ( dot , FixedMul ( distx , distx ) + FixedMul ( disty , disty ) ) ;
2018-07-20 02:37:32 +00:00
if ( bounce = = true & & mass2 > 0 ) // Perform a Goomba Bounce.
mobj1 - > momz = - mobj1 - > momz ;
else
{
fixed_t newz = mobj1 - > momz ;
if ( mass2 > 0 )
mobj1 - > momz = mobj2 - > momz ;
2018-09-06 23:27:07 +00:00
if ( mass1 > 0 & & solid = = false )
2018-07-20 02:37:32 +00:00
mobj2 - > momz = newz ;
}
2017-11-04 13:19:06 +00:00
2018-07-20 02:37:32 +00:00
if ( mass2 > 0 )
{
mobj1 - > momx = mobj1 - > momx - FixedMul ( FixedMul ( FixedDiv ( 2 * mass2 , mass1 + mass2 ) , p ) , distx ) ;
mobj1 - > momy = mobj1 - > momy - FixedMul ( FixedMul ( FixedDiv ( 2 * mass2 , mass1 + mass2 ) , p ) , disty ) ;
}
2017-11-04 13:19:06 +00:00
2018-09-06 23:27:07 +00:00
if ( mass1 > 0 & & solid = = false )
2018-01-08 20:48:19 +00:00
{
mobj2 - > momx = mobj2 - > momx - FixedMul ( FixedMul ( FixedDiv ( 2 * mass1 , mass1 + mass2 ) , p ) , - distx ) ;
mobj2 - > momy = mobj2 - > momy - FixedMul ( FixedMul ( FixedDiv ( 2 * mass1 , mass1 + mass2 ) , p ) , - disty ) ;
}
2017-11-03 00:43:51 +00:00
2018-07-20 02:37:32 +00:00
// Do the bump fx when we've CONFIRMED we can bump.
S_StartSound ( mobj1 , sfx_s3k49 ) ;
fx = P_SpawnMobj ( mobj1 - > x / 2 + mobj2 - > x / 2 , mobj1 - > y / 2 + mobj2 - > y / 2 , mobj1 - > z / 2 + mobj2 - > z / 2 , MT_BUMP ) ;
if ( mobj1 - > eflags & MFE_VERTICALFLIP )
fx - > eflags | = MFE_VERTICALFLIP ;
else
fx - > eflags & = ~ MFE_VERTICALFLIP ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
P_SetScale ( fx , mobj1 - > scale ) ;
2018-07-20 02:37:32 +00:00
2017-11-01 18:40:32 +00:00
// Because this is done during collision now, rmomx and rmomy need to be recalculated
// so that friction doesn't immediately decide to stop the player if they're at a standstill
2017-12-28 23:37:25 +00:00
// Also set justbumped here
2017-11-01 18:40:32 +00:00
if ( mobj1 - > player )
{
mobj1 - > player - > rmomx = mobj1 - > momx - mobj1 - > player - > cmomx ;
mobj1 - > player - > rmomy = mobj1 - > momy - mobj1 - > player - > cmomy ;
2017-12-28 23:37:25 +00:00
mobj1 - > player - > kartstuff [ k_justbumped ] = bumptime ;
2018-07-20 02:37:32 +00:00
if ( mobj1 - > player - > kartstuff [ k_spinouttimer ] )
{
mobj1 - > player - > kartstuff [ k_wipeoutslow ] + = wipeoutslowtime + 1 ;
mobj1 - > player - > kartstuff [ k_spinouttimer ] + = wipeoutslowtime + 1 ;
}
2017-11-01 18:40:32 +00:00
}
if ( mobj2 - > player )
{
mobj2 - > player - > rmomx = mobj2 - > momx - mobj2 - > player - > cmomx ;
mobj2 - > player - > rmomy = mobj2 - > momy - mobj2 - > player - > cmomy ;
2017-12-28 23:37:25 +00:00
mobj2 - > player - > kartstuff [ k_justbumped ] = bumptime ;
2018-07-20 02:37:32 +00:00
if ( mobj2 - > player - > kartstuff [ k_spinouttimer ] )
{
mobj2 - > player - > kartstuff [ k_wipeoutslow ] + = wipeoutslowtime + 1 ;
mobj2 - > player - > kartstuff [ k_spinouttimer ] + = wipeoutslowtime + 1 ;
}
2017-11-01 18:40:32 +00:00
}
2017-04-17 17:18:51 +00:00
}
2017-04-16 20:16:26 +00:00
/** \brief Checks that the player is on an offroad subsector for realsies
\ param mo player mobj object
\ return boolean
*/
2017-11-28 06:13:23 +00:00
static UINT8 K_CheckOffroadCollide ( mobj_t * mo , sector_t * sec )
2017-04-16 20:16:26 +00:00
{
2017-11-28 06:13:23 +00:00
UINT8 i ;
sector_t * sec2 ;
2017-04-16 20:16:26 +00:00
I_Assert ( mo ! = NULL ) ;
I_Assert ( ! P_MobjWasRemoved ( mo ) ) ;
2017-11-28 06:13:23 +00:00
sec2 = P_ThingOnSpecial3DFloor ( mo ) ;
2017-04-16 20:16:26 +00:00
2017-11-28 06:13:23 +00:00
for ( i = 2 ; i < 5 ; i + + )
{
if ( ( sec2 & & GETSECSPECIAL ( sec2 - > special , 1 ) = = i )
| | ( P_IsObjectOnRealGround ( mo , sec )
& & GETSECSPECIAL ( sec - > special , 1 ) = = i ) )
return i ;
}
return 0 ;
2017-04-16 20:16:26 +00:00
}
2017-03-06 02:38:35 +00:00
/** \brief Updates the Player's offroad value once per frame
\ param player player object passed from K_KartPlayerThink
\ return void
*/
static void K_UpdateOffroad ( player_t * player )
{
fixed_t kartweight = player - > kartweight ;
fixed_t offroad ;
sector_t * nextsector = R_PointInSubsector (
player - > mo - > x + player - > mo - > momx * 2 , player - > mo - > y + player - > mo - > momy * 2 ) - > sector ;
2017-04-17 00:43:30 +00:00
fixed_t offroadstrength = 0 ;
2017-11-28 06:13:23 +00:00
if ( K_CheckOffroadCollide ( player - > mo , nextsector ) = = 2 ) // Weak Offroad
2017-04-17 00:43:30 +00:00
offroadstrength = 1 ;
2017-11-28 06:13:23 +00:00
else if ( K_CheckOffroadCollide ( player - > mo , nextsector ) = = 3 ) // Mid Offroad
2017-04-17 00:43:30 +00:00
offroadstrength = 2 ;
2017-11-28 06:13:23 +00:00
else if ( K_CheckOffroadCollide ( player - > mo , nextsector ) = = 4 ) // Strong Offroad
2017-04-17 00:43:30 +00:00
offroadstrength = 3 ;
2017-03-06 02:38:35 +00:00
// If you are offroad, a timer starts. Depending on your weight value, the timer increments differently.
2018-03-13 05:20:47 +00:00
//if ((nextsector->special & 256) && nextsector->special != 768
2017-04-17 00:43:30 +00:00
// && nextsector->special != 1024 && nextsector->special != 4864)
if ( offroadstrength )
2017-03-06 02:38:35 +00:00
{
2017-11-28 06:13:23 +00:00
if ( K_CheckOffroadCollide ( player - > mo , player - > mo - > subsector - > sector ) & & player - > kartstuff [ k_offroad ] = = 0 )
2017-03-06 02:38:35 +00:00
player - > kartstuff [ k_offroad ] = 16 ;
2017-11-28 06:13:23 +00:00
2017-03-06 02:38:35 +00:00
if ( player - > kartstuff [ k_offroad ] > 0 )
{
if ( kartweight < 1 ) { kartweight = 1 ; } if ( kartweight > 9 ) { kartweight = 9 ; } // Safety Net
// 1872 is the magic number - 35 frames adds up to approximately 65536. 1872/4 = 468/3 = 156
// A higher kart weight means you can stay offroad for longer without losing speed
2017-04-17 00:43:30 +00:00
offroad = ( 1872 + 5 * 156 - kartweight * 156 ) * offroadstrength ;
2017-03-06 02:38:35 +00:00
2018-02-10 06:19:33 +00:00
//if (player->kartstuff[k_growshrinktimer] > 1) // grow slows down half as fast
2017-10-13 19:41:36 +00:00
// offroad /= 2;
2017-03-06 02:38:35 +00:00
player - > kartstuff [ k_offroad ] + = offroad ;
}
2017-04-17 00:43:30 +00:00
if ( player - > kartstuff [ k_offroad ] > FRACUNIT * offroadstrength )
player - > kartstuff [ k_offroad ] = FRACUNIT * offroadstrength ;
2017-03-06 02:38:35 +00:00
}
else
player - > kartstuff [ k_offroad ] = 0 ;
}
2018-06-25 02:15:22 +00:00
/** \brief Calculates the respawn timer and drop-boosting
2017-07-16 16:04:33 +00:00
\ param player player object passed from K_KartPlayerThink
\ return void
*/
2018-06-25 02:15:22 +00:00
void K_RespawnChecker ( player_t * player )
2017-07-16 16:04:33 +00:00
{
ticcmd_t * cmd = & player - > cmd ;
2018-07-21 21:45:25 +00:00
if ( player - > spectator )
return ;
2018-06-25 02:15:22 +00:00
if ( player - > kartstuff [ k_respawn ] > 3 )
2017-07-16 16:04:33 +00:00
{
2018-06-25 02:15:22 +00:00
player - > kartstuff [ k_respawn ] - - ;
2017-07-16 16:04:33 +00:00
player - > mo - > momz = 0 ;
player - > powers [ pw_flashing ] = 2 ;
player - > powers [ pw_nocontrol ] = 2 ;
2018-06-25 02:15:22 +00:00
if ( leveltime % 8 = = 0 )
{
2018-06-25 22:17:03 +00:00
INT32 i ;
2018-07-22 04:31:02 +00:00
if ( ! mapreset )
S_StartSound ( player - > mo , sfx_s3kcas ) ;
2018-06-25 02:15:22 +00:00
2018-06-25 22:17:03 +00:00
for ( i = 0 ; i < 8 ; i + + )
2018-06-25 02:15:22 +00:00
{
2018-06-25 22:17:03 +00:00
mobj_t * mo ;
angle_t newangle ;
fixed_t newx , newy , newz ;
newangle = FixedAngle ( ( ( 360 / 8 ) * i ) * FRACUNIT ) ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
newx = player - > mo - > x + P_ReturnThrustX ( player - > mo , newangle , 31 * player - > mo - > scale ) ;
newy = player - > mo - > y + P_ReturnThrustY ( player - > mo , newangle , 31 * player - > mo - > scale ) ;
2018-06-25 02:15:22 +00:00
if ( player - > mo - > eflags & MFE_VERTICALFLIP )
2018-06-25 22:17:03 +00:00
newz = player - > mo - > z + player - > mo - > height ;
else
newz = player - > mo - > z ;
mo = P_SpawnMobj ( newx , newy , newz , MT_DEZLASER ) ;
if ( mo )
{
if ( player - > mo - > eflags & MFE_VERTICALFLIP )
mo - > eflags | = MFE_VERTICALFLIP ;
P_SetTarget ( & mo - > target , player - > mo ) ;
mo - > angle = newangle + ANGLE_90 ;
mo - > momz = ( 8 * FRACUNIT ) * P_MobjFlip ( player - > mo ) ;
}
2018-06-25 02:15:22 +00:00
}
}
2017-07-16 16:04:33 +00:00
}
2018-06-25 02:15:22 +00:00
if ( player - > kartstuff [ k_respawn ] > 0 & & player - > kartstuff [ k_respawn ] < = 3 )
2017-07-16 16:04:33 +00:00
{
if ( ! P_IsObjectOnGround ( player - > mo ) )
{
player - > powers [ pw_flashing ] = 2 ;
// If you tried to boost while in the air,
// you lose your chance of boosting at all.
if ( cmd - > buttons & BT_ACCELERATE )
{
player - > powers [ pw_flashing ] = 0 ;
2018-06-25 02:15:22 +00:00
player - > kartstuff [ k_respawn ] = 0 ;
2017-07-16 16:04:33 +00:00
}
}
else
{
2018-06-25 02:15:22 +00:00
player - > kartstuff [ k_respawn ] - - ;
2017-07-16 16:04:33 +00:00
// Quick! You only have three tics to boost!
if ( cmd - > buttons & BT_ACCELERATE )
2018-03-31 04:44:03 +00:00
K_DoSneaker ( player , true ) ;
2017-07-16 16:04:33 +00:00
}
}
}
2017-11-04 17:32:47 +00:00
/** \brief Handles the state changing for moving players, moved here to eliminate duplicate code
\ param player player data
\ return void
*/
void K_KartMoveAnimation ( player_t * player )
{
ticcmd_t * cmd = & player - > cmd ;
// Standing frames - S_KART_STND1 S_KART_STND1_L S_KART_STND1_R
2017-11-06 04:18:58 +00:00
if ( player - > speed = = 0 )
2017-11-04 17:32:47 +00:00
{
2018-06-05 21:12:42 +00:00
if ( cmd - > driftturn < 0 & & ! ( player - > mo - > state > = & states [ S_KART_STND1_R ] & & player - > mo - > state < = & states [ S_KART_STND2_R ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_STND1_R ) ;
2018-06-05 21:12:42 +00:00
else if ( cmd - > driftturn > 0 & & ! ( player - > mo - > state > = & states [ S_KART_STND1_L ] & & player - > mo - > state < = & states [ S_KART_STND2_L ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_STND1_L ) ;
2018-06-05 21:12:42 +00:00
else if ( cmd - > driftturn = = 0 & & ! ( player - > mo - > state > = & states [ S_KART_STND1 ] & & player - > mo - > state < = & states [ S_KART_STND2 ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_STND1 ) ;
}
// Drifting Left - S_KART_DRIFT1_L
else if ( player - > kartstuff [ k_drift ] > 0 & & P_IsObjectOnGround ( player - > mo ) )
{
if ( ! ( player - > mo - > state > = & states [ S_KART_DRIFT1_L ] & & player - > mo - > state < = & states [ S_KART_DRIFT2_L ] ) )
P_SetPlayerMobjState ( player - > mo , S_KART_DRIFT1_L ) ;
}
// Drifting Right - S_KART_DRIFT1_R
else if ( player - > kartstuff [ k_drift ] < 0 & & P_IsObjectOnGround ( player - > mo ) )
{
if ( ! ( player - > mo - > state > = & states [ S_KART_DRIFT1_R ] & & player - > mo - > state < = & states [ S_KART_DRIFT2_R ] ) )
P_SetPlayerMobjState ( player - > mo , S_KART_DRIFT1_R ) ;
}
// Run frames - S_KART_RUN1 S_KART_RUN1_L S_KART_RUN1_R
else if ( player - > speed > FixedMul ( player - > runspeed , player - > mo - > scale ) )
{
2018-06-05 21:12:42 +00:00
if ( cmd - > driftturn < 0 & & ! ( player - > mo - > state > = & states [ S_KART_RUN1_R ] & & player - > mo - > state < = & states [ S_KART_RUN2_R ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_RUN1_R ) ;
2018-06-05 21:12:42 +00:00
else if ( cmd - > driftturn > 0 & & ! ( player - > mo - > state > = & states [ S_KART_RUN1_L ] & & player - > mo - > state < = & states [ S_KART_RUN2_L ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_RUN1_L ) ;
2018-06-05 21:12:42 +00:00
else if ( cmd - > driftturn = = 0 & & ! ( player - > mo - > state > = & states [ S_KART_RUN1 ] & & player - > mo - > state < = & states [ S_KART_RUN2 ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_RUN1 ) ;
}
// Walk frames - S_KART_WALK1 S_KART_WALK1_L S_KART_WALK1_R
else if ( player - > speed < = FixedMul ( player - > runspeed , player - > mo - > scale ) )
{
2018-06-05 21:12:42 +00:00
if ( cmd - > driftturn < 0 & & ! ( player - > mo - > state > = & states [ S_KART_WALK1_R ] & & player - > mo - > state < = & states [ S_KART_WALK2_R ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_WALK1_R ) ;
2018-06-05 21:12:42 +00:00
else if ( cmd - > driftturn > 0 & & ! ( player - > mo - > state > = & states [ S_KART_WALK1_L ] & & player - > mo - > state < = & states [ S_KART_WALK2_L ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_WALK1_L ) ;
2018-06-05 21:12:42 +00:00
else if ( cmd - > driftturn = = 0 & & ! ( player - > mo - > state > = & states [ S_KART_WALK1 ] & & player - > mo - > state < = & states [ S_KART_WALK2 ] ) )
2017-11-04 17:32:47 +00:00
P_SetPlayerMobjState ( player - > mo , S_KART_WALK1 ) ;
}
}
2018-07-04 21:25:38 +00:00
static void K_TauntVoiceTimers ( player_t * player )
{
if ( ! player )
return ;
player - > kartstuff [ k_tauntvoices ] = 6 * TICRATE ;
player - > kartstuff [ k_voices ] = 4 * TICRATE ;
}
static void K_RegularVoiceTimers ( player_t * player )
{
if ( ! player )
return ;
2018-07-04 21:37:11 +00:00
player - > kartstuff [ k_voices ] = 4 * TICRATE ;
2018-07-04 21:25:38 +00:00
if ( player - > kartstuff [ k_tauntvoices ] < 4 * TICRATE )
player - > kartstuff [ k_tauntvoices ] = 4 * TICRATE ;
}
2017-03-04 22:13:19 +00:00
static void K_PlayTauntSound ( mobj_t * source )
2016-08-15 03:51:08 +00:00
{
2018-07-29 22:51:08 +00:00
# if 1
2018-07-29 17:35:56 +00:00
sfxenum_t pick = P_RandomKey ( 4 ) ; // Gotta roll the RNG every time this is called for sync reasons
boolean tasteful = ( ! source - > player | | ! source - > player - > kartstuff [ k_tauntvoices ] ) ;
if ( cv_kartvoices . value & & ( tasteful | | cv_kartvoices . value = = 2 ) )
S_StartSound ( source , sfx_taunt1 + pick ) ;
2017-11-29 06:09:46 +00:00
2018-07-29 17:35:56 +00:00
if ( ! tasteful )
return ;
2017-02-17 20:14:55 +00:00
2018-07-04 21:25:38 +00:00
K_TauntVoiceTimers ( source - > player ) ;
2018-07-29 19:09:20 +00:00
# else
if ( source - > player & & source - > player - > kartstuff [ k_tauntvoices ] ) // Prevents taunt sounds from playing every time the button is pressed
return ;
S_StartSound ( source , sfx_taunt1 + P_RandomKey ( 4 ) ) ;
K_TauntVoiceTimers ( source - > player ) ;
# endif
2018-06-07 18:56:26 +00:00
}
2017-02-17 20:14:55 +00:00
2018-06-07 19:03:47 +00:00
static void K_PlayOvertakeSound ( mobj_t * source )
2018-06-07 18:56:26 +00:00
{
2018-07-29 22:51:08 +00:00
# if 1
2018-07-29 17:35:56 +00:00
boolean tasteful = ( ! source - > player | | ! source - > player - > kartstuff [ k_voices ] ) ;
2017-07-16 16:04:33 +00:00
2018-06-25 22:17:03 +00:00
if ( ! G_RaceGametype ( ) ) // Only in race
return ;
2018-06-08 23:04:20 +00:00
// 4 seconds from before race begins, 10 seconds afterwards
2018-06-25 02:15:22 +00:00
if ( leveltime < starttime + ( 10 * TICRATE ) )
2018-06-08 23:04:20 +00:00
return ;
2017-02-17 20:14:55 +00:00
2018-07-29 17:35:56 +00:00
if ( cv_kartvoices . value & & ( tasteful | | cv_kartvoices . value = = 2 ) )
S_StartSound ( source , sfx_slow ) ;
if ( ! tasteful )
return ;
2016-08-12 01:42:11 +00:00
2018-07-04 21:25:38 +00:00
K_RegularVoiceTimers ( source - > player ) ;
2018-07-29 19:09:20 +00:00
# else
if ( source - > player & & source - > player - > kartstuff [ k_voices ] ) // Prevents taunt sounds from playing every time the button is pressed
return ;
if ( ! G_RaceGametype ( ) ) // Only in race
return ;
// 4 seconds from before race begins, 10 seconds afterwards
if ( leveltime < starttime + ( 10 * TICRATE ) )
return ;
S_StartSound ( source , sfx_slow ) ;
K_RegularVoiceTimers ( source - > player ) ;
# endif
2016-08-15 03:51:08 +00:00
}
2018-06-07 18:56:26 +00:00
static void K_PlayHitEmSound ( mobj_t * source )
2018-02-05 00:00:36 +00:00
{
2018-07-29 17:35:56 +00:00
if ( cv_kartvoices . value )
S_StartSound ( source , sfx_hitem ) ;
2018-06-07 18:56:26 +00:00
2018-07-04 21:25:38 +00:00
K_RegularVoiceTimers ( source - > player ) ;
2016-08-21 02:15:06 +00:00
}
2016-08-15 03:51:08 +00:00
2017-03-10 02:22:49 +00:00
void K_MomentumToFacing ( player_t * player )
{
angle_t dangle = player - > mo - > angle - R_PointToAngle2 ( 0 , 0 , player - > mo - > momx , player - > mo - > momy ) ;
if ( dangle > ANGLE_180 )
dangle = InvAngle ( dangle ) ;
// If you aren't on the ground or are moving in too different of a direction don't do this
2018-07-14 00:45:18 +00:00
if ( player - > mo - > eflags & MFE_JUSTHITFLOOR )
; // Just hit floor ALWAYS redirects
else if ( ! P_IsObjectOnGround ( player - > mo ) | | dangle > ANGLE_90 )
2017-03-10 02:22:49 +00:00
return ;
2017-03-10 22:54:54 +00:00
P_Thrust ( player - > mo , player - > mo - > angle , player - > speed - FixedMul ( player - > speed , player - > mo - > friction ) ) ;
player - > mo - > momx = FixedMul ( player - > mo - > momx - player - > cmomx , player - > mo - > friction ) + player - > cmomx ;
player - > mo - > momy = FixedMul ( player - > mo - > momy - player - > cmomy , player - > mo - > friction ) + player - > cmomy ;
2017-03-10 02:22:49 +00:00
}
2017-03-09 21:41:11 +00:00
// if speed is true it gets the speed boost power, otherwise it gets the acceleration
2018-09-04 19:11:14 +00:00
static void K_GetKartBoostPower ( player_t * player )
2017-02-13 04:24:49 +00:00
{
2017-04-16 18:55:21 +00:00
fixed_t boostpower = FRACUNIT ;
2018-09-04 19:11:14 +00:00
fixed_t speedboost = 0 , accelboost = 0 ;
2017-02-13 04:24:49 +00:00
2018-07-20 02:37:32 +00:00
if ( player - > kartstuff [ k_spinouttimer ] & & player - > kartstuff [ k_wipeoutslow ] = = 1 ) // Slow down after you've been bumped
2018-09-04 19:11:14 +00:00
{
2018-09-06 17:02:08 +00:00
player - > kartstuff [ k_boostpower ] = player - > kartstuff [ k_speedboost ] = player - > kartstuff [ k_accelboost ] = 0 ;
2018-09-04 19:11:14 +00:00
return ;
}
2018-07-20 02:37:32 +00:00
2017-04-16 18:55:21 +00:00
// Offroad is separate, it's difficult to factor it in with a variable value anyway.
2018-02-05 23:55:52 +00:00
if ( ! ( player - > kartstuff [ k_invincibilitytimer ] | | player - > kartstuff [ k_hyudorotimer ] | | player - > kartstuff [ k_sneakertimer ] )
2018-09-04 19:11:14 +00:00
& & player - > kartstuff [ k_offroad ] > = 0 )
2018-06-20 00:20:06 +00:00
boostpower = FixedDiv ( boostpower , player - > kartstuff [ k_offroad ] + FRACUNIT ) ;
2017-04-16 18:55:21 +00:00
2018-09-05 00:51:16 +00:00
if ( player - > kartstuff [ k_itemtype ] = = KITEM_KITCHENSINK )
2018-09-05 01:14:42 +00:00
boostpower = max ( ( TICRATE / 2 ) , ( 5 * TICRATE ) - ( player - > kartstuff [ k_bananadrag ] / 2 ) ) * boostpower / ( 5 * TICRATE ) ;
2018-09-05 00:51:16 +00:00
else if ( player - > kartstuff [ k_bananadrag ] > TICRATE )
2018-07-04 23:06:45 +00:00
boostpower = 4 * boostpower / 5 ;
2018-09-04 19:11:14 +00:00
if ( player - > kartstuff [ k_growshrinktimer ] > 0 ) // Grow
{
speedboost = max ( speedboost , FRACUNIT / 5 ) ; // + 20%
2017-02-19 17:18:43 +00:00
}
2018-09-04 19:11:14 +00:00
if ( player - > kartstuff [ k_invincibilitytimer ] ) // Invincibility
{
speedboost = max ( speedboost , 3 * ( FRACUNIT / 8 ) ) ; // + 37.5%
accelboost = max ( accelboost , 3 * FRACUNIT ) ; // + 600%
2017-02-19 17:18:43 +00:00
}
2018-09-04 19:11:14 +00:00
if ( player - > kartstuff [ k_driftboost ] ) // Drift Boost
{
speedboost = max ( speedboost , FRACUNIT / 4 ) ; // + 25%
accelboost = max ( accelboost , 4 * FRACUNIT ) ; // + 400%
2017-02-19 17:18:43 +00:00
}
2018-09-04 19:11:14 +00:00
if ( player - > kartstuff [ k_sneakertimer ] ) // Sneaker
{
switch ( gamespeed )
2017-05-12 00:49:17 +00:00
{
2018-09-04 19:11:14 +00:00
case 0 :
speedboost = max ( speedboost , 53740 + 768 ) ;
break ;
case 2 :
speedboost = max ( speedboost , 17294 + 768 ) ;
break ;
default :
speedboost = max ( speedboost , 32768 ) ;
break ;
2017-05-12 00:49:17 +00:00
}
2018-09-04 19:11:14 +00:00
accelboost = max ( accelboost , 8 * FRACUNIT ) ; // + 800%
2017-02-19 17:18:43 +00:00
}
2018-09-04 19:11:14 +00:00
2017-03-09 21:41:11 +00:00
// don't average them anymore, this would make a small boost and a high boost less useful
// just take the highest we want instead
2017-02-13 04:24:49 +00:00
2018-09-06 17:02:08 +00:00
player - > kartstuff [ k_boostpower ] = boostpower ;
// value smoothing
if ( speedboost > player - > kartstuff [ k_speedboost ] )
player - > kartstuff [ k_speedboost ] = speedboost ;
2018-09-04 19:11:14 +00:00
else
2018-09-06 17:02:08 +00:00
player - > kartstuff [ k_speedboost ] + = ( speedboost - player - > kartstuff [ k_speedboost ] ) / ( TICRATE / 2 ) ;
2018-09-04 19:11:14 +00:00
2018-09-06 17:02:08 +00:00
player - > kartstuff [ k_accelboost ] = accelboost ;
2017-02-13 04:24:49 +00:00
}
2017-03-04 22:13:19 +00:00
2017-02-24 01:36:43 +00:00
fixed_t K_GetKartSpeed ( player_t * player , boolean doboostpower )
2017-02-13 04:24:49 +00:00
{
2017-03-08 01:11:14 +00:00
fixed_t k_speed = 150 ;
2017-02-24 01:36:43 +00:00
fixed_t g_cc = FRACUNIT ;
fixed_t xspd = 3072 ; // 4.6875 aka 3/64
2017-11-20 00:39:40 +00:00
UINT8 kartspeed = player - > kartspeed ;
2017-03-10 03:24:15 +00:00
fixed_t finalspeed ;
2017-11-20 00:39:40 +00:00
2018-07-27 21:08:45 +00:00
if ( doboostpower & & ! player - > kartstuff [ k_pogospring ] & & ! P_IsObjectOnGround ( player - > mo ) )
return ( 75 * mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ; // air speed cap
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
switch ( gamespeed )
2017-02-22 04:41:00 +00:00
{
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
case 0 :
2017-02-24 01:36:43 +00:00
g_cc = 53248 + xspd ; // 50cc = 81.25 + 4.69 = 85.94%
2017-02-22 04:41:00 +00:00
break ;
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
case 2 :
2017-02-24 01:36:43 +00:00
g_cc = 77824 + xspd ; // 150cc = 118.75 + 4.69 = 123.44%
2017-02-22 04:41:00 +00:00
break ;
default :
2017-02-24 01:36:43 +00:00
g_cc = 65536 + xspd ; // 100cc = 100.00 + 4.69 = 104.69%
2017-02-22 04:41:00 +00:00
break ;
}
2017-02-13 04:24:49 +00:00
2018-07-03 19:14:47 +00:00
if ( G_BattleGametype ( ) & & player - > kartstuff [ k_bumper ] < = 0 )
2017-11-20 00:39:40 +00:00
kartspeed = 1 ;
k_speed + = kartspeed * 3 ; // 153 - 177
2017-02-13 04:24:49 +00:00
2017-03-10 03:24:15 +00:00
finalspeed = FixedMul ( FixedMul ( k_speed < < 14 , g_cc ) , player - > mo - > scale ) ;
2017-02-24 01:36:43 +00:00
if ( doboostpower )
2018-09-06 17:02:08 +00:00
return FixedMul ( finalspeed , player - > kartstuff [ k_boostpower ] + player - > kartstuff [ k_speedboost ] ) ;
2017-03-10 03:24:15 +00:00
return finalspeed ;
2017-02-13 04:24:49 +00:00
}
2017-03-04 22:13:19 +00:00
2017-11-17 05:48:36 +00:00
fixed_t K_GetKartAccel ( player_t * player )
2017-02-13 04:24:49 +00:00
{
2017-04-21 01:44:56 +00:00
fixed_t k_accel = 32 ; // 36;
2017-11-20 00:39:40 +00:00
UINT8 kartspeed = player - > kartspeed ;
2018-07-03 19:14:47 +00:00
if ( G_BattleGametype ( ) & & player - > kartstuff [ k_bumper ] < = 0 )
2017-11-20 00:39:40 +00:00
kartspeed = 1 ;
2017-02-13 04:24:49 +00:00
2017-11-20 00:39:40 +00:00
//k_accel += 3 * (9 - kartspeed); // 36 - 60
k_accel + = 4 * ( 9 - kartspeed ) ; // 32 - 64
2017-02-13 04:24:49 +00:00
2018-09-06 17:02:08 +00:00
return FixedMul ( k_accel , FRACUNIT + player - > kartstuff [ k_accelboost ] ) ;
2017-02-13 04:24:49 +00:00
}
2017-03-04 22:13:19 +00:00
2018-08-11 04:12:41 +00:00
UINT16 K_GetKartFlashing ( player_t * player )
2017-11-17 05:48:36 +00:00
{
2018-08-11 04:12:41 +00:00
UINT16 tics = flashingtics ;
if ( G_BattleGametype ( ) )
tics * = 2 ;
2018-08-14 17:15:33 +00:00
tics + = ( flashingtics / 8 ) * ( player - > kartspeed ) ;
2018-08-11 04:12:41 +00:00
return tics ;
2017-11-17 05:48:36 +00:00
}
2017-04-20 01:04:44 +00:00
fixed_t K_3dKartMovement ( player_t * player , boolean onground , fixed_t forwardmove )
2017-02-13 04:24:49 +00:00
{
fixed_t accelmax = 4000 ;
fixed_t newspeed , oldspeed , finalspeed ;
2017-02-24 01:36:43 +00:00
fixed_t p_speed = K_GetKartSpeed ( player , true ) ;
2017-02-13 04:24:49 +00:00
fixed_t p_accel = K_GetKartAccel ( player ) ;
2018-03-06 06:31:49 +00:00
if ( ! onground ) return 0 ; // If the player isn't on the ground, there is no change in speed
2017-03-04 22:13:19 +00:00
2017-02-13 04:24:49 +00:00
// ACCELCODE!!!1!11!
2017-03-05 23:24:17 +00:00
oldspeed = R_PointToDist2 ( 0 , 0 , player - > rmomx , player - > rmomy ) ; // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale);
2017-02-13 04:24:49 +00:00
newspeed = FixedDiv ( FixedDiv ( FixedMul ( oldspeed , accelmax - p_accel ) + FixedMul ( p_speed , p_accel ) , accelmax ) , ORIG_FRICTION ) ;
2018-07-14 00:45:18 +00:00
if ( player - > kartstuff [ k_pogospring ] ) // Pogo Spring minimum/maximum thrust
{
2018-08-27 22:09:32 +00:00
const fixed_t hscale = mapheaderinfo [ gamemap - 1 ] - > mobj_scale /*+ (mapheaderinfo[gamemap-1]->mobj_scale - player->mo->scale)*/ ;
2018-08-23 16:53:29 +00:00
const fixed_t minspeed = 24 * hscale ;
2018-08-29 18:46:42 +00:00
const fixed_t maxspeed = 28 * hscale ;
2018-07-14 00:45:18 +00:00
if ( newspeed > maxspeed & & player - > kartstuff [ k_pogospring ] = = 2 )
newspeed = maxspeed ;
if ( newspeed < minspeed )
newspeed = minspeed ;
}
2017-02-13 04:24:49 +00:00
finalspeed = newspeed - oldspeed ;
2017-04-20 01:04:44 +00:00
// forwardmove is:
// 50 while accelerating,
// 25 while clutching,
// 0 with no gas, and
// -25 when only braking.
finalspeed * = forwardmove / 25 ;
finalspeed / = 2 ;
if ( forwardmove < 0 & & finalspeed > FRACUNIT * 2 )
return finalspeed / 2 ;
else if ( forwardmove < 0 )
return - FRACUNIT / 2 ;
2017-02-17 02:33:00 +00:00
2017-03-09 21:53:57 +00:00
if ( finalspeed < 0 )
finalspeed = 0 ;
2017-02-13 04:24:49 +00:00
return finalspeed ;
}
2018-07-27 00:12:42 +00:00
void K_DoInstashield ( player_t * player )
{
mobj_t * layera ;
mobj_t * layerb ;
if ( player - > kartstuff [ k_instashield ] > 0 )
return ;
2018-07-27 21:22:51 +00:00
player - > kartstuff [ k_instashield ] = 15 ; // length of instashield animation
2018-07-27 00:12:42 +00:00
S_StartSound ( player - > mo , sfx_cdpcm9 ) ;
layera = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_INSTASHIELDA ) ;
P_SetTarget ( & layera - > target , player - > mo ) ;
layerb = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_INSTASHIELDB ) ;
P_SetTarget ( & layerb - > target , player - > mo ) ;
}
2018-07-01 08:36:09 +00:00
void K_SpinPlayer ( player_t * player , mobj_t * source , INT32 type , boolean trapitem )
2016-08-21 02:15:06 +00:00
{
2018-08-06 17:37:03 +00:00
UINT8 scoremultiply = 1 ;
if ( ! trapitem & & G_BattleGametype ( ) )
{
if ( K_IsPlayerWanted ( player ) )
scoremultiply = 3 ;
else if ( player - > kartstuff [ k_bumper ] = = 1 )
scoremultiply = 2 ;
}
2018-07-01 08:36:09 +00:00
2016-08-21 02:15:06 +00:00
if ( player - > health < = 0 )
2017-02-07 22:19:04 +00:00
return ;
2016-08-15 03:51:08 +00:00
2018-06-20 00:20:06 +00:00
if ( player - > powers [ pw_flashing ] > 0 | | player - > kartstuff [ k_squishedtimer ] > 0 | | player - > kartstuff [ k_spinouttimer ] > 0
2018-02-05 23:55:52 +00:00
| | player - > kartstuff [ k_invincibilitytimer ] > 0 | | player - > kartstuff [ k_growshrinktimer ] > 0 | | player - > kartstuff [ k_hyudorotimer ] > 0
2018-07-03 19:14:47 +00:00
| | ( G_BattleGametype ( ) & & ( ( player - > kartstuff [ k_bumper ] < = 0 & & player - > kartstuff [ k_comebacktimer ] ) | | player - > kartstuff [ k_comebackmode ] = = 1 ) ) )
2018-07-27 00:12:42 +00:00
{
K_DoInstashield ( player ) ;
2017-02-07 22:19:04 +00:00
return ;
2018-07-27 00:12:42 +00:00
}
2016-08-15 03:51:08 +00:00
2018-06-09 15:42:03 +00:00
if ( source & & source ! = player - > mo & & source - > player )
K_PlayHitEmSound ( source ) ;
2017-11-04 20:42:01 +00:00
2018-06-20 00:20:06 +00:00
//player->kartstuff[k_sneakertimer] = 0;
2017-02-19 17:18:43 +00:00
player - > kartstuff [ k_driftboost ] = 0 ;
2016-08-21 02:15:06 +00:00
2018-03-04 20:27:52 +00:00
if ( G_BattleGametype ( ) )
2017-10-22 07:06:35 +00:00
{
2018-06-02 14:57:43 +00:00
if ( source & & source - > player & & player ! = source - > player )
2018-07-01 08:36:09 +00:00
{
P_AddPlayerScore ( source - > player , scoremultiply ) ;
if ( ! trapitem )
{
source - > player - > kartstuff [ k_wanted ] - = wantedreduce ;
player - > kartstuff [ k_wanted ] - = ( wantedreduce / 2 ) ;
}
}
2017-11-30 23:25:59 +00:00
2018-07-03 19:14:47 +00:00
if ( player - > kartstuff [ k_bumper ] > 0 )
2017-11-05 06:43:47 +00:00
{
2018-07-03 19:14:47 +00:00
if ( player - > kartstuff [ k_bumper ] = = 1 )
2018-06-16 04:00:46 +00:00
{
mobj_t * karmahitbox = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_KARMAHITBOX ) ; // Player hitbox is too small!!
P_SetTarget ( & karmahitbox - > target , player - > mo ) ;
karmahitbox - > destscale = player - > mo - > scale ;
P_SetScale ( karmahitbox , player - > mo - > scale ) ;
2018-07-03 19:14:47 +00:00
CONS_Printf ( M_GetText ( " %s lost all of their bumpers! \n " ) , player_names [ player - players ] ) ;
2018-06-16 04:00:46 +00:00
}
2018-07-06 18:22:48 +00:00
player - > kartstuff [ k_bumper ] - - ;
2018-07-04 01:12:25 +00:00
if ( K_IsPlayerWanted ( player ) )
K_CalculateBattleWanted ( ) ;
2017-11-05 06:43:47 +00:00
}
2017-10-22 07:06:35 +00:00
2018-07-03 19:14:47 +00:00
K_CheckBumpers ( ) ;
2017-10-22 07:06:35 +00:00
}
2017-11-17 05:48:36 +00:00
player - > kartstuff [ k_comebacktimer ] = comebacktime ;
2017-11-06 04:18:58 +00:00
2018-06-25 10:58:23 +00:00
player - > kartstuff [ k_spinouttype ] = type ;
2017-02-07 22:19:04 +00:00
if ( player - > kartstuff [ k_spinouttype ] < = 0 )
2016-08-21 02:15:06 +00:00
{
2018-06-20 00:20:06 +00:00
player - > kartstuff [ k_spinouttimer ] = 3 * TICRATE / 2 ; // Banana Spinout
2016-08-15 03:51:08 +00:00
2018-06-20 00:20:06 +00:00
// At spinout, player speed is increased to 1/4 their regular speed, moving them forward
2017-10-13 19:41:36 +00:00
if ( player - > speed < K_GetKartSpeed ( player , true ) / 4 )
P_InstaThrust ( player - > mo , player - > mo - > angle , FixedMul ( K_GetKartSpeed ( player , true ) / 4 , player - > mo - > scale ) ) ;
2016-08-21 02:15:06 +00:00
S_StartSound ( player - > mo , sfx_slip ) ;
}
else
2018-07-20 20:13:02 +00:00
player - > kartstuff [ k_spinouttimer ] = TICRATE + 20 ; // Wipeout
2016-08-21 02:15:06 +00:00
2018-08-11 04:12:41 +00:00
player - > powers [ pw_flashing ] = K_GetKartFlashing ( player ) ;
2016-08-21 02:15:06 +00:00
2017-11-04 14:07:53 +00:00
if ( player - > mo - > state ! = & states [ S_KART_SPIN ] )
P_SetPlayerMobjState ( player - > mo , S_KART_SPIN ) ;
2016-08-21 02:15:06 +00:00
2018-07-27 21:22:51 +00:00
player - > kartstuff [ k_instashield ] = 15 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
if ( cv_kartdebughuddrop . value )
K_DropItems ( player ) ;
else
K_DropHnextList ( player ) ;
2017-02-07 22:19:04 +00:00
return ;
2016-08-21 02:15:06 +00:00
}
2017-02-07 22:19:04 +00:00
void K_SquishPlayer ( player_t * player , mobj_t * source )
2016-08-21 02:15:06 +00:00
{
2018-08-06 17:37:03 +00:00
UINT8 scoremultiply = 1 ;
if ( G_BattleGametype ( ) )
{
if ( K_IsPlayerWanted ( player ) )
scoremultiply = 3 ;
else if ( player - > kartstuff [ k_bumper ] = = 1 )
scoremultiply = 2 ;
}
2018-07-01 08:36:09 +00:00
2016-08-21 02:15:06 +00:00
if ( player - > health < = 0 )
2017-02-07 22:19:04 +00:00
return ;
2016-08-21 02:15:06 +00:00
2018-02-05 23:55:52 +00:00
if ( player - > powers [ pw_flashing ] > 0 | | player - > kartstuff [ k_squishedtimer ] > 0 | | player - > kartstuff [ k_invincibilitytimer ] > 0
| | player - > kartstuff [ k_growshrinktimer ] > 0 | | player - > kartstuff [ k_hyudorotimer ] > 0
2018-07-03 19:14:47 +00:00
| | ( G_BattleGametype ( ) & & ( ( player - > kartstuff [ k_bumper ] < = 0 & & player - > kartstuff [ k_comebacktimer ] ) | | player - > kartstuff [ k_comebackmode ] = = 1 ) ) )
2018-07-27 00:12:42 +00:00
{
K_DoInstashield ( player ) ;
2017-02-07 22:19:04 +00:00
return ;
2018-07-27 00:12:42 +00:00
}
2016-08-21 02:15:06 +00:00
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_sneakertimer ] = 0 ;
2017-02-19 17:18:43 +00:00
player - > kartstuff [ k_driftboost ] = 0 ;
2016-08-21 02:15:06 +00:00
2018-03-04 20:27:52 +00:00
if ( G_BattleGametype ( ) )
2017-10-22 07:06:35 +00:00
{
2018-06-02 14:57:43 +00:00
if ( source & & source - > player & & player ! = source - > player )
2018-07-01 08:36:09 +00:00
{
P_AddPlayerScore ( source - > player , scoremultiply ) ;
source - > player - > kartstuff [ k_wanted ] - = wantedreduce ;
player - > kartstuff [ k_wanted ] - = ( wantedreduce / 2 ) ;
}
2017-11-30 23:25:59 +00:00
2018-07-03 19:14:47 +00:00
if ( player - > kartstuff [ k_bumper ] > 0 )
2017-11-05 06:43:47 +00:00
{
2018-07-03 19:14:47 +00:00
if ( player - > kartstuff [ k_bumper ] = = 1 )
2018-06-16 04:00:46 +00:00
{
mobj_t * karmahitbox = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_KARMAHITBOX ) ; // Player hitbox is too small!!
P_SetTarget ( & karmahitbox - > target , player - > mo ) ;
karmahitbox - > destscale = player - > mo - > scale ;
P_SetScale ( karmahitbox , player - > mo - > scale ) ;
2018-07-03 19:14:47 +00:00
CONS_Printf ( M_GetText ( " %s lost all of their bumpers! \n " ) , player_names [ player - players ] ) ;
2018-06-16 04:00:46 +00:00
}
2018-07-06 18:22:48 +00:00
player - > kartstuff [ k_bumper ] - - ;
2018-07-04 01:12:25 +00:00
if ( K_IsPlayerWanted ( player ) )
K_CalculateBattleWanted ( ) ;
2017-11-05 06:43:47 +00:00
}
2017-10-22 07:06:35 +00:00
2018-07-03 19:14:47 +00:00
K_CheckBumpers ( ) ;
2017-10-22 07:06:35 +00:00
}
2017-11-17 05:48:36 +00:00
player - > kartstuff [ k_comebacktimer ] = comebacktime ;
2017-11-06 04:18:58 +00:00
2018-06-25 10:58:23 +00:00
player - > kartstuff [ k_squishedtimer ] = 2 * TICRATE ;
2016-08-21 02:15:06 +00:00
2018-08-11 04:12:41 +00:00
player - > powers [ pw_flashing ] = K_GetKartFlashing ( player ) ;
2016-08-21 02:15:06 +00:00
player - > mo - > flags | = MF_NOCLIP ;
if ( player - > mo - > state ! = & states [ S_KART_SQUISH ] ) // Squash
P_SetPlayerMobjState ( player - > mo , S_KART_SQUISH ) ;
P_PlayRinglossSound ( player - > mo ) ;
2018-07-27 21:22:51 +00:00
player - > kartstuff [ k_instashield ] = 15 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
if ( cv_kartdebughuddrop . value )
K_DropItems ( player ) ;
else
K_DropHnextList ( player ) ;
2017-02-07 22:19:04 +00:00
return ;
2016-08-21 02:15:06 +00:00
}
2017-02-07 22:19:04 +00:00
void K_ExplodePlayer ( player_t * player , mobj_t * source ) // A bit of a hack, we just throw the player up higher here and extend their spinout timer
2016-08-21 02:15:06 +00:00
{
2018-08-06 17:37:03 +00:00
UINT8 scoremultiply = 1 ;
if ( G_BattleGametype ( ) )
{
if ( K_IsPlayerWanted ( player ) )
scoremultiply = 3 ;
else if ( player - > kartstuff [ k_bumper ] = = 1 )
scoremultiply = 2 ;
}
2018-07-01 08:36:09 +00:00
2016-08-21 02:15:06 +00:00
if ( player - > health < = 0 )
2017-02-07 22:19:04 +00:00
return ;
2016-08-15 03:51:08 +00:00
2018-06-20 00:20:06 +00:00
if ( player - > powers [ pw_flashing ] > 0 | | player - > kartstuff [ k_squishedtimer ] > 0 | | player - > kartstuff [ k_spinouttimer ] > 0
2018-02-05 23:55:52 +00:00
| | player - > kartstuff [ k_invincibilitytimer ] > 0 | | player - > kartstuff [ k_growshrinktimer ] > 0 | | player - > kartstuff [ k_hyudorotimer ] > 0
2018-07-03 19:14:47 +00:00
| | ( G_BattleGametype ( ) & & ( ( player - > kartstuff [ k_bumper ] < = 0 & & player - > kartstuff [ k_comebacktimer ] ) | | player - > kartstuff [ k_comebackmode ] = = 1 ) ) )
2018-07-27 00:12:42 +00:00
{
K_DoInstashield ( player ) ;
2017-02-07 22:19:04 +00:00
return ;
2018-07-27 00:12:42 +00:00
}
2016-08-15 03:51:08 +00:00
2018-03-04 19:28:29 +00:00
player - > mo - > momz = 18 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ;
2016-08-21 02:15:06 +00:00
player - > mo - > momx = player - > mo - > momy = 0 ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_sneakertimer ] = 0 ;
2017-02-19 17:18:43 +00:00
player - > kartstuff [ k_driftboost ] = 0 ;
2016-08-21 02:15:06 +00:00
2018-03-04 20:27:52 +00:00
if ( G_BattleGametype ( ) )
2017-10-22 07:06:35 +00:00
{
2017-10-22 21:26:43 +00:00
if ( source & & source - > player & & player ! = source - > player )
2018-07-01 08:36:09 +00:00
{
P_AddPlayerScore ( source - > player , scoremultiply ) ;
source - > player - > kartstuff [ k_wanted ] - = wantedreduce ;
player - > kartstuff [ k_wanted ] - = ( wantedreduce / 2 ) ;
}
2017-10-22 07:06:35 +00:00
2018-07-03 19:14:47 +00:00
if ( player - > kartstuff [ k_bumper ] > 0 )
2017-11-30 23:25:59 +00:00
{
2018-07-03 19:14:47 +00:00
if ( player - > kartstuff [ k_bumper ] = = 1 )
2018-06-16 04:00:46 +00:00
{
mobj_t * karmahitbox = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_KARMAHITBOX ) ; // Player hitbox is too small!!
P_SetTarget ( & karmahitbox - > target , player - > mo ) ;
karmahitbox - > destscale = player - > mo - > scale ;
P_SetScale ( karmahitbox , player - > mo - > scale ) ;
2018-07-03 19:14:47 +00:00
CONS_Printf ( M_GetText ( " %s lost all of their bumpers! \n " ) , player_names [ player - players ] ) ;
2018-06-16 04:00:46 +00:00
}
2018-07-06 18:22:48 +00:00
player - > kartstuff [ k_bumper ] - - ;
2018-07-04 01:12:25 +00:00
if ( K_IsPlayerWanted ( player ) )
K_CalculateBattleWanted ( ) ;
2017-11-30 23:25:59 +00:00
}
2018-07-03 19:14:47 +00:00
K_CheckBumpers ( ) ;
2017-10-22 07:06:35 +00:00
}
2017-11-17 05:48:36 +00:00
player - > kartstuff [ k_comebacktimer ] = comebacktime ;
2017-11-06 04:18:58 +00:00
2016-08-21 02:15:06 +00:00
player - > kartstuff [ k_spinouttype ] = 1 ;
player - > kartstuff [ k_spinouttimer ] = 2 * TICRATE + ( TICRATE / 2 ) ;
2018-08-11 04:12:41 +00:00
player - > powers [ pw_flashing ] = K_GetKartFlashing ( player ) ;
2016-08-21 02:15:06 +00:00
2017-11-04 14:07:53 +00:00
if ( player - > mo - > state ! = & states [ S_KART_SPIN ] )
P_SetPlayerMobjState ( player - > mo , S_KART_SPIN ) ;
2016-08-21 02:15:06 +00:00
P_PlayRinglossSound ( player - > mo ) ;
2017-10-24 21:58:59 +00:00
if ( P_IsLocalPlayer ( player ) )
{
quake . intensity = 64 * FRACUNIT ;
quake . time = 5 ;
}
2018-07-27 21:22:51 +00:00
player - > kartstuff [ k_instashield ] = 15 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
if ( cv_kartdebughuddrop . value )
K_DropItems ( player ) ;
else
K_DropHnextList ( player ) ;
2017-02-07 22:19:04 +00:00
return ;
2016-08-21 02:15:06 +00:00
}
2018-07-03 19:14:47 +00:00
void K_StealBumper ( player_t * player , player_t * victim , boolean force )
2017-11-01 22:46:35 +00:00
{
2018-07-03 19:14:47 +00:00
INT32 newbumper ;
2017-11-03 00:43:03 +00:00
angle_t newangle , diff ;
fixed_t newx , newy ;
mobj_t * newmo ;
2018-03-04 20:27:52 +00:00
if ( ! G_BattleGametype ( ) )
2017-11-01 22:46:35 +00:00
return ;
if ( player - > health < = 0 | | victim - > health < = 0 )
return ;
2018-06-20 00:20:06 +00:00
if ( ! force )
2017-11-20 00:39:40 +00:00
{
2018-07-03 19:14:47 +00:00
if ( victim - > kartstuff [ k_bumper ] < = 0 ) // || player->kartstuff[k_bumper] >= cv_kartbumpers.value+2
2017-11-20 00:39:40 +00:00
return ;
2017-11-01 22:46:35 +00:00
2018-07-27 00:12:42 +00:00
if ( player - > kartstuff [ k_squishedtimer ] > 0 | | player - > kartstuff [ k_spinouttimer ] > 0 )
return ;
if ( victim - > powers [ pw_flashing ] > 0 | | victim - > kartstuff [ k_squishedtimer ] > 0 | | victim - > kartstuff [ k_spinouttimer ] > 0
| | victim - > kartstuff [ k_invincibilitytimer ] > 0 | | victim - > kartstuff [ k_growshrinktimer ] > 0 | | victim - > kartstuff [ k_hyudorotimer ] > 0 )
{
K_DoInstashield ( victim ) ;
2017-11-20 00:39:40 +00:00
return ;
2018-07-27 00:12:42 +00:00
}
2017-11-20 00:39:40 +00:00
}
2017-11-01 22:46:35 +00:00
2017-12-28 23:37:25 +00:00
if ( netgame )
{
2018-07-03 19:14:47 +00:00
if ( player - > kartstuff [ k_bumper ] < = 0 )
2017-12-28 23:37:25 +00:00
CONS_Printf ( M_GetText ( " %s is back in the game! \n " ) , player_names [ player - players ] ) ;
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
else if ( cv_hazardlog . value )
2018-07-03 19:14:47 +00:00
CONS_Printf ( M_GetText ( " %s stole a bumper from %s! \n " ) , player_names [ player - players ] , player_names [ victim - players ] ) ;
2017-12-28 23:37:25 +00:00
}
2017-11-01 22:46:35 +00:00
2018-07-03 19:14:47 +00:00
newbumper = player - > kartstuff [ k_bumper ] ;
if ( newbumper < = 1 )
2017-11-03 00:43:03 +00:00
diff = 0 ;
else
2018-07-03 19:14:47 +00:00
diff = FixedAngle ( 360 * FRACUNIT / newbumper ) ;
2017-11-05 06:43:47 +00:00
newangle = player - > mo - > angle ;
2017-11-03 00:43:03 +00:00
newx = player - > mo - > x + P_ReturnThrustX ( player - > mo , newangle + ANGLE_180 , 64 * FRACUNIT ) ;
newy = player - > mo - > y + P_ReturnThrustY ( player - > mo , newangle + ANGLE_180 , 64 * FRACUNIT ) ;
2018-07-03 19:14:47 +00:00
newmo = P_SpawnMobj ( newx , newy , player - > mo - > z , MT_BATTLEBUMPER ) ;
newmo - > threshold = newbumper ;
2017-11-03 00:43:03 +00:00
P_SetTarget ( & newmo - > tracer , victim - > mo ) ;
P_SetTarget ( & newmo - > target , player - > mo ) ;
2018-07-03 19:14:47 +00:00
newmo - > angle = ( diff * ( newbumper - 1 ) ) ;
2017-11-03 00:43:03 +00:00
newmo - > color = victim - > skincolor ;
2018-07-03 19:14:47 +00:00
if ( newbumper + 1 < 2 )
P_SetMobjState ( newmo , S_BATTLEBUMPER3 ) ;
else if ( newbumper + 1 < 3 )
P_SetMobjState ( newmo , S_BATTLEBUMPER2 ) ;
2017-11-03 00:43:03 +00:00
else
2018-07-03 19:14:47 +00:00
P_SetMobjState ( newmo , S_BATTLEBUMPER1 ) ;
2017-11-01 22:46:35 +00:00
2018-06-26 16:02:14 +00:00
S_StartSound ( player - > mo , sfx_3db06 ) ;
2018-07-03 19:14:47 +00:00
player - > kartstuff [ k_bumper ] + + ;
2017-11-20 00:39:40 +00:00
player - > kartstuff [ k_comebackpoints ] = 0 ;
2018-08-11 04:12:41 +00:00
player - > powers [ pw_flashing ] = K_GetKartFlashing ( player ) ;
2017-11-23 02:40:17 +00:00
player - > kartstuff [ k_comebacktimer ] = comebacktime ;
2018-08-11 04:12:41 +00:00
/*victim->powers[pw_flashing] = K_GetKartFlashing(victim);
2017-12-24 01:55:23 +00:00
victim - > kartstuff [ k_comebacktimer ] = comebacktime ; */
2017-11-30 22:34:48 +00:00
2018-07-27 21:22:51 +00:00
victim - > kartstuff [ k_instashield ] = 15 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
if ( cv_kartdebughuddrop . value )
K_DropItems ( victim ) ;
else
K_DropHnextList ( victim ) ;
2017-11-01 22:46:35 +00:00
return ;
2017-11-03 00:43:03 +00:00
}
2017-11-01 22:46:35 +00:00
2017-11-05 17:15:19 +00:00
// source is the mobj that originally threw the bomb that exploded etc.
2018-02-05 22:53:31 +00:00
// Spawns the sphere around the explosion that handles spinout
2017-11-05 17:15:19 +00:00
void K_SpawnKartExplosion ( fixed_t x , fixed_t y , fixed_t z , fixed_t radius , INT32 number , mobjtype_t type , angle_t rotangle , boolean spawncenter , boolean ghostit , mobj_t * source )
2016-08-21 02:15:06 +00:00
{
mobj_t * mobj ;
mobj_t * ghost = NULL ;
INT32 i ;
TVector v ;
TVector * res ;
fixed_t finalx , finaly , finalz , dist ;
//mobj_t hoopcenter;
angle_t degrees , fa , closestangle ;
fixed_t mobjx , mobjy , mobjz ;
//hoopcenter.x = x;
//hoopcenter.y = y;
//hoopcenter.z = z;
//hoopcenter.z = z - mobjinfo[type].height/2;
degrees = FINEANGLES / number ;
closestangle = 0 ;
// Create the hoop!
for ( i = 0 ; i < number ; i + + )
2016-08-15 03:51:08 +00:00
{
2016-08-21 02:15:06 +00:00
fa = ( i * degrees ) ;
v [ 0 ] = FixedMul ( FINECOSINE ( fa ) , radius ) ;
v [ 1 ] = 0 ;
v [ 2 ] = FixedMul ( FINESINE ( fa ) , radius ) ;
v [ 3 ] = FRACUNIT ;
res = VectorMatrixMultiply ( v , * RotateXMatrix ( rotangle ) ) ;
M_Memcpy ( & v , res , sizeof ( v ) ) ;
res = VectorMatrixMultiply ( v , * RotateZMatrix ( closestangle ) ) ;
M_Memcpy ( & v , res , sizeof ( v ) ) ;
finalx = x + v [ 0 ] ;
finaly = y + v [ 1 ] ;
finalz = z + v [ 2 ] ;
mobj = P_SpawnMobj ( finalx , finaly , finalz , type ) ;
mobj - > z - = mobj - > height > > 1 ;
// change angle
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 ) ;
if ( dist < 1 )
dist = 1 ;
mobjx = mobj - > x ;
mobjy = mobj - > y ;
mobjz = mobj - > z ;
2016-08-15 03:51:08 +00:00
2016-08-21 02:15:06 +00:00
if ( ghostit )
2016-08-15 03:51:08 +00:00
{
2016-08-21 02:15:06 +00:00
ghost = P_SpawnGhostMobj ( mobj ) ;
P_SetMobjState ( mobj , S_NULL ) ;
mobj = ghost ;
}
2016-08-15 03:51:08 +00:00
2016-08-21 02:15:06 +00:00
if ( spawncenter )
{
mobj - > x = x ;
mobj - > y = y ;
mobj - > z = z ;
}
2018-02-05 19:24:54 +00:00
mobj - > momx = FixedMul ( FixedDiv ( mobjx - x , dist ) , FixedDiv ( dist , 6 * FRACUNIT ) ) ;
mobj - > momy = FixedMul ( FixedDiv ( mobjy - y , dist ) , FixedDiv ( dist , 6 * FRACUNIT ) ) ;
mobj - > momz = FixedMul ( FixedDiv ( mobjz - z , dist ) , FixedDiv ( dist , 6 * FRACUNIT ) ) ;
2016-08-21 02:15:06 +00:00
mobj - > flags | = MF_NOCLIPTHING ;
mobj - > flags & = ~ MF_SPECIAL ;
2017-11-05 17:15:19 +00:00
P_SetTarget ( & mobj - > target , source ) ;
2016-08-21 02:15:06 +00:00
}
}
2018-02-05 22:53:31 +00:00
// Spawns the purely visual explosion
2018-02-06 02:08:01 +00:00
void K_SpawnMineExplosion ( mobj_t * source , UINT8 color )
2018-02-05 22:53:31 +00:00
{
INT32 i , radius , height ;
mobj_t * smoldering = P_SpawnMobj ( source - > x , source - > y , source - > z , MT_SMOLDERING ) ;
mobj_t * dust ;
mobj_t * truc ;
INT32 speed , speed2 ;
2018-07-07 01:53:37 +00:00
smoldering - > tics = TICRATE * 3 ;
2018-02-05 22:53:31 +00:00
radius = source - > radius > > FRACBITS ;
height = source - > height > > FRACBITS ;
2018-02-06 01:10:20 +00:00
if ( ! color )
color = SKINCOLOR_RED ;
2018-02-05 22:53:31 +00:00
for ( i = 0 ; i < 32 ; i + + )
{
dust = P_SpawnMobj ( source - > x , source - > y , source - > z , MT_SMOKE ) ;
2018-02-06 00:23:10 +00:00
dust - > angle = ( ANGLE_180 / 16 ) * i ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
P_SetScale ( dust , source - > scale ) ;
2018-02-05 22:53:31 +00:00
dust - > destscale = source - > scale * 10 ;
P_InstaThrust ( dust , dust - > angle , FixedMul ( 20 * FRACUNIT , source - > scale ) ) ;
truc = P_SpawnMobj ( source - > x + P_RandomRange ( - radius , radius ) * FRACUNIT ,
source - > y + P_RandomRange ( - radius , radius ) * FRACUNIT ,
2018-02-08 15:46:07 +00:00
source - > z + P_RandomRange ( 0 , height ) * FRACUNIT , MT_BOOMEXPLODE ) ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
P_SetScale ( truc , source - > scale ) ;
2018-02-05 22:53:31 +00:00
truc - > destscale = source - > scale * 6 ;
speed = FixedMul ( 10 * FRACUNIT , source - > scale ) > > FRACBITS ;
truc - > momx = P_RandomRange ( - speed , speed ) * FRACUNIT ;
truc - > momy = P_RandomRange ( - speed , speed ) * FRACUNIT ;
speed = FixedMul ( 20 * FRACUNIT , source - > scale ) > > FRACBITS ;
truc - > momz = P_RandomRange ( - speed , speed ) * FRACUNIT ;
2018-02-06 01:10:20 +00:00
truc - > color = color ;
2018-02-05 22:53:31 +00:00
}
for ( i = 0 ; i < 16 ; i + + )
{
dust = P_SpawnMobj ( source - > x + P_RandomRange ( - radius , radius ) * FRACUNIT ,
source - > y + P_RandomRange ( - radius , radius ) * FRACUNIT ,
source - > z + P_RandomRange ( 0 , height ) * FRACUNIT , MT_SMOKE ) ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
P_SetScale ( dust , source - > scale ) ;
2018-02-05 22:53:31 +00:00
dust - > destscale = source - > scale * 10 ;
dust - > tics = 30 ;
dust - > momz = P_RandomRange ( FixedMul ( 3 * FRACUNIT , source - > scale ) > > FRACBITS , FixedMul ( 7 * FRACUNIT , source - > scale ) > > FRACBITS ) * FRACUNIT ;
truc = P_SpawnMobj ( source - > x + P_RandomRange ( - radius , radius ) * FRACUNIT ,
source - > y + P_RandomRange ( - radius , radius ) * FRACUNIT ,
source - > z + P_RandomRange ( 0 , height ) * FRACUNIT , MT_BOOMPARTICLE ) ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
P_SetScale ( truc , source - > scale ) ;
2018-02-05 22:53:31 +00:00
truc - > destscale = source - > scale * 5 ;
speed = FixedMul ( 20 * FRACUNIT , source - > scale ) > > FRACBITS ;
truc - > momx = P_RandomRange ( - speed , speed ) * FRACUNIT ;
truc - > momy = P_RandomRange ( - speed , speed ) * FRACUNIT ;
speed = FixedMul ( 15 * FRACUNIT , source - > scale ) > > FRACBITS ;
speed2 = FixedMul ( 45 * FRACUNIT , source - > scale ) > > FRACBITS ;
truc - > momz = P_RandomRange ( speed , speed2 ) * FRACUNIT ;
if ( P_RandomChance ( FRACUNIT / 2 ) )
truc - > momz = - truc - > momz ;
truc - > tics = TICRATE * 2 ;
2018-02-06 01:10:20 +00:00
truc - > color = color ;
2018-02-05 22:53:31 +00:00
}
}
2017-03-04 22:13:19 +00:00
static mobj_t * K_SpawnKartMissile ( mobj_t * source , mobjtype_t type , angle_t angle , INT32 flags2 , fixed_t speed )
2016-08-21 02:15:06 +00:00
{
mobj_t * th ;
angle_t an ;
fixed_t x , y , z ;
2018-06-05 02:53:45 +00:00
fixed_t finalspeed = speed ;
2017-11-21 07:23:06 +00:00
mobj_t * throwmo ;
2016-08-21 02:15:06 +00:00
//INT32 dir;
// angle at which you fire, is player angle
an = angle ;
//if (source->player->kartstuff[k_throwdir] != 0)
// dir = source->player->kartstuff[k_throwdir];
//else
// dir = 1;
2018-06-05 02:53:45 +00:00
if ( source - > player & & source - > player - > speed > K_GetKartSpeed ( source - > player , false ) )
finalspeed = FixedMul ( speed , FixedDiv ( source - > player - > speed , K_GetKartSpeed ( source - > player , false ) ) ) ;
x = source - > x + source - > momx + FixedMul ( finalspeed , FINECOSINE ( an > > ANGLETOFINESHIFT ) ) ;
y = source - > y + source - > momy + FixedMul ( finalspeed , FINESINE ( an > > ANGLETOFINESHIFT ) ) ;
2017-11-06 15:27:15 +00:00
z = source - > z ; // spawn on the ground please
if ( P_MobjFlip ( source ) < 0 )
{
z = source - > z + source - > height - mobjinfo [ type ] . height ;
}
2016-08-21 02:15:06 +00:00
th = P_SpawnMobj ( x , y , z , type ) ;
th - > flags2 | = flags2 ;
th - > threshold = 10 ;
# ifdef WEAPON_SFX
//Since rail and bounce have no thrown objects, this hack is necessary.
//Is creating thrown objects for rail and bounce more or less desirable than this?
if ( th - > info - > seesound & & ! ( th - > flags2 & MF2_RAILRING ) & & ! ( th - > flags2 & MF2_SCATTER ) )
S_StartSound ( source , th - > info - > seesound ) ;
# else
if ( th - > info - > seesound )
S_StartSound ( source , th - > info - > seesound ) ;
# endif
P_SetTarget ( & th - > target , source ) ;
2017-11-11 00:25:57 +00:00
if ( P_IsObjectOnGround ( source ) )
{
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs
P_TeleportMove ( th , th - > x , th - > y , th - > z ) ;
// spawn on the ground if the player is on the ground
if ( P_MobjFlip ( source ) < 0 )
{
th - > z = th - > ceilingz - th - > height ;
th - > eflags | = MFE_VERTICALFLIP ;
}
else
th - > z = th - > floorz ;
}
2016-08-21 02:15:06 +00:00
th - > angle = an ;
2018-06-05 02:53:45 +00:00
th - > momx = FixedMul ( finalspeed , FINECOSINE ( an > > ANGLETOFINESHIFT ) ) ;
th - > momy = FixedMul ( finalspeed , FINESINE ( an > > ANGLETOFINESHIFT ) ) ;
2016-08-21 02:15:06 +00:00
2018-07-23 00:55:18 +00:00
if ( type = = MT_ORBINAUT )
{
if ( source & & source - > player )
th - > color = source - > player - > skincolor ;
else
th - > color = SKINCOLOR_CLOUDY ;
}
2018-07-25 02:47:09 +00:00
else if ( type = = MT_JAWZ | | type = = MT_JAWZ_DUD )
{
S_StartSound ( th , th - > info - > activesound ) ;
}
2018-07-23 00:55:18 +00:00
2017-10-24 16:19:14 +00:00
x = x + P_ReturnThrustX ( source , an , source - > radius + th - > radius ) ;
2018-06-05 02:53:45 +00:00
y = y + P_ReturnThrustY ( source , an , source - > radius + th - > radius ) ;
2017-11-21 07:23:06 +00:00
throwmo = P_SpawnMobj ( x , y , z , MT_FIREDITEM ) ;
2017-10-24 16:19:14 +00:00
throwmo - > movecount = 1 ;
throwmo - > movedir = source - > angle - an ;
P_SetTarget ( & throwmo - > target , source ) ;
2016-08-21 02:15:06 +00:00
return NULL ;
}
2018-06-08 20:05:45 +00:00
void K_SpawnBoostTrail ( player_t * player )
2016-11-21 04:23:00 +00:00
{
fixed_t newx ;
fixed_t newy ;
fixed_t ground ;
mobj_t * flame ;
angle_t travelangle ;
INT32 i ;
I_Assert ( player ! = NULL ) ;
I_Assert ( player - > mo ! = NULL ) ;
I_Assert ( ! P_MobjWasRemoved ( player - > mo ) ) ;
2018-03-04 19:28:29 +00:00
if ( ! P_IsObjectOnGround ( player - > mo )
2018-03-12 04:58:13 +00:00
| | player - > kartstuff [ k_hyudorotimer ] ! = 0
2018-07-03 19:14:47 +00:00
| | ( G_BattleGametype ( ) & & player - > kartstuff [ k_bumper ] < = 0 & & player - > kartstuff [ k_comebacktimer ] ) )
2018-03-04 19:28:29 +00:00
return ;
2016-11-21 04:23:00 +00:00
if ( player - > mo - > eflags & MFE_VERTICALFLIP )
2018-02-05 23:55:52 +00:00
ground = player - > mo - > ceilingz - FixedMul ( mobjinfo [ MT_SNEAKERTRAIL ] . height , player - > mo - > scale ) ;
2016-11-21 04:23:00 +00:00
else
ground = player - > mo - > floorz ;
2017-03-07 01:05:18 +00:00
if ( player - > kartstuff [ k_drift ] ! = 0 )
2016-11-21 04:23:00 +00:00
travelangle = player - > mo - > angle ;
else
travelangle = R_PointToAngle2 ( 0 , 0 , player - > rmomx , player - > rmomy ) ;
for ( i = 0 ; i < 2 ; i + + )
{
newx = player - > mo - > x + P_ReturnThrustX ( player - > mo , travelangle + ( ( i & 1 ) ? - 1 : 1 ) * ANGLE_135 , FixedMul ( 24 * FRACUNIT , player - > mo - > scale ) ) ;
newy = player - > mo - > y + P_ReturnThrustY ( player - > mo , travelangle + ( ( i & 1 ) ? - 1 : 1 ) * ANGLE_135 , FixedMul ( 24 * FRACUNIT , player - > mo - > scale ) ) ;
# ifdef ESLOPE
if ( player - > mo - > standingslope )
{
ground = P_GetZAt ( player - > mo - > standingslope , newx , newy ) ;
if ( player - > mo - > eflags & MFE_VERTICALFLIP )
2018-02-05 23:55:52 +00:00
ground - = FixedMul ( mobjinfo [ MT_SNEAKERTRAIL ] . height , player - > mo - > scale ) ;
2016-11-21 04:23:00 +00:00
}
# endif
2018-06-10 02:50:21 +00:00
flame = P_SpawnMobj ( newx , newy , ground , MT_SNEAKERTRAIL ) ;
2016-11-21 04:23:00 +00:00
P_SetTarget ( & flame - > target , player - > mo ) ;
flame - > angle = travelangle ;
flame - > fuse = TICRATE * 2 ;
flame - > destscale = player - > mo - > scale ;
P_SetScale ( flame , player - > mo - > scale ) ;
flame - > eflags = ( flame - > eflags & ~ MFE_VERTICALFLIP ) | ( player - > mo - > eflags & MFE_VERTICALFLIP ) ;
flame - > momx = 8 ;
P_XYMovement ( flame ) ;
if ( P_MobjWasRemoved ( flame ) )
continue ;
if ( player - > mo - > eflags & MFE_VERTICALFLIP )
{
if ( flame - > z + flame - > height < flame - > ceilingz )
P_RemoveMobj ( flame ) ;
}
else if ( flame - > z > flame - > floorz )
P_RemoveMobj ( flame ) ;
}
}
2018-06-10 20:10:24 +00:00
void K_SpawnSparkleTrail ( mobj_t * mo )
2018-02-10 06:19:33 +00:00
{
2018-06-10 20:10:24 +00:00
const INT32 rad = ( mo - > radius * 2 ) > > FRACBITS ;
2018-02-10 06:19:33 +00:00
mobj_t * sparkle ;
INT32 i ;
2018-06-10 20:10:24 +00:00
I_Assert ( mo ! = NULL ) ;
I_Assert ( ! P_MobjWasRemoved ( mo ) ) ;
2018-02-10 06:19:33 +00:00
for ( i = 0 ; i < 3 ; i + + )
{
2018-06-10 20:10:24 +00:00
fixed_t newx = mo - > x + mo - > momx + ( P_RandomRange ( - rad , rad ) < < FRACBITS ) ;
fixed_t newy = mo - > y + mo - > momy + ( P_RandomRange ( - rad , rad ) < < FRACBITS ) ;
fixed_t newz = mo - > z + mo - > momz + ( P_RandomRange ( 0 , mo - > height > > FRACBITS ) < < FRACBITS ) ;
2018-02-10 06:19:33 +00:00
sparkle = P_SpawnMobj ( newx , newy , newz , MT_SPARKLETRAIL ) ;
2018-08-09 21:59:52 +00:00
//if (i == 0)
//P_SetMobjState(sparkle, S_KARTINVULN_LARGE1);
2018-02-10 06:19:33 +00:00
2018-06-10 20:10:24 +00:00
P_SetTarget ( & sparkle - > target , mo ) ;
sparkle - > destscale = mo - > destscale ;
P_SetScale ( sparkle , mo - > scale ) ;
sparkle - > eflags = ( sparkle - > eflags & ~ MFE_VERTICALFLIP ) | ( mo - > eflags & MFE_VERTICALFLIP ) ;
sparkle - > color = mo - > color ;
//sparkle->colorized = mo->colorized;
2018-02-10 06:19:33 +00:00
}
2018-08-09 21:59:52 +00:00
P_SetMobjState ( sparkle , S_KARTINVULN_LARGE1 ) ;
2018-02-10 06:19:33 +00:00
}
2018-07-25 16:49:30 +00:00
void K_SpawnWipeoutTrail ( mobj_t * mo , boolean translucent )
2018-07-20 02:37:32 +00:00
{
mobj_t * dust ;
I_Assert ( mo ! = NULL ) ;
I_Assert ( ! P_MobjWasRemoved ( mo ) ) ;
dust = P_SpawnMobj ( mo - > x + ( P_RandomRange ( - 25 , 25 ) < < FRACBITS ) , mo - > y + ( P_RandomRange ( - 25 , 25 ) < < FRACBITS ) , mo - > z , MT_WIPEOUTTRAIL ) ;
P_SetTarget ( & dust - > target , mo ) ;
dust - > angle = R_PointToAngle2 ( 0 , 0 , mo - > momx , mo - > momy ) ;
dust - > destscale = mo - > scale ;
P_SetScale ( dust , mo - > scale ) ;
dust - > eflags = ( dust - > eflags & ~ MFE_VERTICALFLIP ) | ( mo - > eflags & MFE_VERTICALFLIP ) ;
2018-07-25 16:49:30 +00:00
if ( translucent )
dust - > flags2 | = MF2_SHADOW ;
2018-07-20 02:37:32 +00:00
}
2018-06-08 20:05:45 +00:00
// K_DriftDustHandling
// Parameters:
// spawner: The map object that is spawning the drift dust
// Description: Spawns the drift dust for objects, players use rmomx/y, other objects use regular momx/y.
// Also plays the drift sound.
// Other objects should be angled towards where they're trying to go so they don't randomly spawn dust
// Do note that most of the function won't run in odd intervals of frames
void K_DriftDustHandling ( mobj_t * spawner )
{
angle_t anglediff ;
const INT16 spawnrange = spawner - > radius > > FRACBITS ;
if ( ! P_IsObjectOnGround ( spawner ) | | leveltime % 2 ! = 0 )
return ;
if ( spawner - > player )
{
2018-06-30 22:18:13 +00:00
if ( spawner - > player - > pflags & PF_SKIDDOWN )
2018-06-08 20:05:45 +00:00
{
2018-06-30 22:18:13 +00:00
anglediff = abs ( spawner - > angle - spawner - > player - > frameangle ) ;
if ( leveltime % 6 = = 0 )
S_StartSound ( spawner , sfx_screec ) ; // repeated here because it doesn't always happen to be within the range when this is the case
2018-06-08 20:05:45 +00:00
}
else
{
2018-06-30 22:18:13 +00:00
angle_t playerangle = spawner - > angle ;
if ( spawner - > player - > speed < 5 < < FRACBITS )
return ;
if ( spawner - > player - > cmd . forwardmove < 0 )
playerangle + = ANGLE_180 ;
anglediff = abs ( playerangle - R_PointToAngle2 ( 0 , 0 , spawner - > player - > rmomx , spawner - > player - > rmomy ) ) ;
2018-06-08 20:05:45 +00:00
}
}
else
{
if ( P_AproxDistance ( spawner - > momx , spawner - > momy ) < 5 < < FRACBITS )
return ;
anglediff = abs ( spawner - > angle - R_PointToAngle2 ( 0 , 0 , spawner - > momx , spawner - > momy ) ) ;
}
if ( anglediff > ANGLE_180 )
anglediff = InvAngle ( anglediff ) ;
if ( anglediff > ANG10 * 4 ) // Trying to turn further than 40 degrees
{
fixed_t spawnx = P_RandomRange ( - spawnrange , spawnrange ) < < FRACBITS ;
fixed_t spawny = P_RandomRange ( - spawnrange , spawnrange ) < < FRACBITS ;
INT32 speedrange = 2 ;
mobj_t * dust = P_SpawnMobj ( spawner - > x + spawnx , spawner - > y + spawny , spawner - > z , MT_DRIFTDUST ) ;
2018-07-28 06:37:00 +00:00
if ( spawner - > eflags & MFE_VERTICALFLIP )
{
dust - > z + = spawner - > height - dust - > height ;
}
2018-06-08 20:05:45 +00:00
dust - > momx = FixedMul ( spawner - > momx + ( P_RandomRange ( - speedrange , speedrange ) < < FRACBITS ) , 3 * FRACUNIT / 4 ) ;
dust - > momy = FixedMul ( spawner - > momy + ( P_RandomRange ( - speedrange , speedrange ) < < FRACBITS ) , 3 * FRACUNIT / 4 ) ;
dust - > momz = P_MobjFlip ( spawner ) * P_RandomRange ( 1 , 4 ) < < FRACBITS ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
P_SetScale ( dust , spawner - > scale / 2 ) ;
2018-06-08 20:05:45 +00:00
dust - > destscale = spawner - > scale * 3 ;
2018-06-11 06:15:27 +00:00
2018-06-08 20:05:45 +00:00
if ( leveltime % 6 = = 0 )
S_StartSound ( spawner , sfx_screec ) ;
2018-06-11 06:15:27 +00:00
// Now time for a bunch of flag shit, groooooaann...
if ( spawner - > flags2 & MF2_DONTDRAW )
dust - > flags2 | = MF2_DONTDRAW ;
else
dust - > flags2 & = ~ MF2_DONTDRAW ;
2018-07-28 06:37:00 +00:00
if ( spawner - > eflags & MFE_VERTICALFLIP )
dust - > eflags | = MFE_VERTICALFLIP ;
else
dust - > eflags & = ~ MFE_VERTICALFLIP ;
2018-06-11 06:15:27 +00:00
if ( spawner - > eflags & MFE_DRAWONLYFORP1 )
dust - > eflags | = MFE_DRAWONLYFORP1 ;
else
dust - > eflags & = ~ MFE_DRAWONLYFORP1 ;
if ( spawner - > eflags & MFE_DRAWONLYFORP2 )
dust - > eflags | = MFE_DRAWONLYFORP2 ;
else
dust - > eflags & = ~ MFE_DRAWONLYFORP2 ;
if ( spawner - > eflags & MFE_DRAWONLYFORP3 )
dust - > eflags | = MFE_DRAWONLYFORP3 ;
else
dust - > eflags & = ~ MFE_DRAWONLYFORP3 ;
if ( spawner - > eflags & MFE_DRAWONLYFORP4 )
dust - > eflags | = MFE_DRAWONLYFORP4 ;
else
dust - > eflags & = ~ MFE_DRAWONLYFORP4 ;
2018-06-08 20:05:45 +00:00
}
}
2018-06-27 19:58:43 +00:00
static mobj_t * K_FindLastTrailMobj ( player_t * player )
2018-06-16 21:54:12 +00:00
{
2018-06-28 00:20:19 +00:00
mobj_t * trail ;
2018-06-16 21:54:12 +00:00
2018-07-01 08:36:09 +00:00
if ( ! player | | ! ( trail = player - > mo ) | | ! player - > mo - > hnext | | ! player - > mo - > hnext - > health )
2018-06-16 21:54:12 +00:00
return NULL ;
2018-07-04 21:25:38 +00:00
2018-07-01 08:36:09 +00:00
while ( trail - > hnext & & ! P_MobjWasRemoved ( trail - > hnext ) & & trail - > hnext - > health )
2018-06-16 21:54:12 +00:00
{
2018-06-16 23:57:08 +00:00
trail = trail - > hnext ;
2018-06-16 21:54:12 +00:00
}
return trail ;
}
2018-09-04 23:58:20 +00:00
static mobj_t * K_ThrowKartItem ( player_t * player , boolean missile , mobjtype_t mapthing , INT32 defaultDir , INT32 altthrow )
2016-08-21 02:15:06 +00:00
{
mobj_t * mo ;
2017-10-11 14:48:32 +00:00
INT32 dir , PROJSPEED ;
2016-08-21 02:15:06 +00:00
angle_t newangle ;
2018-07-25 16:49:30 +00:00
fixed_t newx , newy , newz ;
2017-11-21 07:23:06 +00:00
mobj_t * throwmo ;
2016-08-21 02:15:06 +00:00
if ( ! player )
return NULL ;
2018-02-10 21:01:09 +00:00
// Figure out projectile speed by game speed
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
switch ( gamespeed )
2017-10-11 14:48:32 +00:00
{
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
case 0 :
2018-02-10 21:01:09 +00:00
PROJSPEED = 68 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ; // Avg Speed is 34
2017-10-11 14:48:32 +00:00
break ;
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
case 2 :
2018-02-10 21:01:09 +00:00
PROJSPEED = 96 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ; // Avg Speed is 48
2017-10-11 14:48:32 +00:00
break ;
default :
2018-02-10 21:01:09 +00:00
PROJSPEED = 82 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ; // Avg Speed is 41
2017-10-11 14:48:32 +00:00
break ;
}
2018-09-04 23:58:20 +00:00
if ( altthrow )
2016-08-21 02:15:06 +00:00
{
2018-09-04 23:58:20 +00:00
if ( altthrow = = 2 ) // Kitchen sink throwing
{
if ( player - > kartstuff [ k_throwdir ] = = 1 )
dir = 3 ;
else if ( player - > kartstuff [ k_throwdir ] = = - 1 )
dir = 1 ;
else
dir = 2 ;
}
2016-08-21 02:15:06 +00:00
else
2018-09-04 23:58:20 +00:00
{
if ( player - > kartstuff [ k_throwdir ] = = 1 )
dir = 2 ;
else if ( player - > kartstuff [ k_throwdir ] = = - 1 )
dir = - 1 ;
else
dir = 1 ;
}
2016-08-21 02:15:06 +00:00
}
else
{
if ( player - > kartstuff [ k_throwdir ] ! = 0 )
dir = player - > kartstuff [ k_throwdir ] ;
else
dir = defaultDir ;
}
2018-06-18 04:42:53 +00:00
if ( missile ) // Shootables
2016-08-21 02:15:06 +00:00
{
2018-06-25 21:12:01 +00:00
if ( mapthing = = MT_BALLHOG ) // Messy
2016-08-21 02:15:06 +00:00
{
2017-05-13 15:14:26 +00:00
if ( dir = = - 1 )
2016-08-21 02:15:06 +00:00
{
2017-05-13 15:14:26 +00:00
// Shoot backward
2018-08-29 22:12:02 +00:00
mo = K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + ANGLE_180 - 0x06000000 , 0 , PROJSPEED / 4 ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + ANGLE_180 - 0x03000000 , 0 , PROJSPEED / 4 ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + ANGLE_180 , 0 , PROJSPEED / 4 ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + ANGLE_180 + 0x03000000 , 0 , PROJSPEED / 4 ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + ANGLE_180 + 0x06000000 , 0 , PROJSPEED / 4 ) ;
2017-05-13 15:14:26 +00:00
}
else
{
// Shoot forward
2017-11-06 15:27:15 +00:00
mo = K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle - 0x06000000 , 0 , PROJSPEED ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle - 0x03000000 , 0 , PROJSPEED ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle , 0 , PROJSPEED ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + 0x03000000 , 0 , PROJSPEED ) ;
K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + 0x06000000 , 0 , PROJSPEED ) ;
2016-08-21 02:15:06 +00:00
}
}
2018-06-18 04:42:53 +00:00
else
2016-08-21 02:15:06 +00:00
{
2017-05-13 15:14:26 +00:00
if ( dir = = - 1 )
{
// Shoot backward
2018-08-29 22:12:02 +00:00
mo = K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle + ANGLE_180 , 0 , PROJSPEED / 4 ) ;
2017-05-13 15:14:26 +00:00
}
else
2016-08-21 02:15:06 +00:00
{
2017-05-13 15:14:26 +00:00
// Shoot forward
2018-06-05 02:53:45 +00:00
mo = K_SpawnKartMissile ( player - > mo , mapthing , player - > mo - > angle , 0 , PROJSPEED ) ;
2016-08-21 02:15:06 +00:00
}
}
}
else
{
2018-08-06 15:19:07 +00:00
player - > kartstuff [ k_bananadrag ] = 0 ; // RESET timer, for multiple bananas
2018-09-04 23:58:20 +00:00
if ( dir > 0 )
2016-08-21 02:15:06 +00:00
{
// Shoot forward
2017-11-03 01:40:06 +00:00
mo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z + player - > mo - > height / 2 , mapthing ) ;
2016-08-21 02:15:06 +00:00
mo - > threshold = 10 ;
P_SetTarget ( & mo - > target , player - > mo ) ;
2017-10-24 19:59:09 +00:00
S_StartSound ( player - > mo , mo - > info - > seesound ) ;
2016-08-21 02:15:06 +00:00
if ( mo )
{
angle_t fa = player - > mo - > angle > > ANGLETOFINESHIFT ;
2018-09-04 23:58:20 +00:00
INT32 HEIGHT = ( 20 + ( dir * 10 ) ) * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) + player - > mo - > momz ;
2016-08-21 02:15:06 +00:00
2018-09-04 23:58:20 +00:00
mo - > momx = player - > mo - > momx + FixedMul ( FINECOSINE ( fa ) , ( altthrow = = 2 ? 2 * PROJSPEED / 3 : PROJSPEED ) ) ;
mo - > momy = player - > mo - > momy + FixedMul ( FINESINE ( fa ) , ( altthrow = = 2 ? 2 * PROJSPEED / 3 : PROJSPEED ) ) ;
2017-11-06 15:27:15 +00:00
mo - > momz = P_MobjFlip ( player - > mo ) * HEIGHT ;
2016-08-21 02:15:06 +00:00
if ( player - > mo - > eflags & MFE_VERTICALFLIP )
mo - > eflags | = MFE_VERTICALFLIP ;
}
2017-10-24 16:19:14 +00:00
2017-11-21 07:23:06 +00:00
throwmo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z + player - > mo - > height / 2 , MT_FIREDITEM ) ;
2017-10-24 16:19:14 +00:00
P_SetTarget ( & throwmo - > target , player - > mo ) ;
throwmo - > movecount = 0 ; // above player
2016-08-15 03:51:08 +00:00
}
else
2016-08-21 02:15:06 +00:00
{
2018-06-16 21:54:12 +00:00
mobj_t * lasttrail = K_FindLastTrailMobj ( player ) ;
2017-11-06 15:27:15 +00:00
2018-06-16 21:54:12 +00:00
if ( lasttrail )
{
newx = lasttrail - > x ;
newy = lasttrail - > y ;
2018-07-25 16:49:30 +00:00
newz = lasttrail - > z ;
2018-06-16 21:54:12 +00:00
}
else
{
// Drop it directly behind you.
fixed_t dropradius = FixedHypot ( player - > mo - > radius , player - > mo - > radius ) + FixedHypot ( mobjinfo [ mapthing ] . radius , mobjinfo [ mapthing ] . radius ) ;
2016-08-21 02:15:06 +00:00
2018-06-16 21:54:12 +00:00
newangle = player - > mo - > angle ;
newx = player - > mo - > x + P_ReturnThrustX ( player - > mo , newangle + ANGLE_180 , dropradius ) ;
newy = player - > mo - > y + P_ReturnThrustY ( player - > mo , newangle + ANGLE_180 , dropradius ) ;
2018-07-25 16:49:30 +00:00
newz = player - > mo - > z ;
2018-06-16 21:54:12 +00:00
}
2016-08-21 02:15:06 +00:00
2018-07-25 16:49:30 +00:00
mo = P_SpawnMobj ( newx , newy , newz , mapthing ) ;
2016-08-15 03:51:08 +00:00
2017-11-11 00:25:57 +00:00
if ( P_MobjFlip ( player - > mo ) < 0 )
mo - > z = player - > mo - > z + player - > mo - > height - mo - > height ;
2017-11-06 15:27:15 +00:00
mo - > threshold = 10 ;
2016-08-21 02:15:06 +00:00
P_SetTarget ( & mo - > target , player - > mo ) ;
2016-08-15 03:51:08 +00:00
2017-11-11 00:25:57 +00:00
if ( P_IsObjectOnGround ( player - > mo ) )
{
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs
P_TeleportMove ( mo , mo - > x , mo - > y , mo - > z ) ;
if ( P_MobjFlip ( mo ) > 0 )
{
if ( mo - > floorz > mo - > target - > z - mo - > height )
{
mo - > z = mo - > floorz ;
}
}
else
{
if ( mo - > ceilingz < mo - > target - > z + mo - > target - > height + mo - > height )
{
mo - > z = mo - > ceilingz - mo - > height ;
}
}
}
2016-08-21 02:15:06 +00:00
if ( mo )
{
if ( player - > mo - > eflags & MFE_VERTICALFLIP )
mo - > eflags | = MFE_VERTICALFLIP ;
}
}
2016-08-15 03:51:08 +00:00
}
2018-07-23 00:55:18 +00:00
2016-08-21 02:15:06 +00:00
return mo ;
2016-08-15 03:51:08 +00:00
}
2018-08-04 19:48:31 +00:00
static void K_DoThunderShield ( player_t * player )
2017-02-18 18:39:25 +00:00
{
S_StartSound ( player - > mo , sfx_s3k45 ) ;
2018-08-04 19:48:31 +00:00
//player->kartstuff[k_thunderanim] = 35;
2017-05-18 03:09:38 +00:00
P_NukeEnemies ( player - > mo , player - > mo , RING_DIST / 4 ) ;
2017-02-18 18:39:25 +00:00
}
2018-02-05 23:55:52 +00:00
static void K_DoHyudoroSteal ( player_t * player )
2016-08-15 03:51:08 +00:00
{
2016-08-21 02:15:06 +00:00
INT32 i , numplayers = 0 ;
INT32 playerswappable [ MAXPLAYERS ] ;
2018-01-08 20:48:19 +00:00
INT32 stealplayer = - 1 ; // The player that's getting stolen from
2016-08-21 02:15:06 +00:00
INT32 prandom = 0 ;
2018-08-04 19:48:31 +00:00
boolean sink = P_RandomChance ( FRACUNIT / 64 ) ;
2016-08-15 03:51:08 +00:00
2016-08-21 02:15:06 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( playeringame [ i ] & & players [ i ] . mo & & players [ i ] . mo - > health > 0 & & players [ i ] . playerstate = = PST_LIVE
2018-01-08 20:48:19 +00:00
& & player ! = & players [ i ] & & ! players [ i ] . exiting & & ! players [ i ] . spectator // Player in-game
// Can steal from this player
2018-06-15 06:18:43 +00:00
& & ( G_RaceGametype ( ) //&& players[i].kartstuff[k_position] < player->kartstuff[k_position])
2018-07-03 19:14:47 +00:00
| | ( G_BattleGametype ( ) & & players [ i ] . kartstuff [ k_bumper ] > 0 ) )
2016-08-21 02:15:06 +00:00
2018-01-08 20:48:19 +00:00
// Has an item
2018-02-05 23:55:52 +00:00
& & ( players [ i ] . kartstuff [ k_itemtype ]
& & players [ i ] . kartstuff [ k_itemamount ]
& & ! players [ i ] . kartstuff [ k_itemheld ] ) )
2016-08-21 02:15:06 +00:00
{
2018-01-08 20:48:19 +00:00
playerswappable [ numplayers ] = i ;
2016-08-21 02:15:06 +00:00
numplayers + + ;
}
}
2016-08-15 03:51:08 +00:00
2016-08-21 02:15:06 +00:00
prandom = P_RandomFixed ( ) ;
2018-06-15 06:18:43 +00:00
S_StartSound ( player - > mo , sfx_s3k92 ) ;
2016-08-15 03:51:08 +00:00
2018-08-31 17:18:19 +00:00
if ( sink & & numplayers > 0 & & cv_kitchensink . value ) // BEHOLD THE KITCHEN SINK
2018-06-25 05:36:21 +00:00
{
player - > kartstuff [ k_hyudorotimer ] = hyudorotime ;
player - > kartstuff [ k_stealingtimer ] = stealtime ;
player - > kartstuff [ k_itemtype ] = KITEM_KITCHENSINK ;
player - > kartstuff [ k_itemamount ] = 1 ;
player - > kartstuff [ k_itemheld ] = 0 ;
return ;
}
else if ( ( G_RaceGametype ( ) & & player - > kartstuff [ k_position ] = = 1 ) | | numplayers = = 0 ) // No-one can be stolen from? Oh well...
2016-08-21 02:15:06 +00:00
{
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_hyudorotimer ] = hyudorotime ;
player - > kartstuff [ k_stealingtimer ] = stealtime ;
2016-08-21 02:15:06 +00:00
return ;
}
else if ( numplayers = = 1 ) // With just 2 players, we just need to set the other player to be the one to steal from
{
2018-01-08 20:48:19 +00:00
stealplayer = playerswappable [ numplayers - 1 ] ;
2016-08-21 02:15:06 +00:00
}
else if ( numplayers > 1 ) // We need to choose between the available candidates for the 2nd player
{
stealplayer = playerswappable [ prandom % ( numplayers - 1 ) ] ;
}
2016-08-15 03:51:08 +00:00
2018-01-08 20:48:19 +00:00
if ( stealplayer > - 1 ) // Now here's where we do the stealing, has to be done here because we still know the player we're stealing from
2016-08-15 03:51:08 +00:00
{
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_hyudorotimer ] = hyudorotime ;
player - > kartstuff [ k_stealingtimer ] = stealtime ;
players [ stealplayer ] . kartstuff [ k_stolentimer ] = stealtime ;
2016-08-15 03:51:08 +00:00
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemtype ] = players [ stealplayer ] . kartstuff [ k_itemtype ] ;
player - > kartstuff [ k_itemamount ] = players [ stealplayer ] . kartstuff [ k_itemamount ] ;
player - > kartstuff [ k_itemheld ] = 0 ;
players [ stealplayer ] . kartstuff [ k_itemtype ] = KITEM_NONE ;
players [ stealplayer ] . kartstuff [ k_itemamount ] = 0 ;
players [ stealplayer ] . kartstuff [ k_itemheld ] = 0 ;
2018-06-15 06:18:43 +00:00
2018-06-15 07:02:05 +00:00
if ( P_IsLocalPlayer ( & players [ stealplayer ] ) & & ! splitscreen )
2018-06-15 06:18:43 +00:00
S_StartSound ( NULL , sfx_s3k92 ) ;
2016-08-21 02:15:06 +00:00
}
}
2016-08-15 03:51:08 +00:00
2018-03-31 04:44:03 +00:00
void K_DoSneaker ( player_t * player , boolean doPFlag )
2016-08-21 02:15:06 +00:00
{
2018-09-05 15:19:00 +00:00
const fixed_t prevboost = player - > kartstuff [ k_speedboost ] ;
2017-02-07 22:19:04 +00:00
if ( ! player - > kartstuff [ k_floorboost ] | | player - > kartstuff [ k_floorboost ] = = 3 )
2018-06-26 16:02:14 +00:00
S_StartSound ( player - > mo , sfx_cdfm01 ) ;
2017-02-07 22:19:04 +00:00
2018-09-07 03:49:51 +00:00
if ( ! player - > kartstuff [ k_sneakertimer ] )
{
mobj_t * overlay = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_BOOSTFLAME ) ;
P_SetTarget ( & overlay - > target , player - > mo ) ;
overlay - > destscale = player - > mo - > scale ;
P_SetScale ( overlay , player - > mo - > scale ) ;
}
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_sneakertimer ] = sneakertime ;
2017-02-07 22:19:04 +00:00
2016-08-21 02:15:06 +00:00
if ( doPFlag )
player - > pflags | = PF_ATTACKDOWN ;
2016-08-15 03:51:08 +00:00
2017-02-26 15:19:12 +00:00
K_PlayTauntSound ( player - > mo ) ;
2018-09-05 15:19:00 +00:00
K_GetKartBoostPower ( player ) ;
2018-09-06 17:02:08 +00:00
if ( player - > kartstuff [ k_speedboost ] > prevboost )
player - > kartstuff [ k_destboostcam ] = FRACUNIT ;
2016-08-21 02:15:06 +00:00
}
2018-06-07 23:39:45 +00:00
static void K_DoShrink ( player_t * player )
2016-08-21 02:15:06 +00:00
{
2018-06-11 05:51:50 +00:00
INT32 i ;
2018-02-10 21:01:09 +00:00
2018-06-15 06:18:43 +00:00
S_StartSound ( player - > mo , sfx_kc46 ) ; // Sound the BANG!
2016-08-21 02:15:06 +00:00
player - > pflags | = PF_ATTACKDOWN ;
2018-06-11 05:51:50 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
2017-02-26 22:37:52 +00:00
{
2018-06-11 05:51:50 +00:00
/*if (playeringame[i])
P_FlashPal ( & players [ i ] , PAL_NUKE , 10 ) ; */
2017-02-26 22:37:52 +00:00
2018-06-11 05:51:50 +00:00
if ( playeringame [ i ] & & players [ i ] . mo & & ! player - > spectator
& & players [ i ] . kartstuff [ k_position ] < player - > kartstuff [ k_position ] )
P_DamageMobj ( players [ i ] . mo , player - > mo , player - > mo , 64 ) ;
2016-08-15 03:51:08 +00:00
}
2016-08-21 02:15:06 +00:00
2017-03-02 22:59:35 +00:00
K_PlayTauntSound ( player - > mo ) ;
2016-08-15 03:51:08 +00:00
}
2018-06-07 23:39:45 +00:00
static void K_DoSPB ( player_t * victim , player_t * source )
2018-06-06 01:36:48 +00:00
{
2018-06-08 04:02:28 +00:00
//INT32 i;
2018-06-06 01:36:48 +00:00
S_StartSound ( victim - > mo , sfx_bkpoof ) ; // Sound the BANG!
2018-06-07 23:39:45 +00:00
/*for (i = 0; i < MAXPLAYERS; i++)
2018-06-06 01:36:48 +00:00
{
if ( playeringame [ i ] )
P_FlashPal ( & players [ i ] , PAL_NUKE , 10 ) ;
2018-06-07 23:39:45 +00:00
} */
2018-06-06 01:36:48 +00:00
if ( victim - > mo & & ! victim - > spectator )
P_DamageMobj ( victim - > mo , source - > mo , source - > mo , 65 ) ;
}
2018-07-17 01:27:50 +00:00
void K_DoPogoSpring ( mobj_t * mo , fixed_t vertispeed , boolean mute )
2017-11-07 07:36:27 +00:00
{
2018-08-23 16:53:29 +00:00
const fixed_t vscale = mapheaderinfo [ gamemap - 1 ] - > mobj_scale + ( mo - > scale - mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ;
2018-07-14 00:45:18 +00:00
2017-11-19 07:37:28 +00:00
if ( mo - > player & & mo - > player - > spectator )
2017-11-07 07:36:27 +00:00
return ;
2017-11-19 07:37:28 +00:00
if ( mo - > eflags & MFE_SPRUNG )
2017-11-07 07:36:27 +00:00
return ;
# ifdef ESLOPE
2017-11-19 07:37:28 +00:00
mo - > standingslope = NULL ;
2017-11-07 07:36:27 +00:00
# endif
2017-11-19 07:37:28 +00:00
mo - > eflags | = MFE_SPRUNG ;
if ( mo - > eflags & MFE_VERTICALFLIP )
2017-11-07 07:36:27 +00:00
vertispeed * = - 1 ;
2017-11-19 07:37:28 +00:00
if ( vertispeed = = 0 )
{
fixed_t thrust ;
if ( mo - > player )
{
thrust = 3 * mo - > player - > speed / 2 ;
if ( thrust < 48 < < FRACBITS )
thrust = 48 < < FRACBITS ;
2017-11-23 02:40:17 +00:00
if ( thrust > 72 < < FRACBITS )
thrust = 72 < < FRACBITS ;
2018-07-14 00:45:18 +00:00
if ( mo - > player - > kartstuff [ k_pogospring ] ! = 2 )
{
if ( mo - > player - > kartstuff [ k_sneakertimer ] )
thrust = FixedMul ( thrust , 5 * FRACUNIT / 4 ) ;
else if ( mo - > player - > kartstuff [ k_invincibilitytimer ] )
thrust = FixedMul ( thrust , 9 * FRACUNIT / 8 ) ;
}
2017-11-19 07:37:28 +00:00
}
else
{
2018-06-20 00:20:06 +00:00
thrust = FixedDiv ( 3 * P_AproxDistance ( mo - > momx , mo - > momy ) / 2 , 5 * FRACUNIT / 2 ) ;
if ( thrust < 16 < < FRACBITS )
2018-01-08 20:48:19 +00:00
thrust = 16 < < FRACBITS ;
2018-06-20 00:20:06 +00:00
if ( thrust > 32 < < FRACBITS )
thrust = 32 < < FRACBITS ;
2017-11-19 07:37:28 +00:00
}
2018-06-20 00:20:06 +00:00
2018-08-23 16:53:29 +00:00
mo - > momz = FixedMul ( FINESINE ( ANGLE_22h > > ANGLETOFINESHIFT ) , FixedMul ( thrust , vscale ) ) ;
2017-11-19 07:37:28 +00:00
}
else
2018-08-23 16:53:29 +00:00
mo - > momz = FixedMul ( vertispeed , vscale ) ;
2017-11-19 07:37:28 +00:00
2018-07-17 01:27:50 +00:00
if ( ! mute )
S_StartSound ( mo , sfx_kc2f ) ;
2017-11-07 07:36:27 +00:00
}
2018-06-16 23:57:08 +00:00
void K_KillBananaChain ( mobj_t * banana , mobj_t * inflictor , mobj_t * source )
{
2018-08-06 15:19:07 +00:00
mobj_t * cachenext ;
killnext :
cachenext = banana - > hnext ;
2018-06-16 23:57:08 +00:00
if ( banana - > health )
{
if ( banana - > eflags & MFE_VERTICALFLIP )
banana - > z - = banana - > height ;
else
banana - > z + = banana - > height ;
S_StartSound ( banana , banana - > info - > deathsound ) ;
P_KillMobj ( banana , inflictor , source ) ;
P_SetObjectMomZ ( banana , 8 * FRACUNIT , false ) ;
if ( inflictor )
P_InstaThrust ( banana , R_PointToAngle2 ( inflictor - > x , inflictor - > y , banana - > x , banana - > y ) + ANGLE_90 , 16 * FRACUNIT ) ;
}
2018-08-06 15:19:07 +00:00
if ( ( banana = cachenext ) )
goto killnext ;
2018-06-16 23:57:08 +00:00
}
2018-08-24 14:14:18 +00:00
// Just for firing/dropping items.
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
void K_UpdateHnextList ( player_t * player , boolean clean )
2018-08-24 14:14:18 +00:00
{
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
mobj_t * work = player - > mo , * nextwork ;
2018-08-24 14:14:18 +00:00
if ( ! work )
return ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
nextwork = work - > hnext ;
2018-08-24 14:14:18 +00:00
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
while ( ( work = nextwork ) & & ! P_MobjWasRemoved ( work ) )
2018-08-24 14:14:18 +00:00
{
nextwork = work - > hnext ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
if ( ! clean & & ( ! work - > movedir | | work - > movedir < = ( UINT16 ) player - > kartstuff [ k_itemamount ] ) )
continue ;
2018-08-24 14:14:18 +00:00
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
P_RemoveMobj ( work ) ;
2018-08-24 14:14:18 +00:00
}
}
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
// For getting hit!
void K_DropHnextList ( player_t * player )
2018-08-24 14:14:18 +00:00
{
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
mobj_t * work = player - > mo , * nextwork , * dropwork ;
INT32 flip ;
mobjtype_t type ;
boolean orbit , ponground ;
2018-08-24 14:14:18 +00:00
if ( ! work )
return ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
flip = P_MobjFlip ( player - > mo ) ;
ponground = P_IsObjectOnGround ( player - > mo ) ;
if ( player - > kartstuff [ k_itemtype ] = = KITEM_THUNDERSHIELD & & player - > kartstuff [ k_itemamount ] )
{
K_DoThunderShield ( player ) ;
player - > kartstuff [ k_itemamount ] = 0 ;
player - > kartstuff [ k_itemtype ] = KITEM_NONE ;
}
nextwork = work - > hnext ;
2018-08-24 14:14:18 +00:00
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
while ( ( work = nextwork ) & & ! P_MobjWasRemoved ( work ) )
2018-08-24 14:14:18 +00:00
{
nextwork = work - > hnext ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
switch ( work - > type )
{
// Kart orbit items
case MT_ORBINAUT_SHIELD :
orbit = true ;
type = MT_ORBINAUT ;
break ;
case MT_JAWZ_SHIELD :
orbit = true ;
type = MT_JAWZ_DUD ;
break ;
// Kart trailing items
case MT_BANANA_SHIELD :
orbit = false ;
type = MT_BANANA ;
break ;
case MT_SSMINE_SHIELD :
orbit = false ;
type = MT_SSMINE ;
break ;
case MT_FAKESHIELD :
orbit = false ;
type = MT_FAKEITEM ;
break ;
// intentionally do nothing
case MT_SINK_SHIELD :
return ;
default :
continue ;
}
dropwork = P_SpawnMobj ( work - > x , work - > y , work - > z , type ) ;
P_SetTarget ( & dropwork - > target , player - > mo ) ;
dropwork - > angle = work - > angle ;
dropwork - > flags2 = work - > flags2 ;
dropwork - > flags | = MF_NOCLIPTHING ;
dropwork - > floorz = work - > floorz ;
dropwork - > ceilingz = work - > ceilingz ;
2018-08-24 14:14:18 +00:00
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
if ( ponground )
{
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs
//P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
if ( flip = = 1 )
{
if ( dropwork - > floorz > dropwork - > target - > z - dropwork - > height )
{
dropwork - > z = dropwork - > floorz ;
}
}
else
{
if ( dropwork - > ceilingz < dropwork - > target - > z + dropwork - > target - > height + dropwork - > height )
{
dropwork - > z = dropwork - > ceilingz - dropwork - > height ;
}
}
}
if ( orbit ) // splay out
{
dropwork - > flags2 | = MF2_AMBUSH ;
dropwork - > z + = flip ;
dropwork - > momx = player - > mo - > momx > > 1 ;
dropwork - > momy = player - > mo - > momy > > 1 ;
dropwork - > momz = 3 * flip * mapheaderinfo [ gamemap - 1 ] - > mobj_scale ;
P_Thrust ( dropwork , work - > angle - ANGLE_90 , 6 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ) ;
dropwork - > movecount = 2 ;
dropwork - > movedir = work - > angle - ANGLE_90 ;
P_SetMobjState ( dropwork , dropwork - > info - > deathstate ) ;
dropwork - > tics = - 1 ;
if ( type = = MT_JAWZ_DUD )
dropwork - > z + = 20 * flip * dropwork - > scale ;
else
{
dropwork - > color = work - > color ;
dropwork - > angle - = ANGLE_90 ;
}
}
else // plop on the ground
{
dropwork - > flags & = ~ MF_NOCLIPTHING ;
dropwork - > threshold = 10 ;
}
P_RemoveMobj ( work ) ;
2018-08-24 14:14:18 +00:00
}
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
{
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
P_SetTarget ( & player - > mo - > hnext , NULL ) ;
player - > kartstuff [ k_bananadrag ] = 0 ;
if ( player - > kartstuff [ k_eggmanheld ] )
player - > kartstuff [ k_eggmanheld ] = 0 ;
else if ( player - > kartstuff [ k_itemheld ] )
{
player - > kartstuff [ k_itemamount ] = player - > kartstuff [ k_itemheld ] = 0 ;
player - > kartstuff [ k_itemtype ] = KITEM_NONE ;
}
}
}
// For getting EXTRA hit!
void K_DropItems ( player_t * player )
{
boolean thunderhack = ( player - > kartstuff [ k_curshield ] & & player - > kartstuff [ k_itemtype ] = = KITEM_THUNDERSHIELD ) ;
if ( thunderhack )
player - > kartstuff [ k_itemtype ] = KITEM_NONE ;
K_DropHnextList ( player ) ;
if ( player - > mo & & player - > kartstuff [ k_itemamount ] )
{
mobj_t * drop = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z + player - > mo - > height / 2 , MT_FLOATINGITEM ) ;
2018-09-07 13:26:00 +00:00
P_SetScale ( drop , drop - > scale > > 4 ) ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
drop - > destscale = ( 3 * drop - > destscale ) / 2 ; ;
drop - > angle = player - > mo - > angle + ANGLE_90 ;
drop - > momx = player - > mo - > momx > > 1 ;
drop - > momy = player - > mo - > momy > > 1 ;
P_Thrust ( drop ,
FixedAngle ( P_RandomFixed ( ) * 180 ) + player - > mo - > angle + ANGLE_90 ,
8 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ) ;
drop - > momz = P_MobjFlip ( player - > mo ) * 3 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) ;
drop - > threshold = ( thunderhack ? KITEM_THUNDERSHIELD : player - > kartstuff [ k_itemtype ] ) ;
drop - > movecount = player - > kartstuff [ k_itemamount ] ;
drop - > flags | = MF_NOCLIPTHING ;
}
K_StripItems ( player ) ;
2018-08-24 14:14:18 +00:00
}
// When an item in the hnext chain dies.
2018-06-27 19:58:43 +00:00
void K_RepairOrbitChain ( mobj_t * orbit )
{
mobj_t * cachenext = orbit - > hnext ;
// First, repair the chain
2018-07-01 08:36:09 +00:00
if ( orbit - > hnext & & orbit - > hnext - > health & & ! P_MobjWasRemoved ( orbit - > hnext ) )
2018-06-27 19:58:43 +00:00
{
P_SetTarget ( & orbit - > hnext - > hprev , orbit - > hprev ) ;
P_SetTarget ( & orbit - > hnext , NULL ) ;
}
2018-07-01 08:36:09 +00:00
if ( orbit - > hprev & & orbit - > hprev - > health & & ! P_MobjWasRemoved ( orbit - > hprev ) )
2018-06-27 19:58:43 +00:00
{
P_SetTarget ( & orbit - > hprev - > hnext , cachenext ) ;
P_SetTarget ( & orbit - > hprev , NULL ) ;
}
// Then recount to make sure item amount is correct
if ( orbit - > target & & orbit - > target - > player )
{
INT32 num = 0 ;
2018-06-28 00:20:19 +00:00
mobj_t * cur = orbit - > target - > hnext ;
mobj_t * prev = NULL ;
2018-06-27 19:58:43 +00:00
2018-06-28 00:20:19 +00:00
while ( cur & & ! P_MobjWasRemoved ( cur ) )
2018-06-27 19:58:43 +00:00
{
prev = cur ;
cur = cur - > hnext ;
2018-06-28 00:20:19 +00:00
if ( + + num > orbit - > target - > player - > kartstuff [ k_itemamount ] )
2018-06-27 19:58:43 +00:00
P_RemoveMobj ( prev ) ;
2018-06-28 00:20:19 +00:00
else
prev - > movedir = num ;
2018-06-27 19:58:43 +00:00
}
if ( orbit - > target - > player - > kartstuff [ k_itemamount ] ! = num )
orbit - > target - > player - > kartstuff [ k_itemamount ] = num ;
}
}
2018-08-24 14:14:18 +00:00
// Move the hnext chain!
2018-06-27 19:58:43 +00:00
static void K_MoveHeldObjects ( player_t * player )
{
if ( ! player - > mo )
return ;
if ( ! player - > mo - > hnext )
2018-07-04 23:06:45 +00:00
{
player - > kartstuff [ k_bananadrag ] = 0 ;
2018-08-15 13:40:06 +00:00
if ( player - > kartstuff [ k_eggmanheld ] )
player - > kartstuff [ k_eggmanheld ] = 0 ;
else if ( player - > kartstuff [ k_itemheld ] )
{
player - > kartstuff [ k_itemamount ] = player - > kartstuff [ k_itemheld ] = 0 ;
player - > kartstuff [ k_itemtype ] = KITEM_NONE ;
}
2018-06-27 19:58:43 +00:00
return ;
2018-07-04 23:06:45 +00:00
}
2018-06-27 19:58:43 +00:00
2018-08-06 15:19:07 +00:00
if ( P_MobjWasRemoved ( player - > mo - > hnext ) )
{
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
P_SetTarget ( & player - > mo - > hnext , NULL ) ;
player - > kartstuff [ k_bananadrag ] = 0 ;
2018-08-15 13:40:06 +00:00
if ( player - > kartstuff [ k_eggmanheld ] )
player - > kartstuff [ k_eggmanheld ] = 0 ;
else if ( player - > kartstuff [ k_itemheld ] )
{
player - > kartstuff [ k_itemamount ] = player - > kartstuff [ k_itemheld ] = 0 ;
player - > kartstuff [ k_itemtype ] = KITEM_NONE ;
}
2018-08-06 15:19:07 +00:00
return ;
}
2018-06-27 19:58:43 +00:00
switch ( player - > mo - > hnext - > type )
{
2018-07-23 00:55:18 +00:00
case MT_ORBINAUT_SHIELD : // Kart orbit items
2018-06-27 19:58:43 +00:00
case MT_JAWZ_SHIELD :
{
mobj_t * cur = player - > mo - > hnext ;
2018-07-04 23:06:45 +00:00
player - > kartstuff [ k_bananadrag ] = 0 ; // Just to make sure
2018-06-28 00:20:19 +00:00
while ( cur & & ! P_MobjWasRemoved ( cur ) )
2018-06-27 19:58:43 +00:00
{
const fixed_t radius = FixedHypot ( player - > mo - > radius , player - > mo - > radius ) + FixedHypot ( cur - > radius , cur - > radius ) ; // mobj's distance from its Target, or Radius.
fixed_t z ;
2018-07-01 08:36:09 +00:00
if ( ! cur - > health )
{
cur = cur - > hnext ;
continue ;
}
2018-07-23 00:55:18 +00:00
cur - > color = player - > skincolor ;
2018-06-27 19:58:43 +00:00
cur - > angle - = ANGLE_90 ;
cur - > angle + = FixedAngle ( cur - > info - > speed ) ;
2018-08-30 20:10:25 +00:00
if ( cur - > extravalue1 < radius )
cur - > extravalue1 + = FixedMul ( P_AproxDistance ( cur - > extravalue1 , radius ) , FRACUNIT / 12 ) ;
if ( cur - > extravalue1 > radius )
cur - > extravalue1 = radius ;
2018-06-27 19:58:43 +00:00
// If the player is on the ceiling, then flip your items as well.
if ( player & & player - > mo - > eflags & MFE_VERTICALFLIP )
cur - > eflags | = MFE_VERTICALFLIP ;
else
cur - > eflags & = ~ MFE_VERTICALFLIP ;
// Shrink your items if the player shrunk too.
2018-08-30 20:10:25 +00:00
P_SetScale ( cur , ( cur - > destscale = FixedMul ( FixedDiv ( cur - > extravalue1 , radius ) , player - > mo - > scale ) ) ) ;
2018-06-27 19:58:43 +00:00
if ( P_MobjFlip ( cur ) > 0 )
z = player - > mo - > z ;
else
z = player - > mo - > z + player - > mo - > height - cur - > height ;
cur - > flags | = MF_NOCLIPTHING ; // temporarily make them noclip other objects so they can't hit anyone while in the player
P_TeleportMove ( cur , player - > mo - > x , player - > mo - > y , z ) ;
2018-08-30 20:10:25 +00:00
cur - > momx = FixedMul ( FINECOSINE ( cur - > angle > > ANGLETOFINESHIFT ) , cur - > extravalue1 ) ;
cur - > momy = FixedMul ( FINESINE ( cur - > angle > > ANGLETOFINESHIFT ) , cur - > extravalue1 ) ;
2018-06-27 19:58:43 +00:00
cur - > flags & = ~ MF_NOCLIPTHING ;
if ( ! P_TryMove ( cur , player - > mo - > x + cur - > momx , player - > mo - > y + cur - > momy , true ) )
P_SlideMove ( cur , true ) ;
if ( P_IsObjectOnGround ( player - > mo ) )
{
if ( P_MobjFlip ( cur ) > 0 )
{
if ( cur - > floorz > player - > mo - > z - cur - > height )
z = cur - > floorz ;
}
else
{
if ( cur - > ceilingz < player - > mo - > z + player - > mo - > height + cur - > height )
z = cur - > ceilingz - cur - > height ;
}
}
2018-08-30 20:28:01 +00:00
// Center it during the scale up animation
z + = ( FixedMul ( mobjinfo [ cur - > type ] . height , player - > mo - > scale - cur - > scale ) > > 1 ) * P_MobjFlip ( cur ) ;
2018-06-27 19:58:43 +00:00
cur - > z = z ;
cur - > momx = cur - > momy = 0 ;
cur - > angle + = ANGLE_90 ;
cur = cur - > hnext ;
}
}
break ;
case MT_BANANA_SHIELD : // Kart trailing items
case MT_SSMINE_SHIELD :
case MT_FAKESHIELD :
2018-09-04 23:14:44 +00:00
case MT_SINK_SHIELD :
2018-06-27 19:58:43 +00:00
{
mobj_t * cur = player - > mo - > hnext ;
mobj_t * targ = player - > mo ;
2018-09-05 00:51:16 +00:00
if ( P_IsObjectOnGround ( player - > mo ) & & player - > speed > 0 )
2018-07-10 22:16:53 +00:00
{
player - > kartstuff [ k_bananadrag ] + + ;
2018-07-25 16:49:30 +00:00
if ( player - > kartstuff [ k_bananadrag ] > TICRATE )
{
K_SpawnWipeoutTrail ( player - > mo , true ) ;
if ( leveltime % 6 = = 0 )
S_StartSound ( player - > mo , sfx_cdfm70 ) ;
}
2018-07-10 22:16:53 +00:00
}
2018-07-04 23:06:45 +00:00
2018-06-28 00:20:19 +00:00
while ( cur & & ! P_MobjWasRemoved ( cur ) )
2018-06-27 19:58:43 +00:00
{
2018-07-01 08:36:09 +00:00
const fixed_t radius = FixedHypot ( targ - > radius , targ - > radius ) + FixedHypot ( cur - > radius , cur - > radius ) ;
2018-06-27 19:58:43 +00:00
angle_t ang ;
2018-09-04 23:58:20 +00:00
fixed_t targx , targy , targz ;
fixed_t speed , dist ;
2018-07-01 08:36:09 +00:00
2018-08-13 21:46:51 +00:00
cur - > flags & = ~ MF_NOCLIPTHING ;
2018-07-01 08:36:09 +00:00
if ( ! cur - > health )
{
cur = cur - > hnext ;
continue ;
}
2018-06-27 19:58:43 +00:00
2018-08-30 20:36:46 +00:00
if ( cur - > extravalue1 < radius )
cur - > extravalue1 + = FixedMul ( P_AproxDistance ( cur - > extravalue1 , radius ) , FRACUNIT / 12 ) ;
if ( cur - > extravalue1 > radius )
cur - > extravalue1 = radius ;
2018-06-27 19:58:43 +00:00
if ( cur ! = player - > mo - > hnext )
{
targ = cur - > hprev ;
2018-08-30 20:36:46 +00:00
dist = cur - > extravalue1 / 4 ;
2018-06-27 19:58:43 +00:00
}
2018-08-30 20:36:46 +00:00
else
dist = cur - > extravalue1 / 2 ;
2018-06-27 19:58:43 +00:00
if ( ! targ | | P_MobjWasRemoved ( targ ) )
continue ;
2018-08-30 20:36:46 +00:00
// Shrink your items if the player shrunk too.
P_SetScale ( cur , ( cur - > destscale = FixedMul ( FixedDiv ( cur - > extravalue1 , radius ) , player - > mo - > scale ) ) ) ;
2018-06-27 19:58:43 +00:00
ang = targ - > angle ;
targx = targ - > x + P_ReturnThrustX ( cur , ang + ANGLE_180 , dist ) ;
targy = targ - > y + P_ReturnThrustY ( cur , ang + ANGLE_180 , dist ) ;
targz = targ - > z ;
speed = FixedMul ( R_PointToDist2 ( cur - > x , cur - > y , targx , targy ) , 3 * FRACUNIT / 4 ) ;
if ( P_IsObjectOnGround ( targ ) )
targz = cur - > floorz ;
cur - > angle = R_PointToAngle2 ( cur - > x , cur - > y , targx , targy ) ;
2018-07-27 00:12:42 +00:00
/*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE
2018-07-25 16:49:30 +00:00
& & P_RandomChance ( min ( FRACUNIT / 2 , FixedDiv ( player - > speed , K_GetKartSpeed ( player , false ) ) / 2 ) ) )
{
if ( leveltime & 1 )
targz + = 8 * ( 2 * FRACUNIT ) / 7 ;
else
targz - = 8 * ( 2 * FRACUNIT ) / 7 ;
2018-07-27 00:12:42 +00:00
} */
2018-07-25 16:49:30 +00:00
2018-06-27 19:58:43 +00:00
if ( speed > dist )
P_InstaThrust ( cur , cur - > angle , speed - dist ) ;
2018-07-04 23:06:45 +00:00
P_SetObjectMomZ ( cur , FixedMul ( targz - cur - > z , 7 * FRACUNIT / 8 ) - gravity , false ) ;
2018-06-27 19:58:43 +00:00
if ( R_PointToDist2 ( cur - > x , cur - > y , targx , targy ) > 768 * FRACUNIT )
P_TeleportMove ( cur , targx , targy , cur - > z ) ;
cur = cur - > hnext ;
}
}
break ;
default :
break ;
}
}
2018-08-30 23:24:22 +00:00
player_t * K_FindJawzTarget ( mobj_t * actor , player_t * source )
{
fixed_t best = - 1 ;
player_t * wtarg = NULL ;
INT32 i ;
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
angle_t thisang ;
player_t * player ;
if ( ! playeringame [ i ] )
continue ;
player = & players [ i ] ;
if ( player - > spectator )
continue ; // spectator
if ( ! player - > mo )
continue ;
if ( player - > mo - > health < = 0 )
continue ; // dead
// Don't target yourself, stupid.
if ( player = = source )
continue ;
// Don't home in on teammates.
if ( G_GametypeHasTeams ( ) & & source - > ctfteam = = player - > ctfteam )
continue ;
2018-09-04 22:47:30 +00:00
// Invisible, don't bother
if ( player - > kartstuff [ k_hyudorotimer ] )
continue ;
2018-08-30 23:24:22 +00:00
// Find the angle, see who's got the best.
thisang = actor - > angle - R_PointToAngle2 ( actor - > x , actor - > y , player - > mo - > x , player - > mo - > y ) ;
if ( thisang > ANGLE_180 )
thisang = InvAngle ( thisang ) ;
if ( thisang > ANGLE_45 ) // Don't go for people who are behind you
continue ;
// Jawz only go after the person directly ahead of you in race... sort of literally now!
if ( G_RaceGametype ( ) )
{
if ( player - > kartstuff [ k_position ] > = source - > kartstuff [ k_position ] ) // Don't pay attention to people behind you
continue ;
if ( ( best = = - 1 ) | | ( player - > kartstuff [ k_position ] > best ) )
{
wtarg = player ;
best = player - > kartstuff [ k_position ] ;
}
}
else
{
fixed_t thisdist ;
fixed_t thisavg ;
if ( player - > kartstuff [ k_bumper ] < = 0 )
continue ;
2018-09-06 20:05:57 +00:00
// Z pos too high/low
if ( abs ( player - > mo - > z - ( actor - > z + actor - > momz ) ) > RING_DIST / 8 )
continue ;
2018-09-04 22:47:30 +00:00
thisdist = P_AproxDistance ( player - > mo - > x - ( actor - > x + actor - > momx ) , player - > mo - > y - ( actor - > y + actor - > momy ) ) ;
2018-08-30 23:24:22 +00:00
2018-09-06 20:05:57 +00:00
if ( thisdist > 2 * RING_DIST ) // Don't go for people who are too far away
2018-08-30 23:24:22 +00:00
continue ;
thisavg = ( AngleFixed ( thisang ) + thisdist ) / 2 ;
//CONS_Printf("got avg %d from player # %d\n", thisavg>>FRACBITS, i);
if ( ( best = = - 1 ) | | ( thisavg < best ) )
{
wtarg = player ;
best = thisavg ;
}
}
}
return wtarg ;
}
2018-06-06 01:36:48 +00:00
/** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c
\ param player player object passed from P_PlayerThink
\ param cmd control input from player
\ return void
*/
void K_KartPlayerThink ( player_t * player , ticcmd_t * cmd )
{
K_UpdateOffroad ( player ) ;
2018-09-04 19:11:14 +00:00
K_GetKartBoostPower ( player ) ;
2018-06-06 01:36:48 +00:00
2018-08-31 02:27:18 +00:00
if ( player - > kartstuff [ k_eggmanexplode ] ) // You're gonna diiiiie
2018-08-14 14:23:38 +00:00
{
2018-08-14 21:16:33 +00:00
const INT32 flashtime = 4 < < ( player - > kartstuff [ k_eggmanexplode ] / TICRATE ) ;
2018-08-14 14:23:38 +00:00
if ( player - > kartstuff [ k_eggmanexplode ] = = 1 | | ( player - > kartstuff [ k_eggmanexplode ] % ( flashtime / 2 ) ! = 0 ) )
{
player - > mo - > colorized = false ;
player - > mo - > color = player - > skincolor ;
}
else if ( player - > kartstuff [ k_eggmanexplode ] % flashtime = = 0 )
{
player - > mo - > colorized = true ;
player - > mo - > color = SKINCOLOR_BLACK ;
}
else
{
player - > mo - > colorized = true ;
player - > mo - > color = SKINCOLOR_CRIMSON ;
}
}
2018-08-31 02:27:18 +00:00
else if ( player - > kartstuff [ k_invincibilitytimer ] ) // setting players to use the star colormap and spawning afterimages
{
mobj_t * ghost ;
player - > mo - > colorized = true ;
ghost = P_SpawnGhostMobj ( player - > mo ) ;
ghost - > fuse = 4 ;
ghost - > frame | = FF_FULLBRIGHT ;
}
else if ( player - > kartstuff [ k_growshrinktimer ] ) // Ditto, for grow/shrink
2018-07-10 21:40:47 +00:00
{
if ( player - > kartstuff [ k_growshrinktimer ] % 5 = = 0 )
{
player - > mo - > colorized = true ;
2018-07-11 00:27:18 +00:00
player - > mo - > color = ( player - > kartstuff [ k_growshrinktimer ] < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE ) ;
2018-07-10 21:40:47 +00:00
}
else
{
player - > mo - > colorized = false ;
player - > mo - > color = player - > skincolor ;
}
}
2018-06-06 01:36:48 +00:00
else
{
player - > mo - > colorized = false ;
}
2018-08-31 02:27:18 +00:00
if ( player - > kartstuff [ k_dashpadcooldown ] ) // Twinkle Circuit inspired afterimages
{
mobj_t * ghost ;
ghost = P_SpawnGhostMobj ( player - > mo ) ;
ghost - > fuse = player - > kartstuff [ k_dashpadcooldown ] + 1 ;
ghost - > momx = player - > mo - > momx / ( player - > kartstuff [ k_dashpadcooldown ] + 1 ) ;
ghost - > momy = player - > mo - > momy / ( player - > kartstuff [ k_dashpadcooldown ] + 1 ) ;
ghost - > momz = player - > mo - > momz / ( player - > kartstuff [ k_dashpadcooldown ] + 1 ) ;
player - > kartstuff [ k_dashpadcooldown ] - - ;
}
2018-09-05 15:19:00 +00:00
// DKR style camera for boosting
if ( player - > kartstuff [ k_boostcam ] ! = 0 | | player - > kartstuff [ k_destboostcam ] ! = 0 )
{
if ( player - > kartstuff [ k_boostcam ] < player - > kartstuff [ k_destboostcam ]
& & player - > kartstuff [ k_destboostcam ] ! = 0 )
{
2018-09-07 01:58:23 +00:00
player - > kartstuff [ k_boostcam ] + = FRACUNIT / ( TICRATE / 4 ) ;
2018-09-05 15:19:00 +00:00
if ( player - > kartstuff [ k_boostcam ] > = player - > kartstuff [ k_destboostcam ] )
player - > kartstuff [ k_destboostcam ] = 0 ;
}
else
{
2018-09-07 01:58:23 +00:00
player - > kartstuff [ k_boostcam ] - = FRACUNIT / TICRATE ;
2018-09-05 15:19:00 +00:00
if ( player - > kartstuff [ k_boostcam ] < player - > kartstuff [ k_destboostcam ] )
player - > kartstuff [ k_boostcam ] = player - > kartstuff [ k_destboostcam ] = 0 ;
}
//CONS_Printf("cam: %d, dest: %d\n", player->kartstuff[k_boostcam], player->kartstuff[k_destboostcam]);
}
2018-06-25 10:58:23 +00:00
if ( player - > kartstuff [ k_spinouttimer ] )
{
2018-07-10 22:16:53 +00:00
if ( ( P_IsObjectOnGround ( player - > mo ) | | player - > kartstuff [ k_spinouttype ] = = 1 )
& & ( player - > kartstuff [ k_sneakertimer ] = = 0 ) )
2018-07-20 02:37:32 +00:00
{
2018-06-25 10:58:23 +00:00
player - > kartstuff [ k_spinouttimer ] - - ;
2018-07-20 02:37:32 +00:00
if ( player - > kartstuff [ k_wipeoutslow ] > 1 )
player - > kartstuff [ k_wipeoutslow ] - - ;
if ( player - > kartstuff [ k_spinouttimer ] = = 0 )
player - > kartstuff [ k_spinouttype ] = 0 ; // Reset type
}
2018-06-25 10:58:23 +00:00
}
2018-07-20 02:37:32 +00:00
else
2018-06-06 01:36:48 +00:00
{
2018-07-20 02:37:32 +00:00
if ( player - > kartstuff [ k_wipeoutslow ] = = 1 )
player - > mo - > friction = ORIG_FRICTION ;
player - > kartstuff [ k_wipeoutslow ] = 0 ;
if ( ! comeback )
player - > kartstuff [ k_comebacktimer ] = comebacktime ;
else if ( player - > kartstuff [ k_comebacktimer ] )
{
player - > kartstuff [ k_comebacktimer ] - - ;
if ( P_IsLocalPlayer ( player ) & & player - > kartstuff [ k_bumper ] < = 0 & & player - > kartstuff [ k_comebacktimer ] < = 0 )
comebackshowninfo = true ; // client has already seen the message
}
2018-06-06 01:36:48 +00:00
}
2018-08-11 04:12:41 +00:00
if ( player - > kartstuff [ k_spinouttimer ] = = 0 & & player - > powers [ pw_flashing ] = = K_GetKartFlashing ( player ) )
2018-06-06 01:36:48 +00:00
player - > powers [ pw_flashing ] - - ;
2018-08-04 19:48:31 +00:00
/*if (player->kartstuff[k_thunderanim])
player - > kartstuff [ k_thunderanim ] - - ; */
2018-06-06 01:36:48 +00:00
2018-06-20 00:20:06 +00:00
if ( player - > kartstuff [ k_sneakertimer ] )
2018-06-07 23:39:45 +00:00
player - > kartstuff [ k_sneakertimer ] - - ;
2018-06-06 01:36:48 +00:00
if ( player - > kartstuff [ k_floorboost ] )
player - > kartstuff [ k_floorboost ] - - ;
if ( player - > kartstuff [ k_driftboost ] )
player - > kartstuff [ k_driftboost ] - - ;
2018-06-07 23:39:45 +00:00
if ( player - > kartstuff [ k_invincibilitytimer ] )
player - > kartstuff [ k_invincibilitytimer ] - - ;
2018-06-06 01:36:48 +00:00
if ( player - > kartstuff [ k_growshrinktimer ] > 0 )
player - > kartstuff [ k_growshrinktimer ] - - ;
if ( player - > kartstuff [ k_growshrinktimer ] < 0 )
player - > kartstuff [ k_growshrinktimer ] + + ;
if ( player - > kartstuff [ k_growshrinktimer ] = = 1 | | player - > kartstuff [ k_growshrinktimer ] = = - 1 )
{
2018-07-10 21:40:47 +00:00
if ( player - > kartstuff [ k_invincibilitytimer ] = = 0 )
player - > mo - > color = player - > skincolor ;
2018-06-06 01:36:48 +00:00
player - > mo - > destscale = mapheaderinfo [ gamemap - 1 ] - > mobj_scale ;
2018-07-12 05:31:33 +00:00
if ( cv_kartdebugshrink . value & & ! player - > bot )
player - > mo - > destscale = 6 * player - > mo - > destscale / 8 ;
2018-06-06 01:36:48 +00:00
P_RestoreMusic ( player ) ;
}
2018-06-07 23:39:45 +00:00
if ( player - > kartstuff [ k_stealingtimer ] = = 0 & & player - > kartstuff [ k_stolentimer ] = = 0
& & player - > kartstuff [ k_rocketsneakertimer ] )
player - > kartstuff [ k_rocketsneakertimer ] - - ;
if ( player - > kartstuff [ k_hyudorotimer ] )
player - > kartstuff [ k_hyudorotimer ] - - ;
2018-06-06 01:36:48 +00:00
2018-06-07 23:39:45 +00:00
if ( player - > kartstuff [ k_sadtimer ] )
player - > kartstuff [ k_sadtimer ] - - ;
2018-06-06 01:36:48 +00:00
2018-06-07 23:39:45 +00:00
if ( player - > kartstuff [ k_stealingtimer ] )
player - > kartstuff [ k_stealingtimer ] - - ;
2018-06-06 01:36:48 +00:00
2018-06-07 23:39:45 +00:00
if ( player - > kartstuff [ k_stolentimer ] )
player - > kartstuff [ k_stolentimer ] - - ;
2018-06-06 01:36:48 +00:00
if ( player - > kartstuff [ k_squishedtimer ] )
player - > kartstuff [ k_squishedtimer ] - - ;
if ( player - > kartstuff [ k_justbumped ] )
player - > kartstuff [ k_justbumped ] - - ;
if ( player - > kartstuff [ k_deathsentence ] )
{
if ( player - > kartstuff [ k_deathsentence ] = = 1 )
2018-06-08 04:02:28 +00:00
K_DoSPB ( player , & players [ spbplayer ] ) ;
2018-06-06 01:36:48 +00:00
player - > kartstuff [ k_deathsentence ] - - ;
}
2018-08-10 01:52:02 +00:00
if ( player - > kartstuff [ k_lapanimation ] )
player - > kartstuff [ k_lapanimation ] - - ;
2018-06-06 01:36:48 +00:00
if ( G_BattleGametype ( ) & & ( player - > exiting | | player - > kartstuff [ k_comebacktimer ] ) )
{
if ( player - > exiting )
{
if ( player - > exiting < 6 * TICRATE )
player - > kartstuff [ k_cardanimation ] + = ( ( 164 - player - > kartstuff [ k_cardanimation ] ) / 8 ) + 1 ;
2018-07-19 14:58:07 +00:00
else if ( player - > exiting = = 6 * TICRATE )
player - > kartstuff [ k_cardanimation ] = 0 ;
else if ( player - > kartstuff [ k_cardanimation ] < 2 * TICRATE )
player - > kartstuff [ k_cardanimation ] + + ;
2018-06-06 01:36:48 +00:00
}
else
{
if ( player - > kartstuff [ k_comebacktimer ] < 6 * TICRATE )
player - > kartstuff [ k_cardanimation ] - = ( ( 164 - player - > kartstuff [ k_cardanimation ] ) / 8 ) + 1 ;
else if ( player - > kartstuff [ k_comebacktimer ] < 9 * TICRATE )
player - > kartstuff [ k_cardanimation ] + = ( ( 164 - player - > kartstuff [ k_cardanimation ] ) / 8 ) + 1 ;
}
if ( player - > kartstuff [ k_cardanimation ] > 164 )
player - > kartstuff [ k_cardanimation ] = 164 ;
if ( player - > kartstuff [ k_cardanimation ] < 0 )
player - > kartstuff [ k_cardanimation ] = 0 ;
}
2018-07-18 22:20:08 +00:00
else if ( G_RaceGametype ( ) & & player - > exiting )
{
2018-07-19 14:58:07 +00:00
if ( player - > kartstuff [ k_cardanimation ] < 2 * TICRATE )
2018-07-18 22:20:08 +00:00
player - > kartstuff [ k_cardanimation ] + + ;
}
2018-06-06 01:36:48 +00:00
else
player - > kartstuff [ k_cardanimation ] = 0 ;
2018-06-08 23:56:39 +00:00
if ( player - > kartstuff [ k_voices ] )
player - > kartstuff [ k_voices ] - - ;
if ( player - > kartstuff [ k_tauntvoices ] )
player - > kartstuff [ k_tauntvoices ] - - ;
2018-06-06 01:36:48 +00:00
2018-07-03 19:14:47 +00:00
if ( G_BattleGametype ( ) & & player - > kartstuff [ k_bumper ] > 0 )
2018-07-01 08:36:09 +00:00
player - > kartstuff [ k_wanted ] + + ;
2018-07-17 02:51:31 +00:00
if ( P_IsObjectOnGround ( player - > mo ) )
player - > kartstuff [ k_waterskip ] = 0 ;
2018-07-27 00:12:42 +00:00
if ( player - > kartstuff [ k_instashield ] )
player - > kartstuff [ k_instashield ] - - ;
2018-08-12 00:19:09 +00:00
if ( player - > kartstuff [ k_eggmanexplode ] )
{
2018-08-12 10:45:48 +00:00
if ( player - > spectator | | ( G_BattleGametype ( ) & & ! player - > kartstuff [ k_bumper ] ) )
player - > kartstuff [ k_eggmanexplode ] = 0 ;
else
2018-08-12 00:19:09 +00:00
{
2018-08-12 10:45:48 +00:00
player - > kartstuff [ k_eggmanexplode ] - - ;
if ( player - > kartstuff [ k_eggmanexplode ] < = 0 )
{
mobj_t * eggsexplode ;
player - > powers [ pw_flashing ] = 0 ;
eggsexplode = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_BLUEEXPLOSION ) ;
if ( player - > kartstuff [ k_eggmanblame ] > = 0
& & player - > kartstuff [ k_eggmanblame ] < MAXPLAYERS
& & playeringame [ player - > kartstuff [ k_eggmanblame ] ]
& & ! players [ player - > kartstuff [ k_eggmanblame ] ] . spectator
& & players [ player - > kartstuff [ k_eggmanblame ] ] . mo )
P_SetTarget ( & eggsexplode - > target , players [ player - > kartstuff [ k_eggmanblame ] ] . mo ) ;
}
2018-08-12 00:19:09 +00:00
}
}
2018-06-06 01:36:48 +00:00
// ???
/*
if ( player - > kartstuff [ k_jmp ] > 1 & & onground )
{
S_StartSound ( player - > mo , sfx_spring ) ;
P_DoJump ( player , false ) ;
player - > mo - > momz * = player - > kartstuff [ k_jmp ] ;
player - > kartstuff [ k_jmp ] = 0 ;
}
*/
if ( player - > kartstuff [ k_comebacktimer ] )
player - > kartstuff [ k_comebackmode ] = 0 ;
2018-06-07 23:39:45 +00:00
if ( P_IsObjectOnGround ( player - > mo ) & & player - > mo - > momz < = 0 & & player - > kartstuff [ k_pogospring ] )
player - > kartstuff [ k_pogospring ] = 0 ;
2018-06-06 01:36:48 +00:00
if ( cmd - > buttons & BT_DRIFT )
player - > kartstuff [ k_jmp ] = 1 ;
else
player - > kartstuff [ k_jmp ] = 0 ;
2018-06-25 02:15:22 +00:00
// Respawn Checker
if ( player - > kartstuff [ k_respawn ] )
K_RespawnChecker ( player ) ;
2018-06-06 01:36:48 +00:00
// Roulette Code
2018-06-08 04:02:28 +00:00
K_KartItemRoulette ( player , cmd ) ;
2018-06-06 01:36:48 +00:00
2018-06-07 23:39:45 +00:00
// Stopping of the horrible invincibility SFX
if ( player - > mo - > health < = 0 | | player - > mo - > player - > kartstuff [ k_invincibilitytimer ] < = 0
| | player - > mo - > player - > kartstuff [ k_growshrinktimer ] > 0 ) // If you don't have invincibility (or grow is active too)
2018-06-06 01:36:48 +00:00
{
2018-06-07 23:39:45 +00:00
if ( S_SoundPlaying ( player - > mo , sfx_kinvnc ) ) // But the sound is playing
S_StopSoundByID ( player - > mo , sfx_kinvnc ) ; // Stop it
2018-06-06 01:36:48 +00:00
}
2018-06-07 23:39:45 +00:00
// And the same for the grow SFX
2018-06-06 01:36:48 +00:00
if ( ! ( player - > mo - > health > 0 & & player - > mo - > player - > kartstuff [ k_growshrinktimer ] > 0 ) ) // If you aren't big
{
2018-06-07 23:39:45 +00:00
if ( S_SoundPlaying ( player - > mo , sfx_kgrow ) ) // But the sound is playing
S_StopSoundByID ( player - > mo , sfx_kgrow ) ; // Stop it
2018-06-06 01:36:48 +00:00
}
2018-06-15 06:18:43 +00:00
// AAAAAAND handle the invincibility alarm
2018-06-07 23:39:45 +00:00
if ( player - > mo - > health > 0 & & ( player - > mo - > player - > kartstuff [ k_invincibilitytimer ] > 0
2018-06-06 01:36:48 +00:00
| | player - > mo - > player - > kartstuff [ k_growshrinktimer ] > 0 ) )
{
2018-06-15 00:18:29 +00:00
if ( leveltime % 13 = = 0 & & cv_kartinvinsfx . value & & ! P_IsLocalPlayer ( player ) )
2018-06-06 01:36:48 +00:00
S_StartSound ( player - > mo , sfx_smkinv ) ;
}
else if ( S_SoundPlaying ( player - > mo , sfx_smkinv ) )
S_StopSoundByID ( player - > mo , sfx_smkinv ) ;
// Plays the music after the starting countdown.
2018-06-25 02:15:22 +00:00
if ( P_IsLocalPlayer ( player ) & & leveltime = = ( starttime + ( TICRATE / 2 ) ) )
2018-06-07 23:39:45 +00:00
S_ChangeMusicInternal ( mapmusname , true ) ;
2018-06-06 01:36:48 +00:00
}
void K_KartPlayerAfterThink ( player_t * player )
{
2018-07-10 21:40:47 +00:00
if ( player - > kartstuff [ k_invincibilitytimer ]
2018-07-12 05:31:33 +00:00
| | ( player - > kartstuff [ k_growshrinktimer ] ! = 0 & & player - > kartstuff [ k_growshrinktimer ] % 5 = = 4 ) ) // 4 instead of 0 because this is afterthink!
2018-06-06 01:36:48 +00:00
{
player - > mo - > frame | = FF_FULLBRIGHT ;
}
else
{
if ( ! ( player - > mo - > state - > frame & FF_FULLBRIGHT ) )
player - > mo - > frame & = ~ FF_FULLBRIGHT ;
}
2018-06-27 19:58:43 +00:00
// Move held objects (Bananas, Orbinaut, etc)
K_MoveHeldObjects ( player ) ;
2018-08-30 23:24:22 +00:00
// Jawz reticule (seeking)
if ( player - > kartstuff [ k_itemtype ] = = KITEM_JAWZ & & player - > kartstuff [ k_itemheld ] )
{
player_t * targ = K_FindJawzTarget ( player - > mo , player ) ;
mobj_t * ret ;
if ( ! targ )
{
player - > kartstuff [ k_lastjawztarget ] = - 1 ;
return ;
}
ret = P_SpawnMobj ( targ - > mo - > x , targ - > mo - > y , targ - > mo - > z , MT_PLAYERRETICULE ) ;
P_SetTarget ( & ret - > target , targ - > mo ) ;
ret - > frame | = ( ( leveltime % 10 ) / 2 ) ;
ret - > tics = 1 ;
ret - > color = player - > skincolor ;
if ( targ - players ! = player - > kartstuff [ k_lastjawztarget ] )
{
if ( P_IsLocalPlayer ( player ) | | P_IsLocalPlayer ( targ ) )
S_StartSound ( NULL , sfx_s3k89 ) ;
else
S_StartSound ( targ - > mo , sfx_s3k89 ) ;
player - > kartstuff [ k_lastjawztarget ] = targ - players ;
}
}
else
{
player - > kartstuff [ k_lastjawztarget ] = - 1 ;
}
2018-06-06 01:36:48 +00:00
}
2017-11-11 03:28:20 +00:00
// Returns false if this player being placed here causes them to collide with any other player
// Used in g_game.c for match etc. respawning
// This does not check along the z because the z is not correctly set for the spawnee at this point
boolean K_CheckPlayersRespawnColliding ( INT32 playernum , fixed_t x , fixed_t y )
{
INT32 i ;
fixed_t p1radius = players [ playernum ] . mo - > radius ;
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( playernum = = i | | ! playeringame [ i ] | | players [ i ] . spectator | | ! players [ i ] . mo | | players [ i ] . mo - > health < = 0
| | players [ i ] . playerstate ! = PST_LIVE | | ( players [ i ] . mo - > flags & MF_NOCLIP ) | | ( players [ i ] . mo - > flags & MF_NOCLIPTHING ) )
continue ;
if ( abs ( x - players [ i ] . mo - > x ) < ( p1radius + players [ i ] . mo - > radius )
& & abs ( y - players [ i ] . mo - > y ) < ( p1radius + players [ i ] . mo - > radius ) )
{
return false ;
}
}
return true ;
}
2017-03-07 18:31:37 +00:00
// countersteer is how strong the controls are telling us we are turning
2017-03-07 05:00:00 +00:00
// turndir is the direction the controls are telling us to turn, -1 if turning right and 1 if turning left
2017-03-07 18:31:37 +00:00
static INT16 K_GetKartDriftValue ( player_t * player , fixed_t countersteer )
2017-02-22 04:41:00 +00:00
{
2017-03-07 18:31:37 +00:00
INT16 basedrift , driftangle ;
2017-04-21 01:44:56 +00:00
fixed_t driftweight = player - > kartweight * 14 ; // 12
2017-03-07 01:05:18 +00:00
// If they aren't drifting or on the ground this doesn't apply
if ( player - > kartstuff [ k_drift ] = = 0 | | ! P_IsObjectOnGround ( player - > mo ) )
return 0 ;
2017-02-24 01:36:43 +00:00
2017-03-07 18:31:37 +00:00
if ( player - > kartstuff [ k_driftend ] ! = 0 )
2017-03-07 01:05:18 +00:00
{
2017-03-07 18:31:37 +00:00
return - 266 * player - > kartstuff [ k_drift ] ; // Drift has ended and we are tweaking their angle back a bit
2017-03-07 03:27:44 +00:00
}
2017-02-22 04:41:00 +00:00
2017-04-21 01:44:56 +00:00
//basedrift = 90*player->kartstuff[k_drift]; // 450
//basedrift = 93*player->kartstuff[k_drift] - driftweight*3*player->kartstuff[k_drift]/10; // 447 - 303
basedrift = 83 * player - > kartstuff [ k_drift ] - ( driftweight - 14 ) * player - > kartstuff [ k_drift ] / 5 ; // 415 - 303
2017-04-19 01:04:54 +00:00
driftangle = abs ( ( 252 - driftweight ) * player - > kartstuff [ k_drift ] / 5 ) ;
2017-02-22 04:41:00 +00:00
2017-04-19 01:04:54 +00:00
return basedrift + FixedMul ( driftangle , countersteer ) ;
2017-02-22 04:41:00 +00:00
}
2017-03-07 05:00:00 +00:00
INT16 K_GetKartTurnValue ( player_t * player , INT16 turnvalue )
{
fixed_t p_maxspeed = FixedMul ( K_GetKartSpeed ( player , false ) , 3 * FRACUNIT ) ;
fixed_t adjustangle = FixedDiv ( ( p_maxspeed > > 16 ) - ( player - > speed > > 16 ) , ( p_maxspeed > > 16 ) + player - > kartweight ) ;
2018-01-23 03:18:57 +00:00
if ( player - > spectator )
return turnvalue ;
2017-03-07 23:12:46 +00:00
if ( player - > kartstuff [ k_drift ] ! = 0 & & P_IsObjectOnGround ( player - > mo ) )
2017-03-07 05:00:00 +00:00
{
2017-03-07 18:31:37 +00:00
// If we're drifting we have a completely different turning value
2017-03-07 05:00:00 +00:00
if ( player - > kartstuff [ k_driftend ] = = 0 )
{
2017-03-07 18:31:37 +00:00
// 800 is the max set in g_game.c with angleturn
fixed_t countersteer = FixedDiv ( turnvalue * FRACUNIT , 800 * FRACUNIT ) ;
turnvalue = K_GetKartDriftValue ( player , countersteer ) ;
2017-03-07 05:00:00 +00:00
}
else
2017-03-07 18:31:37 +00:00
turnvalue = ( INT16 ) ( turnvalue + K_GetKartDriftValue ( player , FRACUNIT ) ) ;
return turnvalue ;
2017-03-07 05:00:00 +00:00
}
2017-03-07 18:31:37 +00:00
turnvalue = FixedMul ( turnvalue , adjustangle ) ; // Weight has a small effect on turning
2018-02-05 23:55:52 +00:00
if ( player - > kartstuff [ k_invincibilitytimer ] | | player - > kartstuff [ k_sneakertimer ] | | player - > kartstuff [ k_growshrinktimer ] > 0 )
2017-03-07 18:31:37 +00:00
turnvalue = FixedMul ( turnvalue , FixedDiv ( 5 * FRACUNIT , 4 * FRACUNIT ) ) ;
2017-03-07 05:00:00 +00:00
return turnvalue ;
}
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
fixed_t K_GetKartDriftSparkValue ( player_t * player )
2017-02-07 22:19:04 +00:00
{
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
UINT8 kartspeed = ( G_BattleGametype ( ) & & player - > kartstuff [ k_bumper ] < = 0 )
? 1
: player - > kartspeed ;
return ( 26 * 4 + kartspeed * 2 + ( 9 - player - > kartweight ) ) * 8 ;
}
2017-11-20 00:39:40 +00:00
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
static void K_KartDrift ( player_t * player , boolean onground )
{
fixed_t dsone = K_GetKartDriftSparkValue ( player ) ;
fixed_t dstwo = dsone * 2 ;
2017-03-04 22:13:19 +00:00
2017-02-07 22:19:04 +00:00
// Drifting is actually straffing + automatic turning.
// Holding the Jump button will enable drifting.
// Drift Release (Moved here so you can't "chain" drifts)
2017-03-07 05:00:00 +00:00
if ( ( player - > kartstuff [ k_drift ] ! = - 5 & & player - > kartstuff [ k_drift ] ! = 5 )
2017-02-07 22:19:04 +00:00
// || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1))
2017-02-24 01:36:43 +00:00
& & player - > kartstuff [ k_driftcharge ] < dsone
2017-02-07 22:19:04 +00:00
& & onground )
{
player - > kartstuff [ k_driftcharge ] = 0 ;
}
2017-03-07 05:00:00 +00:00
else if ( ( player - > kartstuff [ k_drift ] ! = - 5 & & player - > kartstuff [ k_drift ] ! = 5 )
2017-02-07 22:19:04 +00:00
// || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1))
2017-02-24 01:36:43 +00:00
& & ( player - > kartstuff [ k_driftcharge ] > = dsone & & player - > kartstuff [ k_driftcharge ] < dstwo )
2017-02-07 22:19:04 +00:00
& & onground )
{
2017-02-19 17:18:43 +00:00
player - > kartstuff [ k_driftboost ] = 20 ;
2018-06-19 02:29:52 +00:00
S_StartSound ( player - > mo , sfx_s23c ) ;
2017-02-07 22:19:04 +00:00
player - > kartstuff [ k_driftcharge ] = 0 ;
}
2017-03-07 05:00:00 +00:00
else if ( ( player - > kartstuff [ k_drift ] ! = - 5 & & player - > kartstuff [ k_drift ] ! = 5 )
2017-02-07 22:19:04 +00:00
// || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1))
2017-02-24 01:36:43 +00:00
& & player - > kartstuff [ k_driftcharge ] > = dstwo
2017-02-07 22:19:04 +00:00
& & onground )
{
2017-04-19 01:04:54 +00:00
player - > kartstuff [ k_driftboost ] = 50 ;
2018-06-19 02:29:52 +00:00
S_StartSound ( player - > mo , sfx_s23c ) ;
2017-02-07 22:19:04 +00:00
player - > kartstuff [ k_driftcharge ] = 0 ;
}
// Drifting: left or right?
2018-06-05 21:12:42 +00:00
if ( ( player - > cmd . driftturn > 0 ) & & player - > speed > FixedMul ( 10 < < 16 , player - > mo - > scale ) & & player - > kartstuff [ k_jmp ] = = 1
2017-03-07 05:00:00 +00:00
& & ( player - > kartstuff [ k_drift ] = = 0 | | player - > kartstuff [ k_driftend ] = = 1 ) ) // && player->kartstuff[k_drift] != 1)
{
// Starting left drift
2017-02-07 22:19:04 +00:00
player - > kartstuff [ k_drift ] = 1 ;
2017-03-07 05:00:00 +00:00
player - > kartstuff [ k_driftend ] = 0 ;
player - > kartstuff [ k_driftcharge ] = 0 ;
}
2018-06-05 21:12:42 +00:00
else if ( ( player - > cmd . driftturn < 0 ) & & player - > speed > FixedMul ( 10 < < 16 , player - > mo - > scale ) & & player - > kartstuff [ k_jmp ] = = 1
2017-03-07 05:00:00 +00:00
& & ( player - > kartstuff [ k_drift ] = = 0 | | player - > kartstuff [ k_driftend ] = = 1 ) ) // && player->kartstuff[k_drift] != -1)
{
// Starting right drift
2017-02-07 22:19:04 +00:00
player - > kartstuff [ k_drift ] = - 1 ;
2017-03-07 05:00:00 +00:00
player - > kartstuff [ k_driftend ] = 0 ;
player - > kartstuff [ k_driftcharge ] = 0 ;
}
2017-02-07 22:19:04 +00:00
else if ( player - > kartstuff [ k_jmp ] = = 0 ) // || player->kartstuff[k_turndir] == 0)
2017-03-07 03:00:10 +00:00
{
2017-03-07 05:00:00 +00:00
// drift is not being performed so if we're just finishing set driftend and decrement counters
2017-03-07 03:00:10 +00:00
if ( player - > kartstuff [ k_drift ] > 0 )
2017-03-07 03:27:44 +00:00
{
2017-03-07 03:00:10 +00:00
player - > kartstuff [ k_drift ] - - ;
2017-03-07 03:27:44 +00:00
player - > kartstuff [ k_driftend ] = 1 ;
}
2017-03-07 03:00:10 +00:00
else if ( player - > kartstuff [ k_drift ] < 0 )
2017-03-07 03:27:44 +00:00
{
2017-03-07 03:00:10 +00:00
player - > kartstuff [ k_drift ] + + ;
2017-03-07 03:27:44 +00:00
player - > kartstuff [ k_driftend ] = 1 ;
}
else
player - > kartstuff [ k_driftend ] = 0 ;
2017-03-07 03:00:10 +00:00
}
2017-02-07 22:19:04 +00:00
// Incease/decrease the drift value to continue drifting in that direction
2018-06-20 00:20:06 +00:00
if ( player - > kartstuff [ k_spinouttimer ] = = 0 & & player - > kartstuff [ k_jmp ] = = 1 & & onground & & player - > kartstuff [ k_drift ] ! = 0 )
2017-02-07 22:19:04 +00:00
{
2018-06-05 21:12:42 +00:00
fixed_t driftadditive = 24 ;
2017-02-07 22:19:04 +00:00
2017-03-07 01:05:18 +00:00
if ( player - > kartstuff [ k_drift ] > = 1 ) // Drifting to the left
2017-02-07 22:19:04 +00:00
{
player - > kartstuff [ k_drift ] + + ;
2017-03-07 03:00:10 +00:00
if ( player - > kartstuff [ k_drift ] > 5 )
player - > kartstuff [ k_drift ] = 5 ;
2017-03-13 03:28:54 +00:00
2018-06-05 21:12:42 +00:00
if ( player - > cmd . driftturn > 0 ) // Inward
2018-09-08 07:24:32 +00:00
driftadditive + = abs ( player - > cmd . driftturn ) / 100 ;
2018-06-05 21:12:42 +00:00
if ( player - > cmd . driftturn < 0 ) // Outward
2018-09-08 07:24:32 +00:00
driftadditive - = abs ( player - > cmd . driftturn ) / 75 ;
2017-02-07 22:19:04 +00:00
}
2017-03-07 01:05:18 +00:00
else if ( player - > kartstuff [ k_drift ] < = - 1 ) // Drifting to the right
2017-02-07 22:19:04 +00:00
{
player - > kartstuff [ k_drift ] - - ;
2017-03-07 03:00:10 +00:00
if ( player - > kartstuff [ k_drift ] < - 5 )
player - > kartstuff [ k_drift ] = - 5 ;
2017-03-13 03:28:54 +00:00
2018-06-05 21:12:42 +00:00
if ( player - > cmd . driftturn < 0 ) // Inward
2018-09-08 07:24:32 +00:00
driftadditive + = abs ( player - > cmd . driftturn ) / 100 ;
2018-06-05 21:12:42 +00:00
if ( player - > cmd . driftturn > 0 ) // Outward
2018-09-08 07:24:32 +00:00
driftadditive - = abs ( player - > cmd . driftturn ) / 75 ;
2017-02-07 22:19:04 +00:00
}
2017-03-13 03:28:54 +00:00
// This spawns the drift sparks
if ( player - > kartstuff [ k_driftcharge ] < dsone & & player - > kartstuff [ k_driftcharge ] + driftadditive > = dsone )
P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_DRIFT ) - > target = player - > mo ;
player - > kartstuff [ k_driftcharge ] + = driftadditive ;
player - > kartstuff [ k_driftend ] = 0 ;
2017-02-07 22:19:04 +00:00
}
// Stop drifting
if ( player - > kartstuff [ k_spinouttimer ] > 0 // banana peel
2018-01-15 21:14:45 +00:00
| | player - > speed < FixedMul ( 10 < < 16 , player - > mo - > scale ) ) // you're too slow!
2017-02-07 22:19:04 +00:00
{
player - > kartstuff [ k_drift ] = 0 ;
player - > kartstuff [ k_driftcharge ] = 0 ;
}
}
2017-02-13 04:24:49 +00:00
//
// K_KartUpdatePosition
//
static void K_KartUpdatePosition ( player_t * player )
2017-02-07 22:19:04 +00:00
{
2017-02-13 04:24:49 +00:00
fixed_t position = 1 ;
2017-12-22 15:16:41 +00:00
fixed_t oldposition = player - > kartstuff [ k_position ] ;
2017-02-13 04:24:49 +00:00
fixed_t i , ppcd , pncd , ipcd , incd ;
fixed_t pmo , imo ;
thinker_t * th ;
2017-02-17 20:14:55 +00:00
mobj_t * mo ;
2017-02-10 04:57:31 +00:00
2018-01-30 00:15:25 +00:00
if ( player - > spectator | | ! player - > mo )
return ;
2017-02-13 04:24:49 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-01-30 00:15:25 +00:00
if ( ! playeringame [ i ] | | players [ i ] . spectator | | ! players [ i ] . mo )
continue ;
2018-03-04 20:27:52 +00:00
if ( G_RaceGametype ( ) )
2017-02-13 04:24:49 +00:00
{
2018-01-30 00:15:25 +00:00
if ( ( ( ( players [ i ] . starpostnum ) + ( numstarposts + 1 ) * players [ i ] . laps ) >
2017-11-23 02:40:17 +00:00
( ( player - > starpostnum ) + ( numstarposts + 1 ) * player - > laps ) ) )
position + + ;
2018-01-30 00:15:25 +00:00
else if ( ( ( players [ i ] . starpostnum ) + ( numstarposts + 1 ) * players [ i ] . laps ) = =
( ( player - > starpostnum ) + ( numstarposts + 1 ) * player - > laps ) )
2017-11-23 02:40:17 +00:00
{
ppcd = pncd = ipcd = incd = 0 ;
2017-02-10 04:57:31 +00:00
2017-11-23 02:40:17 +00:00
player - > kartstuff [ k_prevcheck ] = players [ i ] . kartstuff [ k_prevcheck ] = 0 ;
player - > kartstuff [ k_nextcheck ] = players [ i ] . kartstuff [ k_nextcheck ] = 0 ;
2017-02-17 20:14:55 +00:00
2017-11-23 02:40:17 +00:00
// This checks every thing on the map, and looks for MT_BOSS3WAYPOINT (the thing we're using for checkpoint wp's, for now)
for ( th = thinkercap . next ; th ! = & thinkercap ; th = th - > next )
{
if ( th - > function . acp1 ! = ( actionf_p1 ) P_MobjThinker ) // Not a mobj at all, shoo
continue ;
2017-02-17 02:33:00 +00:00
2017-11-23 02:40:17 +00:00
mo = ( mobj_t * ) th ;
2017-02-17 02:33:00 +00:00
2018-03-13 05:25:04 +00:00
if ( mo - > type ! = MT_BOSS3WAYPOINT ) // TODO: Change to 'MT_WAYPOINT'?
continue ;
2017-11-23 02:40:17 +00:00
pmo = P_AproxDistance ( P_AproxDistance ( mo - > x - player - > mo - > x ,
mo - > y - player - > mo - > y ) ,
mo - > z - player - > mo - > z ) / FRACUNIT ;
imo = P_AproxDistance ( P_AproxDistance ( mo - > x - players [ i ] . mo - > x ,
mo - > y - players [ i ] . mo - > y ) ,
mo - > z - players [ i ] . mo - > z ) / FRACUNIT ;
2017-02-17 02:33:00 +00:00
2017-11-23 02:40:17 +00:00
if ( mo - > health = = player - > starpostnum )
{
player - > kartstuff [ k_prevcheck ] + = pmo ;
ppcd + + ;
}
if ( mo - > health = = ( player - > starpostnum + 1 ) )
{
player - > kartstuff [ k_nextcheck ] + = pmo ;
pncd + + ;
}
if ( mo - > health = = players [ i ] . starpostnum )
{
players [ i ] . kartstuff [ k_prevcheck ] + = imo ;
ipcd + + ;
}
if ( mo - > health = = ( players [ i ] . starpostnum + 1 ) )
{
players [ i ] . kartstuff [ k_nextcheck ] + = imo ;
incd + + ;
}
2017-02-17 02:33:00 +00:00
}
2017-11-23 02:40:17 +00:00
if ( ppcd > 1 ) player - > kartstuff [ k_prevcheck ] / = ppcd ;
if ( pncd > 1 ) player - > kartstuff [ k_nextcheck ] / = pncd ;
if ( ipcd > 1 ) players [ i ] . kartstuff [ k_prevcheck ] / = ipcd ;
if ( incd > 1 ) players [ i ] . kartstuff [ k_nextcheck ] / = incd ;
if ( ( players [ i ] . kartstuff [ k_nextcheck ] > 0 | | player - > kartstuff [ k_nextcheck ] > 0 ) & & ! player - > exiting )
2017-02-17 02:33:00 +00:00
{
2017-11-23 02:40:17 +00:00
if ( ( players [ i ] . kartstuff [ k_nextcheck ] - players [ i ] . kartstuff [ k_prevcheck ] ) <
( player - > kartstuff [ k_nextcheck ] - player - > kartstuff [ k_prevcheck ] ) )
position + + ;
2017-02-17 02:33:00 +00:00
}
2017-11-23 02:40:17 +00:00
else if ( ! player - > exiting )
2017-02-17 02:33:00 +00:00
{
2017-11-23 02:40:17 +00:00
if ( players [ i ] . kartstuff [ k_prevcheck ] > player - > kartstuff [ k_prevcheck ] )
position + + ;
2017-02-17 02:33:00 +00:00
}
2017-11-23 02:40:17 +00:00
else
2017-02-17 02:33:00 +00:00
{
2017-11-23 02:40:17 +00:00
if ( players [ i ] . starposttime < player - > starposttime )
position + + ;
2017-02-17 02:33:00 +00:00
}
2017-02-13 04:24:49 +00:00
}
2017-11-23 02:40:17 +00:00
}
2018-03-04 20:27:52 +00:00
else if ( G_BattleGametype ( ) )
2017-11-23 02:40:17 +00:00
{
2018-07-02 21:57:22 +00:00
if ( player - > exiting ) // End of match standings
{
2018-07-18 19:23:46 +00:00
if ( players [ i ] . marescore > player - > marescore ) // Only score matters
2018-07-02 21:57:22 +00:00
position + + ;
}
else
{
2018-07-18 19:23:46 +00:00
if ( players [ i ] . kartstuff [ k_bumper ] = = player - > kartstuff [ k_bumper ] & & players [ i ] . marescore > player - > marescore )
2018-07-02 21:57:22 +00:00
position + + ;
2018-07-03 19:14:47 +00:00
else if ( players [ i ] . kartstuff [ k_bumper ] > player - > kartstuff [ k_bumper ] )
2018-07-02 21:57:22 +00:00
position + + ;
}
2017-02-13 04:24:49 +00:00
}
}
2017-11-30 22:34:48 +00:00
2018-06-25 02:15:22 +00:00
if ( leveltime < starttime | | oldposition = = 0 )
2017-12-22 15:16:41 +00:00
oldposition = position ;
if ( oldposition ! = position ) // Changed places?
2018-07-04 23:06:45 +00:00
player - > kartstuff [ k_positiondelay ] = 10 ; // Position number growth
2017-12-22 15:16:41 +00:00
2017-02-13 04:24:49 +00:00
player - > kartstuff [ k_position ] = position ;
2017-02-07 22:19:04 +00:00
}
2018-06-07 23:39:45 +00:00
2017-11-23 02:40:17 +00:00
//
// K_StripItems
//
2018-06-12 20:27:51 +00:00
void K_StripItems ( player_t * player )
2017-11-01 20:24:40 +00:00
{
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
player - > kartstuff [ k_itemtype ] = KITEM_NONE ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemamount ] = 0 ;
player - > kartstuff [ k_itemheld ] = 0 ;
2018-06-12 20:27:51 +00:00
player - > kartstuff [ k_rocketsneakertimer ] = 0 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
if ( ! player - > kartstuff [ k_itemroulette ] | | player - > kartstuff [ k_roulettetype ] ! = 2 )
{
player - > kartstuff [ k_itemroulette ] = 0 ;
player - > kartstuff [ k_roulettetype ] = 0 ;
}
2018-06-12 20:27:51 +00:00
player - > kartstuff [ k_eggmanheld ] = 0 ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_hyudorotimer ] = 0 ;
player - > kartstuff [ k_stealingtimer ] = 0 ;
player - > kartstuff [ k_stolentimer ] = 0 ;
2018-06-12 20:27:51 +00:00
2018-08-04 19:48:31 +00:00
player - > kartstuff [ k_curshield ] = 0 ;
//player->kartstuff[k_thunderanim] = 0;
player - > kartstuff [ k_bananadrag ] = 0 ;
2018-06-12 20:27:51 +00:00
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_sadtimer ] = 0 ;
2018-08-24 14:14:18 +00:00
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_UpdateHnextList ( player , true ) ;
}
void K_StripOther ( player_t * player )
{
player - > kartstuff [ k_itemroulette ] = 0 ;
player - > kartstuff [ k_roulettetype ] = 0 ;
player - > kartstuff [ k_invincibilitytimer ] = 0 ;
player - > kartstuff [ k_growshrinktimer ] = 0 ;
player - > kartstuff [ k_eggmanexplode ] = 0 ;
player - > kartstuff [ k_eggmanblame ] = 0 ;
2017-11-01 20:24:40 +00:00
}
2018-06-07 23:39:45 +00:00
2017-02-13 04:24:49 +00:00
//
// K_MoveKartPlayer
//
2017-03-07 01:05:18 +00:00
void K_MoveKartPlayer ( player_t * player , boolean onground )
2016-08-15 03:51:08 +00:00
{
2017-03-07 01:05:18 +00:00
ticcmd_t * cmd = & player - > cmd ;
2016-08-21 02:15:06 +00:00
boolean ATTACK_IS_DOWN = ( ( cmd - > buttons & BT_ATTACK ) & & ! ( player - > pflags & PF_ATTACKDOWN ) ) ;
2018-03-14 01:07:08 +00:00
boolean HOLDING_ITEM = ( player - > kartstuff [ k_itemheld ] | | player - > kartstuff [ k_eggmanheld ] ) ;
2018-02-05 23:55:52 +00:00
boolean NO_HYUDORO = ( player - > kartstuff [ k_stolentimer ] = = 0 & & player - > kartstuff [ k_stealingtimer ] = = 0 ) ;
2016-08-21 02:15:06 +00:00
2017-11-23 02:40:17 +00:00
K_KartUpdatePosition ( player ) ;
2017-02-13 04:24:49 +00:00
2018-06-07 18:56:26 +00:00
if ( ! player - > exiting )
2017-02-13 04:24:49 +00:00
{
2018-07-04 21:25:38 +00:00
if ( player - > kartstuff [ k_oldposition ] < player - > kartstuff [ k_position ] ) // But first, if you lost a place,
{
2017-02-13 04:24:49 +00:00
player - > kartstuff [ k_oldposition ] = player - > kartstuff [ k_position ] ; // then the other player taunts.
2018-07-04 21:25:38 +00:00
K_RegularVoiceTimers ( player ) ; // and you can't for a bit
}
2017-02-13 04:24:49 +00:00
else if ( player - > kartstuff [ k_oldposition ] > player - > kartstuff [ k_position ] ) // Otherwise,
{
2018-06-07 18:56:26 +00:00
K_PlayOvertakeSound ( player - > mo ) ; // Say "YOU'RE TOO SLOW!"
2017-02-13 04:24:49 +00:00
player - > kartstuff [ k_oldposition ] = player - > kartstuff [ k_position ] ; // Restore the old position,
}
2018-06-07 18:34:13 +00:00
}
2017-12-22 15:16:41 +00:00
2017-02-13 04:24:49 +00:00
if ( player - > kartstuff [ k_positiondelay ] )
player - > kartstuff [ k_positiondelay ] - - ;
2016-11-21 04:23:00 +00:00
if ( ( player - > pflags & PF_ATTACKDOWN ) & & ! ( cmd - > buttons & BT_ATTACK ) )
player - > pflags & = ~ PF_ATTACKDOWN ;
else if ( cmd - > buttons & BT_ATTACK )
2016-08-21 02:15:06 +00:00
player - > pflags | = PF_ATTACKDOWN ;
2017-02-17 20:14:55 +00:00
2018-07-22 04:31:02 +00:00
if ( player & & player - > mo & & player - > mo - > health > 0 & & ! player - > spectator & & ! ( player - > exiting | | mapreset ) & & player - > kartstuff [ k_spinouttimer ] = = 0 )
2016-08-21 02:15:06 +00:00
{
2018-06-18 04:42:53 +00:00
// First, the really specific, finicky items that function without the item being directly in your item slot.
2018-08-06 17:37:03 +00:00
// Karma item dropping
if ( ATTACK_IS_DOWN & & player - > kartstuff [ k_comebackmode ] & & ! player - > kartstuff [ k_comebacktimer ] )
{
mobj_t * newitem ;
player - > kartstuff [ k_comebackmode ] = 0 ;
player - > kartstuff [ k_comebacktimer ] = comebacktime ;
S_StartSound ( player - > mo , sfx_s254 ) ;
newitem = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_RANDOMITEM ) ;
newitem - > flags2 = ( player - > mo - > flags2 & MF2_OBJECTFLIP ) ;
newitem - > fuse = 15 * TICRATE ; // selected randomly.
newitem - > threshold = 69 ; // selected "randomly".
}
2018-08-12 00:19:09 +00:00
// Eggman Monitor exploding
else if ( player - > kartstuff [ k_eggmanexplode ] )
{
if ( ATTACK_IS_DOWN & & player - > kartstuff [ k_eggmanexplode ] < = 3 * TICRATE & & player - > kartstuff [ k_eggmanexplode ] > 1 )
player - > kartstuff [ k_eggmanexplode ] = 1 ;
}
2018-06-18 04:42:53 +00:00
// Eggman Monitor throwing
2018-08-06 17:37:03 +00:00
else if ( ATTACK_IS_DOWN & & player - > kartstuff [ k_eggmanheld ] )
2016-08-21 02:15:06 +00:00
{
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , false , MT_FAKEITEM , - 1 , 0 ) ;
2017-05-13 15:14:26 +00:00
K_PlayTauntSound ( player - > mo ) ;
2018-03-14 01:07:08 +00:00
player - > kartstuff [ k_eggmanheld ] = 0 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_UpdateHnextList ( player , true ) ;
2017-05-13 15:14:26 +00:00
}
2018-06-18 04:42:53 +00:00
// Rocket Sneaker
2018-02-05 23:55:52 +00:00
else if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & onground & & NO_HYUDORO
& & player - > kartstuff [ k_rocketsneakertimer ] > 1 )
2017-05-13 15:14:26 +00:00
{
2018-03-31 04:44:03 +00:00
K_DoSneaker ( player , true ) ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_rocketsneakertimer ] - = 5 ;
if ( player - > kartstuff [ k_rocketsneakertimer ] < 1 )
player - > kartstuff [ k_rocketsneakertimer ] = 1 ;
2016-08-21 02:15:06 +00:00
}
2018-08-15 13:40:06 +00:00
else if ( player - > kartstuff [ k_itemamount ] < = 0 )
{
player - > kartstuff [ k_itemamount ] = player - > kartstuff [ k_itemheld ] = 0 ;
}
2018-02-05 23:55:52 +00:00
else
2016-08-21 02:15:06 +00:00
{
2018-02-05 23:55:52 +00:00
switch ( player - > kartstuff [ k_itemtype ] )
{
case KITEM_SNEAKER :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & onground & & NO_HYUDORO )
{
2018-03-31 04:44:03 +00:00
K_DoSneaker ( player , true ) ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
case KITEM_ROCKETSNEAKER :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & onground & & NO_HYUDORO
& & player - > kartstuff [ k_rocketsneakertimer ] = = 0 )
{
2018-03-31 04:44:03 +00:00
K_DoSneaker ( player , true ) ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_rocketsneakertimer ] = itemtime ;
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
case KITEM_INVINCIBILITY :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO ) // Doesn't hold your item slot hostage normally, so you're free to waste it if you have multiple
{
2018-02-10 06:19:33 +00:00
if ( ! player - > kartstuff [ k_invincibilitytimer ] )
{
2018-06-10 20:10:24 +00:00
mobj_t * overlay = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_INVULNFLASH ) ;
2018-02-10 06:19:33 +00:00
P_SetTarget ( & overlay - > target , player - > mo ) ;
2018-02-10 21:01:09 +00:00
overlay - > destscale = player - > mo - > scale ;
P_SetScale ( overlay , player - > mo - > scale ) ;
2018-02-10 06:19:33 +00:00
}
2018-06-15 06:18:43 +00:00
player - > kartstuff [ k_invincibilitytimer ] = itemtime + ( 2 * TICRATE ) ; // 10 seconds
2018-07-18 20:40:04 +00:00
P_RestoreMusic ( player ) ;
if ( ! cv_kartinvinsfx . value & & ! P_IsLocalPlayer ( player ) )
S_StartSound ( player - > mo , sfx_kinvnc ) ;
2018-02-05 23:55:52 +00:00
K_PlayTauntSound ( player - > mo ) ;
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
case KITEM_BANANA :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
2018-06-16 23:57:08 +00:00
INT32 moloop ;
mobj_t * mo ;
2018-06-28 00:20:19 +00:00
mobj_t * prev = player - > mo ;
2018-02-05 23:55:52 +00:00
2018-06-18 04:42:53 +00:00
//K_PlayTauntSound(player->mo);
player - > kartstuff [ k_itemheld ] = 1 ;
2018-08-05 15:38:46 +00:00
S_StartSound ( player - > mo , sfx_s254 ) ;
2018-02-05 23:55:52 +00:00
2018-06-16 23:57:08 +00:00
for ( moloop = 0 ; moloop < player - > kartstuff [ k_itemamount ] ; moloop + + )
{
2018-07-12 05:31:33 +00:00
mo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_BANANA_SHIELD ) ;
2018-08-15 13:40:06 +00:00
if ( ! mo )
{
player - > kartstuff [ k_itemamount ] = moloop ;
break ;
}
2018-08-13 21:46:51 +00:00
mo - > flags | = MF_NOCLIPTHING ;
2018-06-16 23:57:08 +00:00
mo - > threshold = 10 ;
mo - > movecount = player - > kartstuff [ k_itemamount ] ;
2018-08-24 14:14:18 +00:00
mo - > movedir = moloop + 1 ;
2018-06-16 23:57:08 +00:00
P_SetTarget ( & mo - > target , player - > mo ) ;
2018-06-28 00:20:19 +00:00
P_SetTarget ( & mo - > hprev , prev ) ;
P_SetTarget ( & prev - > hnext , mo ) ;
2018-06-16 23:57:08 +00:00
prev = mo ;
2018-02-05 23:55:52 +00:00
}
}
2018-06-18 04:42:53 +00:00
else if ( ATTACK_IS_DOWN & & player - > kartstuff [ k_itemheld ] ) // Banana x3 thrown
2018-02-05 23:55:52 +00:00
{
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , false , MT_BANANA , - 1 , 0 ) ;
2018-02-05 23:55:52 +00:00
K_PlayTauntSound ( player - > mo ) ;
2018-08-24 14:14:18 +00:00
player - > kartstuff [ k_itemamount ] - - ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_UpdateHnextList ( player , false ) ;
2018-02-05 23:55:52 +00:00
}
break ;
2018-03-14 01:07:08 +00:00
case KITEM_EGGMAN :
2018-02-05 23:55:52 +00:00
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
mobj_t * mo ;
player - > kartstuff [ k_itemamount ] - - ;
2018-03-14 01:07:08 +00:00
player - > kartstuff [ k_eggmanheld ] = 1 ;
2018-08-05 15:38:46 +00:00
S_StartSound ( player - > mo , sfx_s254 ) ;
2018-07-12 05:31:33 +00:00
mo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_FAKESHIELD ) ;
2018-02-05 23:55:52 +00:00
if ( mo )
{
2018-08-15 13:40:06 +00:00
mo - > flags | = MF_NOCLIPTHING ;
mo - > threshold = 10 ;
mo - > movecount = 1 ;
2018-08-24 14:14:18 +00:00
mo - > movedir = 1 ;
2018-02-05 23:55:52 +00:00
P_SetTarget ( & mo - > target , player - > mo ) ;
2018-06-16 23:57:08 +00:00
P_SetTarget ( & player - > mo - > hnext , mo ) ;
2018-02-05 23:55:52 +00:00
}
}
break ;
case KITEM_ORBINAUT :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
2018-06-27 19:58:43 +00:00
angle_t newangle ;
2018-06-18 04:42:53 +00:00
INT32 moloop ;
2018-06-28 00:20:19 +00:00
mobj_t * mo = NULL ;
mobj_t * prev = player - > mo ;
2018-06-18 04:42:53 +00:00
2018-06-27 19:58:43 +00:00
//K_PlayTauntSound(player->mo);
2018-06-18 04:42:53 +00:00
player - > kartstuff [ k_itemheld ] = 1 ;
S_StartSound ( player - > mo , sfx_s3k3a ) ;
for ( moloop = 0 ; moloop < player - > kartstuff [ k_itemamount ] ; moloop + + )
2018-02-05 23:55:52 +00:00
{
2018-06-27 19:58:43 +00:00
newangle = FixedAngle ( ( ( 360 / player - > kartstuff [ k_itemamount ] ) * moloop ) * FRACUNIT ) + ANGLE_90 ;
2018-08-30 20:10:25 +00:00
mo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_ORBINAUT_SHIELD ) ;
2018-08-15 13:40:06 +00:00
if ( ! mo )
{
player - > kartstuff [ k_itemamount ] = moloop ;
break ;
}
2018-08-13 21:46:51 +00:00
mo - > flags | = MF_NOCLIPTHING ;
2018-06-27 19:58:43 +00:00
mo - > angle = newangle ;
mo - > threshold = 10 ;
mo - > movecount = player - > kartstuff [ k_itemamount ] ;
2018-06-28 00:20:19 +00:00
mo - > movedir = mo - > lastlook = moloop + 1 ;
2018-07-23 00:55:18 +00:00
mo - > color = player - > skincolor ;
2018-06-27 19:58:43 +00:00
P_SetTarget ( & mo - > target , player - > mo ) ;
2018-06-28 00:20:19 +00:00
P_SetTarget ( & mo - > hprev , prev ) ;
P_SetTarget ( & prev - > hnext , mo ) ;
2018-06-27 19:58:43 +00:00
prev = mo ;
2018-06-18 04:42:53 +00:00
}
2018-02-05 23:55:52 +00:00
}
2018-06-18 04:42:53 +00:00
else if ( ATTACK_IS_DOWN & & player - > kartstuff [ k_itemheld ] ) // Orbinaut x3 thrown
2018-02-05 23:55:52 +00:00
{
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , true , MT_ORBINAUT , 1 , 0 ) ;
2018-02-05 23:55:52 +00:00
K_PlayTauntSound ( player - > mo ) ;
2018-08-24 14:14:18 +00:00
player - > kartstuff [ k_itemamount ] - - ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_UpdateHnextList ( player , false ) ;
2018-02-05 23:55:52 +00:00
}
break ;
case KITEM_JAWZ :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
2018-06-27 19:58:43 +00:00
angle_t newangle ;
2018-06-18 04:42:53 +00:00
INT32 moloop ;
2018-06-28 00:20:19 +00:00
mobj_t * mo = NULL ;
mobj_t * prev = player - > mo ;
2018-06-18 04:42:53 +00:00
2018-06-27 19:58:43 +00:00
//K_PlayTauntSound(player->mo);
2018-06-18 04:42:53 +00:00
player - > kartstuff [ k_itemheld ] = 1 ;
S_StartSound ( player - > mo , sfx_s3k3a ) ;
for ( moloop = 0 ; moloop < player - > kartstuff [ k_itemamount ] ; moloop + + )
2018-02-05 23:55:52 +00:00
{
2018-06-27 19:58:43 +00:00
newangle = FixedAngle ( ( ( 360 / player - > kartstuff [ k_itemamount ] ) * moloop ) * FRACUNIT ) + ANGLE_90 ;
2018-08-30 20:10:25 +00:00
mo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_JAWZ_SHIELD ) ;
2018-08-15 13:40:06 +00:00
if ( ! mo )
{
player - > kartstuff [ k_itemamount ] = moloop ;
break ;
}
2018-08-13 21:46:51 +00:00
mo - > flags | = MF_NOCLIPTHING ;
2018-06-27 19:58:43 +00:00
mo - > angle = newangle ;
mo - > threshold = 10 ;
mo - > movecount = player - > kartstuff [ k_itemamount ] ;
2018-06-28 00:20:19 +00:00
mo - > movedir = mo - > lastlook = moloop + 1 ;
2018-06-27 19:58:43 +00:00
P_SetTarget ( & mo - > target , player - > mo ) ;
2018-06-28 00:20:19 +00:00
P_SetTarget ( & mo - > hprev , prev ) ;
P_SetTarget ( & prev - > hnext , mo ) ;
2018-06-27 19:58:43 +00:00
prev = mo ;
2018-06-18 04:42:53 +00:00
}
2018-02-05 23:55:52 +00:00
}
2018-06-18 04:42:53 +00:00
else if ( ATTACK_IS_DOWN & & HOLDING_ITEM & & player - > kartstuff [ k_itemheld ] ) // Jawz thrown
2018-02-05 23:55:52 +00:00
{
if ( player - > kartstuff [ k_throwdir ] = = 1 | | player - > kartstuff [ k_throwdir ] = = 0 )
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , true , MT_JAWZ , 1 , 0 ) ;
2018-02-05 23:55:52 +00:00
else if ( player - > kartstuff [ k_throwdir ] = = - 1 ) // Throwing backward gives you a dud that doesn't home in
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , true , MT_JAWZ_DUD , - 1 , 0 ) ;
2018-02-05 23:55:52 +00:00
K_PlayTauntSound ( player - > mo ) ;
2018-08-24 14:14:18 +00:00
player - > kartstuff [ k_itemamount ] - - ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_UpdateHnextList ( player , false ) ;
2018-02-05 23:55:52 +00:00
}
break ;
case KITEM_MINE :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
mobj_t * mo ;
player - > kartstuff [ k_itemheld ] = 1 ;
2018-08-05 15:38:46 +00:00
S_StartSound ( player - > mo , sfx_s254 ) ;
2018-07-12 05:31:33 +00:00
mo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_SSMINE_SHIELD ) ;
2018-02-05 23:55:52 +00:00
if ( mo )
2018-06-16 23:57:08 +00:00
{
2018-08-15 13:40:06 +00:00
mo - > flags | = MF_NOCLIPTHING ;
mo - > threshold = 10 ;
mo - > movecount = 1 ;
2018-08-24 14:14:18 +00:00
mo - > movedir = 1 ;
2018-02-05 23:55:52 +00:00
P_SetTarget ( & mo - > target , player - > mo ) ;
2018-06-16 23:57:08 +00:00
P_SetTarget ( & player - > mo - > hnext , mo ) ;
}
2018-02-05 23:55:52 +00:00
}
2018-06-20 00:20:06 +00:00
else if ( ATTACK_IS_DOWN & & player - > kartstuff [ k_itemheld ] )
2018-02-05 23:55:52 +00:00
{
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , false , MT_SSMINE , 1 , 1 ) ;
2018-02-05 23:55:52 +00:00
K_PlayTauntSound ( player - > mo ) ;
player - > kartstuff [ k_itemamount ] - - ;
player - > kartstuff [ k_itemheld ] = 0 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_UpdateHnextList ( player , true ) ;
2018-02-05 23:55:52 +00:00
}
break ;
case KITEM_BALLHOG :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
player - > kartstuff [ k_itemamount ] - - ;
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , true , MT_BALLHOG , 1 , 0 ) ;
2018-02-05 23:55:52 +00:00
S_StartSound ( player - > mo , sfx_mario7 ) ;
K_PlayTauntSound ( player - > mo ) ;
}
break ;
case KITEM_SPB :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
2018-06-08 04:02:28 +00:00
UINT8 ploop ;
UINT8 bestrank = 0 ;
fixed_t dist = 0 ;
for ( ploop = 0 ; ploop < MAXPLAYERS ; ploop + + )
{
fixed_t thisdist ;
if ( ! playeringame [ ploop ] | | players [ ploop ] . spectator )
continue ;
if ( & players [ ploop ] = = player )
continue ;
if ( ! players [ ploop ] . mo )
continue ;
if ( players [ ploop ] . exiting )
continue ;
thisdist = R_PointToDist2 ( player - > mo - > x , player - > mo - > y , players [ ploop ] . mo - > x , players [ ploop ] . mo - > y ) ;
if ( bestrank = = 0 | | players [ ploop ] . kartstuff [ k_position ] < bestrank )
{
bestrank = players [ ploop ] . kartstuff [ k_position ] ;
dist = thisdist ;
}
}
if ( dist = = 0 )
spbincoming = 6 * TICRATE ; // If you couldn't find anyone, just set an abritary timer
else
spbincoming = ( tic_t ) max ( 1 , FixedDiv ( dist , 64 * FRACUNIT ) / FRACUNIT ) ;
spbplayer = player - players ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemamount ] - - ;
2018-06-08 04:02:28 +00:00
K_PlayTauntSound ( player - > mo ) ;
2018-02-05 23:55:52 +00:00
}
break ;
2018-02-10 06:19:33 +00:00
case KITEM_GROW :
2018-02-05 23:55:52 +00:00
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO
2018-02-10 06:19:33 +00:00
& & player - > kartstuff [ k_growshrinktimer ] < = 0 ) // Grow holds the item box hostage
2018-02-05 23:55:52 +00:00
{
K_PlayTauntSound ( player - > mo ) ;
2018-06-11 05:51:50 +00:00
player - > mo - > scalespeed = FRACUNIT / TICRATE ;
2018-02-10 21:01:09 +00:00
player - > mo - > destscale = 3 * ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) / 2 ;
2018-07-12 05:31:33 +00:00
if ( cv_kartdebugshrink . value & & ! player - > bot )
player - > mo - > destscale = 6 * player - > mo - > destscale / 8 ;
2018-06-15 06:18:43 +00:00
player - > kartstuff [ k_growshrinktimer ] = itemtime + ( 4 * TICRATE ) ; // 12 seconds
2018-07-18 20:40:04 +00:00
P_RestoreMusic ( player ) ;
if ( ! cv_kartinvinsfx . value & & ! P_IsLocalPlayer ( player ) )
S_StartSound ( player - > mo , sfx_kgrow ) ;
2018-02-10 21:01:09 +00:00
S_StartSound ( player - > mo , sfx_kc5a ) ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
2018-02-10 06:19:33 +00:00
case KITEM_SHRINK :
2018-02-05 23:55:52 +00:00
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
2018-06-08 04:02:28 +00:00
K_DoShrink ( player ) ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
2018-08-04 19:48:31 +00:00
case KITEM_THUNDERSHIELD :
if ( player - > kartstuff [ k_curshield ] < = 0 )
{
mobj_t * shield = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_THUNDERSHIELD ) ;
P_SetTarget ( & shield - > target , player - > mo ) ;
player - > kartstuff [ k_curshield ] = 1 ;
}
2018-02-05 23:55:52 +00:00
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
2018-08-04 19:48:31 +00:00
K_DoThunderShield ( player ) ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
case KITEM_HYUDORO :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
{
player - > kartstuff [ k_itemamount ] - - ;
2018-08-05 15:38:46 +00:00
K_DoHyudoroSteal ( player ) ; // yes. yes they do.
2018-02-05 23:55:52 +00:00
}
break ;
case KITEM_POGOSPRING :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & onground & & NO_HYUDORO
& & ! player - > kartstuff [ k_pogospring ] )
{
K_PlayTauntSound ( player - > mo ) ;
2018-07-17 01:27:50 +00:00
K_DoPogoSpring ( player - > mo , 32 < < FRACBITS , false ) ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_pogospring ] = 1 ;
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
2018-06-25 05:36:21 +00:00
case KITEM_KITCHENSINK :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO )
2018-09-04 23:14:44 +00:00
{
mobj_t * mo ;
player - > kartstuff [ k_itemheld ] = 1 ;
2018-09-05 00:51:16 +00:00
S_StartSound ( player - > mo , sfx_s254 ) ;
2018-09-04 23:14:44 +00:00
mo = P_SpawnMobj ( player - > mo - > x , player - > mo - > y , player - > mo - > z , MT_SINK_SHIELD ) ;
if ( mo )
{
mo - > flags | = MF_NOCLIPTHING ;
mo - > threshold = 10 ;
mo - > movecount = 1 ;
mo - > movedir = 1 ;
P_SetTarget ( & mo - > target , player - > mo ) ;
P_SetTarget ( & player - > mo - > hnext , mo ) ;
}
}
else if ( ATTACK_IS_DOWN & & HOLDING_ITEM & & player - > kartstuff [ k_itemheld ] ) // Sink thrown
2018-06-25 05:36:21 +00:00
{
2018-09-04 23:58:20 +00:00
K_ThrowKartItem ( player , false , MT_SINK , 1 , 2 ) ;
2018-06-25 05:36:21 +00:00
K_PlayTauntSound ( player - > mo ) ;
player - > kartstuff [ k_itemamount ] - - ;
player - > kartstuff [ k_itemheld ] = 0 ;
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_UpdateHnextList ( player , true ) ;
2018-06-25 05:36:21 +00:00
}
break ;
2018-02-05 23:55:52 +00:00
case KITEM_SAD :
if ( ATTACK_IS_DOWN & & ! HOLDING_ITEM & & NO_HYUDORO
& & ! player - > kartstuff [ k_sadtimer ] )
{
player - > kartstuff [ k_sadtimer ] = stealtime ;
player - > kartstuff [ k_itemamount ] - - ;
}
break ;
default :
break ;
}
2017-02-18 18:39:25 +00:00
}
2017-11-07 05:57:42 +00:00
2018-02-05 23:55:52 +00:00
// No more!
2018-08-24 14:14:18 +00:00
if ( ! player - > kartstuff [ k_itemamount ] )
{
player - > kartstuff [ k_itemheld ] = 0 ;
2018-02-05 23:55:52 +00:00
player - > kartstuff [ k_itemtype ] = KITEM_NONE ;
2018-08-24 14:14:18 +00:00
}
2017-11-07 05:57:42 +00:00
2018-08-04 19:48:31 +00:00
if ( player - > kartstuff [ k_itemtype ] ! = KITEM_THUNDERSHIELD )
player - > kartstuff [ k_curshield ] = 0 ;
2018-06-15 06:18:43 +00:00
if ( player - > kartstuff [ k_itemtype ] = = KITEM_SPB
| | player - > kartstuff [ k_itemtype ] = = KITEM_SHRINK
2018-07-01 08:36:09 +00:00
| | player - > kartstuff [ k_growshrinktimer ] < 0
2018-06-15 06:18:43 +00:00
| | spbincoming )
indirectitemcooldown = 20 * TICRATE ;
2018-02-05 23:55:52 +00:00
if ( player - > kartstuff [ k_hyudorotimer ] > 0 )
2016-08-21 02:15:06 +00:00
{
2018-06-06 22:36:39 +00:00
if ( splitscreen )
2016-08-21 02:15:06 +00:00
{
if ( leveltime & 1 )
player - > mo - > flags2 | = MF2_DONTDRAW ;
else
player - > mo - > flags2 & = ~ MF2_DONTDRAW ;
2018-06-06 22:36:39 +00:00
2018-06-07 23:39:45 +00:00
if ( player - > kartstuff [ k_hyudorotimer ] > = ( 1 * TICRATE / 2 ) & & player - > kartstuff [ k_hyudorotimer ] < = hyudorotime - ( 1 * TICRATE / 2 ) )
2018-06-06 22:36:39 +00:00
{
if ( player = = & players [ secondarydisplayplayer ] )
player - > mo - > eflags | = MFE_DRAWONLYFORP2 ;
else if ( player = = & players [ thirddisplayplayer ] & & splitscreen > 1 )
player - > mo - > eflags | = MFE_DRAWONLYFORP3 ;
else if ( player = = & players [ fourthdisplayplayer ] & & splitscreen > 2 )
player - > mo - > eflags | = MFE_DRAWONLYFORP4 ;
else
player - > mo - > eflags | = MFE_DRAWONLYFORP1 ;
}
else
player - > mo - > eflags & = ~ ( MFE_DRAWONLYFORP1 | MFE_DRAWONLYFORP2 | MFE_DRAWONLYFORP3 | MFE_DRAWONLYFORP4 ) ;
2016-08-21 02:15:06 +00:00
}
else
2018-06-06 22:36:39 +00:00
{
if ( player = = & players [ displayplayer ]
2018-06-07 23:39:45 +00:00
| | ( player ! = & players [ displayplayer ] & & ( player - > kartstuff [ k_hyudorotimer ] < ( 1 * TICRATE / 2 ) | | player - > kartstuff [ k_hyudorotimer ] > hyudorotime - ( 1 * TICRATE / 2 ) ) ) )
2018-06-06 22:36:39 +00:00
{
if ( leveltime & 1 )
player - > mo - > flags2 | = MF2_DONTDRAW ;
else
player - > mo - > flags2 & = ~ MF2_DONTDRAW ;
}
else
player - > mo - > flags2 | = MF2_DONTDRAW ;
}
2016-08-21 02:15:06 +00:00
2018-02-05 23:55:52 +00:00
player - > powers [ pw_flashing ] = player - > kartstuff [ k_hyudorotimer ] ; // We'll do this for now, let's people know about the invisible people through subtle hints
2016-08-21 02:15:06 +00:00
}
2018-02-05 23:55:52 +00:00
else if ( player - > kartstuff [ k_hyudorotimer ] = = 0 )
2016-08-21 02:15:06 +00:00
{
2017-11-06 04:18:58 +00:00
player - > mo - > flags2 & = ~ MF2_DONTDRAW ;
2018-06-06 22:36:39 +00:00
player - > mo - > eflags & = ~ ( MFE_DRAWONLYFORP1 | MFE_DRAWONLYFORP2 | MFE_DRAWONLYFORP3 | MFE_DRAWONLYFORP4 ) ;
2017-11-06 04:18:58 +00:00
}
2017-11-13 03:48:32 +00:00
2018-07-03 19:14:47 +00:00
if ( G_BattleGametype ( ) & & player - > kartstuff [ k_bumper ] < = 0 ) // dead in match? you da bomb
2017-11-06 04:18:58 +00:00
{
Dropping items!
* Shield Drop...
* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
* Pops your Thunder Shield.
* Happens upon ANY hit, except for deathpits.
* HUD Drop...
* Also does the above, except for the Thunder Shield thing.
* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
* Happens upon Size Down and battle elimination.
* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
* Allow shrunken players to pick up item boxes again.
* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
* Break NiGHTS a little through my machinations.
2018-09-06 21:17:29 +00:00
K_DropItems ( player ) ; //K_StripItems(player);
K_StripOther ( player ) ;
2017-11-06 04:18:58 +00:00
player - > mo - > flags2 | = MF2_SHADOW ;
2018-06-16 04:00:46 +00:00
player - > powers [ pw_flashing ] = player - > kartstuff [ k_comebacktimer ] ;
2017-11-06 04:18:58 +00:00
}
2018-07-03 19:14:47 +00:00
else if ( G_RaceGametype ( ) | | player - > kartstuff [ k_bumper ] > 0 )
2017-11-06 04:18:58 +00:00
{
player - > mo - > flags2 & = ~ MF2_SHADOW ;
2016-08-21 02:15:06 +00:00
}
2017-11-05 06:43:47 +00:00
}
2018-08-31 01:51:27 +00:00
/*if (player->kartstuff[k_growshrinktimer] > 1)
player - > powers [ pw_flashing ] = 2 ; */
2016-08-21 02:15:06 +00:00
// Friction
if ( player - > speed > 0 & & cmd - > forwardmove = = 0 & & player - > mo - > friction = = 59392 )
2017-11-20 00:39:40 +00:00
player - > mo - > friction + = 4608 ;
2016-08-21 02:15:06 +00:00
if ( player - > speed > 0 & & cmd - > forwardmove < 0 & & player - > mo - > friction = = 59392 )
2017-11-20 00:39:40 +00:00
player - > mo - > friction + = 1608 ;
2018-07-03 19:14:47 +00:00
if ( G_BattleGametype ( ) & & player - > kartstuff [ k_bumper ] < = 0 )
2017-11-20 00:39:40 +00:00
{
player - > mo - > friction + = 1228 ;
if ( player - > mo - > friction > FRACUNIT )
player - > mo - > friction = FRACUNIT ;
if ( player - > mo - > friction < 0 )
player - > mo - > friction = 0 ;
player - > mo - > movefactor = FixedDiv ( ORIG_FRICTION , player - > mo - > friction ) ;
if ( player - > mo - > movefactor < FRACUNIT )
player - > mo - > movefactor = 19 * player - > mo - > movefactor - 18 * FRACUNIT ;
else
player - > mo - > movefactor = FRACUNIT ; //player->mo->movefactor = ((player->mo->friction - 0xDB34)*(0xA))/0x80;
if ( player - > mo - > movefactor < 32 )
player - > mo - > movefactor = 32 ;
}
2018-07-21 02:51:18 +00:00
if ( player - > kartstuff [ k_spinouttimer ] & & player - > kartstuff [ k_wipeoutslow ] )
2018-07-20 20:13:02 +00:00
{
2018-07-21 02:51:18 +00:00
player - > mo - > friction - = FixedMul ( 1228 , player - > kartstuff [ k_offroad ] ) ;
if ( player - > kartstuff [ k_wipeoutslow ] = = 1 )
player - > mo - > friction - = 4912 ;
2018-07-20 20:13:02 +00:00
}
2016-08-21 02:15:06 +00:00
2017-03-07 01:05:18 +00:00
K_KartDrift ( player , onground ) ;
2016-08-15 03:51:08 +00:00
2016-08-21 02:15:06 +00:00
// Quick Turning
// You can't turn your kart when you're not moving.
// So now it's time to burn some rubber!
2018-06-25 02:15:22 +00:00
if ( player - > speed < 2 & & leveltime > starttime & & cmd - > buttons & BT_ACCELERATE & & cmd - > buttons & BT_BRAKE & & cmd - > driftturn ! = 0 )
2016-08-21 02:15:06 +00:00
{
2017-03-07 01:05:18 +00:00
if ( leveltime % 20 = = 0 )
2016-08-21 02:15:06 +00:00
S_StartSound ( player - > mo , sfx_mkslid ) ;
}
2016-08-15 03:51:08 +00:00
2016-08-21 02:15:06 +00:00
// Squishing
2018-06-07 23:39:45 +00:00
// If a Grow player or a sector crushes you, get flattened instead of being killed.
2016-08-15 03:51:08 +00:00
2016-08-21 02:15:06 +00:00
if ( player - > kartstuff [ k_squishedtimer ] < = 0 )
{
player - > mo - > flags & = ~ MF_NOCLIP ;
}
else
{
player - > mo - > flags | = MF_NOCLIP ;
player - > mo - > momx = 0 ;
player - > mo - > momy = 0 ;
}
2018-06-25 02:15:22 +00:00
// Play the starting countdown sounds
2018-06-28 00:51:02 +00:00
if ( player = = & players [ displayplayer ] ) // Don't play louder in splitscreen
{
if ( ( leveltime = = starttime - ( 3 * TICRATE ) ) | | ( leveltime = = starttime - ( 2 * TICRATE ) ) | | ( leveltime = = starttime - TICRATE ) )
S_StartSound ( NULL , sfx_s3ka7 ) ;
if ( leveltime = = starttime )
2018-06-30 00:15:42 +00:00
{
2018-06-28 00:51:02 +00:00
S_StartSound ( NULL , sfx_s3kad ) ;
2018-06-30 00:15:42 +00:00
S_StopMusic ( ) ; // The GO! sound stops the level start ambience
}
2018-06-28 00:51:02 +00:00
}
2018-06-25 02:15:22 +00:00
2016-08-21 02:15:06 +00:00
// Start charging once you're given the opportunity.
2018-06-30 00:15:42 +00:00
if ( leveltime > = starttime - ( 2 * TICRATE ) & & leveltime < = starttime )
2018-07-04 21:25:38 +00:00
{
2018-06-30 00:15:42 +00:00
if ( cmd - > buttons & BT_ACCELERATE )
player - > kartstuff [ k_boostcharge ] + + ;
else
player - > kartstuff [ k_boostcharge ] = 0 ;
}
2018-06-25 02:15:22 +00:00
2016-08-21 02:15:06 +00:00
// Increase your size while charging your engine.
2018-06-25 02:15:22 +00:00
if ( leveltime < starttime + 10 )
2018-07-12 05:31:33 +00:00
{
2018-03-30 01:43:02 +00:00
player - > mo - > destscale = ( mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) + ( player - > kartstuff [ k_boostcharge ] * 131 ) ;
2018-07-12 05:31:33 +00:00
if ( cv_kartdebugshrink . value & & ! player - > bot )
player - > mo - > destscale = 6 * player - > mo - > destscale / 8 ;
}
2016-08-21 02:15:06 +00:00
// Determine the outcome of your charge.
2018-06-25 02:15:22 +00:00
if ( leveltime > starttime & & player - > kartstuff [ k_boostcharge ] )
2016-08-21 02:15:06 +00:00
{
2018-08-05 15:38:46 +00:00
// Not even trying?
if ( player - > kartstuff [ k_boostcharge ] < 35 )
{
if ( player - > kartstuff [ k_boostcharge ] > 17 )
S_StartSound ( player - > mo , sfx_cdfm00 ) ; // chosen instead of a conventional skid because it's more engine-like
}
2016-08-21 02:15:06 +00:00
// Get an instant boost!
2018-08-05 15:38:46 +00:00
else if ( player - > kartstuff [ k_boostcharge ] < = 50 )
2016-08-21 02:15:06 +00:00
{
2018-03-31 04:44:03 +00:00
player - > kartstuff [ k_sneakertimer ] = - ( ( 21 * ( player - > kartstuff [ k_boostcharge ] * player - > kartstuff [ k_boostcharge ] ) ) / 425 ) + 131 ; // max time is 70, min time is 7; yay parabooolas
2018-06-26 16:02:14 +00:00
if ( ! player - > kartstuff [ k_floorboost ] | | player - > kartstuff [ k_floorboost ] = = 3 )
{
if ( player - > kartstuff [ k_sneakertimer ] > = 70 )
S_StartSound ( player - > mo , sfx_s25f ) ; // Special sound for the perfect start boost!
else if ( player - > kartstuff [ k_sneakertimer ] > = sneakertime )
2018-07-04 21:25:38 +00:00
S_StartSound ( player - > mo , sfx_cdfm01 ) ; // Sneaker boost sound for big boost
2018-06-26 16:02:14 +00:00
else
S_StartSound ( player - > mo , sfx_s23c ) ; // Drift boost sound for small boost
}
2016-08-21 02:15:06 +00:00
}
// You overcharged your engine? Those things are expensive!!!
2018-03-30 01:43:02 +00:00
else if ( player - > kartstuff [ k_boostcharge ] > 50 )
2017-02-07 22:19:04 +00:00
{
player - > powers [ pw_nocontrol ] = 40 ;
2018-06-30 22:18:13 +00:00
//S_StartSound(player->mo, sfx_kc34);
S_StartSound ( player - > mo , sfx_s3k83 ) ;
player - > pflags | = PF_SKIDDOWN ; // cheeky pflag reuse
2017-02-07 22:19:04 +00:00
}
2016-08-21 02:15:06 +00:00
player - > kartstuff [ k_boostcharge ] = 0 ;
}
2016-08-15 03:51:08 +00:00
}
2018-07-01 08:36:09 +00:00
void K_CalculateBattleWanted ( void )
{
2018-09-05 00:16:42 +00:00
UINT8 numingame = 0 , numplaying = 0 , numwanted = 0 ;
2018-07-03 19:14:47 +00:00
SINT8 bestbumperplayer = - 1 , bestbumper = - 1 ;
2018-07-01 08:36:09 +00:00
SINT8 camppos [ MAXPLAYERS ] ; // who is the biggest camper
UINT8 ties = 0 , nextcamppos = 0 ;
2018-07-03 19:14:47 +00:00
boolean setbumper = false ;
2018-07-01 08:36:09 +00:00
UINT8 i , j ;
if ( ! G_BattleGametype ( ) )
{
for ( i = 0 ; i < 4 ; i + + )
battlewanted [ i ] = - 1 ;
return ;
}
2018-07-04 01:12:25 +00:00
wantedcalcdelay = wantedfrequency ;
2018-07-01 08:36:09 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
camppos [ i ] = - 1 ; // initialize
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
UINT8 position = 1 ;
if ( ! playeringame [ i ] | | players [ i ] . spectator ) // Not playing
continue ;
if ( players [ i ] . exiting ) // We're done, don't calculate.
return ;
2018-09-05 00:16:42 +00:00
numplaying + + ;
2018-07-03 19:14:47 +00:00
if ( players [ i ] . kartstuff [ k_bumper ] < = 0 ) // Not alive, so don't do anything else
2018-07-01 08:36:09 +00:00
continue ;
2018-07-01 19:25:10 +00:00
numingame + + ;
2018-07-03 19:14:47 +00:00
if ( bestbumper = = - 1 | | players [ i ] . kartstuff [ k_bumper ] > bestbumper )
2018-07-01 08:36:09 +00:00
{
2018-07-03 19:14:47 +00:00
bestbumper = players [ i ] . kartstuff [ k_bumper ] ;
bestbumperplayer = i ;
2018-07-01 08:36:09 +00:00
}
2018-07-03 19:14:47 +00:00
else if ( players [ i ] . kartstuff [ k_bumper ] = = bestbumper )
bestbumperplayer = - 1 ; // Tie, no one has best bumper.
2018-07-01 08:36:09 +00:00
for ( j = 0 ; j < MAXPLAYERS ; j + + )
{
if ( ! playeringame [ j ] | | players [ j ] . spectator )
continue ;
2018-07-03 19:14:47 +00:00
if ( players [ j ] . kartstuff [ k_bumper ] < = 0 )
2018-07-01 08:36:09 +00:00
continue ;
if ( j = = i )
continue ;
2018-07-18 19:23:46 +00:00
if ( players [ j ] . kartstuff [ k_wanted ] = = players [ i ] . kartstuff [ k_wanted ] & & players [ j ] . marescore > players [ i ] . marescore )
2018-07-01 08:36:09 +00:00
position + + ;
else if ( players [ j ] . kartstuff [ k_wanted ] > players [ i ] . kartstuff [ k_wanted ] )
position + + ;
}
position - - ; // Make zero based
while ( camppos [ position ] ! = - 1 ) // Port priority!
position + + ;
camppos [ position ] = i ;
}
2018-09-05 00:16:42 +00:00
if ( numplaying < = 2 | | ( numingame < = 2 & & bestbumper = = 1 ) ) // In 1v1s then there's no need for WANTED. In bigger netgames, don't show anyone as WANTED when they're equally matched.
2018-07-01 08:36:09 +00:00
numwanted = 0 ;
else
numwanted = min ( 4 , 1 + ( ( numingame - 2 ) / 4 ) ) ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( i + 1 > numwanted ) // Not enough players for this slot to be wanted!
battlewanted [ i ] = - 1 ;
2018-07-03 19:14:47 +00:00
else if ( bestbumperplayer ! = - 1 & & ! setbumper ) // If there's a player who has an untied bumper lead over everyone else, they are the first to be wanted.
2018-07-01 08:36:09 +00:00
{
2018-07-03 19:14:47 +00:00
battlewanted [ i ] = bestbumperplayer ;
setbumper = true ; // Don't set twice
2018-07-01 08:36:09 +00:00
}
else
{
2018-07-03 19:14:47 +00:00
// Don't accidentally set the same player, if the bestbumperplayer is also a huge camper.
while ( bestbumperplayer ! = - 1 & & camppos [ nextcamppos ] ! = - 1
& & bestbumperplayer = = camppos [ nextcamppos ] )
2018-07-02 21:57:22 +00:00
nextcamppos + + ;
// Do not add *any* more people if there's too many times that are tied with others.
2018-07-01 08:36:09 +00:00
// This could theoretically happen very easily if people don't hit each other for a while after the start of a match.
2018-07-01 19:25:10 +00:00
// (I will be sincerely impressed if more than 2 people tie after people start hitting each other though)
2018-07-01 08:36:09 +00:00
if ( camppos [ nextcamppos ] = = - 1 // Out of entries
2018-07-02 21:57:22 +00:00
| | ties > = ( numwanted - i ) ) // Already counted ties
2018-07-01 08:36:09 +00:00
{
battlewanted [ i ] = - 1 ;
continue ;
}
2018-07-02 21:57:22 +00:00
if ( ties < ( numwanted - i ) )
2018-07-01 08:36:09 +00:00
{
ties = 0 ; // Reset
for ( j = 0 ; j < 2 ; j + + )
{
if ( camppos [ nextcamppos + ( j + 1 ) ] = = - 1 ) // Nothing beyond, cancel
break ;
if ( players [ camppos [ nextcamppos ] ] . kartstuff [ k_wanted ] = = players [ camppos [ nextcamppos + ( j + 1 ) ] ] . kartstuff [ k_wanted ] )
ties + + ;
}
}
2018-07-02 21:57:22 +00:00
if ( ties < ( numwanted - i ) ) // Is it still low enough after counting?
2018-07-01 08:36:09 +00:00
{
battlewanted [ i ] = camppos [ nextcamppos ] ;
nextcamppos + + ;
}
else
battlewanted [ i ] = - 1 ;
}
}
}
2018-07-03 19:14:47 +00:00
void K_CheckBumpers ( void )
2017-10-22 07:06:35 +00:00
{
UINT8 i ;
2017-10-22 21:26:43 +00:00
UINT8 numingame = 0 ;
2018-02-09 00:58:10 +00:00
SINT8 winnernum = - 1 ;
2018-07-01 03:35:38 +00:00
INT32 winnerscoreadd = 0 ;
2017-12-28 23:37:25 +00:00
2017-12-19 01:59:04 +00:00
if ( ! multiplayer )
2017-11-05 06:43:47 +00:00
return ;
2018-03-04 20:27:52 +00:00
if ( ! G_BattleGametype ( ) )
2017-11-05 06:43:47 +00:00
return ;
if ( gameaction = = ga_completed )
2017-10-22 07:06:35 +00:00
return ;
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2017-10-25 20:15:47 +00:00
if ( ! playeringame [ i ] | | players [ i ] . spectator ) // not even in-game
2017-10-22 07:06:35 +00:00
continue ;
2017-11-14 01:45:57 +00:00
if ( players [ i ] . exiting ) // we're already exiting! stop!
return ;
2017-10-22 21:26:43 +00:00
numingame + + ;
2018-07-18 19:23:46 +00:00
winnerscoreadd + = players [ i ] . marescore ;
2017-10-22 07:06:35 +00:00
2018-07-03 19:14:47 +00:00
if ( players [ i ] . kartstuff [ k_bumper ] < = 0 ) // if you don't have any bumpers, you're probably not a winner
2017-10-22 21:26:43 +00:00
continue ;
else if ( winnernum > - 1 ) // TWO winners? that's dumb :V
return ;
2018-07-01 03:35:38 +00:00
2017-10-22 07:06:35 +00:00
winnernum = i ;
2018-07-18 19:23:46 +00:00
winnerscoreadd - = players [ i ] . marescore ;
2017-10-22 07:06:35 +00:00
}
2018-07-22 22:15:11 +00:00
if ( numingame < = 1 )
return ;
2017-10-22 21:26:43 +00:00
2018-07-01 03:35:38 +00:00
if ( winnernum > - 1 & & playeringame [ winnernum ] )
2017-10-26 23:37:13 +00:00
{
2018-07-18 19:23:46 +00:00
players [ winnernum ] . marescore + = winnerscoreadd ;
2018-07-01 03:35:38 +00:00
CONS_Printf ( M_GetText ( " %s recieved %d point%s for winning! \n " ) , player_names [ winnernum ] , winnerscoreadd , ( winnerscoreadd = = 1 ? " " : " s " ) ) ;
2017-10-26 23:37:13 +00:00
}
2017-10-22 21:26:43 +00:00
2018-07-12 23:04:37 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + ) // This can't go in the earlier loop because winning adds points
K_KartUpdatePosition ( & players [ i ] ) ;
for ( i = 0 ; i < MAXPLAYERS ; i + + ) // and it can't be merged with this loop because it needs to be all updated before exiting... multi-loops suck...
2017-11-14 01:45:57 +00:00
P_DoPlayerExit ( & players [ i ] ) ;
2017-10-22 07:06:35 +00:00
}
2018-07-20 23:11:36 +00:00
void K_CheckSpectateStatus ( void )
{
2018-08-09 21:59:52 +00:00
UINT8 respawnlist [ MAXPLAYERS ] ;
2018-07-21 15:45:08 +00:00
UINT8 i , numingame = 0 , numjoiners = 0 ;
2018-07-20 23:11:36 +00:00
2018-07-21 15:45:08 +00:00
// Get the number of players in game, and the players to be de-spectated.
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( ! playeringame [ i ] )
continue ;
2018-07-20 23:11:36 +00:00
2018-07-21 15:45:08 +00:00
if ( ! players [ i ] . spectator )
{
2018-07-20 23:11:36 +00:00
numingame + + ;
2018-07-22 04:31:02 +00:00
if ( gamestate ! = GS_LEVEL ) // Allow if you're not in a level
2018-07-21 19:54:05 +00:00
continue ;
2018-07-22 04:31:02 +00:00
if ( players [ i ] . exiting ) // DON'T allow if anyone's exiting
return ;
if ( numingame < 2 | | leveltime < starttime | | mapreset ) // Allow if the match hasn't started yet
2018-08-09 21:59:52 +00:00
continue ;
2018-07-22 04:31:02 +00:00
if ( G_RaceGametype ( ) & & players [ i ] . laps ) // DON'T allow if the race is at 2 laps
2018-07-20 23:11:36 +00:00
return ;
2018-07-21 15:45:08 +00:00
continue ;
}
else if ( ! ( players [ i ] . pflags & PF_WANTSTOJOIN ) )
continue ;
2018-07-20 23:11:36 +00:00
2018-07-21 15:45:08 +00:00
respawnlist [ numjoiners + + ] = i ;
}
2018-07-20 23:11:36 +00:00
2018-07-21 15:45:08 +00:00
// literally zero point in going any further if nobody is joining
if ( ! numjoiners )
return ;
2018-07-20 23:11:36 +00:00
2018-07-21 19:54:05 +00:00
// Reset the match if you're in an empty server
2018-07-22 04:31:02 +00:00
if ( ! mapreset & & gamestate = = GS_LEVEL & & leveltime > = starttime & & ( numingame < 2 & & numingame + numjoiners > = 2 ) )
2018-07-21 19:54:05 +00:00
{
2018-07-22 04:31:02 +00:00
S_ChangeMusicInternal ( " chalng " , false ) ; // COME ON
mapreset = 3 * TICRATE ; // Even though only the server uses this for game logic, set for everyone for HUD in the future
2018-07-21 19:54:05 +00:00
}
2018-07-20 23:11:36 +00:00
2018-07-21 15:45:08 +00:00
// Finally, we can de-spectate everyone!
for ( i = 0 ; i < numjoiners ; i + + )
P_SpectatorJoinGame ( & players [ respawnlist [ i ] ] ) ;
2018-07-20 23:11:36 +00:00
}
2016-08-15 03:51:08 +00:00
//}
//{ SRB2kart HUD Code
# define NUMPOSNUMS 10
2017-02-17 20:14:55 +00:00
# define NUMPOSFRAMES 7 // White, three blues, three reds
2018-07-12 05:31:33 +00:00
# define NUMWINFRAMES 6 // Red, yellow, green, cyan, blue, purple
2016-08-15 03:51:08 +00:00
//{ Patch Definitions
static patch_t * kp_nodraw ;
2018-02-05 23:55:52 +00:00
2016-08-15 03:51:08 +00:00
static patch_t * kp_timesticker ;
static patch_t * kp_timestickerwide ;
static patch_t * kp_lapsticker ;
static patch_t * kp_lapstickernarrow ;
2017-12-24 00:14:06 +00:00
static patch_t * kp_splitlapflag ;
2018-07-03 19:14:47 +00:00
static patch_t * kp_bumpersticker ;
static patch_t * kp_bumperstickerwide ;
2017-11-14 01:45:57 +00:00
static patch_t * kp_karmasticker ;
2017-12-24 01:55:23 +00:00
static patch_t * kp_splitkarmabomb ;
2017-11-14 01:45:57 +00:00
static patch_t * kp_timeoutsticker ;
2018-02-05 23:55:52 +00:00
2018-06-25 02:15:22 +00:00
static patch_t * kp_startcountdown [ 8 ] ;
2018-07-18 22:20:08 +00:00
static patch_t * kp_racefinish [ 2 ] ;
2018-02-05 23:55:52 +00:00
2016-08-15 03:51:08 +00:00
static patch_t * kp_positionnum [ NUMPOSNUMS ] [ NUMPOSFRAMES ] ;
2017-11-13 03:48:32 +00:00
static patch_t * kp_winnernum [ NUMPOSFRAMES ] ;
2018-02-05 23:55:52 +00:00
2016-08-15 03:51:08 +00:00
static patch_t * kp_facenull ;
static patch_t * kp_facefirst ;
static patch_t * kp_facesecond ;
static patch_t * kp_facethird ;
static patch_t * kp_facefourth ;
2018-02-05 23:55:52 +00:00
2018-07-03 19:14:47 +00:00
static patch_t * kp_rankbumper ;
static patch_t * kp_ranknobumpers ;
2018-02-05 23:55:52 +00:00
2017-11-14 01:45:57 +00:00
static patch_t * kp_battlewin ;
2018-07-18 22:42:34 +00:00
static patch_t * kp_battlecool ;
2017-11-14 01:45:57 +00:00
static patch_t * kp_battlelose ;
static patch_t * kp_battlewait ;
static patch_t * kp_battleinfo ;
2018-07-01 08:36:09 +00:00
static patch_t * kp_wanted ;
2018-02-05 23:55:52 +00:00
2018-06-29 00:54:06 +00:00
static patch_t * kp_itembg [ 4 ] ;
2018-08-12 14:15:55 +00:00
static patch_t * kp_itemtimer [ 2 ] ;
2018-06-29 00:54:06 +00:00
static patch_t * kp_itemmulsticker [ 2 ] ;
2018-02-05 23:55:52 +00:00
static patch_t * kp_itemx ;
2018-06-29 00:54:06 +00:00
static patch_t * kp_sneaker [ 2 ] ;
static patch_t * kp_rocketsneaker [ 2 ] ;
static patch_t * kp_invincibility [ 13 ] ;
static patch_t * kp_banana [ 2 ] ;
static patch_t * kp_eggman [ 2 ] ;
2018-08-10 02:52:22 +00:00
static patch_t * kp_orbinaut [ 5 ] ;
2018-06-29 00:54:06 +00:00
static patch_t * kp_jawz [ 2 ] ;
static patch_t * kp_mine [ 2 ] ;
static patch_t * kp_ballhog [ 2 ] ;
static patch_t * kp_selfpropelledbomb [ 2 ] ;
static patch_t * kp_grow [ 2 ] ;
static patch_t * kp_shrink [ 2 ] ;
2018-08-04 19:48:31 +00:00
static patch_t * kp_thundershield [ 2 ] ;
2018-06-29 00:54:06 +00:00
static patch_t * kp_hyudoro [ 2 ] ;
static patch_t * kp_pogospring [ 2 ] ;
static patch_t * kp_kitchensink [ 2 ] ;
static patch_t * kp_sadface [ 2 ] ;
2018-02-05 23:55:52 +00:00
2018-02-10 06:19:33 +00:00
static patch_t * kp_check [ 6 ] ;
2016-08-15 03:51:08 +00:00
2018-06-07 23:39:45 +00:00
static patch_t * kp_spbwarning [ 2 ] ;
2018-08-12 14:15:55 +00:00
static patch_t * kp_eggnum [ 4 ] ;
2016-08-15 03:51:08 +00:00
2018-06-26 20:12:42 +00:00
static patch_t * kp_fpview [ 3 ] ;
2018-07-15 22:13:36 +00:00
static patch_t * kp_inputwheel [ 5 ] ;
2018-06-26 20:12:42 +00:00
2018-07-22 04:31:02 +00:00
static patch_t * kp_challenger [ 25 ] ;
2018-08-10 01:52:02 +00:00
static patch_t * kp_lapanim_lap [ 7 ] ;
static patch_t * kp_lapanim_final [ 11 ] ;
static patch_t * kp_lapanim_number [ 10 ] [ 3 ] ;
static patch_t * kp_lapanim_emblem ;
2016-08-15 03:51:08 +00:00
void K_LoadKartHUDGraphics ( void )
{
INT32 i , j ;
char buffer [ 9 ] ;
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
// Null Stuff
kp_nodraw = W_CachePatchName ( " K_TRNULL " , PU_HUDGFX ) ;
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
// Stickers
kp_timesticker = W_CachePatchName ( " K_STTIME " , PU_HUDGFX ) ;
kp_timestickerwide = W_CachePatchName ( " K_STTIMW " , PU_HUDGFX ) ;
kp_lapsticker = W_CachePatchName ( " K_STLAPS " , PU_HUDGFX ) ;
kp_lapstickernarrow = W_CachePatchName ( " K_STLAPN " , PU_HUDGFX ) ;
2017-12-24 00:14:06 +00:00
kp_splitlapflag = W_CachePatchName ( " K_SPTLAP " , PU_HUDGFX ) ;
2018-07-18 22:20:08 +00:00
kp_bumpersticker = W_CachePatchName ( " K_STBALN " , PU_HUDGFX ) ;
kp_bumperstickerwide = W_CachePatchName ( " K_STBALW " , PU_HUDGFX ) ;
2017-11-14 01:45:57 +00:00
kp_karmasticker = W_CachePatchName ( " K_STKARM " , PU_HUDGFX ) ;
2017-12-24 01:55:23 +00:00
kp_splitkarmabomb = W_CachePatchName ( " K_SPTKRM " , PU_HUDGFX ) ;
2017-11-14 01:45:57 +00:00
kp_timeoutsticker = W_CachePatchName ( " K_STTOUT " , PU_HUDGFX ) ;
2017-02-17 20:14:55 +00:00
2018-06-25 02:15:22 +00:00
// Starting countdown
kp_startcountdown [ 0 ] = W_CachePatchName ( " K_CNT3A " , PU_HUDGFX ) ;
kp_startcountdown [ 1 ] = W_CachePatchName ( " K_CNT2A " , PU_HUDGFX ) ;
kp_startcountdown [ 2 ] = W_CachePatchName ( " K_CNT1A " , PU_HUDGFX ) ;
kp_startcountdown [ 3 ] = W_CachePatchName ( " K_CNTGOA " , PU_HUDGFX ) ;
kp_startcountdown [ 4 ] = W_CachePatchName ( " K_CNT3B " , PU_HUDGFX ) ;
kp_startcountdown [ 5 ] = W_CachePatchName ( " K_CNT2B " , PU_HUDGFX ) ;
kp_startcountdown [ 6 ] = W_CachePatchName ( " K_CNT1B " , PU_HUDGFX ) ;
kp_startcountdown [ 7 ] = W_CachePatchName ( " K_CNTGOB " , PU_HUDGFX ) ;
2017-06-03 22:19:06 +00:00
2018-07-18 22:20:08 +00:00
kp_racefinish [ 0 ] = W_CachePatchName ( " K_FINA " , PU_HUDGFX ) ;
kp_racefinish [ 1 ] = W_CachePatchName ( " K_FINB " , PU_HUDGFX ) ;
2016-08-15 03:51:08 +00:00
// Position numbers
2018-07-07 22:49:34 +00:00
sprintf ( buffer , " K_POSNxx " ) ;
2016-08-15 03:51:08 +00:00
for ( i = 0 ; i < NUMPOSNUMS ; i + + )
{
2018-07-07 22:49:34 +00:00
buffer [ 6 ] = ' 0 ' + i ;
2016-08-15 03:51:08 +00:00
for ( j = 0 ; j < NUMPOSFRAMES ; j + + )
{
2018-07-07 22:49:34 +00:00
//sprintf(buffer, "K_POSN%d%d", i, j);
buffer [ 7 ] = ' 0 ' + j ;
2016-08-15 03:51:08 +00:00
kp_positionnum [ i ] [ j ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2016-08-12 01:42:11 +00:00
}
2017-11-13 03:48:32 +00:00
2018-07-15 22:13:36 +00:00
sprintf ( buffer , " K_POSNWx " ) ;
2018-07-12 05:31:33 +00:00
for ( i = 0 ; i < NUMWINFRAMES ; i + + )
2017-11-13 03:48:32 +00:00
{
2018-07-15 22:13:36 +00:00
buffer [ 7 ] = ' 0 ' + i ;
2017-11-13 03:48:32 +00:00
kp_winnernum [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2016-08-15 03:51:08 +00:00
kp_facenull = W_CachePatchName ( " K_PFACE0 " , PU_HUDGFX ) ;
kp_facefirst = W_CachePatchName ( " K_PFACE1 " , PU_HUDGFX ) ;
kp_facesecond = W_CachePatchName ( " K_PFACE2 " , PU_HUDGFX ) ;
kp_facethird = W_CachePatchName ( " K_PFACE3 " , PU_HUDGFX ) ;
kp_facefourth = W_CachePatchName ( " K_PFACE4 " , PU_HUDGFX ) ;
2017-02-17 20:14:55 +00:00
2018-02-05 23:55:52 +00:00
// Extra ranking icons
2018-07-18 19:23:46 +00:00
kp_rankbumper = W_CachePatchName ( " K_BLNICO " , PU_HUDGFX ) ;
2018-07-03 19:14:47 +00:00
kp_ranknobumpers = W_CachePatchName ( " K_NOBLNS " , PU_HUDGFX ) ;
2018-02-05 23:55:52 +00:00
2017-11-14 01:45:57 +00:00
// Battle graphics
kp_battlewin = W_CachePatchName ( " K_BWIN " , PU_HUDGFX ) ;
2018-07-18 22:42:34 +00:00
kp_battlecool = W_CachePatchName ( " K_BCOOL " , PU_HUDGFX ) ;
2017-11-14 01:45:57 +00:00
kp_battlelose = W_CachePatchName ( " K_BLOSE " , PU_HUDGFX ) ;
kp_battlewait = W_CachePatchName ( " K_BWAIT " , PU_HUDGFX ) ;
kp_battleinfo = W_CachePatchName ( " K_BINFO " , PU_HUDGFX ) ;
2018-07-01 08:36:09 +00:00
kp_wanted = W_CachePatchName ( " K_WANTED " , PU_HUDGFX ) ;
2017-11-14 01:45:57 +00:00
2016-08-15 03:51:08 +00:00
// Kart Item Windows
2018-06-29 00:54:06 +00:00
kp_itembg [ 0 ] = W_CachePatchName ( " K_ITBG " , PU_HUDGFX ) ;
kp_itembg [ 1 ] = W_CachePatchName ( " K_ITBGD " , PU_HUDGFX ) ;
2018-08-12 14:15:55 +00:00
kp_itemtimer [ 0 ] = W_CachePatchName ( " K_ITIMER " , PU_HUDGFX ) ;
2018-06-29 00:54:06 +00:00
kp_itemmulsticker [ 0 ] = W_CachePatchName ( " K_ITMUL " , PU_HUDGFX ) ;
2018-02-05 23:55:52 +00:00
kp_itemx = W_CachePatchName ( " K_ITX " , PU_HUDGFX ) ;
2018-06-29 00:54:06 +00:00
kp_sneaker [ 0 ] = W_CachePatchName ( " K_ITSHOE " , PU_HUDGFX ) ;
kp_rocketsneaker [ 0 ] = W_CachePatchName ( " K_ITRSHE " , PU_HUDGFX ) ;
2018-07-15 22:13:36 +00:00
sprintf ( buffer , " K_ITINVx " ) ;
2018-02-05 23:55:52 +00:00
for ( i = 0 ; i < 7 ; i + + )
{
2018-07-15 22:13:36 +00:00
buffer [ 7 ] = ' 1 ' + i ;
2018-02-05 23:55:52 +00:00
kp_invincibility [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2018-06-29 00:54:06 +00:00
kp_banana [ 0 ] = W_CachePatchName ( " K_ITBANA " , PU_HUDGFX ) ;
kp_eggman [ 0 ] = W_CachePatchName ( " K_ITEGGM " , PU_HUDGFX ) ;
2018-08-10 02:52:22 +00:00
sprintf ( buffer , " K_ITORBx " ) ;
for ( i = 0 ; i < 4 ; i + + )
{
buffer [ 7 ] = ' 1 ' + i ;
kp_orbinaut [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2018-06-29 00:54:06 +00:00
kp_jawz [ 0 ] = W_CachePatchName ( " K_ITJAWZ " , PU_HUDGFX ) ;
kp_mine [ 0 ] = W_CachePatchName ( " K_ITMINE " , PU_HUDGFX ) ;
kp_ballhog [ 0 ] = W_CachePatchName ( " K_ITBHOG " , PU_HUDGFX ) ;
kp_selfpropelledbomb [ 0 ] = W_CachePatchName ( " K_ITSPB " , PU_HUDGFX ) ;
kp_grow [ 0 ] = W_CachePatchName ( " K_ITGROW " , PU_HUDGFX ) ;
kp_shrink [ 0 ] = W_CachePatchName ( " K_ITSHRK " , PU_HUDGFX ) ;
2018-08-04 19:48:31 +00:00
kp_thundershield [ 0 ] = W_CachePatchName ( " K_ITTHNS " , PU_HUDGFX ) ;
2018-06-29 00:54:06 +00:00
kp_hyudoro [ 0 ] = W_CachePatchName ( " K_ITHYUD " , PU_HUDGFX ) ;
kp_pogospring [ 0 ] = W_CachePatchName ( " K_ITPOGO " , PU_HUDGFX ) ;
kp_kitchensink [ 0 ] = W_CachePatchName ( " K_ITSINK " , PU_HUDGFX ) ;
kp_sadface [ 0 ] = W_CachePatchName ( " K_ITSAD " , PU_HUDGFX ) ;
// Splitscreen
kp_itembg [ 2 ] = W_CachePatchName ( " K_ISBG " , PU_HUDGFX ) ;
kp_itembg [ 3 ] = W_CachePatchName ( " K_ISBGD " , PU_HUDGFX ) ;
2018-08-12 14:15:55 +00:00
kp_itemtimer [ 1 ] = W_CachePatchName ( " K_ISIMER " , PU_HUDGFX ) ;
2018-06-29 00:54:06 +00:00
kp_itemmulsticker [ 1 ] = W_CachePatchName ( " K_ISMUL " , PU_HUDGFX ) ;
kp_sneaker [ 1 ] = W_CachePatchName ( " K_ISSHOE " , PU_HUDGFX ) ;
kp_rocketsneaker [ 1 ] = W_CachePatchName ( " K_ISRSHE " , PU_HUDGFX ) ;
2018-07-15 22:13:36 +00:00
sprintf ( buffer , " K_ISINVx " ) ;
2018-06-29 00:54:06 +00:00
for ( i = 0 ; i < 6 ; i + + )
{
2018-07-15 22:13:36 +00:00
buffer [ 7 ] = ' 1 ' + i ;
2018-06-29 00:54:06 +00:00
kp_invincibility [ i + 7 ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
kp_banana [ 1 ] = W_CachePatchName ( " K_ISBANA " , PU_HUDGFX ) ;
kp_eggman [ 1 ] = W_CachePatchName ( " K_ISEGGM " , PU_HUDGFX ) ;
2018-08-10 02:52:22 +00:00
kp_orbinaut [ 4 ] = W_CachePatchName ( " K_ISORBN " , PU_HUDGFX ) ;
2018-06-29 00:54:06 +00:00
kp_jawz [ 1 ] = W_CachePatchName ( " K_ISJAWZ " , PU_HUDGFX ) ;
kp_mine [ 1 ] = W_CachePatchName ( " K_ISMINE " , PU_HUDGFX ) ;
kp_ballhog [ 1 ] = W_CachePatchName ( " K_ISBHOG " , PU_HUDGFX ) ;
kp_selfpropelledbomb [ 1 ] = W_CachePatchName ( " K_ISSPB " , PU_HUDGFX ) ;
kp_grow [ 1 ] = W_CachePatchName ( " K_ISGROW " , PU_HUDGFX ) ;
kp_shrink [ 1 ] = W_CachePatchName ( " K_ISSHRK " , PU_HUDGFX ) ;
2018-08-04 19:48:31 +00:00
kp_thundershield [ 1 ] = W_CachePatchName ( " K_ISTHNS " , PU_HUDGFX ) ;
2018-06-29 00:54:06 +00:00
kp_hyudoro [ 1 ] = W_CachePatchName ( " K_ISHYUD " , PU_HUDGFX ) ;
kp_pogospring [ 1 ] = W_CachePatchName ( " K_ISPOGO " , PU_HUDGFX ) ;
kp_kitchensink [ 1 ] = W_CachePatchName ( " K_ISSINK " , PU_HUDGFX ) ;
kp_sadface [ 1 ] = W_CachePatchName ( " K_ISSAD " , PU_HUDGFX ) ;
2016-08-15 03:51:08 +00:00
2017-11-02 04:35:10 +00:00
// CHECK indicators
2018-07-15 22:13:36 +00:00
sprintf ( buffer , " K_CHECKx " ) ;
2018-02-10 06:19:33 +00:00
for ( i = 0 ; i < 6 ; i + + )
{
2018-07-15 22:13:36 +00:00
buffer [ 7 ] = ' 1 ' + i ;
2018-02-10 06:19:33 +00:00
kp_check [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2018-06-06 01:36:48 +00:00
2018-06-07 23:39:45 +00:00
// SPB warning
kp_spbwarning [ 0 ] = W_CachePatchName ( " K_SPBW1 " , PU_HUDGFX ) ;
kp_spbwarning [ 1 ] = W_CachePatchName ( " K_SPBW2 " , PU_HUDGFX ) ;
2018-06-26 20:12:42 +00:00
2018-08-12 14:15:55 +00:00
// Eggman warning numbers
sprintf ( buffer , " K_EGGNx " ) ;
for ( i = 0 ; i < 4 ; i + + )
{
buffer [ 6 ] = ' 0 ' + i ;
kp_eggnum [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2018-06-26 20:12:42 +00:00
// First person mode
kp_fpview [ 0 ] = W_CachePatchName ( " VIEWA0 " , PU_HUDGFX ) ;
kp_fpview [ 1 ] = W_CachePatchName ( " VIEWB0D0 " , PU_HUDGFX ) ;
kp_fpview [ 2 ] = W_CachePatchName ( " VIEWC0E0 " , PU_HUDGFX ) ;
2018-07-15 22:13:36 +00:00
// Input UI Wheel
sprintf ( buffer , " K_WHEELx " ) ;
for ( i = 0 ; i < 5 ; i + + )
{
buffer [ 7 ] = ' 0 ' + i ;
kp_inputwheel [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2018-07-22 04:31:02 +00:00
// HERE COMES A NEW CHALLENGER
sprintf ( buffer , " K_CHALxx " ) ;
for ( i = 0 ; i < 25 ; i + + )
{
buffer [ 6 ] = ' 0 ' + ( ( i + 1 ) / 10 ) ;
buffer [ 7 ] = ' 0 ' + ( ( i + 1 ) % 10 ) ;
kp_challenger [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
2018-08-10 01:52:02 +00:00
// Lap start animation
sprintf ( buffer , " K_LAP0x " ) ;
for ( i = 0 ; i < 7 ; i + + )
{
buffer [ 6 ] = ' 0 ' + ( i + 1 ) ;
kp_lapanim_lap [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
sprintf ( buffer , " K_LAPFxx " ) ;
for ( i = 0 ; i < 11 ; i + + )
{
buffer [ 6 ] = ' 0 ' + ( ( i + 1 ) / 10 ) ;
buffer [ 7 ] = ' 0 ' + ( ( i + 1 ) % 10 ) ;
kp_lapanim_final [ i ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
sprintf ( buffer , " K_LAPNxx " ) ;
for ( i = 0 ; i < 10 ; i + + )
{
buffer [ 6 ] = ' 0 ' + i ;
for ( j = 0 ; j < 3 ; j + + )
{
buffer [ 7 ] = ' 0 ' + ( j + 1 ) ;
kp_lapanim_number [ i ] [ j ] = ( patch_t * ) W_CachePatchName ( buffer , PU_HUDGFX ) ;
}
}
kp_lapanim_emblem = ( patch_t * ) W_CachePatchName ( " K_LAPE00 " , PU_HUDGFX ) ;
2016-08-12 01:42:11 +00:00
}
2018-08-31 17:18:19 +00:00
// For the item toggle menu
const char * K_GetItemPatch ( UINT8 item , boolean small )
{
switch ( item )
{
case KITEM_SNEAKER :
case KRITEM_TRIPLESNEAKER :
return ( small ? " K_ISSHOE " : " K_ITSHOE " ) ;
case KITEM_ROCKETSNEAKER :
return ( small ? " K_ISRSHE " : " K_ITRSHE " ) ;
case KITEM_INVINCIBILITY :
return ( small ? " K_ISINV1 " : " K_ITINV1 " ) ;
case KITEM_BANANA :
case KRITEM_TRIPLEBANANA :
case KRITEM_TENFOLDBANANA :
return ( small ? " K_ISBANA " : " K_ITBANA " ) ;
case KITEM_EGGMAN :
return ( small ? " K_ISEGGM " : " K_ITEGGM " ) ;
case KITEM_ORBINAUT :
return ( small ? " K_ISORBN " : " K_ITORB1 " ) ;
case KITEM_JAWZ :
case KRITEM_DUALJAWZ :
return ( small ? " K_ISJAWZ " : " K_ITJAWZ " ) ;
case KITEM_MINE :
return ( small ? " K_ISMINE " : " K_ITMINE " ) ;
case KITEM_BALLHOG :
return ( small ? " K_ISBHOG " : " K_ITBHOG " ) ;
case KITEM_SPB :
return ( small ? " K_ISSPB " : " K_ITSPB " ) ;
case KITEM_GROW :
return ( small ? " K_ISGROW " : " K_ITGROW " ) ;
case KITEM_SHRINK :
return ( small ? " K_ISSHRK " : " K_ITSHRK " ) ;
case KITEM_THUNDERSHIELD :
return ( small ? " K_ISTHNS " : " K_ITTHNS " ) ;
case KITEM_HYUDORO :
return ( small ? " K_ISHYUD " : " K_ITHYUD " ) ;
case KITEM_POGOSPRING :
return ( small ? " K_ISPOGO " : " K_ITPOGO " ) ;
case KITEM_KITCHENSINK :
return ( small ? " K_ISSINK " : " K_ITSINK " ) ;
case KRITEM_TRIPLEORBINAUT :
return ( small ? " K_ISORBN " : " K_ITORB3 " ) ;
case KRITEM_QUADORBINAUT :
return ( small ? " K_ISORBN " : " K_ITORB4 " ) ;
default :
return ( small ? " K_ISSAD " : " K_ITSAD " ) ;
}
}
2016-08-12 01:42:11 +00:00
//}
2016-08-15 03:51:08 +00:00
INT32 ITEM_X , ITEM_Y ; // Item Window
INT32 TIME_X , TIME_Y ; // Time Sticker
INT32 LAPS_X , LAPS_Y ; // Lap Sticker
2017-12-22 15:16:41 +00:00
INT32 SPDM_X , SPDM_Y ; // Speedometer
2016-08-15 03:51:08 +00:00
INT32 POSI_X , POSI_Y ; // Position Number
INT32 FACE_X , FACE_Y ; // Top-four Faces
2018-06-25 02:15:22 +00:00
INT32 STCD_X , STCD_Y ; // Starting countdown
2017-11-06 22:31:52 +00:00
INT32 CHEK_Y ; // CHECK graphic
2017-12-19 06:55:33 +00:00
INT32 MINI_X , MINI_Y ; // Minimap
2018-06-07 23:39:45 +00:00
INT32 SPBW_X , SPBW_Y ; // SPB warning
2018-07-01 08:36:09 +00:00
INT32 WANT_X , WANT_Y ; // Battle WANTED poster
2016-08-15 03:51:08 +00:00
static void K_initKartHUD ( void )
{
/*
BASEVIDWIDTH = 320
BASEVIDHEIGHT = 200
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
Item window graphic is 41 x 33
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
Time Sticker graphic is 116 x 11
Time Font is a solid block of ( 8 x [ 12 ) x 14 ] , equal to 96 x 14
Therefore , timestamp is 116 x 14 altogether
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
Lap Sticker is 80 x 11
Lap flag is 22 x 20
Lap Font is a solid block of ( 3 x [ 12 ) x 14 ] , equal to 36 x 14
Therefore , lapstamp is 80 x 20 altogether
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
Position numbers are 43 x 53
2017-02-17 20:14:55 +00:00
Faces are 32 x 32
2016-08-15 03:51:08 +00:00
Faces draw downscaled at 16 x 16
Therefore , the allocated space for them is 16 x 67 altogether
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
- - - -
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
ORIGINAL CZ64 SPLITSCREEN :
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
Item window :
if ( ! splitscreen ) { ICONX = 139 ; ICONY = 20 ; }
else { ICONX = BASEVIDWIDTH - 315 ; ICONY = 60 ; }
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
Time : 236 , STRINGY ( 12 )
Lap : BASEVIDWIDTH - 304 , STRINGY ( BASEVIDHEIGHT - 189 )
2017-02-17 20:14:55 +00:00
*/
2017-12-18 01:42:17 +00:00
// Single Screen (defaults)
// Item Window
2018-02-05 23:55:52 +00:00
ITEM_X = 5 ; // 5
ITEM_Y = 5 ; // 5
2017-12-18 01:42:17 +00:00
// Level Timer
2018-02-05 23:55:52 +00:00
TIME_X = BASEVIDWIDTH - 148 ; // 172
TIME_Y = 9 ; // 9
2017-12-18 01:42:17 +00:00
// Level Laps
2018-02-05 23:55:52 +00:00
LAPS_X = 9 ; // 9
LAPS_Y = BASEVIDHEIGHT - 29 ; // 171
2017-12-18 01:42:17 +00:00
// Speedometer
2018-02-05 23:55:52 +00:00
SPDM_X = 9 ; // 9
SPDM_Y = BASEVIDHEIGHT - 45 ; // 155
2017-12-18 01:42:17 +00:00
// Position Number
2018-02-08 03:33:27 +00:00
POSI_X = BASEVIDWIDTH - 9 ; // 268
POSI_Y = BASEVIDHEIGHT - 9 ; // 138
2017-12-18 01:42:17 +00:00
// Top-Four Faces
2018-02-05 23:55:52 +00:00
FACE_X = 9 ; // 9
FACE_Y = 92 ; // 92
2018-06-25 02:15:22 +00:00
// Starting countdown
STCD_X = BASEVIDWIDTH / 2 ; // 9
STCD_Y = BASEVIDHEIGHT / 2 ; // 92
2017-12-18 01:42:17 +00:00
// CHECK graphic
2018-02-05 23:55:52 +00:00
CHEK_Y = BASEVIDHEIGHT ; // 200
2017-12-19 06:55:33 +00:00
// Minimap
2018-02-06 00:08:49 +00:00
MINI_X = BASEVIDWIDTH - 50 ; // 270
2018-02-08 03:33:27 +00:00
MINI_Y = ( BASEVIDHEIGHT / 2 ) - 16 ; // 84
2018-06-06 01:36:48 +00:00
// Blue Shell warning
2018-07-01 08:36:09 +00:00
SPBW_X = BASEVIDWIDTH / 2 ; // 270
SPBW_Y = BASEVIDHEIGHT - 24 ; // 176
// Battle WANTED poster
2018-07-01 18:11:48 +00:00
WANT_X = BASEVIDWIDTH - 55 ; // 270
WANT_Y = BASEVIDHEIGHT - 71 ; // 176
2017-12-18 01:42:17 +00:00
2017-12-19 01:59:04 +00:00
if ( splitscreen ) // Splitscreen
2016-08-15 03:51:08 +00:00
{
2018-02-05 23:55:52 +00:00
ITEM_X = 5 ;
2018-06-29 00:54:06 +00:00
ITEM_Y = 3 ;
2017-02-17 20:14:55 +00:00
2017-12-18 01:42:17 +00:00
LAPS_Y = ( BASEVIDHEIGHT / 2 ) - 24 ;
2017-02-17 20:14:55 +00:00
2017-12-19 06:55:33 +00:00
POSI_Y = ( BASEVIDHEIGHT / 2 ) - 2 ;
2018-06-25 02:15:22 +00:00
STCD_Y = BASEVIDHEIGHT / 4 ;
2017-12-19 06:55:33 +00:00
MINI_Y = ( BASEVIDHEIGHT / 2 ) ;
2017-02-17 20:14:55 +00:00
2018-06-07 23:39:45 +00:00
SPBW_Y = ( BASEVIDHEIGHT / 2 ) - 8 ;
2018-06-06 01:36:48 +00:00
2018-07-01 08:36:09 +00:00
WANT_X = BASEVIDWIDTH - 8 ;
WANT_Y = ( BASEVIDHEIGHT / 2 ) - 12 ;
2017-12-19 01:59:04 +00:00
if ( splitscreen > 1 ) // 3P/4P Small Splitscreen
2017-12-18 01:42:17 +00:00
{
2018-06-29 00:54:06 +00:00
ITEM_X = - 9 ;
ITEM_Y = - 8 ;
2017-02-17 20:14:55 +00:00
2017-12-24 00:14:06 +00:00
LAPS_X = 3 ;
LAPS_Y = ( BASEVIDHEIGHT / 2 ) - 13 ;
2017-11-06 22:31:52 +00:00
2017-12-24 00:14:06 +00:00
POSI_X = ( BASEVIDWIDTH / 2 ) - 3 ;
2017-12-19 06:55:33 +00:00
2018-06-25 02:15:22 +00:00
STCD_X = BASEVIDWIDTH / 4 ;
2017-12-19 06:55:33 +00:00
MINI_X = ( 3 * BASEVIDWIDTH / 4 ) ;
MINI_Y = ( 3 * BASEVIDHEIGHT / 4 ) ;
2018-06-07 23:39:45 +00:00
SPBW_X = BASEVIDWIDTH / 4 ;
2018-06-06 01:36:48 +00:00
2018-07-01 08:36:09 +00:00
WANT_X = ( BASEVIDWIDTH / 2 ) - 8 ;
2017-12-27 02:36:03 +00:00
if ( splitscreen > 2 ) // 4P-only
2017-12-19 06:55:33 +00:00
{
MINI_X = ( BASEVIDWIDTH / 2 ) ;
MINI_Y = ( BASEVIDHEIGHT / 2 ) ;
}
2017-12-18 01:42:17 +00:00
}
2016-08-15 03:51:08 +00:00
}
2018-06-28 18:07:04 +00:00
if ( timeinmap > 113 )
hudtrans = cv_translucenthud . value ;
else if ( timeinmap > 105 )
hudtrans = ( ( ( ( INT32 ) timeinmap ) - 105 ) * cv_translucenthud . value ) / ( 113 - 105 ) ;
else
hudtrans = 0 ;
2016-08-15 03:51:08 +00:00
}
2017-12-25 15:05:36 +00:00
INT32 K_calcSplitFlags ( INT32 snapflags )
2016-08-15 03:51:08 +00:00
{
2017-12-19 01:59:04 +00:00
INT32 splitflags = 0 ;
2017-02-17 20:14:55 +00:00
2017-12-24 14:19:59 +00:00
if ( splitscreen = = 0 )
2017-12-19 01:59:04 +00:00
return snapflags ;
2017-02-17 20:14:55 +00:00
2017-12-18 06:02:53 +00:00
if ( stplyr ! = & players [ displayplayer ] )
2017-12-18 01:42:17 +00:00
{
2017-12-19 01:59:04 +00:00
if ( splitscreen = = 1 & & stplyr = = & players [ secondarydisplayplayer ] )
2017-12-24 14:19:59 +00:00
{
2017-12-18 01:42:17 +00:00
splitflags | = V_SPLITSCREEN ;
2017-12-24 14:19:59 +00:00
}
2017-12-19 01:59:04 +00:00
else if ( splitscreen > 1 )
2017-12-18 06:02:53 +00:00
{
if ( stplyr = = & players [ thirddisplayplayer ] | | stplyr = = & players [ fourthdisplayplayer ] )
splitflags | = V_SPLITSCREEN ;
if ( stplyr = = & players [ secondarydisplayplayer ] | | stplyr = = & players [ fourthdisplayplayer ] )
splitflags | = V_HORZSCREEN ;
}
2017-12-18 01:42:17 +00:00
}
2017-12-19 01:59:04 +00:00
if ( splitflags & V_SPLITSCREEN )
snapflags & = ~ V_SNAPTOTOP ;
else
snapflags & = ~ V_SNAPTOBOTTOM ;
2017-12-24 14:19:59 +00:00
if ( splitscreen > 1 )
{
if ( splitflags & V_HORZSCREEN )
snapflags & = ~ V_SNAPTOLEFT ;
else
snapflags & = ~ V_SNAPTORIGHT ;
}
2017-12-19 01:59:04 +00:00
return ( splitflags | snapflags ) ;
}
2018-02-05 23:55:52 +00:00
static void K_drawKartItem ( void )
2016-08-15 03:51:08 +00:00
{
// ITEM_X = BASEVIDWIDTH-50; // 270
// ITEM_Y = 24; // 24
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
// Why write V_DrawScaledPatch calls over and over when they're all the same?
// Set to 'no item' just in case.
2018-06-29 00:54:06 +00:00
const UINT8 offset = ( ( splitscreen > 1 ) ? 1 : 0 ) ;
2016-08-15 03:51:08 +00:00
patch_t * localpatch = kp_nodraw ;
2018-08-14 21:16:33 +00:00
patch_t * localbg = ( ( offset ) ? kp_itembg [ 2 ] : kp_itembg [ 0 ] ) ;
patch_t * localinv = ( ( offset ) ? kp_invincibility [ ( ( leveltime % ( 6 * 3 ) ) / 3 ) + 7 ] : kp_invincibility [ ( leveltime % ( 7 * 3 ) ) / 3 ] ) ;
2018-06-07 23:39:45 +00:00
INT32 splitflags = K_calcSplitFlags ( V_SNAPTOTOP | V_SNAPTOLEFT ) ;
2018-08-14 21:16:33 +00:00
const INT32 numberdisplaymin = ( ( ! offset & & stplyr - > kartstuff [ k_itemtype ] = = KITEM_ORBINAUT ) ? 5 : 2 ) ;
2018-08-14 14:23:38 +00:00
INT32 itembar = 0 ;
2017-12-24 14:19:59 +00:00
2018-02-05 23:55:52 +00:00
if ( stplyr - > kartstuff [ k_itemroulette ] )
2017-12-24 14:19:59 +00:00
{
2018-02-05 23:55:52 +00:00
switch ( ( stplyr - > kartstuff [ k_itemroulette ] % ( 13 * 3 ) ) / 3 )
2016-08-15 03:51:08 +00:00
{
// Each case is handled in threes, to give three frames of in-game time to see the item on the roulette
2018-08-10 02:52:22 +00:00
case 0 : localpatch = kp_sneaker [ offset ] ; break ; // Sneaker
case 1 : localpatch = kp_banana [ offset ] ; break ; // Banana
case 2 : localpatch = kp_orbinaut [ 3 + offset ] ; break ; // Orbinaut
case 3 : localpatch = kp_mine [ offset ] ; break ; // Mine
case 4 : localpatch = kp_grow [ offset ] ; break ; // Grow
case 5 : localpatch = kp_hyudoro [ offset ] ; break ; // Hyudoro
case 6 : localpatch = kp_rocketsneaker [ offset ] ; break ; // Rocket Sneaker
case 7 : localpatch = kp_jawz [ offset ] ; break ; // Jawz
case 8 : localpatch = kp_selfpropelledbomb [ offset ] ; break ; // Self-Propelled Bomb
case 9 : localpatch = kp_shrink [ offset ] ; break ; // Shrink
case 10 : localpatch = localinv ; break ; // Invincibility
case 11 : localpatch = kp_eggman [ offset ] ; break ; // Eggman Monitor
case 12 : localpatch = kp_ballhog [ offset ] ; break ; // Ballhog
case 13 : localpatch = kp_thundershield [ offset ] ; break ; // Thunder Shield
//case 14: localpatch = kp_pogospring[offset]; break; // Pogo Spring
//case 15: localpatch = kp_kitchensink[offset]; break; // Kitchen Sink
2017-02-17 20:14:55 +00:00
default : break ;
2016-08-15 03:51:08 +00:00
}
2018-02-05 23:55:52 +00:00
}
else
{
// I'm doing this a little weird and drawing mostly in reverse order
// The only actual reason is to make sneakers line up this way in the code below
// This shouldn't have any actual baring over how it functions
// Hyudoro is first, because we're drawing it on top of the player's current item
2018-06-19 02:43:23 +00:00
if ( stplyr - > kartstuff [ k_stolentimer ] > 0 )
2016-08-15 03:51:08 +00:00
{
2018-02-05 23:55:52 +00:00
if ( leveltime & 2 )
2018-06-29 00:54:06 +00:00
localpatch = kp_hyudoro [ offset ] ;
2018-08-24 14:14:18 +00:00
else
2018-02-05 23:55:52 +00:00
localpatch = kp_nodraw ;
}
2018-06-19 02:43:23 +00:00
else if ( ( stplyr - > kartstuff [ k_stealingtimer ] > 0 ) & & ( leveltime & 2 ) )
{
2018-06-29 00:54:06 +00:00
localpatch = kp_hyudoro [ offset ] ;
2018-06-19 02:43:23 +00:00
}
2018-08-12 00:19:09 +00:00
else if ( stplyr - > kartstuff [ k_eggmanexplode ] > 1 )
{
if ( leveltime & 1 )
localpatch = kp_eggman [ offset ] ;
2018-08-24 14:14:18 +00:00
else
2018-08-12 00:19:09 +00:00
localpatch = kp_nodraw ;
}
2018-02-05 23:55:52 +00:00
else if ( stplyr - > kartstuff [ k_rocketsneakertimer ] > 1 )
{
2018-08-14 14:23:38 +00:00
itembar = stplyr - > kartstuff [ k_rocketsneakertimer ] ;
2018-02-05 23:55:52 +00:00
if ( leveltime & 1 )
2018-06-29 00:54:06 +00:00
localpatch = kp_rocketsneaker [ offset ] ;
2018-08-24 14:14:18 +00:00
else
2018-02-05 23:55:52 +00:00
localpatch = kp_nodraw ;
}
else if ( stplyr - > kartstuff [ k_growshrinktimer ] > 1 )
{
if ( leveltime & 1 )
2018-06-29 00:54:06 +00:00
localpatch = kp_grow [ offset ] ;
2018-08-24 14:14:18 +00:00
else
2018-02-05 23:55:52 +00:00
localpatch = kp_nodraw ;
}
else if ( stplyr - > kartstuff [ k_sadtimer ] > 0 )
{
if ( leveltime & 2 )
2018-06-29 00:54:06 +00:00
localpatch = kp_sadface [ offset ] ;
2018-08-24 14:14:18 +00:00
else
2018-02-05 23:55:52 +00:00
localpatch = kp_nodraw ;
2016-08-15 03:51:08 +00:00
}
2018-02-05 23:55:52 +00:00
else
{
2018-08-24 14:14:18 +00:00
if ( stplyr - > kartstuff [ k_itemamount ] < = 0 )
2018-02-05 23:55:52 +00:00
return ;
2017-02-17 20:14:55 +00:00
2018-02-05 23:55:52 +00:00
switch ( stplyr - > kartstuff [ k_itemtype ] )
{
2018-06-29 00:54:06 +00:00
case KITEM_SNEAKER : localpatch = kp_sneaker [ offset ] ; break ;
case KITEM_ROCKETSNEAKER : localpatch = kp_rocketsneaker [ offset ] ; break ;
case KITEM_INVINCIBILITY : localpatch = localinv ; localbg = kp_itembg [ offset + 1 ] ; break ;
case KITEM_BANANA : localpatch = kp_banana [ offset ] ; break ;
case KITEM_EGGMAN : localpatch = kp_eggman [ offset ] ; break ;
2018-08-10 02:52:22 +00:00
case KITEM_ORBINAUT :
2018-08-14 21:16:33 +00:00
localpatch = kp_orbinaut [ ( offset ? 4
2018-08-10 02:52:22 +00:00
: min ( stplyr - > kartstuff [ k_itemamount ] - 1 , 3 ) ) ] ;
break ;
2018-06-29 00:54:06 +00:00
case KITEM_JAWZ : localpatch = kp_jawz [ offset ] ; break ;
case KITEM_MINE : localpatch = kp_mine [ offset ] ; break ;
case KITEM_BALLHOG : localpatch = kp_ballhog [ offset ] ; break ;
case KITEM_SPB : localpatch = kp_selfpropelledbomb [ offset ] ; break ;
case KITEM_GROW : localpatch = kp_grow [ offset ] ; break ;
case KITEM_SHRINK : localpatch = kp_shrink [ offset ] ; break ;
2018-08-04 19:48:31 +00:00
case KITEM_THUNDERSHIELD : localpatch = kp_thundershield [ offset ] ; break ;
2018-06-29 00:54:06 +00:00
case KITEM_HYUDORO : localpatch = kp_hyudoro [ offset ] ; break ;
case KITEM_POGOSPRING : localpatch = kp_pogospring [ offset ] ; break ;
case KITEM_KITCHENSINK : localpatch = kp_kitchensink [ offset ] ; break ;
case KITEM_SAD : localpatch = kp_sadface [ offset ] ; break ;
2018-02-05 23:55:52 +00:00
default : return ;
}
}
}
2017-12-24 00:14:06 +00:00
2017-12-27 02:36:03 +00:00
V_DrawScaledPatch ( ITEM_X , ITEM_Y , V_HUDTRANS | splitflags , localbg ) ;
2017-12-24 00:14:06 +00:00
2018-02-05 23:55:52 +00:00
// Then, the numbers:
2018-08-14 21:16:33 +00:00
if ( stplyr - > kartstuff [ k_itemamount ] > = numberdisplaymin & & ! stplyr - > kartstuff [ k_itemroulette ] )
2017-12-24 14:19:59 +00:00
{
2018-06-29 00:54:06 +00:00
V_DrawScaledPatch ( ITEM_X , ITEM_Y , V_HUDTRANS | splitflags , kp_itemmulsticker [ offset ] ) ;
2018-02-05 23:55:52 +00:00
V_DrawScaledPatch ( ITEM_X , ITEM_Y , V_HUDTRANS | splitflags , localpatch ) ;
2018-08-14 21:16:33 +00:00
if ( offset )
2018-06-29 00:54:06 +00:00
V_DrawString ( ITEM_X + 24 , ITEM_Y + 31 , V_ALLOWLOWERCASE | V_HUDTRANS | splitflags , va ( " x%d " , stplyr - > kartstuff [ k_itemamount ] ) ) ;
else
{
V_DrawScaledPatch ( ITEM_X + 28 , ITEM_Y + 41 , V_HUDTRANS | splitflags , kp_itemx ) ;
V_DrawKartString ( ITEM_X + 38 , ITEM_Y + 36 , V_HUDTRANS | splitflags , va ( " %d " , stplyr - > kartstuff [ k_itemamount ] ) ) ;
2018-07-04 21:25:38 +00:00
}
2016-08-15 03:51:08 +00:00
}
2017-06-03 22:19:06 +00:00
else
2018-02-05 23:55:52 +00:00
V_DrawScaledPatch ( ITEM_X , ITEM_Y , V_HUDTRANS | splitflags , localpatch ) ;
2018-08-12 00:19:09 +00:00
2018-08-14 14:23:38 +00:00
// Extensible meter, currently only used for rocket sneaker...
2018-08-15 13:05:13 +00:00
if ( itembar & & hudtrans )
2018-08-12 14:15:55 +00:00
{
2018-08-14 14:23:38 +00:00
const INT32 barlength = ( splitscreen > 1 ? 12 : 24 ) ;
2018-08-12 14:15:55 +00:00
const INT32 max = itemtime ; // timer's normal highest value
2018-08-14 21:16:33 +00:00
const INT32 length = min ( barlength , ( itembar * barlength ) / max ) ;
const INT32 height = ( offset ? 1 : 2 ) ;
const INT32 x = ( offset ? 17 : 11 ) , y = ( offset ? 27 : 35 ) ;
2018-08-12 14:15:55 +00:00
V_DrawScaledPatch ( ITEM_X + x , ITEM_Y + y , V_HUDTRANS | splitflags , kp_itemtimer [ offset ] ) ;
2018-08-14 14:23:38 +00:00
// The left dark "AA" edge
2018-08-15 13:05:13 +00:00
V_DrawFill ( ITEM_X + x + 1 , ITEM_Y + y + 1 , ( length = = 2 ? 2 : 1 ) , height , 12 | splitflags ) ;
2018-08-12 14:15:55 +00:00
// The bar itself
2018-08-14 14:23:38 +00:00
if ( length > 2 )
2018-08-12 14:15:55 +00:00
{
2018-08-15 13:05:13 +00:00
V_DrawFill ( ITEM_X + x + length , ITEM_Y + y + 1 , 1 , height , 12 | splitflags ) ; // the right one
2018-08-14 14:23:38 +00:00
if ( height = = 2 )
2018-08-15 13:05:13 +00:00
V_DrawFill ( ITEM_X + x + 2 , ITEM_Y + y + 2 , length - 2 , 1 , 8 | splitflags ) ; // the dulled underside
V_DrawFill ( ITEM_X + x + 2 , ITEM_Y + y + 1 , length - 2 , 1 , 120 | splitflags ) ; // the shine
2018-08-12 14:15:55 +00:00
}
2018-08-12 00:19:09 +00:00
}
2018-08-12 14:15:55 +00:00
// Quick Eggman numbers
if ( stplyr - > kartstuff [ k_eggmanexplode ] > 1 /*&& stplyr->kartstuff[k_eggmanexplode] <= 3*TICRATE*/ )
V_DrawScaledPatch ( ITEM_X + 17 , ITEM_Y + 13 , V_HUDTRANS | splitflags , kp_eggnum [ min ( 3 , G_TicsToSeconds ( stplyr - > kartstuff [ k_eggmanexplode ] ) ) ] ) ;
2016-08-15 03:51:08 +00:00
}
static void K_drawKartTimestamp ( void )
{
// TIME_X = BASEVIDWIDTH-124; // 196
// TIME_Y = 6; // 6
2018-07-19 13:39:46 +00:00
INT32 TIME_XB , splitflags = V_HUDTRANS | K_calcSplitFlags ( V_SNAPTOTOP | V_SNAPTORIGHT ) ;
tic_t drawtime = stplyr - > realtime ;
if ( cv_timelimit . value & & timelimitintics > 0 )
{
2018-07-19 13:59:38 +00:00
if ( drawtime > = timelimitintics )
2018-07-19 13:39:46 +00:00
drawtime = 0 ;
else
drawtime = timelimitintics - drawtime ;
}
2016-08-15 03:51:08 +00:00
2018-07-15 22:13:36 +00:00
V_DrawScaledPatch ( TIME_X , TIME_Y , splitflags , kp_timestickerwide ) ;
2016-08-15 03:51:08 +00:00
TIME_XB = TIME_X + 33 ;
2018-07-19 13:39:46 +00:00
if ( drawtime / ( 60 * TICRATE ) < 100 ) // 99:99:99 only
2016-08-15 03:51:08 +00:00
{
// zero minute
2018-07-19 13:39:46 +00:00
if ( drawtime / ( 60 * TICRATE ) < 10 )
2016-08-15 03:51:08 +00:00
{
2018-07-15 22:13:36 +00:00
V_DrawKartString ( TIME_XB , TIME_Y + 3 , splitflags , va ( " 0 " ) ) ;
2016-08-15 03:51:08 +00:00
// minutes time 0 __ __
2018-07-19 13:39:46 +00:00
V_DrawKartString ( TIME_XB + 12 , TIME_Y + 3 , splitflags , va ( " %d " , drawtime / ( 60 * TICRATE ) ) ) ;
2016-08-15 03:51:08 +00:00
}
// minutes time 0 __ __
else
2018-07-19 13:39:46 +00:00
V_DrawKartString ( TIME_XB , TIME_Y + 3 , splitflags , va ( " %d " , drawtime / ( 60 * TICRATE ) ) ) ;
2016-08-15 03:51:08 +00:00
// apostrophe location _'__ __
2018-07-15 22:13:36 +00:00
V_DrawKartString ( TIME_XB + 24 , TIME_Y + 3 , splitflags , va ( " ' " ) ) ;
2016-08-15 03:51:08 +00:00
// zero second _ 0_ __
2018-07-19 13:39:46 +00:00
if ( ( drawtime / TICRATE % 60 ) < 10 )
2016-08-15 03:51:08 +00:00
{
2018-07-15 22:13:36 +00:00
V_DrawKartString ( TIME_XB + 36 , TIME_Y + 3 , splitflags , va ( " 0 " ) ) ;
2016-08-15 03:51:08 +00:00
// seconds time _ _0 __
2018-07-19 13:39:46 +00:00
V_DrawKartString ( TIME_XB + 48 , TIME_Y + 3 , splitflags , va ( " %d " , drawtime / TICRATE % 60 ) ) ;
2016-08-15 03:51:08 +00:00
}
// zero second _ 00 __
else
2018-07-19 13:39:46 +00:00
V_DrawKartString ( TIME_XB + 36 , TIME_Y + 3 , splitflags , va ( " %d " , drawtime / TICRATE % 60 ) ) ;
2016-08-15 03:51:08 +00:00
// quotation mark location _ __"__
2018-07-15 22:13:36 +00:00
V_DrawKartString ( TIME_XB + 60 , TIME_Y + 3 , splitflags , va ( " \" " ) ) ;
2016-08-15 03:51:08 +00:00
// zero tick _ __ 0_
2018-07-19 13:39:46 +00:00
if ( G_TicsToCentiseconds ( drawtime ) < 10 )
2016-08-15 03:51:08 +00:00
{
2018-07-15 22:13:36 +00:00
V_DrawKartString ( TIME_XB + 72 , TIME_Y + 3 , splitflags , va ( " 0 " ) ) ;
2016-08-15 03:51:08 +00:00
// tics _ __ _0
2018-07-19 13:39:46 +00:00
V_DrawKartString ( TIME_XB + 84 , TIME_Y + 3 , splitflags , va ( " %d " , G_TicsToCentiseconds ( drawtime ) ) ) ;
2016-08-15 03:51:08 +00:00
}
// zero tick _ __ 00
2018-07-19 13:39:46 +00:00
if ( G_TicsToCentiseconds ( drawtime ) > = 10 )
V_DrawKartString ( TIME_XB + 72 , TIME_Y + 3 , splitflags , va ( " %d " , G_TicsToCentiseconds ( drawtime ) ) ) ;
2018-07-15 22:13:36 +00:00
}
2018-07-19 13:39:46 +00:00
else if ( ( drawtime / TICRATE ) & 1 )
2018-07-15 22:13:36 +00:00
V_DrawKartString ( TIME_XB , TIME_Y + 3 , splitflags , va ( " 99'59 \" 99 " ) ) ;
if ( modeattacking ) // emblem time!
{
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
INT32 workx = TIME_XB + 96 , worky = TIME_Y + 18 ;
2018-07-16 20:36:27 +00:00
SINT8 curemb = 0 ;
patch_t * emblempic [ 3 ] = { NULL , NULL , NULL } ;
UINT8 * emblemcol [ 3 ] = { NULL , NULL , NULL } ;
2018-07-15 22:13:36 +00:00
emblem_t * emblem = M_GetLevelEmblems ( gamemap ) ;
while ( emblem )
{
char targettext [ 9 ] ;
switch ( emblem - > type )
{
case ET_TIME :
{
2018-07-16 20:36:27 +00:00
static boolean canplaysound = true ;
2018-07-15 22:13:36 +00:00
tic_t timetoreach = emblem - > var ;
2018-07-16 20:36:27 +00:00
if ( emblem - > collected )
{
emblempic [ curemb ] = W_CachePatchName ( M_GetEmblemPatch ( emblem ) , PU_CACHE ) ;
emblemcol [ curemb ] = R_GetTranslationColormap ( TC_DEFAULT , M_GetEmblemColor ( emblem ) , GTC_CACHE ) ;
if ( + + curemb = = 3 )
break ;
goto bademblem ;
}
2018-07-15 22:13:36 +00:00
snprintf ( targettext , 9 , " %i:%02i.%02i " ,
G_TicsToMinutes ( timetoreach , false ) ,
G_TicsToSeconds ( timetoreach ) ,
G_TicsToCentiseconds ( timetoreach ) ) ;
if ( stplyr - > realtime > timetoreach )
{
splitflags = ( splitflags & ~ V_HUDTRANS ) | V_HUDTRANSHALF ;
2018-07-16 20:36:27 +00:00
if ( canplaysound )
2018-07-15 22:13:36 +00:00
{
S_StartSound ( NULL , sfx_s3k72 ) ; //sfx_s26d); -- you STOLE fizzy lifting drinks
2018-07-16 20:36:27 +00:00
canplaysound = false ;
2018-07-15 22:13:36 +00:00
}
}
2018-07-16 20:36:27 +00:00
else if ( ! canplaysound )
canplaysound = true ;
2018-07-15 22:13:36 +00:00
targettext [ 8 ] = 0 ;
}
break ;
default :
goto bademblem ;
}
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
V_DrawRightAlignedString ( workx , worky , splitflags , targettext ) ;
2018-07-16 20:36:27 +00:00
workx - = 69 ; // i SWEAR i wasn't aiming for this
V_DrawSmallScaledPatch ( workx + 4 , worky , splitflags , W_CachePatchName ( " NEEDIT " , PU_CACHE ) ) ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
2018-07-16 20:36:27 +00:00
break ;
2018-07-15 22:13:36 +00:00
bademblem :
emblem = M_GetLevelEmblems ( - 1 ) ;
}
2018-07-16 20:36:27 +00:00
while ( curemb - - )
{
workx - = 16 ;
V_DrawSmallMappedPatch ( workx + 4 , worky , splitflags , emblempic [ curemb ] , emblemcol [ curemb ] ) ;
}
2016-08-15 03:51:08 +00:00
}
}
static void K_DrawKartPositionNum ( INT32 num )
{
// POSI_X = BASEVIDWIDTH - 51; // 269
// POSI_Y = BASEVIDHEIGHT- 64; // 136
2017-02-17 20:14:55 +00:00
2017-12-22 15:16:41 +00:00
INT32 X = POSI_X ;
2016-08-15 03:51:08 +00:00
INT32 W = SHORT ( kp_positionnum [ 0 ] [ 0 ] - > width ) ;
2017-12-19 06:55:33 +00:00
fixed_t scale = FRACUNIT ;
2016-08-15 03:51:08 +00:00
patch_t * localpatch = kp_positionnum [ 0 ] [ 0 ] ;
2017-12-19 01:59:04 +00:00
INT32 splitflags = K_calcSplitFlags ( V_SNAPTOBOTTOM | V_SNAPTORIGHT ) ;
2017-11-06 22:31:52 +00:00
2017-12-24 00:14:06 +00:00
if ( stplyr - > kartstuff [ k_positiondelay ] | | stplyr - > exiting )
2018-08-10 01:52:02 +00:00
scale * = 2 ;
2017-12-27 02:36:03 +00:00
if ( splitscreen )
2017-12-22 15:16:41 +00:00
scale / = 2 ;
W = FixedMul ( W < < FRACBITS , scale ) > > FRACBITS ;
2016-08-15 03:51:08 +00:00
// Special case for 0
if ( ! num )
{
2017-12-27 02:36:03 +00:00
V_DrawFixedPatch ( X < < FRACBITS , POSI_Y < < FRACBITS , scale , V_HUDTRANSHALF | splitflags , kp_positionnum [ 0 ] [ 0 ] , NULL ) ;
2016-08-15 03:51:08 +00:00
return ;
}
I_Assert ( num > = 0 ) ; // This function does not draw negative numbers
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
// Draw the number
while ( num )
{
2017-11-13 03:48:32 +00:00
if ( stplyr - > exiting & & num = = 1 ) // 1st place winner? You get rainbows!!
2018-07-12 05:31:33 +00:00
localpatch = kp_winnernum [ ( leveltime % ( NUMWINFRAMES * 3 ) ) / 3 ] ;
2018-06-05 06:41:55 +00:00
else if ( stplyr - > laps + 1 > = cv_numlaps . value | | stplyr - > exiting ) // Check for the final lap, or won
2016-08-15 03:51:08 +00:00
{
// Alternate frame every three frames
switch ( leveltime % 9 )
{
case 1 : case 2 : case 3 :
Winning positions scale with number of players
Anyone in the top 50% gets winning music & blue position, everyone below
gets the losing music & red position. For odd numbers, it rounds up.
2p: 1st wins, 2nd loses
3p: 1-2 win, 3rd loses
4p: 1-2 win, 3-4 lose
5p: 1-3 win, 4-5 lose
6p: 1-3 win, 4-6 lose
7p: 1-4 win, 5-7 lose
8p: 1-4 win, 5-8 lose (SMK)
12p: 1-6 win, 7-12 lose (modern MK)
16p: 1-8 win, 9-16 lose (max player count)
In big netgames you won't just hear the losing music all of the time now
:V
2018-02-21 00:11:09 +00:00
if ( K_IsPlayerLosing ( stplyr ) )
2016-08-15 03:51:08 +00:00
localpatch = kp_positionnum [ num % 10 ] [ 4 ] ;
2017-02-17 02:33:00 +00:00
else
localpatch = kp_positionnum [ num % 10 ] [ 1 ] ;
2016-08-15 03:51:08 +00:00
break ;
case 4 : case 5 : case 6 :
Winning positions scale with number of players
Anyone in the top 50% gets winning music & blue position, everyone below
gets the losing music & red position. For odd numbers, it rounds up.
2p: 1st wins, 2nd loses
3p: 1-2 win, 3rd loses
4p: 1-2 win, 3-4 lose
5p: 1-3 win, 4-5 lose
6p: 1-3 win, 4-6 lose
7p: 1-4 win, 5-7 lose
8p: 1-4 win, 5-8 lose (SMK)
12p: 1-6 win, 7-12 lose (modern MK)
16p: 1-8 win, 9-16 lose (max player count)
In big netgames you won't just hear the losing music all of the time now
:V
2018-02-21 00:11:09 +00:00
if ( K_IsPlayerLosing ( stplyr ) )
2016-08-15 03:51:08 +00:00
localpatch = kp_positionnum [ num % 10 ] [ 5 ] ;
2017-02-17 02:33:00 +00:00
else
localpatch = kp_positionnum [ num % 10 ] [ 2 ] ;
2016-08-15 03:51:08 +00:00
break ;
case 7 : case 8 : case 9 :
Winning positions scale with number of players
Anyone in the top 50% gets winning music & blue position, everyone below
gets the losing music & red position. For odd numbers, it rounds up.
2p: 1st wins, 2nd loses
3p: 1-2 win, 3rd loses
4p: 1-2 win, 3-4 lose
5p: 1-3 win, 4-5 lose
6p: 1-3 win, 4-6 lose
7p: 1-4 win, 5-7 lose
8p: 1-4 win, 5-8 lose (SMK)
12p: 1-6 win, 7-12 lose (modern MK)
16p: 1-8 win, 9-16 lose (max player count)
In big netgames you won't just hear the losing music all of the time now
:V
2018-02-21 00:11:09 +00:00
if ( K_IsPlayerLosing ( stplyr ) )
2016-08-15 03:51:08 +00:00
localpatch = kp_positionnum [ num % 10 ] [ 6 ] ;
2017-02-17 02:33:00 +00:00
else
localpatch = kp_positionnum [ num % 10 ] [ 3 ] ;
2016-08-15 03:51:08 +00:00
break ;
default :
localpatch = kp_positionnum [ num % 10 ] [ 0 ] ;
break ;
}
}
else
localpatch = kp_positionnum [ num % 10 ] [ 0 ] ;
2017-02-17 20:14:55 +00:00
2017-12-27 02:36:03 +00:00
V_DrawFixedPatch ( X < < FRACBITS , POSI_Y < < FRACBITS , scale , V_HUDTRANSHALF | splitflags , localpatch , NULL ) ;
2017-12-19 06:55:33 +00:00
X - = W ;
2016-08-15 03:51:08 +00:00
num / = 10 ;
}
}
2018-07-22 15:16:03 +00:00
static boolean K_drawKartPositionFaces ( void )
2016-08-15 03:51:08 +00:00
{
// FACE_X = 15; // 15
// FACE_Y = 72; // 72
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
INT32 Y = FACE_Y + 9 ; // +9 to offset where it's being drawn if there are more than one
INT32 i , j , ranklines ;
boolean completed [ MAXPLAYERS ] ;
INT32 rankplayer [ MAXPLAYERS ] ;
2018-07-22 15:16:03 +00:00
INT32 bumperx , numplayersingame = 0 ;
2016-08-15 03:51:08 +00:00
UINT8 * colormap ;
patch_t * localpatch = kp_facenull ;
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
ranklines = 0 ;
memset ( completed , 0 , sizeof ( completed ) ) ;
memset ( rankplayer , 0 , sizeof ( rankplayer ) ) ;
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
2018-07-22 15:16:03 +00:00
{
2016-08-15 03:51:08 +00:00
rankplayer [ i ] = - 1 ;
2017-02-17 20:14:55 +00:00
2018-07-22 15:16:03 +00:00
if ( ! playeringame [ i ] | | players [ i ] . spectator | | ! players [ i ] . mo )
2018-01-23 03:18:57 +00:00
continue ;
2018-07-22 15:16:03 +00:00
numplayersingame + + ;
}
if ( numplayersingame < = 1 )
return true ;
for ( j = 0 ; j < numplayersingame ; j + + )
{
2016-08-15 03:51:08 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-01-23 03:18:57 +00:00
if ( playeringame [ i ] & & completed [ i ] = = false & & players [ i ] . mo & & ! players [ i ] . spectator
2016-08-15 03:51:08 +00:00
& & ( rankplayer [ ranklines ] < 0 | | players [ i ] . kartstuff [ k_position ] < players [ rankplayer [ ranklines ] ] . kartstuff [ k_position ] ) )
{
rankplayer [ ranklines ] = i ;
}
}
2018-07-18 19:23:46 +00:00
i = rankplayer [ ranklines ] ;
completed [ i ] = true ;
if ( ranklines = = 4 )
break ; // Only draw the top 4 players
2016-08-15 03:51:08 +00:00
ranklines + + ;
}
2017-02-17 20:14:55 +00:00
2016-08-15 03:51:08 +00:00
Y - = ( 9 * ranklines ) ;
for ( i = 0 ; i < ranklines ; i + + )
{
if ( players [ rankplayer [ i ] ] . spectator ) continue ; // Spectators are ignored
2018-01-30 00:15:25 +00:00
if ( ! players [ rankplayer [ i ] ] . mo ) continue ;
2016-08-15 03:51:08 +00:00
2018-07-03 19:14:47 +00:00
bumperx = FACE_X + 18 ;
2017-11-30 00:35:37 +00:00
2018-07-18 19:23:46 +00:00
if ( players [ rankplayer [ i ] ] . mo - > color )
2016-08-15 03:51:08 +00:00
{
colormap = R_GetTranslationColormap ( players [ rankplayer [ i ] ] . skin , players [ rankplayer [ i ] ] . mo - > color , GTC_CACHE ) ;
2018-02-05 00:00:36 +00:00
if ( players [ rankplayer [ i ] ] . mo - > colorized )
2018-02-06 00:08:49 +00:00
colormap = R_GetTranslationColormap ( TC_RAINBOW , players [ rankplayer [ i ] ] . mo - > color , GTC_CACHE ) ;
2018-02-05 00:00:36 +00:00
else
colormap = R_GetTranslationColormap ( players [ rankplayer [ i ] ] . skin , players [ rankplayer [ i ] ] . mo - > color , GTC_CACHE ) ;
2018-07-18 19:23:46 +00:00
V_DrawSmallMappedPatch ( FACE_X , Y , V_HUDTRANS | V_SNAPTOLEFT , faceprefix [ players [ rankplayer [ i ] ] . skin ] , colormap ) ;
if ( G_BattleGametype ( ) & & players [ rankplayer [ i ] ] . kartstuff [ k_bumper ] > 0 )
2017-11-30 00:35:37 +00:00
{
2018-07-18 19:23:46 +00:00
for ( j = 0 ; j < players [ rankplayer [ i ] ] . kartstuff [ k_bumper ] ; j + + )
2017-11-30 00:35:37 +00:00
{
2018-07-18 19:23:46 +00:00
V_DrawSmallMappedPatch ( bumperx , Y + 10 , V_HUDTRANS | V_SNAPTOLEFT , kp_rankbumper , colormap ) ;
bumperx + = 3 ;
2017-11-30 00:35:37 +00:00
}
}
2016-08-15 03:51:08 +00:00
}
2017-11-30 00:35:37 +00:00
2016-08-15 03:51:08 +00:00
// Draws the little number over the face
2017-02-13 04:24:49 +00:00
switch ( players [ rankplayer [ i ] ] . kartstuff [ k_position ] )
2016-08-15 03:51:08 +00:00
{
case 1 : localpatch = kp_facefirst ; break ;
case 2 : localpatch = kp_facesecond ; break ;
case 3 : localpatch = kp_facethird ; break ;
case 4 : localpatch = kp_facefourth ; break ;
default : break ;
}
2017-11-30 00:35:37 +00:00
2018-07-18 19:23:46 +00:00
if ( G_BattleGametype ( ) & & players [ rankplayer [ i ] ] . kartstuff [ k_bumper ] < = 0 )
V_DrawSmallScaledPatch ( FACE_X - 2 , Y , V_HUDTRANS | V_SNAPTOLEFT , kp_ranknobumpers ) ;
2016-08-15 03:51:08 +00:00
else
2018-07-18 19:23:46 +00:00
V_DrawSmallScaledPatch ( FACE_X , Y , V_HUDTRANS | V_SNAPTOLEFT , localpatch ) ;
2017-11-30 00:35:37 +00:00
2016-08-15 03:51:08 +00:00
Y + = 18 ;
}
2018-07-22 15:16:03 +00:00
return false ;
2016-08-15 03:51:08 +00:00
}
2017-11-06 22:31:52 +00:00
static void K_drawKartLaps ( void )
{
2017-12-19 01:59:04 +00:00
INT32 splitflags = K_calcSplitFlags ( V_SNAPTOBOTTOM | V_SNAPTOLEFT ) ;
2017-11-06 22:31:52 +00:00
2017-12-24 00:14:06 +00:00
if ( splitscreen > 1 )
{
2017-12-27 02:36:03 +00:00
V_DrawScaledPatch ( LAPS_X , LAPS_Y , V_HUDTRANS | splitflags , kp_splitlapflag ) ;
2017-11-06 22:31:52 +00:00
2017-12-24 00:14:06 +00:00
if ( stplyr - > exiting )
2017-12-27 02:36:03 +00:00
V_DrawString ( LAPS_X + 13 , LAPS_Y + 1 , V_HUDTRANS | splitflags , " FIN " ) ;
2017-12-24 00:14:06 +00:00
else
2017-12-27 02:36:03 +00:00
V_DrawString ( LAPS_X + 13 , LAPS_Y + 1 , V_HUDTRANS | splitflags , va ( " %d/%d " , stplyr - > laps + 1 , cv_numlaps . value ) ) ;
2017-12-24 00:14:06 +00:00
}
2017-11-06 22:31:52 +00:00
else
2017-12-24 00:14:06 +00:00
{
2017-12-27 02:36:03 +00:00
V_DrawScaledPatch ( LAPS_X , LAPS_Y , V_HUDTRANS | splitflags , kp_lapsticker ) ;
2017-12-24 00:14:06 +00:00
if ( stplyr - > exiting )
2017-12-27 02:36:03 +00:00
V_DrawKartString ( LAPS_X + 33 , LAPS_Y + 3 , V_HUDTRANS | splitflags , " FIN " ) ;
2017-12-24 00:14:06 +00:00
else
2017-12-27 02:36:03 +00:00
V_DrawKartString ( LAPS_X + 33 , LAPS_Y + 3 , V_HUDTRANS | splitflags , va ( " %d/%d " , stplyr - > laps + 1 , cv_numlaps . value ) ) ;
2017-12-24 00:14:06 +00:00
}
2017-11-06 22:31:52 +00:00
}
2017-03-08 00:28:31 +00:00
static void K_drawKartSpeedometer ( void )
{
2017-03-09 20:29:17 +00:00
fixed_t convSpeed ;
2017-12-19 01:59:04 +00:00
INT32 splitflags = K_calcSplitFlags ( V_SNAPTOBOTTOM | V_SNAPTOLEFT ) ;
2017-12-18 01:42:17 +00:00
2018-06-15 00:18:29 +00:00
if ( cv_kartspeedometer . value = = 1 ) // Kilometers
2017-03-09 20:29:17 +00:00
{
2018-01-15 21:14:45 +00:00
convSpeed = FixedDiv ( FixedMul ( stplyr - > speed , 142371 ) , mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) / FRACUNIT ; // 2.172409058
2017-12-27 02:36:03 +00:00
V_DrawKartString ( SPDM_X , SPDM_Y , V_HUDTRANS | splitflags , va ( " %3d km/h " , convSpeed ) ) ;
2017-03-09 20:29:17 +00:00
}
2018-06-15 00:18:29 +00:00
else if ( cv_kartspeedometer . value = = 2 ) // Miles
2017-03-09 20:29:17 +00:00
{
2018-01-15 21:14:45 +00:00
convSpeed = FixedDiv ( FixedMul ( stplyr - > speed , 88465 ) , mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) / FRACUNIT ; // 1.349868774
2017-12-27 02:36:03 +00:00
V_DrawKartString ( SPDM_X , SPDM_Y , V_HUDTRANS | splitflags , va ( " %3d mph " , convSpeed ) ) ;
2017-03-09 20:29:17 +00:00
}
2018-06-15 00:18:29 +00:00
else if ( cv_kartspeedometer . value = = 3 ) // Fracunits
2017-03-13 02:44:31 +00:00
{
2018-01-15 21:14:45 +00:00
convSpeed = FixedDiv ( stplyr - > speed , mapheaderinfo [ gamemap - 1 ] - > mobj_scale ) / FRACUNIT ;
2018-01-16 23:02:16 +00:00
V_DrawKartString ( SPDM_X , SPDM_Y , V_HUDTRANS | splitflags , va ( " %3d fu/t " , convSpeed ) ) ;
2017-03-13 02:44:31 +00:00
}
2017-03-08 00:28:31 +00:00
}
2018-07-03 19:14:47 +00:00
static void K_drawKartBumpersOrKarma ( void )
2017-11-14 01:45:57 +00:00
{
2018-01-23 03:18:57 +00:00
UINT8 * colormap = R_GetTranslationColormap ( TC_DEFAULT , stplyr - > skincolor , 0 ) ;
2017-12-19 01:59:04 +00:00
INT32 splitflags = K_calcSplitFlags ( V_SNAPTOBOTTOM | V_SNAPTOLEFT ) ;
2017-11-14 01:45:57 +00:00
2017-12-24 01:55:23 +00:00
if ( splitscreen > 1 )
2017-11-14 01:45:57 +00:00
{
2018-07-03 19:14:47 +00:00
if ( stplyr - > kartstuff [ k_bumper ] < = 0 )
2017-12-24 01:55:23 +00:00
{
2017-12-27 02:36:03 +00:00
V_DrawMappedPatch ( LAPS_X , LAPS_Y - 1 , V_HUDTRANS | splitflags , kp_splitkarmabomb , colormap ) ;
V_DrawString ( LAPS_X + 13 , LAPS_Y + 1 , V_HUDTRANS | splitflags , va ( " %d/3 " , stplyr - > kartstuff [ k_comebackpoints ] ) ) ;
2017-12-24 01:55:23 +00:00
}
else
{
2018-07-03 19:14:47 +00:00
V_DrawMappedPatch ( LAPS_X , LAPS_Y - 1 , V_HUDTRANS | splitflags , kp_rankbumper , colormap ) ;
V_DrawString ( LAPS_X + 13 , LAPS_Y + 1 , V_HUDTRANS | splitflags , va ( " %d/%d " , stplyr - > kartstuff [ k_bumper ] , cv_kartbumpers . value ) ) ;
2017-12-24 01:55:23 +00:00
}
2017-11-14 01:45:57 +00:00
}
else
{
2018-07-03 19:14:47 +00:00
if ( stplyr - > kartstuff [ k_bumper ] < = 0 )
2017-11-14 01:45:57 +00:00
{
2017-12-27 02:36:03 +00:00
V_DrawMappedPatch ( LAPS_X , LAPS_Y , V_HUDTRANS | splitflags , kp_karmasticker , colormap ) ;
2017-12-28 23:37:25 +00:00
V_DrawKartString ( LAPS_X + 59 , LAPS_Y + 3 , V_HUDTRANS | splitflags , va ( " %d/3 " , stplyr - > kartstuff [ k_comebackpoints ] ) ) ;
2017-11-14 01:45:57 +00:00
}
else
{
2018-07-03 19:14:47 +00:00
if ( stplyr - > kartstuff [ k_bumper ] > 9 & & cv_kartbumpers . value > 9 )
V_DrawMappedPatch ( LAPS_X , LAPS_Y , V_HUDTRANS | splitflags , kp_bumperstickerwide , colormap ) ;
2017-12-24 01:55:23 +00:00
else
2018-07-03 19:14:47 +00:00
V_DrawMappedPatch ( LAPS_X , LAPS_Y , V_HUDTRANS | splitflags , kp_bumpersticker , colormap ) ;
V_DrawKartString ( LAPS_X + 47 , LAPS_Y + 3 , V_HUDTRANS | splitflags , va ( " %d/%d " , stplyr - > kartstuff [ k_bumper ] , cv_kartbumpers . value ) ) ;
2017-11-14 01:45:57 +00:00
}
}
}
2018-06-07 23:39:45 +00:00
static void K_drawSPBWarning ( void )
2018-06-06 01:36:48 +00:00
{
patch_t * localpatch = kp_nodraw ;
INT32 splitflags = K_calcSplitFlags ( V_SNAPTOBOTTOM ) ;
if ( ! ( stplyr - > kartstuff [ k_deathsentence ] > 0
2018-06-07 23:39:45 +00:00
| | ( spbincoming > 0 & & spbincoming < 2 * TICRATE & & stplyr - > kartstuff [ k_position ] = = 1 ) ) )
2018-06-06 01:36:48 +00:00
return ;
if ( leveltime % 8 > 3 )
2018-06-07 23:39:45 +00:00
localpatch = kp_spbwarning [ 1 ] ;
2018-06-06 01:36:48 +00:00
else
2018-06-07 23:39:45 +00:00
localpatch = kp_spbwarning [ 0 ] ;
2018-06-06 01:36:48 +00:00
2018-06-07 23:39:45 +00:00
V_DrawScaledPatch ( SPBW_X , SPBW_Y , splitflags , localpatch ) ;
2018-06-06 01:36:48 +00:00
}
2017-11-05 06:43:47 +00:00
fixed_t K_FindCheckX ( fixed_t px , fixed_t py , angle_t ang , fixed_t mx , fixed_t my )
2017-11-02 04:35:10 +00:00
{
2017-11-05 06:43:47 +00:00
fixed_t dist , x ;
2017-11-17 05:48:36 +00:00
fixed_t range = RING_DIST / 3 ;
2017-11-05 06:43:47 +00:00
angle_t diff ;
2017-11-02 04:35:10 +00:00
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
range * = gamespeed + 1 ;
2017-11-06 04:18:58 +00:00
2017-11-05 06:43:47 +00:00
dist = abs ( R_PointToDist2 ( px , py , mx , my ) ) ;
2017-11-06 04:18:58 +00:00
if ( dist > range )
2017-11-02 04:35:10 +00:00
return - 320 ;
2017-11-05 06:43:47 +00:00
diff = R_PointToAngle2 ( px , py , mx , my ) - ang ;
2017-11-02 04:35:10 +00:00
2017-11-05 06:43:47 +00:00
if ( diff < ANGLE_90 | | diff > ANGLE_270 )
2017-11-02 04:35:10 +00:00
return - 320 ;
else
2017-12-13 23:01:26 +00:00
x = ( FixedMul ( FINETANGENT ( ( ( diff + ANGLE_90 ) > > ANGLETOFINESHIFT ) & 4095 ) , 160 < < FRACBITS ) + ( 160 < < FRACBITS ) ) > > FRACBITS ;
2017-11-02 04:35:10 +00:00
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
if ( mirrormode )
2017-12-13 23:01:26 +00:00
x = 320 - x ;
2017-12-19 01:59:04 +00:00
if ( splitscreen > 1 )
2017-12-18 06:02:53 +00:00
x / = 2 ;
2017-11-02 04:35:10 +00:00
2017-12-13 23:01:26 +00:00
return x ;
2017-11-02 04:35:10 +00:00
}
2018-07-01 08:36:09 +00:00
static void K_drawKartWanted ( void )
{
UINT8 i , numwanted = 0 ;
2018-07-01 18:11:48 +00:00
UINT8 * colormap = NULL ;
2018-07-01 08:36:09 +00:00
2018-07-01 18:11:48 +00:00
if ( splitscreen ) // Can't fit the poster on screen, sadly
2018-07-01 08:36:09 +00:00
{
2018-07-01 18:11:48 +00:00
if ( K_IsPlayerWanted ( stplyr ) & & leveltime % 10 > 3 )
2018-07-01 08:36:09 +00:00
V_DrawRightAlignedString ( WANT_X , WANT_Y , K_calcSplitFlags ( V_SNAPTOBOTTOM | V_SNAPTORIGHT | V_HUDTRANS | V_REDMAP ) , " WANTED " ) ;
return ;
2018-07-01 18:11:48 +00:00
}
2018-07-01 08:36:09 +00:00
for ( i = 0 ; i < 4 ; i + + )
{
if ( battlewanted [ i ] = = - 1 )
break ;
numwanted + + ;
}
if ( numwanted < = 0 )
return ;
2018-07-01 18:11:48 +00:00
if ( battlewanted [ 0 ] ! = - 1 )
colormap = R_GetTranslationColormap ( 0 , players [ battlewanted [ 0 ] ] . skincolor , GTC_CACHE ) ;
V_DrawFixedPatch ( WANT_X < < FRACBITS , WANT_Y < < FRACBITS , FRACUNIT , V_HUDTRANS | V_SNAPTORIGHT | V_SNAPTOBOTTOM , kp_wanted , colormap ) ;
2018-07-01 08:36:09 +00:00
for ( i = 0 ; i < numwanted ; i + + )
{
2018-07-01 18:11:48 +00:00
INT32 x = WANT_X + 7 , y = WANT_Y + 20 ;
2018-07-01 08:36:09 +00:00
fixed_t scale = FRACUNIT / 2 ;
player_t * p = & players [ battlewanted [ i ] ] ;
if ( battlewanted [ i ] = = - 1 )
break ;
if ( numwanted = = 1 )
{
2018-07-01 18:11:48 +00:00
x + + ; //y++;
2018-07-01 08:36:09 +00:00
scale = FRACUNIT ;
}
2018-07-01 18:11:48 +00:00
else
{
if ( i & 1 )
x + = 18 ;
if ( i > 1 )
y + = 17 ;
}
2018-07-01 08:36:09 +00:00
if ( players [ battlewanted [ i ] ] . skincolor = = 0 )
2018-07-01 19:15:45 +00:00
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , scale , V_HUDTRANS | V_SNAPTORIGHT | V_SNAPTOBOTTOM , faceprefix [ p - > skin ] , NULL ) ;
2018-07-01 08:36:09 +00:00
else
{
2018-07-01 18:11:48 +00:00
colormap = R_GetTranslationColormap ( TC_RAINBOW , p - > skincolor , GTC_CACHE ) ;
2018-07-01 19:15:45 +00:00
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , scale , V_HUDTRANS | V_SNAPTORIGHT | V_SNAPTOBOTTOM , faceprefix [ p - > skin ] , colormap ) ;
2018-07-01 08:36:09 +00:00
}
}
}
2017-11-02 04:35:10 +00:00
static void K_drawKartPlayerCheck ( void )
{
INT32 i ;
UINT8 * colormap ;
2017-11-06 22:31:52 +00:00
INT32 x ;
2017-11-02 04:35:10 +00:00
2017-12-19 01:59:04 +00:00
INT32 splitflags = K_calcSplitFlags ( V_SNAPTOBOTTOM ) ;
2017-12-18 01:42:17 +00:00
2018-02-10 06:19:33 +00:00
if ( ! stplyr - > mo | | stplyr - > spectator )
2017-11-02 04:35:10 +00:00
return ;
2017-11-06 22:31:52 +00:00
if ( stplyr - > awayviewtics )
2017-11-02 04:35:10 +00:00
return ;
2018-01-23 03:18:57 +00:00
if ( camspin )
return ;
2017-11-02 04:35:10 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-06-12 21:14:32 +00:00
UINT8 pnum = 0 ;
2018-07-22 15:16:03 +00:00
if ( & players [ i ] = = stplyr )
continue ;
2018-02-10 06:19:33 +00:00
if ( ! playeringame [ i ] | | players [ i ] . spectator )
continue ;
if ( ! players [ i ] . mo )
2017-11-02 04:35:10 +00:00
continue ;
2018-02-05 23:55:52 +00:00
if ( ( players [ i ] . kartstuff [ k_invincibilitytimer ] < = 0 ) & & ( leveltime & 2 ) )
2018-02-10 06:19:33 +00:00
pnum + + ; // white frames
if ( players [ i ] . kartstuff [ k_itemtype ] = = KITEM_GROW | | players [ i ] . kartstuff [ k_growshrinktimer ] > 0 )
pnum + = 4 ;
else if ( players [ i ] . kartstuff [ k_itemtype ] = = KITEM_INVINCIBILITY | | players [ i ] . kartstuff [ k_invincibilitytimer ] )
pnum + = 2 ;
2017-11-05 06:43:47 +00:00
2017-11-06 22:31:52 +00:00
x = K_FindCheckX ( stplyr - > mo - > x , stplyr - > mo - > y , stplyr - > mo - > angle , players [ i ] . mo - > x , players [ i ] . mo - > y ) ;
2017-11-02 04:35:10 +00:00
if ( x < = 320 & & x > = 0 )
{
if ( x < 14 )
x = 14 ;
else if ( x > 306 )
x = 306 ;
2017-11-06 22:31:52 +00:00
2018-01-23 03:18:57 +00:00
colormap = R_GetTranslationColormap ( TC_DEFAULT , players [ i ] . mo - > color , 0 ) ;
2018-02-10 06:19:33 +00:00
V_DrawMappedPatch ( x , CHEK_Y , V_HUDTRANS | splitflags , kp_check [ pnum ] , colormap ) ;
2017-11-02 04:35:10 +00:00
}
}
}
2017-12-19 06:55:33 +00:00
void K_LoadIconGraphics ( char * facestr , INT32 skinnum )
{
char namelump [ 9 ] ;
// hack: make sure base face name is no more than 8 chars
if ( strlen ( facestr ) > 8 )
facestr [ 8 ] = ' \0 ' ;
strcpy ( namelump , facestr ) ; // copy base name
iconprefix [ skinnum ] = W_CachePatchName ( namelump , PU_HUDGFX ) ;
iconfreed [ skinnum ] = false ;
}
#if 0 //unused
static void K_UnLoadIconGraphics ( INT32 skinnum )
{
Z_Free ( iconprefix [ skinnum ] ) ;
iconfreed [ skinnum ] = true ;
}
# endif
2017-12-24 00:14:06 +00:00
void K_ReloadSkinIconGraphics ( void )
{
INT32 i ;
for ( i = 0 ; i < numskins ; i + + )
K_LoadIconGraphics ( skins [ i ] . iconprefix , i ) ;
}
2018-07-01 18:29:13 +00:00
static void K_drawKartMinimapHead ( mobj_t * mo , INT32 x , INT32 y , INT32 flags , patch_t * AutomapPic )
2017-12-19 06:55:33 +00:00
{
2018-02-08 03:33:27 +00:00
// amnum xpos & ypos are the icon's speed around the HUD.
// The number being divided by is for how fast it moves.
// The higher the number, the slower it moves.
// am xpos & ypos are the icon's starting position. Withouht
// it, they wouldn't 'spawn' on the top-right side of the HUD.
2018-07-01 18:29:13 +00:00
UINT8 skin = 0 ;
2018-07-07 01:53:37 +00:00
fixed_t amnumxpos , amnumypos ;
INT32 amxpos , amypos ;
2018-02-08 03:33:27 +00:00
node_t * bsp = & nodes [ numnodes - 1 ] ;
fixed_t maxx , minx , maxy , miny ;
2018-07-07 01:53:37 +00:00
fixed_t mapwidth , mapheight ;
fixed_t xoffset , yoffset ;
fixed_t xscale , yscale , zoom ;
2018-07-08 21:51:44 +00:00
if ( mo - > skin )
skin = ( ( skin_t * ) mo - > skin ) - skins ;
2018-02-08 03:33:27 +00:00
maxx = maxy = INT32_MAX ;
minx = miny = INT32_MIN ;
minx = bsp - > bbox [ 0 ] [ BOXLEFT ] ;
maxx = bsp - > bbox [ 0 ] [ BOXRIGHT ] ;
miny = bsp - > bbox [ 0 ] [ BOXBOTTOM ] ;
maxy = bsp - > bbox [ 0 ] [ BOXTOP ] ;
if ( bsp - > bbox [ 1 ] [ BOXLEFT ] < minx )
minx = bsp - > bbox [ 1 ] [ BOXLEFT ] ;
if ( bsp - > bbox [ 1 ] [ BOXRIGHT ] > maxx )
maxx = bsp - > bbox [ 1 ] [ BOXRIGHT ] ;
if ( bsp - > bbox [ 1 ] [ BOXBOTTOM ] < miny )
miny = bsp - > bbox [ 1 ] [ BOXBOTTOM ] ;
if ( bsp - > bbox [ 1 ] [ BOXTOP ] > maxy )
maxy = bsp - > bbox [ 1 ] [ BOXTOP ] ;
// You might be wondering why these are being bitshift here
// it's because mapwidth and height would otherwise overflow for maps larger than half the size possible...
// map boundaries and sizes will ALWAYS be whole numbers thankfully
// later calculations take into consideration that these are actually not in terms of FRACUNIT though
minx > > = FRACBITS ;
maxx > > = FRACBITS ;
miny > > = FRACBITS ;
maxy > > = FRACBITS ;
2018-07-07 01:53:37 +00:00
mapwidth = maxx - minx ;
mapheight = maxy - miny ;
2018-02-08 03:33:27 +00:00
// These should always be small enough to be bitshift back right now
2018-07-07 01:53:37 +00:00
xoffset = ( minx + mapwidth / 2 ) < < FRACBITS ;
yoffset = ( miny + mapheight / 2 ) < < FRACBITS ;
2018-02-08 03:33:27 +00:00
2018-07-07 01:53:37 +00:00
xscale = FixedDiv ( AutomapPic - > width , mapwidth ) ;
yscale = FixedDiv ( AutomapPic - > height , mapheight ) ;
zoom = FixedMul ( min ( xscale , yscale ) , FRACUNIT - FRACUNIT / 20 ) ;
2018-02-08 03:33:27 +00:00
2018-07-01 18:29:13 +00:00
amnumxpos = ( FixedMul ( mo - > x , zoom ) - FixedMul ( xoffset , zoom ) ) ;
amnumypos = - ( FixedMul ( mo - > y , zoom ) - FixedMul ( yoffset , zoom ) ) ;
2018-02-08 03:33:27 +00:00
2018-07-22 15:16:03 +00:00
if ( mirrormode )
amnumxpos = - amnumxpos ;
2018-07-01 18:29:13 +00:00
amxpos = amnumxpos + ( ( x + AutomapPic - > width / 2 - ( iconprefix [ skin ] - > width / 2 ) ) < < FRACBITS ) ;
amypos = amnumypos + ( ( y + AutomapPic - > height / 2 - ( iconprefix [ skin ] - > height / 2 ) ) < < FRACBITS ) ;
2018-02-08 03:33:27 +00:00
2018-07-22 15:16:03 +00:00
// do we want this? it feels unnecessary. easier to just modify the amnumxpos?
/*if (mirrormode)
2018-02-08 03:33:27 +00:00
{
flags | = V_FLIP ;
2018-07-01 18:29:13 +00:00
amxpos = - amnumxpos + ( ( x + AutomapPic - > width / 2 + ( iconprefix [ skin ] - > width / 2 ) ) < < FRACBITS ) ;
2018-07-22 15:16:03 +00:00
} */
2018-02-08 03:33:27 +00:00
2018-07-01 18:29:13 +00:00
if ( ! mo - > color ) // 'default' color
V_DrawSciencePatch ( amxpos , amypos , flags , iconprefix [ skin ] , FRACUNIT ) ;
2018-02-08 03:33:27 +00:00
else
{
UINT8 * colormap ;
2018-07-01 18:29:13 +00:00
if ( mo - > colorized )
colormap = R_GetTranslationColormap ( TC_RAINBOW , mo - > color , 0 ) ;
2018-02-08 03:33:27 +00:00
else
2018-07-01 18:29:13 +00:00
colormap = R_GetTranslationColormap ( skin , mo - > color , 0 ) ;
V_DrawFixedPatch ( amxpos , amypos , FRACUNIT , flags , iconprefix [ skin ] , colormap ) ;
2018-02-08 03:33:27 +00:00
}
}
static void K_drawKartMinimap ( void )
{
2017-12-19 06:55:33 +00:00
INT32 lumpnum ;
patch_t * AutomapPic ;
INT32 i = 0 ;
2017-12-22 21:24:20 +00:00
INT32 x , y ;
2018-06-28 18:07:04 +00:00
INT32 minimaptrans , splitflags = ( splitscreen ? 0 : V_SNAPTORIGHT ) ;
2018-06-30 15:01:03 +00:00
boolean dop1later = false ;
2017-12-19 06:55:33 +00:00
// Draw the HUD only when playing in a level.
// hu_stuff needs this, unlike st_stuff.
2017-12-22 21:24:20 +00:00
if ( ! ( Playing ( ) & & gamestate = = GS_LEVEL ) )
return ;
2017-12-19 06:55:33 +00:00
2017-12-24 00:14:06 +00:00
if ( stplyr ! = & players [ displayplayer ] )
return ;
2017-12-22 21:24:20 +00:00
lumpnum = W_CheckNumForName ( va ( " %sR " , G_BuildMapName ( gamemap ) ) ) ;
2017-12-19 06:55:33 +00:00
2017-12-22 21:24:20 +00:00
if ( lumpnum ! = - 1 )
2017-12-24 00:14:06 +00:00
AutomapPic = W_CachePatchName ( va ( " %sR " , G_BuildMapName ( gamemap ) ) , PU_HUDGFX ) ;
2017-12-22 21:24:20 +00:00
else
return ; // no pic, just get outta here
2017-12-19 06:55:33 +00:00
2018-02-05 03:59:36 +00:00
x = MINI_X - ( AutomapPic - > width / 2 ) ;
y = MINI_Y - ( AutomapPic - > height / 2 ) ;
2017-12-19 06:55:33 +00:00
2018-06-28 18:07:04 +00:00
if ( timeinmap > 105 )
{
minimaptrans = ( splitscreen ? 10 : cv_kartminimap . value ) ;
if ( timeinmap < = 113 )
minimaptrans = ( ( ( ( INT32 ) timeinmap ) - 105 ) * minimaptrans ) / ( 113 - 105 ) ;
if ( ! minimaptrans )
return ;
}
else
return ;
minimaptrans = ( ( 10 - minimaptrans ) < < FF_TRANSSHIFT ) ;
splitflags | = minimaptrans ;
2017-12-27 02:36:03 +00:00
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
if ( mirrormode )
2018-02-05 03:59:36 +00:00
V_DrawScaledPatch ( x + ( AutomapPic - > width ) , y , splitflags | V_FLIP , AutomapPic ) ;
2017-12-22 21:24:20 +00:00
else
2018-02-05 03:59:36 +00:00
V_DrawScaledPatch ( x , y , splitflags , AutomapPic ) ;
2017-12-27 02:36:03 +00:00
2018-03-27 22:22:33 +00:00
if ( ! splitscreen )
2018-02-08 03:33:27 +00:00
{
splitflags & = ~ minimaptrans ;
splitflags | = V_HUDTRANSHALF ;
}
2017-12-19 06:55:33 +00:00
2018-06-04 20:19:36 +00:00
// let offsets transfer to the heads, too!
if ( mirrormode )
x + = SHORT ( AutomapPic - > leftoffset ) ;
else
x - = SHORT ( AutomapPic - > leftoffset ) ;
y - = SHORT ( AutomapPic - > topoffset ) ;
2018-06-30 15:01:03 +00:00
// Player's tiny icons on the Automap. (drawn opposite direction so player 1 is drawn last in splitscreen)
2018-07-01 18:29:13 +00:00
if ( ghosts )
2017-12-22 21:24:20 +00:00
{
2018-07-01 18:29:13 +00:00
demoghost * g = ghosts ;
while ( g )
2018-06-30 15:01:03 +00:00
{
2018-07-01 18:29:13 +00:00
K_drawKartMinimapHead ( g - > mo , x , y , splitflags , AutomapPic ) ;
g = g - > next ;
2018-06-30 15:01:03 +00:00
}
2018-07-01 18:29:13 +00:00
if ( ! stplyr - > mo | | stplyr - > spectator ) // do we need the latter..?
return ;
dop1later = true ;
}
else
{
for ( i = MAXPLAYERS - 1 ; i > = 0 ; i - - )
2018-06-30 15:01:03 +00:00
{
2018-07-01 18:29:13 +00:00
if ( ! playeringame [ i ] )
continue ;
if ( ! players [ i ] . mo | | players [ i ] . spectator )
2018-06-30 15:01:03 +00:00
continue ;
2018-07-01 18:29:13 +00:00
if ( ! splitscreen & & i = = displayplayer )
{
dop1later = true ; // Do displayplayer later
continue ;
}
2018-07-03 19:14:47 +00:00
if ( G_BattleGametype ( ) & & players [ i ] . kartstuff [ k_bumper ] < = 0 )
2018-07-01 18:29:13 +00:00
continue ;
if ( players [ i ] . kartstuff [ k_hyudorotimer ] > 0 )
{
if ( ! ( ( players [ i ] . kartstuff [ k_hyudorotimer ] < 1 * TICRATE / 2
| | players [ i ] . kartstuff [ k_hyudorotimer ] > hyudorotime - ( 1 * TICRATE / 2 ) )
& & ! ( leveltime & 1 ) ) )
continue ;
}
K_drawKartMinimapHead ( players [ i ] . mo , x , y , splitflags , AutomapPic ) ;
}
2017-12-19 06:55:33 +00:00
}
2018-02-08 03:33:27 +00:00
2018-06-30 15:01:03 +00:00
if ( ! dop1later )
return ; // Don't need this
2018-02-08 03:33:27 +00:00
splitflags & = ~ V_HUDTRANSHALF ;
splitflags | = V_HUDTRANS ;
2018-07-01 18:29:13 +00:00
K_drawKartMinimapHead ( stplyr - > mo , x , y , splitflags , AutomapPic ) ;
2017-12-19 06:55:33 +00:00
}
2018-07-19 14:58:07 +00:00
static void K_drawKartStartCountdown ( void )
{
INT32 pnum = 0 , splitflags = K_calcSplitFlags ( 0 ) ; // 3
if ( leveltime > = starttime - ( 2 * TICRATE ) ) // 2
pnum + + ;
if ( leveltime > = starttime - TICRATE ) // 1
pnum + + ;
if ( leveltime > = starttime ) // GO!
pnum + + ;
if ( ( leveltime % ( 2 * 5 ) ) / 5 ) // blink
pnum + = 4 ;
if ( splitscreen )
V_DrawSmallScaledPatch ( STCD_X - ( SHORT ( kp_startcountdown [ pnum ] - > width ) / 4 ) , STCD_Y - ( SHORT ( kp_startcountdown [ pnum ] - > height ) / 4 ) , splitflags , kp_startcountdown [ pnum ] ) ;
else
V_DrawScaledPatch ( STCD_X - ( SHORT ( kp_startcountdown [ pnum ] - > width ) / 2 ) , STCD_Y - ( SHORT ( kp_startcountdown [ pnum ] - > height ) / 2 ) , splitflags , kp_startcountdown [ pnum ] ) ;
}
static void K_drawKartFinish ( void )
{
INT32 pnum = 0 , splitflags = K_calcSplitFlags ( 0 ) ;
if ( ! stplyr - > kartstuff [ k_cardanimation ] | | stplyr - > kartstuff [ k_cardanimation ] > = 2 * TICRATE )
return ;
if ( ( stplyr - > kartstuff [ k_cardanimation ] % ( 2 * 5 ) ) / 5 ) // blink
pnum = 1 ;
2018-07-20 11:37:09 +00:00
if ( splitscreen > 1 )
2018-07-19 14:58:07 +00:00
{
V_DrawTinyScaledPatch ( STCD_X - ( SHORT ( kp_racefinish [ pnum ] - > width ) / 8 ) , STCD_Y - ( SHORT ( kp_racefinish [ pnum ] - > height ) / 8 ) , splitflags , kp_racefinish [ pnum ] ) ;
return ;
}
{
2018-07-20 11:37:09 +00:00
INT32 scaleshift = ( FRACBITS - splitscreen ) ; // FRACUNIT or FRACUNIT/2
INT32 x = ( ( vid . width < < FRACBITS ) / vid . dupx ) , xval = ( SHORT ( kp_racefinish [ pnum ] - > width ) < < scaleshift ) ;
2018-07-19 14:58:07 +00:00
x = ( ( TICRATE - stplyr - > kartstuff [ k_cardanimation ] ) * ( xval > x ? xval : x ) ) / TICRATE ;
2018-07-20 11:37:09 +00:00
if ( splitscreen & & stplyr = = & players [ secondarydisplayplayer ] )
x = - x ;
V_DrawFixedPatch ( x + ( STCD_X < < FRACBITS ) - ( SHORT ( kp_racefinish [ pnum ] - > width ) < < ( scaleshift - 1 ) ) ,
( STCD_Y < < FRACBITS ) - ( SHORT ( kp_racefinish [ pnum ] - > height ) < < ( scaleshift - 1 ) ) ,
( 1 < < scaleshift ) ,
splitflags , kp_racefinish [ pnum ] , NULL ) ;
2018-07-19 14:58:07 +00:00
}
}
2017-11-17 05:48:36 +00:00
static void K_drawBattleFullscreen ( void )
2017-11-14 01:45:57 +00:00
{
2017-12-24 00:14:06 +00:00
INT32 x = BASEVIDWIDTH / 2 ;
2017-11-29 07:07:22 +00:00
INT32 y = - 64 + ( stplyr - > kartstuff [ k_cardanimation ] ) ; // card animation goes from 0 to 164, 164 is the middle of the screen
2018-03-27 22:22:33 +00:00
INT32 splitflags = V_SNAPTOTOP ; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead
2017-12-25 15:05:36 +00:00
fixed_t scale = FRACUNIT ;
2017-11-29 06:09:46 +00:00
2017-12-19 01:59:04 +00:00
if ( splitscreen )
2017-11-29 07:07:22 +00:00
{
2017-12-19 01:59:04 +00:00
if ( ( splitscreen = = 1 & & stplyr = = & players [ secondarydisplayplayer ] )
2018-03-27 22:22:33 +00:00
| | ( splitscreen > 1 & & ( stplyr = = & players [ thirddisplayplayer ]
| | ( stplyr = = & players [ fourthdisplayplayer ] & & splitscreen > 2 ) ) ) )
{
2017-11-29 07:07:22 +00:00
y = 232 - ( stplyr - > kartstuff [ k_cardanimation ] / 2 ) ;
2018-03-27 22:22:33 +00:00
splitflags = V_SNAPTOBOTTOM ;
}
2017-11-29 07:07:22 +00:00
else
y = - 32 + ( stplyr - > kartstuff [ k_cardanimation ] / 2 ) ;
2017-11-14 01:45:57 +00:00
2017-12-24 00:14:06 +00:00
if ( splitscreen > 1 )
2017-11-17 05:48:36 +00:00
{
2017-12-28 23:37:25 +00:00
scale / = 2 ;
2018-03-27 22:22:33 +00:00
if ( stplyr = = & players [ secondarydisplayplayer ]
| | ( stplyr = = & players [ fourthdisplayplayer ] & & splitscreen > 2 ) )
2017-12-24 00:14:06 +00:00
x = 3 * BASEVIDWIDTH / 4 ;
2017-11-17 05:48:36 +00:00
else
2017-12-24 00:14:06 +00:00
x = BASEVIDWIDTH / 4 ;
2017-11-17 05:48:36 +00:00
}
2017-11-14 01:45:57 +00:00
else
2017-11-17 05:48:36 +00:00
{
2017-12-24 00:14:06 +00:00
if ( stplyr = = & players [ secondarydisplayplayer ] )
x = BASEVIDWIDTH - 96 ;
2017-11-17 05:48:36 +00:00
else
2017-12-24 00:14:06 +00:00
x = 96 ;
2017-11-17 05:48:36 +00:00
}
2017-11-14 01:45:57 +00:00
}
2017-12-24 00:14:06 +00:00
if ( stplyr - > exiting )
{
2017-12-25 15:05:36 +00:00
if ( stplyr = = & players [ displayplayer ] )
2018-06-26 14:14:59 +00:00
V_DrawFadeScreen ( 0xFF00 , 16 ) ;
2018-07-19 14:58:07 +00:00
if ( stplyr - > exiting < 6 * TICRATE )
{
if ( stplyr - > kartstuff [ k_position ] = = 1 )
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , scale , splitflags , kp_battlewin , NULL ) ;
else if ( splitscreen < 2 )
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , scale , splitflags , ( K_IsPlayerLosing ( stplyr ) ? kp_battlelose : kp_battlecool ) , NULL ) ;
}
else
K_drawKartFinish ( ) ;
2017-12-24 00:14:06 +00:00
}
2018-07-03 19:14:47 +00:00
else if ( stplyr - > kartstuff [ k_bumper ] < = 0 & & stplyr - > kartstuff [ k_comebacktimer ] & & comeback )
2017-11-14 01:45:57 +00:00
{
2018-07-30 20:53:54 +00:00
UINT16 t = stplyr - > kartstuff [ k_comebacktimer ] / ( 10 * TICRATE ) ;
INT32 txoff , adjust = ( splitscreen > 1 ) ? 4 : 6 ; // normal string is 8, kart string is 12, half of that for ease
2017-12-25 15:05:36 +00:00
INT32 ty = ( BASEVIDHEIGHT / 2 ) + 66 ;
2017-11-17 05:48:36 +00:00
2018-07-30 20:53:54 +00:00
txoff = adjust ;
while ( t )
2017-11-17 05:48:36 +00:00
{
2018-07-30 20:53:54 +00:00
txoff + = adjust ;
t / = 10 ;
2017-11-17 05:48:36 +00:00
}
2017-12-25 15:05:36 +00:00
if ( splitscreen )
{
2018-07-19 14:58:07 +00:00
if ( splitscreen > 1 )
2017-12-25 15:05:36 +00:00
ty = ( BASEVIDHEIGHT / 4 ) + 33 ;
if ( ( splitscreen = = 1 & & stplyr = = & players [ secondarydisplayplayer ] )
2018-03-27 22:22:33 +00:00
| | ( stplyr = = & players [ thirddisplayplayer ] & & splitscreen > 1 )
| | ( stplyr = = & players [ fourthdisplayplayer ] & & splitscreen > 2 ) )
2017-12-25 15:05:36 +00:00
ty + = ( BASEVIDHEIGHT / 2 ) ;
}
2018-02-28 03:07:20 +00:00
else
2018-06-26 14:14:59 +00:00
V_DrawFadeScreen ( 0xFF00 , 16 ) ;
2017-12-25 15:05:36 +00:00
2018-02-08 22:13:06 +00:00
if ( ! comebackshowninfo )
2018-03-27 22:22:33 +00:00
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , scale , splitflags , kp_battleinfo , NULL ) ;
2017-11-14 01:45:57 +00:00
else
2018-03-27 22:22:33 +00:00
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , scale , splitflags , kp_battlewait , NULL ) ;
2017-11-29 07:07:22 +00:00
2017-12-24 01:55:23 +00:00
if ( splitscreen > 1 )
2018-07-30 20:53:54 +00:00
V_DrawString ( x - txoff , ty , 0 , va ( " %d " , stplyr - > kartstuff [ k_comebacktimer ] / TICRATE ) ) ;
2017-12-25 15:05:36 +00:00
else
{
2018-03-28 20:17:04 +00:00
V_DrawFixedPatch ( x < < FRACBITS , ty < < FRACBITS , scale , 0 , kp_timeoutsticker , NULL ) ;
2017-12-25 15:05:36 +00:00
V_DrawKartString ( x - txoff , ty , 0 , va ( " %d " , stplyr - > kartstuff [ k_comebacktimer ] / TICRATE ) ) ;
}
2017-11-14 01:45:57 +00:00
}
2018-07-22 15:16:03 +00:00
if ( netgame & & ! stplyr - > spectator & & timeinmap > 113 ) // FREE PLAY?
{
UINT8 i ;
// check to see if there's anyone else at all
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( i = = displayplayer )
continue ;
if ( playeringame [ i ] & & ! stplyr - > spectator )
return ;
}
K_drawKartFreePlay ( leveltime ) ;
}
2017-11-14 01:45:57 +00:00
}
2018-06-26 20:12:42 +00:00
static void K_drawKartFirstPerson ( void )
{
2018-07-18 00:23:22 +00:00
static INT32 pnum [ 4 ] , turn [ 4 ] , drift [ 4 ] ;
INT32 pn = 0 , tn = 0 , dr = 0 ;
INT32 target = 0 , splitflags = K_calcSplitFlags ( V_SNAPTOBOTTOM ) ;
2018-06-26 20:12:42 +00:00
INT32 x = BASEVIDWIDTH / 2 , y = BASEVIDHEIGHT ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
fixed_t scale ;
UINT8 * colmap = NULL ;
2018-06-26 20:12:42 +00:00
ticcmd_t * cmd = & stplyr - > cmd ;
2018-07-18 20:40:04 +00:00
if ( stplyr - > spectator | | ! stplyr - > mo | | ( stplyr - > mo - > flags2 & MF2_DONTDRAW ) )
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
return ;
2018-06-26 20:12:42 +00:00
if ( stplyr = = & players [ secondarydisplayplayer ] & & splitscreen )
2018-07-18 00:23:22 +00:00
{ pn = pnum [ 1 ] ; tn = turn [ 1 ] ; dr = drift [ 1 ] ; }
2018-06-26 20:12:42 +00:00
else if ( stplyr = = & players [ thirddisplayplayer ] & & splitscreen > 1 )
2018-07-18 00:23:22 +00:00
{ pn = pnum [ 2 ] ; tn = turn [ 2 ] ; dr = drift [ 2 ] ; }
2018-06-26 20:12:42 +00:00
else if ( stplyr = = & players [ fourthdisplayplayer ] & & splitscreen > 2 )
2018-07-18 00:23:22 +00:00
{ pn = pnum [ 3 ] ; tn = turn [ 3 ] ; dr = drift [ 3 ] ; }
2018-06-26 20:12:42 +00:00
else
2018-07-18 00:23:22 +00:00
{ pn = pnum [ 0 ] ; tn = turn [ 0 ] ; dr = drift [ 0 ] ; }
2018-06-26 20:12:42 +00:00
if ( splitscreen )
{
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
y > > = 1 ;
2018-06-26 20:12:42 +00:00
if ( splitscreen > 1 )
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
x > > = 1 ;
2018-06-26 20:12:42 +00:00
}
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
{
if ( stplyr - > speed < FixedMul ( stplyr - > runspeed , stplyr - > mo - > scale ) & & ( leveltime & 1 ) & & ! splitscreen )
y + + ;
2018-07-19 15:07:14 +00:00
// the following isn't EXPLICITLY right, it just gets the result we want, but i'm too lazy to look up the right way to do it
if ( stplyr - > mo - > flags2 & MF2_SHADOW )
splitflags | = FF_TRANS80 ;
else if ( stplyr - > mo - > frame & FF_TRANSMASK )
splitflags | = ( stplyr - > mo - > frame & FF_TRANSMASK ) ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
}
2018-06-26 20:12:42 +00:00
if ( cmd - > driftturn > 400 ) // strong left turn
target = 2 ;
else if ( cmd - > driftturn < - 400 ) // strong right turn
target = - 2 ;
else if ( cmd - > driftturn > 0 ) // weak left turn
target = 1 ;
else if ( cmd - > driftturn < 0 ) // weak right turn
target = - 1 ;
else // forward
target = 0 ;
2018-07-22 15:16:03 +00:00
if ( mirrormode )
target = - target ;
2018-06-26 20:12:42 +00:00
if ( pn < target )
pn + + ;
else if ( pn > target )
pn - - ;
if ( pn < 0 )
splitflags | = V_FLIP ; // right turn
2018-07-15 22:13:36 +00:00
target = abs ( pn ) ;
if ( target > 2 )
target = 2 ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
x < < = FRACBITS ;
y < < = FRACBITS ;
2018-07-18 00:23:22 +00:00
if ( tn ! = cmd - > driftturn / 50 )
tn - = ( tn - ( cmd - > driftturn / 50 ) ) / 8 ;
if ( dr ! = stplyr - > kartstuff [ k_drift ] * 16 )
dr - = ( dr - ( stplyr - > kartstuff [ k_drift ] * 16 ) ) / 8 ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
if ( splitscreen = = 1 )
{
scale = ( 2 * FRACUNIT ) / 3 ;
y + = FRACUNIT / ( vid . dupx < vid . dupy ? vid . dupx : vid . dupy ) ; // correct a one-pixel gap on the screen view (not the basevid view)
}
else if ( splitscreen )
scale = FRACUNIT / 2 ;
2018-06-26 20:12:42 +00:00
else
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
scale = FRACUNIT ;
if ( stplyr - > mo )
{
fixed_t dsone = K_GetKartDriftSparkValue ( stplyr ) ;
fixed_t dstwo = dsone * 2 ;
# ifndef DONTLIKETOASTERSFPTWEAKS
{
2018-07-18 00:23:22 +00:00
const angle_t ang = R_PointToAngle2 ( 0 , 0 , stplyr - > rmomx , stplyr - > rmomy ) - stplyr - > frameangle ;
// yes, the following is correct. no, you do not need to swap the x and y.
fixed_t xoffs = - P_ReturnThrustY ( stplyr - > mo , ang , ( BASEVIDWIDTH < < ( FRACBITS - 2 ) ) / 2 ) ;
fixed_t yoffs = - ( P_ReturnThrustX ( stplyr - > mo , ang , 4 * FRACUNIT ) - 4 * FRACUNIT ) ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
if ( splitscreen )
xoffs = FixedMul ( xoffs , scale ) ;
2018-07-18 00:23:22 +00:00
xoffs - = ( tn ) * scale ;
xoffs - = ( dr ) * scale ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
if ( stplyr - > frameangle = = stplyr - > mo - > angle )
{
const fixed_t mag = FixedDiv ( stplyr - > speed , 10 * stplyr - > mo - > scale ) ;
if ( mag < FRACUNIT )
{
xoffs = FixedMul ( xoffs , mag ) ;
if ( ! splitscreen )
yoffs = FixedMul ( yoffs , mag ) ;
}
}
2018-07-18 00:23:22 +00:00
if ( stplyr - > mo - > momz > 0 ) // TO-DO: Draw more of the kart so we can remove this if!
yoffs + = stplyr - > mo - > momz / 3 ;
2018-07-22 15:16:03 +00:00
if ( mirrormode )
x - = xoffs ;
else
x + = xoffs ;
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
if ( ! splitscreen )
y + = yoffs ;
}
// drift sparks!
if ( ( leveltime & 1 ) & & ( stplyr - > kartstuff [ k_driftcharge ] > = dstwo ) )
colmap = R_GetTranslationColormap ( TC_RAINBOW , SKINCOLOR_TANGERINE , 0 ) ;
else if ( ( leveltime & 1 ) & & ( stplyr - > kartstuff [ k_driftcharge ] > = dsone ) )
colmap = R_GetTranslationColormap ( TC_RAINBOW , SKINCOLOR_SAPPHIRE , 0 ) ;
else
# endif
// invincibility/grow/shrink!
if ( stplyr - > mo - > colorized & & stplyr - > mo - > color )
colmap = R_GetTranslationColormap ( TC_RAINBOW , stplyr - > mo - > color , 0 ) ;
}
V_DrawFixedPatch ( x , y , scale , splitflags , kp_fpview [ target ] , colmap ) ;
2018-06-26 20:12:42 +00:00
if ( stplyr = = & players [ secondarydisplayplayer ] & & splitscreen )
2018-07-18 00:23:22 +00:00
{ pnum [ 1 ] = pn ; turn [ 1 ] = tn ; drift [ 1 ] = dr ; }
2018-06-26 20:12:42 +00:00
else if ( stplyr = = & players [ thirddisplayplayer ] & & splitscreen > 1 )
2018-07-18 00:23:22 +00:00
{ pnum [ 2 ] = pn ; turn [ 2 ] = tn ; drift [ 2 ] = dr ; }
2018-06-26 20:12:42 +00:00
else if ( stplyr = = & players [ fourthdisplayplayer ] & & splitscreen > 2 )
2018-07-18 00:23:22 +00:00
{ pnum [ 3 ] = pn ; turn [ 3 ] = tn ; drift [ 3 ] = dr ; }
2018-06-26 20:12:42 +00:00
else
2018-07-18 00:23:22 +00:00
{ pnum [ 0 ] = pn ; turn [ 0 ] = tn ; drift [ 0 ] = dr ; }
2018-06-26 20:12:42 +00:00
}
2018-07-15 22:13:36 +00:00
// doesn't need to ever support 4p
static void K_drawInput ( void )
{
static INT32 pn = 0 ;
INT32 target = 0 , splitflags = ( V_SNAPTOBOTTOM | V_SNAPTORIGHT ) ;
INT32 x = BASEVIDWIDTH - 32 , y = BASEVIDHEIGHT - 24 , offs , col ;
const INT32 accent1 = splitflags | colortranslations [ stplyr - > skincolor ] [ 5 ] ;
const INT32 accent2 = splitflags | colortranslations [ stplyr - > skincolor ] [ 9 ] ;
ticcmd_t * cmd = & stplyr - > cmd ;
if ( timeinmap < = 105 )
return ;
if ( timeinmap < 113 )
{
INT32 count = ( ( INT32 ) ( timeinmap ) - 105 ) ;
offs = 64 ;
while ( count - - > 0 )
offs > > = 1 ;
x + = offs ;
}
# define BUTTW 8
# define BUTTH 11
# define drawbutt(xoffs, butt, symb)\
if ( stplyr - > cmd . buttons & butt ) \
{ \
offs = 2 ; \
col = accent1 ; \
} \
else \
{ \
offs = 0 ; \
col = accent2 ; \
V_DrawFill ( x + ( xoffs ) , y + BUTTH , BUTTW - 1 , 2 , splitflags | 31 ) ; \
} \
V_DrawFill ( x + ( xoffs ) , y + offs , BUTTW - 1 , BUTTH , col ) ; \
V_DrawFixedPatch ( ( x + 1 + ( xoffs ) ) < < FRACBITS , ( y + offs + 1 ) < < FRACBITS , FRACUNIT , splitflags , tny_font [ symb - HU_FONTSTART ] , NULL )
drawbutt ( - 2 * BUTTW , BT_ACCELERATE , ' A ' ) ;
drawbutt ( - BUTTW , BT_BRAKE , ' B ' ) ;
drawbutt ( 0 , BT_DRIFT , ' D ' ) ;
drawbutt ( BUTTW , BT_ATTACK , ' I ' ) ;
# undef drawbutt
2018-08-09 21:59:52 +00:00
# undef BUTTW
# undef BUTTH
2018-07-15 22:13:36 +00:00
y - = 1 ;
if ( ! cmd - > driftturn ) // no turn
target = 0 ;
else // turning of multiple strengths!
{
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
target = ( ( abs ( cmd - > driftturn ) - 1 ) / 125 ) + 1 ;
2018-07-15 22:13:36 +00:00
if ( target > 4 )
target = 4 ;
if ( cmd - > driftturn < 0 )
target = - target ;
}
if ( pn ! = target )
{
if ( abs ( pn - target ) = = 1 )
pn = target ;
else if ( pn < target )
pn + = 2 ;
else //if (pn > target)
pn - = 2 ;
}
if ( pn < 0 )
{
splitflags | = V_FLIP ; // right turn
x - - ;
}
target = abs ( pn ) ;
if ( target > 4 )
target = 4 ;
if ( ! stplyr - > skincolor )
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , FRACUNIT , splitflags , kp_inputwheel [ target ] , NULL ) ;
else
{
UINT8 * colormap ;
colormap = R_GetTranslationColormap ( 0 , stplyr - > skincolor , 0 ) ;
V_DrawFixedPatch ( x < < FRACBITS , y < < FRACBITS , FRACUNIT , splitflags , kp_inputwheel [ target ] , colormap ) ;
}
}
2018-07-22 04:31:02 +00:00
static void K_drawChallengerScreen ( void )
{
// This is an insanely complicated animation.
static UINT8 anim [ 52 ] = {
0 , 0 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 4 , 5 , 5 , 6 , 6 , 7 , 7 , 8 , 8 , 9 , 9 , 10 , 10 , 11 , 11 , 12 , 12 , 13 , 13 , // frame 1-14, 2 tics: HERE COMES A NEW slides in
14 , 14 , 14 , 14 , 14 , 14 , // frame 15, 6 tics: pause on the W
15 , 16 , 17 , 18 , // frame 16-19, 1 tic: CHALLENGER approaches screen
19 , 20 , 19 , 20 , 19 , 20 , 19 , 20 , 19 , 20 , // frame 20-21, 1 tic, 5 alternating: all text vibrates from impact
21 , 22 , 23 , 24 // frame 22-25, 1 tic: CHALLENGER turns gold
} ;
const UINT8 offset = min ( 52 - 1 , ( 3 * TICRATE ) - mapreset ) ;
V_DrawFadeScreen ( 0xFF00 , 16 ) ; // Fade out
V_DrawScaledPatch ( 0 , 0 , 0 , kp_challenger [ anim [ offset ] ] ) ;
}
2018-08-10 01:52:02 +00:00
static void K_drawLapStartAnim ( void )
2018-06-17 22:10:42 +00:00
{
2018-08-10 01:52:02 +00:00
// This is an EVEN MORE insanely complicated animation.
const UINT8 progress = 80 - stplyr - > kartstuff [ k_lapanimation ] ;
V_DrawScaledPatch ( BASEVIDWIDTH / 2 + ( 32 * max ( 0 , stplyr - > kartstuff [ k_lapanimation ] - 76 ) ) ,
64 - ( 32 * max ( 0 , progress - 76 ) ) ,
0 , kp_lapanim_emblem ) ;
if ( stplyr - > laps = = ( UINT8 ) ( cv_numlaps . value - 1 ) )
{
V_DrawScaledPatch ( 27 - ( 32 * max ( 0 , progress - 76 ) ) ,
40 ,
0 , kp_lapanim_final [ min ( progress / 2 , 10 ) ] ) ;
if ( progress / 2 - 12 > = 0 )
{
V_DrawScaledPatch ( 194 + ( 32 * max ( 0 , progress - 76 ) ) ,
40 ,
0 , kp_lapanim_lap [ min ( progress / 2 - 12 , 6 ) ] ) ;
}
}
2018-06-17 22:10:42 +00:00
else
2018-08-10 01:52:02 +00:00
{
V_DrawScaledPatch ( 61 - ( 32 * max ( 0 , progress - 76 ) ) ,
40 ,
0 , kp_lapanim_lap [ min ( progress / 2 , 6 ) ] ) ;
if ( progress / 2 - 8 > = 0 )
{
V_DrawScaledPatch ( 194 + ( 32 * max ( 0 , progress - 76 ) ) ,
40 ,
0 , kp_lapanim_number [ ( ( ( UINT32 ) stplyr - > laps + 1 ) / 10 ) ] [ min ( progress / 2 - 8 , 2 ) ] ) ;
if ( progress / 2 - 10 > = 0 )
{
V_DrawScaledPatch ( 221 + ( 32 * max ( 0 , progress - 76 ) ) ,
40 ,
0 , kp_lapanim_number [ ( ( ( UINT32 ) stplyr - > laps + 1 ) % 10 ) ] [ min ( progress / 2 - 10 , 2 ) ] ) ;
}
}
}
2018-06-17 22:10:42 +00:00
}
2018-07-22 15:16:03 +00:00
void K_drawKartFreePlay ( UINT32 flashtime )
{
2018-07-30 20:53:54 +00:00
// no splitscreen support because it's not FREE PLAY if you have more than one player in-game
2018-07-22 15:16:03 +00:00
if ( ( flashtime % TICRATE ) < TICRATE / 2 )
return ;
2018-07-30 20:53:54 +00:00
V_DrawKartString ( ( BASEVIDWIDTH - ( LAPS_X + 1 ) ) - ( 12 * 9 ) , // mirror the laps thingy
LAPS_Y + 3 , V_SNAPTOBOTTOM | V_SNAPTORIGHT , " FREE PLAY " ) ;
2018-07-22 15:16:03 +00:00
}
2018-08-29 18:28:28 +00:00
static void K_drawDistributionDebugger ( void )
{
patch_t * items [ NUMKARTRESULTS ] = {
kp_sadface [ 1 ] ,
kp_sneaker [ 1 ] ,
kp_rocketsneaker [ 1 ] ,
kp_invincibility [ 7 ] ,
kp_banana [ 1 ] ,
kp_eggman [ 1 ] ,
kp_orbinaut [ 4 ] ,
kp_jawz [ 1 ] ,
kp_mine [ 1 ] ,
kp_ballhog [ 1 ] ,
kp_selfpropelledbomb [ 1 ] ,
kp_grow [ 1 ] ,
kp_shrink [ 1 ] ,
kp_thundershield [ 1 ] ,
kp_hyudoro [ 1 ] ,
kp_pogospring [ 1 ] ,
kp_kitchensink [ 1 ] ,
kp_sneaker [ 1 ] ,
kp_banana [ 1 ] ,
kp_banana [ 1 ] ,
kp_orbinaut [ 4 ] ,
kp_orbinaut [ 4 ] ,
kp_jawz [ 1 ]
} ;
INT32 useodds = 0 ;
INT32 pingame = 0 , bestbumper = 0 ;
INT32 i ;
INT32 x = - 9 , y = - 9 ;
if ( stplyr ! = & players [ displayplayer ] ) // only for p1
return ;
// The only code duplication from the Kart, just to avoid the actual item function from calculating pingame twice
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( ! playeringame [ i ] | | players [ i ] . spectator )
continue ;
pingame + + ;
if ( players [ i ] . kartstuff [ k_bumper ] > bestbumper )
bestbumper = players [ i ] . kartstuff [ k_bumper ] ;
}
useodds = K_FindUseodds ( stplyr , 0 , pingame , bestbumper ) ;
for ( i = 1 ; i < NUMKARTRESULTS ; i + + )
{
const INT32 itemodds = K_KartGetItemOdds ( useodds , i , 0 ) ;
if ( itemodds < = 0 )
continue ;
V_DrawScaledPatch ( x , y , V_HUDTRANS | V_SNAPTOTOP , items [ i ] ) ;
V_DrawThinString ( x + 11 , y + 31 , V_HUDTRANS | V_SNAPTOTOP , va ( " %d " , itemodds ) ) ;
// Display amount for multi-items
if ( i > = NUMKARTITEMS )
{
INT32 amount ;
switch ( i )
{
case KRITEM_TENFOLDBANANA :
amount = 10 ;
break ;
case KRITEM_QUADORBINAUT :
amount = 4 ;
break ;
case KRITEM_DUALJAWZ :
amount = 2 ;
break ;
default :
amount = 3 ;
break ;
}
V_DrawString ( x + 24 , y + 31 , V_ALLOWLOWERCASE | V_HUDTRANS | V_SNAPTOTOP , va ( " x%d " , amount ) ) ;
}
x + = 32 ;
if ( x > = 297 )
{
x = - 9 ;
y + = 32 ;
}
}
V_DrawString ( 0 , 0 , V_HUDTRANS | V_SNAPTOTOP , va ( " USEODDS %d " , useodds ) ) ;
}
2018-08-10 01:52:02 +00:00
static void K_drawCheckpointDebugger ( void )
{
2018-08-29 18:28:28 +00:00
if ( stplyr ! = & players [ displayplayer ] ) // only for p1
return ;
2018-08-10 01:52:02 +00:00
if ( ( numstarposts / 2 + stplyr - > starpostnum ) > = numstarposts )
V_DrawString ( 8 , 184 , 0 , va ( " Checkpoint: %d / %d (Can finish) " , stplyr - > starpostnum , numstarposts ) ) ;
else
V_DrawString ( 8 , 184 , 0 , va ( " Checkpoint: %d / %d (Skip: %d) " , stplyr - > starpostnum , numstarposts , ( numstarposts / 2 + stplyr - > starpostnum ) ) ) ;
V_DrawString ( 8 , 192 , 0 , va ( " Waypoint dist: Prev %d, Next %d " , stplyr - > kartstuff [ k_prevcheck ] , stplyr - > kartstuff [ k_nextcheck ] ) ) ;
}
2016-08-15 03:51:08 +00:00
void K_drawKartHUD ( void )
{
2018-07-22 15:16:03 +00:00
boolean isfreeplay = false ;
2016-08-15 03:51:08 +00:00
// Define the X and Y for each drawn object
// This is handled by console/menu values
K_initKartHUD ( ) ;
2017-02-17 20:14:55 +00:00
2018-07-01 03:35:38 +00:00
// Draw that fun first person HUD! Drawn ASAP so it looks more "real".
2018-06-26 20:12:42 +00:00
if ( ( stplyr = = & players [ displayplayer ] & & ! camera . chase )
| | ( ( splitscreen & & stplyr = = & players [ secondarydisplayplayer ] ) & & ! camera2 . chase )
| | ( ( splitscreen > 1 & & stplyr = = & players [ thirddisplayplayer ] ) & & ! camera3 . chase )
| | ( ( splitscreen > 2 & & stplyr = = & players [ fourthdisplayplayer ] ) & & ! camera4 . chase ) )
K_drawKartFirstPerson ( ) ;
2018-06-26 15:33:54 +00:00
// Draw a white fade on level opening
if ( leveltime < 15 & & stplyr = = & players [ displayplayer ] )
2018-06-26 14:14:59 +00:00
{
2018-06-28 14:47:56 +00:00
if ( leveltime < = 5 )
2018-07-01 03:35:38 +00:00
V_DrawFill ( 0 , 0 , BASEVIDWIDTH , BASEVIDHEIGHT , 120 ) ; // Pure white on first few frames, to hide SRB2's awful level load artifacts
2018-06-26 14:14:59 +00:00
else
V_DrawFadeScreen ( 120 , 15 - leveltime ) ; // Then gradually fade out from there
}
2018-06-26 15:33:54 +00:00
if ( splitscreen = = 2 ) // Player 4 in 3P is the minimap :p
2018-03-28 19:28:50 +00:00
K_drawKartMinimap ( ) ;
2017-11-14 01:45:57 +00:00
// Draw full screen stuff that turns off the rest of the HUD
2018-07-22 04:31:02 +00:00
if ( mapreset )
{
K_drawChallengerScreen ( ) ;
return ;
}
2018-03-04 20:27:52 +00:00
if ( ( G_BattleGametype ( ) )
2017-12-18 01:42:17 +00:00
& & ( stplyr - > exiting
2018-07-03 19:14:47 +00:00
| | ( stplyr - > kartstuff [ k_bumper ] < = 0
2017-12-18 01:42:17 +00:00
& & stplyr - > kartstuff [ k_comebacktimer ]
Lots of changes
- Menus now have all of the Kart cvars
- Removed any cvars that aren't useful for Kart from the menu (they
still exist in the console, though)
- Removed SP and NiGHTS Mode options from the main menu
- "kartcc" is renamed "kartspeed", uses values 0-2 instead of multiples
of 50, or the terms "Relaxed", "Standard", and "Turbo"
- Many gametype options (game speed, frantic, mirror, & karma comeback)
are now changed on map load instead of instantly
- New cvar, "kartminimap", for disabling the minimap
- The maxplayers cvar now actually matches up with our 16 player limit
- Game now keeps track of matches played. Has a condition type
associated with it, as well.
- Game checks for unlocks and saves gamedata when finishing a match,
even in MP
- Removed most of the normal emblems, added a single emblem for Green
Hills. Didn't know what to do with extra emblems and such so I just left
them (FOR NOW c:<)
2018-01-16 03:31:14 +00:00
& & comeback
2017-12-18 01:42:17 +00:00
& & stplyr - > playerstate = = PST_LIVE ) ) )
2017-11-14 01:45:57 +00:00
{
2017-11-17 05:48:36 +00:00
K_drawBattleFullscreen ( ) ;
return ;
2017-11-14 01:45:57 +00:00
}
2018-06-25 02:15:22 +00:00
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
2018-07-02 00:55:01 +00:00
if ( cv_kartcheck . value & & ! splitscreen & & ! players [ displayplayer ] . exiting )
2018-06-25 02:15:22 +00:00
K_drawKartPlayerCheck ( ) ;
2017-12-22 21:24:20 +00:00
2018-03-27 22:22:33 +00:00
if ( splitscreen = = 0 & & cv_kartminimap . value )
K_drawKartMinimap ( ) ; // 3P splitscreen is handled above
2017-12-18 01:42:17 +00:00
2018-02-05 23:55:52 +00:00
// Draw the item window
K_drawKartItem ( ) ;
2017-10-22 07:06:35 +00:00
2018-07-01 08:36:09 +00:00
// Draw WANTED status
if ( G_BattleGametype ( ) )
K_drawKartWanted ( ) ;
2017-12-18 01:42:17 +00:00
// If not splitscreen, draw...
2017-12-27 02:36:03 +00:00
if ( ! splitscreen )
2017-12-18 01:42:17 +00:00
{
2017-12-27 02:36:03 +00:00
// Draw the timestamp
K_drawKartTimestamp ( ) ;
2017-12-22 15:16:41 +00:00
if ( ! modeattacking )
{
// The top-four faces on the left
2018-07-22 15:16:03 +00:00
isfreeplay = K_drawKartPositionFaces ( ) ;
2017-12-22 15:16:41 +00:00
}
}
2018-01-23 03:18:57 +00:00
if ( ! stplyr - > spectator ) // Bottom of the screen elements, don't need in spectate mode
2017-11-23 02:40:17 +00:00
{
2018-03-04 20:27:52 +00:00
if ( G_RaceGametype ( ) ) // Race-only elements
2017-12-28 23:37:25 +00:00
{
2018-01-23 03:18:57 +00:00
// Draw the lap counter
K_drawKartLaps ( ) ;
2017-12-28 23:37:25 +00:00
2018-01-23 03:18:57 +00:00
if ( ! splitscreen )
{
// Draw the speedometer
// TODO: Make a better speedometer.
K_drawKartSpeedometer ( ) ;
}
2018-07-22 15:16:03 +00:00
if ( isfreeplay )
;
else if ( ! modeattacking )
2018-01-23 03:18:57 +00:00
{
// Draw the numerical position
K_DrawKartPositionNum ( stplyr - > kartstuff [ k_position ] ) ;
}
2018-07-22 15:16:03 +00:00
else //if (!(demoplayback && hu_showscores))
{
// Draw the input UI
K_drawInput ( ) ;
}
2018-06-06 01:36:48 +00:00
// You're about to DIEEEEE
2018-06-07 23:39:45 +00:00
K_drawSPBWarning ( ) ;
2018-01-23 03:18:57 +00:00
}
2018-03-04 20:27:52 +00:00
else if ( G_BattleGametype ( ) ) // Battle-only
2017-12-24 00:14:06 +00:00
{
2018-01-23 03:18:57 +00:00
// Draw the hits left!
2018-07-03 19:14:47 +00:00
K_drawKartBumpersOrKarma ( ) ;
2017-12-24 00:14:06 +00:00
}
2016-08-15 03:51:08 +00:00
}
2018-06-17 22:10:42 +00:00
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
// Draw the countdowns after everything else.
2018-06-25 02:15:22 +00:00
if ( leveltime > = starttime - ( 3 * TICRATE )
& & leveltime < starttime + TICRATE )
2018-07-19 14:58:07 +00:00
K_drawKartStartCountdown ( ) ;
2018-07-18 00:21:36 +00:00
else if ( countdown & & ( ! splitscreen | | ! stplyr - > exiting ) )
Mammoth commit!
* Deaths in record attack no longer put you into a glitchy singleplayer game-over state that we somehow both kept around and also broke since we branched Kart off of Vanilla..
* Fix non-standard mapscales making the Death Egg respawn octagons dissasemble themselves.
* Allow for MULTIPLE TIME EMBLEMS PER MAP, at least in the emblem UI on the timer. It shows all completed emblems plus the uncompleted emblem up to a total of three.
* Major tweaks to the First Person HUD.
* I know this was your baby, Sal, and some of the changes may prove controversial - so I've put the ones that are likely to cause the most fuss inside an ifndef block, so that you can toggle it as you please with minimal code changes.
* Dontdraw-ness, transparency, and colorization match the player's object!
* Moves around on the screen with respect to the direction of the player object's motion, to make drifting look nicer!
* Flashes the colour of your drift sparks.
* Did a WHOLE bunch of things with respect to music. I'm not sure how to describe this, so I'll go through step-by-step.
* Countdowns now play the drowning music again.
* Removed/disabled extraenous P_RestoreMusics.
* Made map-ending music called by its own function, P_EndingMusic(player_t *player).
* Made the ending music play on the LAST player crossing the finishing line in splitscreen, rather than first.
* Make dead players spinout and clip through the floor, at least until we add the new death anims.
* Fix prior pogo spring usage making dead players fall faster.
* Make the time over countdown use the kart font when not splitscreen with 3 or 4 players.
* Removed a weird bonus HWR_DrawCroppedPatch function signature in the hardware header.
2018-07-16 19:19:30 +00:00
{
char * countstr = va ( " %d " , countdown / TICRATE ) ;
if ( splitscreen > 1 )
V_DrawCenteredString ( BASEVIDWIDTH / 4 , LAPS_Y + 1 , K_calcSplitFlags ( 0 ) , countstr ) ;
else
{
INT32 karlen = strlen ( countstr ) * 6 ; // half of 12
V_DrawKartString ( ( BASEVIDWIDTH / 2 ) - karlen , LAPS_Y + 3 , K_calcSplitFlags ( 0 ) , countstr ) ;
}
}
2018-06-25 02:15:22 +00:00
2018-08-10 01:52:02 +00:00
// Race overlays
if ( G_RaceGametype ( ) )
{
if ( stplyr - > exiting )
K_drawKartFinish ( ) ;
else if ( stplyr - > kartstuff [ k_lapanimation ] & & ! splitscreen )
K_drawLapStartAnim ( ) ;
}
2018-07-22 15:16:03 +00:00
// Draw FREE PLAY.
if ( isfreeplay & & ! stplyr - > spectator & & timeinmap > 113 )
K_drawKartFreePlay ( leveltime ) ;
2018-08-10 01:52:02 +00:00
2018-08-29 18:28:28 +00:00
if ( cv_kartdebugdistribution . value )
K_drawDistributionDebugger ( ) ;
2018-08-10 01:52:02 +00:00
if ( cv_kartdebugcheckpoint . value )
K_drawCheckpointDebugger ( ) ;
2016-08-15 03:51:08 +00:00
}
2016-08-12 01:42:11 +00:00
2016-08-15 03:51:08 +00:00
//}