day 5
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { Object3D } from "three";
|
||||
import { PhysicsBody } from "../PhysicsC";
|
||||
import { PropType } from "./PropType";
|
||||
import { PhysicsTriggerC } from "./PhysicsTriggerC";
|
||||
import { PROP_DROPS } from "../Resources/PropDropTable";
|
||||
import { createDropPlan, PropDropPlan } from "../Resources/PropDropPlanner";
|
||||
import { ResourceSpawnC } from "../Resources/ResourceSpawnC";
|
||||
|
||||
export class PropRegistry {
|
||||
private static props = new Map<Object3D, PropC>();
|
||||
|
||||
static register(prop: PropC) {
|
||||
this.props.set(prop.object, prop);
|
||||
}
|
||||
|
||||
static get(object: Object3D) {
|
||||
return this.props.get(object);
|
||||
}
|
||||
}
|
||||
|
||||
export class PropC {
|
||||
readonly object: Object3D;
|
||||
readonly propType: PropType;
|
||||
health: number;
|
||||
readonly maxHealth: number;
|
||||
isBroken = false;
|
||||
|
||||
private wallBodies: PhysicsBody[] = [];
|
||||
private dropPlan: PropDropPlan | null = null;
|
||||
|
||||
constructor(object: Object3D, propType: PropType, maxHealth = 3) {
|
||||
this.object = object;
|
||||
this.propType = propType;
|
||||
this.maxHealth = maxHealth;
|
||||
this.health = maxHealth;
|
||||
PropRegistry.register(this);
|
||||
}
|
||||
|
||||
addWallBody(physicsBody: PhysicsBody) {
|
||||
this.wallBodies.push(physicsBody);
|
||||
}
|
||||
|
||||
takeDamage(amount: number): boolean {
|
||||
if (this.isBroken) return false;
|
||||
|
||||
const hitIndex = this.maxHealth - this.health;
|
||||
this.ensureDropPlan();
|
||||
|
||||
this.health -= amount;
|
||||
this.spawnForHit(hitIndex);
|
||||
|
||||
if (this.health > 0) return false;
|
||||
|
||||
this.break();
|
||||
return true;
|
||||
}
|
||||
|
||||
break() {
|
||||
if (this.isBroken) return;
|
||||
|
||||
this.isBroken = true;
|
||||
this.object.visible = false;
|
||||
|
||||
this.wallBodies.forEach((body) => body.destroy());
|
||||
this.wallBodies = [];
|
||||
|
||||
PhysicsTriggerC.unregister(this.object);
|
||||
}
|
||||
|
||||
private ensureDropPlan() {
|
||||
if (this.dropPlan) return;
|
||||
|
||||
const rules = PROP_DROPS[this.propType];
|
||||
if (!rules.length) return;
|
||||
|
||||
this.dropPlan = createDropPlan(this.maxHealth, rules[0]);
|
||||
}
|
||||
|
||||
private spawnForHit(hitIndex: number) {
|
||||
if (!this.dropPlan) return;
|
||||
|
||||
let spawnCount = this.dropPlan.hitAmounts[hitIndex] ?? 0;
|
||||
|
||||
if (this.health <= 0) {
|
||||
const remaining = this.dropPlan.totalDrop - this.dropPlan.spawnedDrop - spawnCount;
|
||||
if (remaining > 0) {
|
||||
spawnCount += remaining;
|
||||
}
|
||||
}
|
||||
|
||||
if (spawnCount <= 0) return;
|
||||
|
||||
ResourceSpawnC.spawnFromProp(this, this.dropPlan.resource, spawnCount);
|
||||
this.dropPlan.spawnedDrop += spawnCount;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user