mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-08-02 16:09:38 +07:00
Support for weather in rules / Sector weather
This commit is contained in:
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -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}]}
|
@ -1 +0,0 @@
|
||||
{fields:[{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
@ -1 +0,0 @@
|
||||
{version:1,fields:[{name:intensity,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
@ -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.
@ -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){
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import mindustry.gen.*;
|
||||
|
||||
@Component
|
||||
abstract class DrawComp implements Posc{
|
||||
|
||||
abstract float clipSize();
|
||||
|
||||
void draw(){
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user