trade
This commit is contained in:
parent
758c358eea
commit
9007d94b0d
BIN
public/title-image.png
Normal file
BIN
public/title-image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
@ -8,6 +8,9 @@
|
||||
|
||||
<div class="ui-body">
|
||||
<div class="ui-text-secondary" style="padding: 16px;">👥 Bevölkerung: {{ population }} 🚀</div>
|
||||
<div class="ui-section">
|
||||
<div>Landebuchten: {{ planet.dockCapacity }}</div>
|
||||
</div>
|
||||
<div class="ui-section">
|
||||
<div>🏭 Produktion:</div>
|
||||
<ul>
|
||||
@ -33,12 +36,20 @@
|
||||
<li>{{ item.type }}: {{ item.demandRate * planet.population | number:'0.0-1' }}/s</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="ui-section">
|
||||
<div>📦 In Lieferung:</div>
|
||||
<ul>
|
||||
@for (item of goodsInTransit; track $index) {
|
||||
<li>{{ item.type }}: {{ item.amount | number:'0.0-1' }}</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui-section">
|
||||
<button class="button">Produktion upgraden</button>
|
||||
<button class="button" (click)="upgradeHarbour()" >Raumhafen upgraden</button>
|
||||
<button class="button">Siedeln</button>
|
||||
<button class="button" (click)="close()" >Schließen</button>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Component, inject, InjectionToken } from '@angular/core';
|
||||
import { Planet } from '../../../model/planet.model';
|
||||
import { Planet, TradeInstance } from '../../../model/planet.model';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Good } from '../../../model/goods/good.interface';
|
||||
@ -58,5 +58,14 @@ export class PlanetDialogComponent {
|
||||
close() {
|
||||
this.gameService.showPlanetInfo = undefined;
|
||||
}
|
||||
|
||||
get goodsInTransit(): TradeInstance[] {
|
||||
return this.planet.goodsInTransit;
|
||||
}
|
||||
|
||||
upgradeHarbour() {
|
||||
this.planet.upgradeHarbour()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -54,17 +54,26 @@
|
||||
<div>📦 Fracht:</div>
|
||||
<ul>
|
||||
@for (item of cargo; track $index) {
|
||||
<li>{{ item.type }}: {{ item.amount | number:'0.0-0' }}</li>
|
||||
<li>{{ item.type }}: {{ item.amount | number:'0.0-0' }} => {{ item.target }}</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="ui-section">
|
||||
<button class="button">Produktion upgraden</button>
|
||||
<button class="button">Siedeln</button>
|
||||
<button class="button" (click)="onClick($event); close();" >Schließen</button>
|
||||
<div>🛣️ Aktive Route:</div>
|
||||
<div class="flex route">
|
||||
@for (item of activeRoute; track $index) {
|
||||
<div>{{ item }}</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="ui-section">
|
||||
<button class="button">Produktion upgraden</button>
|
||||
<button class="button">Siedeln</button>
|
||||
<button class="button" (click)="onClick($event); close();" >Schließen</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@ -16,3 +16,7 @@ img {
|
||||
width: 92px;
|
||||
height: 92px;
|
||||
}
|
||||
|
||||
.route {
|
||||
padding: 16px 8px;
|
||||
}
|
||||
@ -38,4 +38,8 @@ export class ShipDialogComponent {
|
||||
event.stopPropagation();
|
||||
console.log(event)
|
||||
}
|
||||
|
||||
get activeRoute(): string[] {
|
||||
return this.ship.route?.planetNames ?? []
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import { GOODS_DATA } from "./goods/good-config";
|
||||
import { Good } from "./goods/good.interface";
|
||||
import { ShipUi } from "./ship";
|
||||
import { Ship } from "./ships/ship.model";
|
||||
import { GameService } from "../service/game.service";
|
||||
|
||||
export class Planet {
|
||||
public population: number = 100;
|
||||
@ -20,14 +21,16 @@ export class Planet {
|
||||
|
||||
private productionLevel: Map<GoodType, number> = new Map();
|
||||
private dockedShips: Ship[] = [];
|
||||
private dockCapacity: number = 0;
|
||||
public dockCapacity: number = 0;
|
||||
private shipsWaitingForDocking: Ship[] = [];
|
||||
|
||||
private gameService: GameService;
|
||||
|
||||
constructor(config: PlanetInit) {
|
||||
|
||||
constructor(config: PlanetInit, gameService: GameService) {
|
||||
this.name = config.name;
|
||||
this.image = config.name.toLowerCase().split(' ').join('-')
|
||||
|
||||
this.gameService = gameService;
|
||||
/** set all empty */
|
||||
Object.values(GoodType).forEach(c => {
|
||||
this.goods.set(c, {
|
||||
@ -128,9 +131,16 @@ export class Planet {
|
||||
continue; // Skip if we have enough in stock
|
||||
}
|
||||
|
||||
const inTransit = this.goodsInTransit.filter(g => g.type == good.type).reduce((acc, succ) => acc + succ.amount, 0);
|
||||
|
||||
if (demand < good.amount + inTransit) {
|
||||
continue; // Es werden genug geliefert.
|
||||
}
|
||||
|
||||
result.push({
|
||||
amount: demand * 3, // Request 3x buffer amount
|
||||
type: good.type
|
||||
type: good.type,
|
||||
target: this.name,
|
||||
})
|
||||
}
|
||||
|
||||
@ -138,7 +148,7 @@ export class Planet {
|
||||
}
|
||||
|
||||
get offeredGoods(): TradeInstance[] {
|
||||
return this.getAllGoods().filter(g => g.productionRate && g.amount).map(g => { return { type: g.type, amount: g.amount}})
|
||||
return this.getAllGoods().filter(g => g.productionRate && g.amount).map(g => { return { type: g.type, amount: g.amount, target: this.name }})
|
||||
}
|
||||
|
||||
// request(ship: ShipUi) {
|
||||
@ -282,6 +292,17 @@ export class Planet {
|
||||
console.log('wartend: ',this.shipsWaitingForDocking.map(d => d.name).join(','))
|
||||
}
|
||||
|
||||
get goodsInTransit(): TradeInstance[] {
|
||||
return this.gameService.ships
|
||||
.flatMap(ship => ship.cargoSpace)
|
||||
.filter(item => item.target === this.name);
|
||||
}
|
||||
|
||||
|
||||
upgradeHarbour() {
|
||||
this.dockCapacity++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export interface PlanetInit {
|
||||
@ -296,4 +317,5 @@ export interface PlanetInit {
|
||||
export interface TradeInstance {
|
||||
type: GoodType;
|
||||
amount: number;
|
||||
target: string;
|
||||
}
|
||||
@ -46,6 +46,10 @@ export class TradeRoute {
|
||||
}
|
||||
return demands;
|
||||
}
|
||||
|
||||
get planetNames(): string[] {
|
||||
return this.route.map(r => r.target.name);
|
||||
}
|
||||
}
|
||||
|
||||
interface ITradePlanet {
|
||||
|
||||
@ -159,27 +159,6 @@ export class ShipUi extends Phaser.Physics.Arcade.Sprite {
|
||||
}
|
||||
}
|
||||
|
||||
loadCargo(cargo: TradeInstance): number {
|
||||
const loaded = this.model.cargoSpace.reduce((acc, succ) => acc + succ.amount, 0);
|
||||
if (loaded >= this.model.cargoSize) { return 0; }
|
||||
|
||||
const remaining = this.model.cargoSize - loaded;
|
||||
const load = Math.min(remaining, cargo.amount);
|
||||
|
||||
const exists = this.model.cargoSpace.find(c => c.type == cargo.type);
|
||||
if (exists) {
|
||||
exists.amount += load
|
||||
} else {
|
||||
this.model.cargoSpace.push({
|
||||
amount: load,
|
||||
type: cargo.type
|
||||
})
|
||||
}
|
||||
|
||||
console.log(`Eingeladen: ${cargo.type}: ${load}`)
|
||||
|
||||
return load;
|
||||
}
|
||||
|
||||
activateRoute() {
|
||||
if (!this.model.route) { return; }
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { Good } from "../goods/good.interface";
|
||||
import { Planet, TradeInstance } from "../planet.model";
|
||||
import { TradeRoute } from "../routes/trade-route.model";
|
||||
|
||||
@ -6,11 +7,11 @@ export class Ship {
|
||||
public maxSpeed = 100;
|
||||
public currentSpeed = 0;
|
||||
|
||||
public cargoSize = 100;
|
||||
public cargoSize = 50;
|
||||
cargoSpace: TradeInstance[] = [];
|
||||
public route: TradeRoute | undefined = new TradeRoute([])
|
||||
public name = "Pioneer-01-" + Math.round(Math.random() * 100);
|
||||
public loadingSpeed = 1.5;
|
||||
public loadingSpeed = 3.5;
|
||||
|
||||
public status: 'loading' | 'unloading' | 'waiting' | 'idle' | 'traveling' = 'idle';
|
||||
public flightMode: FlightMode = FlightMode.Normal;
|
||||
@ -38,22 +39,15 @@ export class Ship {
|
||||
private async unloadGoods(planet: Planet) {
|
||||
if (!planet || this.cargoSpace.length == 0) { return Promise.resolve(null); }
|
||||
|
||||
const planetRequests = planet.requestedGoods;
|
||||
if (planetRequests.length == 0) { return Promise.resolve(null); }
|
||||
this.status = 'unloading';
|
||||
const delivering = this.cargoSpace.filter(cargo => cargo.target == planet.name);
|
||||
|
||||
for (const request of planetRequests) {
|
||||
const offer = this.cargoSpace.find(cargo => cargo.type == request.type);
|
||||
if (!offer) { continue; }
|
||||
|
||||
const transfer = Math.min(offer.amount, request.amount);
|
||||
const good = planet.getGood(offer.type);
|
||||
for (let dgood of delivering) {
|
||||
const good = planet.getGood(dgood.type);
|
||||
if (!good) { continue; }
|
||||
await this.removeFromCargoSpace({type: offer.type, amount: transfer});
|
||||
good.amount += transfer;
|
||||
|
||||
await this.removeFromCargoSpace({type: dgood.type, amount: dgood.amount, target: dgood.target}, good);
|
||||
}
|
||||
this.cargoSpace = this.cargoSpace.filter(c => c.amount != 0)
|
||||
|
||||
this.cargoSpace = this.cargoSpace.filter(c => c.amount != 0 && c.amount != undefined)
|
||||
return Promise.resolve(null);
|
||||
|
||||
}
|
||||
@ -77,7 +71,7 @@ export class Ship {
|
||||
demand.amount = Math.max(demand.amount, 0)
|
||||
if (demand.amount == 0) { continue; }
|
||||
const received = planet.request(demand);
|
||||
await this.addToCargoSpace({type: demand.type, amount: received})
|
||||
await this.addToCargoSpace({type: demand.type, amount: received, target: demand.target})
|
||||
}
|
||||
|
||||
return Promise.resolve(null)
|
||||
@ -87,13 +81,14 @@ export class Ship {
|
||||
return this.cargoSize - this.cargoSpace.reduce((acc, succ) => acc + succ.amount, 0)
|
||||
}
|
||||
|
||||
private async removeFromCargoSpace(cargo: TradeInstance) {
|
||||
private async removeFromCargoSpace(cargo: TradeInstance, to: Good) {
|
||||
const steps = Math.ceil(cargo.amount)
|
||||
|
||||
for (let i = 1; i <= steps; i++) {
|
||||
const existing = this.cargoSpace.find(c => c.type == cargo.type);
|
||||
if (existing) {
|
||||
existing.amount -= (cargo.amount / steps);
|
||||
to.amount += (cargo.amount / steps);
|
||||
}
|
||||
await this.waitForLoading(1)
|
||||
}
|
||||
@ -112,7 +107,8 @@ export class Ship {
|
||||
} else {
|
||||
this.cargoSpace.push({
|
||||
type: cargo.type,
|
||||
amount: cargo.amount / steps
|
||||
amount: cargo.amount / steps,
|
||||
target: cargo.target
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -106,6 +106,7 @@ export class MapScene extends Phaser.Scene {
|
||||
this.ships.push(s)
|
||||
this.physics.world.enable(s);
|
||||
s.activateRoute();
|
||||
this.gameService.ships.push(s.model)
|
||||
}
|
||||
|
||||
override update(time: number, delta: number): void {
|
||||
@ -120,7 +121,7 @@ export class MapScene extends Phaser.Scene {
|
||||
}
|
||||
private buildPlanets() {
|
||||
for (let config of PLANETCONFIGS) {
|
||||
const planet = new PlanetUi(this, config.x, config.y, config.texture, config.config);
|
||||
const planet = new PlanetUi(this, config.x, config.y, config.texture, config.config, this.gameService);
|
||||
planet.rightClick.subscribe(planet => {
|
||||
this.ship.moveTo(planet);
|
||||
this.isDragging = false;
|
||||
@ -130,6 +131,7 @@ export class MapScene extends Phaser.Scene {
|
||||
this.isDragging = false;
|
||||
});
|
||||
this.planets.push(planet);
|
||||
this.gameService.planets.push(planet.model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,9 @@ export class GameService {
|
||||
public showPlanetInfo: Planet | undefined;
|
||||
public showShipInfo: Ship | undefined;
|
||||
|
||||
public ships: Ship[] = [];
|
||||
public planets: Planet[] = [];
|
||||
|
||||
constructor() {}
|
||||
|
||||
showDialog(planet: Planet) {
|
||||
|
||||
@ -2,6 +2,7 @@ import { EventEmitter } from "@angular/core";
|
||||
import { interval } from "rxjs";
|
||||
import { Planet } from "../model/planet.model";
|
||||
import { PlanetStatus } from "./planet-status.ui";
|
||||
import { GameService } from "../service/game.service";
|
||||
|
||||
export class PlanetUi extends Phaser.Physics.Arcade.Sprite {
|
||||
|
||||
@ -12,12 +13,12 @@ export class PlanetUi extends Phaser.Physics.Arcade.Sprite {
|
||||
|
||||
private updateInterval = interval(1000)
|
||||
|
||||
constructor(scene: Phaser.Scene, x: number, y: number, texture: string, config: any) {
|
||||
constructor(scene: Phaser.Scene, x: number, y: number, texture: string, config: any, gameService: GameService) {
|
||||
super(scene, x, y, texture);
|
||||
// this.setDisplaySize(200, 200);
|
||||
|
||||
|
||||
this.model = new Planet(config);
|
||||
this.model = new Planet(config, gameService);
|
||||
|
||||
scene.add.existing(this);
|
||||
this.setInteractive({ useHandCursor: true });
|
||||
|
||||
@ -95,7 +95,7 @@ $font-size-base: 14px;
|
||||
|
||||
.ui-section {
|
||||
padding: 16px;
|
||||
border-top: 1px solid #202d3e;
|
||||
|
||||
|
||||
ul {
|
||||
margin: 8px 0 0 16px;
|
||||
@ -114,3 +114,7 @@ $font-size-base: 14px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ui-body > .ui-section {
|
||||
border-top: 1px solid #202d3e;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user