diff --git a/build.gradle b/build.gradle index 8bc3fca889..f77d2ff19a 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ allprojects { appName = 'Mindustry' gdxVersion = '1.9.8' roboVMVersion = '2.3.0' - uCoreVersion = '8919cb7b6881d040fb720149779fcf58c1927893' + uCoreVersion = '2385d794f2cd3db2fb25d320f2223fa2148c25a0' getVersionString = { String buildVersion = getBuildVersion() diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 0bb62bbc96..ee3722141f 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -755,7 +755,7 @@ block.ghoul-factory.description = Produces heavy carpet bombers. block.dagger-factory.description = Produces basic ground units. block.titan-factory.description = Produces advanced, armored 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.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. diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index 6832c8e1d0..342aa94a77 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -452,7 +452,7 @@ liquid.oil.name = Petróleo liquid.cryofluid.name = Criogénico mech.alpha-mech.name = Alpha 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.delta-mech.name = Delta 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.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.weapon = Swarm Missiles +mech.omega-mech.weapon = Enjambre de misiles 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.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.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.weapon = Burst Missiles +mech.javelin-ship.weapon = Ráfaga de misiles mech.javelin-ship.ability = Discharge Booster mech.trident-ship.name = Tridente 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.temperature = [LIGHT_GRAY]Temperatura: {0} block.spawn.name = Punto de generación -block.core.name = núcleo +block.core.name = Núcleo block.metalfloor.name = Suelo de Metal -block.deepwater.name = aguas profundas -block.water.name = agua -block.lava.name = lava +block.deepwater.name = Aguas profundas +block.water.name = Agua +block.lava.name = Lava block.tar.name = Tar -block.blackstone.name = piedra negra -block.stone.name = piedra -block.dirt.name = tierra -block.sand.name = arena -block.ice.name = hielo -block.snow.name = nieve -block.grass.name = pasto -block.shrub.name = arbusto -block.rock.name = roca -block.blackrock.name = roca negra -block.icerock.name = roca de hielo +block.blackstone.name = Piedra negra +block.stone.name = Piedra +block.dirt.name = Tierra +block.sand.name = Arena +block.ice.name = Hielo +block.snow.name = Nieve +block.grass.name = Pasto +block.shrub.name = Arbusto +block.rock.name = Roca +block.blackrock.name = Roca negra +block.icerock.name = Roca de hielo block.copper-wall.name = Muro de cobre block.copper-wall-large.name = Muro de cobre grande 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.conduit.name = Conducto block.mechanical-pump.name = Bomba Mecánica -block.itemsource.name = Objeto Fuente -block.itemvoid.name = Objeto Vacío -block.liquidsource.name = Líquido Fuente -block.powervoid.name = Energía Vacía +block.itemsource.name = Fuente de objetos +block.itemvoid.name = Vacío de objetos +block.liquidsource.name = Fuente de líquidos +block.powervoid.name = Vacío de energía block.powerinfinite.name = Energía Infinita block.unloader.name = Descargador 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.phase-conduit.name = Conducto de Fase 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.bridge-conduit.name = Conducto Puente block.rotary-pump.name = Bomba Rotatoria @@ -620,15 +620,15 @@ block.overdrive-projector.name = Overdrive Projector block.force-projector.name = Force Projector block.arc.name = Arc block.rtg-generator.name = Generador RTG -block.spectre.name = Spectre +block.spectre.name = Espectro block.meltdown.name = Meltdown block.container.name = Contenedor -team.blue.name = azul -team.red.name = rojo -team.orange.name = naranja -team.none.name = gris -team.green.name = verde -team.purple.name = púrpura +team.blue.name = Azul +team.red.name = Rojo +team.orange.name = Naranja +team.none.name = Gris +team.green.name = Verde +team.purple.name = Púrpura unit.alpha-drone.name = Dron Alpha 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. diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index 4706b387dc..e22f8e40bd 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -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.google-play.description = listing par le store google play text.link.wiki.description = wiki officiel de mindustry . -text.linkfail = Failed to open link!\nThe URL has been copied to your cliboard. -text.editor.web = The web version does not support the editor!\nDownload the game to use it. +text.linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copié avec succès. +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.gameover = Partie terminé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.mech = Équiper ce mécha[accent] {0}[] text.mission.create = Créez[accent] {0}[] -text.none = +text.none = text.close = Fermer text.quit = Quitter text.maps = Cartes @@ -262,13 +262,13 @@ text.editor = Éditeur text.mapeditor = Éditeur de carte text.donate = Faire un\ndon text.connectfail = [crimson]Échec de la connexion au serveur : [accent]{0} -text.error.unreachable = Server unreachable. -text.error.invalidaddress = Invalid address. -text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! -text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! -text.error.alreadyconnected = Already connected. -text.error.mapnotfound = Map file not found! -text.error.any = Unkown network error. +text.error.unreachable = Server injoignable. +text.error.invalidaddress = Adresse invalide. +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 = 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 = Déjà connecté. +text.error.mapnotfound = Fichier de la carte introuvable! +text.error.any = Erreur réseau inconnue. text.settings.language = Langage text.settings.reset = Valeur par défaut. text.settings.rebind = Réatttribuer @@ -417,7 +417,7 @@ content.unit.name = Unités content.recipe.name = Blocs content.mech.name = Méchas 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.description = Un matériau de construction utile.Utilisé intensivement dans tout les blocs. 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.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.phase-fabric.name = Phase Fabric -item.phase-fabric.description = A near-weightless substance used in advanced electronics and self-repairing technology. +item.phase-fabric.name = Tissu phasé +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.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.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 @@ -500,7 +500,7 @@ block.metalfloor.name = Sol en métal block.deepwater.name = eau profonde block.water.name = eau block.lava.name = lave -block.tar.name = Tar +block.tar.name = pétrole block.blackstone.name = roche sombre block.stone.name = roche block.dirt.name = terre @@ -623,7 +623,7 @@ block.rtg-generator.name = G.T.R. block.spectre.name = Spectre block.meltdown.name = Meltdown 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.red.name = rouge 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.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". -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.dense-alloy-wall.description = A standard defensive block.\nAdequate protection from enemies. -block.dense-alloy-wall-large.description = A standard defensive block.\nAdequate protection from enemies.\nSpans multiple tiles. -block.thorium-wall.description = A strong defensive block.\nGood protection from enemies. -block.thorium-wall-large.description = A strong defensive block.\nGood protection from enemies.\nSpans multiple tiles. -block.phase-wall.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful. -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.surge-wall.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker. -block.surge-wall-large.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.\nSpans multiple tiles. -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-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.mend-projector.description = Periodically heals buildings in its vicinity. -block.overdrive-projector.description = Increases the speed of nearby buildings like drills and conveyors. -block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage through bullets. -block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy. -block.duo.description = A small, cheap turret. -block.arc.description = A small turret which shoots electricity in a random arc towards the enemy. -block.hail.description = A small artillery turret. -block.lancer.description = A medium-sized turret which shoots charged electricity beams. -block.wave.description = A medium-sized rapid-fire turret which shoots liquid bubbles. -block.salvo.description = A medium-sized turret which fires shots in salvos. -block.swarmer.description = A medium-sized turret which shoots burst missiles. -block.ripple.description = A large artillery turret which fires several shots simultaneously. -block.cyclone.description = A large rapid fire turret. -block.fuse.description = A large turret which shoots powerful short-range beams. -block.spectre.description = A large turret which shoots two powerful bullets at once. -block.meltdown.description = A large turret which shoots powerful long-range beams. -block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable. -block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors. -block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles. -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.mass-driver.description = Ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range. -block.smelter.description = Burns coal for smelting copper and lead into dense alloy. -block.arc-smelter.description = Smelts copper and lead into dense alloy by using an external power source. -block.silicon-smelter.description = Reduces sand with highly pure coke in order to produce silicon. -block.plastanium-compressor.description = Produces plastanium from oil and titanium. -block.phase-weaver.description = Produces phase fabric from radioactive thorium and high amounts of sand. -block.alloy-smelter.description = Produces surge alloy from titanium, lead, silicon and copper. -block.pulverizer.description = Crushes stone into sand. Useful when there is a lack of natural sand. -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.cryofluidmixer.description = Combines water and titanium into cryofluid which is much more efficient for cooling. -block.solidifer.description = Cools lava to stone at a fast pace. -block.melter.description = Heats up stone to very high temperatures to obtain lava. -block.incinerator.description = Gets rid of any excess item or liquid. -block.biomattercompressor.description = Compresses biomatter in order to retrieve oil. -block.separator.description = Exposes stone to water pressure in order to obtain various minerals contained in the stone. -block.centrifuge.description = More efficient than the separator, but also more expensive to build and requires power. -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-large.description = Has a larger radius than the power node and connects to up to six power sources, sinks or nodes. -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-large.description = Stores much more power than a regular battery. -block.combustion-generator.description = Generates power by burning oil or flammable materials. -block.turbine-generator.description = More efficient than a combustion generator, but requires additional water. -block.thermal-generator.description = Generates a large amount of power from lava. -block.solar-panel.description = Provides a small amount of power from the sun. -block.solar-panel-large.description = Provides much better power supply than a standard solar panel, but is also much more expensive to build. -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.rtg-generator.description = A radioisotope thermoelectric generator which does not require cooling but provides less power than a thorium reactor. -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.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.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.mechanical-drill.description = A cheap drill. When placed on appropriate tiles, outputs items at a slow pace indefinitely. -block.pneumatic-drill.description = An improved drill which is faster and able to process harder materials by making use of air pressure. -block.laser-drill.description = Allows drilling even faster through laser technology, but requires power. Additionally, radioactive thorium can be retrieved with this drill. -block.blast-drill.description = The ultimate drill. Requires large amounts of power. -block.water-extractor.description = Extracts water from the ground. Use it when there is no lake nearby. -block.cultivator.description = Cultivates the soil with water in order to obtain biomatter. -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.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.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.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.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.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.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.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.spirit-factory.description = Produces light drones which mine ore and repair blocks. -block.phantom-factory.description = Produces advanced drone units which are significantly more effective than a spirit drone. -block.wraith-factory.description = Produces fast, hit-and-run interceptor units. -block.ghoul-factory.description = Produces heavy carpet bombers. -block.dagger-factory.description = Produces basic ground units. -block.titan-factory.description = Produces advanced, armored ground units. -block.fortress-factory.description = Produces heavy artillery ground units. -block.revenant-factory.description = Produces heavy laser ground units. -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.conduit.description = Basic liquid transport block. Works like a conveyor, but with liquids. Best used with extractors, pumps or other conduits. -block.pulse-conduit.description = Advanced liquid transport block. Transports liquids faster and stores more than standard conduits. -block.phase-conduit.description = Advanced liquid transport block. Uses power to teleport liquids to a connected phase conduit over several tiles. -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-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-junction.description = Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations. -block.bridge-conduit.description = Advanced liquid transport block. Allows transporting liquids over up to 3 tiles of any terrain or building. -block.mechanical-pump.description = A cheap pump with slow output, but no power consumption. -block.rotary-pump.description = An advanced pump which doubles up speed by using power. -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.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.distributor.description = An advanced router which splits items to up to 7 other directions equally. -block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building. -block.alpha-mech-pad.description = When given enough power, rebuilds your ship into the[accent] Alpha[] mech. -block.itemsource.description = Infinitely outputs items. Sandbox only. -block.liquidsource.description = Infinitely outputs liquids. Sandbox only. -block.itemvoid.description = Destroys any items which go into it without using power. Sandbox only. -block.powerinfinite.description = Infinitely outputs power. Sandbox only. -block.powervoid.description = Voids all power inputted into it. Sandbox only. -liquid.water.description = Commonly used for cooling machines and waste processing. -liquid.lava.description = Can be transformed into[LIGHT_GRAY] stone[], used for generating power or used as ammo for certain turrets. -liquid.oil.description = Can be burnt, exploded or used as a coolant. -liquid.cryofluid.description = The most efficient liquid for cooling things down. +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 = 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 = Un bloc défensif standard .\nProcure une bonne protection contre les ennemis. +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 = Un bloc défensif puissant.\nProcure une très bonne protection contre les ennemis. +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 = Moins puissant qu'un mur en Thorium mais déviera les balles sauf si elles sont trop puissantes. +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 = Le plus puissant bloc défensif .\nA une faible chance de créer des éclairs vers les ennemis . +block.surge-wall-large.description = Le plus puissant bloc défensif .\nA une faible chance de créer des éclairs vers les ennemis .\nFait du 2 sur 2. +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 = 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 = Soigne périodiquement les batiments autour de lui. +block.overdrive-projector.description = Accélère les batiments autour de lui, notamment les foreuses et les convoyeurs. +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 = Blesse les ennemis qui marchent dessus. Quasiment invisble pour l'ennemi. +block.duo.description = une petite tourelle avec un coût faible . +block.arc.description = une petite tourelle tirant des arcs électrques vers les ennemis. +block.hail.description = une petite tourelle d'artillerie. +block.lancer.description = une tourelle de taille moyenne tirant des rayons chargés en électricité. +block.wave.description = une tourelle de taille moyenne tirant rapidement des bulles de liquide . +block.salvo.description = une tourelle de taille moyenne qui tire par salves. +block.swarmer.description = une tourelle de taille moyenne qui tire des missiles qui se dispersent. +block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs tirs simultanément. +block.cyclone.description = Une grande tourelle tirant rapidement ... très rapidement . +block.fuse.description = Une grande tourelle qui tire de puissants rayons lasers avec une faible portée. +block.spectre.description = Une grande tourelle qui tire deux puissantes balles simultanément. +block.meltdown.description = Une grande tourelle tirant de puissants rayons lasers avec une grande portée. +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 = Convoyeur avancé . Déplace les objets plus rapidement que les convoyeurs standards. +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 = 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 = 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 = Brûle du charbon pour fondre du cuivre et du plomb en un alliage lourd. +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 = Utilise du sable, du charbon et de l'énergie afin de produire du silicone. +block.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane. +block.phase-weaver.description = Produit du tissu phasé à partir de thorium et de grandes quantités de sable. +block.alloy-smelter.description = Produit un alliage superchargé à l'aide de titane de plomb de silicone et de cuivre. +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 = Mélange charbon, plomb et sable en l'hautement inflammable pyratite. +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 = Combine de l'eau et du titane en un liquide cryogénique bien plus efficace pour refroidir. +block.solidifer.description = Refroidit de la lave en pierre très rapidement. +block.melter.description = chauffe de la pierre à de très hautes températures pour obtenir de la lave. +block.incinerator.description = Permet de se débarasser de n'importe quel objet ou liquide en exces . +block.biomattercompressor.description = Compresse de la biomasse pour en récupérer le pétrole. +block.separator.description = Expose la pierre à de l'eau sous pression afin d'obtenir différents minéraux contenus dansla pierre. +block.centrifuge.description = Plus efficace qu'un séparateur mais aussi plus cher à construire et demande plus d'énergie. +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 = 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 = 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 = Stocke bien plus d'énergie qu'une batterie normale. +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 = Plus efficace qu'un générateur à combustion, mais requiert de l'eau . +block.thermal-generator.description = Génère une grande quantité d'énergie à partir de lave . +block.solar-panel.description = Génère une faible quantité d'énergie . +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 = 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 = Un générateur thermo-électrique à radioisotope qui ne demande pas de refroidissement mais produit moins d'énergie qu'un réacteur à Thorium. +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 = 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 = 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 = 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 = 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 = 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 = La Foreuse ultime . Demande une grande quantité d'énergie . +block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'eau à proximité. +block.cultivator.description = Cultive le sol avec de l'eau afin d'obtenir de la biomasse. +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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = Produit des petits drones qui réparent les batiments et minent des matériaux. +block.phantom-factory.description = Produit des drones avancés qui sont bien plus efficaces que les drones spirituels. +block.wraith-factory.description = Produit des intercepteurs rapides qui harcèlent l'ennemi. +block.ghoul-factory.description = Produit des bombardiers lourds. +block.dagger-factory.description = Produit des unités terrestres basiques. +block.titan-factory.description = Produit des unités terrestres avancées et cuirassées. +block.fortress-factory.description = Produit des unités terrestres d'artillerie lourde . +block.revenant-factory.description = Produit des unités terrestres lourdes avec des lasers. +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 = 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 = 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 = tuyau avancé permettant le transport de liquide . Transporte les liquides plus rapidement et en stocke plus que les tuyaux standards. +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 = 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 = 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 = 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 = 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 = Une pompe de faible prix pompant lentement, mais ne consomme pas d'énergie. +block.rotary-pump.description = Une pompe avancée qui double sa vitesse en utilisant de l'énergie. +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 = 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 = Un routeur avancé qui sépare les objets jusqu'à 7 autres directions équitablement. +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 = Avec assez d'énergie, reconstruit votre vaisseau en un mécha [accent] Alpha[]. +block.itemsource.description = Produit des objets à l'infini. Bac à sable uniquement . +block.liquidsource.description = Source de liquide infinie . Bac à sable uniquement. +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 = Produit de l'énergie à l'infini. Bac à sable uniquement. +block.powervoid.description = Supprime toute l'énergie allant à l'intérieur.Bac à sable uniquement +liquid.water.description = Couramment utilisé pour le refroidissement et le traitement des déchets. +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 = Peut être brûlé, utilisé comme explosif ou comme liquide de refroidissement. +liquid.cryofluid.description = Le liquide de refroidissement le plus efficace. diff --git a/core/assets/bundles/bundle_fr_BE.properties b/core/assets/bundles/bundle_fr_BE.properties index e178e665f9..128921f04e 100644 --- a/core/assets/bundles/bundle_fr_BE.properties +++ b/core/assets/bundles/bundle_fr_BE.properties @@ -73,7 +73,7 @@ text.nextmission = Prochaine Mission text.maps.none = [LIGHT_GRAY]Aucune carte trouvée! text.about.button = À propos text.name = Nom: -text.filename = File Name: +text.filename = Nom du fichier: text.unlocked = Nouveau bloc debloqué! text.unlocked.plural = Nouveaux blocs débloqués! text.players = {0} joueurs en ligne @@ -262,13 +262,13 @@ text.editor = Éditeur text.mapeditor = Éditeur de carte text.donate = Faire un\ndon text.connectfail = [crimson]Échec de la connexion au serveur: [accent]{0} -text.error.unreachable = Server unreachable. -text.error.invalidaddress = Invalid address. -text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! -text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! -text.error.alreadyconnected = Already connected. -text.error.mapnotfound = Map file not found! -text.error.any = Unkown network error. +text.error.unreachable = Serveur inaccessible. +text.error.invalidaddress = Adresse invalide. +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 = 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 = Déjà connecté. +text.error.mapnotfound = Fichier de carte introuvable ! +text.error.any = Erreur réseau inconnue. text.settings.language = Langage text.settings.reset = Valeur par défaut. text.settings.rebind = Réatttribuer @@ -419,9 +419,9 @@ content.mech.name = Mécha 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.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.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.description = Un carburant commun et facile à obtenir. item.dense-alloy.name = Alliage lourd @@ -623,7 +623,7 @@ block.rtg-generator.name = G.T.R. block.spectre.name = Spectre block.meltdown.name = Meltdown 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.red.name = Rouge team.orange.name = Orange @@ -632,7 +632,7 @@ team.green.name = Vert team.purple.name = Violet unit.alpha-drone.name = Drone alpha 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.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 @@ -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.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.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.dense-alloy-wall.description = A standard defensive block.\nAdequate protection from enemies. -block.dense-alloy-wall-large.description = A standard defensive block.\nAdequate protection from enemies.\nSpans multiple tiles. -block.thorium-wall.description = A strong defensive block.\nGood protection from enemies. -block.thorium-wall-large.description = A strong defensive block.\nGood protection from enemies.\nSpans multiple tiles. -block.phase-wall.description = Not as strong as a thorium wall but will deflect bullets unless they are too powerful. -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.surge-wall.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker. -block.surge-wall-large.description = The strongest defensive block.\nHas a small chance of triggering lightning towards the attacker.\nSpans multiple tiles. -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-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.mend-projector.description = Periodically heals buildings in its vicinity. -block.overdrive-projector.description = Increases the speed of nearby buildings like drills and conveyors. -block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage through bullets. -block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy. -block.duo.description = A small, cheap turret. -block.arc.description = A small turret which shoots electricity in a random arc towards the enemy. -block.hail.description = A small artillery turret. -block.lancer.description = A medium-sized turret which shoots charged electricity beams. -block.wave.description = A medium-sized rapid-fire turret which shoots liquid bubbles. -block.salvo.description = A medium-sized turret which fires shots in salvos. -block.swarmer.description = A medium-sized turret which shoots burst missiles. -block.ripple.description = A large artillery turret which fires several shots simultaneously. -block.cyclone.description = A large rapid fire turret. -block.fuse.description = A large turret which shoots powerful short-range beams. -block.spectre.description = A large turret which shoots two powerful bullets at once. -block.meltdown.description = A large turret which shoots powerful long-range beams. -block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable. -block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors. -block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles. -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.mass-driver.description = Ultimate item transport block. Collects several items and then shoots them to another mass driver over a long range. -block.smelter.description = Burns coal for smelting copper and lead into dense alloy. -block.arc-smelter.description = Smelts copper and lead into dense alloy by using an external power source. -block.silicon-smelter.description = Reduces sand with highly pure coke in order to produce silicon. -block.plastanium-compressor.description = Produces plastanium from oil and titanium. -block.phase-weaver.description = Produces phase fabric from radioactive thorium and high amounts of sand. -block.alloy-smelter.description = Produces surge alloy from titanium, lead, silicon and copper. -block.pulverizer.description = Crushes stone into sand. Useful when there is a lack of natural sand. +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 = Un bloc défensif bon marché.\nUtile pour protéger le noyau et les tourelles lors des premières vagues. +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.description = Un bloc défensif standard.\nUne protection adéquate contre les ennemis. +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.description = Un puissant bloc défensif.\nBonne protection contre les ennemis. +block.thorium-wall-large.description = Un puissant bloc défensif.\nBonne protection contre les ennemis.\nS'étend sur plusieurs tuiles. +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.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.description = Le bloc défensif le plus puissant.\nPeu de chances de déclencher des éclairs en direction de l'attaquant. +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.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.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.mend-projector.description = Guérit périodiquement les bâtiments situés à proximité. +block.overdrive-projector.description = Augmente la vitesse des bâtiments à proximité, comme les foreuses et les convoyeurs. +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.shock-mine.description = Endommage les ennemis qui marchent sur la mine. Presque invisible à l'ennemi. +block.duo.description =Une petite tourelle pas chère. +block.arc.description = Une petite tourelle qui tire de l'électricité dans un arc au hasard vers l'ennemi. +block.hail.description = Une petite tourelle d'artillerie. +block.lancer.description = Une tourelle de taille moyenne qui tire des faisceaux d’électricité chargés. +block.wave.description = Une tourelle de taille moyenne à tir rapide qui tire des bulles de liquide. +block.salvo.description = Une tourelle de taille moyenne qui tire des coups de salves. +block.swarmer.description = Une tourelle de taille moyenne qui tire des missiles éclatés. +block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs coups simultanément. +block.cyclone.description = Une grande tourelle à tir rapide. +block.fuse.description = Une grande tourelle qui tire de puissants faisceaux à courte portée. +block.spectre.description = Une grande tourelle qui tire deux balles puissantes à la fois. +block.meltdown.description = Une grande tourelle qui tire de puissants faisceaux à longue portée. +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.titanium-conveyor.description = Bloc de transport d'articles avancé.\nDéplace les articles plus rapidement que les convoyeurs standard. +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.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.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.smelter.description = Brûle le charbon pour fondre le cuivre et le plomb en un alliage dense. +block.arc-smelter.description = Fait fondre le cuivre et le plomb en un alliage dense en utilisant une source d'alimentation externe. +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.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane. +block.phase-weaver.description = Produit un tissu de phase à partir de thorium radioactif et de grandes quantités de sable. +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.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. diff --git a/core/assets/fonts/pixel.ttf b/core/assets/fonts/pixel.ttf index 137848310c..177fff5182 100644 Binary files a/core/assets/fonts/pixel.ttf and b/core/assets/fonts/pixel.ttf differ diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index 1420f0c838..54bd88f2f3 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -4,12 +4,11 @@ import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.blocks.distribution.WarpGate; import io.anuke.mindustry.world.blocks.power.*; public class PowerBlocks extends BlockList implements ContentList{ public static Block combustionGenerator, thermalGenerator, turbineGenerator, rtgGenerator, solarPanel, largeSolarPanel, - thoriumReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge, warpGate; + thoriumReactor, fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge; @Override public void load(){ @@ -85,7 +84,5 @@ public class PowerBlocks extends BlockList implements ContentList{ shadow = "shadow-round-2"; }}; - warpGate = new WarpGate("warp-gate"); - } } diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index f4aa97922b..471eba010e 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -172,7 +172,6 @@ public class Logic extends Module{ @Override public void update(){ - if(threads.isEnabled() && !threads.isOnThread()) return; if(Vars.control != null){ control.runUpdateLogic(); @@ -238,9 +237,5 @@ public class Logic extends Module{ checkGameOver(); } } - - if(threads.isEnabled()){ - netServer.update(); - } } } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 91b52c1cdf..12a644687d 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -399,11 +399,11 @@ public class NetClient extends Module{ quiet = true; } - public synchronized void addRemovedEntity(int id){ + public void addRemovedEntity(int id){ removed.add(id); } - public synchronized boolean isEntityUsed(int id){ + public boolean isEntityUsed(int id){ return removed.contains(id); } @@ -414,11 +414,9 @@ public class NetClient extends Module{ BuildRequest[] requests; - synchronized(player.getPlaceQueue()){ - requests = new BuildRequest[player.getPlaceQueue().size]; - for(int i = 0; i < requests.length; i++){ - requests[i] = player.getPlaceQueue().get(i); - } + requests = new BuildRequest[player.getPlaceQueue().size]; + for(int i = 0; i < requests.length; i++){ + requests[i] = player.getPlaceQueue().get(i); } Call.onClientShapshot(lastSent++, TimeUtils.millis(), player.x, player.y, diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 6fefd332ba..756da10efe 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -416,7 +416,6 @@ public class NetServer extends Module{ } public void update(){ - if(threads.isEnabled() && !threads.isOnThread()) return; if(!headless && !closing && Net.server() && state.is(State.menu)){ closing = true; diff --git a/core/src/io/anuke/mindustry/core/ThreadHandler.java b/core/src/io/anuke/mindustry/core/ThreadHandler.java index f439a6670e..c89a816140 100644 --- a/core/src/io/anuke/mindustry/core/ThreadHandler.java +++ b/core/src/io/anuke/mindustry/core/ThreadHandler.java @@ -1,80 +1,34 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.utils.Queue; import com.badlogic.gdx.utils.TimeUtils; import io.anuke.ucore.core.Settings; 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; -import static io.anuke.mindustry.Vars.logic; - -public class ThreadHandler implements ThreadInfoProvider{ - private final Queue 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; +public class ThreadHandler{ private long lastFrameTime; public ThreadHandler(){ - Threads.setThreadInfoProvider(this); - graphicsThread = Thread.currentThread(); - Timers.setDeltaProvider(() -> { - float result = isOnThread() ? delta : Gdx.graphics.getDeltaTime() * 60f; - return Math.min(Float.isNaN(result) ? 1f : result, 15f); + float result = Gdx.graphics.getDeltaTime() * 60f; + return Math.min(Float.isNaN(result) || Float.isInfinite(result) ? 1f : result, 15f); }); } public void run(Runnable r){ - if(enabled){ - synchronized(toRun){ - toRun.addLast(r); - } - }else{ - r.run(); - } + r.run(); } public void runGraphics(Runnable r){ - if(enabled){ - Gdx.app.postRunnable(r); - }else{ - r.run(); - } + r.run(); } public void runDelay(Runnable r){ - if(enabled){ - synchronized(toRun){ - toRun.addLast(r); - } - }else{ - Gdx.app.postRunnable(r); - } - } - - public int getTPS(){ - if(smoothDelta == 0f){ - return 60; - } - return (int) (60 / smoothDelta); + Gdx.app.postRunnable(r); } public long getFrameID(){ - return enabled ? frame : Gdx.graphics.getFrameId(); - } - - public float getFramesSinceUpdate(){ - return framesSinceUpdate; + return Gdx.graphics.getFrameId(); } 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); - } - } } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 8120e2212a..ab1c29244c 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -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.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; -import io.anuke.ucore.util.Threads; import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.scene.actions.Actions.*; @@ -155,6 +154,7 @@ public class UI extends SceneModule{ load = new LoadDialog(); levels = new CustomGameDialog(); language = new LanguageDialog(); + unlocks = new UnlocksDialog(); settings = new SettingsMenuDialog(); host = new HostDialog(); paused = new PausedDialog(); @@ -165,7 +165,6 @@ public class UI extends SceneModule{ traces = new TraceDialog(); maps = new MapsDialog(); localplayers = new LocalPlayerDialog(); - unlocks = new UnlocksDialog(); content = new ContentInfoDialog(); sectors = new SectorsDialog(); missions = new MissionDialog(); @@ -240,8 +239,6 @@ public class UI extends SceneModule{ } public void showInfoFade(String info){ - Threads.assertGraphics(); - Table table = new Table(); table.setFillParent(true); table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); @@ -250,9 +247,7 @@ public class UI extends SceneModule{ } public void showInfo(String info){ - Threads.assertGraphics(); - - new Dialog("$text.info.title", "dialog"){{ + new Dialog("", "dialog"){{ getCell(content()).growX(); 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); @@ -260,9 +255,7 @@ public class UI extends SceneModule{ } public void showInfo(String info, Runnable clicked){ - Threads.assertGraphics(); - - new Dialog("$text.info.title", "dialog"){{ + new Dialog("", "dialog"){{ getCell(content()).growX(); content().margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center); buttons().addButton("$text.ok", () -> { diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index db16312924..2a15fa770b 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -16,6 +16,7 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Trail; +import io.anuke.mindustry.io.TypeIO; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetConnection; 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.*/ public void drawBuildRequests(){ - synchronized(getPlaceQueue()){ - for(BuildRequest request : getPlaceQueue()){ - if(getCurrentRequest() == request) continue; + for(BuildRequest request : getPlaceQueue()){ + if(getCurrentRequest() == request) continue; - if(request.breaking){ - Block block = world.tile(request.x, request.y).target().block(); + if(request.breaking){ + Block block = world.tile(request.x, request.y).target().block(); - //draw removal request - Lines.stroke(2f); + //draw removal request + 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( - request.x * tilesize + block.offset(), - request.y * tilesize + block.offset() - 1, - rad); + Lines.square( + request.x * tilesize + block.offset(), + request.y * tilesize + block.offset() - 1, + rad); - Draw.color(Palette.remove); + Draw.color(Palette.remove); - Lines.square( - request.x * tilesize + block.offset(), - request.y * tilesize + block.offset(), - rad); - }else{ - //draw place request - Lines.stroke(2f); + Lines.square( + request.x * tilesize + block.offset(), + request.y * tilesize + block.offset(), + rad); + }else{ + //draw place request + 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( - request.x * tilesize + request.recipe.result.offset(), - request.y * tilesize + request.recipe.result.offset() - 1, - rad); + Lines.square( + request.x * tilesize + request.recipe.result.offset(), + request.y * tilesize + request.recipe.result.offset() - 1, + rad); - Draw.color(Palette.accent); + Draw.color(Palette.accent); - Lines.square( - request.x * tilesize + request.recipe.result.offset(), - request.y * tilesize + request.recipe.result.offset(), - rad); - } + Lines.square( + request.x * tilesize + request.recipe.result.offset(), + request.y * tilesize + request.recipe.result.offset(), + rad); } - - Draw.reset(); } + + Draw.reset(); } //endregion @@ -853,7 +852,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra @Override public void write(DataOutput buffer) throws IOException{ 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.writeInt(Color.rgba8888(color)); 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{ float lastx = x, lasty = y, lastrot = rotation; super.readSave(buffer); - name = buffer.readUTF(); + name = TypeIO.readStringData(buffer); byte bools = buffer.readByte(); isAdmin = (bools & 1) != 0; dead = (bools & 2) != 0; diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index 910d36d10f..10aec5f47b 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -259,27 +259,25 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ @Override public void update(){ - synchronized(Tile.tileSetLock){ - //TODO better smoke effect, this one is awful - if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) && - Mathf.chance(0.009f * Timers.delta() * (1f - health / tile.block().health))){ + //TODO better smoke effect, this one is awful + if(health != 0 && health < tile.block().health && !(tile.block() instanceof Wall) && + 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(); - if(timeScaleDuration <= 0f || !tile.block().canOverdrive){ - timeScale = 1f; - } + timeScaleDuration -= Timers.delta(); + if(timeScaleDuration <= 0f || !tile.block().canOverdrive){ + timeScale = 1f; + } - if(health <= 0){ - onDeath(); - } - Block previous = tile.block(); - tile.block().update(tile); - if(tile.block() == previous && cons != null){ - cons.update(this); - } + if(health <= 0){ + onDeath(); + } + Block previous = tile.block(); + tile.block().update(tile); + if(tile.block() == previous && cons != null){ + cons.update(this); } } diff --git a/core/src/io/anuke/mindustry/entities/Units.java b/core/src/io/anuke/mindustry/entities/Units.java index e546b727cd..0d0584371c 100644 --- a/core/src/io/anuke/mindustry/entities/Units.java +++ b/core/src/io/anuke/mindustry/entities/Units.java @@ -13,7 +13,6 @@ import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Predicate; import io.anuke.ucore.util.EnumSet; import io.anuke.ucore.util.Geometry; -import io.anuke.ucore.util.Threads; import static io.anuke.mindustry.Vars.*; @@ -63,45 +62,20 @@ public class Units{ /**Can be called from any thread.*/ public static boolean anyEntities(Rectangle rect){ - if(Threads.isLogic()){ - boolResult = false; + boolResult = false; - Units.getNearby(rect, unit -> { - if(boolResult) return; - if(!unit.isFlying()){ - unit.getHitbox(hitrect); + Units.getNearby(rect, unit -> { + if(boolResult) return; + if(!unit.isFlying()){ + unit.getHitbox(hitrect); - if(hitrect.overlaps(rect)){ - boolResult = true; - } + if(hitrect.overlaps(rect)){ + boolResult = true; } - }); - - return boolResult; - }else{ - boolResultGraphics = false; - - for(EntityGroup 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 -> { - if(u.isFlying()) return; - u.getHitbox(rectGraphics); - if(rectGraphics.overlaps(rect)){ - boolResultGraphics = true; - } - }); - - return boolResultGraphics; - } + return boolResult; } /**Returns whether there are any entities on this tile, with the hitbox expanded.*/ diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index a086bea466..3129e67c64 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -84,30 +84,28 @@ public interface BuilderTrait extends Entity{ } default void readBuilding(DataInput input, boolean applyChanges) throws IOException{ - synchronized(getPlaceQueue()){ - if(applyChanges) getPlaceQueue().clear(); + if(applyChanges) getPlaceQueue().clear(); - byte type = input.readByte(); - if(type != -1){ - int position = input.readInt(); - float progress = input.readFloat(); - BuildRequest request; + byte type = input.readByte(); + if(type != -1){ + int position = input.readInt(); + float progress = input.readFloat(); + BuildRequest request; - if(type == 1){ //remove - request = new BuildRequest(position % world.width(), position / world.width()); - }else{ //place - byte recipe = input.readByte(); - byte rotation = input.readByte(); - request = new BuildRequest(position % world.width(), position / world.width(), rotation, content.recipe(recipe)); - } + if(type == 1){ //remove + request = new BuildRequest(position % world.width(), position / world.width()); + }else{ //place + byte recipe = input.readByte(); + byte rotation = input.readByte(); + request = new BuildRequest(position % world.width(), position / world.width(), rotation, content.recipe(recipe)); + } - request.progress = progress; + request.progress = progress; - if(applyChanges){ - getPlaceQueue().addLast(request); - }else if(isBuilding()){ - getCurrentRequest().progress = progress; - } + if(applyChanges){ + getPlaceQueue().addLast(request); + }else if(isBuilding()){ + getCurrentRequest().progress = progress; } } } @@ -122,13 +120,11 @@ public interface BuilderTrait extends Entity{ * Otherwise, a new place request is added to the queue. */ default void replaceBuilding(int x, int y, int rotation, Recipe recipe){ - synchronized(getPlaceQueue()){ - for(BuildRequest request : getPlaceQueue()){ - if(request.x == x && request.y == y){ - clearBuilding(); - addBuildRequest(request); - return; - } + for(BuildRequest request : getPlaceQueue()){ + if(request.x == x && request.y == y){ + clearBuilding(); + addBuildRequest(request); + 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.*/ default void addBuildRequest(BuildRequest place){ - synchronized(getPlaceQueue()){ - for(BuildRequest request : getPlaceQueue()){ - if(request.x == place.x && request.y == place.y){ - return; - } + for(BuildRequest request : getPlaceQueue()){ + if(request.x == place.x && request.y == place.y){ + return; } - Tile tile = world.tile(place.x, place.y); - if(tile != null && tile.entity instanceof BuildEntity){ - place.progress = tile.entity().progress; - } - getPlaceQueue().addLast(place); } + Tile tile = world.tile(place.x, place.y); + if(tile != null && tile.entity instanceof BuildEntity){ + place.progress = tile.entity().progress; + } + getPlaceQueue().addLast(place); } /** @@ -161,9 +155,7 @@ public interface BuilderTrait extends Entity{ * May return null. */ 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*/ default void drawBuilding(Unit unit){ BuildRequest request; - - synchronized(getPlaceQueue()){ - if(!isBuilding()){ - if(getMineTile() != null){ - drawMining(unit); - } - return; + if(!isBuilding()){ + if(getMineTile() != null){ + drawMining(unit); } - - request = getCurrentRequest(); + return; } + request = getCurrentRequest(); + Tile tile = world.tile(request.x, request.y); if(unit.distanceTo(tile) > placeDistance){ @@ -311,10 +300,6 @@ public interface BuilderTrait extends Entity{ float x1 = tmptr[0].x, y1 = tmptr[0].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); diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java index 3a4a8c7c36..b9fe70456b 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java @@ -320,10 +320,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ if(target != null) behavior(); - if(!isWave && !isFlying()){ - x = Mathf.clamp(x, tilesize/2f, world.width() * tilesize - tilesize/2f); - y = Mathf.clamp(y, tilesize/2f, world.height() * tilesize - tilesize/2f); - } + x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize); + y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize); } @Override diff --git a/core/src/io/anuke/mindustry/entities/units/types/Drone.java b/core/src/io/anuke/mindustry/entities/units/types/Drone.java index 1c131f8c35..afc926d2b0 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Drone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Drone.java @@ -40,7 +40,6 @@ import static io.anuke.mindustry.Vars.unitGroups; import static io.anuke.mindustry.Vars.world; public class Drone extends FlyingUnit implements BuilderTrait{ - protected static float discoverRange = 120f; protected static int timerRepairEffect = timerIndex++; protected Item targetItem; @@ -250,14 +249,12 @@ public class Drone extends FlyingUnit implements BuilderTrait{ for(BaseUnit unit : group.all()){ if(unit instanceof Drone){ Drone drone = (Drone)unit; - synchronized(drone.getPlaceQueue()){ - if(drone.isBuilding()){ - //stop building if opposite building begins. - BuildRequest req = drone.getCurrentRequest(); - if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){ - drone.clearBuilding(); - drone.setState(drone.repair); - } + if(drone.isBuilding()){ + //stop building if opposite building begins. + BuildRequest req = drone.getCurrentRequest(); + if(req.breaking != event.breaking && req.x == event.tile.x && req.y == event.tile.y){ + drone.clearBuilding(); + drone.setState(drone.repair); } } diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 802e17f11f..a2e14ce0ba 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -105,32 +105,29 @@ public class BlockRenderer{ for(int x = minx; x <= maxx; x++){ for(int y = miny; y <= maxy; y++){ boolean expanded = (Math.abs(x - avgx) > rangex || Math.abs(y - avgy) > rangey); + Tile tile = world.rawTile(x, y); - synchronized(Tile.tileSetLock){ - Tile tile = world.rawTile(x, y); + if(tile != null){ + Block block = tile.block(); + Team team = tile.getTeam(); - if(tile != null){ - Block block = tile.block(); - Team team = tile.getTeam(); + if(!expanded && block != Blocks.air && world.isAccessible(x, y)){ + tile.block().drawShadow(tile); + } - if(!expanded && block != Blocks.air && world.isAccessible(x, y)){ - tile.block().drawShadow(tile); + if(block != Blocks.air){ + if(!expanded){ + addRequest(tile, Layer.block); + teamChecks.add(team.ordinal()); } - if(block != Blocks.air){ - if(!expanded){ - addRequest(tile, Layer.block); - teamChecks.add(team.ordinal()); + if(block.expanded || !expanded){ + if(block.layer != null && block.isLayer(tile)){ + addRequest(tile, block.layer); } - if(block.expanded || !expanded){ - if(block.layer != null && block.isLayer(tile)){ - addRequest(tile, block.layer); - } - - if(block.layer2 != null && block.isLayer2(tile)){ - addRequest(tile, block.layer2); - } + if(block.layer2 != null && block.isLayer2(tile)){ + addRequest(tile, block.layer2); } } } @@ -170,16 +167,14 @@ public class BlockRenderer{ layerBegins(req.layer); } - synchronized(Tile.tileSetLock){ - Block block = req.tile.block(); + Block block = req.tile.block(); - if(req.layer == Layer.block){ - block.draw(req.tile); - }else if(req.layer == block.layer){ - block.drawLayer(req.tile); - }else if(req.layer == block.layer2){ - block.drawLayer2(req.tile); - } + if(req.layer == Layer.block){ + block.draw(req.tile); + }else if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); } lastLayer = req.layer; @@ -198,17 +193,16 @@ public class BlockRenderer{ BlockRequest req = requests.get(index); if(req.tile.getTeam() != team) continue; - synchronized(Tile.tileSetLock){ - Block block = req.tile.block(); + Block block = req.tile.block(); - if(req.layer == Layer.block){ - block.draw(req.tile); - }else if(req.layer == block.layer){ - block.drawLayer(req.tile); - }else if(req.layer == block.layer2){ - block.drawLayer2(req.tile); - } + if(req.layer == Layer.block){ + block.draw(req.tile); + }else if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); } + } } diff --git a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java index dab7016c99..917bf12365 100644 --- a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java @@ -74,20 +74,18 @@ public class MinimapRenderer implements Disposable{ dx = Mathf.clamp(dx, sz, world.width() - 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); - Graphics.beginClip(x, y, w, h); + rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); + Graphics.beginClip(x, y, w, h); - for(Unit unit : units){ - float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h; - Draw.color(unit.getTeam().color); - Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2)); - } - - Draw.color(); - - Graphics.endClip(); + for(Unit unit : units){ + float rx = (unit.x - rect.x) / rect.width * w, ry = (unit.y - rect.y) / rect.width * h; + Draw.color(unit.getTeam().color); + Draw.rect("white", x + rx, y + ry, w / (sz * 2), h / (sz * 2)); } + + Draw.color(); + + Graphics.endClip(); } public TextureRegion getRegion(){ @@ -128,11 +126,9 @@ public class MinimapRenderer implements Disposable{ dx = Mathf.clamp(dx, sz, world.width() - 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); - units.clear(); - Units.getNearby(rect, units::add); - } + rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize); + units.clear(); + Units.getNearby(rect, units::add); } private int colorFor(Tile tile){ diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index 1c351764b0..a7598c200d 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -48,10 +48,7 @@ public class OverlayRenderer{ //draw config selected block if(input.frag.config.isShown()){ Tile tile = input.frag.config.getSelectedTile(); - - synchronized(Tile.tileSetLock){ - tile.block().drawConfigure(tile); - } + tile.block().drawConfigure(tile); } input.drawTop(); @@ -108,53 +105,52 @@ public class OverlayRenderer{ Draw.reset(); } - synchronized(Tile.tileSetLock){ - Block block = target.block(); - TileEntity entity = target.entity; + Block block = target.block(); + TileEntity entity = target.entity; - if(entity != null){ - int[] values = {0, 0}; - boolean[] doDraw = {false}; + if(entity != null){ + int[] values = {0, 0}; + boolean[] doDraw = {false}; - Runnable drawbars = () -> { - for(BlockBar bar : block.bars.list()){ - float offset = Mathf.sign(bar.top) * (block.size / 2f * tilesize + 2f + (bar.top ? values[0] : values[1])); + Runnable drawbars = () -> { + for(BlockBar bar : block.bars.list()){ + 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]){ - drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value); - } - - if(bar.top) - values[0]++; - else - values[1]++; + if(doDraw[0]){ + drawBar(bar.type.color, target.drawx(), target.drawy() + offset, value); } - }; - drawbars.run(); - - if(values[0] > 0){ - drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]); + if(bar.top) + values[0]++; + else + values[1]++; } + }; - if(values[1] > 0){ - drawEncloser(target.drawx(), target.drawy() - block.size * tilesize / 2f - 2f - values[1], values[1]); - } + drawbars.run(); - doDraw[0] = true; - values[0] = 0; - values[1] = 1; - - drawbars.run(); + if(values[0] > 0){ + drawEncloser(target.drawx(), target.drawy() + block.size * tilesize / 2f + 2f, values[0]); } + 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); + } } diff --git a/core/src/io/anuke/mindustry/graphics/Trail.java b/core/src/io/anuke/mindustry/graphics/Trail.java index 3d7f5fa87b..e223ae77d2 100644 --- a/core/src/io/anuke/mindustry/graphics/Trail.java +++ b/core/src/io/anuke/mindustry/graphics/Trail.java @@ -22,7 +22,7 @@ public class Trail{ 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){ points.clear(); } @@ -39,11 +39,11 @@ public class Trail{ lastY = cury; } - public synchronized void clear(){ + public void clear(){ points.clear(); } - public synchronized void draw(Color color, float stroke){ + public void draw(Color color, float stroke){ Draw.color(color); for(int i = 0; i < points.size - 2; i += 2){ diff --git a/core/src/io/anuke/mindustry/io/TypeIO.java b/core/src/io/anuke/mindustry/io/TypeIO.java index 7a0f2d3069..6061472054 100644 --- a/core/src/io/anuke/mindustry/io/TypeIO.java +++ b/core/src/io/anuke/mindustry/io/TypeIO.java @@ -23,15 +23,18 @@ import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; 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.charset.Charset; +import java.nio.charset.StandardCharsets; import static io.anuke.mindustry.Vars.*; /** Class for specifying read/write methods for code generation.*/ @SuppressWarnings("unused") public class TypeIO{ - private static final Charset charset = Charset.forName("UTF-8"); @WriteClass(Player.class) public static void writePlayer(ByteBuffer buffer, Player player){ @@ -329,19 +332,29 @@ public class TypeIO{ @WriteClass(String.class) public static void writeString(ByteBuffer buffer, String string){ 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); buffer.putShort((short) bytes.length); buffer.put(bytes); }else{ - buffer.putShort((short) -1); + buffer.put((byte) -1); } } @ReadClass(String.class) public static String readString(ByteBuffer buffer){ - short length = buffer.getShort(); + byte length = buffer.get(); 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); return new String(bytes, charset); }else{ @@ -362,4 +375,35 @@ public class TypeIO{ buffer.get(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; + } + } } diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index 4bd10f57fd..14ab812242 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -20,7 +20,6 @@ import io.anuke.ucore.function.Consumer; import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Pooling; -import io.anuke.ucore.util.Threads; import java.io.IOException; @@ -51,7 +50,6 @@ public class Net{ public static void showError(Throwable e){ if(!headless){ - Threads.assertGraphics(); Throwable t = e; while(t.getCause() != null){ diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index 5f23abf5b3..6e7687948e 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -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){ Player player = players[0]; @@ -165,6 +162,8 @@ public class NetworkIO{ world.sectors.createSector(Bits.getLeftShort(sector), Bits.getRightShort(sector)); world.setSector(world.sectors.get(sector)); world.getSector().completedMissions = missions; + }else{ + world.setSector(null); } ObjectMap tags = new ObjectMap<>(); diff --git a/core/src/io/anuke/mindustry/ui/Links.java b/core/src/io/anuke/mindustry/ui/Links.java index 09ebd501d8..891e44f7f8 100644 --- a/core/src/io/anuke/mindustry/ui/Links.java +++ b/core/src/io/anuke/mindustry/ui/Links.java @@ -8,13 +8,13 @@ public class Links{ private static void createLinks(){ links = new LinkEntry[]{ - new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")), - 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("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("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")), - new LinkEntry("dev-builds", "https://github.com/Anuken/Mindustry/wiki", Color.valueOf("fafbfc")) + new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")), + 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("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("github", "https://github.com/Anuken/Mindustry/", Color.valueOf("24292e")), + new LinkEntry("dev-builds", "https://jenkins.hellomouse.net/job/mindustry/", Color.valueOf("fafbfc")) }; } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java index afcf8abfd3..e4d2324560 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java @@ -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.utils.UIUtils; 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.ui; @@ -55,7 +56,7 @@ public class AboutDialog extends FloatingDialog{ }).size(h - 5, h); table.table(inset -> { - inset.add("[accent]" + link.name.replace("-", " ")).growX().left(); + inset.add("[accent]" + Strings.capitalize(link.name.replace("-", " "))).growX().left(); inset.row(); inset.labelWrap(link.description).width(w - 100f).color(Color.LIGHT_GRAY).growX(); }).padLeft(8); @@ -93,7 +94,7 @@ public class AboutDialog extends FloatingDialog{ public void showCredits(){ FloatingDialog dialog = new FloatingDialog("$text.credits"); dialog.addCloseButton(); - dialog.content().add("$text.credits.text"); + dialog.content().labelWrap("$text.credits.text").width(400f); dialog.show(); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index 26a90e46bc..728e94bae1 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -57,6 +57,9 @@ public class PausedDialog extends FloatingDialog{ hide(); }); + content().row(); + content().addButton("$text.unlocks", ui.unlocks::show); + content().row(); content().addButton("$text.settings", ui.settings::show); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 1c0f04abc9..a8931f70a7 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -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.checkPref("multithread", mobile, threads::setEnabled); - - if(Settings.getBool("multithread")){ - threads.setEnabled(true); - } if(!mobile){ graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b)); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java index 1fbd83d39b..78ec16761b 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java @@ -36,7 +36,7 @@ public class BlockConsumeFragment extends Fragment{ tile = tile.target(); if(tile != lastTile){ - if(tile.block().consumes.hasAny()){ + if(tile.getTeam() == players[0].getTeam() && tile.block().consumes.hasAny()){ show(tile); }else if(visible){ hide(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 7206e82db0..b2deb85ce9 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -126,7 +126,6 @@ public class HudFragment extends Fragment{ IntFormat tps = new IntFormat("text.tps"); IntFormat ping = new IntFormat("text.ping"); t.label(() -> fps.get(Gdx.graphics.getFramesPerSecond())).padRight(10); - t.label(() -> tps.get(threads.getTPS())).visible(() -> threads.isEnabled()); t.row(); if(Net.hasClient()){ t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2); diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java index 8b8633baf3..80a96b3ffb 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java @@ -97,7 +97,7 @@ public class PlayerListFragment extends Fragment{ button.labelWrap("[#" + player.color.toString().toUpperCase() + "]" + player.name).width(170f).pad(10); 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())){ button.add().growY(); @@ -124,12 +124,13 @@ public class PlayerListFragment extends Fragment{ }else{ ui.showConfirm("$text.confirm", "$text.confirmadmin", () -> netServer.admins.adminPlayer(id, player.usid)); } - }).update(b -> { - b.setChecked(player.isAdmin); - b.setDisabled(Net.client()); - }).get().setTouchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled); + }) + .update(b -> b.setChecked(player.isAdmin)) + .disabled(b -> Net.client()) + .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); diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index 6cc2c79119..6b3ef027e7 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -90,7 +90,7 @@ public abstract class BaseBlock extends MappableContent{ public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ 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); } diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index d596422410..6ffab178db 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -17,7 +17,6 @@ import static io.anuke.mindustry.Vars.*; public class Build{ private static final Rectangle rect = new Rectangle(); - private static final Rectangle hitrect = new Rectangle(); /**Returns block type that was broken, or null if unsuccesful.*/ public static void beginBreak(Team team, int x, int y){ diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index f6ea510048..b75b89e433 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -22,7 +22,6 @@ import static io.anuke.mindustry.Vars.*; 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. * 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){ - synchronized(tileSetLock){ - preChanged(); - if(rotation < 0) rotation = (-rotation + 2); - this.wall = type; - this.link = 0; - setRotation((byte) (rotation % 4)); - changed(); - } + preChanged(); + if(rotation < 0) rotation = (-rotation + 2); + this.wall = type; + this.link = 0; + setRotation((byte) (rotation % 4)); + changed(); } public void setBlock(Block type, Team team){ - synchronized(tileSetLock){ - preChanged(); - this.wall = type; - this.team = (byte)team.ordinal(); - this.link = 0; - changed(); - } + preChanged(); + this.wall = type; + this.team = (byte)team.ordinal(); + this.link = 0; + changed(); } public void setBlock(Block type){ - synchronized(tileSetLock){ - preChanged(); - this.wall = type; - this.link = 0; - changed(); - } + preChanged(); + this.wall = type; + this.link = 0; + changed(); } 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. * This array contains all linked tiles, including this tile itself. */ - public synchronized Array getLinkedTiles(Array tmpArray){ + public Array getLinkedTiles(Array tmpArray){ Block block = block(); tmpArray.clear(); 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. * This array contains all linked tiles, including this tile itself. */ - public synchronized Array getLinkedTilesAs(Block block, Array tmpArray){ + public Array getLinkedTilesAs(Block block, Array tmpArray){ tmpArray.clear(); if(block.isMultiblock()){ int offsetx = -(block.size - 1) / 2; @@ -394,52 +387,47 @@ public class Tile implements PosTrait, TargetTrait{ } private void preChanged(){ - synchronized(tileSetLock){ - block().removed(this); - if(entity != null){ - entity.removeFromProximity(); - } - team = 0; + block().removed(this); + if(entity != null){ + entity.removeFromProximity(); } + team = 0; } private void changed(){ - - synchronized(tileSetLock){ - if(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(); + if(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(); + world.notifyChanged(this); } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index 88034c0028..04f7bf3269 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -396,7 +396,7 @@ public class Conveyor extends Block{ public void read(DataInput stream) throws IOException{ convey.clear(); int amount = stream.readInt(); - convey.ensureCapacity(amount); + convey.ensureCapacity(Math.min(amount, 10)); for(int i = 0; i < amount; i++){ convey.add(ItemPos.toLong(stream.readInt())); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java b/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java deleted file mode 100644 index 5ea2c97709..0000000000 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java +++ /dev/null @@ -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[] 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 removal = new Array<>(); - private Array 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 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 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 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 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(); - } - } - -} diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java index 5fecfbeba3..b0c90960eb 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -94,7 +94,7 @@ public class PowerGraph{ public void clear(){ for(Tile other : all){ - other.entity.power.graph = null; + if(other.entity != null && other.entity.power != null) other.entity.power.graph = null; } all.clear(); producers.clear(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index ac641ca4f7..f0232c5cf3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -25,7 +25,6 @@ import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.layout.Cell; import io.anuke.ucore.util.Mathf; -import io.anuke.ucore.util.Threads; import static io.anuke.mindustry.Vars.content; public class Drill extends Block{ @@ -221,7 +220,7 @@ public class Drill extends Block{ @Override public boolean canPlaceOn(Tile tile){ if(isMultiblock()){ - for(Tile other : tile.getLinkedTilesAs(this, Threads.isLogic() ? tempTiles : drawTiles)){ + for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ if(isValid(other)){ return true; } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java index ae7b2f98c5..8566a8017e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java @@ -51,7 +51,7 @@ public class UnitFactory extends Block{ hasItems = true; solid = false; itemCapacity = 10; - flags = EnumSet.of(BlockFlag.producer); + flags = EnumSet.of(BlockFlag.producer, BlockFlag.target); consumes.require(ConsumeItems.class); } diff --git a/ios/robovm.properties b/ios/robovm.properties index f6b10f99b5..694b9dfa68 100644 --- a/ios/robovm.properties +++ b/ios/robovm.properties @@ -2,5 +2,5 @@ app.version=4.0 app.id=io.anuke.mindustry app.mainclass=io.anuke.mindustry.IOSLauncher app.executable=IOSLauncher -app.build=25 +app.build=27 app.name=Mindustry