1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2025-03-15 04:14:07 +07:00

Implemented new accurate turret prediction

This commit is contained in:
Anuken 2018-05-06 10:54:18 -04:00
parent f8a4128c88
commit c74ee2150c
3 changed files with 68 additions and 10 deletions
core/src/io/anuke/mindustry
core
entities
world/blocks/types/defense

View File

@ -21,6 +21,7 @@ import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Placement; import io.anuke.mindustry.world.Placement;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.BaseBulletType; import io.anuke.ucore.entities.BaseBulletType;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
@ -203,7 +204,7 @@ public class NetServer extends Module{
if(recipe == null || recipe.debugOnly != debug) return; if(recipe == null || recipe.debugOnly != debug) return;
Tile tile = world.tile(packet.x, packet.y); Tile tile = world.tile(packet.x, packet.y);
if(tile.synthetic() && admins.isValidateReplace() && !admins.validateBreak(admins.getTrace(Net.getConnection(id).address).uuid, Net.getConnection(id).address)){ if(tile.synthetic() && admins.isValidateReplace() && !admins.validateBreak(placer.uuid, Net.getConnection(id).address)){
if(Timers.get("break-message-" + id, 120)){ if(Timers.get("break-message-" + id, 120)){
sendMessageTo(id, "[scarlet]Anti-grief: you are replacing blocks too quickly. wait until replacing again."); sendMessageTo(id, "[scarlet]Anti-grief: you are replacing blocks too quickly. wait until replacing again.");
} }
@ -231,7 +232,7 @@ public class NetServer extends Module{
Tile tile = world.tile(packet.x, packet.y); Tile tile = world.tile(packet.x, packet.y);
if(tile.synthetic() && !admins.validateBreak(admins.getTrace(Net.getConnection(id).address).uuid, Net.getConnection(id).address)){ if(tile.synthetic() && !admins.validateBreak(placer.uuid, Net.getConnection(id).address)){
if(Timers.get("break-message-" + id, 120)){ if(Timers.get("break-message-" + id, 120)){
sendMessageTo(id, "[scarlet]Anti-grief: you are breaking blocks too quickly. wait until breaking again."); sendMessageTo(id, "[scarlet]Anti-grief: you are breaking blocks too quickly. wait until breaking again.");
} }

View File

@ -0,0 +1,60 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Vector2;
import io.anuke.ucore.util.Mathf;
public class Predict {
private static Vector2 vec = new Vector2();
private static Vector2 vresult = new Vector2();
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,
tvx = dstvx,
tvy = dstvy;
// Get quadratic equation components
float a = tvx*tvx + tvy*tvy - v*v;
float b = 2 * (tvx * tx + tvy * ty);
float c = tx*tx + ty*ty;
// Solve quadratic
Vector2 ts = quad(a, b, c); // See quad(), below
// Find smallest positive solution
Vector2 sol = vresult.set(0, 0);
if (ts != null) {
float t0 = ts.x, t1 = ts.y;
float t = Math.min(t0, t1);
if (t < 0) t = Math.max(t0, t1);
if (t > 0) {
sol.set(dstx + dstvx*t, dsty + dstvy*t);
}
}
return sol;
}
/**
* Return solutions for quadratic
*/
public static Vector2 quad(float a, float b, float c) {
Vector2 sol = null;
if (Math.abs(a) < 1e-6) {
if (Math.abs(b) < 1e-6) {
sol = Math.abs(c) < 1e-6 ? vec.set(0,0) : null;
} else {
vec.set(-c/b, -c/b);
}
} else {
float disc = b*b - 4*a*c;
if (disc >= 0) {
disc = Mathf.sqrt(disc);
a = 2*a;
sol = vec.set((-b-disc)/a, (-b+disc)/a);
}
}
return sol;
}
}

View File

@ -18,10 +18,7 @@ import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.BiConsumer; import io.anuke.ucore.function.BiConsumer;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.*;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.Translator;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -151,14 +148,14 @@ public abstract class Turret extends Block{
float speed = type.bullet.speed; float speed = type.bullet.speed;
if(speed < 0.1f) speed = 9999999f; if(speed < 0.1f) speed = 9999999f;
float targetRot = Angles.predictAngle(tile.worldx(), tile.worldy(), float targetRot = Predict.intercept(tile.drawx(), tile.drawy(),
entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, speed); entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, speed)
.sub(tile.drawx(), tile.drawy()).angle();
if(Float.isNaN(entity.rotation)){ if(Float.isNaN(entity.rotation)){
entity.rotation = 0; entity.rotation = 0;
} }
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRot, entity.rotation = Angles.moveToward(entity.rotation, targetRot, 5f * Timers.delta());
rotatespeed);
if(Angles.angleDist(entity.rotation, targetRot) < shootCone){ if(Angles.angleDist(entity.rotation, targetRot) < shootCone){
updateShooting(tile); updateShooting(tile);