Major refactoring of building, sound, inventory
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Translator;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
/**Interface for units that build thing.*/
|
||||
public interface BlockBuilder {
|
||||
//temporary static final values
|
||||
Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()};
|
||||
float placeDistance = 80f;
|
||||
|
||||
/**Returns the queue for storing build requests.*/
|
||||
Queue<BuildRequest> getPlaceQueue();
|
||||
|
||||
/**Clears the placement queue.*/
|
||||
default void clearBuilding(){
|
||||
getPlaceQueue().clear();
|
||||
}
|
||||
|
||||
/**Add another build requests to the tail of the queue.*/
|
||||
default void addBuildRequest(BuildRequest place){
|
||||
getPlaceQueue().addLast(place);
|
||||
}
|
||||
|
||||
/**Return the build requests currently active, or the one at the top of the queue.
|
||||
* May return null.*/
|
||||
default BuildRequest getCurrentRequest(){
|
||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
|
||||
/**Update building mechanism for this unit.*/
|
||||
default void updateBuilding(Unit unit){
|
||||
BuildRequest current = getCurrentRequest();
|
||||
|
||||
if(current == null) return; //nothing to do here
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(unit.distanceTo(tile) > placeDistance) { //out of range, skip it.
|
||||
getPlaceQueue().removeFirst();
|
||||
}else if(current.remove){
|
||||
if(Build.validBreak(unit.team, current.x, current.y)){ //if it's valid, break it
|
||||
current.removeProgress += 1f / tile.getBreakTime();
|
||||
|
||||
if(current.removeProgress >= 1f){
|
||||
Build.breakBlock(unit.team, current.x, current.y, true, true);
|
||||
}
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
}
|
||||
}else{
|
||||
if (!(tile.block() instanceof BuildBlock)) { //check if haven't started placing
|
||||
if(Build.validPlace(unit.team, current.x, current.y, current.recipe.result, current.rotation)){
|
||||
//if it's valid, place it
|
||||
Build.placeBlock(unit.team, current.x, current.y, current.recipe, current.rotation);
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
}
|
||||
}else{
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
entity.progress += 1f / entity.recipe.cost;
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Draw placement effects for an entity.*/
|
||||
default void drawBuilding(Unit unit){
|
||||
Tile tile = world.tile(getCurrentRequest().x, getCurrentRequest().y);
|
||||
|
||||
Draw.color(unit.distanceTo(tile) > placeDistance ? "placeInvalid" : "accent");
|
||||
float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f);
|
||||
float px = unit.x + Angles.trnsx(unit.rotation, focusLen);
|
||||
float py = unit.y + Angles.trnsy(unit.rotation, focusLen);
|
||||
|
||||
float sz = Vars.tilesize*tile.block().size/2f;
|
||||
float ang = unit.angleTo(tile);
|
||||
|
||||
tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz);
|
||||
tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz);
|
||||
tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz);
|
||||
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
|
||||
|
||||
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(unit.x, unit.y, a.x, a.y), ang),
|
||||
Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang)));
|
||||
|
||||
float x1 = tmptr[0].x, y1 = tmptr[0].y,
|
||||
x3 = tmptr[1].x, y3 = tmptr[1].y;
|
||||
Translator close = Geometry.findClosest(unit.x, unit.y, tmptr);
|
||||
float x2 = close.x, y2 = close.y;
|
||||
|
||||
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
|
||||
|
||||
Fill.tri(px, py, x2, y2, x1, y1);
|
||||
Fill.tri(px, py, x2, y2, x3, y3);
|
||||
|
||||
Draw.alpha(1f);
|
||||
|
||||
Lines.line(px, py, x1, y1);
|
||||
Lines.line(px, py, x3, y3);
|
||||
|
||||
Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f));
|
||||
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
/**Class for storing build requests. Can be either a place or remove request.*/
|
||||
class BuildRequest {
|
||||
public final int x, y, rotation;
|
||||
public final Recipe recipe;
|
||||
public final boolean remove;
|
||||
|
||||
float removeProgress;
|
||||
|
||||
/**This creates a build request.*/
|
||||
public BuildRequest(int x, int y, int rotation, Recipe recipe) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.recipe = recipe;
|
||||
this.remove = false;
|
||||
}
|
||||
|
||||
/**This creates a remove request.*/
|
||||
public BuildRequest(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = -1;
|
||||
this.recipe = null;
|
||||
this.remove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
|
||||
public interface BlockPlacer {
|
||||
void addPlaceBlock(PlaceRequest place);
|
||||
Team getTeam();
|
||||
|
||||
class PlaceRequest{
|
||||
public final int x, y, rotation;
|
||||
public final Recipe recipe;
|
||||
|
||||
public PlaceRequest(int x, int y, int rotation, Recipe recipe) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.recipe = recipe;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ import io.anuke.ucore.function.Callable;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
/**This class should not be used anymore, as the animation does not fit the style well.*/
|
||||
@Deprecated
|
||||
public class ItemAnimationEffect extends TimedEntity {
|
||||
private static final float size = 5f;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.Mechs;
|
||||
import io.anuke.mindustry.content.Weapons;
|
||||
import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
@@ -14,18 +15,11 @@ import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.resource.*;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
|
||||
import io.anuke.mindustry.world.blocks.types.Floor;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Inputs;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.core.*;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.util.*;
|
||||
|
||||
@@ -33,17 +27,13 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Player extends Unit implements BlockPlacer{
|
||||
static final float speed = 1.1f;
|
||||
static final float dashSpeed = 1.8f;
|
||||
public static final float placeDistance = 80f;
|
||||
|
||||
static final int timerRegen = 3;
|
||||
static final Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()};
|
||||
public class Player extends Unit implements BlockBuilder {
|
||||
private static final float speed = 1.1f;
|
||||
private static final float dashSpeed = 1.8f;
|
||||
private static final Vector2 movement = new Vector2();
|
||||
|
||||
public String name = "name";
|
||||
public String uuid;
|
||||
@@ -61,12 +51,10 @@ public class Player extends Unit implements BlockPlacer{
|
||||
public int playerIndex = 0;
|
||||
public boolean isLocal = false;
|
||||
public Timer timer = new Timer(4);
|
||||
public float walktime;
|
||||
public float respawntime;
|
||||
|
||||
private Queue<PlaceRequest> placeQueue = new Queue<>();
|
||||
private Tile currentPlace;
|
||||
private Vector2 movement = new Vector2();
|
||||
private float walktime;
|
||||
private float respawntime;
|
||||
private Queue<BuildRequest> placeQueue = new Queue<>();
|
||||
|
||||
public Player(){
|
||||
hitbox.setSize(5);
|
||||
@@ -110,11 +98,6 @@ public class Player extends Unit implements BlockPlacer{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlaceBlock(PlaceRequest req){
|
||||
placeQueue.addFirst(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
return !isDead() && super.collides(other) && !mech.flying;
|
||||
@@ -227,45 +210,49 @@ public class Player extends Unit implements BlockPlacer{
|
||||
|
||||
@Override
|
||||
public void drawOver(){
|
||||
if(!isShooting() && currentPlace != null) {
|
||||
Draw.color(distanceTo(currentPlace) > placeDistance ? "placeInvalid" : "accent");
|
||||
float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f);
|
||||
float px = x + Angles.trnsx(rotation, focusLen);
|
||||
float py = y + Angles.trnsy(rotation, focusLen);
|
||||
|
||||
Tile tile = currentPlace;
|
||||
|
||||
float sz = Vars.tilesize*tile.block().size/2f;
|
||||
float ang = angleTo(tile);
|
||||
|
||||
tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz);
|
||||
tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz);
|
||||
tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz);
|
||||
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
|
||||
|
||||
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(x, y, a.x, a.y), ang),
|
||||
Angles.angleDist(Angles.angle(x, y, b.x, b.y), ang)));
|
||||
|
||||
float x1 = tmptr[0].x, y1 = tmptr[0].y,
|
||||
x3 = tmptr[1].x, y3 = tmptr[1].y;
|
||||
Translator close = Geometry.findClosest(x, y, tmptr);
|
||||
float x2 = close.x, y2 = close.y;
|
||||
|
||||
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
|
||||
|
||||
Fill.tri(px, py, x2, y2, x1, y1);
|
||||
Fill.tri(px, py, x2, y2, x3, y3);
|
||||
|
||||
Draw.alpha(1f);
|
||||
|
||||
Lines.line(px, py, x1, y1);
|
||||
Lines.line(px, py, x3, y3);
|
||||
|
||||
Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f));
|
||||
|
||||
Draw.color();
|
||||
if(!isShooting() && getCurrentRequest() != null) {
|
||||
drawBuilding(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawName(){
|
||||
GlyphLayout layout = Pools.obtain(GlyphLayout.class);
|
||||
|
||||
Draw.tscl(0.25f/2);
|
||||
layout.setText(Core.font, name);
|
||||
Draw.color(0f, 0f, 0f, 0.3f);
|
||||
Draw.rect("blank", getDrawPosition().x, getDrawPosition().y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
|
||||
Draw.color();
|
||||
Draw.tcolor(color);
|
||||
Draw.text(name, getDrawPosition().x, getDrawPosition().y + 8);
|
||||
|
||||
if(isAdmin){
|
||||
Draw.color(color);
|
||||
float s = 3f;
|
||||
Draw.rect("icon-admin-small", getDrawPosition().x + layout.width/2f + 2 + 1, getDrawPosition().y + 7f, s, s);
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
Pools.free(layout);
|
||||
Draw.tscl(fontscale);
|
||||
}
|
||||
|
||||
public void drawBuildRequests(){
|
||||
for (BuildRequest request : getPlaceQueue()) {
|
||||
if(request.remove){
|
||||
Draw.color("placeInvalid");
|
||||
Tile tile = world.tile(request.x, request.y);
|
||||
|
||||
Lines.poly(tile.drawx(), tile.drawy(),
|
||||
4, tile.block().size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f));
|
||||
}else{
|
||||
Draw.color("accent");
|
||||
Lines.poly(request.x * tilesize + request.recipe.result.getPlaceOffset().x,
|
||||
request.y * tilesize + request.recipe.result.getPlaceOffset().y,
|
||||
4, request.recipe.result.size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
@@ -300,6 +287,7 @@ public class Player extends Unit implements BlockPlacer{
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
}
|
||||
|
||||
/**Resets all values of the player.*/
|
||||
public void reset(){
|
||||
weapon = Weapons.blaster;
|
||||
team = Team.blue;
|
||||
@@ -316,12 +304,11 @@ public class Player extends Unit implements BlockPlacer{
|
||||
return control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo();
|
||||
}
|
||||
|
||||
public Queue<PlaceRequest> getPlaceQueue(){
|
||||
public Queue<BuildRequest> getPlaceQueue(){
|
||||
return placeQueue;
|
||||
}
|
||||
|
||||
protected void updateMech(){
|
||||
|
||||
Tile tile = world.tileWorld(x, y);
|
||||
|
||||
//if player is in solid block
|
||||
@@ -330,29 +317,7 @@ public class Player extends Unit implements BlockPlacer{
|
||||
}
|
||||
|
||||
if(!isShooting()) {
|
||||
//update placing queue
|
||||
|
||||
if(currentPlace != null) {
|
||||
Tile check = currentPlace;
|
||||
|
||||
if (!(check.block() instanceof BuildBlock)) {
|
||||
currentPlace = null;
|
||||
}else if(distanceTo(check) <= placeDistance){
|
||||
BuildEntity entity = check.entity();
|
||||
|
||||
entity.progress += 1f / entity.recipe.cost;
|
||||
rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f);
|
||||
}
|
||||
|
||||
}else if(placeQueue.size > 0){
|
||||
PlaceRequest check = placeQueue.last();
|
||||
if(distanceTo(world.tile(check.x, check.y)) <= placeDistance &&
|
||||
Placement.validPlace(team, check.x, check.y, check.recipe.result, check.rotation)){
|
||||
placeQueue.removeLast();
|
||||
Placement.placeBlock(team, check.x, check.y, check.recipe, check.rotation, true, true);
|
||||
currentPlace = world.tile(check.x, check.y);
|
||||
}
|
||||
}
|
||||
updateBuilding(this);
|
||||
}
|
||||
|
||||
if(ui.chatfrag.chatOpen()) return;
|
||||
@@ -365,11 +330,6 @@ public class Player extends Unit implements BlockPlacer{
|
||||
|
||||
speed *= ((1f-carrySlowdown) + (inventory.hasItem() ? (float)inventory.getItem().amount/inventory.capacity(): 1f) * carrySlowdown);
|
||||
|
||||
if(health < maxhealth && timer.get(timerRegen, 20))
|
||||
health ++;
|
||||
|
||||
health = Mathf.clamp(health, -1, maxhealth);
|
||||
|
||||
movement.set(0, 0);
|
||||
|
||||
String section = "player_" + (playerIndex + 1);
|
||||
@@ -524,18 +484,4 @@ public class Player extends Unit implements BlockPlacer{
|
||||
|
||||
interpolator.read(this.x, this.y, x, y, rot, baseRot, time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interpolate() {
|
||||
super.interpolate();
|
||||
|
||||
Interpolator i = interpolator;
|
||||
|
||||
float tx = x + Angles.trnsx(rotation + 180f, 4f);
|
||||
float ty = y + Angles.trnsy(rotation + 180f, 4f);
|
||||
}
|
||||
|
||||
public Color getColor(){
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ package io.anuke.mindustry.entities;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
/**Class for predicting shoot angles based on velocities of targets.*/
|
||||
public class Predict {
|
||||
private static Vector2 vec = new Vector2();
|
||||
private static Vector2 vresult = new Vector2();
|
||||
|
||||
/**Returns resulting predicted vector.
|
||||
* Don't call from multiple threads, ever.*/
|
||||
* Don't call from multiple threads.*/
|
||||
public static Vector2 intercept(float srcx, float srcy, float dstx, float dsty, float dstvx, float dstvy, float v) {
|
||||
float tx = dstx - srcx,
|
||||
ty = dsty - srcy,
|
||||
@@ -37,7 +38,6 @@ public class Predict {
|
||||
return sol;
|
||||
}
|
||||
|
||||
|
||||
private static Vector2 quad(float a, float b, float c) {
|
||||
Vector2 sol = null;
|
||||
if (Math.abs(a) < 1e-6) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.anuke.mindustry.entities;
|
||||
import io.anuke.mindustry.content.StatusEffects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
|
||||
/**Class for controlling status effects on an entity.*/
|
||||
public class StatusController {
|
||||
private static final TransitionResult globalResult = new TransitionResult();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user