ProjectZombie/src/projectzombie/entity/player/EntityPlayer.java

382 lines
8.3 KiB
Java
Executable File

package projectzombie.entity.player;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import gl_engine.MathHelpers;
import gl_engine.vec.Vec2d;
import gl_engine.vec.Vec2i;
import mainloop.task.IMainloopTask;
import projectzombie.Main;
import projectzombie.display.DisplayLighting;
import projectzombie.entity.Entity;
import projectzombie.entity.EntityAlive;
import projectzombie.entity.EntityBullet;
import projectzombie.entity.EntityHeight;
import projectzombie.entity.EntityInventory;
import projectzombie.entity.EntityItem;
import projectzombie.entity.particle.ParticleBreak;
import projectzombie.init.Items;
import projectzombie.init.Models;
import projectzombie.inventory.Inventory;
import projectzombie.menu.MenuDeath;
import projectzombie.model.Model;
import projectzombie.settings.Cheats;
import projectzombie.util.math.ItemStack;
import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer;
public class EntityPlayer extends Entity implements EntityAlive, EntityInventory, EntityHeight
{
public boolean MOVE_FORWARD = false;
public boolean MOVE_BACKWARD = false;
public boolean MOVE_LEFT = false;
public boolean MOVE_RIGHT = false;
public boolean GUN = false;
public boolean moving = false;
public Model PLAYER_MOVING = Models.ENTITY_PLAYER_B_W_MOVING;
public Model PLAYER_STILL = Models.ENTITY_PLAYER_B_W_STILL;
public double height = 0;
private int bullet_frequency = 0;
private double health_max = 1000;
private double health = health_max;
private double temperature = 0.5;
private double hydration = 1;
public boolean dead = false;
public boolean in_animation = false;
private Inventory inventory;
public int inventory_hand = 0;
public int defence_level = 0;
public int gun_level = 0;
public double angle;
public double speed;
private Vec2i last_chunk;
public EntityPlayer(BdfObject bdf) {
super(bdf);
}
@Override
public void BdfClassLoad(BdfObject bdf) {
super.BdfClassLoad(bdf);
BdfNamedList nl = bdf.getNamedList();
height = nl.get("height").getDouble();
bullet_frequency = nl.get("bullet_frequency").getInteger();
health = nl.get("health").getDouble();
dead = nl.get("dead").getBoolean();
inventory = new Inventory(nl.get("inventory"));
defence_level = nl.get("defence_level").getInteger();
gun_level = nl.get("gun_level").getInteger();
angle = nl.get("angle").getDouble();
temperature = nl.get("temperature").getDouble();
hydration = nl.get("hydration").getDouble();
}
public int getAmmo() {
return inventory.getItemCount(Items.AMMO);
}
@Override
public void BdfClassSave(BdfObject bdf) {
super.BdfClassSave(bdf);
BdfNamedList nl = bdf.getNamedList();
nl.set("height", BdfObject.withDouble(height));
nl.set("bullet_frequency", BdfObject.withInteger(bullet_frequency));
nl.set("health", BdfObject.withDouble(health));
nl.set("dead", BdfObject.withBoolean(dead));
inventory.BdfClassSave(nl.get("inventory"));
nl.set("defence_level", BdfObject.withInteger(defence_level));
nl.set("gun_level", BdfObject.withInteger(gun_level));
nl.set("angle", BdfObject.withDouble(angle));
nl.set("temperature", BdfObject.withDouble(temperature));
nl.set("hydration", BdfObject.withDouble(hydration));
}
public EntityPlayer() {
super(new Vec2d(0, 0));
this.angle = 45;
// Set some settings
hitbox = 0.5;
isSolid = true;
goThroughSolid = false;
crossUnWalkable = false;
emitsLight = true;
speed = 0.1;
// Create the inventory
inventory = new Inventory(10);
inventory.addItem(new ItemStack(Items.AMMO, 999, (short)0));
inventory.addItem(new ItemStack(Items.SPAWN_DUMMY, 999, (short)0));
inventory.addItem(new ItemStack(Items.SPAWN_ZOMBIE, 999, (short)0));
inventory.addItem(new ItemStack(Items.LANTERN, 999, (short)0));
}
@Override
public double getLightLevel()
{
if(Main.menu.playerEmitsLight) {
return getLightWithHeight(1);
}
ItemStack item = inventory.getItem(inventory_hand);
if(!item.isEmpty()) {
return getLightWithHeight(item.item.getLightLevel());
}
return 0;
}
@Override
public void tick(Chunk chunk, Layer layer)
{
chunk = layer.getChunk(pos);
if(chunk != null && chunk.c_pos != null && (last_chunk == null || !chunk.c_pos.equal(last_chunk))) {
last_chunk = chunk.c_pos;
DisplayLighting.setDirty();
}
if(dead) return;
// Handle player deaths
if(health <= 0)
{
chunk.spawnEntity(new ParticleBreak(pos, getModel()));
if(Cheats.god_mode) {
this.resetHealth();
}
else {
dead = true;
health = 0;
Main.mainloop.register(new IMainloopTask() {
@Override
public void MainLoopUpdate() {
Main.menu = new MenuDeath();
}
@Override
public boolean MainLoopRepeat() {
return false;
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > 2500;
}
});
}
return;
}
// Is the player dead or in an animation
if(dead || in_animation) return;
// Call super
super.tick(chunk, layer);
double temp_diff = MathHelpers.biggest(
layer.layergen.getTemperatureDynamic(layer, pos),
chunk.getLightLevel(pos.toInt()) * 0.6) - temperature;
temperature += temp_diff / 1000;
hydration -= Math.sqrt(Math.abs(temperature - 0.5)) / 5000;
if(temperature < 0.3) {
health -= 0.3 - temperature;
}
if(temperature > 0.7) {
health -= temperature - 0.7;
}
if(hydration <= 0) {
hydration = 0;
health -= 0.1;
}
// Rotate left
if(MOVE_LEFT) {
this.angle -= 1;
}
// Rotate right
if(MOVE_RIGHT) {
this.angle += 1;
}
this.angle = MathHelpers.mod(this.angle, 360);
// Move forward
if(MOVE_FORWARD) {
this.moveTowards(this.angle);
}
// Move backward
if(MOVE_BACKWARD) {
this.moveTowards(this.angle + 180);
}
// Use the gun
if(GUN) {
this.fireBullet(0);
}
}
@Override
public void kill()
{
// Is god mode inactive; kill the player
if(Cheats.god_mode) {
return;
}
chunk.spawnEntity(new ParticleBreak(pos, getModel()));
dead = true;
}
@Override
public void moveTowards(double angle, double speed) {
if(dead || in_animation) return;
super.moveTowards(angle, speed);
}
public void moveTowards(double angle) {
this.moveTowards(angle, 0.08);
}
public void fireBullet(double angle)
{
if(dead || in_animation) return;
bullet_frequency += 1;
bullet_frequency %= 10;
// Is there enough ammo and are the bullets at the right frequency
if(bullet_frequency == 0 && getAmmo() > 0)
{
// Remove some ammo
inventory.removeItem(Items.AMMO, 1);
// Summon bullets at this angle relative to the player
int d = (int)(1 + gun_level / 4.0);
Main.world.getLayer().spawnEntity(new EntityBullet(pos.copy(), this, angle + this.angle,
20*d*d, 60).withHeight(0, height));
}
}
public void activateItem() {
if(dead || in_animation) return;
ItemStack is = inventory.getItem(inventory_hand);
if(!is.isEmpty()) {
is.item.onPlayerAction(is, Main.world.getLayer(), chunk, this);
}
}
@Override
public void addHealth(double amount) {
health += amount;
if(health > health_max) health = health_max;
}
@Override
public void removeHealth(double amount) {
amount = amount / (defence_level / 2.5 + 1);
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 Inventory getInventory() {
return inventory;
}
public void dropItem()
{
ItemStack i = inventory.getItem(inventory_hand);
if(!i.isEmpty())
{
EntityItem e = new EntityItem(pos.copy(), new ItemStack(i.item, 1, i.meta));
e.angle = angle;
Main.world.getLayer().spawnEntity(e);
i.count -= 1;
}
}
@Override
public void push(double amount, double angle) {
}
@Override
public int bloodParticles() {
return 12;
}
@Override
public double getHeight() {
return height;
}
@Override
public void setHeight(double height) {
this.height = height;
}
@Override
public Model getModel() {
return moving ? PLAYER_MOVING : PLAYER_STILL;
}
public double getTemperature() {
return temperature;
}
public double getHydration() {
return hydration;
}
}