Compare commits

..

2 Commits

Author SHA1 Message Date
HardiReady 5d94be1c09 Provide highscore fraction colors depending on latest war 2019-10-11 16:53:26 +02:00
HardiReady 4cfa642228 Fix lint 2019-10-11 16:27:41 +02:00
9 changed files with 129 additions and 115 deletions

View File

@ -26,92 +26,100 @@ campaignPlayer.route('/ranking/:campaignId')
const warIds = wars.map((obj) => { const warIds = wars.map((obj) => {
return obj._id; return obj._id;
}); });
PlayerModel.find({warId: {'$in': warIds}}, (err, items) => { WarModel.findOne({campaign: req.params.campaignId}, {}, {sort: {'date': -1}}, (err, latestWar) => {
if (err) return next(err); PlayerModel.find({warId: {'$in': warIds}}, (err, items) => {
if (!items || items.length === 0) { if (err) return next(err);
const err = new Error('No players for given campaignId'); if (!items || items.length === 0) {
err.status = codes.notfound; const err = new Error('No players for given campaignId');
return next(err); err.status = codes.notfound;
} return next(err);
const rankingItems = [];
// check only first player to have valid steamUUID - then decide if tracked by name or by ID
const usesUUID = isSteamUUID(items[0].steamUUID);
new Set(items.map(usesUUID ? (x) => x.steamUUID : (x) => x.name))
.forEach((player) => {
const playerInstances = items.filter(
usesUUID ? (p) => p.steamUUID === player : (p) => p.name === player);
const resItem = {
name: usesUUID ? playerInstances[playerInstances.length - 1].name : player,
kill: 0,
vehicleLight: 0,
vehicleHeavy: 0,
vehicleAir: 0,
death: 0,
friendlyFire: 0,
revive: 0,
respawn: 0,
flagTouch: 0,
travelDistance: 0,
driverDistance: 0,
};
for (let i = 0; i < playerInstances.length; i++) {
const player = playerInstances[i];
resItem.kill += player.kill;
resItem.death += player.death;
resItem.friendlyFire += player.friendlyFire;
resItem.vehicleLight += player.vehicleLight;
resItem.vehicleHeavy += player.vehicleHeavy;
resItem.vehicleAir += player.vehicleAir;
resItem.revive += player.revive;
resItem.respawn += player.respawn;
resItem.flagTouch += player.flagTouch;
if (player.travelDistance) {
resItem.travelDistance += Math.round(player.travelDistance / 1000); // meters -> km
}
if (player.driverDistance) {
resItem.driverDistance += Math.round(player.driverDistance / 1000); // meters -> km
}
}
resItem.warCount = playerInstances.length;
resItem.fraction = playerInstances[playerInstances.length - 1].fraction;
rankingItems.push(resItem);
});
const getSortedField = (fieldName) => {
let num = 1;
const filteredSortResult = rankingItems.map((item) => {
return {
name: item.name,
fraction: item.fraction,
[fieldName]: item[fieldName],
};
})
.sort((a, b) => b[fieldName] - a[fieldName]);
const res = JSON.parse(JSON.stringify(filteredSortResult));
for (const entity of res) {
entity.num = num++;
} }
return res;
};
res.locals.items = { const rankingItems = [];
kill: getSortedField('kill'),
death: getSortedField('death'), // check only first player to have valid steamUUID - then decide if tracked by name or by ID
friendlyFire: getSortedField('friendlyFire'), const usesUUID = isSteamUUID(items[0].steamUUID);
vehicleLight: getSortedField('vehicleLight'),
vehicleHeavy: getSortedField('vehicleHeavy'), new Set(items.map(usesUUID ? (x) => x.steamUUID : (x) => x.name))
vehicleAir: getSortedField('vehicleAir'), .forEach((player) => {
revive: getSortedField('revive'), const playerInstances = items.filter(
respawn: getSortedField('respawn'), usesUUID ? (p) => p.steamUUID === player : (p) => p.name === player);
flagTouch: getSortedField('flagTouch'), const resItem = {
travelDistance: getSortedField('travelDistance'), name: usesUUID ? playerInstances[playerInstances.length - 1].name : player,
driverDistance: getSortedField('driverDistance'), kill: 0,
warCount: getSortedField('warCount'), vehicleLight: 0,
}; vehicleHeavy: 0,
next(); vehicleAir: 0,
death: 0,
friendlyFire: 0,
revive: 0,
respawn: 0,
flagTouch: 0,
travelDistance: 0,
driverDistance: 0,
};
for (let i = 0; i < playerInstances.length; i++) {
const player = playerInstances[i];
resItem.kill += player.kill;
resItem.death += player.death;
resItem.friendlyFire += player.friendlyFire;
resItem.vehicleLight += player.vehicleLight;
resItem.vehicleHeavy += player.vehicleHeavy;
resItem.vehicleAir += player.vehicleAir;
resItem.revive += player.revive;
resItem.respawn += player.respawn;
resItem.flagTouch += player.flagTouch;
if (player.travelDistance) {
resItem.travelDistance += Math.round(player.travelDistance / 1000); // meters -> km
}
if (player.driverDistance) {
resItem.driverDistance += Math.round(player.driverDistance / 1000); // meters -> km
}
}
resItem.warCount = playerInstances.length;
const latestPlayerFraction = playerInstances[playerInstances.length - 1].fraction;
resItem.fraction =
(latestPlayerFraction === 'OPFOR') ?
latestWar.fractionMappingOpfor :
latestWar.fractionMappingBlufor;
rankingItems.push(resItem);
});
const getSortedField = (fieldName) => {
let num = 1;
const filteredSortResult = rankingItems.map((item) => {
return {
name: item.name,
fraction: item.fraction,
[fieldName]: item[fieldName],
};
})
.sort((a, b) => b[fieldName] - a[fieldName]);
const res = JSON.parse(JSON.stringify(filteredSortResult));
for (const entity of res) {
entity.num = num++;
}
return res;
};
res.locals.items = {
kill: getSortedField('kill'),
death: getSortedField('death'),
friendlyFire: getSortedField('friendlyFire'),
vehicleLight: getSortedField('vehicleLight'),
vehicleHeavy: getSortedField('vehicleHeavy'),
vehicleAir: getSortedField('vehicleAir'),
revive: getSortedField('revive'),
respawn: getSortedField('respawn'),
flagTouch: getSortedField('flagTouch'),
travelDistance: getSortedField('travelDistance'),
driverDistance: getSortedField('driverDistance'),
warCount: getSortedField('warCount'),
};
next();
});
}); });
}); });
}) })

View File

@ -60,8 +60,8 @@ export interface War {
endDate?: string; endDate?: string;
ptBlufor?: number; ptBlufor?: number;
ptOpfor?: number; ptOpfor?: number;
fractionMappingBlufor?: Fraction.SWORD | Fraction.ARF | "BLUFOR" | "OPFOR"; fractionMappingBlufor?: Fraction.SWORD | Fraction.ARF | 'BLUFOR' | 'OPFOR';
fractionMappingOpfor?: Fraction.SWORD | Fraction.ARF | "BLUFOR" | "OPFOR"; fractionMappingOpfor?: Fraction.SWORD | Fraction.ARF | 'BLUFOR' | 'OPFOR';
playersBlufor?: number; playersBlufor?: number;
playersOpfor?: number; playersOpfor?: number;
budgetBlufor?: number; budgetBlufor?: number;

View File

@ -28,7 +28,7 @@
<ng-container matColumnDef="name"> <ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>{{'stats.highscore.header.name' | translate}}</th> <th mat-header-cell *matHeaderCellDef>{{'stats.highscore.header.name' | translate}}</th>
<td mat-cell *matCellDef="let element" <td mat-cell *matCellDef="let element"
[style.color]="element['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR"> [style.color]="fractionHelpers.getFractionColor(element['fraction'])">
{{element.name}} {{element.name}}
</td> </td>
</ng-container> </ng-container>

View File

@ -1,11 +1,11 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute} from '@angular/router';
import {PlayerService} from '../../../services/logs/player.service'; import {PlayerService} from '../../../services/logs/player.service';
import {Fraction} from '../../../utils/fraction.enum';
import {FormControl} from '@angular/forms'; import {FormControl} from '@angular/forms';
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import {Player} from '../../../models/model-interfaces'; import {Player} from '../../../models/model-interfaces';
import {PlayerUtils} from '../../../utils/player-utils'; import {PlayerUtils} from '../../../utils/player-utils';
import {FractionHelpers} from '../../../utils/global.helpers';
@Component({ @Component({
@ -25,7 +25,7 @@ export class StatisticHighScoreComponent implements OnInit {
playerAttributeDisplayNames = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length); playerAttributeDisplayNames = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length);
readonly fraction = Fraction; readonly fractionHelpers = FractionHelpers;
constructor(private route: ActivatedRoute, constructor(private route: ActivatedRoute,
private playerService: PlayerService) { private playerService: PlayerService) {

View File

@ -1,6 +1,5 @@
import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core'; import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
import {ChartUtils} from '../../../utils/chart-utils'; import {ChartUtils} from '../../../utils/chart-utils';
import {Fraction} from '../../../utils/fraction.enum';
import {War} from '../../../models/model-interfaces'; import {War} from '../../../models/model-interfaces';
import {TranslateService} from '@ngx-translate/core'; import {TranslateService} from '@ngx-translate/core';
import {FractionHelpers} from '../../../utils/global.helpers'; import {FractionHelpers} from '../../../utils/global.helpers';
@ -75,18 +74,18 @@ export class FractionStatsComponent implements OnInit, OnChanges {
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
if (changes.war || changes.logData) { if (changes.war || changes.logData) {
this.fractionNameBlufor = FractionHelpers.getFractionName(this.war, "BLUFOR"); this.fractionNameBlufor = FractionHelpers.getFractionName(this.war, 'BLUFOR');
this.fractionNameOpfor = FractionHelpers.getFractionName(this.war, "OPFOR"); this.fractionNameOpfor = FractionHelpers.getFractionName(this.war, 'OPFOR');
this.colorScheme = { this.colorScheme = {
domain: [ domain: [
FractionHelpers.getFractionColor(this.war, "BLUFOR"), FractionHelpers.getFractionColor('BLUFOR', this.war),
FractionHelpers.getFractionColor(this.war, "OPFOR"), FractionHelpers.getFractionColor('OPFOR', this.war),
FractionHelpers.getFractionColor(this.war, "BLUFOR", 'LIGHT'), FractionHelpers.getFractionColor('BLUFOR', this.war, 'LIGHT'),
FractionHelpers.getFractionColor(this.war, "OPFOR", 'LIGHT'), FractionHelpers.getFractionColor('OPFOR', this.war, 'LIGHT'),
FractionHelpers.getFractionColor(this.war, "BLUFOR", 'DARK'), FractionHelpers.getFractionColor('BLUFOR', this.war, 'DARK'),
FractionHelpers.getFractionColor(this.war, "OPFOR", 'DARK'), FractionHelpers.getFractionColor('OPFOR', this.war, 'DARK'),
FractionHelpers.getFractionColor(this.war, "BLUFOR", 'GREY'), FractionHelpers.getFractionColor('BLUFOR', this.war, 'GREY'),
FractionHelpers.getFractionColor(this.war, "OPFOR", 'GREY'), FractionHelpers.getFractionColor('OPFOR', this.war, 'GREY'),
] ]
}; };

View File

@ -8,7 +8,7 @@
<mat-header-cell *matHeaderCellDef <mat-header-cell *matHeaderCellDef
mat-sort-header="{{tableHead[0].prop}}">{{tableHead[0].head | translate}}</mat-header-cell> mat-sort-header="{{tableHead[0].prop}}">{{tableHead[0].head | translate}}</mat-header-cell>
<mat-cell *matCellDef="let element" <mat-cell *matCellDef="let element"
[style.color]="fractionHelpers.getFractionColor(war, element['fraction'])"> [style.color]="fractionHelpers.getFractionColor(element['fraction'],war)">
{{element.name}} {{element.name}}
</mat-cell> </mat-cell>
</ng-container> </ng-container>

View File

@ -2,12 +2,12 @@
<div class="war-header-container"> <div class="war-header-container">
<div class="pull-left head-field"> <div class="pull-left head-field">
<h4>{{'stats.scoreboard.standings' | translate}}</h4> <h4>{{'stats.scoreboard.standings' | translate}}</h4>
<span [style.color]="fractionHelpers.getFractionColor(war, 'BLUFOR')" <span [style.color]="fractionHelpers.getFractionColor('BLUFOR',war)"
style="font-weight: bold; margin-right: 10px"> style="font-weight: bold; margin-right: 10px">
{{fractionHelpers.getFractionName(war, 'BLUFOR')}} {{war.ptBlufor}} {{fractionHelpers.getFractionName(war, 'BLUFOR')}} {{war.ptBlufor}}
</span> </span>
<span style="font-size: x-large">|</span> <span style="font-size: x-large">|</span>
<span [style.color]="fractionHelpers.getFractionColor(war, 'OPFOR')" <span [style.color]="fractionHelpers.getFractionColor('OPFOR',war)"
style="font-weight: bold; margin-left: 10px;"> style="font-weight: bold; margin-left: 10px;">
{{war.ptOpfor}} {{fractionHelpers.getFractionName(war, 'OPFOR')}} {{war.ptOpfor}} {{fractionHelpers.getFractionName(war, 'OPFOR')}}
</span> </span>
@ -15,12 +15,12 @@
<div class="pull-left head-field" style="margin-top:0" *ngIf="isSmallLayout"> <div class="pull-left head-field" style="margin-top:0" *ngIf="isSmallLayout">
<h4>{{'stats.scoreboard.participants' | translate}}</h4> <h4>{{'stats.scoreboard.participants' | translate}}</h4>
<span [style.color]="fractionHelpers.getFractionColor(war, 'BLUFOR')" <span [style.color]="fractionHelpers.getFractionColor('BLUFOR',war)"
style="font-weight: bold; margin-right: 10px"> style="font-weight: bold; margin-right: 10px">
{{fractionHelpers.getFractionName(war, 'BLUFOR')}} {{war.playersBlufor}} {{fractionHelpers.getFractionName(war, 'BLUFOR')}} {{war.playersBlufor}}
</span> </span>
<span style="font-size: 13px;font-weight: bold;">vs</span> <span style="font-size: 13px;font-weight: bold;">vs</span>
<span [style.color]="fractionHelpers.getFractionColor(war, 'OPFOR')" <span [style.color]="fractionHelpers.getFractionColor('OPFOR',war)"
style="font-weight: bold; margin-left: 10px;"> style="font-weight: bold; margin-left: 10px;">
{{war.playersOpfor}} {{fractionHelpers.getFractionName(war, 'OPFOR')}} {{war.playersOpfor}} {{fractionHelpers.getFractionName(war, 'OPFOR')}}
</span> </span>

View File

@ -67,8 +67,8 @@ export class WarHeaderComponent implements OnInit {
this.colorScheme = { this.colorScheme = {
domain: [ domain: [
FractionHelpers.getFractionColor(war, 'OPFOR'), FractionHelpers.getFractionColor('OPFOR', war),
FractionHelpers.getFractionColor(war, 'BLUFOR') FractionHelpers.getFractionColor('BLUFOR', war)
] ]
}; };

View File

@ -13,8 +13,15 @@ export const CSSHelpers = {
}; };
export const FractionHelpers = { export const FractionHelpers = {
getFractionColor: (war: War, fraction, style?) => { getFractionColor: (fraction, war?: War, style?) => {
switch (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor) { let switchInput;
if (war) {
switchInput = (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor);
} else {
switchInput = fraction;
}
switch (switchInput) {
case Fraction.ARF: case Fraction.ARF:
switch (style) { switch (style) {
case 'LIGHT': case 'LIGHT':
@ -26,7 +33,7 @@ export const FractionHelpers = {
default: default:
return Fraction.COLOR_ARF; return Fraction.COLOR_ARF;
} }
case "BLUFOR": case 'BLUFOR':
switch (style) { switch (style) {
case 'LIGHT': case 'LIGHT':
return Fraction.COLOR_BLUFOR_LIGHT; return Fraction.COLOR_BLUFOR_LIGHT;
@ -37,7 +44,7 @@ export const FractionHelpers = {
default: default:
return Fraction.COLOR_BLUFOR; return Fraction.COLOR_BLUFOR;
} }
case "OPFOR": case 'OPFOR':
switch (style) { switch (style) {
case 'LIGHT': case 'LIGHT':
return Fraction.COLOR_OPFOR_LIGHT; return Fraction.COLOR_OPFOR_LIGHT;
@ -66,9 +73,9 @@ export const FractionHelpers = {
switch (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor) { switch (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor) {
case Fraction.ARF: case Fraction.ARF:
return Fraction.COLOR_ARF; return Fraction.COLOR_ARF;
case "BLUFOR": case 'BLUFOR':
return Fraction.COLOR_BLUFOR; return Fraction.COLOR_BLUFOR;
case "OPFOR": case 'OPFOR':
return Fraction.COLOR_OPFOR; return Fraction.COLOR_OPFOR;
case Fraction.SWORD: case Fraction.SWORD:
return Fraction.COLOR_SWORD; return Fraction.COLOR_SWORD;
@ -79,9 +86,9 @@ export const FractionHelpers = {
switch (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor) { switch (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor) {
case Fraction.ARF: case Fraction.ARF:
return Fraction.ARF; return Fraction.ARF;
case "BLUFOR": case 'BLUFOR':
return Fraction.BLUFOR; return Fraction.BLUFOR;
case "OPFOR": case 'OPFOR':
return Fraction.OPFOR; return Fraction.OPFOR;
case Fraction.SWORD: case Fraction.SWORD:
return Fraction.SWORD; return Fraction.SWORD;