Added extra items (light sources), added random tile ticks, added more

debug tools, changed how the world works.
This commit is contained in:
josua 2019-09-16 14:35:09 +10:00
parent 54b6262813
commit 85728d450b
39 changed files with 590 additions and 111 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

View File

@ -10,6 +10,7 @@ import shootergame.display.DisplayStatsEventHandler;
import shootergame.display.DisplayWindow; import shootergame.display.DisplayWindow;
import shootergame.entity.EntityEventHandler; import shootergame.entity.EntityEventHandler;
import shootergame.entity.player.EntityPlayer; import shootergame.entity.player.EntityPlayer;
import shootergame.init.Layers;
import shootergame.init.Resources; import shootergame.init.Resources;
import shootergame.init.Sounds; import shootergame.init.Sounds;
import shootergame.init.Textures; import shootergame.init.Textures;
@ -17,6 +18,7 @@ import shootergame.input.JoystickCallback;
import shootergame.mainloop.MainloopEventHandler; import shootergame.mainloop.MainloopEventHandler;
import shootergame.menu.Menu; import shootergame.menu.Menu;
import shootergame.menu.MenuNone; import shootergame.menu.MenuNone;
import shootergame.tiles.LightLevelNoise;
import shootergame.time.GameTimer; import shootergame.time.GameTimer;
import shootergame.world.World; import shootergame.world.World;
import shootergame.world.chunk.ChunkEventHandler; import shootergame.world.chunk.ChunkEventHandler;
@ -57,6 +59,7 @@ public class Main
mainloop.register(ChunkEventHandler.CHUNK_EVENT_HANDLER); mainloop.register(ChunkEventHandler.CHUNK_EVENT_HANDLER);
mainloop.register(DisplayStatsEventHandler.DISPLAY_STATS_EVENT_HANDLER); mainloop.register(DisplayStatsEventHandler.DISPLAY_STATS_EVENT_HANDLER);
mainloop.register(JoystickCallback.JOYSTICK_CALLBACK); mainloop.register(JoystickCallback.JOYSTICK_CALLBACK);
mainloop.register(new LightLevelNoise());
mainloop.register(new GameTimer()); mainloop.register(new GameTimer());
// Create the display // Create the display
@ -70,7 +73,7 @@ public class Main
JoystickCallback.JOYSTICK_CALLBACK.init(); JoystickCallback.JOYSTICK_CALLBACK.init();
// Create the world // Create the world
world = new World(new Random(), new LayerGenEarth(), new LayerGenCaves(), new LayerGenLavaCaves()); Layers.init(rand.nextLong());
// Initialise the entities // Initialise the entities
mainloop.register(EntityEventHandler.ENTITY_EVENT_HANDLER); mainloop.register(EntityEventHandler.ENTITY_EVENT_HANDLER);

View File

@ -83,8 +83,8 @@ public class LightingManager
// Calculate the light given off by the tile // Calculate the light given off by the tile
double light_tile = chunk.getLightLevel(tid); double light_tile = chunk.getLightLevel(tid);
double light_tile_old = light_tile; double light_tile_old = light_tile;
light_tile = MathHelpers.biggest(light_tile, fts.tile.getLightLevel(fts)); light_tile = MathHelpers.biggest(light_tile, fts.tile.getLightLevel(fts, tpos));
light_tile = MathHelpers.biggest(light_tile, fts.tile.getLightLevel(bts)); light_tile = MathHelpers.biggest(light_tile, fts.tile.getLightLevel(bts, tpos));
// Has the light level changed; add light to this tile // Has the light level changed; add light to this tile
if(light_tile != light_tile_old) { if(light_tile != light_tile_old) {

View File

@ -2,6 +2,7 @@ package shootergame.entity;
import java.util.Random; import java.util.Random;
import mainloop.task.IMainloopTask;
import shootergame.Main; import shootergame.Main;
import shootergame.display.Camera; import shootergame.display.Camera;
import shootergame.display.transparent.ITransparentObject; import shootergame.display.transparent.ITransparentObject;
@ -31,6 +32,8 @@ public class Entity implements ITransparentObject
protected static final Random rand = new Random(); protected static final Random rand = new Random();
public boolean emitsLight = false; public boolean emitsLight = false;
public int stepOnTileCooldown = 0;
public Entity(Vec2d pos, double angle) public Entity(Vec2d pos, double angle)
{ {
// Add this entity to the list of entities // Add this entity to the list of entities
@ -47,13 +50,17 @@ public class Entity implements ITransparentObject
public void tick(Chunk chunk, Layer layer) { public void tick(Chunk chunk, Layer layer) {
speed = 1; speed = 1;
angle = MathHelpers.floor(angle); angle = MathHelpers.mod(angle, 360);
Vec2i tpos = new Vec2i(MathHelpers.floor(pos.x)+0, MathHelpers.floor(pos.y)+0); Vec2i tpos = new Vec2i(MathHelpers.floor(pos.x)+0, MathHelpers.floor(pos.y)+0);
if(chunk == null) chunk = layer.getChunk(pos); if(chunk == null) chunk = layer.getChunk(pos);
this.chunk = chunk; this.chunk = chunk;
tile_back = chunk.getBackTile(tpos); tile_back = chunk.getBackTile(tpos);
tile_front = chunk.getFrontTile(tpos); tile_front = chunk.getFrontTile(tpos);
if(stepOnTileCooldown > 0) {
stepOnTileCooldown -= 1;
}
if(this.isSolid) if(this.isSolid)
{ {
this.addSlowness(tile_back.tile.slowness); this.addSlowness(tile_back.tile.slowness);
@ -140,14 +147,20 @@ public class Entity implements ITransparentObject
public void activateSteppedOnTile() public void activateSteppedOnTile()
{ {
// Get the tile position and the layer // Has the cooldown expired
Layer layer = Main.world.getLayer(); if(stepOnTileCooldown == 0)
Vec2i tpos = new Vec2i(MathHelpers.floor(pos.x)+0, MathHelpers.floor(pos.y)+0); {
// Get the tile position and the layer
// Activate both tiles Layer layer = Main.world.getLayer();
tile_front.tile.onWalkedOn(chunk, layer, tpos, this, tile_front); Vec2i tpos = new Vec2i(MathHelpers.floor(pos.x)+0, MathHelpers.floor(pos.y)+0);
tile_back.tile.onWalkedOn(chunk, layer, tpos, this, tile_back);
// Activate both tiles
tile_front.tile.onWalkedOn(chunk, layer, tpos, this, tile_front);
tile_back.tile.onWalkedOn(chunk, layer, tpos, this, tile_back);
// Reset the cooldown
stepOnTileCooldown = 1;
}
} }
public boolean moveIsLegal(Vec2d pos) public boolean moveIsLegal(Vec2d pos)
@ -219,4 +232,30 @@ public class Entity implements ITransparentObject
public double getLightLevel() { public double getLightLevel() {
return 0; return 0;
} }
public void push(double amount, double angle)
{
double[] a = {amount};
Main.mainloop.register(new IMainloopTask() {
@Override
public void MainLoopUpdate() {
if(!Main.game_paused) {
moveTowards(angle, a[0]/100.0);
a[0] -= a[0] / 100.0;
}
}
@Override
public boolean MainLoopRepeat() {
return a[0] > 0.2;
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > 10;
}
});
}
} }

View File

@ -9,4 +9,5 @@ public interface EntityAlive
public void clearHealth(); public void clearHealth();
public double maxHealth(); public double maxHealth();
public void setHealth(double health); public void setHealth(double health);
public int bloodParticles();
} }

View File

@ -87,8 +87,11 @@ public class EntityBullet extends EntityParticle
// Get the alive entity // Get the alive entity
EntityAlive ea = (EntityAlive)e; EntityAlive ea = (EntityAlive)e;
// Knock the entity back abit
e.push(1, angle);
// Spawn some blood particles // Spawn some blood particles
for(int i=0;i<10;i++) { for(int i=0;i<ea.bloodParticles();i++) {
chunk.spawnEntity(new ParticleBlood(rand, pos.copy(), angle)); chunk.spawnEntity(new ParticleBlood(rand, pos.copy(), angle));
} }

View File

@ -0,0 +1,55 @@
package shootergame.entity;
import shootergame.init.Textures;
import shootergame.util.math.vec.Vec2d;
public class EntityDummy extends EntityVertical implements EntityAlive
{
public EntityDummy(Vec2d pos) {
super(Textures.ENTITY_DUMMY, new Vec2d(1, 1));
this.hitbox = 0.5;
this.isSolid = true;
this.pos = pos;
}
@Override
public void addHealth(double amount) {
}
@Override
public void removeHealth(double amount) {
int l = 4;
amount = amount / (l / 2.5 + 1);
System.out.println("Dummy Damage Aount: "+amount);
}
@Override
public double getHealth() {
return 100;
}
@Override
public void resetHealth() {
}
@Override
public void clearHealth() {
}
@Override
public double maxHealth() {
return 100;
}
@Override
public void setHealth(double health) {
}
@Override
public int bloodParticles() {
return 5;
}
}

View File

@ -0,0 +1,32 @@
package shootergame.entity;
import shootergame.display.Camera;
import shootergame.init.Textures;
import shootergame.util.gl.texture.TextureReference;
import shootergame.util.math.vec.Vec2d;
import shootergame.world.layer.Layer;
public class EntityFlare extends EntityTnt
{
@Override
protected void explode(Layer layer) {
kill();
}
public EntityFlare(Vec2d pos, double angle) {
super(pos, angle, 0, 0);
this.explode_time = 1000;
}
@Override
public void render(Vec2d pos, Camera camera, TextureReference tex, Vec2d size) {
super.render(pos, camera, Textures.ENTITY_FLARE, size);
}
@Override
public double getLightLevel() {
return (1 - (this.height * (1/12.0))) * ( rand.nextDouble() / 10.0 + 0.9 );
}
}

View File

@ -4,60 +4,78 @@ import shootergame.display.Camera;
import shootergame.entity.particle.ParticleSpark; import shootergame.entity.particle.ParticleSpark;
import shootergame.init.Textures; import shootergame.init.Textures;
import shootergame.util.gl.GlHelpers; import shootergame.util.gl.GlHelpers;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.vec.Vec2d; import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec3d;
import shootergame.world.chunk.Chunk; import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer; import shootergame.world.layer.Layer;
public class EntityTnt extends EntityVertical public class EntityTnt extends EntityVertical
{ {
private double height = 0.4; protected double height = 0.4;
private double velocity_up; protected Vec3d velocity;
private int explode_time; protected int explode_time;
private int explode_radius; private int explode_radius;
private double explode_damage; private double explode_damage;
public EntityTnt(Vec2d pos, double angle, int explode_radius, double explode_damage) { public EntityTnt(Vec2d pos, double angle, int explode_radius, double explode_damage) {
super(Textures.ENTITY_TNT, new Vec2d(0.5, 0.5)); super(Textures.ENTITY_TNT, new Vec2d(0.5, 0.5));
velocity_up = 0.01; Vec2d v = MathHelpers.moveTowards2(0.05, Math.toRadians(angle));
this.angle = angle; velocity = new Vec3d(v.x, v.y, 0.01);
this.pos = pos; this.pos = pos;
this.explode_radius = explode_radius; this.explode_radius = explode_radius;
this.crossUnWalkable = true; this.crossUnWalkable = true;
this.goThroughSolid = false; this.goThroughSolid = false;
this.explode_damage = explode_damage; this.explode_damage = explode_damage;
this.emitsLight = true;
// Set to 2.5 seconds // Set to 2.5 seconds
this.explode_time = 250; this.explode_time = 250;
} }
protected void explode(Layer layer)
{
// Create an explosion
layer.spawnEntity(new EntityExplosion(pos, explode_radius, explode_damage));
// Delete the entity
kill();
return;
}
@Override @Override
public void tick(Chunk chunk, Layer layer) { public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer); super.tick(chunk, layer);
// Create a downward gravitational pull // Create a downward gravitational pull
height += velocity_up; height += velocity.z;
velocity_up -= 0.001; velocity.z -= 0.001;
// Move forwards // Move forwards
moveForward(0.05); Vec2d pos_copy = pos.copy();
pos.x += velocity.x;
pos.y += velocity.y;
if(!moveIsLegal(new Vec2d(pos.x, pos_copy.y))) {
pos.x = pos_copy.x;
velocity.x *= -1;
}
if(!moveIsLegal(new Vec2d(pos_copy.x, pos.y))) {
pos.y = pos_copy.y;
velocity.y *= -1;
}
// Make the tnt bounce on the ground // Make the tnt bounce on the ground
if(height < 0) { if(height < 0) {
height = 0; height = 0;
velocity_up = -velocity_up; velocity.z *= -1;
} }
// Is it time for the tnt to blow up // Explode if it is time for the tnt to blow up
explode_time -= 1; explode_time -= 1;
if(explode_time < 0) if(explode_time < 0) {
{ explode(layer);
// Create an explosion
layer.spawnEntity(new EntityExplosion(pos, explode_radius, explode_damage));
// Delete the entity
kill();
return;
} }
// Create sparks // Create sparks
@ -74,6 +92,9 @@ public class EntityTnt extends EntityVertical
GlHelpers.popMatrix(); GlHelpers.popMatrix();
} }
@Override
public double getLightLevel() {
return (1 - (this.height * (1/12.0))) * rand.nextDouble();
}
} }

View File

@ -16,6 +16,7 @@ public class EntityZombie extends EntityVertical implements EntityAlive
protected double health_max = 100; protected double health_max = 100;
protected double health = health_max; protected double health = health_max;
protected int gun_interval = 0; protected int gun_interval = 0;
protected int gun_level = 0;
public EntityZombie() { public EntityZombie() {
super(Textures.ENTITY_ZOMBIE, new Vec2d(1, 1)); super(Textures.ENTITY_ZOMBIE, new Vec2d(1, 1));
@ -55,7 +56,9 @@ public class EntityZombie extends EntityVertical implements EntityAlive
angle_gun += noise_gun_angle.eval(time, 0)*20; angle_gun += noise_gun_angle.eval(time, 0)*20;
// Fire the gun // Fire the gun
layer.spawnEntity(new EntityBullet(pos.copy(), this, angle_gun, 20, 5)); int d = (int)(1 + gun_level / 5.0);
int b = (int)(1 - gun_level / 5.0);
layer.spawnEntity(new EntityBullet(pos.copy(), this, angle_gun, 20*d*d, 5*b*b));
} }
} }
@ -107,5 +110,10 @@ public class EntityZombie extends EntityVertical implements EntityAlive
public void setHealth(double health) { public void setHealth(double health) {
this.health = health; this.health = health;
} }
@Override
public int bloodParticles() {
return 10;
}
} }

View File

@ -11,8 +11,10 @@ public class EntityZombieArmored extends EntityZombie
public EntityZombieArmored() { public EntityZombieArmored() {
this.health_max *= 5; this.health_max *= 5;
this.gun_interval *= 2;
this.health = this.health_max; this.health = this.health_max;
this.gun_level = 3;
this.crossUnWalkable = true;
} }
@Override @Override
@ -20,6 +22,9 @@ public class EntityZombieArmored extends EntityZombie
super.render(pos, camera, Textures.ENTITY_ZOMBIE_ARMORED, new Vec2d(1, 1)); super.render(pos, camera, Textures.ENTITY_ZOMBIE_ARMORED, new Vec2d(1, 1));
} }
@Override
public int bloodParticles() {
return 2;
}
} }

View File

@ -0,0 +1,55 @@
package shootergame.entity.particle;
import java.util.Random;
import shootergame.display.Camera;
import shootergame.entity.EntityParticle;
import shootergame.util.gl.GlHelpers;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.random.RandomHelpers;
import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec3d;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class ParticleLava extends EntityParticle
{
private static Random rand = new Random();
private Vec3d velocity;
private double height = 0;
public ParticleLava(Vec2d pos) {
super(rand.nextDouble()/5, 0);
// Set the velocity
velocity = MathHelpers.moveTowards3(0.05, new Vec2d(Math.toRadians(
RandomHelpers.randrange(rand, 360)), Math.toRadians(RandomHelpers.randrange(rand, 0, 45))));
this.pos = pos;
}
@Override
public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer);
// Add the velocity
velocity.z -= 0.0005;
pos.x += velocity.x;
pos.y += velocity.y;
height += velocity.z;
// Is the height below 0; destroy this particle
if(height < 0) {
kill();
}
}
@Override
public void render(Vec2d pos, Camera camera) {
GlHelpers.pushMatrix();
GlHelpers.translate(0, 0, height);
GlHelpers.color3(1, 0, 0);
super.render(pos, camera);
GlHelpers.popMatrix();
}
}

View File

@ -1,7 +1,5 @@
package shootergame.entity.particle; package shootergame.entity.particle;
import java.util.Random;
import shootergame.display.Camera; import shootergame.display.Camera;
import shootergame.entity.EntityParticle; import shootergame.entity.EntityParticle;
import shootergame.util.gl.GlHelpers; import shootergame.util.gl.GlHelpers;
@ -15,7 +13,6 @@ import shootergame.world.layer.Layer;
public class ParticleWater extends EntityParticle public class ParticleWater extends EntityParticle
{ {
private static Random rand = new Random();
private Vec3d velocity; private Vec3d velocity;
private double height = 0; private double height = 0;

View File

@ -9,6 +9,7 @@ import shootergame.entity.EntityBullet;
import shootergame.entity.EntityInventory; import shootergame.entity.EntityInventory;
import shootergame.entity.EntityItem; import shootergame.entity.EntityItem;
import shootergame.entity.EntityVertical; import shootergame.entity.EntityVertical;
import shootergame.init.Items;
import shootergame.init.Textures; import shootergame.init.Textures;
import shootergame.inventory.Inventory; import shootergame.inventory.Inventory;
import shootergame.util.gl.GlHelpers; import shootergame.util.gl.GlHelpers;
@ -70,8 +71,6 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
@Override @Override
public void tick(Chunk chunk, Layer layer) public void tick(Chunk chunk, Layer layer)
{ {
Cheats.god_mode = true;
// Handle player deaths // Handle player deaths
if(health <= 0) if(health <= 0)
{ {
@ -175,7 +174,7 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
if(dead || in_animation) return; if(dead || in_animation) return;
bullet_frequency += 1; bullet_frequency += 1;
bullet_frequency %= 10 - gun_level*2; bullet_frequency %= 10;
// Is there enough ammo and are the bullets at the right frequency // Is there enough ammo and are the bullets at the right frequency
if(bullet_frequency == 0 && ammo > 0) if(bullet_frequency == 0 && ammo > 0)
@ -184,7 +183,10 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
ammo -= 1; ammo -= 1;
// Summon bullets at this angle relative to the player // Summon bullets at this angle relative to the player
Main.world.getLayer().spawnEntity(new EntityBullet(pos.copy(), this, angle + this.angle, 20, 5)); int d = (int)(1 + gun_level / 4.0);
int b = (int)(1 + gun_level / 4.0);
Main.world.getLayer().spawnEntity(new EntityBullet(pos.copy(), this, angle + this.angle,
20*d*d, 5/b));
} }
} }
@ -206,7 +208,7 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
@Override @Override
public void removeHealth(double amount) { public void removeHealth(double amount) {
amount = amount * amount / (amount + defence_level*2); amount = amount / (defence_level / 2.5 + 1);
health -= amount; health -= amount;
} }
@ -252,4 +254,13 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
i.count -= 1; i.count -= 1;
} }
} }
@Override
public void push(double amount, double angle) {
}
@Override
public int bloodParticles() {
return 5;
}
} }

View File

@ -4,8 +4,10 @@ import shootergame.items.Item;
import shootergame.items.ItemAmmo; import shootergame.items.ItemAmmo;
import shootergame.items.ItemDefenceUpgrade; import shootergame.items.ItemDefenceUpgrade;
import shootergame.items.ItemEmpty; import shootergame.items.ItemEmpty;
import shootergame.items.ItemFlare;
import shootergame.items.ItemGunUpgrade; import shootergame.items.ItemGunUpgrade;
import shootergame.items.ItemHealthPotion; import shootergame.items.ItemHealthPotion;
import shootergame.items.ItemLantern;
import shootergame.items.ItemTnt; import shootergame.items.ItemTnt;
public class Items public class Items
@ -16,4 +18,6 @@ public class Items
public static final Item HEALTH_POTION = new ItemHealthPotion("health_potion"); public static final Item HEALTH_POTION = new ItemHealthPotion("health_potion");
public static final Item EMPTY = new ItemEmpty("empty"); public static final Item EMPTY = new ItemEmpty("empty");
public static final Item TNT = new ItemTnt("tnt"); public static final Item TNT = new ItemTnt("tnt");
public static final Item LANTERN = new ItemLantern("lantern");
public static final Item FLARE = new ItemFlare("flare");
} }

View File

@ -0,0 +1,40 @@
package shootergame.init;
import java.util.ArrayList;
import java.util.Random;
import shootergame.Main;
import shootergame.world.World;
import shootergame.world.layer.Layer;
import shootergame.world.layer.layergen.*;
public class Layers
{
private static final ArrayList<Layer> id_layers = new ArrayList<Layer>();
public static void init(long seed)
{
// Create all the layers
EARTH = new Layer(new Random(seed), new LayerGenEarth(), 0);
CAVES = new Layer(new Random(seed), new LayerGenCaves(), 1);
LAVA_CAVES = new Layer(new Random(seed), new LayerGenLavaCaves(), 2);
// Setup all the id-able layers
id_layers.add(EARTH);
id_layers.add(CAVES);
id_layers.add(LAVA_CAVES);
// Create the world and set the earth as the default layer
Main.world = new World();
Main.world.setLayer(EARTH);
}
public static Layer getLayer(int id) {
return id_layers.get(id);
}
public static Layer EARTH;
public static Layer CAVES;
public static Layer LAVA_CAVES;
}

View File

@ -38,6 +38,16 @@ public class Textures
public static final TextureReference TILE_WALL = texmap.getTextureReference(2, 3, 5, 6); public static final TextureReference TILE_WALL = texmap.getTextureReference(2, 3, 5, 6);
public static final TextureReference TILE_LADDER_UP = texmap.getTextureReference(16, 17, 0, 16); public static final TextureReference TILE_LADDER_UP = texmap.getTextureReference(16, 17, 0, 16);
public static final TextureReference TILE_CHEST = texmap.getTextureReference(2, 3, 4, 5); public static final TextureReference TILE_CHEST = texmap.getTextureReference(2, 3, 4, 5);
public static final TextureReference ENTITY_FLARE = texmap.getTextureReference(6, 7, 15, 16);
public static final TextureReference ENTITY_DUMMY = texmap.getTextureReference(7, 8, 15, 16);
public static final AnimationReference TILE_LANTERN = new AnimationReference(10,
texmap.getTextureReference(8, 9, 15, 16),
texmap.getTextureReference(9, 10, 15, 16),
texmap.getTextureReference(10, 11, 15, 16),
texmap.getTextureReference(11, 12, 15, 16),
texmap.getTextureReference(12, 13, 15, 16),
texmap.getTextureReference(13, 14, 15, 16));
public static final TextureReferenceRandom PARTICLE_SMOKE_RANDOM = new TextureReferenceRandom( public static final TextureReferenceRandom PARTICLE_SMOKE_RANDOM = new TextureReferenceRandom(
texmap.getTextureReference(14, 15, 13, 14), texmap.getTextureReference(15, 16, 13, 14), texmap.getTextureReference(14, 15, 13, 14), texmap.getTextureReference(15, 16, 13, 14),

View File

@ -7,6 +7,7 @@ import shootergame.tiles.TileFire;
import shootergame.tiles.TileGrass; import shootergame.tiles.TileGrass;
import shootergame.tiles.TileLadder; import shootergame.tiles.TileLadder;
import shootergame.tiles.TileLadderUp; import shootergame.tiles.TileLadderUp;
import shootergame.tiles.TileLantern;
import shootergame.tiles.TileLava; import shootergame.tiles.TileLava;
import shootergame.tiles.TileLavaFlow; import shootergame.tiles.TileLavaFlow;
import shootergame.tiles.TilePortalDown; import shootergame.tiles.TilePortalDown;
@ -37,5 +38,6 @@ public class Tiles
public static final Tile PORTAL_DOWN = new TilePortalDown("portal_down"); public static final Tile PORTAL_DOWN = new TilePortalDown("portal_down");
public static final Tile WALL = new TileWall("wall"); public static final Tile WALL = new TileWall("wall");
public static final Tile LADDER_UP = new TileLadderUp("ladder_up"); public static final Tile LADDER_UP = new TileLadderUp("ladder_up");
public static final Tile TILE_CHEST = new TileChest("chest"); public static final Tile CHEST = new TileChest("chest");
public static final Tile LANTERN = new TileLantern("lantern");
} }

View File

@ -62,8 +62,13 @@ public class Item
stack.count = 0; stack.count = 0;
return; return;
} }
}
// Loop over the inventory
for(int i=0;i<entity_i.getSlotCount();i++)
{
// Is this item stack empty // Is this item stack empty
ItemStack i_stack = entity_i.getItem(i);
if(i_stack.isEmpty()) if(i_stack.isEmpty())
{ {
// Send the entity stack to the inventory stack // Send the entity stack to the inventory stack

View File

@ -0,0 +1,25 @@
package shootergame.items;
import shootergame.entity.Entity;
import shootergame.entity.EntityFlare;
import shootergame.init.Textures;
import shootergame.util.math.ItemStack;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class ItemFlare extends Item
{
public ItemFlare(String id) {
super(id);
this.texture = Textures.ENTITY_FLARE;
}
@Override
public void onAction(ItemStack stack, Layer layer, Chunk chunk, Entity entity) {
super.onAction(stack, layer, chunk, entity);
layer.spawnEntity(new EntityFlare(entity.pos.copy(), entity.angle));
}
}

View File

@ -0,0 +1,31 @@
package shootergame.items;
import shootergame.entity.Entity;
import shootergame.init.Textures;
import shootergame.init.Tiles;
import shootergame.util.math.ItemStack;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.vec.Vec2i;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class ItemLantern extends Item
{
public ItemLantern(String id) {
super(id);
this.texture = Textures.TILE_LANTERN;
}
@Override
public void onAction(ItemStack stack, Layer layer, Chunk chunk, Entity entity)
{
Vec2i tpos = new Vec2i(MathHelpers.floor(entity.pos.x), MathHelpers.floor(entity.pos.y));
if(layer.getFrontTile(tpos).tile == Tiles.VOID) {
layer.setFrontTile(Tiles.LANTERN.getDefaultState(), tpos);
super.onAction(stack, layer, chunk, entity);
}
}
}

View File

@ -1,18 +0,0 @@
package shootergame.tiles;
import java.util.Random;
import shootergame.time.GameTimer;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.random.OpenSimplexNoise;
class LavaLightlevel
{
static OpenSimplexNoise noise = new OpenSimplexNoise(new Random().nextLong());
static double getLightLevel() {
double v = MathHelpers.map(noise.eval(GameTimer.getTime() / 512.0, 0), -1, 1, 0.6, 0.8);
//System.out.println("v = "+v);
return v;
}
}

View File

@ -0,0 +1,47 @@
package shootergame.tiles;
import java.util.Random;
import mainloop.task.IMainloopTask;
import shootergame.time.GameTimer;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.random.OpenSimplexNoise;
public class LightLevelNoise implements IMainloopTask
{
private static final Random rand = new Random();
private static final OpenSimplexNoise lava_noise_g = new OpenSimplexNoise(rand.nextLong());
private static final OpenSimplexNoise lantern_noise_g = new OpenSimplexNoise(rand.nextLong());
private static double lava_noise = 0;
private static double lantern_noise = 0;
static double getLightLevel(OpenSimplexNoise noise) {
return noise.eval(GameTimer.getTime() / 512.0, 0);
}
static double getLavaLightLevel() {
return lava_noise;
}
static double getLanternLightLevel() {
return lantern_noise;
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > 10;
}
@Override
public boolean MainLoopRepeat() {
return true;
}
@Override
public void MainLoopUpdate()
{
lava_noise = MathHelpers.map(getLightLevel(lava_noise_g), -1, 1, 0.6, 0.8);
lantern_noise = MathHelpers.map(getLightLevel(lantern_noise_g), -1, 1, 0.6, 1);
}
}

View File

@ -69,7 +69,11 @@ public class Tile implements ITransparentObject
return light_dissipation; return light_dissipation;
} }
public double getLightLevel(TileState state) { public double getLightLevel(TileState state, Vec2i pos) {
return 0; return 0;
} }
public void tickRandomly(Layer layer, Chunk chunk, TileState state, Vec2i pos) {
}
} }

View File

@ -48,6 +48,12 @@ public class TileChest extends TileVertical
// Tnt // Tnt
spawnItem(chunk, tpos, new ItemStack(Items.TNT, RandomHelpers.randrange(rand, 2), (short)10)); spawnItem(chunk, tpos, new ItemStack(Items.TNT, RandomHelpers.randrange(rand, 2), (short)10));
// Flare
spawnItem(chunk, tpos, new ItemStack(Items.FLARE, RandomHelpers.randrange(rand, 5), (byte)0));
// Lantern
spawnItem(chunk, tpos, new ItemStack(Items.LANTERN, RandomHelpers.randrange(rand, 5), (byte)0));
// Health potions // Health potions
spawnItem(chunk, tpos, new ItemStack(Items.HEALTH_POTION, RandomHelpers.randrange(rand, 4), (short)50)); spawnItem(chunk, tpos, new ItemStack(Items.HEALTH_POTION, RandomHelpers.randrange(rand, 4), (short)50));
@ -79,6 +85,12 @@ public class TileChest extends TileVertical
// Health potions // Health potions
spawnItem(chunk, tpos, new ItemStack(Items.HEALTH_POTION, RandomHelpers.randrange(rand, 4), (short)50)); spawnItem(chunk, tpos, new ItemStack(Items.HEALTH_POTION, RandomHelpers.randrange(rand, 4), (short)50));
// Flare
spawnItem(chunk, tpos, new ItemStack(Items.FLARE, RandomHelpers.randrange(rand, 5), (byte)0));
// Lantern
spawnItem(chunk, tpos, new ItemStack(Items.LANTERN, RandomHelpers.randrange(rand, 5), (byte)0));
// Gun upgrade // Gun upgrade
if(RandomHelpers.randrange(rand, 5) == 0) { if(RandomHelpers.randrange(rand, 5) == 0) {
spawnItem(chunk, tpos, new ItemStack(Items.GUN_UPGRADE, 1, (short)3)); spawnItem(chunk, tpos, new ItemStack(Items.GUN_UPGRADE, 1, (short)3));

View File

@ -3,6 +3,7 @@ package shootergame.tiles;
import shootergame.init.Textures; import shootergame.init.Textures;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
import shootergame.util.math.vec.Vec2d; import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec2i;
public class TileLadder extends TileVertical public class TileLadder extends TileVertical
{ {
@ -18,7 +19,7 @@ public class TileLadder extends TileVertical
} }
@Override @Override
public double getLightLevel(TileState state) { public double getLightLevel(TileState state, Vec2i pos) {
return 0.5; return 0.5;
} }

View File

@ -4,6 +4,7 @@ import mainloop.task.IMainloopTask;
import shootergame.Main; import shootergame.Main;
import shootergame.entity.Entity; import shootergame.entity.Entity;
import shootergame.entity.player.EntityPlayer; import shootergame.entity.player.EntityPlayer;
import shootergame.init.Layers;
import shootergame.init.Textures; import shootergame.init.Textures;
import shootergame.mainloop.MainloopEventHandler; import shootergame.mainloop.MainloopEventHandler;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
@ -59,7 +60,7 @@ public class TileLadderUp extends TileVertical
if(player.height >= 6 && movingPlayer == 0) if(player.height >= 6 && movingPlayer == 0)
{ {
movingPlayer = 1; movingPlayer = 1;
Main.world.setLayerID(state.meta); Main.world.setLayer(Layers.getLayer(state.meta));
player.height = -1; player.height = -1;
} }

View File

@ -0,0 +1,39 @@
package shootergame.tiles;
import shootergame.entity.Entity;
import shootergame.entity.EntityItem;
import shootergame.init.Items;
import shootergame.init.Textures;
import shootergame.util.math.ItemStack;
import shootergame.util.math.TileState;
import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec2i;
import shootergame.world.layer.Layer;
public class TileLantern extends TileVertical
{
public TileLantern(String id) {
super(id, Textures.TILE_LANTERN, new Vec2d(1, 1));
this.emitsLight = true;
this.opaqueTile = true;
}
@Override
public double getLightLevel(TileState state, Vec2i pos) {
return LightLevelNoise.getLanternLightLevel();
}
@Override
public void onActivated(Layer layer, Vec2i tpos, Entity entity, TileState state) {
super.onActivated(layer, tpos, entity, state);
layer.breakFrontTile(tpos);
layer.spawnEntity(new EntityItem(new Vec2d(tpos.x + 0.5, tpos.y + 0.5),
new ItemStack(Items.LANTERN, 1, (byte)0)));
}
}

View File

@ -1,13 +1,23 @@
package shootergame.tiles; package shootergame.tiles;
import java.util.Random;
import shootergame.display.Camera; import shootergame.display.Camera;
import shootergame.entity.Entity;
import shootergame.entity.particle.ParticleLava;
import shootergame.entity.particle.ParticleSmoke;
import shootergame.init.Textures; import shootergame.init.Textures;
import shootergame.util.gl.GlHelpers; import shootergame.util.gl.GlHelpers;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
import shootergame.util.math.random.RandomHelpers;
import shootergame.util.math.vec.Vec2d; import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec2i;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class TileLava extends TileFlat public class TileLava extends TileFlat
{ {
private Random rand = new Random();
public TileLava(String id) { public TileLava(String id) {
super(id, Textures.TILE_LAVA); super(id, Textures.TILE_LAVA);
@ -25,8 +35,26 @@ public class TileLava extends TileFlat
} }
@Override @Override
public double getLightLevel(TileState state) { public double getLightLevel(TileState state, Vec2i pos) {
return LavaLightlevel.getLightLevel(); return LightLevelNoise.getLavaLightLevel();
}
@Override
public void onWalkedOn(Chunk chunk, Layer layer, Vec2i pos, Entity entity, TileState state)
{
// Call super
super.onWalkedOn(chunk, layer, pos, entity, state);
// Create a lava particle
layer.spawnEntity(new ParticleLava(entity.pos.copy()));
}
@Override
public void tickRandomly(Layer layer, Chunk chunk, TileState state, Vec2i pos) {
super.tickRandomly(layer, chunk, state, pos);
chunk.spawnEntity(new ParticleLava(new Vec2d(
pos.x + rand.nextDouble(), pos.y + rand.nextDouble())));
} }
} }

View File

@ -1,13 +1,21 @@
package shootergame.tiles; package shootergame.tiles;
import java.util.Random;
import shootergame.display.Camera; import shootergame.display.Camera;
import shootergame.entity.particle.ParticleSmoke;
import shootergame.init.Textures; import shootergame.init.Textures;
import shootergame.util.gl.GlHelpers; import shootergame.util.gl.GlHelpers;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
import shootergame.util.math.random.RandomHelpers;
import shootergame.util.math.vec.Vec2d; import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec2i;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class TileLavaFlow extends TileFlat public class TileLavaFlow extends TileFlat
{ {
private Random rand = new Random();
public TileLavaFlow(String id) { public TileLavaFlow(String id) {
super(id, Textures.TILE_LAVA_FLOW); super(id, Textures.TILE_LAVA_FLOW);
@ -24,8 +32,18 @@ public class TileLavaFlow extends TileFlat
} }
@Override @Override
public double getLightLevel(TileState state) { public double getLightLevel(TileState state, Vec2i pos) {
return LavaLightlevel.getLightLevel(); return LightLevelNoise.getLavaLightLevel();
}
@Override
public void tickRandomly(Layer layer, Chunk chunk, TileState state, Vec2i pos) {
super.tickRandomly(layer, chunk, state, pos);
if(RandomHelpers.randrange(rand, 5) == 0) {
chunk.spawnEntity(new ParticleSmoke(new Vec2d(
pos.x + rand.nextDouble(), pos.y + rand.nextDouble())));
}
} }
} }

View File

@ -4,6 +4,7 @@ import mainloop.task.IMainloopTask;
import shootergame.Main; import shootergame.Main;
import shootergame.entity.Entity; import shootergame.entity.Entity;
import shootergame.entity.player.EntityPlayer; import shootergame.entity.player.EntityPlayer;
import shootergame.init.Layers;
import shootergame.init.Textures; import shootergame.init.Textures;
import shootergame.mainloop.MainloopEventHandler; import shootergame.mainloop.MainloopEventHandler;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
@ -56,7 +57,7 @@ public class TilePortalDown extends TileFlat
if(player.height < -1 && movingPlayer == 0) if(player.height < -1 && movingPlayer == 0)
{ {
movingPlayer = 1; movingPlayer = 1;
Main.world.setLayerID(state.meta); Main.world.setLayer(Layers.getLayer(state.meta));
player.height = 6; player.height = 6;
} }

View File

@ -8,9 +8,9 @@ public class Vec2i
public int x; public int x;
public int y; public int y;
public Vec2i(int d, int y) public Vec2i(int x, int y)
{ {
this.x = d; this.x = x;
this.y = y; this.y = y;
} }

View File

@ -1,36 +1,13 @@
package shootergame.world; package shootergame.world;
import java.util.ArrayList;
import java.util.Random;
import shootergame.display.Camera; import shootergame.display.Camera;
import shootergame.world.chunk.ChunkEventHandler; import shootergame.world.chunk.ChunkEventHandler;
import shootergame.world.layer.Layer; import shootergame.world.layer.Layer;
import shootergame.world.layer.layergen.LayerGen;
public class World public class World
{ {
private ArrayList<Layer> layers = new ArrayList<Layer>();
private int layer_id = 0;
private Layer layer; private Layer layer;
public World(Random rand, LayerGen ... layergen)
{
long seed = rand.nextLong();
// Loop over the layer generators
int id = 0;
for(LayerGen lg : layergen)
{
// Create new layers
layers.add(new Layer(new Random(seed), lg, id));
id += 1;
}
// Set the current layer
layer = layers.get(layer_id);
}
public void render(Camera camera) { public void render(Camera camera) {
layer.render(camera); layer.render(camera);
} }
@ -43,14 +20,9 @@ public class World
layer.spawnRandomEntities(); layer.spawnRandomEntities();
} }
public int getLayerID() { public void setLayer(Layer layer) {
return layer_id;
}
public void setLayerID(int id) {
layer_id = id;
layer = layers.get(layer_id);
ChunkEventHandler.loaded = false; ChunkEventHandler.loaded = false;
this.layer = layer;
} }
public Layer getLayer() { public Layer getLayer() {

View File

@ -11,6 +11,7 @@ import shootergame.init.Tiles;
import shootergame.tiles.Tile; import shootergame.tiles.Tile;
import shootergame.util.math.MathHelpers; import shootergame.util.math.MathHelpers;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
import shootergame.util.math.random.RandomHelpers;
import shootergame.util.math.range.Range2i; import shootergame.util.math.range.Range2i;
import shootergame.util.math.vec.Vec2d; import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec2i; import shootergame.util.math.vec.Vec2i;
@ -22,6 +23,7 @@ public class Chunk
public static final Chunk CHUNK_EMPTY = new ChunkEmpty(); public static final Chunk CHUNK_EMPTY = new ChunkEmpty();
public static final int CHUNK_INDEX = CHUNK_SIZE.mx * CHUNK_SIZE.my; public static final int CHUNK_INDEX = CHUNK_SIZE.mx * CHUNK_SIZE.my;
public static final int SIMULATION_DISTANCE = 5; public static final int SIMULATION_DISTANCE = 5;
public static final Random rand = new Random();
private Tile tiles_back[] = new Tile[CHUNK_INDEX]; private Tile tiles_back[] = new Tile[CHUNK_INDEX];
private Tile tiles_front[] = new Tile[CHUNK_INDEX]; private Tile tiles_front[] = new Tile[CHUNK_INDEX];
@ -283,4 +285,25 @@ public class Chunk
return nearby_entities; return nearby_entities;
} }
public void tickRandomly()
{
// Get a random tile
int id = RandomHelpers.randrange(rand, CHUNK_INDEX);
Vec2i pos = Vec2i.fromId(CHUNK_SIZE, id);
pos.x += c_pos.x * 16;
pos.y += c_pos.y * 16;
// Randomly select the front and back tiles
TileState ts;
if(rand.nextBoolean()) {
ts = getBackTile(id);
}
else {
ts = getFrontTile(id);
}
// Tick the tile
ts.tile.tickRandomly(layer, this, ts, pos);
}
} }

View File

@ -52,9 +52,10 @@ public class Layer
public void tickEntities() public void tickEntities()
{ {
// Tick every entity in every loaded chunk // Tick every entity and every tile in every loaded chunk
for(Map2DElement<Chunk> e : chunks) { for(Map2DElement<Chunk> e : chunks) {
e.o.tickEntities(); e.o.tickEntities();
e.o.tickRandomly();
} }
// Move every entitiy in every loaded chunk // Move every entitiy in every loaded chunk

View File

@ -5,7 +5,6 @@ import java.util.Random;
import shootergame.Main; import shootergame.Main;
import shootergame.entity.Entity; import shootergame.entity.Entity;
import shootergame.entity.EntityZombie; import shootergame.entity.EntityZombie;
import shootergame.entity.EntityZombieArmored;
import shootergame.init.Tiles; import shootergame.init.Tiles;
import shootergame.util.math.MathHelpers; import shootergame.util.math.MathHelpers;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
@ -51,7 +50,7 @@ public class LayerGenCaves extends LayerGen
double noise_n = 100 - MathHelpers.positive( noisegen_n.eval(cx/20.0, cy/20.0) * 100 ); double noise_n = 100 - MathHelpers.positive( noisegen_n.eval(cx/20.0, cy/20.0) * 100 );
Vec2i pos = new Vec2i(x, y); Vec2i pos = new Vec2i(x, y);
if(noise_n > 90) { if(noise_n > 80) {
chunk.setBackTile(Tiles.STONE.getDefaultState(), pos); chunk.setBackTile(Tiles.STONE.getDefaultState(), pos);
} }
@ -76,7 +75,7 @@ public class LayerGenCaves extends LayerGen
// Only place a chest here if the tile is clear // Only place a chest here if the tile is clear
if(chunk.getBackTile(chest_pos).tile == getTileDestroyed().tile) { if(chunk.getBackTile(chest_pos).tile == getTileDestroyed().tile) {
chunk.setFrontTile(new TileState(Tiles.TILE_CHEST, 1), chest_pos); chunk.setFrontTile(new TileState(Tiles.CHEST, 1), chest_pos);
} }
} }

View File

@ -4,6 +4,7 @@ import java.util.Random;
import shootergame.Main; import shootergame.Main;
import shootergame.entity.Entity; import shootergame.entity.Entity;
import shootergame.entity.EntityDummy;
import shootergame.entity.EntityZombie; import shootergame.entity.EntityZombie;
import shootergame.init.Tiles; import shootergame.init.Tiles;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;

View File

@ -4,7 +4,6 @@ import java.util.Random;
import shootergame.Main; import shootergame.Main;
import shootergame.entity.Entity; import shootergame.entity.Entity;
import shootergame.entity.EntityZombie;
import shootergame.entity.EntityZombieArmored; import shootergame.entity.EntityZombieArmored;
import shootergame.init.Tiles; import shootergame.init.Tiles;
import shootergame.util.math.TileState; import shootergame.util.math.TileState;
@ -88,10 +87,14 @@ public class LayerGenLavaCaves extends LayerGen
RandomHelpers.randrange(rand, Chunk.CHUNK_SIZE.my)); RandomHelpers.randrange(rand, Chunk.CHUNK_SIZE.my));
// Only place a chest here if the tile is clear // Only place a chest here if the tile is clear
if(chunk.getBackTile(chest_pos).tile == getTileDestroyed().tile) { if(
chunk.setFrontTile(new TileState(Tiles.TILE_CHEST, 2), chest_pos); chunk.getBackTile(chest_pos).tile == getTileDestroyed().tile &&
chunk.getFrontTile(chest_pos).tile == Tiles.VOID) {
chunk.setFrontTile(new TileState(Tiles.CHEST, 2), chest_pos);
} }
if(chunk.getBackTile(lava_flow_pos).tile == getTileDestroyed().tile) { if(
chunk.getBackTile(lava_flow_pos).tile == getTileDestroyed().tile &&
chunk.getFrontTile(lava_flow_pos).tile == Tiles.VOID) {
chunk.setFrontTile(Tiles.LAVA_FLOW.getDefaultState(), lava_flow_pos); chunk.setFrontTile(Tiles.LAVA_FLOW.getDefaultState(), lava_flow_pos);
} }
} }
@ -99,7 +102,7 @@ public class LayerGenLavaCaves extends LayerGen
@Override @Override
public void spawnEntities(Layer layer, Random rand) public void spawnEntities(Layer layer, Random rand)
{ {
if(rand.nextDouble() > 0.95) if(rand.nextDouble() > 0.98)
{ {
Entity zombie = new EntityZombieArmored(); Entity zombie = new EntityZombieArmored();
zombie.pos = new Vec2d( zombie.pos = new Vec2d(