Content cleaning

This commit is contained in:
Anuken
2019-12-14 09:33:07 -05:00
parent 19675068ea
commit 58e3143e2a
17 changed files with 86 additions and 16 deletions

View File

@ -100,7 +100,7 @@ mod.enabled = [lightgray]Enabled
mod.disabled = [scarlet]Disabled
mod.disable = Disable
mod.delete.error = Unable to delete mod. File may be in use.
mod.requiresversion = [scarlet]Requires game version: [accent]{0}
mod.requiresversion = [scarlet]Requires min game version: [accent]{0}
mod.missingdependencies = [scarlet]Missing dependencies: {0}
mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled.
mod.enable = Enable

View File

@ -25,6 +25,7 @@ public class ContentLoader{
private Array<Content>[] contentMap = new Array[ContentType.values().length];
private MappableContent[][] temporaryMapper;
private @Nullable LoadedMod currentMod;
private @Nullable Content lastAdded;
private ObjectSet<Cons<Content>> initialization = new ObjectSet<>();
private ContentList[] content = {
new Fx(),
@ -146,11 +147,27 @@ public class ContentLoader{
//clear all content, currently not used
}
/** Get last piece of content created for error-handling purposes. */
public @Nullable Content getLastAdded(){
return lastAdded;
}
/** Remove last content added in case of an exception. */
public void removeLast(){
if(lastAdded != null && contentMap[lastAdded.getContentType().ordinal()].peek() == lastAdded){
contentMap[lastAdded.getContentType().ordinal()].pop();
if(lastAdded instanceof MappableContent){
contentNameMap[lastAdded.getContentType().ordinal()].remove(((MappableContent)lastAdded).name);
}
}
}
public void handleContent(Content content){
this.lastAdded = content;
contentMap[content.getContentType().ordinal()].add(content);
}
public void setCurrentMod(LoadedMod mod){
public void setCurrentMod(@Nullable LoadedMod mod){
this.currentMod = mod;
}

View File

@ -1,19 +1,17 @@
package io.anuke.mindustry.ctype;
import io.anuke.arc.files.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.mod.*;
import io.anuke.mindustry.type.*;
/** Base class for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}. */
public abstract class Content implements Comparable<Content>{
public final short id;
/** The mod that loaded this piece of content. */
public @Nullable LoadedMod mod;
/** File that this content was loaded from. */
public @Nullable FileHandle sourceFile;
/** Info on which mod this content was loaded from. */
public @Nullable ModContentInfo minfo;
public Content(){
this.id = (short)Vars.content.getBy(getContentType()).size;
@ -37,6 +35,11 @@ public abstract class Content implements Comparable<Content>{
public void load(){
}
/** @return whether an error ocurred during mod loading. */
public boolean hasErrored(){
return minfo != null && minfo.error != null;
}
@Override
public int compareTo(Content c){
return Integer.compare(id, c.id);

View File

@ -150,7 +150,7 @@ public abstract class BulletType extends Content{
public void update(Bullet b){
if(homingPower > 0.0001f){
TargetTrait target = Units.closestTarget(b.getTeam(), b.x, b.y, homingRange);
TargetTrait target = Units.closestTarget(b.getTeam(), b.x, b.y, homingRange, e -> !e.isFlying() || collidesAir);
if(target != null){
b.velocity().setAngle(Mathf.slerpDelta(b.velocity().angle(), b.angleTo(target), 0.08f));
}

View File

@ -258,8 +258,12 @@ public class ContentParser{
if(research[0] != null){
Block parent = find(ContentType.block, research[0]);
TechNode baseNode = TechTree.create(parent, block);
LoadedMod cur = currentMod;
postreads.add(() -> {
currentContent = block;
currentMod = cur;
TechNode parnode = TechTree.all.find(t -> t.block == parent);
if(parnode == null){
throw new ModLoadException("Block '" + parent.name + "' isn't in the tech tree, but '" + block.name + "' requires it to be researched.", block);
@ -383,6 +387,14 @@ public class ContentParser{
}
public void finishParsing(){
reads.each(c -> {
try{
c.run();
}catch(Throwable t){
}
});
try{
reads.each(Runnable::run);
postreads.each(Runnable::run);

View File

@ -0,0 +1,14 @@
package io.anuke.mindustry.mod;
import io.anuke.arc.files.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.mod.Mods.*;
public class ModContentInfo{
/** The mod that loaded this piece of content. */
public LoadedMod mod;
/** File that this content was loaded from. */
public FileHandle sourceFile;
/** The error that occurred during loading, if applicable. Null if no error occurred. */
public @Nullable String error;
}

View File

@ -464,16 +464,15 @@ public class Mods implements Loadable{
//make sure mod content is in proper order
runs.sort();
runs.each(l -> safeRun(l.mod, () -> {
for(LoadRun l : runs){
try{
//this binds the content but does not load it entirely
Content loaded = parser.parse(l.mod, l.file.nameWithoutExtension(), l.file.readString("UTF-8"), l.file, l.type);
Log.debug("[{0}] Loaded '{1}'.", l.mod.meta.name,
(loaded instanceof UnlockableContent ? ((UnlockableContent)loaded).localizedName : loaded));
}catch(Exception e){
Log.debug("[{0}] Loaded '{1}'.", l.mod.meta.name, (loaded instanceof UnlockableContent ? ((UnlockableContent)loaded).localizedName : loaded));
}catch(Throwable e){
throw new RuntimeException("Failed to parse content file '" + l.file + "' for mod '" + l.mod.meta.name + "'.", e);
}
}));
}
//this finishes parsing content fields
parser.finishParsing();
@ -532,7 +531,7 @@ public class Mods implements Loadable{
/** Iterates through each mod with a main class.*/
public void each(Cons<Mod> cons){
loaded.each(p -> p.mod != null, p -> safeRun(p, () -> cons.get(p.mod)));
loaded.each(p -> p.mod != null, p -> contextRun(p, () -> cons.get(p.mod)));
}
public void handleError(Throwable t, LoadedMod mod){
@ -562,7 +561,7 @@ public class Mods implements Loadable{
}
}
public void safeRun(LoadedMod mod, Runnable run){
public void contextRun(LoadedMod mod, Runnable run){
try{
run.run();
}catch(Throwable t){

View File

@ -224,6 +224,10 @@ public class BuildBlock extends Block{
return false;
}
if(cblock.requirements.length != accumulator.length || totalAccumulator.length != cblock.requirements.length){
setConstruct(previous, cblock);
}
float maxProgress = core == null ? amount : checkRequired(core.items, amount, false);
for(int i = 0; i < cblock.requirements.length; i++){

View File

@ -0,0 +1,7 @@
- Added various new features for modding - see documentation
- Added server block state autosync
- Added support for Thai font
- Added JS scripting - unstable, not well tested
- Fixed liquid junction to item bridge crash
- Fixed launch items not saving
- General maintenance bugfixes and translation updates

View File

@ -0,0 +1,7 @@
- Added various new features for modding - see documentation
- Added server block state autosync
- Added support for Thai font
- Added JS scripting - unstable, not well tested
- Fixed liquid junction to item bridge crash
- Fixed launch items not saving
- General maintenance bugfixes and translation updates

View File

@ -0,0 +1,7 @@
- Added various new features for modding - see documentation
- Added server block state autosync
- Added support for Thai font
- Added JS scripting - unstable, not well tested
- Fixed liquid junction to item bridge crash
- Fixed launch items not saving
- General maintenance bugfixes and translation updates