mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-04 16:09:23 +07:00
parent
d61bb66418
commit
f9cfc8a2b8
@ -1283,6 +1283,7 @@ hint.guardian = [accent]Guardian[] units are armored. Weak ammo such as [accent]
|
||||
hint.coreUpgrade = Cores can be upgraded by [accent]placing higher-tier cores over them[].\n\nPlace a [accent]Foundation[] core over the [accent]Shard[] core. Make sure it is free from nearby obstructions.
|
||||
hint.presetLaunch = Gray [accent]landing zone sectors[], such as [accent]Frozen Forest[], can be launched to from anywhere. They do not require capture of nearby territory.\n\n[accent]Numbered sectors[], such as this one, are [accent]optional[].
|
||||
hint.coreIncinerate = After the core is filled to capacity with an item, any extra items of that type it receives will be [accent]incinerated[].
|
||||
hint.coopCampaign = When playing the [accent]co-op campaign[], items that are produced in the current map will also be sent [accent]to your local sectors[].\n\nAny new research done by the host also carries over.
|
||||
|
||||
item.copper.description = Used in all types of construction and ammunition.
|
||||
item.copper.details = Copper. Abnormally abundant metal on Serpulo. Structurally weak unless reinforced.
|
||||
|
@ -153,6 +153,18 @@ public class Logic implements ApplicationListener{
|
||||
}
|
||||
});
|
||||
|
||||
//send out items to each client
|
||||
Events.on(TurnEvent.class, e -> {
|
||||
if(net.server() && state.isCampaign()){
|
||||
int[] out = new int[content.items().size];
|
||||
state.getSector().info.production.each((item, stat) -> {
|
||||
out[item.id] = Math.max(0, (int)(stat.mean * turnDuration / 60));
|
||||
});
|
||||
|
||||
Call.sectorProduced(out);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/** Adds starting items, resets wave time, and sets state to playing. */
|
||||
@ -297,8 +309,46 @@ public class Logic implements ApplicationListener{
|
||||
public static void researched(Content content){
|
||||
if(!(content instanceof UnlockableContent u)) return;
|
||||
|
||||
var node = u.node();
|
||||
|
||||
//unlock all direct dependencies on client, permanently
|
||||
while(node != null){
|
||||
node.content.unlock();
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
state.rules.researched.add(u.name);
|
||||
Events.fire(new UnlockEvent(u));
|
||||
}
|
||||
|
||||
//called when the remote server runs a turn and produces something
|
||||
@Remote
|
||||
public static void sectorProduced(int[] amounts){
|
||||
if(!state.isCampaign()) return;
|
||||
Planet planet = state.rules.sector.planet;
|
||||
boolean any = false;
|
||||
|
||||
for(Item item : content.items()){
|
||||
int am = amounts[item.id];
|
||||
if(am > 0){
|
||||
int sumMissing = planet.sectors.sum(s -> s.hasBase() ? s.info.storageCapacity - s.info.items.get(item) : 0);
|
||||
if(sumMissing == 0) continue;
|
||||
//how much % to add
|
||||
double percent = Math.min((double)am / sumMissing, 1);
|
||||
for(Sector sec : planet.sectors){
|
||||
if(sec.hasBase()){
|
||||
int added = (int)Math.ceil(((sec.info.storageCapacity - sec.info.items.get(item)) * percent));
|
||||
sec.info.items.add(item, added);
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(any){
|
||||
for(Sector sec : planet.sectors){
|
||||
sec.saveInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,7 +117,7 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
|
||||
/** Makes this piece of content unlocked; if it already unlocked, nothing happens. */
|
||||
public void unlock(){
|
||||
if(!net.client() && !unlocked()){
|
||||
if(!unlocked && !alwaysUnlocked){
|
||||
unlocked = true;
|
||||
Core.settings.put(name + "-unlocked", true);
|
||||
|
||||
@ -135,7 +135,7 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
}
|
||||
|
||||
public boolean unlocked(){
|
||||
if(net != null && net.client()) return alwaysUnlocked || state.rules.researched.contains(name);
|
||||
if(net != null && net.client()) return unlocked || alwaysUnlocked || state.rules.researched.contains(name);
|
||||
return unlocked || alwaysUnlocked;
|
||||
}
|
||||
|
||||
|
@ -547,6 +547,22 @@ public class TypeIO{
|
||||
return read.b(new byte[length]);
|
||||
}
|
||||
|
||||
public static void writeInts(Writes write, int[] ints){
|
||||
write.s((short)ints.length);
|
||||
for(int i : ints){
|
||||
write.i(i);
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] readInts(Reads read){
|
||||
short length = read.s();
|
||||
int[] out = new int[length];
|
||||
for(int i = 0; i < length; i++){
|
||||
out[i] = read.i();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public static void writeTraceInfo(Writes write, TraceInfo trace){
|
||||
writeString(write, trace.ip);
|
||||
writeString(write, trace.uuid);
|
||||
|
@ -173,6 +173,7 @@ public class HintsFragment extends Fragment{
|
||||
&& SectorPresets.frozenForest.sector.save == null,
|
||||
() -> state.isCampaign() && state.getSector().preset == SectorPresets.frozenForest),
|
||||
coreIncinerate(() -> state.isCampaign() && state.rules.defaultTeam.core() != null && state.rules.defaultTeam.core().items.get(Items.copper) >= state.rules.defaultTeam.core().storageCapacity - 10, () -> false),
|
||||
coopCampaign(() -> net.client() && state.isCampaign() && SectorPresets.groundZero.sector.hasBase(), () -> false),
|
||||
;
|
||||
|
||||
@Nullable
|
||||
|
@ -6,6 +6,7 @@ import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
@ -246,17 +247,18 @@ public class CoreBlock extends StorageBlock{
|
||||
}
|
||||
state.teams.registerCore(this);
|
||||
|
||||
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) && owns(e) ? e.block.itemCapacity : 0);
|
||||
proximity.each(e -> isContainer(e) && owns(e), t -> {
|
||||
storageCapacity = itemCapacity + proximity().sum(e -> owns(e) ? e.block.itemCapacity : 0);
|
||||
proximity.each(e -> owns(e), t -> {
|
||||
t.items = items;
|
||||
((StorageBuild)t).linkedCore = this;
|
||||
});
|
||||
|
||||
for(Building other : state.teams.cores(team)){
|
||||
if(other.tile() == tile) continue;
|
||||
storageCapacity += other.block.itemCapacity + other.proximity().sum(e -> isContainer(e) && owns(other, e) ? e.block.itemCapacity : 0);
|
||||
storageCapacity += other.block.itemCapacity + other.proximity().sum(e -> owns(e) && owns(other, e) ? e.block.itemCapacity : 0);
|
||||
}
|
||||
|
||||
//Team.sharded.core().items.set(Items.surgeAlloy, 12000)
|
||||
if(!world.isGenerating()){
|
||||
for(Item item : content.items()){
|
||||
items.set(item, Math.min(items.get(item), storageCapacity));
|
||||
@ -303,24 +305,19 @@ public class CoreBlock extends StorageBlock{
|
||||
Draw.rect("block-select", t.x + offset * p.x, t.y + offset * p.y, i * 90);
|
||||
}
|
||||
};
|
||||
if(proximity.contains(e -> isContainer(e) && e.items == items)){
|
||||
if(proximity.contains(e -> owns(e) && e.items == items)){
|
||||
outline.get(this);
|
||||
}
|
||||
proximity.each(e -> isContainer(e) && e.items == items, outline);
|
||||
proximity.each(e -> owns(e) && e.items == items, outline);
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
|
||||
public boolean isContainer(Building tile){
|
||||
return tile instanceof StorageBuild && (((StorageBuild)tile).linkedCore == this || ((StorageBuild)tile).linkedCore == null);
|
||||
}
|
||||
|
||||
public boolean owns(Building tile){
|
||||
return tile instanceof StorageBuild && (((StorageBuild)tile).linkedCore == this || ((StorageBuild)tile).linkedCore == null);
|
||||
return owns(this, tile);
|
||||
}
|
||||
|
||||
public boolean owns(Building core, Building tile){
|
||||
return tile instanceof StorageBuild && (((StorageBuild)tile).linkedCore == core || ((StorageBuild)tile).linkedCore == null);
|
||||
return tile instanceof StorageBuild b && (b.linkedCore == core || b.linkedCore == null);
|
||||
}
|
||||
|
||||
public boolean incinerate(){
|
||||
@ -340,7 +337,7 @@ public class CoreBlock extends StorageBlock{
|
||||
int total = proximity.count(e -> e.items != null && e.items == items);
|
||||
float fract = 1f / total / state.teams.cores(team).size;
|
||||
|
||||
proximity.each(e -> isContainer(e) && e.items == items && owns(e), t -> {
|
||||
proximity.each(e -> owns(e) && e.items == items && owns(e), t -> {
|
||||
StorageBuild ent = (StorageBuild)t;
|
||||
ent.linkedCore = null;
|
||||
ent.items = new ItemModule();
|
||||
|
@ -91,14 +91,16 @@ public class StorageBlock extends Block{
|
||||
|
||||
@Override
|
||||
public void overwrote(Seq<Building> previous){
|
||||
for(Building other : previous){
|
||||
if(other.items != null){
|
||||
items.add(other.items);
|
||||
//only add prev items when core is not linked
|
||||
if(linkedCore == null){
|
||||
for(Building other : previous){
|
||||
if(other.items != null && other.items != items){
|
||||
items.add(other.items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//ensure item counts are not too high
|
||||
items.each((i, a) -> items.set(i, Math.min(a, itemCapacity)));
|
||||
items.each((i, a) -> items.set(i, Math.min(a, itemCapacity)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,8 +31,8 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
final NetProvider provider;
|
||||
|
||||
final PacketSerializer serializer = new PacketSerializer();
|
||||
final ByteBuffer writeBuffer = ByteBuffer.allocateDirect(1024 * 4);
|
||||
final ByteBuffer readBuffer = ByteBuffer.allocateDirect(1024 * 4);
|
||||
final ByteBuffer writeBuffer = ByteBuffer.allocateDirect(16384);
|
||||
final ByteBuffer readBuffer = ByteBuffer.allocateDirect(16384);
|
||||
|
||||
final CopyOnWriteArrayList<SteamConnection> connections = new CopyOnWriteArrayList<>();
|
||||
final IntMap<SteamConnection> steamConnections = new IntMap<>(); //maps steam ID -> valid net connection
|
||||
@ -131,9 +131,10 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
|
||||
writeBuffer.limit(writeBuffer.capacity());
|
||||
writeBuffer.position(0);
|
||||
serializer.write(writeBuffer, object);
|
||||
int length = writeBuffer.position();
|
||||
writeBuffer.flip();
|
||||
|
||||
snet.sendP2PPacket(currentServer, writeBuffer, mode == SendMode.tcp ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0);
|
||||
snet.sendP2PPacket(currentServer, writeBuffer, mode == SendMode.tcp || length >= 1200 ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0);
|
||||
}catch(Exception e){
|
||||
net.showError(e);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user