mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-08-01 23:50:17 +07:00
Completely new continuous collision system to prevent piercing
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
#Autogenerated file. Do not modify.
|
||||
#Fri Mar 02 14:57:27 EST 2018
|
||||
#Sat Mar 03 01:13:15 EST 2018
|
||||
version=release
|
||||
androidBuildCode=321
|
||||
androidBuildCode=328
|
||||
name=Mindustry
|
||||
code=3.4
|
||||
build=custom build
|
||||
|
@ -139,6 +139,6 @@ public class Vars{
|
||||
public static final EntityGroup<Enemy> enemyGroup = Entities.addGroup(Enemy.class).enableMapping();
|
||||
public static final EntityGroup<TileEntity> tileGroup = Entities.addGroup(TileEntity.class, false);
|
||||
public static final EntityGroup<Bullet> bulletGroup = Entities.addGroup(Bullet.class);
|
||||
public static final EntityGroup<Shield> shieldGroup = Entities.addGroup(Shield.class);
|
||||
public static final EntityGroup<EffectEntity> effectGroup = Entities.addGroup(EffectEntity.class);
|
||||
public static final EntityGroup<Shield> shieldGroup = Entities.addGroup(Shield.class, false);
|
||||
public static final EntityGroup<EffectEntity> effectGroup = Entities.addGroup(EffectEntity.class, false);
|
||||
}
|
||||
|
@ -151,8 +151,8 @@ public class Logic extends Module {
|
||||
Entities.update(shieldGroup);
|
||||
Entities.update(playerGroup);
|
||||
|
||||
Entities.collideGroups(enemyGroup, bulletGroup);
|
||||
Entities.collideGroups(playerGroup, bulletGroup);
|
||||
Entities.collideGroups(bulletGroup, enemyGroup);
|
||||
Entities.collideGroups(bulletGroup, playerGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class ThreadHandler {
|
||||
|
||||
Timers.setDeltaProvider(() ->{
|
||||
float result = impl.isOnThread() ? delta : Gdx.graphics.getDeltaTime()*60f;
|
||||
return Float.isNaN(result) ? 1f : result;
|
||||
return Math.min(Float.isNaN(result) ? 1f : result, 12f);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,10 @@ public class World extends Module{
|
||||
public Tile tileWorld(float x, float y){
|
||||
return tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize));
|
||||
}
|
||||
|
||||
public int toTile(float coord){
|
||||
return Mathf.scl2(coord, tilesize);
|
||||
}
|
||||
|
||||
public Tile[][] getTiles(){
|
||||
return tiles;
|
||||
@ -319,4 +323,37 @@ public class World extends Module{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void raycastEach(int x0f, int y0f, int x1, int y1, Raycaster cons){
|
||||
int x0 = x0f;
|
||||
int y0 = y0f;
|
||||
int dx = Math.abs(x1 - x0);
|
||||
int dy = Math.abs(y1 - y0);
|
||||
|
||||
int sx = x0 < x1 ? 1 : -1;
|
||||
int sy = y0 < y1 ? 1 : -1;
|
||||
|
||||
int err = dx - dy;
|
||||
int e2;
|
||||
while(true){
|
||||
|
||||
if(cons.accept(x0, y0)) break;
|
||||
if(x0 == x1 && y0 == y1) break;
|
||||
|
||||
e2 = 2 * err;
|
||||
if(e2 > -dy){
|
||||
err = err - dy;
|
||||
x0 = x0 + sx;
|
||||
}
|
||||
|
||||
if(e2 < dx){
|
||||
err = err + dx;
|
||||
y0 = y0 + sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface Raycaster{
|
||||
boolean accept(int x, int y);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.entities.BulletEntity;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@ -36,49 +36,38 @@ public class Bullet extends BulletEntity{
|
||||
public float drawSize(){
|
||||
return 8;
|
||||
}
|
||||
|
||||
public boolean collidesTiles(){
|
||||
return owner instanceof Enemy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
int tilex = Mathf.scl2(x, tilesize);
|
||||
int tiley = Mathf.scl2(y, tilesize);
|
||||
Tile tile = world.tile(tilex, tiley);
|
||||
TileEntity targetEntity = null;
|
||||
|
||||
if(tile != null){
|
||||
if(tile.entity != null && tile.entity.collide(this) && !tile.entity.dead){
|
||||
targetEntity = tile.entity;
|
||||
}else{
|
||||
//make sure to check for linked block collisions
|
||||
Tile linked = tile.getLinked();
|
||||
if(linked != null &&
|
||||
linked.entity != null && linked.entity.collide(this) && !linked.entity.dead){
|
||||
targetEntity = linked.entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(targetEntity != null){
|
||||
|
||||
targetEntity.collision(this);
|
||||
remove();
|
||||
type.removed(this);
|
||||
}
|
||||
|
||||
super.update();
|
||||
|
||||
if (collidesTiles()) {
|
||||
world.raycastEach(world.toTile(lastX), world.toTile(lastY), world.toTile(x), world.toTile(y), (x, y) -> {
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
if (tile == null) return false;
|
||||
tile = tile.target();
|
||||
|
||||
if (tile.entity != null && tile.entity.collide(this) && !tile.entity.dead) {
|
||||
tile.entity.collision(this);
|
||||
remove();
|
||||
type.hit(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
if(owner instanceof TileEntity && other instanceof Player)
|
||||
return false;
|
||||
return super.collides(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collision(SolidEntity other){
|
||||
super.collision(other);
|
||||
type.removed(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -90,5 +79,4 @@ public class Bullet extends BulletEntity{
|
||||
public Bullet add(){
|
||||
return super.add(bulletGroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -79,10 +79,10 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
public void despawned(Bullet b){
|
||||
removed(b);
|
||||
hit(b);
|
||||
}
|
||||
|
||||
public void removed(Bullet b){
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
Timers.run(5f, ()-> new EMP(b.x, b.y, b.getDamage()).add());
|
||||
Effects.effect(Fx.empshockwave, b);
|
||||
Effects.shake(3f, 3f, b);
|
||||
@ -113,10 +113,10 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
public void despawned(Bullet b){
|
||||
removed(b);
|
||||
hit(b);
|
||||
}
|
||||
|
||||
public void removed(Bullet b){
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
Effects.shake(3f, 3f, b);
|
||||
|
||||
Effects.effect(Fx.shellsmoke, b);
|
||||
@ -146,16 +146,16 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
public void removed(Bullet b) {
|
||||
despawned(b);
|
||||
public void hit(Bullet b, float hitx, float hity) {
|
||||
Effects.effect(shellsmoke, b);
|
||||
for(int i = 0; i < 3; i ++){
|
||||
Bullet bullet = new Bullet(flakspark, b.owner, hitx, hity, b.angle() + Mathf.range(120f));
|
||||
bullet.add();
|
||||
}
|
||||
}
|
||||
|
||||
public void despawned(Bullet b) {
|
||||
Effects.effect(shellsmoke, b);
|
||||
for(int i = 0; i < 3; i ++){
|
||||
Bullet bullet = new Bullet(flakspark, b.owner, b.x, b.y, b.angle() + Mathf.range(120f));
|
||||
bullet.add();
|
||||
}
|
||||
hit(b, b.x, b.y);
|
||||
}
|
||||
},
|
||||
flakspark = new BulletType(2f, 2) {
|
||||
@ -193,10 +193,10 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
public void despawned(Bullet b){
|
||||
removed(b);
|
||||
hit(b);
|
||||
}
|
||||
|
||||
public void removed(Bullet b){
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
Effects.shake(3f, 3f, b);
|
||||
|
||||
Effects.effect(Fx.shellsmoke, b);
|
||||
@ -224,10 +224,10 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
public void despawned(Bullet b){
|
||||
removed(b);
|
||||
hit(b);
|
||||
}
|
||||
|
||||
public void removed(Bullet b){
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
Effects.shake(3f, 3f, b);
|
||||
|
||||
Effects.effect(Fx.shellsmoke, b);
|
||||
@ -244,19 +244,19 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
public void despawned(Bullet b){
|
||||
removed(b);
|
||||
hit(b);
|
||||
}
|
||||
|
||||
public void removed(Bullet b){
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
Effects.shake(3f, 3f, b);
|
||||
|
||||
Effects.effect(Fx.blastsmoke, b);
|
||||
Effects.effect(Fx.blastexplosion, b);
|
||||
|
||||
//TODO remove translation() usage
|
||||
Angles.circleVectors(30, 6f, (x, y) -> {
|
||||
float ang = Mathf.atan2(x, y);
|
||||
Bullet o = new Bullet(blastshot, b.owner, b.x + x, b.y + y, ang).add();
|
||||
Angles.circleVectors(30, 6f, (nx, ny) -> {
|
||||
float ang = Mathf.atan2(nx, ny);
|
||||
Bullet o = new Bullet(blastshot, b.owner, b.x + nx, b.y + ny, ang).add();
|
||||
o.damage = b.damage/9;
|
||||
});
|
||||
}
|
||||
@ -363,10 +363,10 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
public void despawned(Bullet b){
|
||||
removed(b);
|
||||
hit(b);
|
||||
}
|
||||
|
||||
public void removed(Bullet b){
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
Effects.shake(1.5f, 1.5f, b);
|
||||
|
||||
Effects.effect(Fx.clusterbomb, b);
|
||||
@ -415,10 +415,10 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
public void despawned(Bullet b) {
|
||||
removed(b);
|
||||
hit(b);
|
||||
}
|
||||
|
||||
public void removed(Bullet b) {
|
||||
public void hit(Bullet b, float hitx, float hity) {
|
||||
for(int i = 0; i < 4; i ++){
|
||||
Bullet bullet = new Bullet(scrap, b.owner, b.x, b.y, b.angle() + Mathf.range(80f));
|
||||
bullet.add();
|
||||
@ -479,7 +479,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Bullet b){
|
||||
Effects.effect(Fx.hit, b);
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
Effects.effect(Fx.hit, hitx, hity);
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ public class Player extends SyncEntity{
|
||||
public void update(){
|
||||
if(!isLocal || isAndroid){
|
||||
if(isAndroid && isLocal){
|
||||
angle = Mathf.lerpAngDelta(angle, targetAngle, 0.2f);
|
||||
angle = Mathf.slerpDelta(angle, targetAngle, 0.2f);
|
||||
}
|
||||
if(!isLocal) interpolate();
|
||||
return;
|
||||
@ -216,10 +216,10 @@ public class Player extends SyncEntity{
|
||||
|
||||
if(!shooting){
|
||||
if(!movement.isZero())
|
||||
angle = Mathf.lerpAngDelta(angle, movement.angle(), 0.13f);
|
||||
angle = Mathf.slerpDelta(angle, movement.angle(), 0.13f);
|
||||
}else{
|
||||
float angle = Angles.mouseAngle(x, y);
|
||||
this.angle = Mathf.lerpAngDelta(this.angle, angle, 0.1f);
|
||||
this.angle = Mathf.slerpDelta(this.angle, angle, 0.1f);
|
||||
}
|
||||
|
||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||
|
@ -59,7 +59,7 @@ public abstract class SyncEntity extends DestructibleEntity{
|
||||
|
||||
this.x = spos.x = Mathf.lerpDelta(spos.x, x, 0.2f);
|
||||
this.y = spos.y = Mathf.lerpDelta(spos.y, y, 0.2f);
|
||||
this.angle = spos.z = Mathf.lerpAngDelta(spos.z, angle, 0.3f);
|
||||
this.angle = spos.z = Mathf.slerpDelta(spos.z, angle, 0.3f);
|
||||
}
|
||||
|
||||
drawSmooth();
|
||||
@ -124,7 +124,7 @@ public abstract class SyncEntity extends DestructibleEntity{
|
||||
|
||||
Mathf.lerp2(pos.set(last), target, time);
|
||||
|
||||
angle = Mathf.lerpAngDelta(angle, targetrot, 0.6f);
|
||||
angle = Mathf.slerpDelta(angle, targetrot, 0.6f);
|
||||
|
||||
if(target.dst(pos) > 128){
|
||||
pos.set(target);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
@ -22,7 +21,7 @@ import static io.anuke.mindustry.Vars.tileGroup;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class TileEntity extends Entity{
|
||||
private static final boolean friendlyFire = false;
|
||||
private static final boolean friendlyFire = true;
|
||||
|
||||
public Tile tile;
|
||||
public int[] items = new int[Item.getAllItems().size];
|
||||
@ -101,7 +100,7 @@ public class TileEntity extends Entity{
|
||||
}
|
||||
|
||||
public boolean collide(Bullet other){
|
||||
return other.owner instanceof Enemy || friendlyFire;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,9 +144,9 @@ public class EnemyType {
|
||||
}
|
||||
|
||||
if(enemy.target == null || alwaysRotate){
|
||||
enemy.angle = Mathf.slerp(enemy.angle, enemy.velocity.angle(), rotatespeed * Timers.delta());
|
||||
enemy.angle = Mathf.slerpDelta(enemy.angle, enemy.velocity.angle(), rotatespeed);
|
||||
}else{
|
||||
enemy.angle = Mathf.slerp(enemy.angle, enemy.angleTo(enemy.target), turretrotatespeed * Timers.delta());
|
||||
enemy.angle = Mathf.slerpDelta(enemy.angle, enemy.angleTo(enemy.target), turretrotatespeed);
|
||||
}
|
||||
|
||||
enemy.x = Mathf.clamp(enemy.x, 0, world.width() * tilesize);
|
||||
|
@ -235,6 +235,12 @@ public class Tile{
|
||||
}
|
||||
}
|
||||
|
||||
public Tile target(){
|
||||
Tile link = getLinked();
|
||||
return link == null ? this : link;
|
||||
}
|
||||
|
||||
|
||||
public Tile getNearby(int rotation){
|
||||
if(rotation == 0) return world.tile(x + 1, y);
|
||||
if(rotation == 1) return world.tile(x, y + 1);
|
||||
|
@ -56,7 +56,7 @@ public class RepairTurret extends PowerTurret{
|
||||
}
|
||||
|
||||
float target = entity.angleTo(entity.blockTarget);
|
||||
entity.rotation = Mathf.slerp(entity.rotation, target, 0.16f*Timers.delta());
|
||||
entity.rotation = Mathf.slerpDelta(entity.rotation, target, 0.16f);
|
||||
|
||||
int maxhealth = entity.blockTarget.tile.block().health;
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class NuclearReactor extends LiquidPowerGenerator{
|
||||
float fullness = (float)fuel / itemCapacity;
|
||||
|
||||
if(fuel > 0){
|
||||
entity.heat += fullness * heating * Timers.delta();
|
||||
entity.heat += fullness * heating * Math.min(Timers.delta(), 4f);
|
||||
entity.power += powerMultiplier * fullness * Timers.delta();
|
||||
entity.power = Mathf.clamp(entity.power, 0f, powerCapacity);
|
||||
if(entity.timer.get(timerFuel, fuelUseTime)){
|
||||
|
Reference in New Issue
Block a user