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
+3 -1
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){
@@ -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();
@@ -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);
}
}
}
@@ -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;
@@ -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
@@ -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;
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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();
}
}
@@ -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){
@@ -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