Modding improvements
This commit is contained in:
@@ -781,7 +781,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
copperWallLarge = new Wall("copper-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(copperWall.buildRequirements, 4));
|
||||
requirements(Category.defense, ItemStack.mult(copperWall.requirements, 4));
|
||||
health = 80 * 4 * wallHealthMultiplier;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -792,7 +792,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
titaniumWallLarge = new Wall("titanium-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(titaniumWall.buildRequirements, 4));
|
||||
requirements(Category.defense, ItemStack.mult(titaniumWall.requirements, 4));
|
||||
health = 110 * wallHealthMultiplier * 4;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -803,7 +803,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
thoriumWallLarge = new Wall("thorium-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(thoriumWall.buildRequirements, 4));
|
||||
requirements(Category.defense, ItemStack.mult(thoriumWall.requirements, 4));
|
||||
health = 200 * wallHealthMultiplier * 4;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -814,7 +814,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
phaseWallLarge = new DeflectorWall("phase-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(phaseWall.buildRequirements, 4));
|
||||
requirements(Category.defense, ItemStack.mult(phaseWall.requirements, 4));
|
||||
health = 150 * 4 * wallHealthMultiplier;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -825,7 +825,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
surgeWallLarge = new SurgeWall("surge-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(surgeWall.buildRequirements, 4));
|
||||
requirements(Category.defense, ItemStack.mult(surgeWall.requirements, 4));
|
||||
health = 230 * 4 * wallHealthMultiplier;
|
||||
size = 2;
|
||||
}};
|
||||
@@ -836,7 +836,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
doorLarge = new Door("door-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(door.buildRequirements, 4));
|
||||
requirements(Category.defense, ItemStack.mult(door.requirements, 4));
|
||||
openfx = Fx.dooropenlarge;
|
||||
closefx = Fx.doorcloselarge;
|
||||
health = 100 * 4 * wallHealthMultiplier;
|
||||
|
||||
@@ -303,9 +303,9 @@ public class TechTree implements ContentList{
|
||||
}
|
||||
|
||||
private TechNode node(Block block, Runnable children){
|
||||
ItemStack[] requirements = new ItemStack[block.buildRequirements.length];
|
||||
ItemStack[] requirements = new ItemStack[block.requirements.length];
|
||||
for(int i = 0; i < requirements.length; i++){
|
||||
requirements[i] = new ItemStack(block.buildRequirements[i].item, 30 + block.buildRequirements[i].amount * 6);
|
||||
requirements[i] = new ItemStack(block.requirements[i].item, 30 + block.requirements[i].amount * 6);
|
||||
}
|
||||
|
||||
return new TechNode(block, requirements, children);
|
||||
|
||||
@@ -58,37 +58,11 @@ public class ContentLoader{
|
||||
list.load();
|
||||
}
|
||||
|
||||
setupMapping();
|
||||
|
||||
if(mods != null){
|
||||
mods.loadContent();
|
||||
}
|
||||
|
||||
setupMapping();
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
private void setupMapping(){
|
||||
|
||||
for(ContentType type : ContentType.values()){
|
||||
contentNameMap[type.ordinal()].clear();
|
||||
}
|
||||
|
||||
for(ContentType type : ContentType.values()){
|
||||
|
||||
for(Content c : contentMap[type.ordinal()]){
|
||||
if(c instanceof MappableContent){
|
||||
String name = ((MappableContent)c).name;
|
||||
if(contentNameMap[type.ordinal()].containsKey(name)){
|
||||
throw new IllegalArgumentException("Two content objects cannot have the same name! (issue: '" + name + "')");
|
||||
}
|
||||
contentNameMap[type.ordinal()].put(name, (MappableContent)c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//set up ID mapping
|
||||
//check up ID mapping, make sure it's linear
|
||||
for(Array<Content> arr : contentMap){
|
||||
for(int i = 0; i < arr.size; i++){
|
||||
int id = arr.get(i).id;
|
||||
@@ -97,6 +71,8 @@ public class ContentLoader{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
/** Logs content statistics.*/
|
||||
@@ -125,6 +101,7 @@ public class ContentLoader{
|
||||
|
||||
for(ContentType type : ContentType.values()){
|
||||
for(Content content : contentMap[type.ordinal()]){
|
||||
//TODO catch error and display it per mod
|
||||
callable.accept(content);
|
||||
}
|
||||
}
|
||||
@@ -154,6 +131,14 @@ public class ContentLoader{
|
||||
|
||||
public void handleContent(Content content){
|
||||
contentMap[content.getContentType().ordinal()].add(content);
|
||||
|
||||
}
|
||||
|
||||
public void handleMappableContent(MappableContent content){
|
||||
if(contentNameMap[content.getContentType().ordinal()].containsKey(content.name)){
|
||||
throw new IllegalArgumentException("Two content objects cannot have the same name! (issue: '" + content.name + "')");
|
||||
}
|
||||
contentNameMap[content.getContentType().ordinal()].put(content.name, content);
|
||||
}
|
||||
|
||||
public void setTemporaryMapper(MappableContent[][] temporaryMapper){
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.mindustry.*;
|
||||
|
||||
public abstract class MappableContent extends Content{
|
||||
public final String name;
|
||||
|
||||
public MappableContent(String name){
|
||||
this.name = name;
|
||||
Vars.content.handleMappableContent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,6 +13,7 @@ import io.anuke.mindustry.entities.Effects.*;
|
||||
import io.anuke.mindustry.entities.bullet.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.mod.Mods.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
@@ -24,6 +25,10 @@ public class ContentParser{
|
||||
put(BulletType.class, (type, data) -> field(Bullets.class, data));
|
||||
put(Effect.class, (type, data) -> field(Fx.class, data));
|
||||
}};
|
||||
/** Stores things that need to be parsed fully, e.g. reading fields of content.
|
||||
* This is done to accomodate binding of content names first.*/
|
||||
private Array<Runnable> reads = new Array<>();
|
||||
private LoadedMod currentMod;
|
||||
|
||||
private Json parser = new Json(){
|
||||
public <T> T readValue(Class<T> type, Class elementType, JsonValue jsonData){
|
||||
@@ -33,7 +38,11 @@ public class ContentParser{
|
||||
}
|
||||
|
||||
if(Content.class.isAssignableFrom(type)){
|
||||
return (T)Vars.content.getByName(contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName())), jsonData.asString());
|
||||
ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName()));
|
||||
String prefix = currentMod != null ? currentMod.name + "-" : "";
|
||||
T one = (T)Vars.content.getByName(ctype, prefix + jsonData.asString());
|
||||
if(one != null) return one;
|
||||
return (T)Vars.content.getByName(ctype, jsonData.asString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,21 +52,37 @@ public class ContentParser{
|
||||
|
||||
private ObjectMap<ContentType, TypeParser<?>> parsers = ObjectMap.of(
|
||||
ContentType.block, (TypeParser<Block>)(mod, name, value) -> {
|
||||
Class<Block> type = resolve(value.getString("type"), "io.anuke.mindustry.world", "io.anuke.mindustry.world.blocks", "io.anuke.mindustry.world.blocks.defense");
|
||||
Block block = type.getDeclaredConstructor(String.class).newInstance(mod + "-" + name);
|
||||
readFields(block, value, true);
|
||||
//TODO generate dynamically instead of doing.. this
|
||||
Class<? extends Block> type = resolve(value.getString("type"),
|
||||
"io.anuke.mindustry.world",
|
||||
"io.anuke.mindustry.world.blocks",
|
||||
"io.anuke.mindustry.world.blocks.defense",
|
||||
"io.anuke.mindustry.world.blocks.defense.turrets",
|
||||
"io.anuke.mindustry.world.blocks.distribution",
|
||||
"io.anuke.mindustry.world.blocks.logic",
|
||||
"io.anuke.mindustry.world.blocks.power",
|
||||
"io.anuke.mindustry.world.blocks.production",
|
||||
"io.anuke.mindustry.world.blocks.sandbox",
|
||||
"io.anuke.mindustry.world.blocks.storage",
|
||||
"io.anuke.mindustry.world.blocks.units"
|
||||
);
|
||||
|
||||
//make block visible
|
||||
if(block.buildRequirements != null){
|
||||
block.buildVisibility = () -> true;
|
||||
}
|
||||
Block block = type.getDeclaredConstructor(String.class).newInstance(mod + "-" + name);
|
||||
read(() -> {
|
||||
readFields(block, value, true);
|
||||
|
||||
//make block visible
|
||||
if(block.requirements != null){
|
||||
block.buildVisibility = () -> true;
|
||||
}
|
||||
});
|
||||
|
||||
return block;
|
||||
},
|
||||
ContentType.unit, (TypeParser<UnitType>)(mod, name, value) -> {
|
||||
Class<BaseUnit> type = resolve(value.getString("type"), "io.anuke.mindustry.entities.type.base");
|
||||
UnitType unit = new UnitType(mod + "-" + name, supply(type));
|
||||
readFields(unit, value, true);
|
||||
read(() -> readFields(unit, value, true));
|
||||
|
||||
return unit;
|
||||
},
|
||||
@@ -75,11 +100,19 @@ public class ContentParser{
|
||||
}else{
|
||||
item = constructor.get(mod + "-" + name);
|
||||
}
|
||||
readFields(item, value);
|
||||
read(() -> readFields(item, value));
|
||||
return item;
|
||||
};
|
||||
}
|
||||
|
||||
private void read(Runnable run){
|
||||
LoadedMod mod = currentMod;
|
||||
reads.add(() -> {
|
||||
this.currentMod = mod;
|
||||
run.run();
|
||||
});
|
||||
}
|
||||
|
||||
private void init(){
|
||||
for(ContentType type : ContentType.all){
|
||||
Array<Content> arr = Vars.content.getBy(type);
|
||||
@@ -95,6 +128,11 @@ public class ContentParser{
|
||||
}
|
||||
}
|
||||
|
||||
public void finishParsing(){
|
||||
reads.each(Runnable::run);
|
||||
reads.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses content from a json file.
|
||||
* @param name the name of the file without its extension
|
||||
@@ -102,7 +140,7 @@ public class ContentParser{
|
||||
* @param type the type of content this is
|
||||
* @return the content that was parsed
|
||||
*/
|
||||
public Content parse(String mod, String name, String json, ContentType type) throws Exception{
|
||||
public Content parse(LoadedMod mod, String name, String json, ContentType type) throws Exception{
|
||||
if(contentTypes.isEmpty()){
|
||||
init();
|
||||
}
|
||||
@@ -112,7 +150,9 @@ public class ContentParser{
|
||||
throw new SerializationException("No parsers for content type '" + type + "'");
|
||||
}
|
||||
|
||||
Content c = parsers.get(type).parse(mod, name, value);
|
||||
currentMod = mod;
|
||||
Content c = parsers.get(type).parse(mod.name, name, value);
|
||||
c.mod = mod;
|
||||
checkNulls(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -44,8 +44,7 @@ public class Mods implements Loadable{
|
||||
}
|
||||
|
||||
/** @return the loaded mod found by class, or null if not found. */
|
||||
public @Nullable
|
||||
LoadedMod getMod(Class<? extends Mod> type){
|
||||
public @Nullable LoadedMod getMod(Class<? extends Mod> type){
|
||||
return loaded.find(l -> l.mod.getClass() == type);
|
||||
}
|
||||
|
||||
@@ -76,26 +75,29 @@ public class Mods implements Loadable{
|
||||
|
||||
packer = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true);
|
||||
for(LoadedMod mod : loaded){
|
||||
try{
|
||||
int packed = 0;
|
||||
for(FileHandle file : mod.root.child("sprites").list()){
|
||||
if(file.extension().equals("png")){
|
||||
try(InputStream stream = file.read()){
|
||||
byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512));
|
||||
Pixmap pixmap = new Pixmap(bytes, 0, bytes.length);
|
||||
packer.pack(mod.name + "-" + file.nameWithoutExtension(), pixmap);
|
||||
pixmap.dispose();
|
||||
packed ++;
|
||||
totalSprites ++;
|
||||
}
|
||||
int[] packed = {0};
|
||||
boolean[] failed = {false};
|
||||
mod.root.child("sprites").walk(file -> {
|
||||
if(failed[0]) return;
|
||||
if(file.extension().equals("png")){
|
||||
try(InputStream stream = file.read()){
|
||||
byte[] bytes = Streams.copyStreamToByteArray(stream, Math.max((int)file.length(), 512));
|
||||
Pixmap pixmap = new Pixmap(bytes, 0, bytes.length);
|
||||
packer.pack(mod.name + "-" + file.nameWithoutExtension(), pixmap);
|
||||
pixmap.dispose();
|
||||
packed[0] ++;
|
||||
totalSprites ++;
|
||||
}catch(IOException e){
|
||||
failed[0] = true;
|
||||
Core.app.post(() -> {
|
||||
Log.err("Error packing images for mod: {0}", mod.meta.name);
|
||||
e.printStackTrace();
|
||||
if(!headless) ui.showException(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
Log.info("Packed {0} images for mod '{1}'.", packed, mod.meta.name);
|
||||
}catch(IOException e){
|
||||
Log.err("Error packing images for mod: {0}", mod.meta.name);
|
||||
e.printStackTrace();
|
||||
if(!headless) ui.showException(e);
|
||||
}
|
||||
});
|
||||
Log.info("Packed {0} images for mod '{1}'.", packed[0], mod.meta.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +199,7 @@ public class Mods implements Loadable{
|
||||
for(FileHandle file : folder.list()){
|
||||
if(file.extension().equals("json")){
|
||||
try{
|
||||
Content loaded = parser.parse(mod.name, file.nameWithoutExtension(), file.readString(), type);
|
||||
Content loaded = parser.parse(mod, file.nameWithoutExtension(), file.readString(), type);
|
||||
Log.info("[{0}] Loaded '{1}'.", mod.meta.name, loaded);
|
||||
}catch(Exception e){
|
||||
throw new RuntimeException("Failed to parse content file '" + file + "' for mod '" + mod.meta.name + "'.", e);
|
||||
@@ -209,6 +211,8 @@ public class Mods implements Loadable{
|
||||
}
|
||||
}
|
||||
|
||||
parser.finishParsing();
|
||||
|
||||
each(Mod::loadContent);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ public class PlacementFragment extends Fragment{
|
||||
Block tryRecipe = tile.block();
|
||||
if(tryRecipe.isVisible() && unlocked(tryRecipe)){
|
||||
input.block = tryRecipe;
|
||||
currentCategory = input.block.buildCategory;
|
||||
currentCategory = input.block.category;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ public class PlacementFragment extends Fragment{
|
||||
for(KeyCode key : inputCatGrid){
|
||||
if(Core.input.keyDown(key)){
|
||||
input.block = getByCategory(Category.all[i]).first();
|
||||
currentCategory = input.block.buildCategory;
|
||||
currentCategory = input.block.category;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -147,7 +147,7 @@ public class PlacementFragment extends Fragment{
|
||||
|
||||
button.update(() -> { //color unplacable things gray
|
||||
TileEntity core = player.getClosestCore();
|
||||
Color color = state.rules.infiniteResources || (core != null && (core.items.has(block.buildRequirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources)) ? Color.white : Color.gray;
|
||||
Color color = state.rules.infiniteResources || (core != null && (core.items.has(block.requirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources)) ? Color.white : Color.gray;
|
||||
button.forEach(elem -> elem.setColor(color));
|
||||
button.setChecked(control.input.block == block);
|
||||
});
|
||||
@@ -205,7 +205,7 @@ public class PlacementFragment extends Fragment{
|
||||
topTable.table(req -> {
|
||||
req.top().left();
|
||||
|
||||
for(ItemStack stack : lastDisplay.buildRequirements){
|
||||
for(ItemStack stack : lastDisplay.requirements){
|
||||
req.table(line -> {
|
||||
line.left();
|
||||
line.addImage(stack.item.icon(Item.Icon.small)).size(8 * 2);
|
||||
@@ -296,7 +296,7 @@ public class PlacementFragment extends Fragment{
|
||||
Array<Block> getByCategory(Category cat){
|
||||
returnArray.clear();
|
||||
for(Block block : content.blocks()){
|
||||
if(block.buildCategory == cat && block.isVisible()){
|
||||
if(block.category == cat && block.isVisible()){
|
||||
returnArray.add(block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +114,9 @@ public class Block extends BlockStorage{
|
||||
public float idleSoundVolume = 0.5f;
|
||||
|
||||
/** Cost of constructing this block. */
|
||||
public ItemStack[] buildRequirements = new ItemStack[]{};
|
||||
public ItemStack[] requirements = new ItemStack[]{};
|
||||
/** Category in place menu. */
|
||||
public Category buildCategory = Category.distribution;
|
||||
public Category category = Category.distribution;
|
||||
/** Cost of building this block; do not modify directly! */
|
||||
public float buildCost;
|
||||
/** Whether this block is visible and can currently be built. */
|
||||
@@ -387,7 +387,7 @@ public class Block extends BlockStorage{
|
||||
}
|
||||
|
||||
buildCost = 0f;
|
||||
for(ItemStack stack : buildRequirements){
|
||||
for(ItemStack stack : requirements){
|
||||
buildCost += stack.amount * stack.item.cost;
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ public class Block extends BlockStorage{
|
||||
stats.add(BlockStat.health, health, StatUnit.none);
|
||||
if(isBuildable()){
|
||||
stats.add(BlockStat.buildTime, buildCost / 60, StatUnit.seconds);
|
||||
stats.add(BlockStat.buildCost, new ItemListValue(false, buildRequirements));
|
||||
stats.add(BlockStat.buildCost, new ItemListValue(false, requirements));
|
||||
}
|
||||
|
||||
consumes.display(stats);
|
||||
@@ -772,11 +772,11 @@ public class Block extends BlockStorage{
|
||||
|
||||
/** Sets up requirements. Use only this method to set up requirements. */
|
||||
protected void requirements(Category cat, BooleanProvider visible, ItemStack[] stacks){
|
||||
this.buildCategory = cat;
|
||||
this.buildRequirements = stacks;
|
||||
this.category = cat;
|
||||
this.requirements = stacks;
|
||||
this.buildVisibility = visible;
|
||||
|
||||
Arrays.sort(buildRequirements, (a, b) -> Integer.compare(a.item.id, b.item.id));
|
||||
Arrays.sort(requirements, (a, b) -> Integer.compare(a.item.id, b.item.id));
|
||||
}
|
||||
|
||||
public enum Icon{
|
||||
|
||||
@@ -196,8 +196,8 @@ public class BuildBlock extends Block{
|
||||
|
||||
float maxProgress = core == null ? amount : checkRequired(core.items, amount, false);
|
||||
|
||||
for(int i = 0; i < cblock.buildRequirements.length; i++){
|
||||
int reqamount = Math.round(state.rules.buildCostMultiplier * cblock.buildRequirements[i].amount);
|
||||
for(int i = 0; i < cblock.requirements.length; i++){
|
||||
int reqamount = Math.round(state.rules.buildCostMultiplier * cblock.requirements[i].amount);
|
||||
accumulator[i] += Math.min(reqamount * maxProgress, reqamount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator
|
||||
totalAccumulator[i] = Math.min(totalAccumulator[i] + reqamount * maxProgress, reqamount);
|
||||
}
|
||||
@@ -221,7 +221,7 @@ public class BuildBlock extends Block{
|
||||
float deconstructMultiplier = 0.5f;
|
||||
|
||||
if(cblock != null){
|
||||
ItemStack[] requirements = cblock.buildRequirements;
|
||||
ItemStack[] requirements = cblock.requirements;
|
||||
if(requirements.length != accumulator.length || totalAccumulator.length != requirements.length){
|
||||
setDeconstruct(previous);
|
||||
}
|
||||
@@ -258,15 +258,15 @@ public class BuildBlock extends Block{
|
||||
private float checkRequired(ItemModule inventory, float amount, boolean remove){
|
||||
float maxProgress = amount;
|
||||
|
||||
for(int i = 0; i < cblock.buildRequirements.length; i++){
|
||||
int sclamount = Math.round(state.rules.buildCostMultiplier * cblock.buildRequirements[i].amount);
|
||||
for(int i = 0; i < cblock.requirements.length; i++){
|
||||
int sclamount = Math.round(state.rules.buildCostMultiplier * cblock.requirements[i].amount);
|
||||
int required = (int)(accumulator[i]); //calculate items that are required now
|
||||
|
||||
if(inventory.get(cblock.buildRequirements[i].item) == 0 && sclamount != 0){
|
||||
if(inventory.get(cblock.requirements[i].item) == 0 && sclamount != 0){
|
||||
maxProgress = 0f;
|
||||
}else if(required > 0){ //if this amount is positive...
|
||||
//calculate how many items it can actually use
|
||||
int maxUse = Math.min(required, inventory.get(cblock.buildRequirements[i].item));
|
||||
int maxUse = Math.min(required, inventory.get(cblock.requirements[i].item));
|
||||
//get this as a fraction
|
||||
float fraction = maxUse / (float)required;
|
||||
|
||||
@@ -277,7 +277,7 @@ public class BuildBlock extends Block{
|
||||
|
||||
//remove stuff that is actually used
|
||||
if(remove){
|
||||
inventory.remove(cblock.buildRequirements[i].item, maxUse);
|
||||
inventory.remove(cblock.requirements[i].item, maxUse);
|
||||
}
|
||||
}
|
||||
//else, no items are required yet, so just keep going
|
||||
@@ -293,8 +293,8 @@ public class BuildBlock extends Block{
|
||||
public void setConstruct(Block previous, Block block){
|
||||
this.cblock = block;
|
||||
this.previous = previous;
|
||||
this.accumulator = new float[block.buildRequirements.length];
|
||||
this.totalAccumulator = new float[block.buildRequirements.length];
|
||||
this.accumulator = new float[block.requirements.length];
|
||||
this.totalAccumulator = new float[block.requirements.length];
|
||||
this.buildCost = block.buildCost * state.rules.buildCostMultiplier;
|
||||
}
|
||||
|
||||
@@ -303,8 +303,8 @@ public class BuildBlock extends Block{
|
||||
this.progress = 1f;
|
||||
if(previous.buildCost >= 0.01f){
|
||||
this.cblock = previous;
|
||||
this.accumulator = new float[previous.buildRequirements.length];
|
||||
this.totalAccumulator = new float[previous.buildRequirements.length];
|
||||
this.accumulator = new float[previous.requirements.length];
|
||||
this.totalAccumulator = new float[previous.requirements.length];
|
||||
this.buildCost = previous.buildCost * state.rules.buildCostMultiplier;
|
||||
}else{
|
||||
this.buildCost = 20f; //default no-requirement build cost is 20
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.anuke.mindustry.world.blocks;
|
||||
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.*;
|
||||
|
||||
/**An overlay ore for a specific item type.*/
|
||||
public class OreBlock extends OverlayFloor{
|
||||
@@ -14,9 +14,27 @@ public class OreBlock extends OverlayFloor{
|
||||
this.color.set(ore.color);
|
||||
}
|
||||
|
||||
/** For mod use only!*/
|
||||
public OreBlock(String name){
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void setup(Item ore){
|
||||
this.localizedName = ore.localizedName();
|
||||
this.itemDrop = ore;
|
||||
this.variants = 3;
|
||||
this.color.set(ore.color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
|
||||
if(itemDrop != null){
|
||||
setup(itemDrop);
|
||||
}else{
|
||||
throw new IllegalArgumentException(name + " must have an item drop!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user