ProjectZombie/src/projectzombie/entity/EntityZombie.java

231 lines
5.5 KiB
Java
Executable File

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
}
}