package projectzombie.entity; import java.util.Random; import bdf.types.BdfNamedList; import bdf.types.BdfObject; import gl_engine.vec.Vec2i; import gl_engine.vec.Vec3d; import projectzombie.Main; import projectzombie.init.Models; import projectzombie.model.Model; import projectzombie.util.math.astar.AStar; import projectzombie.util.math.astar.AStarSearcher; import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.world.chunk.Chunk; import projectzombie.world.layer.Layer; public class EntityZombie extends Entity implements EntityAlive, EntityKillWithParticles { protected OpenSimplexNoise noise_movement; protected OpenSimplexNoise noise_gun_fire; protected OpenSimplexNoise noise_gun_angle; protected OpenSimplexNoise noise_target_x; protected OpenSimplexNoise noise_target_y; protected long seed; protected double time; protected double health_max = 100; protected double health = health_max; protected int gun_interval = 0; protected int gun_level = 0; private Vec3d walk_to; private int walk_scan_cooldown = 0; private boolean can_see_player = false; protected boolean crossUnwalkable = false; private int walking_for = 0; public EntityZombie(BdfObject bdf) { // Set some settings hitbox = 0.5; isSolid = true; BdfClassLoad(bdf); } @Override public void BdfClassLoad(BdfObject bdf) { super.BdfClassLoad(bdf); BdfNamedList nl = bdf.getNamedList(); health_max = nl.get("max_health").getDouble(); health = nl.get("health").getDouble(); gun_interval = nl.get("gun_interval").getInteger(); gun_level = nl.get("gun_level").getInteger(); seed = nl.get("seed").getLong(); Random rand = new Random(seed); noise_movement = new OpenSimplexNoise(rand.nextLong()); noise_gun_fire = new OpenSimplexNoise(rand.nextLong()); noise_gun_angle = new OpenSimplexNoise(rand.nextLong()); noise_target_x = new OpenSimplexNoise(rand.nextLong()); noise_target_y = new OpenSimplexNoise(rand.nextLong()); } @Override public void BdfClassSave(BdfObject bdf) { super.BdfClassSave(bdf); BdfNamedList nl = bdf.getNamedList(); nl.set("max_health", bdf.newObject().setDouble(health_max)); nl.set("health", bdf.newObject().setDouble(health)); nl.set("gun_interval", bdf.newObject().setInteger(gun_interval)); nl.set("gun_level", bdf.newObject().setInteger(gun_level)); nl.set("seed", bdf.newObject().setLong(seed)); } public EntityZombie(Vec3d pos, Vec3d velocity) { super(pos, velocity); seed = rand.nextLong(); Random rand = new Random(seed); noise_movement = new OpenSimplexNoise(rand.nextLong()); noise_gun_fire = new OpenSimplexNoise(rand.nextLong()); noise_gun_angle = new OpenSimplexNoise(rand.nextLong()); noise_target_x = new OpenSimplexNoise(rand.nextLong()); noise_target_y = new OpenSimplexNoise(rand.nextLong()); time = 0; // Set some settings hitbox = 0.5; isSolid = true; } @Override public void tick(Chunk chunk, Layer layer) { super.tick(chunk, layer); //System.out.println(walk_direction != null ? (walk_direction.x + ", " + walk_direction.y + ": " + pos.toInt().x + ", " + pos.toInt().y) : "null"); if(walk_to == null) { walk_scan_cooldown -= 1; } double player_distance = getPos().squareDistance(Main.player.getPos()); // Only pathfind if in range of the player if(player_distance < 16) { if( (walk_to != null && getPos().toInt().equal(walk_to.toInt()) && player_distance > 2) || walk_scan_cooldown < 1 || walking_for > 200) { AStar astar = new AStar(getPos().xz().toInt(), 16, new AStarSearcher(layer)); Vec2i path[] = astar.getPath(Main.player.getPos().xz().toInt()); walk_scan_cooldown = 100; walking_for = 0; if(path != null && path.length > 1) { walk_to = new Vec3d(path[0].x, 0, path[0].y); } else { walk_to = null; } can_see_player = (path != null); } // Walk towards the player if(walk_to != null) { push(walk_to.subtract(getPos()).normalize().multiply(0.064)); walking_for += 1; } if(can_see_player && noise_gun_fire.eval(time, 0) > 0 && !Main.player.dead && !Main.player.in_animation) { gun_interval += 1; gun_interval %= 10; if(gun_interval == 0) { // Fire the gun int d = (int)(1 + gun_level / 5.0); Vec3d bullet_velocity = getVelocity().add(Main.player.getPos().subtract(getPos())).normalize().multiply(0.2); Vec3d bullet_pos = getPos().add(new Vec3d(0, 0.4, 0)); Main.world.getLayer().spawnEntity(new EntityBullet(bullet_pos, bullet_velocity, this, 20*d*d, 60)); } } } // Despawn if(player_distance > 128) { kill(); } // Increase time time += 0.001; } @Override public Model getModel() { return Models.ENTITY_ZOMBIE_F; } @Override public void addHealth(double amount) { health += amount; } @Override public void addDamage(double amount) { health -= amount; } @Override public void addBlastDamage(double amount) { addDamage(amount); } @Override public void addFireDamage(double amount) { addDamage(amount); } @Override public double getHealth() { return health; } @Override public void resetHealth() { health = health_max; } @Override public void clearHealth() { health = 0; } @Override public double maxHealth() { return health_max; } @Override public void setHealth(double health) { this.health = health; } @Override public int bloodParticles() { return 12; } @Override public void killWithParticles() { // TODO Auto-generated method stub } }