diff --git a/src/common/GameMode.h b/src/common/GameMode.h index 1755116d..010eeefd 100644 --- a/src/common/GameMode.h +++ b/src/common/GameMode.h @@ -122,4 +122,9 @@ class CGameMode bool fReverseScoring; }; +void RemovePlayersButTeam(short teamid); +bool RemoveTeam(short teamid); +void SetupScoreBoard(bool fOrderMatters); +void ShowScoreBoard(); + #endif // GAMEMODE_H diff --git a/src/smw/CMakeLists.txt b/src/smw/CMakeLists.txt index 4cef1029..03b8d448 100644 --- a/src/smw/CMakeLists.txt +++ b/src/smw/CMakeLists.txt @@ -177,11 +177,20 @@ target_sources(smw PRIVATE menu/network/NetRoomMenu.cpp menu/network/NetRoomMenu.h menu/network/NetServersMenu.cpp - menu/network/NetServersMenu.h + menu/network/NetServersMenu.h + + gamemodes/MiniBoss.h + gamemodes/MiniBoss.cpp + gamemodes/MiniBoxes.h + gamemodes/MiniBoxes.cpp + gamemodes/MiniPipe.h + gamemodes/MiniPipe.cpp ) add_subdirectory(ui) +target_compile_features(smw PUBLIC cxx_std_14) + if(NO_NETWORK) target_compile_definitions(smw PRIVATE NETWORK_DISABLED) else() diff --git a/src/smw/GSGameplay.cpp b/src/smw/GSGameplay.cpp index 6d160e84..5193d373 100644 --- a/src/smw/GSGameplay.cpp +++ b/src/smw/GSGameplay.cpp @@ -17,6 +17,7 @@ #include "ResourceManager.h" #include "Score.h" #include "sfx.h" +#include "gamemodes/MiniBoss.h" #include #include diff --git a/src/smw/GSMenu.cpp b/src/smw/GSMenu.cpp index 0ccabc6f..e5ae1fcc 100644 --- a/src/smw/GSMenu.cpp +++ b/src/smw/GSMenu.cpp @@ -10,6 +10,9 @@ #include "MapList.h" #include "ResourceManager.h" #include "Score.h" +#include "gamemodes/MiniBoss.h" +#include "gamemodes/MiniBoxes.h" +#include "gamemodes/MiniPipe.h" #include "ui/MI_BonusWheel.h" #include "ui/MI_MapBrowser.h" #include "ui/MI_MapField.h" diff --git a/src/smw/gamemodes.cpp b/src/smw/gamemodes.cpp index 649eb56c..e64ecffd 100644 --- a/src/smw/gamemodes.cpp +++ b/src/smw/gamemodes.cpp @@ -3045,190 +3045,6 @@ CPlayer * CGM_Chase::GetKeyHolder() } -//Boss Mode -//Person to score fatal hit to boss wins! -CGM_Boss_MiniGame::CGM_Boss_MiniGame() : CGameMode() -{ - gamemode = game_mode_boss_minigame; - SetupModeStrings("Boss", "Lives", 5); - iBossType = 0; -} - -void CGM_Boss_MiniGame::init() -{ - CGameMode::init(); - - fReverseScoring = false; - - enemytimer = (short)(RANDOM_INT(120) + 120); - poweruptimer = 120; - - for (short iScore = 0; iScore < score_cnt; iScore++) - score[iScore]->SetScore(goal); - - objectcontainer[0].add(new MO_SledgeBrother(&rm->spr_sledgebrothers, (iBossType == 0 ? 256 : (iBossType == 1 ? 256 : smw->ScreenWidth/2)), iBossType)); -} - - -void CGM_Boss_MiniGame::think() -{ - if (!gameover && list_players_cnt == 0) { - gameover = true; - - if (game_values.music) { - ifsoundonstop(rm->sfx_invinciblemusic); - ifsoundonstop(rm->sfx_timewarning); - ifsoundonstop(rm->sfx_slowdownmusic); - ifSoundOnPlay(rm->sfx_gameover); - - rm->backgroundmusic[1].stop(); - } - } - - if (gameover) { - displayplayertext(); - } else { - if (iBossType == 0) { - //Randomly spawn koopas - if (--enemytimer <= 0) { - objectcontainer[0].add(new MO_Koopa(&rm->spr_koopa, RANDOM_BOOL(), false, false, true)); - enemytimer = (short)RANDOM_INT(120) + 120; //Spawn koopas slowly - } - } else if (iBossType == 1) { - - } else if (iBossType == 2) { - //Only create podobos if the difficulty is moderate or greater - if (--enemytimer <= 0 && game_values.gamemodesettings.boss.difficulty >= 2) { - objectcontainer[2].add(new MO_Podobo(&rm->spr_podobo, (short)RANDOM_INT(smw->ScreenWidth * 0.95f), smw->ScreenHeight, -(float(RANDOM_INT(9)) / 2.0f) - 9.0f, -1, -1, -1, false)); - enemytimer = (short)(RANDOM_INT(80) + 60); - } - - if (--poweruptimer <= 0) { - poweruptimer = (short)(RANDOM_INT(80) + 60); - - if (objectcontainer[1].countTypes(object_frenzycard) < list_players_cnt) { - objectcontainer[1].add(new MO_FrenzyCard(&rm->spr_frenzycards, 0)); - } - } - } - } -} - -void CGM_Boss_MiniGame::draw_foreground() -{ - if (gameover) { - if (winningteam == -1) { - rm->game_font_large.drawCentered(smw->ScreenWidth/2, 96, "You Failed To Defeat"); - - if (iBossType == 0) - rm->game_font_large.drawCentered(smw->ScreenWidth/2, 118, "The Mighty Sledge Brother"); - else if (iBossType == 1) - rm->game_font_large.drawCentered(smw->ScreenWidth/2, 118, "The Mighty Bomb Brother"); - else if (iBossType == 2) - rm->game_font_large.drawCentered(smw->ScreenWidth/2, 118, "The Mighty Flame Brother"); - } - } -} - -PlayerKillType CGM_Boss_MiniGame::playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style) -{ - if (!gameover) { - other.Score().AdjustScore(-1); - - if (!playedwarningsound) { - short countscore = 0; - for (short k = 0; k < score_cnt; k++) - countscore += score[k]->score; - - if (countscore <= 2) - playwarningsound(); - } - - if (other.Score().score <= 0) { - RemoveTeam(other.getTeamID()); - return PlayerKillType::Removed; - } - } - - return PlayerKillType::Normal; -} - -PlayerKillType CGM_Boss_MiniGame::playerkilledself(CPlayer &player, KillStyle style) -{ - CGameMode::playerkilledself(player, style); - - if (!gameover) { - player.Score().AdjustScore(-1); - - if (!playedwarningsound) { - short countscore = 0; - for (short k = 0; k < score_cnt; k++) - countscore += score[k]->score; - - if (countscore <= 2) - playwarningsound(); - } - - if (player.Score().score <= 0) { - RemoveTeam(player.getTeamID()); - return PlayerKillType::Removed; - } - } - - return PlayerKillType::Normal; -} - -void CGM_Boss_MiniGame::playerextraguy(CPlayer &player, short iType) -{ - if (!gameover) - player.Score().AdjustScore(iType); -} - -bool CGM_Boss_MiniGame::SetWinner(CPlayer * player) -{ - winningteam = player->getTeamID(); - gameover = true; - - RemovePlayersButTeam(winningteam); - - for (short iScore = 0; iScore < score_cnt; iScore++) { - if (winningteam == iScore) - continue; - - score[iScore]->SetScore(0); - } - - SetupScoreBoard(false); - ShowScoreBoard(); - - if (game_values.music) { - ifsoundonstop(rm->sfx_invinciblemusic); - ifsoundonstop(rm->sfx_timewarning); - ifsoundonstop(rm->sfx_slowdownmusic); - - rm->backgroundmusic[1].play(true, false); - } - - //game_values.noexit = true; - - /* - if (iBossType == 0) - objectcontainer[0].add(new PU_SledgeHammerPowerup(&rm->spr_sledgehammerpowerup, 304, -32, 1, 0, 30, 30, 1, 1)); - else if (iBossType == 1) - objectcontainer[0].add(new PU_BombPowerup(&rm->spr_bombpowerup, 304, -32, 1, 0, 30, 30, 1, 1)); - else if (iBossType == 2) - objectcontainer[0].add(new PU_PodoboPowerup(&rm->spr_podobopowerup, 304, -32, 1, 0, 30, 30, 1, 1)); - */ - - return true; -} - -void CGM_Boss_MiniGame::SetBossType(short bosstype) -{ - iBossType = bosstype; -} - - //Bonus Mode (not really a game mode, but involves using the map so we need a mode to play) CGM_Bonus::CGM_Bonus() : CGameMode() { @@ -3304,297 +3120,3 @@ void CGM_Bonus::draw_background() rm->game_font_large.drawChopCentered(smw->ScreenWidth/2, 132 + 24 * iTextLine, 372, tsTourStop->szBonusText[iTextLine]); } } - - -//Pipe Bonus Mini Game (used in world mode) -//Collect coins and powerups that come out of a pipe -CGM_Pipe_MiniGame::CGM_Pipe_MiniGame() : CGameMode() -{ - goal = 50; - gamemode = game_mode_pipe_minigame; - - SetupModeStrings("Pipe Minigame", "Points", 0); -}; - -void CGM_Pipe_MiniGame::init() -{ - CGameMode::init(); - - fReverseScoring = false; - - iNextItemTimer = 0; - iBonusTimer = 0; - iBonusType = 0; - iBonusTeam = 0; -} - - -void CGM_Pipe_MiniGame::think() -{ - if (gameover) { - displayplayertext(); - return; - } - - if (--iNextItemTimer <= 0) { - if (iBonusType == 0 || iBonusType == 2 || iBonusType == 4) { - if (iBonusType == 2) - iNextItemTimer = RANDOM_INT(10) + 10; - else - iNextItemTimer = RANDOM_INT(20) + 25; - - short iRandPowerup = RANDOM_INT(50); - if (iBonusType == 0 && iRandPowerup < 5) { //bonuses - objectcontainer[1].add(new OMO_PipeBonus(&rm->spr_pipegamebonus, (float)(RANDOM_INT(21) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, iRandPowerup, 620, 15)); - } else if (iRandPowerup < 10) { //fireballs - objectcontainer[1].add(new OMO_PipeBonus(&rm->spr_pipegamebonus, (float)(RANDOM_INT(21) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, 5, 0, 15)); - } else { //coins - short iRandCoin = RANDOM_INT(20); - objectcontainer[1].add(new OMO_PipeCoin(&rm->spr_coin, (float)(RANDOM_INT(21) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, -1, iRandCoin < 16 ? 2 : (iRandCoin < 19 ? 0 : 1), 15)); - } - } else if (iBonusType == 1) { - iNextItemTimer = RANDOM_INT(10) + 10; - - short iRandTeam = RANDOM_INT(score_cnt + 2); - - //Give an advantage to the team that got the item - if (iRandTeam >= score_cnt) - iRandTeam = iBonusTeam; - - short iRandPlayer = game_values.teamids[iRandTeam][RANDOM_INT(game_values.teamcounts[iRandTeam])]; - - objectcontainer[1].add(new OMO_PipeCoin(&rm->spr_coin, (float)((RANDOM_INT(21)) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, iRandTeam, game_values.colorids[iRandPlayer], 15)); - } else if (iBonusType == 3) { - iNextItemTimer = RANDOM_INT(5) + 10; - objectcontainer[1].add(new OMO_PipeCoin(&rm->spr_coin, (float)((RANDOM_INT(21)) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, -1, 0, 15)); - } - } - - if (iBonusTimer > 0 && --iBonusTimer <= 0) { - iBonusType = 0; - fSlowdown = false; - } -} - -PlayerKillType CGM_Pipe_MiniGame::playerkilledplayer(CPlayer &player, CPlayer &other, KillStyle style) -{ - //other.Score().AdjustScore(-2); - return PlayerKillType::Normal; -} - -PlayerKillType CGM_Pipe_MiniGame::playerkilledself(CPlayer &player, KillStyle style) -{ - //player.Score().AdjustScore(-2); - return PlayerKillType::Normal; -} - -void CGM_Pipe_MiniGame::playerextraguy(CPlayer &player, short iType) -{ - if (!gameover) { - player.Score().AdjustScore(iType); - CheckWinner(&player); - } -} - -PlayerKillType CGM_Pipe_MiniGame::CheckWinner(CPlayer * player) -{ - if (goal > -1) { - if (player->Score().score >= goal) { - player->Score().SetScore(goal); - - winningteam = player->getTeamID(); - gameover = true; - - RemovePlayersButTeam(winningteam); - SetupScoreBoard(false); - ShowScoreBoard(); - } else if (player->Score().score >= goal - 5 && !playedwarningsound) { - playwarningsound(); - } - } - - return PlayerKillType::Normal; -} - -void CGM_Pipe_MiniGame::SetBonus(short iType, short iTimer, short iTeamID) -{ - iBonusType = iType; - - //This is the random bonus - if (iBonusType == 5) - iBonusType = RANDOM_INT(4) + 1; - - if (iBonusType == 4) - fSlowdown = true; - - iBonusTimer = iTimer; - iBonusTeam = iTeamID; - - if (iBonusType == 3) - ifSoundOnPlay(rm->sfx_powerdown); - else - ifSoundOnPlay(rm->sfx_collectpowerup); -} - -/* -TODO -1) Create new box object that breaks on contact and either gives a coin/bonus/penalty -2) Create levels approprate for distributing boxes onto -3) Add level hazards like thwomps, podobos, fireballs -4) Add hurry up that kicks in after 3 minutes of play that adds more coins or lowers bar to win -*/ - -//Boxes Bonus Mini Game (used in world mode) -//Try to collect all coins from boxes and players -CGM_Boxes_MiniGame::CGM_Boxes_MiniGame() : CGameMode() -{ - goal = 10; - gamemode = game_mode_boxes_minigame; - - SetupModeStrings("Boxes Minigame", "Lives", 5); -}; - -void CGM_Boxes_MiniGame::init() -{ - CGameMode::init(); - - fReverseScoring = false; - - for (short iScore = 0; iScore < score_cnt; iScore++) { - score[iScore]->SetScore(goal); - score[iScore]->subscore[0] = 0; - } -} - - -void CGM_Boxes_MiniGame::think() -{ - if (gameover) { - displayplayertext(); - return; - } -} - -PlayerKillType CGM_Boxes_MiniGame::playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style) -{ - if (gameover) - return PlayerKillType::Normal; - - ReleaseCoin(other); - - other.Score().AdjustScore(-1); - - if (!playedwarningsound) { - short countscore = 0; - for (short k = 0; k < score_cnt; k++) { - if (&inflictor.Score() == score[k]) - continue; - - countscore += score[k]->score; - } - - if (countscore <= 2) { - playwarningsound(); - } - } - - if (other.Score().score <= 0) { - ReleaseAllCoinsFromTeam(other); - RemoveTeam(other.getTeamID()); - return PlayerKillType::Removed; - } - - return PlayerKillType::Normal; -} - -PlayerKillType CGM_Boxes_MiniGame::playerkilledself(CPlayer &player, KillStyle style) -{ - if (gameover) - return PlayerKillType::Normal; - - ReleaseCoin(player); - - player.Score().AdjustScore(-1); - - if (!playedwarningsound) { - short countscore = 0; - bool playwarning = false; - for (short j = 0; j < score_cnt; j++) { - for (short k = 0; k < score_cnt; k++) { - if (j == k) - continue; - - countscore += score[k]->score; - } - - if (countscore <= 2) { - playwarning = true; - break; - } - - countscore = 0; - } - - if (playwarning) - playwarningsound(); - } - - if (player.Score().score <= 0) { - ReleaseAllCoinsFromTeam(player); - RemoveTeam(player.getTeamID()); - return PlayerKillType::Removed; - } - - return PlayerKillType::Normal; -} - -void CGM_Boxes_MiniGame::playerextraguy(CPlayer &player, short iType) -{ - if (gameover) - return; - - player.Score().AdjustScore(iType); -} - -PlayerKillType CGM_Boxes_MiniGame::CheckWinner(CPlayer * player) -{ - if (player->Score().subscore[0] >= 5) { - player->Score().subscore[0] = 5; - - winningteam = player->getTeamID(); - gameover = true; - - RemovePlayersButTeam(winningteam); - SetupScoreBoard(false); - ShowScoreBoard(); - } else if (player->Score().subscore[0] >= 4 && !playedwarningsound) { - playwarningsound(); - } - - return PlayerKillType::Normal; -} - -void CGM_Boxes_MiniGame::ReleaseCoin(CPlayer &player) -{ - if (player.Score().subscore[0] > 0) { - player.Score().subscore[0]--; - - short ix = player.centerX() - 16; - short iy = player.centerY() - 16; - - float vel = 7.0f + (float)RANDOM_INT(9) / 2.0f; - float angle = -(float)RANDOM_INT(314) / 100.0f; - float velx = vel * cos(angle); - float vely = vel * sin(angle); - - ifSoundOnPlay(rm->sfx_coin); - - objectcontainer[1].add(new MO_Coin(&rm->spr_coin, velx, vely, ix, iy, 2, -1, 2, 30, false)); - } -} - -void CGM_Boxes_MiniGame::ReleaseAllCoinsFromTeam(CPlayer &player) -{ - while (player.Score().subscore[0] > 0) - ReleaseCoin(player); -} diff --git a/src/smw/gamemodes.h b/src/smw/gamemodes.h index b4d28e62..fe0590ff 100644 --- a/src/smw/gamemodes.h +++ b/src/smw/gamemodes.h @@ -557,40 +557,6 @@ class CGM_Chase : public CGameMode }; -//Special mode where players try to kill a boss -class CGM_Boss_MiniGame : public CGameMode -{ - public: - CGM_Boss_MiniGame(); - virtual ~CGM_Boss_MiniGame() {} - - void init(); - void think(); - void draw_foreground(); - - PlayerKillType playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style); - PlayerKillType playerkilledself(CPlayer &player, KillStyle style); - void playerextraguy(CPlayer &player, short iType); - - char *getMenuString(char *buffer64); - - bool SetWinner(CPlayer * player); - void SetBossType(short bosstype); - short GetBossType() { - return iBossType; - } - - bool HasStoredPowerups() { - return false; - } - - private: - - short enemytimer, poweruptimer; - short iBossType; -}; - - //Special mode where players can collect a bonus item class CGM_Bonus : public CGameMode { @@ -621,66 +587,4 @@ class CGM_Bonus : public CGameMode TourStop * tsTourStop; }; -//Special mode where players collect coins from a pipe -class CGM_Pipe_MiniGame : public CGameMode -{ - public: - CGM_Pipe_MiniGame(); - virtual ~CGM_Pipe_MiniGame() {} - - void init(); - void think(); - - PlayerKillType playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style); - PlayerKillType playerkilledself(CPlayer &player, KillStyle style); - void playerextraguy(CPlayer &player, short iType); - PlayerKillType CheckWinner(CPlayer * player); - - void SetBonus(short iType, short iTimer, short iTeamID); - bool IsSlowdown() { - return fSlowdown; - } - - bool HasStoredPowerups() { - return false; - } - - private: - - short iNextItemTimer; - short iBonusTimer, iBonusType, iBonusTeam; - - bool fSlowdown; -}; - - -//Special mode where players break boxes -class CGM_Boxes_MiniGame : public CGameMode -{ - public: - CGM_Boxes_MiniGame(); - virtual ~CGM_Boxes_MiniGame() {} - - void init(); - void think(); - - PlayerKillType playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style); - PlayerKillType playerkilledself(CPlayer &player, KillStyle style); - void playerextraguy(CPlayer &player, short iType); - - char *getMenuString(char *buffer64); - - PlayerKillType CheckWinner(CPlayer * player); - bool SetWinner(CPlayer * player); - - bool HasStoredPowerups() { - return false; - } - - private: - - void ReleaseCoin(CPlayer &player); - void ReleaseAllCoinsFromTeam(CPlayer &player); -}; - #endif // GAMEMODES_H diff --git a/src/smw/gamemodes/MiniBoss.cpp b/src/smw/gamemodes/MiniBoss.cpp new file mode 100644 index 00000000..20c57298 --- /dev/null +++ b/src/smw/gamemodes/MiniBoss.cpp @@ -0,0 +1,202 @@ +#include "MiniBoss.h" + +#include "GameValues.h" +#include "ObjectContainer.h" +#include "player.h" +#include "RandomNumberGenerator.h" +#include "ResourceManager.h" +#include "objects/moving/FrenzyCard.h" +#include "objects/moving/Koopa.h" +#include "objects/moving/Podobo.h" +#include "objects/moving/SledgeBrother.h" + +extern short list_players_cnt; +extern short score_cnt; +extern CScore *score[4]; +extern CObjectContainer objectcontainer[3]; +extern CGameValues game_values; +extern CResourceManager* rm; + + +//Boss Mode +//Person to score fatal hit to boss wins! +CGM_Boss_MiniGame::CGM_Boss_MiniGame() : CGameMode() +{ + gamemode = game_mode_boss_minigame; + SetupModeStrings("Boss", "Lives", 5); + iBossType = 0; +} + +void CGM_Boss_MiniGame::init() +{ + CGameMode::init(); + + fReverseScoring = false; + + enemytimer = (short)(RANDOM_INT(120) + 120); + poweruptimer = 120; + + for (short iScore = 0; iScore < score_cnt; iScore++) + score[iScore]->SetScore(goal); + + objectcontainer[0].add(new MO_SledgeBrother(&rm->spr_sledgebrothers, (iBossType == 0 ? 256 : (iBossType == 1 ? 256 : smw->ScreenWidth/2)), iBossType)); +} + + +void CGM_Boss_MiniGame::think() +{ + if (!gameover && list_players_cnt == 0) { + gameover = true; + + if (game_values.music) { + ifsoundonstop(rm->sfx_invinciblemusic); + ifsoundonstop(rm->sfx_timewarning); + ifsoundonstop(rm->sfx_slowdownmusic); + ifSoundOnPlay(rm->sfx_gameover); + + rm->backgroundmusic[1].stop(); + } + } + + if (gameover) { + displayplayertext(); + } else { + if (iBossType == 0) { + //Randomly spawn koopas + if (--enemytimer <= 0) { + objectcontainer[0].add(new MO_Koopa(&rm->spr_koopa, RANDOM_BOOL(), false, false, true)); + enemytimer = (short)RANDOM_INT(120) + 120; //Spawn koopas slowly + } + } else if (iBossType == 1) { + + } else if (iBossType == 2) { + //Only create podobos if the difficulty is moderate or greater + if (--enemytimer <= 0 && game_values.gamemodesettings.boss.difficulty >= 2) { + objectcontainer[2].add(new MO_Podobo(&rm->spr_podobo, (short)RANDOM_INT(smw->ScreenWidth * 0.95f), smw->ScreenHeight, -(float(RANDOM_INT(9)) / 2.0f) - 9.0f, -1, -1, -1, false)); + enemytimer = (short)(RANDOM_INT(80) + 60); + } + + if (--poweruptimer <= 0) { + poweruptimer = (short)(RANDOM_INT(80) + 60); + + if (objectcontainer[1].countTypes(object_frenzycard) < list_players_cnt) { + objectcontainer[1].add(new MO_FrenzyCard(&rm->spr_frenzycards, 0)); + } + } + } + } +} + +void CGM_Boss_MiniGame::draw_foreground() +{ + if (gameover) { + if (winningteam == -1) { + rm->game_font_large.drawCentered(smw->ScreenWidth/2, 96, "You Failed To Defeat"); + + if (iBossType == 0) + rm->game_font_large.drawCentered(smw->ScreenWidth/2, 118, "The Mighty Sledge Brother"); + else if (iBossType == 1) + rm->game_font_large.drawCentered(smw->ScreenWidth/2, 118, "The Mighty Bomb Brother"); + else if (iBossType == 2) + rm->game_font_large.drawCentered(smw->ScreenWidth/2, 118, "The Mighty Flame Brother"); + } + } +} + +PlayerKillType CGM_Boss_MiniGame::playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style) +{ + if (!gameover) { + other.Score().AdjustScore(-1); + + if (!playedwarningsound) { + short countscore = 0; + for (short k = 0; k < score_cnt; k++) + countscore += score[k]->score; + + if (countscore <= 2) + playwarningsound(); + } + + if (other.Score().score <= 0) { + RemoveTeam(other.getTeamID()); + return PlayerKillType::Removed; + } + } + + return PlayerKillType::Normal; +} + +PlayerKillType CGM_Boss_MiniGame::playerkilledself(CPlayer &player, KillStyle style) +{ + CGameMode::playerkilledself(player, style); + + if (!gameover) { + player.Score().AdjustScore(-1); + + if (!playedwarningsound) { + short countscore = 0; + for (short k = 0; k < score_cnt; k++) + countscore += score[k]->score; + + if (countscore <= 2) + playwarningsound(); + } + + if (player.Score().score <= 0) { + RemoveTeam(player.getTeamID()); + return PlayerKillType::Removed; + } + } + + return PlayerKillType::Normal; +} + +void CGM_Boss_MiniGame::playerextraguy(CPlayer &player, short iType) +{ + if (!gameover) + player.Score().AdjustScore(iType); +} + +bool CGM_Boss_MiniGame::SetWinner(CPlayer * player) +{ + winningteam = player->getTeamID(); + gameover = true; + + RemovePlayersButTeam(winningteam); + + for (short iScore = 0; iScore < score_cnt; iScore++) { + if (winningteam == iScore) + continue; + + score[iScore]->SetScore(0); + } + + SetupScoreBoard(false); + ShowScoreBoard(); + + if (game_values.music) { + ifsoundonstop(rm->sfx_invinciblemusic); + ifsoundonstop(rm->sfx_timewarning); + ifsoundonstop(rm->sfx_slowdownmusic); + + rm->backgroundmusic[1].play(true, false); + } + + //game_values.noexit = true; + + /* + if (iBossType == 0) + objectcontainer[0].add(new PU_SledgeHammerPowerup(&rm->spr_sledgehammerpowerup, 304, -32, 1, 0, 30, 30, 1, 1)); + else if (iBossType == 1) + objectcontainer[0].add(new PU_BombPowerup(&rm->spr_bombpowerup, 304, -32, 1, 0, 30, 30, 1, 1)); + else if (iBossType == 2) + objectcontainer[0].add(new PU_PodoboPowerup(&rm->spr_podobopowerup, 304, -32, 1, 0, 30, 30, 1, 1)); + */ + + return true; +} + +void CGM_Boss_MiniGame::SetBossType(short bosstype) +{ + iBossType = bosstype; +} diff --git a/src/smw/gamemodes/MiniBoss.h b/src/smw/gamemodes/MiniBoss.h new file mode 100644 index 00000000..e631445a --- /dev/null +++ b/src/smw/gamemodes/MiniBoss.h @@ -0,0 +1,37 @@ +#pragma once + +#include "GameMode.h" + + +//Special mode where players try to kill a boss +class CGM_Boss_MiniGame : public CGameMode +{ + public: + CGM_Boss_MiniGame(); + virtual ~CGM_Boss_MiniGame() {} + + void init(); + void think(); + void draw_foreground(); + + PlayerKillType playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style); + PlayerKillType playerkilledself(CPlayer &player, KillStyle style); + void playerextraguy(CPlayer &player, short iType); + + char *getMenuString(char *buffer64); + + bool SetWinner(CPlayer * player); + void SetBossType(short bosstype); + short GetBossType() { + return iBossType; + } + + bool HasStoredPowerups() { + return false; + } + + private: + + short enemytimer, poweruptimer; + short iBossType; +}; diff --git a/src/smw/gamemodes/MiniBoxes.cpp b/src/smw/gamemodes/MiniBoxes.cpp new file mode 100644 index 00000000..9e56c59c --- /dev/null +++ b/src/smw/gamemodes/MiniBoxes.cpp @@ -0,0 +1,178 @@ +#include "MiniBoxes.h" + +#include "GameValues.h" +#include "ObjectContainer.h" +#include "player.h" +#include "RandomNumberGenerator.h" +#include "ResourceManager.h" +#include "objects/moving/Coin.h" + +#include + +extern short score_cnt; +extern CScore *score[4]; +extern CObjectContainer objectcontainer[3]; +extern CResourceManager* rm; + +/* +TODO +1) Create new box object that breaks on contact and either gives a coin/bonus/penalty +2) Create levels approprate for distributing boxes onto +3) Add level hazards like thwomps, podobos, fireballs +4) Add hurry up that kicks in after 3 minutes of play that adds more coins or lowers bar to win +*/ + +//Boxes Bonus Mini Game (used in world mode) +//Try to collect all coins from boxes and players +CGM_Boxes_MiniGame::CGM_Boxes_MiniGame() : CGameMode() +{ + goal = 10; + gamemode = game_mode_boxes_minigame; + + SetupModeStrings("Boxes Minigame", "Lives", 5); +}; + +void CGM_Boxes_MiniGame::init() +{ + CGameMode::init(); + + fReverseScoring = false; + + for (short iScore = 0; iScore < score_cnt; iScore++) { + score[iScore]->SetScore(goal); + score[iScore]->subscore[0] = 0; + } +} + + +void CGM_Boxes_MiniGame::think() +{ + if (gameover) { + displayplayertext(); + return; + } +} + +PlayerKillType CGM_Boxes_MiniGame::playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style) +{ + if (gameover) + return PlayerKillType::Normal; + + ReleaseCoin(other); + + other.Score().AdjustScore(-1); + + if (!playedwarningsound) { + short countscore = 0; + for (short k = 0; k < score_cnt; k++) { + if (&inflictor.Score() == score[k]) + continue; + + countscore += score[k]->score; + } + + if (countscore <= 2) { + playwarningsound(); + } + } + + if (other.Score().score <= 0) { + ReleaseAllCoinsFromTeam(other); + RemoveTeam(other.getTeamID()); + return PlayerKillType::Removed; + } + + return PlayerKillType::Normal; +} + +PlayerKillType CGM_Boxes_MiniGame::playerkilledself(CPlayer &player, KillStyle style) +{ + if (gameover) + return PlayerKillType::Normal; + + ReleaseCoin(player); + + player.Score().AdjustScore(-1); + + if (!playedwarningsound) { + short countscore = 0; + bool playwarning = false; + for (short j = 0; j < score_cnt; j++) { + for (short k = 0; k < score_cnt; k++) { + if (j == k) + continue; + + countscore += score[k]->score; + } + + if (countscore <= 2) { + playwarning = true; + break; + } + + countscore = 0; + } + + if (playwarning) + playwarningsound(); + } + + if (player.Score().score <= 0) { + ReleaseAllCoinsFromTeam(player); + RemoveTeam(player.getTeamID()); + return PlayerKillType::Removed; + } + + return PlayerKillType::Normal; +} + +void CGM_Boxes_MiniGame::playerextraguy(CPlayer &player, short iType) +{ + if (gameover) + return; + + player.Score().AdjustScore(iType); +} + +PlayerKillType CGM_Boxes_MiniGame::CheckWinner(CPlayer * player) +{ + if (player->Score().subscore[0] >= 5) { + player->Score().subscore[0] = 5; + + winningteam = player->getTeamID(); + gameover = true; + + RemovePlayersButTeam(winningteam); + SetupScoreBoard(false); + ShowScoreBoard(); + } else if (player->Score().subscore[0] >= 4 && !playedwarningsound) { + playwarningsound(); + } + + return PlayerKillType::Normal; +} + +void CGM_Boxes_MiniGame::ReleaseCoin(CPlayer &player) +{ + if (player.Score().subscore[0] > 0) { + player.Score().subscore[0]--; + + short ix = player.centerX() - 16; + short iy = player.centerY() - 16; + + float vel = 7.0f + (float)RANDOM_INT(9) / 2.0f; + float angle = -(float)RANDOM_INT(314) / 100.0f; + float velx = vel * cos(angle); + float vely = vel * sin(angle); + + ifSoundOnPlay(rm->sfx_coin); + + objectcontainer[1].add(new MO_Coin(&rm->spr_coin, velx, vely, ix, iy, 2, -1, 2, 30, false)); + } +} + +void CGM_Boxes_MiniGame::ReleaseAllCoinsFromTeam(CPlayer &player) +{ + while (player.Score().subscore[0] > 0) + ReleaseCoin(player); +} diff --git a/src/smw/gamemodes/MiniBoxes.h b/src/smw/gamemodes/MiniBoxes.h new file mode 100644 index 00000000..d94b387a --- /dev/null +++ b/src/smw/gamemodes/MiniBoxes.h @@ -0,0 +1,33 @@ +#pragma once + +#include "GameMode.h" + + +//Special mode where players break boxes +class CGM_Boxes_MiniGame : public CGameMode +{ + public: + CGM_Boxes_MiniGame(); + virtual ~CGM_Boxes_MiniGame() {} + + void init(); + void think(); + + PlayerKillType playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style); + PlayerKillType playerkilledself(CPlayer &player, KillStyle style); + void playerextraguy(CPlayer &player, short iType); + + char *getMenuString(char *buffer64); + + PlayerKillType CheckWinner(CPlayer * player); + bool SetWinner(CPlayer * player); + + bool HasStoredPowerups() { + return false; + } + + private: + + void ReleaseCoin(CPlayer &player); + void ReleaseAllCoinsFromTeam(CPlayer &player); +}; diff --git a/src/smw/gamemodes/MiniPipe.cpp b/src/smw/gamemodes/MiniPipe.cpp new file mode 100644 index 00000000..c8aba80f --- /dev/null +++ b/src/smw/gamemodes/MiniPipe.cpp @@ -0,0 +1,146 @@ +#include "MiniPipe.h" + +#include "GameValues.h" +#include "ObjectContainer.h" +#include "player.h" +#include "RandomNumberGenerator.h" +#include "ResourceManager.h" +#include "objects/overmap/PipeBonus.h" +#include "objects/overmap/PipeCoin.h" + + +extern short score_cnt; +extern CObjectContainer objectcontainer[3]; +extern CResourceManager* rm; +extern CGameValues game_values; + + +//Pipe Bonus Mini Game (used in world mode) +//Collect coins and powerups that come out of a pipe +CGM_Pipe_MiniGame::CGM_Pipe_MiniGame() : CGameMode() +{ + goal = 50; + gamemode = game_mode_pipe_minigame; + + SetupModeStrings("Pipe Minigame", "Points", 0); +}; + +void CGM_Pipe_MiniGame::init() +{ + CGameMode::init(); + + fReverseScoring = false; + + iNextItemTimer = 0; + iBonusTimer = 0; + iBonusType = 0; + iBonusTeam = 0; +} + + +void CGM_Pipe_MiniGame::think() +{ + if (gameover) { + displayplayertext(); + return; + } + + if (--iNextItemTimer <= 0) { + if (iBonusType == 0 || iBonusType == 2 || iBonusType == 4) { + if (iBonusType == 2) + iNextItemTimer = RANDOM_INT(10) + 10; + else + iNextItemTimer = RANDOM_INT(20) + 25; + + short iRandPowerup = RANDOM_INT(50); + if (iBonusType == 0 && iRandPowerup < 5) { //bonuses + objectcontainer[1].add(new OMO_PipeBonus(&rm->spr_pipegamebonus, (float)(RANDOM_INT(21) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, iRandPowerup, 620, 15)); + } else if (iRandPowerup < 10) { //fireballs + objectcontainer[1].add(new OMO_PipeBonus(&rm->spr_pipegamebonus, (float)(RANDOM_INT(21) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, 5, 0, 15)); + } else { //coins + short iRandCoin = RANDOM_INT(20); + objectcontainer[1].add(new OMO_PipeCoin(&rm->spr_coin, (float)(RANDOM_INT(21) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, -1, iRandCoin < 16 ? 2 : (iRandCoin < 19 ? 0 : 1), 15)); + } + } else if (iBonusType == 1) { + iNextItemTimer = RANDOM_INT(10) + 10; + + short iRandTeam = RANDOM_INT(score_cnt + 2); + + //Give an advantage to the team that got the item + if (iRandTeam >= score_cnt) + iRandTeam = iBonusTeam; + + short iRandPlayer = game_values.teamids[iRandTeam][RANDOM_INT(game_values.teamcounts[iRandTeam])]; + + objectcontainer[1].add(new OMO_PipeCoin(&rm->spr_coin, (float)((RANDOM_INT(21)) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, iRandTeam, game_values.colorids[iRandPlayer], 15)); + } else if (iBonusType == 3) { + iNextItemTimer = RANDOM_INT(5) + 10; + objectcontainer[1].add(new OMO_PipeCoin(&rm->spr_coin, (float)((RANDOM_INT(21)) - 10) / 2.0f, -((float)RANDOM_INT(11) / 2.0f + 7.0f), 304, 256, -1, 0, 15)); + } + } + + if (iBonusTimer > 0 && --iBonusTimer <= 0) { + iBonusType = 0; + fSlowdown = false; + } +} + +PlayerKillType CGM_Pipe_MiniGame::playerkilledplayer(CPlayer &player, CPlayer &other, KillStyle style) +{ + //other.Score().AdjustScore(-2); + return PlayerKillType::Normal; +} + +PlayerKillType CGM_Pipe_MiniGame::playerkilledself(CPlayer &player, KillStyle style) +{ + //player.Score().AdjustScore(-2); + return PlayerKillType::Normal; +} + +void CGM_Pipe_MiniGame::playerextraguy(CPlayer &player, short iType) +{ + if (!gameover) { + player.Score().AdjustScore(iType); + CheckWinner(&player); + } +} + +PlayerKillType CGM_Pipe_MiniGame::CheckWinner(CPlayer * player) +{ + if (goal > -1) { + if (player->Score().score >= goal) { + player->Score().SetScore(goal); + + winningteam = player->getTeamID(); + gameover = true; + + RemovePlayersButTeam(winningteam); + SetupScoreBoard(false); + ShowScoreBoard(); + } else if (player->Score().score >= goal - 5 && !playedwarningsound) { + playwarningsound(); + } + } + + return PlayerKillType::Normal; +} + +void CGM_Pipe_MiniGame::SetBonus(short iType, short iTimer, short iTeamID) +{ + iBonusType = iType; + + //This is the random bonus + if (iBonusType == 5) + iBonusType = RANDOM_INT(4) + 1; + + if (iBonusType == 4) + fSlowdown = true; + + iBonusTimer = iTimer; + iBonusTeam = iTeamID; + + if (iBonusType == 3) + ifSoundOnPlay(rm->sfx_powerdown); + else + ifSoundOnPlay(rm->sfx_collectpowerup); +} diff --git a/src/smw/gamemodes/MiniPipe.h b/src/smw/gamemodes/MiniPipe.h new file mode 100644 index 00000000..9e154ea4 --- /dev/null +++ b/src/smw/gamemodes/MiniPipe.h @@ -0,0 +1,36 @@ +#pragma once + +#include "GameMode.h" + + +//Special mode where players collect coins from a pipe +class CGM_Pipe_MiniGame : public CGameMode +{ + public: + CGM_Pipe_MiniGame(); + virtual ~CGM_Pipe_MiniGame() {} + + void init(); + void think(); + + PlayerKillType playerkilledplayer(CPlayer &inflictor, CPlayer &other, KillStyle style); + PlayerKillType playerkilledself(CPlayer &player, KillStyle style); + void playerextraguy(CPlayer &player, short iType); + PlayerKillType CheckWinner(CPlayer * player); + + void SetBonus(short iType, short iTimer, short iTeamID); + bool IsSlowdown() { + return fSlowdown; + } + + bool HasStoredPowerups() { + return false; + } + + private: + + short iNextItemTimer; + short iBonusTimer, iBonusType, iBonusTeam; + + bool fSlowdown; +}; diff --git a/src/smw/main.cpp b/src/smw/main.cpp index 1d0626fa..e740b4b5 100644 --- a/src/smw/main.cpp +++ b/src/smw/main.cpp @@ -30,6 +30,9 @@ #include "ResourceManager.h" #include "sfx.h" #include "TilesetManager.h" +#include "gamemodes/MiniBoss.h" +#include "gamemodes/MiniBoxes.h" +#include "gamemodes/MiniPipe.h" #include "FPSLimiter.h" #include "GSSplashScreen.h" diff --git a/src/smw/objectgame.cpp b/src/smw/objectgame.cpp index 634a4ee8..da365f67 100644 --- a/src/smw/objectgame.cpp +++ b/src/smw/objectgame.cpp @@ -10,6 +10,9 @@ #include "objecthazard.h" #include "RandomNumberGenerator.h" #include "ResourceManager.h" +#include "gamemodes/MiniBoss.h" +#include "gamemodes/MiniBoxes.h" +#include "gamemodes/MiniPipe.h" #include // abs() #include diff --git a/src/smw/ui/MI_TourStop.cpp b/src/smw/ui/MI_TourStop.cpp index dee51ef2..b7980df2 100644 --- a/src/smw/ui/MI_TourStop.cpp +++ b/src/smw/ui/MI_TourStop.cpp @@ -3,6 +3,9 @@ #include "gamemodes.h" #include "GameValues.h" #include "ResourceManager.h" +#include "gamemodes/MiniBoss.h" +#include "gamemodes/MiniBoxes.h" +#include "gamemodes/MiniPipe.h" #include "ui/MI_Button.h" #include "ui/MI_Image.h" #include "ui/MI_ImageSelectField.h"