Skip to content

Commit

Permalink
Merge branch 'Team-1-Mobs-Enhancement-variations' of github.com:UQcss…
Browse files Browse the repository at this point in the history
…e3200/2023-studio-3 into Team-1-Mobs-Enhancement-variations
  • Loading branch information
cindyle1 committed Oct 14, 2023
2 parents 40f8661 + 67ecbce commit 300e240
Show file tree
Hide file tree
Showing 28 changed files with 530 additions and 339 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
Expand All @@ -15,6 +16,7 @@
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.csse3200.game.services.GameTime;
import com.csse3200.game.services.ServiceLocator;
import com.csse3200.game.ui.UIComponent;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
Expand Down Expand Up @@ -89,6 +91,15 @@ public void updateScrapsStats() {
scrapsTb.getLabel().setText(text);
}

/**
* Displays a warning animation of the scraps display if the player tries to
* build something that costs more than the balance
*/
public void scrapBalanceFlash() {
// TODO: IMPLEMENT THIS
scrapsTb.setText("Insufficient!");
}

/**
* Updates the currency (Crystals) value on the UI component
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public MainGameActions(GdxGame game) {
public void create() {
entity.getEvents().addListener("exit", this::onExit);
entity.getEvents().addListener("lose", this::onLose);
//entity.getEvents().addListener("win", this::onWin);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,19 @@

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Array;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.factories.TowerFactory;
import com.csse3200.game.screens.TowerType;
import com.csse3200.game.services.ServiceLocator;
import com.csse3200.game.ui.ButtonFactory;
import com.csse3200.game.ui.UIComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.Set;

/**
* Displays a button to represent the remaining mobs left in the current wave and a button to skip to the next wave.
Expand All @@ -40,8 +31,6 @@ public class UIElementsDisplay extends UIComponent {
};
private Sound click;
private Sound hover;
// private TextButton remainingMobsButton = new ButtonFactory().createButton("Mobs left:");
// private final TextButton timerButton = new ButtonFactory().createButton("Next wave:");
private TextButton remainingMobsButton;
private TextButton timerButton;
private final int timer = 110;
Expand All @@ -62,14 +51,11 @@ private void addActors() {
remainingMobsButton = new TextButton("Mobs:"
+ ServiceLocator.getWaveService().getEnemyCount(), skin);
buttonTable.top().right();
towerTable.top();
towerTable.top().padTop(80f);

buttonTable.setFillParent(true);
towerTable.setFillParent(true);

towerTable.setDebug(true);
towerTable.padTop(50f);

TowerType[] defaultTowers = {
TowerType.TNT,
TowerType.DROID,
Expand Down Expand Up @@ -98,6 +84,10 @@ private void addActors() {
}
}

// Update the centrally located towerTypes list -
ServiceLocator.setTowerTypes(towers);

// Create the buttons - TODO This needs overhauling to pretty buttons
TextButton tower1 = new TextButton(towers.get(0).getTowerName(), skin);
TextButton tower2 = new TextButton(towers.get(1).getTowerName(), skin);
TextButton tower3 = new TextButton(towers.get(2).getTowerName(), skin);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.csse3200.game.components.npc;

import com.csse3200.game.components.Component;
import com.csse3200.game.components.tasks.MobTask.MobType;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.factories.NPCFactory;
import com.csse3200.game.services.ServiceLocator;
Expand All @@ -17,6 +18,8 @@
*/
public class SplitMoblings extends Component {
private int amount;
private MobType mobType;
private int baseMoblingHealth = 60;
private float scaleX, scaleY;
public static final float DEFAULT_MINIFIED_SCALE = 0.75f;
public static final double OFFSET_DISTANCE = 1.5;
Expand All @@ -31,10 +34,12 @@ public class SplitMoblings extends Component {
* Initialises a component that splits mob into multiple moblings. Amount of
* moblings split based on the amount provided param.
*
* @param amount Amount of moblings to be split.
* @param mobType Type of moblings split on death based on the MobType enum.
* @param amount Amount of moblings to be split.
* @require amount > 0
*/
public SplitMoblings(int amount) {
public SplitMoblings(MobType mobType, int amount) {
this.mobType = mobType;
this.amount = amount;
scaleX = scaleY = DEFAULT_MINIFIED_SCALE;
}
Expand All @@ -44,12 +49,15 @@ public SplitMoblings(int amount) {
* moblings split is based on the amount provided param.
* The overalling scaling (x and y) is also altered in the param.
*
* @param amount Amount of moblings to be split.
* @param scale X and Y scaling of the moblings in respect to the original size
* of the mobs.
* @param mobType Type of moblings split on death based on the MobType enum.
* @param amount Amount of moblings to be split.
* @param scale X and Y scaling of the moblings in respect to the original
* size
* of the mobs.
* @require amount > 0
*/
public SplitMoblings(int amount, float scale) {
public SplitMoblings(MobType mobType, int amount, float scale) {
this.mobType = mobType;
this.amount = amount;
this.scaleX = this.scaleY = scale;
}
Expand All @@ -59,12 +67,14 @@ public SplitMoblings(int amount, float scale) {
* moblings split is based on the amount provided param.
* The individual scaling (x and y) is also altered in the param.
*
* @param amount Amount of moblings to be split.
* @param scaleX X scaling of the moblings compared to original size.
* @param scaleY Y scaling of the moblings compared to original size.
* @param mobType Type of moblings split on death based on the MobType enum.
* @param amount Amount of moblings to be split.
* @param scaleX X scaling of the moblings compared to original size.
* @param scaleY Y scaling of the moblings compared to original size.
* @require amount > 0
*/
public SplitMoblings(int amount, float scaleX, float scaleY) {
public SplitMoblings(MobType mobType, int amount, float scaleX, float scaleY) {
this.mobType = mobType;
this.amount = amount;
this.scaleX = scaleX;
this.scaleY = scaleY;
Expand Down Expand Up @@ -120,15 +130,26 @@ private void onDeath() {
*/
public void spawnAdditionalMob(float positionX, float positionY,
float initialScaleX, float initialScaleY) {
// MAKE A SWITCH CASE STATEMENT HERE, ASK JASON HOW TO
// Entity waterSlime = NPCFactory.createBaseWaterSlime(60);
Entity waterSlime = NPCFactory.createNightBorne(60);
waterSlime.setPosition(positionX, positionY);
Entity entityType;
switch (mobType) {
case WATER_SLIME -> {
entityType = NPCFactory.createBaseWaterSlime(baseMoblingHealth);
}

case NIGHT_BORNE -> {
entityType = NPCFactory.createNightBorne(baseMoblingHealth);
}

default -> {
entityType = NPCFactory.createBaseWaterSlime(baseMoblingHealth);
}
}
entityType.setPosition(positionX, positionY);

waterSlime.setScale(initialScaleX * scaleX, initialScaleY * scaleY);
// waterSlime.setScale(initialScaleX, initialScaleY);
entityType.setScale(initialScaleX * scaleX, initialScaleY * scaleY);

ServiceLocator.getEntityService().register(waterSlime);
ServiceLocator.getEntityService().register(entityType);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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);
}

Expand All @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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()) {
Expand Down
Loading

0 comments on commit 300e240

Please sign in to comment.