# HG changeset patch # User unc0rr # Date 1388865354 -14400 # Node ID 2759212a27deaf7da09983a35e38f7e57b75cd63 # Parent 8054d9d775fd3c8d8a18551c4884c69474c2c3bd# Parent 91a43c79cd4b97970a8cde7e1415882ec77900e5 merge default diff -r 8054d9d775fd -r 2759212a27de .hgtags --- a/.hgtags Fri Oct 11 17:43:13 2013 +0200 +++ b/.hgtags Sat Jan 04 23:55:54 2014 +0400 @@ -60,3 +60,4 @@ 0000000000000000000000000000000000000000 0.9.18-release 2fc02902c7cbf3c29bfe08a50e5f37983582b251 0.9.18-release 1617149e01a4fa25637e2ab655d0287ef9c21b7c 0.9.19-release +af0520a6bf0061b27f8321514d35fcd2b1ef5f9c 0.9.20-release diff -r 8054d9d775fd -r 2759212a27de .travis.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.travis.yml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,33 @@ +language: c +branches: + except: + gh-pages +compiler: + - gcc + - clang +env: + # Default build. Release. + - BUILD_ARGS="-DCMAKE_BUILD_TYPE=Release" + # Debug build + - BUILD_ARGS="-DCMAKE_BUILD_TYPE=Debug" + # Everything that's optional + - BUILD_ARGS="-NOPNG=1" + - BUILD_ARGS="-NOVIDEOREC=1" + - BUILD_ARGS="-NOSERVER=1" + - BUILD_ARGS="-LUA_SYSTEM=0" +matrix: + allow_failures: + # Failures we expect here +before_install: + - sudo apt-get update -qq + - sudo apt-get install debhelper cmake dpkg-dev libqt4-dev fp-compiler libsdl1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev libsdl-image1.2-dev libsdl-net1.2-dev bzip2 fp-units-gfx ghc libghc-stm-dev libghc-network-dev libghc-dataenc-dev libghc-hslogger-dev libghc-utf8-string-dev liblua5.1-0-dev imagemagick libghc-bytestring-show-dev fpc libpng-dev libavcodec-dev libavformat-dev freeglut3-dev libghc-mtl-dev libghc-parsec3-dev libghc-vector-dev qt4-qmake fp-units-misc libghc-random-dev +script: + - mkdir build && cd build && cmake $BUILD_ARGS .. && make VERBOSE=1 +notifications: + irc: + channels: + - "chat.freenode.net#hedgewars" + template: + - "hw-build #%{build_number} (%{commit} by %{author}): %{message}" + - "See details at %{build_url}" + email: false diff -r 8054d9d775fd -r 2759212a27de CMakeLists.txt --- a/CMakeLists.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/CMakeLists.txt Sat Jan 04 23:55:54 2014 +0400 @@ -47,7 +47,7 @@ set(CPACK_PACKAGE_VERSION_MAJOR 0) set(CPACK_PACKAGE_VERSION_MINOR 9) set(CPACK_PACKAGE_VERSION_PATCH 20) -set(HEDGEWARS_PROTO_VER 46) +set(HEDGEWARS_PROTO_VER 48) set(HEDGEWARS_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") include(${CMAKE_MODULE_PATH}/revinfo.cmake) @@ -55,9 +55,10 @@ #general utilities include(${CMAKE_MODULE_PATH}/utils.cmake) +#paths initialization +include(${CMAKE_MODULE_PATH}/paths.cmake) #platform specific init code include(${CMAKE_MODULE_PATH}/platform.cmake) -include(${CMAKE_MODULE_PATH}/paths.cmake) #when build type is not specified, assume Debug/Release according to build version information @@ -76,15 +77,12 @@ include(${CMAKE_MODULE_PATH}/compilerchecks.cmake) #set default compiler flags -add_flag_append(CMAKE_C_FLAGS "-Wall -pipe -fPIC") -add_flag_append(CMAKE_C_FLAGS_RELEASE "-Os") +add_flag_append(CMAKE_C_FLAGS "-Wall -pipe") +add_flag_append(CMAKE_C_FLAGS_RELEASE "-O2") add_flag_append(CMAKE_C_FLAGS_DEBUG "-Wextra -O0") -add_flag_append(CMAKE_CXX_FLAGS "-Wall -pipe -fPIC") -add_flag_append(CMAKE_CXX_FLAGS_RELEASE "-Os") +add_flag_append(CMAKE_CXX_FLAGS "-Wall -pipe") +add_flag_append(CMAKE_CXX_FLAGS_RELEASE "-O2") add_flag_append(CMAKE_CXX_FLAGS_DEBUG "-Wextra -O0") -add_flag_append(CMAKE_Pascal_FLAGS "-Cs2000000 -fPIC") -add_flag_append(CMAKE_Pascal_FLAGS_DEBUG "-O- -gv") -add_flag_append(CMAKE_Pascal_FLAGS_RELEASE "-Os -Xs") #CMake adds a lot of additional configuration flags, so let's clear them up if(${MINIMAL_FLAGS}) diff -r 8054d9d775fd -r 2759212a27de CREDITS --- a/CREDITS Fri Oct 11 17:43:13 2013 +0200 +++ b/CREDITS Sat Jan 04 23:55:54 2014 +0400 @@ -17,8 +17,7 @@ ========== - Robinator -> Terminator (2010) - shingo666 -> Samus (2010) -- MeinCookie95 -> InfernalHorns (2010) -- MeinCookie95 -> Mummy (2010) +- MeinCookie95 -> InfernalHorns (2010), Mummy (2010), war_* (2010-2011) - thuban -> Elvis (2010) - Miphica -> Disguise (2010) - Blayde -> Deer (2010), Moose (2010) diff -r 8054d9d775fd -r 2759212a27de ChangeLog.txt --- a/ChangeLog.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/ChangeLog.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,8 +1,34 @@ + features * bugfixes -0.9.19 -> ???: - * increase precision in damage calcs; extra damage affects fire properly now +0.9.19 -> 0.9.20: + + New campaign, A Space Adventure! + + Password protected rooms + + Shapes on drawn maps (ellipses, rectangles) - constrain dimensions with ctrl, as with straight line tool. + + New rubber utility, lfBouncy mask (green) for maps. lfBouncy is also anti-portal. + + Lazy loading of many aspects of frontend to improve startup time under Windows + + Set hog/team/health label defaults in config, toggle team health display using delete (left shift + delete for labels now) + + Usernames next to teams when playing online. + + Can now filter rooms by game style (such as Highlander). Filtering simplified since it is mostly unused. + + AFK mode. Press p when not your turn online to trigger autoskip of your turn. + + Russian localisation of Default voice. + + Map edges can wrap or bounce. Also a silly "connect to the sea" mode + + Sticky fire kicks you a bit less, fire interacts with frozen land/ice + + Generated map stays same if the template is the same between groups (all/large for example) + + Visual enhancements for whip and crosshair + + Option to draw maps with a "shoppa" border - used by ShoppaMap lua at present + + New hats + + Translation updates + + New lua script to control gravity. May have unpredictable effects. Try zero g shoppa. Changes to allow lua to spawn poison clouds without interrupting turn. + + Speech bubbles are now echoed to chat for logging purposes with the hog's name. + * You should now thaw on your turn, not enemy's. AI frozen/unfrozen crate movement fix. Blowtorch can thaw frozen hogs. + * Prevent target crosshair moving around unpredictably when doing multiple airstrikes + * Rope should kick along surfaces more reliably, fix rope aim speed if you miss a shot, firing rope does not freeze timer, fix aiming on last rope + * Remember bounce/timer in reset wep modes like Highlander + * Increase precision in damage calcs; extra damage affects fire properly now + * Fixed video recording resolution + * Fixed context menu/cursor in text areas + * Many bugfixes. Keypad enter in chat, hog sliding freezing game, team name flaws in Windows, localisation of tips, crasher in slots with no weapons, frontend holiday css. 0.9.18 -> 0.9.19: + New Freezer weapon - freezes terrain, water, hedgehogs, mines, cases, explosives diff -r 8054d9d775fd -r 2759212a27de QTfrontend/CMakeLists.txt --- a/QTfrontend/CMakeLists.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/CMakeLists.txt Sat Jan 04 23:55:54 2014 +0400 @@ -19,7 +19,7 @@ message(FATAL_ERROR "This version of QT is known *not* to work, please update or use a lower version") endif() -find_package(SDL REQUIRED) #video in SDLInteraction +find_package(SDL1or2) #video in SDLInteraction find_package(SDL_mixer REQUIRED) #audio in SDLInteraction if(${FFMPEG_FOUND}) @@ -61,9 +61,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/util/platform) include_directories(${SDL_INCLUDE_DIR}) include_directories(${SDLMIXER_INCLUDE_DIR}) -include_directories(${PHYSFS_INCLUDE_DIR}) -include_directories(${PHYSLAYER_INCLUDE_DIR}) -include_directories(${LUA_INCLUDE_DIR}) #brought by physlayer hwpacksmounter.h +include_directories(BEFORE ${PHYSFS_INCLUDE_DIR}) +include_directories(BEFORE ${PHYSLAYER_INCLUDE_DIR}) if(UNIX) diff -r 8054d9d775fd -r 2759212a27de QTfrontend/binds.cpp --- a/QTfrontend/binds.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/binds.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -65,6 +65,7 @@ {"mute", "8", QT_TRANSLATE_NOOP("binds", "mute audio"), NULL, NULL}, {"fullscr", "f12", QT_TRANSLATE_NOOP("binds", "change mode"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Toggle fullscreen mode:")}, {"capture", "c", QT_TRANSLATE_NOOP("binds", "capture"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Take a screenshot:")}, + {"+speedup", "s", QT_TRANSLATE_NOOP("binds", "speed up replay"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Demo replay:")}, {"rotmask", "delete", QT_TRANSLATE_NOOP("binds", "hedgehog info"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Toggle labels above hedgehogs:")}, #ifdef VIDEOREC {"record", "r", QT_TRANSLATE_NOOP("binds", "record"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Record video:")} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/binds.h --- a/QTfrontend/binds.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/binds.h Sat Jan 04 23:55:54 2014 +0400 @@ -22,9 +22,9 @@ #include #ifdef VIDEOREC -#define BINDS_NUMBER 46 +#define BINDS_NUMBER 47 #else -#define BINDS_NUMBER 45 +#define BINDS_NUMBER 46 #endif struct BindAction diff -r 8054d9d775fd -r 2759212a27de QTfrontend/campaign.cpp --- a/QTfrontend/campaign.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/campaign.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -17,47 +17,94 @@ */ #include "campaign.h" - #include "hwconsts.h" - +#include "DataManager.h" #include - +#include +#include -QStringList getCampMissionList(QString & campaign) -{ - QSettings campfile("physfs://Missions/Campaign/" + campaign + "/campaign.ini", QSettings::IniFormat, 0); - campfile.setIniCodec("UTF-8"); - unsigned int mNum = campfile.value("MissionNum", 0).toInt(); - - QStringList missionList; - for (unsigned int i = 0; i < mNum; i++) - { - missionList += campfile.value(QString("Mission %1/Name").arg(i + 1)).toString(); - } - return missionList; -} - -unsigned int getCampProgress(QString & teamName, QString & campName) +QList getCampMissionList(QString & campaignName, QString & teamName) { - QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0); + QList missionInfoList; + QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0); teamfile.setIniCodec("UTF-8"); - return teamfile.value("Campaign " + campName + "/Progress", 0).toInt(); -} + + // if entry not found check if there is written without _ + // if then is found rename it to use _ + QString spaceCampName = campaignName; + spaceCampName = spaceCampName.replace(QString("_"),QString(" ")); + if (!teamfile.childGroups().contains("Campaign " + campaignName) and + teamfile.childGroups().contains("Campaign " + spaceCampName)){ + teamfile.beginGroup("Campaign " + spaceCampName); + QStringList keys = teamfile.childKeys(); + teamfile.endGroup(); + for (int i=0;i=0 and unlockedMissions==0) + { + for(unsigned int i=progress+1;i>0;i--) + { + MissionInfo missionInfo; + missionInfo.name = campfile.value(QString("Mission %1/Name").arg(i)).toString(); + QString script = campfile.value(QString("Mission %1/Script").arg(i)).toString(); + missionInfo.script = script; + missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc", + QObject::tr("No description available")).toString(); + QString image = campfile.value(QString("Mission %1/Script").arg(i)).toString().replace(QString(".lua"),QString(".png")); + missionInfo.image = ":/res/campaign/"+campaignName+"/"+image; + if (!QFile::exists(missionInfo.image)) + missionInfo.image = ":/res/CampaignDefault.png"; + missionInfoList.append(missionInfo); + } + } + else if(unlockedMissions>0) + { + for(int i=1;i<=unlockedMissions;i++) + { + QString missionNum = QString("%1").arg(i); + int missionNumber = teamfile.value("Campaign " + campaignName + "/Mission"+missionNum, -1).toInt(); + MissionInfo missionInfo; + missionInfo.name = campfile.value(QString("Mission %1/Name").arg(missionNumber)).toString(); + QString script = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString(); + missionInfo.script = script; + missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc", + QObject::tr("No description available")).toString(); + QString image = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString().replace(QString(".lua"),QString(".png")); + missionInfo.image = ":/res/campaign/"+campaignName+"/"+image; + if (!QFile::exists(missionInfo.image)) + missionInfo.image = ":/res/CampaignDefault.png"; + missionInfoList.append(missionInfo); + } + } + return missionInfoList; } - -QString getCampaignImage(QString campaign, unsigned int mNum) -{ - return getCampaignScript(campaign,mNum).replace(QString(".lua"),QString(".png")); -} - -QString getCampaignMissionName(QString campaign, unsigned int mNum) -{ - return getCampaignScript(campaign,mNum).replace(QString(".lua"),QString("")); -} - diff -r 8054d9d775fd -r 2759212a27de QTfrontend/campaign.h --- a/QTfrontend/campaign.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/campaign.h Sat Jan 04 23:55:54 2014 +0400 @@ -20,12 +20,16 @@ #define CAMPAIGN_H #include -#include -QStringList getCampMissionList(QString & campaign); -unsigned int getCampProgress(QString & teamName, QString & campName); -QString getCampaignScript(QString campaign, unsigned int mNum); -QString getCampaignImage(QString campaign, unsigned int mNum); -QString getCampaignMissionName(QString campaign, unsigned int mNum); +class MissionInfo +{ + public: + QString name; + QString description; + QString script; + QString image; +}; + +QList getCampMissionList(QString & campaignName, QString & teamName); #endif diff -r 8054d9d775fd -r 2759212a27de QTfrontend/drawmapscene.cpp --- a/QTfrontend/drawmapscene.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/drawmapscene.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "drawmapscene.h" @@ -44,6 +46,8 @@ setBackgroundBrush(m_eraser); m_isErasing = false; + m_pathType = Polyline; + m_pen.setWidth(76); m_pen.setJoinStyle(Qt::RoundJoin); m_pen.setCapStyle(Qt::RoundCap); @@ -60,19 +64,45 @@ if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton)) { QPainterPath path = m_currPath->path(); + QPointF currentPos = mouseEvent->scenePos(); if(mouseEvent->modifiers() & Qt::ControlModifier) + currentPos = putSomeConstraints(paths.first().initialPoint, currentPos); + + switch (m_pathType) { - int c = path.elementCount(); - QPointF pos = mouseEvent->scenePos(); - path.setElementPositionAt(c - 1, pos.x(), pos.y()); + case Polyline: + if(mouseEvent->modifiers() & Qt::ControlModifier) + { + int c = path.elementCount(); + path.setElementPositionAt(c - 1, currentPos.x(), currentPos.y()); + } + else + { + path.lineTo(currentPos); + paths.first().points.append(mouseEvent->scenePos().toPoint()); + } + break; + case Rectangle: { + path = QPainterPath(); + QPointF p1 = paths.first().initialPoint; + QPointF p2 = currentPos; + path.moveTo(p1); + path.lineTo(p1.x(), p2.y()); + path.lineTo(p2); + path.lineTo(p2.x(), p1.y()); + path.lineTo(p1); + break; + } + case Ellipse: { + path = QPainterPath(); + QList points = makeEllipse(paths.first().initialPoint, currentPos); + path.addPolygon(QPolygonF(QVector::fromList(points))); + break; } - else - { - path.lineTo(mouseEvent->scenePos()); - paths.first().points.append(mouseEvent->scenePos().toPoint()); } + m_currPath->setPath(path); emit pathChanged(); @@ -96,7 +126,8 @@ PathParams params; params.width = serializePenWidth(m_pen.width()); params.erasing = m_isErasing; - params.points = QList() << mouseEvent->scenePos().toPoint(); + params.initialPoint = mouseEvent->scenePos().toPoint(); + params.points = QList() << params.initialPoint; paths.prepend(params); m_currPath->setPath(path); @@ -107,14 +138,43 @@ { if (m_currPath) { - QPainterPath path = m_currPath->path(); - path.lineTo(mouseEvent->scenePos()); - paths.first().points.append(mouseEvent->scenePos().toPoint()); - m_currPath->setPath(path); + QPointF currentPos = mouseEvent->scenePos(); + + if(mouseEvent->modifiers() & Qt::ControlModifier) + currentPos = putSomeConstraints(paths.first().initialPoint, currentPos); - simplifyLast(); + switch (m_pathType) + { + case Polyline: { + QPainterPath path = m_currPath->path(); + path.lineTo(mouseEvent->scenePos()); + paths.first().points.append(currentPos.toPoint()); + m_currPath->setPath(path); + simplifyLast(); + break; + } + case Rectangle: { + QPoint p1 = paths.first().initialPoint; + QPoint p2 = currentPos.toPoint(); + QList rpoints; + rpoints << p1 << QPoint(p1.x(), p2.y()) << p2 << QPoint(p2.x(), p1.y()) << p1; + paths.first().points = rpoints; + break; + } + case Ellipse: + QPoint p1 = paths.first().initialPoint; + QPoint p2 = currentPos.toPoint(); + QList points = makeEllipse(p1, p2); + QList epoints; + foreach(const QPointF & p, points) + epoints.append(p.toPoint()); + paths.first().points = epoints; + break; + } m_currPath = 0; + + emit pathChanged(); } } @@ -345,8 +405,6 @@ QGraphicsPathItem * pathItem = static_cast(items()[m_isCursorShown ? 1 : 0]); pathItem->setPath(pointsToPath(paths[0].points)); } - - emit pathChanged(); } int DrawMapScene::pointsCount() @@ -383,3 +441,47 @@ { return width * 10 + 6; } + +void DrawMapScene::setPathType(PathType pathType) +{ + m_pathType = pathType; +} + +QList DrawMapScene::makeEllipse(const QPointF ¢er, const QPointF &corner) +{ + QList l; + qreal rx = qAbs(center.x() - corner.x()); + qreal ry = qAbs(center.y() - corner.y()); + qreal r = qMax(rx, ry); + + if(r < 4) + { + l.append(center); + } else + { + qreal angleDelta = qMax(0.1, qMin(0.7, 120 / r)); + for(qreal angle = 0.0; angle < 2*M_PI; angle += angleDelta) + l.append(center + QPointF(rx * cos(angle), ry * sin(angle))); + l.append(l.first()); + } + + return l; +} + +QPointF DrawMapScene::putSomeConstraints(const QPointF &initialPoint, const QPointF &point) +{ + QPointF vector = point - initialPoint; + + for(int angle = 0; angle < 180; angle += 15) + { + QTransform transform; + transform.rotate(angle); + + QPointF rotated = transform.map(vector); + + if(rotated.x() == 0) return point; + if(qAbs(rotated.y() / rotated.x()) < 0.05) return initialPoint + transform.inverted().map(QPointF(rotated.x(), 0)); + } + + return point; +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/drawmapscene.h --- a/QTfrontend/drawmapscene.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/drawmapscene.h Sat Jan 04 23:55:54 2014 +0400 @@ -29,6 +29,7 @@ { quint8 width; bool erasing; + QPoint initialPoint; QList points; }; @@ -38,6 +39,12 @@ { Q_OBJECT public: + enum PathType { + Polyline = 0, + Rectangle = 1, + Ellipse = 2 + }; + explicit DrawMapScene(QObject *parent = 0); QByteArray encode(); @@ -54,6 +61,7 @@ void setErasing(bool erasing); void showCursor(); void hideCursor(); + void setPathType(PathType pathType); private: QPen m_pen; @@ -67,6 +75,7 @@ QGraphicsEllipseItem * m_cursor; bool m_isCursorShown; QByteArray m_specialPoints; + PathType m_pathType; virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent); virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent); @@ -77,6 +86,8 @@ quint8 serializePenWidth(int width); int deserializePenWidth(quint8 width); + QList makeEllipse(const QPointF & center, const QPointF & corner); + QPointF putSomeConstraints(const QPointF & initialPoint, const QPointF & point); }; #endif // DRAWMAPSCENE_H diff -r 8054d9d775fd -r 2759212a27de QTfrontend/game.cpp --- a/QTfrontend/game.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/game.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -506,7 +506,7 @@ void HWGame::sendCampaignVar(const QByteArray &varToSend) { - QString varToFind(varToSend); + QString varToFind = QString::fromUtf8(varToSend); QSettings teamfile(QString("physfs://Teams/%1.hwt").arg(campaignTeam), QSettings::IniFormat, 0); teamfile.setIniCodec("UTF-8"); QString varValue = teamfile.value("Campaign " + campaign + "/" + varToFind, "").toString(); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/gameuiconfig.cpp --- a/QTfrontend/gameuiconfig.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/gameuiconfig.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -159,6 +159,8 @@ Form->ui.pageOptions->leProxyLogin->setText(value("proxy/login", "").toString()); Form->ui.pageOptions->leProxyPassword->setText(value("proxy/password", "").toString()); + applyProxySettings(); + { // load colors QStandardItemModel * model = DataManager::instance().colorsModel(); for(int i = model->rowCount() - 1; i >= 0; --i) @@ -310,22 +312,7 @@ setValue("proxy/password", Form->ui.pageOptions->leProxyPassword->text()); } - QNetworkProxy proxy; - - if(proxyType == PageOptions::SystemProxy) - { - // use system proxy settings - proxy = QNetworkProxyFactory::systemProxyForQuery().at(0); - } else - { - proxy.setType(proxyTypesMap[proxyType]); - proxy.setHostName(Form->ui.pageOptions->leProxy->text()); - proxy.setPort(Form->ui.pageOptions->sbProxyPort->value()); - proxy.setUser(Form->ui.pageOptions->leProxyLogin->text()); - proxy.setPassword(Form->ui.pageOptions->leProxyPassword->text()); - } - - QNetworkProxy::setApplicationProxy(proxy); + applyProxySettings(); } { // save colors @@ -665,3 +652,25 @@ m_binds[bindID].strbind = strbind; setValue(QString("Binds/%1").arg(m_binds[bindID].action), strbind); } + +void GameUIConfig::applyProxySettings() +{ + QNetworkProxy proxy; + + int proxyType = Form->ui.pageOptions->cbProxyType->currentIndex(); + + if(proxyType == PageOptions::SystemProxy) + { + // use system proxy settings + proxy = QNetworkProxyFactory::systemProxyForQuery().at(0); + } else + { + proxy.setType(proxyTypesMap[proxyType]); + proxy.setHostName(Form->ui.pageOptions->leProxy->text()); + proxy.setPort(Form->ui.pageOptions->sbProxyPort->value()); + proxy.setUser(Form->ui.pageOptions->leProxyLogin->text()); + proxy.setPassword(Form->ui.pageOptions->leProxyPassword->text()); + } + + QNetworkProxy::setApplicationProxy(proxy); +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/gameuiconfig.h --- a/QTfrontend/gameuiconfig.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/gameuiconfig.h Sat Jan 04 23:55:54 2014 +0400 @@ -99,6 +99,8 @@ bool eventFilter(QObject *object, QEvent *event); QString temphash; QList m_binds; + + void applyProxySettings(); }; #endif diff -r 8054d9d775fd -r 2759212a27de QTfrontend/hedgewars.qrc --- a/QTfrontend/hedgewars.qrc Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/hedgewars.qrc Sat Jan 04 23:55:54 2014 +0400 @@ -38,12 +38,27 @@ res/campaign/A_Classic_Fairytale/queen.png res/campaign/A_Classic_Fairytale/enemy.png res/campaign/A_Classic_Fairytale/epil.png + res/campaign/A_Space_Adventure/cosmos.png + res/campaign/A_Space_Adventure/moon01.png + res/campaign/A_Space_Adventure/moon02.png + res/campaign/A_Space_Adventure/ice01.png + res/campaign/A_Space_Adventure/ice02.png + res/campaign/A_Space_Adventure/desert01.png + res/campaign/A_Space_Adventure/desert02.png + res/campaign/A_Space_Adventure/desert03.png + res/campaign/A_Space_Adventure/fruit01.png + res/campaign/A_Space_Adventure/fruit02.png + res/campaign/A_Space_Adventure/fruit03.png + res/campaign/A_Space_Adventure/death01.png + res/campaign/A_Space_Adventure/death02.png + res/campaign/A_Space_Adventure/final.png res/bonus.png res/Hedgehog.png res/net.png res/About.png res/SimpleGame.png res/Campaign.png + res/CampaignDefault.png res/Multiplayer.png res/Trainings.png res/Background.png @@ -164,7 +179,6 @@ res/chat/ingame.png res/splash.png res/html/about.html - res/xml/tips.xml res/chat/hedgehogcontributor.png res/chat/hedgehogcontributor_gray.png res/chat/roomadmincontributor.png diff -r 8054d9d775fd -r 2759212a27de QTfrontend/hwform.cpp --- a/QTfrontend/hwform.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/hwform.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -198,6 +198,7 @@ UpdateTeamsLists(); InitCampaignPage(); UpdateCampaignPage(0); + UpdateCampaignPageMission(0); UpdateWeapons(); // connect all goBack signals @@ -305,6 +306,7 @@ connect(ui.pageTraining, SIGNAL(startMission(const QString&)), this, SLOT(startTraining(const QString&))); connect(ui.pageCampaign->BtnStartCampaign, SIGNAL(clicked()), this, SLOT(StartCampaign())); + connect(ui.pageCampaign->btnPreview, SIGNAL(clicked()), this, SLOT(StartCampaign())); connect(ui.pageCampaign->CBTeam, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateCampaignPage(int))); connect(ui.pageCampaign->CBCampaign, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateCampaignPage(int))); connect(ui.pageCampaign->CBMission, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateCampaignPageMission(int))); @@ -1128,7 +1130,7 @@ //ForcedDisconnect(tr("No nickname supplied.")); bool retry = RetryDialog(tr("Hedgewars - Empty nickname"), tr("No nickname supplied.")); GoBack(); - if (retry) { + if (retry && hwnet) { if (hwnet->m_private_game) { QStringList list = hwnet->getHost().split(":"); NetConnectServer(list.at(0), list.at(1).toShort()); @@ -1138,7 +1140,8 @@ return; } - hwnet->NewNick(newNick); + if(hwnet) + hwnet->NewNick(newNick); config->setValue("net/nick", newNick); config->updNetNick(); @@ -1162,6 +1165,13 @@ } } +void HWForm::askRoomPassword() +{ + QString password = QInputDialog::getText(this, tr("Room password"), tr("The room is protected with password.\nPlease, enter the password:")); + if(hwnet && !password.isEmpty()) + hwnet->roomPasswordEntered(password); +} + bool HWForm::RetryDialog(const QString & title, const QString & label) { QMessageBox retryMsg(this); @@ -1241,6 +1251,7 @@ connect(hwnet, SIGNAL(NickTaken(const QString&)), this, SLOT(NetNickTaken(const QString&)), Qt::QueuedConnection); connect(hwnet, SIGNAL(AuthFailed()), this, SLOT(NetAuthFailed()), Qt::QueuedConnection); //connect(ui.pageNetGame->BtnBack, SIGNAL(clicked()), hwnet, SLOT(partRoom())); + connect(hwnet, SIGNAL(askForRoomPassword()), this, SLOT(askRoomPassword()), Qt::QueuedConnection); ui.pageRoomsList->chatWidget->setUsersModel(hwnet->lobbyPlayersModel()); ui.pageNetGame->chatWidget->setUsersModel(hwnet->roomPlayersModel()); @@ -1255,10 +1266,10 @@ connect(hwnet, SIGNAL(serverMessage(const QString&)), ui.pageRoomsList->chatWidget, SLOT(onServerMessage(const QString&)), Qt::QueuedConnection); - connect(ui.pageRoomsList, SIGNAL(askForCreateRoom(const QString &)), - hwnet, SLOT(CreateRoom(const QString&))); - connect(ui.pageRoomsList, SIGNAL(askForJoinRoom(const QString &)), - hwnet, SLOT(JoinRoom(const QString&))); + connect(ui.pageRoomsList, SIGNAL(askForCreateRoom(const QString &, const QString &)), + hwnet, SLOT(CreateRoom(const QString&, const QString &))); + connect(ui.pageRoomsList, SIGNAL(askForJoinRoom(const QString &, const QString &)), + hwnet, SLOT(JoinRoom(const QString&, const QString &))); // connect(ui.pageRoomsList, SIGNAL(askForCreateRoom(const QString &)), // this, SLOT(NetGameMaster())); // connect(ui.pageRoomsList, SIGNAL(askForJoinRoom(const QString &)), @@ -1720,13 +1731,9 @@ void HWForm::StartCampaign() { CreateGame(0, 0, 0); - - QComboBox *combo = ui.pageCampaign->CBMission; QString camp = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_")); - unsigned int mNum = combo->count() - combo->currentIndex(); - QString miss = getCampaignScript(camp, mNum); + QString miss = campaignMissionInfo[ui.pageCampaign->CBMission->currentIndex()].script; QString campTeam = ui.pageCampaign->CBTeam->currentText(); - game->StartCampaign(camp, miss, campTeam); } @@ -1891,85 +1898,32 @@ } } - void HWForm::UpdateCampaignPage(int index) { Q_UNUSED(index); - HWTeam team(ui.pageCampaign->CBTeam->currentText()); - ui.pageCampaign->CBMission->clear(); - QString campaignName = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_")); - QStringList missionEntries = getCampMissionList(campaignName); - QString tName = team.name(); - unsigned int n = missionEntries.count(); - unsigned int m = getCampProgress(tName, campaignName); - - // if the campaign name changes update the campaignMissionDescriptions list - // this will be used later in UpdateCampaignPageMission() to update - // the mission description in the campaign page - bool updateMissionList = false; - QSettings * m_info; - if(previousCampaignName.compare(campaignName)!=0 || - previousTeamName.compare(tName) != 0) + QString tName = team.name(); + + campaignMissionInfo = getCampMissionList(campaignName,tName); + ui.pageCampaign->CBMission->clear(); + + for(int i=0;isetIniCodec("UTF-8"); - campaignMissionDescriptions.clear(); - ui.pageCampaign->CBMission->clear(); - } - - for (unsigned int i = qMin(m + 1, n); i > 0; i--) - { - if(updateMissionList) - { - campaignMissionDescriptions += m_info->value(campaignName+"-"+ getCampaignMissionName(campaignName,i) + ".desc", - tr("No description available")).toString(); - } - ui.pageCampaign->CBMission->addItem(QString("Mission %1: ").arg(i) + QString(missionEntries[i-1]), QString(missionEntries[i-1])); - } - if(updateMissionList) - delete m_info; - - UpdateCampaignPageMission(index); + ui.pageCampaign->CBMission->addItem(QString(campaignMissionInfo[i].name), QString(campaignMissionInfo[i].name)); + } } void HWForm::UpdateCampaignPageMission(int index) { - // update thumbnail + // update thumbnail and description QString campaignName = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_")); - unsigned int mNum = ui.pageCampaign->CBMission->count() - ui.pageCampaign->CBMission->currentIndex(); - QString image = getCampaignImage(campaignName,mNum); - ui.pageCampaign->btnPreview->setIcon(QIcon((":/res/campaign/"+campaignName+"/"+image))); - // update description // when campaign changes the UpdateCampaignPageMission is triggered with wrong values // this will cause segfault. This check prevents illegal memory reads - if(index > -1 && index < campaignMissionDescriptions.count()) { + if(index > -1 && index < campaignMissionInfo.count()) { ui.pageCampaign->lbltitle->setText("

"+ui.pageCampaign->CBMission->currentText()+"

"); - ui.pageCampaign->lbldescription->setText(campaignMissionDescriptions[index]); + ui.pageCampaign->lbldescription->setText(campaignMissionInfo[index].description); + ui.pageCampaign->btnPreview->setIcon(QIcon(campaignMissionInfo[index].image)); } } @@ -1977,9 +1931,16 @@ { Q_UNUSED(index); - int missionIndex = ui.pageCampaign->CBMission->currentIndex(); + QString missionTitle = ui.pageCampaign->CBMission->currentText(); UpdateCampaignPage(0); - ui.pageCampaign->CBMission->setCurrentIndex(missionIndex); + for(int i=0;iCBMission->count();i++) + { + if (ui.pageCampaign->CBMission->itemText(i)==missionTitle) + { + ui.pageCampaign->CBMission->setCurrentIndex(i); + break; + } + } } // used for --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality] diff -r 8054d9d775fd -r 2759212a27de QTfrontend/hwform.h --- a/QTfrontend/hwform.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/hwform.h Sat Jan 04 23:55:54 2014 +0400 @@ -34,6 +34,7 @@ #include "ui_hwform.h" #include "SDLInteraction.h" #include "bgwidget.h" +#include "campaign.h" #ifdef __APPLE__ #include "InstallController.h" @@ -111,6 +112,7 @@ void NetNickNotRegistered(const QString & nick); void NetNickTaken(const QString & nick); void NetAuthFailed(); + void askRoomPassword(); bool RetryDialog(const QString & title, const QString & label); void NetTeamAccepted(const QString& team); void AddNetTeam(const HWTeam& team); @@ -194,8 +196,8 @@ AmmoSchemeModel * ammoSchemeModel; QStack PagesStack; QString previousCampaignName; - QString previousTeamName; - QStringList campaignMissionDescriptions; + QString previousTeamName; + QList campaignMissionInfo; QTime eggTimer; BGWidget * wBackground; QSignalMapper * pageSwitchMapper; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/HatModel.cpp --- a/QTfrontend/model/HatModel.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/HatModel.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -37,6 +37,8 @@ void HatModel::loadHats() { + qDebug("HatModel::loadHats()"); + // this method resets the contents of this model (important to know for views). QStandardItemModel::beginResetModel(); QStandardItemModel::clear(); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/MapModel.cpp --- a/QTfrontend/model/MapModel.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/MapModel.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -28,12 +28,26 @@ #include "HWApplication.h" #include "hwconsts.h" -MapModel::MapInfo MapModel::MapInfoRandom = {MapModel::GeneratedMap, "+rnd+", "", 0, "", "", ""}; -MapModel::MapInfo MapModel::MapInfoMaze = {MapModel::GeneratedMaze, "+maze+", "", 0, "", "", ""}; -MapModel::MapInfo MapModel::MapInfoDrawn = {MapModel::HandDrawnMap, "+drawn+", "", 0, "", "", ""}; +MapModel::MapInfo MapModel::MapInfoRandom = {MapModel::GeneratedMap, "+rnd+", "", 0, "", "", "", false}; +MapModel::MapInfo MapModel::MapInfoMaze = {MapModel::GeneratedMaze, "+maze+", "", 0, "", "", "", false}; +MapModel::MapInfo MapModel::MapInfoDrawn = {MapModel::HandDrawnMap, "+drawn+", "", 0, "", "", "", false}; + -void MapModel::loadMaps(MapType maptype) +MapModel::MapModel(MapType maptype, QObject *parent) : QStandardItemModel(parent) +{ + m_maptype = maptype; + m_loaded = false; +} + +bool MapModel::loadMaps() { + if(m_loaded) + return false; + + m_loaded = true; + + qDebug("[LAZINESS] MapModel::loadMaps()"); + // this method resets the contents of this model (important to know for views). beginResetModel(); @@ -75,7 +89,7 @@ MapType type = isMission ? MissionMap : StaticMap; // if we're supposed to ignore this type, continue - if (type != maptype) continue; + if (type != m_maptype) continue; // load map info from file QTextStream input(&mapCfgFile); @@ -149,15 +163,19 @@ QStandardItemModel::appendColumn(mapList); endResetModel(); + + return true; } -bool MapModel::mapExists(const QString & map) const +bool MapModel::mapExists(const QString & map) { return findMap(map) >= 0; } -int MapModel::findMap(const QString & map) const +int MapModel::findMap(const QString & map) { + loadMaps(); + return m_mapIndexes.value(map, -1); } diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/MapModel.h --- a/QTfrontend/model/MapModel.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/MapModel.h Sat Jan 04 23:55:54 2014 +0400 @@ -67,12 +67,14 @@ bool dlc; ///< True if this map was not packaged with the game }; + MapModel(MapType maptype, QObject *parent = 0); + /** * @brief Searches maps in model to find out if one exists * @param map map of which to check existence * @return true if it exists */ - bool mapExists(const QString & map) const; + bool mapExists(const QString & map); /** * @brief Finds a map index (column, row) for a map name @@ -86,7 +88,7 @@ * @param map map of which to find index * @return int of index, or -1 if map not found */ - int findMap(const QString & map) const; + int findMap(const QString & map); /** * @brief Finds and returns a map item for a map name @@ -98,16 +100,16 @@ // Static MapInfos for drawn and generated maps static MapInfo MapInfoRandom, MapInfoMaze, MapInfoDrawn; - public slots: - /// Reloads the maps using the DataManager. - /// Accepts two map types: StaticMap or MissionMap. - void loadMaps(MapType maptype); + /// Loads the maps + bool loadMaps(); private: /// map index lookup table. QPair contains: //QHash > m_mapIndexes; QHash m_mapIndexes; + MapType m_maptype; + bool m_loaded; /** * @brief Creates a QStandardItem, that holds the map info and item appearance. diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/ThemeModel.cpp --- a/QTfrontend/model/ThemeModel.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/ThemeModel.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -29,6 +29,8 @@ QAbstractListModel(parent) { m_data = QList >(); + + m_themesLoaded = false; } int ThemeModel::rowCount(const QModelIndex &parent) const @@ -36,7 +38,11 @@ if(parent.isValid()) return 0; else + { + if(!m_themesLoaded) + loadThemes(); return m_data.size(); + } } @@ -45,13 +51,21 @@ if(index.column() > 0 || index.row() >= m_data.size()) return QVariant(); else + { + if(!m_themesLoaded) + loadThemes(); + return m_data.at(index.row()).value(role); + } } -void ThemeModel::loadThemes() +void ThemeModel::loadThemes() const { - beginResetModel(); + qDebug("[LAZINESS] ThemeModel::loadThemes()"); + + m_themesLoaded = true; + DataManager & datamgr = DataManager::instance(); @@ -94,7 +108,4 @@ m_data.append(dataset); } - - - endResetModel(); } diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/ThemeModel.h --- a/QTfrontend/model/ThemeModel.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/ThemeModel.h Sat Jan 04 23:55:54 2014 +0400 @@ -45,14 +45,11 @@ int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; + private: + mutable QList > m_data; + mutable bool m_themesLoaded; - public slots: - /// reloads the themes from the DataManager - void loadThemes(); - - - private: - QList > m_data; + void loadThemes() const; }; #endif // HEDGEWARS_THEMEMODEL_H diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/ammoSchemeModel.cpp --- a/QTfrontend/model/ammoSchemeModel.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/ammoSchemeModel.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -65,6 +65,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; AmmoSchemeModel::AmmoSchemeModel(QObject* parent, const QString & fileName) : @@ -130,6 +131,7 @@ << "ropepct" // 39 << "getawaytime" // 40 << "worldedge" // 41 + << "scriptparam" // scriptparam 42 ; QList proMode; @@ -176,6 +178,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList shoppa; @@ -222,6 +225,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList cleanslate; @@ -268,6 +272,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList minefield; @@ -314,6 +319,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList barrelmayhem; @@ -360,6 +366,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList tunnelhogs; @@ -406,6 +413,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList forts; @@ -452,6 +460,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList timeless; @@ -498,6 +507,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList thinkingportals; @@ -544,6 +554,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; QList kingmode; @@ -590,6 +601,7 @@ << QVariant(100) // rope modfier 39 << QVariant(100) // get away time 40 << QVariant(0) // world edge 41 + << QVariant() // scriptparam 42 ; @@ -793,6 +805,8 @@ return; } + cfg[42] = cfg[42].mid(1); + for(int i = 0; i < cfg.size(); ++i) netScheme[i] = QVariant(cfg[i]); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/playerslistmodel.cpp --- a/QTfrontend/model/playerslistmodel.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/playerslistmodel.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -84,6 +84,15 @@ return true; } +QModelIndex PlayersListModel::nicknameIndex(const QString & nickname) +{ + QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly); + + if(mil.size() > 0) + return mil[0]; + else + return QModelIndex(); +} void PlayersListModel::addPlayer(const QString & nickname, bool notify) { @@ -105,22 +114,22 @@ else emit nickRemovedLobby(nickname, msg); - QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly); + QModelIndex mi = nicknameIndex(nickname); - if(mil.size()) - removeRow(mil[0].row()); + if(mi.isValid()) + removeRow(mi.row()); } void PlayersListModel::playerJoinedRoom(const QString & nickname, bool notify) { - QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly); + QModelIndex mi = nicknameIndex(nickname); - if(mil.size()) + if(mi.isValid()) { - setData(mil[0], true, RoomFilterRole); - updateIcon(mil[0]); - updateSortData(mil[0]); + setData(mi, true, RoomFilterRole); + updateIcon(mi); + updateSortData(mi); } emit nickAdded(nickname, notify); @@ -131,62 +140,65 @@ { emit nickRemoved(nickname); - QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly); + QModelIndex mi = nicknameIndex(nickname); - if(mil.size()) + if(mi.isValid()) { - setData(mil[0], false, RoomFilterRole); - setData(mil[0], false, RoomAdmin); - setData(mil[0], false, Ready); - setData(mil[0], false, InGame); - updateIcon(mil[0]); + setData(mi, false, RoomFilterRole); + setData(mi, false, RoomAdmin); + setData(mi, false, Ready); + setData(mi, false, InGame); + updateIcon(mi); } } void PlayersListModel::setFlag(const QString &nickname, StateFlag flagType, bool isSet) { - QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly); + if(flagType == Friend) + { + if(isSet) + m_friendsSet.insert(nickname.toLower()); + else + m_friendsSet.remove(nickname.toLower()); - if(mil.size()) + saveSet(m_friendsSet, "friends"); + } + else if(flagType == Ignore) { - setData(mil[0], isSet, flagType); + if(isSet) + m_ignoredSet.insert(nickname.toLower()); + else + m_ignoredSet.remove(nickname.toLower()); + + saveSet(m_ignoredSet, "ignore"); + } + + QModelIndex mi = nicknameIndex(nickname); + + if(mi.isValid()) + { + setData(mi, isSet, flagType); if(flagType == Friend || flagType == ServerAdmin || flagType == Ignore || flagType == RoomAdmin) - updateSortData(mil[0]); - - if(flagType == Friend) - { - if(isSet) - m_friendsSet.insert(nickname.toLower()); - else - m_friendsSet.remove(nickname.toLower()); - - saveSet(m_friendsSet, "friends"); - } + updateSortData(mi); - if(flagType == Ignore) - { - if(isSet) - m_ignoredSet.insert(nickname.toLower()); - else - m_ignoredSet.remove(nickname.toLower()); - - saveSet(m_ignoredSet, "ignore"); - } - - updateIcon(mil[0]); + updateIcon(mi); } } bool PlayersListModel::isFlagSet(const QString & nickname, StateFlag flagType) { - QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly); + QModelIndex mi = nicknameIndex(nickname); - if(mil.size()) - return mil[0].data(flagType).toBool(); + if(mi.isValid()) + return mi.data(flagType).toBool(); + else if(flagType == Friend) + return isFriend(nickname); + else if(flagType == Ignore) + return isIgnored(nickname); else return false; } @@ -344,11 +356,20 @@ checkFriendIgnore(index(i)); } +bool PlayersListModel::isFriend(const QString & nickname) +{ + return m_friendsSet.contains(nickname.toLower()); +} + +bool PlayersListModel::isIgnored(const QString & nickname) +{ + return m_ignoredSet.contains(nickname.toLower()); +} void PlayersListModel::checkFriendIgnore(const QModelIndex &mi) { - setData(mi, m_friendsSet.contains(mi.data().toString().toLower()), Friend); - setData(mi, m_ignoredSet.contains(mi.data().toString().toLower()), Ignore); + setData(mi, isFriend(mi.data().toString()), Friend); + setData(mi, isIgnored(mi.data().toString()), Ignore); updateIcon(mi); updateSortData(mi); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/playerslistmodel.h --- a/QTfrontend/model/playerslistmodel.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/playerslistmodel.h Sat Jan 04 23:55:54 2014 +0400 @@ -43,6 +43,8 @@ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + QModelIndex nicknameIndex(const QString & nickname); + public slots: void addPlayer(const QString & nickname, bool notify); void removePlayer(const QString & nickname, const QString & msg = QString()); @@ -71,6 +73,8 @@ void loadSet(QSet & set, const QString & suffix); void saveSet(const QSet & set, const QString & suffix); void checkFriendIgnore(const QModelIndex & mi); + bool isFriend(const QString & nickname); + bool isIgnored(const QString & nickname); }; #endif // PLAYERSLISTMODEL_H diff -r 8054d9d775fd -r 2759212a27de QTfrontend/model/roomslistmodel.cpp --- a/QTfrontend/model/roomslistmodel.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/model/roomslistmodel.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -30,7 +30,7 @@ RoomsListModel::RoomsListModel(QObject *parent) : QAbstractTableModel(parent), - c_nColumns(8) + c_nColumns(9) { m_headerData = QStringList() @@ -40,6 +40,7 @@ << tr("T") << tr("Owner") << tr("Map") + << tr("Script") << tr("Rules") << tr("Weapons"); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/net/newnetclient.cpp --- a/QTfrontend/net/newnetclient.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/net/newnetclient.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -94,7 +94,7 @@ NetSocket.disconnectFromHost(); } -void HWNewNet::CreateRoom(const QString & room) +void HWNewNet::CreateRoom(const QString & room, const QString & password) { if(netClientState != InLobby) { @@ -104,11 +104,15 @@ myroom = room; - RawSendNet(QString("CREATE_ROOM%1%2").arg(delimeter).arg(room)); + if(password.isEmpty()) + RawSendNet(QString("CREATE_ROOM%1%2").arg(delimeter).arg(room)); + else + RawSendNet(QString("CREATE_ROOM%1%2%1%3").arg(delimeter).arg(room).arg(password)); + isChief = true; } -void HWNewNet::JoinRoom(const QString & room) +void HWNewNet::JoinRoom(const QString & room, const QString &password) { if(netClientState != InLobby) { @@ -118,7 +122,11 @@ myroom = room; - RawSendNet(QString("JOIN_ROOM%1%2").arg(delimeter).arg(room)); + if(password.isEmpty()) + RawSendNet(QString("JOIN_ROOM%1%2").arg(delimeter).arg(room)); + else + RawSendNet(QString("JOIN_ROOM%1%2%1%3").arg(delimeter).arg(room).arg(password)); + isChief = false; } @@ -303,14 +311,12 @@ if (lst[0] == "ROOMS") { - if(lst.size() % 8 != 1) + if(lst.size() % 9 != 1) { qWarning("Net: Malformed ROOMS message"); return; } - QStringList tmp = lst; - tmp.removeFirst(); - m_roomsListModel->setRoomsList(tmp); + m_roomsListModel->setRoomsList(lst.mid(1)); if (m_private_game == false && m_nick_registered == false) { emit NickNotRegistered(mynick); @@ -398,7 +404,7 @@ return; } - if (lst[0] == "CLIENT_FLAGS") + if (lst[0] == "CLIENT_FLAGS" || lst[0] == "CF") { if(lst.size() < 3 || lst[1].size() < 2) { @@ -519,7 +525,7 @@ return; } - if(lst[0] == "ROOM" && lst.size() == 10 && lst[1] == "ADD") + if(lst[0] == "ROOM" && lst.size() == 11 && lst[1] == "ADD") { QStringList tmp = lst; tmp.removeFirst(); @@ -529,7 +535,7 @@ return; } - if(lst[0] == "ROOM" && lst.size() == 11 && lst[1] == "UPD") + if(lst[0] == "ROOM" && lst.size() == 12 && lst[1] == "UPD") { QStringList tmp = lst; tmp.removeFirst(); @@ -539,7 +545,7 @@ m_roomsListModel->updateRoom(roomName, tmp); // keep track of room name so correct name is displayed - if(myroom == roomName) + if(myroom == roomName && myroom != tmp[1]) { myroom = tmp[1]; emit roomNameUpdated(myroom); @@ -619,15 +625,9 @@ return; } - if (lst[0] == "ADMIN_ACCESS") - { - // obsolete, see +a client flag - return; - } - if(lst[0] == "JOINING") { - if(lst.size() < 2) + if(lst.size() != 2) { qWarning("Net: Bad JOINING message"); return; @@ -635,6 +635,7 @@ myroom = lst[1]; emit roomNameUpdated(myroom); + return; } if(netClientState == InLobby && lst[0] == "JOINED") @@ -810,17 +811,6 @@ m_playersModel->playerLeftRoom(lst[1]); return; } - - // obsolete - if (lst[0] == "ROOM_CONTROL_ACCESS") - { - if (lst.size() < 2) - { - qWarning("Net: Bad ROOM_CONTROL_ACCESS message"); - return; - } - return; - } } qWarning() << "Net: Unknown message or wrong state:" << lst; @@ -1065,10 +1055,11 @@ switch(n) { case 0: - { emit NickTaken(mynick); break; - } + case 2: + emit askForRoomPassword(); + break; } } @@ -1086,3 +1077,9 @@ { return m_roomPlayersModel; } + +void HWNewNet::roomPasswordEntered(const QString &password) +{ + if(!myroom.isEmpty()) + JoinRoom(myroom, password); +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/net/newnetclient.h --- a/QTfrontend/net/newnetclient.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/net/newnetclient.h Sat Jan 04 23:55:54 2014 +0400 @@ -76,6 +76,7 @@ PlayersListModel * m_playersModel; QSortFilterProxyModel * m_lobbyPlayersModel; QSortFilterProxyModel * m_roomPlayersModel; + QString m_lastRoom; QStringList cmdbuf; @@ -103,6 +104,7 @@ void adminAccess(bool); void roomMaster(bool); void roomNameUpdated(const QString & name); + void askForRoomPassword(); void netSchemeConfig(QStringList &); void paramChanged(const QString & param, const QStringList & value); @@ -153,8 +155,8 @@ void setLatestProtocolVar(int proto); void askServerVars(); - void JoinRoom(const QString & room); - void CreateRoom(const QString & room); + void JoinRoom(const QString & room, const QString & password); + void CreateRoom(const QString & room, const QString &password); void updateRoomName(const QString &); void askRoomsList(); void gameFinished(bool correcly); @@ -173,6 +175,7 @@ void removeBan(const QString &); void banIP(const QString & ip, const QString & reason, int seconds); void banNick(const QString & nick, const QString & reason, int seconds); + void roomPasswordEntered(const QString & password); private slots: void ClientRead(); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/net/recorder.cpp --- a/QTfrontend/net/recorder.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/net/recorder.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -143,3 +143,8 @@ return arguments; } + +bool HWRecorder::simultaneousRun() +{ + return true; +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/net/recorder.h --- a/QTfrontend/net/recorder.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/net/recorder.h Sat Jan 04 23:55:54 2014 +0400 @@ -35,6 +35,7 @@ virtual ~HWRecorder(); void EncodeVideo(const QByteArray & record); + bool simultaneousRun(); VideoItem * item; // used by pagevideos QString name; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/net/tcpBase.cpp --- a/QTfrontend/net/tcpBase.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/net/tcpBase.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -80,6 +80,7 @@ QObject(parent), m_hasStarted(false), m_isDemoMode(demoMode), + m_connected(false), IPCSocket(0) { if(!IPCServer) @@ -103,12 +104,23 @@ // connection should be already finished return; } + disconnect(IPCServer, SIGNAL(newConnection()), this, SLOT(NewConnection())); IPCSocket = IPCServer->nextPendingConnection(); + if(!IPCSocket) return; + + m_connected = true; + connect(IPCSocket, SIGNAL(disconnected()), this, SLOT(ClientDisconnect())); connect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead())); SendToClientFirst(); + + if(simultaneousRun()) + { + srvsList.removeOne(this); + emit isReadyNow(); + } } void TCPBase::RealStart() @@ -149,7 +161,8 @@ disconnect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead())); onClientDisconnect(); - emit isReadyNow(); + if(!simultaneousRun()) + emit isReadyNow(); IPCSocket->deleteLater(); deleteLater(); @@ -188,6 +201,7 @@ TCPBase * last = srvsList.last(); if(couldCancelPreviousRequest && last->couldBeRemoved() + && (last->isConnected() || !last->hasStarted()) && (last->parent() == parent())) { srvsList.removeLast(); @@ -195,7 +209,7 @@ Start(couldCancelPreviousRequest); } else { - connect(srvsList.last(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady())); + connect(last, SIGNAL(isReadyNow()), this, SLOT(tcpServerReady())); srvsList.push_back(this); } } @@ -246,3 +260,18 @@ { return false; } + +bool TCPBase::isConnected() +{ + return m_connected; +} + +bool TCPBase::simultaneousRun() +{ + return false; +} + +bool TCPBase::hasStarted() +{ + return m_hasStarted; +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/net/tcpBase.h --- a/QTfrontend/net/tcpBase.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/net/tcpBase.h Sat Jan 04 23:55:54 2014 +0400 @@ -42,6 +42,9 @@ virtual ~TCPBase(); virtual bool couldBeRemoved(); + virtual bool simultaneousRun(); + bool isConnected(); + bool hasStarted(); signals: void isReadyNow(); @@ -69,6 +72,7 @@ static QPointer IPCServer; bool m_isDemoMode; + bool m_connected; void RealStart(); QPointer IPCSocket; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/CampaignDefault.png Binary file QTfrontend/res/CampaignDefault.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/cosmos.png Binary file QTfrontend/res/campaign/A_Space_Adventure/cosmos.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/death01.png Binary file QTfrontend/res/campaign/A_Space_Adventure/death01.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/death02.png Binary file QTfrontend/res/campaign/A_Space_Adventure/death02.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/desert01.png Binary file QTfrontend/res/campaign/A_Space_Adventure/desert01.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/desert02.png Binary file QTfrontend/res/campaign/A_Space_Adventure/desert02.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/desert03.png Binary file QTfrontend/res/campaign/A_Space_Adventure/desert03.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/final.png Binary file QTfrontend/res/campaign/A_Space_Adventure/final.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/fruit01.png Binary file QTfrontend/res/campaign/A_Space_Adventure/fruit01.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/fruit02.png Binary file QTfrontend/res/campaign/A_Space_Adventure/fruit02.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/fruit03.png Binary file QTfrontend/res/campaign/A_Space_Adventure/fruit03.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/ice01.png Binary file QTfrontend/res/campaign/A_Space_Adventure/ice01.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/ice02.png Binary file QTfrontend/res/campaign/A_Space_Adventure/ice02.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/moon01.png Binary file QTfrontend/res/campaign/A_Space_Adventure/moon01.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/campaign/A_Space_Adventure/moon02.png Binary file QTfrontend/res/campaign/A_Space_Adventure/moon02.png has changed diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/css/birthday.css --- a/QTfrontend/res/css/birthday.css Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/res/css/birthday.css Sat Jan 04 23:55:54 2014 +0400 @@ -33,7 +33,7 @@ a { color:#c8c8ff; } QLineEdit, QListWidget, QListView, QTableView, QTextBrowser, QSpinBox, QComboBox, -QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item { +QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item, #labelLikeLineEdit { background-color: rgba(20, 20, 20, 70%); } @@ -44,8 +44,8 @@ QPushButton, QListWidget, QListView, QTableView, QLineEdit, QHeaderView, QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit, QComboBox QAbstractItemView, IconedGroupBox, -.QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget, -QTabWidget::pane, QTabBar::tab { +.QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget, +QTabWidget::pane, QTabBar::tab, #mapPreview, #labelLikeLineEdit { border: solid; border-width: 3px; border-color: #ffcc00; @@ -56,14 +56,30 @@ border-color: yellow; } -QLineEdit, QListWidget, QListView,QTableView, QTextBrowser, -QSpinBox, QToolBox, QPlainTextEdit { +QToolButton { +background-color: #11084A; +} + +QToolButton:hover { +background-color: #150A61; +} + +QToolButton:pressed { +background-color: #100744; +} + +QLineEdit, QListWidget, QListView, QTableView, QTextBrowser, +QSpinBox, QToolBox, QPlainTextEdit, QToolButton, #mapPreview, #labelLikeLineEdit { border-radius: 10px; } +#mapPreview { +background-color: #0d0544; +} + QLineEdit, QLabel, QHeaderView, QListWidget, QListView, QTableView, QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView, -IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, +IconedGroupBox, .QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit { font: bold 13px; } @@ -72,7 +88,7 @@ background-repeat: repeat-x; background-color: #000000; } -.QGroupBox,GameCFGWidget,TeamSelWidget,SelWeaponWidget { +.QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget { background-position: bottom center; background-repeat: repeat-x; border-radius: 16px; @@ -89,6 +105,18 @@ background-color: #130f2c; } +QTabWidget::pane { +border-radius: 8px; +border-top-left-radius: 0px; +} + +QLineEdit:disabled, QSpinBox:disabled { +border-color: gray; +} + +GameCFGWidget { +border: none; +} QPushButton { border-radius: 8px; @@ -97,7 +125,7 @@ background-color: rgba(18, 42, 5, 70%); } -QPushButton:pressed{ +QPushButton:pressed, QToolButton:pressed { border-color: white; } @@ -105,7 +133,6 @@ outline: none; } - QHeaderView { border-radius: 0; border-width: 0; @@ -116,17 +143,18 @@ alternate-background-color: #2f213a; gridline-color: transparent; } - +QTabWidget::pane { top: -2px; } QTabBar::tab { -border-bottom-width: 0; border-radius: 0; border-top-left-radius: 6px; border-top-right-radius: 6px; padding: 3px; +background-color: #00351d; +color: #ffcc00; } -QTabBar::tab:!selected { -color: #0d0544; -background-color: #ffcc00; +QTabBar::tab:selected { +border-bottom-color: #0d0544; +border-bottom-width: 0; } QSpinBox::up-button{ background: transparent; @@ -151,6 +179,7 @@ QComboBox { border-radius: 10px; padding: 3px; +height: 18px; } QComboBox:pressed{ border-color: white; @@ -240,9 +269,66 @@ QSlider::handle::horizontal { border: 0px; -margin: -2px 0px; +margin: -8px 0px; +background-color: #ffcc00; +width: 12px; +height: 6px; border-radius: 3px; -background-color: #ffcc00; -width: 8px; +} + +HatButton, ThemeButton { +text-align: left; +} + +#hatList, #hatList:hover, #themeList, #themeList:hover { +border-color: #F6CB1C; +} + +#hatList QScrollBar, #themeList QScrollBar { +background-color: #130F2A; +border-top-right-radius: 10px; +border-bottom-right-radius: 10px; +} + +#hatList, #themeList { +border-color: #F6CB1C; +border-width: 3px; +border-style: solid; +border-radius: 10px; +border-top-left-radius: 0px; } +#hatList::item, #themeList::item { +background-color: #11084A; +padding: 4px; +border-radius: 10px; +color: #ffcc00 !important; +font: 8px; +border-width: 2px; +border-color: #11084A; +} + +#hatList::item:hover, #themeList::item:hover { +background-color: #150A61; +} + +#hatList::item:selected, #themeList::item:selected { +background-color: #150A61; +} + +QDialogButtonBox QPushButton { +padding: 3px 5px; +} + +#gameCfgWidgetTabs { +border-radius: 16px; +border-top-left-radius: 0px; +} + +TeamSelWidget, #gameStackContainer, #GBoxOptions { +border-radius: 10px; +} + +PageMultiplayer TeamSelWidget { +min-height: 500px; +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/css/chat.css --- a/QTfrontend/res/css/chat.css Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/res/css/chat.css Sat Jan 04 23:55:54 2014 +0400 @@ -9,7 +9,7 @@ * * In the QTfrontend of hedgewars also display:none; will work for class names * that start with msg_ and .timestamp - as long as they are referenced - * directly and not within any class hierachy. + * directly and not within any class hierarchy. * Note: Will only effect new lines! * ****************************************************************************** diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/css/christmas.css --- a/QTfrontend/res/css/christmas.css Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/res/css/christmas.css Sat Jan 04 23:55:54 2014 +0400 @@ -33,7 +33,7 @@ a { color:#c8c8ff; } QLineEdit, QListWidget, QListView, QTableView, QTextBrowser, QSpinBox, QComboBox, -QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item { +QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item, #labelLikeLineEdit { background-color: rgba(13, 5, 68, 70%); } @@ -44,8 +44,8 @@ QPushButton, QListWidget, QListView, QTableView, QLineEdit, QHeaderView, QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit, QComboBox QAbstractItemView, IconedGroupBox, -.QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget, -QTabWidget::pane, QTabBar::tab { +.QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget, +QTabWidget::pane, QTabBar::tab, #mapPreview, #labelLikeLineEdit { border: solid; border-width: 3px; border-color: #ffcc00; @@ -56,14 +56,30 @@ border-color: yellow; } -QLineEdit, QListWidget, QListView,QTableView, QTextBrowser, -QSpinBox, QToolBox, QPlainTextEdit { +QToolButton { +background-color: #11084A; +} + +QToolButton:hover { +background-color: #150A61; +} + +QToolButton:pressed { +background-color: #100744; +} + +QLineEdit, QListWidget, QListView, QTableView, QTextBrowser, +QSpinBox, QToolBox, QPlainTextEdit, QToolButton, #mapPreview, #labelLikeLineEdit { border-radius: 10px; } +#mapPreview { +background-color: #0d0544; +} + QLineEdit, QLabel, QHeaderView, QListWidget, QListView, QTableView, QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView, -IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, +IconedGroupBox, .QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit { font: bold 13px; } @@ -72,7 +88,7 @@ background-repeat: repeat-x; background-color: #000000; } -.QGroupBox,GameCFGWidget,TeamSelWidget,SelWeaponWidget { +.QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget { background-position: bottom center; background-repeat: repeat-x; border-radius: 16px; @@ -89,6 +105,18 @@ background-color: #130f2c; } +QTabWidget::pane { +border-radius: 8px; +border-top-left-radius: 0px; +} + +QLineEdit:disabled, QSpinBox:disabled { +border-color: gray; +} + +GameCFGWidget { +border: none; +} QPushButton { border-radius: 8px; @@ -97,7 +125,7 @@ background-color: rgba(18, 42, 5, 70%); } -QPushButton:pressed{ +QPushButton:pressed, QToolButton:pressed { border-color: white; } @@ -105,7 +133,6 @@ outline: none; } - QHeaderView { border-radius: 0; border-width: 0; @@ -116,17 +143,18 @@ alternate-background-color: #2f213a; gridline-color: transparent; } - +QTabWidget::pane { top: -2px; } QTabBar::tab { -border-bottom-width: 0; border-radius: 0; border-top-left-radius: 6px; border-top-right-radius: 6px; padding: 3px; +background-color: #00351d; +color: #ffcc00; } -QTabBar::tab:!selected { -color: #0d0544; -background-color: #ffcc00; +QTabBar::tab:selected { +border-bottom-color: #0d0544; +border-bottom-width: 0; } QSpinBox::up-button{ background: transparent; @@ -151,6 +179,7 @@ QComboBox { border-radius: 10px; padding: 3px; +height: 18px; } QComboBox:pressed{ border-color: white; @@ -240,9 +269,66 @@ QSlider::handle::horizontal { border: 0px; -margin: -2px 0px; +margin: -8px 0px; +background-color: #ffcc00; +width: 12px; +height: 6px; border-radius: 3px; -background-color: #ffcc00; -width: 8px; +} + +HatButton, ThemeButton { +text-align: left; +} + +#hatList, #hatList:hover, #themeList, #themeList:hover { +border-color: #F6CB1C; +} + +#hatList QScrollBar, #themeList QScrollBar { +background-color: #130F2A; +border-top-right-radius: 10px; +border-bottom-right-radius: 10px; +} + +#hatList, #themeList { +border-color: #F6CB1C; +border-width: 3px; +border-style: solid; +border-radius: 10px; +border-top-left-radius: 0px; } +#hatList::item, #themeList::item { +background-color: #11084A; +padding: 4px; +border-radius: 10px; +color: #ffcc00 !important; +font: 8px; +border-width: 2px; +border-color: #11084A; +} + +#hatList::item:hover, #themeList::item:hover { +background-color: #150A61; +} + +#hatList::item:selected, #themeList::item:selected { +background-color: #150A61; +} + +QDialogButtonBox QPushButton { +padding: 3px 5px; +} + +#gameCfgWidgetTabs { +border-radius: 16px; +border-top-left-radius: 0px; +} + +TeamSelWidget, #gameStackContainer, #GBoxOptions { +border-radius: 10px; +} + +PageMultiplayer TeamSelWidget { +min-height: 500px; +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/res/xml/tips.xml --- a/QTfrontend/res/xml/tips.xml Fri Oct 11 17:43:13 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -# This is not xml actually, but it looks and behaves like it. -# Including an xml library would need too much resources. -# Tips between the platform specific tags are shown only on those platforms. -# Do not escape characters or use the CDATA tag. - - Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together. - Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water. - If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death! - Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground or miss a shot you'll reuse your rope without wasting ammo! - If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/. - You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked. - By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them. - Hedgewars is free software (Open Source) we create in our spare time. If you've got problems, ask on our forums or visit our IRC room! - Hedgewars is free software (Open Source) we create in our spare time. If you like it, help us with a small donation or contribute your own work! - Hedgewars is free software (Open Source) we create in our spare time. Share it with your family and friends as you like! - Hedgewars is free software (Open Source) we create in our spare time, just for fun! Meet the devs in #hedgewars! - From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance. - Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us! - Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and GNU/Linux. - Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option. - Connect one or more gamepads before starting the game to be able to assign their controls to your teams. - Create an account on http://www.hedgewars.org/ to keep others from using your most favourite nickname while playing on the official server. - While playing you should give yourself a short break at least once an hour. - If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance. - If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers. - We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know! - Especially while playing online be polite and always remember there might be some minors playing with or against you as well! - Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game! - You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead! - Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well. - No hedgehogs were harmed in making this game. - There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump. - Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving. - Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once. - Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this. - The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once. - The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well. - The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power. - Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water. - The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground. - If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion. - The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early. - The Flame Thrower is a weapon but it can be used for tunnel digging as well. - Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms. - Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits. - Like Hedgewars? Become a fan on Facebook or follow us on Twitter - Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online. - Keep your video card drivers up to date to avoid issues playing the game. - Heads or tails? Type '/rnd' in lobby and you'll find out. Also '/rnd rock paper scissors' works! - You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser. - - The version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing. - You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand. - - - You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand. - - - lintip - You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand. - - diff -r 8054d9d775fd -r 2759212a27de QTfrontend/team.cpp --- a/QTfrontend/team.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/team.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -276,6 +276,9 @@ sl.push_back(QString("evoicepack " + m_voicepack)); sl.push_back(QString("eflag " + m_flag)); + if(!m_owner.isEmpty()) + sl.push_back(QString("eowner ") + m_owner); + for (int t = 0; t < m_numHedgehogs; t++) { sl.push_back(QString("eaddhh %1 %2 %3") diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/mouseoverfilter.cpp --- a/QTfrontend/ui/mouseoverfilter.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/mouseoverfilter.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -49,8 +49,6 @@ { SDLInteraction::instance().playSoundFile("/Sounds/steps.ogg"); } - - return true; } else if (event->type() == QEvent::Leave) { @@ -63,7 +61,6 @@ else abstractpage->setButtonDescription(""); } - return false; } diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/AbstractPage.cpp --- a/QTfrontend/ui/page/AbstractPage.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/AbstractPage.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -67,7 +67,7 @@ descLabel->setAlignment(Qt::AlignCenter); descLabel->setWordWrap(true); descLabel->setOpenExternalLinks(true); - descLabel->setFixedHeight(50); + descLabel->setFixedHeight(60); descLabel->setStyleSheet("font-size: 16px"); bottomLeftLayout->addWidget(descLabel); pageLayout->addWidget(descLabel, 1, 1); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagedata.cpp --- a/QTfrontend/ui/page/pagedata.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagedata.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -26,6 +26,7 @@ #include #include #include +#include #include "pagedata.h" #include "databrowser.h" @@ -48,10 +49,23 @@ return pageLayout; } +QLayout * PageDataDownload::footerLayoutDefinition() +{ + QHBoxLayout * bottomLayout = new QHBoxLayout(); + bottomLayout->setStretch(0, 1); + + pbOpenDir = addButton(tr("Open packages directory"), bottomLayout, 1, false); + + bottomLayout->setStretch(2, 1); + + return bottomLayout; +} + void PageDataDownload::connectSignals() { connect(web, SIGNAL(anchorClicked(QUrl)), this, SLOT(request(const QUrl&))); connect(this, SIGNAL(goBack()), this, SLOT(onPageLeave())); + connect(pbOpenDir, SIGNAL(clicked()), this, SLOT(openPackagesDir())); } PageDataDownload::PageDataDownload(QWidget* parent) : AbstractPage(parent) @@ -193,3 +207,9 @@ //DataManager::instance().reload(); } } + +void PageDataDownload::openPackagesDir() +{ + QString path = QDir::toNativeSeparators(cfgdir->absolutePath() + "/Data"); + QDesktopServices::openUrl(QUrl("file:///" + path)); +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagedata.h --- a/QTfrontend/ui/page/pagedata.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagedata.h Sat Jan 04 23:55:54 2014 +0400 @@ -27,6 +27,7 @@ class QNetworkReply; class QVBoxLayout; + class PageDataDownload : public AbstractPage { Q_OBJECT @@ -39,12 +40,14 @@ protected: QLayout * bodyLayoutDefinition(); + QLayout * footerLayoutDefinition(); void connectSignals(); private: DataBrowser *web; QHash progressBars; QVBoxLayout *progressBarsLayout; + QPushButtonWithSound * pbOpenDir; bool m_contentDownloaded; ///< true if something was downloaded since last page leave @@ -54,6 +57,7 @@ void pageDownloaded(); void fileDownloaded(); void downloadProgress(qint64, qint64); + void openPackagesDir(); void onPageLeave(); }; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagedrawmap.cpp --- a/QTfrontend/ui/page/pagedrawmap.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagedrawmap.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -20,6 +20,7 @@ #include #include #include +#include #include "pagedrawmap.h" #include "drawmapwidget.h" @@ -32,12 +33,22 @@ cbEraser = new QCheckBox(tr("Eraser"), this); pageLayout->addWidget(cbEraser, 0, 0); pbUndo = addButton(tr("Undo"), pageLayout, 1, 0); - pbClear = addButton(tr("Clear"), pageLayout, 2, 0); - pbLoad = addButton(tr("Load"), pageLayout, 3, 0); - pbSave = addButton(tr("Save"), pageLayout, 4, 0); + + rbPolyline = new QRadioButton(tr("Polyline"), this); + pageLayout->addWidget(rbPolyline, 2, 0); + rbRectangle = new QRadioButton(tr("Rectangle"), this); + pageLayout->addWidget(rbRectangle, 3, 0); + rbEllipse = new QRadioButton(tr("Ellipse"), this); + pageLayout->addWidget(rbEllipse, 4, 0); + + rbPolyline->setChecked(true); + + pbClear = addButton(tr("Clear"), pageLayout, 5, 0); + pbLoad = addButton(tr("Load"), pageLayout, 6, 0); + pbSave = addButton(tr("Save"), pageLayout, 7, 0); drawMapWidget = new DrawMapWidget(this); - pageLayout->addWidget(drawMapWidget, 0, 1, 6, 1); + pageLayout->addWidget(drawMapWidget, 0, 1, 9, 1); return pageLayout; } @@ -49,6 +60,10 @@ connect(pbClear, SIGNAL(clicked()), drawMapWidget, SLOT(clear())); connect(pbLoad, SIGNAL(clicked()), this, SLOT(load())); connect(pbSave, SIGNAL(clicked()), this, SLOT(save())); + + connect(rbPolyline, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool))); + connect(rbRectangle, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool))); + connect(rbEllipse, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool))); } PageDrawMap::PageDrawMap(QWidget* parent) : AbstractPage(parent) @@ -71,3 +86,13 @@ if(!fileName.isEmpty()) drawMapWidget->save(fileName); } + +void PageDrawMap::pathTypeSwitched(bool b) +{ + if(b) + { + if(rbPolyline->isChecked()) drawMapWidget->setPathType(DrawMapScene::Polyline); + else if(rbRectangle->isChecked()) drawMapWidget->setPathType(DrawMapScene::Rectangle); + else if(rbEllipse->isChecked()) drawMapWidget->setPathType(DrawMapScene::Ellipse); + } +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagedrawmap.h --- a/QTfrontend/ui/page/pagedrawmap.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagedrawmap.h Sat Jan 04 23:55:54 2014 +0400 @@ -22,6 +22,7 @@ #include "AbstractPage.h" class DrawMapWidget; +class QRadioButton; class PageDrawMap : public AbstractPage { @@ -42,10 +43,14 @@ QPushButton * pbLoad; QPushButton * pbSave; QCheckBox * cbEraser; + QRadioButton * rbPolyline; + QRadioButton * rbRectangle; + QRadioButton * rbEllipse; private slots: void load(); void save(); + void pathTypeSwitched(bool b); }; #endif diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pageeditteam.cpp --- a/QTfrontend/ui/page/pageeditteam.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pageeditteam.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -211,7 +211,12 @@ { if(m_loaded) return; m_loaded = true; - qDebug("[LAZYNESS] PageEditTeam::lazyLoad()"); + qDebug("[LAZINESS] PageEditTeam::lazyLoad()"); + + HatModel * hatsModel = DataManager::instance().hatModel(); + for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++) + HHHats[i]->setModel(hatsModel); + QRegExp pngSuffix("\\.png$"); DataManager & dataMgr = DataManager::instance(); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagemain.cpp --- a/QTfrontend/ui/page/pagemain.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagemain.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -21,10 +21,12 @@ #include #include #include +#include #include "pagemain.h" #include "hwconsts.h" #include "hwform.h" +#include "DataManager.h" QLayout * PageMain::bodyLayoutDefinition() { @@ -119,6 +121,9 @@ void PageMain::connectSignals() { +#ifndef QT_DEBUG + connect(this, SIGNAL(pageEnter()), this, SLOT(updateTip())); +#endif connect(BtnNet, SIGNAL(clicked()), this, SLOT(toggleNetworkChoice())); //connect(BtnNetLocal, SIGNAL(clicked()), this, SLOT(toggleNetworkChoice())); //connect(BtnNetOfficial, SIGNAL(clicked()), this, SLOT(toggleNetworkChoice())); @@ -132,16 +137,19 @@ if(frontendEffects) setAttribute(Qt::WA_NoSystemBackground, true); mainNote->setOpenExternalLinks(true); - #ifdef QT_DEBUG setDefaultDescription(QLabel::tr("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!")); #else setDefaultDescription(QLabel::tr("Tip: %1").arg(randomTip())); #endif - } -QString PageMain::randomTip() const +void PageMain::updateTip() +{ + setDefaultDescription(QLabel::tr("Tip: %1").arg(randomTip())); +} + +QString PageMain::randomTip() { #ifdef _WIN32 int platform = 1; @@ -150,35 +158,62 @@ #else int platform = 3; #endif - QStringList Tips; - QFile file(":/res/xml/tips.xml"); - file.open(QIODevice::ReadOnly); - QTextStream in(&file); - QString line = in.readLine(); - int tip_platform = 0; - while (!line.isNull()) { - if(line.contains("", Qt::CaseSensitive)) - tip_platform = 1; - if(line.contains("", Qt::CaseSensitive)) - tip_platform = 2; - if(line.contains("", Qt::CaseSensitive)) - tip_platform = 3; - if(line.contains("", Qt::CaseSensitive) || - line.contains("", Qt::CaseSensitive) || - line.contains("", Qt::CaseSensitive)) { - tip_platform = 0; + if(!Tips.length()) + { + DataManager & dataMgr = DataManager::instance(); + + // get locale + QSettings settings(dataMgr.settingsFileName(), + QSettings::IniFormat); + + QString loc = settings.value("misc/locale", "").toString(); + if (loc.isEmpty()) + loc = QLocale::system().name(); + + QString tipFile = QString("physfs://Locale/tips_" + loc + ".xml"); + + // if file is non-existant try with language only + if (!QFile::exists(tipFile)) + tipFile = QString("physfs://Locale/tips_" + loc.remove(QRegExp("_.*$")) + ".xml"); + + // fallback if file for current locale is non-existant + if (!QFile::exists(tipFile)) + tipFile = QString("physfs://Locale/tips_en.xml"); + + QFile file(tipFile); + file.open(QIODevice::ReadOnly); + QTextStream in(&file); + in.setCodec("UTF-8"); + QString line = in.readLine(); + int tip_platform = 0; + while (!line.isNull()) { + if(line.contains("", Qt::CaseSensitive)) + tip_platform = 1; + if(line.contains("", Qt::CaseSensitive)) + tip_platform = 2; + if(line.contains("", Qt::CaseSensitive)) + tip_platform = 3; + if(line.contains("", Qt::CaseSensitive) || + line.contains("", Qt::CaseSensitive) || + line.contains("", Qt::CaseSensitive)) { + tip_platform = 0; + } + QStringList split_string = line.split(QRegExp("")); + if((tip_platform == platform || tip_platform == 0) && split_string.size() != 1) + Tips << split_string[1]; + line = in.readLine(); } - QStringList split_string = line.split(QRegExp("")); - if((tip_platform == platform || tip_platform == 0) && split_string.size() != 1) - Tips << tr(split_string[1].toLatin1().data(), "Tips"); - line = in.readLine(); + // The following tip will require links to app store entries first. + //Tips << tr("Want to play Hedgewars any time? Grab the Mobile version for %1 and %2.", "Tips").arg("").arg(""); + // the ios version is located here: http://itunes.apple.com/us/app/hedgewars/id391234866 + + file.close(); } - // The following tip will require links to app store entries first. - //Tips << tr("Want to play Hedgewars any time? Grab the Mobile version for %1 and %2.", "Tips").arg("").arg(""); - // the ios version is located here: http://itunes.apple.com/us/app/hedgewars/id391234866 - - file.close(); - return Tips[QTime(0, 0, 0).secsTo(QTime::currentTime()) % Tips.length()]; + + if(Tips.length()) + return Tips[QTime(0, 0, 0).secsTo(QTime::currentTime()) % Tips.length()]; + else + return QString(); } void PageMain::toggleNetworkChoice() diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagemain.h --- a/QTfrontend/ui/page/pagemain.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagemain.h Sat Jan 04 23:55:54 2014 +0400 @@ -48,10 +48,12 @@ void connectSignals(); QIcon originalNetworkIcon, disabledNetworkIcon; - QString randomTip() const; + QString randomTip(); + QStringList Tips; private slots: void toggleNetworkChoice(); + void updateTip(); }; #endif diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pageroomslist.cpp --- a/QTfrontend/ui/page/pageroomslist.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pageroomslist.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -169,47 +169,11 @@ stateMenu->addAction(showGamesInProgress); btnState->setMenu(stateMenu); - // Rules dropdown - - CBRules = new QComboBox(this); - CBRules->setStyleSheet("QComboBox { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left-width: 2px; }"); - - QLabel * ruleLabel = new QLabel(tr("Rules:"), this); - ruleLabel->setFixedHeight(CBRules->height()); - ruleLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - ruleLabel->setStyleSheet("border: solid; border-width: 3px; border-right-width: 0px; border-color: #ffcc00; border-top-left-radius: 10px; border-bottom-left-radius: 10px; background-color: rgba(13, 5, 68, 70%);"); - - filterLayout->addWidget(ruleLabel); - filterLayout->addWidget(CBRules); - filterLayout->addSpacing(filterSpacing); - - // Weapons dropdown - - CBWeapons = new QComboBox(this); - CBWeapons->setStyleSheet("QComboBox { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left-width: 2px; }"); - - QLabel * weaponLabel = new QLabel(tr("Weapons:"), this); - weaponLabel->setFixedHeight(CBWeapons->height()); - weaponLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - weaponLabel->setStyleSheet("border: solid; border-width: 3px; border-right-width: 0px; border-color: #ffcc00; border-top-left-radius: 10px; border-bottom-left-radius: 10px; background-color: rgba(13, 5, 68, 70%);"); - - filterLayout->addWidget(weaponLabel); - filterLayout->addWidget(CBWeapons); - filterLayout->addSpacing(filterSpacing); - - // Clear filters button - - BtnClear = addButton(tr("Clear filters"), filterLayout, 0); - weaponLabel->setFixedHeight(CBWeapons->height()); - BtnClear->setStyleSheet("padding: 4px;"); - // Lobby chat chatWidget = new HWChatWidget(this, false); m_splitter->addWidget(chatWidget); - CBRules->addItem(QComboBox::tr("Any")); - return pageLayout; } @@ -230,7 +194,6 @@ connect(BtnCreate, SIGNAL(clicked()), this, SLOT(onCreateClick())); connect(BtnJoin, SIGNAL(clicked()), this, SLOT(onJoinClick())); - connect(BtnClear, SIGNAL(clicked()), this, SLOT(onClearClick())); connect(searchText, SIGNAL(moveUp()), this, SLOT(moveSelectionUp())); connect(searchText, SIGNAL(moveDown()), this, SLOT(moveSelectionDown())); connect(searchText, SIGNAL(returnPressed()), this, SLOT(onJoinClick())); @@ -238,8 +201,6 @@ connect(roomsList, SIGNAL(clicked (const QModelIndex &)), searchText, SLOT(setFocus())); connect(showGamesInLobby, SIGNAL(triggered()), this, SLOT(onFilterChanged())); connect(showGamesInProgress, SIGNAL(triggered()), this, SLOT(onFilterChanged())); - connect(CBRules, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged())); - connect(CBWeapons, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged())); connect(searchText, SIGNAL(textChanged (const QString &)), this, SLOT(onFilterChanged())); connect(this, SIGNAL(askJoinConfirmation (const QString &)), this, SLOT(onJoinConfirmation(const QString &)), Qt::QueuedConnection); @@ -273,22 +234,8 @@ { roomsModel = NULL; stateFilteredModel = NULL; - schemeFilteredModel = NULL; - weaponsFilteredModel = NULL; initPage(); - - // not the most elegant solution but it works - ammoSchemeModel = new AmmoSchemeModel(this, NULL); - for (int i = 0; i < ammoSchemeModel->predefSchemesNames.count(); i++) - CBRules->addItem(ammoSchemeModel->predefSchemesNames.at(i).toAscii().constData()); - - CBWeapons->addItem(QComboBox::tr("Any")); - for (int i = 0; i < cDefaultAmmos.count(); i++) - { - QPair ammo = cDefaultAmmos.at(i); - CBWeapons->addItem(ammo.first.toAscii().constData()); - } } @@ -531,17 +478,17 @@ void PageRoomsList::onCreateClick() { - RoomNamePrompt prompt(parentWidget()->parentWidget(), m_gameSettings->value("frontend/lastroomname", QString()).toString()); - connect(&prompt, SIGNAL(roomNameChosen(const QString &)), this, SLOT(onRoomNameChosen(const QString &))); - prompt.exec(); + RoomNamePrompt prompt(this, m_gameSettings->value("frontend/lastroomname", QString()).toString()); + if(prompt.exec()) + onRoomNameChosen(prompt.getRoomName(), prompt.getPassword()); } -void PageRoomsList::onRoomNameChosen(const QString & roomName) +void PageRoomsList::onRoomNameChosen(const QString & roomName, const QString & password) { if (!roomName.trimmed().isEmpty()) { m_gameSettings->setValue("frontend/lastroomname", roomName); - emit askForCreateRoom(roomName); + emit askForCreateRoom(roomName, password); } else { @@ -570,7 +517,7 @@ if (!gameInLobby) emit askJoinConfirmation(roomName); else - emit askForJoinRoom(roomName); + emit askForJoinRoom(roomName, QString()); } void PageRoomsList::onRefreshClick() @@ -578,16 +525,6 @@ emit askForRoomList(); } -void PageRoomsList::onClearClick() -{ - showGamesInLobby->setChecked(true); - showGamesInProgress->setChecked(true); - CBRules->setCurrentIndex(0); - CBWeapons->setCurrentIndex(0); - searchText->clear(); - searchText->setFocus(); -} - void PageRoomsList::onJoinConfirmation(const QString & room) { @@ -600,7 +537,7 @@ if (reallyJoinMsg.exec() == QMessageBox::Ok) { - emit askForJoinRoom(room); + emit askForJoinRoom(room, QString()); } } @@ -628,25 +565,15 @@ roomsModel->sort(RoomsListModel::StateColumn, Qt::AscendingOrder); stateFilteredModel = new QSortFilterProxyModel(this); - schemeFilteredModel = new QSortFilterProxyModel(this); - weaponsFilteredModel = new QSortFilterProxyModel(this); stateFilteredModel->setDynamicSortFilter(true); - schemeFilteredModel->setDynamicSortFilter(true); - weaponsFilteredModel->setDynamicSortFilter(true); roomsModel->setFilterKeyColumn(-1); // search in all columns stateFilteredModel->setFilterKeyColumn(RoomsListModel::StateColumn); - schemeFilteredModel->setFilterKeyColumn(RoomsListModel::SchemeColumn); - weaponsFilteredModel->setFilterKeyColumn(RoomsListModel::WeaponsColumn); roomsModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - schemeFilteredModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - weaponsFilteredModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - schemeFilteredModel->setSourceModel(stateFilteredModel); - weaponsFilteredModel->setSourceModel(schemeFilteredModel); - roomsModel->setSourceModel(weaponsFilteredModel); + roomsModel->setSourceModel(stateFilteredModel); // let the table view display the last model in the filter chain roomsList->setModel(roomsModel); @@ -660,8 +587,6 @@ stateFilteredModel->setSourceModel(model); - roomsList->hideColumn(RoomsListModel::StateColumn); - QHeaderView * h = roomsList->horizontalHeader(); h->setSortIndicatorShown(true); @@ -678,6 +603,8 @@ h->resizeSection(RoomsListModel::WeaponsColumn, 100); } + // hide column used for filtering + roomsList->hideColumn(RoomsListModel::StateColumn); // save header state on change connect(roomsList->horizontalHeader(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), @@ -714,29 +641,17 @@ if (roomsModel == NULL) return; - roomsModel->setFilterWildcard(QString("*%1*").arg(searchText->text())); + roomsModel->setFilterFixedString(searchText->text()); bool stateLobby = showGamesInLobby->isChecked(); bool stateProgress = showGamesInProgress->isChecked(); if (stateLobby && stateProgress) - stateFilteredModel->setFilterWildcard("*"); // "any" + stateFilteredModel->setFilterFixedString(QString()); // "any" else if (stateLobby != stateProgress) stateFilteredModel->setFilterFixedString(QString(stateProgress)); else stateFilteredModel->setFilterFixedString(QString("none")); // Basically, none. - - if (CBRules->currentIndex() == 0) - schemeFilteredModel->setFilterWildcard("*"); // "any" - else - schemeFilteredModel->setFilterWildcard( - QString("*%1*").arg(CBRules->currentText())); - - if (CBWeapons->currentIndex() == 0) - weaponsFilteredModel->setFilterWildcard("*"); // "any" - else - weaponsFilteredModel->setFilterWildcard( - QString("*%1*").arg(CBWeapons->currentText())); } void PageRoomsList::setSettings(QSettings *settings) diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pageroomslist.h --- a/QTfrontend/ui/page/pageroomslist.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pageroomslist.h Sat Jan 04 23:55:54 2014 +0400 @@ -55,10 +55,7 @@ QPushButton * BtnCreate; QPushButton * BtnJoin; QPushButton * BtnAdmin; - QPushButton * BtnClear; QComboBox * CBState; - QComboBox * CBRules; - QComboBox * CBWeapons; HWChatWidget * chatWidget; QLabel * lblCount; @@ -70,8 +67,8 @@ void updateNickCounter(int cnt); signals: - void askForCreateRoom(const QString &); - void askForJoinRoom(const QString &); + void askForCreateRoom(const QString &, const QString &); + void askForJoinRoom(const QString &, const QString &); void askForRoomList(); void askJoinConfirmation(const QString &); @@ -84,12 +81,11 @@ void onCreateClick(); void onJoinClick(); void onRefreshClick(); - void onClearClick(); void onJoinConfirmation(const QString &); void onSortIndicatorChanged(int logicalIndex, Qt::SortOrder order); void onFilterChanged(); void saveHeaderState(); - void onRoomNameChosen(const QString &); + void onRoomNameChosen(const QString &, const QString &password); void roomSelectionChanged(const QModelIndex &, const QModelIndex &); void moveSelectionUp(); void moveSelectionDown(); @@ -98,8 +94,6 @@ QSettings * m_gameSettings; QSortFilterProxyModel * roomsModel; QSortFilterProxyModel * stateFilteredModel; - QSortFilterProxyModel * schemeFilteredModel; - QSortFilterProxyModel * weaponsFilteredModel; QAction * showGamesInLobby; QAction * showGamesInProgress; QSplitter * m_splitter; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagescheme.cpp --- a/QTfrontend/ui/page/pagescheme.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagescheme.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -390,6 +390,7 @@ l->setFixedSize(32,32); l->setPixmap(QPixmap(":/res/iconEarth.png")); glBSLayout->addWidget(l,15,1,1,1); + CB_WorldEdge = new QComboBox(gbBasicSettings); CB_WorldEdge->insertItem(0, tr("None (Default)")); CB_WorldEdge->insertItem(1, tr("Wrap (World wraps)")); @@ -400,6 +401,20 @@ l = new QLabel(gbBasicSettings); + l->setText(QLabel::tr("Script parameter")); + l->setWordWrap(true); + glBSLayout->addWidget(l,16,0,1,1); + l = new QLabel(gbBasicSettings); + l->setFixedSize(32,32); + l->setPixmap(QPixmap(":/res/iconBox.png")); + glBSLayout->addWidget(l,16,1,1,1); + + LE_ScriptParam = new QLineEdit(gbBasicSettings); + LE_ScriptParam->setMaxLength(240); + glBSLayout->addWidget(LE_ScriptParam,16,2,1,1); + + + l = new QLabel(gbBasicSettings); l->setText(QLabel::tr("Scheme Name:")); LE_name = new QLineEdit(this); @@ -489,6 +504,7 @@ mapper->addMapping(SB_RopeModifier, 39); mapper->addMapping(SB_GetAwayTime, 40); mapper->addMapping(CB_WorldEdge, 41, "currentIndex"); + mapper->addMapping(LE_ScriptParam, 42); mapper->toFirst(); } diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/page/pagescheme.h --- a/QTfrontend/ui/page/pagescheme.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/page/pagescheme.h Sat Jan 04 23:55:54 2014 +0400 @@ -93,6 +93,7 @@ QSpinBox * SB_GetAwayTime; QComboBox * CB_WorldEdge; QLineEdit * LE_name; + QLineEdit * LE_ScriptParam; QGroupBox * gbGameModes; QGroupBox * gbBasicSettings; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/about.cpp diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/chatwidget.cpp --- a/QTfrontend/ui/widget/chatwidget.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/chatwidget.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -861,6 +861,8 @@ else nick = m_clickedNick; + bool isOnline = (mil.size() > 0); + QSortFilterProxyModel * playersSortFilterModel = qobject_cast(chatNicks->model()); if(!playersSortFilterModel) return; @@ -871,8 +873,11 @@ return; bool isSelf = (nick == m_userNick); + bool isInRoom = players->isFlagSet(nick, PlayersListModel::InRoom); - acFollow->setVisible(!isSelf); + acFollow->setVisible(!isSelf && isInRoom); + + acInfo->setVisible(isOnline); // update context menu labels according to possible action if(players->isFlagSet(nick, PlayersListModel::Ignore)) @@ -901,7 +906,7 @@ if (m_isAdmin) { - acKick->setVisible(!isSelf); + acKick->setVisible(!isSelf && isOnline); acBan->setVisible(!isSelf); } diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/drawmapwidget.cpp --- a/QTfrontend/ui/widget/drawmapwidget.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/drawmapwidget.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -123,6 +123,11 @@ if(m_scene) m_scene->setErasing(erasing); } +void DrawMapWidget::setPathType(DrawMapScene::PathType pathType) +{ + if(m_scene) m_scene->setPathType(pathType); +} + void DrawMapWidget::save(const QString & fileName) { if(m_scene) @@ -192,7 +197,7 @@ QGraphicsView::setScene(scene); } -// Why don't I ever recieve this event? +// Why don't I ever receive this event? void DrawMapView::enterEvent(QEvent *event) { if(m_scene) diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/drawmapwidget.h --- a/QTfrontend/ui/widget/drawmapwidget.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/drawmapwidget.h Sat Jan 04 23:55:54 2014 +0400 @@ -100,6 +100,7 @@ void setErasing(bool erasing); void save(const QString & fileName); void load(const QString & fileName); + void setPathType(DrawMapScene::PathType pathType); protected: void changeEvent(QEvent *e); diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/feedbackdialog.cpp --- a/QTfrontend/ui/widget/feedbackdialog.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/feedbackdialog.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -283,7 +283,7 @@ delete process; #endif -#if (!defined(Q_OS_MAC) && defined(__i386__)) || defined(__x86_64__) +#if (defined(Q_OS_WIN) && defined(__i386__)) || defined(__x86_64__) // cpu info quint32 registers[4]; quint32 i; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/gamecfgwidget.cpp --- a/QTfrontend/ui/widget/gamecfgwidget.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/gamecfgwidget.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -324,7 +324,8 @@ bcfg << QString("e$worldedge %1").arg(schemeData(41).toInt()).toUtf8(); bcfg << QString("e$template_filter %1").arg(pMapContainer->getTemplateFilter()).toUtf8(); bcfg << QString("e$mapgen %1").arg(mapgen).toUtf8(); - + if(!schemeData(42).isNull()) + bcfg << QString("e$scriptparam %1").arg(schemeData(42).toString()).toUtf8(); switch (mapgen) @@ -390,7 +391,10 @@ seedChanged(pMapContainer->getCurrentSeed()); templateFilterChanged(pMapContainer->getTemplateFilter()); - themeChanged(pMapContainer->getCurrentTheme()); + + QString t = pMapContainer->getCurrentTheme(); + if(!t.isEmpty()) + themeChanged(t); schemeChanged(GameSchemes->currentIndex()); scriptChanged(Scripts->currentIndex()); @@ -566,7 +570,11 @@ for(int i = 0; i < size; ++i) sl << schemeData(i).toString(); - if (sl.size()!=1) emit paramChanged("SCHEME", sl); // this is a stupid hack for the fact that SCHEME is being sent once, empty. Still need to find out why. + if (sl.size() >= 42) + { + sl[42].prepend('!'); + emit paramChanged("SCHEME", sl); // this is a stupid hack for the fact that SCHEME is being sent once, empty. Still need to find out why. + } if (isEnabled() && bindEntries->isEnabled() && bindEntries->isChecked()) { diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/hatbutton.cpp --- a/QTfrontend/ui/widget/hatbutton.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/hatbutton.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -19,7 +19,6 @@ #include #include "hatprompt.h" -#include "DataManager.h" #include "HatModel.h" #include "hatbutton.h" @@ -28,8 +27,13 @@ setIconSize(QSize(32, 37)); setFixedSize(44, 44); - m_hatModel = DataManager::instance().hatModel(); + m_hatModel = 0; connect(this, SIGNAL(clicked()), this, SLOT(showPrompt())); +} + +void HatButton::setModel(HatModel *model) +{ + m_hatModel = model; setCurrentIndex(0); } diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/hatbutton.h --- a/QTfrontend/ui/widget/hatbutton.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/hatbutton.h Sat Jan 04 23:55:54 2014 +0400 @@ -35,6 +35,7 @@ HatButton(QWidget* parent); int currentIndex(); QString currentHat() const; + void setModel(HatModel * model); private: QModelIndex m_hat; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/mapContainer.cpp --- a/QTfrontend/ui/widget/mapContainer.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/mapContainer.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -55,6 +55,11 @@ mapgen(MAPGEN_REGULAR), m_previewSize(256, 128) { + // don't show preview anything until first show event + m_previewEnabled = false; + m_missionsViewSetup = false; + m_staticViewSetup = false; + hhSmall.load(":/res/hh_small.png"); hhLimit = 18; templateFilter = 0; @@ -158,28 +163,14 @@ /* Static maps list */ staticMapList = new QListView; - staticMapList->setModel(m_staticMapModel); rightLayout->addWidget(staticMapList, 1); - staticMapList->setEditTriggers(QAbstractItemView::NoEditTriggers); m_childWidgets << staticMapList; - QItemSelectionModel * staticSelectionModel = staticMapList->selectionModel(); - connect(staticSelectionModel, - SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), - this, - SLOT(staticMapChanged(const QModelIndex &, const QModelIndex &))); /* Mission maps list */ - missionMapList = new QListView; - missionMapList->setModel(m_missionMapModel); - missionMapList->setEditTriggers(QAbstractItemView::NoEditTriggers); + missionMapList = new QListView(this); rightLayout->addWidget(missionMapList, 1); m_childWidgets << missionMapList; - QItemSelectionModel * missionSelectionModel = missionMapList->selectionModel(); - connect(missionSelectionModel, - SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), - this, - SLOT(missionMapChanged(const QModelIndex &, const QModelIndex &))); /* Map load and edit buttons */ @@ -261,7 +252,6 @@ staticMapChanged(m_staticMapModel->index(0, 0)); missionMapChanged(m_missionMapModel->index(0, 0)); changeMapType(MapModel::GeneratedMap); - setRandomTheme(); } void HWMapContainer::setImage(const QImage newImage) @@ -608,8 +598,22 @@ updatePreview(); } +void HWMapContainer::showEvent(QShowEvent * event) +{ + if (!m_previewEnabled) { + m_previewEnabled = true; + setRandomTheme(); + updatePreview(); + } + QWidget::showEvent(event); +} + void HWMapContainer::updatePreview() { + // abort if the widget isn't supposed to show anything yet + if (!m_previewEnabled) + return; + if (pMap) { disconnect(pMap, 0, this, SLOT(setImage(const QImage))); @@ -726,6 +730,7 @@ btnEditMap->show(); break; case MapModel::MissionMap: + setupMissionMapsView(); mapgen = MAPGEN_MAP; missionMapChanged(newMap.isValid() ? newMap : missionMapList->currentIndex()); lblMapList->setText(tr("Mission:")); @@ -736,6 +741,7 @@ emit mapChanged(m_curMap); break; case MapModel::StaticMap: + setupStaticMapsView(); mapgen = MAPGEN_MAP; staticMapChanged(newMap.isValid() ? newMap : staticMapList->currentIndex()); lblMapList->setText(tr("Map:")); @@ -935,3 +941,35 @@ btnTheme->setIcon(QIcon()); btnTheme->setText(tr("Theme: %1").arg(name)); } + +void HWMapContainer::setupMissionMapsView() +{ + if(m_missionsViewSetup) return; + m_missionsViewSetup = true; + + m_missionMapModel->loadMaps(); + missionMapList->setModel(m_missionMapModel); + missionMapList->setEditTriggers(QAbstractItemView::NoEditTriggers); + QItemSelectionModel * missionSelectionModel = missionMapList->selectionModel(); + connect(missionSelectionModel, + SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), + this, + SLOT(missionMapChanged(const QModelIndex &, const QModelIndex &))); + missionSelectionModel->setCurrentIndex(m_missionMapModel->index(0, 0), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); +} + +void HWMapContainer::setupStaticMapsView() +{ + if(m_staticViewSetup) return; + m_staticViewSetup = true; + + m_staticMapModel->loadMaps(); + staticMapList->setModel(m_staticMapModel); + staticMapList->setEditTriggers(QAbstractItemView::NoEditTriggers); + QItemSelectionModel * staticSelectionModel = staticMapList->selectionModel(); + connect(staticSelectionModel, + SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), + this, + SLOT(staticMapChanged(const QModelIndex &, const QModelIndex &))); + staticSelectionModel->setCurrentIndex(m_staticMapModel->index(0, 0), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/mapContainer.h --- a/QTfrontend/ui/widget/mapContainer.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/mapContainer.h Sat Jan 04 23:55:54 2014 +0400 @@ -111,6 +111,7 @@ protected: virtual void resizeEvent ( QResizeEvent * event ); + virtual void showEvent ( QShowEvent * event ); private: QVBoxLayout mainLayout; @@ -149,6 +150,9 @@ QPushButton * btnSeed; bool m_master; QList m_childWidgets; + bool m_previewEnabled; + bool m_missionsViewSetup; + bool m_staticViewSetup; void intSetSeed(const QString & seed); void intSetMap(const QString & map); @@ -161,6 +165,8 @@ void changeMapType(MapModel::MapType type, const QModelIndex & newMap = QModelIndex()); void updatePreview(); void updateThemeButtonSize(); + void setupMissionMapsView(); + void setupStaticMapsView(); MapModel::MapInfo m_mapInfo; int m_themeID; diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/roomnameprompt.cpp --- a/QTfrontend/ui/widget/roomnameprompt.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/roomnameprompt.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -23,6 +23,7 @@ #include #include #include +#include #include "roomnameprompt.h" @@ -32,24 +33,34 @@ setWindowFlags(Qt::Sheet); setWindowModality(Qt::WindowModal); setMinimumSize(360, 130); - resize(360, 130); + resize(360, 180); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); // Layout QVBoxLayout * dialogLayout = new QVBoxLayout(this); // Label - label = new QLabel(tr("Enter a name for your room.")); + label = new QLabel(tr("Enter a name for your room."), this); label->setWordWrap(true); - dialogLayout->addWidget(label, 0); + dialogLayout->addWidget(label); // Input box - editBox = new QLineEdit(); - editBox->setText(roomName); - editBox->setMaxLength(59); // It didn't like 60 :( - editBox->setStyleSheet("QLineEdit { padding: 3px; }"); - editBox->selectAll(); - dialogLayout->addWidget(editBox, 1); + leRoomName = new QLineEdit(this); + leRoomName->setText(roomName); + leRoomName->setMaxLength(59); // It didn't like 60 :( + leRoomName->setStyleSheet("QLineEdit { padding: 3px; }"); + leRoomName->selectAll(); + dialogLayout->addWidget(leRoomName); + + cbSetPassword = new QCheckBox(this); + cbSetPassword->setText(tr("set password")); + dialogLayout->addWidget(cbSetPassword); + + lePassword = new QLineEdit(this); + lePassword->setMaxLength(30); + lePassword->setStyleSheet("QLineEdit { padding: 3px; }"); + lePassword->setEnabled(false); + dialogLayout->addWidget(lePassword); dialogLayout->addStretch(1); @@ -73,10 +84,20 @@ setStyleSheet("QPushButton { padding: 5px; }"); - connect(btnOkay, SIGNAL(clicked()), this, SLOT(setRoomName())); + connect(cbSetPassword, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled())); +} + +QString RoomNamePrompt::getRoomName() +{ + return leRoomName->text(); } -void RoomNamePrompt::setRoomName() +QString RoomNamePrompt::getPassword() { - emit roomNameChosen(editBox->text()); + return lePassword->text(); } + +void RoomNamePrompt::checkBoxToggled() +{ + lePassword->setEnabled(cbSetPassword->isChecked()); +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/roomnameprompt.h --- a/QTfrontend/ui/widget/roomnameprompt.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/roomnameprompt.h Sat Jan 04 23:55:54 2014 +0400 @@ -23,6 +23,7 @@ class QLineEdit; class QLabel; +class QCheckBox; class RoomNamePrompt : public QDialog { @@ -30,16 +31,17 @@ public: RoomNamePrompt(QWidget* parent, const QString & roomName); + QString getRoomName(); + QString getPassword(); - signals: - void roomNameChosen(const QString & roomName); + private: + QLineEdit * leRoomName; + QLabel * label; + QCheckBox * cbSetPassword; + QLineEdit * lePassword; private slots: - void setRoomName(); - - private: - QLineEdit * editBox; - QLabel * label; + void checkBoxToggled(); }; #endif // ROOMNAMEPROMPT_H diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/selectWeapon.cpp --- a/QTfrontend/ui/widget/selectWeapon.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/selectWeapon.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -93,7 +93,7 @@ for(int i = 0; i < keys.size(); i++) { if (wconf->value(keys[i]).toString().size() != cDefaultAmmoStore->size()) - wconf->remove(keys[i]); + wconf->setValue(keys[i], fixWeaponSet(wconf->value(keys[i]).toString())); } QString currentState = *cDefaultAmmoStore; @@ -333,3 +333,22 @@ setWeapons(ammo); } } + +QString SelWeaponWidget::fixWeaponSet(const QString &s) +{ + int neededLength = cDefaultAmmoStore->size() / 4; + int thisSetLength = s.size() / 4; + + QStringList sl; + sl + << s.left(thisSetLength) + << s.mid(thisSetLength, thisSetLength) + << s.mid(thisSetLength * 2, thisSetLength) + << s.right(thisSetLength) + ; + + for(int i = sl.length() - 1; i >= 0; --i) + sl[i] = sl[i].leftJustified(neededLength, '0', true); + + return sl.join(QString()); +} diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/selectWeapon.h --- a/QTfrontend/ui/widget/selectWeapon.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/selectWeapon.h Sat Jan 04 23:55:54 2014 +0400 @@ -87,6 +87,8 @@ QGridLayout* p2Layout; QGridLayout* p3Layout; QGridLayout* p4Layout; + + QString fixWeaponSet(const QString & s); }; #endif // _SELECT_WEAPON_INCLUDED diff -r 8054d9d775fd -r 2759212a27de QTfrontend/ui/widget/teamselhelper.cpp --- a/QTfrontend/ui/widget/teamselhelper.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/ui/widget/teamselhelper.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -55,7 +55,7 @@ butt = new QPushButton(difficultyIcon, team.name().replace("&","&&"), this); butt->setFlat(true); - butt->setWhatsThis(tr("%1's team").arg(team.owner())); + butt->setToolTip(team.owner()); mainLayout.addWidget(butt); butt->setStyleSheet("QPushButton{" "icon-size: 48px;" diff -r 8054d9d775fd -r 2759212a27de QTfrontend/util/DataManager.cpp --- a/QTfrontend/util/DataManager.cpp Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/util/DataManager.cpp Sat Jan 04 23:55:54 2014 +0400 @@ -98,8 +98,7 @@ MapModel * DataManager::staticMapModel() { if (m_staticMapModel == NULL) { - m_staticMapModel = new MapModel(); - m_staticMapModel->loadMaps(MapModel::StaticMap); + m_staticMapModel = new MapModel(MapModel::StaticMap, this); } return m_staticMapModel; } @@ -107,8 +106,7 @@ MapModel * DataManager::missionMapModel() { if (m_missionMapModel == NULL) { - m_missionMapModel = new MapModel(); - m_missionMapModel->loadMaps(MapModel::MissionMap); + m_missionMapModel = new MapModel(MapModel::MissionMap, this); } return m_missionMapModel; } @@ -117,7 +115,6 @@ { if (m_themeModel == NULL) { m_themeModel = new ThemeModel(); - m_themeModel->loadThemes(); } return m_themeModel; } diff -r 8054d9d775fd -r 2759212a27de QTfrontend/weapons.h --- a/QTfrontend/weapons.h Fri Oct 11 17:43:13 2013 +0200 +++ b/QTfrontend/weapons.h Sat Jan 04 23:55:54 2014 +0400 @@ -21,45 +21,46 @@ //skip---------------------------------| //structure------------------------------------------------------------------| -#define AMMOLINE_DEFAULT_QT "9391929422199121032235111001201000000211110101011111121" -#define AMMOLINE_DEFAULT_PROB "0405040541600655546554464776576666666155510101115411121" -#define AMMOLINE_DEFAULT_DELAY "0000000000000205500000040007004000000000220000000600020" -#define AMMOLINE_DEFAULT_CRATE "1311110312111111123114111111111111111211111101111111121" -#define AMMOLINE_CRAZY_QT "9999999999999999992999999999999999299999999909999992999" -#define AMMOLINE_CRAZY_PROB "1111110111111111111111111111111111111111111101111111111" -#define AMMOLINE_CRAZY_DELAY "0000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_CRAZY_CRATE "1311110312111111123114111111111111111211110101111111121" +#define AMMOLINE_DEFAULT_QT "93919294221991210322351110012000000002111001010111110001" +#define AMMOLINE_DEFAULT_PROB "04050405416006555465544647765766666661555101011154111111" +#define AMMOLINE_DEFAULT_DELAY "00000000000002055000000400070040000000002200000006000200" +#define AMMOLINE_DEFAULT_CRATE "13111103121111111231141111111111111112111111011111111111" -#define AMMOLINE_PROMODE_QT "9090009000000000000009000000000000000000000000000000000" -#define AMMOLINE_PROMODE_PROB "0000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_PROMODE_DELAY "0000000000000205500000040007004000000000200000000000020" -#define AMMOLINE_PROMODE_CRATE "1111110111111111111111111111111111111111100101111111121" +#define AMMOLINE_CRAZY_QT "99999999999999999929999999999999992999999999099999929991" +#define AMMOLINE_CRAZY_PROB "11111101111111111111111111111111111111111111011111111111" +#define AMMOLINE_CRAZY_DELAY "00000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_CRAZY_CRATE "13111103121111111231141111111111111112111101011111111111" -#define AMMOLINE_SHOPPA_QT "0000009900000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPA_PROB "4444410044244402210112121222422000000002000400010011001" -#define AMMOLINE_SHOPPA_DELAY "0000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPA_CRATE "1111110111111111111111111111111111111111101101111111121" +#define AMMOLINE_PROMODE_QT "90900090000000000000090000000000000000000000000000000000" +#define AMMOLINE_PROMODE_PROB "00000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_PROMODE_DELAY "00000000000002055000000400070040000000002000000000000200" +#define AMMOLINE_PROMODE_CRATE "11111101111111111111111111111111111111111001011111111111" -#define AMMOLINE_CLEAN_QT "1010009000010000011000000000000000000000000000001000000" -#define AMMOLINE_CLEAN_PROB "0405040541600655546554464776576666666155510101115411121" -#define AMMOLINE_CLEAN_DELAY "0000000000000000000000000000000000000000000000000000020" -#define AMMOLINE_CLEAN_CRATE "1311110312111111123114111111111111111211111101111111121" +#define AMMOLINE_SHOPPA_QT "00000099000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPA_PROB "44444100442444022101121212224220000000020004000100110010" +#define AMMOLINE_SHOPPA_DELAY "00000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPA_CRATE "11111101111111111111111111111111111111111011011111111110" -#define AMMOLINE_MINES_QT "0000009900090000000300000000000000000000000000000000000" -#define AMMOLINE_MINES_PROB "0000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_MINES_DELAY "0000000000000205500000040007004000000000200000000600020" -#define AMMOLINE_MINES_CRATE "1111110111111111111111111111111111111111111101111111121" +#define AMMOLINE_CLEAN_QT "10100090000100000110000000000000000000000000000010000000" +#define AMMOLINE_CLEAN_PROB "04050405416006555465544647765766666661555101011154111211" +#define AMMOLINE_CLEAN_DELAY "00000000000000000000000000000000000000000000000000000200" +#define AMMOLINE_CLEAN_CRATE "13111103121111111231141111111111111112111111011111111111" -#define AMMOLINE_PORTALS_QT "9000009002000000002100000000000000110000090000000000000" -#define AMMOLINE_PORTALS_PROB "0405040541600655546554464776576666666155510101115411121" -#define AMMOLINE_PORTALS_DELAY "0000000000000205500000040007004000000000200000000600020" -#define AMMOLINE_PORTALS_CRATE "1311110312111111123114111111111111111211111101111111121" +#define AMMOLINE_MINES_QT "00000099000900000003000000000000000000000000000000000000" +#define AMMOLINE_MINES_PROB "00000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_MINES_DELAY "00000000000002055000000400070040000000002000000006000200" +#define AMMOLINE_MINES_CRATE "11111101111111111111111111111111111111111111011111111111" -#define AMMOLINE_ONEEVERY_QT "1111119111111111111111111111111111111111111111111111111" -#define AMMOLINE_ONEEVERY_PROB "1111110111111111111111111111111111111111111111111111111" -#define AMMOLINE_ONEEVERY_DELAY "0000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_ONEEVERY_CRATE "1111110111111111111111111111111111111111111111111111111" +#define AMMOLINE_PORTALS_QT "90000090020000000021000000000000001100000900000000000000" +#define AMMOLINE_PORTALS_PROB "04050405416006555465544647765766666661555101011154111211" +#define AMMOLINE_PORTALS_DELAY "00000000000002055000000400070040000000002000000006000200" +#define AMMOLINE_PORTALS_CRATE "13111103121111111231141111111111111112111111011111111111" + +#define AMMOLINE_ONEEVERY_QT "11111191111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_PROB "11111101111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_DELAY "00000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_ONEEVERY_CRATE "11111101111111111111111111111111111111111111111111111111" //When adding new weapons also insert one element in cDefaultAmmos list (hwconsts.cpp.in) diff -r 8054d9d775fd -r 2759212a27de cmake_modules/CMakePascalInformation.cmake --- a/cmake_modules/CMakePascalInformation.cmake Fri Oct 11 17:43:13 2013 +0200 +++ b/cmake_modules/CMakePascalInformation.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -9,9 +9,9 @@ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL) # This section should actually be in Platform/${CMAKE_SYSTME_NAME}-fpc.cmake -set(CMAKE_Pascal_FLAGS_DEBUG_INIT "-g -gl -gp -gh") +set(CMAKE_Pascal_FLAGS_DEBUG_INIT "-O- -g -gl -gp -gh") set(CMAKE_Pascal_FLAGS_MINSIZEREL_INIT "-Os -dNDEBUG") -set(CMAKE_Pascal_FLAGS_RELEASE_INIT "-O3 -dNDEBUG") +set(CMAKE_Pascal_FLAGS_RELEASE_INIT "-O2 -dNDEBUG") set(CMAKE_Pascal_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -gl -gp") # This should be included before the _INIT variables are diff -r 8054d9d775fd -r 2759212a27de cmake_modules/FindSDL1or2.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmake_modules/FindSDL1or2.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,24 @@ +find_package(SDL QUIET) + +if(NOT SDL_FOUND) + find_package(SDL2 REQUIRED) + set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIR}) + set(SDL_LIBRARY ${SDL2_LIBRARY}) +endif() + +if(NOT SDL_VERSION) + #find which version of SDL we have + find_file(sdlversion_h SDL_version.h ${SDL_INCLUDE_DIR}) + if(sdlversion_h) + file(STRINGS ${sdlversion_h} sdl_majorversion_tmp REGEX "SDL_MAJOR_VERSION[\t' ']+[0-9]+") + file(STRINGS ${sdlversion_h} sdl_minorversion_tmp REGEX "SDL_MINOR_VERSION[\t' ']+[0-9]+") + file(STRINGS ${sdlversion_h} sdl_patchversion_tmp REGEX "SDL_PATCHLEVEL[\t' ']+[0-9]+") + string(REGEX MATCH "([0-9]+)" sdl_majorversion "${sdl_majorversion_tmp}") + string(REGEX MATCH "([0-9]+)" sdl_minorversion "${sdl_minorversion_tmp}") + string(REGEX MATCH "([0-9]+)" sdl_patchversion "${sdl_patchversion_tmp}") + set(SDL_VERSION "${sdl_majorversion}.${sdl_minorversion}.${sdl_patchversion}") + endif() +endif() + +mark_as_advanced(sdlversion_h sdl_majorversion sdl_minorversion sdl_patchversion) + diff -r 8054d9d775fd -r 2759212a27de cmake_modules/FindSDL2.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmake_modules/FindSDL2.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,164 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDLmain.h and SDLmain.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +SET(SDL2_SEARCH_PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS ${SDL2_SEARCH_PATHS} +) + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} +) + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) + diff -r 8054d9d775fd -r 2759212a27de cmake_modules/TargetArch.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmake_modules/TargetArch.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,142 @@ +# Original file location https://github.com/petroules/solar-cmake/blob/master/TargetArch.cmake +#Copyright (c) 2012 Petroules Corporation. All rights reserved. +#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +# +# 1 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +# 2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# Based on the Qt 5 processor detection code, so should be very accurate +# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h +# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64) + +# Regarding POWER/PowerPC, just as is noted in the Qt source, +# "There are many more known variants/revisions that we do not handle/detect." + +set(archdetect_c_code " +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) + #if defined(__ARM_ARCH_7__) \\ + || defined(__ARM_ARCH_7A__) \\ + || defined(__ARM_ARCH_7R__) \\ + || defined(__ARM_ARCH_7M__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7) + #error cmake_ARCH armv7 + #elif defined(__ARM_ARCH_6__) \\ + || defined(__ARM_ARCH_6J__) \\ + || defined(__ARM_ARCH_6T2__) \\ + || defined(__ARM_ARCH_6Z__) \\ + || defined(__ARM_ARCH_6K__) \\ + || defined(__ARM_ARCH_6ZK__) \\ + || defined(__ARM_ARCH_6M__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6) + #error cmake_ARCH armv6 + #elif defined(__ARM_ARCH_5TEJ__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5) + #error cmake_ARCH armv5 + #else + #error cmake_ARCH arm + #endif +#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) + #error cmake_ARCH i386 +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) + #error cmake_ARCH x86_64 +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + #error cmake_ARCH ia64 +#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\ + || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\ + || defined(_M_MPPC) || defined(_M_PPC) + #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) + #error cmake_ARCH ppc64 + #else + #error cmake_ARCH ppc + #endif +#endif + +#error cmake_ARCH unknown +") + +# Set ppc_support to TRUE before including this file or ppc and ppc64 +# will be treated as invalid architectures since they are no longer supported by Apple + +function(target_architecture output_var) + if(APPLE AND CMAKE_OSX_ARCHITECTURES) + # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set + # First let's normalize the order of the values + + # Note that it's not possible to compile PowerPC applications if you are using + # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we + # disable it by default + # See this page for more information: + # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4 + + # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime. + # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise. + + foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES}) + if("${osx_arch}" STREQUAL "ppc" AND ppc_support) + set(osx_arch_ppc TRUE) + elseif("${osx_arch}" STREQUAL "i386") + set(osx_arch_i386 TRUE) + elseif("${osx_arch}" STREQUAL "x86_64") + set(osx_arch_x86_64 TRUE) + elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support) + set(osx_arch_ppc64 TRUE) + else() + message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}") + endif() + endforeach() + + # Now add all the architectures in our normalized order + if(osx_arch_ppc) + list(APPEND ARCH ppc) + endif() + + if(osx_arch_i386) + list(APPEND ARCH i386) + endif() + + if(osx_arch_x86_64) + list(APPEND ARCH x86_64) + endif() + + if(osx_arch_ppc64) + list(APPEND ARCH ppc64) + endif() + else() + file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}") + + enable_language(C) + + # Detect the architecture in a rather creative way... + # This compiles a small C program which is a series of ifdefs that selects a + # particular #error preprocessor directive whose message string contains the + # target architecture. The program will always fail to compile (both because + # file is not a valid C program, and obviously because of the presence of the + # #error preprocessor directives... but by exploiting the preprocessor in this + # way, we can detect the correct target architecture even when cross-compiling, + # since the program itself never needs to be run (only the compiler/preprocessor) + try_run( + run_result_unused + compile_result_unused + "${CMAKE_BINARY_DIR}" + "${CMAKE_BINARY_DIR}/arch.c" + COMPILE_OUTPUT_VARIABLE ARCH + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + ) + + # Parse the architecture name from the compiler output + string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}") + + # Get rid of the value marker leaving just the architecture name + string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}") + + # If we are compiling with an unknown architecture this variable should + # already be set to "unknown" but in the case that it's empty (i.e. due + # to a typo in the code), then set it to unknown + if (NOT ARCH) + set(ARCH unknown) + endif() + endif() + + set(${output_var} "${ARCH}" PARENT_SCOPE) +endfunction() diff -r 8054d9d775fd -r 2759212a27de cmake_modules/cpackvars.cmake --- a/cmake_modules/cpackvars.cmake Fri Oct 11 17:43:13 2013 +0200 +++ b/cmake_modules/cpackvars.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -89,6 +89,8 @@ # "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/cmdlineClient" "^${CMAKE_CURRENT_SOURCE_DIR}/misc/winutils/bin" "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/promotional_art" + "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/AudioMono" + "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/HedgewarsMobile" "^${CMAKE_CURRENT_SOURCE_DIR}/tools/templates" "^${CMAKE_CURRENT_SOURCE_DIR}/tools/drawMapTest" "^${CMAKE_CURRENT_SOURCE_DIR}/doc" diff -r 8054d9d775fd -r 2759212a27de cmake_modules/paths.cmake --- a/cmake_modules/paths.cmake Fri Oct 11 17:43:13 2013 +0200 +++ b/cmake_modules/paths.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -14,8 +14,8 @@ #resource paths if(UNIX AND NOT APPLE) - set(target_binary_install_dir "bin") - set(target_library_install_dir "lib") + set(target_binary_install_dir "bin" CACHE PATH "install dest for binaries") + set(target_library_install_dir "lib" CACHE PATH "install dest for libs") string(SUBSTRING "${DATA_INSTALL_DIR}" 0 1 sharepath_start) if (NOT (${sharepath_start} MATCHES "/")) @@ -55,31 +55,16 @@ #which point to directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) -#paths where to find libraries (final slash not optional): -# - the first is relative to the executable -# - the second is the same directory of the executable (so it runs in bin/) -# - the third one is the full path of the system dir -#source http://www.cmake.org/pipermail/cmake/2008-January/019290.html -set(CMAKE_INSTALL_RPATH "$ORIGIN/../${target_library_install_dir}/:$ORIGIN/:${CMAKE_INSTALL_PREFIX}/${target_library_install_dir}/") -#\\\\ is just \\ which escapes '\' in the final script; same for $$ which escapes '$' in cmake -set(CMAKE_INSTALL_RPATH_ESCAPED "\\\\$$ORIGIN/../${target_library_install_dir}/:\\\\$$ORIGIN/:${CMAKE_INSTALL_PREFIX}/${target_library_install_dir}/") - -if(UNIX AND NOT APPLE) - if(CMAKE_COMPILER_IS_GNUCC) - #make sure $ORIGIN is respected - add_linker_flag("-zorigin") - endif() - #apply RPATH settings to pascal executables - add_flag_append(CMAKE_Pascal_FLAGS "-k-rpath -k'${CMAKE_INSTALL_RPATH_ESCAPED}'") - #until we link with external things there is no need to set rpath on haskell - #list(APPEND haskell_flags "-optl" "-Wl,-rpath,'${CMAKE_INSTALL_RPATH_ESCAPED}'") -endif() - -#add the automatically determined parts of the RPATH -#which point to directories outside the build tree to the install RPATH -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) - - -#install_name_tool magic for OS X -set(CMAKE_INSTALL_NAME_DIR "@executable_path/../Frameworks") - +if(APPLE) + #@rpath mangling + set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks") + #install_name_tool for libraries + set(CMAKE_INSTALL_NAME_DIR "@executable_path/../Frameworks") +else(APPLE) + #paths where to find libraries (final slash not optional): + # - the first is relative to the executable + # - the second is the same directory of the executable (so it runs in bin/) + # - the third one is the full path of the system dir + #source http://www.cmake.org/pipermail/cmake/2008-January/019290.html + set(CMAKE_INSTALL_RPATH "$ORIGIN/../${target_library_install_dir}/:$ORIGIN/:${CMAKE_INSTALL_PREFIX}/${target_library_install_dir}/") +endif(APPLE) diff -r 8054d9d775fd -r 2759212a27de cmake_modules/platform.cmake --- a/cmake_modules/platform.cmake Fri Oct 11 17:43:13 2013 +0200 +++ b/cmake_modules/platform.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -31,24 +31,15 @@ set(minimum_macosx_version ${current_macosx_version}) endif() - #lower systems don't have enough processing power anyway - if (minimum_macosx_version VERSION_LESS "10.4") - message(FATAL_ERROR "Hedgewars is not supported on Mac OS X pre-10.4") - endif() - - #workaround for http://playcontrol.net/ewing/jibberjabber/big_behind-the-scenes_chang.html#SDL_mixer (Update 2) - if(current_macosx_version VERSION_EQUAL "10.4") - find_package(SDL_mixer REQUIRED) - set(DYLIB_SMPEG "-dylib_file @loader_path/Frameworks/smpeg.framework/Versions/A/smpeg:${SDLMIXER_LIBRARY}/Versions/A/Frameworks/smpeg.framework/Versions/A/smpeg") - set(DYLIB_MIKMOD "-dylib_file @loader_path/Frameworks/mikmod.framework/Versions/A/mikmod:${SDLMIXER_LIBRARY}/Versions/A/Frameworks/mikmod.framework/Versions/A/mikmod") - add_flag_append(CMAKE_C_FLAGS "${DYLIB_SMPEG} ${DYLIB_MIKMOD}") - add_flag_append(CMAKE_CXX_FLAGS "${DYLIB_SMPEG} ${DYLIB_MIKMOD}") - add_flag_append(CMAKE_Pascal_FLAGS "-k${DYLIB_SMPEG} -k${DYLIB_MIKMOD}") + #10.3 systems don't have enough processing power anyway + #10.4 does not have @rpath support (which SDL uses) + if(minimum_macosx_version VERSION_LESS "10.5") + message(FATAL_ERROR "Hedgewars is not supported on your version of Mac OS X") endif() if(NOT CMAKE_OSX_ARCHITECTURES) if(current_macosx_version VERSION_LESS "10.6") - #SDL is only 32 bit on lower OS + #SDL is only 32 bit on older OS version if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "powerpc*") set(CMAKE_OSX_ARCHITECTURES "ppc7400") else() @@ -73,7 +64,7 @@ endif() list(LENGTH CMAKE_OSX_ARCHITECTURES num_of_archs) if(num_of_archs GREATER 1) - message(${WARNING} "Only one architecture in CMAKE_OSX_ARCHITECTURES is currently supported, picking the first one") + message("*** Only one architecture in CMAKE_OSX_ARCHITECTURES is supported, picking the first one ***") endif() elseif(CMAKE_SIZEOF_VOID_P MATCHES "8") #if that variable is not set check if we are on x86_64 and if so force it, else use default @@ -82,21 +73,36 @@ #CMAKE_OSX_SYSROOT is set at the system version we are supposed to build on #we need to provide the correct one when host and target differ - if(NOT ${minimum_macosx_version} VERSION_EQUAL ${current_macosx_version}) - if(minimum_macosx_version VERSION_EQUAL "10.4") - set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.4u.sdk/") - set(CMAKE_C_COMPILER "/Developer/usr/bin/gcc-4.0") - set(CMAKE_CXX_COMPILER "/Developer/usr/bin/g++-4.0") + if(NOT CMAKE_OSX_SYSROOT AND + NOT ${minimum_macosx_version} VERSION_EQUAL ${current_macosx_version}) + find_program(xcrun xcrun) + if(xcrun) + execute_process(COMMAND ${xcrun} "--show-sdk-path" + OUTPUT_VARIABLE current_sdk_path + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE "${current_macosx_version}" + "${minimum_macosx_version}" + CMAKE_OSX_SYSROOT + "${current_sdk_path}") else() - string(REGEX REPLACE "([0-9]+.[0-9]+).[0-9]+" "\\1" sdk_version ${minimum_macosx_version}) - set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX${sdk_version}.sdk/") + message("*** xcrun not found! Build will work on ${current_macosx_version} only ***") endif() + endif() + if(CMAKE_OSX_SYSROOT) add_flag_append(CMAKE_Pascal_FLAGS "-XR${CMAKE_OSX_SYSROOT}") add_flag_append(CMAKE_Pascal_FLAGS "-k-macosx_version_min -k${minimum_macosx_version}") + add_flag_append(CMAKE_Pascal_FLAGS "-k-L${LIBRARY_OUTPUT_PATH} -Fl${LIBRARY_OUTPUT_PATH}") endif() #add user framework directory add_flag_append(CMAKE_Pascal_FLAGS "-Ff~/Library/Frameworks") + + #workaround older cmake versions + if(${CMAKE_VERSION} VERSION_LESS "2.8.12") + add_flag_append(CMAKE_C_LINK_FLAGS "-Wl,-rpath -Wl,${CMAKE_INSTALL_RPATH}") + add_flag_append(CMAKE_CXX_LINK_FLAGS "-Wl,-rpath -Wl,${CMAKE_INSTALL_RPATH}") + add_flag_append(CMAKE_Pascal_LINK_FLAGS "-k-rpath -k${CMAKE_INSTALL_RPATH}") + endif() endif(APPLE) if(MINGW) @@ -110,3 +116,8 @@ message(FATAL_ERROR "Static linking is not supported on Windows") endif() endif(WIN32) + +if(UNIX) + add_flag_append(CMAKE_C_FLAGS "-fPIC") + add_flag_append(CMAKE_CXX_FLAGS "-fPIC") +endif(UNIX) diff -r 8054d9d775fd -r 2759212a27de cmake_modules/revinfo.cmake --- a/cmake_modules/revinfo.cmake Fri Oct 11 17:43:13 2013 +0200 +++ b/cmake_modules/revinfo.cmake Sat Jan 04 23:55:54 2014 +0400 @@ -1,11 +1,12 @@ #detect Mercurial revision and init rev/hash information find_program(HGCOMMAND hg) -if(HGCOMMAND AND (EXISTS ${CMAKE_SOURCE_DIR}/.hg)) +find_program(GITCOMMAND git) +if(EXISTS ${CMAKE_SOURCE_DIR}/.hg AND HGCOMMAND) execute_process(COMMAND ${HGCOMMAND} identify -in WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE internal_version - ERROR_QUIET - ) + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE + ) #check local repo status string(REGEX REPLACE "[^+]" "" HGCHANGED ${internal_version}) string(REGEX REPLACE "[0-9a-zA-Z]+(.*) ([0-9]+)(.*)" "\\2" HEDGEWARS_REVISION ${internal_version}) @@ -14,8 +15,23 @@ if(HGCHANGED) message("*** You have uncommitted changes in your repository ***") endif() + #let's assume that if you have hg you might be interested in debugging set(default_build_type "DEBUG") + + #write down hash and rev for easy picking should hg be missing + file(WRITE "${CMAKE_SOURCE_DIR}/share/version_info.txt" "Hedgewars versioning information, do not modify\nrev ${HEDGEWARS_REVISION}\nhash ${HEDGEWARS_HASH}\n") +elseif(EXISTS ${CMAKE_SOURCE_DIR}/.git AND GITCOMMAND) + execute_process(COMMAND ${GITCOMMAND} rev-parse --short HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE HEDGEWARS_HASH + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(HEDGEWARS_REVISION "GIT") + + #let's assume that if you have git you might be interested in debugging + set(default_build_type "DEBUG") + #write down hash and rev for easy picking should hg be missing file(WRITE "${CMAKE_SOURCE_DIR}/share/version_info.txt" "Hedgewars versioning information, do not modify\nrev ${HEDGEWARS_REVISION}\nhash ${HEDGEWARS_HASH}\n") else() @@ -24,7 +40,7 @@ find_file(version_info version_info.txt PATH ${CMAKE_SOURCE_DIR}/share) if(version_info) file(STRINGS ${version_info} internal_version REGEX "rev") - string(REGEX REPLACE "rev ([0-9]*)" "\\1" HEDGEWARS_REVISION ${internal_version}) + string(REGEX REPLACE "rev ([GIT0-9]*)" "\\1" HEDGEWARS_REVISION ${internal_version}) file(STRINGS ${version_info} internal_version REGEX "hash") string(REGEX REPLACE "hash ([a-zA-Z0-9]*)" "\\1" HEDGEWARS_HASH ${internal_version}) else() diff -r 8054d9d775fd -r 2759212a27de gameServer/Actions.hs --- a/gameServer/Actions.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/Actions.hs Sat Jan 04 23:55:54 2014 +0400 @@ -21,6 +21,7 @@ import System.Process import Network.Socket import System.Random +import qualified Data.Traversable as DT ----------------------------- #if defined(OFFICIAL_SERVER) import OfficialServer.GameReplayStore @@ -187,13 +188,14 @@ ri <- clientRoomA rnc <- gets roomsClients playersNum <- io $ room'sM rnc playersIn ri + specialRoom <- io $ room'sM rnc isSpecial ri master <- client's isMaster -- client <- client's id clNick <- client's nick chans <- othersChans if master then - if playersNum > 1 then + if (playersNum > 1) || specialRoom then mapM_ processAction [ChangeMaster Nothing, NoticeMessage AdminLeft, RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]] else processAction RemoveRoom @@ -205,7 +207,7 @@ -- when not removing room ready <- client's isReady - when (not master || playersNum > 1) . io $ do + when (not master || playersNum > 1 || specialRoom) . io $ do modifyRoom rnc (\r -> r{ playersIn = playersIn r - 1, readyPlayers = if ready then readyPlayers r - 1 else readyPlayers r @@ -218,31 +220,40 @@ proto <- client's clientProto ri <- clientRoomA rnc <- gets roomsClients - newMasterId <- liftM (\ids -> fromMaybe (last . filter (/= ci) $ ids) delegateId) . io $ roomClientsIndicesM rnc ri - newMaster <- io $ client'sM rnc id newMasterId + specialRoom <- io $ room'sM rnc isSpecial ri + newMasterId <- liftM (\ids -> fromMaybe (listToMaybe . reverse . filter (/= ci) $ ids) $ liftM Just delegateId) . io $ roomClientsIndicesM rnc ri + newMaster <- io $ client'sM rnc id `DT.mapM` newMasterId oldMasterId <- io $ room'sM rnc masterID ri - oldMaster <- io $ client'sM rnc id oldMasterId oldRoomName <- io $ room'sM rnc name ri kicked <- client's isKickedFromServer thisRoomChans <- liftM (map sendChan) $ roomClientsS ri - let newRoomName = if (proto < 42) || kicked then nick newMaster else oldRoomName - mapM_ processAction [ + let newRoomName = if ((proto < 42) || kicked) && (not specialRoom) then maybeNick newMaster else oldRoomName + + when (isJust oldMasterId) $ do + oldMasterNick <- io $ client'sM rnc nick (fromJust oldMasterId) + mapM_ processAction [ + ModifyClient2 (fromJust oldMasterId) (\c -> c{isMaster = False}) + , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", oldMasterNick] + ] + + when (isJust newMasterId) $ + mapM_ processAction [ + ModifyClient2 (fromJust newMasterId) (\c -> c{isMaster = True}) + , AnswerClients [sendChan $ fromJust newMaster] ["ROOM_CONTROL_ACCESS", "1"] + , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+h", nick $ fromJust newMaster] + ] + + processAction $ ModifyRoom (\r -> r{masterID = newMasterId , name = newRoomName , isRestrictedJoins = False , isRestrictedTeams = False - , isRegisteredOnly = False} + , isRegisteredOnly = isSpecial r} ) - , ModifyClient2 newMasterId (\c -> c{isMaster = True}) - , ModifyClient2 oldMasterId (\c -> c{isMaster = False}) - , AnswerClients [sendChan newMaster] ["ROOM_CONTROL_ACCESS", "1"] - , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", nick oldMaster] - , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+h", nick newMaster] - ] newRoom' <- io $ room'sM rnc id ri chans <- liftM (map sendChan) $! sameProtoClientsS proto - processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo (nick newMaster) newRoom') + processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo proto (maybeNick newMaster) newRoom') processAction (AddRoom roomName roomPassword) = do @@ -252,7 +263,7 @@ n <- client's nick let rm = newRoom{ - masterID = clId, + masterID = Just clId, name = roomName, password = roomPassword, roomProto = proto @@ -265,7 +276,7 @@ chans <- liftM (map sendChan) $! sameProtoClientsS proto mapM_ processAction [ - AnswerClients chans ("ROOM" : "ADD" : roomInfo n rm{playersIn = 1}) + AnswerClients chans ("ROOM" : "ADD" : roomInfo proto n rm{playersIn = 1}) ] @@ -292,9 +303,9 @@ rnc <- gets roomsClients ri <- io $ clientRoomM rnc clId rm <- io $ room'sM rnc id ri - n <- io $ client'sM rnc nick (masterID rm) + masterCl <- io $ client'sM rnc id `DT.mapM` (masterID rm) chans <- liftM (map sendChan) $! sameProtoClientsS proto - processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo n rm) + processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo proto (maybeNick masterCl) rm) processAction UnreadyRoomClients = do @@ -433,10 +444,8 @@ checkerLogin "" False False else processAction JoinLobby - Admin -> do + Admin -> mapM_ processAction [ModifyClient (\cl -> cl{isAdministrator = True}), JoinLobby] - chan <- client's sendChan - processAction $ AnswerClients [chan] ["ADMIN_ACCESS"] ReplayName fn -> processAction $ ShowReplay fn where isBanned = do @@ -456,6 +465,7 @@ processAction JoinLobby = do chan <- client's sendChan + rnc <- gets roomsClients clientNick <- client's nick isAuthenticated <- liftM (not . B.null) $ client's webPassword isAdmin <- client's isAdministrator @@ -465,6 +475,10 @@ let authenticatedNicks = L.map nick . L.filter (not . B.null . webPassword) $ loggedInClients let adminsNicks = L.map nick . L.filter isAdministrator $ loggedInClients let contrNicks = L.map nick . L.filter isContributor $ loggedInClients + inRoomNicks <- io $ + allClientsM rnc + >>= filterM (liftM ((/=) lobbyId) . clientRoomM rnc) + >>= mapM (client'sM rnc nick) let clFlags = B.concat . L.concat $ [["u" | isAuthenticated], ["a" | isAdmin], ["c" | isContr]] mapM_ processAction . concat $ [ [AnswerClients clientsChans ["LOBBY:JOINED", clientNick]] @@ -472,6 +486,7 @@ , [AnswerClients [chan] ("CLIENT_FLAGS" : "+u" : authenticatedNicks) | not $ null authenticatedNicks] , [AnswerClients [chan] ("CLIENT_FLAGS" : "+a" : adminsNicks) | not $ null adminsNicks] , [AnswerClients [chan] ("CLIENT_FLAGS" : "+c" : contrNicks) | not $ null contrNicks] + , [AnswerClients [chan] ("CLIENT_FLAGS" : "+i" : inRoomNicks) | not $ null inRoomNicks] , [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags] , [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})] , [SendServerMessage] @@ -678,7 +693,16 @@ processAction CheckRecord = do p <- client's clientProto c <- client's sendChan - (cinfo, l) <- io $ loadReplay (fromIntegral p) + ri <- clientRoomA + rnc <- gets roomsClients + + blackList <- liftM (map (recordFileName . fromJust . checkInfo) . filter (isJust . checkInfo)) allClientsS + + readyCheckersIds <- io $ do + allci <- allClientsM rnc + filterM (client'sM rnc (isJust . checkInfo)) allci + + (cinfo, l) <- io $ loadReplay (fromIntegral p) blackList when (not . null $ l) $ mapM_ processAction [ AnswerClients [c] ("REPLAY" : l) @@ -693,17 +717,18 @@ processAction (CheckSuccess info) = do Just (CheckInfo fileName teams) <- client's checkInfo + p <- client's clientProto si <- gets serverInfo - io $ writeChan (dbQueries si) $ StoreAchievements (B.pack fileName) (map toPair teams) info + io $ writeChan (dbQueries si) $ StoreAchievements p (B.pack fileName) (map toPair teams) info io $ moveCheckedRecord fileName where toPair t = (teamname t, teamowner t) -processAction (QueryReplay name) = do +processAction (QueryReplay rname) = do (Just ci) <- gets clientIndex si <- gets serverInfo uid <- client's clUID - io $ writeChan (dbQueries si) $ GetReplayName ci (hashUnique uid) name + io $ writeChan (dbQueries si) $ GetReplayName ci (hashUnique uid) rname #else processAction SaveReplay = return () @@ -713,25 +738,25 @@ processAction (QueryReplay _) = return () #endif -processAction (ShowReplay name) = do +processAction (ShowReplay rname) = do c <- client's sendChan cl <- client's id - let fileName = B.concat ["checked/", if B.isPrefixOf "replays/" name then B.drop 8 name else name] + let fileName = B.concat ["checked/", if B.isPrefixOf "replays/" rname then B.drop 8 rname else rname] - checkInfo <- liftIO $ E.handle (\(e :: SomeException) -> + cInfo <- liftIO $ E.handle (\(e :: SomeException) -> warningM "REPLAYS" (B.unpack $ B.concat ["Problems reading ", fileName, ": ", B.pack $ show e]) >> return Nothing) $ do (t, p1, p2, msgs) <- liftM read $ readFile (B.unpack fileName) return $ Just (t, Map.fromList p1, Map.fromList p2, reverse msgs) - let (teams, params1, params2, roundMsgs) = fromJust checkInfo + let (teams', params1, params2, roundMsgs') = fromJust cInfo - when (isJust checkInfo) $ do + when (isJust cInfo) $ do mapM_ processAction $ concat [ [AnswerClients [c] ["JOINED", nick cl]] , answerFullConfigParams cl params1 params2 - , answerAllTeams cl teams + , answerAllTeams cl teams' , [AnswerClients [c] ["RUN_GAME"]] - , [AnswerClients [c] $ "EM" : roundMsgs] + , [AnswerClients [c] $ "EM" : roundMsgs'] , [AnswerClients [c] ["KICKED"]] ] diff -r 8054d9d775fd -r 2759212a27de gameServer/Consts.hs --- a/gameServer/Consts.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/Consts.hs Sat Jan 04 23:55:54 2014 +0400 @@ -4,4 +4,4 @@ import qualified Data.ByteString.Char8 as B serverVersion :: B.ByteString -serverVersion = "1" +serverVersion = "2" diff -r 8054d9d775fd -r 2759212a27de gameServer/CoreTypes.hs --- a/gameServer/CoreTypes.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/CoreTypes.hs Sat Jan 04 23:55:54 2014 +0400 @@ -101,7 +101,6 @@ logonPassed :: Bool, isVisible :: Bool, clientProto :: !Word16, - roomID :: RoomIndex, pingsQueue :: !Word, isMaster :: Bool, isReady :: !Bool, @@ -171,7 +170,7 @@ data RoomInfo = RoomInfo { - masterID :: ClientIndex, + masterID :: Maybe ClientIndex, name :: B.ByteString, password :: B.ByteString, roomProto :: Word16, @@ -182,6 +181,8 @@ isRestrictedJoins :: Bool, isRestrictedTeams :: Bool, isRegisteredOnly :: Bool, + isSpecial :: Bool, + greeting :: B.ByteString, roomBansList :: ![B.ByteString], mapParams :: Map.Map B.ByteString B.ByteString, params :: Map.Map B.ByteString [B.ByteString] @@ -190,7 +191,7 @@ newRoom :: RoomInfo newRoom = RoomInfo - (error "No room master defined") + Nothing "" "" 0 @@ -201,13 +202,20 @@ False False False + False + "" [] ( - Map.fromList $ Prelude.zipWith (,) + Map.fromList $ Prelude.zip ["MAP", "MAPGEN", "MAZE_SIZE", "SEED", "TEMPLATE"] ["+rnd+", "0", "0", "seed", "0"] ) - (Map.singleton "SCHEME" ["Default"]) + ( + Map.fromList $ Prelude.zip + ["SCHEME", "SCRIPT"] + [["Default"], ["Normal"]] + ) + data StatisticsInfo = StatisticsInfo @@ -245,7 +253,7 @@ True "

http://www.hedgewars.org/

" "

Hedgewars 0.9.19 is out! Please update.

Download page here" - 45 -- latestReleaseVersion + 47 -- latestReleaseVersion 41 -- earliestCompatibleVersion 46631 "" @@ -267,7 +275,7 @@ CheckAccount ClientIndex Int B.ByteString B.ByteString | ClearCache | SendStats Int Int - | StoreAchievements B.ByteString [(B.ByteString, B.ByteString)] [B.ByteString] + | StoreAchievements Word16 B.ByteString [(B.ByteString, B.ByteString)] [B.ByteString] | GetReplayName ClientIndex Int B.ByteString deriving (Show, Read) diff -r 8054d9d775fd -r 2759212a27de gameServer/EngineInteraction.hs --- a/gameServer/EngineInteraction.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/EngineInteraction.hs Sat Jan 04 23:55:54 2014 +0400 @@ -12,6 +12,7 @@ import Data.Word import Data.Bits import Control.Arrow +import Data.Maybe ------------- import CoreTypes import Utils @@ -74,7 +75,7 @@ em = toEngineMsg eml = em . B.concat mapGenTypes = ["+rnd+", "+maze+", "+drawn+"] - maybeScript = let s = head $ prms Map.! "SCRIPT" in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]] + maybeScript = let s = head . fromMaybe ["Normal"] $ Map.lookup "SCRIPT" prms in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]] maybeMap = let m = mParams Map.! "MAP" in if m `elem` mapGenTypes then [] else [eml ["emap ", m]] scheme = tail $ prms Map.! "SCHEME" mapgen = mParams Map.! "MAPGEN" diff -r 8054d9d775fd -r 2759212a27de gameServer/HWProtoCore.hs --- a/gameServer/HWProtoCore.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/HWProtoCore.hs Sat Jan 04 23:55:54 2014 +0400 @@ -51,6 +51,9 @@ let chans = map (sendChan . client rnc) $ allClients rnc return [AnswerClients chans ["CHAT", "[global notice]", p] | isAdministrator cl] h "WATCH" f = return [QueryReplay f] + h "FIX" _ = handleCmd ["FIX"] + h "UNFIX" _ = handleCmd ["UNFIX"] + h "GREETING" msg = handleCmd ["GREETING", msg] h c p = return [Warning $ B.concat ["Unknown cmd: /", c, p]] handleCmd cmd = do diff -r 8054d9d775fd -r 2759212a27de gameServer/HWProtoInRoomState.hs --- a/gameServer/HWProtoInRoomState.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/HWProtoInRoomState.hs Sat Jan 04 23:55:54 2014 +0400 @@ -31,7 +31,11 @@ | otherwise = do chans <- roomOthersChans cl <- thisClient - if isMaster cl then + rm <- thisRoom + + if isSpecial rm then + return [Warning $ loc "Restricted"] + else if isMaster cl then return [ ModifyRoom f, AnswerClients chans ("CFG" : paramName : paramStrs)] @@ -43,6 +47,7 @@ else r{params = Map.insert paramName paramStrs (params r)} + handleCmd_inRoom ("ADD_TEAM" : tName : color : grave : fort : voicepack : flag : difStr : hhsInfo) | length hhsInfo /= 16 = return [ProtocolError $ loc "Corrupted hedgehogs info"] | otherwise = do @@ -290,11 +295,14 @@ if illegalName newName then [Warning $ loc "Illegal room name"] else + if isSpecial rm then + [Warning $ loc "Restricted"] + else if isJust $ find (\r -> newName == name r) rs then [Warning $ loc "Room with such name already exists"] else [ModifyRoom roomUpdate, - AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo (nick cl) (roomUpdate rm))] + AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo (clientProto cl) (nick cl) (roomUpdate rm))] where roomUpdate r = r{name = newName} @@ -323,6 +331,7 @@ maybeClientId <- clientByNick newAdmin master <- liftM isMaster thisClient serverAdmin <- liftM isAdministrator thisClient + thisRoomMasterId <- liftM masterID thisRoom let newAdminId = fromJust maybeClientId let sameRoom = clientRoom rnc thisClientId == clientRoom rnc newAdminId return @@ -330,6 +339,7 @@ (master || serverAdmin) && isJust maybeClientId && ((newAdminId /= thisClientId) || (serverAdmin && not master)) + && (Just newAdminId /= thisRoomMasterId) && sameRoom] @@ -360,6 +370,19 @@ s <- roomClientsChans return [AnswerClients s ["CHAT", n, B.unwords $ "/rnd" : rs], Random s rs] +handleCmd_inRoom ["FIX"] = do + cl <- thisClient + return [ModifyRoom (\r -> r{isSpecial = True}) | isAdministrator cl] + +handleCmd_inRoom ["UNFIX"] = do + cl <- thisClient + return [ModifyRoom (\r -> r{isSpecial = False}) | isAdministrator cl] + +handleCmd_inRoom ["GREETING", msg] = do + cl <- thisClient + rm <- thisRoom + return [ModifyRoom (\r -> r{greeting = msg}) | isAdministrator cl || (isMaster cl && (not $ isSpecial rm))] + handleCmd_inRoom ["LIST"] = return [] -- for old clients (<= 0.9.17) handleCmd_inRoom (s:_) = return [ProtocolError $ "Incorrect command '" `B.append` s `B.append` "' (state: in room)"] diff -r 8054d9d775fd -r 2759212a27de gameServer/HWProtoLobbyState.hs --- a/gameServer/HWProtoLobbyState.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/HWProtoLobbyState.hs Sat Jan 04 23:55:54 2014 +0400 @@ -21,10 +21,9 @@ (ci, irnc) <- ask let cl = irnc `client` ci rooms <- allRoomInfos - let roomsInfoList = concatMap (\r -> roomInfo (nick $ irnc `client` masterID r) r) . filter (\r -> (roomProto r == clientProto cl)) + let roomsInfoList = concatMap (\r -> roomInfo (clientProto cl) (maybeNick . liftM (client irnc) $ masterID r) r) . filter (\r -> (roomProto r == clientProto cl)) return [AnswerClients [sendChan cl] ("ROOMS" : roomsInfoList rooms)] - handleCmd_lobby ["CHAT", msg] = do n <- clientNick s <- roomOthersChans @@ -60,35 +59,37 @@ let sameProto = clientProto cl == roomProto jRoom let jRoomClients = map (client irnc) $ roomClients irnc jRI let nicks = map nick jRoomClients - let ownerNick = nick . fromJust $ find isMaster jRoomClients + let owner = find isMaster jRoomClients let chans = map sendChan (cl : jRoomClients) let isBanned = host cl `elem` roomBansList jRoom return $ - if isNothing maybeRI || not sameProto then + if isNothing maybeRI then [Warning $ loc "No such room"] + else if not sameProto then + [Warning $ loc "Room version incompatible to your hedgewars version"] else if isRestrictedJoins jRoom then [Warning $ loc "Joining restricted"] - else if isRegisteredOnly jRoom && (B.null . webPassword $ cl) then + else if isRegisteredOnly jRoom && (B.null . webPassword $ cl) && not (isAdministrator cl) then [Warning $ loc "Registered users only"] else if isBanned then [Warning $ loc "You are banned in this room"] else if roomPassword /= password jRoom then [NoticeMessage WrongPassword] else - [ + ( MoveToRoom jRI - , ModifyClient (\c -> c{isJoinedMidGame = isJust $ gameInfo jRoom}) - , AnswerClients [sendChan cl] $ "JOINED" : nicks - , AnswerClients chans ["CLIENT_FLAGS", "-r", nick cl] - , AnswerClients [sendChan cl] $ ["CLIENT_FLAGS", "+h", ownerNick] - ] - ++ (if clientProto cl < 38 then map (readynessMessage cl) jRoomClients else [sendStateFlags cl jRoomClients]) + : ModifyClient (\c -> c{isJoinedMidGame = isJust $ gameInfo jRoom}) + : AnswerClients chans ["CLIENT_FLAGS", "-r", nick cl] + : [(AnswerClients [sendChan cl] $ "JOINED" : nicks) | not $ null nicks] + ) + ++ [AnswerClients [sendChan cl] ["CLIENT_FLAGS", "+h", nick $ fromJust owner] | isJust owner] + ++ [sendStateFlags cl jRoomClients | not $ null jRoomClients] ++ answerFullConfig cl jRoom ++ answerTeams cl jRoom ++ watchRound cl jRoom chans + ++ [AnswerClients [sendChan cl] ["CHAT", "[greeting]", greeting jRoom] | greeting jRoom /= ""] where - readynessMessage cl c = AnswerClients [sendChan cl] [if isReady c then "READY" else "NOT_READY", nick c] sendStateFlags cl clients = AnswerClients [sendChan cl] . concat . intersperse [""] . filter (not . null) . concat $ [f "+r" ready, f "-r" unready, f "+g" ingame, f "-g" inroomlobby] where diff -r 8054d9d775fd -r 2759212a27de gameServer/NetRoutines.hs --- a/gameServer/NetRoutines.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/NetRoutines.hs Sat Jan 04 23:55:54 2014 +0400 @@ -36,7 +36,6 @@ False False 0 - lobbyId 0 False False diff -r 8054d9d775fd -r 2759212a27de gameServer/OfficialServer/DBInteraction.hs --- a/gameServer/OfficialServer/DBInteraction.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/OfficialServer/DBInteraction.hs Sat Jan 04 23:55:54 2014 +0400 @@ -49,6 +49,8 @@ writeChan (coreChan si) $ ClientAccountInfo clId clUid (if clHost `L.elem` localAddressList then Admin else Guest) ClearCache -> return () SendStats {} -> return () + GetReplayName {} -> return () + StoreAchievements {} -> return () flushRequests si pipeDbConnectionLoop :: Chan DBQuery -> Chan CoreMessage -> Handle -> Handle -> Map.Map ByteString (UTCTime, AccountInfo) -> Int -> IO (Map.Map ByteString (UTCTime, AccountInfo), Int) diff -r 8054d9d775fd -r 2759212a27de gameServer/OfficialServer/GameReplayStore.hs --- a/gameServer/OfficialServer/GameReplayStore.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/OfficialServer/GameReplayStore.hs Sat Jan 04 23:55:54 2014 +0400 @@ -17,13 +17,16 @@ import EngineInteraction -pickReplayFile :: Int -> IO String -pickReplayFile p = do - files <- liftM (filter (isSuffixOf ('.' : show p))) $ getDirectoryContents "replays" +pickReplayFile :: Int -> [String] -> IO String +pickReplayFile p blackList = do + files <- liftM (filter (\f -> sameProto f && notBlacklisted f)) $ getDirectoryContents "replays" if (not $ null files) then return $ "replays/" ++ head files else return "" + where + sameProto = (isSuffixOf ('.' : show p)) + notBlacklisted = flip notElem blackList saveReplay :: RoomInfo -> IO () saveReplay r = do @@ -38,9 +41,9 @@ (\(e :: IOException) -> warningM "REPLAYS" $ "Couldn't write to " ++ fileName ++ ": " ++ show e) -loadReplay :: Int -> IO (Maybe CheckInfo, [B.ByteString]) -loadReplay p = E.handle (\(e :: SomeException) -> warningM "REPLAYS" "Problems reading replay" >> return (Nothing, [])) $ do - fileName <- pickReplayFile p +loadReplay :: Int -> [String] -> IO (Maybe CheckInfo, [B.ByteString]) +loadReplay p blackList = E.handle (\(e :: SomeException) -> warningM "REPLAYS" "Problems reading replay" >> return (Nothing, [])) $ do + fileName <- pickReplayFile p blackList if (not $ null fileName) then loadFile fileName else diff -r 8054d9d775fd -r 2759212a27de gameServer/OfficialServer/checker.hs --- a/gameServer/OfficialServer/checker.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/OfficialServer/checker.hs Sat Jan 04 23:55:54 2014 +0400 @@ -36,7 +36,7 @@ deriving Show serverAddress = "netserver.hedgewars.org" -protocolNumber = "45" +protocolNumber = "47" getLines :: Handle -> IO [B.ByteString] getLines h = g @@ -77,10 +77,10 @@ hFlush h hClose h - (_, _, Just hOut, _) <- createProcess (proc "/usr/home/unC0Rr/Sources/Hedgewars/Releases/0.9.19/bin/hwengine" + (_, _, Just hOut, _) <- createProcess (proc "/usr/home/unC0Rr/Sources/Hedgewars/Releases/0.9.20/bin/hwengine" [fileName , "--user-prefix", "/usr/home/unC0Rr/.hedgewars" - , "--prefix", "/usr/home/unC0Rr/Sources/Hedgewars/Releases/0.9.19/share/hedgewars/Data" + , "--prefix", "/usr/home/unC0Rr/Sources/Hedgewars/Releases/0.9.20/share/hedgewars/Data" , "--nomusic" , "--nosound" , "--stats-only" @@ -171,7 +171,7 @@ Right (login, password) <- runErrorT $ do d <- liftIO $ getHomeDirectory - conf <- join . liftIO . CF.readfile CF.emptyCP $ d ++ "/.hedgewars/hedgewars.ini" + conf <- join . liftIO . CF.readfile CF.emptyCP $ d ++ "/.hedgewars/settings.ini" l <- CF.get conf "net" "nick" p <- CF.get conf "net" "passwordhash" return (B.pack l, B.pack p) diff -r 8054d9d775fd -r 2759212a27de gameServer/OfficialServer/extdbinterface.hs --- a/gameServer/OfficialServer/extdbinterface.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/OfficialServer/extdbinterface.hs Sat Jan 04 23:55:54 2014 +0400 @@ -11,6 +11,7 @@ import Database.HDBC.MySQL import Data.List (lookup) import qualified Data.ByteString.Char8 as B +import Data.Word -------------------------- import CoreTypes import Utils @@ -26,9 +27,9 @@ "INSERT INTO gameserver_stats (players, rooms, last_update) VALUES (?, ?, UNIX_TIMESTAMP())" dbQueryAchievement = - "INSERT INTO achievements (time, typeid, userid, value, filename, location) \ + "INSERT INTO achievements (time, typeid, userid, value, filename, location, protocol) \ \ VALUES (?, (SELECT id FROM achievement_types WHERE name = ?), (SELECT uid FROM users WHERE name = ?), \ - \ ?, ?, ?)" + \ ?, ?, ?, ?)" dbQueryReplayFilename = "SELECT filename FROM achievements WHERE id = ?" @@ -70,15 +71,15 @@ SendStats clients rooms -> run dbConn dbQueryStats [SqlInt32 $ fromIntegral clients, SqlInt32 $ fromIntegral rooms] >> return () --StoreAchievements (B.pack fileName) (map toPair teams) info - StoreAchievements fileName teams info -> - mapM_ (run dbConn dbQueryAchievement) $ (parseStats fileName teams) info + StoreAchievements p fileName teams info -> + mapM_ (run dbConn dbQueryAchievement) $ (parseStats p fileName teams) info readTime = read . B.unpack . B.take 19 . B.drop 8 -parseStats :: B.ByteString -> [(B.ByteString, B.ByteString)] -> [B.ByteString] -> [[SqlValue]] -parseStats fileName teams = ps +parseStats :: Word16 -> B.ByteString -> [(B.ByteString, B.ByteString)] -> [B.ByteString] -> [[SqlValue]] +parseStats p fileName teams = ps where time = readTime fileName ps [] = [] @@ -91,6 +92,7 @@ , SqlInt32 (readInt_ value) , SqlByteString fileName , SqlByteString location + , SqlInt32 $ fromIntegral p ] : ps bs ps (b:bs) = ps bs diff -r 8054d9d775fd -r 2759212a27de gameServer/Utils.hs --- a/gameServer/Utils.hs Fri Oct 11 17:43:13 2013 +0200 +++ b/gameServer/Utils.hs Sat Jan 04 23:55:54 2014 +0400 @@ -92,6 +92,8 @@ , (44, "0.9.19-dev") , (45, "0.9.19") , (46, "0.9.20-dev") + , (47, "0.9.20") + , (48, "0.9.21-dev") ] askFromConsole :: B.ByteString -> IO B.ByteString @@ -125,8 +127,9 @@ upperCase :: B.ByteString -> B.ByteString upperCase = UTF8.fromString . map Char.toUpper . UTF8.toString -roomInfo :: B.ByteString -> RoomInfo -> [B.ByteString] -roomInfo n r = [ +roomInfo :: Word16 -> B.ByteString -> RoomInfo -> [B.ByteString] +roomInfo p n r + | p < 46 = [ showB $ isJust $ gameInfo r, name r, showB $ playersIn r, @@ -136,7 +139,17 @@ head (Map.findWithDefault ["Default"] "SCHEME" (params r)), head (Map.findWithDefault ["Default"] "AMMO" (params r)) ] - + | otherwise = [ + showB $ isJust $ gameInfo r, + name r, + showB $ playersIn r, + showB $ length $ teams r, + n, + Map.findWithDefault "+rnd+" "MAP" (mapParams r), + head (Map.findWithDefault ["Normal"] "SCRIPT" (params r)), + head (Map.findWithDefault ["Default"] "SCHEME" (params r)), + head (Map.findWithDefault ["Default"] "AMMO" (params r)) + ] answerFullConfigParams :: ClientInfo @@ -169,3 +182,6 @@ loc :: B.ByteString -> B.ByteString loc = id + +maybeNick :: Maybe ClientInfo -> B.ByteString +maybeNick = fromMaybe "[empty]" . liftM nick diff -r 8054d9d775fd -r 2759212a27de hedgewars/CMakeLists.txt --- a/hedgewars/CMakeLists.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/CMakeLists.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,13 +1,25 @@ -find_package(SDL) +find_package(SDL1or2) find_package(SDL_image) find_package(SDL_net) find_package(SDL_ttf) find_package(SDL_mixer) -include (CheckLibraryExists) +include(CheckLibraryExists) +include(${CMAKE_MODULE_PATH}/utils.cmake) enable_language(Pascal) +add_flag_append(CMAKE_Pascal_FLAGS "-Cs2000000") +add_flag_append(CMAKE_Pascal_FLAGS_DEBUG "-gv") +add_flag_append(CMAKE_Pascal_FLAGS_RELEASE "-Xs") +if(UNIX) + include(TargetArch) + target_architecture(CMAKE_TARGET_ARCHITECTURES) + if(${CMAKE_Pascal_COMPILER_VERSION} VERSION_GREATER 2.7 OR ${CMAKE_TARGET_ARCHITECTURES} MATCHES "x86_64" OR ${CMAKE_TARGET_ARCHITECTURES} MATCHES "i386") + add_flag_append(CMAKE_Pascal_FLAGS "-fPIC") + endif() +endif(UNIX) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc) include_directories(${CMAKE_CURRENT_BINARY_DIR}) @@ -79,11 +91,6 @@ #these interact with everything, so compile last uScript.pas - hwengine.pas - - #we also have uTouch.pas - options.inc - ${CMAKE_CURRENT_BINARY_DIR}/config.inc ) @@ -102,20 +109,20 @@ add_flag_prepend(CMAKE_Pascal_FLAGS_RELEASE -Si) endif() +#generic folder where our libraries reside +add_flag_append(CMAKE_Pascal_FLAGS "-Fl${LIBRARY_OUTPUT_PATH}") #DEPENDECIES AND EXECUTABLES SECTION if(NOT ${BUILD_ENGINE_LIBRARY} AND APPLE) #on OSX we need to provide the SDL_main() function when building as executable add_subdirectory(sdlmain) list(APPEND HW_LINK_LIBS SDLmain) - add_flag_append(CMAKE_Pascal_FLAGS -Fl${LIBRARY_OUTPUT_PATH}) endif() if(FFMPEG_FOUND) add_subdirectory(avwrapper) list(APPEND HW_LINK_LIBS avwrapper) add_definitions(-dUSE_VIDEO_RECORDING) - add_flag_append(CMAKE_Pascal_FLAGS -Fl${LIBRARY_OUTPUT_PATH}) #only for SDL < 2, linking carried out by fpc find_package_or_disable_msg(GLUT NOVIDEOREC "Video recording will not be built") endif() @@ -125,7 +132,8 @@ list(INSERT engine_sources 0 PNGh.pas) list(REMOVE_AT PNG_LIBRARIES 1) #removing the zlib library path get_filename_component(PNG_LIBRARY_DIR ${PNG_LIBRARIES} PATH) - add_flag_append(CMAKE_Pascal_FLAGS -Fl${PNG_LIBRARY_DIR}) + add_flag_append(CMAKE_Pascal_FLAGS "-k-L${PNG_LIBRARY_DIR} -Fl${PNG_LIBRARY_DIR}") + add_definitions(-dPNG_SCREENSHOTS) endif() if(LUA_FOUND AND LUA_SYSTEM) @@ -140,17 +148,20 @@ add_flag_append(CMAKE_Pascal_FLAGS "-XLAlua=${lua_output_name}") endif() - -if(NOT PHYSFS_FOUND) +if(PHYSFS_FOUND) + get_filename_component(PHYSFS_LIBRARY_DIR ${PHYSFS_LIBRARY} PATH) + add_flag_append(CMAKE_Pascal_FLAGS "-Fl${PHYSFS_LIBRARY}") +else() add_definitions(-dPHYSFS_INTERNAL) list(APPEND HW_LINK_LIBS physfs) #-XLA is a beta fpc flag that renames libraries before passing them to the linker #we also have to pass PHYSFS_INTERNAL to satisfy windows runtime requirements #(should be harmless on other platforms) - add_flag_append(CMAKE_Pascal_FLAGS "-Fl${LIBRARY_OUTPUT_PATH} -XLAphysfs=${physfs_output_name}") + add_flag_append(CMAKE_Pascal_FLAGS "-XLAphysfs=${physfs_output_name}") endif() list(APPEND HW_LINK_LIBS physlayer) + #Mix_Init/Mix_Quit from SDL_mixer 1.2.10 check_library_exists(${SDLMIXER_LIBRARY} Mix_Init "" HAVE_MIXINIT) if(HAVE_MIXINIT) @@ -163,9 +174,21 @@ add_definitions(-dSDL_IMAGE_NEWER) endif(HAVE_IMGINIT) +if(NOT (SDL_VERSION VERSION_LESS 2.0)) + add_definitions(-dSDL2) +endif() + #needs to be last add_definitions(-dDEBUGFILE) + +# source files are with full path after this +set(sourcefiles_sofar "${CMAKE_CURRENT_SOURCE_DIR}/options.inc" "${CMAKE_CURRENT_BINARY_DIR}/config.inc") +foreach(loop_var ${engine_sources}) + list(APPEND sourcefiles_sofar "${CMAKE_CURRENT_SOURCE_DIR}/${loop_var}") +endforeach(loop_var) + + #SOURCE AND PROGRAMS SECTION if(BUILD_ENGINE_LIBRARY) message("***Engine will be built as library (experimental)***") @@ -180,12 +203,15 @@ add_flag_prepend(CMAKE_Pascal_FLAGS "-o${LIBRARY_OUTPUT_PATH}/${engine_output_name}") add_definitions(-dHWLIBRARY) - add_library(hwengine SHARED ${engine_sources} hwLibrary.pas) + set_source_files_properties(hwLibrary.pas PROPERTIES OBJECT_DEPENDS "${sourcefiles_sofar}") + set_source_files_properties(hwLibrary.pas PROPERTIES OBJECT_DEPENDS hwengine.pas) + add_library(hwengine SHARED hwLibrary.pas) else() # no need to change name here because target has same name set(engine_output_name "hwengine${CMAKE_EXECUTABLE_SUFFIX}") set(destination_dir ${target_binary_install_dir}) - add_executable(hwengine ${engine_sources}) + set_source_files_properties(hwengine.pas PROPERTIES OBJECT_DEPENDS "${sourcefiles_sofar}") + add_executable(hwengine hwengine.pas) endif() #even though not actually used, this will trigger relink if any lib changes diff -r 8054d9d775fd -r 2759212a27de hedgewars/avwrapper/avwrapper.c --- a/hedgewars/avwrapper/avwrapper.c Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/avwrapper/avwrapper.c Sat Jan 04 23:55:54 2014 +0400 @@ -65,7 +65,7 @@ // pointer to function from hwengine (uUtils.pas) static void (*AddFileLogRaw)(const char* pString); -static void FatalError(const char* pFmt, ...) +static int FatalError(const char* pFmt, ...) { char Buffer[1024]; va_list VaArgs; @@ -77,7 +77,7 @@ AddFileLogRaw("Error in av-wrapper: "); AddFileLogRaw(Buffer); AddFileLogRaw("\n"); - exit(1); + return(-1); } // Function to be called from libav for logging. @@ -166,7 +166,7 @@ } } -// returns non-zero if there is more sound +// returns non-zero if there is more sound, -1 in case of error static int WriteAudioFrame() { if (!g_pAStream) @@ -189,7 +189,7 @@ // when NumSamples == 0 we still need to call encode_audio2 to flush int got_packet; if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0) - FatalError("avcodec_encode_audio2 failed"); + return FatalError("avcodec_encode_audio2 failed"); if (!got_packet) return 0; #else @@ -210,12 +210,12 @@ // Write the compressed frame to the media file. Packet.stream_index = g_pAStream->index; if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing audio frame"); + return FatalError("Error while writing audio frame"); return 1; } // add a video output stream -static void AddVideoStream() +static int AddVideoStream() { #if LIBAVFORMAT_VERSION_MAJOR >= 53 g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec); @@ -223,7 +223,7 @@ g_pVStream = av_new_stream(g_pContainer, 0); #endif if (!g_pVStream) - FatalError("Could not allocate video stream"); + return FatalError("Could not allocate video stream"); g_pVideo = g_pVStream->codec; @@ -297,29 +297,35 @@ #else if (avcodec_open(g_pVideo, g_pVCodec) < 0) #endif - FatalError("Could not open video codec %s", g_pVCodec->long_name); + return FatalError("Could not open video codec %s", g_pVCodec->long_name); g_pVFrame = avcodec_alloc_frame(); if (!g_pVFrame) - FatalError("Could not allocate frame"); + return FatalError("Could not allocate frame"); g_pVFrame->linesize[0] = g_Width; g_pVFrame->linesize[1] = g_Width/2; g_pVFrame->linesize[2] = g_Width/2; g_pVFrame->linesize[3] = 0; + return 0; } static int WriteFrame(AVFrame* pFrame) { double AudioTime, VideoTime; - + int ret; // write interleaved audio frame if (g_pAStream) { VideoTime = (double)g_pVStream->pts.val*g_pVStream->time_base.num/g_pVStream->time_base.den; do + { AudioTime = (double)g_pAStream->pts.val*g_pAStream->time_base.num/g_pAStream->time_base.den; - while (AudioTime < VideoTime && WriteAudioFrame()); + ret = WriteAudioFrame(); + } + while (AudioTime < VideoTime && ret); + if (ret < 0) + return ret; } if (!g_pVStream) @@ -341,7 +347,7 @@ Packet.size = sizeof(AVPicture); if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing video frame"); + return FatalError("Error while writing video frame"); return 0; } else @@ -349,7 +355,7 @@ #if LIBAVCODEC_VERSION_MAJOR >= 54 int got_packet; if (avcodec_encode_video2(g_pVideo, &Packet, pFrame, &got_packet) < 0) - FatalError("avcodec_encode_video2 failed"); + return FatalError("avcodec_encode_video2 failed"); if (!got_packet) return 0; @@ -360,7 +366,7 @@ #else Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame); if (Packet.size < 0) - FatalError("avcodec_encode_video failed"); + return FatalError("avcodec_encode_video failed"); if (Packet.size == 0) return 0; @@ -373,21 +379,21 @@ // write the compressed frame in the media file Packet.stream_index = g_pVStream->index; if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing video frame"); + return FatalError("Error while writing video frame"); return 1; } } -AVWRAP_DECL void AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr) +AVWRAP_DECL int AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr) { g_pVFrame->data[0] = pY; g_pVFrame->data[1] = pCb; g_pVFrame->data[2] = pCr; - WriteFrame(g_pVFrame); + return WriteFrame(g_pVFrame); } -AVWRAP_DECL void AVWrapper_Init( +AVWRAP_DECL int AVWrapper_Init( void (*pAddFileLogRaw)(const char*), const char* pFilename, const char* pDesc, @@ -399,6 +405,7 @@ int FramerateNum, int FramerateDen, int VQuality) { + int ret; AddFileLogRaw = pAddFileLogRaw; av_log_set_callback( &LogCallback ); @@ -414,12 +421,12 @@ // find format g_pFormat = av_guess_format(pFormatName, NULL, NULL); if (!g_pFormat) - FatalError("Format \"%s\" was not found", pFormatName); + return FatalError("Format \"%s\" was not found", pFormatName); // allocate the output media context g_pContainer = avformat_alloc_context(); if (!g_pContainer) - FatalError("Could not allocate output context"); + return FatalError("Could not allocate output context"); g_pContainer->oformat = g_pFormat; @@ -442,7 +449,11 @@ g_pAStream = NULL; if (g_pVCodec) - AddVideoStream(); + { + ret = AddVideoStream(); + if (ret < 0) + return ret; + } else Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName); @@ -462,7 +473,7 @@ Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName); if (!g_pAStream && !g_pVStream) - FatalError("No video, no audio, aborting..."); + return FatalError("No video, no audio, aborting..."); // write format info to log av_dump_format(g_pContainer, 0, g_pContainer->filename, 1); @@ -471,22 +482,36 @@ if (!(g_pFormat->flags & AVFMT_NOFILE)) { if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0) - FatalError("Could not open output file (%s)", g_pContainer->filename); + return FatalError("Could not open output file (%s)", g_pContainer->filename); } // write the stream header, if any avformat_write_header(g_pContainer, NULL); g_pVFrame->pts = -1; + return 0; } -AVWRAP_DECL void AVWrapper_Close() +AVWRAP_DECL int AVWrapper_Close() { + int ret; // output buffered frames if (g_pVCodec->capabilities & CODEC_CAP_DELAY) - while( WriteFrame(NULL) ); + { + do + ret = WriteFrame(NULL); + while (ret >= 0); + if (ret < 0) + return ret; + } // output any remaining audio - while( WriteAudioFrame() ); + do + { + ret = WriteAudioFrame(); + } + while(ret >= 0); + if (ret < 0) + return ret; // write the trailer, if any. av_write_trailer(g_pContainer); @@ -514,4 +539,5 @@ } av_free(g_pContainer); + return 0; } diff -r 8054d9d775fd -r 2759212a27de hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/hwengine.pas Sat Jan 04 23:55:54 2014 +0400 @@ -223,7 +223,7 @@ cNewScreenHeight:= max(2 * (event.window.data2 div 2), cMinScreenHeight); cScreenResizeDelay:= RealTicks + 500{$IFDEF IPHONEOS}div 2{$ENDIF}; end; - +{$IFDEF USE_TOUCH_INTERFACE} SDL_FINGERMOTION: onTouchMotion(event.tfinger.x, event.tfinger.y, event.tfinger.dx, event.tfinger.dy, event.tfinger.fingerId); @@ -232,6 +232,7 @@ SDL_FINGERUP: onTouchUp(event.tfinger.x, event.tfinger.y, event.tfinger.fingerId); +{$ENDIF} {$ELSE} SDL_KEYDOWN: if GameState = gsChat then @@ -507,7 +508,7 @@ uTextures.initModule; {$IFDEF ANDROID}GLUnit.initModule;{$ENDIF} {$IFDEF USE_TOUCH_INTERFACE}uTouch.initModule;{$ENDIF} -{$IFDEF USE_VIDEO_RECORDING}uVideoRec.initModule;{$ENDIF} //stub +{$IFDEF USE_VIDEO_RECORDING}uVideoRec.initModule;{$ENDIF} uAI.initModule; uAIMisc.initModule; uAILandMarks.initModule; //stub diff -r 8054d9d775fd -r 2759212a27de hedgewars/uAI.pas --- a/hedgewars/uAI.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uAI.pas Sat Jan 04 23:55:54 2014 +0400 @@ -256,7 +256,7 @@ AddAction(Actions, aia_Weapon, Longword(amSkip), 100 + random(200), 0, 0); if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoMoveAfter) = 0)) - and (GameFlags and gfArtillery = 0) then + and (GameFlags and gfArtillery = 0) and (cGravityf <> 0) then begin tmp:= random(2) + 1; Push(0, Actions, Me^, tmp); diff -r 8054d9d775fd -r 2759212a27de hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uAIAmmoTests.pas Sat Jan 04 23:55:54 2014 +0400 @@ -54,6 +54,7 @@ function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; +function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; type TAmmoTestProc = function (Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; TAmmoTest = record @@ -74,7 +75,7 @@ (proc: nil; flags: 0), // amRope (proc: nil; flags: 0), // amMine (proc: @TestDesertEagle; flags: amtest_MultipleAttacks), // amDEagle - (proc: nil; flags: 0), // amDynamite + (proc: @TestDynamite; flags: amtest_NoTarget), // amDynamite (proc: @TestFirePunch; flags: amtest_NoTarget), // amFirePunch (proc: @TestWhip; flags: amtest_NoTarget), // amWhip (proc: @TestBaseballBat; flags: amtest_NoTarget), // amBaseballBat @@ -120,7 +121,8 @@ //(proc: nil; flags: 0), // amStructure (proc: nil; flags: 0), // amLandGun (proc: nil; flags: 0), // amIceGun - (proc: nil; flags: 0) // amKnife + (proc: nil; flags: 0), // amKnife + (proc: nil; flags: 0) // amGirder ); implementation @@ -1045,7 +1047,7 @@ begin ap.ExplR:= 0; ap.Time:= 0; -if (Level > 3) then +if (Level > 3) or (cGravityf = 0) then exit(BadTurn); ap.Angle:= 0; @@ -1222,4 +1224,48 @@ TestCake:= valueResult; end; +function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; +var valueResult: LongInt; + x, y, dx, dy: real; + EX, EY, t: LongInt; +begin +Targ:= Targ; // avoid compiler hint + +x:= hwFloat2Float(Me^.X) + hwSign(Me^.dX) * 7; +y:= hwFloat2Float(Me^.Y); +dx:= hwSign(Me^.dX) * 0.03; +dy:= 0; +t:= 5000; +repeat + dec(t); + x:= x + dx; + dy:= dy + cGravityf; + y:= y + dy; + + if TestColl(trunc(x), trunc(y), 3) then + t:= 0; +until t = 0; + +EX:= trunc(x); +EY:= trunc(y); + +if Level = 1 then + valueResult:= RateExplosion(Me, EX, EY, 76, afTrackFall or afErasesLand) +else + valueResult:= RateExplosion(Me, EX, EY, 76); + +if (valueResult > 0) then + begin + ap.Angle:= 0; + ap.Power:= 1; + ap.Time:= 0; + ap.ExplR:= 150; + ap.ExplX:= EX; + ap.ExplY:= EY + end else + valueResult:= BadTurn; + +TestDynamite:= valueResult +end; + end. diff -r 8054d9d775fd -r 2759212a27de hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uAIMisc.pas Sat Jan 04 23:55:54 2014 +0400 @@ -816,13 +816,13 @@ jmpLJump: begin if TestCollisionYwithGear(Gear, -1) <> 0 then - if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then + if TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) = 0 then Gear^.Y:= Gear^.Y - int2hwFloat(2) else - if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then + if TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) = 0 then Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or - (TestCollisionYwithGear(Gear, -1) <> 0)) then + if (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.dY:= -_0_15; Gear^.dX:= SignAs(_0_15, Gear^.dX); @@ -850,7 +850,7 @@ Gear^.dY:= -_0_25; Gear^.dX:= SignAs(_0_02, Gear^.dX) end; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then SetLittle(Gear^.dX); + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then SetLittle(Gear^.dX); Gear^.X:= Gear^.X + Gear^.dX; inc(GoInfo.Ticks); Gear^.dY:= Gear^.dY + cGravity; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uAmmos.pas --- a/hedgewars/uAmmos.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uAmmos.pas Sat Jan 04 23:55:54 2014 +0400 @@ -224,6 +224,7 @@ CurWeapon: PAmmo; a: TAmmoType; begin +if ammo = amNothing then exit; {$HINTS OFF} FillChar(ammos, sizeof(ammos), 0); {$HINTS ON} @@ -321,18 +322,21 @@ if Hedgehog.Gear <> nil then with Hedgehog do begin - CurMinAngle:= Ammoz[AmmoType].minAngle; - if Ammoz[AmmoType].maxAngle <> 0 then - CurMaxAngle:= Ammoz[AmmoType].maxAngle - else - CurMaxAngle:= cMaxAngle; + if (AmmoType <> amNothing) then + begin + CurMinAngle:= Ammoz[AmmoType].minAngle; + if Ammoz[AmmoType].maxAngle <> 0 then + CurMaxAngle:= Ammoz[AmmoType].maxAngle + else + CurMaxAngle:= cMaxAngle; - with Hedgehog.Gear^ do - begin - if Angle < CurMinAngle then - Angle:= CurMinAngle; - if Angle > CurMaxAngle then - Angle:= CurMaxAngle; + with Hedgehog.Gear^ do + begin + if Angle < CurMinAngle then + Angle:= CurMinAngle; + if Angle > CurMaxAngle then + Angle:= CurMaxAngle; + end end end end; @@ -508,6 +512,8 @@ RegisterVariable('ammreinf', @SetAmmoReinforcement, false); RegisterVariable('ammstore', @chAddAmmoStore , false); + CurMinAngle:= 0; + CurMaxAngle:= cMaxAngle; StoreCnt:= 0; ammoLoadout:= ''; ammoProbability:= ''; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uChat.pas --- a/hedgewars/uChat.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uChat.pas Sat Jan 04 23:55:54 2014 +0400 @@ -29,6 +29,7 @@ procedure AddChatString(s: shortstring); procedure DrawChat; procedure KeyPressChat(Key, Sym: Longword); +procedure SendHogSpeech(s: shortstring); implementation uses SDLh, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO; @@ -41,7 +42,7 @@ Width: LongInt; s: shortstring; end; - TChatCmd = (quitCmd, pauseCmd, finishCmd, fullscreenCmd); + TChatCmd = (quit, pause, finish, showhistory, fullscreen); var Strs: array[0 .. MaxStrIndex] of TChatLine; MStrs: array[0 .. MaxStrIndex] of shortstring; @@ -73,6 +74,7 @@ (ChatCmd: '/quit'; ProcedureCallChatCmd: 'halt'), (ChatCmd: '/pause'; ProcedureCallChatCmd: 'pause'), (ChatCmd: '/finish'; ProcedureCallChatCmd: 'finish'), + (ChatCmd: '/history'; ProcedureCallChatCmd: 'history'), (ChatCmd: '/fullscreen'; ProcedureCallChatCmd: 'fullscr') ); @@ -174,7 +176,7 @@ DrawFillRect(r); Tint($00, $00, $00, $80); DrawTexture(9 - cScreenWidth div 2, visibleCount * 16 + 11, InputStr.Tex); - Tint($FF, $FF, $FF, $FF); + untint; DrawTexture(8 - cScreenWidth div 2, visibleCount * 16 + 10, InputStr.Tex); end; @@ -187,7 +189,7 @@ DrawFillRect(r); Tint($00, $00, $00, $80); DrawTexture(9 - cScreenWidth div 2, (visibleCount - t) * 16 - 5, Strs[i].Tex); - Tint($FF, $FF, $FF, $FF); + untint; DrawTexture(8 - cScreenWidth div 2, (visibleCount - t) * 16 - 6, Strs[i].Tex); dec(r.y, 16); @@ -240,55 +242,64 @@ exit end; -// These 3 are same as above, only are to make the hedgehog say it on next attack -if (s[1] = '/') and (copy(s, 1, 5) = '/hsa ') then - begin - if CurrentTeam^.ExtDriven then - ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) - else - SendHogSpeech(#4 + copy(s, 6, Length(s)-5)); - exit - end; -if (s[1] = '/') and (copy(s, 1, 5) = '/hta ') then - begin - if CurrentTeam^.ExtDriven then - ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) - else - SendHogSpeech(#5 + copy(s, 6, Length(s)-5)); - exit - end; -if (s[1] = '/') and (copy(s, 1, 5) = '/hya ') then +if (s[1] = '/') then begin - if CurrentTeam^.ExtDriven then - ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) - else - SendHogSpeech(#6 + copy(s, 6, Length(s)-5)); - exit - end; + // These 3 are same as above, only are to make the hedgehog say it on next attack + if (copy(s, 1, 5) = '/hsa ') then + begin + if CurrentTeam^.ExtDriven then + ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) + else + SendHogSpeech(#4 + copy(s, 6, Length(s)-5)); + exit + end; + + if (copy(s, 1, 5) = '/hta ') then + begin + if CurrentTeam^.ExtDriven then + ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) + else + SendHogSpeech(#5 + copy(s, 6, Length(s)-5)); + exit + end; + + if (copy(s, 1, 5) = '/hya ') then + begin + if CurrentTeam^.ExtDriven then + ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) + else + SendHogSpeech(#6 + copy(s, 6, Length(s)-5)); + exit + end; -if (copy(s, 1, 6) = '/team ') and (length(s) > 6) then - begin - ParseCommand(s, true); - exit - end; -if (s[1] = '/') and (copy(s, 1, 4) <> '/me ') then - begin - if CurrentTeam^.ExtDriven or (CurrentTeam^.Hedgehogs[0].BotLevel <> 0) then - exit; + if (copy(s, 1, 6) = '/team ') and (length(s) > 6) then + begin + ParseCommand(s, true); + exit + end; + + if (copy(s, 1, 4) = '/me ') then + begin + ParseCommand('/say ' + s, true); + exit + end; - for i:= Low(TWave) to High(TWave) do - if (s = Wavez[i].cmd) then - begin - ParseCommand('/taunt ' + char(i), true); - exit - end; + if (not CurrentTeam^.ExtDriven) and (CurrentTeam^.Hedgehogs[0].BotLevel = 0) then + begin + for i:= Low(TWave) to High(TWave) do + if (s = Wavez[i].cmd) then + begin + ParseCommand('/taunt ' + char(i), true); + exit + end; - for j:= Low(TChatCmd) to High(TChatCmd) do - if (s = ChatCommandz[j].ChatCmd) then - begin - ParseCommand(ChatCommandz[j].ProcedureCallChatCmd, true); - exit - end; + for j:= Low(TChatCmd) to High(TChatCmd) do + if (s = ChatCommandz[j].ChatCmd) then + begin + ParseCommand(ChatCommandz[j].ProcedureCallChatCmd, true); + exit + end; + end end else ParseCommand('/say ' + s, true); diff -r 8054d9d775fd -r 2759212a27de hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uCollisions.pas Sat Jan 04 23:55:54 2014 +0400 @@ -38,29 +38,29 @@ function CheckGearsCollision(Gear: PGear): PGearArray; -function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): Word; function TestCollisionYwithGear(Gear: PGear; Dir: LongInt): Word; -function TestCollisionXKick(Gear: PGear; Dir: LongInt): boolean; -function TestCollisionYKick(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionXKick(Gear: PGear; Dir: LongInt): Word; +function TestCollisionYKick(Gear: PGear; Dir: LongInt): Word; -function TestCollisionX(Gear: PGear; Dir: LongInt): boolean; -function TestCollisionY(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionX(Gear: PGear; Dir: LongInt): Word; +function TestCollisionY(Gear: PGear; Dir: LongInt): Word; -function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean; inline; -function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; -function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean; inline; -function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): Word; inline; +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word; +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): Word; inline; +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word; function TestRectancleForObstacle(x1, y1, x2, y2: LongInt; landOnly: boolean): boolean; // returns: negative sign if going downhill to left, value is steepness (noslope/error = _0, 45 = _0_5) function CalcSlopeBelowGear(Gear: PGear): hwFloat; function CalcSlopeNearGear(Gear: PGear; dirX, dirY: LongInt): hwFloat; -function CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): Boolean; +function CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): boolean; implementation -uses uConsts, uLandGraphics, uVariables, uDebug, uGearsList; +uses uConsts, uLandGraphics, uVariables, uDebug; type TCollisionEntry = record X, Y, Radius: LongInt; @@ -95,7 +95,7 @@ while (t <> nil) and (t^.Kind <> gtMine) do t:= t^.NextGear; if (t <> nil) then - DeleteGear(t) + t^.State:= t^.State or gmDelete end; end; @@ -135,7 +135,7 @@ end end; -function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): Word; var x, y, i: LongInt; begin // Special case to emulate the old intersect gear clearing, but with a bit of slop for pixel overlap @@ -150,7 +150,6 @@ else x:= x + Gear^.Radius; -TestCollisionXwithGear:= true; if (x and LAND_WIDTH_MASK) = 0 then begin y:= hwRound(Gear^.Y) - Gear^.Radius + 1; @@ -158,11 +157,11 @@ repeat if (y and LAND_HEIGHT_MASK) = 0 then if Land[y, x] and Gear^.CollisionMask <> 0 then - exit; + exit(Land[y, x] and Gear^.CollisionMask); inc(y) until (y > i); end; -TestCollisionXwithGear:= false +TestCollisionXwithGear:= 0 end; function TestCollisionYwithGear(Gear: PGear; Dir: LongInt): Word; @@ -188,8 +187,7 @@ if (x and LAND_WIDTH_MASK) = 0 then if Land[y, x] and Gear^.CollisionMask <> 0 then begin - TestCollisionYwithGear:= Land[y, x]; - exit; + exit(Land[y, x] and Gear^.CollisionMask) end; inc(x) until (x > i); @@ -197,34 +195,33 @@ TestCollisionYwithGear:= 0 end; -function TestCollisionXKick(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionXKick(Gear: PGear; Dir: LongInt): Word; var x, y, mx, my, i: LongInt; - flag: boolean; + pixel: Word; begin -flag:= false; +pixel:= 0; x:= hwRound(Gear^.X); if Dir < 0 then x:= x - Gear^.Radius else x:= x + Gear^.Radius; -TestCollisionXKick:= true; if (x and LAND_WIDTH_MASK) = 0 then begin y:= hwRound(Gear^.Y) - Gear^.Radius + 1; i:= y + Gear^.Radius * 2 - 2; repeat if (y and LAND_HEIGHT_MASK) = 0 then - if Land[y, x] > 255 then - exit - else if Land[y, x] <> 0 then - flag:= true; + if Land[y, x] and Gear^.CollisionMask > 255 then + exit(Land[y, x] and Gear^.CollisionMask) + else if Land[y, x] and Gear^.CollisionMask <> 0 then + pixel:= Land[y, x] and Gear^.CollisionMask; inc(y) until (y > i); end; -TestCollisionXKick:= flag; +TestCollisionXKick:= pixel; -if flag then +if pixel <> 0 then begin if hwAbs(Gear^.dX) < cHHKick then exit; @@ -255,24 +252,22 @@ Active:= true end; DeleteCI(cGear); - TestCollisionXKick:= false; - exit; + exit(0); end end end; -function TestCollisionYKick(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionYKick(Gear: PGear; Dir: LongInt): Word; var x, y, mx, my, myr, i: LongInt; - flag: boolean; + pixel: Word; begin -flag:= false; +pixel:= 0; y:= hwRound(Gear^.Y); if Dir < 0 then y:= y - Gear^.Radius else y:= y + Gear^.Radius; -TestCollisionYKick:= true; if (y and LAND_HEIGHT_MASK) = 0 then begin x:= hwRound(Gear^.X) - Gear^.Radius + 1; @@ -280,16 +275,16 @@ repeat if (x and LAND_WIDTH_MASK) = 0 then if Land[y, x] > 0 then - if Land[y, x] > 255 then - exit + if Land[y, x] and Gear^.CollisionMask > 255 then + exit(Land[y, x] and Gear^.CollisionMask) else if Land[y, x] <> 0 then - flag:= true; + pixel:= Land[y, x] and Gear^.CollisionMask; inc(x) until (x > i); end; -TestCollisionYKick:= flag; +TestCollisionYKick:= pixel; -if flag then +if pixel <> 0 then begin if hwAbs(Gear^.dY) < cHHKick then exit; @@ -318,18 +313,17 @@ Active:= true end; DeleteCI(cGear); - TestCollisionYKick:= false; - exit + exit(0) end end end; -function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean; inline; +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): Word; inline; begin TestCollisionXwithXYShift:= TestCollisionXwithXYShift(Gear, ShiftX, ShiftY, Dir, true); end; -function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word; begin Gear^.X:= Gear^.X + ShiftX; Gear^.Y:= Gear^.Y + int2hwFloat(ShiftY); @@ -340,7 +334,7 @@ Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY) end; -function TestCollisionX(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionX(Gear: PGear; Dir: LongInt): Word; var x, y, i: LongInt; begin x:= hwRound(Gear^.X); @@ -349,22 +343,21 @@ else x:= x + Gear^.Radius; -TestCollisionX:= true; if (x and LAND_WIDTH_MASK) = 0 then begin y:= hwRound(Gear^.Y) - Gear^.Radius + 1; i:= y + Gear^.Radius * 2 - 2; repeat if (y and LAND_HEIGHT_MASK) = 0 then - if Land[y, x] > 255 then - exit; + if Land[y, x] and Gear^.CollisionMask > 255 then + exit(Land[y, x] and Gear^.CollisionMask); inc(y) until (y > i); end; -TestCollisionX:= false +TestCollisionX:= 0 end; -function TestCollisionY(Gear: PGear; Dir: LongInt): boolean; +function TestCollisionY(Gear: PGear; Dir: LongInt): Word; var x, y, i: LongInt; begin y:= hwRound(Gear^.Y); @@ -373,33 +366,32 @@ else y:= y + Gear^.Radius; -TestCollisionY:= true; if (y and LAND_HEIGHT_MASK) = 0 then begin x:= hwRound(Gear^.X) - Gear^.Radius + 1; i:= x + Gear^.Radius * 2 - 2; repeat if (x and LAND_WIDTH_MASK) = 0 then - if Land[y, x] > 255 then - exit; + if Land[y, x] and Gear^.CollisionMask > 255 then + exit(Land[y, x] and Gear^.CollisionMask); inc(x) until (x > i); end; -TestCollisionY:= false +TestCollisionY:= 0 end; -function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean; inline; +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): Word; inline; begin TestCollisionYwithXYShift:= TestCollisionYwithXYShift(Gear, ShiftX, ShiftY, Dir, true); end; -function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word; begin Gear^.X:= Gear^.X + int2hwFloat(ShiftX); Gear^.Y:= Gear^.Y + int2hwFloat(ShiftY); if withGear then - TestCollisionYwithXYShift:= TestCollisionYwithGear(Gear, Dir) <> 0 + TestCollisionYwithXYShift:= TestCollisionYwithGear(Gear, Dir) else TestCollisionYwithXYShift:= TestCollisionY(Gear, Dir); diff -r 8054d9d775fd -r 2759212a27de hedgewars/uCommandHandlers.pas --- a/hedgewars/uCommandHandlers.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uCommandHandlers.pas Sat Jan 04 23:55:54 2014 +0400 @@ -109,39 +109,6 @@ CurrentTeam^.ExtDriven:= true end; -procedure chGrave(var s: shortstring); -begin -if CurrentTeam = nil then - OutError(errmsgIncorrectUse + ' "/grave"', true); -if s[1]='"' then - Delete(s, 1, 1); -if s[byte(s[0])]='"' then - Delete(s, byte(s[0]), 1); -CurrentTeam^.GraveName:= s -end; - -procedure chFort(var s: shortstring); -begin -if CurrentTeam = nil then - OutError(errmsgIncorrectUse + ' "/fort"', true); -if s[1]='"' then - Delete(s, 1, 1); -if s[byte(s[0])]='"' then - Delete(s, byte(s[0]), 1); -CurrentTeam^.FortName:= s -end; - -procedure chFlag(var s: shortstring); -begin -if CurrentTeam = nil then - OutError(errmsgIncorrectUse + ' "/flag"', true); -if s[1]='"' then - Delete(s, 1, 1); -if s[byte(s[0])]='"' then - Delete(s, byte(s[0]), 1); -CurrentTeam^.flag:= s -end; - procedure chScript(var s: shortstring); begin if s[1]='"' then @@ -152,19 +119,9 @@ ScriptLoad(s) end; -procedure chSetHat(var s: shortstring); +procedure chScriptParam(var s: shortstring); begin -if (not isDeveloperMode) or (CurrentTeam = nil) then exit; -with CurrentTeam^ do - begin - if not CurrentHedgehog^.King then - if (s = '') - or (((GameFlags and gfKing) <> 0) and (s = 'crown')) - or ((Length(s) > 39) and (Copy(s,1,8) = 'Reserved') and (Copy(s,9,32) <> PlayerHash)) then - CurrentHedgehog^.Hat:= 'NoHat' - else - CurrentHedgehog^.Hat:= s - end; + cScriptParam:= s; end; procedure chCurU_p(var s: shortstring); @@ -642,9 +599,14 @@ begin s:=s; // avoid compiler hint if gameType <> gmtNet then - isPaused:= not isPaused; + isPaused:= not isPaused + else + if (CurrentTeam^.ExtDriven) or (CurrentHedgehog^.BotLevel > 0) then + isAFK:= not isAFK + else + isAFK:= false; // for real ninjas -if isPaused then +if isPaused or isAFK then SDL_ShowCursor(1) else SDL_ShowCursor(ord(GameState = gsConfirm)) @@ -652,11 +614,27 @@ procedure chRotateMask(var s: shortstring); begin -s:=s; // avoid compiler hint -if ((GameFlags and gfInvulnerable) = 0) then - cTagsMask:= cTagsMasks[cTagsMask] +s:= s; // avoid compiler hint +// this is just for me, 'cause I thought it'd be fun. using the old precise + switch to keep it out of people's way +if LocalMessage and (gmPrecise or gmSwitch) = (gmPrecise or gmSwitch) then + begin + if UIDisplay <> uiNone then + UIDisplay:= uiNone + else UIDisplay:= uiAll + end +else if LocalMessage and gmPrecise = gmPrecise then + begin + if ((GameFlags and gfInvulnerable) = 0) then + cTagsMask:= cTagsMasks[cTagsMask] + else + cTagsMask:= cTagsMasksNoHealth[cTagsMask] + end else - cTagsMask:= cTagsMasksNoHealth[cTagsMask]; + begin + if UIDisplay <> uiNoTeams then + UIDisplay:= uiNoTeams + else UIDisplay:= uiAll + end end; procedure chSpeedup_p(var s: shortstring); @@ -823,8 +801,8 @@ RegisterVariable('setweap' , @chSetWeapon , false, true); //////// End top by freq analysis RegisterVariable('gencmd' , @chGenCmd , false); - RegisterVariable('flag' , @chFlag , false); RegisterVariable('script' , @chScript , false); + RegisterVariable('scriptparam', @chScriptParam, false); RegisterVariable('proto' , @chCheckProto , true ); RegisterVariable('spectate', @chFastUntilLag , false); RegisterVariable('capture' , @chCapture , true ); @@ -853,9 +831,6 @@ RegisterVariable('gmflags' , @chGameFlags , false); RegisterVariable('turntime', @chHedgehogTurnTime, false); RegisterVariable('minestime',@chMinesTime , false); - RegisterVariable('fort' , @chFort , false); - RegisterVariable('grave' , @chGrave , false); - RegisterVariable('hat' , @chSetHat , false); RegisterVariable('quit' , @chQuit , true ); RegisterVariable('forcequit', @chForceQuit , true ); RegisterVariable('confirm' , @chConfirm , true ); diff -r 8054d9d775fd -r 2759212a27de hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uConsts.pas Sat Jan 04 23:55:54 2014 +0400 @@ -252,6 +252,8 @@ ammoprop_NeedTarget = $00000004; ammoprop_ForwMsgs = $00000008; ammoprop_AttackInMove = $00000010; + ammoprop_DoesntStopTimerWhileAttacking + = $00000020; ammoprop_NoCrosshair = $00000040; ammoprop_AttackingPut = $00000080; ammoprop_DontHold = $00000100; @@ -265,6 +267,8 @@ ammoprop_OscAim = $00010000; ammoprop_NoMoveAfter = $00020000; ammoprop_Track = $00040000; + ammoprop_DoesntStopTimerInMultiShoot + = $00080000; ammoprop_NoRoundEnd = $10000000; AMMO_INFINITE = 100; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGame.pas --- a/hedgewars/uGame.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGame.pas Sat Jan 04 23:55:54 2014 +0400 @@ -90,7 +90,7 @@ if CurrentHedgehog^.BotLevel <> 0 then ProcessBot; ProcessGears; - {$IFDEF SDL2}ProcessTouch;{$ENDIF} + {$IFDEF USE_TOUCH_INTERFACE}ProcessTouch;{$ENDIF} end else begin diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGears.pas --- a/hedgewars/uGears.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGears.pas Sat Jan 04 23:55:54 2014 +0400 @@ -33,7 +33,7 @@ * effects are called "Visual Gears" and defined in the respective unit! *) interface -uses uConsts, uFloat, uTypes; +uses uConsts, uFloat, uTypes, uChat; procedure initModule; procedure freeModule; @@ -47,7 +47,8 @@ procedure AssignHHCoords; function GearByUID(uid : Longword) : PGear; implementation -uses uStore, uSound, uTeams, uRandom, uIO, uLandGraphics, {$IFDEF SDL2}uTouch,{$ENDIF} +uses uStore, uSound, uTeams, uRandom, uIO, uLandGraphics, + {$IFDEF USE_TOUCH_INTERFACE}uTouch,{$ENDIF} uLocale, uAmmos, uStats, uVisualGears, uScript, uVariables, uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture, uGearsHedgehog, uGearsUtils, uGearsList, uGearsHandlersRope @@ -76,7 +77,7 @@ begin if (not isInMultiShoot) then inc(Gear^.Damage, Gear^.Karma); - if ((Gear^.Damage <> 0) and (not Gear^.Invulnerable)) then + if (Gear^.Damage <> 0) and ((Gear^.Hedgehog^.Effects[heInvulnerable] = 0)) then begin CheckNoDamage:= false; @@ -165,13 +166,15 @@ var t: PGear; i, AliveCount: LongInt; s: shortstring; + prevtime: LongWord; begin +prevtime:= TurnTimeLeft; ScriptCall('onGameTick'); if GameTicks mod 20 = 0 then ScriptCall('onGameTick20'); if GameTicks = NewTurnTick then begin ScriptCall('onNewTurn'); -{$IFDEF SDL2} +{$IFDEF USE_TOUCH_INTERFACE} uTouch.NewTurnBeginning(); {$ENDIF} end; @@ -419,8 +422,10 @@ if TurnTimeLeft > 0 then if CurrentHedgehog^.Gear <> nil then - if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) and - (not (isInMultiShoot and (CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle]))) then + if (((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) + or (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_DoesntStopTimerWhileAttacking <> 0)) + and not(isInMultiShoot and ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_DoesntStopTimerInMultiShoot) <> 0)) then + //(CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle]) begin if (TurnTimeLeft = 5000) and (cHedgehogTurnTime >= 10000) @@ -459,7 +464,7 @@ inc(hiTicks) // we do not recieve a message for this end; AddRandomness(CheckSum); - +TurnClockActive:= prevtime <> TurnTimeLeft; inc(GameTicks) end; @@ -504,7 +509,7 @@ if (Gear <> nil) then begin if (GameFlags and gfInvulnerable) = 0 then - Gear^.Invulnerable:= false; + Gear^.Hedgehog^.Effects[heInvulnerable]:= 0; end; end; t:= GearsList; @@ -558,7 +563,7 @@ end; procedure AddMiscGears; -var i,rx, ry: Longword; +var p,i,j,rx, ry: Longword; rdx, rdy: hwFloat; Gear: PGear; temp: Longword; @@ -594,11 +599,13 @@ Gear:= GearsList; if (GameFlags and gfInvulnerable) <> 0 then - while Gear <> nil do - begin - Gear^.Invulnerable:= true; // this is only checked on hogs right now, so no need for gear type check - Gear:= Gear^.NextGear - end; + for p:= 0 to Pred(ClansCount) do + with ClansArray[p]^ do + for j:= 0 to Pred(TeamsNumber) do + with Teams[j]^ do + for i:= 0 to cMaxHHIndex do + with Hedgehogs[i] do + Effects[heInvulnerable]:= 1; if (GameFlags and gfLaserSight) <> 0 then cLaserSighting:= true; @@ -617,7 +624,7 @@ snowRight:= max(LAND_WIDTH,4096)+512; snowLeft:= -(snowRight-LAND_WIDTH); -if (not hasBorder) and ((Theme = 'Snow') or (Theme = 'Christmas')) then +if (not hasBorder) and cSnow then for i:= vobCount * Longword(max(LAND_WIDTH,4096)) div 2048 downto 1 do AddGear(LongInt(GetRandom(snowRight - snowLeft)) + snowLeft, LAND_HEIGHT + LongInt(GetRandom(750)) - 1300, gtFlake, 0, _0, _0, 0); end; @@ -840,6 +847,8 @@ text:= copy(s, 3, Length(s) - 1) else text:= copy(s, 2, Length(s) - 1); + if text = '' then text:= '...'; + (* if CheckNoTeamOrHH then begin @@ -877,9 +886,10 @@ Gear^.Hedgehog:= hh; Gear^.Text:= text; Gear^.FrameTicks:= x - end + end; + //ParseCommand('/say [' + hh^.Name + '] '+text, true) + AddChatString(#1+'[' + HH^.Name + '] '+text); end - //else ParseCommand('say ' + text, true) end else if (x >= 4) then begin diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGearsHandlers.pas --- a/hedgewars/uGearsHandlers.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGearsHandlers.pas Sat Jan 04 23:55:54 2014 +0400 @@ -64,7 +64,7 @@ begin Gear^.Tag := 0; Gear^.Y := Gear^.Y + int2hwFloat(yy); - if not TestCollisionXwithGear(Gear, xxn) then + if TestCollisionXwithGear(Gear, xxn) = 0 then begin Gear^.X := Gear^.X + int2hwFloat(xxn); NextAngle(Gear, dA) @@ -72,7 +72,7 @@ end; if (yy = 0) then - if TestCollisionXwithGear(Gear, xx) then + if TestCollisionXwithGear(Gear, xx) <> 0 then PrevAngle(Gear, dA) else begin diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGearsHandlersMess.pas Sat Jan 04 23:55:54 2014 +0400 @@ -208,7 +208,7 @@ if (gi^.Kind = gtHedgehog) then begin d := r - hwRound(Distance(gi^.X - x, gi^.Y - y)); - if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then + if (d > 1) and ((gi^.Hedgehog^.Effects[heInvulnerable] = 0)) and (GetRandom(2) = 0) then begin if (CurrentHedgehog^.Gear = gi) then PlaySoundV(sndOops, gi^.Hedgehog^.Team^.voicepack) @@ -263,13 +263,13 @@ Gear^.Y := Gear^.Y + cDrownSpeed; Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed; // Create some bubbles (0.5% might be better but causes too few bubbles sometimes) - if (((not SuddenDeathDmg) and (WaterOpacity < $FF)) + if ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble) else if Random(12) = 0 then AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble); - if ((not SuddenDeathDmg) and (WaterOpacity > $FE)) + if (not SuddenDeathDmg and (WaterOpacity > $FE)) or (SuddenDeathDmg and (SDWaterOpacity > $FE)) or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then DeleteGear(Gear); @@ -280,30 +280,33 @@ var isFalling: boolean; //tmp: QWord; - tdX, tdY: hwFloat; - collV, collH: LongInt; - land: word; + tX, tdX, tdY: hwFloat; + collV, collH, gX, gY: LongInt; + land, xland: word; + boing: PVisualGear; begin - WorldWrap(Gear); + tX:= Gear^.X; + gX:= hwRound(Gear^.X); + gY:= hwRound(Gear^.Y); + if (Gear^.Kind <> gtGenericFaller) and WorldWrap(Gear) and (WorldEdge = weWrap) and (Gear^.AdvBounce <> 0) and + ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0)) then + begin + Gear^.X:= tX; + Gear^.dX.isNegative:= (gX > LongInt(leftX) + Gear^.Radius*2) + end; // clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems. -{$IFNDEF WEBGL} if Gear^.dX.Round > 2 then Gear^.dX.QWordValue:= 8589934592; if Gear^.dY.Round > 2 then Gear^.dY.QWordValue:= 8589934592; -{$ELSE} - if Gear^.dX.Round > 2 then - begin - Gear^.dX.Round:= 2; - Gear^.dX.Frac:= 0 + + if (Gear^.State and gstSubmersible <> 0) and (gY > cWaterLine) then + begin + Gear^.dX:= Gear^.dX * _0_999; + Gear^.dY:= Gear^.dY * _0_999 end; - if Gear^.dY.QWordValue > 2 then - begin - Gear^.dY.Round:= 2; - Gear^.dY.Frac:= 0 - end; -{$ENDIF} + Gear^.State := Gear^.State and (not gstCollision); collV := 0; collH := 0; @@ -311,27 +314,32 @@ tdY := Gear^.dY; // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips) - if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048)) - or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then + if (gX < min(LAND_WIDTH div -2, -2048)) + or (gX > max(LAND_WIDTH * 3 div 2, 6144)) then Gear^.State := Gear^.State or gstCollision; if Gear^.dY.isNegative then begin - isFalling := true; land:= TestCollisionYwithGear(Gear, -1); + isFalling := land = 0; if land <> 0 then begin collV := -1; if land and lfIce <> 0 then - Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1) - else - Gear^.dX := Gear^.dX * Gear^.Friction; - - Gear^.dY := - Gear^.dY * Gear^.Elasticity; - Gear^.State := Gear^.State or gstCollision + Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1) + else Gear^.dX := Gear^.dX * Gear^.Friction; + if (Gear^.AdvBounce = 0) or (land and lfBouncy = 0) then + begin + Gear^.dY := - Gear^.dY * Gear^.Elasticity; + Gear^.State := Gear^.State or gstCollision + end + else Gear^.dY := - Gear^.dY * cElastic end - else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then - collV := 1; + else if Gear^.AdvBounce = 1 then + begin + land:= TestCollisionYwithGear(Gear, 1); + if land <> 0 then collV := 1 + end end else begin // Gear^.dY.isNegative is false @@ -345,35 +353,64 @@ else Gear^.dX := Gear^.dX * Gear^.Friction; - Gear^.dY := - Gear^.dY * Gear^.Elasticity; - Gear^.State := Gear^.State or gstCollision + if (Gear^.AdvBounce = 0) or (land and lfBouncy = 0) then + begin + Gear^.dY := - Gear^.dY * Gear^.Elasticity; + Gear^.State := Gear^.State or gstCollision + end + else Gear^.dY := - Gear^.dY * cElastic end else begin isFalling := true; - if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, -1) <> 0) then - collV := -1 + if Gear^.AdvBounce = 1 then + begin + land:= TestCollisionYwithGear(Gear, -1); + if land <> 0 then collV := -1 + end end end; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + xland:= TestCollisionXwithGear(Gear, hwSign(Gear^.dX)); + if xland <> 0 then begin collH := hwSign(Gear^.dX); - Gear^.dX := - Gear^.dX * Gear^.Elasticity; - Gear^.dY := Gear^.dY * Gear^.Elasticity; - Gear^.State := Gear^.State or gstCollision + if (Gear^.AdvBounce = 0) or (xland and lfBouncy = 0) then + begin + Gear^.dX := - Gear^.dX * Gear^.Elasticity; + Gear^.dY := Gear^.dY * Gear^.Elasticity; + Gear^.State := Gear^.State or gstCollision + end + else + begin + Gear^.dX := - Gear^.dX * cElastic; + Gear^.dY := Gear^.dY * cElastic + end end - else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then - collH := -hwSign(Gear^.dX); + else if Gear^.AdvBounce = 1 then + begin + xland:= TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)); + if xland <> 0 then collH := -hwSign(Gear^.dX) + end; //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then - if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1) - or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then - begin - Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction; - Gear^.dY := tdX*Gear^.Elasticity; - //*Gear^.Friction; - Gear^.dY.isNegative := (not tdY.isNegative); + if (collV <> 0) and (collH <> 0) and + (((Gear^.AdvBounce=1) and ((collV=-1) or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)))) then + //or ((xland or land) and lfBouncy <> 0)) then + begin + if (xland or land) and lfBouncy = 0 then + begin + Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction; + Gear^.dY := tdX*Gear^.Elasticity; + Gear^.State := Gear^.State or gstCollision + end + else + begin + Gear^.dX := tdY*cElastic*Gear^.Friction; + Gear^.dY := tdX*cElastic + end; + + Gear^.dY.isNegative := not tdY.isNegative; isFalling := false; Gear^.AdvBounce := 10; end; @@ -386,7 +423,7 @@ Gear^.dY := Gear^.dY + cGravity; if (GameFlags and gfMoreWind) <> 0 then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density - end; + end; Gear^.X := Gear^.X + Gear^.dX; Gear^.Y := Gear^.Y + Gear^.dY; @@ -397,7 +434,28 @@ else Gear^.State := Gear^.State or gstMoving; - if (Gear^.nImpactSounds > 0) and + if ((xland or land) and lfBouncy <> 0) and (Gear^.dX.QWordValue < _0_15.QWordValue) and (Gear^.dY.QWordValue < _0_15.QWordValue) then + Gear^.State := Gear^.State or gstCollision; + + if ((xland or land) and lfBouncy <> 0) and (Gear^.Radius >= 3) and + ((Gear^.dX.QWordValue > _0_15.QWordValue) or (Gear^.dY.QWordValue > _0_15.QWordValue)) then + begin + boing:= AddVisualGear(gX, gY, vgtStraightShot, 0, false, 1); + if boing <> nil then + with boing^ do + begin + Angle:= random(360); + dx:= 0; + dy:= 0; + FrameTicks:= 200; + tX:= _0; + tX.QWordValue:= Gear^.dY.QWordValue + Gear^.dX.QWordValue; + Scale:= hwFloat2Float(Gear^.Density * tX) / 1.5; + State:= ord(sprBoing) + end; + PlaySound(sndMelonImpact, true) + end + else if (Gear^.nImpactSounds > 0) and (Gear^.State and gstCollision <> 0) and (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or @@ -700,6 +758,13 @@ draw:= true; xx:= hwRound(Gear^.X); yy:= hwRound(Gear^.Y); + if draw and (WorldEdge = weWrap) and ((xx < LongInt(leftX) + 3) or (xx > LongInt(rightX) - 3)) then + begin + if xx < LongInt(leftX) + 3 then + xx:= rightX-3 + else xx:= leftX+3; + Gear^.X:= int2hwFloat(xx) + end end else if GameTicks and $7 = 0 then begin @@ -864,21 +929,21 @@ AllInactive := false; if Gear^.dY.isNegative then - if TestCollisionY(Gear, -1) then + if TestCollisionY(Gear, -1) <> 0 then Gear^.dY := _0; - if (not Gear^.dY.isNegative) then - if TestCollisionY(Gear, 1) then - begin + if not Gear^.dY.isNegative then + if TestCollisionY(Gear, 1) <> 0 then + begin Gear^.dY := - Gear^.dY * Gear^.Elasticity; if Gear^.dY > - _1div1024 then - begin + begin Gear^.Active := false; exit - end + end else if Gear^.dY < - _0_03 then PlaySound(Gear^.ImpactSound) - end; + end; Gear^.Y := Gear^.Y + Gear^.dY; CheckGearDrowning(Gear); @@ -924,13 +989,24 @@ if Gear^.Timer = 0 then - Gear^.RenderTimer:= false + begin + // no "fuel"? just fall + doStepFallingGear(Gear); + // if drowning, stop bee sound + if (Gear^.State and gstDrowning) <> 0 then + StopSoundChan(Gear^.SoundChannel); + end else begin if (GameTicks and $F) = 0 then begin if (GameTicks and $30) = 0 then - AddVisualGear(gX, gY, vgtBeeTrace); + begin + if nuw then + AddVisualGear(gX, gY, vgtBubble) + else + AddVisualGear(gX, gY, vgtBeeTrace); + end; Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX)); Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY)); // make sure new speed isn't higher than original one (which we stored in Friction variable) @@ -971,17 +1047,15 @@ end; if (Gear^.Timer > 0) then - dec(Gear^.Timer) - else - begin - Gear^.State:= Gear^.State and (not gstSubmersible); - if nuw then - begin - StopSoundChan(Gear^.SoundChannel); - CheckGearDrowning(Gear); - end - else - doStepFallingGear(Gear); + begin + dec(Gear^.Timer); + if Gear^.Timer = 0 then + begin + // no need to display remaining time anymore + Gear^.RenderTimer:= false; + // bee can drown when timer reached 0 + Gear^.State:= Gear^.State and not gstSubmersible; + end; end; end; @@ -1141,7 +1215,7 @@ Gear^.Y := Gear^.Y + Gear^.dY; tX:= Gear^.X; tY:= Gear^.Y; - if WorldWrap(Gear) then + if (Gear^.PortalCounter < 30) and WorldWrap(Gear) then begin cX:= Gear^.X; cY:= Gear^.Y; @@ -1161,7 +1235,7 @@ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then inc(Gear^.Damage); // let's interrupt before a collision to give portals a chance to catch the bullet - if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (not(CheckLandValue(x, y, lfLandMask))) then + if (Gear^.Damage = 1) and (Gear^.Tag = 0) and not(CheckLandValue(x, y, lfLandMask)) then begin Gear^.Tag := 1; Gear^.Damage := 0; @@ -1188,7 +1262,7 @@ dec(Gear^.Health, Gear^.Damage); Gear^.Damage := 0 end; - if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and (((not SuddenDeathDmg) and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then + if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then begin for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do begin @@ -1374,7 +1448,7 @@ Gear^.X := Gear^.X + Gear^.dX; Gear^.Y := Gear^.Y + _1_9; end; - SetAllHHToActive(true); + SetAllHHToActive; end; if TestCollisionYwithGear(Gear, 1) <> 0 then begin @@ -1649,12 +1723,14 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepSMine(Gear: PGear); + var land: Word; begin // TODO: do real calculation? - if TestCollisionXwithGear(Gear, 2) - or (TestCollisionYwithGear(Gear, -2) <> 0) - or TestCollisionXwithGear(Gear, -2) - or (TestCollisionYwithGear(Gear, 2) <> 0) then + land:= TestCollisionXwithGear(Gear, 2); + if land = 0 then land:= TestCollisionYwithGear(Gear,-2); + if land = 0 then land:= TestCollisionXwithGear(Gear,-2); + if land = 0 then land:= TestCollisionYwithGear(Gear, 2); + if (land <> 0) and (land and lfBouncy = 0) then begin if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then begin @@ -1681,24 +1757,23 @@ Gear^.State := Gear^.State or gstAttacking end else // gstAttacking <> 0 - begin + begin AllInactive := false; if Gear^.Timer = 0 then begin doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); exit - end else + end + else if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick); - - dec(Gear^.Timer); + dec(Gear^.Timer); end - end + end else // gsttmpFlag = 0 - if (TurnTimeLeft = 0) - or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) - or (Gear^.Hedgehog^.Gear = nil) then + if ((GameFlags and gfInfAttack = 0) and ((TurnTimeLeft = 0) or (Gear^.Hedgehog^.Gear = nil))) + or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) then Gear^.State := Gear^.State or gsttmpFlag; end; @@ -1731,7 +1806,7 @@ if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then SetLittle(Gear^.dY); Gear^.State := Gear^.State or gstAnimation; - if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and (not gstFrozen); + if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and not gstFrozen; if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0)) then @@ -1779,7 +1854,7 @@ if Gear^.dX.QWordValue = 0 then AddCI(Gear) end; *) - if (not Gear^.dY.isNegative) and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then + if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then Gear^.dY := _0; if hwAbs(Gear^.dX) < _0_001 then Gear^.dX := _0; @@ -1817,7 +1892,7 @@ Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump)); exit end; - if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and (not gstFrozen); + if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and not gstFrozen; if ((k <> gtExplosives) and (Gear^.Damage > 0)) or ((k = gtExplosives) and (Gear^.Health<=0)) then begin @@ -1924,10 +1999,10 @@ Gear^.dY := Gear^.dY + cGravity; - if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then - Gear^.dY := _0; - - Gear^.Y := Gear^.Y + Gear^.dY; + if ((not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0)) or + (Gear^.dY.isNegative and (TestCollisionYwithGear(Gear, -1) <> 0)) then + Gear^.dY := _0 + else Gear^.Y := Gear^.Y + Gear^.dY; if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive(false); @@ -1962,7 +2037,11 @@ procedure doStepTarget(Gear: PGear); begin if (Gear^.Timer = 0) and (Gear^.Tag = 0) then + begin PlaySound(sndWarp); + // workaround: save spawn Y for doStepCase (which is a mess atm) + Gear^.Angle:= hwRound(Gear^.Y); + end; if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then inc(Gear^.Timer) @@ -2020,6 +2099,7 @@ for i:= 0 to 3 do begin + AddVisualGear(hwRound(Gear^.X) + hwSign(Gear^.dX) * (10 + 6 * i), hwRound(Gear^.Y) + 12 + Random(6), vgtDust); AmmoShove(Gear, 30, 25); Gear^.X := Gear^.X + Gear^.dX * 5 end; @@ -2041,7 +2121,7 @@ begin WorldWrap(Gear); sticky:= (Gear^.State and gsttmpFlag) <> 0; - if (not sticky) then AllInactive := false; + if not sticky then AllInactive := false; landPixel:= TestCollisionYwithGear(Gear, 1); if landPixel = 0 then @@ -2124,7 +2204,7 @@ gX := hwRound(Gear^.X); gY := hwRound(Gear^.Y); // Standard fire - if (not sticky) then + if not sticky then begin if ((GameTicks and $1) = 0) then begin @@ -2150,7 +2230,7 @@ if Gear^.Health > 0 then dec(Gear^.Health); - Gear^.Timer := 450 - Gear^.Tag * 8 + GetRandom(2) + Gear^.Timer := 450 - Gear^.Tag * 8 + LongInt(GetRandom(2)) end else begin @@ -2164,7 +2244,7 @@ end; // This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom. - Gear^.Timer := 100 - Gear^.Tag * 3 + GetRandom(2); + Gear^.Timer := 100 - Gear^.Tag * 3 + LongInt(GetRandom(2)); if (Gear^.Damage > 3000+Gear^.Tag*1500) then Gear^.Health := 0 end @@ -2174,7 +2254,7 @@ begin gX := hwRound(Gear^.X); gY := hwRound(Gear^.Y); - if (not sticky) then + if not sticky then begin if ((GameTicks and $3) = 0) and (Random(1) = 0) then for i:= Random(2) downto 0 do @@ -2213,7 +2293,8 @@ end; HHGear^.dY := HHGear^.dY + cGravity; - if (not HHGear^.dY.isNegative) then + if Gear^.Timer > 0 then dec(Gear^.Timer); + if not (HHGear^.dY.isNegative) or (Gear^.Timer = 0) then begin HHGear^.State := HHGear^.State or gstMoving; DeleteGear(Gear); @@ -2290,7 +2371,7 @@ HHGear^.Y := HHGear^.Y + cGravity * 40; // don't drift into obstacles - if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0 then HHGear^.X := HHGear^.X - int2hwFloat(hwSign(HHGear^.dX)); HHGear^.Y := HHGear^.Y + cGravity * 100; Gear^.X := HHGear^.X; @@ -2322,7 +2403,7 @@ AllInactive := false; Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag; - if (Gear^.Health > 0) and (not (Gear^.X < Gear^.dX)) and (Gear^.X < Gear^.dX + cAirPlaneSpeed) then + if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then begin dec(Gear^.Health); case Gear^.State of @@ -2390,11 +2471,9 @@ begin doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); DeleteGear(Gear); - {$IFNDEF PAS2C} with mobileRecord do if (performRumble <> nil) and (not fastUntilLag) then performRumble(kSystemSoundID_Vibrate); - {$ENDIF} exit end; if (GameTicks and $3F) = 0 then @@ -2408,6 +2487,7 @@ HHGear: PGear; x, y, tx, ty: hwFloat; rx: LongInt; + LandFlags: Word; begin AllInactive := false; @@ -2418,12 +2498,16 @@ y := HHGear^.Y; rx:= hwRound(x); + LandFlags:= 0; + if Gear^.AmmoType = amRubber then LandFlags:= lfBouncy + else if cIce then LandFlags:= lfIce; + if ((Distance(tx - x, ty - y) > _256) and ((WorldEdge <> weWrap) or ( (Distance(tx - int2hwFloat(rightX+(rx-leftX)), ty - y) > _256) and (Distance(tx - int2hwFloat(leftX-(rightX-rx)), ty - y) > _256) ))) - or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false)) then + or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Width div 2, Gear^.Target.Y - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Height div 2, Ammoz[Gear^.AmmoType].PosSprite, Gear^.State, true, false, LandFlags)) then begin PlaySound(sndDenied); HHGear^.Message := HHGear^.Message and (not gmAttack); @@ -2485,9 +2569,9 @@ AllInactive := false; HHGear := Gear^.Hedgehog^.Gear; - if (not (TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2, + if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2, Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2, - sprHHTelepMask, 0, false, false))) then + sprHHTelepMask, 0, false, false) then begin HHGear^.Message := HHGear^.Message and (not gmAttack); HHGear^.State := HHGear^.State and (not gstAttacking); @@ -2499,7 +2583,7 @@ else begin DeleteCI(HHGear); - SetAllHHToActive(true); + SetAllHHToActive; Gear^.doStep := @doStepTeleportAnim; // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog) @@ -2821,7 +2905,7 @@ dmg:= dmgBase - max(hwRound(Distance(tdX, tdY)),gi^.Radius); if (dmg > 1) then dmg:= ModifyDamage(min(dmg div 2, cakeDmg), gi); if (dmg > 1) then - if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then + if (CurrentHedgehog^.Gear = gi) and ((gi^.Hedgehog^.Effects[heInvulnerable] = 0)) then gi^.State := gi^.State or gstLoser else gi^.State := gi^.State or gstWinner; @@ -3072,16 +3156,16 @@ tempColl:= Gear^.CollisionMask; Gear^.CollisionMask:= $007F; - if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then + if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) <> 0) or (GameTicks > Gear^.FlightTime) then t := CheckGearsCollision(Gear) else t := nil; Gear^.CollisionMask:= tempColl; //fixes drill not exploding when touching HH bug if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0)) - or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))) + or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) = 0)) // CheckLandValue returns true if the type isn't matched - or (not (CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible))) then + or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then begin //out of time or exited ground StopSoundChan(Gear^.SoundChannel); @@ -3093,7 +3177,7 @@ exit end - else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))) then + else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) = 0) then begin StopSoundChan(Gear^.SoundChannel); Gear^.Tag := 1; @@ -3251,7 +3335,7 @@ dec(Gear^.Timer); fChanged := false; - if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then + if (HHGear = nil) or ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then begin fChanged := true; if Gear^.Angle > 2048 then @@ -3296,7 +3380,7 @@ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); - if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then + if (HHGear <> nil) and ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then begin HHGear^.Message := HHGear^.Message and (not gmAttack); AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * @@ -3304,7 +3388,7 @@ dec(Gear^.Health) end; - if ((HHGear^.Message and gmLJump) <> 0) and ((Gear^.State and gsttmpFlag) = 0) then + if (HHGear <> nil) and ((HHGear^.Message and gmLJump) <> 0) and ((Gear^.State and gsttmpFlag) = 0) then begin Gear^.State := Gear^.State or gsttmpFlag; PauseMusic; @@ -3471,7 +3555,7 @@ Gear^.X := HHGear^.X; Gear^.Y := HHGear^.Y; - if (not isUnderWater) and hasBorder and ((HHGear^.X < _0) + if not isUnderWater and hasBorder and ((HHGear^.X < _0) or (hwRound(HHGear^.X) > LAND_WIDTH)) then HHGear^.dY.isNegative:= false; @@ -3550,7 +3634,13 @@ HHGear := Gear^.Hedgehog^.Gear; if HHGear = nil then begin - DeleteGear(Gear); + Gear^.Timer := 0; + Gear^.State := Gear^.State or gstAnimation or gstTmpFlag; + Gear^.Timer := 0; + Gear^.doStep := @doStepBirdyDisappear; + CurAmmoGear := nil; + isCursorVisible := false; + AfterAttack; exit end; @@ -3652,14 +3742,21 @@ HHGear: PGear; begin if Gear^.Timer > 0 then - dec(Gear^.Timer, 1) - else if Gear^.Hedgehog^.Gear = nil then - begin - DeleteGear(Gear); + dec(Gear^.Timer, 1); + + HHGear := Gear^.Hedgehog^.Gear; + if HHGear = nil then + begin + Gear^.Timer := 0; + Gear^.State := Gear^.State or gstAnimation or gstTmpFlag; + Gear^.Timer := 0; + Gear^.doStep := @doStepBirdyDisappear; + CurAmmoGear := nil; + isCursorVisible := false; AfterAttack; exit end; - HHGear := Gear^.Hedgehog^.Gear; + HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then begin @@ -3724,9 +3821,7 @@ i: LongInt; begin AllInactive := false; - {$IFNDEF PAS2C} Gear^.dX := Gear^.dX; - {$ENDIF} doStepFallingGear(Gear); // CheckGearDrowning(Gear); // already checked for in doStepFallingGear CalcRotationDirAngle(Gear); @@ -3867,18 +3962,18 @@ // won't port stuff that does not move towards the front/portal entrance if iscake then begin - if (not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative)) then + if not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative) then continue; end else - if (not ((Gear^.dX*ox + Gear^.dY*oy).isNegative)) then + if not ((Gear^.dX*ox + Gear^.dY*oy).isNegative) then continue; isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]); r:= int2hwFloat(iterator^.Radius); - if (not (isbullet or iscake)) then + if not (isbullet or iscake) then begin // wow! good candidate there, let's see if the distance and direction is okay! if hasdxy then @@ -3910,7 +4005,7 @@ oy := (iterator^.Y - Gear^.Y); poffs:= (Gear^.dX * ox + Gear^.dY * oy); - if (not isBullet) and poffs.isNegative then + if not isBullet and poffs.isNegative then continue; // only port bullets close to the portal @@ -3937,7 +4032,7 @@ if Gear^.Elasticity.isNegative then nx.isNegative := (not nx.isNegative) else - ny.isNegative := (not ny.isNegative); + ny.isNegative := not ny.isNegative; // calc gear offset in portal normal vector direction noffs:= (nx * ox + ny * oy); @@ -3946,7 +4041,7 @@ continue; // avoid gravity related loops of not really moving gear - if (not (iscake or isbullet)) + if not (iscake or isbullet) and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative) and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue) @@ -3971,7 +4066,7 @@ if conPortal^.Elasticity.isNegative then nx.isNegative := (not nx.isNegative) else - ny.isNegative := (not ny.isNegative); + ny.isNegative := not ny.isNegative; // inverse cake's normal movement direction, // as if it just walked through a hole @@ -4007,14 +4102,14 @@ iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx; iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny; - if (not hasdxy) and (not (conPortal^.dY.isNegative)) then + if not hasdxy and (not (conPortal^.dY.isNegative)) then begin iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y)) end; // see if the space on the exit side actually is enough - if (not (isBullet or isCake)) then + if not (isBullet or isCake) then begin // TestCollisionXwithXYShift requires a hwFloat for xShift ox.QWordValue := _1.QWordValue; @@ -4027,17 +4122,16 @@ iterator^.Radius := iterator^.Radius - 1; // check front - isCollision := TestCollisionY(iterator, sy) - or TestCollisionX(iterator, sx); - - if (not isCollision) then + isCollision := (TestCollisionY(iterator, sy) <> 0) or (TestCollisionX(iterator, sx) <> 0); + + if not isCollision then begin // check center area (with half the radius so that the // the square check won't check more pixels than we want to) iterator^.Radius := 1 + resetr div 2; rh := resetr div 4; - isCollision := TestCollisionYwithXYShift(iterator, 0, -sy * rh, sy, false) - or TestCollisionXwithXYShift(iterator, ox * rh, 0, sx, false); + isCollision := (TestCollisionYwithXYShift(iterator, 0, -sy * rh, sy, false) <> 0) + or (TestCollisionXwithXYShift(iterator, ox * rh, 0, sx, false) <> 0); end; iterator^.Radius := resetr; @@ -4082,7 +4176,7 @@ resetdy:=hwAbs(iterator^.dX*4); resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx; iterator^.Angle:= hwRound(resetdy*_2048 / _PI); - if (not iterator^.dY.isNegative) then iterator^.Angle:= 2048-iterator^.Angle; + if not iterator^.dY.isNegative then iterator^.Angle:= 2048-iterator^.Angle; if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle; end // VISUAL USE OF ANGLE ONLY @@ -4096,10 +4190,11 @@ if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and (iterator = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) - and (CurAmmoGear^.Kind =gtRope) then + and (CurAmmoGear^.Kind = gtRope) + and (CurAmmoGear^.Elasticity <> _0) then CurAmmoGear^.PortalCounter:= 1; - if (not isbullet) and (iterator^.State and gstInvisible = 0) + if not isbullet and (iterator^.State and gstInvisible = 0) and (iterator^.Kind <> gtFlake) then FollowGear := iterator; @@ -4162,7 +4257,7 @@ Gear^.State := Gear^.State and (not gstMoving); if (Land[y, x] and lfBouncy <> 0) - or (not (CalcSlopeTangent(Gear, x, y, tx, ty, 255))) + or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255)) or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain begin loadNewPortalBall(Gear, true); @@ -4175,7 +4270,7 @@ Gear^.dY := -s * tx; Gear^.DirAngle := DxDy2Angle(-Gear^.dY,Gear^.dX); - if (not Gear^.dX.isNegative) then + if not Gear^.dX.isNegative then Gear^.DirAngle := 180-Gear^.DirAngle; if ((Gear^.LinkedGear = nil) @@ -4265,7 +4360,7 @@ iterator:= GearsList; while iterator <> nil do begin - if (not (iterator^.Kind in [gtPortal, gtAirAttack, gtKnife])) and ((iterator^.Hedgehog <> CurrentHedgehog) + if not (iterator^.Kind in [gtPortal, gtAirAttack, gtKnife]) and ((iterator^.Hedgehog <> CurrentHedgehog) or ((iterator^.Message and gmAllStoppable) = 0)) then begin iterator^.Active:= true; @@ -4520,11 +4615,9 @@ Gear^.dY.isNegative := not Gear^.dY.isNegative; Gear^.doStep := @doStepSineGunShotWork; - {$IFNDEF PAS2C} with mobileRecord do if (performRumble <> nil) and (not fastUntilLag) then performRumble(kSystemSoundID_Vibrate); - {$ENDIF} end; //////////////////////////////////////////////////////////////////////////////// @@ -4705,7 +4798,8 @@ Gear^.dY := Gear^.dY + cGravity / 100; if (GameTicks and $FF) = 0 then doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx or EXPLNoDamage or EXPLDoNotTouchAny or EXPLPoisoned); - AllInactive:= false; + if Gear^.State and gstTmpFlag = 0 then + AllInactive:= false; end; //////////////////////////////////////////////////////////////////////////////// @@ -4732,7 +4826,7 @@ if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then begin //tmp^.State:= tmp^.State or gstFlatened; - if not tmp^.Invulnerable then + if (tmp^.Hedgehog^.Effects[heInvulnerable] = 0) then ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown); //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3); tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0); @@ -5073,7 +5167,7 @@ while t <> nil do begin if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then - t^.Invulnerable:= true; + t^.Hedgehog^.Effects[heInvulnerable]:= 1; t:= t^.NextGear; end; end; @@ -5387,7 +5481,7 @@ if (Timer = iceCollideWithGround) and ((GameTicks - Power) > groundFreezingTime) then begin - FillRoundInLand2(target.x, target.y, iceRadius, icePixel); + FillRoundInLandFT(target.x, target.y, iceRadius, icePixel); landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1); landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1); landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1); @@ -5400,7 +5494,7 @@ begin if (iter^.State and gstFrozen = 0) and ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine)) and - (Distance(iter^.X-int2hwFloat(target.x),iter^.Y-int2hwFloat(target.y)) int2hwFloat(Gear^.Angle)) + (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) > Gear^.Angle) and + (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle))) then begin hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Angle); @@ -5626,9 +5721,9 @@ begin tdX:= HHGear^.X-Gear^.X; dir:= hwSign(tdX); - if (not TestCollisionX(Gear, dir)) then + if TestCollisionX(Gear, dir) = 0 then Gear^.X:= Gear^.X + signAs(_1,tdX); - if TestCollisionXwithXYShift(Gear, signAs(_10,tdX), 0, dir) then + if TestCollisionXwithXYShift(Gear, signAs(_10,tdX), 0, dir) <> 0 then begin Gear^.dX:= SignAs(_0_15, tdX); Gear^.dY:= -_0_3; @@ -5667,9 +5762,9 @@ begin (*ox:= 0; oy:= 0; if TestCollisionYwithGear(Gear, -1) <> 0 then oy:= -1; - if TestCollisionXwithGear(Gear, 1) then ox:= 1; - if TestCollisionXwithGear(Gear, -1) then ox:= -1; - if TestCollisionYwithGear(Gear, 1) <> 0 then oy:= 1; + if TestCollisionXwithGear(Gear, 1) <> 0 then ox:= 1; + if TestCollisionXwithGear(Gear, -1) <> 0 then ox:= -1; + if TestCollisionYwithGear(Gear, 1) <> 0 then oy:= 1; if Gear^.Health > 0 then PlaySound(sndRopeAttach); @@ -5698,9 +5793,9 @@ end else if GameTicks and $3F = 0 then begin - if (TestCollisionYwithGear(Gear, -1) = 0) - and (not (TestCollisionXwithGear(Gear, 1))) - and (not (TestCollisionXwithGear(Gear, -1))) + if (TestCollisionYwithGear(Gear,-1) = 0) + and (TestCollisionXwithGear(Gear, 1) = 0) + and (TestCollisionXwithGear(Gear,-1) = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then Gear^.State:= Gear^.State and (not gstCollision) or gstMoving; end end; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGearsHandlersRope.pas --- a/hedgewars/uGearsHandlersRope.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGearsHandlersRope.pas Sat Jan 04 23:55:54 2014 +0400 @@ -31,9 +31,17 @@ procedure doStepRopeAfterAttack(Gear: PGear); var HHGear: PGear; + tX: hwFloat; begin HHGear := Gear^.Hedgehog^.Gear; - WorldWrap(HHGear); + tX:= HHGear^.X; + if WorldWrap(HHGear) and (WorldEdge = weWrap) and + ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then + begin + HHGear^.X:= tX; + HHGear^.dX.isNegative:= hwRound(tX) > LongInt(leftX) + HHGear^.Radius * 2 + end; + if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then begin DeleteGear(Gear); @@ -54,7 +62,7 @@ HedgehogChAngle(HHGear); - if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0 then SetLittle(HHGear^.dX); if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then @@ -117,8 +125,20 @@ HHGear := Gear^.Hedgehog^.Gear; - if ((HHGear^.State and gstHHDriven) = 0) or WorldWrap(HHGear) - or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then + tX:= HHGear^.X; + if WorldWrap(HHGear) and (WorldEdge = weWrap) and + ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then + begin + PlaySound(sndRopeRelease); + RopeDeleteMe(Gear, HHGear); + HHGear^.X:= tX; + HHGear^.dX.isNegative:= hwRound(tX) > LongInt(leftX) + HHGear^.Radius * 2; + exit + end; + + tX:= HHGear^.X; + if ((HHGear^.State and gstHHDriven) = 0) or + (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then begin PlaySound(sndRopeRelease); RopeDeleteMe(Gear, HHGear); @@ -127,17 +147,17 @@ HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shl 2; HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shl 2; - if (Gear^.Message and gmLeft <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then + if (Gear^.Message and gmLeft <> 0) and (TestCollisionXwithGear(HHGear, -1) = 0) then HHGear^.dX := HHGear^.dX - _0_0032; - if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear, 1)) then + if (Gear^.Message and gmRight <> 0) and (TestCollisionXwithGear(HHGear, 1) = 0) then HHGear^.dX := HHGear^.dX + _0_0032; // vector between hedgehog and rope attaching point ropeDx := HHGear^.X - Gear^.X; ropeDy := HHGear^.Y - Gear^.Y; - if TestCollisionYwithGear(HHGear, 1) = 0 then + if TestCollisionYwithXYShift(HHGear, 0, 1, 1) = 0 then begin // depending on the rope vector we know which X-side to check for collision @@ -148,12 +168,12 @@ cd:= 1; // apply gravity if there is no obstacle - if not TestCollisionXwithGear(HHGear, cd) then + if TestCollisionXwithXYShift(HHGear, _2*cd, 0, cd, true) = 0 then HHGear^.dY := HHGear^.dY + cGravity * 16; if (GameFlags and gfMoreWind) <> 0 then // apply wind if there's no obstacle - if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then + if TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) = 0 then HHGear^.dX := HHGear^.dX + cWindSpeed * 16 / HHGear^.Density; end; @@ -173,13 +193,13 @@ ty := HHGear^.Y; if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then - if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) - or ((ropeDy.QWordValue <> 0) and TestCollisionYwithXYShift(HHGear, 0, 1, hwSign(ropeDy)))) then + if not ((TestCollisionXwithXYShift(HHGear, _2*hwSign(ropeDx), 0, hwSign(ropeDx), true) <> 0) + or ((ropeDy.QWordValue <> 0) and (TestCollisionYwithXYShift(HHGear, 0, 1*hwSign(ropeDy), hwSign(ropeDy)) <> 0))) then Gear^.Elasticity := Gear^.Elasticity + _1_2; if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then - if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) - or ((ropeDy.QWordValue <> 0) and TestCollisionYwithXYShift(HHGear, 0, 1, -hwSign(ropeDy)))) then + if not ((TestCollisionXwithXYShift(HHGear, -_2*hwSign(ropeDx), 0, -hwSign(ropeDx), true) <> 0) + or ((ropeDy.QWordValue <> 0) and (TestCollisionYwithXYShift(HHGear, 0, 1*-hwSign(ropeDy), -hwSign(ropeDy)) <> 0))) then Gear^.Elasticity := Gear^.Elasticity - _1_2; HHGear^.X := Gear^.X + mdX * Gear^.Elasticity; @@ -295,12 +315,12 @@ end; haveCollision := false; - if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + if TestCollisionXwithXYShift(HHGear, _2*hwSign(HHGear^.dX), 0, hwSign(HHGear^.dX), true) <> 0 then begin HHGear^.dX := -_0_6 * HHGear^.dX; haveCollision := true end; - if TestCollisionYwithXYShift(HHGear, 0, 1, hwSign(HHGear^.dY)) then + if TestCollisionYwithXYShift(HHGear, 0, 1*hwSign(HHGear^.dY), hwSign(HHGear^.dY)) <> 0 then begin HHGear^.dY := -_0_6 * HHGear^.dY; haveCollision := true @@ -398,7 +418,7 @@ if (HHGear^.State and gstMoving) <> 0 then begin - if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0 then SetLittle(HHGear^.dX); if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then HHGear^.dY := _0; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGearsHedgehog.pas Sat Jan 04 23:55:54 2014 +0400 @@ -20,7 +20,7 @@ unit uGearsHedgehog; interface -uses uTypes; +uses uTypes, uGearsHandlersMess; procedure doStepHedgehog(Gear: PGear); procedure AfterAttack; @@ -35,10 +35,22 @@ uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, uCommands, uLocale, uUtils, uStats, uIO, uScript, uGearsList, uCollisions, uRandom, uStore, uTeams, - uGearsUtils, uVisualGearsList; + uGearsUtils, uVisualGearsList, uChat; var GHStepTicks: LongWord = 0; +procedure AFKSkip; +var + t: byte; +begin + t:= 0; + while (TeamsArray[t] <> CurrentTeam) do inc(t); + + SendHogSpeech(#1 + char(t) + 'AFK'); + + ParseCommand('/skip', true) +end; + // Shouldn't more of this ammo switching stuff be moved to uAmmos ? function ChangeAmmo(HHGear: PGear): boolean; var slot, i: Longword; @@ -53,7 +65,7 @@ HHGear^.Message:= HHGear^.Message and (not gmSlot); prevAmmo:= CurAmmoType; ammoidx:= 0; - if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0) + if (((HHGear^.State and (gstAttacking or gstAttacked)) <> 0) and (GameFlags and gfInfAttack = 0)) or ((HHGear^.State and gstHHDriven) = 0) then exit; ChangeAmmo:= true; @@ -114,9 +126,9 @@ LoadHedgehogHat(HHGear^.Hedgehog^, Hat); end; // Try again in the next slot - if CurAmmoType = prevAmmo then + if (CurAmmoType = prevAmmo) and (slot < cMaxSlotIndex) then begin - if slot >= cMaxSlotIndex then slot:= 0 else inc(slot); + inc(slot); HHGear^.MsgParam:= slot; ChangeAmmo(HHGear) end @@ -128,6 +140,7 @@ weap: TAmmoType; Hedgehog: PHedgehog; s: boolean; + prevState, newState: LongWord; begin s:= false; @@ -143,12 +156,18 @@ HHGear^.Message:= HHGear^.Message and (not gmWeapon); +prevState:= HHGear^.State; +newState:= prevState; with Hedgehog^ do while (CurAmmoType <> weap) and (t >= 0) do begin s:= ChangeAmmo(HHGear); + if HHGear^.State <> prevState then // so we can keep gstAttacked out of consideration when looping + newState:= HHGear^.State; + HHGear^.State:= prevState; dec(t) end; +HHGear^.State:= newState; if s then ApplyAmmoChanges(HHGear^.Hedgehog^) @@ -334,6 +353,10 @@ amNapalm: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0); amBlowTorch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0); amGirder: newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0); + amRubber: begin + newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0); + newGear^.AmmoType:= amRubber + end; amTeleport: newGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0); amSwitch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0); amMortar: begin @@ -365,7 +388,7 @@ PlaySound(sndHellishImpact4); cDamageModifier:= _1_5 end; - amInvulnerable: Invulnerable:= true; + amInvulnerable: Effects[heInvulnerable]:= 1; amExtraTime: begin PlaySound(sndSwitchHog); TurnTimeLeft:= TurnTimeLeft + 30000 @@ -390,7 +413,7 @@ newGear^.SoundChannel := LoopSound(sndResurrector); end; //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000); - amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000); + amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 0); amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0); end; if altUse and (newGear <> nil) and @@ -425,7 +448,7 @@ amFlamethrower, amLandGun, amResurrector, //amStructure, amTardis, amPiano, - amIceGun: CurAmmoGear:= newGear; + amIceGun, amRubber: CurAmmoGear:= newGear; end; if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then @@ -747,13 +770,13 @@ Gear^.Message:= Gear^.Message and (not gmLJump); DeleteCI(Gear); if TestCollisionYwithGear(Gear, -1) = 0 then - if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then + if TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) = 0 then Gear^.Y:= Gear^.Y - _2 else - if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then + if TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) = 0 then Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.dY:= -_0_15; if not cArtillery then @@ -841,11 +864,21 @@ Gear^.State:= Gear^.State and (not gstMoving); exit end; -isFalling:= (Gear^.dY.isNegative) or (not TestCollisionYKick(Gear, 1)); +isFalling:= (Gear^.dY.isNegative) or (TestCollisionYKick(Gear, 1) = 0); if isFalling then begin - if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then - Gear^.dY:= _0; + land:= TestCollisionYKick(Gear, -1); + if (Gear^.dY.isNegative) and (land <> 0) then + begin + if land and lfBouncy <> 0 then + begin + doStepFallingGear(Gear); + Gear^.dX:= Gear^.dX * _0_8 + end; + if (land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0) then + Gear^.dY:= _0; + Gear^.State:= Gear^.State and not gstCollision + end; Gear^.State:= Gear^.State or gstMoving; if (CurrentHedgehog^.Gear = Gear) and (CurrentHedgehog^.Gear^.State and gstHHDriven <> 0) and (not CurrentTeam^.ExtDriven) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then @@ -870,19 +903,36 @@ else begin land:= TestCollisionYwithGear(Gear, 1); - if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0) + if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0) + and ((land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0)) and ((Gear^.State and gstHHJumping) <> 0) then SetLittle(Gear^.dX); if not Gear^.dY.isNegative then begin + if land and lfBouncy <> 0 then + begin + doStepFallingGear(Gear); + // hogs for some reason have very low friction. slippery little buggers + Gear^.dX:= Gear^.dX * _0_8 + end; + CheckHHDamage(Gear); - if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) - and (Gear^.dX.QWordValue < _0_02.QWordValue) then - Gear^.dX.isNegative:= not Gear^.dX.isNegative; // landing after high jump - Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump)); - Gear^.dY:= _0; + if (land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0) then + begin + if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) + and (Gear^.dX.QWordValue < _0_02.QWordValue) then + begin + if land and lfBouncy <> 0 then + Gear^.dY:= _0; + Gear^.dX.isNegative:= not Gear^.dX.isNegative // landing after high jump + end; + Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump)); + if (land and lfBouncy = 0) or (Gear^.dX.QWordValue < _0_02.QWordValue) then + Gear^.dY:= _0 + end; + Gear^.State:= Gear^.State and not gstCollision end else Gear^.dY:= Gear^.dY + cGravity; @@ -908,43 +958,43 @@ end; if (Gear^.State and gstMoving) <> 0 then - if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then + if TestCollisionXKick(Gear, hwSign(Gear^.dX)) <> 0 then if not isFalling then if hwAbs(Gear^.dX) > _0_01 then - if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) or - (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then + if (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_96; Gear^.Y:= Gear^.Y - _1 end else - if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) or - (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then + if (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_93; Gear^.Y:= Gear^.Y - _2 end else - if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) or - (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then + if (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_9 ; Gear^.Y:= Gear^.Y - _3 end else - if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) or - (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then + if (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_87; Gear^.Y:= Gear^.Y - _4 end else - if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) or - (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then + if (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_84; @@ -978,7 +1028,7 @@ begin Gear^.State:= Gear^.State and (not gstWinner); Gear^.State:= Gear^.State and (not gstMoving); - while (TestCollisionYWithGear(Gear,1) = 0) and (not CheckGearDrowning(Gear)) and (Gear <> nil) do + while (not CheckGearDrowning(Gear)) and (Gear <> nil) and (TestCollisionYWithGear(Gear,1) = 0) do Gear^.Y:= Gear^.Y + _1; // could become nil in CheckGearDrowning if ai's hog fails to respawn in ai survival @@ -995,15 +1045,21 @@ // ARTILLERY but not being moved by explosions Gear^.X:= Gear^.X + Gear^.dX; Gear^.Y:= Gear^.Y + Gear^.dY; - if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1)) - and TestCollisionYwithXYShift(Gear, 0, 1, 1) then + if (not Gear^.dY.isNegative) and (TestCollisionYKick(Gear, 1) = 0) then begin - CheckHHDamage(Gear); - Gear^.dY:= _0; - Gear^.Y:= Gear^.Y + _1 + land:= TestCollisionYwithXYShift(Gear, 0, 1, 1); + if land and lfBouncy <> 0 then + doStepFallingGear(Gear); + + if (land <> 0) and ((land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0)) then + begin + CheckHHDamage(Gear); + Gear^.dY:= _0; + Gear^.Y:= Gear^.Y + _1 + end; + Gear^.State:= Gear^.State and not gstCollision end; - CheckGearDrowning(Gear); // could become nil if ai's hog fails to respawn in ai survival if Gear = nil then exit; // hide target cursor if current hog is drowning @@ -1060,6 +1116,12 @@ exit end; +if isAFK and (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0) then + begin + AFKSkip; + exit + end; + if (HHGear^.State and gstAnimation) <> 0 then begin HHGear^.Message:= 0; @@ -1143,7 +1205,7 @@ HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump)); - if (not cArtillery) and wasJumping and TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then + if (not cArtillery) and wasJumping and (TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0) then SetLittle(HHGear^.dX); if Hedgehog^.Gear <> nil then @@ -1252,7 +1314,7 @@ if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0) and ((Gear^.Hedgehog = nil) or ((Gear^.Hedgehog^.Effects[heFrozen] = 0) or (Gear^.Hedgehog^.Effects[heFrozen] > 255))) - and (not Gear^.dY.isNegative) and (TurnTimeLeft > 0) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then + and (not Gear^.dY.isNegative) and TurnClockActive and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then begin slope:= CalcSlopeBelowGear(Gear); if slope.QWordValue > 730144440 then // ignore mild slopes @@ -1279,10 +1341,22 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepHedgehog(Gear: PGear); +var tX: hwFloat; begin -if WorldWrap(Gear) and (WorldEdge <> weBounce) and - (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) then - CurAmmoGear^.PortalCounter:= 1; +CheckGearDrowning(Gear); +if Gear = nil then exit; +tX:= Gear^.X; +if WorldWrap(Gear) then + begin + if (WorldEdge <> weBounce) and (Gear = CurrentHedgehog^.Gear) and + (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) and (CurAmmoGear^.Elasticity <> _0) then + CurAmmoGear^.PortalCounter:= 1; + if (WorldEdge = weWrap) and ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0)) then + begin + Gear^.X:= tX; + Gear^.dX.isNegative:= (hwRound(tX) > LongInt(leftX) + Gear^.Radius * 2) + end + end; CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel; if (Gear^.Message and gmDestroy) <> 0 then @@ -1290,7 +1364,7 @@ DeleteGear(Gear); exit end; -if GameTicks mod 100 = 0 then CheckIce(Gear); +if GameTicks mod 128 = 0 then CheckIce(Gear); (* if Gear^.Hedgehog^.Effects[heFrozen] > 0 then begin diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGearsList.pas Sat Jan 04 23:55:54 2014 +0400 @@ -223,7 +223,8 @@ gear^.Timer:= 3000 end; gtMelonPiece: begin - gear^.Density:= _2; + gear^.AdvBounce:= 1; + gear^.Density:= _2 end; gtHedgehog: begin gear^.AdvBounce:= 1; @@ -238,16 +239,20 @@ gear^.Hedgehog^.Effects[heResurrectable] := 1; end; gtShell: begin + gear^.Elasticity:= _0_8; + gear^.Friction:= _0_8; gear^.Radius:= 4; gear^.Density:= _1; + gear^.AdvBounce:= 1; end; gtSnowball: begin gear^.ImpactSound:= sndMudballImpact; gear^.nImpactSounds:= 1; gear^.Radius:= 4; - gear^.Elasticity:= _1; - gear^.Friction:= _1; gear^.Density:= _0_5; + gear^.AdvBounce:= 1; + gear^.Elasticity:= _0_8; + gear^.Friction:= _0_8; end; gtFlake: begin @@ -259,9 +264,9 @@ if State and gstTmpFlag = 0 then begin dx.isNegative:= GetRandom(2) = 0; - dx.QWordValue:= $40DA * GetRandom(10000) * 8; + dx.QWordValue:= QWord($40DA) * GetRandom(10000) * 8; dy.isNegative:= false; - dy.QWordValue:= $3AD3 * GetRandom(7000) * 8; + dy.QWordValue:= QWord($3AD3) * GetRandom(7000) * 8; if GetRandom(2) = 0 then dx := -dx end; @@ -329,9 +334,13 @@ gear^.Elasticity:= _0_55; gear^.Friction:= _0_995; gear^.Density:= _1_6; + gear^.AdvBounce:= 1; if gear^.Timer = 0 then gear^.Timer:= 500; end; gtKnife: begin + gear^.AdvBounce:= 1; + gear^.Elasticity:= _0_8; + gear^.Friction:= _0_8; gear^.Density:= _4; gear^.Radius:= 7 end; @@ -343,6 +352,7 @@ if gear^.Timer = 0 then gear^.Timer:= 500 end; gtExplosives: begin + gear^.AdvBounce:= 1; gear^.ImpactSound:= sndGrenadeImpact; gear^.nImpactSounds:= 1; gear^.Radius:= 16; @@ -368,6 +378,9 @@ if gear^.Timer = 0 then gear^.Timer:= 5000; end; gtCluster: begin + gear^.AdvBounce:= 1; + gear^.Elasticity:= _0_8; + gear^.Friction:= _0_8; gear^.Radius:= 2; gear^.Density:= _1_5; gear^.RenderTimer:= true @@ -385,6 +398,7 @@ end end; gtFirePunch: begin + if gear^.Timer = 0 then gear^.Timer:= 3000; gear^.Radius:= 15; gear^.Tag:= Y end; @@ -411,6 +425,7 @@ gear^.Z:= cCurrHHZ+1; end; gtMortar: begin + gear^.AdvBounce:= 1; gear^.Radius:= 4; gear^.Elasticity:= _0_2; gear^.Friction:= _0_08; @@ -445,6 +460,9 @@ if gear^.Timer = 0 then gear^.Timer:= 5000 end; gtDrill: begin + gear^.AdvBounce:= 1; + gear^.Elasticity:= _0_8; + gear^.Friction:= _0_8; if gear^.Timer = 0 then gear^.Timer:= 5000; // Tag for drill strike. if 1 then first impact occured already @@ -477,15 +495,17 @@ gear^.State:= Gear^.State or gstSubmersible end; gtMolotov: begin + gear^.AdvBounce:= 1; gear^.Radius:= 6; - gear^.Density:= _2; + gear^.Density:= _2 end; gtBirdy: begin gear^.Radius:= 16; // todo: check gear^.Health := 2000; - gear^.FlightTime := 2; + gear^.FlightTime := 2 end; gtEgg: begin + gear^.AdvBounce:= 1; gear^.Radius:= 4; gear^.Elasticity:= _0_6; gear^.Friction:= _0_96; @@ -496,7 +516,6 @@ gtPortal: begin gear^.ImpactSound:= sndMelonImpact; gear^.nImpactSounds:= 1; - gear^.AdvBounce:= 0; gear^.Radius:= 17; // set color gear^.Tag:= 2 * gear^.Timer; @@ -536,6 +555,8 @@ gear^.Tag := 47; end; gtNapalmBomb: begin + gear^.Elasticity:= _0_8; + gear^.Friction:= _0_8; if gear^.Timer = 0 then gear^.Timer:= 1000; gear^.Radius:= 5; gear^.Density:= _1_5; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGearsRender.pas --- a/hedgewars/uGearsRender.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGearsRender.pas Sat Jan 04 23:55:54 2014 +0400 @@ -77,7 +77,7 @@ glVertexPointer(2, GL_FLOAT, 0, @RopePoints.rounded[0]); glDrawArrays(GL_LINE_STRIP, 0, RopePoints.Count + 2); - Tint($FF, $FF, $FF, $FF); + untint; glPopMatrix; @@ -235,7 +235,7 @@ DrawSprite(sprHHDeath, ox - 16, oy - 26, Gear^.Pos); Tint(HH^.Team^.Clan^.Color shl 8 or $FF); DrawSprite(sprHHDeath, ox - 16, oy - 26, Gear^.Pos + 8); - Tint($FF, $FF, $FF, $FF); + untint; exit end else if (Gear^.State and gstHHGone) <> 0 then @@ -276,7 +276,7 @@ begin Tint($00, $FF, $40, $40); DrawTextureRotatedF(SpritesData[sprSmokeWhite].texture, 2, 0, 0, sx, sy, 0, 1, 22, 22, (RealTicks shr 36) mod 360); - Tint($FF, $FF, $FF, $FF) + untint end; @@ -375,11 +375,15 @@ CrosshairX := Round(hwRound(Gear^.X) + dx * 80 + GetLaunchX(HH^.CurAmmoType, sign * m, Gear^.Angle)); CrosshairY := Round(hwRound(Gear^.Y) + dy * 80 + GetLaunchY(HH^.CurAmmoType, Gear^.Angle)); - - DrawTextureRotated(HH^.Team^.CrosshairTex, + setTintAdd(true); + Tint(HH^.Team^.Clan^.Color shl 8 or $FF); + DrawTextureRotated(CrosshairTexture, 12, 12, CrosshairX + WorldDx, CrosshairY + WorldDy, 0, - sign * (Gear^.Angle * 180.0) / cMaxAngle); + sign * m * (Gear^.Angle * 180.0) / cMaxAngle); + untint; + setTintAdd(false); end; + hx:= ox + 8 * sign; hy:= oy - 2; aangle:= Gear^.Angle * 180 / cMaxAngle - 90; @@ -434,7 +438,7 @@ Tint(HH^.Team^.Clan^.Color shl 8 or $FF); DrawTextureRotatedF(HatTex, 1.0, -1.0, -6.0, ox, oy, 32, i, 32, 32, i*DxDy2Angle(CurAmmoGear^.dY, CurAmmoGear^.dX) + hAngle); - Tint($FF, $FF, $FF, $FF) + untint end end end; @@ -471,7 +475,7 @@ sign, 32, 32); - Tint($FF, $FF, $FF, $FF) + untint end end; defaultPos:= false @@ -675,18 +679,19 @@ DrawCircle(ox, oy, 248, 4, $FF, $00, $00, $AA); //Tint($FF, $0, $0, $AA); //DrawTexture(ox - 240, oy - 240, SpritesData[sprVampiric].Texture, 10); - //Tint($FF, $FF, $FF, $FF); + //untint; end; amVampiric: DrawSpriteRotatedF(sprHandVamp, hx, hy, (RealTicks div 125) mod 4, sign, aangle); amRCPlane: begin DrawSpriteRotated(sprHandPlane, hx, hy, sign, 0); defaultPos:= false end; + amRubber, amGirder: begin DrawSpriteRotated(sprHandConstruction, hx, hy, sign, aangle); if WorldEdge = weWrap then begin - if hwRound(Gear^.X) < leftX+256 then + if hwRound(Gear^.X) < LongInt(leftX) + 256 then DrawSpriteClipped(sprGirder, rightX+(ox-leftX)-256, oy-256, @@ -844,9 +849,9 @@ sign, 32, 32); - Tint($FF, $FF, $FF, $FF) + untint end; - if HH^.Team^.hasGone then Tint($FF, $FF, $FF, $FF) + if HH^.Team^.hasGone then untint end else begin @@ -869,7 +874,7 @@ sign*m, 32, 32); - Tint($FF, $FF, $FF, $FF) + untint end end end; @@ -929,7 +934,7 @@ DrawTextureCentered(ox, t, Team^.NameTagTex) end; if (cTagsMask and htTransparent) <> 0 then - Tint($FF, $FF, $FF, $FF) + untint end; if (Gear^.State and gstHHDriven) <> 0 then // Current hedgehog begin @@ -957,7 +962,7 @@ DrawSprite(sprVampiric, sx - 24, sy - 24, 0); end; - if Gear^.Invulnerable then + if (Gear^.Hedgehog^.Effects[heInvulnerable] <> 0) then begin Tint($FF, $FF, $FF, max($40, round($FF * abs(1 - ((RealTicks div 2 + Gear^.uid * 491) mod 1500) / 750)))); DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0); @@ -980,7 +985,7 @@ if HH^.Effects[heFrozen] < 150000 then - Tint($FF, $FF, $FF, $FF); + untint; end; @@ -991,7 +996,7 @@ Tint($FF, 0, 0, max($40, round($FF * abs(1 - (RealTicks mod 1500) / 750)))); DrawSprite(sprVampiric, sx - 24, sy - 24, 0); end; - Tint($FF, $FF, $FF, $FF) + untint end; @@ -1029,7 +1034,7 @@ if Gear^.Tag < 0 then aangle:= 360-aangle; Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF); DrawSpriteRotatedF(sprPlane, x, y, 0, Gear^.Tag, aangle - 90); - Tint($FF, $FF, $FF, $FF); + untint; DrawSpriteRotatedF(sprPlane, x, y, 1, Gear^.Tag, aangle - 90) end; gtBall: DrawSpriteRotatedF(sprBalls, x, y, Gear^.Tag,0, Gear^.DirAngle); @@ -1057,7 +1062,7 @@ Tint($f5, $db, $35, max($40, round($FF * abs(1 - (GameTicks mod 1500) / (750 + Gear^.Health))))); //Tint($FF, $FF, $FF, max($40, round($FF * abs(1 - (RealTicks mod 1500) / 750)))); DrawSprite(sprVampiric, x - 24, y - 24, 0); - Tint($FF, $FF, $FF, $FF) + untint end end; gtBee: DrawSpriteRotatedF(sprBee, x, y, (GameTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); @@ -1151,7 +1156,7 @@ gtAirAttack: begin Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF); DrawSpriteRotatedF(sprAirplane, x, y, 0, Gear^.Tag, 0); - Tint($FF, $FF, $FF, $FF); + untint; DrawSpriteRotatedF(sprAirplane, x, y, 1, Gear^.Tag, 0); end; gtAirBomb: DrawSpriteRotated(sprAirBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); @@ -1165,7 +1170,7 @@ gtTarget: begin Tint($FF, $FF, $FF, round($FF * Gear^.Timer / 1000)); DrawSprite(sprTarget, x - 16, y - 16, 0); - Tint($FF, $FF, $FF, $FF); + untint; end; gtMortar: DrawSpriteRotated(sprMortar, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtCake: if Gear^.Pos = 6 then @@ -1219,7 +1224,7 @@ Tint($FF, $FF, $FF, $10); for i:= 8 downto 1 do DrawTextureF(SpritesData[sprPiano].Texture, 1, x, y - hwRound(Gear^.dY * 4 * i), 0, 1, 128, 128); - Tint($FF, $FF, $FF, $FF) + untint end; DrawTextureF(SpritesData[sprPiano].Texture, 1, x, y, 0, 1, 128, 128); end; @@ -1231,13 +1236,13 @@ else Tint($C0, $C0, $00, $C0); DrawTextureRotatedF(SpritesData[sprSmokeWhite].texture, 3, 0, 0, x, y, 0, 1, 22, 22, (RealTicks shr 36 + Gear^.UID * 100) mod 360); - Tint($FF, $FF, $FF, $FF) + untint end; gtResurrector: begin DrawSpriteRotated(sprCross, x, y, 0, 0); Tint($f5, $db, $35, max($00, round($C0 * abs(1 - (GameTicks mod 6000) / 3000)))); DrawTexture(x - 108, y - 108, SpritesData[sprVampiric].Texture, 4.5); - Tint($FF, $FF, $FF, $FF); + untint; end; gtNapalmBomb: DrawSpriteRotated(sprNapalmBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtFlake: if Gear^.State and (gstDrowning or gstTmpFlag) <> 0 then @@ -1250,7 +1255,7 @@ DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1, 0, 0, x, y, 0, 1, 8, 8, Gear^.DirAngle); //DrawSpriteRotated(sprSnowDust, x, y, 0, Gear^.DirAngle); //DrawTexture(x, y, SpritesData[sprVampiric].Texture, 0.1); - Tint($FF, $FF, $FF, $FF); + untint; end else //if not isInLag then begin @@ -1267,7 +1272,7 @@ //DrawSprite(sprFlake, x-SpritesData[sprFlake].Width div 2, y-SpritesData[sprFlake].Height div 2, Gear^.Timer) //DrawSpriteRotatedF(sprFlake, x-SpritesData[sprFlake].Width div 2, y-SpritesData[sprFlake].Height div 2, Gear^.Timer, 1, Gear^.DirAngle); if Gear^.FlightTime > 0 then - Tint($FF, $FF, $FF, $FF); + untint; end; //gtStructure: DrawSprite(sprTarget, x - 16, y - 16, 0); gtTardis: if Gear^.Pos <> 4 then @@ -1278,16 +1283,16 @@ Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or max($00, round(Gear^.Power * (1-abs(0.5 - (GameTicks mod 2000) / 2000))))); DrawSprite(sprTardis, x-24, y-63,0); if Gear^.Pos = 2 then - Tint($FF, $FF, $FF, $FF) + untint else Tint($FF,$FF,$FF,max($00, round(Gear^.Power * (1-abs(0.5 - (GameTicks mod 2000) / 2000))))); DrawSprite(sprTardis, x-24, y-63,1); if Gear^.Pos <> 2 then - Tint($FF, $FF, $FF, $FF) + untint (* Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or max($00, round(Gear^.Power * abs(1 - (RealTicks mod 500) / 250)))); DrawTexture(x-6, y-70, SpritesData[sprVampiric].Texture, 0.25); - Tint($FF, $FF, $FF, $FF) + untint *) end; gtIceGun: begin @@ -1325,7 +1330,7 @@ end; if Gear^.RenderTimer and (Gear^.Tex <> nil) then DrawTextureCentered(x + 8, y + 8, Gear^.Tex); - if Gear^.State and gstFrozen <> 0 then Tint($FF, $FF, $FF, $FF) + if Gear^.State and gstFrozen <> 0 then untint end; end. diff -r 8054d9d775fd -r 2759212a27de hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uGearsUtils.pas Sat Jan 04 23:55:54 2014 +0400 @@ -61,7 +61,6 @@ var doStepHandlers: array[TGearType] of TGearStepProcedure; - implementation uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc, uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore, @@ -136,7 +135,7 @@ //AddFileLog('Damage: ' + inttostr(dmg)); if (Mask and EXPLNoDamage) = 0 then begin - if not Gear^.Invulnerable then + if Gear^.Hedgehog^.Effects[heInvulnerable] = 0 then ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) else Gear^.State:= Gear^.State or gstWinner; @@ -149,29 +148,30 @@ Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser); if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); - if not Gear^.Invulnerable then + if Gear^.Hedgehog^.Effects[heInvulnerable] = 0 then Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner); Gear^.Active:= true; if Gear^.Kind <> gtFlame then FollowGear:= Gear end; - if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) and ((Gear^.State and gstHHDeath) = 0) then + if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heInvulnerable] = 0) and (Gear^.State and gstHHDeath = 0) then Gear^.Hedgehog^.Effects[hePoisoned] := 1; end; end; - gtGrave: begin + gtGrave: if Mask and EXPLDoNotTouchAny = 0 then // Run the calcs only once we know we have a type that will need damage - tdX:= Gear^.X-fX; - tdY:= Gear^.Y-fY; - if LongInt(tdX.Round + tdY.Round + 2) < dmgBase then - dmg:= dmgBase - hwRound(Distance(tdX, tdY)); - if dmg > 1 then begin - dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); - Gear^.dY:= - _0_004 * dmg; - Gear^.Active:= true - end - end; + tdX:= Gear^.X-fX; + tdY:= Gear^.Y-fY; + if LongInt(tdX.Round + tdY.Round + 2) < dmgBase then + dmg:= dmgBase - hwRound(Distance(tdX, tdY)); + if dmg > 1 then + begin + dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); + Gear^.dY:= - _0_004 * dmg; + Gear^.Active:= true + end + end; end; end; Gear:= Gear^.NextGear @@ -250,9 +250,8 @@ end; end end; - if ((GameFlags and gfKarma) <> 0) and - ((GameFlags and gfInvulnerable) = 0) - and (not CurrentHedgehog^.Gear^.Invulnerable) then + if (GameFlags and gfKarma <> 0) and (GameFlags and gfInvulnerable = 0) and + (CurrentHedgehog^.Effects[heInvulnerable] = 0) then begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid inc(CurrentHedgehog^.Gear^.Karma, tmpDmg); CurrentHedgehog^.Gear^.LastDamage := CurrentHedgehog; @@ -302,8 +301,8 @@ end; procedure CheckHHDamage(Gear: PGear); -var - dmg: Longword; +var + dmg: LongInt; i: LongWord; particle: PVisualGear; begin @@ -316,14 +315,14 @@ if dmg < 1 then exit; - for i:= min(12, (3 + dmg div 10)) downto 0 do + for i:= min(12, 3 + dmg div 10) downto 0 do begin particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480); end; - if (Gear^.Invulnerable) then + if ((Gear^.Hedgehog^.Effects[heInvulnerable] <> 0)) then exit; //if _0_6 < Gear^.dY then @@ -598,7 +597,7 @@ tryAgain:= true; if WorldEdge <> weNone then begin - Left:= max(Left,leftX+Gear^.Radius); + Left:= max(Left, LongInt(leftX) + Gear^.Radius); Right:= min(Right,rightX-Gear^.Radius) end; while tryAgain do @@ -610,7 +609,7 @@ repeat inc(x, Delta); cnt:= 0; - y:= min(1024, topY) - 2 * Gear^.Radius; + y:= min(1024, topY) - Gear^.Radius shl 1; while y < cWaterLine do begin repeat @@ -714,7 +713,7 @@ procedure CheckCollision(Gear: PGear); inline; begin - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) + if (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then Gear^.State := Gear^.State or gstCollision else @@ -723,8 +722,8 @@ procedure CheckCollisionWithLand(Gear: PGear); inline; begin - if TestCollisionX(Gear, hwSign(Gear^.dX)) - or TestCollisionY(Gear, hwSign(Gear^.dY)) then + if (TestCollisionX(Gear, hwSign(Gear^.dX)) <> 0) + or (TestCollisionY(Gear, hwSign(Gear^.dY)) <> 0) then Gear^.State := Gear^.State or gstCollision else Gear^.State := Gear^.State and (not gstCollision) @@ -732,25 +731,25 @@ function MakeHedgehogsStep(Gear: PGear) : boolean; begin - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.Y:= Gear^.Y - _1; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.Y:= Gear^.Y - _1; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.Y:= Gear^.Y - _1; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.Y:= Gear^.Y - _1; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.Y:= Gear^.Y - _1; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then begin Gear^.Y:= Gear^.Y - _1; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then Gear^.Y:= Gear^.Y + _6 end else Gear^.Y:= Gear^.Y + _5 else end else Gear^.Y:= Gear^.Y + _4 else @@ -759,7 +758,7 @@ end else Gear^.Y:= Gear^.Y + _1 end; - if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) = 0 then begin Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX); MakeHedgehogsStep:= true @@ -832,7 +831,7 @@ end; if dmg > 0 then begin - if (not t^.Invulnerable) then + if t^.Hedgehog^.Effects[heInvulnerable] = 0 then ApplyDamage(t, Gear^.Hedgehog, dmg, dsBullet) else Gear^.State:= Gear^.State or gstWinner; @@ -928,7 +927,7 @@ Ammo^.Timer:= 0; exit; end; - if (not Gear^.Invulnerable) then + if Gear^.Hedgehog^.Effects[heInvulnerable] = 0 then begin if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then for j:= 1 to max(1,min(3,tmpDmg div 5)) do @@ -978,16 +977,16 @@ Gear^.State:= Gear^.State or gstMoving; if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); // move the gear upwards a bit to throw it over tiny obstacles at start - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then begin - if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithGear(Gear, -1) = 0) then Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithGear(Gear, -1) = 0) then Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) = 0) and + (TestCollisionYwithGear(Gear, -1) = 0) then Gear^.Y:= Gear^.Y - _1; end end; @@ -1230,27 +1229,33 @@ begin WorldWrap:= false; if WorldEdge = weNone then exit(false); -if (hwRound(Gear^.X)-Gear^.Radius < leftX) or - (hwRound(Gear^.X)+Gear^.Radius > rightX) then +if (hwRound(Gear^.X) - Gear^.Radius < LongInt(leftX)) or + (hwRound(Gear^.X) + LongInt(Gear^.Radius) > LongInt(rightX)) then begin if WorldEdge = weWrap then begin - if (hwRound(Gear^.X)-Gear^.Radius < leftX) then - Gear^.X:= int2hwfloat(rightX-Gear^.Radius) - else Gear^.X:= int2hwfloat(leftX+Gear^.Radius) + if (hwRound(Gear^.X) - Gear^.Radius < LongInt(leftX)) then + Gear^.X:= int2hwfloat(rightX - Gear^.Radius) + else Gear^.X:= int2hwfloat(LongInt(leftX) + Gear^.Radius); + LeftImpactTimer:= 150; + RightImpactTimer:= 150 end else if WorldEdge = weBounce then begin - if (hwRound(Gear^.X)-Gear^.Radius < leftX) then + if (hwRound(Gear^.X) - Gear^.Radius < LongInt(leftX)) then begin + LeftImpactTimer:= 333; Gear^.dX.isNegative:= false; - Gear^.X:= int2hwfloat(leftX+Gear^.Radius) + Gear^.X:= int2hwfloat(LongInt(leftX) + Gear^.Radius) end else begin + RightImpactTimer:= 333; Gear^.dX.isNegative:= true; Gear^.X:= int2hwfloat(rightX-Gear^.Radius) - end + end; + if (Gear^.Radius > 2) and (Gear^.dX.QWordValue > _0_001.QWordValue) then + PlaySound(sndMelonImpact) end else if WorldEdge = weSea then begin @@ -1262,7 +1267,7 @@ Gear^.X:= int2hwFloat(PlayWidth)*int2hwFloat(min(max(0,hwRound(Gear^.Y)),PlayHeight))/PlayHeight; Gear^.Y:= int2hwFloat(cWaterLine+cVisibleWater+Gear^.Radius*2); tdx:= Gear^.dX; - Gear^.dX:= Gear^.dY; + Gear^.dX:= -Gear^.dY; Gear^.dY:= tdx; Gear^.dY.isNegative:= true end diff -r 8054d9d775fd -r 2759212a27de hedgewars/uInputHandler.pas --- a/hedgewars/uInputHandler.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uInputHandler.pas Sat Jan 04 23:55:54 2014 +0400 @@ -136,7 +136,9 @@ Trusted:= (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0); - +// REVIEW OR FIXME +// ctrl/cmd + q to close engine and frontend - this seems like a bad idea, since we let people set arbitrary binds, and don't warn them of this. +// There's no confirmation at all // ctrl/cmd + q to close engine and frontend if(KeyDown and (code = SDLK_q)) then begin @@ -167,21 +169,32 @@ if CurrentBinds[code][0] <> #0 then begin if (code > 3) and KeyDown and (not ((CurrentBinds[code] = 'put')) or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) and (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) then bShowAmmoMenu:= false; - if KeyDown then begin + if CurrentBinds[code] = 'switch' then + LocalMessage:= LocalMessage or gmSwitch + else if CurrentBinds[code] = '+precise' then + LocalMessage:= LocalMessage or gmPrecise; + ParseCommand(CurrentBinds[code], Trusted); if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then ParseCommand('gencmd R', true) end else if (CurrentBinds[code][1] = '+') then begin + if CurrentBinds[code] = '+precise' then + LocalMessage:= LocalMessage and not(gmPrecise); s:= CurrentBinds[code]; s[1]:= '-'; ParseCommand(s, Trusted); if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then ParseCommand('gencmd R', true) - end; + end + else + begin + if CurrentBinds[code] = 'switch' then + LocalMessage:= LocalMessage and not(gmSwitch) + end end end; @@ -313,7 +326,7 @@ DefaultBinds[KeyNameToCode('j0a0d')]:= '+right'; DefaultBinds[KeyNameToCode('j0a1u')]:= '+up'; DefaultBinds[KeyNameToCode('j0a1d')]:= '+down'; -for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i); +for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+char(i+48); for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i); loadBinds('dbind', cPathz[ptData] + '/settings.ini'); diff -r 8054d9d775fd -r 2759212a27de hedgewars/uLand.pas --- a/hedgewars/uLand.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uLand.pas Sat Jan 04 23:55:54 2014 +0400 @@ -123,7 +123,7 @@ for x:= 0 to LAND_WIDTH - 1 do for y:= 0 to LAND_HEIGHT - 1 do - if LandPixels[y, x] = 0 then + if Land[y, x] = 0 then if s < y then begin for i:= max(s, y - 8) to y - 1 do @@ -157,7 +157,7 @@ for y:= 0 to LAND_HEIGHT - 1 do for x:= 0 to LAND_WIDTH - 1 do - if LandPixels[y, x] = 0 then + if Land[y, x] = 0 then if s < x then begin for i:= max(s, x - 8) to x - 1 do @@ -190,19 +190,22 @@ procedure ColorizeLand(Surface: PSDL_Surface); var tmpsurf: PSDL_Surface; r: TSDL_Rect; + y: LongWord; // stupid SDL 1.2 uses stupid SmallInt for y which limits us to 32767. But is even worse if LandTex is large, can overflow on 32767 map. begin tmpsurf:= LoadDataImage(ptCurrTheme, 'LandTex', ifCritical or ifIgnoreCaps); r.y:= 0; - while r.y < LAND_HEIGHT do - begin + y:= 0; + while y < LAND_HEIGHT do + begin r.x:= 0; while r.x < LAND_WIDTH do - begin + begin SDL_UpperBlit(tmpsurf, nil, Surface, @r); inc(r.x, tmpsurf^.w) + end; + inc(y, tmpsurf^.h); + r.y:= y end; - inc(r.y, tmpsurf^.h) - end; SDL_FreeSurface(tmpsurf); // freed in freeModule() below @@ -731,26 +734,27 @@ // also try basing cave dimensions on map/template dimensions, if they exist for w:= 0 to 5 do // width of 3 allowed hogs to be knocked through with grenade begin - for y:= topY to LAND_HEIGHT - 1 do - begin - Land[y, leftX + w]:= lfIndestructible; - Land[y, rightX - w]:= lfIndestructible; - if (y + w) mod 32 < 16 then - c:= AMask - else - c:= AMask or RMask or GMask; // FF00FFFF + if (WorldEdge <> weBounce) and (WorldEdge <> weWrap) then + for y:= topY to LAND_HEIGHT - 1 do + begin + Land[y, leftX + w]:= lfIndestructible; + Land[y, rightX - w]:= lfIndestructible; + if (y + w) mod 32 < 16 then + c:= AMask + else + c:= AMask or RMask or GMask; // FF00FFFF - if (cReducedQuality and rqBlurryLand) = 0 then - begin - LandPixels[y, leftX + w]:= c; - LandPixels[y, rightX - w]:= c; - end - else - begin - LandPixels[y div 2, (leftX + w) div 2]:= c; - LandPixels[y div 2, (rightX - w) div 2]:= c; + if (cReducedQuality and rqBlurryLand) = 0 then + begin + LandPixels[y, leftX + w]:= c; + LandPixels[y, rightX - w]:= c; + end + else + begin + LandPixels[y div 2, (leftX + w) div 2]:= c; + LandPixels[y div 2, (rightX - w) div 2]:= c; + end; end; - end; for x:= leftX to rightX do begin diff -r 8054d9d775fd -r 2759212a27de hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uLandGraphics.pas Sat Jan 04 23:55:54 2014 +0400 @@ -40,14 +40,15 @@ procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword); -function FillRoundInLand2(X, Y, Radius: LongInt; fill: fillType): LongWord; +function FillRoundInLandFT(X, Y, Radius: LongInt; fill: fillType): Longword; procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean); function LandBackPixel(x, y: LongInt): LongWord; procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword); procedure DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword); procedure DumpLandToLog(x, y, r: LongInt); procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint); -function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean; +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline; +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean; LandFlags: Word): boolean; implementation uses SDLh, uLandTexture, uVariables, uUtils, uDebug; @@ -170,87 +171,87 @@ end; -function FillLandCircleLine(y, fromPix, toPix: LongInt; fill : fillType): Longword; +function FillLandCircleLineFT(y, fromPix, toPix: LongInt; fill : fillType): Longword; var px, py, i: LongInt; begin //get rid of compiler warning px := 0; py := 0; - FillLandCircleLine := 0; + FillLandCircleLineFT := 0; case fill of backgroundPixel: - for i:= fromPix to toPix do - begin - calculatePixelsCoordinates(i, y, px, py); - inc(FillLandCircleLine, drawPixelBG(i, y, px, py)); - end; + for i:= fromPix to toPix do + begin + calculatePixelsCoordinates(i, y, px, py); + inc(FillLandCircleLineFT, drawPixelBG(i, y, px, py)); + end; ebcPixel: - for i:= fromPix to toPix do - begin - calculatePixelsCoordinates(i, y, px, py); - drawPixelEBC(i, y, px, py); - end; + for i:= fromPix to toPix do + begin + calculatePixelsCoordinates(i, y, px, py); + drawPixelEBC(i, y, px, py); + end; nullPixel: - for i:= fromPix to toPix do - begin - calculatePixelsCoordinates(i, y, px, py); - if ((Land[y, i] and lfIndestructible) = 0) and (not disableLandBack or (Land[y, i] > 255)) then - LandPixels[py, px]:= 0 - end; + for i:= fromPix to toPix do + begin + calculatePixelsCoordinates(i, y, px, py); + if ((Land[y, i] and lfIndestructible) = 0) and (not disableLandBack or (Land[y, i] > 255)) then + LandPixels[py, px]:= 0 + end; icePixel: - for i:= fromPix to toPix do - begin - calculatePixelsCoordinates(i, y, px, py); - DrawPixelIce(i, y, px, py); - end; + for i:= fromPix to toPix do + begin + calculatePixelsCoordinates(i, y, px, py); + DrawPixelIce(i, y, px, py); + end; setNotCurrentMask: - for i:= fromPix to toPix do - begin - Land[y, i]:= Land[y, i] and lfNotCurrentMask; - end; + for i:= fromPix to toPix do + begin + Land[y, i]:= Land[y, i] and lfNotCurrentMask; + end; changePixelSetNotCurrent: - for i:= fromPix to toPix do - begin - if Land[y, i] and lfObjMask > 0 then - Land[y, i]:= (Land[y, i] and lfNotObjMask) or ((Land[y, i] and lfObjMask) - 1); - end; + for i:= fromPix to toPix do + begin + if Land[y, i] and lfObjMask > 0 then + Land[y, i]:= Land[y, i] - 1; + end; setCurrentHog: - for i:= fromPix to toPix do - begin - Land[y, i]:= Land[y, i] or lfCurrentHog - end; + for i:= fromPix to toPix do + begin + Land[y, i]:= Land[y, i] or lfCurrentHog + end; changePixelNotSetNotCurrent: - for i:= fromPix to toPix do - begin - if Land[y, i] and lfObjMask < lfObjMask then - Land[y, i]:= (Land[y, i] and lfNotObjMask) or ((Land[y, i] and lfObjMask) + 1) - end; + for i:= fromPix to toPix do + begin + if Land[y, i] and lfObjMask < lfObjMask then + Land[y, i]:= Land[y, i] + 1 + end; end; end; -function FillLandCircleSegment(x, y, dx, dy: LongInt; fill : fillType): Longword; inline; +function FillLandCircleSegmentFT(x, y, dx, dy: LongInt; fill : fillType): Longword; inline; begin - FillLandCircleSegment := 0; + FillLandCircleSegmentFT := 0; if ((y + dy) and LAND_HEIGHT_MASK) = 0 then - inc(FillLandCircleSegment, FillLandCircleLine(y + dy, Max(x - dx, 0), Min(x + dx, LAND_WIDTH - 1), fill)); + inc(FillLandCircleSegmentFT, FillLandCircleLineFT(y + dy, Max(x - dx, 0), Min(x + dx, LAND_WIDTH - 1), fill)); if ((y - dy) and LAND_HEIGHT_MASK) = 0 then - inc(FillLandCircleSegment, FillLandCircleLine(y - dy, Max(x - dx, 0), Min(x + dx, LAND_WIDTH - 1), fill)); + inc(FillLandCircleSegmentFT, FillLandCircleLineFT(y - dy, Max(x - dx, 0), Min(x + dx, LAND_WIDTH - 1), fill)); if ((y + dx) and LAND_HEIGHT_MASK) = 0 then - inc(FillLandCircleSegment, FillLandCircleLine(y + dx, Max(x - dy, 0), Min(x + dy, LAND_WIDTH - 1), fill)); + inc(FillLandCircleSegmentFT, FillLandCircleLineFT(y + dx, Max(x - dy, 0), Min(x + dy, LAND_WIDTH - 1), fill)); if ((y - dx) and LAND_HEIGHT_MASK) = 0 then - inc(FillLandCircleSegment, FillLandCircleLine(y - dx, Max(x - dy, 0), Min(x + dy, LAND_WIDTH - 1), fill)); + inc(FillLandCircleSegmentFT, FillLandCircleLineFT(y - dx, Max(x - dy, 0), Min(x + dy, LAND_WIDTH - 1), fill)); end; -function FillRoundInLand2(X, Y, Radius: LongInt; fill: fillType): Longword; inline; -var dx, dy, d, r: LongInt; +function FillRoundInLandFT(X, Y, Radius: LongInt; fill: fillType): Longword; inline; +var dx, dy, d: LongInt; begin dx:= 0; dy:= Radius; d:= 3 - 2 * Radius; -r := 0; +FillRoundInLandFT := 0; while (dx < dy) do begin - inc(r, FillLandCircleSegment(x, y, dx, dy, fill)); + inc(FillRoundInLandFT, FillLandCircleSegmentFT(x, y, dx, dy, fill)); if (d < 0) then d:= d + 4 * dx + 6 else @@ -261,9 +262,7 @@ inc(dx) end; if (dx = dy) then - inc(r, FillLandCircleSegment(x, y, dx, dy, fill)); - -FillRoundInLand2:= r + inc (FillRoundInLandFT, FillLandCircleSegmentFT(x, y, dx, dy, fill)); end; @@ -344,13 +343,13 @@ procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean); begin if not doSet and isCurrent then - FillRoundInLand2(X, Y, Radius, setNotCurrentMask) -else if not doSet and (not IsCurrent) then - FillRoundInLand2(X, Y, Radius, changePixelSetNotCurrent) + FillRoundInLandFT(X, Y, Radius, setNotCurrentMask) +else if not doSet and not IsCurrent then + FillRoundInLandFT(X, Y, Radius, changePixelSetNotCurrent) else if doSet and IsCurrent then - FillRoundInLand2(X, Y, Radius, setCurrentHog) -else if doSet and (not IsCurrent) then - FillRoundInLand2(X, Y, Radius, changePixelNotSetNotCurrent); + FillRoundInLandFT(X, Y, Radius, setCurrentHog) +else if doSet and not IsCurrent then + FillRoundInLandFT(X, Y, Radius, changePixelNotSetNotCurrent); end; procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint); @@ -380,11 +379,11 @@ var tx, ty, dx, dy: Longint; begin - DrawExplosion := FillRoundInLand2(x, y, Radius, backgroundPixel); + DrawExplosion := FillRoundInLandFT(x, y, Radius, backgroundPixel); if Radius > 20 then - FillRoundInLand2(x, y, Radius - 15, nullPixel); + FillRoundInLandFT(x, y, Radius - 15, nullPixel); FillRoundInLand(X, Y, Radius, 0); - FillRoundInLand2(x, y, Radius + 4, ebcPixel); + FillRoundInLandFT(x, y, Radius + 4, ebcPixel); tx:= Max(X - Radius - 5, 0); dx:= Min(X + Radius + 5, LAND_WIDTH) - tx; ty:= Max(Y - Radius - 5, 0); @@ -587,7 +586,12 @@ UpdateLandTexture(tx, ddx, ty, ddy, false) end; -function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean; +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline; +begin +TryPlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, indestructible, 0); +end; + +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean; LandFlags: Word): boolean; var X, Y, bpp, h, w, row, col, gx, gy, numFramesFirstCol: LongInt; p: PByteArray; Image: PSDL_Surface; @@ -652,15 +656,12 @@ gY:= (cpY + y) div 2; end; if indestructible then - Land[cpY + y, cpX + x]:= lfIndestructible + Land[cpY + y, cpX + x]:= lfIndestructible or LandFlags else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then // This test assumes lfBasic and lfObject differ only graphically - Land[cpY + y, cpX + x]:= lfBasic + Land[cpY + y, cpX + x]:= lfBasic or LandFlags else - Land[cpY + y, cpX + x]:= lfObject; - // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun - if (Theme = 'Snow') or (Theme = 'Christmas') then - Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or lfIce; - LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^ + Land[cpY + y, cpX + x]:= lfObject or LandFlags; + LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^ end; p:= @(p^[Image^.pitch]); end; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uLandObjects.pas --- a/hedgewars/uLandObjects.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uLandObjects.pas Sat Jan 04 23:55:54 2014 +0400 @@ -26,7 +26,7 @@ procedure FreeLandObjects(); procedure LoadThemeConfig; procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline; -procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word); +procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; LandFlags: Word); procedure BlitImageUsingMask(cpX, cpY: Longword; Image, Mask: PSDL_Surface); procedure AddOnLandObjects(Surface: PSDL_Surface); procedure SetLand(var LandWord: Word; Pixel: LongWord); inline; @@ -94,8 +94,8 @@ begin BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0); end; - -procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word); + +procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; LandFlags: Word); var p: PLongwordArray; x, y: Longword; bpp: LongInt; @@ -128,10 +128,7 @@ LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x]; if (Land[cpY + y, cpX + x] <= lfAllObjMask) and ((p^[x] and AMask) <> 0) then - begin - Land[cpY + y, cpX + x]:= lfObject; - Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or extraFlags - end; + Land[cpY + y, cpX + x]:= lfObject or LandFlags end; p:= @(p^[Image^.pitch shr 2]) end; @@ -280,8 +277,7 @@ rr.x:= x1; while rr.x < x2 do begin - // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun - if (Theme = 'Snow') or (Theme = 'Christmas') then + if cIce then BlitImageAndGenerateCollisionInfo(rr.x, y, min(x2 - rr.x, tmpsurf^.w), tmpsurf, lfIce) else BlitImageAndGenerateCollisionInfo(rr.x, y, min(x2 - rr.x, tmpsurf^.w), tmpsurf); @@ -499,7 +495,7 @@ s:= cPathz[ptCurrTheme] + '/' + cThemeCFGFilename; WriteLnToConsole('Reading objects info...'); f:= pfsOpenRead(s); -TryDo(f <> nil, 'Bad data or cannot access file ' + cThemeCFGFilename, true); +TryDo(f <> nil, 'Bad data or cannot access file ' + s, true); ThemeObjects.Count:= 0; SprayObjects.Count:= 0; @@ -709,6 +705,10 @@ cFlattenFlakes:= true else if key = 'flatten-clouds' then cFlattenClouds:= true + else if key = 'ice' then + cIce:= true + else if key = 'snow' then + cSnow:= true else if key = 'sd-water-top' then begin i:= Pos(',', s); diff -r 8054d9d775fd -r 2759212a27de hedgewars/uPhysFSLayer.pas --- a/hedgewars/uPhysFSLayer.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uPhysFSLayer.pas Sat Jan 04 23:55:54 2014 +0400 @@ -149,10 +149,14 @@ i:= PHYSFS_mount(Str2PChar(PathPrefix), nil, false); AddFileLog('[PhysFS] mount ' + PathPrefix + ': ' + inttostr(i)); - i:= PHYSFS_mount(Str2PChar(UserPathPrefix + '/'), '/', false); - AddFileLog('[PhysFS] mount ' + UserPathPrefix + '/: ' + inttostr(i)); + i:= PHYSFS_mount(Str2PChar(UserPathPrefix + '/Data'), nil, false); + AddFileLog('[PhysFS] mount ' + UserPathPrefix + '/Data: ' + inttostr(i)); hedgewarsMountPackages; + + i:= PHYSFS_mount(Str2PChar(UserPathPrefix), nil, false); + // need access to teams and frontend configs (for bindings) + AddFileLog('[PhysFS] mount ' + UserPathPrefix + ': ' + inttostr(i)); end; procedure freeModule; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uRender.pas --- a/hedgewars/uRender.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uRender.pas Sat Jan 04 23:55:54 2014 +0400 @@ -45,6 +45,7 @@ procedure DrawCircle (X, Y, Radius, Width: LongInt); procedure DrawCircle (X, Y, Radius, Width: LongInt; r, g, b, a: Byte); +procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); procedure DrawFillRect (r: TSDL_Rect); procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); @@ -52,6 +53,8 @@ procedure Tint (r, g, b, a: Byte); inline; procedure Tint (c: Longword); inline; +procedure untint(); inline; +procedure setTintAdd (f: boolean); inline; implementation uses uVariables; @@ -412,6 +415,9 @@ if (X + SpritesData[Sprite].Width > RightX) then r.w:= RightX - X + 1; +if (r.h < r.y) or (r.w < r.x) then + exit; + dec(r.h, r.y); dec(r.w, r.x); @@ -428,6 +434,11 @@ DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale) end; +procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; +begin +DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF) +end; + procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); var VertexBuffer: array [0..1] of TVertex2f; begin @@ -447,8 +458,8 @@ SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer)); glDrawArrays(GL_LINES, 0, Length(VertexBuffer)); - Tint($FF, $FF, $FF, $FF); - + untint; + glPopMatrix; glEnable(GL_TEXTURE_2D); @@ -509,8 +520,7 @@ SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer)); glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); -Tint($FF, $FF, $FF, $FF); - +untint; {$IFDEF GL2} EnableTexture(True); {$ELSE} @@ -522,8 +532,8 @@ procedure DrawCircle(X, Y, Radius, Width: LongInt; r, g, b, a: Byte); begin Tint(r, g, b, a); - DrawCircle(X, Y, Radius, Width); - Tint($FF, $FF, $FF, $FF); + DrawCircle(X, Y, Radius, Width); + untint; end; procedure DrawCircle(X, Y, Radius, Width: LongInt); @@ -666,7 +676,7 @@ begin Tint($FF, $FF, $FF, alpha); DrawTexture(frame.x, frame.y, spritesData[sprite].Texture, buttonScale); - Tint($FF, $FF, $FF, $FF); + untint; end; end; {$ELSE} @@ -680,7 +690,7 @@ nc, tw: Longword; scale:Real = 1.0/255.0; begin - nc:= (a shl 24) or (b shl 16) or (g shl 8) or r; + nc:= (r shl 24) or (g shl 16) or (b shl 8) or a; if nc = lastTint then exit; @@ -706,8 +716,21 @@ procedure Tint(c: Longword); inline; begin + if c = lastTint then exit; Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF)) end; +procedure untint(); inline; +begin + Tint($FF, $FF, $FF, $FF) +end; + +procedure setTintAdd(f: boolean); inline; +begin + if f then + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD) + else + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +end; end. diff -r 8054d9d775fd -r 2759212a27de hedgewars/uScript.pas --- a/hedgewars/uScript.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uScript.pas Sat Jan 04 23:55:54 2014 +0400 @@ -80,7 +80,6 @@ uRenderUtils, uTextures, uLandGraphics, - SDLh, SysUtils, uIO, uVisualGearsList, @@ -99,10 +98,12 @@ ScriptAmmoDelay : shortstring; ScriptAmmoReinforcement : shortstring; ScriptLoaded : boolean; + mapDims : boolean; procedure ScriptPrepareAmmoStore; forward; procedure ScriptApplyAmmoStore; forward; -procedure ScriptSetAmmo(ammo : TAmmoType; count, propability, delay, reinforcement: Byte); forward; +procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte); forward; +procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: Byte); forward; procedure LuaError(s: shortstring); begin @@ -110,6 +111,12 @@ AddChatString(#5 + s); end; +procedure LuaParameterCountError(call, paramsyntax: shortstring; wrongcount: LongInt); +begin + // TODO: i18n? + LuaError('Lua: Wrong number of parameters (' + inttostr(wrongcount) + ') passed to ' + call + '! syntax: ' + call + ' ( ' + paramsyntax + ' )'); +end; + // wrapped calls // // functions called from Lua: @@ -121,7 +128,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to band!'); + LuaParameterCountError('band', 'value1, value2', lua_gettop(L)); lua_pushnil(L); end else @@ -133,7 +140,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to bor!'); + LuaParameterCountError('bor', 'value1, value2', lua_gettop(L)); lua_pushnil(L); end else @@ -145,7 +152,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to bnot!'); + LuaParameterCountError('bnot', 'value', lua_gettop(L)); lua_pushnil(L); end else @@ -157,7 +164,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to div!'); + LuaParameterCountError('div', 'dividend, divisor', lua_gettop(L)); lua_pushnil(L); end else @@ -168,7 +175,7 @@ function lc_getinputmask(L : Plua_State) : LongInt; Cdecl; begin if lua_gettop(L) <> 0 then - LuaError('Lua: Wrong number of parameters passed to GetInputMask!') + LuaParameterCountError('GetInputMask', '', lua_gettop(L)) else lua_pushinteger(L, InputMask); lc_getinputmask:= 1 @@ -177,7 +184,7 @@ function lc_setinputmask(L : Plua_State) : LongInt; Cdecl; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to SetInputMask!') + LuaParameterCountError('SetInputMask', 'mask', lua_gettop(L)) else InputMask:= lua_tointeger(L, 1); lc_setinputmask:= 0 @@ -190,7 +197,7 @@ WriteLnToConsole('Lua: ' + lua_tostring(L ,1)); end else - LuaError('Lua: Wrong number of parameters passed to WriteLnToConsole!'); + LuaParameterCountError('WriteLnToConsole', 'string', lua_gettop(L)); lc_writelntoconsole:= 0; end; @@ -210,7 +217,7 @@ end else - LuaError('Lua: Wrong number of parameters passed to ParseCommand!'); + LuaParameterCountError('ParseCommand', 'string', lua_gettop(L)); lc_parsecommand:= 0; end; @@ -221,7 +228,7 @@ ShowMission(lua_tostring(L, 1), lua_tostring(L, 2), lua_tostring(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); end else - LuaError('Lua: Wrong number of parameters passed to ShowMission!'); + LuaParameterCountError('ShowMission', 'caption, subcaption, text, icon, time', lua_gettop(L)); lc_showmission:= 0; end; @@ -268,7 +275,7 @@ AddCaption(lua_tostring(L, 1), lua_tointeger(L, 2) shr 8, TCapGroup(lua_tointeger(L, 3))); end else - LuaError('Lua: Wrong number of parameters passed to AddCaption!'); + LuaParameterCountError('AddCaption', 'text[, color, captiongroup]', lua_gettop(L)); lc_addcaption:= 0; end; @@ -279,7 +286,7 @@ // to be done end else - LuaError('Lua: Wrong number of parameters passed to CampaignLock!'); + LuaParameterCountError('CampaignLock', 'TODO', lua_gettop(L)); lc_campaignlock:= 0; end; @@ -290,7 +297,7 @@ // to be done end else - LuaError('Lua: Wrong number of parameters passed to CampaignUnlock!'); + LuaParameterCountError('CampaignUnlock', 'TODO', lua_gettop(L)); lc_campaignunlock:= 0; end; @@ -299,7 +306,7 @@ begin if lua_gettop(L) <> 4 then begin - LuaError('Lua: Wrong number of parameters passed to SpawnFakeHealthCrate!'); + LuaParameterCountError('SpawnFakeHealthCrate', 'x, y, explode, poison', lua_gettop(L)); lua_pushnil(L); end else @@ -316,7 +323,7 @@ begin if lua_gettop(L) <> 4 then begin - LuaError('Lua: Wrong number of parameters passed to SpawnFakeAmmoCrate!'); + LuaParameterCountError('SpawnFakeAmmoCrate', 'x, y, explode, poison', lua_gettop(L)); lua_pushnil(L); end else @@ -333,7 +340,7 @@ begin if lua_gettop(L) <> 4 then begin - LuaError('Lua: Wrong number of parameters passed to SpawnFakeUtilityCrate!'); + LuaParameterCountError('SpawnFakeUtilityCrate', 'x, y, explode, poison', lua_gettop(L)); lua_pushnil(L); end else @@ -351,7 +358,7 @@ begin if (lua_gettop(L) < 2) or (lua_gettop(L) > 3) then begin - LuaError('Lua: Wrong number of parameters passed to SpawnHealthCrate!'); + LuaParameterCountError('SpawnHealthCrate', 'x, y[, health]', lua_gettop(L)); lua_pushnil(L); end else @@ -374,7 +381,7 @@ begin if (lua_gettop(L) <> 3) and (lua_gettop(L) <> 4) then begin - LuaError('Lua: Wrong number of parameters passed to SpawnAmmoCrate!'); + LuaParameterCountError('SpawnAmmoCrate', 'x, y, content[, amount]', lua_gettop(L)); lua_pushnil(L); end else @@ -395,7 +402,7 @@ begin if (lua_gettop(L) <> 3) and (lua_gettop(L) <> 4) then begin - LuaError('Lua: Wrong number of parameters passed to SpawnUtilityCrate!'); + LuaParameterCountError('SpawnUtilityCrate', 'x, y, content[, amount]', lua_gettop(L)); lua_pushnil(L); end else @@ -419,7 +426,7 @@ begin if lua_gettop(L) <> 7 then begin - LuaError('Lua: Wrong number of parameters passed to AddGear!'); + LuaParameterCountError('AddGear', 'x, y, gearType, state, dx, dy, timer', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -444,7 +451,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to DeleteGear!'); + LuaParameterCountError('DeleteGear', 'gearUid', lua_gettop(L)); end else begin @@ -463,7 +470,7 @@ begin if lua_gettop(L) <> 5 then begin - LuaError('Lua: Wrong number of parameters passed to AddVisualGear!'); + LuaParameterCountError('AddVisualGear', 'x, y, visualGearType, state, critical', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -491,7 +498,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to DeleteVisualGear!'); + LuaParameterCountError('DeleteVisualGear', 'vgUid', lua_gettop(L)); end else begin @@ -507,7 +514,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetVisualGearValues!'); + LuaParameterCountError('GetVisualGearValues', 'vgUid', lua_gettop(L)); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L) end @@ -541,7 +548,7 @@ begin if lua_gettop(L) <> 11 then begin - LuaError('Lua: Wrong number of parameters passed to SetVisualGearValues!'); + LuaParameterCountError('SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -569,7 +576,7 @@ begin if lua_gettop(L) <> 0 then begin - LuaError('Lua: Wrong number of parameters passed to GetFollowGear!'); + LuaParameterCountError('GetFollowGear', '', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -585,7 +592,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearType!'); + LuaParameterCountError('GetGearType', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -604,7 +611,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearMessage!'); + LuaParameterCountError('GetGearMessage', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -623,7 +630,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearElasticity!'); + LuaParameterCountError('GetGearElasticity', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -641,7 +648,7 @@ var gear : PGear; begin if lua_gettop(L) <> 2 then - LuaError('Lua: Wrong number of parameters passed to SetGearMessage!') + LuaParameterCountError('SetGearMessage', 'gearUid, message', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -656,7 +663,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearPos!'); + LuaParameterCountError('GetGearPos', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -674,7 +681,7 @@ var gear : PGear; begin if lua_gettop(L) <> 2 then - LuaError('Lua: Wrong number of parameters passed to SetGearPos!') + LuaParameterCountError('SetGearPos', 'gearUid, value', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -689,7 +696,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearCollisionMask!'); + LuaParameterCountError('GetGearCollisionMask', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -707,7 +714,7 @@ var gear : PGear; begin if lua_gettop(L) <> 2 then - LuaError('Lua: Wrong number of parameters passed to SetGearCollisionMask!') + LuaParameterCountError('SetGearCollisionMask', 'gearUid, mask', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -721,7 +728,7 @@ var gear : PGear; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to GetHogLevel!') + LuaParameterCountError('GetHogLevel', 'gearUid', lua_gettop(L)) else begin gear := GearByUID(lua_tointeger(L, 1)); @@ -737,7 +744,7 @@ var gear : PGear; begin if lua_gettop(L) <> 2 then - LuaError('Lua: Wrong number of parameters passed to SetHogLevel!') + LuaParameterCountError('SetHogLevel', 'gearUid, level', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -752,7 +759,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetHogClan!'); + LuaParameterCountError('GetHogClan', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -772,7 +779,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetClanColor!'); + LuaParameterCountError('GetClanColor', 'clan', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else lua_pushinteger(L, ClansArray[lua_tointeger(L, 1)]^.Color shl 8 or $FF); @@ -784,15 +791,14 @@ team : PTeam; hh : THedgehog; i, j : LongInt; - r, rr: TSDL_Rect; - texsurf: PSDL_Surface; begin if lua_gettop(L) <> 2 then - LuaError('Lua: Wrong number of parameters passed to SetClanColor!') + LuaParameterCountError('SetClanColor', 'clan, color', lua_gettop(L)) else begin clan := ClansArray[lua_tointeger(L, 1)]; clan^.Color:= lua_tointeger(L, 2) shr 8; + for i:= 0 to Pred(clan^.TeamsNumber) do begin team:= clan^.Teams[i]; @@ -808,24 +814,11 @@ end; FreeTexture(team^.NameTagTex); team^.NameTagTex:= RenderStringTex(clan^.Teams[i]^.TeamName, clan^.Color, fnt16); - r.w:= cTeamHealthWidth + 5; - r.h:= team^.NameTagTex^.h; - - texsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 32, RMask, GMask, BMask, AMask); - TryDo(texsurf <> nil, errmsgCreateSurface, true); - TryDo(SDL_SetColorKey(texsurf, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); + end; - DrawRoundRect(@r, cWhiteColor, cNearBlackColor, texsurf, true); - rr:= r; - inc(rr.x, 2); dec(rr.w, 4); inc(rr.y, 2); dec(rr.h, 4); - DrawRoundRect(@rr, clan^.Color, clan^.Color, texsurf, false); + clan^.HealthTex:= makeHealthBarTexture(cTeamHealthWidth + 5, clan^.Teams[0]^.NameTagTex^.h, clan^.Color); + end; - FreeTexture(team^.HealthTex); - team^.HealthTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf); - MakeCrossHairs - end - end; lc_setclancolor:= 0 end; @@ -834,7 +827,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetHogTeamName!'); + LuaParameterCountError('GetHogTeamName', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -850,12 +843,36 @@ lc_gethogteamname:= 1 end; +function lc_sethogteamname(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if lua_gettop(L) <> 2 then + begin + LuaParameterCountError('SetHogTeamName', 'gearUid, name', lua_gettop(L)); + lua_pushnil(L); // return value on stack (nil) + end + else + begin + gear := GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then + begin + gear^.Hedgehog^.Team^.TeamName := lua_tostring(L, 2); + + FreeTexture(gear^.Hedgehog^.Team^.NameTagTex); + gear^.Hedgehog^.Team^.NameTagTex:= RenderStringTex(gear^.Hedgehog^.Team^.TeamName, gear^.Hedgehog^.Team^.Clan^.Color, fnt16); + end + else + lua_pushnil(L); + end; + lc_sethogteamname:= 1 +end; + function lc_gethogname(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetHogName!'); + LuaParameterCountError('GetHogName', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -873,24 +890,22 @@ function lc_sethogname(L : Plua_State) : LongInt; Cdecl; var gear : PGear; - hogName: ShortString; begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to SetHogName!'); + LuaParameterCountError('SetHogName', 'gearUid, name', lua_gettop(L)); lua_pushnil(L) end else begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then - - hogName:= lua_tostring(L, 2); - gear^.Hedgehog^.Name:= hogName; + begin + gear^.Hedgehog^.Name:= lua_tostring(L, 2); - FreeTexture(gear^.Hedgehog^.NameTagTex); - gear^.Hedgehog^.NameTagTex:= RenderStringTex(gear^.Hedgehog^.Name, gear^.Hedgehog^.Team^.Clan^.Color, fnt16); - + FreeTexture(gear^.Hedgehog^.NameTagTex); + gear^.Hedgehog^.NameTagTex:= RenderStringTex(gear^.Hedgehog^.Name, gear^.Hedgehog^.Team^.Clan^.Color, fnt16) + end end; lc_sethogname:= 0; end; @@ -900,7 +915,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetTimer!'); + LuaParameterCountError('GetTimer', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -919,7 +934,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetHealth!'); + LuaParameterCountError('GetHealth', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -938,7 +953,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetX!'); + LuaParameterCountError('GetX', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -957,7 +972,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetY!'); + LuaParameterCountError('GetY', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -976,7 +991,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to CopyPV!'); + LuaParameterCountError('CopyPV', 'fromGearUid, toGearUid', lua_gettop(L)); end else begin @@ -997,7 +1012,7 @@ var gear : PGear; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to FollowGear!') + LuaParameterCountError('FollowGear', 'gearUid', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1029,13 +1044,14 @@ vgear^.FrameTicks:= lua_tointeger(L, 3); if (vgear^.FrameTicks < 1) or (vgear^.FrameTicks > 3) then vgear^.FrameTicks:= 1; - lua_pushinteger(L, vgear^.Uid) + lua_pushinteger(L, vgear^.Uid); + AddChatString(#1+'[' + gear^.Hedgehog^.Name + '] '+vgear^.text) end end else lua_pushnil(L) end - else LuaError('Lua: Wrong number of parameters passed to HogSay!'); + else LuaParameterCountError('HogSay', 'gearUid, text, manner[, vgState]', lua_gettop(L)); lc_hogsay:= 1 end; @@ -1043,7 +1059,7 @@ var gear, prevgear : PGear; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to SwitchHog!') + LuaParameterCountError('SwitchHog', 'gearUid', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1089,7 +1105,7 @@ AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))); end else begin - LuaError('Lua: Wrong number of parameters passed to AddAmmo!'); + LuaParameterCountError('AddAmmo', 'TODO', lua_gettop(L)); end; lc_addammo:= 0; @@ -1108,7 +1124,7 @@ else SetAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L, 3)) end - else LuaError('Lua: Wrong number of parameters passed to AddAmmo!'); + else LuaParameterCountError('AddAmmo', 'gearUid, ammoType[, ammoCount]', lua_gettop(L)); lc_addammo:= 0 end; @@ -1131,7 +1147,7 @@ end else begin - LuaError('Lua: Wrong number of parameters passed to GetAmmoCount!'); + LuaParameterCountError('GetAmmoCount', 'gearUid, ammoType', lua_gettop(L)); lua_pushnil(L) end; lc_getammocount:= 1 @@ -1142,7 +1158,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to SetHealth!'); + LuaParameterCountError('SetHealth', 'gearUid, health', lua_gettop(L)); end else begin @@ -1151,13 +1167,15 @@ begin gear^.Health:= lua_tointeger(L, 2); - if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then - begin - RenderHealth(gear^.Hedgehog^); - RecountTeamHealth(gear^.Hedgehog^.Team) - end; - - SetAllToActive; + if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then + begin + RenderHealth(gear^.Hedgehog^); + RecountTeamHealth(gear^.Hedgehog^.Team) + end; + // Why did this do a "setalltoactive" ? + //SetAllToActive; + Gear^.Active:= true; + AllInactive:= false end end; lc_sethealth:= 0 @@ -1168,7 +1186,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to SetTimer!'); + LuaParameterCountError('SetTimer', 'gearUid, timer', lua_gettop(L)); end else begin @@ -1182,7 +1200,7 @@ var gear: PGear; begin if lua_gettop(L) <> 3 then - LuaError('Lua: Wrong number of parameters passed to SetEffect!') + LuaParameterCountError('SetEffect', 'gearUid, effect, enabled', lua_gettop(L)) else begin gear := GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Hedgehog <> nil) then @@ -1190,12 +1208,13 @@ end; lc_seteffect := 0; end; + function lc_geteffect(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to GetEffect!'); + LuaParameterCountError('GetEffect', 'gearUid, effect', lua_gettop(L)); end else begin @@ -1213,7 +1232,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to SetState!'); + LuaParameterCountError('SetState', 'gearUid, state', lua_gettop(L)); end else begin @@ -1232,7 +1251,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetState!'); + LuaParameterCountError('GetState', 'gearUid', lua_gettop(L)); end else begin @@ -1250,7 +1269,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetX!'); + LuaParameterCountError('GetTag', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -1269,7 +1288,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to SetTag!'); + LuaParameterCountError('SetTag', 'gearUid, tag', lua_gettop(L)); end else begin @@ -1299,12 +1318,12 @@ if (lua_gettop(L) <> 2) and ((statInfo <> siPlayerKills) and (statInfo <> siClanHealth)) then begin - LuaError('Lua: Wrong number of parameters passed to SendStat! Expected 2 parameters.'); + LuaParameterCountError('SendStat', 'statInfoType, color', lua_gettop(L)); end else if (lua_gettop(L) <> 3) and ((statInfo = siPlayerKills) or (statInfo = siClanHealth)) then begin - LuaError('Lua: Wrong number of parameters passed to SendStat! Expected 3 parameters.'); + LuaParameterCountError('SendStat', 'siClanHealth, color, teamname', lua_gettop(L)); end else begin @@ -1356,7 +1375,7 @@ begin tryhard:= false; if (lua_gettop(L) <> 4) and (lua_gettop(L) <> 5) then - LuaError('Lua: Wrong number of parameters passed to FindPlace!') + LuaParameterCountError('FindPlace', 'gearUid, fall, left, right[, tryHarder]', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1386,7 +1405,7 @@ if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then AddVoice(TSound(lua_tointeger(L, 1)),gear^.Hedgehog^.Team^.Voicepack) end - else LuaError('Lua: Wrong number of parameters passed to PlaySound!'); + else LuaParameterCountError('PlaySound', 'soundId', lua_gettop(L)); lc_playsound:= 0; end; @@ -1396,7 +1415,7 @@ np:= lua_gettop(L); if (np < 5) or (np > 6) then begin - LuaError('Lua: Wrong number of parameters passed to AddTeam!'); + LuaParameterCountError('AddTeam', 'teamname, color, grave, fort, voicepack[, flag]', lua_gettop(L)); //lua_pushnil(L) end else @@ -1418,7 +1437,7 @@ begin if lua_gettop(L) <> 4 then begin - LuaError('Lua: Wrong number of parameters passed to AddHog!'); + LuaParameterCountError('AddHog', 'hogname, botlevel, health, hat', lua_gettop(L)); lua_pushnil(L) end else @@ -1436,7 +1455,7 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to HogTurnLeft!'); + LuaParameterCountError('HogTurnLeft', 'gearUid, boolean', lua_gettop(L)); end else begin @@ -1452,7 +1471,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearPosition!'); + LuaParameterCountError('GetGearPosition', 'gearUid', lua_gettop(L)); lua_pushnil(L); lua_pushnil(L) end @@ -1479,7 +1498,7 @@ x, y: LongInt; begin if lua_gettop(L) <> 3 then - LuaError('Lua: Wrong number of parameters passed to SetGearPosition!') + LuaParameterCountError('SetGearPosition', 'gearUid, x, y', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1505,7 +1524,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearTarget!'); + LuaParameterCountError('GetGearTarget', 'gearUid', lua_gettop(L)); lua_pushnil(L); lua_pushnil(L) end @@ -1530,7 +1549,7 @@ var gear: PGear; begin if lua_gettop(L) <> 3 then - LuaError('Lua: Wrong number of parameters passed to SetGearTarget!') + LuaParameterCountError('SetGearTarget', 'gearUid, x, y', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1549,7 +1568,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearVelocity!'); + LuaParameterCountError('GetGearVelocity', 'gearUid', lua_gettop(L)); lua_pushnil(L); lua_pushnil(L) end @@ -1572,7 +1591,7 @@ var gear: PGear; begin if lua_gettop(L) <> 3 then - LuaError('Lua: Wrong number of parameters passed to SetGearVelocity!') + LuaParameterCountError('SetGearVelocity', 'gearUid, dx, dy', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1589,7 +1608,7 @@ function lc_setzoom(L : Plua_State) : LongInt; Cdecl; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to SetZoom!') + LuaParameterCountError('SetZoom', 'zoomLevel', lua_gettop(L)) else begin ZoomValue:= lua_tonumber(L, 1); @@ -1605,7 +1624,7 @@ begin if lua_gettop(L) <> 0 then begin - LuaError('Lua: Wrong number of parameters passed to GetZoom!'); + LuaParameterCountError('GetZoom', '', lua_gettop(L)); lua_pushnil(L) end else @@ -1618,7 +1637,7 @@ begin np:= lua_gettop(L); if (np < 4) or (np > 5) then - LuaError('Lua: Wrong number of parameters passed to SetAmmo!') + LuaParameterCountError('SetAmmo', 'ammoType, count, probability, delay[, numberInCrate]', lua_gettop(L)) else if np = 4 then ScriptSetAmmo(TAmmoType(lua_tointeger(L, 1)), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), 1) else @@ -1626,12 +1645,23 @@ lc_setammo:= 0 end; +function lc_setammodelay(L : Plua_State) : LongInt; Cdecl; +var np: LongInt; +begin + np:= lua_gettop(L); + if (np <> 2) then + LuaParameterCountError('SetAmmoDelay', 'ammoType, delay', lua_gettop(L)) + else + ScriptSetAmmoDelay(TAmmoType(lua_tointeger(L, 1)), lua_tointeger(L, 2)); + lc_setammodelay:= 0 +end; + function lc_setammostore(L : Plua_State) : LongInt; Cdecl; var np: LongInt; begin np:= lua_gettop(L); if (np <> 4) then - LuaError('Lua: Wrong number of parameters passed to SetAmmoStore!') + LuaParameterCountError('SetAmmoStore', 'loadouts, probabilities, delays, reinforments', lua_gettop(L)) else begin ScriptAmmoLoadout:= lua_tostring(L, 1); @@ -1647,7 +1677,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetRandom!'); + LuaParameterCountError('GetRandom', 'number', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -1667,7 +1697,7 @@ function lc_setwind(L : Plua_State) : LongInt; Cdecl; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to SetWind!') + LuaParameterCountError('SetWind', 'windSpeed', lua_gettop(L)) else begin cWindSpeed:= int2hwfloat(lua_tointeger(L, 1)) / 100 * cMaxWindSpeed; @@ -1683,7 +1713,7 @@ begin if lua_gettop(L) <> 0 then begin - LuaError('Lua: Wrong number of parameters passed to GetDataPath!'); + LuaParameterCountError('GetDataPath', '', lua_gettop(L)); lua_pushnil(L); end else @@ -1695,7 +1725,7 @@ begin if lua_gettop(L) <> 0 then begin - LuaError('Lua: Wrong number of parameters passed to GetUserDataPath!'); + LuaParameterCountError('GetUserDataPath', '', lua_gettop(L)); lua_pushnil(L); end else @@ -1707,7 +1737,7 @@ begin if lua_gettop(L) <> 0 then begin - LuaError('Lua: Wrong number of parameters passed to MapHasBorder!'); + LuaParameterCountError('MapHasBorder', '', lua_gettop(L)); lua_pushnil(L); end else @@ -1720,7 +1750,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to GetGearRadius!'); + LuaParameterCountError('GetGearRadius', 'gearUid', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -1738,7 +1768,7 @@ var gear : PGear; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to GetHogHat!') + LuaParameterCountError('GetHogHat', 'gearUid', lua_gettop(L)) else begin gear := GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then @@ -1755,20 +1785,22 @@ begin if lua_gettop(L) <> 2 then begin - LuaError('Lua: Wrong number of parameters passed to SetHogHat!'); + LuaParameterCountError('SetHogHat', 'gearUid, hat', lua_gettop(L)); lua_pushnil(L) end else begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then + begin hat:= lua_tostring(L, 2); gear^.Hedgehog^.Hat:= hat; -AddFileLog('Changed hat to: '+hat); + AddFileLog('Changed hat to: '+hat); if (Length(hat) > 39) and (Copy(hat,1,8) = 'Reserved') and (Copy(hat,9,32) = gear^.Hedgehog^.Team^.PlayerHash) then LoadHedgehogHat(gear^.Hedgehog^, 'Reserved/' + Copy(hat,9,Length(hat)-8)) else - LoadHedgehogHat(gear^.Hedgehog^, hat); + LoadHedgehogHat(gear^.Hedgehog^, hat) + end end; lc_sethoghat:= 0; end; @@ -1776,7 +1808,7 @@ function lc_placegirder(L : Plua_State) : LongInt; Cdecl; begin if lua_gettop(L) <> 3 then - LuaError('Lua: Wrong number of parameters passed to PlaceGirder!') + LuaParameterCountError('PlaceGirder', 'x, y, state', lua_gettop(L)) else TryPlaceOnLand( lua_tointeger(L, 1) - SpritesData[sprAmGirder].Width div 2, @@ -1788,7 +1820,7 @@ function lc_getcurammotype(L : Plua_State): LongInt; Cdecl; begin if lua_gettop(L) <> 0 then - LuaError('Lua: Wrong number of parameters passed to GetCurAmmoType!') + LuaParameterCountError('GetCurAmmoType', '', lua_gettop(L)) else lua_pushinteger(L, ord(CurrentHedgehog^.CurAmmoType)); lc_getcurammotype := 1; @@ -1797,7 +1829,7 @@ function lc_savecampaignvar(L : Plua_State): LongInt; Cdecl; begin if lua_gettop(L) <> 2 then - LuaError('Lua: Wrong number of parameters passed to SaveCampaignVar!') + LuaParameterCountError('SaveCampaignVar', 'varname, value', lua_gettop(L)) else begin SendIPC('V!' + lua_tostring(L, 1) + ' ' + lua_tostring(L, 2) + #0); end; @@ -1807,9 +1839,9 @@ function lc_getcampaignvar(L : Plua_State): LongInt; Cdecl; begin if (lua_gettop(L) <> 1) then - LuaError('Lua: Wrong number of parameters passed to GetCampaignVar!') + LuaParameterCountError('GetCampaignVar', 'varname', lua_gettop(L)) else - SendIPCAndWaitReply('V?' + lua_tostring(L, 1)); + SendIPCAndWaitReply('V?' + lua_tostring(L, 1) + #0); lua_pushstring(L, str2pchar(CampaignVariable)); lc_getcampaignvar := 1; end; @@ -1818,7 +1850,7 @@ var gear: PGear; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to HideHog!') + LuaParameterCountError('HideHog', 'gearUid', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1832,7 +1864,7 @@ uid: LongWord; begin if lua_gettop(L) <> 1 then - LuaError('Lua: Wrong number of parameters passed to RestoreHog!') + LuaParameterCountError('RestoreHog', 'gearUid', lua_gettop(L)) else begin uid:= LongWord(lua_tointeger(L, 1)); @@ -1854,7 +1886,7 @@ begin if lua_gettop(L) <> 5 then begin - LuaError('Lua: Wrong number of parameters passed to TestRectForObstacle!'); + LuaParameterCountError('TestRectForObstacle', 'x1, y1, x2, y2, landOnly', lua_gettop(L)); lua_pushnil(L); // return value on stack (nil) end else @@ -1872,11 +1904,57 @@ end; +function lc_getgravity(L : Plua_State) : LongInt; Cdecl; +begin + if lua_gettop(L) <> 0 then + LuaParameterCountError('GetGravity', '', lua_gettop(L)) + else + lua_pushinteger(L, hwRound(cGravity * 50 / cWindSpeed)); + lc_getgravity:= 1 +end; + +function lc_setgravity(L : Plua_State) : LongInt; Cdecl; +begin + if lua_gettop(L) <> 1 then + LuaParameterCountError('SetGravity', 'gravity', lua_gettop(L)) + else + begin + cGravity:= cMaxWindSpeed * lua_tointeger(L, 1) * _0_02; + cGravityf:= 0.00025 * lua_tointeger(L, 1) * 0.02 + end; + lc_setgravity:= 0 +end; + +function lc_setwaterline(L : Plua_State) : LongInt; Cdecl; +var iterator: PGear; +begin + if lua_gettop(L) <> 1 then + LuaParameterCountError('SetWaterLine', 'waterline', lua_gettop(L)) + else + begin + cWaterLine:= lua_tointeger(L,1); + AllInactive:= false; + iterator:= GearsList; + while iterator <> nil do + begin + if not (iterator^.Kind in [gtPortal, gtAirAttack]) and (iterator^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) then + begin + iterator^.Active:= true; + if iterator^.dY.QWordValue = 0 then iterator^.dY.isNegative:= false; + iterator^.State:= iterator^.State or gstMoving; + DeleteCI(iterator) + end; + iterator:= iterator^.NextGear + end + end; + lc_setwaterline:= 0 +end; + function lc_setaihintsongear(L : Plua_State) : LongInt; Cdecl; var gear: PGear; begin if lua_gettop(L) <> 2 then - LuaError('Lua: Wrong number of parameters passed to SetAIHintOnGear!') + LuaParameterCountError('SetAIHintOnGear', 'gearUid, aiHints', lua_gettop(L)) else begin gear:= GearByUID(lua_tointeger(L, 1)); @@ -1891,7 +1969,7 @@ begin if lua_gettop(L) <> 1 then begin - LuaError('Lua: Wrong number of parameters passed to HedgewarsScriptLoad!'); + LuaParameterCountError('HedgewarsScriptLoad', 'scriptPath', lua_gettop(L)); lua_pushnil(L) end else @@ -1901,10 +1979,9 @@ function lc_declareachievement(L : Plua_State) : LongInt; Cdecl; -var gear: PGear; begin if lua_gettop(L) <> 4 then - LuaError('Lua: Wrong number of parameters passed to DeclareAchievement!') + LuaParameterCountError('DeclareAchievement', 'achievementId, teamname, location, value', lua_gettop(L)) else declareAchievement(lua_tostring(L, 1), lua_tostring(L, 2), lua_tostring(L, 3), lua_tointeger(L, 4)); lc_declareachievement:= 0 @@ -1993,10 +2070,11 @@ ScriptSetInteger('SuddenDeathTurns', cSuddenDTurns); ScriptSetInteger('WaterRise', cWaterRise); ScriptSetInteger('HealthDecrease', cHealthDecrease); +ScriptSetInteger('GetAwayTime', cGetAwayTime); ScriptSetString('Map', cMapName); - ScriptSetString('Theme', ''); ScriptSetString('Goals', ''); +ScriptSetString('ScriptParam', cScriptParam); ScriptCall('onGameInit'); @@ -2021,6 +2099,7 @@ cSuddenDTurns := ScriptGetInteger('SuddenDeathTurns'); cWaterRise := ScriptGetInteger('WaterRise'); cHealthDecrease := ScriptGetInteger('HealthDecrease'); +cGetAwayTime := ScriptGetInteger('GetAwayTime'); if cMapName <> ScriptGetString('Map') then ParseCommand('map ' + ScriptGetString('Map'), true, true); @@ -2069,7 +2148,8 @@ end; ScriptSetInteger('ClansCount', ClansCount); -ScriptSetInteger('TeamsCount', TeamsCount) +ScriptSetInteger('TeamsCount', TeamsCount); +mapDims:= false end; @@ -2092,7 +2172,10 @@ begin s:= cPathz[ptData] + name; if not pfsExists(s) then + begin + AddFileLog('[LUA] Script not found: ' + name); exit; + end; f:= pfsOpenRead(s); if f = nil then @@ -2123,8 +2206,9 @@ ScriptSetInteger('GameTime', GameTicks); ScriptSetInteger('TotalRounds', TotalRounds); ScriptSetInteger('WaterLine', cWaterLine); -if GameTicks = 0 then +if not mapDims then begin + mapDims:= true; ScriptSetInteger('LAND_WIDTH', LAND_WIDTH); ScriptSetInteger('LAND_HEIGHT', LAND_HEIGHT); ScriptSetInteger('LeftX', leftX); @@ -2245,17 +2329,30 @@ end; end; -procedure ScriptSetAmmo(ammo : TAmmoType; count, propability, delay, reinforcement: Byte); +procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte); begin -//if (ord(ammo) < 1) or (count > 9) or (count < 0) or (propability < 0) or (propability > 8) or (delay < 0) or (delay > 9) or (reinforcement < 0) or (reinforcement > 8) then -if (ord(ammo) < 1) or (count > 9) or (propability > 8) or (delay > 9) or (reinforcement > 8) then +//if (ord(ammo) < 1) or (count > 9) or (count < 0) or (probability < 0) or (probability > 8) or (delay < 0) or (delay > 9) or (reinforcement < 0) or (reinforcement > 8) then +if (ord(ammo) < 1) or (count > 9) or (probability > 8) or (delay > 9) or (reinforcement > 8) then exit; ScriptAmmoLoadout[ord(ammo)]:= inttostr(count)[1]; -ScriptAmmoProbability[ord(ammo)]:= inttostr(propability)[1]; -ScriptAmmoDelay[ord(ammo)]:= inttostr(delay)[1]; +ScriptAmmoProbability[ord(ammo)]:= inttostr(probability)[1]; +ScriptSetAmmoDelay(ammo, delay); ScriptAmmoReinforcement[ord(ammo)]:= inttostr(reinforcement)[1]; end; +procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: Byte); +begin +// change loadout string if ammo store hasn't been initialized yet +if (StoreCnt = 0) then +begin + if (delay <= 9) then + ScriptAmmoDelay[ord(ammo)]:= inttostr(delay)[1]; +end +// change "live" delay values +else if (CurrentTeam <> nil) then + ammoz[ammo].SkipTurns:= CurrentTeam^.Clan^.TurnNumber + delay; +end; + procedure ScriptApplyAmmoStore; var i, j, k : LongInt; begin @@ -2314,6 +2411,7 @@ var at : TGearType; vgt: TVisualGearType; am : TAmmoType; + si : TStatInfoType; st : TSound; he : THogEffect; cg : TCapGroup; @@ -2376,7 +2474,6 @@ ScriptSetInteger('gmPrecise', gmPrecise); ScriptSetInteger('gmAllStoppable', gmAllStoppable); - // speech bubbles ScriptSetInteger('SAY_SAY', 1); ScriptSetInteger('SAY_THINK', 2); @@ -2397,6 +2494,9 @@ for am:= Low(TAmmoType) to High(TAmmoType) do ScriptSetInteger(EnumToStr(am), ord(am)); +for si:= Low(TStatInfoType) to High(TStatInfoType) do + ScriptSetInteger(EnumToStr(si), ord(si)); + for he:= Low(THogEffect) to High(THogEffect) do ScriptSetInteger(EnumToStr(he), ord(he)); @@ -2471,6 +2571,7 @@ lua_register(luaState, _P'HideMission', @lc_hidemission); lua_register(luaState, _P'AddCaption', @lc_addcaption); lua_register(luaState, _P'SetAmmo', @lc_setammo); +lua_register(luaState, _P'SetAmmoDelay', @lc_setammodelay); lua_register(luaState, _P'SetAmmoStore', @lc_setammostore); lua_register(luaState, _P'PlaySound', @lc_playsound); lua_register(luaState, _P'AddTeam', @lc_addteam); @@ -2485,6 +2586,7 @@ lua_register(luaState, _P'GetClanColor', @lc_getclancolor); lua_register(luaState, _P'SetClanColor', @lc_setclancolor); lua_register(luaState, _P'GetHogTeamName', @lc_gethogteamname); +lua_register(luaState, _P'SetHogTeamName', @lc_sethogteamname); lua_register(luaState, _P'GetHogName', @lc_gethogname); lua_register(luaState, _P'SetHogName', @lc_sethogname); lua_register(luaState, _P'GetHogLevel', @lc_gethoglevel); @@ -2525,6 +2627,9 @@ lua_register(luaState, _P'PlaceGirder', @lc_placegirder); lua_register(luaState, _P'GetCurAmmoType', @lc_getcurammotype); lua_register(luaState, _P'TestRectForObstacle', @lc_testrectforobstacle); +lua_register(luaState, _P'GetGravity', @lc_getgravity); +lua_register(luaState, _P'SetGravity', @lc_setgravity); +lua_register(luaState, _P'SetWaterLine', @lc_setwaterline); lua_register(luaState, _P'SetGearAIHints', @lc_setaihintsongear); lua_register(luaState, _P'HedgewarsScriptLoad', @lc_hedgewarsscriptload); @@ -2622,6 +2727,7 @@ procedure initModule; begin +mapDims:= false; end; procedure freeModule; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uStore.pas --- a/hedgewars/uStore.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uStore.pas Sat Jan 04 23:55:54 2014 +0400 @@ -29,6 +29,7 @@ procedure StoreLoad(reload: boolean); procedure StoreRelease(reload: boolean); procedure RenderHealth(var Hedgehog: THedgehog); +function makeHealthBarTexture(w, h, Color: Longword): PTexture; procedure AddProgress; procedure FinishProgress; function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface; @@ -132,76 +133,61 @@ end; procedure MakeCrossHairs; -var t: LongInt; - tmpsurf, texsurf: PSDL_Surface; - Color, i: Longword; +var tmpsurf: PSDL_Surface; begin -tmpsurf:= LoadDataImage(ptGraphics, cCHFileName, ifAlpha or ifCritical); - -for t:= 0 to Pred(TeamsCount) do - with TeamsArray[t]^ do - begin - texsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, tmpsurf^.w, tmpsurf^.h, 32, RMask, GMask, BMask, AMask); - TryDo(texsurf <> nil, errmsgCreateSurface, true); - - Color:= Clan^.Color; - Color:= SDL_MapRGB(texsurf^.format, Color shr 16, Color shr 8, Color and $FF); - SDL_FillRect(texsurf, nil, Color); - - SDL_UpperBlit(tmpsurf, nil, texsurf, nil); + tmpsurf:= LoadDataImage(ptGraphics, cCHFileName, ifAlpha or ifCritical); - TryDo(tmpsurf^.format^.BytesPerPixel = 4, 'Ooops', true); - - if SDL_MustLock(texsurf) then - SDLTry(SDL_LockSurface(texsurf) >= 0, true); - - // make black pixel be alpha-transparent - for i:= 0 to texsurf^.w * texsurf^.h - 1 do - if PLongwordArray(texsurf^.pixels)^[i] = AMask then - PLongwordArray(texsurf^.pixels)^[i]:= (RMask or GMask or BMask) and Color; + CrosshairTexture:= Surface2Tex(tmpsurf, false); - if SDL_MustLock(texsurf) then - SDL_UnlockSurface(texsurf); - - FreeTexture(CrosshairTex); - CrosshairTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf) - end; - -SDL_FreeSurface(tmpsurf) + SDL_FreeSurface(tmpsurf) end; +function makeHealthBarTexture(w, h, Color: Longword): PTexture; +var + rr: TSDL_Rect; + texsurf: PSDL_Surface; +begin + rr.x:= 0; + rr.y:= 0; + rr.w:= w; + rr.h:= h; + + texsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask); + TryDo(texsurf <> nil, errmsgCreateSurface, true); + TryDo(SDL_SetColorKey(texsurf, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); + + DrawRoundRect(@rr, cWhiteColor, cNearBlackColor, texsurf, true); + + rr.x:= 2; + rr.y:= 2; + rr.w:= w - 4; + rr.h:= h - 4; + + DrawRoundRect(@rr, Color, Color, texsurf, false); + makeHealthBarTexture:= Surface2Tex(texsurf, false); + SDL_FreeSurface(texsurf); +end; procedure WriteNames(Font: THWFont); var t: LongInt; i, maxLevel: LongInt; - r, rr: TSDL_Rect; + r: TSDL_Rect; drY: LongInt; texsurf, flagsurf, iconsurf: PSDL_Surface; foundBot: boolean; + year, month, md : word; begin if cOnlyStats then exit; r.x:= 0; r.y:= 0; drY:= - 4; +DecodeDate(Date, year, month, md); for t:= 0 to Pred(TeamsCount) do with TeamsArray[t]^ do begin NameTagTex:= RenderStringTexLim(TeamName, Clan^.Color, Font, cTeamHealthWidth); - - r.w:= cTeamHealthWidth + 5; - r.h:= NameTagTex^.h; - - texsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 32, RMask, GMask, BMask, AMask); - TryDo(texsurf <> nil, errmsgCreateSurface, true); - TryDo(SDL_SetColorKey(texsurf, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); - - DrawRoundRect(@r, cWhiteColor, cNearBlackColor, texsurf, true); - rr:= r; - inc(rr.x, 2); dec(rr.w, 4); inc(rr.y, 2); dec(rr.h, 4); - DrawRoundRect(@rr, Clan^.Color, Clan^.Color, texsurf, false); - HealthTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf); + if length(Owner) > 0 then + OwnerTex:= RenderStringTexLim(Owner, Clan^.Color, Font, cTeamHealthWidth); r.x:= 0; r.y:= 0; @@ -276,6 +262,16 @@ if Gear <> nil then begin NameTagTex:= RenderStringTexLim(Name, Clan^.Color, fnt16, cTeamHealthWidth); + if Hat = 'NoHat' then + begin + if (month = 4) and (md = 20) then + Hat := 'eastertop' // Easter + else if (month = 12) and ((md = 24) or (md = 25) or (md = 26)) then + Hat := 'Santa' // Christmas Eve/Christmas/Boxing Day + else if (month = 10) and (md = 31) then + Hat := 'fr_pumpkin'; // Halloween/Hedgewars' birthday + end; + if Hat <> 'NoHat' then begin if (Length(Hat) > 39) and (Copy(Hat,1,8) = 'Reserved') and (Copy(Hat,9,32) = PlayerHash) then @@ -298,8 +294,16 @@ SDL_FreeSurface(iconsurf); iconsurf:= nil; end; + + +for t:= 0 to Pred(ClansCount) do + with ClansArray[t]^ do + HealthTex:= makeHealthBarTexture(cTeamHealthWidth + 5, Teams[0]^.NameTagTex^.h, Color); + +GenericHealthTexture:= makeHealthBarTexture(cTeamHealthWidth + 5, TeamsArray[0]^.NameTagTex^.h, cWhiteColor) end; + procedure InitHealth; var i, t: LongInt; begin @@ -362,7 +366,7 @@ if (((cReducedQuality and (rqNoBackground or rqLowRes)) = 0) or // why rqLowRes? (not (ii in [sprSky, sprSkyL, sprSkyR, sprHorizont, sprHorizontL, sprHorizontR]))) and (((cReducedQuality and rqPlainSplash) = 0) or ((not (ii in [sprSplash, sprDroplet, sprSDSplash, sprSDDroplet])))) and - (((cReducedQuality and rqKillFlakes) = 0) or (Theme = 'Snow') or (Theme = 'Christmas') or ((not (ii in [sprFlake, sprSDFlake])))) and + (((cReducedQuality and rqKillFlakes) = 0) or cSnow or ((not (ii in [sprFlake, sprSDFlake])))) and ((cCloudsNumber > 0) or (ii <> sprCloud)) and ((vobCount > 0) or (ii <> sprFlake)) then begin @@ -435,6 +439,7 @@ InitHealth; PauseTexture:= RenderStringTex(trmsg[sidPaused], cYellowColor, fntBig); +AFKTexture:= RenderStringTex(trmsg[sidAFK], cYellowColor, fntBig); ConfirmTexture:= RenderStringTex(trmsg[sidConfirm], cYellowColor, fntBig); SyncTexture:= RenderStringTex(trmsg[sidSync], cYellowColor, fntBig); @@ -505,8 +510,8 @@ begin for ii:= Low(TSprite) to High(TSprite) do begin - FreeTexture(SpritesData[ii].Texture); - SpritesData[ii].Texture:= nil; + FreeAndNilTexture(SpritesData[ii].Texture); + if (SpritesData[ii].Surface <> nil) and (not reload) then begin SDL_FreeSurface(SpritesData[ii].Surface); @@ -516,58 +521,47 @@ SDL_FreeSurface(MissionIcons); // free the textures declared in uVariables -FreeTexture(WeaponTooltipTex); -WeaponTooltipTex:= nil; -FreeTexture(PauseTexture); -PauseTexture:= nil; -FreeTexture(SyncTexture); -SyncTexture:= nil; -FreeTexture(ConfirmTexture); -ConfirmTexture:= nil; -FreeTexture(ropeIconTex); -ropeIconTex:= nil; -FreeTexture(HHTexture); -HHTexture:= nil; - +FreeAndNilTexture(CrosshairTexture); +FreeAndNilTexture(WeaponTooltipTex); +FreeAndNilTexture(PauseTexture); +FreeAndNilTexture(AFKTexture); +FreeAndNilTexture(SyncTexture); +FreeAndNilTexture(ConfirmTexture); +FreeAndNilTexture(ropeIconTex); +FreeAndNilTexture(HHTexture); +FreeAndNilTexture(GenericHealthTexture); // free all ammo name textures for ai:= Low(TAmmoType) to High(TAmmoType) do - begin - FreeTexture(Ammoz[ai].NameTex); - Ammoz[ai].NameTex:= nil - end; + FreeAndNilTexture(Ammoz[ai].NameTex); // free all count textures for i:= Low(CountTexz) to High(CountTexz) do begin - FreeTexture(CountTexz[i]); + FreeAndNilTexture(CountTexz[i]); CountTexz[i]:= nil end; + for t:= 0 to Pred(ClansCount) do + begin + if ClansArray[t] <> nil then + FreeAndNilTexture(ClansArray[t]^.HealthTex); + end; + // free all team and hedgehog textures for t:= 0 to Pred(TeamsCount) do begin if TeamsArray[t] <> nil then begin - FreeTexture(TeamsArray[t]^.NameTagTex); - TeamsArray[t]^.NameTagTex:= nil; - FreeTexture(TeamsArray[t]^.CrosshairTex); - TeamsArray[t]^.CrosshairTex:= nil; - FreeTexture(TeamsArray[t]^.GraveTex); - TeamsArray[t]^.GraveTex:= nil; - FreeTexture(TeamsArray[t]^.HealthTex); - TeamsArray[t]^.HealthTex:= nil; - FreeTexture(TeamsArray[t]^.AIKillsTex); - TeamsArray[t]^.AIKillsTex:= nil; - FreeTexture(TeamsArray[t]^.FlagTex); - TeamsArray[t]^.FlagTex:= nil; + FreeAndNilTexture(TeamsArray[t]^.NameTagTex); + FreeAndNilTexture(TeamsArray[t]^.GraveTex); + FreeAndNilTexture(TeamsArray[t]^.AIKillsTex); + FreeAndNilTexture(TeamsArray[t]^.FlagTex); + for i:= 0 to cMaxHHIndex do begin - FreeTexture(TeamsArray[t]^.Hedgehogs[i].NameTagTex); - TeamsArray[t]^.Hedgehogs[i].NameTagTex:= nil; - FreeTexture(TeamsArray[t]^.Hedgehogs[i].HealthTagTex); - TeamsArray[t]^.Hedgehogs[i].HealthTagTex:= nil; - FreeTexture(TeamsArray[t]^.Hedgehogs[i].HatTex); - TeamsArray[t]^.Hedgehogs[i].HatTex:= nil; + FreeAndNilTexture(TeamsArray[t]^.Hedgehogs[i].NameTagTex); + FreeAndNilTexture(TeamsArray[t]^.Hedgehogs[i].HealthTagTex); + FreeAndNilTexture(TeamsArray[t]^.Hedgehogs[i].HatTex); end; end; end; @@ -678,14 +672,18 @@ procedure LoadHedgehogHat(var HH: THedgehog; newHat: shortstring); var texsurf: PSDL_Surface; begin + // free the mem of any previously assigned texture. This was previously only if the new one could be loaded, but, NoHat is usually a better choice + if HH.HatTex <> nil then + begin + FreeTexture(HH.HatTex); + HH.HatTex:= nil + end; texsurf:= LoadDataImage(ptHats, newHat, ifNone); AddFileLog('Hat => '+newHat); // only do something if the hat could be loaded if texsurf <> nil then begin AddFileLog('Got Hat'); - // free the mem of any previously assigned texture - FreeTexture(HH.HatTex); // assign new hat to hedgehog HH.HatTex:= Surface2Tex(texsurf, true); @@ -841,7 +839,7 @@ {$ENDIF} procedure SetupOpenGL; -var name: array[byte] of char; +var buf: array[byte] of char; AuxBufNum: LongInt = 0; tmpstr: AnsiString; tmpint: LongInt; @@ -849,13 +847,13 @@ begin {$IFDEF SDL2} - name:= SDL_GetCurrentVideoDriver(); + AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')'); {$ELSE} - name:= SDL_VideoDriverName(name, sizeof(name)); + buf[0]:= char(0); // avoid compiler hint + AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')'); {$ENDIF} AuxBufNum:= AuxBufNum; - AddFileLog('Setting up OpenGL (using driver: ' + shortstring(name) + ')'); {$IFDEF MOBILE} // TODO: this function creates an opengles1.1 context diff -r 8054d9d775fd -r 2759212a27de hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uTeams.pas Sat Jan 04 23:55:54 2014 +0400 @@ -41,13 +41,14 @@ procedure TeamGoneEffect(var Team: TTeam); procedure SwitchCurrentHedgehog(newHog: PHedgehog); +var MaxTeamHealth: LongInt; + implementation uses uLocale, uAmmos, uChat, uVariables, uUtils, uIO, uCaptions, uCommands, uDebug, uGearsUtils, uGearsList, uVisualGearsList, uTextures {$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF}; -var MaxTeamHealth: LongInt; - GameOver: boolean; +var GameOver: boolean; NextClan: boolean; function CheckForWin: boolean; @@ -480,17 +481,11 @@ else if Hedgehogs[i].GearHidden <> nil then inc(TeamHealth, Hedgehogs[i].GearHidden^.Health); - if not hasGone then - NewTeamHealthBarWidth:= TeamHealth - else - NewTeamHealthBarWidth:= 0; - - if NewTeamHealthBarWidth > MaxTeamHealth then + if TeamHealth > MaxTeamHealth then begin - MaxTeamHealth:= NewTeamHealthBarWidth; + MaxTeamHealth:= TeamHealth; RecountAllTeamsHealth; - end else if NewTeamHealthBarWidth > 0 then - NewTeamHealthBarWidth:= (NewTeamHealthBarWidth * cTeamHealthWidth) div MaxTeamHealth + end end; RecountClanHealth(team^.Clan); @@ -528,7 +523,7 @@ if Gear <> nil then begin - Gear^.Invulnerable:= false; + Gear^.Hedgehog^.Effects[heInvulnerable]:= 0; Gear^.Damage:= Gear^.Health; Gear^.State:= (Gear^.State or gstHHGone) and (not gstHHDriven) end @@ -547,11 +542,11 @@ SplitBySpace(id, s); SwitchCurrentHedgehog(@Hedgehogs[HedgehogsNumber]); CurrentHedgehog^.BotLevel:= StrToInt(id); + CurrentHedgehog^.Team:= CurrentTeam; Gear:= AddGear(0, 0, gtHedgehog, 0, _0, _0, 0); SplitBySpace(s, id); Gear^.Health:= StrToInt(s); TryDo(Gear^.Health > 0, 'Invalid hedgehog health', true); - Gear^.Hedgehog^.Team:= CurrentTeam; if (GameFlags and gfSharedAmmo) <> 0 then CurrentHedgehog^.AmmoStore:= Clan^.ClanIndex else if (GameFlags and gfPerHogAmmo) <> 0 then @@ -688,6 +683,62 @@ end; +procedure chSetHat(var s: shortstring); +begin +if (not isDeveloperMode) or (CurrentTeam = nil) then exit; +with CurrentTeam^ do + begin + if not CurrentHedgehog^.King then + if (s = '') + or (((GameFlags and gfKing) <> 0) and (s = 'crown')) + or ((Length(s) > 39) and (Copy(s,1,8) = 'Reserved') and (Copy(s,9,32) <> PlayerHash)) then + CurrentHedgehog^.Hat:= 'NoHat' + else + CurrentHedgehog^.Hat:= s + end; +end; + +procedure chGrave(var s: shortstring); +begin + if CurrentTeam = nil then + OutError(errmsgIncorrectUse + ' "/grave"', true); + if s[1]='"' then + Delete(s, 1, 1); + if s[byte(s[0])]='"' then + Delete(s, byte(s[0]), 1); + CurrentTeam^.GraveName:= s +end; + +procedure chFort(var s: shortstring); +begin + if CurrentTeam = nil then + OutError(errmsgIncorrectUse + ' "/fort"', true); + if s[1]='"' then + Delete(s, 1, 1); + if s[byte(s[0])]='"' then + Delete(s, byte(s[0]), 1); + CurrentTeam^.FortName:= s +end; + +procedure chFlag(var s: shortstring); +begin + if CurrentTeam = nil then + OutError(errmsgIncorrectUse + ' "/flag"', true); + if s[1]='"' then + Delete(s, 1, 1); + if s[byte(s[0])]='"' then + Delete(s, byte(s[0]), 1); + CurrentTeam^.flag:= s +end; + +procedure chOwner(var s: shortstring); +begin + if CurrentTeam = nil then + OutError(errmsgIncorrectUse + ' "/owner"', true); + + CurrentTeam^.Owner:= s +end; + procedure initModule; begin RegisterVariable('addhh', @chAddHH, false); @@ -696,6 +747,11 @@ RegisterVariable('bind', @chBind, true ); RegisterVariable('teamgone', @chTeamGone, true ); RegisterVariable('finish', @chFinish, true ); // all teams gone +RegisterVariable('fort' , @chFort , false); +RegisterVariable('grave' , @chGrave , false); +RegisterVariable('hat' , @chSetHat , false); +RegisterVariable('flag' , @chFlag , false); +RegisterVariable('owner' , @chOwner , false); CurrentTeam:= nil; PreviousTeam:= nil; @@ -722,26 +778,27 @@ begin if GearHidden <> nil then Dispose(GearHidden); - + FreeTexture(NameTagTex); FreeTexture(HealthTagTex); FreeTexture(HatTex); end; - + with TeamsArray[i]^ do begin FreeTexture(NameTagTex); - FreeTexture(CrosshairTex); FreeTexture(GraveTex); - FreeTexture(HealthTex); FreeTexture(AIKillsTex); FreeTexture(FlagTex); end; - + Dispose(TeamsArray[i]); end; -for i:= 0 to Pred(ClansCount) do - Dispose(ClansArray[i]); + for i:= 0 to Pred(ClansCount) do + begin + FreeTexture(ClansArray[i]^.HealthTex); + Dispose(ClansArray[i]); + end end; TeamsCount:= 0; ClansCount:= 0; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uTextures.pas --- a/hedgewars/uTextures.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uTextures.pas Sat Jan 04 23:55:54 2014 +0400 @@ -26,6 +26,7 @@ procedure Surface2GrayScale(surf: PSDL_Surface); function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; procedure FreeTexture(tex: PTexture); +procedure FreeAndNilTexture(var tex: PTexture); procedure initModule; procedure freeModule; @@ -226,6 +227,12 @@ end end; +procedure FreeAndNilTexture(var tex: PTexture); +begin + FreeTexture(tex); + tex:= nil +end; + procedure initModule; begin TextureList:= nil; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uTypes.pas Sat Jan 04 23:55:54 2014 +0400 @@ -87,8 +87,7 @@ sprHandResurrector, sprCross, sprAirDrill, sprNapalmBomb, sprBulletHit, sprSnowball, sprHandSnowball, sprSnow, sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis, - sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, - sprFrozenHog + sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, sprFrozenHog, sprAmRubber, sprBoing ); // Gears that interact with other Gears and/or Land @@ -155,9 +154,7 @@ amRCPlane, amLowGravity, amExtraDamage, amInvulnerable, amExtraTime, // 35 amLaserSight, amVampiric, amSniperRifle, amJetpack, amMolotov, amBirdy, amPortalGun, // 42 amPiano, amGasBomb, amSineGun, amFlamethrower, amSMine, amHammer, // 48 - amResurrector, amDrillStrike, amSnowball, amTardis, {amStructure,} amLandGun, amIceGun, - amKnife // 54 - ); + amResurrector, amDrillStrike, amSnowball, amTardis, {amStructure,} amLandGun, amIceGun, amKnife, amRubber); // 56 // Different kind of crates that e.g. hedgehogs can pick up TCrateType = (HealthCrate, AmmoCrate, UtilityCrate); @@ -176,10 +173,9 @@ TWave = (waveRollup, waveSad, waveWave, waveHurrah, waveLemonade, waveShrug, waveJuggle); TRenderMode = (rmDefault, rmLeftEye, rmRightEye); - TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, - smHorizontal, smVertical); - + TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, smHorizontal, smVertical); TWorldEdge = (weNone, weWrap, weBounce, weSea, weSky); + TUIDisplay = (uiAll, uiNoTeams, uiNone); THHFont = record Handle: PTTF_Font; @@ -265,8 +261,7 @@ Density : hwFloat; // Density is kind of a mix of size and density. Impacts distance thrown, wind. ImpactSound: TSound; // first sound, others have to be after it in the sounds def. nImpactSounds: Word; // count of ImpactSounds. -// Do not use these if you want to take damage normally, otherwise health/damage are commonly used for other purposes - Invulnerable: Boolean; +// Don't use these if you want to take damage normally, otherwise health/damage are commonly used for other purposes Health, Damage, Karma: LongInt; // DirAngle is a 'real' - if you do not need it for rotation of sprite in uGearsRender, you can use it for any visual-only value DirAngle: real; @@ -378,6 +373,7 @@ King: boolean; // Flag for a bunch of hedgehog attributes Unplaced: boolean; // Flag for hog placing mode Timer: Longword; + HealthBarHealth: LongInt; Effects: array[THogEffect] of LongInt; end; @@ -388,18 +384,17 @@ Binds: TBinds; Hedgehogs: array[0..cMaxHHIndex] of THedgehog; CurrHedgehog: LongWord; - NameTagTex: PTexture; - CrosshairTex, + NameTagTex, + OwnerTex: PTexture; GraveTex, - HealthTex, AIKillsTex, FlagTex: PTexture; Flag: shortstring; GraveName: shortstring; FortName: shortstring; + Owner: shortstring; TeamHealth: LongInt; - TeamHealthBarWidth, - NewTeamHealthBarWidth: LongInt; + TeamHealthBarHealth: LongInt; DrawHealthY: LongInt; AttackBar: LongWord; HedgehogsNumber: Longword; @@ -412,7 +407,8 @@ TClan = record Color: Longword; Teams: array[0..Pred(cMaxTeams)] of PTeam; - TeamsNumber: LongInt;{xymeng, org:LongWord} + HealthTex: PTexture; + TeamsNumber: Longword; TagTeamIndex: Longword; CurrTeam: LongWord; ClanHealth: LongInt; @@ -444,13 +440,13 @@ sidMolotov, sidBirdy, sidPortalGun, sidPiano, sidGasBomb, sidSineGun, sidFlamethrower,sidSMine, sidHammer, sidResurrector, sidDrillStrike, sidSnowball, sidNothing, sidTardis, - {sidStructure,} sidLandGun, sidIceGun, sidKnife); + {sidStructure,} sidLandGun, sidIceGun, sidKnife, sidRubber); TMsgStrId = (sidStartFight, sidDraw, sidWinner, sidVolume, sidPaused, sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync, sidNoEndTurn, sidNotYetAvailable, sidRoundSD, sidRoundsSD, sidReady, sidBounce1, sidBounce2, sidBounce3, sidBounce4, sidBounce5, sidBounce, - sidMute); + sidMute, sidAFK); // Events that are important for the course of the game or at least interesting for other reasons TEventId = (eidDied, eidDrowned, eidRoundStart, eidRoundWin, eidRoundDraw, diff -r 8054d9d775fd -r 2759212a27de hedgewars/uUtils.pas --- a/hedgewars/uUtils.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uUtils.pas Sat Jan 04 23:55:54 2014 +0400 @@ -34,6 +34,7 @@ function EnumToStr(const en : TVisualGearType) : shortstring; overload; function EnumToStr(const en : TSound) : shortstring; overload; function EnumToStr(const en : TAmmoType) : shortstring; overload; +function EnumToStr(const en : TStatInfoType) : shortstring; overload; function EnumToStr(const en : THogEffect) : shortstring; overload; function EnumToStr(const en : TCapGroup) : shortstring; overload; @@ -160,6 +161,11 @@ EnumToStr:= GetEnumName(TypeInfo(TAmmoType), ord(en)) end; +function EnumToStr(const en : TStatInfoType) : shortstring; overload; +begin +EnumToStr:= GetEnumName(TypeInfo(TStatInfoType), ord(en)) +end; + function EnumToStr(const en: THogEffect) : shortstring; overload; begin EnumToStr := GetEnumName(TypeInfo(THogEffect), ord(en)) diff -r 8054d9d775fd -r 2759212a27de hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uVariables.pas Sat Jan 04 23:55:54 2014 +0400 @@ -46,6 +46,9 @@ cShowFPS : boolean; cFlattenFlakes : boolean; cFlattenClouds : boolean; + cIce : boolean; + cSnow : boolean; + cAltDamage : boolean; cReducedQuality : LongWord; UserNick : shortstring; @@ -69,6 +72,7 @@ isPaused : boolean; isInMultiShoot : boolean; isSpeed : boolean; + isAFK : boolean; SpeedStart : LongWord; fastUntilLag : boolean; @@ -83,7 +87,10 @@ InputMask : LongWord; GameFlags : Longword; WorldEdge : TWorldEdge; + LeftImpactTimer : LongWord; + RightImpactTimer: LongWord; TurnTimeLeft : Longword; + TurnClockActive : boolean; TagTurnTimeLeft : Longword; ReadyTimeLeft : Longword; cSuddenDTurns : LongInt; @@ -128,6 +135,9 @@ LAND_WIDTH_MASK : LongWord; LAND_HEIGHT_MASK : LongWord; + CrosshairTexture : PTexture; + GenericHealthTexture : PTexture; + cLeftScreenBorder : LongInt; cRightScreenBorder : LongInt; cScreenSpace : Longword; @@ -137,6 +147,7 @@ cExplosives : Longword; cScriptName : shortstring; + cScriptParam : shortstring; cSeed : shortstring; cVolumeDelta : LongInt; cHasFocus : boolean; @@ -154,6 +165,7 @@ cMaxWindSpeed : hwFloat; cWindSpeed : hwFloat; cWindSpeedf : real; + cElastic : hwFloat; cGravity : hwFloat; cGravityf : real; cDamageModifier : hwFloat; @@ -188,6 +200,9 @@ ScreenFadeValue : LongInt; ScreenFadeSpeed : LongInt; + UIDisplay : TUIDisplay; + LocalMessage : LongWord; + Theme : shortstring; disableLandBack : boolean; @@ -441,7 +456,7 @@ (FileName: 'amKamikaze'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; Width: 128; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprKamikaze (FileName: 'amWhip'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; - Width: 128; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprWhip + Width: 128; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprWhip (FileName: 'Kowtow'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpLowest; getDimensions: false; getImageDimensions: true),// sprKowtow (FileName: 'Sad'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; @@ -670,7 +685,11 @@ (FileName: 'amIceGun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; Width: 32; Height: 32; imageWidth: 32; imageHeight: 32; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprIceGun (FileName: 'amFrozenHog'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; - Width: 64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprFrozenHog + Width: 64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprFrozenHog + (FileName: 'amRubber'; Path: ptCurrTheme; AltPath: ptGraphics; Texture: nil; Surface: nil; + Width: 160; Height:160; imageWidth: 0; imageHeight: 0; saveSurf: true; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprAmRubber + (FileName: 'boing'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; + Width: 101; Height: 97; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprBoing ); const @@ -844,7 +863,8 @@ Probability: 0; NumberInCase: 1; Ammo: (Propz: ammoprop_ForwMsgs or - ammoprop_NeedUpDown; + ammoprop_NeedUpDown or + ammoprop_DoesntStopTimerInMultiShoot; Count: AMMO_INFINITE; NumPerTurn: 1; Timer: 0; @@ -896,6 +916,7 @@ Probability: 0; NumberInCase: 1; Ammo: (Propz: ammoprop_NoCrosshair or + ammoprop_AttackInMove or ammoprop_DontHold; Count: AMMO_INFINITE; NumPerTurn: 0; @@ -925,7 +946,8 @@ ammoprop_AttackInMove or ammoprop_Utility or ammoprop_AltAttack or - ammoprop_NeedUpDown; + ammoprop_NeedUpDown or + ammoprop_DoesntStopTimerWhileAttacking; Count: 5; NumPerTurn: 0; Timer: 0; @@ -977,7 +999,7 @@ NameTex: nil; Probability: 20; NumberInCase: 2; - Ammo: (Propz: ammoprop_NeedUpDown; + Ammo: (Propz: ammoprop_NeedUpDown or ammoprop_DoesntStopTimerInMultiShoot; Count: 3; NumPerTurn: 3; Timer: 0; @@ -1741,7 +1763,8 @@ NumberInCase: 2; Ammo: (Propz: ammoprop_NeedUpDown or ammoprop_OscAim or - ammoprop_NoMoveAfter; + ammoprop_NoMoveAfter or + ammoprop_DoesntStopTimerInMultiShoot; Count: 2; NumPerTurn: 1; Timer: 0; @@ -1860,7 +1883,7 @@ AmmoType: amPortalGun; AttackVoice: sndNone; Bounciness: 1000); - Slot: 6; + Slot: 7; TimeAfterTurn: 0; minAngle: 0; maxAngle: 0; @@ -2125,7 +2148,7 @@ AmmoType: amTardis; AttackVoice: sndNone; Bounciness: 1000); - Slot: 7; + Slot: 8; TimeAfterTurn: 0; minAngle: 0; maxAngle: 0; @@ -2238,6 +2261,33 @@ PosCount: 1; PosSprite: sprWater; ejectX: 0; + ejectY: 0), +// Rubber + (NameId: sidRubber; + NameTex: nil; + Probability: 150; + NumberInCase: 1; + Ammo: (Propz: ammoprop_NoRoundEnd or + ammoprop_NoCrosshair or + ammoprop_NeedTarget or + ammoprop_Utility or + ammoprop_AttackingPut; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amRubber; + AttackVoice: sndNone; + Bounciness: 1000); + Slot: 6; + TimeAfterTurn: 3000; + minAngle: 0; + maxAngle: 0; + isDamaging: false; + SkipTurns: 0; + PosCount: 4; + PosSprite: sprAmRubber; + ejectX: 0; ejectY: 0) ); @@ -2290,6 +2340,7 @@ PauseTexture, + AFKTexture, SyncTexture, ConfirmTexture: PTexture; cScaleFactor: GLfloat; @@ -2397,6 +2448,8 @@ cFlattenFlakes := false; cFlattenClouds := false; + cIce := false; + cSnow := false; lastVisualGearByUID := nil; lastGearByUID := nil; cReadyDelay := 5000; @@ -2444,6 +2497,7 @@ cMaxWindSpeed.QWordValue:= 1073742; // 0.00025 cWindSpeed.QWordValue := 0; // 0.0 cWindSpeedf := 0.0; + cElastic := _0_9; cGravity := cMaxWindSpeed * 2; cGravityf := 0.00025 * 2; cDamageModifier := _1; @@ -2472,7 +2526,10 @@ InputMask := $FFFFFFFF; GameFlags := 0; WorldEdge := weNone; + LeftImpactTimer := 0; + RightImpactTimer := 0; TurnTimeLeft := 0; + TurnClockActive := true; TagTurnTimeLeft := 0; cSuddenDTurns := 15; cDamagePercent := 100; @@ -2513,11 +2570,13 @@ isPaused := false; isInMultiShoot := false; isSpeed := false; + isAFK := false; SpeedStart := 0; fastUntilLag := false; fastScrolling := false; autoCameraOn := true; cScriptName := ''; + cScriptParam := ''; cSeed := ''; cVolumeDelta := 0; cHasFocus := true; @@ -2562,13 +2621,9 @@ cMapName:= ''; LuaTemplateNumber:= 0; - cStereoDepth := 0; -// MatrixLoadIdentity(mModelview); -// MatrixLoadIdentity(mProjection); - aVertex:= 0; - aTexCoord:= 1; - aColor:= 2; + UIDisplay:= uiAll; + LocalMessage:= 0; end; procedure freeModule; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uVideoRec.pas --- a/hedgewars/uVideoRec.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uVideoRec.pas Sat Jan 04 23:55:54 2014 +0400 @@ -53,12 +53,12 @@ type TAddFileLogRaw = procedure (s: pchar); cdecl; const AvwrapperLibName = 'libavwrapper'; -procedure AVWrapper_Init( +function AVWrapper_Init( AddLog: TAddFileLogRaw; filename, desc, soundFile, format, vcodec, acodec: PChar; - width, height, framerateNum, framerateDen, vquality: LongInt); cdecl; external AvwrapperLibName; -procedure AVWrapper_Close; cdecl; external AvwrapperLibName; -procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external AvwrapperLibName; + width, height, framerateNum, framerateDen, vquality: LongInt): LongInt; cdecl; external AvwrapperLibName; +function AVWrapper_Close: LongInt; cdecl; external AvwrapperLibName; +function AVWrapper_WriteFrame( pY, pCb, pCr: PByte ): LongInt; cdecl; external AvwrapperLibName; type TFrame = record realTicks: LongWord; @@ -109,14 +109,15 @@ filename:= UserPathPrefix + '/VideoTemp/' + RecPrefix; soundFilePath:= UserPathPrefix + '/VideoTemp/' + RecPrefix + '.sw'; - AVWrapper_Init(@AddFileLogRaw + if AVWrapper_Init(@AddFileLogRaw , PChar(ansistring(filename)) , PChar(ansistring(desc)) , PChar(ansistring(soundFilePath)) , PChar(ansistring(cAVFormat)) , PChar(ansistring(cVideoCodec)) , PChar(ansistring(cAudioCodec)) - , cScreenWidth, cScreenHeight, cVideoFramerateNum, cVideoFramerateDen, cVideoQuality); + , cScreenWidth, cScreenHeight, cVideoFramerateNum, cVideoFramerateDen, cVideoQuality) < 0 then + halt(-1); numPixels:= cScreenWidth*cScreenHeight; YCbCr_Planes[0]:= GetMem(numPixels); @@ -150,7 +151,8 @@ FreeMem(YCbCr_Planes[2], numPixels div 4); FreeMem(RGB_Buffer, 4*numPixels); Close(cameraFile); - AVWrapper_Close(); + if AVWrapper_Close() < 0 then + halt(-1); Erase(cameraFile); DeleteFile(soundFilePath); SendIPC(_S'v'); // inform frontend that we finished @@ -185,7 +187,8 @@ YCbCr_Planes[2][y*(cScreenWidth div 2) + x]:= Byte(128 + (( 7196*r - 6026*g - 1170*b) shr 16)); end; - AVWrapper_WriteFrame(YCbCr_Planes[0], YCbCr_Planes[1], YCbCr_Planes[2]); + if AVWrapper_WriteFrame(YCbCr_Planes[0], YCbCr_Planes[1], YCbCr_Planes[2]) < 0 then + halt(-1); // inform frontend that we have encoded new frame s[0]:= #3; @@ -367,6 +370,10 @@ procedure initModule; begin + // we need to make sure these variables are initialized before the main loop + // or the wrapper will keep the default values of preinit + cScreenWidth:= max(cWindowedWidth, 640); + cScreenHeight:= max(cWindowedHeight, 480); end; procedure freeModule; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uVisualGears.pas Sat Jan 04 23:55:54 2014 +0400 @@ -167,7 +167,7 @@ end; end; if Gear^.Tint <> $FFFFFFFF then - Tint($FF,$FF,$FF,$FF); + untint; Gear:= Gear^.NextGear end end; @@ -219,10 +219,17 @@ else DrawSprite(sprDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame); vgtBubble: DrawSprite(sprBubbles, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8); + vgtStraightShot: begin + if Gear^.dX < 0 then + i:= -1 + else + i:= 1; + DrawTextureRotatedF(SpritesData[TSprite(Gear^.State)].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, i, SpritesData[TSprite(Gear^.State)].Width, SpritesData[TSprite(Gear^.State)].Height, Gear^.Angle); + end; end; - //if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF); + //if (Gear^.Tint <> $FFFFFFFF) or tinted then untint; if (Gear^.Tint <> $FFFFFFFF) then - Tint($FF,$FF,$FF,$FF); + untint; Gear:= Gear^.NextGear end end; @@ -284,7 +291,7 @@ vgtChunk: DrawSpriteRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) or tinted then - Tint($FF,$FF,$FF,$FF); + untint; Gear:= Gear^.NextGear end end; @@ -368,7 +375,7 @@ DrawCircle(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State, Gear^.Timer); end; if (Gear^.Tint <> $FFFFFFFF) or tinted then - Tint($FF,$FF,$FF,$FF); + untint; Gear:= Gear^.NextGear end end; @@ -396,7 +403,7 @@ DrawTextureRotatedF(SpritesData[sprFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) then - Tint($FF,$FF,$FF,$FF); + untint; Gear:= Gear^.NextGear end end; @@ -424,7 +431,7 @@ DrawSpriteRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) then - Tint($FF,$FF,$FF,$FF); + untint; Gear:= Gear^.NextGear end end; @@ -448,7 +455,7 @@ DrawSpriteRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) then - Tint($FF,$FF,$FF,$FF); + untint; Gear:= Gear^.NextGear end end; @@ -487,7 +494,7 @@ if (cReducedQuality and rqKillFlakes) <> 0 then exit; -if hasBorder or ((Theme <> 'Snow') and (Theme <> 'Christmas')) then +if hasBorder or (not cSnow) then for i:= 0 to Pred(vobCount * cScreenSpace div 4096) do AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake) else @@ -515,7 +522,7 @@ end else vg:= vg^.NextGear; end; -if ((GameFlags and gfBorder) <> 0) or ((Theme <> 'Snow') and (Theme <> 'Christmas')) then +if hasBorder or (not cSnow) then for i:= 0 to Pred(vobSDCount * cScreenSpace div 4096) do AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake) else diff -r 8054d9d775fd -r 2759212a27de hedgewars/uVisualGearsHandlers.pas --- a/hedgewars/uVisualGearsHandlers.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uVisualGearsHandlers.pas Sat Jan 04 23:55:54 2014 +0400 @@ -71,6 +71,7 @@ procedure doStepSmoothWindBar(Gear: PVisualGear; Steps: Longword); procedure doStepStraightShot(Gear: PVisualGear; Steps: Longword); +function isSorterActive: boolean; inline; procedure initModule; implementation @@ -483,11 +484,17 @@ dy, ny, dw: LongInt; team: PTeam; SortFactor: QWord; + hdw: array[0..cMaxHHIndex] of LongInt; end; currsorter: PVisualGear = nil; +function isSorterActive: boolean; inline; +begin + isSorterActive:= currsorter <> nil +end; + procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword); -var i, t: LongInt; +var i, t, h: LongInt; begin for t:= 1 to min(Steps, Gear^.Timer) do begin @@ -498,7 +505,13 @@ begin {$WARNINGS OFF} team^.DrawHealthY:= ny + dy * LongInt(Gear^.Timer) div cSorterWorkTime; - team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * LongInt(Gear^.Timer) div cSorterWorkTime; + team^.TeamHealthBarHealth:= team^.TeamHealth + dw * LongInt(Gear^.Timer) div cSorterWorkTime; + + for h:= 0 to cMaxHHIndex do + if (team^.Hedgehogs[h].Gear <> nil) then + team^.Hedgehogs[h].HealthBarHealth:= team^.Hedgehogs[h].Gear^.Health + hdw[h] * LongInt(Gear^.Timer) div cSorterWorkTime + else + team^.Hedgehogs[h].HealthBarHealth:= hdw[h] * LongInt(Gear^.Timer) div cSorterWorkTime; {$WARNINGS ON} end; end; @@ -515,7 +528,7 @@ procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword); var i: Longword; b: boolean; - t: LongInt; + t, h: LongInt; begin {$IFNDEF PAS2C} Steps:= Steps; // avoid compiler hint @@ -526,7 +539,7 @@ begin team:= TeamsArray[t]; dy:= team^.DrawHealthY; - dw:= team^.TeamHealthBarWidth - team^.NewTeamHealthBarWidth; + dw:= team^.TeamHealthBarHealth - team^.TeamHealth; if team^.TeamHealth > 0 then begin SortFactor:= team^.Clan^.ClanHealth; @@ -535,6 +548,12 @@ end else SortFactor:= 0; + + for h:= 0 to cMaxHHIndex do + if (team^.Hedgehogs[h].Gear <> nil) then + hdw[h]:= team^.Hedgehogs[h].HealthBarHealth - team^.Hedgehogs[h].Gear^.Health + else + hdw[h]:= team^.Hedgehogs[h].HealthBarHealth; end; if TeamsCount > 1 then @@ -555,7 +574,7 @@ with thexchar[i] do if team^.TeamHealth > 0 then begin - dec(t, team^.HealthTex^.h + 2); + dec(t, team^.Clan^.HealthTex^.h + 2); ny:= t; dy:= dy - ny end; @@ -573,7 +592,7 @@ if (Gear^.Hedgehog^.Gear <> nil) then begin - Gear^.X:= hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + (Gear^.Tex^.w div 2 - Gear^.FrameTicks); + Gear^.X:= hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + (Gear^.Tex^.w div 2 - Gear^.Tag); Gear^.Y:= hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) - (16 + Gear^.Tex^.h); end; @@ -602,10 +621,11 @@ Gear^.Tex:= RenderSpeechBubbleTex(Gear^.Text, Gear^.FrameTicks, fnt16); +// FrameTicks cannot hold negative values case Gear^.FrameTicks of - 1: Gear^.FrameTicks:= SpritesData[sprSpeechTail].Width-28; - 2: Gear^.FrameTicks:= SpritesData[sprThoughtTail].Width-20; - 3: Gear^.FrameTicks:= SpritesData[sprShoutTail].Width-10; + 1: Gear^.Tag:= SpritesData[sprSpeechTail].Width-28; + 2: Gear^.Tag:= SpritesData[sprThoughtTail].Width-20; + 3: Gear^.Tag:= SpritesData[sprShoutTail].Width-10; end; Gear^.doStep:= @doStepSpeechBubbleWork; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uVisualGearsList.pas --- a/hedgewars/uVisualGearsList.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uVisualGearsList.pas Sat Jan 04 23:55:54 2014 +0400 @@ -24,7 +24,8 @@ function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline; function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline; -function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear; inline; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean; Layer: LongInt): PVisualGear; procedure DeleteVisualGear(Gear: PVisualGear); function VisualGearByUID(uid : Longword) : PVisualGear; @@ -39,15 +40,20 @@ function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline; begin - AddVisualGear:= AddVisualGear(X, Y, Kind, 0, false); + AddVisualGear:= AddVisualGear(X, Y, Kind, 0, false, -1); end; function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline; begin - AddVisualGear:= AddVisualGear(X, Y, Kind, State, false); + AddVisualGear:= AddVisualGear(X, Y, Kind, State, false, -1); end; -function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear; inline; +begin + AddVisualGear:= AddVisualGear(X, Y, Kind, State, Critical, -1); +end; + +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean; Layer: LongInt): PVisualGear; var gear: PVisualGear; t: Longword; sp: real; @@ -401,6 +407,8 @@ vgtCircle: gear^.Layer:= 2 end; +if Layer <> -1 then gear^.Layer:= Layer; + if VisualGearLayers[gear^.Layer] <> nil then begin VisualGearLayers[gear^.Layer]^.PrevGear:= gear; diff -r 8054d9d775fd -r 2759212a27de hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Fri Oct 11 17:43:13 2013 +0200 +++ b/hedgewars/uWorld.pas Sat Jan 04 23:55:54 2014 +0400 @@ -60,6 +60,7 @@ , uCaptions , uCursor , uCommands + , uTeams {$IFDEF USE_VIDEO_RECORDING} , uVideoRec {$ENDIF} @@ -88,6 +89,7 @@ AmmoMenuTex : PTexture; HorizontOffset: LongInt; cOffsetY: LongInt; + WorldEnd, WorldFade : array[0..3] of HwColor4f; const cStereo_Sky = 0.0500; cStereo_Horizon = 0.0250; @@ -921,7 +923,7 @@ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); -Tint($FF, $FF, $FF, $FF); +untint; {for i:= -1 to cWaterSprCount do DrawSprite(sprWater, @@ -1008,7 +1010,7 @@ //glPushMatrix; //glScalef(1.0, 1.0, 1.0); - if (not isPaused) and (GameType <> gmtRecord) then + if (not isPaused) and (not isAFK) and (GameType <> gmtRecord) then MoveCamera; if cStereoMode = smNone then @@ -1164,16 +1166,225 @@ {$ENDIF} end; +procedure RenderWorldEdge(Lag: Longword); +var + VertexBuffer: array [0..3] of TVertex2f; + c1, c2: LongWord; // couple of colours for edges +begin +if WorldEdge <> weNone then + begin +(* I think for a bounded world, will fill the left and right areas with black or something. Also will probably want various border effects/animations based on border type. Prob also, say, trigger a border animation timer on an impact. *) + + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glPushMatrix; + glTranslatef(WorldDx, WorldDy, 0); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]); + + VertexBuffer[0].X:= leftX-20; + VertexBuffer[0].Y:= -3000; + VertexBuffer[1].X:= leftX-20; + VertexBuffer[1].Y:= cWaterLine+cVisibleWater; + VertexBuffer[2].X:= leftX+30; + VertexBuffer[2].Y:= cWaterLine+cVisibleWater; + VertexBuffer[3].X:= leftX+30; + VertexBuffer[3].Y:= -3000; + + glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); + glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); + + VertexBuffer[0].X:= rightX+20; + VertexBuffer[1].X:= rightX+20; + VertexBuffer[2].X:= rightX-30; + VertexBuffer[3].X:= rightX-30; + + glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); + glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); + + glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldEnd[0]); + + VertexBuffer[0].X:= -5000; + VertexBuffer[1].X:= -5000; + VertexBuffer[2].X:= leftX-20; + VertexBuffer[3].X:= leftX-20; + + glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); + glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); + + VertexBuffer[0].X:= rightX+5000; + VertexBuffer[1].X:= rightX+5000; + VertexBuffer[2].X:= rightX+20; + VertexBuffer[3].X:= rightX+20; + + glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); + glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); + + glPopMatrix; + glDisableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required + glEnable(GL_TEXTURE_2D); + + // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer + if WorldEdge = weBounce then + begin + // could maybe alternate order of these on a bounce, or maybe drop the outer ones. + if LeftImpactTimer mod 2 = 0 then + begin + c1:= $5454FFFF; c2:= $FFFFFFFF; + end + else begin + c1:= $FFFFFFFF; c2:= $5454FFFF; + end; + DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 7.0, c1); + DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, c2); + DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 3.0, c1); + DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 1.0, c2); + if RightImpactTimer mod 2 = 0 then + begin + c1:= $5454FFFF; c2:= $FFFFFFFF; + end + else begin + c1:= $FFFFFFFF; c2:= $5454FFFF; + end; + DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 7.0, c1); + DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, c2); + DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 3.0, c1); + DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 1.0, c2) + end + else if WorldEdge = weWrap then + begin + DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-LeftImpactTimer)); + DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 2.0, $FF0000FF); + DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-RightImpactTimer)); + DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 2.0, $FF0000FF); + end + else + begin + DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $2E8B5780); + DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $2E8B5780) + end; + if LeftImpactTimer > Lag then dec(LeftImpactTimer,Lag) else LeftImpactTimer:= 0; + if RightImpactTimer > Lag then dec(RightImpactTimer,Lag) else RightImpactTimer:= 0 + end; +end; + + +procedure RenderTeamsHealth; +var t, i, h, smallScreenOffset, TeamHealthBarWidth : LongInt; + r: TSDL_Rect; + highlight: boolean; + htex: PTexture; +begin +if TeamsCount * 20 > Longword(cScreenHeight) div 7 then // take up less screen on small displays + begin + SetScale(1.5); + smallScreenOffset:= cScreenHeight div 6; + if TeamsCount * 100 > Longword(cScreenHeight) then + Tint($FF,$FF,$FF,$80); + end +else smallScreenOffset:= 0; +for t:= 0 to Pred(TeamsCount) do + with TeamsArray[t]^ do + if TeamHealth > 0 then + begin + highlight:= bShowFinger and (CurrentTeam = TeamsArray[t]) and ((RealTicks mod 1000) < 500); + + if highlight then + begin + Tint(Clan^.Color shl 8 or $FF); + htex:= GenericHealthTexture + end + else + htex:= Clan^.HealthTex; + + // draw owner + if OwnerTex <> nil then + DrawTexture(-OwnerTex^.w - NameTagTex^.w - 18, cScreenHeight + DrawHealthY + smallScreenOffset, OwnerTex); + + // draw name + DrawTexture(-NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset, NameTagTex); + + // draw flag + DrawTexture(-14, cScreenHeight + DrawHealthY + smallScreenOffset, FlagTex); + + TeamHealthBarWidth:= cTeamHealthWidth * TeamHealthBarHealth div MaxTeamHealth; + + // draw health bar + r.x:= 0; + r.y:= 0; + r.w:= 2 + TeamHealthBarWidth; + r.h:= htex^.h; + DrawTextureFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, htex); + + // draw health bars right border + inc(r.x, cTeamHealthWidth + 2); + r.w:= 3; + DrawTextureFromRect(TeamHealthBarWidth + 15, cScreenHeight + DrawHealthY + smallScreenOffset, @r, htex); + + h:= 0; + if not hasGone then + for i:= 0 to cMaxHHIndex do + begin + inc(h, Hedgehogs[i].HealthBarHealth); + if (h < TeamHealthBarHealth) and (Hedgehogs[i].HealthBarHealth > 0) then + DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture); + end; + + // draw ai kill counter for gfAISurvival + if (GameFlags and gfAISurvival) <> 0 then + begin + DrawTexture(TeamHealthBarWidth + 22, cScreenHeight + DrawHealthY + smallScreenOffset, AIKillsTex); + end; + + // if highlighted, draw flag and other contents again to keep their colors + // this approach should be faster than drawing all borders one by one tinted or not + if highlight then + begin + if TeamsCount * 100 > Longword(cScreenHeight) then + Tint($FF,$FF,$FF,$80) + else untint; + + if OwnerTex <> nil then + begin + r.x:= 2; + r.y:= 2; + r.w:= OwnerTex^.w - 4; + r.h:= OwnerTex^.h - 4; + DrawTextureFromRect(-OwnerTex^.w - NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, OwnerTex) + end; + // draw name + r.x:= 2; + r.y:= 2; + r.w:= NameTagTex^.w - 4; + r.h:= NameTagTex^.h - 4; + DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex); + // draw flag + r.w:= 22; + r.h:= 15; + DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex); + end; + end; +if smallScreenOffset <> 0 then + begin + SetScale(cDefaultZoomLevel); + if TeamsCount * 20 > Longword(cScreenHeight) div 5 then + Tint($FF,$FF,$FF,$FF); + end; +end; + + +>>>>>>> other procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode); -var i, t, h: LongInt; +var i, t: LongInt; r: TSDL_Rect; tdx, tdy: Double; s: shortstring; - highlight: Boolean; - smallScreenOffset, offsetX, offsetY, screenBottom: LongInt; + offsetX, offsetY, screenBottom: LongInt; VertexBuffer: array [0..3] of TVertex2f; - lw, lh: GLfloat; - WorldEnd, WorldFade : array[0..3] of HwColor4f; begin if (cReducedQuality and rqNoBackground) = 0 then begin @@ -1193,7 +1404,7 @@ ChangeDepth(RM, -cStereo_Horizon); DrawRepeated(sprHorizont, sprHorizontL, sprHorizontR, (WorldDx + LAND_WIDTH div 2) * 3 div 5, HorizontOffset); if SuddenDeathDmg then - Tint($FF, $FF, $FF, $FF); + untint; end; DrawVisualGears(0); @@ -1304,111 +1515,46 @@ end; {$WARNINGS ON} -if WorldEdge <> weNone then - begin -(* I think for a bounded world, will fill the left and right areas with black or something. Also will probably want various border effects/animations based on border type. Prob also, say, trigger a border animation timer on an impact. *) - - FillChar(WorldFade, sizeof(WorldFade), 0); - WorldFade[0].a:= 255; - WorldFade[1].a:= 255; - FillChar(WorldEnd, sizeof(WorldEnd), 0); - WorldEnd[0].a:= 255; - WorldEnd[1].a:= 255; - WorldEnd[2].a:= 255; - WorldEnd[3].a:= 255; - - glDisable(GL_TEXTURE_2D); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glPushMatrix; - glTranslatef(WorldDx, WorldDy, 0); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]); - - VertexBuffer[0].X:= leftX-20; - VertexBuffer[0].Y:= -3000; - VertexBuffer[1].X:= leftX-20; - VertexBuffer[1].Y:= cWaterLine+cVisibleWater; - VertexBuffer[2].X:= leftX+30; - VertexBuffer[2].Y:= cWaterLine+cVisibleWater; - VertexBuffer[3].X:= leftX+30; - VertexBuffer[3].Y:= -3000; - - glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); - glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); - - VertexBuffer[0].X:= rightX+20; - VertexBuffer[1].X:= rightX+20; - VertexBuffer[2].X:= rightX-30; - VertexBuffer[3].X:= rightX-30; - - glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); - glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); - - glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldEnd[0]); - - VertexBuffer[0].X:= -5000; - VertexBuffer[1].X:= -5000; - VertexBuffer[2].X:= leftX-20; - VertexBuffer[3].X:= leftX-20; - - glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); - glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); - - VertexBuffer[0].X:= rightX+5000; - VertexBuffer[1].X:= rightX+5000; - VertexBuffer[2].X:= rightX+20; - VertexBuffer[3].X:= rightX+20; - - glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); - glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); - - glPopMatrix; - glDisableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required - glEnable(GL_TEXTURE_2D); - - DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 3.0, $FF, $00, $FF, $FF); - DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 3.0, $FF, $00, $FF, $FF); - end; +RenderWorldEdge(Lag); // this scale is used to keep the various widgets at the same dimension at all zoom levels SetScale(cDefaultZoomLevel); // Turn time -{$IFDEF USE_TOUCH_INTERFACE} -offsetX:= cScreenHeight - 13; -{$ELSE} -offsetX:= 48; -{$ENDIF} -offsetY:= cOffsetY; -if ((TurnTimeLeft <> 0) and (TurnTimeLeft < 1000000)) or (ReadyTimeLeft <> 0) then +if UIDisplay <> uiNone then begin - if ReadyTimeLeft <> 0 then - i:= Succ(Pred(ReadyTimeLeft) div 1000) - else - i:= Succ(Pred(TurnTimeLeft) div 1000); - - if i>99 then - t:= 112 - else if i>9 then - t:= 96 - else - t:= 80; - DrawSprite(sprFrame, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, 1); - while i > 0 do +{$IFDEF USE_TOUCH_INTERFACE} + offsetX:= cScreenHeight - 13; +{$ELSE} + offsetX:= 48; +{$ENDIF} + offsetY:= cOffsetY; + if ((TurnTimeLeft <> 0) and (TurnTimeLeft < 1000000)) or (ReadyTimeLeft <> 0) then begin - dec(t, 32); - DrawSprite(sprBigDigit, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, i mod 10); - i:= i div 10 + if ReadyTimeLeft <> 0 then + i:= Succ(Pred(ReadyTimeLeft) div 1000) + else + i:= Succ(Pred(TurnTimeLeft) div 1000); + + if i>99 then + t:= 112 + else if i>9 then + t:= 96 + else + t:= 80; + DrawSprite(sprFrame, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, 1); + while i > 0 do + begin + dec(t, 32); + DrawSprite(sprBigDigit, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, i mod 10); + i:= i div 10 + end; + DrawSprite(sprFrame, -(cScreenWidth shr 1) + t - 4 + offsetY, cScreenHeight - offsetX, 0); end; - DrawSprite(sprFrame, -(cScreenWidth shr 1) + t - 4 + offsetY, cScreenHeight - offsetX, 0); - end; // Captions -DrawCaptions; + DrawCaptions + end; {$IFDEF USE_TOUCH_INTERFACE} // Draw buttons Related to the Touch interface @@ -1424,106 +1570,16 @@ DrawScreenWidget(@utilityWidget); {$ENDIF} -// Teams Healths -if TeamsCount * 20 > Longword(cScreenHeight) div 7 then // take up less screen on small displays - begin - SetScale(1.5); - smallScreenOffset:= cScreenHeight div 6; - if TeamsCount * 20 > Longword(cScreenHeight) div 5 then - Tint($FF,$FF,$FF,$80); - end -else smallScreenOffset:= 0; -for t:= 0 to Pred(TeamsCount) do - with TeamsArray[t]^ do - if TeamHealth > 0 then - begin - h:= 0; - highlight:= bShowFinger and (CurrentTeam = TeamsArray[t]) and ((RealTicks mod 1000) < 500); - - if highlight then - Tint(Clan^.Color shl 8 or $FF); - - // draw name - DrawTexture(-NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset, NameTagTex); - - // draw flag - DrawTexture(-14, cScreenHeight + DrawHealthY + smallScreenOffset, FlagTex); - - // draw health bar - r.x:= 0; - r.y:= 0; - r.w:= 2 + TeamHealthBarWidth; - r.h:= HealthTex^.h; - DrawTextureFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex); - - // draw health bars right border - inc(r.x, cTeamHealthWidth + 2); - r.w:= 3; - DrawTextureFromRect(TeamHealthBarWidth + 15, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex); - - if (not highlight) and (not hasGone) then - for i:= 0 to cMaxHHIndex do - if Hedgehogs[i].Gear <> nil then - begin - inc(h,Hedgehogs[i].Gear^.Health); - if h < TeamHealth then DrawTexture(15 + h*TeamHealthBarWidth div TeamHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture); - end; - - // draw ai kill counter for gfAISurvival - if (GameFlags and gfAISurvival) <> 0 then - begin - DrawTexture(TeamHealthBarWidth + 22, cScreenHeight + DrawHealthY + smallScreenOffset, AIKillsTex); - end; - - // if highlighted, draw flag and other contents again to keep their colors - // this approach should be faster than drawing all borders one by one tinted or not - if highlight then - begin - if TeamsCount * 20 > Longword(cScreenHeight) div 5 then - Tint($FF,$FF,$FF,$80) - else Tint($FF, $FF, $FF, $FF); - - // draw name - r.x:= 2; - r.y:= 2; - r.w:= NameTagTex^.w - 4; - r.h:= NameTagTex^.h - 4; - DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex); - // draw flag - r.w:= 22; - r.h:= 15; - DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex); - // draw health bar - r.w:= TeamHealthBarWidth + 1; - r.h:= HealthTex^.h - 4; - DrawTextureFromRect(15, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, HealthTex); - if not hasGone and (TeamHealth > 1) then - begin - Tint(Clan^.Color shl 8 or $FF); - for i:= 0 to cMaxHHIndex do - if Hedgehogs[i].Gear <> nil then - begin - inc(h,Hedgehogs[i].Gear^.Health); - if h < TeamHealth then DrawTexture(15 + h*TeamHealthBarWidth div TeamHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture); - end; - if TeamsCount * 20 > Longword(cScreenHeight) div 5 then - Tint($FF,$FF,$FF,$80) - else Tint($FF, $FF, $FF, $FF); - end; - end; - end; -if smallScreenOffset <> 0 then - begin - SetScale(cDefaultZoomLevel); - if TeamsCount * 20 > Longword(cScreenHeight) div 5 then - Tint($FF,$FF,$FF,$FF); - end; +if UIDisplay = uiAll then + RenderTeamsHealth; // Lag alert if isInLag then DrawSprite(sprLag, 32 - (cScreenWidth shr 1), 32, (RealTicks shr 7) mod 12); // Wind bar +if UIDisplay <> uiNone then + begin {$IFDEF USE_TOUCH_INTERFACE} offsetX:= cScreenHeight - 13; offsetY:= (cScreenWidth shr 1) + 74; @@ -1545,14 +1601,15 @@ else if WindBarWidth < 0 then begin - {$WARNINGS OFF} - r.x:= (Longword(WindBarWidth) + RealTicks shr 6) mod 8; - {$WARNINGS ON} - r.y:= 0; - r.w:= - WindBarWidth; - r.h:= 13; - DrawSpriteFromRect(sprWindL, r, (cScreenWidth shr 1) - offsetY + 74 + WindBarWidth, cScreenHeight - offsetX + 2, 13, 0); - end; + {$WARNINGS OFF} + r.x:= (Longword(WindBarWidth) + RealTicks shr 6) mod 8; + {$WARNINGS ON} + r.y:= 0; + r.w:= - WindBarWidth; + r.h:= 13; + DrawSpriteFromRect(sprWindL, r, (cScreenWidth shr 1) - offsetY + 74 + WindBarWidth, cScreenHeight - offsetX + 2, 13, 0); + end + end; // AmmoMenu if bShowAmmoMenu and ((AMState = AMHidden) or (AMState = AMHiding)) then @@ -1588,7 +1645,9 @@ DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture); if isPaused then DrawTextureCentered(0, (cScreenHeight shr 1), PauseTexture); -if (not isFirstFrame) and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then +if isAFK then + DrawTextureCentered(0, (cScreenHeight shr 1), AFKTexture); +if not isFirstFrame and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then begin if (ReadyTimeLeft = 0) and (missionTimer > 0) then dec(missionTimer, Lag); @@ -1694,8 +1753,8 @@ glDrawArrays(GL_TRIANGLE_FAN, 0, High(VertexBuffer) - Low(VertexBuffer) + 1); glEnable(GL_TEXTURE_2D); - Tint($FF, $FF, $FF, $FF); - if (not isFirstFrame) and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then + untint; + if not isFirstFrame and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then ScreenFade:= sfNone end end; @@ -1722,7 +1781,7 @@ for i:= 0 to 20 do glVertex2f(-(cScreenWidth shr 1) + 30 + sin(i*2*Pi/20)*10, 35 + cos(i*2*Pi/20)*10); glEnd(); - Tint($FF, $FF, $FF, $FF); + untint; glEnable(GL_TEXTURE_2D); end; {$ENDIF} @@ -1779,13 +1838,15 @@ procedure MoveCamera; var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY: LongInt; + inbtwnTrgtAttks: Boolean; begin {$IFNDEF MOBILE} if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu) and autoCameraOn)) and cHasFocus and (GameState <> gsConfirm) then uCursor.updatePosition(); {$ENDIF} z:= round(200/zoom); -if (not PlacingHogs) and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and autoCameraOn then +inbtwnTrgtAttks := (CurrentHedgehog <> nil) and ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0) and ((GameFlags and gfInfAttack) <> 0); +if autoCameraOn and not PlacingHogs and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and not inbtwnTrgtAttks then if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then begin FollowGear:= nil; @@ -2040,6 +2101,16 @@ AMState:= AMHidden; isFirstFrame:= true; stereoDepth:= stereoDepth; // avoid hint + + FillChar(WorldFade, sizeof(WorldFade), 0); + WorldFade[0].a:= 255; + WorldFade[1].a:= 255; + FillChar(WorldEnd, sizeof(WorldEnd), 0); + WorldEnd[0].a:= 255; + WorldEnd[1].a:= 255; + WorldEnd[2].a:= 255; + WorldEnd[3].a:= 255; + end; procedure freeModule; diff -r 8054d9d775fd -r 2759212a27de misc/libphysfs/platform_unix.c --- a/misc/libphysfs/platform_unix.c Fri Oct 11 17:43:13 2013 +0200 +++ b/misc/libphysfs/platform_unix.c Sat Jan 04 23:55:54 2014 +0400 @@ -193,7 +193,7 @@ if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */ { - exe[size - binlen] = '\0'; /* chop off filename, leave '/' */ + exe[size - binlen - 1] = '\0'; /* chop off filename, leave '/' */ return exe; } /* if */ diff -r 8054d9d775fd -r 2759212a27de misc/libphyslayer/CMakeLists.txt --- a/misc/libphyslayer/CMakeLists.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/misc/libphyslayer/CMakeLists.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,5 +1,5 @@ -find_package(SDL REQUIRED) +find_package(SDL1or2) include_directories(${PHYSFS_INCLUDE_DIR}) include_directories(${SDL_INCLUDE_DIR}) include_directories(${LUA_INCLUDE_DIR}) diff -r 8054d9d775fd -r 2759212a27de project_files/HedgewarsMobile/Locale/Turkish.lproj/Localizable.strings Binary file project_files/HedgewarsMobile/Locale/Turkish.lproj/Localizable.strings has changed diff -r 8054d9d775fd -r 2759212a27de project_files/HedgewarsMobile/Locale/Turkish.lproj/Scheme.strings Binary file project_files/HedgewarsMobile/Locale/Turkish.lproj/Scheme.strings has changed diff -r 8054d9d775fd -r 2759212a27de project_files/HedgewarsMobile/Locale/hw-desc_tr.txt Binary file project_files/HedgewarsMobile/Locale/hw-desc_tr.txt has changed diff -r 8054d9d775fd -r 2759212a27de project_files/hedgewars.pro --- a/project_files/hedgewars.pro Fri Oct 11 17:43:13 2013 +0200 +++ b/project_files/hedgewars.pro Sat Jan 04 23:55:54 2014 +0400 @@ -114,7 +114,8 @@ ../QTfrontend/ui/widget/feedbackdialog.h \ ../QTfrontend/ui/widget/lineeditcursor.h \ ../QTfrontend/servermessages.h \ - ../QTfrontend/ui/widget/roomnameprompt.h + ../QTfrontend/ui/widget/roomnameprompt.h \ + ../QTfrontend/weapons.h SOURCES += ../QTfrontend/model/ammoSchemeModel.cpp \ diff -r 8054d9d775fd -r 2759212a27de share/Info.plist.in --- a/share/Info.plist.in Fri Oct 11 17:43:13 2013 +0200 +++ b/share/Info.plist.in Sat Jan 04 23:55:54 2014 +0400 @@ -23,7 +23,7 @@ CFBundleShortVersionString ${HEDGEWARS_VERSION} NSHumanReadableCopyright - Copyright © 2004-2012, Hedgewars Project + Copyright © 2004-2014, Hedgewars Project NSAppleScriptEnabled LSRequiresNativeExecution diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Crosshair.png Binary file share/hedgewars/Data/Graphics/Crosshair.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/Einstein.png Binary file share/hedgewars/Data/Graphics/Hats/Einstein.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/constructor.png Binary file share/hedgewars/Data/Graphics/Hats/constructor.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/doctor.png Binary file share/hedgewars/Data/Graphics/Hats/doctor.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/nurse.png Binary file share/hedgewars/Data/Graphics/Hats/nurse.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/punkman.png Binary file share/hedgewars/Data/Graphics/Hats/punkman.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/scif_cosmonaut.png Binary file share/hedgewars/Data/Graphics/Hats/scif_cosmonaut.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/scif_cyberpunk.png Binary file share/hedgewars/Data/Graphics/Hats/scif_cyberpunk.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/snorkel.png Binary file share/hedgewars/Data/Graphics/Hats/snorkel.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/tf_demoman.png Binary file share/hedgewars/Data/Graphics/Hats/tf_demoman.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/tf_scount.png Binary file share/hedgewars/Data/Graphics/Hats/tf_scount.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_gakupo.png Binary file share/hedgewars/Data/Graphics/Hats/vc_gakupo.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_gumi.png Binary file share/hedgewars/Data/Graphics/Hats/vc_gumi.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_kaito.png Binary file share/hedgewars/Data/Graphics/Hats/vc_kaito.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_len.png Binary file share/hedgewars/Data/Graphics/Hats/vc_len.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_luka.png Binary file share/hedgewars/Data/Graphics/Hats/vc_luka.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_meiko.png Binary file share/hedgewars/Data/Graphics/Hats/vc_meiko.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_miku.png Binary file share/hedgewars/Data/Graphics/Hats/vc_miku.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hats/vc_rin.png Binary file share/hedgewars/Data/Graphics/Hats/vc_rin.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/Hedgehog/amWhip.png Binary file share/hedgewars/Data/Graphics/Hedgehog/amWhip.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/amRubber.png Binary file share/hedgewars/Data/Graphics/amRubber.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/amRubber.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Graphics/amRubber.svg Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,657 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/boing.png Binary file share/hedgewars/Data/Graphics/boing.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Graphics/boing.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Graphics/boing.svg Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,40 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/CMakeLists.txt --- a/share/hedgewars/Data/Locale/CMakeLists.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/CMakeLists.txt Sat Jan 04 23:55:54 2014 +0400 @@ -4,6 +4,7 @@ file(GLOB luafiles *.lua) file(GLOB missionfiles missions_*.txt) file(GLOB campaignfiles campaigns_*.txt) +file(GLOB tipfiles tips_*.xml) QT4_ADD_TRANSLATION(QM ${tsfiles}) @@ -19,6 +20,7 @@ ${luafiles} ${missionfiles} ${campaignfiles} + ${tipfiles} DESTINATION ${SHAREPATH}Data/Locale ) diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/campaigns_de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/campaigns_de.txt Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,43 @@ +A_Classic_Fairytale-first_blood.desc="Hilf Leaks a lot dabei, sein Training zu absolvieren und zu einem richtigen Igelkrieger zu werden. Du wirst in der Kunst des Seils, Fallschirms, Shoryukens und der Desert Eagle trainiert." + +A_Classic_Fairytale-shadow.desc="Leaks a lot und Dense Cloud gehen für die Jagd raus. Sei auf Gefahren im Wald gefasst. Denk dran, bedenke deine Entscheidungen gut." + +A_Classic_Fairytale-journey.desc="Leaks a lot muss zur anderen Seite der Insel gehen. Sei schnell und vorsichtig." + +A_Classic_Fairytale-united.desc="Nach seiner langen Reise kehrte Leaks a lot endlich wieder zum Dorf zurück. Allerdings gibt es keine Zeit zum Ausruhen. Du musst das Dorf von der Rage der Kannibalen verteidigen." + +A_Classic_Fairytale-backstab.desc="Die monströsen Kannibalen jagen Leaks a lot und seine Freunde. Besiege sie erneut und beschütze deine Freunde. Benutze deine Ressourcen entsprechend, um die eintreffenden Feinde zu besiegen!" + +A_Classic_Fairytale-dragon.desc="Leaks a lot muss auf die andere Seite des Sees kommen. Werd zum Seilprofi und vermeide es, von feindlichen Schüssen getroffen zu werden." + +A_Classic_Fairytale-family.desc="Leaks a lot muss erneut seine Freunde retten. Eliminiere die feindlichen Igel und befreie deine Kameraden. Benutze deine Ressourcen vorsichtig, weil sie begrenzt sind. Bohr ein paar Löcher an den richtigen Stellen und nähere dich der Prinzessin." + +A_Classic_Fairytale-queen.desc="Leaks a lot muss noch einmal kämpfen. Um zu gewinnen, muss er den Veräräter bekämpfen und alle verfügbaren Ressourcen benutzen. Besieg den Feind!" + +A_Classic_Fairytale-enemy.desc="Was für eine umwerfende Wendung! Leaks a lot muss mit den … »Kannibalen« gegen den gemeinsamen Feind – die bösen Cyborgs – kämpfen!" + +A_Classic_Fairytale-epil.desc="Gratulation! Leaks a lot kann endlich in Frieden gehen und von seinen neuen Freunden und seinem Stamm angepriesen werden. Sei stolz auf das, was du erreicht hast! Du kannst vorherige Missionen wieder spielen und andere mögliche Enden sehen." + +A_Space_Adventure-cosmos.desc="Hogera, der Igelplanet, wird bald von einem riesigen Meteroid getroffen. In diesem Wettlauf ums Überleben musst du PAdIs besten Piloten, Hog Solo, in einer Weltraumreise um die Nachbarplaneten führen, um alle 4 Teil des lang verschollenem Antigravitationsgeräts zu finden!" + +A_Space_Adventure-moon01.desc="Hog Solo ist auf dem Mond gelandet, um seine fliegende Untertasse aufzutanken, aber Prof. Hogevil war zuerst da und hat einen Hinterhalt aufgestellt! Rette die gefangenen PAdI-Forscher und verscheuche Prof. Hogevil!" + +A_Space_Adventure-moon02.desc="Hog Solo besucht einen Eremiten, einen alten PAdI-Veteran, der im Mond lebt, um Prof. Hogevil auszuspionieren. Allerdings muss er den Eremiten, Soneek the Crazy Runner, zuerst in einem Wettlauf besiegen!" + +A_Space_Adventure-ice01.desc="Willkommen auf dem Planeten des Eises. Hier ist es so kalt, dass Hog Solos meiste Waffe nicht funktionieren werden. Du musst dir das verlorene Teil von dem Banditenanführer Thanta ergattern, indem du die Waffen, die du hier findest, verwendest!" + +A_Space_Adventure-ice02.desc="Hog Solo konnt nicht einfach nur den Eisplaneten besuchen, ohne das Olympiastadion des Untertassenfliegens zu besuchen! In dieser Mission kannst du deine Flugkünste unter Beweis stellen und deinen Platz unter den Besten einnehmen!" + +A_Space_Adventure-desert01.desc="Du must auf dem Planeten aus Sand gelandet! Hog Solo muss das fehlende Teil in den Berkwerksstollen finden. Sei vorsichtig, weil bösartige Schmuggler nur darauf warten, dich anzugreifen und auszurauben!" + +A_Space_Adventure-desert02.desc="Hog Solo suchte nach dem Teil in diesem Tunnel, als er unerwarteterweise anfing, geflutet zu werden! Komm so schnell wie möglich zur Oberfläche und pass auf, keine Mine auszulösen." +A_Space_Adventure-desert03.desc="Hog Solo hat etwas Zeit, um sein Funkflugzeug zu fliegen und etwas Spaß zu haben. Flieg das Funkflugzeug und triff alle Ziele!" +A_Space_Adventure-fruit01.desc="Auf dem Obstplaneten laufen die Dinge nicht so gut. Igel sammeln kein Obst, sondern sie bereiten sich auf den Kampf vor. Du musst dich entscheiden, ob du kämpfen oder fliehen wirst." +A_Space_Adventure-fruit02.desc="Hog Solo nähert sich dem verlorenen Teil des Obstplaneten. Wird ihn Captain Lime dabei helfen, das Teil zu besorgen? Oder nicht?" + +A_Space_Adventure-fruit03.desc="Hog Solo has sich verlaufen und ist in den Hinterhalt der Roten Erdbeeren geraten. Hilf ihm, sie zu eliminieren, um etwas zusätzliche Munition für die Mission »Getting to the device« zu gewinnen." + +A_Space_Adventure-death01.desc="Auf dem Todesplaneten, dem sterilsten Planeten in der Gegend, ist Hog Solo ganz kurz davor, das letzte Teil des Geräts zu holen! Allerdings erwartet ihn eine unangenehme Überraschnug." + +A_Space_Adventure-death02.desc="Hog Solo ist wieder in eine schwierige Situation geraten. Hilf ihm, die »5 tödlichen Igel« in ihrem eigenem Spiel zu besiegen!" +A_Space_Adventure-final.desc="Hog Solo muss ein paar Sprengkörper, die auf dem Meterioden platziert wurden, detonieren. Hilf ihm, diese Mission zu beenden, ohne verletzt zu werden!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/campaigns_el.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/campaigns_el.txt Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,34 @@ +A_Classic_Fairytale-first_blood.desc="Βοήθησε τον Leaks a lot να ολοκληρώσει την εκπαίδευσή του και να γίνει ένας κανονικός πολεμιστής σκαντζόχοιρος. Θα εκπαιδευτείς στη τέχνη του σκοινιού, του αλεξίπτωτου, της μπουνιάς και της σκοποβολής με όπλο." + +A_Classic_Fairytale-shadow.desc="Ο Leaks a lot και ο Dense Cloud πηγαίνουν για κυνήγι. Να είσαι έτοιμος για τους κινδύνους που παραμονεύουν στο δάσος. Θυμίσου, κάνε τις επιλογές σου προσεκτικά." + +A_Classic_Fairytale-journey.desc="Ο Leaks a lot πρέπει να πάει στην άλλη μεριά του νησιού. Να είσαι γρήγορος και προσεκτικός." + +A_Classic_Fairytale-united.desc="Μετά το μεγάλο του ταξίδι ο Leaks a lot επιστρέφει επιτέλους στο χωριό. Παρόλα αυτά δεν υπάρχει χρόνος για ξεκούραση. Πρέπει να υπερασπιστείς το χωριό από την οργή των κανίβαλων." + +A_Classic_Fairytale-backstab.desc="Οι τερατώδεις κανίβαλοι κυνηγούν τον Leaks a lot και τους φίλους του. Νίκησε τους άλλη μία φορά και προστάτεψε τους συμμάχους σου. Χρησιμοποίησε τον εξοπλισμό σου κατάλληλα για να νικήσεις τους εχθρούς!" + +A_Classic_Fairytale-dragon.desc="Ο Leaks a lot πρέπει να φτάσει στην άλλη μεριά της λίμνης. Γίνε μαέστρος του σκοινιού και απέφυγε τα πυρά των αντιπάλων." + +A_Classic_Fairytale-family.desc="Ο Leaks a lot πρέπει να σώσει ξανά τους συμμάχους του. Εξόντωσε τους εχθρικούς σκαντζόχοιρους και ελευθέρωσε τους συμμάχους. Χρησιμοποίησε τον εξοπλισμό σου προσεκτικά καθώς είναι περιορισμένος. Άνοιξε μερικές τρύπες στο σωστό σημείο και πήγαινε κοντά στην πριγκίπισσα." + +A_Classic_Fairytale-queen.desc="Ο Leaks a lot πρέπει να πολεμήσει και πάλι. Για να νικήσεις πρέπει να πολεμήσεις τον προδότη και να χρησιμοποιήσεις όλο τον διαθέσιμο εξοπλισμό. Νίκησε τον εχθρό!" + +A_Classic_Fairytale-enemy.desc="Τι μεγάλη αλλαγή στην πλοκή! Ο Leaks a lot πρέπει να πολεμήσει πλαϊ στους… “κανίβαλους” εναντίον στον κοινό εχθρό. Τα υποχθόνια ανδροειδη!" + +A_Classic_Fairytale-epil.desc="Συγχαρητήρια! Ο Leaks a lot μπορεί επιτέλους να ζήσει ήσυχα και να δοξαστεί από τους νέους φίλους του και τη φυλή του. Να είσαι περίφανος για αυτό που κατάφερες! Μπορείς να παίξεις τις προηγούμενες αποστολές και δεις τα άλλα πιθανά αποτελέσματα." + +A_Space_Adventure-cosmos.desc="Η Hogera, ο πλανήτης των σκαντζόχοιρων πρόκειται να συγκρουστεί με έναν γιγαντιαίο μετεωρίτη. Σε αυτό τον αγώνα για επιβίωση πρέπει να οδηγήσετε τον καλύτερο πιλότο της PAotH, Hog Solo, σε ένα διαστημικό ταξίδι στους γειτονικούς πλανήτες για να συλλέξει τα 4 χαμένα κομμάτια της συσκευής αντιβαρύτητας!" +A_Space_Adventure-moon01.desc="Ο Hog Solo έχει προσγειωθεί στο φεγγάρι για να ανεφοδειάσει με κάυσιμα τον δίσκο αλλά ο καθηγητής Hogevil έχει φτάσει εκεί πρώτος και έχει στήσει ενέδρα! Σώσε τους φυλακισμένους ερευνητές του PAotH και διώξε τον καθηγητή Hogevil!" +A_Space_Adventure-moon02.desc="Ο Hog Solo επισκέπτεται έναν ερημίτη, παλιό βετεράνο του PAotH, που ζει στο φεγγάρι για να συλέξει πληροφορίες σχετικά με τον Καθηγητή Hogevil. Ωστόσο, πρέπει να νικήσει πρώτα τον ερημίτη, τον Soneek τον Τρελό Δρομέα, σε ένα παιχνίδι κυνηγητού!" +A_Space_Adventure-ice01.desc="Καλώς ήλθατε στον πλανήτη του πάγου. Εδώ, είναι τόσο κρύα που ο περισσότερος εξοπλισμός του Hog Solo δεν λειτουργεί. Πρέπει να πάρεις το χαμένο κομμάτι από τον Thanta, τον αρχηγό των κλεφτών, χρησιμοποιώντας τον εξοπλισμό που θα βρεις εκεί!" +A_Space_Adventure-ice02.desc="Ο Hog Solo δεν μπορούσε να επισκεφτεί απλά τον Παγωμένο Πλανήτη χωρίς να επισκεφτεί το ολυμπιακό στάδιο πτήσης δίσκων! Σε αυτή την αποστολή θα επιβεβαιώσετε τις ικανότητες πτήσης σας και θα διεκδικήσετε τη θέση που σας ανοίκει ανάμεσα στους καλύτερους!" +A_Space_Adventure-desert01.desc="Προσγειωθήκατε στον πλανήτη της άμμου! Ο Hog Solo πρέπει να βρει το χαμένο κομμάτι στις υπόγειες στοές. Προσοχή καθώς μοχθηροί κλέφτες περιμένουν να σας επιτεθούν και να σας ληστέψουν!" +A_Space_Adventure-desert02.desc="O Hog Solo έψαχνε το κομμάτι σε αυτή τη στοά όταν απρόσμενα ξεκίνησε να πλημμυρίζει! Πήγαινε στην επιφάνεια το συντομότερο δυνατό και πρόσεχε μην πυροδοτήσεις κάποια νάρκη." +A_Space_Adventure-desert03.desc="Ο Hog Solo έχει λίγο χρόνο για να πετάξει το τηλεκατευθυνόμενο αεροπλάνο του και να περάσει καλά. Πέτα το τηλεκατευθυνόμενο και χτύπα όλους τους στόχους!" +A_Space_Adventure-fruit01.desc="Στον Φρουτο-πλανήτη τα πράγματα δεν πηγαίνουν τόσο καλά. Οι σκαντζόχοιροι δεν μαζεύουν φρούτα αλλά ετοιμάζονται για μάχη. Θα πρέπει να επιλέξεις εάν θα πολεμήσεις ή θα υποχωρήσεις." +A_Space_Adventure-fruit02.desc="Ο Hog Solo πλησιάζει στο χαμένο κομμάτι στον Φρουτο-πλανήτη. Θα τον βοηθήσει ο Captain Lime να πάρει το κομμάτι ή όχι?" +A_Space_Adventure-fruit03.desc="Ο Hog Solo χάθηκε και έπεσε στην ενέδρα των Red Strawberies. Βοήθησε τον να τους εξοντώσει και κέρδισε περισσότερα πυρομαχικά για την αποστολή Getting to the device." +A_Space_Adventure-death01.desc="Στον Πλανήτη του Θανάτου, τον πιο άγονο πλανήτη απ'όλους, ο Hog Solo είναι πολύ κοντά να πάρει το τελευταίο κομμάτι της συσκευής! Ωστόσο μία δυσάρεστη έκλπηξη τον περιμένει..." +A_Space_Adventure-death02.desc="Ξανά ο Hog Solo έβαλε τον εαυτό του σε μία δύσκολη κατάσταση. Βοήθησε τον να νικήσει τους “5 deadly hogs“ στο δικό τους παιχνίδι!" +A_Space_Adventure-final.desc="Ο Hog Solo πρέπει να πυροδοτήσει μερικά εκρηκτικά που έχουν τοποθετηθεί στον μετεωρίτη. Βοήθησε τον να ολοκληρώσει την αποστολή του χωρίς να πάθει κακό!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/campaigns_en.txt --- a/share/hedgewars/Data/Locale/campaigns_en.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/campaigns_en.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,19 +1,34 @@ -A_Classic_Fairytale-first_blood.desc="Help Leaks a lot to complete his training and become a proper hedgehog warrior. You will be trained in the art of rope, parachute, shoryuken and desert eagle." - -A_Classic_Fairytale-shadow.desc="Leaks a lot and Dense Cloud are going for hunting. Be prepared for the dangers awaiting you at the forest. Remember, make your choices wisely." - -A_Classic_Fairytale-journey.desc="Leaks a lot has to go to the other side of the island. Be fast and cautious." - -A_Classic_Fairytale-united.desc="After his long journey Leaks a lot is finally back to the village. However, there isn't time to rest. You have to defend the village from the rage of the cannibals." - -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-dragon.desc="Leaks a lot has to get to the other side of the lake. Become a rope master and avoid get hit by the enemy shots." - -A_Classic_Fairytale-family.desc="Leaks a lot has to save once more his allies. Eliminate the enemy hogs and free your comrades. Use your resources carefully as they are limited. Drill some holes in the right spot and go close to the princess." - -A_Classic_Fairytale-queen.desc="Leaks a lot has to fight once again. In order to win he'll have to fight the traitor and use all the resources available. Defeat the enemy!" - -A_Classic_Fairytale-enemy.desc="What a great twist! Leaks a lot has to fight side by side with the… “cannibals” against the common enemy. The evil cyborgs!" - -A_Classic_Fairytale-epil.desc="Congratulations! Leaks a lot can finally leave in peace and get praised by his new friends and his tribe. Be proud for what you succeed! You can play again previous missions and see the other possible endings." +A_Classic_Fairytale-first_blood.desc="Help Leaks a lot to complete his training and become a proper hedgehog warrior. You will be trained in the art of rope, parachute, shoryuken and desert eagle." + +A_Classic_Fairytale-shadow.desc="Leaks a lot and Dense Cloud are going for hunting. Be prepared for the dangers awaiting you at the forest. Remember, make your choices wisely." + +A_Classic_Fairytale-journey.desc="Leaks a lot has to go to the other side of the island. Be fast and cautious." + +A_Classic_Fairytale-united.desc="After his long journey Leaks a lot is finally back to the village. However, there isn't time to rest. You have to defend the village from the rage of the cannibals." + +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-dragon.desc="Leaks a lot has to get to the other side of the lake. Become a rope master and avoid get hit by the enemy shots." + +A_Classic_Fairytale-family.desc="Leaks a lot has to save once more his allies. Eliminate the enemy hogs and free your comrades. Use your resources carefully as they are limited. Drill some holes in the right spot and go close to the princess." + +A_Classic_Fairytale-queen.desc="Leaks a lot has to fight once again. In order to win he'll have to fight the traitor and use all the resources available. Defeat the enemy!" + +A_Classic_Fairytale-enemy.desc="What a great twist! Leaks a lot has to fight side by side with the… “cannibals” against the common enemy. The evil cyborgs!" + +A_Classic_Fairytale-epil.desc="Congratulations! Leaks a lot can finally leave in peace and get praised by his new friends and his tribe. Be proud for what you succeed! You can play again previous missions and see the other possible endings." + +A_Space_Adventure-cosmos.desc="Hogera, the planet of hogs is about to be hit by a gigantic meteorite. In this race for survival you have to lead PAotH's best pilot, Hog Solo, in a space trip around the neighbor planets to collect all the 4 pieces of the long lost anti gravity device!" +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-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-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..." +A_Space_Adventure-death02.desc="Again Hog Solo has got himself in a difficult situation. Help him defeat the “5 deadly hogs“ in their own game!" +A_Space_Adventure-final.desc="Hog Solo has to detonate some explosives that have been placed on the meteorite. Help him complete his mission without getting hurt!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/campaigns_pt_BR.txt --- a/share/hedgewars/Data/Locale/campaigns_pt_BR.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/campaigns_pt_BR.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,19 +1,19 @@ -A_Classic_Fairytale-first_blood.desc="Ajude Vaza Demais a completar seu treinamento e a se tornar um guerreiro ouriço. Você será treinado na arte da corda, do paraquedas, do shoryuken e da pistola." - -A_Classic_Fairytale-shadow.desc="Vaza Demais e Nuvem Densa saíram para caçar. Esteja preparado para os perigos à sua espera na floresta. Lembre-se de fazer suas escolhas sabiamente." - -A_Classic_Fairytale-journey.desc="Vaza Demais tem que ir ao outro lado da ilha. Seja rápido e cauteloso." - -A_Classic_Fairytale-united.desc="Depois de sua longa jornada, Vaza Demais está finalmente de volta à vila. Entretanto, não há tempo para descanso. Você tem que defender a vila da fúria dos canibais." - -A_Classic_Fairytale-backstab.desc="Os monstruosos canibais estão caçando Vaza Demais e seus amigos. Derrote-os de uma vez e proteja seus aliados. Use seus recursos para derrotas os inimigos que chegam!" - -A_Classic_Fairytale-dragon.desc="Vaza Demais tem que chegar ao outro lado do lago. Torne-se um mestre na corda e evite ser atingido pelos tiros dos inimigos." - -A_Classic_Fairytale-family.desc="Vaza Demais tem que salvar mais uma vez seus aliados. Elimine os ouriços inimigos e liberte seus companheiros. Use seus recursos com cuidado já que são limitados. Cave alguns buracos no lugar certo e se aproxime da princesa." - -A_Classic_Fairytale-queen.desc="Vaza Demais tem que lutar mais uma vez. Para vencer, ele terá que lutar contra o traidor e usar todos os recursos disponíveis. Derrote o inimigo!" - -A_Classic_Fairytale-enemy.desc="Que grande virada! Vaza Demais tem que lutar lado a lado com os… “canibais” contra o inimigo comum. Os ciborgues malignos!" - -A_Classic_Fairytale-epil.desc="Parabéns! Vaza Demais pode finalmente ficar em paz e ser exaltado pelos seus novos amigos e sua tribo. Orgulhe-se do que conquistou! Você pode jogar missões anteriores novamente e ver outros finais possíveis." +A_Classic_Fairytale-first_blood.desc="Ajude Vaza Demais a completar seu treinamento e a se tornar um guerreiro ouriço. Você será treinado na arte da corda, do paraquedas, do shoryuken e da pistola." + +A_Classic_Fairytale-shadow.desc="Vaza Demais e Nuvem Densa saíram para caçar. Esteja preparado para os perigos à sua espera na floresta. Lembre-se de fazer suas escolhas sabiamente." + +A_Classic_Fairytale-journey.desc="Vaza Demais tem que ir ao outro lado da ilha. Seja rápido e cauteloso." + +A_Classic_Fairytale-united.desc="Depois de sua longa jornada, Vaza Demais está finalmente de volta à vila. Entretanto, não há tempo para descanso. Você tem que defender a vila da fúria dos canibais." + +A_Classic_Fairytale-backstab.desc="Os monstruosos canibais estão caçando Vaza Demais e seus amigos. Derrote-os de uma vez e proteja seus aliados. Use seus recursos para derrotas os inimigos que chegam!" + +A_Classic_Fairytale-dragon.desc="Vaza Demais tem que chegar ao outro lado do lago. Torne-se um mestre na corda e evite ser atingido pelos tiros dos inimigos." + +A_Classic_Fairytale-family.desc="Vaza Demais tem que salvar mais uma vez seus aliados. Elimine os ouriços inimigos e liberte seus companheiros. Use seus recursos com cuidado já que são limitados. Cave alguns buracos no lugar certo e se aproxime da princesa." + +A_Classic_Fairytale-queen.desc="Vaza Demais tem que lutar mais uma vez. Para vencer, ele terá que lutar contra o traidor e usar todos os recursos disponíveis. Derrote o inimigo!" + +A_Classic_Fairytale-enemy.desc="Que grande virada! Vaza Demais tem que lutar lado a lado com os… “canibais” contra o inimigo comum. Os ciborgues malignos!" + +A_Classic_Fairytale-epil.desc="Parabéns! Vaza Demais pode finalmente ficar em paz e ser exaltado pelos seus novos amigos e sua tribo. Orgulhe-se do que conquistou! Você pode jogar missões anteriores novamente e ver outros finais possíveis." diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/de.txt --- a/share/hedgewars/Data/Locale/de.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/de.txt Sat Jan 04 23:55:54 2014 +0400 @@ -40,9 +40,9 @@ 00:37=Vampirismus 00:38=Scharfschützengewehr 00:39=Fliegende Untertasse -00:40=Molotov-Cocktail +00:40=Molotowcocktail 00:41=Birdy -00:42=Tragbares Portal Device +00:42=Tragbares Portalgerät 00:43=Piano-Angriff 00:44=Alter Limburger 00:45=Sinuskanone @@ -53,12 +53,12 @@ 00:50=Bohr-Luftangriff 00:51=Schlammball 00:52=Keine Waffe ausgewählt -00:53=ZeitBox +00:53=Zeitkasten ; 00:54=Bauwerk 00:54=Landkanone -00:55=Gefrierer +00:55=Eiskanone 00:56=Hackebeil - +00:57=Gummi 01:00=Auf in die Schlacht! 01:01=Unentschieden @@ -113,7 +113,7 @@ 02:00=%1 hat die letzte Melone geworfen 02:00=%1 hat die letzte Deagle gezogen 02:00=%1 nahm einen Schuss zu viel -02:00=%1 hätte wirklich ein Erste-Hilfe-Kit gebrauchen können +02:00=%1 hätte wirklich einen Erste-Hilfe-Koffer gebrauchen können 02:00=%1 ist gegangen, um ein besseres Spiel zu spielen 02:00=%1 will nicht mehr 02:00=%1 scheitert @@ -376,7 +376,7 @@ 02:08=%1 zählt Schäfchen 02:08=%1 lässt sich die Sonne auf den Bauch scheinen 02:08=%1 genießt die Stille -02:08=%1 fragt sich ob es schon Zeit für den Winterschlaf ist +02:08=%1 fragt sich, ob es schon Zeit für den Winterschlaf ist ; Hog (%1) hurts himself only 02:09=%1 sollte lieber zielen üben! @@ -508,64 +508,69 @@ 03:53=Typ 40 ;03:54=Baue etwas 03:54=Werkzeug +03:55=Cooler wird’s nicht +03:56=Bitte ge- oder missbrauchen +03:57=Werkzeug ; Weapon Descriptions (use | as line breaks) -04:00=Greife deine Feinde mit einfachen Granaten an.|Der Zeitzünder steuert den Explosionszeitpunkt.|1-5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen -04:01=Greife deine Feinde mit Splittergranaten an.|Der Zeitzünder wird die Granate in mehrere|kleine Bomben zerspringen lassen.|1-5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen +04:00=Greife deine Feinde mit einfachen Granaten an.|Der Zeitzünder steuert den Explosionszeitpunkt.|1–5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen +04:01=Greife deine Feinde mit Splittergranaten an.|Der Zeitzünder wird die Granate in mehrere|kleine Bomben zerspringen lassen.|1–5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen 04:02=Greife deine Feinde mit einem ballistischen|Projektil an, das vom Wind beeinflusst wird.|Angriff: Halten, um mit mehr Kraft zu feuern 04:03=Starte eine explosive Biene, die auf ein gewähltes|Ziel zusteuern wird. Feuere nicht mit voller Kraft,|um die Zielgenauigkeit zu verbessern.|Cursor: Ziel wählen|Angriff: Halten, um mit mehr Kraft zu feuern 04:04=Greife deine Feinde mit einer Schrotflinte und|zwei Schüssen an. Durch die Streuung musst du|nicht genau zielen, um trotzdem zu treffen.|Angriff: Feuern (mehrfach) 04:05=Ab in den Untergrund! Benutze den Presslufthammer,|um einen Schacht nach unten zu graben und so|andere Gebiete zu erreichen.|Angriff: Presslufthammer ein- oder ausschalten 04:06=Gelangweilt? Keine Optionen? Munition sparen?|Kein Problem! Passe einfach diese Runde, Feigling!|Angriff: Runde ohne Angriff aussetzen -04:07=Überbrücke große Distanzen mit gezielt abgefeuerten|Seilschüssen. Benutze deine Bewegungsenergie, um|andere Igel zu schubsen oder wirf vom Seil aus Granaten|und ähnliche Waffen.|Angriff: Seil abfeuern oder lösen|Weiter Sprung: Waffe benutzen +04:07=Überbrücke große Distanzen mit gezielt abgefeuerten|Seilschüssen. Benutze deine Bewegungsenergie, um|andere Igel zu schubsen oder wirf vom Seil aus Granaten|und ähnliche Waffen.|Angriff: Seil abfeuern oder lösen|Weitsprung: Waffe benutzen 04:08=Halte dir deine Feinde fern oder blockiere sie,|indem du ihnen Minen vor die Beine wirfst.|Sei aber schnell genug, damit du sie nicht noch|selbst auslöst!|Angriff: Mine legen 04:09=Nicht so ganz zielsicher? Versuche es mit der|Desert Eagle, denn diese bietet dir vier Schuss.|Angriff: Feuern (mehrfach) -04:10=Pure Gewalt ist immer eine Option. Lege einfach|diesen klassischen Sprengsatz neben deinen Feinden|ab und mach dich aus dem Staub.|Angriff: Dynamitstange legen +04:10=Rohe Gewalt ist immer eine Lösung. Lege einfach|diesen klassischen Sprengsatz neben deinen Feinden|ab und mach dich aus dem Staub.|Angriff: Dynamitstange legen 04:11=Beseitige Feinde, indem du diese mit dem|Baseballschläger einfach von der Karte fegst.|Oder wie wäre es, wenn du deinen Freunden ein|paar Minen vor die Beine schlägst?|Angriff: Alles vor dem Igel schlagen 04:12=Rücke mit deinen Feinden näher zusammen und|entfessle die Kraft dieser so gut wie tödlichen|Kampftechnik.|Angriff: Feuerfaust einsetzen 04:13=UNUSED -04:14=Höhenangst? Greif besser zum Fallschirm.|Er wird sich von alleine entfalten, wenn du|zu lange oder zu tief fällst, und so deinem|Igel den Hals retten.|Angriff: Fallschirm öffnen|Weiter Sprung: Waffe benutzen +04:14=Höhenangst? Greif besser zum Fallschirm.|Er wird sich von alleine entfalten, wenn du|zu lange oder zu tief fällst, und so deinem|Igel den Hals retten.|Angriff: Fallschirm öffnen|Weitsprung: Waffe benutzen 04:15=Rufe ein Flugzeug, um deine Feinde mit einem|Bombenteppich einzudecken.|Links/Rechts: Angriffsrichtung wählen|Cursor: Zielgebiet wählen und Angriff starten 04:16=Rufe ein Flugzeug, um mehrere Minen im|Zielgebiet abwerfen zu lassen.|Links/Rechts: Angriffsrichtung wählen|Cursor: Zielgebiet wählen und Angriff starten 04:17=Unterschlupf gefällig? Benutze den Schweißbrenner,|um einen Tunnel in festen Untergrund zu graben|oder einem Feind eine heiße Bekanntschaft machen|zu lassen.|Angriff: Brenner ein- oder ausschalten -04:18=Brauchst du Schutz oder eine Möglichkeit, einen|Abgrund zu überwinden? Platziere einige Bauträger,|um dir zu helfen.|Links/Rechts: Bauform und Orientierung wählen|Cursor: Bauträger platzieren +04:18=Brauchst du Schutz oder eine Möglichkeit, einen|Abgrund zu überwinden? Platziere einige Bauträger,|um dir zu helfen.|Links/Rechts: Bauform und Ausrichtung wählen|Cursor: Bauträger platzieren 04:19=Im richtigen Moment kann sich eine Teleportation|mächtiger als jede Waffe erweisen, da sich so ein|Igel gezielt einer gefährlichen Situation binnen|Sekunden entziehen kann.|Cursor: Zielposition wählen 04:20=Erlaubt es dir, den aktiven Igel zu wechseln|und mit einem anderen Igel fortzufahren.|Angriff: Wechsel aktivieren -04:21=Feuere ein granatenartiges Projektil in die|Richtung deines Gegners, das beim Aufschlag|mehrere kleine Bomben freisetzen wird.|Angriff: Mit voller Kraft feuern +04:21=Feuere ein granatenartiges Projektil in die|Richtung deines Gegners. Es wird beim Aufschlag|mehrere kleine Bomben freisetzen.|Angriff: Mit voller Kraft feuern 04:22=Nicht nur etwas für Indiana Jones! Die Peitsche|eignet sich besonders gut, um ungezogene Igel|eine Klippe hinunter zu treiben.|Angriff: Alles vor dem Igel schlagen 04:23=Wenn man nichts mehr zu verlieren hat …|Opfere deinen Igel, indem du ihn in eine|festgelegte Richtung losstürmen lässt.|Er wird alles auf dem Weg treffen und am|Ende selbst explodieren.|Angriff: Tödlichen Angriff starten -04:24=Alles Gute! Schick diesen Kuchen auf den Weg,|damit er deinen lieben Feinden eine explosive|Party beschert. Die Torte überwindet fast jedes|Terrain, verliert dabei aber an Laufzeit.|Angriff: Torte losschicken explodieren lassen +04:24=Alles Gute! Schick diesen Kuchen auf den Weg,|damit er deinen lieben Feinden eine explosive|Party beschert. Die Torte überwindet fast jedes|Terrain, verliert dabei aber an Laufzeit.|Angriff: Torte losschicken / explodieren lassen 04:25=Benutze diese Verkleidung, um einen Feind blind|vor Liebe in deine Richtung (und damit in einen|Abgrund oder ähnliches) springen zu lassen.|Angriff: Verkleiden und verführen 04:26=Wirf diese saftige Wassermelone auf deine Feinde.|Sobald die Zeit abgelaufen ist, wird sie in|einzelne und explosive Stücke zerspringen.|Angriff: Halten, um mit mehr Kraft zu werfen -04:27=Entfessle das Höllenfeuer und umgebe deine|Widersacher damit, indem du diesen teuflischen|Sprengsatz gegen sie einsetzt. Komm ihr aber|nicht zu nahe, denn die Flammen könnten|länger bestehen bleiben.|Angriff: Halten, um mit mehr Kraft zu werfen +04:27=Entfessle das Höllenfeuer und umgebe deine|Widersacher damit, indem du diesen teuflischen|Sprengsatz gegen sie einsetzt. Komm ihm aber|nicht zu nahe, denn die Flammen könnten|länger bestehen bleiben.|Angriff: Halten, um mit mehr Kraft zu werfen 04:28=Kurz nach dem Start wird diese Rakete beginnen,|sich durch soliden Grund zu graben. Sobald sie|wieder austritt oder der Zeitzünder abläuft,|wird sie explodieren.|Angriff: Halten, um mit mehr Kraft zu feuern 04:29=Das ist nichts für kleine Kinder! Die Ballpistole|feuert Tonnen kleiner farbiger Bälle, die mit|Sprengstoff gefüllt sind.|Angriff: Mit voller Kraft feuern|Hoch/Runter: Im Feuern zielen 04:30=Rufe ein Flugzeug, um ein Areal gezielt mit|tödlichem Napalm einzudecken. Gut gezielt|lassen sich so große Teile der Karte auslöschen.|Links/Rechts: Angriffsrichtung wählen|Cursor: Zielgebiet wählen und Angriff starten -04:31=Das Funkflugzeug kann Kisten einsammeln und weit|entfernte Igel angreifen. Steuere es direkt in|ein Opfer oder wirf erst einige Bomben ab.|Angriff: Flugzeug starten und Bomben abwerfen|Weiter Sprung: "Ritt der Walküren"|Hoch/Runter: Flugzeug lenken +04:31=Das Funkflugzeug kann Kisten einsammeln und weit|entfernte Igel angreifen. Steuere es direkt in|ein Opfer oder wirf erst einige Bomben ab.|Angriff: Flugzeug starten und Bomben abwerfen|Weitsprung: »Ritt der Walküren«|Hoch/Runter: Flugzeug lenken 04:32=Niedrige Schwerkraft ist effektiver als jede|Diät! Springe höher und weiter oder lass|einfach deine Gegner noch weiter fliegen.|Angriff: Aktivieren -04:33=Manchmal muss es eben doch ein bisschen|mehr sein …|Angreifen: Aktivieren -04:34=Can’t touch me!|Angreifen: Aktivieren +04:33=Manchmal muss es eben doch ein bisschen|mehr sein …|Angriff: Aktivieren +04:34=Can’t touch me!|Angriff: Aktivieren 04:35=Manchmal vergeht die Zeit einfach zu schnell.|Schnapp dir einige zusätzliche Sekunden, um|deinen Angriff abzuschließen.|Angriff: Aktivieren 04:36=Nun, manchmal trifft man einfach nicht. In solchen|Fällen kann die moderne Technik natürlich nachhelfen.|Angriff: Aktivieren -04:37=Fürchte nicht das Tageslicht! Die Wirkung hält|nur eine Runde an, aber sie erlaubt es deinem|Igel, den Schaden, den er direkt verursacht|als Leben zu absorbieren.|Angreifen: Aktivieren +04:37=Fürchte nicht das Tageslicht! Die Wirkung hält|nur eine Runde an, aber sie erlaubt es deinem|Igel, den Schaden, den er direkt verursacht|als Leben zu absorbieren.|Angriff: Aktivieren 04:38=Das Scharfschützengewehr kann die vernichtendste|Waffe im gesamten Arsenal sein, allerdings ist|es auf kurze Distanz sehr ineffektiv. Der|verursachte Schaden nimmt mit der Distanz zu.|Angriff: Feuern (mehrfach) -04:39=Fliege mit der fliegenden Untertasse in andere|Teile der Karte. Sie ist schwer zu beherrschen,|bringt dich aber an so gut wie jeden Ort.|Angriff: Aktivieren|Hoch/Links/Rechts: Beschleunigen|Weiter Sprung: Waffe benutzen +04:39=Fliege mit der fliegenden Untertasse in andere|Teile der Karte. Sie ist schwer zu beherrschen,|bringt dich aber an so gut wie jeden Ort.|Angriff: Aktivieren|Hoch/Links/Rechts: Beschleunigen|Weitsprung: Waffe benutzen 04:40=Entzünde einen Teil der Landschaft oder auch etwas|mehr mit dieser (schon bald) brennenden Flüssigkeit.|Angriff: Halten, um mit mehr Kraft zu werfen 04:41=Der Beweis, dass die Natur sogar die fliegende|Untertasse übertreffen könnte. Birdy kann|deinen Igel herumtragen und zudem Eier auf|deine Feinde fallen lassen.|Angriff: Aktivieren und Eier fallen lassen|Hoch/Links/Rechts: In eine Richtung flattern -04:42=Das tragbare Portal Device ermöglicht es dir,|dich, deine Feinde oder Waffen direkt zwischen|zwei Punkten auf der Karte zu|teleportieren.|Benutze es weise und deine Kampagne wird ein …|RIESENERFOLG!|Angriff: Öffnet ein Portal|Wechsel: Wechsle die Portalfarbe -04:43=Lass dein musikalisches Debüt einschlagen wie eine Bombe!|Lass ein Piano vom Himmel fallen, aber pass auf …|jemand muss es spielen und das könnte dich |dein Leben kosten!|Cursor: Zielgebiet wählen und Angriff starten|F1-F9: Spiel das Piano -04:44=Das ist nicht nur Käse, das ist biologische Kriegsführung!|Er wird nicht viel Schaden verursachen, sobald der Zünder|abgelaufen ist, aber er wird garantiert jeden in der Nähe|vergiften!|1-5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen +04:42=Das tragbare Portalgerät ermöglicht es dir,|dich, deine Feinde oder Waffen direkt zwischen|zwei Punkten auf der Karte zu|teleportieren.|Benutze es weise und deine Kampagne wird ein …|RIESENERFOLG!|Angriff: Öffnet ein Portal|Wechsel: Wechsle die Portalfarbe +04:43=Lass dein musikalisches Debüt einschlagen wie eine Bombe!|Lass ein Piano vom Himmel fallen, aber pass auf …|jemand muss es spielen und das könnte dich |dein Leben kosten!|Cursor: Zielgebiet wählen und Angriff starten|F1–F9: Das Piano spielen +04:44=Das ist nicht nur Käse, das ist biologische Kriegsführung!|Er wird nicht viel Schaden verursachen, sobald der Zünder|abgelaufen ist, aber er wird garantiert jeden in der Nähe|vergiften!|1–5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen 04:45=All die Physikstunden haben sich endlich|bezahlt gemacht: Entfessle eine zerstörerische Sinuswelle|gegen deine Feinde.|Pass auf, die Waffe erzeugt einen ordentlichen Rückstoß.|(Diese Waffe ist unvollständig)|Angriff: Sinuswellen erzeugen 04:46=Brutzle deine Feinde mit fließenden Flammen.|Herzerwärmend!|Angriff: Aktivieren|Hoch/Runter: Im Feuern zielen|Links/Rechts: Durchfluss ändern 04:47=Verdopple den Spaß mit zwei spitzigen, schicken, klebrigen Minen.|Löse eine Kettenreaktion aus oder beschütze dich (oder beides).|Angriff: Halten, um mit mehr Kraft zu feuern (zweimal) 04:48=Warum sind Maulwürfe verhasst? Einen|Igel in den Boden zu stampfen kann sehr lustig sein!|Ein guter Treffer des Hammers wird ein Drittel|der Lebenspunkte eines Igels abziehen und ihn|im Boden versenken.|Angriff: Aktivieren 04:49=Hol deine Freunde zurück!|Aber pass auf, dass du keine Feinde beschwörst.|Angriff: Gedrückt halten, um Igel langsam wiederauferstehen zu lassen.|Hoch: Beschleunige Totenbeschwörung -04:50=Verstecken sich Feinde im Untergrund?|Grabe sie aus mit dem Bohr-Luftangriff!|Der Zeitzünder bestimmt wie tief dieser graben wird. -04:51=Wirf mit Dreck um dich!|Schmerzt ein wenig und schubst Igel weg. +04:50=Verstecken sich Feinde im Untergrund?|Grabe sie aus mit dem Bohr-Luftangriff!|Der Zeitzünder bestimmt, wie tief dieser graben wird. +04:51=Wirf mit Dreck um dich!|Schubst Igel weg. 04:52=NICHT IN VERWENDUNG -04:53=Unternimm eine Reise durch Zeit und Raum,|während du deine Kameraden alleine am Schlachtfeld zurücklässt.|Sei darauf vorbereitet jederzeit wieder zurückzukommen,|oder auf Sudden Death wenn sie alle besiegt wurden.|Disclaimer: Nicht funktionstüchtig wenn in Sudden Death,|wenn du alleine bist - oder der König. -;04:54=IN ARBEIT +04:53=Unternimm eine Reise durch Zeit und Raum,|während du deine Kameraden alleine am Schlachtfeld zurücklässt.|Sei darauf vorbereitet jederzeit wieder zurückzukommen,|oder auf Sudden Death wenn sie alle besiegt wurden.|Haftungsausschluss: Nicht funktionstüchtig, wenn in Sudden Death,|wenn du alleine bist – oder der König. 04:54=Versprühe einen Strahl klebriger Flocken.|Baue Brücken, begrabe Gegner, versiegle Tunnel.|Pass auf, dass du selbst nichts abbekommst! +04:55=Hol die Eiszeit zurück! Friere Igel ein, mach den Boden rutschig oder|rette dich selbst vor dem Ertrinken,|indem du das Wasser einfrierst.|Angriff: Schießen +04:56=Du kannst zwei Hackebeile auf deinen Feind schleudern,|Passagen und Tunnel blockieren, und sie sogar zum Klettern benutzen!|Sei vorsichtig! Es ist gefährlich, mit Messern zu spielen.|Angriff: Gedrückt halten, um mit mehr Schwung zu werfen (zwei mal) +04:57=Bau einen SEHR elastischen Balken aus Gummi,|von dem Igel und andere Sachen abprallen,|ohne Fallschaden zu nehmen.|Links/Rechts: Ausrichtung des Gummis wählen|Cursor: Gummi platzieren ; Game goal strings 05:00=Spielmodifikationen @@ -582,12 +587,11 @@ 05:11=Gemeinsames Arsenal: Alle Teams gleicher Farbe teilen sich ihr Arsenal 05:12=Minenzünder: Minen explodieren nach %1 Sekunde(n) 05:13=Minenzünder: Minen explodieren sofort -05:14=Minenzünder: Minen explodieren nach 0-3 Sekunden +05:14=Minenzünder: Minen explodieren nach 0–3 Sekunden 05:15=Prozentualer Schaden: Alle Waffen verursachen %1 % Schaden -05:16=Lebenspunkter aller Igel wird am Ende jeder Runde zurückgesetzt +05:16=Lebenspunkte aller Igel werden am Ende jeder Runde zurückgesetzt 05:17=Computergesteuerte Igel erscheinen nach dem Tod wieder 05:18=Unbegrenzte Attacken 05:19=Waffen werden am Ende jedes Zuges zurückgesetzt 05:20=Igel teilen Waffen nicht untereinander -05:21=Tag Team: Teams gleicher Farbe kommen nacheinander dran und teilen sich ihre Zugzeit. - +05:21=Tag Team: Teams gleicher Farbe kommen nacheinander dran und teilen sich ihre Zugzeit. \ No newline at end of file diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/en.txt --- a/share/hedgewars/Data/Locale/en.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/en.txt Sat Jan 04 23:55:54 2014 +0400 @@ -58,6 +58,7 @@ 00:54=Land Spray 00:55=Freezer 00:56=Cleaver +00:57=Rubber 01:00=Let's fight! 01:01=Round draw @@ -81,6 +82,7 @@ 01:19=Extreme 01:20=%1 Bounce 01:21=Audio Muted +01:22=AFK mode ; Event messages ; Hog (%1) died @@ -453,6 +455,7 @@ 03:54=Utility 03:55=It doesn't get cooler than this! 03:56=Please use or misuse +03:57=Utility ; Weapon Descriptions (use | as line breaks) 04:00=Attack your enemies using a simple grenade.|It will explode once its timer reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power @@ -512,6 +515,7 @@ 04:54=Spray a stream of sticky flakes.|Build bridges, bury enemies, seal off tunnels.|Be careful you don't get any on you!|Attack: Activate|Up/Down: Continue aiming|Left/Right: Modify spitting power 04:55=Bring back the ice-age!|Freeze hedgehogs, make the floor slippery or|save yourself from drowning by freezing the water.|Attack: Shoot 04:56=You can throw two cleavers at your enemy,|block passages and tunnels and even use them for climbing!|Be careful! Playing with knifes is dangerous.|Attack: Hold to shoot with more power (twice) +04:57=Build an elastic bar made of rubber,|from which hedgehogs and other|things bounce off without taking fall damage.|Left/Right: Change rubber bar orientation|Cursor: Place rubber bar in a valid position ; Game goal strings 05:00=Game Modes diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_ar.ts --- a/share/hedgewars/Data/Locale/hedgewars_ar.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_ar.ts Sat Jan 04 23:55:54 2014 +0400 @@ -154,6 +154,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -370,6 +377,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -634,7 +654,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. + SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. @@ -647,19 +667,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -667,6 +674,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -794,6 +813,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -906,6 +937,13 @@ Save + + (%1 %2) + + + + + PageInGame @@ -1225,14 +1263,6 @@ Room Name: رقم الغرقة - - Rules: - - - - Weapons: - - %1 players online @@ -1257,10 +1287,6 @@ - Clear filters - - - Open server administration page @@ -1387,6 +1413,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1483,13 +1525,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1626,6 +1666,38 @@ 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 + + QComboBox @@ -1646,10 +1718,6 @@ - Any - - - Disabled @@ -1852,10 +1920,6 @@ متفجرات - Tip: - - - Quality @@ -1997,6 +2061,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2019,10 +2095,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2247,6 +2319,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2383,6 +2462,10 @@ Create room + + set password + + RoomsListModel @@ -2430,6 +2513,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2497,13 +2584,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3098,4 +3178,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_bg.ts --- a/share/hedgewars/Data/Locale/hedgewars_bg.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_bg.ts Sat Jan 04 23:55:54 2014 +0400 @@ -153,6 +153,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -369,6 +376,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -633,7 +653,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf се натъкна на грешка при показването на текста, най-вероятно свързана с програмна грешка в библиотеката freetype2. Препоръчително е да я обновите. + SDL_ttf се натъкна на грешка при показването на текста, най-вероятно свързана с програмна грешка в библиотеката freetype2. Препоръчително е да я обновите. @@ -646,19 +666,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -666,6 +673,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -793,6 +812,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -905,6 +936,13 @@ Save Запазване + + (%1 %2) + + + + + PageInGame @@ -1226,11 +1264,11 @@ Rules: - Правила: + Правила: Weapons: - Оръжия: + Оръжия: Search: @@ -1264,10 +1302,6 @@ - Clear filters - - - Open server administration page @@ -1394,6 +1428,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1490,13 +1540,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1633,6 +1681,38 @@ 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 + + QComboBox @@ -1654,7 +1734,7 @@ Any - Без значение + Без значение In lobby @@ -1868,7 +1948,7 @@ Tip: - Съвет: + Съвет: Quality @@ -2012,6 +2092,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2034,10 +2126,6 @@ Hedgewars %1 Таралежови войни %1 - - -r%1 (%2) - - QMessageBox @@ -2263,6 +2351,13 @@ + QObject + + No description available + + + + QPushButton Play demo @@ -2399,6 +2494,10 @@ Create room + + set password + + RoomsListModel @@ -2446,6 +2545,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2513,13 +2616,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3114,4 +3210,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_cs.ts --- a/share/hedgewars/Data/Locale/hedgewars_cs.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_cs.ts Sat Jan 04 23:55:54 2014 +0400 @@ -154,6 +154,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -375,6 +382,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -639,7 +659,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf vyhodil chybu v renderování textu, s největší pravděpodobností je to spojeno s chybou ve freetype2. Je doporučeno aktualizovat Vaši freetype knihovnu. + SDL_ttf vyhodil chybu v renderování textu, s největší pravděpodobností je to spojeno s chybou ve freetype2. Je doporučeno aktualizovat Vaši freetype knihovnu. @@ -652,19 +672,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -672,6 +679,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -799,6 +818,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -917,6 +948,14 @@ Save Uložit + + (%1 %2) + + + + + + PageInGame @@ -1238,11 +1277,11 @@ Rules: - Pravidla: + Pravidla: Weapons: - Zbraně: + Zbraně: Search: @@ -1277,10 +1316,6 @@ - Clear filters - - - Open server administration page @@ -1407,6 +1442,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1504,13 +1555,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1647,6 +1696,38 @@ 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 + + QComboBox @@ -1668,7 +1749,7 @@ Any - Jakékoliv + Jakékoliv In lobby @@ -1882,7 +1963,7 @@ Tip: - Tip: + Tip: Quality @@ -2026,6 +2107,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2048,10 +2141,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2278,6 +2367,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2414,6 +2510,10 @@ Create room + + set password + + RoomsListModel @@ -2461,6 +2561,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2528,13 +2632,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3129,4 +3226,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_da.ts --- a/share/hedgewars/Data/Locale/hedgewars_da.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_da.ts Sat Jan 04 23:55:54 2014 +0400 @@ -157,6 +157,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -373,6 +380,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -637,7 +657,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf returnerede en fejl under tekstrendering, højst sandsynligt er den relateret til en fejl i freetype2. Det anbefales at opdatere dit freetype bibliotek. + SDL_ttf returnerede en fejl under tekstrendering, højst sandsynligt er den relateret til en fejl i freetype2. Det anbefales at opdatere dit freetype bibliotek. @@ -650,19 +670,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -670,6 +677,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -797,6 +816,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -909,6 +940,13 @@ Save Gem + + (%1 %2) + + + + + PageInGame @@ -1230,11 +1268,11 @@ Rules: - Regler: + Regler: Weapons: - Våben: + Våben: Search: @@ -1268,10 +1306,6 @@ - Clear filters - - - Open server administration page @@ -1398,6 +1432,22 @@ Add an indestructible border along the bottom Tilføj en kant under banen som ikke kan destrueres + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1494,13 +1544,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1637,6 +1685,38 @@ 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 + + QComboBox @@ -1658,7 +1738,7 @@ Any - Ethvert + Ethvert In lobby @@ -1872,7 +1952,7 @@ Tip: - Tip: + Tip: Quality @@ -2020,6 +2100,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2042,10 +2134,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2271,6 +2359,13 @@ + QObject + + No description available + Ingen beskrivelse tilgængelig + + + QPushButton default @@ -2407,6 +2502,10 @@ Create room + + set password + + RoomsListModel @@ -2454,6 +2553,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2521,13 +2624,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3122,4 +3218,127 @@ 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_de.ts --- a/share/hedgewars/Data/Locale/hedgewars_de.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_de.ts Sat Jan 04 23:55:54 2014 +0400 @@ -5,7 +5,7 @@ About Unknown Compiler - + Unbekannter Compiler @@ -19,7 +19,7 @@ AmmoSchemeModel new - neu + Neu copy of @@ -30,89 +30,101 @@ BanDialog IP - IP + IP-Adresse Nick - + Spitzname IP/Nick - + IP-Adresse/Spitzname Reason - + Grund Duration - + Dauer Ok - + OK Cancel - Abbrechen + Abbrechen you know why - + du weißt schon, warum Warning - + Warnung Please, specify %1 - + Bitte leg %1 fest nickname - + Spitzname permanent - + Spitzname DataManager Use Default - + Verwende Standard FeedbackDialog View - + Ansehen Cancel - Abbrechen + Abbrechen Send Feedback - + Feedback senden + + + Please give us feedback! + Bitte gib uns Feedback! We are always happy about suggestions, ideas, or bug reports. - + Wir freuen uns immer über Vorschläge, Ideen oder Fehlerberichte. + + + If you found a bug, you can see if it's already known here (english): + Falls du einen Fehler gefunden hast, kannst du hier sehen, ob er bereits bekannt is (auf Englisch): + + + Your email address is optional, but we may want to contact you. + Deine E-Mail-Adresse ist optional, aber wir könnten sie brauchen, um dich zu kontaktieren. Send us feedback! - + Schicke uns dein Feedback! If you found a bug, you can see if it's already been reported here: - + Falls du einen Fehler gefunden hast, kannst du hier sehen, ob er bereits bekannt is (auf Englisch): Your email address is optional, but necessary if you want us to get back at you. - + Deine E-Mail-Adresse ist optional, es sei denn du möchtest, dass wir dir antworten. @@ -133,11 +145,11 @@ GameCFGWidget Edit weapons - Waffenzusammenstellung bearbeiten + Arsenal bearbeiten Edit schemes - Spielprofile bearbeiten + Spielprofil bearbeiten Game Options @@ -145,68 +157,75 @@ Game scheme will auto-select a weapon - + Das Auswählen eines Spielprofils wird automatisch ein Arsenal auswählen Map - Karte + Karte Game options - + Spieloptionen + + + + GameUIConfig + + Guest + Gast HWApplication %1 minutes - - - + + %1 Minute + %1 Minuten %1 hour - - - + + %1 Stunde + %1 Stunden %1 hours - - - + + %1 Stunde + %1 Stunden %1 day - - - + + %1 Tag + %1 Tage %1 days - - - + + %1 Tag + %1 Tage Scheme '%1' not supported - + Das Spielprofil »%1« wird nicht unterstützt Cannot create directory %1 - Verzeichnis %1 konnte nicht angelegt werden + Das Verzeichnis %1 konnte nicht angelegt werden Failed to open data directory: %1 Please check your installation! - Konnte Daten-Verzeichnis nicht öffnen: + Ich konnte dieses Daten-Verzeichnis nicht öffnen: %1 Bitte überprüfe deine Installation! @@ -239,11 +258,11 @@ Stylesheet imported from %1 - Style-Sheet aus %1 importiert + Stylesheet aus %1 importiert Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset! - Gib %1 ein wenn du das jetzige Style-Sheet in Zukunft weiterverwenden willst, gib %2 ein um es zurückzusetzen! + Gib %1 ein, wenn du das jetzige Stylesheet in Zukunft weiterverwenden willst; gib %2 ein, um es zurückzusetzen! Couldn't read %1 @@ -251,27 +270,27 @@ StyleSheet discarded - Style-Sheet verworfen + Stylesheet verworfen StyleSheet saved to %1 - Style-Sheet wurde nach %1 gesichert + Stylesheet wurde nach %1 gesichert Failed to save StyleSheet to %1 - Style-Sheet konnte nich nach %1 gesichert werden + Stylesheet konnte nicht nach %1 gesichert werden %1 has joined - + %1 ist beigetreten %1 has left - + %1 ist gegangen %1 has left (%2) - + %1 ist gegangen (%2) @@ -282,25 +301,25 @@ DefaultTeam - + Standard-Team Hedgewars Demo File File Types - Hedgewars Demo Datei + Hedgewars-Wiederholungsdatei Hedgewars Save File File Types - Hedgewars gespeichertes Spiel + Hedgewars-Spielstandsdatei Demo name - Demo-Name + Wiederholungsname Demo name: - Demo-Name: + Wiederholungsname: Game aborted @@ -317,15 +336,15 @@ Someone already uses your nickname %1 on the server. Please pick another nickname: - Dein Spitzname '%1' ist bereits in Verwendung. Bitte wähle einen anderen Spitznamen: + Dein Spitzname »%1« ist bereits in Verwendung. Bitte wähle einen anderen Spitznamen: %1's Team - + Team von %1 Hedgewars - Nick registered - + Hedgewars – Spitzname registriert This nick is registered, and you haven't specified a password. @@ -333,48 +352,71 @@ If this nick isn't yours, please register your own nick at www.hedgewars.org Password: - + Dieser Spitzname ist registriert und du hast kein Passwort angegeben. + +Falls dieser Spitzname nicht deiner ist, dann registirier bitte deinen eigenen Spitznamen an www.hedgewars.org. + +Passwort: Your nickname is not registered. To prevent someone else from using it, please register it at www.hedgewars.org - + Dein Spitzname ist nicht registriert. +Um Andere von der Benutzung abzuhalten, registrier +ihn bitte auf www.hedgewars.org Your password wasn't saved either. - + + +Außerdem wurde auch dein Passwort nicht gespeichert. Hedgewars - Empty nickname - + Hedgewars – leerer Spitzname Hedgewars - Wrong password - + Hedgewars – falsches Passwort You entered a wrong password. - + Du hast ein falsches Passwort eingegeben. Try Again - + noch einmal versuchen Hedgewars - Connection error - + Hedgewars – Verbindungsfehler You reconnected too fast. Please wait a few seconds and try again. - + Du hast dich zu früh erneut verbunden. +Bitte warte ein paar Sekunden und versuch es noch einmal. + + + Guest + Gast + + + Room password + Raumkennwort + + + The room is protected with password. +Please, enter the password: + Der Raum wird durch ein Kennwort geschützt. +Bitte Kennwort eingeben: This page requires an internet connection. - + Diese Seite benötigt eine Internetverbindung. @@ -385,7 +427,7 @@ Cannot open demofile %1 - Demodatei %1 konnte nicht geöffnet werden + Wiederholungsdatei »%1« konnte nicht geöffnet werden @@ -420,7 +462,7 @@ Medium tunnels - Mittlere Tunnel + Mittelgroße Tunnel Seed @@ -428,91 +470,97 @@ Map type: - + Kartentyp: Image map - + Bild Mission map - + Missionskarte Hand-drawn - Handgemalt + Handgemalt Randomly generated - + Zufallsgeneriert Random maze - + Zufallslabyrinth Random - Zufall + Zufall Map preview: - + Kartenvorschau: Load map drawing - + Gezeichnete +Karte laden Edit map drawing - + Gezeichnete +Karte bearbeiten Small islands - + Kleine Inseln Medium islands - + Mittelgroße Inseln Large islands - + Große Inseln Map size: - + Kartengröße: Maze style: - + Labyrinth-Art: Mission: - + Mission: Map: - + Karte: + + + Theme: + Thema: Load drawn map - Gezeichnete Karte laden + Gezeichnete Karte laden Drawn Maps - Gezeichnete Karten + Gezeichnete Karten All files - Alle Dateien + Alle Dateien Large tunnels - + Große Tunnel Theme: %1 - + Szenerie: %1 @@ -585,22 +633,25 @@ HWPasswordDialog Login - + Einloggen To connect to the server, please log in. If you don't have an account on www.hedgewars.org, just enter your nickname. - + Um dich zu dem Server zu verbinden, log dich bitte ein. + +Wenn du kein Benutzerkonto von www.hedgewars.org hast, +dann trag einfach nur deinen Spitznamen ein. Nickname: - + Spitzname: Password: - + Passwort: @@ -618,36 +669,36 @@ HatButton Change hat (%1) - + Hut wechseln (%1) HatPrompt Cancel - Abbrechen + Abbrechen Use selected hat - + Gewählten Hut auswählen Search for a hat: - + Nach einem Hut suchen: KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf meldete einen Fehler beim Rendern des Textes, dies liegt vermutlich an einem Fehler in freetype2. Es wird empfohlen die freetype Bibliothek auf den neuesten Stand zu bringen. + SDL_ttf meldete einen Fehler beim Rendern des Textes, dies liegt vermutlich an einem Fehler in freetype2. Es wird empfohlen, die freetype-Bibliothek auf dem neuesten Stand zu bringen. KeyBinder Category - + Kategorie @@ -655,30 +706,42 @@ Duration: %1m %2s - Dauer: %1m %2s + Dauer: %1m %2s Video: %1x%2, - Video: %1x%2, + Video: %1x%2, %1 fps, - %1 fps, + %1 Bilder pro Sekunde, Audio: - Audio: + Audio: unknown - + unbekannt + + + Duration: %1m %2s + Dauer: %1m %2s + + + Video: %1x%2 + Video: %1x%2 + + + %1 fps + %1 Hz MapModel No description available. - + Keine Beschreibung verfügbar. @@ -701,7 +764,7 @@ Latest version protocol number: - Letzte Protokoll-Version + Protokollnummer der neuesten Version: MOTD preview: @@ -713,53 +776,53 @@ General - Allgemein + Allgemein Bans - + Verbannungen IP/Nick - + IP-Adr./Spitzname Expiration - + Ablaufzeitpunkt Reason - + Grund Refresh - + Aktualisieren Add - + Hinzufügen Remove - + Entfernen PageConnecting Connecting... - Verbinde ... + Verbinden … PageDataDownload Loading, please wait. - + Ladevorgang. Bitte warten. This page requires an internet connection. - + Diese Seite benötigt eine Internetverbindung. @@ -770,7 +833,7 @@ Clear - Löschen + Leeren Load @@ -778,7 +841,7 @@ Save - Sichern + Wiederholung speichern Load drawn map @@ -800,6 +863,18 @@ Eraser Radierer + + Polyline + Linienzug + + + Rectangle + Rechteck + + + Ellipse + Ellipse + PageEditTeam @@ -809,39 +884,39 @@ Select an action to choose a custom key bind for this team - + Wählt eine Aktion, um eine benutzerdefinierte Taste für dieses Team auszuwählen Use my default - + Verwende meine Vorgabe Reset all binds - + Alle Tastenbelegungen zurücksetzen Custom Controls - + Benutzerdefinierte Steuerung Hat - Cooliehat + Hut Name - Name + Name This hedgehog's name - + Name dieses Igels Randomize this hedgehog's name - + Zufälligen Igelnamen generieren Random Team - Zufallsteam + Zufallsteam @@ -856,7 +931,7 @@ Ranking - Ranking + Platzierung The best shot award was won by <b>%1</b> with <b>%2</b> pts. @@ -886,15 +961,15 @@ <b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts. - <b>%1</b> dachte es ist gut seinen eigenen Igel mit <b>%2</b> Punkten zu verletzen. - <b>%1</b> dachte es ist gut seine eigenen Igel mit <b>%2</b> Punkten zu verletzen. + <b>%1</b> dachte, es sei gut, die eigenen Igel mit <b>%2</b> Punkt zu verletzen. + <b>%1</b> dachte, es sei gut, die eigenen Igel mit <b>%2</b> Punkten zu verletzen. <b>%1</b> killed <b>%2</b> of his own hedgehogs. <b>%1</b> erledigte <b>%2</b> seiner eigenen Igel. - + <b>%1</b> erledigte <b>%2</b> seiner eigenen Igel. @@ -906,25 +981,32 @@ Play again - + Nochmal spielen Save - Sichern + Speichern + + + (%1 %2) + + (%1 %2) + (%1 %2) + PageInGame In game... - Im Spiel... + Im Spiel … PageInfo Open the snapshot folder - Schnappschuss-Ordner öffnen + Screenshot-Verzeichnis öffnen @@ -935,11 +1017,11 @@ Play a game on a single computer - Spiele auf einem einzelnen PC + Auf einen einzelnen Computer spielen Play a game across a network - Spiele über ein Netzwerk + Über ein Netzwerk spielen Read about who is behind the Hedgewars Project @@ -947,11 +1029,11 @@ Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars - + Hier kannst du uns Feedback geben, indem du uns Probleme meldest, neue Funktionen vorschlägst oder einfach nur sagst, wie dir Hedgewars gefällt Access the user created content downloadable from our website - Greife auf von Benutzern ergestellte Inhalte zu, herunterladbar von unserer Webseite + Auf von Benutzern erstellte Inhalte, die man von unserer Webseite herunterladen kann, zugreifen Exit game @@ -959,42 +1041,42 @@ Manage videos recorded from game - Verwalte vom Spiel aufgenommene Videos + Vom Spiel aufgezeichnete Videos verwalten Edit game preferences - Bearbeite Spieleinstellungen + Spieleinstellungen bearbeiten Play a game across a local area network - + ein Spiel über ein lokales Netzwerk (LAN) spielen Play a game on an official server - + ein Spiel auf einem offiziellen Server spielen Feedback - + Feedback Play local network game - + Im lokalen Netzwerk spielen Play official network game - + Im offiziellem Netzwerk spielen PageMultiplayer Start - Start + Starten Edit game preferences - Bearbeite Spieleinstellungen + Spieleinstellungen bearbeiten @@ -1005,30 +1087,30 @@ Edit game preferences - Bearbeite Spieleinstellungen + Spieleinstellungen bearbeiten Start - Start + Starten Update - Aktualisieren + Aktualisieren Room controls - + Raumeinstellungen PageNetServer Click here for details - + Klick hier, um mehr zu erfahren Insert your address here - + Gib deine Adress hier ein @@ -1047,7 +1129,7 @@ You can't edit teams from team selection. Go back to main menu to add, edit or delete teams. - Du kannst keine Teams bei der Team-Auswahl ändern. Gehe zum Hauptmenü zurück um Teams hinzuzufügen, zu editieren oder zu löschen. + Du kannst keine Teams bei der Team-Auswahl ändern. Gehe zum Hauptmenü zurück, um Teams hinzuzufügen, zu editieren oder zu löschen. New scheme @@ -1063,15 +1145,15 @@ New weapon set - Neues Waffenprofil + Neues Arsenal Edit weapon set - Waffenprofil bearbeiten + Arsenal bearbeiten Delete weapon set - Waffenprofil löschen + Arsenal löschen Advanced @@ -1091,7 +1173,7 @@ Proxy login - Login + Benutzername Proxy password @@ -1111,95 +1193,95 @@ System proxy settings - Betriebsystem Proxy-Einstellungen + System-Proxy-Einstellungen Select an action to change what key controls it - + Wähle eine Aktion, um ihre Tastenbelegung zu ändern Reset to default - + Auf Standard zurücksetzen Reset all binds - + Alle Tastenbelegungen zurücksetzen Game - + Spiel Graphics - + Grafik Audio - + Ton Controls - + Steuerung Video Recording - + Videoaufzeichnung Network - + Netzwerk Teams - Teams + Teams Schemes - + Spielprofile Weapons - Waffen + Arsenale Frontend - + Benutzeroberfläche Custom colors - Benutzerdefinierte Farben + Benutzerdefinierte Farben Game audio - + Ton im Spiel Frontend audio - + Ton in der Benutzeroberfläche Account - + Benutzerkonto Proxy settings - Proxy-Einstellungen + Proxy-Einstellungen Miscellaneous - Verschiedenes + Verschiedenes Updates - + Updates Check for updates - + nach Updates suchen Video recording options - Videoaufnahmeoptionen + Videoaufzeichnungseinstellungen @@ -1233,11 +1315,11 @@ Rules: - Regeln: + Regeln: Weapons: - Waffen: + Waffen: Search: @@ -1256,27 +1338,27 @@ Search for a room: - + Nach einem Raum suchen: Create room - + Raum erstellen Join room - + Raum beitreten Room state - + Raumfilter Clear filters - + Filter leeren Open server administration page - + Server-Administrationsseite öffnen @@ -1291,11 +1373,11 @@ Gain 80% of the damage you do back in health - 80% des ausgeteilten Schadens werden in Lebenspunkte gewandelt + 80% des ausgeteilten Schadens werden dir als Gesundheitspunkte gutgeschrieben Share your opponents pain, share their damage - Teile den Schmerz Deines Gegners, teile dessen verursachten Schaden + Teile den Schmerz deines Gegners, teile seinen verursachten Schaden Your hogs are unable to move, put your artillery skills to the test @@ -1311,7 +1393,7 @@ Defend your fort and destroy the opponents, two team colours max! - Verteidige Dein Fort und zerstöre das des Gegners, maximal zwei Teamfarben! + Verteidige deine Festung und zerstöre die des Gegners, maximal zwei Teamfarben! Teams will start on opposite sides of the terrain, two team colours max! @@ -1351,11 +1433,11 @@ Disable girders when generating random maps. - Platziere keine Bauträger auf Zufallskarten. + Keine Bauträger auf Zufallskarten platzieren. Disable land objects when generating random maps. - Deaktiviere Landschaftsobjekte beim Generieren von Zufallskarten. + Keine Landschaftsobjekte beim Generieren von Zufallskarten platzieren. AI respawns on death. @@ -1371,11 +1453,11 @@ Weapons are reset to starting values each turn. - Waffenarsenal wird jede Runde zurückgesetzt. + Arsenal wird jede Runde zurückgesetzt. Each hedgehog has its own ammo. It does not share with the team. - Jeder igel hat sein eigenes Waffenarsenal. Es wird nicht mit dem Team geteilt. + Jeder Igel hat sein eigenes Arsenal. Es wird nicht mit dem Team geteilt. You will not have to worry about wind anymore. @@ -1395,11 +1477,27 @@ Add an indestructible border around the terrain - Fügt eine unzerstörbare Randbegrenzung um das Spielfeld herum hinzu. + Dem Spielfeld eine unzerstörbare Randbegrenzung hinzufügen Add an indestructible border along the bottom - Fügt eine unzerstörbare Randbegrenzung am unteren Kartenrand hinzu. + Dem unteren Kartenrand eine unzerstörbare Randbegrenzung anfügen + + + None (Default) + Keine (Standard) + + + Wrap (World wraps) + Umbrechen (Welt wiederholt sich) + + + Bounce (Edges reflect) + Abprallen (Grenzen reflektieren) + + + Sea (Edges connect to sea) + Ozean (Grenzen sind mit dem Wasser verbunden) @@ -1425,11 +1523,11 @@ PageSinglePlayer Play a quick game against the computer with random settings - Spiele ein schnelles Spiel gegen den Computer - mit Zufallseinstellungen + Ein Schnellspiel gegen den Computer mit Zufallseinstellungen spielen Play a hotseat game against your friends, or AI teams - Spiele gegen deine Freunde oder Computer-Teams. + Gegen deine Freunde oder KI-Teams spielen Campaign Mode @@ -1437,15 +1535,15 @@ Practice your skills in a range of training missions - Verbessere deine Fähigkeiten in verschiedenen Trainingsmissionen + Deine Fähigkeiten in verschiedenen Trainingsmissionen verbessern Watch recorded demos - Sehe aufgenommene Demos an + Aufgezeichnete Widerholungen ansehen Load a previously saved game - Lade ein vormals gespeichtes Spiel + Ein vormals gespeichertes Spiel ansehen @@ -1486,7 +1584,7 @@ (in progress...) - (in Bearbeitung...) + (in Bearbeitung …) encoding @@ -1499,27 +1597,35 @@ Date: %1 - + Datum: %1 Size: %1 - + Größe: %1 + + + Date: %1 + Datum: %1 + + + Size: %1 + Größe: %1 QAction Kick - Rauswerfen + Hinauswerfen Restrict Joins - Zugang beschränken + Beitreten unterbinden Restrict Team Additions - Teamzugang beschränken + Hinzufügen weiterer Teams unterbinden Info @@ -1555,15 +1661,15 @@ Restrict Unregistered Players Join - + Beitreten unregistrierter Spieler unterbinden Show games in lobby - + Spiele in Vorbereitung zeigen Show games in-progress - + Zur Zeit laufende Spiele zeigen @@ -1574,7 +1680,7 @@ Show FPS - FPS anzeigen + Bildwiederholrate anzeigen Alternative damage show @@ -1582,11 +1688,11 @@ Append date and time to record file name - Datum und Uhrzeit an Aufnahmedatei anhängen + Datum und Uhrzeit an Wiederholungsdateinamen anhängen Check for updates at startup - Beim Start nach neuen Versionen suchen + Beim Spielstart nach neuen Versionen suchen Show ammo menu tooltips @@ -1606,7 +1712,7 @@ Record audio - Audio aufnehmen + Audio aufzeichnen Use game resolution @@ -1614,31 +1720,63 @@ Visual effects - + Visuelle Effekte Sound - + Ton In-game sound effects - + Toneffekte im Spiel Music - + Musik In-game music - + Musik im Spiel Frontend sound effects - + Toneffekte in der Benutzeroberfläche Frontend music - + Musik in der Benutzeroberfläche + + + Team + Team + + + Enable team tags by default + Teambeschriftungsschilder standardmäßig aktivieren + + + Hog + Igel + + + Enable hedgehog tags by default + Namensschilder standardmäßig aktivieren + + + Health + Lebenspunkte + + + Enable health tags by default + Lebenspunktebeschriftungsschilder standardmäßig aktivieren + + + Translucent + Transluzent + + + Enable translucent tags by default + Transluzente Beschriftungsschilder standardmäßig aktivieren @@ -1661,7 +1799,7 @@ Any - Alle + Alle In lobby @@ -1775,7 +1913,7 @@ QLabel Weapons - Waffen + Arsenal Host: @@ -1791,7 +1929,7 @@ FPS limit - FPS-Limit + Bildwiederholratenbegrenzung (Hz) Server name: @@ -1875,7 +2013,7 @@ Tip: - Tipp: + Tipp: Quality @@ -1883,11 +2021,11 @@ % Health Crates - % Medipacks + % Erste-Hilfe-Koffer Health in Crates - Lebenspunkte pro Medipack + Lebenspunkte in Erste-Hilfe-Koffern Sudden Death Water Rise @@ -1979,51 +2117,63 @@ Bitrate (Kbps) - Bitrate (Kbps) + Bitrate (kB/s) 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! - + Diese Entwicklungsversion ist unfertig und könnte nicht kompatibel mit anderen Versionen des Spiels sein, wobei sogar einige Funktionen sogar kaputt oder unfertig sein könnten. Fullscreen - Vollbild + Vollbild Fullscreen Resolution - + Vollbild-Auflösung Windowed Resolution - + Fenster-Auflösung Your Email - + Deine E-Mail-Adresse Summary - + Zusammenfassung Send system information - + Systeminformation senden Type the security code: - + Gib den Sicherheitscode ein: Revision - + Revision This program is distributed under the %1 - + Dieses Programm wird unter der %1 veröffentlicht + + + Tip: %1 + Tipp: %1 + + + Displayed tags above hogs and translucent tags + Angezeigte/transluzente Beschriftungsschilder über Igel This setting will be effective at next restart. - + Diese Einstellung tritt ab nächstem Neustart in Kraft. + + + World Edge + Spielfeldgrenze @@ -2047,10 +2197,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2088,11 +2234,11 @@ Do you really want to delete the team '%1'? - Willst du das Team '%1' wirklich löschen? + Willst du das Team »%1« wirklich löschen? Cannot delete default scheme '%1'! - Standard-Profil '%1' kann nicht gelöscht werden! + Standard-Profil »%1« kann nicht gelöscht werden! Please select a record from the list @@ -2100,15 +2246,15 @@ Unable to start server - Konnte Server nicht starten + Server konnte nicht gestartet werden Hedgewars - Error - Hedgewars - Fehler + Hedgewars – Fehler Hedgewars - Success - Hedgewars - Erfolg + Hedgewars – Erfolg All file associations have been set @@ -2200,23 +2346,23 @@ Schemes - Warning - Spielprofil - Warnung + Spielprofile – Warnung Schemes - Are you sure? - Spielprofil - Bist du dir sicher? + Spielprofile – Bist du dir sicher? Do you really want to delete the game scheme '%1'? - Willst du das Profil '%1' wirklich löschen? + Willst du das Spielprofil »%1« wirklich löschen? Videos - Are you sure? - Videos - Bist du dir sicher? + Videos – Bist du dir sicher? Do you really want to delete the video '%1'? - Willst du das Video '%1' wirklich löschen? + Willst du das Video »%1« wirklich löschen? Do you really want to remove %1 file(s)? @@ -2227,7 +2373,7 @@ Do you really want to cancel uploading %1? - Willst du das Hochladen von %1 wirklich abbrechen_ + Willst du das Hochladen von %1 wirklich abbrechen? File error @@ -2235,72 +2381,80 @@ Cannot open '%1' for writing - '%1' konnte nicht geschrieben werden + »%1« konnte zum Schreiben nicht geöffnet werden Cannot open '%1' for reading - '%1' konnte nicht gelesen werden + »%1« konnte zum Lesen nicht geöffnet werden Cannot use the ammo '%1'! - Munition '%1' kann nicht benutzt werden! + Munition »%1« kann nicht benutzt werden! Weapons - Warning - Waffenprofil - Warnung + Arsenal – Warnung Cannot overwrite default weapon set '%1'! - Standard-Waffenprofil '%1' kann nicht überschrieben werden! + Standard-Arsenal »%1« kann nicht überschrieben werden! Cannot delete default weapon set '%1'! - Standard-Waffenprofil '%1' kann nicht gelöscht werden! + Standard-Arsenal »%1« kann nicht gelöscht werden! Weapons - Are you sure? - Waffenprofil - Bist du dir sicher? + Arsenal – Bist du dir sicher? Do you really want to delete the weapon set '%1'? - Willst du das Waffenprofil '%1' wirklich löschen? + Willst du das Arsenal »%1« wirklich löschen? Hedgewars - Nick not registered - + Hedgewars – Spitzname nicht registriert System Information Preview - + Systeminformations-Vorschau Failed to generate captcha - + Captcha-Generierung fehlgeschlagen Failed to download captcha - + Captcha-Download fehlgeschlagen Please fill out all fields. Email is optional. - + Bitte füll alle Felder aus. Das Feld »E-Mail« ist optional. Hedgewars - Warning - + Hedgewars – Warnung Hedgewars - Information - + Hedgewars – Information Not all players are ready - + Es sind nicht alle Spieler bereit Are you sure you want to start this game? Not all players are ready. - + Bist du sicher, dass du diesees Spiel starten willst? +Es sind nicht alle Spieler bereit. + + + + QObject + + No description available + Keine Beschreibung verfügbar @@ -2335,15 +2489,15 @@ Specify - Verbinden zu ... + Verbinden zu … Start - Start + Starten Play demo - Demo abspielen + Wiederholung abspielen Rename @@ -2359,7 +2513,7 @@ Associate file extensions - Ordne Dateitypen zu + Dateitypen zuordnen More info @@ -2367,7 +2521,7 @@ Set default options - Setzen + Auf Standardeinstellungen zurücksetzen Open videos directory @@ -2375,7 +2529,7 @@ Play - Spielen + Abspielen Upload to YouTube @@ -2387,58 +2541,66 @@ Restore default coding parameters - + Standard-Kodierungs-Einstellungen wiederherstellen Open the video directory in your system - + Das Videoverzeichnis deines Systems öffnen Play this video - + Dieses Video abspielen Delete this video - + Dieses Video löschen Upload this video to your Youtube account - + Dieses Video zu deinem YouTube-Benutzerkonto hochladen Reset - + Zurücksetzen Set the default server port for Hedgewars - + Den Standard-Server-Port für Hedgewars setzen Invite your friends to your server in just 1 click! - + Lad deine Freunde zu deinem Server mit nur einem Klick ein! + + + Click to copy your unique server URL in your clipboard. Send this link to your friends and they will be able to join you. + Klick, um deine einzigartige URL in die Zwischenablage zu kopieren. Versende diesen Link an deine Freunde, damit sie dich auf deinem Server besuchen können. + + + Start private server + Privaten Server starten Click to copy your unique server URL to your clipboard. Send this link to your friends and they will be able to join you. - - - - Start private server - + Klicke um deine Server-Adresse in die Zwischenablage zu kopieren. Sende diese als Link zu deinen Freunden, damit sie dir beitreten können. RoomNamePrompt Enter a name for your room. - + Gib einen Namen für deinen Raum ein. Cancel - Abbrechen + Abbrechen Create room - + Raum erstellen + + + set password + Kennwort setzen @@ -2469,11 +2631,11 @@ Rules - Regeln + Spielprofil Weapons - Waffen + Arsenal Random Map @@ -2487,39 +2649,43 @@ Hand-drawn Handgemalt + + Script + Stil + SeedPrompt The map seed is the basis for all random values generated by the game. - + Der sog. Seed (wörtlich übersetzt: engl. für »Saat«) ist die Basis für alle Zufallswerte, die vom Spiel generiert werden. Cancel - Abbrechen + Abbrechen Set seed - + Seed setzen Close - + Schließen SelWeaponWidget Weapon set - Bewaffnung + Anfangsbewaffnung Probabilities - Nachschub + Wahrscheinlichkeiten Ammo in boxes - Kisteninhalt + Kisteninhalte Delays @@ -2527,7 +2693,7 @@ new - neu + Neu copy of @@ -2538,41 +2704,42 @@ TCPBase Unable to start server at %1. - + Ich bin unfähig, den Server auf %1 zu starten. Unable to run engine at %1 Error code: %2 - + Ich bin unfähig, die Engine auf %1 laufen zu lassen. +Fehlercode: %2 TeamSelWidget At least two teams are required to play! - + Es sind mindestens zwei Teams für ein Spiel nötig! TeamShowWidget %1's team - + Team von %1 ThemePrompt Cancel - Abbrechen + Abbrechen Search for a theme: - + Nach einer Szenerie suchen: Use selected theme - + Ausgewählte Szenerie benutzen @@ -2723,11 +2890,11 @@ long jump - Weiter Sprung + Weitsprung high jump - Hoher Sprung + Hochsprung slot 10 @@ -2739,101 +2906,101 @@ record - aufnehmen + aufzeichnen hedgehog info - + Igel-Info binds (categories) Movement - + Bewegung Weapons - Waffen + Waffen Camera - + Kamera Miscellaneous - Verschiedenes + Verschiedenes binds (descriptions) Traverse gaps and obstacles by jumping: - Überwinde Abgründe und Hindernisse mit Sprüngen: + Abgründe und Hindernisse mit Sprüngen überwinden: Fire your selected weapon or trigger an utility item: - Benutze deine gewählte Waffe oder Werkzeug: + Deine gewählte Waffe feuern oder dein Werkzeug benutzen: Pick a weapon or a target location under the cursor: - Wähle eine Waffe oder einen Zielpunkt mit dem Cursor: + Eine Waffe oder einen Zielpunkt mit dem Cursor wählen: Switch your currently active hog (if possible): - Wähle den zu steuernden Igel (falls möglich): + Den zu steuernden Igel wählen (falls möglich): Pick a weapon or utility item: - Wähle eine Waffe oder Werkzeug aus: + Eine Waffe oder Werkzeug auswählen: Set the timer on bombs and timed weapons: - Setze den Zeitzünder von verschiedenen Waffen: + Den Zeitzünder von verschiedenen Waffen setzen: Move the camera to the active hog: - Bewege die Kamera zum aktiven Igel: + Die Kamera zum aktiven Igel bewegen: Move the cursor or camera without using the mouse: - Bewege den Zeiger oder die Kamera ohne die Maus: + Den Zeiger oder die Kamera ohne die Maus bewegen: Modify the camera's zoom level: - Verändere den Bildausschnitt: + Den Zoom verändern: Talk to your team or all participants: - Spreche mit anderen Spielern: + Mit anderen Spielern sprechen: Pause, continue or leave your game: - Pausiere oder verlasse das Spiel: + Spiel pausieren, fortsetzen oder verlassen: Modify the game's volume while playing: - Ändere die Lautstärke im Spiel: + Lautstärke im Spiel ändern: Toggle fullscreen mode: - Schalte den Vollbildmodus um: + Vollbildmodus umschalten: Take a screenshot: - Erstelle ein Bildschirmfoto: + Screenshot machen: Toggle labels above hedgehogs: - Einblendungen über Igeln ein/ausschalten: + Beschriftungsschilder über Igel durchschalten: Record video: - Video aufnehmen: + Video aufzeichnen: Hedgehog movement - + Igel-Bewegung @@ -3020,11 +3187,11 @@ Page up - Bild hoch + Bild auf Page down - Bild runter + Bild ab Num lock @@ -3155,4 +3322,127 @@ Steuerkreuz + + server + + Authentication failed + Authentifizierung fehlgeschlagen + + + 60 seconds cooldown after kick + 60 Sekunden Abkühlzeit nach Hinauswurf + + + kicked + hinausgeworfen + + + Ping timeout + Ping-Timeout + + + bye + tschüss + + + Empty config entry + Leerer Konfigurations-Eintrag + + + Corrupted hedgehogs info + Kaputte Igel-Info + + + too many teams + zu viele Teams + + + too many hedgehogs + zu viele Igel + + + There's already a team with same name in the list + Es gibt bereits ein Team mit dem selben Namen in der Liste + + + round in progress + laufende Runde + + + restricted + eingeschränkt + + + REMOVE_TEAM: no such team + REMOVE_TEAM: kein solches Team + + + Not team owner! + Nicht Team-Besitzer*In! + + + Less than two clans! + Weniger als zwei Klans! + + + Room with such name already exists + ein Raum mit einem solchen Namen existiert bereits + + + Illegal room name + Verbotener Raumname + + + No such room + Ein solcher Raum existiert nicht + + + Joining restricted + Zutritt verboten + + + Registered users only + Nur für registrierte Benutzer + + + You are banned in this room + Du wurdest aus diesem Raum verbannt + + + Nickname already chosen + Spitzname bereits gewählt + + + Illegal nickname + Verbotener Spitzname + + + Protocol already known + Protokoll bereits bekannt + + + Bad number + Schlechte Zahl + + + Nickname is already in use + Spitzname bereits in Benutzung + + + Restricted + Eingeschränkt + + + Not room master + Nicht Gastgeber + + + No checker rights + Keine Rechte zum Benutzen des Inspektionshilfsprogramms + + + Room version incompatible to your hedgewars version + Die Raumversion ist inkompatibel zu deiner Hedgewars-Version + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_el.ts --- a/share/hedgewars/Data/Locale/hedgewars_el.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_el.ts Sat Jan 04 23:55:54 2014 +0400 @@ -153,6 +153,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -371,6 +378,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -635,7 +655,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - Το SDL_ttf επέστρεψε σφάλμα καθώς διερμήνευσε κείμενο. Το πιο πιθανό είναι αυτό να σχετίζεται με το σφάλμα στο freetype2. Προτείνεται να αναβαθμίσετε το freetype lib. + Το SDL_ttf επέστρεψε σφάλμα καθώς διερμήνευσε κείμενο. Το πιο πιθανό είναι αυτό να σχετίζεται με το σφάλμα στο freetype2. Προτείνεται να αναβαθμίσετε το freetype lib. @@ -648,19 +668,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -668,6 +675,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -795,6 +814,18 @@ Save drawn map + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -907,6 +938,13 @@ Save + + (%1 %2) + + + + + PageInGame @@ -1228,11 +1266,11 @@ Rules: - Κανόνες : + Κανόνες : Weapons: - Όπλα : + Όπλα : Search: @@ -1266,10 +1304,6 @@ - Clear filters - - - Open server administration page @@ -1396,6 +1430,22 @@ Copy + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1492,13 +1542,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1635,6 +1683,38 @@ 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 + + QComboBox @@ -1656,7 +1736,7 @@ Any - Οποιοσδήποτε + Οποιοσδήποτε In lobby @@ -1870,7 +1950,7 @@ Tip: - Συμβουλή : + Συμβουλή : Quality @@ -2014,6 +2094,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2036,10 +2128,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2265,6 +2353,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2401,6 +2496,10 @@ Create room + + set password + + RoomsListModel @@ -2448,6 +2547,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2515,13 +2618,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3116,4 +3212,127 @@ 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_en.ts --- a/share/hedgewars/Data/Locale/hedgewars_en.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_en.ts Sat Jan 04 23:55:54 2014 +0400 @@ -153,6 +153,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -369,6 +376,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -633,7 +653,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. + SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. @@ -646,19 +666,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -666,6 +673,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -793,6 +812,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -905,6 +936,13 @@ Save + + (%1 %2) + + + + + PageInGame @@ -1224,14 +1262,6 @@ Room Name: Room Name: - - Rules: - - - - Weapons: - - %1 players online @@ -1256,10 +1286,6 @@ - Clear filters - - - Open server administration page @@ -1386,6 +1412,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1482,13 +1524,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1625,6 +1665,38 @@ 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 + + QComboBox @@ -1645,10 +1717,6 @@ - Any - - - Disabled @@ -1851,10 +1919,6 @@ Explosives - Tip: - - - Quality @@ -1996,6 +2060,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2018,10 +2094,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2247,6 +2319,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2383,6 +2462,10 @@ Create room + + set password + + RoomsListModel @@ -2430,6 +2513,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2497,13 +2584,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3098,4 +3178,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_es.ts --- a/share/hedgewars/Data/Locale/hedgewars_es.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_es.ts Sat Jan 04 23:55:54 2014 +0400 @@ -157,6 +157,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -373,6 +380,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -637,7 +657,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf ha devuelto un error al dibujar texto, probablemente relacionado con un bug en freetype2. Se recomienda actualizar la librería freetype. + SDL_ttf ha devuelto un error al dibujar texto, probablemente relacionado con un bug en freetype2. Se recomienda actualizar la librería freetype. @@ -650,19 +670,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -670,6 +677,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -797,6 +816,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -909,6 +940,13 @@ Save Guardar + + (%1 %2) + + + + + PageInGame @@ -1230,11 +1268,11 @@ Rules: - Reglas: + Reglas: Weapons: - Armas: + Armas: Search: @@ -1268,10 +1306,6 @@ - Clear filters - - - Open server administration page @@ -1398,6 +1432,22 @@ Add an indestructible border along the bottom Añade un borde indestructible en la parta inferior + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1494,13 +1544,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1637,6 +1685,38 @@ 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 + + QComboBox @@ -1658,7 +1738,7 @@ Any - Cualquiera + Cualquiera In lobby @@ -1872,7 +1952,7 @@ Tip: - Consejo: + Consejo: Quality @@ -2016,6 +2096,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2038,10 +2130,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2267,6 +2355,13 @@ + QObject + + No description available + + + + QPushButton Go! @@ -2403,6 +2498,10 @@ Create room + + set password + + RoomsListModel @@ -2450,6 +2549,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2517,13 +2620,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3118,4 +3214,127 @@ 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_fi.ts --- a/share/hedgewars/Data/Locale/hedgewars_fi.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_fi.ts Sat Jan 04 23:55:54 2014 +0400 @@ -153,6 +153,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -369,6 +376,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -633,7 +653,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf palautti virheen mallintaessaan tekstiä, todennäköisesti syy on freetype2:n ohjelmavirheessä. Freetype-kirjaston päivitys on suosiltetavaa. + SDL_ttf palautti virheen mallintaessaan tekstiä, todennäköisesti syy on freetype2:n ohjelmavirheessä. Freetype-kirjaston päivitys on suosiltetavaa. @@ -646,19 +666,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -666,6 +673,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -793,6 +812,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -905,6 +936,13 @@ Save + + (%1 %2) + + + + + PageInGame @@ -1226,11 +1264,11 @@ Rules: - Säännöt: + Säännöt: Weapons: - Aseet: + Aseet: Search: @@ -1264,10 +1302,6 @@ - Clear filters - - - Open server administration page @@ -1394,6 +1428,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1490,13 +1540,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1633,6 +1681,38 @@ 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 + + QComboBox @@ -1654,7 +1734,7 @@ Any - Mikä tahansa + Mikä tahansa In lobby @@ -1868,7 +1948,7 @@ Tip: - Vinkki: + Vinkki: Quality @@ -2012,6 +2092,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2034,10 +2126,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2263,6 +2351,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2399,6 +2494,10 @@ Create room + + set password + + RoomsListModel @@ -2446,6 +2545,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2513,13 +2616,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3114,4 +3210,127 @@ Hiiri: Vasen nappi + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_fr.ts --- a/share/hedgewars/Data/Locale/hedgewars_fr.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_fr.ts Sat Jan 04 23:55:54 2014 +0400 @@ -165,6 +165,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -394,6 +401,19 @@ This page requires an internet connection. Cette page nécessite une connexion internet. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -665,7 +685,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf a renvoyé une erreur pendant l'affichage du texte, cela est sûrement causé par le bug de freetype2. Il est recommandé de mettre à jour la librairie freetype. + SDL_ttf a renvoyé une erreur pendant l'affichage du texte, cela est sûrement causé par le bug de freetype2. Il est recommandé de mettre à jour la librairie freetype. @@ -680,15 +700,15 @@ Duration: %1m %2s - Durée: %1m %2s + Durée: %1m %2s Video: %1x%2, - Vidéo: %1x%2 + Vidéo: %1x%2 %1 fps, - %1 fps, + %1 fps, Audio: @@ -698,6 +718,18 @@ unknown inconnu + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -825,6 +857,18 @@ Eraser Gomme + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -937,6 +981,13 @@ Save Enregistrer + + (%1 %2) + + + + + PageInGame @@ -1258,11 +1309,11 @@ Rules: - Règles : + Règles : Weapons: - Armes : + Armes : Search: @@ -1297,7 +1348,7 @@ Clear filters - Enlever les filtres + Enlever les filtres Open server administration page @@ -1427,6 +1478,22 @@ Add an indestructible border along the bottom Ajouter une bordure indestructible en bas + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1525,12 +1592,20 @@ Date: %1 - Date: %1 + Date: %1 Size: %1 - Taille: %1 + Taille: %1 + + + Date: %1 + Date: %1 {1?} + + + Size: %1 + Taille: %1 {1?} @@ -1666,6 +1741,38 @@ Frontend music Musique de l'interface + + Team + + + + Enable team tags by default + + + + Hog + + + + Enable hedgehog tags by default + + + + Health + + + + Enable health tags by default + + + + Translucent + + + + Enable translucent tags by default + + QComboBox @@ -1687,7 +1794,7 @@ Any - Tout + Tout In lobby @@ -1901,7 +2008,7 @@ Tip: - Conseil: + Conseil: Quality @@ -2047,6 +2154,18 @@ This setting will be effective at next restart. Le changement sera opérationnel au prochain redémarrage. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2071,7 +2190,7 @@ -r%1 (%2) - -r%1 (%2) + -r%1 (%2) @@ -2301,6 +2420,13 @@ + QObject + + No description available + Aucune description disponible + + + QPushButton Play demo @@ -2437,6 +2563,10 @@ Create room Créer une salle + + set password + + RoomsListModel @@ -2484,6 +2614,10 @@ Hand-drawn Dessinée + + Script + + SeedPrompt @@ -2555,7 +2689,7 @@ TeamShowWidget %1's team - Equipe de %1 + Equipe de %1 @@ -3158,111 +3292,123 @@ server Authentication failed - Echec d'authentification + Echec d'authentification 60 seconds cooldown after kick - Bannis pour 60 sec après un kick + Bannis pour 60 sec après un kick kicked - Exclus (kick) + Exclus (kick) Ping timeout - Met trop de temps à répondre + Met trop de temps à répondre bye - Aurevoir + Aurevoir Empty config entry - Configuration vide + Configuration vide Not room master - Vous n'êtes pas le propriétaire de la room + Vous n'êtes pas le propriétaire de la room Corrupted hedgehogs info - Info hérisson corrompus + Info hérisson corrompus too many teams - trop d'équipes + trop d'équipes too many hedgehogs - trop de hérissons + trop de hérissons There's already a team with same name in the list - Il y a déja une équipe avec le même nom dans la liste + Il y a déja une équipe avec le même nom dans la liste round in progress - La partie est en cour + La partie est en cour restricted - Ajout interdis + Ajout interdis REMOVE_TEAM: no such team - REMOVE_TEAM: aucune équipe de ce nom + REMOVE_TEAM: aucune équipe de ce nom Not team owner! - Vous n'êtes pas le propriétaire de cette équipe! + Vous n'êtes pas le propriétaire de cette équipe! Less than two clans! - Il faut 2 clans minimum! + Il faut 2 clans minimum! Room with such name already exists - Ce nom de room existe déjà + Ce nom de room existe déjà Illegal room name - Nom de room invalide + Nom de room invalide No such room - Cette room n'existe pas + Cette room n'existe pas Joining restricted - Accès interdis + Accès interdis Registered users only - Accès réservé aux utilisateurs enregistré + Accès réservé aux utilisateurs enregistré You are banned in this room - Vous avez été bannis de cette room + Vous avez été bannis de cette room Nickname already chosen - Pseudo déjà choisis + Pseudo déjà choisis Illegal nickname - Pseudo invalide + Pseudo invalide Protocol already known - Protocole déjà connu + Protocole déjà connu Bad number - Mauvais numéro + Mauvais numéro Nickname is already in use - Ce pseudo est actuellement utilisé sur le serveur + Ce pseudo est actuellement utilisé sur le serveur + + + Restricted + + + + No checker rights + + + + Room version incompatible to your hedgewars version + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_gl.ts --- a/share/hedgewars/Data/Locale/hedgewars_gl.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_gl.ts Sat Jan 04 23:55:54 2014 +0400 @@ -153,6 +153,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -369,6 +376,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -633,7 +653,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf devolveu un erro ao renderizar o texto, seguramente sexa por mor do erro de freetype2. Cómpre que actualices a túa biblioteca freetype. + SDL_ttf devolveu un erro ao renderizar o texto, seguramente sexa por mor do erro de freetype2. Cómpre que actualices a túa biblioteca freetype. @@ -646,19 +666,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -666,6 +673,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -793,6 +812,18 @@ Save drawn map + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -905,6 +936,13 @@ Save + + (%1 %2) + + + + + PageInGame @@ -1225,14 +1263,6 @@ Nome da sala: - Rules: - - - - Weapons: - - - Clear Borrado @@ -1260,10 +1290,6 @@ - Clear filters - - - Open server administration page @@ -1390,6 +1416,22 @@ Copy + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1486,13 +1528,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1629,6 +1669,38 @@ 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 + + QComboBox @@ -1708,10 +1780,6 @@ Green/Red grayscale - - Any - - QGroupBox @@ -1877,10 +1945,6 @@ - Tip: - - - Locale @@ -2000,6 +2064,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2022,10 +2098,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2250,6 +2322,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2386,6 +2465,10 @@ Create room + + set password + + RoomsListModel @@ -2433,6 +2516,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2500,13 +2587,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3101,4 +3181,127 @@ Mando + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_hu.ts --- a/share/hedgewars/Data/Locale/hedgewars_hu.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_hu.ts Sat Jan 04 23:55:54 2014 +0400 @@ -152,6 +152,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -363,6 +370,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -627,7 +647,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf hibát dobott a szöveg kiírásakor, ezt valószínűleg a freetype2 egy hibája okozza. Ajánlott a freetype lib frissítése. + SDL_ttf hibát dobott a szöveg kiírásakor, ezt valószínűleg a freetype2 egy hibája okozza. Ajánlott a freetype lib frissítése. @@ -640,19 +660,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -660,6 +667,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -787,6 +806,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -893,6 +924,12 @@ Save + + (%1 %2) + + + + PageInGame @@ -1213,14 +1250,6 @@ Szoba neve: - Rules: - - - - Weapons: - - - Clear Törlés @@ -1247,10 +1276,6 @@ - Clear filters - - - Open server administration page @@ -1377,6 +1402,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1472,13 +1513,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1615,6 +1654,38 @@ 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 + + QComboBox @@ -1635,10 +1706,6 @@ - Any - - - Disabled @@ -1841,10 +1908,6 @@ Robbanótöltetek - Tip: - - - Quality @@ -1986,6 +2049,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2008,10 +2083,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2235,6 +2306,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2371,6 +2449,10 @@ Create room + + set password + + RoomsListModel @@ -2418,6 +2500,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2485,13 +2571,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3086,4 +3165,127 @@ 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_it.ts --- a/share/hedgewars/Data/Locale/hedgewars_it.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_it.ts Sat Jan 04 23:55:54 2014 +0400 @@ -169,6 +169,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -398,6 +405,19 @@ This page requires an internet connection. Questa pagina richiede una connessione a Internet. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -669,7 +689,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf ha restituito un errore durante il rendering del testo, probabilmente relativo ad un bug della libreria freetype2. Si raccomanda di aggiornare le proprie librerie freetype. + SDL_ttf ha restituito un errore durante il rendering del testo, probabilmente relativo ad un bug della libreria freetype2. Si raccomanda di aggiornare le proprie librerie freetype. @@ -684,15 +704,15 @@ Duration: %1m %2s - Durata: %1m %2s + Durata: %1m %2s Video: %1x%2, - Video: %1x%2, + Video: %1x%2, %1 fps, - %1 fps, + %1 fps, Audio: @@ -702,6 +722,18 @@ unknown sconosciuto + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -829,6 +861,18 @@ Eraser Gomma + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -941,6 +985,13 @@ Save Salva + + (%1 %2) + + + + + PageInGame @@ -1262,11 +1313,11 @@ Rules: - Regole: + Regole: Weapons: - Armi: + Armi: Search: @@ -1301,7 +1352,7 @@ Clear filters - Rimuovi filtri + Rimuovi filtri Open server administration page @@ -1430,6 +1481,22 @@ Add an indestructible border along the bottom Aggiungi un bordo indistruttibile lungo la parte inferiore della mappa + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1528,15 +1595,25 @@ Date: %1 - Data: %1 + Data: %1 Size: %1 - Dimensione: %1 + Dimensione: %1 + + Date: %1 + Data: %1 + {1?} + + + Size: %1 + Dimensione: %1 + {1?} + QAction @@ -1671,6 +1748,38 @@ Frontend music Musica in presentazione + + Team + + + + Enable team tags by default + + + + Hog + + + + Enable hedgehog tags by default + + + + Health + + + + Enable health tags by default + + + + Translucent + + + + Enable translucent tags by default + + QComboBox @@ -1692,7 +1801,7 @@ Any - Qualsiasi + Qualsiasi In lobby @@ -1906,7 +2015,7 @@ Tip: - Suggerimento: + Suggerimento: Quality @@ -2056,6 +2165,18 @@ This setting will be effective at next restart. Questa impostazione avrà effetto al prossimo riavvio. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2080,7 +2201,7 @@ -r%1 (%2) - -r%1 (%2) + -r%1 (%2) @@ -2338,6 +2459,13 @@ + QObject + + No description available + Nessuna descrizione disponibile + + + QPushButton Go! @@ -2474,6 +2602,10 @@ Create room Crea stanza + + set password + + RoomsListModel @@ -2521,6 +2653,10 @@ Hand-drawn Disegnata a mano + + Script + + SeedPrompt @@ -2592,7 +2728,7 @@ TeamShowWidget %1's team - Squadra di %1 + Squadra di %1 @@ -3194,111 +3330,123 @@ server Not room master - Non proprietario della stanza + Non proprietario della stanza Corrupted hedgehogs info - Informazioni ricci corrotte + Informazioni ricci corrotte too many teams - troppe squadre + troppe squadre too many hedgehogs - troppi ricci + troppi ricci There's already a team with same name in the list - C'è già una quadra collo stesso nome in lista + C'è già una quadra collo stesso nome in lista round in progress - turno in corso + turno in corso restricted - proibito + proibito REMOVE_TEAM: no such team - CANCELLA_SQUADRA: squadra non presente + CANCELLA_SQUADRA: squadra non presente Not team owner! - Non proprietario della squadra! + Non proprietario della squadra! Less than two clans! - Meno di due clan! + Meno di due clan! Room with such name already exists - Esiste già una stanza con questo nome + Esiste già una stanza con questo nome Nickname already chosen - Nome già scelto + Nome già scelto Illegal nickname - Nome non valido + Nome non valido Protocol already known - Protocollo già conosciuto + Protocollo già conosciuto Bad number - Numero non valido + Numero non valido Nickname is already in use - Nome già in uso + Nome già in uso Authentication failed - Autenticazione fallita + Autenticazione fallita 60 seconds cooldown after kick - 60 secondi di raffreddamento prima dell'espulsione + 60 secondi di raffreddamento prima dell'espulsione kicked - espulso + espulso Ping timeout - Scadenza ping + Scadenza ping bye - ciao + ciao Illegal room name - Nome stanza non valido + Nome stanza non valido No such room - Stanza non esistente + Stanza non esistente Joining restricted - Ingresso riservato + Ingresso riservato Registered users only - Solo utenti registrati + Solo utenti registrati You are banned in this room - Sei stato espulso dalla stanza + Sei stato espulso dalla stanza Empty config entry - Configurazione vuota + Configurazione vuota + + + Restricted + + + + No checker rights + + + + Room version incompatible to your hedgewars version + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_ja.ts --- a/share/hedgewars/Data/Locale/hedgewars_ja.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_ja.ts Sat Jan 04 23:55:54 2014 +0400 @@ -152,6 +152,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -363,6 +370,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -627,7 +647,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. + SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. @@ -640,19 +660,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -660,6 +667,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -787,6 +806,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -893,6 +924,12 @@ Save セーブ + + (%1 %2) + + + + PageInGame @@ -1212,14 +1249,6 @@ Room Name: ルーム名: - - Rules: - - - - Weapons: - - %1 players online @@ -1243,10 +1272,6 @@ - Clear filters - - - Open server administration page @@ -1373,6 +1398,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1468,13 +1509,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1611,6 +1650,38 @@ 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 + + QComboBox @@ -1631,10 +1702,6 @@ - Any - - - Disabled @@ -1837,10 +1904,6 @@ - Tip: - - - Quality @@ -1982,6 +2045,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2004,10 +2079,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2231,6 +2302,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2367,6 +2445,10 @@ Create room + + set password + + RoomsListModel @@ -2414,6 +2496,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2481,13 +2567,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3082,4 +3161,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_ko.ts --- a/share/hedgewars/Data/Locale/hedgewars_ko.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_ko.ts Sat Jan 04 23:55:54 2014 +0400 @@ -152,6 +152,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -363,6 +370,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -620,13 +640,6 @@ - KB - - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - - - - KeyBinder Category @@ -636,19 +649,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -656,6 +656,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -783,6 +795,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -889,6 +913,12 @@ Save + + (%1 %2) + + + + PageInGame @@ -1192,14 +1222,6 @@ Admin features - - Rules: - - - - Weapons: - - %1 players online @@ -1223,10 +1245,6 @@ - Clear filters - - - Open server administration page @@ -1353,6 +1371,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1448,13 +1482,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1587,6 +1619,38 @@ 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 + + QComboBox @@ -1607,10 +1671,6 @@ - Any - - - Disabled @@ -1809,10 +1869,6 @@ - Tip: - - - Quality @@ -1954,6 +2010,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -1976,10 +2044,6 @@ Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2195,6 +2259,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2331,6 +2402,10 @@ Create room + + set password + + RoomsListModel @@ -2378,6 +2453,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2445,13 +2524,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3046,4 +3118,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_lt.ts --- a/share/hedgewars/Data/Locale/hedgewars_lt.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_lt.ts Sat Jan 04 23:55:54 2014 +0400 @@ -4,7 +4,7 @@ About - + Unknown Compiler @@ -20,12 +20,12 @@ AmmoSchemeModel - + new - + copy of @@ -97,7 +97,7 @@ DataManager - + Use Default @@ -186,6 +186,14 @@ + GameUIConfig + + + Guest + + + + HWApplication @@ -238,7 +246,7 @@ - + Scheme '%1' not supported @@ -335,44 +343,52 @@ HWForm - + DefaultTeam - + Game aborted - + Nickname + + + No nickname supplied. + + + - - No nickname supplied. - - - - Someone already uses your nickname %1 on the server. Please pick another nickname: - + + + + + Guest + + + + %1's Team - + Hedgewars - Nick registered - + This nick is registered, and you haven't specified a password. If this nick isn't yours, please register your own nick at www.hedgewars.org @@ -381,81 +397,92 @@ - + Your nickname is not registered. To prevent someone else from using it, please register it at www.hedgewars.org - + Your password wasn't saved either. - - + + Hedgewars - Empty nickname - + Hedgewars - Wrong password - + You entered a wrong password. - + + Room password + + + + + The room is protected with password. +Please, enter the password: + + + + Try Again - + Hedgewars - Connection error - + You reconnected too fast. Please wait a few seconds and try again. - - + + Cannot save record to file %1 - + Hedgewars Demo File File Types - + Hedgewars Save File File Types - + Demo name - + Demo name: - + This page requires an internet connection. @@ -463,13 +490,13 @@ HWGame - + en.txt lt.txt - + Cannot open demofile %1 @@ -477,158 +504,158 @@ HWMapContainer - + Map type: - + Image map - + Mission map - + Hand-drawn - + Randomly generated - + Random maze - + Random - + Map preview: - + Load map drawing - + Edit map drawing - + All - + Small - + Medium - + Large + + Cavern + + + + + Wacky + + + + + Large tunnels + + + + + Small islands + + + + + Medium islands + + + + + Large islands + + + + + Map size: + + + + + Maze style: + + + + + Mission: + + + + + Map: + + + + + + Theme: %1 + + + + + Load drawn map + + + + + Drawn Maps + + + + + All files + + + - Cavern + Small tunnels - Wacky - - - - - Large tunnels - - - - - Small islands - - - - - Medium islands - - - - - Large islands - - - - - Map size: - - - - - Maze style: - - - - - Mission: - - - - - Map: - - - - - - Theme: %1 - - - - - Load drawn map - - - - - Drawn Maps - - - - - All files - - - - - Small tunnels - - - - Medium tunnels - + Seed @@ -659,53 +686,53 @@ - + Remote host has closed connection - + The host was not found. Please check the host name and port settings. - + Connection refused - + The server is too old. Disconnecting now. - + Room destroyed - + You got kicked - - + + %1 *** %2 has joined the room - + %1 *** %2 has left - + %1 *** %2 has left (%3) - + Quit reason: @@ -752,7 +779,7 @@ HatButton - + Change hat (%1) @@ -776,14 +803,6 @@ - KB - - - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - - - - KeyBinder @@ -794,28 +813,27 @@ LibavInteraction - - Duration: %1m %2s - - - - - - Video: %1x%2, + + Duration: %1m %2s - %1 fps, + Video: %1x%2 - Audio: + %1 fps + Audio: + + + + unknown @@ -823,7 +841,7 @@ MapModel - + No description available. @@ -930,49 +948,64 @@ PageDrawMap - + Eraser - - Undo - - - - Clear - - - - - Load + Undo + Polyline + + + + + Rectangle + + + + + Ellipse + + + + + Clear + + + + + Load + + + + Save - + Load drawn map - - + + Drawn Maps - - + + All files - + Save drawn map @@ -1033,37 +1066,38 @@ PageGameStats - + Details - + + Health graph - + Ranking - - Play again - - - + Play again + + + + Save - + The best shot award was won by <b>%1</b> with <b>%2</b> pts. - + The best killer is <b>%1</b> with <b>%2</b> kills in a turn. @@ -1072,7 +1106,7 @@ - + A total of <b>%1</b> hedgehog(s) were killed during this round. @@ -1081,7 +1115,7 @@ - + (%1 kill) @@ -1090,7 +1124,16 @@ - + + (%1 %2) + + + + + + + + <b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts. @@ -1099,7 +1142,7 @@ - + <b>%1</b> killed <b>%2</b> of his own hedgehogs. @@ -1108,7 +1151,7 @@ - + <b>%1</b> was scared and skipped turn <b>%2</b> times. @@ -1374,97 +1417,97 @@ - + Frontend - + Custom colors - + Reset to default colors - + Game audio - + Frontend audio - - Account - - - - - Proxy settings - - - - - Proxy host - - - + Account + + + + + Proxy settings + + + + + Proxy host + + + + Proxy port - + Proxy login - + Proxy password - + No proxy - + System proxy settings - + Socks5 proxy - + HTTP proxy - + Miscellaneous - + Updates - + Check for updates - + Video recording options @@ -1505,32 +1548,17 @@ - - Rules: - - - - - Weapons: - - - - - Clear filters - - - - + Admin features - + Open server administration page - + %1 players online @@ -1677,17 +1705,37 @@ - + + None (Default) + + + + + Wrap (World wraps) + + + + + Bounce (Edges reflect) + + + + + Sea (Edges connect to sea) + + + + Copy - + New - + Delete @@ -1799,14 +1847,12 @@ - Date: %1 - + Date: %1 - Size: %1 - + Size: %1 @@ -1844,23 +1890,23 @@ - + Ignore - + Add friend - + Unignore - + Remove friend @@ -1903,54 +1949,94 @@ - + + Team + + + + + Enable team tags by default + + + + + Hog + + + + + Enable hedgehog tags by default + + + + + Health + + + + + Enable health tags by default + + + + + Translucent + + + + + Enable translucent tags by default + + + + Visual effects - - + + Sound - + In-game sound effects - - + + Music - + In-game music - + Frontend sound effects - + Frontend music - + Append date and time to record file name - + Check for updates at startup - + Fullscreen @@ -1961,7 +2047,7 @@ - + Save password @@ -1976,12 +2062,12 @@ - + Record audio - + Use game resolution @@ -1999,12 +2085,12 @@ - + Community - + (System default) @@ -2083,12 +2169,6 @@ Green/Red grayscale - - - - Any - - QGroupBox @@ -2141,12 +2221,12 @@ QLabel - + Revision - + This program is distributed under the %1 @@ -2201,16 +2281,16 @@ - - Tip: - - - 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! + + Tip: %1 + + + Server name: @@ -2221,22 +2301,22 @@ - + Locale - + Nickname - + This setting will be effective at next restart. - + Resolution @@ -2266,7 +2346,12 @@ - + + Displayed tags above hogs and translucent tags + + + + Initial sound volume @@ -2352,6 +2437,11 @@ + World Edge + + + + Scheme Name: @@ -2418,27 +2508,27 @@ - + Format - + Audio codec - + Video codec - + Framerate - + Bitrate (Kbps) @@ -2446,18 +2536,18 @@ QLineEdit - + unnamed - + hedgehog %1 - + anonymous @@ -2469,111 +2559,106 @@ Hedgewars %1 - - - -r%1 (%2) - - QMessageBox - + Teams - Are you sure? - + Do you really want to delete the team '%1'? - - + + Cannot delete default scheme '%1'! - + Please select a record from the list - + Hedgewars - Nick not registered - + Unable to start server - + Connection to server is lost - + Not all players are ready - + Are you sure you want to start this game? Not all players are ready. - + Hedgewars - Error - + System Information Preview - - + + Failed to generate captcha - + Failed to download captcha - + Please fill out all fields. Email is optional. - - + + Hedgewars - Success - + All file associations have been set - + File association failed. - - Error - - - + Error + + + + Cannot use the ammo '%1'! @@ -2641,38 +2726,38 @@ - + Room Name - Error - + Please select room from the list - + 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'? @@ -2703,20 +2788,20 @@ - - - + + + File error - + Cannot open '%1' for writing - - + + Cannot open '%1' for reading @@ -2758,6 +2843,15 @@ + QObject + + + + No description available + + + + QPushButton @@ -2776,7 +2870,7 @@ - + Go! @@ -2832,7 +2926,7 @@ - + Associate file extensions @@ -2865,12 +2959,12 @@ - + Set default options - + Restore default coding parameters @@ -2920,17 +3014,22 @@ RoomNamePrompt - + Enter a name for your room. - + + set password + + + + Cancel - + Create room @@ -2969,26 +3068,31 @@ - Rules + Script + Rules + + + + Weapons - - Random Map - - - - Random Maze + Random Map + Random Maze + + + + Hand-drawn @@ -3054,12 +3158,12 @@ TCPBase - + Unable to start server at %1. - + Unable to run engine at %1 Error code: %2 @@ -3074,14 +3178,6 @@ - TeamShowWidget - - - %1's team - - - - ThemePrompt @@ -3467,7 +3563,7 @@ - + Keyboard @@ -3827,4 +3923,157 @@ + + 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 + + + + + kicked + + + + + Ping timeout + + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_ms.ts --- a/share/hedgewars/Data/Locale/hedgewars_ms.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_ms.ts Sat Jan 04 23:55:54 2014 +0400 @@ -4,7 +4,7 @@ About - + Unknown Compiler @@ -20,12 +20,12 @@ AmmoSchemeModel - + new - + copy of @@ -97,7 +97,7 @@ DataManager - + Use Default @@ -184,6 +184,14 @@ + GameUIConfig + + + Guest + + + + HWApplication @@ -226,7 +234,7 @@ - + Scheme '%1' not supported @@ -323,27 +331,35 @@ HWForm - + + + + + Guest + + + + DefaultTeam - + %1's Team - + Game aborted - + Hedgewars - Nick registered - + This nick is registered, and you haven't specified a password. If this nick isn't yours, please register your own nick at www.hedgewars.org @@ -352,98 +368,109 @@ - + Your nickname is not registered. To prevent someone else from using it, please register it at www.hedgewars.org - + Your password wasn't saved either. - - Nickname - - - - - Someone already uses your nickname %1 on the server. -Please pick another nickname: - - - - - No nickname supplied. + Nickname - + Someone already uses your nickname %1 on the server. +Please pick another nickname: + + + + + + No nickname supplied. + + + + + Hedgewars - Empty nickname - + Hedgewars - Wrong password - + You entered a wrong password. - + + Room password + + + + + The room is protected with password. +Please, enter the password: + + + + Try Again - + Hedgewars - Connection error - + You reconnected too fast. Please wait a few seconds and try again. - - + + Cannot save record to file %1 - + Hedgewars Demo File File Types - + Hedgewars Save File File Types - + Demo name - + Demo name: - + This page requires an internet connection. @@ -451,13 +478,13 @@ HWGame - + en.txt ms.txt - + Cannot open demofile %1 @@ -465,158 +492,158 @@ HWMapContainer - + Map type: - + Image map - + Mission map - + Hand-drawn - + Randomly generated - + Random maze - + Random - + Map preview: - + Load map drawing - + Edit map drawing - + All - + Small - + Medium - + Large + + Cavern + + + + + Wacky + + + + + Large tunnels + + + + + Small islands + + + + + Medium islands + + + + + Large islands + + + + + Map size: + + + + + Maze style: + + + + + Mission: + + + + + Map: + + + + + + Theme: %1 + + + + + Load drawn map + + + + + Drawn Maps + + + + + All files + + + - Cavern + Small tunnels - Wacky - - - - - Large tunnels - - - - - Small islands - - - - - Medium islands - - - - - Large islands - - - - - Map size: - - - - - Maze style: - - - - - Mission: - - - - - Map: - - - - - - Theme: %1 - - - - - Load drawn map - - - - - Drawn Maps - - - - - All files - - - - - Small tunnels - - - - Medium tunnels - + Seed @@ -642,7 +669,7 @@ HWNewNet - + Quit reason: @@ -652,48 +679,48 @@ - + Remote host has closed connection - + The host was not found. Please check the host name and port settings. - + Connection refused - + The server is too old. Disconnecting now. - + You got kicked - + %1 *** %2 has left - + %1 *** %2 has left (%3) - - + + %1 *** %2 has joined the room - + Room destroyed @@ -740,7 +767,7 @@ HatButton - + Change hat (%1) @@ -764,14 +791,6 @@ - KB - - - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - - - - KeyBinder @@ -782,28 +801,27 @@ LibavInteraction - - Duration: %1m %2s - - - - - - Video: %1x%2, + + Duration: %1m %2s - %1 fps, + Video: %1x%2 - Audio: + %1 fps + Audio: + + + + unknown @@ -811,7 +829,7 @@ MapModel - + No description available. @@ -918,49 +936,64 @@ PageDrawMap - + Eraser - - Undo - - - - Clear - - - - - Load + Undo + Polyline + + + + + Rectangle + + + + + Ellipse + + + + + Clear + + + + + Load + + + + Save - + Load drawn map - - + + Drawn Maps - - + + All files - + Save drawn map @@ -1021,72 +1054,80 @@ PageGameStats - + Details - + + Health graph - + Ranking - - Play again - - - + Play again + + + + Save - + The best shot award was won by <b>%1</b> with <b>%2</b> pts. - + The best killer is <b>%1</b> with <b>%2</b> kills in a turn. - + A total of <b>%1</b> hedgehog(s) were killed during this round. - + (%1 kill) - + + (%1 %2) + + + + + + <b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts. - + <b>%1</b> killed <b>%2</b> of his own hedgehogs. - + <b>%1</b> was scared and skipped turn <b>%2</b> times. @@ -1350,97 +1391,97 @@ - + Frontend - + Custom colors - + Reset to default colors - + Game audio - + Frontend audio - - Account - - - - - Proxy settings - - - - - Proxy host - - - + Account + + + + + Proxy settings + + + + + Proxy host + + + + Proxy port - + Proxy login - + Proxy password - + No proxy - + System proxy settings - + Socks5 proxy - + HTTP proxy - + Miscellaneous - + Updates - + Check for updates - + Video recording options @@ -1481,32 +1522,17 @@ - - Rules: - - - - - Weapons: - - - - - Clear filters - - - - + Admin features - + Open server administration page - + %1 players online @@ -1651,17 +1677,37 @@ - + + None (Default) + + + + + Wrap (World wraps) + + + + + Bounce (Edges reflect) + + + + + Sea (Edges connect to sea) + + + + Copy - + New - + Delete @@ -1771,14 +1817,12 @@ - Date: %1 - + Date: %1 - Size: %1 - + Size: %1 @@ -1831,23 +1875,23 @@ - + Ignore - + Add friend - + Unignore - + Remove friend @@ -1866,7 +1910,7 @@ QCheckBox - + Save password @@ -1881,12 +1925,12 @@ - + Check for updates at startup - + Fullscreen @@ -1906,54 +1950,94 @@ - + + Team + + + + + Enable team tags by default + + + + + Hog + + + + + Enable hedgehog tags by default + + + + + Health + + + + + Enable health tags by default + + + + + Translucent + + + + + Enable translucent tags by default + + + + Visual effects - - + + Sound - + In-game sound effects - - + + Music - + In-game music - + Frontend sound effects - + Frontend music - + Append date and time to record file name - + Record audio - + Use game resolution @@ -1971,12 +2055,12 @@ - + Community - + (System default) @@ -2055,12 +2139,6 @@ Green/Red grayscale - - - - Any - - QGroupBox @@ -2210,16 +2288,16 @@ - - Tip: - - - 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! + + Tip: %1 + + + Server name: @@ -2235,22 +2313,22 @@ - + Locale - + Nickname - + This setting will be effective at next restart. - + Resolution @@ -2280,7 +2358,12 @@ - + + Displayed tags above hogs and translucent tags + + + + Initial sound volume @@ -2366,41 +2449,46 @@ + World Edge + + + + Scheme Name: - + Format - + Audio codec - + Video codec - + Framerate - + Bitrate (Kbps) - + Revision - + This program is distributed under the %1 @@ -2418,18 +2506,18 @@ QLineEdit - + unnamed - + hedgehog %1 - + anonymous @@ -2441,101 +2529,96 @@ Hedgewars %1 - - - -r%1 (%2) - - QMessageBox - + Teams - Are you sure? - + Do you really want to delete the team '%1'? - - + + Cannot delete default scheme '%1'! - + Please select a record from the list - + Hedgewars - Nick not registered - + Unable to start server - + Connection to server is lost - + Not all players are ready - + Are you sure you want to start this game? Not all players are ready. - + Hedgewars - Error - + System Information Preview - - + + Failed to generate captcha - + Failed to download captcha - + Please fill out all fields. Email is optional. - - + + Hedgewars - Success - + All file associations have been set - + File association failed. @@ -2603,38 +2686,38 @@ - + Room Name - Error - + Please select room from the list - + 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'? @@ -2663,30 +2746,30 @@ - - - + + + File error - + Cannot open '%1' for writing - - + + Cannot open '%1' for reading - - Error - - - + Error + + + + Cannot use the ammo '%1'! @@ -2728,6 +2811,15 @@ + QObject + + + + No description available + + + + QPushButton @@ -2751,7 +2843,7 @@ - + Go! @@ -2807,7 +2899,7 @@ - + Associate file extensions @@ -2835,12 +2927,12 @@ - + Set default options - + Restore default coding parameters @@ -2890,17 +2982,22 @@ RoomNamePrompt - + Enter a name for your room. - + + set password + + + + Cancel - + Create room @@ -2939,26 +3036,31 @@ - Rules + Script + Rules + + + + Weapons - - Random Map - - - - Random Maze + Random Map + Random Maze + + + + Hand-drawn @@ -3024,12 +3126,12 @@ TCPBase - + Unable to start server at %1. - + Unable to run engine at %1 Error code: %2 @@ -3044,14 +3146,6 @@ - TeamShowWidget - - - %1's team - - - - ThemePrompt @@ -3755,7 +3849,7 @@ - + Keyboard @@ -3797,4 +3891,157 @@ + + 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 + + + + + kicked + + + + + Ping timeout + + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_nl.ts --- a/share/hedgewars/Data/Locale/hedgewars_nl.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_nl.ts Sat Jan 04 23:55:54 2014 +0400 @@ -153,6 +153,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -369,6 +376,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -626,13 +646,6 @@ - KB - - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - - - - KeyBinder Category @@ -642,19 +655,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -662,6 +662,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -789,6 +801,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -901,6 +925,13 @@ Save + + (%1 %2) + + + + + PageInGame @@ -1204,14 +1235,6 @@ Admin features - - Rules: - - - - Weapons: - - %1 players online @@ -1236,10 +1259,6 @@ - Clear filters - - - Open server administration page @@ -1366,6 +1385,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1462,13 +1497,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1601,6 +1634,38 @@ 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 + + QComboBox @@ -1621,10 +1686,6 @@ - Any - - - Disabled @@ -1823,10 +1884,6 @@ - Tip: - - - Quality @@ -1968,6 +2025,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -1990,10 +2059,6 @@ Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2210,6 +2275,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2346,6 +2418,10 @@ Create room + + set password + + RoomsListModel @@ -2393,6 +2469,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2460,13 +2540,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3061,4 +3134,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_pl.ts --- a/share/hedgewars/Data/Locale/hedgewars_pl.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_pl.ts Sat Jan 04 23:55:54 2014 +0400 @@ -403,6 +403,15 @@ Guest Gość + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -670,7 +679,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf zwrócił problem podczas przetwarzania tekstu, najprawdopodobniej jest to związane z błędem we freetype2. Zaleca się zaktualizowanie biblioteki freetype. + SDL_ttf zwrócił problem podczas przetwarzania tekstu, najprawdopodobniej jest to związane z błędem we freetype2. Zaleca się zaktualizowanie biblioteki freetype. @@ -685,15 +694,15 @@ Duration: %1m %2s - Długość: %1m %2s + Długość: %1m %2s Video: %1x%2, - Wideo: %1x%2, + Wideo: %1x%2, %1 fps, - %1 kl/s, + %1 kl/s, Audio: @@ -703,6 +712,18 @@ unknown nieznany + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -830,6 +851,18 @@ Eraser Gumka + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -948,6 +981,14 @@ Save Zapisz + + (%1 %2) + + + + + + PageInGame @@ -1269,11 +1310,11 @@ Rules: - Zasady: + Zasady: Weapons: - Uzbrojenie: + Uzbrojenie: Search: @@ -1309,7 +1350,7 @@ Clear filters - Usuń filtry + Usuń filtry Open server administration page @@ -1438,6 +1479,22 @@ Add an indestructible border along the bottom Dodaje niezniszczalną ramkę u dołu mapy + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1537,12 +1594,20 @@ Date: %1 - Data: %1 + Data: %1 Size: %1 - Rozmiar: %1 + Rozmiar: %1 + + + Date: %1 + Data: %1 {1?} + + + Size: %1 + Rozmiar: %1 {1?} @@ -1678,6 +1743,38 @@ Frontend music Muzyka w menu + + Team + + + + Enable team tags by default + + + + Hog + + + + Enable hedgehog tags by default + + + + Health + + + + Enable health tags by default + + + + Translucent + + + + Enable translucent tags by default + + QComboBox @@ -1699,7 +1796,7 @@ Any - Dowolne + Dowolne In lobby @@ -1913,7 +2010,7 @@ Tip: - Rada: + Rada: Quality @@ -2063,6 +2160,18 @@ This setting will be effective at next restart. Ustawienia zadziałają po restarcie gry. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2087,7 +2196,7 @@ -r%1 (%2) - -r%1 (%2) + -r%1 (%2) @@ -2342,6 +2451,13 @@ + QObject + + No description available + Brak opisu + + + QPushButton Go! @@ -2478,6 +2594,10 @@ Create room Stwórz pokój + + set password + + RoomsListModel @@ -2525,6 +2645,10 @@ Hand-drawn Rys. ręcznie + + Script + + SeedPrompt @@ -2596,7 +2720,7 @@ TeamShowWidget %1's team - Drużyna %1 + Drużyna %1 @@ -3194,4 +3318,127 @@ 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_pt_BR.ts --- a/share/hedgewars/Data/Locale/hedgewars_pt_BR.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_pt_BR.ts Sat Jan 04 23:55:54 2014 +0400 @@ -153,6 +153,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -382,6 +389,19 @@ This page requires an internet connection. Esta página exige uma conexão com a Internet. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -650,7 +670,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf retornou um erro enquanto renderizava o texto, o mais provável é que esse esteja relacionado a um problema na freetype2. Recomendamos que você atualize sua biblioteca freetype. + SDL_ttf retornou um erro enquanto renderizava o texto, o mais provável é que esse esteja relacionado a um problema na freetype2. Recomendamos que você atualize sua biblioteca freetype. @@ -665,15 +685,15 @@ Duration: %1m %2s - Duração: %1m %2s + Duração: %1m %2s Video: %1x%2, - Vídeo: %1x%2, + Vídeo: %1x%2, %1 fps, - %1 fps, + %1 fps, Audio: @@ -683,6 +703,18 @@ unknown desconhecido + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -810,6 +842,18 @@ Eraser Borracha + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -922,6 +966,13 @@ Save Salvar + + (%1 %2) + + + + + PageInGame @@ -1243,11 +1294,11 @@ Rules: - Regras: + Regras: Weapons: - Armas: + Armas: Search: @@ -1282,7 +1333,7 @@ Clear filters - Limpar filtros + Limpar filtros Open server administration page @@ -1411,6 +1462,22 @@ Add an indestructible border along the bottom Adicione uma borda indestrutível na parte inferior + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1509,12 +1576,20 @@ Date: %1 - Data: %1 + Data: %1 Size: %1 - Tamanho: %1 + Tamanho: %1 + + + Date: %1 + Data: %1 {1?} + + + Size: %1 + Tamanho: %1 {1?} @@ -1650,6 +1725,38 @@ Frontend music Música da interface + + Team + + + + Enable team tags by default + + + + Hog + + + + Enable hedgehog tags by default + + + + Health + + + + Enable health tags by default + + + + Translucent + + + + Enable translucent tags by default + + QComboBox @@ -1671,7 +1778,7 @@ Any - Qualquer + Qualquer In lobby @@ -1885,7 +1992,7 @@ Tip: - Dica: + Dica: Quality @@ -2031,6 +2138,18 @@ This setting will be effective at next restart. Esta configuração se efetivará no próximo reinício. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2055,7 +2174,7 @@ -r%1 (%2) - -r%1 (%2) + -r%1 (%2) @@ -2283,6 +2402,13 @@ + QObject + + No description available + Não há descrição disponível + + + QPushButton Go! @@ -2419,6 +2545,10 @@ Create room Criar sala + + set password + + RoomsListModel @@ -2466,6 +2596,10 @@ Hand-drawn Desenhado à mão + + Script + + SeedPrompt @@ -2537,7 +2671,7 @@ TeamShowWidget %1's team - Equipe de %1 + Equipe de %1 @@ -3137,4 +3271,127 @@ 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_pt_PT.ts --- a/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts Sat Jan 04 23:55:54 2014 +0400 @@ -157,6 +157,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -386,6 +393,19 @@ This page requires an internet connection. Esta página requer ligação à internet + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -657,7 +677,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf retornou um erro ao renderizar o texto, muito provavelmente está relacionado com o bug no freetype2. É recomendado atualizar a sua lib freetype. + SDL_ttf retornou um erro ao renderizar o texto, muito provavelmente está relacionado com o bug no freetype2. É recomendado atualizar a sua lib freetype. @@ -672,16 +692,16 @@ Duration: %1m %2s - Duração: %1m %2s + Duração: %1m %2s Video: %1x%2, - Vídeo: %1x%2, + Vídeo: %1x%2, %1 fps, - %1 fps, + %1 fps, Audio: @@ -691,6 +711,18 @@ unknown desconhecido + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -818,6 +850,18 @@ Eraser Apagador + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -930,6 +974,13 @@ Save Gravar + + (%1 %2) + + + + + PageInGame @@ -1235,11 +1286,11 @@ Rules: - Regras: + Regras: Weapons: - Armamento: + Armamento: %1 players online @@ -1266,7 +1317,7 @@ Clear filters - Limpar filtros + Limpar filtros Open server administration page @@ -1395,6 +1446,22 @@ Add an indestructible border along the bottom Adiciona uma barreira indestrutível ao longo do fundo do terreno + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1493,15 +1560,25 @@ Date: %1 - Data: %1 + Data: %1 Size: %1 - Tamanho: %1 + Tamanho: %1 + + Date: %1 + Data: %1 + {1?} + + + Size: %1 + Tamanho: %1 + {1?} + QAction @@ -1632,6 +1709,38 @@ Frontend music Musica no frontend + + Team + + + + Enable team tags by default + + + + Hog + + + + Enable hedgehog tags by default + + + + Health + + + + Enable health tags by default + + + + Translucent + + + + Enable translucent tags by default + + QComboBox @@ -1653,7 +1762,7 @@ Any - Qualquer + Qualquer Disabled @@ -1855,7 +1964,7 @@ Tip: - Dica: + Dica: Quality @@ -2001,6 +2110,18 @@ This setting will be effective at next restart. Esta opção entrará em efeito quando o jogo for reiniciado. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2025,7 +2146,7 @@ -r%1 (%2) - -r%1 (%2) + -r%1 (%2) @@ -2285,6 +2406,13 @@ + QObject + + No description available + Sem descrição disponível + + + QPushButton default @@ -2421,6 +2549,10 @@ Create room Criar sala + + set password + + RoomsListModel @@ -2468,6 +2600,10 @@ Hand-drawn Desenhado à mão + + Script + + SeedPrompt @@ -2539,7 +2675,7 @@ TeamShowWidget %1's team - Equipa de %1 + Equipa de %1 @@ -3141,115 +3277,123 @@ server Not room master - Não és o anfitrião da sala + Não és o anfitrião da sala Corrupted hedgehogs info - Informação dos ouriços corrompida + Informação dos ouriços corrompida too many teams - demasiadas equipas + demasiadas equipas too many hedgehogs - demasiados ouriços + demasiados ouriços There's already a team with same name in the list - Já existe uma equipa com o mesmo nome na lista + Já existe uma equipa com o mesmo nome na lista round in progress - partida em progresso + partida em progresso restricted - limitada + limitada REMOVE_TEAM: no such team - REMOVE_TEAM: equipa inexistente + REMOVE_TEAM: equipa inexistente Not team owner! - A equipa não te pertence! + A equipa não te pertence! Less than two clans! - Menos de 2 clãs! + Menos de 2 clãs! Room with such name already exists - Já existe uma sala com esse nome + Já existe uma sala com esse nome Nickname already chosen - Utilizador já em uso + Utilizador já em uso Illegal nickname - Nome de utilizador ilegal + Nome de utilizador ilegal Protocol already known - Protocolo já conhecido + Protocolo já conhecido Bad number - Número inválido + Número inválido Nickname is already in use - Nome de utilizador já em uso + Nome de utilizador já em uso No checker rights - Não possui permissões para verificar + Não possui permissões para verificar Authentication failed - A autenticação falhou + A autenticação falhou 60 seconds cooldown after kick - É necessário aguardar 60 segundos após uma expulsão + É necessário aguardar 60 segundos após uma expulsão kicked - expulso + expulso Ping timeout - Ping timeout + Ping timeout bye - tchau (bye) + tchau (bye) Illegal room name - Nome da sala ilegal + Nome da sala ilegal No such room - Sala inexistente + Sala inexistente Joining restricted - Entrada restrita + Entrada restrita Registered users only - Apenas utilizadores registados + Apenas utilizadores registados You are banned in this room - Estás banido desta sala + Estás banido desta sala Empty config entry - Campo vazio na configuração + Campo vazio na configuração + + + Restricted + + + + Room version incompatible to your hedgewars version + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_ro.ts --- a/share/hedgewars/Data/Locale/hedgewars_ro.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_ro.ts Sat Jan 04 23:55:54 2014 +0400 @@ -154,6 +154,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -375,6 +382,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -639,7 +659,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. + SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. @@ -652,19 +672,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -672,6 +679,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -799,6 +818,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -917,6 +948,14 @@ Save + + (%1 %2) + + + + + + PageInGame @@ -1236,14 +1275,6 @@ Room Name: Room Name: - - Rules: - - - - Weapons: - - %1 players online @@ -1269,10 +1300,6 @@ - Clear filters - - - Open server administration page @@ -1399,6 +1426,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1496,13 +1539,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1639,6 +1680,38 @@ 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 + + QComboBox @@ -1659,10 +1732,6 @@ - Any - - - Disabled @@ -1865,10 +1934,6 @@ Explosives - Tip: - - - Quality @@ -2010,6 +2075,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2032,10 +2109,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2262,6 +2335,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2398,6 +2478,10 @@ Create room + + set password + + RoomsListModel @@ -2445,6 +2529,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2512,13 +2600,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3113,4 +3194,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_ru.ts --- a/share/hedgewars/Data/Locale/hedgewars_ru.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_ru.ts Sat Jan 04 23:55:54 2014 +0400 @@ -158,6 +158,13 @@ + GameUIConfig + + Guest + Гость + + + HWApplication %1 minutes @@ -332,7 +339,7 @@ Hedgewars - Nick registered - + Hedgewars - Имя пользователя зарегистрировано This nick is registered, and you haven't specified a password. @@ -340,39 +347,45 @@ 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 - Пустое имя пользователя Hedgewars - Wrong password - + Hedgewars - Неверный пароль You entered a wrong password. - + Вы ввели неверный пароль. Try Again - + Попробуйте снова Hedgewars - Connection error - + Hedgewars - Ошибка соединения You reconnected too fast. @@ -382,7 +395,21 @@ This page requires an internet connection. - + Для этой страницы нужно соединение с интернетом. + + + Guest + Гость + + + Room password + Пароль комнаты + + + The room is protected with password. +Please, enter the password: + Эта комната защищена паролем. +Пожалуйста, введите пароль: @@ -593,14 +620,17 @@ 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: @@ -648,7 +678,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf возвратил ошибку при выводе текста, наиболее вероятно это вызвано багом в библиотеке freetype2. Рекомендуется обновить библиотеку. + SDL_ttf возвратил ошибку при выводе текста, наиболее вероятно это вызвано багом в библиотеке freetype2. Рекомендуется обновить библиотеку. @@ -663,15 +693,15 @@ Duration: %1m %2s - Длительность: %1мин %2сек + Длительность: %1мин %2сек Video: %1x%2, - Видео: %1x%2, + Видео: %1x%2, %1 fps, - %1 кадров/сек, + %1 кадров/сек, Audio: @@ -681,6 +711,18 @@ unknown неизвестно + + Duration: %1m %2s + Длительность: %1мин %2сек + + + Video: %1x%2 + Видео: %1x%2 + + + %1 fps + %1 кадров/сек + MapModel @@ -767,7 +809,7 @@ This page requires an internet connection. - + Для этой страницы нужно соединение с интернетом. @@ -808,6 +850,18 @@ Eraser Стирательная резинка + + Polyline + Ломаная + + + Rectangle + Прямоугольник + + + Ellipse + Эллипс + PageEditTeam @@ -920,11 +974,19 @@ Play again - + Играть заново Save - Сохранить + Сохранить + + + (%1 %2) + + + + + @@ -961,7 +1023,7 @@ Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars - + Оставьте отзыв, упомянув проблемы, предложив новые возможности или просто рассказав, что вам нравится Hedgewars Access the user created content downloadable from our website @@ -1185,7 +1247,7 @@ Game audio - + Звук в игре Frontend audio @@ -1193,7 +1255,7 @@ Account - + Учётная запись Proxy settings @@ -1247,11 +1309,11 @@ Rules: - Правила: + Правила: Weapons: - Оружие: + Оружие: Search: @@ -1287,7 +1349,7 @@ Clear filters - Очистить фильтры + Очистить фильтры Open server administration page @@ -1416,6 +1478,22 @@ Add an indestructible border along the bottom Добавить неразрушимую границу внизу карты + + None (Default) + Отсутствует (по умолчанию) + + + Wrap (World wraps) + Замыкание + + + Bounce (Edges reflect) + Отражение + + + Sea (Edges connect to sea) + Море (края соединены с морем) + PageSelectWeapon @@ -1515,11 +1593,19 @@ Date: %1 - Дата: %1 + Дата: %1 Size: %1 + Размер: %1 + + + Date: %1 + Дата: %1 + + + Size: %1 Размер: %1 @@ -1575,11 +1661,11 @@ Show games in lobby - + Показывать неначавшиеся игры Show games in-progress - Показать текущие игры + Показывать текущие игры @@ -1638,7 +1724,7 @@ In-game sound effects - + Внутриигровые звуковые эффекты Music @@ -1646,7 +1732,7 @@ In-game music - + Внутриигровая музыка Frontend sound effects @@ -1656,6 +1742,38 @@ 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 + + QComboBox @@ -1677,7 +1795,7 @@ Any - Любой + Любой In lobby @@ -1891,7 +2009,7 @@ Tip: - Подсказка: + Подсказка: Quality @@ -2041,6 +2159,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + Край мира + QLineEdit @@ -2063,10 +2193,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2294,6 +2420,13 @@ + QObject + + No description available + Описание отсутствует + + + QPushButton Play demo @@ -2377,7 +2510,7 @@ Restore default coding parameters - + Восстановить параметры кодирования Open the video directory in your system @@ -2385,15 +2518,15 @@ Play this video - + Играть видео Delete this video - + Удалить видео Upload this video to your Youtube account - + Отправить на YouTube Reset @@ -2430,6 +2563,10 @@ Create room Создать комнату + + set password + указать пароль + RoomsListModel @@ -2477,12 +2614,16 @@ Hand-drawn Рисованная карта + + Script + Скрипт + SeedPrompt The map seed is the basis for all random values generated by the game. - Зерно карты - это основа для всех псведослучайных значений, используемых в игре. + Зерно карты - это основа для всех псевдослучайных значений, используемых в игре. Cancel @@ -2547,7 +2688,7 @@ TeamShowWidget %1's team - Команда %1 + Команда %1 @@ -3145,4 +3286,127 @@ + + server + + 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 + + + + kicked + + + + Ping timeout + + + + bye + + + + No such room + Нет такой комнаты + + + Joining restricted + + + + Registered users only + Только для зарегистрированных игроков + + + You are banned in this room + + + + Empty config entry + + + + Restricted + + + + Room version incompatible to your hedgewars version + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_sk.ts --- a/share/hedgewars/Data/Locale/hedgewars_sk.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_sk.ts Sat Jan 04 23:55:54 2014 +0400 @@ -158,6 +158,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -382,6 +389,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -646,7 +666,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf vrátil chybu počas renderovania textu, s najväčšou pravdepodobnosťou sa jedná o chybu vo freetype2. Doporučujeme aktualizovať vašu knižnicu freetype. + SDL_ttf vrátil chybu počas renderovania textu, s najväčšou pravdepodobnosťou sa jedná o chybu vo freetype2. Doporučujeme aktualizovať vašu knižnicu freetype. @@ -661,15 +681,15 @@ Duration: %1m %2s - Trvanie: %1m %2s + Trvanie: %1m %2s Video: %1x%2, - Video: %1x%2, + Video: %1x%2, %1 fps, - %1 fps, + %1 fps, Audio: @@ -679,6 +699,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -806,6 +838,18 @@ Eraser Guma + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -924,6 +968,14 @@ Save Uložiť + + (%1 %2) + + + + + + PageInGame @@ -1245,11 +1297,11 @@ Rules: - Pravidlá: + Pravidlá: Weapons: - Zbrane: + Zbrane: Search: @@ -1284,10 +1336,6 @@ - Clear filters - - - Open server administration page @@ -1414,6 +1462,22 @@ Add an indestructible border along the bottom Pridať nezničiteľný okraj popri spodku obrazovky + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1511,13 +1575,11 @@ uploadujem - Date: %1 - + Date: %1 - Size: %1 - + Size: %1 @@ -1654,6 +1716,38 @@ 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 + + QComboBox @@ -1675,7 +1769,7 @@ Any - Ľubovoľný + Ľubovoľný In lobby @@ -1889,7 +1983,7 @@ Tip: - Tip: + Tip: Quality @@ -2037,6 +2131,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2059,10 +2165,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2315,6 +2417,13 @@ + QObject + + No description available + Žiaden popis nie je dostupný + + + QPushButton Go! @@ -2451,6 +2560,10 @@ Create room + + set password + + RoomsListModel @@ -2498,6 +2611,10 @@ Hand-drawn Ručne kreslená + + Script + + SeedPrompt @@ -2565,13 +2682,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3166,4 +3276,127 @@ Pravý joystick (Doľava) + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_sv.ts --- a/share/hedgewars/Data/Locale/hedgewars_sv.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_sv.ts Sat Jan 04 23:55:54 2014 +0400 @@ -157,6 +157,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -373,6 +380,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -637,7 +657,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - Fel uppstod då SDL_ttf skulle rendera text. Det beror högst troligen på felet i freetype2. Du rekommenderas att uppdatera ditt freetype-bibliotek. + Fel uppstod då SDL_ttf skulle rendera text. Det beror högst troligen på felet i freetype2. Du rekommenderas att uppdatera ditt freetype-bibliotek. @@ -650,19 +670,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -670,6 +677,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -797,6 +816,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -909,6 +940,13 @@ Save Spara + + (%1 %2) + + + + + PageInGame @@ -1230,11 +1268,11 @@ Rules: - Regler: + Regler: Weapons: - Vapen: + Vapen: Search: @@ -1268,10 +1306,6 @@ - Clear filters - - - Open server administration page @@ -1398,6 +1432,22 @@ Add an indestructible border along the bottom Lägg till en oförstörbar barriär längs botten + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1494,13 +1544,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1637,6 +1685,38 @@ 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 + + QComboBox @@ -1658,7 +1738,7 @@ Any - Vilken som + Vilken som In lobby @@ -1872,7 +1952,7 @@ Tip: - Tips: + Tips: Quality @@ -2016,6 +2096,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2038,10 +2130,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2267,6 +2355,13 @@ + QObject + + No description available + + + + QPushButton Go! @@ -2403,6 +2498,10 @@ Create room + + set password + + RoomsListModel @@ -2450,6 +2549,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2517,13 +2620,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3118,4 +3214,127 @@ Styrkors + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_tr_TR.ts --- a/share/hedgewars/Data/Locale/hedgewars_tr_TR.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_tr_TR.ts Sat Jan 04 23:55:54 2014 +0400 @@ -5,14 +5,14 @@ About Unknown Compiler - + Bilinmeyen Derleyici AbstractPage Go back - + Geri Dön @@ -23,108 +23,108 @@ copy of - + kopya BanDialog IP - IP + IP Nick - + Takma Ad IP/Nick - + IP Reason - + Sebep Duration - + Süre Ok - + Tamam Cancel - İptal + İptal you know why - + biliyor musunuz Warning - + Uyarı Please, specify %1 - + Lütfen %1 belirtin nickname - + takmaad permanent - + kalıcı DataManager Use Default - + Varsayılanı Kullan FeedbackDialog View - + Göster Cancel - İptal + İptal Send Feedback - + Geribildirim Gönder + + + Please give us feedback! + Lütfen bize geribildirim gönder! We are always happy about suggestions, ideas, or bug reports. - - - - Send us feedback! - - - - If you found a bug, you can see if it's already been reported here: - - - - Your email address is optional, but necessary if you want us to get back at you. - + Her zaman yeni öneri, fikir ve hata raporlarından mutlu oluyoruz. + + + If you found a bug, you can see if it's already known here (english): + Eğer bir hata bulduysan, burada olup olmadığını görebilirsin (İngilizce): + + + Your email address is optional, but we may want to contact you. + E-posta adresi isteğe bağlıdır, ancak iletişime geçmek isteyebiliriz. FreqSpinBox Never - + Asla Every %1 turn - - + + Her %1 turda @@ -140,125 +140,120 @@ Game scheme will auto-select a weapon - + Oyun planı otomatik bir silah seçecek Map - Harita + Harita Game options - + Oyun seçenekleri HWApplication %1 minutes - - + + %1 dakika %1 hour - - + + %1 saat %1 hours - - + + %1 saat %1 day - - + + %1 gün %1 days - - + + %1 gün Scheme '%1' not supported - + '%1' planı desteklenmiyor Cannot create directory %1 - %1 dizini oluşturulamadı + %1 dizini oluşturulamadı Failed to open data directory: %1 Please check your installation! - + Veri dizini açılamadı: +%1 + +Lütfen kurulumunuzu denetleyin! HWAskQuitDialog Do you really want to quit? - + Gerçekten çıkmak istiyor musunuz? HWChatWidget %1 has been removed from your ignore list - - - - %1 has been added to your ignore list - + %1 yoksayma listenizden kaldırıldı + + + %1 has been added toINCOMPLETE your ignore list + %1 yoksayma listenize eklendi %1 has been removed from your friends list - + %1 arkadaş listenizden kaldırıldı %1 has been added to your friends list - + %1 arkadaş listenize eklendi Stylesheet imported from %1 - + %1 biçembelgesi aktarıldı Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset! - + Geçerli BiçemBelgesini ileride kullanmak için %1, sıfırlamak için %3 girin! Couldn't read %1 - + %1 okunamadı StyleSheet discarded - + BiçemBelgesi silindi StyleSheet saved to %1 - + BiçemBelgesi %1 konumuna kaydedildi Failed to save StyleSheet to %1 - - - - %1 has joined - - - - %1 has left - - - - %1 has left (%2) - + BiçemBelgesi %1 konumuna kaydedilemedi + + + %1 has been added to your ignore list + %1 yoksayma listenize eklendi @@ -269,50 +264,50 @@ DefaultTeam - + VarsayılanTakım Hedgewars Demo File File Types - + Hedgewars Gösteri Dosyası Hedgewars Save File File Types - + Hedgewars Kayıt Dosyası Demo name - + Gösteri adı Demo name: - + Gösteri adı: Game aborted - + Oyun sonlandı Nickname - + Takma ad No nickname supplied. - + Takma ad girilmedi. Someone already uses your nickname %1 on the server. Please pick another nickname: - + Sunucuda başka biri %1 takma adını kullanıyor. Başka bir isim girin: %1's Team - + %1 Oyuncusunun Takımı Hedgewars - Nick registered - + Hedgewars - Takma ad kayıtlı This nick is registered, and you haven't specified a password. @@ -320,48 +315,53 @@ If this nick isn't yours, please register your own nick at www.hedgewars.org Password: - + Bu takma ad kayıtlı ve bir parola belirtmedin. + +Bu takma ad senin değilse, lütfen kendi takma adını www.hedgewars.org adresinden kaydet. + +Parola: Your nickname is not registered. To prevent someone else from using it, please register it at www.hedgewars.org - + Takma adın kayıtlı değil. +Başkasının kullanmaması için lütfen, +www.hedgewars.org sitesinden kaydet. Your password wasn't saved either. - + + +Parolan da kaydedilmedi. Hedgewars - Empty nickname - + Hedgewars - Boş takma ad Hedgewars - Wrong password - + Hedgewars - Hatalı parola You entered a wrong password. - + Hatalı parola girdin. Try Again - + Tekrar Dene Hedgewars - Connection error - + Hedgewars - Bağlantı hatası You reconnected too fast. Please wait a few seconds and try again. - - - - This page requires an internet connection. - + Çok hızlı yeniden bağlandın. +Birkaç saniye bekle ve yeniden dene. @@ -403,103 +403,103 @@ Small tunnels - + Küçük tüneller Medium tunnels - + Orta tüneller Seed - + Besleme Map type: - + Harita türü: Image map - + Resim haritası Mission map - + Görev haritası Hand-drawn - + El çizimi Randomly generated - + Rastgele oluşturulmuş Random maze - + Rastgele labirent Random - Rastgele + Rastgele Map preview: - + Harita önizleme: Load map drawing - + Yerel harita çizimi Edit map drawing - + Harita çizimini düzenle Small islands - + Küçük adalar Medium islands - + Orta adalar Large islands - + Büyük adalar Map size: - + Harita boyutu: Maze style: - + Labirent biçemi: Mission: - + Görev: Map: - + Harita: + + + Theme: + Tema: Load drawn map - + Çizili harita yükle Drawn Maps - + Çizili Haritalar All files - + Tüm dosyalar Large tunnels - - - - Theme: %1 - + Büyük tüneller @@ -533,7 +533,7 @@ Quit reason: - Çıkma sebebi: + Çıkma sebebi: You got kicked @@ -541,82 +541,89 @@ %1 *** %2 has joined the room - + %1 *** %2 odaya katıldı + + + %1 *** %2 has joined + %1 *** %2 katıldı %1 *** %2 has left - + %1 *** %2 ayrıldı %1 *** %2 has left (%3) - + %1 *** %2 ayrıldı (%3) User quit - + Kullanıcı çıktı Remote host has closed connection - + Uzak sunucu bağlantıyı kapattı The server is too old. Disconnecting now. - + Sunucu çok eski. Bağlantı kesiliyor. HWPasswordDialog Login - + Oturum aç To connect to the server, please log in. If you don't have an account on www.hedgewars.org, just enter your nickname. - + Sunucuya bağlanmak için lütfen oturum aç. + +Eğer www.hedgewars.org adresinde bir hesabın yoksa, +sadece takma adını gir. Nickname: - + Takma ad: Password: - + Parola: HWUploadVideoDialog Upload video - + Video yükle Upload - + Yükle HatButton Change hat (%1) - + Şapkayı değiştir (%1) HatPrompt Cancel - İptal + İptal Use selected hat - + Seçili şapkayı kullan Search for a hat: - + Şapka ara: @@ -630,7 +637,7 @@ KeyBinder Category - + Kategori @@ -638,93 +645,94 @@ Duration: %1m %2s - + Süre: %1d %2s + Video: %1x%2, - + Video: %1x%2, %1 fps, - + %1 fps, Audio: - + Ses: unknown - + bilinmiyor MapModel No description available. - + Kullanılabilir açıklama yok. PageAdmin Clear Accounts Cache - + Hesap Belleğini Temizle Fetch data - + Veri getir Server message for latest version: - + Son sürüm için sunucu iletisi: Server message for previous versions: - + Önceki sürümler için sunucu iletisi: Latest version protocol number: - + En son sürüm protokol numarası: MOTD preview: - + MOTD önizleme: Set data - + Veri ayarla General - Genel + Genel Bans - + Engellemeler IP/Nick - + IP/Takma Ad Expiration - + Dolum Reason - + Sebep Refresh - + Yenile Add - + Ekle Remove - + Kaldır @@ -735,53 +743,42 @@ - PageDataDownload - - Loading, please wait. - - - - This page requires an internet connection. - - - - PageDrawMap Undo - + Geri al Clear - + Temizle Load - Yükle + Yükle Save - + Kaydet Load drawn map - + Çizili harita yükle Save drawn map - + Çizili haritayı kaydet Drawn Maps - + Çizili Haritalar All files - + Tüm dosyalar Eraser - + Silgi @@ -792,175 +789,167 @@ Select an action to choose a custom key bind for this team - + Bu takıma özel tuş ataması için bir eylem seçin Use my default - + Varsayılanı kullan Reset all binds - + Tüm atamaları sıfırla Custom Controls - + Özel Denetimler Hat - + Şapka Name - + İsim This hedgehog's name - + Bu kirpinin adı Randomize this hedgehog's name - + Kirpi adını rastgele ata Random Team - + Rastgele Takım PageGameStats Details - + Ayrıntılar Health graph - + Sağlık Grafiği Ranking - + Sıralama The best shot award was won by <b>%1</b> with <b>%2</b> pts. - + En iyi atış ödülü: <b>%2</b> puanla <b>%1</b> The best killer is <b>%1</b> with <b>%2</b> kills in a turn. - - + + En iyi öldürücü: <b>%1</b> bir turda <b>%2</b> öldürme. A total of <b>%1</b> hedgehog(s) were killed during this round. - - + + Bu turda toplam <b>%1</b> kirpi öldürüldü. (%1 kill) - - + + (%1 öldürme) <b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts. - - + + <b>%1</b> kendi kirpilerini <b>%2</b> puanla vurmanın güzel olduğunu düşündü <b>%1</b> killed <b>%2</b> of his own hedgehogs. - - + + <b>%1</b> kendi <b>%2</b> kirpisini öldürdü <b>%1</b> was scared and skipped turn <b>%2</b> times. - - + + <b>%1</b> korktu ve <b>%2</b> kez turu pas geçti. - - Play again - - - - Save - - PageInGame In game... - + Oyunda... PageInfo Open the snapshot folder - + Ekran görüntü klasörünü aç PageMain Downloadable Content - + İndirilebilir İçerik Play a game on a single computer - + Tek bir bilgisayarda oyna Play a game across a network - + Ağ üzerinde oyna Read about who is behind the Hedgewars Project - + Hedgewars Projesinin arkasında kimlerin olduğunu göster Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars - + Sorunları bildirme, özellik önerme veya Hedgewars oyununu ne kadar sevdiğini söylemek için geri bildirim bırak Access the user created content downloadable from our website - + Websitemizdeki kullanıcılar tarafından oluşturulmuş indirilebilir içeriğe bak Exit game - + Oyundan çık Manage videos recorded from game - + Oyunda kayıtlı videolarını yönet Edit game preferences - + Oyun tercihlerini düzenle Play a game across a local area network - + Yerel ağda bir oyun oyna Play a game on an official server - + Resmi bir sunucuda oyun oyna Feedback - + Geri Bildirim Play local network game - + Yerel ağ oyunu oyna Play official network game - + Resmi ağ oyunu oyna @@ -971,41 +960,37 @@ Edit game preferences - + Oyun tercihlerini düzenle PageNetGame Control - Kontrol + Denetim Edit game preferences - + Oyun tercihlerini düzenle Start - Başla + Başla Update - Güncelle + Güncelle Room controls - + Oda denetimleri PageNetServer - Click here for details - - - Insert your address here - + Adresi buraya girin @@ -1020,163 +1005,163 @@ Delete team - + Takımı sil You can't edit teams from team selection. Go back to main menu to add, edit or delete teams. - + Takım seçiminden takımları düzenleyemezsiniz. Takım eklemek, düzenlemek ve silmek için ana menüye dönün. New scheme - + Yeni plan Edit scheme - + Planı düzenle Delete scheme - + Planı sil New weapon set - + Yeni silah seti Edit weapon set - + Silah setini düzenle Delete weapon set - + Silah setini sil Advanced - Gelişmiş + Gelişmiş Reset to default colors - + Varsayılan renklere sıfırla Proxy host - + Vekil sunucusu Proxy port - + Vekil portu Proxy login - + Vekil kullanıcı adı Proxy password - + Vekil parolası No proxy - + Vekil sunucu yok Socks5 proxy - + Socks5 vekil sunucusu HTTP proxy - + HTTP vekil sunucusu System proxy settings - + Sistem vekil ayarları Select an action to change what key controls it - + Denetimi kullanan tuşu değiştirmek için bir eylem seçin Reset to default - + Varsayılana sıfırla Reset all binds - + Tüm atamaları sıfırla Game - + Oyun Graphics - + Grafik Audio - + Ses Controls - + Denetimler Video Recording - + Video Kaydı Network - + Teams - Takımlar + Takımlar Schemes - + Planlar Weapons - Silahlar + Silahlar Frontend - + Ön Uç Custom colors - + Özel renkler Game audio - + Oyun sesi Frontend audio - + Ön uç sesi Account - + Hesap Proxy settings - + Vekil sunucu ayarları Miscellaneous - + Çeşitli Updates - + Güncellemeler Check for updates - + Güncellemeleri Denetle Video recording options - + Video kayıt seçenekleri @@ -1206,41 +1191,41 @@ Rules: - + Kurallar: Weapons: - + Silahlar: %1 players online - - + + %1 oyuncu çevrimiçi Search for a room: - + Bir oda ara: Create room - + Oda oluştur Join room - + Odaya katıl Room state - + Oda durumu Clear filters - + Süzgeçleri temizle Open server administration page - + Sunucu yönetim sayfasını aç @@ -1251,7 +1236,7 @@ Teams will start on opposite sides of the terrain, two team colours max! - Takımlar bölgenin faklı taraflarında başlarlar, en fazla iki takım rengi! + Takımlar bölgenin farklı taraflarında başlarlar, en fazla iki takım rengi! Land can not be destroyed! @@ -1271,7 +1256,7 @@ Gain 80% of the damage you do back in health - Verdiğin hasarın %%80'ini sağlık olarak kazan + Verdiğin hasarın %80'ini sağlık olarak kazan Share your opponents pain, share their damage @@ -1299,63 +1284,63 @@ Order of play is random instead of in room order. - + Oda sırası yerine oynama sırası rastgeledir. Play with a King. If he dies, your side dies. - + Bir Kralla oyna. O ölürse takımın ölür. Take turns placing your hedgehogs before the start of play. - + Oyuna başlamadan önce kirpileri sırayla yerleştir. Ammo is shared between all teams that share a colour. - + Aynı rengi paylaşan tüm takımlar cephaneyi paylaşır. Disable girders when generating random maps. - + Rastgele haritalar oluştururken kirişleri devre dışı bırak. Disable land objects when generating random maps. - + Rastgele haritalar oluştururken zemin nesnelerini devre dışı bırak. AI respawns on death. - + Yapay zeka, öldükten sonra yeniden doğar. All (living) hedgehogs are fully restored at the end of turn - + Tüm (yaşayan) kirpiler tur sonunda eski haline gelir Attacking does not end your turn. - + Saldırmak sıranı bitirmez. Weapons are reset to starting values each turn. - + Silahlar her turda başlangıç değerlerine sıfırlanır. Each hedgehog has its own ammo. It does not share with the team. - + Her kirpinin kendi cephanesi olur. Takımla paylaşmaz. You will not have to worry about wind anymore. - + Artık rüzgarı dert etmen gerekmiyor. Wind will affect almost everything. - + Rüzgar neredeyse her şeyi etkiler. Copy - + Kopyala Teams in each clan take successive turns sharing their turn time. - + Her klandaki takımlar kendi sıralarındaki zamanı paylaşarak değişirler. Add an indestructible border around the terrain @@ -1363,14 +1348,14 @@ Add an indestructible border along the bottom - + Alta yok edilemez bir sınır ekle PageSelectWeapon Default - Öntanımlı + Varsayılan Delete @@ -1378,96 +1363,98 @@ New - Yeni + Yeni Copy - + Kopyala PageSinglePlayer Play a quick game against the computer with random settings - + Rastgele ayarlarla bilgisayara karşı hızlı bir oyun oyna Play a hotseat game against your friends, or AI teams - + Arkadaşlarınla veya Yapay Zeka takımlarıyla ayarlanmış bir oyun oyna Campaign Mode - + Mücadele Kipi Practice your skills in a range of training missions - + Yeteneklerini çeşitli eğitim görevleri ile geliştir Watch recorded demos - + Kayıtlı gösterileri izle Load a previously saved game - + Önceden kayıtlı bir oyun yükle PageTraining No description available - + Kullanılabilir açıklama yok Select a mission! - + Bir görev seç! Pick the mission or training to play - + Oynamak üzere bir görev veya eğitim seç Start fighting - + Dövüşe başla PageVideos Name - + İsim Size - + Boyut %1 bytes - - + + %1 bayt (in progress...) - + (yapım aşamasında...) encoding - + kodlanıyor uploading - + yükleniyor Date: %1 - + Tarih: %1 + Size: %1 - + Boyut: %1 + @@ -1494,23 +1481,23 @@ Follow - + Takip Et Ignore - + Yoksay Add friend - + Arkadaş ekle Unignore - + Yoksaymayı kapat Remove friend - + Arkadaş kaldır Update @@ -1518,15 +1505,15 @@ Restrict Unregistered Players Join - + Kayıtsız Oyuncuların Katılmasını Kısıtla Show games in lobby - + Lobideki oyunları göster Show games in-progress - + Süren oyunları göster @@ -1549,59 +1536,59 @@ Check for updates at startup - + Başlangıçta güncellemeleri denetle Show ammo menu tooltips - + Cephane menüsü araç ipuçlarını göster Save password - + Parolayı kaydet Save account name and password - + Hesap adı ve parolasını kaydet Video is private - + Video özel Record audio - + Sesi kaydet Use game resolution - + Oyun çözünürlüğünü kullan Visual effects - + Görsel efektler Sound - + Ses In-game sound effects - + Oyun ses efektleri Music - + Müzik In-game music - + Oyun içi müzik Frontend sound effects - + Ön uç ses efektleri Frontend music - + Ön uç müziği @@ -1612,79 +1599,79 @@ Level - Bilgisayar + Seviye (System default) - + (Sistem varsayılanı) Community - + Topluluk Any - + Herhangi Disabled - + Kapalı Red/Cyan - + Kırmızı/Camgöbeği Cyan/Red - + Camgöbeği/Kırmızı Red/Blue - + Kırmızı/Mavi Blue/Red - + Mavi/Kırmızı Red/Green - + Kırmızı/Yeşil Green/Red - + Yeşil/Kırmızı Side-by-side - + Yan yana Top-Bottom - + Üst-Alt Red/Cyan grayscale - + Kırmızı/Camgöbeği gri Cyan/Red grayscale - + Camgöbeği/Kırmızı gri Red/Blue grayscale - + Kırmızı/Mavi gri Blue/Red grayscale - + Mavi/Kırmızı gri Red/Green grayscale - + Kırmızı/Yeşil gri Green/Red grayscale - + Yeşil/Kırmızı gri @@ -1715,15 +1702,15 @@ Team Settings - + Takım ayarları Videos - + Videolar Description - + Açıklama @@ -1798,181 +1785,183 @@ % Dud Mines - + Sahte Mayın % Name - + İsim Type - + Tür Grave - + Mezar taşı Flag - + Bayrak Voice - + Ses Locale - + Dil Explosives - + Patlayıcılar Tip: - + İpucu: Quality - + Kalite % Health Crates - + Sağlık Sandık %'si Health in Crates - + Sandıklardaki Sağlık Sudden Death Water Rise - + Ani Ölüm Su Yükselmesi Sudden Death Health Decrease - + Ani Ölüm Sağlık Azaltması % Rope Length - + Halat Uzunluk %'si Stereo rendering - + Stereo hazırlama Style - + Biçem Scheme - + Plan % Get Away Time - + Uzakta Zamanı %'si There are videos that are currently being processed. Exiting now will abort them. Do you really want to quit? - + Şu anda işlenen videolar var. +Çıkmak bu işlemi sonlandıracak. +Gerçekten çıkmak istiyor musunuz? Please provide either the YouTube account name or the email address associated with the Google Account. - + Lütfen YouTube hesap adını veya Google Hesabınız ile ilişkilendirmiş e-posta adresini gir. Account name (or email): - + Hesap adı (veya e-posta): Password: - + Parola: Video title: - + Video başlığı: Video description: - + Video açıklaması: Tags (comma separated): - + Etiketler (virgülle ayrılmış): Description - + Açıklama Nickname - + Takma ad Format - + Biçim Audio codec - + Ses kodlayıcı Video codec - + Video kodlayıcı Framerate - + Kare oranı Bitrate (Kbps) - + Bit oranı (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! - + Bu geliştirme derlemesi 'yapım aşamasındadır' ve oyunun diğer sürümleri ile uyumlu olmayabilir; bazı özellikler bozuk veya tamamlanmamış olabilir! Fullscreen - Tam ekran + Tam ekran Fullscreen Resolution - + Tam Ekran Çözünürlüğü Windowed Resolution - + Pencere Çözünürlüğü Your Email - + E-postanız Summary - + Özet Send system information - + Sistem bilgisi gönder Type the security code: - + Güvenlik kodunu yaz: Revision - + Gözden Geçirme This program is distributed under the %1 - + Bu program %1 altında dağıtılmaktadır This setting will be effective at next restart. - + Bu ayar bir sonraki başlatmada etkin olacaktır. @@ -1983,11 +1972,11 @@ hedgehog %1 - + kirpi %1 anonymous - + anonim @@ -1998,7 +1987,7 @@ -r%1 (%2) - + -r%1 (%2) @@ -2013,220 +2002,248 @@ File association failed. - + Dosya ilişkilendirme başarısız. Error while authenticating at google.com: - + Google.com ile kimlik açma başarısız Login or password is incorrect - + Kullanıcı adı veya parolası yanlış Error while sending metadata to youtube.com: - + Youtube.com üst verisi gönderilirken hata Teams - Are you sure? - + Takımlar - Emin misin? Do you really want to delete the team '%1'? - + '%1' takımını gerçekten silmek istiyor musun? Cannot delete default scheme '%1'! - + Varsayılan '%1' planı silinemez Please select a record from the list - + Lütfen listeden bir kayıt seç Unable to start server - + Sunucu başlatılamadı Hedgewars - Error - + Hedgewars - Hata Hedgewars - Success - + Hedgewars - Başarılı All file associations have been set - + Tüm dosya ilişkilendirmeleri ayarlandı Cannot create directory %1 %1 dizini oluşturulamadı + Failed to open data directory: +%1 + +Please check your installation! + Veri dizini açılamadı: +%1 + +Lütfen kurulumunuzu denetleyin! + + + TCP - Error + TCP - Hata + + Unable to start the server: %1. Sunucu başlatılamadı: %1. + Unable to run engine at + Motor şurada başlatılamadı: + + + Error code: %1 + Hata kodu: %1 + + Video upload - Error - + Video yükleme - Hata Netgame - Error - + Ağ oyunu - Hata Please select a server from the list - + Lütfen listeden bir sunucu seç Please enter room name - Lütfen oda ismini girin + Lütfen oda ismini gir Record Play - Error - + Oyunu Kaydet - Hata Please select record from the list - Lütfen listeden kaydı seçin + Lütfen listeden kaydı seç Cannot rename to - + Adlandırma başarısız: Cannot delete file - + Dosya silinemedi: Room Name - Error - + Oda Adı - Hata Please select room from the list - Lütfen listeden bir oda seçin + Lütfen listeden bir oda seçin Room Name - Are you sure? - + Oda Adı - Emin misiniz? The game you are trying to join has started. Do you still want to join the room? - + Katılmaya çalıştığınız oyun başlamış. +Hala odaya katılmak istiyor musunuz? Schemes - Warning - + Planlar - Uyarı Schemes - Are you sure? - + Planlar - Emin misiniz? Do you really want to delete the game scheme '%1'? - + Gerçekten '%1' oyun planını silmek istiyor musunuz? Videos - Are you sure? - + Videolar - Emin misiniz? Do you really want to delete the video '%1'? - + Gerçekten '%1' videosunu silmek istiyor musunuz? Do you really want to remove %1 file(s)? - - + + Gerçekten %1 dosyayı kaldırmak istiyor musunuz? Do you really want to cancel uploading %1? - + Gerçekten %1 yüklemesini iptal etmek istiyor musunuz? File error - + Dosya hatası Cannot open '%1' for writing - + '%1' yazmak için açılamıyor Cannot open '%1' for reading - + '%1' okumak için açılamıyor Cannot use the ammo '%1'! - + '%1' cephanesi kullanılamıyor! Weapons - Warning - + Silahlar - Uyarı Cannot overwrite default weapon set '%1'! - + Varsayılan '%1' silah setinin üzerine yazılamaz! Cannot delete default weapon set '%1'! - + Varsayılan '%1' silah seti silinemez! Weapons - Are you sure? - + Silahlar - Emin misiniz? Do you really want to delete the weapon set '%1'? - + Gerçekten '%1' silah setini silmek istiyor musunuz? Hedgewars - Nick not registered - + Hedgewars - Takma ad kayıtlı değil System Information Preview - + Sistem Bilgi Önizlemesi Failed to generate captcha - + Captcha oluşturulamadı Failed to download captcha - + Captcha indirilemedi Please fill out all fields. Email is optional. - + Lütfen tüm alanları doldurun. E-posta isteğe bağlıdır. Hedgewars - Warning - + Hedgewars - Uyarı Hedgewars - Information - + Hedgewars - Bilgi + + + Hedgewars + Hedgewars Not all players are ready - + Tüm oyuncular hazır değil Are you sure you want to start this game? Not all players are ready. - + Oyunu başlatmak istiyor musunuz? +Tüm oyuncular hazır değil. QPushButton default - öntanımlı + varsayılan OK @@ -2278,220 +2295,221 @@ Associate file extensions - + Dosya uzantılarını ilişkilendir More info - + Daha fazla bilgi Set default options - + Varsayılan seçenekleri ayarla Open videos directory - + Video dizinini aç Play - + Oynat Upload to YouTube - + YouTube'a Yükle Cancel uploading - + Yüklemeyi iptal et Restore default coding parameters - + Varsayılan kodlama parametrelerini geri al Open the video directory in your system - + Sistemindeki video dizinini aç Play this video - + Bu videoyu oynat Delete this video - + Bu videoyu sil Upload this video to your Youtube account - + Bu videoyu Youtube hesabıma yükle Reset - + Sıfırla Set the default server port for Hedgewars - + Hedgewars için öntanımlı sunucu portu Invite your friends to your server in just 1 click! - - - - Click to copy your unique server URL to your clipboard. Send this link to your friends and they will be able to join you. - + Sadece 1 tık ile arkadaşlarını sunucuna davet et! + + + Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you. + Benzersiz sunucu adresini panoya kopyalamak için tıkla. Bu bağlantıyı arkadaşlarına gönder ve sana katılmalarını sağla. Start private server - + Özel sunucuyu başlat RoomNamePrompt Enter a name for your room. - + Oda için bir ad gir. Cancel - İptal + İptal Create room - + Oda oluştur RoomsListModel In progress - + Sürüyor Room Name - + Oda Adı C - + K T - + T Owner - + Sahip Map - Harita + Harita Rules - + Kurallar Weapons - Silahlar + Silahlar Random Map - + Rastgele Harita Random Maze - + Rastgele Labirent Hand-drawn - + El Çizimi SeedPrompt The map seed is the basis for all random values generated by the game. - + Harita beslemesi, oyun tarafından oluşturulan tüm rastgele değerler için bir tabandır. Cancel - İptal + İptal Set seed - + Besleme ayarla Close - + Kapat SelWeaponWidget Weapon set - + Silah seti Probabilities - + Olasılıklar Ammo in boxes - + Kutulardaki cephane Delays - + Gecikmeler new - yeni + yeni copy of - + kopya TCPBase Unable to start server at %1. - + %1 içinde sunucu başlatılamıyor Unable to run engine at %1 Error code: %2 - + %1 içinde motor çalıştırılamıyor +Hata kodu: %2 TeamSelWidget At least two teams are required to play! - + Oynamak için en az iki takım gerekli! TeamShowWidget %1's team - + %1 takımı ThemePrompt Cancel - İptal + İptal Search for a theme: - + Tema arayın: Use selected theme - + Seçili temayı kullan @@ -2618,7 +2636,7 @@ change mode - modu değiştir + kipi değiştir capture @@ -2630,164 +2648,164 @@ long jump - + uzun zıplama high jump - + yüksek zıplama zoom in - + yakınlaştırma zoom out - + uzaklaştırma reset zoom - + yakınlaştırmayı sıfırla slot 10 - slot 10 + slot 10 mute audio - + sesi kapat record - + kaydet hedgehog info - + kirpi bilgisi binds (categories) Movement - + Hareket Weapons - Silahlar + Silahlar Camera - + Kamera Miscellaneous - + Çeşitli binds (descriptions) Traverse gaps and obstacles by jumping: - + Boşluklardan ve engellerden zıplayarak kaçın: Fire your selected weapon or trigger an utility item: - + Seçili silahını ateşle veya bir yardımcı öge tetikle: Pick a weapon or a target location under the cursor: - + Bir silah seç veya imleç altında konum işaretle Switch your currently active hog (if possible): - + Geçerli kirpiyi değiştir (mümkünse): Pick a weapon or utility item: - + Bir silah veya yardımcı öge al: Set the timer on bombs and timed weapons: - + Bombalarda ve zamanlı silahlarda zamanlayıcıyı ayarla: Move the camera to the active hog: - + Kamerayı etkin kirpiye götür: Move the cursor or camera without using the mouse: - + Kamera veya imleci fare kullanmadan hareket ettir Modify the camera's zoom level: - + Kamera yakınlaştırma seviyesini değiştir: Talk to your team or all participants: - + Takımla veya tüm katılanlarla konuş Pause, continue or leave your game: - + Oyunu beklet, devam et veya oyundan ayrıl Modify the game's volume while playing: - + Oynarken oyunun sesini değiştir: Toggle fullscreen mode: - + Tam ekran kipini değiştir: Take a screenshot: - + Ekran görüntüsü al: Toggle labels above hedgehogs: - + Kirpilerin üzerindeki etiketleri aç/kapat Record video: - + Video kaydet: Hedgehog movement - + Kirpi hareketi binds (keys) Axis - + Eksen (Up) - + (Yukarı) (Down) - + (Aşağı) Hat - + Şapka (Left) - + (Sol) (Right) - + (Sağ) Button - + Düğme Keyboard - + Klavye Delete @@ -2795,283 +2813,398 @@ Mouse: Left button - + Fare: Sol düğme Mouse: Middle button - + Fare: Orta düğme Mouse: Right button - + Fare: Sağ düğme Mouse: Wheel up - + Fare: Tekerlek yukarı Mouse: Wheel down - + Fare: Tekerlek aşağı Backspace - + Backspace Tab - + Sekme Clear - + Temizle Return - + Enter Pause - + Pause Escape - + Escape Space - + Boşluk Numpad 0 - + Nümerik 0 Numpad 1 - + Nümerik 1 Numpad 2 - + Nümerik 2 Numpad 3 - + Nümerik 3 Numpad 4 - + Nümerik 4 Numpad 5 - + Nümerik 5 Numpad 6 - + Nümerik 6 Numpad 7 - + Nümerik 7 Numpad 8 - + Nümerik 8 Numpad 9 - + Nümerik 9 Numpad . - + Nümerik . Numpad / - + Nümerik / Numpad * - + Nümerik * Numpad - - + Nümerik - Numpad + - + Nümerik + Enter - + Enter Equals - + Eşittir Up - + Yukarı Down - + Aşağı Right - + Sağ Left - + Sol Insert - + Ekle Home - + Ev End - + Son Page up - + Sayfa yukarı Page down - + Sayfa aşağı Num lock - + Nümerik kilit Caps lock - + Büyük harf Scroll lock - + Kaydırma kilidi Right shift - + Sağ üst karakter Left shift - + Sol üst karakter Right ctrl - + Sağ kontrol Left ctrl - + Sol kontrol Right alt - + Sağ alt Left alt - + Sol alt Right meta - + Sağ meta Left meta - + Sol meta A button - + A düğmesi B button - + B düğmesi X button - + X düğmesi Y button - + Y düğmesi LB button - + LB düğmesi RB button - + RB düğmesi Back button - + Geri düğmesi Start button - + Start düğmesi Left stick - + Sol çubuk Right stick - + Sağ çubuk Left stick (Right) - + Sol çubuk (Sağ) Left stick (Left) - + Sol çubuk (Sol) Left stick (Down) - + Sol çubuk (Aşağı) Left stick (Up) - + Sol çubuk (Yukarı) Left trigger - + Sol tetik Right trigger - + Sağ tetik Right stick (Down) - + Sağ çubuk (Aşağı) Right stick (Up) - + Sağ çubuk (Yukarı) Right stick (Right) - + Sağ çubuk (Sağ) Right stick (Left) - + Sağ çubuk (Sol) DPad - + DPad + + + + server + + Not room master + Oda uzmanı değil + + + Corrupted hedgehogs info + Bozuk kirpi bilgisi + + + too many teams + çok fazla takım + + + too many hedgehogs + çok fazla kirpi + + + There's already a team with same name in the list + Listede aynı isimde başka bir takım var + + + round in progress + tur sürüyor + + + restricted + kısıtlı + + + REMOVE_TEAM: no such team + REMOVE_TEAM: böyle bir takım yok + + + Not team owner! + Takım sahibi değil! + + + Less than two clans! + İki klandan daha az! + + + Room with such name already exists + Oda adı zaten mevcut + + + Nickname already chosen + Takma ad zaten seçilmiş + + + Illegal nickname + Geçersiz takma ad + + + Protocol already known + Protokol zaten biliniyor + + + Bad number + Hatalı sayı + + + Nickname is already in use + Takma ad zaten kullanımda + + + No checker rights + Denetim hakları yok + + + Authentication failed + Kimlik doğrulama başarısız + + + 60 seconds cooldown after kick + Kovulduktan sonra 60 saniye sakinleşme + + + kicked + kovuldu + + + Ping timeout + Ping zaman aşımı + + + bye + hoşça kal + + + Illegal room name + Geçersiz oda adı + + + No such room + Böyle bir oda yok + + + Joining restricted + Katılma kısıtlı + + + Registered users only + Sadece kayıtlı kullanıcılar + + + You are banned in this room + Bu odadan engellendiniz + + + Empty config entry + Boş yapılandırma girdisi diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_uk.ts --- a/share/hedgewars/Data/Locale/hedgewars_uk.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_uk.ts Sat Jan 04 23:55:54 2014 +0400 @@ -158,6 +158,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -379,6 +386,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -643,7 +663,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf повернула помилку при виведенні тексту, найімовірніше через помилку у бібліотеці freetype2. Рекомендується оновити бібліотеку freetype2. + SDL_ttf повернула помилку при виведенні тексту, найімовірніше через помилку у бібліотеці freetype2. Рекомендується оновити бібліотеку freetype2. @@ -656,19 +676,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -676,6 +683,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -803,6 +822,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -921,6 +952,14 @@ Save Зберегти + + (%1 %2) + + + + + + PageInGame @@ -1242,11 +1281,11 @@ Rules: - Правила: + Правила: Weapons: - Зброя: + Зброя: Search: @@ -1281,10 +1320,6 @@ - Clear filters - - - Open server administration page @@ -1411,6 +1446,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1508,13 +1559,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1651,6 +1700,38 @@ 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 + + QComboBox @@ -1672,7 +1753,7 @@ Any - Усі + Усі In lobby @@ -1886,7 +1967,7 @@ Tip: - Порада: + Порада: Quality @@ -2030,6 +2111,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2052,10 +2145,6 @@ Hedgewars %1 Hedgewars %1 - - -r%1 (%2) - - QMessageBox @@ -2282,6 +2371,13 @@ + QObject + + No description available + + + + QPushButton default @@ -2418,6 +2514,10 @@ Create room + + set password + + RoomsListModel @@ -2465,6 +2565,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2532,13 +2636,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3133,4 +3230,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_zh_CN.ts --- a/share/hedgewars/Data/Locale/hedgewars_zh_CN.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_zh_CN.ts Sat Jan 04 23:55:54 2014 +0400 @@ -4,7 +4,7 @@ About - + Unknown Compiler @@ -20,12 +20,12 @@ AmmoSchemeModel - + new - + copy of @@ -97,7 +97,7 @@ DataManager - + Use Default @@ -184,6 +184,14 @@ + GameUIConfig + + + Guest + + + + HWApplication @@ -226,7 +234,7 @@ - + Scheme '%1' not supported @@ -323,27 +331,35 @@ HWForm - + + + + + Guest + + + + DefaultTeam - + %1's Team - + Game aborted - + Hedgewars - Nick registered - + This nick is registered, and you haven't specified a password. If this nick isn't yours, please register your own nick at www.hedgewars.org @@ -352,98 +368,109 @@ - + Your nickname is not registered. To prevent someone else from using it, please register it at www.hedgewars.org - + Your password wasn't saved either. - - Nickname - - - - - Someone already uses your nickname %1 on the server. -Please pick another nickname: - - - - - No nickname supplied. + Nickname - + Someone already uses your nickname %1 on the server. +Please pick another nickname: + + + + + + No nickname supplied. + + + + + Hedgewars - Empty nickname - + Hedgewars - Wrong password - + You entered a wrong password. - + + Room password + + + + + The room is protected with password. +Please, enter the password: + + + + Try Again - + Hedgewars - Connection error - + You reconnected too fast. Please wait a few seconds and try again. - + Hedgewars Demo File File Types - + Hedgewars Save File File Types - + Demo name - + Demo name: - + This page requires an internet connection. - - + + Cannot save record to file %1 无法录入文件 %1 @@ -451,13 +478,13 @@ HWGame - + en.txt zh_CN.txt - + Cannot open demofile %1 DEMO %1 打不开 @@ -465,158 +492,158 @@ HWMapContainer - + Small tunnels - + Medium tunnels - + Seed - - Map type: - - - - - Image map - - - - - Mission map - - - + Map type: + + + + + Image map + + + + + Mission map + + + + Hand-drawn - + Randomly generated - + Random maze - + Random - + Map preview: - + Load map drawing - + Edit map drawing - + All 全部 - + Small 小型 - + Medium 中型 - + Large 大型 - + Cavern 洞穴 - + Wacky 曲折 - + Large tunnels - + Small islands - + Medium islands - + Large islands - + Map size: - + Maze style: - + Mission: - + Map: - - + + Theme: %1 - + Load drawn map - + Drawn Maps - + All files @@ -647,53 +674,53 @@ - + Remote host has closed connection - + The host was not found. Please check the host name and port settings. 错误没找到这个主机。请检查主机名和端口设置。 - + Connection refused 连接被拒绝 - + The server is too old. Disconnecting now. - + %1 *** %2 has left - + %1 *** %2 has left (%3) - - + + %1 *** %2 has joined the room - + Quit reason: 退出原因: - + Room destroyed 房间损坏 - + You got kicked 被踢出 @@ -740,7 +767,7 @@ HatButton - + Change hat (%1) @@ -766,9 +793,8 @@ KB - SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf 返回错误-渲染文字失败,可能有关freetype2的bug。建议升级 freetype。 + SDL_ttf 返回错误-渲染文字失败,可能有关freetype2的bug。建议升级 freetype。 @@ -782,28 +808,27 @@ LibavInteraction - - Duration: %1m %2s - - - - - - Video: %1x%2, + + Duration: %1m %2s - %1 fps, + Video: %1x%2 - Audio: + %1 fps + Audio: + + + + unknown @@ -811,7 +836,7 @@ MapModel - + No description available. @@ -918,49 +943,64 @@ PageDrawMap - + Eraser - - Undo - - - - Clear - - - - - Load - 读取 + Undo + + Polyline + + + + + Rectangle + + + + + Ellipse + + + + + Clear + + + + + Load + 读取 + + + Save 保存 - + Load drawn map - - + + Drawn Maps - - + + All files - + Save drawn map @@ -1021,72 +1061,80 @@ PageGameStats - + Details - + + Health graph - + Ranking - - Play again - - - + Play again + + + + Save 保存 - + The best shot award was won by <b>%1</b> with <b>%2</b> pts. - + The best killer is <b>%1</b> with <b>%2</b> kills in a turn. - + A total of <b>%1</b> hedgehog(s) were killed during this round. - + (%1 kill) - + + (%1 %2) + + + + + + <b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts. - + <b>%1</b> killed <b>%2</b> of his own hedgehogs. - + <b>%1</b> was scared and skipped turn <b>%2</b> times. @@ -1354,97 +1402,97 @@ - + Frontend - + Custom colors - + Reset to default colors - + Game audio - + Frontend audio - - Account - - - - - Proxy settings - - - - - Proxy host - - - + Account + + + + + Proxy settings + + + + + Proxy host + + + + Proxy port - + Proxy login - + Proxy password - + No proxy - + System proxy settings - + Socks5 proxy - + HTTP proxy - + Miscellaneous - + Updates - + Check for updates - + Video recording options @@ -1485,22 +1533,7 @@ - - Rules: - - - - - Weapons: - - - - - Clear filters - - - - + Open server administration page @@ -1513,14 +1546,14 @@ 加入 - + %1 players online - + Admin features 管理员功能 @@ -1663,17 +1696,37 @@ - + + None (Default) + + + + + Wrap (World wraps) + + + + + Bounce (Edges reflect) + + + + + Sea (Edges connect to sea) + + + + Copy - + New 新游戏 - + Delete 删除 @@ -1783,14 +1836,12 @@ - Date: %1 - + Date: %1 - Size: %1 - + Size: %1 @@ -1847,23 +1898,23 @@ - + Ignore - + Add friend - + Unignore - + Remove friend @@ -1881,7 +1932,7 @@ QCheckBox - + Fullscreen 游戏全屏幕 @@ -1896,44 +1947,84 @@ 另一种伤害显示方式 - + + Team + + + + + Enable team tags by default + + + + + Hog + + + + + Enable hedgehog tags by default + + + + + Health + + + + + Enable health tags by default + + + + + Translucent + + + + + Enable translucent tags by default + + + + Visual effects - - + + Sound - + In-game sound effects - - + + Music - + In-game music - + Frontend sound effects - + Frontend music - + Check for updates at startup @@ -1943,13 +2034,13 @@ - + Append date and time to record file name 记录名称中包含具体时间日期 - + Save password @@ -1964,12 +2055,12 @@ - + Record audio - + Use game resolution @@ -1982,7 +2073,7 @@ 玩家 - + Community @@ -1992,7 +2083,7 @@ Lv 级别 - + (System default) @@ -2071,12 +2162,6 @@ Green/Red grayscale - - - - Any - - QGroupBox @@ -2129,22 +2214,27 @@ QLabel - + Locale - + Nickname - + + Displayed tags above hogs and translucent tags + + + + This setting will be effective at next restart. - + Resolution 分辨率 @@ -2179,12 +2269,12 @@ FPS 上限 - + Revision - + This program is distributed under the %1 @@ -2218,7 +2308,7 @@ 版本 - + Initial sound volume 初始音量 @@ -2294,6 +2384,11 @@ + World Edge + + + + Scheme Name: 设置名称: @@ -2390,37 +2485,37 @@ - - Tip: - - - 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! - + + Tip: %1 + + + + Format - + Audio codec - + Video codec - + Framerate - + Bitrate (Kbps) @@ -2438,18 +2533,18 @@ QLineEdit - + unnamed 无名 - + hedgehog %1 - + anonymous @@ -2461,111 +2556,106 @@ Hedgewars %1 刺猬大作战 %1 - - - -r%1 (%2) - - QMessageBox - + Error 错误 - + Cannot use the ammo '%1'! - + Teams - Are you sure? - + Do you really want to delete the team '%1'? - - + + Cannot delete default scheme '%1'! - + Please select a record from the list - + Hedgewars - Nick not registered - + Unable to start server - + Connection to server is lost 服务器连接丢失 - + Not all players are ready - + Are you sure you want to start this game? Not all players are ready. - + Hedgewars - Error - + System Information Preview - - + + Failed to generate captcha - + Failed to download captcha - + Please fill out all fields. Email is optional. - - + + Hedgewars - Success - + All file associations have been set - + File association failed. @@ -2633,38 +2723,38 @@ - + Room Name - Error - + Please select room from the list - + 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'? @@ -2693,20 +2783,20 @@ - - - + + + File error - + Cannot open '%1' for writing - - + + Cannot open '%1' for reading @@ -2748,6 +2838,15 @@ + QObject + + + + No description available + + + + QPushButton @@ -2761,7 +2860,7 @@ 连接 - + Go! 上场! @@ -2850,17 +2949,17 @@ - + Associate file extensions - + Set default options - + Restore default coding parameters @@ -2910,17 +3009,22 @@ RoomNamePrompt - + Enter a name for your room. - + + set password + + + + Cancel 取消 - + Create room @@ -2959,26 +3063,31 @@ - Rules + Script + Rules + + + + Weapons 武器 - - Random Map - - - - Random Maze + Random Map + Random Maze + + + + Hand-drawn @@ -3044,12 +3153,12 @@ TCPBase - + Unable to start server at %1. - + Unable to run engine at %1 Error code: %2 @@ -3064,14 +3173,6 @@ - TeamShowWidget - - - %1's team - - - - ThemePrompt @@ -3775,7 +3876,7 @@ - + Keyboard @@ -3817,4 +3918,157 @@ + + 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 + + + + + kicked + + + + + Ping timeout + + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/hedgewars_zh_TW.ts --- a/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts Sat Jan 04 23:55:54 2014 +0400 @@ -152,6 +152,13 @@ + GameUIConfig + + Guest + + + + HWApplication %1 minutes @@ -363,6 +370,19 @@ This page requires an internet connection. + + Guest + + + + Room password + + + + The room is protected with password. +Please, enter the password: + + HWGame @@ -627,7 +647,7 @@ KB SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib. - SDL_ttf 返回錯誤-渲染文字失敗,可能有關freetype2的bug。建議升級 freetype。 + SDL_ttf 返回錯誤-渲染文字失敗,可能有關freetype2的bug。建議升級 freetype。 @@ -640,19 +660,6 @@ LibavInteraction - Duration: %1m %2s - - - - - Video: %1x%2, - - - - %1 fps, - - - Audio: @@ -660,6 +667,18 @@ unknown + + Duration: %1m %2s + + + + Video: %1x%2 + + + + %1 fps + + MapModel @@ -787,6 +806,18 @@ Eraser + + Polyline + + + + Rectangle + + + + Ellipse + + PageEditTeam @@ -893,6 +924,12 @@ Save + + (%1 %2) + + + + PageInGame @@ -1213,14 +1250,6 @@ 房間名: - Rules: - - - - Weapons: - - - Clear 清除 @@ -1247,10 +1276,6 @@ - Clear filters - - - Open server administration page @@ -1377,6 +1402,22 @@ Add an indestructible border along the bottom + + None (Default) + + + + Wrap (World wraps) + + + + Bounce (Edges reflect) + + + + Sea (Edges connect to sea) + + PageSelectWeapon @@ -1472,13 +1513,11 @@ - Date: %1 - - - - - Size: %1 - + Date: %1 + + + + Size: %1 @@ -1615,6 +1654,38 @@ 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 + + QComboBox @@ -1635,10 +1706,6 @@ - Any - - - Disabled @@ -1841,10 +1908,6 @@ - Tip: - - - Quality @@ -1986,6 +2049,18 @@ This setting will be effective at next restart. + + Tip: %1 + + + + Displayed tags above hogs and translucent tags + + + + World Edge + + QLineEdit @@ -2008,10 +2083,6 @@ Hedgewars %1 刺蝟大作戰 %1 - - -r%1 (%2) - - QMessageBox @@ -2235,6 +2306,13 @@ + QObject + + No description available + + + + QPushButton Play demo @@ -2371,6 +2449,10 @@ Create room + + set password + + RoomsListModel @@ -2418,6 +2500,10 @@ Hand-drawn + + Script + + SeedPrompt @@ -2485,13 +2571,6 @@ - TeamShowWidget - - %1's team - - - - ThemePrompt Cancel @@ -3086,4 +3165,127 @@ + + 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 + + + + kicked + + + + Ping timeout + + + + 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 + + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/missions_de.txt --- a/share/hedgewars/Data/Locale/missions_de.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/missions_de.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,23 +1,29 @@ -Basic_Training_-_Bazooka.name=Training: Bazooka - Grundlagen +Basic_Training_-_Bazooka.name=Grundlagentraining: Bazooka Basic_Training_-_Bazooka.desc="Nutze den Wind zu deinem Vorteil aus!" -Basic_Training_-_Grenade.name=Training: Granate - Grundlagen +Basic_Training_-_Grenade.name=Grundlagentraining: Granate Basic_Training_-_Grenade.desc="Vergiss nicht: Stift ziehen UND werfen!" -Basic_Training_-_Shotgun.name=Training: Schrotflinte - Grundlagen +Basic_Training_-_Shotgun.name=Grundlagentraining: Schrotflinte Basic_Training_-_Shotgun.desc="Zuerst schießen, dann fragen!" -Basic_Training_-_Sniper_Rifle.name=Training: Scharfschützengewehr - Grundlagen -Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!" +Basic_Training_-_Sniper_Rifle.name=Grundlagentraining: Scharfschützengewehr +Basic_Training_-_Sniper_Rifle.desc="Peng, Kopfschuss!" + +Basic_Training_-_Cluster_Bomb.name=Grundlagentraining: Splittergranate +Basic_Training_-_Cluster_Bomb.desc="Jemand braucht eine heiße Dusche!" -User_Mission_-_Dangerous_Ducklings.name=Mission: Dangerous Ducklings -User_Mission_-_Dangerous_Ducklings.desc="Nun gut, Rekrut! Es ist Zeit, dass du das im Grundlagentraining gelernte in die Tag umsetzt!" +Basic_Training_-_Rope.name=Grundlagentraining: Seil +Basic_Training_-_Rope.desc="Raus da und schwing!" + +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!" User_Mission_-_Diver.name=Mission: Taucher -User_Mission_-_Diver.desc="Diese amphibische Angriffstrategie ist schwieriger als sie aussieht." +User_Mission_-_Diver.desc="Diese amphibische Angriffstrategie ist schwieriger, als sie aussieht." User_Mission_-_Teamwork.name=Mission: Teamwork -User_Mission_-_Teamwork.desc="Ab und zu... tut Liebe weh." +User_Mission_-_Teamwork.desc="Ab und zu … tut Liebe weh." User_Mission_-_Spooky_Tree.name=Mission: Spukiger Baum User_Mission_-_Spooky_Tree.desc="Viele Kisten hier draußen. Ich hoffe jedenfalls, dass dieser Vogel hier nicht hungrig wird." @@ -26,7 +32,22 @@ User_Mission_-_Bamboo_Thicket.desc="Tod von oben." User_Mission_-_That_Sinking_Feeling.name=Mission: That Sinking Feeling -User_Mission_-_That_Sinking_Feeling.desc="Hier steht einen das Wasser ganz schön schnell bis zu Hals. Viele sind hieran gescheitert. Kannst du alle Igel retten?" +User_Mission_-_That_Sinking_Feeling.desc="Hier steht einen das Wasser ganz schön schnell bis zum Halse. Viele sind hieran gescheitert. Kannst du alle Igel retten?" User_Mission_-_Newton_and_the_Hammock.name=Mission: Newton und die Hängematte -User_Mission_-_Newton_and_the_Hammock.desc="Nicht vergessen Igelinge: Die Geschwindigkeit eines Körpers bleibt konstant, es sei denn es wirkt eine äußere Kraft wird auf ihn ein!" +User_Mission_-_Newton_and_the_Hammock.desc="Nicht vergessen, Igelinge: Die Geschwindigkeit eines Körpers bleibt konstant, es sei denn, es wirkt eine äußere Kraft auf ihn ein!" + +User_Mission_-_The_Great_Escape.name=Mission: Gesprengte Ketten +User_Mission_-_The_Great_Escape.desc="Glaubst du, dass du mich einsperren könnest?" + +User_Mission_-_Rope_Knock_Challenge.name=Herausforderung: Seilschubsen +User_Mission_-_Rope_Knock_Challenge.desc="Sieh! Hinter dir!" + +User_Mission_-_Nobody_Laugh.name=Mission: Niemand darf lachen +User_Mission_-_Nobody_Laugh.desc="Das ist kein Witz!" + +User_Mission_-_RCPlane_Challenge.name=Herausforderung: Funkflugzeug +User_Mission_-_RCPlane_Challenge.desc="Bist wohl ziemlich eingebildet, was, Flieger?" + +portal.name=Mission: Knifflige Portalherausforderung +portal.desc="Benutze das Portalgerät, um dich schnell und weit zu bewegen; benutze es zum Töten; benutze es mit Vorsicht!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/missions_el.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/missions_el.txt Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,53 @@ +Basic_Training_-_Bazooka.name=Βασική Εκπαίδευση Μπαζούκα +Basic_Training_-_Bazooka.desc="Το κλειδί είναι να χρησιμοποιήσεις τον άνεμο προς όφελός σου!" + +Basic_Training_-_Grenade.name=Βασική Εκπαίδευση Χειροβομβίδας +Basic_Training_-_Grenade.desc="Θυμίσου, τραβάς την περόνη ΚΑΙ πετάς!" + +Basic_Training_-_Cluster_Bomb.name=Βασική Εκπαίδευση Βόμβας Θραυσμάτων +Basic_Training_-_Cluster_Bomb.desc="Κάποιος χρειάζεται ένα καυτό ντουζ!" + +Basic_Training_-_Shotgun.name=Βασική Εκπαίδευση Καραμπίνας +Basic_Training_-_Shotgun.desc="Πυροβόλα πρώτα, ρώτα μετά!" + +Basic_Training_-_Sniper_Rifle.name=Βασική Εκπαίδευση Ελεύθερου Σκοπευτή +Basic_Training_-_Sniper_Rifle.desc="Μπαμ, χτύπημα στο κεφάλι!" + +Basic_Training_-_Rope.name=Βασική Εκπαίδευση Σκοινιού +Basic_Training_-_Rope.desc="Τράβα εκεί έξω και κουνίσου!" + +User_Mission_-_Dangerous_Ducklings.name=Αποστολή: Επικίνδυνα Παπιά +User_Mission_-_Dangerous_Ducklings.desc="Λοιπόν, στραβάδι! Καιρός να θέσουμε ό,τι μάθαμε στη Βασική Εκπαίδευση σε εφαρμογή!" + +User_Mission_-_Diver.name=Αποστολή: Δύτης +User_Mission_-_Diver.desc="Αυτή η 'αμφίβια εισβολή' είναι πιο δύσκολη απ'ότι φαίνεται..." + +User_Mission_-_Teamwork.name=Αποστολή: Ομαδική Δουλειά +User_Mission_-_Teamwork.desc="Μερικές φορές, η αγάπη πονάει." + +User_Mission_-_Spooky_Tree.name=Αποστολή: Τρομακτικό Δέντρο +User_Mission_-_Spooky_Tree.desc="Πολλά κιβώτια εκεί έξω. Ελπίζω αυτό το πτηνό να μην αισθάνεται πεινασμένο." + +User_Mission_-_Bamboo_Thicket.name=Αποστολή: Θάμνος από Bamboo +User_Mission_-_Bamboo_Thicket.desc="Ο θάνατος έρχεται από κάτω." + +User_Mission_-_That_Sinking_Feeling.name=Αποστολή: Αυτό το Αίσθημα ότι Βουλιάζεις +User_Mission_-_That_Sinking_Feeling.desc="Η στάθμη του νερού ανεβαίνει απότομα και ο χρόνος είναι περιορισμένος. Πολλοί προσπάθησαν και απέτυχαν. Μπορείς να τους σώσεις όλους;" + +User_Mission_-_Newton_and_the_Hammock.name=Αποστολή: ο Νεύτωνας και η Αιώρα +User_Mission_-_Newton_and_the_Hammock.desc="Θυμηθείτε σκαντζοχοίρια: Η ταχύτητα ενός σώματος παραμένει σταθερή εκτός εάν ασκηθεί στο σώμα κάποια εξωτερική δύναμη!" + +User_Mission_-_The_Great_Escape.name=Αποστολή: Η Μεγάλη Απόδραση +User_Mission_-_The_Great_Escape.desc="Νομίζεις ότι μπορείς να με φυλακίσεις!;" + +User_Mission_-_Rope_Knock_Challenge.name=Πρόκληση: Χτύπημα με Σκοινί +User_Mission_-_Rope_Knock_Challenge.desc="Κοίτα πίσω σου!" + +User_Mission_-_Nobody_Laugh.name=Αποστολή: Μη Γελάσει Κανείς +User_Mission_-_Nobody_Laugh.desc="Αυτό δεν είναι αστείο." + +User_Mission_-_RCPlane_Challenge.name=Πρόκληση: Τηλεκατευθυνόμενο Αεροπλάνο +User_Mission_-_RCPlane_Challenge.desc="Νοιώθεις πολύ σίγουρος, ε, πιλότε;" + +portal.name=Αποστολή: Σπαζοκεφαλιά με Πύλες(Portals) +portal.desc="Χρησιμοποίησε την πύλη για να μετακινηθείς γρήγορα και μακριά, χρησιμοποιησέ την για να σκοτώσεις, χρησιμοποιησέ την με προσοχή!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/missions_en.txt --- a/share/hedgewars/Data/Locale/missions_en.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/missions_en.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,53 +1,53 @@ -Basic_Training_-_Bazooka.name=Basic Bazooka Training -Basic_Training_-_Bazooka.desc="Using the wind to your advantage is key!" - -Basic_Training_-_Grenade.name=Basic Grenade Training -Basic_Training_-_Grenade.desc="Remember, you pull the pin out AND throw!" - -Basic_Training_-_Cluster_Bomb.name=Basic Cluster Bomb Training -Basic_Training_-_Cluster_Bomb.desc="Someone needs hot shower!" - -Basic_Training_-_Shotgun.name=Basic Shotgun Training -Basic_Training_-_Shotgun.desc="Shoot first, ask questions later!" - -Basic_Training_-_Sniper_Rifle.name=Basic Sniper Rifle Training -Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!" - -Basic_Training_-_Rope.name=Basic Rope Training -Basic_Training_-_Rope.desc="Get out there and swing!" - -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!" - -User_Mission_-_Diver.name=Mission: Diver -User_Mission_-_Diver.desc="This 'amphibious assault' thing is harder than it looks..." - -User_Mission_-_Teamwork.name=Mission: Teamwork -User_Mission_-_Teamwork.desc="Sometimes, love hurts." - -User_Mission_-_Spooky_Tree.name=Mission: Spooky Tree -User_Mission_-_Spooky_Tree.desc="Lots of crates out here. I sure hope that bird ain't feeling hungry." - -User_Mission_-_Bamboo_Thicket.name=Mission: Bamboo Thicket -User_Mission_-_Bamboo_Thicket.desc="Death comes from above." - -User_Mission_-_That_Sinking_Feeling.name=Mission: That Sinking Feeling -User_Mission_-_That_Sinking_Feeling.desc="The water is rising rapidly and time is limited. Many have tried and failed. Can you save them all?" - -User_Mission_-_Newton_and_the_Hammock.name=Mission: Newton and the Hammock -User_Mission_-_Newton_and_the_Hammock.desc="Remember hoglets: The velocity of a body remains constant unless the body is acted upon by an external force!" - -User_Mission_-_The_Great_Escape.name=Mission: The Great Escape -User_Mission_-_The_Great_Escape.desc="You think you can cage me!?" - -User_Mission_-_Rope_Knock_Challenge.name=Challenge: Rope Knocking -User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!" - -User_Mission_-_Nobody_Laugh.name=Mission: Nobody Laugh -User_Mission_-_Nobody_Laugh.desc="This ain't no joke." - -User_Mission_-_RCPlane_Challenge.name=Challenge: RC Plane -User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?" - -portal.name=Mission: Portal Mind Challenge -portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!" +Basic_Training_-_Bazooka.name=Basic Bazooka Training +Basic_Training_-_Bazooka.desc="Using the wind to your advantage is key!" + +Basic_Training_-_Grenade.name=Basic Grenade Training +Basic_Training_-_Grenade.desc="Remember, you pull the pin out AND throw!" + +Basic_Training_-_Cluster_Bomb.name=Basic Cluster Bomb Training +Basic_Training_-_Cluster_Bomb.desc="Someone needs hot shower!" + +Basic_Training_-_Shotgun.name=Basic Shotgun Training +Basic_Training_-_Shotgun.desc="Shoot first, ask questions later!" + +Basic_Training_-_Sniper_Rifle.name=Basic Sniper Rifle Training +Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!" + +Basic_Training_-_Rope.name=Basic Rope Training +Basic_Training_-_Rope.desc="Get out there and swing!" + +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!" + +User_Mission_-_Diver.name=Mission: Diver +User_Mission_-_Diver.desc="This 'amphibious assault' thing is harder than it looks..." + +User_Mission_-_Teamwork.name=Mission: Teamwork +User_Mission_-_Teamwork.desc="Sometimes, love hurts." + +User_Mission_-_Spooky_Tree.name=Mission: Spooky Tree +User_Mission_-_Spooky_Tree.desc="Lots of crates out here. I sure hope that bird ain't feeling hungry." + +User_Mission_-_Bamboo_Thicket.name=Mission: Bamboo Thicket +User_Mission_-_Bamboo_Thicket.desc="Death comes from above." + +User_Mission_-_That_Sinking_Feeling.name=Mission: That Sinking Feeling +User_Mission_-_That_Sinking_Feeling.desc="The water is rising rapidly and time is limited. Many have tried and failed. Can you save them all?" + +User_Mission_-_Newton_and_the_Hammock.name=Mission: Newton and the Hammock +User_Mission_-_Newton_and_the_Hammock.desc="Remember hoglets: The velocity of a body remains constant unless the body is acted upon by an external force!" + +User_Mission_-_The_Great_Escape.name=Mission: The Great Escape +User_Mission_-_The_Great_Escape.desc="You think you can cage me!?" + +User_Mission_-_Rope_Knock_Challenge.name=Challenge: Rope Knocking +User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!" + +User_Mission_-_Nobody_Laugh.name=Mission: Nobody Laugh +User_Mission_-_Nobody_Laugh.desc="This ain't no joke." + +User_Mission_-_RCPlane_Challenge.name=Challenge: RC Plane +User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?" + +portal.name=Mission: Portal Mind Challenge +portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/missions_pt.txt --- a/share/hedgewars/Data/Locale/missions_pt.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/missions_pt.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,50 +1,50 @@ -Basic_Training_-_Bazooka.name=Treino Básico com Bazuca -Basic_Training_-_Bazooka.desc="Saber utilizar o vento para tua vantagem é a chave!" - -Basic_Training_-_Grenade.name=Treino Básico com Granada -Basic_Training_-_Grenade.desc="Lembra-te, tens de retirar a cavilha E ATIRAR!" - -Basic_Training_-_Cluster_Bomb.name=Treino Básico com Bomba de Fragmentos -Basic_Training_-_Cluster_Bomb.desc="Alguem está a precisar de um duche bem quente!" - -Basic_Training_-_Shotgun.name=Treino Básico com Caçadeira -Basic_Training_-_Shotgun.desc="Dispara primeiro, questiona depois!" - -Basic_Training_-_Sniper_Rifle.name=Treino Básico com Sniper -Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!" - -Basic_Training_-_Rope.name=Treino Básico com Corda -Basic_Training_-_Rope.desc="Get out there and swing!" - -User_Mission_-_Dangerous_Ducklings.name=Missão: Dangerous Ducklings -User_Mission_-_Dangerous_Ducklings.desc="Alright, rookie! Time to put what we learned in Basic Training into practice!" - -User_Mission_-_Diver.name=Missão: Diver -User_Mission_-_Diver.desc="Esta coisa do 'assalto anfíbio' é mais difícil do que parece..." - -User_Mission_-_Teamwork.name=Missão: Teamwork -User_Mission_-_Teamwork.desc="Por vezes, o amor doi." - -User_Mission_-_Spooky_Tree.name=Missão: Spooky Tree -User_Mission_-_Spooky_Tree.desc="Imensas caixas por todo o lado. Só espero que este pássaro não se esteja a sentir com fome." - -User_Mission_-_Bamboo_Thicket.name=Missão: Bamboo Thicket -User_Mission_-_Bamboo_Thicket.desc="Death comes from above." - -User_Mission_-_That_Sinking_Feeling.name=Missão: That Sinking Feeling -User_Mission_-_That_Sinking_Feeling.desc="A água está a subir rapidamente e o tempo é limitado. Muitos tentaram e falharam. Consegues salvá-los todos?" - -User_Mission_-_Newton_and_the_Hammock.name=Missão: Newton and the Hammock -User_Mission_-_Newton_and_the_Hammock.desc="Remember hoglets: The velocity of a body remains constant unless the body is acted upon by an external force!" - -User_Mission_-_The_Great_Escape.name=Missão: The Great Escape -User_Mission_-_The_Great_Escape.desc="Pensas que me consegues enjaular!?" - -User_Mission_-_Rope_Knock_Challenge.name=Desafio: Rope Knocking -User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!" - -User_Mission_-_RCPlane_Challenge.name=Desafio: Avião Telecomandado -User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?" - -portal.name=Missão: Treino com Portais -portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!" +Basic_Training_-_Bazooka.name=Treino Básico com Bazuca +Basic_Training_-_Bazooka.desc="Saber utilizar o vento para tua vantagem é a chave!" + +Basic_Training_-_Grenade.name=Treino Básico com Granada +Basic_Training_-_Grenade.desc="Lembra-te, tens de retirar a cavilha E ATIRAR!" + +Basic_Training_-_Cluster_Bomb.name=Treino Básico com Bomba de Fragmentos +Basic_Training_-_Cluster_Bomb.desc="Alguem está a precisar de um duche bem quente!" + +Basic_Training_-_Shotgun.name=Treino Básico com Caçadeira +Basic_Training_-_Shotgun.desc="Dispara primeiro, questiona depois!" + +Basic_Training_-_Sniper_Rifle.name=Treino Básico com Sniper +Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!" + +Basic_Training_-_Rope.name=Treino Básico com Corda +Basic_Training_-_Rope.desc="Get out there and swing!" + +User_Mission_-_Dangerous_Ducklings.name=Missão: Dangerous Ducklings +User_Mission_-_Dangerous_Ducklings.desc="Alright, rookie! Time to put what we learned in Basic Training into practice!" + +User_Mission_-_Diver.name=Missão: Diver +User_Mission_-_Diver.desc="Esta coisa do 'assalto anfíbio' é mais difícil do que parece..." + +User_Mission_-_Teamwork.name=Missão: Teamwork +User_Mission_-_Teamwork.desc="Por vezes, o amor doi." + +User_Mission_-_Spooky_Tree.name=Missão: Spooky Tree +User_Mission_-_Spooky_Tree.desc="Imensas caixas por todo o lado. Só espero que este pássaro não se esteja a sentir com fome." + +User_Mission_-_Bamboo_Thicket.name=Missão: Bamboo Thicket +User_Mission_-_Bamboo_Thicket.desc="Death comes from above." + +User_Mission_-_That_Sinking_Feeling.name=Missão: That Sinking Feeling +User_Mission_-_That_Sinking_Feeling.desc="A água está a subir rapidamente e o tempo é limitado. Muitos tentaram e falharam. Consegues salvá-los todos?" + +User_Mission_-_Newton_and_the_Hammock.name=Missão: Newton and the Hammock +User_Mission_-_Newton_and_the_Hammock.desc="Remember hoglets: The velocity of a body remains constant unless the body is acted upon by an external force!" + +User_Mission_-_The_Great_Escape.name=Missão: The Great Escape +User_Mission_-_The_Great_Escape.desc="Pensas que me consegues enjaular!?" + +User_Mission_-_Rope_Knock_Challenge.name=Desafio: Rope Knocking +User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!" + +User_Mission_-_RCPlane_Challenge.name=Desafio: Avião Telecomandado +User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?" + +portal.name=Missão: Treino com Portais +portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/missions_pt_BR.txt --- a/share/hedgewars/Data/Locale/missions_pt_BR.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/missions_pt_BR.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,53 +1,53 @@ -Basic_Training_-_Bazooka.name=Treino básico de bazuca -Basic_Training_-_Bazooka.desc="O segredo é usar o vento ao seu favor!" - -Basic_Training_-_Grenade.name=Treino básico de granada -Basic_Training_-_Grenade.desc="Lembre, você tira o pino E arremessa!" - -Basic_Training_-_Cluster_Bomb.name=Treino básico de bomba de estilhaço -Basic_Training_-_Cluster_Bomb.desc="Alguém está precisando de um banho quente!" - -Basic_Training_-_Shotgun.name=Treino básico de escopeta -Basic_Training_-_Shotgun.desc="Atire primeiro, pergunte depois!" - -Basic_Training_-_Sniper_Rifle.name=Treino básico de Rifle Sniper -Basic_Training_-_Sniper_Rifle.desc="Bum! Na cabeça!" - -Basic_Training_-_Rope.name=Treino básico de corda -Basic_Training_-_Rope.desc="Saia daí e balance!" - -User_Mission_-_Dangerous_Ducklings.name=Missão: Patinhos perigosos -User_Mission_-_Dangerous_Ducklings.desc="Certo, recruta! Hora de colocar em prática o que aprendeu nos Treinos Básicos!" - -User_Mission_-_Diver.name=Missão: Mergulhador -User_Mission_-_Diver.desc="Essa coisa de 'investida anfíbio' é mais difícil do que parece..." - -User_Mission_-_Teamwork.name=Missão: Trabalho em equipe -User_Mission_-_Teamwork.desc="Às vezes, o amor doi." - -User_Mission_-_Spooky_Tree.name=Missão: Árvore medonha -User_Mission_-_Spooky_Tree.desc="Muitas caixas por aqui. Só espero que aquele pássaro não esteja com fome." - -User_Mission_-_Bamboo_Thicket.name=Missão: Floresta de bambus -User_Mission_-_Bamboo_Thicket.desc="A morte vem de cima." - -User_Mission_-_That_Sinking_Feeling.name=Missão: Aquela sensação de afundar -User_Mission_-_That_Sinking_Feeling.desc="A água está subindo rapidamente e o tempo é contado. Muitos tentaram, muitos falharam. Consegue salvar todos?" - -User_Mission_-_Newton_and_the_Hammock.name=Missão: Newton e a rede -User_Mission_-_Newton_and_the_Hammock.desc="Lembrem-se, ouriçozinhos: A velocidade de um corpo permanece constante a menos que aja sobre ele uma força externa!" - -User_Mission_-_The_Great_Escape.name=Missão: A grande fuga -User_Mission_-_The_Great_Escape.desc="Está pensando que consegue me prender!?" - -User_Mission_-_Rope_Knock_Challenge.name=Challenge: Corda que doi -User_Mission_-_Rope_Knock_Challenge.desc="Atrás de você!" - -User_Mission_-_Nobody_Laugh.name=Missão: Ninguém ri -User_Mission_-_Nobody_Laugh.desc="Isso não é piada." - -User_Mission_-_RCPlane_Challenge.name=Desafio: Aeromodelo -User_Mission_-_RCPlane_Challenge.desc="Está bem confiante, né, aviador?" - -portal.name=Missão: Desafio dos portais -portal.desc="Use o portal para se mover rápido e para longe, use-o para matar, use-o com cuidado!" +Basic_Training_-_Bazooka.name=Treino básico de bazuca +Basic_Training_-_Bazooka.desc="O segredo é usar o vento ao seu favor!" + +Basic_Training_-_Grenade.name=Treino básico de granada +Basic_Training_-_Grenade.desc="Lembre, você tira o pino E arremessa!" + +Basic_Training_-_Cluster_Bomb.name=Treino básico de bomba de estilhaço +Basic_Training_-_Cluster_Bomb.desc="Alguém está precisando de um banho quente!" + +Basic_Training_-_Shotgun.name=Treino básico de escopeta +Basic_Training_-_Shotgun.desc="Atire primeiro, pergunte depois!" + +Basic_Training_-_Sniper_Rifle.name=Treino básico de Rifle Sniper +Basic_Training_-_Sniper_Rifle.desc="Bum! Na cabeça!" + +Basic_Training_-_Rope.name=Treino básico de corda +Basic_Training_-_Rope.desc="Saia daí e balance!" + +User_Mission_-_Dangerous_Ducklings.name=Missão: Patinhos perigosos +User_Mission_-_Dangerous_Ducklings.desc="Certo, recruta! Hora de colocar em prática o que aprendeu nos Treinos Básicos!" + +User_Mission_-_Diver.name=Missão: Mergulhador +User_Mission_-_Diver.desc="Essa coisa de 'investida anfíbio' é mais difícil do que parece..." + +User_Mission_-_Teamwork.name=Missão: Trabalho em equipe +User_Mission_-_Teamwork.desc="Às vezes, o amor doi." + +User_Mission_-_Spooky_Tree.name=Missão: Árvore medonha +User_Mission_-_Spooky_Tree.desc="Muitas caixas por aqui. Só espero que aquele pássaro não esteja com fome." + +User_Mission_-_Bamboo_Thicket.name=Missão: Floresta de bambus +User_Mission_-_Bamboo_Thicket.desc="A morte vem de cima." + +User_Mission_-_That_Sinking_Feeling.name=Missão: Aquela sensação de afundar +User_Mission_-_That_Sinking_Feeling.desc="A água está subindo rapidamente e o tempo é contado. Muitos tentaram, muitos falharam. Consegue salvar todos?" + +User_Mission_-_Newton_and_the_Hammock.name=Missão: Newton e a rede +User_Mission_-_Newton_and_the_Hammock.desc="Lembrem-se, ouriçozinhos: A velocidade de um corpo permanece constante a menos que aja sobre ele uma força externa!" + +User_Mission_-_The_Great_Escape.name=Missão: A grande fuga +User_Mission_-_The_Great_Escape.desc="Está pensando que consegue me prender!?" + +User_Mission_-_Rope_Knock_Challenge.name=Challenge: Corda que doi +User_Mission_-_Rope_Knock_Challenge.desc="Atrás de você!" + +User_Mission_-_Nobody_Laugh.name=Missão: Ninguém ri +User_Mission_-_Nobody_Laugh.desc="Isso não é piada." + +User_Mission_-_RCPlane_Challenge.name=Desafio: Aeromodelo +User_Mission_-_RCPlane_Challenge.desc="Está bem confiante, né, aviador?" + +portal.name=Missão: Desafio dos portais +portal.desc="Use o portal para se mover rápido e para longe, use-o para matar, use-o com cuidado!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/missions_tr.txt --- a/share/hedgewars/Data/Locale/missions_tr.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/missions_tr.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,50 +1,50 @@ -Basic_Training_-_Bazooka.name=Temel Roketatar Eğitimi -Basic_Training_-_Bazooka.desc="Rüzgarı yararına kullanmak bir anahtar!" - -Basic_Training_-_Grenade.name=Temel Bomba Eğitimi -Basic_Training_-_Grenade.desc="Unutma, pimi çek VE at!" - -Basic_Training_-_Cluster_Bomb.name=Temel Parça Tesirli Bomba Eğitimi -Basic_Training_-_Cluster_Bomb.desc="Birinin sıcak duşa ihtiyacı var!" - -Basic_Training_-_Shotgun.name=Temel Tüfek Eğitimi -Basic_Training_-_Shotgun.desc="Önce atış yap, soruları sonra sor!" - -Basic_Training_-_Sniper_Rifle.name=Temel Keskin Nişancı Tüfeği Eğitimi -Basic_Training_-_Sniper_Rifle.desc="Bum, kafadan!" - -Basic_Training_-_Rope.name=Temel Halat Eğitimi -Basic_Training_-_Rope.desc="Ordan çık ve sallan!" - -User_Mission_-_Dangerous_Ducklings.name=Görev: Tehlikeli Ördek Yavruları -User_Mission_-_Dangerous_Ducklings.desc="Peki acemi! Şimdi Temel Eğitimde öğrendiklerini uygulamanın zamanı!" - -User_Mission_-_Diver.name=Görev: Dalıcı -User_Mission_-_Diver.desc="Bu 'iki yönlü saldırı' göründüğünden daha zor..." - -User_Mission_-_Teamwork.name=Görev: Takım Çalışması -User_Mission_-_Teamwork.desc="Bazen, aşk acıtır." - -User_Mission_-_Spooky_Tree.name=Görev: Korkak Ağaç -User_Mission_-_Spooky_Tree.desc="Burada çok fazla kasa var. Eminim bu kuş aç değildir." - -User_Mission_-_Bamboo_Thicket.name=Görev: Bambu Ormanı -User_Mission_-_Bamboo_Thicket.desc="Ölüm yukardan gelir." - -User_Mission_-_That_Sinking_Feeling.name=Görev: Batıyormuş Hissi -User_Mission_-_That_Sinking_Feeling.desc="Su hızlıca yükseliyor ve zaman kısıtlı. Çoğu denedi ve kaybetti. Hepsini kurtarabilecek misin?" - -User_Mission_-_Newton_and_the_Hammock.name=Görev: Newton ve Hamak -User_Mission_-_Newton_and_the_Hammock.desc="Kirpişleri unutma: Bir vücudun hızı harici bir kuvvetle itilmedikçe sabit kalır!" - -User_Mission_-_The_Great_Escape.name=Görev: Büyük Kaçış -User_Mission_-_The_Great_Escape.desc="Beni hapsedebileceğini mi sanıyorsun!?" - -User_Mission_-_Rope_Knock_Challenge.name=Mücadele: Halat Vuruşu -User_Mission_-_Rope_Knock_Challenge.desc="Arkana bak!" - -User_Mission_-_RCPlane_Challenge.name=Mücadele: RC Uçağı -User_Mission_-_RCPlane_Challenge.desc="Çok emin görünüyorsun değil mi, uçan çocuk?" - -portal.name= Görev: Portal eğitim görevi -portal.desc="Hızlı ve uzak yerlere hareket için portalı kullan, öldürmek için kullan, dikkatli kullan!" +Basic_Training_-_Bazooka.name=Temel Roketatar Eğitimi +Basic_Training_-_Bazooka.desc="Rüzgarı yararına kullanmak bir anahtar!" + +Basic_Training_-_Grenade.name=Temel Bomba Eğitimi +Basic_Training_-_Grenade.desc="Unutma, pimi çek VE at!" + +Basic_Training_-_Cluster_Bomb.name=Temel Parça Tesirli Bomba Eğitimi +Basic_Training_-_Cluster_Bomb.desc="Birinin sıcak duşa ihtiyacı var!" + +Basic_Training_-_Shotgun.name=Temel Tüfek Eğitimi +Basic_Training_-_Shotgun.desc="Önce atış yap, soruları sonra sor!" + +Basic_Training_-_Sniper_Rifle.name=Temel Keskin Nişancı Tüfeği Eğitimi +Basic_Training_-_Sniper_Rifle.desc="Bum, kafadan!" + +Basic_Training_-_Rope.name=Temel Halat Eğitimi +Basic_Training_-_Rope.desc="Ordan çık ve sallan!" + +User_Mission_-_Dangerous_Ducklings.name=Görev: Tehlikeli Ördek Yavruları +User_Mission_-_Dangerous_Ducklings.desc="Peki acemi! Şimdi Temel Eğitimde öğrendiklerini uygulamanın zamanı!" + +User_Mission_-_Diver.name=Görev: Dalıcı +User_Mission_-_Diver.desc="Bu 'iki yönlü saldırı' göründüğünden daha zor..." + +User_Mission_-_Teamwork.name=Görev: Takım Çalışması +User_Mission_-_Teamwork.desc="Bazen, aşk acıtır." + +User_Mission_-_Spooky_Tree.name=Görev: Korkak Ağaç +User_Mission_-_Spooky_Tree.desc="Burada çok fazla kasa var. Eminim bu kuş aç değildir." + +User_Mission_-_Bamboo_Thicket.name=Görev: Bambu Ormanı +User_Mission_-_Bamboo_Thicket.desc="Ölüm yukardan gelir." + +User_Mission_-_That_Sinking_Feeling.name=Görev: Batıyormuş Hissi +User_Mission_-_That_Sinking_Feeling.desc="Su hızlıca yükseliyor ve zaman kısıtlı. Çoğu denedi ve kaybetti. Hepsini kurtarabilecek misin?" + +User_Mission_-_Newton_and_the_Hammock.name=Görev: Newton ve Hamak +User_Mission_-_Newton_and_the_Hammock.desc="Kirpişleri unutma: Bir vücudun hızı harici bir kuvvetle itilmedikçe sabit kalır!" + +User_Mission_-_The_Great_Escape.name=Görev: Büyük Kaçış +User_Mission_-_The_Great_Escape.desc="Beni hapsedebileceğini mi sanıyorsun!?" + +User_Mission_-_Rope_Knock_Challenge.name=Mücadele: Halat Vuruşu +User_Mission_-_Rope_Knock_Challenge.desc="Arkana bak!" + +User_Mission_-_RCPlane_Challenge.name=Mücadele: RC Uçağı +User_Mission_-_RCPlane_Challenge.desc="Çok emin görünüyorsun değil mi, uçan çocuk?" + +portal.name= Görev: Portal eğitim görevi +portal.desc="Hızlı ve uzak yerlere hareket için portalı kullan, öldürmek için kullan, dikkatli kullan!" diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/ru.txt --- a/share/hedgewars/Data/Locale/ru.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/ru.txt Sat Jan 04 23:55:54 2014 +0400 @@ -58,6 +58,7 @@ 00:54=Распылитель земли 00:55=Замораживатель 00:56=Секач +00:57=Батут 01:00=Вперёд к победе! 01:01=Ничья @@ -80,6 +81,8 @@ 01:18=Высокий 01:19=Экстремальный 01:20=%1 отскок +01:21=Звук отключен +01:22=Режим отсутствия ; Event messages ; Hog (%1) died diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_cs.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_cs.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,51 @@ + + + Jednoduše zvol stejnou barvu jako spoluhráč, abys hrál ve stejném týmu. Každý z vás bude mít kontrolu nad svými vlastními ježky, ale vyhraje nebo prohraje společně. + Některé zbraně mohou způsobovat jen malé poškození, ale mohou být devastující v pravé chvíli. Zkus použít pistoli Desert Eagle ke sražení několika nepřátelských ježků do vody. + Pokud si nejsi jistý, co dělat a nechceš plýtvat municí, přeskoč tah. Ale nenech uběhnout moc času, protože pak přijde Náhlá smrt! + Pokud chceš zabránit ostatním, aby používali tvoji oblíbenou přezdívku na oficiálním serveru, zaregistruj se na http://www.hedgewars.org/. + Jsi znuděn standardní hrou? Vyzkoušej některou misi - nabídnou jiný herní zážitek v závislosti na tom, kterou si vybereš. + Standardně hra vždycky nahrává poslední odehraný zápas jako ukázku. Vyber si 'Místní hru' a zvol tlačítko 'Ukázky' v pravém spodním rohu k jejich přehrávání a správě. + Hedgewars je Open Source a Freeware, který jsme vytvořili v našem volném čase. Pokud máš problémy, zeptej se na našem fóru, ale neočekávej prosím nonstop podporu! + Hedgewars je Open Source a Freeware, který jsme vytvořili v našem volném čase. Pokud se ti líbí, pomož nám malým příspěvkem, nebo se podílej na práci! + Hedgewars je Open Source a Freeware, který jsme vytvořili v našem volném čase. Sdílej ho se svoji rodinou a přáteli dle libosti! + Čas od času se konají oficiální turnaje. Nadcházející události budou publikovány na http://www.hedgewars.org/ s několika denním předstihem. + Hedgewars je k dispozici v mnoha jazycích. Pokud překlad do tvého jazyka vypadá zastaralý nebo chybí, neváhej nás kontaktovat! + Hedgewars může být spuštěno na mnoha různých operačních systémech včetně Microsoft Windows, Mac OS X a Linuxu. + Vždycky si pamatuj, že můžeš vytvořit vlastní hru na místní síti i internetu. Nejsi odkázán jen na možnost 'Prostá hra'. + Během hraní bys měl dělat krátké přestávky alespoň jednou za hodinu. + Pokud tvoje grafická karta nepodporuje hardwarovou akceleraci OpenGL, zkus zapnout nízkou kvalitu pro zlepšení výkonu. + Jsme otevřeni návrhům a konstruktivní kritice. Pokud se ti něco nelíbí, nebo máš skvělý nápad, dej nám vědět! + Obzvláště při hře online buď slušný a vždy pamatuj na to, že s tebou nebo proti tobě může hrát někdo z nějaké menšiny! + Speciální herní módy jako třeba 'Vampyrismus' nebo 'Karma' ti dovolují vymýšlet úplně jiné herní taktiky. Vyzkoušej je v nějaké hře! + Nikdy bys neměl instalovat Hedgewars na počítači, který ti nepatří (škola, univerzita, práce a jiné). Prosím, zeptej se nejprve zodpovědné osoby! + Hedgewars mohou být perfektní pro krátkou hru během pauzy. Jen se ujisti, že jsi nepřidal příliš mnoho ježků nebo nezvolil velkou mapu. Zmenšit čas nebo zdraví také urychlí hru. + Žádný ježek nebyl zraněn během vytváření této hry. + Hedgewars je Open Source a Freeware, který jsme vytvořili v našem volném čase. Pokud ti tuto hru někdo prodal, měl bys chtít vrátit peníze! + Připojenim jednoho nebo více gamepadů před začátkem hry ti umožní nastavit je jako ovladač pro tvé týmy. + Vytvoř si účet na %1, abys zabránil ostatním používat tvoji oblíbenou přezdívku na oficiálním serveru. + Pokud tvoje grafická karta nepodporuje hardwarovou akceleraci OpenGL, zkus aktualizovat ovladače. + Některé zbraně vyžadují speciální strategii, nebo jen spoustu cvičení. Nezavrhuj hned některou zbraň, pokud jednou mineš cíl. + Většina zbraní nefunguje, jakmile se ponoří do vody. Naváděná včela nebo dort jsou vyjímka z tohoto pravidla. + Olomoucké tvarůžky vybuchují jen málo, ale vítr ovlivňuje oblak smradu, který může nakazit mnoho ježků najednou. + Útok pianem je nejničivější letecký útok. Na druhé straně ale ztratíš ježka, který tento útok vykoná. + Přisavné miny jsou perfektní nástroj na vytváření malých řetězových reakcí, které mohou nepřátelské ježky dostat do divokých situací ... nebo vody. + Kladivo je nejefektivnější při použitǐ na mostech a traverzách. Zasažený ježek prostě prorazí skrz zem. + Pokud jsi zaseklý za nepřátelským ježkem, použij kladivo, aby ses osvobodil a nemusel riskovat zranění z exploze. + Maximální vzdálenost, do které dort dojde, je ovlivněna terénem, kterým musí jít. Použij [útok] k dřívější explozi. + Plamenomet je zbraň, ale dá se použít i pro kopání tunelů. + Chceš vědět, kdo stojí za touto hrou? Klikni na logo Hedgewars v hlavním menu a podívej se. + Líbí se ti Hedgewars? Staň se fanouškem na %1 nebo nás sleduj na %2! + Neboj se kreslit vlastní hroby, čepice, vlajky nebo mapy a témata! Ale pamatuj, že je musíš někde sdílet, abys je mohl používat online. + Opravdu chceš nosit specifickou čepici? Daruj nám něco a dostaneš exklusivní čepici dle svého výběru! + Udržuj ovladače grafické karty aktuální, aby ses vyhnul problémům při hře. + Můžeš si asociovat Hedgewars soubory (uložené hry a nahrávky) tak, abys je mohl ihned spouštět z internetového prohlížeče nebo prúzkumníka souborů. + Chceš ušetřit lana? Uvolni ho ve vzduchu a vystřel znovu. Dokud se nedotkneš země, využíváš ho bez plýtvání munice! + Použij Molotov nebo plamenomet, abys dočasně zamezil ježkům v přechodu terénu jako jsou tunely nebo plošiny. + + Windows verze Hedgewars podporuje Xfire. Přidej si Hedgewars do jeho seznamu her, abys viděl přátele, kteří ho hrají. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_da.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_da.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,57 @@ + + + Bare vælg samme farve som en ven for at spille sammen som et hold. Hver af jer vil stadig kontrollere sine egne pindsvin, men vil vinde eller tabe sammen. + Nogle våben giver måske ikke særlig meget skade, men de kan være meget mere farlige i de rigtige situationer. Prøv at bruge Desert Eagle-pistolen til at skubbe flere pindsvin i vandet. + Hvis du er usikker på hvad du skal gøre og ikke vil spilde ammunition, kan du springe en runde over. Men lad der ikke gå alt for meget tid, for ellers indtræffer Pludselig Død! + Hvis du ikke vil have at andre anvender dit foretrukne brugernavn på den officielle server, kan du registrere en bruger på http://www.hedgewars.org/. + Er du træt af den almindelige måde at spille på? Prøv en af missionerne - de tilbyder forskellige måder at spille på afhængigt af hvilken en du vælger. + Som standard optager spillet altid det sidste spil du har spillet som en demo. Tryk på 'Lokalt spil' og vælg 'Demoer'-knappen i nederste højre hjørne for at afspille eller administrere dem. + Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis du har problemer er du velkommen til at spørge på forummet, men forvent ikke at få hjælp 24 timer i døgnet! + Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis du holder af det, kan du hjælpe os med en lille donation eller ved at indsende dine egne modifikationer! + Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Del det med dine venner og din familie som du ønsker! + Fra tid til anden er der officielle turneringer. Kommende begivenheder vil blive annonceret på http://www.hedgewars.org/ et par dage i forvejen. + Hedgewars er tilgængeligt på mange sprog. Hvis oversættelsen på dit sprog mangler noget eller er uddateret, skal du være velkommen til at kontakte os! + Hedgewars kan køre på mange forskellige operativsystemer, herunder Microsoft Windows, Mac OS X og Linux. + Husk altid at du kan sætte dine egne spil op under lokale-, netværks- og online-spil. Du er ikke begrænset til kun at bruge 'Simpelt spil'-muligheden. + Mens du spiller bør du tage en kort pause mindst en gang i timen. + Hvis dit grafikkort ikke understøtter hardware-accelereret OpenGL, kan du prøve at slå indstillingen 'Reduceret kvalitet' til for at forbedre ydelsen. + Vi er åbne over for foreslag og konstruktive tilbagemeldinger. Fortæl os det hvis der er noget du ikke kan lide eller hvis du har en god idé! + Specielt når du spiller online bør du være venlig og altid huske at du måske også spiller med eller mod børn! + Specielle måder at spille på som f.eks. 'Varmpyr' eller 'Karma' tillader dig at udvikle helt nye taktikker. Prøv dem i et brugerdefineret spil! + Du bør aldrig installere Hedgewars på computere du ikke ejer (skole, universitet, arbejde,e.l.). Spørg venligst den ansvarlige person i stedet! + Hedgewars er perfekt til korte spil under pauser. Bare par på du ikke tilføjer for mange pindsvin eller bruger en kæmpe bane. Det kan også hjælpe at reducere tid og liv. + Ingen pindsvin kom til skade under produktionen af dette spil. + Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis nogen solgte dig spiller skal du bede om at få pengene tilbage! + Tilslut en eller flere gamepads før du starter spiller for at kunne tildele dem til dit hold. + Opret en bruger på %1 hvis du ikke vil have at andre anvender dit foretrukne brugernavn på den officielle server. + Hvis du ikke er i stand til at slå hardware-accelereret OpenGL til, bør du prøve at opdatere dine grafikkort-drivere. + Der er tre forskellige typer hop tilgængelige. Tryk hurtigt på [hight jump] to gange i træk for at lave et højt, baglæns hop. + Er du bange for at falde ned fra en skrænt? Hold [precise] nede for at vende dig mod [left] eller [right] uden at bevæge dig. + Nogle våben kræver specielle strategier eller bare masser af træning, så undlad ikke at bruge et bestemt våben bare fordi du rammer ved siden af én gang. + De fleste våben virker ikke så snart de har rørt vandet. Den Målsøgende Bi og Kagen er de eneste undtagelser. + Gamle Ole laver kun en lille eksplosion. Til gengæld kan den stænkende sky den udsender føres rundt af vinden og ramme mange pindsvin på én gang. + Klaveranslaget er det luftvåben der giver allermest skade. Til gengæld mister du det pindsvin som bruger angrebet, så der er også en bagside af medaljen. + Klæbrige Miner er det perfekte værktøj til at lave små kædereaktioner og smide pindsvin ud i faretruende situationer... eller bare direkte i vandet. + Hammeren er mest effektiv når den bruges enten på broer eller bærebjælker. Sigter du mod pindsvin med den, laver du bare huller i jorden. + Hvis du sidder fast bag en af modstanderens pindsvin, kan du bruge Hammeren til at slå dig fri uden at tage skade under en eksplosion. + Kagen kan gå kortere eller længere, afhængig af hvad den skal over på vejen. Du kan brrug [attack] til at detonere den før den når sin destination. + Flammekasteren er et våben, men den kan også bruges til hurtigt at grave tunneler. + Vil du vide hvem der står bag spillet? Klik på Hedgewars-logoet i hovedmenuen for at se rulleteksterne. + Er du glad for Hedgewars? Bliv fan på %1 eller følge vores opdateringer på %2! + Du skal være velkommen til at tegne dine egne gravsten, hatte, flag eller endda baner og temaer! Men læg mærke til at du bliver nød til at dele dem med andre hvis du vil spille med dem online. + Vil du virkelig gerne have en specifik hat? Send os en donation, så kvitterer vi med en eksklusiv hat efter eget valg! + Hold dine grafikkortdrivere opdaterede for at undgå problemmer i spillet. + Du kan finde konfigurationsfilerne til Hedgewars under mappen "(Mine) Dokumenter\Hedgewars". Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem. + Du kan indstille Hedgewars-filer (gemte spil og demooptagelser) til automatisk at åbne når du trykker på dem eller åbner dem i din internet-browser. + Vil du gerne spare på dine reb? Slip rebet midt i luften og skyd straks igen. Så længe du ikke rører jorden bruger du ikke noget ammunition! + Du kan finde konfigurationsfilerne til Hedgewars under mappen "Bibliotek/Application Support/Hedgewars" i din hjemmemappe. Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem. + Du kan finde konfigurationsfilerne til Hedgewars under mappen ".hedgewars" i din hjemmemappe. Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem. + Brug en Molotovcocktail eller Flammekasteren til midlertidigt at forhindre pindsvin i at passere et område, f.eks. en tunnel eller platform. + Den Målsøgende Bi kan være svær at bruge. Den vender lettere hvis den ikke flyver alt for hurtigt, så prøv at spare på kraften når du affyrer den. + + Windows-versionen af Hedgewars understøtter integrering med Xfire. Husk at tilføje Hedgewars til din liste med spil så dine venner kan se hvornår du spiller. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_de.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_de.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,61 @@ +# This is not xml actually, but it looks and behaves like it. +# Including an xml library would need too much resources. +# Tips between the platform specific tags are shown only on those platforms. +# Do not escape characters or use the CDATA tag. + + Wähl einfach die selbe Farbe wie die eines Freundes aus, um gemeinsam als ein Klan zu spielen. Jeder von euch wird immer noch Kontrolle über seine eigenen Igel haben, aber sie werden gemeinsam siegen oder verlieren. + Einige Waffen mögen zwar nur geringfügigen Schaden anrichten, aber sie können in der passenden Sitation verheerend sein. Versuche, die Desert Eagle zu benutzen, um mehrere Igel ins Wasser zu schubsen. + Falls du dir unsicher darüber bist, was du tun sollst und du keine Munition verschwenden willst, überspring die Runde. Aber lass nicht zu viel Zeit verstreichen, weil irgendwann der Sudden Death kommt. + Willst du Seile sparen? Lass das Seil im Flug los und schieß erneut. Solange du den Boden nicht berührst oder ein Schuss daneben geht, wirst du dein Seil wiederverwenden, ohne Vorräte zu vergeuden. + Wenn du Andere davon abhalten willst, deinen Lieblingsspitznamen auf dem offiziellen Server zu benutzen, registiere ein Benutzerkonto auf http://www.hedgewars.org/. + Bist du vom Standardspiel gelangweilt? Dann probier eine der Missionen aus – sie spielen sich anders, je nach dem, welche Mission du ausgewählt hast. + Standardmäßig wird das Programm immer vom letzten Spiel eine Wiederholung abspeichern. Wähle »Auf einen einzelnen Computer spielen« und dann den »Aufgezeichnete Wiederholungen ansehen«-Knopf auf der rechten unteren Ecke, um sie abzuspielen oder zu verwalten. + Hedgewars ist freie Open-Source-Software, die wir in unserer Freizeit erstellen. Falls du Probleme hast, frag uns in unseren Foren oder besuch unseren IRC-Channel! + Hedgewars ist freie Open-Source-Software, die wir in unserer Freizeit erstellen. Wenn es dir gefällt, hilf uns mit einer kleinen Spende oder steuere deine eigenen Werke bei! + Hedgewars ist freie Open-Source-Software, die wir in unserer Freizeit erstellen. Teile es mit deiner Famlie und deinen Freunden, wie es dir gefällt! + Hedgewars ist freie Open-Source-Software, die wir in unserer Freizeit nur so zum Spaß erstellen. Triff die Entwickler auf #hedgewars! + Von Zeit zu Zeit wird es offizielle Turniere geben. Bevorstehende Ereignisse werden auf http://www.hedgewars.org/ ein paar Tage im voraus angekündigt. + Hedgewars ist in vielen Sprachen verfügbar. Wenn die Übersetzung deiner Sprache zu fehlen oder veraltet zu sein scheint, nimm ruhig mit uns Kontakt auf! + Hedgewars läuft auf vielen verschiedenen Betriebssystemem, unter anderen Microsoft Windows, Mac OS X und GNU/Linux. + Denk immer daran, dass du in der Lage bist, deine eigenen Spiele in lokalen Spielen und Netzwerkspielen aufzusetzen. Du musst nicht zwangsläufig nur einfache Spiele spielen. + Verbinde einen oder mehr Gamepads, bevor du das Spiel startest, damit du ihre Belegung deinen Teams zuweisen kannst. + Erstelle ein Benutzerkonto auf http://www.hedgewars.org/, um andere davon abzuhalten, deinen Lieblingsspitznamen beim Spielen auf dem offiziellen Server zu benutzen. + Wenn du spielst, solltest du dir wenigstens ein mal pro Stunde eine kurze Pause gönnen. + Wenn deine Grafikkarte nicht in der Lage ist, hardwarebeschleunigtes OpenGL zur Verfügung zu stellen, versuche es mit einer niedrigen Qualitätsstufe (in den Grafikeinstellungen), um die Geschwindigkeit zu erhöhen. + Wenn deine Grafikkarte nicht in der Lage ist, hardwarebeschleunigtes OpenGL zur Verfügung zu stellen, versuche, die benötigten Treiber zu updaten. + Wir sind offen gegenüber Vorschlägen und konstruktiver Kritik. Wenn du etwas nicht magst oder du eine großartige Idee hast, lass es uns wissen! + Inbesondere, wenn du online spielst, sei höflich und denk immer daran, dass ein paar Minderjährige mit bzw. gegen dich spielen könnten. + Mit besonderen Spielmodi wie »Vampirismus« oder »Karma« kannst du völlig andere Strategien entwickeln. Probier sie in einem benutzerdefinierten Spiel aus! + Du solltest Hedgewars niemals auf Computern, die dir nicht gehören (Schule, Universität, Arbeit, usw.), installieren. Bitte frag die verantwortliche Person stattdessen! + Hedgewars kann perfekt für kurze Spiele in Pausen sein. Stell nur sicher, dass du nicht zu viele Igel hinzufügst oder eine gigantische Karte benutzt. Das Verringern der Zeit und Anfangsgesundheit kann ebenfalls helfen. + Bei der Erstellung dieses Spiels wurden keine Igel verletzt. + Drei verschiedene Sprünge sind verfügbar. Drücke [Hochsprung] doppelt, um einen sehr hohen Rückwärtssprung zu machen. + Hast du Angst, von einer Klippe zu stürzen? Halte [Genau zielen], um dich nach [links] oder [rechts], ohne dich tatsächlich zu bewegen, umzudrehen. + Ein paar Waffen erfordern besondere Strategien oder einfach nur sehr viel Training, also gib ein bestimmtes Werkzeug nicht auf, wenn du einen Gegner mal verfehlt haben solltest. + Die meisten Waffen würden nicht funktionieren, sobald sie das Wasser berührt haben. Die zielsuchende Biene sowie der Kuchen sind Ausnahmen davon. + Der alte Limburger verursacht nur eine kleine Explosion. Allerdings kann die vom Wind beeinflusste Stinkewolke viele Igel auf einmal vergiften. + Der Pianoangriff ist der zerstörerischste Luftangriff. Du verlierst den Igel, der ihn vornimmt, also gibt es hier eben auch einen riesigen Nachteil. + Die zielsuchende Biene kann knifflig zu verwenden sein. Ihr Drehradius hängt von ihrer Geschwindigkeit hab, also versuche, nicht mit voller Kraft zu schießen. + Haftminen sind ein perfektes Werkzeug, um kleine Kettenreaktionen, die feindliche Igel in fatale Situationen – oder Wasser - befördern. + Der Hammer ist am effektivsten, wenn er auf Brücken oder Bauträgern verwendet wird. Getroffene Igel werden einfach durch den Boden fallen. + Wenn du hinter einem feindlichen Igel feststeckst, benutze den Hammer, um dich selbst, ohne selbst durch eine Explosion verletzt zu werden, zu befreien. + Des Kuchens maximale Laufentfernung hängt von dem Boden, den er überqueren muss, ab. Benutze [Angriff], um ihn vorzeitig zu detonieren. + Der Flammenwerfer ist eine Waffe, aber sie kann auch zum Tunnelgraben verwendet werden. + Benutze den Molotowcocktail oder Flammenwerfer, um kurzzeitig Igel daran zu hindern, Gelände wie Tunnel oder Bauträger zu überqueren. + Willst du wissen, wer hinter dem Spiel steckt? Klick auf das Hedgewars-Logo im Hauptmenü, um die Liste der Mitwirkenden (derzeit nur auf Englisch, Anm. eines Übersetzers) zu sehen. + Magst du Hedgewars? Werd zum Fan auf Facebook oder folg uns auf Twitter! + Tu dir keinen Zwang an, dir deine eigenen Grabsteine, Hüte, Flaggen oder sogar Karten und Szenerien zu malen! Aber beachte, dass du sie irgendwo online teilen musst, um sie online benutzen zu können. + Halte deine Grafikkartentreiber auf dem neuesten Stand, um Probleme beim Spielen des Spiels zu vermeiden. + Kopf oder Zahl? Gib »/rnd« in der Lobby ein und finde es heraus. »/rnd Schere Stein Papier« funktioniert auch! + Du kannst Hedgewars-bezogene Dateien (Spielstände und Wiederholungen) mit dem Spiel assoziieren, um sie direkt von deinem Lieblingsdateiverwaltungsprogramm oder Webbrowser starten zu können. + + Diese Hedgewars-Version unterstützt Xfire. Stell sicher, Hedgewars dessen Spielliste hinzuzufügen, damit deine Freunde dich beim Spielen sehen können. + Du kannst deine Hedgewars-Einstellungsdateien unter »Eigene Dokumente\Hedgewars« finden. Erstelle Backups oder nimm die Dateien mit, aber bitte bearbeite sie nicht von Hand. + + + Du kannst deine Hedgewars-Einstellungsdateien unter »Library/Application Support/Hedgewars« in deinem »home«-Verzeichnis finden. Erstelle Backups oder nimm die Dateien mit, aber bitte bearbeite sie nicht von Hand. + + + Du kannst deine Hedgewars-Einstellungsdateien unter ».hedgewars« in deinem »home«-Verzeichnis finden. Erstelle Backups oder nimm die Dateien mit, aber bitte bearbeite sie nicht von Hand. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_en.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_en.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,61 @@ + + + Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together. + Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water. + If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death! + Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground or miss a shot you'll reuse your rope without wasting ammo! + If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/. + You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked. + By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them. + Hedgewars is free software (Open Source) we create in our spare time. If you've got problems, ask on our forums or visit our IRC room! + Hedgewars is free software (Open Source) we create in our spare time. If you like it, help us with a small donation or contribute your own work! + Hedgewars is free software (Open Source) we create in our spare time. Share it with your family and friends as you like! + Hedgewars is free software (Open Source) we create in our spare time, just for fun! Meet the devs in #hedgewars! + From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance. + Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us! + Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and GNU/Linux. + Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option. + Connect one or more gamepads before starting the game to be able to assign their controls to your teams. + Create an account on http://www.hedgewars.org/ to keep others from using your most favourite nickname while playing on the official server. + While playing you should give yourself a short break at least once an hour. + If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance. + If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers. + We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know! + Especially while playing online be polite and always remember there might be some minors playing with or against you as well! + Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game! + You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead! + Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well. + No hedgehogs were harmed in making this game. + There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump. + Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving. + Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once. + Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this. + The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once. + The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well. + The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power. + Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water. + The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground. + If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion. + The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early. + The Flame Thrower is a weapon but it can be used for tunnel digging as well. + Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms. + Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits. + Like Hedgewars? Become a fan on Facebook or follow us on Twitter + Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online. + Keep your video card drivers up to date to avoid issues playing the game. + Heads or tails? Type '/rnd' in lobby and you'll find out. Also '/rnd rock paper scissors' works! + You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser. + + The version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing. + You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand. + + + You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand. + + + You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_es.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_es.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,57 @@ + + + Elige el mismo color que tus amigos para hacer una alianza con ellos. Cada uno de vosotros controlará sus propios erizos, pero la victoria o derrota será compartida por vuestra facción. + Puede que algunas armas hagan poco daño, pero pueden ser realmente devastadoras si son usadas en el momento correcto. Prueba a usar la Desert eagle para empujar erizos enemigos al agua, por ejemplo. + Si no tienes claro qué vas a hacer y prefieres no desperdiciar munición puedes pasar un turno. ¡Pero ten cuidado, si dejas pasar muchos turnos puede que empiece la muerte súbita! + Si prefieres que nadie más use tu nick en el servidor oficial puedes registrarlo en http://www.hedgewars.org/. + ¿Estás cansado del modo de juego de siempre? Prueba alguna de las misiones, encontrarás en ellas nuevos tipos de juego dependiendo de la que elijas. + El juego intentará guardar la última partida como una demo de forma predeterminada. Más tarde puedes ir a "Juego local" y visitar la sección de "Demos" en la esquina inferior derecha para reproducirlas o gestionarlas. + Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. Si tienes algún problema estaremos encantados de ayudarte en nuestros foros o canal de IRC, pero ¡no esperes que estemos allí las 24 horas del día! + Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. ¡Si te gusta podrías considerar el ayudarnos con una pequeña donación o contribuyendo con tu propio trabajo! + Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. ¡Compártelo con tu família y amigos tanto como quieras! + De cuando en cuando celebramos torneos oficiales. Puedes mantenerte al día sobre los próximos eventos en http://www.hedgewars.org. + Hedgewars está disponible en varios idiomas. Si no encuentras traducción a tu idioma o piensas que la actual es de baja calidad o está desactualizada estaremos encantados de aceptar tu colaboración para mejorarla. + Hedgewars es un juego multiplataforma que puede ser ejecutado en diversos sistemas operativos, incluyendo Windows, Mac OS X y Linux. + Recuerda: puedes crear tus propias partidas multijugador tanto en local como por red, no estás limitado a jugar contra la máquina. + Tu salud es lo primero. Recuerda descansar unos minutos al menos una vez por cada hora de juego. + Si tu tarjeta gráfica no soporta aceleración gráfica mediante OpenGL prueba a habilitar el modo de baja calidad gráfica en la pantalla de opciones, puede que mejore el rendimiento del juego. + Siempre estamos abiertos a sugerencias y opiniones constructivas. Si hay algo que no te guste o tienes grandes ideas que te gustaría ver en el juego, ¡háznoslo saber! + Si juegas a través de internet recuerda mantener tus buenos modales y siempre ten en cuenta que puede que estés jugando con o contra menores de edad. + Los modos de juego especiales como "vampirismo" o "karma" te permiten desarrollar tácticas de juego completamente nuevas. ¡Pruébalos en tu próxima partida! + ¡Nunca instales Hedgewars en ordenadores que no te pertenezcan tales como los de tu escuela, universidad o trabajo sin perdir permiso primero a las personas responsables de los mismos! + Hedgewars es realmente genial para jugar partidas rápidas durante pausas o descansos; sólo recuerda no añadir muchos erizos y no usar mapas excesivamente grandes para que la partida no se alargue demasiado. Reducir la duración de los turnos o la vida inicial también puede ayudar. + Ningún erizo fue lastimado durante la creación de este juego. + Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. Si alguien te ha vendido el juego deberías pedirle que te devuelva tu dinero. + Conecta tus mandos al ordenador antes de iniciar el juego para poder asignar correctamente los controles de a equipo. + Crea una cuenta con tu nick en %1 para evitar que otras personas puedan usarlo en el servidor oficial. + Si tu tarjeta gráfica no es capaz de usar aceleración gráfica mediante OpenGL prueba a instalar drivers más actualizados. + Hay tres tipos de salto en el juego. Presiona [salto alto] dos veces para realizar un salto muy alto, vertical y ligeramente hacia atrás. + ¿Te da miedo caerte por una cornisa? Mantén presionado [aumentar precisión] para voltearte a [izquierda] o [derecha] sin moverte del sitio. + Algunas armas pueden requerir estrategias especiales o mucho entrenamiento antes de ser usadas correctamente. No tires la a toalla con alguna de ellas sólo porque has fallado el tiro la primera vez. + La mayoría de armas se desactivarán al tocar el agua. El abejorro y la tarta son algunas de las excepciones a la regla. + La explosión del limbuger añejo es relativamente pequeña, pero produce una nube de gas venenoso que será arrastrada por el viento, siendo capaz de intoxicar a varios erizos a la vez. + El piano es el ataque aéreo más destructivo del juego, aunque perderás el erizo que lo lance, así que úsalo con cuidado. + Las bombas lapa son perfectas para crear reacciones en cadena y mandar a tus enemigos al agua... o la Luna. + El mazo es mucho más efectivo si lo usas sobre vigas o puentes. Los erizos golpeados simplemente caerán por el agujero como Alicia por la madriguera. + Si estás atrapado tras un erizo enemigo puedes usar el mazo para abrirte paso sin resultar dañado por una explosión. + El alcance de la tarta depende de lo escarpado del terreno que tenga que atravesar, aunque puedes pulsar [atacar] para detonarla antes de que el contador llegue a cero. + El lanzallamas es un arma, pero puede usarse para excavar túneles en caso de necesidad. + ¿Quieres saber quiénes son los desarrolladores del juego? Pulsa el logo del juego en la pantalla principal para ver los créditos. + ¿Te gusta Hedgewars? ¡Hazte fan en %1 o síguenos en %2! + ¡Puedes dibujar tus propias tumbas, sombreros, banderas o incluso mapas y temas! Sólo ten en cuenta que el juego no es capaz de enviar archivos todavía, así que tendrás que enviar tú mismo los archivos a tus amigos para poder jugar en red con ellos. + ¿Te gustaría poder usar un sombrero especial, sólo para ti? Haz una donación y dinos qué sombrero quieres, lo dibujaremos para ti. + Mantén los drivers de tu tarjeta gráfica actualizados para evitar posibles problemas con este y otros juegos. + Puedes encontrar los archivos de configuración del juego en la carpeta "Mis Documentos\Hedgewars". Haz copias de seguridad de los mismos o cópialos a otro ordenador si lo deseas, pero no intentes editarlos a mano para evitar posibles pérdidas de datos. + Puedes asociar los tipos de archivo relacionados, partidas guardadas y demos, con Hedgewars para lanzarlos directamente desde tu gestor de archivos o navegador favoritos. + ¿Necesitas conservar cuerdas? Cuando estés usando una cuerda puedes desengancharla y volver a lanzarla de nuevo. ¡Mientras no toques el suelo seguirás usando la misma cuerda continuamente sin desperdiciar munición adicional! + Puedes encontrar los archivos de configuración del juego en la carpeta "Library/Application Support/Hedgewars" dentro de tu directorio personal. Puedes hacer copias de seguridad de los mismos o copiarlos a otro ordenador si lo deseas, pero no intentes editarlos a mano para evitar posibles pérdidas de datos. + Puedes encontrar los archivos de configuración del juego en la carpeta ".hedgewars" dentro de tu directorio personal. Puedes hacer copias de seguridad de los mismos o copiarlos a otro ordenador si lo deseas, pero no intentes editarlos a mano para evitar posibles pérdidas de datos. + Puedes usar el cóctel molotov o el lanzallamas para evitar que erizos enemigos crucen túneles angostos o puentes. + El abejorro puede ser complicado de usar. Su maniobrabilidad depende de su velocidad, así que intenta no lanzarlo a máxima potencia. + + La versión de Hedgewars para Windows soporta Xfire. Recuerda agregar Hedgewars a tu lista de juegos para que tus amigos puedan saber cuándo estás jugando. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_fi.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_fi.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,47 @@ + + + Valitse sama väri kaverisi kanssa pelataksesi samassa joukkueessa. Kumpikin ohjaa omia siilejään, mutta voitatte ja häviätte yhdessä. + Jotkut aseet tekevät vain vähän vahinkoa, mutta voivat olla tuhoisampia oikeassa tilanteessa. Kokeile ampua useampi siili veteen Desert Eaglella. + Jos et tiedä mitä tehdä etkä halua tuhlata ammuksia, jätä vuoro väliin. Mutta älä anna ajan kulua liikaa koska Äkkikuolema koittaa ennemmin tai myöhemmin! + Jos haluat estää muita käyttämästä nimimerkkiäsi virallisella palvelimella, rekisteröi tunnus osoitteessa http://www.hedgewars.org/. + Kyllästyttääkö normaali peli? Kokeila tehtäviä - Ne tarjoaa erilaisia pelitapoja riippuen valinnasta. + Oletuksena viimeisin peli nauhoitetaan demoksi. Valitse 'Demot' vasemmasta alakulmasta katsoaksesi ja hallitaksesi niitä. + Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jos sinulla on ongelmia, kysy keskustelualueilta apua, mutta älä odota 24/7-tukea! + Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jos pidät siitä, voit auttaa meitä pienellä lahjoituksella tai omaa työllä! + Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jaa sitä perheesi ja ystäviesi kesken miten haluat! + Toisinaan järjestetään virallisia turnauksia. Tulevista tapahtumista tiedotetaan osoitteessa http://www.hedgewars.org/ muutama päivä etukäteen. + Hedgewars on saatavilla monilla kielillä. Jos oman kielinen käännös puuttuu tai on vanhentunut, ota yhteyttä! + Hedgewars toimii useilla eri käyttöjärjestelmillä, kuten Microsoft Windowsissa, Mac OS X:ssä ja Linuxissa. + Muista että voit aina luoda oman pelisi paikallisesti ja verkkopelissä. Et ole rajoitettu yksinkertaiseen peliin. + Pelatessa sinun pitäisi pitää lyhyt tauko vähintään kerran tunnissa. + Jos näytönohjaimesi ei tarjoa laitteistokiihdytettä OpenGL:ää, kokeile heikennetyn laadun tilaa parantaaksesi suorituskykyä. + Me olemme avoimia ehdotuksille ja rakentavalle palautteelle. Jos et pidä jostain tai sinulla on loistava idea, kerro meille! + Erityisesti verkossa pelattaessa ole kohtelias ja muista että alaikäisiä saattaa myös olla pelaamassa. + Erityispelimoodit kuten 'Vampyrismi' ja 'Karma' mahdollistavat kokonaan uusien taktiikoiden kehittämisen. Kokeile niitä muokatussa pelissä! + Sinun ei ikinä tulisi asentaa Hedgewarsia tietokoneille joita et omista (koulu, yliopisto, työpaikka jne.). Ole hvä ja pyydä vastuuhenkilöä tekemään se! + Hedgewars voi olla täydellinen peli tauoille. Mutta varmista ettet lisää liian montaa siiltä ta käytä liian suurta karttaa. Ajan ja terveyden vähentäminen voi myös auttaa. + Yhtään siiliä ei vahingoitettu tämän pelin tekemisen aikana. + Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jos joku myi sinulle tämän pelin, koita saada rahasi takaisin! + Yhdistä yksi tai useampi peliohjain ennen pelin käynnistämistä liittääksesi niiden kontrollit omaan joukkueeseesi. + Luo käyttäjätili osoitteessa %1 estääksesi muita käyttämästä suosikkinimimerkkiäsi pelatessasi virallisella palvelimella. + Jos näytönohjaimesi ei tue laitteistokiihdytettyä OpenGL:ää, kokeile päivittää ajurit. + Hyppyjä on saatavilla kolmea erilaista. Napauta [korkea hyppy]-nappai kahdesti tehdäksesi todella korkean/taaksepäin hypyn. + Pelkäätkö että putoat kielekkeeltä? Pidä [tarkkuus]-näppäintä pohjassa kääntyäksesi [vasemmalle] ja [oikealle] liikkumatta. + Jotkut aseet vaativat erityisstrategiaa tai todella paljon harjoittelua, joten älä anna periksi vaikka et kerran osuisikaan. + + Vanha Limburger-juusto aiheuttaa vain pienen räjähdyksen, mutta tuulen vaikuttama hajupilvi voi myrkyttää suuren määrän siiliä kerralla. + Pianoisku on vahingollisin ilmaisku. Menetät siilen joka sen esittää, joten sillä on myös suuri huono puoli. + Tarttuvat miinat ovat täydellinen työkalu luomaan pieniä ketjureaktioita jotka vie vihollissiilit kauheisiin tilanteisiin...tai veteen. + Vasara on tehokkaimmillaan silloilla ja palkeilla. Lyödyt siilit iskeytyvät maan läpi. + Jos olet jumissa vihollissiilin takana, käytä vasaraa vapauttaaksesi itsesi ilman että vahingoidut räjädyksen voimasta. + Kakun pisin mahdollinen kulkumatka riippuu maastosta. Käytä [hyökkäystä] räjäyttääksesi sen aikaisemmin. + Liekinheitin on ase mutta sitä voi käyttää myös tunneleiden kaivamiseen. + Haluatko tietää ketkä ovat pelin takana? Klikkaa Hedgewars-logoa päävalikossa nähdäksesi tekijäluettelon. + Piirrä vapaasti omia hautoja, hattuja, lippuja ja jopa karttoja ja teemoja! Mutta huomaa että sinun pitää jakaa ne jossain käyttääksesi niitä verkossa. + Haluatko todella pitää tiettyä hattua? Lahjoita meille niin saat yksinoikeudella vapaavalintaisen hatun! + Pidä näytönohjaimesi ajurit ajantasall välttääksesi ongelmat pelin pelaamisessa. + Löydät Hedgewars-asetustiedostot hakemistosta "Omat tiedostot\Hedgewars". Ota varmuuskopio tai ota ne mukaasi, mutta älä muokkaa niitä käsin. + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_fr.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_fr.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,44 @@ + + + Choisissez la même couleur qu'un ami pour jouer dans la même équipe. Chacun de vous continuera à contrôler son ou ses hérissons mais ils gagneront ou perdront ensembles. + Certaines armes peuvent occasionner seulement de faibles dommages mais être beaucoup plus dévastatrices dans la situation adéquate. Essayez le Révolver pour envoyer plusieurs hérissons à l'eau. + Si vous ne savez pas quoi faire et ne voulez pas gaspiller de munitions, passez un tour. Mais ne laissez pas trop filer le temps ou ce sera la Mort Subite ! + Si vous voulez empêcher les autres d'utiliser votre pseudo sur le serveur officiel, créez un compte sur http://www.hedgewars.org/. + Assez du mode par défaut ? Essayez une des missions - elles offrent différents types de jeu suivant votre choix. + Par défaut le jeu enregistre la dernière partie jouée comme une démonstration. Sélectionnez « Jeu en local » puis « Démonstrations » en bas à droite pour les visionner ou les gérer. + Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Si vous avez des problèmes, demandez sur nos forums mais n'attendez pas de support 24h/24. + Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Si vous l'aimez, aidez-nous avec un petit don ou contribuez par votre travail ! + Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Partagez-le avec votre famille et vos amis comme vous le voulez ! + De temps en temps il y aura des tournois officiels. Les évènements à venir seront annoncés sur http://www.hedgewars.org/ quelques jours à l'avance. + Hedgewars est disponible dans de nombreuses langues. Si la traduction dans votre langue est partielle ou obsolète, contactez-nous ! + Hedgewars peux être exécuté sur de nombreux systèmes d'exploitation différents, incluant Microsoft Windows, Mac OS X et Linux. + Souvenez-vous que vous pouvez créer votre propres parties en local et en ligne. Vous n'est pas limités aux options de jeu par défaut. + Vous devriez faire une petite pause au moins une fois par heure. + Si votre carte graphique ne peut pas fournir d'accélération matérielle pour OpenGL, essayez le mode de faible qualité pour améliorer les performances. + Nous sommes ouverts aux suggestions et au critiques constructives. Si vous n'aimez pas quelque chose ou avez une grande idée, contactez-nous ! + Particulièrement quand vous jouez en ligne soyez polis et n'oubliez pas que certains joueurs peuvent être mineurs. + Les modes de jeu spéciaux comme « Vampirisme » ou « Karma » vous permettent de développer de nouvelles tactiques. Essayez-les en parties personnalisées ! + Vous ne devriez jamais installer Hedgewars sur des ordinateurs ne vous appartenant pas (école, université, travail, etc...). Demandez au responsable ! + Hedgewars peut être parfait pour des parties courtes pendant une pause. Assurez-vous juste de ne pas avoir mis trop de hérissons ou de ne pas utiliser une carte énorme. Réduire le temps ou la santé peuvent aider également. + Aucun hérisson n'a été blessé durant la conception de ce jeu. + Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Si quelqu'un vous l'a vendu, vous devriez vous faire rembourser ! + Branchez une ou plusieurs manettes avant de lancer le jeu pour pouvoir contrôler vos équipes avec. + Créer un compte sur %1 vous permet d'empêcher les autres d'utiliser votre pseudo favori sur le serveur officiel. + Si votre carte graphique ne peut pas fournir d'accélération matérielle pour OpenGL, essayez d'installer les drivers associés. + Certaines armes demandent de la stratégie ou juste beaucoup d'entrainement, alors ne laissez pas tomber une arme si vous avez raté une fois un ennemi. + La plupart des armes ne fonctionnent pas une fois qu'elles ont touché l'eau. L'Abeille Missile ou le Gâteau sont des exceptions. + La distance maximale que le Gâteau peux parcourir dépend du terrain qu'il doit franchir. Utiliser [attack] pour le faire exploser avant. + Vous voulez savoir qui est derrière le jeu ? Cliquez sur le logo Hedgewars dans le menu principal pour voir les crédits. + Soyez libre de dessiner vos propres tombes, chapeaux, drapeaux ou même cartes et thèmes ! Mais pour les utiliser en ligne vous devrez les partager quelque part. + Vous voulez vraiment un chapeau spécifique ? Faites un don et recevez un chapeau exclusif de votre choix. + Conservez les pilotes de votre carte graphique à jour pour éviter les problèmes en jouant. + Vous pouvez trouver vos fichiers de configuration Hedgewars sous « Mes Documents\Hedgewars ». Créez des sauvegardes ou prenez les fichiers avec vous, mais ne les modifiez pas à la main ! + Vous pouvez associer les fichiers relatifs à Hedgewars (parties enregistrées ou démonstrations) au jeu pour les lancer depuis votre navigateur de fichiers ou internet. + Vous aimez Hedgewars ? Devenez un fan sur %1 ou suivez-nous sur %2 ! + Envie d'économiser des Cordes Ninja ? Relâchez la Corde Ninja en l'air et tirez à nouveau. Du moment que vous ne touchez pas le sol, vous réutiliserez votre Corde Ninja sans gaspiller de munitions. + Vous pouvez trouver vos fichiers de configuration Hedgewars sous « Library/Application Support/Hedgewars » dans votre répertoire personnel. Créez des sauvegardes ou prenez les fichiers avec vous, mais ne les modifiez pas à la main ! + Vous pouvez trouver vos fichiers de configuration Hedgewars sous « .hedgewars » dans votre répertoire personnel. Créez des sauvegardes ou prenez les fichiers avec vous, mais ne les modifiez pas à la main ! + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_it.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_it.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,57 @@ + + + Scegli lo stesso colore di un amico per giocare in squadra. Ciascuno controllerà i propri ricci ma la vittoria o la sconfitta saranno comuni. + Alcune armi potrebbero fare pochi danni ma possono essere devastanti se usate al momento giusto. Prova ad esempio ad utilizzare la Desert Eagle per spingere più ricci in acqua. + Se non sai cosa fare e non vuoi sprecare munizioni, salta il turno. Ma non farlo troppe volte perché c'è il Sudden Death! + Se vuoi evitare che altri possano impersonarti, utilizzando il tuo nickname, sul server ufficiale, registrati su http://www.hedgewars.org/. + Sei stanco delle partite preimpostate? Prova una missione - le missioni offrono interessanti modalità differenti di partite in base alle tue scelte. + Il gioco salverà sempre l'ultima partita giocata come demo. Seleziona 'Gioco locale' e clicca il bottone 'Demos' nell'angolo in basso a destra per gestirle. + Hedgewars è un programma Open Source e gratuito che noi creiamo nel nostro tempo libero. Se hai problemi, chiedi nei nostri forum ma, per favore, non aspettarti un supporto 24/7! + Hedgewars è un programma Open Source e gratuito che creiamo nel nostro tempo libero. Se ti piace, aiutaci con una piccola donazione o contribuisci con il tuo lavoro! + Hedgewars è un programma Open Source e gratuito che creiamo nel nostro tempo libero. Condividilo con tutta la famiglia e e con gli amici come più ti piace! + Di tanto in tanto ci saranno tornei ufficiali. Gli eventi saranno annunciati su http://www.hedgewars.org/ con qualche giorno di anticipo. + Hedgewars è disponibile in molte lingue. Se la traduzione nella tua lingua sembra mancante o non aggiornata, sentiti libero di contattaci! + Hedgewars può essere usato su molti sistemi operativi differenti come Microsoft Windows - XP, Vista, 7 -, Mac OS X e Linux. + Ricordati che sei sempre in grado di configurare partire personalizzate in locale e online. Non devi sentirti limitato alle opzioni predefinite! + Durante il gioco dovresti fare una breve pausa almeno ogni ora. In caso di partite più lunghe, sospendi l'attività per almeno 30 minuti al termine del gioco! + Se la tua scheda grafica non è in grado di fornire OpenGL con accelerazione hardware, prova ad abilitare la modalità a bassa qualità per migliorare le prestazioni. + Siamo aperti a suggerimenti e consigli costruttivi. Se non ti piace qualcosa o hai una buona idea, comunicacelo! + In particolare quando giochi online sii educato e ricorda che potrebbero esserci dei minorenni che stanno giocando con te o contro di te! + Le modalità di gioco speciali, come 'Vampirismo' o 'Karma' ti permettono di sviluppare nuove tattiche. Provale in una partita personalizzata! + Non dovresti mai installare Hedgewars su computer che non possiedi (scuola, università, lavoro, ecc.). Per favore, chiedi ai responsabili! + Hedgewars può essere perfetto per brevi partite durante le pause. Assicurati solamente di non aver aggiunto troppi ricci o di usare una mappa troppo grande. Ridurre tempo e vita può aiutare allo stesso modo. + Nessun riccio è stato maltrattato durante lo sviluppo di questo gioco. + Hedgewars è un programma Open Source e gratuito che creiamo nel nostro tempo libero. Se qualcuno ti ha venduto il gioco, dovresti chiedere un rimborso! + Collega uno o più gamepad prima di iniziare il gioco per poterli assegnare alle tue squadra. + Crea un account su %1 per evitare che altri possano usare il tuo nickname preferito mentre giochi sul server ufficiale. + Se la tua scheda grafica non è in grado di fornire OpenGL con accelerazione hardware, prova ad aggiornarne i driver. + Ci sono tre salti disponibili. Premi [salto in alto] due volte per eseguire un salto in alto all'indietro. + Paura di cadere da un dirupo? Premi [mirino di precisione] per girare a [sinistra] o a [destra] senza muoverti. + Alcune armi richiedono strategie particolari o semplicemente molto allenamento, quindi non arrenderti nell'utilizzo di un'arma specifica se manchi il nemico una volta. + Molte armi non funzionano quando toccano l'acqua. L'Ape a Ricerca così come la Torta sono delle eccezioni. + Il vecchio Limburger causa solo una piccola esplosione. Tuttavia il vento influisce sulla nuvola puzzolente e può avvelenare più ricci contemporaneamente. + L'Ultima Sonata è l'attacco aereo più dannoso. Perderai il tuo riccio, eseguendolo, quindi ci sono anche delle grosse controindicazioni. + Le Mine Adesive sono lo strumento perfetto per creare piccole reazioni a catena e spingere i ricci nemici in situazioni difficili... o in acqua. + Il Martello è più efficate se usato su ponti o travi. Colpire i ricci li farà sprofondare attraverso il terreno. + Se sei bloccato dietro un riccio nemico, usa il Martello per liberarti senza essere danneggiato da un'esplosione. + La distanza massima di cammino della Torta dipende dal terreno che deve attraversare. Usa [attacca] per farla esplodere prima. + Il Lanciafiamme è un'arma che può essere usata anche per scavare gallerie. + Vuoi sapere chi c'è dietro il gioco? Clicca sul logo Hedgewars nel menu principale per vederne gli autori e sviluppatori. + Ti piace Hedgewars? Diventa fan su %1 o seguici su %2! + Sentiti libero di disegnare tombe, cappelli, bandiere o anche mappe e temi personalizzati - lo puoi fare con TheGIMP! Ma nota che dovrai condividerli in qualche modo per usarli online. + Vuoi proprio un cappello specifico? Facci una piccola donazione e riceverai un cappello esclusivo a tua scelta! + Mantieni aggiornati i driver della tua scheda video, per evitare problemi durante il gioco. + Puoi trovare i file di configurazione del gioco in "Documenti\Hedgewars". Crea delle copie di sicurezza o prendi i file con te, ma non modificarli manualmente! + Puoi associare i file relativi a Hedgewars (partite salvate e registrazioni demo) al gioco, in modo da lanciarli direttamente dal tuo gestore file o browser Internet. + Vuoi utilizzare più a lungo la corda? Rilascia la corda a mezz'aria e spara di nuovo. Finché non tocchi il terreno potrai riusare la corda senza sprecare munizioni! + Puoi trovare i file di configurazione del gioco in "Library/Application Support/Hedgewars" nella tua cartella utente. Crea una copia di sicurezza o porta i file con te, ma non modificarli mai manualmente. + Puoi trovare i file di configurazione del gioco in ".hedgewars" nella tua cartella home. Crea una copia di sicurezza o porta i file con te, ma non modificarli mai manualmente. + Usa la Bomba Molotov o il Lanciafiamme per impedire temporaneamente ai ricci di attraversari terreni pianeggianti, tunnel o collinette. + L'Ape a Ricerca può essere difficile da usare. Il suo raggio di curvatura dipende dalla sua velocità, quindi cerca di non usarla a piena potenza. + + La versione Windows di Hedgewars supporta Xfire. Assicurati di aggiungere Hedgewars alla sua lista giochi, così i tuoi amici potranno vederti giocare. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_pl.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_pl.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,57 @@ + + + By grać ze swoim przyjacielem w tej samej drużynie po prostu wybierzcie taki sam kolor obydwu zespołów. Każdy z was będzie sterować swoimi własnymi jeżami ale wygracie bądź przegracie jako jedna drużyna. + Niektóre z broni zadają mało punktów obrażeń jednak użyte w odpowiednim momencie mogą pokazać pazur. Na przykład spróbuj użyć pistoletu by strącić swoich przeciwników do wody. + Jeśli nie jesteś pewien co zrobić w danej turze i nie chcesz tracić amunicji możesz pominąć turę. Nie rób tak jednak zbyt często gdyż nagła śmierć jest nieuchronna! + Jeśli chciałbyś zapobiec używania własnego nicka przez kogoś innego, zarejestruj go na http://www.hedgewars.org . + Znudzony domyślnymi ustawieniami gry? Spróbuj zagrać w którąś z misji. - oferują one zmienione zasady gry w zależności od tej którą wybrałeś. + Gra zawsze będzie zapisywała ostatnią rozgrywkę jako Demo. Wybierz "Grę Lokalną" i kliknij w przycisk "Dema" który znajduje się w prawym dolnym rogu ekranu by je odtworzyć i zarządzać nimi. + Hedgewars jest darmową grą o otwartym kodzie, którą tworzymy w naszym wolnym czasie. Jeśli masz jakiś problem, zapytaj na forum ale nie spodziewaj się wsparcia 24 godziny na dobę! + Hedgewars jest darmową grą o otwartym kodzie, którą tworzymy w naszym wolnym czasie. Jeśli ją lubisz, wspomóż nas małą wpłatą lub stwórz własną czapkę bądź mapę! + Hedgewars jest darmową grą o otwartym kodzie, którą tworzymy w naszym wolnym czasie. Jeśli tylko chcesz, rozdaj ją swojej rodzinie i kolegom! + Od czasu do czasu będą organizowane mistrzostwa. Będą one ogłaszane z wyprzedzeniem na http://www.hedgewars.org/ . + Hedgewars jest dostępne w wielu językach. Jeśli brakuje tłumaczenia w twoim języku bądź jest ono niekompletne, nie bój się z nami skontaktować! + Hedgewars może być uruchomione na różnych systemach operacyjnych takich jak Microsoft Windows, MacOS X, FreeBSD oraz Linux. + Zawsze możesz zmieniać ustawienia gry w opcjach gry lokalnej lub sieciowej. Nie musisz ciągle używać tzw. "Szybkiej gry". + Zawsze pamiętaj o robieniu krótkich przerw co godzinę kiedy grasz na komputerze. + Jeśli twoja karta graficzna nie ma sprzętowego przyspieszania OpenGL, spróbuj włączyć tryb obniżonej jakości by zwiększyć płynność gry. + Jesteśmy otwarci na sugestie oraz konstruktywną krytykę. Jeśli coś Ci się nie podoba bądź masz jakiś pomysł, daj nam znać! + Bądź kulturalny grając przez internet. Pamiętaj o tym, że w Hedgewars mogą grać także młodsze osoby! + Specjalne tryby gry takie jak "Karma" bądź "Wampiryzm" pozwalają na stworzenie nowej taktyki! + Nie powinieneś instalować Hedgewars na komputerach których nie posiadasz (w szkole, na studiach, w pracy itp.). Zapytaj osoby odpowiedzialnej za te komputery! + Hedgewars jest idealny do gry w czasie przerw.Upewnij się, że nie dałeś zbyt dużej ilości jeży, bądź zbyt dużej mapy. Pomóc może także zmniejszenie długości tury lub obniżenie ilości życia. + Żaden jeż nie został ranny w czasie tworzenia tej gry. + Hedgewars jest darmową grą o otwartym kodzie źródłowym którą tworzymy w naszym wolnym czasie. Jeśli ktokolwiek sprzedał Tobie tę grę powinieneś upomnieć się o swoje pieniądze! + Jeśli podłączysz jeden lub więcej gamepadów przed włączeniem gry będziesz miał możliwość przypisania klawiszy by sterować swoimi jeżami. + Stwórz konto na %1 by zapobiec używania twojego ulubionego nicku przez innych na oficjalnym serwerze. + Jeśli twoja karta nie wspiera sprzętowego przyspieszania OpenGL spróbuj uaktualnić swoje sterowniki. + Są trzy różne rodzaje skoku możliwe do wykonania. Naciśnij [wysoki skok] dwa razy by zrobić bardzo wysoki skok w tył. + Boisz się upadku z krawędzi terenu? Przytrzymaj klawisz [precyzyjnego celowania] by obrócić się w [lewo] lub [prawo] bez ruszenia się z miejsca. + Niektóre z broni wymagają specjalnej strategii lub dużo treningu by je popranie używać. Nie poddawaj się gdy nie wychodzi ci za pierwszym razem. + Większość uzbrojenia nie działa pod wodą. Pszczoła i Ciasto są wyjątkami od tej reguły. + Cuchnący ser nie powoduje wielkiego wybuchu. Jednakże pod wpływem wiatru chmura śmierdzącego gazu może bardzo daleko zawędrować i otruć wiele jeży naraz. + Zrzut pianina jest najbardziej morderczym atakiem powietrznym. Pamiętaj, że tracisz jeża którym wykonujesz ten atak więc dobrze zaplanuj swój ruch. + Miny samoprzylepne są idealnym narzędziem by tworzyć małe reakcje łańcuchowe bądź do zmuszenia przeciwnika by popadł w tarapaty lub wpadł do wody. + Młotek jest najbardziej skuteczny na mostach bądź kładkach. Uderzone jeże przelecą przez nie na sam dół. + Jeśli utknąłeś za jeżem przeciwnika, użyj młotka by wbić go w ziemię. Unikniesz wtedy eksplozji która z pewnością zabrałaby Tobie punkty życia. + Dystans który Ciasto może przebyć zależy od terenu który ma do przebycia. Użyj [ataku] by zdetonować je wcześniej. + Miotacz ognia jest śmiercionośną bronią ale może być użyty również jako narzędzie do kopania tuneli. + Chcesz wiedzieć kto tworzy tę grę? Kliknij logo w głównym menu by zobaczyć autorów. + Lubisz Hedgewars? Zostań fanem na %1 lub dołącz do grupy na %2! + Możesz rysować własne nagrobki, czapki, flagi lub nawet mapy albo tematy! Miej na uwadze to by udostępnić je każdemu który będzie grał z Tobą przez sieć. + Chcesz nosić wymarzoną czapkę? Wspomóż nas pieniężnie a my zrobimy specjalną czapkę tylko dla Ciebie! + Pamiętaj o aktualizowaniu sterowników by zapobiec problemom z grami. + Swoje zespoły i konfigurację gry znajdziesz w folderze "Moje Dokumenty\Hedgewars". Twórz regularnie kopie zapasowe, ale nie edytuj tych plików własnoręcznie. + Możesz powiązać typy plików związane z Hedgewars (zapisy gier i dema) by móc je uruchamiać bezpośrednio z ulubionego menedżera plików bądź przeglądarki internetowej. + Chcesz zaoszczędzić liny? Odłącz ją będąc w powietrzu, a potem wypuść ją ponownie. Dopóki nie dotkniesz ziemi, będziesz używał pojedynczego naboju! + Swoje zespoły i konfigurację gry znajdziesz w folderze "Library/Application Support/Hedgewars" w twoim katalogu domowym. Twórz regularnie kopie zapasowe, ale nie edytuj tych plików własnoręcznie. + Swoje zespoły i konfigurację gry znajdziesz w folderze ".hedgewars" w twoim katalogu domowym. Twórz regularnie kopie zapasowe, ale nie edytuj tych plików własnoręcznie. + Użyj koktajlu Mołotowa lub Miotacza ognia by powstrzymać przeciwnika przed przedostaniem się przez tunele lub platformy. + Pszczoła potrafi być ciężka w użyciu. Jej promień skrętu zależy od prędkości lotu, więc nie staraj się nie używać pełnej mocy podczas strzału. + + Wersja Hedgewars dla systemu Windows wspiera Xfire. Upewnij się, że dodałeś Hedgewars do listy gier by Twoi znajomi mogli zobaczyć Ciebie w czasie gry. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_ru.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_ru.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,57 @@ + + + Выберите тот же цвет команда, что у друга, чтобы играть в союзе. Вы будете управлять своими ежами, но выиграете или проиграете вместе. + Некоторые виды оружия наносят небольшой урон, но могут наносить больший урон в правильной ситуации. Попробуйте использовать пистолет Дезерт Игл, чтобы столкнуть несколько ежей в воду. + Если вы не уверены в том, что хотите сделать и не хотите тратить снаряды, пропустите ход. Но не теряйте много времени, так как смерть неизбежна! + Если вы хотите предотвратить использование вашего псевдонима другими игроками на официальном игровом сервере, зарегистрируйтесь на http://www.hedgewars.org/. + Наскучила обычная игра? Попробуйте миссии, имеющие различные виды сценариев. + По умолчанию игры всегда записывает последнюю игру в виде демки. Выберите "Локальную игру" и нажмите кнопку "Демки" в правом нижнем углу, чтобы проиграть запись. + Hedgewars - это открытое и свободное программное обеспечение, которое мы создаём в наше свободное время. Если у вас возникают вопросы, задавайте их на нашем форуме, но пожалуйста, не ожидайте круглосуточной поддержки! + Hedgewars - это открытое и свободное программное обеспечение, которое мы создаём в наше свободное время. Если вам понравилась игра, помогите нам денежным вознаграждением или вкладом в виде вашей работы! + Hedgewars - это открытое и свободное программное обеспечение, которое мы создаём в наше свободное время. Распространяйте его среди друзей и членов семьи! + Время от времени проводятся официальные турниры. Предстоящие события анонсируются на http://www.hedgewars.org/ за несколько дней. + Hedgewars доступен на многих языках. Если перевод на ваш язык отсутствует или устарел, сообщите нам! + Hedgewars запускается на множестве различных операционных систем, включая Microsoft Windows, Mac OS X и Linux. + Помните, что у вас есть возможность создать собственную игру локально или по сети. Вы не ограничены кнопкой "Простая игра". + Играя, не забывайте делать небольшой перерыв хотя бы раз в час. + Если ваша видеокарта не поддерживает ускорение OpenGL, попробуйте включить опцию "низкое качество", чтобы улучшить производительность. + Мы открыты для предложений и конструктивной критики. Если вам что-то не понравилось или у вас появилась отличная идея, сообщите нам! + Играя по сети, будьте особенно вежливы и всегда помните, что с вами или против вас могут играть дети! + Особые настройки игры "Вампиризм" и "Карма" дают возможность выработать совершенно новую тактику. Попробуйте их! + Не следует устанавливать Hedgewars на компьютеры, не принадлежащие вам (в школе, на работе, в университете и т.п.). Не забудь спросить разрешения у ответственного лица! + Hedgewars может отлично подойти для коротких матчей на перерывах. Просто не добавляйте слишком много ежей и не играйти на больших картах. Также можно уменьшить время или количество начального здоровья. + При подготовке игры не пострадал ни один ёж. + Hedgewars - это открытое и свободное программное обеспечение, которое мы создаём в наше свободное время. Если кто-то продал вам игру, потребуйте возврат денег! + Подсоедините один или несколько геймпадов перед запуском игры, и вы сможете настроить их для управления командами. + Если вы хотите предотвратить использование вашего псевдонима другими игроками на официальном игровом сервере, зарегистрируйтесь на http://www.hedgewars.org/. + Если ваша видеокарта не поддерживает ускорение OpenGL, попробуйте обновить видеодрайвер. + Есть три вида прыжков. Нажмите [прыжок вверх] дважды, чтобы сделать очень высокий прыжок назад. + Боитесь упасть с обрыва? Нажмите левый shift, чтобы повернуться влево или вправо, не передвигаясь. + Некоторые виды оружия требуют особых стратегий или просто много тренировок, поэтому не разочаровывайтесь в инструменте, если разок промахнётесь. + Большинство видов оружия не сработают при попадании в воду. Пчела и Торт - это исключения. + Старый Лимбургер взрывается несильно. Однако ветер, несущий зловонное облако, может отравить несколько ежей за раз. + Фортепьяновый удар - это наиболее мощный из ударов с воздуха. При использовании вы потеряете ежа, в этом его недостаток. + Мины-липучки - отличный инструмент для создания небольших цепных реакций, от которых ёж попадет в неприятную ситуацию... или в воду. + Молот наиболее эффективен, когда используется на мосту или балке. Ударенный ёж пролетит сквозь землю. + Если вы застряли позади ежа противника, используйте Молот. чтобы освободить себя без риска потери здоровья от взрыва. + Дистанция, которую проходит Торт, зависит от поверхности. Используйте клавишу атаки, чтобы сдетонировать его раньше. + Огнемёт - это оружие, но он также может быть использован как инструмент для рытья туннелей. + Хотите узнать, кто стоит за разработкой игры? Нажмите на логотип Hedgewars в главном меню, чтобы увидеть состав разработчиков. + Нравится Hedgewars? Станьте фанатом на %1 или следите за нами на %2! + Рисуйте свои варианты надгробий, шляп, флагов или даже карт и тем! Но не забудьте передать их соперникам каким-либо образом для игры по сети. + Очень хочется особенную шляпу? Сделайте пожертвование и получите эксклюзивную шляпу на выбор! + Обновляйте видеодрайвера, чтобы не было проблем во время игры. + Файлы конфигурации Hedgewars находятся в папке "Мои документы\Hedgewars". Создавайте бэкапы или переносите файлы, но не редактируйте их вручную. + Можно ассоциировать файлы Hedgewars (сохранения и демки игр) с игрой, чтобы запускать их прямо из вашего любимого файлового менеджера или браузера. + Хотите сэкономить верёвки? Отпустите верёвку в воздухе и стреляйте снова. Пока вы не затронете землю, вы можете использовать верёвку сколько угодно, не тратя дополнительных! + Файлы конфигурации Hedgewars находятся в папке ""Library/Application Support/Hedgewars". Создавайте бэкапы или переносите файлы, но не редактируйте их вручную. + Файлы конфигурации Hedgewars находятся в папке ".hedgewars". Создавайте бэкапы или переносите файлы, но не редактируйте их вручную. + Используйте Коктейль Молотова или Огнемёт, чтобы временно не дать ежам пройти через туннель или по платформе. + Пчёлку можеть быть сложно использовать. Её радиус поворота зависит от скорости, поэтому попробуйте не использовать полную силу броска. + + Версия Hedgewars под операционную систему Windows поддерживает Xfire. Не забудьте добавить Hedgewars в список игр, чтобы ваши друзья видели, когда вы в игре. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_sk.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_sk.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,57 @@ + + + Ak chcete hrať s priateľom ako tím, jednoducho si zvoľte tú istú farbu. I naďalej budete ovládať svojich vlastných ježkov, ale víťazstvá či prehry budú spoločné. + Niektoré zbrane môžu spôsobovať málo škody, ale dokážu byť oveľa účinnejšie v tej správnej situácii. Skúste použiť Desert Eagle na zostrelenie viacerých ježkov do vody. + Ak neviete, čo robiť a nechcete mrhať muníciou, preskočte ťah. Ale nerobte tak príliš často, pretože príde Náhla smrť! + Ak nechcete, aby niekto iný používal vašu prezývku na oficiálnom serveri, registrujte si účet na http://www.hedgewars.org/. + Nudí vás štandardná hra? Vyskúšajte si jednu z misii - ponúkajú iný herný zážitok v závislosti na tom, akú si vyberiete. + Vo východzom nastavení sa posledná hra automaticky ukladá ako demo. Vyberte 'Miestna hra' a kliknite na tlačidlo 'Demá' v pravom dolnom rohu, ak si chcete demo uložiť alebo prehrať. + Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom čase. Ak máte problém, spýtajte sa na fóre, ale nečakajte podporu 24 hodín v týždni! + Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom čase. Ak chcete pomôcť, môžete nám zaslať malú finančnú výpomoc alebo prispieť vlastnou prácou! + Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom čase. Podeľte sa oň so svojou rodinou a priateľmi! + Z času na čas bývajú usporiadavané oficiálne turnaje. Najbližšie akcie sú vždy uverejnené na http://www.hedgewars.org/ pár dní dopredu. + Hedgewars je dostupný v mnohých jazykoch. Ak preklad do vašej reči chýba alebo nie je aktuálny, prosím, kontaktujte nás! + Hedgewars beží na množstve rozličných operačných systémov vrátane Microsoft Windows, Mac OS X a Linuxu. + Nezabudnite, že si vždy môžete vytvoriť vlastnú lokálnu alebo sieťovú/online hru. Nie ste obmedzený len na voľbu 'Jednoduchá hra'. + Mali by ste si dopriať krátky odpočinok po každej hodine hry. + Ak vaša grafická karta nie je schopná poskytnúť hardvérovo akcelerované OpenGL, skúste povoliť režim nízkej kvality, aby ste dosiahli požadovaný výkon. + Sme otvorení novým nápadom a konštruktívnej kritike. Ak sa vám niečo nepáči alebo máte skvelý nápad, dajte nám vedieť! + Obzvlášť pri hre online buďte slušný a pamätajte, že s vami alebo proti vám môžu hrať tiež neplnoletí! + Špeciálne herné režimy ako 'Vampírizmus' alebo 'Karma' vám umožnia vyvinúť úplne novú taktiku. Vyskúšajte ich vo vlastnej hre! + Nikdy by ste nemali inštalovať Hedgewars na cudzí počítač (v škole, na univerzite, v práci, atď). Prosím, radšej požiadajte zodpovednú osobu! + Hedgewars môže byť výborná hra, ak máte krátku chvíľku počas prestávky. Iba sa uistite, že nepoužijete príliš veľa ježkov alebo príliš veľkú mapu. Rovnako môže pomocť zníženie času a zdravia. + Počas tvorby tejto hry nebolo ublížené žiadnemu ježkovi. + Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom čase. Ak vám niekto túto hru predal, skúste žiadať o refundáciu! + Ak chcete pre hru použiť jeden alebo viacero gamepadov, pripojte ich pred spustením hry. + Vytvorte si účet na %1, aby ste tak zabránili ostatným používať vašu obľúbenú prezývku počas hrania na oficiálnom serveri. + Ak vaša grafická karta nie je schopná poskytnúť hardvérovo akcelerované OpenGL, skúste aktualizovať príslušné ovládače. + Dostupné sú tri rôzne výskoky. Dvakrát stlačte [vysoký skok] pre veľmi vysoký skok vzad. + Bojíte sa pádu z útesu? Podržte [presné mierenie] a stlačte [doľava] alebo [doprava] pre otočenie na mieste. + Niektoré zbrane vyžaduju osobitnú stratégiu alebo len veľa tréningu, takže to s vybranou zbraňou nevzdávajte, ak sa vám nepodarí trafiť nepriateľa. + Väčšina zbraní prestane fungovať pri kontakte s vodou. Navádzané včela a Torta sú výnimkami z tohto pravidla. + Starý cheeseburger spôsobí len malú explóziu. Obláčik smradu, ktorý je ovplyvňovaný vetrom, však dokáže otráviť množstvo ježkov. + Klavírový útok je najničivejší vzdušný útok. Pri jeho použití prídete o ježka, čo je jeho veľké mínus. + Lepkavé míny sú perfektným nástrojom na vytvorenie malých reťazových reakcii, vďaka ktorým postavíte ježkov do krajných situácii ... alebo vody. + Kladivo je najefektívnejšie pri použití na mostoch alebo trámoch. Zasiahnutí ježkovia prerazia zem. + Ak ste zaseknutý za nepriateľským ježkom, použite kladivo, aby ste sa oslobodili bez toho, aby vám ublížila explózia. + Maximálna prejdená vzdialenosť torty zavisí na zemi, ktorou musí prejsť. Použitie [útok], ak chcete spustiť detonáciu skôr. + Plameňomet je zbraň, no rovnako môže byť použitý na kopanie tunelov. + Chcete vedieť, kto stojí za hrou? Kliknite na logo Hedgewars v hlavnom menu pre zobrazenie zásluh. + Ak máte chuť, môžte si nakresliť vlastné hrobčeky, klobúky, vlajky alebo dokonca mapy a témy! Pamätajte však, že ak ich budete chcieť použiť v hre online, budete ich musieť zdieľať s ostatnými. + Chcete nosiť špecifický klobúk? Prispejte nám a ako odmenu získate exkluzívny klobúk podľa vášho výberu! + Aby ste sa vyhli problémom pri hre, udržujte ovládače vašej grafickej karty vždy aktuálne. + Konfiguračné súbory Hedgewars nájdete v "Moje Dokumenty\Hedgewars". Vytvárajte si zálohy alebo prenášajte si tieto súbory medzi počítačmi, ale needitujte ich ručne. + Chcete ušetriť lano? Kým ste vo vzduchu, uvoľnite ho a opäť vystreľte. Kým sa nedotknete zeme, môžete to isté lano znovu použiť bez toho, aby sa vám míňali jeho zásoby! + Páčia sa vám Hedgewars? Staňte sa fanúšikom na %1 alebo sa pripojte k našej skupine na %2. Môžte nás tiež nasledovať na %3! + Môžte priradiť súbory patriace Hedgewars (uložené hry a nahrávky záznamov) ku hre, čím sa vám budú otvárať priamo z vášho obľubeného prehliadača súborov alebo internetu. + Konfiguračné súbory Hedgewars nájdete v "Library/Application Support/Hedgewars" vo vašom domovskom adresári. Vytvárajte si zálohy alebo prenášajte si tieto súbory medzi počítačmi, ale needitujte ich ručne. + Konfiguračné súbory Hedgewars nájdete v ".hedgewars" vo vašom domovskom adresári. Vytvárajte si zálohy alebo prenášajte si tieto súbory medzi počítačmi, ale needitujte ich ručne. + Použite Molotovov koktejl alebo plameňomet na dočasné zabránenie ježkom prejsť terénom ako sú tunely alebo plošiny. + Navádzaná včela je trošku zložitejšia na použitie. Jej polomer otočenia závisí na jej rýchlosti, takže ju radšej nepoužívajte pri plnej sile. + + Hedgewars vo verzii pre Windows podporujú Xfire. Pridajte si Hedgewars do vášho zoznamu hier tak, aby vás vaši priatelia videli hrať. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tips_uk.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Locale/tips_uk.xml Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,57 @@ + + + Виберіть той же колір що і в друга щоб грати в одній команді. Кожен з вас буде керувати власними їжаками але вони виграють чи програють разом. + Деяка зброя наносить мало шкоди, але вона може бути більш руйнівною в правильній ситуації. Спробуйте використати Пустельного Орла для скидання кількох їжаків у воду. + Якщо ви не знаєте що робити і не хочете витрачати боєприпаси, пропустіть один раунд. Але не марнуйте занадто багато часу, тому-що прийде Раптова Смерть! + Якщо ви хочете закріпити за собою нік на офіційному сервері, зареєструйте аккаунт на http://www.hedgewars.org/. + Ви втомилися від гри за замовчуванням? Спробуйте одну з місій - вони пропонують різні види гри залежно від вашого вибору. + За замовчуванням остання гра завжди буде записуватись в якості демо. Виберіть 'Локальну Гру' і натисніть кнопку 'Демонстрації' у нижньому правому куті щоб грати або керувати ними. + Hedgewars є відкритою та безплатною, ми створюємо її у вільний час. Якщо у вас є проблеми, запитайте на нашому форумі, але будь-ласка, не чекайте підтримки 24/7! + Hedgewars є відкритою та безплатною, ми створюємо її у вільний час. Якщо вона вам подобається, допоможіть нам невеликим внеском або вкладіть свою роботу! + Hedgewars є відкритою та безплатною, ми створюємо її у вільний час. Поділіться грою з родиною та друзями! + Час від часу проводяться офіційні турніри. Майбутні події будуть оголошені на http://www.hedgewars.org/ за кілька днів перед проведенням. + Hedgewars доступна на багатьох мовах. Якщо переклад на вашу мову застарів чи відсутній, не соромтеся звертатися до нас! + Hedgewars може бути запущений на багатьох операційних системах, включаючи Microsoft Windows, Mac OS X і Linux. + Завжди пам'ятайте, ви можете створити свою власну гру в локальному та мережному/онлайн-режимах. Ви не обмежені опцією 'Проста Гра'. + Поки граєте гру зробіть коротку перерву хоча б раз на годину. + Якщо ваша відеокарта не може забезпечити апаратне прискорення OpenGL, спробуйте включити режим низької якості для підвищення продуктивності. + Ми відкриті для пропозицій і конструктивного зворотнього зв'язку. Якщо вам не подобається щось або є відмінна ідея, дайте нам знати! + Особливо під час гри онлайн будьте ввічливі і завжди пам'ятайте, з вами чи проти вас можуть грати неповнолітні! + Спеціальні режими гри, такі як 'Вампіризм' чи 'Карма' дозволяють розробляти цілком нову тактику. Спробуйте їх в налаштованій грі! + Ви не повинні встановлювати Hedgewars на комп'ютерах, які вам не належать (школа, університет, робота тощо). Будь ласка, звертайтесь до відповідальної особи! + Hedgewars чудово підходить для короткої гри під час перерв. Переконайтеся, що ви не додали занадто багато їжаків і не взяли велику карту. Скорочення часу і здоров'я також підійде. + Під час розробки гри не постраждав жодний їжак. + Hedgewars є відкритою та безплатною, ми створюємо її у вільний час. Якщо хтось продав вам гру, ви повинні спробувати отримати відшкодування! + Підключіть один або кілька геймпадів перед початком гри, щоб ваші команди могли ними користуватись. + Створіть акаунт на %1 щоб запобігти використанню іншими особами вашого улюбленого ніку під час гри на офіційному сервері. + Якщо ваша відеокарта не може забезпечити апаратне прискорення OpenGL, спробуйте оновити відповідні драйвери. + В грі існують три різних види стрибків. Натисніть [високий стрибок] двічі щоб зробити дуже високий стрибок назад. + Боїтесь падіння зі скелі? Утримуйте [точно] щоб повернутись [вліво] чи [вправо] без фактичного переміщення. + Деяка зброя вимагає спеціальних стратегій або просто багато тренувань, тому не відмовляйтесь від конкретного інструменту, якщо ви раз не знешкодили ворога. + Більшість зброї не буде працювати після торкання води. Бджола та Торт є виключеннями з цього правила. + Старий лімбургський сир викликає лише невеликий вибух. Однак смердюча хмара, яку відносить вітер, може отруїти багато їжаків за раз. + Напад піаніно є найбільш руйнівним повітряним ударом. Але ви втратите їжака, тому він має і негативну сторону. + Липкі Міни чудовий інструмент створення малих ланцюгових реакцій для закидання ворогів у складні ситуації ... або у воду. + Молоток найбільш ефективний при використанні на мостах чи балках. Удар їжака просто провалить його крізь землю. + Якщо ви застрягли за ворожим їжаком, використайте Молоток, щоб звільнити себе без пошкоджень від вибуху. + Найбільший шлях ходьби Торта залежить від землі, по якій він повинен пройти. Використовуйте [атака] щоб підірвати його раніше. + Вогнемет це зброя, але його можна також використати для риття тунелю. + Хочете знати хто робить гру? Натисніть на логотип Hedgewars в головному меню, щоб побачити список. + Подобається Hedgewars? Станьте фанатом на %1 або слідуйте за нами на %2! + Ви можете самі намалювати надгробки, шапки, прапори та навіть мапи і теми! Але врахуйте, вам доведеться поділитися ними з кимось щоб використати їх в інтернет-грі. + Хочете носити особливий капелюх? Внесіть пожертву і отримайте ексклюзивний капелюх на ваш вибір! + Використовуйте останні відео драйвери щоб уникнути проблем під час гри. + Ви можете знайти файли конфігурації Hedgewars в "My Documents\Hedgewars". Ви можете створити резервні копії або взяти файли з собою, але не редагуйте їх. + Ви можете зв'язати відповідні файли Hedgewars (файли збереження та демо-записи) з грою щоб запускати їх з вашої улюбленої теки чи інтернет-браузеру. + Хочете заощадити мотузки? Випустіть мотузку в повітря а потім знову стріляйте. Поки ви не торкнулись грунту ви можете знову використовувати мотузку, не витрачаючи боєприпаси! + Ви можете знайти файли конфігурації Hedgewars в "Library/Application Support/Hedgewars" в домашній теці. Ви можете створити резервні копії або взяти файли з собою, але не редагуйте їх. + Ви можете знайти файли конфігурації Hedgewars в ".hedgewars" в домашній теці. Ви можете створити резервні копії або взяти файли з собою, але не редагуйте їх. + Використайте Коктейль Молотова або Вогнемет щоб тимчасово утримати їжаків від проходження такої місцевості як тунелі або платформи. + Навідна Бджілка може бути складною у керуванні. Радіус повороту залежить від її швидкості, тому постарайтеся не стріляти на повну силу. + + Windows-версія Hedgewars підтримує Xfire. Переконайтеся в тому, що ви додали Hedgewars до списку ігор, щоб ваші друзі могли бачити вас в грі. + + diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tr.lua --- a/share/hedgewars/Data/Locale/tr.lua Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/tr.lua Sat Jan 04 23:55:54 2014 +0400 @@ -26,10 +26,10 @@ -- ["All gone...everything!"] = "", -- A_Classic_Fairytale:enemy -- ["All right, we just need to get to the other side of the island!"] = "", -- A_Classic_Fairytale:journey -- ["All walls touched!"] = "", -- WxW - ["Ammo Depleted!"] = "Munition erschöpft!", - ["ammo extended!"] = "Munition aufgestockt!", - ["Ammo is reset at the end of your turn."] = "Munition wird am Ende des Spielzuges zurückgesetzt.", - ["Ammo Maniac!"] = "Munitionsverrückter!", + ["Ammo Depleted!"] = "Mermi Bitti!", + ["ammo extended!"] = "mermi genişletildi!", + ["Ammo is reset at the end of your turn."] = "Mermi turunun sonunda sıfırlanır.", + ["Ammo Maniac!"] = "Mermi Manyağı!", ["Ammo"] = "Mermi", -- ["And how am I alive?!"] = "", -- A_Classic_Fairytale:enemy -- ["And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."] = "", -- A_Classic_Fairytale:first_blood @@ -53,35 +53,35 @@ -- ["As you can see, there is no way to get on the other side!"] = "", -- A_Classic_Fairytale:dragon -- ["Attack From Rope"] = "", -- WxW -- ["Australia"] = "", -- Continental_supplies - ["Available points remaining: "] = "Verfügbare Punkte verbleibend:", + ["Available points remaining: "] = "Halan kullanılabilir puanlar: ", -- ["Back Breaker"] = "", -- A_Classic_Fairytale:backstab -- ["Back in the village, after telling the villagers about the threat..."] = "", -- A_Classic_Fairytale:united -- ["[Backspace]"] = "", -- ["Backstab"] = "", -- A_Classic_Fairytale:backstab -- ["Bad Team"] = "", -- User_Mission_-_The_Great_Escape -- ["Bamboo Thicket"] = "", - ["Barrel Eater!"] = "Fassfresser!", - ["Barrel Launcher"] = "Fasswerfer", + ["Barrel Eater!"] = "Varilsever!", + ["Barrel Launcher"] = "Varil Patlatıcı", -- ["Baseballbat"] = "", -- Continental_supplies - ["Bat balls at your enemies and|push them into the sea!"] = "Schlage Bälle auf deine Widersacher|und lass sie ins Meer fallen!", - ["Bat your opponents through the|baskets and out of the map!"] = "Schlage deine Widersacher durch|die Körbe und aus der Karte hinaus!", - ["Bazooka Training"] = "Bazooka-Training", + ["Bat balls at your enemies and|push them into the sea!"] = "Düşmanlarına sopayla vur|ve denize dök!", + ["Bat your opponents through the|baskets and out of the map!"] = "Düşmanlarını sepetlere vurarak|harita dışına at!", + ["Bazooka Training"] = "Roketatar Eğitimi", -- ["Beep Loopers"] = "", -- A_Classic_Fairytale:queen - ["Best laps per team: "] = "Beste Rundenzeiten pro Team: ", - ["Best Team Times: "] = "Beste Team-Zeiten: ", + ["Best laps per team: "] = "Her takım için en iyi tur: ", + ["Best Team Times: "] = "En İyi Takım Süresi: ", -- ["Beware, though! If you are slow, you die!"] = "", -- A_Classic_Fairytale:dragon -- ["Biomechanic Team"] = "", -- 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"] = "Blutige Anfänger", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree + ["Bloody Rookies"] = "Kanlı Acemiler", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree -- ["Bone Jackson"] = "", -- A_Classic_Fairytale:backstab -- ["Bonely"] = "", -- A_Classic_Fairytale:shadow ["Boom!"] = "Bumm!", - ["BOOM!"] = "KABUMM!", - ["Boss defeated!"] = "Boss wurde besiegt!", - ["Boss Slayer!"] = "Boss-Töter!", + ["BOOM!"] = "BUMM!", + ["Boss defeated!"] = "Patron öldürüldü!", + ["Boss Slayer!"] = "Patron Katili!", -- ["Brain Blower"] = "", -- A_Classic_Fairytale:journey -- ["Brainiac"] = "", -- A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:shadow -- ["Brainila"] = "", -- A_Classic_Fairytale:united @@ -89,7 +89,7 @@ -- ["Brain Teaser"] = "", -- A_Classic_Fairytale:backstab -- ["Brutal Lily"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil -- ["Brutus"] = "", -- A_Classic_Fairytale:backstab - ["Build a track and race."] = "Konstruiere eine Strecke und mach ein Wettrennen.", + ["Build a track and race."] = "Bir yol inşa et ve yarış.", -- ["Bullseye"] = "", -- A_Classic_Fairytale:dragon -- ["But it proved to be no easy task!"] = "", -- A_Classic_Fairytale:dragon -- ["But that's impossible!"] = "", -- A_Classic_Fairytale:backstab @@ -103,16 +103,16 @@ -- ["Cannibals"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood -- ["Cannibal Sentry"] = "", -- A_Classic_Fairytale:journey -- ["Cannibals?! You're the cannibals!"] = "", -- A_Classic_Fairytale:enemy - ["CAPTURE THE FLAG"] = "EROBERE DIE FAHNE", - ["Careless"] = "Achtlos", + ["CAPTURE THE FLAG"] = "BAYRAĞI YAKALA", + ["Careless"] = "Dikkatsiz", -- ["Carol"] = "", -- A_Classic_Fairytale:family -- ["CHALLENGE COMPLETE"] = "", -- User_Mission_-_RCPlane_Challenge - ["Change Weapon"] = "Waffenwechsel", + ["Change Weapon"] = "Silahı Değiştir", -- ["Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."] = "", -- A_Classic_Fairytale:shadow - ["Clumsy"] = "Hoppla", + ["Clumsy"] = "Sakar", -- ["Cluster Bomb MASTER!"] = "", -- Basic_Training_-_Cluster_Bomb -- ["Cluster Bomb Training"] = "", -- Basic_Training_-_Cluster_Bomb - ["Codename: Teamwork"] = "Code-Name: Teamwork", + ["Codename: Teamwork"] = "Kodadı: Takım Çalışması", -- ["Collateral Damage"] = "", -- A_Classic_Fairytale:journey -- ["Collateral Damage II"] = "", -- A_Classic_Fairytale:journey -- ["Collect all the crates, but remember, our time in this life is limited!"] = "", -- A_Classic_Fairytale:first_blood @@ -121,16 +121,16 @@ -- ["Collect the crates within the time limit!|If you fail, you'll have to try again."] = "", -- A_Classic_Fairytale:first_blood -- ["Come closer, so that your training may continue!"] = "", -- A_Classic_Fairytale:first_blood -- ["Compete to use as few planes as possible!"] = "", -- User_Mission_-_RCPlane_Challenge - ["Complete the track as fast as you can!"] = "Durchlaufe die Strecke so schnell du kannst!", + ["Complete the track as fast as you can!"] = "Yolu mümkün olduğunca hızlı tamamla!", -- ["COMPLETION TIME"] = "", -- User_Mission_-_Rope_Knock_Challenge -- ["Configuration accepted."] = "", -- WxW -- ["Congratulations"] = "", -- Basic_Training_-_Rope - ["Congratulations!"] = "Gratulation!", + ["Congratulations!"] = "Tebrikler!", -- ["Congratulations! You needed only half of time|to eliminate all targets."] = "", -- Basic_Training_-_Cluster_Bomb -- ["Congratulations! You've completed the Rope tutorial! |- Tutorial ends in 10 seconds!"] = "", -- Basic_Training_-_Rope - ["Congratulations! You've eliminated all targets|within the allowed time frame."] = "Gratulation! Du hast alle Ziele innerhalb der|verfügbaren Zeit ausgeschaltet.", --Bazooka, Shotgun, SniperRifle + ["Congratulations! You've eliminated all targets|within the allowed time frame."] = "Tebrikler! Tüm hedefleri|belirtilen sürede yendin.", --Bazooka, Shotgun, SniperRifle -- ["Continental supplies"] = "", -- Continental_supplies - ["Control pillars to score points."] = "Kontrolliere die Säulen um Punkte zu erhalten.", + ["Control pillars to score points."] = "Puan toplamak için sütunları denetle.", -- ["Corporationals"] = "", -- A_Classic_Fairytale:queen -- ["Corpsemonger"] = "", -- A_Classic_Fairytale:shadow -- ["Corpse Thrower"] = "", -- A_Classic_Fairytale:epil @@ -138,21 +138,21 @@ ["Cybernetic Empire"] = "Kybernetisches Imperium", -- ["Cyborg. It's what the aliens call themselves."] = "", -- A_Classic_Fairytale:enemy -- ["Dahmer"] = "", -- A_Classic_Fairytale:backstab - ["DAMMIT, ROOKIE! GET OFF MY HEAD!"] = "VERDAMMT, REKRUT! RUNTER VON MEINEM KOPF!", - ["DAMMIT, ROOKIE!"] = "VERDAMMT, REKRUT!", + ["DAMMIT, ROOKIE! GET OFF MY HEAD!"] = "LANET OLSUN ACEMİ! DEFOL BAŞIMDAN!", + ["DAMMIT, ROOKIE!"] = "LANET OLSUN ACEMİ!", -- ["Dangerous Ducklings"] = "", - ["Deadweight"] = "Gravitus", + ["Deadweight"] = "Graviton", -- ["Defeat the cannibals"] = "", -- A_Classic_Fairytale:backstab -- ["Defeat the cannibals!|"] = "", -- A_Classic_Fairytale:united -- ["Defeat the cannibals!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "", -- A_Classic_Fairytale:shadow -- ["Defeat the cyborgs!"] = "", -- A_Classic_Fairytale:enemy -- ["Defend yourself!|Hint: You can get tips on using weapons by moving your mouse over them in the weapon selection menu"] = "", -- A_Classic_Fairytale:shadow - ["Demolition is fun!"] = "Zerstörung macht Spaß!", + ["Demolition is fun!"] = "Yok etmek eğlencelidir!", -- ["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 - ["Depleted Kamikaze!"] = "Munitionsloses Kamikaze!", + ["Depleted Kamikaze!"] = "Boşa yapılmış Kamikaze!", -- ["Destroy him, Leaks A Lot! He is responsible for the deaths of many of us!"] = "", -- A_Classic_Fairytale:first_blood - ["Destroy invaders to score points."] = "Zerstöre die Angreifer um Punkte zu erhalten.", + ["Destroy invaders to score points."] = "Puan kazanmak için istilacıları yok et.", -- ["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 -- ["Did anyone follow you?"] = "", -- A_Classic_Fairytale:united @@ -172,7 +172,7 @@ -- ["Drills"] = "", -- A_Classic_Fairytale:backstab -- ["Drone Hunter!"] = "", -- ["Drop a bomb: [drop some heroic wind that will turn into a bomb on impact]"] = "", -- Continental_supplies - ["Drowner"] = "Absäufer", + ["Drowner"] = "Boğulucu", -- ["Dude, all the plants are gone!"] = "", -- A_Classic_Fairytale:family -- ["Dude, can you see Ramon and Spiky?"] = "", -- A_Classic_Fairytale:journey -- ["Dude, that's so cool!"] = "", -- A_Classic_Fairytale:backstab @@ -182,15 +182,15 @@ -- ["Dude, wow! I just had the weirdest high!"] = "", -- A_Classic_Fairytale:backstab -- ["Duration"] = "", -- Continental_supplies -- ["Dust storm: [Deals 20 damage to all enemies in the circle]"] = "", -- Continental_supplies - ["Each turn you get 1-3 random weapons"] = "Du bekommst jede Runde 1-3 zufällig gewählte Waffen", - ["Each turn you get one random weapon"] = "Du bekommst jede Runde eine zufällig gewählte Waffe.", + ["Each turn you get 1-3 random weapons"] = "Her turda 1-3 rastgele silah alacaksın", + ["Each turn you get one random weapon"] = "Her turda bir adet rastgele silah alacaksın", -- ["Eagle Eye"] = "", -- A_Classic_Fairytale:backstab -- ["Eagle Eye: [Blink to the impact ~ one shot]"] = "", -- Continental_supplies -- ["Ear Sniffer"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:epil -- ["Elderbot"] = "", -- A_Classic_Fairytale:family -- ["Elimate your captor."] = "", -- User_Mission_-_The_Great_Escape - ["Eliminate all enemies"] = "Vernichte alle Gegner", - ["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Eliminiere alle Ziele bevor die Zeit ausläuft.|Du hast in dieser Mission unbegrenzte Munition.", --Bazooka, Shotgun, SniperRifle + ["Eliminate all enemies"] = "Tüm düşmanı yoket", + ["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Süren dolmadan tüm hedefleri yoket.|Bu görevde sınırsız mermin var.", --Bazooka, Shotgun, SniperRifle -- ["Eliminate enemy hogs and take their weapons."] = "", -- Highlander ["Eliminate Poison before the time runs out"] = "Neutralisiere das Gift bevor die Zeit abgelaufen ist", ["Eliminate the Blue Team"] = "Lösche das Blaue Team aus", diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Locale/tr.txt --- a/share/hedgewars/Data/Locale/tr.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Locale/tr.txt Sat Jan 04 23:55:54 2014 +0400 @@ -451,8 +451,10 @@ 03:51=Zeminde bulunan 03:52=KULLANILMIYOR 03:53=Tür 40 -03:54=Bir şey inşa et -03:55=Yardımcı +; 03:54=Bir şey inşa et +03:54=Yardımcı +03:55=Bundan daha iyi olamazdı! +03:56=Lütfen yanlış veya doğru, kullanın ; Weapon Descriptions (use | as line breaks) 04:00=Düşmanlarına basit el bombası ile saldır.|Zamanlayıcı sıfır olduğunda patlayacak.|1-5: Bomba süresini ayarla|Saldır: Daha fazla güçte atmak için basılı tut @@ -511,6 +513,7 @@ 04:53=Arkadaşlarını savaşta yalnız bırakarak|zaman ve uzaya seyahat et.|Herhangi bir an, Ani Ölüm veya tümü|ölmüşse geri gelmeye hazır ol.|Yadsıma: Ani Ölüm kipinde, tek isen veya|Kralsan çalışmaz. 04:54=TAM DEĞİL 04:55=Yapışkan tanecikler püskürt.|Köprü yap, düşmanı göm, tünelleri kapat.|Dikkatli ol sana gelmesin! +04:56=İki satırı düşmanına atabilir, geçişleri|ve tünelleri kapatabilir,|hatta tırmanmak için bile|kullanabilirsin!|Dikkatli ol! Bıçakla oynamak tehlikeli!|Saldır: Daha yüksek hızda atmak için basılı tut (iki kez) ; Game goal strings 05:00=Oyun Kipleri diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Maps/TrophyRace/map.lua --- a/share/hedgewars/Data/Maps/TrophyRace/map.lua Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Maps/TrophyRace/map.lua Sat Jan 04 23:55:54 2014 +0400 @@ -29,144 +29,173 @@ -- active hog reached the goal? local reached = false --- hog with best time -local besthog = nil -local besthogteam = "" - -- hog with worst time (per round) local worsthog = nil +local besthog = nil + -- best time local besttime = maxtime + 1 +-- best time per team +local bestTimes = {} + -- worst time (per round) local worsttime = 0 +local startTime = 0; function onGameInit() - GameFlags = gfSolidLand + gfInvulnerable - TurnTime = maxtime - CaseFreq = 0 - MinesNum = 0 - Explosives = 0 - Delay = 500 - SuddenDeathTurns = 99999 -- "disable" sudden death - Theme = 'Olympics' + GameFlags = gfSolidLand + gfInvulnerable + TurnTime = maxtime + CaseFreq = 0 + MinesNum = 0 + Explosives = 0 + Delay = 500 + SuddenDeathTurns = 99999 -- "disable" sudden death + Theme = 'Olympics' end function onGameStart() - ShowMission(loc("TrophyRace"), "", loc("Use your rope to get from start to finish as fast as you can!"), -amRope, 0) - started = true - p=1820 - for i = 0, numhhs - 1 do - p = p + 50 - SetGearPosition(hhs[i], p, 0) - end - - for i=0, ClansCount-1 do - clantimes[i] = 0 - end + ShowMission(loc("TrophyRace"), "", loc("Use your rope to get from start to finish as fast as you can!"), -amRope, 0) + started = true + p=1820 + for i = 0, numhhs - 1 do + p = p + 50 + SetGearPosition(hhs[i], p, 0) + end + + for i=0, ClansCount-1 do + clantimes[i] = 0 + end end function onAmmoStoreInit() - SetAmmo(amRope, 9, 2, 0) + SetAmmo(amRope, 9, 1, 0) + SetAmmo(amSkip, 9, 1, 0) +end + +function killHog() + SetHealth(CurrentHedgehog, 0) + SetEffect(CurrentHedgehog, heInvulnerable, 0) + x, y = GetGearPosition(CurrentHedgehog) + AddGear(x, y, gtShell, 0, 0, 0, 0) + worsttime = 99999 + worsthog = nil + lasthog = nil +end + +function onHogAttack() + if TurnTimeLeft == 0 then + killHog() + end +end + +function onNewTurn() + if lasthog ~= nil then + SetGearPosition(lasthog, p , 0) + if not reached then + end + end + startTime = 0 + reached = false + if CurrentHedgehog ~= nil then + SetGearVelocity(CurrentHedgehog, 1, 0) + SetGearPosition(CurrentHedgehog, start_area[1] + start_area[3] / 2, start_area[2] + start_area[4] / 2) + ParseCommand("setweap " .. string.char(amRope)) + lasthog = CurrentHedgehog + end end -function onGameTick20() - if CurrentHedgehog ~= nil and TurnTimeLeft <= 20 and TurnTimeLeft > 0 then - SetHealth(CurrentHedgehog, 0) - x, y = GetGearPosition(CurrentHedgehog) - AddGear(x, y, gtShell, 0, 0, 0, 0) - worsttime = 99999 - worsthog = nil - elseif TurnTimeLeft > maxtime - 25 and CurrentHedgehog ~= nil then - if lasthog ~= nil then - SetGearPosition(lasthog, p , 0) - end - reached = false - SetGearVelocity(CurrentHedgehog, 1, 0) - SetGearPosition(CurrentHedgehog, start_area[1] + start_area[3] / 2, start_area[2] + start_area[4] / 2) - ParseCommand("setweap " .. string.char(amRope)) - lasthog = CurrentHedgehog - elseif CurrentHedgehog ~= nil then - x, y = GetGearPosition(CurrentHedgehog) - if not reached and x > goal_area[1] and x < goal_area[1] + goal_area[3] and y > goal_area[2] and y < goal_area[2] + goal_area[4] then -- hog is within goal rectangle - reached = true - local ttime = maxtime - TurnTimeLeft - --give it a sound;) - if ttime < besttime then - PlaySound (sndHomerun) - else - PlaySound (sndHellish) - end - for i = 0, numhhs - 1 do - if hhs[i] == CurrentHedgehog then - times[numhhs] = ttime - end - end - - local hscore = "| |" - local clan = GetHogClan(CurrentHedgehog) - if ttime < clantimes[clan] or clantimes[clan] == 0 then - clantimes[clan] = ttime - end - - if ttime < besttime then - besttime = ttime - besthog = CurrentHedgehog - besthogteam = GetHogTeamName(besthog) - hscore = hscore .. loc("NEW fastest lap: ") - else - hscore = hscore .. loc("Fastest lap: ") - end - if ttime > worsttime then - worsttime = ttime - worsthog = CurrentHedgehog - end - hscore = hscore .. GetHogName(besthog) .. " - " .. (besttime / 1000) .. " s | |" .. loc("Best laps per team: ") - - if clan == ClansCount -1 then - -- Time for elimination - worst hog is out and the worst hog vars are reset. - SetHealth(worsthog, 0) - --Place a grenade to make inactive slowest hog active - x, y = GetGearPosition(worsthog) - AddGear(x, y, gtShell, 0, 0, 0, 0) - worsttime = 0 - worsthog = nil - end - - for i=0, ClansCount -1 do - local tt = "" .. (clantimes[i] / 1000) .. " s" - if clantimes[i] == 0 then - tt = "--" - end - hscore = hscore .. "|" .. string.format(loc("Team %d: "), i+1) .. tt - end - - ShowMission(loc("TrophyRace"), "", loc("You've reached the goal!| |Time: ") .. (ttime / 1000) .. " s" .. hscore, 0, 0) - TurnTimeLeft = 0 - end - end +function onGameTick() + if startTime == 0 and TurnTimeLeft < maxtime then + startTime = GameTime + end + if CurrentHedgehog ~= nil and TurnTimeLeft == 1 then + killHog() + elseif CurrentHedgehog ~= nil then + x, y = GetGearPosition(CurrentHedgehog) + if not reached and x > goal_area[1] and x < goal_area[1] + goal_area[3] and y > goal_area[2] and y < goal_area[2] + goal_area[4] then -- hog is within goal rectangle + reached = true + local ttime = GameTime-startTime + --give it a sound;) + if ttime < besttime then + PlaySound (sndHomerun) + else + PlaySound (sndHellish) + end + for i = 0, numhhs - 1 do + if hhs[i] == CurrentHedgehog then + times[numhhs] = ttime + end + end + + local hscore = "| |" + local clan = GetHogClan(CurrentHedgehog) + if ttime < clantimes[clan] or clantimes[clan] == 0 then + clantimes[clan] = ttime + end + local teamname = GetHogTeamName(CurrentHedgehog) + if bestTimes[teamname] == nil or bestTimes[teamname] > ttime then + bestTimes[teamname] = ttime + end + if ttime < besttime then + besttime = ttime + besthog = CurrentHedgehog + hscore = hscore .. loc("NEW fastest lap: ") + else + hscore = hscore .. loc("Fastest lap: ") + end + if ttime > worsttime then + worsttime = ttime + worsthog = CurrentHedgehog + end + hscore = hscore .. GetHogName(besthog) .. " - " .. (besttime / 1000) .. " s | |" .. loc("Best laps per team: ") + + if clan == ClansCount -1 then + -- Time for elimination - worst hog is out and the worst hog vars are reset. + if worsthog ~= nil then + SetHealth(worsthog, 0) + --Place a grenade to make inactive slowest hog active + x, y = GetGearPosition(worsthog) + AddGear(x, y, gtShell, 0, 0, 0, 0) + worsttime = 0 + worsthog = nil + end + end + + for i=0, ClansCount -1 do + local tt = "" .. (clantimes[i] / 1000) .. " s" + if clantimes[i] == 0 then + tt = "--" + end + hscore = hscore .. "|" .. string.format(loc("Team %d: "), i+1) .. tt + end + + ShowMission(loc("TrophyRace"), "", loc("You've reached the goal!| |Time: ") .. (ttime / 1000) .. " s" .. hscore, 0, 0) + TurnTimeLeft = 0 + end + end end function onGearAdd(gear) - if GetGearType(gear) == gtHedgehog then - hhs[numhhs] = gear - times[numhhs] = 0 - numhhs = numhhs + 1 - end --- elseif GetGearType(gear) == gtRope then -- rope is shot + if GetGearType(gear) == gtHedgehog then + hhs[numhhs] = gear + times[numhhs] = 0 + numhhs = numhhs + 1 + end +-- elseif GetGearType(gear) == gtRope then -- rope is shot end --function onGearDelete(gear) --- if GetGearType(gear) == gtRope then -- rope deletion - hog didn't manage to rerope --- --TurnTimeLeft = 0 -- end turn or not? hm... --- lasthog = CurrentHedgehog --- --- end +-- if GetGearType(gear) == gtRope then -- rope deletion - hog didn't manage to rerope +-- --TurnTimeLeft = 0 -- end turn or not? hm... +-- lasthog = CurrentHedgehog +-- +-- end --end function onAchievementsDeclaration() - if besthog ~= nil then - DeclareAchievement("rope race", besthogteam, "TrophyRace", besttime) + for team,time in pairs(bestTimes) do + DeclareAchievement("rope race", team, "TrophyRace", time) end end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/campaign.ini --- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/campaign.ini Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/campaign.ini Sat Jan 04 23:55:54 2014 +0400 @@ -2,41 +2,41 @@ ResetRetry=1 [Mission 1] -Name=First Blood +Name=Mission 1: First Blood Script=first_blood.lua [Mission 2] -Name=The Shadow Falls +Name=Mission 2: The Shadow Falls Script=shadow.lua [Mission 3] -Name=The Journey Back +Name=Mission 3: The Journey Back Script=journey.lua [Mission 4] -Name=United We Stand +Name=Mission 4: United We Stand Script=united.lua [Mission 5] -Name=Backstab +Name=Mission 5: Backstab Script=backstab.lua [Mission 6] -Name=Dragon's Lair +Name=Mission 6: Dragon's Lair Script=dragon.lua [Mission 7] -Name=Family Reunion +Name=Mission 7: Family Reunion Script=family.lua [Mission 8] -Name=Long Live The Queen +Name=Mission 8: Long Live The Queen Script=queen.lua [Mission 9] -Name=The Enemy Of My Enemy +Name=Mission 9: The Enemy Of My Enemy Script=enemy.lua [Mission 10] -Name=Epilogue +Name=Mission 10: Epilogue Script=epil.lua diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/first_blood.lua diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/journey.lua diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/CMakeLists.txt Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,9 @@ +file(GLOB Config *.ini) +file(GLOB Missions *.lua) +file(GLOB Packs *.hwp) + +install(FILES + ${Config} + ${Missions} + ${Packs} + DESTINATION "${SHAREPATH}Data/Missions/Campaign/A_Space_Adventure") diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/campaign.ini --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/campaign.ini Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,58 @@ +MissionNum=5 +ResetRetry=1 + +[Mission 1] +Name=Menu: Spacetrip +Script=cosmos.lua + +[Mission 2] +Name=Main Mission: The first stop +Script=moon01.lua + +[Mission 3] +Name=Main Mission: Bad timing +Script=fruit01.lua + +[Mission 4] +Name=Main Mission: Searching in the dust +Script=desert01.lua + +[Mission 5] +Name=Main Mission: A frozen adventure +Script=ice01.lua + +[Mission 6] +Name=Side Mission: Hard flying +Script=ice02.lua + +[Mission 7] +Name=Side Mission: Running for survival +Script=desert02.lua + +[Mission 8] +Name=Main Mission: Getting to the device +Script=fruit02.lua + +[Mission 9] +Name=Main Mission: The last encounter +Script=death01.lua + +[Mission 10] +Name=Side Mission: Precise shooting +Script=fruit03.lua + +[Mission 11] +Name=Side Mission: Killing the specialists +Script=death02.lua + +[Mission 12] +Name=Side Mission: Precise flying +Script=desert03.lua + +[Mission 13] +Name=Side Mission: Chasing the blue hog +Script=moon02.lua + +[Mission 14] +Name=Main Mission: The big bang +Script=final.lua diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,609 @@ +------------------- ABOUT ---------------------- +-- +-- This map works as a menu for the hero hog to +-- navigate through planets. It portrays the hogs +-- planet and above the planets that he'll later +-- visit. + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Spacetrip") +local timeForGuard1ToTurn = 1000 * 5 -- 5 sec +local timeForGuard1ToTurnLeft = timeForGuard1ToTurn +local saucerAcquired = false +local status +local checkPointReached = 1 -- 1 is start of the game +local objectives = loc("Go to the moon by using the flying saucer and complete the main mission").."|".. +loc("Come back to this mission and visit the other planets to collect the crates").."|".. +loc("Visit the Death Planet after completing all the other planets' main missions").."|".. +loc("Come back to this mission after collecting all the device parts") +-- dialogs +local dialog01 = {} +local dialog02 = {} +local dialog03 = {} +local dialog04 = {} +local dialog05 = {} +local dialog06 = {} +local dialog07 = {} +local dialog08 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Getting ready"), loc("Go and collect the crate").."|"..loc("Try not to get spotted by the guards!"), 1, 4500}, + [dialog02] = {missionName, loc("The adventure begins!"), loc("Use the saucer and fly to the moon").."|"..loc("Travel carefully as your fuel is limited"), 1, 4500}, + [dialog03] = {missionName, loc("An unexpected event!"), loc("Use the saucer and fly away").."|"..loc("Beware, any damage taken will stay until you complete the moon's main mission"), 1, 7000}, + [dialog04] = {missionName, loc("Objectives"), objectives, 1, 7000}, + [dialog05] = {missionName, loc("Objectives"), objectives, 1, 7000}, + [dialog06] = {missionName, loc("Objectives"), objectives, 1, 7000}, + [dialog07] = {missionName, loc("Searching the stars!"), loc("Use the saucer and fly away").."|"..loc("Visit the planets of Ice, Desert and Fruit before you proceed to the Death Planet"), 1, 6000}, + [dialog08] = {missionName, loc("Saving Hogera"), loc("Fly to the meteorite and detonate the explosives"), 1, 7000} +} +-- crates +local saucerX = 3270 +local saucerY = 1500 +-- hogs +local hero = {} +local director = {} +local doctor = {} +local guard1 = {} +local guard2 = {} +-- teams +local teamA = {} +local teamB = {} +local teamC = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 1450 +hero.y = 1550 +director.name = loc("H") +director.x = 1350 +director.y = 1550 +doctor.name = loc("Dr.Cornelius") +doctor.x = 1300 +doctor.y = 1550 +guard1.name = loc("Bob") +guard1.x = 3350 +guard1.y = 1800 +guard1.turn = false +guard1.keepTurning = true +guard2.name = loc("Sam") +guard2.x = 3400 +guard2.y = 1800 +teamA.name = loc("PAotH") +teamA.color = tonumber("FF0000",16) -- red +teamB.name = loc("Guards") +teamB.color = tonumber("0033FF",16) -- blue +teamC.name = loc("Hog Solo") +teamC.color = tonumber("38D61C",16) -- green + +-------------- LuaAPI EVENT HANDLERS ------------------ +function onGameInit() + Seed = 35 + GameFlags = gfSolidLand + gfDisableWind + TurnTime = 40000 + CaseFreq = 0 + MinesNum = 0 + Explosives = 0 + Delay = 5 + -- completed main missions + status = getCompletedStatus() + if status.death01 then + Map = "cosmos2_map" + else + Map = "cosmos_map" -- custom map included in file + end + Theme = "Nature" + -- I had originally hero in PAotH team and changed it, may reconsider though + -- PAotH + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + HogTurnLeft(hero.gear, true) + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + director.gear = AddHog(director.name, 0, 100, "hair_yellow") + AnimSetGearPosition(director.gear, director.x, director.y) + doctor.gear = AddHog(doctor.name, 0, 100, "Glasses") + AnimSetGearPosition(doctor.gear, doctor.x, doctor.y) + -- Guards + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + guard1.gear = AddHog(guard1.name, 1, 100, "policecap") + AnimSetGearPosition(guard1.gear, guard1.x, guard1.y) + guard2.gear = AddHog(guard2.name, 1, 100, "policecap") + AnimSetGearPosition(guard2.gear, guard2.x, guard2.y) + -- get the check point + if tonumber(GetCampaignVar("CosmosCheckPoint")) then + checkPointReached = tonumber(GetCampaignVar("CosmosCheckPoint")) + end + -- do checkpoint stuff needed before game starts + if checkPointReached == 1 then + -- Start of the game + elseif checkPointReached == 2 then + -- Hero on the column, just took space ship unnoticed + AnimSetGearPosition(hero.gear, saucerX, saucerY) + elseif checkPointReached == 3 then + -- Hero near column, without space ship unnoticed + elseif checkPointReached == 4 then + -- Hero visited moon for fuels + AnimSetGearPosition(hero.gear, 1110, 850) + elseif checkPointReached == 5 then + -- Hero has visited a planet, he has plenty of fuels and can change planet + if GetCampaignVar("Planet") == "moon" then + AnimSetGearPosition(hero.gear, 1110, 850) + elseif GetCampaignVar("Planet") == "desertPlanet" then + AnimSetGearPosition(hero.gear, 3670, 270) + elseif GetCampaignVar("Planet") == "fruitPlanet" then + AnimSetGearPosition(hero.gear, 2400, 375) + elseif GetCampaignVar("Planet") == "icePlanet" then + AnimSetGearPosition(hero.gear, 1440, 260) + elseif GetCampaignVar("Planet") == "deathPlanet" then + AnimSetGearPosition(hero.gear, 620, 530) + elseif GetCampaignVar("Planet") == "meteorite" then + AnimSetGearPosition(hero.gear, 3080, 850) + end + end + + AnimInit() + AnimationSetup() +end + +function onGameStart() + -- wait for the first turn to start + AnimWait(hero.gear, 3000) + + FollowGear(hero.gear) + ShowMission(loc("Spacetrip"), loc("Getting ready"), loc("Help Hog Solo to find all the parts of the anti-gravity device.").. + "|"..loc("Travel to all the neighbor planets and collect all the pieces"), -amSkip, 0) + + -- do checkpoint stuff needed after game starts + if checkPointReached == 1 then + AddAnim(dialog01) + AddAmmo(hero.gear, amRope, 1) + AddAmmo(guard1.gear, amDEagle, 2) + AddAmmo(guard2.gear, amDEagle, 2) + SpawnAmmoCrate(saucerX, saucerY, amJetpack) + -- EVENT HANDLERS + AddEvent(onHeroBeforeTreePosition, {hero.gear}, heroBeforeTreePosition, {hero.gear}, 0) + AddEvent(onHeroAtSaucerPosition, {hero.gear}, heroAtSaucerPosition, {hero.gear}, 0) + AddEvent(onHeroOutOfGuardSight, {hero.gear}, heroOutOfGuardSight, {hero.gear}, 0) + elseif checkPointReached == 2 then + AddAmmo(hero.gear, amJetpack, 1) + AddAnim(dialog02) + elseif checkPointReached == 3 then + -- Hero near column, without space ship unnoticed + elseif checkPointReached == 4 then + -- Hero visited moon for fuels + AddAnim(dialog05) + elseif checkPointReached == 5 then + -- Hero has visited a planet, he has plenty of fuels and can change planet + AddAmmo(hero.gear, amJetpack, 99) + end + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onNoFuelAtLand, {hero.gear}, noFuelAtLand, {hero.gear}, 0) + -- always check for landings + if GetCampaignVar("Planet") ~= "moon" then + AddEvent(onMoonLanding, {hero.gear}, moonLanding, {hero.gear}, 0) + end + if GetCampaignVar("Planet") ~= "desertPlanet" then + AddEvent(onDesertPlanetLanding, {hero.gear}, desertPlanetLanding, {hero.gear}, 0) + end + if GetCampaignVar("Planet") ~= "fruitPlanet" then + AddEvent(onFruitPlanetLanding, {hero.gear}, fruitPlanetLanding, {hero.gear}, 0) + end + if GetCampaignVar("Planet") ~= "icePlanet" then + AddEvent(onIcePlanetLanding, {hero.gear}, icePlanetLanding, {hero.gear}, 0) + end + if GetCampaignVar("Planet") ~= "deathPlanet" then + AddEvent(onDeathPlanetLanding, {hero.gear}, deathPlanetLanding, {hero.gear}, 0) + end + + if status.death01 and not status.final then + AddAnim(dialog08) + if GetCampaignVar("Planet") ~= "meteorite" then + AddEvent(onMeteoriteLanding, {hero.gear}, meteoriteLanding, {hero.gear}, 0) + end + end + + SendHealthStatsOff() +end + +function onGameTick() + -- maybe alert this to avoid timeForGuard1ToTurnLeft overflow + if timeForGuard1ToTurnLeft == 0 and guard1.keepTurning then + guard1.turn = not guard1.turn + HogTurnLeft(guard1.gear, guard1.turn) + timeForGuard1ToTurnLeft = timeForGuard1ToTurn + end + timeForGuard1ToTurnLeft = timeForGuard1ToTurnLeft - 1 + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGameTick20() + setFoundDeviceVisual() +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +function onAmmoStoreInit() + SetAmmo(amJetpack, 0, 0, 0, 1) +end + +function onNewTurn() + if CurrentHedgehog == director.gear or CurrentHedgehog == doctor.gear then + TurnTimeLeft = 0 + end + if guard1.keepTurning then + AnimSwitchHog(hero.gear) + TurnTimeLeft = -1 + end +end + +-------------- EVENTS ------------------ + +function onHeroBeforeTreePosition(gear) + if GetHealth(hero.gear) and GetX(gear) > 2350 then + return true + end + return false +end + +function onHeroAtSaucerPosition(gear) + if GetHealth(hero.gear) and GetX(gear) >= saucerX-25 and GetX(gear) <= saucerX+32 and GetY(gear) >= saucerY-32 and GetY(gear) <= saucerY+32 then + saucerAcquired = true + end + if saucerAcquired and GetHealth(hero.gear) and StoppedGear(gear) then + return true + end + return false +end + +function onHeroOutOfGuardSight(gear) + if GetHealth(hero.gear) and GetX(gear) < 3100 and GetY(gear) > saucerY-25 and StoppedGear(gear) and not guard1.keepTurning then + return true + end + return false +end + +function onMoonLanding(gear) + if GetHealth(hero.gear) and GetX(gear) > 1010 and GetX(gear) < 1220 and GetY(gear) < 1300 and GetY(gear) > 750 and StoppedGear(gear) then + return true + end + return false +end + +function onFruitPlanetLanding(gear) + if GetHealth(hero.gear) and GetX(gear) > 2240 and GetX(gear) < 2540 and GetY(gear) < 1100 and StoppedGear(gear) then + return true + end + return false +end + +function onDesertPlanetLanding(gear) + if GetHealth(hero.gear) and GetX(gear) > 3568 and GetX(gear) < 4052 and GetY(gear) < 500 and StoppedGear(gear) then + return true + end + return false +end + +function onIcePlanetLanding(gear) + if GetHealth(hero.gear) and GetX(gear) > 1330 and GetX(gear) < 1650 and GetY(gear) < 500 and StoppedGear(gear) then + return true + end + return false +end + +function onDeathPlanetLanding(gear) + if GetHealth(hero.gear) and GetX(gear) > 280 and GetX(gear) < 700 and GetY(gear) < 720 and StoppedGear(gear) then + return true + end + return false +end + +function onMeteoriteLanding(gear) + if GetHealth(hero.gear) and GetX(gear) > 2990 and GetX(gear) < 3395 and GetY(gear) < 940 and StoppedGear(gear) then + return true + end + return false +end + +function onNoFuelAtLand(gear) + if checkPointReached > 1 and GetHealth(hero.gear) and GetY(gear) > 1400 and + GetAmmoCount(gear, amJetpack) == 0 and StoppedGear(gear) then + return true + end + return false +end + +function onHeroDeath(gear) + if not GetHealth(hero.gear) then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function heroBeforeTreePosition(gear) + AnimSay(gear,loc("Now I have to climb these trees"), SAY_SAY, 4000) + AnimCaption(hero.gear, loc("Use the rope to get to the crate"), 4000) +end + +function heroAtSaucerPosition(gear) + TurnTimeLeft = 0 + -- save check point + SaveCampaignVar("CosmosCheckPoint", "2") + checkPointReached = 2 + AddAnim(dialog02) + -- check if he was spotted by the guard + if guard1.turn and GetX(hero.gear) > saucerX-150 then + guard1.keepTurning = false + AddAnim(dialog03) + end +end + +function heroOutOfGuardSight(gear) + guard1.keepTurning = true + AddAnim(dialog04) +end + +function moonLanding(gear) + if checkPointReached == 1 then + -- player climbed the moon with rope + FollowGear(doctor.gear) + AnimSay(doctor.gear, loc("One cannot simply walk in moon with rope!"), SAY_SHOUT, 4000) + SendStat(siGameResult, loc("This is the wrong way!")) + SendStat(siCustomAchievement, loc("Collect the crate with the flying saucer")) + SendStat(siCustomAchievement, loc("Fly to the moon")) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() + else + if checkPointReached ~= 5 then + SaveCampaignVar("CosmosCheckPoint", "4") + SaveCampaignVar("HeroHealth",GetHealth(hero.gear)) + end + AnimCaption(hero.gear,loc("Welcome to the moon!")) + SaveCampaignVar("HeroHealth", GetHealth(hero.gear)) + SaveCampaignVar("Planet", "moon") + SaveCampaignVar("UnlockedMissions", "3") + SaveCampaignVar("Mission1", "2") + SaveCampaignVar("Mission2", "13") + SaveCampaignVar("Mission3", "1") + sendStats(loc("the moon")) + end +end + +function fruitPlanetLanding(gear) + if checkPointReached < 5 then + AddAnim(dialog06) + else + AnimCaption(hero.gear,loc("Welcome to the Fruit Planet!")) + SaveCampaignVar("Planet", "fruitPlanet") + if status.fruit02 then + SaveCampaignVar("UnlockedMissions", "4") + SaveCampaignVar("Mission1", "3") + SaveCampaignVar("Mission2", "8") + SaveCampaignVar("Mission3", "10") + SaveCampaignVar("Mission4", "1") + else + SaveCampaignVar("UnlockedMissions", "3") + SaveCampaignVar("Mission1", "3") + SaveCampaignVar("Mission2", "10") + SaveCampaignVar("Mission3", "1") + end + sendStats(loc("the Fruit Planet")) + end +end + +function desertPlanetLanding(gear) + if checkPointReached < 5 then + AddAnim(dialog06) + else + AnimCaption(hero.gear,loc("Welcome to the Desert Planet!")) + SaveCampaignVar("Planet", "desertPlanet") + SaveCampaignVar("UnlockedMissions", "4") + SaveCampaignVar("Mission1", "4") + SaveCampaignVar("Mission2", "7") + SaveCampaignVar("Mission3", "12") + SaveCampaignVar("Mission4", "1") + sendStats(loc("the Desert Planet")) + end +end + +function icePlanetLanding(gear) + if checkPointReached < 5 then + AddAnim(dialog06) + else + AnimCaption(hero.gear,loc("Welcome to the Planet of Ice!")) + SaveCampaignVar("Planet", "icePlanet") + SaveCampaignVar("UnlockedMissions", "3") + SaveCampaignVar("Mission1", "5") + SaveCampaignVar("Mission2", "6") + SaveCampaignVar("Mission3", "1") + sendStats(loc("the Ice Planet")) + end +end + +function deathPlanetLanding(gear) + if checkPointReached < 5 then + AddAnim(dialog06) + elseif not (status.fruit02 and status.ice01 and status.desert01) then + AddAnim(dialog07) + else + AnimCaption(hero.gear,loc("Welcome to the Death Planet!")) + SaveCampaignVar("Planet", "deathPlanet") + SaveCampaignVar("UnlockedMissions", "3") + SaveCampaignVar("Mission1", "9") + SaveCampaignVar("Mission2", "11") + SaveCampaignVar("Mission3", "1") + sendStats(loc("the Planet of Death")) + end +end + +function meteoriteLanding(gear) + -- first two conditionals are not possible but I'll leave it there... + if checkPointReached < 5 then + AddAnim(dialog06) + elseif not (status.fruit02 and status.ice01 and status.desert01) then + AddAnim(dialog07) + else + AnimCaption(hero.gear,loc("Welcome to the meteorite!")) + SaveCampaignVar("Planet", "meteorite") + SaveCampaignVar("UnlockedMissions", "2") + SaveCampaignVar("Mission1", "14") + SaveCampaignVar("Mission2", "1") + sendStats(loc("the meteorite")) + end +end + +function noFuelAtLand(gear) + AddAnim(dialog06) +end + +function heroDeath(gear) + sendStatsOnRetry() +end + +function setFoundDeviceVisual() + --WriteLnToConsole("status: "..status.fruit01.." - "..status.fruit02) + if status.moon01 then + vgear = AddVisualGear(1116, 848, vgtBeeTrace, 0, false) + + end + if status.ice01 then + vgear = AddVisualGear(1512, 120, vgtBeeTrace, 0, false) + + end + if status.desert01 then + vgear = AddVisualGear(4015, 316, vgtBeeTrace, 0, false) + + end + if status.fruit01 and status.fruit02 then + vgear = AddVisualGear(2390, 384, vgtBeeTrace, 0, false) + + end + if status.death01 then + vgear = AddVisualGear(444, 400, vgtBeeTrace, 0, false) + + end + if status.final then + vgear = AddVisualGear(3070, 810, vgtBeeTrace, 0, false) + + end +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + if CurrentHedgehog ~= hero.gear and anim ~= dialog03 then + AnimSwitchHog(hero.gear) + elseif anim == dialog03 then + startCombat() + elseif anim == dialog05 or anim == dialog06 then + sendStatsOnRetry() + end +end + +function AnimationSetup() + -- DIALOG 01 - Start + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {doctor.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Near secret base 17 of PAotH in the rural Hogland..."), 4000}}) + table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("So Hog Solo, here we are..."), SAY_SAY, 2000}}) + table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Behind these trees on the east side there is secret base 17"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("You have to continue alone from now on."), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Be careful, the future of Hogera is in your hands!"), SAY_SAY, 7200}}) + table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("We'll use our communicators to contact you"), SAY_SAY, 2600}}) + table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("In am also entrusting you with some rope"), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("You may find it handy"), SAY_SAY, 2300}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Thank you Dr.Cornelius"), SAY_SAY, 1600}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I'll make good use of it"), SAY_SAY, 4500}}) + table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("It would be wiser to steal the space ship while PAotH guards are taking a brake!"), SAY_SAY, 7000}}) + table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Remember! Many will seek the anti-gravity device! Now go, hurry up!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG 02 - Hero got the saucer + AddSkipFunction(dialog02, Skipanim, {dialog02}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("CheckPoint reached!"), 4000}}) + table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("Got the saucer!"), SAY_SHOUT, 2000}}) + table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Nice!"), SAY_SHOUT, 1000}}) + table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Now use it and go to the moon PAotH station to get more fuel!"), SAY_SHOUT, 5000}}) + table.insert(dialog02, {func = AnimGearWait, args = {hero.gear, 500}}) + -- DIALOG 03 - Hero got spotted by guard + AddSkipFunction(dialog03, Skipanim, {dialog03}) + table.insert(dialog03, {func = AnimWait, args = {guard1.gear, 4000}}) + table.insert(dialog03, {func = AnimCaption, args = {guard1.gear, loc("Prepare to flee!"), 4000}}) + table.insert(dialog03, {func = AnimSay, args = {guard1.gear, loc("Hey").." "..guard2.name.."! "..loc("Look, someone is stealing the saucer!"), SAY_SHOUT, 4000}}) + table.insert(dialog03, {func = AnimSay, args = {guard2.gear, loc("I'll get him!"), SAY_SAY, 4000}}) + table.insert(dialog03, {func = startCombat, args = {guard1.gear}}) + -- DIALOG 04 - Hero out of sight + AddSkipFunction(dialog04, Skipanim, {dialog04}) + table.insert(dialog04, {func = AnimCaption, args = {guard1.gear, loc("You are out of danger, time to go to the moon!"), 4000}}) + table.insert(dialog04, {func = AnimSay, args = {guard1.gear, loc("I guess we lost him!"), SAY_SAY, 3000}}) + table.insert(dialog04, {func = AnimSay, args = {guard2.gear, loc("We should better report this and continue our watch!"), SAY_SAY, 5000}}) + table.insert(dialog04, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG 05 - Hero returned from moon without fuels + AddSkipFunction(dialog05, Skipanim, {dialog05}) + table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("I guess I can't go far without fuels!"), SAY_THINK, 6000}}) + table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("Go to go back"), SAY_THINK, 2000}}) + table.insert(dialog05, {func = sendStatsOnRetry, args = {hero.gear}}) + -- DIALOG 06 - Landing on wrong planet or on earth if not enough fuels + AddSkipFunction(dialog06, Skipanim, {dialog06}) + table.insert(dialog06, {func = AnimCaption, args = {hero.gear, loc("You have to try again!"), 5000}}) + table.insert(dialog06, {func = AnimSay, args = {hero.gear, loc("Hm... Now I ran out of fuel..."), SAY_THINK, 3000}}) + table.insert(dialog06, {func = sendStatsOnRetry, args = {hero.gear}}) + -- DIALOG 07 - Hero lands on Death Planet but isn't allowed yet to play this map + AddSkipFunction(dialog07, Skipanim, {dialog07}) + table.insert(dialog07, {func = AnimCaption, args = {hero.gear, loc("This planet seems dangerous!"), 5000}}) + table.insert(dialog07, {func = AnimSay, args = {hero.gear, loc("I am not ready for this planet yet. I should visit it when I have found all the other device parts"), SAY_THINK, 4000}}) + -- DIALOG 08 - Hero wins death01 + AddSkipFunction(dialog08, Skipanim, {dialog08}) + table.insert(dialog08, {func = AnimCaption, args = {hero.gear, loc("Under the meteorite shadow..."), 4000}}) + table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("You did great Hog Solo! However we aren't out of danger yet!"), SAY_SHOUT, 4500}}) + table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("The meteorite has come too close and the anti-gravity device isn't powerful enough to stop it now"), SAY_SHOUT, 5000}}) + table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("We need it to get split into at least two parts"), SAY_SHOUT, 3000}}) + table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("PAotH has sent explosives but unfortunately the trigger mechanism seems to be faulty!"), SAY_SHOUT, 5000}}) + table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("We need you to go there and detonate them yourself! Good luck!"), SAY_SHOUT, 500}}) + table.insert(dialog08, {func = AnimWait, args = {doctor.gear, 3000}}) + table.insert(dialog08, {func = AnimSwitchHog, args = {hero.gear}}) +end + +------------------- custom "animation" functions -------------------------- + +function startCombat() + -- use this so guard2 will gain control + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 +end + +function sendStats(planet) + SendStat(siGameResult, loc("Hog Solo arrived at "..planet)) + SendStat(siCustomAchievement, loc("Return to the mission menu by pressing the \"Go back\" button")) + SendStat(siCustomAchievement, loc("You can choose another planet by replaying this mission")) + SendStat(siCustomAchievement, loc("Planets with completed main missions will be marked with a flower")) + SendStat(siPlayerKills,'1',teamC.name) + EndGame() +end + +function sendStatsOnRetry() + SendStat(siGameResult, loc("You have to travel again")) + SendStat(siCustomAchievement, loc("Your first destination is the moon in order to get more fuel")) + SendStat(siCustomAchievement, loc("You have to complete the main mission on moon in order to travel to other planets")) + SendStat(siCustomAchievement, loc("You have to be careful and not die!")) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death01.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death01.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death01.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death01.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,319 @@ +------------------- ABOUT ---------------------- +-- +-- This is the mission to acquire the last part. +-- This mission is the cameo of Professor Hogevil +-- who has took hostages H and Dr. Cornelius. +-- Hog Solo has to defeat him and his thugs. + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("The last encounter") +-- dialogs +local dialog01 = {} +-- missions objectives +local goals = { + [dialog01] = {missionName, loc("The final part"), loc("Defeat Professor Hogevil!"), 1, 4500}, +} +-- crates +local teleportCrate = {x = 1935, y = 1830} +local drillCrate = {x = 3810, y = 1705} +local batCrate = {x = 1975, y = 1830} +local blowtorchCrate = {x = 1520, y = 1950} +local cakeCrate = {x = 325, y = 1500} +local ropeCrate = {x = 1860, y = 500} +local pickHammerCrate = {x = 1900, y = 400} +-- hogs +local hero = {} +local paoth1 = {} +local paoth2 = {} +local professor = {} +local thug1 = {} +local thug2 = {} +local thug3 = {} +local thug4 = {} +local thug5 = {} +local thug6 = {} +local thug7 = {} +local thugs = { thug1, thug2, thug3, thug4, thug5, thug6, thug7 } +-- teams +local teamA = {} +local teamB = {} +local teamC = {} +-- hedgehogs values +hero.name = "Hog Solo" +hero.x = 520 +hero.y = 845 +hero.dead = false +paoth1.name = "H" +paoth1.x = 3730 +paoth1.y = 1480 +paoth2.name = "Dr.Cornelius" +paoth2.x = 3800 +paoth2.y = 1480 +professor.name = "Prof. Hogevil" +professor.dead = false +thug1.x = 1265 +thug1.y = 1400 +thug1.health = 70 +thug2.x = 2035 +thug2.y = 1320 +thug2.health = 95 +thug3.x = 1980 +thug3.y = 815 +thug3.health = 35 +thug3.turnLeft = true +thug4.x = 2830 +thug4.y = 1960 +thug4.health = 80 +thug5.x = 2890 +thug5.y = 1960 +thug5.health = 80 +thug6.x = 2940 +thug6.y = 1960 +thug6.health = 80 +thug7.x = 2990 +thug7.y = 1960 +thug7.health = 80 +teamA.name = loc("Hog Solo") +teamA.color = tonumber("38D61C",16) -- green +teamB.name = loc("PAotH") +teamB.color = tonumber("0033FF",16) -- blue because otherwise enemies attack them +teamC.name = loc("Professor") +teamC.color = tonumber("0033FF",16) -- blue + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + Seed = 1 + TurnTime = 25000 + CaseFreq = 0 + MinesNum = 3 + MinesTime = 1500 + Explosives = 2 + Delay = 3 + HealthCaseAmount = 50 + SuddenDeathTurns = 100 + Map = "death01_map" + Theme = "Hell" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + -- PAotH + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + paoth1.gear = AddHog(paoth1.name, 0, 100, "hair_yellow") + AnimSetGearPosition(paoth1.gear, paoth1.x, paoth1.y) + HogTurnLeft(paoth1.gear, true) + paoth2.gear = AddHog(paoth2.name, 0, 100, "Glasses") + AnimSetGearPosition(paoth2.gear, paoth2.x, paoth2.y) + HogTurnLeft(paoth2.gear, true) + -- Professor and Thugs + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + professor.human = AddHog(professor.name, 0, 300, "tophats") + AnimSetGearPosition(professor.human, hero.x + 70, hero.y) + HogTurnLeft(professor.human, true) + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + professor.bot = AddHog(professor.name, 1, 300, "tophats") + AnimSetGearPosition(professor.bot, paoth1.x - 100, paoth1.y) + HogTurnLeft(professor.bot, true) + professor.gear = professor.bot + for i=1,table.getn(thugs) do + thugs[i].gear = AddHog(loc("thug").." #"..i, 1, thugs[i].health, "war_desertgrenadier1") + AnimSetGearPosition(thugs[i].gear, thugs[i].x, thugs[i].y) + HogTurnLeft(thugs[i].gear, not thugs[i].turnLeft) + end + + initCheckpoint("death01") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onEnemiesDeath, {hero.gear}, enemiesDeath, {hero.gear}, 0) + + -- add crates + SpawnAmmoCrate(teleportCrate.x, teleportCrate.y, amTeleport) + SpawnAmmoCrate(drillCrate.x, drillCrate.y, amTeleport) + SpawnAmmoCrate(drillCrate.x, drillCrate.y, amDrill) + SpawnAmmoCrate(batCrate.x, batCrate.y, amBaseballBat) + SpawnAmmoCrate(blowtorchCrate.x, blowtorchCrate.y, amBlowTorch) + SpawnAmmoCrate(cakeCrate.x, cakeCrate.y, amCake) + SpawnAmmoCrate(ropeCrate.x, ropeCrate.y, amRope) + SpawnAmmoCrate(pickHammerCrate.x, pickHammerCrate.y, amPickHammer) + SpawnHealthCrate(cakeCrate.x + 40, cakeCrate.y) + SpawnHealthCrate(blowtorchCrate.x + 40, blowtorchCrate.y) + -- add explosives + AddGear(1900, 850, gtExplosives, 0, 0, 0, 0) + AddGear(1900, 800, gtExplosives, 0, 0, 0, 0) + AddGear(1900, 750, gtExplosives, 0, 0, 0, 0) + AddGear(1900, 710, gtExplosives, 0, 0, 0, 0) + -- add mines + AddGear(3520, 1650, gtMine, 0, 0, 0, 0) + AddGear(3480, 1680, gtMine, 0, 0, 0, 0) + AddGear(3440, 1690, gtMine, 0, 0, 0, 0) + AddGear(3400, 1710, gtMine, 0, 0, 0, 0) + AddGear(2100, 1730, gtMine, 0, 0, 0, 0) + AddGear(2150, 1730, gtMine, 0, 0, 0, 0) + AddGear(2200, 1750, gtMine, 0, 0, 0, 0) + -- add girders + PlaceGirder(3770, 1370, 4) + PlaceGirder(3700, 1460, 6) + PlaceGirder(3840, 1460, 6) + + -- add ammo + -- hero ammo + AddAmmo(hero.gear, amRope, 2) + AddAmmo(hero.gear, amBazooka, 3) + AddAmmo(hero.gear, amParachute, 1) + AddAmmo(hero.gear, amGrenade, 6) + AddAmmo(hero.gear, amDEagle, 4) + AddAmmo(hero.gear, amSkip, 100) + local bonus = tonumber(getBonus(3)) + if bonus > 0 then + SetHealth(hero.gear, 120) + AddAmmo(hero.gear, amLaserSight, 1) + saveBonus(3, bonus-1) + end + -- evil ammo + AddAmmo(professor.gear, amRope, 4) + AddAmmo(professor.gear, amBazooka, 8) + AddAmmo(professor.gear, amSwitch, 100) + AddAmmo(professor.gear, amGrenade, 8) + AddAmmo(professor.gear, amDEagle, 8) + + HideHog(professor.bot) + AddAnim(dialog01) + + SendHealthStatsOff() +end + +function onNewTurn() + if CurrentHedgehog == paoth1.gear or CurrentHedgehog == paoth2.gear then + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 + end +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onAmmoStoreInit() + SetAmmo(amCake, 0, 0, 0, 1) + SetAmmo(amTeleport, 0, 0, 0, 1) + SetAmmo(amBaseballBat, 0, 0, 0, 4) + SetAmmo(amBlowTorch, 0, 0, 0, 1) + SetAmmo(amRope, 0, 0, 0, 2) + SetAmmo(amPickHammer, 0, 0, 0, 1) + SetAmmo(amDrill, 0, 0, 0, 1) +end + +function onGearDelete(gear) + if gear == hero.gear then + hero.dead = true + elseif gear == professor.gear then + professor.dead = true + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +function onEnemiesDeath(gear) + local allDead = true + if GetHealth(hero.gear) and professor.dead then + for i=1,table.getn(thugs) do + if GetHealth(thugs[i]) then + allDead = false + break + end + end + else + allDead = false + end + return allDead +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("To win the game you have to eliminate all your enemies")) + SendStat(siPlayerKills,'1',teamC.name) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end + +function enemiesDeath(gear) + saveCompletedStatus(6) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("You have successfully eliminated Professor Hogevil")) + SendStat(siCustomAchievement, loc("You have rescued H and Dr.Cornelius")) + SendStat(siCustomAchievement, loc("You have acquired the last device part")) + SendStat(siCustomAchievement, loc("Now go and play the menu mission to complete the campaign")) + SendStat(siPlayerKills,'1',teamA.name) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + startBattle() +end + +function AnimationSetup() + -- DIALOG01, GAME START, INTRODUCTION + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere in the uninhabitable Death Planet..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("Welcome Hog Solo, surprised to see me?"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("As you can see I have survived our last encounter and I had time to plot my master plan!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("I've thought that the best way to get the device is to let you collect most of the parts for me!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("So, now I got the last part and I have your friends captured..."), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("Will you give me the other parts?"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I will never hand you the parts!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimWait, args = {professor.human, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("Then prepare for battle!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = startBattle, args = {}}) +end + +-------------- OTHER FUNCTIONS ----------------- + +function startBattle() + DeleteGear(professor.human) + RestoreHog(professor.bot) + AnimSwitchHog(professor.gear) + TurnTimeLeft = 0 +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death02.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death02.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death02.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death02.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,292 @@ +------------------- ABOUT ---------------------- +-- +-- Hero has been surrounded my some space villains +-- He has to defeat them in order to escape + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Killing the specialists") +local challengeObjectives = loc("Use your available weapons in order to eliminate the enemies").."|".. + loc("Each time you play this missions enemy hogs will play in a random order").."|".. + loc("At the start of the game each enemy hog has only the weapon that he is named after").."|".. + loc("A random hedgehog will inherit the weapons of his deceased team-mates").."|".. + loc("If you kill a hedgehog with the respective weapon your health points will be set to 100").."|".. + loc("If you injure a hedgehog you'll get 35% of the damage dealt").."|".. + loc("Every time you kill an enemy hog your ammo will get reset").."|".. + loc("Rope won't get reset") +-- dialogs +local dialog01 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500}, +} +-- hogs +local hero = { + name = loc("Hog Solo"), + x = 850, + y = 460, + mortarAmmo = 2, + firepunchAmmo = 1, + deagleAmmo = 4, + bazookaAmmo = 2, + grenadeAmmo = 4, +} +local enemies = { + { name = loc("Mortar"), x = 1890, y = 520, weapon = amMortar, additionalWeapons = {}}, + { name = loc("Desert Eagle"), x = 1390, y = 790, weapon = amDEagle, additionalWeapons = {}}, + { name = loc("Grenade"), x = 186, y = 48, weapon = amGrenade, additionalWeapons = {}}, + { name = loc("Shoryuken"), x = 330, y = 270, weapon = amFirePunch, additionalWeapons = {}}, + { name = loc("Bazooka"), x = 1950, y = 150, weapon = amBazooka, additionalWeapons = {}}, +} +-- teams +local teamA = { + name = loc("Hog Solo"), + color = tonumber("38D61C",16) -- green +} +local teamB = { + name = loc("5 deadly hogs"), + color = tonumber("FF0000",16) -- red +} + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + Seed = 1 + TurnTime = 25000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Map = "death02_map" + Theme = "Hell" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + -- enemies + shuffleHogs(enemies) + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + for i=1,table.getn(enemies) do + enemies[i].gear = AddHog(enemies[i].name, 1, 100, "war_desertgrenadier1") + AnimSetGearPosition(enemies[i].gear, enemies[i].x, enemies[i].y) + end + + initCheckpoint("death02") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0) + + --hero ammo + AddAmmo(hero.gear, amSkip, 100) + AddAmmo(hero.gear, amRope, 2) + refreshHeroAmmo() + + SendHealthStatsOff() + AddAnim(dialog01) +end + +function onNewTurn() + if CurrentHedgehog ~= hero.gear then + enemyWeapons() + end +end + +function onGearDelete(gear) + if isHog(gear) then + SetHealth(hero.gear, 100) + local deadHog = getHog(gear) + if deadHog.weapon == amMortar then + hero.mortarAmmo = 0 + elseif deadHog.weapon == amFirePunch then + hero.firepunchAmmo = 0 + elseif deadHog.weapon == amDEagle then + hero.deagleAmmo = 0 + elseif deadHog.weapon == amBazooka then + hero.bazookaAmmo = 0 + elseif deadHog.weapon == amGrenade then + hero.grenadeAmmo = 0 + end + local randomHog = GetRandom(table.getn(enemies))+1 + while not GetHealth(enemies[randomHog].gear) do + randomHog = GetRandom(table.getn(enemies))+1 + end + table.insert(enemies[randomHog].additionalWeapons, deadHog.weapon) + for i=1,table.getn(deadHog.additionalWeapons) do + table.insert(enemies[randomHog].additionalWeapons, deadHog.additionalWeapons[i]) + end + refreshHeroAmmo() + end +end + +function onGearDamage(gear, damage) + if isHog(gear) and GetHealth(hero.gear) then + SetHealth(hero.gear, GetHealth(hero.gear) + damage/3) + end +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if not GetHealth(hero.gear) then + return true + end + return false +end + +function onHeroWin(gear) + local allDead = true + for i=1,table.getn(enemies) do + if GetHealth(enemies[i].gear) then + allDead = false + break + end + end + return allDead +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("You have to eliminate all the enemies")) + SendStat(siCustomAchievement, loc("Read the Challenge Objectives from within the mission for more details")) + SendStat(siPlayerKills,'1',teamB.name) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end + +function heroWin(gear) + saveBonus(3, 4) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("You complete the mission in "..TotalRounds.." rounds")) + SendStat(siCustomAchievement, loc("The next 4 times you play the \"The last encounter\" mission you'll get 20 more hit points and a Laser Sight")) + SendStat(siPlayerKills,'1',teamA.name) + EndGame() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + startBattle() +end + +function AnimationSetup() + -- DIALOG 01 - Start, game instructions + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere in the Planet of Death..."), 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("...Hog Solo fights for his life"), 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Each time you play this missions enemy hogs will play in a random order"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("At the start of the game each enemy hog has only the weapon that he is named after"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("A random hedgehog will inherit the weapons of his deceased team-mates"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("If you kill a hedgehog with the respective weapon your health points will be set to 100"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("If you injure a hedgehog you'll get 35% of the damage dealt"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Every time you kill an enemy hog your ammo will get reset"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Rope won't get reset"), 2000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = startBattle, args = {hero.gear}}) +end + +------------ Other Functions ------------------- + +function startBattle() + AnimSwitchHog(hero.gear) + TurnTimeLeft = TurnTime +end + +function shuffleHogs(hogs) + local hogsNumber = table.getn(hogs) + for i=1,hogsNumber do + local randomHog = GetRandom(hogsNumber) + 1 + hogs[i], hogs[randomHog] = hogs[randomHog], hogs[i] + end +end + +function refreshHeroAmmo() + local extraAmmo = 0 + if getAliveEnemiesCount() == 1 then + extraAmmo = 2 + end + AddAmmo(hero.gear, amMortar, hero.mortarAmmo + extraAmmo) + AddAmmo(hero.gear, amFirePunch, hero.firepunchAmmo + extraAmmo) + AddAmmo(hero.gear, amDEagle, hero.deagleAmmo + extraAmmo) + AddAmmo(hero.gear, amBazooka, hero.bazookaAmmo + extraAmmo) + AddAmmo(hero.gear, amGrenade, hero.grenadeAmmo + extraAmmo) +end + +function enemyWeapons() + for i=1,table.getn(enemies) do + if GetHealth(enemies[i].gear) and enemies[i].gear == CurrentHedgehog then + AddAmmo(enemies[i].gear, amMortar, 0) + AddAmmo(enemies[i].gear, amFirePunch, 0) + AddAmmo(enemies[i].gear, amDEagle, 0) + AddAmmo(enemies[i].gear, amBazooka, 0) + AddAmmo(enemies[i].gear, amGrenade, 0) + AddAmmo(enemies[i].gear, enemies[i].weapon, 1) + for w=1,table.getn(enemies[i].additionalWeapons) do + AddAmmo(enemies[i].gear, enemies[i].additionalWeapons[w], 1) + end + end + end +end + +function isHog(gear) + local hog = false + for i=1,table.getn(enemies) do + if gear == enemies[i].gear then + hog = true + break + end + end + return hog +end + +function getHog(gear) + for i=1,table.getn(enemies) do + if gear == enemies[i].gear then + return enemies[i] + end + end +end + +function getAliveEnemiesCount() + local count = 0 + for i=1,table.getn(enemies) do + if GetHealth(enemies[i].gear) then + count = count + 1 + end + end + return count +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert01.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert01.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert01.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert01.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,577 @@ +------------------- ABOUT ---------------------- +-- +-- In the desert planet Hero will have to explore +-- the dunes below the surface and find the hidden +-- crates. It is told that one crate contains the +-- lost part. + +-- Idea: game will be successfully end when the 2 lower crates are collected +-- it would be more defficult (and sadistic) if one should collect *all* the crates + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Scripts/Utils.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local campaignName = loc("A Space Adventure") +local missionName = loc("Searching in the dust") +local heroIsInBattle = false +local ongoingBattle = 0 +local cratesFound = 0 +local checkPointReached = 1 -- 1 is normal spawn +-- dialogs +local dialog01 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Getting ready"), loc("The device part is hidden in one of the crates! Go and get it!").."|".. + loc("Most of the destructible terrain in marked with blue color"), 1, 4500}, +} +-- crates +local btorch1Y = 60 +local btorch1X = 2700 +local btorch2Y = 1900 +local btorch2X = 2150 +local btorch3Y = 980 +local btorch3X = 3260 +local rope1Y = 970 +local rope1X = 3200 +local rope2Y = 1900 +local rope2X = 680 +local rope3Y = 1850 +local rope3X = 2460 +local portalY = 480 +local portalX = 1465 +local girderY = 1630 +local girderX = 3350 +-- win crates +local btorch2 = {} +local girder = {} +-- hogs +local hero = {} +local ally = {} +local smuggler1 = {} +local smuggler2 = {} +local smuggler3 = {} +-- teams +local teamA = {} +local teamB = {} +local teamC = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 1740 +hero.y = 40 +hero.dead = false +ally.name = loc("Chief Sandologist") +ally.x = 1660 +ally.y = 40 +smuggler1.name = loc("Sandy") +smuggler1.x = 400 +smuggler1.y = 235 +smuggler2.name = loc("Spike") +smuggler2.x = 736 +smuggler2.y = 860 +smuggler3.name = loc("Sandstorm") +smuggler3.x = 1940 +smuggler3.y = 1625 +teamA.name = loc("PAotH") +teamA.color = tonumber("FF0000",16) -- red +teamB.name = loc("Smugglers") +teamB.color = tonumber("0033FF",16) -- blues +teamC.name = loc("Hog Solo") +teamC.color = tonumber("38D61C",16) -- green + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + Seed = 1 + TurnTime = 20000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Delay = 3 + HealthCaseAmount = 30 + Map = "desert01_map" + Theme = "Desert" + + -- get the check point + checkPointReached = initCheckpoint("desert01") + -- get hero health + local heroHealth = 100 + if checkPointReached > 1 and tonumber(GetCampaignVar("HeroHealth")) then + heroHealth = tonumber(GetCampaignVar("HeroHealth")) + end + + -- Hog Solo + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, heroHealth, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + HogTurnLeft(hero.gear, true) + -- PAotH undercover scientist and chief Sandologist + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + ally.gear = AddHog(ally.name, 0, 100, "Cowboy") + AnimSetGearPosition(ally.gear, ally.x, ally.y) + -- Smugglers + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + smuggler1.gear = AddHog(smuggler1.name, 1, 100, "hair_orange") + AnimSetGearPosition(smuggler1.gear, smuggler1.x, smuggler1.y) + smuggler2.gear = AddHog(smuggler2.name, 1, 100, "lambda") + AnimSetGearPosition(smuggler2.gear, smuggler2.x, smuggler2.y) + smuggler3.gear = AddHog(smuggler3.name, 1, 100, "beefeater") + AnimSetGearPosition(smuggler3.gear, smuggler3.x, smuggler3.y) + + if checkPointReached == 1 then + -- Start of the game + elseif checkPointReached == 2 then + AnimSetGearPosition(hero.gear, 1050, 615) + HogTurnLeft(hero.gear, true) + elseif checkPointReached == 3 then + AnimSetGearPosition(hero.gear, 1680, 920) + HogTurnLeft(hero.gear, true) + elseif checkPointReached == 4 then + AnimSetGearPosition(hero.gear, 1160, 1180) + elseif checkPointReached == 5 then + local positions = GetCampaignVar("HogsPosition") + positions = split(positions,",") + local x + local y + if positions[1] then + x = positions[1] + y = positions[2] + else + -- this should *NEVER* happen, remove? + x = girderX+40 + y = girderY-30 + end + AnimSetGearPosition(hero.gear, x, y) + end + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onHeroAtFirstBattle, {hero.gear}, heroAtFirstBattle, {hero.gear}, 1) + AddEvent(onHeroAtCheckpoint4, {hero.gear}, heroAtCheckpoint4, {hero.gear}, 0) + AddEvent(onHeroAtThirdBattle, {hero.gear}, heroAtThirdBattle, {hero.gear}, 0) + AddEvent(onCheckForWin1, {hero.gear}, checkForWin1, {hero.gear}, 0) + AddEvent(onCheckForWin2, {hero.gear}, checkForWin2, {hero.gear}, 0) + AddEvent(onCrateDestroyed, {hero.gear}, crateDestroyed, {hero.gear}, 0) + + -- smugglers ammo + AddAmmo(smuggler1.gear, amBazooka, 2) + AddAmmo(smuggler1.gear, amGrenade, 2) + AddAmmo(smuggler1.gear, amDEagle, 2) + AddAmmo(smuggler3.gear, amRope, 2) + + -- spawn crates + SpawnAmmoCrate(btorch2X, btorch2Y, amBlowTorch) + SpawnAmmoCrate(btorch3X, btorch3Y, amBlowTorch) + SpawnAmmoCrate(rope1X, rope1Y, amRope) + SpawnAmmoCrate(rope2X, rope2Y, amRope) + SpawnAmmoCrate(rope3X, rope3Y, amRope) + SpawnAmmoCrate(portalX, portalY, amPortalGun) + SpawnAmmoCrate(girderX, girderY, amGirder) + + SpawnHealthCrate(3300, 970) + + -- adding mines - BOOM! + AddGear(1280, 460, gtMine, 0, 0, 0, 0) + AddGear(270, 460, gtMine, 0, 0, 0, 0) + AddGear(3460, 60, gtMine, 0, 0, 0, 0) + AddGear(3500, 240, gtMine, 0, 0, 0, 0) + AddGear(3410, 670, gtMine, 0, 0, 0, 0) + AddGear(3450, 720, gtMine, 0, 0, 0, 0) + + local x = 800 + while x < 1630 do + AddGear(x, 900, gtMine, 0, 0, 0, 0) + x = x + GetRandom(13)+8 + end + x = 1890 + while x < 2988 do + AddGear(x, 760, gtMine, 0, 0, 0, 0) + x = x + GetRandom(13)+8 + end + x = 2500 + while x < 3300 do + AddGear(x, 1450, gtMine, 0, 0, 0, 0) + x = x + GetRandom(13)+8 + end + x = 1570 + while x < 2900 do + AddGear(x, 470, gtMine, 0, 0, 0, 0) + x = x + GetRandom(13)+8 + end + + if checkPointReached == 1 then + AddEvent(onHeroFleeFirstBattle, {hero.gear}, heroFleeFirstBattle, {hero.gear}, 1) + AddEvent(onHeroAtCheckpoint2, {hero.gear}, heroAtCheckpoint2, {hero.gear}, 0) + AddEvent(onHeroAtCheckpoint3, {hero.gear}, heroAtCheckpoint3, {hero.gear}, 0) + -- crates + SpawnAmmoCrate(btorch1X, btorch1Y, amBlowTorch) + SpawnHealthCrate(680, 460) + -- hero ammo + AddAmmo(hero.gear, amRope, 2) + AddAmmo(hero.gear, amBazooka, 3) + AddAmmo(hero.gear, amParachute, 1) + AddAmmo(hero.gear, amGrenade, 6) + AddAmmo(hero.gear, amDEagle, 4) + AddAmmo(hero.gear, amRCPlane, tonumber(getBonus(1))) + + AddAnim(dialog01) + elseif checkPointReached == 2 or checkPointReached == 3 then + ShowMission(campaignName, missionName, loc("The device part is hidden in one of the crates! Go and get it!"), -amSkip, 0) + loadHeroAmmo() + + secondBattle() + elseif checkPointReached == 4 or checkPointReached == 5 then + ShowMission(campaignName, missionName, loc("The part device is hidden in one of the crates! Go and get it!"), -amSkip, 0) + loadHeroAmmo() + end + + SendHealthStatsOff() +end + +function onNewTurn() + if CurrentHedgehog ~= hero.gear and not heroIsInBattle then + TurnTimeLeft = 0 + elseif CurrentHedgehog == hero.gear and not heroIsInBattle then + TurnTimeLeft = -1 + elseif (CurrentHedgehog == smuggler2.gear or CurrentHedgehog == smuggler3.gear) and ongoingBattle == 1 then + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 + elseif (CurrentHedgehog == smuggler1.gear or CurrentHedgehog == smuggler3.gear) and ongoingBattle == 2 then + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 + elseif (CurrentHedgehog == smuggler1.gear or CurrentHedgehog == smuggler2.gear) and ongoingBattle == 3 then + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 + elseif CurrentHedgehog == ally.gear then + TurnTimeLeft = 0 + end +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onAmmoStoreInit() + SetAmmo(amBlowTorch, 0, 0, 0, 1) + SetAmmo(amRope, 0, 0, 0, 1) + SetAmmo(amPortalGun, 0, 0, 0, 1) + SetAmmo(amGirder, 0, 0, 0, 3) +end + +function onGearAdd(gear) + if GetGearType(gear) == gtCase then + if GetX(gear) == btorch2X and GetY(gear) == btorch2Y then + btorch2.gear = gear + btorch2.destroyed = false + btorch2.deleted = false + elseif GetX(gear) == girderX and GetY(gear) == girderY then + girder.gear = gear + girder.destroyed = false + girder.deleted = false + end + end +end + +function onGearDamage(gear, damage) + if gear == girder.gear then + girder.destroyed = true + elseif gear == btorch2.gear then + btorch2.destroyed = true + end +end + +function onGearDelete(gear) + if gear == girder.gear then + girder.deleted = true + elseif gear == btorch2.gear then + btorch2.deleted = true + end + if gear == hero.gear then + hero.dead = true + elseif (gear == smuggler1.gear or gear == smuggler2.gear or gear == smuggler3.gear) and heroIsInBattle then + heroIsInBattle = false + ongoingBattle = 0 + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +function onHeroAtFirstBattle(gear) + if not hero.dead and not heroIsInBattle and GetHealth(smuggler1.gear) and GetX(hero.gear) <= 1450 and GetX(hero.gear) > 80 + and GetY(hero.gear) <= GetY(smuggler1.gear)+5 and GetY(hero.gear) >= GetY(smuggler1.gear)-40 and StoppedGear(hero.gear) then + return true + end + return false +end + +function onHeroFleeFirstBattle(gear) + if GetHealth(hero.gear) and GetHealth(smuggler1.gear) and heroIsInBattle + and not gearIsInCircle(smuggler1.gear, GetX(hero.gear), GetY(hero.gear), 1400, false) + and StoppedGear(hero.gear) then + return true + end + return false +end + +-- saves the location of the hero and prompts him for the second battle +function onHeroAtCheckpoint2(gear) + if not hero.dead and GetX(hero.gear) > 1000 and GetX(hero.gear) < 1100 + and GetY(hero.gear) > 590 and GetY(hero.gear) < 700 and StoppedGear(hero.gear) then + return true + end + return false +end + +function onHeroAtCheckpoint3(gear) + if not hero.dead and GetX(hero.gear) > 1610 and GetX(hero.gear) < 1680 + and GetY(hero.gear) > 850 and GetY(hero.gear) < 1000 and StoppedGear(hero.gear) then + return true + end + return false +end + +function onHeroAtCheckpoint4(gear) + if not hero.dead and GetX(hero.gear) > 1110 and GetX(hero.gear) < 1300 + and GetY(hero.gear) > 1100 and GetY(hero.gear) < 1220 then + return true + end + return false +end + +function onHeroAtThirdBattle(gear) + if not hero.dead and GetX(hero.gear) > 2000 and GetX(hero.gear) < 2200 + and GetY(hero.gear) > 1430 and GetY(hero.gear) < 1670 then + return true + end + return false +end + +function onCheckForWin1(gear) + if not hero.dead and not btorch2.destroyed and btorch2.deleted then + return true + end + return false +end + +function onCheckForWin2(gear) + if not hero.dead and not girder.destroyed and girder.deleted then + return true + end + return false +end + +function onCrateDestroyed(gear) + if not hero.dead and girder.destroyed or btorch2.destroyed then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + lose() +end + +function heroAtFirstBattle(gear) + AnimCaption(hero.gear, loc("A smuggler! Prepare for battle"), 5000) + TurnTimeLeft = 0 + heroIsInBattle = true + ongoingBattle = 1 + AnimSwitchHog(smuggler1.gear) + TurnTimeLeft = 0 +end + +function heroFleeFirstBattle(gear) + AnimSay(smuggler1.gear, loc("Run away you coward!"), SAY_SHOUT, 4000) + TurnTimeLeft = 0 + heroIsInBattle = false + ongoingBattle = 0 +end + +function heroAtCheckpoint2(gear) + if GetAmmoCount(hero.gear, amRope) > 0 or GetAmmoCount(hero.gear, amParachute) > 0 then + saveCheckPointLocal("2") + end + secondBattle() +end + +function heroAtCheckpoint3(gear) + if GetAmmoCount(hero.gear, amRope) > 0 then + saveCheckPointLocal("3") + end + secondBattle() +end + +function heroAtCheckpoint4(gear) + saveCheckPointLocal("4") +end + +function heroAtThirdBattle(gear) + heroIsInBattle = true + ongoingBattle = 3 + AnimSay(smuggler3.gear, loc("Who's there?! I'll get you..."), SAY_SHOUT, 5000) + AnimSwitchHog(smuggler3.gear) + TurnTimeLeft = 0 +end + +function crateDestroyed(gear) + lose() +end + +-- for some weird reson I couldn't call the same action for both events +function checkForWin1(gear) + checkForWin() +end + +function checkForWin2(gear) + -- ok lets place one more checkpoint as next part seems challenging without rope + if cratesFound == 0 then + saveCheckPointLocal("5") + SaveCampaignVar("HogsPosition", GetX(hero.gear)..","..GetY(hero.gear)) + end + + checkForWin() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + AnimSwitchHog(hero.gear) + if anim == dialog01 then + startMission() + end +end + +function AnimationSetup() + -- DIALOG 01 - Start, getting info about the device + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("In the Planet of Sand, you have to double check your moves..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Finally you are here..."), SAY_SAY, 2000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 2000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Thank you for meeting me on such a short notice!"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimWait, args = {ally.gear, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("No problem, I would do anything for H!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Now listen carefully! Below us there are tunnels that have been created naturally over the years"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("I have heard that the local tribes say that many years ago some PAotH scientists were dumping their waste here"), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("H confirmed that there isn't such a PAotH activity logged"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("So, I believe that it's a good place to start"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Beware though! Many smugglers come often to explore these tunnels and scavenge whatever valuable items they can find"), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("They won't hesitate to attack you in order to rob you!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 6000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("OK, I'll be extra careful!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimWait, args = {ally.gear, 2000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("There is the tunnel entrance"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Good luck!"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = startMission, args = {hero.gear}}) +end + +--------------- OTHER FUNCTIONS ------------------ + +function startMission() + AnimSwitchHog(ally.gear) + TurnTimeLeft = 0 +end + +function secondBattle() + -- second battle + if heroIsInBattle and ongoingBattle == 1 then + AnimSay(smuggler1.gear, loc("Get him Spike!"), SAY_SHOUT, 4000) + end + heroIsInBattle = true + ongoingBattle = 2 + AnimSay(smuggler2.gear, loc("This is seems like a wealthy hedgehog, nice..."), SAY_THINK, 5000) + AnimSwitchHog(smuggler2.gear) + TurnTimeLeft = 0 +end + +function saveCheckPointLocal(cpoint) + -- save checkpoint + saveCheckpoint(cpoint) + SaveCampaignVar("HeroHealth", GetHealth(hero.gear)) + -- bazooka - grenade - rope - parachute - deagle - btorch - construct - portal - rcplane + SaveCampaignVar("HeroAmmo", GetAmmoCount(hero.gear, amBazooka)..GetAmmoCount(hero.gear, amGrenade).. + GetAmmoCount(hero.gear, amRope)..GetAmmoCount(hero.gear, amParachute)..GetAmmoCount(hero.gear, amDEagle).. + GetAmmoCount(hero.gear, amBlowTorch)..GetAmmoCount(hero.gear, amConstruction).. + GetAmmoCount(hero.gear, amPortalGun)..GetAmmoCount(hero.gear, amRCPlane)) + AnimCaption(hero.gear, loc("Checkpoint reached!"), 5000) +end + +function loadHeroAmmo() + -- hero ammo + local ammo = GetCampaignVar("HeroAmmo") + AddAmmo(hero.gear, amRope, tonumber(ammo:sub(3,3))) + AddAmmo(hero.gear, amBazooka, tonumber(ammo:sub(1,1))) + AddAmmo(hero.gear, amParachute, tonumber(ammo:sub(4,4))) + AddAmmo(hero.gear, amGrenade, tonumber(ammo:sub(2,2))) + AddAmmo(hero.gear, amDEagle, tonumber(ammo:sub(5,5))) + AddAmmo(hero.gear, amBlowTorch, tonumber(ammo:sub(6,6))) + -- weird, if 0 bazooka isn't displayed in the weapons menu + if tonumber(ammo:sub(7,7)) > 0 then + AddAmmo(hero.gear, amConstruction, tonumber(ammo:sub(7,7))) + end + AddAmmo(hero.gear, amPortalGun, tonumber(ammo:sub(8,8))) + AddAmmo(hero.gear, amRCPlane, tonumber(ammo:sub(9,9))) +end + +function checkForWin() + if cratesFound == 0 then + -- have to look more + AnimSay(hero.gear, loc("Haven't found it yet..."), SAY_THINK, 5000) + cratesFound = cratesFound + 1 + elseif cratesFound == 1 then + -- end game + saveCompletedStatus(5) + AnimSay(hero.gear, loc("Hoorah!!!"), SAY_SHOUT, 5000) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("To win the game you had to collect the 2 crates with no specific order")) + SendStat(siPlayerKills,'1',teamC.name) + SendStat(siPlayerKills,'0',teamB.name) + EndGame() + end +end + +function lose() + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("To win the game you have to find the right crate")) + SendStat(siCustomAchievement, loc("You can avoid some battles")) + SendStat(siCustomAchievement, loc("Use your ammo wisely")) + SendStat(siCustomAchievement, loc("Don't destroy the device crate!")) + SendStat(siPlayerKills,'1',teamB.name) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert02.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert02.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert02.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert02.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,187 @@ +------------------- ABOUT ---------------------- +-- +-- Hero has to get to the surface as soon as possible. +-- Tunnel is about to get flooded. + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Running for survival") +local startChallenge = false +-- dialogs +local dialog01 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Getting ready"), loc("Use the rope to quickly get to the surface!"), 1, 4500}, +} +-- health crates +healthX = 565 +health1Y = 1400 +health2Y = 850 +-- hogs +local hero = {} +-- teams +local teamA = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 1600 +hero.y = 1950 +hero.dead = false +teamA.name = loc("Hog Solo") +teamA.color = tonumber("38D61C",16) -- green +-- way points +local current waypoint = 1 +local waypoints = { + [1] = {x=1450, y=140}, + [2] = {x=990, y=580}, + [3] = {x=1650, y=950}, + [4] = {x=620, y=630}, + [5] = {x=1470, y=540}, + [6] = {x=1960, y=60}, + [7] = {x=1600, y=400}, + [8] = {x=240, y=940}, + [9] = {x=200, y=530}, + [10] = {x=1180, y=120}, + [11] = {x=1950, y=660}, + [12] = {x=1280, y=980}, + [13] = {x=590, y=1100}, + [14] = {x=20, y=620}, + [15] = {x=hero.x, y=hero.y} +} + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + GameFlags = gfOneClanMode + Seed = 1 + TurnTime = 8000 + Delay = 2 + CaseFreq = 0 + HealthCaseAmount = 50 + MinesNum = 500 + MinesTime = 1000 + MineDudPercent = 75 + Explosives = 0 + SuddenDeathTurns = 1 + WaterRise = 150 + HealthDecrease = 0 + Map = "desert02_map" + Theme = "Desert" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + HogTurnLeft(hero.gear, true) + + initCheckpoint("desert02") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onHeroSafe, {hero.gear}, heroSafe, {hero.gear}, 0) + + SpawnHealthCrate(healthX, health1Y) + SpawnHealthCrate(healthX, health2Y) + + AddAmmo(hero.gear, amRope, 99) + + SendHealthStatsOff() + AddAnim(dialog01) +end + +function onNewTurn() + ParseCommand("setweap " .. string.char(amRope)) +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGearDelete(gear) + if gear == hero.gear then + hero.dead = true + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +function onHeroSafe(gear) + if not hero.dead and GetY(hero.gear) < 170 and StoppedGear(hero.gear) then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("To win the game you have to go to the surface")) + SendStat(siCustomAchievement, loc("Most mines are not active")) + SendStat(siCustomAchievement, loc("From the second turn and beyond the water rises")) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end + +function heroSafe(gear) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("You have escaped successfully")) + SendStat(siCustomAchievement, loc("Your escape took you "..TotalRounds.." turns")) + SendStat(siPlayerKills,'1',teamA.name) + EndGame() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + challengeStart() +end + +function AnimationSetup() + -- DIALOG 01 - Start + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Many meters below the surface..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("The tunnel is about to get flooded..."), SAY_THINK, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I have to reach the surface as quickly as I can..."), SAY_THINK, 4000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = challengeStart, args = {hero.gear}}) +end + +------------------ Other Functions ------------------- + +function challengeStart() + startChallenge = true + TurnTimeLeft = 0 +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert03.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert03.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert03.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert03.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,226 @@ +------------------- ABOUT ---------------------- +-- +-- Hero has to use the rc plane end perform some +-- flying tasks + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +-- globals +local missionName = loc("Precise flying") +local challengeObjectives = loc("Use the RC plane and destroy the all the targets").."|".. + loc("Each time you destroy all the targets on your current level you'll get teleported to the next level").."|".. + loc("You'll have only one RC plane at the start of the mission").."|".. + loc("During the game you can get new RC planes by collecting the weapon crates") +local currentTarget = 1 +-- dialogs +local dialog01 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500}, +} +-- hogs +local hero = { + name = loc("Hog Solo"), + x = 100, + y = 170 +} +-- teams +local teamA = { + name = loc("Hog Solo"), + color = tonumber("38D61C",16) -- green +} +-- creates & targets +local rcCrates = { + { x = 1680, y = 240}, + { x = 2810, y = 720}, + { x = 2440, y = 660}, + { x = 256, y = 1090}, +} +local targets = { + { x = 2070, y = 410}, + { x = 3880, y = 1430}, + { x = 4000, y = 1430}, + { x = 2190, y = 1160}, + { x = 2190, y = 1460}, + { x = 2110, y = 1700}, + { x = 2260, y = 1700}, + { x = 2085, y = 1330}, + { x = 156, y = 1400}, + { x = 324, y = 1400}, + { x = 660, y = 1310}, + { x = 1200, y = 1310}, + { x = 1700, y = 1310}, +} + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + GameFlags = gfOneClanMode + Seed = 1 + TurnTime = -1 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Map = "desert03_map" + Theme = "Desert" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 1, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + + initCheckpoint("desert03") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onLose, {hero.gear}, lose, {hero.gear}, 0) + + -- original crates and targets + SpawnAmmoCrate(rcCrates[1].x, rcCrates[1].y, amRCPlane) + targets[1].gear = AddGear(targets[1].x, targets[1].y, gtTarget, 0, 0, 0, 0) + + -- hero ammo + AddAmmo(hero.gear, amRCPlane, 1) + + SendHealthStatsOff() + AddAnim(dialog01) +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGameTick20() + checkTargetsDestroyed() +end + +function onAmmoStoreInit() + SetAmmo(amNothing, 0, 0, 0, 0) + SetAmmo(amRCPlane, 0, 0, 0, 1) +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if not GetHealth(hero.gear) then + return true + end + return false +end + +function onLose(gear) + if GetHealth(hero.gear) and currentTarget < 4 and GetAmmoCount(hero.gear, amRCPlane) == 0 then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + gameOver() +end + +function lose(gear) + gameOver() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end +end + +function AnimationSetup() + -- DIALOG 01 - Start, game instructions + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("On the Desert Planet, Hog Solo found some time to play with his RC plane..."), 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Each time you destroy all the targets on your current level you'll get teleported to the next level"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll have only one RC plane at the start of the mission"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("During the game you can get new RC planes by collecting the weapon crates"), 5000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) +end + +----------------- Other Functions ----------------- + +function checkTargetsDestroyed() + if currentTarget == 1 then + if not GetHealth(targets[1].gear) then + AddCaption(loc("Level 1 clear!")) + SetGearPosition(hero.gear, 3590, 90) + currentTarget = 2 + setTargets(currentTarget) + end + elseif currentTarget == 2 then + if not (GetHealth(targets[2].gear) or GetHealth(targets[3].gear)) then + AddCaption(loc("Level 2 clear!")) + SetGearPosition(hero.gear, 1110, 580) + currentTarget = 3 + setTargets(currentTarget) + end + elseif currentTarget == 3 then + + else + win() + end +end + +function setTargets(ct) + if ct == 2 then + SpawnAmmoCrate(rcCrates[2].x, rcCrates[2].y, amRCPlane) + for i=2,3 do + targets[i].gear = AddGear(targets[i].x, targets[i].y, gtTarget, 0, 0, 0, 0) + end + elseif ct == 3 then + SpawnAmmoCrate(rcCrates[3].x, rcCrates[3].y, amRCPlane) + SpawnAmmoCrate(rcCrates[3].x, rcCrates[3].y, amRCPlane) + SpawnAmmoCrate(rcCrates[4].x, rcCrates[4].y, amNothing) + for i=4,13 do + targets[i].gear = AddGear(targets[i].x, targets[i].y, gtTarget, 0, 0, 0, 0) + end + end +end + +function win() + saveBonus(1, 1) + SendStat(siGameResult, loc("Congratulations, you are the best!")) + SendStat(siCustomAchievement, loc("You have destroyed all the targets")) + SendStat(siCustomAchievement, loc("You are indeed the best PAotH pilot")) + SendStat(siCustomAchievement, loc("Next time you play \"Searching in the dust\" you'll have an RC plane available")) + SendStat(siPlayerKills,'1',teamA.name) + EndGame() +end + +function gameOver() + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("You have to destroy all the targets")) + SendStat(siCustomAchievement, loc("You will fail if you run out of ammo and there are still targets available")) + SendStat(siCustomAchievement, loc("Read the Challenge Objectives from within the mission for more details")) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/final.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/final.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/final.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/final.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,158 @@ +------------------- ABOUT ---------------------- +-- +-- Hero has collected all the anti-gravity device +-- parts but because of the size of the meteorite +-- he needs to detonate some faulty explosives that +-- PAotH have previously placed on it. + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("The big bang") +local challengeObjectives = loc("Find a way to detonate all the explosives and stay alive!").."|".. + loc("Red areas are indestructible").."|".. + loc("Green areas aren't portal enabled") +local explosives = {} +local currentHealth = 1 +local currentDamage = 0 +-- hogs +local hero = { + name = loc("Hog Solo"), + x = 790, + y = 70 +} +-- teams +local teamA = { + name = loc("Hog Solo"), + color = tonumber("38D61C",16) -- green +} + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + GameFlags = gfDisableWind + gfOneClanMode + Seed = 1 + TurnTime = -1 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + HealthCaseAmount = 35 + Map = "final_map" + Theme = "EarthRise" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 1, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + + initCheckpoint("final") + + AnimInit() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0) + + -- explosives + x = 400 + while x < 815 do + local gear = AddGear(x, 500, gtExplosives, 0, 0, 0, 0) + x = x + GetRandom(26) + 15 + table.insert(explosives, gear) + end + -- mines + local x = 360 + while x < 815 do + AddGear(x, 480, gtMine, 0, 0, 0, 0) + x = x + GetRandom(16) + 5 + end + -- health crate + SpawnHealthCrate(910, 5) + -- ammo crates + SpawnAmmoCrate(930, 1000,amRCPlane) + SpawnAmmoCrate(1220, 672,amPickHammer) + SpawnAmmoCrate(1220, 672,amGirder) + + -- ammo + AddAmmo(hero.gear, amPortalGun, 1) + AddAmmo(hero.gear, amFirePunch, 1) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0) + + SendHealthStatsOff() +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onAmmoStoreInit() + SetAmmo(amRCPlane, 0, 0, 0, 1) + SetAmmo(amPickHammer, 0, 0, 0, 2) + SetAmmo(amGirder, 0, 0, 0, 1) +end + +function onNewTurn() + currentDamage = 0 + currentHealth = GetHealth(hero.gear) +end + +function onGearDamage(gear, damage) + if gear == hero.gear then + currentDamage = currentDamage + damage + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if not GetHealth(hero.gear) then + return true + end + return false +end + +function onHeroWin(gear) + local win = true + for i=1,table.getn(explosives) do + if GetHealth(explosives[i]) then + win = false + break + end + end + if currentHealth <= currentDamage then + win = false + end + return win +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("You have to destroy all the explosives without dying!")) + SendStat(siCustomAchievement, loc("Red areas are indestructible")) + SendStat(siCustomAchievement, loc("Green areas aren't portal enabled")) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end + +function heroWin(gear) + saveCompletedStatus(7) + SendStat(siGameResult, loc("Congratulations, you have saved Hogera!")) + SendStat(siCustomAchievement, loc("Hogera is safe!")) + SendStat(siPlayerKills,'1',teamA.name) + EndGame() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit01.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit01.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit01.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit01.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,497 @@ +------------------- ABOUT ---------------------- +-- +-- In this adventure hero visits the fruit planet +-- to search for the missing part. However, a war +-- has broke out and hero has to take part or leave. + +-- NOTES: +-- There is an ugly hack out there! I use 2 Captain Limes +-- One in human level and one in bot level +-- I want to have a Captain Lime in human level when the game +-- begins because in animation if the hog is in bot level skip +-- doesn't work - onPrecise() isn't triggered +-- Later I want the hog to take place in the battle in bot level +-- However if I use SetHogLevel I get an error: Engine bug: AI may break demos playing +-- So I have 2 hogs, one in bot level and one in hog level that I hide them +-- or restore them regarding the case + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Bad timing") +local chooseToBattle = false +local previousHog = 0 +local heroPlayedFirstTurn = false +local startBattleCalled = false +-- dialogs +local dialog01 = {} +local dialog02 = {} +local dialog03 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Ready for Battle?"), loc("Walk left if you want to join Captain Lime or right if you want to decline his offer"), 1, 4000}, + [dialog02] = {missionName, loc("Battle Starts Now!"), loc("You have chosen to fight! Lead the Green Bananas to battle and eliminate all the enemies"), 1, 4000}, + [dialog03] = {missionName, loc("Time to run!"), loc("You have chosen to flee... Unfortunately the only place where you can launch your saucer is the left-most place on the map"), 1, 4000}, +} +-- crates +local crateWMX = 2170 +local crateWMY = 1950 +local health1X = 2680 +local health1Y = 916 +-- hogs +local hero = {} +local yellow1 = {} +local green1 = {} +local green2 = {} +local green3 = {} +local green4 = {} +local green5 = {} +-- teams +local teamA = {} +local teamB = {} +local teamC = {} +local teamD = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 3350 +hero.y = 365 +hero.dead = false +green1.name = loc("Captain Lime") +green1.x = 3300 +green1.y = 395 +green1.dead = false +green2.name = loc("Mister Pear") +green2.x = 3600 +green2.y = 1570 +green3.name = loc("Lady Mango") +green3.x = 2170 +green3.y = 980 +green4.name = loc("Green Hog Grape") +green4.x = 2900 +green4.y = 1650 +green5.name = loc("Mr Mango") +green5.x = 1350 +green5.y = 850 +yellow1.name = loc("General Lemon") +yellow1.x = 140 +yellow1.y = 1980 +local yellowArmy = { + {name = loc("Robert Yellow Apple"), x = 710, y = 1780, health = 100}, + {name = loc("Summer Squash"), x = 315 , y = 1960, health = 100}, + {name = loc("Tall Potato"), x = 830 , y = 1748, health = 80}, + {name = loc("Yellow Pepper"), x = 2160 , y = 820, health = 60}, + {name = loc("Corn"), x = 1320 , y = 740, health = 60}, + {name = loc("Max Citrus"), x = 1900 , y = 1700, health = 40}, + {name = loc("Naranja Jed"), x = 960 , y = 516, health = 40}, +} +teamA.name = loc("Hog Solo") +teamA.color = tonumber("38D61C",16) -- green +teamB.name = loc("Green Bananas") +teamB.color = tonumber("38D61C",16) -- green +teamC.name = loc("Yellow Watermelons") +teamC.color = tonumber("DDFF00",16) -- yellow +teamD.name = loc("Captain Lime") +teamD.color = tonumber("38D61C",16) -- green + +function onGameInit() + Seed = 1 + TurnTime = 20000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Delay = 3 + SuddenDeathTurns = 100 + HealthCaseAmount = 50 + Map = "fruit01_map" + Theme = "Fruit" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + HogTurnLeft(hero.gear, true) + -- Captain Lime + AddTeam(teamD.name, teamD.color, "Bone", "Island", "HillBilly", "cm_birdy") + green1.bot = AddHog(green1.name, 1, 200, "war_desertofficer") + AnimSetGearPosition(green1.bot, green1.x, green1.y) + green1.human = AddHog(green1.name, 0, 200, "war_desertofficer") + AnimSetGearPosition(green1.human, green1.x, green1.y) + green1.gear = green1.human + -- Green Bananas + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + green2.gear = AddHog(green2.name, 0, 100, "war_britmedic") + AnimSetGearPosition(green2.gear, green2.x, green2.y) + HogTurnLeft(green2.gear, true) + green3.gear = AddHog(green3.name, 0, 100, "hair_red") + AnimSetGearPosition(green3.gear, green3.x, green3.y) + HogTurnLeft(green3.gear, true) + green4.gear = AddHog(green4.name, 0, 100, "war_desertsapper1") + AnimSetGearPosition(green4.gear, green4.x, green4.y) + HogTurnLeft(green4.gear, true) + green5.gear = AddHog(green5.name, 0, 100, "war_sovietcomrade2") + AnimSetGearPosition(green5.gear, green5.x, green5.y) + HogTurnLeft(green5.gear, true) + -- Yellow Watermelons + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + yellow1.gear = AddHog(yellow1.name, 1, 100, "war_desertgrenadier2") + AnimSetGearPosition(yellow1.gear, yellow1.x, yellow1.y) + -- the rest of the Yellow Watermelons + local yellowHats = { "fr_apple", "fr_banana", "fr_lemon", "fr_orange" } + for i=1,7 do + yellowArmy[i].gear = AddHog(yellowArmy[i].name, 1, yellowArmy[i].health, yellowHats[GetRandom(4)+1]) + AnimSetGearPosition(yellowArmy[i].gear, yellowArmy[i].x, yellowArmy[i].y) + end + + initCheckpoint("fruit01") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onHeroSelect, {hero.gear}, heroSelect, {hero.gear}, 0) + + -- Green team weapons + local greenArmy = { green1, green2 } + for i=1,2 do + AddAmmo(greenArmy[i].gear, amBlowTorch, 5) + AddAmmo(greenArmy[i].gear, amRope, 5) + AddAmmo(greenArmy[i].gear, amBazooka, 10) + AddAmmo(greenArmy[i].gear, amGrenade, 7) + AddAmmo(greenArmy[i].gear, amFirePunch, 2) + AddAmmo(greenArmy[i].gear, amDrill, 3) + AddAmmo(greenArmy[i].gear, amSwitch, 2) + AddAmmo(greenArmy[i].gear, amSkip, 100) + end + -- Yellow team weapons + AddAmmo(yellow1.gear, amBlowTorch, 1) + AddAmmo(yellow1.gear, amRope, 1) + AddAmmo(yellow1.gear, amBazooka, 10) + AddAmmo(yellow1.gear, amGrenade, 10) + AddAmmo(yellow1.gear, amFirePunch, 5) + AddAmmo(yellow1.gear, amDrill, 3) + AddAmmo(yellow1.gear, amBee, 1) + AddAmmo(yellow1.gear, amMortar, 3) + AddAmmo(yellow1.gear, amDEagle, 4) + AddAmmo(yellow1.gear, amDynamite, 1) + AddAmmo(yellow1.gear, amSwitch, 100) + for i=3,7 do + HideHog(yellowArmy[i].gear) + end + HideHog(green1.bot) + + -- crates + SpawnHealthCrate(health1X, health1Y) + SpawnAmmoCrate(crateWMX, crateWMY, amWatermelon) + + AddAnim(dialog01) + SendHealthStatsOff() +end + +function onNewTurn() + if not heroPlayedFirstTurn and CurrentHedgehog ~= hero.gear and startBattleCalled then + TurnTimeLeft = 0 + elseif not heroPlayedFirstTurn and CurrentHedgehog == hero.gear and startBattleCalled then + heroPlayedFirstTurn = true + elseif not heroPlayedFirstTurn and CurrentHedgehog == green1.gear then + TurnTimeLeft = 0 + else + if chooseToBattle then + if CurrentHedgehog == green1.gear then + TotalRounds = TotalRounds - 2 + AnimSwitchHog(previousHog) + TurnTimeLeft = 0 + end + previousHog = CurrentHedgehog + end + getNextWave() + end +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGearDelete(gear) + if gear == hero.gear then + hero.dead = true + elseif gear == green1.gear then + green1.dead = true + end +end + +function onAmmoStoreInit() + SetAmmo(amWatermelon, 0, 0, 0, 1) +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +function onHogHide(gear) + for i=3,7 do + if gear == yellowArmy[i].gear then + yellowArmy[i].hidden = true + break + end + end +end + +function onHogRestore(gear) + for i=3,7 do + if gear == yellowArmy[i].gear then + yellowArmy[i].hidden = false + break + end + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +function onGreen1Death(gear) + if green1.dead then + return true + end + return false +end + +function onBattleWin(gear) + local win = true + for i=1,7 do + if i<3 then + if GetHealth(yellowArmy[i].gear) then + win = false + end + else + if GetHealth(yellowArmy[i].gear) and not yellowArmy[i].hidden then + win = false + end + end + end + if GetHealth(yellow1.gear) then + win = false + end + return win +end + +function onEscapeWin(gear) + local escape = false + if not hero.dead and GetX(hero.gear) < 170 and GetY(hero.gear) > 1980 and StoppedGear(hero.gear) then + escape = true + local yellowTeam = { yellow1, unpack(yellowArmy) } + for i=1,8 do + if not yellowTeam[i].hidden and GetHealth(yellowTeam[i].gear) and GetX(yellowTeam[i].gear) < 170 then + escape = false + break + end + end + end + return escape +end + +function onHeroSelect(gear) + if GetX(hero.gear) ~= hero.x then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + gameLost() +end + +function green1Death(gear) + gameLost() +end + +function battleWin(gear) + -- add stats + saveVariables() + SendStat(siGameResult, loc("Green Bananas won!")) + SendStat(siCustomAchievement, loc("You have eliminated all visible enemy hedgehogs!")) + SendStat(siPlayerKills,'1',teamA.name) + SendStat(siPlayerKills,'1',teamB.name) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end + +function escapeWin(gear) + -- add stats + saveVariables() + SendStat(siGameResult, loc("Hog Solo escaped successfully!")) + SendStat(siCustomAchievement, loc("You have reached the take-off area successfully!")) + SendStat(siPlayerKills,'1',teamA.name) + SendStat(siPlayerKills,'0',teamB.name) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end + +function heroSelect(gear) + TurnTimeLeft = 0 + FollowGear(hero.gear) + if GetX(hero.gear) < hero.x then + chooseToBattle = true + AddEvent(onGreen1Death, {green1.gear}, green1Death, {green1.gear}, 0) + AddEvent(onBattleWin, {hero.gear}, battleWin, {hero.gear}, 0) + AddAnim(dialog02) + elseif GetX(hero.gear) > hero.x then + HogTurnLeft(hero.gear, true) + AddAmmo(green1.gear, amSwitch, 100) + AddEvent(onEscapeWin, {hero.gear}, escapeWin, {hero.gear}, 0) + local greenTeam = { green2, green3, green4, green5 } + for i=1,4 do + SetHogLevel(greenTeam[i].gear, 1) + end + AddAnim(dialog03) + end +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + if anim == dialog01 then + AnimSwitchHog(hero.gear) + elseif anim == dialog02 or anim == dialog03 then + startBattle() + end +end + +function AnimationSetup() + -- DIALOG 01 - Start, Captain Lime talks explains to Hog Solo + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere on the Planet of Fruits a terrible war is about to begin..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I was told that as the leader of the king's guard, no one knows this world better than you!"), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("So, I kindly ask for your help"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimWait, args = {green1.gear, 2000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("You couldn't have come to a worse time Hog Solo!"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("The clan of the Red Strawberry wants to take over the dominion and overthrone king Pineapple."), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("Under normal circumstances we could easily defeat them but we have kindly sent most of our men to the kingdom of Sand to help to the annual dusting of the king's palace."), SAY_SAY, 8000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("However the army of Yellow Watermelons is about to attack any moment now."), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("I would gladly help you if we won this battle but under these circumstances I'll only help you if you fight for our side."), SAY_SAY, 6000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("What do you say? Will you fight for us?"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = ShowMission, args = {missionName, loc("Ready for Battle?"), loc("Walk left if you want to join Captain Lime or right if you want to decline his offer"), 1, 7000}}) + table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG 02 - Hero selects to fight + AddSkipFunction(dialog02, Skipanim, {dialog02}) + table.insert(dialog02, {func = AnimWait, args = {green1.gear, 3000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("You choose well Hog Solo!"), SAY_SAY, 3000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("I have only 3 hogs available and they are all cadets"), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("As you are more experienced, I want you to lead them to the battle"), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("I of course will observe the battle and intervene if necessary"), SAY_SAY, 5000}}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 4500}}) + table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("No problem Captain!"), SAY_SAY, 2000}}) + table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("The enemies aren't many anyway, it is going to be easy!"), SAY_SAY, 1}}) + table.insert(dialog02, {func = AnimWait, args = {green1.gear, 9000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("Don't be foolish son, there will be more"), SAY_SAY, 2000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("Try to be smart and eliminate them quickly. This way you might scare off the rest!"), SAY_SAY, 5000}}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 5000}}) + table.insert(dialog02, {func = startBattle, args = {hero.gear}}) + -- DIALOG 03 - Hero selects to flee + AddSkipFunction(dialog03, Skipanim, {dialog03}) + table.insert(dialog03, {func = AnimWait, args = {green1.gear, 3000}}) + table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Too bad... Then you should really leave!"), SAY_SAY, 3000}}) + table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Things are going to get messy around here"), SAY_SAY, 3000}}) + table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Also, you should know that the only place where you can fly is the left-most part of this area"), SAY_SAY, 5000}}) + table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("All the other places are protected by our flight-inhibiting weapons"), SAY_SAY, 4000}}) + table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Now go and don't waste more of my time you coward..."), SAY_SAY, 4000}}) + table.insert(dialog03, {func = AnimWait, args = {hero.gear, 5000}}) + table.insert(dialog03, {func = startBattle, args = {hero.gear}}) +end + +------------- OTHER FUNCTIONS --------------- + +function startBattle() + -- Hog Solo weapons + AddAmmo(hero.gear, amRope, 2) + AddAmmo(hero.gear, amBazooka, 3) + AddAmmo(hero.gear, amParachute, 1) + AddAmmo(hero.gear, amGrenade, 6) + AddAmmo(hero.gear, amDEagle, 4) + AddAmmo(hero.gear, amSkip, 100) + RestoreHog(green1.bot) + DeleteGear(green1.human) + green1.gear = green1.bot + startBattleCalled = true + TurnTimeLeft = 0 +end + +function gameLost() + if chooseToBattle then + SendStat(siGameResult, loc("The Green Bananas lost, try again!")) + SendStat(siCustomAchievement, loc("You have to eliminate all the visible enemies")) + SendStat(siCustomAchievement, loc("5 additional enemies will be spawned during the game")) + SendStat(siCustomAchievement, loc("You are in control of all the active ally units")) + SendStat(siCustomAchievement, loc("The ally units share their ammo")) + SendStat(siCustomAchievement, loc("Try to keep as many allies alive as possible")) + else + SendStat(siGameResult, loc("Hog Solo couldn't escape, try again!")) + SendStat(siCustomAchievement, loc("You have to get to the left-most land and remove any enemy hog from there")) + SendStat(siCustomAchievement, loc("You will play every 3 turns")) + SendStat(siCustomAchievement, loc("Green hogs won't intentionally hurt you")) + end + SendStat(siPlayerKills,'1',teamC.name) + SendStat(siPlayerKills,'0',teamA.name) + SendStat(siPlayerKills,'0',teamB.name) + EndGame() +end + +function getNextWave() + if TotalRounds == 4 then + RestoreHog(yellowArmy[3].gear) + AnimCaption(hero.gear, loc("Next wave in 3 turns"), 5000) + if not chooseToBattle and not GetHealth(yellow1.gear) then + SetGearPosition(yellowArmy[3].gear, yellow1.x, yellow1.y) + end + elseif TotalRounds == 7 then + RestoreHog(yellowArmy[4].gear) + RestoreHog(yellowArmy[5].gear) + AnimCaption(hero.gear, loc("Last wave in 3 turns"), 5000) + if not chooseToBattle and not GetHealth(yellow1.gear) and not GetHealth(yellowArmy[3].gear) then + SetGearPosition(yellowArmy[4].gear, yellow1.x, yellow1.y) + end + elseif TotalRounds == 10 then + RestoreHog(yellowArmy[6].gear) + RestoreHog(yellowArmy[7].gear) + if not chooseToBattle and not GetHealth(yellow1.gear) and not GetHealth(yellowArmy[3].gear) + and not GetHealth(yellowArmy[4].gear) then + SetGearPosition(yellowArmy[6].gear, yellow1.x, yellow1.y) + end + end +end + +function saveVariables() + saveCompletedStatus(2) + SaveCampaignVar("UnlockedMissions", "3") + SaveCampaignVar("Mission1", "3") + SaveCampaignVar("Mission2", "8") + SaveCampaignVar("Mission3", "1") +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit02.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit02.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit02.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit02.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,621 @@ +------------------- ABOUT ---------------------- +-- +-- In this adventure hero gets the lost part with +-- the help of the green bananas hogs. + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Getting to the device") +local inBattle = false +local tookPartInBattle = false +local previousHog = -1 +local checkPointReached = 1 -- 1 is normal spawn +local permitCaptainLimeDeath = false +-- dialogs +local dialog01 = {} +local dialog02 = {} +local dialog03 = {} +local dialog04 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Exploring the tunnel"), loc("Search for the device with the help of the other hedgehogs ").."|"..loc("Hog Solo has to reach the last crates"), 1, 4000}, + [dialog02] = {missionName, loc("Exploring the tunnel"), loc("Explore the tunnel with the other hedgehogs and search for the device").."|"..loc("Hog Solo has to reach the last crates"), 1, 4000}, + [dialog03] = {missionName, loc("Return to the Surface"), loc("Go to the surface!").."|"..loc("Attack Captain Lime before he attacks back"), 1, 4000}, + [dialog04] = {missionName, loc("Return to the Surface"), loc("Go to the surface!").."|"..loc("Attack the assassins before they attack back"), 1, 4000}, +} +-- crates +local eagleCrate = {name = amDEagle, x = 1680, y = 1650} +local girderCrate = {name = amGirder, x = 1680, y = 1160} +local ropeCrate = {name = amRope, x = 1400, y = 1870} +local weaponCrate = { x = 1360, y = 1870} +-- hogs +local hero = {} +local green1 = {} +local green2 = {} +local green3 = {} +-- teams +local teamA = {} +local teamB = {} +local teamC = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 1200 +hero.y = 820 +hero.dead = false +green1.name = loc("Captain Lime") +green1.x = 1050 +green1.y = 820 +green1.dead = false +green2.name = loc("Mister Pear") +green2.x = 1350 +green2.y = 820 +green3.name = loc("Lady Mango") +green3.x = 1450 +green3.y = 820 +local redHedgehogs = { + { name = loc("Poisonous Apple") }, + { name = loc("Dark Strawberry") }, + { name = loc("Watermelon Heart") }, + { name = loc("Deadly Grape") } +} +teamA.name = loc("Hog Solo and GB") +teamA.color = tonumber("38D61C",16) -- green +teamB.name = loc("Captain Lime") +teamB.color = tonumber("38D61D",16) -- greenish +teamC.name = loc("Fruit Assassins") +teamC.color = tonumber("FF0000",16) -- red + +function onGameInit() + GameFlags = gfDisableWind + Seed = 1 + TurnTime = 20000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Delay = 3 + SuddenDeathTurns = 200 + Map = "fruit02_map" + Theme = "Fruit" + + -- load checkpoints, problem getting the campaign variable + local health = 100 + checkPointReached = initCheckpoint("fruit02") + if checkPointReached ~= 1 then + loadHogsPositions() + health = tonumber(GetCampaignVar("HeroHealth")) + end + + -- Hog Solo and Green Bananas + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, health, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + HogTurnLeft(hero.gear, true) + green2.gear = AddHog(green2.name, 0, 100, "war_britmedic") + AnimSetGearPosition(green2.gear, green2.x, green2.y) + HogTurnLeft(green2.gear, true) + green3.gear = AddHog(green3.name, 0, 100, "hair_red") + AnimSetGearPosition(green3.gear, green3.x, green3.y) + HogTurnLeft(green3.gear, true) + -- Captain Lime + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + green1.human = AddHog(green1.name, 0, 100, "war_desertofficer") + AnimSetGearPosition(green1.human, green1.x, green1.y) + green1.bot = AddHog(green1.name, 1, 100, "war_desertofficer") + AnimSetGearPosition(green1.bot, green1.x, green1.y) + green1.gear = green1.human + -- Fruit Assassins + local assasinsHats = { "NinjaFull", "NinjaStraight", "NinjaTriangle" } + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + for i=1,table.getn(redHedgehogs) do + redHedgehogs[i].gear = AddHog(redHedgehogs[i].name, 1, 100, assasinsHats[GetRandom(3)+1]) + AnimSetGearPosition(redHedgehogs[i].gear, 2010 + 50*i, 630) + end + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + + if GetCampaignVar("Fruit01JoinedBattle") and GetCampaignVar("Fruit01JoinedBattle") == "true" then + tookPartInBattle = true + end + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onDeviceCrates, {hero.gear}, deviceCrates, {hero.gear}, 0) + + -- Hog Solo and GB weapons + AddAmmo(hero.gear, amSwitch, 100) + -- Captain Lime weapons + AddAmmo(green1.bot, amBazooka, 6) + AddAmmo(green1.bot, amGrenade, 6) + AddAmmo(green1.bot, amDEagle, 2) + HideHog(green1.bot) + -- Assassins weapons + AddAmmo(redHedgehogs[1].gear, amBazooka, 6) + AddAmmo(redHedgehogs[1].gear, amGrenade, 6) + AddAmmo(redHedgehogs[1].bot, amDEagle, 6) + for i=1,table.getn(redHedgehogs) do + HideHog(redHedgehogs[i].gear) + end + + -- explosives + -- I wanted to use FindPlace but doesn't accept height values... + local x1 = 950 + local x2 = 1306 + local y1 = 1210 + local y2 = 1620 + while true do + if y2 1 then + PlaceGirder(1580, 875, 4) + PlaceGirder(1800, 875, 4) + end + + -- place crates + if checkPointReached < 2 then + SpawnAmmoCrate(girderCrate.x, girderCrate.y, girderCrate.name) + end + if checkPointReached < 5 then + SpawnAmmoCrate(eagleCrate.x, eagleCrate.y, eagleCrate.name) + end + SpawnAmmoCrate(ropeCrate.x, ropeCrate.y, ropeCrate.name) + + if tookPartInBattle then + SpawnAmmoCrate(weaponCrate.x, weaponCrate.y, amWatermelon) + else + SpawnAmmoCrate(weaponCrate.x, weaponCrate.y, amSniperRifle) + end + + SendHealthStatsOff() +end + +function onNewTurn() + if not inBattle and CurrentHedgehog == green1.gear then + TurnTimeLeft = 0 + elseif CurrentHedgehog == green2.gear or CurrentHedgehog == green3.gear then + TurnTimeLeft = 0 + elseif inBattle then + if CurrentHedgehog == green1.gear and previousHog ~= hero.gear then + TurnTimeLeft = 0 + return + end + for i=1,table.getn(redHedgehogs) do + if CurrentHedgehog == redHedgehogs[i].gear and previousHog ~= hero.gear then + TurnTimeLeft = 0 + return + end + end + TurnTimeLeft = 20000 + wind() + elseif not inBattle and CurrentHedgehog == hero.gear then + TurnTimeLeft = -1 + wind() + else + TurnTimeLeft = 0 + end + previousHog = CurrentHedgehog +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGameTick20() + if not permitCaptainLimeDeath and not GetHealth(green1.gear) then + -- game ends with the according stat messages + heroDeath() + permitCaptainLimeDeath = true + end + if CurrentHedgehog and GetY(CurrentHedgehog) > 1350 then + SetWind(-40) + end +end + +function onGearDelete(gear) + if gear == hero.gear then + hero.dead = true + elseif gear == green1.bot then + green1.dead = true + end +end + +function onGearDamage(gear, damage) + if GetGearType(gear) == gtCase then + -- in this mode every crate is essential in order to complete the mission + -- destroying a crate ends the game + heroDeath() + end +end + +function onAmmoStoreInit() + SetAmmo(amDEagle, 0, 0, 0, 6) + SetAmmo(amGirder, 0, 0, 0, 2) + SetAmmo(amRope, 0, 0, 0, 1) + if tonumber(getBonus(2)) == 1 then + SetAmmo(amWatermelon, 0, 0, 0, 2) + SetAmmo(amSniperRifle, 0, 0, 0, 2) + else + SetAmmo(amWatermelon, 0, 0, 0, 1) + SetAmmo(amSniperRifle, 0, 0, 0, 1) + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +function onDeviceCrates(gear) + if not hero.dead and GetY(hero.gear)>1850 and GetX(hero.gear)>1340 and GetX(hero.gear)<1640 then + return true + end + return false +end + +function onSurface(gear) + if not hero.dead and GetY(hero.gear)<850 and StoppedGear(hero.gear) then + return true + end + return false +end + +function onGaptainLimeDeath(gear) + if green1.dead then + return true + end + return false +end + +function onRedTeamDeath(gear) + local redDead = true + for i=1,table.getn(redHedgehogs) do + if GetHealth(redHedgehogs[i].gear) then + redDead = false + break + end + end + return redDead +end + +function onCheckPoint1(gear) + -- before barrel jump + if not hero.dead and GetX(hero.gear) > 2850 and GetX(hero.gear) < 2945 + and GetY(hero.gear) > 808 and GetY(hero.gear) < 852 and not isHeroAtWrongPlace() then + return true + end + return false +end + +function onCheckPoint2(gear) + -- before barrel jump + if ((GetHealth(green2.gear) and GetX(green2.gear) > 2850 and GetX(green2.gear) < 2945 and GetY(green2.gear) > 808 and GetY(green2.gear) < 852) + or (GetHealth(green3.gear) and GetX(green3.gear) > 2850 and GetX(green3.gear) < 2945 and GetY(green3.gear) > 808 and GetY(green3.gear) < 852)) + and not isHeroAtWrongPlace() then + return true + end + return false +end + +function onCheckPoint3(gear) + -- after barrel jump + if ((GetHealth(green2.gear) and GetY(green2.gear) > 1550 and GetX(green2.gear) < 3000 and StoppedGear(green2.gear)) + or (GetHealth(green3.gear) and GetY(green3.gear) > 1550 and GetX(green3.gear) < 3000 and StoppedGear(green2.gear))) + and not isHeroAtWrongPlace() then + return true + end + return false +end + +function onCheckPoint4(gear) + -- hero at crates + if not hero.dead and GetX(hero.gear) > 1288 and GetX(hero.gear) < 1420 + and GetY(hero.gear) > 1840 and not isHeroAtWrongPlace() then + return true + end + return false +end + +-------------- ACTIONS ------------------ +ended = false + +function heroDeath(gear) + if not ended then + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("To win the game, Hog Solo has to get the bottom crates and come back to the surface")) + SendStat(siCustomAchievement, loc("You can use the other 2 hogs to assist you")) + SendStat(siCustomAchievement, loc("Do not destroy the crates")) + if tookPartInBattle then + SendStat(siCustomAchievement, loc("You'll have to eliminate the Strawberry Assassins at the end")) + else + SendStat(siCustomAchievement, loc("You'll have to eliminate Captain Lime at the end")) + SendStat(siCustomAchievement, loc("Don't eliminate Captain Lime before collecting the last crate!")) + end + SendStat(siPlayerKills,'0',teamA.name) + EndGame() + ended = true + end +end + +function deviceCrates(gear) + TurnTimeLeft = 0 + if not tookPartInBattle then + AddAnim(dialog03) + else + for i=1,table.getn(redHedgehogs) do + RestoreHog(redHedgehogs[i].gear) + end + AddAnim(dialog04) + end + -- needs to be set to true for both plots + permitCaptainLimeDeath = true + AddAmmo(hero.gear, amSwitch, 0) + AddEvent(onSurface, {hero.gear}, surface, {hero.gear}, 0) +end + +function surface(gear) + previousHog = -1 + if tookPartInBattle then + if GetHealth(green1.gear) then + HideHog(green1.gear) + end + AddEvent(onRedTeamDeath, {green1.gear}, redTeamDeath, {green1.gear}, 0) + else + DeleteGear(green1.human) + RestoreHog(green1.bot) + green1.gear = green1.bot + AddEvent(onGaptainLimeDeath, {green1.gear}, captainLimeDeath, {green1.gear}, 0) + end + if GetHealth(green2.gear) then + HideHog(green2.gear) + end + if GetHealth(green3.gear) then + HideHog(green3.gear) + end + inBattle = true +end + +function captainLimeDeath(gear) + -- hero win in scenario of escape in 1st part + saveCompletedStatus(3) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("You retrieved the lost part")) + SendStat(siCustomAchievement, loc("You defended yourself against Captain Lime")) + SendStat(siPlayerKills,'1',teamA.name) + SendStat(siPlayerKills,'0',teamB.name) + EndGame() +end + +function redTeamDeath(gear) + -- hero win in battle scenario + saveCompletedStatus(3) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("You retrieved the lost part")) + SendStat(siCustomAchievement, loc("You defended yourself against Strawberry Assassins")) + SendStat(siPlayerKills,'1',teamA.name) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end + +function checkPoint1(gear) + saveCheckPointLocal(2) +end + +function checkPoint2(gear) + saveCheckPointLocal(3) +end + +function checkPoint3(gear) + saveCheckPointLocal(4) +end + +function checkPoint4(gear) + saveCheckPointLocal(5) +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + TurnTimeLeft = 0 +end + +function AnimationSetup() + -- DIALOG 01 - Start, Captain Lime helps Hog Solo because he took part in the battle + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere else on the planet of fruits Captain Lime helps Hog Solo..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("You fought bravely and you helped us win this battle!"), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("So, as promised I have brought you where I think that the device you are looking for is hidden."), SAY_SAY, 7000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("I know that your resources are low due to the battle but I'll send two of my best hogs to assist you."), SAY_SAY, 7000}}) + table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("Good luck!"), SAY_SAY, 2000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG02 - Start, Hog Solo escaped from the previous battle + AddSkipFunction(dialog02, Skipanim, {dialog02}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("Somewhere else on the planet of fruits Hog Solo gets closer to the device..."), 5000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("You are the one who fled! So, you are alive..."), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("I'm still low on hogs. If you are not afraid I could use a set of extra hands"), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 8000}}) + table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("I am sorry but I was looking for a device that may be hidden somewhere around here"), SAY_SAY, 4500}}) + table.insert(dialog02, {func = AnimWait, args = {green1.gear, 12500}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("Many long forgotten things can be found in the same tunnels that we are about to explore!"), SAY_SAY, 7000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("If you help us you can keep the device if you find it but we'll keep everything else"), SAY_SAY, 7000}}) + table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("What do you say? Are you in?"), SAY_SAY, 3000}}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 1800}}) + table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("Ok then!"), SAY_SAY, 2000}}) + table.insert(dialog02, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG03 - At crates, hero learns that Captain Lime is bad + AddSkipFunction(dialog03, Skipanim, {dialog03}) + table.insert(dialog03, {func = AnimWait, args = {hero.gear, 4000}}) + table.insert(dialog03, {func = FollowGear, args = {hero.gear}}) + table.insert(dialog03, {func = AnimSay, args = {hero.gear, loc("Hoorah! I've found it, now I have to get back to Captain Lime!"), SAY_SAY, 4000}}) + table.insert(dialog03, {func = AnimWait, args = {green1.gear, 4000}}) + table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("This Hog Solo is so naive! When he returns I'll shoot him and keep that device for myself!"), SAY_THINK, 4000}}) + table.insert(dialog03, {func = goToThesurface, args = {hero.gear}}) + -- DIALOG04 - At crates, hero learns about the Assassins ambush + AddSkipFunction(dialog04, Skipanim, {dialog04}) + table.insert(dialog04, {func = AnimWait, args = {hero.gear, 4000}}) + table.insert(dialog04, {func = FollowGear, args = {hero.gear}}) + table.insert(dialog04, {func = AnimSay, args = {hero.gear, loc("Hoorah! I've found it, now I have to get back to Captain Lime!"), SAY_SAY, 4000}}) + table.insert(dialog04, {func = AnimWait, args = {redHedgehogs[1].gear, 4000}}) + table.insert(dialog04, {func = AnimSay, args = {redHedgehogs[1].gear, loc("We have spotted the enemy! We'll attack when the enemies start gathering!"), SAY_THINK, 4000}}) + table.insert(dialog04, {func = goToThesurface, args = {hero.gear}}) +end + +------------- OTHER FUNCTIONS --------------- + +function goToThesurface() + TurnTimeLeft = 0 +end + +function wind() + SetWind(GetRandom(201)-100) +end + +function saveHogsPositions() + local positions; + positions = GetX(hero.gear)..","..GetY(hero.gear) + if GetHealth(green2.gear) then + positions = positions..","..GetX(green2.gear)..","..GetY(green2.gear) + else + positions = positions..",1,1" + end + if GetHealth(green3.gear) then + positions = positions..","..GetX(green3.gear)..","..GetY(green3.gear) + else + positions = positions..",1,1" + end + SaveCampaignVar("HogsPosition", positions) +end + +function loadHogsPositions() + local positions; + if GetCampaignVar("HogsPosition") then + positions = GetCampaignVar("HogsPosition") + else + return + end + positions = split(positions,",") + if positions[1] then + hero.x = positions[1] + hero.y = positions[2] + end + if positions[3] then + green2.x = tonumber(positions[3]) + green2.y = tonumber(positions[4]) + end + if positions[5] then + green3.x = tonumber(positions[5]) + green3.y = tonumber(positions[6]) + end +end + +function saveWeapons() + -- firepunch - gilder - deagle - watermelon - sniper + SaveCampaignVar("HeroAmmo", GetAmmoCount(hero.gear, amFirePunch)..GetAmmoCount(hero.gear, amGirder).. + GetAmmoCount(hero.gear, amDEagle)..GetAmmoCount(hero.gear, amWatermelon)..GetAmmoCount(hero.gear, amSniperRifle)) +end + +function loadWeapons() + local ammo = GetCampaignVar("HeroAmmo") + AddAmmo(hero.gear, amFirePunch, tonumber(ammo:sub(1,1))) + AddAmmo(hero.gear, amGirder, tonumber(ammo:sub(2,2))) + AddAmmo(hero.gear, amDEagle, tonumber(ammo:sub(3,3))) + AddAmmo(hero.gear, amWatermelon, tonumber(ammo:sub(4,4))) + AddAmmo(hero.gear, amSniperRifle, tonumber(ammo:sub(5,5))) +end + +function isHeroAtWrongPlace() + if GetX(hero.gear) > 1480 and GetX(hero.gear) < 1892 and GetY(hero.gear) > 1000 and GetY(hero.gear) < 1220 then + return true + end + return false +end + +function saveCheckPointLocal(cpoint) + AnimCaption(hero.gear, loc("Checkpoint reached!"), 3000) + saveCheckpoint(cpoint) + SaveCampaignVar("HeroHealth", GetHealth(hero.gear)) + saveHogsPositions() + saveWeapons() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit03.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit03.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit03.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit03.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,299 @@ +------------------- ABOUT ---------------------- +-- +-- Hero has get into an Red Strawberries ambush +-- He has to eliminate the enemies by using limited +-- ammo of sniper rifle and watermelon + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Precise shooting") +local timeLeft = 10000 +local lastWeaponUsed = amSniperRifle +local challengeObjectives = loc("Use your available weapons in order to eliminate the enemies").."|".. + loc("You can only use the Sniper Rifle or the Watermelon bomb").."|".. + loc("You'll have only 2 watermelon bombs during the game").."|".. + loc("You'll get an extra Sniper Rifle every time you kill an enemy hog with a limit of max 4 rifles").."|".. + loc("You'll get an extra Teleport every time you kill an enemy hog with a limit of max 2 teleports").."|".. + loc("The first turn will last 25 sec and every other turn 15 sec").."|".. + loc("If you skip a turn then the turn time left will be added to your next turn").."|".. + loc("Some parts of the land are indestructible") +-- dialogs +local dialog01 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500}, +} +-- hogs +local hero = { + name = loc("Hog Solo"), + x = 1100, + y = 560 +} +local enemiesOdd = { + {name = loc("Hog 1"), x = 2000 , y = 175}, + {name = loc("Hog III"), x = 1950 , y = 1110}, + {name = loc("Hog 100"), x = 1270 , y = 1480}, + {name = loc("Hog Saturn"), x = 240 , y = 790}, + {name = loc("Hog nueve"), x = 620 , y = 1950}, + {name = loc("Hog onze"), x = 720 , y = 1950}, + {name = loc("Hog dertien"), x = 1620 , y = 1950}, + {name = loc("Hog 3x5"), x = 1720 , y = 1950}, +} +local enemiesEven = { + {name = loc("Hog two"), x = 660, y = 140}, + {name = loc("Hog D"), x = 1120, y = 1250}, + {name = loc("Hog exi"), x = 1290, y = 1250}, + {name = loc("Hog octo"), x = 820, y = 1950}, + {name = loc("Hog decar"), x = 920, y = 1950}, + {name = loc("Hog Hephaestus"), x = 1820, y = 1950}, + {name = loc("Hog 7+7"), x = 1920, y = 1950}, + {name = loc("Hog EOF"), x = 1200, y = 560}, +} +-- teams +local teamA = { + name = loc("Hog Solo"), + color = tonumber("38D61C",16) -- green +} +local teamB = { + name = loc("RS1"), + color = tonumber("FF0000",16) -- red +} +local teamC = { + name = loc("RS2"), + color = tonumber("FF0000",16) -- red +} + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + GameFlags = gfDisableWind + gfInfAttack + Seed = 1 + TurnTime = 15000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Map = "fruit03_map" + Theme = "Fruit" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + -- enemies + local hats = { "Bandit", "fr_apple", "fr_banana", "fr_lemon", "fr_orange", + "fr_pumpkin", "Gasmask", "NinjaFull", "NinjaStraight", "NinjaTriangle" } + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + for i=1,table.getn(enemiesEven) do + enemiesEven[i].gear = AddHog(enemiesEven[i].name, 1, 100, hats[GetRandom(table.getn(hats))+1]) + AnimSetGearPosition(enemiesEven[i].gear, enemiesEven[i].x, enemiesEven[i].y) + end + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + for i=1,table.getn(enemiesOdd) do + enemiesOdd[i].gear = AddHog(enemiesOdd[i].name, 1, 100, hats[GetRandom(table.getn(hats))+1]) + AnimSetGearPosition(enemiesOdd[i].gear, enemiesOdd[i].x, enemiesOdd[i].y) + end + + initCheckpoint("fruit03") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0) + + --hero ammo + AddAmmo(hero.gear, amTeleport, 2) + AddAmmo(hero.gear, amSniperRifle, 2) + AddAmmo(hero.gear, amWatermelon, 2) + --enemies ammo + AddAmmo(enemiesOdd[1].gear, amDEagle, 100) + AddAmmo(enemiesOdd[1].gear, amSniperRifle, 100) + AddAmmo(enemiesOdd[1].gear, amWatermelon, 1) + AddAmmo(enemiesOdd[1].gear, amGrenade, 5) + AddAmmo(enemiesEven[1].gear, amDEagle, 100) + AddAmmo(enemiesEven[1].gear, amSniperRifle, 100) + AddAmmo(enemiesEven[1].gear, amWatermelon, 1) + AddAmmo(enemiesEven[1].gear, amGrenade, 5) + + SendHealthStatsOff() + AddAnim(dialog01) +end + +function onNewTurn() + if CurrentHedgehog == hero.gear then + if GetAmmoCount(hero.gear, amSkip) == 0 then + TurnTimeLeft = TurnTime + timeLeft + AddAmmo(hero.gear, amSkip, 1) + end + timeLeft = 0 + end + turnHogs() +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGameTick20() + if CurrentHedgehog == hero.gear and TurnTimeLeft ~= 0 then + timeLeft = TurnTimeLeft + end +end + +function onGearDelete(gear) + if (isHog(gear)) then + local availableTeleports = GetAmmoCount(hero.gear,amTeleport) + local availableSniper = GetAmmoCount(hero.gear,amSniperRifle) + if availableTeleports < 2 then + AddAmmo(hero.gear, amTeleport, availableTeleports + 1 ) + end + if availableSniper < 4 then + AddAmmo(hero.gear, amSniperRifle, availableSniper + 1 ) + end + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if not GetHealth(hero.gear) then + return true + end + return false +end + +function onHeroWin(gear) + local enemies = enemiesOdd + for i=1,table.getn(enemiesEven) do + table.insert(enemies, enemiesEven[i]) + end + local allDead = true + for i=1,table.getn(enemies) do + if GetHealth(enemies[i].gear) then + allDead = false + break + end + end + return allDead +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("You have to eliminate all the enemies")) + SendStat(siCustomAchievement, loc("Read the Challenge Objectives from within the mission for more details")) + SendStat(siPlayerKills,'1',teamB.name) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end + +function heroWin(gear) + saveBonus(2, 1) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("You complete the mission in "..TotalRounds.." rounds")) + SendStat(siCustomAchievement, loc("You will gain some extra ammo from the crates the next time you play the \"Getting to the device\" mission")) + SendStat(siPlayerKills,'1',teamA.name) + EndGame() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + startBattle() +end + +function AnimationSetup() + -- DIALOG 01 - Start, game instructions + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere in the Fruit Planet Hog Solo got lost..."), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("...and got ambushed by the Red Strawberries"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Use your available weapons in order to eliminate the enemies"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You can only use the Sniper Rifle or the Watermelon bomb"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll have only 2 watermelon bombs during the game"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll get an extra Sniper Rifle every time you kill an enemy hog with a limit of max 4 rifles"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll get an extra Teleport every time you kill an enemy hog with a limit of max 2 teleports"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("The first turn will last 25 sec and every other turn 15 sec"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("If you skip the game your time left will be added to your next turn"), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Some parts of the land are indestructible"), 5000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = startBattle, args = {hero.gear}}) +end + +------------------ Other Functions ------------------- + +function turnHogs() + if GetHealth(hero.gear) then + for i=1,table.getn(enemiesEven) do + if GetHealth(enemiesEven[i].gear) then + if GetX(enemiesEven[i].gear) < GetX(hero.gear) then + HogTurnLeft(enemiesEven[i].gear, false) + elseif GetX(enemiesEven[i].gear) > GetX(hero.gear) then + HogTurnLeft(enemiesEven[i].gear, true) + end + end + end + for i=1,table.getn(enemiesOdd) do + if GetHealth(enemiesOdd[i].gear) then + if GetX(enemiesOdd[i].gear) < GetX(hero.gear) then + HogTurnLeft(enemiesOdd[i].gear, false) + elseif GetX(enemiesOdd[i].gear) > GetX(hero.gear) then + HogTurnLeft(enemiesOdd[i].gear, true) + end + end + end + end +end + +function startBattle() + AnimSwitchHog(enemiesOdd[table.getn(enemiesOdd)].gear) + TurnTimeLeft = 0 + -- these 2 are needed in order hero has 10 sec more in the first turn + timeLeft = 10000 + AddAmmo(hero.gear, amSkip, 0) +end + +function isHog(gear) + local hog = false + for i=1,table.getn(enemiesOdd) do + if gear == enemiesOdd[i].gear then + hog = true + break + end + end + if not hog then + for i=1,table.getn(enemiesEven) do + if gear == enemiesEven then + hog = true + break + end + end + end + return hog +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/global_functions.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/global_functions.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,120 @@ +function saveCompletedStatus(planetNum) + -- 1 2 3 4 5 6 7 + -- order: moon01, fruit01, fruit02, ice01, desert01, death01, final + local status = "0000000" + if tonumber(GetCampaignVar("MainMissionsStatus")) then + status = GetCampaignVar("MainMissionsStatus") + end + + if planetNum == 1 then + status = "1"..status:sub(2) + elseif planetNum == status:len() then + status = status:sub(1,planetNum-1).."1" + else + status = status:sub(1,planetNum-1).."1"..status:sub(planetNum+1) + end + SaveCampaignVar("MainMissionsStatus",status) +end + +function getCompletedStatus() + local allStatus = "" + if tonumber(GetCampaignVar("MainMissionsStatus")) then + allStatus = GetCampaignVar("MainMissionsStatus") + end + local status = { + moon01 = false, + fruit01 = false, + fruit02 = false, + ice01 = false, + desert01 = false, + death01 = false, + final = false + } + if allStatus ~= "" then + if allStatus:sub(1,1) == "1" then + status.moon01 = true + end + if allStatus:sub(2,2) == "1" then + status.fruit01 = true + end + if allStatus:sub(3,3) == "1" then + status.fruit02 = true + end + if allStatus:sub(4,4) == "1" then + status.ice01 = true + end + if allStatus:sub(5,5) == "1" then + status.desert01 = true + end + if allStatus:sub(6,6) == "1" then + status.death01 = true + end + if allStatus:sub(7,7) == "1" then + status.final = true + end + end + return status +end + +function initCheckpoint(mission) + local checkPoint = 1 + if GetCampaignVar("CurrentMission") ~= mission then + SaveCampaignVar("CurrentMission", mission) + SaveCampaignVar("CurrentMissionCheckpoint", 1) + SaveCampaignVar("HogsPosition", "") + else + checkPoint = tonumber(GetCampaignVar("currentMissionCheckpoint")) + end + return checkPoint +end + +function saveCheckpoint(cp) + SaveCampaignVar("CurrentMissionCheckpoint", cp) +end + +-- saves what bonuses are available +-- times is how many times the bonus will be available, this will be mission specific +function saveBonus(index, times) + -- 1 2 3 + -- order: desert03, fruit03, death02 + local bonus = "000" + if tonumber(GetCampaignVar("SideMissionsBonuses")) then + bonus = GetCampaignVar("SideMissionsBonuses") + end + if index == 1 then + bonus = times..bonus:sub(2) + elseif index == bonus:len() then + bonus = bonus:sub(1,index-1)..times + else + bonus = bonus:sub(1,index-1)..times..bonus:sub(index+1) + end + SaveCampaignVar("SideMissionsBonuses",bonus) +end + +function getBonus(index) + local bonus = 0 + if tonumber(GetCampaignVar("SideMissionsBonuses")) then + bonusString = GetCampaignVar("SideMissionsBonuses") + bonus = bonusString:sub(index,index) + end + return bonus +end + +-- splits number by delimiter +function split(s, delimiter) + local res = {} + local first = "" + for i=1,s:len() do + if s:sub(1,1) == delimiter then + table.insert(res, tonumber(first)) + first = "" + else + first = first..s:sub(1,1) + end + s = s:sub(2) + end + if first:len() > 0 then + table.insert(res, tonumber(first)) + end + return res +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice01.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice01.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice01.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice01.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,529 @@ +------------------- ABOUT ---------------------- +-- +-- In this cold planet hero seeks for a part of the +-- antigravity device. He has to capture Thanta who +-- knows where the device is hidden. Hero will be +-- able to use only the ice gun for this mission. + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("A frozen adventure") +local heroAtAntiFlyArea = false +local heroVisitedAntiFlyArea = false +local heroAtFinalStep = false +local iceGunTaken = false +local checkPointReached = 1 -- 1 is normal spawn +local heroDamageAtCurrentTurn = 0 +-- dialogs +local dialog01 = {} +local dialog02 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Getting ready"), loc("Collect the icegun and get the device part from Thanta"), 1, 4500}, + [dialog02] = {missionName, loc("Win"), loc("Congratulations, you collected the device part!"), 1, 3500}, +} +-- crates +local icegunY = 1950 +local icegunX = 260 +-- hogs +local hero = {} +local ally = {} +local bandit1 = {} +local bandit2 = {} +local bandit3 = {} +local bandit4 = {} +local bandit5 = {} +-- teams +local teamA = {} +local teamB = {} +local teamC = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 340 +hero.y = 1840 +hero.dead = false +ally.name = loc("Paul McHoggy") +ally.x = 300 +ally.y = 1840 +bandit1.name = loc("Thanta") +bandit1.x = 3240 +bandit1.y = 1280 +bandit1.dead = false +bandit1.frozen = false +bandit1.roundsToUnfreeze = 0 +bandit2.name = loc("Billy Frost") +bandit2.x = 1480 +bandit2.y = 1990 +bandit3.name = loc("Ice Jake") +bandit3.x = 1860 +bandit3.y = 1150 +bandit4.name = loc("John Snow") +bandit4.x = 3200 +bandit4.y = 970 +bandit4.frozen = false +bandit4.roundsToUnfreeze = 0 +bandit5.name = loc("White Tee") +bandit5.x = 3280 +bandit5.y = 600 +bandit5.frozen = false +bandit5.roundsToUnfreeze = 0 +teamA.name = loc("Allies") +teamA.color = tonumber("FF0000",16) -- red +teamB.name = loc("Frozen Bandits") +teamB.color = tonumber("0033FF",16) -- blues +teamC.name = loc("Hog Solo") +teamC.color = tonumber("38D61C",16) -- green + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + Seed = 1 + TurnTime = 25000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Delay = 3 + Map = "ice01_map" + Theme = "Snow" + + -- get the check point + checkPointReached = initCheckpoint("ice01") + -- get hero health + local heroHealth = 100 + if tonumber(GetCampaignVar("HeroHealth")) then + heroHealth = tonumber(GetCampaignVar("HeroHealth")) + end + + if heroHealth ~= 100 then + heroHealth = heroHealth + 5 + if heroHealth > 100 then + heroHealth = 100 + end + SaveCampaignVar("HeroHealth", heroHealth) + end + + -- Hog Solo + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, heroHealth, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + HogTurnLeft(hero.gear, true) + -- Ally + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + ally.gear = AddHog(ally.name, 0, 100, "war_airwarden02") + AnimSetGearPosition(ally.gear, ally.x, ally.y) + -- Frozen Bandits + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + bandit1.gear = AddHog(bandit1.name, 1, 120, "Santa") + AnimSetGearPosition(bandit1.gear, bandit1.x, bandit1.y) + HogTurnLeft(bandit1.gear, true) + bandit2.gear = AddHog(bandit2.name, 1, 100, "ushanka") + AnimSetGearPosition(bandit2.gear, bandit2.x, bandit2.y) + bandit3.gear = AddHog(bandit3.name, 1, 100, "thug") + AnimSetGearPosition(bandit3.gear, bandit3.x, bandit3.y) + bandit4.gear = AddHog(bandit4.name, 1, 40, "tophats") + AnimSetGearPosition(bandit4.gear, bandit4.x, bandit4.y) + HogTurnLeft(bandit4.gear, true) + bandit5.gear = AddHog(bandit5.name, 1, 40, "Sniper") + AnimSetGearPosition(bandit5.gear, bandit5.x, bandit5.y) + HogTurnLeft(bandit5.gear, true) + + if checkPointReached == 1 then + -- Start of the game + elseif checkPointReached == 2 then + iceGunTaken = true + AnimSetGearPosition(hero.gear, 840, 1650) + elseif checkPointReached == 3 then + iceGunTaken = true + heroAtFinalStep = true + heroVisitedAntiFlyArea = true + AnimSetGearPosition(hero.gear, 1450, 910) + end + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + + -- Add mines + AddGear(1612, 940, gtMine, 0, 0, 0, 0) + AddGear(1622, 945, gtMine, 0, 0, 0, 0) + AddGear(1645, 950, gtMine, 0, 0, 0, 0) + AddGear(1655, 960, gtMine, 0, 0, 0, 0) + AddGear(1665, 965, gtMine, 0, 0, 0, 0) + + AddGear(1800, 1000, gtMine, 0, 0, 0, 0) + AddGear(1810, 1005, gtMine, 0, 0, 0, 0) + AddGear(1820, 1010, gtMine, 0, 0, 0, 0) + AddGear(1830, 1015, gtMine, 0, 0, 0, 0) + AddGear(1840, 1020, gtMine, 0, 0, 0, 0) + + AddGear(1900, 1020, gtMine, 0, 0, 0, 0) + AddGear(1910, 1020, gtMine, 0, 0, 0, 0) + AddGear(1920, 1020, gtMine, 0, 0, 0, 0) + AddGear(1930, 1030, gtMine, 0, 0, 0, 0) + AddGear(1940, 1040, gtMine, 0, 0, 0, 0) + + AddGear(2130, 1110, gtMine, 0, 0, 0, 0) + AddGear(2140, 1120, gtMine, 0, 0, 0, 0) + AddGear(2180, 1120, gtMine, 0, 0, 0, 0) + AddGear(2200, 1130, gtMine, 0, 0, 0, 0) + AddGear(2210, 1130, gtMine, 0, 0, 0, 0) + + local x=2300 + local step=0 + while x<3100 do + AddGear(x, 1150, gtMine, 0, 0, 0, 0) + step = step + 1 + if step == 5 then + step = 0 + x = x + GetRandom(201)+100 + else + x = x + GetRandom(21)+10 + end + end + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onHeroFinalStep, {hero.gear}, heroFinalStep, {hero.gear}, 0) + AddEvent(onAntiFlyArea, {hero.gear}, antiFlyArea, {hero.gear}, 1) + AddEvent(onAntiFlyAreaVelocity, {hero.gear}, antiFlyAreaVelocity, {hero.gear}, 1) + AddEvent(onNonAntiFlyArea, {hero.gear}, nonAntiFlyArea, {hero.gear}, 1) + AddEvent(onThantaDeath, {bandit1.gear}, thantaDeath, {bandit1.gear}, 0) + AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0) + + AddAmmo(hero.gear, amJetpack, 99) + AddAmmo(bandit1.gear, amBazooka, 5) + AddAmmo(bandit2.gear, amBazooka, 4) + AddAmmo(bandit3.gear, amMine, 2) + AddAmmo(bandit3.gear, amGrenade, 3) + AddAmmo(bandit4.gear, amBazooka, 5) + AddAmmo(bandit5.gear, amBazooka, 5) + + goToThantaString = loc("Go to Thanta and get the device part!") + + if checkPointReached == 1 then + AddAmmo(hero.gear, amBazooka, 1) + SpawnAmmoCrate(icegunX, icegunY, amIceGun) + AddEvent(onColumnCheckPoint, {hero.gear}, columnCheckPoint, {hero.gear}, 0) + AddEvent(onHeroAtIceGun, {hero.gear}, heroAtIceGun, {hero.gear}, 0) + AddAnim(dialog01) + elseif checkPointReached == 2 then + AddAmmo(hero.gear, amIceGun, 8) + AnimCaption(hero.gear, goToThantaString, 5000) + elseif checkPointReached == 3 then + AddAmmo(hero.gear, amIceGun, 6) + AnimCaption(hero.gear, goToThantaString, 5000) + end + + SendHealthStatsOff() +end + +function onNewTurn() + heroDamageAtCurrentTurn = 0 + -- round has to start if hero goes near the column + if not heroVisitedAntiFlyArea and CurrentHedgehog ~= hero.gear then + TurnTimeLeft = 0 + elseif not heroVisitedAntiFlyArea and CurrentHedgehog == hero.gear then + TurnTimeLeft = -1 + elseif not heroAtFinalStep and (CurrentHedgehog == bandit1.gear or CurrentHedgehog == bandit4.gear or CurrentHedgehog == bandit5.gear) then + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 + elseif heroAtFinalStep and (CurrentHedgehog == bandit2.gear or CurrentHedgehog == bandit3.gear) then + if (GetHealth(bandit1.gear) and GetEffect(bandit1.gear,heFrozen) > 256) and + ((GetHealth(bandit4.gear) and GetEffect(bandit4.gear,heFrozen) > 256) or not GetHealth(bandit4.gear)) and + ((GetHealth(bandit5.gear) and GetEffect(bandit5.gear,heFrozen) > 256) or not GetHealth(bandit5.gear)) then + TurnTimeLeft = 0 + else + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 + end + elseif CurrentHedgehog == ally.gear then + TurnTimeLeft = 0 + end + -- frozen hogs accounting + if CurrentHedgehog == hero.gear and heroAtFinalStep and TurnTimeLeft > 0 then + if bandit1.frozen then + if bandit1.roundsToUnfreeze == 0 then + SetEffect(bandit1.gear, heFrozen, 255) + bandit1.frozen = false + else + bandit1.roundsToUnfreeze = bandit1.roundsToUnfreeze - 1 + end + end + if bandit4.frozen then + if bandit4.roundsToUnfreeze == 0 then + SetEffect(bandit4.gear, heFrozen, 255) + bandit4.frozen = false + else + bandit4.roundsToUnfreeze = bandit4.roundsToUnfreeze - 1 + end + end + if bandit5.frozen then + if bandit5.roundsToUnfreeze == 0 then + SetEffect(bandit5.gear, heFrozen, 255) + bandit5.frozen = false + else + bandit5.roundsToUnfreeze = bandit5.roundsToUnfreeze - 1 + end + end + else + if bandit1.frozen then + SetEffect(bandit1.gear, heFrozen, 9999999999) + end + if bandit4.frozen then + SetEffect(bandit4.gear, heFrozen, 9999999999) + end + if bandit5.frozen then + SetEffect(bandit5.gear, heFrozen, 9999999999) + end + end +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() + + if GetEffect(bandit1.gear, heFrozen) > 256 and not bandit1.frozen then + bandit1.frozen = true + SetEffect(bandit1.gear, heFrozen, 9999999999) + bandit1.roundsToUnfreeze = 1 + end + if GetEffect(bandit4.gear, heFrozen) > 256 and not bandit4.frozen then + bandit4.frozen = true + SetEffect(bandit4.gear, heFrozen, 9999999999) + bandit4.roundsToUnfreeze = 2 + end + if GetEffect(bandit5.gear, heFrozen) > 256 and not bandit5.frozen then + bandit5.frozen = true + SetEffect(bandit5.gear, heFrozen, 9999999999) + bandit5.roundsToUnfreeze = 2 + end +end + +function onAmmoStoreInit() + SetAmmo(amIceGun, 0, 0, 0, 8) +end + +function onGearDelete(gear) + if gear == hero.gear then + hero.dead = true + elseif gear == bandit1.gear then + bandit1.dead = true + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +function onGearDamage(gear, damage) + if gear == hero.gear then + heroDamageAtCurrentTurn = heroDamageAtCurrentTurn + damage + end +end + +-------------- EVENTS ------------------ + +function onAntiFlyArea(gear) + if not hero.dead and (GetX(gear) > 860 or GetY(gear) < 1400) and not heroAtAntiFlyArea then + return true + end + return false +end + +function onAntiFlyAreaVelocity(gear) + if not hero.dead and GetY(gear) < 1300 and GetX(gear) < 1190 then + return true + end + return false +end + +function onNonAntiFlyArea(gear) + if not hero.dead and (GetX(gear) < 860 and GetY(gear) > 1400) and heroAtAntiFlyArea then + return true + end + return false +end + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +function onHeroFinalStep(gear) + if not hero.dead and GetY(gear) < 960 and GetX(gear) > 1400 then + return true + end + return false +end + +function onColumnCheckPoint(gear) + if not hero.dead and iceGunTaken and GetX(gear) < 870 and GetX(gear) > 850 and GetY(gear) > 1500 and StoppedGear(gear) then + return true + end + return false +end + +function onHeroAtIceGun(gear) + if not hero.dead and GetX(gear) < icegunX+15 and GetX(gear) > icegunX-15 and GetY(gear) > icegunY-15 and GetY(gear) < icegunY+15 then + return true + end + return false +end + +function onThantaDeath(gear) + if bandit1.dead then + return true + end + return false +end + +function onHeroWin(gear) + if (not hero.dead and not bandit1.dead) and heroDamageAtCurrentTurn == 0 and (GetX(hero.gear)>=GetX(bandit1.gear)-80 + and GetX(hero.gear)<=GetX(bandit1.gear)+80) and (GetY(hero.gear)>=GetY(bandit1.gear)-30 and GetY(hero.gear)<=GetY(bandit1.gear)+30) then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function antiFlyArea(gear) + heroAtAntiFlyArea = true + if not heroVisitedAntiFlyArea then + TurnTimeLeft = 0 + FollowGear(hero.gear) + AnimSwitchHog(bandit1.gear) + FollowGear(hero.gear) + TurnTimeLeft = 0 + end + AddAmmo(hero.gear, amJetpack, 0) + heroVisitedAntiFlyArea = true +end + +function antiFlyAreaVelocity(gear) + dx, dy = GetGearVelocity(hero.gear) + SetGearVelocity(hero.gear, dx, math.max(dy, 0)) +end + +function nonAntiFlyArea(gear) + heroAtAntiFlyArea = false + AddAmmo(hero.gear, amJetpack, 99) +end + +function heroDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("To win the game you have to go next to Thanta")) + SendStat(siCustomAchievement, loc("Most of the time you'll be able to use only the icegun")) + SendStat(siCustomAchievement, loc("Use the bazooka and the flying saucer to get the icegun")) + SendStat(siPlayerKills,'1',teamB.name) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end + +function heroFinalStep(gear) + heroAtFinalStep = true + saveCheckpoint("3") + SaveCampaignVar("HeroHealth", GetHealth(hero.gear)) +end + +function columnCheckPoint(gear) + saveCheckpoint("2") + SaveCampaignVar("HeroHealth", GetHealth(hero.gear)) + AnimCaption(hero.gear, loc("Checkpoint reached!"), 5000) +end + +function heroAtIceGun(gear) + iceGunTaken=true +end + +function thantaDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("Noooo, Thanta has to stay alive!")) + SendStat(siCustomAchievement, loc("To win the game you have to go next to Thanta")) + SendStat(siCustomAchievement, loc("Most of the time you'll be able to use only the icegun")) + SendStat(siCustomAchievement, loc("Use the bazooka and the flying saucer to get the icegun")) + SendStat(siPlayerKills,'1',teamB.name) + SendStat(siPlayerKills,'0',teamC.name) + EndGame() +end + +function heroWin(gear) + TurnTimeLeft=0 + if GetX(hero.gear) < GetX(bandit1.gear) then + HogTurnLeft(bandit1.gear, true) + else + HogTurnLeft(bandit1.gear, false) + end + AddAnim(dialog02) +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + if anim == dialog02 then + actionsOnWin() + else + AnimSwitchHog(hero.gear) + end +end + +function AnimationSetup() + -- DIALOG 01 - Start, welcome to moon + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("On the Ice Planet, where ice rules..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Finally you are here..."), SAY_SAY, 2000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 2000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Hi! Nice to meet you"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimWait, args = {ally.gear, 2000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Listen carefully! The bandit leader, Thanta, has recently found a very strange device"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("He doesn't know it but this device is a part of the anti-gravity device"), SAY_SAY, 2500}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 8000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Nice, then I should get the part as soon as possible!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimWait, args = {ally.gear, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Be careful, your gadgets won't work in the bandit area. You should get an ice gun"), SAY_SAY, 7000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("There is one below us!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG 02 - Hero got to Thant2 + AddSkipFunction(dialog02, Skipanim, {dialog02}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("Congratulations, now you can take Thanta's device part..."), 5000}}) + table.insert(dialog02, {func = AnimSay, args = {bandit1.gear, loc("Oh! Please spare me. You can take all my treasures!"), SAY_SAY, 3000}}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 5000}}) + table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("I just want the strange device you found!"), SAY_SAY, 3000}}) + table.insert(dialog02, {func = AnimWait, args = {bandit1.gear, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {bandit1.gear, loc("Here! Take it..."), SAY_SAY, 3000}}) + table.insert(dialog02, {func = actionsOnWin, args = {}}) +end + +-------------- Other Functions ------------------- + +function actionsOnWin() + saveCompletedStatus(4) + SendStat(siGameResult, loc("Congratulations, you acquired the device part!")) + SendStat(siCustomAchievement, loc("At the end of the game your health was ")..GetHealth(hero.gear)) + -- maybe add number of tries for each part? + SendStat(siPlayerKills,'1',teamC.name) + SendStat(siPlayerKills,'0',teamB.name) + EndGame() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice02.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice02.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice02.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice02.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,269 @@ +------------------- ABOUT ---------------------- +-- +-- Hero has to pass as fast as possible inside the +-- rings as in the racer mode + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Scripts/Utils.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Hard flying") +local challengeStarted = false +local currentWaypoint = 1 +local radius = 75 +local totalTime = 15000 +local totalSaucers = 3 +local gameEnded = false +local RED = 0xff0000ff +local GREEN = 0x38d61cff +local challengeObjectives = loc("To win the game you have to pass into the rings in time").. + "|"..loc("You'll get extra time in case you need it when you pass a ring").."|".. + loc("Every 2 rings, the ring color will be green and you'll get an extra flying saucer").."|".. + loc("Use space button twice to change flying saucer while floating in mid-air") +-- dialogs +local dialog01 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Getting ready"), challengeObjectives, 1, 4500}, +} +-- hogs +local hero = {} +local ally = {} +-- teams +local teamA = {} +local teamB = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 750 +hero.y = 130 +hero.dead = false +ally.name = loc("Paul McHoggy") +ally.x = 860 +ally.y = 130 +teamA.name = loc("Hog Solo") +teamA.color = tonumber("38D61C",16) -- green +teamB.name = loc("Allies") +teamB.color = tonumber("FF0000",16) -- red +-- way points +local current waypoint = 1 +local waypoints = { + [1] = {x=1450, y=140}, + [2] = {x=990, y=580}, + [3] = {x=1650, y=950}, + [4] = {x=620, y=630}, + [5] = {x=1470, y=540}, + [6] = {x=1960, y=60}, + [7] = {x=1600, y=400}, + [8] = {x=240, y=940}, + [9] = {x=200, y=530}, + [10] = {x=1180, y=120}, + [11] = {x=1950, y=660}, + [12] = {x=1280, y=980}, + [13] = {x=590, y=1100}, + [14] = {x=20, y=620}, + [15] = {x=hero.x, y=hero.y} +} + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + GameFlags = gfInvulnerable + Seed = 1 + TurnTime = 15000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Map = "ice02_map" + Theme = "Snow" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + -- Ally + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + ally.gear = AddHog(ally.name, 0, 100, "war_airwarden02") + AnimSetGearPosition(ally.gear, ally.x, ally.y) + HogTurnLeft(ally.gear, true) + + initCheckpoint("ice02") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + + AddAmmo(hero.gear, amJetpack, 3) + + -- place a waypoint + placeNextWaypoint() + + SendHealthStatsOff() + AddAnim(dialog01) +end + +function onNewTurn() + if not hero.dead and CurrentHedgehog == ally.gear and challengeStarted then + heroLost() + elseif not hero.dead and CurrentHedgehog == hero.gear and challengeStarted then + ParseCommand("setweap " .. string.char(amJetpack)) + end +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGameTick20() + if checkIfHeroInWaypoint() then + if not gameEnded and not placeNextWaypoint() then + gameEnded = true + -- GAME OVER, WIN! + totalTime = totalTime - TurnTimeLeft + totalTime = totalTime / 1000 + local saucersLeft = GetAmmoCount(hero.gear, amJetpack) + local saucersUsed = totalSaucers - saucersLeft + SendStat(siGameResult, loc("Hoorah! You are a champion!")) + SendStat(siCustomAchievement, loc("You completed the mission in "..totalTime.." seconds")) + SendStat(siCustomAchievement, loc("You have used "..saucersUsed.." flying saucers")) + SendStat(siCustomAchievement, loc("You had "..saucersLeft.." more flying saucers left")) + SendStat(siPlayerKills,'1',teamA.name) + EndGame() + end + end +end + +function onGearDelete(gear) + if gear == hero.gear then + hero.dead = true + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + heroLost() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + startFlying() +end + +function AnimationSetup() + -- DIALOG 01 - Start, some story telling + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("In the Ice Planet flying saucer stadium..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("This is the Olympic stadium of saucer flying..."), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("All the saucer pilots dream to come here one day in order to compete with the best!"), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Now you have the chance to try and claim the place that you deserve among the best..."), SAY_SAY, 6000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Use the saucer and pass through the rings..."), 5000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Pause the game by pressing the pause key (default \"P\") for more details"), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("... can you do it?"), SAY_SAY, 2000}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}}) + table.insert(dialog01, {func = startFlying, args = {hero.gear}}) +end + +------------------ Other Functions ------------------- + +function startFlying() + AnimSwitchHog(ally.gear) + TurnTimeLeft = 0 + challengeStarted = true +end + +function placeNextWaypoint() + if currentWaypoint > 1 then + local wp = waypoints[currentWaypoint-1] + DeleteVisualGear(wp.gear) + end + if currentWaypoint < 16 then + local wp = waypoints[currentWaypoint] + wp.gear = AddVisualGear(1,1,vgtCircle,1,true) + -- add bonus time and "fuel" + if currentWaypoint % 2 == 0 then + PlaySound(sndBump) -- what's the crate sound? + SetVisualGearValues(wp.gear, wp.x,wp.y, 20, 200, 0, 0, 100, radius, 3, RED) + AddAmmo(hero.gear, amJetpack, GetAmmoCount(hero.gear, amJetpack)+1) + totalSaucers = totalSaucers + 1 + local message = loc("Got 1 more saucer") + if TurnTimeLeft <= 22000 then + TurnTimeLeft = TurnTimeLeft + 8000 + totalTime = totalTime + 8000 + message = message..loc(" and 8 more seconds added to the clock") + end + AnimCaption(hero.gear, message, 4000) + else + SetVisualGearValues(wp.gear, wp.x,wp.y, 20, 200, 0, 0, 100, radius, 3, GREEN) + if TurnTimeLeft <= 16000 then + TurnTimeLeft = TurnTimeLeft + 6000 + totalTime = totalTime + 6000 + if currentWaypoint ~= 1 then + AnimCaption(hero.gear, loc("6 more seconds added to the clock"), 4000) + end + end + end + radius = radius - 4 + currentWaypoint = currentWaypoint + 1 + return true + else + AnimCaption(hero.gear, loc("Congratulations, you won!"), 4000) + end + return false +end + +function checkIfHeroInWaypoint() + if not hero.dead then + local wp = waypoints[currentWaypoint-1] + if gearIsInCircle(hero.gear, wp.x, wp.y, radius+4, false) then + SetWind(GetRandom(201)-100) + return true + end + end + return false +end + +function heroLost() + SendStat(siGameResult, loc("Oh man! Learn how to fly!")) + SendStat(siCustomAchievement, loc("To win the game you have to pass into the rings in time")) + SendStat(siCustomAchievement, loc("You'll get extra time in case you need it when you pass a ring")) + SendStat(siCustomAchievement, loc("Every 2 rings you'll get extra flying saucers")) + SendStat(siCustomAchievement, loc("Use space button twice to change flying saucer while being on air")) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon01.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon01.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon01.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon01.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,458 @@ +------------------- ABOUT ---------------------- +-- +-- This is the first stop of hero's journey. +-- Here he'll get fuels to continue traveling. +-- However, the PAotH allies of the hero have +-- been taken hostages by professor Hogevil. +-- So hero has to get whatever available equipement +-- there is and rescue them. + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local campaignName = loc("A Space Adventure") +local missionName = loc("The first stop") +local weaponsAcquired = false +local battleZoneReached = false +local checkPointReached = 1 -- 1 is start of the game +local afterDialog02 = false +-- dialogs +local dialog01 = {} +local dialog02 = {} +local dialog03 = {} +local dialog04 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Getting ready"), loc("Go to the upper platform and get the weapons in the crates!"), 1, 4500}, + [dialog02] = {missionName, loc("Prepare to fight"), loc("Go down and save these PAotH hogs!"), 1, 5000}, + [dialog03] = {missionName, loc("The fight begins!"), loc("Neutralize your enemies and be careful!"), 1, 5000}, + [dialog04] = {missionName, loc("The fight begins!"), loc("Neutralize your enemies and be careful!"), 1, 5000} +} +-- crates +local weaponsY = 100 +local bazookaX = 70 +local parachuteX = 110 +local grenadeX = 160 +local deserteagleX = 200 +-- hogs +local hero = {} +local paoth1 = {} +local paoth2 = {} +local paoth3 = {} +local paoth4 = {} +local professor = {} +local minion1 = {} +local minion2 = {} +local minion3 = {} +local minion4 = {} +-- teams +local teamA = {} +local teamB = {} +local teamC = {} +local teamD = {} +-- hedgehogs values +hero.name = loc("Hog Solo") +hero.x = 1380 +hero.y = 1750 +hero.dead = false +paoth1.name = loc("Joe") +paoth1.x = 1430 +paoth1.y = 1750 +paoth2.name = loc("Bruce") +paoth2.x = 3760 +paoth2.y = 1800 +paoth3.name = loc("Helena") +paoth3.x = 3800 +paoth3.y = 1800 +paoth4.name = loc("Boris") +paoth4.x = 3860 +paoth4.y = 1800 +professor.name = loc("Prof. Hogevil") +professor.x = 3800 +professor.y = 1600 +professor.dead = false +professor.health = 100 +minion1.name = loc("Minion") +minion1.x = 2460 +minion1.y = 1450 +minion2.name = loc("Minion") +minion2.x = 2450 +minion2.y = 1900 +minion3.name = loc("Minion") +minion3.x = 3500 +minion3.y = 1750 +teamA.name = loc("PAotH") +teamA.color = tonumber("FF0000",16) -- red +teamB.name = loc("Minions") +teamB.color = tonumber("0033FF",16) -- blue +teamC.name = loc("Professor") +teamC.color = tonumber("0033FF",16) -- blue +teamD.name = loc("Hog Solo") +teamD.color = tonumber("38D61C",16) -- green + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + Seed = 1 + GameFlags = gfSolidLand + gfDisableWind + TurnTime = 25000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 3000 + Explosives = 0 + Delay = 5 + Map = "moon01_map" + Theme = "Cheese" -- Because ofc moon is made of cheese :) + -- Hog Solo + AddTeam(teamD.name, teamD.color, "Bone", "Island", "HillBilly", "cm_birdy") + if tonumber(GetCampaignVar("HeroHealth")) then + hero.gear = AddHog(hero.name, 0, tonumber(GetCampaignVar("HeroHealth")), "war_desertgrenadier1") + else + hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1") + end + AnimSetGearPosition(hero.gear, hero.x, hero.y) + -- PAotH + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + paoth1.gear = AddHog(paoth1.name, 0, 100, "scif_2001O") + AnimSetGearPosition(paoth1.gear, paoth1.x, paoth1.y) + HogTurnLeft(paoth1.gear, true) + paoth2.gear = AddHog(paoth2.name, 0, 100, "scif_2001Y") + AnimSetGearPosition(paoth2.gear, paoth2.x, paoth2.y) + HogTurnLeft(paoth2.gear, true) + paoth3.gear = AddHog(paoth3.name, 0, 100, "hair_purple") + AnimSetGearPosition(paoth3.gear, paoth3.x, paoth3.y) + HogTurnLeft(paoth3.gear, true) + paoth4.gear = AddHog(paoth4.name, 0, 100, "scif_2001Y") + AnimSetGearPosition(paoth4.gear, paoth4.x, paoth4.y) + HogTurnLeft(paoth4.gear, true) + -- Professor + AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy") + professor.gear = AddHog(professor.name, 0, 120, "tophats") + AnimSetGearPosition(professor.gear, professor.x, professor.y) + HogTurnLeft(professor.gear, true) + -- Minions + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + minion1.gear = AddHog(minion1.name, 1, 50, "Gasmask") + AnimSetGearPosition(minion1.gear, minion1.x, minion1.y) + HogTurnLeft(minion1.gear, true) + minion2.gear = AddHog(minion2.name, 1, 50, "Gasmask") + AnimSetGearPosition(minion2.gear, minion2.x, minion2.y) + HogTurnLeft(minion2.gear, true) + minion3.gear = AddHog(minion3.name, 1, 50, "Gasmask") + AnimSetGearPosition(minion3.gear, minion3.x, minion3.y) + HogTurnLeft(minion3.gear, true) + + -- get the check point + checkPointReached = initCheckpoint("moon01") + if checkPointReached == 1 then + -- Start of the game + elseif checkPointReached == 2 then + AnimSetGearPosition(hero.gear, parachuteX, weaponsY) + if GetHealth(hero.gear) + 5 > 100 then + SaveCampaignVar("HeroHealth", 100) + else + SaveCampaignVar("HeroHealth", GetHealth(hero.gear) + 5) + end + end + + AnimInit() + AnimationSetup() +end + +function onGameStart() + -- wait for the first turn to start + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + + ShowMission(campaignName, missionName, loc("Hog Solo has to refuel his saucer.").. + "|"..loc("Rescue the imprisoned PAotH team and get the fuel!"), -amSkip, 0) + + AddAmmo(minion1.gear, amDEagle, 10) + AddAmmo(minion2.gear, amDEagle, 10) + AddAmmo(minion3.gear, amDEagle, 10) + AddAmmo(minion1.gear, amBazooka, 2) + AddAmmo(minion2.gear, amBazooka, 2) + AddAmmo(minion3.gear, amBazooka, 2) + AddAmmo(minion1.gear, amGrenade, 2) + AddAmmo(minion2.gear, amGrenade, 2) + AddAmmo(minion3.gear, amGrenade, 2) + + -- check for death has to go first + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + AddEvent(onProfessorDeath, {professor.gear}, professorDeath, {professor.gear}, 0) + AddEvent(onMinionsDeath, {professor.gear}, minionsDeath, {professor.gear}, 0) + AddEvent(onProfessorHit, {professor.gear}, professorHit, {professor.gear}, 1) + + if checkPointReached == 1 then + AddAmmo(hero.gear, amRope, 2) + SpawnAmmoCrate(bazookaX, weaponsY, amBazooka) + SpawnAmmoCrate(parachuteX, weaponsY, amParachute) + SpawnAmmoCrate(grenadeX, weaponsY, amGrenade) + SpawnAmmoCrate(deserteagleX, weaponsY, amDEagle) + AddEvent(onWeaponsPlatform, {hero.gear}, weaponsPlatform, {hero.gear}, 0) + TurnTimeLeft = 0 + AddAnim(dialog01) + elseif checkPointReached == 2 then + AddAmmo(hero.gear, amBazooka, 3) + AddAmmo(hero.gear, amParachute, 1) + AddAmmo(hero.gear, amGrenade, 6) + AddAmmo(hero.gear, amDEagle, 4) + SetWind(60) + GameFlags = bor(GameFlags,gfDisableWind) + weaponsAcquired = true + afterDialog02 = true + TurnTimeLeft = 0 + AddAnim(dialog02) + end + -- this event check goes here to be executed after the onWeaponsPlatform check + AddEvent(onBattleZone, {hero.gear}, battleZone, {hero.gear}, 0) + + SendHealthStatsOff() +end + +function onAmmoStoreInit() + SetAmmo(amBazooka, 0, 0, 0, 3) + SetAmmo(amParachute, 0, 0, 0, 1) + SetAmmo(amGrenade, 0, 0, 0, 6) + SetAmmo(amDEagle, 0, 0, 0, 4) +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() + if CurrentHedgehog ~= hero.gear and not battleZone then + TurnTimeLeft = 0 + end +end + +function onNewTurn() + -- rounds start if hero got his weapons or got near the enemies + if not weaponsAcquired and not battleZoneReached and CurrentHedgehog ~= hero.gear then + TurnTimeLeft = 0 + elseif weaponsAcquired and not battleZoneReached and CurrentHedgehog ~= hero.gear and afterDialog02 then + battleZone(hero.gear) + elseif not weaponsAcquired and not battleZoneReached and CurrentHedgehog == hero.gear then + TurnTimeLeft = -1 + elseif CurrentHedgehog == paoth1.gear or CurrentHedgehog == paoth2.gear + or CurrentHedgehog == paoth3.gear or CurrentHedgehog == paoth4.gear then + TurnTimeLeft = 0 + elseif CurrentHedgehog == professor.gear then + AnimSwitchHog(hero.gear) + TurnTimeLeft = 0 + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +function onGearDelete(gear) + if gear == hero.gear then + hero.dead = true + elseif gear == professor.gear then + professor.dead = true + end +end + +-------------- EVENTS ------------------ + +function onWeaponsPlatform(gear) + if not hero.dead and (GetAmmoCount(hero.gear, amBazooka) > 0 or GetAmmoCount(hero.gear, amParachute) > 0 or + GetAmmoCount(hero.gear, amGrenade) > 0 or GetAmmoCount(hero.gear, amDEagle) > 0) and StoppedGear(hero.gear) then + return true + end + return false +end + +function onHeroDeath(gear) + if hero.dead then + return true + end + return false +end + +function onBattleZone(gear) + if not battleZoneReached and not hero.dead and GetX(gear) > 1900 and StoppedGear(gear) then + return true + end + return false +end + +function onProfessorHit(gear) + if GetHealth(gear) then + if CurrentHedgehog ~= hero.gear and GetHealth(gear) < professor.health then + professor.health = GetHealth(gear) + return true + elseif GetHealth(gear) < professor.health then + professor.health = GetHealth(gear) + end + end + return false +end + +function onProfessorDeath(gear) + if professor.dead then + return true + end + return false +end + +function onMinionsDeath(gear) + if not (GetHealth(minion1.gear) or GetHealth(minion2.gear) or GetHealth(minion3.gear)) then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function weaponsPlatform(gear) + saveCheckpoint("2") + SaveCampaignVar("HeroHealth",GetHealth(hero.gear)) + TurnTimeLeft = 0 + weaponsAcquired = true + SetWind(60) + GameFlags = bor(GameFlags,gfDisableWind) + AddAmmo(hero.gear, amRope, 0) + if GetX(hero.gear) < 1900 then + AddAnim(dialog02) + end +end + +function heroDeath(gear) + SendStat(siGameResult, loc("Hog Solo lost, try again!")) + SendStat(siCustomAchievement, loc("You have to get the weapons and rescue the PAotH researchers")) + SendStat(siPlayerKills,'1',teamC.name) + SendStat(siPlayerKills,'0',teamD.name) + EndGame() +end + +function battleZone(gear) + TurnTimeLeft = 0 + battleZoneReached = true + if weaponsAcquired then + AddAnim(dialog04) + else + AddAnim(dialog03) + end +end + +function professorHit(gear) + if currentHedgehog ~= hero.gear then + AnimSay(professor.gear,loc("Don't hit me you fools!"), SAY_SHOUT, 2000) + end +end + +function professorDeath(gear) + if GetHealth(minion1.gear) then + AnimSay(minion1.gear, loc("The boss has fallen! Retreat!"), SAY_SHOUT, 6000) + elseif GetHealth(minion2.gear) then + AnimSay(minion2.gear, loc("The boss has fallen! Retreat!"), SAY_SHOUT, 6000) + elseif GetHealth(minion3.gear) then + AnimSay(minion3.gear, loc("The boss has fallen! Retreat!"), SAY_SHOUT, 6000) + end + ParseCommand("teamgone " .. teamB.name) + AnimCaption(hero.gear, loc("Congrats! You made them run away!"), 6000) + AnimWait(hero.gear,5000) + + saveCompletedStatus(1) + SendStat(siGameResult, loc("Hog Solo wins, congratulations!")) + SendStat(siCustomAchievement, loc("Eliminated the Professor Hogevil")) + SendStat(siCustomAchievement, loc("Drove the minions away")) + SendStat(siPlayerKills,'1',teamD.name) + SendStat(siPlayerKills,'0',teamC.name) + SaveCampaignVar("CosmosCheckPoint", "5") -- hero got fuels + EndGame() +end + +function minionsDeath(gear) + -- do staffs here + AnimSay(professor.gear, loc("I may lost this battle, but I haven't lost the war yet!"), SAY_SHOUT, 6000) + ParseCommand("teamgone " .. teamC.name) + AnimCaption(hero.gear, loc("Congrats! You won!"), 6000) + AnimWait(hero.gear,5000) + + saveCompletedStatus(1) + SendStat(siGameResult, loc("Congratulations, you won!")) + SendStat(siCustomAchievement, loc("Eliminated the evil minions")) + SendStat(siCustomAchievement, loc("Drove the Professor away")) + SendStat(siPlayerKills,'1',teamD.name) + SendStat(siPlayerKills,'0',teamC.name) + SaveCampaignVar("CosmosCheckPoint", "5") -- hero got fuels + EndGame() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + if anim == dialog02 then + setAfterDialog02() + elseif anim == dialog03 then + startCombat() + else + AnimSwitchHog(hero.gear) + end +end + +function AnimationSetup() + -- DIALOG 01 - Start, welcome to moon + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Near PAotH base at moon..."), 4000}}) + table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("Hey Hog Solo! Finally you have come..."), SAY_SAY, 2000}}) + table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("It seems that Professor Hogevil has prepared for your arrival!"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("He has captured the rest of the PAotH team and awaits to capture you!"), SAY_SAY, 5000}}) + table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("We have to hurry! Are you armed?"), SAY_SAY, 4300}}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 450}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("No, I am afraid I had to travel light"), SAY_SAY, 2500}}) + table.insert(dialog01, {func = AnimWait, args = {paoth1.gear, 3200}}) + table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("Ok, then you have to go and take some of the weapons we have hidden in case of an emergency!"), SAY_SAY, 7000}}) + table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("They are up there! Take this rope and hurry!"), SAY_SAY, 7000}}) + table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Ehm... ok..."), SAY_SAY, 2500}}) + table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG 02 - To the weapons platform + AddSkipFunction(dialog02, Skipanim, {dialog02}) + table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("Checkpoint reached!"), 4000}}) + table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("I've made it! YEAAAAAH!"), SAY_SHOUT, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {paoth1.gear, loc("Nice! Now hurry and get down! You have to rescue my friends!"), SAY_SHOUT, 7000}}) + table.insert(dialog02, {func = setAfterDialog02, args = {}}) + table.insert(dialog02, {func = AnimSwitchHog, args = {hero.gear}}) + -- DIALOG 03 - Hero spotted and has no weapons + AddSkipFunction(dialog03, Skipanim, {dialog03}) + table.insert(dialog03, {func = AnimCaption, args = {hero.gear, loc("Get ready to fight!"), 4000}}) + table.insert(dialog03, {func = AnimSay, args = {minion1.gear, loc("Look boss! There is the target!"), SAY_SHOUT, 4000}}) + table.insert(dialog03, {func = AnimSay, args = {professor.gear, loc("Prepare for battle!"), SAY_SHOUT, 4000}}) + table.insert(dialog03, {func = AnimSay, args = {hero.gear, loc("Oops, I've been spotted and I have no weapons! I am doomed!"), SAY_THINK, 4000}}) + table.insert(dialog03, {func = startCombat, args = {hero.gear}}) + -- DIALOG 04 - Hero spotted and *HAS* weapons + AddSkipFunction(dialog04, Skipanim, {dialog04}) + table.insert(dialog04, {func = AnimCaption, args = {hero.gear, loc("Get ready to fight!"), 4000}}) + table.insert(dialog04, {func = AnimSay, args = {minion1.gear, loc("Look boss! There is the target!"), SAY_SHOUT, 4000}}) + table.insert(dialog04, {func = AnimSay, args = {professor.gear, loc("Prepare for battle!"), SAY_SHOUT, 4000}}) + table.insert(dialog04, {func = AnimSay, args = {hero.gear, loc("Here we go!"), SAY_THINK, 4000}}) + table.insert(dialog04, {func = startCombat, args = {hero.gear}}) +end + +------------------- custom "animation" functions -------------------------- + +function startCombat() + -- use this so minion3 will gain control + AnimSwitchHog(minion3.gear) + TurnTimeLeft = 0 +end + +function setAfterDialog02() + afterDialog02 = true +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon02.hwp Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon02.hwp has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon02.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon02.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,237 @@ +------------------- ABOUT ---------------------- +-- +-- Hog Solo has to catch the other hog in order +-- to get informations about the origin of Pr. Hogevil + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Animate.lua") +HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua") + +----------------- VARIABLES -------------------- +-- globals +local missionName = loc("Chasing the blue hog") +local challengeObjectives = loc("Use the rope in order to catch the blue hedgehog").."|".. + loc("You have to stand very close to him") +local currentPosition = 1 +local previousTimeLeft = 0 +local startChallenge = false +-- dialogs +local dialog01 = {} +local dialog02 = {} +-- mission objectives +local goals = { + [dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500}, +} +-- hogs +local hero = { + name = loc("Hog Solo"), + x = 1300, + y = 850 +} +local runner = { + name = loc("Crazy Runner"), + places = { + {x = 1400,y = 850, turnTime = 0}, + {x = 3880,y = 33, turnTime = 30000}, + {x = 250,y = 1780, turnTime = 25000}, + {x = 3850,y = 1940, turnTime = 20000}, + } +} +-- teams +local teamA = { + name = loc("Hog Solo"), + color = tonumber("38D61C",16) -- green +} +local teamB = { + name = loc("Crazy Runner"), + color = tonumber("FF0000",16) -- red +} + +-------------- LuaAPI EVENT HANDLERS ------------------ + +function onGameInit() + GameFlags = gfDisableWind + Seed = 1 + TurnTime = 25000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 1 + Explosives = 0 + Map = "moon02_map" + Theme = "Cheese" + + -- Hog Solo + AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy") + hero.gear = AddHog(hero.name, 0, 1, "war_desertgrenadier1") + AnimSetGearPosition(hero.gear, hero.x, hero.y) + -- Crazy Runner + AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy") + runner.gear = AddHog(runner.name, 0, 100, "sth_Sonic") + AnimSetGearPosition(runner.gear, runner.places[1].x, runner.places[1].y) + HogTurnLeft(runner.gear, true) + + initCheckpoint("moon02") + + AnimInit() + AnimationSetup() +end + +function onGameStart() + AnimWait(hero.gear, 3000) + FollowGear(hero.gear) + ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0) + + AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0) + + AddAmmo(hero.gear, amRope, 1) + + SendHealthStatsOff() + hogTurn = runner.gear + AddAnim(dialog01) +end + +function onNewTurn() + if startChallenge and currentPosition < 5 then + if CurrentHedgehog ~= hero.gear then + TurnTimeLeft = 0 + else + if GetAmmoCount(hero.gear, amRope) == 0 then + lose() + end + ParseCommand("setweap " .. string.char(amRope)) + TurnTimeLeft = runner.places[currentPosition].turnTime + previousTimeLeft + previousTimeLeft = 0 + end + end +end + +function onGameTick() + AnimUnWait() + if ShowAnimation() == false then + return + end + ExecuteAfterAnimations() + CheckEvents() +end + +function onGameTick20() + if GetHealth(hero.gear) and startChallenge and isHeroNextToRunner() and currentPosition < 5 then + moveRunner() + end +end + +function onPrecise() + if GameTime > 3000 then + SetAnimSkip(true) + end +end + +-------------- EVENTS ------------------ + +function onHeroDeath(gear) + if not GetHealth(hero.gear) then + return true + end + return false +end + +-------------- ACTIONS ------------------ + +function heroDeath(gear) + lose() +end + +-------------- ANIMATIONS ------------------ + +function Skipanim(anim) + if goals[anim] ~= nil then + ShowMission(unpack(goals[anim])) + end + if anim == dialog01 then + moveRunner() + elseif anim == dialog02 then + win() + end +end + +function AnimationSetup() + -- DIALOG 01 - Start, game instructions + AddSkipFunction(dialog01, Skipanim, {dialog01}) + table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3200}}) + table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("On the other side of the moon..."), 5000}}) + table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("So you are interested in Professor Hogevil"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("We'll play a game first"), SAY_SAY, 3000}}) + table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("I'll let you know whatever I know about him if you manage to catch me 3 times"), SAY_SAY, 4000}}) + table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("Let's go!"), SAY_SAY, 2000}}) + table.insert(dialog01, {func = moveRunner, args = {}}) + -- DIALOG 02 - Hog Solo story + AddSkipFunction(dialog02, Skipanim, {dialog02}) + table.insert(dialog02, {func = AnimWait, args = {hero.gear, 3200}}) + table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("The truth about Professor Hogevil"), 5000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("Amazing! I was never beaten in a race before!"), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("So, let me tell you what I know about Professor Hogevil..."), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("Professor Hogevil, then known as James Hogus, worked for PAotH back in my time"), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("He was the lab assistant of Dr. Goodhogan, the inventor of the anti-gravity device"), SAY_SAY, 5000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("During the final testing of the device an accident happened"), SAY_SAY, 5000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("In this accident Professor Hogevil lost all his spines on his head!"), SAY_SAY, 5000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("That's why he always wears a hat since then"), SAY_SAY, 4000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("After that incident he went underground and started working on his plan to steal the device"), SAY_SAY, 5000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("He is a very tough and very determined hedgehog. I would be extremely careful if I were you"), SAY_SAY, 5000}}) + table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("I should go now, goodbye!"), SAY_SAY, 3000}}) + table.insert(dialog02, {func = win, args = {}}) +end + +------------- other functions --------------- + +function isHeroNextToRunner() + if GetHealth(hero.gear) and math.abs(GetX(hero.gear) - GetX(runner.gear)) < 75 and + math.abs(GetY(hero.gear) - GetY(runner.gear)) < 75 and StoppedGear(hero.gear) then + return true + end + return false +end + +function moveRunner() + if currentPosition == 4 then + currentPosition = currentPosition + 1 + if GetX(hero.gear) > GetX(runner.gear) then + HogTurnLeft(runner.gear, false) + end + AddAnim(dialog02) + TurnTimeLeft = 0 + elseif currentPosition < 4 then + if not startChallenge then + startChallenge = true + end + AddAmmo(hero.gear, amRope, 1) + if currentPosition ~= 1 then + PlaySound(sndVictory) + if currentPosition > 1 and currentPosition < 4 then + AnimCaption(hero.gear, loc("Go get him again"), 3000) + AnimSay(runner.gear, loc("You got me"), SAY_SAY, 3000) + end + previousTimeLeft = TurnTimeLeft + end + currentPosition = currentPosition + 1 + AddVisualGear(GetX(runner.gear), GetY(runner.gear), vgtExplosion, 0, false) + SetGearPosition(runner.gear, runner.places[currentPosition].x, runner.places[currentPosition].y) + TurnTimeLeft = 0 + end +end + +function lose() + SendStat(siGameResult, loc("Too slow! Try again...")) + SendStat(siCustomAchievement, loc("You have to catch the other hog 3 times")) + SendStat(siCustomAchievement, loc("The time that you have left when you reach the blue hedgehog will be added to the next turn")) + SendStat(siCustomAchievement, loc("Each turn you'll have only one rope to use")) + SendStat(siCustomAchievement, loc("You'll lose if you die or if your time is up")) + SendStat(siPlayerKills,'0',teamA.name) + EndGame() +end + +function win() + SendStat(siGameResult, loc("Congratulations, you are the fastest!")) + SendStat(siCustomAchievement, loc("You have managed to catch the blue hedgehog in time")) + SendStat(siPlayerKills,'1',teamA.name) + EndGame() +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Campaign/CMakeLists.txt --- a/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt Sat Jan 04 23:55:54 2014 +0400 @@ -1,4 +1,5 @@ add_subdirectory("A_Classic_Fairytale") +add_subdirectory("A_Space_Adventure") file(GLOB Scripts *.lua) diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Missions/Training/User_Mission_-_Newton_and_the_Hammock.lua --- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Newton_and_the_Hammock.lua Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Newton_and_the_Hammock.lua Sat Jan 04 23:55:54 2014 +0400 @@ -126,7 +126,7 @@ if (gear == enemy) and (failed == false) then ShowMission(loc("Newton's Hammock"), loc("MISSION SUCCESSFUL"), loc("Congratulations!"), 0, 0) elseif gear == player then - ShowMission(loc("Newton's Hammock"), loc("MISSION FAILED"), loc("Oh no! Just try again!"), -amSkip, 0) + ShowMission(loc("Newton's Hammock"), loc("MISSION FAILED"), loc("Oh no! Just try again!"), -amSkip, 0) end end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Scripts/Multiplayer/Continental_supplies.lua --- a/share/hedgewars/Data/Scripts/Multiplayer/Continental_supplies.lua Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Continental_supplies.lua Sat Jan 04 23:55:54 2014 +0400 @@ -1,5 +1,5 @@ --[[ -Version 1.1c +Made for 0.9.20 Copyright (C) 2012 Vatten @@ -44,6 +44,15 @@ end end +function EndTurn(baseRetreatTime) + local retreatTimePercentage = 100 + SetState(CurrentHedgehog,bor(GetState(CurrentHedgehog),gstAttacked)) + TurnTimeLeft = baseRetreatTime / 100 * retreatTimePercentage + end + +--for sundaland +local turnhog=0 + local teams_ok = {} local wepcode_teams={} local swapweps=false @@ -52,7 +61,6 @@ local australianSpecial=false local africanSpecial=0 local africaspecial2=0 -local asianSpecial=false local samericanSpecial=false local namericanSpecial=1 local sniper_s_in_use=false @@ -72,72 +80,78 @@ --for sabotage local disallowattack=0 local disable_moving={} -local disableoffsetai=0 +local disableRand=0 +--local disableoffsetai=0 local onsabotageai=false local continent = {} -local generalinfo=loc("- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]") +local generalinfo="- "..loc("Per team weapons").."|- 10 "..loc("weaponschemes").."|- "..loc("Unique new weapons").."| |"..loc("Select continent first round with the Weapon Menu or by").." (["..loc("switch").."/"..loc("tab").."]="..loc("Increase")..",["..loc("presice").."/"..loc("left shift").."]="..loc("Decrease")..") "..loc("on Skip").."|"..loc("Some weapons have a second option. Find them with").." ["..loc("switch").."/"..loc("tab").."]" local weapontexts = { -loc("Green lipstick bullet: [Is poisonous]"), -loc("Piñata bullet: [Contains some sweet candy!]"), -loc("Anno 1032: [The explosion will make a strong push ~ wide range, wont affect hogs close to the target]"), +loc("Green lipstick bullet: [Poisonous, deals no damage]"), +loc("REMOVED"), +loc("Anno 1032: [The explosion will make a strong push ~ Wide range, wont affect hogs close to the target]"), loc("Dust storm: [Deals 15 damage to all enemies in the circle]"), -loc("Fire a mine: [Does what it says ~ Cant be dropped close to an enemy ~ 1 sec]"), -loc("Drop a bomb: [drop some heroic wind that will turn into a bomb on impact ~ once per turn]"), -loc("Scream from a Walrus: [Deal 20 damage + 10% of your hogs health to all hogs around you and get half back]"), +loc("Cricket time: [Drop a fireable mine! ~ Will work if fired close to your hog & far away from enemy ~ 1 sec]"), +loc("Drop a bomb: [Drop some heroic wind that will turn into a bomb on impact]"), +loc("Penguin roar: [Deal 15 damage + 15% of your hogs health to all hogs around you and get 2/3 back]"), loc("Disguise as a Rockhopper Penguin: [Swap place with a random enemy hog in the circle]"), -loc("Flare: [fire up some bombs depending on hogs depending on hogs in the circle"), +loc("REMOVED"), loc("Lonely Cries: [Rise the water if no hog is in the circle and deal 7 damage to all enemy hogs]"), -loc("Hedgehog projectile: [fire your hog like a Sticky Bomb]"), +loc("Hedgehog projectile: [Fire your hog like a Sticky Bomb]"), loc("Napalm rocket: [Fire a bomb with napalm!]"), -loc("Eagle Eye: [Blink to the impact ~ one shot]"), +loc("Eagle Eye: [Blink to the impact ~ One shot]"), loc("Medicine: [Fire some exploding medicine that will heal all hogs effected by the explosion]"), -loc("Sabotage: [Sabotage all hogs in the circle and deal ~10 dmg]") +loc("Sabotage/Flare: [Sabotage all hogs in the circle and deal ~1 dmg OR Fire a cluster up into the air]") } local weaponsets = { -{loc("North America"),"Area: 24,709,000 km2, Population: 528,720,588",loc("Special Weapons:").."|"..loc("Shotgun")..": "..weapontexts[13].."|"..loc("Sniper Rifle")..": "..weapontexts[1].."|"..loc("Sniper Rifle")..": "..weapontexts[2],amSniperRifle, -{{amShotgun,100},{amDEagle,100},{amLaserSight,4},{amSniperRifle,100},{amCake,1},{amAirAttack,2},{amSwitch,6}}}, +{loc("North America"),loc("Area")..": 24,709,000 km2, "..loc("Population")..": 529,000,000",loc("- Will give you an airstrike every fifth turn.").."|"..loc("Special Weapons:").."|"..loc("Shotgun")..": "..weapontexts[13].."|"..loc("Sniper Rifle")..": "..weapontexts[1],amSniperRifle, +{{amShotgun,100},{amDEagle,100},{amLaserSight,4},{amSniperRifle,100},{amCake,1},{amAirAttack,2},{amSwitch,5}}}, -{loc("South America"),"Area: 17,840,000 km2, Population: 387,489,196 ",loc("Special Weapons:").."|"..loc("GasBomb")..": "..weapontexts[3],amGasBomb, -{{amBirdy,6},{amHellishBomb,1},{amBee,100},{amWhip,100},{amGasBomb,100},{amFlamethrower,100},{amNapalm,1},{amExtraDamage,2}}}, +{loc("South America"),loc("Area")..": 17,840,000 km2, "..loc("Population")..": 387,000,000",loc("Special Weapons:").."|"..loc("GasBomb")..": "..weapontexts[3],amGasBomb, +{{amBirdy,100},{amHellishBomb,1},{amBee,100},{amGasBomb,100},{amFlamethrower,100},{amNapalm,1},{amExtraDamage,3}}}, -{loc("Europe"),"Area: 10,180,000 km2, Population: 739,165,030",loc("Special Weapons:").."|"..loc("Molotov")..": "..weapontexts[14],amBazooka, -{{amBazooka,100},{amGrenade,100},{amMortar,100},{amClusterBomb,5},{amMolotov,5},{amVampiric,4},{amPiano,1},{amResurrector,2},{amJetpack,2}}}, +{loc("Europe"),loc("Area")..": 10,180,000 km2, "..loc("Population")..": 740,000,000",loc("Special Weapons:").."|"..loc("Molotov")..": "..weapontexts[14],amBazooka, +{{amBazooka,100},{amGrenade,100},{amMortar,100},{amMolotov,100},{amVampiric,3},{amPiano,1},{amResurrector,2},{amJetpack,4}}}, -{loc("Africa"),"Area: 30,221,532 km2, Population: 1,032,532,974",loc("Special Weapons:").."|"..loc("Seduction")..": "..weapontexts[4].."|"..loc("Sticky Mine")..": "..weapontexts[11].."|"..loc("Sticky Mine")..": "..weapontexts[12],amSMine, -{{amSMine,100},{amWatermelon,1},{amDrillStrike,1},{amExtraTime,2},{amDrill,100},{amLandGun,3},{amSeduction,100}}}, +{loc("Africa"),loc("Area")..": 30,222,000 km2, "..loc("Population")..": 1,033,000,000",loc("Special Weapons:").."|"..loc("Seduction")..": "..weapontexts[4].."|"..loc("Sticky Mine")..": "..weapontexts[11].."|"..loc("Sticky Mine")..": "..weapontexts[12],amSMine, +{{amSMine,100},{amWatermelon,1},{amDrillStrike,1},{amDrill,100},{amInvulnerable,4},{amSeduction,100},{amLandGun,2}}}, + +{loc("Asia"),loc("Area")..": 44,579,000 km2, "..loc("Population")..": 3,880,000,000",loc("- Will give you a parachute every second turn.").."|"..loc("Special Weapons:").."|"..loc("Parachute")..": "..weapontexts[6],amRope, +{{amRope,100},{amFirePunch,100},{amParachute,1},{amKnife,2},{amDynamite,1}}}, -{loc("Asia"),"Area: 44,579,000 km2, Population: 3,879,000,000",loc("- Will give you a parachute each turn.").."|"..loc("Special Weapons:").."|"..loc("Parachute")..": "..weapontexts[6],amRope, -{{amKamikaze,4},{amRope,100},{amFirePunch,100},{amParachute,1},{amKnife,2},{amDynamite,1}}}, +{loc("Australia"),loc("Area")..": 8,468,000 km2, "..loc("Population")..": 31,000,000",loc("Special Weapons:").."|"..loc("Baseballbat")..": "..weapontexts[5],amBaseballBat, +{{amBaseballBat,100},{amMine,100},{amLowGravity,4},{amBlowTorch,100},{amRCPlane,2},{amTeleport,3}}}, -{loc("Australia"),"Area: 8,468,300 km2, Population: 31,260,000",loc("Special Weapons:").."|"..loc("Baseballbat")..": "..weapontexts[5],amBaseballBat, -{{amBaseballBat,100},{amMine,100},{amLowGravity,6},{amBlowTorch,100},{amRCPlane,2},{amTardis,100}}}, +{loc("Antarctica"),loc("Area")..": 14,000,000 km2, "..loc("Population")..": ~1,000",loc("Antarctic summer: - Will give you one girder/mudball and two sineguns/portals every fourth turn."),amIceGun, +{{amSnowball,2},{amIceGun,2},{amPickHammer,100},{amSineGun,4},{amGirder,2},{amExtraTime,2},{amPortalGun,2}}}, -{loc("Antarctica"),"Area: 14,000,000 km2, Population: ~1,000",loc("- Will give you a portalgun every second turn."),amTeleport, -{{amSnowball,4},{amTeleport,2},{amInvulnerable,6},{amPickHammer,100},{amSineGun,100},{amGirder,3},{amPortalGun,2}}}, +{loc("Kerguelen"),loc("Area")..": 1,100,000 km2, "..loc("Population")..": ~100",loc("Special Weapons:").."|"..loc("Hammer")..": "..weapontexts[7].."|"..loc("Hammer")..": "..weapontexts[8].." ("..loc("Duration")..": 2)|"..loc("Hammer")..": "..weapontexts[10].."|"..loc("Hammer")..": "..weapontexts[15],amHammer, +{{amHammer,100},{amMineStrike,2},{amBallgun,1}}}, -{loc("Kerguelen"),"Area: 1,100,000 km2, Population: ~70",loc("Special Weapons:").."|"..loc("Hammer")..": "..weapontexts[7].."|"..loc("Hammer")..": "..weapontexts[8].." ("..loc("Duration")..": 2)|"..loc("Hammer")..": "..weapontexts[9].."|"..loc("Hammer")..": "..weapontexts[10].."|"..loc("Hammer")..": "..weapontexts[15],amHammer, -{{amHammer,100},{amMineStrike,2},{amBallgun,1},{amIceGun,2}}}, +{loc("Zealandia"),loc("Area")..": 3,500,000 km2, "..loc("Population")..": 5,000,000",loc("- Will Get 1-3 random weapons") .. "|" .. loc("- Massive weapon bonus on first turn"),amInvulnerable, +{{amBazooka,1},{amGrenade,1},{amBlowTorch,1},{amSwitch,100},{amRope,1},{amDrill,1},{amDEagle,1},{amPickHammer,1},{amFirePunch,1},{amWhip,1},{amMortar,1},{amSnowball,1},{amExtraTime,1},{amInvulnerable,1},{amVampiric,1},{amFlamethrower,1},{amBee,1},{amClusterBomb,1},{amTeleport,1},{amLowGravity,1},{amJetpack,1},{amGirder,1},{amLandGun,1},{amBirdy,1}}}, -{loc("Zealandia"),"Area: 3,500,000 km2, Population: 4,650,000",loc("- Will Get 1-3 random weapons"),amInvulnerable, -{{amBazooka,1},{amBlowTorch,1},{amSwitch,1}}} +{loc("Sundaland"),loc("Area")..": 1,850,000 km2, "..loc("Population")..": 290,000,000",loc("- You will recieve 2-4 weapons on each kill! (Even on own hogs)"),amTardis, +{{amClusterBomb,3},{amTardis,4},{amWhip,100},{amKamikaze,4}}} + } local weaponsetssounds= { -{sndShotgunFire,sndCover}, -{sndEggBreak,sndLaugh}, -{sndExplosion,sndEnemyDown}, -{sndMelonImpact,sndHello}, -{sndRopeAttach,sndComeonthen}, -{sndBaseballBat,sndNooo}, -{sndSineGun,sndOops}, -{sndPiano5,sndStupid}, -{sndSplash,sndFirstBlood} + {sndShotgunFire,sndCover}, + {sndEggBreak,sndLaugh}, + {sndExplosion,sndEnemyDown}, + {sndMelonImpact,sndCoward}, + {sndRopeAttach,sndComeonthen}, + {sndBaseballBat,sndNooo}, + {sndSineGun,sndOops}, + {sndPiano5,sndStupid}, + {sndSplash,sndFirstBlood}, + {sndWarp,sndSameTeam} } --weapontype,ammo,?,duration,*times your choice,affect on random team (should be placed with 1,0,1,0,1 on the 6th option for better randomness) @@ -147,7 +161,7 @@ {amBazooka, 0, 1, 0, 1, 0}, {amMineStrike, 0, 1, 5, 1, 2}, {amGrenade, 0, 1, 0, 1, 0}, - {amPiano, 0, 1, 5, 1, 1}, + {amPiano, 0, 1, 5, 1, 0}, {amClusterBomb, 0, 1, 0, 1, 0}, {amBee, 0, 1, 0, 1, 0}, {amShotgun, 0, 0, 0, 1, 1}, @@ -168,7 +182,7 @@ {amDrill, 0, 1, 0, 1, 0}, {amBallgun, 0, 1, 5, 1, 2}, {amMolotov, 0, 1, 0, 1, 0}, - {amBirdy, 0, 1, 1, 1, 1}, + {amBirdy, 0, 1, 0, 1, 0}, {amBlowTorch, 0, 1, 0, 1, 0}, {amRCPlane, 0, 1, 5, 1, 2}, {amGasBomb, 0, 0, 0, 1, 0}, @@ -178,7 +192,6 @@ {amHammer, 0, 1, 0, 1, 0}, {amDrillStrike, 0, 1, 4, 1, 2}, {amSnowball, 0, 1, 0, 1, 0} - --{amStructure, 0, 0, 0, 1, 1} } local weapons_supp = { {amParachute, 0, 1, 0, 1, 0}, @@ -205,7 +218,20 @@ function validate_weapon(hog,weapon,amount) if(MapHasBorder() == false or (MapHasBorder() == true and weapon ~= amAirAttack and weapon ~= amMineStrike and weapon ~= amNapalm and weapon ~= amDrillStrike and weapon ~= amPiano)) then - AddAmmo(hog, weapon,amount) + if(amount==1) + then + AddAmmo(hog, weapon) + else + AddAmmo(hog, weapon,amount) + end + end +end + +function RemoveWeapon(hog,weapon) + + if(GetAmmoCount(hog, weapon)<100) + then + AddAmmo(hog,weapon,GetAmmoCount(hog, weapon)-1) end end @@ -233,11 +259,22 @@ --list up all weapons from the icons for each continent function load_continent_selection(hog) - for v,w in pairs(weaponsets) - do - validate_weapon(hog, weaponsets[v][4],1) + + if(GetHogLevel(hog)==0) + then + for v,w in pairs(weaponsets) + do + validate_weapon(hog, weaponsets[v][4],1) + end + AddAmmo(hog,amSwitch) --random continent + + --for the computers + else + --europe + validate_weapon(hog, weaponsets[3][4],1) + --north america + validate_weapon(hog, weaponsets[1][4],1) end - AddAmmo(hog,amSwitch) --random continent end --shows the continent info @@ -293,12 +330,12 @@ local numberof_weapons_supp=table.maxn(weapons_supp) local numberof_weapons_dmg=table.maxn(weapons_dmg) - local rand1=GetRandom(table.maxn(weapons_supp))+1 - local rand2=GetRandom(table.maxn(weapons_dmg))+1 + local rand1=math.abs(GetRandom(numberof_weapons_supp)+1) + local rand2=math.abs(GetRandom(numberof_weapons_dmg)+1) - random_weapon = GetRandom(table.maxn(weapons_dmg))+1 + random_weapon = math.abs(GetRandom(table.maxn(weapons_dmg))+1) - while(weapons_dmg[random_weapon][4]>TotalRounds) + while(weapons_dmg[random_weapon][4]>TotalRounds or (MapHasBorder() == true and (weapons_dmg[random_weapon][1]== amAirAttack or weapons_dmg[random_weapon][1] == amMineStrike or weapons_dmg[random_weapon][1] == amNapalm or weapons_dmg[random_weapon][1] == amDrillStrike or weapons_dmg[random_weapon][1] == amPiano))) do if(random_weapon>=numberof_weapons_dmg) then @@ -328,7 +365,7 @@ if(rand_weaponset_power <1) then random_weapon = rand2 - while(weapons_dmg[random_weapon][4]>TotalRounds or old_rand_weap == random_weapon or weapons_dmg[random_weapon][6]>0) + while(weapons_dmg[random_weapon][4]>TotalRounds or old_rand_weap == random_weapon or weapons_dmg[random_weapon][6]>0 or (MapHasBorder() == true and (weapons_dmg[random_weapon][1]== amAirAttack or weapons_dmg[random_weapon][1] == amMineStrike or weapons_dmg[random_weapon][1] == amNapalm or weapons_dmg[random_weapon][1] == amDrillStrike or weapons_dmg[random_weapon][1] == amPiano))) do if(random_weapon>=numberof_weapons_dmg) then @@ -343,6 +380,88 @@ end end +--sundaland add weps +function get_random_weapon_on_death(hog) + + local random_weapon = 0 + local old_rand_weap = 0 + local rand_weaponset_power = 0 + + local firstTurn=0 + + local numberof_weapons_supp=table.maxn(weapons_supp) + local numberof_weapons_dmg=table.maxn(weapons_dmg) + + local rand1=GetRandom(numberof_weapons_supp)+1 + local rand2=GetRandom(numberof_weapons_dmg)+1 + local rand3=GetRandom(numberof_weapons_dmg)+1 + + random_weapon = GetRandom(numberof_weapons_dmg)+1 + + if(TotalRounds<0) + then + firstTurn=-TotalRounds + end + + while(weapons_dmg[random_weapon][4]>(TotalRounds+firstTurn) or (MapHasBorder() == true and (weapons_dmg[random_weapon][1]== amAirAttack or weapons_dmg[random_weapon][1] == amMineStrike or weapons_dmg[random_weapon][1] == amNapalm or weapons_dmg[random_weapon][1] == amDrillStrike or weapons_dmg[random_weapon][1] == amPiano))) + do + if(random_weapon>=numberof_weapons_dmg) + then + random_weapon=0 + end + random_weapon = random_weapon+1 + end + validate_weapon(hog, weapons_dmg[random_weapon][1],1) + rand_weaponset_power=weapons_dmg[random_weapon][6] + old_rand_weap = random_weapon + + random_weapon = rand1 + while(weapons_supp[random_weapon][4]>(TotalRounds+firstTurn) or rand_weaponset_power+weapons_supp[random_weapon][6]>2) + do + if(random_weapon>=numberof_weapons_supp) + then + random_weapon=0 + end + random_weapon = random_weapon+1 + end + validate_weapon(hog, weapons_supp[random_weapon][1],1) + rand_weaponset_power=rand_weaponset_power+weapons_supp[random_weapon][6] + + --check again if the power is enough + if(rand_weaponset_power <2) + then + random_weapon = rand2 + while(weapons_dmg[random_weapon][4]>(TotalRounds+firstTurn) or old_rand_weap == random_weapon or weapons_dmg[random_weapon][6]>0 or (MapHasBorder() == true and (weapons_dmg[random_weapon][1]== amAirAttack or weapons_dmg[random_weapon][1] == amMineStrike or weapons_dmg[random_weapon][1] == amNapalm or weapons_dmg[random_weapon][1] == amDrillStrike or weapons_dmg[random_weapon][1] == amPiano))) + do + if(random_weapon>=numberof_weapons_dmg) + then + random_weapon=0 + end + random_weapon = random_weapon+1 + end + validate_weapon(hog, weapons_dmg[random_weapon][1],1) + rand_weaponset_power=weapons_dmg[random_weapon][6] + end + + if(rand_weaponset_power <1) + then + random_weapon = rand3 + while(weapons_dmg[random_weapon][4]>(TotalRounds+firstTurn) or old_rand_weap == random_weapon or weapons_dmg[random_weapon][6]>0 or (MapHasBorder() == true and (weapons_dmg[random_weapon][1]== amAirAttack or weapons_dmg[random_weapon][1] == amMineStrike or weapons_dmg[random_weapon][1] == amNapalm or weapons_dmg[random_weapon][1] == amDrillStrike or weapons_dmg[random_weapon][1] == amPiano))) + do + if(random_weapon>=numberof_weapons_dmg) + then + random_weapon=0 + end + random_weapon = random_weapon+1 + end + validate_weapon(hog, weapons_dmg[random_weapon][1],1) + end + + AddVisualGear(GetX(hog), GetY(hog)-30, vgtEvilTrace,0, false) + PlaySound(sndReinforce,hog) +end + + --this will take that hogs settings for the weapons and add them function setweapons() @@ -402,20 +521,22 @@ end --kerguelen special on structure -function weapon_scream_walrus(hog) +function weapon_scream_pen(hog) if(GetGearType(hog) == gtHedgehog) then if(gearIsInCircle(hog,GetX(CurrentHedgehog), GetY(CurrentHedgehog), 120, false)==true and GetHogClan(hog) ~= GetHogClan(CurrentHedgehog)) then - if(GetHealth(hog)>(20+GetHealth(CurrentHedgehog)*0.1)) + local dmg=15+GetHealth(CurrentHedgehog)*0.15 + + if(GetHealth(hog)>dmg) then - temp_val=temp_val+10+(GetHealth(CurrentHedgehog)*0.05)+div((20+GetHealth(CurrentHedgehog)*0.1)*VampOn,100) - SetHealth(hog, GetHealth(hog)-(20+GetHealth(CurrentHedgehog)*0.1)) + temp_val=temp_val+div(dmg*2,3)+div(dmg*VampOn*2,100*3) + SetHealth(hog, GetHealth(hog)-dmg) else - temp_val=temp_val+(GetHealth(hog)*0.5)+(GetHealth(CurrentHedgehog)*0.05)+div((GetHealth(hog)+(GetHealth(CurrentHedgehog)*0.1))*VampOn,100) + temp_val=temp_val+(GetHealth(hog)*0.75)+(GetHealth(CurrentHedgehog)*0.1)+div((GetHealth(hog)+(GetHealth(CurrentHedgehog)*0.15))*VampOn,100) SetHealth(hog, 0) end - show_damage_tag(hog,(20+GetHealth(CurrentHedgehog)*0.1)) + show_damage_tag(hog,dmg) AddVisualGear(GetX(hog), GetY(hog), vgtExplosion, 0, false) AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmokeWhite, 0, false) end @@ -437,35 +558,15 @@ end end ---kerguelen special on structure -function weapon_flare(hog) - if(GetGearType(hog) == gtHedgehog) - then - if(GetHogClan(hog) ~= GetHogClan(CurrentHedgehog) and gearIsInCircle(hog,GetX(CurrentHedgehog), GetY(CurrentHedgehog), 45, false)) - then - if(GetX(hog)<=GetX(CurrentHedgehog)) - then - dirker=1 - else - dirker=-1 - end - AddVisualGear(GetX(hog), GetY(hog), vgtFire, 0, false) - SetGearPosition(CurrentHedgehog, GetX(CurrentHedgehog), GetY(CurrentHedgehog)-5) - SetGearVelocity(CurrentHedgehog, 100000*dirker, -300000) - AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)-20, gtCluster, 0, -10000*dirker, -1000000, 35) - PlaySound(sndHellishImpact2) - end - end -end - --kerguelen special will apply sabotage function weapon_sabotage(hog) if(GetGearType(hog) == gtHedgehog) then - if(GetHogClan(hog) ~= GetHogClan(CurrentHedgehog) and gearIsInCircle(hog,GetX(CurrentHedgehog), GetY(CurrentHedgehog), 100, false)) + if(CurrentHedgehog~=hog and gearIsInCircle(hog,GetX(CurrentHedgehog), GetY(CurrentHedgehog), 80, false)) then + temp_val=1 disable_moving[hog]=true - AddGear(GetX(hog), GetY(hog), gtCluster, 0, 0, 0, 10) + AddGear(GetX(hog), GetY(hog), gtCluster, 0, 0, 0, 1) PlaySound(sndNooo,hog) end end @@ -536,11 +637,22 @@ then if(gearIsInCircle(temp_val,GetX(hog), GetY(hog), 100, false)) then - SetHealth(hog, GetHealth(hog)+25) + SetHealth(hog, GetHealth(hog)+25+(div(25*VampOn,100))) SetEffect(hog, hePoisoned, false) end end end + +--for sundaland +function find_other_hog_in_team(hog) + if(GetGearType(hog) == gtHedgehog) + then + if(GetHogTeamName(turnhog)==GetHogTeamName(hog)) + then + turnhog=hog + end + end +end --============================================================================ --set each weapons settings @@ -562,7 +674,7 @@ function onGameStart() --trackTeams() - ShowMission(loc("Continental supplies").." 1.1c",loc("Let a Continent provide your weapons!"), + ShowMission(loc("Continental supplies"),loc("Let a Continent provide your weapons!"), loc(generalinfo), -amLowGravity, 0) end @@ -571,7 +683,6 @@ --will refresh the info on each tab weapon australianSpecial=true - asianSpecial=false austmine=nil africanSpecial=0 samericanSpecial=false @@ -586,11 +697,13 @@ temp_val=0 + turnhog=CurrentHedgehog + --for sabotage - disallowattack=0 if(disable_moving[CurrentHedgehog]==true) then - disableoffsetai=GetHogLevel(CurrentHedgehog) + disallowattack=-100 + disableRand=GetRandom(3)+5 end --when all hogs are "placed" @@ -599,12 +712,16 @@ --will run once when the game really starts (after placing hogs and so on if(teams_ok[GetHogTeamName(CurrentHedgehog)] == nil) then - disable_moving[CurrentHedgehog]=false AddCaption("["..loc("Select continent!").."]") load_continent_selection(CurrentHedgehog) continent[GetHogTeamName(CurrentHedgehog)]=0 swapweps=true teams_ok[GetHogTeamName(CurrentHedgehog)] = 2 + + if(disable_moving[CurrentHedgehog]==true) + then + disallowattack=-1000 + end else --if its not the initialization turn swapweps=false @@ -624,21 +741,49 @@ setTeamValue(GetHogTeamName(CurrentHedgehog), "rand-done-turn", nil) elseif(continent[GetHogTeamName(CurrentHedgehog)]==7) then - if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick")==nil) + if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica2-turntick")==nil) then - setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick", 1) + setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica2-turntick", 1) end - if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick")>=2) + if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica2-turntick")>=4) then AddAmmo(CurrentHedgehog,amPortalGun) - setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick", 0) + AddAmmo(CurrentHedgehog,amPortalGun) + AddAmmo(CurrentHedgehog,amSineGun) + AddAmmo(CurrentHedgehog,amSineGun) + AddAmmo(CurrentHedgehog,amGirder) + AddAmmo(CurrentHedgehog,amSnowball) + setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica2-turntick", 0) end - setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick", getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick")+1) + setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica2-turntick", getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica2-turntick")+1) elseif(continent[GetHogTeamName(CurrentHedgehog)]==5) then - AddAmmo(CurrentHedgehog,amParachute) + if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Asia-turntick")==nil) + then + setTeamValue(GetHogTeamName(CurrentHedgehog), "Asia-turntick", 1) + end + + if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Asia-turntick")>=2) + then + AddAmmo(CurrentHedgehog,amParachute) + setTeamValue(GetHogTeamName(CurrentHedgehog), "Asia-turntick", 0) + end + setTeamValue(GetHogTeamName(CurrentHedgehog), "Asia-turntick", getTeamValue(GetHogTeamName(CurrentHedgehog), "Asia-turntick")+1) + elseif(continent[GetHogTeamName(CurrentHedgehog)]==1) + then + if(getTeamValue(GetHogTeamName(CurrentHedgehog), "NA-turntick")==nil) + then + setTeamValue(GetHogTeamName(CurrentHedgehog), "NA-turntick", 1) + end + + if(getTeamValue(GetHogTeamName(CurrentHedgehog), "NA-turntick")>=5) + then + validate_weapon(CurrentHedgehog,amAirAttack,1) + setTeamValue(GetHogTeamName(CurrentHedgehog), "NA-turntick", 0) + end + setTeamValue(GetHogTeamName(CurrentHedgehog), "NA-turntick", getTeamValue(GetHogTeamName(CurrentHedgehog), "NA-turntick")+1) end end end @@ -663,19 +808,18 @@ else PlaySound(sndDenied) end - end - + --Asian special - if(asianSpecial==false and inpara~=false) + elseif(inpara==1) then asiabomb=AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)+3, gtSnowball, 0, 0, 0, 0) SetGearMessage(asiabomb, 1) - asianSpecial=true + + inpara=2 swapweps=false - end - + --africa - if(GetCurAmmoType() == amSeduction) + elseif(GetCurAmmoType() == amSeduction) then if(africanSpecial==0) then @@ -685,9 +829,9 @@ africanSpecial = 0 AddCaption(loc("NORMAL")) end - end + --south america - if(GetCurAmmoType() == amGasBomb) + elseif(GetCurAmmoType() == amGasBomb) then if(samericanSpecial==false) then @@ -697,9 +841,9 @@ samericanSpecial = false AddCaption(loc("NORMAL")) end - end + --africa - if(GetCurAmmoType() == amSMine) + elseif(GetCurAmmoType() == amSMine) then if(africaspecial2==0) then @@ -714,12 +858,11 @@ africaspecial2 = 0 AddCaption(loc("NORMAL")) end - end - + --north america (sniper) - if(GetCurAmmoType() == amSniperRifle and sniper_s_in_use==false) + elseif(GetCurAmmoType() == amSniperRifle and sniper_s_in_use==false) then - if(namericanSpecial==3) + if(namericanSpecial==2) then namericanSpecial = 1 AddCaption(loc("NORMAL")) @@ -727,15 +870,10 @@ then namericanSpecial = 2 AddCaption("#"..weapontexts[1]) - elseif(namericanSpecial==2) - then - namericanSpecial = 3 - AddCaption("##"..weapontexts[2]) end - end - + --north america (shotgun) - if(GetCurAmmoType() == amShotgun and shotgun_s~=nil) + elseif(GetCurAmmoType() == amShotgun and shotgun_s~=nil) then if(shotgun_s==false) then @@ -745,10 +883,9 @@ shotgun_s = false AddCaption(loc("NORMAL")) end - end - + --europe - if(GetCurAmmoType() == amMolotov) + elseif(GetCurAmmoType() == amMolotov) then if(europe_s==0) then @@ -758,10 +895,9 @@ europe_s = 0 AddCaption(loc("NORMAL")) end - end - + --swap forward in the weaponmenu (1.0 style) - if(swapweps==true and (GetCurAmmoType() == amSkip or GetCurAmmoType() == amNothing)) + elseif(swapweps==true and (GetCurAmmoType() == amSkip or GetCurAmmoType() == amNothing)) then continent[GetHogTeamName(CurrentHedgehog)]=continent[GetHogTeamName(CurrentHedgehog)]+1 @@ -770,10 +906,9 @@ continent[GetHogTeamName(CurrentHedgehog)]=1 end setweapons() - end - + --kerguelen - if(GetCurAmmoType() == amHammer) + elseif(GetCurAmmoType() == amHammer) then if(kergulenSpecial==6) then @@ -789,16 +924,12 @@ AddCaption("##"..weapontexts[8]) elseif(kergulenSpecial==3 or (kergulenSpecial==2 and TotalRounds<1)) then - kergulenSpecial = 4 - AddCaption("###"..weapontexts[9]) - elseif(kergulenSpecial==4) - then kergulenSpecial = 5 - AddCaption("####"..weapontexts[10]) + AddCaption("###"..weapontexts[10]) elseif(kergulenSpecial==5) then kergulenSpecial = 6 - AddCaption("#####"..weapontexts[15]) + AddCaption("####"..weapontexts[15]) end end end @@ -811,7 +942,7 @@ if(continent[GetHogTeamName(CurrentHedgehog)]<=0) then - continent[GetHogTeamName(CurrentHedgehog)]=9 + continent[GetHogTeamName(CurrentHedgehog)]=table.maxn(weaponsets) end setweapons() end @@ -845,7 +976,7 @@ then if(visualcircle==nil) then - visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 0, false) + visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 0, true) end if(kergulenSpecial == 2) --walrus scream @@ -854,15 +985,12 @@ elseif(kergulenSpecial == 3) --swap hog then SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 450, 3, 0xffff00ee) - elseif(kergulenSpecial == 4) --flare - then - SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 45, 6, 0x00ff00ee) elseif(kergulenSpecial == 5) --cries then SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 500, 1, 0x0000ffee) elseif(kergulenSpecial == 6) --sabotage then - SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 100, 10, 0xeeeeeeee) + SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 80, 10, 0x00ff00ee) end elseif(visualcircle~=nil) @@ -878,19 +1006,21 @@ if(TurnTimeLeft<=150) then disable_moving[CurrentHedgehog]=false - SetHogLevel(CurrentHedgehog,disableoffsetai) - onsabotageai=false - elseif(disallowattack>=15 and disallowattack >= 20) + SetInputMask(0xFFFFFFFF) + elseif(disallowattack >= (25*disableRand)+5) then + temp_val=0 + + AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)-10, gtCluster, 0, 0, -160000, 40) + disallowattack=0 - onsabotageai=true - SetHogLevel(CurrentHedgehog,1) + elseif(disallowattack % 20 == 0 and disallowattack>0) + then + SetInputMask(band(0xFFFFFFFF, bnot(gmLJump + gmHJump))) AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmokeWhite, 0, false) - elseif(onsabotageai==true) - then - SetHogLevel(CurrentHedgehog,disableoffsetai) - onsabotageai=false + disallowattack=disallowattack+1 else + SetInputMask(0xFFFFFFFF) disallowattack=disallowattack+1 end @@ -903,9 +1033,10 @@ swapweps=false --african special - if(africanSpecial == 1 and GetCurAmmoType() == amSeduction) + if(africanSpecial == 1 and GetCurAmmoType() == amSeduction and band(GetState(CurrentHedgehog),gstAttacked)==0) then - SetState(CurrentHedgehog, gstAttacked) + --SetState(CurrentHedgehog, gstAttacked) + EndTurn(3000) temp_val=0 runOnGears(weapon_duststorm) @@ -914,16 +1045,20 @@ --visual stuff visual_gear_explosion(250,GetX(CurrentHedgehog), GetY(CurrentHedgehog),vgtSmoke,vgtSmokeWhite) PlaySound(sndParachute) + + RemoveWeapon(CurrentHedgehog,amSeduction) --Kerguelen specials - elseif(GetCurAmmoType() == amHammer and kergulenSpecial > 1) + elseif(GetCurAmmoType() == amHammer and kergulenSpecial > 1 and band(GetState(CurrentHedgehog),gstAttacked)==0) then - SetState(CurrentHedgehog, gstAttacked) + --SetState(CurrentHedgehog, gstAttacked) + + --scream if(kergulenSpecial == 2) then temp_val=0 - runOnGears(weapon_scream_walrus) + runOnGears(weapon_scream_pen) SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+temp_val) PlaySound(sndHellish) @@ -933,14 +1068,6 @@ runOnGears(weapon_swap_kerg) PlaySound(sndPiano3) - --flare - elseif(kergulenSpecial == 4) - then - runOnGears(weapon_flare) - PlaySound(sndThrowRelease) - AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmokeWhite, 0, false) - AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)-20, gtCluster, 0, 0, -1000000, 34) - --cries elseif(kergulenSpecial == 5) then @@ -961,10 +1088,22 @@ --sabotage elseif(kergulenSpecial == 6) then + temp_val=0 runOnGears(weapon_sabotage) + if(temp_val==0) + then + PlaySound(sndThrowRelease) + AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)-20, gtCluster, 0, 0, -1000000, 32) + end end + + EndTurn(3000) + DeleteVisualGear(visualcircle) visualcircle=nil + kergulenSpecial=0 + + RemoveWeapon(CurrentHedgehog,amHammer) elseif(GetCurAmmoType() == amVampiric) then @@ -986,14 +1125,6 @@ austmine=nil end - --stop sabotage (avoiding a bug) - if(disable_moving[CurrentHedgehog]==true) - then - disable_moving[CurrentHedgehog]=false - onsabotageai=false - SetHogLevel(CurrentHedgehog,disableoffsetai) - end - australianSpecial=false end @@ -1056,7 +1187,7 @@ elseif(GetGearType(gearUid)==gtParachute) then - inpara=gearUid + inpara=1 end end @@ -1065,6 +1196,17 @@ if(GetGearType(gearUid) == gtHedgehog or GetGearType(gearUid) == gtMine or GetGearType(gearUid) == gtExplosives) then trackDeletion(gearUid) + + --sundaland special + if(GetGearType(gearUid) == gtHedgehog and continent[GetHogTeamName(turnhog)]==10) + then + if(turnhog==CurrentHedgehog) + then + runOnGears(find_other_hog_in_team) + end + + get_random_weapon_on_death(turnhog) + end end --north american lipstick @@ -1075,20 +1217,7 @@ then temp_val=gearUid runOnGears(weapon_lipstick) - - elseif(namericanSpecial==3) - then - AddVisualGear(GetX(gearUid), GetY(gearUid), vgtExplosion, 0, false) - - pinata=AddGear(GetX(gearUid), GetY(gearUid), gtCluster, 0, 0, 0, 5) - SetGearMessage(pinata,1) end - - --north american pinata - elseif(GetGearType(gearUid)==gtCluster and GetGearMessage(gearUid)==1 and namericanSpecial==3) - then - AddGear(GetX(gearUid), GetY(gearUid), gtCluster, 0, 0, 0, 20) - --north american eagle eye elseif(GetGearType(gearUid)==gtShotgunShot and shotgun_s==true) then @@ -1123,9 +1252,6 @@ inpara=false end end ---[[ -sources (populations & area): -Wikipedia +--[[sources (populations & area): Own calculations -if you think they are wrong, then please tell me :) -]] \ No newline at end of file +Some are approximations.]] \ No newline at end of file diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Scripts/Multiplayer/Gravity.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Gravity.cfg Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,2 @@ +Default +Default diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Scripts/Multiplayer/Gravity.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Gravity.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,106 @@ +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Params.lua") + +local gravity = 100 +local mingravity +local maxgravity +local delta = 0 +local period +local periodtimer = 0 +local wdGameTicks = 0 +local wdTTL = 0 +local mln = 1000000 + +function onNewTurn() + SetGravity(gravity) + wdGameTicks = GameTime +end + +function onGameTick20() + if wdGameTicks + 15000 < GameTime then + SetGravity(100) + else + if wdTTL ~= TurnTimeLeft then + wdGameTicks = GameTime + end + + if delta == nil then + if periodtimer == 0 then + periodtimer = period * 2 + SetGravity(div(GetRandom(maxgravity - mingravity) + mingravity, mln)) + else + periodtimer = periodtimer - 1 + end + elseif delta == 0 then + SetGravity(gravity) + else + if delta > 0 and gravity + delta > maxgravity then + gravity = maxgravity + delta = -delta + elseif delta < 0 and gravity - delta < mingravity then + gravity = mingravity + delta = -delta + else + gravity = gravity + delta + end + + SetGravity(div(gravity, mln)) + end + end + + wdTTL = TurnTimeLeft +end + +function onGameInit() + parseParams() + + gravity = params["g"] + + mingravity = gravity + maxgravity = params["g2"] + period = params["period"] + + if mingravity ~= nil and maxgravity ~= nil then + if period ~= nil then + period = div(period, 40) + else + period = 125 + end + + if mingravity > maxgravity then + mingravity, maxgravity = maxgravity, mingravity + end + + mingravity = mingravity * mln + maxgravity = maxgravity * mln + gravity = mingravity + + if period > 0 then + delta = div(maxgravity - mingravity, period) + else + period = -period + delta = nil + end + end + + if gravity == nil then + gravity = 100 + end +end + +function onGameStart() + if delta == nil then + v = string.format(loc("random in range from %i%% to %i%% with period of %i msec"), div(mingravity, mln), div(maxgravity, mln), period * 40) + elseif period ~= nil then + v = string.format(loc("changing range from %i%% to %i%% with period of %i msec"), div(mingravity, mln), div(maxgravity, mln), period * 40) + else + v = gravity .. "%" + end + + ShowMission(loc("Gravity"), + loc("Current setting is ") .. v, + loc("Setup:|'g=150', where 150 is 150% of normal gravity") .. "|" + .. loc("or 'g=50, g2=150, period=4000' for gravity changing|from 50 to 150 and back with period of 4000 msec") + .. "||" .. loc("Set period to negative value for random gravity"), + 0, 5000) +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Scripts/Params.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Scripts/Params.lua Sat Jan 04 23:55:54 2014 +0400 @@ -0,0 +1,9 @@ +-- Library for parameters handling + +params = {} + +function parseParams() + for k, v in string.gmatch(ScriptParam, "(%w+)=([^,]+)") do + params[k] = v + end +end diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Themes/Christmas/theme.cfg --- a/share/hedgewars/Data/Themes/Christmas/theme.cfg Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Themes/Christmas/theme.cfg Sat Jan 04 23:55:54 2014 +0400 @@ -14,3 +14,5 @@ spray = holly, 4 spray = holly2, 4 flakes = 100, 3, 99999999, 100, 300 +ice = yes +snow = yes diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Themes/Olympics/SkyL.png Binary file share/hedgewars/Data/Themes/Olympics/SkyL.png has changed diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/Themes/Snow/theme.cfg --- a/share/hedgewars/Data/Themes/Snow/theme.cfg Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/Themes/Snow/theme.cfg Sat Jan 04 23:55:54 2014 +0400 @@ -10,3 +10,5 @@ object = plant3, 3, 26, 0, 48, 1, 1, 25, 15, 50, 60 object = plant4, 3, 45, 4, 1, 45, 1, 20, 45, 20, 60 flakes = 100, 3, 99999999, 100, 300 +ice = yes +snow = yes diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/misc/hedgewars.desktop --- a/share/hedgewars/Data/misc/hedgewars.desktop Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/misc/hedgewars.desktop Sat Jan 04 23:55:54 2014 +0400 @@ -16,9 +16,9 @@ GenericName[cs]=Bojující ježci GenericName[sv]=Stridande igelkottar GenericName[tr]=Dövüşen Kirpiler -Icon=hedgewars.png +Icon=hedgewars Exec=hedgewars %U Terminal=false StartupNotify=false -Categories=Application;Game;StrategyGame; -MimeType=x-scheme-handler/hwplay +Categories=Game;StrategyGame; +MimeType=x-scheme-handler/hwplay; diff -r 8054d9d775fd -r 2759212a27de share/hedgewars/Data/misc/hwengine.desktop.in --- a/share/hedgewars/Data/misc/hwengine.desktop.in Fri Oct 11 17:43:13 2013 +0200 +++ b/share/hedgewars/Data/misc/hwengine.desktop.in Sat Jan 04 23:55:54 2014 +0400 @@ -16,11 +16,11 @@ GenericName[cs]=Engine hry Hedgewars pro přehrávání uložených her a ukázkových souborů GenericName[sv]=Hedgewarsmotorn, för att öppna demo- och sparfiler GenericName[da]=Kæmpende Pindsvin -Icon=hedgewars.png +Icon=hedgewars Exec=${CMAKE_INSTALL_PREFIX}/${target_binary_install_dir}/hwengine %f Path=/tmp Terminal=false StartupNotify=false NoDisplay=true Categories=Application;Game;StrategyGame; -MimeType=application/x-hedgewars-demo;application/x-hedgewars-save +MimeType=application/x-hedgewars-demo;application/x-hedgewars-save; diff -r 8054d9d775fd -r 2759212a27de tools/CreateMacBundle.cmake.in --- a/tools/CreateMacBundle.cmake.in Fri Oct 11 17:43:13 2013 +0200 +++ b/tools/CreateMacBundle.cmake.in Sat Jan 04 23:55:54 2014 +0400 @@ -19,16 +19,18 @@ endif() if(doBundle EQUAL 1) - execute_process(COMMAND cp -pPR ${sdl_library_only} ${frameworks_dir}/SDL.framework) - execute_process(COMMAND cp -pPR ${SDLIMAGE_LIBRARY} ${frameworks_dir}/SDL_image.framework) - execute_process(COMMAND cp -pPR ${SDLNET_LIBRARY} ${frameworks_dir}/SDL_net.framework) - execute_process(COMMAND cp -pPR ${SDLTTF_LIBRARY} ${frameworks_dir}/SDL_ttf.framework) - execute_process(COMMAND cp -pPR ${SDLMIXER_LIBRARY} ${frameworks_dir}/SDL_mixer.framework) - execute_process(COMMAND cp -pPR ${OGG_LIBRARY} ${frameworks_dir}/Ogg.framework) - execute_process(COMMAND cp -pPR ${VORBIS_LIBRARY} ${frameworks_dir}/Vorbis.framework) + execute_process(COMMAND cp ${PNG_LIBRARY} ${frameworks_dir}) + + execute_process(COMMAND cp -pPR ${sdl_library_only} ${frameworks_dir}) + execute_process(COMMAND cp -pPR ${SDLIMAGE_LIBRARY} ${frameworks_dir}) + execute_process(COMMAND cp -pPR ${SDLNET_LIBRARY} ${frameworks_dir}) + execute_process(COMMAND cp -pPR ${SDLTTF_LIBRARY} ${frameworks_dir}) + execute_process(COMMAND cp -pPR ${SDLMIXER_LIBRARY} ${frameworks_dir}) + execute_process(COMMAND cp -pPR ${OGG_LIBRARY} ${frameworks_dir}) + execute_process(COMMAND cp -pPR ${VORBIS_LIBRARY} ${frameworks_dir}) if(${SPARKLE_FOUND}) - execute_process(COMMAND cp -pPR ${SPARKLE_LIBRARY} ${frameworks_dir}/Sparkle.framework) + execute_process(COMMAND cp -pPR ${SPARKLE_LIBRARY} ${frameworks_dir}) endif() message(STATUS "Frameworks and libraries successfully copied...") else()