diff --git a/assets/Data/GameSettings.json b/assets/Data/GameSettings.json index 2d59cfe..1d3d210 100644 --- a/assets/Data/GameSettings.json +++ b/assets/Data/GameSettings.json @@ -258,6 +258,13 @@ "goldReward": 1 } ], + "periodicFollowMovers": [ + { + "enemyIdToAffect": "BasicCheetah", + "followTime": 3, + "waitTime": 5 + } + ], "individualEnemySpawners": [ { "common": { diff --git a/assets/Scripts/Game/Data/GameSettings.ts b/assets/Scripts/Game/Data/GameSettings.ts index e52be9f..74ff556 100644 --- a/assets/Scripts/Game/Data/GameSettings.ts +++ b/assets/Scripts/Game/Data/GameSettings.ts @@ -66,11 +66,18 @@ export class MetaUpgradeSettings { export class EnemyManagerSettings { public enemies: EnemySettings[] = [new EnemySettings()]; + public periodicFollowMovers: PeriodicFollowMoverSettings[] = [new PeriodicFollowMoverSettings()]; public individualEnemySpawners: IndividualEnemySpawnerSettings[] = [new IndividualEnemySpawnerSettings()]; public circularEnemySpawners: CircularEnemySpawnerSettings[] = [new CircularEnemySpawnerSettings()]; public waveEnemySpawners: WaveEnemySpawnerSettings[] = [new WaveEnemySpawnerSettings()]; } +export class PeriodicFollowMoverSettings { + public enemyIdToAffect = ""; + public followTime = 0; + public waitTime = 0; +} + export class GeneralEnemySpawnerSettings { public enemyId = ""; public startDelay = 0; diff --git a/assets/Scripts/Game/Unit/Enemy/Enemy.ts b/assets/Scripts/Game/Unit/Enemy/Enemy.ts index 4142817..7385315 100644 --- a/assets/Scripts/Game/Unit/Enemy/Enemy.ts +++ b/assets/Scripts/Game/Unit/Enemy/Enemy.ts @@ -18,6 +18,7 @@ export class Enemy extends Component { private deathEvent: Signal = new Signal(); private lifetimeEndedEvent: Signal = new Signal(); + private id: string; private movementType: EnemyMovementType; private health: UnitHealth; private damage: number; @@ -31,6 +32,7 @@ export class Enemy extends Component { private endOfLifetimeTriggered = false; public setup(position: Vec3, settings: EnemySettings): void { + this.id = settings.id; this.movementType = settings.moveType; this.health = new UnitHealth(settings.health); this.damage = settings.damage; @@ -48,6 +50,10 @@ export class Enemy extends Component { this.endOfLifetimeTriggered = false; } + public get Id(): string { + return this.id; + } + public get MovementType(): EnemyMovementType { return this.movementType; } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts index 42417b6..30eb718 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts @@ -3,9 +3,9 @@ import { ISignal } from "../../../Services/EventSystem/ISignal"; import { EnemyManagerSettings } from "../../Data/GameSettings"; import { Enemy } from "./Enemy"; import { EnemyMovementType } from "./EnemyMovementType"; -import { EnemyMover } from "./EnemyMover/EnemyMover"; +import { IEnemyMover } from "./EnemyMover/EnemyMover"; import { FollowTargetEnemyMover } from "./EnemyMover/FollowTargetEnemyMover"; -import { PeriodicFollowTargetEnemyMover } from "./EnemyMover/PeriodicFollowTargetEnemyMover"; +import { PeriodicFollowMovers } from "./EnemyMover/PeriodicFollow/PeriodicFollowMovers"; import { WaveEnemyMover } from "./EnemyMover/WaveEnemyMover"; import { CircularEnemySpawner } from "./EnemySpawner/CircularEnemySpawner"; import { DelayedEnemySpawner } from "./EnemySpawner/DelayedEnemySpawner"; @@ -19,7 +19,7 @@ const { ccclass, property } = _decorator; export class EnemyManager extends Component { @property(EnemySpawner) private enemySpawner: EnemySpawner; - private movementTypeToMover: Map = new Map(); + private movementTypeToMover: Map = new Map(); private spawners: DelayedEnemySpawner[] = []; @@ -45,7 +45,7 @@ export class EnemyManager extends Component { this.movementTypeToMover.set(EnemyMovementType.Follow, new FollowTargetEnemyMover(targetNode)); this.movementTypeToMover.set(EnemyMovementType.Launch, new WaveEnemyMover(targetNode)); - this.movementTypeToMover.set(EnemyMovementType.PeriodicFollow, new PeriodicFollowTargetEnemyMover(targetNode, 5, 5)); + this.movementTypeToMover.set(EnemyMovementType.PeriodicFollow, new PeriodicFollowMovers(targetNode, settings.periodicFollowMovers)); } public gameTick(deltaTime: number): void { @@ -74,7 +74,7 @@ export class EnemyManager extends Component { this.getEnemyMover(enemy).removeEnemy(enemy); } - private getEnemyMover(enemy: Enemy): EnemyMover { + private getEnemyMover(enemy: Enemy): IEnemyMover { if (this.movementTypeToMover.has(enemy.MovementType)) { return this.movementTypeToMover.get(enemy.MovementType); } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/EnemyMover.ts b/assets/Scripts/Game/Unit/Enemy/EnemyMover/EnemyMover.ts index 2bf477c..e9ddd43 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyMover/EnemyMover.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/EnemyMover.ts @@ -1,7 +1,7 @@ import { Node } from "cc"; import { Enemy } from "../Enemy"; -export abstract class EnemyMover { +export abstract class EnemyMover implements IEnemyMover { protected targetNode: Node; protected enemies: Enemy[] = []; @@ -21,3 +21,9 @@ export abstract class EnemyMover { public abstract gameTick(deltaTime: number): void; } + +export interface IEnemyMover { + addEnemy(enemy: Enemy): void; + removeEnemy(enemy: Enemy): void; + gameTick(deltaTime: number): void; +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow.meta b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow.meta new file mode 100644 index 0000000..ecd43e8 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "6a81340e-e6eb-4fa0-9d0c-09d988986e6a", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowMovers.ts b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowMovers.ts new file mode 100644 index 0000000..aa8ef04 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowMovers.ts @@ -0,0 +1,39 @@ +import { Node } from "cc"; +import { PeriodicFollowMoverSettings } from "../../../../Data/GameSettings"; +import { Enemy } from "../../Enemy"; +import { IEnemyMover } from "../EnemyMover"; +import { PeriodicFollowTargetEnemyMover } from "./PeriodicFollowTargetEnemyMover"; + +export class PeriodicFollowMovers implements IEnemyMover { + private enemyIdToMover = new Map(); + public constructor(targetNode: Node, settings: PeriodicFollowMoverSettings[]) { + for (const moverSettings of settings) { + this.enemyIdToMover.set( + moverSettings.enemyIdToAffect, + new PeriodicFollowTargetEnemyMover(targetNode, moverSettings.followTime, moverSettings.waitTime) + ); + } + } + + public addEnemy(enemy: Enemy): void { + this.requireEnemyMover(enemy); + this.enemyIdToMover.get(enemy.Id).addEnemy(enemy); + } + + public removeEnemy(enemy: Enemy): void { + this.requireEnemyMover(enemy); + this.enemyIdToMover.get(enemy.Id).removeEnemy(enemy); + } + + public gameTick(deltaTime: number): void { + for (const enemyMover of this.enemyIdToMover.values()) { + enemyMover.gameTick(deltaTime); + } + } + + private requireEnemyMover(enemy: Enemy): void { + if (!this.enemyIdToMover.has(enemy.Id)) { + throw new Error("There is no periodic follow mover for enemy with id " + enemy.Id); + } + } +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowMovers.ts.meta b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowMovers.ts.meta new file mode 100644 index 0000000..35e35a6 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowMovers.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "dadbf2fc-29f0-4348-83e8-c186353581e9", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowTargetEnemyMover.ts similarity index 96% rename from assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts rename to assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowTargetEnemyMover.ts index 927a9ca..62be0ac 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowTargetEnemyMover.ts @@ -1,6 +1,6 @@ import { Node, Vec3 } from "cc"; -import { Enemy } from "../Enemy"; -import { EnemyMover } from "./EnemyMover"; +import { Enemy } from "../../Enemy"; +import { EnemyMover } from "../EnemyMover"; export class PeriodicFollowTargetEnemyMover extends EnemyMover { private enemyToFollowState: Map = new Map(); diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts.meta b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowTargetEnemyMover.ts.meta similarity index 100% rename from assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts.meta rename to assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollow/PeriodicFollowTargetEnemyMover.ts.meta