# HG changeset patch # User Grigory Ustinov # Date 1541762122 -10800 # Node ID fae0dd90663b0ae81f3b1c6f0a86d3c382e7dd10 # Parent ec07ddc1a4a49784e25118f7c64ac173ed0c4518# Parent abbb74b9cb6236197afa232d21ccbdb8ff025430 Merge with master branch diff -r ec07ddc1a4a4 -r fae0dd90663b rust/fpnum/src/lib.rs --- a/rust/fpnum/src/lib.rs Fri Nov 09 14:12:00 2018 +0300 +++ b/rust/fpnum/src/lib.rs Fri Nov 09 14:15:22 2018 +0300 @@ -364,6 +364,11 @@ } #[inline] + pub fn is_zero(&self) -> bool { + self.x().is_zero() && self.y().is_zero() + } + + #[inline] pub fn max_norm(&self) -> FPNum { std::cmp::max(self.x().abs(), self.y().abs()) } diff -r ec07ddc1a4a4 -r fae0dd90663b rust/hwphysics/src/collision.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hwphysics/src/collision.rs Fri Nov 09 14:15:22 2018 +0300 @@ -0,0 +1,128 @@ +use std::{ + ops::RangeInclusive +}; + +use crate::{ + common::{GearId, GearData, GearDataProcessor}, + physics::PhysicsData, + grid::Grid +}; + +use fpnum::*; +use integral_geometry::{ + Point, Size, GridIndex +}; +use land2d::Land2D; + +pub fn fppoint_round(point: &FPPoint) -> Point { + Point::new(point.x().round() as i32, point.y().round() as i32) +} + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct CircleBounds { + pub center: FPPoint, + pub radius: FPNum +} + +impl CircleBounds { + pub fn intersects(&self, other: &CircleBounds) -> bool { + (other.center - self.center).is_in_range(self.radius + other.radius) + } + + pub fn rows(&self) -> impl Iterator)> { + let radius = self.radius.abs_round() as usize; + let center = Point::from_fppoint(&self.center); + (center.y as usize - radius..=center.y as usize + radius) + .map(move |row| (row, center.x as usize - radius..=center.x as usize + radius)) + } +} + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct CollisionData { + pub bounds: CircleBounds +} + +impl GearData for CollisionData {} + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ContactData { + pub elasticity: FPNum, + pub friction: FPNum +} + +impl GearData for ContactData {} + +struct EnabledCollisionsCollection { + gear_ids: Vec, + collisions: Vec +} + +impl EnabledCollisionsCollection { + fn new() -> Self { + Self { + gear_ids: Vec::new(), + collisions: Vec::new() + } + } + + fn push(&mut self, gear_id: GearId, collision: CollisionData) { + self.gear_ids.push(gear_id); + self.collisions.push(collision); + } + + fn iter(&self) -> impl Iterator { + self.gear_ids.iter().cloned().zip(self.collisions.iter()) + } +} + +pub struct CollisionProcessor { + grid: Grid, + enabled_collisions: EnabledCollisionsCollection, + + detected_collisions: DetectedCollisions, +} + +pub struct DetectedCollisions { + pub pairs: Vec<(GearId, GearId)>, + pub positions: Vec +} + +impl DetectedCollisions { + pub fn new(capacity: usize) -> Self { + Self { + pairs: Vec::with_capacity(capacity), + positions: Vec::with_capacity(capacity), + } + } + + pub fn push(&mut self, contact_gear_id1: GearId, contact_gear_id2: GearId, position: &FPPoint) { + self.pairs.push((contact_gear_id1, contact_gear_id2)); + self.positions.push(fppoint_round(&position)); + } +} + +impl CollisionProcessor { + pub fn new(size: Size) -> Self { + Self { + grid: Grid::new(size), + enabled_collisions: EnabledCollisionsCollection::new(), + detected_collisions: DetectedCollisions::new(0) + } + } + + pub fn process(&mut self, land: &Land2D, updates: &crate::physics::PositionUpdates) { + self.grid.check_collisions(&mut self.detected_collisions); + + for (gear_id, collision) in self.enabled_collisions.iter() { + if collision.bounds.rows().any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0)) { + self.detected_collisions.push(gear_id, 0, &collision.bounds.center) + } + } + } +} + +impl GearDataProcessor for CollisionProcessor { + fn add(&mut self, gear_id: GearId, gear_data: CollisionData) { + self.grid.insert_static(gear_id, &gear_data.bounds); + } +} \ No newline at end of file diff -r ec07ddc1a4a4 -r fae0dd90663b rust/hwphysics/src/common.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hwphysics/src/common.rs Fri Nov 09 14:15:22 2018 +0300 @@ -0,0 +1,10 @@ +pub type GearId = u16; +pub trait GearData {} + +pub trait GearDataProcessor { + fn add(&mut self, gear_id: GearId, gear_data: T); +} + +pub trait GearDataAggregator { + fn find_processor(&mut self) -> &mut GearDataProcessor; +} diff -r ec07ddc1a4a4 -r fae0dd90663b rust/hwphysics/src/grid.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hwphysics/src/grid.rs Fri Nov 09 14:15:22 2018 +0300 @@ -0,0 +1,91 @@ +use crate::{ + common::GearId, + collision::{ + fppoint_round, + CircleBounds, + DetectedCollisions + } +}; + +use integral_geometry::{ + Point, + Size, + GridIndex +}; +use fpnum::FPPoint; + +struct GridBin { + refs: Vec, + static_entries: Vec, + dynamic_entries: Vec +} + +impl GridBin { + fn new() -> Self { + Self { + refs: vec![], + static_entries: vec![], + dynamic_entries: vec![] + } + } +} + +const GRID_BIN_SIZE: usize = 128; + +pub struct Grid { + bins: Vec, + space_size: Size, + bins_count: Size, + index: GridIndex +} + +impl Grid { + pub fn new(size: Size) -> Self { + assert!(size.is_power_of_two()); + let bins_count = + Size::new(size.width / GRID_BIN_SIZE, + size.height / GRID_BIN_SIZE); + + Self { + bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(), + space_size: size, + bins_count, + index: Size::square(GRID_BIN_SIZE).to_grid_index() + } + } + + fn bin_index(&self, position: &FPPoint) -> Point { + self.index.map(fppoint_round(position)) + } + + fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin { + let index = self.bin_index(position); + &mut self.bins[index.x as usize * self.bins_count.width + index.y as usize] + } + + pub fn insert_static(&mut self, gear_id: GearId, bounds: &CircleBounds) { + self.lookup_bin(&bounds.center).static_entries.push(*bounds) + } + + pub fn insert_dynamic(&mut self, gear_id: GearId, bounds: &CircleBounds) { + self.lookup_bin(&bounds.center).dynamic_entries.push(*bounds) + } + + pub fn check_collisions(&self, collisions: &mut DetectedCollisions) { + for bin in &self.bins { + for bounds in &bin.dynamic_entries { + for other in &bin.dynamic_entries { + if bounds.intersects(other) && bounds != other { + collisions.push(0, 0, &bounds.center) + } + } + + for other in &bin.static_entries { + if bounds.intersects(other) { + collisions.push(0, 0, &bounds.center) + } + } + } + } + } +} \ No newline at end of file diff -r ec07ddc1a4a4 -r fae0dd90663b rust/hwphysics/src/lib.rs --- a/rust/hwphysics/src/lib.rs Fri Nov 09 14:12:00 2018 +0300 +++ b/rust/hwphysics/src/lib.rs Fri Nov 09 14:15:22 2018 +0300 @@ -1,195 +1,108 @@ -use std::{ - ops::RangeInclusive -}; +mod common; +mod physics; +mod grid; +mod collision; -use fpnum::*; -use integral_geometry::{ - Point, Size, GridIndex -}; +use fpnum::FPNum; +use integral_geometry::Size; use land2d::Land2D; -type Index = u16; - -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -struct PhysicsData { - position: FPPoint, - velocity: FPPoint, -} - -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -struct CollisionData { - bounds: CircleBounds -} - -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -struct ContactData { - elasticity: FPNum, - friction: FPNum -} - -pub struct PhysicsCollection { - positions: Vec, - velocities: Vec -} - -impl PhysicsCollection { - fn push(&mut self, data: PhysicsData) { - self.positions.push(data.position); - self.velocities.push(data.velocity); +use crate::{ + common::{ + GearId, + GearData, + GearDataAggregator, + GearDataProcessor + }, + physics::{ + PhysicsProcessor, + PhysicsData + }, + collision::{ + CollisionProcessor, + CollisionData, + ContactData } - - fn iter_mut_pos(&mut self) -> impl Iterator { - self.positions.iter_mut().zip(self.velocities.iter()) - } -} +}; pub struct JoinedData { + gear_id: GearId, physics: PhysicsData, collision: CollisionData, contact: ContactData } pub struct World { - enabled_physics: PhysicsCollection, - disabled_physics: Vec, - - enabled_collision: Vec, - disabled_collision: Vec, - grid: Grid, - - physics_cleanup: Vec, - collision_output: Vec<(Index, Index)>, - land_collision_output: Vec -} - -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -struct CircleBounds { - center: FPPoint, - radius: FPNum -} - -impl CircleBounds { - pub fn intersects(&self, other: &CircleBounds) -> bool { - (other.center - self.center).is_in_range(self.radius + other.radius) - } - - pub fn rows(&self) -> impl Iterator)> { - let radius = self.radius.abs_round() as usize; - let center = Point::from_fppoint(&self.center); - (center.y as usize - radius..=center.y as usize + radius) - .map(move |row| (row, center.x as usize - radius..=center.x as usize + radius)) - } -} - -fn fppoint_round(point: &FPPoint) -> Point { - Point::new(point.x().round() as i32, point.y().round() as i32) -} - -struct GridBin { - refs: Vec, - static_entries: Vec, - dynamic_entries: Vec -} - -impl GridBin { - fn new() -> Self { - Self { - refs: vec![], - static_entries: vec![], - dynamic_entries: vec![] - } - } + physics: PhysicsProcessor, + collision: CollisionProcessor, } -const GRID_BIN_SIZE: usize = 256; - -struct Grid { - bins: Vec, - space_size: Size, - bins_count: Size, - index: GridIndex -} - -impl Grid { - fn new(size: Size) -> Self { - assert!(size.is_power_of_two()); - let bins_count = - Size::new(size.width / GRID_BIN_SIZE, - size.height / GRID_BIN_SIZE); - - Self { - bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(), - space_size: size, - bins_count, - index: Size::square(GRID_BIN_SIZE).to_grid_index() - } - } - - fn bin_index(&self, position: &FPPoint) -> Point { - self.index.map(fppoint_round(position)) - } - - fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin { - let index = self.bin_index(position); - &mut self.bins[index.x as usize * self.bins_count.width + index.y as usize] - } - - fn insert_static(&mut self, index: Index, position: &FPPoint, bounds: &CircleBounds) { - self.lookup_bin(position).static_entries.push(*bounds) - } - - fn insert_dynamic(&mut self, index: Index, position: &FPPoint, bounds: &CircleBounds) { - self.lookup_bin(position).dynamic_entries.push(*bounds) - } - - fn check_collisions(&self, collisions: &mut Vec<(Index, Index)>) { - for bin in &self.bins { - for bounds in &bin.dynamic_entries { - for other in &bin.dynamic_entries { - if bounds.intersects(other) && bounds != other { - collisions.push((0, 0)) - } - } - - for other in &bin.static_entries { - if bounds.intersects(other) { - collisions.push((0, 0)) - } - } +macro_rules! processor_map { + ( $data_type: ident => $field: ident ) => { + impl GearDataAggregator<$data_type> for World { + fn find_processor(&mut self) -> &mut GearDataProcessor<$data_type> { + &mut self.$field } } } } -impl World { - pub fn step(&mut self, time_step: FPNum, land: &Land2D) { - for (pos, vel) in self.enabled_physics.iter_mut_pos() { - *pos += *vel - } +processor_map!(PhysicsData => physics); +processor_map!(CollisionData => collision); - self.grid.check_collisions(&mut self.collision_output); - } - - fn check_land_collisions(&mut self, land: &Land2D) { - for collision in &self.enabled_collision { - if collision.bounds.rows().any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0)) { - self.land_collision_output.push(0) - } +impl World { + pub fn new(world_size: Size) -> Self { + Self { + physics: PhysicsProcessor::new(), + collision: CollisionProcessor::new(world_size) } } - pub fn add_gear(&mut self, data: JoinedData) { - if data.physics.velocity == FPPoint::zero() { - self.disabled_physics.push(data.physics); - self.grid.insert_static(0, &data.physics.position, &data.collision.bounds); - } else { - self.enabled_physics.push(data.physics); - self.grid.insert_dynamic(0, &data.physics.position, &data.collision.bounds); - } + pub fn step(&mut self, time_step: FPNum, land: &Land2D) { + let updates = self.physics.process(time_step); + self.collision.process(land, &updates); + } + + pub fn add_gear_data(&mut self, gear_id: GearId, data: T) + where T: GearData, + Self: GearDataAggregator + { + self.find_processor().add(gear_id, data); } } #[cfg(test)] mod tests { + use crate::{ + World, + physics::PhysicsData, + collision::{CollisionData, CircleBounds} + }; + use fpnum::{FPNum, FPPoint, fp}; + use integral_geometry::Size; + use land2d::Land2D; + #[test] + fn data_flow() { + let world_size = Size::new(2048, 2048); + + let mut world = World::new(world_size); + let gear_id = 46631; + + world.add_gear_data(gear_id, PhysicsData { + position: FPPoint::zero(), + velocity: FPPoint::unit_y() + }); + + world.add_gear_data(gear_id, CollisionData { + bounds: CircleBounds { + center: FPPoint::zero(), + radius: fp!(10) + } + }); + + let land = Land2D::new(Size::new(world_size.width - 2, world_size.height - 2), 0); + + world.step(fp!(1), &land); + } } diff -r ec07ddc1a4a4 -r fae0dd90663b rust/hwphysics/src/physics.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hwphysics/src/physics.rs Fri Nov 09 14:15:22 2018 +0300 @@ -0,0 +1,134 @@ +use crate::{ + common::{GearId, GearData, GearDataProcessor} +}; +use fpnum::*; +use integral_geometry::{ + Point, Size, GridIndex +}; + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct PhysicsData { + pub position: FPPoint, + pub velocity: FPPoint, +} + +impl GearData for PhysicsData {} + +pub struct DynamicPhysicsCollection { + gear_ids: Vec, + positions: Vec, + velocities: Vec, +} + +impl DynamicPhysicsCollection { + fn new() -> Self { + Self { + gear_ids: Vec::new(), + positions: Vec::new(), + velocities: Vec::new() + } + } + + fn len(&self) -> usize { + self.gear_ids.len() + } + + fn push(&mut self, id: GearId, physics: PhysicsData) { + self.gear_ids.push(id); + self.positions.push(physics.position); + self.velocities.push(physics.velocity); + } + + fn iter_pos_update(&mut self) -> impl Iterator { + self.gear_ids.iter().cloned() + .zip(self.positions.iter_mut() + .zip(self.velocities.iter())) + } +} + +pub struct StaticPhysicsCollection { + gear_ids: Vec, + positions: Vec +} + +impl StaticPhysicsCollection { + fn new() -> Self { + Self { + gear_ids: Vec::new(), + positions: Vec::new() + } + } + + fn push(&mut self, gear_id: GearId, physics: PhysicsData) { + self.gear_ids.push(gear_id); + self.positions.push(physics.position); + } +} + +pub struct PhysicsProcessor { + dynamic_physics: DynamicPhysicsCollection, + static_physics: StaticPhysicsCollection, + + physics_cleanup: Vec, + position_updates: PositionUpdates +} + +pub struct PositionUpdates { + pub gear_ids: Vec, + pub positions: Vec +} + +impl PositionUpdates { + pub fn new(capacity: usize) -> Self { + Self { + gear_ids: Vec::with_capacity(capacity), + positions: Vec::with_capacity(capacity), + } + } + + pub fn push(&mut self, gear_id: GearId, position: &FPPoint) { + self.gear_ids.push(gear_id); + self.positions.push(*position); + } +} + +impl PhysicsProcessor { + pub fn new() -> Self { + PhysicsProcessor { + dynamic_physics: DynamicPhysicsCollection::new(), + static_physics: StaticPhysicsCollection::new(), + physics_cleanup: Vec::new(), + position_updates: PositionUpdates::new(0) + } + } + + pub fn process(&mut self, time_step: FPNum) -> &PositionUpdates { + for (gear_id, (pos, vel)) in self.dynamic_physics.iter_pos_update() { + *pos += *vel * time_step; + if !vel.is_zero() { + self.position_updates.push(gear_id, pos) + } else { + self.physics_cleanup.push(gear_id) + } + } + &self.position_updates + } + + pub fn push(&mut self, gear_id: GearId, physics_data: PhysicsData) { + if physics_data.velocity.is_zero() { + self.static_physics.push(gear_id, physics_data); + } else { + self.dynamic_physics.push(gear_id, physics_data); + } + } +} + +impl GearDataProcessor for PhysicsProcessor { + fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) { + if gear_data.velocity.is_zero() { + self.static_physics.push(gear_id, gear_data); + } else { + self.dynamic_physics.push(gear_id, gear_data); + } + } +} \ No newline at end of file diff -r ec07ddc1a4a4 -r fae0dd90663b rust/integral-geometry/src/lib.rs --- a/rust/integral-geometry/src/lib.rs Fri Nov 09 14:12:00 2018 +0300 +++ b/rust/integral-geometry/src/lib.rs Fri Nov 09 14:15:22 2018 +0300 @@ -152,6 +152,11 @@ } #[inline] + pub fn transpose(&self) -> Self { + Self::new(self.height, self.width) + } + + #[inline] pub fn to_mask(&self) -> SizeMask { SizeMask::new(*self) } diff -r ec07ddc1a4a4 -r fae0dd90663b rust/lib-hedgewars-engine/src/command.rs --- a/rust/lib-hedgewars-engine/src/command.rs Fri Nov 09 14:12:00 2018 +0300 +++ b/rust/lib-hedgewars-engine/src/command.rs Fri Nov 09 14:15:22 2018 +0300 @@ -1,4 +1,3 @@ pub enum Command { - SetAmmo(String), ChatMessage(String), } diff -r ec07ddc1a4a4 -r fae0dd90663b rust/lib-hedgewars-engine/src/engine_message.rs --- a/rust/lib-hedgewars-engine/src/engine_message.rs Fri Nov 09 14:12:00 2018 +0300 +++ b/rust/lib-hedgewars-engine/src/engine_message.rs Fri Nov 09 14:15:22 2018 +0300 @@ -11,6 +11,7 @@ Up(KeystrokeAction), Down(KeystrokeAction), Precise(KeystrokeAction), + Attack(KeystrokeAction), NextTurn, Switch, Empty, @@ -30,18 +31,88 @@ Pong, Say(String), Taunt(u8), - ExecCommand(Command), - GameType(u8),// TODO: use enum + GameType(u8), Warning(String), StopSyncing, - ConfigRequest, GameOver, GameInterrupted, + GameSetupChecksum(String), +} + +pub enum ConfigEngineMessage { + ConfigRequest, + SetAmmo(String), + SetScript(String), + SetScriptParam(String), + Spectate, + TeamLocality(bool), + SetMap(String), + SetTheme(String), + SetSeed(String), + SetTemplateFilter(String), + SetMapGenerator(String), + SetFeatureSize(u8), + SetDelay(u32), + SetReadyDelay(u32), + SetCratesFrequency(u8), + SetHealthCrateProbability(u8), + SetHealthCratesNumber(u8), + SetRoundsTilSuddenDeath(u8), + SetSuddenDeathWaterRiseSpeed(u8), + SetSuddenDeathHealthDecreaseRate(u8), + SetDamageMultiplier(u32), + SetRopeLength(u32), + SetGetawayTime(u32), + SetDudMinesPercent(u8), + SetMinesNumber(u32), + SetAirMinesNumber(u32), + SetBarrelsNumber(u32), + SetTurnTime(u32), + SetMinesTime(u32), + SetWorldEdge(u8), + Draw, // TODO + SetVoicePack(String), + AddHedgehog(String, u8, u32), + AddTeam(String, u8), + SetHedgehogCoordinates(i32, i32), + SetFort(String), + SetGrave(String), + SetHat(String), + SetFlag(String), + SetOwner(String), + SetOneClanMode(bool), + SetMultishootMode(bool), + SetSolidLand(bool), + SetBorders(bool), + SetDivideTeams(bool), + SetLowGravity(bool), + SetLaserSight(bool), + SetInvulnerability(bool), + SetHealthReset(bool), + SetVampiric(bool), + SetKarma(bool), + SetArtilleryMode(bool), + SetHedgehogSwitch(bool), + SetRandomOrder(bool), + SetKingMode(bool), + SetPlaceHedgehog(bool), + SetSharedAmmo(bool), + SetGirdersEnabled(bool), + SetLandObjectsEnabled(bool), + SetAISurvivalMode(bool), + SetInfiniteAttack(bool), + SetResetWeapons(bool), + SetAmmoPerHedgehog(bool), + SetWindMode(u8), + SetTagTeam(bool), + SetBottomBorder(bool), + SetShoppaBorder(bool), } pub enum EngineMessage { Synced(SyncedEngineMessage, u32), Unsynced(UnsyncedEngineMessage), + Config(ConfigEngineMessage), } impl EngineMessage { diff -r ec07ddc1a4a4 -r fae0dd90663b rust/mapgen/src/lib.rs --- a/rust/mapgen/src/lib.rs Fri Nov 09 14:12:00 2018 +0300 +++ b/rust/mapgen/src/lib.rs Fri Nov 09 14:15:22 2018 +0300 @@ -141,6 +141,7 @@ if let Some(border_sprite) = theme.border_texture() { assert!(border_sprite.height() <= 512); let border_width = (border_sprite.height() / 2) as u8; + let border_sprite = border_sprite.to_tiled(); let mut offsets = vec![255u8; land.width()]; diff -r ec07ddc1a4a4 -r fae0dd90663b rust/mapgen/src/theme.rs --- a/rust/mapgen/src/theme.rs Fri Nov 09 14:12:00 2018 +0300 +++ b/rust/mapgen/src/theme.rs Fri Nov 09 14:15:22 2018 +0300 @@ -23,18 +23,18 @@ impl ThemeSprite { #[inline] + pub fn size(&self) -> Size { + self.pixels.size() + } + + #[inline] pub fn width(&self) -> usize { - self.pixels.size().width + self.size().width } #[inline] pub fn height(&self) -> usize { - self.pixels.size().height - } - - #[inline] - pub fn bounds(&self) -> Size { - self.pixels.size() + self.size().height } #[inline] @@ -51,6 +51,65 @@ pub fn get_pixel(&self, x: usize, y: usize) -> u32 { self.pixels[y][x] } + + pub fn to_transposed(&self) -> ThemeSprite { + let size = self.size().transpose(); + let mut pixels = Vec2D::new(size, 0u32); + for (y, row) in self.pixels.rows().enumerate() { + for (x, v) in row.iter().enumerate() { + pixels[x][y] = *v; + } + } + ThemeSprite { pixels } + } + + pub fn to_tiled(&self) -> TiledSprite { + let size = self.size(); + assert!(size.is_power_of_two()); + let tile_width_shift = size.width.trailing_zeros() as usize + 2; + let mut pixels = vec![0u32; size.area()]; + + for (y, row) in self.pixels.rows().enumerate() { + for (x, v) in row.iter().enumerate() { + pixels[get_tiled_index(x, y, tile_width_shift)] = *v; + } + } + + TiledSprite { tile_width_shift, size, pixels } + } +} + +#[inline] +fn get_tiled_index(x: usize, y: usize, tile_width_shift: usize) -> usize { + (((y >> 2) << tile_width_shift) + ((x >> 2) << 4)) + ((y & 0b11) << 2) + (x & 0b11) +} + +pub struct TiledSprite { + tile_width_shift: usize, + size: Size, + pixels: Vec +} + +impl TiledSprite { + #[inline] + pub fn size(&self) -> Size { + self.size + } + + #[inline] + pub fn width(&self) -> usize { + self.size().width + } + + #[inline] + pub fn height(&self) -> usize { + self.size().height + } + + #[inline] + pub fn get_pixel(&self, x: usize, y: usize) -> u32 { + self.pixels[get_tiled_index(x, y, self.tile_width_shift)] + } } pub struct Theme { diff -r ec07ddc1a4a4 -r fae0dd90663b share/hedgewars/Data/Locale/campaigns_uk.txt --- a/share/hedgewars/Data/Locale/campaigns_uk.txt Fri Nov 09 14:12:00 2018 +0300 +++ b/share/hedgewars/Data/Locale/campaigns_uk.txt Fri Nov 09 14:15:22 2018 +0300 @@ -6,7 +6,7 @@ A_Classic_Fairytale-united.desc="Після довгої мандрівки Протікайко повернувся до села. Але немає коли відпочивати. Треба захистити село від нападу канібалів." -A_Classic_Fairytale-backstab.desc="The monstrous cannibals are hunting Leaks a lot and his friends. Defeat them once again and protect your allies. Use your resources accordingly to defeat the incoming enemies!" +A_Classic_Fairytale-backstab.desc="Жорстокі канібали полюють на Протікайка і його друзів. Подолай їх знов і захисти союзників. Використовуй наявні ресурси розумно для подолання атакуючих ворогів!" A_Classic_Fairytale-dragon.desc="Протікайту треба перебратись на інший берег озера. Стань майстром мотузки і уникай пострілів ворога." @@ -16,17 +16,17 @@ A_Classic_Fairytale-enemy.desc="Який поворот! Протікайку треба битись пліч-о-пліч з… “канібалами” протиспільного ворога. Злих кіборгів!" -A_Classic_Fairytale-epil.desc="Вітання! Протікайко нарешті може мирно жити і бути поцінованим новими друзями і йоо племенем. Гордись доясненнями! Ти можеш пройти попередні місії знов і глянути на інші кінцівки." +A_Classic_Fairytale-epil.desc="Вітання! Протікайко нарешті може мирно жити і бути поцінованим новими друзями і його племенем. Гордись досягненнями! Ти можеш пройти попередні місії знов і глянути на інші кінцівки." A_Space_Adventure-cosmos.desc="На планету їжаків, Їжакію, незабаром має впасти гігантський метеорит. В боротьбі за виживання вам потрібно провести кращого пілота PAotH, Їжака Соло, в подорож сусідніми планетами щоб знайти всі 4 частини давно загубленого антигравітаційного пристрою!" A_Space_Adventure-moon01.desc="Hog Solo has landed on the moon to refuel his saucer but professor Hogevil has gone there first and set an ambush! Rescue the captured PAotH researchers and drive professor Hogevil away!" A_Space_Adventure-moon02.desc="Hog Solo visits an hermit, old PAotH veteran, who lives in moon in order to gather some intel about Pr. Hogevil. However, he has to beat the hermit, Soneek the Crazy Runner, in a chase game first!" -A_Space_Adventure-ice01.desc="Welcome to the planet of ice. Here, it's so cold that most of Hog Solo's weapons won't work. You have to get the lost part from the bandit leader Thanta using the weapons that you'll find there!" +A_Space_Adventure-ice01.desc="Вітаємо на планеті льоду. Тут настільки холодно, що більшість зброї Їжака Соло не працює. You have to get the lost part from the bandit leader Thanta using the weapons that you'll find there!" A_Space_Adventure-ice02.desc="Hog Solo couldn't just visit the Ice Planet without visiting the Olympic stadium of saucer flying! In this mission you can prove your flying skills and claim your place between the best!" A_Space_Adventure-desert01.desc="You have landed to the planet of sand! Hog Solo has to find the missing part in the underground tunnels. Be careful as vicious smugglers await to attack and rob you!" A_Space_Adventure-desert02.desc="Hog Solo was searching for the part in this tunnel when it unexpectedly start getting flooded! Get to the surface as soon as possible and be careful not to trigger a mine." A_Space_Adventure-desert03.desc="Hog Solo has some time to fly his RC plane and have some fun. Fly the RC plane and hit all the targets!" -A_Space_Adventure-fruit01.desc="In the fruit planet things aren't going so well. Hogs aren't collecting fruits but they are preparing for battle. You'll have to choose if you'll fight or if you'll flee." +A_Space_Adventure-fruit01.desc="На фруктовій планеті справи кепські. Їжаки не збирають фрукти але готуються до бою. You'll have to choose if you'll fight or if you'll flee." A_Space_Adventure-fruit02.desc="Hog Solo gets closer to the lost part in the Fruit Planet. Will Captain Lime help him acquire the part or not?" A_Space_Adventure-fruit03.desc="Hog Solo got lost and got ambushed by the Red Strawberries. Help him eliminate them and win some extra ammo for the Getting to the device mission." A_Space_Adventure-death01.desc="In the Death Planet, the most infertile planet around, Hog Solo is very close to get the last part of the device! However an unpleasant surprise awaits him..." diff -r ec07ddc1a4a4 -r fae0dd90663b share/hedgewars/Data/Locale/hedgewars_uk.ts --- a/share/hedgewars/Data/Locale/hedgewars_uk.ts Fri Nov 09 14:12:00 2018 +0300 +++ b/share/hedgewars/Data/Locale/hedgewars_uk.ts Fri Nov 09 14:15:22 2018 +0300 @@ -10,73 +10,73 @@ Hedgewars %1 %1 contains Hedgewars' version number - Hedgewars %1 + Hedgewars %1 Revision %1 (%2) - + Ревізія %1 (%2) Visit our homepage: %1 - + Наша домашня сторінка: %1 This program is distributed under the %1. - Ця програма поширюється згідно з %1. + Ця програма поширюється згідно з %1. GNU GPL v2 Short for “GNU General Public License version 2” - + GNU GPL v2 Dependency versions: For the version numbers of Hedgewars' software dependencies - + Версії залежностей: <a href="https://gcc.gnu.org">GCC</a>: %1 - + <a href="https://gcc.gnu.org">GCC</a>: %1 <a href="https://www.libsdl.org/">SDL2</a>: %1.%2.%3 - + <a href="https://www.libsdl.org/">SDL2</a>: %1.%2.%3 <a href="https://www.libsdl.org/">SDL2_mixer</a>: %1.%2.%3 - + <a href="https://www.libsdl.org/">SDL2_mixer</a>: %1.%2.%3 <a href="https://www.libsdl.org/">SDL2_net</a>: %1.%2.%3 - + <a href="https://www.libsdl.org/">SDL2_net</a>: %1.%2.%3 <a href="https://www.libsdl.org/">SDL2_image</a>: %1.%2.%3 - + <a href="https://www.libsdl.org/">SDL2_image</a>: %1.%2.%3 <a href="https://www.libsdl.org/">SDL2_ttf</a>: %1.%2.%3 - + <a href="https://www.libsdl.org/">SDL2_ttf</a>: %1.%2.%3 <a href="https://www.qt.io/developers/">Qt</a>: %1 - + <a href="https://www.qt.io/developers/">Qt</a>: %1 <a href="https://libav.org">libavcodec</a>: %1.%2.%3 - + <a href="https://libav.org">libavcodec</a>: %1.%2.%3 <a href="https://libav.org">libavformat</a>: %1.%2.%3 - + <a href="https://libav.org">libavformat</a>: %1.%2.%3 <a href="https://libav.org">libavutil</a>: %1.%2.%3 - + <a href="https://libav.org">libavutil</a>: %1.%2.%3 <a href="https://icculus.org/physfs/">PhysFS</a>: %1.%2.%3 - + <a href="https://icculus.org/physfs/">PhysFS</a>: %1.%2.%3 @@ -138,15 +138,15 @@ Ban player - + Забанити гравця Please specify an IP address. - + Вкажіть IP адресу. Please specify a nickname. - + Вкажіть нікнейм. @@ -188,11 +188,11 @@ Feedback - Відгук + Відгук This is optional, but this information might help us to resolve bugs and other technical problems. - + Це необов'язково, але ця інформація може допомогти нам у вирішенні проблем. @@ -249,19 +249,19 @@ New - Нова + Нова Copy of %1 - + Копія %1 New (%1) - + Нова (%1) Copy of %1 (%2) - + Копія %1 (%2) @@ -285,8 +285,8 @@ %1 hour %1 година - - + %1 години + %1 годин @@ -301,8 +301,8 @@ %1 day %1 день - - + %1 дні + %1 днів @@ -334,52 +334,52 @@ Usage command-line - + Використання OPTION command-line - + OPTION CONNECTSTRING command-line - + CONNECTSTRING Options command-line - + Опції Display this help command-line - + Показати цю довідку Custom path for configuration data and user data command-line - + Користувацький шлях до даних конфігурації та даних користувача Custom path to the game data folder command-line - + Користувацький шлях до теки даних гри Hedgewars can use a %1 (e.g. "%2") to connect on start. command-line - + Hedgewars може використовувати %1 (напр. "%2") щоб під'єднуватися на старті. Malformed option argument: %1 command-line - + Невірний аргумент опції: %1 Unknown option argument: %1 command-line - + Невідомий аргумент опції: %1 @@ -445,15 +445,15 @@ Chat log - + Журнал чату Enter chat messages here and send them with [Enter] - + Вводіть повідомлення чату тут і надсилайте їх натиснувши [Enter] List of players - + Перелік гравців @@ -579,34 +579,34 @@ The room is protected with password. Please, enter the password: - Кімната захищена паролем. + Кімната захищена паролем. Будь ласка, введіть пароль: Team 1 - + Команда 1 Team %1 Default team name - + Команда %1 Computer %1 Default computer team name - + Комп'ютер %1 Unknown network error (possibly missing SSL library). - + Невідома помилка мережі (можливо відсутня бібліотека SSL). This feature requires an Internet connection, but you don't appear to be online (error code: %1). - + Ця функція потребує підключення до Інтернету, але ви, здається, не знаходитесь в мережі (код помилки: %1). Internal error: Reply object is invalid. - + Внутрішня помилка: об'єкт відповіді недійсний. @@ -629,14 +629,21 @@ Last engine message: %1 - + Виникла фатальна ПОМИЛКА! Ігровий двигун довелося зупинити. + +Нам дуже шкода за незручності. :-( + +Якщо це триватиме, натисніть кнопку "Зворотний зв'язок" у головному меню! + +Останнє повідомлення двигуна: +%1 HWHostPortDialog Connect to server - + Під'єднатись до сервера @@ -772,11 +779,11 @@ Style: - + Стиль: Forts - + Форти View and edit the seed, the source of randomness in the game @@ -784,11 +791,11 @@ Randomize the theme - + Випадкова тема Choose a theme - + Виберіть тему Randomize the map, theme and seed @@ -812,15 +819,15 @@ Adjust the complexity of the generated map - + Вкажіть складність згенерованої мапи Adjust the distance between forts - + Вкажіть відстань між фортами Click to edit - + Клацніть для зміни @@ -892,15 +899,15 @@ Server authentication error - + Помилка автентифікації на сервері Reason: - + Причина: The connection was refused by the official server or timed out. Something seems to be wrong with the official server at the moment. This might be a temporary problem. Please try again later. - + Зв'язок розірвано офіційним сервером або закінчився час очікування. Здається на даний момент є проблеми з офіційним сервером. Це може бути тимчасовою проблемою. Будь ласка спробуйте пізніше. The connection was refused by the host or timed out. This might have one of the following reasons: @@ -909,7 +916,12 @@ - There is a temporary network problem Please check the host name and port settings and/or try again later. - + З'єднання розірвано хостом або закінчився час очікування. Це може мати одну з наступних причин: +- Серверна частина Hedgewars наразі не працює на хості +- Вказаний невірний номер порту +- Існує тимчасова проблема з мережею + +Перевірте налаштування імені хоста та порту та/або повторіть спробу пізніше. @@ -938,7 +950,7 @@ New Account - + Новий акаунт @@ -975,7 +987,7 @@ Choose a hat - + Виберіть капелюх @@ -1017,33 +1029,33 @@ Duration: %1min %2s Duration in minutes and seconds (SI units) - + Тривалість: %1хв %2с Video: %1x%2, %3 FPS, %4 Video metadata. %1 = video width, %2 = video height, %3 = frames per second = %4 = decoder name - + Відео: %1x%2, %3 FPS, %4 Video: %1x%2, %3 Video metadata. %1 = video width, %2 = video height, %3 = decoder name - + Відео: %1x%2, %3 Player: %1 - + Гравець: %1 Theme: %1 - Тема: %1 + Тема: %1 Map: %1 - + Мапа: %1 Record: %1 - + Рекорд: %1 @@ -1057,12 +1069,12 @@ MinesTimeSpinBox Random - + Випадково %1 seconds - - + + %1 секунд @@ -1136,19 +1148,19 @@ PageCampaign Team - Команда + Команда Campaign - + Кампанія Mission - + Місія Start fighting - Розпочати бій + Розпочати бій @@ -1170,23 +1182,23 @@ Open packages directory - + Відкрити теку з пакунками Load the start page - + Завантажити стартову сторінку Unknown network error (possibly missing SSL library). - + Невідома помилка мережі (можливо відсутня бібліотека SSL). This feature requires an Internet connection, but you don't appear to be online (error code: %1). - + Ця функція потребує підключення до Інтернету, але ви, здається, не знаходитесь в мережі (код помилки: %1). Internal error: Reply object is invalid. - + Внутрішня помилка: об'єкт відповіді недійсний. @@ -1241,11 +1253,11 @@ Optimize - + Оптимізувати Brush size - + Розмір пензля @@ -1292,44 +1304,44 @@ Play a random example of this voice - + Програти випадковий приклад голосу Random Hats - + Випадкові капелюхи Random Names - + Випадкові імена Randomize the team name - + Випадкова назва команди Randomize the grave - + Випадкова могила Randomize the flag - + Випадковий прапор Randomize the voice - + Випадковий голос Randomize the fort - + Випадковий форт CPU %1 Name of a flag for computer-controlled enemies. %1 is replaced with the computer level - + ЦП %1 %1 (%2) - + %1 (%2) @@ -1348,7 +1360,7 @@ The best shot award was won by <b>%1</b> with <b>%2</b> pts. - + Нагороду за кращий постріл отримує <b>%1</b> з <b>%2</b> пунктами нанесених втрат. @@ -1438,7 +1450,7 @@ With everyone having the same clan color, there was no reason to fight. And so the hedgehogs happily lived in peace ever after. - + Оскільки клани мали той самий колір, не було причин для бою. Тому їжаки довго жили в мирі і щасті. @@ -1515,7 +1527,7 @@ Open the Hedgewars online game manual in your web browser - + Відкрийте онлайн посібник Hedgewars у своєму веб-переглядачі @@ -1530,7 +1542,7 @@ Start fighting (requires at least 2 teams) - + Розпочати бій (потребує хоча б 2 команди) @@ -1557,19 +1569,19 @@ Room name - + Назва кімнати Update the room name - + Оновити назву кімнати Turn on the lightbulb to show the other players when you're ready to fight - + Увімкніть лампочку, щоб показати іншим гравцям, коли будете готові до бою Start fighting (requires at least 2 teams) - + Розпочати бій (потребує хоча б 2 команди) @@ -1756,7 +1768,7 @@ x Multiplication sign, to be used between two numbers. Note the “x” is only a dummy character, we recommend to use “×” if your language permits it - + x MISSING LANGUAGE NAME [%1] @@ -1764,15 +1776,15 @@ Check now - + Перевірити зараз Can't delete last team - + Неможливо видалити останню команду You can't delete the last team! - + Ви не можете видалити останню команду! @@ -1787,15 +1799,15 @@ Play demo - Грати демо + Грати демо Play the selected demo - + Грати обране демо Load the selected game - + Завантажити обрану гру @@ -2001,7 +2013,7 @@ Each clan starts in its own part of the terrain. - + Кожен клан стартує на своїй території. Overall damage and knockback in percent @@ -2013,7 +2025,7 @@ Initial health of hedgehogs - + Початкове здоров'я їжаків How many rounds have to be played before Sudden Death begins @@ -2029,7 +2041,7 @@ Maximum rope length in percent - + Максимальна довжина мотузки у відсотках Likelihood of a dropped crate being a health crate. All other crates will be weapon or utility crates. @@ -2041,7 +2053,7 @@ Health bonus for collecting a health crate - + Бонус здоров'я за підібраний ящик зі здоров'ям Detonation timer of mines. The random timer lies between 0 and 5 seconds. The timer of air mines will be a quarter of the mines timer. @@ -2069,7 +2081,7 @@ Time you get after an attack - + Час, який у вас є після атаки Additional parameter to configure game styles. The meaning depends on the used style, refer to the documentation. When in doubt, leave it empty. @@ -2077,19 +2089,19 @@ Name of this scheme - + Назва цієї схеми Select a hedgehog at the beginning of a turn - + Виберіть їжака на початку ходу Land can not be destroyed by most weapons. - + Земля не може бути знищена більшістю зброї. %1 (%2) - + %1 (%2) @@ -2158,27 +2170,27 @@ Pick the training to play - + Виберіть навчальну гру Pick the challenge to play - + Виберіть виклик Pick the scenario to play - + Виберіть сценарій гри Trainings - + Навчання Challenges - + Виклики Scenarios - + Сценарії @@ -2195,8 +2207,8 @@ %1 bytes %1 байт - - + %1 байти + %1 байтів @@ -2222,12 +2234,12 @@ %1% Video encoding progress. %1 = number - + %1% %1 (%2%) - %3 Video encoding list entry. %1 = file name, %2 = percent complete, %3 = video operation type (e.g. “encoding”) - + %1 (%2%) - %3 @@ -2290,15 +2302,15 @@ Show password protected - + Показати захищені паролем Show join restricted - + Показати з обмеженим приєднанням Delegate room control - + Делегувати керування кімнатою @@ -2409,20 +2421,20 @@ Enable visual effects such as animated menu transitions and falling stars - + Ввімкнути візуальні ефекти, такі як анімаційні переходи меню та падіння зірок If enabled, Hedgewars adds the date and time in the form "YYYY-MM-DD_hh-mm" for automatically created demos. - + Якщо ввімкнено, Hedgewars додасть дату та час у вигляді "YYYY-MM-DD_hh-mm" до автоматично створених демо. Dampen when losing focus Checkbox text. If checked, the in-game audio volume is reduced (=dampened) when the game window loses its focus - + Занижувати звук при втраті фокусу Reduce the game audio volume if the game window has lost its focus - + Знизити гучність звук гри, якщо вікно гри втратило фокус @@ -2517,31 +2529,31 @@ Computer (Level %1) - + Комп'ютер (Рівень %1) Stereoscopy creates an illusion of depth when you wear 3D glasses. - + Стереоскопія створює ілюзію глибини, коли ви одягаєте 3D-окуляри. 24 FPS - + 24 FPS 25 FPS - + 25 FPS 30 FPS - + 30 FPS 50 FPS - + 50 FPS 60 FPS - + 60 FPS @@ -2851,15 +2863,15 @@ Air Mines - + Повітряні міни Player - + Гравець Barrels - + Бочки % Retreat Time @@ -2867,12 +2879,12 @@ Stereoscopy - + Стереоскопія Bitrate (Kibit/s) “Kibit/s” is the symbol for 1024 bits per second - + Бітрейт (Kibit/s) Loading<br>CAPTCHA ... @@ -2895,11 +2907,11 @@ unnamed (%1) - + без_назви (%1) Hedgehog %1 - + Їжак %1 @@ -3137,53 +3149,55 @@ Teams - Name already taken - + Команди - Назва вже зайнята The team name '%1' is already taken, so your team has been renamed to '%2'. - + Назва команди '%1' вже зайнята, тому ваша команда була перейменована на '%2'. Please select a file from the list. - + Виберіть файл зі списку. Cannot rename file to %1. - + Неможливо перейменувати файл %1. Cannot delete file %1. - + Неможливо видалити файл %1. Welcome to Hedgewars - + Вітаємо в Hedgewars Welcome to Hedgewars! You seem to be new around here. Would you like to play some training missions first to learn the basics of Hedgewars? - + Вітаємо в Hedgewars! + +Ви, схоже, новенький. Чи не хочете спочатку зіграти деякі навчальні місії, щоб вивчити основи Hedgewars? Cannot use the weapon scheme '%1'! - + Неможливо використати схему зброї '%1'! The connection to the server is lost. - + З'єднання з сервером втрачено. Schemes - Name already taken - + Схеми - Назва вже зайнята A scheme with the name '%1' already exists. Your scheme has been renamed to '%2'. - + Схема з назвою '%1' вже існує. Ваша схема перейменована на '%2'. A weapon scheme with the name '%1' already exists. Changes made to the weapon scheme have been discarded. - + Схема зброї з назвою '%1' вже існує. Зміни, внесені до схеми зброї, були відхилені. @@ -3320,7 +3334,7 @@ QSpinBox Specify the bitrate of recorded videos as a multiple of 1024 bits per second - + Вкажіть бітрейт записаного відео кратний 1024 бітам за секунду @@ -3400,7 +3414,7 @@ Forts - + Форти @@ -3424,7 +3438,7 @@ Seed Refers to the "random seed"; the source of randomness in the game - Висів + Висів @@ -3455,19 +3469,19 @@ New - Нова + Новий New (%1) - + Новий (%1) Copy of %1 - + Копія %1 Copy of %1 (%2) - + Копія %1 (%2) @@ -3489,7 +3503,12 @@ We are very sorry for the inconvenience :( If this keeps happening, please click the '%2' button in the main menu! - + Ігровий двигун несподівано помер! +(код виходу %1) + +Нам дуже шкода за незручності :( + +Якщо це триватиме, натисніть на кнопку '%2' в головному меню! @@ -3515,7 +3534,7 @@ Choose a theme - + Виберіть тему @@ -3860,7 +3879,7 @@ Delete - Видалити + Delete Mouse: Left button @@ -3896,15 +3915,15 @@ Return - + Return Pause - + Pause Escape - + Escape Space @@ -3972,11 +3991,11 @@ Enter - + Enter Equals - + Дорівнює Up @@ -3996,23 +4015,23 @@ Insert - + Insert Home - + Home End - + End Page up - + Page up Page down - + Page down Num lock @@ -4020,11 +4039,11 @@ Caps lock - + Caps lock Scroll lock - + Scroll lock Right shift @@ -4052,27 +4071,27 @@ Right meta - + Права Meta Left meta - + Ліва Meta A button - + Кнопка A B button - + Кнопка B X button - + Кнопка X Y button - + Кнопка Y LB button @@ -4282,19 +4301,19 @@ New voting started - + Почалося нове голосування kick - + копнути map - + мапа pause - пауза + пауза Reconnected too fast @@ -4318,7 +4337,7 @@ new seed - + новий висів /maxteams: specify number from 2 to 8 @@ -4338,11 +4357,11 @@ Access denied. - + Доступ заборонено. You're not the room master! - + Ви не голова кімнати! Corrupted hedgehogs info! @@ -4350,15 +4369,15 @@ Too many teams! - + Забагато команд! Too many hedgehogs! - + Забагато їжаків! There's already a team with same name in the list. - + Команда з таким же іменем вже є в списку. Joining not possible: Round is in progress. @@ -4410,7 +4429,7 @@ No such room. - + Немає такої кімнати. Room version incompatible to your Hedgewars version! @@ -4442,7 +4461,7 @@ Bad number. - + Невірне число. There's no voting going on. @@ -4450,15 +4469,15 @@ You already have voted. - + Ви вже проголосували. Your vote has been counted. - + Ваш голос було враховано. Voting closed. - + Голосування завершене. Pause toggled. @@ -4466,11 +4485,11 @@ Voting expired. - + Голосування вже скінчилось. hedgehogs per team: - + їжаків в команді: /info <player>: Show info about player @@ -4554,11 +4573,11 @@ room - + кімната lobby - + вестибюль (playing) @@ -4582,7 +4601,7 @@ Kicked - + Копнутий This server only allows registered users to join. @@ -4626,7 +4645,7 @@ Super power activated. - + Суперсила активована. Unknown command or invalid parameters. Say '/help' in chat for a list of commands. @@ -4634,7 +4653,7 @@ You can't kick yourself! - + Не можна копати себе! You can't kick the only other player! @@ -4654,7 +4673,7 @@ You're already the room master. - + Ви вже є головою кімнати! Greeting message cleared. @@ -4674,11 +4693,11 @@ You're the new room master! - + Ви новий голова кімнати! /quit: Quit the server - + /quit: Вийти з сервера This command is only available in the lobby. @@ -4686,7 +4705,7 @@ This command is only available in rooms. - + Ця команда працює лише в кімнатах. diff -r ec07ddc1a4a4 -r fae0dd90663b share/hedgewars/Data/Locale/uk.lua --- a/share/hedgewars/Data/Locale/uk.lua Fri Nov 09 14:12:00 2018 +0300 +++ b/share/hedgewars/Data/Locale/uk.lua Fri Nov 09 14:15:22 2018 +0300 @@ -1,32 +1,32 @@ locale = { -- ["..."] = "", --- ["011101000"] = "", -- A_Classic_Fairytale:dragon --- ["011101001"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united +-- ["011101000"] = "011101000", -- A_Classic_Fairytale:dragon +-- ["011101001"] = "011101001", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united -- ["10 weapon schemes"] = "", -- Continental_supplies -- ["15+%d damage, %d invulnerable left"] = "", -- Continental_supplies -- ["1-5, Precise + 1-4: Choose structure type"] = "", -- Construction_Mode --- ["+1 barrel!"] = "", -- Tumbler +-- ["+1 barrel!"] = "+1 бочка!", -- Tumbler -- ["%.1f seconds were remaining."] = "", -- Basic_Training_-_Bazooka --- ["%.1fs"] = "", -- Racer, TechRacer +-- ["%.1fs"] = "%.1fс", -- Racer, TechRacer -- ["+1 Grenade"] = "", -- Basic_Training_-_Flying_Saucer --- ["+1 mine!"] = "", -- Tumbler --- ["+1 point"] = "", -- Mutant --- ["-1 point"] = "", -- Mutant --- ["-1 to anyone for a suicide"] = "", -- Mutant +-- ["+1 mine!"] = "+1 міна!", -- Tumbler +-- ["+1 point"] = "+1 очко", -- Mutant +-- ["-1 point"] = "-1 очко", -- Mutant +-- ["-1 to anyone for a suicide"] = "-1 кожному за суїцид", -- Mutant -- ["+1 to the Bottom Feeder for killing anyone"] = "", -- Mutant --- ["+1 to the Mutant for killing anyone"] = "", -- Mutant --- ["+2 for becoming the Mutant"] = "", -- Mutant --- ["30 minutes later..."] = "", -- A_Classic_Fairytale:shadow --- ["%.3fs"] = "", -- A_Space_Adventure:ice02 +-- ["+1 to the Mutant for killing anyone"] = "+1 Мутанту за вбивство будь-кого", -- Mutant +-- ["+2 for becoming the Mutant"] = "+2 за те що став Мутантом", -- Mutant +-- ["30 minutes later..."] = "За 30 хвилин...", -- A_Classic_Fairytale:shadow +-- ["%.3fs"] = "%.3fс", -- A_Space_Adventure:ice02 -- ["5 additional enemies will be spawned during the game."] = "", -- A_Space_Adventure:fruit01 -- ["5 Deadly Hogs"] = "", -- A_Space_Adventure:death02 -- ["6 more seconds added to the clock"] = "", -- A_Space_Adventure:ice02 -- ["About a month ago, a cyborg came and told us that you're the cannibals!"] = "", -- A_Classic_Fairytale:enemy -- ["Above-average pilot"] = "", -- User_Mission_-_RCPlane_Challenge --- ["Accuracy Bonus! +15 points"] = "", -- Space_Invasion --- ["Accuracy bonus: +%d points"] = "", -- Basic_Training_-_Sniper_Rifle +-- ["Accuracy Bonus! +15 points"] = "Бонус Точності! +15 очок", -- Space_Invasion +-- ["Accuracy bonus: +%d points"] = "Бонус точності: +%d очок", -- Basic_Training_-_Sniper_Rifle -- ["Ace"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge --- ["Achievement gotten: %s"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_That_Sinking_Feeling, User_Mission_-_Bamboo_Thicket, User_Mission_-_Dangerous_Ducklings, Basic_Training_-_Rope, Tumbler +-- ["Achievement gotten: %s"] = "Досягнення: %s", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_That_Sinking_Feeling, User_Mission_-_Bamboo_Thicket, User_Mission_-_Dangerous_Ducklings, Basic_Training_-_Rope, Tumbler ["A Classic Fairytale"] = "Класична казка", -- A_Classic_Fairytale:first_blood -- ["A crate critical to this mission has been destroyed."] = "", -- SimpleMission -- ["Actually, you aren't worthy of life! Take this..."] = "", -- A_Classic_Fairytale:shadow @@ -52,7 +52,7 @@ -- ["Aiming practice"] = "", -- TargetPractice ["Aiming Practice"] = "Практика прицілювання", --Bazooka, Shotgun, SniperRifle -- ["Aim: [Up]/[Down]"] = "", -- Basic_Training_-_Bazooka, Basic_Training_-_Grenade, Basic_Training_-_Rope --- ["Air Attack"] = "", -- Construction_Mode +-- ["Air Attack"] = "Повітряна атака", -- Construction_Mode -- ["Air General"] = "", -- Battalion -- ["Air Mine Placement Mode"] = "", -- HedgeEditor -- ["AIR MINE PLACEMENT MODE"] = "", -- HedgeEditor @@ -79,10 +79,10 @@ -- ["Always being considered weak and fragile."] = "", -- A_Classic_Fairytale:queen -- ["Amazing! I was never beaten in a race before!"] = "", -- A_Space_Adventure:moon02 -- ["Ammo depleted!"] = "", -- Space_Invasion --- ["Ammo: %d"] = "", -- Tumbler +-- ["Ammo: %d"] = "Боєприпаси: %d", -- Tumbler ["Ammo is reset at the end of your turn."] = "Боєприпаси обнуляються в кінці вашого ходу.", -- ["Ammo Limit: Hogs can’t have more than 1 ammo per type"] = "", -- Highlander --- ["Ammo Maniac! +5 points!"] = "", -- Space_Invasion +-- ["Ammo Maniac! +5 points!"] = "Маніяк Боєприпасів! +5 очок!", -- Space_Invasion -- ["A mysterious Box"] = "", -- Basic_Training_-_Movement ["And how am I alive?!"] = "І чому я живий!?", -- A_Classic_Fairytale:enemy -- ["And I just forgot the checkpoint of my main mission. Great, just great!"] = "", -- A_Space_Adventure:cosmos @@ -165,7 +165,7 @@ -- ["Back Jumping (2/2)"] = "", -- Basic_Training_-_Movement -- ["Backstab"] = "", -- A_Classic_Fairytale:backstab -- ["Bacon"] = "", -- --- ["Bad Guy"] = "", -- User_Mission_-_The_Great_Escape +-- ["Bad Guy"] = "Поганий хлопець", -- User_Mission_-_The_Great_Escape -- ["Badmad"] = "", -- portal ["Bad Team"] = "Погана команда", -- User_Mission_-_The_Great_Escape -- ["Bad timing"] = "", -- A_Space_Adventure:fruit01 @@ -187,7 +187,7 @@ -- ["Basic Movement Training"] = "", -- Basic_Training_-_Movement -- ["Basic Rope Training"] = "", -- Basic_Training_-_Rope -- ["Basic Training"] = "", -- Basic_Training_-_Bazooka, Basic_Training_-_Grenade, Basic_Training_-_Movement, Basic_Training_-_Rope --- ["Basketball"] = "", -- Basketball +-- ["Basketball"] = "Баскетбол", -- Basketball ["Bat balls at your enemies and|push them into the sea!"] = "Закидайте ворогів м'ячами щоб|зіштовути їх у море!", -- ["Battalion"] = "", -- Battalion -- ["Battle Starts Now!"] = "", -- A_Space_Adventure:fruit01 @@ -208,7 +208,7 @@ -- ["Below-average pilot"] = "", -- User_Mission_-_RCPlane_Challenge -- ["Besides, why would I choose certain death?"] = "", -- A_Classic_Fairytale:queen ["Best laps per team: "] = "Кращі партії на команду: ", --- ["Best team times: "] = "", -- Racer, TechRacer +-- ["Best team times: "] = "Кращий командний час: ", -- Racer, TechRacer -- ["Better get yourself another health crate to heal your wounds."] = "", -- Basic_Training_-_Movement -- ["Better luck next time!"] = "", -- ClimbHome -- ["Better Safe Than Sorry"] = "", -- A_Space_Adventure:desert02 @@ -226,13 +226,13 @@ -- ["Biomechanic Team"] = "", -- A_Classic_Fairytale:family -- ["Bitter"] = "", -- -- ["Blanka"] = "", -- --- ["Blender"] = "", -- A_Classic_Fairytale:family +-- ["Blender"] = "Блендер", -- A_Classic_Fairytale:family -- ["Bloodpie"] = "", -- A_Classic_Fairytale:backstab -- ["Bloodrocutor"] = "", -- A_Classic_Fairytale:shadow -- ["Bloodsucker"] = "", -- A_Classic_Fairytale:shadow ["Bloody Rookies"] = "Криваві Салаги", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree -- ["Blue"] = "", -- --- ["Blue Team"] = "", -- User_Mission_-_Dangerous_Ducklings +-- ["Blue Team"] = "Блакитна команда", -- User_Mission_-_Dangerous_Ducklings -- ["Bob"] = "", -- A_Space_Adventure:cosmos -- ["Bobo"] = "", -- User_Mission_-_Nobody_Laugh -- ["Bone Jackson"] = "", -- A_Classic_Fairytale:backstab @@ -243,8 +243,8 @@ -- ["BOOM! %s really didn't like the invaders, so they decided to destroy as much as %d of them."] = "", -- Space_Invasion ["Boom!"] = "Бабах!", -- ["Boris"] = "", -- A_Space_Adventure:moon01 --- ["Boss defeated! +30 points!"] = "", -- Space_Invasion --- ["Boss Slayer! +25 points!"] = "", -- Space_Invasion +-- ["Boss defeated! +30 points!"] = "Боса переможено! +30 очок!", -- Space_Invasion +-- ["Boss Slayer! +25 points!"] = "Вбивця Боса! +25 очок!", -- Space_Invasion -- ["Both Barrels"] = "", -- -- ["Both your hedgehogs must survive."] = "", -- User_Mission_-_Teamwork_2, User_Mission_-_Teamwork -- ["Bottom Feeder"] = "", -- Mutant @@ -299,11 +299,11 @@ -- ["Cannibal Sentry"] = "", -- A_Classic_Fairytale:journey ["Cannibals?! You're the cannibals!"] = "Канібали!? Ви канібали!", -- A_Classic_Fairytale:enemy ["Cannibals"] = "Канібали", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood --- ["Can you do it?"] = "", -- A_Space_Adventure:ice02 +-- ["Can you do it?"] = "Ти можеш це зробити?", -- A_Space_Adventure:ice02 -- ["Cappy"] = "", -- Basic_Training_-_Movement -- ["Captain Lime"] = "", -- A_Space_Adventure:fruit01, A_Space_Adventure:fruit02 -- ["Captain Lime offered his help if you assist him in battle."] = "", -- A_Space_Adventure:fruit01 --- ["Capture The Flag"] = "", -- Capture_the_Flag, CTF_Blizzard +-- ["Capture The Flag"] = "Захоплення прапора", -- Capture_the_Flag, CTF_Blizzard -- ["Careful, hedgehogs can't swim!"] = "", -- Basic_Training_-_Movement ["Careless"] = "Безтурботний", -- ["Carol"] = "", -- A_Classic_Fairytale:family @@ -323,7 +323,7 @@ -- ["Change Sprite Frame: [Precise]+[Left], [Precise]+[Right]"] = "", -- HedgeEditor -- ["Change Sprite: [Left], [Right]"] = "", -- HedgeEditor -- ["Change Timer: [Left], [Right]"] = "", -- HedgeEditor --- ["Change weapon: [Long jump] or [Slot 1]-[Slot 3]"] = "", -- Tumbler +-- ["Change weapon: [Long jump] or [Slot 1]-[Slot 3]"] = "Змінити Зброю: [Довгий стрибок] або [Слот 1]-[Слот 3]", -- Tumbler -- ["Charmander"] = "", -- -- ["Chasing the blue hog"] = "", -- A_Space_Adventure:moon02 -- ["Cheater"] = "", -- User_Mission_-_RCPlane_Challenge @@ -375,10 +375,10 @@ ["Complete the track as fast as you can!"] = "Подолайте трасу так швидко, як тільки зможете!", -- ["Completion time: %.2fs"] = "", -- User_Mission_-_Rope_Knock_Challenge -- ["Comrades! Sail me away!"] = "", -- A_Classic_Fairytale:queen --- ["Configuration accepted."] = "", -- WxW --- ["Configuration phase"] = "", -- WxW --- ["Congrats! You won!"] = "", -- A_Space_Adventure:moon01 --- ["Congratulations"] = "", -- Basic_Training_-_Rope +-- ["Configuration accepted."] = "Привітання прийняті.", -- WxW +-- ["Configuration phase"] = "Привітальна фраза", -- WxW +-- ["Congrats! You won!"] = "Вітання! Ви перемогли!", -- A_Space_Adventure:moon01 +-- ["Congratulations"] = "Вітання", -- Basic_Training_-_Rope -- ["Congratulations, you acquired the device part!"] = "", -- A_Space_Adventure:ice01 -- ["Congratulations, you are the best!"] = "", -- A_Space_Adventure:desert03 -- ["Congratulations, you are the fastest!"] = "", -- A_Space_Adventure:moon02 @@ -409,18 +409,18 @@ -- ["Corporationals"] = "", -- A_Classic_Fairytale:queen -- ["Corpsemonger"] = "", -- A_Classic_Fairytale:shadow -- ["Corpse Thrower"] = "", -- A_Classic_Fairytale:epil --- ["Cost"] = "", -- Construction_Mode --- ["Cost: %d"] = "", -- Construction_Mode +-- ["Cost"] = "Ціна", -- Construction_Mode +-- ["Cost: %d"] = "Ціна: %d", -- Construction_Mode -- ["Cotton Needer"] = "", -- Mutant -- ["Count Hogula"] = "", -- --- ["Coward"] = "", -- A_Classic_Fairytale:queen +-- ["Coward"] = "Боягуз", -- A_Classic_Fairytale:queen -- ["Crate Before Attack: %s"] = "", -- WxW -- ["Crate Before Attack: You must collect a crate before you can attack."] = "", -- WxW -- ["Crate Placer"] = "", -- Construction_Mode -- ["Crates: Crates drop more often with a higher chance of bonus ammo"] = "", -- Battalion -- ["Crates: Crates drop randomly and may be empty"] = "", -- Battalion -- ["Crates: Crates drop randomly with chance of being empty"] = "", -- Battalion --- ["Crates left: %d"] = "", -- User_Mission_-_RCPlane_Challenge +-- ["Crates left: %d"] = "Залишилось ящиків: %d", -- User_Mission_-_RCPlane_Challenge ["Crates Left:"] = "Залишилось ящиків:", -- User_Mission_-_RCPlane_Challenge -- ["Crates per turn: %d"] = "", -- WxW -- ["crate(s)"] = "", -- SpeedShoppa @@ -444,12 +444,12 @@ -- ["+%d Ammo"] = "", -- Space_Invasion ["Dangerous Ducklings"] = "Небезпечні Каченята", -- ["Dark Strawberry"] = "", -- A_Space_Adventure:fruit02 --- ["+%d"] = "", -- Battalion +-- ["+%d"] = "+%d", -- Battalion -- ["%d crate(s) remaining"] = "", -- SpeedShoppa -- ["%d damage was dealt in this game."] = "", -- Mutant --- ["%d / %d"] = "", -- Battalion --- ["%d | %d"] = "", -- Mutant --- ["%d/%d"] = "", -- SpeedShoppa +-- ["%d / %d"] = "%d / %d", -- Battalion +-- ["%d | %d"] = "%d | %d", -- Mutant +-- ["%d/%d"] = "%d/%d", -- SpeedShoppa -- ["Deadly Grape"] = "", -- A_Space_Adventure:fruit02 ["Deadweight"] = "Власна вага", -- ["Deal 15 damage + 10% of your hog’s health to all hogs around you and get 2/3 back."] = "", -- Continental_supplies @@ -468,19 +468,19 @@ -- ["Deletion Mode"] = "", -- HedgeEditor -- ["Deletition Mode"] = "", -- HedgeEditor ["Demolition is fun!"] = "Руйнування це весело!", --- ["Demo"] = "", -- The_Specialists +-- ["Demo"] = "Демо", -- The_Specialists -- ["Dense Cloud"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united -- ["Dense Cloud must have already told them everything..."] = "", -- A_Classic_Fairytale:shadow -- ["Dense Cloud?! What are you doing?!"] = "", -- A_Classic_Fairytale:queen --- ["Depleted Kamikaze! +5 points!"] = "", -- Space_Invasion +-- ["Depleted Kamikaze! +5 points!"] = "Виснажений Камікадзе! +5 очок!", -- Space_Invasion -- ["Derp"] = "", -- User_Mission_-_Nobody_Laugh --- ["Desert Storm"] = "", -- +-- ["Desert Storm"] = "Пустельний шторм", -- -- ["Destroy all targets with no more than 10 bazookas."] = "", -- Basic_Training_-_Bazooka -- ["Destroy all targets with no more than 5 bazookas."] = "", -- Basic_Training_-_Bazooka -- ["Destroy all the targets!"] = "", -- Basic_Training_-_Bazooka, Basic_Training_-_Grenade -- ["Destroyer of planes"] = "", -- User_Mission_-_RCPlane_Challenge -- ["Destroy him, Leaks A Lot! He is responsible for the deaths of many of us!"] = "", -- A_Classic_Fairytale:first_blood --- ["Destroy invaders and collect bonuses to score points."] = "", -- Space_Invasion +-- ["Destroy invaders and collect bonuses to score points."] = "Знищіть загарбників і зберіть бонуси, щоб набрати очки.", -- Space_Invasion -- ["Destroy the targets!"] = "", -- Basic_Training_-_Bazooka, Basic_Training_-_Grenade -- ["Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."] = "", -- A_Classic_Fairytale:first_blood -- ["Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"] = "", -- A_Classic_Fairytale:first_blood @@ -496,8 +496,8 @@ -- ["Did you really think that we needed the help of one of you?"] = "", -- A_Classic_Fairytale:queen -- ["Did you see him coming?"] = "", -- A_Classic_Fairytale:shadow -- ["Did you warn the village?"] = "", -- A_Classic_Fairytale:shadow --- ["Die, die, die!"] = "", -- A_Classic_Fairytale:dragon --- ["Difficulty: "] = "", -- Continental_supplies +-- ["Die, die, die!"] = "Вмри, вмри, вмри!", -- A_Classic_Fairytale:dragon +-- ["Difficulty: "] = "Складність: ", -- Continental_supplies -- ["Difficulty: Easy"] = "", -- A_Classic_Fairytale:first_blood -- ["Difficulty: Hard"] = "", -- A_Classic_Fairytale:first_blood -- ["Dimitry"] = "", -- @@ -523,7 +523,7 @@ -- ["Don't hit yourself!"] = "", -- Basic_Training_-_Bazooka -- ["Don't touch the flames!"] = "", -- ClimbHome -- ["Don't you dare harming our tribe!"] = "", -- A_Classic_Fairytale:queen --- ["Double kill!"] = "", -- Mutant +-- ["Double kill!"] = "Подвійне вбивство!", -- Mutant ["Double Kill!"] = "Подвійне Вбивство!", -- ["Do you have any idea how bad an exploding arrow hurts?"] = "", -- A_Classic_Fairytale:queen -- ["Do you have any idea how valuable grass is?"] = "", -- A_Classic_Fairytale:enemy @@ -544,14 +544,14 @@ ["Drills"] = "Дрелі", -- A_Classic_Fairytale:backstab -- ["Dr. Jenner"] = "", -- -- ["Dr. Jung"] = "", -- --- ["Drone Hunter! +10 points!"] = "", -- Space_Invasion +-- ["Drone Hunter! +10 points!"] = "Мисливець за Джмелями! +10 очок!", -- Space_Invasion -- ["Drop a ball of dirt which turns into a|cluster on impact. Doesn’t end turn."] = "", -- Continental_supplies -- ["Drop a bomb: [Drop some heroic wind that will turn into a bomb on impact]"] = "", -- Continental_supplies -- ["- Dropped flags may be returned or recaptured"] = "", -- Capture_the_Flag -- ["Dropping a weapon while in water would just drown it, but launching one would work."] = "", -- Basic_Training_-_Flying_Saucer -- ["Drop weapon (while on rope): [Long Jump]"] = "", -- Basic_Training_-_Rope ["Drowner"] = "Потопаючий", --- ["Dr. Parkinson"] = "", -- +-- ["Dr. Parkinson"] = "Доктор Паркінсон", -- -- ["Drunk greenhorn"] = "", -- User_Mission_-_RCPlane_Challenge -- ["Drunk with power, perhaps!"] = "", -- A_Classic_Fairytale:queen -- ["%d sec"] = "", -- Construction_Mode @@ -589,7 +589,7 @@ -- ["Eckles"] = "", -- User_Mission_-_Nobody_Laugh -- ["Eclipse"] = "", -- Big_Armory -- ["Editing Commands: (Use while no weapon is selected)"] = "", -- HedgeEditor --- ["Ehm, okay ..."] = "", -- A_Space_Adventure:moon01 +-- ["Ehm, okay ..."] = "Гм, гаразд ...", -- A_Space_Adventure:moon01 -- ["Elderbot"] = "", -- A_Classic_Fairytale:family -- ["Elimate your captor."] = "", -- User_Mission_-_The_Great_Escape ["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Знищіть всі цілі до закінчення часу.|У вас безмежні боєприпаси.", --Bazooka, Shotgun, SniperRifle @@ -606,13 +606,13 @@ -- ["Enabled"] = "", -- WxW -- ["Enemy kills: Collect victim's weapons and +%d%% of its base health"] = "", -- Battalion ["Energetic Engineer"] = "Енергетичний Інженер", --- ["Engineer"] = "", -- HedgeEditor, The_Specialists +-- ["Engineer"] = "Інженер", -- HedgeEditor, The_Specialists ["Enjoy the swim..."] = "Насолоджуйся плаванням...", -- ["Entered boredom phase! Discrepancies detected …"] = "", -- A_Classic_Fairytale:queen -- ["Epilogue"] = "", -- A_Classic_Fairytale:epil -- ["ERROR [getHogInfo]: Hog is nil!"] = "", -- Battalion -- ["Eugene"] = "", -- --- ["Europe"] = "", -- Continental_supplies +-- ["Europe"] = "Європа", -- Continental_supplies ["Everyone knows this."] = "Кожен це знає.", -- A_Classic_Fairytale:enemy ["Every single time!"] = "КОжного разу!", -- A_Classic_Fairytale:dragon -- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy @@ -693,17 +693,17 @@ -- ["Fruit"] = "", -- -- ["Fruit Assassins"] = "", -- A_Space_Adventure:fruit02 -- ["Fruity"] = "", -- --- ["Fuel: %d"] = "", -- Tumbler +-- ["Fuel: %d"] = "Пальне: %d", -- Tumbler -- ["Fuzzy Beard"] = "", -- -- ["“g=150”, where 150 is 150% of normal gravity."] = "", -- Gravity -- ["“g=50, g2=150, period=4000” for gravity changing|from 50 to 150 and back with period of 4000 ms."] = "", -- Gravity --- ["Galaxy Guardians"] = "", -- Big_Armory +-- ["Galaxy Guardians"] = "Охоронці Галактики", -- Big_Armory ["Game Modifiers: "] = "Модифікатори Гри: ", --- ["Game over!"] = "", -- Space_Invasion +-- ["Game over!"] = "Кінець гри!", -- Space_Invasion ["GAME OVER!"] = "КІНЕЦЬ ГРИ!", ["Game Started!"] = "Гра почалась!", ["Game? Was this a game to you?!"] = "Гра? Це для тебе була лише гра?!", -- A_Classic_Fairytale:enemy --- ["Gangsters"] = "", -- +-- ["Gangsters"] = "Гангстери", -- -- ["GasBomb"] = "", -- Continental_supplies -- ["Gas Gargler"] = "", -- A_Classic_Fairytale:queen -- ["Gasp! A smuggler!"] = "", -- A_Space_Adventure:desert01 @@ -748,7 +748,7 @@ -- ["Glassy"] = "", -- -- ["Goal Definition Mode"] = "", -- HedgeEditor -- ["GOAL DEFINITION MODE"] = "", -- HedgeEditor --- ["Goal: Score %d points or more to win!"] = "", -- Mutant +-- ["Goal: Score %d points or more to win!"] = "Мета: Наберіть %d очок чи більше для перемоги!", -- Mutant -- ["Go and collect the crate"] = "", -- A_Space_Adventure:cosmos -- ["Godai"] = "", -- -- ["Go down and save these PAotH hogs!"] = "", -- A_Space_Adventure:moon01 @@ -814,7 +814,7 @@ -- ["Guards"] = "", -- A_Space_Adventure:cosmos -- ["Guile"] = "", -- ["Guys, do you think there's more of them?"] = "Хлопці, думаєте їх ще більше?", -- A_Classic_Fairytale:backstab --- ["Haha! Come!"] = "", -- A_Classic_Fairytale:queen +-- ["Haha! Come!"] = "Хаха! Ходи!", -- A_Classic_Fairytale:queen ["Hahahaha!"] = "Хахахаха!", -- ["Haha, I love the look on your face!"] = "", -- A_Classic_Fairytale:queen ["Haha, now THAT would be something!"] = "Хаха, от ЦЕ буде щось!", @@ -900,7 +900,7 @@ -- ["Hey, Hog Solo! Finally you have come!"] = "", -- A_Space_Adventure:moon01 -- ["Hey! I was supposed to collect it!"] = "", -- A_Space_Adventure:fruit02 -- ["Hey, %s! Look, someone is stealing the saucer!"] = "", -- A_Space_Adventure:cosmos --- ["Hey! This is cheating!"] = "", -- A_Classic_Fairytale:journey +-- ["Hey! This is cheating!"] = "Ей! Так не чесно!", -- A_Classic_Fairytale:journey -- ["Hidden"] = "", -- portal -- ["High Gravity: Gravity is %i%%"] = "", -- Gravity -- ["High Jump: [Backspace]"] = "", -- Basic_Training_-_Movement @@ -1236,8 +1236,8 @@ -- ["Jimmy"] = "", -- -- ["Jingo"] = "", -- -- ["Joe"] = "", -- A_Space_Adventure:moon01 --- ["John"] = "", -- A_Classic_Fairytale:journey --- ["John Snow"] = "", -- A_Space_Adventure:ice01 +-- ["John"] = "Джон", -- A_Classic_Fairytale:journey +-- ["John Snow"] = "Джон Сноу", -- A_Space_Adventure:ice01 -- ["Jolly Roger"] = "", -- -- ["Jones"] = "", -- -- ["Judas"] = "", -- A_Classic_Fairytale:backstab @@ -1251,7 +1251,7 @@ -- ["Kaboom!"] = "", -- Basic_Training_-_Flying_Saucer -- ["Kaboom! Hahahaha! Take this, stupid meteorite!"] = "", -- A_Space_Adventure:final -- ["Kamikaze"] = "", -- Construction_Mode --- ["Kamikaze Expert! +15 points!"] = "", -- Space_Invasion +-- ["Kamikaze Expert! +15 points!"] = "Камікадзе Експерт! +15 очок!", -- Space_Invasion ["Keep it up!"] = "Так тримати!", -- ["Ken"] = "", -- -- ["Kenshi"] = "", -- @@ -1262,23 +1262,23 @@ ["Killing spree!"] = "Череда вбивств!", -- ["Killing the specialists"] = "", -- A_Space_Adventure:death02 -- ["KILL IT!"] = "", -- A_Classic_Fairytale:first_blood --- ["Kills: %d"] = "", -- Space_Invasion +-- ["Kills: %d"] = "Вбивств: %d", -- Space_Invasion -- ["Kill the aliens!"] = "", -- A_Classic_Fairytale:dragon -- ["Kill the cannibal!"] = "", -- A_Classic_Fairytale:first_blood -- ["Kill The Leader"] = "", -- WxW -- ["Kill The Leader: You must also hit the team with the most health."] = "", -- WxW -- ["Kill the traitor, %s, or spare his life!"] = "", -- A_Classic_Fairytale:backstab --- ["--- King ---"] = "", -- Battalion --- ["King"] = "", -- Battalion +-- ["--- King ---"] = "--- Король ---", -- Battalion +-- ["King"] = "Король", -- Battalion -- ["King Customer"] = "", -- Challenge_-_Speed_Shoppa_-_ShoppaKing -- ["--- King Mode ---"] = "", -- Battalion --- ["Knight"] = "", -- Battalion +-- ["Knight"] = "Лицар", -- Battalion -- ["Knives"] = "", -- -- ["Knockball"] = "", -- Knockball -- ["Knockball weapon"] = "", -- Knockball -- ["Knock off the enemies from the left-most place of the map!"] = "", -- A_Space_Adventure:fruit01 -- ["koda"] = "", -- --- ["Kostya"] = "", -- +-- ["Kostya"] = "Костя", -- -- ["Lady Mango"] = "", -- A_Space_Adventure:fruit01, A_Space_Adventure:fruit02 -- ["LandFlag Modification Mode"] = "", -- HedgeEditor -- ["Land mines explode instantly."] = "", -- User_Mission_-_Teamwork_2 @@ -1385,15 +1385,15 @@ -- ["Mine Placement Mode"] = "", -- Construction_Mode -- ["MINE PLACEMENT MODE"] = "", -- HedgeEditor -- ["Mines explode after %d s."] = "", -- Mutant --- ["Mines time: 0s-5s"] = "", -- SimpleMission --- ["Mines time: 0 seconds"] = "", -- portal, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork, User_Mission_-_The_Great_Escape, A_Space_Adventure:desert01, A_Space_Adventure:final, A_Space_Adventure:fruit02, A_Space_Adventure:ice01 --- ["Mines time: 1.5 seconds"] = "", -- A_Space_Adventure:death01 --- ["Mines time: %.1fs"] = "", -- SimpleMission --- ["Mines time: 1 second"] = "", -- User_Mission_-_Diver, User_Mission_-_Newton_and_the_Hammock, A_Space_Adventure:desert02 --- ["Mines time: %.2fs"] = "", -- SimpleMission --- ["Mines time: 3 seconds"] = "", -- A_Classic_Fairytale:journey --- ["Mines time: 5 seconds"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:journey --- ["Mines time: %ds"] = "", -- SimpleMission +-- ["Mines time: 0s-5s"] = "Час детонування мін: 0с-5с", -- SimpleMission +-- ["Mines time: 0 seconds"] = "Час детонування мін: 0 секунд", -- portal, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork, User_Mission_-_The_Great_Escape, A_Space_Adventure:desert01, A_Space_Adventure:final, A_Space_Adventure:fruit02, A_Space_Adventure:ice01 +-- ["Mines time: 1.5 seconds"] = "Час детонування мін: 1.5 секунди", -- A_Space_Adventure:death01 +-- ["Mines time: %.1fs"] = "Час детонування мін: %.2fс", -- SimpleMission +-- ["Mines time: 1 second"] = "Час детонування мін: 1 секунда", -- User_Mission_-_Diver, User_Mission_-_Newton_and_the_Hammock, A_Space_Adventure:desert02 +-- ["Mines time: %.2fs"] = "Час детонування мін: %.2fс", -- SimpleMission +-- ["Mines time: 3 seconds"] = "Час детонування мін: 3 секунди", -- A_Classic_Fairytale:journey +-- ["Mines time: 5 seconds"] = "Час детонування мін: 5 секунд", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:journey +-- ["Mines time: %ds"] = "Час детонування мін: %dс", -- SimpleMission -- ["Mine Strike"] = "", -- Construction_Mode -- ["Minion"] = "", -- A_Space_Adventure:moon01 -- ["Minions"] = "", -- A_Space_Adventure:moon01 @@ -1428,7 +1428,7 @@ ["Movement: [Up], [Down], [Left], [Right]"] = "Керування: [Вверх], [Вниз], [Вліво], [Вправо]", -- ["Mr Mango"] = "", -- A_Space_Adventure:fruit01 -- ["Mudkip"] = "", -- --- ["Multi-shot! +15 points!"] = "", -- Space_Invasion +-- ["Multi-shot! +15 points!"] = "Мультипостріл! +15 очок!", -- Space_Invasion -- ["Multi-Use: You can take and use the same ammo type multiple times in a turn"] = "", -- Highlander -- ["Muriel"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen -- ["Muscle Dissolver"] = "", -- A_Classic_Fairytale:shadow @@ -1451,12 +1451,12 @@ -- ["Near Secret Base 17 of PAotH in the rural Hogland ..."] = "", -- A_Space_Adventure:cosmos -- ["nemo"] = "", -- -- ["Neutralize your enemies and be careful!"] = "", -- A_Space_Adventure:moon01 --- ["New barrels per turn: %d"] = "", -- Tumbler --- ["New clan record: %.1fs"] = "", -- Racer, TechRacer +-- ["New barrels per turn: %d"] = "Нових бочок на хід: %d", -- Tumbler +-- ["New clan record: %.1fs"] = "Новий рекорд клану: %.1fс", -- Racer, TechRacer ["NEW fastest lap: "] = "НОВА найшвидша партія: ", --- ["New mines per turn: %d"] = "", -- Tumbler --- ["New race record: %.1fs"] = "", -- Racer, TechRacer --- ["Newton and the Hammock"] = "", -- User_Mission_-_Newton_and_the_Hammock +-- ["New mines per turn: %d"] = "Нових мін на хід: %d", -- Tumbler +-- ["New race record: %.1fs"] = "Новий рекорд гонки: %.1fс", -- Racer, TechRacer +-- ["Newton and the Hammock"] = "Ньютон і Гамак", -- User_Mission_-_Newton_and_the_Hammock -- ["Next target is ready!"] = "", -- Basic_Training_-_Flying_Saucer -- ["Next time you play \"Searching in the dust\" you'll have an RC plane available."] = "", -- A_Space_Adventure:desert03 -- ["Nice!"] = "", -- A_Space_Adventure:cosmos @@ -1556,7 +1556,7 @@ -- ["Okay then!"] = "", -- A_Space_Adventure:fruit02 -- ["Okay, then you have to go and take some of the weapons we have hidden in case of an emergency!"] = "", -- A_Space_Adventure:moon01 -- ["Old One Eye"] = "", -- --- ["Oleg"] = "", -- +-- ["Oleg"] = "Олег", -- -- ["Olive"] = "", -- A_Classic_Fairytale:united -- ["Omnivore"] = "", -- A_Classic_Fairytale:first_blood -- ["Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."] = "", -- A_Classic_Fairytale:first_blood @@ -1619,7 +1619,7 @@ -- ["Pincer Knights"] = "", -- Bazooka_Battlefield -- ["Pings left: %d"] = "", -- Space_Invasion -- ["Pink"] = "", -- --- ["Pirates"] = "", -- +-- ["Pirates"] = "Пірати", -- -- ["Place 2-%d waypoints using the waypoint placement tool."] = "", -- Racer -- ["Place 2 waypoints using the waypoint placement tool."] = "", -- Racer -- ["Place air mines"] = "", -- HedgeEditor @@ -1720,8 +1720,8 @@ -- ["Pyro"] = "", -- HedgeEditor, The_Specialists -- ["Pyromancer"] = "", -- Battalion -- ["Quit: [Esc]"] = "", -- Basic_Training_-_Movement --- ["Race complexity limit reached"] = "", -- Racer, TechRacer --- ["Racer"] = "", -- Racer +-- ["Race complexity limit reached"] = "Досягнута межа складності гонки", -- Racer, TechRacer +-- ["Racer"] = "Гонщик", -- Racer -- ["Racer tool"] = "", -- Racer -- ["Race"] = "", -- TrophyRace -- ["Rachel"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen @@ -1791,10 +1791,10 @@ -- ["Rotten"] = "", -- -- ["Round draw"] = "", -- Racer, TechRacer -- ["Round %d (Sudden Death in round %d)"] = "", -- Battalion --- ["Round limit: %d"] = "", -- Racer --- ["Round Limit: %d"] = "", -- Space_Invasion +-- ["Round limit: %d"] = "Межа раунду: %d", -- Racer +-- ["Round Limit: %d"] = "Межа Раунду: %d", -- Space_Invasion -- ["Round limit:"] = "", -- TechRacer --- ["Rounds complete: %d/%d"] = "", -- Racer, Space_Invasion, TechRacer +-- ["Rounds complete: %d/%d"] = "Раундів завершено: %d/%d", -- Racer, Space_Invasion, TechRacer -- ["Round's slowest lap: %.3fs by %s"] = "", -- TrophyRace -- ["Rounds until Sudden Death: %d"] = "", -- Battalion -- ["RS1"] = "", -- A_Space_Adventure:fruit03 @@ -1803,8 +1803,8 @@ -- ["Rubber Placement Mode"] = "", -- Construction_Mode -- ["RUBBER PLACEMENT MODE"] = "", -- HedgeEditor -- ["Rules:"] = "", -- Capture_the_Flag --- ["RULES:"] = "", -- Frenzy --- ["Rules: "] = "", -- Mutant +-- ["RULES:"] = "ПРАВИЛА:", -- Frenzy +-- ["Rules: "] = "Правила: ", -- Mutant -- ["Run away, you coward!"] = "", -- A_Space_Adventure:desert01 -- ["Running displacement algorithm …"] = "", -- A_Classic_Fairytale:queen -- ["Running for survival"] = "", -- A_Space_Adventure:desert02 @@ -1923,14 +1923,14 @@ -- ["sheepluva"] = "", -- -- ["Sheepy"] = "", -- -- ["She's behind that tall thingy."] = "", -- A_Classic_Fairytale:family --- ["Shield boosted! +%d power"] = "", -- Space_Invasion --- ["Shield depleted"] = "", -- Space_Invasion +-- ["Shield boosted! +%d power"] = "Щит підсилено! +%d сили", -- Space_Invasion +-- ["Shield depleted"] = "Щит вичерпаний", -- Space_Invasion ["Shield is fully recharged!"] = "Щит повністю заряджений!", --- ["Shield Master! +10 points!"] = "", -- Space_Invasion --- ["Shield Miser! +%d points!"] = "", -- Space_Invasion --- ["Shield OFF: %d power remaining"] = "", -- Space_Invasion --- ["Shield ON: %d power remaining"] = "", -- Space_Invasion --- ["Shield Seeker! +10 points!"] = "", -- Space_Invasion +-- ["Shield Master! +10 points!"] = "Майстер Щита! +10 очок!", -- Space_Invasion +-- ["Shield Miser! +%d points!"] = "Скупій Щита! +%d очок!", -- Space_Invasion +-- ["Shield OFF: %d power remaining"] = "Щит Вимкнено: %d сили залишилось", -- Space_Invasion +-- ["Shield ON: %d power remaining"] = "Щит Ввімкнено: %d сили залишилось", -- Space_Invasion +-- ["Shield Seeker! +10 points!"] = "Шукач Щита! +10 очок!", -- Space_Invasion -- ["Shinobi"] = "", -- -- ["%s hit the ground."] = "", -- User_Mission_-_Rope_Knock_Challenge -- ["Shoppa Love"] = "", -- Challenge_-_Speed_Shoppa_-_Hedgelove @@ -1982,7 +1982,7 @@ -- ["So, I believe that it's a good place to start."] = "", -- A_Space_Adventure:desert01 -- ["So, I kindly ask for your help."] = "", -- A_Space_Adventure:fruit01 -- ["So I shook my fist in the air!"] = "", -- A_Classic_Fairytale:epil --- ["Soldier"] = "", -- HedgeEditor, The_Specialists +-- ["Soldier"] = "Солдат", -- HedgeEditor, The_Specialists -- ["So, let me tell you what I know about Professor Hogevil."] = "", -- A_Space_Adventure:moon02 -- ["Some parts of the land are indestructible."] = "", -- A_Space_Adventure:fruit03 -- ["Some sick game of yours?!"] = "", -- A_Classic_Fairytale:queen @@ -2163,14 +2163,14 @@ -- ["Targets left: %d"] = "", -- TargetPractice -- ["Tatsujin"] = "", -- -- ["Tatters"] = "", -- --- ["Team %d"] = "", -- SimpleMission +-- ["Team %d"] = "Команда %d", -- SimpleMission ["Team %d: "] = "Команда %d: ", -- ["Team Identity Mode"] = "", -- HedgeEditor -- ["TEAM IDENTITY MODE"] = "", -- HedgeEditor -- ["Team of Hearts"] = "", -- Challenge_-_Speed_Shoppa_-_Hedgelove -- ["Teams are tied! Continue playing rounds until we have a winner!"] = "", -- Space_Invasion --- ["Team Scores:"] = "", -- Control --- ["Team scores:"] = "", -- Space_Invasion +-- ["Team Scores:"] = "Очки Команди", -- Control +-- ["Team scores:"] = "Очки команди", -- Space_Invasion -- ["Teamwork 2"] = "", -- User_Mission_-_Teamwork_2 -- ["Teamwork"] = "", -- User_Mission_-_Teamwork -- ["Team Zook"] = "", -- Target_Practice_-_Bazooka_easy, Target_Practice_-_Bazooka_hard @@ -2210,7 +2210,7 @@ -- ["That's why he always wears a hat since then."] = "", -- A_Space_Adventure:moon02 -- ["That traitor won't be killing us anymore!"] = "", -- A_Classic_Fairytale:queen -- ["That was just mean!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united --- ["That was pointless. The flag will respawn next round."] = "", -- CTF_Blizzard +-- ["That was pointless. The flag will respawn next round."] = "Це було безглуздо. Прапор з'явиться знов у наступному раунді.", -- CTF_Blizzard -- ["The adventure begins!"] = "", -- A_Space_Adventure:cosmos -- ["The air bombs are weaker than usual."] = "", -- Battalion -- ["The aliens respect me, even worship me!"] = "", -- A_Classic_Fairytale:queen @@ -2406,15 +2406,15 @@ -- ["Thug #%d"] = "", -- A_Space_Adventure:death01 -- ["Tie-breaking round %d"] = "", -- Space_Invasion -- ["Timbers"] = "", -- --- ["Time: %.1fs"] = "", -- Racer, TechRacer +-- ["Time: %.1fs"] = "Час: %.1fс", -- Racer, TechRacer -- ["Time: %.3fs by %s"] = "", -- TrophyRace --- ["Time: %.3fs"] = "", -- TrophyRace +-- ["Time: %.3fs"] = "Час: %.3fс", -- TrophyRace -- ["Time Box"] = "", -- Construction_Mode --- ["Timed Kamikaze! +10 points!"] = "", -- Space_Invasion --- ["Time extended! +%dsec"] = "", -- Space_Invasion --- ["Time extension: %ds"] = "", -- Tumbler +-- ["Timed Kamikaze! +10 points!"] = "Часовий Камікадзе! +10 очок!", -- Space_Invasion +-- ["Time extended! +%dsec"] = "Час продовжено! +%dсек", -- Space_Invasion +-- ["Time extension: %ds"] = "Збільшення часу: %dс", -- Tumbler -- ["Time for a more interesting stunt, but first just collect the next crate!"] = "", -- Basic_Training_-_Flying_Saucer --- ["Timer"] = "", -- Basic_Training_-_Grenade +-- ["Timer"] = "Таймер", -- Basic_Training_-_Grenade -- ["Time's up!"] = "", -- Basic_Training_-_Sniper_Rifle, SpeedShoppa, Space_Invasion -- ["Time’s up!"] = "", -- TargetPractice -- ["Time to run!"] = "", -- A_Space_Adventure:fruit01 @@ -2438,7 +2438,7 @@ -- ["Toggle Gear Information: [Precise]+[3]"] = "", -- HedgeEditor -- ["Toggle Help: [Precise]+[1]"] = "", -- HedgeEditor -- ["Toggle Placement/Deletion: [Left], [Right]"] = "", -- HedgeEditor --- ["Toggle Shield: [Long jump]"] = "", -- Space_Invasion +-- ["Toggle Shield: [Long jump]"] = "Перемкнути Щит [Довгий стрибок]", -- Space_Invasion -- ["To help you, of course!"] = "", -- A_Classic_Fairytale:journey -- ["To launch a projectile in mid-flight, hold [Precise] and press [Long jump]."] = "", -- Basic_Training_-_Flying_Saucer -- ["Tony"] = "", -- @@ -2459,9 +2459,9 @@ -- ["To win the game you have to pass into the rings in time."] = "", -- A_Space_Adventure:ice02 -- ["To win the game you have to stand next to Thanta."] = "", -- A_Space_Adventure:ice01 ["Toxic Team"] = "Токсична Команда", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork --- ["Track completed!"] = "", -- Racer, TechRacer +-- ["Track completed!"] = "Трасу пройдено", -- Racer, TechRacer -- ["Trainee"] = "", -- TargetPractice --- ["Training"] = "", -- Basic_Training_-_Flying_Saucer, Basic_Training_-_Rope +-- ["Training"] = "Тренування", -- Basic_Training_-_Flying_Saucer, Basic_Training_-_Rope -- ["Training complete!"] = "", -- Basic_Training_-_Flying_Saucer -- ["Training Team"] = "", -- TargetPractice -- ["Traitors"] = "", -- A_Classic_Fairytale:epil @@ -2617,7 +2617,7 @@ -- ["Water: Rises by 37 per turn"] = "", -- Battalion -- ["Waypoint Editing Mode"] = "", -- HedgeEditor -- ["WAYPOINT EDITING MODE"] = "", -- HedgeEditor --- ["Waypoint placed. Available points remaining: %d"] = "", -- Racer +-- ["Waypoint placed. Available points remaining: %d"] = "Точка шляху розміщена. Залишилось точок: %d", -- Racer -- ["Waypoint placement phase"] = "", -- Racer -- ["Waypoint removed. Available points: %d"] = "", -- Racer -- ["Waypoints remaining: %d"] = "", -- Racer, TechRacer @@ -2749,7 +2749,7 @@ -- ["Why do you not like me?"] = "", -- A_Classic_Fairytale:shadow -- ["Why do you want to take over our island?"] = "", -- A_Classic_Fairytale:enemy -- ["Why me?!"] = "", -- A_Classic_Fairytale:backstab --- ["Why %s? Why?"] = "", -- A_Classic_Fairytale:backstab +-- ["Why %s? Why?"] = "Чому %s? Чому?", -- A_Classic_Fairytale:backstab -- ["Why, why, why, why!"] = "", -- A_Classic_Fairytale:queen -- ["Why would they do this?"] = "", -- A_Classic_Fairytale:backstab -- ["- Will get 1-3 random weapons"] = "", -- Continental_supplies diff -r ec07ddc1a4a4 -r fae0dd90663b share/hedgewars/Data/Locale/uk.txt --- a/share/hedgewars/Data/Locale/uk.txt Fri Nov 09 14:12:00 2018 +0300 +++ b/share/hedgewars/Data/Locale/uk.txt Fri Nov 09 14:15:22 2018 +0300 @@ -307,7 +307,7 @@ 04:00=Атакуй ворогів використовуючи просту гранату.|Вона вибухне як тільки її таймер доходить до нуля.|1-5: Вистав таймер гранати|Атака: Утримуй щоб метнути сильніше 04:01=Атакуй ворогів використовуючи кластерну|бомбу. Вона розділиться на менші бомби|коли таймер досягає нуля.|1-5: Вистав таймер гранати|Атака: Утримуй щоб метнути сильніше 04:02=Атакуй ворогів балістичним снарядом,|на політ якого впливає вітер.|Атака: Утримуй щоб стрельнути сильніше -04:03=Запусти вибухо-небезпечну бджолу, яка|полетить до вибраної цілі. Не стріляй на|повну силу щоб поліпшити її точність.|Курсор: Вибери ціль|Атака: Утримуй щоб стрельнути сильніше +04:03=Запусти вибухонебезпечну бджолу, яка|полетить до вибраної цілі. Не стріляй на|повну силу щоб поліпшити її точність.|Курсор: Вибери ціль|Атака: Утримуй щоб стрельнути сильніше 04:04=Атакуй ворогів використовуючи рушницю з двома|пострілами.Завдяки її розмаху тобі не потрібні точні|попадання щоб зашкодити супернику.|Атака: Стріляй (кілька разів) 04:05=Прямуй під землю! Візьми відбійний молоток,|просвердли в землі дірку та досягни інших областей.|Атака: Почни або заверши рити 04:06=Засмутився? Немає можливості атакувати? Хочеш зберегти|боєприпаси? Без проблем! Просто пропусти хід, боягузе!|Атака: Пропусти свою чергу без бою @@ -325,7 +325,7 @@ 04:18=Потрібний додатковий захист або хочеш пройти|непрохідну землю? Розмісти кілька балок як|тобі до вподоби.|Вліво/Вправо: Вибери потрібну балку|Курсор: Встанови балку в доступне місце 04:19=Застосована в потрбний момент телепортація|може бути могутнішою більшості зброї,|оскільки дозволяє вберегти їжаків від|небезпечних ситуацій за лічені секунди.|Курсор: Вибери цільовий регіон 04:20=Дозволяє здійснити поточний хід|іншим їжаком.|Атака: Ввімкни перемикання їжаків -04:21=Стріляє гранато-подібним снарядом, який|при зіткненні розлетиться на декілька бомб.|Атака: Стріляй з всієї сили +04:21=Стріляє гранатоподібним снарядом, який|при зіткненні розлетиться на декілька бомб.|Атака: Стріляй з всієї сили 04:22=Не лише для Індіани Джонс! Батіг корисний|в багатьох ситуаціях. Особливо|коли треба штовхнути когось з кручі.|Атака: Бий все, що бачиш перед собою 04:23=Коли нічого втрачати, це може бути|доречним. Принеси їжака в жертву, запустивши|його в певному напрямку та шкодячи всьому|на його шляху.В кінці шляху він вибухне.|Атака: Почни спустошливу та смертоносну атаку 04:24=З днем народження! Запусти цей торт, нехай він|йде прямо до твоїх ворогів і влаштує їм вибухову|вечірку. Торт може пройти майже всюди|але може вибухнути раніше, ніж треба.|Атака: Запусти торт або хай зупиниться і вибухне @@ -346,7 +346,7 @@ 04:39=Лети до іншої частини карти на літаючій тарілці.|Цей важко керований пристрій здатний перенести|тебе на практично будь-яку позицію поля бою.|Атака: Активувати|Вверх/Вліво/Вправо: Приклади зусилля в одному напрямку|Довгий Стрибок: Кинь гранати чи подібну зброю 04:40=Покрий землю вогнем, використавши цю плашечку|наповнену горючою (незабаром) рідиною.|Атака: Утримуй щоб стрельнути сильніше 04:41=Природа може переплюнути навіть літаючу|тарілку. Пташка може поносити їжака|навколо та скинути яйця на ворогів!|Атака: Активуй та скинь яйця|Вверх/Вліво/Вправо: Лети в одному напрямку -04:42=Цей портативний портал здатний миттєво преренести|вас, ваших ворогів, чи ваше озброєння між двома|точками на місцевості.|Використовуйте його з розумом і ваша кампанія буде...|ДУЖЕ УСПІШНОЮ!|Атака: Вистріли портал|Переключити: Змінюй колір порталу +04:42=Цей портативний портал здатний миттєво перенести|вас, ваших ворогів, чи ваше озброєння між двома|точками на місцевості.|Використовуйте його з розумом і ваша кампанія буде...|ДУЖЕ УСПІШНОЮ!|Атака: Вистріли портал|Переключити: Змінюй колір порталу 04:43=Проведи свій музичний дебют з величезним|успіхом! Скинь фортепіано з небес, але май|на увазі...хтось повинен на ньому грати,|і це може коштувати тобі життя!|Курсор: Вкажи цільовий регіон|F1-F9: Грай на піаніно 04:44=Це не просто сир, це біологічна зброя! Він не|нанесе багато шкоди, коли таймер досягне нуля,|але він точно отруїть всіх, хто відчув його запах!|1-5: Встановити таймер гранати|Атака: Утримуй щоб метнути сильніше 04:45=Всі ці класи фізики нарешті окупились, пусти|руйнівну Синусну хвилю на ворогів. Бережись,|ця зброя не іграшка. (Ця зброя не завершена)|Атака: Стріляй diff -r ec07ddc1a4a4 -r fae0dd90663b tools/find_outdated_engine_translations.sh --- a/tools/find_outdated_engine_translations.sh Fri Nov 09 14:12:00 2018 +0300 +++ b/tools/find_outdated_engine_translations.sh Fri Nov 09 14:15:22 2018 +0300 @@ -33,8 +33,10 @@ TEMP_EN=$(mktemp); TEMP_LANG=$(mktemp); +#hg fa en.txt | grep -P "^\s*\d+:\s+0[013-6]:" > $TEMP_EN; hg blame en.txt | grep -P "^\s*\d+:\s+0[013-6]:" > $TEMP_EN; +#hg fa $BLAMELANGFILE | grep -P "^\s*\d+:\s+0[013-6]:" > $TEMP_LANG; hg blame $BLAMELANGFILE | grep -P "^\s*\d+:\s+0[013-6]:" > $TEMP_LANG; cat $TEMP_EN | while read f; @@ -48,7 +50,9 @@ if (($REV>$OTHER_REV)); then TEXT=$(echo $f | sed 's/^\s*[0-9]\+:\s*[0-9]\+:[0-9]\+=//'); - OLD_TEXT=$(hg grep --all -r "1:$OTHER_REV" "$CODE" en.txt | tail -n1 | sed 's/.*en.txt:[0-9]\+:[+-]:[0-9]\+:[0-9]\+=//;s/ //'); + # script runs ~20% faster than with blame but nonstandard + # OLD_TEXT=$(hg fa -r "$OTHER_REV" en.txt | grep -P "^\s*\d+:\s+${CODE}=" | sed 's/^\s*[0-9]\+:\s*[0-9]\+:[0-9]\+=//;s/ //'); + OLD_TEXT=$(hg blame -r "$OTHER_REV" en.txt | grep -P "^\s*\d+:\s+${CODE}=" | sed 's/^\s*[0-9]\+:\s*[0-9]\+:[0-9]\+=//;s/ //'); COMPARE_TEXT=$TEXT; COMPARE_OLD_TEXT=$OLD_TEXT; @@ -67,9 +71,9 @@ else printf '━%.0s' $(seq $COLUMNS); fi; - echo "$TEXT ← Current English"; - echo "$OLD_TEXT ← English at time of translation"; - echo "$(echo $OTHER | sed 's/^\s*[0-9]\+:\s*[0-9]\{2\}:[0-9]\{2\}=//') ← current translation"; + echo "${CODE}=$TEXT ← Current English"; + echo "${CODE}=$OLD_TEXT ← English at time of translation"; + echo "${CODE}=$(echo $OTHER | sed 's/^\s*[0-9]\+:\s*[0-9]\{2\}:[0-9]\{2\}=//') ← current translation"; fi; fi; fi;