Merge branch 'master' of https://github.com/Anuken/Mindustry into rendering-optimizations

This commit is contained in:
Anuken
2018-11-14 10:12:12 -05:00
41 changed files with 544 additions and 1120 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ allprojects {
appName = 'Mindustry' appName = 'Mindustry'
gdxVersion = '1.9.8' gdxVersion = '1.9.8'
roboVMVersion = '2.3.0' roboVMVersion = '2.3.0'
uCoreVersion = '8919cb7b6881d040fb720149779fcf58c1927893' uCoreVersion = '2385d794f2cd3db2fb25d320f2223fa2148c25a0'
getVersionString = { getVersionString = {
String buildVersion = getBuildVersion() String buildVersion = getBuildVersion()
+1 -1
View File
@@ -755,7 +755,7 @@ block.ghoul-factory.description = Produces heavy carpet bombers.
block.dagger-factory.description = Produces basic ground units. block.dagger-factory.description = Produces basic ground units.
block.titan-factory.description = Produces advanced, armored ground units. block.titan-factory.description = Produces advanced, armored ground units.
block.fortress-factory.description = Produces heavy artillery ground units. block.fortress-factory.description = Produces heavy artillery ground units.
block.revenant-factory.description = Produces heavy laser ground units. block.revenant-factory.description = Produces heavy laser air units.
block.repair-point.description = Continuously heals the closest damaged unit in its vicinity. block.repair-point.description = Continuously heals the closest damaged unit in its vicinity.
block.command-center.description = Allows changing friendly AI behavior. Currently, attack, retreat and patrol commands are supported. block.command-center.description = Allows changing friendly AI behavior. Currently, attack, retreat and patrol commands are supported.
block.conduit.description = Basic liquid transport block. Works like a conveyor, but with liquids. Best used with extractors, pumps or other conduits. block.conduit.description = Basic liquid transport block. Works like a conveyor, but with liquids. Best used with extractors, pumps or other conduits.
+30 -30
View File
@@ -452,7 +452,7 @@ liquid.oil.name = Petróleo
liquid.cryofluid.name = Criogénico liquid.cryofluid.name = Criogénico
mech.alpha-mech.name = Alpha mech.alpha-mech.name = Alpha
mech.alpha-mech.weapon = Repetidor Pesado mech.alpha-mech.weapon = Repetidor Pesado
mech.alpha-mech.ability = Drone Swarm mech.alpha-mech.ability = Enjambre de Drones
mech.alpha-mech.description = El mecanoide estándar. Tiene velocidad y daño decentes, puede crear hasta 3 drones para poder ofensivo incremenado. mech.alpha-mech.description = El mecanoide estándar. Tiene velocidad y daño decentes, puede crear hasta 3 drones para poder ofensivo incremenado.
mech.delta-mech.name = Delta mech.delta-mech.name = Delta
mech.delta-mech.weapon = Generador de arco mech.delta-mech.weapon = Generador de arco
@@ -463,7 +463,7 @@ mech.tau-mech.weapon = Láser de reestructuración
mech.tau-mech.ability = Repair Burst mech.tau-mech.ability = Repair Burst
mech.tau-mech.description = El mecanoide de soporte. Repara bloques aliados disparándolos. Puede extinguir el fuego y reparar aliados en un rango con su habilidad de reparación. mech.tau-mech.description = El mecanoide de soporte. Repara bloques aliados disparándolos. Puede extinguir el fuego y reparar aliados en un rango con su habilidad de reparación.
mech.omega-mech.name = Omega mech.omega-mech.name = Omega
mech.omega-mech.weapon = Swarm Missiles mech.omega-mech.weapon = Enjambre de misiles
mech.omega-mech.ability = Armored Configuration mech.omega-mech.ability = Armored Configuration
mech.omega-mech.description = Un mecanoide grande y bien armado, hecho para asaltos en primera línea. Su habilidad de armadura puede bloquear hasta el 90% del daño que recibe. mech.omega-mech.description = Un mecanoide grande y bien armado, hecho para asaltos en primera línea. Su habilidad de armadura puede bloquear hasta el 90% del daño que recibe.
mech.dart-ship.name = Dardo mech.dart-ship.name = Dardo
@@ -471,7 +471,7 @@ mech.dart-ship.weapon = Repetidor
mech.dart-ship.description = La nave normal. Bastante ligera y rápida, pero tiene poca capacidad ofensiva y baja velocidad minado. mech.dart-ship.description = La nave normal. Bastante ligera y rápida, pero tiene poca capacidad ofensiva y baja velocidad minado.
mech.javelin-ship.name = Jabalina mech.javelin-ship.name = Jabalina
mech.javelin-ship.description = Una nave de ataque y retirada. Aunque inicialmente lento, puede acelerar a altas velocidades y volar sobre puestos enemigos, causando gran daño con su habilidad de rayos y misiles. mech.javelin-ship.description = Una nave de ataque y retirada. Aunque inicialmente lento, puede acelerar a altas velocidades y volar sobre puestos enemigos, causando gran daño con su habilidad de rayos y misiles.
mech.javelin-ship.weapon = Burst Missiles mech.javelin-ship.weapon = Ráfaga de misiles
mech.javelin-ship.ability = Discharge Booster mech.javelin-ship.ability = Discharge Booster
mech.trident-ship.name = Tridente mech.trident-ship.name = Tridente
mech.trident-ship.description = Un bombardero pesado. Razonablemente bien equipado. mech.trident-ship.description = Un bombardero pesado. Razonablemente bien equipado.
@@ -495,23 +495,23 @@ text.liquid.heatcapacity = [LIGHT_GRAY]Capacidad Térmica: {0}
text.liquid.viscosity = [LIGHT_GRAY]Viscosidad: {0} text.liquid.viscosity = [LIGHT_GRAY]Viscosidad: {0}
text.liquid.temperature = [LIGHT_GRAY]Temperatura: {0} text.liquid.temperature = [LIGHT_GRAY]Temperatura: {0}
block.spawn.name = Punto de generación block.spawn.name = Punto de generación
block.core.name = núcleo block.core.name = Núcleo
block.metalfloor.name = Suelo de Metal block.metalfloor.name = Suelo de Metal
block.deepwater.name = aguas profundas block.deepwater.name = Aguas profundas
block.water.name = agua block.water.name = Agua
block.lava.name = lava block.lava.name = Lava
block.tar.name = Tar block.tar.name = Tar
block.blackstone.name = piedra negra block.blackstone.name = Piedra negra
block.stone.name = piedra block.stone.name = Piedra
block.dirt.name = tierra block.dirt.name = Tierra
block.sand.name = arena block.sand.name = Arena
block.ice.name = hielo block.ice.name = Hielo
block.snow.name = nieve block.snow.name = Nieve
block.grass.name = pasto block.grass.name = Pasto
block.shrub.name = arbusto block.shrub.name = Arbusto
block.rock.name = roca block.rock.name = Roca
block.blackrock.name = roca negra block.blackrock.name = Roca negra
block.icerock.name = roca de hielo block.icerock.name = Roca de hielo
block.copper-wall.name = Muro de cobre block.copper-wall.name = Muro de cobre
block.copper-wall-large.name = Muro de cobre grande block.copper-wall-large.name = Muro de cobre grande
block.dense-alloy-wall.name = Muro de aleación densa block.dense-alloy-wall.name = Muro de aleación densa
@@ -567,10 +567,10 @@ block.omega-mech-pad.name = Pad de mecanoide Omega
block.tau-mech-pad.name = Pad de mecanoide Tau block.tau-mech-pad.name = Pad de mecanoide Tau
block.conduit.name = Conducto block.conduit.name = Conducto
block.mechanical-pump.name = Bomba Mecánica block.mechanical-pump.name = Bomba Mecánica
block.itemsource.name = Objeto Fuente block.itemsource.name = Fuente de objetos
block.itemvoid.name = Objeto Vacío block.itemvoid.name = Vacío de objetos
block.liquidsource.name = Líquido Fuente block.liquidsource.name = Fuente de líquidos
block.powervoid.name = Energía Vacía block.powervoid.name = Vacío de energía
block.powerinfinite.name = Energía Infinita block.powerinfinite.name = Energía Infinita
block.unloader.name = Descargador block.unloader.name = Descargador
block.vault.name = Bóveda block.vault.name = Bóveda
@@ -599,7 +599,7 @@ block.repair-point.name = Punto de Reparación
block.pulse-conduit.name = Conducto de Pulso block.pulse-conduit.name = Conducto de Pulso
block.phase-conduit.name = Conducto de Fase block.phase-conduit.name = Conducto de Fase
block.liquid-router.name = Enrutador de Líquidos block.liquid-router.name = Enrutador de Líquidos
block.liquid-tank.name = Tanque de Líquido block.liquid-tank.name = Tanque de Líquidos
block.liquid-junction.name = Cruce de Líquidos block.liquid-junction.name = Cruce de Líquidos
block.bridge-conduit.name = Conducto Puente block.bridge-conduit.name = Conducto Puente
block.rotary-pump.name = Bomba Rotatoria block.rotary-pump.name = Bomba Rotatoria
@@ -620,15 +620,15 @@ block.overdrive-projector.name = Overdrive Projector
block.force-projector.name = Force Projector block.force-projector.name = Force Projector
block.arc.name = Arc block.arc.name = Arc
block.rtg-generator.name = Generador RTG block.rtg-generator.name = Generador RTG
block.spectre.name = Spectre block.spectre.name = Espectro
block.meltdown.name = Meltdown block.meltdown.name = Meltdown
block.container.name = Contenedor block.container.name = Contenedor
team.blue.name = azul team.blue.name = Azul
team.red.name = rojo team.red.name = Rojo
team.orange.name = naranja team.orange.name = Naranja
team.none.name = gris team.none.name = Gris
team.green.name = verde team.green.name = Verde
team.purple.name = púrpura team.purple.name = Púrpura
unit.alpha-drone.name = Dron Alpha unit.alpha-drone.name = Dron Alpha
unit.spirit.name = Dron Espíritu unit.spirit.name = Dron Espíritu
unit.spirit.description = El dron del comienzo. Aparece en el núcleo por defecto. Mina automáticamente minerales, recoge objetos y repara bloques. unit.spirit.description = El dron del comienzo. Aparece en el núcleo por defecto. Mina automáticamente minerales, recoge objetos y repara bloques.
+126 -126
View File
@@ -8,8 +8,8 @@ text.link.trello.description = Trello officiel pour les futurs ajouts .
text.link.itch.io.description = page itch.io avec le lien du téléchargement pour PC et la version web . text.link.itch.io.description = page itch.io avec le lien du téléchargement pour PC et la version web .
text.link.google-play.description = listing par le store google play text.link.google-play.description = listing par le store google play
text.link.wiki.description = wiki officiel de mindustry . text.link.wiki.description = wiki officiel de mindustry .
text.linkfail = Failed to open link!\nThe URL has been copied to your cliboard. text.linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copié avec succès.
text.editor.web = The web version does not support the editor!\nDownload the game to use it. text.editor.web = La version web ne possède pas l'éditeur !\nTéléchargez le jeu pour l'avoir.
text.web.unsupported = La version web ne supporte pas cette fonction ! Téléchargez le jeu pour l'utiliser. text.web.unsupported = La version web ne supporte pas cette fonction ! Téléchargez le jeu pour l'utiliser.
text.gameover = Partie terminée. text.gameover = Partie terminée.
text.gameover.pvp = L'équipe [accent] {0}[] a gagnée ! text.gameover.pvp = L'équipe [accent] {0}[] a gagnée !
@@ -64,7 +64,7 @@ text.mission.linknode = Reliez un transmetteur
text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0}
text.mission.mech = Équiper ce mécha[accent] {0}[] text.mission.mech = Équiper ce mécha[accent] {0}[]
text.mission.create = Créez[accent] {0}[] text.mission.create = Créez[accent] {0}[]
text.none = <none> text.none = <vide>
text.close = Fermer text.close = Fermer
text.quit = Quitter text.quit = Quitter
text.maps = Cartes text.maps = Cartes
@@ -262,13 +262,13 @@ text.editor = Éditeur
text.mapeditor = Éditeur de carte text.mapeditor = Éditeur de carte
text.donate = Faire un\ndon text.donate = Faire un\ndon
text.connectfail = [crimson]Échec de la connexion au serveur : [accent]{0} text.connectfail = [crimson]Échec de la connexion au serveur : [accent]{0}
text.error.unreachable = Server unreachable. text.error.unreachable = Server injoignable.
text.error.invalidaddress = Invalid address. text.error.invalidaddress = Adresse invalide.
text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! text.error.timedout = Délai de connexion dépassé!\nAssurez-vous que l'hôte a autorisé l'accès au port, et que l'adresse soit correcte!
text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! text.error.mismatch = Erreur de paquet:\nPossible différence de verison entre le client et le serveur .\nVérifiez que vous et l'hôte avez la plus récente version de Mindustry !
text.error.alreadyconnected = Already connected. text.error.alreadyconnected = Déjà connecté.
text.error.mapnotfound = Map file not found! text.error.mapnotfound = Fichier de la carte introuvable!
text.error.any = Unkown network error. text.error.any = Erreur réseau inconnue.
text.settings.language = Langage text.settings.language = Langage
text.settings.reset = Valeur par défaut. text.settings.reset = Valeur par défaut.
text.settings.rebind = Réatttribuer text.settings.rebind = Réatttribuer
@@ -417,7 +417,7 @@ content.unit.name = Unités
content.recipe.name = Blocs content.recipe.name = Blocs
content.mech.name = Méchas content.mech.name = Méchas
item.stone.name = Pierre item.stone.name = Pierre
item.stone.description = Un matériau brut commun. Peut-être séparé et raffiné en d'autres matériaux, ou fondus en lave. item.stone.description = Un matériau brut commun. Peut être séparé et raffiné en d'autres matériaux, ou fondu en lave.
item.copper.name = Cuivre item.copper.name = Cuivre
item.copper.description = Un matériau de construction utile.Utilisé intensivement dans tout les blocs. item.copper.description = Un matériau de construction utile.Utilisé intensivement dans tout les blocs.
item.lead.name = Plomb item.lead.name = Plomb
@@ -434,10 +434,10 @@ item.silicon.name = Silicone
item.silicon.description = Un matériau semi-conducteur extrêmement utile, avec des utilisations dans les panneaux solaires et beaucoup d'autre composants électroniques complexes. item.silicon.description = Un matériau semi-conducteur extrêmement utile, avec des utilisations dans les panneaux solaires et beaucoup d'autre composants électroniques complexes.
item.plastanium.name = Plastanium item.plastanium.name = Plastanium
item.plastanium.description = Un matériau léger et docile utilisé dans l'aviation avancée et dans les munitions à fragmentation. item.plastanium.description = Un matériau léger et docile utilisé dans l'aviation avancée et dans les munitions à fragmentation.
item.phase-fabric.name = Phase Fabric item.phase-fabric.name = Tissu phasé
item.phase-fabric.description = A near-weightless substance used in advanced electronics and self-repairing technology. item.phase-fabric.description = Une substance au poids quasiment inexistant utilisé pour l'électronique avancé et la technologie auto-réparatrice.
item.surge-alloy.name = alliage superchargé item.surge-alloy.name = alliage superchargé
item.surge-alloy.description = An advanced alloy with unique electrical properties. item.surge-alloy.description = Un alliage avancé avec des propriétés électriques avancées.
item.biomatter.name = Biomasse item.biomatter.name = Biomasse
item.biomatter.description = Un mélange de matières organiques; utilisé pour la transformation en huile ou en tant que carburant de base. item.biomatter.description = Un mélange de matières organiques; utilisé pour la transformation en huile ou en tant que carburant de base.
item.sand.name = Sable item.sand.name = Sable
@@ -500,7 +500,7 @@ block.metalfloor.name = Sol en métal
block.deepwater.name = eau profonde block.deepwater.name = eau profonde
block.water.name = eau block.water.name = eau
block.lava.name = lave block.lava.name = lave
block.tar.name = Tar block.tar.name = pétrole
block.blackstone.name = roche sombre block.blackstone.name = roche sombre
block.stone.name = roche block.stone.name = roche
block.dirt.name = terre block.dirt.name = terre
@@ -623,7 +623,7 @@ block.rtg-generator.name = G.T.R.
block.spectre.name = Spectre block.spectre.name = Spectre
block.meltdown.name = Meltdown block.meltdown.name = Meltdown
block.container.name = Conteneur block.container.name = Conteneur
block.core.description = The most important building in the game. block.core.description = Le batiment le plus important du jeu .
team.blue.name = bleu team.blue.name = bleu
team.red.name = rouge team.red.name = rouge
team.orange.name = orange team.orange.name = orange
@@ -668,113 +668,113 @@ tutorial.daggerfactory = Construire [accent]une usine de "Poignards" []est recom
tutorial.router = Les usines ont besoin de ressources pour fonctionner.\nCréez un routeur pour séparer les objets. tutorial.router = Les usines ont besoin de ressources pour fonctionner.\nCréez un routeur pour séparer les objets.
tutorial.dagger = Reliez des transmetteurs énergétiques à l'usine.\nUne fois que les conditions seront remplies , un mécha sera créé.\nConstruisez autant de foreuses, de générateurs et de tapis roulants que nécessaire. tutorial.dagger = Reliez des transmetteurs énergétiques à l'usine.\nUne fois que les conditions seront remplies , un mécha sera créé.\nConstruisez autant de foreuses, de générateurs et de tapis roulants que nécessaire.
tutorial.battle = [LIGHT_GRAY]L'Ennemi[] a révélé sa base .\nDétruisez la avec votre unité et des méchas "Poignard". tutorial.battle = [LIGHT_GRAY]L'Ennemi[] a révélé sa base .\nDétruisez la avec votre unité et des méchas "Poignard".
block.copper-wall.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves. block.copper-wall.description = Un bloc défensif à faible coût.\nUtile pour protéger la base et les tourelles dans les premières lors des premières vagues.
block.copper-wall-large.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.\nSpans multiple tiles. block.copper-wall-large.description = Un bloc défensif à faible coût.\nUtile pour protéger la base et les tourelles dans les premières lors des premières vagues.\nFait du 2 sur 2.
block.dense-alloy-wall.description = A standard defensive block.\nAdequate protection from enemies. block.dense-alloy-wall.description = Un bloc défensif standard .\nProcure une bonne protection contre les ennemis.
block.dense-alloy-wall-large.description = A standard defensive block.\nAdequate protection from enemies.\nSpans multiple tiles. block.dense-alloy-wall-large.description = Un bloc défensif standard .\nProcure une bonne protection contre les ennemis.\nFait du 2 sur 2.
block.thorium-wall.description = A strong defensive block.\nGood protection from enemies. block.thorium-wall.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les ennemis.
block.thorium-wall-large.description = A strong defensive block.\nGood protection from enemies.\nSpans multiple tiles. block.thorium-wall-large.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les ennemis.\nFait du 2 sur 2.
block.phase-wall.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful. block.phase-wall.description = Moins puissant qu'un mur en Thorium mais déviera les balles sauf si elles sont trop puissantes.
block.phase-wall-large.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.\nSpans multiple tiles. block.phase-wall-large.description = Moins puissant qu'un mur en Thorium mais déviera les balles sauf si elles sont trop puissantes.\nFait du 2 sur 2.
block.surge-wall.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker. 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-large.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.\nSpans multiple tiles. block.surge-wall-large.description = Le plus puissant bloc défensif .\nA une faible chance de créer des éclairs vers les ennemis .\nFait du 2 sur 2.
block.door.description = A small door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through. block.door.description = Une petite porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte les ennemis peuvent tirer et passer à travers.
block.door-large.description = A large door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.\nSpans multiple tiles. block.door-large.description = Une large porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte les ennemis peuvent tirer et passer à travers.\nFait du 2 sur 2.
block.mend-projector.description = Periodically heals buildings in its vicinity. block.mend-projector.description = Soigne périodiquement les batiments autour de lui.
block.overdrive-projector.description = Increases the speed of nearby buildings like drills and conveyors. block.overdrive-projector.description = Accélère les batiments autour de lui, notamment les foreuses et les convoyeurs.
block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage through bullets. block.force-projector.description = Crée un champ de force hexagonal autour de lui qui protège les batiments et les unités à l'intérieur de prendre des dégâts à cause des balles.
block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy. block.shock-mine.description = Blesse les ennemis qui marchent dessus. Quasiment invisble pour l'ennemi.
block.duo.description = A small, cheap turret. block.duo.description = une petite tourelle avec un coût faible .
block.arc.description = A small turret which shoots electricity in a random arc towards the enemy. block.arc.description = une petite tourelle tirant des arcs électrques vers les ennemis.
block.hail.description = A small artillery turret. block.hail.description = une petite tourelle d'artillerie.
block.lancer.description = A medium-sized turret which shoots charged electricity beams. block.lancer.description = une tourelle de taille moyenne tirant des rayons chargés en électricité.
block.wave.description = A medium-sized rapid-fire turret which shoots liquid bubbles. block.wave.description = une tourelle de taille moyenne tirant rapidement des bulles de liquide .
block.salvo.description = A medium-sized turret which fires shots in salvos. block.salvo.description = une tourelle de taille moyenne qui tire par salves.
block.swarmer.description = A medium-sized turret which shoots burst missiles. block.swarmer.description = une tourelle de taille moyenne qui tire des missiles qui se dispersent.
block.ripple.description = A large artillery turret which fires several shots simultaneously. block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs tirs simultanément.
block.cyclone.description = A large rapid fire turret. block.cyclone.description = Une grande tourelle tirant rapidement ... très rapidement .
block.fuse.description = A large turret which shoots powerful short-range beams. block.fuse.description = Une grande tourelle qui tire de puissants rayons lasers avec une faible portée.
block.spectre.description = A large turret which shoots two powerful bullets at once. block.spectre.description = Une grande tourelle qui tire deux puissantes balles simultanément.
block.meltdown.description = A large turret which shoots powerful long-range beams. block.meltdown.description = Une grande tourelle tirant de puissants rayons lasers avec une grande portée.
block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable. 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 batiments. Peut être tourné.
block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors. block.titanium-conveyor.description = Convoyeur avancé . Déplace les objets plus rapidement que les convoyeurs standards.
block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles. block.phase-conveyor.description = convoyeur très avancé . Utilise de l'énergie pour téléporter des objets à un convoyeur phasé connecté jusqu'à une longue distance .
block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations. block.junction.description = Agit comme un pont pour deux ligne de convoyeurs se croisant. Utile lorsque deux différents convoyeurs déplacent différents matériaux à différents endroits.
block.mass-driver.description = Ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range. block.mass-driver.description = Batiment de transport d'objet [accent]ultime[]. Collecte un grand nombre d'objets puis les tire à un autre transporteur de masse sur une très longue distance.
block.smelter.description = Burns coal for smelting copper and lead into dense alloy. block.smelter.description = Brûle du charbon pour fondre du cuivre et du plomb en un alliage lourd.
block.arc-smelter.description = Smelts copper and lead into dense alloy by using an external power source. block.arc-smelter.description = Fait fondre du cuivre et du plomb en un alliage lourd en utilisant une source d'énergie extérieure .
block.silicon-smelter.description = Reduces sand with highly pure coke in order to produce silicon. block.silicon-smelter.description = Utilise du sable, du charbon et de l'énergie afin de produire du silicone.
block.plastanium-compressor.description = Produces plastanium from oil and titanium. block.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane.
block.phase-weaver.description = Produces phase fabric from radioactive thorium and high amounts of sand. block.phase-weaver.description = Produit du tissu phasé à partir de thorium et de grandes quantités de sable.
block.alloy-smelter.description = Produces surge alloy from titanium, lead, silicon and copper. block.alloy-smelter.description = Produit un alliage superchargé à l'aide de titane de plomb de silicone et de cuivre.
block.pulverizer.description = Crushes stone into sand. Useful when there is a lack of natural sand. block.pulverizer.description = Écrase la pierre pour en faire du sable. Utile quand il y a un manque de sable naturel.
block.pyratite-mixer.description = Mixes coal, lead and sand into highly flammable pyratite. block.pyratite-mixer.description = Mélange charbon, plomb et sable en l'hautement inflammable pyratite.
block.blast-mixer.description = Uses oil for transforming pyratite into the less flammable but more explosive blast compound. block.blast-mixer.description = Utilise du pétrole pour transformer la pyratite en un mélange explosif moins inflammable mais plus explosif que la pyratite.
block.cryofluidmixer.description = Combines water and titanium into cryofluid which is much more efficient for cooling. block.cryofluidmixer.description = Combine de l'eau et du titane en un liquide cryogénique bien plus efficace pour refroidir.
block.solidifer.description = Cools lava to stone at a fast pace. block.solidifer.description = Refroidit de la lave en pierre très rapidement.
block.melter.description = Heats up stone to very high temperatures to obtain lava. block.melter.description = chauffe de la pierre à de très hautes températures pour obtenir de la lave.
block.incinerator.description = Gets rid of any excess item or liquid. block.incinerator.description = Permet de se débarasser de n'importe quel objet ou liquide en exces .
block.biomattercompressor.description = Compresses biomatter in order to retrieve oil. block.biomattercompressor.description = Compresse de la biomasse pour en récupérer le pétrole.
block.separator.description = Exposes stone to water pressure in order to obtain various minerals contained in the stone. block.separator.description = Expose la pierre à de l'eau sous pression afin d'obtenir différents minéraux contenus dansla pierre.
block.centrifuge.description = More efficient than the separator, but also more expensive to build and requires power. block.centrifuge.description = Plus efficace qu'un séparateur mais aussi plus cher à construire et demande plus d'énergie.
block.power-node.description = Transmits power to connected nodes. Up to four power sources, sinks or nodes can be connected. The node will receive power from or supply power to any adjacent blocks. block.power-node.description = Transmet l'énergie aux transmetteurs énergétiques connectés . Jusqu'à quatre sources d'énergie, consommateurs ou transmetteurs peuvent être connectés. Le transmetteur recevra de l'énergie ou le transmettra à n'importe quel batiment adjacent.
block.power-node-large.description = Has a larger radius than the power node and connects to up to six power sources, sinks or nodes. block.power-node-large.description = A un plus grand rayon que le transmetteur énergétique standard et jusqu'à six sources d'énergie, consommateurs ou transmetteurs peuvent être connectés.
block.battery.description = Stores power whenever there is an abundance and provides power whenever there is a shortage, as long as there is capacity left. block.battery.description = Stocke l'énergie quand elle est en abondance et le distribue si il y a trop peu d'énergie tant qu'il lui reste de l'énergie.
block.battery-large.description = Stores much more power than a regular battery. block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale.
block.combustion-generator.description = Generates power by burning oil or flammable materials. block.combustion-generator.description = Génère de l'énergie en brûlant du pétrole ou des matériaux inflammables.
block.turbine-generator.description = More efficient than a combustion generator, but requires additional water. block.turbine-generator.description = Plus efficace qu'un générateur à combustion, mais requiert de l'eau .
block.thermal-generator.description = Generates a large amount of power from lava. block.thermal-generator.description = Génère une grande quantité d'énergie à partir de lave .
block.solar-panel.description = Provides a small amount of power from the sun. block.solar-panel.description = Génère une faible quantité d'énergie .
block.solar-panel-large.description = Provides much better power supply than a standard solar panel, but is also much more expensive to build. block.solar-panel-large.description = Génère bien plus d'énergie qu'un panneau solaire standard, Mais est aussi bien plus cher à construire.
block.thorium-reactor.description = Generates huge amounts of power from highly radioactive thorium. Requires constant cooling. Will explode violently if insufficient amounts of coolant are supplied. block.thorium-reactor.description = Génère énormément d'énergie à l'aide de la radioactivité du thorium. Requiert néanmoins un refroidissement constant. Explosera violemment en cas de surchauffe.
block.rtg-generator.description = A radioisotope thermoelectric generator which does not require cooling but provides less power than a thorium reactor. block.rtg-generator.description = Un générateur thermolectrique à radioisotope qui ne demande pas de refroidissement mais produit moins d'énergie qu'un réacteur à Thorium.
block.unloader.description = Unloads items from a container, vault or core onto a conveyor or directly into an adjacent block. The type of item to be unloaded can be changed by tapping on the unloader. block.unloader.description = Décharge des objets depuis des conteneurs, coffres-forts ou de la base sur un convoyeur ou directement dans un bloc adjacent . Le type d'objet peut être changé en appuyant sur le déchargeur.
block.container.description = Stores a small amount of items. Use it for creating buffers when there is a non-constant demand of materials. An[LIGHT_GRAY] unloader[] can be used to retrieve items from the container. block.container.description = Stocke un petit nombre d'objet . Utile pour réguler le flux d'objet quand la demande de matériaux est inconstante.un [LIGHT_GRAY] déchargeur[] peut être utilisé pour récupérer des objets depuis le conteneur.
block.vault.description = Stores a large amount of items. Use it for creating buffers when there is a non-constant demand of materials. An[LIGHT_GRAY] unloader[] can be used to retrieve items from the vault. block.vault.description = Stocke un grand nombre d'objets. Utile pour réguler le flux d'objet quand la demande de matériaux est inconstante.un [LIGHT_GRAY] déchargeur[] peut être utilisé pour récupérer des objets depuis le coffre-fort.
block.mechanical-drill.description = A cheap drill. When placed on appropriate tiles, outputs items at a slow pace indefinitely. block.mechanical-drill.description = Une foreuse de faible coût. Si elle est placée sur à un endroit approprié, produit des matériaux lentement à l'infini.
block.pneumatic-drill.description = An improved drill which is faster and able to process harder materials by making use of air pressure. block.pneumatic-drill.description = Une foreuse amélioré plus rapide et capable de forer des matériaux plus dur grâce à l'usage de vérins à air comprimé.
block.laser-drill.description = Allows drilling even faster through laser technology, but requires power. Additionally, radioactive thorium can be retrieved with this drill. block.laser-drill.description = Permet de forer bien plus vite grâce à la technologie laser, cela demande néanmoins de l'énergie . Additionnellement, le thorium, un matériau radioactif, peut-être récupéré avec cette foreuse.
block.blast-drill.description = The ultimate drill. Requires large amounts of power. block.blast-drill.description = La Foreuse ultime . Demande une grande quantité d'énergie .
block.water-extractor.description = Extracts water from the ground. Use it when there is no lake nearby. block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'eau à proximité.
block.cultivator.description = Cultivates the soil with water in order to obtain biomatter. block.cultivator.description = Cultive le sol avec de l'eau afin d'obtenir de la biomasse.
block.oil-extractor.description = Uses large amounts of power in order to extract oil from sand. Use it when there is no direct source of oil nearby. block.oil-extractor.description = Utilise une grande quantité d'énergie afin d'extraire du pétrole du sable . Utile quand il n'y a pas de lacs de pétrole à proximité.
block.dart-ship-pad.description = Leave your current vessel and change into a basic fighter aircraft.\nUse the pad by double tapping while standing on it. block.dart-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un avion de combat basique .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
block.trident-ship-pad.description = Leave your current vessel and change into a reasonably well armored heavy bomber.\nUse the pad by double tapping while standing on it. block.trident-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un bombardier lourd raisonnablement cuirassé .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
block.javelin-ship-pad.description = Leave your current vessel and change into a strong and fast interceptor with lightning weapons.\nUse the pad by double tapping while standing on it. block.javelin-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un intercepteur rapide et puissant avec des armes électriques.\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
block.glaive-ship-pad.description = Leave your current vessel and change into a large, well-armored gunship.\nUse the pad by double tapping while standing on it. block.glaive-ship-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un large vaisseau cuirassé .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
block.tau-mech-pad.description = Leave your current vessel and change into a support mech which can heal friendly buildings and units.\nUse the pad by double tapping while standing on it. block.tau-mech-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un mécha de support qui peut soigner les batiments et unités alliées.\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
block.delta-mech-pad.description = Leave your current vessel and change into a fast, lightly-armored mech made for hit-and-run attacks.\nUse the pad by double tapping while standing on it. block.delta-mech-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un mécha rapide mais peu résistant fait pour les stratégies de harcèlement.\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
block.omega-mech-pad.description = Leave your current vessel and change into a bulky and well-armored mech, made for front-line assaults.\nUse the pad by double tapping while standing on it. block.omega-mech-pad.description = Quitte ton mécha ou ton vaisseau actuel pour un mécha cuirassé et large, fait pour les assauts frontaux .\nUtilisez le reconstructeur en double cliquant dessus lorsque vous êtes dessus.
block.spirit-factory.description = Produces light drones which mine ore and repair blocks. block.spirit-factory.description = Produit des petits drones qui réparent les batiments et minent des matériaux.
block.phantom-factory.description = Produces advanced drone units which are significantly more effective than a spirit drone. block.phantom-factory.description = Produit des drones avancés qui sont bien plus efficaces que les drones spirituels.
block.wraith-factory.description = Produces fast, hit-and-run interceptor units. block.wraith-factory.description = Produit des intercepteurs rapides qui harcèlent l'ennemi.
block.ghoul-factory.description = Produces heavy carpet bombers. block.ghoul-factory.description = Produit des bombardiers lourds.
block.dagger-factory.description = Produces basic ground units. block.dagger-factory.description = Produit des unités terrestres basiques.
block.titan-factory.description = Produces advanced, armored ground units. block.titan-factory.description = Produit des unités terrestres avancées et cuirassées.
block.fortress-factory.description = Produces heavy artillery ground units. block.fortress-factory.description = Produit des unités terrestres d'artillerie lourde .
block.revenant-factory.description = Produces heavy laser ground units. block.revenant-factory.description = Produit des unités terrestres lourdes avec des lasers.
block.repair-point.description = Continuously heals the closest damaged unit in its vicinity. block.repair-point.description = Soigne en continu l'unité blessée la plus proche tant qu'elle est à sa portée.
block.command-center.description = Allows changing friendly AI behavior. Currently, attack, retreat and patrol commands are supported. block.command-center.description = Permet de changer le comportement des IA alliées. Pour le moment, l'attaque, la retraite et les patrouilles sont supportées.
block.conduit.description = Basic liquid transport block. Works like a conveyor, but with liquids. Best used with extractors, pumps or other conduits. block.conduit.description = tuyau basique permettant le transport de liquide . Marche comme un convoyeur mais avec les liquides. Utile si utilisé avec des extracteurs, des pompes ou d'autres conduits.
block.pulse-conduit.description = Advanced liquid transport block. Transports liquids faster and stores more than standard conduits. block.pulse-conduit.description = tuyau avancé permettant le transport de liquide . Transporte les liquides plus rapidement et en stocke plus que les tuyaux standards.
block.phase-conduit.description = Advanced liquid transport block. Uses power to teleport liquids to a connected phase conduit over several tiles. block.phase-conduit.description = tuyau très avancé permettant le transport de liquide. Utilise de l'énergie pour téléporter les liquides à un autre tuyau phasé sur une longue distance.
block.liquid-router.description = Accepts liquids from one direction and outputs them to up to 3 other directions equally. Can also store a certain amount of liquid. Useful for splitting the liquids from one source to multiple targets. block.liquid-router.description = Accepte les liquide en une direction et les rejete de tout les côtés équitablement. Peut aussi stocker une certaine quantité de liquide. Utile pour envoyer un liquide à plusieurs endroits.
block.liquid-tank.description = Stores a large amount of liquids. Use it for creating buffers when there is a non-constant demand of materials or as a safeguard for cooling vital blocks. block.liquid-tank.description = Stocke une grande quantité de liquides . Utile pour réguler la sortie quand la demande est inconstante ou comme sécurité pour refroidir des batiments important.
block.liquid-junction.description = Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations. block.liquid-junction.description = Agit comme une intersection pour deux conduits se croisant.Utile si deux conduits amènent différents liquides à différents endroits.
block.bridge-conduit.description = Advanced liquid transport block. Allows transporting liquids over up to 3 tiles of any terrain or building. block.bridge-conduit.description = bloc de transport de liquide avancé . Permet le transport de liquides jusqu'à 3 blocs de n'importe quel terrain ou batiment .
block.mechanical-pump.description = A cheap pump with slow output, but no power consumption. block.mechanical-pump.description = Une pompe de faible prix pompant lentement, mais ne consomme pas d'énergie.
block.rotary-pump.description = An advanced pump which doubles up speed by using power. block.rotary-pump.description = Une pompe avancée qui double sa vitesse en utilisant de l'énergie.
block.thermal-pump.description = The ultimate pump. Three times as fast as a mechanical pump and the only pump which is able to retrieve lava. block.thermal-pump.description = La pompe ultime . Trois fois plus rapide qu'une pompe mécanique et la seule pompe capable de récupérer de la lave.
block.router.description = Accepts items from one direction and outputs them to up to 3 other directions equally. Useful for splitting the materials from one source to multiple targets. block.router.description = Accepte les objets depuis une ou plus directions et le renvoie dans n'importe quelle direction. Utile pour séparer une chaîne de convoyeurs en plusieurs.[accent]Le seul et l'Unique[]
block.distributor.description = An advanced router which splits items to up to 7 other directions equally. block.distributor.description = Un routeur avancé qui sépare les objets jusqu'à 7 autres directions équitablement.
block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building. block.bridge-conveyor.description = bloc de transport avancé permettant de traverser jusqu'à 3 blocs de n'importe quel terrain ou batiment.
block.alpha-mech-pad.description = When given enough power, rebuilds your ship into the[accent] Alpha[] mech. block.alpha-mech-pad.description = Avec assez d'énergie, reconstruit votre vaisseau en un mécha [accent] Alpha[].
block.itemsource.description = Infinitely outputs items. Sandbox only. block.itemsource.description = Produit des objets à l'infini. Bac à sable uniquement .
block.liquidsource.description = Infinitely outputs liquids. Sandbox only. block.liquidsource.description = Source de liquide infinie . Bac à sable uniquement.
block.itemvoid.description = Destroys any items which go into it without using power. Sandbox only. block.itemvoid.description = Désintègre n'importe quel objet qui va à l'intérieur sans utiliser d'énergie. Bac à sable uniquement.
block.powerinfinite.description = Infinitely outputs power. Sandbox only. block.powerinfinite.description = Produit de l'énergie à l'infini. Bac à sable uniquement.
block.powervoid.description = Voids all power inputted into it. Sandbox only. block.powervoid.description = Supprime toute l'énergie allant à l'intérieur.Bac à sable uniquement
liquid.water.description = Commonly used for cooling machines and waste processing. liquid.water.description = Couramment utilisé pour le refroidissement et le traitement des déchets.
liquid.lava.description = Can be transformed into[LIGHT_GRAY] stone[], used for generating power or used as ammo for certain turrets. liquid.lava.description = Peut être transformé en [LIGHT_GRAY]pierre[], utilisé pour produire de l'énergie ou utilisé comme munition par certaines tourelles.
liquid.oil.description = Can be burnt, exploded or used as a coolant. liquid.oil.description = Peut être brûlé, utilisé comme explosif ou comme liquide de refroidissement.
liquid.cryofluid.description = The most efficient liquid for cooling things down. liquid.cryofluid.description = Le liquide de refroidissement le plus efficace.
+54 -53
View File
@@ -73,7 +73,7 @@ text.nextmission = Prochaine Mission
text.maps.none = [LIGHT_GRAY]Aucune carte trouvée! text.maps.none = [LIGHT_GRAY]Aucune carte trouvée!
text.about.button = À propos text.about.button = À propos
text.name = Nom: text.name = Nom:
text.filename = File Name: text.filename = Nom du fichier:
text.unlocked = Nouveau bloc debloqué! text.unlocked = Nouveau bloc debloqué!
text.unlocked.plural = Nouveaux blocs débloqués! text.unlocked.plural = Nouveaux blocs débloqués!
text.players = {0} joueurs en ligne text.players = {0} joueurs en ligne
@@ -262,13 +262,13 @@ text.editor = Éditeur
text.mapeditor = Éditeur de carte text.mapeditor = Éditeur de carte
text.donate = Faire un\ndon text.donate = Faire un\ndon
text.connectfail = [crimson]Échec de la connexion au serveur: [accent]{0} text.connectfail = [crimson]Échec de la connexion au serveur: [accent]{0}
text.error.unreachable = Server unreachable. text.error.unreachable = Serveur inaccessible.
text.error.invalidaddress = Invalid address. text.error.invalidaddress = Adresse invalide.
text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! text.error.timedout = Expiration du délai !\nAssurez-vous que la redirection de port est configurée sur l'hôte et que l'adresse est correcte !
text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! text.error.mismatch = Erreur de paquet:\nPossible d'incompatibilité de version client/serveur.\nAssurez-vous que l'hôte et vous disposez de la dernière version de Mindustry !
text.error.alreadyconnected = Already connected. text.error.alreadyconnected = Déjà connecté.
text.error.mapnotfound = Map file not found! text.error.mapnotfound = Fichier de carte introuvable !
text.error.any = Unkown network error. text.error.any = Erreur réseau inconnue.
text.settings.language = Langage text.settings.language = Langage
text.settings.reset = Valeur par défaut. text.settings.reset = Valeur par défaut.
text.settings.rebind = Réatttribuer text.settings.rebind = Réatttribuer
@@ -419,9 +419,9 @@ content.mech.name = Mécha
item.stone.name = Pierre item.stone.name = Pierre
item.stone.description = Un matériau brut commun. Peut-être séparé et raffiné en d'autres matériaux, ou fondus en lave. item.stone.description = Un matériau brut commun. Peut-être séparé et raffiné en d'autres matériaux, ou fondus en lave.
item.copper.name = Cuivre item.copper.name = Cuivre
item.copper.description = Un matériau de construction utile.Utilisé intensivement dans tout les blocs. item.copper.description = Un matériau de construction utile. Utilisé intensivement dans tout les blocs.
item.lead.name = Plomb item.lead.name = Plomb
item.lead.description = Un matériau de départ . Utilisé intensivement en électronique et pour le transport de blocs. item.lead.description = Un matériau de départ. Utilisé intensivement en électronique et pour le transport de blocs.
item.coal.name = Charbon item.coal.name = Charbon
item.coal.description = Un carburant commun et facile à obtenir. item.coal.description = Un carburant commun et facile à obtenir.
item.dense-alloy.name = Alliage lourd item.dense-alloy.name = Alliage lourd
@@ -623,7 +623,7 @@ block.rtg-generator.name = G.T.R.
block.spectre.name = Spectre block.spectre.name = Spectre
block.meltdown.name = Meltdown block.meltdown.name = Meltdown
block.container.name = Conteneur block.container.name = Conteneur
block.core.description = The most important building in the game. block.core.description = Sert de point de base pour le/les joueur(s). Ce bâtiment est le plus [SCARLET]important[] du jeu !
team.blue.name = Bleu team.blue.name = Bleu
team.red.name = Rouge team.red.name = Rouge
team.orange.name = Orange team.orange.name = Orange
@@ -632,7 +632,7 @@ team.green.name = Vert
team.purple.name = Violet team.purple.name = Violet
unit.alpha-drone.name = Drone alpha unit.alpha-drone.name = Drone alpha
unit.spirit.name = Drone spirituel unit.spirit.name = Drone spirituel
unit.spirit.description = TL'unité de soutien de départ. Apparaît dans la base par défaut. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs. unit.spirit.description = L'unité de soutien de départ. Apparaît dans la base par défaut. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs.
unit.phantom.name = Drone Fantôme unit.phantom.name = Drone Fantôme
unit.phantom.description = Une unité de soutien avancée. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs. Bien plus efficace qu'un drone spirituel. unit.phantom.description = Une unité de soutien avancée. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs. Bien plus efficace qu'un drone spirituel.
unit.dagger.name = Poignard unit.dagger.name = Poignard
@@ -667,47 +667,48 @@ tutorial.silicon = Du silicone est maintenant produit. Obtenez-en.\n\nAugmenter
tutorial.daggerfactory = Construire [accent]une usine de "Poignards" []est recommandé .\n\nElle sera utilisée pour produire des unités d'attaque. tutorial.daggerfactory = Construire [accent]une usine de "Poignards" []est recommandé .\n\nElle sera utilisée pour produire des unités d'attaque.
tutorial.router = Les usines ont besoin de ressources pour fonctionner.\nCréez un routeur pour séparer les objets. tutorial.router = Les usines ont besoin de ressources pour fonctionner.\nCréez un routeur pour séparer les objets.
tutorial.dagger = Reliez des transmetteurs énergétiques à l'usine.\nUne fois que les conditions seront remplies , un mécha sera créé.\nConstruisez autant de foreuses, de générateurs et de tapis roulants que nécessaire. tutorial.dagger = Reliez des transmetteurs énergétiques à l'usine.\nUne fois que les conditions seront remplies , un mécha sera créé.\nConstruisez autant de foreuses, de générateurs et de tapis roulants que nécessaire.
tutorial.battle = [LIGHT_GRAY]L'Ennemi[] a révélé sa base .\nDétruisez la avec votre unité et des méchas "Poignard". tutorial.battle = [LIGHT_GRAY]L'Ennemi[] a révélé sa base.\nDétruisez la avec votre unité et des méchas "Poignard".
block.copper-wall.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.
block.copper-wall-large.description = A cheap defensive block.\nUseful for protecting the core and turrets in the first few waves.\nSpans multiple tiles. block.copper-wall.description = Un bloc défensif bon marché.\nUtile pour protéger le noyau et les tourelles lors des premières vagues.
block.dense-alloy-wall.description = A standard defensive block.\nAdequate protection from enemies. block.copper-wall-large.description = Un bloc défensif bon marché.\nUtile pour protéger le noyau et les tourelles lors des premières vagues.\nS'étend sur plusieurs tuiles.
block.dense-alloy-wall-large.description = A standard defensive block.\nAdequate protection from enemies.\nSpans multiple tiles. block.dense-alloy-wall.description = Un bloc défensif standard.\nUne protection adéquate contre les ennemis.
block.thorium-wall.description = A strong defensive block.\nGood protection from enemies. block.dense-alloy-wall-large.description = Un bloc défensif standard.\nUne protection adéquate contre les ennemis.\nS'étend sur plusieurs tuiles.
block.thorium-wall-large.description = A strong defensive block.\nGood protection from enemies.\nSpans multiple tiles. block.thorium-wall.description = Un puissant bloc défensif.\nBonne protection contre les ennemis.
block.phase-wall.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful. block.thorium-wall-large.description = Un puissant bloc défensif.\nBonne protection contre les ennemis.\nS'étend sur plusieurs tuiles.
block.phase-wall-large.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful.\nSpans multiple tiles. block.phase-wall.description = Pas aussi fort qu'un mur de thorium, mais détournera les balles à moins qu'elles ne soient trop puissantes.
block.surge-wall.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker. block.phase-wall-large.description = Pas aussi fort qu'un mur de thorium, mais détournera les balles à moins qu'elles ne soient trop puissantes.\nS'étend sur plusieurs tuiles.
block.surge-wall-large.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.\nSpans multiple tiles. block.surge-wall.description = Le bloc défensif le plus puissant.\nPeu de chances de déclencher des éclairs en direction de l'attaquant.
block.door.description = A small door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through. block.surge-wall-large.description = Le bloc défensif le plus puissant.\nPeu de chances de déclencher des éclairs en direction de l'attaquant.\nS'étend sur plusieurs tuiles.
block.door-large.description = A large door that can be opened and closed by tapping on it.\nIf opened, enemies can shoot and move through.\nSpans multiple tiles. block.door.description = Une petite porte qui peut être ouverte et fermée en tapotant dessus.\nSi elle est ouverte, les ennemis peuvent tirer et se déplacer.
block.mend-projector.description = Periodically heals buildings in its vicinity. block.door-large.description = Une grande porte qui peut être ouverte et fermée en tapotant dessus.\nSi elle est ouverte, les ennemis peuvent tirer et se déplacer.\nS'étend sur plusieurs tuiles.
block.overdrive-projector.description = Increases the speed of nearby buildings like drills and conveyors. block.mend-projector.description = Guérit périodiquement les bâtiments situés à proximité.
block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage through bullets. block.overdrive-projector.description = Augmente la vitesse des bâtiments à proximité, comme les foreuses et les convoyeurs.
block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy. block.force-projector.description = Crée un champ de force hexagonal autour de lui-même, protégeant les bâtiments et les unités internes des dommages causés par les balles.
block.duo.description = A small, cheap turret. block.shock-mine.description = Endommage les ennemis qui marchent sur la mine. Presque invisible à l'ennemi.
block.arc.description = A small turret which shoots electricity in a random arc towards the enemy. block.duo.description =Une petite tourelle pas chère.
block.hail.description = A small artillery turret. block.arc.description = Une petite tourelle qui tire de l'électricité dans un arc au hasard vers l'ennemi.
block.lancer.description = A medium-sized turret which shoots charged electricity beams. block.hail.description = Une petite tourelle d'artillerie.
block.wave.description = A medium-sized rapid-fire turret which shoots liquid bubbles. block.lancer.description = Une tourelle de taille moyenne qui tire des faisceaux d’électricité chargés.
block.salvo.description = A medium-sized turret which fires shots in salvos. block.wave.description = Une tourelle de taille moyenne à tir rapide qui tire des bulles de liquide.
block.swarmer.description = A medium-sized turret which shoots burst missiles. block.salvo.description = Une tourelle de taille moyenne qui tire des coups de salves.
block.ripple.description = A large artillery turret which fires several shots simultaneously. block.swarmer.description = Une tourelle de taille moyenne qui tire des missiles éclatés.
block.cyclone.description = A large rapid fire turret. block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs coups simultanément.
block.fuse.description = A large turret which shoots powerful short-range beams. block.cyclone.description = Une grande tourelle à tir rapide.
block.spectre.description = A large turret which shoots two powerful bullets at once. block.fuse.description = Une grande tourelle qui tire de puissants faisceaux à courte portée.
block.meltdown.description = A large turret which shoots powerful long-range beams. block.spectre.description = Une grande tourelle qui tire deux balles puissantes à la fois.
block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable. block.meltdown.description = Une grande tourelle qui tire de puissants faisceaux à longue portée.
block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors. block.conveyor.description = Bloc de transport d'articles standard.\nDéplace les objets et les déposes automatiquement dans des tourelles ou des usines. Rotatif.
block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles. block.titanium-conveyor.description = Bloc de transport d'articles avancé.\nDéplace les articles plus rapidement que les convoyeurs standard.
block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations. block.phase-conveyor.description = Bloc de transport d'articles avancé.\nUtilise le pouvoir de téléporter des articles vers un convoyeur de phase connecté sur plusieurs carreaux.
block.mass-driver.description = Ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range. block.junction.description = Agit comme un pont pour deux bandes transporteuses qui se croisent.\nUtile dans les situations avec deux convoyeurs différents transportant des matériaux différents à des endroits différents.
block.smelter.description = Burns coal for smelting copper and lead into dense alloy. block.mass-driver.description = Bloc de transport d'articles ultime.\nRecueille plusieurs objets et les envoie ensuite à un autre pilote de masse sur une longue distance.
block.arc-smelter.description = Smelts copper and lead into dense alloy by using an external power source. block.smelter.description = Brûle le charbon pour fondre le cuivre et le plomb en un alliage dense.
block.silicon-smelter.description = Reduces sand with highly pure coke in order to produce silicon. block.arc-smelter.description = Fait fondre le cuivre et le plomb en un alliage dense en utilisant une source d'alimentation externe.
block.plastanium-compressor.description = Produces plastanium from oil and titanium. block.silicon-smelter.description = Réduit le sable avec du coke* très pur afin de produire du silicium. (*Coke produit à partir de charbon:REF)
block.phase-weaver.description = Produces phase fabric from radioactive thorium and high amounts of sand. block.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane.
block.alloy-smelter.description = Produces surge alloy from titanium, lead, silicon and copper. block.phase-weaver.description = Produit un tissu de phase à partir de thorium radioactif et de grandes quantités de sable.
block.pulverizer.description = Crushes stone into sand. Useful when there is a lack of natural sand. block.alloy-smelter.description = Produit un alliage de surtension à partir de titane, plomb, silicium et cuivre.
block.pulverizer.description = Brise la pierre en sable. Utile en cas de manque de sable naturel.
block.pyratite-mixer.description = Mixes coal, lead and sand into highly flammable pyratite. block.pyratite-mixer.description = Mixes coal, lead and sand into highly flammable pyratite.
block.blast-mixer.description = Uses oil for transforming pyratite into the less flammable but more explosive blast compound. block.blast-mixer.description = Uses oil for transforming pyratite into the less flammable but more explosive blast compound.
block.cryofluidmixer.description = Combines water and titanium into cryofluid which is much more efficient for cooling. block.cryofluidmixer.description = Combines water and titanium into cryofluid which is much more efficient for cooling.
Binary file not shown.
@@ -4,12 +4,11 @@ import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.distribution.WarpGate;
import io.anuke.mindustry.world.blocks.power.*; import io.anuke.mindustry.world.blocks.power.*;
public class PowerBlocks extends BlockList implements ContentList{ public class PowerBlocks extends BlockList implements ContentList{
public static Block combustionGenerator, thermalGenerator, turbineGenerator, rtgGenerator, solarPanel, largeSolarPanel, public static Block combustionGenerator, thermalGenerator, turbineGenerator, rtgGenerator, solarPanel, largeSolarPanel,
thoriumReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge, warpGate; thoriumReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge;
@Override @Override
public void load(){ public void load(){
@@ -85,7 +84,5 @@ public class PowerBlocks extends BlockList implements ContentList{
shadow = "shadow-round-2"; shadow = "shadow-round-2";
}}; }};
warpGate = new WarpGate("warp-gate");
} }
} }
@@ -172,7 +172,6 @@ public class Logic extends Module{
@Override @Override
public void update(){ public void update(){
if(threads.isEnabled() && !threads.isOnThread()) return;
if(Vars.control != null){ if(Vars.control != null){
control.runUpdateLogic(); control.runUpdateLogic();
@@ -238,9 +237,5 @@ public class Logic extends Module{
checkGameOver(); checkGameOver();
} }
} }
if(threads.isEnabled()){
netServer.update();
}
} }
} }
@@ -399,11 +399,11 @@ public class NetClient extends Module{
quiet = true; quiet = true;
} }
public synchronized void addRemovedEntity(int id){ public void addRemovedEntity(int id){
removed.add(id); removed.add(id);
} }
public synchronized boolean isEntityUsed(int id){ public boolean isEntityUsed(int id){
return removed.contains(id); return removed.contains(id);
} }
@@ -414,11 +414,9 @@ public class NetClient extends Module{
BuildRequest[] requests; BuildRequest[] requests;
synchronized(player.getPlaceQueue()){ requests = new BuildRequest[player.getPlaceQueue().size];
requests = new BuildRequest[player.getPlaceQueue().size]; for(int i = 0; i < requests.length; i++){
for(int i = 0; i < requests.length; i++){ requests[i] = player.getPlaceQueue().get(i);
requests[i] = player.getPlaceQueue().get(i);
}
} }
Call.onClientShapshot(lastSent++, TimeUtils.millis(), player.x, player.y, Call.onClientShapshot(lastSent++, TimeUtils.millis(), player.x, player.y,
@@ -416,7 +416,6 @@ public class NetServer extends Module{
} }
public void update(){ public void update(){
if(threads.isEnabled() && !threads.isOnThread()) return;
if(!headless && !closing && Net.server() && state.is(State.menu)){ if(!headless && !closing && Net.server() && state.is(State.menu)){
closing = true; closing = true;
@@ -1,80 +1,34 @@
package io.anuke.mindustry.core; package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.Queue;
import com.badlogic.gdx.utils.TimeUtils; import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Threads;
import io.anuke.ucore.util.Threads.ThreadInfoProvider;
import static io.anuke.mindustry.Vars.control; public class ThreadHandler{
import static io.anuke.mindustry.Vars.logic;
public class ThreadHandler implements ThreadInfoProvider{
private final Queue<Runnable> toRun = new Queue<>();
private Thread thread, graphicsThread;
private final Object updateLock = new Object();
private float delta = 1f;
private float smoothDelta = 1f;
private long frame = 0, lastDeltaUpdate;
private float framesSinceUpdate;
private boolean enabled;
private boolean rendered = true;
private long lastFrameTime; private long lastFrameTime;
public ThreadHandler(){ public ThreadHandler(){
Threads.setThreadInfoProvider(this);
graphicsThread = Thread.currentThread();
Timers.setDeltaProvider(() -> { Timers.setDeltaProvider(() -> {
float result = isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f; float result = Gdx.graphics.getDeltaTime() * 60f;
return Math.min(Float.isNaN(result) ? 1f : result, 15f); return Math.min(Float.isNaN(result) || Float.isInfinite(result) ? 1f : result, 15f);
}); });
} }
public void run(Runnable r){ public void run(Runnable r){
if(enabled){ r.run();
synchronized(toRun){
toRun.addLast(r);
}
}else{
r.run();
}
} }
public void runGraphics(Runnable r){ public void runGraphics(Runnable r){
if(enabled){ r.run();
Gdx.app.postRunnable(r);
}else{
r.run();
}
} }
public void runDelay(Runnable r){ public void runDelay(Runnable r){
if(enabled){ Gdx.app.postRunnable(r);
synchronized(toRun){
toRun.addLast(r);
}
}else{
Gdx.app.postRunnable(r);
}
}
public int getTPS(){
if(smoothDelta == 0f){
return 60;
}
return (int) (60 / smoothDelta);
} }
public long getFrameID(){ public long getFrameID(){
return enabled ? frame : Gdx.graphics.getFrameId(); return Gdx.graphics.getFrameId();
}
public float getFramesSinceUpdate(){
return framesSinceUpdate;
} }
public void handleBeginRender(){ public void handleBeginRender(){
@@ -95,119 +49,6 @@ public class ThreadHandler implements ThreadInfoProvider{
} }
} }
} }
if(!enabled) return;
framesSinceUpdate += Timers.delta();
synchronized(updateLock){
rendered = true;
updateLock.notify();
}
} }
public boolean isEnabled(){
return enabled;
}
public void setEnabled(boolean enabled){
if(enabled){
logic.doUpdate = false;
Timers.runTask(2f, () -> {
if(thread != null){
thread.interrupt();
thread = null;
}
thread = new Thread(this::runLogic);
thread.setDaemon(true);
thread.setName("Update Thread");
thread.start();
Log.info("Starting logic thread.");
this.enabled = true;
});
}else{
this.enabled = false;
if(thread != null){
thread.interrupt();
thread = null;
}
Timers.runTask(2f, () -> {
logic.doUpdate = true;
});
}
}
public boolean doInterpolate(){
return enabled && Gdx.graphics.getFramesPerSecond() - getTPS() > 20 && getTPS() < 30;
}
public boolean isOnThread(){
return Thread.currentThread() == thread;
}
@Override
public boolean isOnLogicThread() {
return !enabled || Thread.currentThread() == thread;
}
@Override
public boolean isOnGraphicsThread() {
return !enabled || Thread.currentThread() == graphicsThread;
}
private void runLogic(){
try{
while(true){
long time = TimeUtils.nanoTime();
while(true){
Runnable r;
synchronized(toRun){
if(toRun.size > 0){
r = toRun.removeFirst();
}else{
break;
}
}
r.run();
}
logic.doUpdate = true;
logic.update();
logic.doUpdate = false;
long elapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
long target = (long) ((1000) / 60f);
if(elapsed < target){
Thread.sleep(target - elapsed);
}
synchronized(updateLock){
while(!rendered){
updateLock.wait();
}
rendered = false;
}
long actuallyElapsed = TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(time));
delta = Math.max(actuallyElapsed, target) / 1000f * 60f;
if(TimeUtils.timeSinceMillis(lastDeltaUpdate) > 1000){
lastDeltaUpdate = TimeUtils.millis();
smoothDelta = delta;
}
frame++;
framesSinceUpdate = 0;
}
}catch(InterruptedException ex){
Log.info("Stopping logic thread.");
}catch(Throwable ex){
control.setError(ex);
}
}
} }
+3 -10
View File
@@ -28,7 +28,6 @@ import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
import io.anuke.ucore.scene.ui.TooltipManager; import io.anuke.ucore.scene.ui.TooltipManager;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Threads;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.scene.actions.Actions.*; import static io.anuke.ucore.scene.actions.Actions.*;
@@ -155,6 +154,7 @@ public class UI extends SceneModule{
load = new LoadDialog(); load = new LoadDialog();
levels = new CustomGameDialog(); levels = new CustomGameDialog();
language = new LanguageDialog(); language = new LanguageDialog();
unlocks = new UnlocksDialog();
settings = new SettingsMenuDialog(); settings = new SettingsMenuDialog();
host = new HostDialog(); host = new HostDialog();
paused = new PausedDialog(); paused = new PausedDialog();
@@ -165,7 +165,6 @@ public class UI extends SceneModule{
traces = new TraceDialog(); traces = new TraceDialog();
maps = new MapsDialog(); maps = new MapsDialog();
localplayers = new LocalPlayerDialog(); localplayers = new LocalPlayerDialog();
unlocks = new UnlocksDialog();
content = new ContentInfoDialog(); content = new ContentInfoDialog();
sectors = new SectorsDialog(); sectors = new SectorsDialog();
missions = new MissionDialog(); missions = new MissionDialog();
@@ -240,8 +239,6 @@ public class UI extends SceneModule{
} }
public void showInfoFade(String info){ public void showInfoFade(String info){
Threads.assertGraphics();
Table table = new Table(); Table table = new Table();
table.setFillParent(true); table.setFillParent(true);
table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor());
@@ -250,9 +247,7 @@ public class UI extends SceneModule{
} }
public void showInfo(String info){ public void showInfo(String info){
Threads.assertGraphics(); new Dialog("", "dialog"){{
new Dialog("$text.info.title", "dialog"){{
getCell(content()).growX(); getCell(content()).growX();
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center); content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4); buttons().addButton("$text.ok", this::hide).size(90, 50).pad(4);
@@ -260,9 +255,7 @@ public class UI extends SceneModule{
} }
public void showInfo(String info, Runnable clicked){ public void showInfo(String info, Runnable clicked){
Threads.assertGraphics(); new Dialog("", "dialog"){{
new Dialog("$text.info.title", "dialog"){{
getCell(content()).growX(); getCell(content()).growX();
content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center); content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
buttons().addButton("$text.ok", () -> { buttons().addButton("$text.ok", () -> {
@@ -16,6 +16,7 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail; import io.anuke.mindustry.graphics.Trail;
import io.anuke.mindustry.io.TypeIO;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetConnection; import io.anuke.mindustry.net.NetConnection;
import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.ContentType;
@@ -425,55 +426,53 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
/**Draw all current build requests. Does not draw the beam effect, only the positions.*/ /**Draw all current build requests. Does not draw the beam effect, only the positions.*/
public void drawBuildRequests(){ public void drawBuildRequests(){
synchronized(getPlaceQueue()){ for(BuildRequest request : getPlaceQueue()){
for(BuildRequest request : getPlaceQueue()){ if(getCurrentRequest() == request) continue;
if(getCurrentRequest() == request) continue;
if(request.breaking){ if(request.breaking){
Block block = world.tile(request.x, request.y).target().block(); Block block = world.tile(request.x, request.y).target().block();
//draw removal request //draw removal request
Lines.stroke(2f); Lines.stroke(2f);
Draw.color(Palette.removeBack); Draw.color(Palette.removeBack);
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1; float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
Lines.square( Lines.square(
request.x * tilesize + block.offset(), request.x * tilesize + block.offset(),
request.y * tilesize + block.offset() - 1, request.y * tilesize + block.offset() - 1,
rad); rad);
Draw.color(Palette.remove); Draw.color(Palette.remove);
Lines.square( Lines.square(
request.x * tilesize + block.offset(), request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(), request.y * tilesize + block.offset(),
rad); rad);
}else{ }else{
//draw place request //draw place request
Lines.stroke(2f); Lines.stroke(2f);
Draw.color(Palette.accentBack); Draw.color(Palette.accentBack);
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f; float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
Lines.square( Lines.square(
request.x * tilesize + request.recipe.result.offset(), request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset() - 1, request.y * tilesize + request.recipe.result.offset() - 1,
rad); rad);
Draw.color(Palette.accent); Draw.color(Palette.accent);
Lines.square( Lines.square(
request.x * tilesize + request.recipe.result.offset(), request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(), request.y * tilesize + request.recipe.result.offset(),
rad); rad);
}
} }
Draw.reset();
} }
Draw.reset();
} }
//endregion //endregion
@@ -853,7 +852,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
@Override @Override
public void write(DataOutput buffer) throws IOException{ public void write(DataOutput buffer) throws IOException{
super.writeSave(buffer, !isLocal); super.writeSave(buffer, !isLocal);
buffer.writeUTF(name); //TODO writing strings is very inefficient TypeIO.writeStringData(buffer, name); //TODO writing strings is very inefficient
buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2)); buffer.writeByte(Bits.toByte(isAdmin) | (Bits.toByte(dead) << 1) | (Bits.toByte(isBoosting) << 2));
buffer.writeInt(Color.rgba8888(color)); buffer.writeInt(Color.rgba8888(color));
buffer.writeByte(mech.id); buffer.writeByte(mech.id);
@@ -868,7 +867,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
public void read(DataInput buffer, long time) throws IOException{ public void read(DataInput buffer, long time) throws IOException{
float lastx = x, lasty = y, lastrot = rotation; float lastx = x, lasty = y, lastrot = rotation;
super.readSave(buffer); super.readSave(buffer);
name = buffer.readUTF(); name = TypeIO.readStringData(buffer);
byte bools = buffer.readByte(); byte bools = buffer.readByte();
isAdmin = (bools & 1) != 0; isAdmin = (bools & 1) != 0;
dead = (bools & 2) != 0; dead = (bools & 2) != 0;
@@ -259,27 +259,25 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
@Override @Override
public void update(){ public void update(){
synchronized(Tile.tileSetLock){ //TODO better smoke effect, this one is awful
//TODO better smoke effect, this one is awful if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) &&
if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) && Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){
Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){
Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4)); Effects.effect(Fx.smoke, x + Mathf.range(4), y + Mathf.range(4));
} }
timeScaleDuration -= Timers.delta(); timeScaleDuration -= Timers.delta();
if(timeScaleDuration <= 0f || !tile.block().canOverdrive){ if(timeScaleDuration <= 0f || !tile.block().canOverdrive){
timeScale = 1f; timeScale = 1f;
} }
if(health <= 0){ if(health <= 0){
onDeath(); onDeath();
} }
Block previous = tile.block(); Block previous = tile.block();
tile.block().update(tile); tile.block().update(tile);
if(tile.block() == previous && cons != null){ if(tile.block() == previous && cons != null){
cons.update(this); cons.update(this);
}
} }
} }
@@ -13,7 +13,6 @@ import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate; import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.EnumSet; import io.anuke.ucore.util.EnumSet;
import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Threads;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -63,45 +62,20 @@ public class Units{
/**Can be called from any thread.*/ /**Can be called from any thread.*/
public static boolean anyEntities(Rectangle rect){ public static boolean anyEntities(Rectangle rect){
if(Threads.isLogic()){ boolResult = false;
boolResult = false;
Units.getNearby(rect, unit -> { Units.getNearby(rect, unit -> {
if(boolResult) return; if(boolResult) return;
if(!unit.isFlying()){ if(!unit.isFlying()){
unit.getHitbox(hitrect); unit.getHitbox(hitrect);
if(hitrect.overlaps(rect)){ if(hitrect.overlaps(rect)){
boolResult = true; boolResult = true;
}
} }
});
return boolResult;
}else{
boolResultGraphics = false;
for(EntityGroup<? extends BaseUnit> g : unitGroups){
g.forEach(u -> {
if(u.isFlying()) return;
u.getHitbox(rectGraphics);
if(rectGraphics.overlaps(rect)){
boolResultGraphics = true;
}
});
if(boolResultGraphics) return true;
} }
});
playerGroup.forEach(u -> { return boolResult;
if(u.isFlying()) return;
u.getHitbox(rectGraphics);
if(rectGraphics.overlaps(rect)){
boolResultGraphics = true;
}
});
return boolResultGraphics;
}
} }
/**Returns whether there are any entities on this tile, with the hitbox expanded.*/ /**Returns whether there are any entities on this tile, with the hitbox expanded.*/
@@ -84,30 +84,28 @@ public interface BuilderTrait extends Entity{
} }
default void readBuilding(DataInput input, boolean applyChanges) throws IOException{ default void readBuilding(DataInput input, boolean applyChanges) throws IOException{
synchronized(getPlaceQueue()){ if(applyChanges) getPlaceQueue().clear();
if(applyChanges) getPlaceQueue().clear();
byte type = input.readByte(); byte type = input.readByte();
if(type != -1){ if(type != -1){
int position = input.readInt(); int position = input.readInt();
float progress = input.readFloat(); float progress = input.readFloat();
BuildRequest request; BuildRequest request;
if(type == 1){ //remove if(type == 1){ //remove
request = new BuildRequest(position % world.width(), position / world.width()); request = new BuildRequest(position % world.width(), position / world.width());
}else{ //place }else{ //place
byte recipe = input.readByte(); byte recipe = input.readByte();
byte rotation = input.readByte(); byte rotation = input.readByte();
request = new BuildRequest(position % world.width(), position / world.width(), rotation, content.recipe(recipe)); request = new BuildRequest(position % world.width(), position / world.width(), rotation, content.recipe(recipe));
} }
request.progress = progress; request.progress = progress;
if(applyChanges){ if(applyChanges){
getPlaceQueue().addLast(request); getPlaceQueue().addLast(request);
}else if(isBuilding()){ }else if(isBuilding()){
getCurrentRequest().progress = progress; getCurrentRequest().progress = progress;
}
} }
} }
} }
@@ -122,13 +120,11 @@ public interface BuilderTrait extends Entity{
* Otherwise, a new place request is added to the queue. * Otherwise, a new place request is added to the queue.
*/ */
default void replaceBuilding(int x, int y, int rotation, Recipe recipe){ default void replaceBuilding(int x, int y, int rotation, Recipe recipe){
synchronized(getPlaceQueue()){ for(BuildRequest request : getPlaceQueue()){
for(BuildRequest request : getPlaceQueue()){ if(request.x == x && request.y == y){
if(request.x == x && request.y == y){ clearBuilding();
clearBuilding(); addBuildRequest(request);
addBuildRequest(request); return;
return;
}
} }
} }
@@ -142,18 +138,16 @@ public interface BuilderTrait extends Entity{
/**Add another build requests to the tail of the queue, if it doesn't exist there yet.*/ /**Add another build requests to the tail of the queue, if it doesn't exist there yet.*/
default void addBuildRequest(BuildRequest place){ default void addBuildRequest(BuildRequest place){
synchronized(getPlaceQueue()){ for(BuildRequest request : getPlaceQueue()){
for(BuildRequest request : getPlaceQueue()){ if(request.x == place.x && request.y == place.y){
if(request.x == place.x && request.y == place.y){ return;
return;
}
} }
Tile tile = world.tile(place.x, place.y);
if(tile != null && tile.entity instanceof BuildEntity){
place.progress = tile.<BuildEntity>entity().progress;
}
getPlaceQueue().addLast(place);
} }
Tile tile = world.tile(place.x, place.y);
if(tile != null && tile.entity instanceof BuildEntity){
place.progress = tile.<BuildEntity>entity().progress;
}
getPlaceQueue().addLast(place);
} }
/** /**
@@ -161,9 +155,7 @@ public interface BuilderTrait extends Entity{
* May return null. * May return null.
*/ */
default BuildRequest getCurrentRequest(){ default BuildRequest getCurrentRequest(){
synchronized(getPlaceQueue()){ return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
}
} }
/** /**
@@ -275,18 +267,15 @@ public interface BuilderTrait extends Entity{
/**Draw placement effects for an entity. This includes mining*/ /**Draw placement effects for an entity. This includes mining*/
default void drawBuilding(Unit unit){ default void drawBuilding(Unit unit){
BuildRequest request; BuildRequest request;
if(!isBuilding()){
synchronized(getPlaceQueue()){ if(getMineTile() != null){
if(!isBuilding()){ drawMining(unit);
if(getMineTile() != null){
drawMining(unit);
}
return;
} }
return;
request = getCurrentRequest();
} }
request = getCurrentRequest();
Tile tile = world.tile(request.x, request.y); Tile tile = world.tile(request.x, request.y);
if(unit.distanceTo(tile) > placeDistance){ if(unit.distanceTo(tile) > placeDistance){
@@ -311,10 +300,6 @@ public interface BuilderTrait extends Entity{
float x1 = tmptr[0].x, y1 = tmptr[0].y, float x1 = tmptr[0].x, y1 = tmptr[0].y,
x3 = tmptr[1].x, y3 = tmptr[1].y; x3 = tmptr[1].x, y3 = tmptr[1].y;
Translator close = Geometry.findClosest(unit.x, unit.y, tmptr);
float x2 = close.x, y2 = close.y;
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
Draw.alpha(1f); Draw.alpha(1f);
@@ -320,10 +320,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
if(target != null) behavior(); if(target != null) behavior();
if(!isWave && !isFlying()){ x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize);
x = Mathf.clamp(x, tilesize/2f, world.width() * tilesize - tilesize/2f); y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize);
y = Mathf.clamp(y, tilesize/2f, world.height() * tilesize - tilesize/2f);
}
} }
@Override @Override
@@ -40,7 +40,6 @@ import static io.anuke.mindustry.Vars.unitGroups;
import static io.anuke.mindustry.Vars.world; import static io.anuke.mindustry.Vars.world;
public class Drone extends FlyingUnit implements BuilderTrait{ public class Drone extends FlyingUnit implements BuilderTrait{
protected static float discoverRange = 120f;
protected static int timerRepairEffect = timerIndex++; protected static int timerRepairEffect = timerIndex++;
protected Item targetItem; protected Item targetItem;
@@ -250,14 +249,12 @@ public class Drone extends FlyingUnit implements BuilderTrait{
for(BaseUnit unit : group.all()){ for(BaseUnit unit : group.all()){
if(unit instanceof Drone){ if(unit instanceof Drone){
Drone drone = (Drone)unit; Drone drone = (Drone)unit;
synchronized(drone.getPlaceQueue()){ if(drone.isBuilding()){
if(drone.isBuilding()){ //stop building if opposite building begins.
//stop building if opposite building begins. BuildRequest req = drone.getCurrentRequest();
BuildRequest req = drone.getCurrentRequest(); if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){
if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){ drone.clearBuilding();
drone.clearBuilding(); drone.setState(drone.repair);
drone.setState(drone.repair);
}
} }
} }
@@ -105,32 +105,29 @@ public class BlockRenderer{
for(int x = minx; x <= maxx; x++){ for(int x = minx; x <= maxx; x++){
for(int y = miny; y <= maxy; y++){ for(int y = miny; y <= maxy; y++){
boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey); boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey);
Tile tile = world.rawTile(x, y);
synchronized(Tile.tileSetLock){ if(tile != null){
Tile tile = world.rawTile(x, y); Block block = tile.block();
Team team = tile.getTeam();
if(tile != null){ if(!expanded && block != Blocks.air && world.isAccessible(x, y)){
Block block = tile.block(); tile.block().drawShadow(tile);
Team team = tile.getTeam(); }
if(!expanded && block != Blocks.air && world.isAccessible(x, y)){ if(block != Blocks.air){
tile.block().drawShadow(tile); if(!expanded){
addRequest(tile, Layer.block);
teamChecks.add(team.ordinal());
} }
if(block != Blocks.air){ if(block.expanded || !expanded){
if(!expanded){ if(block.layer != null && block.isLayer(tile)){
addRequest(tile, Layer.block); addRequest(tile, block.layer);
teamChecks.add(team.ordinal());
} }
if(block.expanded || !expanded){ if(block.layer2 != null && block.isLayer2(tile)){
if(block.layer != null && block.isLayer(tile)){ addRequest(tile, block.layer2);
addRequest(tile, block.layer);
}
if(block.layer2 != null && block.isLayer2(tile)){
addRequest(tile, block.layer2);
}
} }
} }
} }
@@ -170,16 +167,14 @@ public class BlockRenderer{
layerBegins(req.layer); layerBegins(req.layer);
} }
synchronized(Tile.tileSetLock){ Block block = req.tile.block();
Block block = req.tile.block();
if(req.layer == Layer.block){ if(req.layer == Layer.block){
block.draw(req.tile); block.draw(req.tile);
}else if(req.layer == block.layer){ }else if(req.layer == block.layer){
block.drawLayer(req.tile); block.drawLayer(req.tile);
}else if(req.layer == block.layer2){ }else if(req.layer == block.layer2){
block.drawLayer2(req.tile); block.drawLayer2(req.tile);
}
} }
lastLayer = req.layer; lastLayer = req.layer;
@@ -198,17 +193,16 @@ public class BlockRenderer{
BlockRequest req = requests.get(index); BlockRequest req = requests.get(index);
if(req.tile.getTeam() != team) continue; if(req.tile.getTeam() != team) continue;
synchronized(Tile.tileSetLock){ Block block = req.tile.block();
Block block = req.tile.block();
if(req.layer == Layer.block){ if(req.layer == Layer.block){
block.draw(req.tile); block.draw(req.tile);
}else if(req.layer == block.layer){ }else if(req.layer == block.layer){
block.drawLayer(req.tile); block.drawLayer(req.tile);
}else if(req.layer == block.layer2){ }else if(req.layer == block.layer2){
block.drawLayer2(req.tile); block.drawLayer2(req.tile);
}
} }
} }
} }
@@ -74,20 +74,18 @@ public class MinimapRenderer implements Disposable{
dx = Mathf.clamp(dx, sz, world.width() - sz); dx = Mathf.clamp(dx, sz, world.width() - sz);
dy = Mathf.clamp(dy, sz, world.height() - sz); dy = Mathf.clamp(dy, sz, world.height() - sz);
synchronized(units){ rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); Graphics.beginClip(x, y, w, h);
Graphics.beginClip(x, y, w, h);
for(Unit unit : units){ for(Unit unit : units){
float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h; float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h;
Draw.color(unit.getTeam().color); Draw.color(unit.getTeam().color);
Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2)); Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2));
}
Draw.color();
Graphics.endClip();
} }
Draw.color();
Graphics.endClip();
} }
public TextureRegion getRegion(){ public TextureRegion getRegion(){
@@ -128,11 +126,9 @@ public class MinimapRenderer implements Disposable{
dx = Mathf.clamp(dx, sz, world.width() - sz); dx = Mathf.clamp(dx, sz, world.width() - sz);
dy = Mathf.clamp(dy, sz, world.height() - sz); dy = Mathf.clamp(dy, sz, world.height() - sz);
synchronized(units){ rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); units.clear();
units.clear(); Units.getNearby(rect, units::add);
Units.getNearby(rect, units::add);
}
} }
private int colorFor(Tile tile){ private int colorFor(Tile tile){
@@ -48,10 +48,7 @@ public class OverlayRenderer{
//draw config selected block //draw config selected block
if(input.frag.config.isShown()){ if(input.frag.config.isShown()){
Tile tile = input.frag.config.getSelectedTile(); Tile tile = input.frag.config.getSelectedTile();
tile.block().drawConfigure(tile);
synchronized(Tile.tileSetLock){
tile.block().drawConfigure(tile);
}
} }
input.drawTop(); input.drawTop();
@@ -108,53 +105,52 @@ public class OverlayRenderer{
Draw.reset(); Draw.reset();
} }
synchronized(Tile.tileSetLock){ Block block = target.block();
Block block = target.block(); TileEntity entity = target.entity;
TileEntity entity = target.entity;
if(entity != null){ if(entity != null){
int[] values = {0, 0}; int[] values = {0, 0};
boolean[] doDraw = {false}; boolean[] doDraw = {false};
Runnable drawbars = () -> { Runnable drawbars = () -> {
for(BlockBar bar : block.bars.list()){ for(BlockBar bar : block.bars.list()){
float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1])); float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1]));
float value = bar.value.get(target); float value = bar.value.get(target);
if(MathUtils.isEqual(value, -1f)) continue; if(MathUtils.isEqual(value, -1f)) continue;
if(doDraw[0]){ if(doDraw[0]){
drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value); drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value);
}
if(bar.top)
values[0]++;
else
values[1]++;
} }
};
drawbars.run(); if(bar.top)
values[0]++;
if(values[0] > 0){ else
drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]); values[1]++;
} }
};
if(values[1] > 0){ drawbars.run();
drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]);
}
doDraw[0] = true; if(values[0] > 0){
values[0] = 0; drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]);
values[1] = 1;
drawbars.run();
} }
if(values[1] > 0){
drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]);
}
target.block().drawSelect(target); doDraw[0] = true;
values[0] = 0;
values[1] = 1;
drawbars.run();
} }
target.block().drawSelect(target);
} }
} }
@@ -22,7 +22,7 @@ public class Trail{
this.length = length; this.length = length;
} }
public synchronized void update(float curx, float cury){ public void update(float curx, float cury){
if(Vector2.dst(curx, cury, lastX, lastY) >= maxJump){ if(Vector2.dst(curx, cury, lastX, lastY) >= maxJump){
points.clear(); points.clear();
} }
@@ -39,11 +39,11 @@ public class Trail{
lastY = cury; lastY = cury;
} }
public synchronized void clear(){ public void clear(){
points.clear(); points.clear();
} }
public synchronized void draw(Color color, float stroke){ public void draw(Color color, float stroke){
Draw.color(color); Draw.color(color);
for(int i = 0; i < points.size - 2; i += 2){ for(int i = 0; i < points.size - 2; i += 2){
+48 -4
View File
@@ -23,15 +23,18 @@ import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
/** Class for specifying read/write methods for code generation.*/ /** Class for specifying read/write methods for code generation.*/
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class TypeIO{ public class TypeIO{
private static final Charset charset = Charset.forName("UTF-8");
@WriteClass(Player.class) @WriteClass(Player.class)
public static void writePlayer(ByteBuffer buffer, Player player){ public static void writePlayer(ByteBuffer buffer, Player player){
@@ -329,19 +332,29 @@ public class TypeIO{
@WriteClass(String.class) @WriteClass(String.class)
public static void writeString(ByteBuffer buffer, String string){ public static void writeString(ByteBuffer buffer, String string){
if(string != null){ if(string != null){
Charset charset = Charset.defaultCharset();
byte[] nameBytes = charset.name().getBytes(StandardCharsets.UTF_8);
buffer.put((byte)nameBytes.length);
buffer.put(nameBytes);
byte[] bytes = string.getBytes(charset); byte[] bytes = string.getBytes(charset);
buffer.putShort((short) bytes.length); buffer.putShort((short) bytes.length);
buffer.put(bytes); buffer.put(bytes);
}else{ }else{
buffer.putShort((short) -1); buffer.put((byte) -1);
} }
} }
@ReadClass(String.class) @ReadClass(String.class)
public static String readString(ByteBuffer buffer){ public static String readString(ByteBuffer buffer){
short length = buffer.getShort(); byte length = buffer.get();
if(length != -1){ if(length != -1){
byte[] bytes = new byte[length]; byte[] cbytes = new byte[length];
buffer.get(cbytes);
Charset charset = Charset.forName(new String(cbytes, StandardCharsets.UTF_8));
short slength = buffer.getShort();
byte[] bytes = new byte[slength];
buffer.get(bytes); buffer.get(bytes);
return new String(bytes, charset); return new String(bytes, charset);
}else{ }else{
@@ -362,4 +375,35 @@ public class TypeIO{
buffer.get(bytes); buffer.get(bytes);
return bytes; return bytes;
} }
public static void writeStringData(DataOutput buffer, String string) throws IOException{
if(string != null){
Charset charset = Charset.defaultCharset();
byte[] nameBytes = charset.name().getBytes(StandardCharsets.UTF_8);
buffer.writeByte((byte)nameBytes.length);
buffer.write(nameBytes);
byte[] bytes = string.getBytes(charset);
buffer.writeShort((short) bytes.length);
buffer.write(bytes);
}else{
buffer.writeByte((byte) -1);
}
}
public static String readStringData(DataInput buffer) throws IOException{
byte length = buffer.readByte();
if(length != -1){
byte[] cbytes = new byte[length];
buffer.readFully(cbytes);
Charset charset = Charset.forName(new String(cbytes, StandardCharsets.UTF_8));
short slength = buffer.readShort();
byte[] bytes = new byte[slength];
buffer.readFully(bytes);
return new String(bytes, charset);
}else{
return null;
}
}
} }
-2
View File
@@ -20,7 +20,6 @@ import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Pooling; import io.anuke.ucore.util.Pooling;
import io.anuke.ucore.util.Threads;
import java.io.IOException; import java.io.IOException;
@@ -51,7 +50,6 @@ public class Net{
public static void showError(Throwable e){ public static void showError(Throwable e){
if(!headless){ if(!headless){
Threads.assertGraphics();
Throwable t = e; Throwable t = e;
while(t.getCause() != null){ while(t.getCause() != null){
@@ -145,9 +145,6 @@ public class NetworkIO{
} }
} }
/**
* Return whether a custom map is expected, and thus whether the client should wait for additional data.
*/
public static void loadWorld(InputStream is){ public static void loadWorld(InputStream is){
Player player = players[0]; Player player = players[0];
@@ -165,6 +162,8 @@ public class NetworkIO{
world.sectors.createSector(Bits.getLeftShort(sector), Bits.getRightShort(sector)); world.sectors.createSector(Bits.getLeftShort(sector), Bits.getRightShort(sector));
world.setSector(world.sectors.get(sector)); world.setSector(world.sectors.get(sector));
world.getSector().completedMissions = missions; world.getSector().completedMissions = missions;
}else{
world.setSector(null);
} }
ObjectMap<String, String> tags = new ObjectMap<>(); ObjectMap<String, String> tags = new ObjectMap<>();
+7 -7
View File
@@ -8,13 +8,13 @@ public class Links{
private static void createLinks(){ private static void createLinks(){
links = new LinkEntry[]{ links = new LinkEntry[]{
new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")), new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")),
new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Color.valueOf("026aa7")), new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Color.valueOf("026aa7")),
new LinkEntry("wiki", "http://mindustry.wikia.com/wiki/Mindustry_Wiki", Color.valueOf("0f142f")), new LinkEntry("wiki", "http://mindustry.wikia.com/wiki/Mindustry_Wiki", Color.valueOf("0f142f")),
new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")), new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")),
new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Color.valueOf("689f38")), new LinkEntry("google-play", "https://play.google.com/store/apps/details?id=io.anuke.mindustry", Color.valueOf("689f38")),
new LinkEntry("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")), new LinkEntry("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")),
new LinkEntry("dev-builds", "https://github.com/Anuken/Mindustry/wiki", Color.valueOf("fafbfc")) new LinkEntry("dev-builds", "https://jenkins.hellomouse.net/job/mindustry/", Color.valueOf("fafbfc"))
}; };
} }
@@ -12,6 +12,7 @@ import io.anuke.ucore.scene.ui.layout.Cell;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.utils.UIUtils; import io.anuke.ucore.scene.utils.UIUtils;
import io.anuke.ucore.util.OS; import io.anuke.ucore.util.OS;
import io.anuke.ucore.util.Strings;
import static io.anuke.mindustry.Vars.ios; import static io.anuke.mindustry.Vars.ios;
import static io.anuke.mindustry.Vars.ui; import static io.anuke.mindustry.Vars.ui;
@@ -55,7 +56,7 @@ public class AboutDialog extends FloatingDialog{
}).size(h - 5, h); }).size(h - 5, h);
table.table(inset -> { table.table(inset -> {
inset.add("[accent]" + link.name.replace("-", " ")).growX().left(); inset.add("[accent]" + Strings.capitalize(link.name.replace("-", " "))).growX().left();
inset.row(); inset.row();
inset.labelWrap(link.description).width(w - 100f).color(Color.LIGHT_GRAY).growX(); inset.labelWrap(link.description).width(w - 100f).color(Color.LIGHT_GRAY).growX();
}).padLeft(8); }).padLeft(8);
@@ -93,7 +94,7 @@ public class AboutDialog extends FloatingDialog{
public void showCredits(){ public void showCredits(){
FloatingDialog dialog = new FloatingDialog("$text.credits"); FloatingDialog dialog = new FloatingDialog("$text.credits");
dialog.addCloseButton(); dialog.addCloseButton();
dialog.content().add("$text.credits.text"); dialog.content().labelWrap("$text.credits.text").width(400f);
dialog.show(); dialog.show();
} }
} }
@@ -57,6 +57,9 @@ public class PausedDialog extends FloatingDialog{
hide(); hide();
}); });
content().row();
content().addButton("$text.unlocks", ui.unlocks::show);
content().row(); content().row();
content().addButton("$text.settings", ui.settings::show); content().addButton("$text.settings", ui.settings::show);
@@ -190,11 +190,6 @@ public class SettingsMenuDialog extends SettingsDialog{
}); });
graphics.sliderPref("fpscap", 125, 5, 125, 5, s -> (s > 120 ? Bundles.get("setting.fpscap.none") : Bundles.format("setting.fpscap.text", s))); graphics.sliderPref("fpscap", 125, 5, 125, 5, s -> (s > 120 ? Bundles.get("setting.fpscap.none") : Bundles.format("setting.fpscap.text", s)));
graphics.checkPref("multithread", mobile, threads::setEnabled);
if(Settings.getBool("multithread")){
threads.setEnabled(true);
}
if(!mobile){ if(!mobile){
graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b)); graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b));
@@ -36,7 +36,7 @@ public class BlockConsumeFragment extends Fragment{
tile = tile.target(); tile = tile.target();
if(tile != lastTile){ if(tile != lastTile){
if(tile.block().consumes.hasAny()){ if(tile.getTeam() == players[0].getTeam() && tile.block().consumes.hasAny()){
show(tile); show(tile);
}else if(visible){ }else if(visible){
hide(); hide();
@@ -126,7 +126,6 @@ public class HudFragment extends Fragment{
IntFormat tps = new IntFormat("text.tps"); IntFormat tps = new IntFormat("text.tps");
IntFormat ping = new IntFormat("text.ping"); IntFormat ping = new IntFormat("text.ping");
t.label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10); t.label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10);
t.label(() -> tps.get(threads.getTPS())).visible(() -> threads.isEnabled());
t.row(); t.row();
if(Net.hasClient()){ if(Net.hasClient()){
t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2); t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2);
@@ -97,7 +97,7 @@ public class PlayerListFragment extends Fragment{
button.labelWrap("[#" + player.color.toString().toUpperCase() + "]" + player.name).width(170f).pad(10); button.labelWrap("[#" + player.color.toString().toUpperCase() + "]" + player.name).width(170f).pad(10);
button.add().grow(); button.add().grow();
button.addImage("icon-admin").size(14 * 2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5); button.addImage("icon-admin").size(14 * 2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5).get().updateVisibility();
if((Net.server() || players[0].isAdmin) && !player.isLocal && (!player.isAdmin || Net.server())){ if((Net.server() || players[0].isAdmin) && !player.isLocal && (!player.isAdmin || Net.server())){
button.add().growY(); button.add().growY();
@@ -124,12 +124,13 @@ public class PlayerListFragment extends Fragment{
}else{ }else{
ui.showConfirm("$text.confirm", "$text.confirmadmin", () -> netServer.admins.adminPlayer(id, player.usid)); ui.showConfirm("$text.confirm", "$text.confirmadmin", () -> netServer.admins.adminPlayer(id, player.usid));
} }
}).update(b -> { })
b.setChecked(player.isAdmin); .update(b -> b.setChecked(player.isAdmin))
b.setDisabled(Net.client()); .disabled(b -> Net.client())
}).get().setTouchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled); .touchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled)
.checked(player.isAdmin);
t.addImageButton("icon-zoom-small", 14 * 2, () -> Call.onAdminRequest(player, AdminAction.trace)); t.addImageButton("icon-zoom-small", 14 * 2, () -> ui.showError("Currently unimplemented.")/*Call.onAdminRequest(player, AdminAction.trace)*/);
}).padRight(12).padTop(-5).padLeft(0).padBottom(-10).size(bs + 10f, bs); }).padRight(12).padTop(-5).padLeft(0).padBottom(-10).size(bs + 10f, bs);
@@ -90,7 +90,7 @@ public abstract class BaseBlock extends MappableContent{
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return hasLiquids && tile.entity.liquids.get(liquid) + amount < liquidCapacity && return hasLiquids && tile.entity.liquids.get(liquid) + amount < liquidCapacity &&
(!singleLiquid || (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f)) && (!singleLiquid || (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f)) &&
(!consumes.has(ConsumeLiquid.class) || consumes.liquid() == liquid); (!consumes.has(ConsumeLiquid.class) || consumes.liquid() == liquid);
} }
@@ -17,7 +17,6 @@ import static io.anuke.mindustry.Vars.*;
public class Build{ public class Build{
private static final Rectangle rect = new Rectangle(); private static final Rectangle rect = new Rectangle();
private static final Rectangle hitrect = new Rectangle();
/**Returns block type that was broken, or null if unsuccesful.*/ /**Returns block type that was broken, or null if unsuccesful.*/
public static void beginBreak(Team team, int x, int y){ public static void beginBreak(Team team, int x, int y){
+52 -64
View File
@@ -22,7 +22,6 @@ import static io.anuke.mindustry.Vars.*;
public class Tile implements PosTrait, TargetTrait{ public class Tile implements PosTrait, TargetTrait{
public static final Object tileSetLock = new Object();
/** /**
* The coordinates of the core tile this is linked to, in the form of two bytes packed into one. * The coordinates of the core tile this is linked to, in the form of two bytes packed into one.
* This is relative to the block it is linked to; negate coords to find the link. * This is relative to the block it is linked to; negate coords to find the link.
@@ -147,33 +146,27 @@ public class Tile implements PosTrait, TargetTrait{
} }
public void setBlock(Block type, int rotation){ public void setBlock(Block type, int rotation){
synchronized(tileSetLock){ preChanged();
preChanged(); if(rotation < 0) rotation = (-rotation + 2);
if(rotation < 0) rotation = (-rotation + 2); this.wall = type;
this.wall = type; this.link = 0;
this.link = 0; setRotation((byte) (rotation % 4));
setRotation((byte) (rotation % 4)); changed();
changed();
}
} }
public void setBlock(Block type, Team team){ public void setBlock(Block type, Team team){
synchronized(tileSetLock){ preChanged();
preChanged(); this.wall = type;
this.wall = type; this.team = (byte)team.ordinal();
this.team = (byte)team.ordinal(); this.link = 0;
this.link = 0; changed();
changed();
}
} }
public void setBlock(Block type){ public void setBlock(Block type){
synchronized(tileSetLock){ preChanged();
preChanged(); this.wall = type;
this.wall = type; this.link = 0;
this.link = 0; changed();
changed();
}
} }
public void setFloor(Floor type){ public void setFloor(Floor type){
@@ -270,7 +263,7 @@ public class Tile implements PosTrait, TargetTrait{
* Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock. * Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock.
* This array contains all linked tiles, including this tile itself. * This array contains all linked tiles, including this tile itself.
*/ */
public synchronized Array<Tile> getLinkedTiles(Array<Tile> tmpArray){ public Array<Tile> getLinkedTiles(Array<Tile> tmpArray){
Block block = block(); Block block = block();
tmpArray.clear(); tmpArray.clear();
if(block.isMultiblock()){ if(block.isMultiblock()){
@@ -292,7 +285,7 @@ public class Tile implements PosTrait, TargetTrait{
* Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock. * Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock.
* This array contains all linked tiles, including this tile itself. * This array contains all linked tiles, including this tile itself.
*/ */
public synchronized Array<Tile> getLinkedTilesAs(Block block, Array<Tile> tmpArray){ public Array<Tile> getLinkedTilesAs(Block block, Array<Tile> tmpArray){
tmpArray.clear(); tmpArray.clear();
if(block.isMultiblock()){ if(block.isMultiblock()){
int offsetx = -(block.size - 1) / 2; int offsetx = -(block.size - 1) / 2;
@@ -394,52 +387,47 @@ public class Tile implements PosTrait, TargetTrait{
} }
private void preChanged(){ private void preChanged(){
synchronized(tileSetLock){ block().removed(this);
block().removed(this); if(entity != null){
if(entity != null){ entity.removeFromProximity();
entity.removeFromProximity();
}
team = 0;
} }
team = 0;
} }
private void changed(){ private void changed(){
if(entity != null){
synchronized(tileSetLock){ entity.remove();
if(entity != null){ entity = null;
entity.remove();
entity = null;
}
Block block = block();
if(block.hasEntity()){
entity = block.newEntity().init(this, block.update);
entity.cons = new ConsumeModule();
if(block.hasItems) entity.items = new ItemModule();
if(block.hasLiquids) entity.liquids = new LiquidModule();
if(block.hasPower){
entity.power = new PowerModule();
entity.power.graph.add(this);
}
if(!world.isGenerating()){
entity.updateProximity();
}
}else if(!(block instanceof BlockPart) && !world.isGenerating()){
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
for(GridPoint2 p : Geometry.d4){
Tile tile = world.tile(x + p.x, y + p.y);
if(tile != null){
tile = tile.target();
tile.block().onProximityUpdate(tile);
}
}
}
updateOcclusion();
} }
Block block = block();
if(block.hasEntity()){
entity = block.newEntity().init(this, block.update);
entity.cons = new ConsumeModule();
if(block.hasItems) entity.items = new ItemModule();
if(block.hasLiquids) entity.liquids = new LiquidModule();
if(block.hasPower){
entity.power = new PowerModule();
entity.power.graph.add(this);
}
if(!world.isGenerating()){
entity.updateProximity();
}
}else if(!(block instanceof BlockPart) && !world.isGenerating()){
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
for(GridPoint2 p : Geometry.d4){
Tile tile = world.tile(x + p.x, y + p.y);
if(tile != null){
tile = tile.target();
tile.block().onProximityUpdate(tile);
}
}
}
updateOcclusion();
world.notifyChanged(this); world.notifyChanged(this);
} }
@@ -396,7 +396,7 @@ public class Conveyor extends Block{
public void read(DataInput stream) throws IOException{ public void read(DataInput stream) throws IOException{
convey.clear(); convey.clear();
int amount = stream.readInt(); int amount = stream.readInt();
convey.ensureCapacity(amount); convey.ensureCapacity(Math.min(amount, 10));
for(int i = 0; i < amount; i++){ for(int i = 0; i < amount; i++){
convey.add(ItemPos.toLong(stream.readInt())); convey.add(ItemPos.toLong(stream.readInt()));
@@ -1,363 +0,0 @@
package io.anuke.mindustry.world.blocks.distribution;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Mathf;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.tilesize;
//TODO implement
public class WarpGate extends PowerBlock{
public static final Color[] colorArray = {Color.ROYAL, Color.ORANGE, Color.SCARLET, Color.LIME,
Color.PURPLE, Color.GOLD, Color.PINK, Color.LIGHT_GRAY};
public static final int colors = colorArray.length;
private static ObjectSet<Tile>[] teleporters = new ObjectSet[colors];
private static Color color = new Color();
private static byte lastColor = 0;
static{
for(int i = 0; i < colors; i++){
teleporters[i] = new ObjectSet<>();
}
}
protected int timerTeleport = timers++;
protected float warmupTime = 60f;
//time between teleports
protected float teleportMax = 400f;
protected float teleportLiquidUse = 0.3f;
protected Liquid inputLiquid = Liquids.cryofluid;
protected Effect activateEffect = BlockFx.teleportActivate;
protected Effect teleportEffect = BlockFx.teleport;
protected Effect teleportOutEffect = BlockFx.teleportOut;
private Array<Tile> removal = new Array<>();
private Array<Tile> returns = new Array<>();
public WarpGate(String name){
super(name);
update = true;
solid = true;
health = 80;
powerCapacity = 300f;
size = 3;
itemCapacity = 100;
hasLiquids = true;
hasItems = true;
liquidCapacity = 100f;
configurable = true;
}
@Remote(targets = Loc.both, called = Loc.both, forward = true)
public static void setTeleporterColor(Player player, Tile tile, byte color){
TeleporterEntity entity = tile.entity();
entity.color = color;
}
@Override
public void playerPlaced(Tile tile){
Call.setTeleporterColor(null, tile, lastColor);
}
@Override
public void draw(Tile tile){
super.draw(tile);
TeleporterEntity entity = tile.entity();
float time = entity.time;
float rad = entity.activeScl;
if(entity.liquidLackScl > 0.01f){
Graphics.setAdditiveBlending();
Draw.color(1f, 0.3f, 0.3f, 0.4f * entity.liquidLackScl);
Fill.square(tile.drawx(), tile.drawy(), size * tilesize);
Graphics.setNormalBlending();
}
Draw.color(getColor(tile, 0));
Draw.rect(name + "-top", tile.drawx(), tile.drawy());
Draw.reset();
if(rad <= 0.0001f) return;
Draw.color(getColor(tile, 0));
Fill.circle(tile.drawx(), tile.drawy(), rad * (7f + Mathf.absin(time + 55, 8f, 1f)));
Draw.color(getColor(tile, -1));
Fill.circle(tile.drawx(), tile.drawy(), rad * (2f + Mathf.absin(time, 7f, 3f)));
for(int i = 0; i < 11; i++){
Lines.swirl(tile.drawx(), tile.drawy(),
rad * (2f + i / 3f + Mathf.sin(time - i * 75, 20f + i, 3f)),
0.3f + Mathf.sin(time + i * 33, 10f + i, 0.1f),
time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f));
}
Draw.color(getColor(tile, 1));
Lines.stroke(2f);
Lines.circle(tile.drawx(), tile.drawy(), rad * (7f + Mathf.absin(time + 55, 8f, 1f)));
Lines.stroke(1f);
for(int i = 0; i < 11; i++){
Lines.swirl(tile.drawx(), tile.drawy(),
rad * (3f + i / 3f + Mathf.sin(time + i * 93, 20f + i, 3f)),
0.2f + Mathf.sin(time + i * 33, 10f + i, 0.1f),
time * (1f + Mathf.randomSeedRange(i + 1, 1f)) + Mathf.randomSeedRange(i, 360f));
}
Draw.reset();
}
@Override
public void update(Tile tile){
TeleporterEntity entity = tile.entity();
teleporters[entity.color].add(tile);
if(entity.items.total() > 0){
tryDump(tile);
}
if(!entity.active){
entity.activeScl = Mathf.lerpDelta(entity.activeScl, 0f, 0.01f);
if(entity.power.amount >= powerCapacity){
Color resultColor = new Color();
resultColor.set(getColor(tile, 0));
entity.active = true;
entity.power.amount = 0f;
Effects.effect(activateEffect, resultColor, tile.drawx(), tile.drawy());
}
}else{
entity.activeScl = Mathf.lerpDelta(entity.activeScl, 1f, 0.015f);
/*
if (entity.power.amount >= powerUsed) {
entity.power.amount -= powerUsed;
entity.powerLackScl = Mathf.lerpDelta(entity.powerLackScl, 0f, 0.1f);
}else{
entity.power.amount = 0f;
entity.powerLackScl = Mathf.lerpDelta(entity.powerLackScl, 1f, 0.1f);
}
if(entity.powerLackScl >= 0.999f){
catastrophicFailure(tile);
}
if (entity.liquids.amount >= liquidUsed) {
entity.liquids.amount -= liquidUsed;
entity.liquidLackScl = Mathf.lerpDelta(entity.liquidLackScl, 0f, 0.1f);
}else{
entity.liquids.amount = 0f;
entity.liquidLackScl = Mathf.lerpDelta(entity.liquidLackScl, 1f, 0.1f);
}*/
if(entity.liquidLackScl >= 0.999f){
catastrophicFailure(tile);
}
//TODO draw warning info!
if(entity.teleporting){
entity.speedScl = Mathf.lerpDelta(entity.speedScl, 2f, 0.01f);
//liquidUsed = Math.min(liquidCapacity, teleportLiquidUse * Timers.delta());
//if (entity.liquids.amount >= liquidUsed) {
// entity.liquids.amount -= liquidUsed;
//} else {
catastrophicFailure(tile);
//}
}else{
entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.04f);
}
entity.time += Timers.delta() * entity.speedScl;
/*
if (!entity.teleporting && entity.items.total() >= itemCapacity && entity.power.amount >= powerCapacity - 0.01f - powerUse &&
entity.timer.get(timerTeleport, teleportMax)) {
Array<Tile> testLinks = findLinks(tile);
if (testLinks.size == 0) return;
Color resultColor = new Color();
resultColor.set(getColor(tile, 0));
entity.teleporting = true;
Effects.effect(teleportEffect, resultColor, tile.drawx(), tile.drawy());
Timers.run(warmupTime, () -> {
Array<Tile> links = findLinks(tile);
for (Tile other : links) {
int canAccept = itemCapacity - other.entity.items.total();
int total = entity.items.total();
if (total == 0) break;
Effects.effect(teleportOutEffect, resultColor, other.drawx(), other.drawy());
for (int i = 0; i < canAccept && i < total; i++) {
other.entity.items.add(entity.items.take(), 1);
}
}
Effects.effect(teleportOutEffect, resultColor, tile.drawx(), tile.drawy());
entity.power.amount = 0f;
entity.teleporting = false;
});
}*/
}
}
@Override
public void buildTable(Tile tile, Table table){
TeleporterEntity entity = tile.entity();
//TODO call event for change
ButtonGroup<ImageButton> group = new ButtonGroup<>();
Table cont = new Table();
for(int i = 0; i < colors; i++){
final int f = i;
ImageButton button = cont.addImageButton("white", "toggle", 24, () -> {
lastColor = (byte) f;
Call.setTeleporterColor(null, tile, (byte) f);
}).size(34, 38).padBottom(-5.1f).group(group).get();
button.getStyle().imageUpColor = colorArray[f];
button.setChecked(entity.color == f);
if(i % 4 == 3){
cont.row();
}
}
table.add(cont);
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
TeleporterEntity entity = tile.entity();
return entity.items.total() < itemCapacity;
}
@Override
public TileEntity newEntity(){
return new TeleporterEntity();
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid;
}
@Override
public void onDestroyed(Tile tile){
super.onDestroyed(tile);
TeleporterEntity entity = tile.entity();
if(entity.activeScl < 0.5f) return;
//TODO catastrophic failure
}
private void catastrophicFailure(Tile tile){
tile.entity.damage(tile.entity.health + 1);
//TODO fail gloriously
}
private Color getColor(Tile tile, int shift){
TeleporterEntity entity = tile.entity();
Color target = colorArray[entity.color];
float ss = 0.5f;
float bs = 0.2f;
return Hue.shift(Hue.multiply(color.set(target), 1, ss), 2, shift * bs + (entity.speedScl - 1f) / 3f);
}
private Array<Tile> findLinks(Tile tile){
TeleporterEntity entity = tile.entity();
removal.clear();
returns.clear();
for(Tile other : teleporters[entity.color]){
if(other != tile){
if(other.block() instanceof WarpGate){
TeleporterEntity oe = other.entity();
if(!oe.active) continue;
if(oe.color != entity.color){
removal.add(other);
}else if(other.entity.items.total() == 0){
returns.add(other);
}
}else{
removal.add(other);
}
}
}
for(Tile remove : removal){
teleporters[entity.color].remove(remove);
}
return returns;
}
public static class TeleporterEntity extends TileEntity{
public byte color = 0;
public boolean teleporting;
public boolean active;
public float activeScl = 0f;
public float speedScl = 1f;
public float powerLackScl, liquidLackScl;
public float time;
@Override
public void write(DataOutput stream) throws IOException{
stream.writeByte(color);
stream.writeBoolean(active);
stream.writeFloat(activeScl);
stream.writeFloat(speedScl);
stream.writeFloat(powerLackScl);
}
@Override
public void read(DataInput stream) throws IOException{
color = stream.readByte();
active = stream.readBoolean();
activeScl = stream.readFloat();
speedScl = stream.readFloat();
powerLackScl = stream.readFloat();
}
}
}
@@ -94,7 +94,7 @@ public class PowerGraph{
public void clear(){ public void clear(){
for(Tile other : all){ for(Tile other : all){
other.entity.power.graph = null; if(other.entity != null && other.entity.power != null) other.entity.power.graph = null;
} }
all.clear(); all.clear();
producers.clear(); producers.clear();
@@ -25,7 +25,6 @@ import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.scene.ui.layout.Cell;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Threads;
import static io.anuke.mindustry.Vars.content; import static io.anuke.mindustry.Vars.content;
public class Drill extends Block{ public class Drill extends Block{
@@ -221,7 +220,7 @@ public class Drill extends Block{
@Override @Override
public boolean canPlaceOn(Tile tile){ public boolean canPlaceOn(Tile tile){
if(isMultiblock()){ if(isMultiblock()){
for(Tile other : tile.getLinkedTilesAs(this, Threads.isLogic() ? tempTiles : drawTiles)){ for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
if(isValid(other)){ if(isValid(other)){
return true; return true;
} }
@@ -51,7 +51,7 @@ public class UnitFactory extends Block{
hasItems = true; hasItems = true;
solid = false; solid = false;
itemCapacity = 10; itemCapacity = 10;
flags = EnumSet.of(BlockFlag.producer); flags = EnumSet.of(BlockFlag.producer, BlockFlag.target);
consumes.require(ConsumeItems.class); consumes.require(ConsumeItems.class);
} }
+1 -1
View File
@@ -2,5 +2,5 @@ app.version=4.0
app.id=io.anuke.mindustry app.id=io.anuke.mindustry
app.mainclass=io.anuke.mindustry.IOSLauncher app.mainclass=io.anuke.mindustry.IOSLauncher
app.executable=IOSLauncher app.executable=IOSLauncher
app.build=25 app.build=27
app.name=Mindustry app.name=Mindustry