Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f46a9730a3 | ||
|
|
d45cd7c15e | ||
|
|
a84d52f5fe | ||
|
|
330d37b7a5 | ||
|
|
d2792a4e9d | ||
|
|
c50a69d42a | ||
|
|
ee689d1597 | ||
|
|
6ef8d64d46 | ||
|
|
0095e89673 | ||
|
|
55d97ea202 | ||
|
|
85b8868d2b | ||
|
|
65e92ab6fc | ||
|
|
478baf2532 | ||
|
|
0750348cb1 | ||
|
|
db6cbc5cc3 | ||
|
|
b4359c0489 | ||
|
|
977192bc54 | ||
|
|
d54b557a9f | ||
|
|
f6c97f4ff6 | ||
|
|
66f4118896 | ||
|
|
4a8f8c4ecf | ||
|
|
6d7c207b95 | ||
|
|
597bd31a0c | ||
|
|
98157f2852 | ||
|
|
5e324e71d4 | ||
|
|
3159ce6707 | ||
|
|
9b033532c8 | ||
|
|
0678592d59 | ||
|
|
00d6b0d483 | ||
|
|
598049265a | ||
|
|
c3209f2cdd | ||
|
|
b2b4602c91 | ||
|
|
b1e1fe4922 | ||
|
|
edcf3c4223 | ||
|
|
58315acfa3 | ||
|
|
ec9eadd660 | ||
|
|
7277892e33 | ||
|
|
54962a158d | ||
|
|
30dcbe1af3 |
@@ -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.
|
||||||
|
|||||||
@@ -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 l’energia solar
|
rules.solarmultiplier = Multiplicador de l’energia solar
|
||||||
rules.unitcapvariable = Els nuclis contribueixen al límit d’unitats
|
rules.unitcapvariable = Els nuclis contribueixen al límit d’unitats
|
||||||
rules.unitcap = Capacitat base d’unitats
|
rules.unitcap = Capacitat base d’unitats
|
||||||
|
|||||||
@@ -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
@@ -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 = 기본 기체 제한
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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)),
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(){
|
||||||
|
|||||||
@@ -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();
|
||||||
stats.add(Stat.productionTime, craftTime / 60f, StatUnit.seconds);
|
if((hasItems && itemCapacity > 0) || outputItems != null){
|
||||||
|
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));
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, () -> {
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user