230 lines
5.6 KiB
Java
Executable File
230 lines
5.6 KiB
Java
Executable File
package projectzombie.entity;
|
|
|
|
import java.util.Random;
|
|
|
|
import bdf.types.BdfNamedList;
|
|
import bdf.types.BdfObject;
|
|
import projectzombie.Main;
|
|
import projectzombie.init.Models;
|
|
import projectzombie.model.Model;
|
|
import projectzombie.util.gl.texture.TextureReference;
|
|
import projectzombie.util.math.astar.AStar;
|
|
import projectzombie.util.math.astar.AStarSearcher;
|
|
import projectzombie.util.math.random.OpenSimplexNoise;
|
|
import gl_engine.vec.Vec2d;
|
|
import gl_engine.vec.Vec2i;
|
|
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 Vec2i walk_direction;
|
|
private int walk_scan_cooldown = 0;
|
|
private boolean can_see_player = false;
|
|
private int walking_for = 0;
|
|
|
|
public EntityZombie(BdfObject bdf) {
|
|
super(bdf);
|
|
|
|
// Set some settings
|
|
hitbox = 0.5;
|
|
isSolid = true;
|
|
goThroughSolid = false;
|
|
crossUnWalkable = false;
|
|
}
|
|
|
|
@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", BdfObject.withDouble(health_max));
|
|
nl.set("health", BdfObject.withDouble(health));
|
|
nl.set("gun_interval", BdfObject.withInteger(gun_interval));
|
|
nl.set("gun_level", BdfObject.withInteger(gun_level));
|
|
nl.set("seed", BdfObject.withLong(seed));
|
|
|
|
|
|
}
|
|
|
|
public EntityZombie(Vec2d pos) {
|
|
super(pos);
|
|
|
|
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;
|
|
goThroughSolid = false;
|
|
crossUnWalkable = false;
|
|
}
|
|
|
|
@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_direction == null) {
|
|
walk_scan_cooldown -= 1;
|
|
}
|
|
|
|
if(
|
|
(walk_direction != null && pos.toInt().equal(walk_direction) &&
|
|
pos.squareDistance(Main.player.pos) > 2) ||
|
|
walk_scan_cooldown < 1 || walking_for > 200)
|
|
{
|
|
AStar astar = new AStar(pos.toInt(), 16, new AStarSearcher(layer, crossUnWalkable));
|
|
Vec2i path[] = astar.getPath(Main.player.pos.toInt());
|
|
|
|
walk_scan_cooldown = 100;
|
|
walking_for = 0;
|
|
|
|
if(path != null && path.length > 1) {
|
|
walk_direction = path[1];
|
|
} else {
|
|
walk_direction = Main.player.pos.toInt();
|
|
}
|
|
|
|
can_see_player = (path != null);
|
|
}
|
|
|
|
// Walk towards the player
|
|
if(walk_direction != null)
|
|
{
|
|
double angle = Math.toDegrees(Math.atan2(
|
|
walk_direction.x - (this.pos.x - 0.5) + noise_target_x.eval(time, pos.x/10, pos.y/10),
|
|
walk_direction.y - (this.pos.y - 0.5) + noise_target_y.eval(time, pos.x/10, pos.y/10)));
|
|
this.moveTowards(angle);
|
|
|
|
walking_for += 1;
|
|
}
|
|
|
|
if(can_see_player && noise_gun_fire.eval(time, 0) > 0 && !Main.player.dead && !Main.player.in_animation)
|
|
{
|
|
// Get the angle between the player and the zombie
|
|
double angle_fire = Math.atan2(pos.x - Main.player.pos.x, pos.y - Main.player.pos.y);
|
|
|
|
gun_interval += 1;
|
|
gun_interval %= 10;
|
|
|
|
if(gun_interval == 0)
|
|
{
|
|
// Aim the gun at the player
|
|
double angle_gun = Math.toDegrees(angle_fire) + 180;
|
|
angle_gun += noise_gun_angle.eval(time, 0)*20;
|
|
|
|
// Fire the gun
|
|
int d = (int)(1 + gun_level / 5.0);
|
|
layer.spawnEntity(new EntityBullet(pos.copy(), this, angle_gun, 20*d*d, 60));
|
|
}
|
|
}
|
|
|
|
// Increase time
|
|
time += 0.001;
|
|
}
|
|
|
|
@Override
|
|
public Model getModel() {
|
|
return Models.ENTITY_ZOMBIE_F;
|
|
}
|
|
|
|
public void moveInVector(Vec2d vec) {
|
|
super.moveInVector(vec, 0.06);
|
|
}
|
|
|
|
public void moveTowards(double angle) {
|
|
super.moveTowards(angle, 0.06);
|
|
}
|
|
|
|
@Override
|
|
public void addHealth(double amount) {
|
|
health += amount;
|
|
}
|
|
|
|
@Override
|
|
public void removeHealth(double amount) {
|
|
health -= 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 10;
|
|
}
|
|
|
|
@Override
|
|
public void killWithParticles() {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
}
|