Finally a somewhat functional tutorial / Many bugfixes

This commit is contained in:
Anuken 2018-09-24 20:24:51 -04:00
parent 32c59b66f6
commit 5354e02b6f
31 changed files with 365 additions and 135 deletions

View File

@ -21,7 +21,7 @@ text.level.delete.title=Confirm Delete
text.map.delete=Are you sure you want to delete the map "[orange]{0}[]"?
text.level.select=Level Select
text.level.mode=Gamemode:
text.construction.desktop=Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use space[].
text.construction.desktop=To deselect a block or stop building, [accent]use space[].
text.construction.title=Block Construction Guide
text.construction=\
You've just selected [accent]block construction mode[].\n\n\
@ -62,11 +62,14 @@ text.mission.info=Mission Info
text.mission.complete=Mission complete!
text.mission.complete.body=Sector {0},{1} has been conquered.
text.mission.wave=Survive[accent] {0}/{1} []waves\nWave in {2}
text.mission.wave.enemies=Survive[accent] {0}/{1} []waves\n{2} Enemies
text.mission.wave.menu=Survive[accent] {0} []waves
text.mission.battle=Destroy the enemy core
text.mission.resource=Obtain {0} x{1}
text.mission.resource.menu=Obtain {0} x{1}
text.mission.resource=Obtain {0}:\n[accent]{1}/{2}[]
text.mission.block=Create {0}
text.mission.unit=Create {0} Unit
text.mission.linknode=Link Power Node
text.mission.display=[accent]Mission:\n[LIGHT_GRAY]{0}
text.none=<none>
text.close=Close
@ -657,20 +660,24 @@ unit.fortress.description=A heavy artillery ground unit.
unit.revenant.name=Revenant
unit.revenant.description=A heavy laser platform.
tutorial.begin=Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by [accent]mining copper[]. Tap a copper ore vein near your core to do this.
tutorial.begin=Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this.
tutorial.drill=Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein.
tutorial.conveyor=[accent]Conveyors []are used to transport items to the core.\nMake a line of conveyors from the drill to the core.
tutorial.morecopper=More copper is required. Use drills to mine it.
tutorial.turret=Defensive structures must be built to repel the [LIGHT_GRAY]enemy[].\nBuild a duo turret near your base.
tutorial.drillturret=Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret.
tutorial.waves=The[LIGHT_GRAY] enemy[] approaches.\n\nDefend your core for 5 waves. Build more turrets.
tutorial.lead=More ores are available. Explore to your right and mine[accent] lead[].\n\nDrag from your unit to the core to transfer resources.
tutorial.conveyor=[accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core.
tutorial.morecopper=More copper is required.\n\nEither mine it manually, or place more drills.
tutorial.turret=Defensive structures must be built to repel the[LIGHT_GRAY] enemy[].\nBuild a duo turret near your base.
tutorial.drillturret=Duo turrets require[accent] copper ammo []to shoot.\nPlace a drill next to the turret to supply it with mined copper.
tutorial.waves=The[LIGHT_GRAY] enemy[] approaches.\n\nDefend your core for 2 waves. Build more turrets.
tutorial.lead=More ores are available. Explore and mine[accent] lead[].\n\nDrag from your unit to the core to transfer resources.
tutorial.smelter=Copper and lead are weak metals.\nSuperior[accent] Dense Alloy[] can be created in a smelter.\n\nBuild one.
tutorial.densealloy=Create conveyors leading copper, lead and coal from drills into the smelter.\nCreate an additional output conveyor leading to the core.\n\nUse this to create 30 dense alloy.
tutorial.siliconsmelter=Advanced weapons require[accent] silicon.\nMake a silicon smelter.
tutorial.densealloy=The smelter will now produce alloy.\nGet some.\nImprove the production if necessary.
tutorial.siliconsmelter=The core will now create a[accent] spirit drone[] for mining and repairing blocks.\n\nFactories for other units can be created with [accent] silicon.\nMake a silicon smelter.
tutorial.silicondrill=Silicon requires[accent] coal[] and[accent] sand[].\nStart by making drills.
tutorial.generator=This technology requires power.\nCreate a[accent] combustion generator[] for it.
tutorial.node=Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power.\nTo link power, tap the node.\n\nLink the generator to the silicon smelter.
tutorial.silicon=Fuel the combustion generator with coal from drills.\nInput sand and coal from drills into the silicon smelter\nThis will produce silicon.\n\nMake some silicon and move it into your base.
tutorial.generatordrill=Combustion generators need fuel.\nFuel it with coal from a drill.
tutorial.node=Power requires transport.\nCreate a[accent] power node[] next to your combustion generator to transfer its power.
tutorial.nodelink=Power can be transferred through contacting power blocks and generators, or by linked power nodes.\n\nLink power by tapping the node and selecting the generator and silicon smelter.
tutorial.silicon=Silicon is being produced. Get some.\n\nImproving the production system is advised.
tutorial.daggerfactory=Construct a[accent] dagger mech factory.[]\n\nThis will be used to create attack mechs.
tutorial.dagger=Supply silicon, copper and power to the factory.\nOnce requirements are met, a mech will be created.\n\nCreate more drills, generators and conveyors as necessary.
tutorial.router=Factories need resources to function.\nCreate a router to split conveyor resources.
tutorial.dagger=Link power nodes to the factory.\nOnce requirements are met, a mech will be created.\n\nCreate more drills, generators and conveyors as necessary.
tutorial.battle=The[LIGHT_GRAY] enemy[] has revealed their core.\nDestroy it with your unit and dagger mechs.

View File

@ -41,6 +41,7 @@ TintedDrawable: {
loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} },
chatfield: {name: white, color: {r: 0, g: 0, b: 0, a: 0.2}},
clear: {name: white, color: {r: 0.1, g: 0.1, b: 0.1, a: 0.75}},
none: {name: white, color: {r: 0, g: 0, b: 0, a: 0}},
clear-over: {name: white, color: {r: 1, g: 1, b: 1, a: 0.2} },
clear-down: {name: white, color: {r: 1, g: 1, b: 1, a: 0.4} }
},
@ -64,7 +65,7 @@ ImageButtonStyle: {
static: {up: button },
static-down: {up: button-down },
toggle: {checked: button-down, down: button-down, up: button, imageDisabledColor: gray, imageUpColor: white },
select: {checked: button-select, up: clear },
select: {checked: button-select, up: none },
clear: {down: clear-down, up: clear, over: clear-over},
},
ScrollPaneStyle: {

View File

@ -36,14 +36,14 @@ public class Vars{
//time between waves in frames (on normal mode)
public static final float wavespace = 60 * 60 * 1.5f;
public static final float mineTransferRange = 310f;
public static final float mineTransferRange = 250f;
//set ridiculously high for now
public static final float coreBuildRange = 999999f;
//team of the player by default
public static final Team defaultTeam = Team.blue;
//team of the enemy in waves
public static final Team waveTeam = Team.red;
public static final float unlockResourceScaling = 1.5f;
public static final float unlockResourceScaling = 1f;
public static final int maxTextLength = 150;
public static final int maxNameLength = 40;
public static final float itemSize = 5f;

View File

@ -14,17 +14,17 @@ public class Recipes implements ContentList{
@Override
public void load(){
//DEBUG
new Recipe(distribution, DebugBlocks.itemSource).setMode(GameMode.sandbox).setHidden(true);
new Recipe(distribution, DebugBlocks.itemVoid).setMode(GameMode.sandbox).setHidden(true);
new Recipe(liquid, DebugBlocks.liquidSource).setMode(GameMode.sandbox).setHidden(true);
new Recipe(power, DebugBlocks.powerVoid).setMode(GameMode.sandbox).setHidden(true);
new Recipe(power, DebugBlocks.powerInfinite).setMode(GameMode.sandbox).setHidden(true);
new Recipe(distribution, DebugBlocks.itemSource).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true);
new Recipe(distribution, DebugBlocks.itemVoid).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true);
new Recipe(liquid, DebugBlocks.liquidSource).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true);
new Recipe(power, DebugBlocks.powerVoid).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true);
new Recipe(power, DebugBlocks.powerInfinite).setMode(GameMode.sandbox).setHidden(true).setAlwaysUnlocked(true);
//DEFENSE
//walls
new Recipe(defense, DefenseBlocks.copperWall, new ItemStack(Items.copper, 12));
new Recipe(defense, DefenseBlocks.copperWallLarge, new ItemStack(Items.copper, 12 * 4));
new Recipe(defense, DefenseBlocks.copperWall, new ItemStack(Items.copper, 12)).setAlwaysUnlocked(true);
new Recipe(defense, DefenseBlocks.copperWallLarge, new ItemStack(Items.copper, 12 * 4)).setAlwaysUnlocked(true);
new Recipe(defense, DefenseBlocks.denseAlloyWall, new ItemStack(Items.densealloy, 12));
new Recipe(defense, DefenseBlocks.denseAlloyWallLarge, new ItemStack(Items.densealloy, 12 * 4));
@ -51,7 +51,7 @@ public class Recipes implements ContentList{
.setDependencies(Items.blastCompound);
//TURRETS
new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.copper, 40));
new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.copper, 40)).setAlwaysUnlocked(true);
new Recipe(weapon, TurretBlocks.arc, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 30), new ItemStack(Items.silicon, 20));
new Recipe(weapon, TurretBlocks.hail, new ItemStack(Items.copper, 60), new ItemStack(Items.densealloy, 35));
new Recipe(weapon, TurretBlocks.lancer, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 90));
@ -65,13 +65,13 @@ public class Recipes implements ContentList{
new Recipe(weapon, TurretBlocks.meltdown, new ItemStack(Items.copper, 500), new ItemStack(Items.lead, 700), new ItemStack(Items.densealloy, 600), new ItemStack(Items.surgealloy, 650), new ItemStack(Items.silicon, 650));
//DISTRIBUTION
new Recipe(distribution, DistributionBlocks.conveyor, new ItemStack(Items.copper, 1));
new Recipe(distribution, DistributionBlocks.conveyor, new ItemStack(Items.copper, 1)).setAlwaysUnlocked(true);
new Recipe(distribution, DistributionBlocks.titaniumconveyor, new ItemStack(Items.copper, 2), new ItemStack(Items.titanium, 1));
new Recipe(distribution, DistributionBlocks.phaseConveyor, new ItemStack(Items.phasematter, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.densealloy, 20));
//starter lead transportation
new Recipe(distribution, DistributionBlocks.junction, new ItemStack(Items.copper, 2));
new Recipe(distribution, DistributionBlocks.router, new ItemStack(Items.copper, 6));
new Recipe(distribution, DistributionBlocks.junction, new ItemStack(Items.copper, 2)).setAlwaysUnlocked(true);
new Recipe(distribution, DistributionBlocks.router, new ItemStack(Items.copper, 6)).setAlwaysUnlocked(true);
//advanced densealloy transporation
new Recipe(distribution, DistributionBlocks.distributor, new ItemStack(Items.densealloy, 8), new ItemStack(Items.copper, 8));
@ -140,7 +140,7 @@ public class Recipes implements ContentList{
);
//DRILLS, PRODUCERS
new Recipe(production, ProductionBlocks.mechanicalDrill, new ItemStack(Items.copper, 50));
new Recipe(production, ProductionBlocks.mechanicalDrill, new ItemStack(Items.copper, 45)).setAlwaysUnlocked(true);
new Recipe(production, ProductionBlocks.pneumaticDrill, new ItemStack(Items.copper, 60), new ItemStack(Items.densealloy, 50));
new Recipe(production, ProductionBlocks.laserdrill, new ItemStack(Items.copper, 70), new ItemStack(Items.densealloy, 90), new ItemStack(Items.silicon, 60), new ItemStack(Items.titanium, 50));
new Recipe(production, ProductionBlocks.blastdrill, new ItemStack(Items.copper, 130), new ItemStack(Items.densealloy, 180), new ItemStack(Items.silicon, 120), new ItemStack(Items.titanium, 100), new ItemStack(Items.thorium, 60));

View File

@ -40,7 +40,7 @@ public class UnitTypes implements ContentList{
speed = 0.2f;
maxVelocity = 0.8f;
range = 50f;
healSpeed = 0.25f;
healSpeed = 0.22f;
health = 60;
}};
@ -50,7 +50,7 @@ public class UnitTypes implements ContentList{
drag = 0.4f;
range = 40f;
weapon = Weapons.chainBlaster;
health = 150;
health = 130;
}};
titan = new UnitType("titan", Titan.class, Titan::new){{
@ -108,7 +108,7 @@ public class UnitTypes implements ContentList{
health = 220;
buildPower = 0.9f;
minePower = 1.1f;
healSpeed = 0.55f;
healSpeed = 0.5f;
toMine = ObjectSet.with(Items.lead, Items.copper, Items.titanium);
}};
}

View File

@ -12,7 +12,7 @@ public class StorageBlocks extends BlockList implements ContentList{
@Override
public void load(){
core = new CoreBlock("core"){{
health = 1400;
health = 1100;
}};
vault = new Vault("vault"){{

View File

@ -63,7 +63,7 @@ public class UnitBlocks extends BlockList implements ContentList{
produceTime = 1700;
size = 2;
consumes.power(0.05f);
consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10), new ItemStack(Items.copper, 10)});
consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10)});
}};
titanFactory = new UnitFactory("titan-factory"){{

View File

@ -316,27 +316,19 @@ public class Control extends Module{
Platform.instance.updateRPC();
if(!Settings.has("4.0-warning")){
Settings.putBool("4.0-warning", true);
if(!Settings.getBool("4.0-warning-2", false)){
Timers.run(5f, () -> {
FloatingDialog dialog = new FloatingDialog("[orange]WARNING![]");
dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f);
dialog.content().add("The beta version you are about to play should be considered very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " +
"A large portion of content is still unimplemented. \nAll current art and UI is temporary, and will be re-drawn before release. " +
"\n\n[accent]Saves and maps may be corrupted without warning between updates.[] You have been warned!").wrap().width(400f);
dialog.show();
});
}
if(!Settings.has("4.0-no-sound")){
Settings.putBool("4.0-no-sound", true);
Timers.run(4f, () -> {
FloatingDialog dialog = new FloatingDialog("[orange]Attention![]");
dialog.buttons().addButton("$text.ok", dialog::hide).size(100f, 60f);
dialog.content().add("You might have noticed that 4.0 does not have any sound.\nThis is [orange]intentional![] Sound will be added in a later update.\n\n[LIGHT_GRAY](now stop reporting this as a bug)").wrap().width(400f);
dialog.buttons().addButton("$text.ok", () -> {
dialog.hide();
Settings.putBool("4.0-warning-2", true);
Settings.save();
}).size(100f, 60f);
dialog.content().add("Reminder: The beta version you are about to play is very unstable, and is [accent]not representative of the final 4.0 release.[]\n\n " +
"\nThere is currently[scarlet] no sound implemented[]; this is intentional.\n" +
"All current art and UI is temporary, and will be re-drawn before release. " +
"\n\n[accent]Saves and maps may be corrupted without warning between updates.").wrap().width(400f);
dialog.show();
});
}
@ -352,6 +344,8 @@ public class Control extends Module{
private void updateSectors(){
if(world.getSector() == null) return;
world.getSector().currentMission().update();
//TODO move sector code into logic class
//check unlocked sectors
while(!world.getSector().complete && world.getSector().currentMission().isComplete()){
@ -360,6 +354,7 @@ public class Control extends Module{
state.mode = world.getSector().currentMission().getMode();
world.getSector().currentMission().onBegin();
world.sectors().save();
}
//check if all assigned missions are complete

View File

@ -334,6 +334,15 @@ public class World extends Module{
}
}
public int transform(int packed, int oldWidth, int oldHeight, int newWidth, int shiftX, int shiftY){
int x = packed % oldWidth;
int y = packed / oldWidth;
if(!Mathf.inBounds(x, y, oldWidth, oldHeight)) return -1;
x += shiftX;
y += shiftY;
return y*newWidth + x;
}
/**
* Raycast, but with world coordinates.
*/

View File

@ -311,9 +311,6 @@ public interface BuilderTrait extends Entity{
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
Fill.tri(px, py, x2, y2, x1, y1);
Fill.tri(px, py, x2, y2, x3, y3);
Draw.alpha(1f);
Lines.line(px, py, x1, y1);

View File

@ -40,7 +40,7 @@ public class ContentDatabase{
* @return whether or not this content was newly unlocked.
*/
public boolean unlockContent(UnlockableContent content){
if(!content.canBeUnlocked()) return false;
if(!content.canBeUnlocked() || content.alwaysUnlocked()) return false;
if(!unlocked.containsKey(content.getContentType())){
unlocked.put(content.getContentType(), new ObjectSet<>());

View File

@ -79,7 +79,7 @@ public class Saves{
if(time > Settings.getInt("saveinterval") * 60){
saving = true;
Timers.run(2f, () -> {
Timers.runTask(2f, () -> {
try{
current.save();
}catch(Exception e){

View File

@ -41,7 +41,9 @@ public class Sector{
/**Returns scaled difficulty. This is not just the difficulty ordinal.*/
public Difficulty getDifficulty(){
if(difficulty == 0){
return Difficulty.easy;
//yes, this means insane tutorial difficulty
//(((have fun)))
return Difficulty.hard;
}else if(difficulty < 4){
return Difficulty.normal;
}else if(difficulty < 9){

View File

@ -41,6 +41,9 @@ public class Sectors{
}
if(!sector.hasSave()){
for(Mission mission : sector.missions){
mission.reset();
}
world.loadSector(sector);
logic.play();
sector.saveID = control.getSaves().addSave("sector-" + sector.packedPosition()).index;
@ -53,6 +56,7 @@ public class Sectors{
sector.getSave().load();
world.setSector(sector);
state.set(State.playing);
sector.currentMission().onBegin();
}catch(Exception e){
Log.err(e);
sector.getSave().delete();
@ -145,6 +149,7 @@ public class Sectors{
tile.x = (short)(x + shiftX);
tile.y = (short)(y + shiftY);
newTiles[x + shiftX][y + shiftY] = tile;
tile.block().transformLinks(tile, world.width(), world.height(), sector.width*sectorSize, sector.height*sectorSize, shiftX, shiftY);
}
}
@ -171,6 +176,8 @@ public class Sectors{
//end loading of map
world.endMapLoad();
threads.runGraphics(() -> createTexture(sector));
return true;
}
@ -297,6 +304,10 @@ public class Sectors{
private void createTexture(Sector sector){
if(headless) return; //obviously not created or needed on server
if(sector.texture != null){
sector.texture.dispose();
}
Pixmap pixmap = new Pixmap(sectorImageSize * sector.width, sectorImageSize * sector.height, Format.RGBA8888);
GenResult secResult = new GenResult();

View File

@ -5,91 +5,150 @@ import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.content.blocks.*;
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
import io.anuke.mindustry.maps.generation.Generation;
import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult;
import io.anuke.mindustry.maps.missions.*;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Bundles;
import static io.anuke.mindustry.Vars.*;
/**Just a class for returning the list of tutorial missions.*/
public class TutorialSector{
private static int droneIndex;
public static Array<Mission> getMissions(){
//int x = sectorSize/2, y = sectorSize/2;
return Array.with(
new ItemMission(Items.copper, 30).setMessage("$tutorial.begin"),
Array<Mission> missions = Array.with(
new ItemMission(Items.copper, 60).setMessage("$tutorial.begin"),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 62).setMessage("$tutorial.drill"),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 62).setMessage("$tutorial.drill"),
new BlockLocMission(DistributionBlocks.conveyor, 57, 62, 0).setShowComplete(false).setMessage("$tutorial.conveyor"),
new BlockLocMission(DistributionBlocks.conveyor, 58, 62, 0).setShowComplete(false),
new BlockLocMission(DistributionBlocks.conveyor, 59, 62, 0).setShowComplete(false),
new BlockLocMission(DistributionBlocks.conveyor, 60, 62, 3).setShowComplete(false),
new BlockLocMission(DistributionBlocks.conveyor, 57, 62, 0).setShowComplete(false).setMessage("$tutorial.conveyor"),
new BlockLocMission(DistributionBlocks.conveyor, 58, 62, 0).setShowComplete(false),
new BlockLocMission(DistributionBlocks.conveyor, 59, 62, 0).setShowComplete(false),
new BlockLocMission(DistributionBlocks.conveyor, 60, 62, 3).setShowComplete(false),
new ItemMission(Items.copper, 50).setMessage("$tutorial.morecopper"),
new ItemMission(Items.copper, 100).setMessage("$tutorial.morecopper"),
new BlockLocMission(TurretBlocks.duo, 56, 59).setMessage("$tutorial.turret"),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 60).setMessage("$tutorial.drillturret"),
new BlockLocMission(TurretBlocks.duo, 56, 59).setMessage("$tutorial.turret"),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 55, 60).setMessage("$tutorial.drillturret"),
new WaveMission(5).setMessage("$tutorial.waves"),
new WaveMission(2).setMessage("$tutorial.waves"),
new ActionMission(() -> {
Array<Item> ores = Array.with(Items.copper, Items.coal, Items.lead);
GenResult res = new GenResult();
for(int x = 0; x < world.width(); x++){
for(int y = 0; y < world.height(); y++){
Tile tile = world.tile(x, y);
world.generator().generateTile(res, 0, 0, x, y, true, null, ores);
if(!tile.hasCliffs()){
tile.setFloor((Floor) res.floor);
new ActionMission(() -> {
Timers.runTask(30f, () -> {
Runnable r = () -> {
Array<Item> ores = Array.with(Items.copper, Items.coal, Items.lead);
GenResult res = new GenResult();
for(int x = 0; x < world.width(); x++){
for(int y = 0; y < world.height(); y++){
Tile tile = world.tile(x, y);
world.generator().generateTile(res, 0, 0, x, y, true, null, ores);
if(!tile.hasCliffs()){
tile.setFloor((Floor) res.floor);
}
}
}
Events.fire(new WorldLoadEvent());
};
if(headless){
ui.loadLogic(r);
}else{
threads.run(r);
}
});
}),
new ItemMission(Items.lead, 90).setMessage("$tutorial.lead"),
new ItemMission(Items.copper, 250).setMessage("$tutorial.morecopper"),
new BlockLocMission(CraftingBlocks.smelter, 58, 69).setMessage("$tutorial.smelter"),
//drills for smelter
new BlockLocMission(ProductionBlocks.mechanicalDrill, 62, 86),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 58, 89),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 54, 68),
//conveyors for smelter
new LineBlockMission(DistributionBlocks.conveyor, 58, 88, 58, 70, 3),
new LineBlockMission(DistributionBlocks.conveyor, 61, 86, 61, 70, 3),
new LineBlockMission(DistributionBlocks.conveyor, 61, 69, 59, 69, 2),
new LineBlockMission(DistributionBlocks.conveyor, 56, 69, 57, 69, 0),
new LineBlockMission(DistributionBlocks.conveyor, 58, 68, 58, 63, 3),
new BlockLocMission(DistributionBlocks.junction, 58, 62, 0),
new BlockLocMission(DistributionBlocks.conveyor, 58, 61, 0),
new ItemMission(Items.densealloy, 20).setMessage("$tutorial.densealloy"),
new MarkerBlockMission(CraftingBlocks.siliconsmelter, 54, 52).setMessage("$tutorial.siliconsmelter"),
//coal line
new BlockLocMission(ProductionBlocks.mechanicalDrill, 47, 52).setMessage("$tutorial.silicondrill"),
new LineBlockMission(DistributionBlocks.conveyor, 49, 52, 53, 52, 0),
//sand line
new BlockLocMission(ProductionBlocks.mechanicalDrill, 53, 49),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 56, 49),
new LineBlockMission(DistributionBlocks.conveyor, 55, 50, 55, 51, 1),
//silicon line
new LineBlockMission(DistributionBlocks.conveyor, 56, 53, 59, 53, 0),
new LineBlockMission(DistributionBlocks.conveyor, 60, 53, 60, 58, 1),
new BlockLocMission(PowerBlocks.combustionGenerator, 49, 54).setMessage("$tutorial.generator"),
new BlockLocMission(ProductionBlocks.mechanicalDrill, 47, 54).setMessage("$tutorial.generatordrill"),
new BlockLocMission(PowerBlocks.powerNode, 52, 54).setMessage("$tutorial.node"),
new ConditionMission(Bundles.get("text.mission.linknode"), () -> world.tile(54, 52).entity != null && world.tile(54, 52).entity.power != null && world.tile(54, 52).entity.power.amount >= 0.01f)
.setMessage("$tutorial.nodelink"),
new ItemMission(Items.silicon, 70).setMessage("$tutorial.silicon"),
new BlockLocMission(UnitBlocks.daggerFactory, 64, 59).setMessage("$tutorial.daggerfactory"),
//silicon lines for dagger factory
new BlockLocMission(DistributionBlocks.router, 60, 57).setMessage("$tutorial.router"),
new LineBlockMission(DistributionBlocks.conveyor, 61, 57, 63, 57, 0),
new LineBlockMission(DistributionBlocks.conveyor, 64, 57, 64, 58, 1),
//power for dagger factory
new BlockLocMission(PowerBlocks.powerNode, 57, 54),
new BlockLocMission(PowerBlocks.powerNode, 62, 54),
new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"),
new ExpandMission(1, 0){
@Override
public void onComplete(){
super.onComplete();
generateBase();
}
}
Events.fire(new WorldLoadEvent());
}),
new ItemMission(Items.lead, 30).setMessage("$tutorial.lead"),
new ItemMission(Items.copper, 150).setMessage("$tutorial.morecopper"),
new BlockMission(CraftingBlocks.smelter).setMessage("$tutorial.smelter"),
new ItemMission(Items.densealloy, 30).setMessage("$tutorial.densealloy"),
new BlockMission(CraftingBlocks.siliconsmelter).setMessage("$tutorial.siliconsmelter"),
new BlockMission(PowerBlocks.combustionGenerator).setMessage("$tutorial.generator"),
new BlockMission(PowerBlocks.powerNode).setMessage("$tutorial.node"),
new ItemMission(Items.silicon, 30).setMessage("$tutorial.silicon"),
new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"),
new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"),
new ExpandMission(1, 0),
new BattleMission(){
public void generate(Generation gen){
}
@Override
public boolean isComplete(){
return false;
}
public void onBegin(){
super.onBegin();
generateBase();
}
}.setMessage("$tutorial.battle")
},
new BattleMission().setMessage("$tutorial.battle")
);
//find drone marker mission
for(int i = 0; i < missions.size; i++){
if(missions.get(i) instanceof MarkerBlockMission){
droneIndex = i;
break;
}
}
return missions;
}
public static boolean supressDrone(){
return world.getSector() != null && world.getSector().x == 0 && world.getSector().y == 0;
return world.getSector() != null && world.getSector().x == 0 && world.getSector().y == 0 && world.getSector().completedMissions < droneIndex;
}
private static void generateBase(){
int x = sectorSize/2, y = sectorSize + sectorSize/2;
int x = sectorSize/2 + sectorSize, y = sectorSize/2;
world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam);
// world.setBlock(world.tile(x + 1, y + 2), TurretBlocks.duo, waveTeam);
//world.setBlock(world.tile(x + 1, y - 2), TurretBlocks.duo, waveTeam);
@ -101,6 +160,14 @@ public class TutorialSector{
//world.tile(x + 1, y - 2).block().handleStack(Items.copper, 1, world.tile(x + 1, y - 2), null);
//since placed() is not called here, add core manually
state.teams.get(waveTeam).cores.add(world.tile(x, y));
if(!state.teams.get(waveTeam).cores.contains(world.tile(x, y), true)){
state.teams.get(waveTeam).cores.add(world.tile(x, y));
}
}
private static class MarkerBlockMission extends BlockLocMission{
public MarkerBlockMission(Block block, int x, int y){
super(block, x, y);
}
}
}

View File

@ -215,8 +215,6 @@ public class WorldGenerator{
}
}
//generateOres(tiles, sector.getSeed(), true, ores);
for(int x = 0; x < tiles.length; x++){
for(int y = 0; y < tiles[0].length; y++){
Tile tile = tiles[x][y];
@ -242,7 +240,6 @@ public class WorldGenerator{
return generateTile(result, sectorX, sectorY, localX, localY, detailed, null, null);
}
//TODO include ore in result
/**
* Gets the generation result from a specific sector at specific coordinates.
* @param result where to put the generation results
@ -265,7 +262,7 @@ public class WorldGenerator{
double iceridge = rid.getValue(x+99999, y, 1f / 300f) + sim3.octaveNoise2D(2, 1f, 1f/14f, x, y)/11f;
double elevation = elevationOf(x, y, detailed);
double temp =
+ sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x, y);
+ sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x - 120, y);
int lerpDst = 20;
lerpDst *= lerpDst;

View File

@ -2,6 +2,7 @@ package io.anuke.mindustry.maps.missions;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.GameMode;
import io.anuke.ucore.util.Bundles;
import static io.anuke.mindustry.Vars.threads;
@ -28,7 +29,7 @@ public class ActionMission extends Mission{
@Override
public String displayString(){
return "";
return Bundles.get("text.loading");
}
@Override

View File

@ -10,6 +10,7 @@ import static io.anuke.mindustry.Vars.defaultTeam;
import static io.anuke.mindustry.Vars.world;
/**A mission in which the player must place a block.*/
@Deprecated
public class BlockMission extends Mission{
private final Block block;
private boolean complete;
@ -33,8 +34,7 @@ public class BlockMission extends Mission{
}
@Override
public void onComplete(){
super.onComplete();
public void reset(){
complete = false;
}

View File

@ -0,0 +1,23 @@
package io.anuke.mindustry.maps.missions;
import io.anuke.ucore.function.BooleanProvider;
public class ConditionMission extends Mission{
private final BooleanProvider complete;
private final String display;
public ConditionMission(String display, BooleanProvider complete){
this.complete = complete;
this.display = display;
}
@Override
public boolean isComplete(){
return complete.get();
}
@Override
public String displayString(){
return display;
}
}

View File

@ -1,6 +1,7 @@
package io.anuke.mindustry.maps.missions;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
@ -35,6 +36,13 @@ public class ItemMission extends Mission{
@Override
public String displayString(){
return Bundles.format("text.mission.resource", item.localizedName(), amount);
TileEntity core = Vars.players[0].getClosestCore();
if(core == null) return "imminent doom";
return Bundles.format("text.mission.resource", item.localizedName(), core.items.get(item), amount);
}
@Override
public String menuDisplayString(){
return Bundles.format("text.mission.resource.menu", item.localizedName(), amount);
}
}

View File

@ -0,0 +1,46 @@
package io.anuke.mindustry.maps.missions;
import com.badlogic.gdx.math.Bresenham2;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.world.Block;
public class LineBlockMission extends Mission{
private Array<BlockLocMission> points = new Array<>();
private int completeIndex;
public LineBlockMission(Block block, int x1, int y1, int x2, int y2, int rotation){
Array<GridPoint2> points = new Bresenham2().line(x1, y1, x2, y2);
for(GridPoint2 point : points){
this.points.add(new BlockLocMission(block, point.x, point.y, rotation));
}
}
@Override
public boolean isComplete(){
while(completeIndex < points.size && points.get(completeIndex).isComplete()){
completeIndex ++;
}
return completeIndex >= points.size;
}
@Override
public void drawOverlay(){
if(completeIndex < points.size){
points.get(completeIndex).drawOverlay();
}
}
@Override
public void reset(){
completeIndex = 0;
}
@Override
public String displayString(){
if(completeIndex < points.size){
return points.get(completeIndex).displayString();
}
return points.first().displayString();
}
}

View File

@ -49,6 +49,14 @@ public abstract class Mission{
}
public void update(){
}
public void reset(){
}
/**Shows the unique sector message.*/
public void showMessage(){
if(!headless && extraMessage != null){

View File

@ -2,6 +2,7 @@ package io.anuke.mindustry.maps.missions;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.game.Team;
@ -46,7 +47,9 @@ public class WaveMission extends Mission{
@Override
public String displayString(){
return Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60));
return state.wave > target ?
Bundles.format("text.mission.wave.enemies", state.wave, target, Vars.unitGroups[Vars.waveTeam.ordinal()].size()) :
Bundles.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60));
}
@Override
@ -54,9 +57,16 @@ public class WaveMission extends Mission{
return Bundles.format("text.mission.wave.menu", target);
}
@Override
public void update(){
if(state.wave > target){
state.mode = GameMode.noWaves;
}
}
@Override
public boolean isComplete(){
return state.wave >= target;
return state.wave > target && Vars.unitGroups[Vars.waveTeam.ordinal()].size() == 0;
}
@Override

View File

@ -33,6 +33,7 @@ public class Recipe extends UnlockableContent{
public GameMode mode;
public boolean isPad;
public boolean hidden;
public boolean alwaysUnlocked;
private UnlockableContent[] dependencies;
private Block[] blockDependencies;
@ -58,15 +59,16 @@ public class Recipe extends UnlockableContent{
* Returns unlocked recipes in a category.
* Do not call on the server backend, as unlocking does not exist!
*/
public static void getUnlockedByCategory(Category category, Array<Recipe> r){
public static void getUnlockedByCategory(Category category, Array<Recipe> arr){
if(headless){
throw new RuntimeException("Not implemented on the headless backend!");
}
r.clear();
for(Recipe recipe : content.recipes()){
if(recipe.category == category && (control.database().isUnlocked(recipe))){
r.add(recipe);
arr.clear();
for(Recipe r : content.recipes()){
if(r.category == category && (control.database().isUnlocked(r)) &&
!((r.mode != null && r.mode != state.mode) || (r.desktopOnly && mobile) || (r.isPad && !state.mode.showPads))){
arr.add(r);
}
}
}
@ -107,9 +109,15 @@ public class Recipe extends UnlockableContent{
return this;
}
public Recipe setAlwaysUnlocked(boolean unlocked){
this.alwaysUnlocked = unlocked;
return this;
}
@Override
public boolean alwaysUnlocked(){
return hidden;
return alwaysUnlocked;
}
@Override

View File

@ -44,7 +44,7 @@ public class SectorsDialog extends FloatingDialog{
content().row();
content().label(() -> Bundles.format("text.mission", selected == null || selected.completedMissions >= selected.missions.size
? Bundles.get("text.none") : selected.missions.get(selected.completedMissions).menuDisplayString())
+ "[WHITE] " + (selected == null ? "" : Bundles.format("text.save.difficulty", "[LIGHT_GRAY]" + selected.getDifficulty().toString())));
+ "[WHITE] " /*+ (selected == null ? "" : Bundles.format("text.save.difficulty", "[LIGHT_GRAY]" + selected.getDifficulty().toString()))*/);
content().row();
content().add(new SectorView()).grow();
content().row();

View File

@ -81,14 +81,16 @@ public class BlocksFragment extends Fragment{
}
});
container.add(descTable).fillX().uniformX();
float w = 246f;
container.row();
main.add(descTable).width(w);
main.row();
//now add the block selection menu
selectTable = main.table("pane", select -> {})
.margin(10f).marginLeft(0f).marginRight(0f).marginTop(-5)
.touchable(Touchable.enabled).right().bottom().get();
.touchable(Touchable.enabled).right().bottom().width(w).get();
}).bottom().right().get();
});

View File

@ -308,7 +308,7 @@ public class HudFragment extends Fragment{
shouldPause = true;
setFillParent(false);
getCell(content()).growX();
content().margin(15).add(str).width(600f).wrap().get().setAlignment(Align.left, Align.left);
content().margin(15).add(str).width(400f).wrap().get().setAlignment(Align.left, Align.left);
buttons().addButton("$text.continue", this::hide).size(140, 60).pad(4);
}}.show();
}

View File

@ -3,6 +3,7 @@ package io.anuke.mindustry.world;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
@ -252,6 +253,19 @@ public class Block extends BaseBlock {
region = Draw.region(name);
}
/**Called when the world is resized.
* Call super!*/
public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){
if(tile.entity != null && tile.entity.power != null){
IntArray links = tile.entity.power.links;
IntArray out = new IntArray();
for(int i = 0; i < links.size; i++){
out.add(world.transform(links.get(i), oldWidth, oldHeight, newWidth, shiftX, shiftY));
}
tile.entity.power.links = out;
}
}
/** Called when the block is tapped. */
public void tapped(Tile tile, Player player){

View File

@ -286,6 +286,14 @@ public class ItemBridge extends Block{
return rel != rel2;
}
@Override
public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){
super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY);
ItemBridgeEntity entity = tile.entity();
entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY);
}
@Override
public TileEntity newEntity(){
return new ItemBridgeEntity();

View File

@ -233,6 +233,14 @@ public class MassDriver extends Block{
return tile.entity.items.total() < itemCapacity;
}
@Override
public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){
super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY);
MassDriverEntity entity = tile.entity();
entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY);
}
@Override
public TileEntity newEntity(){
return new MassDriverEntity();

View File

@ -298,6 +298,14 @@ public class Reconstructor extends Block{
Call.reconstructPlayer(player, tile);
}
@Override
public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){
super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY);
ReconstructorEntity entity = tile.entity();
entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY);
}
@Override
public TileEntity newEntity(){
return new ReconstructorEntity();