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