Skip to content

Commit

Permalink
Merge branch 'Team-1--Projectiles' of https://github.com/UQcsse3200/2…
Browse files Browse the repository at this point in the history
…023-studio-3 into Team-1--Projectiles
  • Loading branch information
MiniSoda17 committed Sep 7, 2023
2 parents e540536 + 33fc4e3 commit 63709fe
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public void create() {
playMusic();

// Types of projectile
spawnEffectProjectile(new Vector2(0, 10), PhysicsLayer.PLAYER, towardsMobs, new Vector2(2f, 2f), ProjectileEffects.FIREBALL, true);
spawnEffectProjectile(new Vector2(0, 10), PhysicsLayer.PLAYER, towardsMobs, new Vector2(2f, 2f), ProjectileEffects.BURN, true);
spawnMobBall(new Vector2(15, 10), PhysicsLayer.PLAYER, towardsTowers, new Vector2(2f, 2f));
// spawnProjectile(new Vector2(0, 10), player, towardsMobs, new Vector2(2f, 2f));
// spawnMultiProjectile(new Vector2(0, 10), player, towardsMobs, 20, new Vector2(2f, 2f), 7);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@
import com.badlogic.gdx.physics.box2d.Fixture;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.factories.ProjectileFactory;
import com.csse3200.game.physics.BodyUserData;
import com.csse3200.game.physics.PhysicsLayer;
import com.csse3200.game.physics.components.HitboxComponent;
import com.csse3200.game.services.ServiceLocator;

import com.badlogic.gdx.utils.Timer;

import com.badlogic.gdx.utils.Array;

import java.util.ArrayList;

public class EffectsComponent extends Component {
private final float radius;
private final ProjectileEffects effect;
private final boolean aoe;
private HitboxComponent hitboxComponent;
private final short targetLayer;
private ArrayList<CombatStatsComponent> burnEntities = new ArrayList<>();

/**
* Constructor for the AoEComponent.
Expand All @@ -30,8 +36,8 @@ public EffectsComponent(short targetLayer, float radius, ProjectileEffects effec

@Override
public void create() {
entity.getEvents().addListener("projectileCollisionStart", this::onCollisionStart);
entity.getEvents().addListener("projectileCollisionEnd", this::onCollisionEnd);
entity.getEvents().addListener("collisionStart", this::onCollisionStart);
entity.getEvents().addListener("collisionEnd", this::onCollisionEnd);
hitboxComponent = entity.getComponent(HitboxComponent.class);
}

Expand All @@ -50,19 +56,57 @@ private void onCollisionEnd(Fixture me, Fixture other) {
return;
}

// Get the other entity involved in the collision
Entity otherEntity = ((BodyUserData) other.getBody().getUserData()).entity;
CombatStatsComponent otherCombatStats = otherEntity.getComponent(CombatStatsComponent.class);
if (otherCombatStats == null) {
// The other entity does not have a CombatStatsComponent
return;
}

switch (effect) {
case FIREBALL -> {
if (aoe) {
applyAoeEffect(ProjectileEffects.FIREBALL);
}
}
case BURN -> {}
case BURN -> {
if (aoe) {
applyAoeEffect(ProjectileEffects.BURN);
} else {
applySingleEffect(ProjectileEffects.BURN, otherCombatStats);
}
}
case SLOW -> {}
case STUN -> {}
}
}

/**
* Used for singe targeting projectiles to apply effects entity it collides with.
* @param effect effect to be applied to entity
*/
public void applySingleEffect(ProjectileEffects effect, CombatStatsComponent targetCombatStats) {
Entity hostEntity = getEntity();
CombatStatsComponent hostCombatStats = hostEntity.getComponent(CombatStatsComponent.class);

if (hostCombatStats == null) {
// The host entity does not have a CombatStatsComponent to deal damage
return;
}

switch (effect) {
case FIREBALL -> {}
case BURN -> {
burnEffect(targetCombatStats, hostCombatStats);
}
case SLOW -> {}
case STUN -> {}
}
}
/**
* Used for aoe fireball projectile to apply damage to all entities within the area of effect (radius).
* Used for aoe projectiles to apply effects to all entities within the area of effect (radius).
* @param effect effect to be applied to entities within radius
*/
public void applyAoeEffect(ProjectileEffects effect) {
Entity hostEntity = getEntity();
Expand All @@ -75,11 +119,51 @@ public void applyAoeEffect(ProjectileEffects effect) {

Array<Entity> nearbyEntities = ServiceLocator.getEntityService().getNearbyEntities(hostEntity, radius);

for (Entity targetEntity : nearbyEntities) {
for (int i = 0; i < nearbyEntities.size; i++) {
Entity targetEntity = nearbyEntities.get(i);
CombatStatsComponent targetCombatStats = targetEntity.getComponent(CombatStatsComponent.class);
if (targetCombatStats != null) {
targetCombatStats.hit(hostCombatStats);
switch (effect) {
case FIREBALL -> {
fireballEffect(targetCombatStats, hostCombatStats);
}
case BURN -> {
burnEffect(targetCombatStats, hostCombatStats);
}
case SLOW -> {}
case STUN -> {}
}
}
}
}

private void fireballEffect(CombatStatsComponent target, CombatStatsComponent host) {
target.hit(host);
}

private void burnEffect(CombatStatsComponent target, CombatStatsComponent host) {
// Ensure burn effects aren't applied multiple times by same projectile
if (burnEntities.contains(target)) {
return;
}
burnEntities.add(target);

// Create a timer task to apply the effect repeatedly
int numberOfTicks = 5;
long delay = 1;
Timer.schedule(new Timer.Task() {
private int count = 0;

@Override
public void run() {
if (count < numberOfTicks) {
target.hit(host);
count++;
} else {
// Ensure to cancel the task when it's done
this.cancel();
}
}
}, delay, delay);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import com.csse3200.game.entities.Entity;
import com.csse3200.game.extensions.GameExtension;
import com.csse3200.game.physics.PhysicsService;
import com.csse3200.game.physics.components.ColliderComponent;
import com.csse3200.game.physics.components.HitboxComponent;
import com.csse3200.game.physics.components.PhysicsComponent;
import com.csse3200.game.physics.components.PhysicsMovementComponent;
Expand All @@ -39,6 +38,7 @@
class ProjectileFactoryTest {
private Entity projectile;

@Disabled
@BeforeEach
public void setUp() {
GameTime gameTime = mock(GameTime.class);
Expand All @@ -60,23 +60,27 @@ public void setUp() {
projectile = ProjectileFactory.createBaseProjectile(destination);
}

@Disabled
@Test
public void testBaseProjectileNotNull() {
assertNotNull(projectile, "Base projectile is null");
}

@Disabled
@Test
public void testBaseProjectileHitbox() {
assertNotNull(projectile.getComponent(HitboxComponent.class),
"Projectile does not contain Hotbox component");
}

@Disabled
@Test
public void testBaseProjectilePhysics() {
assertNotNull(projectile.getComponent(PhysicsComponent.class),
"Projectile does not have Physics component");
}

@Disabled
@Test
public void testBaseProjectilePhysicsMovement() {
assertNotNull(projectile.getComponent(PhysicsMovementComponent.class),
Expand Down

0 comments on commit 63709fe

Please sign in to comment.