WIP tank unit type

This commit is contained in:
Anuken
2021-12-12 18:29:44 -05:00
parent 86a6ec6bd2
commit 0d33768f58
19 changed files with 168 additions and 33 deletions

View File

@@ -15,6 +15,7 @@ import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.type.ammo.*;
import mindustry.type.unit.*;
import mindustry.type.weapons.*;
import mindustry.world.meta.*;
@@ -70,6 +71,10 @@ public class UnitTypes{
//transport
public static @EntityDef({Unitc.class, BuildingTetherc.class}) UnitType manifold;
//tank
//TODO tank comp
public static @EntityDef({Unitc.class, Tankc.class}) UnitType vanquish;
//endregion
//missile definition, needed for codegen
@@ -1372,8 +1377,8 @@ public class UnitTypes{
lowAltitude = false;
flying = true;
circleTarget = true;
engineOffset = 12f;
engineSize = 6f;
engineOffset = 13f;
engineSize = 7f;
rotateShooting = false;
hitSize = 36f;
payloadCapacity = (3 * 3) * tilePayload;
@@ -2419,6 +2424,13 @@ public class UnitTypes{
}});
}};
//endregion
//region erekir - tank
vanquish = new TankUnitType("vanquish"){{
hitSize = 28f;
}};
//endregion
//region erekir - core

View File

@@ -11,9 +11,7 @@ import mindustry.world.*;
import static mindustry.Vars.*;
public class EntityCollisions{
//range for tile collision scanning
private static final int r = 1;
//move in 1-unit chunks
//move in 1-unit chunks (can this be made more efficient?)
private static final float seg = 1f;
//tile collisions
@@ -42,10 +40,12 @@ public class EntityCollisions{
if(Math.abs(deltax) < 0.0001f & Math.abs(deltay) < 0.0001f) return;
boolean movedx = false;
entity.hitboxTile(r1);
int r = Math.max(Math.round(r1.width / tilesize), 1);
while(Math.abs(deltax) > 0 || !movedx){
movedx = true;
moveDelta(entity, Math.min(Math.abs(deltax), seg) * Mathf.sign(deltax), 0, true, solidCheck);
moveDelta(entity, Math.min(Math.abs(deltax), seg) * Mathf.sign(deltax), 0, r, true, solidCheck);
if(Math.abs(deltax) >= seg){
deltax -= seg * Mathf.sign(deltax);
@@ -58,7 +58,7 @@ public class EntityCollisions{
while(Math.abs(deltay) > 0 || !movedy){
movedy = true;
moveDelta(entity, 0, Math.min(Math.abs(deltay), seg) * Mathf.sign(deltay), false, solidCheck);
moveDelta(entity, 0, Math.min(Math.abs(deltay), seg) * Mathf.sign(deltay), r, false, solidCheck);
if(Math.abs(deltay) >= seg){
deltay -= seg * Mathf.sign(deltay);
@@ -68,7 +68,7 @@ public class EntityCollisions{
}
}
public void moveDelta(Hitboxc entity, float deltax, float deltay, boolean x, SolidPred solidCheck){
public void moveDelta(Hitboxc entity, float deltax, float deltay, int r, boolean x, SolidPred solidCheck){
entity.hitboxTile(r1);
entity.hitboxTile(r2);
r1.x += deltax;

View File

@@ -69,6 +69,9 @@ abstract class HitboxComp implements Posc, Sized, QuadTreeObject{
public void hitboxTile(Rect rect){
//tile hitboxes are never bigger than a tile, otherwise units get stuck
float size = Math.min(hitSize * 0.66f, 7.9f);
//TODO: better / more accurate version is
//float size = hitSize * 0.85f;
//- for tanks?
rect.setCentered(x, y, size, size);
}
}

View File

@@ -0,0 +1,63 @@
package mindustry.entities.comp;
import arc.math.geom.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.blocks.environment.*;
import static mindustry.Vars.*;
@Component
abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec{
@Import float x, y, hitSize;
@Import UnitType type;
transient float treadTime;
transient boolean walked;
@Override
public void update(){
//trigger animation only when walking manually
if(walked || net.client()){
float len = deltaLen();
treadTime += len;
walked = false;
}
//TODO treads should create dust, see MechComp
}
@Replace
@Override
public @Nullable Floor drownFloor(){
//tanks can only drown when all the nearby floors are deep
//TODO implement properly
if(hitSize >= 12 && canDrown()){
for(Point2 p : Geometry.d8){
Floor f = world.floorWorld(x + p.x * tilesize, y + p.y * tilesize);
if(!f.isDeep()){
return null;
}
}
}
return canDrown() ? floorOn() : null;
}
@Override
public void moveAt(Vec2 vector, float acceleration){
//mark walking state when moving in a controlled manner
if(!vector.isZero()){
walked = true;
}
}
@Override
public void approach(Vec2 vector){
//mark walking state when moving in a controlled manner
if(!vector.isZero(0.001f)){
walked = true;
}
}
}

View File

@@ -71,7 +71,10 @@ public class UnitType extends UnlockableContent{
public boolean createWreck = true;
public boolean useUnitCap = true;
public boolean destructibleWreck = true;
public boolean squareShadow = false;
/** If true, this modded unit always has a -outline region generated for its base. Normally, outlines are ignored if there are no top = false weapons. */
public boolean alwaysCreateOutline = false;
/** If true, this unit has a square shadow. TODO physics? */
public boolean squareShape = false;
public float groundLayer = Layer.groundUnit;
public float payloadCapacity = 8;
public float aimDst = -1f;
@@ -162,7 +165,7 @@ public class UnitType extends UnlockableContent{
public Seq<Weapon> weapons = new Seq<>();
public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion,
softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion;
softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion, treadRegion;
public TextureRegion[] wreckRegions;
public TextureRegion[] segmentRegions, segmentOutlineRegions;
@@ -494,12 +497,13 @@ public class UnitType extends UnlockableContent{
jointRegion = Core.atlas.find(name + "-joint");
baseJointRegion = Core.atlas.find(name + "-joint-base");
footRegion = Core.atlas.find(name + "-foot");
treadRegion = Core.atlas.find(name + "-treads");
legBaseRegion = Core.atlas.find(name + "-leg-base", name + "-leg");
baseRegion = Core.atlas.find(name + "-base");
cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell"));
//when linear filtering is on, it's acceptable to use the relatively low-res 'particle' region
softShadowRegion =
squareShadow ? Core.atlas.find("square-shadow") :
squareShape ? Core.atlas.find("square-shadow") :
hitSize <= 10f || (Core.settings != null && Core.settings.getBool("linear", true)) ?
Core.atlas.find("particle") :
Core.atlas.find("circle-shadow");
@@ -522,16 +526,16 @@ public class UnitType extends UnlockableContent{
clipSize = Math.max(region.width * 2f, clipSize);
}
private void makeOutline(MultiPacker packer, TextureRegion region){
private void makeOutline(MultiPacker packer, TextureRegion region, boolean makeNew){
if(region instanceof AtlasRegion at && region.found()){
String name = at.name;
if(!packer.has(name + "-outline")){
if(!makeNew || !packer.has(name + "-outline")){
PixmapRegion base = Core.atlas.getPixmap(region);
var result = Pixmaps.outline(base, outlineColor, outlineRadius);
if(Core.settings.getBool("linear", true)){
Pixmaps.bleed(result);
}
packer.add(PageType.main, name + "-outline", result);
packer.add(PageType.main, name + (makeNew ? "-outline" : ""), result);
}
}
}
@@ -542,10 +546,13 @@ public class UnitType extends UnlockableContent{
//currently does not create outlines for legs or base regions due to older mods having them outlined by default
if(outlines){
makeOutline(packer, region);
//outlines only created when weapons are drawn under w/ merged outlines
makeOutline(packer, region, alwaysCreateOutline || weapons.contains(w -> !w.top));
for(Weapon weapon : weapons){
if(!weapon.name.isEmpty()){
makeOutline(packer, weapon.region);
makeOutline(packer, weapon.region, true);
}
}
}
@@ -686,6 +693,10 @@ public class UnitType extends UnlockableContent{
unit.trns(legOffset.x, legOffset.y);
}
if(unit instanceof Tankc){
drawTank((Unit & Tankc)unit);
}
if(unit instanceof Legsc){
drawLegs((Unit & Legsc)unit);
}
@@ -950,6 +961,10 @@ public class UnitType extends UnlockableContent{
}
}
public <T extends Unit & Tankc> void drawTank(T unit){
Draw.rect(treadRegion, unit.x, unit.y, unit.rotation - 90);
}
public <T extends Unit & Legsc> void drawLegs(T unit){
applyColor(unit);
Tmp.c3.set(Draw.getMixColor());

View File

@@ -1,7 +1,8 @@
package mindustry.type;
package mindustry.type.unit;
import mindustry.ai.types.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.meta.*;
/** Field template for unit types. No new functionality. */

View File

@@ -1,8 +1,9 @@
package mindustry.type;
package mindustry.type.unit;
import mindustry.content.*;
import mindustry.entities.abilities.*;
import mindustry.graphics.*;
import mindustry.type.*;
/** This is just a preset. Contains no new behavior. */
public class NeoplasmUnitType extends UnitType{

View File

@@ -0,0 +1,21 @@
package mindustry.type.unit;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.meta.*;
public class TankUnitType extends UnitType{
public TankUnitType(String name){
super(name);
squareShape = true;
omniMovement = false;
rotateSpeed = 1.3f;
envDisabled = Env.none;
speed = 0.8f;
outlineColor = Pal.darkOutline;
}
}

View File

@@ -72,7 +72,7 @@ public class ImpactReactor extends PowerGenerator{
}
public class ImpactReactorBuild extends GeneratorBuild{
public float warmup;
public float warmup, totalProgress;
@Override
public void updateTile(){
@@ -95,9 +95,16 @@ public class ImpactReactor extends PowerGenerator{
warmup = Mathf.lerpDelta(warmup, 0f, 0.01f);
}
totalProgress += warmup * Time.delta;
productionEfficiency = Mathf.pow(warmup, 5f);
}
@Override
public float totalProgress(){
return totalProgress;
}
@Override
public float ambientVolume(){
return warmup;
@@ -113,7 +120,7 @@ public class ImpactReactor extends PowerGenerator{
Draw.color(plasma1, plasma2, (float)i / plasmaRegions.length);
Draw.alpha((0.3f + Mathf.absin(Time.time, 2f + i * 2f, 0.3f + i * 0.05f)) * warmup);
Draw.rect(plasmaRegions[i], x, y, r, r, Time.time * (12 + i * 6f) * warmup);
Draw.rect(plasmaRegions[i], x, y, r, r, totalProgress * (12 + i * 6f));
}
Draw.blend();