Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00d6b0d483 | ||
|
|
598049265a | ||
|
|
c3209f2cdd | ||
|
|
b2b4602c91 | ||
|
|
b1e1fe4922 | ||
|
|
edcf3c4223 | ||
|
|
58315acfa3 | ||
|
|
ec9eadd660 | ||
|
|
7277892e33 | ||
|
|
54962a158d | ||
|
|
30dcbe1af3 | ||
|
|
e92d5d2d2d | ||
|
|
411367f294 | ||
|
|
f49e05a915 |
@@ -629,7 +629,7 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
groupsBuilder.addField(ParameterizedTypeName.get(
|
groupsBuilder.addField(ParameterizedTypeName.get(
|
||||||
ClassName.bestGuess("mindustry.entities.EntityGroup"), itype), group.name, Modifier.PUBLIC, Modifier.STATIC);
|
ClassName.bestGuess("mindustry.entities.EntityGroup"), itype), group.name, Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
|
||||||
groupInit.addStatement("$L = new $T<>($L.class, $L, $L, (e, pos) -> (($L.IndexableEntity__$L)e).setIndex__$L(pos))", group.name, groupc, itype, group.spatial, group.mapping, packageName, group.name, group.name);
|
groupInit.addStatement("$L = new $T<>($L.class, $L, $L, (e, pos) -> { if(e instanceof $L.IndexableEntity__$L ix) ix.setIndex__$L(pos); })", group.name, groupc, itype, group.spatial, group.mapping, packageName, group.name, group.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
//write the groups
|
//write the groups
|
||||||
|
|||||||
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;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.pooling.*;
|
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
@@ -27,8 +26,6 @@ public class Damage{
|
|||||||
private static final Seq<Unit> units = new Seq<>();
|
private static final Seq<Unit> units = new Seq<>();
|
||||||
private static final IntSet collidedBlocks = new IntSet();
|
private static final IntSet collidedBlocks = new IntSet();
|
||||||
private static final IntFloatMap damages = new IntFloatMap();
|
private static final IntFloatMap damages = new IntFloatMap();
|
||||||
private static final Seq<Collided> collided = new Seq<>();
|
|
||||||
private static final Pool<Collided> collidePool = Pools.get(Collided.class, Collided::new);
|
|
||||||
private static final Seq<Building> builds = new Seq<>();
|
private static final Seq<Building> builds = new Seq<>();
|
||||||
private static final FloatSeq distances = new FloatSeq();
|
private static final FloatSeq distances = new FloatSeq();
|
||||||
|
|
||||||
@@ -187,7 +184,7 @@ public class Damage{
|
|||||||
return Math.min(distances.size < pierceCap || pierceCap < 0 ? length : Math.max(6f, distances.get(pierceCap - 1)), maxDst);
|
return Math.min(distances.size < pierceCap || pierceCap < 0 ? length : Math.max(6f, distances.get(pierceCap - 1)), maxDst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Collides a bullet with blocks in a laser, taking into account absorption blocks. Resulting length is stored in the bullet's fdata. */
|
/** TODO Collides a bullet with blocks in a laser, taking into account absorption blocks. Resulting length is stored in the bullet's fdata. */
|
||||||
public static float collideLaser(Bullet b, float length, boolean large, boolean laser, int pierceCap){
|
public static float collideLaser(Bullet b, float length, boolean large, boolean laser, int pierceCap){
|
||||||
float resultLength = findPierceLength(b, pierceCap, length);
|
float resultLength = findPierceLength(b, pierceCap, length);
|
||||||
|
|
||||||
@@ -229,26 +226,40 @@ public class Damage{
|
|||||||
length = findPierceLength(hitter, pierceCap, length);
|
length = findPierceLength(hitter, pierceCap, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO pierceCount ++ should happen in blocks AND units!
|
||||||
|
|
||||||
collidedBlocks.clear();
|
collidedBlocks.clear();
|
||||||
vec.trnsExact(angle, length);
|
vec.trnsExact(angle, length);
|
||||||
|
|
||||||
|
Intc2 collider = (cx, cy) -> {
|
||||||
|
Building tile = world.build(cx, cy);
|
||||||
|
boolean collide = tile != null && hitter.checkUnderBuild(tile, cx * tilesize, cy * tilesize) && collidedBlocks.add(tile.pos());
|
||||||
|
|
||||||
|
if(hitter.damage > 0){
|
||||||
|
float health = !collide ? 0 : tile.health;
|
||||||
|
|
||||||
|
if(collide && tile.team != team && tile.collide(hitter)){
|
||||||
|
tile.collision(hitter);
|
||||||
|
hitter.type.hit(hitter, cx * tilesize, cy * tilesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//try to heal the tile
|
||||||
|
if(collide && hitter.type.testCollision(hitter, tile)){
|
||||||
|
hitter.type.hitTile(hitter, tile, cx * tilesize, cy * tilesize, health, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if(hitter.type.collidesGround){
|
if(hitter.type.collidesGround){
|
||||||
seg1.set(x, y);
|
seg1.set(x, y);
|
||||||
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);
|
collider.get(cx, cy);
|
||||||
boolean collide = tile != null && hitter.checkUnderBuild(tile, cx * tilesize, cy * tilesize) && collidedBlocks.add(tile.pos());
|
|
||||||
if(collide){
|
|
||||||
collided.add(collidePool.obtain().set(cx * tilesize, cy * tilesize, tile));
|
|
||||||
|
|
||||||
for(Point2 p : Geometry.d4){
|
for(Point2 p : Geometry.d4){
|
||||||
Tile other = world.tile(p.x + cx, p.y + cy);
|
Tile other = world.tile(p.x + cx, p.y + cy);
|
||||||
if(other != null && (large || Intersector.intersectSegmentRectangle(seg1, seg2, other.getBounds(Tmp.r1)))){
|
if(other != null && (large || Intersector.intersectSegmentRectangle(seg1, seg2, other.getBounds(Tmp.r1)))){
|
||||||
Building build = other.build;
|
collider.get(cx + p.x, cy + p.y);
|
||||||
if(build != null && hitter.checkUnderBuild(build, cx * tilesize, cy * tilesize) && collidedBlocks.add(build.pos())){
|
|
||||||
collided.add(collidePool.obtain().set((p.x + cx * tilesize), (p.y + cy) * tilesize, build));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -260,44 +271,32 @@ public class Damage{
|
|||||||
rect.setPosition(x, y).setSize(vec.x, vec.y).normalize().grow(expand * 2f);
|
rect.setPosition(x, y).setSize(vec.x, vec.y).normalize().grow(expand * 2f);
|
||||||
float x2 = vec.x + x, y2 = vec.y + y;
|
float x2 = vec.x + x, y2 = vec.y + y;
|
||||||
|
|
||||||
Units.nearbyEnemies(team, rect, u -> {
|
Cons<Unit> cons = e -> {
|
||||||
if(u.checkTarget(hitter.type.collidesAir, hitter.type.collidesGround) && u.hittable()){
|
if(!e.hittable()) return;
|
||||||
u.hitbox(hitrect);
|
//the peirce cap works for units, but really terribly, I'm just disabling it for now.
|
||||||
|
//if(pierceCap > 0 && pierceCount > pierceCap) return;
|
||||||
|
|
||||||
|
e.hitbox(hitrect);
|
||||||
|
|
||||||
Vec2 vec = Geometry.raycastRect(x, y, x2, y2, hitrect.grow(expand * 2));
|
Vec2 vec = Geometry.raycastRect(x, y, x2, y2, hitrect.grow(expand * 2));
|
||||||
|
|
||||||
if(vec != null){
|
if(vec != null && hitter.damage > 0){
|
||||||
collided.add(collidePool.obtain().set(vec.x, vec.y, u));
|
effect.at(vec.x, vec.y);
|
||||||
|
e.collision(hitter, vec.x, vec.y);
|
||||||
|
hitter.collision(e, vec.x, vec.y);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
units.clear();
|
||||||
|
|
||||||
|
Units.nearbyEnemies(team, rect, u -> {
|
||||||
|
if(u.checkTarget(hitter.type.collidesAir, hitter.type.collidesGround)){
|
||||||
|
units.add(u);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
int[] collideCount = {0};
|
units.sort(u -> u.dst2(hitter));
|
||||||
collided.sort(c -> hitter.dst2(c.x, c.y));
|
units.each(cons);
|
||||||
collided.each(c -> {
|
|
||||||
if(hitter.damage > 0 && (pierceCap <= 0 || collideCount[0]++ < pierceCap)){
|
|
||||||
if(c.target instanceof Unit u){
|
|
||||||
effect.at(c.x, c.y);
|
|
||||||
u.collision(hitter, c.x, c.y);
|
|
||||||
hitter.collision(u, c.x, c.y);
|
|
||||||
}else if(c.target instanceof Building tile){
|
|
||||||
float health = tile.health;
|
|
||||||
|
|
||||||
if(tile.team != team && tile.collide(hitter)){
|
|
||||||
tile.collision(hitter);
|
|
||||||
hitter.type.hit(hitter, c.x, c.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//try to heal the tile
|
|
||||||
if(hitter.type.testCollision(hitter, tile)){
|
|
||||||
hitter.type.hitTile(hitter, tile, c.x, c.y, health, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
collidePool.freeAll(collided);
|
|
||||||
collided.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -614,16 +613,4 @@ public class Damage{
|
|||||||
public static float applyArmor(float damage, float armor){
|
public static float applyArmor(float damage, float armor){
|
||||||
return Math.max(damage - armor, minArmorDamage * damage);
|
return Math.max(damage - armor, minArmorDamage * damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Collided{
|
|
||||||
public float x, y;
|
|
||||||
public Teamc target;
|
|
||||||
|
|
||||||
public Collided set(float x, float y, Teamc target){
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.target = target;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ public class Puddles{
|
|||||||
if(tile.floor().solid) return;
|
if(tile.floor().solid) return;
|
||||||
|
|
||||||
Puddle p = map.get(tile.pos());
|
Puddle p = map.get(tile.pos());
|
||||||
if(p == null){
|
if(p == null || p.liquid == null){
|
||||||
Puddle puddle = Puddle.create();
|
Puddle puddle = Puddle.create();
|
||||||
puddle.tile = tile;
|
puddle.tile = tile;
|
||||||
puddle.liquid = liquid;
|
puddle.liquid = liquid;
|
||||||
@@ -107,6 +107,8 @@ public class Puddles{
|
|||||||
|
|
||||||
/** Reacts two liquids together at a location. */
|
/** Reacts two liquids together at a location. */
|
||||||
private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){
|
private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){
|
||||||
|
if(dest == null) return 0f;
|
||||||
|
|
||||||
if((dest.flammability > 0.3f && liquid.temperature > 0.7f) ||
|
if((dest.flammability > 0.3f && liquid.temperature > 0.7f) ||
|
||||||
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid
|
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid
|
||||||
Fires.create(tile);
|
Fires.create(tile);
|
||||||
|
|||||||
@@ -142,6 +142,8 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc, Syncc{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterSync(){
|
public void afterSync(){
|
||||||
|
if(liquid != null){
|
||||||
Puddles.register(self());
|
Puddles.register(self());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package mindustry.io;
|
|||||||
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.serialization.*;
|
import arc.util.serialization.*;
|
||||||
import arc.util.serialization.Json.*;
|
import arc.util.serialization.Json.*;
|
||||||
@@ -79,30 +78,6 @@ public class JsonIO{
|
|||||||
json.setElementType(Rules.class, "spawns", SpawnGroup.class);
|
json.setElementType(Rules.class, "spawns", SpawnGroup.class);
|
||||||
json.setElementType(Rules.class, "loadout", ItemStack.class);
|
json.setElementType(Rules.class, "loadout", ItemStack.class);
|
||||||
|
|
||||||
json.setSerializer(Rules.class, new Serializer<>(){
|
|
||||||
@Override
|
|
||||||
public void write(Json json, Rules object, Class knownType){
|
|
||||||
json.writeObjectStart();
|
|
||||||
json.writeFields(object);
|
|
||||||
json.writeValue("envMapping", Env.idToName, IntMap.class);
|
|
||||||
json.writeObjectEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Rules read(Json json, JsonValue jsonData, Class type){
|
|
||||||
Rules out = baseObject instanceof Rules rules ? rules : new Rules();
|
|
||||||
json.readFields(out, jsonData);
|
|
||||||
|
|
||||||
// Older Rules data doesn't have env mapping.
|
|
||||||
if(jsonData.has("envMapping")){
|
|
||||||
IntMap<String> idToName = json.readValue(IntMap.class, jsonData.get("envMapping"));
|
|
||||||
out.env = Env.remap(out.env, idToName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
json.setSerializer(Color.class, new Serializer<>(){
|
json.setSerializer(Color.class, new Serializer<>(){
|
||||||
@Override
|
@Override
|
||||||
public void write(Json json, Color object, Class knownType){
|
public void write(Json json, Color object, Class knownType){
|
||||||
@@ -345,6 +320,8 @@ 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();
|
||||||
@@ -352,9 +329,8 @@ public class JsonIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object baseObject;
|
|
||||||
|
|
||||||
static class CustomJson extends Json{
|
static class CustomJson extends Json{
|
||||||
|
private Object baseObject;
|
||||||
|
|
||||||
{ apply(this); }
|
{ apply(this); }
|
||||||
|
|
||||||
@@ -364,7 +340,7 @@ public class JsonIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> T fromBaseJson(Class<T> type, T base, String json){
|
public <T> T fromBaseJson(Class<T> type, T base, String json){
|
||||||
baseObject = base;
|
this.baseObject = base;
|
||||||
return readValue(type, null, new JsonReader().parse(json));
|
return readValue(type, null, new JsonReader().parse(json));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)),
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ public class ArcNetProvider implements NetProvider{
|
|||||||
}
|
}
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(packet.getData());
|
ByteBuffer buffer = ByteBuffer.wrap(packet.getData());
|
||||||
Host host = NetworkIO.readServerData((int)Time.timeSinceMillis(time), packet.getAddress().getHostAddress(), buffer);
|
Host host = NetworkIO.readServerData((int)Time.timeSinceMillis(time), packet.getAddress().getHostAddress(), buffer);
|
||||||
callback.get(host);
|
Core.app.post(() -> callback.get(host));
|
||||||
foundAddresses.add(packet.getAddress());
|
foundAddresses.add(packet.getAddress());
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
//don't crash when there's an error pinging a server or parsing data
|
//don't crash when there's an error pinging a server or parsing data
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user