mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-01-20 17:28:14 +07:00
Implemented shield hit effects and bullet absorption and powered rturret
This commit is contained in:
parent
c0d28eca65
commit
63d8aed9a5
@ -79,8 +79,7 @@ project(":core") {
|
|||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.github.Anuken:ucore:d43f3b48ec'
|
// compile 'com.github.Anuken:ucore:61c43bf'
|
||||||
//compile fileTree(dir: '../core/lib', include: '*.jar')
|
|
||||||
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
|
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
|
||||||
compile "com.badlogicgames.gdx:gdx-ai:1.8.1"
|
compile "com.badlogicgames.gdx:gdx-ai:1.8.1"
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ precision mediump float;
|
|||||||
precision mediump int;
|
precision mediump int;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAX_HITS 64
|
||||||
|
#define HIT_RADIUS 12.0
|
||||||
|
|
||||||
uniform sampler2D u_texture;
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
uniform vec4 u_color;
|
uniform vec4 u_color;
|
||||||
@ -10,6 +13,8 @@ uniform vec2 u_texsize;
|
|||||||
uniform float u_time;
|
uniform float u_time;
|
||||||
uniform float u_scaling;
|
uniform float u_scaling;
|
||||||
uniform vec2 u_offset;
|
uniform vec2 u_offset;
|
||||||
|
uniform int u_hitamount;
|
||||||
|
uniform vec3 u_hits[MAX_HITS];
|
||||||
|
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
varying vec2 v_texCoord;
|
varying vec2 v_texCoord;
|
||||||
@ -49,8 +54,19 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
color.a = 0.18;
|
color.a = 0.18;
|
||||||
|
|
||||||
|
for(int i = 0; i < u_hitamount; i ++){
|
||||||
|
vec3 hit = u_hits[i];
|
||||||
|
float rad = hit.z * HIT_RADIUS;
|
||||||
|
float fract = 1.0 - hit.z;
|
||||||
|
|
||||||
|
if(abs(distance(vec2(hit.x, hit.y), coords - u_texsize/2.0) - rad) < 1.0){
|
||||||
|
color = mix(color, u_color* vec4(si, si, si, 1.0), (1.0 * fract));
|
||||||
|
color.a = 0.18 + 0.82 *fract;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class Vars{
|
|||||||
//whether to draw chunk borders
|
//whether to draw chunk borders
|
||||||
public static boolean debugChunks = false;
|
public static boolean debugChunks = false;
|
||||||
//whether turrets have infinite ammo (only with debug)
|
//whether turrets have infinite ammo (only with debug)
|
||||||
public static boolean infiniteAmmo = true;
|
public static boolean infiniteAmmo = false;
|
||||||
//whether to show paths of enemies
|
//whether to show paths of enemies
|
||||||
public static boolean showPaths = true;
|
public static boolean showPaths = true;
|
||||||
//number of save slots-- increasing may lead to layout issues
|
//number of save slots-- increasing may lead to layout issues
|
||||||
|
@ -59,9 +59,12 @@ public class Control extends Module{
|
|||||||
float respawntime;
|
float respawntime;
|
||||||
|
|
||||||
public Control(){
|
public Control(){
|
||||||
if(Mindustry.args.contains("-debug", false)){
|
if(Mindustry.args.contains("-debug", false))
|
||||||
Vars.debug = true;
|
Vars.debug = true;
|
||||||
}
|
if(Mindustry.args.contains("-profile", false))
|
||||||
|
Vars.profile = true;
|
||||||
|
if(Mindustry.args.contains("-debugGL", false))
|
||||||
|
Vars.debugGL = true;
|
||||||
|
|
||||||
UCore.log("Total blocks loaded: " + Block.getAllBlocks().size);
|
UCore.log("Total blocks loaded: " + Block.getAllBlocks().size);
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import com.badlogic.gdx.graphics.Texture;
|
|||||||
import com.badlogic.gdx.graphics.profiling.GLProfiler;
|
import com.badlogic.gdx.graphics.profiling.GLProfiler;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.utils.FloatArray;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
@ -39,6 +40,8 @@ public class Renderer extends RendererModule{
|
|||||||
int targetscale = baseCameraScale;
|
int targetscale = baseCameraScale;
|
||||||
int chunksize = 32;
|
int chunksize = 32;
|
||||||
Cache[][] floorCache;
|
Cache[][] floorCache;
|
||||||
|
FloatArray shieldHits = new FloatArray();
|
||||||
|
float shieldHitDuration = 18f;
|
||||||
|
|
||||||
public Renderer() {
|
public Renderer() {
|
||||||
Core.cameraScale = baseCameraScale;
|
Core.cameraScale = baseCameraScale;
|
||||||
@ -127,6 +130,10 @@ public class Renderer extends RendererModule{
|
|||||||
drawDefault();
|
drawDefault();
|
||||||
|
|
||||||
Profiler.end("draw");
|
Profiler.end("draw");
|
||||||
|
if(Profiler.updating())
|
||||||
|
Profiler.getTimes().put("draw", Profiler.getTimes().get("draw")
|
||||||
|
- Profiler.getTimes().get("blockDraw")
|
||||||
|
- Profiler.getTimes().get("entityDraw"));
|
||||||
|
|
||||||
if(Vars.debug && Vars.debugGL && Timers.get("profile", 60)){
|
if(Vars.debug && Vars.debugGL && Timers.get("profile", 60)){
|
||||||
UCore.log("shaders: " + GLProfiler.shaderSwitches, "calls: " + GLProfiler.drawCalls, "bindings: " + GLProfiler.textureBindings, "vertices: " + GLProfiler.vertexCount.average);
|
UCore.log("shaders: " + GLProfiler.shaderSwitches, "calls: " + GLProfiler.drawCalls, "bindings: " + GLProfiler.textureBindings, "vertices: " + GLProfiler.vertexCount.average);
|
||||||
@ -195,11 +202,26 @@ public class Renderer extends RendererModule{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void drawShield(){
|
void drawShield(){
|
||||||
|
for(int i = 0; i < shieldHits.size/3; i ++){
|
||||||
|
//float x = hits.get(i*3+0);
|
||||||
|
//float y = hits.get(i*3+1);
|
||||||
|
float time = shieldHits.get(i*3+2);
|
||||||
|
|
||||||
|
time += Timers.delta() / shieldHitDuration;
|
||||||
|
shieldHits.set(i*3 + 2, time);
|
||||||
|
|
||||||
|
if(time >= 1f){
|
||||||
|
shieldHits.removeRange(i*3, i*3 + 2);
|
||||||
|
i --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Texture texture = Graphics.getSurface("shield").texture();
|
Texture texture = Graphics.getSurface("shield").texture();
|
||||||
Shaders.shield.color.set(Color.SKY);
|
Shaders.shield.color.set(Color.SKY);
|
||||||
|
|
||||||
Tmp.tr2.setRegion(texture);
|
Tmp.tr2.setRegion(texture);
|
||||||
Shaders.shield.region = Tmp.tr2;
|
Shaders.shield.region = Tmp.tr2;
|
||||||
|
Shaders.shield.hits = shieldHits;
|
||||||
|
|
||||||
Graphics.end();
|
Graphics.end();
|
||||||
Graphics.shader(Shaders.shield);
|
Graphics.shader(Shaders.shield);
|
||||||
@ -211,6 +233,10 @@ public class Renderer extends RendererModule{
|
|||||||
Graphics.end();
|
Graphics.end();
|
||||||
Graphics.beginCam();
|
Graphics.beginCam();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addShieldHit(float x, float y){
|
||||||
|
shieldHits.addAll(x, y, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
void renderTiles(){
|
void renderTiles(){
|
||||||
int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize;
|
int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.anuke.mindustry.entities.effect;
|
package io.anuke.mindustry.entities.effect;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.utils.FloatArray;
|
||||||
|
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
@ -28,7 +29,9 @@ public class Shaders{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Shield extends Shader{
|
public static class Shield extends Shader{
|
||||||
|
public static final int MAX_HITS = 3*64;
|
||||||
public Color color = new Color();
|
public Color color = new Color();
|
||||||
|
public FloatArray hits;
|
||||||
|
|
||||||
public Shield(){
|
public Shield(){
|
||||||
super("shield", "default");
|
super("shield", "default");
|
||||||
@ -38,6 +41,8 @@ public class Shaders{
|
|||||||
public void apply(){
|
public void apply(){
|
||||||
float scale = Settings.getBool("pixelate") ? 1 : Core.cameraScale / Core.camera.zoom;
|
float scale = Settings.getBool("pixelate") ? 1 : Core.cameraScale / Core.camera.zoom;
|
||||||
float scaling = Core.cameraScale / 4f / Core.camera.zoom;
|
float scaling = Core.cameraScale / 4f / Core.camera.zoom;
|
||||||
|
shader.setUniform3fv("u_hits[0]", hits.items, 0, Math.min(hits.size, MAX_HITS));
|
||||||
|
shader.setUniformi("u_hitamount", Math.min(hits.size, MAX_HITS)/3);
|
||||||
shader.setUniformf("u_color", color);
|
shader.setUniformf("u_color", color);
|
||||||
shader.setUniformf("u_time", Timers.time());
|
shader.setUniformf("u_time", Timers.time());
|
||||||
shader.setUniformf("u_scaling", scaling);
|
shader.setUniformf("u_scaling", scaling);
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package io.anuke.mindustry.entities.effect;
|
package io.anuke.mindustry.entities.effect;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.math.Interpolation;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.Bullet;
|
||||||
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock;
|
import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock;
|
||||||
import io.anuke.ucore.core.Draw;
|
import io.anuke.ucore.core.Draw;
|
||||||
@ -14,6 +17,8 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
|
|
||||||
public class Shield extends Entity{
|
public class Shield extends Entity{
|
||||||
public boolean active;
|
public boolean active;
|
||||||
|
public boolean hitPlayers = true;
|
||||||
|
|
||||||
private float uptime = 0f;
|
private float uptime = 0f;
|
||||||
private final Tile tile;
|
private final Tile tile;
|
||||||
//TODO
|
//TODO
|
||||||
@ -30,11 +35,14 @@ public class Shield extends Entity{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
|
float alpha = 0.1f;
|
||||||
|
Interpolation interp = Interpolation.fade;
|
||||||
|
|
||||||
if(active){
|
if(active){
|
||||||
uptime += Timers.delta() / 90f;
|
uptime = interp.apply(uptime, 1f, alpha * Timers.delta());
|
||||||
}else{
|
}else{
|
||||||
uptime -= Timers.delta() / 60f;
|
uptime = interp.apply(uptime, 0f, alpha * Timers.delta());
|
||||||
if(uptime < 0)
|
if(uptime <= 0.05f)
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
uptime = Mathf.clamp(uptime);
|
uptime = Mathf.clamp(uptime);
|
||||||
@ -46,14 +54,14 @@ public class Shield extends Entity{
|
|||||||
|
|
||||||
ShieldBlock block = (ShieldBlock)tile.block();
|
ShieldBlock block = (ShieldBlock)tile.block();
|
||||||
|
|
||||||
Entities.getNearby(x, y, block.shieldRadius * 2*uptime + 10, entity->{
|
Entities.getNearby(Entities.getGroup(Bullet.class), x, y, block.shieldRadius * 2*uptime + 10, entity->{
|
||||||
if(entity instanceof BulletEntity){
|
BulletEntity bullet = (BulletEntity)entity;
|
||||||
BulletEntity bullet = (BulletEntity)entity;
|
if((bullet.owner instanceof Enemy || hitPlayers)){
|
||||||
|
|
||||||
float dst = entity.distanceTo(this);
|
float dst = entity.distanceTo(this);
|
||||||
|
|
||||||
if(Math.abs(dst - block.shieldRadius) < 2){
|
if(dst < drawRadius()/2f){
|
||||||
bullet.velocity.scl(-1);
|
((ShieldBlock)tile.block()).handleBullet(tile, bullet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -65,10 +73,7 @@ public class Shield extends Entity{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShieldBlock block = (ShieldBlock)tile.block();
|
float rad = drawRadius();
|
||||||
|
|
||||||
float rad = block.shieldRadius*2 + Mathf.sin(Timers.time(), 25f, 2f);
|
|
||||||
rad *= uptime;
|
|
||||||
|
|
||||||
Graphics.surface("shield", false);
|
Graphics.surface("shield", false);
|
||||||
Draw.color(Color.ROYAL);
|
Draw.color(Color.ROYAL);
|
||||||
@ -78,6 +83,11 @@ public class Shield extends Entity{
|
|||||||
Graphics.surface();
|
Graphics.surface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float drawRadius(){
|
||||||
|
ShieldBlock block = (ShieldBlock)tile.block();
|
||||||
|
return (block.shieldRadius*2 + Mathf.sin(Timers.time(), 25f, 2f)) * uptime;
|
||||||
|
}
|
||||||
|
|
||||||
public void removeDelay(){
|
public void removeDelay(){
|
||||||
active = false;
|
active = false;
|
||||||
}
|
}
|
||||||
|
@ -163,6 +163,7 @@ public class HudFragment implements Fragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateItems(){
|
public void updateItems(){
|
||||||
|
|
||||||
itemtable.clear();
|
itemtable.clear();
|
||||||
itemtable.left();
|
itemtable.left();
|
||||||
|
|
||||||
@ -183,6 +184,7 @@ public class HudFragment implements Fragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fadeRespawn(boolean in){
|
public void fadeRespawn(boolean in){
|
||||||
|
|
||||||
respawntable.addAction(Actions.color(in ? new Color(0, 0, 0, 0.3f) : Color.CLEAR, 0.3f));
|
respawntable.addAction(Actions.color(in ? new Color(0, 0, 0, 0.3f) : Color.CLEAR, 0.3f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,12 @@ public class PowerTurret extends Turret implements PowerAcceptor{
|
|||||||
Draw.dashcircle(tile.worldx() + offset.x, tile.worldy() + offset.y, range);
|
Draw.dashcircle(tile.worldx() + offset.x, tile.worldy() + offset.y, range);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
|
drawPowerBar(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPowerBar(Tile tile){
|
||||||
|
Vector2 offset = getPlaceOffset();
|
||||||
|
|
||||||
PowerTurretEntity entity = tile.entity();
|
PowerTurretEntity entity = tile.entity();
|
||||||
|
|
||||||
float fract = (float)entity.power / powerCapacity;
|
float fract = (float)entity.power / powerCapacity;
|
||||||
|
@ -36,7 +36,9 @@ public class RepairTurret extends PowerTurret{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
TurretEntity entity = tile.entity();
|
PowerTurretEntity entity = tile.entity();
|
||||||
|
|
||||||
|
if(entity.power < powerUsed) return;
|
||||||
|
|
||||||
if(Timers.get(entity, "blocktarget", targetInterval)){
|
if(Timers.get(entity, "blocktarget", targetInterval)){
|
||||||
entity.blockTarget = Vars.world.findTileTarget(tile.worldx(), tile.worldy(), tile, range, true);
|
entity.blockTarget = Vars.world.findTileTarget(tile.worldx(), tile.worldy(), tile, range, true);
|
||||||
@ -51,6 +53,8 @@ public class RepairTurret extends PowerTurret{
|
|||||||
|
|
||||||
if(entity.blockTarget.health > entity.blockTarget.health)
|
if(entity.blockTarget.health > entity.blockTarget.health)
|
||||||
entity.blockTarget.health = entity.blockTarget.maxhealth;
|
entity.blockTarget.health = entity.blockTarget.maxhealth;
|
||||||
|
|
||||||
|
entity.power -= powerUsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +64,8 @@ public class RepairTurret extends PowerTurret{
|
|||||||
Draw.color("green");
|
Draw.color("green");
|
||||||
Draw.dashcircle(tile.worldx(), tile.worldy(), range);
|
Draw.dashcircle(tile.worldx(), tile.worldy(), range);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
|
drawPowerBar(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
package io.anuke.mindustry.world.blocks.types.defense;
|
package io.anuke.mindustry.world.blocks.types.defense;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
|
import io.anuke.mindustry.entities.effect.Fx;
|
||||||
import io.anuke.mindustry.entities.effect.Shield;
|
import io.anuke.mindustry.entities.effect.Shield;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.types.PowerBlock;
|
import io.anuke.mindustry.world.blocks.types.PowerBlock;
|
||||||
|
import io.anuke.ucore.core.Effects;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.entities.BulletEntity;
|
||||||
|
|
||||||
public class ShieldBlock extends PowerBlock{
|
public class ShieldBlock extends PowerBlock{
|
||||||
private static boolean debugShield = false;
|
|
||||||
|
|
||||||
public float shieldRadius = 40f;
|
public float shieldRadius = 40f;
|
||||||
public float powerDrain = 0.005f;
|
public float powerDrain = 0.005f;
|
||||||
|
public float powerPerDamage = 0.1f;
|
||||||
|
|
||||||
public ShieldBlock(String name) {
|
public ShieldBlock(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
voltage = powerDrain;
|
voltage = powerDrain;
|
||||||
@ -23,18 +26,18 @@ public class ShieldBlock extends PowerBlock{
|
|||||||
|
|
||||||
if(entity.shield == null){
|
if(entity.shield == null){
|
||||||
entity.shield = new Shield(tile);
|
entity.shield = new Shield(tile);
|
||||||
if(debugShield)
|
if(Vars.infiniteAmmo && Vars.debug)
|
||||||
entity.shield.add();
|
entity.shield.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.power > powerDrain * Timers.delta()){
|
if(entity.power > powerPerDamage){
|
||||||
if(!entity.shield.active && entity.power > powerDrain * Timers.delta() * 10f){
|
if(!entity.shield.active && entity.power > powerDrain * Timers.delta() * 10f){
|
||||||
entity.shield.add();
|
entity.shield.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.power -= powerDrain * Timers.delta();
|
entity.power -= powerDrain * Timers.delta();
|
||||||
}else{
|
}else{
|
||||||
if(entity.shield.active && !debugShield){
|
if(entity.shield.active && !(Vars.infiniteAmmo && Vars.debug)){
|
||||||
entity.shield.removeDelay();
|
entity.shield.removeDelay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,6 +48,20 @@ public class ShieldBlock extends PowerBlock{
|
|||||||
public TileEntity getEntity(){
|
public TileEntity getEntity(){
|
||||||
return new ShieldEntity();
|
return new ShieldEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleBullet(Tile tile, BulletEntity bullet){
|
||||||
|
ShieldEntity entity = tile.entity();
|
||||||
|
|
||||||
|
if(entity.power < bullet.getDamage() * powerPerDamage){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bullet.remove();
|
||||||
|
Effects.effect(Fx.laserhit, bullet);
|
||||||
|
Vars.renderer.addShieldHit(bullet.x, bullet.y);
|
||||||
|
|
||||||
|
entity.power -= bullet.getDamage() * powerPerDamage;
|
||||||
|
}
|
||||||
|
|
||||||
static class ShieldEntity extends PowerEntity{
|
static class ShieldEntity extends PowerEntity{
|
||||||
Shield shield;
|
Shield shield;
|
||||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user