# HG changeset patch # User unc0rr # Date 1449423381 -10800 # Node ID 42a9dd7b724caa6960af01781032394771040030 # Parent 2572afe532af5e7c4733d9fe2533785a44098199# Parent 6f119783a1adb69759c00dea16f39d2c3cefb0a8 Merge default diff -r 2572afe532af -r 42a9dd7b724c .hgtags --- a/.hgtags Sun Dec 06 20:35:58 2015 +0300 +++ b/.hgtags Sun Dec 06 20:36:21 2015 +0300 @@ -70,6 +70,7 @@ 4c4f22cc3fa4e6c1e5cd6cce35350dd93478415f 0.9.22-release 4c4f22cc3fa4e6c1e5cd6cce35350dd93478415f 0.9.22-release 9621fdcad96589b3fd78713a0f31e72f26f068bb 0.9.22-release +a0163b8302c592aac60d98134bb6730f390fcaad Hedgewars-iOS-2.0 7e55468ffe384a3065524c483eb5e3cdb1658fd5 fab746a3597e 0000000000000000000000000000000000000000 fab746a3597e d9622394ec9c2974a84b9b4d9e6c0ac26c4060ff 0.9.22-RC diff -r 2572afe532af -r 42a9dd7b724c .travis.yml --- a/.travis.yml Sun Dec 06 20:35:58 2015 +0300 +++ b/.travis.yml Sun Dec 06 20:36:21 2015 +0300 @@ -1,7 +1,10 @@ language: c +os: + - linux + - osx branches: - except: - gh-pages + only: + master compiler: - gcc - clang @@ -11,15 +14,41 @@ - BUILD_ARGS="-DNOSERVER=1 -DBUILD_ENGINE_C=1" - BUILD_ARGS="-DNOSERVER=1 -DNOVIDEOREC=1 -DNOPNG=1" - BUILD_ARGS="-DNOSERVER=1 -DLUA_SYSTEM=0 -DPHYSFS_SYSTEM=0" -matrix: - allow_failures: - # Failures we expect here -before_install: - - sudo add-apt-repository -y ppa:zoogie/sdl2-snapshots - - sudo apt-get update -qq - - sudo apt-get install debhelper cmake dpkg-dev libqt4-dev qt4-qmake libphysfs-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev libsdl2-net-dev bzip2 ghc libghc-mtl-dev libghc-parsec3-dev libghc-bytestring-show-dev libghc-vector-dev libghc-zlib-dev libghc-random-dev libghc-stm-dev libghc-network-dev libghc-dataenc-dev libghc-hslogger-dev libghc-utf8-string-dev libghc-sha-dev libghc-entropy-dev liblua5.1-0-dev imagemagick fpc fp-compiler fp-units-misc libpng-dev fp-units-gfx libavcodec-dev libavformat-dev libglew1.6-dev -script: - - mkdir build && cd build && cmake $BUILD_ARGS .. && make VERBOSE=1 && make test_verbose +before_install: | + if [ "$TRAVIS_OS_NAME" == "linux" ]; then + sudo add-apt-repository -y ppa:zoogie/sdl2-snapshots + sudo apt-get update -qq + elif [ "$TRAVIS_OS_NAME" == "osx" ]; then + brew update --all + fi +install: | + if [ "$TRAVIS_OS_NAME" == "linux" ]; then + sudo apt-get install debhelper cmake dpkg-dev libqt4-dev qt4-qmake libphysfs-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev libsdl2-net-dev bzip2 ghc libghc-mtl-dev libghc-parsec3-dev libghc-bytestring-show-dev libghc-vector-dev libghc-zlib-dev libghc-random-dev libghc-stm-dev libghc-network-dev libghc-dataenc-dev libghc-hslogger-dev libghc-utf8-string-dev libghc-sha-dev libghc-entropy-dev liblua5.1-0-dev imagemagick fpc fp-compiler fp-units-misc libpng-dev fp-units-gfx libavcodec-dev libavformat-dev libglew1.6-dev + elif [ "$TRAVIS_OS_NAME" == "osx" ]; then + brew install fpc glew qt physfs lua51 sdl2 sdl2_image sdl2_net sdl2_ttf ffmpeg ghc cabal-install + brew install sdl2_mixer --with-vorbis + # use cabal install haskell deps, pas2c ones are covered by server + if [[ "$BUILD_ARGS" != *"NOSERVER"* ]]; then + cabal update + cabal install --only-dependencies gameServer/hedgewars-server.cabal + fi + if [[ "$BUILD_ARGS" == *"BUILD_ENGINE_C"* ]]; then + cabal update + cabal install --only-dependencies tools/pas2c/pas2c.cabal + fi + # avoid installing Sparkle, add default unit path + export BUILD_ARGS="$BUILD_ARGS -DNOAUTOUPDATE=1 -DCMAKE_Pascal_FLAGS=-Fu/usr/local/lib/fpc/$(fpc -iW)/units/x86_64-darwin/*/" + fi +before_script: + - mkdir build && cd build && cmake $BUILD_ARGS .. +script: + - make VERBOSE=1 +after_success: | + if [ "$TRAVIS_OS_NAME" == "linux" ]; then + make test_verbose + elif [ "$TRAVIS_OS_NAME" == "osx" ]; then + make install + fi notifications: email: false irc: @@ -30,3 +59,4 @@ - "See details at %{build_url}" on_success: change on_failure: always + skip_join: true diff -r 2572afe532af -r 42a9dd7b724c ChangeLog.txt --- a/ChangeLog.txt Sun Dec 06 20:35:58 2015 +0300 +++ b/ChangeLog.txt Sun Dec 06 20:36:21 2015 +0300 @@ -30,8 +30,12 @@ Lua-API: + New map parameter: MapFeatureSize -- numeric representation of detail slider below map preview; use within onGameInit()/onPreviewInit() - + New function: SetMaxBuildDistance([ distInPx ]) -- specify how many pixels away a hedgehog can still place girders/etc. set to 0 for no limit; call with no param to reset to default + + New functions: SetMaxBuildDistance([ distInPx ]) -- specify how many pixels away a hedgehog can still place girders/etc. set to 0 for no limit; call with no param to reset to default, + New hook: onSuddenDeath() -- called by engine when sudden death begins + + Parameters are now optional for the generic gear setters. i.e. - SetVisualGearValues(gear, x, y). nil values are skipped and not set. + + PlaceSprite can now set land type (bouncy, indestructible, ice etc), colour the sprite, flip the sprite, and place the sprite behind existing land. + + EraseSprite. Can flip and selectively erase based on land flags. + + More of the gear structure values are now accessible in the generic gear getter/setter. * Previously missing gear states are now available (gstSubmersible, gstFrozen and gstNoGravity) * Fixed OnHogAttack giving the incorrect AmmoType (amNothing) under certain conditions diff -r 2572afe532af -r 42a9dd7b724c gameServer/HWProtoInRoomState.hs --- a/gameServer/HWProtoInRoomState.hs Sun Dec 06 20:35:58 2015 +0300 +++ b/gameServer/HWProtoInRoomState.hs Sun Dec 06 20:36:21 2015 +0300 @@ -175,11 +175,11 @@ ModifyClient (\c -> c{ teamsInGame = teamsInGame c - 1, - clientClan = if teamsInGame c == 1 then Nothing else Just $ anotherTeamClan clNick team r + clientClan = if teamsInGame c == 1 then Nothing else anotherTeamClan clNick team r }) ] where - anotherTeamClan clNick team = teamcolor . fromMaybe (error "CHECKPOINT 011") . find (\t -> (teamowner t == clNick) && (t /= team)) . teams + anotherTeamClan clNick team = liftM teamcolor . find (\t -> (teamowner t == clNick) && (t /= team)) . teams findTeam = find (\t -> tName == teamname t) . teams diff -r 2572afe532af -r 42a9dd7b724c hedgewars/uStore.pas --- a/hedgewars/uStore.pas Sun Dec 06 20:35:58 2015 +0300 +++ b/hedgewars/uStore.pas Sun Dec 06 20:36:21 2015 +0300 @@ -745,7 +745,7 @@ if SDLGLcontext = nil then SDLGLcontext:= SDL_GL_CreateContext(SDLwindow); SDLTry(SDLGLcontext <> nil, 'SDLGLcontext', true); - SDLTry(SDL_GL_SetSwapInterval(1) = 0, 'SDL_GL_SetSwapInterval', true); + SDL_GL_SetSwapInterval(1); RendererSetup(); diff -r 2572afe532af -r 42a9dd7b724c project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons/forwardjump.png Binary file project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons/forwardjump.png has changed diff -r 2572afe532af -r 42a9dd7b724c project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons/forwardjump_old.png Binary file project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons/forwardjump_old.png has changed diff -r 2572afe532af -r 42a9dd7b724c project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m --- a/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m Sun Dec 06 20:35:58 2015 +0300 +++ b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m Sun Dec 06 20:36:21 2015 +0300 @@ -267,7 +267,6 @@ -(void) didReceiveMemoryWarning { - self.previewImage = nil; self.missionName = nil; self.listOfMissionIDs = nil; self.dictOfMissions = nil; diff -r 2572afe532af -r 42a9dd7b724c project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m Sun Dec 06 20:35:58 2015 +0300 +++ b/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m Sun Dec 06 20:36:21 2015 +0300 @@ -268,14 +268,14 @@ footer.backgroundColor = [UIColor clearColor]; footer.autoresizingMask = UIViewAutoresizingFlexibleWidth; - UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width*80/100, height)]; + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width*90/100, height)]; label.center = CGPointMake(aTableView.frame.size.width/2, height/2); label.textAlignment = UITextAlignmentCenter; label.font = [UIFont italicSystemFontOfSize:12]; label.textColor = [UIColor whiteColor]; label.numberOfLines = 2; label.backgroundColor = [UIColor clearColor]; - label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth; label.text = NSLocalizedString(@"Setting a Style might force a particular Scheme or Weapon configuration.",@""); diff -r 2572afe532af -r 42a9dd7b724c project_files/HedgewarsMobile/Classes/TeamConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Sun Dec 06 20:35:58 2015 +0300 +++ b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Sun Dec 06 20:36:21 2015 +0300 @@ -194,23 +194,23 @@ } -(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { - return IS_IPAD() ? 40 : 20; + return IS_IPAD() ? 40 : 30; } -(UIView *)tableView:(UITableView *)aTableView viewForFooterInSection:(NSInteger) section { - NSInteger height = IS_IPAD() ? 40 : 20; + NSInteger height = IS_IPAD() ? 40 : 30; UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width, height)]; footer.backgroundColor = [UIColor clearColor]; footer.autoresizingMask = UIViewAutoresizingFlexibleWidth; - UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width*80/100, height)]; + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width*90/100, height)]; label.center = CGPointMake(aTableView.frame.size.width/2, height/2); label.textAlignment = UITextAlignmentCenter; label.font = [UIFont italicSystemFontOfSize:12]; label.textColor = [UIColor whiteColor]; label.numberOfLines = 2; label.backgroundColor = [UIColor clearColor]; - label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth; if (section == 0) label.text = NSLocalizedString(@"Tap to add hogs or change color, touch and hold to remove a team.",@""); diff -r 2572afe532af -r 42a9dd7b724c share/hedgewars/Data/Graphics/Missions/Training/Basic_Training_-_Flying_Saucer@2x.png Binary file share/hedgewars/Data/Graphics/Missions/Training/Basic_Training_-_Flying_Saucer@2x.png has changed diff -r 2572afe532af -r 42a9dd7b724c share/hedgewars/Data/Locale/hedgewars_zh_TW.ts --- a/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts Sun Dec 06 20:35:58 2015 +0300 +++ b/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts Sun Dec 06 20:36:21 2015 +0300 @@ -5,14 +5,14 @@ About Unknown Compiler - + 未知的編譯器 AbstractPage Go back - + 退回 @@ -23,96 +23,96 @@ copy of %1 - + %1的拷貝 BanDialog IP - IP + IP Nick - + 暱稱 IP/Nick - + IP/暱稱 Reason - + 原因 Duration - + 持續時間 Ok - + 確定 Cancel - 取消 + 取消 you know why - + 你知道為什麼 Warning - + 警告 Please, specify %1 - + 請指定%1 nickname - + 暱稱 permanent - + 永久 DataManager Use Default - + 使用預設值 FeedbackDialog View - + 查看 Cancel - 取消 + 取消 Send Feedback - + 發送反饋 We are always happy about suggestions, ideas, or bug reports. - + 我們很樂意收到建議,想法,或是bug回報。 Send us feedback! - + 給我們反饋! If you found a bug, you can see if it's already been reported here: - + 如果你發現了一個bug,可以先檢查它是否已經被回報過: Your email address is optional, but necessary if you want us to get back at you. - + 如果希望我們回覆你, 請留下你的電子郵件地址。 @@ -132,244 +132,246 @@ GameCFGWidget Edit weapons - 改變武器設置 + 修改武器 Edit schemes - 修改遊戲設置 + 修改方案 Game scheme will auto-select a weapon - + 遊戲方案將自動選擇武器 Map - 地圖 + 地圖 Game options - + 遊戲選項 GameUIConfig Guest - + 遊客 HWApplication %1 minutes - - + + %1 分鐘 %1 hour - - + + %1 小時 %1 hours - - + + %1 小時 %1 day - - + + %1 天 %1 days - - + + %1 天 Scheme '%1' not supported - + 不支持遊戲方案“%1” Cannot create directory %1 - 無法創建路徑 %1 + 不能建立目錄 %1 Failed to open data directory: %1 Please check your installation! - + 無法打開數據目錄:%1 +請檢查你的安裝! Usage command-line - + 用法 OPTION command-line - + 選項 CONNECTSTRING command-line - + 連接字串 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 - + 啟動刺蝟大作戰能使用%1(例如 "%2")來連線 Malformed option argument: %1 command-line - + 格式不正確的選項參數:%1 Unknown option argument: %1 command-line - + 未知的選項參數:%1 HWAskQuitDialog Do you really want to quit? - + 你真的要退出嗎? HWChatWidget %1 has been removed from your ignore list - + %1已從你的忽略列表中刪除 %1 has been added to your ignore list - + %1已添加到你的忽略列表 %1 has been removed from your friends list - + %1已從你的好友列表中刪除 %1 has been added to your friends list - + %1已添加到你的好友列表 Stylesheet imported from %1 - + 樣式表已從%1導入 Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset! - + 如果你未來想使用當前的樣式表,請輸入%1 ;重置,請輸入%2! Couldn't read %1 - + 無法讀取 %1 StyleSheet discarded - + 樣式表被丟棄 StyleSheet saved to %1 - + 樣式表保存到%1 Failed to save StyleSheet to %1 - + 無法保存樣式表%1 %1 has joined - + %1已經加入 %1 has left - + %1已經離開 %1 has left (%2) - + %1已經離開(%2) HWForm Cannot save record to file %1 - 無法錄入檔 %1 + 無法保存記錄到文件%1 DefaultTeam - + 預設隊伍 Hedgewars Demo File File Types - + 刺蝟大作戰演示檔 Hedgewars Save File File Types - + 刺蝟大作戰存檔 Demo name - + 演示名稱 Demo name: - + 演示名稱: Game aborted - + 比賽中止 Nickname - 匿稱 + 匿稱 No nickname supplied. - + 沒有暱稱供應。 Someone already uses your nickname %1 on the server. Please pick another nickname: - + 在伺服器上已經有人使用你的暱稱(%1) +請選擇另一個暱稱: %1's Team - + %1的隊伍 Hedgewars - Nick registered - + 刺蝟大作戰 - 暱稱註冊 This nick is registered, and you haven't specified a password. @@ -377,61 +379,67 @@ If this nick isn't yours, please register your own nick at www.hedgewars.org Password: - + 這個暱稱被註冊,並且你還沒有指定密碼 +如果這個暱稱是不是你的,請上www.hedgewars.org註冊自己的暱稱 +密碼: Your nickname is not registered. To prevent someone else from using it, please register it at www.hedgewars.org - + 你的暱稱未註冊。 +要防止其他人使用它, +請上www.hedgewars.org進行註冊 Your password wasn't saved either. - + 未保存任何你的密碼。 Hedgewars - Empty nickname - + 刺蝟大作戰 - 空的暱稱 Hedgewars - Wrong password - + 刺蝟大作戰 - 密碼錯誤 You entered a wrong password. - + 你輸入了錯誤的密碼。 Try Again - + 再試一次 Hedgewars - Connection error - + 刺蝟大作戰 - 連接錯誤 You reconnected too fast. Please wait a few seconds and try again. - + 你太快重新連接了。 +請等待幾秒鐘,然後再試一次。 This page requires an internet connection. - + 此頁面需要連接網際網路。 Guest - + 遊客 Room password - + 房間密碼 The room is protected with password. Please, enter the password: - + 房間使用密碼保護 +請輸入密碼: @@ -442,7 +450,7 @@ Cannot open demofile %1 - DEMO %1 打不開 + 無法打開 演示檔案 %1 A Fatal ERROR occured! - The game engine had to stop. @@ -453,7 +461,11 @@ Last two engine messages: %2 - + 一個致命的錯誤! - 遊戲引擎不得不停止 +我們很抱歉給你帶來不便:( +如果這一情況持續發生,請點擊主菜單中的“%1”按鈕 +上次兩款發動機的消息: +%2 @@ -484,103 +496,103 @@ Small tunnels - + 小隧道 Medium tunnels - + 中隧道 Seed - + 種子 Map type: - + 地圖類型: Image map - + 圖片地圖 Mission map - + 任務地圖 Hand-drawn - + 手繪 Randomly generated - + 隨機產生 Random maze - + 隨機迷宮 Random - 隨機 + 隨機 Map preview: - + 地圖預覽: Load map drawing - + 加載地圖繪製 Edit map drawing - + 編輯地圖繪製 Small islands - + 小島嶼 Medium islands - + 中島嶼 Large islands - + 大島嶼 Map size: - + 地圖尺寸: Maze style: - + 迷宮的風格: Mission: - + 任務: Map: - + 地圖: Load drawn map - + 加載繪製的地圖 Drawn Maps - + 繪製地圖 All files - + 所有文件 Large tunnels - + 大隧道 Theme: %1 - + 主題:%1 Random perlin @@ -588,7 +600,7 @@ Style: - + 風格: @@ -603,14 +615,14 @@ Port - + 端口 HWNewNet The host was not found. Please check the host name and port settings. - 錯誤沒找到這個主機。請檢查主機名稱和埠設置。 + 錯誤沒找到這個主機。請檢查主機名稱和端口設置。 Connection refused @@ -646,74 +658,77 @@ User quit - + 用戶退出 Remote host has closed connection - + 遠程主機已關閉連接 The server is too old. Disconnecting now. - + 伺服器太舊。立即斷線。 Server authentication error - + 伺服器身份驗證錯誤 HWPasswordDialog Login - + 登入 To connect to the server, please log in. If you don't have an account on www.hedgewars.org, just enter your nickname. - + 要連接到伺服器,請登錄。 + +如果你在www.hedgewars.org沒有一個的帳號, +只需輸入你的暱稱。 Nickname: - + 暱稱: Password: - + 密碼: HWUploadVideoDialog Upload video - + 上傳視頻 Upload - + 上傳 HatButton Change hat (%1) - + 改變帽子(%1) HatPrompt Cancel - 取消 + 取消 Use selected hat - + 使用選定的帽子 Search for a hat: - + 搜索一頂帽子: @@ -727,7 +742,7 @@ KeyBinder Category - + 分類 @@ -738,26 +753,26 @@ unknown - + 未知 Duration: %1m %2s - + 持續時間:%1分 %2秒 Video: %1x%2 - + 視頻:%1X%2 %1 fps - + %1 FPS MapModel No description available. - + 沒有可用的描述。 @@ -768,27 +783,27 @@ Fetch data - + 獲取數據 Server message for latest version: - + 對於最新版本的伺服器消息: Server message for previous versions: - + 以前版本的伺服器消息: Latest version protocol number: - + 最新版本協議號: MOTD preview: - + 今日消息預覽: Set data - + 設置數據 General @@ -796,31 +811,31 @@ Bans - + 封鎖 IP/Nick - + IP/暱稱 Expiration - + 期滿 Reason - + 原因 Refresh - + 刷新 Add - + 增加 Remove - + 刪除 @@ -834,145 +849,145 @@ PageDataDownload Loading, please wait. - + 載入中,請稍候。 This page requires an internet connection. - + 此頁面需要連接網際網路。 Open packages directory - + 打開組件目錄 PageDrawMap Undo - + 復原 Clear - 清除 + 清除 Load - 讀取 + 讀取 Save - + 保存 Load drawn map - + 讀取繪製的地圖 Save drawn map - + 保存繪製的地圖 Drawn Maps - + 繪製地圖 All files - + 所有文件 Eraser - + 黑板擦 Polyline - + 折線 Rectangle - + 矩形 Ellipse - + 橢圓 Optimize - + 優化 PageEditTeam General - 常規 + 常規 Select an action to choose a custom key bind for this team - + 點動作,來替隊伍選擇自定義的按鍵綁定 Use my default - + 使用我的預設值 Reset all binds - + 重置全部綁定 Custom Controls - + 自定義控制 Hat - 帽子 + 帽子 Name - + 名字 This hedgehog's name - + 這隻刺猬的名字 Randomize this hedgehog's name - + 隨機選擇這隻刺猬的名字 Random Team - 隨機隊伍分配 + 隨機隊伍分配 PageGameStats Details - + 細節 Health graph - + 生命圖 Ranking - + 排行 The best shot award was won by <b>%1</b> with <b>%2</b> pts. - + <b>%1%n</b>的<b>%2</b>傷害獲得最佳攻擊獎。 The best killer is <b>%1</b> with <b>%2</b> kills in a turn. - + 最佳殺手為<b>%1</b>在一回合<b>%2</b>殺。 A total of <b>%1</b> hedgehog(s) were killed during this round. - + 這場總共<b>%1</b>隻刺蝟死亡。 @@ -984,28 +999,28 @@ <b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts. - + <b>%1</b>認為攻擊自己的刺猬<b>%2</b>傷害是很好的。 <b>%1</b> killed <b>%2</b> of his own hedgehogs. - + <b>%1</b>殺了<b>%2</b>隻自己的刺蝟。 <b>%1</b> was scared and skipped turn <b>%2</b> times. - + <b>%1</b>很慌張,跳過<b>%2</b>次。 Play again - + 再玩一次 Save - + 存檔 (%1 %2) @@ -1018,73 +1033,73 @@ PageInGame In game... - + 在遊戲中... PageInfo Open the snapshot folder - + 打開快照文件夾 PageMain Downloadable Content - + 可下載的內容 Play a game on a single computer - + 開始一個單機版遊戲 Play a game across a network - + 開始一個網路對戰遊戲 Read about who is behind the Hedgewars Project - + 看看刺蝟大作戰背後的功臣們 Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars - + 在這裡可以回報問題,提出建議,或是說說你多麼喜歡刺蝟大作戰 Access the user created content downloadable from our website - + 從我們的網站訪問用戶創建的內容 Exit game - + 退出遊戲 Manage videos recorded from game - + 管理從遊戲中錄製的視頻 Edit game preferences - + 編輯遊戲偏好設定 Play a game across a local area network - + 跨內網玩遊戲 Play a game on an official server - + 在官方伺服器上玩遊戲 Feedback - + 信息反饋 Play local network game - + 玩內網遊戲 Play official network game - + 玩官網遊戲 @@ -1095,7 +1110,7 @@ Edit game preferences - + 編輯遊戲偏好設定 @@ -1106,37 +1121,37 @@ Edit game preferences - + 編輯遊戲偏好設定 Start - 開始 + 開始 Update - 更新 + 更新 Room controls - + 房間管理 PageNetServer Click here for details - + 點擊查看詳情 Insert your address here - + 在此處插入你的地址 PageOptions New team - 新隊伍 + 新增隊伍 Edit team @@ -1144,163 +1159,163 @@ Delete team - + 刪除隊伍 You can't edit teams from team selection. Go back to main menu to add, edit or delete teams. - + 你不能在隊伍選單中修改隊伍。回到主選單上,新增,編輯或刪除隊伍. New scheme - + 新增方案 Edit scheme - + 修改方案 Delete scheme - + 刪除方案 New weapon set - + 新增武器組合 Edit weapon set - + 修改武器組合 Delete weapon set - + 刪除武器組合 Advanced - 進階 + 進階 Reset to default colors - + 重置為預設顏色 Proxy host - + 代理伺服器主機 Proxy port - + 代理伺服器端口 Proxy login - + 代理伺服器帳號 Proxy password - + 代理伺服器密碼 No proxy - + 無代理 Socks5 proxy - + Socks5代理 HTTP proxy - + HTTP代理 System proxy settings - + 系統代理設置 Select an action to change what key controls it - + 點動作,來改變控制它的按鍵 Reset to default - + 重置為預設值 Reset all binds - + 重置所有的綁定 Game - + 遊戲 Graphics - + 圖像 Audio - + 聲音 Controls - + 控制 Video Recording - + 錄像 Network - + 網路 Teams - 隊伍 + 隊伍 Schemes - + 方案 Weapons - 武器 + 武器 Frontend - + 前端 Custom colors - + 自定義顏色 Game audio - + 遊戲音效 Frontend audio - + 前端音效 Account - + 帳戶 Proxy settings - + 代理伺服器設置 Miscellaneous - + 雜項 Updates - + 更新 Check for updates - + 檢查更新 Video recording options - + 視頻錄製選項 @@ -1339,35 +1354,35 @@ %1 players online - + %1%n 玩家在線 Search for a room: - + 搜索房間: Create room - + 創建房間 Join room - + 加入房間 Room state - + 房間狀態 Open server administration page - + 打開伺服器管理頁面 PageScheme New - 新模式 + 新增 Delete @@ -1375,7 +1390,7 @@ Gain 80% of the damage you do back in health - 傷害的80%變成自身力量 + 傷害的80%成為自身生命 Share your opponents pain, share their damage @@ -1395,7 +1410,7 @@ Defend your fort and destroy the opponents, two team colours max! - 保衛你的城堡,破壞對手的,努力吧! + 保衛你的堡壘,破壞對手的,努力吧! Teams will start on opposite sides of the terrain, two team colours max! @@ -1427,86 +1442,86 @@ Take turns placing your hedgehogs before the start of play. - 在開局前手動放置刺猬 + 在開局前手動放置刺猬。 Ammo is shared between all teams that share a colour. - + 同一個顏色的所有隊伍之間共享彈藥。 Disable girders when generating random maps. - + 生成隨機地圖時,禁用橋樑。 Disable land objects when generating random maps. - + 生成隨機地圖時,禁用地面物體。 AI respawns on death. - + AI死亡後重生。 All (living) hedgehogs are fully restored at the end of turn - + 所有(活的)刺猬在回合結束時完全恢復 Attacking does not end your turn. - + 進攻後不會自動結束你的回合。 Weapons are reset to starting values each turn. - + 每回合武器被重置為初始值。 Each hedgehog has its own ammo. It does not share with the team. - + 每個刺猬有它自己的彈藥。它不與隊伍分享。 You will not have to worry about wind anymore. - + 禁風,你將不用擔心風了。 Wind will affect almost everything. - + 風將影響幾乎所有東西。 Copy - + 複製 Teams in each clan take successive turns sharing their turn time. - + 同一顏色的每個隊伍採取連續輪流分享他們的回合時間。 Add an indestructible border around the terrain - 添加不可毀壞地邊界 + 在地型周圍添加一個堅不可摧的邊界 Add an indestructible border along the bottom - + 沿著底部添加一個堅不可摧的邊界 None (Default) - + 沒有(預設值) Wrap (World wraps) - + 重疊(世界重疊) Bounce (Edges reflect) - + 彈跳(邊緣反射) Sea (Edges connect to sea) - + 海水(邊緣連接到海) PageSelectWeapon Default - 默認 + 預設值 Delete @@ -1514,68 +1529,68 @@ New - 新模式 + 新增 Copy - + 複製 PageSinglePlayer Play a quick game against the computer with random settings - + 使用隨機設置與電腦快速開始遊戲 Play a hotseat game against your friends, or AI teams - + 與你的朋友或AI隊伍進行遊戲 Campaign Mode - + 戰役模式 Practice your skills in a range of training missions - + 透過一系列的培訓任務,練習你的技能 Watch recorded demos - + 觀看錄製的演示 Load a previously saved game - + 讀取以前保存的遊戲 PageTraining No description available - + 沒有可用的描述 Select a mission! - + 選擇一個任務! Pick the mission or training to play - + 選擇要玩的任務或培訓 Start fighting - + 開始戰鬥 PageVideos Name - + 名稱 Size - + 大小 %1 bytes @@ -1585,23 +1600,23 @@ (in progress...) - + (處理中...) encoding - + 編碼 uploading - + 上傳 Date: %1 - + 日期:%1 Size: %1 - + 大小:%1 @@ -1620,7 +1635,7 @@ Restrict Team Additions - 限制團隊外掛程式 + 限制隊伍外掛程式 Ban @@ -1632,19 +1647,19 @@ Ignore - + 忽略 Add friend - + 加為好友 Unignore - + 不忽略 Remove friend - + 刪除好友 Update @@ -1652,22 +1667,22 @@ Restrict Unregistered Players Join - + 限制未註冊的玩家加入 Show games in lobby - + 顯示遊戲大廳 Show games in-progress - + 顯示正在進行的遊戲 QCheckBox Fullscreen - 遊戲全螢幕 + 全螢幕 Show FPS @@ -1679,11 +1694,11 @@ Append date and time to record file name - 記錄名稱中包含具體時間日期 + 記錄檔名中包含具體時間日期 Check for updates at startup - 啟動時檢查程式升級 + 啟動時檢查更新 Show ammo menu tooltips @@ -1691,83 +1706,83 @@ Save password - + 保存密碼 Save account name and password - + 保存帳戶名和密碼 Video is private - + 視頻是私人 Record audio - + 錄製音頻 Use game resolution - + 套用遊戲解析度 Visual effects - + 視覺效果 Sound - + 音效 In-game sound effects - + 在遊戲中的聲音效果 Music - + 音樂 In-game music - + 在遊戲中的音樂 Frontend sound effects - + 前端音效 Frontend music - + 前端的音樂 Team - + 隊伍 Enable team tags by default - + 預設顯示隊伍名標示 Hog - + 刺蝟 Enable hedgehog tags by default - + 預設顯示刺猬名標示 Health - + 生命 Enable health tags by default - + 預設顯示生命值標示 Translucent - + 半透明 Enable translucent tags by default - + 預設啟用半透明顯示 @@ -1778,11 +1793,11 @@ Level - Lv 級別 + AI等級 (System default) - + (系統預設值) Community @@ -1790,31 +1805,31 @@ Disabled - + 關閉 Red/Cyan - + 紅色/青色 Cyan/Red - + 青色/紅 Red/Blue - + 紅/藍 Blue/Red - + 藍/紅 Red/Green - + 紅/綠 Green/Red - + 綠/紅 Side-by-side @@ -1826,42 +1841,42 @@ Red/Cyan grayscale - + 紅/青色灰度 Cyan/Red grayscale - + 青色/紅灰度 Red/Blue grayscale - + 紅/藍灰度 Blue/Red grayscale - + 藍/紅灰度 Red/Green grayscale - + 紅/綠灰度 Green/Red grayscale - + 綠/紅灰度 QGroupBox Team Members - 成員 + 隊伍成員 Fort - 城堡模式 + 堡壘 Playing teams - 玩家隊伍 + 玩家隊伍 Net game @@ -1877,15 +1892,15 @@ Team Settings - + 隊伍設置 Videos - + 視頻 Description - + 描述 @@ -1900,11 +1915,11 @@ Server name: - 伺服器名: + 伺服器名稱: Server port: - 伺服器埠: + 伺服器端口: Host: @@ -1912,7 +1927,7 @@ Port: - 埠: + 端口: Weapons @@ -1928,7 +1943,7 @@ Damage Modifier - 傷害修改 + 傷害修正 Turn Time @@ -1940,11 +1955,11 @@ Sudden Death Timeout - 死亡模式倒計時 + 意外死亡倒數 Scheme Name: - 設置名稱: + 方案名稱: Crate Drops @@ -1952,7 +1967,7 @@ Mines Time - 佈雷時間 + 地雷爆炸緩衝 Mines @@ -1960,193 +1975,195 @@ % Dud Mines - + 地雷啞彈率(%) Name - + 名稱 Type - + 類型 Grave - + 墳墓 Flag - + 旗幟 Voice - + 語音 Locale - + 語言環境 Explosives - + 炸藥桶 Quality - + 品質 % Health Crates - + 急救箱率(%) Health in Crates - + 急救箱生命 Sudden Death Water Rise - + 意外死亡水上升 Sudden Death Health Decrease - + 意外死亡生命減少 % Rope Length - + 繩長(%) Stereo rendering - + 立體渲染 Style - + 風格 Scheme - + 方案 % Get Away Time - + 爆炸逃離緩衝(%) There are videos that are currently being processed. Exiting now will abort them. Do you really want to quit? - + 有視頻正在處理中 +現在離開將中止它 +你確定要離開嗎? Please provide either the YouTube account name or the email address associated with the Google Account. - + 請提供YouTube帳戶名稱或與Google帳戶關聯的電子郵件地址。 Account name (or email): - + 賬戶名(或電子郵件): Password: - + 密碼: Video title: - + 視頻標題: Video description: - + 視頻說明: Tags (comma separated): - + 標籤(以逗號分隔): Description - + 描寫 Nickname - 匿稱 + 暱稱 Format - + 格式 Audio codec - + 音頻編解碼器 Video codec - + 視頻編解碼器 Framerate - + 畫面刷新率 Bitrate (Kbps) - + 位元速率 (Kbps) This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete! - + 這個開發版本是“尚未完成的”,可能不與其他的版本兼容,同時一些功能可能被破壞或殘缺! Fullscreen - 遊戲全螢幕 + 全螢幕 Fullscreen Resolution - + 全螢幕解析度 Windowed Resolution - + 視窗解析度 Your Email - + 你的電子郵件 Summary - + 摘要 Send system information - + 發送系統信息 Type the security code: - + 鍵入安全碼: Revision - + 版本 This program is distributed under the %1 - + 此程序使用%1釋出 This setting will be effective at next restart. - + 該設置將在下次重啟時生效。 Tip: %1 - + 提示:%1 Displayed tags above hogs and translucent tags - + 刺蝟頭上顯示的標籤和半透明的標籤 World Edge - + 世界邊緣 Script parameter - + 腳本參數 @@ -2157,11 +2174,11 @@ hedgehog %1 - + 刺蝟 %1 anonymous - + 匿名 @@ -2183,53 +2200,53 @@ File association failed. - + 檔案關聯失敗。 Error while authenticating at google.com: - + 在google.com認證時錯誤: Login or password is incorrect - + 登錄或密碼不正確 Error while sending metadata to youtube.com: - + 傳送中繼資料給youtube.com時錯誤: Teams - Are you sure? - + 隊伍 - 你確定嗎? Do you really want to delete the team '%1'? - + 你確定要刪除隊伍'%1'? Cannot delete default scheme '%1'! - + 不能刪除預設方案 "%1"! Please select a record from the list - + 請從列表中選擇一個紀錄 Unable to start server - + 無法開啟伺服器 Hedgewars - Error - + 刺蝟大作戰 - 錯誤 Hedgewars - Success - + 刺蝟大作戰 - 成功 All file associations have been set - + 所有檔案關聯已經被設定 Cannot create directory %1 @@ -2237,19 +2254,19 @@ Unable to start the server: %1. - 無法開始服務端: %1. + 無法開啟伺服器: %1. Video upload - Error - + 視頻上錯 - 錯誤 Netgame - Error - + 網路遊戲 - 錯誤 Please select a server from the list - + 請從列表中選擇一個伺服器 Please enter room name @@ -2257,23 +2274,23 @@ Record Play - Error - + 記錄播放 - 錯誤 Please select record from the list - 請從清單選擇記錄 + 請從列表選擇記錄 Cannot rename to - + 不能改名 Cannot delete file - + 不能刪除檔案 Room Name - Error - + 房間名 - 錯誤 Please select room from the list @@ -2281,129 +2298,131 @@ Room Name - Are you sure? - + 房間名 - 你確定嗎? The game you are trying to join has started. Do you still want to join the room? - + 你試著加入的遊戲已經開始了。 +你仍要加入這個房間嗎? Schemes - Warning - + 方案 - 警告 Schemes - Are you sure? - + 方案 - 你確定嗎? Do you really want to delete the game scheme '%1'? - + 你真的確定要刪除遊戲方案 '%1'? Videos - Are you sure? - + 視頻 - 你確定嗎? Do you really want to delete the video '%1'? - + 你確定要刪除視頻 '%1'嗎? Do you really want to remove %1 file(s)? - + 你確定要移除檔案%1%n嗎? Do you really want to cancel uploading %1? - + 你確定要取消上傳%1嗎? File error - + 檔案 - 錯誤 Cannot open '%1' for writing - + 不能開啟'%1' Cannot open '%1' for reading - + 不能開啟'%1' Cannot use the ammo '%1'! - + 不能使用武器 '%1'! Weapons - Warning - + 武器 - 警告 Cannot overwrite default weapon set '%1'! - + 不能複寫預設武器設定'%1'! Cannot delete default weapon set '%1'! - + 不能刪除預設武器設定'%1'! Weapons - Are you sure? - + 武器 - 你確定嗎? Do you really want to delete the weapon set '%1'? - + 你確定要刪除武器設定'%1'嗎? Hedgewars - Nick not registered - + 刺蝟大作戰 - 暱稱已經被註冊 System Information Preview - + 系統資訊預覽 Failed to generate captcha - + 產生驗證碼失敗 Failed to download captcha - + 下載驗證碼失敗 Please fill out all fields. Email is optional. - + 請填寫所有欄位. 電子郵件地址是選填的. Hedgewars - Warning - + 刺蝟大作戰 - 警告 Hedgewars - Information - + 刺蝟大作戰 - 資訊 Not all players are ready - + 並不是所有的玩家都準備就緒 Are you sure you want to start this game? Not all players are ready. - + 你確定要啟動這個遊戲嗎? +並不是所有的玩家都準備就緒。 QObject No description available - + 沒有可用的描述 QPushButton Play demo - 播放 demo + 播放演示 Connect @@ -2419,7 +2438,7 @@ Start server - 開始服務端 + 啟動伺服器 Update @@ -2435,11 +2454,11 @@ default - 默認 + 預設值 Rename - 重命名 + 更名 OK @@ -2455,97 +2474,97 @@ Associate file extensions - + 關聯副檔名 More info - + 更多信息 Set default options - + 回到預設值 Open videos directory - + 打開視頻目錄 Play - + 播放 Upload to YouTube - + 上傳到YouTube Cancel uploading - + 取消上傳 Restore default coding parameters - + 恢復預設的編碼參數 Open the video directory in your system - + 打開你系統上的視頻目錄 Play this video - + 播放此視頻 Delete this video - + 刪除此視頻 Upload this video to your Youtube account - + 上傳視頻到你的YouTube帳戶 Reset - + 重置 Set the default server port for Hedgewars - + 設置為刺猬大作戰預設的伺服器端口 Invite your friends to your server in just 1 click! - + 只要1個點擊就可以邀請你的朋友到你的伺服器! Click to copy your unique server URL to your clipboard. Send this link to your friends and they will be able to join you. - + 點擊複製你獨特的伺服器URL到剪貼簿。將此鏈接發送給你的朋友,他們就可以加入你。 Start private server - + 啟動私人伺服器 RoomNamePrompt Enter a name for your room. - + 為你的房間輸入一個名稱。 Cancel - 取消 + 取消 Create room - + 創建房間 set password - + 設定密碼 RoomsListModel In progress - + 進行中 Room Name @@ -2581,15 +2600,15 @@ Random Maze - + 隨機迷宮 Hand-drawn - + 手繪 Script - + 腳本 Random Perlin @@ -2600,38 +2619,38 @@ SeedPrompt The map seed is the basis for all random values generated by the game. - + 地圖種子是基礎由遊戲生成的所有隨機值。 Cancel - 取消 + 取消 Set seed - + 給定種子 Close - + 關閉 SelWeaponWidget Weapon set - 武器設置 + 武器組合 Probabilities - 幾率 + 機率 Ammo in boxes - + 箱中彈藥 Delays - + 延遲 new @@ -2639,19 +2658,20 @@ copy of %1 - + %1的拷貝 TCPBase Unable to start server at %1. - + 無法在%1,啟動伺服器。 Unable to run engine at %1 Error code: %2 - + 無法在%1,運行引擎 +錯誤代碼:%2 The game engine died unexpectedly! @@ -2660,29 +2680,34 @@ We are very sorry for the inconvenience :( If this keeps happening, please click the '%2' button in the main menu! - + 遊戲引擎意外死亡 +(退出代碼為%1) + +我們很抱歉給你帶來不便! :( + +如果這一情況持續發生,請點擊主菜單中的“%2”按鈕! TeamSelWidget At least two teams are required to play! - + 至少要有兩隻隊伍才能玩! ThemePrompt Cancel - 取消 + 取消 Search for a theme: - + 搜索主題: Use selected theme - + 使用選定的主題 @@ -2717,35 +2742,35 @@ slot 1 - slot 1 + 第1類 slot 2 - slot 2 + 第2類 slot 3 - slot 3 + 第3類 slot 4 - slot 4 + 第4類 slot 5 - slot 5 + 第5類 slot 6 - slot 6 + 第6類 slot 7 - slot 7 + 第7類 slot 8 - slot 8 + 第8類 timer 1 sec @@ -2769,7 +2794,7 @@ capture - 奪取 + 抓取 quit @@ -2801,11 +2826,11 @@ slot 9 - slot 9 + 第9類 precise aim - 練習瞄準 + 精細瞄準 chat @@ -2821,180 +2846,180 @@ zoom in - 放大 + 放大 zoom out - 縮小 + 縮小 reset zoom - 重置 + 重置 long jump - 跳遠 + 跳遠 high jump - 跳高 + 跳高 slot 10 - slot 10 + 第10類 mute audio - + 靜音 record - + 錄像切換 hedgehog info - + 刺蝟資訊 autocam / find hedgehog - + 自動鏡頭/搜尋刺蝟 speed up replay - + 加速播放 binds (categories) Movement - + 移動 Weapons - 武器 + 武器 Camera - + 鏡頭 Miscellaneous - + 雜項 binds (descriptions) Traverse gaps and obstacles by jumping: - 越過障礙: + 藉由跳躍通過間隙與障礙: Fire your selected weapon or trigger an utility item: - 開火、使用物品: + 開火或使用物品: Pick a weapon or a target location under the cursor: - 選取武器、目的地: + 選取游標下的武器或是目標位置: Switch your currently active hog (if possible): - 切換刺蝟(如果可用): + 切換現在能動的刺蝟(如果可能): Pick a weapon or utility item: - 選取武器、物品: + 挑武器或物品: Set the timer on bombs and timed weapons: - 設置定時炸彈等武器時間: + 設置定時炸彈和限時武器的時間: Move the camera to the active hog: - 移動鏡頭到選中刺蝟: + 移動鏡頭到能動的刺蝟: Move the cursor or camera without using the mouse: - 不用滑鼠移動遊標或鏡頭: + 不用滑鼠移動游標或鏡頭: Modify the camera's zoom level: - 調整鏡頭放大倍數: + 調整鏡頭放大倍數: Talk to your team or all participants: - 同隊友或全部參與者對話: + 同隊友或全部參與者對話: Pause, continue or leave your game: - 暫停、繼續或離開遊戲: + 暫停、繼續或離開遊戲: Modify the game's volume while playing: - 調整遊戲時音量: + 調整遊戲時音量: Toggle fullscreen mode: - 全屏模式: + 切換全屏模式: Take a screenshot: - 截圖: + 截圖: Toggle labels above hedgehogs: - 切換刺蝟標籤顯示方式: + 切換刺蝟頭上標籤的顯示方式: Record video: - + 錄像: Hedgehog movement - + 刺蝟移動 Toggle automatic camera / refocus on active hedgehog: - + 切換自動鏡頭/重新關注能動的刺蝟: Demo replay: - + 播放演示: binds (keys) Axis - + (Up) - + (上) (Down) - + (下) Hat - 帽子 + 帽子 (Left) - + (左) (Right) - + (右) Button - 按鍵 + 按鈕 Keyboard - 鍵盤 + 鍵盤 Mouse: Left button @@ -3018,27 +3043,27 @@ Backspace - 倒退鍵 + Tab - 製錶鍵 + Clear - 清除 + Return - 返回 + Pause - 暫停鍵 + Pause/Break Escape - 逸出鍵 + Esc Space @@ -3046,7 +3071,7 @@ Delete - 刪除鍵 + Numpad 0 @@ -3110,11 +3135,11 @@ Enter - 回車鍵 + Enter Equals - 等於 + Up @@ -3134,23 +3159,23 @@ Insert - 插入鍵 + Home - Home鍵 + End - End鍵 + Page up - 向上翻頁鍵 + Page down - 向下翻頁鍵 + Num lock @@ -3162,7 +3187,7 @@ Scroll lock - Scroll Lock鍵 + Right shift @@ -3198,266 +3223,266 @@ A button - + A鈕 B button - + B鈕 X button - + X鈕 Y button - + Y鈕 LB button - + LB鈕 RB button - + RB鈕 Back button - + Back鈕 Start button - + Start鈕 Left stick - + 左搖桿 Right stick - + 右搖桿 Left stick (Right) - + 左搖桿(右) Left stick (Left) - + 左搖桿(左) Left stick (Down) - + 左搖桿(下) Left stick (Up) - + 左搖桿(上) Left trigger - + LT鈕 Right trigger - + RT鈕 Right stick (Down) - + 右搖桿(下) Right stick (Up) - + 右搖桿(上) Right stick (Right) - + 右搖桿(右) Right stick (Left) - + 右搖桿(左) DPad - + 十字键 server Restricted - + 限制 Not room master - + 不是房間主人 Corrupted hedgehogs info - + 錯誤的刺蝟資訊 too many teams - + 太多隊伍 too many hedgehogs - + 太多隻刺蝟 There's already a team with same name in the list - + 已經有一個同樣名稱的隊伍在列表中 round in progress - + 遊戲正在進行 restricted - + 限制 REMOVE_TEAM: no such team - + 移除隊伍: 沒有這樣的隊伍 Not team owner! - + 不是隊伍的擁有者! Less than two clans! - + 少於兩個家族! Illegal room name - + 不合法的房間名 Room with such name already exists - + 這樣名稱的房間已經存在 Nickname already chosen - + 暱稱已經選擇 Illegal nickname - + 不合法的暱稱 Protocol already known - + 已知協議 Bad number - + 壞數字 Nickname is already in use - + 暱稱已經被使用 No checker rights - + 沒有檢查權 Authentication failed - + 驗證失敗 60 seconds cooldown after kick - + 被踢出後60秒冷卻時間 kicked - + 被踢出 Ping timeout - + Ping超時 bye - + 再見 No such room - + 沒有這樣的房間 Room version incompatible to your hedgewars version - + 房間版本不兼容你的刺猬大作戰版本 Joining restricted - + 加入限制 Registered users only - + 僅已經註冊的使用者 You are banned in this room - + 你被這個房間封鎖 Empty config entry - + 空的設定項目 You already have voted - + 你已經投過票了 Voting closed - + 投票已經關閉 New voting started - + 新的投票開始 Voting expired - + 投票已經過期 kick - + map - + 地圖 pause - 暫停 + 暫停 Reconnected too fast - + 太快重新連線 Warning! Chat flood protection activated - + 警告! 避免聊天氾濫的防護機制被啟動 Excess flood - + 超額洪水 Game messages flood detected - 1 - + 已經偵測到遊戲訊息氾濫 - 1 Game messages flood detected - 2 - + 已經偵測到遊戲訊息氾濫 - 2 Warning! Joins flood protection activated - + 警告! 避免加入氾濫的防護機制被啟動 There's no voting going on - + 沒有正在進行的投票 diff -r 2572afe532af -r 42a9dd7b724c share/hedgewars/Data/Locale/missions_de.txt --- a/share/hedgewars/Data/Locale/missions_de.txt Sun Dec 06 20:35:58 2015 +0300 +++ b/share/hedgewars/Data/Locale/missions_de.txt Sun Dec 06 20:36:21 2015 +0300 @@ -16,6 +16,9 @@ Basic_Training_-_Rope.name=Grundlagentraining: Seil Basic_Training_-_Rope.desc="Raus da und schwing!" +Basic_Training_-_Flying_Saucer.name=Grundlagentraining: Fliegende Untertasse +Basic_Training_-_Flying_Saucer.desc="Du willst also ausgerechnet Astronaut werden, wie? Dann lern erstmal fliegen!" + User_Mission_-_Dangerous_Ducklings.name=Mission: Gefährliche Entchen User_Mission_-_Dangerous_Ducklings.desc="Nun gut, Rekrut! Es ist Zeit, dass du das im Grundlagentraining Gelernte in die Tag umsetzt!" diff -r 2572afe532af -r 42a9dd7b724c share/hedgewars/Data/Locale/missions_en.txt --- a/share/hedgewars/Data/Locale/missions_en.txt Sun Dec 06 20:35:58 2015 +0300 +++ b/share/hedgewars/Data/Locale/missions_en.txt Sun Dec 06 20:36:21 2015 +0300 @@ -16,6 +16,9 @@ Basic_Training_-_Rope.name=Basic Rope Training Basic_Training_-_Rope.desc="Get out there and swing!" +Basic_Training_-_Flying_Saucer.name=Basic Flying Saucer Training +Basic_Training_-_Flying_Saucer.desc="So you really want to become an astronaut, eh? You should learn how to fly first!" + User_Mission_-_Dangerous_Ducklings.name=Mission: Dangerous Ducklings User_Mission_-_Dangerous_Ducklings.desc="Alright, rookie! Time to put what we learned in Basic Training into practice!" @@ -80,4 +83,4 @@ Challenge_-_Speed_Shoppa_-_Ropes.desc="Take your rope and collect all crates on this medium-sized map." Challenge_-_Speed_Shoppa_-_ShoppaKing.name=Challenge: The Customer is King -Challenge_-_Speed_Shoppa_-_ShoppaKing.desc="Show you're worthy of a true king and collect all crates as fast as possible on this large map." \ No newline at end of file +Challenge_-_Speed_Shoppa_-_ShoppaKing.desc="Show you're worthy of a true king and collect all crates as fast as possible on this large map." diff -r 2572afe532af -r 42a9dd7b724c share/hedgewars/Data/Missions/Training/Basic_Training_-_Flying_Saucer.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Flying_Saucer.lua Sun Dec 06 20:36:21 2015 +0300 @@ -0,0 +1,558 @@ +--[[ + Flying Saucer Training + This is a training mission which teaches many basic (and not-so-basic) moves + with the flying saucer. + + Lesson plan: + - Taking off + - Basic flight + - Landing safely + - Managing fuel + - Changing saucers in mid-flight + - Diving + - Dropping weapons from flying saucer + - Firing from flying saucer with [Precise] + [Attack] + - Aiming in flying saucer with [Precise] + [Up]/[Down] + - Underwater attack + - Free flight with inf. fuel and some weapons at end of training + + FIXME: + - Bad respawn animation ("explosion" just happens randomly because of the way the resurrection effect works) + - Hide fuel if infinite (probably needs engine support) +]] + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Tracker.lua") + +local Player = nil -- Pointer to hog created in: onGameInit +local Target = nil -- Pointer to target hog +local Objective = false -- Get to the target + +local TargetNumber = 0 -- The current target number +local GrenadeThrown = false -- Used for the Boom Target +local BazookasLeft = 0 -- Used by the Launch Target and the Unterwater Attack Target + +local InfFuel = false -- If true, flying saucer has infinite fuel +local SaucerGear = nil -- Store flying saucer gear here (if one exists) +local TargetGears = {} -- List of remaining gears to collect or destroy in the current round +local TargetsRemaining = 0 +local Barrels = {} -- Table contraining the explosive barrel gears + +local CheckTimer = 500 -- Time to wait at least before checking safe landing +local Check = false -- The last target has recently been collected/destroyed and the CheckTimer is running +local GrenadeTimer = 0 -- Time after a grenade has been thrown + +local TargetPos = {} -- Table of targets + +local StartPos = { X = 742, Y = 290 } + +--[[ +List of all targets (or "objectives"). The player has to complete them one-by-one and must always land safely afterwards. +Some target numbers have names for easier reference. +]] +TargetPos[1] = { + Targets = {{ X = 1027, Y = 217 }}, + Ammo = { }, + Message = loc("Here you will learn how to fly the flying saucer|and get so learn some cool tricks.") .. "|" .. + loc("Collect the first crate to begin!"), + MessageIcon = -amJetpack, } +TargetPos[2] = { + Targets = {{ X = 1369, Y = 265 }}, + Ammo = { [amJetpack] = 100 }, + InfFuel = true, + MessageTime = 10000, + Message = loc("Get to the crate using your flying saucer!") .. "|" .. + loc("Press [Attack] (space bar by default) to start,|repeadedly tap the up, left and right movement keys to accelerate.") .. "|" .. + loc("Try to land softly, as you can still take fall damage!"), } +TargetPos[3] = { + Targets = {{ X = 689, Y = 58 }}, + Ammo = { [amJetpack] = 100 }, + MessageTime = 5000, + Message = loc("Now collect the next crate!") .. "|" .. loc("Be careful, your fuel is limited from now on!") .."|" .. + loc("Tip: If you get stuck in this training, use \"Skip turn\" to restart the current objective.") } + +-- The Double Target +local DoubleTarget = 4 +TargetPos[4] = { + Targets = { { X = 84, Y = -20 }, { X = 1980 , Y = -20 } }, + Ammo = { [amJetpack] = 2 }, + MessageTime = 9000, + Message = loc("Now collect the 2 crates to the far left and right.") .. "|" .. + loc("You only have 2 flying saucers this time.") .. "|" .. + loc("Tip: You can change your flying saucer|in mid-flight by hitting the [Attack] key twice."), } +TargetPos[5] = { + Targets = {{ X = 47, Y = 804 }}, + Ammo = { [amJetpack] = 100 }, + MessageTime = 5000, + Message = loc("Time for a more interesting stunt, but first just collect the next crate!"), } +TargetPos[6] = { + Targets = {{ X = 604, Y = 871}}, + MessageTime = 15000, + Message = loc("You can dive with your flying saucer!") .. "|" .. + loc("Try it now and dive here to collect the crate on the right girder.") .. "|" .. + loc("You only have one flying saucer this time.") .. "|" .. + loc("Beware, though, you will only be able to move slowly through the water.") .. "|" .. + loc("Warning: Never ever leave the flying saucer while in water!"), + Ammo = { [amJetpack] = 1 }, } + +TargetPos[7] = { + Targets = {{ X = 1884, Y = 704 }}, + MessageTime = 6500, + Message = loc("Now dive just one more time and collect the next crate." .. "|" .. + loc("Tip: Don't remain for too long in the water, or you won't make it.")), + Ammo = { [amJetpack] = 1}, } + +-- The Boom Target +local BoomTarget = 8 +TargetPos[8] = { + Modifier = true, Func = function() + Info(loc("Instructions"), + loc("Now let's try to drop weapons while flying!") .. "|" .. + loc("You have to destroy the target above by dropping a grenade on it from your flying saucer.") .. "|" .. + loc("It's not that easy, so listen carefully:") .. "|" .. + loc("Step 1: Activate your flying saucer but do NOT move yet!") .. "|" .. + loc("Step 2: Select your grenade.") .. "|" .. + loc("Step 3: Start flying and get yourself right above the target.") .. "|" .. + loc("Step 4: Drop your grenade by pressing the [Long jump] key.") .. "|" .. + loc("Step 5: Get away quickly and land safely anywhere." .. "| |" .. + loc("Note: We only give you grenades if you stay in your flying saucer.")), nil, 20000) + + SpawnBoomTarget() + + if SaucerGear ~= nil then + AddAmmo(Player, amGrenade, 1) + else + AddAmmo(Player, amGrenade, 0) + end + GrenadeThrown = false + + end, + Ammo = { [amJetpack] = 100 }, + Respawn = { X = 2000, Y = 742 }, } + +-- The Launch Target +local LaunchTarget = 9 +TargetPos[9] = { + Targets = {{ X = 1700, Y = 640, Type = gtTarget }, { X = 1460, Y = 775, Type = gtTarget }}, + MessageTime = 20000, + Message = loc("Only the best pilots can master the following stunts.") .. "|" .. + loc("As you've seen, the dropped grenade roughly fell into your flying direction.") .. "|" .. + loc("You have to destroy two targets, but the previous technique would be very difficult or dangerous to use.") .. "|" .. + loc("So you are able to launch projectiles into your aiming direction, always at full power.") .."|".. + loc("To launch a projectile in mid-flight, hold [Precise] and press [Long jump].") .. "|" .. + loc("You can even change your aiming direction in mid-flight if you first hold [Precice] and then press [Up] or [Down].") .. "|" .. + loc("Tip: Changing your aim while flying is very difficult, so adjust it before you take off."), + Ammo = { [amJetpack] = 1, }, + Respawn = { X = 1764, Y = 916 }, + ExtraFunc = function() + HogTurnLeft(Player, true) + if SaucerGear ~= nil then + AddAmmo(Player, amBazooka, 2) + else + AddAmmo(Player, amBazooka, 0) + end + BazookasLeft = 2 + + end } + +-- The Underwater Attack Target +local UnderwaterAttackTarget = 10 +TargetPos[10] = { + MessageTime = 17000, + Message = loc("Now for the supreme discipline of saucer flying, the underwater attack.") .. "|" .. + loc("Basically this is a combination of diving and launching.") .. "|" .. + loc("Dropping a weapon while in water would just drown it, but launching one would work.") .."|" .. + loc("Based on what you've learned, destroy the target on the girder and as always, land safely!"), + Targets = {{ X = 1200, Y = 930, Type = gtTarget }}, + Ammo = { [amJetpack] = 1, }, + Respawn = { X = 1027, Y = 217 }, + ExtraFunc = function() + if SaucerGear ~= nil then + AddAmmo(Player, amBazooka, 1) + else + AddAmmo(Player, amBazooka, 0) + end + BazookasLeft = 1 + end } +TargetPos[11] = { + Targets = {{ X = 742, Y = 290 }}, + MessageTime = 5000, + Message = loc("This almost concludes our tutorial.") .. "|" .. + loc("You now have infinite fuel, grenades and bazookas for fun.") .. "|" .. + loc("Collect or destroy the final crate to finish the training."), + Ammo = { [amJetpack] = 100, [amGrenade] = 100, [amBazooka] = 100 }, + InfFuel = true, } +TargetPos[12] = { Modifier = true, Func = function() + Objective = true + AddCaption(loc("Training complete!"), 0xFFFFFFFF, capgrpGameState) + Info(loc("Training complete!"), loc("Good bye!"), 4, 5000) + + if SaucerGear ~= nil then + DeleteGear(SaucerGear) + end + SetState(Player, band(GetState(Player), bnot(gstHHDriven))) + SetState(Player, bor(GetState(Player), gstWinner)) + PlaySound(sndVictory, Player) + + SendStat(siGameResult, loc("You have finished the Flying Saucer Training!")) + SendStat(siCustomAchievement, loc("Good job!")) + SendStat(siPlayerKills, "0", loc("Hogonauts")) + + TurnTimeLeft = 0 + EndGame() +end, +} + +-- Just a wrapper for ShowMission +function Info(Title, Text, Icon, Time) + if Time == nil then Time = 0 end + if Icon == nil then Icon = 2 end + ShowMission(loc("Flying Saucer Training"), Title, Text, Icon, Time) +end + +-- Spawn all the gears for the Boom Target +function SpawnBoomTarget() + if TargetsRemaining < 1 then + TargetGears[1] = AddGear(1602, 507, gtTarget, 0, 0, 0, 0) + TargetsRemaining = TargetsRemaining + 1 + end + + if Barrels[1] == nil then + Barrels[1] = AddGear(1563, 532, gtExplosives, 0, 0, 0, 0) + end + if Barrels[2] == nil then + Barrels[2] = AddGear(1648, 463, gtExplosives, 0, 0, 0, 0) + end + + for i=1,#Barrels do + SetHealth(Barrels[i], 1) + end +end + +-- Generic target spawning for the current target +function SpawnTargets() + for i=1,#TargetPos[TargetNumber].Targets do + if TargetGears[i] == nil then + SpawnTarget(TargetPos[TargetNumber].Targets[i].X, TargetPos[TargetNumber].Targets[i].Y, + TargetPos[TargetNumber].Targets[i].Type, i) + end + end +end + +function SpawnTarget( PosX, PosY, Type, ID ) + if Type ~= nil and Type ~= gtCase then + if Type == gtTarget then + TargetGears[ID] = AddGear(PosX, PosY, gtTarget, 0, 0, 0, 0) + end + else + TargetGears[ID] = SpawnFakeUtilityCrate(PosX, PosY, false, false) + end + TargetsRemaining = TargetsRemaining + 1 +end + +function AutoSpawn() -- Auto-spawn the next target after you've obtained the current target! + TargetNumber = TargetNumber + 1 + TargetsRemaining = 0 + + if TargetPos[TargetNumber].Ammo then + for ammoType, count in pairs(TargetPos[TargetNumber].Ammo) do + AddAmmo(Player, ammoType, count) + end + if GetCurAmmoType() ~= amJetpack then + SetWeapon(amJetpack) + end + end + if TargetPos[TargetNumber].InfFuel then + InfFuel = true + else + InfFuel = false + end + + -- Func (if present) will be run instead of the ordinary spawning handling + if TargetPos[TargetNumber].Modifier then -- If there is a modifier, run the function + TargetPos[TargetNumber].Func() + return true + end + + -- ExtraFunc is for additional events for a target + if TargetPos[TargetNumber].ExtraFunc ~= nil then + TargetPos[TargetNumber].ExtraFunc() + end + + local subcap + if TargetNumber == 1 then + subcap = loc("Training") + else + subcap = loc("Instructions") + end + Info(subcap, TargetPos[TargetNumber].Message, TargetPos[TargetNumber].MessageIcon, TargetPos[TargetNumber].MessageTime) + + -- Spawn targets on the next position + SpawnTargets() + + if TargetNumber > 1 then + AddCaption(loc("Next target is ready!"), 0xFFFFFFFF, capgrpMessage2) + end +end + +-- Returns true if the hedgehog has safely "landed" (alive, no flying saucer gear and not moving) +-- This is to ensure the training only continues when the player didn't screw up and to restart the current target +function HasHedgehogLandedYet() + if band(GetState(Player), gstMoving) == 0 and SaucerGear == nil and GetHealth(Player) > 0 then + return true + else + return false + end +end + +-- Clean up the gear mess left behind when the player failed to get a clean state after restarting +function CleanUpGears() + -- (We track flames, grenades, bazooka shells) + runOnGears(DeleteGear) +end + +-- Completely restarts the current target/objective; the hedgehog is spawned at the last "checkpoint" +-- Called when hedgeghog is resurrected or skips turn +function ResetCurrentTarget() + GrenadeThrown = false + GrenadeTimer = 0 + if TargetNumber == LaunchTarget then + BazookasLeft = 2 + elseif TargetNumber == UnderwaterAttackTarget then + BazookasLeft = 1 + else + BazookasLeft = 0 + end + Check = false + + CleanUpGears() + + local X, Y + if TargetNumber == 1 then + X, Y = StartPos.X, StartPos.Y + else + if TargetPos[TargetNumber-1].Modifier or TargetPos[TargetNumber-1].Respawn ~= nil then + X, Y = TargetPos[TargetNumber-1].Respawn.X, TargetPos[TargetNumber-1].Respawn.Y + else + X, Y = TargetPos[TargetNumber-1].Targets[1].X, TargetPos[TargetNumber-1].Targets[1].Y + end + end + if TargetNumber == BoomTarget then + SpawnBoomTarget() + end + if TargetPos[TargetNumber].Modifier ~= true then + SpawnTargets() + end + if TargetPos[TargetNumber].Ammo then + for ammoType, count in pairs(TargetPos[TargetNumber].Ammo) do + AddAmmo(Player, ammoType, count) + end + if GetCurAmmoType() ~= amJetpack then + SetWeapon(amJetpack) + end + end + if TargetPos[TargetNumber].InfFuel then + InfFuel = true + else + InfFuel = false + end + + SetGearPosition(Player, X, Y) +end + +function onGameInit() + Seed = 1 + GameFlags = gfInfAttack + gfOneClanMode + gfSolidLand + gfDisableWind + TurnTime = 2000000 --[[ This rffectively hides the turn time; a turn time above 1000s is not displayed. + We will also ensure this timer always stays above 999s later ]] + CaseFreq = 0 + MinesNum = 0 + Explosives = 0 + Map = "Eyes" + Theme = "EarthRise" + SuddenDeathTurns = 50 + WaterRise = 0 + HealthDecrease = 0 + + -- Team name is a pun on “hedgehog” and “astronauts” + AddTeam( loc( "Hogonauts" ), 0xDDDD00, "earth", "Earth", "Default", "cm_galaxy" ) + + -- Hedgehog name is a pun on “Neil Armstrong” + Player = AddHog( loc( "Neil Hogstrong" ), 0, 1, "NoHat" ) + SetGearPosition( Player, StartPos.X, StartPos.Y) + SetEffect( Player, heResurrectable, 1 ) +end + +function onGameStart() + SendHealthStatsOff() + + -- Girder near first crate + PlaceGirder(1257, 204, 6) + + -- The upper girders + PlaceGirder(84, 16, 0) + PlaceGirder(1980, 16, 0) + + -- The lower girder platform at the water pit + PlaceGirder(509, 896, 4) + PlaceGirder(668, 896, 4) + PlaceGirder(421, 896, 2) + PlaceGirder(758, 896, 2) + + -- Girders for the Launch Target and the Underwater Attack Target + PlaceGirder(1191, 960, 4) + PlaceGirder(1311, 960, 0) + PlaceGirder(1460, 827, 3) + PlaceGirder(1509, 763, 2) + PlaceGirder(1605, 672, 4) + PlaceGirder(1764, 672, 4) + PlaceGirder(1803, 577, 6) + + -- Spawn our 1st target using the wrapper function + AutoSpawn() +end + +function onAmmoStoreInit() + SetAmmo(amJetpack, 0, 0, 0, 0) + SetAmmo(amGrenade, 0, 0, 0, 0) + SetAmmo(amBazooka, 0, 0, 0, 0) + + -- Added for resetting current target/objective when player is stuck somehow + SetAmmo(amSkip, 9, 0, 0, 0) +end + +function onGearAdd(Gear) + if GetGearType(Gear) == gtJetpack then + SaucerGear = Gear + if TargetNumber == BoomTarget and GrenadeThrown == false then + AddAmmo(Player, amGrenade, 1) + end + if (TargetNumber == LaunchTarget or TargetNumber == UnderwaterAttackTarget) and BazookasLeft > 0 then + AddAmmo(Player, amBazooka, BazookasLeft) + end + end + if GetGearType(Gear) == gtGrenade then + GrenadeThrown = true + GrenadeTimer = 0 + end + if GetGearType(Gear) == gtShell then + BazookasLeft = BazookasLeft - 1 + end + if GetGearType(Gear) == gtFlame or GetGearType(Gear) == gtGrenade or GetGearType(Gear) == gtShell then + trackGear(Gear) + end +end + +function onGearDelete(Gear) + if GetGearType(Player) ~= nil and (GetGearType(Gear) == gtTarget or GetGearType(Gear) == gtCase) then + for i=1, #TargetGears do + if Gear == TargetGears[i] then + TargetGears[i] = nil + TargetsRemaining = TargetsRemaining - 1 + end + end + if TargetsRemaining <= 0 then + if TargetNumber == BoomTarget or not HasHedgehogLandedYet() then + if SaucerGear then + AddCaption(loc("Objective completed! Now land safely."), 0xFFFFFFFF, capgrpMessage2) + end + Check = true + CheckTimer = 500 + else + AutoSpawn() + end + end + end + if GetGearType(Gear) == gtGrenade then + GrenadeTimer = 0 + GrenadeExploded = true + end + if GetGearType(Gear) == gtJetpack then + SaucerGear = nil + if TargetNumber == BoomTarget then + AddAmmo(Player, amGrenade, 0) + end + if TargetNumber == LaunchTarget or TargetNumber == UnderwaterAttackTarget then + AddAmmo(Player, amBazooka, 0) + end + end + if GetGearType(Gear) == gtCase and GetGearType(Player) ~= nil then + PlaySound(sndShotgunReload) + end + if Gear == Barrels[1] then + Barrels[1] = nil + end + if Gear == Barrels[2] then + Barrels[2] = nil + AddCaption(loc("Kaboom!"), 0xFFFFFFFF, capgrpMessage) + end +end + + + +function onNewTurn() + SetWeapon(amJetpack) +end + +function onGameTick20() + if (TurnTimeLeft < 1500000 and not Objective) then + TurnTimeLeft = TurnTime + end + if Check then + CheckTimer = CheckTimer - 20 + if CheckTimer <= 0 then + if HasHedgehogLandedYet() then + AutoSpawn() + Check = false + GrenadeThrown = false + end + end + end + if GrenadeExploded and TargetNumber == BoomTarget then + GrenadeTimer = GrenadeTimer + 20 + if GrenadeTimer > 1500 then + GrenadeTimer = 0 + GrenadeThrown = false + GrenadeExploded = false + if SaucerGear and TargetNumber == BoomTarget and TargetsRemaining > 0 then + PlaySound(sndShotgunReload) + AddCaption(loc("+1 Grenade"), 0xDDDD00FF, capgrpAmmoinfo) + AddAmmo(Player, amGrenade, 1) + end + end + end + ResetFuel() +end + +-- Used to ensure infinite fuel +function ResetFuel() + if SaucerGear and InfFuel then + SetHealth(SaucerGear, 2000) + end +end + +onUp = ResetFuel +onLeft = ResetFuel +onRight = ResetFuel + +function onGearDamage(Gear) + if Gear == Player then + CleanUpGears() + GrenadeThrown = false + Check = false + end +end + +function onGearResurrect(Gear) + if Gear == Player then + AddCaption(loc("Oh no! You have died. Try again!"), 0xFFFFFFFF, capgrpMessage2) + ResetCurrentTarget() + end +end + +function onHogAttack(ammoType) + if ammoType == amSkip then + AddCaption(loc("Try again!"), 0xFFFFFFFF, capgrpMessage2) + ResetCurrentTarget() + end +end