Skip to content

Commit

Permalink
Merge branch 'Team-4---General-Mobs' into Team-4--General-Mobs-Max
Browse files Browse the repository at this point in the history
  • Loading branch information
max9753 committed Sep 11, 2023
2 parents e303bd5 + 4003dcd commit 1c6dac0
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,8 @@ private void spawnProjectile(Vector2 position, short targetLayer, int space, in


private void spawnXenoGrunts() {
GridPoint2 minPos = terrain.getMapBounds(0).sub(1, 5);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(1, 25);
GridPoint2 minPos = terrain.getMapBounds(0).sub(1, 0);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(1, 10);
for (int i = 0; i < NUM_GRUNTS; i++) {
GridPoint2 randomPos = RandomUtils.random(maxPos, minPos);
System.out.println(randomPos);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.Weapon;
import com.csse3200.game.physics.BodyUserData;
import com.csse3200.game.physics.PhysicsLayer;
import com.csse3200.game.physics.components.HitboxComponent;
Expand Down Expand Up @@ -103,6 +104,18 @@ private void onCollisionStart(Fixture me, Fixture other) {
public void setDisposeOnHit(boolean disposeOnHit) {
this.disposeOnHit = disposeOnHit;
}
public Weapon chooseWeapon(Fixture other) {
Entity target = ((BodyUserData) other.getBody().getUserData()).entity;
Weapon weapon = null;
if (target.getComponent(CombatStatsComponent.class) != null) {
weapon = combatStats.getWeapon(target);
}
return weapon;
}

private void onCollisionEnd(Fixture me, Fixture other) {
// Nothing to do on collision end
}
// private void onCollisionEnd(Fixture me, Fixture other) {
// // Nothing to do on collision end
// }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.csse3200.game.components.tasks;

import com.badlogic.gdx.physics.box2d.Fixture;
import com.csse3200.game.ai.tasks.DefaultTask;
import com.csse3200.game.ai.tasks.PriorityTask;
import com.csse3200.game.components.CombatStatsComponent;
import com.csse3200.game.components.TouchAttackComponent;
import com.csse3200.game.entities.Entity;
import com.badlogic.gdx.math.Vector2;
import com.csse3200.game.entities.Melee;
import com.csse3200.game.entities.Weapon;
import com.csse3200.game.physics.BodyUserData;
import com.csse3200.game.physics.PhysicsEngine;
import com.csse3200.game.physics.PhysicsLayer;
import com.csse3200.game.physics.components.PhysicsMovementComponent;
import com.csse3200.game.physics.raycast.RaycastHit;
import com.csse3200.game.rendering.AnimationRenderComponent;
import com.csse3200.game.services.ServiceLocator;
Expand All @@ -20,7 +25,7 @@
*/
public class MobAttackTask extends DefaultTask implements PriorityTask {
private static final int INTERVAL = 1; // time interval to scan for towers in
private static final short TARGET = PhysicsLayer.OBSTACLE; // mobs detecting for towers
private static final short TARGET = PhysicsLayer.HUMANS; // mobs detecting for towers
// ^ fix this

private static final String STOW = "wanderStart";
Expand Down Expand Up @@ -70,6 +75,7 @@ public void start() {
this.maxRangePosition.set(0, mobPosition.y);
//owner.getEntity().getEvents().trigger(IDLE);
endTime = timeSource.getTime() + (INTERVAL * 500);
owner.getEntity().getEvents().trigger("shootStart");
}

/**
Expand All @@ -90,41 +96,37 @@ public void update() {
* triggers the appropriate events corresponding to the STATE enum.
*/
public void updateMobState() {
// TouchAttackComponent attackComp = owner.getEntity().getComponent(TouchAttackComponent.class);
CombatStatsComponent statsComp = owner.getEntity().getComponent(CombatStatsComponent.class);
// if (statsComp != null) {
// System.out.println("is the target visible " + isTargetVisible());
// }
if (!isTargetVisible()) {
System.out.println("target is not visible for " + owner.getEntity().getId());
}
switch (mobState) {

case IDLE -> {
if (isTargetVisible()) {
// targets detected in idle mode - start deployment
//owner.getEntity().getEvents().trigger(DEPLOY);
owner.getEntity().getEvents().trigger(DEPLOY);
mobState = STATE.DEPLOY;
}
}

case DEPLOY -> {
// currently deploying,
if (isTargetVisible()) {
//owner.getEntity().getEvents().trigger(FIRING);
if (isTargetVisible() || this.meleeOrProjectile() != null) {
owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(false);
owner.getEntity().getEvents().trigger(FIRING);
mobState = STATE.FIRING;
} else {
//owner.getEntity().getEvents().trigger(STOW);
owner.getEntity().getEvents().trigger(STOW);
mobState = STATE.STOW;
}
}

case FIRING -> {
// targets gone - stop firing
if (!isTargetVisible()) {
//owner.getEntity().getEvents().trigger(STOW);
// targets gone or cannot be attacked - stop firing
if (!isTargetVisible() || this.meleeOrProjectile() == null) {
owner.getEntity().getEvents().trigger(STOW);
mobState = STATE.STOW;
} else {
if (this.meleeOrProjectile() instanceof Melee) {

}
Entity newProjectile = ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f));
newProjectile.setPosition((float) (owner.getEntity().getPosition().x), (float) (owner.getEntity().getPosition().y));
newProjectile.setScale(-1f, 0.5f);
Expand All @@ -134,15 +136,17 @@ public void updateMobState() {
owner.getEntity().getEvents().trigger(FIRING);
mobState = STATE.STOW;
}
owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(true);

}

case STOW -> {
// currently stowing
if (isTargetVisible()) {
//owner.getEntity().getEvents().trigger(DEPLOY);
owner.getEntity().getEvents().trigger(DEPLOY);
mobState = STATE.DEPLOY;
} else {
//owner.getEntity().getEvents().trigger(IDLE);
owner.getEntity().getEvents().trigger(IDLE);
mobState = STATE.IDLE;
}
}
Expand All @@ -154,8 +158,12 @@ public void updateMobState() {
*/
@Override
public void stop() {
super.stop();
owner.getEntity().getEvents().trigger(STOW);
if (mobState == STATE.FIRING || mobState == STATE.DEPLOY) {
this.updateMobState();
} else {
super.stop();
owner.getEntity().getEvents().trigger(STOW);
}
}

/**
Expand All @@ -164,26 +172,20 @@ public void stop() {
*/
@Override
public int getPriority() {
// return -1;
if (status == Status.ACTIVE) {
return getActivePriority();
}
return getInactivePriority();
// return isTargetVisible() ? getActivePriority() : getInactivePriority();
}

/**
* Fetches the active priority of the Task if a target is visible.
* @return (int) active priority if a target is visible, -1 otherwise
*/
private int getActivePriority() {
if ((startTime + delay) < timeSource.getTime()) {
// if (isTargetVisible() && (startTime + delay) > timeSource.getTime()) {
// System.out.println("ready to fire while active");
if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) {
return priority;
}
// System.out.println("not ready to fire while active");
// return !isTargetVisible() ? -1 : priority;
return -1;
}

Expand All @@ -192,22 +194,45 @@ private int getActivePriority() {
* @return (int) -1 if a target is not visible, active priority otherwise
*/
private int getInactivePriority() {
// return isTargetVisible() ? priority : 0;
if ((startTime + delay) < timeSource.getTime()) {
// if (isTargetVisible() && (startTime + delay) > timeSource.getTime()) {
// System.out.println("ready to fire while inactive");
if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) {
return priority;
}
return -1;
// System.out.println("not ready to fire while inactive");
// return isTargetVisible() ? priority : -1;
}

/**
* Uses a raycast to determine whether there are any targets in detection range
* @return true if a target is visible, false otherwise
*/
private boolean isTargetVisible() {
return physics.raycast(mobPosition, maxRangePosition, TARGET, hit);
Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f);
return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET, hit);
}

/**
* Uses a custom raycast method to find the closest target to the mob. Based on the distance to the
* target, the mob will choose a weapon to attack with.
*
* If the object does not have a CombatStatsComponent (which handles dealing damage etc), then
* the function will return null. If it returns null when the mob is in state FIRING or DEPLOY, it will not fire
* and will STOW.
*
* returns the Weapon (Melee or Projectile) the mob will use to attack the target. null if immune target or no target
* */
private Weapon meleeOrProjectile() {
Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f);
Fixture hitraycast = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET);
TouchAttackComponent comp = owner.getEntity().getComponent(TouchAttackComponent.class);
Weapon chosenWeapon = null;
if (comp != null) {
chosenWeapon = comp.chooseWeapon(hitraycast);
}

return chosenWeapon;
}

private void setTarget() {
Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f);
Fixture hitraycast = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.csse3200.game.entities;

import com.csse3200.game.entities.configs.NPCConfigs;
import com.csse3200.game.entities.configs.ProjectileConfig;

public class PredefinedWeapons {
// Melee attacks
public static Melee sword = new Melee(10, 4, "fire", 1, 1);
public static Melee punch = new Melee(3, 1, "air", 1, 1);
public static Melee axe = new Melee(9, 3, "fire", 1, 1);
public static Melee kick = new Melee(2, 1, "earth", 1, 1);

public static ProjectileConfig fireBall = new ProjectileConfig();
public static ProjectileConfig frostBall = new ProjectileConfig();

// Projectile attacks TODO: change Weapon and Melee to Projectile class
public static Weapon fireBall = new Melee(9, 20, "fire", 1, 1);
public static Weapon frostBall = new Melee(6, 20, "ice", 1, 1);
public static Weapon hurricane = new Melee(7, 20, "air", 1, 1);
// public static Weapon fireBall = new Melee(9, 20, "fire", 1, 1);
// public static Weapon frostBall = new Melee(6, 20, "ice", 1, 1);
// public static Weapon hurricane = new Melee(7, 20, "air", 1, 1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,8 @@ public static Entity createXenoGrunt(Entity target) {
Entity xenoGrunt = createBaseNPC(target);
BaseEnemyConfig config = configs.xenoGrunt;
ArrayList<Melee> melee = new ArrayList<>(Arrays.asList(PredefinedWeapons.sword, PredefinedWeapons.kick));
ArrayList<ProjectileConfig> projectiles = new ArrayList<>();
// ArrayList<ProjectileConfig> projectiles = new ArrayList<>(Arrays.asList(PredefinedWeapons.fireBall, PredefinedWeapons.hurricane));
// ArrayList<Integer> drops = new ArrayList<>(Arrays.asList(1, 2));
// tester projectiles
ArrayList<ProjectileConfig> projectiles = new ArrayList<>(Arrays.asList(PredefinedWeapons.fireBall, PredefinedWeapons.frostBall));
ArrayList<Currency> drops = new ArrayList<>();

AnimationRenderComponent animator =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,18 @@ public boolean raycast(Vector2 from, Vector2 to, short layerMask, RaycastHit hit
return singleHitCallback.didHit;
}

public Fixture raycastGetHit(Vector2 from, Vector2 to, short layerMask, RaycastHit hit) {

/**
* Cast a ray in a straight line from one point to another, checking for a collision
* against colliders in the specified layers.
*
* @param from The starting point of the ray.
* @param to The end point of the ray.
* @param layerMask The physics layer mask which specifies layers that can be hit. Other layers
* will be ignored.
* @return The fixture of the closest collider hit by the ray, or null if no collider was hit.
* */
public Fixture raycastGetHit(Vector2 from, Vector2 to, short layerMask) {
singleHitCallback.didHit = false;
singleHitCallback.layerMask = layerMask;
world.rayCast(singleHitCallback, from, to);
Expand Down

0 comments on commit 1c6dac0

Please sign in to comment.