Fires, puddles, feature reimplementations
This commit is contained in:
@@ -192,11 +192,13 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
for(Selement<?> type : allDefs){
|
for(Selement<?> type : allDefs){
|
||||||
EntityDef ann = type.annotation(EntityDef.class);
|
EntityDef ann = type.annotation(EntityDef.class);
|
||||||
boolean isFinal = ann.isFinal();
|
boolean isFinal = ann.isFinal();
|
||||||
if(type.isType() && !type.name().endsWith("Def")){
|
|
||||||
err("All entity def names must end with 'Def'", type.e);
|
if(type.isType() && (!type.name().endsWith("Def") && !type.name().endsWith("Comp"))){
|
||||||
|
err("All entity def names must end with 'Def'/'Comp'", type.e);
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = type.isType() ?
|
String name = type.isType() ?
|
||||||
type.name().replace("Def", "Entity") :
|
type.name().replace("Def", "Entity").replace("Comp", "Entity") :
|
||||||
createName(type);
|
createName(type);
|
||||||
|
|
||||||
//skip double classes
|
//skip double classes
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#Maps entity names to IDs. Autogenerated.
|
#Maps entity names to IDs. Autogenerated.
|
||||||
|
|
||||||
|
mindustry.entities.def.PuddleComp=12
|
||||||
|
mindustry.entities.def.BulletComp=13
|
||||||
dagger=7
|
dagger=7
|
||||||
mindustry.entities.AllEntities.GenericBuilderDef=6
|
mindustry.entities.AllEntities.GenericBuilderDef=6
|
||||||
mindustry.entities.AllEntities.BulletDef=0
|
mindustry.entities.AllEntities.BulletDef=0
|
||||||
@@ -10,5 +12,11 @@ mindustry.entities.AllEntities.EffectDef=2
|
|||||||
mindustry.entities.AllEntities.GenericUnitDef=5
|
mindustry.entities.AllEntities.GenericUnitDef=5
|
||||||
mindustry.entities.AllEntities.TileDef=3
|
mindustry.entities.AllEntities.TileDef=3
|
||||||
vanguard=10
|
vanguard=10
|
||||||
|
mindustry.entities.def.PlayerComp=17
|
||||||
dagger2=8
|
dagger2=8
|
||||||
|
mindustry.entities.def.DecalComp=14
|
||||||
mindustry.entities.AllEntities.DecalDef=1
|
mindustry.entities.AllEntities.DecalDef=1
|
||||||
|
mindustry.entities.def.StandardEffectComp=18
|
||||||
|
mindustry.entities.def.TileComp=19
|
||||||
|
mindustry.entities.def.FireComp=15
|
||||||
|
mindustry.entities.def.GroundEffectComp=16
|
||||||
@@ -425,8 +425,7 @@ public class Bullets implements ContentList{
|
|||||||
if(Mathf.chance(0.04 * Time.delta())){
|
if(Mathf.chance(0.04 * Time.delta())){
|
||||||
Tile tile = world.tileWorld(b.x(), b.y());
|
Tile tile = world.tileWorld(b.x(), b.y());
|
||||||
if(tile != null){
|
if(tile != null){
|
||||||
//TODO implement
|
Fires.create(tile);
|
||||||
//Fire.create(tile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,8 +520,7 @@ public class Bullets implements ContentList{
|
|||||||
public void hit(Bulletc b, float hitx, float hity){
|
public void hit(Bulletc b, float hitx, float hity){
|
||||||
hitEffect.at(hitx, hity, colors[2]);
|
hitEffect.at(hitx, hity, colors[2]);
|
||||||
if(Mathf.chance(0.4)){
|
if(Mathf.chance(0.4)){
|
||||||
//TODO implement
|
Fires.create(world.tileWorld(hitx + Mathf.range(5f), hity + Mathf.range(5f)));
|
||||||
// Fire.create(world.tileWorld(hitx + Mathf.range(5f), hity + Mathf.range(5f)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,8 +639,7 @@ public class Bullets implements ContentList{
|
|||||||
|
|
||||||
for(int i = 0; i < 3; i++){
|
for(int i = 0; i < 3; i++){
|
||||||
Tile tile = world.tileWorld(x + Mathf.range(8f), y + Mathf.range(8f));
|
Tile tile = world.tileWorld(x + Mathf.range(8f), y + Mathf.range(8f));
|
||||||
//TODO implement
|
Puddles.deposit(tile, Liquids.oil, 5f);
|
||||||
//Puddle.deposit(tile, Liquids.oil, 5f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
32
core/src/mindustry/entities/AllDefs.java
Normal file
32
core/src/mindustry/entities/AllDefs.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package mindustry.entities;
|
||||||
|
|
||||||
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
class AllDefs{
|
||||||
|
|
||||||
|
@GroupDef(Entityc.class)
|
||||||
|
void all(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GroupDef(Playerc.class)
|
||||||
|
void player(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GroupDef(value = Unitc.class, spatial = true)
|
||||||
|
void unit(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GroupDef(Tilec.class)
|
||||||
|
void tile(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GroupDef(Syncc.class)
|
||||||
|
void sync(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package mindustry.entities;
|
|
||||||
|
|
||||||
import mindustry.annotations.Annotations.*;
|
|
||||||
import mindustry.gen.*;
|
|
||||||
|
|
||||||
class AllEntities{
|
|
||||||
|
|
||||||
@EntityDef(value = {Bulletc.class, Velc.class, Timedc.class}, pooled = true)
|
|
||||||
class BulletDef{}
|
|
||||||
|
|
||||||
@EntityDef(value = {Tilec.class}, isFinal = false)
|
|
||||||
class TileDef{}
|
|
||||||
|
|
||||||
@EntityDef(value = {StandardEffectc.class, Childc.class}, pooled = true)
|
|
||||||
class EffectDef{}
|
|
||||||
|
|
||||||
@EntityDef(value = {GroundEffectc.class, Childc.class}, pooled = true)
|
|
||||||
class GroundEffectDef{}
|
|
||||||
|
|
||||||
@EntityDef(value = {Decalc.class}, pooled = true)
|
|
||||||
class DecalDef{}
|
|
||||||
|
|
||||||
@EntityDef({Playerc.class})
|
|
||||||
class PlayerDef{}
|
|
||||||
|
|
||||||
@EntityDef({Unitc.class})
|
|
||||||
class GenericUnitDef{}
|
|
||||||
|
|
||||||
@EntityDef(value = {Firec.class}, pooled = true)
|
|
||||||
class FireDef{}
|
|
||||||
|
|
||||||
@GroupDef(Entityc.class)
|
|
||||||
void all(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@GroupDef(Playerc.class)
|
|
||||||
void player(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@GroupDef(value = Unitc.class, spatial = true)
|
|
||||||
void unit(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@GroupDef(Tilec.class)
|
|
||||||
void tile(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@GroupDef(Syncc.class)
|
|
||||||
void sync(){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -66,8 +66,7 @@ public class Damage{
|
|||||||
float cy = y + Mathf.range(range);
|
float cy = y + Mathf.range(range);
|
||||||
Tile tile = world.tileWorld(cx, cy);
|
Tile tile = world.tileWorld(cx, cy);
|
||||||
if(tile != null){
|
if(tile != null){
|
||||||
//TODO uncomment
|
Fires.create(tile);
|
||||||
//Fire.create(tile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class Effects{
|
|||||||
Rect pos = Tmp.r2.setSize(effect.size).setCenter(x, y);
|
Rect pos = Tmp.r2.setSize(effect.size).setCenter(x, y);
|
||||||
|
|
||||||
if(view.overlaps(pos)){
|
if(view.overlaps(pos)){
|
||||||
Effectc entity = effect.ground ? GroundEffectEntity.create() : EffectEntity.create();
|
Effectc entity = effect.ground ? GroundEffectEntity.create() : StandardEffectEntity.create();
|
||||||
entity.effect(effect);
|
entity.effect(effect);
|
||||||
entity.rotation(rotation);
|
entity.rotation(rotation);
|
||||||
entity.data(data);
|
entity.data(data);
|
||||||
|
|||||||
65
core/src/mindustry/entities/Fires.java
Normal file
65
core/src/mindustry/entities/Fires.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package mindustry.entities;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.game.EventType.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
public class Fires{
|
||||||
|
private static final float baseLifetime = 1000f;
|
||||||
|
private static final IntMap<Firec> map = new IntMap<>();
|
||||||
|
|
||||||
|
/** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */
|
||||||
|
public static void create(Tile tile){
|
||||||
|
if(net.client() || tile == null) return; //not clientside.
|
||||||
|
|
||||||
|
Firec fire = map.get(tile.pos());
|
||||||
|
|
||||||
|
if(fire == null){
|
||||||
|
fire = FireEntity.create();
|
||||||
|
fire.tile(tile);
|
||||||
|
fire.lifetime(baseLifetime);
|
||||||
|
fire.set(tile.worldx(), tile.worldy());
|
||||||
|
fire.add();
|
||||||
|
map.put(tile.pos(), fire);
|
||||||
|
}else{
|
||||||
|
fire.lifetime(baseLifetime);
|
||||||
|
fire.time(0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Firec get(int x, int y){
|
||||||
|
return map.get(Pos.get(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean has(int x, int y){
|
||||||
|
if(!Structs.inBounds(x, y, world.width(), world.height()) || !map.containsKey(Pos.get(x, y))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Firec fire = map.get(Pos.get(x, y));
|
||||||
|
return fire.isAdded() && fire.fin() < 1f && fire.tile() != null && fire.tile().x == x && fire.tile().y == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.
|
||||||
|
*/
|
||||||
|
public static void extinguish(Tile tile, float intensity){
|
||||||
|
if(tile != null && map.containsKey(tile.pos())){
|
||||||
|
Firec fire = map.get(tile.pos());
|
||||||
|
fire.time(fire.time() + intensity * Time.delta());
|
||||||
|
Fx.steam.at(fire);
|
||||||
|
if(fire.time() >= fire.lifetime()){
|
||||||
|
Events.fire(Trigger.fireExtinguish);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove(Tile tile){
|
||||||
|
map.remove(tile.pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
105
core/src/mindustry/entities/Puddles.java
Normal file
105
core/src/mindustry/entities/Puddles.java
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package mindustry.entities;
|
||||||
|
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.game.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
public class Puddles{
|
||||||
|
private static final IntMap<Puddlec> map = new IntMap<>();
|
||||||
|
|
||||||
|
public static final float maxLiquid = 70f;
|
||||||
|
|
||||||
|
/** Deposists a Puddlec between tile and source. */
|
||||||
|
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
|
deposit(tile, source, liquid, amount, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Deposists a Puddlec at a tile. */
|
||||||
|
public static void deposit(Tile tile, Liquid liquid, float amount){
|
||||||
|
deposit(tile, tile, liquid, amount, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the Puddlec on the specified tile. May return null. */
|
||||||
|
public static Puddlec get(Tile tile){
|
||||||
|
return map.get(tile.pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount, int generation){
|
||||||
|
if(tile == null) return;
|
||||||
|
|
||||||
|
if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){
|
||||||
|
reactPuddle(tile.floor().liquidDrop, liquid, amount, tile,
|
||||||
|
(tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
|
||||||
|
|
||||||
|
Puddlec p = map.get(tile.pos());
|
||||||
|
|
||||||
|
if(generation == 0 && p != null && p.lastRipple() <= Time.time() - 40f){
|
||||||
|
Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, tile.floor().liquidDrop.color);
|
||||||
|
p.lastRipple(Time.time());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Puddlec p = map.get(tile.pos());
|
||||||
|
if(p == null){
|
||||||
|
Puddlec puddle = PuddleEntity.create();
|
||||||
|
puddle.tile(tile);
|
||||||
|
puddle.liquid(liquid);
|
||||||
|
puddle.amount(amount);
|
||||||
|
puddle.generation(generation);
|
||||||
|
puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
|
||||||
|
puddle.add();
|
||||||
|
map.put(tile.pos(), puddle);
|
||||||
|
}else if(p.liquid() == liquid){
|
||||||
|
p.accepting(Math.max(amount, p.accepting()));
|
||||||
|
|
||||||
|
if(generation == 0 && p.lastRipple() <= Time.time() - 40f && p.amount() >= maxLiquid / 2f){
|
||||||
|
Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, p.liquid().color);
|
||||||
|
p.lastRipple(Time.time());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
p.amount(p.amount() + reactPuddle(p.liquid(), liquid, amount, p.tile(), p.x(), p.y()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove(Tile tile){
|
||||||
|
if(tile == null) return;
|
||||||
|
|
||||||
|
map.remove(tile.pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reacts two liquids together at a location. */
|
||||||
|
private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){
|
||||||
|
if((dest.flammability > 0.3f && liquid.temperature > 0.7f) ||
|
||||||
|
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid
|
||||||
|
Fires.create(tile);
|
||||||
|
if(Mathf.chance(0.006 * amount)){
|
||||||
|
Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), -1f, 1f, 1f);
|
||||||
|
}
|
||||||
|
}else if(dest.temperature > 0.7f && liquid.temperature < 0.55f){ //cold liquid poured onto hot Puddlec
|
||||||
|
if(Mathf.chance(0.5f * amount)){
|
||||||
|
Fx.steam.at(x, y);
|
||||||
|
}
|
||||||
|
return -0.1f * amount;
|
||||||
|
}else if(liquid.temperature > 0.7f && dest.temperature < 0.55f){ //hot liquid poured onto cold Puddlec
|
||||||
|
if(Mathf.chance(0.8f * amount)){
|
||||||
|
Fx.steam.at(x, y);
|
||||||
|
}
|
||||||
|
return -0.4f * amount;
|
||||||
|
}
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the first liquid can 'stay' on the second one.
|
||||||
|
* Currently, the only place where this can happen is oil on water.
|
||||||
|
*/
|
||||||
|
private static boolean canStayOn(Liquid liquid, Liquid other){
|
||||||
|
return liquid == Liquids.oil && other == Liquids.water;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,16 +29,16 @@ public class Units{
|
|||||||
* @param range The maximum distance from the target X/Y the targeter can be for it to be valid
|
* @param range The maximum distance from the target X/Y the targeter can be for it to be valid
|
||||||
* @return whether the target is invalid
|
* @return whether the target is invalid
|
||||||
*/
|
*/
|
||||||
public static boolean invalidateTarget(Teamc target, Team team, float x, float y, float range){
|
public static boolean invalidateTarget(Posc target, Team team, float x, float y, float range){
|
||||||
return target == null || (range != Float.MAX_VALUE && !target.withinDst(x, y, range)) || target.team() == team || (target instanceof Healthc && !((Healthc)target).isValid());
|
return target == null || !target.isAdded() || (range != Float.MAX_VALUE && !target.withinDst(x, y, range)) || (target instanceof Teamc && ((Teamc)target).team() == team) || (target instanceof Healthc && !((Healthc)target).isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link #invalidateTarget(Teamc, Team, float, float, float)} */
|
/** See {@link #invalidateTarget(Posc, Team, float, float, float)} */
|
||||||
public static boolean invalidateTarget(Teamc target, Team team, float x, float y){
|
public static boolean invalidateTarget(Posc target, Team team, float x, float y){
|
||||||
return invalidateTarget(target, team, x, y, Float.MAX_VALUE);
|
return invalidateTarget(target, team, x, y, Float.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link #invalidateTarget(Teamc, Team, float, float, float)} */
|
/** See {@link #invalidateTarget(Posc, Team, float, float, float)} */
|
||||||
public static boolean invalidateTarget(Teamc target, Unitc targeter, float range){
|
public static boolean invalidateTarget(Teamc target, Unitc targeter, float range){
|
||||||
return invalidateTarget(target, targeter.team(), targeter.x(), targeter.y(), range);
|
return invalidateTarget(target, targeter.team(), targeter.x(), targeter.y(), range);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import arc.graphics.g2d.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -47,13 +48,12 @@ public class LiquidBulletType extends BulletType{
|
|||||||
super.update(b);
|
super.update(b);
|
||||||
|
|
||||||
if(liquid.canExtinguish()){
|
if(liquid.canExtinguish()){
|
||||||
//TODO implement
|
|
||||||
Tile tile = world.tileWorld(b.x(), b.y());
|
Tile tile = world.tileWorld(b.x(), b.y());
|
||||||
//if(tile != null && Fire.has(tile.x, tile.y)){
|
if(tile != null && Fires.has(tile.x, tile.y)){
|
||||||
//Fire.extinguish(tile, 100f);
|
Fires.extinguish(tile, 100f);
|
||||||
// b.remove();
|
b.remove();
|
||||||
// hit(b);
|
hit(b);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +67,13 @@ public class LiquidBulletType extends BulletType{
|
|||||||
@Override
|
@Override
|
||||||
public void hit(Bulletc b, float hitx, float hity){
|
public void hit(Bulletc b, float hitx, float hity){
|
||||||
hitEffect.at(hitx, hity, liquid.color);
|
hitEffect.at(hitx, hity, liquid.color);
|
||||||
//TODO implement
|
Puddles.deposit(world.tileWorld(hitx, hity), liquid, puddleSize);
|
||||||
// Puddle.deposit(world.tileWorld(hitx, hity), liquid, puddleSize);
|
|
||||||
|
|
||||||
if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){
|
if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){
|
||||||
float intensity = 400f;
|
float intensity = 400f;
|
||||||
//Fire.extinguish(world.tileWorld(hitx, hity), intensity);
|
Fires.extinguish(world.tileWorld(hitx, hity), intensity);
|
||||||
for(Point2 p : Geometry.d4){
|
for(Point2 p : Geometry.d4){
|
||||||
// Fire.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity);
|
Fires.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import mindustry.world.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
@EntityDef(value = {Bulletc.class}, pooled = true)
|
||||||
@Component
|
@Component
|
||||||
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc, Timerc, DrawLayerBulletsc{
|
abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc, Timerc, DrawLayerBulletsc{
|
||||||
Object data;
|
Object data;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.math.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
@EntityDef(value = {Decalc.class}, pooled = true)
|
||||||
@Component
|
@Component
|
||||||
abstract class DecalComp implements Drawc, Timedc, Rotc, Posc, DrawLayerFloorc{
|
abstract class DecalComp implements Drawc, Timedc, Rotc, Posc, DrawLayerFloorc{
|
||||||
transient float x, y, rotation;
|
transient float x, y, rotation;
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
package mindustry.entities.def;
|
package mindustry.entities.def;
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.game.EventType.*;
|
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
@EntityDef(value = {Firec.class}, pooled = true)
|
||||||
@Component
|
@Component
|
||||||
abstract class FireComp implements Timedc, Posc, Firec{
|
abstract class FireComp implements Timedc, Posc, Firec{
|
||||||
private static final IntMap<Firec> map = new IntMap<>();
|
private static final float spreadChance = 0.05f, fireballChance = 0.07f;
|
||||||
private static final float baseLifetime = 1000f, spreadChance = 0.05f, fireballChance = 0.07f;
|
|
||||||
|
|
||||||
transient float time, lifetime, x, y;
|
transient float time, lifetime, x, y;
|
||||||
|
|
||||||
@@ -27,46 +24,6 @@ abstract class FireComp implements Timedc, Posc, Firec{
|
|||||||
private Block block;
|
private Block block;
|
||||||
private float baseFlammability = -1, puddleFlammability;
|
private float baseFlammability = -1, puddleFlammability;
|
||||||
|
|
||||||
/** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */
|
|
||||||
public static void create(Tile tile){
|
|
||||||
if(net.client() || tile == null) return; //not clientside.
|
|
||||||
|
|
||||||
Firec fire = map.get(tile.pos());
|
|
||||||
|
|
||||||
if(fire == null){
|
|
||||||
fire = FireEntity.create();
|
|
||||||
fire.tile(tile);
|
|
||||||
fire.lifetime(baseLifetime);
|
|
||||||
fire.set(tile.worldx(), tile.worldy());
|
|
||||||
fire.add();
|
|
||||||
map.put(tile.pos(), fire);
|
|
||||||
}else{
|
|
||||||
fire.lifetime(baseLifetime);
|
|
||||||
fire.time(0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean has(int x, int y){
|
|
||||||
if(!Structs.inBounds(x, y, world.width(), world.height()) || !map.containsKey(Pos.get(x, y))){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Firec fire = map.get(Pos.get(x, y));
|
|
||||||
return fire.isAdded() && fire.fin() < 1f && fire.tile() != null && fire.tile().x == x && fire.tile().y == y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing.
|
|
||||||
*/
|
|
||||||
public static void extinguish(Tile tile, float intensity){
|
|
||||||
if(tile != null && map.containsKey(tile.pos())){
|
|
||||||
Firec fire = map.get(tile.pos());
|
|
||||||
fire.time(fire.time() + intensity * Time.delta());
|
|
||||||
if(fire.time() >= fire.lifetime()){
|
|
||||||
Events.fire(Trigger.fireExtinguish);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
if(Mathf.chance(0.1 * Time.delta())){
|
if(Mathf.chance(0.1 * Time.delta())){
|
||||||
@@ -82,7 +39,6 @@ abstract class FireComp implements Timedc, Posc, Firec{
|
|||||||
}
|
}
|
||||||
|
|
||||||
time = Mathf.clamp(time + Time.delta(), 0, lifetime());
|
time = Mathf.clamp(time + Time.delta(), 0, lifetime());
|
||||||
map.put(tile.pos(), this);
|
|
||||||
|
|
||||||
if(Vars.net.client()){
|
if(Vars.net.client()){
|
||||||
return;
|
return;
|
||||||
@@ -114,7 +70,7 @@ abstract class FireComp implements Timedc, Posc, Firec{
|
|||||||
if(flammability > 1f && Mathf.chance(spreadChance * Time.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){
|
if(flammability > 1f && Mathf.chance(spreadChance * Time.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){
|
||||||
Point2 p = Geometry.d4[Mathf.random(3)];
|
Point2 p = Geometry.d4[Mathf.random(3)];
|
||||||
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
|
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
|
||||||
create(other);
|
Fires.create(other);
|
||||||
|
|
||||||
if(Mathf.chance(fireballChance * Time.delta() * Mathf.clamp(flammability / 10f))){
|
if(Mathf.chance(fireballChance * Time.delta() * Mathf.clamp(flammability / 10f))){
|
||||||
Bullets.fireball.createNet(Team.derelict, x, y, Mathf.random(360f), -1f, 1, 1);
|
Bullets.fireball.createNet(Team.derelict, x, y, Mathf.random(360f), -1f, 1, 1);
|
||||||
@@ -122,13 +78,8 @@ abstract class FireComp implements Timedc, Posc, Firec{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Mathf.chance(0.1 * Time.delta())){
|
if(Mathf.chance(0.1 * Time.delta())){
|
||||||
//TODO implement
|
Puddlec p = Puddles.get(tile);
|
||||||
//Puddle p = Puddle.getPuddle(tile);
|
puddleFlammability = p != null ? p.getFlammability() / 3f : 0;
|
||||||
//if(p != null){
|
|
||||||
// puddleFlammability = p.getFlammability() / 3f;
|
|
||||||
//}else{
|
|
||||||
puddleFlammability = 0;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if(damage){
|
if(damage){
|
||||||
entity.damage(0.4f);
|
entity.damage(0.4f);
|
||||||
@@ -141,7 +92,7 @@ abstract class FireComp implements Timedc, Posc, Firec{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(){
|
public void remove(){
|
||||||
map.remove(tile.pos());
|
Fires.remove(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package mindustry.entities.def;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
@EntityDef(value = {GroundEffectc.class, Childc.class}, pooled = true)
|
||||||
@Component
|
@Component
|
||||||
abstract class GroundEffectComp implements Effectc, DrawLayerFloorOverc{
|
abstract class GroundEffectComp implements Effectc, DrawLayerFloorOverc{
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import mindustry.ui.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
@EntityDef({Playerc.class})
|
||||||
@Component
|
@Component
|
||||||
abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc{
|
abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc{
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|||||||
119
core/src/mindustry/entities/def/PuddleComp.java
Normal file
119
core/src/mindustry/entities/def/PuddleComp.java
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package mindustry.entities.def;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.world;
|
||||||
|
import static mindustry.entities.Puddles.maxLiquid;
|
||||||
|
|
||||||
|
@EntityDef(value = {Puddlec.class}, pooled = true)
|
||||||
|
@Component
|
||||||
|
abstract class PuddleComp implements Posc, DrawLayerFloorOverc{
|
||||||
|
private static final int maxGeneration = 2;
|
||||||
|
private static final Color tmp = new Color();
|
||||||
|
private static final Rect rect = new Rect();
|
||||||
|
private static final Rect rect2 = new Rect();
|
||||||
|
private static int seeds;
|
||||||
|
|
||||||
|
transient float x, y;
|
||||||
|
|
||||||
|
float amount, lastRipple, accepting, updateTime;
|
||||||
|
int generation;
|
||||||
|
Tile tile;
|
||||||
|
Liquid liquid;
|
||||||
|
|
||||||
|
public float getFlammability(){
|
||||||
|
return liquid.flammability * amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(){
|
||||||
|
//update code
|
||||||
|
float addSpeed = accepting > 0 ? 3f : 0f;
|
||||||
|
|
||||||
|
amount -= Time.delta() * (1f - liquid.viscosity) / (5f + addSpeed);
|
||||||
|
|
||||||
|
amount += accepting;
|
||||||
|
accepting = 0f;
|
||||||
|
|
||||||
|
if(amount >= maxLiquid / 1.5f && generation < maxGeneration){
|
||||||
|
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta();
|
||||||
|
for(Point2 point : Geometry.d4){
|
||||||
|
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
||||||
|
if(other != null && other.block() == Blocks.air){
|
||||||
|
Puddles.deposit(other, tile, liquid, deposited, generation + 1);
|
||||||
|
amount -= deposited / 2f; //tweak to speed up/slow down Puddlec propagation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amount = Mathf.clamp(amount, 0, maxLiquid);
|
||||||
|
|
||||||
|
if(amount <= 0f){
|
||||||
|
remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
//effects-only code
|
||||||
|
if(amount >= maxLiquid / 2f && updateTime <= 0f){
|
||||||
|
Units.nearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> {
|
||||||
|
if(unit.isGrounded()){
|
||||||
|
unit.hitbox(rect2);
|
||||||
|
if(rect.overlaps(rect2)){
|
||||||
|
unit.apply(liquid.effect, 60 * 2);
|
||||||
|
|
||||||
|
if(unit.vel().len() > 0.1){
|
||||||
|
Fx.ripple.at(unit.x(), unit.y(), liquid.color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(liquid.temperature > 0.7f && (tile.link().entity != null) && Mathf.chance(0.3 * Time.delta())){
|
||||||
|
Fires.create(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTime = 20f;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTime -= Time.delta();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawFloorOver(){
|
||||||
|
seeds = id();
|
||||||
|
boolean onLiquid = tile.floor().isLiquid;
|
||||||
|
float f = Mathf.clamp(amount / (maxLiquid / 1.5f));
|
||||||
|
float smag = onLiquid ? 0.8f : 0f;
|
||||||
|
float sscl = 20f;
|
||||||
|
|
||||||
|
Draw.color(tmp.set(liquid.color).shiftValue(-0.05f));
|
||||||
|
Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f);
|
||||||
|
Angles.randLenVectors(id(), 3, f * 6f, (ex, ey) -> {
|
||||||
|
Fill.circle(x + ex + Mathf.sin(Time.time() + seeds * 532, sscl, smag),
|
||||||
|
y + ey + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 5f);
|
||||||
|
seeds++;
|
||||||
|
});
|
||||||
|
Draw.color();
|
||||||
|
|
||||||
|
if(liquid.lightColor.a > 0.001f && f > 0){
|
||||||
|
Color color = liquid.lightColor;
|
||||||
|
float opacity = color.a * f;
|
||||||
|
Vars.renderer.lights.add(tile.drawx(), tile.drawy(), 30f * f, color, opacity * 0.8f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(){
|
||||||
|
Puddles.remove(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package mindustry.entities.def;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
@EntityDef(value = {StandardEffectc.class, Childc.class}, pooled = true)
|
||||||
@Component
|
@Component
|
||||||
abstract class StandardEffectComp implements Effectc, DrawLayerEffectsc{
|
abstract class StandardEffectComp implements Effectc, DrawLayerEffectsc{
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import mindustry.world.modules.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
@EntityDef(value = {Tilec.class}, isFinal = false)
|
||||||
@Component
|
@Component
|
||||||
abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
||||||
static final float timeToSleep = 60f * 1;
|
static final float timeToSleep = 60f * 1;
|
||||||
|
|||||||
@@ -630,8 +630,7 @@ public class Block extends BlockStorage{
|
|||||||
Time.run(i / 2f, () -> {
|
Time.run(i / 2f, () -> {
|
||||||
Tile other = world.tile(tile.x + Mathf.range(size / 2), tile.y + Mathf.range(size / 2));
|
Tile other = world.tile(tile.x + Mathf.range(size / 2), tile.y + Mathf.range(size / 2));
|
||||||
if(other != null){
|
if(other != null){
|
||||||
//TODO puddle
|
Puddles.deposit(other, liquid, splash);
|
||||||
//Puddle.deposit(other, liquid, splash);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import arc.util.*;
|
|||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.consumers.*;
|
import mindustry.world.consumers.*;
|
||||||
@@ -176,8 +177,7 @@ public abstract class BlockStorage extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
}else if(leakResistance != 100f && !next.block().solid && !next.block().hasLiquids){
|
}else if(leakResistance != 100f && !next.block().solid && !next.block().hasLiquids){
|
||||||
float leakAmount = tile.entity.liquids().get(liquid) / leakResistance;
|
float leakAmount = tile.entity.liquids().get(liquid) / leakResistance;
|
||||||
//TODO deposit puddle
|
Puddles.deposit(next, tile, liquid, leakAmount);
|
||||||
//Puddle.deposit(next, tile, liquid, leakAmount);
|
|
||||||
tile.entity.liquids().remove(liquid, leakAmount);
|
tile.entity.liquids().remove(liquid, leakAmount);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -67,16 +67,6 @@ public class LiquidTurret extends Turret{
|
|||||||
return entity.target != null && hasAmmo(tile);
|
return entity.target != null && hasAmmo(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean validateTarget(Tile tile){
|
|
||||||
TurretEntity entity = tile.ent();
|
|
||||||
if(entity.liquids().current().canExtinguish() && entity.target instanceof Tile){
|
|
||||||
//TODO fix
|
|
||||||
//return Fire.has(((Tile)entity.target).x, ((Tile)entity.target).y);
|
|
||||||
}
|
|
||||||
return super.validateTarget(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void findTarget(Tile tile){
|
protected void findTarget(Tile tile){
|
||||||
TurretEntity entity = tile.ent();
|
TurretEntity entity = tile.ent();
|
||||||
@@ -84,10 +74,10 @@ public class LiquidTurret extends Turret{
|
|||||||
int tr = (int)(range / tilesize);
|
int tr = (int)(range / tilesize);
|
||||||
for(int x = -tr; x <= tr; x++){
|
for(int x = -tr; x <= tr; x++){
|
||||||
for(int y = -tr; y <= tr; y++){
|
for(int y = -tr; y <= tr; y++){
|
||||||
//if(Fire.has(x + tile.x, y + tile.y)){
|
if(Fires.has(x + tile.x, y + tile.y)){
|
||||||
// entity.target = world.tile(x + tile.x, y + tile.y);
|
entity.target = Fires.get(x + tile.x, y + tile.y);
|
||||||
// return;
|
return;
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +93,7 @@ public class LiquidTurret extends Turret{
|
|||||||
|
|
||||||
type.shootEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color);
|
type.shootEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color);
|
||||||
type.smokeEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color);
|
type.smokeEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color);
|
||||||
//shootSound.at(tile);
|
shootSound.at(tile);
|
||||||
|
|
||||||
if(shootShake > 0){
|
if(shootShake > 0){
|
||||||
Effects.shake(shootShake, shootShake, tile.entity);
|
Effects.shake(shootShake, shootShake, tile.entity);
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ public abstract class Turret extends Block{
|
|||||||
public float recoil = 0f;
|
public float recoil = 0f;
|
||||||
public float heat;
|
public float heat;
|
||||||
public int shots;
|
public int shots;
|
||||||
public Teamc target;
|
public Posc target;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput stream) throws IOException{
|
public void write(DataOutput stream) throws IOException{
|
||||||
|
|||||||
Reference in New Issue
Block a user