Compare commits

..

39 Commits

Author SHA1 Message Date
Tentyanuk
f46a9730a3 Update SERVERLIST.md (#8205) 2023-01-22 11:03:59 -05:00
Tentyanuk
d45cd7c15e Banned logic displays on sandbox (#8204) 2023-01-22 09:54:39 -05:00
Anuken
a84d52f5fe Removed Omnidustry sandbox due to moderation issues (#8203) 2023-01-22 09:26:09 -05:00
Anuken
330d37b7a5 Merge remote-tracking branch 'origin/master' 2023-01-22 08:59:36 -05:00
Anuken
d2792a4e9d Fixed #8202 2023-01-22 08:59:32 -05:00
Kotamus
c50a69d42a Update servers_v7.json (#8201)
Crawler arena
2023-01-21 09:40:26 -05:00
Anuken
ee689d1597 Merge remote-tracking branch 'origin/master' 2023-01-20 09:37:33 -05:00
Anuken
6ef8d64d46 Efficiency fix 2023-01-20 09:37:28 -05:00
eSK8er
0095e89673 Update servers_v7.json (#8145) 2023-01-19 00:34:13 -05:00
SachaTending
55d97ea202 add tendhost(not running) [reopened] (#8147) 2023-01-18 11:49:22 -05:00
Anuken
85b8868d2b Fixed #8194 2023-01-18 10:41:39 -05:00
Anuken
65e92ab6fc Merge remote-tracking branch 'origin/master' 2023-01-17 18:50:49 -05:00
Anuken
478baf2532 Fixed #8192 2023-01-17 18:50:44 -05:00
Joan Josep
0750348cb1 Update bundle_ca.properties (#8190) 2023-01-17 18:49:20 -05:00
UnCaughT
db6cbc5cc3 Update servers_v7.json (#8189)
HexPvP IP Change
2023-01-17 00:18:09 -05:00
Anuken
b4359c0489 Merge remote-tracking branch 'origin/master' 2023-01-16 15:28:45 -05:00
Anuken
977192bc54 Fixed #8187 2023-01-16 15:28:40 -05:00
南门阳德
d54b557a9f Revert #8176 (#8186)
Liquid turrets are used to give buff like wet but not do the damage. The ammo change is not appropriate.
2023-01-16 11:07:00 -05:00
Anuken
f6c97f4ff6 Fixed #8185 2023-01-16 11:06:34 -05:00
Anuken
66f4118896 Fixed #8184 2023-01-15 15:19:13 -05:00
Anuken
4a8f8c4ecf Merge remote-tracking branch 'origin/master' 2023-01-15 08:51:57 -05:00
Anuken
6d7c207b95 Fixed drawing of assembler payloads 2023-01-15 08:51:51 -05:00
DinnerWool
597bd31a0c Update servers_v7.json (#8183) 2023-01-15 08:42:59 -05:00
Knochi
98157f2852 Never use „tun“ in German language (#8179) 2023-01-14 14:41:14 -05:00
MEEPofFaith
5e324e71d4 Hitscan fix 2 (#8175)
* Revert "Reverting #8037"

Re-implement #8037

* Properly count collisions

Fix #8170
2023-01-14 10:05:30 -05:00
Anuken
3159ce6707 Merge remote-tracking branch 'origin/master' 2023-01-13 19:34:52 -05:00
Anuken
9b033532c8 Fixed #8177 2023-01-13 19:34:48 -05:00
Даркнесс#3729
0678592d59 Fix cheaty item and liquid turrets (#8176)
* Update Turret.java

* Update TractorBeamTurret.java

* Update TractorBeamTurret.java

* Update ItemTurret.java

* Update LiquidTurret.java
2023-01-13 16:51:36 -05:00
Anuken
00d6b0d483 Merge remote-tracking branch 'origin/master' 2023-01-13 09:59:05 -05:00
Anuken
598049265a Complete revert of #8019 2023-01-13 09:59:01 -05:00
Nunting
c3209f2cdd Update bundle_ko.properties (#8171) 2023-01-13 09:44:08 -05:00
Anuken
b2b4602c91 Reverting #8037 2023-01-13 09:42:28 -05:00
Anuken
b1e1fe4922 Merge remote-tracking branch 'origin/master' 2023-01-13 09:31:14 -05:00
Anuken
edcf3c4223 Fixed #8170 2023-01-13 09:31:10 -05:00
Github Actions
58315acfa3 Automatic bundle update 2023-01-13 03:53:33 +00:00
Anuken
ec9eadd660 encoding test 2023-01-12 22:52:32 -05:00
Anuken
7277892e33 Merge remote-tracking branch 'origin/master' 2023-01-12 17:01:52 -05:00
Anuken
54962a158d Fixed #8168 2023-01-12 17:01:47 -05:00
Даркнесс#3729
30dcbe1af3 Administration improvements (#8167)
* Administration improvements

Reduced the interval for preventing sending the same message because 50 seconds is too much and kinda confusing
Added saving and loading kicked IPs so they are saved even when the server crashes
Fixed smth in Config

* skill issue
2023-01-12 16:24:51 -05:00
22 changed files with 1048 additions and 1056 deletions

View File

@@ -9,7 +9,7 @@ You may want to add your server to this list. The steps for getting this done ar
1. **Ensure your server is properly moderated.** For the most part, this applies to survival servers, but PvP servers can be affected as well. 1. **Ensure your server is properly moderated.** For the most part, this applies to survival servers, but PvP servers can be affected as well.
You'll need to either hire some moderators, or make use of (currently non-existent) anti-grief and anti-curse plugins. You'll need to either hire some moderators, or make use of (currently non-existent) anti-grief and anti-curse plugins.
*Consider enabling a rate limit:* `config messageRateLimit 2` will make it so that players can only send messages every 2 seconds, for example. *Consider enabling a rate limit:* `config messageRateLimit 2` will make it so that players can only send messages every 2 seconds, for example.
2. Make sure that your server is able to handle inappropriate content - this includes NSFW display/sorter art and abusive messages. **Servers that allow such content will be removed immediately.** Consider banning display blocks if it is a problem for your server: `rules add bannedBlocks ["logic-display", "large-logic-display"]`. 2. Make sure that your server is able to handle inappropriate content - this includes NSFW display/sorter art and abusive messages. **Servers that allow such content will be removed immediately.** Consider banning display blocks if it is a problem for your server: `rules add bannedBlocks ["canvas", "logic-display", "large-logic-display"]`.
3. **Set an appropriate MOTD, name and description.** This is set with `config <name/desc/motd> <value>`. "Appropriate" means that: 3. **Set an appropriate MOTD, name and description.** This is set with `config <name/desc/motd> <value>`. "Appropriate" means that:
- Your name or description must reflect the type of server you're hosting. - Your name or description must reflect the type of server you're hosting.
Since new players may be exposed to the server list early on, put in a phrase like "Co-op survival" or "PvP" so players know what they're getting into. Yes, this is also displayed in the server mode info text, but having extra info in the name doesn't hurt. Since new players may be exposed to the server list early on, put in a phrase like "Co-op survival" or "PvP" so players know what they're getting into. Yes, this is also displayed in the server mode info text, but having extra info in the name doesn't hurt.

View File

@@ -1207,7 +1207,7 @@ rules.unitbuildspeedmultiplier = Multiplicador de la velocitat de producció d
rules.unitcostmultiplier = Multiplicador del cost de les unitats rules.unitcostmultiplier = Multiplicador del cost de les unitats
rules.unithealthmultiplier = Multiplicador de la salut de les unitats rules.unithealthmultiplier = Multiplicador de la salut de les unitats
rules.unitdamagemultiplier = Multiplicador del dany de les unitats rules.unitdamagemultiplier = Multiplicador del dany de les unitats
rules.unitcrashdamagemultiplier = Unit Crash Damage Multiplier rules.unitcrashdamagemultiplier = Multiplicador del dany de xoc de les unitats
rules.solarmultiplier = Multiplicador de lenergia solar rules.solarmultiplier = Multiplicador de lenergia solar
rules.unitcapvariable = Els nuclis contribueixen al límit dunitats rules.unitcapvariable = Els nuclis contribueixen al límit dunitats
rules.unitcap = Capacitat base dunitats rules.unitcap = Capacitat base dunitats

View File

@@ -1759,7 +1759,7 @@ hint.skip = Fertig
hint.desktopMove = Drücke [accent][[WASD][], um dich zu bewegen. hint.desktopMove = Drücke [accent][[WASD][], um dich zu bewegen.
hint.zoom = [accent]Scrolle[], um rein oder raus zu zoomen. hint.zoom = [accent]Scrolle[], um rein oder raus zu zoomen.
hint.desktopShoot = Benutze [accent][[Linksklick][], um zu schießen. hint.desktopShoot = Benutze [accent][[Linksklick][], um zu schießen.
hint.depositItems = Um Materialien in den Kern zu tun, ziehe sie von dir zum Kern. hint.depositItems = Um Materialien in den Kern zu verschieben, ziehe sie von dir zum Kern.
hint.respawn = Um im Kern zu respawnen, drücke [accent][[V][]. hint.respawn = Um im Kern zu respawnen, drücke [accent][[V][].
hint.respawn.mobile = Du steuerst nun eine Einheit oder einen Block. Um wieder zur normalen Einheit zu werden, [accent]drücke die Abbildung von dir oben links[]. hint.respawn.mobile = Du steuerst nun eine Einheit oder einen Block. Um wieder zur normalen Einheit zu werden, [accent]drücke die Abbildung von dir oben links[].
hint.desktopPause = Benutze [accent][[Leertaste][], um das Spiel zu pausieren oder entpausieren. hint.desktopPause = Benutze [accent][[Leertaste][], um das Spiel zu pausieren oder entpausieren.

File diff suppressed because it is too large Load Diff

View File

@@ -288,7 +288,7 @@ server.invalidport = 잘못된 포트 번호입니다!
server.error = [scarlet]서버 호스팅 오류 server.error = [scarlet]서버 호스팅 오류
save.new = 새로 저장 save.new = 새로 저장
save.overwrite = 저장된 슬롯을 덮어쓰시겠습니까? save.overwrite = 저장된 슬롯을 덮어쓰시겠습니까?
save.nocampaign = Individual save files from the campaign cannot be imported. save.nocampaign = 캠페인의 개별 저장 파일을 가져올 수 없습니다.
overwrite = 덮어쓰기 overwrite = 덮어쓰기
save.none = 저장된 파일을 찾을 수 없습니다! save.none = 저장된 파일을 찾을 수 없습니다!
savefail = 게임을 저장하지 못했습니다! savefail = 게임을 저장하지 못했습니다!
@@ -356,8 +356,8 @@ pausebuilding = [accent][[{0}][] 키를 눌러 건설을 일시중지
resumebuilding = [scarlet][[{0}][] 키를 눌러 건설을 재개 resumebuilding = [scarlet][[{0}][] 키를 눌러 건설을 재개
enablebuilding = [scarlet][[{0}][] 키를 눌러 건설을 활성 enablebuilding = [scarlet][[{0}][] 키를 눌러 건설을 활성
showui = UI가 숨겨졌습니다. [accent][[{0}][] 키를 눌러 UI를 활성화하세요. showui = UI가 숨겨졌습니다. [accent][[{0}][] 키를 눌러 UI를 활성화하세요.
commandmode.name = [accent]Command Mode commandmode.name = [accent]명령 모드
commandmode.nounits = [no units] commandmode.nounits = [기체 없음]
wave = [accent]{0}단계 wave = [accent]{0}단계
wave.cap = [accent]단계 {0}/{1} wave.cap = [accent]단계 {0}/{1}
wave.waiting = 다음 단계까지[lightgray] {0}초 wave.waiting = 다음 단계까지[lightgray] {0}초
@@ -441,7 +441,7 @@ waves.max = 기까지
waves.guardian = 수호자 waves.guardian = 수호자
waves.preview = 미리보기 waves.preview = 미리보기
waves.edit = 편집 waves.edit = 편집
waves.random = Random waves.random = 무작위
waves.copy = 클립보드로 복사하기 waves.copy = 클립보드로 복사하기
waves.load = 클립보드에서 불러오기 waves.load = 클립보드에서 불러오기
waves.invalid = 클립보드에 잘못된 단계 데이터가 있습니다. waves.invalid = 클립보드에 잘못된 단계 데이터가 있습니다.
@@ -700,7 +700,7 @@ sectors.enemybase = [scarlet]적 기지[]
sectors.vulnerable = [scarlet]취약함[] sectors.vulnerable = [scarlet]취약함[]
sectors.underattack = [scarlet]공격받고 있습니다! [accent]{0}% 손상됨[] sectors.underattack = [scarlet]공격받고 있습니다! [accent]{0}% 손상됨[]
sectors.underattack.nodamage = [scarlet]점령되지 않음 sectors.underattack.nodamage = [scarlet]점령되지 않음
sectors.survives = [accent]{0} 단계 이상 버티세요.[] sectors.survives = [accent]{0} 단계 버팀[]
sectors.go = 진입 sectors.go = 진입
sector.abandon = 포기 sector.abandon = 포기
sector.abandon.confirm = 이 지역의 코어가 자폭합니다.\n계속하시겠습니까? sector.abandon.confirm = 이 지역의 코어가 자폭합니다.\n계속하시겠습니까?
@@ -1205,7 +1205,7 @@ rules.unitbuildspeedmultiplier = 기체 생산속도 배수
rules.unitcostmultiplier = 기체 비용 배수 rules.unitcostmultiplier = 기체 비용 배수
rules.unithealthmultiplier = 기체 체력 배수 rules.unithealthmultiplier = 기체 체력 배수
rules.unitdamagemultiplier = 기체 피해량 배수 rules.unitdamagemultiplier = 기체 피해량 배수
rules.unitcrashdamagemultiplier = Unit Crash Damage Multiplier rules.unitcrashdamagemultiplier = 기체 파손 피해량 배수
rules.solarmultiplier = 태양광 전력 배수 rules.solarmultiplier = 태양광 전력 배수
rules.unitcapvariable = 코어 기체수 제한 추가 rules.unitcapvariable = 코어 기체수 제한 추가
rules.unitcap = 기본 기체 제한 rules.unitcap = 기본 기체 제한

View File

@@ -1277,6 +1277,7 @@ public class Blocks{
heatOutput = 3f; heatOutput = 3f;
regionRotated1 = 1; regionRotated1 = 1;
ambientSound = Sounds.hum; ambientSound = Sounds.hum;
itemCapacity = 0;
consumePower(100f / 60f); consumePower(100f / 60f);
}}; }};
@@ -1287,6 +1288,7 @@ public class Blocks{
drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawLiquidTile(Liquids.slag), new DrawDefault(), new DrawHeatOutput()); drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawLiquidTile(Liquids.slag), new DrawDefault(), new DrawHeatOutput());
size = 3; size = 3;
itemCapacity = 0;
liquidCapacity = 40f; liquidCapacity = 40f;
rotateDraw = false; rotateDraw = false;
regionRotated1 = 1; regionRotated1 = 1;

View File

@@ -383,7 +383,12 @@ public class Logic implements ApplicationListener{
public static void researched(Content content){ public static void researched(Content content){
if(!(content instanceof UnlockableContent u)) return; if(!(content instanceof UnlockableContent u)) return;
boolean was = !u.unlockedNow();
state.rules.researched.add(u.name); state.rules.researched.add(u.name);
if(!was){
Events.fire(new UnlockEvent(u));
}
} }
@Override @Override
@@ -401,6 +406,8 @@ public class Logic implements ApplicationListener{
Core.settings.forceSave(); Core.settings.forceSave();
} }
boolean runStateCheck = !net.client() && !world.isInvalidMap() && !state.isEditor() && state.rules.canGameOver;
if(state.isGame()){ if(state.isGame()){
if(!net.client()){ if(!net.client()){
state.enemies = Groups.unit.count(u -> u.team() == state.rules.waveTeam && u.isEnemy()); state.enemies = Groups.unit.count(u -> u.team() == state.rules.waveTeam && u.isEnemy());
@@ -466,9 +473,11 @@ public class Logic implements ApplicationListener{
Groups.update(); Groups.update();
} }
if(!net.client() && !world.isInvalidMap() && !state.isEditor() && state.rules.canGameOver){ if(runStateCheck){
checkGameState(); checkGameState();
} }
}else if(netServer.isWaitingForPlayers() && runStateCheck){
checkGameState();
} }
} }

View File

@@ -237,7 +237,8 @@ public class Damage{
seg2.set(seg1).add(vec); seg2.set(seg1).add(vec);
World.raycastEachWorld(x, y, seg2.x, seg2.y, (cx, cy) -> { World.raycastEachWorld(x, y, seg2.x, seg2.y, (cx, cy) -> {
Building tile = world.build(cx, cy); Building tile = world.build(cx, cy);
boolean collide = tile != null && hitter.checkUnderBuild(tile, cx * tilesize, cy * tilesize) && collidedBlocks.add(tile.pos()); boolean collide = tile != null && hitter.checkUnderBuild(tile, cx * tilesize, cy * tilesize)
&& ((tile.team != team && tile.collide(hitter)) || hitter.type.testCollision(hitter, tile)) && collidedBlocks.add(tile.pos());
if(collide){ if(collide){
collided.add(collidePool.obtain().set(cx * tilesize, cy * tilesize, tile)); collided.add(collidePool.obtain().set(cx * tilesize, cy * tilesize, tile));
@@ -275,17 +276,19 @@ public class Damage{
int[] collideCount = {0}; int[] collideCount = {0};
collided.sort(c -> hitter.dst2(c.x, c.y)); collided.sort(c -> hitter.dst2(c.x, c.y));
collided.each(c -> { collided.each(c -> {
if(hitter.damage > 0 && (pierceCap <= 0 || collideCount[0]++ < pierceCap)){ if(hitter.damage > 0 && (pierceCap <= 0 || collideCount[0] < pierceCap)){
if(c.target instanceof Unit u){ if(c.target instanceof Unit u){
effect.at(c.x, c.y); effect.at(c.x, c.y);
u.collision(hitter, c.x, c.y); u.collision(hitter, c.x, c.y);
hitter.collision(u, c.x, c.y); hitter.collision(u, c.x, c.y);
collideCount[0]++;
}else if(c.target instanceof Building tile){ }else if(c.target instanceof Building tile){
float health = tile.health; float health = tile.health;
if(tile.team != team && tile.collide(hitter)){ if(tile.team != team && tile.collide(hitter)){
tile.collision(hitter); tile.collision(hitter);
hitter.type.hit(hitter, c.x, c.y); hitter.type.hit(hitter, c.x, c.y);
collideCount[0]++;
} }
//try to heal the tile //try to heal the tile

View File

@@ -206,7 +206,7 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
//fix incorrect HEAD index since it was swapped //fix incorrect HEAD index since it was swapped
if(array.size > 0 && idx != array.size){ if(array.size > 0 && idx != array.size){
var swapped = array.items[idx]; var swapped = array.items[idx];
indexer.change(swapped, idx); if(indexer != null) indexer.change(swapped, idx);
} }
if(map != null){ if(map != null){
@@ -228,7 +228,7 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
//swap head with current //swap head with current
if(array.size > 1){ if(array.size > 1){
var head = array.items[array.size - 1]; var head = array.items[array.size - 1];
indexer.change(head, position); if(indexer != null) indexer.change(head, position);
array.items[position] = head; array.items[position] = head;
} }

View File

@@ -1746,7 +1746,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
public void updateConsumption(){ public void updateConsumption(){
//everything is valid when cheating //everything is valid when cheating
if(!block.hasConsumers || cheating()){ if(!block.hasConsumers || cheating()){
potentialEfficiency = efficiency = optionalEfficiency = enabled ? 1f : 0f; potentialEfficiency = efficiency = optionalEfficiency = enabled && shouldConsume() && productionValid() ? 1f : 0f;
updateEfficiencyMultiplier();
return; return;
} }

View File

@@ -306,7 +306,13 @@ public class MobileInput extends InputHandler implements GestureListener{
b.button(Icon.flipX, style, () -> flipPlans(selectPlans, true)); b.button(Icon.flipX, style, () -> flipPlans(selectPlans, true));
b.button(Icon.flipY, style, () -> flipPlans(selectPlans, false)); b.button(Icon.flipY, style, () -> flipPlans(selectPlans, false));
b.row(); b.row();
b.button(Icon.rotate, style, () -> rotatePlans(selectPlans, 1)); b.button(Icon.rotate, style, () -> rotatePlans(selectPlans, 1)).update(i -> {
var img = i.getCells().first().get();
img.setScale(-1f, 1f);
//why the heck doesn't setOrigin work for scaling
img.setTranslation(img.getWidth(), 0f);
});
}).margin(4f); }).margin(4f);
}); });

View File

@@ -320,8 +320,6 @@ public class JsonIO{
} }
}); });
//use short names for all filter types //use short names for all filter types
for(var filter : Maps.allFilterTypes){ for(var filter : Maps.allFilterTypes){
var i = filter.get(); var i = filter.get();

View File

@@ -48,8 +48,8 @@ public class Administration{
player.getInfo().messageInfractions = 0; player.getInfo().messageInfractions = 0;
} }
//prevent players from sending the same message twice in the span of 50 seconds //prevent players from sending the same message twice in the span of 10 seconds
if(message.equals(player.getInfo().lastSentMessage) && Time.timeSinceMillis(player.getInfo().lastMessageTime) < 1000 * 50){ if(message.equals(player.getInfo().lastSentMessage) && Time.timeSinceMillis(player.getInfo().lastMessageTime) < 1000 * 10){
player.sendMessage("[scarlet]You may not send the same message twice."); player.sendMessage("[scarlet]You may not send the same message twice.");
return null; return null;
} }
@@ -449,6 +449,7 @@ public class Administration{
public void save(){ public void save(){
Core.settings.putJson("player-data", playerInfo); Core.settings.putJson("player-data", playerInfo);
Core.settings.putJson("ip-kicks", kickedIPs);
Core.settings.putJson("ip-bans", String.class, bannedIPs); Core.settings.putJson("ip-bans", String.class, bannedIPs);
Core.settings.putJson("whitelist-ids", String.class, whitelist); Core.settings.putJson("whitelist-ids", String.class, whitelist);
Core.settings.putJson("banned-subnets", String.class, subnetBans); Core.settings.putJson("banned-subnets", String.class, subnetBans);
@@ -458,6 +459,7 @@ public class Administration{
private void load(){ private void load(){
//load default data //load default data
playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new); playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new);
kickedIPs = Core.settings.getJson("ip-kicks", ObjectMap.class, ObjectMap::new);
bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new); bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new);
whitelist = Core.settings.getJson("whitelist-ids", Seq.class, Seq::new); whitelist = Core.settings.getJson("whitelist-ids", Seq.class, Seq::new);
subnetBans = Core.settings.getJson("banned-subnets", Seq.class, Seq::new); subnetBans = Core.settings.getJson("banned-subnets", Seq.class, Seq::new);
@@ -488,7 +490,7 @@ public class Administration{
messageRateLimit = new Config("messageRateLimit", "Message rate limit in seconds. 0 to disable.", 0), messageRateLimit = new Config("messageRateLimit", "Message rate limit in seconds. 0 to disable.", 0),
messageSpamKick = new Config("messageSpamKick", "How many times a player must send a message before the cooldown to get kicked. 0 to disable.", 3), messageSpamKick = new Config("messageSpamKick", "How many times a player must send a message before the cooldown to get kicked. 0 to disable.", 3),
packetSpamLimit = new Config("packetSpamLimit", "Limit for packet count sent within 3sec that will lead to a blacklist + kick.", 300), packetSpamLimit = new Config("packetSpamLimit", "Limit for packet count sent within 3sec that will lead to a blacklist + kick.", 300),
chatSpamLimit = new Config("packetSpamLimit", "Limit for chat packet count sent within 2sec that will lead to a blacklist + kick. Not the same as a rate limit.", 20), chatSpamLimit = new Config("chatSpamLimit", "Limit for chat packet count sent within 2sec that will lead to a blacklist + kick. Not the same as a rate limit.", 20),
socketInput = new Config("socketInput", "Allows a local application to control this server through a local TCP socket.", false, "socket", () -> Events.fire(Trigger.socketConfigChanged)), socketInput = new Config("socketInput", "Allows a local application to control this server through a local TCP socket.", false, "socket", () -> Events.fire(Trigger.socketConfigChanged)),
socketInputPort = new Config("socketInputPort", "The port for socket input.", 6859, () -> Events.fire(Trigger.socketConfigChanged)), socketInputPort = new Config("socketInputPort", "The port for socket input.", 6859, () -> Events.fire(Trigger.socketConfigChanged)),
socketInputAddress = new Config("socketInputAddress", "The bind address for socket input.", "localhost", () -> Events.fire(Trigger.socketConfigChanged)), socketInputAddress = new Config("socketInputAddress", "The bind address for socket input.", "localhost", () -> Events.fire(Trigger.socketConfigChanged)),

View File

@@ -177,6 +177,15 @@ public class ResearchDialog extends BaseDialog{
}); });
} }
@Override
public Dialog show(){
if(net.client()){
ui.showInfo("@research.multiplayer");
return this;
}
return show(Core.scene);
}
void checkMargin(){ void checkMargin(){
if(Core.graphics.isPortrait() && showTechSelect){ if(Core.graphics.isPortrait() && showTechSelect){
itemDisplay.marginTop(60f); itemDisplay.marginTop(60f);

View File

@@ -105,7 +105,9 @@ public class BuildTurret extends BaseTurret{
unit.lookAt(angleTo(unit.buildPlan())); unit.lookAt(angleTo(unit.buildPlan()));
} }
checkSuppression(); if(checkSuppression()){
efficiency = potentialEfficiency = 0f;
}
unit.buildSpeedMultiplier(potentialEfficiency * timeScale); unit.buildSpeedMultiplier(potentialEfficiency * timeScale);
unit.speedMultiplier(potentialEfficiency * timeScale); unit.speedMultiplier(potentialEfficiency * timeScale);

View File

@@ -88,7 +88,7 @@ public class ItemTurret extends Turret{
super.onProximityAdded(); super.onProximityAdded();
//add first ammo item to cheaty blocks so they can shoot properly //add first ammo item to cheaty blocks so they can shoot properly
if(cheating() && ammo.size > 0){ if(cheating() && ammoTypes.size > 0){
handleItem(this, ammoTypes.entries().next().key); handleItem(this, ammoTypes.entries().next().key);
} }
} }

View File

@@ -500,7 +500,8 @@ public class Turret extends ReloadTurret{
if(ammo.size >= 2 && ammo.peek().amount < ammoPerShot && ammo.get(ammo.size - 2).amount >= ammoPerShot){ if(ammo.size >= 2 && ammo.peek().amount < ammoPerShot && ammo.get(ammo.size - 2).amount >= ammoPerShot){
ammo.swap(ammo.size - 1, ammo.size - 2); ammo.swap(ammo.size - 1, ammo.size - 2);
} }
return ammo.size > 0 && ammo.peek().amount >= ammoPerShot;
return ammo.size > 0 && ammo.peek().amount >= ammoPerShot || cheating();
} }
public boolean charging(){ public boolean charging(){

View File

@@ -61,7 +61,9 @@ public class GenericCrafter extends Block{
public void setStats(){ public void setStats(){
stats.timePeriod = craftTime; stats.timePeriod = craftTime;
super.setStats(); super.setStats();
if((hasItems && itemCapacity > 0) || outputItems != null){
stats.add(Stat.productionTime, craftTime / 60f, StatUnit.seconds); stats.add(Stat.productionTime, craftTime / 60f, StatUnit.seconds);
}
if(outputItems != null){ if(outputItems != null){
stats.add(Stat.output, StatValues.items(craftTime, outputItems)); stats.add(Stat.output, StatValues.items(craftTime, outputItems));

View File

@@ -26,7 +26,7 @@ public class HeatCrafter extends GenericCrafter{
addBar("heat", (HeatCrafterBuild entity) -> addBar("heat", (HeatCrafterBuild entity) ->
new Bar(() -> new Bar(() ->
Core.bundle.format("bar.heatpercent", (int)(entity.heat + 0.00001f), (int)(entity.efficiencyScale() * 100 + 0.0001f)), Core.bundle.format("bar.heatpercent", (int)(entity.heat + 0.01f), (int)(entity.efficiencyScale() * 100 + 0.01f)),
() -> Pal.lightOrange, () -> Pal.lightOrange,
() -> entity.heat / heatRequirement)); () -> entity.heat / heatRequirement));
} }

View File

@@ -479,6 +479,8 @@ public class UnitAssembler extends PayloadBlock{
Draw.rect(topRegion, x, y); Draw.rect(topRegion, x, y);
if(isPayload()) return;
//draw drone construction //draw drone construction
if(droneWarmup > 0.001f){ if(droneWarmup > 0.001f){
Draw.draw(Layer.blockOver + 0.2f, () -> { Draw.draw(Layer.blockOver + 0.2f, () -> {

View File

@@ -1,83 +1,26 @@
package mindustry.world.meta; package mindustry.world.meta;
import arc.struct.*;
import arc.util.*;
/** Environmental flags for different types of locations. */ /** Environmental flags for different types of locations. */
public class Env{ public class Env{
public static final int public static final int
//is on a planet //is on a planet
terrestrial, terrestrial = 1,
//is in space, no atmosphere //is in space, no atmosphere
space, space = 1 << 1,
//is underwater, on a planet //is underwater, on a planet
underwater, underwater = 1 << 2,
//has a spores //has a spores
spores, spores = 1 << 3,
//has a scorching env effect //has a scorching env effect
scorching, scorching = 1 << 4,
//has oil reservoirs //has oil reservoirs
groundOil, groundOil = 1 << 5,
//has water reservoirs //has water reservoirs
groundWater, groundWater = 1 << 6,
//has oxygen in the atmosphere //has oxygen in the atmosphere
oxygen, oxygen = 1 << 7,
//all attributes combined, only used for bitmasking purposes //all attributes combined, only used for bitmasking purposes
any = 0xffffffff, any = 0xffffffff,
//no attributes (0) //no attributes (0)
none = 0; none = 0;
//do NOT modify directly!
public static final ObjectIntMap<String> nameToId;
public static final IntMap<String> idToName;
static{
//last time i didn't use a static initializer i got a null pointer.
//i can probably just move the fields around, but i don't trust java enough for that
nameToId = new ObjectIntMap<>();
idToName = new IntMap<>();
terrestrial = add("terrestrial");
space = add("space");
underwater = add("underwater");
spores = add("spores");
scorching = add("scorching");
groundOil = add("groundOil");
groundWater = add("groundWater");
oxygen = add("oxygen");
}
public static int add(String key){
if(nameToId.containsKey(key)) throw new IllegalArgumentException("'" + key + "' env already exists.");
if(nameToId.size >= 32) throw new IllegalStateException("Max env count 32 exceeded.");
int id = 1 << nameToId.size;
nameToId.put(key, id);
idToName.put(id, key);
return id;
}
public static int remap(int mask, IntMap<String> idToName){
int out = 0;
for(int i = 0; i < 32; i++){
int key = 1 << i;
if((mask & key) == key){
String name = idToName.get(key);
if(name == null){
//if it's unmapped it's probably just some mods using constant value
out |= key;
continue;
}
int id = nameToId.get(name, -1);
if(id == -1){
Log.warn("Ignoring '@' env key.", name);
}else{
out |= id;
}
}
}
return out;
}
} }

View File

@@ -1,12 +1,16 @@
[ [
{ {
"name": "Explosive corp", "name": "Explosive corp",
"address": ["94.103.91.96:4545", "94.103.91.96:4848", "94.103.91.96:4949", "94.103.91.96:5050"] "address": ["94.103.91.96:4545", "94.103.91.96:4848", "94.103.91.96:4949", "94.103.91.96:5050", "94.103.91.96:5151"]
}, },
{ {
"name": "RCM", "name": "RCM",
"address": ["rcrms.ru:6567"] "address": ["rcrms.ru:6567"]
}, },
{
"name": "Tendhost",
"address": ["tendhost.ddns.net:7576"]
},
{ {
"name": "generic mindustry", "name": "generic mindustry",
"address": ["212.192.29.92:25554", "212.192.29.24:25298"] "address": ["212.192.29.92:25554", "212.192.29.24:25298"]
@@ -45,7 +49,7 @@
}, },
{ {
"name": "HexPvP Network", "name": "HexPvP Network",
"address": ["hexpvp.ml", "kycb42148.ddns.net:6614"] "address": ["hexpvp.ddns.net", "kycb42148.ddns.net:6614"]
}, },
{ {
"name": "Omega Hub", "name": "Omega Hub",
@@ -142,5 +146,13 @@
{ {
"name": "SubZero", "name": "SubZero",
"address": ["mintyserver.net"] "address": ["mintyserver.net"]
},
{
"name": "Router Pi",
"address": ["a55c81b7c4d6e6d604651a93f8af5cd83.asuscomm.com"]
},
{
"name": "Vndustry",
"address": ["vndustry.ddns.net","vndustry.ddns.net:6568"]
} }
] ]