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