Merge branch 'master' of https://github.com/Anuken/Mindustry into v105
@@ -77,7 +77,11 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
for(Smethod elem : component.methods()){
|
for(Smethod elem : component.methods()){
|
||||||
if(elem.is(Modifier.ABSTRACT) || elem.is(Modifier.NATIVE)) continue;
|
if(elem.is(Modifier.ABSTRACT) || elem.is(Modifier.NATIVE)) continue;
|
||||||
//get all statements in the method, store them
|
//get all statements in the method, store them
|
||||||
methodBlocks.put(elem.descString(), elem.tree().getBody().toString());
|
methodBlocks.put(elem.descString(), elem.tree().getBody().toString()
|
||||||
|
//replace all self() invocations with this
|
||||||
|
.replaceAll("this\\.<(.*)>self\\(\\)", "this")
|
||||||
|
.replaceAll("self\\(\\)", "this")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 150 B After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 121 B |
|
After Width: | Height: | Size: 628 B |
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 435 B |
|
After Width: | Height: | Size: 854 B |
|
Before Width: | Height: | Size: 904 B After Width: | Height: | Size: 671 B |
|
Before Width: | Height: | Size: 984 B After Width: | Height: | Size: 893 B |
|
After Width: | Height: | Size: 459 B |
|
After Width: | Height: | Size: 355 B |
@@ -4,6 +4,5 @@
|
|||||||
flattenPaths: true,
|
flattenPaths: true,
|
||||||
maxWidth: 4096,
|
maxWidth: 4096,
|
||||||
maxHeight: 4096,
|
maxHeight: 4096,
|
||||||
minHeight: 2048,
|
|
||||||
fast: true
|
fast: true
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -20,7 +20,8 @@ gameover = Game Over
|
|||||||
gameover.pvp = The[accent] {0}[] team is victorious!
|
gameover.pvp = The[accent] {0}[] team is victorious!
|
||||||
highscore = [accent]New highscore!
|
highscore = [accent]New highscore!
|
||||||
copied = Copied.
|
copied = Copied.
|
||||||
indevpopup = [accent]v6[] is currently in [accent]alpha[].\n[lightgray]This means:[]\n[scarlet]- The campaign is completely unfinished[]\n- Content is missing\n - Most [scarlet]Unit AI[] does not work properly\n- Many units are unfinished\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[].
|
indev.popup = [accent]v6[] is currently in [accent]alpha[].\n[lightgray]This means:[]\n[scarlet]- The campaign is completely unfinished[]\n- Content is missing\n - Most [scarlet]Unit AI[] does not work properly\n- Many units are unfinished\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[].
|
||||||
|
indev.notready = This part of the game isn't ready yet
|
||||||
|
|
||||||
load.sound = Sounds
|
load.sound = Sounds
|
||||||
load.map = Maps
|
load.map = Maps
|
||||||
@@ -615,6 +616,8 @@ blocks.inaccuracy = Inaccuracy
|
|||||||
blocks.shots = Shots
|
blocks.shots = Shots
|
||||||
blocks.reload = Shots/Second
|
blocks.reload = Shots/Second
|
||||||
blocks.ammo = Ammo
|
blocks.ammo = Ammo
|
||||||
|
blocks.shieldhealth = Shield Health
|
||||||
|
blocks.cooldowntime = Cooldown Time
|
||||||
|
|
||||||
bar.drilltierreq = Better Drill Required
|
bar.drilltierreq = Better Drill Required
|
||||||
bar.noresources = Missing Resources
|
bar.noresources = Missing Resources
|
||||||
@@ -662,6 +665,7 @@ unit.persecond = /sec
|
|||||||
unit.perminute = /min
|
unit.perminute = /min
|
||||||
unit.timesspeed = x speed
|
unit.timesspeed = x speed
|
||||||
unit.percent = %
|
unit.percent = %
|
||||||
|
unit.shieldhealth = shield health
|
||||||
unit.items = items
|
unit.items = items
|
||||||
unit.thousands = k
|
unit.thousands = k
|
||||||
unit.millions = mil
|
unit.millions = mil
|
||||||
@@ -789,6 +793,9 @@ keybind.diagonal_placement.name = Diagonal Placement
|
|||||||
keybind.pick.name = Pick Block
|
keybind.pick.name = Pick Block
|
||||||
keybind.break_block.name = Break Block
|
keybind.break_block.name = Break Block
|
||||||
keybind.deselect.name = Deselect
|
keybind.deselect.name = Deselect
|
||||||
|
keybind.pickupCargo.name = Pickup Cargo
|
||||||
|
keybind.dropCargo.name = Drop Cargo
|
||||||
|
keybind.command.name = Command
|
||||||
keybind.shoot.name = Shoot
|
keybind.shoot.name = Shoot
|
||||||
keybind.zoom.name = Zoom
|
keybind.zoom.name = Zoom
|
||||||
keybind.menu.name = Menu
|
keybind.menu.name = Menu
|
||||||
@@ -876,9 +883,11 @@ liquid.water.name = Water
|
|||||||
liquid.slag.name = Slag
|
liquid.slag.name = Slag
|
||||||
liquid.oil.name = Oil
|
liquid.oil.name = Oil
|
||||||
liquid.cryofluid.name = Cryofluid
|
liquid.cryofluid.name = Cryofluid
|
||||||
|
|
||||||
item.explosiveness = [lightgray]Explosiveness: {0}%
|
item.explosiveness = [lightgray]Explosiveness: {0}%
|
||||||
item.flammability = [lightgray]Flammability: {0}%
|
item.flammability = [lightgray]Flammability: {0}%
|
||||||
item.radioactivity = [lightgray]Radioactivity: {0}%
|
item.radioactivity = [lightgray]Radioactivity: {0}%
|
||||||
|
|
||||||
unit.health = [lightgray]Health: {0}
|
unit.health = [lightgray]Health: {0}
|
||||||
unit.speed = [lightgray]Speed: {0}
|
unit.speed = [lightgray]Speed: {0}
|
||||||
unit.weapon = [lightgray]Weapon: {0}
|
unit.weapon = [lightgray]Weapon: {0}
|
||||||
@@ -914,6 +923,8 @@ unit.mega.name = Mega
|
|||||||
unit.risso.name = Risso
|
unit.risso.name = Risso
|
||||||
unit.minke.name = Minke
|
unit.minke.name = Minke
|
||||||
unit.bryde.name = Bryde
|
unit.bryde.name = Bryde
|
||||||
|
unit.sei.name = Sei
|
||||||
|
unit.omura.name = Omura
|
||||||
unit.alpha.name = Alpha
|
unit.alpha.name = Alpha
|
||||||
unit.beta.name = Beta
|
unit.beta.name = Beta
|
||||||
unit.gamma.name = Gamma
|
unit.gamma.name = Gamma
|
||||||
@@ -979,6 +990,7 @@ block.dune-wall.name = Dune Wall
|
|||||||
block.pine.name = Pine
|
block.pine.name = Pine
|
||||||
block.dirt.name = Dirt
|
block.dirt.name = Dirt
|
||||||
block.dirt-wall.name = Dirt Wall
|
block.dirt-wall.name = Dirt Wall
|
||||||
|
block.mud.name = Mud
|
||||||
block.white-tree-dead.name = White Tree Dead
|
block.white-tree-dead.name = White Tree Dead
|
||||||
block.white-tree.name = White Tree
|
block.white-tree.name = White Tree
|
||||||
block.spore-cluster.name = Spore Cluster
|
block.spore-cluster.name = Spore Cluster
|
||||||
@@ -997,7 +1009,6 @@ block.dark-metal.name = Dark Metal
|
|||||||
block.basalt.name = Basalt
|
block.basalt.name = Basalt
|
||||||
block.hotrock.name = Hot Rock
|
block.hotrock.name = Hot Rock
|
||||||
block.magmarock.name = Magma Rock
|
block.magmarock.name = Magma Rock
|
||||||
block.cliffs.name = Cliffs
|
|
||||||
block.copper-wall.name = Copper Wall
|
block.copper-wall.name = Copper Wall
|
||||||
block.copper-wall-large.name = Large Copper Wall
|
block.copper-wall-large.name = Large Copper Wall
|
||||||
block.titanium-wall.name = Titanium Wall
|
block.titanium-wall.name = Titanium Wall
|
||||||
|
|||||||
@@ -803,7 +803,7 @@ rules.title.unit = 유닛
|
|||||||
rules.title.experimental = 실험적인 기능
|
rules.title.experimental = 실험적인 기능
|
||||||
rules.title.environment = 환경
|
rules.title.environment = 환경
|
||||||
rules.lighting = 조명
|
rules.lighting = 조명
|
||||||
rules.ambientlight = 주변 조명
|
rules.ambientlight = 자연 조명
|
||||||
rules.solarpowermultiplier = 태양광 발전 배수
|
rules.solarpowermultiplier = 태양광 발전 배수
|
||||||
|
|
||||||
content.item.name = 자원
|
content.item.name = 자원
|
||||||
@@ -856,17 +856,20 @@ unit.crawler.name = 크롤러
|
|||||||
unit.atrax.name = 아트락스
|
unit.atrax.name = 아트락스
|
||||||
unit.spiroct.name = 스피록트
|
unit.spiroct.name = 스피록트
|
||||||
unit.arkyid.name = 아키드
|
unit.arkyid.name = 아키드
|
||||||
unit.flare.name = 화염
|
unit.toxipod.name = 독소포드
|
||||||
unit.horizon.name = 수평선
|
unit.flare.name = 플레어
|
||||||
unit.zenith.name = 천정
|
unit.horizon.name = 호라이즌
|
||||||
unit.antumbra.name = 그림자
|
unit.zenith.name = 제니스
|
||||||
unit.eclipse.name = 일식
|
unit.antumbra.name = 안텀브라
|
||||||
|
unit.eclipse.name = 이클립스
|
||||||
unit.mono.name = 모노
|
unit.mono.name = 모노
|
||||||
unit.poly.name = 폴리
|
unit.poly.name = 폴리
|
||||||
unit.mega.name = 메가
|
unit.mega.name = 메가
|
||||||
unit.risso.name = 리소
|
unit.risso.name = 리소
|
||||||
unit.minke.name = 민케
|
unit.minke.name = 민케
|
||||||
unit.bryde.name = 브리드
|
unit.bryde.name = 브리드
|
||||||
|
unit.sei.name = 세이
|
||||||
|
unit.omura.name = 오무라
|
||||||
unit.alpha.name = 알파
|
unit.alpha.name = 알파
|
||||||
unit.beta.name = 베타
|
unit.beta.name = 베타
|
||||||
unit.gamma.name = 감마
|
unit.gamma.name = 감마
|
||||||
@@ -877,21 +880,21 @@ block.sand-boulder.name = 사암
|
|||||||
block.grass.name = 잔디
|
block.grass.name = 잔디
|
||||||
block.slag.name = 광재
|
block.slag.name = 광재
|
||||||
block.salt.name = 소금
|
block.salt.name = 소금
|
||||||
block.saltrocks.name = 소금 바위
|
block.salt-wall.name = 소금 벽
|
||||||
block.pebbles.name = 조약돌
|
block.pebbles.name = 조약돌
|
||||||
block.tendrils.name = 덩굴
|
block.tendrils.name = 덩굴
|
||||||
block.sandrocks.name = 모래 바위
|
block.sand-wall.name = 모래 벽
|
||||||
block.spore-pine.name = 포자 덮인 소나무
|
block.spore-pine.name = 포자 덮인 소나무
|
||||||
block.sporerocks.name = 포자 바위
|
block.spore-wall.name = 포자 벽
|
||||||
block.rock.name = 돌
|
block.boulder.name = 돌
|
||||||
block.snowrock.name = 눈덩이
|
block.snow-boulder.name = 눈덩이
|
||||||
block.snow-pine.name = 눈 덮인 소나무
|
block.snow-pine.name = 눈 덮인 소나무
|
||||||
block.shale.name = 이판암
|
block.shale.name = 이판암
|
||||||
block.shale-boulder.name = 둥근 이판암
|
block.shale-boulder.name = 둥근 이판암
|
||||||
block.moss.name = 이끼
|
block.moss.name = 이끼
|
||||||
block.shrubs.name = 관목
|
block.shrubs.name = 관목
|
||||||
block.spore-moss.name = 포자 이끼
|
block.spore-moss.name = 포자 이끼
|
||||||
block.shalerocks.name = 이판암 바위
|
block.shale-wall.name = 이판암 벽
|
||||||
block.scrap-wall.name = 조각벽
|
block.scrap-wall.name = 조각벽
|
||||||
block.scrap-wall-large.name = 대형 조각벽
|
block.scrap-wall-large.name = 대형 조각벽
|
||||||
block.scrap-wall-huge.name = 거대한 조각 벽
|
block.scrap-wall-huge.name = 거대한 조각 벽
|
||||||
@@ -910,6 +913,7 @@ block.water.name = 물
|
|||||||
block.tainted-water.name = 오염된 물
|
block.tainted-water.name = 오염된 물
|
||||||
block.darksand-tainted-water.name = 오염된 젖은 검은 모래
|
block.darksand-tainted-water.name = 오염된 젖은 검은 모래
|
||||||
block.tar.name = 석유
|
block.tar.name = 석유
|
||||||
|
block.mud.name = 진흙
|
||||||
block.stone.name = 바위
|
block.stone.name = 바위
|
||||||
block.sand.name = 모래
|
block.sand.name = 모래
|
||||||
block.darksand.name = 검은 모래
|
block.darksand.name = 검은 모래
|
||||||
@@ -919,13 +923,16 @@ block.craters.name = 구덩이
|
|||||||
block.sand-water.name = 젖은 모래
|
block.sand-water.name = 젖은 모래
|
||||||
block.darksand-water.name = 젖은 검은 모래
|
block.darksand-water.name = 젖은 검은 모래
|
||||||
block.char.name = 숯
|
block.char.name = 숯
|
||||||
block.holostone.name = 홀로스톤
|
block.dacite.name = 데이사이트
|
||||||
|
block.dacite-wall.name = 데이사이트 벽
|
||||||
block.ice-snow.name = 얼음눈
|
block.ice-snow.name = 얼음눈
|
||||||
block.rocks.name = 돌
|
block.stone-wall.name = 돌 벽
|
||||||
block.icerocks.name = 얼음바위
|
block.ice-wall.name = 얼음 벽
|
||||||
block.snowrocks.name = 눈바위
|
block.snow-wall.name = 눈 벽
|
||||||
block.dunerocks.name = 모래돌
|
block.dune-wall.name = 모래 벽
|
||||||
block.pine.name = 소나무
|
block.pine.name = 소나무
|
||||||
|
block.dirt.name = 흙
|
||||||
|
block.dirt-wall.name = 흙 벽
|
||||||
block.white-tree-dead.name = 죽은 하얀나무
|
block.white-tree-dead.name = 죽은 하얀나무
|
||||||
block.white-tree.name = 하얀 나무
|
block.white-tree.name = 하얀 나무
|
||||||
block.spore-cluster.name = 포자낭
|
block.spore-cluster.name = 포자낭
|
||||||
@@ -941,7 +948,7 @@ block.dark-panel-4.name = 어두운 패널 4
|
|||||||
block.dark-panel-5.name = 어두운 패널 5
|
block.dark-panel-5.name = 어두운 패널 5
|
||||||
block.dark-panel-6.name = 어두운 패널 6
|
block.dark-panel-6.name = 어두운 패널 6
|
||||||
block.dark-metal.name = 어두운 금속제
|
block.dark-metal.name = 어두운 금속제
|
||||||
block.ignarock.name = 얼은 바위
|
block.basalt.name = 현무암
|
||||||
block.hotrock.name = 뜨거운 바위
|
block.hotrock.name = 뜨거운 바위
|
||||||
block.magmarock.name = 용암 바위
|
block.magmarock.name = 용암 바위
|
||||||
block.cliffs.name = 절벽
|
block.cliffs.name = 절벽
|
||||||
@@ -1011,7 +1018,7 @@ block.power-void.name = 방전장치
|
|||||||
block.power-source.name = 전력 공급기
|
block.power-source.name = 전력 공급기
|
||||||
block.unloader.name = 언로더
|
block.unloader.name = 언로더
|
||||||
block.vault.name = 창고
|
block.vault.name = 창고
|
||||||
block.wave.name = 웨이브
|
block.wave.name = 파도
|
||||||
block.swarmer.name = 스워머
|
block.swarmer.name = 스워머
|
||||||
block.salvo.name = 살보
|
block.salvo.name = 살보
|
||||||
block.ripple.name = 립플
|
block.ripple.name = 립플
|
||||||
@@ -1019,7 +1026,7 @@ block.phase-conveyor.name = 메타 컨베이어
|
|||||||
block.bridge-conveyor.name = 다리 컨베이어
|
block.bridge-conveyor.name = 다리 컨베이어
|
||||||
block.plastanium-compressor.name = 플라스터늄 압축기
|
block.plastanium-compressor.name = 플라스터늄 압축기
|
||||||
block.pyratite-mixer.name = 파이라타이트 혼합기
|
block.pyratite-mixer.name = 파이라타이트 혼합기
|
||||||
block.blast-mixer.name = 화합물 혼합기
|
block.blast-mixer.name = 폭발물 혼합기
|
||||||
block.solar-panel.name = 태양 전지판
|
block.solar-panel.name = 태양 전지판
|
||||||
block.solar-panel-large.name = 대형 태양 전지판
|
block.solar-panel-large.name = 대형 태양 전지판
|
||||||
block.oil-extractor.name = 석유 추출기
|
block.oil-extractor.name = 석유 추출기
|
||||||
@@ -1062,11 +1069,11 @@ block.additive-reconstructor.name = 첨가물 재구성기
|
|||||||
block.multiplicative-reconstructor.name = 다중 재구성기
|
block.multiplicative-reconstructor.name = 다중 재구성기
|
||||||
block.exponential-reconstructor.name = 지수 재구성기
|
block.exponential-reconstructor.name = 지수 재구성기
|
||||||
block.tetrative-reconstructor.name = 정서 재구성기
|
block.tetrative-reconstructor.name = 정서 재구성기
|
||||||
block.payload-conveyor.name = 매스 컨베이어
|
block.payload-conveyor.name = 화물 컨베이어
|
||||||
block.payload-router.name = 화물 분배기
|
block.payload-router.name = 화물 분배기
|
||||||
block.disassembler.name = 분해기
|
block.disassembler.name = 가속 분해기
|
||||||
block.silicon-crucible.name = 실리콘 도가니
|
block.silicon-crucible.name = 실리콘 도가니
|
||||||
block.large-overdrive-projector.name = 대형 과부하 프로젝터
|
block.overdrive-dome.name = 대형 과부하 프로젝터
|
||||||
team.blue.name = 파랑색 팀
|
team.blue.name = 파랑색 팀
|
||||||
team.crux.name = 빨강색 팀
|
team.crux.name = 빨강색 팀
|
||||||
team.sharded.name = 주황색 팀
|
team.sharded.name = 주황색 팀
|
||||||
@@ -1099,7 +1106,7 @@ tutorial.launch = 특정 웨이브에 도달하면 [accent]코어로 출격[]
|
|||||||
|
|
||||||
item.copper.description = 가장 기본적인 건설 재료. 모든 유형의 블록에서 광범위하게 사용됩니다.
|
item.copper.description = 가장 기본적인 건설 재료. 모든 유형의 블록에서 광범위하게 사용됩니다.
|
||||||
item.lead.description = 기본 초반 재료. 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다.
|
item.lead.description = 기본 초반 재료. 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다.
|
||||||
item.metaglass.description = 초강력 유리 화합물. 액체 분배 및 저장에 광범위하게 사용됩니다.
|
item.metaglass.description = 초강력 방탄 유리. 액체 분배 및 저장에 광범위하게 사용됩니다.
|
||||||
item.graphite.description = 탄약 및 전기 부품에 사용되는 무기질 탄소.
|
item.graphite.description = 탄약 및 전기 부품에 사용되는 무기질 탄소.
|
||||||
item.sand.description = 제련에서 합금 또는 플럭스에서 광범위하게 사용되는 일반적인 재료.
|
item.sand.description = 제련에서 합금 또는 플럭스에서 광범위하게 사용되는 일반적인 재료.
|
||||||
item.coal.description = 화석화된 식물 물질. 씨앗이 나오기 훨씬 전에 형성되었습니다. 연료 및 자원 생산에 광범위하게 사용됩니다.
|
item.coal.description = 화석화된 식물 물질. 씨앗이 나오기 훨씬 전에 형성되었습니다. 연료 및 자원 생산에 광범위하게 사용됩니다.
|
||||||
@@ -1127,7 +1134,7 @@ block.plastanium-compressor.description = 석유와 티타늄으로 플라스터
|
|||||||
block.phase-weaver.description = 방사성 토륨과 모래에서 메타를 합성합니다. 작동하려면 엄청난 양의 전력이 필요합니다.
|
block.phase-weaver.description = 방사성 토륨과 모래에서 메타를 합성합니다. 작동하려면 엄청난 양의 전력이 필요합니다.
|
||||||
block.alloy-smelter.description = 티타늄, 납, 실리콘, 구리를 결합하여 설금을 생산합니다.
|
block.alloy-smelter.description = 티타늄, 납, 실리콘, 구리를 결합하여 설금을 생산합니다.
|
||||||
block.cryofluidmixer.description = 물과 미세 티타늄 분말을 냉각수로 혼합합니다. 토륨 원자로 사용에 필수적입니다.
|
block.cryofluidmixer.description = 물과 미세 티타늄 분말을 냉각수로 혼합합니다. 토륨 원자로 사용에 필수적입니다.
|
||||||
block.blast-mixer.description = 포자 클러스터를 파이라타이트와 분쇄하고 혼합하여 화합물을 만듭니다.
|
block.blast-mixer.description = 포자 클러스터를 파이라타이트와 분쇄하고 혼합하여 폭발물을 만듭니다.
|
||||||
block.pyratite-mixer.description = 석탄, 납, 모래를 가연성이 높은 파이라타이트로 만듭니다.
|
block.pyratite-mixer.description = 석탄, 납, 모래를 가연성이 높은 파이라타이트로 만듭니다.
|
||||||
block.melter.description = 웨이브 포탑에서 추가 처리 또는 사용을 위해 고철을 광재로 녹입니다.
|
block.melter.description = 웨이브 포탑에서 추가 처리 또는 사용을 위해 고철을 광재로 녹입니다.
|
||||||
block.separator.description = 광재를 미네랄 성분으로 분리합니다. 그리고 냉각된 결과를 출력합니다.
|
block.separator.description = 광재를 미네랄 성분으로 분리합니다. 그리고 냉각된 결과를 출력합니다.
|
||||||
@@ -1194,7 +1201,7 @@ block.combustion-generator.description = 석탄과 같은 가연성 물질을
|
|||||||
block.thermal-generator.description = 열이 있는 곳에 설치하면 전력이 생성됩니다.
|
block.thermal-generator.description = 열이 있는 곳에 설치하면 전력이 생성됩니다.
|
||||||
block.steam-generator.description = 고급 연소 발전기. 더 효율적이지만 증기를 생성하기 위해 물이 필요합니다.
|
block.steam-generator.description = 고급 연소 발전기. 더 효율적이지만 증기를 생성하기 위해 물이 필요합니다.
|
||||||
block.differential-generator.description = 많은 양의 전력을 생성합니다. 냉각수와 불타는 파이라타이트의 온도 차이를 이용합니다.
|
block.differential-generator.description = 많은 양의 전력을 생성합니다. 냉각수와 불타는 파이라타이트의 온도 차이를 이용합니다.
|
||||||
block.rtg-generator.description = 간단하고 안정적인 발전기. 붕괴하는 방사성 화합물의 열을 이용하여 느린 속도로 전력을 생성합니다.
|
block.rtg-generator.description = 간단하고 안정적인 발전기. 붕괴하는 방사성 물질의 열을 이용하여 느린 속도로 전력을 생성합니다.
|
||||||
block.solar-panel.description = 태양으로부터 소량의 전력을 생성합니다.
|
block.solar-panel.description = 태양으로부터 소량의 전력을 생성합니다.
|
||||||
block.solar-panel-large.description = 표준 태양 전지판보다 훨씬 더 효율적인 버전.
|
block.solar-panel-large.description = 표준 태양 전지판보다 훨씬 더 효율적인 버전.
|
||||||
block.thorium-reactor.description = 토륨으로부터 상당한 양의 전력을 생산합니다. 지속적인 냉각이 필요하며, 충분한 양의 냉각수가 공급되지 않으면 크게 폭발합니다. 전력 출력은 토륨의 양에 따라 달라집니다.
|
block.thorium-reactor.description = 토륨으로부터 상당한 양의 전력을 생산합니다. 지속적인 냉각이 필요하며, 충분한 양의 냉각수가 공급되지 않으면 크게 폭발합니다. 전력 출력은 토륨의 양에 따라 달라집니다.
|
||||||
@@ -1228,5 +1235,5 @@ block.ripple.description = 매우 강력한 포병 포탑. 원거리에 있는
|
|||||||
block.cyclone.description = 대공 및 대지 포탑. 근처 유닛에게 폭발성 덩어리를 발사합니다.
|
block.cyclone.description = 대공 및 대지 포탑. 근처 유닛에게 폭발성 덩어리를 발사합니다.
|
||||||
block.spectre.description = 거대한 이중 배럴 대포. 공중 및 지상 목표물에 큰 관통 철갑탄을 발사합니다.
|
block.spectre.description = 거대한 이중 배럴 대포. 공중 및 지상 목표물에 큰 관통 철갑탄을 발사합니다.
|
||||||
block.meltdown.description = 거대한 레이저 대포. 근처의 적에게 지속적인 레이버 빔을 충전하여 발사합니다. 냉각수가 있어야 작동합니다.
|
block.meltdown.description = 거대한 레이저 대포. 근처의 적에게 지속적인 레이버 빔을 충전하여 발사합니다. 냉각수가 있어야 작동합니다.
|
||||||
block.repair-point.description = 주변에서 가장 가까운 유닛들을 지속적으로 치료합니다.
|
block.repair-point.description = 주변에서 가장 가까운 유닛을 지속적으로 치료합니다.
|
||||||
block.segment.description = 날아오는 발사체를 요격합니다. 레이저는 목표 대상이 아닙니다.
|
block.segment.description = 날아오는 발사체를 요격합니다. 레이저는 목표 대상이 아닙니다.
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ gameover = Игра окончена
|
|||||||
gameover.pvp = [accent]{0}[] команда победила!
|
gameover.pvp = [accent]{0}[] команда победила!
|
||||||
highscore = [accent]Новый рекорд!
|
highscore = [accent]Новый рекорд!
|
||||||
copied = Скопировано.
|
copied = Скопировано.
|
||||||
indevpopup = [accent]v6[] находится на стадии [accent]alpha[].\n[lightgray]Это означает следующее:[]\n- Отсутствие контента.\n- Большинство [scarlet]ИИ единиц[] не работает.\n- Множество единиц не готово.\n- Кампания не завершена.\n- Всё, что вы видите, может быть изменено или удалено.\n\nСообщайте о багах и вылетах на [accent]Github[].
|
indev.popup = [accent]v6[] находится на стадии [accent]alpha[].\n[lightgray]Это означает следующее:[]\n- Отсутствие контента.\n- Большинство [scarlet]ИИ единиц[] не работает.\n- Множество единиц не готово.\n- Кампания не завершена.\n- Всё, что вы видите, может быть изменено или удалено.\n\nСообщайте о багах и вылетах на [accent]Github[].
|
||||||
|
indev.notready = Эта часть игры ещё не готова
|
||||||
|
|
||||||
load.sound = Звуки
|
load.sound = Звуки
|
||||||
load.map = Карты
|
load.map = Карты
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ gameover = Гра завершена
|
|||||||
gameover.pvp = [accent]{0}[] команда перемогла!
|
gameover.pvp = [accent]{0}[] команда перемогла!
|
||||||
highscore = [accent]Новий рекорд!
|
highscore = [accent]Новий рекорд!
|
||||||
copied = Скопійовано.
|
copied = Скопійовано.
|
||||||
indevpopup = Наразі [accent]6.0[] знаходиться у стадії [accent]альфа[].\n[lightgray]Це означає наступне:[]\n- Не вистачає наповнення гри;\n- Більшість [scarlet]ШІ бойових одиниць[] не працює належним чином;\n- Багато одиниць [scarlet]відсутні[] або незавершені;\n- Кампанія повністю не є завершеною;\n- Усе, що ви бачите, може змінитися або видалитися.\n\nПовідомляйте про вади або збої на [accent]Github[], а про помилки в перекладі в Discord.
|
indev.popup = Наразі [accent]6.0[] знаходиться у стадії [accent]альфа[].\n[lightgray]Це означає наступне:[]\n- Не вистачає наповнення гри;\n- Більшість [scarlet]ШІ бойових одиниць[] не працює належним чином;\n- Багато одиниць [scarlet]відсутні[] або незавершені;\n- Кампанія повністю не є завершеною;\n- Усе, що ви бачите, може змінитися або видалитися.\n\nПовідомляйте про вади або збої на [accent]Github[], а про помилки в перекладі в Discord.
|
||||||
|
indev.notready = Ця частина гри ще не готова
|
||||||
|
|
||||||
load.sound = Звуки
|
load.sound = Звуки
|
||||||
load.map = Мапи
|
load.map = Мапи
|
||||||
|
|||||||
@@ -90,3 +90,4 @@ DeltaNedas
|
|||||||
GioIacca9
|
GioIacca9
|
||||||
SnakkiZXZ
|
SnakkiZXZ
|
||||||
sk7725
|
sk7725
|
||||||
|
ThePlayerA
|
||||||
|
|||||||
@@ -311,3 +311,7 @@
|
|||||||
63433=dacite-wall|block-dacite-wall-medium
|
63433=dacite-wall|block-dacite-wall-medium
|
||||||
63432=dacite-boulder|block-dacite-boulder-medium
|
63432=dacite-boulder|block-dacite-boulder-medium
|
||||||
63431=large-logic-display|block-large-logic-display-medium
|
63431=large-logic-display|block-large-logic-display-medium
|
||||||
|
63430=omura|unit-omura-medium
|
||||||
|
63429=mud|block-mud-medium
|
||||||
|
63428=sei|unit-sei-medium
|
||||||
|
63427=quad|unit-quad-medium
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ importPackage(Packages.mindustry.gen)
|
|||||||
importPackage(Packages.mindustry.graphics)
|
importPackage(Packages.mindustry.graphics)
|
||||||
importPackage(Packages.mindustry.graphics.g3d)
|
importPackage(Packages.mindustry.graphics.g3d)
|
||||||
importPackage(Packages.mindustry.input)
|
importPackage(Packages.mindustry.input)
|
||||||
|
importPackage(Packages.mindustry.io)
|
||||||
importPackage(Packages.mindustry.logic)
|
importPackage(Packages.mindustry.logic)
|
||||||
importPackage(Packages.mindustry.maps)
|
importPackage(Packages.mindustry.maps)
|
||||||
importPackage(Packages.mindustry.maps.filters)
|
importPackage(Packages.mindustry.maps.filters)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#define HIGHP
|
||||||
|
|
||||||
|
#define NSCALE 180.0 / 2.0
|
||||||
|
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
uniform sampler2D u_noise;
|
||||||
|
|
||||||
|
uniform vec2 u_campos;
|
||||||
|
uniform vec2 u_resolution;
|
||||||
|
uniform float u_time;
|
||||||
|
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec2 c = v_texCoords.xy;
|
||||||
|
vec2 coords = vec2(c.x * u_resolution.x + u_campos.x, c.y * u_resolution.y + u_campos.y);
|
||||||
|
|
||||||
|
float btime = u_time / 70000.0;
|
||||||
|
float noise = sin((texture2D(u_noise, (coords) / NSCALE + vec2(btime) * vec2(-0.9, 0.8)).r + texture2D(u_noise, (coords) / NSCALE + vec2(abs(sin(btime)) * 1.1) * vec2(-0.8, -1.0)).r) / 2.0);
|
||||||
|
vec4 color = texture2D(u_texture, c);
|
||||||
|
|
||||||
|
if(noise > 0.54 && noise < 0.68){
|
||||||
|
color.rgb *= 1.4;
|
||||||
|
}else if(!(noise > 0.40 && noise < 0.54)){
|
||||||
|
color.rgb *= 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
||||||
@@ -22,12 +22,10 @@ void main(){
|
|||||||
float noise = (texture2D(u_noise, (coords) / NSCALE + vec2(btime) * vec2(-0.9, 0.8)).r + texture2D(u_noise, (coords) / NSCALE + vec2(btime * 1.1) * vec2(0.8, -1.0)).r) / 2.0;
|
float noise = (texture2D(u_noise, (coords) / NSCALE + vec2(btime) * vec2(-0.9, 0.8)).r + texture2D(u_noise, (coords) / NSCALE + vec2(btime * 1.1) * vec2(0.8, -1.0)).r) / 2.0;
|
||||||
vec4 color = texture2D(u_texture, c);
|
vec4 color = texture2D(u_texture, c);
|
||||||
|
|
||||||
if(color.a > 0.1){
|
if(noise > 0.6){
|
||||||
if(noise > 0.6){
|
color.rgb = S2;
|
||||||
color.rgb = S2;
|
}else if (noise > 0.54){
|
||||||
}else if (noise > 0.54){
|
color.rgb = S1;
|
||||||
color.rgb = S1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void main(){
|
|||||||
vec4 color = texture2D(u_texture, c);
|
vec4 color = texture2D(u_texture, c);
|
||||||
|
|
||||||
if(!(noise > 0.54 && noise < 0.58)){
|
if(!(noise > 0.54 && noise < 0.58)){
|
||||||
color.rgb *= 0.6;
|
color.rgb *= vec3(0.6, 0.6, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 810 B |
|
Before Width: | Height: | Size: 647 KiB After Width: | Height: | Size: 639 KiB |
|
Before Width: | Height: | Size: 958 KiB After Width: | Height: | Size: 760 KiB |
|
Before Width: | Height: | Size: 365 KiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 317 KiB After Width: | Height: | Size: 326 KiB |
|
Before Width: | Height: | Size: 415 KiB After Width: | Height: | Size: 416 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 314 KiB After Width: | Height: | Size: 314 KiB |
|
Before Width: | Height: | Size: 418 KiB After Width: | Height: | Size: 420 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.4 MiB |
@@ -33,7 +33,7 @@ public class BlockIndexer{
|
|||||||
/** Maps each team ID to a quarant. A quadrant is a grid of bits, where each bit is set if and only if there is a block of that team in that quadrant. */
|
/** Maps each team ID to a quarant. A quadrant is a grid of bits, where each bit is set if and only if there is a block of that team in that quadrant. */
|
||||||
private GridBits[] structQuadrants;
|
private GridBits[] structQuadrants;
|
||||||
/** Stores all damaged tile entities by team. */
|
/** Stores all damaged tile entities by team. */
|
||||||
private BuildingArray[] damagedTiles = new BuildingArray[Team.all.length];
|
private ObjectSet<Building>[] damagedTiles = new ObjectSet[Team.all.length];
|
||||||
/** All ores available on this map. */
|
/** All ores available on this map. */
|
||||||
private ObjectSet<Item> allOres = new ObjectSet<>();
|
private ObjectSet<Item> allOres = new ObjectSet<>();
|
||||||
/** Stores teams that are present here as tiles. */
|
/** Stores teams that are present here as tiles. */
|
||||||
@@ -70,7 +70,7 @@ public class BlockIndexer{
|
|||||||
Events.on(WorldLoadEvent.class, event -> {
|
Events.on(WorldLoadEvent.class, event -> {
|
||||||
scanOres.clear();
|
scanOres.clear();
|
||||||
scanOres.addAll(Item.getAllOres());
|
scanOres.addAll(Item.getAllOres());
|
||||||
damagedTiles = new BuildingArray[Team.all.length];
|
damagedTiles = new ObjectSet[Team.all.length];
|
||||||
flagMap = new TileArray[Team.all.length][BlockFlag.all.length];
|
flagMap = new TileArray[Team.all.length][BlockFlag.all.length];
|
||||||
unitCaps = new int[Team.all.length];
|
unitCaps = new int[Team.all.length];
|
||||||
activeTeams = new Seq<>(Team.class);
|
activeTeams = new Seq<>(Team.class);
|
||||||
@@ -139,14 +139,14 @@ public class BlockIndexer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all damaged tiles by team. */
|
/** Returns all damaged tiles by team. */
|
||||||
public BuildingArray getDamaged(Team team){
|
public ObjectSet<Building> getDamaged(Team team){
|
||||||
returnArray.clear();
|
breturnArray.clear();
|
||||||
|
|
||||||
if(damagedTiles[team.id] == null){
|
if(damagedTiles[team.id] == null){
|
||||||
damagedTiles[team.id] = new BuildingArray();
|
damagedTiles[team.id] = new ObjectSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildingArray set = damagedTiles[team.id];
|
ObjectSet<Building> set = damagedTiles[team.id];
|
||||||
for(Building build : set){
|
for(Building build : set){
|
||||||
if((!build.isValid() || build.team != team || !build.damaged()) || build.block instanceof ConstructBlock){
|
if((!build.isValid() || build.team != team || !build.damaged()) || build.block instanceof ConstructBlock){
|
||||||
breturnArray.add(build);
|
breturnArray.add(build);
|
||||||
@@ -214,7 +214,7 @@ public class BlockIndexer{
|
|||||||
|
|
||||||
public void notifyTileDamaged(Building entity){
|
public void notifyTileDamaged(Building entity){
|
||||||
if(damagedTiles[entity.team.id] == null){
|
if(damagedTiles[entity.team.id] == null){
|
||||||
damagedTiles[entity.team.id] = new BuildingArray();
|
damagedTiles[entity.team.id] = new ObjectSet<Building>();
|
||||||
}
|
}
|
||||||
|
|
||||||
damagedTiles[entity.team.id].add(entity);
|
damagedTiles[entity.team.id].add(entity);
|
||||||
@@ -476,35 +476,4 @@ public class BlockIndexer{
|
|||||||
return tiles.iterator();
|
return tiles.iterator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO copy-pasted code, generics would be nice here
|
|
||||||
public static class BuildingArray implements Iterable<Building>{
|
|
||||||
private Seq<Building> tiles = new Seq<>(false, 16);
|
|
||||||
private IntSet contained = new IntSet();
|
|
||||||
|
|
||||||
public void add(Building tile){
|
|
||||||
if(contained.add(tile.pos())){
|
|
||||||
tiles.add(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Building tile){
|
|
||||||
if(contained.remove(tile.pos())){
|
|
||||||
tiles.remove(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size(){
|
|
||||||
return tiles.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Building first(){
|
|
||||||
return tiles.first();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<Building> iterator(){
|
|
||||||
return tiles.iterator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class Pathfinder implements Runnable{
|
|||||||
Flowfield[][][] cache;
|
Flowfield[][][] cache;
|
||||||
|
|
||||||
/** tile data, see PathTileStruct */
|
/** tile data, see PathTileStruct */
|
||||||
int[][] tiles;
|
int[][] tiles = new int[0][0];
|
||||||
/** unordered array of path data for iteration only. DO NOT iterate or access this in the main thread. */
|
/** unordered array of path data for iteration only. DO NOT iterate or access this in the main thread. */
|
||||||
Seq<Flowfield> threadList = new Seq<>(), mainList = new Seq<>();
|
Seq<Flowfield> threadList = new Seq<>(), mainList = new Seq<>();
|
||||||
/** handles task scheduling on the update thread. */
|
/** handles task scheduling on the update thread. */
|
||||||
|
|||||||
@@ -5,20 +5,14 @@ import arc.math.geom.*;
|
|||||||
import mindustry.ai.formations.*;
|
import mindustry.ai.formations.*;
|
||||||
|
|
||||||
public class CircleFormation extends FormationPattern{
|
public class CircleFormation extends FormationPattern{
|
||||||
/** The radius of one member. This is needed to determine how close we can pack a given number of members around circle. */
|
|
||||||
public float memberRadius;
|
|
||||||
/** Angle offset. */
|
/** Angle offset. */
|
||||||
public float angleOffset = 0;
|
public float angleOffset = 0;
|
||||||
|
|
||||||
public CircleFormation(float memberRadius){
|
|
||||||
this.memberRadius = memberRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vec3 calculateSlotLocation(Vec3 outLocation, int slotNumber){
|
public Vec3 calculateSlotLocation(Vec3 outLocation, int slotNumber){
|
||||||
if(slots > 1){
|
if(slots > 1){
|
||||||
float angle = (360f * slotNumber) / slots;
|
float angle = (360f * slotNumber) / slots;
|
||||||
float radius = memberRadius / (float)Math.sin(180f / slots * Mathf.degRad);
|
float radius = spacing / (float)Math.sin(180f / slots * Mathf.degRad);
|
||||||
outLocation.set(Angles.trnsx(angle, radius), Angles.trnsy(angle, radius), angle);
|
outLocation.set(Angles.trnsx(angle, radius), Angles.trnsy(angle, radius), angle);
|
||||||
}else{
|
}else{
|
||||||
outLocation.set(0, 0, 360f * slotNumber);
|
outLocation.set(0, 0, 360f * slotNumber);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package mindustry.ai.types;
|
package mindustry.ai.types;
|
||||||
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.*;
|
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
@@ -59,7 +58,7 @@ public class FlyingAI extends AIController{
|
|||||||
vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f));
|
vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec.setLength(unit.type().speed * Time.delta);
|
vec.setLength(unit.type().speed);
|
||||||
|
|
||||||
unit.moveAt(vec);
|
unit.moveAt(vec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package mindustry.ai.types;
|
|||||||
|
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.*;
|
|
||||||
import mindustry.ai.formations.*;
|
import mindustry.ai.formations.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
|
||||||
public class FormationAI extends AIController implements FormationMember{
|
public class FormationAI extends AIController implements FormationMember{
|
||||||
public Unit leader;
|
public Unit leader;
|
||||||
@@ -25,39 +25,40 @@ public class FormationAI extends AIController implements FormationMember{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUnit(){
|
public void updateUnit(){
|
||||||
|
UnitType type = unit.type();
|
||||||
|
|
||||||
if(leader.dead){
|
if(leader.dead){
|
||||||
unit.resetController();
|
unit.resetController();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unit.controlWeapons(leader.isRotate(), leader.isShooting);
|
unit.controlWeapons(true, leader.isShooting);
|
||||||
// unit.moveAt(Tmp.v1.set(deltaX, deltaY).limit(unit.type().speed));
|
// unit.moveAt(Tmp.v1.set(deltaX, deltaY).limit(unit.type().speed));
|
||||||
if(leader.isShooting){
|
|
||||||
unit.aimLook(leader.aimX(), leader.aimY());
|
unit.aim(leader.aimX(), leader.aimY());
|
||||||
}else{
|
|
||||||
if(!leader.moving() || !unit.type().rotateShooting){
|
if(unit.type().rotateShooting){
|
||||||
if(unit.moving()){
|
unit.lookAt(leader.aimX(), leader.aimY());
|
||||||
unit.lookAt(unit.vel.angle());
|
}else if(unit.moving()){
|
||||||
}
|
unit.lookAt(unit.vel.angle());
|
||||||
}else{
|
|
||||||
unit.lookAt(leader.rotation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2 realtarget = vec.set(target);
|
Vec2 realtarget = vec.set(target);
|
||||||
|
|
||||||
if(unit.isGrounded() && Vars.world.raycast(unit.tileX(), unit.tileY(), leader.tileX(), leader.tileY(), Vars.world::solid)){
|
float margin = 3f;
|
||||||
//TODO pathfind
|
|
||||||
//realtarget.set(Vars.pathfinder.getTargetTile(unit.tileOn(), unit.team, leader));
|
|
||||||
}
|
|
||||||
|
|
||||||
unit.moveAt(realtarget.sub(unit).limit(unit.type().speed));
|
if(unit.dst(realtarget) <= margin){
|
||||||
|
unit.vel.approachDelta(Vec2.ZERO, type.speed * type.accel / 2f);
|
||||||
|
}else{
|
||||||
|
unit.moveAt(realtarget.sub(unit).limit(type.speed));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed(Unit unit){
|
public void removed(Unit unit){
|
||||||
if(formation != null){
|
if(formation != null){
|
||||||
formation.removeMember(this);
|
formation.removeMember(this);
|
||||||
|
unit.resetController();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ public class FormationAI extends AIController implements FormationMember{
|
|||||||
//TODO return formation size
|
//TODO return formation size
|
||||||
//eturn ((Commanderc)unit).formation().
|
//eturn ((Commanderc)unit).formation().
|
||||||
}
|
}
|
||||||
return unit.hitSize * 1.7f;
|
return unit.hitSize * 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ public class GroundAI extends AIController{
|
|||||||
unit.elevation = Mathf.approachDelta(unit.elevation, 0f, 0.08f);
|
unit.elevation = Mathf.approachDelta(unit.elevation, 0f, 0.08f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Units.invalidateTarget(target, unit, unit.range())){
|
if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type().rotateShooting){
|
||||||
if(unit.type().hasWeapons()){
|
if(unit.type().hasWeapons()){
|
||||||
//TODO certain units should not look at the target, e.g. ships
|
//TODO certain units should not look at the target, e.g. ships
|
||||||
unit.aimLook(Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed));
|
unit.lookAt(Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed));
|
||||||
}
|
}
|
||||||
}else if(unit.moving()){
|
}else if(unit.moving()){
|
||||||
unit.lookAt(unit.vel().angle());
|
unit.lookAt(unit.vel().angle());
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class MinerAI extends AIController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ore != null){
|
if(ore != null){
|
||||||
moveTo(ore, unit.type().range / 1.5f);
|
moveTo(ore, unit.type().range / 2f);
|
||||||
|
|
||||||
if(unit.within(ore, unit.type().range)){
|
if(unit.within(ore, unit.type().range)){
|
||||||
miner.mineTile(ore);
|
miner.mineTile(ore);
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ public class RepairAI extends AIController{
|
|||||||
boolean shoot = false;
|
boolean shoot = false;
|
||||||
|
|
||||||
if(target != null){
|
if(target != null){
|
||||||
if(!target.within(unit, unit.type().range)){
|
if(!target.within(unit, unit.type().range * 0.8f)){
|
||||||
moveTo(target, unit.type().range * 0.9f);
|
moveTo(target, unit.type().range * 0.8f);
|
||||||
}else{
|
}else{
|
||||||
unit.aim(target);
|
unit.aim(target);
|
||||||
shoot = true;
|
shoot = true;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public class PhysicsProcess implements AsyncProcess{
|
|||||||
refs.removeAll(ref -> {
|
refs.removeAll(ref -> {
|
||||||
if(!ref.entity.isAdded()){
|
if(!ref.entity.isAdded()){
|
||||||
physics.destroyBody(ref.body);
|
physics.destroyBody(ref.body);
|
||||||
|
ref.entity.physref(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import mindustry.*;
|
|||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.blocks.payloads.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -48,6 +49,19 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
activeCounts[team.id][type.id] += amount;
|
activeCounts[team.id][type.id] += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void count(Unit unit){
|
||||||
|
updateCount(unit.team, unit.type(), 1);
|
||||||
|
if(!unit.deactivated) updateActiveCount(unit.team, unit.type(), 1);
|
||||||
|
|
||||||
|
if(unit instanceof Payloadc){
|
||||||
|
((Payloadc)unit).payloads().each(p -> {
|
||||||
|
if(p instanceof UnitPayload){
|
||||||
|
count(((UnitPayload)p).unit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset(){
|
public void reset(){
|
||||||
counts = new int[Team.all.length];
|
counts = new int[Team.all.length];
|
||||||
@@ -71,8 +85,7 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
for(Unit unit : Groups.unit){
|
for(Unit unit : Groups.unit){
|
||||||
tree(unit.team).insert(unit);
|
tree(unit.team).insert(unit);
|
||||||
|
|
||||||
updateCount(unit.team, unit.type(), 1);
|
count(unit);
|
||||||
if(!unit.deactivated) updateActiveCount(unit.team, unit.type(), 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class Blocks implements ContentList{
|
|||||||
public static Block
|
public static Block
|
||||||
|
|
||||||
//environment
|
//environment
|
||||||
air, spawn, cliff, deepwater, water, taintedWater, tar, slag, stone, craters, charr, sand, darksand, dirt, ice, snow, darksandTaintedWater,
|
air, spawn, cliff, deepwater, water, taintedWater, tar, slag, stone, craters, charr, sand, darksand, dirt, mud, ice, snow, darksandTaintedWater,
|
||||||
dacite, stoneWall, dirtWall, sporeWall, iceWall, daciteWall, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster,
|
dacite, stoneWall, dirtWall, sporeWall, iceWall, daciteWall, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster,
|
||||||
iceSnow, sandWater, darksandWater, duneWall, sandWall, moss, sporeMoss, shale, shaleWall, shaleBoulder, sandBoulder, daciteBoulder, grass, salt,
|
iceSnow, sandWater, darksandWater, duneWall, sandWall, moss, sporeMoss, shale, shaleWall, shaleBoulder, sandBoulder, daciteBoulder, grass, salt,
|
||||||
metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, basalt, magmarock, hotrock, snowWall, boulder, snowBoulder, saltWall,
|
metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, basalt, magmarock, hotrock, snowWall, boulder, snowBoulder, saltWall,
|
||||||
@@ -260,6 +260,16 @@ public class Blocks implements ContentList{
|
|||||||
|
|
||||||
dirt = new Floor("dirt");
|
dirt = new Floor("dirt");
|
||||||
|
|
||||||
|
mud = new Floor("mud"){{
|
||||||
|
speedMultiplier = 0.6f;
|
||||||
|
variants = 3;
|
||||||
|
status = StatusEffects.muddy;
|
||||||
|
statusDuration = 30f;
|
||||||
|
attributes.set(Attribute.water, 2f);
|
||||||
|
cacheLayer = CacheLayer.mud;
|
||||||
|
albedo = 0.35f;
|
||||||
|
}};
|
||||||
|
|
||||||
((ShallowLiquid)darksandTaintedWater).set(Blocks.taintedWater, Blocks.darksand);
|
((ShallowLiquid)darksandTaintedWater).set(Blocks.taintedWater, Blocks.darksand);
|
||||||
((ShallowLiquid)sandWater).set(Blocks.water, Blocks.sand);
|
((ShallowLiquid)sandWater).set(Blocks.water, Blocks.sand);
|
||||||
((ShallowLiquid)darksandWater).set(Blocks.water, Blocks.darksand);
|
((ShallowLiquid)darksandWater).set(Blocks.water, Blocks.darksand);
|
||||||
@@ -327,11 +337,12 @@ public class Blocks implements ContentList{
|
|||||||
|
|
||||||
duneWall = new StaticWall("dune-wall"){{
|
duneWall = new StaticWall("dune-wall"){{
|
||||||
variants = 2;
|
variants = 2;
|
||||||
basalt.asFloor().wall = this;
|
basalt.asFloor().wall = darksandWater.asFloor().wall = darksandTaintedWater.asFloor().wall = this;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
sandWall = new StaticWall("sand-wall"){{
|
sandWall = new StaticWall("sand-wall"){{
|
||||||
variants = 2;
|
variants = 2;
|
||||||
|
sandWater.asFloor().wall = this;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
saltWall = new StaticWall("salt-wall");
|
saltWall = new StaticWall("salt-wall");
|
||||||
@@ -791,7 +802,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
door = new Door("door"){{
|
door = new Door("door"){{
|
||||||
requirements(Category.defense, with(Items.graphite, 6, Items.silicon, 4));
|
requirements(Category.defense, with(Items.titanium, 6, Items.silicon, 4));
|
||||||
health = 100 * wallHealthMultiplier;
|
health = 100 * wallHealthMultiplier;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -1011,7 +1022,7 @@ public class Blocks implements ContentList{
|
|||||||
|
|
||||||
mechanicalPump = new Pump("mechanical-pump"){{
|
mechanicalPump = new Pump("mechanical-pump"){{
|
||||||
requirements(Category.liquid, with(Items.copper, 15, Items.metaglass, 10));
|
requirements(Category.liquid, with(Items.copper, 15, Items.metaglass, 10));
|
||||||
pumpAmount = 0.1f;
|
pumpAmount = 0.11f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
rotaryPump = new Pump("rotary-pump"){{
|
rotaryPump = new Pump("rotary-pump"){{
|
||||||
@@ -1136,7 +1147,7 @@ public class Blocks implements ContentList{
|
|||||||
requirements(Category.power, with(Items.copper, 35, Items.graphite, 25, Items.lead, 40, Items.silicon, 30));
|
requirements(Category.power, with(Items.copper, 35, Items.graphite, 25, Items.lead, 40, Items.silicon, 30));
|
||||||
powerProduction = 5.5f;
|
powerProduction = 5.5f;
|
||||||
itemDuration = 90f;
|
itemDuration = 90f;
|
||||||
consumes.liquid(Liquids.water, 0.06f);
|
consumes.liquid(Liquids.water, 0.07f);
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
@@ -1269,7 +1280,7 @@ public class Blocks implements ContentList{
|
|||||||
hasItems = true;
|
hasItems = true;
|
||||||
|
|
||||||
consumes.power(0.80f);
|
consumes.power(0.80f);
|
||||||
consumes.liquid(Liquids.water, 0.18f);
|
consumes.liquid(Liquids.water, 0.2f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
oilExtractor = new Fracker("oil-extractor"){{
|
oilExtractor = new Fracker("oil-extractor"){{
|
||||||
@@ -1645,7 +1656,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
spectre = new ItemTurret("spectre"){{
|
spectre = new ItemTurret("spectre"){{
|
||||||
requirements(Category.turret, with(Items.copper, 350, Items.graphite, 300, Items.surgealloy, 250, Items.plastanium, 175, Items.thorium, 250));
|
requirements(Category.turret, with(Items.copper, 900, Items.graphite, 300, Items.surgealloy, 250, Items.plastanium, 175, Items.thorium, 250));
|
||||||
ammo(
|
ammo(
|
||||||
Items.graphite, Bullets.standardDenseBig,
|
Items.graphite, Bullets.standardDenseBig,
|
||||||
Items.pyratite, Bullets.standardIncendiaryBig,
|
Items.pyratite, Bullets.standardIncendiaryBig,
|
||||||
@@ -1671,7 +1682,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
meltdown = new LaserTurret("meltdown"){{
|
meltdown = new LaserTurret("meltdown"){{
|
||||||
requirements(Category.turret, with(Items.copper, 250, Items.lead, 350, Items.graphite, 300, Items.surgealloy, 325, Items.silicon, 325));
|
requirements(Category.turret, with(Items.copper, 1200, Items.lead, 350, Items.graphite, 300, Items.surgealloy, 325, Items.silicon, 325));
|
||||||
shootEffect = Fx.shootBigSmoke2;
|
shootEffect = Fx.shootBigSmoke2;
|
||||||
shootCone = 40f;
|
shootCone = 40f;
|
||||||
recoilAmount = 4f;
|
recoilAmount = 4f;
|
||||||
@@ -1793,6 +1804,7 @@ public class Blocks implements ContentList{
|
|||||||
{UnitTypes.zenith, UnitTypes.antumbra},
|
{UnitTypes.zenith, UnitTypes.antumbra},
|
||||||
{UnitTypes.spiroct, UnitTypes.arkyid},
|
{UnitTypes.spiroct, UnitTypes.arkyid},
|
||||||
{UnitTypes.fortress, UnitTypes.scepter},
|
{UnitTypes.fortress, UnitTypes.scepter},
|
||||||
|
{UnitTypes.bryde, UnitTypes.sei},
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -1811,6 +1823,7 @@ public class Blocks implements ContentList{
|
|||||||
{UnitTypes.antumbra, UnitTypes.eclipse},
|
{UnitTypes.antumbra, UnitTypes.eclipse},
|
||||||
{UnitTypes.arkyid, UnitTypes.toxopid},
|
{UnitTypes.arkyid, UnitTypes.toxopid},
|
||||||
{UnitTypes.scepter, UnitTypes.reign},
|
{UnitTypes.scepter, UnitTypes.reign},
|
||||||
|
{UnitTypes.sei, UnitTypes.omura}
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -269,13 +269,13 @@ public class Bullets implements ContentList{
|
|||||||
status = StatusEffects.burning;
|
status = StatusEffects.burning;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
missileSurge = new MissileBulletType(3.7f, 20){{
|
missileSurge = new MissileBulletType(3.7f, 18){{
|
||||||
width = 8f;
|
width = 8f;
|
||||||
height = 8f;
|
height = 8f;
|
||||||
shrinkY = 0f;
|
shrinkY = 0f;
|
||||||
drag = -0.01f;
|
drag = -0.01f;
|
||||||
splashDamageRadius = 28f;
|
splashDamageRadius = 25f;
|
||||||
splashDamage = 35f;
|
splashDamage = 25f;
|
||||||
hitEffect = Fx.blastExplosion;
|
hitEffect = Fx.blastExplosion;
|
||||||
despawnEffect = Fx.blastExplosion;
|
despawnEffect = Fx.blastExplosion;
|
||||||
lightning = 2;
|
lightning = 2;
|
||||||
|
|||||||
@@ -290,6 +290,22 @@ public class Fx{
|
|||||||
Lines.spikes(e.x, e.y, 1f + e.fin() * 6f, e.fout() * 4f, 6);
|
Lines.spikes(e.x, e.y, 1f + e.fin() * 6f, e.fout() * 4f, 6);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
healBomb = new Effect(40f, 100f, e -> {
|
||||||
|
color(Pal.heal);
|
||||||
|
stroke(e.fout() * 2f);
|
||||||
|
Lines.circle(e.x, e.y, 4f + e.finpow() * 65f);
|
||||||
|
|
||||||
|
color(Pal.heal);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
Drawf.tri(e.x, e.y, 6f, 100f * e.fout(), i*90);
|
||||||
|
}
|
||||||
|
|
||||||
|
color();
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
Drawf.tri(e.x, e.y, 3f, 35f * e.fout(), i*90);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
healWave = new Effect(22, e -> {
|
healWave = new Effect(22, e -> {
|
||||||
color(Pal.heal);
|
color(Pal.heal);
|
||||||
stroke(e.fout() * 2f);
|
stroke(e.fout() * 2f);
|
||||||
@@ -686,6 +702,13 @@ public class Fx{
|
|||||||
|
|
||||||
Fill.circle(e.x, e.y, e.fout() * 1f);
|
Fill.circle(e.x, e.y, e.fout() * 1f);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
muddy = new Effect(80f, e -> {
|
||||||
|
color(Color.valueOf("432722"));
|
||||||
|
alpha(Mathf.clamp(e.fin() * 2f));
|
||||||
|
|
||||||
|
Fill.circle(e.x, e.y, e.fout() * 1f);
|
||||||
|
}),
|
||||||
|
|
||||||
sapped = new Effect(40f, e -> {
|
sapped = new Effect(40f, e -> {
|
||||||
color(Pal.sap);
|
color(Pal.sap);
|
||||||
@@ -989,6 +1012,53 @@ public class Fx{
|
|||||||
|
|
||||||
}).ground(400f),
|
}).ground(400f),
|
||||||
|
|
||||||
|
railShoot = new Effect(24f, e -> {
|
||||||
|
e.scaled(10f, b -> {
|
||||||
|
color(Color.white, Color.lightGray, b.fin());
|
||||||
|
stroke(b.fout() * 3f + 0.2f);
|
||||||
|
Lines.circle(b.x, b.y, b.fin() * 50f);
|
||||||
|
});
|
||||||
|
|
||||||
|
color(Pal.orangeSpark);
|
||||||
|
|
||||||
|
for(int i : Mathf.signs){
|
||||||
|
Drawf.tri(e.x, e.y, 13f * e.fout(), 85f, e.rotation + 90f * i);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
railTrail = new Effect(16f, e -> {
|
||||||
|
color(Pal.orangeSpark);
|
||||||
|
|
||||||
|
for(int i : Mathf.signs){
|
||||||
|
Drawf.tri(e.x, e.y, 10f * e.fout(), 24f, e.rotation + 90 + 90f * i);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
railHit = new Effect(18f, 200f, e -> {
|
||||||
|
if(true){
|
||||||
|
color(Pal.orangeSpark);
|
||||||
|
|
||||||
|
for(int i : Mathf.signs){
|
||||||
|
Drawf.tri(e.x, e.y, 10f * e.fout(), 60f, e.rotation + 140f * i);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
e.scaled(7f, b -> {
|
||||||
|
color(Color.white, Color.lightGray, b.fin());
|
||||||
|
stroke(b.fout() * 2f + 0.2f);
|
||||||
|
Lines.circle(b.x, b.y, b.fin() * 28f);
|
||||||
|
});
|
||||||
|
|
||||||
|
color(Pal.orangeSpark);
|
||||||
|
float rot = e.rotation + Mathf.randomSeedRange(e.id, 20f);
|
||||||
|
float w = 9f * e.fout();
|
||||||
|
|
||||||
|
Drawf.tri(e.x, e.y, w, 100f, rot);
|
||||||
|
Drawf.tri(e.x, e.y, w, 10f, rot + 180f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}),
|
||||||
|
|
||||||
lancerLaserShoot = new Effect(21f, e -> {
|
lancerLaserShoot = new Effect(21f, e -> {
|
||||||
color(Pal.lancerLaser);
|
color(Pal.lancerLaser);
|
||||||
|
|
||||||
@@ -1000,7 +1070,7 @@ public class Fx{
|
|||||||
|
|
||||||
lancerLaserShootSmoke = new Effect(26f, e -> {
|
lancerLaserShootSmoke = new Effect(26f, e -> {
|
||||||
color(Color.white);
|
color(Color.white);
|
||||||
float length = e.data == null ? 70f : (Float)e.data;
|
float length = e.data == null || !(e.data instanceof Float) ? 70f : (Float)e.data;
|
||||||
|
|
||||||
randLenVectors(e.id, 7, length, e.rotation, 0f, (x, y) -> {
|
randLenVectors(e.id, 7, length, e.rotation, 0f, (x, y) -> {
|
||||||
lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
|
lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
|
||||||
@@ -1070,6 +1140,15 @@ public class Fx{
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
cloudsmoke = new Effect(70, e -> {
|
||||||
|
randLenVectors(e.id, 12, 15f + e.fin() * 45f, (x, y) -> {
|
||||||
|
float size = e.fslope() * 2f;
|
||||||
|
color(Color.gray);
|
||||||
|
alpha(e.fslope());
|
||||||
|
Fill.circle(e.x + x, e.y + y, size);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
nuclearcloud = new Effect(90, 200f, e -> {
|
nuclearcloud = new Effect(90, 200f, e -> {
|
||||||
randLenVectors(e.id, 10, e.finpow() * 90f, (x, y) -> {
|
randLenVectors(e.id, 10, e.finpow() * 90f, (x, y) -> {
|
||||||
float size = e.fout() * 14f;
|
float size = e.fout() * 14f;
|
||||||
@@ -1295,10 +1374,11 @@ public class Fx{
|
|||||||
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
//TODO fix false in constructor
|
|
||||||
ripple = new Effect(30, e -> {
|
ripple = new Effect(30, e -> {
|
||||||
|
e.lifetime = 30f*e.rotation;
|
||||||
|
|
||||||
color(Tmp.c1.set(e.color).mul(1.5f));
|
color(Tmp.c1.set(e.color).mul(1.5f));
|
||||||
stroke(e.fout() + 0.4f);
|
stroke(e.fout() * 1.4f);
|
||||||
Lines.circle(e.x, e.y, (2f + e.fin() * 4f) * e.rotation);
|
Lines.circle(e.x, e.y, (2f + e.fin() * 4f) * e.rotation);
|
||||||
}).ground(),
|
}).ground(),
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import mindustry.type.StatusEffect;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class StatusEffects implements ContentList{
|
public class StatusEffects implements ContentList{
|
||||||
public static StatusEffect none, burning, freezing, wet, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed;
|
public static StatusEffect none, burning, freezing, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
@@ -62,6 +62,13 @@ public class StatusEffects implements ContentList{
|
|||||||
opposite(burning);
|
opposite(burning);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
muddy = new StatusEffect("muddy"){{
|
||||||
|
color = Color.valueOf("46382a");
|
||||||
|
speedMultiplier = 0.94f;
|
||||||
|
effect = Fx.muddy;
|
||||||
|
effectChance = 0.09f;
|
||||||
|
}};
|
||||||
|
|
||||||
melting = new StatusEffect("melting"){{
|
melting = new StatusEffect("melting"){{
|
||||||
speedMultiplier = 0.8f;
|
speedMultiplier = 0.8f;
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
package mindustry.content;
|
package mindustry.content;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.math.*;
|
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.core.*;
|
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.Objectives.*;
|
import mindustry.game.Objectives.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
|
||||||
|
|
||||||
import static mindustry.content.Blocks.*;
|
import static mindustry.content.Blocks.*;
|
||||||
import static mindustry.content.SectorPresets.*;
|
|
||||||
import static mindustry.content.SectorPresets.craters;
|
import static mindustry.content.SectorPresets.craters;
|
||||||
|
import static mindustry.content.SectorPresets.*;
|
||||||
import static mindustry.content.UnitTypes.*;
|
import static mindustry.content.UnitTypes.*;
|
||||||
import static mindustry.type.ItemStack.*;
|
import static mindustry.type.ItemStack.*;
|
||||||
|
|
||||||
@@ -422,7 +419,11 @@ public class TechTree implements ContentList{
|
|||||||
node(risso, () -> {
|
node(risso, () -> {
|
||||||
node(minke, () -> {
|
node(minke, () -> {
|
||||||
node(bryde, () -> {
|
node(bryde, () -> {
|
||||||
|
node(sei, () -> {
|
||||||
|
node(omura, () -> {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -522,42 +523,27 @@ public class TechTree implements ContentList{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setup(){
|
public static void setup(){
|
||||||
TechNode.context = null;
|
TechNode.context = null;
|
||||||
map = new ObjectMap<>();
|
map = new ObjectMap<>();
|
||||||
all = new Seq<>();
|
all = new Seq<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TechNode node(UnlockableContent content, Runnable children){
|
public static TechNode node(UnlockableContent content, Runnable children){
|
||||||
ItemStack[] requirements;
|
return node(content, content.researchRequirements(), children);
|
||||||
|
|
||||||
if(content instanceof Block){
|
|
||||||
Block block = (Block)content;
|
|
||||||
|
|
||||||
requirements = new ItemStack[block.requirements.length];
|
|
||||||
for(int i = 0; i < requirements.length; i++){
|
|
||||||
int quantity = 40 + Mathf.round(Mathf.pow(block.requirements[i].amount, 1.25f) * 20, 10);
|
|
||||||
|
|
||||||
requirements[i] = new ItemStack(block.requirements[i].item, UI.roundAmount(quantity));
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
requirements = ItemStack.empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node(content, requirements, children);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TechNode node(UnlockableContent content, ItemStack[] requirements, Runnable children){
|
public static TechNode node(UnlockableContent content, ItemStack[] requirements, Runnable children){
|
||||||
return new TechNode(content, requirements, children);
|
return new TechNode(content, requirements, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TechNode node(UnlockableContent content, Seq<Objective> objectives, Runnable children){
|
public static TechNode node(UnlockableContent content, Seq<Objective> objectives, Runnable children){
|
||||||
TechNode node = new TechNode(content, empty, children);
|
TechNode node = new TechNode(content, empty, children);
|
||||||
node.objectives = objectives;
|
node.objectives = objectives;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TechNode node(UnlockableContent block){
|
public static TechNode node(UnlockableContent block){
|
||||||
return node(block, () -> {});
|
return node(block, () -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,14 @@ public class UnitTypes implements ContentList{
|
|||||||
//air + building + mining + payload
|
//air + building + mining + payload
|
||||||
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class, Payloadc.class}) UnitType mega;
|
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class, Payloadc.class}) UnitType mega;
|
||||||
|
|
||||||
|
//air + building + payload TODO implement
|
||||||
|
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class}) UnitType quad, oct;
|
||||||
|
|
||||||
//air + building + mining
|
//air + building + mining
|
||||||
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class}) UnitType alpha, beta, gamma;
|
public static @EntityDef({Unitc.class, Builderc.class, Minerc.class}) UnitType alpha, beta, gamma;
|
||||||
|
|
||||||
//water
|
//water + commander
|
||||||
public static @EntityDef({Unitc.class, WaterMovec.class, Commanderc.class}) UnitType risso, minke, bryde;
|
public static @EntityDef({Unitc.class, WaterMovec.class, Commanderc.class}) UnitType risso, minke, bryde, sei, omura;
|
||||||
|
|
||||||
//special block unit type
|
//special block unit type
|
||||||
public static @EntityDef({Unitc.class, BlockUnitc.class}) UnitType block;
|
public static @EntityDef({Unitc.class, BlockUnitc.class}) UnitType block;
|
||||||
@@ -61,6 +64,7 @@ public class UnitTypes implements ContentList{
|
|||||||
reload = 14f;
|
reload = 14f;
|
||||||
x = 4f;
|
x = 4f;
|
||||||
y = 2f;
|
y = 2f;
|
||||||
|
top = false;
|
||||||
ejectEffect = Fx.shellEjectSmall;
|
ejectEffect = Fx.shellEjectSmall;
|
||||||
bullet = Bullets.standardCopper;
|
bullet = Bullets.standardCopper;
|
||||||
}});
|
}});
|
||||||
@@ -75,6 +79,7 @@ public class UnitTypes implements ContentList{
|
|||||||
immunities.add(StatusEffects.burning);
|
immunities.add(StatusEffects.burning);
|
||||||
|
|
||||||
weapons.add(new Weapon("flamethrower"){{
|
weapons.add(new Weapon("flamethrower"){{
|
||||||
|
top = false;
|
||||||
shootSound = Sounds.flame;
|
shootSound = Sounds.flame;
|
||||||
shootY = 2f;
|
shootY = 2f;
|
||||||
reload = 14f;
|
reload = 14f;
|
||||||
@@ -106,6 +111,7 @@ public class UnitTypes implements ContentList{
|
|||||||
mechFrontSway = 0.55f;
|
mechFrontSway = 0.55f;
|
||||||
|
|
||||||
weapons.add(new Weapon("artillery"){{
|
weapons.add(new Weapon("artillery"){{
|
||||||
|
top = false;
|
||||||
y = 1f;
|
y = 1f;
|
||||||
x = 9f;
|
x = 9f;
|
||||||
reload = 60f;
|
reload = 60f;
|
||||||
@@ -142,6 +148,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
weapons.add(
|
weapons.add(
|
||||||
new Weapon("scepter-weapon"){{
|
new Weapon("scepter-weapon"){{
|
||||||
|
top = false;
|
||||||
y = 1f;
|
y = 1f;
|
||||||
x = 16f;
|
x = 16f;
|
||||||
shootY = 8f;
|
shootY = 8f;
|
||||||
@@ -201,6 +208,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
weapons.add(
|
weapons.add(
|
||||||
new Weapon("reign-weapon"){{
|
new Weapon("reign-weapon"){{
|
||||||
|
top = false;
|
||||||
y = 1f;
|
y = 1f;
|
||||||
x = 21.5f;
|
x = 21.5f;
|
||||||
shootY = 11f;
|
shootY = 11f;
|
||||||
@@ -259,6 +267,7 @@ public class UnitTypes implements ContentList{
|
|||||||
abilities.add(new HealFieldAbility(10f, 60f * 4, 60f));
|
abilities.add(new HealFieldAbility(10f, 60f * 4, 60f));
|
||||||
|
|
||||||
weapons.add(new Weapon("heal-weapon"){{
|
weapons.add(new Weapon("heal-weapon"){{
|
||||||
|
top = false;
|
||||||
shootY = 2f;
|
shootY = 2f;
|
||||||
reload = 24f;
|
reload = 24f;
|
||||||
x = 4.5f;
|
x = 4.5f;
|
||||||
@@ -274,7 +283,7 @@ public class UnitTypes implements ContentList{
|
|||||||
itemCapacity = 60;
|
itemCapacity = 60;
|
||||||
canBoost = true;
|
canBoost = true;
|
||||||
boostMultiplier = 1.5f;
|
boostMultiplier = 1.5f;
|
||||||
speed = 0.48f;
|
speed = 0.62f;
|
||||||
hitsize = 10f;
|
hitsize = 10f;
|
||||||
health = 320f;
|
health = 320f;
|
||||||
buildSpeed = 0.9f;
|
buildSpeed = 0.9f;
|
||||||
@@ -287,6 +296,7 @@ public class UnitTypes implements ContentList{
|
|||||||
abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f));
|
abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f));
|
||||||
|
|
||||||
weapons.add(new Weapon("heal-shotgun-weapon"){{
|
weapons.add(new Weapon("heal-shotgun-weapon"){{
|
||||||
|
top = false;
|
||||||
x = 5f;
|
x = 5f;
|
||||||
shake = 2.2f;
|
shake = 2.2f;
|
||||||
y = 0.5f;
|
y = 0.5f;
|
||||||
@@ -336,6 +346,7 @@ public class UnitTypes implements ContentList{
|
|||||||
abilities.add(new ForceFieldAbility(60f, 0.3f, 400f, 60f * 6));
|
abilities.add(new ForceFieldAbility(60f, 0.3f, 400f, 60f * 6));
|
||||||
|
|
||||||
weapons.add(new Weapon("beam-weapon"){{
|
weapons.add(new Weapon("beam-weapon"){{
|
||||||
|
top = false;
|
||||||
shake = 2f;
|
shake = 2f;
|
||||||
shootY = 4f;
|
shootY = 4f;
|
||||||
x = 6.5f;
|
x = 6.5f;
|
||||||
@@ -406,6 +417,7 @@ public class UnitTypes implements ContentList{
|
|||||||
groundLayer = Layer.legUnit - 1f;
|
groundLayer = Layer.legUnit - 1f;
|
||||||
|
|
||||||
weapons.add(new Weapon("eruption"){{
|
weapons.add(new Weapon("eruption"){{
|
||||||
|
top = false;
|
||||||
shootY = 3f;
|
shootY = 3f;
|
||||||
reload = 10f;
|
reload = 10f;
|
||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
@@ -668,8 +680,8 @@ public class UnitTypes implements ContentList{
|
|||||||
width = height = 25f;
|
width = height = 25f;
|
||||||
collidesTiles = collides = true;
|
collidesTiles = collides = true;
|
||||||
ammoMultiplier = 4f;
|
ammoMultiplier = 4f;
|
||||||
splashDamageRadius = 95f;
|
splashDamageRadius = 90f;
|
||||||
splashDamage = 90f;
|
splashDamage = 75f;
|
||||||
backColor = Pal.sapBulletBack;
|
backColor = Pal.sapBulletBack;
|
||||||
frontColor = lightningColor = Pal.sapBullet;
|
frontColor = lightningColor = Pal.sapBullet;
|
||||||
lightning = 5;
|
lightning = 5;
|
||||||
@@ -690,7 +702,7 @@ public class UnitTypes implements ContentList{
|
|||||||
width = height = 20f;
|
width = height = 20f;
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
splashDamageRadius = 80f;
|
splashDamageRadius = 80f;
|
||||||
splashDamage = 45f;
|
splashDamage = 40f;
|
||||||
backColor = Pal.sapBulletBack;
|
backColor = Pal.sapBulletBack;
|
||||||
frontColor = lightningColor = Pal.sapBullet;
|
frontColor = lightningColor = Pal.sapBullet;
|
||||||
lightning = 2;
|
lightning = 2;
|
||||||
@@ -735,6 +747,7 @@ public class UnitTypes implements ContentList{
|
|||||||
accel = 0.08f;
|
accel = 0.08f;
|
||||||
drag = 0.016f;
|
drag = 0.016f;
|
||||||
flying = true;
|
flying = true;
|
||||||
|
hitsize = 9f;
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
engineOffset = 7.8f;
|
engineOffset = 7.8f;
|
||||||
range = 140f;
|
range = 140f;
|
||||||
@@ -1001,6 +1014,7 @@ public class UnitTypes implements ContentList{
|
|||||||
abilities.add(new HealFieldAbility(5f, 60f * 5, 50f));
|
abilities.add(new HealFieldAbility(5f, 60f * 5, 50f));
|
||||||
|
|
||||||
weapons.add(new Weapon("heal-weapon-mount"){{
|
weapons.add(new Weapon("heal-weapon-mount"){{
|
||||||
|
top = false;
|
||||||
y = -2.5f;
|
y = -2.5f;
|
||||||
x = 3.5f;
|
x = 3.5f;
|
||||||
reload = 30f;
|
reload = 30f;
|
||||||
@@ -1033,6 +1047,8 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
mineTier = 2;
|
mineTier = 2;
|
||||||
health = 500;
|
health = 500;
|
||||||
|
armor = 2f;
|
||||||
|
armor = 5f;
|
||||||
speed = 1.8f;
|
speed = 1.8f;
|
||||||
accel = 0.06f;
|
accel = 0.06f;
|
||||||
drag = 0.017f;
|
drag = 0.017f;
|
||||||
@@ -1062,6 +1078,65 @@ public class UnitTypes implements ContentList{
|
|||||||
}});
|
}});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
quad = new UnitType("quad"){{
|
||||||
|
mineTier = 2;
|
||||||
|
armor = 4f;
|
||||||
|
health = 7000;
|
||||||
|
speed = 1.2f;
|
||||||
|
rotateSpeed = 2f;
|
||||||
|
accel = 0.05f;
|
||||||
|
drag = 0.017f;
|
||||||
|
lowAltitude = false;
|
||||||
|
flying = true;
|
||||||
|
engineOffset = 12f;
|
||||||
|
engineSize = 6f;
|
||||||
|
rotateShooting = false;
|
||||||
|
hitsize = 32f;
|
||||||
|
payloadCapacity = (3 * 3) * (8 * 8);
|
||||||
|
buildSpeed = 2.5f;
|
||||||
|
range = 140f;
|
||||||
|
|
||||||
|
weapons.add(
|
||||||
|
new Weapon(){{
|
||||||
|
x = y = 0f;
|
||||||
|
mirror = false;
|
||||||
|
reload = 60f;
|
||||||
|
minShootVelocity = 0.01f;
|
||||||
|
|
||||||
|
bullet = new BasicBulletType(){{
|
||||||
|
sprite = "large-bomb";
|
||||||
|
width = height = 120/4f;
|
||||||
|
|
||||||
|
backColor = Pal.heal;
|
||||||
|
frontColor = Color.white;
|
||||||
|
mixColorTo = Color.white;
|
||||||
|
|
||||||
|
shootCone = 180f;
|
||||||
|
ejectEffect = Fx.none;
|
||||||
|
ignoreRotation = true;
|
||||||
|
shootSound = Sounds.none;
|
||||||
|
despawnShake = 4f;
|
||||||
|
|
||||||
|
collidesAir = false;
|
||||||
|
|
||||||
|
lifetime = 70f;
|
||||||
|
|
||||||
|
despawnEffect = Fx.healBomb;
|
||||||
|
hitEffect = Fx.massiveExplosion;
|
||||||
|
keepVelocity = false;
|
||||||
|
spin = 2f;
|
||||||
|
|
||||||
|
shrinkX = shrinkY = 0.7f;
|
||||||
|
|
||||||
|
speed = 0.001f;
|
||||||
|
collides = false;
|
||||||
|
|
||||||
|
splashDamage = 230f;
|
||||||
|
splashDamageRadius = 90f;
|
||||||
|
}};
|
||||||
|
}});
|
||||||
|
}};
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region naval attack
|
//region naval attack
|
||||||
|
|
||||||
@@ -1125,6 +1200,7 @@ public class UnitTypes implements ContentList{
|
|||||||
accel = 0.3f;
|
accel = 0.3f;
|
||||||
rotateSpeed = 2.6f;
|
rotateSpeed = 2.6f;
|
||||||
immunities = ObjectSet.with(StatusEffects.wet);
|
immunities = ObjectSet.with(StatusEffects.wet);
|
||||||
|
rotateShooting = false;
|
||||||
|
|
||||||
trailLength = 20;
|
trailLength = 20;
|
||||||
trailX = 5.5f;
|
trailX = 5.5f;
|
||||||
@@ -1164,7 +1240,7 @@ public class UnitTypes implements ContentList{
|
|||||||
accel = 0.2f;
|
accel = 0.2f;
|
||||||
rotateSpeed = 1.8f;
|
rotateSpeed = 1.8f;
|
||||||
drag = 0.17f;
|
drag = 0.17f;
|
||||||
hitsize = 14f;
|
hitsize = 16f;
|
||||||
armor = 6f;
|
armor = 6f;
|
||||||
immunities = ObjectSet.with(StatusEffects.wet);
|
immunities = ObjectSet.with(StatusEffects.wet);
|
||||||
rotateShooting = false;
|
rotateShooting = false;
|
||||||
@@ -1186,7 +1262,7 @@ public class UnitTypes implements ContentList{
|
|||||||
shootY = 7f;
|
shootY = 7f;
|
||||||
shake = 5f;
|
shake = 5f;
|
||||||
recoil = 4f;
|
recoil = 4f;
|
||||||
occlusion = 17f;
|
occlusion = 12f;
|
||||||
|
|
||||||
shots = 1;
|
shots = 1;
|
||||||
inaccuracy = 3f;
|
inaccuracy = 3f;
|
||||||
@@ -1252,6 +1328,142 @@ public class UnitTypes implements ContentList{
|
|||||||
}});
|
}});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
sei = new UnitType("sei"){{
|
||||||
|
health = 10000;
|
||||||
|
armor = 12f;
|
||||||
|
|
||||||
|
speed = 0.73f;
|
||||||
|
drag = 0.17f;
|
||||||
|
hitsize = 39f;
|
||||||
|
accel = 0.2f;
|
||||||
|
rotateSpeed = 1.3f;
|
||||||
|
immunities = ObjectSet.with(StatusEffects.wet);
|
||||||
|
rotateShooting = false;
|
||||||
|
|
||||||
|
trailLength = 50;
|
||||||
|
trailX = 18f;
|
||||||
|
trailY = -21f;
|
||||||
|
trailScl = 3f;
|
||||||
|
|
||||||
|
weapons.add(new Weapon("sei-launcher"){{
|
||||||
|
|
||||||
|
x = 0f;
|
||||||
|
y = 0f;
|
||||||
|
rotate = true;
|
||||||
|
rotateSpeed = 4f;
|
||||||
|
mirror = false;
|
||||||
|
|
||||||
|
occlusion = 20f;
|
||||||
|
|
||||||
|
shootY = 2f;
|
||||||
|
recoil = 4f;
|
||||||
|
reload = 45f;
|
||||||
|
shots = 6;
|
||||||
|
spacing = 10f;
|
||||||
|
velocityRnd = 0.4f;
|
||||||
|
inaccuracy = 7f;
|
||||||
|
ejectEffect = Fx.none;
|
||||||
|
shake = 3f;
|
||||||
|
shootSound = Sounds.shootBig;
|
||||||
|
xRand = 8f;
|
||||||
|
shotDelay = 1f;
|
||||||
|
|
||||||
|
bullet = new MissileBulletType(4.2f, 25){{
|
||||||
|
homingPower = 0.12f;
|
||||||
|
width = 8f;
|
||||||
|
height = 8f;
|
||||||
|
shrinkX = shrinkY = 0f;
|
||||||
|
drag = -0.003f;
|
||||||
|
homingRange = 80f;
|
||||||
|
keepVelocity = false;
|
||||||
|
splashDamageRadius = 25f;
|
||||||
|
splashDamage = 25f;
|
||||||
|
lifetime = 56f;
|
||||||
|
trailColor = Pal.bulletYellowBack;
|
||||||
|
backColor = Pal.bulletYellowBack;
|
||||||
|
frontColor = Pal.bulletYellow;
|
||||||
|
hitEffect = Fx.blastExplosion;
|
||||||
|
despawnEffect = Fx.blastExplosion;
|
||||||
|
weaveScale = 8f;
|
||||||
|
weaveMag = 2f;
|
||||||
|
}};
|
||||||
|
}});
|
||||||
|
|
||||||
|
weapons.add(new Weapon("large-bullet-mount"){{
|
||||||
|
reload = 80f;
|
||||||
|
cooldownTime = 90f;
|
||||||
|
x = 70f/4f;
|
||||||
|
y = -66f/4f;
|
||||||
|
rotateSpeed = 4f;
|
||||||
|
rotate = true;
|
||||||
|
shootY = 7f;
|
||||||
|
shake = 2f;
|
||||||
|
recoil = 3f;
|
||||||
|
occlusion = 12f;
|
||||||
|
ejectEffect = Fx.shellEjectBig;
|
||||||
|
|
||||||
|
shots = 3;
|
||||||
|
shotDelay = 4f;
|
||||||
|
inaccuracy = 1f;
|
||||||
|
bullet = new BasicBulletType(7f, 50){{
|
||||||
|
width = 13f;
|
||||||
|
height = 19f;
|
||||||
|
shootEffect = Fx.shootBig;
|
||||||
|
lifetime = 30f;
|
||||||
|
}};
|
||||||
|
}});
|
||||||
|
}};
|
||||||
|
|
||||||
|
omura = new UnitType("omura"){{
|
||||||
|
health = 22000;
|
||||||
|
speed = 0.62f;
|
||||||
|
drag = 0.18f;
|
||||||
|
hitsize = 50f;
|
||||||
|
armor = 16f;
|
||||||
|
accel = 0.19f;
|
||||||
|
rotateSpeed = 0.9f;
|
||||||
|
immunities = ObjectSet.with(StatusEffects.wet);
|
||||||
|
rotateShooting = false;
|
||||||
|
|
||||||
|
float spawnTime = 60f * 25f;
|
||||||
|
|
||||||
|
abilities.add(new UnitSpawnAbility(flare, spawnTime, 19.25f, -31.75f), new UnitSpawnAbility(flare, spawnTime, -19.25f, -31.75f));
|
||||||
|
|
||||||
|
trailLength = 70;
|
||||||
|
trailX = 23f;
|
||||||
|
trailY = -32f;
|
||||||
|
trailScl = 3.5f;
|
||||||
|
|
||||||
|
weapons.add(new Weapon("omura-cannon"){{
|
||||||
|
reload = 110f;
|
||||||
|
cooldownTime = 90f;
|
||||||
|
mirror = false;
|
||||||
|
x = 0f;
|
||||||
|
y = -3.5f;
|
||||||
|
rotateSpeed = 1.4f;
|
||||||
|
rotate = true;
|
||||||
|
shootY = 23f;
|
||||||
|
shake = 6f;
|
||||||
|
recoil = 10.5f;
|
||||||
|
occlusion = 50f;
|
||||||
|
|
||||||
|
shots = 1;
|
||||||
|
ejectEffect = Fx.none;
|
||||||
|
|
||||||
|
bullet = new RailBulletType(){{
|
||||||
|
shootEffect = Fx.railShoot;
|
||||||
|
speed = 67f;
|
||||||
|
lifetime = 8f;
|
||||||
|
pierceEffect = Fx.railHit;
|
||||||
|
updateEffect = Fx.railTrail;
|
||||||
|
hitEffect = Fx.massiveExplosion;
|
||||||
|
smokeEffect = Fx.shootBig2;
|
||||||
|
damage = 1250;
|
||||||
|
pierceDamageFactor = 0.5f;
|
||||||
|
}};
|
||||||
|
}});
|
||||||
|
}};
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region core
|
//region core
|
||||||
|
|
||||||
@@ -1276,6 +1488,7 @@ public class UnitTypes implements ContentList{
|
|||||||
reload = 17f;
|
reload = 17f;
|
||||||
x = 2.75f;
|
x = 2.75f;
|
||||||
y = 1f;
|
y = 1f;
|
||||||
|
top = false;
|
||||||
|
|
||||||
bullet = new BasicBulletType(2.5f, 9){{
|
bullet = new BasicBulletType(2.5f, 9){{
|
||||||
width = 7f;
|
width = 7f;
|
||||||
@@ -1308,6 +1521,7 @@ public class UnitTypes implements ContentList{
|
|||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
|
|
||||||
weapons.add(new Weapon("small-mount-weapon"){{
|
weapons.add(new Weapon("small-mount-weapon"){{
|
||||||
|
top = false;
|
||||||
reload = 20f;
|
reload = 20f;
|
||||||
x = 3f;
|
x = 3f;
|
||||||
y = 0.5f;
|
y = 0.5f;
|
||||||
@@ -1345,6 +1559,7 @@ public class UnitTypes implements ContentList{
|
|||||||
hitsize = 10f;
|
hitsize = 10f;
|
||||||
|
|
||||||
weapons.add(new Weapon("small-mount-weapon"){{
|
weapons.add(new Weapon("small-mount-weapon"){{
|
||||||
|
top = false;
|
||||||
reload = 15f;
|
reload = 15f;
|
||||||
x = 1f;
|
x = 1f;
|
||||||
y = 2f;
|
y = 2f;
|
||||||
|
|||||||
@@ -191,6 +191,10 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetCamera(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadAsync(){
|
public void loadAsync(){
|
||||||
Draw.scl = 1f / Core.atlas.find("scale_marker").width;
|
Draw.scl = 1f / Core.atlas.find("scale_marker").width;
|
||||||
@@ -280,6 +284,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
try{
|
try{
|
||||||
net.reset();
|
net.reset();
|
||||||
slot.load();
|
slot.load();
|
||||||
|
slot.setAutosave(true);
|
||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
|
|
||||||
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
||||||
@@ -329,7 +334,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void playTutorial(){
|
public void playTutorial(){
|
||||||
ui.showInfo("There is no tutorial yet.");
|
ui.showInfo("@indev.notready");
|
||||||
//TODO implement
|
//TODO implement
|
||||||
//ui.showInfo("death");
|
//ui.showInfo("death");
|
||||||
/*
|
/*
|
||||||
@@ -429,7 +434,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
//just a regular reminder
|
//just a regular reminder
|
||||||
if(!OS.prop("user.name").equals("anuke") && !OS.hasEnv("iknowwhatimdoing")){
|
if(!OS.prop("user.name").equals("anuke") && !OS.hasEnv("iknowwhatimdoing")){
|
||||||
app.post(() -> app.post(() -> {
|
app.post(() -> app.post(() -> {
|
||||||
ui.showStartupInfo("@indevpopup");
|
ui.showStartupInfo("@indev.popup");
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class GameState{
|
|||||||
/** Wave countdown in ticks. */
|
/** Wave countdown in ticks. */
|
||||||
public float wavetime;
|
public float wavetime;
|
||||||
/** Whether the game is in game over state. */
|
/** Whether the game is in game over state. */
|
||||||
public boolean gameOver = false, launched = false, serverPaused = false;
|
public boolean gameOver = false, launched = false, serverPaused = false, wasTimeout;
|
||||||
/** Map that is currently being played on. */
|
/** Map that is currently being played on. */
|
||||||
public @NonNull Map map = emptyMap;
|
public @NonNull Map map = emptyMap;
|
||||||
/** The current game rules. */
|
/** The current game rules. */
|
||||||
|
|||||||
@@ -337,7 +337,14 @@ public class Logic implements ApplicationListener{
|
|||||||
|
|
||||||
//force pausing when the player is out of sector time
|
//force pausing when the player is out of sector time
|
||||||
if(state.isOutOfTime()){
|
if(state.isOutOfTime()){
|
||||||
state.set(State.paused);
|
if(!state.wasTimeout){
|
||||||
|
universe.displayTimeEnd();
|
||||||
|
state.wasTimeout = true;
|
||||||
|
}
|
||||||
|
//if no turn was run.
|
||||||
|
if(state.isOutOfTime()){
|
||||||
|
state.set(State.paused);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!state.isPaused()){
|
if(!state.isPaused()){
|
||||||
|
|||||||
@@ -338,8 +338,6 @@ public class NetClient implements ApplicationListener{
|
|||||||
@Remote(variants = Variant.both)
|
@Remote(variants = Variant.both)
|
||||||
public static void setRules(Rules rules){
|
public static void setRules(Rules rules){
|
||||||
state.rules = rules;
|
state.rules = rules;
|
||||||
//campaign is not valid in multiplayer
|
|
||||||
state.rules.sector = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(variants = Variant.both)
|
@Remote(variants = Variant.both)
|
||||||
@@ -442,7 +440,7 @@ public class NetClient implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
|
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
|
||||||
public static void stateSnapshot(float waveTime, int wave, int enemies, boolean paused, boolean gameOver, short coreDataLen, byte[] coreData){
|
public static void stateSnapshot(float waveTime, int wave, int enemies, boolean paused, boolean gameOver, int timeData, short coreDataLen, byte[] coreData){
|
||||||
try{
|
try{
|
||||||
if(wave > state.wave){
|
if(wave > state.wave){
|
||||||
state.wave = wave;
|
state.wave = wave;
|
||||||
@@ -455,6 +453,8 @@ public class NetClient implements ApplicationListener{
|
|||||||
state.enemies = enemies;
|
state.enemies = enemies;
|
||||||
state.serverPaused = paused;
|
state.serverPaused = paused;
|
||||||
|
|
||||||
|
universe.updateNetSeconds(timeData);
|
||||||
|
|
||||||
netClient.byteStream.setBytes(net.decompressSnapshot(coreData, coreDataLen));
|
netClient.byteStream.setBytes(net.decompressSnapshot(coreData, coreDataLen));
|
||||||
DataInputStream input = netClient.dataStream;
|
DataInputStream input = netClient.dataStream;
|
||||||
|
|
||||||
@@ -549,6 +549,10 @@ public class NetClient implements ApplicationListener{
|
|||||||
quiet = true;
|
quiet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearRemovedEntity(int id){
|
||||||
|
removed.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
public void addRemovedEntity(int id){
|
public void addRemovedEntity(int id){
|
||||||
removed.add(id);
|
removed.add(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -593,38 +593,38 @@ public class NetServer implements ApplicationListener{
|
|||||||
if(player.isBuilder()){
|
if(player.isBuilder()){
|
||||||
player.builder().clearBuilding();
|
player.builder().clearBuilding();
|
||||||
player.builder().updateBuilding(building);
|
player.builder().updateBuilding(building);
|
||||||
|
|
||||||
|
if(requests != null){
|
||||||
|
for(BuildPlan req : requests){
|
||||||
|
if(req == null) continue;
|
||||||
|
Tile tile = world.tile(req.x, req.y);
|
||||||
|
if(tile == null || (!req.breaking && req.block == null)) continue;
|
||||||
|
//auto-skip done requests
|
||||||
|
if(req.breaking && tile.block() == Blocks.air){
|
||||||
|
continue;
|
||||||
|
}else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || (tile.build != null && tile.build.rotation == req.rotation))){
|
||||||
|
continue;
|
||||||
|
}else if(con.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so
|
||||||
|
continue;
|
||||||
|
}else if(!netServer.admins.allowAction(player, req.breaking ? ActionType.breakBlock : ActionType.placeBlock, tile, action -> { //make sure request is allowed by the server
|
||||||
|
action.block = req.block;
|
||||||
|
action.rotation = req.rotation;
|
||||||
|
action.config = req.config;
|
||||||
|
})){
|
||||||
|
//force the player to remove this request if that's not the case
|
||||||
|
Call.removeQueueBlock(player.con, req.x, req.y, req.breaking);
|
||||||
|
con.rejectedRequests.add(req);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
player.builder().plans().addLast(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(player.isMiner()){
|
if(player.isMiner()){
|
||||||
player.miner().mineTile(mining);
|
player.miner().mineTile(mining);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(requests != null){
|
|
||||||
for(BuildPlan req : requests){
|
|
||||||
if(req == null) continue;
|
|
||||||
Tile tile = world.tile(req.x, req.y);
|
|
||||||
if(tile == null || (!req.breaking && req.block == null)) continue;
|
|
||||||
//auto-skip done requests
|
|
||||||
if(req.breaking && tile.block() == Blocks.air){
|
|
||||||
continue;
|
|
||||||
}else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || (tile.build != null && tile.build.rotation == req.rotation))){
|
|
||||||
continue;
|
|
||||||
}else if(con.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so
|
|
||||||
continue;
|
|
||||||
}else if(!netServer.admins.allowAction(player, req.breaking ? ActionType.breakBlock : ActionType.placeBlock, tile, action -> { //make sure request is allowed by the server
|
|
||||||
action.block = req.block;
|
|
||||||
action.rotation = req.rotation;
|
|
||||||
action.config = req.config;
|
|
||||||
})){
|
|
||||||
//force the player to remove this request if that's not the case
|
|
||||||
Call.removeQueueBlock(player.con, req.x, req.y, req.breaking);
|
|
||||||
con.rejectedRequests.add(req);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
player.builder().plans().addLast(req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
con.rejectedRequests.clear();
|
con.rejectedRequests.clear();
|
||||||
|
|
||||||
if(!player.dead()){
|
if(!player.dead()){
|
||||||
@@ -846,7 +846,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
byte[] stateBytes = syncStream.toByteArray();
|
byte[] stateBytes = syncStream.toByteArray();
|
||||||
|
|
||||||
//write basic state data.
|
//write basic state data.
|
||||||
Call.stateSnapshot(player.con, state.wavetime, state.wave, state.enemies, state.serverPaused, state.gameOver, (short)stateBytes.length, net.compressSnapshot(stateBytes));
|
Call.stateSnapshot(player.con, state.wavetime, state.wave, state.enemies, state.serverPaused, state.gameOver, universe.seconds(), (short)stateBytes.length, net.compressSnapshot(stateBytes));
|
||||||
|
|
||||||
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
|
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import arc.func.*;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.struct.ObjectIntMap.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.noise.*;
|
import arc.util.noise.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
@@ -19,7 +21,6 @@ import mindustry.maps.*;
|
|||||||
import mindustry.maps.filters.*;
|
import mindustry.maps.filters.*;
|
||||||
import mindustry.maps.filters.GenerateFilter.*;
|
import mindustry.maps.filters.GenerateFilter.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.type.Sector.*;
|
|
||||||
import mindustry.type.Weather.*;
|
import mindustry.type.Weather.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
@@ -33,11 +34,17 @@ public class World{
|
|||||||
public @NonNull Tiles tiles = new Tiles(0, 0);
|
public @NonNull Tiles tiles = new Tiles(0, 0);
|
||||||
|
|
||||||
private boolean generating, invalidMap;
|
private boolean generating, invalidMap;
|
||||||
|
private ObjectMap<Map, Runnable> customMapLoaders = new ObjectMap<>();
|
||||||
|
|
||||||
public World(){
|
public World(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Adds a custom handler function for loading a custom map - usually a generated one. */
|
||||||
|
public void addMapLoader(Map map, Runnable loader){
|
||||||
|
customMapLoaders.put(map, loader);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isInvalidMap(){
|
public boolean isInvalidMap(){
|
||||||
return invalidMap;
|
return invalidMap;
|
||||||
}
|
}
|
||||||
@@ -255,9 +262,71 @@ public class World{
|
|||||||
|
|
||||||
state.rules.weather.clear();
|
state.rules.weather.clear();
|
||||||
|
|
||||||
if(sector.is(SectorAttribute.rainy)) state.rules.weather.add(new WeatherEntry(Weathers.rain));
|
//apply weather based on terrain
|
||||||
if(sector.is(SectorAttribute.snowy)) state.rules.weather.add(new WeatherEntry(Weathers.snow));
|
ObjectIntMap<Block> floorc = new ObjectIntMap<>();
|
||||||
if(sector.is(SectorAttribute.desert)) state.rules.weather.add(new WeatherEntry(Weathers.sandstorm));
|
ObjectSet<UnlockableContent> content = new ObjectSet<>();
|
||||||
|
|
||||||
|
float waterFloors = 0, totalFloors = 0;
|
||||||
|
|
||||||
|
for(Tile tile : world.tiles){
|
||||||
|
if(world.getDarkness(tile.x, tile.y) >= 3){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Liquid liquid = tile.floor().liquidDrop;
|
||||||
|
if(tile.floor().itemDrop != null) content.add(tile.floor().itemDrop);
|
||||||
|
if(tile.overlay().itemDrop != null) content.add(tile.overlay().itemDrop);
|
||||||
|
if(liquid != null) content.add(liquid);
|
||||||
|
|
||||||
|
if(!tile.block().isStatic()){
|
||||||
|
totalFloors ++;
|
||||||
|
if(liquid == Liquids.water){
|
||||||
|
waterFloors += tile.floor().isDeep() ? 1f : 0.7f;
|
||||||
|
}
|
||||||
|
floorc.increment(tile.floor());
|
||||||
|
if(tile.overlay() != Blocks.air){
|
||||||
|
floorc.increment(tile.overlay());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//sort counts in descending order
|
||||||
|
Seq<Entry<Block>> entries = floorc.entries().toArray();
|
||||||
|
entries.sort(e -> -e.value);
|
||||||
|
//remove all blocks occuring < 30 times - unimportant
|
||||||
|
entries.removeAll(e -> e.value < 30);
|
||||||
|
|
||||||
|
Block[] floors = new Block[entries.size];
|
||||||
|
int[] floorCounts = new int[entries.size];
|
||||||
|
for(int i = 0; i < entries.size; i++){
|
||||||
|
floorCounts[i] = entries.get(i).value;
|
||||||
|
floors[i] = entries.get(i).key;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO bad code
|
||||||
|
boolean hasSnow = floors[0].name.contains("ice") || floors[0].name.contains("snow");
|
||||||
|
boolean hasRain = !hasSnow && floors[0].name.contains("water");
|
||||||
|
boolean hasDesert = !hasSnow && !hasRain && floors[0].name.contains("sand");
|
||||||
|
boolean hasSpores = floors[0].name.contains("spore") || floors[0].name.contains("moss") || floors[0].name.contains("tainted");
|
||||||
|
|
||||||
|
if(hasSnow){
|
||||||
|
state.rules.weather.add(new WeatherEntry(Weathers.snow));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasRain){
|
||||||
|
state.rules.weather.add(new WeatherEntry(Weathers.rain));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasDesert){
|
||||||
|
state.rules.weather.add(new WeatherEntry(Weathers.sandstorm));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasSpores){
|
||||||
|
state.rules.weather.add(new WeatherEntry(Weathers.sporestorm));
|
||||||
|
}
|
||||||
|
|
||||||
|
state.secinfo.resources = content.asArray();
|
||||||
|
state.secinfo.resources.sort(Structs.comps(Structs.comparing(Content::getContentType), Structs.comparingInt(c -> c.id)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +339,12 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void loadMap(Map map, Rules checkRules){
|
public void loadMap(Map map, Rules checkRules){
|
||||||
|
//load using custom loader if possible
|
||||||
|
if(customMapLoaders.containsKey(map)){
|
||||||
|
customMapLoaders.get(map).run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
SaveIO.load(map.file, new FilterContext(map));
|
SaveIO.load(map.file, new FilterContext(map));
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
@@ -444,7 +519,7 @@ public class World{
|
|||||||
dark = Math.max((edgeBlend - edgeDst) * (4f / edgeBlend), dark);
|
dark = Math.max((edgeBlend - edgeDst) * (4f / edgeBlend), dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.hasSector()){
|
if(state.hasSector() && state.getSector().preset == null){
|
||||||
int circleBlend = 14;
|
int circleBlend = 14;
|
||||||
//quantized angle
|
//quantized angle
|
||||||
float offset = state.getSector().rect.rotation + 90;
|
float offset = state.getSector().rect.rotation + 90;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import arc.util.ArcAnnotate.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.type.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -30,7 +31,7 @@ public abstract class UnlockableContent extends MappableContent{
|
|||||||
|
|
||||||
this.localizedName = Core.bundle.get(getContentType() + "." + this.name + ".name", this.name);
|
this.localizedName = Core.bundle.get(getContentType() + "." + this.name + ".name", this.name);
|
||||||
this.description = Core.bundle.getOrNull(getContentType() + "." + this.name + ".description");
|
this.description = Core.bundle.getOrNull(getContentType() + "." + this.name + ".description");
|
||||||
this.unlocked = Core.settings != null && Core.settings.getBool(name + "-unlocked", false);
|
this.unlocked = Core.settings != null && Core.settings.getBool(this.name + "-unlocked", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String displayDescription(){
|
public String displayDescription(){
|
||||||
@@ -43,6 +44,11 @@ public abstract class UnlockableContent extends MappableContent{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return items needed to research this content */
|
||||||
|
public ItemStack[] researchRequirements(){
|
||||||
|
return ItemStack.empty;
|
||||||
|
}
|
||||||
|
|
||||||
public String emoji(){
|
public String emoji(){
|
||||||
return Fonts.getUnicodeStr(name);
|
return Fonts.getUnicodeStr(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,8 +64,12 @@ public class DrawOperation{
|
|||||||
if(type == OpType.floor.ordinal()){
|
if(type == OpType.floor.ordinal()){
|
||||||
tile.setFloor((Floor)content.block(to));
|
tile.setFloor((Floor)content.block(to));
|
||||||
}else if(type == OpType.block.ordinal()){
|
}else if(type == OpType.block.ordinal()){
|
||||||
|
tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y));
|
||||||
|
|
||||||
Block block = content.block(to);
|
Block block = content.block(to);
|
||||||
tile.setBlock(block, tile.team(), tile.build == null ? 0 : tile.build.rotation);
|
tile.setBlock(block, tile.team(), tile.build == null ? 0 : tile.build.rotation);
|
||||||
|
|
||||||
|
tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y));
|
||||||
}else if(type == OpType.rotation.ordinal()){
|
}else if(type == OpType.rotation.ordinal()){
|
||||||
if(tile.build != null) tile.build.rotation = to;
|
if(tile.build != null) tile.build.rotation = to;
|
||||||
}else if(type == OpType.team.ordinal()){
|
}else if(type == OpType.team.ordinal()){
|
||||||
@@ -74,7 +78,7 @@ public class DrawOperation{
|
|||||||
tile.setOverlayID(to);
|
tile.setOverlayID(to);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
editor.renderer().updatePoint(tile.x, tile.y);
|
editor.renderer.updatePoint(tile.x, tile.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Struct
|
@Struct
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFloor(@NonNull Floor type){
|
public void setFloor(@NonNull Floor type){
|
||||||
if(state.isGame()){
|
if(skip()){
|
||||||
super.setFloor(type);
|
super.setFloor(type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -41,20 +41,25 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(Block type, Team team, int rotation){
|
public void setBlock(Block type, Team team, int rotation){
|
||||||
if(state.isGame()){
|
if(skip()){
|
||||||
super.setBlock(type, team, rotation);
|
super.setBlock(type, team, rotation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.block == type && (build == null || build.rotation == rotation)){
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
op(OpType.block, block.id);
|
op(OpType.block, block.id);
|
||||||
if(rotation != 0) op(OpType.rotation, (byte)rotation);
|
if(rotation != 0) op(OpType.rotation, (byte)rotation);
|
||||||
if(team() != Team.derelict) op(OpType.team, (byte)team().id);
|
if(team != Team.derelict) op(OpType.team, (byte)team.id);
|
||||||
super.setBlock(type, team, rotation);
|
super.setBlock(type, team, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTeam(Team team){
|
public void setTeam(Team team){
|
||||||
if(state.isGame()){
|
if(skip()){
|
||||||
super.setTeam(team);
|
super.setTeam(team);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -66,7 +71,7 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOverlay(Block overlay){
|
public void setOverlay(Block overlay){
|
||||||
if(state.isGame()){
|
if(skip()){
|
||||||
super.setOverlay(overlay);
|
super.setOverlay(overlay);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -79,23 +84,23 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void fireChanged(){
|
protected void fireChanged(){
|
||||||
if(state.isGame()){
|
if(skip()){
|
||||||
super.fireChanged();
|
super.fireChanged();
|
||||||
}else{
|
}else{
|
||||||
ui.editor.editor.renderer().updatePoint(x, y);
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recache(){
|
public void recache(){
|
||||||
if(state.isGame()){
|
if(skip()){
|
||||||
super.recache();
|
super.recache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeEntity(Team team, Prov<Building> entityprov, int rotation){
|
protected void changeEntity(Team team, Prov<Building> entityprov, int rotation){
|
||||||
if(state.isGame()){
|
if(skip()){
|
||||||
super.changeEntity(team, entityprov, rotation);
|
super.changeEntity(team, entityprov, rotation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -116,6 +121,14 @@ public class EditorTile extends Tile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void update(){
|
||||||
|
ui.editor.editor.renderer.updatePoint(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean skip(){
|
||||||
|
return state.isGame() || ui.editor.editor.isLoading();
|
||||||
|
}
|
||||||
|
|
||||||
private void op(OpType type, short value){
|
private void op(OpType type, short value){
|
||||||
ui.editor.editor.addTileOp(TileOp.get(x, y, (byte)type.ordinal(), value));
|
ui.editor.editor.addTileOp(TileOp.get(x, y, (byte)type.ordinal(), value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public enum EditorTool{
|
|||||||
if(!Structs.inBounds(x, y, editor.width(), editor.height())) return;
|
if(!Structs.inBounds(x, y, editor.width(), editor.height())) return;
|
||||||
|
|
||||||
Tile tile = editor.tile(x, y);
|
Tile tile = editor.tile(x, y);
|
||||||
editor.drawBlock = tile.block() == Blocks.air ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block();
|
editor.drawBlock = tile.block() == Blocks.air || !tile.block().inEditor ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
line(KeyCode.l, "replace", "orthogonal"){
|
line(KeyCode.l, "replace", "orthogonal"){
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ import static mindustry.Vars.*;
|
|||||||
public class MapEditor{
|
public class MapEditor{
|
||||||
public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15, 20};
|
public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15, 20};
|
||||||
|
|
||||||
private final Context context = new Context();
|
public StringMap tags = new StringMap();
|
||||||
private StringMap tags = new StringMap();
|
public MapRenderer renderer = new MapRenderer(this);
|
||||||
private MapRenderer renderer = new MapRenderer(this);
|
|
||||||
|
|
||||||
|
private final Context context = new Context();
|
||||||
private OperationStack stack = new OperationStack();
|
private OperationStack stack = new OperationStack();
|
||||||
private DrawOperation currentOp;
|
private DrawOperation currentOp;
|
||||||
private boolean loading;
|
private boolean loading;
|
||||||
@@ -31,8 +31,8 @@ public class MapEditor{
|
|||||||
public Block drawBlock = Blocks.stone;
|
public Block drawBlock = Blocks.stone;
|
||||||
public Team drawTeam = Team.sharded;
|
public Team drawTeam = Team.sharded;
|
||||||
|
|
||||||
public StringMap getTags(){
|
public boolean isLoading(){
|
||||||
return tags;
|
return loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginEdit(int width, int height){
|
public void beginEdit(int width, int height){
|
||||||
@@ -52,7 +52,7 @@ public class MapEditor{
|
|||||||
if(map.file.parent().parent().name().equals("1127400") && steam){
|
if(map.file.parent().parent().name().equals("1127400") && steam){
|
||||||
tags.put("steamid", map.file.parent().name());
|
tags.put("steamid", map.file.parent().name());
|
||||||
}
|
}
|
||||||
MapIO.loadMap(map, context);
|
load(() -> MapIO.loadMap(map, context));
|
||||||
renderer.resize(width(), height());
|
renderer.resize(width(), height());
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
@@ -210,10 +210,6 @@ public class MapEditor{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapRenderer renderer(){
|
|
||||||
return renderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
clearOp();
|
clearOp();
|
||||||
|
|
||||||
@@ -227,8 +223,14 @@ public class MapEditor{
|
|||||||
int px = offsetX + x, py = offsetY + y;
|
int px = offsetX + x, py = offsetY + y;
|
||||||
if(previous.in(px, py)){
|
if(previous.in(px, py)){
|
||||||
tiles.set(x, y, previous.getn(px, py));
|
tiles.set(x, y, previous.getn(px, py));
|
||||||
tiles.getn(x, y).x = (short)x;
|
Tile tile = tiles.getn(x, y);
|
||||||
tiles.getn(x, y).y = (short)y;
|
tile.x = (short)x;
|
||||||
|
tile.y = (short)y;
|
||||||
|
|
||||||
|
if(tile.build != null && tile.isCenter()){
|
||||||
|
tile.build.x = x * tilesize + tile.block().offset;
|
||||||
|
tile.build.y = y * tilesize + tile.block().offset;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
|
tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
t.button("@editor.export", Icon.upload, () -> createDialog("@editor.export",
|
t.button("@editor.export", Icon.upload, () -> createDialog("@editor.export",
|
||||||
"@editor.exportfile", "@editor.exportfile.description", Icon.file,
|
"@editor.exportfile", "@editor.exportfile.description", Icon.file,
|
||||||
(Runnable)() -> platform.export(editor.getTags().get("name", "unknown"), mapExtension, file -> MapIO.writeMap(file, editor.createMap(file))),
|
(Runnable)() -> platform.export(editor.tags.get("name", "unknown"), mapExtension, file -> MapIO.writeMap(file, editor.createMap(file))),
|
||||||
"@editor.exportimage", "@editor.exportimage.description", Icon.fileImage,
|
"@editor.exportimage", "@editor.exportimage.description", Icon.fileImage,
|
||||||
(Runnable)() -> platform.export(editor.getTags().get("name", "unknown"), "png", file -> {
|
(Runnable)() -> platform.export(editor.tags.get("name", "unknown"), "png", file -> {
|
||||||
Pixmap out = MapIO.writeImage(editor.tiles());
|
Pixmap out = MapIO.writeImage(editor.tiles());
|
||||||
file.writePNG(out);
|
file.writePNG(out);
|
||||||
out.dispose();
|
out.dispose();
|
||||||
@@ -129,16 +129,16 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
if(steam){
|
if(steam){
|
||||||
menu.cont.button("@editor.publish.workshop", Icon.link, () -> {
|
menu.cont.button("@editor.publish.workshop", Icon.link, () -> {
|
||||||
Map builtin = maps.all().find(m -> m.name().equals(editor.getTags().get("name", "").trim()));
|
Map builtin = maps.all().find(m -> m.name().equals(editor.tags.get("name", "").trim()));
|
||||||
|
|
||||||
if(editor.getTags().containsKey("steamid") && builtin != null && !builtin.custom){
|
if(editor.tags.containsKey("steamid") && builtin != null && !builtin.custom){
|
||||||
platform.viewListingID(editor.getTags().get("steamid"));
|
platform.viewListingID(editor.tags.get("steamid"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map map = save();
|
Map map = save();
|
||||||
|
|
||||||
if(editor.getTags().containsKey("steamid") && map != null){
|
if(editor.tags.containsKey("steamid") && map != null){
|
||||||
platform.viewListing(map);
|
platform.viewListing(map);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
platform.publish(map);
|
platform.publish(map);
|
||||||
}).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.getTags().containsKey("steamid") ? editor.getTags().get("author").equals(player.name) ? "@workshop.listing" : "@view.workshop" : "@editor.publish.workshop"));
|
}).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.tags.containsKey("steamid") ? editor.tags.get("author").equals(player.name) ? "@workshop.listing" : "@view.workshop" : "@editor.publish.workshop"));
|
||||||
|
|
||||||
menu.cont.row();
|
menu.cont.row();
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
state.rules = (lastSavedRules == null ? new Rules() : lastSavedRules);
|
state.rules = (lastSavedRules == null ? new Rules() : lastSavedRules);
|
||||||
lastSavedRules = null;
|
lastSavedRules = null;
|
||||||
saved = false;
|
saved = false;
|
||||||
editor.renderer().updateAll();
|
editor.renderer.updateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playtest(){
|
private void playtest(){
|
||||||
@@ -264,10 +264,10 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
public @Nullable Map save(){
|
public @Nullable Map save(){
|
||||||
boolean isEditor = state.rules.editor;
|
boolean isEditor = state.rules.editor;
|
||||||
state.rules.editor = false;
|
state.rules.editor = false;
|
||||||
String name = editor.getTags().get("name", "").trim();
|
String name = editor.tags.get("name", "").trim();
|
||||||
editor.getTags().put("rules", JsonIO.write(state.rules));
|
editor.tags.put("rules", JsonIO.write(state.rules));
|
||||||
editor.getTags().remove("width");
|
editor.tags.remove("width");
|
||||||
editor.getTags().remove("height");
|
editor.tags.remove("height");
|
||||||
|
|
||||||
player.clearUnit();
|
player.clearUnit();
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
if(map != null && !map.custom){
|
if(map != null && !map.custom){
|
||||||
handleSaveBuiltin(map);
|
handleSaveBuiltin(map);
|
||||||
}else{
|
}else{
|
||||||
returned = maps.saveMap(editor.getTags());
|
returned = maps.saveMap(editor.tags);
|
||||||
ui.showInfoFade("@editor.saved");
|
ui.showInfoFade("@editor.saved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,7 +352,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(){
|
public void dispose(){
|
||||||
editor.renderer().dispose();
|
editor.renderer.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginEditMap(Fi file){
|
public void beginEditMap(Fi file){
|
||||||
@@ -614,12 +614,12 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
Tile tile = editor.tile(x, y);
|
Tile tile = editor.tile(x, y);
|
||||||
if(tile.block().breakable && tile.block() instanceof Boulder){
|
if(tile.block().breakable && tile.block() instanceof Boulder){
|
||||||
tile.setBlock(Blocks.air);
|
tile.setBlock(Blocks.air);
|
||||||
editor.renderer().updatePoint(x, y);
|
editor.renderer.updatePoint(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tile.overlay() != Blocks.air && tile.overlay() != Blocks.spawn){
|
if(tile.overlay() != Blocks.air && tile.overlay() != Blocks.spawn){
|
||||||
tile.setOverlay(Blocks.air);
|
tile.setOverlay(Blocks.air);
|
||||||
editor.renderer().updatePoint(x, y);
|
editor.renderer.updatePoint(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public class MapGenerateDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//reset undo stack as generation... messes things up
|
//reset undo stack as generation... messes things up
|
||||||
editor.renderer().updateAll();
|
editor.renderer.updateAll();
|
||||||
editor.clearOp();
|
editor.clearOp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class MapInfoDialog extends BaseDialog{
|
|||||||
private void setup(){
|
private void setup(){
|
||||||
cont.clear();
|
cont.clear();
|
||||||
|
|
||||||
ObjectMap<String, String> tags = editor.getTags();
|
ObjectMap<String, String> tags = editor.tags;
|
||||||
|
|
||||||
cont.pane(t -> {
|
cont.pane(t -> {
|
||||||
t.add("@editor.mapname").padRight(8).left();
|
t.add("@editor.mapname").padRight(8).left();
|
||||||
@@ -73,8 +73,8 @@ public class MapInfoDialog extends BaseDialog{
|
|||||||
t.row();
|
t.row();
|
||||||
t.add("@editor.generation").padRight(8).left();
|
t.add("@editor.generation").padRight(8).left();
|
||||||
t.button("@edit", () -> {
|
t.button("@edit", () -> {
|
||||||
generate.show(Vars.maps.readFilters(editor.getTags().get("genfilters", "")),
|
generate.show(Vars.maps.readFilters(editor.tags.get("genfilters", "")),
|
||||||
filters -> editor.getTags().put("genfilters", JsonIO.write(filters)));
|
filters -> editor.tags.put("genfilters", JsonIO.write(filters)));
|
||||||
hide();
|
hide();
|
||||||
}).left().width(200f);
|
}).left().width(200f);
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public class MapRenderer implements Disposable{
|
|||||||
wx * tilesize + wall.offset + (tilesize - width) / 2f,
|
wx * tilesize + wall.offset + (tilesize - width) / 2f,
|
||||||
wy * tilesize + wall.offset + (tilesize - height) / 2f,
|
wy * tilesize + wall.offset + (tilesize - height) / 2f,
|
||||||
width, height,
|
width, height,
|
||||||
tile.build == null || !wall.rotate ? 0 : tile.build.rotdeg() - 90);
|
tile.build == null || !wall.rotate ? 0 : tile.build.rotdeg());
|
||||||
}else{
|
}else{
|
||||||
region = floor.editorVariantRegions()[Mathf.randomSeed(idxWall, 0, floor.editorVariantRegions().length - 1)];
|
region = floor.editorVariantRegions()[Mathf.randomSeed(idxWall, 0, floor.editorVariantRegions().length - 1)];
|
||||||
|
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
Draw.color(Pal.remove);
|
Draw.color(Pal.remove);
|
||||||
Lines.stroke(2f);
|
Lines.stroke(2f);
|
||||||
Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2);
|
Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2);
|
||||||
editor.renderer().draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight);
|
editor.renderer.draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
if(grid){
|
if(grid){
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class Effect{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Effect(float life, Cons<EffectContainer> renderer){
|
public Effect(float life, Cons<EffectContainer> renderer){
|
||||||
this(life, 32f, renderer);
|
this(life,50f, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Effect ground(){
|
public Effect ground(){
|
||||||
@@ -86,12 +86,14 @@ public class Effect{
|
|||||||
create(this, x, y, rotation, Color.white, data);
|
create(this, x, y, rotation, Color.white, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(int id, Color color, float life, float rotation, float x, float y, Object data){
|
public float render(int id, Color color, float life, float lifetime, float rotation, float x, float y, Object data){
|
||||||
container.set(id, color, life, lifetime, rotation, x, y, data);
|
container.set(id, color, life, lifetime, rotation, x, y, data);
|
||||||
Draw.z(ground ? Layer.debris : Layer.effect);
|
Draw.z(ground ? Layer.debris : Layer.effect);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
renderer.get(container);
|
renderer.get(container);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
|
return container.lifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable Effect get(int id){
|
public static @Nullable Effect get(int id){
|
||||||
@@ -125,13 +127,13 @@ public class Effect{
|
|||||||
|
|
||||||
if(view.overlaps(pos)){
|
if(view.overlaps(pos)){
|
||||||
EffectState entity = EffectState.create();
|
EffectState entity = EffectState.create();
|
||||||
entity.effect(effect);
|
entity.effect = effect;
|
||||||
entity.rotation(rotation);
|
entity.rotation = rotation;
|
||||||
entity.data(data);
|
entity.data = (data);
|
||||||
entity.lifetime(effect.lifetime);
|
entity.lifetime = (effect.lifetime);
|
||||||
entity.set(x, y);
|
entity.set(x, y);
|
||||||
entity.color().set(color);
|
entity.color.set(color);
|
||||||
if(data instanceof Posc) entity.parent((Posc)data);
|
if(data instanceof Posc) entity.parent = ((Posc)data);
|
||||||
entity.add();
|
entity.add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.entities;
|
package mindustry.entities;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
@@ -18,6 +19,15 @@ public class Units{
|
|||||||
private static float cdist;
|
private static float cdist;
|
||||||
private static boolean boolResult;
|
private static boolean boolResult;
|
||||||
|
|
||||||
|
@Remote(called = Loc.server)
|
||||||
|
public static void unitCapDeath(Unit unit){
|
||||||
|
if(unit != null){
|
||||||
|
unit.dead = true;
|
||||||
|
Fx.unitCapKill.at(unit);
|
||||||
|
Core.app.post(() -> Call.unitDeath(unit.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server)
|
||||||
public static void unitDeath(int uid){
|
public static void unitDeath(int uid){
|
||||||
Unit unit = Groups.unit.getByID(uid);
|
Unit unit = Groups.unit.getByID(uid);
|
||||||
|
|||||||
@@ -2,7 +2,16 @@ package mindustry.entities.abilities;
|
|||||||
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
public interface Ability{
|
public abstract class Ability implements Cloneable{
|
||||||
default void update(Unit unit){}
|
public void update(Unit unit){}
|
||||||
default void draw(Unit unit){}
|
public void draw(Unit unit){}
|
||||||
|
|
||||||
|
public Ability copy(){
|
||||||
|
try{
|
||||||
|
return (Ability)clone();
|
||||||
|
}catch(CloneNotSupportedException e){
|
||||||
|
//I am disgusted
|
||||||
|
throw new RuntimeException("java sucks", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import mindustry.content.*;
|
|||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
public class ForceFieldAbility implements Ability{
|
public class ForceFieldAbility extends Ability{
|
||||||
/** Shield radius. */
|
/** Shield radius. */
|
||||||
public float radius = 60f;
|
public float radius = 60f;
|
||||||
/** Shield regen speed in damage/tick. */
|
/** Shield regen speed in damage/tick. */
|
||||||
@@ -21,18 +21,22 @@ public class ForceFieldAbility implements Ability{
|
|||||||
/** Cooldown after the shield is broken, in ticks. */
|
/** Cooldown after the shield is broken, in ticks. */
|
||||||
public float cooldown = 60f * 5;
|
public float cooldown = 60f * 5;
|
||||||
|
|
||||||
private float realRad;
|
/** State: radius scaling. */
|
||||||
private Unit paramUnit;
|
protected float radiusScale;
|
||||||
private final Cons<Shielderc> shieldConsumer = trait -> {
|
|
||||||
|
private static float realRad;
|
||||||
|
private static Unit paramUnit;
|
||||||
|
private static ForceFieldAbility paramField;
|
||||||
|
private static final Cons<Shielderc> shieldConsumer = trait -> {
|
||||||
if(trait.team() != paramUnit.team && Intersector.isInsideHexagon(paramUnit.x, paramUnit.y, realRad * 2f, trait.x(), trait.y()) && paramUnit.shield > 0){
|
if(trait.team() != paramUnit.team && Intersector.isInsideHexagon(paramUnit.x, paramUnit.y, realRad * 2f, trait.x(), trait.y()) && paramUnit.shield > 0){
|
||||||
trait.absorb();
|
trait.absorb();
|
||||||
Fx.absorb.at(trait);
|
Fx.absorb.at(trait);
|
||||||
|
|
||||||
//break shield
|
//break shield
|
||||||
if(paramUnit.shield <= trait.damage()){
|
if(paramUnit.shield <= trait.damage()){
|
||||||
paramUnit.shield -= cooldown * regen;
|
paramUnit.shield -= paramField.cooldown * paramField.regen;
|
||||||
|
|
||||||
Fx.shieldBreak.at(paramUnit.x, paramUnit.y, radius, paramUnit.team.color);
|
Fx.shieldBreak.at(paramUnit.x, paramUnit.y, paramField.radius, paramUnit.team.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
paramUnit.shield -= trait.damage();
|
paramUnit.shield -= trait.damage();
|
||||||
@@ -56,13 +60,14 @@ public class ForceFieldAbility implements Ability{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(unit.shield > 0){
|
if(unit.shield > 0){
|
||||||
unit.timer2 = Mathf.lerpDelta(unit.timer2, 1f, 0.06f);
|
radiusScale = Mathf.lerpDelta(radiusScale, 1f, 0.06f);
|
||||||
paramUnit = unit;
|
paramUnit = unit;
|
||||||
|
paramField = this;
|
||||||
checkRadius(unit);
|
checkRadius(unit);
|
||||||
|
|
||||||
Groups.bullet.intersect(unit.x - realRad, unit.y - realRad, realRad * 2f, realRad * 2f, shieldConsumer);
|
Groups.bullet.intersect(unit.x - realRad, unit.y - realRad, realRad * 2f, realRad * 2f, shieldConsumer);
|
||||||
}else{
|
}else{
|
||||||
unit.timer2 = 0f;
|
radiusScale = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +94,6 @@ public class ForceFieldAbility implements Ability{
|
|||||||
|
|
||||||
private void checkRadius(Unit unit){
|
private void checkRadius(Unit unit){
|
||||||
//timer2 is used to store radius scale as an effect
|
//timer2 is used to store radius scale as an effect
|
||||||
realRad = unit.timer2 * radius;
|
realRad = radiusScale * radius;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
public class HealFieldAbility implements Ability{
|
public class HealFieldAbility extends Ability{
|
||||||
public float amount = 1, reload = 100, range = 60;
|
public float amount = 1, reload = 100, range = 60;
|
||||||
public Effect healEffect = Fx.heal;
|
public Effect healEffect = Fx.heal;
|
||||||
public Effect activeEffect = Fx.healWave;
|
public Effect activeEffect = Fx.healWave;
|
||||||
|
|
||||||
private boolean wasHealed = false;
|
protected float timer;
|
||||||
|
protected boolean wasHealed = false;
|
||||||
|
|
||||||
HealFieldAbility(){}
|
HealFieldAbility(){}
|
||||||
|
|
||||||
@@ -22,9 +23,9 @@ public class HealFieldAbility implements Ability{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Unit unit){
|
public void update(Unit unit){
|
||||||
unit.timer1 += Time.delta;
|
timer += Time.delta;
|
||||||
|
|
||||||
if(unit.timer1 >= reload){
|
if(timer >= reload){
|
||||||
wasHealed = false;
|
wasHealed = false;
|
||||||
|
|
||||||
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
|
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
|
||||||
@@ -39,7 +40,7 @@ public class HealFieldAbility implements Ability{
|
|||||||
activeEffect.at(unit);
|
activeEffect.at(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
unit.timer1 = 0f;
|
timer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
public class ShieldFieldAbility implements Ability{
|
public class ShieldFieldAbility extends Ability{
|
||||||
public float amount = 1, max = 100f, reload = 100, range = 60;
|
public float amount = 1, max = 100f, reload = 100, range = 60;
|
||||||
public Effect applyEffect = Fx.shieldApply;
|
public Effect applyEffect = Fx.shieldApply;
|
||||||
public Effect activeEffect = Fx.shieldWave;
|
public Effect activeEffect = Fx.shieldWave;
|
||||||
|
|
||||||
private boolean applied = false;
|
protected float timer;
|
||||||
|
protected boolean applied = false;
|
||||||
|
|
||||||
ShieldFieldAbility(){}
|
ShieldFieldAbility(){}
|
||||||
|
|
||||||
@@ -23,9 +24,9 @@ public class ShieldFieldAbility implements Ability{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Unit unit){
|
public void update(Unit unit){
|
||||||
unit.timer1 += Time.delta;
|
timer += Time.delta;
|
||||||
|
|
||||||
if(unit.timer1 >= reload){
|
if(timer >= reload){
|
||||||
applied = false;
|
applied = false;
|
||||||
|
|
||||||
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
|
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
|
||||||
@@ -41,7 +42,7 @@ public class ShieldFieldAbility implements Ability{
|
|||||||
activeEffect.at(unit);
|
activeEffect.at(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
unit.timer1 = 0f;
|
timer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ import mindustry.entities.*;
|
|||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
public class StatusFieldAbility implements Ability{
|
public class StatusFieldAbility extends Ability{
|
||||||
public @NonNull StatusEffect effect;
|
public @NonNull StatusEffect effect;
|
||||||
public float duration = 60, reload = 100, range = 20;
|
public float duration = 60, reload = 100, range = 20;
|
||||||
public Effect applyEffect = Fx.heal;
|
public Effect applyEffect = Fx.heal;
|
||||||
public Effect activeEffect = Fx.overdriveWave;
|
public Effect activeEffect = Fx.overdriveWave;
|
||||||
|
|
||||||
|
protected float timer;
|
||||||
|
|
||||||
StatusFieldAbility(){}
|
StatusFieldAbility(){}
|
||||||
|
|
||||||
public StatusFieldAbility(@NonNull StatusEffect effect, float duration, float reload, float range){
|
public StatusFieldAbility(@NonNull StatusEffect effect, float duration, float reload, float range){
|
||||||
@@ -24,9 +26,9 @@ public class StatusFieldAbility implements Ability{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Unit unit){
|
public void update(Unit unit){
|
||||||
unit.timer2 += Time.delta;
|
timer += Time.delta;
|
||||||
|
|
||||||
if(unit.timer2 >= reload){
|
if(timer >= reload){
|
||||||
|
|
||||||
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
|
Units.nearby(unit.team, unit.x, unit.y, range, other -> {
|
||||||
other.apply(effect, duration);
|
other.apply(effect, duration);
|
||||||
@@ -34,7 +36,7 @@ public class StatusFieldAbility implements Ability{
|
|||||||
|
|
||||||
activeEffect.at(unit);
|
activeEffect.at(unit);
|
||||||
|
|
||||||
unit.timer2 = 0f;
|
timer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package mindustry.entities.abilities;
|
||||||
|
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
|
|
||||||
|
public class UnitSpawnAbility extends Ability{
|
||||||
|
public @NonNull UnitType type;
|
||||||
|
public float spawnTime = 60f, spawnX, spawnY;
|
||||||
|
public Effect spawnEffect = Fx.spawn;
|
||||||
|
|
||||||
|
protected float timer;
|
||||||
|
|
||||||
|
public UnitSpawnAbility(@NonNull UnitType type, float spawnTime, float spawnX, float spawnY){
|
||||||
|
this.type = type;
|
||||||
|
this.spawnTime = spawnTime;
|
||||||
|
this.spawnX = spawnX;
|
||||||
|
this.spawnY = spawnY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitSpawnAbility(){
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Unit unit){
|
||||||
|
timer += Time.delta;
|
||||||
|
|
||||||
|
if(timer >= spawnTime && Units.canCreate(unit.team, type)){
|
||||||
|
|
||||||
|
float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX);
|
||||||
|
spawnEffect.at(x, y);
|
||||||
|
Unit u = type.create(unit.team);
|
||||||
|
u.set(x, y);
|
||||||
|
u.rotation = unit.rotation;
|
||||||
|
if(!Vars.net.client()){
|
||||||
|
u.add();
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Unit unit){
|
||||||
|
if(Units.canCreate(unit.team, type)){
|
||||||
|
Draw.draw(Draw.z(), () -> {
|
||||||
|
float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX);
|
||||||
|
Drawf.construct(x, y, type.icon(Cicon.full), unit.rotation - 90, timer / spawnTime, 1f, timer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
package mindustry.entities.bullet;
|
package mindustry.entities.bullet;
|
||||||
|
|
||||||
import arc.Core;
|
import arc.*;
|
||||||
import arc.graphics.Color;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.Draw;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g2d.TextureRegion;
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
/** An extended BulletType for most ammo-based bullets shot from turrets and units. */
|
/** An extended BulletType for most ammo-based bullets shot from turrets and units. */
|
||||||
public class BasicBulletType extends BulletType{
|
public class BasicBulletType extends BulletType{
|
||||||
public Color backColor = Pal.bulletYellowBack, frontColor = Pal.bulletYellow;
|
public Color backColor = Pal.bulletYellowBack, frontColor = Pal.bulletYellow;
|
||||||
|
public Color mixColorFrom = new Color(1f, 1f, 1f, 0f), mixColorTo = new Color(1f, 1f, 1f, 0f);
|
||||||
public float width = 5f, height = 7f;
|
public float width = 5f, height = 7f;
|
||||||
public float shrinkX = 0f, shrinkY = 0.5f;
|
public float shrinkX = 0f, shrinkY = 0.5f;
|
||||||
public float spin = 0;
|
public float spin = 0;
|
||||||
@@ -45,10 +46,15 @@ public class BasicBulletType extends BulletType{
|
|||||||
float width = this.width * ((1f - shrinkX) + shrinkX * b.fout());
|
float width = this.width * ((1f - shrinkX) + shrinkX * b.fout());
|
||||||
float offset = -90 + (spin != 0 ? Mathf.randomSeed(b.id, 360f) + b.time * spin : 0f);
|
float offset = -90 + (spin != 0 ? Mathf.randomSeed(b.id, 360f) + b.time * spin : 0f);
|
||||||
|
|
||||||
|
Color mix = Tmp.c1.set(mixColorFrom).lerp(mixColorTo, b.fin());
|
||||||
|
|
||||||
|
Draw.mixcol(mix, mix.a);
|
||||||
|
|
||||||
Draw.color(backColor);
|
Draw.color(backColor);
|
||||||
Draw.rect(backRegion, b.x, b.y, width, height, b.rotation() + offset);
|
Draw.rect(backRegion, b.x, b.y, width, height, b.rotation() + offset);
|
||||||
Draw.color(frontColor);
|
Draw.color(frontColor);
|
||||||
Draw.rect(frontRegion, b.x, b.y, width, height, b.rotation() + offset);
|
Draw.rect(frontRegion, b.x, b.y, width, height, b.rotation() + offset);
|
||||||
Draw.color();
|
|
||||||
|
Draw.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public abstract class BulletType extends Content{
|
|||||||
public float hitSize = 4;
|
public float hitSize = 4;
|
||||||
public float drawSize = 40f;
|
public float drawSize = 40f;
|
||||||
public float drag = 0f;
|
public float drag = 0f;
|
||||||
public boolean pierce;
|
public boolean pierce, pierceBuilding;
|
||||||
public Effect hitEffect, despawnEffect;
|
public Effect hitEffect, despawnEffect;
|
||||||
|
|
||||||
/** Effect created when shooting. */
|
/** Effect created when shooting. */
|
||||||
@@ -69,6 +69,8 @@ public abstract class BulletType extends Content{
|
|||||||
public boolean scaleVelocity;
|
public boolean scaleVelocity;
|
||||||
/** Whether this bullet can be hit by point defense. */
|
/** Whether this bullet can be hit by point defense. */
|
||||||
public boolean hittable = true;
|
public boolean hittable = true;
|
||||||
|
/** Whether this bullet can be reflected. */
|
||||||
|
public boolean reflectable = true;
|
||||||
|
|
||||||
//additional effects
|
//additional effects
|
||||||
|
|
||||||
@@ -100,7 +102,7 @@ public abstract class BulletType extends Content{
|
|||||||
|
|
||||||
public float weaveScale = 1f;
|
public float weaveScale = 1f;
|
||||||
public float weaveMag = -1f;
|
public float weaveMag = -1f;
|
||||||
public float hitShake = 0f;
|
public float hitShake = 0f, despawnShake = 0f;
|
||||||
|
|
||||||
public int puddles;
|
public int puddles;
|
||||||
public float puddleRange;
|
public float puddleRange;
|
||||||
@@ -131,10 +133,14 @@ public abstract class BulletType extends Content{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hitTile(Bullet b, Building tile){
|
public void hitTile(Bullet b, Building tile, float initialHealth){
|
||||||
hit(b);
|
hit(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void hitEntity(Bullet b, Hitboxc other, float initialHealth){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void hit(Bullet b){
|
public void hit(Bullet b){
|
||||||
hit(b, b.x, b.y);
|
hit(b, b.x, b.y);
|
||||||
}
|
}
|
||||||
@@ -181,6 +187,8 @@ public abstract class BulletType extends Content{
|
|||||||
despawnEffect.at(b.x, b.y, b.rotation(), hitColor);
|
despawnEffect.at(b.x, b.y, b.rotation(), hitColor);
|
||||||
hitSound.at(b);
|
hitSound.at(b);
|
||||||
|
|
||||||
|
Effect.shake(despawnShake, despawnShake, b);
|
||||||
|
|
||||||
if(fragBullet != null || splashDamageRadius > 0 || lightning > 0){
|
if(fragBullet != null || splashDamageRadius > 0 || lightning > 0){
|
||||||
hit(b);
|
hit(b);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class HealBulletType extends BulletType{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hitTile(Bullet b, Building tile){
|
public void hitTile(Bullet b, Building tile, float initialHealth){
|
||||||
super.hit(b);
|
super.hit(b);
|
||||||
|
|
||||||
if(tile.team == b.team && !(tile.block instanceof ConstructBlock)){
|
if(tile.team == b.team && !(tile.block instanceof ConstructBlock)){
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package mindustry.entities.bullet;
|
||||||
|
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
public class RailBulletType extends BulletType{
|
||||||
|
public Effect pierceEffect = Fx.hitBulletSmall, updateEffect = Fx.none;
|
||||||
|
/** Multiplier of damage decreased per health pierced. */
|
||||||
|
public float pierceDamageFactor = 1f;
|
||||||
|
|
||||||
|
public RailBulletType(){
|
||||||
|
pierceBuilding = true;
|
||||||
|
pierce = true;
|
||||||
|
reflectable = false;
|
||||||
|
hitEffect = Fx.none;
|
||||||
|
despawnEffect = Fx.none;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle(Bullet b, Posc pos, float initialHealth){
|
||||||
|
float sub = initialHealth*pierceDamageFactor;
|
||||||
|
|
||||||
|
if(sub >= b.damage){
|
||||||
|
//cause a despawn
|
||||||
|
b.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
//subtract health from each consecutive pierce
|
||||||
|
b.damage -= Math.min(b.damage, sub);
|
||||||
|
|
||||||
|
if(b.damage > 0){
|
||||||
|
pierceEffect.at(pos.getX(), pos.getY(), b.rotation());
|
||||||
|
}
|
||||||
|
|
||||||
|
hitEffect.at(pos.getX(), pos.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Bullet b){
|
||||||
|
updateEffect.at(b.x, b.y, b.rotation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hitEntity(Bullet b, Hitboxc entity, float initialHealth){
|
||||||
|
handle(b, entity, initialHealth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hitTile(Bullet b, Building tile, float initialHealth){
|
||||||
|
handle(b, tile, initialHealth);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,10 +39,15 @@ public class SapBulletType extends BulletType{
|
|||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
Drawf.light(b.team, b.x, b.y, b.x + Tmp.v1.x, b.y + Tmp.v1.y, 15f * b.fout(), lightColor, 0.6f);
|
Drawf.light(b.team, b.x, b.y, Tmp.v1.x, Tmp.v1.y, 15f * b.fout(), lightColor, 0.6f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawLight(Bullet b){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float range(){
|
public float range(){
|
||||||
return length;
|
return length;
|
||||||
|
|||||||
@@ -108,9 +108,9 @@ abstract class BuilderComp implements Unitc{
|
|||||||
ConstructBuild entity = tile.bc();
|
ConstructBuild entity = tile.bc();
|
||||||
|
|
||||||
if(current.breaking){
|
if(current.breaking){
|
||||||
entity.deconstruct(base(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier);
|
entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier);
|
||||||
}else{
|
}else{
|
||||||
entity.construct(base(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier, current.config);
|
entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier, current.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
current.stuck = Mathf.equal(current.progress, entity.progress);
|
current.stuck = Mathf.equal(current.progress, entity.progress);
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
if(block.hasPower){
|
if(block.hasPower){
|
||||||
//reinit power graph
|
//reinit power graph
|
||||||
power.graph = new PowerGraph();
|
power.graph = new PowerGraph();
|
||||||
power.graph.add(base());
|
power.graph.add(self());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
@@ -94,7 +94,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
created();
|
created();
|
||||||
|
|
||||||
return base();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets up all the necessary variables, but does not add this entity anywhere. */
|
/** Sets up all the necessary variables, but does not add this entity anywhere. */
|
||||||
@@ -111,17 +111,17 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
maxHealth(block.health);
|
maxHealth(block.health);
|
||||||
timer(new Interval(block.timers));
|
timer(new Interval(block.timers));
|
||||||
|
|
||||||
cons = new ConsumeModule(base());
|
cons = new ConsumeModule(self());
|
||||||
if(block.hasItems) items = new ItemModule();
|
if(block.hasItems) items = new ItemModule();
|
||||||
if(block.hasLiquids) liquids = new LiquidModule();
|
if(block.hasLiquids) liquids = new LiquidModule();
|
||||||
if(block.hasPower){
|
if(block.hasPower){
|
||||||
power = new PowerModule();
|
power = new PowerModule();
|
||||||
power.graph.add(base());
|
power.graph.add(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
return base();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -195,17 +195,17 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
public void configure(Object value){
|
public void configure(Object value){
|
||||||
//save last used config
|
//save last used config
|
||||||
block.lastConfig = value;
|
block.lastConfig = value;
|
||||||
Call.tileConfig(player, base(), value);
|
Call.tileConfig(player, self(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Configure from a server. */
|
/** Configure from a server. */
|
||||||
public void configureAny(Object value){
|
public void configureAny(Object value){
|
||||||
Call.tileConfig(null, base(), value);
|
Call.tileConfig(null, self(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Deselect this tile from configuration. */
|
/** Deselect this tile from configuration. */
|
||||||
public void deselect(){
|
public void deselect(){
|
||||||
if(!headless && control.input.frag.config.getSelectedTile() == base()){
|
if(!headless && control.input.frag.config.getSelectedTile() == self()){
|
||||||
control.input.frag.config.hideConfig();
|
control.input.frag.config.hideConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
/** Returns the amount of items this block can accept. */
|
/** Returns the amount of items this block can accept. */
|
||||||
public int acceptStack(Item item, int amount, Teamc source){
|
public int acceptStack(Item item, int amount, Teamc source){
|
||||||
if(acceptItem(base(), item) && block.hasItems && (source == null || source.team() == team)){
|
if(acceptItem(self(), item) && block.hasItems && (source == null || source.team() == team)){
|
||||||
return Math.min(getMaximumAccepted(item) - items.get(item), amount);
|
return Math.min(getMaximumAccepted(item) - items.get(item), amount);
|
||||||
}else{
|
}else{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -425,8 +425,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
int trns = block.size/2 + 1;
|
int trns = block.size/2 + 1;
|
||||||
Tile next = tile.getNearby(Geometry.d4(rotation).x * trns, Geometry.d4(rotation).y * trns);
|
Tile next = tile.getNearby(Geometry.d4(rotation).x * trns, Geometry.d4(rotation).y * trns);
|
||||||
|
|
||||||
if(next != null && next.build != null && next.build.team == team && next.build.acceptPayload(base(), todump)){
|
if(next != null && next.build != null && next.build.team == team && next.build.acceptPayload(self(), todump)){
|
||||||
next.build.handlePayload(base(), todump);
|
next.build.handlePayload(self(), todump);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,8 +446,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
Building other = proximity.get((i + dump) % proximity.size);
|
Building other = proximity.get((i + dump) % proximity.size);
|
||||||
|
|
||||||
if(other.team == team && other.acceptPayload(base(), todump)){
|
if(other.team == team && other.acceptPayload(self(), todump)){
|
||||||
other.handlePayload(base(), todump);
|
other.handlePayload(self(), todump);
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -480,7 +480,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
Building other = proximity.get((i + dump) % proximity.size);
|
Building other = proximity.get((i + dump) % proximity.size);
|
||||||
other = other.getLiquidDestination(base(), liquid);
|
other = other.getLiquidDestination(self(), liquid);
|
||||||
|
|
||||||
if(other != null && other.team == team && other.block.hasLiquids && canDumpLiquid(other, liquid) && other.liquids != null){
|
if(other != null && other.team == team && other.block.hasLiquids && canDumpLiquid(other, liquid) && other.liquids != null){
|
||||||
float ofract = other.liquids.get(liquid) / other.block.liquidCapacity;
|
float ofract = other.liquids.get(liquid) / other.block.liquidCapacity;
|
||||||
@@ -499,8 +499,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
public void transferLiquid(Building next, float amount, Liquid liquid){
|
public void transferLiquid(Building next, float amount, Liquid liquid){
|
||||||
float flow = Math.min(next.block.liquidCapacity - next.liquids.get(liquid) - 0.001f, amount);
|
float flow = Math.min(next.block.liquidCapacity - next.liquids.get(liquid) - 0.001f, amount);
|
||||||
|
|
||||||
if(next.acceptLiquid(base(), liquid, flow)){
|
if(next.acceptLiquid(self(), liquid, flow)){
|
||||||
next.handleLiquid(base(), liquid, flow);
|
next.handleLiquid(self(), liquid, flow);
|
||||||
liquids.remove(liquid, flow);
|
liquids.remove(liquid, flow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,7 +523,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
public float moveLiquid(Building next, Liquid liquid){
|
public float moveLiquid(Building next, Liquid liquid){
|
||||||
if(next == null) return 0;
|
if(next == null) return 0;
|
||||||
|
|
||||||
next = next.getLiquidDestination(base(), liquid);
|
next = next.getLiquidDestination(self(), liquid);
|
||||||
|
|
||||||
if(next.team == team && next.block.hasLiquids && liquids.get(liquid) > 0f){
|
if(next.team == team && next.block.hasLiquids && liquids.get(liquid) > 0f){
|
||||||
float ofract = next.liquids.get(liquid) / next.block.liquidCapacity;
|
float ofract = next.liquids.get(liquid) / next.block.liquidCapacity;
|
||||||
@@ -531,8 +531,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
float flow = Math.min(Mathf.clamp((fract - ofract) * (1f)) * (block.liquidCapacity), liquids.get(liquid));
|
float flow = Math.min(Mathf.clamp((fract - ofract) * (1f)) * (block.liquidCapacity), liquids.get(liquid));
|
||||||
flow = Math.min(flow, next.block.liquidCapacity - next.liquids.get(liquid) - 0.001f);
|
flow = Math.min(flow, next.block.liquidCapacity - next.liquids.get(liquid) - 0.001f);
|
||||||
|
|
||||||
if(flow > 0f && ofract <= fract && next.acceptLiquid(base(), liquid, flow)){
|
if(flow > 0f && ofract <= fract && next.acceptLiquid(self(), liquid, flow)){
|
||||||
next.handleLiquid(base(), liquid, flow);
|
next.handleLiquid(self(), liquid, flow);
|
||||||
liquids.remove(liquid, flow);
|
liquids.remove(liquid, flow);
|
||||||
return flow;
|
return flow;
|
||||||
}else if(next.liquids.currentAmount() / next.block.liquidCapacity > 0.1f && fract > 0.1f){
|
}else if(next.liquids.currentAmount() / next.block.liquidCapacity > 0.1f && fract > 0.1f){
|
||||||
@@ -558,7 +558,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Building getLiquidDestination(Building from, Liquid liquid){
|
public Building getLiquidDestination(Building from, Liquid liquid){
|
||||||
return base();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Payload getPayload(){
|
public @Nullable Payload getPayload(){
|
||||||
@@ -580,13 +580,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
Building other = proximity.get((i + dump) % proximity.size);
|
Building other = proximity.get((i + dump) % proximity.size);
|
||||||
if(other.team == team && other.acceptItem(base(), item) && canDump(other, item)){
|
if(other.team == team && other.acceptItem(self(), item) && canDump(other, item)){
|
||||||
other.handleItem(base(), item);
|
other.handleItem(self(), item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleItem(base(), item);
|
handleItem(self(), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -598,8 +598,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
Building other = proximity.get((i + dump) % proximity.size);
|
Building other = proximity.get((i + dump) % proximity.size);
|
||||||
if(other.team == team && other.acceptItem(base(), item) && canDump(other, item)){
|
if(other.team == team && other.acceptItem(self(), item) && canDump(other, item)){
|
||||||
other.handleItem(base(), item);
|
other.handleItem(self(), item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -631,16 +631,16 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
for(int ii = 0; ii < content.items().size; ii++){
|
for(int ii = 0; ii < content.items().size; ii++){
|
||||||
Item item = content.item(ii);
|
Item item = content.item(ii);
|
||||||
|
|
||||||
if(other.team == team && items.has(item) && other.acceptItem(base(), item) && canDump(other, item)){
|
if(other.team == team && items.has(item) && other.acceptItem(self(), item) && canDump(other, item)){
|
||||||
other.handleItem(base(), item);
|
other.handleItem(self(), item);
|
||||||
items.remove(item, 1);
|
items.remove(item, 1);
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(other.team == team && other.acceptItem(base(), todump) && canDump(other, todump)){
|
if(other.team == team && other.acceptItem(self(), todump) && canDump(other, todump)){
|
||||||
other.handleItem(base(), todump);
|
other.handleItem(self(), todump);
|
||||||
items.remove(todump, 1);
|
items.remove(todump, 1);
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
return true;
|
return true;
|
||||||
@@ -665,8 +665,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
/** Try offloading an item to a nearby container in its facing direction. Returns true if success. */
|
/** Try offloading an item to a nearby container in its facing direction. Returns true if success. */
|
||||||
public boolean moveForward(Item item){
|
public boolean moveForward(Item item){
|
||||||
Building other = front();
|
Building other = front();
|
||||||
if(other != null && other.team == team && other.acceptItem(base(), item)){
|
if(other != null && other.team == team && other.acceptItem(self(), item)){
|
||||||
other.handleItem(base(), item);
|
other.handleItem(self(), item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -696,7 +696,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
power.graph.remove(base());
|
power.graph.remove(self());
|
||||||
for(int i = 0; i < power.links.size; i++){
|
for(int i = 0; i < power.links.size; i++){
|
||||||
Tile other = world.tile(power.links.get(i));
|
Tile other = world.tile(power.links.get(i));
|
||||||
if(other != null && other.build != null && other.build.power != null){
|
if(other != null && other.build != null && other.build.power != null){
|
||||||
@@ -833,8 +833,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
tempTiles.clear();
|
tempTiles.clear();
|
||||||
Geometry.circle(tileX(), tileY(), range, (x, y) -> {
|
Geometry.circle(tileX(), tileY(), range, (x, y) -> {
|
||||||
Building other = world.build(x, y);
|
Building other = world.build(x, y);
|
||||||
if(other != null && other.block instanceof PowerNode && ((PowerNode)other.block).linkValid(other, base()) && !PowerNode.insulated(other, base())
|
if(other != null && other.block instanceof PowerNode && ((PowerNode)other.block).linkValid(other, self()) && !PowerNode.insulated(other, self())
|
||||||
&& !other.proximity().contains(this.<Building>base()) &&
|
&& !other.proximity().contains(this.<Building>self()) &&
|
||||||
!(block.outputsPower && proximity.contains(p -> p.power != null && p.power.graph == other.power.graph))){
|
!(block.outputsPower && proximity.contains(p -> p.power != null && p.power.graph == other.power.graph))){
|
||||||
tempTiles.add(other.tile);
|
tempTiles.add(other.tile);
|
||||||
}
|
}
|
||||||
@@ -1037,13 +1037,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
table.left();
|
table.left();
|
||||||
for(Consume cons : block.consumes.all()){
|
for(Consume cons : block.consumes.all()){
|
||||||
if(cons.isOptional() && cons.isBoost()) continue;
|
if(cons.isOptional() && cons.isBoost()) continue;
|
||||||
cons.build(base(), table);
|
cons.build(self(), table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayBars(Table table){
|
public void displayBars(Table table){
|
||||||
for(Func<Building, Bar> bar : block.bars.list()){
|
for(Func<Building, Bar> bar : block.bars.list()){
|
||||||
table.add(bar.get(base())).growX();
|
table.add(bar.get(self())).growX();
|
||||||
table.row();
|
table.row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1069,7 +1069,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
* @return whether or not this block should be deselected.
|
* @return whether or not this block should be deselected.
|
||||||
*/
|
*/
|
||||||
public boolean onConfigureTileTapped(Building other){
|
public boolean onConfigureTileTapped(Building other){
|
||||||
return base() != other;
|
return self() != other;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether this config menu should show when the specified player taps it. */
|
/** Returns whether this config menu should show when the specified player taps it. */
|
||||||
@@ -1128,7 +1128,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(Building other : tmpTiles){
|
for(Building other : tmpTiles){
|
||||||
other.proximity.remove(base(), true);
|
other.proximity.remove(self(), true);
|
||||||
other.onProximityUpdate();
|
other.onProximityUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1144,8 +1144,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
if(other == null || !(other.tile.interactable(team))) continue;
|
if(other == null || !(other.tile.interactable(team))) continue;
|
||||||
|
|
||||||
//add this tile to proximity of nearby tiles
|
//add this tile to proximity of nearby tiles
|
||||||
if(!other.proximity.contains(base(), true)){
|
if(!other.proximity.contains(self(), true)){
|
||||||
other.proximity.add(base());
|
other.proximity.add(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpTiles.add(other);
|
tmpTiles.add(other);
|
||||||
@@ -1184,13 +1184,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
@Replace
|
@Replace
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(){
|
public boolean isValid(){
|
||||||
return tile.build == base() && !dead();
|
return tile.build == self() && !dead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
@Override
|
@Override
|
||||||
public void kill(){
|
public void kill(){
|
||||||
Call.tileDestroyed(base());
|
Call.tileDestroyed(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
@@ -1204,10 +1204,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
damage /= state.rules.blockHealthMultiplier;
|
damage /= state.rules.blockHealthMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
Call.tileDamage(base(), health - handleDamage(damage));
|
Call.tileDamage(self(), health - handleDamage(damage));
|
||||||
|
|
||||||
if(health <= 0){
|
if(health <= 0){
|
||||||
Call.tileDestroyed(base());
|
Call.tileDestroyed(self());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1292,7 +1292,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(block.idleSound != Sounds.none && shouldIdleSound()){
|
if(block.idleSound != Sounds.none && shouldIdleSound()){
|
||||||
loops.play(block.idleSound, base(), block.idleSoundVolume);
|
loops.play(block.idleSound, self(), block.idleSoundVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enabled || !block.noUpdateDisabled){
|
if(enabled || !block.noUpdateDisabled){
|
||||||
|
|||||||
@@ -44,17 +44,17 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawBullets(){
|
public void drawBullets(){
|
||||||
type.draw(base());
|
type.draw(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(){
|
public void add(){
|
||||||
type.init(base());
|
type.init(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(){
|
public void remove(){
|
||||||
type.despawned(base());
|
type.despawned(self());
|
||||||
collided.clear();
|
collided.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,10 +92,12 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
@MethodPriority(100)
|
@MethodPriority(100)
|
||||||
@Override
|
@Override
|
||||||
public void collision(Hitboxc other, float x, float y){
|
public void collision(Hitboxc other, float x, float y){
|
||||||
type.hit(base(), x, y);
|
type.hit(self(), x, y);
|
||||||
|
float health = 0f;
|
||||||
|
|
||||||
if(other instanceof Healthc){
|
if(other instanceof Healthc){
|
||||||
Healthc h = (Healthc)other;
|
Healthc h = (Healthc)other;
|
||||||
|
health = h.health();
|
||||||
h.damage(damage);
|
h.damage(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,30 +113,40 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
}else{
|
}else{
|
||||||
collided.add(other.id());
|
collided.add(other.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type.hitEntity(self(), other, health);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
type.update(base());
|
type.update(self());
|
||||||
|
|
||||||
if(type.collidesTiles && type.collides && type.collidesGround){
|
if(type.collidesTiles && type.collides && type.collidesGround){
|
||||||
world.raycastEach(world.toTile(lastX()), world.toTile(lastY()), tileX(), tileY(), (x, y) -> {
|
world.raycastEach(world.toTile(lastX()), world.toTile(lastY()), tileX(), tileY(), (x, y) -> {
|
||||||
|
|
||||||
Building tile = world.build(x, y);
|
Building tile = world.build(x, y);
|
||||||
if(tile == null) return false;
|
if(tile == null || !isAdded()) return false;
|
||||||
|
|
||||||
if(tile.collide(base()) && type.collides(base(), tile) && !tile.dead() && (type.collidesTeam || tile.team != team)){
|
if(tile.collide(self()) && type.collides(self(), tile) && !tile.dead() && (type.collidesTeam || tile.team != team) && !(type.pierceBuilding && collided.contains(tile.id))){
|
||||||
boolean remove = false;
|
boolean remove = false;
|
||||||
|
|
||||||
|
float health = tile.health;
|
||||||
|
|
||||||
if(tile.team != team){
|
if(tile.team != team){
|
||||||
remove = tile.collision(base());
|
remove = tile.collision(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(remove || type.collidesTeam){
|
if(remove || type.collidesTeam){
|
||||||
type.hitTile(base(), tile);
|
if(!type.pierceBuilding){
|
||||||
remove();
|
remove();
|
||||||
|
}else{
|
||||||
|
collided.add(tile.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
type.hitTile(self(), tile, health);
|
||||||
|
|
||||||
|
return !type.pierceBuilding;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -146,8 +158,8 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
public void draw(){
|
public void draw(){
|
||||||
Draw.z(Layer.bullet);
|
Draw.z(Layer.bullet);
|
||||||
|
|
||||||
type.draw(base());
|
type.draw(self());
|
||||||
type.drawLight(base());
|
type.drawLight(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the bullet's rotation in degrees. */
|
/** Sets the bullet's rotation in degrees. */
|
||||||
|
|||||||