Support for weather in rules / Sector weather

This commit is contained in:
Anuken
2020-05-08 21:51:17 -04:00
parent d7eb365446
commit 95a1d84eb9
30 changed files with 141 additions and 29 deletions

View File

@ -1 +0,0 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:damage,type:float,size:4},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:time,type:float,size:4},{name:type,type:mindustry.entities.bullet.BulletType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:lifetime,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:baseFlammability,type:float,size:4},{name:block,type:mindustry.world.Block,size:-1},{name:lifetime,type:float,size:4},{name:puddleFlammability,type:float,size:4},{name:tile,type:mindustry.world.Tile,size:-1},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:baseRotation,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:admin,type:boolean,size:1},{name:color,type:arc.graphics.Color,size:-1},{name:lastText,type:java.lang.String,size:-1},{name:mouseX,type:float,size:4},{name:mouseY,type:float,size:4},{name:name,type:java.lang.String,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:textFadeTime,type:float,size:4},{name:typing,type:boolean,size:1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:admin,type:boolean,size:1},{name:color,type:arc.graphics.Color,size:-1},{name:deathTimer,type:float,size:4},{name:lastText,type:java.lang.String,size:-1},{name:mouseX,type:float,size:4},{name:mouseY,type:float,size:4},{name:name,type:java.lang.String,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:textFadeTime,type:float,size:4},{name:typing,type:boolean,size:1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:accepting,type:float,size:4},{name:amount,type:float,size:4},{name:generation,type:int,size:4},{name:lastRipple,type:float,size:4},{name:liquid,type:mindustry.type.Liquid,size:-1},{name:tile,type:mindustry.world.Tile,size:-1},{name:updateTime,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:health,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{fields:[{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:1,fields:[{name:intensity,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

View File

@ -1 +0,0 @@
{version:2,fields:[{name:intensity,type:float,size:4},{name:opacity,type:float,size:4},{name:weather,type:mindustry.type.Weather,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}

Binary file not shown.

View File

@ -1,6 +1,7 @@
package mindustry.core;
import arc.*;
import arc.math.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
@ -11,6 +12,7 @@ import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.type.*;
import mindustry.type.Weather.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.BuildBlock.*;
@ -167,6 +169,21 @@ public class Logic implements ApplicationListener{
}
}
private void updateWeather(){
for(WeatherEntry entry : state.rules.weather){
//update cooldown
entry.cooldown -= Time.delta();
//create new event when not active
if(entry.cooldown < 0 && !entry.weather.isActive()){
float duration = Mathf.random(entry.minDuration, entry.maxDuration);
entry.cooldown = duration + Mathf.random(entry.minFrequency, entry.maxFrequency);
entry.weather.create(entry.intensity, duration);
}
}
}
@Remote(called = Loc.both)
public static void launchZone(){
if(!headless){
@ -220,6 +237,7 @@ public class Logic implements ApplicationListener{
universe.update();
}
Time.update();
updateWeather();
if(state.rules.waves && state.rules.waveTimer && !state.gameOver){
if(!state.rules.waitForWaveToEnd || state.enemies == 0){

View File

@ -8,6 +8,7 @@ import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import arc.util.noise.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
@ -18,6 +19,8 @@ import mindustry.maps.*;
import mindustry.maps.filters.*;
import mindustry.maps.filters.GenerateFilter.*;
import mindustry.type.*;
import mindustry.type.Sector.*;
import mindustry.type.Weather.*;
import mindustry.world.*;
import mindustry.world.blocks.legacy.*;
@ -208,12 +211,25 @@ public class World{
}
public void loadSector(Sector sector){
state.map = new Map(StringMap.of("name", sector.planet.localizedName + "; Sector " + sector.id));
state.rules.sector = sector;
setSectorRules(sector);
int size = sector.getSize();
loadGenerator(size, size, tiles -> sector.planet.generator.generate(tiles, sector));
}
private void setSectorRules(Sector sector){
state.map = new Map(StringMap.of("name", sector.planet.localizedName + "; Sector " + sector.id));
state.rules.sector = sector;
if(sector.is(SectorAttribute.rainy)){
state.rules.weather.add(new WeatherEntry(Weathers.rain));
}
if(sector.is(SectorAttribute.snowy)){
state.rules.weather.add(new WeatherEntry(Weathers.snow));
}
}
public void loadMap(Map map){
loadMap(map, new Rules());
}

View File

@ -10,7 +10,7 @@ import mindustry.graphics.Pal;
public class MissileBulletType extends BasicBulletType{
protected Color trailColor = Pal.missileYellowBack;
protected float weaveScale = 0f;
protected float weaveScale = 1f;
protected float weaveMag = -1f;
public MissileBulletType(float speed, float damage, String bulletSprite){
@ -34,7 +34,7 @@ public class MissileBulletType extends BasicBulletType{
}
if(weaveMag > 0){
b.vel().rotate(Mathf.sin(Time.time() + b.id() * 442, weaveScale, weaveMag) * Time.delta());
b.vel().rotate(Mathf.sin(Time.time() + b.id() * 3, weaveScale, weaveMag) * Time.delta());
}
}
}

View File

@ -5,6 +5,7 @@ import mindustry.gen.*;
@Component
abstract class DrawComp implements Posc{
abstract float clipSize();
void draw(){

View File

@ -7,6 +7,7 @@ import arc.graphics.*;
import mindustry.content.*;
import mindustry.io.*;
import mindustry.type.*;
import mindustry.type.Weather.*;
import mindustry.world.*;
/**
@ -82,6 +83,8 @@ public class Rules{
public boolean drawDarkness = true;
/** Starting items put in cores */
public Array<ItemStack> loadout = Array.with(ItemStack.with(Items.copper, 100));
/** Weather events that occur here. */
public Array<WeatherEntry> weather = new Array<>(1);
/** Blocks that cannot be placed. */
public ObjectSet<Block> bannedBlocks = new ObjectSet<>();
/** Whether everything is dark. Enables lights. Experimental. */

View File

@ -6,8 +6,9 @@ import arc.util.*;
import mindustry.content.*;
import mindustry.type.*;
import static mindustry.Vars.*;
import static mindustry.Vars.state;
/** Updates the campaign universe. Has no relevance to other gamemodes. */
public class Universe{
private long seconds;
private float secondCounter;
@ -48,6 +49,7 @@ public class Universe{
//update sector light
float light = state.getSector().getLight();
float alpha = Mathf.clamp(Mathf.map(light, 0f, 0.8f, 0.1f, 1f));
//assign and map so darkness is not 100% dark
state.rules.ambientLight.a = 1f - alpha;
state.rules.lighting = !Mathf.equal(alpha, 1f);

View File

@ -68,6 +68,8 @@ public class JsonIO{
json.setElementType(Rules.class, "spawns", SpawnGroup.class);
json.setElementType(Rules.class, "loadout", ItemStack.class);
//TODO this is terrible
json.setSerializer(Sector.class, new Serializer<Sector>(){
@Override
public void write(Json json, Sector object, Class knownType){
@ -131,6 +133,18 @@ public class JsonIO{
}
});
json.setSerializer(Weather.class, new Serializer<Weather>(){
@Override
public void write(Json json, Weather object, Class knownType){
json.writeValue(object.name);
}
@Override
public Weather read(Json json, JsonValue jsonData, Class type){
return Vars.content.getByName(ContentType.weather, jsonData.asString());
}
});
json.setSerializer(ItemStack.class, new Serializer<ItemStack>(){
@Override
public void write(Json json, ItemStack object, Class knownType){

View File

@ -241,7 +241,7 @@ public abstract class SaveVersion extends SaveFileReader{
Array<TeamData> data = state.teams.getActive();
stream.writeInt(data.size);
for(TeamData team : data){
stream.writeInt((int)team.team.id);
stream.writeInt(team.team.id);
stream.writeInt(team.brokenBlocks.size);
for(BrokenBlock block : team.brokenBlocks){
stream.writeShort(block.x);

View File

@ -171,6 +171,10 @@ public class Sector{
public enum SectorAttribute{
/** Requires naval technology to land on, e.g. mostly water */
naval
naval,
/** Has rain. */
rainy,
/** Has snow. */
snowy
}
}

View File

@ -3,6 +3,7 @@ package mindustry.type;
import arc.func.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.gen.*;
@ -11,7 +12,10 @@ import mindustry.graphics.*;
import static mindustry.Vars.renderer;
public abstract class Weather extends MappableContent{
protected float duration = 100f;
/** Default duration of this weather event in ticks. */
public float duration = 15f * Time.toMinutes;
//internals
protected Rand rand = new Rand();
protected Prov<Weatherc> type = WeatherEntity::create;
@ -24,10 +28,25 @@ public abstract class Weather extends MappableContent{
super(name);
}
public void create(){
public Weatherc create(){
return create(1f);
}
public Weatherc create(float intensity){
return create(intensity, duration);
}
public Weatherc create(float intensity, float duration){
Weatherc entity = type.get();
entity.intensity(intensity);
entity.init(this);
entity.life(duration);
entity.add();
return entity;
}
public boolean isActive(){
return Groups.weather.find(w -> w.weather() == this) != null;
}
public void remove(){
@ -48,11 +67,44 @@ public abstract class Weather extends MappableContent{
return ContentType.weather;
}
public static class WeatherEntry{
/** The type of weather used. */
public Weather weather;
/** Minimum and maximum spacing between weather events. Does not include the time of the event itself. */
public float minFrequency, maxFrequency, minDuration, maxDuration;
/** Cooldown time before the next weather event takes place. */
public float cooldown;
/** Intensity of the weather produced. */
public float intensity = 1f;
/** Creates a weather entry with some approximate weather values. */
public WeatherEntry(Weather weather){
this(weather, weather.duration/2f, weather.duration * 1.5f, weather.duration/2f, weather.duration * 1.5f);
}
public WeatherEntry(Weather weather, float minFrequency, float maxFrequency, float minDuration, float maxDuration){
this.weather = weather;
this.minFrequency = minFrequency;
this.maxFrequency = maxFrequency;
this.minDuration = minDuration;
this.maxDuration = maxDuration;
//specifies cooldown to something random
this.cooldown = Mathf.random(minFrequency, maxFrequency);
}
//mods
public WeatherEntry(){
}
}
@EntityDef(value = {Weatherc.class}, pooled = true, isFinal = false)
@Component
abstract class WeatherComp implements Posc, Drawc{
abstract class WeatherComp implements Drawc{
private static final float fadeTime = 60 * 4;
Weather weather;
float intensity = 1f, opacity = 1f;
float intensity = 1f, opacity = 1f, life;
void init(Weather weather){
this.weather = weather;
@ -60,6 +112,14 @@ public abstract class Weather extends MappableContent{
@Override
public void update(){
if(life < fadeTime){
opacity = life / fadeTime;
}else{
opacity = Mathf.lerpDelta(opacity, 1f, 0.02f);
}
life -= Time.delta();
weather.update((Weatherc)this);
}

View File

@ -117,6 +117,18 @@ public class SectorDataGenerator{
data.floors[i] = entries.get(i).key;
}
//TODO bad code
boolean hasSnow = data.floors[0].name.contains("ice") || data.floors[0].name.contains("snow");
boolean hasRain = !hasSnow && data.floors[0].name.contains("water");
if(hasSnow){
data.attributes |= (1 << SectorAttribute.snowy.ordinal());
}
if(hasRain){
data.attributes |= (1 << SectorAttribute.rainy.ordinal());
}
data.resources = content.asArray().sort(Structs.comps(Structs.comparing(Content::getContentType), Structs.comparingInt(c -> c.id))).toArray(UnlockableContent.class);
//50% water -> naval attribute