Skip to content

Commit 141d5b1

Browse files
authored
Merge pull request #70 from x-team/GAMESHQ_New-Scoreboard
🚀 GamesHQ: New TowerStatistics fields and display
2 parents cb60747 + 8dd3b3a commit 141d5b1

File tree

7 files changed

+115
-13
lines changed

7 files changed

+115
-13
lines changed

src/games/consts/emojis.ts

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const SAD_PARROT = ':sad-parrot:';
2929
export const FREE_AGENT_EMOJI = ':arena-hunter:';
3030
export const ARMOR_INVENTORY_EMOJI = ':shield:';
3131
export const WEAPON_INVENTORY_EMOJI = ':blaster:';
32+
export const WATCHMAN_EMOJI = ':watchman:';
3233

3334
// ARENA BOSS EMOJIS
3435
export const BOSS_EMOJI = ':arena-boss:';

src/games/tower/repositories/tower/actions/admin/create-or-finish-game.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Game } from '../../../../../../models';
33
import { startTowerGame } from '../../../../../../models/TowerGame';
44
import { findActiveRound } from '../../../../../../models/TowerRound';
55
import { findTowerStatisticsByGame } from '../../../../../../models/TowerStatistics';
6+
import { ZERO } from '../../../../../consts/global';
67
import type { GameResponse } from '../../../../../utils';
78
import { adminAction, getGameError, getGameResponse } from '../../../../../utils';
89
import { generateTowerEndGameConfirmationBlockKit } from '../../../../generators/gameplay';
@@ -145,7 +146,7 @@ export async function displayScoreboard(userRequesting: User) {
145146
if (!(activeTower instanceof Game)) {
146147
return activeTower as GameResponse;
147148
}
148-
const stats = await findTowerStatisticsByGame(activeTower.id, transaction);
149+
const stats = await findTowerStatisticsByGame(activeTower._tower?.id || ZERO, transaction);
149150
await publishTowerPublicMessage(towerCommandReply.adminDisplayScoreboard(activeTower, stats));
150151
return getGameResponse('Scoreboard displayed');
151152
});

src/games/tower/repositories/tower/actions/player/start-round.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import {
1212
import { addRaidersToTowerFloorBattlefield } from '../../../../../../models/TowerRaider';
1313
import { startRound } from '../../../../../../models/TowerRound';
1414
import { findAllActionsByRound } from '../../../../../../models/TowerRoundAction';
15-
import { updateTowerAsCompleted } from '../../../../../../models/TowerStatistics';
15+
import {
16+
updateTowerAsCompleted,
17+
updateTowerAttempts,
18+
} from '../../../../../../models/TowerStatistics';
1619
import { ONE, TWO, ZERO } from '../../../../../consts/global';
1720
import type { SlackBlockKitLayoutElement } from '../../../../../model/SlackBlockKit';
1821
import type { GameResponse } from '../../../../../utils';
@@ -72,6 +75,14 @@ export async function startRoundCommand(userRequesting: User) {
7275
await publishTowerPublicMessage(
7376
towerCommandReply.raiderLoseTower(raider._user?.slackId!, towerFloor.number)
7477
);
78+
const lastFloorVisited = towerFloor.number;
79+
await updateTowerAttempts(
80+
towerFloor._towerGameId,
81+
raider._user?.id ?? ZERO,
82+
lastFloorVisited,
83+
raider._perks ?? [],
84+
transaction
85+
);
7586
const blockKit = generateReEnterTowerQuestionSection(towerCommandReply.raiderMustEnter());
7687
await theTowerNotifyEphemeral('', raider._user?.slackId!, raider._user?.slackId!, blockKit);
7788
return getGameResponse('');
@@ -101,16 +112,18 @@ export async function startRoundCommand(userRequesting: User) {
101112
);
102113
} else {
103114
await round.endRound(transaction);
104-
105115
if (towerFloor.number === towerFloor._towerGame?.height) {
106116
await theTowerNotifyInPrivate(
107117
`${towerCommandReply.raiderWinsTower(raider._user?.slackId!)}\n\n` +
108118
`${towerCommandReply.finalStats(raider)}`,
109119
raider._user?.slackId!
110120
);
121+
const lastFloorVisited = towerFloor.number;
111122
await updateTowerAsCompleted(
112123
towerFloor._towerGameId,
113124
raider._user?.id ?? ZERO,
125+
lastFloorVisited,
126+
raider._perks ?? [],
114127
transaction
115128
);
116129
// TOWER PRIZE

src/games/tower/repositories/tower/engine/helpers/evaluate-hunt-raiders.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type { Transaction } from 'sequelize';
33

44
import type { TowerRaider } from '../../../../../../models';
55
import { perkImpactCalculator } from '../../../../../../models/Perk';
6+
import { findTowerFloorById } from '../../../../../../models/TowerFloor';
7+
import { updateLastHealth } from '../../../../../../models/TowerStatistics';
68
import { ONE, TRAIT, ZERO } from '../../../../../consts/global';
79
import { hasLuck } from '../../../../../utils';
810
import type { HuntPlayerParams } from '../../../../consts';
@@ -88,13 +90,27 @@ export async function huntRaiders(
8890
await randomTargetRaider.useArmor(targetArmor, transaction);
8991
}
9092
}
91-
93+
const lastHealth = randomTargetRaider.health;
9294
await randomTargetRaider.damageAndHide(
9395
damageDealtDetails.newDamage ?? damageDealtDetails.originalDamage,
9496
isEveryoneVisible,
9597
transaction
9698
);
9799

100+
if (!randomTargetRaider.isAlive()) {
101+
const towerFloor = await findTowerFloorById(
102+
randomTargetRaider._currentTowerFloorBattlefield?._towerFloorId ?? ZERO,
103+
true,
104+
transaction
105+
);
106+
await updateLastHealth(
107+
towerFloor?._towerGameId ?? ZERO,
108+
randomTargetRaider._userId,
109+
lastHealth,
110+
transaction
111+
);
112+
}
113+
98114
await randomTargetRaider.reloadFullInventory(transaction);
99115

100116
const dealtDamageMessage = towerEngineReply.enemyDealtDamage(

src/games/tower/repositories/tower/replies.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import type {
1212
import type { TOWER_ACTIONS_TYPE } from '../../../../models/TowerRoundAction';
1313
import {
1414
APPROVE_SIGN,
15-
FREE_AGENT_EMOJI,
1615
FULL_HEALTH_HEART_EMOJI,
1716
HEALTH_KIT_EMOJI,
1817
INFINITY_GIF_EMOJI,
1918
INITIATIVE_EMOJI,
2019
NO_ENTRY_SIGN,
2120
PLAYER_HIDE_EMOJI,
2221
PLAYER_VISIBLE_EMOJI,
22+
WATCHMAN_EMOJI,
2323
} from '../../../consts/emojis';
2424
import { SLACK_SPACE, TRAIT, ZERO } from '../../../consts/global';
2525
import {
@@ -61,9 +61,11 @@ function towerBasicScoreboard(towerStatistics: TowerStatistics[]) {
6161
return `${towerStatistics
6262
.map((raiderStats) => {
6363
return (
64-
`<@${raiderStats._user?.slackId}>\t*=>*\t` +
65-
`_${raiderStats.completed} *completed*_ ~ ` +
66-
`_${raiderStats.attempts} *attempts*_`
64+
` ${WATCHMAN_EMOJI} <@${raiderStats._user?.slackId}> *[* ${raiderStats.lastHealth} ${FULL_HEALTH_HEART_EMOJI} *]*\t*=>*\t` +
65+
`_*Reached to floor* ${raiderStats.lastFloorVisited}_ ` +
66+
`_*~ ${raiderStats.perks} Perks*_\t` +
67+
`_(${raiderStats.completed} *towers completed*)_`
68+
// `_${raiderStats.attempts} *attempts*_`
6769
);
6870
})
6971
.join('\n')}`;
@@ -144,8 +146,7 @@ export const towerCommandReply = {
144146
`\n*The Tower: ${game.name} Stats*\n` +
145147
`\n${towerBasicScoreboard(gameStatistics)}\n` +
146148
`\n*Notation*\n` +
147-
`> _house_emoji_ *|* _@raider_ *=>* _# of towers completed_ ~ _# of attempts_\n` +
148-
`> ${FREE_AGENT_EMOJI} (Free Agent)`,
149+
`> ${WATCHMAN_EMOJI} *|* _@raider_ *=>* _last floor visited_\t _(# of towers completed)_\n`,
149150
cancelEndGame: () =>
150151
`Ok, the tower is still open and active, nothing happened here, you can keep walking :cop:${randomSkinColor()}`,
151152
towerGatesInfo: (isOpen: boolean) => `The Tower Gates are ${isOpen ? '*open*' : '*closed*'}`,

src/games/tower/utils/leave-tower.ts

+18
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
import type { Transaction } from 'sequelize';
22

33
import type { TowerRaider, TowerRound } from '../../../models';
4+
import { findTowerFloorById } from '../../../models/TowerFloor';
5+
import { updateTowerAsCompleted } from '../../../models/TowerStatistics';
46
import { Ability } from '../../classes/GameAbilities';
7+
import { ZERO } from '../../consts/global';
58

69
export async function leaveTower(
710
{ raider, round }: { raider: TowerRaider; round?: TowerRound | null },
811
transaction: Transaction
912
) {
1013
if (round) {
14+
const towerFloor = (await findTowerFloorById(
15+
round._floorBattlefield?._towerFloorId!,
16+
true,
17+
transaction
18+
))!;
19+
const lastFloorVisited = towerFloor.number;
20+
await updateTowerAsCompleted(
21+
towerFloor._towerGameId,
22+
raider._user?.id ?? ZERO,
23+
lastFloorVisited,
24+
raider._perks ?? [],
25+
transaction
26+
);
27+
1128
await round.endRound(transaction);
1229
}
30+
1331
await raider.resetFullInventory(transaction);
1432
raider._towerFloorBattlefieldId = null;
1533
raider.abilitiesJSON = Ability.defaultProps();

src/models/TowerStatistics.ts

+55-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111

1212
import { ONE, ZERO } from '../games/consts/global';
1313

14-
import { User, TowerGame } from '.';
14+
import { User, TowerGame, Perk, PerkInventory } from '.';
1515

1616
interface TowerStatisticsAttributes {
1717
attempts: number;
@@ -31,7 +31,7 @@ interface TowerStatisticsCreationAttributes {
3131
indexes: [
3232
{
3333
unique: true,
34-
fields: ['_userId', '_gameId'],
34+
fields: ['_userId', '_towerGameId'],
3535
},
3636
],
3737
})
@@ -57,7 +57,7 @@ export class TowerStatistics
5757
declare _towerGameId: number;
5858

5959
@BelongsTo(() => TowerGame, {
60-
foreignKey: '_gameId',
60+
foreignKey: '_towerGameId',
6161
onUpdate: 'CASCADE',
6262
onDelete: 'CASCADE',
6363
})
@@ -69,6 +69,15 @@ export class TowerStatistics
6969
@Column(DataType.INTEGER)
7070
declare completed: number;
7171

72+
@Column(DataType.INTEGER)
73+
declare lastFloorVisited: number;
74+
75+
@Column(DataType.INTEGER)
76+
declare lastHealth: number;
77+
78+
@Column(DataType.INTEGER)
79+
declare perks: number;
80+
7281
static associations: {
7382
_user: Association<TowerStatistics, User>;
7483
_towerGame: Association<TowerStatistics, TowerGame>;
@@ -109,9 +118,18 @@ export async function findOrCreateTowerStatistics(
109118
return towerStatistics.reload({ transaction });
110119
}
111120

121+
function calculatePerkNumber(perks: Array<Perk & { PerkInventory: PerkInventory }>) {
122+
return perks.reduce(
123+
(totalPerks, { PerkInventory: { quantity } }) => totalPerks + (quantity ?? ZERO),
124+
ZERO
125+
);
126+
}
127+
112128
export async function updateTowerAsCompleted(
113129
gameId: number,
114130
userId: number,
131+
lastFloorVisited: number,
132+
perks: Array<Perk & { PerkInventory: PerkInventory }>,
115133
transaction?: Transaction
116134
) {
117135
const towerStats = await TowerStatistics.findOne({
@@ -122,7 +140,11 @@ export async function updateTowerAsCompleted(
122140
transaction,
123141
});
124142
if (towerStats) {
143+
const perksNumber = calculatePerkNumber(perks);
125144
await towerStats.increment({ completed: 1 }, { transaction });
145+
towerStats.lastFloorVisited = lastFloorVisited;
146+
towerStats.perks = perksNumber;
147+
await towerStats.save({ transaction });
126148
}
127149
}
128150

@@ -132,6 +154,9 @@ export function findTowerStatisticsByGame(gameId: number, transaction: Transacti
132154
_towerGameId: gameId,
133155
},
134156
order: [
157+
['lastFloorVisited', 'DESC'],
158+
['lastHealth', 'DESC'],
159+
['perks', 'ASC'],
135160
['completed', 'DESC'],
136161
['attempts', 'ASC'],
137162
],
@@ -147,6 +172,8 @@ export function findTowerStatisticsByGame(gameId: number, transaction: Transacti
147172
export async function updateTowerAttempts(
148173
gameId: number,
149174
userId: number,
175+
lastFloorVisited: number,
176+
perks: Array<Perk & { PerkInventory: PerkInventory }>,
150177
transaction?: Transaction
151178
) {
152179
const towerStats = await TowerStatistics.findOne({
@@ -157,6 +184,31 @@ export async function updateTowerAttempts(
157184
transaction,
158185
});
159186
if (towerStats) {
187+
const perksNumber = calculatePerkNumber(perks);
160188
await towerStats.increment({ attempts: 1 }, { transaction });
189+
towerStats.lastFloorVisited = lastFloorVisited;
190+
towerStats.perks = perksNumber;
191+
await towerStats.save({ transaction });
192+
}
193+
}
194+
195+
export async function updateLastHealth(
196+
gameId: number,
197+
userId: number,
198+
lastHealth: number,
199+
transaction?: Transaction
200+
) {
201+
const towerStats = await TowerStatistics.findOne({
202+
where: {
203+
_userId: userId,
204+
_towerGameId: gameId,
205+
},
206+
transaction,
207+
});
208+
if (towerStats) {
209+
console.log('============================================');
210+
console.log('Here ', lastHealth);
211+
towerStats.lastHealth = lastHealth;
212+
await towerStats.save({ transaction });
161213
}
162214
}

0 commit comments

Comments
 (0)