Basic unit rendering

This commit is contained in:
Anuken
2020-02-06 22:08:31 -05:00
parent f83b6728cf
commit eeae5149a1
16 changed files with 195 additions and 233 deletions

View File

@ -5,6 +5,7 @@ import arc.func.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import arc.util.pooling.*;
import com.squareup.javapoet.*;
import com.squareup.javapoet.TypeSpec.*;
import com.sun.source.tree.*;
@ -271,6 +272,10 @@ public class EntityProcess extends BaseProcessor{
if(writeBlock) mbuilder.addCode("}\n");
}
if(first.name().equals("remove") && ann.pooled()){
mbuilder.addStatement("$T.free(this)", Pools.class);
}
builder.addMethod(mbuilder.build());
}
@ -280,7 +285,7 @@ public class EntityProcess extends BaseProcessor{
//add create() method
builder.addMethod(MethodSpec.methodBuilder("create").addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(tname(packageName + "." + name))
.addStatement(ann.pooled() ? "return " : "return new $L()", name).build());
.addStatement(ann.pooled() ? "return Pools.obtain($L.class, " +name +"::new)" : "return new $L()", name).build());
definitions.add(new EntityDefinition("mindustry.gen." + name, builder, type, components, groups));
}

View File

@ -23,6 +23,7 @@ public class UnitTypes implements ContentList{
health = 130;
weapons.add(new Weapon("chain-blaster"){{
reload = 28f;
x = 4f;
alternate = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardCopper;

View File

@ -1,57 +0,0 @@
package mindustry.entities.def;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
import static mindustry.Vars.itemSize;
@Component
abstract class DrawItemsComp implements Drawc, Itemsc, Posc, Rotc{
transient float x, y, rotation;
float itemTime;
//drawn after base
@Override
@MethodPriority(3)
public void draw(){
boolean number = isLocal();
itemTime = Mathf.lerpDelta(itemTime, Mathf.num(hasItem()), 0.05f);
//draw back items
if(itemTime > 0.01f){
float backTrns = 5f;
float size = (itemSize + Mathf.absin(Time.time(), 5f, 1f)) * itemTime;
Draw.mixcol(Pal.accent, Mathf.absin(Time.time(), 5f, 0.5f));
Draw.rect(item().icon(Cicon.medium),
x + Angles.trnsx(rotation + 180f, backTrns),
y + Angles.trnsy(rotation + 180f, backTrns),
size, size, rotation);
Draw.mixcol();
Lines.stroke(1f, Pal.accent);
Lines.circle(
x + Angles.trnsx(rotation + 180f, backTrns),
y + Angles.trnsy(rotation + 180f, backTrns),
(3f + Mathf.absin(Time.time(), 5f, 1f)) * itemTime);
if(isLocal()){
Fonts.outline.draw(stack().amount + "",
x + Angles.trnsx(rotation + 180f, backTrns),
y + Angles.trnsy(rotation + 180f, backTrns) - 3,
Pal.accent, 0.25f * itemTime / Scl.scl(1f), false, Align.center
);
}
Draw.reset();
}
}
}

View File

@ -1,9 +0,0 @@
package mindustry.entities.def;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
@Component
abstract class DrawOverComp implements Drawc{
void drawOver(){}
}

View File

@ -1,24 +0,0 @@
package mindustry.entities.def;
import arc.graphics.*;
import arc.graphics.g2d.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
@Component
abstract class DrawShadowComp implements Drawc, Rotc, Flyingc, DrawLayerFlyingShadowsc{
static final float shadowTX = -12, shadowTY = -13, shadowColor = Color.toFloatBits(0, 0, 0, 0.22f);
transient float x, y, rotation;
abstract TextureRegion getShadowRegion();
@Override
public void drawFlyingShadows(){
if(isFlying()){
Draw.color(shadowColor);
Draw.rect(getShadowRegion(), x + shadowTX * elevation(), y + shadowTY * elevation(), rotation - 90);
Draw.color();
}
}
}

View File

@ -1,9 +0,0 @@
package mindustry.entities.def;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
@Component
abstract class DrawUnderComp implements Drawc{
void drawUnder(){}
}

View File

@ -8,12 +8,14 @@ import mindustry.type.*;
@Component
abstract class ItemsComp implements Posc{
@ReadOnly ItemStack stack = new ItemStack();
float itemTime;
abstract int itemCapacity();
@Override
public void update(){
stack.amount = Mathf.clamp(stack.amount, 0, itemCapacity());
itemTime = Mathf.lerpDelta(itemTime, Mathf.num(hasItem()), 0.05f);
}
Item item(){

View File

@ -1,48 +1,16 @@
package mindustry.entities.def;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
import mindustry.world.blocks.*;
@Component
abstract class LegsComp implements Posc, Flyingc, Hitboxc, DrawLayerGroundUnderc{
abstract class LegsComp implements Posc, Flyingc, Hitboxc, DrawLayerGroundUnderc, Unitc, Legsc{
transient float x, y;
float baseRotation, walkTime;
abstract TextureRegion legRegion();
abstract TextureRegion baseRegion();
@Override
public void drawGroundUnder(){
Draw.mixcol(Color.white, hitAlpha());
float ft = Mathf.sin(walkTime * vel().len() * 5f, 6f, 2f + hitSize() / 15f);
Floor floor = floorOn();
if(floor.isLiquid){
Draw.color(Color.white, floor.color, 0.5f);
}
for(int i : Mathf.signs){
Draw.rect(legRegion(),
x + Angles.trnsx(baseRotation, ft * i),
y + Angles.trnsy(baseRotation, ft * i),
legRegion().getWidth() * i * Draw.scl, legRegion().getHeight() * Draw.scl - Mathf.clamp(ft * i, 0, 2), baseRotation - 90);
}
if(floor.isLiquid){
Draw.color(Color.white, floor.color, drownTime() * 0.4f);
}else{
Draw.color(Color.white);
}
Draw.rect(baseRegion(), x, y, baseRotation - 90);
Draw.mixcol();
type().drawLegs(this);
}
}

View File

@ -66,9 +66,7 @@ abstract class StatusComp implements Posc, Flyingc{
return hasEffect(StatusEffects.boss);
}
boolean isImmune(StatusEffect effect){
return false;
}
abstract boolean isImmune(StatusEffect effect);
Color statusColor(){
if(statuses.size == 0){

View File

@ -1,9 +1,6 @@
package mindustry.entities.def;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
@ -19,25 +16,13 @@ import mindustry.world.blocks.*;
import static mindustry.Vars.*;
@Component
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc, Massc, Unitc, Weaponsc, DrawShadowc, DrawLayerGroundc, DrawLayerFlyingc{
abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitboxc, Rotc, Massc, Unitc, Weaponsc, Drawc,
DrawLayerGroundc, DrawLayerFlyingc, DrawLayerGroundShadowsc, DrawLayerFlyingShadowsc{
transient float x, y, rotation;
private UnitController controller;
private UnitDef type;
TextureRegion baseRegion(){
return type.baseRegion;
}
TextureRegion legRegion(){
return type.legRegion;
}
@Override
public TextureRegion getShadowRegion(){
return type.region;
}
@Override
public float clipSize(){
return type.region.getWidth() * 2f;
@ -110,29 +95,27 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
}
@Override
public void drawLight(){
//TODO move
if(type.lightRadius > 0){
renderer.lights.add(x, y, type.lightRadius, type.lightColor, 0.6f);
}
public boolean isImmune(StatusEffect effect){
return type.immunities.contains(effect);
}
@Override
public void draw(){
drawCell();
if(type.lightRadius > 0){
renderer.lights.add(x, y, type.lightRadius, type.lightColor, type.lightOpacity);
}
type.drawBody(this);
type.drawWeapons(this);
if(type.drawCell) type.drawCell(this);
if(type.drawItems) type.drawItems(this);
type.drawLight(this);
}
@Override
public void drawBody(){
Draw.mixcol(Color.white, hitAlpha());
public void drawFlyingShadows(){
if(isFlying()) type.drawShadow(this);
}
Draw.rect(type.region, x, y, rotation - 90);
Draw.reset();
@Override
public void drawGroundShadows(){
type.drawOcclusion(this);
}
@Override
@ -145,14 +128,6 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
if(isGrounded()) draw();
}
@Override
public void drawCell(){
//draw power cell - TODO move
Draw.color(Color.black, team().color, healthf() + Mathf.absin(Time.time(), Math.max(healthf() * 5f, 1f), 1f - healthf()));
Draw.rect(type.cellRegion, x, y, rotation() - 90);
Draw.color();
}
@Override
public void killed(){
float explosiveness = 2f + item().explosiveness * stack().amount;

View File

@ -1,6 +1,5 @@
package mindustry.entities.def;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
@ -14,8 +13,6 @@ import mindustry.type.*;
abstract class WeaponsComp implements Teamc, Posc, Rotc{
transient float x, y, rotation;
/** 1 */
static final int[] one = {1};
/** minimum cursor distance from player, fixes 'cross-eyed' shooting */
static final float minAimDst = 20f;
/** temporary weapon sequence number */
@ -50,8 +47,9 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
public void update(){
for(WeaponMount mount : mounts){
Weapon weapon = mount.weapon;
mount.reload -= Time.delta();
mount.reload = Math.max(mount.reload - Time.delta(), 0);
if(mount.shoot){
float rotation = this.rotation - 90;
//rotate if applicable
@ -65,8 +63,8 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
//shoot if applicable
//TODO only shoot if angle is reached, don't shoot inaccurately
if(mount.reload <= 0){
for(int i : (weapon.mirror && !weapon.alternate ? Mathf.signs : one)){
if(mount.reload <= 0.0001f){
for(int i : (weapon.mirror && !weapon.alternate ? Mathf.signs : Mathf.one)){
i *= Mathf.sign(weapon.flipped) * Mathf.sign(mount.side);
//m a t h
@ -85,27 +83,6 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
}
}
}
/** Draw weapon mounts. */
void drawWeapons(){
for(WeaponMount mount : mounts){
Weapon weapon = mount.weapon;
for(int i : (weapon.mirror ? Mathf.signs : one)){
i *= Mathf.sign(weapon.flipped);
float rotation = this.rotation - 90 + (weapon.rotate ? mount.rotation : 0);
float trY = weapon.y - (mount.reload / weapon.reload * weapon.recoil) * (weapon.alternate ? Mathf.num(i == Mathf.sign(mount.side)) : 1);
float width = i > 0 ? -weapon.region.getWidth() : weapon.region.getWidth();
Draw.rect(weapon.region,
x + Angles.trnsx(rotation, weapon.x * i, trY),
y + Angles.trnsy(rotation, weapon.x * i, trY),
width * Draw.scl,
weapon.region.getHeight() * Draw.scl,
rotation - 90);
}
}
}
private void shoot(Weapon weapon, float x, float y, float rotation){

View File

@ -13,6 +13,8 @@ public class WeaponMount{
public float aimX, aimY;
/** side that's being shot - only valid for mirrors */
public boolean side;
/** whether to shoot right now */
public boolean shoot = false;
public WeaponMount(Weapon weapon){
this.weapon = weapon;

View File

@ -24,6 +24,10 @@ public class LightRenderer{
lights.add(run);
}
public void add(Position pos, float radius, Color color, float opacity){
add(pos.getX(), pos.getY(), radius, color, opacity);
}
public void add(float x, float y, float radius, Color color, float opacity){
if(!enabled()) return;

View File

@ -5,7 +5,7 @@ import mindustry.content.Items;
public class ItemStack implements Comparable<ItemStack>{
public Item item;
public int amount = 1;
public int amount = 0;
public ItemStack(Item item, int amount){
if(item == null) item = Items.copper;

View File

@ -5,9 +5,11 @@ import arc.audio.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.entities.units.*;
@ -15,10 +17,14 @@ import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
import mindustry.world.blocks.*;
import static mindustry.Vars.*;
//TODO change to UnitType or Shell or something
public class UnitDef extends UnlockableContent{
//TODO implement
static final float shadowTX = -12, shadowTY = -13, shadowColor = Color.toFloatBits(0, 0, 0, 0.22f);
public @NonNull Prov<? extends UnitController> defaultController = AIController::new;
public @NonNull Prov<? extends Unitc> constructor;
public boolean flying;
@ -26,7 +32,7 @@ public class UnitDef extends UnlockableContent{
public float drag = 0.3f, mass = 1f, accel = 0.1f;
public float health = 200f, range = -1;
public boolean targetAir = false, targetGround = false;
public boolean faceTarget = true; //equivalent to turnCursor
public boolean faceTarget = true;
public int itemCapacity = 30;
public int drillTier = -1;
@ -35,8 +41,8 @@ public class UnitDef extends UnlockableContent{
public Color engineColor = Pal.boostTo;
public float engineOffset = 5f, engineSize = 2.5f;
public float hitsize = 6f, hitsizeTile = 4f;
public float cellOffsetX = 0f, cellOffsetY = 0f;
public float hitsize = 6f;
public float itemOffsetY = 3f;
public float lightRadius = 60f, lightOpacity = 0.6f;
public Color lightColor = Pal.powerLight;
public boolean drawCell = true, drawItems = true;
@ -45,7 +51,7 @@ public class UnitDef extends UnlockableContent{
public Sound deathSound = Sounds.bang;
public Array<Weapon> weapons = new Array<>();
public TextureRegion baseRegion, legRegion, region, cellRegion;
public TextureRegion baseRegion, legRegion, region, cellRegion, occlusionRegion;
public UnitDef(String name, Prov<Unitc> constructor){
super(name);
@ -91,10 +97,133 @@ public class UnitDef extends UnlockableContent{
legRegion = Core.atlas.find(name + "-leg");
baseRegion = Core.atlas.find(name + "-base");
cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell"));
occlusionRegion = Core.atlas.find("circle-shadow");
}
@Override
public ContentType getContentType(){
return ContentType.unit;
}
//region drawing
public void drawShadow(Unitc unit){
Draw.color(shadowColor);
Draw.rect(region, unit.x() + shadowTX * unit.elevation(), unit.y() + shadowTY * unit.elevation(), unit.rotation() - 90);
Draw.color();
}
public void drawOcclusion(Unitc unit){
Draw.color(0, 0, 0, 0.4f);
float rad = 1.6f;
float size = Math.max(region.getWidth(), region.getHeight()) * Draw.scl;
Draw.rect(occlusionRegion, unit, size * rad, size * rad);
Draw.color();
}
public void drawItems(Unitc unit){
//draw back items
if(unit.hasItem() && unit.itemTime() > 0.01f){
float size = (itemSize + Mathf.absin(Time.time(), 5f, 1f)) * unit.itemTime();
Draw.mixcol(Pal.accent, Mathf.absin(Time.time(), 5f, 0.5f));
Draw.rect(unit.item().icon(Cicon.medium),
unit.x() + Angles.trnsx(unit.rotation() + 180f, itemOffsetY),
unit.y() + Angles.trnsy(unit.rotation() + 180f, itemOffsetY),
size, size, unit.rotation());
Draw.mixcol();
Lines.stroke(1f, Pal.accent);
Lines.circle(
unit.x() + Angles.trnsx(unit.rotation() + 180f, itemOffsetY),
unit.y() + Angles.trnsy(unit.rotation() + 180f, itemOffsetY),
(3f + Mathf.absin(Time.time(), 5f, 1f)) * unit.itemTime());
if(unit.isLocal()){
Fonts.outline.draw(unit.stack().amount + "",
unit.x() + Angles.trnsx(unit.rotation() + 180f, itemOffsetY),
unit.y() + Angles.trnsy(unit.rotation() + 180f, itemOffsetY) - 3,
Pal.accent, 0.25f * unit.itemTime() / Scl.scl(1f), false, Align.center
);
}
Draw.reset();
}
}
public void drawWeapons(Unitc unit){
for(WeaponMount mount : unit.mounts()){
Weapon weapon = mount.weapon;
for(int i : (weapon.mirror ? Mathf.signs : Mathf.one)){
i *= Mathf.sign(weapon.flipped);
float rotation = unit.rotation() - 90 + (weapon.rotate ? mount.rotation : 0);
float trY = weapon.y - (mount.reload / weapon.reload * weapon.recoil) * (weapon.alternate ? Mathf.num(i == Mathf.sign(mount.side)) : 1);
float width = i > 0 ? -weapon.region.getWidth() : weapon.region.getWidth();
Draw.rect(weapon.region,
unit.x() + Angles.trnsx(rotation, weapon.x * i, trY),
unit.y() + Angles.trnsy(rotation, weapon.x * i, trY),
width * Draw.scl,
weapon.region.getHeight() * Draw.scl,
rotation);
}
}
}
public void drawBody(Unitc unit){
Draw.mixcol(Color.white, unit.hitAlpha());
Draw.rect(region, unit, unit.rotation() - 90);
Draw.reset();
}
public void drawCell(Unitc unit){
if(!drawCell) return;
Draw.color(Color.black, unit.team().color, unit.healthf() + Mathf.absin(Time.time(), Math.max(unit.healthf() * 5f, 1f), 1f - unit.healthf()));
Draw.rect(cellRegion, unit, unit.rotation() - 90);
Draw.color();
}
public void drawLight(Unitc unit){
if(lightRadius > 0){
renderer.lights.add(unit, lightRadius, lightColor, lightOpacity);
}
}
public void drawLegs(Legsc unit){
Draw.mixcol(Color.white, unit.hitAlpha());
float ft = Mathf.sin(unit.walkTime() * unit.vel().len() * 5f, 6f, 2f + unit.hitSize() / 15f);
Floor floor = unit.floorOn();
if(floor.isLiquid){
Draw.color(Color.white, floor.color, 0.5f);
}
for(int i : Mathf.signs){
Draw.rect(legRegion,
unit.x() + Angles.trnsx(unit.baseRotation(), ft * i),
unit.y() + Angles.trnsy(unit.baseRotation(), ft * i),
legRegion.getWidth() * i * Draw.scl, legRegion.getHeight() * Draw.scl - Mathf.clamp(ft * i, 0, 2), unit.baseRotation() - 90);
}
if(floor.isLiquid){
Draw.color(Color.white, floor.color, unit.drownTime() * 0.4f);
}else{
Draw.color(Color.white);
}
Draw.rect(baseRegion, unit, unit.baseRotation() - 90);
Draw.mixcol();
}
//endregion
}

View File

@ -1,3 +1,3 @@
org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=a57e709113a364ff718821de4c40366e17353329
archash=0e6ac9406fa34f2f5596ff1b151a3ebd07856aac