-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'Team-7--Tower-Extension' of https://github.com/UQcsse32…
…00/2023-studio-3 into Team-7--Tower-Extension
- Loading branch information
Showing
8 changed files
with
450 additions
and
3 deletions.
There are no files selected for viewing
1 change: 0 additions & 1 deletion
1
...mponents/BombShipAnimationController.java → ...s/player/BombShipAnimationController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
//BombshipController | ||
package com.csse3200.game.components.npc; | ||
|
||
import com.csse3200.game.components.Component; | ||
|
176 changes: 176 additions & 0 deletions
176
source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipCombatTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
package com.csse3200.game.components.tasks; | ||
|
||
import com.badlogic.gdx.math.Vector2; | ||
import com.csse3200.game.ai.tasks.DefaultTask; | ||
import com.csse3200.game.ai.tasks.PriorityTask; | ||
import com.csse3200.game.entities.Entity; | ||
import com.csse3200.game.entities.factories.ProjectileFactory; | ||
import com.csse3200.game.physics.PhysicsEngine; | ||
import com.csse3200.game.physics.PhysicsLayer; | ||
import com.csse3200.game.physics.raycast.RaycastHit; | ||
import com.csse3200.game.services.GameTime; | ||
import com.csse3200.game.services.ServiceLocator; | ||
|
||
import java.util.ArrayList; | ||
|
||
/** | ||
* The AI Task for the Engineer entity. The Engineer will scan for targets within its detection range | ||
* and trigger events to change its state accordingly. This task must be called once the Engineer has | ||
* appropiately moved into position. | ||
*/ | ||
public class BombshipCombatTask extends DefaultTask implements PriorityTask { | ||
|
||
private static final int INTERVAL = 1; // The time interval for each target scan from the Engineer. | ||
private static final int PRIORITY = 3; // Default priority of the combat task when mobs are in range. | ||
private static final short TARGET1 = PhysicsLayer.BOSS; // The type of targets that the Engineer will detect. | ||
private static final short TARGET2 = PhysicsLayer.XENO; | ||
|
||
// Animation event names for the Engineer's state machine. | ||
private static final String START = "start"; | ||
private static final String IDLE = "idle"; | ||
private static final String DESTROY = "destroy"; | ||
|
||
// The Engineer's attributes. | ||
private final float maxRange; // The maximum range of the bombship. | ||
|
||
private Vector2 bombShipPosition = new Vector2(0, 0); // Placeholder value for the Engineer's position. | ||
private final Vector2 maxRangePosition = new Vector2(); | ||
private PhysicsEngine physics; | ||
private GameTime timeSource; | ||
private long endTime; | ||
private long reloadTime; | ||
|
||
private ArrayList<RaycastHit> hits = new ArrayList<>(); | ||
private final RaycastHit hit = new RaycastHit(); | ||
private ArrayList<Vector2> targets = new ArrayList<>(); | ||
|
||
/** The Engineer's states. */ | ||
private enum STATE { | ||
IDLE, START , DESTROY | ||
} | ||
private STATE bombshipState = STATE.IDLE; | ||
|
||
public BombshipCombatTask(float maxRange) { | ||
this.maxRange = maxRange; | ||
physics = ServiceLocator.getPhysicsService().getPhysics(); | ||
timeSource = ServiceLocator.getTimeSource(); | ||
} | ||
|
||
/** | ||
* Runs the task and triggers Bombship's idle animation. | ||
*/ | ||
@Override | ||
public void start() { | ||
super.start(); | ||
this.bombShipPosition = owner.getEntity().getCenterPosition(); | ||
this.maxRangePosition.set(bombShipPosition.x + maxRange, bombShipPosition.y); | ||
// Default to idle mode | ||
owner.getEntity().getEvents().trigger(IDLE); | ||
endTime = timeSource.getTime() + (INTERVAL * 600); | ||
} | ||
|
||
/** | ||
* The update method is what is run every time the TaskRunner in the AiTaskComponent calls update(). | ||
* triggers events depending on the presence or otherwise of targets in the detection range | ||
*/ | ||
@Override | ||
public void update() { | ||
if (timeSource.getTime() >= endTime) { | ||
updateBombshipState(); | ||
endTime = timeSource.getTime() + (INTERVAL * 1200); | ||
} | ||
} | ||
|
||
/** | ||
* Bombship state machine | ||
*/ | ||
public void updateBombshipState() { | ||
// configure engineer state depending on target visibility | ||
switch (bombshipState) { | ||
case IDLE -> { | ||
// targets detected in idle mode - start deployment | ||
if (isEngineerDied()) { | ||
combatState(); | ||
} | ||
} | ||
case START -> { | ||
// targets gone - stop firing | ||
if (!isEngineerDied()) { | ||
owner.getEntity().getEvents().trigger(IDLE); | ||
bombshipState = STATE.IDLE; | ||
} else { | ||
owner.getEntity().getEvents().trigger(START); | ||
} | ||
} | ||
case DESTROY -> { | ||
owner.getEntity().getEvents().trigger(DESTROY); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Puts the BombshipCombatTask state into combat mode | ||
*/ | ||
private void combatState() { | ||
owner.getEntity().getEvents().trigger(START); | ||
bombshipState = STATE.START; | ||
} | ||
/** | ||
* For stopping the running task | ||
*/ | ||
@Override | ||
public void stop() { | ||
super.stop(); | ||
} | ||
|
||
/** | ||
* Simplified getPriority function, returns the priority of the task | ||
* @return priority as an integer value. If mobs are visible, return the current priority, otherwise return 0. | ||
*/ | ||
@Override | ||
public int getPriority() { | ||
return isEngineerDied() ? PRIORITY : 0; | ||
} | ||
|
||
/** | ||
* Uses a raycast to determine whether there are any targets in detection range. Performs multiple raycasts | ||
* to a range of points at x = engineer.x + maxRange, and a range of y values above and below current y position. | ||
* Allows the bombship entity to detect mobs in adjacent lanes. | ||
* @return true if a target is detected, false otherwise | ||
*/ | ||
public boolean isEngineerDied() { | ||
// If there is an obstacle in the path to the max range point, mobs visible. | ||
Vector2 position = owner.getEntity().getCenterPosition(); | ||
hits.clear(); | ||
for (int i = 8; i > -8; i--) { | ||
if (physics.raycast(position, new Vector2(position.x + maxRange, position.y + i), TARGET1, hit) | ||
|| physics.raycast(position, new Vector2(position.x + maxRange, position.y + i), TARGET2, hit)) { | ||
hits.add(hit); | ||
targets.add(new Vector2(position.x + maxRange, position.y + i)); | ||
} | ||
} | ||
return !hits.isEmpty(); | ||
} | ||
|
||
/** | ||
* Fetches the nearest target from the array of detected target positions created during the last call of | ||
* isTargetVisible | ||
* @return a Vector2 position of the nearest mob detected. | ||
*/ | ||
public Vector2 fetchTarget() { | ||
// Initial nearest position for comparison | ||
int lowest = 10; | ||
|
||
Vector2 nearest = new Vector2(owner.getEntity().getCenterPosition().x, | ||
owner.getEntity().getCenterPosition().y); | ||
|
||
// Find the nearest target from the array of targets | ||
for (Vector2 tgt : targets){ | ||
if (Math.abs(tgt.y - nearest.y) < lowest) { | ||
lowest = (int)Math.abs(tgt.y - nearest.y); | ||
nearest = tgt; | ||
} | ||
} | ||
return nearest; | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipWaitTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
167 changes: 167 additions & 0 deletions
167
source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipWanderTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
package com.csse3200.game.components.tasks; | ||
|
||
import com.badlogic.gdx.math.Vector2; | ||
import com.csse3200.game.ai.tasks.DefaultTask; | ||
import com.csse3200.game.ai.tasks.PriorityTask; | ||
import com.csse3200.game.ai.tasks.Task; | ||
import com.csse3200.game.components.CombatStatsComponent; | ||
import com.csse3200.game.physics.PhysicsLayer; | ||
import com.csse3200.game.physics.components.ColliderComponent; | ||
import com.csse3200.game.physics.components.HitboxComponent; | ||
import com.csse3200.game.rendering.AnimationRenderComponent; | ||
import com.csse3200.game.services.ServiceLocator; | ||
|
||
/** | ||
* BombshipWanderTask is the entry point for the engineer entity's behaviour. Instantiates subtasks HumanWaitTask, | ||
* BombshipMovementTask and BombshipCombatTask, and manages transitions between the tasks. Bombship damage and destruction is | ||
* handled in this class. | ||
*/ | ||
public class BombshipWanderTask extends DefaultTask implements PriorityTask { | ||
private static final int TOLERANCE = 1; | ||
private static final float STOP_DISTANCE = 0.5f; | ||
private static final int DEFAULT_PRIORITY = 1; | ||
private static final String START = "start"; | ||
private static final String DESTROY = "destroy"; | ||
private static final String IDLE = "idle"; | ||
private AnimationRenderComponent animator; | ||
private final float maxRange; | ||
private final float waitTime; | ||
private BombshipMovementTask movementTask; | ||
private BombshipWaitTask waitTask; | ||
private BombshipCombatTask combatTask; | ||
private Task currentTask; | ||
private boolean isDestroyed = false; | ||
|
||
/** | ||
* Constructor of BombshipWanderTask | ||
* | ||
* @param waitTime How long in seconds to wait between wandering. | ||
* @param maxRange Maximum of the entity to fight | ||
*/ | ||
public BombshipWanderTask(float waitTime, float maxRange) { | ||
this.waitTime = waitTime; | ||
this.maxRange = maxRange; | ||
} | ||
|
||
/** | ||
* Fetches the priority of this task. | ||
* @return current priority of this task. Priority for this task is a set value and does not change. | ||
*/ | ||
@Override | ||
public int getPriority() { | ||
return DEFAULT_PRIORITY; // Low priority task | ||
} | ||
|
||
/** | ||
* Starts the BombshipWanderTask instance and instantiates subtasks (BombshipWaitTask, BombshipWanderTask, BombshipCombatTask). | ||
*/ | ||
@Override | ||
public void start() { | ||
super.start(); | ||
Vector2 startPos = owner.getEntity().getCenterPosition(); | ||
waitTask = new BombshipWaitTask(waitTime); | ||
waitTask.create(owner); | ||
|
||
movementTask = new BombshipMovementTask(startPos, STOP_DISTANCE); | ||
movementTask.create(owner); | ||
movementTask.start(); | ||
|
||
combatTask = new BombshipCombatTask(maxRange); | ||
combatTask.create(owner); | ||
combatTask.start(); | ||
|
||
currentTask = movementTask; | ||
|
||
animator = owner.getEntity().getComponent(AnimationRenderComponent.class); | ||
} | ||
|
||
/** | ||
* Operates the main logic of the entity in this task. All calls to switch to particular states are determined during | ||
* the update phase. | ||
* The logical flow is: | ||
* - Check if the entity has died since last update | ||
* - Check if the entity has finished dying | ||
* - If not dead | ||
*/ | ||
@Override | ||
public void update() { | ||
if (!isDestroyed) { | ||
startDestroying(); | ||
} | ||
|
||
// Check if bombship has destroyed since last update | ||
if (!isDestroyed) { | ||
startDestroying(); | ||
} else if (isDestroyed && animator.isFinished()) { | ||
owner.getEntity().setFlagForDelete(true); | ||
} | ||
|
||
// otherwise doing engineer things since engineer is alive | ||
else if (!isDestroyed){ | ||
doBombshipThings(); | ||
|
||
currentTask.update(); | ||
} | ||
} | ||
|
||
private void doBombshipThings() { | ||
if (currentTask.getStatus() != Status.ACTIVE) { | ||
|
||
// if the engineer is in move state and update has been called, engineer has arrived at destination | ||
if (currentTask == movementTask) { | ||
startWaiting(); | ||
owner.getEntity().getEvents().trigger(IDLE); | ||
|
||
} else if (combatTask.isEngineerDied()) { | ||
owner.getEntity().getEvents().trigger(START); | ||
} | ||
} | ||
} | ||
/** | ||
* Handle the dying phase of the entity. Triggers an event to play the appropriate media, | ||
* sets HitBox and Collider components to ignore contact (stops the body being pushed around) | ||
* and stops the current task. | ||
*/ | ||
private void startDestroying() { | ||
owner.getEntity().getEvents().trigger(DESTROY); | ||
owner.getEntity().getComponent(ColliderComponent.class).setLayer(PhysicsLayer.NONE); | ||
owner.getEntity().getComponent(HitboxComponent.class).setLayer(PhysicsLayer.NONE); | ||
currentTask.stop(); | ||
isDestroyed = true; | ||
} | ||
|
||
/** | ||
* Starts the wait task. | ||
*/ | ||
private void startWaiting() { | ||
swapTask(waitTask); | ||
} | ||
|
||
/** | ||
* Starts the movement task, to a particular destination | ||
* @param destination the Vector2 position to which the entity needs to move | ||
*/ | ||
private void startMoving(Vector2 destination) { | ||
movementTask.setTarget(destination); | ||
swapTask(movementTask); | ||
} | ||
|
||
/** | ||
* Starts the combat task. | ||
*/ | ||
private void startCombat() { | ||
swapTask(combatTask); | ||
} | ||
|
||
/** | ||
* Allows manual switching of tasks, from the current task to the supplied newTask. | ||
* @param newTask the task being switched to. | ||
*/ | ||
private void swapTask(Task newTask) { | ||
if (currentTask != null) { | ||
currentTask.stop(); | ||
} | ||
currentTask = newTask; | ||
currentTask.start(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
source/core/src/main/com/csse3200/game/entities/configs/BombshipConfigs.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.csse3200.game.entities.configs; | ||
|
||
/** | ||
* Defines the properties stored in Bombship config files to be loaded by the Bombship Factory. | ||
*/ | ||
public class BombshipConfigs extends BaseEntityConfig { | ||
public BaseEntityConfig bombship = new BaseEntityConfig(); | ||
public int health = 100; | ||
public int baseAttack = 20; | ||
} |
Oops, something went wrong.