Skip to content

Commit

Permalink
Merge pull request #904 from sgfost/tournament-mode
Browse files Browse the repository at this point in the history
- add preliminary tournament lobby and dashboard with onboarding and schedules
- add tournament banner to the landing page when tournaments are enabled
- add tournament participation links to the navbar, landing page, and footer when tournaments are enabled
  • Loading branch information
alee authored Oct 28, 2023
2 parents c4b59ff + 63a45d6 commit 6ec3485
Show file tree
Hide file tree
Showing 73 changed files with 1,746 additions and 661 deletions.
4 changes: 2 additions & 2 deletions client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Footer from "@port-of-mars/client/components/global/Footer.vue";
import {
GAME_PAGE,
MANUAL_PAGE,
LOBBY_PAGE,
FREE_PLAY_LOBBY_PAGE,
HOME_PAGE,
ABOUT_PAGE,
PRIVACY_PAGE,
Expand All @@ -32,7 +32,7 @@ Vue.use(BootstrapVue);
export default class App extends Vue {
game = { name: GAME_PAGE };
manual = { name: MANUAL_PAGE };
lobby = { name: LOBBY_PAGE };
freePlayLobby = { name: FREE_PLAY_LOBBY_PAGE };
home = { name: HOME_PAGE };
about = { name: ABOUT_PAGE };
privacy = { name: PRIVACY_PAGE };
Expand Down
20 changes: 12 additions & 8 deletions client/src/api/lobby/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ export class LobbyRequestAPI {
this.send(msg);
}

public sendChatMessage(message: string) {
const msg: SendLobbyChatMessage = {
kind: "send-lobby-chat-message",
value: message,
};
this.send(msg);
}
}

export class FreePlayLobbyRequestAPI extends LobbyRequestAPI {
public startWithBots() {
const msg: StartWithBots = { kind: "start-with-bots" };
this.send(msg);
Expand All @@ -47,12 +57,6 @@ export class LobbyRequestAPI {
};
this.send(msg);
}

public sendChatMessage(message: string) {
const msg: SendLobbyChatMessage = {
kind: "send-lobby-chat-message",
value: message,
};
this.send(msg);
}
}

export class TournamentLobbyRequestAPI extends LobbyRequestAPI {}
27 changes: 20 additions & 7 deletions client/src/api/lobby/response.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { Room } from "colyseus.js";
import { DataChange, Schema } from "@colyseus/schema";
import { SentInvitation, JoinFailure } from "@port-of-mars/shared/lobby/responses";
import { LobbyChatMessageData, LobbyClientData } from "@port-of-mars/shared/types";
import { LOBBY_PAGE, GAME_PAGE } from "@port-of-mars/shared/routes";
import { LobbyChatMessageData, LobbyClientData, LobbyType } from "@port-of-mars/shared/types";
import {
FREE_PLAY_LOBBY_PAGE,
GAME_PAGE,
TOURNAMENT_LOBBY_PAGE,
} from "@port-of-mars/shared/routes";

type Schemify<T> = T & Schema;

function deschemify<T>(s: Schemify<T>): T {
return s.toJSON() as T;
}

export function applyLobbyResponses(room: Room, component: any) {
export function applyLobbyResponses(room: Room, component: any, lobbyType: LobbyType) {
const store = component.$tstore;
const router = component.$router;

store.commit("SET_LOBBY_TYPE", lobbyType);

room.onError((code: number, message?: string) => {
console.log(`Error ${code} occurred in room: ${message} `);
alert("sorry, we encountered an error, please try refreshing the page or contact us");
Expand All @@ -25,15 +31,22 @@ export function applyLobbyResponses(room: Room, component: any) {

room.onMessage("join-failure", (msg: JoinFailure) => {
store.commit("SET_DASHBOARD_MESSAGE", { kind: "warning", message: msg.reason });
router.push({ name: LOBBY_PAGE });
router.push({
name: lobbyType === "freeplay" ? FREE_PLAY_LOBBY_PAGE : TOURNAMENT_LOBBY_PAGE,
});
});

room.onMessage("sent-invitation", (msg: SentInvitation) => {
component.$ajax.roomId = msg.roomId;
store.commit("SET_LOBBY_READINESS", true);
setTimeout(() => {
// set ready and wait for freeplay, in a tournament we just put them right into a game
if (lobbyType === "freeplay") {
store.commit("SET_LOBBY_READINESS", true);
setTimeout(() => {
room.send("accept-invitation", { kind: "accept-invitation" });
}, 5 * 1000);
} else {
room.send("accept-invitation", { kind: "accept-invitation" });
}, 5 * 1000);
}
});

room.onMessage("removed-client-from-lobby", () => {
Expand Down
28 changes: 28 additions & 0 deletions client/src/api/tournament/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { url } from "@port-of-mars/client/util";
import { TournamentRoundInviteStatus, TournamentStatus } from "@port-of-mars/shared/types";
import { TStore } from "@port-of-mars/client/plugins/tstore";
import { AjaxRequest } from "@port-of-mars/client/plugins/ajax";

export class TournamentAPI {
constructor(public store: TStore, public ajax: AjaxRequest) {}

async getTournamentStatus(): Promise<TournamentStatus> {
try {
return this.ajax.get(url("/tournament/status"), ({ data }) => data);
} catch (e) {
console.log("Unable to get tournament status");
console.log(e);
throw e;
}
}

async getInviteStatus(): Promise<TournamentRoundInviteStatus> {
try {
return this.ajax.get(url("/tournament/invite-status"), ({ data }) => data);
} catch (e) {
console.log("Unable to get tournament round invite status");
console.log(e);
throw e;
}
}
}
2 changes: 1 addition & 1 deletion client/src/components/game/phases/Investments.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<div class="h-100 p-2 scrollable">
<AccomplishmentCard
v-for="accomplishment in purchasableAccomplishments"
:key="accomplishment.label + Math.random()"
:key="accomplishment.id"
:accomplishment="accomplishment"
:enableModal="true"
></AccomplishmentCard>
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/game/static/popups/ProfileMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</button>
<div class="wrapper" v-show="profileMenuVisible">
<p>Logged in as {{ username }}</p>
<router-link :to="lobby" class="link">
<router-link :to="freePlayLobby" class="link">
<button>
<b-icon-person-fill></b-icon-person-fill>
<span>Return to Lobby</span>
Expand Down Expand Up @@ -40,7 +40,7 @@
import { Vue, Component, Inject } from "vue-property-decorator";
import { GameRequestAPI } from "@port-of-mars/client/api/game/request";
import { isDev, isStaging } from "@port-of-mars/shared/settings";
import { LOBBY_PAGE } from "@port-of-mars/shared/routes";
import { FREE_PLAY_LOBBY_PAGE } from "@port-of-mars/shared/routes";
@Component({
components: {},
Expand All @@ -49,7 +49,7 @@ export default class ProfileMenu extends Vue {
@Inject() readonly api!: GameRequestAPI;
devtoolsEnabled: boolean = false;
lobby = { name: LOBBY_PAGE };
freePlayLobby = { name: FREE_PLAY_LOBBY_PAGE };
get profileMenuVisible() {
return this.$tstore.state.userInterface.profileMenuView.visible;
Expand Down
37 changes: 20 additions & 17 deletions client/src/components/global/Countdown.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<template>
<div class="countdown">
<div class="countdown-block">
<div class="countdown-digit">{{ format(hours) }}</div>
<div class="countdown-digit" :style="`font-size: ${size}rem`">{{ format(days) }}</div>
<div class="countdown-unit">Days</div>
</div>
<div class="countdown-block">
<div class="countdown-digit" :style="`font-size: ${size}rem`">{{ format(hours) }}</div>
<div class="countdown-unit">Hrs</div>
</div>
<div class="countdown-block">
<div class="countdown-digit">{{ format(minutes) }}</div>
<div class="countdown-digit" :style="`font-size: ${size}rem`">{{ format(minutes) }}</div>
<div class="countdown-unit">Min</div>
</div>
<div class="countdown-block">
<div class="countdown-digit">{{ format(seconds) }}</div>
<div class="countdown-digit" :style="`font-size: ${size}rem`">{{ format(seconds) }}</div>
<div class="countdown-unit">Sec</div>
</div>
</div>
Expand All @@ -23,6 +27,9 @@ export default class Countdown extends Vue {
@Prop({ default: 0 })
nextLaunch!: number;
@Prop({ default: 3 })
size!: number;
secondInterval = 0;
now: number = Math.trunc(Date.now() / 1000);
Expand All @@ -44,7 +51,11 @@ export default class Countdown extends Vue {
}
get hours() {
return Math.trunc(this.secondsUntilLaunch / 60 / 60);
return Math.trunc(this.secondsUntilLaunch / 60 / 60) % 24;
}
get days() {
return Math.trunc(this.secondsUntilLaunch / 60 / 60 / 24);
}
mounted() {
Expand Down Expand Up @@ -74,36 +85,28 @@ export default class Countdown extends Vue {
}
.countdown-block {
background-color: rgba(255, 255, 255, 0.05);
text-align: center;
padding: 0px 15px;
margin: 0.5rem;
padding: 0.75rem;
padding-bottom: 0.5rem;
border-radius: 0.25rem;
position: relative;
&:first-child {
padding-left: 0;
.countdown-digit {
&:before {
display: none;
}
}
}
&:last-child {
padding-right: 0;
}
}
.countdown-digit {
font-size: 500%;
font-weight: bold;
line-height: 1;
margin-bottom: 5px;
&:before {
content: ":";
position: absolute;
left: -10px;
}
}
.countdown-unit {
text-transform: uppercase;
margin-bottom: 5px;
}
</style>
23 changes: 20 additions & 3 deletions client/src/components/global/Footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ [email protected]
<b-link :to="solo" title="Solo Mode">Solo Mode</b-link>
</li>
<li>
<b-link :to="lobby" title="Play Port of Mars">Play Port of Mars</b-link>
<b-link v-if="isFreePlayEnabled" :to="freePlayLobby" title="Port of Mars Free Play"
>Free Play</b-link
>
</li>
<li>
<b-link v-if="isTournamentEnabled" :to="tournamentDashboard" title="Join Mars Madness"
>Join Mars Madness</b-link
>
</li>
<li>
<b-link :to="manual" title="User Manual">How to Play</b-link>
Expand Down Expand Up @@ -97,11 +104,12 @@ import { Component, Vue } from "vue-property-decorator";
import { Constants } from "@port-of-mars/shared/settings";
import {
LOGIN_PAGE,
LOBBY_PAGE,
FREE_PLAY_LOBBY_PAGE,
CONSENT_PAGE,
MANUAL_PAGE,
PRIVACY_PAGE,
SOLO_GAME_PAGE,
TOURNAMENT_DASHBOARD_PAGE,
} from "@port-of-mars/shared/routes";
@Component({})
Expand All @@ -110,13 +118,22 @@ export default class Footer extends Vue {
consent = { name: CONSENT_PAGE };
manual = { name: MANUAL_PAGE };
login = { name: LOGIN_PAGE };
lobby = { name: LOBBY_PAGE };
freePlayLobby = { name: FREE_PLAY_LOBBY_PAGE };
tournamentDashboard = { name: TOURNAMENT_DASHBOARD_PAGE };
privacy = { name: PRIVACY_PAGE };
solo = { name: SOLO_GAME_PAGE };
get constants() {
return Constants;
}
get isTournamentEnabled() {
return this.$tstore.state.isTournamentEnabled;
}
get isFreePlayEnabled() {
return this.$tstore.state.isFreePlayEnabled;
}
}
</script>

Expand Down
Loading

0 comments on commit 6ec3485

Please sign in to comment.