mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-09 15:27:45 +07:00
Derelict block click repair
This commit is contained in:
@ -1836,7 +1836,7 @@ hint.desktopPause = Press [accent][[Space][] to pause and unpause the game.
|
||||
hint.breaking = [accent]Right-click[] and drag to break blocks.
|
||||
hint.breaking.mobile = Activate the \uE817 [accent]hammer[] in the bottom right and tap to break blocks.\n\nHold down your finger for a second and drag to break in a selection.
|
||||
hint.blockInfo = View information of a block by selecting it in the [accent]build menu[], then selecting the [accent][[?][] button at the right.
|
||||
hint.derelict = [accent]Derelict[] structures are broken remnants of old bases that no longer function.\n\nThese structures can be [accent]deconstructed[] for resources.
|
||||
hint.derelict = [accent]Derelict[] structures are broken remnants of old bases that no longer function.\n\nThese structures can be [accent]deconstructed[] for resources, or repaired.
|
||||
hint.research = Use the \uE875 [accent]Research[] button to research new technology.
|
||||
hint.research.mobile = Use the \uE875 [accent]Research[] button in the \uE88C [accent]Menu[] to research new technology.
|
||||
hint.unitControl = Hold [accent][[L-ctrl][] and [accent]click[] to manually control friendly units or turrets.
|
||||
|
BIN
core/assets/cursors/repair.png
Normal file
BIN
core/assets/cursors/repair.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -78,7 +78,7 @@ public class UI implements ApplicationListener, Loadable{
|
||||
|
||||
public IntMap<Dialog> followUpMenus;
|
||||
|
||||
public Cursor drillCursor, unloadCursor, targetCursor;
|
||||
public Cursor drillCursor, unloadCursor, targetCursor, repairCursor;
|
||||
|
||||
private @Nullable Element lastAnnouncement;
|
||||
|
||||
@ -142,6 +142,7 @@ public class UI implements ApplicationListener, Loadable{
|
||||
drillCursor = Core.graphics.newCursor("drill", Fonts.cursorScale());
|
||||
unloadCursor = Core.graphics.newCursor("unload", Fonts.cursorScale());
|
||||
targetCursor = Core.graphics.newCursor("target", Fonts.cursorScale());
|
||||
repairCursor = Core.graphics.newCursor("repair", Fonts.cursorScale());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,8 +61,12 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
|
||||
while(it.hasNext()){
|
||||
BuildPlan plan = it.next();
|
||||
Tile tile = world.tile(plan.x, plan.y);
|
||||
if(tile == null || (plan.breaking && tile.block() == Blocks.air) || (!plan.breaking && ((tile.build != null && tile.build.rotation == plan.rotation) || !plan.block.rotate) &&
|
||||
(tile.block() == plan.block || (plan.block != null && (plan.block.isOverlay() && plan.block == tile.overlay() || (plan.block.isFloor() && plan.block == tile.floor())))))){
|
||||
boolean isSameDerelict = (tile != null && tile.build != null && tile.block() == plan.block && tile.build.tileX() == plan.x && tile.build.tileY() == plan.y && tile.team() == Team.derelict);
|
||||
if(tile == null || (plan.breaking && tile.block() == Blocks.air) || (!plan.breaking && ((tile.build != null && tile.build.rotation == plan.rotation && !isSameDerelict) || !plan.block.rotate) &&
|
||||
//th block must be the same, but not derelict and the same
|
||||
((tile.block() == plan.block && !isSameDerelict) ||
|
||||
//same floor or overlay
|
||||
(plan.block != null && (plan.block.isOverlay() && plan.block == tile.overlay() || (plan.block.isFloor() && plan.block == tile.floor())))))){
|
||||
|
||||
it.remove();
|
||||
}
|
||||
|
@ -447,10 +447,14 @@ public class DesktopInput extends InputHandler{
|
||||
Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY());
|
||||
|
||||
if(cursor != null){
|
||||
if(cursor.build != null){
|
||||
if(cursor.build != null && cursor.build.interactable(player.team())){
|
||||
cursorType = cursor.build.getCursor();
|
||||
}
|
||||
|
||||
if(cursor.build != null && cursor.build.team == Team.derelict && Build.validPlace(cursor.block(), player.team(), cursor.build.tileX(), cursor.build.tileY(), cursor.build.rotation)){
|
||||
cursorType = ui.repairCursor;
|
||||
}
|
||||
|
||||
if((isPlacing() && player.isBuilder()) || !selectPlans.isEmpty()){
|
||||
cursorType = SystemCursor.hand;
|
||||
}
|
||||
@ -672,7 +676,7 @@ public class DesktopInput extends InputHandler{
|
||||
commandRect = true;
|
||||
commandRectX = input.mouseWorldX();
|
||||
commandRectY = input.mouseWorldY();
|
||||
}else if(!checkConfigTap() && selected != null){
|
||||
}else if(!checkConfigTap() && selected != null && !tryRepairDerelict(selected)){
|
||||
//only begin shooting if there's no cursor event
|
||||
if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem
|
||||
&& !(tryStopMine(selected) || (!settings.getBool("doubletapmine") || selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500) && tryBeginMine(selected)) && !Core.scene.hasKeyboard()){
|
||||
|
@ -1641,6 +1641,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean tryRepairDerelict(Tile selected){
|
||||
if(selected != null && selected.build != null && selected.build.block.unlockedNow() && selected.build.team == Team.derelict && Build.validPlace(selected.block(), player.team(), selected.build.tileX(), selected.build.tileY(), selected.build.rotation)){
|
||||
player.unit().addBuild(new BuildPlan(selected.build.tileX(), selected.build.tileY(), selected.build.rotation, selected.block(), selected.build.config()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canMine(Tile tile){
|
||||
return !Core.scene.hasMouse()
|
||||
&& player.unit().validMine(tile)
|
||||
|
@ -712,7 +712,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
buildingTapped = selectedControlBuild();
|
||||
|
||||
//prevent mining if placing/breaking blocks
|
||||
if(!tryStopMine() && !canTapPlayer(worldx, worldy) && !checkConfigTap() && !tileTapped(linked.build) && mode == none && !Core.settings.getBool("doubletapmine")){
|
||||
if(!tryRepairDerelict(cursor) && !tryStopMine() && !canTapPlayer(worldx, worldy) && !checkConfigTap() && !tileTapped(linked.build) && mode == none && !Core.settings.getBool("doubletapmine")){
|
||||
tryBeginMine(cursor);
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +336,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public boolean instantTransfer = false;
|
||||
/** Whether you can rotate this block after it is placed. */
|
||||
public boolean quickRotate = true;
|
||||
/** If true, this derelict block can be repair by clicking it. */
|
||||
public boolean allowDerelictRepair = true;
|
||||
/** Main subclass. Non-anonymous. */
|
||||
public @Nullable Class<?> subclass;
|
||||
/** Scroll position for certain blocks. */
|
||||
|
@ -86,6 +86,31 @@ public class Build{
|
||||
return;
|
||||
}
|
||||
|
||||
//repair derelict tile
|
||||
if(tile.team() == Team.derelict && tile.block == result && tile.build != null && tile.block.allowDerelictRepair){
|
||||
float healthf = tile.build.healthf();
|
||||
var config = tile.build.config();
|
||||
|
||||
tile.setBlock(result, team, rotation);
|
||||
|
||||
if(unit != null && unit.getControllerName() != null) tile.build.lastAccessed = unit.getControllerName();
|
||||
|
||||
if(config != null){
|
||||
tile.build.configured(unit, config);
|
||||
}
|
||||
//keep health
|
||||
tile.build.health = result.health * healthf;
|
||||
|
||||
if(fogControl.isVisibleTile(team, tile.x, tile.y)){
|
||||
result.placeEffect.at(tile.drawx(), tile.drawy(), result.size);
|
||||
Fx.rotateBlock.at(tile.build.x, tile.build.y, tile.build.block.size);
|
||||
//doesn't play a sound
|
||||
}
|
||||
|
||||
Events.fire(new BlockBuildEndEvent(tile, unit, team, false, config));
|
||||
return;
|
||||
}
|
||||
|
||||
//break all props in the way
|
||||
tile.getLinkedTilesAs(result, out -> {
|
||||
if(out.block != Blocks.air && out.block.alwaysReplace){
|
||||
@ -193,11 +218,11 @@ public class Build{
|
||||
(type.size == 2 && world.getDarkness(wx, wy) >= 3) ||
|
||||
(state.rules.staticFog && state.rules.fog && !fogControl.isDiscovered(team, wx, wy)) ||
|
||||
(check.floor().isDeep() && !type.floating && !type.requiresWater && !type.placeableLiquid) || //deep water
|
||||
(type == check.block() && check.build != null && rotation == check.build.rotation && type.rotate) || //same block, same rotation
|
||||
(type == check.block() && check.build != null && rotation == check.build.rotation && type.rotate && !((type == check.block && check.team() == Team.derelict))) || //same block, same rotation
|
||||
!check.interactable(team) || //cannot interact
|
||||
!check.floor().placeableOn || //solid wall
|
||||
(!checkVisible && !check.block().alwaysReplace) || //replacing a block that should be replaced (e.g. payload placement)
|
||||
!((type.canReplace(check.block()) || //can replace type
|
||||
!(((type.canReplace(check.block()) || (type == check.block && check.team() == Team.derelict)) || //can replace type OR can replace derelict block of same type
|
||||
(check.build instanceof ConstructBuild build && build.current == type && check.centerX() == tile.x && check.centerY() == tile.y)) && //same type in construction
|
||||
type.bounds(tile.x, tile.y, Tmp.r1).grow(0.01f).contains(check.block.bounds(check.centerX(), check.centerY(), Tmp.r2))) || //no replacement
|
||||
(type.requiresWater && check.floor().liquidDrop != Liquids.water) //requires water but none found
|
||||
|
Reference in New Issue
Block a user