mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-10-03 20:00:26 +03:00
Compare 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(
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -288,7 +288,7 @@ server.invalidport = 잘못된 포트 번호입니다!
|
||||
server.error = [scarlet]서버 호스팅 오류
|
||||
save.new = 새로 저장
|
||||
save.overwrite = 저장된 슬롯을 덮어쓰시겠습니까?
|
||||
save.nocampaign = Individual save files from the campaign cannot be imported.
|
||||
save.nocampaign = 캠페인의 개별 저장 파일을 가져올 수 없습니다.
|
||||
overwrite = 덮어쓰기
|
||||
save.none = 저장된 파일을 찾을 수 없습니다!
|
||||
savefail = 게임을 저장하지 못했습니다!
|
||||
@@ -356,8 +356,8 @@ pausebuilding = [accent][[{0}][] 키를 눌러 건설을 일시중지
|
||||
resumebuilding = [scarlet][[{0}][] 키를 눌러 건설을 재개
|
||||
enablebuilding = [scarlet][[{0}][] 키를 눌러 건설을 활성
|
||||
showui = UI가 숨겨졌습니다. [accent][[{0}][] 키를 눌러 UI를 활성화하세요.
|
||||
commandmode.name = [accent]Command Mode
|
||||
commandmode.nounits = [no units]
|
||||
commandmode.name = [accent]명령 모드
|
||||
commandmode.nounits = [기체 없음]
|
||||
wave = [accent]{0}단계
|
||||
wave.cap = [accent]단계 {0}/{1}
|
||||
wave.waiting = 다음 단계까지[lightgray] {0}초
|
||||
@@ -441,7 +441,7 @@ waves.max = 기까지
|
||||
waves.guardian = 수호자
|
||||
waves.preview = 미리보기
|
||||
waves.edit = 편집
|
||||
waves.random = Random
|
||||
waves.random = 무작위
|
||||
waves.copy = 클립보드로 복사하기
|
||||
waves.load = 클립보드에서 불러오기
|
||||
waves.invalid = 클립보드에 잘못된 단계 데이터가 있습니다.
|
||||
@@ -700,7 +700,7 @@ sectors.enemybase = [scarlet]적 기지[]
|
||||
sectors.vulnerable = [scarlet]취약함[]
|
||||
sectors.underattack = [scarlet]공격받고 있습니다! [accent]{0}% 손상됨[]
|
||||
sectors.underattack.nodamage = [scarlet]점령되지 않음
|
||||
sectors.survives = [accent]{0} 단계 이상 버티세요.[]
|
||||
sectors.survives = [accent]{0} 단계 버팀[]
|
||||
sectors.go = 진입
|
||||
sector.abandon = 포기
|
||||
sector.abandon.confirm = 이 지역의 코어가 자폭합니다.\n계속하시겠습니까?
|
||||
@@ -1205,7 +1205,7 @@ rules.unitbuildspeedmultiplier = 기체 생산속도 배수
|
||||
rules.unitcostmultiplier = 기체 비용 배수
|
||||
rules.unithealthmultiplier = 기체 체력 배수
|
||||
rules.unitdamagemultiplier = 기체 피해량 배수
|
||||
rules.unitcrashdamagemultiplier = Unit Crash Damage Multiplier
|
||||
rules.unitcrashdamagemultiplier = 기체 파손 피해량 배수
|
||||
rules.solarmultiplier = 태양광 전력 배수
|
||||
rules.unitcapvariable = 코어 기체수 제한 추가
|
||||
rules.unitcap = 기본 기체 제한
|
||||
|
||||
@@ -1277,6 +1277,7 @@ public class Blocks{
|
||||
heatOutput = 3f;
|
||||
regionRotated1 = 1;
|
||||
ambientSound = Sounds.hum;
|
||||
itemCapacity = 0;
|
||||
consumePower(100f / 60f);
|
||||
}};
|
||||
|
||||
@@ -1287,6 +1288,7 @@ public class Blocks{
|
||||
|
||||
drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawLiquidTile(Liquids.slag), new DrawDefault(), new DrawHeatOutput());
|
||||
size = 3;
|
||||
itemCapacity = 0;
|
||||
liquidCapacity = 40f;
|
||||
rotateDraw = false;
|
||||
regionRotated1 = 1;
|
||||
|
||||
@@ -6,7 +6,6 @@ import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.pooling.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.game.EventType.*;
|
||||
@@ -27,8 +26,6 @@ public class Damage{
|
||||
private static final Seq<Unit> units = new Seq<>();
|
||||
private static final IntSet collidedBlocks = new IntSet();
|
||||
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 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);
|
||||
}
|
||||
|
||||
/** 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){
|
||||
float resultLength = findPierceLength(b, pierceCap, length);
|
||||
|
||||
@@ -229,26 +226,40 @@ public class Damage{
|
||||
length = findPierceLength(hitter, pierceCap, length);
|
||||
}
|
||||
|
||||
//TODO pierceCount ++ should happen in blocks AND units!
|
||||
|
||||
collidedBlocks.clear();
|
||||
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){
|
||||
seg1.set(x, y);
|
||||
seg2.set(seg1).add(vec);
|
||||
World.raycastEachWorld(x, y, seg2.x, seg2.y, (cx, cy) -> {
|
||||
Building tile = world.build(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));
|
||||
collider.get(cx, cy);
|
||||
|
||||
for(Point2 p : Geometry.d4){
|
||||
Tile other = world.tile(p.x + cx, p.y + cy);
|
||||
if(other != null && (large || Intersector.intersectSegmentRectangle(seg1, seg2, other.getBounds(Tmp.r1)))){
|
||||
Building build = other.build;
|
||||
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));
|
||||
}
|
||||
}
|
||||
for(Point2 p : Geometry.d4){
|
||||
Tile other = world.tile(p.x + cx, p.y + cy);
|
||||
if(other != null && (large || Intersector.intersectSegmentRectangle(seg1, seg2, other.getBounds(Tmp.r1)))){
|
||||
collider.get(cx + p.x, cy + p.y);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -260,44 +271,32 @@ public class Damage{
|
||||
rect.setPosition(x, y).setSize(vec.x, vec.y).normalize().grow(expand * 2f);
|
||||
float x2 = vec.x + x, y2 = vec.y + y;
|
||||
|
||||
Cons<Unit> cons = e -> {
|
||||
if(!e.hittable()) return;
|
||||
//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));
|
||||
|
||||
if(vec != null && hitter.damage > 0){
|
||||
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) && u.hittable()){
|
||||
u.hitbox(hitrect);
|
||||
|
||||
Vec2 vec = Geometry.raycastRect(x, y, x2, y2, hitrect.grow(expand * 2));
|
||||
|
||||
if(vec != null){
|
||||
collided.add(collidePool.obtain().set(vec.x, vec.y, u));
|
||||
}
|
||||
if(u.checkTarget(hitter.type.collidesAir, hitter.type.collidesGround)){
|
||||
units.add(u);
|
||||
}
|
||||
});
|
||||
|
||||
int[] collideCount = {0};
|
||||
collided.sort(c -> hitter.dst2(c.x, c.y));
|
||||
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();
|
||||
units.sort(u -> u.dst2(hitter));
|
||||
units.each(cons);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,7 +338,7 @@ public class Damage{
|
||||
*/
|
||||
public static Healthc linecast(Bullet hitter, float x, float y, float angle, float length){
|
||||
vec.trns(angle, length);
|
||||
|
||||
|
||||
tmpBuilding = null;
|
||||
|
||||
if(hitter.type.collidesGround){
|
||||
@@ -614,16 +613,4 @@ public class Damage{
|
||||
public static float applyArmor(float damage, float armor){
|
||||
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;
|
||||
|
||||
Puddle p = map.get(tile.pos());
|
||||
if(p == null){
|
||||
if(p == null || p.liquid == null){
|
||||
Puddle puddle = Puddle.create();
|
||||
puddle.tile = tile;
|
||||
puddle.liquid = liquid;
|
||||
@@ -107,6 +107,8 @@ public class Puddles{
|
||||
|
||||
/** Reacts two liquids together at a location. */
|
||||
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) ||
|
||||
(liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid
|
||||
Fires.create(tile);
|
||||
|
||||
@@ -142,6 +142,8 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc, Syncc{
|
||||
|
||||
@Override
|
||||
public void afterSync(){
|
||||
Puddles.register(self());
|
||||
if(liquid != null){
|
||||
Puddles.register(self());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package mindustry.io;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.serialization.*;
|
||||
import arc.util.serialization.Json.*;
|
||||
@@ -79,30 +78,6 @@ public class JsonIO{
|
||||
json.setElementType(Rules.class, "spawns", SpawnGroup.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<>(){
|
||||
@Override
|
||||
public void write(Json json, Color object, Class knownType){
|
||||
@@ -345,6 +320,8 @@ public class JsonIO{
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
//use short names for all filter types
|
||||
for(var filter : Maps.allFilterTypes){
|
||||
var i = filter.get();
|
||||
@@ -352,9 +329,8 @@ public class JsonIO{
|
||||
}
|
||||
}
|
||||
|
||||
private static Object baseObject;
|
||||
|
||||
static class CustomJson extends Json{
|
||||
private Object baseObject;
|
||||
|
||||
{ apply(this); }
|
||||
|
||||
@@ -364,7 +340,7 @@ public class JsonIO{
|
||||
}
|
||||
|
||||
public <T> T fromBaseJson(Class<T> type, T base, String json){
|
||||
baseObject = base;
|
||||
this.baseObject = base;
|
||||
return readValue(type, null, new JsonReader().parse(json));
|
||||
}
|
||||
|
||||
@@ -376,4 +352,4 @@ public class JsonIO{
|
||||
return baseObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,8 +48,8 @@ public class Administration{
|
||||
player.getInfo().messageInfractions = 0;
|
||||
}
|
||||
|
||||
//prevent players from sending the same message twice in the span of 50 seconds
|
||||
if(message.equals(player.getInfo().lastSentMessage) && Time.timeSinceMillis(player.getInfo().lastMessageTime) < 1000 * 50){
|
||||
//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 * 10){
|
||||
player.sendMessage("[scarlet]You may not send the same message twice.");
|
||||
return null;
|
||||
}
|
||||
@@ -449,6 +449,7 @@ public class Administration{
|
||||
|
||||
public void save(){
|
||||
Core.settings.putJson("player-data", playerInfo);
|
||||
Core.settings.putJson("ip-kicks", kickedIPs);
|
||||
Core.settings.putJson("ip-bans", String.class, bannedIPs);
|
||||
Core.settings.putJson("whitelist-ids", String.class, whitelist);
|
||||
Core.settings.putJson("banned-subnets", String.class, subnetBans);
|
||||
@@ -458,6 +459,7 @@ public class Administration{
|
||||
private void load(){
|
||||
//load default data
|
||||
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);
|
||||
whitelist = Core.settings.getJson("whitelist-ids", 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),
|
||||
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),
|
||||
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)),
|
||||
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)),
|
||||
|
||||
@@ -261,7 +261,7 @@ public class ArcNetProvider implements NetProvider{
|
||||
}
|
||||
ByteBuffer buffer = ByteBuffer.wrap(packet.getData());
|
||||
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());
|
||||
}catch(Exception e){
|
||||
//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(){
|
||||
stats.timePeriod = craftTime;
|
||||
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){
|
||||
stats.add(Stat.output, StatValues.items(craftTime, outputItems));
|
||||
|
||||
@@ -1,83 +1,26 @@
|
||||
package mindustry.world.meta;
|
||||
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
|
||||
/** Environmental flags for different types of locations. */
|
||||
public class Env{
|
||||
public static final int
|
||||
//is on a planet
|
||||
terrestrial,
|
||||
terrestrial = 1,
|
||||
//is in space, no atmosphere
|
||||
space,
|
||||
space = 1 << 1,
|
||||
//is underwater, on a planet
|
||||
underwater,
|
||||
underwater = 1 << 2,
|
||||
//has a spores
|
||||
spores,
|
||||
spores = 1 << 3,
|
||||
//has a scorching env effect
|
||||
scorching,
|
||||
scorching = 1 << 4,
|
||||
//has oil reservoirs
|
||||
groundOil,
|
||||
groundOil = 1 << 5,
|
||||
//has water reservoirs
|
||||
groundWater,
|
||||
groundWater = 1 << 6,
|
||||
//has oxygen in the atmosphere
|
||||
oxygen,
|
||||
oxygen = 1 << 7,
|
||||
//all attributes combined, only used for bitmasking purposes
|
||||
any = 0xffffffff,
|
||||
//no attributes (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