Compare commits
147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24195dac81 | ||
|
|
830fe03898 | ||
|
|
4690aae197 | ||
|
|
b82dca89b3 | ||
|
|
dce79a621a | ||
|
|
d6f00a5d2d | ||
|
|
545b75a091 | ||
|
|
979daca221 | ||
|
|
fb2fed7c28 | ||
|
|
0ec71750b7 | ||
|
|
51f7858b78 | ||
|
|
ab83b872a2 | ||
|
|
879adb7458 | ||
|
|
39cbd607ef | ||
|
|
7478cdf4a4 | ||
|
|
b75a8d5260 | ||
|
|
120c694a42 | ||
|
|
569293e577 | ||
|
|
4f0f2499be | ||
|
|
d34dd0c603 | ||
|
|
b6c645b701 | ||
|
|
0c28bb7dcf | ||
|
|
2bb303e709 | ||
|
|
cc65feb392 | ||
|
|
c12b9ee3e3 | ||
|
|
d863c971c2 | ||
|
|
3ccdf45ed1 | ||
|
|
efa5c5db7b | ||
|
|
d73cf9fcff | ||
|
|
93dafc82eb | ||
|
|
87142b06c3 | ||
|
|
3075616b03 | ||
|
|
019898dfc3 | ||
|
|
ae838b9392 | ||
|
|
4d9a30b7c7 | ||
|
|
ea82773157 | ||
|
|
8289da1415 | ||
|
|
19eb6334b7 | ||
|
|
e992be1bfb | ||
|
|
7e216d198e | ||
|
|
a89d50e74d | ||
|
|
05dc13c922 | ||
|
|
1de4dd1bfe | ||
|
|
72aa87128e | ||
|
|
8f91576f85 | ||
|
|
4019c49fff | ||
|
|
5f83c92829 | ||
|
|
4c9cda7e40 | ||
|
|
01f7b1c9a6 | ||
|
|
1a30edc55f | ||
|
|
49bccffd7c | ||
|
|
526157a514 | ||
|
|
d025ba63e1 | ||
|
|
662515ce2e | ||
|
|
c55ff4ad5e | ||
|
|
666c0f3582 | ||
|
|
0c00760ae0 | ||
|
|
2146b35e5a | ||
|
|
44d10a355e | ||
|
|
5037c4e00e | ||
|
|
e4ecfc4ee7 | ||
|
|
ae6be1db3b | ||
|
|
d06eee99ba | ||
|
|
8349c8a5b8 | ||
|
|
2df7484649 | ||
|
|
1bb97cae39 | ||
|
|
f5ac3ff7b0 | ||
|
|
f6eba3edae | ||
|
|
781410ea04 | ||
|
|
c0d9712beb | ||
|
|
0672878920 | ||
|
|
b0cdac59f0 | ||
|
|
4b6a83dd82 | ||
|
|
25ae7b97aa | ||
|
|
afbde49fa2 | ||
|
|
befda9baaa | ||
|
|
502c7eb388 | ||
|
|
ad2a18f929 | ||
|
|
830eb86a0f | ||
|
|
e5413cebdc | ||
|
|
1a75951840 | ||
|
|
08e36aca98 | ||
|
|
aabbfd624a | ||
|
|
2f836d779a | ||
|
|
d7f848f8cd | ||
|
|
6f7f980563 | ||
|
|
e2515fc4bf | ||
|
|
d06a7bb7a2 | ||
|
|
dbdfdac94b | ||
|
|
3b2a0cfd66 | ||
|
|
5b652ae51f | ||
|
|
9e8a2b8296 | ||
|
|
e6787c5146 | ||
|
|
d8552915f7 | ||
|
|
61d9dea487 | ||
|
|
02d8f679b5 | ||
|
|
544828d9fb | ||
|
|
ca726d579e | ||
|
|
8257fb5e11 | ||
|
|
0d287e6d59 | ||
|
|
4d9dc66a96 | ||
|
|
868d4e05f7 | ||
|
|
a3bf39d86b | ||
|
|
d76795e0ae | ||
|
|
a2e075ee54 | ||
|
|
2df2a0971a | ||
|
|
158e23bd5e | ||
|
|
467402ef73 | ||
|
|
f78719afc0 | ||
|
|
e6513702d6 | ||
|
|
aeddf7014c | ||
|
|
1613f49c16 | ||
|
|
57a833c2fb | ||
|
|
6de53343a4 | ||
|
|
7bb4b09308 | ||
|
|
68020fa7d4 | ||
|
|
b94aba0301 | ||
|
|
0316009a9c | ||
|
|
820f7f0ef2 | ||
|
|
6d105ad3e7 | ||
|
|
f043a5f340 | ||
|
|
73d6f95d2e | ||
|
|
fb48070388 | ||
|
|
fa7697fc40 | ||
|
|
b46a5c0bda | ||
|
|
1072c310ad | ||
|
|
d5448b59a2 | ||
|
|
78317e6126 | ||
|
|
5a58f9c71a | ||
|
|
06b8dd61c7 | ||
|
|
a81b5778a0 | ||
|
|
a7188c4884 | ||
|
|
0bf0d48a02 | ||
|
|
dc5cd196ed | ||
|
|
f8f9bf228b | ||
|
|
d0dc1ea132 | ||
|
|
ff9fad6a2c | ||
|
|
76dbdb59ce | ||
|
|
0013402962 | ||
|
|
1ef7ae7079 | ||
|
|
07a39d0da8 | ||
|
|
b8bfb30c56 | ||
|
|
00342ddaae | ||
|
|
fb40c0b9de | ||
|
|
5d9506eb12 | ||
|
|
080fe8c3c4 | ||
|
|
48745d7380 |
@@ -1,7 +1,7 @@
|
|||||||

|

|
||||||
|
|
||||||
[](https://travis-ci.org/Anuken/Mindustry)
|
[](https://github.com/Anuken/Mindustry/actions)
|
||||||
[](https://discord.gg/mindustry)
|
[](https://discord.gg/mindustry)
|
||||||
|
|
||||||
A sandbox tower defense game written in Java.
|
A sandbox tower defense game written in Java.
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,15 @@ You may want to add your server to this list. The steps for getting this done ar
|
|||||||
1. **Ensure your server is properly moderated.** For the most part, this applies to survival servers, but PvP servers can be affected as well.
|
1. **Ensure your server is properly moderated.** For the most part, this applies to survival servers, but PvP servers can be affected as well.
|
||||||
You'll need to either hire some moderators, or make use of (currently non-existent) anti-grief and anti-curse plugins.
|
You'll need to either hire some moderators, or make use of (currently non-existent) anti-grief and anti-curse plugins.
|
||||||
*Consider enabling a rate limit:* `config messageRateLimit 2` will make it so that players can only send messages every 2 seconds, for example.
|
*Consider enabling a rate limit:* `config messageRateLimit 2` will make it so that players can only send messages every 2 seconds, for example.
|
||||||
2. **Set an appropriate MOTD, name and description.** This is set with `config <name/desc/motd> <value>`. "Appropriate" means that:
|
2. Make sure that your server is able to handle inappropriate content - this includes NSFW display/sorter art and abusive messages. **Servers that allow such content will be removed immediately.** Consider banning display blocks if it is a problem for your server: `rules add bannedBlocks ["logic-display", "large-logic-display"]`.
|
||||||
|
3. **Set an appropriate MOTD, name and description.** This is set with `config <name/desc/motd> <value>`. "Appropriate" means that:
|
||||||
- Your name or description must reflect the type of server you're hosting.
|
- Your name or description must reflect the type of server you're hosting.
|
||||||
Since new players may be exposed to the server list early on, put in a phrase like "Co-op survival" or "PvP" so players know what they're getting into. Yes, this is also displayed in the server mode info text, but having extra info in the name doesn't hurt.
|
Since new players may be exposed to the server list early on, put in a phrase like "Co-op survival" or "PvP" so players know what they're getting into. Yes, this is also displayed in the server mode info text, but having extra info in the name doesn't hurt.
|
||||||
- Make sure players know where to refer to for server support. It should be fairly clear that the server owner is not me, but you.
|
- Make sure players know where to refer to for server support. It should be fairly clear that the server owner is not me, but you.
|
||||||
- Try to be professional in your text; use common sense.
|
- Try to be professional in your text; use common sense.
|
||||||
3. **Get some good maps.** *(optional, but highly recommended)*. Add some maps to your server and set the map rotation to custom-only. You can get maps from the Steam workshop by subscribing and exporting them; using the `#maps` channel on Discord is also an option.
|
4. **Get some good maps.** *(optional, but highly recommended)*. Add some maps to your server and set the map rotation to custom-only. You can get maps from the Steam workshop by subscribing and exporting them; using the `#maps` channel on Discord is also an option.
|
||||||
4. **Check your server configuration.** *(optional)* I would recommend adding a message rate limit of 1 second (`config messageRateLimit 1`), and disabling connect/disconnect messages to reduce spam (`config showConnectMessages false`).
|
5. **Check your server configuration.** *(optional)* I would recommend adding a message rate limit of 1 second (`config messageRateLimit 1`), and disabling connect/disconnect messages to reduce spam (`config showConnectMessages false`).
|
||||||
5. Finally, **submit a pull request** to add your server's IP to the list.
|
6. Finally, **submit a pull request** to add your server's IP to the list.
|
||||||
This should be fairly straightforward: Press the edit button on the [server file](https://github.com/Anuken/Mindustry/blob/master/servers_v6.json), then add a JSON object with a single key, indicating your server address.
|
This should be fairly straightforward: Press the edit button on the [server file](https://github.com/Anuken/Mindustry/blob/master/servers_v6.json), then add a JSON object with a single key, indicating your server address.
|
||||||
For example, if your server address is `google.com`, you would add a comma after the last entry and insert:
|
For example, if your server address is `google.com`, you would add a comma after the last entry and insert:
|
||||||
```json
|
```json
|
||||||
|
|||||||
@@ -72,9 +72,8 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> loadJar(Fi jar, String mainClass) throws Exception{
|
public ClassLoader loadJar(Fi jar, String mainClass) throws Exception{
|
||||||
DexClassLoader loader = new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, getClassLoader());
|
return new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, getClassLoader());
|
||||||
return Class.forName(mainClass, true, loader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class RemoteProcess extends BaseProcessor{
|
|||||||
classes = new Seq<>();
|
classes = new Seq<>();
|
||||||
|
|
||||||
Seq<Smethod> orderedElements = elements.copy();
|
Seq<Smethod> orderedElements = elements.copy();
|
||||||
orderedElements.sortComparing(Object::toString);
|
orderedElements.sort((a, b) -> -a.toString().compareTo(b.toString()));
|
||||||
|
|
||||||
//create methods
|
//create methods
|
||||||
for(Smethod element : orderedElements){
|
for(Smethod element : orderedElements){
|
||||||
@@ -71,12 +71,12 @@ public class RemoteProcess extends BaseProcessor{
|
|||||||
|
|
||||||
//check for static
|
//check for static
|
||||||
if(!element.is(Modifier.STATIC) || !element.is(Modifier.PUBLIC)){
|
if(!element.is(Modifier.STATIC) || !element.is(Modifier.PUBLIC)){
|
||||||
err("All @Remote methods must be public and static: ", element);
|
err("All @Remote methods must be public and static", element);
|
||||||
}
|
}
|
||||||
|
|
||||||
//can't generate none methods
|
//can't generate none methods
|
||||||
if(annotation.targets() == Loc.none){
|
if(annotation.targets() == Loc.none){
|
||||||
err("A @Remote method's targets() cannot be equal to 'none':", element);
|
err("A @Remote method's targets() cannot be equal to 'none'", element);
|
||||||
}
|
}
|
||||||
|
|
||||||
//get and create class entry if needed
|
//get and create class entry if needed
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ allprojects{
|
|||||||
if(!project.hasProperty("versionType")) versionType = 'official'
|
if(!project.hasProperty("versionType")) versionType = 'official'
|
||||||
appName = 'Mindustry'
|
appName = 'Mindustry'
|
||||||
steamworksVersion = '891ed912791e01fe9ee6237a6497e5212b85c256'
|
steamworksVersion = '891ed912791e01fe9ee6237a6497e5212b85c256'
|
||||||
rhinoVersion = '2617981f706e50b8753155d8e15e326308be3b22'
|
rhinoVersion = '378626d8abc552bba57864358358045d2f2dbe9b'
|
||||||
|
|
||||||
loadVersionProps = {
|
loadVersionProps = {
|
||||||
return new Properties().with{p -> p.load(file('../core/assets/version.properties').newReader()); return p }
|
return new Properties().with{p -> p.load(file('../core/assets/version.properties').newReader()); return p }
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 514 B |
|
Before Width: | Height: | Size: 359 B After Width: | Height: | Size: 536 B |
|
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 430 B |
@@ -113,7 +113,7 @@ committingchanges = Committing Changes
|
|||||||
done = Done
|
done = Done
|
||||||
feature.unsupported = Your device does not support this feature.
|
feature.unsupported = Your device does not support this feature.
|
||||||
|
|
||||||
mods.alphainfo = Keep in mind that mods are in alpha, and[scarlet] may be very buggy[].\nReport any issues you find to the Mindustry GitHub.
|
mods.initfailed = [red]⚠[] The previous Mindustry instance failed to initialize. This was likely caused by misbehaving mods.\n\nTo prevent a crash loop, [red]all mods have been disabled.[]\n\nTo disable this feature, turn it off in [accent]Settings->Game->Disable Mods On Startup Crash[].
|
||||||
mods = Mods
|
mods = Mods
|
||||||
mods.none = [lightgray]No mods found!
|
mods.none = [lightgray]No mods found!
|
||||||
mods.guide = Modding Guide
|
mods.guide = Modding Guide
|
||||||
@@ -126,6 +126,7 @@ mod.installed = [[Installed]
|
|||||||
mod.display = [gray]Mod:[orange] {0}
|
mod.display = [gray]Mod:[orange] {0}
|
||||||
mod.enabled = [lightgray]Enabled
|
mod.enabled = [lightgray]Enabled
|
||||||
mod.disabled = [scarlet]Disabled
|
mod.disabled = [scarlet]Disabled
|
||||||
|
mod.multiplayer.compatible = [gray]Multiplayer Compatible
|
||||||
mod.disable = Disable
|
mod.disable = Disable
|
||||||
mod.content = Content:
|
mod.content = Content:
|
||||||
mod.delete.error = Unable to delete mod. File may be in use.
|
mod.delete.error = Unable to delete mod. File may be in use.
|
||||||
@@ -216,9 +217,11 @@ server.hidden = Hidden
|
|||||||
trace = Trace Player
|
trace = Trace Player
|
||||||
trace.playername = Player name: [accent]{0}
|
trace.playername = Player name: [accent]{0}
|
||||||
trace.ip = IP: [accent]{0}
|
trace.ip = IP: [accent]{0}
|
||||||
trace.id = Unique ID: [accent]{0}
|
trace.id = ID: [accent]{0}
|
||||||
trace.mobile = Mobile Client: [accent]{0}
|
trace.mobile = Mobile Client: [accent]{0}
|
||||||
trace.modclient = Custom Client: [accent]{0}
|
trace.modclient = Custom Client: [accent]{0}
|
||||||
|
trace.times.joined = Times Joined: [accent]{0}
|
||||||
|
trace.times.kicked = Times Kicked: [accent]{0}
|
||||||
invalidid = Invalid client ID! Submit a bug report.
|
invalidid = Invalid client ID! Submit a bug report.
|
||||||
server.bans = Bans
|
server.bans = Bans
|
||||||
server.bans.none = No banned players found!
|
server.bans.none = No banned players found!
|
||||||
@@ -800,6 +803,8 @@ setting.logichints.name = Logic Hints
|
|||||||
setting.flow.name = Display Resource Flow Rate
|
setting.flow.name = Display Resource Flow Rate
|
||||||
setting.backgroundpause.name = Pause In Background
|
setting.backgroundpause.name = Pause In Background
|
||||||
setting.buildautopause.name = Auto-Pause Building
|
setting.buildautopause.name = Auto-Pause Building
|
||||||
|
setting.doubletapmine.name = Double-Tap to Mine
|
||||||
|
setting.modcrashdisable.name = Disable Mods On Startup Crash
|
||||||
setting.animatedwater.name = Animated Surfaces
|
setting.animatedwater.name = Animated Surfaces
|
||||||
setting.animatedshields.name = Animated Shields
|
setting.animatedshields.name = Animated Shields
|
||||||
setting.antialias.name = Antialias[lightgray] (requires restart)[]
|
setting.antialias.name = Antialias[lightgray] (requires restart)[]
|
||||||
@@ -1455,7 +1460,7 @@ block.ripple.description = Shoots clusters of shells at ground enemies over long
|
|||||||
block.cyclone.description = Fires explosive clumps of flak at nearby enemies.
|
block.cyclone.description = Fires explosive clumps of flak at nearby enemies.
|
||||||
block.spectre.description = Fires large armor-piercing bullets at air and ground targets.
|
block.spectre.description = Fires large armor-piercing bullets at air and ground targets.
|
||||||
block.meltdown.description = Charges and fires a persistent laser beam at nearby enemies. Requires coolant to operate.
|
block.meltdown.description = Charges and fires a persistent laser beam at nearby enemies. Requires coolant to operate.
|
||||||
block.foreshadow.description = Fires a large single-target bolt over long distances.
|
block.foreshadow.description = Fires a large single-target bolt over long distances. Prioritizes enemies with higher max health.
|
||||||
block.repair-point.description = Continuously repairs the closest damaged unit in its vicinity.
|
block.repair-point.description = Continuously repairs the closest damaged unit in its vicinity.
|
||||||
block.segment.description = Damages and destroys incoming projectiles. Laser projectiles are not targeted.
|
block.segment.description = Damages and destroys incoming projectiles. Laser projectiles are not targeted.
|
||||||
block.parallax.description = Fires a tractor beam that pulls in air targets, damaging them in the process.
|
block.parallax.description = Fires a tractor beam that pulls in air targets, damaging them in the process.
|
||||||
@@ -1536,12 +1541,30 @@ lst.unitcontrol = Control the currently bound unit.
|
|||||||
lst.unitradar = Locate units around the currently bound unit.
|
lst.unitradar = Locate units around the currently bound unit.
|
||||||
lst.unitlocate = Locate a specific type of position/building anywhere on the map.\nRequires a bound unit.
|
lst.unitlocate = Locate a specific type of position/building anywhere on the map.\nRequires a bound unit.
|
||||||
|
|
||||||
|
logic.nounitbuild = [red]Unit building logic is not allowed here.
|
||||||
|
|
||||||
lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string.
|
lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string.
|
||||||
lenum.shoot = Shoot at a position.
|
lenum.shoot = Shoot at a position.
|
||||||
lenum.shootp = Shoot at a unit/building with velocity prediction.
|
lenum.shootp = Shoot at a unit/building with velocity prediction.
|
||||||
lenum.configure = Building configuration, e.g. sorter item.
|
lenum.configure = Building configuration, e.g. sorter item.
|
||||||
lenum.enabled = Whether the block is enabled.
|
lenum.enabled = Whether the block is enabled.
|
||||||
lenum.color = Illuminator color.
|
|
||||||
|
laccess.color = Illuminator color.
|
||||||
|
laccess.controller = Unit controller. If processor controlled, returns processor.\nIf in a formation, returns leader.\nOtherwise, returns the unit itself.
|
||||||
|
laccess.dead = Whether a unit/building is dead or no longer valid.
|
||||||
|
laccess.controlled = Returns:\n[accent]@ctrlProcessor[] if unit controller is processor\n[accent]@ctrlPlayer[] if unit/building controller is player\n[accent]@ctrlFormation[] if unit is in formation\nOtherwise, 0.
|
||||||
|
laccess.commanded = [red]Deprecated. Will be removed![]\nUse [accent]controlled[] instead.
|
||||||
|
|
||||||
|
graphicstype.clear = Fill the display with a color.
|
||||||
|
graphicstype.color = Set color for next drawing operations.
|
||||||
|
graphicstype.stroke = Set line width.
|
||||||
|
graphicstype.line = Draw line segment.
|
||||||
|
graphicstype.rect = Fill a rectangle.
|
||||||
|
graphicstype.linerect = Draw a rectangle outline.
|
||||||
|
graphicstype.poly = Fill a regular polygon.
|
||||||
|
graphicstype.linepoly = Draw a regular polygon outline.
|
||||||
|
graphicstype.triangle = Fill a triangle.
|
||||||
|
graphicstype.image = Draw an image of some content.\nex: [accent]@router[] or [accent]@dagger[].
|
||||||
|
|
||||||
lenum.always = Always true.
|
lenum.always = Always true.
|
||||||
lenum.idiv = Integer division.
|
lenum.idiv = Integer division.
|
||||||
@@ -1566,7 +1589,7 @@ lenum.sin = Sine, in degrees.
|
|||||||
lenum.cos = Cosine, in degrees.
|
lenum.cos = Cosine, in degrees.
|
||||||
lenum.tan = Tangent, in degrees.
|
lenum.tan = Tangent, in degrees.
|
||||||
#not a typo, look up 'range notation'
|
#not a typo, look up 'range notation'
|
||||||
lenum.rand = Random number in range [0, value).
|
lenum.rand = Random decimal in range [0, value).
|
||||||
lenum.log = Natural logarithm (ln).
|
lenum.log = Natural logarithm (ln).
|
||||||
lenum.log10 = Base 10 logarithm.
|
lenum.log10 = Base 10 logarithm.
|
||||||
lenum.noise = 2D simplex noise.
|
lenum.noise = 2D simplex noise.
|
||||||
@@ -1624,6 +1647,7 @@ unitlocate.outx = Output X coordinate.
|
|||||||
unitlocate.outy = Output Y coordinate.
|
unitlocate.outy = Output Y coordinate.
|
||||||
unitlocate.group = Building group to look for.
|
unitlocate.group = Building group to look for.
|
||||||
|
|
||||||
|
lenum.idle = Don't move, but keep building/mining.\nThe default state.
|
||||||
lenum.stop = Stop moving/mining/building.
|
lenum.stop = Stop moving/mining/building.
|
||||||
lenum.move = Move to exact position.
|
lenum.move = Move to exact position.
|
||||||
lenum.approach = Approach a position with a radius.
|
lenum.approach = Approach a position with a radius.
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ committingchanges = Veränderungen werden übernommen
|
|||||||
done = Fertig
|
done = Fertig
|
||||||
feature.unsupported = Dein System unterstützt dieses Feature nicht.
|
feature.unsupported = Dein System unterstützt dieses Feature nicht.
|
||||||
|
|
||||||
mods.alphainfo = Vergiss nicht, dass Mods in der Alpha sind und[scarlet] sehr fehlerhaft sein können[].\nMelde alle Probleme auf GitHub oder Discord.
|
mods.initfailed = [red]⚠[] Die vorherige Mindustry-Instanz konnte nicht starten. Dies lag wahrscheinlich an fehlerhaften Mods.\n\nDamit das Spiel starten kann, [red]wurden alle Mods deaktiviert.[]\n\nWenn du nicht willst, dass das passiert, kannst du es unter [accent]Einstellungen->Spiel->Mods bei Absturz deaktivieren[] ändern.
|
||||||
mods = Mods
|
mods = Mods
|
||||||
mods.none = [lightgray]Keine Mods gefunden!
|
mods.none = [lightgray]Keine Mods gefunden!
|
||||||
mods.guide = Modding-Anleitung
|
mods.guide = Modding-Anleitung
|
||||||
@@ -216,9 +216,11 @@ server.hidden = Versteckt
|
|||||||
trace = Spieler verfolgen
|
trace = Spieler verfolgen
|
||||||
trace.playername = Spielername: [accent]{0}
|
trace.playername = Spielername: [accent]{0}
|
||||||
trace.ip = IP: [accent]{0}
|
trace.ip = IP: [accent]{0}
|
||||||
trace.id = Eindeutige ID: [accent]{0}
|
trace.id = ID: [accent]{0}
|
||||||
trace.mobile = Mobiler Client: [accent]{0}
|
trace.mobile = Mobiler Client: [accent]{0}
|
||||||
trace.modclient = Gemoddeter Client: [accent]{0}
|
trace.modclient = Gemoddeter Client: [accent]{0}
|
||||||
|
trace.times.joined = Beigetreten: [accent]{0}[] Mal
|
||||||
|
trace.times.kicked = Rausgeworfen: [accent]{0}[] Mal
|
||||||
invalidid = Ungültige Client-ID! Berichte den Fehler.
|
invalidid = Ungültige Client-ID! Berichte den Fehler.
|
||||||
server.bans = Verbannungen
|
server.bans = Verbannungen
|
||||||
server.bans.none = Keine verbannten Spieler gefunden!
|
server.bans.none = Keine verbannten Spieler gefunden!
|
||||||
@@ -800,6 +802,8 @@ setting.logichints.name = Logiktipps
|
|||||||
setting.flow.name = Ressourcen-Fluss anzeigen
|
setting.flow.name = Ressourcen-Fluss anzeigen
|
||||||
setting.backgroundpause.name = Im Hintergrund pausieren
|
setting.backgroundpause.name = Im Hintergrund pausieren
|
||||||
setting.buildautopause.name = Bauen automatisch pausieren
|
setting.buildautopause.name = Bauen automatisch pausieren
|
||||||
|
setting.doubletapmine.name = Doppeltippen zum Abbauen
|
||||||
|
setting.modcrashdisable.name = Mods bei Absturz deaktivieren
|
||||||
setting.animatedwater.name = Animiertes Wasser
|
setting.animatedwater.name = Animiertes Wasser
|
||||||
setting.animatedshields.name = Animierte Schilde
|
setting.animatedshields.name = Animierte Schilde
|
||||||
setting.antialias.name = Antialias[lightgray] (Neustart erforderlich)[]
|
setting.antialias.name = Antialias[lightgray] (Neustart erforderlich)[]
|
||||||
@@ -957,6 +961,8 @@ rules.blockdamagemultiplier = Block-Schaden-Multiplikator
|
|||||||
rules.unitbuildspeedmultiplier = Baugeschwindigkeit-Einheit Multiplikator
|
rules.unitbuildspeedmultiplier = Baugeschwindigkeit-Einheit Multiplikator
|
||||||
rules.unithealthmultiplier = Lebenspunkte-Einheit Multiplikator
|
rules.unithealthmultiplier = Lebenspunkte-Einheit Multiplikator
|
||||||
rules.unitdamagemultiplier = Schaden-Einheit Multiplikator
|
rules.unitdamagemultiplier = Schaden-Einheit Multiplikator
|
||||||
|
rules.unitcapvariable = Kerne zählen zum Einheiten-Limit dazu
|
||||||
|
rules.unitcap = Einheiten-Limit
|
||||||
rules.enemycorebuildradius = Bauverbot-Radius durch feindlichen Kern:[lightgray] (Kacheln)
|
rules.enemycorebuildradius = Bauverbot-Radius durch feindlichen Kern:[lightgray] (Kacheln)
|
||||||
rules.wavespacing = Wellen-Abstand:[lightgray] (Sek)
|
rules.wavespacing = Wellen-Abstand:[lightgray] (Sek)
|
||||||
rules.buildcostmultiplier = Bau-Kosten Multiplikator
|
rules.buildcostmultiplier = Bau-Kosten Multiplikator
|
||||||
@@ -1042,7 +1048,7 @@ unit.reign.name = Reign
|
|||||||
unit.vela.name = Vela
|
unit.vela.name = Vela
|
||||||
unit.corvus.name = Korvus
|
unit.corvus.name = Korvus
|
||||||
|
|
||||||
block.resupply-point.name = Nachlade-Punkt
|
block.resupply-point.name = Munitionsvorrat
|
||||||
block.parallax.name = Parallax
|
block.parallax.name = Parallax
|
||||||
block.cliff.name = Klippe
|
block.cliff.name = Klippe
|
||||||
block.sand-boulder.name = Sandbrocken
|
block.sand-boulder.name = Sandbrocken
|
||||||
@@ -1534,12 +1540,30 @@ lst.unitcontrol = Steuert [accent]@unit[].
|
|||||||
lst.unitradar = Findet Einheiten in der Nähe von [accent]@unit[].
|
lst.unitradar = Findet Einheiten in der Nähe von [accent]@unit[].
|
||||||
lst.unitlocate = Findet mit [accent]@unit[] bestimmte Positionen / Blöcke auf der ganzen Karte.
|
lst.unitlocate = Findet mit [accent]@unit[] bestimmte Positionen / Blöcke auf der ganzen Karte.
|
||||||
|
|
||||||
|
logic.nounitbuild = [red]Logik, die Blöcke baut, ist hier nicht erlaubt.
|
||||||
|
|
||||||
lenum.type = Englischer Name eines Blocks / einer Einheit. Ein Verteiler gibt [accent]@router[] wieder.\nKein string.
|
lenum.type = Englischer Name eines Blocks / einer Einheit. Ein Verteiler gibt [accent]@router[] wieder.\nKein string.
|
||||||
lenum.shoot = Schießt auf eine Position.
|
lenum.shoot = Schießt auf eine Position.
|
||||||
lenum.shootp = Schießt auf eine Einheit / einen Block und sagt deren Position voraus.
|
lenum.shootp = Schießt auf eine Einheit / einen Block und sagt deren Position voraus.
|
||||||
lenum.configure = Blockkonfiguration, z.B. das ausgewählte Item in einem Sortierer.
|
lenum.configure = Blockkonfiguration, z.B. das ausgewählte Item in einem Sortierer.
|
||||||
lenum.enabled = Ob der Block an oder aus ist.
|
lenum.enabled = Ob der Block an oder aus ist.
|
||||||
lenum.color = Illuminiererfarbe.
|
|
||||||
|
laccess.color = Illuminiererfarbe.
|
||||||
|
laccess.controller = Einheitensteurer. Gibt "processor" zurück, wenn die Einheit prozessorgesteuert ist,.\nGibt den Steuerer zurück, wenn die Einheit Teil einer Formation ist.\nSonst wird einfach die Einheit zurückgegeben.
|
||||||
|
laccess.dead = Ob ein Block / eine Einheit tot oder nicht mehr gültig ist.
|
||||||
|
laccess.controlled = Gibt zurück:\n[accent]@ctrlProcessor[] wenn die Einheit prozessorgesteuert ist\n[accent]@ctrlPlayer[] wenn die Einheit / der Block von einem Spieler gesteuert wird\n[accent]@ctrlFormation[] wenn die Einheit Teil einer Formation ist\nSonst 0.
|
||||||
|
laccess.commanded = [red]Veraltet. Wird bald entfernt![]\nBenutze stattdessen [accent]controlled[].
|
||||||
|
|
||||||
|
graphicstype.stroke = Setzt die Linienbreite fest.
|
||||||
|
graphicstype.line = Zeichnet eine Linie.
|
||||||
|
graphicstype.clear = Füllt den Bildschirm mit einer Farbe.
|
||||||
|
graphicstype.color = Wählt eine Farbe aus.
|
||||||
|
graphicstype.rect = Zeichnet ein Rechteck.
|
||||||
|
graphicstype.linerect = Zeichnet den Umriss eines Rechtecks.
|
||||||
|
graphicstype.poly = Füllt ein gleichmäßiges Polygon.
|
||||||
|
graphicstype.linepoly = Zeichnet den Umriss eines gleichmäßigen Polygons.
|
||||||
|
graphicstype.triangle = Zeichnet ein Dreieck.
|
||||||
|
graphicstype.image = Zeichnet ein Bild von einem englischen Namen.\nz.B. [accent]@router[] oder [accent]@dagger[].
|
||||||
|
|
||||||
lenum.always = Immer.
|
lenum.always = Immer.
|
||||||
lenum.idiv = Division mit ganzen Zahlen.
|
lenum.idiv = Division mit ganzen Zahlen.
|
||||||
@@ -1563,6 +1587,7 @@ lenum.len = Length of vector.
|
|||||||
lenum.sin = Sinus in Grad.
|
lenum.sin = Sinus in Grad.
|
||||||
lenum.cos = Cosinus in Grad.
|
lenum.cos = Cosinus in Grad.
|
||||||
lenum.tan = Tangens in Grad.
|
lenum.tan = Tangens in Grad.
|
||||||
|
#not a typo, look up 'range notation'
|
||||||
lenum.rand = Zufällige Zahl zwischen [0, <wert>).
|
lenum.rand = Zufällige Zahl zwischen [0, <wert>).
|
||||||
lenum.log = Logarithmus (ln).
|
lenum.log = Logarithmus (ln).
|
||||||
lenum.log10 = Logarithmus zur Basis 10.
|
lenum.log10 = Logarithmus zur Basis 10.
|
||||||
@@ -1586,6 +1611,14 @@ lenum.building = Ein Block einer bestimmten Sorte.
|
|||||||
|
|
||||||
lenum.core = Irgendein Kern.
|
lenum.core = Irgendein Kern.
|
||||||
lenum.storage = Speicherblock, z.B. ein Tresor.
|
lenum.storage = Speicherblock, z.B. ein Tresor.
|
||||||
|
lenum.generator = Blöcke, die Strom generieren.
|
||||||
|
lenum.factory = Blöcke, die Ressourcen verarbeiten.
|
||||||
|
lenum.repair = Reperaturpunkt.
|
||||||
|
lenum.rally = Kommandozentrale
|
||||||
|
lenum.battery = Irgendeine Batterie.
|
||||||
|
lenum.resupply = Munitionsvorrat.\nNur wichtig, wenn [accent]"Einheiten benötigen Munition"[] an ist.
|
||||||
|
lenum.reactor = Schlag- / Thoriumreaktor.
|
||||||
|
lenum.turret = Irgendein Geschütz.
|
||||||
|
|
||||||
sensor.in = Der Block / die Einheit.
|
sensor.in = Der Block / die Einheit.
|
||||||
|
|
||||||
@@ -1613,6 +1646,7 @@ unitlocate.outx = Variable für die X-Koordinate.
|
|||||||
unitlocate.outy = Variable für die Y-Koordinate.
|
unitlocate.outy = Variable für die Y-Koordinate.
|
||||||
unitlocate.group = Gesuchter Blocktyp.
|
unitlocate.group = Gesuchter Blocktyp.
|
||||||
|
|
||||||
|
lenum.idle = Bewegt sich nicht, baut aber weiter ab.\nDer normale Zustand.
|
||||||
lenum.stop = Bewegung / Abbau / Bau abbrechen.
|
lenum.stop = Bewegung / Abbau / Bau abbrechen.
|
||||||
lenum.move = Geht zu diese Position.
|
lenum.move = Geht zu diese Position.
|
||||||
lenum.approach = Geht auf einen Punkt mit einem bestimmten Radius zu.
|
lenum.approach = Geht auf einen Punkt mit einem bestimmten Radius zu.
|
||||||
|
|||||||
@@ -678,6 +678,7 @@ stat.drillspeed = Velocidad del Taladro
|
|||||||
stat.boosteffect = Efecto de Potenciador
|
stat.boosteffect = Efecto de Potenciador
|
||||||
stat.maxunits = Máximo de Unidades Activas
|
stat.maxunits = Máximo de Unidades Activas
|
||||||
stat.health = Vida
|
stat.health = Vida
|
||||||
|
stat.armor = Armadura
|
||||||
stat.buildtime = Tiempo de construcción
|
stat.buildtime = Tiempo de construcción
|
||||||
stat.maxconsecutive = Máximo consecutivo
|
stat.maxconsecutive = Máximo consecutivo
|
||||||
stat.buildcost = Coste de construcción
|
stat.buildcost = Coste de construcción
|
||||||
@@ -693,7 +694,8 @@ stat.lightningchance = Probabilidad de descarga
|
|||||||
stat.lightningdamage = Daño por rayo
|
stat.lightningdamage = Daño por rayo
|
||||||
stat.flammability = Inflamabilidad
|
stat.flammability = Inflamabilidad
|
||||||
stat.radioactivity = Radioactividad
|
stat.radioactivity = Radioactividad
|
||||||
stat.heatcapacity = Resistencia temperatura
|
stat.charge = Carga eléctrica
|
||||||
|
stat.heatcapacity = Resistencia a la temperatura
|
||||||
stat.viscosity = Viscosidad
|
stat.viscosity = Viscosidad
|
||||||
stat.temperature = Temperatura
|
stat.temperature = Temperatura
|
||||||
stat.speed = Velocidad
|
stat.speed = Velocidad
|
||||||
@@ -744,6 +746,7 @@ bullet.sapping = [stat]Oxidante
|
|||||||
bullet.homing = [stat]Rastreadora
|
bullet.homing = [stat]Rastreadora
|
||||||
bullet.shock = [stat]Electrizante
|
bullet.shock = [stat]Electrizante
|
||||||
bullet.frag = [stat]De fragmentación
|
bullet.frag = [stat]De fragmentación
|
||||||
|
bullet.buildingdamage = [stat]{0}%[lightgray]daño a estructuras
|
||||||
bullet.knockback = [stat]{0}[lightgray] Empuje
|
bullet.knockback = [stat]{0}[lightgray] Empuje
|
||||||
bullet.pierce = [stat]{0}[lightgray]x penetración
|
bullet.pierce = [stat]{0}[lightgray]x penetración
|
||||||
bullet.infinitepierce = [stat]Penetrante
|
bullet.infinitepierce = [stat]Penetrante
|
||||||
@@ -1116,7 +1119,7 @@ block.plastanium-wall.name = Muro de Plastanio
|
|||||||
block.plastanium-wall-large.name = Muro de Plastanio grande
|
block.plastanium-wall-large.name = Muro de Plastanio grande
|
||||||
block.phase-wall.name = Muro de Fase grande
|
block.phase-wall.name = Muro de Fase grande
|
||||||
block.phase-wall-large.name = Muro de Fase grande
|
block.phase-wall-large.name = Muro de Fase grande
|
||||||
block.thorium-wall.name = Pared de Torio
|
block.thorium-wall.name = Muro de Torio
|
||||||
block.thorium-wall-large.name = Muro de Torio grande
|
block.thorium-wall-large.name = Muro de Torio grande
|
||||||
block.door.name = Puerta
|
block.door.name = Puerta
|
||||||
block.door-large.name = Puerta Grande
|
block.door-large.name = Puerta Grande
|
||||||
@@ -1329,16 +1332,16 @@ block.graphite-press.description = Comprime carbón en piezas de grafito puro.
|
|||||||
block.multi-press.description = Una versión mejorada de la prensa de grafito. Utiliza agua y energía para procesar carbón rápida y eficientemente.
|
block.multi-press.description = Una versión mejorada de la prensa de grafito. Utiliza agua y energía para procesar carbón rápida y eficientemente.
|
||||||
block.silicon-smelter.description = Reduce la arena con carbón puro. Produce silicio.
|
block.silicon-smelter.description = Reduce la arena con carbón puro. Produce silicio.
|
||||||
block.kiln.description = Funde arena y plomo en metacristal. Requiere cantidades pequeñas de energía para funcionar.
|
block.kiln.description = Funde arena y plomo en metacristal. Requiere cantidades pequeñas de energía para funcionar.
|
||||||
block.plastanium-compressor.description = Produce plastanio con aceite y titanio.
|
block.plastanium-compressor.description = Produce plastanio con petróleo y titanio.
|
||||||
block.phase-weaver.description = Produce tejido de fase del torio radioactivo y altas cantidades de arena.
|
block.phase-weaver.description = Produce tejido de fase del torio radioactivo y altas cantidades de arena.
|
||||||
block.alloy-smelter.description = Produce aleación eléctrica con titanio, plomo, silicio y cobre.
|
block.alloy-smelter.description = Produce aleación eléctrica con titanio, plomo, silicio y cobre.
|
||||||
block.cryofluid-mixer.description = Combina agua y titanio en líquido criogénico, que es mucho más eficiente para enfriar.
|
block.cryofluid-mixer.description = Combina agua y titanio en líquido criogénico, que es mucho más eficiente para enfriar.
|
||||||
block.blast-mixer.description = Usa aceite para transformar pirotita en un objeto menos inflamable pero más explosivo: el compuesto explosivo.
|
block.blast-mixer.description = Usa esporas para transformar pirotita en un objeto menos inflamable pero más explosivo: el compuesto explosivo.
|
||||||
block.pyratite-mixer.description = Mezcla carbón, plomo y arena en pirotita altamente inflamable.
|
block.pyratite-mixer.description = Mezcla carbón, plomo y arena en pirotita altamente inflamable.
|
||||||
block.melter.description = Calienta piedra a temperaturas muy altas para obtener lava.
|
block.melter.description = Calienta chatarra a temperaturas muy altas para obtener magma.
|
||||||
block.separator.description = Expone piedra a la presión del agua para obtener diversos minerales contenidos en la piedra.
|
block.separator.description = Separa el magma en sus componentes minerales.
|
||||||
block.spore-press.description = Comprime esporas en petróleo.
|
block.spore-press.description = Comprime esporas en petróleo.
|
||||||
block.pulverizer.description = Despedaza la piedra en arena. Útil cuando no hay arena natural.
|
block.pulverizer.description = Despedaza la chatarra en arena. Útil cuando no hay arena natural.
|
||||||
block.coal-centrifuge.description = Solidifica petróleo en piezas de carbón.
|
block.coal-centrifuge.description = Solidifica petróleo en piezas de carbón.
|
||||||
block.incinerator.description = Se deshace de cualquier líquido o material producido en exceso.
|
block.incinerator.description = Se deshace de cualquier líquido o material producido en exceso.
|
||||||
block.power-void.description = Elimina toda la energía que se le da. Solo en disponible en el modo Libre.
|
block.power-void.description = Elimina toda la energía que se le da. Solo en disponible en el modo Libre.
|
||||||
@@ -1351,7 +1354,7 @@ block.copper-wall.description = Un bloque defensivo barato.\nÚtil para defender
|
|||||||
block.copper-wall-large.description = Un bloque defensivo barato.\nÚtil para defender el núcleo y las torres en las primeras oleadas.\nOcupa múltiples casillas.
|
block.copper-wall-large.description = Un bloque defensivo barato.\nÚtil para defender el núcleo y las torres en las primeras oleadas.\nOcupa múltiples casillas.
|
||||||
block.titanium-wall.description = Un bloque defensivo moderadamente fuerte.\nProporciona protección moderada contra los enemigos.
|
block.titanium-wall.description = Un bloque defensivo moderadamente fuerte.\nProporciona protección moderada contra los enemigos.
|
||||||
block.titanium-wall-large.description = Un bloque defensivo moderadamente fuerte.\nProporciona protección moderada contra los enemigos.\nOcupa múltiples casillas.
|
block.titanium-wall-large.description = Un bloque defensivo moderadamente fuerte.\nProporciona protección moderada contra los enemigos.\nOcupa múltiples casillas.
|
||||||
block.plastanium-wall.description = Un tipo especial de pared que absorbe los arcos eléctricos y bloquea las conexiones automáticas de los nodos de potencia..
|
block.plastanium-wall.description = Un tipo especial de pared que absorbe los arcos eléctricos y bloquea las conexiones automáticas de los nodos de potencia.
|
||||||
block.plastanium-wall-large.description = Un tipo especial de pared que absorbe los arcos eléctricos y bloquea las conexiones automáticas de los nodos de potencia.\nOcupa múltiples casillas.
|
block.plastanium-wall-large.description = Un tipo especial de pared que absorbe los arcos eléctricos y bloquea las conexiones automáticas de los nodos de potencia.\nOcupa múltiples casillas.
|
||||||
block.thorium-wall.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.
|
block.thorium-wall.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.
|
||||||
block.thorium-wall-large.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.\nOcupa múltiples casillas.
|
block.thorium-wall-large.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.\nOcupa múltiples casillas.
|
||||||
@@ -1359,8 +1362,8 @@ block.phase-wall.description = No es tan fuerte como un muro de torio pero hace
|
|||||||
block.phase-wall-large.description = No es tan fuerte como un muro de torio pero rebota balas al enemigo si no son demasiado fuertes.\nOcupa múltiples casillas.
|
block.phase-wall-large.description = No es tan fuerte como un muro de torio pero rebota balas al enemigo si no son demasiado fuertes.\nOcupa múltiples casillas.
|
||||||
block.surge-wall.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.
|
block.surge-wall.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.
|
||||||
block.surge-wall-large.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.\nOcupa múltiplies casillas.
|
block.surge-wall-large.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.\nOcupa múltiplies casillas.
|
||||||
block.door.description = Una puerta pequeña que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella.
|
block.door.description = Una puerta pequeña que puede ser abierta y cerrada tocándola.\nSi está abierta, los enemigos pueden moverse y disparar a través de ella.
|
||||||
block.door-large.description = Una puerta grande que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas.
|
block.door-large.description = Una puerta grande que puede ser abierta y cerrada tocándola.\nSi está abierta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas.
|
||||||
block.mender.description = Repara bloques cercanos de forma constante. Mantiene a las defensas reparadas entre oleadas. Puede usar silicio opcionalmente para mejorar el alcance y la eficiencia.
|
block.mender.description = Repara bloques cercanos de forma constante. Mantiene a las defensas reparadas entre oleadas. Puede usar silicio opcionalmente para mejorar el alcance y la eficiencia.
|
||||||
block.mend-projector.description = Regenera edificios cercanos de forma constante. Ocupa multiples casillas.
|
block.mend-projector.description = Regenera edificios cercanos de forma constante. Ocupa multiples casillas.
|
||||||
block.overdrive-projector.description = Aumenta la velocidad de edificios cercanos como taladros y transportadores.
|
block.overdrive-projector.description = Aumenta la velocidad de edificios cercanos como taladros y transportadores.
|
||||||
@@ -1388,7 +1391,7 @@ block.pulse-conduit.description = Bloque de transporte de líquidos avanzado. Tr
|
|||||||
block.plated-conduit.description = Mueve líquidos a la misma velocidad que los conductos de pulso, pero posee más armadura. No acepta líquidos de los lados por otra cosa que no sean conductos.\nGotea menos.
|
block.plated-conduit.description = Mueve líquidos a la misma velocidad que los conductos de pulso, pero posee más armadura. No acepta líquidos de los lados por otra cosa que no sean conductos.\nGotea menos.
|
||||||
block.liquid-router.description = Acepta líquidos de una dirección y los deja en hasta 3 direcciones equitativamente. También puede almacenar cierta capacidad de líquido. Útil para dividir los líquidos de una fuente a varios objetivos.
|
block.liquid-router.description = Acepta líquidos de una dirección y los deja en hasta 3 direcciones equitativamente. También puede almacenar cierta capacidad de líquido. Útil para dividir los líquidos de una fuente a varios objetivos.
|
||||||
block.liquid-tank.description = Almacena una gran cantidad de líquidos. Úsalo para crear almacenes cuando no hay una demanda constante de materiales o para asegurarse de enfriar bloques vitales.
|
block.liquid-tank.description = Almacena una gran cantidad de líquidos. Úsalo para crear almacenes cuando no hay una demanda constante de materiales o para asegurarse de enfriar bloques vitales.
|
||||||
block.liquid-junction.description = Actúa como un puente para dos condusctos que se cruzan. Útil en situaciones en las que hay dos conductos con líquidos diferentes a diferentes lugares.
|
block.liquid-junction.description = Actúa como un puente para dos conductos que se cruzan. Útil en situaciones en las que hay dos conductos con líquidos diferentes a diferentes lugares.
|
||||||
block.bridge-conduit.description = Bloque avanzado de transporte de líquidos. Permite transportar líquidos por encima de hasta 3 casillas de cualquier terreno o construcción.
|
block.bridge-conduit.description = Bloque avanzado de transporte de líquidos. Permite transportar líquidos por encima de hasta 3 casillas de cualquier terreno o construcción.
|
||||||
block.phase-conduit.description = Bloque de transporte de líquidos avanzado. Usa energía para transportar líquidos a otro conducto de fase conectado a través de varias casillas.
|
block.phase-conduit.description = Bloque de transporte de líquidos avanzado. Usa energía para transportar líquidos a otro conducto de fase conectado a través de varias casillas.
|
||||||
block.power-node.description = Transmite energía a nodos conectados, conecta hasta diez fuentes de energía, edificios que usan energía o nodos. El nodo obtendrá o transmitirá energía de cualquier bloque adyacente.
|
block.power-node.description = Transmite energía a nodos conectados, conecta hasta diez fuentes de energía, edificios que usan energía o nodos. El nodo obtendrá o transmitirá energía de cualquier bloque adyacente.
|
||||||
@@ -1398,7 +1401,7 @@ block.diode.description = La energía de la batería puede fluir a través de es
|
|||||||
block.battery.description = Guarda energía cuando hay abundancia y proporciona energía cuando hay escasez de energía mientras la batería tenga energía.
|
block.battery.description = Guarda energía cuando hay abundancia y proporciona energía cuando hay escasez de energía mientras la batería tenga energía.
|
||||||
block.battery-large.description = Almacena mucha más energía que una batería normal.
|
block.battery-large.description = Almacena mucha más energía que una batería normal.
|
||||||
block.combustion-generator.description = Genera energía quemando materiales inflamables o petróleo.
|
block.combustion-generator.description = Genera energía quemando materiales inflamables o petróleo.
|
||||||
block.thermal-generator.description = Genera una gran cantidad de energía con la lava.
|
block.thermal-generator.description = Genera una gran cantidad de energía con el magma.
|
||||||
block.steam-generator.description = Más eficiente que un generador de combustión, pero requiere agua adicional.
|
block.steam-generator.description = Más eficiente que un generador de combustión, pero requiere agua adicional.
|
||||||
block.differential-generator.description = Genera grandes cantidades de energía. Utiliza la diferencia de temperatura entre el fluído criogenico y la quema de pirotita.
|
block.differential-generator.description = Genera grandes cantidades de energía. Utiliza la diferencia de temperatura entre el fluído criogenico y la quema de pirotita.
|
||||||
block.rtg-generator.description = Un generador radioisótropo termoeléctrico que no necesita enfriamiento, pero proporciona menos energía que un reactor de torio.
|
block.rtg-generator.description = Un generador radioisótropo termoeléctrico que no necesita enfriamiento, pero proporciona menos energía que un reactor de torio.
|
||||||
@@ -1444,7 +1447,7 @@ block.segment.description = Daña y destruye proyectiles que se acerquen. No afe
|
|||||||
block.parallax.description = Dispara un rayo tractor que atrae enemigos aéreos, dañándolos en el proceso.
|
block.parallax.description = Dispara un rayo tractor que atrae enemigos aéreos, dañándolos en el proceso.
|
||||||
block.tsunami.description = Dispara poderosos torrentes de líquido a los enemigos. También apaga fuegos automáticamente si se lo abastece con agua.
|
block.tsunami.description = Dispara poderosos torrentes de líquido a los enemigos. También apaga fuegos automáticamente si se lo abastece con agua.
|
||||||
block.silicon-crucible.description = Refina silicio a partir de arena y carbón, usando pirotita como una fuente de calor adicional. Es más eficiente en lugares cálidos.
|
block.silicon-crucible.description = Refina silicio a partir de arena y carbón, usando pirotita como una fuente de calor adicional. Es más eficiente en lugares cálidos.
|
||||||
block.disassembler.description = Separa magma cantidades moderadas de componentes minerales exóticos con baja eficiencia. Puede producir Torio.
|
block.disassembler.description = Separa magma en cantidades moderadas de componentes minerales exóticos con baja eficiencia. Puede producir Torio.
|
||||||
block.overdrive-dome.description = Incrementa la velocidad de estructuras cercanas. Requiere Tejido de Fase y Silicio para operar.
|
block.overdrive-dome.description = Incrementa la velocidad de estructuras cercanas. Requiere Tejido de Fase y Silicio para operar.
|
||||||
block.payload-conveyor.description = Mueve tanto grandes cargas, como unidades recién ensambladas de sus fábricas.
|
block.payload-conveyor.description = Mueve tanto grandes cargas, como unidades recién ensambladas de sus fábricas.
|
||||||
block.payload-router.description = Divide las cargas entrantes en 3 direcciones de salida.
|
block.payload-router.description = Divide las cargas entrantes en 3 direcciones de salida.
|
||||||
@@ -1487,7 +1490,7 @@ unit.zenith.description = Dispara ráfagas de misiles a enemigos cercanos.
|
|||||||
unit.antumbra.description = Dispara un enjambre de balas a cualquer enemigo cercano.
|
unit.antumbra.description = Dispara un enjambre de balas a cualquer enemigo cercano.
|
||||||
unit.eclipse.description = Dispara dos láseres perforantes y un enjambre de balas de fragmentación.
|
unit.eclipse.description = Dispara dos láseres perforantes y un enjambre de balas de fragmentación.
|
||||||
unit.mono.description = Extrae cobre y plomo, y los deposita en el núcleo.
|
unit.mono.description = Extrae cobre y plomo, y los deposita en el núcleo.
|
||||||
unit.poly.description = Recosntruye automáticamente estructuras dañadas y asiste a otras unidades en la construcción.
|
unit.poly.description = Reconstruye automáticamente estructuras dañadas y asiste a otras unidades en la construcción.
|
||||||
unit.mega.description = Repara automáticamente estructuras dañadas. Puede llevar estructuras y unidades terrestres pequeñas.
|
unit.mega.description = Repara automáticamente estructuras dañadas. Puede llevar estructuras y unidades terrestres pequeñas.
|
||||||
unit.quad.description = Suelta grandes bombas sobre objetivos terrestres, repara estructuras aliadas y daña enemigos. Puede cargar con unidades terrestres de tamaño medio.
|
unit.quad.description = Suelta grandes bombas sobre objetivos terrestres, repara estructuras aliadas y daña enemigos. Puede cargar con unidades terrestres de tamaño medio.
|
||||||
unit.oct.description = Protege aliados con su escudo. Puede cargar con la mayoría de unidades terrestres.
|
unit.oct.description = Protege aliados con su escudo. Puede cargar con la mayoría de unidades terrestres.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ link.discord.description = Discord officiel de Mindustry
|
|||||||
link.reddit.description = Subreddit de Mindustry
|
link.reddit.description = Subreddit de Mindustry
|
||||||
link.github.description = Code source du jeu
|
link.github.description = Code source du jeu
|
||||||
link.changelog.description = Liste des mises à jour
|
link.changelog.description = Liste des mises à jour
|
||||||
link.dev-builds.description = Versions expérimentale du jeu
|
link.dev-builds.description = Versions expérimentales du jeu
|
||||||
link.trello.description = Trello officiel pour les nouvelles fonctionalités planifiées
|
link.trello.description = Trello officiel pour les nouvelles fonctionalités planifiées
|
||||||
link.itch.io.description = Page itch.io avec les différentes versions du jeu.
|
link.itch.io.description = Page itch.io avec les différentes versions du jeu.
|
||||||
link.google-play.description = Page Google Play du jeu
|
link.google-play.description = Page Google Play du jeu
|
||||||
@@ -41,17 +41,20 @@ be.ignore = Ignorer
|
|||||||
be.noupdates = Aucune mise à jour trouvée.
|
be.noupdates = Aucune mise à jour trouvée.
|
||||||
be.check = Chercher des mises à jour
|
be.check = Chercher des mises à jour
|
||||||
|
|
||||||
mod.featured.dialog.title = Navigateur de Mods (WIP)
|
mods.browser = Navigateur de Mods
|
||||||
mods.browser.selected = Mod sélectionné
|
mods.browser.selected = Mod sélectionné
|
||||||
mods.browser.add = Installer
|
mods.browser.add = Installer
|
||||||
mods.github.open = Voir
|
mods.browser.reinstall = Reinstaller
|
||||||
|
mods.github.open = Voir sur Github
|
||||||
|
mods.browser.sortdate = Classer par date
|
||||||
|
mods.browser.sortstars = Classer par étoiles
|
||||||
|
|
||||||
schematic = Schéma
|
schematic = Schéma
|
||||||
schematic.add = Enregistrer le Schéma...
|
schematic.add = Enregistrer le Schéma
|
||||||
schematics = Schémas
|
schematics = Schémas
|
||||||
schematic.replace = Un schéma avec ce nom existe déjà. Voulez-vous le remplacer ?
|
schematic.replace = Un schéma avec ce nom existe déjà. Voulez-vous le remplacer?
|
||||||
schematic.exists = Un schéma avec ce nom existe déjà.
|
schematic.exists = Un schéma avec ce nom existe déjà.
|
||||||
schematic.import = Importer un schéma...
|
schematic.import = Importer un schéma
|
||||||
schematic.exportfile = Exporter le fichier
|
schematic.exportfile = Exporter le fichier
|
||||||
schematic.importfile = Importer un fichier
|
schematic.importfile = Importer un fichier
|
||||||
schematic.browseworkshop = Consulter le Steam Workshop
|
schematic.browseworkshop = Consulter le Steam Workshop
|
||||||
@@ -63,7 +66,7 @@ schematic.saved = Schéma enregistré.
|
|||||||
schematic.delete.confirm = Ce schéma sera supprimé définitivement.
|
schematic.delete.confirm = Ce schéma sera supprimé définitivement.
|
||||||
schematic.rename = Renommer le Schéma
|
schematic.rename = Renommer le Schéma
|
||||||
schematic.info = {0}x{1}, {2} blocs
|
schematic.info = {0}x{1}, {2} blocs
|
||||||
schematic.disabled = [scarlet] Schémas désactivés![]\nVous n'êtes pas autorisés à utiliser des schémas sur cette [accent]cartemap[] ou ce [accent]serveur.
|
schematic.disabled = [scarlet]Schémas désactivés![]\nVous n'êtes pas autorisés à utiliser des schémas sur cette [accent]carte[] ou dans ce [accent]serveur.
|
||||||
|
|
||||||
stats = Stats
|
stats = Stats
|
||||||
stat.wave = Vagues vaincues:[accent] {0}
|
stat.wave = Vagues vaincues:[accent] {0}
|
||||||
@@ -84,8 +87,8 @@ coreattack = [scarlet]< Le Noyau est attaqué! >
|
|||||||
nearpoint = [[ [scarlet]QUITTEZ LE POINT D'APPARITION ENNEMI IMMÉDIATEMENT[] ]\nannihilation imminente
|
nearpoint = [[ [scarlet]QUITTEZ LE POINT D'APPARITION ENNEMI IMMÉDIATEMENT[] ]\nannihilation imminente
|
||||||
database = Base de données
|
database = Base de données
|
||||||
savegame = Sauvegarder la partie
|
savegame = Sauvegarder la partie
|
||||||
loadgame = Charger la partie
|
loadgame = Charger une partie
|
||||||
joingame = Rejoindre la partie
|
joingame = Rejoindre une partie
|
||||||
customgame = Partie personnalisée
|
customgame = Partie personnalisée
|
||||||
newgame = Nouvelle partie
|
newgame = Nouvelle partie
|
||||||
none = <Vide>
|
none = <Vide>
|
||||||
@@ -116,8 +119,10 @@ mods.none = [lightgray]Aucun Mod trouvé!
|
|||||||
mods.guide = Guide de Modding
|
mods.guide = Guide de Modding
|
||||||
mods.report = Signaler un Bug
|
mods.report = Signaler un Bug
|
||||||
mods.openfolder = Ouvrir le Dossier
|
mods.openfolder = Ouvrir le Dossier
|
||||||
|
mods.viewcontent = Voir le Contenu
|
||||||
mods.reload = Relancer
|
mods.reload = Relancer
|
||||||
mods.reloadexit = Le jeu va se fermer pour relancer les mods.
|
mods.reloadexit = Le jeu va se fermer pour relancer les mods.
|
||||||
|
mod.installed = [[Installé]
|
||||||
mod.display = [gray]Mod:[orange] {0}
|
mod.display = [gray]Mod:[orange] {0}
|
||||||
mod.enabled = [lightgray]Activé
|
mod.enabled = [lightgray]Activé
|
||||||
mod.disabled = [scarlet]Désactivé
|
mod.disabled = [scarlet]Désactivé
|
||||||
@@ -125,7 +130,7 @@ mod.disable = Désactiver
|
|||||||
mod.content = Contenu:
|
mod.content = Contenu:
|
||||||
mod.delete.error = Impossible de supprimer le mod. Le fichier est probablement en cours d'utilisation.
|
mod.delete.error = Impossible de supprimer le mod. Le fichier est probablement en cours d'utilisation.
|
||||||
mod.requiresversion = [scarlet]Version minimale du jeu requise : [accent]{0}
|
mod.requiresversion = [scarlet]Version minimale du jeu requise : [accent]{0}
|
||||||
mod.outdated = [scarlet]non compatible avec la V6 (no minGameVersion: 105)
|
mod.outdated = [scarlet]Non compatible avec la V6 (no minGameVersion: 105)
|
||||||
mod.missingdependencies = [scarlet]Dépendances manquantes: {0}
|
mod.missingdependencies = [scarlet]Dépendances manquantes: {0}
|
||||||
mod.erroredcontent = [scarlet]Erreurs de contenu
|
mod.erroredcontent = [scarlet]Erreurs de contenu
|
||||||
mod.errors = Des erreurs se sont produites lors du chargement du contenu.
|
mod.errors = Des erreurs se sont produites lors du chargement du contenu.
|
||||||
@@ -137,7 +142,7 @@ mod.reloadrequired = [scarlet]Redémarrage requis
|
|||||||
mod.import = Importer un mod
|
mod.import = Importer un mod
|
||||||
mod.import.file = Importer un fichier
|
mod.import.file = Importer un fichier
|
||||||
mod.import.github = Importer un mod depuis GitHub
|
mod.import.github = Importer un mod depuis GitHub
|
||||||
mod.jarwarn = [scarlet]Les mods JAR sont par nature peu sûrs.[]\nFaites en sorte d'Importer ce mod depuis une source digne de confiance.
|
mod.jarwarn = [scarlet]Les mods JAR sont par nature peu sûrs.[]\nFaites en sorte d'importer ce mod depuis une source digne de confiance.
|
||||||
mod.item.remove = Cet objet fait partie du mod[accent] '{0}'[]. Pour le supprimer, désinstallez le mod en question.
|
mod.item.remove = Cet objet fait partie du mod[accent] '{0}'[]. Pour le supprimer, désinstallez le mod en question.
|
||||||
mod.remove.confirm = Ce mod sera supprimé.
|
mod.remove.confirm = Ce mod sera supprimé.
|
||||||
mod.author = [lightgray]Auteur:[] {0}
|
mod.author = [lightgray]Auteur:[] {0}
|
||||||
@@ -148,7 +153,7 @@ mod.scripts.disable = Votre appareil ne prend pas an charge les mods avec des sc
|
|||||||
|
|
||||||
about.button = À propos
|
about.button = À propos
|
||||||
name = Nom:
|
name = Nom:
|
||||||
noname = Commencez par choisir un[accent] pseudo[].
|
noname = Commencez par choisir un[accent] nom[].
|
||||||
planetmap = Carte de la planète
|
planetmap = Carte de la planète
|
||||||
launchcore = Lancer le Noyau
|
launchcore = Lancer le Noyau
|
||||||
filename = Nom du fichier:
|
filename = Nom du fichier:
|
||||||
@@ -156,8 +161,8 @@ unlocked = Nouveau contenu débloqué!
|
|||||||
available = Nouvelle recherche disponible!
|
available = Nouvelle recherche disponible!
|
||||||
completed = [accent]Complété
|
completed = [accent]Complété
|
||||||
techtree = Arbre technologique
|
techtree = Arbre technologique
|
||||||
research.legacy = Données de recherche de la [accent]5.0[] trouvées.\nVoulez-vous [accent]charger les données[] ou [accent]les ignorer[] et recommencer la recherche dans la nouvelle campagne? (recommandé)
|
research.legacy = Des données de recherche de la [accent]5.0[] ont été trouvées.\nVoulez-vous [accent]charger ces données[] ou [accent]les ignorer[] et recommencer la recherche dans la nouvelle campagne? (recommandé)
|
||||||
research.load = Chargement
|
research.load = Charger
|
||||||
research.discard = Ignorer
|
research.discard = Ignorer
|
||||||
research.list = [lightgray]Recherche:
|
research.list = [lightgray]Recherche:
|
||||||
research = Rechercher
|
research = Rechercher
|
||||||
@@ -176,7 +181,7 @@ server.kicked.clientOutdated = Client obsolète! Mettez votre jeu à jour!
|
|||||||
server.kicked.serverOutdated = Serveur obsolète! Demandez à l'hôte de le mettre à jour!
|
server.kicked.serverOutdated = Serveur obsolète! Demandez à l'hôte de le mettre à jour!
|
||||||
server.kicked.banned = Vous avez été banni de ce serveur.
|
server.kicked.banned = Vous avez été banni de ce serveur.
|
||||||
server.kicked.typeMismatch = Ce serveur n'est pas compatible avec votre version du jeu.
|
server.kicked.typeMismatch = Ce serveur n'est pas compatible avec votre version du jeu.
|
||||||
server.kicked.playerLimit = Ce serveur est complet. Attendez qu'une place se libére.
|
server.kicked.playerLimit = Ce serveur est complet. Attendez qu'une place se libère.
|
||||||
server.kicked.recentKick = Vous avez été expulsé récemment.\nAttendez avant de vous reconnecter.
|
server.kicked.recentKick = Vous avez été expulsé récemment.\nAttendez avant de vous reconnecter.
|
||||||
server.kicked.nameInUse = Il y a déjà quelqu'un avec\nce nom sur ce serveur.
|
server.kicked.nameInUse = Il y a déjà quelqu'un avec\nce nom sur ce serveur.
|
||||||
server.kicked.nameEmpty = Votre nom est invalide.
|
server.kicked.nameEmpty = Votre nom est invalide.
|
||||||
@@ -203,9 +208,9 @@ servers.local = Serveurs locaux
|
|||||||
servers.remote = Serveurs distants
|
servers.remote = Serveurs distants
|
||||||
servers.global = Serveurs communautaires
|
servers.global = Serveurs communautaires
|
||||||
|
|
||||||
servers.disclaimer = Les serveurs communautaires ne sont [accent]pas[] gérés ou controllés par le développeur.\n\nCes serveurs peuvent contenir du contenu qui ne convient pas à tout les âges.
|
servers.disclaimer = Les serveurs communautaires ne sont [accent]pas[] gérés, ni controllés par le développeur.\n\nCes serveurs peuvent contenir du contenu qui ne convient pas à tout les âges.
|
||||||
servers.showhidden = Montrer les serveurs cachés
|
servers.showhidden = Montrer les serveurs cachés
|
||||||
server.shown = Montré
|
server.shown = Visible
|
||||||
server.hidden = Caché
|
server.hidden = Caché
|
||||||
|
|
||||||
trace = Suivre le joueur
|
trace = Suivre le joueur
|
||||||
@@ -307,6 +312,7 @@ cancelbuilding = [accent][[{0}][] pour effacer le plan
|
|||||||
selectschematic = [accent][[{0}][] pour sélectionner+copier
|
selectschematic = [accent][[{0}][] pour sélectionner+copier
|
||||||
pausebuilding = [accent][[{0}][] pour mettre la construction en pause
|
pausebuilding = [accent][[{0}][] pour mettre la construction en pause
|
||||||
resumebuilding = [scarlet][[{0}][] pour reprendre la construction
|
resumebuilding = [scarlet][[{0}][] pour reprendre la construction
|
||||||
|
enablebuilding = [scarlet][[{0}][] pour activer la construction
|
||||||
showui = Interface cachée.\nPressez [accent][[{0}][] pour montrer l'interface.
|
showui = Interface cachée.\nPressez [accent][[{0}][] pour montrer l'interface.
|
||||||
wave = [accent]Vague {0}
|
wave = [accent]Vague {0}
|
||||||
wave.cap = [accent]Vague {0}/{1}
|
wave.cap = [accent]Vague {0}/{1}
|
||||||
@@ -327,9 +333,9 @@ custom = Personnalisé
|
|||||||
builtin = Pré-fait
|
builtin = Pré-fait
|
||||||
map.delete.confirm = Voulez-vous vraiment supprimer cette carte? Il n'y aura pas de retour en arrière!
|
map.delete.confirm = Voulez-vous vraiment supprimer cette carte? Il n'y aura pas de retour en arrière!
|
||||||
map.random = [accent]Carte aléatoire
|
map.random = [accent]Carte aléatoire
|
||||||
map.nospawn = Cette carte ne possède pas de base pour que le joueur puisse apparaître! Ajouter un [royalNoyau orange[] sur cette carte dans l'éditeur.
|
map.nospawn = Cette carte ne possède pas de base pour que le joueur puisse apparaître! Ajouter un [accent]Noyau orange[] sur cette carte dans l'éditeur.
|
||||||
map.nospawn.pvp = Cette carte n'a pas de base ennemie pour qu'un joueur ennemi puisse y apparaître! Ajoutez au moins une base [scarlet] non-orange[] dans l'éditeur.
|
map.nospawn.pvp = Cette carte n'a pas de base ennemie pour qu'un joueur ennemi puisse y apparaître! Ajoutez au moins un Noyau[scarlet] non-orange[] dans l'éditeur.
|
||||||
map.nospawn.attack = Cette carte n'a aucune base ennemie à attaquer! Veuillez ajouter une base[scarlet] rouge[] sur cette carte dans l'éditeur.
|
map.nospawn.attack = Cette carte n'a aucune base ennemie à attaquer! Veuillez ajouter un Noyau[scarlet] rouge[] sur cette carte dans l'éditeur.
|
||||||
map.invalid = Erreur lors du chargement de la carte: carte corrompue ou invalide.
|
map.invalid = Erreur lors du chargement de la carte: carte corrompue ou invalide.
|
||||||
workshop.update = Mettre à jour
|
workshop.update = Mettre à jour
|
||||||
workshop.error = Erreur lors de la récupération des détails du Steam Workshop: {0}
|
workshop.error = Erreur lors de la récupération des détails du Steam Workshop: {0}
|
||||||
@@ -487,7 +493,7 @@ play = Jouer
|
|||||||
campaign = Campagne
|
campaign = Campagne
|
||||||
load = Charger
|
load = Charger
|
||||||
save = Sauvegarder
|
save = Sauvegarder
|
||||||
fps = IPS: {0}
|
fps = FPS: {0}
|
||||||
ping = Ping: {0}ms
|
ping = Ping: {0}ms
|
||||||
memory = Mem: {0}mb
|
memory = Mem: {0}mb
|
||||||
memory2 = Mem:\n {0}mb +\n {1}mb
|
memory2 = Mem:\n {0}mb +\n {1}mb
|
||||||
@@ -601,9 +607,9 @@ sector.craters.description = Ce cratère est une relique d'anciennes guerres. De
|
|||||||
sector.ruinousShores.description = Au-delà des déchets, se trouve le littoral. Autrefois, cet endroit abritait un réseau de défense côtière, mais il n’en reste pas grand-chose. Seules quelques structures de défense basiques sont restées intactes, tout le reste a été réduit en ferraille.\nContinuez votre exploration en redécouvrant la technologie.
|
sector.ruinousShores.description = Au-delà des déchets, se trouve le littoral. Autrefois, cet endroit abritait un réseau de défense côtière, mais il n’en reste pas grand-chose. Seules quelques structures de défense basiques sont restées intactes, tout le reste a été réduit en ferraille.\nContinuez votre exploration en redécouvrant la technologie.
|
||||||
sector.stainedMountains.description = Plus loin, à l’intérieur des terres, se trouvent des montagnes qui n'ont pas touchées par les spores.\nExploitez le Titane présent en abondance dans cette zone et apprenez comment l'utiliser.\n\nLa présence ennemie est bien plus grande ici. Ne leur donnez pas le temps d’envoyer leurs unités les plus fortes.
|
sector.stainedMountains.description = Plus loin, à l’intérieur des terres, se trouvent des montagnes qui n'ont pas touchées par les spores.\nExploitez le Titane présent en abondance dans cette zone et apprenez comment l'utiliser.\n\nLa présence ennemie est bien plus grande ici. Ne leur donnez pas le temps d’envoyer leurs unités les plus fortes.
|
||||||
sector.overgrowth.description = Étant plus proche de la source des spores, cette zone a été complètement envahie.\nL'ennemi y a établi un avant-poste. Formez des Titans et détruisez-le.
|
sector.overgrowth.description = Étant plus proche de la source des spores, cette zone a été complètement envahie.\nL'ennemi y a établi un avant-poste. Formez des Titans et détruisez-le.
|
||||||
sector.tarFields.description = La périphérie d’une zone de production de pétrole, situé entre les montagnes et le désert. L’une des rares avec des réserves de goudron utilisables.\nBien qu’abandonnée, cette zone a quelques forces ennemies dangereuses à proximité. Ne les sous-estimez pas!\n\n[lightgray]Recherchez la technologie de traitement de pétrole si possible.
|
sector.tarFields.description = La périphérie d’une zone de production de pétrole, situé entre les montagnes et le désert. L’une des rares avec des réserves de goudron utilisables.\nBien qu’abandonnée, quelques forces ennemies dangereuses se trouvent à proximité. Ne les sous-estimez pas!\n\n[lightgray]Recherchez la technologie de traitement de pétrole si possible.
|
||||||
sector.desolateRift.description = Une zone extrêmement dangereuse. Des ressources abondantes, mais peu d’espace. Un risque élevé de destruction donc partez dès que possible! Ne vous laissez surtout pas berner par le long temps d'attente entre les vagues ennemies. Vous risquerez de le regretter.
|
sector.desolateRift.description = Une zone extrêmement dangereuse. Des ressources abondantes, mais peu d’espace. Un risque élevé de destruction donc partez dès que possible! Ne vous laissez surtout pas berner par le long temps d'attente entre les vagues ennemies. Vous risquerez de le regretter.
|
||||||
sector.nuclearComplex.description = Une ancienne installation de production et de traitement de thorium, réduite en ruines.\n[lightgray]Faites des recherches sur le thorium et ses nombreuses utilisations.\n\nL’ennemi est présent ici en grand nombre, recherchant constamment des attaquants.
|
sector.nuclearComplex.description = Une ancienne installation de production et de traitement de thorium, réduite en ruines.\n[lightgray]Faites des recherches sur ce minerai et ses nombreuses utilisations.\n\nL’ennemi est présent ici en grand nombre, recherchant constamment des attaquants.
|
||||||
sector.fungalPass.description = Une zone de transition entre les hautes montagnes et les terres plus basses, infestées de spores. Une petite base de reconnaissance ennemie se trouve ici.\nDétruisez les 2 Noyaux ennemis en utilisant des Poingnards et des Rampeurs.
|
sector.fungalPass.description = Une zone de transition entre les hautes montagnes et les terres plus basses, infestées de spores. Une petite base de reconnaissance ennemie se trouve ici.\nDétruisez les 2 Noyaux ennemis en utilisant des Poingnards et des Rampeurs.
|
||||||
sector.biomassFacility.description = L’origine des spores. Il s’agit de l’installation dans laquelle elles ont été étudiées et initialement produites.\nRecherchez la technologie présente sur les lieux et cultivez des spores pour la production de carburant et de plastique.\n\n[lightgray]Lors de la destruction de cette installation, les spores ont été libérées. Rien dans l’écosystème local ne pouvait concurrencer un organisme aussi envahissant.
|
sector.biomassFacility.description = L’origine des spores. Il s’agit de l’installation dans laquelle elles ont été étudiées et initialement produites.\nRecherchez la technologie présente sur les lieux et cultivez des spores pour la production de carburant et de plastique.\n\n[lightgray]Lors de la destruction de cette installation, les spores ont été libérées. Rien dans l’écosystème local ne pouvait concurrencer un organisme aussi envahissant.
|
||||||
sector.windsweptIslands.description = Au delà du rivage se trouve cette chaîne d’îles reculées. Les registres montrent qu’il y avait autrefois des usines de [accent]Plastanium[].\n\nDéfendez-vous contre les unités navales ennemies, établissez-y une base et faites des recherches sur ces usines.
|
sector.windsweptIslands.description = Au delà du rivage se trouve cette chaîne d’îles reculées. Les registres montrent qu’il y avait autrefois des usines de [accent]Plastanium[].\n\nDéfendez-vous contre les unités navales ennemies, établissez-y une base et faites des recherches sur ces usines.
|
||||||
@@ -631,17 +637,17 @@ settings.clearcampaignsaves = Supprimer la Campagne
|
|||||||
settings.clearcampaignsaves.confirm = Êtes-vous sûr de vouloir supprimer toutes les sauvegardes de la campagne?
|
settings.clearcampaignsaves.confirm = Êtes-vous sûr de vouloir supprimer toutes les sauvegardes de la campagne?
|
||||||
paused = [accent]< Pause >
|
paused = [accent]< Pause >
|
||||||
clear = Effacer
|
clear = Effacer
|
||||||
banned = [scarlet]Bannis
|
banned = [scarlet]Banni
|
||||||
yes = Oui
|
yes = Oui
|
||||||
no = Non
|
no = Non
|
||||||
info.title = Info
|
info.title = Info
|
||||||
error.title = [scarlet]Une erreur s'est produite
|
error.title = [scarlet]Une erreur s'est produite
|
||||||
error.crashtitle = Une erreur s'est produite
|
error.crashtitle = Une erreur s'est produite
|
||||||
unit.nobuild = [scarlet]Cette unité ne peut construire
|
unit.nobuild = [scarlet]Cette unité ne peut pas construire
|
||||||
lastaccessed = [lightgray]Dernier accès: {0}
|
lastaccessed = [lightgray]Dernier accès: {0}
|
||||||
block.unknown = [lightgray]???
|
block.unknown = [lightgray]???
|
||||||
|
|
||||||
stat.description = But
|
stat.description = Description
|
||||||
stat.input = Ressource(s) requise(s)
|
stat.input = Ressource(s) requise(s)
|
||||||
stat.output = Ressource(s) produite(s)
|
stat.output = Ressource(s) produite(s)
|
||||||
stat.booster = Boosteur
|
stat.booster = Boosteur
|
||||||
@@ -678,6 +684,7 @@ stat.drillspeed = Vitesse de forage de Base
|
|||||||
stat.boosteffect = Effet(s) du Boost
|
stat.boosteffect = Effet(s) du Boost
|
||||||
stat.maxunits = Max d'Unités Actives
|
stat.maxunits = Max d'Unités Actives
|
||||||
stat.health = Santé
|
stat.health = Santé
|
||||||
|
stat.armor = Armure
|
||||||
stat.buildtime = Durée de construction
|
stat.buildtime = Durée de construction
|
||||||
stat.maxconsecutive = Max Consécutif
|
stat.maxconsecutive = Max Consécutif
|
||||||
stat.buildcost = Coût de construction
|
stat.buildcost = Coût de construction
|
||||||
@@ -693,6 +700,7 @@ stat.lightningchance = Chance d'Éclairs
|
|||||||
stat.lightningdamage = Dégats des Éclairs
|
stat.lightningdamage = Dégats des Éclairs
|
||||||
stat.flammability = Inflammabilité
|
stat.flammability = Inflammabilité
|
||||||
stat.radioactivity = Radioactivité
|
stat.radioactivity = Radioactivité
|
||||||
|
stat.charge = Charge
|
||||||
stat.heatcapacity = Capacité Thermique
|
stat.heatcapacity = Capacité Thermique
|
||||||
stat.viscosity = Viscosité
|
stat.viscosity = Viscosité
|
||||||
stat.temperature = Température
|
stat.temperature = Température
|
||||||
@@ -709,7 +717,7 @@ stat.ammouse = Utilisation de munitions
|
|||||||
|
|
||||||
ability.forcefield = Champ de Force
|
ability.forcefield = Champ de Force
|
||||||
ability.repairfield = Champ de Réparation
|
ability.repairfield = Champ de Réparation
|
||||||
ability.statusfield = Champ de statut
|
ability.statusfield = Champ d'Amélioration
|
||||||
ability.unitspawn = Usine de {0}
|
ability.unitspawn = Usine de {0}
|
||||||
ability.shieldregenfield = Champ de regénération de bouclier
|
ability.shieldregenfield = Champ de regénération de bouclier
|
||||||
ability.movelightning = Déplacement éclair
|
ability.movelightning = Déplacement éclair
|
||||||
@@ -736,7 +744,7 @@ bar.progress = Construction en cours
|
|||||||
bar.input = Entrée
|
bar.input = Entrée
|
||||||
bar.output = Sortie
|
bar.output = Sortie
|
||||||
|
|
||||||
units.processorcontrol = [lightgray]Contrôlée par un processeur
|
units.processorcontrol = [lightgray]Contrôlé par un processeur
|
||||||
|
|
||||||
bullet.damage = [stat]{0}[lightgray] dégâts
|
bullet.damage = [stat]{0}[lightgray] dégâts
|
||||||
bullet.splashdamage = [stat]{0}[lightgray] dégâts de zone ~[stat] {1}[lightgray] blocs
|
bullet.splashdamage = [stat]{0}[lightgray] dégâts de zone ~[stat] {1}[lightgray] blocs
|
||||||
@@ -775,8 +783,8 @@ unit.thousands = k
|
|||||||
unit.millions = mil
|
unit.millions = mil
|
||||||
unit.billions = Md
|
unit.billions = Md
|
||||||
unit.pershot = /tirs
|
unit.pershot = /tirs
|
||||||
category.purpose = But
|
category.purpose = Description
|
||||||
category.general = Général
|
category.general = Caractéristiques
|
||||||
category.power = Énergie
|
category.power = Énergie
|
||||||
category.liquids = Liquides
|
category.liquids = Liquides
|
||||||
category.items = Objets
|
category.items = Objets
|
||||||
@@ -788,6 +796,7 @@ setting.shadows.name = Ombres
|
|||||||
setting.blockreplace.name = Suggestion automatique des Blocs
|
setting.blockreplace.name = Suggestion automatique des Blocs
|
||||||
setting.linear.name = Filtrage linéaire
|
setting.linear.name = Filtrage linéaire
|
||||||
setting.hints.name = Astuces
|
setting.hints.name = Astuces
|
||||||
|
setting.logichints.name = Astuces pour les commandes des processeurs
|
||||||
setting.flow.name = Afficher le Débit des ressources
|
setting.flow.name = Afficher le Débit des ressources
|
||||||
setting.backgroundpause.name = Pause en Arrière-plan
|
setting.backgroundpause.name = Pause en Arrière-plan
|
||||||
setting.buildautopause.name = Confirmation avant construction
|
setting.buildautopause.name = Confirmation avant construction
|
||||||
@@ -799,10 +808,10 @@ setting.indicators.name = Indicateurs ennemis
|
|||||||
setting.autotarget.name = Visée automatique
|
setting.autotarget.name = Visée automatique
|
||||||
setting.keyboard.name = Contrôles Souris+Clavier
|
setting.keyboard.name = Contrôles Souris+Clavier
|
||||||
setting.touchscreen.name = Commandes d'écran tactile
|
setting.touchscreen.name = Commandes d'écran tactile
|
||||||
setting.fpscap.name = Max IPS
|
setting.fpscap.name = Max FPS
|
||||||
setting.fpscap.none = Illimité
|
setting.fpscap.none = Illimité
|
||||||
setting.fpscap.text = {0} IPS
|
setting.fpscap.text = {0} FPS
|
||||||
Échelle de l'interface[lightgray] (redémarrage du jeu nécessaire)[]
|
setting.uiscale.name = Échelle de l'interface[lightgray] (redémarrage du jeu nécessaire)[]
|
||||||
setting.swapdiagonal.name = Autoriser le placement en diagonale
|
setting.swapdiagonal.name = Autoriser le placement en diagonale
|
||||||
setting.difficulty.training = Entraînement
|
setting.difficulty.training = Entraînement
|
||||||
setting.difficulty.easy = Facile
|
setting.difficulty.easy = Facile
|
||||||
@@ -821,7 +830,7 @@ setting.seconds = {0} secondes
|
|||||||
setting.milliseconds = {0} millisecondes
|
setting.milliseconds = {0} millisecondes
|
||||||
setting.fullscreen.name = Plein Écran
|
setting.fullscreen.name = Plein Écran
|
||||||
setting.borderlesswindow.name = Fenêtre sans bords[lightgray] (peut nécessiter le redémarrage du jeu)
|
setting.borderlesswindow.name = Fenêtre sans bords[lightgray] (peut nécessiter le redémarrage du jeu)
|
||||||
setting.fps.name = Afficher IPS et Ping
|
setting.fps.name = Afficher FPS et Ping
|
||||||
setting.smoothcamera.name = Lissage de la Caméra
|
setting.smoothcamera.name = Lissage de la Caméra
|
||||||
setting.vsync.name = Synchronisation Verticale
|
setting.vsync.name = Synchronisation Verticale
|
||||||
setting.pixelate.name = Pixeliser
|
setting.pixelate.name = Pixeliser
|
||||||
@@ -858,7 +867,7 @@ category.blocks.name = Sélection des blocs
|
|||||||
command.attack = Attaquer
|
command.attack = Attaquer
|
||||||
command.rally = Rallier
|
command.rally = Rallier
|
||||||
command.retreat = Retraite
|
command.retreat = Retraite
|
||||||
command.idle = Pause
|
command.idle = Inactif
|
||||||
placement.blockselectkeys = \n[lightgray]Raccourci: [{0},
|
placement.blockselectkeys = \n[lightgray]Raccourci: [{0},
|
||||||
keybind.respawn.name = Réapparaître
|
keybind.respawn.name = Réapparaître
|
||||||
keybind.control.name = Controler une Unité
|
keybind.control.name = Controler une Unité
|
||||||
@@ -948,6 +957,8 @@ rules.blockdamagemultiplier = Multiplicateur de Dégât des Blocs
|
|||||||
rules.unitbuildspeedmultiplier = Multiplicateur de Vitesse de Construction des Unités
|
rules.unitbuildspeedmultiplier = Multiplicateur de Vitesse de Construction des Unités
|
||||||
rules.unithealthmultiplier = Multiplicateur de Santé des Unités
|
rules.unithealthmultiplier = Multiplicateur de Santé des Unités
|
||||||
rules.unitdamagemultiplier = Multiplicateur de Dégât des Unités
|
rules.unitdamagemultiplier = Multiplicateur de Dégât des Unités
|
||||||
|
rules.unitcapvariable = Les Noyaux contribuent à la limite d'Unités actives
|
||||||
|
rules.unitcap = Limite d'Unités actives de Base
|
||||||
rules.enemycorebuildradius = Périmètre de Non-Construction autour du Noyau ennemi:[lightgray] (blocs)
|
rules.enemycorebuildradius = Périmètre de Non-Construction autour du Noyau ennemi:[lightgray] (blocs)
|
||||||
rules.wavespacing = Temps entre les Vagues:[lightgray] (sec)
|
rules.wavespacing = Temps entre les Vagues:[lightgray] (sec)
|
||||||
rules.buildcostmultiplier = Multiplicateur du prix de construction
|
rules.buildcostmultiplier = Multiplicateur du prix de construction
|
||||||
@@ -1140,7 +1151,7 @@ block.router.name = Routeur
|
|||||||
block.distributor.name = Distributeur
|
block.distributor.name = Distributeur
|
||||||
block.sorter.name = Trieur
|
block.sorter.name = Trieur
|
||||||
block.inverted-sorter.name = Trieur Inversé
|
block.inverted-sorter.name = Trieur Inversé
|
||||||
block.message.name = Message
|
block.message.name = Bloc de Message
|
||||||
block.illuminator.name = Illuminateur
|
block.illuminator.name = Illuminateur
|
||||||
block.overflow-gate.name = Barrière de Débordement
|
block.overflow-gate.name = Barrière de Débordement
|
||||||
block.underflow-gate.name = Barrière de Refoulement
|
block.underflow-gate.name = Barrière de Refoulement
|
||||||
@@ -1249,7 +1260,7 @@ block.logic-processor.name = Processeur
|
|||||||
block.hyper-processor.name = Hyper Processeur
|
block.hyper-processor.name = Hyper Processeur
|
||||||
block.logic-display.name = Écran
|
block.logic-display.name = Écran
|
||||||
block.large-logic-display.name = Grand Écran
|
block.large-logic-display.name = Grand Écran
|
||||||
block.memory-cell.name = Bloc de mémoire
|
block.memory-cell.name = Cellule de mémoire
|
||||||
block.memory-bank.name = Banque de mémoire
|
block.memory-bank.name = Banque de mémoire
|
||||||
|
|
||||||
team.blue.name = bleu
|
team.blue.name = bleu
|
||||||
@@ -1286,8 +1297,8 @@ hint.schematicSelect = Retenez [accent][[F][] pour sélectionner des blocs dans
|
|||||||
hint.conveyorPathfind = Retenez [accent][[Ctrl-gauche][] pendant que vous placez des convoyeurs, afin de générer un chemin automatiquement.
|
hint.conveyorPathfind = Retenez [accent][[Ctrl-gauche][] pendant que vous placez des convoyeurs, afin de générer un chemin automatiquement.
|
||||||
hint.conveyorPathfind.mobile = Activez le mode \ue844 [accent]Diagonale[] et déplacez des convoyeurs, afin de générer un chemin automatiquement.
|
hint.conveyorPathfind.mobile = Activez le mode \ue844 [accent]Diagonale[] et déplacez des convoyeurs, afin de générer un chemin automatiquement.
|
||||||
hint.boost = Retenez [accent][[Maj-gauche][] pour voler au-dessus des obstacles avec votre unité actuelle.\n\nSeules quelques unités terrestres peuvent voler.
|
hint.boost = Retenez [accent][[Maj-gauche][] pour voler au-dessus des obstacles avec votre unité actuelle.\n\nSeules quelques unités terrestres peuvent voler.
|
||||||
hint.command = Pressez [accent][[G][] pour commander les unités proches d'un [accent]type similaire[] et bouger une formation.\n\nSeules les unités terrestres peuvent controller d'autres unités terrestres.
|
hint.command = Pressez [accent][[G][] pour commander les unités proches d'un [accent]type similaire[] et bouger en formation.\n\nSeules les unités terrestres peuvent controller d'autres unités terrestres.
|
||||||
hint.command.mobile = [accent][[Tapez][] 2 fois votre unité pour commander les unités proches d'un [accent]type similaire[] et bouger une formation.
|
hint.command.mobile = [accent][[Tapez][] 2 fois votre unité pour commander les unités proches d'un [accent]type similaire[] et bouger en formation.
|
||||||
hint.payloadPickup = Pressez [accent][[[] pour transporter des blocs ou des unités.
|
hint.payloadPickup = Pressez [accent][[[] pour transporter des blocs ou des unités.
|
||||||
hint.payloadPickup.mobile = [accent]Tapez et retenez[] votre doigt pour transporter des blocs ou des unités.
|
hint.payloadPickup.mobile = [accent]Tapez et retenez[] votre doigt pour transporter des blocs ou des unités.
|
||||||
hint.payloadDrop = Pressez [accent]][] pour larguer votre chargement.
|
hint.payloadDrop = Pressez [accent]][] pour larguer votre chargement.
|
||||||
@@ -1363,8 +1374,8 @@ block.thorium-wall.description = Un bloc défensif puissant.\nProcure une très
|
|||||||
block.thorium-wall-large.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les attaques ennemies.
|
block.thorium-wall-large.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les attaques ennemies.
|
||||||
block.phase-wall.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes.
|
block.phase-wall.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes.
|
||||||
block.phase-wall-large.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes.
|
block.phase-wall-large.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes.
|
||||||
block.surge-wall.description = Le plus puissant bloc défensif.\nA une faible chance de créer des éclairs vers les ennemis.
|
block.surge-wall.description = Le plus puissant bloc défensif.\nA une faible chance d'envoyer des éclairs vers les ennemis.
|
||||||
block.surge-wall-large.description = Le plus puissant bloc défensif.\nA une faible chance de créer des éclairs vers les ennemis.
|
block.surge-wall-large.description = Le plus puissant bloc défensif.\nA une faible chance d'envoyer des éclairs vers les ennemis.
|
||||||
block.door.description = Une petite porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers.
|
block.door.description = Une petite porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers.
|
||||||
block.door-large.description = Une grande porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers.
|
block.door-large.description = Une grande porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers.
|
||||||
block.mender.description = Soigne périodiquement les bâtiments autour de lui, ce qui permet de remettre les défenses en bon état entre les vagues ennemies.\nPeut utiliser du silicium pour booster la portée et l'efficacité.
|
block.mender.description = Soigne périodiquement les bâtiments autour de lui, ce qui permet de remettre les défenses en bon état entre les vagues ennemies.\nPeut utiliser du silicium pour booster la portée et l'efficacité.
|
||||||
@@ -1374,7 +1385,7 @@ block.force-projector.description = Crée un champ de force hexagonal autour de
|
|||||||
block.shock-mine.description = Blesse les ennemis qui marchent dessus.
|
block.shock-mine.description = Blesse les ennemis qui marchent dessus.
|
||||||
block.conveyor.description = Convoyeur basique servant à transporter des objets. Les objets déplacés en avant sont automatiquement déposés dans les tourelles ou les bâtiments. Peut être tourné.
|
block.conveyor.description = Convoyeur basique servant à transporter des objets. Les objets déplacés en avant sont automatiquement déposés dans les tourelles ou les bâtiments. Peut être tourné.
|
||||||
block.titanium-conveyor.description = Convoyeur avancé. Déplace les objets plus rapidement que les convoyeurs standards.
|
block.titanium-conveyor.description = Convoyeur avancé. Déplace les objets plus rapidement que les convoyeurs standards.
|
||||||
block.plastanium-conveyor.description = Convoyeur transportant les ressources par paquets. Accepte les ressources par derrière et les déchargent par 3 directions à l'avant. Pour une efficacité maximale, utilisez plusieurs points de chargement et de déchargement pour une même ligne.
|
block.plastanium-conveyor.description = Convoyeur transportant les ressources par paquets. Accepte les ressources par derrière et les décharge par 3 directions à l'avant. Pour une efficacité maximale, utilisez plusieurs points de chargement et de déchargement pour une même ligne.
|
||||||
block.junction.description = Agit comme un pont pour deux lignes de convoyeurs se croisant. Utile lorsque deux lignes de convoyeurs différentes déplacent différents matériaux à différents endroits.
|
block.junction.description = Agit comme un pont pour deux lignes de convoyeurs se croisant. Utile lorsque deux lignes de convoyeurs différentes déplacent différents matériaux à différents endroits.
|
||||||
block.bridge-conveyor.description = Bloc de transport avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment.
|
block.bridge-conveyor.description = Bloc de transport avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment.
|
||||||
block.phase-conveyor.description = Convoyeur très avancé. Utilise de l'énergie pour téléporter des objets à un autre convoyeur phasé. Possède une longue portée.
|
block.phase-conveyor.description = Convoyeur très avancé. Utilise de l'énergie pour téléporter des objets à un autre convoyeur phasé. Possède une longue portée.
|
||||||
@@ -1393,13 +1404,13 @@ block.conduit.description = Bloc de transport de liquide de base, faisant avance
|
|||||||
block.pulse-conduit.description = Conduit avancé permettant le transport de liquide. Transporte les liquides plus rapidement et en stocke plus que les conduits standards.
|
block.pulse-conduit.description = Conduit avancé permettant le transport de liquide. Transporte les liquides plus rapidement et en stocke plus que les conduits standards.
|
||||||
block.plated-conduit.description = Déplace les liquides au même rythme que les conduits à impulsion, mais est renforcé et empêche les fuites en cas de rupture. N'accepte pas les liquides provenant des côtés, seuls les autres conduits peuvent le faire.
|
block.plated-conduit.description = Déplace les liquides au même rythme que les conduits à impulsion, mais est renforcé et empêche les fuites en cas de rupture. N'accepte pas les liquides provenant des côtés, seuls les autres conduits peuvent le faire.
|
||||||
block.liquid-router.description = Accepte les liquides depuis une direction et les distribue jusqu'à 3 directions équitablement. Utile pour envoyer un liquide à plusieurs endroits. Peut aussi stocker une certaine quantité de liquide.
|
block.liquid-router.description = Accepte les liquides depuis une direction et les distribue jusqu'à 3 directions équitablement. Utile pour envoyer un liquide à plusieurs endroits. Peut aussi stocker une certaine quantité de liquide.
|
||||||
block.liquid-tank.description = Stocke une grande quantité de liquide et peut les distribuer dans tous les côtés, un peu comme un routeur liquide.\nUtile pour réguler la sortie quand la demande en liquide si elle est inconstante ou comme sécurité pour refroidir des bâtiments importants.
|
block.liquid-tank.description = Stocke une grande quantité de liquide et peut les distribuer dans tous les côtés, un peu comme un routeur liquide.\nUtile pour réguler la demande en liquide si elle est inconstante ou comme sécurité pour refroidir des bâtiments importants.
|
||||||
block.liquid-junction.description = Agit comme un pont pour deux conduits se croisant. Utile si deux conduits amènent différents liquides à différents endroits.
|
block.liquid-junction.description = Agit comme un pont pour deux conduits se croisant. Utile si deux conduits amènent différents liquides à différents endroits.
|
||||||
block.bridge-conduit.description = Bloc de transport de liquide avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment.
|
block.bridge-conduit.description = Bloc de transport de liquide avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment.
|
||||||
block.phase-conduit.description = Conduit très avancé permettant le transport de liquide. Utilise de l'énergie pour téléporter les liquides à un autre conduit phasé sur une longue distance.
|
block.phase-conduit.description = Conduit très avancé permettant le transport de liquide. Utilise de l'énergie pour téléporter les liquides à un autre conduit phasé sur une longue distance.
|
||||||
block.power-node.description = Transmet de l'énergie aux autres transmetteurs énergétiques connectés. Le transmetteur recevra de l'énergie ou la transmettra à n'importe quel bâtiment adjacent. La connexion peut être activée/désactivée manuellement.
|
block.power-node.description = Transmet de l'énergie aux autres transmetteurs énergétiques connectés. Le transmetteur recevra de l'énergie ou la transmettra à n'importe quel bâtiment adjacent. La connexion peut être activée/désactivée manuellement.
|
||||||
block.power-node-large.description = Ce transmetteur possède un rayon plus grand que le transmetteur énergétique standard. Il peut aussi accepter plus de connexions.
|
block.power-node-large.description = Ce transmetteur possède un rayon plus grand que le transmetteur énergétique standard. Il peut aussi accepter plus de connexions.
|
||||||
block.surge-tower.description = Un transmetteur énergétique de très grande portée mais avec moins de connections disponibles.
|
block.surge-tower.description = Un transmetteur énergétique à très grande portée mais avec moins de connections disponibles.
|
||||||
block.diode.description = L'énergie ne circule que dans un sens à travers ce bloc, et uniquement si l’autre côté présente moins d’énergie en stock. Idéal pour protéger les lieux de production d'énergie.
|
block.diode.description = L'énergie ne circule que dans un sens à travers ce bloc, et uniquement si l’autre côté présente moins d’énergie en stock. Idéal pour protéger les lieux de production d'énergie.
|
||||||
block.battery.description = Stocke le surplus d'énergie et le redistribue en cas de besoin.
|
block.battery.description = Stocke le surplus d'énergie et le redistribue en cas de besoin.
|
||||||
block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale.
|
block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale.
|
||||||
@@ -1418,7 +1429,7 @@ block.laser-drill.description = Permet de forer bien plus vite grâce à la tech
|
|||||||
block.blast-drill.description = La Foreuse ultime. Demande une grande quantité d'énergie pour fonctionner.
|
block.blast-drill.description = La Foreuse ultime. Demande une grande quantité d'énergie pour fonctionner.
|
||||||
block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'étendue d'eau à proximité.
|
block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'étendue d'eau à proximité.
|
||||||
block.cultivator.description = Cultive une petite quantité de spores atmosphériques afin de former des bulbes sporifères.
|
block.cultivator.description = Cultive une petite quantité de spores atmosphériques afin de former des bulbes sporifères.
|
||||||
block.cultivator.details = Technologie de récupération. Utilisée pour produire des quantités massives de biomasse aussi efficacement que possible. Probablement l’incubateur initial des spores qui couvrent maintenant Serpulo.
|
block.cultivator.details = Technologie de récupération. Utilisée pour produire des quantités massives de biomasse aussi efficacement que possible. Probablement l’incubateur initial des spores, qui couvrent maintenant Serpulo.
|
||||||
block.oil-extractor.description = Utilise de grandes quantités d'énergie pour extraire le pétrole du sable. Utilisez-le lorsqu'il n'y a pas de source directe de pétrole à proximité.
|
block.oil-extractor.description = Utilise de grandes quantités d'énergie pour extraire le pétrole du sable. Utilisez-le lorsqu'il n'y a pas de source directe de pétrole à proximité.
|
||||||
block.core-shard.description = Le coeur de votre base. Une fois détruit, le secteur est perdu. Ne laissez pas cela arriver.
|
block.core-shard.description = Le coeur de votre base. Une fois détruit, le secteur est perdu. Ne laissez pas cela arriver.
|
||||||
block.core-shard.details = La première version du Noyau. Il est compact, doté d'un module d'auto-réplication et est équippé de propulseurs de lancement à usage unique. Equipped with single-use launch thrusters. Ceux-ci n'ont pas été conçus pour le voyage interplanétaire.
|
block.core-shard.details = La première version du Noyau. Il est compact, doté d'un module d'auto-réplication et est équippé de propulseurs de lancement à usage unique. Equipped with single-use launch thrusters. Ceux-ci n'ont pas été conçus pour le voyage interplanétaire.
|
||||||
@@ -1445,7 +1456,7 @@ block.cyclone.description = Une grande tourelle qui tire rapidement des balles e
|
|||||||
block.spectre.description = Une tourelle massive à double cannon qui tire de puissantes balles perçantes.
|
block.spectre.description = Une tourelle massive à double cannon qui tire de puissantes balles perçantes.
|
||||||
block.meltdown.description = Une tourelle massive chargeant et tirant de puissants rayons lasers. Nécessite un liquide de refroidissement.
|
block.meltdown.description = Une tourelle massive chargeant et tirant de puissants rayons lasers. Nécessite un liquide de refroidissement.
|
||||||
block.foreshadow.description = Une tourelle massive tirant une puissante balle sur une cible, sur de très longues distances. Elle vise les unités ayant le plus de santé en priorité.
|
block.foreshadow.description = Une tourelle massive tirant une puissante balle sur une cible, sur de très longues distances. Elle vise les unités ayant le plus de santé en priorité.
|
||||||
block.repair-point.description = Soigne en permanence l'unité endommagée la plus proche à proximité.
|
block.repair-point.description = Soigne l'unité endommagée la plus proche.
|
||||||
block.segment.description = Endommage et détruit les tirs ennemis. Les lasers ne peuvent pas être ciblés.
|
block.segment.description = Endommage et détruit les tirs ennemis. Les lasers ne peuvent pas être ciblés.
|
||||||
block.parallax.description = Tire un rayon tracteur qui attire les ennemis volants, infligeant aussi des dégâts.
|
block.parallax.description = Tire un rayon tracteur qui attire les ennemis volants, infligeant aussi des dégâts.
|
||||||
block.tsunami.description = Tire un puissant jet de liquide aux ennemis. Peut éteindre les incendies automatiquement si elle est alimentée en eau.
|
block.tsunami.description = Tire un puissant jet de liquide aux ennemis. Peut éteindre les incendies automatiquement si elle est alimentée en eau.
|
||||||
@@ -1453,7 +1464,7 @@ block.silicon-crucible.description = Raffine du silicium avec du sable et du cha
|
|||||||
block.disassembler.description = Cette verion avancée du séparateur peut produire du thorium.
|
block.disassembler.description = Cette verion avancée du séparateur peut produire du thorium.
|
||||||
block.overdrive-dome.description = Accélère le fonctionnement des bâtiments autour de lui. Requiert du silicium et du tissu phasé pour fonctionner.
|
block.overdrive-dome.description = Accélère le fonctionnement des bâtiments autour de lui. Requiert du silicium et du tissu phasé pour fonctionner.
|
||||||
block.payload-conveyor.description = Ce grand convoyeur peut déplacer de gros chargements, comme des unité depuis leurs usines ou bien des conteneurs.
|
block.payload-conveyor.description = Ce grand convoyeur peut déplacer de gros chargements, comme des unité depuis leurs usines ou bien des conteneurs.
|
||||||
block.payload-router.description = Distribue les chargements qui entrent dans 3 directions différentes.
|
block.payload-router.description = Distribue les chargements qui entrent jusqu'à 3 directions différentes.
|
||||||
block.command-center.description = Contrôle le comportement des unités avec plusieurs commandes différentes.
|
block.command-center.description = Contrôle le comportement des unités avec plusieurs commandes différentes.
|
||||||
block.ground-factory.description = Produit des unités terrestres. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées.
|
block.ground-factory.description = Produit des unités terrestres. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées.
|
||||||
block.air-factory.description = Produit des unités aériennes. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées.
|
block.air-factory.description = Produit des unités aériennes. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées.
|
||||||
@@ -1479,21 +1490,21 @@ unit.scepter.description = Tire un barrage de balles superchargées aux ennemis
|
|||||||
unit.reign.description = Tire un barrage de grosses balles perçantes aux ennemis proches.
|
unit.reign.description = Tire un barrage de grosses balles perçantes aux ennemis proches.
|
||||||
unit.nova.description = Tire des balles laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler.
|
unit.nova.description = Tire des balles laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler.
|
||||||
unit.pulsar.description = Tire des arcs électriques qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler.
|
unit.pulsar.description = Tire des arcs électriques qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler.
|
||||||
unit.quasar.description = Tire des faisceaux laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler et est dotée d'un champ de force.
|
unit.quasar.description = Tire des faisceaux laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler et est doté d'un champ de force.
|
||||||
unit.vela.description = Tire un rayon laser continu qui inflige des dégâts aux ennemis, cause des incendies aux structures ennemies et répare les structures alliées. Est capable de voler.
|
unit.vela.description = Tire un rayon laser continu qui inflige des dégâts aux ennemis, cause des incendies aux structures ennemies et répare les structures alliées. Est capable de voler.
|
||||||
unit.corvus.description = Tire un rayon laser massif qui inflige des dégâts aux ennemis et répare les structures alliées. Peut marcher sur de la plupart des terrains.
|
unit.corvus.description = Tire un rayon laser massif qui inflige des dégâts aux ennemis et répare les structures alliées. Peut marcher sur la plupart des terrains.
|
||||||
unit.crawler.description = Court vers un ennemi proche pour s'auto-détruire, causant une large explosion.
|
unit.crawler.description = Court vers un ennemi proche pour s'auto-détruire, causant une large explosion.
|
||||||
unit.atrax.description = Tire des orbes débilitants de scories sur des cibles terrestres. Peut marcher sur de la plupart des terrains.
|
unit.atrax.description = Tire des orbes débilitants de scories sur des cibles terrestres. Peut marcher sur la plupart des terrains.
|
||||||
unit.spiroct.description = Tire des faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur de la plupart des terrains.
|
unit.spiroct.description = Tire des faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur la plupart des terrains.
|
||||||
unit.arkyid.description = Tire de larges faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur de la plupart des terrains.
|
unit.arkyid.description = Tire de larges faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur la plupart des terrains.
|
||||||
unit.toxopid.description = Tire de larges obus électriques et des lasers perçants aux ennemis proches. Peut marcher sur de la plupart des terrains.
|
unit.toxopid.description = Tire de larges obus électriques et des lasers perçants aux ennemis proches. Peut marcher sur la plupart des terrains.
|
||||||
unit.flare.description = Tire des balles normales cibles terrestres.
|
unit.flare.description = Tire des balles normales aux cibles terrestres.
|
||||||
unit.horizon.description = Largue des bombes sur des cibles terrestres.
|
unit.horizon.description = Largue des bombes sur des cibles terrestres.
|
||||||
unit.zenith.description = Tire des salves de missiles sur les ennemis proches.
|
unit.zenith.description = Tire des salves de missiles sur les ennemis proches.
|
||||||
unit.antumbra.description = Tire un barrage de balles aux ennemis proches.
|
unit.antumbra.description = Tire un barrage de balles aux ennemis proches.
|
||||||
unit.eclipse.description = Tire 2 lasers perçants et un barrage de balles explosives aux ennemis proches.
|
unit.eclipse.description = Tire 2 lasers perçants et un barrage de balles explosives aux ennemis proches.
|
||||||
unit.mono.description = Mine automatiquement du cuivre et du plomb et le dépose dans un Noyau proche.
|
unit.mono.description = Mine automatiquement du cuivre et du plomb et le dépose dans un Noyau proche.
|
||||||
unit.poly.description = Reconstruit automatiquement les structures détruites (sauf les réacteurs au thorium) et assiste les autres unités lorsqu'elles construisent.
|
unit.poly.description = Reconstruit automatiquement les structures détruites (sauf les réacteurs à thorium) et assiste les autres unités lorsqu'elles construisent.
|
||||||
unit.mega.description = Répare automatiquement les structures endommagées. Capable de transporter des blocs et de petites unités terrestres.
|
unit.mega.description = Répare automatiquement les structures endommagées. Capable de transporter des blocs et de petites unités terrestres.
|
||||||
unit.quad.description = Largue de grosses bombes sur des cibles terrestres, réparant les structures alliées et infligeant des dégâts aux ennemis. Capable de transporter des blocs et des unités terrestres de taille moyenne.
|
unit.quad.description = Largue de grosses bombes sur des cibles terrestres, réparant les structures alliées et infligeant des dégâts aux ennemis. Capable de transporter des blocs et des unités terrestres de taille moyenne.
|
||||||
unit.oct.description = Protège les alliés proches avec son champ de force auto-regénérant. Capable de transporter des blocs et de grosses unités terrestres.
|
unit.oct.description = Protège les alliés proches avec son champ de force auto-regénérant. Capable de transporter des blocs et de grosses unités terrestres.
|
||||||
@@ -1505,3 +1516,139 @@ unit.omura.description = Tire avec un canon à rails à longue portée, une puis
|
|||||||
unit.alpha.description = Défend le Noyau fragment contre les ennemis. Peut construire des structures.
|
unit.alpha.description = Défend le Noyau fragment contre les ennemis. Peut construire des structures.
|
||||||
unit.beta.description = Défend le Noyau fondation contre les ennemis. Peut construire des structures.
|
unit.beta.description = Défend le Noyau fondation contre les ennemis. Peut construire des structures.
|
||||||
unit.gamma.description = Défend le Noyau épicentre contre les ennemis. Peut construire des structures.
|
unit.gamma.description = Défend le Noyau épicentre contre les ennemis. Peut construire des structures.
|
||||||
|
|
||||||
|
lst.read = Lit un nombre depuis un bloc de mémoire relié au processeur.
|
||||||
|
lst.write = Écrit un nombre dans un bloc de mémoire relié au processeur.
|
||||||
|
lst.print = Ajoute du texte dans la mémoire tampon de l'imprimante.\nNe montrera aucun texte tant que [accent]Print Flush[] ne sera pas utilisé.
|
||||||
|
lst.draw = Ajoute une opération dans la mémoire tampon de dessin.\nNe montrera aucune image tant que [accent]Draw Flush[] ne sera pas utilisé.
|
||||||
|
lst.drawflush = Affiche les opérations [accent]Draw[] en file d'attente vers un écran.
|
||||||
|
lst.printflush = Affiche les opérations [accent]Print[] en file d'attente vers un bloc de message.
|
||||||
|
lst.getlink = Obtient un lien de processeur par index. Commence à 0.
|
||||||
|
lst.control = Contrôle un bâtiment.
|
||||||
|
lst.radar = Localise des unités dans la portée d'un bâtiment.
|
||||||
|
lst.sensor = Récupère des données depuis un bâtiment ou une unité.
|
||||||
|
lst.set = Définit une variable.
|
||||||
|
lst.operation = Éffectue une opération sur 1 ou 2 variables.
|
||||||
|
lst.end = Saute au sommet de la série d’instructions.
|
||||||
|
lst.jump = Saute conditionnelement vers une autre instruction.
|
||||||
|
lst.unitbind = Se lie à une unité du type donné et la stocke dans [accent]@unit[].
|
||||||
|
lst.unitcontrol = Contrôle l'unité actuellement liée.
|
||||||
|
lst.unitradar = Localise des unités dans la portée de l'unité actuellement liée.
|
||||||
|
lst.unitlocate = Localise une position ou un type spécifique de bâtiment, n'importe où sur la carte.\nRequiert une unité reliée.
|
||||||
|
|
||||||
|
lenum.type = Type de bâtiment/unité.\nPar exemple, pour tout routeur, cela retournera [accent]@router[].\nPas en texte.
|
||||||
|
lenum.shoot = Tire à une position donnée.
|
||||||
|
lenum.shootp = Tire à une unité/bâtiment avec la prédiction de mouvement.
|
||||||
|
lenum.configure = La configuration d'un bâtiment. Par exemple, l'objet sélectionné dans un trieur.
|
||||||
|
lenum.enabled = Retourne si le bloc est activé ou pas.
|
||||||
|
|
||||||
|
laccess.color = La couleur d'un illuminateur.
|
||||||
|
|
||||||
|
graphicstype.clear = Remplit l’écran d’une couleur.
|
||||||
|
graphicstype.color = Définit une couleur pour les prochaines opérations de dessin.
|
||||||
|
graphicstype.stroke = Définit la largeur d'une ligne.
|
||||||
|
graphicstype.line = Dessine un segment de droite.
|
||||||
|
graphicstype.rect = Dessine un rectangle.
|
||||||
|
graphicstype.linerect = Dessine le contour d'un rectangle.
|
||||||
|
graphicstype.poly = Dessine un polygone régulier.
|
||||||
|
graphicstype.linepoly = Dessine le contour un polygone régulier.
|
||||||
|
graphicstype.triangle = Dessine un triangle.
|
||||||
|
graphicstype.image = Dessine une image venant du contenu du jeu.\nex: [accent]@router[] ou [accent]@dagger[].
|
||||||
|
|
||||||
|
lenum.always = Toujours [accent]true[].
|
||||||
|
lenum.idiv = Division entière.
|
||||||
|
lenum.div = Division.\nRetourne [accent]null[] lors d'une division par zéro.
|
||||||
|
lenum.mod = Modulo.
|
||||||
|
lenum.equal = Égalité. Conversion des types.\nLes objets non-nuls comparés avec des nombres deviennent 1, sinon 0.
|
||||||
|
lenum.notequal = Inégalité. Conversion des types.
|
||||||
|
lenum.strictequal = Égalité stricte. Ne convertit pas les types.\nPeut être utilisé pour vérifier les valeurs [accent]null[].
|
||||||
|
lenum.shl = Décalage de bits gauche.
|
||||||
|
lenum.shr = Décalage de bits droite.
|
||||||
|
lenum.or = Opération binaire OR.
|
||||||
|
lenum.land = Opération logique AND.
|
||||||
|
lenum.and = Opération binaire AND.
|
||||||
|
lenum.not = Opération binaire flip.
|
||||||
|
lenum.xor = Opération binaire XOR.
|
||||||
|
|
||||||
|
lenum.min = Le minimum des 2 nombres.
|
||||||
|
lenum.max = Le maximum des 2 nombres.
|
||||||
|
lenum.angle = Angle d'un vecteur en degrés.
|
||||||
|
lenum.len = Longueur d'un vecteur.
|
||||||
|
lenum.sin = Sinus, en degrés.
|
||||||
|
lenum.cos = Cosinus, en degrés.
|
||||||
|
lenum.tan = Tangente, en degrés.
|
||||||
|
#not a typo, look up 'range notation'
|
||||||
|
lenum.rand = Nombre aléatoire dans la plage [0, valeur].
|
||||||
|
lenum.log = Logarithme naturel (ln).
|
||||||
|
lenum.log10 = Logarithme de base 10.
|
||||||
|
lenum.noise = Bruit simplex 2D.
|
||||||
|
lenum.abs = Valeur absolue.
|
||||||
|
lenum.sqrt = Racine carrée.
|
||||||
|
|
||||||
|
lenum.any = N'importe quelle unité.
|
||||||
|
lenum.ally = Unité alliée.
|
||||||
|
lenum.attacker = Unité avec des armes.
|
||||||
|
lenum.enemy = Unité ennemie.
|
||||||
|
lenum.boss = Gardien.
|
||||||
|
lenum.flying = Unité volante.
|
||||||
|
lenum.ground = Unité terrestre.
|
||||||
|
lenum.player = Unité controllée par un joueur.
|
||||||
|
|
||||||
|
lenum.ore = Gisement de minerai.
|
||||||
|
lenum.damaged = Bâtiments alliés endommagés.
|
||||||
|
lenum.spawn = Point d'apparition ennemi.\nPeut être un noyau ou une position.
|
||||||
|
lenum.building = Bâtiment dans un groupe spécifique.
|
||||||
|
|
||||||
|
lenum.core = N'importe quel noyau.
|
||||||
|
lenum.storage = Bâtiments de stockage, un coffre-fort par exemple.
|
||||||
|
lenum.generator = Bâtiments générant de l'énergie.
|
||||||
|
lenum.factory = Bâtiments traitant des ressources.
|
||||||
|
lenum.repair = Points de réparation.
|
||||||
|
lenum.rally = Centres de commandes.
|
||||||
|
lenum.battery = N'importe quelle batterie.
|
||||||
|
lenum.resupply = Points de rechargement.\nUtile seulement lorsque [accent]"munitions"[] sont limitées.
|
||||||
|
lenum.reactor = Réacteur à Impact/Thorium.
|
||||||
|
lenum.turret = N'importe quelle tourelle.
|
||||||
|
|
||||||
|
sensor.in = Les bâtiments/unités à analyser.
|
||||||
|
|
||||||
|
radar.from = Bâtiment de détection.\nLa portée du détecteur est limitée à la portée du bâtiment.
|
||||||
|
radar.target = Filtre pour les unités à détecter.
|
||||||
|
radar.and = Filtres additionnels
|
||||||
|
radar.order = Ordre de filtrage. 0 pour inverser.
|
||||||
|
radar.sort = Valeur par laquelle les résultats sont triés.
|
||||||
|
radar.output = Variable dans laquelle écrire l'unité retournée.
|
||||||
|
|
||||||
|
unitradar.target = Filtre pour les unités à détecter.
|
||||||
|
unitradar.and = Filtres additionnels
|
||||||
|
unitradar.order = Ordre de filtrage. 0 pour inverser.
|
||||||
|
unitradar.sort = Valeur par laquelle les résultats sont triés.
|
||||||
|
unitradar.output = Variable dans laquelle écrire l'unité retournée.
|
||||||
|
|
||||||
|
control.of = Bâtiment à contrôler.
|
||||||
|
control.unit = Unité/bâtiment à viser.
|
||||||
|
control.shoot = S’il faut tirer ou non.
|
||||||
|
|
||||||
|
unitlocate.enemy = S'il faut détecter les bâtiments ennemis au non.
|
||||||
|
unitlocate.found = Retourne un boolean s'il l'objet a été trouvé ou non.
|
||||||
|
unitlocate.building = Retourne une variable pour le bâtiment localisé.
|
||||||
|
unitlocate.outx = Retourne la coordonnée X.
|
||||||
|
unitlocate.outy = Retourne la coordonnée Y.
|
||||||
|
unitlocate.group = Le groupe de bâtiments à rechercher.
|
||||||
|
|
||||||
|
lenum.stop = Empêche l'unité de bouger/miner/construire.
|
||||||
|
lenum.move = Bouge vers la position exacte.
|
||||||
|
lenum.approach = Approche une position avec un rayon.
|
||||||
|
lenum.pathfind = Détermine un itinéraire et bouge vers le point d'apparition ennemi.
|
||||||
|
lenum.target = Tire vers la position donnée.
|
||||||
|
lenum.targetp = Tire sur un cible avec la prédiction de mouvement.
|
||||||
|
lenum.itemdrop = Lâche un objet.
|
||||||
|
lenum.itemtake = Prend un objet depuis un bâtiment.
|
||||||
|
lenum.paydrop = Lâche le chargement actuel.
|
||||||
|
lenum.paytake = Prend un chargement à la position actuelle.
|
||||||
|
lenum.flag = Drapeau numérique d'une unité.
|
||||||
|
lenum.mine = Mine à une position donnée.
|
||||||
|
lenum.build = Construit une structure.
|
||||||
|
lenum.getblock = Récupère des données sur un bâtiment et son type aux coordonnées données.\nL'unité doit se trouver dans la portée de la position.\nLes blocs solides qui ne sont pas des bâtiments auront le type [accent]@solid[].
|
||||||
|
lenum.within = Vérifie si l'unité est près de la position.
|
||||||
|
lenum.boost = Active/Désactive le boost.
|
||||||
@@ -9,7 +9,7 @@ link.changelog.description = 업데이트 내용 목록
|
|||||||
link.dev-builds.description = 불안정한 개발 버전
|
link.dev-builds.description = 불안정한 개발 버전
|
||||||
link.trello.description = 출시 예정 기능 계획을 게시한 공식 Trello 보드
|
link.trello.description = 출시 예정 기능 계획을 게시한 공식 Trello 보드
|
||||||
link.itch.io.description = PC 다운로드가 있는 itch.io 페이지
|
link.itch.io.description = PC 다운로드가 있는 itch.io 페이지
|
||||||
link.google-play.description = Google Play 스토어 목록
|
link.google-play.description = oogle Play 스토어 목록
|
||||||
link.f-droid.description = F-Droid 카탈로그 목록
|
link.f-droid.description = F-Droid 카탈로그 목록
|
||||||
link.wiki.description = 공식 Mindustry 위키
|
link.wiki.description = 공식 Mindustry 위키
|
||||||
link.suggestions.description = 새 기능 제안하기
|
link.suggestions.description = 새 기능 제안하기
|
||||||
@@ -113,7 +113,7 @@ committingchanges = 바뀐 점 적용
|
|||||||
done = 완료
|
done = 완료
|
||||||
feature.unsupported = 기기가 이 기능을 지원하지 않습니다.
|
feature.unsupported = 기기가 이 기능을 지원하지 않습니다.
|
||||||
|
|
||||||
mods.alphainfo = 현재 모드는 정식 출시 버전이 아니며, [scarlet]오류가 많을 수 있습니다[].\n발견한 문제는 Mindustry Github 또는 Discord에 보고하세요.
|
mods.initfailed = [red]⚠[]이전 Mindustry 인스턴스를 초기화하지 못했습니다. 잘못된 모드로 인해 발생한 것일 수 있습니다.\n\n 게임 충돌 무한반복을 막기 위해, [red]모든 모드가 비활성화되었습니다.[]\n\n이 시스템을 비활성화할려면, [accent]설정->게임->로딩 중 충돌 시 모드 비활성화[]설정을 끄세요.
|
||||||
mods = 모드
|
mods = 모드
|
||||||
mods.none = [lightgray]모드를 찾을 수 없습니다!
|
mods.none = [lightgray]모드를 찾을 수 없습니다!
|
||||||
mods.guide = 모드 제작 가이드
|
mods.guide = 모드 제작 가이드
|
||||||
@@ -219,6 +219,8 @@ trace.ip = IP: [accent]{0}
|
|||||||
trace.id = UUID: [accent]{0}
|
trace.id = UUID: [accent]{0}
|
||||||
trace.mobile = 모바일 클라이언트: [accent]{0}
|
trace.mobile = 모바일 클라이언트: [accent]{0}
|
||||||
trace.modclient = 사용자 지정 클라이언트: [accent]{0}
|
trace.modclient = 사용자 지정 클라이언트: [accent]{0}
|
||||||
|
trace.times.joined = 입장 횟수: [accent]{0}
|
||||||
|
trace.times.kicked = 추방 횟수: [accent]{0}
|
||||||
invalidid = 잘못된 클라이언트 ID입니다! 버그 보고서를 보내주세요.
|
invalidid = 잘못된 클라이언트 ID입니다! 버그 보고서를 보내주세요.
|
||||||
server.bans = 차단 목록
|
server.bans = 차단 목록
|
||||||
server.bans.none = 차단된 플레이어를 찾을 수 없습니다!
|
server.bans.none = 차단된 플레이어를 찾을 수 없습니다!
|
||||||
@@ -800,6 +802,8 @@ setting.logichints.name = 로직 힌트 표시
|
|||||||
setting.flow.name = 자원 흐름량 표시
|
setting.flow.name = 자원 흐름량 표시
|
||||||
setting.backgroundpause.name = 백그라운드에서 일시정지
|
setting.backgroundpause.name = 백그라운드에서 일시정지
|
||||||
setting.buildautopause.name = 건설 자동 일시정지
|
setting.buildautopause.name = 건설 자동 일시정지
|
||||||
|
setting.doubletapmine.name = 연속 터치로 채광
|
||||||
|
setting.modcrashdisable.name = 로딩 중 충돌 시 모드 비활성화
|
||||||
setting.animatedwater.name = 액체 애니메이션 효과
|
setting.animatedwater.name = 액체 애니메이션 효과
|
||||||
setting.animatedshields.name = 보호막 애니메이션 효과
|
setting.animatedshields.name = 보호막 애니메이션 효과
|
||||||
setting.antialias.name = 위신호 제거 필터[lightgray] (재시작 필요)[]
|
setting.antialias.name = 위신호 제거 필터[lightgray] (재시작 필요)[]
|
||||||
@@ -1528,7 +1532,7 @@ lst.control = 건물 조종하기
|
|||||||
lst.radar = 건물 주변의 유닛 검색하기
|
lst.radar = 건물 주변의 유닛 검색하기
|
||||||
lst.sensor = 건물 또는 유닛의 정보 얻기
|
lst.sensor = 건물 또는 유닛의 정보 얻기
|
||||||
lst.set = 변수 선언/할당하기
|
lst.set = 변수 선언/할당하기
|
||||||
lst.operation = 1~2개의 변수로 연산자하기
|
lst.operation = 1~2개의 변수로 연산하기
|
||||||
lst.end = 실행줄의 가장 위로 점프하기
|
lst.end = 실행줄의 가장 위로 점프하기
|
||||||
lst.jump = 조건부로 다른 실행문으로 점프하기
|
lst.jump = 조건부로 다른 실행문으로 점프하기
|
||||||
lst.unitbind = type 옆에 있는 유닛을 지정하고, [accent]@unit[]에 저장하기
|
lst.unitbind = type 옆에 있는 유닛을 지정하고, [accent]@unit[]에 저장하기
|
||||||
@@ -1536,12 +1540,30 @@ lst.unitcontrol = 현재 지정된 유닛을 조종하기
|
|||||||
lst.unitradar = 현재 지정된 유닛 주변의 유닛 검색하기
|
lst.unitradar = 현재 지정된 유닛 주변의 유닛 검색하기
|
||||||
lst.unitlocate = 특정 유형의 위치/건물을 지도상에서 찾기\n지정된 유닛이 필요합니다.
|
lst.unitlocate = 특정 유형의 위치/건물을 지도상에서 찾기\n지정된 유닛이 필요합니다.
|
||||||
|
|
||||||
lenum.type = 건물/유닛의 타입\n예로 분배기는 [accent]@router[]를 반환할 것입니다.\n문자열이 아니라.
|
logic.nounitbuild = [red]유닛의 건물 로직은 여기서 허용되지 않습니다.
|
||||||
|
|
||||||
|
lenum.type = 건물/유닛의 타입\n예로 분배기는 문자열이 아니라 [accent]@router[]를 반환합니다.
|
||||||
lenum.shoot = 특정 위치에 발사
|
lenum.shoot = 특정 위치에 발사
|
||||||
lenum.shootp = 목표물 속도를 예측하여 발사
|
lenum.shootp = 목표물 속도를 예측하여 발사
|
||||||
lenum.configure = 필터의 아이템같은 건물의 설정
|
lenum.configure = 필터의 아이템같은 건물의 설정
|
||||||
lenum.enabled = 블록의 활성 여부
|
lenum.enabled = 블록의 활성 여부
|
||||||
|
|
||||||
lenum.color = 조명 색 설정
|
lenum.color = 조명 색 설정
|
||||||
|
laccess.controller = 유닛 제어자. 프로세서가 제어하면, 프로세서를 반환합니다.\n다른 유닛에 의해 지휘되면(G키), 지휘하는 유닛을 반환합니다.\n그 외에는 자신을 반환합니다.
|
||||||
|
laccess.dead = 유닛 또는 건물 사망/무효 여부
|
||||||
|
laccess.controlled = 만약 유닛 제어자가 프로세서라면 [accent]@ctrlProcessor[]를 반환합니다.\n만약 유닛/건물 제어자가 플레이어라면 [accent]@ctrlPlayer[]를 반환합니다.\n만약 유닛이 다른 유닛에 의해 지휘되면(G키)[accent]@ctrlFormation[]를 반환합니다.\n그 외에는 0을 반환합니다.
|
||||||
|
laccess.commanded = [red]이제 사용되지 않으며, 곧 제거될 예정입니다![]\n대신 [accent]controlled[]를 사용하세요.
|
||||||
|
|
||||||
|
graphicstype.clear = 이 색으로 화면을 채우기
|
||||||
|
graphicstype.color = 아래 그래픽 실행문들의 색 설정하기
|
||||||
|
graphicstype.stroke = 선 굵기 설정하기
|
||||||
|
graphicstype.line = 선분 그리기
|
||||||
|
graphicstype.rect = 직사각형 채우기
|
||||||
|
graphicstype.linerect = 직사각형 외곽선 그리기
|
||||||
|
graphicstype.poly = 정다각형 채우기
|
||||||
|
graphicstype.linepoly = 정다각형 외곽선 그리기
|
||||||
|
graphicstype.triangle = 삼각형 채우기
|
||||||
|
graphicstype.image = 일부 콘텐츠의 이미지 그리기\n예: [accent]@router[] 또는 [accent]@dagger[].
|
||||||
|
|
||||||
lenum.always = 항상 참
|
lenum.always = 항상 참
|
||||||
lenum.idiv = 정수 나누기
|
lenum.idiv = 정수 나누기
|
||||||
@@ -1566,7 +1588,7 @@ lenum.sin = 사인(도)
|
|||||||
lenum.cos = 코사인(도)
|
lenum.cos = 코사인(도)
|
||||||
lenum.tan = 탄젠트(도)
|
lenum.tan = 탄젠트(도)
|
||||||
#not a typo, look up 'range notation'
|
#not a typo, look up 'range notation'
|
||||||
lenum.rand = 범위 내 난수[0 ~ 값)
|
lenum.rand = 범위 내 십진법 난수[0 ~ 값)
|
||||||
lenum.log = 자연 로그(진수)
|
lenum.log = 자연 로그(진수)
|
||||||
lenum.log10 = 상수 로그
|
lenum.log10 = 상수 로그
|
||||||
lenum.noise = 2D 심플렉스 노이즈
|
lenum.noise = 2D 심플렉스 노이즈
|
||||||
@@ -1596,7 +1618,7 @@ lenum.rally = 지휘소
|
|||||||
lenum.battery = 배터리
|
lenum.battery = 배터리
|
||||||
lenum.resupply = 보급 지점.\n[accent]"유닛 탄약 필요"[]가 활성화되었을 때만 유의미합니다.
|
lenum.resupply = 보급 지점.\n[accent]"유닛 탄약 필요"[]가 활성화되었을 때만 유의미합니다.
|
||||||
lenum.reactor = 핵융합로/토륨 원자로
|
lenum.reactor = 핵융합로/토륨 원자로
|
||||||
lenum.turret = 포탑ㅁ
|
lenum.turret = 포탑
|
||||||
|
|
||||||
sensor.in = 감지할 건물/유닛
|
sensor.in = 감지할 건물/유닛
|
||||||
|
|
||||||
@@ -1624,6 +1646,7 @@ unitlocate.outx = X좌표
|
|||||||
unitlocate.outy = Y좌표
|
unitlocate.outy = Y좌표
|
||||||
unitlocate.group = 찾을 건물 집단
|
unitlocate.group = 찾을 건물 집단
|
||||||
|
|
||||||
|
lenum.idle = 채광/건설 제외 이동만 중단\n기본 상태입니다.
|
||||||
lenum.stop = 이동/채광/건설 중단
|
lenum.stop = 이동/채광/건설 중단
|
||||||
lenum.move = 특정 위치로 이동
|
lenum.move = 특정 위치로 이동
|
||||||
lenum.approach = 특정 위치로 반지름만큼 접근
|
lenum.approach = 특정 위치로 반지름만큼 접근
|
||||||
@@ -1640,3 +1663,205 @@ lenum.build = 구조물 건설
|
|||||||
lenum.getblock = 특정 좌표의 빌딩과 블록을 반환합니다.\n위치는 유닛의 인지 범위 내여야 합니다.\n자연 지형은 [accent]@solid[]의 타입을 가집니다.
|
lenum.getblock = 특정 좌표의 빌딩과 블록을 반환합니다.\n위치는 유닛의 인지 범위 내여야 합니다.\n자연 지형은 [accent]@solid[]의 타입을 가집니다.
|
||||||
lenum.within = 좌표 주변 유닛 발견 여부
|
lenum.within = 좌표 주변 유닛 발견 여부
|
||||||
lenum.boost = 이륙 시작/중단
|
lenum.boost = 이륙 시작/중단
|
||||||
|
#1665 줄 매칭
|
||||||
|
|
||||||
|
#-------------비공식 번역주-------------
|
||||||
|
#팁, 패치 기록, 약간의 관련 드립을 넣는 곳입니다. 이미 쓰여진 줄이 있다면 \n\n를 입력한 다음 작성하고 끝에 깃허브 작성자 닉네임(또는 디스코드)을 적어주세요.
|
||||||
|
#심각한 노잼, 뇌절, 무례한 말들을 적지 말아주세요, 이는 목적이 어떠하든 공통적으로 적용됩니다(친근함 유도를 위한 평어 x). 다음 패치에 업데이트되어 그 언어를 쓰는 모든 유저가 보게 됩니다.
|
||||||
|
#양이 너무 많으면 사족을 더 붙이는걸 추천하지 않습니다.
|
||||||
|
#이 비공식 번역주는 공식 디테일이 추가되면 언제든지 삭제될 수 있습니다.
|
||||||
|
#비어있는 디테일은 아래 details가 전부이므로 추가 또는 삭제를 따로 안하셔도 됩니다.
|
||||||
|
#유색코드가 아닌, 흑백 색코드만 사용 가능합니다. 되도록이면 그냥 안쓰시는걸 추천.
|
||||||
|
#관련 문의는 공식 디스코드에서 절 불러주세요. Sharlotte#0018
|
||||||
|
|
||||||
|
#아이템
|
||||||
|
item.metaglass.details = 쓰임세가 가장 적은 아이템
|
||||||
|
item.graphite.details =
|
||||||
|
item.sand.details =
|
||||||
|
item.titanium.details =
|
||||||
|
item.thorium.details =
|
||||||
|
item.silicon.details =
|
||||||
|
item.plastanium.details =
|
||||||
|
item.phase-fabric.details =
|
||||||
|
item.surge-alloy.details =
|
||||||
|
item.blast-compound.details = 화력 발전기에 넣어보세요.
|
||||||
|
item.pyratite.details =
|
||||||
|
|
||||||
|
#액체
|
||||||
|
liquid.water.details =
|
||||||
|
liquid.slag.details =
|
||||||
|
liquid.oil.details =
|
||||||
|
liquid.cryofluid.details = 티타늄을 갈아서 물에 희석했다는 소문이 있다.
|
||||||
|
|
||||||
|
#블록
|
||||||
|
block.resupply-point.details =
|
||||||
|
block.armored-conveyor.details =
|
||||||
|
block.illuminator.details =
|
||||||
|
block.message.details =
|
||||||
|
block.graphite-press.details =
|
||||||
|
block.multi-press.details =
|
||||||
|
block.silicon-smelter.details =
|
||||||
|
block.kiln.details =
|
||||||
|
block.plastanium-compressor.details = 석유를 정말 많이 먹는다.
|
||||||
|
block.phase-weaver.details =
|
||||||
|
block.alloy-smelter.details =
|
||||||
|
block.cryofluid-mixer.details =
|
||||||
|
block.blast-mixer.details =
|
||||||
|
block.pyratite-mixer.details =
|
||||||
|
block.melter.details =
|
||||||
|
block.separator.details =
|
||||||
|
block.spore-press.details =
|
||||||
|
block.pulverizer.details =
|
||||||
|
block.coal-centrifuge.details = 가성비가 매우 뛰어나다.
|
||||||
|
block.incinerator.details =
|
||||||
|
block.power-void.details =
|
||||||
|
block.power-source.details =
|
||||||
|
block.item-source.details =
|
||||||
|
block.item-void.details =
|
||||||
|
block.liquid-source.details =
|
||||||
|
block.liquid-void.details =
|
||||||
|
block.copper-wall.details =
|
||||||
|
block.copper-wall-large.details =
|
||||||
|
block.titanium-wall.details =
|
||||||
|
block.titanium-wall-large.details =
|
||||||
|
block.plastanium-wall.details =
|
||||||
|
block.plastanium-wall-large.details =
|
||||||
|
block.thorium-wall.details =
|
||||||
|
block.thorium-wall-large.details =
|
||||||
|
block.phase-wall.details =
|
||||||
|
block.phase-wall-large.details =
|
||||||
|
block.surge-wall.details =
|
||||||
|
block.surge-wall-large.details =
|
||||||
|
block.door.details =
|
||||||
|
block.door-large.details =
|
||||||
|
block.mender.details =
|
||||||
|
block.mend-projector.details =
|
||||||
|
block.overdrive-projector.details =
|
||||||
|
block.force-projector.details =
|
||||||
|
block.shock-mine.details =
|
||||||
|
block.conveyor.details =
|
||||||
|
block.titanium-conveyor.details =
|
||||||
|
block.plastanium-conveyor.details =
|
||||||
|
block.junction.details =
|
||||||
|
block.bridge-conveyor.details = 티타늄 컨베이어보다 빠르다.
|
||||||
|
block.phase-conveyor.details =
|
||||||
|
block.sorter.details = 자원을 분류하여 주변 블록에 건내는 과정이 거의 한순간에 일어난다.
|
||||||
|
block.inverted-sorter.details =
|
||||||
|
block.distributor.details =
|
||||||
|
block.overflow-gate.details =
|
||||||
|
block.underflow-gate.details =
|
||||||
|
block.mass-driver.details = 발사할려면 최소 아이템 10개가 필요하다.
|
||||||
|
block.mechanical-pump.details =
|
||||||
|
block.rotary-pump.details =
|
||||||
|
block.thermal-pump.details =
|
||||||
|
block.conduit.details =
|
||||||
|
block.pulse-conduit.details =
|
||||||
|
block.plated-conduit.details =
|
||||||
|
block.liquid-router.details =
|
||||||
|
block.liquid-tank.details =
|
||||||
|
block.liquid-junction.details =
|
||||||
|
block.bridge-conduit.details =
|
||||||
|
block.phase-conduit.details =
|
||||||
|
block.power-node.details =
|
||||||
|
block.power-node-large.details =
|
||||||
|
block.surge-tower.details =
|
||||||
|
block.diode.details =
|
||||||
|
block.battery.details =
|
||||||
|
block.battery-large.details =
|
||||||
|
block.combustion-generator.details =
|
||||||
|
block.thermal-generator.details =
|
||||||
|
block.steam-generator.details =
|
||||||
|
block.differential-generator.details =
|
||||||
|
block.rtg-generator.details =
|
||||||
|
block.solar-panel.details =
|
||||||
|
block.solar-panel-large.details =
|
||||||
|
block.thorium-reactor.details =
|
||||||
|
block.impact-reactor.details =
|
||||||
|
block.mechanical-drill.details =
|
||||||
|
block.pneumatic-drill.details =
|
||||||
|
block.laser-drill.details =
|
||||||
|
block.blast-drill.details =
|
||||||
|
block.water-extractor.details =
|
||||||
|
block.cultivator.details =
|
||||||
|
block.cultivator.details =
|
||||||
|
block.oil-extractor.details =
|
||||||
|
block.vault.details =
|
||||||
|
block.container.details =
|
||||||
|
block.unloader.details =
|
||||||
|
block.launch-pad.details =
|
||||||
|
block.duo.details =
|
||||||
|
block.scatter.details =
|
||||||
|
block.scorch.details =
|
||||||
|
block.hail.details = 일점사하면 립플보다 더 뛰어난 정확도와 연사력을 보여준다.
|
||||||
|
block.wave.details =
|
||||||
|
block.lancer.details =
|
||||||
|
block.arc.details =
|
||||||
|
block.swarmer.details =
|
||||||
|
block.salvo.details =
|
||||||
|
block.fuse.details =
|
||||||
|
block.ripple.details =
|
||||||
|
block.cyclone.details =
|
||||||
|
block.spectre.details =
|
||||||
|
block.meltdown.details =
|
||||||
|
block.foreshadow.details =
|
||||||
|
block.repair-point.details =
|
||||||
|
block.segment.details =
|
||||||
|
block.parallax.details =
|
||||||
|
block.tsunami.details =
|
||||||
|
block.silicon-crucible.details =
|
||||||
|
block.disassembler.details =
|
||||||
|
block.overdrive-dome.details =
|
||||||
|
block.payload-conveyor.details =
|
||||||
|
block.payload-router.details =
|
||||||
|
block.command-center.details =
|
||||||
|
block.ground-factory.details =
|
||||||
|
block.air-factory.details = 건설&연구 재료는 구리와 납뿐이지만, 정작 유닛을 생산할 땐 실리콘이 필요하다.
|
||||||
|
block.naval-factory.details =
|
||||||
|
block.additive-reconstructor.details =
|
||||||
|
block.multiplicative-reconstructor.details =
|
||||||
|
block.exponential-reconstructor.details =
|
||||||
|
block.tetrative-reconstructor.details =
|
||||||
|
block.switch.details =
|
||||||
|
block.micro-processor.details =
|
||||||
|
block.logic-processor.details =
|
||||||
|
block.hyper-processor.details =
|
||||||
|
block.memory-cell.details =
|
||||||
|
block.memory-bank.details =
|
||||||
|
block.logic-display.details =
|
||||||
|
block.large-logic-display.details =
|
||||||
|
block.interplanetary-accelerator.details =
|
||||||
|
|
||||||
|
#유닛
|
||||||
|
unit.dagger.details = 이전에 디거란 이명으로 종교가 생겼었다.
|
||||||
|
unit.mace.details =
|
||||||
|
unit.fortress.details =
|
||||||
|
unit.scepter.details =
|
||||||
|
unit.reign.details =
|
||||||
|
unit.nova.details =
|
||||||
|
unit.pulsar.details =
|
||||||
|
unit.quasar.details =
|
||||||
|
unit.vela.details =
|
||||||
|
unit.corvus.details = 정말 느리다.
|
||||||
|
unit.crawler.details = 최근에 자폭 AI가 향상되면서 컨베이어로 자폭을 유도할 수 없게 되었다.
|
||||||
|
unit.atrax.details =
|
||||||
|
unit.spiroct.details =
|
||||||
|
unit.arkyid.details =
|
||||||
|
unit.toxopid.details =
|
||||||
|
unit.flare.details =
|
||||||
|
unit.horizon.details =
|
||||||
|
unit.zenith.details =
|
||||||
|
unit.antumbra.details =
|
||||||
|
unit.eclipse.details =
|
||||||
|
unit.mono.details =
|
||||||
|
unit.poly.details =
|
||||||
|
unit.mega.details =
|
||||||
|
unit.quad.details =
|
||||||
|
unit.oct.details =
|
||||||
|
unit.risso.details = 뭉치면 연사력이 무시무시하다.
|
||||||
|
unit.minke.details =
|
||||||
|
unit.bryde.details =
|
||||||
|
unit.sei.details =
|
||||||
|
unit.omura.details =
|
||||||
|
unit.alpha.details =
|
||||||
|
unit.beta.details =
|
||||||
|
unit.gamma.details =
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ committingchanges = Se Încarcă Schimbările
|
|||||||
done = Gata
|
done = Gata
|
||||||
feature.unsupported = Dispozitivul tău nu suportă această funcție.
|
feature.unsupported = Dispozitivul tău nu suportă această funcție.
|
||||||
|
|
||||||
mods.alphainfo = Modurile sunt încă în alpha și[scarlet] pot avea multe buguri[].\nRaportează orice probleme apărute pe Githubul Mindustry.
|
mods.initfailed = [red]⚠[] Instanța Mindustry precedentă a eșuat la inițializare. De obicei se întâmplă din cauza unui mod care nu se acționează cum trebuie.\n\nPt a preveni un lanț de crashuri continue, [red]toate modurile au fost dezactivate.[]\n\nPoți dezactiva asta din [accent]Setări->Joc->Dezactivează Modurile în Cazul unui Crash la Pornire[].
|
||||||
mods = Moduri
|
mods = Moduri
|
||||||
mods.none = [lightgray]Nu s-au găsit moduri!
|
mods.none = [lightgray]Nu s-au găsit moduri!
|
||||||
mods.guide = Ghid de Modding
|
mods.guide = Ghid de Modding
|
||||||
@@ -216,9 +216,11 @@ server.hidden = Ascunse
|
|||||||
trace = Urmărește Jucător
|
trace = Urmărește Jucător
|
||||||
trace.playername = Nume jucător: [accent]{0}
|
trace.playername = Nume jucător: [accent]{0}
|
||||||
trace.ip = IP: [accent]{0}
|
trace.ip = IP: [accent]{0}
|
||||||
trace.id = ID unic: [accent]{0}
|
trace.id = ID: [accent]{0}
|
||||||
trace.mobile = Client Mobil: [accent]{0}
|
trace.mobile = Client Mobil: [accent]{0}
|
||||||
trace.modclient = Client Personalizat: [accent]{0}
|
trace.modclient = Client Personalizat: [accent]{0}
|
||||||
|
trace.times.joined = A Intrat: de [accent]{0}[] ori
|
||||||
|
trace.times.kicked = Dat Afară: de [accent]{0}[] ori
|
||||||
invalidid = ID client invalid! Raportează bugul.
|
invalidid = ID client invalid! Raportează bugul.
|
||||||
server.bans = Interziși
|
server.bans = Interziși
|
||||||
server.bans.none = Nu s-au găsit jucători intreziși!
|
server.bans.none = Nu s-au găsit jucători intreziși!
|
||||||
@@ -800,6 +802,8 @@ setting.logichints.name = Indicii Procesoare Logice
|
|||||||
setting.flow.name = Afișează Rata de Curgere a lichidelor
|
setting.flow.name = Afișează Rata de Curgere a lichidelor
|
||||||
setting.buildautopause.name = Autopauză de la Construit
|
setting.buildautopause.name = Autopauză de la Construit
|
||||||
setting.backgroundpause.name = Pune Pauză în Fundal
|
setting.backgroundpause.name = Pune Pauză în Fundal
|
||||||
|
setting.doubletapmine.name = Dublu-Click pt a Mina
|
||||||
|
setting.modcrashdisable.name = Dezactivează Modurile în Cazul unui Crash la Pornire
|
||||||
setting.animatedwater.name = Suprafețe Animate
|
setting.animatedwater.name = Suprafețe Animate
|
||||||
setting.animatedshields.name = Scuturi Animate
|
setting.animatedshields.name = Scuturi Animate
|
||||||
setting.antialias.name = Antialiasing[lightgray] (necesită repornire)[]
|
setting.antialias.name = Antialiasing[lightgray] (necesită repornire)[]
|
||||||
@@ -1039,7 +1043,7 @@ 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
|
||||||
unit.scepter.name = Septer
|
unit.scepter.name = Scepter
|
||||||
unit.reign.name = Reign
|
unit.reign.name = Reign
|
||||||
unit.vela.name = Vela
|
unit.vela.name = Vela
|
||||||
unit.corvus.name = Corvus
|
unit.corvus.name = Corvus
|
||||||
@@ -1228,7 +1232,7 @@ block.overdrive-projector.name = Proiector de Suprasolicitare
|
|||||||
block.force-projector.name = Proiector de Forță
|
block.force-projector.name = Proiector de Forță
|
||||||
block.arc.name = Arc
|
block.arc.name = Arc
|
||||||
block.rtg-generator.name = Generator RTG
|
block.rtg-generator.name = Generator RTG
|
||||||
block.spectre.name = Specter
|
block.spectre.name = Spectre
|
||||||
block.meltdown.name = Meltdown
|
block.meltdown.name = Meltdown
|
||||||
block.foreshadow.name = Foreshadow
|
block.foreshadow.name = Foreshadow
|
||||||
block.container.name = Container
|
block.container.name = Container
|
||||||
@@ -1536,12 +1540,30 @@ lst.unitcontrol = Controlează unitatea controlată de procesor.
|
|||||||
lst.unitradar = Localizează unitățile din jurul unității controlate de procesor.
|
lst.unitradar = Localizează unitățile din jurul unității controlate de procesor.
|
||||||
lst.unitlocate = Localizează o poziție/clădire specifică oriunde pe hartă.\nNecesită o unitate controlată de procesor.
|
lst.unitlocate = Localizează o poziție/clădire specifică oriunde pe hartă.\nNecesită o unitate controlată de procesor.
|
||||||
|
|
||||||
|
logic.nounitbuild = [red]Nu ai voie să construiești cu unitățile folosind procesoare.
|
||||||
|
|
||||||
lenum.type = Tipul clădirii/unității.\nde ex.: pt orice Router, va returna [accent]@router[].\nNu e un șir de caractere.
|
lenum.type = Tipul clădirii/unității.\nde ex.: pt orice Router, va returna [accent]@router[].\nNu e un șir de caractere.
|
||||||
lenum.shoot = Lovește către o locație.
|
lenum.shoot = Lovește către o locație.
|
||||||
lenum.shootp = Lovește către o unitate/clădire. Anticipează viteza țintei și a proiectilului.
|
lenum.shootp = Lovește către o unitate/clădire. Anticipează viteza țintei și a proiectilului.
|
||||||
lenum.configure = Configurașia clădirii, de ex. materialul selectat pt Sortator.
|
lenum.configure = Configurația clădirii, de ex. materialul selectat pt Sortator.
|
||||||
lenum.enabled = Specifică dacă clădirea este pornită.
|
lenum.enabled = Specifică dacă clădirea este pornită.
|
||||||
lenum.color = Culoarea Iluminatorului.
|
|
||||||
|
laccess.color = Culoarea iluminatorului.
|
||||||
|
laccess.controller = Controlorul unității. Dacă e controlată de procesor, returnează procesorul.\nDacă e într-o formație, returnează liderul.\nAltfel, returnează unitatea însăși.
|
||||||
|
laccess.dead = Specifică dacă o unitate sau clădire a murit/nu mai e validă.
|
||||||
|
laccess.controlled = Returnează:\n[accent]@ctrlProcessor[] dacă controlorul unității e procesor\n[accent]@ctrlPlayer[] dacă controlorul unității/clădirii e jucător\n[accent]@ctrlFormation[] dacă unitatea e într-o formație\nAltfel dă 0.
|
||||||
|
laccess.commanded = [red]Învechit. Se va șterge![]\nFolosește [accent]controlled[].
|
||||||
|
|
||||||
|
graphicstype.clear = Umple monitorul cu o culoare.
|
||||||
|
graphicstype.color = Setează culoarea pt următoarele instrucțiuni Draw.
|
||||||
|
graphicstype.stroke = Setează grosimea liniei.
|
||||||
|
graphicstype.line = Desenează un segment de linie.
|
||||||
|
graphicstype.rect = Desenează un dreptunghi.
|
||||||
|
graphicstype.linerect = Desenează conturul unui dreptunghi.
|
||||||
|
graphicstype.poly = Desenează un poligon regulat.
|
||||||
|
graphicstype.linepoly = Desenează conturul unui poligon regulat.
|
||||||
|
graphicstype.triangle = Desenează un triunghi.
|
||||||
|
graphicstype.image = Desenează imaginea unui obiect din joc.\nde ex.: [accent]@router[] sau [accent]@dagger[].
|
||||||
|
|
||||||
lenum.always = Mereu adevărat.
|
lenum.always = Mereu adevărat.
|
||||||
lenum.idiv = Împărțirea naturală a numerelor (int).
|
lenum.idiv = Împărțirea naturală a numerelor (int).
|
||||||
@@ -1566,7 +1588,7 @@ lenum.sin = Sinus în grade.
|
|||||||
lenum.cos = Cosinus în grade.
|
lenum.cos = Cosinus în grade.
|
||||||
lenum.tan = Tangentă în grade.
|
lenum.tan = Tangentă în grade.
|
||||||
#cea de mai jos nu-i o greșeală, caută pe net notarea intervalelor în matematică
|
#cea de mai jos nu-i o greșeală, caută pe net notarea intervalelor în matematică
|
||||||
lenum.rand = Număr aleatoriu în intervalul [0, val).
|
lenum.rand = Număr natural aleatoriu în intervalul [0, val).
|
||||||
lenum.log = Logaritm natural (ln).
|
lenum.log = Logaritm natural (ln).
|
||||||
lenum.log10 = Logaritm în baza 10.
|
lenum.log10 = Logaritm în baza 10.
|
||||||
lenum.noise = 2D simplex noise.
|
lenum.noise = 2D simplex noise.
|
||||||
@@ -1624,6 +1646,7 @@ unitlocate.outx = Coordonata X a obiectului detectat.
|
|||||||
unitlocate.outy = Coordonata Y a obiectului detectat.
|
unitlocate.outy = Coordonata Y a obiectului detectat.
|
||||||
unitlocate.group = Grupul clădirilor de detectat.
|
unitlocate.group = Grupul clădirilor de detectat.
|
||||||
|
|
||||||
|
lenum.idle = Nu mișca, dar continuă să construiești/minezi.\nModul prestabilit.
|
||||||
lenum.stop = Oprește acțiunea curentă. Nu mișca/mina/construi.
|
lenum.stop = Oprește acțiunea curentă. Nu mișca/mina/construi.
|
||||||
lenum.move = Mergi la această poziție.
|
lenum.move = Mergi la această poziție.
|
||||||
lenum.approach = Apropie-te la o anumită distanță de poziție.
|
lenum.approach = Apropie-te la o anumită distanță de poziție.
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ committingchanges = Внесение изменений
|
|||||||
done = Готово
|
done = Готово
|
||||||
feature.unsupported = Ваше устройство не поддерживает эту возможность.
|
feature.unsupported = Ваше устройство не поддерживает эту возможность.
|
||||||
|
|
||||||
mods.alphainfo = Имейте в виду, что модификации находятся в альфа-версии и [scarlet]могут содержать много ошибок[]. Докладывайте о любых проблемах, которые вы найдете в Mindustry Github.
|
mods.initfailed = [red]⚠[] Не удалось инициализировать предыдущий запуск Mindustry. Это могло быть вызвано неисправными модификациями.\n\nЧтобы предотвратить зацикленные вылеты игры, [red]все модификации были отключены.[]\n\nЧтобы отключить эту функцию, выключите её в [accent]Настройки->Игра->Отключение модификаций после вылета при запуске[].
|
||||||
mods = Модификации
|
mods = Модификации
|
||||||
mods.none = [lightgray]Модификации не найдены!
|
mods.none = [lightgray]Модификации не найдены!
|
||||||
mods.guide = Руководство по модификациям
|
mods.guide = Руководство по модификациям
|
||||||
@@ -126,6 +126,7 @@ mod.installed = [[Установлено]
|
|||||||
mod.display = [gray]Модификация:[orange] {0}
|
mod.display = [gray]Модификация:[orange] {0}
|
||||||
mod.enabled = [lightgray]Включён
|
mod.enabled = [lightgray]Включён
|
||||||
mod.disabled = [scarlet]Выключен
|
mod.disabled = [scarlet]Выключен
|
||||||
|
mod.multiplayer.compatible = [gray]Доступна в игре по сети
|
||||||
mod.disable = Выкл.
|
mod.disable = Выкл.
|
||||||
mod.content = Содержимое:
|
mod.content = Содержимое:
|
||||||
mod.delete.error = Невозможно удалить модификацию. Возможно, файл используется.
|
mod.delete.error = Невозможно удалить модификацию. Возможно, файл используется.
|
||||||
@@ -217,6 +218,8 @@ trace = Отслеживать игрока
|
|||||||
trace.playername = Имя игрока: [accent]{0}
|
trace.playername = Имя игрока: [accent]{0}
|
||||||
trace.ip = IP: [accent]{0}
|
trace.ip = IP: [accent]{0}
|
||||||
trace.id = ID: [accent]{0}
|
trace.id = ID: [accent]{0}
|
||||||
|
trace.times.joined = Присоединялся раз: [accent]{0}
|
||||||
|
trace.times.kicked = Был выгнан раз: [accent]{0}
|
||||||
trace.mobile = Мобильный клиент: [accent]{0}
|
trace.mobile = Мобильный клиент: [accent]{0}
|
||||||
trace.modclient = Пользовательский клиент: [accent]{0}
|
trace.modclient = Пользовательский клиент: [accent]{0}
|
||||||
invalidid = Недопустимый ID клиента! Отправьте отчёт об ошибке.
|
invalidid = Недопустимый ID клиента! Отправьте отчёт об ошибке.
|
||||||
@@ -771,8 +774,8 @@ unit.itemssecond = предметов/секунду
|
|||||||
unit.liquidunits = жидкостных единиц
|
unit.liquidunits = жидкостных единиц
|
||||||
unit.powerunits = энерг. единиц
|
unit.powerunits = энерг. единиц
|
||||||
unit.degrees = °
|
unit.degrees = °
|
||||||
unit.seconds = сек.
|
unit.seconds = сек
|
||||||
unit.minutes = мин.
|
unit.minutes = мин
|
||||||
unit.persecond = /сек
|
unit.persecond = /сек
|
||||||
unit.perminute = /мин
|
unit.perminute = /мин
|
||||||
unit.timesspeed = x скорость
|
unit.timesspeed = x скорость
|
||||||
@@ -800,6 +803,8 @@ setting.logichints.name = Подсказки для логики
|
|||||||
setting.flow.name = Показывать скорость потока ресурсов
|
setting.flow.name = Показывать скорость потока ресурсов
|
||||||
setting.backgroundpause.name = Фоновая пауза
|
setting.backgroundpause.name = Фоновая пауза
|
||||||
setting.buildautopause.name = Автоматическая приостановка строительства
|
setting.buildautopause.name = Автоматическая приостановка строительства
|
||||||
|
setting.doubletapmine.name = Добыча руды двойным нажатием
|
||||||
|
setting.modcrashdisable.name = Отключение модификаций после вылета при запуске
|
||||||
setting.animatedwater.name = Анимированные поверхности
|
setting.animatedwater.name = Анимированные поверхности
|
||||||
setting.animatedshields.name = Анимированные щиты
|
setting.animatedshields.name = Анимированные щиты
|
||||||
setting.antialias.name = Сглаживание[lightgray] (требует перезапуска)[]
|
setting.antialias.name = Сглаживание[lightgray] (требует перезапуска)[]
|
||||||
@@ -957,6 +962,8 @@ rules.blockdamagemultiplier = Множитель урона блоков
|
|||||||
rules.unitbuildspeedmultiplier = Множитель скорости производства боев. ед.
|
rules.unitbuildspeedmultiplier = Множитель скорости производства боев. ед.
|
||||||
rules.unithealthmultiplier = Множитель здоровья боев. ед.
|
rules.unithealthmultiplier = Множитель здоровья боев. ед.
|
||||||
rules.unitdamagemultiplier = Множитель урона боев. ед.
|
rules.unitdamagemultiplier = Множитель урона боев. ед.
|
||||||
|
rules.unitcapvariable = Ядра увеличивают лимит единиц
|
||||||
|
rules.unitcap = Начальный лимит единиц
|
||||||
rules.enemycorebuildradius = Радиус защиты враж. ядер:[lightgray] (блок.)
|
rules.enemycorebuildradius = Радиус защиты враж. ядер:[lightgray] (блок.)
|
||||||
rules.wavespacing = Интервал волн:[lightgray] (сек)
|
rules.wavespacing = Интервал волн:[lightgray] (сек)
|
||||||
rules.buildcostmultiplier = Множитель затрат на строительство
|
rules.buildcostmultiplier = Множитель затрат на строительство
|
||||||
@@ -1534,12 +1541,30 @@ lst.unitcontrol = Управляет привязанной в данный мо
|
|||||||
lst.unitradar = Обнаруживает единицы вокруг привязанной в данный момент единицы.
|
lst.unitradar = Обнаруживает единицы вокруг привязанной в данный момент единицы.
|
||||||
lst.unitlocate = Обнаруживает позицию/постройку определённого типа где-либо на карте. Требует привязанную единицу.
|
lst.unitlocate = Обнаруживает позицию/постройку определённого типа где-либо на карте. Требует привязанную единицу.
|
||||||
|
|
||||||
|
logic.nounitbuild = [red]Строительство с помощью процессоров здесь запрещено.
|
||||||
|
|
||||||
lenum.type = Тип постройки/единицы. \nНапример, для маршрутизатора это будет [accent]@router[].\nНе строка.
|
lenum.type = Тип постройки/единицы. \nНапример, для маршрутизатора это будет [accent]@router[].\nНе строка.
|
||||||
lenum.shoot = Стрельба в определённую позицию.
|
lenum.shoot = Стрельба в определённую позицию.
|
||||||
lenum.shootp = Стрельба в единицу/постройку с расчётом скорости.
|
lenum.shootp = Стрельба в единицу/постройку с расчётом скорости.
|
||||||
lenum.configure = Конфигурация постройки, например, предмет сортировки.
|
lenum.configure = Конфигурация постройки, например, предмет сортировки.
|
||||||
lenum.enabled = Включён ли блок.
|
lenum.enabled = Включён ли блок.
|
||||||
lenum.color = Цвет осветителя.
|
|
||||||
|
laccess.color = Цвет осветителя.
|
||||||
|
laccess.controller = Командующий единицей. Если единица управляется процессором, возвращает процессор. Если в строю, возращает командуещего.\nВ противном случае возвращает саму единицу.
|
||||||
|
laccess.dead = Является ли единица/постройка неработающей или несуществующей.
|
||||||
|
laccess.controlled = Возвращает:\n[accent]@ctrlProcessor[] если единица управляется процессором\n[accent]@ctrlPlayer[] если единица/постройка управляется игроком\n[accent]@ctrlFormation[] если единица в строю\nВ противном случае — 0.
|
||||||
|
laccess.commanded = [red]Устарело. Будет удалено![]\nВместо этого, используйте [accent]controlled[].
|
||||||
|
|
||||||
|
graphicstype.clear = Заливка дисплея цветом.
|
||||||
|
graphicstype.color = Установка цвета для следующих операций отрисовки.
|
||||||
|
graphicstype.stroke = Установка толщины линии.
|
||||||
|
graphicstype.line = Отрисовка отрезка.
|
||||||
|
graphicstype.rect = Отрисовка закрашенного прямоугольника.
|
||||||
|
graphicstype.linerect = Отрисовка контура прямоугольника.
|
||||||
|
graphicstype.poly = Отрисовка закрашенного правильного многоугольника.
|
||||||
|
graphicstype.linepoly = Отрисовка контура правильного многоугольника.
|
||||||
|
graphicstype.triangle = Отрисовка закрашенного треугольника.
|
||||||
|
graphicstype.image = Отрисовка внутриигровых спрайтов.\nНапример: [accent]@router[] или [accent]@dagger[].
|
||||||
|
|
||||||
lenum.always = Всегда истина.
|
lenum.always = Всегда истина.
|
||||||
lenum.idiv = Целочисленное деление.
|
lenum.idiv = Целочисленное деление.
|
||||||
@@ -1622,7 +1647,8 @@ unitlocate.outx = Вывод X координаты.
|
|||||||
unitlocate.outy = Вывод Y координаты.
|
unitlocate.outy = Вывод Y координаты.
|
||||||
unitlocate.group = Группа построек для поиска.
|
unitlocate.group = Группа построек для поиска.
|
||||||
|
|
||||||
lenum.stop = Остановка передвижения/копания/стротельства.
|
lenum.idle = Остановка движения, но продолжение строительства/копания.\nСостояние по умолчанию.
|
||||||
|
lenum.stop = Остановка передвижения/копания/строительства.
|
||||||
lenum.move = Перемещение в определённую позицию.
|
lenum.move = Перемещение в определённую позицию.
|
||||||
lenum.approach = Приближение к позиции с указанным радиусом.
|
lenum.approach = Приближение к позиции с указанным радиусом.
|
||||||
lenum.pathfind = Перемещение к точке появления врагов.
|
lenum.pathfind = Перемещение к точке появления врагов.
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ link.google-play.description = Google Play store listing
|
|||||||
link.f-droid.description = F-Droid listing
|
link.f-droid.description = F-Droid listing
|
||||||
link.wiki.description = Mindustry wiki chính thức
|
link.wiki.description = Mindustry wiki chính thức
|
||||||
link.suggestions.description = Đề xuất các tính năng mới
|
link.suggestions.description = Đề xuất các tính năng mới
|
||||||
|
link.bug.description = Tìm thấy lỗi? Báo cáo nó ở đây
|
||||||
linkfail = Không mở được liên kết!\nURL đã được sao chép vào bộ nhớ tạm.
|
linkfail = Không mở được liên kết!\nURL đã được sao chép vào bộ nhớ tạm.
|
||||||
screenshot = Ảnh chụp màn hình được lưu vào {0}
|
screenshot = Ảnh chụp màn hình được lưu vào {0}
|
||||||
screenshot.invalid = Bản đồ quá lớn, có khả năng không đủ bộ nhớ để chụp ảnh màn hình.
|
screenshot.invalid = Bản đồ quá lớn, có khả năng không đủ bộ nhớ để chụp ảnh màn hình.
|
||||||
@@ -40,24 +41,32 @@ be.ignore = Bỏ qua
|
|||||||
be.noupdates = Không tìm thấy bản cập nhật mới.
|
be.noupdates = Không tìm thấy bản cập nhật mới.
|
||||||
be.check = Kiểm tra các bản cập nhật.
|
be.check = Kiểm tra các bản cập nhật.
|
||||||
|
|
||||||
schematic = Schematic
|
mods.browser = Duyệt mod
|
||||||
schematic.add = Lưu Schematic...
|
mods.browser.selected = Mod Đã chọn
|
||||||
schematics = Schematics
|
mods.browser.add = Cài đặt
|
||||||
schematic.replace = Schematics có tên đó đã tồn tại. Thay thế nó?
|
mods.browser.reinstall = Cài đặt lại
|
||||||
schematic.exists = Schematics có tên đó đã tồn tại.
|
mods.github.open = Repo
|
||||||
schematic.import = Nhập Schematic...
|
mods.browser.sortdate = Sắp xếp theo gần đây
|
||||||
|
mods.browser.sortstars = Sắp xếp theo sao
|
||||||
|
|
||||||
|
schematic = Bản thiết kế
|
||||||
|
schematic.add = Lưu bản thiết kế...
|
||||||
|
schematics = Các bản thiết kế
|
||||||
|
schematic.replace = Bản thiết kế có tên đó đã tồn tại. Thay thế nó?
|
||||||
|
schematic.exists = Bản thiết kế có tên đó đã tồn tại.
|
||||||
|
schematic.import = Nhập Bản thiết kế...
|
||||||
schematic.exportfile = Xuất tệp
|
schematic.exportfile = Xuất tệp
|
||||||
schematic.importfile = Nhập tệp
|
schematic.importfile = Nhập tệp
|
||||||
schematic.browseworkshop = Duyệt qua Workshop
|
schematic.browseworkshop = Duyệt qua Workshop
|
||||||
schematic.copy = Sao chép vào bộ nhớ tạm
|
schematic.copy = Sao chép vào bộ nhớ tạm
|
||||||
schematic.copy.import = Nhập từ bộ nhớ tạm
|
schematic.copy.import = Thêm từ bộ nhớ tạm
|
||||||
schematic.shareworkshop = Chia sẻ từ Workshop
|
schematic.shareworkshop = Chia sẻ từ Workshop
|
||||||
schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Lật Schematic
|
schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Lật bản thiết kế
|
||||||
schematic.saved = Đã lưu Schematic.
|
schematic.saved = Đã lưu bản thiết kế.
|
||||||
schematic.delete.confirm = Schematic này sẽ bị xóa hoàn toàn.
|
schematic.delete.confirm = Bản thiết kế này sẽ bị xóa hoàn toàn.
|
||||||
schematic.rename = Đổi tên Schematic
|
schematic.rename = Đổi tên bản thiết kế
|
||||||
schematic.info = {0}x{1}, {2} khối
|
schematic.info = {0}x{1}, {2} khối
|
||||||
schematic.disabled = [scarlet]Tính năng Schematics đã bị tắt[]\nBạn không được sử dụng schematic trong [accent]bản đồ[] hoặc [accent]máy chủ.
|
schematic.disabled = [scarlet]Tính năng bản thiết kế đã bị tắt[]\nBạn không được sử dụng bản thiết kế trong [accent]bản đồ[] hoặc [accent]máy chủ.
|
||||||
|
|
||||||
stats = Thống kê
|
stats = Thống kê
|
||||||
stat.wave = Đợt đã vượt qua:[accent] {0}
|
stat.wave = Đợt đã vượt qua:[accent] {0}
|
||||||
@@ -75,14 +84,15 @@ level.highscore = Điểm cao nhất: [accent]{0}
|
|||||||
level.select = Chọn cấp độ
|
level.select = Chọn cấp độ
|
||||||
level.mode = Chế độ:
|
level.mode = Chế độ:
|
||||||
coreattack = < Căn cứ đang bị tấn công! >
|
coreattack = < Căn cứ đang bị tấn công! >
|
||||||
nearpoint = [[ [scarlet]RỜI KHỎI ĐIỂM THẢ NGAY LẬP TỨC[] ]\nsự hủy diệt sắp xảy ra
|
nearpoint = [[ [scarlet]RỜI KHỎI KHU VỰC ĐÁP NGAY LẬP TỨC[] ]\nsự hủy diệt sắp xảy ra
|
||||||
database = Cơ sở dữ liệu căn cứ
|
database = Cơ sở dữ liệu
|
||||||
savegame = Lưu trò chơi
|
savegame = Lưu trò chơi
|
||||||
loadgame = Tải trò chơi
|
loadgame = Tải lại màn chơi
|
||||||
joingame = Tham gia trò chơi
|
joingame = Tham gia trò chơi
|
||||||
customgame = Tùy chỉnh
|
customgame = Tùy chỉnh
|
||||||
newgame = Trò chơi mới
|
newgame = Trò chơi mới
|
||||||
none = <trống>
|
none = <trống>
|
||||||
|
none.found = [lightgray]<không tìm thấy>
|
||||||
minimap = Bản đồ nhỏ
|
minimap = Bản đồ nhỏ
|
||||||
position = Vị trí
|
position = Vị trí
|
||||||
close = Đóng
|
close = Đóng
|
||||||
@@ -90,9 +100,9 @@ website = Website
|
|||||||
quit = Thoát
|
quit = Thoát
|
||||||
save.quit = Lưu & Thoát
|
save.quit = Lưu & Thoát
|
||||||
maps = Bản đồ
|
maps = Bản đồ
|
||||||
maps.browse = Duyệt bản đồ
|
maps.browse = Chọn bản đồ
|
||||||
continue = Tiếp tục
|
continue = Tiếp tục
|
||||||
maps.none = [lightgray]Không có bản đồ nào được tìm thấy!
|
maps.none = [lightgray]Không tìm thấy bản đồ!
|
||||||
invalid = Không hợp lệ
|
invalid = Không hợp lệ
|
||||||
pickcolor = Chọn màu
|
pickcolor = Chọn màu
|
||||||
preparingconfig = Đang chuẩn bị cấu hình
|
preparingconfig = Đang chuẩn bị cấu hình
|
||||||
@@ -103,14 +113,16 @@ committingchanges = Đang cập nhật các thay đổi
|
|||||||
done = Hoàn tất
|
done = Hoàn tất
|
||||||
feature.unsupported = Thiết bị của bạn không hỗ trợ tính năng này.
|
feature.unsupported = Thiết bị của bạn không hỗ trợ tính năng này.
|
||||||
|
|
||||||
mods.alphainfo = Hãy nhớ rằng các bản mod đang ở giai đoạn alpha, và[scarlet] có thể chứa rất rất lỗi[].\nBáo cáo bất kỳ vấn đề nào bạn gặp phải tại Mindustry GitHub.
|
mods.initfailed = [red]⚠[] Mindustry không khởi chạy được. Điều này có thể do các mod bị lỗi.\n\nĐể tránh gặp sự cố liên tiếp, [red]tất cả các mod đã bị tắt.[]\n\nĐể tắt tính năng này, vào [accent]Cài đặt->Trò chơi->Tắt các mod khi gặp sự cố trong khởi động[].
|
||||||
mods = Mods
|
mods = Mods
|
||||||
mods.none = [lightgray]Không có mod nào được tìm thấy!
|
mods.none = [lightgray]Không tìm thấy mod!
|
||||||
mods.guide = Hướng dẫn mod
|
mods.guide = Hướng dẫn mod
|
||||||
mods.report = Báo lỗi
|
mods.report = Báo lỗi
|
||||||
mods.openfolder = Mở thư mục
|
mods.openfolder = Mở thư mục
|
||||||
|
mods.viewcontent = Xem nội dung
|
||||||
mods.reload = Tải lại
|
mods.reload = Tải lại
|
||||||
mods.reloadexit = Trò chơi sẽ đóng để tải lại mod.
|
mods.reloadexit = Trò chơi sẽ đóng để mod được tải.
|
||||||
|
mod.installed = [[Đã cài đặt]
|
||||||
mod.display = [gray]Mod:[orange] {0}
|
mod.display = [gray]Mod:[orange] {0}
|
||||||
mod.enabled = [lightgray]Đã Bật
|
mod.enabled = [lightgray]Đã Bật
|
||||||
mod.disabled = [scarlet]Đã Tắt
|
mod.disabled = [scarlet]Đã Tắt
|
||||||
@@ -122,21 +134,21 @@ mod.outdated = [scarlet]Không tương thích với V6 (no minGameVersion: 105)
|
|||||||
mod.missingdependencies = [scarlet]Thiếu phụ thuộc: {0}
|
mod.missingdependencies = [scarlet]Thiếu phụ thuộc: {0}
|
||||||
mod.erroredcontent = [scarlet]Lỗi nội dung
|
mod.erroredcontent = [scarlet]Lỗi nội dung
|
||||||
mod.errors = Đã xảy ra lỗi khi tải nội dung.
|
mod.errors = Đã xảy ra lỗi khi tải nội dung.
|
||||||
mod.noerrorplay = [scarlet]Bạn có mod bị lỗi.[]Tắt các mod bị ảnh hưởng hoặc sửa chữa các lỗi trước khi chơi.
|
mod.noerrorplay = [scarlet]Bạn có mod bị lỗi.[]Tắt các mod bị lỗi hoặc sửa các lỗi trước khi chơi.
|
||||||
mod.nowdisabled = [scarlet]Mod '{0}' cần mod này để chạy:[accent] {1}\n[lightgray]Trước tiên bạn cần tải các mod này xuống.\nBản mod này sẽ tự động tắt.
|
mod.nowdisabled = [scarlet]Mod '{0}' cần mod này để chạy:[accent] {1}\n[lightgray]Trước tiên bạn cần tải các mod này xuống.\nBản mod này sẽ tự động tắt.
|
||||||
mod.enable = Bật
|
mod.enable = Bật
|
||||||
mod.requiresrestart = Trò chơi sẽ đóng để áp dụng các thay đổi của mod.
|
mod.requiresrestart = Trò chơi sẽ đóng để áp dụng các thay đổi của mod.
|
||||||
mod.reloadrequired = [scarlet]Yêu cầu khởi động lại
|
mod.reloadrequired = [scarlet]Yêu cầu khởi động lại
|
||||||
mod.import = Nhập Mod
|
mod.import = Thêm Mod
|
||||||
mod.import.file = Nhập tệp
|
mod.import.file = Thêm từ tệp
|
||||||
mod.import.github = Nhập từ GitHub
|
mod.import.github = Thêm từ GitHub
|
||||||
mod.jarwarn = [scarlet]JAR mod vốn dĩ không an toàn.[]\nĐảm bảo rằng bạn đang nhập bản mod này từ một nguồn đáng tin cậy!
|
mod.jarwarn = [scarlet]Các JAR mod vốn dĩ không an toàn.[]\nĐảm bảo rằng bạn đang thêm mod này từ một nguồn đáng tin cậy!
|
||||||
mod.item.remove = Mục này là một phần của[accent] '{0}'[] mod. Để xóa nó, hãy gỡ cài đặt mod này.
|
mod.item.remove = Mục này là một phần của[accent] '{0}'[] mod. Để xóa nó, hãy gỡ cài đặt mod này.
|
||||||
mod.remove.confirm = Mod này sẽ bị xóa.
|
mod.remove.confirm = Mod này sẽ bị xóa.
|
||||||
mod.author = [lightgray]Tác giả:[] {0}
|
mod.author = [lightgray]Tác giả:[] {0}
|
||||||
mod.missing = Bản lưu này chứa các mod mà bạn đã cập nhật gần đây hoặc không còn cài đặt nữa. Có thể gây ra lỗi khi mở. Bạn có chắc muốn mở nó?\n[lightgray]Mods:\n{0}
|
mod.missing = Bản lưu này chứa các mod mà bạn đã cập nhật gần đây hoặc không được cài đặt. Có thể gây ra lỗi khi mở. Bạn có chắc muốn mở nó?\n[lightgray]Mods:\n{0}
|
||||||
mod.preview.missing = Trước khi xuất bản bản mod này lên workshop, bạn phải thêm hình ảnh xem trước.\nĐặt một hình ảnh có tên[accent] preview.png[] vào thư mục của mod và thử lại.
|
mod.preview.missing = Trước khi đăng bản mod này lên workshop, bạn phải thêm hình ảnh xem trước.\nĐặt một hình ảnh có tên[accent] preview.png[] vào thư mục của mod và thử lại.
|
||||||
mod.folder.missing = Chỉ có thể xuất bản các mod ở dạng thư mục lên workshop.\nĐể chuyển đổi bất kỳ mod nào thành một thư mục, chỉ cần giải nén tệp của nó vào một thư mục và xóa tệp nén cũ, sau đó khởi động lại trò chơi của bạn hoặc tải lại các bản mod của bạn.
|
mod.folder.missing = Chỉ có thể đăng các mod ở dạng thư mục lên workshop.\nĐể chuyển đổi bất kỳ mod nào thành một thư mục, chỉ cần giải nén tệp của nó vào một thư mục và xóa tệp nén cũ, sau đó khởi động lại trò chơi của bạn hoặc tải lại các bản mod của bạn.
|
||||||
mod.scripts.disable = Thiết bị của bạn không hổ trợ mod chứa scripts này. Bạn phải tắt các mod này để chơi trò chơi.
|
mod.scripts.disable = Thiết bị của bạn không hổ trợ mod chứa scripts này. Bạn phải tắt các mod này để chơi trò chơi.
|
||||||
|
|
||||||
about.button = Thông tin
|
about.button = Thông tin
|
||||||
@@ -196,6 +208,7 @@ servers.local = Máy chủ cục bộ
|
|||||||
servers.remote = Máy chủ tùy chỉnh
|
servers.remote = Máy chủ tùy chỉnh
|
||||||
servers.global = Máy chủ từ cộng đồng
|
servers.global = Máy chủ từ cộng đồng
|
||||||
|
|
||||||
|
servers.disclaimer = Nhà phát triển [accent]không[] sở hữu và kiểm soát máy chủ cộng đồng.\n\nMáy chủ có thể chứa nội dung do người dùng tạo và không phù hợp với mọi lứa tuổi.
|
||||||
servers.showhidden = Hiển thị Máy chủ Ẩn
|
servers.showhidden = Hiển thị Máy chủ Ẩn
|
||||||
server.shown = Hiện
|
server.shown = Hiện
|
||||||
server.hidden = Ẩn
|
server.hidden = Ẩn
|
||||||
@@ -279,6 +292,7 @@ cancel = Hủy
|
|||||||
openlink = Mở link
|
openlink = Mở link
|
||||||
copylink = Sao chép link
|
copylink = Sao chép link
|
||||||
back = Quay lại
|
back = Quay lại
|
||||||
|
max = Tối đa
|
||||||
crash.export = Xuất Crash Logs
|
crash.export = Xuất Crash Logs
|
||||||
crash.none = Không có Crash Logs nào được tìm thấy.
|
crash.none = Không có Crash Logs nào được tìm thấy.
|
||||||
crash.exported = Crash logs đã được xuất.
|
crash.exported = Crash logs đã được xuất.
|
||||||
@@ -298,6 +312,7 @@ cancelbuilding = [accent][[{0}][] để hủy xây
|
|||||||
selectschematic = [accent][[{0}][] to để chọn+sao chép
|
selectschematic = [accent][[{0}][] to để chọn+sao chép
|
||||||
pausebuilding = [accent][[{0}][] để tạm dừng xây dựng
|
pausebuilding = [accent][[{0}][] để tạm dừng xây dựng
|
||||||
resumebuilding = [scarlet][[{0}][] để tiếp tục xây dựng
|
resumebuilding = [scarlet][[{0}][] để tiếp tục xây dựng
|
||||||
|
enablebuilding = [scarlet][[{0}][] để bật xây dựng
|
||||||
showui = UI hidden.\nPress [accent][[{0}][] để hiện UI.
|
showui = UI hidden.\nPress [accent][[{0}][] để hiện UI.
|
||||||
wave = [accent]Đợt {0}
|
wave = [accent]Đợt {0}
|
||||||
wave.cap = [accent]Đợt {0}/{1}
|
wave.cap = [accent]Đợt {0}/{1}
|
||||||
@@ -353,7 +368,6 @@ editor.center = Trung tâm
|
|||||||
workshop = Workshop
|
workshop = Workshop
|
||||||
waves.title = Đợt
|
waves.title = Đợt
|
||||||
waves.remove = Xóa
|
waves.remove = Xóa
|
||||||
waves.never = <vô hạn>
|
|
||||||
waves.every = mỗi
|
waves.every = mỗi
|
||||||
waves.waves = đợt
|
waves.waves = đợt
|
||||||
waves.perspawn = mỗi lần xuất hiện
|
waves.perspawn = mỗi lần xuất hiện
|
||||||
@@ -382,7 +396,7 @@ editor.removeunit = Xóa kẻ địch
|
|||||||
editor.teams = Đội
|
editor.teams = Đội
|
||||||
editor.errorload = Lỗi khi tải tệp.
|
editor.errorload = Lỗi khi tải tệp.
|
||||||
editor.errorsave = Lỗi khi lưu tệp.
|
editor.errorsave = Lỗi khi lưu tệp.
|
||||||
editor.errorimage = Đó là một hình ảnh, không phải bản đồ.\n\nNếu bạn muốn nhập một bản đồ 3.5/build 40, sử dụng nút 'Nhập bản đồ thay thế' trong trình chỉnh sửa.
|
editor.errorimage = Đó là một hình ảnh, không phải bản đồ.
|
||||||
editor.errorlegacy = Bản đồ này quá cũ, và sử dụng định dạng bản đồ cũ không còn được hỗ trợ.
|
editor.errorlegacy = Bản đồ này quá cũ, và sử dụng định dạng bản đồ cũ không còn được hỗ trợ.
|
||||||
editor.errornot = Đây không phải là tệp bản đồ.
|
editor.errornot = Đây không phải là tệp bản đồ.
|
||||||
editor.errorheader = Tệp bản đồ này không hợp lệ hoặc bị hỏng.
|
editor.errorheader = Tệp bản đồ này không hợp lệ hoặc bị hỏng.
|
||||||
@@ -672,9 +686,10 @@ stat.drillspeed = Tốc độ khoang cơ bản
|
|||||||
stat.boosteffect = Hiệu ứng tăng cường
|
stat.boosteffect = Hiệu ứng tăng cường
|
||||||
stat.maxunits = Số quân lính hoạt động tối đa
|
stat.maxunits = Số quân lính hoạt động tối đa
|
||||||
stat.health = Độ bền
|
stat.health = Độ bền
|
||||||
|
stat.armor = Giáp
|
||||||
stat.buildtime = Thời gian xây
|
stat.buildtime = Thời gian xây
|
||||||
stat.maxconsecutive = Đầu ra tối đa
|
stat.maxconsecutive = Đầu ra tối đa
|
||||||
stat.buildcost = Chi phí
|
stat.buildcost = Yêu cầu
|
||||||
stat.inaccuracy = Độ lệch
|
stat.inaccuracy = Độ lệch
|
||||||
stat.shots = Phát bắn
|
stat.shots = Phát bắn
|
||||||
stat.reload = Phát bắn/Giây
|
stat.reload = Phát bắn/Giây
|
||||||
@@ -687,6 +702,7 @@ stat.lightningchance = Tỷ lệ phóng điện
|
|||||||
stat.lightningdamage = Sát thương tia điện
|
stat.lightningdamage = Sát thương tia điện
|
||||||
stat.flammability = Dễ cháy
|
stat.flammability = Dễ cháy
|
||||||
stat.radioactivity = Phóng xạ
|
stat.radioactivity = Phóng xạ
|
||||||
|
stat.charge = Phóng điện
|
||||||
stat.heatcapacity = Nhiệt dung
|
stat.heatcapacity = Nhiệt dung
|
||||||
stat.viscosity = Độ nhớt
|
stat.viscosity = Độ nhớt
|
||||||
stat.temperature = Nhiệt độ
|
stat.temperature = Nhiệt độ
|
||||||
@@ -699,12 +715,13 @@ stat.commandlimit = Giới hạn lệnh
|
|||||||
stat.abilities = Khả năng
|
stat.abilities = Khả năng
|
||||||
stat.canboost = Nâng cấp
|
stat.canboost = Nâng cấp
|
||||||
stat.flying = Bay
|
stat.flying = Bay
|
||||||
|
stat.ammouse = Sử dụng đạn
|
||||||
|
|
||||||
ability.forcefield = Force Field
|
ability.forcefield = Tạo khiên
|
||||||
ability.repairfield = Repair Field
|
ability.repairfield = Sửa chữa/Xây dựng
|
||||||
ability.statusfield = Status Field
|
ability.statusfield = Status Field
|
||||||
ability.unitspawn = {0} Factory
|
ability.unitspawn = Sản xuất {0}
|
||||||
ability.shieldregenfield = Shield Regen Field
|
ability.shieldregenfield = Tạo khiên nhỏ
|
||||||
ability.movelightning = Movement Lightning
|
ability.movelightning = Movement Lightning
|
||||||
|
|
||||||
bar.drilltierreq = Cần máy khoan tốt hơn
|
bar.drilltierreq = Cần máy khoan tốt hơn
|
||||||
@@ -713,6 +730,7 @@ bar.corereq = Yêu cầu căn cứ
|
|||||||
bar.drillspeed = Tốc độ khoan: {0}/giây
|
bar.drillspeed = Tốc độ khoan: {0}/giây
|
||||||
bar.pumpspeed = Tốc độ bơm: {0}/giây
|
bar.pumpspeed = Tốc độ bơm: {0}/giây
|
||||||
bar.efficiency = Hiệu suất: {0}%
|
bar.efficiency = Hiệu suất: {0}%
|
||||||
|
bar.boost = Tăng tốc: {0}%
|
||||||
bar.powerbalance = Năng lượng: {0}/giây
|
bar.powerbalance = Năng lượng: {0}/giây
|
||||||
bar.powerstored = Lưu trữ: {0}/{1}
|
bar.powerstored = Lưu trữ: {0}/{1}
|
||||||
bar.poweramount = Năng lượng: {0}
|
bar.poweramount = Năng lượng: {0}
|
||||||
@@ -721,7 +739,6 @@ bar.powerlines = Số lượng kết nối: {0}/{1}
|
|||||||
bar.items = Vật phẩm: {0}
|
bar.items = Vật phẩm: {0}
|
||||||
bar.capacity = Sức chứa: {0}
|
bar.capacity = Sức chứa: {0}
|
||||||
bar.unitcap = {0} {1}/{2}
|
bar.unitcap = {0} {1}/{2}
|
||||||
bar.limitreached = [scarlet] {0} / {1}[white] {2}\n[lightgray][[quân lính bị vô hiệu hóa]
|
|
||||||
bar.liquid = Chất lỏng
|
bar.liquid = Chất lỏng
|
||||||
bar.heat = Nhiệt độ
|
bar.heat = Nhiệt độ
|
||||||
bar.power = Năng lượng
|
bar.power = Năng lượng
|
||||||
@@ -735,12 +752,13 @@ bullet.damage = [stat]{0}[lightgray] sát thương
|
|||||||
bullet.splashdamage = [stat]{0}[lightgray] sát thương diện rộng ~[stat] {1}[lightgray] ô
|
bullet.splashdamage = [stat]{0}[lightgray] sát thương diện rộng ~[stat] {1}[lightgray] ô
|
||||||
bullet.incendiary = [stat]cháy
|
bullet.incendiary = [stat]cháy
|
||||||
bullet.sapping = [stat]sapping
|
bullet.sapping = [stat]sapping
|
||||||
bullet.homing = [stat]homing
|
bullet.homing = [stat]truy đuổi
|
||||||
bullet.shock = [stat]sốc
|
bullet.shock = [stat]sốc
|
||||||
bullet.frag = [stat]frag
|
bullet.buildingdamage = [stat]{0}%[lightgray] sát thương khối
|
||||||
|
bullet.frag = [stat]phá mảnh
|
||||||
bullet.knockback = [stat]{0}[lightgray] bật lùi
|
bullet.knockback = [stat]{0}[lightgray] bật lùi
|
||||||
bullet.pierce = [stat]{0}[lightgray]x xuyên giáp
|
bullet.pierce = [stat]{0}[lightgray]x xuyên giáp
|
||||||
bullet.infinitepierce = [stat]pierce
|
bullet.infinitepierce = [stat]xuyên thấu
|
||||||
bullet.healpercent = [stat]{0}[lightgray]% sửa chửa
|
bullet.healpercent = [stat]{0}[lightgray]% sửa chửa
|
||||||
bullet.freezing = [stat]đóng băng
|
bullet.freezing = [stat]đóng băng
|
||||||
bullet.tarred = [stat]tarred
|
bullet.tarred = [stat]tarred
|
||||||
@@ -763,9 +781,10 @@ unit.timesspeed = x tốc độ
|
|||||||
unit.percent = %
|
unit.percent = %
|
||||||
unit.shieldhealth = độ bền khiên
|
unit.shieldhealth = độ bền khiên
|
||||||
unit.items = vật phẩm
|
unit.items = vật phẩm
|
||||||
unit.thousands = nghìn
|
unit.thousands = k
|
||||||
unit.millions = triệu
|
unit.millions = mil
|
||||||
unit.billions = tỷ
|
unit.billions = b
|
||||||
|
unit.pershot = /shot
|
||||||
category.purpose = Mô tả
|
category.purpose = Mô tả
|
||||||
category.general = Chung
|
category.general = Chung
|
||||||
category.power = Năng lượng
|
category.power = Năng lượng
|
||||||
@@ -782,14 +801,15 @@ setting.hints.name = Gợi ý
|
|||||||
setting.flow.name = Hiện thị tốc độ chuyền tài nguyên
|
setting.flow.name = Hiện thị tốc độ chuyền tài nguyên
|
||||||
setting.backgroundpause.name = Tạm dừng trong nền
|
setting.backgroundpause.name = Tạm dừng trong nền
|
||||||
setting.buildautopause.name = Tự động dừng xây dựng
|
setting.buildautopause.name = Tự động dừng xây dựng
|
||||||
|
setting.modcrashdisable.name = Tắt các mod khi gặp sự cố trong khởi động
|
||||||
setting.animatedwater.name = Hiệu ứng nước
|
setting.animatedwater.name = Hiệu ứng nước
|
||||||
setting.animatedshields.name = Hiệu ứng khiên
|
setting.animatedshields.name = Hiệu ứng khiên
|
||||||
setting.antialias.name = Khử răng cưa[lightgray] (yêu cầu khởi động lại)[]
|
setting.antialias.name = Khử răng cưa[lightgray] (yêu cầu khởi động lại)[]
|
||||||
setting.playerindicators.name = Hướng người chơi
|
setting.playerindicators.name = Hướng người chơi
|
||||||
setting.indicators.name = Hướng kẻ địch
|
setting.indicators.name = Hướng kẻ địch
|
||||||
setting.autotarget.name = Tự động nhắm mục tiêu
|
setting.autotarget.name = Tự động nhắm mục tiêu
|
||||||
setting.keyboard.name = Điều khiển bằng chuột+bàn phím
|
setting.keyboard.name = Điều khiển bằng chuột + bàn phím
|
||||||
setting.touchscreen.name = Điều khiển bằng màng hình cảm ứng
|
setting.touchscreen.name = Điều khiển bằng màn hình cảm ứng
|
||||||
setting.fpscap.name = FPS tối đa
|
setting.fpscap.name = FPS tối đa
|
||||||
setting.fpscap.none = Không giới hạn
|
setting.fpscap.none = Không giới hạn
|
||||||
setting.fpscap.text = {0} FPS
|
setting.fpscap.text = {0} FPS
|
||||||
@@ -810,13 +830,13 @@ setting.sensitivity.name = Độ nhạy điều khiển
|
|||||||
setting.saveinterval.name = Khoảng thời gian lưu
|
setting.saveinterval.name = Khoảng thời gian lưu
|
||||||
setting.seconds = {0} giây
|
setting.seconds = {0} giây
|
||||||
setting.milliseconds = {0} mili giây
|
setting.milliseconds = {0} mili giây
|
||||||
setting.fullscreen.name = Toàn màng hình
|
setting.fullscreen.name = Toàn màn hình
|
||||||
setting.borderlesswindow.name = Không viền[lightgray] (yêu cầu khởi động lại)
|
setting.borderlesswindow.name = Không viền[lightgray] (yêu cầu khởi động lại)
|
||||||
setting.fps.name = Hiển thị FPS & Ping
|
setting.fps.name = Hiển thị FPS & Ping
|
||||||
setting.smoothcamera.name = Chế độ mượt mà
|
setting.smoothcamera.name = Chế độ mượt mà
|
||||||
setting.vsync.name = VSync
|
setting.vsync.name = VSync
|
||||||
setting.pixelate.name = Đồ họa pixel
|
setting.pixelate.name = Đồ họa pixel
|
||||||
setting.minimap.name = Hiển thị bảng đồ mini
|
setting.minimap.name = Hiển thị bản đồ mini
|
||||||
setting.coreitems.name = Hiển thị vật phẩm trong căn cứ
|
setting.coreitems.name = Hiển thị vật phẩm trong căn cứ
|
||||||
setting.position.name = Hiển thị vị trí người chơi
|
setting.position.name = Hiển thị vị trí người chơi
|
||||||
setting.musicvol.name = Âm lượng nhạc
|
setting.musicvol.name = Âm lượng nhạc
|
||||||
@@ -833,7 +853,9 @@ setting.chatopacity.name = Độ mờ trò chuyện
|
|||||||
setting.lasersopacity.name = Độ mờ kết nối năng lượng
|
setting.lasersopacity.name = Độ mờ kết nối năng lượng
|
||||||
setting.bridgeopacity.name = Độ mờ cầu
|
setting.bridgeopacity.name = Độ mờ cầu
|
||||||
setting.playerchat.name = Hiển thị bong bóng trò chuyện của người chơi
|
setting.playerchat.name = Hiển thị bong bóng trò chuyện của người chơi
|
||||||
|
setting.showweather.name = Hiển thị đồ họa thời tiết
|
||||||
public.confirm = Bạn có muốn công khai trò chơi của mình không?\n[accent]Bất kỳ ai cũng có thể tham gia trò chơi của bạn.\n[lightgray]Điều này có thể được thay đổi sau trong Cài đặt-> Trò chơi-> Hiển thị trò chơi công khai.
|
public.confirm = Bạn có muốn công khai trò chơi của mình không?\n[accent]Bất kỳ ai cũng có thể tham gia trò chơi của bạn.\n[lightgray]Điều này có thể được thay đổi sau trong Cài đặt-> Trò chơi-> Hiển thị trò chơi công khai.
|
||||||
|
public.confirm.really = Nếu bạn muốn chơi với bạn bè, sử dụng [green]Invite Friend[] thay vì [scarlet]Public server[]!\nBạn có chắc chắn muốn làm trò chơi của mình [scarlet]công khai[]?
|
||||||
public.beta = Lưu ý rằng phiên bản beta của trò chơi không thể tạo sảnh công khai.
|
public.beta = Lưu ý rằng phiên bản beta của trò chơi không thể tạo sảnh công khai.
|
||||||
uiscale.reset = Kích thước UI đã được thay đổi.\nNhấn "OK" để xác nhận.\n[scarlet]Hoàn lại và thoát trong[accent] {0}[] giây...
|
uiscale.reset = Kích thước UI đã được thay đổi.\nNhấn "OK" để xác nhận.\n[scarlet]Hoàn lại và thoát trong[accent] {0}[] giây...
|
||||||
uiscale.cancel = Hủy & Thoát
|
uiscale.cancel = Hủy & Thoát
|
||||||
@@ -855,17 +877,17 @@ keybind.clear_building.name = Xóa công trình
|
|||||||
keybind.press = Nhấn một phím...
|
keybind.press = Nhấn một phím...
|
||||||
keybind.press.axis = Nhấn một tổ hợp phím hoặc một phím...
|
keybind.press.axis = Nhấn một tổ hợp phím hoặc một phím...
|
||||||
keybind.screenshot.name = Chụp ảnh bản đồ
|
keybind.screenshot.name = Chụp ảnh bản đồ
|
||||||
keybind.toggle_power_lines.name = Toggle Power Lasers
|
keybind.toggle_power_lines.name = Ẩn/Hiện đường truyền năng lượng
|
||||||
keybind.toggle_block_status.name = Toggle Block Statuses
|
keybind.toggle_block_status.name = Ẩn/Hiện trạng thái khối
|
||||||
keybind.move_x.name = Di chuyển X
|
keybind.move_x.name = Di chuyển X
|
||||||
keybind.move_y.name = Di chuyển Y
|
keybind.move_y.name = Di chuyển Y
|
||||||
keybind.mouse_move.name = Theo chuột
|
keybind.mouse_move.name = Theo chuột
|
||||||
keybind.pan.name = Xem Pan
|
keybind.pan.name = Di chuyển góc nhìn
|
||||||
keybind.boost.name = Tăng tốc
|
keybind.boost.name = Tăng tốc
|
||||||
keybind.schematic_select.name = Chọn khu vực
|
keybind.schematic_select.name = Chọn khu vực
|
||||||
keybind.schematic_menu.name = Menu Schematic
|
keybind.schematic_menu.name = Menu bản thiết kế
|
||||||
keybind.schematic_flip_x.name = Lật Schematic X
|
keybind.schematic_flip_x.name = Lật bản thiết kế X
|
||||||
keybind.schematic_flip_y.name = Lật Schematic Y
|
keybind.schematic_flip_y.name = Lật bản thiết kế Y
|
||||||
keybind.category_prev.name = Danh mục trước
|
keybind.category_prev.name = Danh mục trước
|
||||||
keybind.category_next.name = Danh mục tiếp theo
|
keybind.category_next.name = Danh mục tiếp theo
|
||||||
keybind.block_select_left.name = Chọn khối trái
|
keybind.block_select_left.name = Chọn khối trái
|
||||||
@@ -903,11 +925,12 @@ keybind.chat.name = Trò chuyện
|
|||||||
keybind.player_list.name = Danh sách người chơi
|
keybind.player_list.name = Danh sách người chơi
|
||||||
keybind.console.name = Bảng điều khiển
|
keybind.console.name = Bảng điều khiển
|
||||||
keybind.rotate.name = Xoay
|
keybind.rotate.name = Xoay
|
||||||
keybind.rotateplaced.name = Xoay hiện có (Giữ)
|
keybind.rotateplaced.name = Xoay khối (Giữ)
|
||||||
keybind.toggle_menus.name = Chuyển đổi Menus
|
keybind.toggle_menus.name = Ẩn/Hiện Menus
|
||||||
keybind.chat_history_prev.name = Lịch sử trò chuyện trước
|
keybind.chat_history_prev.name = Lịch sử trò chuyện trước
|
||||||
keybind.chat_history_next.name = Lịch sử trò chuyện sau
|
keybind.chat_history_next.name = Lịch sử trò chuyện sau
|
||||||
keybind.chat_scroll.name = Cuộn trò chuyện
|
keybind.chat_scroll.name = Cuộn trò chuyện
|
||||||
|
keybind.chat_mode.name = Thay đổi chế độ trò chuyện
|
||||||
keybind.drop_unit.name = Thả quân
|
keybind.drop_unit.name = Thả quân
|
||||||
keybind.zoom_minimap.name = Thu phóng bản đồ mini
|
keybind.zoom_minimap.name = Thu phóng bản đồ mini
|
||||||
mode.help.title = Mô tả chế độ
|
mode.help.title = Mô tả chế độ
|
||||||
@@ -924,7 +947,8 @@ mode.custom = Tùy chỉnh luật
|
|||||||
|
|
||||||
rules.infiniteresources = Tài nguyên vô hạn
|
rules.infiniteresources = Tài nguyên vô hạn
|
||||||
rules.reactorexplosions = Nổ lò phản ứng
|
rules.reactorexplosions = Nổ lò phản ứng
|
||||||
rules.schematic = Cho phép dùng schematic
|
rules.coreincinerates = Hủy vật phẩm khi căn cứ đầy
|
||||||
|
rules.schematic = Cho phép dùng bản thiết kế
|
||||||
rules.wavetimer = Đếm ngược đợt
|
rules.wavetimer = Đếm ngược đợt
|
||||||
rules.waves = Đợt
|
rules.waves = Đợt
|
||||||
rules.attack = Chế độ tấn công
|
rules.attack = Chế độ tấn công
|
||||||
@@ -935,6 +959,8 @@ rules.blockdamagemultiplier = Hệ số sát thương của khối
|
|||||||
rules.unitbuildspeedmultiplier = Hệ số tốc độ sản xuất lính
|
rules.unitbuildspeedmultiplier = Hệ số tốc độ sản xuất lính
|
||||||
rules.unithealthmultiplier = Hệ số máu của quân lính
|
rules.unithealthmultiplier = Hệ số máu của quân lính
|
||||||
rules.unitdamagemultiplier = Hệ số sát thương của quân lính
|
rules.unitdamagemultiplier = Hệ số sát thương của quân lính
|
||||||
|
rules.unitcapvariable = Căn cứ tăng giới hạn quân lính
|
||||||
|
rules.unitcap = Giới hạn quân lính
|
||||||
rules.enemycorebuildradius = Bán kính không xây dựng trong căn cứ của kẻ địch:[lightgray] (ô)
|
rules.enemycorebuildradius = Bán kính không xây dựng trong căn cứ của kẻ địch:[lightgray] (ô)
|
||||||
rules.wavespacing = Thời gian giữa các đợt:[lightgray] (giây)
|
rules.wavespacing = Thời gian giữa các đợt:[lightgray] (giây)
|
||||||
rules.buildcostmultiplier = Hệ số chi phí xây dựng
|
rules.buildcostmultiplier = Hệ số chi phí xây dựng
|
||||||
@@ -956,6 +982,7 @@ rules.explosions = Sát thương nổ của Khối/Quân lính
|
|||||||
rules.ambientlight = Ánh sáng môi trường
|
rules.ambientlight = Ánh sáng môi trường
|
||||||
rules.weather = Thời tiết
|
rules.weather = Thời tiết
|
||||||
rules.weather.frequency = Tần suất:
|
rules.weather.frequency = Tần suất:
|
||||||
|
rules.weather.always = Luôn luôn
|
||||||
rules.weather.duration = Thời gian:
|
rules.weather.duration = Thời gian:
|
||||||
|
|
||||||
content.item.name = Vật phẩm
|
content.item.name = Vật phẩm
|
||||||
@@ -977,7 +1004,7 @@ item.surge-alloy.name = Hợp kim
|
|||||||
item.spore-pod.name = Vỏ bào tử
|
item.spore-pod.name = Vỏ bào tử
|
||||||
item.sand.name = Cát
|
item.sand.name = Cát
|
||||||
item.blast-compound.name = Chất nổ
|
item.blast-compound.name = Chất nổ
|
||||||
item.pyratite.name = Tiền chất nổ
|
item.pyratite.name = Nhiệt thạch
|
||||||
item.metaglass.name = Thuỷ tinh
|
item.metaglass.name = Thuỷ tinh
|
||||||
item.scrap.name = Phế liệu
|
item.scrap.name = Phế liệu
|
||||||
liquid.water.name = Nước
|
liquid.water.name = Nước
|
||||||
@@ -1044,7 +1071,7 @@ block.moss.name = Rêu
|
|||||||
block.shrubs.name = Bụi cây
|
block.shrubs.name = Bụi cây
|
||||||
block.spore-moss.name = Rêu bào tử
|
block.spore-moss.name = Rêu bào tử
|
||||||
block.shale-wall.name = Tường đá phiến sét
|
block.shale-wall.name = Tường đá phiến sét
|
||||||
block.scrap-wall.name = Tường sắt vụn
|
block.scrap-wall.name = Tường phế liệu
|
||||||
block.scrap-wall-large.name = Tường phế liệu lớn
|
block.scrap-wall-large.name = Tường phế liệu lớn
|
||||||
block.scrap-wall-huge.name = Tường phế liệu khổng lồ
|
block.scrap-wall-huge.name = Tường phế liệu khổng lồ
|
||||||
block.scrap-wall-gigantic.name = Tường phế liệu siêu khổng lồ
|
block.scrap-wall-gigantic.name = Tường phế liệu siêu khổng lồ
|
||||||
@@ -1105,8 +1132,8 @@ block.copper-wall.name = Tường đồng
|
|||||||
block.copper-wall-large.name = Tường đồng lớn
|
block.copper-wall-large.name = Tường đồng lớn
|
||||||
block.titanium-wall.name = Tường titan
|
block.titanium-wall.name = Tường titan
|
||||||
block.titanium-wall-large.name = Tường titan lớn
|
block.titanium-wall-large.name = Tường titan lớn
|
||||||
block.plastanium-wall.name = Tường Plastanium
|
block.plastanium-wall.name = Tường Nhựa
|
||||||
block.plastanium-wall-large.name = Tường Plastanium lớn
|
block.plastanium-wall-large.name = Tường Nhựa lớn
|
||||||
block.phase-wall.name = Tường Phase
|
block.phase-wall.name = Tường Phase
|
||||||
block.phase-wall-large.name = Tường Phase lớn
|
block.phase-wall-large.name = Tường Phase lớn
|
||||||
block.thorium-wall.name = Tường Thorium
|
block.thorium-wall.name = Tường Thorium
|
||||||
@@ -1122,9 +1149,9 @@ block.conveyor.name = Băng chuyền
|
|||||||
block.titanium-conveyor.name = Băng chuyền titan
|
block.titanium-conveyor.name = Băng chuyền titan
|
||||||
block.plastanium-conveyor.name = Băng chuyền nhựa
|
block.plastanium-conveyor.name = Băng chuyền nhựa
|
||||||
block.armored-conveyor.name = Băng chuyền bọc giáp
|
block.armored-conveyor.name = Băng chuyền bọc giáp
|
||||||
block.junction.name = Junction
|
block.junction.name = Giao điểm
|
||||||
block.router.name = Bộ định tuyến
|
block.router.name = Bộ phân phát
|
||||||
block.distributor.name = Bộ phân phát
|
block.distributor.name = Bộ phân phát lớn
|
||||||
block.sorter.name = Bộ lọc
|
block.sorter.name = Bộ lọc
|
||||||
block.inverted-sorter.name = Bộ lọc ngược
|
block.inverted-sorter.name = Bộ lọc ngược
|
||||||
block.message.name = Thông điệp
|
block.message.name = Thông điệp
|
||||||
@@ -1134,8 +1161,8 @@ block.underflow-gate.name = Cổng tràn ngược
|
|||||||
block.silicon-smelter.name = Máy nấu silicon
|
block.silicon-smelter.name = Máy nấu silicon
|
||||||
block.phase-weaver.name = Máy tạo Phase
|
block.phase-weaver.name = Máy tạo Phase
|
||||||
block.pulverizer.name = Máy nghiền
|
block.pulverizer.name = Máy nghiền
|
||||||
block.cryofluid-mixer.name = Máy sản xuất chất làm mát
|
block.cryofluid-mixer.name = Máy sản xuất chất làm lạnh
|
||||||
block.melter.name = Máy nung chảy
|
block.melter.name = Lò nung chảy
|
||||||
block.incinerator.name = Máy phân hủy
|
block.incinerator.name = Máy phân hủy
|
||||||
block.spore-press.name = Máy nén bào tử
|
block.spore-press.name = Máy nén bào tử
|
||||||
block.separator.name = Máy phân tách
|
block.separator.name = Máy phân tách
|
||||||
@@ -1162,7 +1189,7 @@ block.item-void.name = Hủy vật phẩm
|
|||||||
block.liquid-source.name = Nguồn chất lỏng
|
block.liquid-source.name = Nguồn chất lỏng
|
||||||
block.liquid-void.name = Hủy chất lỏng
|
block.liquid-void.name = Hủy chất lỏng
|
||||||
block.power-void.name = Hủy năng lượng
|
block.power-void.name = Hủy năng lượng
|
||||||
block.power-source.name = Vô hạn năng lượng
|
block.power-source.name = Nguồn năng lượng
|
||||||
block.unloader.name = Điểm dỡ hàng
|
block.unloader.name = Điểm dỡ hàng
|
||||||
block.vault.name = Nhà kho
|
block.vault.name = Nhà kho
|
||||||
block.wave.name = Wave
|
block.wave.name = Wave
|
||||||
@@ -1171,9 +1198,9 @@ block.swarmer.name = Swarmer
|
|||||||
block.salvo.name = Salvo
|
block.salvo.name = Salvo
|
||||||
block.ripple.name = Ripple
|
block.ripple.name = Ripple
|
||||||
block.phase-conveyor.name = Phase Conveyor
|
block.phase-conveyor.name = Phase Conveyor
|
||||||
block.bridge-conveyor.name = Bridge Conveyor
|
block.bridge-conveyor.name = Cầu dẫn
|
||||||
block.plastanium-compressor.name = Máy sản xuất nhựa
|
block.plastanium-compressor.name = Máy sản xuất nhựa
|
||||||
block.pyratite-mixer.name = Máy trộn tiền chất nổ
|
block.pyratite-mixer.name = Máy trộn nhiệt thạch
|
||||||
block.blast-mixer.name = Máy trộn chất nổ
|
block.blast-mixer.name = Máy trộn chất nổ
|
||||||
block.solar-panel.name = Pin mặt trời
|
block.solar-panel.name = Pin mặt trời
|
||||||
block.solar-panel-large.name = Pin mặt trời lớn
|
block.solar-panel-large.name = Pin mặt trời lớn
|
||||||
@@ -1182,10 +1209,10 @@ block.repair-point.name = Điểm sửa chữa
|
|||||||
block.pulse-conduit.name = Ống dẫn titan
|
block.pulse-conduit.name = Ống dẫn titan
|
||||||
block.plated-conduit.name = Ống dẫn bọc giáp
|
block.plated-conduit.name = Ống dẫn bọc giáp
|
||||||
block.phase-conduit.name = Ống dẫn Phase
|
block.phase-conduit.name = Ống dẫn Phase
|
||||||
block.liquid-router.name = Bộ định tuyến chất lỏng
|
block.liquid-router.name = Bộ phân phát chất lỏng
|
||||||
block.liquid-tank.name = Thùng chất lỏng
|
block.liquid-tank.name = Thùng chất lỏng
|
||||||
block.liquid-junction.name = Liquid Junction
|
block.liquid-junction.name = Giao điểm chất lỏng
|
||||||
block.bridge-conduit.name = Bridge Conduit
|
block.bridge-conduit.name = Cầu dẫn chất lỏng
|
||||||
block.rotary-pump.name = Bơm điện
|
block.rotary-pump.name = Bơm điện
|
||||||
block.thorium-reactor.name = Lò phản ứng Thorium
|
block.thorium-reactor.name = Lò phản ứng Thorium
|
||||||
block.mass-driver.name = Máy phóng điện từ
|
block.mass-driver.name = Máy phóng điện từ
|
||||||
@@ -1227,11 +1254,11 @@ block.overdrive-dome.name = Máy tăng tốc lớn
|
|||||||
#experimental, may be removed
|
#experimental, may be removed
|
||||||
block.block-forge.name = Block Forge
|
block.block-forge.name = Block Forge
|
||||||
block.block-loader.name = Block Loader
|
block.block-loader.name = Block Loader
|
||||||
block.block-unloader.name = Block Unloader
|
block.block-unloader.name = Điểm dỡ hàng
|
||||||
block.interplanetary-accelerator.name = Máy gia tốc liên hành tinh
|
block.interplanetary-accelerator.name = Máy gia tốc liên hành tinh
|
||||||
|
|
||||||
block.switch.name = Công tắc
|
block.switch.name = Công tắc
|
||||||
block.micro-processor.name = Bộ xử lí mini
|
block.micro-processor.name = Bộ xử lí nhỏ
|
||||||
block.logic-processor.name = Bộ xử lý
|
block.logic-processor.name = Bộ xử lý
|
||||||
block.hyper-processor.name = Bộ xử lý lớn
|
block.hyper-processor.name = Bộ xử lý lớn
|
||||||
block.logic-display.name = Màn hình
|
block.logic-display.name = Màn hình
|
||||||
@@ -1282,6 +1309,9 @@ hint.payloadDrop.mobile = [accent]Nhấn và giữ[] tại một khu vực trố
|
|||||||
hint.waveFire = [accent]Wave[] súng có nước làm đạn dược sẽ tự động dập tắt các đám cháy gần đó.
|
hint.waveFire = [accent]Wave[] súng có nước làm đạn dược sẽ tự động dập tắt các đám cháy gần đó.
|
||||||
hint.generator = \uf879 [accent]Máy phát điện đốt cháy[] đốt than và truyền năng lượng cho các khối liền kề.\n\nPhạm vi truyền tải năng lượng có thể được mở rộng với \uf87f [accent]Chốt điện[].
|
hint.generator = \uf879 [accent]Máy phát điện đốt cháy[] đốt than và truyền năng lượng cho các khối liền kề.\n\nPhạm vi truyền tải năng lượng có thể được mở rộng với \uf87f [accent]Chốt điện[].
|
||||||
hint.guardian = [accent]Boss[] được bọc giáp. Sử dụng loại đạn yếu chẳng hạn như [accent]Đồng[] và [accent]Chì[] là [scarlet]không hiệu quả[].\n\nSử dụng súng tiên tiến hơn hoặc sử dụng \uf835 [accent]Than chì làm đạn [] \uf861Duo/\uf859Salvo đạn dược để hạ gục Boss.
|
hint.guardian = [accent]Boss[] được bọc giáp. Sử dụng loại đạn yếu chẳng hạn như [accent]Đồng[] và [accent]Chì[] là [scarlet]không hiệu quả[].\n\nSử dụng súng tiên tiến hơn hoặc sử dụng \uf835 [accent]Than chì làm đạn [] \uf861Duo/\uf859Salvo đạn dược để hạ gục Boss.
|
||||||
|
hint.coreUpgrade = Các căn cứ có thể được nâng cấp bằng cách [accent]đặt căn cứ cấp cao hơn trên chúng[].\n\nĐặt một căn cứ [accent]Trụ sở[] trên căn cứ [accent]Cơ sở[]. Đảm bảo không có vật cản gần đó.
|
||||||
|
hint.presetLaunch = Khác khu vực đáp [accent] xám[], như [accent]Frozen Forest[], có thể được phóng đến từ bất cứ đâu. Nó không yêu cầu chiếm các khu vực lân cận.\n\n[accent]Các khu vực được đánh số[], chẳng hạn như cái này, là [accent]không bắt buộc[].
|
||||||
|
hint.coopCampaign = Khi chơi chiến dịch[accent]co-op[], các vật phẩm được sản xuất trong bản đồ hiện tại cũng sẽ được gửi [accent]đến các khu vực của bạn[].\n\nBất kỳ nghiên cứu mới nào được thực hiện đều được lưu lại.
|
||||||
|
|
||||||
item.copper.description = Dùng trong tất cả các khu xây dựng và các loại đạn dược.
|
item.copper.description = Dùng trong tất cả các khu xây dựng và các loại đạn dược.
|
||||||
item.copper.details = Đồng, là kim loại phổ biến trên Serpulo. Có cấu trúc yếu trừ khi được tôi luyện.
|
item.copper.details = Đồng, là kim loại phổ biến trên Serpulo. Có cấu trúc yếu trừ khi được tôi luyện.
|
||||||
@@ -1315,15 +1345,15 @@ block.armored-conveyor.description = Vận chuyển vật phẩm về phía. Kh
|
|||||||
block.illuminator.description = Phát sáng.
|
block.illuminator.description = Phát sáng.
|
||||||
block.message.description = Lưu trữ tin nhắn giao tiếp giữa đồng đội.
|
block.message.description = Lưu trữ tin nhắn giao tiếp giữa đồng đội.
|
||||||
block.graphite-press.description = Nén than thành than chì.
|
block.graphite-press.description = Nén than thành than chì.
|
||||||
block.multi-press.description = Nén than thành than chì. Cần nước làm chất làm mát.
|
block.multi-press.description = Nén than thành than chì. Cần nước làm mát.
|
||||||
block.silicon-smelter.description = Tinh chế silicon từ cát và than.
|
block.silicon-smelter.description = Tinh chế silicon từ cát và than.
|
||||||
block.kiln.description = Nấu chảy cát và chì thành thuỷ tinh.
|
block.kiln.description = Nấu chảy cát và chì thành thuỷ tinh.
|
||||||
block.plastanium-compressor.description = Sản xuất nhựa từ dầu và titan.
|
block.plastanium-compressor.description = Sản xuất nhựa từ dầu và titan.
|
||||||
block.phase-weaver.description = Tổng hợp phase fabric từ thorium và cát.
|
block.phase-weaver.description = Tổng hợp phase fabric từ thorium và cát.
|
||||||
block.alloy-smelter.description = Trộn titan, chì, silicon và đồng thành hợp kim.
|
block.alloy-smelter.description = Trộn titan, chì, silicon và đồng thành hợp kim.
|
||||||
block.cryofluid-mixer.description = Trộn nước và bột titan để sản xuất chất làm mát.
|
block.cryofluid-mixer.description = Trộn nước và bột titan để sản xuất chất làm mát.
|
||||||
block.blast-mixer.description = Tạo ra hợp chất nổ từ tiền chất nổ và vỏ bào tử.
|
block.blast-mixer.description = Tạo ra hợp chất nổ từ nhiệt thạch và vỏ bào tử.
|
||||||
block.pyratite-mixer.description = Trộn than, chì và cát thành tiền chất nổ.
|
block.pyratite-mixer.description = Trộn than, chì và cát thành nhiệt thạch.
|
||||||
block.melter.description = Nung phế liệu thành xỉ.
|
block.melter.description = Nung phế liệu thành xỉ.
|
||||||
block.separator.description = Tách xỉ thành các thành phần khoáng của nó.
|
block.separator.description = Tách xỉ thành các thành phần khoáng của nó.
|
||||||
block.spore-press.description = Nén vỏ bào tử thành dầu.
|
block.spore-press.description = Nén vỏ bào tử thành dầu.
|
||||||
@@ -1350,10 +1380,10 @@ block.surge-wall.description = Bảo vệ công trình khỏi đạn của kẻ
|
|||||||
block.surge-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù, đôi khi tạo ra tia điện khi bị bắn.
|
block.surge-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù, đôi khi tạo ra tia điện khi bị bắn.
|
||||||
block.door.description = Một bức tường có thể đóng mở.
|
block.door.description = Một bức tường có thể đóng mở.
|
||||||
block.door-large.description = Một bức tường có thể đóng mở.
|
block.door-large.description = Một bức tường có thể đóng mở.
|
||||||
block.mender.description = Sửa chữa định kỳ các khối trong vùng lân cận.\nSử dụng silicon để tăng phạm vi và hiệu quả.
|
block.mender.description = Sửa chữa định kỳ các khối trong vùng lân cận.\nSử dụng Phase Fabric để tăng phạm vi và hiệu quả.
|
||||||
block.mend-projector.description = Sửa chữa các khối lân cận.\nSử dụng silicon để tăng phạm vi và hiệu quả.
|
block.mend-projector.description = Sửa chữa các khối lân cận.\nSử dụng Phase Fabric để tăng phạm vi và hiệu quả.
|
||||||
block.overdrive-projector.description = Tăng tốc độ làm việc của các công trình lân cận.\nSử dụng phase fabric để tăng phạm vi và hiệu quả.
|
block.overdrive-projector.description = Tăng tốc độ làm việc của các công trình lân cận.\nSử dụng phase fabric để tăng phạm vi và hiệu quả.
|
||||||
block.force-projector.description = Tạo ra một trường lực lục giác xung quanh nó, bảo vệ các tòa nhà và quân lính bên trong khỏi bị hư hại.\nQuá nóng nếu chịu quá nhiều sát thương. Sử dụng chất làm mát để giảm nhiệt độ. Sử dụng Phase fabric để tăng kích thước lá chắn.
|
block.force-projector.description = Tạo ra một trường lực lục giác xung quanh nó, bảo vệ các công trình và quân lính bên trong khỏi bị hư hại.\nQuá nóng nếu chịu quá nhiều sát thương. Sử dụng chất làm mát để giảm nhiệt độ. Sử dụng Phase fabric để tăng kích thước lá chắn.
|
||||||
block.shock-mine.description = Giải phóng tia điện khi tiếp xúc với quân lính đối phương.
|
block.shock-mine.description = Giải phóng tia điện khi tiếp xúc với quân lính đối phương.
|
||||||
block.conveyor.description = Vận chuyển vật phẩm về phía trước.
|
block.conveyor.description = Vận chuyển vật phẩm về phía trước.
|
||||||
block.titanium-conveyor.description = Vận chuyển vật phẩm về phía trước. Nhanh hơn băng chuyền tiêu chuẩn.
|
block.titanium-conveyor.description = Vận chuyển vật phẩm về phía trước. Nhanh hơn băng chuyền tiêu chuẩn.
|
||||||
@@ -1366,9 +1396,9 @@ block.inverted-sorter.description = Giống như máy phân loại, nhưng vật
|
|||||||
block.router.description = Phân phối các vật phẩm đầu vào thành 3 hướng đầu ra như nhau.
|
block.router.description = Phân phối các vật phẩm đầu vào thành 3 hướng đầu ra như nhau.
|
||||||
block.router.details = Không khuyên dùng cạnh đầu vào dây chuyền vì sẽ bị kẹt bởi đầu ra.
|
block.router.details = Không khuyên dùng cạnh đầu vào dây chuyền vì sẽ bị kẹt bởi đầu ra.
|
||||||
block.distributor.description = Phân phối các vật phẩm đầu vào thành 7 hướng đầu ra như nhau.
|
block.distributor.description = Phân phối các vật phẩm đầu vào thành 7 hướng đầu ra như nhau.
|
||||||
block.overflow-gate.description = Chỉ đưa vật phẩm ra 2 phía nếu phía trước bị chặn, không thể đặt cạnh nhau.
|
block.overflow-gate.description = Chỉ đưa vật phẩm ra 2 phía nếu phía trước bị chặn.
|
||||||
block.underflow-gate.description = Ngược với cổng tràn, chỉ đưa vật phẩm đến trước khi hai bên bị chặn, không thể đặt cạnh nhau.
|
block.underflow-gate.description = Ngược với cổng tràn, chỉ đưa vật phẩm đến trước khi hai bên bị chặn.
|
||||||
block.mass-driver.description = Cấu trúc vận chuyển vật phẩm tầm xa. Thu thập các lô vật phẩm và bắn chúng cho các mass driver khác.
|
block.mass-driver.description = Cấu trúc vận chuyển vật phẩm tầm xa. Thu thập các lô vật phẩm và bắn chúng cho các máy phóng điện từ khác.
|
||||||
block.mechanical-pump.description = Bơm chất lỏng, không yêu cầu năng lượng.
|
block.mechanical-pump.description = Bơm chất lỏng, không yêu cầu năng lượng.
|
||||||
block.rotary-pump.description = Bơm chất lỏng, yêu cầu năng lượng.
|
block.rotary-pump.description = Bơm chất lỏng, yêu cầu năng lượng.
|
||||||
block.thermal-pump.description = Bơm chất lỏng.
|
block.thermal-pump.description = Bơm chất lỏng.
|
||||||
@@ -1389,7 +1419,7 @@ block.battery-large.description = Tích trữ năng lượng khi dư thừa. Xu
|
|||||||
block.combustion-generator.description = Tạo ra năng lượng bằng cách đốt các vật liệu dễ cháy như than.
|
block.combustion-generator.description = Tạo ra năng lượng bằng cách đốt các vật liệu dễ cháy như than.
|
||||||
block.thermal-generator.description = Tạo ra năng lượng khi đặt ở những nơi nóng.
|
block.thermal-generator.description = Tạo ra năng lượng khi đặt ở những nơi nóng.
|
||||||
block.steam-generator.description = Tạo ra năng lượng bằng cách đốt cháy các vật liệu dễ cháy và chuyển nước thành hơi nước.
|
block.steam-generator.description = Tạo ra năng lượng bằng cách đốt cháy các vật liệu dễ cháy và chuyển nước thành hơi nước.
|
||||||
block.differential-generator.description = Tạo ra một lượng lớn năng lượng. Sử dụng sự chênh lệch nhiệt độ giữa cryofluid và pyratite đang cháy.
|
block.differential-generator.description = Tạo ra một lượng lớn năng lượng. Sử dụng sự chênh lệch nhiệt độ giữa chất làm lạnh và nhiệt thạch đang cháy.
|
||||||
block.rtg-generator.description = Sử dụng nhiệt của các hợp chất phóng xạ đang phân hủy để tạo ra năng lượng với tốc độ chậm.
|
block.rtg-generator.description = Sử dụng nhiệt của các hợp chất phóng xạ đang phân hủy để tạo ra năng lượng với tốc độ chậm.
|
||||||
block.solar-panel.description = Cung cấp một lượng nhỏ năng lượng từ mặt trời.
|
block.solar-panel.description = Cung cấp một lượng nhỏ năng lượng từ mặt trời.
|
||||||
block.solar-panel-large.description = Cung cấp một lượng nhỏ năng lượng từ mặt trời. Hiệu quả hơn pin mặt trời tiêu chuẩn.
|
block.solar-panel-large.description = Cung cấp một lượng nhỏ năng lượng từ mặt trời. Hiệu quả hơn pin mặt trời tiêu chuẩn.
|
||||||
@@ -1405,10 +1435,10 @@ block.cultivator.details = Công nghệ được phục hồi. Được sử d
|
|||||||
block.oil-extractor.description = Sử dụng lượng năng lượng năng lớn, sử dụng cát và nước để khoan dầu.
|
block.oil-extractor.description = Sử dụng lượng năng lượng năng lớn, sử dụng cát và nước để khoan dầu.
|
||||||
block.core-shard.description = Trung tâm của căn cứ. Sau khi bị phá hủy, khu vực này sẽ bị mất.
|
block.core-shard.description = Trung tâm của căn cứ. Sau khi bị phá hủy, khu vực này sẽ bị mất.
|
||||||
block.core-shard.details = Lần thử đầu tiên. Gọn nhẹ. Tự thay thế. Được trang bị tên lửa đẩy dùng một lần. Không được thiết kế để di chuyển giữa các hành tinh.
|
block.core-shard.details = Lần thử đầu tiên. Gọn nhẹ. Tự thay thế. Được trang bị tên lửa đẩy dùng một lần. Không được thiết kế để di chuyển giữa các hành tinh.
|
||||||
block.core-foundation.description = Trung tâm của căn cứ. Được bọc giáp. Stores more resources than a Shard.
|
block.core-foundation.description = Trung tâm của căn cứ. Được bọc giáp. Chứa được nhiều tài nguyên hơn Căn cứ: Cơ sỏ.
|
||||||
block.core-foundation.details = The second iteration.
|
block.core-foundation.details = Căn cứ cấp 2.
|
||||||
block.core-nucleus.description = Lõi của căn cứ. Bọc giáp chắc chắn. Lưu trữ lượng lớn tài nguyên.
|
block.core-nucleus.description = Lõi của căn cứ. Bọc giáp chắc chắn. Lưu trữ lượng lớn tài nguyên.
|
||||||
block.core-nucleus.details = Lần thử thứ ba và lần thử cuối.
|
block.core-nucleus.details = Căn cứ cấp 3 và cũng là cấp cao nhất.
|
||||||
block.vault.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng.
|
block.vault.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng.
|
||||||
block.container.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng.
|
block.container.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng.
|
||||||
block.unloader.description = Lấy các vật phẩm được chọn từ các ô gần đó.
|
block.unloader.description = Lấy các vật phẩm được chọn từ các ô gần đó.
|
||||||
@@ -1421,17 +1451,17 @@ block.wave.description = Phóng một tia chất lỏng vào kẻ địch. Tự
|
|||||||
block.lancer.description = Tích tụ và phóng tia năng lượng mạnh vào kẻ địch trên mặt đất.
|
block.lancer.description = Tích tụ và phóng tia năng lượng mạnh vào kẻ địch trên mặt đất.
|
||||||
block.arc.description = Phóng tia điện vào kẻ địch trên mặt đất.
|
block.arc.description = Phóng tia điện vào kẻ địch trên mặt đất.
|
||||||
block.swarmer.description = Bắn tên lửa truy đuổi vào kẻ địch.
|
block.swarmer.description = Bắn tên lửa truy đuổi vào kẻ địch.
|
||||||
block.salvo.description = Bắn đạn salvo vào kẻ địch.
|
block.salvo.description = Bắn loạt đạn vào kẻ địch.
|
||||||
block.fuse.description = Bắn ba đạn xuyên giáp tầm gần vào kẻ địch.
|
block.fuse.description = Bắn ba đạn xuyên giáp tầm gần vào kẻ địch.
|
||||||
block.ripple.description = Bắn cụm đạn vào kẻ địch trên mặt đất ở tầm xa.
|
block.ripple.description = Bắn cụm đạn vào kẻ địch trên mặt đất ở tầm xa.
|
||||||
block.cyclone.description = Bắn đạn nổ vào kẻ địch ở gần.
|
block.cyclone.description = Bắn đạn nổ vào kẻ địch ở gần.
|
||||||
block.spectre.description = Bắn đạn xuyên giáp lớn ở kẻ địch trên không và trên mặt đất.
|
block.spectre.description = Bắn đạn xuyên giáp lớn ở kẻ địch trên không và trên mặt đất.
|
||||||
block.meltdown.description = Nạp và bắn một tia laser liên tục vào kẻ địch ở gần. Cần có chất làm mát để hoạt động.
|
block.meltdown.description = Nạp và bắn một tia laser liên tục vào kẻ địch ở gần. Cần có chất làm mát để hoạt động.
|
||||||
block.foreshadow.description = Bắn viên một viên đạn tỉa lớn ở tầm xa.
|
block.foreshadow.description = Bắn viên một viên đạn tỉa lớn ở tầm xa.
|
||||||
block.repair-point.description = Liên tục sửa chữa robot ở gần trong phạm vi hoạt động.
|
block.repair-point.description = Liên tục sửa chữa robot ở trong phạm vi hoạt động.
|
||||||
block.segment.description = Gây hư hại và phá hủy đạn đến. Ngoại trừ tia laser.
|
block.segment.description = Gây hư hại và phá hủy đạn đến. Ngoại trừ tia laser.
|
||||||
block.parallax.description = Bắn một tia kéo máy bay địch và làm hư hỏng nó trong quá trình kéo.
|
block.parallax.description = Bắn một tia kéo máy bay địch và làm hư hỏng nó trong quá trình kéo.
|
||||||
block.tsunami.description = Phóng một tia chất lỏng mạnh vào kẻ địch. Tự chữa cháy nếu được cung cấp nước.
|
block.tsunami.description = Phóng một tia chất lỏng mạnh vào kẻ địch. Tự chữa cháy nếu được cung cấp nước hoặc chất làm mát.
|
||||||
block.silicon-crucible.description = Tinh chế silicon từ cát và than, sử dụng tiền chất nổ làm nguồn nhiệt phụ. Có hiệu quả cao hơn khi ở nơi nóng.
|
block.silicon-crucible.description = Tinh chế silicon từ cát và than, sử dụng tiền chất nổ làm nguồn nhiệt phụ. Có hiệu quả cao hơn khi ở nơi nóng.
|
||||||
block.disassembler.description = Tách xỉ thành các kim loại khác nhau với hiệu suất thấp. Có thể sản xuất thorium.
|
block.disassembler.description = Tách xỉ thành các kim loại khác nhau với hiệu suất thấp. Có thể sản xuất thorium.
|
||||||
block.overdrive-dome.description = Tăng tốc độ làm việc của các công trình lân cận. Sử dụng phase fabric and silicon để hoạt động.
|
block.overdrive-dome.description = Tăng tốc độ làm việc của các công trình lân cận. Sử dụng phase fabric and silicon để hoạt động.
|
||||||
@@ -1447,12 +1477,12 @@ block.exponential-reconstructor.description = Nâng cấp quân của bạn lên
|
|||||||
block.tetrative-reconstructor.description = Nâng cấp quân của bạn nên cấp năm (cuối cùng).
|
block.tetrative-reconstructor.description = Nâng cấp quân của bạn nên cấp năm (cuối cùng).
|
||||||
block.switch.description = Công tắc, trạng thái có thể được đọc và điều khiển với vi xử lí logic.
|
block.switch.description = Công tắc, trạng thái có thể được đọc và điều khiển với vi xử lí logic.
|
||||||
block.micro-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình.
|
block.micro-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình.
|
||||||
block.logic-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn vi xử lí micro.
|
block.logic-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn bộ xử lí nhỏ.
|
||||||
block.hyper-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn vi xử lí logic.
|
block.hyper-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn bộ xử lí.
|
||||||
block.memory-cell.description = Lưu trữ thông tin cho bộ xử lí logic.
|
block.memory-cell.description = Lưu trữ thông tin cho bộ xử lí.
|
||||||
block.memory-bank.description = Lưu trữ thông tin cho bộ xử lí logic. Dung lượng cao.
|
block.memory-bank.description = Lưu trữ thông tin cho bộ xử lí. Dung lượng cao.
|
||||||
block.logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí logic.
|
block.logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí.
|
||||||
block.large-logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí logic.
|
block.large-logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí.
|
||||||
block.interplanetary-accelerator.description = Tòa súng từ trường cỡ lớn. Tăng tốc vật phóng đến vận tốc thoát để di chuyển giữa các hành tinh.
|
block.interplanetary-accelerator.description = Tòa súng từ trường cỡ lớn. Tăng tốc vật phóng đến vận tốc thoát để di chuyển giữa các hành tinh.
|
||||||
|
|
||||||
unit.dagger.description = Bắn đạn tiêu chuẩn vào tất cả kẻ địch xung quanh.
|
unit.dagger.description = Bắn đạn tiêu chuẩn vào tất cả kẻ địch xung quanh.
|
||||||
@@ -1466,7 +1496,7 @@ unit.quasar.description = Bắn tia laser xuyên giáp làm tổn hại kẻ đ
|
|||||||
unit.vela.description = Bắn tia laser liên tục xuyên giáp làm tổn hại kẻ địch, gây cháy và sửa chữa các tòa nhà. Có khả năng bay.
|
unit.vela.description = Bắn tia laser liên tục xuyên giáp làm tổn hại kẻ địch, gây cháy và sửa chữa các tòa nhà. Có khả năng bay.
|
||||||
unit.corvus.description = Bắn đia laser đánh bật kẻ địch và sửa chữa các tòa nhà. Có thể đi qua đa số địa hình.
|
unit.corvus.description = Bắn đia laser đánh bật kẻ địch và sửa chữa các tòa nhà. Có thể đi qua đa số địa hình.
|
||||||
unit.crawler.description = Chạy đến kẻ địch và nổ.
|
unit.crawler.description = Chạy đến kẻ địch và nổ.
|
||||||
unit.atrax.description = Bắn cục xỉ vào kẻ địch trên mặt đất. Có thể đi qua đa số địa hình.
|
unit.atrax.description = Phun xỉ nóng chảy vào kẻ địch trên mặt đất. Có thể đi qua đa số địa hình.
|
||||||
unit.spiroct.description = Bắn tia laser vào kẻ địch trên mặt đất và tự sửa chữa nó. Có thể đi qua đa số địa hình.
|
unit.spiroct.description = Bắn tia laser vào kẻ địch trên mặt đất và tự sửa chữa nó. Có thể đi qua đa số địa hình.
|
||||||
unit.arkyid.description = Bắn tia laser lớn vào kẻ địch trên mặt đất và tự sửa chữa chính nó. Có thể đi qua đa số địa hình.
|
unit.arkyid.description = Bắn tia laser lớn vào kẻ địch trên mặt đất và tự sửa chữa chính nó. Có thể đi qua đa số địa hình.
|
||||||
unit.toxopid.description = Bắn chùm đạn điện và tia laser xuyên giáp vào kẻ địch trên mặt đất và tự sửa chữa chính nó. Có thể đi qua đa số địa hình.
|
unit.toxopid.description = Bắn chùm đạn điện và tia laser xuyên giáp vào kẻ địch trên mặt đất và tự sửa chữa chính nó. Có thể đi qua đa số địa hình.
|
||||||
@@ -1479,12 +1509,148 @@ unit.mono.description = Tự động khai thác đồng và chì, và vận chuy
|
|||||||
unit.poly.description = Tự động xây dựng lại các công trình bị hỏng và hỗ trợ các quân lính khác thi công.
|
unit.poly.description = Tự động xây dựng lại các công trình bị hỏng và hỗ trợ các quân lính khác thi công.
|
||||||
unit.mega.description = Tự động sửa chữa các công trình bị hỏng. Có khả năng mang bộ binh nhỏ.
|
unit.mega.description = Tự động sửa chữa các công trình bị hỏng. Có khả năng mang bộ binh nhỏ.
|
||||||
unit.quad.description = Thả bom to lên kẻ địch, sửa chữa các tòa nhà và tổn hại kẻ địch. Có khả năng mang bộ binh vừa.
|
unit.quad.description = Thả bom to lên kẻ địch, sửa chữa các tòa nhà và tổn hại kẻ địch. Có khả năng mang bộ binh vừa.
|
||||||
unit.oct.description = Bảo vệ đồng minh với giáp. Có kả năng mang đa số bộ binh.
|
unit.oct.description = Bảo vệ đồng minh với giáp. Có khả năng mang đa số bộ binh.
|
||||||
unit.risso.description = Bắn chùm tên lửa và đạn lên kẻ địch tầm gần.
|
unit.risso.description = Bắn chùm tên lửa và đạn lên kẻ địch tầm gần.
|
||||||
unit.minke.description = Bắn đạn và đạn thường lên kẻ địch tầm gần trên mặt đất.
|
unit.minke.description = Bắn đạn và đạn thường lên kẻ địch tầm gần trên mặt đất.
|
||||||
unit.bryde.description = Bắn đạn tầm xa và tên lửa vào kẻ địch.
|
unit.bryde.description = Bắn đạn tầm xa và tên lửa vào kẻ địch.
|
||||||
unit.sei.description = Bắn chùm tên lửa và đạn xuyên giáp vào kẻ địch.
|
unit.sei.description = Bắn chùm tên lửa và đạn xuyên giáp vào kẻ địch.
|
||||||
unit.omura.description = Bắn đạn từ trường xuyên giáp tầm xa vào kẻ địch. Tạo nên drone báo hiệu.
|
unit.omura.description = Bắn đạn từ trường xuyên giáp tầm xa vào kẻ địch. Tạo nên Flare.
|
||||||
unit.alpha.description = Bảo vệ căn cứ cơ sở khỏi kẻ thù. Có thể xây dựng.
|
unit.alpha.description = Bảo vệ căn cứ cơ sở khỏi kẻ thù. Có thể xây dựng.
|
||||||
unit.beta.description = Bảo vệ căn cứ trụ sở khỏi kẻ thù. Có thể xây dựng.
|
unit.beta.description = Bảo vệ căn cứ trụ sở khỏi kẻ thù. Có thể xây dựng.
|
||||||
unit.gamma.description = Bảo vệ căn cứ trung tâm khỏi kẻ thù. Có thể xây dựng.
|
unit.gamma.description = Bảo vệ căn cứ trung tâm khỏi kẻ thù. Có thể xây dựng.
|
||||||
|
|
||||||
|
lst.read = Đọc một số từ bộ nhớ được liên kết.
|
||||||
|
lst.write = Ghi một số vào bộ nhớ được liên kết.
|
||||||
|
lst.print = Thêm văn bản vào bộ nhớ in.\nKhông hiển thị gì cho đến khi sử dụng [accent]Print Flush[].
|
||||||
|
lst.draw = Thêm một thao tác vào bộ nhớ vẽ.\nKhông hiển thị gì cho đến khi sử dụng [accent]Draw Flush[].
|
||||||
|
lst.drawflush = Chuyển các thao tác [accent]Draw[] đến màng hình.
|
||||||
|
lst.printflush = Chuyển các thao tác [accent]Print[] đến khối tin nhắn.
|
||||||
|
lst.getlink = Nhận liên kết bộ xử lý theo thứ tự. Bắt đầu từ 0.
|
||||||
|
lst.control = Điều khiển một khối.
|
||||||
|
lst.radar = Định vị các quân lính trong phạm vi xung quanh một khối.
|
||||||
|
lst.sensor = Lấy dữ liệu từ một khối hoặc quân lính.
|
||||||
|
lst.set = Đặt một biến.
|
||||||
|
lst.operation = Thực hiện thao tác trên 1-2 biến.
|
||||||
|
lst.end = Chuyển đến lệnh đầu tiên.
|
||||||
|
lst.jump = Chuyển qua lệnh khác nếu điều kiện đúng.
|
||||||
|
lst.unitbind = Bind to the next unit of a type, and store it in [accent]@unit[].
|
||||||
|
lst.unitcontrol = Control the currently bound unit.
|
||||||
|
lst.unitradar = Locate units around the currently bound unit.
|
||||||
|
lst.unitlocate = Locate a specific type of position/building anywhere on the map.\nRequires a bound unit.
|
||||||
|
|
||||||
|
lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string.
|
||||||
|
lenum.shoot = Bắn vào vị trí xác định.
|
||||||
|
lenum.shootp = Shoot at a unit/building with velocity prediction.
|
||||||
|
lenum.configure = Building configuration, e.g. sorter item.
|
||||||
|
lenum.enabled = Bất cứ khi nào khối hoạt động.
|
||||||
|
|
||||||
|
laccess.color = Màu đèn chiếu sáng.
|
||||||
|
|
||||||
|
graphicstype.clear = Tô màu cho màn hình.
|
||||||
|
graphicstype.color = Đặt màu cho thao tác vẽ tiếp theo.
|
||||||
|
graphicstype.stroke = Đặt chiều rộng đoạn thẳng.
|
||||||
|
graphicstype.line = Vẽ đoạn thẳng.
|
||||||
|
graphicstype.rect = Tô một hình chữ nhật.
|
||||||
|
graphicstype.linerect = Vẽ đường viền hình chữ nhật.
|
||||||
|
graphicstype.poly = Tô vào đa giác đều.
|
||||||
|
graphicstype.linepoly = Vẽ đường viền đa giác đều.
|
||||||
|
graphicstype.triangle = Tô một hình tam giác.
|
||||||
|
graphicstype.image = Vẽ hình ảnh một số nội dung.\nVd: [accent]@router[] hoặc [accent]@dagger[].
|
||||||
|
|
||||||
|
lenum.always = Luôn đúng.
|
||||||
|
lenum.idiv = Chia lấy phần nguyên.
|
||||||
|
lenum.div = Phép chia.\nTrả về [accent]null[] khi chia cho 0.
|
||||||
|
lenum.mod = Chia lấy phần dư.
|
||||||
|
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||||
|
lenum.notequal = Not equal. Coerces types.
|
||||||
|
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||||
|
lenum.shl = Bit-shift left.
|
||||||
|
lenum.shr = Bit-shift right.
|
||||||
|
lenum.or = Bitwise OR.
|
||||||
|
lenum.land = Logical AND.
|
||||||
|
lenum.and = Bitwise AND.
|
||||||
|
lenum.not = Bitwise flip.
|
||||||
|
lenum.xor = Bitwise XOR.
|
||||||
|
|
||||||
|
lenum.min = Số nhỏ nhất giữa hai số.
|
||||||
|
lenum.max = Số lớn nhất giữa hai số.
|
||||||
|
lenum.angle = Góc của vectơ tính bằng độ.
|
||||||
|
lenum.len = Chiều dài của vectơ.
|
||||||
|
lenum.sin = Sin, tính bằng độ.
|
||||||
|
lenum.cos = Cos, tính bằng độ.
|
||||||
|
lenum.tan = Tan, tính bằng độ.
|
||||||
|
#not a typo, look up 'range notation'
|
||||||
|
lenum.rand = Số ngẫu nhiên trong phạm vi [0, giá trị).
|
||||||
|
lenum.log = Lôgarit tự nhiên (ln).
|
||||||
|
lenum.log10 = Lôgarit cơ số 10.
|
||||||
|
lenum.noise = 2D simplex noise.
|
||||||
|
lenum.abs = Giá trị tuyệt đối.
|
||||||
|
lenum.sqrt = Căn bậc hai.
|
||||||
|
|
||||||
|
lenum.any = Bất kì quân lính.
|
||||||
|
lenum.ally = Quân lính cùng đội.
|
||||||
|
lenum.attacker = Quân lính với vũ khí.
|
||||||
|
lenum.enemy = Quân lính địch.
|
||||||
|
lenum.boss = Boss.
|
||||||
|
lenum.flying = Không quân.
|
||||||
|
lenum.ground = Bộ binh.
|
||||||
|
lenum.player = Quân lính do người chơi điều khiển.
|
||||||
|
|
||||||
|
lenum.ore = Ore deposit.
|
||||||
|
lenum.damaged = Damaged ally building.
|
||||||
|
lenum.spawn = Enemy spawn point.\nMay be a core or a position.
|
||||||
|
lenum.building = Building in a specific group.
|
||||||
|
|
||||||
|
lenum.core = Bất kì căn cứ.
|
||||||
|
lenum.storage = Khối lưu trữ, Ví dụ Nhà kho.
|
||||||
|
lenum.generator = Khối có thể tạo ra năng lượng.
|
||||||
|
lenum.factory = Khối có thể biến đổi vật phẩm.
|
||||||
|
lenum.repair = Điểm sửa chữa.
|
||||||
|
lenum.rally = Trung tâm chỉ huy.
|
||||||
|
lenum.battery = Bất kì pin.
|
||||||
|
lenum.resupply = Điểm tiếp tế.\nChỉ phù hợp khi [accent]"Quân lính cần đạn"[] được bật.
|
||||||
|
lenum.reactor = Lò phản ứng Thorium\Nhiệt hạch.
|
||||||
|
lenum.turret = Bất kì súng.
|
||||||
|
|
||||||
|
sensor.in = The building/unit to sense.
|
||||||
|
|
||||||
|
radar.from = Building to sense from.\nSensor range is limited by building range.
|
||||||
|
radar.target = Filter for units to sense.
|
||||||
|
radar.and = Additional filters.
|
||||||
|
radar.order = Sorting order. 0 to reverse.
|
||||||
|
radar.sort = Metric to sort results by.
|
||||||
|
radar.output = Variable to write output unit to.
|
||||||
|
|
||||||
|
unitradar.target = Filter for units to sense.
|
||||||
|
unitradar.and = Additional filters.
|
||||||
|
unitradar.order = Sorting order. 0 to reverse.
|
||||||
|
unitradar.sort = Metric to sort results by.
|
||||||
|
unitradar.output = Variable to write output unit to.
|
||||||
|
|
||||||
|
control.of = Building to control.
|
||||||
|
control.unit = Unit/building to aim at.
|
||||||
|
control.shoot = Whether to shoot.
|
||||||
|
|
||||||
|
unitlocate.enemy = Whether to locate enemy buildings.
|
||||||
|
unitlocate.found = Whether the object was found.
|
||||||
|
unitlocate.building = Output variable for located building.
|
||||||
|
unitlocate.outx = Output X coordinate.
|
||||||
|
unitlocate.outy = Output Y coordinate.
|
||||||
|
unitlocate.group = Building group to look for.
|
||||||
|
|
||||||
|
lenum.stop = Dừng di chuyển/Đào/Xây dựng.
|
||||||
|
lenum.move = Di chuyển đến vị trí xác định.
|
||||||
|
lenum.approach = Approach a position with a radius.
|
||||||
|
lenum.pathfind = Tìm đường đến nơi tạo ra kẻ địch.
|
||||||
|
lenum.target = Bắn vào vị trí xác định.
|
||||||
|
lenum.targetp = Shoot a target with velocity prediction.
|
||||||
|
lenum.itemdrop = Thả vật phẩm.
|
||||||
|
lenum.itemtake = Lấy vật phẩm từ khối.
|
||||||
|
lenum.paydrop = Thả khối hàng hiện tại.
|
||||||
|
lenum.paytake = Nhất khối hàng tại vị trí hiện tại.
|
||||||
|
lenum.flag = Numeric unit flag.
|
||||||
|
lenum.mine = Đào tại vị trí.
|
||||||
|
lenum.build = Xây công trình.
|
||||||
|
lenum.getblock = Fetch a building and type at coordinates.\nUnit must be in range of position.\nSolid non-buildings will have the type [accent]@solid[].
|
||||||
|
lenum.within = Kiểm tra xem quân lính có gần vị trí không.
|
||||||
|
lenum.boost = Start/stop boosting.
|
||||||
@@ -957,6 +957,8 @@ rules.blockdamagemultiplier = 建築物傷害倍數
|
|||||||
rules.unitbuildspeedmultiplier = 單位建設速度倍數
|
rules.unitbuildspeedmultiplier = 單位建設速度倍數
|
||||||
rules.unithealthmultiplier = 單位生命值倍數
|
rules.unithealthmultiplier = 單位生命值倍數
|
||||||
rules.unitdamagemultiplier = 單位傷害倍數
|
rules.unitdamagemultiplier = 單位傷害倍數
|
||||||
|
rules.unitcapvariable = 核心限制單位上限
|
||||||
|
rules.unitcap = 基礎單位上限
|
||||||
rules.enemycorebuildradius = 敵人核心禁止建設半徑︰[lightgray](格)
|
rules.enemycorebuildradius = 敵人核心禁止建設半徑︰[lightgray](格)
|
||||||
rules.wavespacing = 波次間距︰[lightgray](秒)
|
rules.wavespacing = 波次間距︰[lightgray](秒)
|
||||||
rules.buildcostmultiplier = 建設成本倍數
|
rules.buildcostmultiplier = 建設成本倍數
|
||||||
@@ -1539,7 +1541,19 @@ lenum.shoot = 對該位置開火
|
|||||||
lenum.shootp = 對指定單位/建築開火,具自瞄功能
|
lenum.shootp = 對指定單位/建築開火,具自瞄功能
|
||||||
lenum.configure = 建築設定,如分類器、兵器工廠
|
lenum.configure = 建築設定,如分類器、兵器工廠
|
||||||
lenum.enabled = 確認該建築是否啟用
|
lenum.enabled = 確認該建築是否啟用
|
||||||
lenum.color = 設定照明燈的顏色
|
|
||||||
|
laacess.color = 設定照明燈的顏色
|
||||||
|
|
||||||
|
graphicstype.clear = 重製版面為指定顏色
|
||||||
|
graphicstype.color = 為接下來的圖畫指令設定顏色
|
||||||
|
graphicstype.stroke = 為接下來的圖畫指令設定直線寬度
|
||||||
|
graphicstype.line = 畫一直線
|
||||||
|
graphicstype.rect = 畫實心長方形
|
||||||
|
graphicstype.linerect = 畫空心長方形
|
||||||
|
graphicstype.poly = 畫實心正多邊形
|
||||||
|
graphicstype.linepoly = 畫空心正多邊形
|
||||||
|
graphicstype.triangle = 畫實心三角形
|
||||||
|
graphicstype.image = 繪製內建圖畫\n如: [accent]@router[]或[accent]@dagger[].
|
||||||
|
|
||||||
lenum.always = 永遠 true (直接跳).
|
lenum.always = 永遠 true (直接跳).
|
||||||
lenum.idiv = 整數除法,無條件捨去.
|
lenum.idiv = 整數除法,無條件捨去.
|
||||||
@@ -1556,17 +1570,17 @@ lenum.and = Bitwise AND.
|
|||||||
lenum.not = Bitwise flip.
|
lenum.not = Bitwise flip.
|
||||||
lenum.xor = Bitwise XOR.
|
lenum.xor = Bitwise XOR.
|
||||||
|
|
||||||
lenum.min = Minimum of two numbers.
|
lenum.min = 兩數取小
|
||||||
lenum.max = Maximum of two numbers.
|
lenum.max = 兩數取大
|
||||||
lenum.angle = Angle of vector in degrees.
|
lenum.angle = 向量與x軸夾角
|
||||||
lenum.len = Length of vector.
|
lenum.len = 向量長度
|
||||||
lenum.sin = Sine, in degrees.
|
lenum.sin = 度數Sin值
|
||||||
lenum.cos = Cosine, in degrees.
|
lenum.cos = 度數Cos值
|
||||||
lenum.tan = Tangent, in degrees.
|
lenum.tan = 度數Tan值
|
||||||
#not a typo, look up 'range notation'
|
#not a typo, look up 'range notation'
|
||||||
lenum.rand = Random number in range [0, value).
|
lenum.rand = 產生隨機數值: [0, 值).
|
||||||
lenum.log = Natural logarithm (ln).
|
lenum.log = 自然對數(ln、log_e).
|
||||||
lenum.log10 = Base 10 logarithm.
|
lenum.log10 = 高中數學.
|
||||||
lenum.noise = 2D simplex noise.
|
lenum.noise = 2D simplex noise.
|
||||||
lenum.abs = 取絕對值
|
lenum.abs = 取絕對值
|
||||||
lenum.sqrt = 開根號
|
lenum.sqrt = 開根號
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(){
|
public void setup(){
|
||||||
|
String dataDir = OS.env("MINDUSTRY_DATA_DIR");
|
||||||
|
if(dataDir != null){
|
||||||
|
Core.settings.setDataDirectory(files.absolute(dataDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
checkLaunch();
|
||||||
loadLogger();
|
loadLogger();
|
||||||
|
|
||||||
loader = new LoadRenderer();
|
loader = new LoadRenderer();
|
||||||
@@ -145,7 +151,12 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||||||
finished = true;
|
finished = true;
|
||||||
Events.fire(new ClientLoadEvent());
|
Events.fire(new ClientLoadEvent());
|
||||||
super.resize(graphics.getWidth(), graphics.getHeight());
|
super.resize(graphics.getWidth(), graphics.getHeight());
|
||||||
app.post(() -> app.post(() -> app.post(() -> app.post(() -> super.resize(graphics.getWidth(), graphics.getHeight())))));
|
app.post(() -> app.post(() -> app.post(() -> app.post(() -> {
|
||||||
|
super.resize(graphics.getWidth(), graphics.getHeight());
|
||||||
|
|
||||||
|
//mark initialization as complete
|
||||||
|
finishLaunch();
|
||||||
|
}))));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
asyncCore.begin();
|
asyncCore.begin();
|
||||||
@@ -168,6 +179,12 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||||||
lastTime = Time.nanos();
|
lastTime = Time.nanos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exit(){
|
||||||
|
//on graceful exit, finish the launch normally.
|
||||||
|
Vars.finishLaunch();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
setup();
|
setup();
|
||||||
@@ -182,6 +199,11 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause(){
|
public void pause(){
|
||||||
|
//when the user tabs out on mobile, the exit() event doesn't fire reliably - in that case, just assume they're about to kill the app
|
||||||
|
//this isn't 100% reliable but it should work for most cases
|
||||||
|
if(mobile){
|
||||||
|
Vars.finishLaunch();
|
||||||
|
}
|
||||||
if(finished){
|
if(finished){
|
||||||
super.pause();
|
super.pause();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import java.util.*;
|
|||||||
import static arc.Core.*;
|
import static arc.Core.*;
|
||||||
|
|
||||||
public class Vars implements Loadable{
|
public class Vars implements Loadable{
|
||||||
|
/** Whether the game failed to launch last time. */
|
||||||
|
public static boolean failedToLaunch = false;
|
||||||
/** Whether to load locales.*/
|
/** Whether to load locales.*/
|
||||||
public static boolean loadLocales = true;
|
public static boolean loadLocales = true;
|
||||||
/** Whether the logger is loaded. */
|
/** Whether the logger is loaded. */
|
||||||
@@ -62,7 +64,7 @@ public class Vars implements Loadable{
|
|||||||
public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/";
|
public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/";
|
||||||
/** URL to the JSON file containing all the BE servers. Only queried in BE. */
|
/** URL to the JSON file containing all the BE servers. Only queried in BE. */
|
||||||
public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json";
|
public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json";
|
||||||
/** URL to the JSON file containing all the BE servers. */
|
/** URL to the JSON file containing all the stable servers. */
|
||||||
public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json";
|
public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json";
|
||||||
/** URL of the github issue report template.*/
|
/** URL of the github issue report template.*/
|
||||||
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md";
|
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md";
|
||||||
@@ -172,6 +174,8 @@ public class Vars implements Loadable{
|
|||||||
public static Fi schematicDirectory;
|
public static Fi schematicDirectory;
|
||||||
/** data subdirectory used for bleeding edge build versions */
|
/** data subdirectory used for bleeding edge build versions */
|
||||||
public static Fi bebuildDirectory;
|
public static Fi bebuildDirectory;
|
||||||
|
/** file used to store launch ID */
|
||||||
|
public static Fi launchIDFile;
|
||||||
/** empty map, indicates no current map */
|
/** empty map, indicates no current map */
|
||||||
public static Map emptyMap;
|
public static Map emptyMap;
|
||||||
/** map file extension */
|
/** map file extension */
|
||||||
@@ -284,6 +288,27 @@ public class Vars implements Loadable{
|
|||||||
maps.load();
|
maps.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Checks if a launch failure occurred.
|
||||||
|
* If this is the case, failedToLaunch is set to true. */
|
||||||
|
public static void checkLaunch(){
|
||||||
|
settings.setAppName(appName);
|
||||||
|
launchIDFile = settings.getDataDirectory().child("launchid.dat");
|
||||||
|
|
||||||
|
if(launchIDFile.exists()){
|
||||||
|
failedToLaunch = true;
|
||||||
|
}else{
|
||||||
|
failedToLaunch = false;
|
||||||
|
launchIDFile.writeString("go away");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Cleans up after a successful launch. */
|
||||||
|
public static void finishLaunch(){
|
||||||
|
if(launchIDFile != null){
|
||||||
|
launchIDFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void loadLogger(){
|
public static void loadLogger(){
|
||||||
if(loadedLogger) return;
|
if(loadedLogger) return;
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,16 @@ public class BaseAI{
|
|||||||
}
|
}
|
||||||
Tile wtile = world.tile(realX, realY);
|
Tile wtile = world.tile(realX, realY);
|
||||||
|
|
||||||
|
if(tile.block instanceof PayloadConveyor || tile.block instanceof PayloadAcceptor){
|
||||||
|
//near a building
|
||||||
|
for(Point2 point : Edges.getEdges(tile.block.size)){
|
||||||
|
var t = world.build(tile.x + point.x, tile.y + point.y);
|
||||||
|
if(t != null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//may intersect AI path
|
//may intersect AI path
|
||||||
tmpTiles.clear();
|
tmpTiles.clear();
|
||||||
if(tile.block.solid && wtile != null && wtile.getLinkedTilesAs(tile.block, tmpTiles).contains(t -> path.contains(t.pos()))){
|
if(tile.block.solid && wtile != null && wtile.getLinkedTilesAs(tile.block, tmpTiles).contains(t -> path.contains(t.pos()))){
|
||||||
|
|||||||
40
core/src/mindustry/ai/types/DefenderAI.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package mindustry.ai.types;
|
||||||
|
|
||||||
|
import arc.math.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.comp.*;
|
||||||
|
import mindustry.entities.units.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
|
public class DefenderAI extends AIController{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateMovement(){
|
||||||
|
if(target != null){
|
||||||
|
moveTo(target, (target instanceof Sized s ? s.hitSize()/2f * 1.1f : 0f) + unit.hitSize/2f + 15f, 50f);
|
||||||
|
unit.lookAt(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateTargeting(){
|
||||||
|
if(retarget()) target = findTarget(unit.x, unit.y, unit.range(), true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
|
||||||
|
//find unit to follow if not in rally mode
|
||||||
|
if(command() != UnitCommand.rally){
|
||||||
|
//Sort by max health and closer target.
|
||||||
|
var result = Units.closest(unit.team, x, y, Math.max(range, 400f), u -> !u.dead() && u.type != unit.type, (u, tx, ty) -> -u.maxHealth + Mathf.dst2(u.x, u.y, tx, ty) / 800f);
|
||||||
|
if(result != null) return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//find rally point
|
||||||
|
var block = targetFlag(unit.x, unit.y, BlockFlag.rally, false);
|
||||||
|
if(block != null) return block;
|
||||||
|
//return core if found
|
||||||
|
return unit.closestCore();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ public class FlyingAI extends AIController{
|
|||||||
public void updateMovement(){
|
public void updateMovement(){
|
||||||
if(target != null && unit.hasWeapons() && command() == UnitCommand.attack){
|
if(target != null && unit.hasWeapons() && command() == UnitCommand.attack){
|
||||||
if(!unit.type.circleTarget){
|
if(!unit.type.circleTarget){
|
||||||
moveTo(target, unit.range() * 0.8f);
|
moveTo(target, unit.type.range * 0.8f);
|
||||||
unit.lookAt(target);
|
unit.lookAt(target);
|
||||||
}else{
|
}else{
|
||||||
attack(120f);
|
attack(120f);
|
||||||
@@ -49,10 +49,10 @@ public class FlyingAI extends AIController{
|
|||||||
float ang = unit.angleTo(target);
|
float ang = unit.angleTo(target);
|
||||||
float diff = Angles.angleDist(ang, unit.rotation());
|
float diff = Angles.angleDist(ang, unit.rotation());
|
||||||
|
|
||||||
if(diff > 100f && vec.len() < circleLength){
|
if(diff > 70f && vec.len() < circleLength){
|
||||||
vec.setAngle(unit.vel().angle());
|
vec.setAngle(unit.vel().angle());
|
||||||
}else{
|
}else{
|
||||||
vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f));
|
vec.setAngle(Angles.moveToward(unit.vel().angle(), vec.angle(), 6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec.setLength(unit.speed());
|
vec.setLength(unit.speed());
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class FormationAI extends AIController implements FormationMember{
|
|||||||
|
|
||||||
Vec2 realtarget = vec.set(target).add(leader.vel);
|
Vec2 realtarget = vec.set(target).add(leader.vel);
|
||||||
|
|
||||||
float speed = unit.realSpeed() * unit.floorSpeedMultiplier() * Time.delta;
|
float speed = unit.realSpeed() * Time.delta;
|
||||||
unit.approach(Mathf.arrive(unit.x, unit.y, realtarget.x, realtarget.y, unit.vel, speed, 0f, speed, 1f).scl(1f / Time.delta));
|
unit.approach(Mathf.arrive(unit.x, unit.y, realtarget.x, realtarget.y, unit.vel, speed, 0f, speed, 1f).scl(1f / Time.delta));
|
||||||
|
|
||||||
if(unit.canMine() && leader.canMine()){
|
if(unit.canMine() && leader.canMine()){
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class LogicAI extends AIController{
|
|||||||
/** Time after which the unit resets its controlled and reverts to a normal unit. */
|
/** Time after which the unit resets its controlled and reverts to a normal unit. */
|
||||||
public static final float logicControlTimeout = 10f * 60f;
|
public static final float logicControlTimeout = 10f * 60f;
|
||||||
|
|
||||||
public LUnitControl control = LUnitControl.stop;
|
public LUnitControl control = LUnitControl.idle;
|
||||||
public float moveX, moveY, moveRad;
|
public float moveX, moveY, moveRad;
|
||||||
public float itemTimer, payTimer, controlTimer = logicControlTimeout, targetTimer;
|
public float itemTimer, payTimer, controlTimer = logicControlTimeout, targetTimer;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -647,10 +647,10 @@ public class Blocks implements ContentList{
|
|||||||
separator = new Separator("separator"){{
|
separator = new Separator("separator"){{
|
||||||
requirements(Category.crafting, with(Items.copper, 30, Items.titanium, 25));
|
requirements(Category.crafting, with(Items.copper, 30, Items.titanium, 25));
|
||||||
results = with(
|
results = with(
|
||||||
Items.copper, 5,
|
Items.copper, 5,
|
||||||
Items.lead, 3,
|
Items.lead, 3,
|
||||||
Items.graphite, 2,
|
Items.graphite, 2,
|
||||||
Items.titanium, 2
|
Items.titanium, 2
|
||||||
);
|
);
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
craftTime = 35f;
|
craftTime = 35f;
|
||||||
@@ -663,10 +663,10 @@ public class Blocks implements ContentList{
|
|||||||
disassembler = new Separator("disassembler"){{
|
disassembler = new Separator("disassembler"){{
|
||||||
requirements(Category.crafting, with(Items.graphite, 140, Items.titanium, 100, Items.silicon, 150, Items.surgeAlloy, 70));
|
requirements(Category.crafting, with(Items.graphite, 140, Items.titanium, 100, Items.silicon, 150, Items.surgeAlloy, 70));
|
||||||
results = with(
|
results = with(
|
||||||
Items.sand, 4,
|
Items.sand, 4,
|
||||||
Items.graphite, 2,
|
Items.graphite, 2,
|
||||||
Items.titanium, 2,
|
Items.titanium, 2,
|
||||||
Items.thorium, 1
|
Items.thorium, 1
|
||||||
);
|
);
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
craftTime = 15f;
|
craftTime = 15f;
|
||||||
@@ -1285,7 +1285,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
waterExtractor = new SolidPump("water-extractor"){{
|
waterExtractor = new SolidPump("water-extractor"){{
|
||||||
requirements(Category.production, with(Items.copper, 30, Items.graphite, 30, Items.lead, 30));
|
requirements(Category.production, with(Items.metaglass, 30, Items.graphite, 30, Items.lead, 30));
|
||||||
result = Liquids.water;
|
result = Liquids.water;
|
||||||
pumpAmount = 0.11f;
|
pumpAmount = 0.11f;
|
||||||
size = 2;
|
size = 2;
|
||||||
@@ -1370,16 +1370,12 @@ public class Blocks implements ContentList{
|
|||||||
requirements(Category.effect, with(Items.titanium, 250, Items.thorium, 125));
|
requirements(Category.effect, with(Items.titanium, 250, Items.thorium, 125));
|
||||||
size = 3;
|
size = 3;
|
||||||
itemCapacity = 1000;
|
itemCapacity = 1000;
|
||||||
flags = EnumSet.of(BlockFlag.storage);
|
|
||||||
group = BlockGroup.transportation;
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
container = new StorageBlock("container"){{
|
container = new StorageBlock("container"){{
|
||||||
requirements(Category.effect, with(Items.titanium, 100));
|
requirements(Category.effect, with(Items.titanium, 100));
|
||||||
size = 2;
|
size = 2;
|
||||||
itemCapacity = 300;
|
itemCapacity = 300;
|
||||||
flags = EnumSet.of(BlockFlag.storage);
|
|
||||||
group = BlockGroup.transportation;
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
unloader = new Unloader("unloader"){{
|
unloader = new Unloader("unloader"){{
|
||||||
@@ -1394,10 +1390,10 @@ public class Blocks implements ContentList{
|
|||||||
duo = new ItemTurret("duo"){{
|
duo = new ItemTurret("duo"){{
|
||||||
requirements(Category.turret, with(Items.copper, 35), true);
|
requirements(Category.turret, with(Items.copper, 35), true);
|
||||||
ammo(
|
ammo(
|
||||||
Items.copper, Bullets.standardCopper,
|
Items.copper, Bullets.standardCopper,
|
||||||
Items.graphite, Bullets.standardDense,
|
Items.graphite, Bullets.standardDense,
|
||||||
Items.pyratite, Bullets.standardIncendiary,
|
Items.pyratite, Bullets.standardIncendiary,
|
||||||
Items.silicon, Bullets.standardHoming
|
Items.silicon, Bullets.standardHoming
|
||||||
);
|
);
|
||||||
|
|
||||||
spread = 4f;
|
spread = 4f;
|
||||||
@@ -1416,9 +1412,9 @@ public class Blocks implements ContentList{
|
|||||||
scatter = new ItemTurret("scatter"){{
|
scatter = new ItemTurret("scatter"){{
|
||||||
requirements(Category.turret, with(Items.copper, 85, Items.lead, 45));
|
requirements(Category.turret, with(Items.copper, 85, Items.lead, 45));
|
||||||
ammo(
|
ammo(
|
||||||
Items.scrap, Bullets.flakScrap,
|
Items.scrap, Bullets.flakScrap,
|
||||||
Items.lead, Bullets.flakLead,
|
Items.lead, Bullets.flakLead,
|
||||||
Items.metaglass, Bullets.flakGlass
|
Items.metaglass, Bullets.flakGlass
|
||||||
);
|
);
|
||||||
reloadTime = 18f;
|
reloadTime = 18f;
|
||||||
range = 160f;
|
range = 160f;
|
||||||
@@ -1439,8 +1435,8 @@ public class Blocks implements ContentList{
|
|||||||
scorch = new ItemTurret("scorch"){{
|
scorch = new ItemTurret("scorch"){{
|
||||||
requirements(Category.turret, with(Items.copper, 25, Items.graphite, 22));
|
requirements(Category.turret, with(Items.copper, 25, Items.graphite, 22));
|
||||||
ammo(
|
ammo(
|
||||||
Items.coal, Bullets.basicFlame,
|
Items.coal, Bullets.basicFlame,
|
||||||
Items.pyratite, Bullets.pyraFlame
|
Items.pyratite, Bullets.pyraFlame
|
||||||
);
|
);
|
||||||
recoilAmount = 0f;
|
recoilAmount = 0f;
|
||||||
reloadTime = 6f;
|
reloadTime = 6f;
|
||||||
@@ -1456,9 +1452,9 @@ public class Blocks implements ContentList{
|
|||||||
hail = new ItemTurret("hail"){{
|
hail = new ItemTurret("hail"){{
|
||||||
requirements(Category.turret, with(Items.copper, 40, Items.graphite, 17));
|
requirements(Category.turret, with(Items.copper, 40, Items.graphite, 17));
|
||||||
ammo(
|
ammo(
|
||||||
Items.graphite, Bullets.artilleryDense,
|
Items.graphite, Bullets.artilleryDense,
|
||||||
Items.silicon, Bullets.artilleryHoming,
|
Items.silicon, Bullets.artilleryHoming,
|
||||||
Items.pyratite, Bullets.artilleryIncendiary
|
Items.pyratite, Bullets.artilleryIncendiary
|
||||||
);
|
);
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
reloadTime = 60f;
|
reloadTime = 60f;
|
||||||
@@ -1473,10 +1469,10 @@ public class Blocks implements ContentList{
|
|||||||
wave = new LiquidTurret("wave"){{
|
wave = new LiquidTurret("wave"){{
|
||||||
requirements(Category.turret, with(Items.metaglass, 45, Items.lead, 75));
|
requirements(Category.turret, with(Items.metaglass, 45, Items.lead, 75));
|
||||||
ammo(
|
ammo(
|
||||||
Liquids.water, Bullets.waterShot,
|
Liquids.water, Bullets.waterShot,
|
||||||
Liquids.slag, Bullets.slagShot,
|
Liquids.slag, Bullets.slagShot,
|
||||||
Liquids.cryofluid, Bullets.cryoShot,
|
Liquids.cryofluid, Bullets.cryoShot,
|
||||||
Liquids.oil, Bullets.oilShot
|
Liquids.oil, Bullets.oilShot
|
||||||
);
|
);
|
||||||
size = 2;
|
size = 2;
|
||||||
recoilAmount = 0f;
|
recoilAmount = 0f;
|
||||||
@@ -1562,9 +1558,9 @@ public class Blocks implements ContentList{
|
|||||||
swarmer = new ItemTurret("swarmer"){{
|
swarmer = new ItemTurret("swarmer"){{
|
||||||
requirements(Category.turret, with(Items.graphite, 35, Items.titanium, 35, Items.plastanium, 45, Items.silicon, 30));
|
requirements(Category.turret, with(Items.graphite, 35, Items.titanium, 35, Items.plastanium, 45, Items.silicon, 30));
|
||||||
ammo(
|
ammo(
|
||||||
Items.blastCompound, Bullets.missileExplosive,
|
Items.blastCompound, Bullets.missileExplosive,
|
||||||
Items.pyratite, Bullets.missileIncendiary,
|
Items.pyratite, Bullets.missileIncendiary,
|
||||||
Items.surgeAlloy, Bullets.missileSurge
|
Items.surgeAlloy, Bullets.missileSurge
|
||||||
);
|
);
|
||||||
reloadTime = 30f;
|
reloadTime = 30f;
|
||||||
shots = 4;
|
shots = 4;
|
||||||
@@ -1580,11 +1576,11 @@ public class Blocks implements ContentList{
|
|||||||
salvo = new ItemTurret("salvo"){{
|
salvo = new ItemTurret("salvo"){{
|
||||||
requirements(Category.turret, with(Items.copper, 100, Items.graphite, 90, Items.titanium, 60));
|
requirements(Category.turret, with(Items.copper, 100, Items.graphite, 90, Items.titanium, 60));
|
||||||
ammo(
|
ammo(
|
||||||
Items.copper, Bullets.standardCopper,
|
Items.copper, Bullets.standardCopper,
|
||||||
Items.graphite, Bullets.standardDense,
|
Items.graphite, Bullets.standardDense,
|
||||||
Items.pyratite, Bullets.standardIncendiary,
|
Items.pyratite, Bullets.standardIncendiary,
|
||||||
Items.silicon, Bullets.standardHoming,
|
Items.silicon, Bullets.standardHoming,
|
||||||
Items.thorium, Bullets.standardThorium
|
Items.thorium, Bullets.standardThorium
|
||||||
);
|
);
|
||||||
|
|
||||||
size = 2;
|
size = 2;
|
||||||
@@ -1606,12 +1602,12 @@ public class Blocks implements ContentList{
|
|||||||
requirements(Category.turret, with(Items.silicon, 130, Items.thorium, 80, Items.phaseFabric, 40));
|
requirements(Category.turret, with(Items.silicon, 130, Items.thorium, 80, Items.phaseFabric, 40));
|
||||||
|
|
||||||
health = 250 * size * size;
|
health = 250 * size * size;
|
||||||
range = 160f;
|
range = 180f;
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
consumes.powerCond(8f, (PointDefenseBuild b) -> b.target != null);
|
consumes.powerCond(8f, (PointDefenseBuild b) -> b.target != null);
|
||||||
size = 2;
|
size = 2;
|
||||||
shootLength = 5f;
|
shootLength = 5f;
|
||||||
bulletDamage = 25f;
|
bulletDamage = 30f;
|
||||||
reloadTime = 9f;
|
reloadTime = 9f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -1624,7 +1620,6 @@ public class Blocks implements ContentList{
|
|||||||
Liquids.oil, Bullets.heavyOilShot
|
Liquids.oil, Bullets.heavyOilShot
|
||||||
);
|
);
|
||||||
size = 3;
|
size = 3;
|
||||||
recoilAmount = 0f;
|
|
||||||
reloadTime = 2f;
|
reloadTime = 2f;
|
||||||
shots = 2;
|
shots = 2;
|
||||||
velocityInaccuracy = 0.1f;
|
velocityInaccuracy = 0.1f;
|
||||||
@@ -1658,31 +1653,31 @@ public class Blocks implements ContentList{
|
|||||||
float brange = range + 10f;
|
float brange = range + 10f;
|
||||||
|
|
||||||
ammo(
|
ammo(
|
||||||
Items.titanium, new ShrapnelBulletType(){{
|
Items.titanium, new ShrapnelBulletType(){{
|
||||||
length = brange;
|
length = brange;
|
||||||
damage = 66f;
|
damage = 66f;
|
||||||
ammoMultiplier = 4f;
|
ammoMultiplier = 4f;
|
||||||
width = 17f;
|
width = 17f;
|
||||||
reloadMultiplier = 1.3f;
|
reloadMultiplier = 1.3f;
|
||||||
}},
|
}},
|
||||||
Items.thorium, new ShrapnelBulletType(){{
|
Items.thorium, new ShrapnelBulletType(){{
|
||||||
length = brange;
|
length = brange;
|
||||||
damage = 105f;
|
damage = 105f;
|
||||||
ammoMultiplier = 5f;
|
ammoMultiplier = 5f;
|
||||||
toColor = Pal.thoriumPink;
|
toColor = Pal.thoriumPink;
|
||||||
shootEffect = smokeEffect = Fx.thoriumShoot;
|
shootEffect = smokeEffect = Fx.thoriumShoot;
|
||||||
}}
|
}}
|
||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
ripple = new ItemTurret("ripple"){{
|
ripple = new ItemTurret("ripple"){{
|
||||||
requirements(Category.turret, with(Items.copper, 150, Items.graphite, 135, Items.titanium, 60));
|
requirements(Category.turret, with(Items.copper, 150, Items.graphite, 135, Items.titanium, 60));
|
||||||
ammo(
|
ammo(
|
||||||
Items.graphite, Bullets.artilleryDense,
|
Items.graphite, Bullets.artilleryDense,
|
||||||
Items.silicon, Bullets.artilleryHoming,
|
Items.silicon, Bullets.artilleryHoming,
|
||||||
Items.pyratite, Bullets.artilleryIncendiary,
|
Items.pyratite, Bullets.artilleryIncendiary,
|
||||||
Items.blastCompound, Bullets.artilleryExplosive,
|
Items.blastCompound, Bullets.artilleryExplosive,
|
||||||
Items.plastanium, Bullets.artilleryPlastic
|
Items.plastanium, Bullets.artilleryPlastic
|
||||||
);
|
);
|
||||||
|
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
@@ -1708,10 +1703,10 @@ public class Blocks implements ContentList{
|
|||||||
cyclone = new ItemTurret("cyclone"){{
|
cyclone = new ItemTurret("cyclone"){{
|
||||||
requirements(Category.turret, with(Items.copper, 200, Items.titanium, 125, Items.plastanium, 80));
|
requirements(Category.turret, with(Items.copper, 200, Items.titanium, 125, Items.plastanium, 80));
|
||||||
ammo(
|
ammo(
|
||||||
Items.metaglass, Bullets.fragGlass,
|
Items.metaglass, Bullets.fragGlass,
|
||||||
Items.blastCompound, Bullets.fragExplosive,
|
Items.blastCompound, Bullets.fragExplosive,
|
||||||
Items.plastanium, Bullets.fragPlastic,
|
Items.plastanium, Bullets.fragPlastic,
|
||||||
Items.surgeAlloy, Bullets.fragSurge
|
Items.surgeAlloy, Bullets.fragSurge
|
||||||
);
|
);
|
||||||
xRand = 4f;
|
xRand = 4f;
|
||||||
reloadTime = 8f;
|
reloadTime = 8f;
|
||||||
@@ -1731,19 +1726,19 @@ public class Blocks implements ContentList{
|
|||||||
|
|
||||||
requirements(Category.turret, with(Items.copper, 1000, Items.metaglass, 600, Items.surgeAlloy, 300, Items.plastanium, 200, Items.silicon, 600));
|
requirements(Category.turret, with(Items.copper, 1000, Items.metaglass, 600, Items.surgeAlloy, 300, Items.plastanium, 200, Items.silicon, 600));
|
||||||
ammo(
|
ammo(
|
||||||
Items.surgeAlloy, new PointBulletType(){{
|
Items.surgeAlloy, new PointBulletType(){{
|
||||||
shootEffect = Fx.instShoot;
|
shootEffect = Fx.instShoot;
|
||||||
hitEffect = Fx.instHit;
|
hitEffect = Fx.instHit;
|
||||||
smokeEffect = Fx.smokeCloud;
|
smokeEffect = Fx.smokeCloud;
|
||||||
trailEffect = Fx.instTrail;
|
trailEffect = Fx.instTrail;
|
||||||
despawnEffect = Fx.instBomb;
|
despawnEffect = Fx.instBomb;
|
||||||
trailSpacing = 20f;
|
trailSpacing = 20f;
|
||||||
damage = 1350;
|
damage = 1350;
|
||||||
buildingDamageMultiplier = 0.3f;
|
buildingDamageMultiplier = 0.3f;
|
||||||
speed = brange;
|
speed = brange;
|
||||||
hitShake = 6f;
|
hitShake = 6f;
|
||||||
ammoMultiplier = 1f;
|
ammoMultiplier = 1f;
|
||||||
}}
|
}}
|
||||||
);
|
);
|
||||||
|
|
||||||
maxAmmo = 40;
|
maxAmmo = 40;
|
||||||
@@ -1772,9 +1767,9 @@ public class Blocks implements ContentList{
|
|||||||
spectre = new ItemTurret("spectre"){{
|
spectre = new ItemTurret("spectre"){{
|
||||||
requirements(Category.turret, with(Items.copper, 900, 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,
|
||||||
Items.thorium, Bullets.standardThoriumBig
|
Items.thorium, Bullets.standardThoriumBig
|
||||||
);
|
);
|
||||||
reloadTime = 6f;
|
reloadTime = 6f;
|
||||||
coolantMultiplier = 0.5f;
|
coolantMultiplier = 0.5f;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class Bullets implements ContentList{
|
|||||||
lifetime = 80f;
|
lifetime = 80f;
|
||||||
width = height = 11f;
|
width = height = 11f;
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
splashDamageRadius = 25f;
|
splashDamageRadius = 25f * 0.75f;
|
||||||
splashDamage = 33f;
|
splashDamage = 33f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ public class Bullets implements ContentList{
|
|||||||
lifetime = 80f;
|
lifetime = 80f;
|
||||||
width = height = 13f;
|
width = height = 13f;
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
splashDamageRadius = 35f;
|
splashDamageRadius = 35f * 0.75f;
|
||||||
splashDamage = 45f;
|
splashDamage = 45f;
|
||||||
fragBullet = artilleryPlasticFrag;
|
fragBullet = artilleryPlasticFrag;
|
||||||
fragBullets = 10;
|
fragBullets = 10;
|
||||||
@@ -98,7 +98,7 @@ public class Bullets implements ContentList{
|
|||||||
lifetime = 80f;
|
lifetime = 80f;
|
||||||
width = height = 11f;
|
width = height = 11f;
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
splashDamageRadius = 25f;
|
splashDamageRadius = 25f * 0.75f;
|
||||||
splashDamage = 33f;
|
splashDamage = 33f;
|
||||||
reloadMultiplier = 1.2f;
|
reloadMultiplier = 1.2f;
|
||||||
ammoMultiplier = 3f;
|
ammoMultiplier = 3f;
|
||||||
@@ -112,7 +112,7 @@ public class Bullets implements ContentList{
|
|||||||
lifetime = 80f;
|
lifetime = 80f;
|
||||||
width = height = 13f;
|
width = height = 13f;
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
splashDamageRadius = 25f;
|
splashDamageRadius = 25f * 0.75f;
|
||||||
splashDamage = 35f;
|
splashDamage = 35f;
|
||||||
status = StatusEffects.burning;
|
status = StatusEffects.burning;
|
||||||
frontColor = Pal.lightishOrange;
|
frontColor = Pal.lightishOrange;
|
||||||
@@ -128,7 +128,7 @@ public class Bullets implements ContentList{
|
|||||||
width = height = 14f;
|
width = height = 14f;
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
ammoMultiplier = 4f;
|
ammoMultiplier = 4f;
|
||||||
splashDamageRadius = 45f;
|
splashDamageRadius = 45f * 0.75f;
|
||||||
splashDamage = 50f;
|
splashDamage = 50f;
|
||||||
backColor = Pal.missileYellowBack;
|
backColor = Pal.missileYellowBack;
|
||||||
frontColor = Pal.missileYellow;
|
frontColor = Pal.missileYellow;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import mindustry.graphics.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class StatusEffects implements ContentList{
|
public class StatusEffects implements ContentList{
|
||||||
public static StatusEffect none, burning, freezing, unmoving, slow, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed;
|
public static StatusEffect none, burning, freezing, unmoving, slow, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed, disarmed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
@@ -173,5 +173,10 @@ public class StatusEffects implements ContentList{
|
|||||||
color = Pal.plastanium;
|
color = Pal.plastanium;
|
||||||
damage = 0.1f;
|
damage = 0.1f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
disarmed = new StatusEffect("disarmed"){{
|
||||||
|
color = Color.valueOf("e9ead3");
|
||||||
|
disarm = true;
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,8 +240,8 @@ public class UnitTypes implements ContentList{
|
|||||||
fragVelocityMin = 0.4f;
|
fragVelocityMin = 0.4f;
|
||||||
|
|
||||||
hitEffect = Fx.blastExplosion;
|
hitEffect = Fx.blastExplosion;
|
||||||
splashDamage = 18f;
|
splashDamage = 16f;
|
||||||
splashDamageRadius = 30f;
|
splashDamageRadius = 13f;
|
||||||
|
|
||||||
fragBullets = 2;
|
fragBullets = 2;
|
||||||
fragLifeMin = 0f;
|
fragLifeMin = 0f;
|
||||||
@@ -257,7 +257,7 @@ public class UnitTypes implements ContentList{
|
|||||||
lifetime = 20f;
|
lifetime = 20f;
|
||||||
hitEffect = Fx.flakExplosion;
|
hitEffect = Fx.flakExplosion;
|
||||||
splashDamage = 15f;
|
splashDamage = 15f;
|
||||||
splashDamageRadius = 15f;
|
splashDamageRadius = 10f;
|
||||||
}};
|
}};
|
||||||
}};
|
}};
|
||||||
}}
|
}}
|
||||||
@@ -322,9 +322,8 @@ public class UnitTypes implements ContentList{
|
|||||||
x = 5f;
|
x = 5f;
|
||||||
shake = 2.2f;
|
shake = 2.2f;
|
||||||
y = 0.5f;
|
y = 0.5f;
|
||||||
shootY = 5f;
|
|
||||||
|
|
||||||
shootY = 2.5f;
|
shootY = 2.5f;
|
||||||
|
|
||||||
reload = 38f;
|
reload = 38f;
|
||||||
shots = 3;
|
shots = 3;
|
||||||
inaccuracy = 35;
|
inaccuracy = 35;
|
||||||
@@ -359,7 +358,6 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
quasar = new UnitType("quasar"){{
|
quasar = new UnitType("quasar"){{
|
||||||
mineTier = 3;
|
mineTier = 3;
|
||||||
hitSize = 12f;
|
|
||||||
boostMultiplier = 2f;
|
boostMultiplier = 2f;
|
||||||
health = 650f;
|
health = 650f;
|
||||||
buildSpeed = 1.7f;
|
buildSpeed = 1.7f;
|
||||||
@@ -407,19 +405,20 @@ public class UnitTypes implements ContentList{
|
|||||||
rotateSpeed = 1.6f;
|
rotateSpeed = 1.6f;
|
||||||
canDrown = false;
|
canDrown = false;
|
||||||
mechFrontSway = 1f;
|
mechFrontSway = 1f;
|
||||||
|
buildSpeed = 3f;
|
||||||
|
|
||||||
mechStepParticles = true;
|
mechStepParticles = true;
|
||||||
mechStepShake = 0.15f;
|
mechStepShake = 0.15f;
|
||||||
ammoType = AmmoTypes.powerHigh;
|
ammoType = AmmoTypes.powerHigh;
|
||||||
|
|
||||||
speed = 0.35f;
|
speed = 0.38f;
|
||||||
boostMultiplier = 2.1f;
|
boostMultiplier = 2.2f;
|
||||||
engineOffset = 12f;
|
engineOffset = 12f;
|
||||||
engineSize = 6f;
|
engineSize = 6f;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
|
|
||||||
health = 7200f;
|
health = 7500f;
|
||||||
armor = 8f;
|
armor = 9f;
|
||||||
canBoost = true;
|
canBoost = true;
|
||||||
landShake = 4f;
|
landShake = 4f;
|
||||||
immunities = ObjectSet.with(StatusEffects.burning);
|
immunities = ObjectSet.with(StatusEffects.burning);
|
||||||
@@ -443,8 +442,8 @@ public class UnitTypes implements ContentList{
|
|||||||
cooldownTime = 200f;
|
cooldownTime = 200f;
|
||||||
|
|
||||||
bullet = new ContinuousLaserBulletType(){{
|
bullet = new ContinuousLaserBulletType(){{
|
||||||
damage = 26f;
|
damage = 28f;
|
||||||
length = 170f;
|
length = 175f;
|
||||||
hitEffect = Fx.hitMeltHeal;
|
hitEffect = Fx.hitMeltHeal;
|
||||||
drawSize = 420f;
|
drawSize = 420f;
|
||||||
lifetime = 160f;
|
lifetime = 160f;
|
||||||
@@ -454,7 +453,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
shootEffect = Fx.greenLaserChargeSmall;
|
shootEffect = Fx.greenLaserChargeSmall;
|
||||||
|
|
||||||
incendChance = 0.08f;
|
incendChance = 0.09f;
|
||||||
incendSpread = 5f;
|
incendSpread = 5f;
|
||||||
incendAmount = 1;
|
incendAmount = 1;
|
||||||
|
|
||||||
@@ -471,7 +470,6 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
corvus = new UnitType("corvus"){{
|
corvus = new UnitType("corvus"){{
|
||||||
mineTier = 1;
|
|
||||||
hitSize = 29f;
|
hitSize = 29f;
|
||||||
health = 18000f;
|
health = 18000f;
|
||||||
armor = 9f;
|
armor = 9f;
|
||||||
@@ -769,7 +767,7 @@ public class UnitTypes implements ContentList{
|
|||||||
width = height = 19f;
|
width = height = 19f;
|
||||||
collidesTiles = true;
|
collidesTiles = true;
|
||||||
ammoMultiplier = 4f;
|
ammoMultiplier = 4f;
|
||||||
splashDamageRadius = 80f;
|
splashDamageRadius = 70f;
|
||||||
splashDamage = 65f;
|
splashDamage = 65f;
|
||||||
backColor = Pal.sapBulletBack;
|
backColor = Pal.sapBulletBack;
|
||||||
frontColor = lightningColor = Pal.sapBullet;
|
frontColor = lightningColor = Pal.sapBullet;
|
||||||
@@ -1373,6 +1371,8 @@ public class UnitTypes implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
oct = new UnitType("oct"){{
|
oct = new UnitType("oct"){{
|
||||||
|
defaultController = DefenderAI::new;
|
||||||
|
|
||||||
armor = 16f;
|
armor = 16f;
|
||||||
health = 24000;
|
health = 24000;
|
||||||
speed = 0.8f;
|
speed = 0.8f;
|
||||||
@@ -1537,7 +1537,7 @@ public class UnitTypes implements ContentList{
|
|||||||
width = 15f;
|
width = 15f;
|
||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
ammoMultiplier = 4f;
|
ammoMultiplier = 4f;
|
||||||
splashDamageRadius = 50f;
|
splashDamageRadius = 40f;
|
||||||
splashDamage = 80f;
|
splashDamage = 80f;
|
||||||
backColor = Pal.missileYellowBack;
|
backColor = Pal.missileYellowBack;
|
||||||
frontColor = Pal.missileYellow;
|
frontColor = Pal.missileYellow;
|
||||||
|
|||||||
@@ -59,6 +59,15 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
saves = new Saves();
|
saves = new Saves();
|
||||||
sound = new SoundControl();
|
sound = new SoundControl();
|
||||||
|
|
||||||
|
//show dialog saying that mod loading was skipped.
|
||||||
|
Events.on(ClientLoadEvent.class, e -> {
|
||||||
|
if(Vars.mods.skipModLoading() && Vars.mods.list().any()){
|
||||||
|
Time.runTask(4f, () -> {
|
||||||
|
ui.showInfo("@mods.initfailed");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Events.on(StateChangeEvent.class, event -> {
|
Events.on(StateChangeEvent.class, event -> {
|
||||||
if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){
|
if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){
|
||||||
Time.runTask(5f, platform::updateRPC);
|
Time.runTask(5f, platform::updateRPC);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import mindustry.world.*;
|
|||||||
import mindustry.world.modules.*;
|
import mindustry.world.modules.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
import java.util.zip.*;
|
import java.util.zip.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -65,6 +66,13 @@ public class NetClient implements ApplicationListener{
|
|||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
|
//connection after reset
|
||||||
|
if(!net.client()){
|
||||||
|
Log.info("Connection canceled.");
|
||||||
|
disconnectQuietly();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ui.loadfrag.hide();
|
ui.loadfrag.hide();
|
||||||
ui.loadfrag.show("@connecting.data");
|
ui.loadfrag.show("@connecting.data");
|
||||||
|
|
||||||
@@ -73,9 +81,14 @@ public class NetClient implements ApplicationListener{
|
|||||||
disconnectQuietly();
|
disconnectQuietly();
|
||||||
});
|
});
|
||||||
|
|
||||||
ConnectPacket c = new ConnectPacket();
|
String locale = Core.settings.getString("locale");
|
||||||
|
if(locale.equals("default")){
|
||||||
|
locale = Locale.getDefault().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = new ConnectPacket();
|
||||||
c.name = player.name;
|
c.name = player.name;
|
||||||
c.locale = Core.settings.getString("locale");
|
c.locale = locale;
|
||||||
c.mods = mods.getModStrings();
|
c.mods = mods.getModStrings();
|
||||||
c.mobile = mobile;
|
c.mobile = mobile;
|
||||||
c.versionType = Version.type;
|
c.versionType = Version.type;
|
||||||
@@ -175,6 +188,10 @@ public class NetClient implements ApplicationListener{
|
|||||||
//called when a server receives a chat message from a player
|
//called when a server receives a chat message from a player
|
||||||
@Remote(called = Loc.server, targets = Loc.client)
|
@Remote(called = Loc.server, targets = Loc.client)
|
||||||
public static void sendChatMessage(Player player, String message){
|
public static void sendChatMessage(Player player, String message){
|
||||||
|
|
||||||
|
//do not receive chat messages from clients that are too young or not registered
|
||||||
|
if(Time.timeSinceMillis(player.con.connectTime) < 500 || !player.con.hasConnected || !player.isAdded()) return;
|
||||||
|
|
||||||
if(message.length() > maxTextLength){
|
if(message.length() > maxTextLength){
|
||||||
throw new ValidateException(player, "Player has sent a message above the text limit.");
|
throw new ValidateException(player, "Player has sent a message above the text limit.");
|
||||||
}
|
}
|
||||||
@@ -185,7 +202,7 @@ public class NetClient implements ApplicationListener{
|
|||||||
CommandResponse response = netServer.clientCommands.handleMessage(message, player);
|
CommandResponse response = netServer.clientCommands.handleMessage(message, player);
|
||||||
if(response.type == ResponseType.noCommand){ //no command to handle
|
if(response.type == ResponseType.noCommand){ //no command to handle
|
||||||
message = netServer.admins.filterMessage(player, message);
|
message = netServer.admins.filterMessage(player, message);
|
||||||
//supress chat message if it's filtered out
|
//suppress chat message if it's filtered out
|
||||||
if(message == null){
|
if(message == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -620,7 +637,7 @@ public class NetClient implements ApplicationListener{
|
|||||||
lastSent++,
|
lastSent++,
|
||||||
uid,
|
uid,
|
||||||
player.dead(),
|
player.dead(),
|
||||||
unit.x, unit.y,
|
player.dead() ? player.x : unit.x, player.dead() ? player.y : unit.y,
|
||||||
player.unit().aimX(), player.unit().aimY(),
|
player.unit().aimX(), player.unit().aimY(),
|
||||||
unit.rotation,
|
unit.rotation,
|
||||||
unit instanceof Mechc m ? m.baseRotation() : 0,
|
unit instanceof Mechc m ? m.baseRotation() : 0,
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ public class NetServer implements ApplicationListener{
|
|||||||
public NetServer(){
|
public NetServer(){
|
||||||
|
|
||||||
net.handleServer(Connect.class, (con, connect) -> {
|
net.handleServer(Connect.class, (con, connect) -> {
|
||||||
|
Events.fire(new ConnectionEvent(con));
|
||||||
|
|
||||||
if(admins.isIPBanned(connect.addressTCP) || admins.isSubnetBanned(connect.addressTCP)){
|
if(admins.isIPBanned(connect.addressTCP) || admins.isSubnetBanned(connect.addressTCP)){
|
||||||
con.kick(KickReason.banned);
|
con.kick(KickReason.banned);
|
||||||
}
|
}
|
||||||
@@ -93,10 +95,14 @@ public class NetServer implements ApplicationListener{
|
|||||||
});
|
});
|
||||||
|
|
||||||
net.handleServer(ConnectPacket.class, (con, packet) -> {
|
net.handleServer(ConnectPacket.class, (con, packet) -> {
|
||||||
|
if(con.kicked) return;
|
||||||
|
|
||||||
if(con.address.startsWith("steam:")){
|
if(con.address.startsWith("steam:")){
|
||||||
packet.uuid = con.address.substring("steam:".length());
|
packet.uuid = con.address.substring("steam:".length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
con.connectTime = Time.millis();
|
||||||
|
|
||||||
String uuid = packet.uuid;
|
String uuid = packet.uuid;
|
||||||
byte[] buuid = Base64Coder.decode(uuid);
|
byte[] buuid = Base64Coder.decode(uuid);
|
||||||
CRC32 crc = new CRC32();
|
CRC32 crc = new CRC32();
|
||||||
@@ -196,7 +202,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(packet.locale == null){
|
if(packet.locale == null){
|
||||||
packet.locale = "en_US";
|
packet.locale = "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
String ip = con.address;
|
String ip = con.address;
|
||||||
@@ -249,7 +255,8 @@ public class NetServer implements ApplicationListener{
|
|||||||
});
|
});
|
||||||
|
|
||||||
net.handleServer(InvokePacket.class, (con, packet) -> {
|
net.handleServer(InvokePacket.class, (con, packet) -> {
|
||||||
if(con.player == null) return;
|
if(con.player == null || con.kicked) return;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
RemoteReadServer.readPacket(packet.reader(), packet.type, con.player);
|
RemoteReadServer.readPacket(packet.reader(), packet.type, con.player);
|
||||||
}catch(ValidateException e){
|
}catch(ValidateException e){
|
||||||
@@ -725,6 +732,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
//no verification is done, so admins can hypothetically spam waves
|
//no verification is done, so admins can hypothetically spam waves
|
||||||
//not a real issue, because server owners may want to do just that
|
//not a real issue, because server owners may want to do just that
|
||||||
logic.skipWave();
|
logic.skipWave();
|
||||||
|
info("&lc@ has skipped the wave.", player.name);
|
||||||
}else if(action == AdminAction.ban){
|
}else if(action == AdminAction.ban){
|
||||||
netServer.admins.banPlayerIP(other.con.address);
|
netServer.admins.banPlayerIP(other.con.address);
|
||||||
netServer.admins.banPlayerID(other.con.uuid);
|
netServer.admins.banPlayerID(other.con.uuid);
|
||||||
@@ -734,7 +742,8 @@ public class NetServer implements ApplicationListener{
|
|||||||
other.kick(KickReason.kick);
|
other.kick(KickReason.kick);
|
||||||
info("&lc@ has kicked @.", player.name, other.name);
|
info("&lc@ has kicked @.", player.name, other.name);
|
||||||
}else if(action == AdminAction.trace){
|
}else if(action == AdminAction.trace){
|
||||||
TraceInfo info = new TraceInfo(other.con.address, other.uuid(), other.con.modclient, other.con.mobile);
|
PlayerInfo stats = netServer.admins.getInfo(other.uuid());
|
||||||
|
TraceInfo info = new TraceInfo(other.con.address, other.uuid(), other.con.modclient, other.con.mobile, stats.timesJoined, stats.timesKicked);
|
||||||
if(player.con != null){
|
if(player.con != null){
|
||||||
Call.traceInfo(player.con, other, info);
|
Call.traceInfo(player.con, other, info);
|
||||||
}else{
|
}else{
|
||||||
@@ -746,6 +755,8 @@ public class NetServer implements ApplicationListener{
|
|||||||
|
|
||||||
@Remote(targets = Loc.client)
|
@Remote(targets = Loc.client)
|
||||||
public static void connectConfirm(Player player){
|
public static void connectConfirm(Player player){
|
||||||
|
if(player.con.kicked) return;
|
||||||
|
|
||||||
player.add();
|
player.add();
|
||||||
|
|
||||||
if(player.con == null || player.con.hasConnected) return;
|
if(player.con == null || player.con.hasConnected) return;
|
||||||
|
|||||||
@@ -20,10 +20,9 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public interface Platform{
|
public interface Platform{
|
||||||
|
|
||||||
/** Dynamically loads a jar file. */
|
/** Dynamically creates a class loader for a jar file. */
|
||||||
default Class<?> loadJar(Fi jar, String mainClass) throws Exception{
|
default ClassLoader loadJar(Fi jar, String mainClass) throws Exception{
|
||||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, getClass().getClassLoader());
|
return new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, getClass().getClassLoader());
|
||||||
return Class.forName(mainClass, true, classLoader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Steam: Update lobby visibility.*/
|
/** Steam: Update lobby visibility.*/
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
platform.publish(map);
|
platform.publish(map);
|
||||||
}).padTop(-3).size(swidth * 2f + 10, 60f).update(b ->
|
}).padTop(-3).size(swidth * 2f + 10, 60f).update(b ->
|
||||||
b.setText(editor.tags.containsKey("steamid") ?
|
b.setText(editor.tags.containsKey("steamid") ?
|
||||||
editor.tags.get("author").equals(steamPlayerName) ? "@workshop.listing" : "@view.workshop" :
|
editor.tags.get("author", "").equals(steamPlayerName) ? "@workshop.listing" : "@view.workshop" :
|
||||||
"@editor.publish.workshop"));
|
"@editor.publish.workshop"));
|
||||||
|
|
||||||
menu.cont.row();
|
menu.cont.row();
|
||||||
|
|||||||
@@ -363,8 +363,7 @@ public class Damage{
|
|||||||
|
|
||||||
if(ground){
|
if(ground){
|
||||||
if(!complete){
|
if(!complete){
|
||||||
//increase damage slightly to compensate for new algorithm
|
tileDamage(team, World.toTile(x), World.toTile(y), radius / tilesize, damage);
|
||||||
tileDamage(team, World.toTile(x), World.toTile(y), radius / tilesize, damage * 1.1f);
|
|
||||||
}else{
|
}else{
|
||||||
completeDamage(team, x, y, radius, damage);
|
completeDamage(team, x, y, radius, damage);
|
||||||
}
|
}
|
||||||
@@ -380,8 +379,8 @@ public class Damage{
|
|||||||
//why? because otherwise the building would absorb everything in one cell, which means much less damage than a nearby explosion.
|
//why? because otherwise the building would absorb everything in one cell, which means much less damage than a nearby explosion.
|
||||||
//this needs to be compensated
|
//this needs to be compensated
|
||||||
if(in != null && in.team != team && in.block.size > 1 && in.health > damage){
|
if(in != null && in.team != team && in.block.size > 1 && in.health > damage){
|
||||||
//deal the damage of an entire side + 1, to be equivalent with maximum 'standard' damage
|
//deal the damage of an entire side, to be equivalent with maximum 'standard' damage
|
||||||
in.damage(damage * (in.block.size + 1));
|
in.damage(damage * Math.min((in.block.size), baseRadius * 0.45f));
|
||||||
//no need to continue with the explosion
|
//no need to continue with the explosion
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ public class Units{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the closest ally of this team. Filter by predicate. */
|
/** Returns the closest ally of this team in a range. Filter by predicate. */
|
||||||
public static Unit closest(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
public static Unit closest(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
||||||
result = null;
|
result = null;
|
||||||
cdist = 0f;
|
cdist = 0f;
|
||||||
@@ -266,6 +266,24 @@ public class Units{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the closest ally of this team in a range. Filter by predicate. */
|
||||||
|
public static Unit closest(Team team, float x, float y, float range, Boolf<Unit> predicate, Sortf sort){
|
||||||
|
result = null;
|
||||||
|
cdist = 0f;
|
||||||
|
|
||||||
|
nearby(team, x, y, range, e -> {
|
||||||
|
if(!predicate.get(e)) return;
|
||||||
|
|
||||||
|
float dist = sort.cost(e, x, y);
|
||||||
|
if(result == null || dist < cdist){
|
||||||
|
result = e;
|
||||||
|
cdist = dist;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the closest ally of this team. Filter by predicate.
|
/** Returns the closest ally of this team. Filter by predicate.
|
||||||
* Unlike the closest() function, this only guarantees that unit hitboxes overlap the range. */
|
* Unlike the closest() function, this only guarantees that unit hitboxes overlap the range. */
|
||||||
public static Unit closestOverlap(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
public static Unit closestOverlap(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ import mindustry.ui.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class UnitSpawnAbility extends Ability{
|
public class UnitSpawnAbility extends Ability{
|
||||||
public UnitType type;
|
public UnitType unit;
|
||||||
public float spawnTime = 60f, spawnX, spawnY;
|
public float spawnTime = 60f, spawnX, spawnY;
|
||||||
public Effect spawnEffect = Fx.spawn;
|
public Effect spawnEffect = Fx.spawn;
|
||||||
|
|
||||||
protected float timer;
|
protected float timer;
|
||||||
|
|
||||||
public UnitSpawnAbility(UnitType type, float spawnTime, float spawnX, float spawnY){
|
public UnitSpawnAbility(UnitType unit, float spawnTime, float spawnX, float spawnY){
|
||||||
this.type = type;
|
this.unit = unit;
|
||||||
this.spawnTime = spawnTime;
|
this.spawnTime = spawnTime;
|
||||||
this.spawnX = spawnX;
|
this.spawnX = spawnX;
|
||||||
this.spawnY = spawnY;
|
this.spawnY = spawnY;
|
||||||
@@ -35,10 +35,10 @@ public class UnitSpawnAbility extends Ability{
|
|||||||
public void update(Unit unit){
|
public void update(Unit unit){
|
||||||
timer += Time.delta * state.rules.unitBuildSpeedMultiplier;
|
timer += Time.delta * state.rules.unitBuildSpeedMultiplier;
|
||||||
|
|
||||||
if(timer >= spawnTime && Units.canCreate(unit.team, type)){
|
if(timer >= spawnTime && Units.canCreate(unit.team, this.unit)){
|
||||||
float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX);
|
float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX);
|
||||||
spawnEffect.at(x, y);
|
spawnEffect.at(x, y);
|
||||||
Unit u = type.create(unit.team);
|
Unit u = this.unit.create(unit.team);
|
||||||
u.set(x, y);
|
u.set(x, y);
|
||||||
u.rotation = unit.rotation;
|
u.rotation = unit.rotation;
|
||||||
if(!Vars.net.client()){
|
if(!Vars.net.client()){
|
||||||
@@ -51,16 +51,16 @@ public class UnitSpawnAbility extends Ability{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Unit unit){
|
public void draw(Unit unit){
|
||||||
if(Units.canCreate(unit.team, type)){
|
if(Units.canCreate(unit.team, this.unit)){
|
||||||
Draw.draw(Draw.z(), () -> {
|
Draw.draw(Draw.z(), () -> {
|
||||||
float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX);
|
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);
|
Drawf.construct(x, y, this.unit.icon(Cicon.full), unit.rotation - 90, timer / spawnTime, 1f, timer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String localized(){
|
public String localized(){
|
||||||
return Core.bundle.format("ability.unitspawn", type.localizedName);
|
return Core.bundle.format("ability.unitspawn", unit.localizedName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ import java.util.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class BuilderComp implements Posc, Teamc, Rotc{
|
abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
|
||||||
static final Vec2[] vecs = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()};
|
static final Vec2[] vecs = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()};
|
||||||
|
|
||||||
@Import float x, y, rotation;
|
@Import float x, y, rotation, buildSpeedMultiplier;
|
||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
@Import Team team;
|
@Import Team team;
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
|
|||||||
private transient float buildAlpha = 0f;
|
private transient float buildAlpha = 0f;
|
||||||
|
|
||||||
public boolean canBuild(){
|
public boolean canBuild(){
|
||||||
return type.buildSpeed > 0;
|
return type.buildSpeed > 0 && buildSpeedMultiplier > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -126,9 +126,9 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
|
|||||||
|
|
||||||
//otherwise, update it.
|
//otherwise, update it.
|
||||||
if(current.breaking){
|
if(current.breaking){
|
||||||
entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier);
|
entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * buildSpeedMultiplier * state.rules.buildSpeedMultiplier);
|
||||||
}else{
|
}else{
|
||||||
entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier, current.config);
|
entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * buildSpeedMultiplier * state.rules.buildSpeedMultiplier, current.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
current.stuck = Mathf.equal(current.progress, entity.progress);
|
current.stuck = Mathf.equal(current.progress, entity.progress);
|
||||||
|
|||||||
@@ -910,24 +910,12 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
public void placed(){
|
public void placed(){
|
||||||
if(net.client()) return;
|
if(net.client()) return;
|
||||||
|
|
||||||
if(block.consumesPower || block.outputsPower){
|
if((block.consumesPower || block.outputsPower) && block.hasPower){
|
||||||
int range = 10;
|
PowerNode.getNodeLinks(tile, block, team, other -> {
|
||||||
tempTiles.clear();
|
if(!other.power.links.contains(pos())){
|
||||||
Geometry.circle(tileX(), tileY(), range, (x, y) -> {
|
other.configureAny(pos());
|
||||||
Building other = world.build(x, y);
|
|
||||||
if(other != null && other.block instanceof PowerNode node && node.linkValid(other, self()) && !PowerNode.insulated(other, self())
|
|
||||||
&& !other.proximity().contains(this.<Building>self()) &&
|
|
||||||
!(block.outputsPower && proximity.contains(p -> p.power != null && p.power.graph == other.power.graph))){
|
|
||||||
tempTiles.add(other.tile);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tempTiles.sort(Structs.comparingFloat(t -> t.dst2(tile)));
|
|
||||||
if(!tempTiles.isEmpty()){
|
|
||||||
Tile toLink = tempTiles.first();
|
|
||||||
if(!toLink.build.power.links.contains(pos())){
|
|
||||||
toLink.build.configureAny(pos());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,6 +952,12 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
if(block.configurations.containsKey(type)){
|
if(block.configurations.containsKey(type)){
|
||||||
block.configurations.get(type).get(this, value);
|
block.configurations.get(type).get(this, value);
|
||||||
|
}else if(value instanceof Building build){
|
||||||
|
//copy config of another building
|
||||||
|
var conf = build.config();
|
||||||
|
if(conf != null && !(conf instanceof Building)){
|
||||||
|
configured(builder, conf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1148,7 +1142,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
/** Returns whether or not a hand cursor should be shown over this block. */
|
/** Returns whether or not a hand cursor should be shown over this block. */
|
||||||
public Cursor getCursor(){
|
public Cursor getCursor(){
|
||||||
return block.configurable && team == player.team() ? SystemCursor.hand : SystemCursor.arrow;
|
return block.configurable && interactable(player.team()) ? SystemCursor.hand : SystemCursor.arrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1312,6 +1306,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
return switch(sensor){
|
return switch(sensor){
|
||||||
case x -> World.conv(x);
|
case x -> World.conv(x);
|
||||||
case y -> World.conv(y);
|
case y -> World.conv(y);
|
||||||
|
case dead -> !isValid() ? 1 : 0;
|
||||||
case team -> team.id;
|
case team -> team.id;
|
||||||
case health -> health;
|
case health -> health;
|
||||||
case maxHealth -> maxHealth;
|
case maxHealth -> maxHealth;
|
||||||
@@ -1330,8 +1325,9 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored();
|
case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored();
|
||||||
case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity();
|
case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity();
|
||||||
case enabled -> enabled ? 1 : 0;
|
case enabled -> enabled ? 1 : 0;
|
||||||
case controlled -> this instanceof ControlBlock c ? c.isControlled() ? 1 : 0 : 0;
|
case controlled -> this instanceof ControlBlock c && c.isControlled() ? GlobalConstants.ctrlPlayer : 0;
|
||||||
case payloadCount -> getPayload() != null ? 1 : 0;
|
case payloadCount -> getPayload() != null ? 1 : 0;
|
||||||
|
case size -> block.size;
|
||||||
default -> Float.NaN; //gets converted to null in logic
|
default -> Float.NaN; //gets converted to null in logic
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,16 +78,16 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveAt(Vec2 vector, float acceleration){
|
public void moveAt(Vec2 vector, float acceleration){
|
||||||
|
//mark walking state when moving in a controlled manner
|
||||||
if(!vector.isZero()){
|
if(!vector.isZero()){
|
||||||
//mark walking state when moving in a controlled manner
|
|
||||||
walked = true;
|
walked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void approach(Vec2 vector){
|
public void approach(Vec2 vector){
|
||||||
if(!vector.isZero(0.09f)){
|
//mark walking state when moving in a controlled manner
|
||||||
//mark walking state when moving in a controlled manner
|
if(!vector.isZero(0.001f)){
|
||||||
walked = true;
|
walked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ abstract class StatusComp implements Posc, Flyingc{
|
|||||||
private Seq<StatusEntry> statuses = new Seq<>();
|
private Seq<StatusEntry> statuses = new Seq<>();
|
||||||
private transient Bits applied = new Bits(content.getBy(ContentType.status).size);
|
private transient Bits applied = new Bits(content.getBy(ContentType.status).size);
|
||||||
|
|
||||||
@ReadOnly transient float speedMultiplier = 1, damageMultiplier = 1, healthMultiplier = 1, reloadMultiplier = 1;
|
@ReadOnly transient float speedMultiplier = 1, damageMultiplier = 1, healthMultiplier = 1, reloadMultiplier = 1, buildSpeedMultiplier = 1;
|
||||||
|
@ReadOnly transient boolean disarmed = false;
|
||||||
|
|
||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
|
|
||||||
@@ -110,7 +111,8 @@ abstract class StatusComp implements Posc, Flyingc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
applied.clear();
|
applied.clear();
|
||||||
speedMultiplier = damageMultiplier = healthMultiplier = reloadMultiplier = 1f;
|
speedMultiplier = damageMultiplier = healthMultiplier = reloadMultiplier = buildSpeedMultiplier = 1f;
|
||||||
|
disarmed = false;
|
||||||
|
|
||||||
if(statuses.isEmpty()) return;
|
if(statuses.isEmpty()) return;
|
||||||
|
|
||||||
@@ -132,6 +134,10 @@ abstract class StatusComp implements Posc, Flyingc{
|
|||||||
healthMultiplier *= entry.effect.healthMultiplier;
|
healthMultiplier *= entry.effect.healthMultiplier;
|
||||||
damageMultiplier *= entry.effect.damageMultiplier;
|
damageMultiplier *= entry.effect.damageMultiplier;
|
||||||
reloadMultiplier *= entry.effect.reloadMultiplier;
|
reloadMultiplier *= entry.effect.reloadMultiplier;
|
||||||
|
buildSpeedMultiplier *= entry.effect.buildSpeedMultiplier;
|
||||||
|
|
||||||
|
disarmed |= entry.effect.disarm;
|
||||||
|
|
||||||
entry.effect.update(self(), entry.time);
|
entry.effect.update(self(), entry.time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import static mindustry.Vars.*;
|
|||||||
@Component(base = true)
|
@Component(base = true)
|
||||||
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc, Builderc{
|
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc, Builderc{
|
||||||
|
|
||||||
@Import boolean hovering, dead;
|
@Import boolean hovering, dead, disarmed;
|
||||||
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed;
|
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed;
|
||||||
@Import Team team;
|
@Import Team team;
|
||||||
@Import int id;
|
@Import int id;
|
||||||
@@ -128,8 +128,10 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
case ammoCapacity -> type.ammoCapacity;
|
case ammoCapacity -> type.ammoCapacity;
|
||||||
case x -> World.conv(x);
|
case x -> World.conv(x);
|
||||||
case y -> World.conv(y);
|
case y -> World.conv(y);
|
||||||
|
case dead -> dead || !isAdded() ? 1 : 0;
|
||||||
case team -> team.id;
|
case team -> team.id;
|
||||||
case shooting -> isShooting() ? 1 : 0;
|
case shooting -> isShooting() ? 1 : 0;
|
||||||
|
case boosting -> type.canBoost && isFlying() ? 1 : 0;
|
||||||
case range -> range() / tilesize;
|
case range -> range() / tilesize;
|
||||||
case shootX -> World.conv(aimX());
|
case shootX -> World.conv(aimX());
|
||||||
case shootY -> World.conv(aimY());
|
case shootY -> World.conv(aimY());
|
||||||
@@ -137,10 +139,15 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
case mineX -> mining() ? mineTile.x : -1;
|
case mineX -> mining() ? mineTile.x : -1;
|
||||||
case mineY -> mining() ? mineTile.y : -1;
|
case mineY -> mining() ? mineTile.y : -1;
|
||||||
case flag -> flag;
|
case flag -> flag;
|
||||||
case controlled -> controller instanceof LogicAI || controller instanceof Player ? 1 : 0;
|
case controlled -> !isValid() ? 0 :
|
||||||
case commanded -> controller instanceof FormationAI ? 1 : 0;
|
controller instanceof LogicAI ? GlobalConstants.ctrlProcessor :
|
||||||
|
controller instanceof Player ? GlobalConstants.ctrlPlayer :
|
||||||
|
controller instanceof FormationAI ? GlobalConstants.ctrlFormation :
|
||||||
|
0;
|
||||||
|
case commanded -> controller instanceof FormationAI && isValid() ? 1 : 0;
|
||||||
case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0;
|
case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0;
|
||||||
default -> 0;
|
case size -> hitSize / tilesize;
|
||||||
|
default -> Float.NaN;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +157,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
case type -> type;
|
case type -> type;
|
||||||
case name -> controller instanceof Player p ? p.name : null;
|
case name -> controller instanceof Player p ? p.name : null;
|
||||||
case firstItem -> stack().amount == 0 ? null : item();
|
case firstItem -> stack().amount == 0 ? null : item();
|
||||||
|
case controller -> !isValid() ? null : controller instanceof LogicAI log ? log.controller : controller instanceof FormationAI form ? form.leader : this;
|
||||||
case payloadType -> self() instanceof Payloadc pay ?
|
case payloadType -> self() instanceof Payloadc pay ?
|
||||||
(pay.payloads().isEmpty() ? null :
|
(pay.payloads().isEmpty() ? null :
|
||||||
pay.payloads().peek() instanceof UnitPayload p1 ? p1.unit.type :
|
pay.payloads().peek() instanceof UnitPayload p1 ? p1.unit.type :
|
||||||
@@ -162,7 +170,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
@Override
|
@Override
|
||||||
public double sense(Content content){
|
public double sense(Content content){
|
||||||
if(content == stack().item) return stack().amount;
|
if(content == stack().item) return stack().amount;
|
||||||
return 0;
|
return Float.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,7 +183,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
@Replace
|
@Replace
|
||||||
public boolean canShoot(){
|
public boolean canShoot(){
|
||||||
//cannot shoot while boosting
|
//cannot shoot while boosting
|
||||||
return !(type.canBoost && isFlying());
|
return !disarmed && !(type.canBoost && isFlying());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import static mindustry.Vars.*;
|
|||||||
@Component
|
@Component
|
||||||
abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
||||||
@Import float x, y, rotation, reloadMultiplier;
|
@Import float x, y, rotation, reloadMultiplier;
|
||||||
|
@Import boolean disarmed;
|
||||||
@Import Vec2 vel;
|
@Import Vec2 vel;
|
||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean canShoot(){
|
boolean canShoot(){
|
||||||
return true;
|
return !disarmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public class AIController implements UnitController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean retarget(){
|
protected boolean retarget(){
|
||||||
return timer.get(timerTarget, 40);
|
return timer.get(timerTarget, target == null ? 40 : 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
|
protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ public class BuildPlan implements Position{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean placeable(Team team){
|
||||||
|
return Build.validPlace(block, team, x, y, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRotation(Team team){
|
public boolean isRotation(Team team){
|
||||||
if(breaking) return false;
|
if(breaking) return false;
|
||||||
Tile tile = tile();
|
Tile tile = tile();
|
||||||
|
|||||||
@@ -383,6 +383,15 @@ public class EventType{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called when a connection is established to a client. */
|
||||||
|
public static class ConnectionEvent{
|
||||||
|
public final NetConnection connection;
|
||||||
|
|
||||||
|
public ConnectionEvent(NetConnection connection){
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Called after connecting; when a player receives world data and is ready to play.*/
|
/** Called after connecting; when a player receives world data and is ready to play.*/
|
||||||
public static class PlayerJoin{
|
public static class PlayerJoin{
|
||||||
public final Player player;
|
public final Player player;
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ public class Rules{
|
|||||||
public float unitBuildSpeedMultiplier = 1f;
|
public float unitBuildSpeedMultiplier = 1f;
|
||||||
/** How much damage any other units deal. */
|
/** How much damage any other units deal. */
|
||||||
public float unitDamageMultiplier = 1f;
|
public float unitDamageMultiplier = 1f;
|
||||||
|
/** Whether to allow units to build with logic. */
|
||||||
|
public boolean logicUnitBuild = true;
|
||||||
/** How much health blocks start with. */
|
/** How much health blocks start with. */
|
||||||
public float blockHealthMultiplier = 1f;
|
public float blockHealthMultiplier = 1f;
|
||||||
/** How much damage blocks (turrets) deal. */
|
/** How much damage blocks (turrets) deal. */
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import mindustry.input.Placement.*;
|
|||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
|
import mindustry.world.blocks.ConstructBlock.*;
|
||||||
import mindustry.world.blocks.distribution.*;
|
import mindustry.world.blocks.distribution.*;
|
||||||
import mindustry.world.blocks.legacy.*;
|
import mindustry.world.blocks.legacy.*;
|
||||||
import mindustry.world.blocks.power.*;
|
import mindustry.world.blocks.power.*;
|
||||||
@@ -357,10 +358,11 @@ public class Schematics implements Loadable{
|
|||||||
for(int cx = x; cx <= x2; cx++){
|
for(int cx = x; cx <= x2; cx++){
|
||||||
for(int cy = y; cy <= y2; cy++){
|
for(int cy = y; cy <= y2; cy++){
|
||||||
Building linked = world.build(cx, cy);
|
Building linked = world.build(cx, cy);
|
||||||
|
Block realBlock = linked == null ? null : linked instanceof ConstructBuild cons ? cons.cblock : linked.block;
|
||||||
|
|
||||||
if(linked != null && (linked.block.isVisible() || linked.block() instanceof CoreBlock) && !(linked.block instanceof ConstructBlock)){
|
if(linked != null && (realBlock.isVisible() || realBlock instanceof CoreBlock)){
|
||||||
int top = linked.block.size/2;
|
int top = realBlock.size/2;
|
||||||
int bot = linked.block.size % 2 == 1 ? -linked.block.size/2 : -(linked.block.size - 1)/2;
|
int bot = realBlock.size % 2 == 1 ? -realBlock.size/2 : -(realBlock.size - 1)/2;
|
||||||
minx = Math.min(linked.tileX() + bot, minx);
|
minx = Math.min(linked.tileX() + bot, minx);
|
||||||
miny = Math.min(linked.tileY() + bot, miny);
|
miny = Math.min(linked.tileY() + bot, miny);
|
||||||
maxx = Math.max(linked.tileX() + top, maxx);
|
maxx = Math.max(linked.tileX() + top, maxx);
|
||||||
@@ -385,12 +387,13 @@ public class Schematics implements Loadable{
|
|||||||
for(int cx = ox; cx <= ox2; cx++){
|
for(int cx = ox; cx <= ox2; cx++){
|
||||||
for(int cy = oy; cy <= oy2; cy++){
|
for(int cy = oy; cy <= oy2; cy++){
|
||||||
Building tile = world.build(cx, cy);
|
Building tile = world.build(cx, cy);
|
||||||
|
Block realBlock = tile == null ? null : tile instanceof ConstructBuild cons ? cons.cblock : tile.block;
|
||||||
|
|
||||||
if(tile != null && !counted.contains(tile.pos()) && !(tile.block instanceof ConstructBlock)
|
if(tile != null && !counted.contains(tile.pos())
|
||||||
&& (tile.block.isVisible() || tile.block instanceof CoreBlock)){
|
&& (realBlock.isVisible() || realBlock instanceof CoreBlock)){
|
||||||
Object config = tile.config();
|
Object config = tile instanceof ConstructBuild cons ? cons.lastConfig : tile.config();
|
||||||
|
|
||||||
tiles.add(new Stile(tile.block, tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation));
|
tiles.add(new Stile(realBlock, tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation));
|
||||||
counted.add(tile.pos());
|
counted.add(tile.pos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,12 @@ public class Drawf{
|
|||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void shadow(TextureRegion region, float x, float y, float width, float height, float rotation){
|
||||||
|
Draw.color(Pal.shadow);
|
||||||
|
Draw.rect(region, x, y, width, height, rotation);
|
||||||
|
Draw.color();
|
||||||
|
}
|
||||||
|
|
||||||
public static void liquid(TextureRegion region, float x, float y, float alpha, Color color, float rotation){
|
public static void liquid(TextureRegion region, float x, float y, float alpha, Color color, float rotation){
|
||||||
Draw.color(color, alpha);
|
Draw.color(color, alpha);
|
||||||
Draw.rect(region, x, y, rotation);
|
Draw.rect(region, x, y, rotation);
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ public class DesktopInput extends InputHandler{
|
|||||||
public boolean deleting = false, shouldShoot = false, panning = false;
|
public boolean deleting = false, shouldShoot = false, panning = false;
|
||||||
/** Mouse pan speed. */
|
/** Mouse pan speed. */
|
||||||
public float panScale = 0.005f, panSpeed = 4.5f, panBoostSpeed = 11f;
|
public float panScale = 0.005f, panSpeed = 4.5f, panBoostSpeed = 11f;
|
||||||
|
/** Delta time between consecutive clicks. */
|
||||||
|
public long selectMillis = 0;
|
||||||
|
/** Previously selected tile. */
|
||||||
|
public Tile prevSelected;
|
||||||
|
|
||||||
boolean showHint(){
|
boolean showHint(){
|
||||||
return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() &&
|
return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() &&
|
||||||
@@ -489,13 +493,15 @@ public class DesktopInput extends InputHandler{
|
|||||||
deleting = true;
|
deleting = true;
|
||||||
}else if(selected != null){
|
}else if(selected != null){
|
||||||
//only begin shooting if there's no cursor event
|
//only begin shooting if there's no cursor event
|
||||||
if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem &&
|
if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem
|
||||||
!tryBeginMine(selected) && player.unit().mineTile == null && !Core.scene.hasKeyboard()){
|
&& !(tryStopMine(selected) || (!settings.getBool("doubletapmine") || selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500) && tryBeginMine(selected)) && !Core.scene.hasKeyboard()){
|
||||||
player.shooting = shouldShoot;
|
player.shooting = shouldShoot;
|
||||||
}
|
}
|
||||||
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
|
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
|
||||||
player.shooting = shouldShoot;
|
player.shooting = shouldShoot;
|
||||||
}
|
}
|
||||||
|
selectMillis = Time.millis();
|
||||||
|
prevSelected = selected;
|
||||||
}else if(Core.input.keyTap(Binding.deselect) && isPlacing()){
|
}else if(Core.input.keyTap(Binding.deselect) && isPlacing()){
|
||||||
block = null;
|
block = null;
|
||||||
mode = none;
|
mode = none;
|
||||||
|
|||||||
@@ -30,11 +30,10 @@ import mindustry.net.*;
|
|||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.ui.fragments.*;
|
import mindustry.ui.fragments.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
|
||||||
import mindustry.world.blocks.ConstructBlock.*;
|
import mindustry.world.blocks.ConstructBlock.*;
|
||||||
|
import mindustry.world.blocks.*;
|
||||||
import mindustry.world.blocks.distribution.*;
|
import mindustry.world.blocks.distribution.*;
|
||||||
import mindustry.world.blocks.payloads.*;
|
import mindustry.world.blocks.payloads.*;
|
||||||
import mindustry.world.blocks.power.*;
|
|
||||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
@@ -771,7 +770,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime, 6f, 0.28f));
|
Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime, 6f, 0.28f));
|
||||||
Draw.alpha(1f);
|
Draw.alpha(1f);
|
||||||
request.block.drawRequestConfigTop(request, selectRequests);
|
request.block.drawRequestConfigTop(request, cons -> {
|
||||||
|
selectRequests.each(cons);
|
||||||
|
lineRequests.each(cons);
|
||||||
|
});
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -867,6 +869,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
req.block = replace;
|
req.block = replace;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
block.handlePlacementLine(lineRequests);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,8 +948,24 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
/** Tries to begin mining a tile, returns true if successful. */
|
/** Tries to begin mining a tile, returns true if successful. */
|
||||||
boolean tryBeginMine(Tile tile){
|
boolean tryBeginMine(Tile tile){
|
||||||
if(canMine(tile)){
|
if(canMine(tile)){
|
||||||
//if a block is clicked twice, reset it
|
player.unit().mineTile = tile;
|
||||||
player.unit().mineTile = player.unit().mineTile == tile ? null : tile;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tries to stop mining, returns true if mining was stopped. */
|
||||||
|
boolean tryStopMine(){
|
||||||
|
if(player.unit().mining()){
|
||||||
|
player.unit().mineTile = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean tryStopMine(Tile tile){
|
||||||
|
if(player.unit().mineTile == tile){
|
||||||
|
player.unit().mineTile = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
public Teamc target;
|
public Teamc target;
|
||||||
/** Payload target being moved to. Can be a position (for dropping), or a unit/block. */
|
/** Payload target being moved to. Can be a position (for dropping), or a unit/block. */
|
||||||
public Position payloadTarget;
|
public Position payloadTarget;
|
||||||
|
/** Unit last tapped, or null if last tap was not on a unit. */
|
||||||
|
public Unit unitTapped;
|
||||||
|
|
||||||
//region utility methods
|
//region utility methods
|
||||||
|
|
||||||
@@ -314,6 +316,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
request.block.drawPlan(request, allRequests(), validPlace(request.x, request.y, request.block, request.rotation) && getRequest(request.x, request.y, request.block.size, null) == null);
|
request.block.drawPlan(request, allRequests(), validPlace(request.x, request.y, request.block, request.rotation) && getRequest(request.x, request.y, request.block.size, null) == null);
|
||||||
drawSelected(request.x, request.y, request.block, Pal.accent);
|
drawSelected(request.x, request.y, request.block, Pal.accent);
|
||||||
}
|
}
|
||||||
|
lineRequests.each(this::drawOverRequest);
|
||||||
}else if(mode == breaking){
|
}else if(mode == breaking){
|
||||||
drawBreakSelection(lineStartX, lineStartY, tileX, tileY);
|
drawBreakSelection(lineStartX, lineStartY, tileX, tileY);
|
||||||
}
|
}
|
||||||
@@ -423,7 +426,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
@Override
|
@Override
|
||||||
public void useSchematic(Schematic schem){
|
public void useSchematic(Schematic schem){
|
||||||
selectRequests.clear();
|
selectRequests.clear();
|
||||||
selectRequests.addAll(schematics.toRequests(schem, player.tileX(), player.tileY()));
|
selectRequests.addAll(schematics.toRequests(schem, World.toTile(Core.camera.position.x), World.toTile(Core.camera.position.y)));
|
||||||
lastSchematic = schem;
|
lastSchematic = schem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,11 +601,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
//add to selection queue if it's a valid BREAK position
|
//add to selection queue if it's a valid BREAK position
|
||||||
selectRequests.add(new BuildPlan(linked.x, linked.y));
|
selectRequests.add(new BuildPlan(linked.x, linked.y));
|
||||||
}else{
|
}else{
|
||||||
if(!canTapPlayer(worldx, worldy) && !tileTapped(linked.build)){
|
//control units
|
||||||
tryBeginMine(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
//control units.
|
|
||||||
if(count == 2){
|
if(count == 2){
|
||||||
//reset payload target
|
//reset payload target
|
||||||
payloadTarget = null;
|
payloadTarget = null;
|
||||||
@@ -610,12 +609,20 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
if(!player.dead() && Mathf.within(worldx, worldy, player.unit().x, player.unit().y, player.unit().hitSize * 0.6f + 8f) && player.unit().type.commandLimit > 0){
|
if(!player.dead() && Mathf.within(worldx, worldy, player.unit().x, player.unit().y, player.unit().hitSize * 0.6f + 8f) && player.unit().type.commandLimit > 0){
|
||||||
Call.unitCommand(player);
|
Call.unitCommand(player);
|
||||||
}else{
|
}else{
|
||||||
//control a unit/block
|
//control a unit/block detected on first tap of double-tap
|
||||||
Unit on = selectedUnit();
|
if(unitTapped != null){
|
||||||
if(on != null){
|
Call.unitControl(player, unitTapped);
|
||||||
Call.unitControl(player, on);
|
}else if(!tryBeginMine(cursor)){
|
||||||
|
tileTapped(linked.build);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unitTapped = selectedUnit();
|
||||||
|
//prevent mining if placing/breaking blocks
|
||||||
|
if(!tryStopMine() && !canTapPlayer(worldx, worldy) && !tileTapped(linked.build) && mode == none && !Core.settings.getBool("doubletapmine")){
|
||||||
|
tryBeginMine(cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,22 +6,24 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
|
import mindustry.entities.units.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.distribution.*;
|
import mindustry.world.blocks.distribution.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class Placement{
|
public class Placement{
|
||||||
private final static Seq<Point2> tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>();
|
private static final Seq<BuildPlan> plans1 = new Seq<>();
|
||||||
|
private static final Seq<Point2> tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>();
|
||||||
private static final NormalizeResult result = new NormalizeResult();
|
private static final NormalizeResult result = new NormalizeResult();
|
||||||
private static final NormalizeDrawResult drawResult = new NormalizeDrawResult();
|
private static final NormalizeDrawResult drawResult = new NormalizeDrawResult();
|
||||||
private static Bresenham2 bres = new Bresenham2();
|
private static final Bresenham2 bres = new Bresenham2();
|
||||||
private static Seq<Point2> points = new Seq<>();
|
private static final Seq<Point2> points = new Seq<>();
|
||||||
|
|
||||||
//for pathfinding
|
//for pathfinding
|
||||||
private static IntFloatMap costs = new IntFloatMap();
|
private static final IntFloatMap costs = new IntFloatMap();
|
||||||
private static IntIntMap parents = new IntIntMap();
|
private static final IntIntMap parents = new IntIntMap();
|
||||||
private static IntSet closed = new IntSet();
|
private static final IntSet closed = new IntSet();
|
||||||
|
|
||||||
/** Normalize a diagonal line into points. */
|
/** Normalize a diagonal line into points. */
|
||||||
public static Seq<Point2> pathfindLine(boolean conveyors, int startX, int startY, int endX, int endY){
|
public static Seq<Point2> pathfindLine(boolean conveyors, int startX, int startY, int endX, int endY){
|
||||||
@@ -75,7 +77,7 @@ public class Placement{
|
|||||||
var base = tmpPoints2;
|
var base = tmpPoints2;
|
||||||
var result = tmpPoints.clear();
|
var result = tmpPoints.clear();
|
||||||
|
|
||||||
base.selectFrom(points, p -> p == points.first() || p == points.peek() || Build.validPlace(block, player.team(), p.x, p.y, rotation, false));
|
base.selectFrom(points, p -> p == points.first() || p == points.peek() || Build.validPlace(block, player.team(), p.x, p.y, rotation));
|
||||||
boolean addedLast = false;
|
boolean addedLast = false;
|
||||||
|
|
||||||
outer:
|
outer:
|
||||||
@@ -106,6 +108,67 @@ public class Placement{
|
|||||||
points.addAll(result);
|
points.addAll(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void calculateBridges(Seq<BuildPlan> plans, ItemBridge bridge){
|
||||||
|
//check for orthogonal placement + unlocked state
|
||||||
|
if(!(plans.first().x == plans.peek().x || plans.first().y == plans.peek().y || !bridge.unlockedNow())){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolf<BuildPlan> placeable = plan -> (plan.placeable(player.team())) ||
|
||||||
|
(plan.tile() != null && plan.tile().block() == plan.block); //don't count the same block as inaccessible
|
||||||
|
|
||||||
|
var result = plans1.clear();
|
||||||
|
var team = player.team();
|
||||||
|
var rotated = plans.first().tile() != null && plans.first().tile().absoluteRelativeTo(plans.peek().x, plans.peek().y) == Mathf.mod(plans.first().rotation + 2, 4);
|
||||||
|
|
||||||
|
outer:
|
||||||
|
for(int i = 0; i < plans.size;){
|
||||||
|
var cur = plans.get(i);
|
||||||
|
result.add(cur);
|
||||||
|
|
||||||
|
//gap found
|
||||||
|
if(i < plans.size - 1 && placeable.get(cur) && !placeable.get(plans.get(i + 1))){
|
||||||
|
|
||||||
|
//find the closest valid position within range
|
||||||
|
for(int j = i + 1; j < plans.size; j++){
|
||||||
|
var other = plans.get(j);
|
||||||
|
|
||||||
|
//out of range now, set to current position and keep scanning forward for next occurrence
|
||||||
|
if(!bridge.positionsValid(cur.x, cur.y, other.x, other.y)){
|
||||||
|
//add 'missed' conveyors
|
||||||
|
for(int k = i + 1; k < j; k++){
|
||||||
|
result.add(plans.get(k));
|
||||||
|
}
|
||||||
|
i = j;
|
||||||
|
continue outer;
|
||||||
|
}else if(other.placeable(team)){
|
||||||
|
//found a link, assign bridges
|
||||||
|
cur.block = bridge;
|
||||||
|
other.block = bridge;
|
||||||
|
if(rotated){
|
||||||
|
other.config = new Point2(cur.x - other.x, cur.y - other.y);
|
||||||
|
}else{
|
||||||
|
cur.config = new Point2(other.x - cur.x, other.y - cur.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = j;
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if it got here, that means nothing was found. this likely means there's a bunch of stuff at the end; add it and bail out
|
||||||
|
for(int j = i + 1; j < plans.size; j++){
|
||||||
|
result.add(plans.get(j));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
i ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plans.set(result);
|
||||||
|
}
|
||||||
|
|
||||||
private static float tileHeuristic(Tile tile, Tile other){
|
private static float tileHeuristic(Tile tile, Tile other){
|
||||||
Block block = control.input.block;
|
Block block = control.input.block;
|
||||||
|
|
||||||
|
|||||||
@@ -572,10 +572,12 @@ public class TypeIO{
|
|||||||
writeString(write, trace.uuid);
|
writeString(write, trace.uuid);
|
||||||
write.b(trace.modded ? (byte)1 : 0);
|
write.b(trace.modded ? (byte)1 : 0);
|
||||||
write.b(trace.mobile ? (byte)1 : 0);
|
write.b(trace.mobile ? (byte)1 : 0);
|
||||||
|
write.i(trace.timesJoined);
|
||||||
|
write.i(trace.timesKicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TraceInfo readTraceInfo(Reads read){
|
public static TraceInfo readTraceInfo(Reads read){
|
||||||
return new TraceInfo(readString(read), readString(read), read.b() == 1, read.b() == 1);
|
return new TraceInfo(readString(read), readString(read), read.b() == 1, read.b() == 1, read.i(), read.i());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeStringData(DataOutput buffer, String string) throws IOException{
|
public static void writeStringData(DataOutput buffer, String string) throws IOException{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
|
|
||||||
public enum ConditionOp{
|
public enum ConditionOp{
|
||||||
equal("==", (a, b) -> Math.abs(a - b) < 0.000001, (a, b) -> a == b),
|
equal("==", (a, b) -> Math.abs(a - b) < 0.000001, Structs::eq),
|
||||||
notEqual("not", (a, b) -> Math.abs(a - b) >= 0.000001, (a, b) -> a != b),
|
notEqual("not", (a, b) -> Math.abs(a - b) >= 0.000001, (a, b) -> !Structs.eq(a, b)),
|
||||||
lessThan("<", (a, b) -> a < b),
|
lessThan("<", (a, b) -> a < b),
|
||||||
lessThanEq("<=", (a, b) -> a <= b),
|
lessThanEq("<=", (a, b) -> a <= b),
|
||||||
greaterThan(">", (a, b) -> a > b),
|
greaterThan(">", (a, b) -> a > b),
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import mindustry.world.*;
|
|||||||
|
|
||||||
/** Stores global constants for logic processors. */
|
/** Stores global constants for logic processors. */
|
||||||
public class GlobalConstants{
|
public class GlobalConstants{
|
||||||
|
public static final int ctrlProcessor = 1, ctrlPlayer = 2, ctrlFormation = 3;
|
||||||
|
|
||||||
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
|
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
|
||||||
private Seq<Var> vars = new Seq<>(Var.class);
|
private Seq<Var> vars = new Seq<>(Var.class);
|
||||||
|
|
||||||
@@ -19,6 +21,12 @@ public class GlobalConstants{
|
|||||||
put("true", 1);
|
put("true", 1);
|
||||||
put("null", null);
|
put("null", null);
|
||||||
|
|
||||||
|
//special enums
|
||||||
|
|
||||||
|
put("@ctrlProcessor", ctrlProcessor);
|
||||||
|
put("@ctrlPlayer", ctrlPlayer);
|
||||||
|
put("@ctrlFormation", ctrlFormation);
|
||||||
|
|
||||||
//store base content
|
//store base content
|
||||||
|
|
||||||
for(Item item : Vars.content.items()){
|
for(Item item : Vars.content.items()){
|
||||||
|
|||||||
@@ -27,8 +27,11 @@ public enum LAccess{
|
|||||||
y,
|
y,
|
||||||
shootX,
|
shootX,
|
||||||
shootY,
|
shootY,
|
||||||
|
size,
|
||||||
|
dead,
|
||||||
range,
|
range,
|
||||||
shooting,
|
shooting,
|
||||||
|
boosting,
|
||||||
mineX,
|
mineX,
|
||||||
mineY,
|
mineY,
|
||||||
mining,
|
mining,
|
||||||
@@ -36,6 +39,7 @@ public enum LAccess{
|
|||||||
type,
|
type,
|
||||||
flag,
|
flag,
|
||||||
controlled,
|
controlled,
|
||||||
|
controller,
|
||||||
commanded,
|
commanded,
|
||||||
name,
|
name,
|
||||||
config,
|
config,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import arc.scene.ui.*;
|
|||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
@@ -29,10 +30,26 @@ public class LCanvas extends Table{
|
|||||||
StatementElem hovered;
|
StatementElem hovered;
|
||||||
float targetWidth;
|
float targetWidth;
|
||||||
int jumpCount = 0;
|
int jumpCount = 0;
|
||||||
|
Seq<Tooltip> tooltips = new Seq<>();
|
||||||
|
|
||||||
public LCanvas(){
|
public LCanvas(){
|
||||||
canvas = this;
|
canvas = this;
|
||||||
|
|
||||||
|
Core.scene.addListener(new InputListener(){
|
||||||
|
@Override
|
||||||
|
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){
|
||||||
|
//hide tooltips on tap
|
||||||
|
for(var t : tooltips){
|
||||||
|
t.container.toFront();
|
||||||
|
}
|
||||||
|
Core.app.post(() -> {
|
||||||
|
tooltips.each(Tooltip::hide);
|
||||||
|
tooltips.clear();
|
||||||
|
});
|
||||||
|
return super.touchDown(event, x, y, pointer, button);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
rebuild();
|
rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +61,37 @@ public class LCanvas extends Table{
|
|||||||
public static void tooltip(Cell<?> cell, String key){
|
public static void tooltip(Cell<?> cell, String key){
|
||||||
String lkey = key.toLowerCase().replace(" ", "");
|
String lkey = key.toLowerCase().replace(" ", "");
|
||||||
if(Core.settings.getBool("logichints", true) && Core.bundle.has(lkey)){
|
if(Core.settings.getBool("logichints", true) && Core.bundle.has(lkey)){
|
||||||
cell.get().addListener(new Tooltip(t -> t.background(Styles.black8).margin(4f).add("[lightgray]" + Core.bundle.get(lkey)).style(Styles.outlineLabel)));
|
var tip = new Tooltip(t -> t.background(Styles.black8).margin(4f).add("[lightgray]" + Core.bundle.get(lkey)).style(Styles.outlineLabel));
|
||||||
|
|
||||||
|
//mobile devices need long-press tooltips
|
||||||
|
if(Vars.mobile){
|
||||||
|
cell.get().addListener(new ElementGestureListener(20, 0.4f, 0.43f, 0.15f){
|
||||||
|
@Override
|
||||||
|
public boolean longPress(Element element, float x, float y){
|
||||||
|
tip.show(element, x, y);
|
||||||
|
canvas.tooltips.add(tip);
|
||||||
|
//prevent touch down for other listeners
|
||||||
|
for(var list : cell.get().getListeners()){
|
||||||
|
if(list instanceof ClickListener cl){
|
||||||
|
cl.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
cell.get().addListener(tip);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tooltip(Cell<?> cell, Enum<?> key){
|
||||||
|
String cl = key.getClass().getSimpleName().toLowerCase() + "." + key.name().toLowerCase();
|
||||||
|
if(Core.bundle.has(cl)){
|
||||||
|
tooltip(cell, cl);
|
||||||
|
}else{
|
||||||
|
tooltip(cell, "lenum." + key.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case build -> {
|
case build -> {
|
||||||
if(unit.canBuild() && exec.obj(p3) instanceof Block block){
|
if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block){
|
||||||
int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize);
|
int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize);
|
||||||
int rot = exec.numi(p4);
|
int rot = exec.numi(p4);
|
||||||
|
|
||||||
@@ -458,12 +458,14 @@ public class LExecutor{
|
|||||||
ai.plan.stuck = false;
|
ai.plan.stuck = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var conf = exec.obj(p5);
|
||||||
ai.plan.set(x, y, rot, block);
|
ai.plan.set(x, y, rot, block);
|
||||||
ai.plan.config = exec.obj(p5) instanceof Content c ? c : null;
|
ai.plan.config = conf instanceof Content c ? c : conf instanceof Building b ? b : null;
|
||||||
|
|
||||||
unit.clearBuilding();
|
unit.clearBuilding();
|
||||||
|
Tile tile = ai.plan.tile();
|
||||||
|
|
||||||
if(ai.plan.tile() != null){
|
if(tile != null && !(tile.block() == block && tile.build != null && tile.build.rotation == rot)){
|
||||||
unit.updateBuilding = true;
|
unit.updateBuilding = true;
|
||||||
unit.addBuild(ai.plan);
|
unit.addBuild(ai.plan);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public abstract class LStatement{
|
|||||||
sizer.get(t.button(p.toString(), Styles.logicTogglet, () -> {
|
sizer.get(t.button(p.toString(), Styles.logicTogglet, () -> {
|
||||||
getter.get(p);
|
getter.get(p);
|
||||||
hide.run();
|
hide.run();
|
||||||
}).self(c -> tooltip(c, "lenum." + p.name())).checked(current == p).group(group));
|
}).self(c -> tooltip(c, p)).checked(current == p).group(group));
|
||||||
|
|
||||||
if(++i % cols == 0) t.row();
|
if(++i % cols == 0) t.row();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ public class LStatements{
|
|||||||
i.button(sensor.name(), Styles.cleart, () -> {
|
i.button(sensor.name(), Styles.cleart, () -> {
|
||||||
stype("@" + sensor.name());
|
stype("@" + sensor.name());
|
||||||
hide.run();
|
hide.run();
|
||||||
}).size(240f, 40f).self(c -> tooltip(c, "lenum." + sensor.name())).row();
|
}).size(240f, 40f).self(c -> tooltip(c, sensor)).row();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@@ -603,7 +603,7 @@ public class LStatements{
|
|||||||
table.add(" = ");
|
table.add(" = ");
|
||||||
|
|
||||||
if(op.unary){
|
if(op.unary){
|
||||||
opButton(table);
|
opButton(table, table);
|
||||||
|
|
||||||
field(table, a, str -> a = str);
|
field(table, a, str -> a = str);
|
||||||
}else{
|
}else{
|
||||||
@@ -617,35 +617,35 @@ public class LStatements{
|
|||||||
table.table(c -> {
|
table.table(c -> {
|
||||||
c.color.set(color());
|
c.color.set(color());
|
||||||
c.left();
|
c.left();
|
||||||
funcs(c);
|
funcs(c, table);
|
||||||
}).colspan(2).left();
|
}).colspan(2).left();
|
||||||
}else{
|
}else{
|
||||||
funcs(table);
|
funcs(table, table);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
field(table, a, str -> a = str);
|
field(table, a, str -> a = str);
|
||||||
|
|
||||||
opButton(table);
|
opButton(table, table);
|
||||||
|
|
||||||
field(table, b, str -> b = str);
|
field(table, b, str -> b = str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void funcs(Table table){
|
void funcs(Table table, Table parent){
|
||||||
opButton(table);
|
opButton(table, parent);
|
||||||
|
|
||||||
field(table, a, str -> a = str);
|
field(table, a, str -> a = str);
|
||||||
|
|
||||||
field(table, b, str -> b = str);
|
field(table, b, str -> b = str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void opButton(Table table){
|
void opButton(Table table, Table parent){
|
||||||
table.button(b -> {
|
table.button(b -> {
|
||||||
b.label(() -> op.symbol);
|
b.label(() -> op.symbol);
|
||||||
b.clicked(() -> showSelect(b, LogicOp.all, op, o -> {
|
b.clicked(() -> showSelect(b, LogicOp.all, op, o -> {
|
||||||
op = o;
|
op = o;
|
||||||
rebuild(table);
|
rebuild(parent);
|
||||||
}));
|
}));
|
||||||
}, Styles.logict, () -> {}).size(64f, 40f).pad(4f).color(table.color);
|
}, Styles.logict, () -> {}).size(64f, 40f).pad(4f).color(table.color);
|
||||||
}
|
}
|
||||||
@@ -829,7 +829,11 @@ public class LStatements{
|
|||||||
table.button(b -> {
|
table.button(b -> {
|
||||||
b.label(() -> type.name());
|
b.label(() -> type.name());
|
||||||
b.clicked(() -> showSelect(b, LUnitControl.all, type, t -> {
|
b.clicked(() -> showSelect(b, LUnitControl.all, type, t -> {
|
||||||
type = t;
|
if(t == LUnitControl.build && !Vars.state.rules.logicUnitBuild){
|
||||||
|
Vars.ui.showInfo("@logic.nounitbuild");
|
||||||
|
}else{
|
||||||
|
type = t;
|
||||||
|
}
|
||||||
rebuild(table);
|
rebuild(table);
|
||||||
}, 2, cell -> cell.size(120, 50)));
|
}, 2, cell -> cell.size(120, 50)));
|
||||||
}, Styles.logict, () -> {}).size(120, 40).color(table.color).left().padLeft(2);
|
}, Styles.logict, () -> {}).size(120, 40).color(table.color).left().padLeft(2);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
public enum LUnitControl{
|
public enum LUnitControl{
|
||||||
|
idle,
|
||||||
stop,
|
stop,
|
||||||
move("x", "y"),
|
move("x", "y"),
|
||||||
approach("x", "y", "radius"),
|
approach("x", "y", "radius"),
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
}
|
}
|
||||||
}else if(floor != Blocks.basalt && floor != Blocks.ice && floor.asFloor().hasSurface()){
|
}else if(floor != Blocks.basalt && floor != Blocks.ice && floor.asFloor().hasSurface()){
|
||||||
float noise = noise(x + 782, y, 5, 0.75f, 260f, 1f);
|
float noise = noise(x + 782, y, 5, 0.75f, 260f, 1f);
|
||||||
if(noise > 0.67f && !enemies.contains(e -> Mathf.within(x, y, e.x, e.y, 8))){
|
if(noise > 0.67f && !roomseq.contains(e -> Mathf.within(x, y, e.x, e.y, 14))){
|
||||||
if(noise > 0.72f){
|
if(noise > 0.72f){
|
||||||
floor = noise > 0.78f ? Blocks.taintedWater : (floor == Blocks.sand ? Blocks.sandWater : Blocks.darksandTaintedWater);
|
floor = noise > 0.78f ? Blocks.taintedWater : (floor == Blocks.sand ? Blocks.sandWater : Blocks.darksandTaintedWater);
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
266
core/src/mindustry/mod/ClassMap.java
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
package mindustry.mod;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
|
/** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */
|
||||||
|
public class ClassMap{
|
||||||
|
public static final ObjectMap<String, Class<?>> classes = new ObjectMap<>();
|
||||||
|
|
||||||
|
static{
|
||||||
|
classes.put("BuilderAI", mindustry.ai.types.BuilderAI.class);
|
||||||
|
classes.put("FlyingAI", mindustry.ai.types.FlyingAI.class);
|
||||||
|
classes.put("FormationAI", mindustry.ai.types.FormationAI.class);
|
||||||
|
classes.put("GroundAI", mindustry.ai.types.GroundAI.class);
|
||||||
|
classes.put("LogicAI", mindustry.ai.types.LogicAI.class);
|
||||||
|
classes.put("MinerAI", mindustry.ai.types.MinerAI.class);
|
||||||
|
classes.put("RepairAI", mindustry.ai.types.RepairAI.class);
|
||||||
|
classes.put("SuicideAI", mindustry.ai.types.SuicideAI.class);
|
||||||
|
classes.put("Ability", mindustry.entities.abilities.Ability.class);
|
||||||
|
classes.put("ForceFieldAbility", mindustry.entities.abilities.ForceFieldAbility.class);
|
||||||
|
classes.put("MoveLightningAbility", mindustry.entities.abilities.MoveLightningAbility.class);
|
||||||
|
classes.put("RepairFieldAbility", mindustry.entities.abilities.RepairFieldAbility.class);
|
||||||
|
classes.put("ShieldRegenFieldAbility", mindustry.entities.abilities.ShieldRegenFieldAbility.class);
|
||||||
|
classes.put("StatusFieldAbility", mindustry.entities.abilities.StatusFieldAbility.class);
|
||||||
|
classes.put("UnitSpawnAbility", mindustry.entities.abilities.UnitSpawnAbility.class);
|
||||||
|
classes.put("ArtilleryBulletType", mindustry.entities.bullet.ArtilleryBulletType.class);
|
||||||
|
classes.put("BasicBulletType", mindustry.entities.bullet.BasicBulletType.class);
|
||||||
|
classes.put("BombBulletType", mindustry.entities.bullet.BombBulletType.class);
|
||||||
|
classes.put("BulletType", mindustry.entities.bullet.BulletType.class);
|
||||||
|
classes.put("ContinuousLaserBulletType", mindustry.entities.bullet.ContinuousLaserBulletType.class);
|
||||||
|
classes.put("FlakBulletType", mindustry.entities.bullet.FlakBulletType.class);
|
||||||
|
classes.put("LaserBoltBulletType", mindustry.entities.bullet.LaserBoltBulletType.class);
|
||||||
|
classes.put("LaserBulletType", mindustry.entities.bullet.LaserBulletType.class);
|
||||||
|
classes.put("LightningBulletType", mindustry.entities.bullet.LightningBulletType.class);
|
||||||
|
classes.put("LiquidBulletType", mindustry.entities.bullet.LiquidBulletType.class);
|
||||||
|
classes.put("MassDriverBolt", mindustry.entities.bullet.MassDriverBolt.class);
|
||||||
|
classes.put("MissileBulletType", mindustry.entities.bullet.MissileBulletType.class);
|
||||||
|
classes.put("PointBulletType", mindustry.entities.bullet.PointBulletType.class);
|
||||||
|
classes.put("RailBulletType", mindustry.entities.bullet.RailBulletType.class);
|
||||||
|
classes.put("SapBulletType", mindustry.entities.bullet.SapBulletType.class);
|
||||||
|
classes.put("ShrapnelBulletType", mindustry.entities.bullet.ShrapnelBulletType.class);
|
||||||
|
classes.put("MultiEffect", mindustry.entities.effect.MultiEffect.class);
|
||||||
|
classes.put("ParticleEffect", mindustry.entities.effect.ParticleEffect.class);
|
||||||
|
classes.put("WaveEffect", mindustry.entities.effect.WaveEffect.class);
|
||||||
|
classes.put("Objectives", mindustry.game.Objectives.class);
|
||||||
|
classes.put("Objective", mindustry.game.Objectives.Objective.class);
|
||||||
|
classes.put("Produce", mindustry.game.Objectives.Produce.class);
|
||||||
|
classes.put("Research", mindustry.game.Objectives.Research.class);
|
||||||
|
classes.put("SectorComplete", mindustry.game.Objectives.SectorComplete.class);
|
||||||
|
classes.put("ParticleWeather", mindustry.type.weather.ParticleWeather.class);
|
||||||
|
classes.put("RainWeather", mindustry.type.weather.RainWeather.class);
|
||||||
|
classes.put("Attributes", mindustry.world.blocks.Attributes.class);
|
||||||
|
classes.put("Autotiler", mindustry.world.blocks.Autotiler.class);
|
||||||
|
classes.put("AutotilerHolder", mindustry.world.blocks.Autotiler.AutotilerHolder.class);
|
||||||
|
classes.put("SliceMode", mindustry.world.blocks.Autotiler.SliceMode.class);
|
||||||
|
classes.put("ConstructBlock", mindustry.world.blocks.ConstructBlock.class);
|
||||||
|
classes.put("ConstructBuild", mindustry.world.blocks.ConstructBlock.ConstructBuild.class);
|
||||||
|
classes.put("ControlBlock", mindustry.world.blocks.ControlBlock.class);
|
||||||
|
classes.put("ItemSelection", mindustry.world.blocks.ItemSelection.class);
|
||||||
|
classes.put("Accelerator", mindustry.world.blocks.campaign.Accelerator.class);
|
||||||
|
classes.put("AcceleratorBuild", mindustry.world.blocks.campaign.Accelerator.AcceleratorBuild.class);
|
||||||
|
classes.put("LaunchPad", mindustry.world.blocks.campaign.LaunchPad.class);
|
||||||
|
classes.put("LaunchPadBuild", mindustry.world.blocks.campaign.LaunchPad.LaunchPadBuild.class);
|
||||||
|
classes.put("Door", mindustry.world.blocks.defense.Door.class);
|
||||||
|
classes.put("DoorBuild", mindustry.world.blocks.defense.Door.DoorBuild.class);
|
||||||
|
classes.put("ForceProjector", mindustry.world.blocks.defense.ForceProjector.class);
|
||||||
|
classes.put("ForceBuild", mindustry.world.blocks.defense.ForceProjector.ForceBuild.class);
|
||||||
|
classes.put("MendProjector", mindustry.world.blocks.defense.MendProjector.class);
|
||||||
|
classes.put("MendBuild", mindustry.world.blocks.defense.MendProjector.MendBuild.class);
|
||||||
|
classes.put("OverdriveProjector", mindustry.world.blocks.defense.OverdriveProjector.class);
|
||||||
|
classes.put("OverdriveBuild", mindustry.world.blocks.defense.OverdriveProjector.OverdriveBuild.class);
|
||||||
|
classes.put("ShockMine", mindustry.world.blocks.defense.ShockMine.class);
|
||||||
|
classes.put("ShockMineBuild", mindustry.world.blocks.defense.ShockMine.ShockMineBuild.class);
|
||||||
|
classes.put("Thruster", mindustry.world.blocks.defense.Thruster.class);
|
||||||
|
classes.put("ThrusterBuild", mindustry.world.blocks.defense.Thruster.ThrusterBuild.class);
|
||||||
|
classes.put("Wall", mindustry.world.blocks.defense.Wall.class);
|
||||||
|
classes.put("WallBuild", mindustry.world.blocks.defense.Wall.WallBuild.class);
|
||||||
|
classes.put("BaseTurret", mindustry.world.blocks.defense.turrets.BaseTurret.class);
|
||||||
|
classes.put("BaseTurretBuild", mindustry.world.blocks.defense.turrets.BaseTurret.BaseTurretBuild.class);
|
||||||
|
classes.put("ItemTurret", mindustry.world.blocks.defense.turrets.ItemTurret.class);
|
||||||
|
classes.put("ItemTurretBuild", mindustry.world.blocks.defense.turrets.ItemTurret.ItemTurretBuild.class);
|
||||||
|
classes.put("LaserTurret", mindustry.world.blocks.defense.turrets.LaserTurret.class);
|
||||||
|
classes.put("LaserTurretBuild", mindustry.world.blocks.defense.turrets.LaserTurret.LaserTurretBuild.class);
|
||||||
|
classes.put("LiquidTurret", mindustry.world.blocks.defense.turrets.LiquidTurret.class);
|
||||||
|
classes.put("LiquidTurretBuild", mindustry.world.blocks.defense.turrets.LiquidTurret.LiquidTurretBuild.class);
|
||||||
|
classes.put("PointDefenseTurret", mindustry.world.blocks.defense.turrets.PointDefenseTurret.class);
|
||||||
|
classes.put("PointDefenseBuild", mindustry.world.blocks.defense.turrets.PointDefenseTurret.PointDefenseBuild.class);
|
||||||
|
classes.put("PowerTurret", mindustry.world.blocks.defense.turrets.PowerTurret.class);
|
||||||
|
classes.put("PowerTurretBuild", mindustry.world.blocks.defense.turrets.PowerTurret.PowerTurretBuild.class);
|
||||||
|
classes.put("ReloadTurret", mindustry.world.blocks.defense.turrets.ReloadTurret.class);
|
||||||
|
classes.put("ReloadTurretBuild", mindustry.world.blocks.defense.turrets.ReloadTurret.ReloadTurretBuild.class);
|
||||||
|
classes.put("TractorBeamTurret", mindustry.world.blocks.defense.turrets.TractorBeamTurret.class);
|
||||||
|
classes.put("TractorBeamBuild", mindustry.world.blocks.defense.turrets.TractorBeamTurret.TractorBeamBuild.class);
|
||||||
|
classes.put("Turret", mindustry.world.blocks.defense.turrets.Turret.class);
|
||||||
|
classes.put("AmmoEntry", mindustry.world.blocks.defense.turrets.Turret.AmmoEntry.class);
|
||||||
|
classes.put("TurretBuild", mindustry.world.blocks.defense.turrets.Turret.TurretBuild.class);
|
||||||
|
classes.put("ArmoredConveyor", mindustry.world.blocks.distribution.ArmoredConveyor.class);
|
||||||
|
classes.put("ArmoredConveyorBuild", mindustry.world.blocks.distribution.ArmoredConveyor.ArmoredConveyorBuild.class);
|
||||||
|
classes.put("BufferedItemBridge", mindustry.world.blocks.distribution.BufferedItemBridge.class);
|
||||||
|
classes.put("BufferedItemBridgeBuild", mindustry.world.blocks.distribution.BufferedItemBridge.BufferedItemBridgeBuild.class);
|
||||||
|
classes.put("ChainedBuilding", mindustry.world.blocks.distribution.ChainedBuilding.class);
|
||||||
|
classes.put("Conveyor", mindustry.world.blocks.distribution.Conveyor.class);
|
||||||
|
classes.put("ConveyorBuild", mindustry.world.blocks.distribution.Conveyor.ConveyorBuild.class);
|
||||||
|
classes.put("ExtendingItemBridge", mindustry.world.blocks.distribution.ExtendingItemBridge.class);
|
||||||
|
classes.put("ExtendingItemBridgeBuild", mindustry.world.blocks.distribution.ExtendingItemBridge.ExtendingItemBridgeBuild.class);
|
||||||
|
classes.put("ItemBridge", mindustry.world.blocks.distribution.ItemBridge.class);
|
||||||
|
classes.put("ItemBridgeBuild", mindustry.world.blocks.distribution.ItemBridge.ItemBridgeBuild.class);
|
||||||
|
classes.put("Junction", mindustry.world.blocks.distribution.Junction.class);
|
||||||
|
classes.put("JunctionBuild", mindustry.world.blocks.distribution.Junction.JunctionBuild.class);
|
||||||
|
classes.put("MassDriver", mindustry.world.blocks.distribution.MassDriver.class);
|
||||||
|
classes.put("DriverBulletData", mindustry.world.blocks.distribution.MassDriver.DriverBulletData.class);
|
||||||
|
classes.put("DriverState", mindustry.world.blocks.distribution.MassDriver.DriverState.class);
|
||||||
|
classes.put("MassDriverBuild", mindustry.world.blocks.distribution.MassDriver.MassDriverBuild.class);
|
||||||
|
classes.put("OverflowGate", mindustry.world.blocks.distribution.OverflowGate.class);
|
||||||
|
classes.put("OverflowGateBuild", mindustry.world.blocks.distribution.OverflowGate.OverflowGateBuild.class);
|
||||||
|
classes.put("PayloadConveyor", mindustry.world.blocks.distribution.PayloadConveyor.class);
|
||||||
|
classes.put("PayloadConveyorBuild", mindustry.world.blocks.distribution.PayloadConveyor.PayloadConveyorBuild.class);
|
||||||
|
classes.put("PayloadRouter", mindustry.world.blocks.distribution.PayloadRouter.class);
|
||||||
|
classes.put("PayloadRouterBuild", mindustry.world.blocks.distribution.PayloadRouter.PayloadRouterBuild.class);
|
||||||
|
classes.put("Router", mindustry.world.blocks.distribution.Router.class);
|
||||||
|
classes.put("RouterBuild", mindustry.world.blocks.distribution.Router.RouterBuild.class);
|
||||||
|
classes.put("Sorter", mindustry.world.blocks.distribution.Sorter.class);
|
||||||
|
classes.put("SorterBuild", mindustry.world.blocks.distribution.Sorter.SorterBuild.class);
|
||||||
|
classes.put("StackConveyor", mindustry.world.blocks.distribution.StackConveyor.class);
|
||||||
|
classes.put("StackConveyorBuild", mindustry.world.blocks.distribution.StackConveyor.StackConveyorBuild.class);
|
||||||
|
classes.put("AirBlock", mindustry.world.blocks.environment.AirBlock.class);
|
||||||
|
classes.put("Boulder", mindustry.world.blocks.environment.Boulder.class);
|
||||||
|
classes.put("Cliff", mindustry.world.blocks.environment.Cliff.class);
|
||||||
|
classes.put("DoubleOverlayFloor", mindustry.world.blocks.environment.DoubleOverlayFloor.class);
|
||||||
|
classes.put("Floor", mindustry.world.blocks.environment.Floor.class);
|
||||||
|
classes.put("OreBlock", mindustry.world.blocks.environment.OreBlock.class);
|
||||||
|
classes.put("OverlayFloor", mindustry.world.blocks.environment.OverlayFloor.class);
|
||||||
|
classes.put("ShallowLiquid", mindustry.world.blocks.environment.ShallowLiquid.class);
|
||||||
|
classes.put("SpawnBlock", mindustry.world.blocks.environment.SpawnBlock.class);
|
||||||
|
classes.put("StaticTree", mindustry.world.blocks.environment.StaticTree.class);
|
||||||
|
classes.put("StaticWall", mindustry.world.blocks.environment.StaticWall.class);
|
||||||
|
classes.put("TreeBlock", mindustry.world.blocks.environment.TreeBlock.class);
|
||||||
|
classes.put("BlockForge", mindustry.world.blocks.experimental.BlockForge.class);
|
||||||
|
classes.put("BlockForgeBuild", mindustry.world.blocks.experimental.BlockForge.BlockForgeBuild.class);
|
||||||
|
classes.put("BlockLoader", mindustry.world.blocks.experimental.BlockLoader.class);
|
||||||
|
classes.put("BlockLoaderBuild", mindustry.world.blocks.experimental.BlockLoader.BlockLoaderBuild.class);
|
||||||
|
classes.put("BlockUnloader", mindustry.world.blocks.experimental.BlockUnloader.class);
|
||||||
|
classes.put("BlockUnloaderBuild", mindustry.world.blocks.experimental.BlockUnloader.BlockUnloaderBuild.class);
|
||||||
|
classes.put("LegacyBlock", mindustry.world.blocks.legacy.LegacyBlock.class);
|
||||||
|
classes.put("LegacyMechPad", mindustry.world.blocks.legacy.LegacyMechPad.class);
|
||||||
|
classes.put("LegacyMechPadBuild", mindustry.world.blocks.legacy.LegacyMechPad.LegacyMechPadBuild.class);
|
||||||
|
classes.put("LegacyUnitFactory", mindustry.world.blocks.legacy.LegacyUnitFactory.class);
|
||||||
|
classes.put("LegacyUnitFactoryBuild", mindustry.world.blocks.legacy.LegacyUnitFactory.LegacyUnitFactoryBuild.class);
|
||||||
|
classes.put("ArmoredConduit", mindustry.world.blocks.liquid.ArmoredConduit.class);
|
||||||
|
classes.put("ArmoredConduitBuild", mindustry.world.blocks.liquid.ArmoredConduit.ArmoredConduitBuild.class);
|
||||||
|
classes.put("Conduit", mindustry.world.blocks.liquid.Conduit.class);
|
||||||
|
classes.put("ConduitBuild", mindustry.world.blocks.liquid.Conduit.ConduitBuild.class);
|
||||||
|
classes.put("LiquidBlock", mindustry.world.blocks.liquid.LiquidBlock.class);
|
||||||
|
classes.put("LiquidBuild", mindustry.world.blocks.liquid.LiquidBlock.LiquidBuild.class);
|
||||||
|
classes.put("LiquidBridge", mindustry.world.blocks.liquid.LiquidBridge.class);
|
||||||
|
classes.put("LiquidBridgeBuild", mindustry.world.blocks.liquid.LiquidBridge.LiquidBridgeBuild.class);
|
||||||
|
classes.put("LiquidExtendingBridge", mindustry.world.blocks.liquid.LiquidExtendingBridge.class);
|
||||||
|
classes.put("LiquidExtendingBridgeBuild", mindustry.world.blocks.liquid.LiquidExtendingBridge.LiquidExtendingBridgeBuild.class);
|
||||||
|
classes.put("LiquidJunction", mindustry.world.blocks.liquid.LiquidJunction.class);
|
||||||
|
classes.put("LiquidJunctionBuild", mindustry.world.blocks.liquid.LiquidJunction.LiquidJunctionBuild.class);
|
||||||
|
classes.put("LiquidRouter", mindustry.world.blocks.liquid.LiquidRouter.class);
|
||||||
|
classes.put("LiquidRouterBuild", mindustry.world.blocks.liquid.LiquidRouter.LiquidRouterBuild.class);
|
||||||
|
classes.put("LogicBlock", mindustry.world.blocks.logic.LogicBlock.class);
|
||||||
|
classes.put("LogicBuild", mindustry.world.blocks.logic.LogicBlock.LogicBuild.class);
|
||||||
|
classes.put("LogicLink", mindustry.world.blocks.logic.LogicBlock.LogicLink.class);
|
||||||
|
classes.put("LogicDisplay", mindustry.world.blocks.logic.LogicDisplay.class);
|
||||||
|
classes.put("GraphicsType", mindustry.world.blocks.logic.LogicDisplay.GraphicsType.class);
|
||||||
|
classes.put("LogicDisplayBuild", mindustry.world.blocks.logic.LogicDisplay.LogicDisplayBuild.class);
|
||||||
|
classes.put("MemoryBlock", mindustry.world.blocks.logic.MemoryBlock.class);
|
||||||
|
classes.put("MemoryBuild", mindustry.world.blocks.logic.MemoryBlock.MemoryBuild.class);
|
||||||
|
classes.put("MessageBlock", mindustry.world.blocks.logic.MessageBlock.class);
|
||||||
|
classes.put("MessageBuild", mindustry.world.blocks.logic.MessageBlock.MessageBuild.class);
|
||||||
|
classes.put("SwitchBlock", mindustry.world.blocks.logic.SwitchBlock.class);
|
||||||
|
classes.put("SwitchBuild", mindustry.world.blocks.logic.SwitchBlock.SwitchBuild.class);
|
||||||
|
classes.put("BuildPayload", mindustry.world.blocks.payloads.BuildPayload.class);
|
||||||
|
classes.put("Payload", mindustry.world.blocks.payloads.Payload.class);
|
||||||
|
classes.put("UnitPayload", mindustry.world.blocks.payloads.UnitPayload.class);
|
||||||
|
classes.put("Battery", mindustry.world.blocks.power.Battery.class);
|
||||||
|
classes.put("BatteryBuild", mindustry.world.blocks.power.Battery.BatteryBuild.class);
|
||||||
|
classes.put("BurnerGenerator", mindustry.world.blocks.power.BurnerGenerator.class);
|
||||||
|
classes.put("BurnerGeneratorBuild", mindustry.world.blocks.power.BurnerGenerator.BurnerGeneratorBuild.class);
|
||||||
|
classes.put("ConditionalConsumePower", mindustry.world.blocks.power.ConditionalConsumePower.class);
|
||||||
|
classes.put("DecayGenerator", mindustry.world.blocks.power.DecayGenerator.class);
|
||||||
|
classes.put("ImpactReactor", mindustry.world.blocks.power.ImpactReactor.class);
|
||||||
|
classes.put("ImpactReactorBuild", mindustry.world.blocks.power.ImpactReactor.ImpactReactorBuild.class);
|
||||||
|
classes.put("ItemLiquidGenerator", mindustry.world.blocks.power.ItemLiquidGenerator.class);
|
||||||
|
classes.put("ItemLiquidGeneratorBuild", mindustry.world.blocks.power.ItemLiquidGenerator.ItemLiquidGeneratorBuild.class);
|
||||||
|
classes.put("LightBlock", mindustry.world.blocks.power.LightBlock.class);
|
||||||
|
classes.put("LightBuild", mindustry.world.blocks.power.LightBlock.LightBuild.class);
|
||||||
|
classes.put("NuclearReactor", mindustry.world.blocks.power.NuclearReactor.class);
|
||||||
|
classes.put("NuclearReactorBuild", mindustry.world.blocks.power.NuclearReactor.NuclearReactorBuild.class);
|
||||||
|
classes.put("PowerBlock", mindustry.world.blocks.power.PowerBlock.class);
|
||||||
|
classes.put("PowerDiode", mindustry.world.blocks.power.PowerDiode.class);
|
||||||
|
classes.put("PowerDiodeBuild", mindustry.world.blocks.power.PowerDiode.PowerDiodeBuild.class);
|
||||||
|
classes.put("PowerDistributor", mindustry.world.blocks.power.PowerDistributor.class);
|
||||||
|
classes.put("PowerGenerator", mindustry.world.blocks.power.PowerGenerator.class);
|
||||||
|
classes.put("GeneratorBuild", mindustry.world.blocks.power.PowerGenerator.GeneratorBuild.class);
|
||||||
|
classes.put("PowerGraph", mindustry.world.blocks.power.PowerGraph.class);
|
||||||
|
classes.put("PowerNode", mindustry.world.blocks.power.PowerNode.class);
|
||||||
|
classes.put("PowerNodeBuild", mindustry.world.blocks.power.PowerNode.PowerNodeBuild.class);
|
||||||
|
classes.put("SingleTypeGenerator", mindustry.world.blocks.power.SingleTypeGenerator.class);
|
||||||
|
classes.put("SolarGenerator", mindustry.world.blocks.power.SolarGenerator.class);
|
||||||
|
classes.put("SolarGeneratorBuild", mindustry.world.blocks.power.SolarGenerator.SolarGeneratorBuild.class);
|
||||||
|
classes.put("ThermalGenerator", mindustry.world.blocks.power.ThermalGenerator.class);
|
||||||
|
classes.put("ThermalGeneratorBuild", mindustry.world.blocks.power.ThermalGenerator.ThermalGeneratorBuild.class);
|
||||||
|
classes.put("AttributeSmelter", mindustry.world.blocks.production.AttributeSmelter.class);
|
||||||
|
classes.put("AttributeSmelterBuild", mindustry.world.blocks.production.AttributeSmelter.AttributeSmelterBuild.class);
|
||||||
|
classes.put("Cultivator", mindustry.world.blocks.production.Cultivator.class);
|
||||||
|
classes.put("CultivatorBuild", mindustry.world.blocks.production.Cultivator.CultivatorBuild.class);
|
||||||
|
classes.put("Drill", mindustry.world.blocks.production.Drill.class);
|
||||||
|
classes.put("DrillBuild", mindustry.world.blocks.production.Drill.DrillBuild.class);
|
||||||
|
classes.put("Fracker", mindustry.world.blocks.production.Fracker.class);
|
||||||
|
classes.put("FrackerBuild", mindustry.world.blocks.production.Fracker.FrackerBuild.class);
|
||||||
|
classes.put("GenericCrafter", mindustry.world.blocks.production.GenericCrafter.class);
|
||||||
|
classes.put("GenericCrafterBuild", mindustry.world.blocks.production.GenericCrafter.GenericCrafterBuild.class);
|
||||||
|
classes.put("GenericSmelter", mindustry.world.blocks.production.GenericSmelter.class);
|
||||||
|
classes.put("SmelterBuild", mindustry.world.blocks.production.GenericSmelter.SmelterBuild.class);
|
||||||
|
classes.put("Incinerator", mindustry.world.blocks.production.Incinerator.class);
|
||||||
|
classes.put("IncineratorBuild", mindustry.world.blocks.production.Incinerator.IncineratorBuild.class);
|
||||||
|
classes.put("LiquidConverter", mindustry.world.blocks.production.LiquidConverter.class);
|
||||||
|
classes.put("LiquidConverterBuild", mindustry.world.blocks.production.LiquidConverter.LiquidConverterBuild.class);
|
||||||
|
classes.put("PayloadAcceptor", mindustry.world.blocks.production.PayloadAcceptor.class);
|
||||||
|
classes.put("PayloadAcceptorBuild", mindustry.world.blocks.production.PayloadAcceptor.PayloadAcceptorBuild.class);
|
||||||
|
classes.put("Pump", mindustry.world.blocks.production.Pump.class);
|
||||||
|
classes.put("PumpBuild", mindustry.world.blocks.production.Pump.PumpBuild.class);
|
||||||
|
classes.put("Separator", mindustry.world.blocks.production.Separator.class);
|
||||||
|
classes.put("SeparatorBuild", mindustry.world.blocks.production.Separator.SeparatorBuild.class);
|
||||||
|
classes.put("SolidPump", mindustry.world.blocks.production.SolidPump.class);
|
||||||
|
classes.put("SolidPumpBuild", mindustry.world.blocks.production.SolidPump.SolidPumpBuild.class);
|
||||||
|
classes.put("ItemSource", mindustry.world.blocks.sandbox.ItemSource.class);
|
||||||
|
classes.put("ItemSourceBuild", mindustry.world.blocks.sandbox.ItemSource.ItemSourceBuild.class);
|
||||||
|
classes.put("ItemVoid", mindustry.world.blocks.sandbox.ItemVoid.class);
|
||||||
|
classes.put("ItemVoidBuild", mindustry.world.blocks.sandbox.ItemVoid.ItemVoidBuild.class);
|
||||||
|
classes.put("LiquidSource", mindustry.world.blocks.sandbox.LiquidSource.class);
|
||||||
|
classes.put("LiquidSourceBuild", mindustry.world.blocks.sandbox.LiquidSource.LiquidSourceBuild.class);
|
||||||
|
classes.put("LiquidVoid", mindustry.world.blocks.sandbox.LiquidVoid.class);
|
||||||
|
classes.put("LiquidVoidBuild", mindustry.world.blocks.sandbox.LiquidVoid.LiquidVoidBuild.class);
|
||||||
|
classes.put("PowerSource", mindustry.world.blocks.sandbox.PowerSource.class);
|
||||||
|
classes.put("PowerSourceBuild", mindustry.world.blocks.sandbox.PowerSource.PowerSourceBuild.class);
|
||||||
|
classes.put("PowerVoid", mindustry.world.blocks.sandbox.PowerVoid.class);
|
||||||
|
classes.put("CoreBlock", mindustry.world.blocks.storage.CoreBlock.class);
|
||||||
|
classes.put("CoreBuild", mindustry.world.blocks.storage.CoreBlock.CoreBuild.class);
|
||||||
|
classes.put("StorageBlock", mindustry.world.blocks.storage.StorageBlock.class);
|
||||||
|
classes.put("StorageBuild", mindustry.world.blocks.storage.StorageBlock.StorageBuild.class);
|
||||||
|
classes.put("Unloader", mindustry.world.blocks.storage.Unloader.class);
|
||||||
|
classes.put("UnloaderBuild", mindustry.world.blocks.storage.Unloader.UnloaderBuild.class);
|
||||||
|
classes.put("CommandCenter", mindustry.world.blocks.units.CommandCenter.class);
|
||||||
|
classes.put("CommandBuild", mindustry.world.blocks.units.CommandCenter.CommandBuild.class);
|
||||||
|
classes.put("Reconstructor", mindustry.world.blocks.units.Reconstructor.class);
|
||||||
|
classes.put("ReconstructorBuild", mindustry.world.blocks.units.Reconstructor.ReconstructorBuild.class);
|
||||||
|
classes.put("RepairPoint", mindustry.world.blocks.units.RepairPoint.class);
|
||||||
|
classes.put("RepairPointBuild", mindustry.world.blocks.units.RepairPoint.RepairPointBuild.class);
|
||||||
|
classes.put("ResupplyPoint", mindustry.world.blocks.units.ResupplyPoint.class);
|
||||||
|
classes.put("ResupplyPointBuild", mindustry.world.blocks.units.ResupplyPoint.ResupplyPointBuild.class);
|
||||||
|
classes.put("UnitBlock", mindustry.world.blocks.units.UnitBlock.class);
|
||||||
|
classes.put("UnitBuild", mindustry.world.blocks.units.UnitBlock.UnitBuild.class);
|
||||||
|
classes.put("UnitFactory", mindustry.world.blocks.units.UnitFactory.class);
|
||||||
|
classes.put("UnitFactoryBuild", mindustry.world.blocks.units.UnitFactory.UnitFactoryBuild.class);
|
||||||
|
classes.put("UnitPlan", mindustry.world.blocks.units.UnitFactory.UnitPlan.class);
|
||||||
|
classes.put("DrawAnimation", mindustry.world.draw.DrawAnimation.class);
|
||||||
|
classes.put("DrawBlock", mindustry.world.draw.DrawBlock.class);
|
||||||
|
classes.put("DrawGlow", mindustry.world.draw.DrawGlow.class);
|
||||||
|
classes.put("DrawMixer", mindustry.world.draw.DrawMixer.class);
|
||||||
|
classes.put("DrawRotator", mindustry.world.draw.DrawRotator.class);
|
||||||
|
classes.put("DrawWeave", mindustry.world.draw.DrawWeave.class);
|
||||||
|
classes.put("Block", mindustry.world.Block.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,10 +15,12 @@ import arc.util.serialization.*;
|
|||||||
import arc.util.serialization.Json.*;
|
import arc.util.serialization.Json.*;
|
||||||
import arc.util.serialization.Jval.*;
|
import arc.util.serialization.Jval.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.ai.types.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.content.TechTree.*;
|
import mindustry.content.TechTree.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.abilities.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.entities.effect.*;
|
import mindustry.entities.effect.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -26,6 +28,7 @@ import mindustry.game.Objectives.*;
|
|||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.mod.Mods.*;
|
import mindustry.mod.Mods.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.type.weather.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.units.*;
|
import mindustry.world.blocks.units.*;
|
||||||
import mindustry.world.blocks.units.UnitFactory.*;
|
import mindustry.world.blocks.units.UnitFactory.*;
|
||||||
@@ -42,14 +45,14 @@ public class ContentParser{
|
|||||||
private static final boolean ignoreUnknownFields = true;
|
private static final boolean ignoreUnknownFields = true;
|
||||||
ObjectMap<Class<?>, ContentType> contentTypes = new ObjectMap<>();
|
ObjectMap<Class<?>, ContentType> contentTypes = new ObjectMap<>();
|
||||||
ObjectSet<Class<?>> implicitNullable = ObjectSet.with(TextureRegion.class, TextureRegion[].class, TextureRegion[][].class);
|
ObjectSet<Class<?>> implicitNullable = ObjectSet.with(TextureRegion.class, TextureRegion[].class, TextureRegion[][].class);
|
||||||
ObjectMap<String, AssetDescriptor> sounds = new ObjectMap<>();
|
ObjectMap<String, AssetDescriptor<?>> sounds = new ObjectMap<>();
|
||||||
|
|
||||||
ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<>(){{
|
ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<>(){{
|
||||||
put(Effect.class, (type, data) -> {
|
put(Effect.class, (type, data) -> {
|
||||||
if(data.isString()){
|
if(data.isString()){
|
||||||
return field(Fx.class, data);
|
return field(Fx.class, data);
|
||||||
}
|
}
|
||||||
Class<? extends Effect> bc = data.has("type") ? resolve(data.getString("type"), "mindustry.entities.effect") : ParticleEffect.class;
|
Class<? extends Effect> bc = resolve(data.getString("type", ""), ParticleEffect.class);
|
||||||
data.remove("type");
|
data.remove("type");
|
||||||
Effect result = make(bc);
|
Effect result = make(bc);
|
||||||
readFields(result, data);
|
readFields(result, data);
|
||||||
@@ -83,12 +86,23 @@ public class ContentParser{
|
|||||||
if(data.isString()){
|
if(data.isString()){
|
||||||
return field(Bullets.class, data);
|
return field(Bullets.class, data);
|
||||||
}
|
}
|
||||||
Class<? extends BulletType> bc = data.has("type") ? resolve(data.getString("type"), "mindustry.entities.bullet") : BasicBulletType.class;
|
var bc = resolve(data.getString("type", ""), BasicBulletType.class);
|
||||||
data.remove("type");
|
data.remove("type");
|
||||||
BulletType result = make(bc);
|
BulletType result = make(bc);
|
||||||
readFields(result, data);
|
readFields(result, data);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
put(DrawBlock.class, (type, data) -> {
|
||||||
|
if(data.isString()){
|
||||||
|
//try to instantiate
|
||||||
|
return make(resolve(data.asString()));
|
||||||
|
}
|
||||||
|
var bc = resolve(data.getString("type", ""), DrawBlock.class);
|
||||||
|
data.remove("type");
|
||||||
|
var result = make(bc);
|
||||||
|
readFields(result, data);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
put(Sound.class, (type, data) -> {
|
put(Sound.class, (type, data) -> {
|
||||||
if(fieldOpt(Sounds.class, data) != null) return fieldOpt(Sounds.class, data);
|
if(fieldOpt(Sounds.class, data) != null) return fieldOpt(Sounds.class, data);
|
||||||
if(Vars.headless) return new Sound();
|
if(Vars.headless) return new Sound();
|
||||||
@@ -104,12 +118,19 @@ public class ContentParser{
|
|||||||
return sound;
|
return sound;
|
||||||
});
|
});
|
||||||
put(Objectives.Objective.class, (type, data) -> {
|
put(Objectives.Objective.class, (type, data) -> {
|
||||||
Class<? extends Objectives.Objective> oc = data.has("type") ? resolve(data.getString("type"), "mindustry.game.Objectives") : SectorComplete.class;
|
var oc = resolve(data.getString("type", ""), SectorComplete.class);
|
||||||
data.remove("type");
|
data.remove("type");
|
||||||
Objectives.Objective obj = make(oc);
|
Objectives.Objective obj = make(oc);
|
||||||
readFields(obj, data);
|
readFields(obj, data);
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
|
put(Ability.class, (type, data) -> {
|
||||||
|
Class<? extends Ability> oc = resolve(data.getString("type", ""));
|
||||||
|
data.remove("type");
|
||||||
|
Ability obj = make(oc);
|
||||||
|
readFields(obj, data);
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
put(Weapon.class, (type, data) -> {
|
put(Weapon.class, (type, data) -> {
|
||||||
Weapon weapon = new Weapon();
|
Weapon weapon = new Weapon();
|
||||||
readFields(weapon, data);
|
readFields(weapon, data);
|
||||||
@@ -118,12 +139,13 @@ public class ContentParser{
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
/** Stores things that need to be parsed fully, e.g. reading fields of content.
|
/** Stores things that need to be parsed fully, e.g. reading fields of content.
|
||||||
* This is done to accomodate binding of content names first.*/
|
* This is done to accommodate binding of content names first.*/
|
||||||
private Seq<Runnable> reads = new Seq<>();
|
private Seq<Runnable> reads = new Seq<>();
|
||||||
private Seq<Runnable> postreads = new Seq<>();
|
private Seq<Runnable> postreads = new Seq<>();
|
||||||
private ObjectSet<Object> toBeParsed = new ObjectSet<>();
|
private ObjectSet<Object> toBeParsed = new ObjectSet<>();
|
||||||
|
|
||||||
LoadedMod currentMod;
|
LoadedMod currentMod;
|
||||||
private Content currentContent;
|
Content currentContent;
|
||||||
|
|
||||||
private Json parser = new Json(){
|
private Json parser = new Json(){
|
||||||
@Override
|
@Override
|
||||||
@@ -160,11 +182,6 @@ public class ContentParser{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to load DrawBlock by instantiating it
|
|
||||||
if(type == DrawBlock.class && jsonData.isString()){
|
|
||||||
return Reflect.make("mindustry.world.draw." + Strings.capitalize(jsonData.asString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Content.class.isAssignableFrom(type)){
|
if(Content.class.isAssignableFrom(type)){
|
||||||
ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName()));
|
ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName()));
|
||||||
String prefix = currentMod != null ? currentMod.name + "-" : "";
|
String prefix = currentMod != null ? currentMod.name + "-" : "";
|
||||||
@@ -194,30 +211,7 @@ public class ContentParser{
|
|||||||
throw new IllegalArgumentException("When defining properties for an existing block, you must not re-declare its type. The original type will be used. Block: " + name);
|
throw new IllegalArgumentException("When defining properties for an existing block, you must not re-declare its type. The original type will be used. Block: " + name);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
//TODO generate dynamically instead of doing.. this
|
block = make(resolve(value.getString("type", ""), Block.class), mod + "-" + name);
|
||||||
Class<? extends Block> type;
|
|
||||||
|
|
||||||
try{
|
|
||||||
type = resolve(getType(value),
|
|
||||||
"mindustry.world",
|
|
||||||
"mindustry.world.blocks",
|
|
||||||
"mindustry.world.blocks.defense",
|
|
||||||
"mindustry.world.blocks.defense.turrets",
|
|
||||||
"mindustry.world.blocks.distribution",
|
|
||||||
"mindustry.world.blocks.environment",
|
|
||||||
"mindustry.world.blocks.liquid",
|
|
||||||
"mindustry.world.blocks.logic",
|
|
||||||
"mindustry.world.blocks.power",
|
|
||||||
"mindustry.world.blocks.production",
|
|
||||||
"mindustry.world.blocks.sandbox",
|
|
||||||
"mindustry.world.blocks.storage",
|
|
||||||
"mindustry.world.blocks.units"
|
|
||||||
);
|
|
||||||
}catch(IllegalArgumentException e){
|
|
||||||
type = Block.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
block = make(type, mod + "-" + name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentContent = block;
|
currentContent = block;
|
||||||
@@ -225,22 +219,19 @@ public class ContentParser{
|
|||||||
read(() -> {
|
read(() -> {
|
||||||
if(value.has("consumes") && value.get("consumes").isObject()){
|
if(value.has("consumes") && value.get("consumes").isObject()){
|
||||||
for(JsonValue child : value.get("consumes")){
|
for(JsonValue child : value.get("consumes")){
|
||||||
if(child.name.equals("item")){
|
switch(child.name){
|
||||||
block.consumes.item(find(ContentType.item, child.asString()));
|
case "item" -> block.consumes.item(find(ContentType.item, child.asString()));
|
||||||
}else if(child.name.equals("items")){
|
case "items" -> block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child));
|
||||||
block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child));
|
case "liquid" -> block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child));
|
||||||
}else if(child.name.equals("liquid")){
|
case "power" -> {
|
||||||
block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child));
|
if(child.isNumber()){
|
||||||
}else if(child.name.equals("power")){
|
block.consumes.power(child.asFloat());
|
||||||
if(child.isNumber()){
|
}else{
|
||||||
block.consumes.power(child.asFloat());
|
block.consumes.add((Consume)parser.readValue(ConsumePower.class, child));
|
||||||
}else{
|
}
|
||||||
block.consumes.add((Consume)parser.readValue(ConsumePower.class, child));
|
|
||||||
}
|
}
|
||||||
}else if(child.name.equals("powerBuffered")){
|
case "powerBuffered" -> block.consumes.powerBuffered(child.asFloat());
|
||||||
block.consumes.powerBuffered(child.asFloat());
|
default -> throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'.");
|
||||||
}else{
|
|
||||||
throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value.remove("consumes");
|
value.remove("consumes");
|
||||||
@@ -284,15 +275,6 @@ public class ContentParser{
|
|||||||
if(value.has("requirements")){
|
if(value.has("requirements")){
|
||||||
JsonValue rec = value.remove("requirements");
|
JsonValue rec = value.remove("requirements");
|
||||||
|
|
||||||
//intermediate class for parsing
|
|
||||||
class UnitReq{
|
|
||||||
public Block block;
|
|
||||||
public ItemStack[] requirements = {};
|
|
||||||
@Nullable
|
|
||||||
public UnitType previous;
|
|
||||||
public float time = 60f * 10f;
|
|
||||||
}
|
|
||||||
|
|
||||||
UnitReq req = parser.readValue(UnitReq.class, rec);
|
UnitReq req = parser.readValue(UnitReq.class, rec);
|
||||||
|
|
||||||
if(req.block instanceof Reconstructor r){
|
if(req.block instanceof Reconstructor r){
|
||||||
@@ -308,7 +290,8 @@ public class ContentParser{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(value.has("controller")){
|
if(value.has("controller")){
|
||||||
unit.defaultController = make(resolve(value.getString("controller"), "mindustry.ai.types"));
|
unit.defaultController = supply(resolve(value.getString("controller"), FlyingAI.class));
|
||||||
|
value.remove("controller");
|
||||||
}
|
}
|
||||||
|
|
||||||
//read extra default waves
|
//read extra default waves
|
||||||
@@ -334,8 +317,7 @@ public class ContentParser{
|
|||||||
readBundle(ContentType.weather, name, value);
|
readBundle(ContentType.weather, name, value);
|
||||||
}else{
|
}else{
|
||||||
readBundle(ContentType.weather, name, value);
|
readBundle(ContentType.weather, name, value);
|
||||||
Class<? extends Weather> type = resolve(getType(value), "mindustry.type.weather");
|
item = make(resolve(getType(value), ParticleWeather.class));
|
||||||
item = make(type);
|
|
||||||
}
|
}
|
||||||
currentContent = item;
|
currentContent = item;
|
||||||
read(() -> readFields(item, value));
|
read(() -> readFields(item, value));
|
||||||
@@ -425,6 +407,12 @@ public class ContentParser{
|
|||||||
this.currentMod = mod;
|
this.currentMod = mod;
|
||||||
this.currentContent = cont;
|
this.currentContent = cont;
|
||||||
run.run();
|
run.run();
|
||||||
|
|
||||||
|
//check nulls after parsing
|
||||||
|
if(cont != null){
|
||||||
|
toBeParsed.remove(cont);
|
||||||
|
checkNullFields(cont);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,8 +612,8 @@ public class ContentParser{
|
|||||||
JsonValue research = jsonMap.remove("research");
|
JsonValue research = jsonMap.remove("research");
|
||||||
|
|
||||||
toBeParsed.remove(object);
|
toBeParsed.remove(object);
|
||||||
Class type = object.getClass();
|
var type = object.getClass();
|
||||||
ObjectMap<String, FieldMetadata> fields = parser.getFields(type);
|
var fields = parser.getFields(type);
|
||||||
for(JsonValue child = jsonMap.child; child != null; child = child.next){
|
for(JsonValue child = jsonMap.child; child != null; child = child.next){
|
||||||
FieldMetadata metadata = fields.get(child.name().replace(" ", "_"));
|
FieldMetadata metadata = fields.get(child.name().replace(" ", "_"));
|
||||||
if(metadata == null){
|
if(metadata == null){
|
||||||
@@ -654,7 +642,6 @@ public class ContentParser{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(object instanceof UnlockableContent unlock && research != null){
|
if(object instanceof UnlockableContent unlock && research != null){
|
||||||
|
|
||||||
//add research tech node
|
//add research tech node
|
||||||
@@ -706,21 +693,41 @@ public class ContentParser{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tries to resolve a class from a list of potential class names. */
|
/** Tries to resolve a class from the class type map. */
|
||||||
<T> Class<T> resolve(String base, String... potentials){
|
<T> Class<T> resolve(String base){
|
||||||
if(!base.isEmpty() && Character.isLowerCase(base.charAt(0))) base = Strings.capitalize(base);
|
return resolve(base, null);
|
||||||
|
}
|
||||||
|
|
||||||
for(String type : potentials){
|
/** Tries to resolve a class from the class type map. */
|
||||||
|
<T> Class<T> resolve(String base, Class<T> def){
|
||||||
|
//no base class specified
|
||||||
|
if(base.isEmpty() && def != null) return def;
|
||||||
|
|
||||||
|
//return mapped class if found in the global map
|
||||||
|
var out = ClassMap.classes.get(!base.isEmpty() && Character.isLowerCase(base.charAt(0)) ? Strings.capitalize(base) : base);
|
||||||
|
if(out != null) return (Class<T>)out;
|
||||||
|
|
||||||
|
//try to resolve it as a raw class name if it's allowed
|
||||||
|
if(base.indexOf('.') != -1 && Scripts.allowClass(base)){
|
||||||
try{
|
try{
|
||||||
return (Class<T>)Class.forName(type + '.' + base);
|
return (Class<T>)Class.forName(base);
|
||||||
}catch(Exception ignored){
|
}catch(Exception ignored){
|
||||||
try{
|
//try to load from a mod's class loader
|
||||||
return (Class<T>)Class.forName(type + '$' + base);
|
for(LoadedMod mod : mods.mods){
|
||||||
}catch(Exception ignored2){
|
if(mod.loader != null){
|
||||||
|
try{
|
||||||
|
return (Class<T>)Class.forName(base, true, mod.loader);
|
||||||
|
}catch(Exception ignore){}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Types not found: " + base + "." + potentials[0]);
|
|
||||||
|
if(def != null){
|
||||||
|
Log.warn("[@] No type '" + base + "' found, defaulting to type '" + def.getSimpleName() + "'", currentContent == null ? currentMod.name : "");
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Type not found: " + base);
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface FieldParser{
|
private interface FieldParser{
|
||||||
@@ -731,4 +738,13 @@ public class ContentParser{
|
|||||||
T parse(String mod, String name, JsonValue value) throws Exception;
|
T parse(String mod, String name, JsonValue value) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//intermediate class for parsing
|
||||||
|
static class UnitReq{
|
||||||
|
public Block block;
|
||||||
|
public ItemStack[] requirements = {};
|
||||||
|
@Nullable
|
||||||
|
public UnitType previous;
|
||||||
|
public float time = 60f * 10f;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import mindustry.type.*;
|
|||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -92,6 +93,8 @@ public class Mods implements Loadable{
|
|||||||
var loaded = loadMod(dest, true);
|
var loaded = loadMod(dest, true);
|
||||||
mods.add(loaded);
|
mods.add(loaded);
|
||||||
requiresReload = true;
|
requiresReload = true;
|
||||||
|
//enable the mod on import
|
||||||
|
Core.settings.put("mod-" + loaded.name + "-enabled", true);
|
||||||
sortMods();
|
sortMods();
|
||||||
//try to load the mod's icon so it displays on import
|
//try to load the mod's icon so it displays on import
|
||||||
Core.app.post(() -> {
|
Core.app.post(() -> {
|
||||||
@@ -257,6 +260,11 @@ public class Mods implements Loadable{
|
|||||||
return requiresReload;
|
return requiresReload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether to skip mod loading due to previous initialization failure. */
|
||||||
|
public boolean skipModLoading(){
|
||||||
|
return failedToLaunch && Core.settings.getBool("modcrashdisable", true);
|
||||||
|
}
|
||||||
|
|
||||||
/** Loads all mods from the folder, but does not call any methods on them.*/
|
/** Loads all mods from the folder, but does not call any methods on them.*/
|
||||||
public void load(){
|
public void load(){
|
||||||
for(Fi file : modDirectory.list()){
|
for(Fi file : modDirectory.list()){
|
||||||
@@ -519,7 +527,7 @@ public class Mods implements Loadable{
|
|||||||
if(mod.root.child("content").exists()){
|
if(mod.root.child("content").exists()){
|
||||||
Fi contentRoot = mod.root.child("content");
|
Fi contentRoot = mod.root.child("content");
|
||||||
for(ContentType type : ContentType.all){
|
for(ContentType type : ContentType.all){
|
||||||
Fi folder = contentRoot.child(type.name().toLowerCase() + "s");
|
Fi folder = contentRoot.child(type.name().toLowerCase(Locale.ROOT) + "s");
|
||||||
if(folder.exists()){
|
if(folder.exists()){
|
||||||
for(Fi file : folder.findAll(f -> f.extension().equals("json") || f.extension().equals("hjson"))){
|
for(Fi file : folder.findAll(f -> f.extension().equals("json") || f.extension().equals("hjson"))){
|
||||||
runs.add(new LoadRun(type, file, mod));
|
runs.add(new LoadRun(type, file, mod));
|
||||||
@@ -639,8 +647,8 @@ public class Mods implements Loadable{
|
|||||||
ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain));
|
ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain));
|
||||||
meta.cleanup();
|
meta.cleanup();
|
||||||
String camelized = meta.name.replace(" ", "");
|
String camelized = meta.name.replace(" ", "");
|
||||||
String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main;
|
String mainClass = meta.main == null ? camelized.toLowerCase(Locale.ROOT) + "." + camelized + "Mod" : meta.main;
|
||||||
String baseName = meta.name.toLowerCase().replace(" ", "-");
|
String baseName = meta.name.toLowerCase(Locale.ROOT).replace(" ", "-");
|
||||||
|
|
||||||
var other = mods.find(m -> m.name.equals(baseName));
|
var other = mods.find(m -> m.name.equals(baseName));
|
||||||
|
|
||||||
@@ -664,9 +672,10 @@ public class Mods implements Loadable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClassLoader loader = null;
|
||||||
Mod mainMod;
|
Mod mainMod;
|
||||||
|
|
||||||
Fi mainFile = zip;
|
Fi mainFile = zip;
|
||||||
|
|
||||||
if(android){
|
if(android){
|
||||||
mainFile = mainFile.child("classes.dex");
|
mainFile = mainFile.child("classes.dex");
|
||||||
}else{
|
}else{
|
||||||
@@ -680,14 +689,20 @@ public class Mods implements Loadable{
|
|||||||
|
|
||||||
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
||||||
//if the mod is explicitly marked as java, try loading it anyway
|
//if the mod is explicitly marked as java, try loading it anyway
|
||||||
if((mainFile.exists() || meta.java) &&
|
if(
|
||||||
Core.settings.getBool("mod-" + baseName + "-enabled", true) && Version.isAtLeast(meta.minGameVersion) && (meta.getMinMajor() >= 105 || headless)){
|
(mainFile.exists() || meta.java) &&
|
||||||
|
!skipModLoading() &&
|
||||||
|
Core.settings.getBool("mod-" + baseName + "-enabled", true) &&
|
||||||
|
Version.isAtLeast(meta.minGameVersion) &&
|
||||||
|
(meta.getMinMajor() >= 105 || headless)
|
||||||
|
){
|
||||||
|
|
||||||
if(ios){
|
if(ios){
|
||||||
throw new IllegalArgumentException("Java class mods are not supported on iOS.");
|
throw new IllegalArgumentException("Java class mods are not supported on iOS.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<?> main = platform.loadJar(sourceFile, mainClass);
|
loader = platform.loadJar(sourceFile, mainClass);
|
||||||
|
Class<?> main = Class.forName(mainClass, true, loader);
|
||||||
metas.put(main, meta);
|
metas.put(main, meta);
|
||||||
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
|
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
|
||||||
}else{
|
}else{
|
||||||
@@ -707,11 +722,16 @@ public class Mods implements Loadable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//skip mod loading if it failed
|
||||||
|
if(skipModLoading()){
|
||||||
|
Core.settings.put("mod-" + baseName + "-enabled", false);
|
||||||
|
}
|
||||||
|
|
||||||
if(!headless){
|
if(!headless){
|
||||||
Log.info("Loaded mod '@' in @ms", meta.name, Time.elapsed());
|
Log.info("Loaded mod '@' in @ms", meta.name, Time.elapsed());
|
||||||
}
|
}
|
||||||
return new LoadedMod(sourceFile, zip, mainMod, meta);
|
|
||||||
|
|
||||||
|
return new LoadedMod(sourceFile, zip, mainMod, loader, meta);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
//delete root zip file so it can be closed on windows
|
//delete root zip file so it can be closed on windows
|
||||||
if(rootZip != null) rootZip.delete();
|
if(rootZip != null) rootZip.delete();
|
||||||
@@ -743,13 +763,16 @@ public class Mods implements Loadable{
|
|||||||
public ModState state = ModState.enabled;
|
public ModState state = ModState.enabled;
|
||||||
/** Icon texture. Should be disposed. */
|
/** Icon texture. Should be disposed. */
|
||||||
public @Nullable Texture iconTexture;
|
public @Nullable Texture iconTexture;
|
||||||
|
/** Class loader for JAR mods. Null if the mod isn't loaded or this isn't a jar mod. */
|
||||||
|
public @Nullable ClassLoader loader;
|
||||||
|
|
||||||
public LoadedMod(Fi file, Fi root, Mod main, ModMeta meta){
|
public LoadedMod(Fi file, Fi root, Mod main, ClassLoader loader, ModMeta meta){
|
||||||
this.root = root;
|
this.root = root;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
this.loader = loader;
|
||||||
this.main = main;
|
this.main = main;
|
||||||
this.meta = meta;
|
this.meta = meta;
|
||||||
this.name = meta.name.toLowerCase().replace(" ", "-");
|
this.name = meta.name.toLowerCase(Locale.ROOT).replace(" ", "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether this is a java class mod. */
|
/** @return whether this is a java class mod. */
|
||||||
|
|||||||
@@ -18,23 +18,29 @@ import rhino.module.provider.*;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
import java.util.*;
|
||||||
import java.util.regex.*;
|
import java.util.regex.*;
|
||||||
|
|
||||||
public class Scripts implements Disposable{
|
public class Scripts implements Disposable{
|
||||||
private final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk",
|
private static final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk",
|
||||||
"runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system",
|
"runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system",
|
||||||
".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.");
|
".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.", "mod.classmap");
|
||||||
private final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent");
|
private static final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent");
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final Scriptable scope;
|
private final Scriptable scope;
|
||||||
private boolean errored;
|
private boolean errored;
|
||||||
LoadedMod currentMod = null;
|
LoadedMod currentMod = null;
|
||||||
|
|
||||||
|
public static boolean allowClass(String type){
|
||||||
|
return !blacklist.contains(t -> type.toLowerCase(Locale.ROOT).contains(t)) || whitelist.contains(t -> type.toLowerCase(Locale.ROOT).contains(t));
|
||||||
|
}
|
||||||
|
|
||||||
public Scripts(){
|
public Scripts(){
|
||||||
Time.mark();
|
Time.mark();
|
||||||
|
|
||||||
context = Vars.platform.getScriptContext();
|
context = Vars.platform.getScriptContext();
|
||||||
context.setClassShutter(type -> !blacklist.contains(type.toLowerCase()::contains) || whitelist.contains(type.toLowerCase()::contains));
|
context.setClassShutter(Scripts::allowClass);
|
||||||
context.getWrapFactory().setJavaPrimitiveWrap(false);
|
context.getWrapFactory().setJavaPrimitiveWrap(false);
|
||||||
context.setLanguageVersion(Context.VERSION_ES6);
|
context.setLanguageVersion(Context.VERSION_ES6);
|
||||||
|
|
||||||
|
|||||||
@@ -479,9 +479,7 @@ public class Administration{
|
|||||||
autosave("Whether the periodically save the map when playing.", false),
|
autosave("Whether the periodically save the map when playing.", false),
|
||||||
autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10),
|
autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10),
|
||||||
autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5),
|
autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5),
|
||||||
debug("Enable debug logging", false, () -> {
|
debug("Enable debug logging", false, () -> Log.level = debug() ? LogLevel.debug : LogLevel.info);
|
||||||
Log.level = debug() ? LogLevel.debug : LogLevel.info;
|
|
||||||
});
|
|
||||||
|
|
||||||
public static final Config[] all = values();
|
public static final Config[] all = values();
|
||||||
|
|
||||||
@@ -586,12 +584,15 @@ public class Administration{
|
|||||||
public static class TraceInfo{
|
public static class TraceInfo{
|
||||||
public String ip, uuid;
|
public String ip, uuid;
|
||||||
public boolean modded, mobile;
|
public boolean modded, mobile;
|
||||||
|
public int timesJoined, timesKicked;
|
||||||
|
|
||||||
public TraceInfo(String ip, String uuid, boolean modded, boolean mobile){
|
public TraceInfo(String ip, String uuid, boolean modded, boolean mobile, int timesJoined, int timesKicked){
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.modded = modded;
|
this.modded = modded;
|
||||||
this.mobile = mobile;
|
this.mobile = mobile;
|
||||||
|
this.timesJoined = timesJoined;
|
||||||
|
this.timesKicked = timesKicked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ public class Net{
|
|||||||
*/
|
*/
|
||||||
void discoverServers(Cons<Host> callback, Runnable done);
|
void discoverServers(Cons<Host> callback, Runnable done);
|
||||||
|
|
||||||
/** Ping a host. If an error occured, failed() should be called with the exception. */
|
/** Ping a host. If an error occurred, failed() should be called with the exception. */
|
||||||
void pingHost(String address, int port, Cons<Host> valid, Cons<Exception> failed);
|
void pingHost(String address, int port, Cons<Host> valid, Cons<Exception> failed);
|
||||||
|
|
||||||
/** Host a server at specified port. */
|
/** Host a server at specified port. */
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public abstract class NetConnection{
|
|||||||
public @Nullable Player player;
|
public @Nullable Player player;
|
||||||
public boolean kicked = false;
|
public boolean kicked = false;
|
||||||
|
|
||||||
|
/** When this connection was established. */
|
||||||
|
public long connectTime = Time.millis();
|
||||||
/** ID of last received client snapshot. */
|
/** ID of last received client snapshot. */
|
||||||
public int lastReceivedClientSnapshot = -1;
|
public int lastReceivedClientSnapshot = -1;
|
||||||
/** Timestamp of last received snapshot. */
|
/** Timestamp of last received snapshot. */
|
||||||
@@ -47,7 +49,7 @@ public abstract class NetConnection{
|
|||||||
|
|
||||||
Call.kick(this, reason);
|
Call.kick(this, reason);
|
||||||
|
|
||||||
Time.runTask(2f, this::close);
|
close();
|
||||||
|
|
||||||
netServer.admins.save();
|
netServer.admins.save();
|
||||||
kicked = true;
|
kicked = true;
|
||||||
@@ -68,7 +70,7 @@ public abstract class NetConnection{
|
|||||||
|
|
||||||
Call.kick(this, reason);
|
Call.kick(this, reason);
|
||||||
|
|
||||||
Time.runTask(2f, this::close);
|
close();
|
||||||
|
|
||||||
netServer.admins.save();
|
netServer.admins.save();
|
||||||
kicked = true;
|
kicked = true;
|
||||||
|
|||||||
@@ -15,10 +15,14 @@ public class StatusEffect extends MappableContent{
|
|||||||
public float damageMultiplier = 1f;
|
public float damageMultiplier = 1f;
|
||||||
/** Unit health multiplier. */
|
/** Unit health multiplier. */
|
||||||
public float healthMultiplier = 1f;
|
public float healthMultiplier = 1f;
|
||||||
/** Unit speed multiplier */
|
/** Unit speed multiplier. */
|
||||||
public float speedMultiplier = 1f;
|
public float speedMultiplier = 1f;
|
||||||
/** Unit speed multiplier */
|
/** Unit reload multiplier. */
|
||||||
public float reloadMultiplier = 1f;
|
public float reloadMultiplier = 1f;
|
||||||
|
/** Unit build speed multiplier. */
|
||||||
|
public float buildSpeedMultiplier = 1f;
|
||||||
|
/** Unit weapon(s) disabled. */
|
||||||
|
public boolean disarm = false;
|
||||||
/** Damage per frame. */
|
/** Damage per frame. */
|
||||||
public float damage;
|
public float damage;
|
||||||
/** Chance of effect appearing. */
|
/** Chance of effect appearing. */
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
if(unit.controller() instanceof LogicAI){
|
if(unit.controller() instanceof LogicAI){
|
||||||
table.row();
|
table.row();
|
||||||
table.add(Blocks.microProcessor.emoji() + " " + Core.bundle.get("units.processorcontrol")).growX().left();
|
table.add(Blocks.microProcessor.emoji() + " " + Core.bundle.get("units.processorcontrol")).growX().wrap().left();
|
||||||
table.row();
|
table.row();
|
||||||
table.label(() -> Iconc.settings + " " + (long)unit.flag + "").color(Color.lightGray).growX().wrap().left();
|
table.label(() -> Iconc.settings + " " + (long)unit.flag + "").color(Color.lightGray).growX().wrap().left();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -463,8 +463,10 @@ public class JoinDialog extends BaseDialog{
|
|||||||
net.reset();
|
net.reset();
|
||||||
Vars.netClient.beginConnecting();
|
Vars.netClient.beginConnecting();
|
||||||
net.connect(lastIp = ip, lastPort = port, () -> {
|
net.connect(lastIp = ip, lastPort = port, () -> {
|
||||||
hide();
|
if(net.client()){
|
||||||
add.hide();
|
hide();
|
||||||
|
add.hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -568,7 +570,7 @@ public class JoinDialog extends BaseDialog{
|
|||||||
if(isIpv6 && ip.lastIndexOf("]:") != -1 && ip.lastIndexOf("]:") != ip.length() - 1){
|
if(isIpv6 && ip.lastIndexOf("]:") != -1 && ip.lastIndexOf("]:") != ip.length() - 1){
|
||||||
int idx = ip.indexOf("]:");
|
int idx = ip.indexOf("]:");
|
||||||
this.ip = ip.substring(1, idx);
|
this.ip = ip.substring(1, idx);
|
||||||
this.port = Integer.parseInt(ip.substring(idx + 2, ip.length()));
|
this.port = Integer.parseInt(ip.substring(idx + 2));
|
||||||
}else if(!isIpv6 && ip.lastIndexOf(':') != -1 && ip.lastIndexOf(':') != ip.length() - 1){
|
}else if(!isIpv6 && ip.lastIndexOf(':') != -1 && ip.lastIndexOf(':') != ip.length() - 1){
|
||||||
int idx = ip.lastIndexOf(':');
|
int idx = ip.lastIndexOf(':');
|
||||||
this.ip = ip.substring(0, idx);
|
this.ip = ip.substring(0, idx);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class LoadoutDialog extends BaseDialog{
|
|||||||
|
|
||||||
public void maxItems() {
|
public void maxItems() {
|
||||||
for(ItemStack stack : stacks){
|
for(ItemStack stack : stacks){
|
||||||
stack.amount = total == null ? capacity : Math.min(capacity, total.get(stack.item));
|
stack.amount = total == null ? capacity : Math.max(Math.min(capacity, total.get(stack.item)), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,11 +106,6 @@ public class ModsDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
shown(() -> Core.app.post(() -> {
|
|
||||||
Core.settings.getBoolOnce("modsalpha", () -> {
|
|
||||||
ui.showText("@mods", "@mods.alphainfo");
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void modError(Throwable error){
|
void modError(Throwable error){
|
||||||
@@ -283,6 +278,9 @@ public class ModsDialog extends BaseDialog{
|
|||||||
}else if(mod.hasContentErrors()){
|
}else if(mod.hasContentErrors()){
|
||||||
text.labelWrap("@mod.erroredcontent").growX();
|
text.labelWrap("@mod.erroredcontent").growX();
|
||||||
text.row();
|
text.row();
|
||||||
|
}else if(mod.meta.hidden){
|
||||||
|
text.labelWrap("@mod.multiplayer.compatible").growX();
|
||||||
|
text.row();
|
||||||
}
|
}
|
||||||
}).top().growX();
|
}).top().growX();
|
||||||
|
|
||||||
@@ -309,7 +307,7 @@ public class ModsDialog extends BaseDialog{
|
|||||||
|
|
||||||
if(steam && !mod.hasSteamID()){
|
if(steam && !mod.hasSteamID()){
|
||||||
right.row();
|
right.row();
|
||||||
right.button(Icon.download, Styles.clearTransi, () -> {
|
right.button(Icon.export, Styles.clearTransi, () -> {
|
||||||
platform.publish(mod);
|
platform.publish(mod);
|
||||||
}).size(50f);
|
}).size(50f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -327,6 +327,12 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
game.checkPref("buildautopause", false);
|
game.checkPref("buildautopause", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game.checkPref("doubletapmine", false);
|
||||||
|
|
||||||
|
if(!ios){
|
||||||
|
game.checkPref("modcrashdisable", true);
|
||||||
|
}
|
||||||
|
|
||||||
if(steam){
|
if(steam){
|
||||||
game.sliderPref("playerlimit", 16, 2, 32, i -> {
|
game.sliderPref("playerlimit", 16, 2, 32, i -> {
|
||||||
platform.updateLobby();
|
platform.updateLobby();
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ public class TraceDialog extends BaseDialog{
|
|||||||
table.row();
|
table.row();
|
||||||
table.add(Core.bundle.format("trace.mobile", info.mobile));
|
table.add(Core.bundle.format("trace.mobile", info.mobile));
|
||||||
table.row();
|
table.row();
|
||||||
|
table.add(Core.bundle.format("trace.times.joined", info.timesJoined));
|
||||||
|
table.row();
|
||||||
|
table.add(Core.bundle.format("trace.times.kicked", info.timesKicked));
|
||||||
|
table.row();
|
||||||
|
|
||||||
table.add().pad(5);
|
table.add().pad(5);
|
||||||
table.row();
|
table.row();
|
||||||
|
|||||||
@@ -642,6 +642,9 @@ public class HudFragment extends Fragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void drawInner(Color color, float fract){
|
void drawInner(Color color, float fract){
|
||||||
|
if(fract < 0) return;
|
||||||
|
|
||||||
|
fract = Mathf.clamp(fract);
|
||||||
if(flip){
|
if(flip){
|
||||||
x += width;
|
x += width;
|
||||||
width = -width;
|
width = -width;
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ public class MenuFragment extends Fragment{
|
|||||||
new Buttoni("@customgame", Icon.terrain, () -> checkPlay(ui.custom::show)),
|
new Buttoni("@customgame", Icon.terrain, () -> checkPlay(ui.custom::show)),
|
||||||
new Buttoni("@loadgame", Icon.download, () -> checkPlay(ui.load::show))
|
new Buttoni("@loadgame", Icon.download, () -> checkPlay(ui.load::show))
|
||||||
),
|
),
|
||||||
new Buttoni("@editor", Icon.terrain, () -> checkPlay(ui.maps::show)), steam ? new Buttoni("@workshop", Icon.book, platform::openWorkshop) : null,
|
new Buttoni("@editor", Icon.terrain, () -> checkPlay(ui.maps::show)), steam ? new Buttoni("@workshop", Icon.steam, platform::openWorkshop) : null,
|
||||||
new Buttoni("@mods", Icon.book, ui.mods::show),
|
new Buttoni("@mods", Icon.book, ui.mods::show),
|
||||||
//not enough space for this button
|
//not enough space for this button
|
||||||
//new Buttoni("@schematics", Icon.paste, ui.schematics::show),
|
//new Buttoni("@schematics", Icon.paste, ui.schematics::show),
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import mindustry.graphics.MultiPacker.*;
|
|||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
|
import mindustry.world.blocks.power.*;
|
||||||
import mindustry.world.consumers.*;
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
import mindustry.world.meta.values.*;
|
import mindustry.world.meta.values.*;
|
||||||
@@ -122,6 +123,8 @@ public class Block extends UnlockableContent{
|
|||||||
public boolean fillsTile = true;
|
public boolean fillsTile = true;
|
||||||
/** whether this block can be replaced in all cases */
|
/** whether this block can be replaced in all cases */
|
||||||
public boolean alwaysReplace = false;
|
public boolean alwaysReplace = false;
|
||||||
|
/** if false, this block can never be replaced. */
|
||||||
|
public boolean replaceable = true;
|
||||||
/** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */
|
/** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */
|
||||||
public BlockGroup group = BlockGroup.none;
|
public BlockGroup group = BlockGroup.none;
|
||||||
/** List of block flags. Used for AI indexing. */
|
/** List of block flags. Used for AI indexing. */
|
||||||
@@ -255,6 +258,26 @@ public class Block extends UnlockableContent{
|
|||||||
|
|
||||||
/** Drawn when you are placing a block. */
|
/** Drawn when you are placing a block. */
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
|
drawPotentialLinks(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPotentialLinks(int x, int y){
|
||||||
|
if((consumesPower || outputsPower) && hasPower){
|
||||||
|
Tile tile = world.tile(x, y);
|
||||||
|
if(tile != null){
|
||||||
|
PowerNode.getNodeLinks(tile, this, player.team(), other -> {
|
||||||
|
PowerNode node = (PowerNode)other.block;
|
||||||
|
Draw.color(node.laserColor1, Renderer.laserOpacity * 0.5f);
|
||||||
|
node.drawLaser(tile.team(), x * tilesize + offset, y * tilesize + offset, other.x, other.y, size, other.block.size);
|
||||||
|
|
||||||
|
Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place);
|
||||||
|
|
||||||
|
PowerNode.insulators(other.tileX(), other.tileY(), tile.x, tile.y, cause -> {
|
||||||
|
Drawf.square(cause.x, cause.y, cause.block.size * tilesize / 2f + 2f, Pal.plastanium);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float drawPlaceText(String text, int x, int y, boolean valid){
|
public float drawPlaceText(String text, int x, int y, boolean valid){
|
||||||
@@ -335,7 +358,11 @@ public class Block extends UnlockableContent{
|
|||||||
super.setStats();
|
super.setStats();
|
||||||
|
|
||||||
stats.add(Stat.size, "@x@", size, size);
|
stats.add(Stat.size, "@x@", size, size);
|
||||||
stats.add(Stat.health, health, StatUnit.none);
|
|
||||||
|
if(synthetic()){
|
||||||
|
stats.add(Stat.health, health, StatUnit.none);
|
||||||
|
}
|
||||||
|
|
||||||
if(canBeBuilt()){
|
if(canBeBuilt()){
|
||||||
stats.add(Stat.buildTime, buildCost / 60, StatUnit.seconds);
|
stats.add(Stat.buildTime, buildCost / 60, StatUnit.seconds);
|
||||||
stats.add(Stat.buildCost, new ItemListValue(false, requirements));
|
stats.add(Stat.buildCost, new ItemListValue(false, requirements));
|
||||||
@@ -385,7 +412,7 @@ public class Block extends UnlockableContent{
|
|||||||
|
|
||||||
public boolean canReplace(Block other){
|
public boolean canReplace(Block other){
|
||||||
if(other.alwaysReplace) return true;
|
if(other.alwaysReplace) return true;
|
||||||
return (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group &&
|
return other.replaceable && (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group &&
|
||||||
(size == other.size || (size >= other.size && ((subclass != null && subclass == other.subclass) || group.anyReplace)));
|
(size == other.size || (size >= other.size && ((subclass != null && subclass == other.subclass) || group.anyReplace)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,6 +426,11 @@ public class Block extends UnlockableContent{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Mutates the given list of requests used during line placement. */
|
||||||
|
public void handlePlacementLine(Seq<BuildPlan> plans){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public Object nextConfig(){
|
public Object nextConfig(){
|
||||||
if(saveConfig && lastConfig != null){
|
if(saveConfig && lastConfig != null){
|
||||||
return lastConfig;
|
return lastConfig;
|
||||||
@@ -595,6 +627,14 @@ public class Block extends UnlockableContent{
|
|||||||
return cacheLayer == CacheLayer.walls;
|
return cacheLayer == CacheLayer.walls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setupRequirements(Category cat, ItemStack[] stacks){
|
||||||
|
requirements(cat, stacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setupRequirements(Category cat, BuildVisibility visible, ItemStack[] stacks){
|
||||||
|
requirements(cat, visible, stacks);
|
||||||
|
}
|
||||||
|
|
||||||
public void requirements(Category cat, ItemStack[] stacks, boolean unlocked){
|
public void requirements(Category cat, ItemStack[] stacks, boolean unlocked){
|
||||||
requirements(cat, BuildVisibility.shown, stacks);
|
requirements(cat, BuildVisibility.shown, stacks);
|
||||||
this.alwaysUnlocked = unlocked;
|
this.alwaysUnlocked = unlocked;
|
||||||
|
|||||||
@@ -491,6 +491,11 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
return block.solid && block.fillsTile && !block.synthetic() ? data : 0;
|
return block.solid && block.fillsTile && !block.synthetic() ? data : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return true if these tiles are right next to each other. */
|
||||||
|
public boolean adjacentTo(Tile tile){
|
||||||
|
return relativeTo(tile) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
protected void preChanged(){
|
protected void preChanged(){
|
||||||
if(build != null){
|
if(build != null){
|
||||||
//only call removed() for the center block - this only gets called once.
|
//only call removed() for the center block - this only gets called once.
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public class ConstructBlock extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor getCursor(){
|
public Cursor getCursor(){
|
||||||
return SystemCursor.hand;
|
return interactable(player.team()) ? SystemCursor.hand : SystemCursor.arrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class Accelerator extends Block{
|
|||||||
public @Load("launch-arrow") TextureRegion arrowRegion;
|
public @Load("launch-arrow") TextureRegion arrowRegion;
|
||||||
|
|
||||||
public Block launching = Blocks.coreNucleus;
|
public Block launching = Blocks.coreNucleus;
|
||||||
public int[] capacities;
|
public int[] capacities = {};
|
||||||
|
|
||||||
public Accelerator(String name){
|
public Accelerator(String name){
|
||||||
super(name);
|
super(name);
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public class Door extends Wall{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor getCursor(){
|
public Cursor getCursor(){
|
||||||
return SystemCursor.hand;
|
return interactable(player.team()) ? SystemCursor.hand : SystemCursor.arrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -54,7 +54,11 @@ public class MendProjector extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.accent);
|
super.drawPlace(x, y, rotation, valid);
|
||||||
|
|
||||||
|
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, baseColor);
|
||||||
|
|
||||||
|
indexer.eachBlock(player.team(), x * tilesize + offset, y * tilesize + offset, range, other -> true, other -> Drawf.selected(other, Tmp.c1.set(baseColor).a(Mathf.absin(4f, 1f))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MendBuild extends Building implements Ranged{
|
public class MendBuild extends Building implements Ranged{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import arc.*;
|
|||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
@@ -47,7 +48,11 @@ public class OverdriveProjector extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.accent);
|
super.drawPlace(x, y, rotation, valid);
|
||||||
|
|
||||||
|
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, baseColor);
|
||||||
|
|
||||||
|
indexer.eachBlock(player.team(), x * tilesize + offset, y * tilesize + offset, range, other -> other.block.canOverdrive, other -> Drawf.selected(other, Tmp.c1.set(baseColor).a(Mathf.absin(4f, 1f))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,7 +137,14 @@ public class OverdriveProjector extends Block{
|
|||||||
Draw.rect(topRegion, x, y);
|
Draw.rect(topRegion, x, y);
|
||||||
Draw.alpha(1f);
|
Draw.alpha(1f);
|
||||||
Lines.stroke((2f * f + 0.1f) * heat);
|
Lines.stroke((2f * f + 0.1f) * heat);
|
||||||
Lines.square(x, y, Math.min(1f + (1f - f) * size * tilesize / 2f, size * tilesize/2f));
|
|
||||||
|
float r = Math.max(0f, Mathf.clamp(2f - f * 2f) * size * tilesize / 2f - f - 0.2f), w = Mathf.clamp(0.5f - f) * size * tilesize;
|
||||||
|
Lines.beginLine();
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
Lines.linePoint(x + Geometry.d4(i).x * r + Geometry.d4(i).y * w, y + Geometry.d4(i).y * r - Geometry.d4(i).x * w);
|
||||||
|
if(f < 0.5f) Lines.linePoint(x + Geometry.d4(i).x * r - Geometry.d4(i).y * w, y + Geometry.d4(i).y * r + Geometry.d4(i).x * w);
|
||||||
|
}
|
||||||
|
Lines.endLine(true);
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.world.blocks.defense.turrets;
|
package mindustry.world.blocks.defense.turrets;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -27,6 +28,9 @@ public class BaseTurret extends Block{
|
|||||||
update = true;
|
update = true;
|
||||||
solid = true;
|
solid = true;
|
||||||
outlineIcon = true;
|
outlineIcon = true;
|
||||||
|
priority = TargetPriority.turret;
|
||||||
|
group = BlockGroup.turrets;
|
||||||
|
flags = EnumSet.of(BlockFlag.turret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -41,6 +45,8 @@ public class BaseTurret extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
|
super.drawPlace(x, y, rotation, valid);
|
||||||
|
|
||||||
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.placing);
|
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.placing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,12 +93,6 @@ public class Turret extends ReloadTurret{
|
|||||||
|
|
||||||
public Turret(String name){
|
public Turret(String name){
|
||||||
super(name);
|
super(name);
|
||||||
priority = TargetPriority.turret;
|
|
||||||
update = true;
|
|
||||||
solid = true;
|
|
||||||
group = BlockGroup.turrets;
|
|
||||||
flags = EnumSet.of(BlockFlag.turret);
|
|
||||||
outlineIcon = true;
|
|
||||||
liquidCapacity = 20f;
|
liquidCapacity = 20f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.input.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -71,6 +72,17 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
&& lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
|
&& lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//stack conveyors should be bridged over, not replaced
|
||||||
|
@Override
|
||||||
|
public boolean canReplace(Block other){
|
||||||
|
return super.canReplace(other) && !(other instanceof StackConveyor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlePlacementLine(Seq<BuildPlan> plans){
|
||||||
|
Placement.calculateBridges(plans, (ItemBridge)Blocks.itemBridge);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureRegion[] icons(){
|
public TextureRegion[] icons(){
|
||||||
return new TextureRegion[]{regions[0][0]};
|
return new TextureRegion[]{regions[0][0]};
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package mindustry.world.blocks.distribution;
|
package mindustry.world.blocks.distribution;
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
@@ -32,10 +31,7 @@ public class ItemBridge extends Block{
|
|||||||
public @Load("@-arrow") TextureRegion arrowRegion;
|
public @Load("@-arrow") TextureRegion arrowRegion;
|
||||||
|
|
||||||
//for autolink
|
//for autolink
|
||||||
@Nullable
|
public @Nullable ItemBridgeBuild lastBuild;
|
||||||
public ItemBridgeBuild lastBuild;
|
|
||||||
@Nullable
|
|
||||||
public BuildPlan lastPlan;
|
|
||||||
|
|
||||||
public ItemBridge(String name){
|
public ItemBridge(String name){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -94,6 +90,8 @@ public class ItemBridge extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
|
super.drawPlace(x, y, rotation, valid);
|
||||||
|
|
||||||
Tile link = findLink(x, y);
|
Tile link = findLink(x, y);
|
||||||
|
|
||||||
Lines.stroke(2f, Pal.placing);
|
Lines.stroke(2f, Pal.placing);
|
||||||
@@ -151,12 +149,14 @@ public class ItemBridge extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNewPlan(BuildPlan plan){
|
public void handlePlacementLine(Seq<BuildPlan> plans){
|
||||||
if(lastPlan != null && lastPlan.config == null && positionsValid(lastPlan.x, lastPlan.y, plan.x, plan.y)){
|
for(int i = 0; i < plans.size - 1; i++){
|
||||||
lastPlan.config = new Point2(plan.x - lastPlan.x, plan.y - lastPlan.y);
|
var cur = plans.get(i);
|
||||||
|
var next = plans.get(i + 1);
|
||||||
|
if(positionsValid(cur.x, cur.y, next.x, next.y)){
|
||||||
|
cur.config = new Point2(next.x - cur.x, next.y - cur.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastPlan = plan;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -176,11 +176,11 @@ public class ItemBridge extends Block{
|
|||||||
public void playerPlaced(Object config){
|
public void playerPlaced(Object config){
|
||||||
super.playerPlaced(config);
|
super.playerPlaced(config);
|
||||||
|
|
||||||
if(config != null) return;
|
if(config == null){
|
||||||
|
Tile link = findLink(tile.x, tile.y);
|
||||||
Tile link = findLink(tile.x, tile.y);
|
if(linkValid(tile, link) && !proximity.contains(link.build)){
|
||||||
if(linkValid(tile, link) && !proximity.contains(link.build)){
|
link.build.configure(tile.pos());
|
||||||
link.build.configure(tile.pos());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastBuild = this;
|
lastBuild = this;
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ public class MassDriver extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
|
super.drawPlace(x, y, rotation, valid);
|
||||||
|
|
||||||
Drawf.dashCircle(x * tilesize, y * tilesize, range, Pal.accent);
|
Drawf.dashCircle(x * tilesize, y * tilesize, range, Pal.accent);
|
||||||
|
|
||||||
//check if a mass driver is selected while placing this driver
|
//check if a mass driver is selected while placing this driver
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package mindustry.world.blocks.environment;
|
package mindustry.world.blocks.environment;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
//do not use in mods!
|
/**
|
||||||
|
* Do not use in mods. This class provides no new functionality, and is only used for the Mindustry sprite generator.
|
||||||
|
* Use the standard Floor class instead.
|
||||||
|
* */
|
||||||
public class ShallowLiquid extends Floor{
|
public class ShallowLiquid extends Floor{
|
||||||
public Floor liquidBase, floorBase;
|
public @Nullable Floor liquidBase, floorBase;
|
||||||
public float liquidOpacity = 0.35f;
|
public float liquidOpacity = 0.35f;
|
||||||
|
|
||||||
public ShallowLiquid(String name){
|
public ShallowLiquid(String name){
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class BlockForge extends PayloadAcceptor{
|
|||||||
consume();
|
consume();
|
||||||
payload = new BuildPayload(recipe, team);
|
payload = new BuildPayload(recipe, team);
|
||||||
payVector.setZero();
|
payVector.setZero();
|
||||||
progress = 0f;
|
progress %= 1f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.input.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
@@ -69,6 +70,11 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
return otherblock.hasLiquids && (otherblock.outputsLiquid || (lookingAt(tile, rotation, otherx, othery, otherblock))) && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
|
return otherblock.hasLiquids && (otherblock.outputsLiquid || (lookingAt(tile, rotation, otherx, othery, otherblock))) && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlePlacementLine(Seq<BuildPlan> plans){
|
||||||
|
Placement.calculateBridges(plans, (ItemBridge)Blocks.bridgeConduit);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureRegion[] icons(){
|
public TextureRegion[] icons(){
|
||||||
return new TextureRegion[]{Core.atlas.find("conduit-bottom"), topRegions[0]};
|
return new TextureRegion[]{Core.atlas.find("conduit-bottom"), topRegions[0]};
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public class LogicBlock extends Block{
|
|||||||
solid = true;
|
solid = true;
|
||||||
configurable = true;
|
configurable = true;
|
||||||
group = BlockGroup.logic;
|
group = BlockGroup.logic;
|
||||||
|
schematicPriority = 5;
|
||||||
|
|
||||||
config(byte[].class, (LogicBuild build, byte[] data) -> build.readCompressed(data, true));
|
config(byte[].class, (LogicBuild build, byte[] data) -> build.readCompressed(data, true));
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ public class UnitPayload implements Payload{
|
|||||||
public void draw(){
|
public void draw(){
|
||||||
Drawf.shadow(unit.x, unit.y, 20);
|
Drawf.shadow(unit.x, unit.y, 20);
|
||||||
Draw.rect(unit.type.icon(Cicon.full), unit.x, unit.y, unit.rotation - 90);
|
Draw.rect(unit.type.icon(Cicon.full), unit.x, unit.y, unit.rotation - 90);
|
||||||
|
unit.type.drawCell(unit);
|
||||||
|
|
||||||
//draw warning
|
//draw warning
|
||||||
if(deactiveTime > 0){
|
if(deactiveTime > 0){
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ public class ImpactReactor extends PowerGenerator{
|
|||||||
|
|
||||||
public float warmupSpeed = 0.001f;
|
public float warmupSpeed = 0.001f;
|
||||||
public float itemDuration = 60f;
|
public float itemDuration = 60f;
|
||||||
public int explosionRadius = 50;
|
public int explosionRadius = 23;
|
||||||
public int explosionDamage = 2000;
|
public int explosionDamage = 1900;
|
||||||
|
|
||||||
public Color plasma1 = Color.valueOf("ffd06b"), plasma2 = Color.valueOf("ff361b");
|
public Color plasma1 = Color.valueOf("ffd06b"), plasma2 = Color.valueOf("ff361b");
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,17 @@ public class NuclearReactor extends PowerGenerator{
|
|||||||
public Color lightColor = Color.valueOf("7f19ea");
|
public Color lightColor = Color.valueOf("7f19ea");
|
||||||
public Color coolColor = new Color(1, 1, 1, 0f);
|
public Color coolColor = new Color(1, 1, 1, 0f);
|
||||||
public Color hotColor = Color.valueOf("ff9575a3");
|
public Color hotColor = Color.valueOf("ff9575a3");
|
||||||
public float itemDuration = 120; //time to consume 1 fuel
|
/** ticks to consume 1 fuel */
|
||||||
public float heating = 0.01f; //heating per frame * fullness
|
public float itemDuration = 120;
|
||||||
public float smokeThreshold = 0.3f; //threshold at which block starts smoking
|
/** heating per frame * fullness */
|
||||||
public int explosionRadius = 20;
|
public float heating = 0.01f;
|
||||||
|
/** threshold at which block starts smoking */
|
||||||
|
public float smokeThreshold = 0.3f;
|
||||||
|
/** heat threshold at which lights start flashing */
|
||||||
|
public float flashThreshold = 0.46f;
|
||||||
|
public int explosionRadius = 19;
|
||||||
public int explosionDamage = 1250;
|
public int explosionDamage = 1250;
|
||||||
public float flashThreshold = 0.46f; //heat threshold at which the lights start flashing
|
/** heat removed per unit of coolant */
|
||||||
public float coolantPower = 0.5f;
|
public float coolantPower = 0.5f;
|
||||||
|
|
||||||
public @Load("@-top") TextureRegion topRegion;
|
public @Load("@-top") TextureRegion topRegion;
|
||||||
@@ -49,6 +54,7 @@ public class NuclearReactor extends PowerGenerator{
|
|||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
rebuildable = false;
|
rebuildable = false;
|
||||||
flags = EnumSet.of(BlockFlag.reactor, BlockFlag.generator);
|
flags = EnumSet.of(BlockFlag.reactor, BlockFlag.generator);
|
||||||
|
schematicPriority = -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
protected static BuildPlan otherReq;
|
protected static BuildPlan otherReq;
|
||||||
|
|
||||||
protected final static ObjectSet<PowerGraph> graphs = new ObjectSet<>();
|
protected final static ObjectSet<PowerGraph> graphs = new ObjectSet<>();
|
||||||
protected final static Seq<Point2> tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>();
|
protected static int returnInt = 0;
|
||||||
|
|
||||||
public @Load("laser") TextureRegion laser;
|
public @Load("laser") TextureRegion laser;
|
||||||
public @Load("laser-end") TextureRegion laserEnd;
|
public @Load("laser-end") TextureRegion laserEnd;
|
||||||
@@ -144,6 +144,9 @@ public class PowerNode extends PowerBlock{
|
|||||||
Drawf.circles(x * tilesize + offset, y * tilesize + offset, laserRange * tilesize);
|
Drawf.circles(x * tilesize + offset, y * tilesize + offset, laserRange * tilesize);
|
||||||
|
|
||||||
getPotentialLinks(tile, other -> {
|
getPotentialLinks(tile, other -> {
|
||||||
|
Draw.color(laserColor1, Renderer.laserOpacity * 0.5f);
|
||||||
|
drawLaser(tile.team(), x * tilesize + offset, y * tilesize + offset, other.x, other.y, size, other.block.size);
|
||||||
|
|
||||||
Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place);
|
Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place);
|
||||||
|
|
||||||
insulators(tile.x, tile.y, other.tileX(), other.tileY(), cause -> {
|
insulators(tile.x, tile.y, other.tileX(), other.tileY(), cause -> {
|
||||||
@@ -164,7 +167,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
Draw.alpha(Renderer.laserOpacity);
|
Draw.alpha(Renderer.laserOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawLaser(Team team, float x1, float y1, float x2, float y2, int size1, int size2){
|
public void drawLaser(Team team, float x1, float y1, float x2, float y2, int size1, int size2){
|
||||||
float angle1 = Angles.angle(x1, y1, x2, y2),
|
float angle1 = Angles.angle(x1, y1, x2, y2),
|
||||||
vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1),
|
vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1),
|
||||||
len1 = size1 * tilesize / 2f - 1.5f, len2 = size2 * tilesize / 2f - 1.5f;
|
len1 = size1 * tilesize / 2f - 1.5f, len2 = size2 * tilesize / 2f - 1.5f;
|
||||||
@@ -172,6 +175,11 @@ public class PowerNode extends PowerBlock{
|
|||||||
Drawf.laser(team, laser, laserEnd, x1 + vx*len1, y1 + vy*len1, x2 - vx*len2, y2 - vy*len2, 0.25f);
|
Drawf.laser(team, laser, laserEnd, x1 + vx*len1, y1 + vy*len1, x2 - vx*len2, y2 - vy*len2, 0.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean overlaps(float srcx, float srcy, Tile other, Block otherBlock, float range){
|
||||||
|
return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), Tmp.r1.setCentered(other.worldx() + otherBlock.offset, other.worldy() + otherBlock.offset,
|
||||||
|
otherBlock.size * tilesize, otherBlock.size * tilesize));
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean overlaps(float srcx, float srcy, Tile other, float range){
|
protected boolean overlaps(float srcx, float srcy, Tile other, float range){
|
||||||
return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), other.getHitbox(Tmp.r1));
|
return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), other.getHitbox(Tmp.r1));
|
||||||
}
|
}
|
||||||
@@ -193,10 +201,23 @@ public class PowerNode extends PowerBlock{
|
|||||||
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.power != null &&
|
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.power != null &&
|
||||||
(other.block.outputsPower || other.block.consumesPower || other.block instanceof PowerNode) &&
|
(other.block.outputsPower || other.block.consumesPower || other.block instanceof PowerNode) &&
|
||||||
overlaps(tile.x * tilesize + offset, tile.y * tilesize + offset, other.tile(), laserRange * tilesize) && other.team == player.team()
|
overlaps(tile.x * tilesize + offset, tile.y * tilesize + offset, other.tile(), laserRange * tilesize) && other.team == player.team()
|
||||||
&& !other.proximity.contains(e -> e.tile == tile) && !graphs.contains(other.power.graph);
|
&& !graphs.contains(other.power.graph) &&
|
||||||
|
!Structs.contains(Edges.getEdges(size), p -> { //do not link to adjacent buildings
|
||||||
|
var t = world.tile(tile.x + p.x, tile.y + p.y);
|
||||||
|
return t != null && t.build == other;
|
||||||
|
});
|
||||||
|
|
||||||
tempTileEnts.clear();
|
tempTileEnts.clear();
|
||||||
graphs.clear();
|
graphs.clear();
|
||||||
|
|
||||||
|
//add conducting graphs to prevent double link
|
||||||
|
for(var p : Edges.getEdges(size)){
|
||||||
|
Tile other = tile.nearby(p);
|
||||||
|
if(other != null && other.team() == player.team() && other.build != null && other.build.power != null){
|
||||||
|
graphs.add(other.build.power.graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(tile.build != null && tile.build.power != null){
|
if(tile.build != null && tile.build.power != null){
|
||||||
graphs.add(tile.build.power.graph);
|
graphs.add(tile.build.power.graph);
|
||||||
}
|
}
|
||||||
@@ -214,6 +235,57 @@ public class PowerNode extends PowerBlock{
|
|||||||
return Float.compare(a.dst2(tile), b.dst2(tile));
|
return Float.compare(a.dst2(tile), b.dst2(tile));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
returnInt = 0;
|
||||||
|
|
||||||
|
tempTileEnts.each(valid, t -> {
|
||||||
|
if(returnInt ++ < maxNodes){
|
||||||
|
graphs.add(t.power.graph);
|
||||||
|
others.get(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO code duplication w/ method above?
|
||||||
|
/** Iterates through linked nodes of a block at a tile. All returned buildings are power nodes. */
|
||||||
|
public static void getNodeLinks(Tile tile, Block block, Team team, Cons<Building> others){
|
||||||
|
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.block instanceof PowerNode node &&
|
||||||
|
other.power.links.size < node.maxNodes &&
|
||||||
|
node.overlaps(other.x, other.y, tile, block, node.laserRange * tilesize) && other.team == team
|
||||||
|
&& !graphs.contains(other.power.graph) &&
|
||||||
|
!Structs.contains(Edges.getEdges(block.size), p -> { //do not link to adjacent buildings
|
||||||
|
var t = world.tile(tile.x + p.x, tile.y + p.y);
|
||||||
|
return t != null && t.build == other;
|
||||||
|
});
|
||||||
|
|
||||||
|
tempTileEnts.clear();
|
||||||
|
graphs.clear();
|
||||||
|
|
||||||
|
//add conducting graphs to prevent double link
|
||||||
|
for(var p : Edges.getEdges(block.size)){
|
||||||
|
Tile other = tile.nearby(p);
|
||||||
|
if(other != null && other.team() == team && other.build != null && other.build.power != null
|
||||||
|
&& !(block.consumesPower && other.block().consumesPower && !block.outputsPower && !other.block().outputsPower)){
|
||||||
|
graphs.add(other.build.power.graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tile.build != null && tile.build.power != null){
|
||||||
|
graphs.add(tile.build.power.graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
Geometry.circle(tile.x, tile.y, 13, (x, y) -> {
|
||||||
|
Building other = world.build(x, y);
|
||||||
|
if(valid.get(other) && !tempTileEnts.contains(other)){
|
||||||
|
tempTileEnts.add(other);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tempTileEnts.sort((a, b) -> {
|
||||||
|
int type = -Boolean.compare(a.block instanceof PowerNode, b.block instanceof PowerNode);
|
||||||
|
if(type != 0) return type;
|
||||||
|
return Float.compare(a.dst2(tile), b.dst2(tile));
|
||||||
|
});
|
||||||
|
|
||||||
tempTileEnts.each(valid, t -> {
|
tempTileEnts.each(valid, t -> {
|
||||||
graphs.add(t.power.graph);
|
graphs.add(t.power.graph);
|
||||||
others.get(t);
|
others.get(t);
|
||||||
@@ -235,7 +307,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(otherReq == null || otherReq.block == null) return;
|
if(otherReq == null || otherReq.block == null) continue;
|
||||||
|
|
||||||
drawLaser(player == null ? Team.sharded : player.team(), req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), size, otherReq.block.size);
|
drawLaser(player == null ? Team.sharded : player.team(), req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), size, otherReq.block.size);
|
||||||
}
|
}
|
||||||
|
|||||||