Skip to content

Commit

Permalink
FEATURE (mercs): add team widget on the bounty map
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastientromp committed Oct 13, 2021
1 parent 5eac935 commit b6fdd9f
Show file tree
Hide file tree
Showing 26 changed files with 631 additions and 50 deletions.
9 changes: 9 additions & 0 deletions core/overwolf/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@
"start_position": { "top": 0, "left": 0 },
"in_game_only": true
},
"MercenariesOutOfCombatPlayerTeamWindow": {
"file": "Files/mercenaries_out_of_combat_player_team.html",
"transparent": true,
"resizable": true,
"show_in_taskbar": false,
"size": { "width": 530, "height": 800 },
"start_position": { "top": 0, "left": 0 },
"in_game_only": true
},

"CounterPlayerLibram": {
"file": "Files/counter_player_libram.html",
Expand Down
Binary file modified core/plugins/UnitySpy.HearthstoneLib.dll
Binary file not shown.
Binary file modified core/plugins/UnitySpy.HearthstoneLib.pdb
Binary file not shown.
173 changes: 173 additions & 0 deletions core/src/html/mercenaries_out_of_combat_player_team.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<!DOCTYPE html>
<html style="width: 100%; overflow: hidden; height: 100%">
<head>
<script type="text/javascript">
(function (e, t) {
var n = e.amplitude || { _q: [], _iq: {} };
var r = t.createElement('script');
r.type = 'text/javascript';
r.integrity = 'sha384-d/yhnowERvm+7eCU79T/bYjOiMmq4F11ElWYLmt0ktvYEVgqLDazh4+gW9CKMpYW';
r.crossOrigin = 'anonymous';
r.async = true;
r.src = 'https://cdn.amplitude.com/libs/amplitude-5.2.2-min.gz.js';
r.onload = function () {
if (!e.amplitude.runQueuedFunctions) {
console.log('[Amplitude] Error: could not load SDK');
}
};
var i = t.getElementsByTagName('script')[0];
i.parentNode.insertBefore(r, i);
function s(e, t) {
e.prototype[t] = function () {
this._q.push([t].concat(Array.prototype.slice.call(arguments, 0)));
return this;
};
}
var o = function () {
this._q = [];
return this;
};
var a = ['add', 'append', 'clearAll', 'prepend', 'set', 'setOnce', 'unset'];
for (var u = 0; u < a.length; u++) {
s(o, a[u]);
}
n.Identify = o;
var c = function () {
this._q = [];
return this;
};
var l = ['setProductId', 'setQuantity', 'setPrice', 'setRevenueType', 'setEventProperties'];
for (var p = 0; p < l.length; p++) {
s(c, l[p]);
}
n.Revenue = c;
var d = [
'init',
'logEvent',
'logRevenue',
'setUserId',
'setUserProperties',
'setOptOut',
'setVersionName',
'setDomain',
'setDeviceId',
'setGlobalUserProperties',
'identify',
'clearUserProperties',
'setGroup',
'logRevenueV2',
'regenerateDeviceId',
'groupIdentify',
'onInit',
'logEventWithTimestamp',
'logEventWithGroups',
'setSessionId',
'resetSessionId',
];
function v(e) {
function t(t) {
e[t] = function () {
e._q.push([t].concat(Array.prototype.slice.call(arguments, 0)));
};
}
for (var n = 0; n < d.length; n++) {
t(d[n]);
}
}
v(n);
n.getInstance = function (e) {
e = (!e || e.length === 0 ? '$default_instance' : e).toLowerCase();
if (!n._iq.hasOwnProperty(e)) {
n._iq[e] = { _q: [] };
v(n._iq[e]);
}
return n._iq[e];
};
e.amplitude = n;
})(window, document);

amplitude.getInstance().init('9c277b849857b1e890eef22bc4471f2e');
</script>

<title>Firestone - Mercenaries Out of Combat Player Team</title>
<meta charset="UTF-8" />
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,700" rel="stylesheet" />

<style>
.cdk-global-overlay-wrapper,
.cdk-overlay-container {
pointer-events: none;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.cdk-overlay-container {
position: fixed;
z-index: 1000;
}
.cdk-overlay-container:empty {
display: none;
}
.cdk-global-overlay-wrapper {
display: flex;
position: absolute;
z-index: 1000;
}
.cdk-overlay-pane {
position: absolute;
pointer-events: auto;
box-sizing: border-box;
z-index: 1000;
display: flex;
max-width: 100%;
max-height: 100%;
}
.cdk-overlay-backdrop {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
pointer-events: auto;
-webkit-tap-highlight-color: transparent;
transition: opacity 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
opacity: 0;
}
.cdk-overlay-backdrop.cdk-overlay-backdrop-showing {
opacity: 1;
}
@media screen and (-ms-high-contrast: active) {
.cdk-overlay-backdrop.cdk-overlay-backdrop-showing {
opacity: 0.6;
}
}
.cdk-overlay-dark-backdrop {
background: rgba(0, 0, 0, 0.32);
}
.cdk-overlay-transparent-backdrop,
.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing {
opacity: 0;
}
.cdk-overlay-connected-position-bounding-box {
position: absolute;
z-index: 1000;
display: flex;
flex-direction: column;
min-width: 1px;
min-height: 1px;
}
.cdk-global-scrollblock {
position: fixed;
width: 100%;
overflow-y: scroll;
}
</style>
</head>

<body style="width: 100%; height: 100%; overflow: hidden; padding: 0; margin: 0">
<mercenaries-out-of-combat-player-team></mercenaries-out-of-combat-player-team>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MercenariesBattleState } from '../../../../models/mercenaries/mercenaries-battle-state';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core';
import { Observable } from 'rxjs';
import { debounceTime, filter, map, tap } from 'rxjs/operators';
import { MercenariesBattleTeam } from '../../../../models/mercenaries/mercenaries-battle-state';
import { Preferences } from '../../../../models/preferences';
import { PreferencesService } from '../../../../services/preferences.service';
import { AppUiStoreService, cdLog } from '../../../../services/ui-store/app-ui-store.service';

@Component({
selector: 'mercenaries-opponent-team',
styleUrls: [],
template: ` <mercenaries-team-root
[teamExtractor]="teamExtractor"
[team$]="teamProvider$"
[side]="'opponent'"
[trackerPositionUpdater]="trackerPositionUpdater"
[trackerPositionExtractor]="trackerPositionExtractor"
Expand All @@ -17,12 +20,34 @@ import { PreferencesService } from '../../../../services/preferences.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MercenariesOpponentTeamComponent {
teamExtractor = (state: MercenariesBattleState) => state.opponentTeam;
// teamExtractor = (state: MercenariesBattleState) => state.opponentTeam;
trackerPositionUpdater = (left: number, top: number) => this.prefs.updateMercenariesTeamOpponentPosition(left, top);
trackerPositionExtractor = (prefs: Preferences) => prefs.mercenariesOpponentTeamOverlayPosition;
// Because whitespace for the tooltips
defaultTrackerPositionLeftProvider = (gameWidth: number, windowWidth: number) => -windowWidth / 2 + 250;
defaultTrackerPositionTopProvider = (gameHeight: number, windowHeight: number) => 50;
teamProvider$: Observable<MercenariesBattleTeam>;

constructor(private readonly prefs: PreferencesService) {}
constructor(
private readonly prefs: PreferencesService,
private readonly store: AppUiStoreService,
private readonly cdr: ChangeDetectorRef,
) {
this.teamProvider$ = this.store
.listenMercenaries$(([battleState, prefs]) => battleState)
.pipe(
debounceTime(50),
filter(([battleState]) => !!battleState),
map(([battleState]) => battleState.opponentTeam),
map((team) =>
team.update({
...team,
mercenaries: team.mercenaries.filter((merc) => !merc.isDead || !merc.creatorCardId),
}),
),
// FIXME
tap((filter) => setTimeout(() => this.cdr.detectChanges(), 0)),
tap((filter) => cdLog('emitting team in ', this.constructor.name, filter)),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core';
import { combineLatest, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map, tap } from 'rxjs/operators';
import { MemoryMercenary } from '../../../../models/memory/memory-mercenaries-info';
import {
BattleAbility,
BattleMercenary,
MercenariesBattleTeam,
} from '../../../../models/mercenaries/mercenaries-battle-state';
import { Preferences } from '../../../../models/preferences';
import { CardsFacadeService } from '../../../../services/cards-facade.service';
import { MercenariesReferenceData } from '../../../../services/mercenaries/mercenaries-state-builder.service';
import { getHeroRole } from '../../../../services/mercenaries/mercenaries-utils';
import { PreferencesService } from '../../../../services/preferences.service';
import { AppUiStoreService, cdLog } from '../../../../services/ui-store/app-ui-store.service';
import { arraysEqual } from '../../../../services/utils';

@Component({
selector: 'mercenaries-out-of-combat-player-team',
styleUrls: [],
template: ` <mercenaries-team-root
[team$]="teamProvider$"
[side]="'out-of-combat-player'"
[trackerPositionUpdater]="trackerPositionUpdater"
[trackerPositionExtractor]="trackerPositionExtractor"
[defaultTrackerPositionLeftProvider]="defaultTrackerPositionLeftProvider"
[defaultTrackerPositionTopProvider]="defaultTrackerPositionTopProvider"
></mercenaries-team-root>`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MercenariesOutOfCombatPlayerTeamComponent {
trackerPositionUpdater = (left: number, top: number) =>
this.prefs.updateMercenariesOutOfCombatTeamPlayerPosition(left, top);
trackerPositionExtractor = (prefs: Preferences) => prefs.mercenariesOutOfCombatPlayerTeamOverlayPosition;
defaultTrackerPositionLeftProvider = (gameWidth: number, windowWidth: number) => gameWidth - windowWidth / 2 - 180;
defaultTrackerPositionTopProvider = (gameHeight: number, windowHeight: number) => 10;
teamProvider$: Observable<MercenariesBattleTeam>;

constructor(
private readonly prefs: PreferencesService,
private readonly store: AppUiStoreService,
private readonly cdr: ChangeDetectorRef,
private readonly allCards: CardsFacadeService,
) {
this.teamProvider$ = combineLatest(
this.store.listenMercenariesOutOfCombat$(([state, prefs]) => state),
this.store.listen$(([main, nav, prefs]) => main.mercenaries?.referenceData),
).pipe(
tap((info) => console.debug('info', info)),
debounceTime(50),
filter(
([[state], [referenceData]]) =>
!!referenceData && !!state?.mercenariesMemoryInfo?.Map?.PlayerTeam?.length,
),
map(
([[state], [referenceData]]) =>
[state.mercenariesMemoryInfo.Map.PlayerTeam, referenceData] as [
readonly MemoryMercenary[],
MercenariesReferenceData,
],
),
distinctUntilChanged((a, b) => arraysEqual(a, b)),
map(([playerTeam, referenceData]) =>
MercenariesBattleTeam.create({
mercenaries: playerTeam.map((playerTeamInfo) => {
const refMerc = referenceData.mercenaries.find((merc) => merc.id === playerTeamInfo.Id);
console.debug('refMerc', playerTeamInfo.Id, refMerc, playerTeamInfo, referenceData);
const mercCard = this.allCards.getCardFromDbfId(refMerc.cardDbfId);
return BattleMercenary.create({
cardId: mercCard.id,
role: getHeroRole(mercCard.mercenaryRole),
level: playerTeamInfo.Level,
abilities: playerTeamInfo.Abilities.map((ability) => {
return BattleAbility.create({
cardId: ability.CardId,
});
}),
});
}),
}),
),
// FIXME
tap((filter) => setTimeout(() => this.cdr.detectChanges(), 0)),
tap((filter) => cdLog('emitting team in ', this.constructor.name, filter)),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MercenariesBattleState } from '../../../../models/mercenaries/mercenaries-battle-state';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core';
import { Observable } from 'rxjs';
import { debounceTime, filter, map, tap } from 'rxjs/operators';
import { MercenariesBattleTeam } from '../../../../models/mercenaries/mercenaries-battle-state';
import { Preferences } from '../../../../models/preferences';
import { PreferencesService } from '../../../../services/preferences.service';
import { AppUiStoreService, cdLog } from '../../../../services/ui-store/app-ui-store.service';

@Component({
selector: 'mercenaries-player-team',
styleUrls: [],
template: ` <mercenaries-team-root
[teamExtractor]="teamExtractor"
[team$]="teamProvider$"
[side]="'player'"
[trackerPositionUpdater]="trackerPositionUpdater"
[trackerPositionExtractor]="trackerPositionExtractor"
Expand All @@ -17,11 +20,33 @@ import { PreferencesService } from '../../../../services/preferences.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MercenariesPlayerTeamComponent {
teamExtractor = (state: MercenariesBattleState) => state.playerTeam;
// teamExtractor = (state: MercenariesBattleState) => state.playerTeam;
trackerPositionUpdater = (left: number, top: number) => this.prefs.updateMercenariesTeamPlayerPosition(left, top);
trackerPositionExtractor = (prefs: Preferences) => prefs.mercenariesPlayerTeamOverlayPosition;
defaultTrackerPositionLeftProvider = (gameWidth: number, windowWidth: number) => gameWidth - windowWidth / 2 - 180;
defaultTrackerPositionTopProvider = (gameHeight: number, windowHeight: number) => 10;
teamProvider$: Observable<MercenariesBattleTeam>;

constructor(private readonly prefs: PreferencesService) {}
constructor(
private readonly prefs: PreferencesService,
private readonly store: AppUiStoreService,
private readonly cdr: ChangeDetectorRef,
) {
this.teamProvider$ = this.store
.listenMercenaries$(([battleState, prefs]) => battleState)
.pipe(
debounceTime(50),
filter(([battleState]) => !!battleState),
map(([battleState]) => battleState.playerTeam),
map((team) =>
team.update({
...team,
mercenaries: team.mercenaries.filter((merc) => !merc.isDead || !merc.creatorCardId),
}),
),
// FIXME
tap((filter) => setTimeout(() => this.cdr.detectChanges(), 0)),
tap((filter) => cdLog('emitting team in ', this.constructor.name, filter)),
);
}
}
Loading

0 comments on commit b6fdd9f

Please sign in to comment.