implement loot system feedback

This commit is contained in:
peter
2020-02-06 23:37:17 +01:00
parent b987974b9e
commit 5ace7357a4
22 changed files with 382 additions and 199 deletions
@@ -1,13 +1,25 @@
<nb-card
class = "col-12 col-xl-9"
status="control">
<nb-card-header [ngStyle]="{'color': color}" style="text-transform: capitalize;">
{{char.charactername}}
<nb-card-header style="text-transform: capitalize;">
<h4>
<a *ngIf="link === 'character'" [ngStyle]="{'color': color}" [routerLink]="'/frontcraft/character/'+char.charactername">
{{char.charactername}}
</a>
</h4>
<h3>
<span [ngStyle]="{'color': color}" *ngIf="link !== 'character'">
{{char.charactername}}
</span>
</h3>
</nb-card-header>
<nb-card-body>
{{char.race}}<br />
{{char.specname}} {{char.class}}<br />
Owned by <a [routerLink]="'/frontcraft/user/'+char.username"> {{char.username}} ({{char.rank}})</a>
<span *ngIf="link === 'owner'">
Owned by <a [routerLink]="'/frontcraft/user/'+char.username"> {{char.username}} ({{char.rank}})</a>
</span>
<br/><br />
<span *ngFor="let token of tokens">
[ {{token.level}} ]
@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ApiService as ApiService } from '../../services/login-api';
import { Spec, User, Character } from '../../../../../../backend/Types/Types';
@@ -10,6 +10,9 @@ import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
})
export class FrontcraftCharacterComponent implements OnInit{
@Input() name?: string
@Input() link?: "owner" | "character" = 'owner'
char : (Character & User & Spec) = {} as any
color : string
tokens
@@ -20,7 +23,9 @@ export class FrontcraftCharacterComponent implements OnInit{
){}
async ngOnInit(){
const param = this.route.snapshot.paramMap.get('name');
const param = this.name || this.route.snapshot.paramMap.get('name');
if(!param) return
this.api.get('CharacterManager')
.getCharacterByName(param)
.then((char) => {
@@ -6,9 +6,6 @@
</nb-card-body>
</nb-card>
<nb-card class="col-12 col-xl-9">
<nb-card-body>
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true" />
@@ -32,11 +32,12 @@ import { FrontcraftRaidComponent } from './raid/raid.component';
import { FrontcraftArchiveComponent } from './raid/archive.component';
import { NbEvaIconsModule } from '@nebular/eva-icons';
import { FrontcraftCharacerpickerComponent } from './raid/characterpicker.component';
import { FrontcraftShopComponent, FrontcraftBuyTokenComponent } from './shop/shop.component';
import { FrontcraftShopComponent } from './shop/shop.component';
import { FrontcraftRulesComponent } from './rules/rules.component';
import { FrontcraftItemSelectComponent } from './shop/itemselector.component';
import { NgxEchartsModule } from 'ngx-echarts';
import { FrontcraftCharactersComponent } from './characters/characters.component';
import { FrontcraftBuyTokenComponent } from './shop/buytoken.component';
@NgModule({
@@ -67,14 +67,15 @@
</div>
</nb-card-body>
</nb-card>
</ng-container>
</div>
</nb-tab>
<nb-tab tabTitle="Shop">
<shop (onSelect)="itemSelect($event)"></shop>
</nb-tab>
<nb-tab tabTitle="Reserves">
<nb-list>
<nb-list-item *ngFor="let item of raid.tokens | keyvalue">
<a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}"
target="_blank"
[href]="item.value[0].url">
@@ -5,6 +5,7 @@ import { RaidData, Raid, Signup } from '../../../../../../backend/Types/Types';
import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/theme';
import { FrontcraftCharacerpickerComponent } from './characterpicker.component';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { FrontcraftBuyTokenComponent } from '../shop/buytoken.component';
@Component({
selector: 'raid',
@@ -52,6 +53,15 @@ export class FrontcraftRaidComponent implements OnInit{
this.refresh()
}
itemSelect = async(item) => {
this.dialogService.open(FrontcraftBuyTokenComponent, {
context: {
item: item,
signup: this.mySignup
}
}).onClose.subscribe(() => this.refresh())
}
signup = async () => {
const signupFeature = this.api.get('signup')
if(!signupFeature) return
@@ -60,7 +70,7 @@ export class FrontcraftRaidComponent implements OnInit{
closeOnBackdropClick: true,
closeOnEsc: true,
context: {
'raid': this.raid,
raid: this.raid,
}
}).onClose.subscribe(()=>{
this.refresh()
@@ -83,7 +93,7 @@ export class FrontcraftRaidComponent implements OnInit{
const signupFeature = this.api.get('signup')
if(!signupFeature) return
await signupFeature.unsign(this.api.getAuth().token.value, this.mySignup, this.raid)
await signupFeature.unsign(this.api.getAuth().token.value, <any>{id: this.mySignup.characterid, userid: this.mySignup.userid}, this.raid)
this.toast.show('Success', 'Unsigned', { status: 'success' })
this.refresh()
}
@@ -102,7 +112,8 @@ export class FrontcraftRaidComponent implements OnInit{
})
const user = this.api.getCurrentUser()
const matchingSignup = Object.values(raiddata.participants).flat().find(char => user && char.userid === user.id!)
if(matchingSignup){
if(matchingSignup){
this.isSignedup = true
this.mySignup = matchingSignup
this.mySignup.status = matchingSignup['benched']?'Bench':matchingSignup['late']?'Late':'Attending'
@@ -4,7 +4,7 @@
<nb-tab tabTitle="Info">
Smart text here
</nb-tab>
<nb-tab *ngIf="managePriorities" tabTitle="priorities">
<nb-tab tabTitle="priorities">
<nb-list>
<nb-list-item *ngFor="let item of rules | keyvalue">
<a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}"
@@ -0,0 +1,104 @@
import { Component, OnInit, ContentChild, AfterContentInit, ViewChild, AfterViewInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService as ApiService } from '../../services/login-api';
import { FrontcraftItemSelectComponent } from './itemselector.component';
import { NbWindowService, NbWindowRef, NbToastrService, NbDialogService, NbDialogRef } from '@nebular/theme';
import { Item, Character, SRToken, Signup } from '../../../../../../backend/Types/Types';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
@Component({
selector: 'buyToken',
template: `
<nb-card class="col-12 col-xl-9">
<nb-card-header>
Buy {{item.itemname}}
</nb-card-header>
<nb-card-body>
<p>
You currently have {{currency}} softreserve currency
</p>
<div *ngIf="currency>0">
<div *ngFor="let kv of modifier | keyvalue">
<button
(click)="buyToken(kv.key)"
[disabled]="currency<=0"
nbButton
outline
status="success"
size="tiny">
buy
</button>
{{kv.key}} <span *ngIf="kv.value>0">(<b>+{{kv.value}}</b> from priorities)</span>
</div>
<div *ngFor="let token of ownedtokens">
<button
(click)="buyToken(token.charactername)"
nbButton
outline
status="success"
size="tiny">
buy
</button>
{{token.charactername}} [ {{token.level}} ] => [ {{token.level+1}} ]
</div>
</div>
</nb-card-body>
</nb-card>
`,
})
export class FrontcraftBuyTokenComponent implements OnInit{
@Input() item : Item
@Input() signup : Signup
@Input() tier: Tiers
characters: Character[]
modifier = {}
currency: number = 0
ownedtokens: SRToken[] = []
constructor(
private toastr: NbToastrService,
protected dialogRef: NbDialogRef<FrontcraftBuyTokenComponent>,
private api : ApiService
){}
ngOnInit(): void {
const usr = this.api.getCurrentUser()
this.api.get('CharacterManager')
.getCharactersOfUser(usr.username)
.then(chars => {
chars.forEach(char => {
char['color'] = getClassColor(char.class)
this.api.get('ItemManager').getToken(char, this.item).then(token => {
if(token) this.ownedtokens.push(token)
else{
this.api.get('ItemManager').calculatePriorities(this.item.itemname, char).then(modifier => {
this.modifier[char.charactername] = modifier
})
}
})
})
this.characters = chars
})
this.api.get('UserManager').getUser(usr.username).then(u => {
if(!u) return
this.currency = u.currency
})
}
buyToken = async (charactername:string) => {
const src = this.api.get('ItemManager')
const token = await src.buyToken(this.api.getAuth().token.value, charactername, this.item.itemname, this.signup)
if(token){
this.toastr.show(token.characterid+' now has a token for '+token.itemname+' of level '+token.level, 'Yay', {status: 'success'})
}else{
this.toastr.show('Error (something went wrong)', 'Oh no', {status: 'danger'})
}
this.dialogRef.close()
}
}
@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService } from '../../services/login-api';
import { Item } from '../../../../../../backend/Types/Types';
@@ -10,10 +10,11 @@ export class FrontcraftItemSelectComponent implements OnInit{
selected: Item
search: string
items: any[]
allItems:Item[] = []
displayedItems: any[]
callbacks = []
@Input() items: string[]
@Output() onSelect = new EventEmitter<Item>();
constructor(
private api: ApiService,
@@ -21,25 +22,23 @@ export class FrontcraftItemSelectComponent implements OnInit{
}
async ngOnInit(){
this.api.get('ItemManager').getItems().then(items => {
this.items = items
this.displayedItems = items
Promise.all(this.items.map(itemname =>
this.api.get('ItemManager').getItem(itemname)
)).then(items => {
this.allItems = items
this.displayedItems = this.allItems
})
}
changeSearch(){
if(!this.search || this.search == "")
this.displayedItems = this.items
this.displayedItems = this.allItems
else
this.displayedItems = this.items.filter(it => it.itemname.toLowerCase().includes(this.search.toLowerCase()))
this.displayedItems = this.allItems.filter(it => it.itemname.toLowerCase().includes(this.search.toLowerCase()))
}
select(item: Item){
this.selected = item
this.callbacks.forEach(cb => cb(item))
this.onSelect.emit(item)
}
onselect(callback:Function){
this.callbacks.push(callback)
}
}
@@ -1,13 +1,7 @@
<h3>
{{tier}} items
</h3>
<nb-card class="col-12 col-xl-9">
<nb-card-body>
<nb-tabset>
<nb-tab tabTitle="Items">
<itemselect></itemselect>
</nb-tab>
<nb-tab tabTitle="About">
</nb-tab>
</nb-tabset>
</nb-card-body>
</nb-card>
<itemselect
[items]="allItems[tier]"
(onSelect)="onSelect.emit($event)"></itemselect>
@@ -1,43 +1,28 @@
import { Component, OnInit, ContentChild, AfterContentInit, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, ContentChild, AfterContentInit, ViewChild, AfterViewInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService as ApiService } from '../../services/login-api';
import { FrontcraftItemSelectComponent } from './itemselector.component';
import { NbWindowService, NbWindowRef, NbToastrService, NbDialogService, NbDialogRef } from '@nebular/theme';
import { Item, Character, SRToken } from '../../../../../../backend/Types/Types';
import { Item, Character, SRToken, Signup } from '../../../../../../backend/Types/Types';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
import { _Tiers, allItems } from '../../../../../../backend/Types/Items';
@Component({
selector: 'shop',
templateUrl: './shop.component.html',
})
export class FrontcraftShopComponent implements AfterViewInit{
export class FrontcraftShopComponent{
@ViewChild(FrontcraftItemSelectComponent, {static: false})
itemselect !: FrontcraftItemSelectComponent
@Input() character: Character
@Input() signup: Signup
@Input() tier = _Tiers[0]
@Output() onSelect = new EventEmitter<Item>()
allItems = allItems
constructor(
private api: ApiService,
private dialogService : NbDialogService
){
window['shop'] = this
}
buy = (item) => {
this.dialogService.open(FrontcraftBuyTokenComponent, {
closeOnBackdropClick: true,
closeOnEsc: true,
context: {
item: item
}
}).onClose.subscribe(()=>{
});
}
ngAfterViewInit(){
this.itemselect.onselect(this.buy)
}
){}
}
@Component({
@@ -7,32 +7,8 @@ accent="info">
</nb-card-header>
<nb-card-body>
{{user.currency}}
<nb-card
accent="control"
*ngFor="let char of characters">
<nb-card-header>
<h4>
<a [ngStyle]="{'color': char.color}" style="text-transform: capitalize;" [routerLink]="'/frontcraft/character/'+char.charactername">
{{char.charactername}}
</a>
</h4>
</nb-card-header>
<nb-card-body>
{{char.race}}<br />
{{char.specname}} {{char.class}}
<br />
<br />
<span *ngFor="let token of char.tokens">
[ {{token.level}} ]
<a [ngStyle]="{'color':token.quality=='Epic'?'#a335ee':'#ff8000'}"
target="_blank"
[href]="token.url">
<img style="min-width: 25px; width: 2.25vw; max-width: 50px"
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+token.iconname+'.jpg'" />
{{token.itemname}}
</a><br />
</span>
</nb-card-body>
</nb-card>
<ng-container *ngFor="let char of characters">
<character [name]="char.charactername" [link]="'character'"></character>
</ng-container>
</nb-card-body>
</nb-card>
@@ -134,14 +134,6 @@ export class ApiService{
}
}
function str2arraybuf(str:string): ArrayBuffer {
return new Buffer(str)
}
function buf2hex(buffer: ArrayBuffer) {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
export async function hash(value:string) : Promise<string>{
return saltedHash(value, "")
}