diff --git a/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java b/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java index 1793115c6..8f2ea18cd 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java @@ -3,7 +3,9 @@ import com.badlogic.gdx.math.Vector2; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; +import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.currency.Scrap; +import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; @@ -22,6 +24,13 @@ public class CurrencyTask extends DefaultTask implements PriorityTask { private final int currencyAmount = scrap.getAmount(); // amount of currency to update private static final String IDLE = "idleStartEco"; private static final String MOVE = "moveStartEco"; + private static final String DEATH = "deathStartEco"; + + public enum STATE { + IDLE, DEATH + } + public STATE towerState = STATE.IDLE; + /** * @param priority Task priority for currency updates. Must be a positive integer. @@ -40,7 +49,8 @@ public CurrencyTask(int priority, int interval) { public void start() { super.start(); owner.getEntity().getEvents().addListener("addIncome",this::changeInterval); - endTime = timeSource.getTime() + (30 * 1000L); + // TODO: changed 30 TIMES MULTIPLIER to 5 times + endTime = timeSource.getTime() + (interval * 1500L); owner.getEntity().getEvents().trigger(IDLE); } @@ -52,14 +62,38 @@ public void start() { @Override public void update() { if (timeSource.getTime() >= endTime) { - owner.getEntity().getEvents().trigger(MOVE); - updateCurrency(); // update currency + updateTowerState(); logger.info(String.format("Interval: %d", interval)); endTime = timeSource.getTime() + (interval * 1000L); // reset end time } } + /** + * This method acts is the state machine for IncomeTower. Relevant animations are triggered based on relevant state + * of the game. If the tower runs out of health it dies. + */ + public void updateTowerState() { + if (owner.getEntity().getComponent(CombatStatsComponent.class).getHealth() <= 0 && towerState != STATE.DEATH) { + owner.getEntity().getEvents().trigger(DEATH); + towerState = STATE.DEATH; + } + + switch (towerState) { + case IDLE -> { + owner.getEntity().getEvents().trigger(MOVE); + updateCurrency(); // update currency + towerState = STATE.IDLE; + } + case DEATH -> { + if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { + owner.getEntity().setFlagForDelete(true); + } + } + } + } + + /** * Updates the currency based on time intervals. */ diff --git a/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java index 384549af7..1c597fc2e 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java @@ -74,7 +74,7 @@ public void start() { // Default to idle mode owner.getEntity().getEvents().trigger(WALK); owner.getEntity().getEvents().addListener("addFireRate",this::changeFireRateInterval); - endTime = timeSource.getTime() + (INTERVAL * 500); + endTime = timeSource.getTime() + (INTERVAL * 1000); } /** diff --git a/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java index abf01bb79..13aa11a18 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java @@ -42,6 +42,7 @@ public class FireTowerCombatTask extends DefaultTask implements PriorityTask { private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); + private boolean shoot = true; public enum STATE { IDLE, PREP_ATTACK, ATTACK, DEATH @@ -115,17 +116,21 @@ public void updateTowerState() { } } case ATTACK -> { - if (!isTargetVisible()) { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } else { - owner.getEntity().getEvents().trigger(ATTACK); - Entity newProjectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, - new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), ProjectileEffects.BURN, false); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y + 0.25)); - ServiceLocator.getEntityService().register(newProjectile); + if (shoot) { + if (!isTargetVisible()) { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } else { + owner.getEntity().getEvents().trigger(ATTACK); + Entity newProjectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, + new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), ProjectileEffects.BURN, false); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), + (float) (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + } } + shoot = !shoot; + } case DEATH -> { if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java index ef7c74f89..8d10036ae 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java @@ -40,6 +40,7 @@ public class FireworksTowerCombatTask extends DefaultTask implements PriorityTas private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); + private boolean shoot = true; public enum STATE { IDLE, ATTACK, DEATH @@ -69,7 +70,7 @@ public void start() { // Set the default state to IDLE state owner.getEntity().getEvents().trigger(IDLE); - endTime = timeSource.getTime() + (INTERVAL * 5000); + endTime = timeSource.getTime() + (INTERVAL * 1000); } /** @@ -103,17 +104,21 @@ public void updateTowerState() { } } case ATTACK -> { - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(ATTACK); - Entity newProjectile = ProjectileFactory.createSplitFireWorksFireball(PhysicsLayer.NPC, - new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), 3); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y + 0.25)); - ServiceLocator.getEntityService().register(newProjectile); - } else { - owner.getEntity().getEvents().trigger(IDLE); - towerState=STATE.IDLE; + // check if fired last time if not fire if so hold + if (shoot) { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(ATTACK); + Entity newProjectile = ProjectileFactory.createSplitFireWorksFireball(PhysicsLayer.NPC, + new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), 3); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), + (float) (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + } else { + owner.getEntity().getEvents().trigger(IDLE); + towerState=STATE.IDLE; + } } + shoot = !shoot; } case DEATH -> { if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java index 8d8723f65..b6c6f7619 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java @@ -39,6 +39,7 @@ public class PierceTowerCombatTask extends DefaultTask implements PriorityTask { private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); + private boolean shoot = true; public enum STATE { IDLE, ATTACK, DEATH @@ -103,18 +104,22 @@ public void updateTowerState() { } } case ATTACK -> { - if (!isTargetVisible()) { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } else { - owner.getEntity().getEvents().trigger(ALERT); - owner.getEntity().getEvents().trigger(ATTACK); - Entity newProjectile = ProjectileFactory.createPierceFireBall(PhysicsLayer.NPC, - new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y + 0.25)); - ServiceLocator.getEntityService().register(newProjectile); + if (shoot) { + if (!isTargetVisible()) { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } else { + owner.getEntity().getEvents().trigger(ALERT); + owner.getEntity().getEvents().trigger(ATTACK); + Entity newProjectile = ProjectileFactory.createPierceFireBall(PhysicsLayer.NPC, + new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), + (float) (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + } } + + shoot = !shoot; } case DEATH -> { if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java index d057c1ab0..63c662417 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java @@ -40,6 +40,7 @@ public class RicochetTowerCombatTask extends DefaultTask implements PriorityTask private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); + private boolean shoot = true; //enums for the state triggers public enum STATE { @@ -104,18 +105,21 @@ public void updateTowerState() { } } case ATTACK -> { - if (!isTargetVisible()) { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } else { - owner.getEntity().getEvents().trigger(ATTACK); - Entity newProjectile = ProjectileFactory.createRicochetFireball(PhysicsLayer.NPC, - // NEED TO DO USER TESTING TO FIGURE OUT THE BOUNCE COUNT - new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), 3); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y + 0.25)); - ServiceLocator.getEntityService().register(newProjectile); + if (shoot) { + if (!isTargetVisible()) { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } else { + owner.getEntity().getEvents().trigger(ATTACK); + Entity newProjectile = ProjectileFactory.createRicochetFireball(PhysicsLayer.NPC, + // NEED TO DO USER TESTING TO FIGURE OUT THE BOUNCE COUNT + new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), 3); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), + (float) (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + } } + shoot = !shoot; } case DEATH -> { if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java index cce8ec833..ec469b269 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java @@ -40,6 +40,7 @@ public class StunTowerCombatTask extends DefaultTask implements PriorityTask { private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); + private boolean shoot = true; //enums for the state triggers public enum STATE { @@ -111,20 +112,25 @@ public void updateTowerState() { } } case ATTACK -> { - if (!isTargetVisible()) { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } else { - owner.getEntity().getEvents().trigger(ATTACK); + if (shoot) { + if (!isTargetVisible()) { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } else { + owner.getEntity().getEvents().trigger(ATTACK); // Entity newProjectile = ProjectileFactory.createFireBall(PhysicsLayer.NPC, // new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); - Entity newProjectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, - new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), - ProjectileEffects.STUN, false); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y + 0.25)); - ServiceLocator.getEntityService().register(newProjectile); + Entity newProjectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, + new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), + ProjectileEffects.STUN, false); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), + (float) (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } } + shoot = !shoot; } case DIE -> { if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java index f1d0eb9ca..c9f5c2b33 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java @@ -4,11 +4,13 @@ import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; import com.csse3200.game.areas.ForestGameArea; +import com.csse3200.game.components.CombatStatsComponent; 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.rendering.AnimationRenderComponent; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; @@ -30,6 +32,7 @@ public class TowerCombatTask extends DefaultTask implements PriorityTask { private static final String DEPLOY = "deployStart"; private static final String FIRING = "firingStart"; private static final String IDLE = "idleStart"; + private static final String DEATH = "deathStart"; // class attributes private final int priority; // The active priority this task will have @@ -42,9 +45,10 @@ public class TowerCombatTask extends DefaultTask implements PriorityTask { private long endTime; private final RaycastHit hit = new RaycastHit(); private static final Logger logger = LoggerFactory.getLogger(ForestGameArea.class); + private boolean shoot = true; private enum STATE { - IDLE, DEPLOY, FIRING, STOW + IDLE, DEPLOY, FIRING, STOW, DEATH } private STATE towerState = STATE.IDLE; @@ -114,6 +118,11 @@ public void update() { */ public void updateTowerState() { // configure tower state depending on target visibility + if (owner.getEntity().getComponent(CombatStatsComponent.class).getHealth() <= 0 && towerState != STATE.DEATH) { + owner.getEntity().getEvents().trigger(DEATH); + towerState = STATE.DEATH; + return; + } switch (towerState) { case IDLE -> { // targets detected in idle mode - start deployment @@ -133,38 +142,41 @@ public void updateTowerState() { } } case FIRING -> { - // targets gone - stop firing - if (!isTargetVisible()) { + if (shoot) { + // targets gone - stop firing + if (!isTargetVisible()) { - owner.getEntity().getEvents().trigger(STOW); - towerState = STATE.STOW; - } else { - owner.getEntity().getEvents().trigger(FIRING); - // this might be changed to an event which gets triggered everytime the tower enters the firing state - - Entity newProjectile = ProjectileFactory.createFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - newProjectile.setScale(1.1f, 0.8f); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.5), (float) (owner.getEntity().getPosition().y + 0.5)); - ServiceLocator.getEntityService().register(newProjectile); - - // * TEMPRORARYYYYYYYY PLS DON'T DELETE THIS - // PIERCE FIREBALL - // Entity pierceFireball = ProjectileFactory.createPierceFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - // pierceFireball.setPosition((float) (owner.getEntity().getPosition().x + 0), (float) (owner.getEntity().getPosition().y + 0.4)); - // ServiceLocator.getEntityService().register(pierceFireball); - - // RICOCHET FIREBALL - // Entity ricochetProjectile = ProjectileFactory.createRicochetFireball(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f), 0); - - // ricochetProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0), (float) (owner.getEntity().getPosition().y + 0.4)); - // ServiceLocator.getEntityService().register(ricochetProjectile); - - // SPLIT FIREWORKS FIREBALLL - // Entity splitFireWorksProjectile = ProjectileFactory.createSplitFireWorksFireball(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f), 16); - - // splitFireWorksProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.75), (float) (owner.getEntity().getPosition().y + 0.4)); - // ServiceLocator.getEntityService().register(splitFireWorksProjectile); + owner.getEntity().getEvents().trigger(STOW); + towerState = STATE.STOW; + } else { + owner.getEntity().getEvents().trigger(FIRING); + // this might be changed to an event which gets triggered everytime the tower enters the firing state + + Entity newProjectile = ProjectileFactory.createFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); + newProjectile.setScale(1.1f, 0.8f); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.5), (float) (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + + // * TEMPRORARYYYYYYYY PLS DON'T DELETE THIS + // PIERCE FIREBALL + // Entity pierceFireball = ProjectileFactory.createPierceFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f)); + // pierceFireball.setPosition((float) (owner.getEntity().getPosition().x + 0), (float) (owner.getEntity().getPosition().y + 0.4)); + // ServiceLocator.getEntityService().register(pierceFireball); + + // RICOCHET FIREBALL + // Entity ricochetProjectile = ProjectileFactory.createRicochetFireball(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f), 0); + + // ricochetProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0), (float) (owner.getEntity().getPosition().y + 0.4)); + // ServiceLocator.getEntityService().register(ricochetProjectile); + + // SPLIT FIREWORKS FIREBALLL + // Entity splitFireWorksProjectile = ProjectileFactory.createSplitFireWorksFireball(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f), 16); + + // splitFireWorksProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.75), (float) (owner.getEntity().getPosition().y + 0.4)); + // ServiceLocator.getEntityService().register(splitFireWorksProjectile); + } } + shoot = !shoot; } case STOW -> { // currently stowing @@ -177,6 +189,11 @@ public void updateTowerState() { towerState = STATE.IDLE; } } + case DEATH -> { + if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { + owner.getEntity().setFlagForDelete(true); + } + } } } /** diff --git a/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java b/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java index 988ff0071..749647851 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java @@ -41,7 +41,7 @@ public class WallTowerDestructionTask extends DefaultTask implements PriorityTas private final RaycastHit hit = new RaycastHit(); public enum STATE { - IDLE, ATTACK, DEATH + IDLE, DEATH } public STATE towerState = STATE.IDLE; @@ -68,7 +68,7 @@ public void start() { // Set the default state to IDLE state owner.getEntity().getEvents().trigger(IDLE); - endTime = timeSource.getTime() + (INTERVAL * 5000); + endTime = timeSource.getTime() + (INTERVAL * 1000); } /** @@ -97,7 +97,7 @@ public void updateTowerState() { switch (towerState) { case IDLE -> { owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.ATTACK; + towerState = STATE.IDLE; } case DEATH -> { if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { diff --git a/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java index d8307e0e4..19406ff99 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java @@ -114,9 +114,8 @@ void shootDown() { entity.getPosition().y), new Vector2(2,2), ProjectileEffects.SLOW, false); Projectile.setScale(new Vector2(0.5f,0.5f)); Projectile.setPosition((float) (entity.getPosition().x + 0.2), - (float) (entity.getPosition().y - 0.2)); + (float) (entity.getPosition().y)); ServiceLocator.getEntityService().register(Projectile); - } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java index 9e79376e2..bdcf77c06 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java @@ -9,6 +9,6 @@ public class IncomeTowerConfig { public int cost = 1; public float attackRate = 0; - public float incomeRate = 30; + public float incomeRate = 10; } diff --git a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java index a92dbb234..81ff0012f 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java @@ -1,5 +1,6 @@ package com.csse3200.game.entities.factories; +import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.physics.box2d.Filter; import com.csse3200.game.components.tasks.DroidCombatTask; import com.csse3200.game.components.tasks.TNTTowerCombatTask; @@ -25,6 +26,7 @@ import com.csse3200.game.input.UpgradeUIComponent;import java.util.HashSet; import java.util.Set; + /** * Factory to create a tower entity. * @@ -34,7 +36,6 @@ public class TowerFactory { // Define a set to keep track of occupied lanes private static final Set occupiedLanes = new HashSet<>(); - private static final int COMBAT_TASK_PRIORITY = 2; private static final int WEAPON_TOWER_MAX_RANGE = 40; private static final int TNT_TOWER_MAX_RANGE = 6; @@ -180,6 +181,10 @@ public static Entity createWallTower() { */ public static Entity createTNTTower() { Entity TNTTower = createBaseTower(); + TNTTower.getComponent(HitboxComponent.class) + .setLayer(PhysicsLayer.NONE) + .setSensor(true); + TNTTower.getComponent(ColliderComponent.class).setSensor(true); TNTTowerConfigs config = configs.TNTTower; AITaskComponent aiTaskComponent = new AITaskComponent() @@ -269,7 +274,7 @@ public static Entity createWeaponTower() { animator.addAnimation(IDLE_ANIM, IDLE_SPEED, Animation.PlayMode.LOOP); animator.addAnimation(STOW_ANIM, STOW_SPEED, Animation.PlayMode.NORMAL); animator.addAnimation(DEPLOY_ANIM, DEPLOY_SPEED, Animation.PlayMode.REVERSED); - animator.addAnimation(FIRE_ANIM, FIRE_SPEED, Animation.PlayMode.LOOP); + animator.addAnimation(FIRE_ANIM, (2*FIRE_SPEED), Animation.PlayMode.LOOP); weapon .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) @@ -302,7 +307,7 @@ public static Entity createFireTower() { .getAsset(FIRE_TOWER_ATLAS, TextureAtlas.class)); animator.addAnimation(FIRE_TOWER_IDLE_ANIM, FIRE_TOWER_IDLE_SPEED, Animation.PlayMode.LOOP); animator.addAnimation(FIRE_TOWER_PREP_ATTACK_ANIM, FIRE_TOWER_PREP_ATTACK_SPEED, Animation.PlayMode.NORMAL); - animator.addAnimation(FIRE_TOWER_ATTACK_ANIM, FIRE_TOWER_ATTACK_SPEED+ 0.25f, Animation.PlayMode.LOOP); + animator.addAnimation(FIRE_TOWER_ATTACK_ANIM, (2*(FIRE_TOWER_ATTACK_SPEED+ 0.25f)), Animation.PlayMode.LOOP); animator.addAnimation(FIRE_TOWER_DEATH_ANIM, FIRE_TOWER_DEATH_SPEED, Animation.PlayMode.NORMAL); fireTower @@ -332,7 +337,7 @@ public static Entity createStunTower() { ServiceLocator.getResourceService() .getAsset(STUN_TOWER_ATLAS, TextureAtlas.class)); animator.addAnimation(STUN_TOWER_IDLE_ANIM, STUN_TOWER_IDLE_SPEED, Animation.PlayMode.LOOP); - animator.addAnimation(STUN_TOWER_ATTACK_ANIM, STUN_TOWER_ATTACK_SPEED+ 0.25f, Animation.PlayMode.LOOP); + animator.addAnimation(STUN_TOWER_ATTACK_ANIM, ((STUN_TOWER_ATTACK_SPEED+ 0.20f)), Animation.PlayMode.LOOP); animator.addAnimation(STUN_TOWER_DEATH_ANIM, STUN_TOWER_DEATH_SPEED, Animation.PlayMode.NORMAL); stunTower @@ -344,7 +349,6 @@ public static Entity createStunTower() { .addComponent(new StunTowerAnimationController()); stunTower.setScale(1.5f, 1.5f); - PhysicsUtils.setScaledCollider(stunTower, 0.5f, 0.5f); return stunTower; } @@ -364,7 +368,7 @@ public static Entity createFireworksTower() { new AnimationRenderComponent( ServiceLocator.getResourceService() .getAsset(FIREWORKS_TOWER_ATLAS, TextureAtlas.class)); - animator.addAnimation(FIREWORKS_TOWER_ATTACK_ANIM, FIREWORKS_TOWER_ANIM_ATTACK_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation(FIREWORKS_TOWER_ATTACK_ANIM, (2*FIREWORKS_TOWER_ANIM_ATTACK_SPEED), Animation.PlayMode.NORMAL); animator.addAnimation(FIREWORKS_TOWER_IDLE_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.LOOP); animator.addAnimation(FIREWORKS_TOWER_DEATH_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.NORMAL); @@ -375,8 +379,6 @@ public static Entity createFireworksTower() { .addComponent(animator) .addComponent(new FireworksTowerAnimationController()); - fireworksTower.setScale(1.5f, 1.5f); - PhysicsUtils.setScaledCollider(fireworksTower, 0.2f, 0.2f); return fireworksTower; } @@ -395,7 +397,7 @@ public static Entity createPierceTower() { new AnimationRenderComponent( ServiceLocator.getResourceService() .getAsset(PIERCE_TOWER_ATLAS, TextureAtlas.class)); - animator.addAnimation(PIERCE_TOWER_ATTACK_ANIM, PIERCE_TOWER_ANIM_ATTACK_SPEED, Animation.PlayMode.LOOP); + animator.addAnimation(PIERCE_TOWER_ATTACK_ANIM, (2*PIERCE_TOWER_ANIM_ATTACK_SPEED), Animation.PlayMode.LOOP); animator.addAnimation(PIERCE_TOWER_IDLE_ANIM, PIERCE_TOWER_ANIM_ATTACK_SPEED, Animation.PlayMode.LOOP); animator.addAnimation(PIERCE_TOWER_DEATH_ANIM, PIERCE_TOWER_ANIM_ATTACK_SPEED, Animation.PlayMode.NORMAL); animator.addAnimation(PIERCE_TOWER_ALERT_ANIM, PIERCE_TOWER_ANIM_ATTACK_SPEED, Animation.PlayMode.NORMAL); @@ -409,7 +411,6 @@ public static Entity createPierceTower() { .addComponent(aiTaskComponent); pierceTower.setScale(1.5f, 1.5f); - PhysicsUtils.setScaledCollider(pierceTower, 0.5f, 0.5f); return pierceTower; } @@ -426,7 +427,7 @@ public static Entity createRicochetTower() { AnimationRenderComponent animator = new AnimationRenderComponent( ServiceLocator.getResourceService().getAsset(RICOCHET_TOWER_ATLAS,TextureAtlas.class)); - animator.addAnimation(RICOCHET_TOWER_ATTACK_ANIM,RICOCHET_TOWER_ANIM_ATTACK_SPEED,Animation.PlayMode.LOOP); + animator.addAnimation(RICOCHET_TOWER_ATTACK_ANIM,(2*RICOCHET_TOWER_ANIM_ATTACK_SPEED),Animation.PlayMode.LOOP); animator.addAnimation(RICOCHET_TOWER_DEATH_ANIM,RICOCHET_TOWER_ANIM_ATTACK_SPEED,Animation.PlayMode.NORMAL); animator.addAnimation(RICOCHET_TOWER_IDLE_ANIM,RICOCHET_TOWER_ANIM_ATTACK_SPEED,Animation.PlayMode.LOOP); ricochetTower @@ -438,26 +439,6 @@ public static Entity createRicochetTower() { // ADD ANIMATION COMPONENTS ricochetTower.setScale(1.5f, 1.5f); - PhysicsUtils.setScaledCollider(ricochetTower, 0.5f, 0.5f); - return ricochetTower; - } - public static Entity createHealTower() { - Entity ricochetTower = createBaseTower(); - HealTowerConfig config = configs.HealTower; - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new RicochetTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); - - // ADD AnimationRenderComponent - - ricochetTower - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent((new CostComponent(config.cost))) - .addComponent(aiTaskComponent); - // ADD ANIMATION COMPONENTS - - ricochetTower.setScale(1.5f, 1.5f); - PhysicsUtils.setScaledCollider(ricochetTower, 0.5f, 0.5f); return ricochetTower; } @@ -467,6 +448,8 @@ public static Entity createHealTower() { */ public static Entity createBaseTower() { // we're going to add more components later on + + Entity tower = new Entity() .addComponent(new ColliderComponent()) .addComponent(new HitboxComponent().setLayer(PhysicsLayer.TOWER)) // TODO: we might have to change the names of the layers @@ -475,6 +458,9 @@ public static Entity createBaseTower() { tower.setLayer(1); // Set priority to 1, which is 1 below scrap (which is 0) + // Set hitbox and collider to a vector of size 1 and align the hitbox and collider to the center of the tower + tower.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(1f, 1f), PhysicsComponent.AlignX.CENTER, PhysicsComponent.AlignY.CENTER); + tower.getComponent(ColliderComponent.class).setAsBoxAligned(new Vector2(1f, 1f), PhysicsComponent.AlignX.CENTER, PhysicsComponent.AlignY.CENTER); return tower; } public static Entity createAndPlaceTower(int lane) {