2021-09-25 23:21:50 +02:00
|
|
|
import { Fragment, FragmentById } from "./Fragment";
|
|
|
|
import { FragmentType } from "./FragmentType";
|
|
|
|
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
|
|
|
|
2021-10-05 05:51:39 +02:00
|
|
|
const noCharge = [FragmentType.None, FragmentType.Delete, FragmentType.Booster];
|
2021-09-25 23:21:50 +02:00
|
|
|
|
|
|
|
export interface IActiveFragmentParams {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
2021-10-16 23:12:04 +02:00
|
|
|
rotation: number;
|
2021-09-25 23:21:50 +02:00
|
|
|
fragment: Fragment;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ActiveFragment {
|
|
|
|
id: number;
|
|
|
|
charge: number;
|
2021-10-16 23:12:04 +02:00
|
|
|
rotation: number;
|
2021-09-25 23:21:50 +02:00
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
|
|
|
|
constructor(params?: IActiveFragmentParams) {
|
|
|
|
if (params) {
|
|
|
|
this.id = params.fragment.id;
|
|
|
|
this.x = params.x;
|
|
|
|
this.y = params.y;
|
2021-10-16 23:12:04 +02:00
|
|
|
this.charge = 0;
|
|
|
|
this.rotation = params.rotation;
|
2021-09-25 23:21:50 +02:00
|
|
|
} else {
|
|
|
|
this.id = -1;
|
|
|
|
this.x = -1;
|
|
|
|
this.y = -1;
|
|
|
|
this.charge = -1;
|
2021-10-16 23:12:04 +02:00
|
|
|
this.rotation = -1;
|
2021-09-25 23:21:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
collide(other: ActiveFragment): boolean {
|
|
|
|
const thisFragment = this.fragment();
|
|
|
|
const otherFragment = other.fragment();
|
|
|
|
// These 2 variables converts 'this' local coordinates to world to other local.
|
|
|
|
const dx: number = other.x - this.x;
|
|
|
|
const dy: number = other.y - this.y;
|
|
|
|
for (let j = 0; j < thisFragment.shape.length; j++) {
|
|
|
|
for (let i = 0; i < thisFragment.shape[j].length; i++) {
|
2021-10-16 23:12:04 +02:00
|
|
|
if (thisFragment.fullAt(i, j, this.rotation) && otherFragment.fullAt(i - dx, j - dy, other.rotation))
|
|
|
|
return true;
|
2021-09-25 23:21:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fragment(): Fragment {
|
|
|
|
const fragment = FragmentById(this.id);
|
2021-10-04 18:28:57 +02:00
|
|
|
if (fragment === null) throw new Error("ActiveFragment id refers to unknown Fragment.");
|
2021-09-25 23:21:50 +02:00
|
|
|
return fragment;
|
|
|
|
}
|
|
|
|
|
|
|
|
fullAt(worldX: number, worldY: number): boolean {
|
2021-10-16 23:12:04 +02:00
|
|
|
return this.fragment().fullAt(worldX - this.x, worldY - this.y, this.rotation);
|
2021-09-25 23:21:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
neighboors(): number[][] {
|
|
|
|
return this.fragment()
|
2021-10-16 23:12:04 +02:00
|
|
|
.neighboors(this.rotation)
|
2021-09-25 23:21:50 +02:00
|
|
|
.map((cell) => [this.x + cell[0], this.y + cell[1]]);
|
|
|
|
}
|
|
|
|
|
|
|
|
copy(): ActiveFragment {
|
|
|
|
// We have to do a round trip because the constructor.
|
|
|
|
const fragment = FragmentById(this.id);
|
2021-10-04 18:28:57 +02:00
|
|
|
if (fragment === null) throw new Error("ActiveFragment id refers to unknown Fragment.");
|
2021-10-16 23:12:04 +02:00
|
|
|
const c = new ActiveFragment({ x: this.x, y: this.y, rotation: this.rotation, fragment: fragment });
|
2021-09-25 23:21:50 +02:00
|
|
|
c.charge = this.charge;
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Serialize an active fragment to a JSON save state.
|
|
|
|
*/
|
|
|
|
toJSON(): any {
|
|
|
|
return Generic_toJSON("ActiveFragment", this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes an acive fragment from a JSON save state
|
|
|
|
*/
|
|
|
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
|
|
static fromJSON(value: any): ActiveFragment {
|
|
|
|
return Generic_fromJSON(ActiveFragment, value.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Reviver.constructors.ActiveFragment = ActiveFragment;
|