Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/mindustry/core/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public void play(){

for(ItemStack stack : state.rules.loadout){
//make sure to cap storage
entity.items.add(stack.item, Math.min(stack.amount, entity.storageCapacity - entity.items.get(stack.item)));
entity.items.add(stack.item, Math.min(stack.amount, entity.capacity() - entity.items.get(stack.item)));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/mindustry/core/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public void beginMapLoad(){

/**
* Call to signify the end of map loading. Updates tile proximities and sets up physics for the world.
* A WorldLoadEvent will be fire.
* A WorldLoadEvent will be fired.
*/
public void endMapLoad(){
Events.fire(new WorldLoadEndEvent());
Expand Down
9 changes: 8 additions & 1 deletion core/src/mindustry/editor/MapEditorDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,15 @@ private void editInGame(){
ui.loadAnd(() -> {
lastSavedRules = state.rules;
hide();

Teams data = new Teams();
//keep the old itemCap for each team, otherwise it breaks
state.teams.active.each(t ->
data.get(t.team).itemCap = t.itemCap
);
state.teams = data;

//only reset the player; logic.reset() will clear entities, which we do not want
state.teams = new Teams();
player.reset();
state.rules = Gamemode.editor.apply(lastSavedRules.copy());
state.rules.limitMapArea = false;
Expand Down
4 changes: 2 additions & 2 deletions core/src/mindustry/game/SectorInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public void write(){
entity.items.clear();
entity.items.add(items);
//ensure capacity.
entity.items.each((i, a) -> entity.items.set(i, Mathf.clamp(a, 0, entity.storageCapacity)));
entity.items.each((i, a) -> entity.items.set(i, Mathf.clamp(a, 0, entity.capacity())));
}
}

Expand Down Expand Up @@ -221,7 +221,7 @@ public void prepare(Sector sector){
attack = state.rules.attackMode;
hasCore = entity != null;
bestCoreType = !hasCore ? Blocks.air : state.rules.defaultTeam.cores().max(e -> e.block.size).block;
storageCapacity = entity != null ? entity.storageCapacity : 0;
storageCapacity = entity != null ? entity.capacity() : 0;
hasSpawns = spawner.countSpawns() > 0;
lastPresetName = sector.preset == null ? null : sector.preset.name;
lastWidth = world.width();
Expand Down
5 changes: 5 additions & 0 deletions core/src/mindustry/game/Teams.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import mindustry.world.*;
import mindustry.world.blocks.payloads.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import mindustry.world.modules.*;

import java.util.*;

Expand Down Expand Up @@ -298,6 +299,8 @@ public static class TeamData{
public int unitCap;
/** Total unit count. */
public int unitCount;
/** Current item cap. */
public int itemCap;
/** Counts for each type of unit. Do not access directly. */
public @Nullable int[] typeCounts;
/** Cached buildings by type. */
Expand All @@ -308,6 +311,8 @@ public static class TeamData{
public Seq<Player> players = new Seq<>(false);
/** All buildings. Updated on team change / building addition or removal. Includes even buildings that do not update(). */
public Seq<Building> buildings = new Seq<>(false);
/** The item module for cores of this team. Null if no core was loaded. */
public @Nullable ItemModule items;
/** Units of this team by type. Updated each frame. */
public @Nullable Seq<Unit>[] unitsByType;

Expand Down
2 changes: 1 addition & 1 deletion core/src/mindustry/type/Sector.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public void addItems(ItemSeq items){
if(isBeingPlayed()){
if(state.rules.defaultTeam.core() != null){
ItemModule storage = state.rules.defaultTeam.items();
int cap = state.rules.defaultTeam.core().storageCapacity;
int cap = state.rules.defaultTeam.data().itemCap;
items.each((item, amount) -> storage.add(item, Math.min(cap - storage.get(item), amount)));
}
}else if(hasBase()){
Expand Down
2 changes: 1 addition & 1 deletion core/src/mindustry/ui/fragments/HintsFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public enum DefaultHint implements Hint{
),

coreIncinerate(
() -> state.isCampaign() && state.rules.defaultTeam.core() != null && state.rules.defaultTeam.core().items.get(Items.copper) >= state.rules.defaultTeam.core().storageCapacity - 10,
() -> state.isCampaign() && state.rules.defaultTeam.core() != null && state.rules.defaultTeam.core().items.get(Items.copper) >= state.rules.defaultTeam.data().itemCap - 10,
() -> false
)
;
Expand Down
4 changes: 2 additions & 2 deletions core/src/mindustry/world/blocks/ConstructBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ public void deconstruct(Unit builder, @Nullable CoreBuild core, float amount){

if(clampedAmount > 0 && accumulated > 0){ //if it's positive, add it to the core
if(core != null && requirements[i].item.unlockedNowHost()){ //only accept items that are unlocked
int accepting = Math.min(accumulated, core.storageCapacity - core.items.get(requirements[i].item));
int accepting = Math.min(accumulated, core.capacity() - core.items.get(requirements[i].item));
//transfer items directly, as this is not production.
if(!state.rules.infiniteResources) core.items.add(requirements[i].item, accepting);
itemsLeft[i] += accepting;
Expand All @@ -387,7 +387,7 @@ public void deconstruct(Unit builder, @Nullable CoreBuild core, float amount){
int remaining = target - itemsLeft[i];

if(requirements[i].item.unlockedNowHost()){
core.items.add(requirements[i].item, Mathf.clamp(remaining, 0, core.storageCapacity - core.items.get(requirements[i].item)));
core.items.add(requirements[i].item, Mathf.clamp(remaining, 0, core.capacity() - core.items.get(requirements[i].item)));
}
itemsLeft[i] = target;
}
Expand Down
75 changes: 46 additions & 29 deletions core/src/mindustry/world/blocks/storage/CoreBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ public void setBars(){
super.setBars();

addBar("capacity", (CoreBuild e) -> new Bar(
() -> Core.bundle.format("bar.capacity", UI.formatAmount(e.storageCapacity)),
() -> Core.bundle.format("bar.capacity", UI.formatAmount(e.team.data().itemCap)),
() -> Pal.items,
() -> e.items.total() / ((float)e.storageCapacity * content.items().count(UnlockableContent::unlockedNow))
() -> e.items.total() / ((float)e.team.data().itemCap * content.items().count(UnlockableContent::unlockedNow))
));
}

Expand Down Expand Up @@ -252,7 +252,8 @@ public void drawPlace(int x, int y, int rotation, boolean valid){
}

public class CoreBuild extends Building implements LaunchAnimator{
public int storageCapacity;
private int storageCapacity;

public boolean noEffect = false;
public Team lastDamage = Team.derelict;
public float iframes = -1f;
Expand Down Expand Up @@ -530,7 +531,6 @@ public void damage(@Nullable Team source, float damage){
@Override
public void created(){
super.created();

Events.fire(new CoreChangeEvent(this));
}

Expand All @@ -542,14 +542,15 @@ public void changeTeam(Team next){

super.changeTeam(next);

items = next.data().items;
onProximityUpdate();

Events.fire(new CoreChangeEvent(this));
}

@Override
public double sense(LAccess sensor){
if(sensor == LAccess.itemCapacity) return storageCapacity;
if(sensor == LAccess.itemCapacity) return team.data().itemCap;
if(sensor == LAccess.maxUnits) return Units.getCap(team);
return super.sense(sensor);
}
Expand Down Expand Up @@ -684,6 +685,10 @@ public void afterDestroyed(){
}
}

public int capacity(){
return team.data().itemCap;
}

@Override
public void drawLight(){
Drawf.light(x, y, lightRadius, Pal.accent, 0.65f + Mathf.absin(20f, 0.1f));
Expand All @@ -696,46 +701,41 @@ public boolean acceptItem(Building source, Item item){

@Override
public int getMaximumAccepted(Item item){
return state.rules.coreIncinerates ? Integer.MAX_VALUE/2 : storageCapacity;
return state.rules.coreIncinerates ? Integer.MAX_VALUE/2 : team.data().itemCap;
}

@Override
public void onProximityUpdate(){
super.onProximityUpdate();

for(Building other : state.teams.cores(team)){
if(other.tile != tile){
this.items = other.items;
}
if(team.data().items == null){
// this is the first core of this team, assign its ItemModule as the default one
team.data().items = items;
}else{
items = team.data().items;
}

state.teams.registerCore(this);
int previousCapacity = storageCapacity;

storageCapacity = itemCapacity + proximity.sum(e -> owns(e) ? e.block.itemCapacity : 0);
storageCapacity = itemCapacity;
proximity.each(this::owns, t -> {
t.items = items;
storageCapacity += t.block.itemCapacity;
((StorageBuild)t).linkedCore = this;
});

for(Building other : state.teams.cores(team)){
if(other.tile == tile) continue;
storageCapacity += other.block.itemCapacity + other.proximity.sum(e -> owns(other, e) ? e.block.itemCapacity : 0);
}
team.data().itemCap += storageCapacity - previousCapacity;

if(!world.isGenerating()){
for(Item item : content.items()){
items.set(item, Math.min(items.get(item), storageCapacity));
}
}

for(CoreBuild other : state.teams.cores(team)){
other.storageCapacity = storageCapacity;
clampItems();
}
}

@Override
public void handleStack(Item item, int amount, Teamc source){
boolean incinerate = incinerateNonBuildable && !item.buildable;
int realAmount = incinerate ? 0 : Math.min(amount, storageCapacity - items.get(item));
int realAmount = incinerate ? 0 : Math.min(amount, team.data().itemCap - items.get(item));
super.handleStack(item, realAmount, source);

if(team == state.rules.defaultTeam && state.isCampaign()){
Expand All @@ -760,6 +760,12 @@ public int removeStack(Item item, int amount){
return result;
}

public void clampItems(){
for(Item item : content.items()){
items.set(item, Math.min(items.get(item), team.data().itemCap));
}
}

@Override
public void drawSelect(){
//do not draw a pointless single outline when there's no storage
Expand Down Expand Up @@ -801,20 +807,31 @@ public void damage(float amount){
public void onRemoved(){
int totalCapacity = proximity.sum(e -> e.items != null && e.items == items ? e.block.itemCapacity : 0);

proximity.each(e -> owns(e) && e.items == items && owns(e), t -> {
proximity.each(e -> owns(e) && e.items == items, t -> {
StorageBuild ent = (StorageBuild)t;
ent.linkedCore = null;
ent.items = new ItemModule();
for(Item item : content.items()){
ent.items.set(item, (int)Math.min(ent.block.itemCapacity, items.get(item) * (float)ent.block.itemCapacity / totalCapacity));
}

// check if there are any other nearby cores
Point2[] edges = Edges.getEdges(ent.block.size);
for(Point2 edge : edges){
Building b = world.build(ent.tileX() + edge.x, ent.tileY() + edge.y);
if(b != this && b instanceof CoreBuild c){
c.onProximityUpdate();
if(ent.linkedCore == c){
break;
}
}
}
});

team.data().itemCap -= storageCapacity;
state.teams.unregisterCore(this);

for(CoreBuild other : state.teams.cores(team)){
other.onProximityUpdate();
}
clampItems();
}

@Override
Expand Down Expand Up @@ -844,7 +861,7 @@ public void handleItem(Building source, Item item){
state.rules.sector.info.handleCoreItem(item, 1);
}

if(items.get(item) >= storageCapacity || incinerate){
if(items.get(item) >= team.data().itemCap || incinerate){
//create item incineration effect at random intervals
if(!noEffect){
incinerateEffect(this, source);
Expand All @@ -853,7 +870,7 @@ public void handleItem(Building source, Item item){
}else{
super.handleItem(source, item);
}
}else if(((state.rules.coreIncinerates && items.get(item) >= storageCapacity) || incinerate) && !noEffect){
}else if(((state.rules.coreIncinerates && items.get(item) >= team.data().itemCap) || incinerate) && !noEffect){
//create item incineration effect at random intervals
incinerateEffect(this, source);
noEffect = false;
Expand Down
6 changes: 3 additions & 3 deletions core/src/mindustry/world/blocks/storage/StorageBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static void incinerateEffect(Building self, Building source){
}

public class StorageBuild extends Building{
public @Nullable Building linkedCore;
public @Nullable CoreBuild linkedCore;

@Override
public boolean acceptItem(Building source, Item item){
Expand All @@ -61,10 +61,10 @@ public boolean canUnload(){
@Override
public void handleItem(Building source, Item item){
if(linkedCore != null){
if(linkedCore.items.get(item) >= ((CoreBuild)linkedCore).storageCapacity){
if(linkedCore.items.get(item) >= team.data().itemCap){
incinerateEffect(this, source);
}
((CoreBuild)linkedCore).noEffect = true;
linkedCore.noEffect = true;
linkedCore.handleItem(source, item);
}else{
super.handleItem(source, item);
Expand Down
2 changes: 1 addition & 1 deletion server/src/mindustry/server/ServerControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ protected void registerCommands(){
}

for(Item item : content.items()){
state.teams.cores(team).first().items.set(item, state.teams.cores(team).first().storageCapacity);
state.teams.cores(team).first().items.set(item, state.teams.get(team).itemCap);
}

info("Core filled.");
Expand Down
Loading