# HG changeset patch # User unc0rr # Date 1308849583 -14400 # Node ID 67278f1cba2c0a6e8d3aa978632d4abced0315fb # Parent bf6d4bc531d2782580957d93d3132d4a9e4f80e6# Parent f9f75c5bc39562ce9aebf45a6e139e912a7833c0 merge diff -r bf6d4bc531d2 -r 67278f1cba2c .hgignore --- a/.hgignore Tue Jun 21 16:43:05 2011 +0400 +++ b/.hgignore Thu Jun 23 21:19:43 2011 +0400 @@ -22,6 +22,7 @@ glob:vittorio.* glob:project_files/HedgewarsMobile/Data/ glob:project_files/HedgewarsMobile/build/ +glob:gameServer/dist/ glob:misc/libtremor/Xcode/build/ glob:misc/liblua/Xcode/build/ glob:misc/libfreetype/Xcode/build/ diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/CMakeLists.txt --- a/QTfrontend/CMakeLists.txt Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/CMakeLists.txt Thu Jun 23 21:19:43 2011 +0400 @@ -4,6 +4,7 @@ set(QT_USE_QTCORE TRUE) set(QT_USE_QTGUI TRUE) set(QT_USE_QTNETWORK TRUE) +set(QT_USE_QTWEBKIT TRUE) set(QT_USE_QTSVG FALSE) set(QT_USE_QTXML FALSE) set(QT_USE_QTOPENGL FALSE) @@ -46,6 +47,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/hwconsts.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/hwconsts.cpp) set(hwfr_src + HWApplication.cpp game.cpp main.cpp hwform.cpp @@ -66,6 +68,7 @@ pagenetserver.cpp pagenetgame.cpp pageinfo.cpp + pagedata.cpp pagesingleplayer.cpp pagetraining.cpp pagecampaign.cpp @@ -111,6 +114,7 @@ qaspectratiolayout.cpp drawmapwidget.cpp drawmapscene.cpp + themesmodel.cpp ) #xfire integration @@ -130,6 +134,7 @@ endif(MINGW) set(hwfr_moc_hdrs + HWApplication.h game.h hats.h hwform.h @@ -149,6 +154,7 @@ pageoptions.h pagemain.h pageinfo.h + pagedata.h pagesingleplayer.h pagenettype.h pageconnecting.h @@ -190,6 +196,7 @@ qaspectratiolayout.h drawmapwidget.h drawmapscene.h + themesmodel.h ) set(hwfr_hdrs diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/HWApplication.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/HWApplication.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,45 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2005-2011 Andrey Korotaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "HWApplication.h" +#include + +#include "hwform.h" + +HWApplication::HWApplication(int &argc, char **argv): + QApplication(argc, argv) +{ + +} + +bool HWApplication::event(QEvent *event) { + QFileOpenEvent *openEvent; + + switch (event->type()) { + case QEvent::FileOpen: + openEvent = (QFileOpenEvent *)event; + if (form) form->PlayDemoQuick(openEvent->file()); + return true; + break; + default: + return QApplication::event(event); + break; + } +} + + diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/HWApplication.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/HWApplication.h Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,41 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2005-2011 Andrey Korotaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef HWAPP_H +#define HWAPP_H + +#include +#include +#include + +class HWForm; + +class HWApplication : public QApplication +{ + Q_OBJECT +public: + HWApplication(int &argc, char **argv); + ~HWApplication() {}; + + HWForm *form; +protected: + bool event(QEvent *); +}; + +#endif + diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/SDLs.cpp --- a/QTfrontend/SDLs.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/SDLs.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -21,8 +21,7 @@ #include "SDL.h" #include "SDL_mixer.h" #include "hwconsts.h" - -#include +#include "HWApplication.h" extern char sdlkeys[1024][2][128]; @@ -101,38 +100,38 @@ for(int aid = 0; aid < SDL_JoystickNumAxes(joy) && i < 1021; aid++) { // Again store the part of the string not changing for multiple uses - QString axis = prefix + QApplication::translate("binds (keys)", "Axis") + QString(" %1 ").arg(aid + 1); + QString axis = prefix + HWApplication::translate("binds (keys)", "Axis") + QString(" %1 ").arg(aid + 1); // Entry for "Axis Up" sprintf(sdlkeys[i][0], "j%da%du", jid, aid); - sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + QApplication::translate("binds (keys)", xbox360axes[aid * 2])) : axis + QApplication::translate("binds (keys)", "(Up)")).toStdString().c_str()); + sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + HWApplication::translate("binds (keys)", xbox360axes[aid * 2])) : axis + HWApplication::translate("binds (keys)", "(Up)")).toStdString().c_str()); // Entry for "Axis Down" sprintf(sdlkeys[i][0], "j%da%dd", jid, aid); - sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + QApplication::translate("binds (keys)", xbox360axes[aid * 2 + 1])) : axis + QApplication::translate("binds (keys)", "(Down)")).toStdString().c_str()); + sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + HWApplication::translate("binds (keys)", xbox360axes[aid * 2 + 1])) : axis + HWApplication::translate("binds (keys)", "(Down)")).toStdString().c_str()); } // Register entries for all coolie hats of this joystick/gamepad for(int hid = 0; hid < SDL_JoystickNumHats(joy) && i < 1019; hid++) { // Again store the part of the string not changing for multiple uses - QString hat = prefix + (isxb ? (QApplication::translate("binds (keys)", xb360dpad) + QString(" ")) : QApplication::translate("binds (keys)", "Hat") + QString(" %1 ").arg(hid + 1)); + QString hat = prefix + (isxb ? (HWApplication::translate("binds (keys)", xb360dpad) + QString(" ")) : HWApplication::translate("binds (keys)", "Hat") + QString(" %1 ").arg(hid + 1)); // Entry for "Hat Up" sprintf(sdlkeys[i][0], "j%dh%du", jid, hid); - sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Up)")).toStdString().c_str()); + sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Up)")).toStdString().c_str()); // Entry for "Hat Down" sprintf(sdlkeys[i][0], "j%dh%dd", jid, hid); - sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Down)")).toStdString().c_str()); + sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Down)")).toStdString().c_str()); // Entry for "Hat Left" sprintf(sdlkeys[i][0], "j%dh%dl", jid, hid); - sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Left)")).toStdString().c_str()); + sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Left)")).toStdString().c_str()); // Entry for "Hat Right" sprintf(sdlkeys[i][0], "j%dh%dr", jid, hid); - sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Right)")).toStdString().c_str()); + sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Right)")).toStdString().c_str()); } // Register entries for all buttons of this joystick/gamepad @@ -140,7 +139,7 @@ { // Buttons sprintf(sdlkeys[i][0], "j%db%d", jid, bid); - sprintf(sdlkeys[i++][1], "%s", (prefix + ((isxb && bid < 10) ? (QApplication::translate("binds (keys)", xb360buttons[bid]) + QString(" ")) : QApplication::translate("binds (keys)", "Button") + QString(" %1").arg(bid + 1))).toStdString().c_str()); + sprintf(sdlkeys[i++][1], "%s", (prefix + ((isxb && bid < 10) ? (HWApplication::translate("binds (keys)", xb360buttons[bid]) + QString(" ")) : HWApplication::translate("binds (keys)", "Button") + QString(" %1").arg(bid + 1))).toStdString().c_str()); } // Close the game controller as we no longer need it SDL_JoystickClose(joy); diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/chatwidget.cpp --- a/QTfrontend/chatwidget.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/chatwidget.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -31,7 +30,6 @@ #include #include #include -#include #include "hwconsts.h" #include "SDLs.h" @@ -165,12 +163,7 @@ connect(chatNicks, SIGNAL(currentRowChanged(int)), this, SLOT(chatNickSelected(int))); - mainLayout.addWidget(chatNicks, 1, 1, 2, 1); - - lblCount = new QLabel(this); - mainLayout.addWidget(lblCount, 0, 1); - lblCount->setText("0"); - lblCount->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + mainLayout.addWidget(chatNicks, 0, 1, 3, 1); acInfo = new QAction(QAction::tr("Info"), chatNicks); acInfo->setIcon(QIcon(":/res/info.png")); @@ -398,7 +391,7 @@ updateNickItem(item); chatNicks->addItem(item); - lblCount->setText(QString::number(chatNicks->count())); + emit nickCountUpdate(chatNicks->count()); if(notifyNick && notify && gameSettings->value("frontend/sound", true).toBool()) { Mix_PlayChannel(-1, sound[rand()%4], 0); @@ -411,7 +404,7 @@ QListIterator it(items); while(it.hasNext()) chatNicks->takeItem(chatNicks->row(it.next())); - lblCount->setText(QString::number(chatNicks->count())); + emit nickCountUpdate(chatNicks->count()); } void HWChatWidget::clear() diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/chatwidget.h --- a/QTfrontend/chatwidget.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/chatwidget.h Thu Jun 23 21:19:43 2011 +0400 @@ -34,7 +34,6 @@ class QListWidget; class QSettings; class SDLInteraction; -class QLabel; // this class is for custom nick sorting class ListWidgetNickItem : public QListWidgetItem @@ -88,6 +87,7 @@ void ban(const QString & str); void info(const QString & str); void follow(const QString &); + void nickCountUpdate(int cnt); private: QGridLayout mainLayout; @@ -102,7 +102,6 @@ QAction * acIgnore; QAction * acFriend; QSettings * gameSettings; - QLabel * lblCount; SDLInteraction * sdli; Mix_Chunk *sound[4]; bool notify; diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/drawmapwidget.cpp --- a/QTfrontend/drawmapwidget.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/drawmapwidget.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -18,6 +18,7 @@ #include #include +#include #include "drawmapwidget.h" diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/drawmapwidget.h --- a/QTfrontend/drawmapwidget.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/drawmapwidget.h Thu Jun 23 21:19:43 2011 +0400 @@ -23,7 +23,6 @@ #include #include #include -#include #include "qaspectratiolayout.h" #include "drawmapscene.h" diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/game.cpp --- a/QTfrontend/game.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/game.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -20,6 +20,7 @@ #include #include #include +#include #include "game.h" #include "hwconsts.h" @@ -110,7 +111,7 @@ HWProto::addStringToBuffer(teamscfg, "TL"); HWProto::addStringToBuffer(teamscfg, QString("etheme %1") - .arg((Themes->size() > 0) ? Themes->at(rand() % Themes->size()) : "steel")); + .arg((themesModel->rowCount() > 0) ? themesModel->index(rand() % themesModel->rowCount()).data().toString() : "steel")); HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString()); HWNamegen namegen; diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/gameuiconfig.cpp --- a/QTfrontend/gameuiconfig.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/gameuiconfig.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -30,6 +29,7 @@ #include "pagenetserver.h" #include "hwconsts.h" #include "fpsedit.h" +#include "HWApplication.h" GameUIConfig::GameUIConfig(HWForm * FormWidgets, const QString & fileName) : QSettings(fileName, QSettings::IniFormat) @@ -75,6 +75,8 @@ Form->ui.pageOptions->editNetNick->setText(netNick); + Form->ui.pageOptions->editNetPassword->installEventFilter(this); + int passLength = value("net/passwordlength", 0).toInt(); setNetPasswordLength(passLength); @@ -97,7 +99,7 @@ Form->ui.pageOptions->CBLanguage->setCurrentIndex(Form->ui.pageOptions->CBLanguage->findData(value("misc/locale", "").toString())); - depth = QApplication::desktop()->depth(); + depth = HWApplication::desktop()->depth(); if (depth < 16) depth = 16; else if (depth > 16) depth = 32; } @@ -327,6 +329,24 @@ return (netPasswordLength() == 0 || Form->ui.pageOptions->editNetPassword->text() != QString(netPasswordLength(), '\0')); } +// When hedgewars launches, the password field is set with null characters. If the user tries to edit the field and there are such characters, then clear the field +bool GameUIConfig::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::FocusIn) + { + if ((QLineEdit *)object == Form->ui.pageOptions->editNetPassword) + { + if (!netPasswordIsValid()) + { + Form->ui.pageOptions->editNetPassword->clear(); + } + } + } + + // Don't filter anything + return false; +} + void GameUIConfig::setNetPasswordLength(int passwordLength) { if (passwordLength > 0) diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/gameuiconfig.h --- a/QTfrontend/gameuiconfig.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/gameuiconfig.h Thu Jun 23 21:19:43 2011 +0400 @@ -22,6 +22,7 @@ #include #include #include +#include class HWForm; class QSettings; @@ -69,9 +70,9 @@ public slots: void SaveOptions(); - private: bool netPasswordIsValid(); + bool eventFilter(QObject *object, QEvent *event); quint8 depth; }; diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/hwconsts.cpp.in --- a/QTfrontend/hwconsts.cpp.in Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/hwconsts.cpp.in Thu Jun 23 21:19:43 2011 +0400 @@ -27,7 +27,7 @@ QDir * cfgdir = new QDir(); QDir * datadir = new QDir(); -QStringList * Themes; +ThemesModel * themesModel; QStringList * mapList; QStringList * scriptList; diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/hwconsts.h --- a/QTfrontend/hwconsts.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/hwconsts.h Thu Jun 23 21:19:43 2011 +0400 @@ -22,6 +22,8 @@ #include #include +#include "themesmodel.h" + extern QString * cProtoVer; extern QString * cVersionString; extern QString * cDataDir; @@ -37,7 +39,9 @@ extern int cMaxTeams; extern int cMinServerVersion; -extern QStringList * Themes; +class QStringListModel; + +extern ThemesModel * themesModel; extern QStringList * mapList; extern QStringList * scriptList; diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/hwform.cpp --- a/QTfrontend/hwform.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/hwform.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -182,9 +182,7 @@ connect(ui.pageOptions->BtnDeleteTeam, SIGNAL(clicked()), this, SLOT(DeleteTeam())); connect(ui.pageOptions->BtnSaveOptions, SIGNAL(clicked()), config, SLOT(SaveOptions())); connect(ui.pageOptions->BtnSaveOptions, SIGNAL(clicked()), this, SLOT(GoBack())); -#ifndef __APPLE__ connect(ui.pageOptions->BtnAssociateFiles, SIGNAL(clicked()), this, SLOT(AssociateFiles())); -#endif connect(ui.pageOptions->WeaponEdit, SIGNAL(clicked()), this, SLOT(GoToSelectWeapon())); connect(ui.pageOptions->WeaponNew, SIGNAL(clicked()), this, SLOT(GoToSelectNewWeapon())); @@ -460,8 +458,7 @@ #ifdef USE_XFIRE updateXfire(); #endif - if(id == ID_PAGE_DRAWMAP) - { + if (id == ID_PAGE_DRAWMAP) { DrawMapScene * scene; if(lastid == ID_PAGE_MULTIPLAYER) scene = ui.pageMultiplayer->gameCFG->pMapContainer->getDrawMapScene(); @@ -470,9 +467,9 @@ ui.pageDrawMap->drawMapWidget->setScene(scene); } - if(lastid == ID_PAGE_DRAWMAP) - { - if(id == ID_PAGE_MULTIPLAYER) + + if (lastid == ID_PAGE_DRAWMAP) { + if (id == ID_PAGE_MULTIPLAYER) ui.pageMultiplayer->gameCFG->pMapContainer->mapDrawingFinished(); else ui.pageNetGame->pGameCFG->pMapContainer->mapDrawingFinished(); @@ -487,37 +484,35 @@ ui.pageOptions->CBTeamName->setVisible(false); ui.pageOptions->LblNoEditTeam->setVisible(true); - if(id == ID_PAGE_MULTIPLAYER) { - curTeamSelWidget = ui.pageMultiplayer->teamsSelect; + if (id == ID_PAGE_MULTIPLAYER) { + curTeamSelWidget = ui.pageMultiplayer->teamsSelect; } else { - curTeamSelWidget = ui.pageNetGame->pNetTeamsWidget; + curTeamSelWidget = ui.pageNetGame->pNetTeamsWidget; } QList teamsList; - for(QStringList::iterator it = tmNames.begin(); it != tmNames.end(); it++) { - HWTeam team(*it); - team.LoadFromFile(); - teamsList.push_back(team); + for (QStringList::iterator it = tmNames.begin(); it != tmNames.end(); it++) { + HWTeam team(*it); + team.LoadFromFile(); + teamsList.push_back(team); } - if(lastid == ID_PAGE_SETUP || lastid == ID_PAGE_DRAWMAP) { // _TEAM - if (editedTeam) { - curTeamSelWidget->addTeam(*editedTeam); - } - } else if(lastid != ID_PAGE_GAMESTATS + if (lastid == ID_PAGE_SETUP || lastid == ID_PAGE_DRAWMAP) { // _TEAM + if (editedTeam) { + curTeamSelWidget->addTeam(*editedTeam); + } + } else if (lastid != ID_PAGE_GAMESTATS && lastid != ID_PAGE_INGAME && lastid != ID_PAGE_SCHEME && lastid != ID_PAGE_SELECTWEAPON) { curTeamSelWidget->resetPlayingTeams(teamsList); } } else - if (id == ID_PAGE_GAMESTATS) - { - ui.pageGameStats->renderStats(); - } + if (id == ID_PAGE_GAMESTATS) { + ui.pageGameStats->renderStats(); + } - if(id == ID_PAGE_MAIN) - { + if (id == ID_PAGE_MAIN) { ui.pageOptions->BtnNewTeam->setVisible(true); ui.pageOptions->BtnEditTeam->setVisible(true); ui.pageOptions->BtnDeleteTeam->setVisible(true); @@ -526,16 +521,16 @@ } // load and save ignore/friends lists - if(lastid == ID_PAGE_NETGAME) // leaving a room + if (lastid == ID_PAGE_NETGAME) // leaving a room ui.pageNetGame->pChatWidget->saveLists(ui.pageOptions->editNetNick->text()); else if(lastid == ID_PAGE_ROOMSLIST) // leaving the lobby ui.pageRoomsList->chatWidget->saveLists(ui.pageOptions->editNetNick->text()); - if(id == ID_PAGE_NETGAME) // joining a room + if (id == ID_PAGE_NETGAME) // joining a room ui.pageNetGame->pChatWidget->loadLists(ui.pageOptions->editNetNick->text()); // joining the lobby - else if(id == ID_PAGE_ROOMSLIST) { - if ( hwnet && game && game->gameState == gsStarted) { // abnormal exit - kick or room destruction - send kills. + else if (id == ID_PAGE_ROOMSLIST) { + if (hwnet && game && game->gameState == gsStarted) { // abnormal exit - kick or room destruction - send kills. game->netSuspend = true; game->KillAllTeams(); } @@ -713,12 +708,21 @@ tr("Error"), tr("Please select record from the list above"), tr("OK")); - return ; + return; } CreateGame(0, 0, 0); game->PlayDemo(curritem->data(Qt::UserRole).toString()); } +void HWForm::PlayDemoQuick(const QString & demofilename) +{ + if (game && game->gameState == gsStarted) return; + GoBack(); //needed to cleanly disconnect from netgame + GoToPage(ID_PAGE_MAIN); + CreateGame(0, 0, 0); + game->PlayDemo(demofilename); +} + void HWForm::NetConnectServer(const QString & host, quint16 port) { _NetConnect(host, port, ui.pageOptions->editNetNick->text().trimmed()); @@ -1253,8 +1257,10 @@ registry_hkcr.setValue("Hedgewars.Demo/Shell/Open/Command/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwengine.exe\" \"" + cfgdir->absolutePath().replace("/","\\") + "\" \"" + datadir->absolutePath().replace("/", "\\") + "\" \"%1\" --set-everything "+arguments); registry_hkcr.setValue("Hedgewars.Save/Shell/Open/Command/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwengine.exe\" \"" + cfgdir->absolutePath().replace("/","\\") + "\" \"" + datadir->absolutePath().replace("/", "\\") + "\" \"%1\" --set-everything "+arguments); #elif defined __APPLE__ - success = false; - // TODO; also enable button in pages.cpp and signal in hwform.cpp + // only useful when other apps have taken precedence over our file extensions and you want to reset it + system("defaults write com.apple.LaunchServices LSHandlers -array-add 'LSHandlerContentTaghwdLSHandlerContentTagClasspublic.filename-extensionLSHandlerRoleAllorg.hedgewars.desktop'"); + system("defaults write com.apple.LaunchServices LSHandlers -array-add 'LSHandlerContentTaghwsLSHandlerContentTagClasspublic.filename-extensionLSHandlerRoleAllorg.hedgewars.desktop'"); + system("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -domain local -domain system -domain user"); #else // this is a little silly due to all the system commands below anyway - just use mkdir -p ? Does have the advantage of the alert I guess if (success) success = checkForDir(QDir::home().absolutePath() + "/.local"); diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/hwform.h --- a/QTfrontend/hwform.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/hwform.h Thu Jun 23 21:19:43 2011 +0400 @@ -58,6 +58,7 @@ GameUIConfig * config; QSettings * gameSettings; // Same file GameUIConfig points to but without the baggage. Needs sync() calls if you want to get GameUIConfig changes though void updateXfire(); + void PlayDemoQuick(const QString & demofilename); private slots: void GoToSaves(); @@ -161,7 +162,7 @@ QSignalMapper * pageSwitchMapper; #ifdef __APPLE__ - InstallController * panel; + InstallController * panel; #endif void OnPageShown(quint8 id, quint8 lastid=0); diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/main.cpp --- a/QTfrontend/main.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/main.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -16,7 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include +#include "HWApplication.h" + #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include "hwform.h" #include "hwconsts.h" @@ -51,7 +53,7 @@ } int main(int argc, char *argv[]) { - QApplication app(argc, argv); + HWApplication app(argc, argv); app.setAttribute(Qt::AA_DontShowIconsInMenus,false); QStringList arguments = app.arguments(); @@ -383,24 +385,52 @@ return 1; } - Themes = new QStringList(); - QFile userthemesfile(cfgdir->absolutePath() + "/Data/Themes/themes.cfg"); - if (userthemesfile.open(QIODevice::ReadOnly)) { - QTextStream stream(&userthemesfile); - while (!stream.atEnd()) Themes->append(stream.readLine()); - userthemesfile.close(); - } - QFile themesfile(datadir->absolutePath() + "/Themes/themes.cfg"); - QString str; - if (themesfile.open(QIODevice::ReadOnly)) { - QTextStream stream(&themesfile); - while (!stream.atEnd()) { - str = stream.readLine(); - if (!Themes->contains(str)) Themes->append(str); + { + QDir dir; + dir.setPath(cfgdir->absolutePath() + "/Data/Themes"); + + QStringList themes; + themes.append(dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)); + + dir.setPath(datadir->absolutePath() + "/Themes"); + themes.append(dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)); + + QList > icons; + + for(int i = themes.size() - 1; i >= 0; --i) + { + QFile tmpfile; + tmpfile.setFileName(QString("%1/Data/Themes/%2/icon.png").arg(cfgdir->absolutePath()).arg(themes.at(i))); + if (!tmpfile.exists()) + { + tmpfile.setFileName(QString("%1/Themes/%2/icon.png").arg(datadir->absolutePath()).arg(themes.at(i))); + if(tmpfile.exists()) + { // load icon + QPair ic; + ic.first = QIcon(QFileInfo(tmpfile).absoluteFilePath()); + + QFile previewIconFile; + previewIconFile.setFileName(QString("%1/Data/Themes/%2/icon@2x.png").arg(cfgdir->absolutePath()).arg(themes.at(i))); + if (previewIconFile.exists()) ic.second = QIcon(QFileInfo(previewIconFile).absoluteFilePath()); + else ic.second = QIcon(QString("%1/Themes/%2/icon@2x.png").arg(datadir->absolutePath()).arg(themes.at(i))); + + icons.prepend(ic); + } + else + { + themes.removeAt(i); + } + } } - themesfile.close(); - } else { - QMessageBox::critical(0, "Error", "Cannot access themes.cfg", "OK"); + + themesModel = new ThemesModel(themes); + for(int i = 0; i < icons.size(); ++i) + { + themesModel->setData(themesModel->index(i), icons[i].first, Qt::DecorationRole); + themesModel->setData(themesModel->index(i), icons[i].second, Qt::UserRole); + + qDebug() << "icon test" << themesModel->index(i).data(Qt::UserRole).toString(); + } } QDir tmpdir; @@ -431,8 +461,8 @@ QTranslator Translator; { QSettings settings(cfgdir->absolutePath() + "/hedgewars.ini", QSettings::IniFormat); - QString cc = settings.value("misc/locale", "").toString(); - if(!cc.compare("")) + QString cc = settings.value("misc/locale", QString()).toString(); + if(cc.isEmpty()) cc = QLocale::system().name(); QFile tmpfile; tmpfile.setFileName(cfgdir->absolutePath() + "Data/Locale/hedgewars_" + cc); @@ -455,8 +485,8 @@ CocoaInitializer initializer; #endif - HWForm *Form = new HWForm(); + app.form = new HWForm(); - Form->show(); + app.form->show(); return app.exec(); } diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/mapContainer.cpp --- a/QTfrontend/mapContainer.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/mapContainer.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -24,17 +24,18 @@ #include #include #include -#include #include -#include +#include #include #include #include #include +#include #include "hwconsts.h" #include "mapContainer.h" #include "igbox.h" +#include "HWApplication.h" HWMapContainer::HWMapContainer(QWidget * parent) : QWidget(parent), @@ -46,10 +47,10 @@ hhLimit = 18; templateFilter = 0; - mainLayout.setContentsMargins(QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin), + mainLayout.setContentsMargins(HWApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin), 1, - QApplication::style()->pixelMetric(QStyle::PM_LayoutRightMargin), - QApplication::style()->pixelMetric(QStyle::PM_LayoutBottomMargin)); + HWApplication::style()->pixelMetric(QStyle::PM_LayoutRightMargin), + HWApplication::style()->pixelMetric(QStyle::PM_LayoutBottomMargin)); QWidget* mapWidget = new QWidget(this); mainLayout.addWidget(mapWidget, 0, 0, Qt::AlignHCenter); @@ -200,24 +201,18 @@ QVBoxLayout * gbTLayout = new QVBoxLayout(gbThemes); gbTLayout->setContentsMargins(0, 0, 0 ,0); gbTLayout->setSpacing(0); - lwThemes = new QListWidget(mapWidget); - lwThemes->setMinimumHeight(30); - lwThemes->setFixedWidth(140); - QFile tmpfile; - for (int i = 0; i < Themes->size(); ++i) { - QListWidgetItem * lwi = new QListWidgetItem(); - lwi->setText(Themes->at(i)); - tmpfile.setFileName(QString("%1/Data/Themes/%2/icon.png").arg(cfgdir->absolutePath()).arg(Themes->at(i))); - if (tmpfile.exists()) lwi->setIcon(QIcon(QFileInfo(tmpfile).absoluteFilePath())); - else lwi->setIcon(QIcon(QString("%1/Themes/%2/icon.png").arg(datadir->absolutePath()).arg(Themes->at(i)))); - //lwi->setTextAlignment(Qt::AlignHCenter); - lwThemes->addItem(lwi); - } - connect(lwThemes, SIGNAL(currentRowChanged(int)), this, SLOT(themeSelected(int))); + lvThemes = new QListView(mapWidget); + lvThemes->setMinimumHeight(30); + lvThemes->setFixedWidth(140); + lvThemes->setModel(themesModel); + lvThemes->setIconSize(QSize(16, 16)); + lvThemes->setEditTriggers(QListView::NoEditTriggers); + + connect(lvThemes->selectionModel(), SIGNAL(currentRowChanged( const QModelIndex &, const QModelIndex &)), this, SLOT(themeSelected( const QModelIndex &, const QModelIndex &))); // override default style to tighten up theme scroller - lwThemes->setStyleSheet(QString( - "QListWidget{" + lvThemes->setStyleSheet(QString( + "QListView{" "border: solid;" "border-width: 0px;" "border-radius: 0px;" @@ -229,8 +224,8 @@ ) ); - gbTLayout->addWidget(lwThemes); - lwThemes->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); + gbTLayout->addWidget(lvThemes); + lvThemes->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); mapLayout->setSizeConstraint(QLayout::SetFixedSize); @@ -376,9 +371,9 @@ ); } -void HWMapContainer::themeSelected(int currentRow) +void HWMapContainer::themeSelected(const QModelIndex & current, const QModelIndex &) { - QString theme = Themes->at(currentRow); + QString theme = current.data().toString(); QList mapInfo; mapInfo.push_back(QString("+rnd+")); mapInfo.push_back(theme); @@ -389,10 +384,8 @@ chooseMap->setItemData(1, mapInfo); mapInfo[0] = QString("+drawn+"); chooseMap->setItemData(2, mapInfo); - QFile tmpfile; - tmpfile.setFileName(QString("%1/Data/Themes/%2/icon@2x.png").arg(cfgdir->absolutePath()).arg(theme)); - if (tmpfile.exists()) gbThemes->setIcon(QIcon(QFileInfo(tmpfile).absoluteFilePath())); - else gbThemes->setIcon(QIcon(QString("%1/Themes/%2/icon@2x.png").arg(datadir->absolutePath()).arg(theme))); + + gbThemes->setIcon(qVariantValue(current.data(Qt::UserRole))); emit themeChanged(theme); } @@ -487,9 +480,10 @@ void HWMapContainer::setTheme(const QString & theme) { - QList items = lwThemes->findItems(theme, Qt::MatchExactly); - if(items.size()) - lwThemes->setCurrentItem(items.at(0)); + QModelIndexList mdl = themesModel->match(themesModel->index(0), Qt::DisplayRole, theme); + + if(mdl.size()) + lvThemes->setCurrentIndex(mdl.at(0)); } void HWMapContainer::setRandomMap() @@ -539,9 +533,9 @@ void HWMapContainer::setRandomTheme() { - if(!Themes->size()) return; - quint32 themeNum = rand() % Themes->size(); - lwThemes->setCurrentRow(themeNum); + if(!themesModel->rowCount()) return; + quint32 themeNum = rand() % themesModel->rowCount(); + lvThemes->setCurrentIndex(themesModel->index(themeNum)); } void HWMapContainer::intSetTemplateFilter(int filter) diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/mapContainer.h --- a/QTfrontend/mapContainer.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/mapContainer.h Thu Jun 23 21:19:43 2011 +0400 @@ -32,7 +32,7 @@ class QPushButton; class IconedGroupBox; -class QListWidget; +class QListView; class MapFileErrorException { @@ -89,7 +89,7 @@ void setRandomMap(); void setRandomStatic(); void setRandomMission(); - void themeSelected(int currentRow); + void themeSelected(const QModelIndex & current, const QModelIndex &); void addInfoToPreview(QPixmap image); void seedEdited(); @@ -101,7 +101,7 @@ QPushButton* imageButt; QComboBox* chooseMap; IconedGroupBox* gbThemes; - QListWidget* lwThemes; + QListView* lvThemes; HWMap* pMap; QString m_seed; QPushButton* seedSet; diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/namegen.cpp --- a/QTfrontend/namegen.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/namegen.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -19,7 +19,6 @@ #include #include -#include #include #include #include "namegen.h" diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/pagedata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/pagedata.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,36 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2006-2011 Andrey Korotaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pagedata.h" + +PageDataDownload::PageDataDownload(QWidget* parent) : AbstractPage(parent) +{ + QGridLayout * pageLayout = new QGridLayout(this); + pageLayout->setColumnStretch(0, 1); + pageLayout->setColumnStretch(1, 1); + pageLayout->setColumnStretch(2, 1); + + BtnBack = addButton(":/res/Exit.png", pageLayout, 1, 0, true); + + web = new QWebView(this); + web->load(QUrl("http://m8y.org/hw/")); + pageLayout->addWidget(web, 0, 0, 1, 3); +} diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/pagedata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/pagedata.h Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,35 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2006-2011 Andrey Korotaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef PAGE_DATA_H +#define PAGE_DATA_H +#include +#include "AbstractPage.h" + +class PageDataDownload : public AbstractPage +{ + Q_OBJECT + +public: + PageDataDownload(QWidget* parent = 0); + + QPushButton *BtnBack; + QWebView *web; +}; + +#endif diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/pageeditteam.cpp --- a/QTfrontend/pageeditteam.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/pageeditteam.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -24,13 +24,13 @@ #include #include #include -#include #include "pageeditteam.h" #include "sdlkeys.h" #include "hwconsts.h" #include "SquareLabel.h" #include "hats.h" +#include "HWApplication.h" PageEditTeam::PageEditTeam(QWidget* parent, SDLInteraction * sdli) : AbstractPage(parent) @@ -315,24 +315,24 @@ pagelayout->addWidget(l, num++, 0, 1, 2); } curW = new QWidget(this); - BindsBox->addItem(curW, QApplication::translate("binds (categories)", cbinds[i].category)); + BindsBox->addItem(curW, HWApplication::translate("binds (categories)", cbinds[i].category)); pagelayout = new QGridLayout(curW); num = 0; } if(cbinds[i].description != NULL) { l = new QLabel(curW); - l->setText((num > 0 ? QString("\n") : QString("")) + QApplication::translate("binds (descriptions)", cbinds[i].description)); + l->setText((num > 0 ? QString("\n") : QString("")) + HWApplication::translate("binds (descriptions)", cbinds[i].description)); pagelayout->addWidget(l, num++, 0, 1, 2); } l = new QLabel(curW); - l->setText(QApplication::translate("binds", cbinds[i].name)); + l->setText(HWApplication::translate("binds", cbinds[i].name)); l->setAlignment(Qt::AlignRight); pagelayout->addWidget(l, num, 0); CBBind[i] = new QComboBox(curW); for(int j = 0; sdlkeys[j][1][0] != '\0'; j++) - CBBind[i]->addItem(QApplication::translate("binds (keys)", sdlkeys[j][1]).contains(": ") ? QApplication::translate("binds (keys)", sdlkeys[j][1]) : QApplication::translate("binds (keys)", "Keyboard") + QString(": ") + QApplication::translate("binds (keys)", sdlkeys[j][1]), sdlkeys[j][0]); + CBBind[i]->addItem(HWApplication::translate("binds (keys)", sdlkeys[j][1]).contains(": ") ? HWApplication::translate("binds (keys)", sdlkeys[j][1]) : HWApplication::translate("binds (keys)", "Keyboard") + QString(": ") + HWApplication::translate("binds (keys)", sdlkeys[j][1]), sdlkeys[j][0]); pagelayout->addWidget(CBBind[i++], num++, 1); } } diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/pageoptions.cpp --- a/QTfrontend/pageoptions.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/pageoptions.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -239,16 +239,17 @@ CBNameWithDate->setText(QCheckBox::tr("Append date and time to record file name")); MiscLayout->addWidget(CBNameWithDate, 4, 0, 1, 2); -#ifdef SPARKLE_ENABLED - CBAutoUpdate = new QCheckBox(groupMisc); - CBAutoUpdate->setText(QCheckBox::tr("Check for updates at startup")); - MiscLayout->addWidget(CBAutoUpdate, 5, 0, 1, 2); -#endif -#ifndef __APPLE__ BtnAssociateFiles = new QPushButton(groupMisc); BtnAssociateFiles->setText(QPushButton::tr("Associate file extensions")); BtnAssociateFiles->setEnabled(!custom_data && !custom_config); MiscLayout->addWidget(BtnAssociateFiles, 5, 0, 1, 2); + +#ifdef __APPLE__ +#ifdef SPARKLE_ENABLED + CBAutoUpdate = new QCheckBox(groupMisc); + CBAutoUpdate->setText(QCheckBox::tr("Check for updates at startup")); + MiscLayout->addWidget(CBAutoUpdate, 6, 0, 1, 3); +#endif #endif gbTBLayout->addWidget(groupMisc, 2, 0); } diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/pageroomslist.cpp --- a/QTfrontend/pageroomslist.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/pageroomslist.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -42,7 +42,7 @@ roomName->setMaxLength(60); newRoomLayout->addWidget(roomNameLabel); newRoomLayout->addWidget(roomName); - pageLayout->addLayout(newRoomLayout, 0, 0); + pageLayout->addLayout(newRoomLayout, 0, 0, 1, 2); roomsList = new QTableWidget(this); roomsList->setSelectionBehavior(QAbstractItemView::SelectRows); @@ -51,7 +51,7 @@ roomsList->setAlternatingRowColors(true); roomsList->setShowGrid(false); roomsList->setSelectionMode(QAbstractItemView::SingleSelection); - pageLayout->addWidget(roomsList, 1, 0, 3, 1); + pageLayout->addWidget(roomsList, 1, 0, 3, 2); pageLayout->setRowStretch(2, 100); QHBoxLayout * filterLayout = new QHBoxLayout(); @@ -97,19 +97,27 @@ filterLayout->addWidget(searchLabel); filterLayout->addWidget(searchText); - pageLayout->addLayout(filterLayout, 4, 0); + pageLayout->addLayout(filterLayout, 4, 0, 1, 2); chatWidget = new HWChatWidget(this, gameSettings, sdli, false); - pageLayout->addWidget(chatWidget, 5, 0, 1, 2); + pageLayout->addWidget(chatWidget, 5, 0, 1, 3); pageLayout->setRowStretch(5, 350); - BtnCreate = addButton(tr("Create"), pageLayout, 0, 1); - BtnJoin = addButton(tr("Join"), pageLayout, 1, 1); - BtnRefresh = addButton(tr("Refresh"), pageLayout, 3, 1); - BtnClear = addButton(tr("Clear"), pageLayout, 4, 1); + BtnCreate = addButton(tr("Create"), pageLayout, 0, 2); + BtnJoin = addButton(tr("Join"), pageLayout, 1, 2); + BtnRefresh = addButton(tr("Refresh"), pageLayout, 3, 2); + BtnClear = addButton(tr("Clear"), pageLayout, 4, 2); BtnBack = addButton(":/res/Exit.png", pageLayout, 6, 0, true); - BtnAdmin = addButton(tr("Admin features"), pageLayout, 6, 1); + + lblCount = new QLabel(this); + pageLayout->addWidget(lblCount, 6, 1, Qt::AlignHCenter); + lblCount->setText("?"); + lblCount->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + connect(chatWidget, SIGNAL(nickCountUpdate(const int)), this, SLOT(updateNickCounter(const int))); + + BtnAdmin = addButton(tr("Admin features"), pageLayout, 6, 2); connect(BtnCreate, SIGNAL(clicked()), this, SLOT(onCreateClick())); connect(BtnJoin, SIGNAL(clicked()), this, SLOT(onJoinClick())); @@ -380,3 +388,9 @@ emit askForJoinRoom(room); } } + +void PageRoomsList::updateNickCounter(int cnt) +{ + lblCount->setText(tr("%1 players online").arg(cnt)); +} + diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/pageroomslist.h --- a/QTfrontend/pageroomslist.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/pageroomslist.h Thu Jun 23 21:19:43 2011 +0400 @@ -45,6 +45,7 @@ QComboBox * CBRules; QComboBox * CBWeapons; HWChatWidget * chatWidget; + QLabel * lblCount; private: bool gameInLobby; @@ -55,6 +56,7 @@ public slots: void setRoomsList(const QStringList & list); void setAdmin(bool); + void updateNickCounter(int cnt); private slots: void onCreateClick(); diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/team.cpp --- a/QTfrontend/team.cpp Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/team.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -18,11 +18,11 @@ #include #include -#include #include #include #include #include + #include "team.h" #include "hwform.h" #include "pageeditteam.h" diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/themesmodel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/themesmodel.cpp Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,47 @@ + +#include "themesmodel.h" + +ThemesModel::ThemesModel(QStringList themes, QObject *parent) : + QAbstractListModel(parent) +{ + m_data.reserve(themes.size()); + + foreach(QString theme, themes) + { + m_data.append(QHash()); + m_data.last().insert(Qt::DisplayRole, theme); + } +} + +int ThemesModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + else + return m_data.size(); +} + +QVariant ThemesModel::data(const QModelIndex &index, int role) const +{ + if(index.column() > 0 || index.row() >= m_data.size()) + return QVariant(); + else + return m_data.at(index.row()).value(role); +} + +bool ThemesModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(index.column() > 0 || index.row() >= m_data.size()) + return false; + else + { + m_data[index.row()].insert(role, value); + + return true; + } + +} + + + + diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/themesmodel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/themesmodel.h Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,28 @@ +#ifndef THEMESMODEL_H +#define THEMESMODEL_H + +#include +#include +#include + +class ThemesModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit ThemesModel(QStringList themes, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + +signals: + +public slots: + +private: + + QList > m_data; +}; + +#endif // THEMESMODEL_H diff -r bf6d4bc531d2 -r 67278f1cba2c QTfrontend/ui_hwform.h --- a/QTfrontend/ui_hwform.h Tue Jun 21 16:43:05 2011 +0400 +++ b/QTfrontend/ui_hwform.h Thu Jun 23 21:19:43 2011 +0400 @@ -29,6 +29,7 @@ class PageNetChat; class PageNetGame; class PageInfo; +class PageDataDownload; class PageGameStats; class PageSinglePlayer; class PageTraining; @@ -62,6 +63,7 @@ PageNetChat *pageNetChat; PageNetGame *pageNetGame; PageInfo *pageInfo; + PageDataDownload *pageDataDownload; PageGameStats *pageGameStats; PageSinglePlayer *pageSinglePlayer; PageTraining *pageTraining; diff -r bf6d4bc531d2 -r 67278f1cba2c gameServer/Utils.hs --- a/gameServer/Utils.hs Tue Jun 21 16:43:05 2011 +0400 +++ b/gameServer/Utils.hs Thu Jun 23 21:19:43 2011 +0400 @@ -75,7 +75,9 @@ t : replaceTeam tm ts illegalName :: B.ByteString -> Bool -illegalName s = B.null s || B.all isSpace s || isSpace (B.head s) || isSpace (B.last s) +illegalName s = B.null s || B.all isSpace s || isSpace (B.head s) || isSpace (B.last s) || B.any isIllegalChar s + where + isIllegalChar c = c `List.elem` "$()*+?[]^{|}" protoNumber2ver :: Word16 -> B.ByteString protoNumber2ver v = Map.findWithDefault "Unknown" v vermap diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/GSHandlers.inc Thu Jun 23 21:19:43 2011 +0400 @@ -4813,89 +4813,52 @@ x, y: LongInt; hog: PHedgehog; begin - if (Gear^.Hedgehog <> nil) and (Gear^.Tag = TotalRounds) then + if CurAmmoGear = Gear then begin - hog:= Gear^.Hedgehog; - hog^.Gear:= hog^.GearHidden; - hog^.Gear^.X:= Gear^.X; - hog^.Gear^.Y:= Gear^.Y - Int2hwFloat(Gear^.Radius); - hog^.Gear^.Active:= false; - hog^.Gear^.State:= hog^.Gear^.State And not gstHHdriven; - InsertGearToList(hog^.Gear); - hog^.GearHidden:= nil; - Gear^.Hedgehog:= nil; + if (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then + begin + DeleteGear(Gear); + exit + end; + if Gear = CurAmmoGear then CurAmmoGear := nil; + Gear^.Hedgehog:= CurrentHedgehog; + RemoveGearFromList(CurrentHedgehog^.Gear); + CurrentHedgehog^.Gear^.Z := cHHZ; + CurrentHedgehog^.Gear^.Active := false; + CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and not gstHHDriven; + CurrentHedgehog^.GearHidden:= CurrentHedgehog^.Gear; + CurrentHedgehog^.Gear:= nil; + Gear^.Tag:= TotalRounds + Gear^.Tag; + AddGearCI(Gear); end; dec(Gear^.Health, Gear^.Damage); Gear^.Damage := 0; - - if Gear^.Health <= 0 then - begin - if Gear^.Hedgehog <> nil then + + if (Gear^.Tag = TotalRounds) or (Gear^.Health <= 0) then begin - hog:= Gear^.Hedgehog; - hog^.Gear:= hog^.GearHidden; - hog^.Gear^.X:= Gear^.X; - hog^.Gear^.Y:= Gear^.Y; - InsertGearToList(hog^.Gear); - hog^.GearHidden:= nil; + if Gear^.Hedgehog <> nil then + begin + Gear^.Hedgehog^.Gear:= Gear^.Hedgehog^.GearHidden; + Gear^.Hedgehog^.GearHidden:= nil; + Gear^.Hedgehog^.Gear^.X:= Gear^.X; + Gear^.Hedgehog^.Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Radius + cHHRadius); + InsertGearToList(Gear^.Hedgehog^.Gear); Gear^.Hedgehog:= nil; + SetAllHHToActive; + end; end; - + + if Gear^.Health <= 0 then + begin x := hwRound(Gear^.X); y := hwRound(Gear^.Y); + DeleteCI(Gear); DeleteGear(Gear); doMakeExplosion(x, y, 50, CurrentHedgehog, EXPLAutoSound); - end; -end; - -procedure doStepPlaceStructure(Gear: PGear); -var - hog: PHedgehog; - HHGear: PGear; - x, y, tx, ty: hwFloat; -begin - AllInactive := false; - - HHGear := Gear^.Hedgehog^.Gear; - tx := int2hwFloat(TargetPoint.X); - ty := int2hwFloat(TargetPoint.Y); - x := HHGear^.X; - y := HHGear^.Y; - - HHGear := Gear^.Hedgehog^.Gear; - if (Distance(tx - x, ty - y) > _256) or - not TryPlaceOnLand(TargetPoint.X - SpritesData[sprHHTelepMask].Width div 2, - TargetPoint.Y - SpritesData[sprHHTelepMask].Height div 2, - sprHHTelepMask, 0, false, false) then - begin - HHGear^.Message := HHGear^.Message and not gmAttack; - HHGear^.State := HHGear^.State and not gstAttacking; - HHGear^.State := HHGear^.State or gstHHChooseTarget; - DeleteGear(Gear); - isCursorVisible := true; - PlaySound(sndDenied) - end - else - begin - DeleteCI(HHGear); - SetAllHHToActive; - PlaySound(sndPlaced); - CurAmmoGear:= nil; - AfterAttack; - Gear^.X := tx; - Gear^.Y := ty; - Gear^.Tag := TotalRounds + Gear^.Tag; - hog:= CurrentHedgehog; - hog^.GearHidden:= hog^.Gear; - RemoveGearFromList(hog^.Gear); - hog^.Gear:= nil; - Gear^.Hedgehog := hog; - Gear^.doStep := @doStepStructure; end; - TargetPoint.X := NoPointX; end; procedure doStepTardis(Gear: PGear); diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/HHHandlers.inc --- a/hedgewars/HHHandlers.inc Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/HHHandlers.inc Thu Jun 23 21:19:43 2011 +0400 @@ -316,7 +316,7 @@ end; amDrillStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 3, _0, _0, CurWeapon^.Timer); //amMelonStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 4, _0, _0, 0); - amStructure: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtStructure, 0, _0, _0, 0); + amStructure: CurAmmoGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000); amTardis: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000); end; @@ -380,7 +380,7 @@ else begin OnUsedAmmo(CurrentHedgehog^); - if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and ((GameFlags and gfInfAttack) = 0) then + if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then begin if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft; TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/options.inc --- a/hedgewars/options.inc Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/options.inc Thu Jun 23 21:19:43 2011 +0400 @@ -34,11 +34,8 @@ {$DEFINE GLunit:=gles11} {$ENDIF} -{$IFNDEF DARWIN} - {$DEFINE DEBUGFILE} - { $DEFINE DUMP} - { $DEFINE TRACEAIACTIONS} - { $DEFINE COUNTTICKS} -{$ENDIF} +{$DEFINE DEBUGFILE} +//{$DEFINE TRACEAIACTIONS} +//{$DEFINE COUNTTICKS} //also available LUA_DISABLED diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uAmmos.pas --- a/hedgewars/uAmmos.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uAmmos.pas Thu Jun 23 21:19:43 2011 +0400 @@ -32,6 +32,7 @@ procedure SetAmmoReinforcement(s: shortstring); procedure AssignStores; procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType); +procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType; cnt: LongWord); function HHHasAmmo(var Hedgehog: THedgehog; Ammo: TAmmoType): boolean; procedure PackAmmo(Ammo: PHHAmmo; Slot: LongInt); procedure OnUsedAmmo(var Hedgehog: THedgehog); @@ -43,6 +44,7 @@ procedure ResetWeapons; function GetAmmoByNum(num: Longword): PHHAmmo; function GetAmmoEntry(var Hedgehog: THedgehog): PAmmo; +function GetAmmoEntry(var Hedgehog: THedgehog; am: TAmmoType): PAmmo; var StoreCnt: Longword; @@ -139,13 +141,18 @@ end; function GetAmmoEntry(var Hedgehog: THedgehog): PAmmo; +begin +GetAmmoEntry:= GetAmmoEntry(Hedgehog, Hedgehog.CurAmmoType) +end; + +function GetAmmoEntry(var Hedgehog: THedgehog; am: TAmmoType): PAmmo; var ammoidx, slot: LongWord; begin with Hedgehog do begin - slot:= Ammoz[CurAmmoType].Slot; + slot:= Ammoz[am].Slot; ammoidx:= 0; - while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do inc(ammoidx); + while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> am) do inc(ammoidx); GetAmmoEntry:= @Ammo^[slot, ammoidx]; end end; @@ -170,6 +177,17 @@ end; procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType); +var cnt: LongWord; +begin +cnt:= GetAmmoEntry(Hedgehog, ammo)^.Count; +if cnt <> AMMO_INFINITE then + begin + inc(cnt, Ammoz[ammo].NumberInCase); + AddAmmo(Hedgehog, ammo, cnt) + end +end; + +procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType; cnt: LongWord); var ammos: TAmmoCounts; slot, ami: LongInt; hhammo: PHHAmmo; @@ -184,11 +202,8 @@ if hhammo^[slot, ami].Count > 0 then ammos[hhammo^[slot, ami].AmmoType]:= hhammo^[slot, ami].Count; -if ammos[ammo] <> AMMO_INFINITE then - begin - inc(ammos[ammo], Ammoz[ammo].NumberInCase); - if ammos[ammo] > AMMO_INFINITE then ammos[ammo]:= AMMO_INFINITE - end; +ammos[ammo]:= cnt; +if ammos[ammo] > AMMO_INFINITE then ammos[ammo]:= AMMO_INFINITE; FillAmmoStore(hhammo, ammos) end; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uCollisions.pas Thu Jun 23 21:19:43 2011 +0400 @@ -22,7 +22,7 @@ interface uses uFloat, uTypes; -const cMaxGearArrayInd = 255; +const cMaxGearArrayInd = 1023; type PGearArray = ^TGearArray; TGearArray = record diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uGears.pas --- a/hedgewars/uGears.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uGears.pas Thu Jun 23 21:19:43 2011 +0400 @@ -147,7 +147,7 @@ @doStepNapalmBomb, @doStepSnowball, @doStepSnowflake, - @doStepPlaceStructure, + @doStepStructure, @doStepLandGun, @doStepTardis); @@ -1292,7 +1292,7 @@ if (GameFlags and gfSolidLand) = 0 then begin cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk - if cnt > 0 then + if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then for i:= 0 to cnt do AddVisualGear(X, Y, vgtChunk) end; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uLand.pas --- a/hedgewars/uLand.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uLand.pas Thu Jun 23 21:19:43 2011 +0400 @@ -1062,35 +1062,40 @@ LandSurface2LandPixels(tmpsurf); SDL_FreeSurface(tmpsurf); - if (cReducedQuality and rqBlurryLand) = 0 then - for x:= leftX+2 to rightX-2 do - for y:= topY+2 to LAND_HEIGHT-3 do - if (Land[y, x] = 0) and - (((Land[y, x-1] = lfBasic) and ((Land[y+1,x] = lfBasic)) or (Land[y-1,x] = lfBasic)) or - ((Land[y, x+1] = lfBasic) and ((Land[y-1,x] = lfBasic) or (Land[y+1,x] = lfBasic)))) then - begin + for x:= leftX+2 to rightX-2 do + for y:= topY+2 to LAND_HEIGHT-3 do + if (Land[y, x] = 0) and + (((Land[y, x-1] = lfBasic) and ((Land[y+1,x] = lfBasic)) or (Land[y-1,x] = lfBasic)) or + ((Land[y, x+1] = lfBasic) and ((Land[y-1,x] = lfBasic) or (Land[y+1,x] = lfBasic)))) then + begin + if (cReducedQuality and rqBlurryLand) = 0 then + begin if Land[y, x-1] = lfBasic then LandPixels[y, x]:= LandPixels[y, x-1] else if Land[y, x+1] = lfBasic then LandPixels[y, x]:= LandPixels[y, x+1]; - LandPixels[y,x]:= (LandPixels[y,x] and not AMask) or (128 shl AShift); - Land[y,x]:= lfObject - end - else if (Land[y, x] = 0) and - (((Land[y, x-1] = lfBasic) and (Land[y+1,x-1] = lfBasic) and (Land[y+2,x] = lfBasic)) or - ((Land[y, x-1] = lfBasic) and (Land[y-1,x-1] = lfBasic) and (Land[y-2,x] = lfBasic)) or - ((Land[y, x+1] = lfBasic) and (Land[y+1,x+1] = lfBasic) and (Land[y+2,x] = lfBasic)) or - ((Land[y, x+1] = lfBasic) and (Land[y-1,x+1] = lfBasic) and (Land[y-2,x] = lfBasic)) or - ((Land[y+1, x] = lfBasic) and (Land[y+1,x+1] = lfBasic) and (Land[y,x+2] = lfBasic)) or - ((Land[y-1, x] = lfBasic) and (Land[y-1,x+1] = lfBasic) and (Land[y,x+2] = lfBasic)) or - ((Land[y+1, x] = lfBasic) and (Land[y+1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic)) or - ((Land[y-1, x] = lfBasic) and (Land[y-1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic))) then - begin + LandPixels[y,x]:= (LandPixels[y,x] and not AMask) or (128 shl AShift) + end; + Land[y,x]:= lfObject + end + else if (Land[y, x] = 0) and + (((Land[y, x-1] = lfBasic) and (Land[y+1,x-1] = lfBasic) and (Land[y+2,x] = lfBasic)) or + ((Land[y, x-1] = lfBasic) and (Land[y-1,x-1] = lfBasic) and (Land[y-2,x] = lfBasic)) or + ((Land[y, x+1] = lfBasic) and (Land[y+1,x+1] = lfBasic) and (Land[y+2,x] = lfBasic)) or + ((Land[y, x+1] = lfBasic) and (Land[y-1,x+1] = lfBasic) and (Land[y-2,x] = lfBasic)) or + ((Land[y+1, x] = lfBasic) and (Land[y+1,x+1] = lfBasic) and (Land[y,x+2] = lfBasic)) or + ((Land[y-1, x] = lfBasic) and (Land[y-1,x+1] = lfBasic) and (Land[y,x+2] = lfBasic)) or + ((Land[y+1, x] = lfBasic) and (Land[y+1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic)) or + ((Land[y-1, x] = lfBasic) and (Land[y-1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic))) then + begin + if (cReducedQuality and rqBlurryLand) = 0 then + begin if Land[y, x-1] = lfBasic then LandPixels[y, x]:= LandPixels[y, x-1] else if Land[y, x+1] = lfBasic then LandPixels[y, x]:= LandPixels[y, x+1] else if Land[y+1, x] = lfBasic then LandPixels[y, x]:= LandPixels[y+1, x] else if Land[y-1, x] = lfBasic then LandPixels[y, x]:= LandPixels[y-1, x]; - LandPixels[y,x]:= (LandPixels[y,x] and not AMask) or (64 shl AShift); - Land[y,x]:= lfObject - end; + LandPixels[y,x]:= (LandPixels[y,x] and not AMask) or (64 shl AShift) + end; + Land[y,x]:= lfObject + end; AddProgress(); end; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uLandGraphics.pas Thu Jun 23 21:19:43 2011 +0400 @@ -30,6 +30,7 @@ function addBgColor(OldColor, NewColor: LongWord): LongWord; function SweepDirty: boolean; function Despeckle(X, Y: LongInt): boolean; +procedure Smooth(X, Y: LongInt); function CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean; function DrawExplosion(X, Y, Radius: LongInt): Longword; procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); @@ -751,9 +752,52 @@ Despeckle:= false end; +procedure Smooth(X, Y: LongInt); +begin +// a bit of AA for explosions +if (Land[Y, X] = 0) and (Y > topY+1) and + (Y < LAND_HEIGHT-2) and (X>leftX+1) and (X 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0)) or + (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then + begin + if (cReducedQuality and rqBlurryLand) = 0 then + begin + if (LandPixels[y,x] = 0) then LandPixels[y,x]:= (cExplosionBorderColor and not AMask) or (128 shl AShift) + else + LandPixels[y,x]:= + (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or + (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or + (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift) + end; + Land[y,x]:= lfBasic + end + else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or + (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or + (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or + (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or + (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or + (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or + (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0)) or + (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then + begin + if (cReducedQuality and rqBlurryLand) = 0 then + begin + if (LandPixels[y,x] = 0) then LandPixels[y,x]:= (cExplosionBorderColor and not AMask) or (64 shl AShift) + else + LandPixels[y,x]:= + (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or + (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or + (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift) + end; + Land[y,x]:= lfBasic + end + end +end; + function SweepDirty: boolean; var x, y, xx, yy, ty, tx: LongInt; - bRes, updateBlock, resweep, recheck: boolean; + bRes, updateBlock, resweep, recheck, firstpass: boolean; begin bRes:= false; reCheck:= true; @@ -769,6 +813,7 @@ begin updateBlock:= false; resweep:= true; + firstpass:= true; ty:= y * 32; tx:= x * 32; while(resweep) do @@ -776,6 +821,7 @@ resweep:= false; for yy:= ty to ty + 31 do for xx:= tx to tx + 31 do + begin if Despeckle(xx, yy) then begin bRes:= true; @@ -802,6 +848,9 @@ recheck:= true; end end; + if firstpass then Smooth(xx,yy); + end; + firstpass:= false end; if updateBlock then UpdateLandTexture(tx, 32, ty, 32); LandDirty[y, x]:= 0; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uScript.pas --- a/hedgewars/uScript.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uScript.pas Thu Jun 23 21:19:43 2011 +0400 @@ -657,6 +657,30 @@ lc_gethogname:= 1 end; +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!'); + 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; + + FreeTexture(gear^.Hedgehog^.NameTagTex); + gear^.Hedgehog^.NameTagTex:= RenderStringTex(gear^.Hedgehog^.Name, gear^.Hedgehog^.Team^.Clan^.Color, fnt16); + + end; + lc_sethogname:= 0; +end; + function lc_gettimer(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin @@ -827,19 +851,42 @@ lc_switchhog:= 0 end; +{function lc_addammo(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + + if lua_gettop(L) = 3 then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and (gear^.Hedgehog <> nil) then + AddAmmoAmount(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L,3) ); + end else + + if lua_gettop(L) = 2 then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and (gear^.Hedgehog <> nil) then + AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))); + end else + begin + LuaError('Lua: Wrong number of parameters passed to AddAmmo!'); + end; + + lc_addammo:= 0; + +end;} + function lc_addammo(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaError('Lua: Wrong number of parameters passed to AddAmmo!'); - end - else + if (lua_gettop(L) = 3) or (lua_gettop(L) = 2) then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Hedgehog <> nil) then - AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))); - end; + if lua_gettop(L) = 2 then AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))) + else AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L, 3)) + end + else LuaError('Lua: Wrong number of parameters passed to AddAmmo!'); lc_addammo:= 0 end; @@ -856,6 +903,12 @@ if gear <> nil then begin gear^.Health:= lua_tointeger(L, 2); + + if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then + begin + RenderHealth(gear^.Hedgehog^); + end; + SetAllToActive; end end; @@ -1712,6 +1765,7 @@ lua_register(luaState, 'SetClanColor', @lc_setclancolor); lua_register(luaState, 'GetHogTeamName', @lc_gethogteamname); lua_register(luaState, 'GetHogName', @lc_gethogname); +lua_register(luaState, 'SetHogName', @lc_sethogname); lua_register(luaState, 'GetHogLevel', @lc_gethoglevel); lua_register(luaState, 'SetHogLevel', @lc_sethoglevel); lua_register(luaState, 'GetX', @lc_getx); diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uStore.pas --- a/hedgewars/uStore.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uStore.pas Thu Jun 23 21:19:43 2011 +0400 @@ -283,10 +283,12 @@ 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])))) then + (((cReducedQuality and rqKillFlakes) = 0) or (Theme = 'Snow') or (Theme = 'Christmas') or ((not (ii in [sprFlake, sprSDFlake])))) and + ((cCloudsNumber > 0) or (ii <> sprCloud)) and + ((vobCount > 0) or (ii <> sprFlake)) then begin if AltPath = ptNone then - if ii in [sprHorizontL, sprHorizontR, sprSkyL, sprSkyR] then // FIXME: hack + if ii in [sprHorizont, sprHorizontL, sprHorizontR, sprSky, sprSkyL, sprSkyR, sprChunk] then // FIXME: hack begin tmpsurf:= LoadImage(UserPathz[Path] + '/' + FileName, ifAlpha or ifTransparent); if tmpsurf = nil then tmpsurf:= LoadImage(Pathz[Path] + '/' + FileName, ifAlpha or ifTransparent) @@ -306,7 +308,7 @@ if tmpsurf <> nil then begin if getImageDimensions then - begin + begin imageWidth:= tmpsurf^.w; imageHeight:= tmpsurf^.h end; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uVariables.pas Thu Jun 23 21:19:43 2011 +0400 @@ -547,7 +547,7 @@ Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandCheese (FileName: 'amFlamethrower'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandFlamethrower - (FileName: 'Chunk'; Path: ptCurrTheme; AltPath: ptGraphics; Texture: nil; Surface: nil; + (FileName: 'Chunk'; Path: ptCurrTheme; AltPath: ptNone; Texture: nil; Surface: nil; Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprChunk (FileName: 'Note'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprNote @@ -2037,7 +2037,7 @@ ejectX: 0; ejectY: 0), -// Tardis (just a copy of teleport til nemo arives) +// Tardis (NameId: sidTardis; NameTex: nil; Probability: 200; @@ -2063,15 +2063,13 @@ ejectX: 0; ejectY: 0), -// Structure +// Structure (NameId: sidStructure; NameTex: nil; Probability: 0; NumberInCase: 1; Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_NoCrosshair or - ammoprop_NeedTarget or - ammoprop_AttackingPut or ammoprop_Utility or ammoprop_DontHold; Count: 1; @@ -2086,10 +2084,11 @@ maxAngle: 0; isDamaging: false; SkipTurns: 0; - PosCount: 2; - PosSprite: sprAmTeleport; + PosCount: 1; + PosSprite: sprWater; ejectX: 0; ejectY: 0), + // Land Gun (NameId: sidLandGun; NameTex: nil; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uVisualGears.pas Thu Jun 23 21:19:43 2011 +0400 @@ -403,21 +403,21 @@ begin Gear:= VisualGearsList; case Layer of - // this level is very distant in the background when stereo + // this layer is very distant in the background when stereo 0: while Gear <> nil do begin if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint); case Gear^.Kind of vgtFlake: if SuddenDeathDmg then - if vobSDVelocity = 0 then - DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) - else - DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) + if vobSDVelocity = 0 then + DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) + else + DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) else - if vobVelocity = 0 then - DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) - else - DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); + if vobVelocity = 0 then + DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) + else + DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); vgtCloud: if SuddenDeathDmg then DrawSprite(sprSDCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else @@ -425,8 +425,8 @@ end; if Gear^.Tint <> $FFFFFFFF then Tint($FF,$FF,$FF,$FF); Gear:= Gear^.NextGear - end; - // this level is on the land one when stereo + end; + // this layer is on the land level (which is close but behind the screen plane) when stereo 1: while Gear <> nil do begin tinted:= false; @@ -436,47 +436,47 @@ vgtEvilTrace: if Gear^.State < 8 then DrawSprite(sprEvilTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State); vgtLineTrail: DrawLine(Gear^.X, Gear^.Y, Gear^.dX, Gear^.dY, 1.0, $FF, min(Gear^.Timer, $C0), min(Gear^.Timer, $80), min(Gear^.Timer, $FF)); end; - if (cReducedQuality and rqAntiBoom) = 0 then - case Gear^.Kind of - vgtSmoke: DrawSprite(sprSmoke, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); - vgtSmokeWhite: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); - vgtDust: if Gear^.State = 1 then - DrawSprite(sprSnowDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame) - else - DrawSprite(sprDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); - vgtFire: if (Gear^.State and gstTmpFlag) = 0 then - DrawSprite(sprFlame, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy, (RealTicks shr 6 + Gear^.Frame) mod 8) - else - DrawTextureF(SpritesData[sprFlame].Texture, Gear^.FrameTicks / 900, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, (RealTicks shr 7 + Gear^.Frame) mod 8, 1, 16, 16); - vgtSplash: if SuddenDeathDmg then - DrawSprite(sprSDSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37)) - else - DrawSprite(sprSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37)); - vgtDroplet: if SuddenDeathDmg then - DrawSprite(sprSDDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame) - else - DrawSprite(sprDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame); - vgtChunk: DrawRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); - end; + if (cReducedQuality and rqAntiBoom) = 0 then + case Gear^.Kind of + vgtSmoke: DrawSprite(sprSmoke, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); + vgtSmokeWhite: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); + vgtDust: if Gear^.State = 1 then + DrawSprite(sprSnowDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame) + else + DrawSprite(sprDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); + vgtFire: if (Gear^.State and gstTmpFlag) = 0 then + DrawSprite(sprFlame, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy, (RealTicks shr 6 + Gear^.Frame) mod 8) + else + DrawTextureF(SpritesData[sprFlame].Texture, Gear^.FrameTicks / 900, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, (RealTicks shr 7 + Gear^.Frame) mod 8, 1, 16, 16); + vgtSplash: if SuddenDeathDmg then + DrawSprite(sprSDSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37)) + else + DrawSprite(sprSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37)); + vgtDroplet: if SuddenDeathDmg then + DrawSprite(sprSDDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame) + 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); + end; if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF); Gear:= Gear^.NextGear - end; - // this level is on the screen plane when stereo (depth = 0) + end; + // this layer is on the screen plane (depth = 0) when stereo 3: while Gear <> nil do begin tinted:= false; if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint); case Gear^.Kind of vgtSpeechBubble: begin - if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team <> CurrentTeam)) or (Gear^.State = 1)) then - begin - tinted:= true; - Tint($FF, $FF, $FF, $66); - DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex) - end - else if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team = CurrentTeam)) or (Gear^.State = 2)) then - DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); - end; + if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team <> CurrentTeam)) or (Gear^.State = 1)) then + begin + tinted:= true; + Tint($FF, $FF, $FF, $66); + DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex) + end + else if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team = CurrentTeam)) or (Gear^.State = 2)) then + DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); + end; vgtSmallDamageTag: DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); vgtHealthTag: if Gear^.Tex <> nil then DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); vgtHealth: begin @@ -488,10 +488,14 @@ DrawSprite(sprHealth, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, 0); end; end; + if (cReducedQuality and rqAntiBoom) = 0 then + case Gear^.Kind of + vgtChunk: DrawRotatedF(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); Gear:= Gear^.NextGear end; - // this level is outside the screen when stereo + // this layer is outside the screen when stereo 2: while Gear <> nil do begin tinted:= false; @@ -503,27 +507,26 @@ Tint($FF, $FF, $FF, round($FF * (1 - power(Gear^.Timer / 250, 4)))); DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle); end; - end; + end; if (cReducedQuality and rqAntiBoom) = 0 then case Gear^.Kind of vgtExplPart: DrawSprite(sprExplPart, round(Gear^.X) + WorldDx - 16, round(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame); vgtExplPart2: DrawSprite(sprExplPart2, round(Gear^.X) + WorldDx - 16, round(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame); - vgtBubble: DrawSprite(sprBubbles, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8); vgtSteam: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame); vgtAmmo: begin - tinted:= true; - Tint($FF, $FF, $FF, round(Gear^.alpha * $FF)); - DrawTextureF(ropeIconTex, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 32, 32); - DrawTextureF(SpritesData[sprAMAmmos].Texture, Gear^.scale * 0.90, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame - 1, 1, 32, 32); - end; + tinted:= true; + Tint($FF, $FF, $FF, round(Gear^.alpha * $FF)); + DrawTextureF(ropeIconTex, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 32, 32); + DrawTextureF(SpritesData[sprAMAmmos].Texture, Gear^.scale * 0.90, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame - 1, 1, 32, 32); + end; vgtShell: begin - if Gear^.FrameTicks < $FF then - begin - Tint($FF, $FF, $FF, Gear^.FrameTicks); - tinted:= true - end; - DrawRotatedF(sprShell, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); - end; + if Gear^.FrameTicks < $FF then + begin + Tint($FF, $FF, $FF, Gear^.FrameTicks); + tinted:= true + end; + DrawRotatedF(sprShell, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + end; vgtFeather: begin if Gear^.FrameTicks < 255 then begin @@ -533,40 +536,40 @@ DrawRotatedF(sprFeather, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); end; vgtEgg: begin - if Gear^.FrameTicks < $FF then - begin + if Gear^.FrameTicks < $FF then + begin Tint($FF, $FF, $FF, Gear^.FrameTicks); tinted:= true - end; - DrawRotatedF(sprEgg, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); end; - vgtBeeTrace: begin - if Gear^.FrameTicks < $FF then - Tint($FF, $FF, $FF, Gear^.FrameTicks div 2) - else - Tint($FF, $FF, $FF, $80); - tinted:= true; - DrawRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle); - end; + DrawRotatedF(sprEgg, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + end; + vgtBeeTrace: begin + if Gear^.FrameTicks < $FF then + Tint($FF, $FF, $FF, Gear^.FrameTicks div 2) + else + Tint($FF, $FF, $FF, $80); + tinted:= true; + DrawRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle); + end; vgtSmokeRing: begin - tinted:= true; - Tint($FF, $FF, $FF, round(Gear^.alpha * $FF)); - DrawRotatedTextureF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle); - end; - vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + tinted:= true; + Tint($FF, $FF, $FF, round(Gear^.alpha * $FF)); + DrawRotatedTextureF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle); + end; + vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); vgtBulletHit: DrawRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle); end; case Gear^.Kind of - vgtCircle: if gear^.Angle = 1 then - begin - tmp:= Gear^.State / 100; - DrawTexture(round(Gear^.X-24*tmp) + WorldDx, round(Gear^.Y-24*tmp) + WorldDy, SpritesData[sprVampiric].Texture, tmp) - end - else DrawCircle(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State, Gear^.Timer); + vgtCircle: if gear^.Angle = 1 then + begin + tmp:= Gear^.State / 100; + DrawTexture(round(Gear^.X-24*tmp) + WorldDx, round(Gear^.Y-24*tmp) + WorldDy, SpritesData[sprVampiric].Texture, tmp) + end + else 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); Gear:= Gear^.NextGear - end + end end; end; diff -r bf6d4bc531d2 -r 67278f1cba2c hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Tue Jun 21 16:43:05 2011 +0400 +++ b/hedgewars/uWorld.pas Thu Jun 23 21:19:43 2011 +0400 @@ -528,8 +528,8 @@ var i, w, h, lw, lh, rw, rh, sw: LongInt; begin sw:= round(cScreenWidth / cScaleFactor); - if (SpritesData[sprL].Texture = nil) or (SpritesData[sprR].Texture = nil) then - begin + if ((SpritesData[sprL].Texture = nil) or (SpritesData[sprR].Texture = nil)) and (SpritesData[spr].Texture <> nil) then + begin w:= SpritesData[spr].Width * SpritesData[spr].Texture^.Scale; h:= SpritesData[spr].Height * SpritesData[spr].Texture^.Scale; i:= Shift mod w; @@ -539,9 +539,9 @@ DrawTexture(i, WorldDy + LAND_HEIGHT + OffsetY - h, SpritesData[spr].Texture, SpritesData[spr].Texture^.Scale); inc(i, w) until i > sw - end - else - begin + end + else if SpritesData[spr].Texture <> nil then + begin w:= SpritesData[spr].Width * SpritesData[spr].Texture^.Scale; h:= SpritesData[spr].Height * SpritesData[spr].Texture^.Scale; lw:= SpritesData[sprL].Width * SpritesData[spr].Texture^.Scale; @@ -553,18 +553,18 @@ i:= Shift - lw; while i >= -sw - lw do - begin + begin DrawTexture(i, WorldDy + LAND_HEIGHT + OffsetY - lh, SpritesData[sprL].Texture, SpritesData[sprL].Texture^.Scale); dec(i, lw); - end; + end; i:= Shift + w; while i <= sw do - begin + begin DrawTexture(i, WorldDy + LAND_HEIGHT + OffsetY - rh, SpritesData[sprR].Texture, SpritesData[sprR].Texture^.Scale); inc(i, rw) + end end - end end; diff -r bf6d4bc531d2 -r 67278f1cba2c misc/hedgewars.png Binary file misc/hedgewars.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c project_files/HedgewarsMobile/Classes/MapConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/MapConfigViewController.m Tue Jun 21 16:43:05 2011 +0400 +++ b/project_files/HedgewarsMobile/Classes/MapConfigViewController.m Thu Jun 23 21:19:43 2011 +0400 @@ -380,14 +380,14 @@ -(void) loadDataSourceArray { NSString *model = getModelType(); - // themes.cfg contains all the user-selectable themes - NSString *string = [[NSString alloc] initWithContentsOfFile:[THEMES_DIRECTORY() stringByAppendingString:@"/themes.cfg"] - encoding:NSUTF8StringEncoding - error:NULL]; - NSMutableArray *themeArray = [[NSMutableArray alloc] initWithArray:[string componentsSeparatedByString:@"\n"]]; - [string release]; - // remove a trailing "" element - [themeArray removeLastObject]; + // only folders containing icon.png are a valid theme + NSArray *themeArrayFull = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:THEMES_DIRECTORY() error:NULL]; + NSMutableArray *themeArray = [[NSMutableArray alloc] init]; + for (NSString *themeName in themeArrayFull) { + NSString *checkPath = [[NSString alloc] initWithFormat:@"%@/%@/icon.png",THEMES_DIRECTORY(),themeName]; + if ([[NSFileManager defaultManager] fileExistsAtPath:checkPath]) + [themeArray addObject:themeName]; + } // remove images that are too big for certain devices without loading the whole image NSArray *mapArrayFull = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:MAPS_DIRECTORY() error:NULL]; diff -r bf6d4bc531d2 -r 67278f1cba2c project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj --- a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Tue Jun 21 16:43:05 2011 +0400 +++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Thu Jun 23 21:19:43 2011 +0400 @@ -1370,7 +1370,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "#copy new stuff over old stuff\nrm -rf ${PROJECT_DIR}/Data\n\n#create config.inc\necho \"Updating config file...\"\nPROTO=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep HEDGEWARS_PROTO_VER | cut -d ' ' -f 3`\nMAJN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MAJOR | xargs | cut -d ' ' -f 3`\nMINN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MINOR | xargs | cut -d ' ' -f 3`\nPATN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_PATCH | xargs | cut -d ' ' -f 3 | cut -d '$' -f 1`\nREVN=-`/usr/local/bin/hg id -n ${PROJECT_DIR}/../../`\necho \"const cNetProtoVersion = $PROTO; const cVersionString = '${MAJN}.${MINN}.${PATN}${REVN}'; const cLuaLibrary = '';\" > ${PROJECT_DIR}/../../hedgewars/config.inc\n\necho \"Copying Data...\"\ncp -R ${PROJECT_DIR}/../../share/hedgewars/Data ${PROJECT_DIR}/Data\n\n#copy some files from QTfrontend/res\necho \"Fetching additional graphics from QTfrontend/res...\"\nmkdir ${PROJECT_DIR}/Data/Graphics/Btn\ncp ${PROJECT_DIR}/../../QTfrontend/res/btn*.png ${PROJECT_DIR}/Data/Graphics/Btn/\ncp ${PROJECT_DIR}/../../QTfrontend/res/icon*.png ${PROJECT_DIR}/Data/Graphics/Btn/\ncp ${PROJECT_DIR}/../../QTfrontend/res/StatsMedal*.png ${PROJECT_DIR}/Data/Graphics/Btn/\ncp ${PROJECT_DIR}/../../QTfrontend/res/StatsR.png ${PROJECT_DIR}/Data/Graphics/Btn/StatsStar.png\ncp ${PROJECT_DIR}/../../QTfrontend/res/ammopic.png ${PROJECT_DIR}/Data/Graphics/Btn/iconAmmo.png\ncp -R ${PROJECT_DIR}/../../QTfrontend/res/botlevels ${PROJECT_DIR}/Data/Graphics/Hedgehog/botlevels/\n\necho \"Removing text and dummy files...\"\n#delete all CMakeLists.txt and image source files\nfind ${PROJECT_DIR}/Data -name CMakeLists.txt -delete\nfind ${PROJECT_DIR}/Data -name *.svg -delete\nfind ${PROJECT_DIR}/Data -name *.svgz -delete\nfind ${PROJECT_DIR}/Data -name *.sifz -delete\nfind ${PROJECT_DIR}/Data -name *.xcf -delete\nfind ${PROJECT_DIR}/Data -name *.orig -delete\n\n#delete desktop frontend translation\nrm -rf ${PROJECT_DIR}/Data/Locale/hedgewars_*\n\n#delete dummy maps and hats, misc stuff\nrm -rf ${PROJECT_DIR}/Data/Maps/{test*,Ruler}\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/{TeamCap,TeamHeadband,TeamHair}\nrm -rf ${PROJECT_DIR}/Data/misc/\n\n#delete forbidden maps\nrm -rf ${PROJECT_DIR}/Data/Maps/{Cheese,FlightJoust}\n\n#delete useless fonts\nrm -rf ${PROJECT_DIR}/Data/Fonts/{wqy-zenhei.ttc,DroidSansFallback.ttf}\n\n#delete all names, reserved hats\nrm -rf ${PROJECT_DIR}/Data/Names/\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/Reserved/\n\necho \"Handling audio files...\"\n#delete the Classic voice\nrm -rf ${PROJECT_DIR}/Data/Sounds/voices/Classic\n#delete the main theme file\nrm -rf ${PROJECT_DIR}/Data/Music/main_theme.ogg\n#copy mono audio\ncp -R ${PROJECT_DIR}/Audio/* ${PROJECT_DIR}/Data/\n#remove unused voices\nfor i in {Amazing,Brilliant,Bugger,Bungee,Cutitout,Drat,Excellent,Fire,FlawlessPossibility,Gonnagetyou,Grenade,Hmm,Justyouwait,Leavemealone,Ohdear,Ouch,Perfect,Revenge,Runaway,Solong,Thisoneismine,VictoryPossibility,Watchthis,Whatthe,Whoopsee}; do find Data/Sounds/voices/ -name $i.ogg -delete; done\n\necho \"Tweaking Data contents...\"\n#move Lua maps in Missions\nmkdir ${PROJECT_DIR}/Data/Missions/Maps/\nmv ${PROJECT_DIR}/Data/Maps/{Basketball,Knockball,TrophyRace,CTF_Blizzard,Control} ${PROJECT_DIR}/Data/Missions/Maps/\n#workaround for missing map in CTF_Blizzard\nln -s ../../../Maps/Blizzard/map.png ${PROJECT_DIR}/Data/Missions/Maps/CTF_Blizzard/map.png\n\n#reduce the number of flakes for City\nawk '{if ($1 == 1500) $1=40; print $0}' < ${PROJECT_DIR}/Data/Themes/City/theme.cfg > /tmp/tempfile\nmv /tmp/tempfile ${PROJECT_DIR}/Data/Themes/City/theme.cfg\n\n#remove Isalnd from the list of Themes\nawk '{if ($1 != \"Island\") print $0}' < ${PROJECT_DIR}/Data/Themes/themes.cfg > /tmp/tempfile && mv /tmp/tempfile ${PROJECT_DIR}/Data/Themes/themes.cfg\n\n#remove Beach and Digital themes as well as Islqnd (from Maps and Themes folders)\nrm -rf ${PROJECT_DIR}/Data/Themes/{Beach,Digital}\nrm -rf ${PROJECT_DIR}/Data/Themes/Island\nawk '{if ($1 == \"Island\") print \"Nature\"}' < ${PROJECT_DIR}/Data/Maps/Cave/map.cfg > /tmp/tempfile && mv /tmp/tempfile ${PROJECT_DIR}/Data/Maps/Cave/map.cfg\nawk '{if ($1 == \"Island\") print \"Nature\"}' < ${PROJECT_DIR}/Data/Maps/Lonely_Island/map.cfg > /tmp/tempfile && mv /tmp/tempfile ${PROJECT_DIR}/Data/Maps/Lonely_Island/map.cfg\nawk '{if ($1 == \"Island\") print \"Nature\"}' < ${PROJECT_DIR}/Data/Maps/PirateFlag/map.cfg > /tmp/tempfile && mv /tmp/tempfile ${PROJECT_DIR}/Data/Maps/PirateFlag/map.cfg\n\necho \"Done\""; + shellScript = "#copy new stuff over old stuff\nrm -rf ${PROJECT_DIR}/Data\n\n#create config.inc\necho \"Updating config file...\"\nPROTO=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep HEDGEWARS_PROTO_VER | cut -d ' ' -f 3`\nMAJN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MAJOR | xargs | cut -d ' ' -f 3`\nMINN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MINOR | xargs | cut -d ' ' -f 3`\nPATN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_PATCH | xargs | cut -d ' ' -f 3 | cut -d '$' -f 1`\nREVN=-`/usr/local/bin/hg id -n ${PROJECT_DIR}/../../`\necho \"const cNetProtoVersion = $PROTO; const cVersionString = '${MAJN}.${MINN}.${PATN}${REVN}'; const cLuaLibrary = '';\" > ${PROJECT_DIR}/../../hedgewars/config.inc\n\necho \"Copying Data...\"\ncp -R ${PROJECT_DIR}/../../share/hedgewars/Data ${PROJECT_DIR}/Data\n\n#copy some files from QTfrontend/res\necho \"Fetching additional graphics from QTfrontend/res...\"\nmkdir ${PROJECT_DIR}/Data/Graphics/Btn\ncp ${PROJECT_DIR}/../../QTfrontend/res/btn*.png ${PROJECT_DIR}/Data/Graphics/Btn/\ncp ${PROJECT_DIR}/../../QTfrontend/res/icon*.png ${PROJECT_DIR}/Data/Graphics/Btn/\ncp ${PROJECT_DIR}/../../QTfrontend/res/StatsMedal*.png ${PROJECT_DIR}/Data/Graphics/Btn/\ncp ${PROJECT_DIR}/../../QTfrontend/res/StatsR.png ${PROJECT_DIR}/Data/Graphics/Btn/StatsStar.png\ncp ${PROJECT_DIR}/../../QTfrontend/res/ammopic.png ${PROJECT_DIR}/Data/Graphics/Btn/iconAmmo.png\ncp -R ${PROJECT_DIR}/../../QTfrontend/res/botlevels ${PROJECT_DIR}/Data/Graphics/Hedgehog/botlevels/\n\necho \"Removing text and dummy files...\"\n#delete all CMakeLists.txt and image source files\nfind ${PROJECT_DIR}/Data -name CMakeLists.txt -delete\nfind ${PROJECT_DIR}/Data -name *.svg -delete\nfind ${PROJECT_DIR}/Data -name *.svgz -delete\nfind ${PROJECT_DIR}/Data -name *.sifz -delete\nfind ${PROJECT_DIR}/Data -name *.xcf -delete\nfind ${PROJECT_DIR}/Data -name *.orig -delete\n\n#delete desktop frontend translation\nrm -rf ${PROJECT_DIR}/Data/Locale/hedgewars_*\n\n#delete dummy maps and hats, misc stuff\nrm -rf ${PROJECT_DIR}/Data/Maps/{test*,Ruler}\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/{TeamCap,TeamHeadband,TeamHair}\nrm -rf ${PROJECT_DIR}/Data/misc/\n\n#delete forbidden maps\nrm -rf ${PROJECT_DIR}/Data/Maps/{Cheese,FlightJoust}\n\n#delete useless fonts\nrm -rf ${PROJECT_DIR}/Data/Fonts/{wqy-zenhei.ttc,DroidSansFallback.ttf}\n\n#delete all names, reserved hats\nrm -rf ${PROJECT_DIR}/Data/Names/\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/Reserved/\n\necho \"Handling audio files...\"\n#delete the Classic voice\nrm -rf ${PROJECT_DIR}/Data/Sounds/voices/Classic\n#delete the main theme file\nrm -rf ${PROJECT_DIR}/Data/Music/main_theme.ogg\n#copy mono audio\ncp -R ${PROJECT_DIR}/Audio/* ${PROJECT_DIR}/Data/\n#remove unused voices\nfor i in {Amazing,Brilliant,Bugger,Bungee,Cutitout,Drat,Excellent,Fire,FlawlessPossibility,Gonnagetyou,Grenade,Hmm,Justyouwait,Leavemealone,Ohdear,Ouch,Perfect,Revenge,Runaway,Solong,Thisoneismine,VictoryPossibility,Watchthis,Whatthe,Whoopsee}; do find Data/Sounds/voices/ -name $i.ogg -delete; done\n\necho \"Tweaking Data contents...\"\n#move Lua maps in Missions\nmkdir ${PROJECT_DIR}/Data/Missions/Maps/\nmv ${PROJECT_DIR}/Data/Maps/{Basketball,Knockball,TrophyRace,CTF_Blizzard,Control} ${PROJECT_DIR}/Data/Missions/Maps/\n#workaround for missing map in CTF_Blizzard\nln -s ../../../Maps/Blizzard/map.png ${PROJECT_DIR}/Data/Missions/Maps/CTF_Blizzard/map.png\n\n#reduce the number of flakes for City\nawk '{if ($1 == 1500) $1=40; print $0}' < ${PROJECT_DIR}/Data/Themes/City/theme.cfg > /tmp/tempfile\nmv /tmp/tempfile ${PROJECT_DIR}/Data/Themes/City/theme.cfg\n\n#remove WIP themes (check they are not used in Maps)\nrm -rf ${PROJECT_DIR}/Data/Themes/{Beach,Digital}\n\necho \"Done\""; showEnvVarsInLog = 0; }; 9283011B0F10CB2D00CC5A3C /* Build libfpc.a */ = { diff -r bf6d4bc531d2 -r 67278f1cba2c project_files/hedgewars.pro --- a/project_files/hedgewars.pro Tue Jun 21 16:43:05 2011 +0400 +++ b/project_files/hedgewars.pro Thu Jun 23 21:19:43 2011 +0400 @@ -3,6 +3,7 @@ DEPENDPATH += ../QTfrontend/ INCLUDEPATH += ../QTfrontend/ INCLUDEPATH += /usr/local/include/SDL +INCLUDEPATH += /usr/include/SDL DESTDIR = . @@ -11,6 +12,7 @@ } QT += network +QT += webkit HEADERS += ../QTfrontend/KB.h ../QTfrontend/SDLs.h \ ../QTfrontend/SquareLabel.h ../QTfrontend/about.h \ @@ -24,13 +26,12 @@ ../QTfrontend/igbox.h ../QTfrontend/input_ip.h \ ../QTfrontend/itemNum.h ../QTfrontend/mapContainer.h \ ../QTfrontend/misc.h ../QTfrontend/namegen.h \ - ../QTfrontend/netregister.h ../QTfrontend/netserver.h \ + ../QTfrontend/netregister.h ../QTfrontend/netserver.h \ ../QTfrontend/netserverslist.h ../QTfrontend/netudpserver.h \ ../QTfrontend/netudpwidget.h ../QTfrontend/newnetclient.h \ - ../QTfrontend/pages.h ../QTfrontend/playrecordpage.h \ - ../QTfrontend/proto.h \ + ../QTfrontend/proto.h \ ../QTfrontend/sdlkeys.h ../QTfrontend/selectWeapon.h \ - ../QTfrontend/statsPage.h ../QTfrontend/tcpBase.h \ + ../QTfrontend/tcpBase.h \ ../QTfrontend/team.h ../QTfrontend/teamselect.h \ ../QTfrontend/teamselhelper.h ../QTfrontend/togglebutton.h \ ../QTfrontend/ui_hwform.h ../QTfrontend/vertScrollArea.h \ @@ -38,7 +39,32 @@ ../QTfrontend/achievements.h \ ../QTfrontend/drawmapwidget.h \ ../QTfrontend/drawmapscene.h \ - ../QTfrontend/qaspectratiolayout.h + ../QTfrontend/qaspectratiolayout.h \ + ../QTfrontend/pagetraining.h \ + ../QTfrontend/pagesingleplayer.h \ + ../QTfrontend/pageselectweapon.h \ + ../QTfrontend/pagescheme.h \ + ../QTfrontend/pageroomslist.h \ + ../QTfrontend/pageoptions.h \ + ../QTfrontend/pagenettype.h \ + ../QTfrontend/pagenetserver.h \ + ../QTfrontend/pagenetgame.h \ + ../QTfrontend/pagenet.h \ + ../QTfrontend/pagemultiplayer.h \ + ../QTfrontend/pagemain.h \ + ../QTfrontend/pageingame.h \ + ../QTfrontend/pageinfo.h \ + ../QTfrontend/pagedata.h \ + ../QTfrontend/pageeditteam.h \ + ../QTfrontend/pagedrawmap.h \ + ../QTfrontend/pageconnecting.h \ + ../QTfrontend/pagecampaign.h \ + ../QTfrontend/pageadmin.h \ + ../QTfrontend/pageplayrecord.h \ + ../QTfrontend/pagegamestats.h \ + ../QTfrontend/HWApplication.h \ + ../QTfrontend/AbstractPage.h \ + ../QTfrontend/themesmodel.h SOURCES += ../QTfrontend/SDLs.cpp ../QTfrontend/SquareLabel.cpp \ ../QTfrontend/about.cpp ../QTfrontend/ammoSchemeModel.cpp \ @@ -54,9 +80,9 @@ ../QTfrontend/namegen.cpp ../QTfrontend/netregister.cpp \ ../QTfrontend/netserver.cpp ../QTfrontend/netserverslist.cpp \ ../QTfrontend/netudpserver.cpp ../QTfrontend/netudpwidget.cpp \ - ../QTfrontend/newnetclient.cpp \ - ../QTfrontend/playrecordpage.cpp ../QTfrontend/proto.cpp \ - ../QTfrontend/selectWeapon.cpp ../QTfrontend/statsPage.cpp \ + ../QTfrontend/newnetclient.cpp \ + ../QTfrontend/proto.cpp \ + ../QTfrontend/selectWeapon.cpp \ ../QTfrontend/tcpBase.cpp ../QTfrontend/team.cpp \ ../QTfrontend/teamselect.cpp ../QTfrontend/teamselhelper.cpp \ ../QTfrontend/togglebutton.cpp ../QTfrontend/ui_hwform.cpp \ @@ -80,11 +106,16 @@ ../QTfrontend/pagemain.cpp \ ../QTfrontend/pageingame.cpp \ ../QTfrontend/pageinfo.cpp \ + ../QTfrontend/pagedata.cpp \ ../QTfrontend/pageeditteam.cpp \ ../QTfrontend/pagedrawmap.cpp \ ../QTfrontend/pageconnecting.cpp \ ../QTfrontend/pagecampaign.cpp \ - ../QTfrontend/pageadmin.cpp + ../QTfrontend/pageadmin.cpp \ + ../QTfrontend/pagegamestats.cpp \ + ../QTfrontend/pageplayrecord.cpp \ + ../QTfrontend/HWApplication.cpp \ + ../QTfrontend/themesmodel.cpp win32 { SOURCES += ../QTfrontend/xfire.cpp diff -r bf6d4bc531d2 -r 67278f1cba2c share/CMakeLists.txt --- a/share/CMakeLists.txt Tue Jun 21 16:43:05 2011 +0400 +++ b/share/CMakeLists.txt Thu Jun 23 21:19:43 2011 +0400 @@ -20,6 +20,8 @@ DESTINATION ../) install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/Icon.icns" DESTINATION ../Resources/) + install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/hwico.icns" + DESTINATION ../Resources/) install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/dsa_pub.pem" DESTINATION ../Resources/) ENDIF(APPLE) diff -r bf6d4bc531d2 -r 67278f1cba2c share/Info.plist.in --- a/share/Info.plist.in Tue Jun 21 16:43:05 2011 +0400 +++ b/share/Info.plist.in Thu Jun 23 21:19:43 2011 +0400 @@ -44,8 +44,112 @@ ppc LSMinimumSystemVersion - ${minimum_macosx} + ${minimum_macosx_version} SUPublicDSAKeyFile dsa_pub.pem + CFBundleLocalizations + + ar + bg + cs + de + el + en + es + fi + fr + gl + hu + it + ja + ko + nl + pl + pt_BR + pt_PT + ru + sk + sv + tr + uk + zh_CN + zh_TW + + UTExportedTypeDeclarations + + + UTTypeIdentifier + org.hedgewars.desktop.hws + UTTypeReferenceURL + http://www.hedgewars.org/demos/ + UTTypeDescription + Hedgewars Save Game + UTTypeIconFile + public.text.icns + UTTypeConformsTo + + public.data + + UTTypeTagSpecification + + public.filename-extension + + hws + + public.mime-type + application/x-hedgewars-save + + + + UTTypeIdentifier + org.hedgewars.desktop.hwd + UTTypeReferenceURL + http://www.hedgewars.org/demos/ + UTTypeIconFile + public.text.icns + UTTypeDescription + Hedgewars Demo Game + UTTypeConformsTo + + public.data + + UTTypeTagSpecification + + public.filename-extension + + hwd + + public.mime-type + application/x-hedgewars-demo + + + + CFBundleDocumentTypes + + + CFBundleTypeIconFile + hwico.icns + CFBundleTypeName + Hedgewars Savefile + LSItemContentTypes + + org.hedgewars.desktop.hws + + CFBundleTypeRole + Editor + + + CFBundleTypeIconFile + hwico.icns + CFBundleTypeName + Hedgewars Demofile + LSItemContentTypes + + org.hedgewars.desktop.hwd + + CFBundleTypeRole + Viewer + + diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Graphics/Chunk.png Binary file share/hedgewars/Data/Graphics/Chunk.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Locale/pl.txt --- a/share/hedgewars/Data/Locale/pl.txt Tue Jun 21 16:43:05 2011 +0400 +++ b/share/hedgewars/Data/Locale/pl.txt Thu Jun 23 21:19:43 2011 +0400 @@ -52,6 +52,10 @@ 00:49=Wskrzeszacz 00:50=Wiertniczy nalot 00:51=Kula błotna +00:52=Nie wybrano broń +00:53=TARDIS +00:54=Struktura +00:55=Land Spray 01:00=Walczmy! 01:01=Remis @@ -142,7 +146,6 @@ 02:00=%1 się wykrwawił 02:00=%1 zginął za słuszną sprawę 02:00=%1 zostawił w domu kamizelkę kuloodporną - ; Hog (%1) drowned 02:01=%1 robi za łódź podwodną! @@ -207,6 +210,7 @@ 02:01=%1 chciał sobie pogadać z rybkami 02:01=%1, uważaj na rekiny! 02:01=%1 pływa po Warszawsku. Tyłkiem po piasku! + ; Round starts 02:02=Walczmy! 02:02=Cel! Pal! @@ -259,10 +263,13 @@ 02:02=Daj im popalić! 02:02=Nie odczuwaj strachu! 02:02=Bądź odważny i podbijaj! + ; Round ends (win; unused atm) 02:03=... + ; Round ends (draw; unused atm) 02:04=... + ; New health crate 02:05=Przybyła pomoc! 02:05=Medyk! @@ -294,6 +301,7 @@ 02:05=W Hedgewars opieka zdrowotna naprawdę wymiata! 02:05=Na zdrowie! 02:05=Szczepionka! + ; New ammo crate 02:06=Więcej broni! 02:06=Posiłki! @@ -325,6 +333,7 @@ 02:06=Wyślij SMS na numer 7400 do wygrania zawartość zasobnika! 02:06=Czy to ptak...? Czy to samolot...? 02:06=Spadające gwiazdy nie spełniają życzeń, ale zasobniki jak najbardziej + ; New utility crate 02:07=Czas na narzędzia! 02:07=To może się przydać... @@ -343,6 +352,7 @@ 02:07=Zasobniki prosto z Ameryki! 02:07=Zapasy materiałów eksploatacyjnych! 02:07=Dorwij przeciwnika szybciej z nowymi narzędziami + ; Hog (%1) skips his turn 02:08=%1 jest taki nudny... 02:08=%1 próbuje się skupić @@ -394,6 +404,7 @@ 02:08=%1 ma wszystko w nosie 02:08=%1 nie chce połamać sobie igieł 02:08=%1 ma stracha + ; Hog (%1) hurts himself only 02:09=%1 powinien potrenować celowanie! 02:09=%1 najwidoczniej nienawidzi samego siebie.. @@ -445,6 +456,7 @@ 02:09=%1 ma już dość tego świata 02:09=%1 dostał łapówkę 02:09=%1 przywalił, jak łysy czupryną o kant kuli + ; Hog shot an home run (using the bat and another hog) 02:10=Home Run! 02:10=To ptak? To samolot? @@ -455,6 +467,16 @@ 02:10=Niezły rzut! 02:10=Chyba padnie rekord Guinessa w rzucie jeżem! 02:10=To było odlotowe! + +; Hog (%1) has to leave (team is gone) +02:11=%1 musi iść do łóżka! +02:11=%1 wydaje się zbyt zajęty, by grać +02:11=Zostałeś zajęty zamrozić dla jeża, %1 +02:11=Źłe gry przestała, albo nie działa. +02:11=%1 awaria z gracza +02:11=Belka go, Szkot! +02:11=%1 musi odejść + ; Weapon Categories 03:00=Granat z zapalnikiem 03:01=Granat z zapalnikiem @@ -507,6 +529,10 @@ 03:48=Ała! Moja głowa... 03:49=Powrót z zaświatów 03:50=Krecia brygada +03:51=Znalezione na ziemi +03:52=UNUSED +03:53=Typ 40 +03:54=Zbudować coś ; Weapon Descriptions (use | as line breaks) 04:00=Atakuj przeciwników zwykłym granatem.|Wybuchnie kiedy zapalnik skończy odliczanie.|1-5: Ustawia zapalnik|Atak: Przytrzymaj by rzucić z większą siłą @@ -560,7 +586,6 @@ 04:48=Czyż walenie jeży po głowach nie|jest zabawne? Dobre uderzenie|z młotka zabierze 1/3 życia|przeciwnika i wkopie go w podłoże|Atak: Uderz 04:49=Wskrześ swoich przyjaciół!|Jednakże uważaj byś nie pomógł swojemu wrogowi.|Atak: Przytrzymaj by powoli przywracać życie|Góra: Przyspiesz wskrzeszanie - ; Game goal strings 05:00=Ustawienia gry 05:01=Obowiązują następujące zasady: @@ -583,3 +608,4 @@ 05:18=Tura nie kończy się po wykonaniu ataku 05:19=Uzbrojenie zostaje przywrócone przy kolejnej turze 05:20=Każdy z jeży ma oddzielne uzbrojenie +05:21=Zespół Tag: Zespoły w klanie na kolejnych kolejkach|Wspólna Godzina: Drużyny w akcji raz z kolei klanu diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Locale/ru.txt --- a/share/hedgewars/Data/Locale/ru.txt Tue Jun 21 16:43:05 2011 +0400 +++ b/share/hedgewars/Data/Locale/ru.txt Thu Jun 23 21:19:43 2011 +0400 @@ -12,7 +12,7 @@ 00:09=Пистолет Desert Eagle 00:10=Динамит 00:11=Бейсбольная бита -00:12=Shoryuken +00:12=Восходящий удар Дракона 00:13=сек 00:14=Парашют 00:15=Воздушная атака @@ -42,6 +42,20 @@ 00:39=Летающая тарелка 00:40=Коктейль Молотова 00:41=Птичка +00:42=Портативный телепорт +00:43=Фортепьяновый удар +00:44=Старый Лимбургер +00:45=Синус-пушка (в разработке) +00:46=Огнемет +00:47=Мина-липучка +00:48=Молот +00:49=Воскреситель +00:50=Сверлящий удар +00:51=Комок грязи +00:52=Оружие не выбрано +00:53=Машина времени и пространства +00:54=Структура +00:55=Земляной распылитель 01:00=Вперёд к победе! 01:01=Ничья @@ -49,152 +63,327 @@ 01:03=Громкость %1% 01:04=Пауза 01:05=Точно выйти (Y-Да/Esc-Нет)? -01:06=Скоро погибель! +01:06=Скоро потоп! 01:07=Ещё %1 01:08=Топливо 01:09=Синхронизация... +01:10=Использование этого предмета не завершит твой ход! +01:11=Это оружие или предмет еще недоступно! +01:12=Последний раунд до потопа! +01:13=%1 раундов до потопа! +01:14=Приготовься, %1! ; Event messages ; Hog (%1) died -02:00=%1 не думал, что так случится! -02:00=%1 машет на прощание рукой! +02:00=%1 накрылся медным тазом! +02:00=%1 увидел свет в конце тонеля! +02:00=%1 никогда не знал, что его ждет! +02:00=%1 помахал на прощание лапкой! 02:00=%1 ушёл в лучший мир! +02:00=%1 встретился со своим Создателем! +02:00=%1 больше не может держаться! +02:00=%1 исполнил свой долг! +02:00=%1 принес последнюю жертву! +02:00=%1 покидает мирскую суету! +02:00=%1 стал удобрением! +02:00=%1 отстрелялся! +02:00=%1 приказал долго жить! +02:00=%1, мы будем вспоминать о тебе с любовью! +02:00=%1 покинул этот мир из-за аневризмы! +02:00=%1 оставил жену и ребенка 02:00=%1 уже не воспользуется базукой 02:00=%1 уже не бросит гранату 02:00=%1 уже не испечёт торт 02:00=%1 уже не повисит на верёвке -02:00=%1 отстрелялся -02:00=%1 ушёл поиграть в лучшую игру +02:00=%1 уже не вызовет воздушную атаку +02:00=%1 уже не выстрелит из дробовика +02:00=%1 уже не достанет свой арбуз +02:00=%1 уже не достанет свой Desert Eagle +02:00=%1 заплатил сполна +02:00=%1 мог бы воспользоваться аптечкой +02:00=%1 ушел играть в игру получше +02:00=%1 прожил трудную жизнь 02:00=%1 вышел из строя 02:00=Бедный, бедный %1... -02:00=%1 предпочитает Warmux -02:00=%1 идёт по пути динозавров +02:00=%1 предпочитает Wormux +02:00=%1 принял удар на себя +02:00=%1 герой среди лю...гм...ежей +02:00=%1 занял свое место в Валгале +02:00=%1 оставил дом +02:00=%1 пошел по стопам динозавров 02:00=%1 ведёт ежей по пути вымирания 02:00=%1 выдавил слезу из моих глаз +02:00=%1 бывший ёж +02:00=%1 откинул копыта 02:00=%1 перестал существовать 02:00=Скажите "Прощай, %1!" 02:00=Надежды больше нет, %1 -02:00=Срок истёк, %1 -02:00=%1 терпел обиды +02:00=Это было твое последнее представление, %1 +02:00=Закури перед смертью, %1, т.к твоему здоровью это уже не повредит +02:00=%1 испытал Внезапный Массовый Отказ в Системе Жизнеобеспечения (C) +02:00=%1 преставился +02:00=%1 стопроцентный труп +02:00=%1 ... его больше нет +02:00=%1 закончился +02:00=Лишенный жизни, %1, покойся с миром +02:00=%1 присоединился к хору невидимых +02:00=Прощай %1, мы едва тебя знали! +02:00=%1 имел плохую сопротивляемость к тому, чтобы быть застреленным 02:00=%1 хотел бы иметь ещё одну жизнь 02:00=В доме есть доктор? + ; Hog (%1) drowned 02:01=%1 играет подводную лодку! 02:01=%1 подражает Титанику! 02:01=%1 плавает как топор! 02:01=%1 плавает как кирпич! 02:01=%1 проверяет глубину -02:01=%1 вызывает всплеск -02:01=%1 забыл надувной круг +02:01=%1 издал бульк, бульк, бульк +02:01=От %1 пошли брызги +02:01=%1 забыл свои надувные нарукавнички 02:01=%1 пропустил уроки плавания +02:01=%1 забыл дома доску для серфинга +02:01=%1 помылся +02:01=%1 - это один мокрый ёж 02:01=%1 забыл надеть спасательный жилет +02:01=%1 плескается в воде 02:01=%1 спит среди рыб -02:01=%1 томится жаждой +02:01=%1 думал, что физика воды в этой игре полный отстой +02:01=%1 испытывает жажду +02:01=Море заказало %1 02:01=%1 потерян в море 02:01=%1 забыл надеть акваланг 02:01=%1 похоронен в море -02:01=%1 пробует плавать на спине +02:01=У %1 было дурное предчуствие +02:01=%1 учится плавать на спине 02:01=%1 поплыл искать Титаник -02:01=%1 ищет Немо +02:01=%1 не Иисус +02:01=%1 в поисках Немо +02:01=%1 дал течь +02:01=Ты будешь удивлен, узнав, сколько здесь внизу ежей, %1 02:01=%1 немного повысил уровень океана 02:01=%1 не записался в моряки +02:01=%1 перевоплотился в мертвую рыбу +02:01=По крайней мере, тебя не смыло в унитаз, %1 +02:01=Соник тоже никогда не умел плавать и не умеет сейчас, %1 +02:01=%1 хочет поиграть в Ecco the Dolphin +02:01=%1 пошел посмотреть аквариум 02:01=%1 нашёл потерянный город Атлантиды +02:01=%1 стремится к главной роли в игре Bioshock 3 +02:01=Твое плаванье по-сабачьи принесло мало пользы, %1 +02:01=%1 забыл взять гидроцикл 02:01=%1 не любит водный спорт -02:01=%1 заливает раны солёной водой +02:01=%1 всегда пускает пузыри +02:01=%1 нуждается в плоту +02:01=%1 думает, что соленая вода полезна для кожи +02:01=%1 обрабатывает раны соленой водой +02:01=%1 прошел по доске 02:01=%1 принимает ванну +02:01=%1 промок 02:01=%1 промочил иголки +02:01=Это сундучок Дэйви Джонса для %1 + ; Round starts -02:02=Вперёд к победе! -02:02=Вооружены и готовы! -02:02=Сделаем это! -02:02=Начнём вечеринку! +02:02=Сразимся! +02:02=Вооружены и готовы к бою! +02:02=Приготовься пошуметь! +02:02=Начнем! +02:02=Начнем эту партию +02:02=Останется только один 02:02=Поехали! +02:02=Поколбасимся! +02:02=Налетай! 02:02=Это начало... 02:02=Это начало чего-то большого -02:02=Добро пожаловать на войну ежей -02:02=Добро пожаловать на фронт -02:02=Разбей врага! +02:02=Добро пожаловать в Hedgewars +02:02=Добро пожаловать на передовую +02:02=Сокруши своих врагов! +02:02=Пусть победит сильнейший 02:02=Победа или смерть +02:02=Победитель получает все 02:02=Поражение - не вариант +02:02=Порви всех! Спусти с цепей ежей войны! 02:02=Hedgewars от команды Hedgewars.org 02:02=Удачи, веселись -02:02=Побеждённые убирают за всех! +02:02=Можешь считать себя счастливчиком, что ты играешь не против Tiyuri +02:02=Можешь считать себя счастливчиком, что ты играешь против unC0Rr +02:02=Можешь считать себя счастливчиком, что ты играешь против Nemo +02:02=Можешь считать себя счастливчиком, что ты играешь не против Smaxx +02:02=Можешь считать себя счастливчиком, что ты играешь не против Jessor +02:02=Сделай все что сможешь и даже больше! +02:02=Проигравшие убирают за всех! +02:02=Начни битву тысячелетия +02:02=Начни битву века +02:02=Начни битву этого квартала года +02:02=Начни битву года +02:02=Начни битву месяца +02:02=Начни битву недели +02:02=Нажни битву дня +02:02=Начни битву часа +02:02=Покажи все, на что ты способен! +02:02=Уничтожь врагов! 02:02=Удачи -02:02=Не сдавайся! +02:02=Веселись +02:02=Отдайся всецело битве +02:02=Сражайся грязно, не брезгуй любыми методами +02:02=Сражайся с честью +02:02=Не сдавайся +02:02=Никогда не сдавайся +02:02=Врежь им и наваляй! +02:02=Открой счет убитым ежам. Начни Frag-фестиваль! +02:02=Я надеюсь, что ты готов к потасовке! +02:02=Давай, давай, поехали! +02:02=Ежиное наступление! +02:02=Наваляй им! +02:02=Не бойся! +02:02=Будь храбрым и победи + ; Round ends (win; unused atm) 02:03=... + ; Round ends (draw; unused atm) 02:04=... + ; New health crate 02:05=Помощь пришла! 02:05=Аптечка! 02:05=Первая помощь с небес! +02:05=Медпакет для тебя 02:05=Здоровье... в форме ящика! -02:05=Доктор звонит -02:05=Для улучшения самочувствия -02:05=Подбери это +02:05=Доктора вызывали? +02:05=Новые бинты! +02:05=Это улучшит твое самочуствие +02:05=Супер-микстура! Еще не все потеряно +02:05=Подбери меня +02:05=Подбери ее +02:05=Оздоровительная закуска 02:05=Средство от боли -02:05=Дозировка: сколько найдёшь! +02:05=Способ применения и дозы: столько, сколько сможешь найти! +02:05=Срочная доставка +02:05=Доставка! + ; New ammo crate 02:06=Ещё оружие! 02:06=Подкрепление! -02:06=Интересно, что там? +02:06=Опечатано и погружено! +02:06=Интересно, что там за оружие? +02:06=Доставка! +02:06=Что бы там могло быть внутри? +02:06=Рождество в Hedgewars приходит раньше 02:06=Подарок! 02:06=Особая посылка! 02:06=Было сложно провести это через таможню 02:06=Опасные игрушки с небес -02:06=Подбери или взорви -02:06=Мммм... оружие +02:06=Предупреждение! Содержимое изменчиво +02:06=Подбери это или взорви, выбор за тобой +02:06=Клёвые штучки! +02:06=Мммм... боеприпасы +02:06=Ящик разрушительной силы 02:06=Воздушная почта! 02:06=Что бы там ни было, это не пицца 02:06=Подбери! -02:06=Не отдавай врагу! -02:06=Новые игрушки! +02:06=Прибыло подкрепление +02:06=Не отдавай это врагу! +02:06=Игрушки - новые, блестящие, совсем как настоящие! 02:06=Магический ящик! + ; New utility crate -02:07=Это может быть полезно... +02:07=Время мастерить! +02:07=Это может пригодиться... +02:07=Полезная вещь! +02:07=Используй этот ящик +02:07=Ищи его внизу +02:07=Еще полезные вещи! +02:07=Инструменты для тебя! +02:07=Это должно быть что-то хорошее! 02:07=Используй с умом -02:07=Тебе это понадобится -02:07=Используй этот ящик 02:07=О! Это тяжёлый ящик +02:07=Тебе это может понадобиться + ; Hog (%1) skips his turn 02:08=%1 такой скучный... +02:08=%1 ни о чем не беспокоится 02:08=%1 ленивый ёж 02:08=%1 беспечен 02:08=%1 сдался +02:08=Задремаешь - проиграешь, %1 02:08=%1 позорно пропускает -02:08=%1 нуждается в мотивации +02:08=%1 самый настоящий лентяй +02:08=%1 нуждается в немного большей мотивации 02:08=%1 пацифист +02:08=%1 взял передышку 02:08=%1 отдыхает -02:08=%1 расслабляется -02:08=%1 позволяет врагу делать что угодно +02:08=%1 прохлаждается +02:08=%1 не верит в собственные силы +02:08=%1 решил вообще ничего не делать +02:08=%1 позволяет врагу уничтожить себя +02:08=%1 был бы самым скучным на вечеринках 02:08=%1 прячется 02:08=%1 решил пропустить эту возможность 02:08=%1 решил, что лучше сделать... ничего -02:08=%1 большой копуша +02:08=%1 слабак +02:08=Цыпа цыпа цыпа, цыпленок %1 +02:08=%1 выглядит желторотым юнцом 02:08=%1 трус! -02:08=%1 ожидает потоп +02:08=%1 ждет потопа +02:08=%1 не боец 02:08=%1 пересматривает свой смысл жизни -02:08=%1 всё равно не умеет стрелять +02:08=%1 в любом случае, никогда не умел хорошо стрелять +02:08=%1 не хотел присоединяться к армии в первых рядах +02:08=Хватит впустую тратить время, %1 02:08=Я разочарован тобой, %1 +02:08=Давай, ты можешь добиться большего, чем этот %1 +02:08=Намерения %1 провалились +02:08=%1 очевидно знает более интересные дела +02:08=%1 оцепенел от страха +02:08=%1 уснул + ; Hog (%1) hurts himself only 02:09=%1 должен практиковаться в прицеливании! 02:09=%1 ненавидит себя +02:09=%1 перешел на сторону врага! +02:09=%1 уподобился эмо 02:09=%1 не той стороной взялся за оружие +02:09=%1 немного садистский +02:09=%1 мазохист 02:09=%1 не имеет инстинкта самосохранения 02:09=%1 напортачил +02:09=%1 перенервничал 02:09=Это был плохой выстрел, %1 -02:09=%1 неосторожен с оружием +02:09=%1 немного неосторожен с опасным оружием +02:09=%1 должен пересмотреть свой карьерный путь 02:09=Худший. Выстрел. Из всех! 02:09=Нет, нет, нет %1, стреляй по ВРАГУ! -02:09=%1 на шаг ближе к самоубийству +02:09=%1 должен был всего лишь уничтожить врага +02:09=%1 стал на шаг ближе к самоубийству 02:09=%1 помогает врагу +02:09=Это было глупо, %1 +02:09=%1 живет молитвами "через мучения к наслаждению" +02:09=%1 совсем запутался +02:09=%1 поранил себя в суматохе +02:09=%1 горазд ставить себя в глупое положение +02:09=%1 недотёпа! +02:09=%1 неуклюжий 02:09=%1 показывает врагу, на что он способен -02:09=%1, конечно, сделал это специально +02:09=Нельзя от %1 всегда ожидать совершенства +02:09=Не волнуйся %1, сикто не новершенен +02:09=%1 вообщем-то сделал это намерено 02:09=Я никому не скажу, если ты не скажешь, %1 +02:09=Какой стыд! +02:09=Я уверен, никто этого не видел %1 +02:09=%1 должен пересмотреть свой боевой устав +02:09=Очевидно, что оружие %1 работало со сбоями + ; Hog shot an home run (using the bat and another hog) -02:10=Птица, самолёт, ... -02:10=Он вылетел! +02:10=Хоум-ран! +02:10=Птица, самолет, ... +02:10=Тот отсутствует! + +; Hog (%1) has to leave (team is gone) +02:11=%1 должен идти спать! +02:11=%1 кажется слишком занят, чтобы играть +02:11=Излучи его, Скотти! +02:11=%1 должен идти ; Weapon Categories 03:00=Граната с таймером @@ -239,50 +428,72 @@ 03:39=Инструмент для перемещения 03:40=Испепеляющая граната 03:41=Большой поклонник Squawks +03:42=Здесь я веду записи... +; the misspelled "Beethoven" is intentional (-> to beat) +03:43=Исполнение смертельной сонаты Бетховена +03:44=Годен до: 1923 +03:45=Достижения науки +03:46=Горячо, горячо, горячо! +03:47=Прикрепи их где-нибудь с пользой! +03:48=Время Молота! +03:49=Делает то, о чем ты подумал +03:50=Большой любитель кротов +03:51=Найденный на земле +03:52=Не используется +03:53=Модель 40 +03:54=Построй что нибудь ; Weapon Descriptions (use | as line breaks) -04:00=Атакуй своих врагов обычной гранатой.|Она взорвется сразу, как только таймер|достигнет нуля.|1-5: Установить таймер гранаты|Attack: Удерживай для более дальнего броска -04:01=Атакуй своих врагов касетной бомбой.|Она расколется на несколько меньших бомб,|когда таймер достигнет нуля.|1-5: Установить таймер бомбы|Attack: Удерживай для более дальнего броска -04:02=Атакуй своих врагов баллистическим снарядом,|на который может повлиять направление ветра.|Attack: Удерживай для выстрела с большей силой -04:03=Запусти взрывчатую пчелу, которая соединится|с выбранной целью. Не бросай ее слишком сильно,|чтобы повысить точность.|Cursor: Захватить цель|Attack: Удерживай для более дальнего броска -04:04=Атакуй своих врагов с помощью дробовика|с двумя выстрелами. Благодаря его большому|радиусу поражения тебе не нужно заботиться о|точности попадания, чтобы нанести урон сопернику.|Attack: Выстрелить (несколько раз) -04:05=Двигайся вглубь земли! Используй отбойный|молоток, чтобы пробурить отверстие в земле и|добраться до других участков.|Attack: Запустить или остановить бурение -04:06=Заскучал?|Нет возможности атаковать?|Бережешь боеприпасы?|Нет проблем! Пропусти ход, трус!|Attack: Пропустить ход без сражения -04:07=Преодолевай большие расстояния за короткое|время с помощью веревки. Используй инерцию тела,|чтобы переместиться к другим ежам или сбросить|на них гранаты и другое вооружение.|Attack: Выстрелить или освободить веревку|Long Jump: Сбросить гранаты или похожее вооружение -04:08=Держи своих врагов на расстоянии,|бросая мины в узкие проходы или|прямо им под ноги. Убедись, что отступил,|пока мина не сработала рядом с тобой!|Attack: Бросить мину рядом с собой -04:09=Не уверен, что хорошо прицелился?|Используй пистолет Desert Eagle|с возможностью сделать до четырех|выстрелов за ход.|Attack: Выстрелить (несколько раз) -04:10=Грубая сила всегда была в цене.|Брось эту классическую взрывчатку|возле своих врагов и убегай.|Attack: Бросить динамит рядом с собой -04:11=Избавься от вражеских ежей с помощью|подачи битой, отправив их за край карты|или в воду. Или как насчет того, чтобы отправить ударом|одну из мин на карте в подарок своим друзьям?|Attack: Нанести удар по всему, что стоит перед тобой -04:12=Стань лицом к лицу со своим врагом,|чтобы обрушить на него всю мощь|смертоносной техники боевых исскуств.|Attack: Исполнить Неистовый Удар +04:00=Атакуй своих врагов обычной гранатой.|Она взорвется сразу, как только таймер|достигнет нуля.|1-5: Установить таймер гранаты|Атака: Удерживай для более дальнего броска +04:01=Атакуй своих врагов касетной бомбой.|Она расколется на несколько меньших бомб,|когда таймер достигнет нуля.|1-5: Установить таймер бомбы|Атака: Удерживай для более дальнего броска +04:02=Атакуй своих врагов баллистическим снарядом,|на который может повлиять направление ветра.|Атака: Удерживай для выстрела с большей силой +04:03=Запусти взрывчатую пчелу, которая соединится|с выбранной целью. Не бросай ее слишком сильно,|чтобы повысить точность.|Курсор: Захватить цель|Атака: Удерживай для более дальнего броска +04:04=Атакуй своих врагов с помощью дробовика|с двумя выстрелами. Благодаря его большому|радиусу поражения тебе не нужно заботиться о|точности попадания, чтобы нанести урон сопернику.|Атака: Выстрелить (несколько раз) +04:05=Двигайся вглубь земли! Используй отбойный|молоток, чтобы пробурить отверстие в земле и|добраться до других участков.|Атака: Запустить или остановить бурение +04:06=Заскучал?|Нет возможности атаковать?|Бережешь боеприпасы?|Нет проблем! Пропусти ход, трус!|Атака: Пропустить ход без сражения +04:07=Преодолевай большие расстояния за короткое|время с помощью веревки. Используй инерцию тела,|чтобы переместиться к другим ежам или сбросить|на них гранаты и другое вооружение.|Атака: Выстрелить или освободить веревку|Длинный прыжок: Сбросить гранаты или похожее вооружение +04:08=Держи своих врагов на расстоянии,|бросая мины в узкие проходы или|прямо им под ноги. Убедись, что отступил,|пока мина не сработала рядом с тобой!|Атака: Бросить мину рядом с собой +04:09=Не уверен, что хорошо прицелился?|Используй пистолет Desert Eagle|с возможностью сделать до четырех|выстрелов за ход.|Атака: Выстрелить (несколько раз) +04:10=Грубая сила всегда была в цене.|Брось эту классическую взрывчатку|возле своих врагов и убегай.|Атака: Бросить динамит рядом с собой +04:11=Избавься от вражеских ежей с помощью|подачи битой, отправив их за край карты|или в воду. Или как насчет того, чтобы отправить ударом|одну из мин на карте в подарок своим друзьям?|Атака: Нанести удар по всему, что стоит перед тобой +04:12=Стань лицом к лицу со своим врагом,|чтобы обрушить на него всю мощь|смертоносной техники боевых исскуств.|Атака: Исполнить Восходящий удар Дракона 04:13=Не используется -04:14=Боишься высоты? Тогда возьми парашут.|Он раскроется, как только ты начнешь слишком|долго падать, и тем самым убережет ежа|от падения с большой высоты.|Attack: Раскрыть парашут|Long Jump: Сбросить гранаты или похожее вооружение -04:15=Вызови самолет, чтобы атаковать своих врагов|с помощью воздушной бомбардировки.|Left/Right: Определить направление атаки|Cursor: Выбрать бомбардируемую область -04:16=Вызови самолет, чтобы сбросить несколько мин|в заданной области.|Left/Right: Определить направление атаки|Cursor: Выбрать минируемую область -04:17=Нуждаешься в убежище? Используй паяльную|лампу, чтобы пробурить тунель в твердом грунте,|обеспечив себя крышей над головой.|Attack: Запустить или остановить бурение -04:18=Нуждаешься в дополнительной защите|или хочешь преодолеть непреодолимую преграду?|Размести несколько поперечных балок там,|где тебе будет удобно.|Left/Right: Выбрать балку для размещения|Cursor: Разместить поперечную балку в нужной позиции -04:19=Использование телепортации в нужный момент|времени может оказаться более полезным,|чем все имеющееся оружие, поскольку она|позволяет тебе вытаскивать ежей из опасных|ситуаций за считанные секунды.|Cursor: Выбрать место телепортации -04:20=Позволь себе сыграть текущий ход другим ежом.|Attack: Активировать переключение ежей|Tab: Переключить ежа -04:21=Выстрели снарядом с разделяющейся боеголовкой,|которая в результате столкновения с препятствием|расколется на несколько бомб.|Attack: Выстрелить с максимальной силой -04:22=Эта штука не только для Индианы Джонс!|Кнут - полезное оружие во многих ситуациях.|Особенно, когда ты хочешь кого-нибудь сбросить|с крутого склона.|Attack: Нанести удар по всему, что стоит перед тобой -04:23=Когда тебе нечего терять, эта возможность|может быть очень кстати. Пожертвуй своим ежом,|запустив его в заданном направлении. Он нанесет|урон всему на своем пути и в конце взорвется.|Attack: Запустить разрушительную и смертельную атаку -04:24=С Днем Рождения! Запусти этот торт, дай ему|добежать до твоих врагов и организуй взрывную вечеринку.|Торт способен преодолеть практически всю территорию,|но может взорваться и раньше на этом пути.|Attack: Запустить торт или остановить его и взорвать -04:25=Используй этот набор косметики, чтобы привлечь|к себе вражеского ежа, который пылая страстью|бросится к твоему ежу (а также в какой-нибудь|обрыв или яму).|Attack: Использовать косметику и попытаться соблазнить|другого ежа -04:26=Брось этот сочный арбуз по своим врагам.|Когда таймер достигнет нуля он разделится|на несколько взрывоопасных арбузных корок.|1-5: Установить арбузный таймер|Attack: Удерживай для более дальнего броска -04:27=Пролей дождь адского огня на своих|оппонентов, используя эту дьявольскую|взрывчатку. Держись подальше от взрыва,|поскольку мелкий огонь после него|будет гореть еще некоторое время.|Attack: Удерживай для более дальнего броска -04:28=Через короткий промежуток времени после|запуска этой ракеты она начнет сверлить|твердую поверхность и взорвется как только|сработает ее плавкий предохранитель или|она высвободится на открытое пространство.|Attack: Удерживай для выстрела с большей силой -04:29=Это штука - детям не игрушка!|Шаромет стреляет огромным количеством|маленьких шариков, заполненных взрывчаткой.|Attack: Выстрелить с максимальной силой|Up/Down: Продолжать прицельную стрельбу -04:30=Вызови самолет для осуществления мощного|удара напалмом. При надлежащем прицеливании,|такая атака может нанести опустошительный урон|большим участкам поверхности, включая ежей,|которым не повезло оказаться не в то время,|не в том месте.|И еще... не забудь учесть направление и силу ветра.|Left/Right: Определить направление атаки|Cursor: Выбрать область для удара напалмом -04:31=Радиоуправляемый самолет - идеальное оружие,|чтобы пополнить коллекцию старых самолетов|или атаковать далеко стоящих ежей. Направь его|прямо на своих врагов или сбрось сперва несколько|бомб.|Attack: Запусти самолет или сбрось бомбы|Long Jump: Исполнить 'Полет валькирий'|Up/Down: Направлять самолет в процессе полета -04:32=Слабая гравитация более эффективна, чем диета!|Прыгай выше и на более дальние дистанции или|позволь своим врагам улететь еще дальше.|Attack: Включить слабую гравитацию -04:33=Иногда тебе нужно просто немного повысить|силу своего оружия, чтобы нанести сопернику|больший урон.|Attack: Включить дополнительный урон -04:34=Не сможете ко мне прикоснуться!|Attack: Включить неуязвимость -04:35=Иногда кажется, что время летит слишком быстро.|Воспользуйся этими дополнительными секундами,|чтобы завершить свою атаку.|Attack: Включить дополнительное время -04:36=Действительно, иногда ты выглядишь|просто мазилой. Воспользуйся поддержкой|современных технологий.|Attack: Включить лазерный прицел -04:37=Не бойся дневного света. Его вред для тебя|продлится всего один ход, но позволит тебе|поглотить весь урон, который ты нанесешь|другим ежам.|Attack: Включить вампиризм -04:38=Снайперская винтовка может быть самым|разрушительным оружием во всем твоем|арсенале, однако она очень неэффективна|на близких дистанциях. Наносимый урон|увеличивается пропорционально расстоянию|до цели.|Attack: Выстрелить (дважды) -04:39=Летай в другие части карты на летающей тарелке.|Это сложное в освоении устройство позволит тебе|переместиться практически в любую точку на поле|битвы.|Attack: Запустить тарелку|Up/Left/Right: Приложить тягу для движения в одном|направлении (многократное нажатие)|Long Jump: Сбросить гранаты или похожее вооружение -04:40=Вызови пожар на каком-нибудь участке|поверхности с помощью это бутылки,|заполненной горючей жидкостью.|Attack: Удерживай для более дальнего броска -04:41=Очевидно, что живая природа может превзойти|летающую тарелку. Птичка может носить повсюду|твоего ежа и сбрасывать яйца на твоих врагов!|Attack: Запустить птичку и бросать яйца|Up/Left/Right: Хлопать крыльями для движения в одном|направлении +04:14=Боишься высоты? Тогда возьми парашут.|Он раскроется, как только ты начнешь слишком|долго падать, и тем самым убережет ежа|от падения с большой высоты.|Атака: Раскрыть парашут|Длинный прыжок: Сбросить гранаты или похожее вооружение +04:15=Вызови самолет, чтобы атаковать своих врагов|с помощью воздушной бомбардировки.|Влево/Вправо: Определить направление атаки|Курсор: Выбрать бомбардируемую область +04:16=Вызови самолет, чтобы сбросить несколько мин|в заданной области.|Влево/Вправо: Определить направление атаки|Курсор: Выбрать минируемую область +04:17=Нуждаешься в убежище? Используй паяльную|лампу, чтобы пробурить тунель в твердом грунте,|обеспечив себя крышей над головой.|Атака: Запустить или остановить бурение +04:18=Нуждаешься в дополнительной защите|или хочешь преодолеть непреодолимую преграду?|Размести несколько поперечных балок там,|где тебе будет удобно.|Left/Right: Выбрать балку для размещения|Курсор: Разместить поперечную балку в нужной позиции +04:19=Использование телепортации в нужный момент|времени может оказаться более полезным,|чем все имеющееся оружие, поскольку она|позволяет тебе вытаскивать ежей из опасных|ситуаций за считанные секунды.|Курсор: Выбрать место телепортации +04:20=Позволь себе сыграть текущий ход другим ежом.|Атака: Активировать переключение ежей|Tab: Переключить ежа +04:21=Выстрели снарядом с разделяющейся боеголовкой,|которая в результате столкновения с препятствием|расколется на несколько бомб.|Атака: Выстрелить с максимальной силой +04:22=Эта штука не только для Индианы Джонс!|Кнут - полезное оружие во многих ситуациях.|Особенно, когда ты хочешь кого-нибудь сбросить|с крутого склона.|Атака: Нанести удар по всему, что стоит перед тобой +04:23=Когда тебе нечего терять, эта возможность|может быть очень кстати. Пожертвуй своим ежом,|запустив его в заданном направлении. Он нанесет|урон всему на своем пути и в конце взорвется.|Атака: Запустить разрушительную и смертельную атаку +04:24=С Днем Рождения! Запусти этот торт, дай ему|добежать до твоих врагов и организуй взрывную вечеринку.|Торт способен преодолеть практически всю территорию,|но может взорваться и раньше на этом пути.|Атака: Запустить торт или остановить его и взорвать +04:25=Используй этот набор косметики, чтобы привлечь|к себе вражеского ежа, который пылая страстью|бросится к твоему ежу (а также в какой-нибудь|обрыв или яму).|Атака: Использовать косметику и попытаться соблазнить|другого ежа +04:26=Брось этот сочный арбуз по своим врагам.|Когда таймер достигнет нуля он разделится|на несколько взрывоопасных арбузных корок.|1-5: Установить арбузный таймер|Атака: Удерживай для более дальнего броска +04:27=Пролей дождь адского огня на своих|оппонентов, используя эту дьявольскую|взрывчатку. Держись подальше от взрыва,|поскольку мелкий огонь после него|будет гореть еще некоторое время.|Атака: Удерживай для более дальнего броска +04:28=Через короткий промежуток времени после|запуска этой ракеты она начнет сверлить|твердую поверхность и взорвется как только|сработает ее плавкий предохранитель или|она высвободится на открытое пространство.|Атака: Удерживай для выстрела с большей силой +04:29=Это штука - детям не игрушка!|Шаромет стреляет огромным количеством|маленьких шариков, заполненных взрывчаткой.|Атака: Выстрелить с максимальной силой|Вверх/Вниз: Продолжать прицельную стрельбу +04:30=Вызови самолет для осуществления мощного|удара напалмом. При надлежащем прицеливании,|такая атака может нанести опустошительный урон|большим участкам поверхности, включая ежей,|которым не повезло оказаться не в то время,|не в том месте.|И еще... не забудь учесть направление и силу ветра.|Влево/Вправо: Определить направление атаки|Курсор: Выбрать область для удара напалмом +04:31=Радиоуправляемый самолет - идеальное оружие,|чтобы пополнить коллекцию старых самолетов|или атаковать далеко стоящих ежей. Направь его|прямо на своих врагов или сбрось сперва несколько|бомб.|Атака: Запустить самолет или сбросить бомбы|Длинный прыжок: Исполнить 'Полет валькирий'|Вверх/Вниз: Управлять самолетом в процессе полета +04:32=Слабая гравитация более эффективна, чем диета!|Прыгай выше и на более дальние дистанции или|позволь своим врагам улететь еще дальше.|Атака: Включить слабую гравитацию +04:33=Иногда тебе нужно просто немного повысить|силу своего оружия, чтобы нанести сопернику|больший урон.|Атака: Включить дополнительный урон +04:34=Не сможете меня задеть!|Атака: Включить неуязвимость +04:35=Иногда кажется, что время летит слишком быстро.|Воспользуйся этими дополнительными секундами,|чтобы завершить свою атаку.|Атака: Включить дополнительное время +04:36=Действительно, иногда ты выглядишь|просто мазилой. Воспользуйся поддержкой|современных технологий.|Атака: Включить лазерный прицел +04:37=Не бойся дневного света. Его вред для тебя|продлится всего один ход, но позволит тебе|поглотить весь урон, который ты нанесешь|другим ежам.|Атака: Включить вампиризм +04:38=Снайперская винтовка может быть самым|разрушительным оружием во всем твоем|арсенале, однако она очень неэффективна|на близких дистанциях. Наносимый урон|увеличивается пропорционально расстоянию|до цели.|Атака: Выстрелить (дважды) +04:39=Летай в другие части карты на летающей тарелке.|Это сложное в освоении устройство позволит тебе|переместиться практически в любую точку на поле|битвы.|Атака: Запустить тарелку|Вверх/Влево/Вправо: Приложить тягу для движения|в одном направлении (многократное нажатие)|Длинный прыжок: Сбросить гранаты или похожее|вооружение +04:40=Вызови пожар на каком-нибудь участке|поверхности с помощью этой бутылки,|заполненной горючей жидкостью.|Атака: Удерживай для более дальнего броска +04:41=Очевидно, что живая природа может превзойти|летающую тарелку. Птичка может повсюду носить|твоего ежа и сбрасывать яйца на твоих врагов!|Атака: Запустить птичку и бросать яйца|Вверх/Влево/Вправо: Хлопать крыльями для движения в одном|направлении +04:42=Этот портативный телепорт способен мгновенно|переместить тебя, твоих врагов, или твое вооружение|между двумя точками на местности. Используй его с умом|и твоей кампании будет сопутствовать...|ОГРОМНЫЙ УСПЕХ!|Атака: Выстрелить точкой телепорта|Переключение: Прокрутить цвета точек телепорта +04:43=Обеспечь своему музыкальному дебюту взрывной успех!|Сбрось фортепьяно с небес, но знай... кто-то должен|играть на нем, и это может стоить тебе жизни!|Курсор: Выбрать область удара|F1-F9: Играть на фортепьяно +04:44=Это не обычный сыр, это война с применением|биологического оружия! Сыр не причинит большого|урона сразу, как только таймер достигнет нуля.|Но он будет постоянно отравлять любого,|кто имел неудачу вдохнуть зловоние!|1-5: Установить таймер гранаты|Атака: Удерживай для более дальнего броска +04:45=Все те уроки физики, что были, наконец окупились|запуском разрушительной Синус-волны|по твоим врагам.|Будь осторожен, это оружие наносит серийный удар.|(Разработка этого оружия еще не завершена)|Атака: Выстрелить +04:46=Накрой своих врагов испепеляющим жидким|пламенем. С самыми теплыми чувствами!|Атака: Активировать|Вверх/Вниз: Продолжать прицельный полив|Влево/Вправо: Изменить силу (дальность) полива +04:47=Удвой веселье с двумя шипованными, коварными,|липучими минами. Устрой цепную реакцию или|защити себя (или то и другое!)|Атака: Удерживай для более дальнего броска|(дважды) +04:48=Почему кротам достаются все оскорбления?|Вакингующий ёж может быть столь забавным!|Хороший удар этого молота сбреет треть|здоровья ежа и погрузит его в землю.|Атака: Ударить молотом +04:49=Воскреси своих друзей!|Но будь осторожен, т.к. оно также воскресит|твоих врагов.|Атака: Удерживай атаку нажатой для медленного|воскрешения|Вверх: Ускорить воскрешение ; Game goal strings 05:00=Режимы игры @@ -301,3 +512,10 @@ 05:13=Таймер мины: мины детонируют мгновенно 05:14=Таймер мины: мины детонируют после 0 - 3 секунд 05:15=Изменение уровня урона: всё оружие наносит %1% урона +05:16=Здоровье всех ежей восстановится в конце хода +05:17=Ежи ИИ возрождаются в момент гибели +05:18=Неограниченное количество атак +05:19=Оружие восстановится в конце хода +05:20=Ежи не имеют общего оружия +05:21=Признак команды: Команды в клане ходят последовательно|Общее время: Команды в клане имеют общее время хода + diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Missions/Training/User_Mission_-_That_Sinking_Feeling.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_That_Sinking_Feeling.lua Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,244 @@ + + +loadfile(GetDataPath() .. "Scripts/Locale.lua")() + +local player +local hh = {} +local hhCount = 8 +local GameOver = false +local introStage = 0 +local genCounter = 0 +local waterCounter = 0 +local waterPix = 0 + +-- allow skipping of the intro via hitting precise key +function onPrecise() + if introStage < 100 then + introStage = 110 + genCounter = 0 + FollowGear(CurrentHedgehog) + AddCaption(loc("Good luck out there!")) + ShowMission(loc("That Sinking Feeling"), loc("User Challenge"), loc("Save as many hapless hogs as possible!"), 4, 0) + end +end + +function onGameInit() + + Seed = 0 + GameFlags = gfInfAttack + gfInvulnerable + TurnTime = 90000 + CaseFreq = 0 + MinesNum = 0 + MinesTime = 3000 + Explosives = 0 + Delay = 10 + Map = "Islands" + Theme = "City" + + AddTeam(loc("Nameless Heroes"), 14483456, "Simple", "Island", "Default") + player = AddHog(loc("The Nameless One"), 0, 1, "NoHat") + + AddTeam(loc("Hapless Hogs"), 1175851, "Simple", "Island", "Default") + hh[0] = AddHog(loc("Sinky"), 1, 100, "lemon") + hh[1] = AddHog(loc("Drowner"), 1, 100, "orange") + hh[2] = AddHog(loc("Heavy"), 1, 100, "Teapot") + hh[3] = AddHog(loc("Clumsy"), 1, 100, "SauceBoatSilver") + hh[4] = AddHog(loc("Silly"), 1, 100, "Ladle") + hh[5] = AddHog(loc("Careless"), 1, 100, "StrawHatEyes") + hh[6] = AddHog(loc("Sponge"), 1, 100, "Chunli") + hh[7] = AddHog(loc("Deadweight"), 1, 100, "Teacup") + + SetGearPosition(player, 3992, 733) + SetGearPosition(hh[0], 938, 1369) + SetGearPosition(hh[1], 1301, 1439) + SetGearPosition(hh[2], 2093, 447) + SetGearPosition(hh[3], 2971, 926) + SetGearPosition(hh[4], 719, 545) + SetGearPosition(hh[5], 1630, 821) + SetGearPosition(hh[6], 2191, 810) + SetGearPosition(hh[7], 3799, 945) + +end + + +function onGameStart() + + ShowMission(loc("That Sinking Feeling"), loc("User Challenge"), loc("Save as many hapless hogs as possible!"), 4, 1) + + HogTurnLeft(hh[0], false) + HogTurnLeft(hh[1], true) + + SpawnUtilityCrate(148,265,amLowGravity) + SpawnUtilityCrate(2124,1516,amJetpack) + +end + + +function onNewTurn() + TurnTimeLeft = -1 +end + +function onGameTick() + + -- intro sequence + if introStage < 100 then + + AddCaption(loc("Press [Precise] to skip intro")) + + genCounter = genCounter + 1 + + if introStage == 0 then + + FollowGear(hh[0]) + + if genCounter == 2000 then + HogSay(hh[0], loc("This rain is really something..."), SAY_SAY,2) + elseif genCounter == 5000 then + introStage = 1 + genCounter = 0 + end + + elseif introStage == 1 then + + FollowGear(hh[1]) + + if genCounter == 2000 then + HogSay(hh[1], loc("Heh, it's not that bad."), SAY_SAY,2) + elseif genCounter == 5000 then + introStage = 2 + genCounter = 0 + end + + elseif introStage == 2 then + + FollowGear(hh[0]) + + if genCounter == 2000 then + HogSay(hh[0], loc("You'd almost swear the water was rising!"), SAY_SHOUT,2) + elseif genCounter == 6000 then + introStage = 3 + genCounter = 0 + end + + elseif introStage == 3 then + + FollowGear(hh[1]) + + if genCounter == 2000 then + HogSay(hh[1], loc("Haha, now THAT would be something!"), SAY_SAY,2) + elseif genCounter == 6000 then + introStage = 4 + genCounter = 0 + end + + elseif introStage == 4 then + + FollowGear(hh[0]) + + if genCounter == 2000 then + HogSay(hh[0], loc("Hahahaha!"), SAY_SHOUT,2) + HogSay(hh[1], loc("Hahahaha!"), SAY_SHOUT,2) + elseif genCounter == 3000 then + introStage = 5 + genCounter = 0 + end + + elseif introStage == 5 then + + FollowGear(hh[1]) + + if genCounter == 2000 then + HogSay(hh[0], loc("..."), SAY_THINK,2) + HogSay(hh[1], loc("..."), SAY_THINK,2) + elseif genCounter == 5000 then + introStage = 6 + genCounter = 0 + end + + elseif introStage == 6 then + + FollowGear(hh[0]) + + if genCounter == 2000 then + HogSay(hh[0], loc("It's a good thing SUDDEN DEATH is 99 turns away..."), SAY_THINK,2) + elseif genCounter == 6000 then + introStage = 7 + genCounter = 0 + end + + + elseif introStage == 7 then + + if genCounter == 2000 then + introStage = 110 + FollowGear(CurrentHedgehog) + ShowMission(loc("That Sinking Feeling"), loc("User Challenge"), loc("Save as many hapless hogs as possible!"), 4, 0) + end + + end + + end + + -- start the water rising when the intro is finished + if introStage == 110 then + + waterCounter = waterCounter + 1 + if (waterCounter == 100) and (waterPix < 1615) then + waterCounter = 0 + SetTag(AddGear(0, 0, gtWaterUp, 0, 0, 0, 0), 1) + waterPix = waterPix +1 + --AddCaption(waterPix) + + if (waterPix >= 1615) and (GameOver == false) then + GameOver = true + SetHealth(player, 0) + TurnTimeLeft = 1 + ShowMission(loc("That Sinking Feeling"), loc("MISSION SUCCESS"), loc("You saved") .. " " .. hhCount .. " " .. loc("Hapless Hogs") .."!", 0, 0) + end + + end + + end + + if TurnTimeLeft == 1 then + SetHealth(player, 0) + end + +end + + +function onAmmoStoreInit() + + SetAmmo(amBazooka, 9, 0, 0, 0) + + SetAmmo(amRope, 9, 0, 0, 0) + SetAmmo(amParachute, 9, 0, 0, 0) + SetAmmo(amJetpack, 2, 0, 0, 2) + + SetAmmo(amGirder, 9, 0, 0, 0) + SetAmmo(amBaseballBat, 9, 0, 0, 0) + + SetAmmo(amTeleport, 1, 0, 0, 1) + SetAmmo(amPortalGun, 3, 0, 0, 1) + + SetAmmo(amLowGravity, 0, 0, 0, 1) + +end + +function onGearDelete(gear) + + if GetGearType(gear) == gtHedgehog then + if GetHogTeamName(gear) == "Hapless Hogs" then + hhCount = hhCount - 1 + AddCaption(hhCount .. loc(" Hapless Hogs left!")) + end + end + + if ((gear == player) or (hhCount == 0)) and (GameOver == false) then + SetHealth(player, 0) + TurnTimeLeft = 1 + ShowMission(loc("That Sinking Feeling"), loc("MISSION FAILED"), loc("Oh no! Just try again!"), -amSkip, 0) + GameOver = true + end + +end diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua --- a/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua Tue Jun 21 16:43:05 2011 +0400 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua Thu Jun 23 21:19:43 2011 +0400 @@ -1,7 +1,7 @@ --------------------------------- --- CAPTURE_THE_FLAG_CUSTOM 0.3 +--------------------------------------- +-- CAPTURE_THE_FLAG GAMEPLAY MODE 0.4 -- by mikade --------------------------------- +--------------------------------------- -- Version History --------- @@ -50,6 +50,17 @@ -- added a check to make sure the player doesn't kamikaze straight down and make the flag's starting point underwater -- added a check to make sure the player drops the flag if he has it and he uses kamikaze +-------- +-- 0.4 +-------- + +-- remove user-branding and version numbers +-- removed some stuff that wasn't needed +-- fix piano strike exploit +-- changed delay to allow for better portals +-- changed starting feedback a little +-- increased the radius around the circle indicating the flag thief so that it doesn't obscure his health + ----------------- --SCRIPT BEGINS ----------------- @@ -188,10 +199,6 @@ end AddCaption(loc("Flag captured!")) - --below line doesnt usually get called - --else - -- now gets called if you go over your own flag, presumably - --AddCaption("Hmm... that wasn't supposed to happen...") end end @@ -227,7 +234,7 @@ fGear[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true) fGearX[i] = fSpawnX[i] fGearY[i] = fSpawnY[i] - --fGear[i] = SpawnAmmoCrate(fSpawnX[i],fSpawnY[i],amSkip) + fNeedsRespawn[i] = false fIsMissing[i] = false -- new, this should solve problems of a respawned flag being "returned" when a player tries to score AddCaption(loc("Flag respawned!")) @@ -255,12 +262,10 @@ fIsMissing[wtf] = true fNeedsRespawn[wtf] = true HandleRespawns() - --AddCaption("hah??") else --normally fGearX[wtf] = fThiefX[wtf] fGearY[wtf] = fThiefY[wtf] fGear[wtf] = AddVisualGear(fGearX[wtf],fGearY[wtf],vgtCircle,0,true) - --fGear[wtf] = AddVisualGear(fThiefX[wtf],fThiefY[wtf],vgtCircle,0,true) end AddVisualGear(fThiefX[wtf], fThiefY[wtf], vgtBigExplosion, 0, false) @@ -290,8 +295,8 @@ SetVisualGearValues(fGear[i], fSpawnX[i],fSpawnY[i], 20, 200, 0, 0, 100, fGearRad, 2, fCol[i]) end elseif (fIsMissing[i] == true) and (fNeedsRespawn[i] == false) then - if fThief[i] ~= nil then -- draw circle round flag carrier - SetVisualGearValues(fCirc[i], fThiefX[i], fThiefY[i], 20, 200, 0, 0, 100, 33, 3, fCol[i]) + if fThief[i] ~= nil then -- draw circle round flag carrier -- 33 + SetVisualGearValues(fCirc[i], fThiefX[i], fThiefY[i], 20, 200, 0, 0, 100, 50, 3, fCol[i]) --AddCaption("circle marking carrier") elseif fThief[i] == nil then -- draw cirle round dropped flag --g1X,g1Y,g4,g5,g6,g7,g8,g9,g10,g11 = GetVisualGearValues(fGear[i]) @@ -419,8 +424,6 @@ --SetVisualGearValues(zxc, 1000,1000, 20, 100, 0, 10, 1, 100, 5, GetClanColor(0)) SetVisualGearValues(fSpawnC[i], fSpawnX[i],fSpawnY[i], 20, 100, 0, 10, 0, 75, 5, fCol[i]) - --SetVisualGearValues(fCirc[i], fSpawnX[i],fSpawnY[i], 20, 20, 0, 10, 0, 33, 3, fCol[i]) - end @@ -432,12 +435,9 @@ function onGameInit() - -- Things we don't modify here will use their default values. - GameFlags = band(bor(GameFlags, gfDivideTeams), bnot(gfKing + gfForts)) - SuddenDeathTurns = 99 -- suddendeath is off, effectively - --TurnTime = 30000 -- (was 30) The time the player has to move each round (in ms) - --Delay = 10 -- The delay between each round + SuddenDeathTurns = 999 -- suddendeath is off, effectively + Delay = 10 end @@ -445,7 +445,7 @@ function onGameStart() --ShowMission(loc(caption), loc(subcaption), loc(goal), 0, 0) - ShowMission(loc("CAPTURE THE FLAG"), loc("by mikade"), loc("CUSTOM BUILD 0.2"), 0, 0) + ShowMission(loc("CAPTURE THE FLAG"), loc("Flags, and their home base will be placed where each team ends their first turn."), "", 0, 0) RebuildTeamInfo() @@ -484,7 +484,7 @@ HandleRespawns() --new method of placing starting flags elseif gameTurns == 1 then - ShowMission(loc("CAPTURE THE FLAG"), loc("Flags will be placed where each team ends their turn."), "", 0, 0) + ShowMission(loc("CAPTURE THE FLAG"), loc("Flags, and their home base will be placed where each team ends their first turn."), "", 0, 0) elseif gameTurns == 2 then fPlaced[0] = true ShowMission(loc("CAPTURE THE FLAG"), loc("RULES OF THE GAME [Press ESC to view]"), loc(" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"), 0, 0) @@ -562,16 +562,21 @@ end -function onGearDamage(gear, damage) --- -end - function onGearAdd(gear) if GetGearType(gear) == gtHedgehog then hhs[numhhs] = gear numhhs = numhhs + 1 SetEffect(gear, heResurrectable, true) + + elseif GetGearType(gear) == gtPiano then + + for i = 0, 1 do + if CurrentHedgehog == fThief[i] then + FlagThiefDead(gear) + end + end + end end @@ -579,7 +584,6 @@ function onGearDelete(gear) if GetGearType(gear) == gtHedgehog then - --AddCaption("gear deleted!") for i = 0, (numhhs-1) do if gear == hhs[i] then @@ -588,8 +592,7 @@ FlagThiefDead(gear) end end - hhs[i] = nil - --AddCaption("for real") + hhs[i] = nil end end end diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.cfg Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,2 @@ +Default +Default diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,1886 @@ + +loadfile(GetDataPath() .. "Scripts/Locale.lua")() +loadfile(GetDataPath() .. "Scripts/Tracker.lua")() + +--------------------------------------------------- +--------------------------------------------------- +--------------------------------------------------- +--- Space Invasion Code Follows (0.7) +--------------------------------------------------- +--------------------------------------------------- +-- VERSION HISTORY +---------------- +-- version 0.1 +---------------- +-- conversion of tumbler into space invasion +-- a million and one changes +-- bells and whistles + +---------------- +-- version 0.2 +---------------- +-- code slowly getting cleaner, it still looks like a spaghetti monster tho +-- lots of console tracking :/ +-- all visual gears are now compulsary (will probably revert this) +-- implemented fMod to try combat desyncs and bring this in line with dev + +---------------- +-- version 0.3 +---------------- +-- values of scoring changed to 3:10, and now based on vCircScore +-- time gained from killing a red circ increased from 3 to 4 +-- circles now spawn at a distance of at least 800 or until sanity limit +-- roundsLimit now based off MinesTime (kinda, its an experiment) + +----------------- +--0.4 +----------------- +-- commented out a lot of WriteLnToConsoles (dont need them at this point) +-- added some different WriteLnToConsoles +-- changed some of the collision detect for explosives in checkvarious() + +----------------- +--0.5 +----------------- +-- added implementation for a projectile shield +-- added a "bonus" orange invader that partially recharges player shield +-- added a tough "blueboss" blue invader +-- expanded user feedback +-- circles now have health and are capable of being merely "damaged" +-- redid a lot of the collision code and added CircleDamaged +-- added more sounds to events +-- added more visual gears + +----------------- +--0.6 +----------------- +-- removed a few WriteLns +-- added randomized grunts on circ damage +-- added (mostly) graceful fading out of circles :D: +-- changed odds for circles +-- changed user feedback +-- fixed the location of the explosion where player bashes into circ + +----------------- +--0.7 +----------------- +-- added PlaySound(sndSuddenDeath) when ammo gets depleted +-- added an extra "Ammo Depleted" note if user presses fire while empty +-- specified how much shield power is gained on shield powerup collection +-- changed odds for circles AGAIN, ammo is now sliiightly more common +-- switched most of the explosions/smoke effects back to non-critical vgears (with a few exceptions) +-- tumbletime is now based off turntime and is variable +-- delete explosives in DeleteFarFlungBarrel rather than explode them on map boundaries to save on performance +-- utilized the improved AddCaption to tint / prevent overrides +-- temporarily disabled bugged sort that displays teams according to their score +-- reluctantly changed the colour of the bonus circ to purple +-- standarized point notation +-- added some missing locs +-- commented out remaining WriteLnToConsoles for the meanwhile with the prefix "nw" + +-- ACHIEIVEMENTS added +-- (during one turn) aka repeatable +-- Ammo Manic (Destroy 3 green circles for + 5 points) +-- Drone Hunter (Destroy 5 red circles for + 10 points) +-- Shield Seeker (Destroy 3 purple circles for +10 points) +-- Boss Slayer (Destroy 2 blue circles for +25 points) + +-- Shield Master (disolve 5 shells for +10 points) +-- Shield Miser (don't use your shield at all +20 points) + +-- Depleted Kamikaze! (kamikaze into a blue/red circ when you are out of ammo) 5pts +-- Timed Kamikaze! (kamikaze into a blue/red circ when you only have 5s left) 10pts +-- Kamikaze Expert (combination of the above two) 15pts + +-- Multi-shot (destroy more than 1 invader with a single bullet) 5pts +-- X-Hit Combo (destroy another invader in less than 3 seconds) chainLength*2 points + +-- Accuracy Bonus (80% accuracy at the end of your turn with more than 5 shots fired) 15pts + +--(during the length of the game) aka non-repeatable +-- 10/25/50 kills (+25/+50/+100 points) + +-------------------------- +--notes for later +-------------------------- +-- maybe add a check for a tie, NAH +-- more achievements? (3 kamikazes in a row, long distance shooter, supreme shield expert/miser etc?) + +--[[CAPTION CATEGORIES +----------------- +capgrpGameState +----------------- + +----------------- +capgrpAmmostate +----------------- +AddCaption( chainLength .. loc("-chain! +") .. chainLength*2 .. loc(" points!"),0xffba00ff,capgrpAmmostate) +AddCaption(loc("Multi-shot! +5 points!"),0xffba00ff,capgrpAmmostate) + +----------------- +capgrpAmmoinfo +----------------- +AddCaption(loc("Shield Miser! +20 points!"),0xffba00ff,capgrpAmmoinfo) +AddCaption(loc("Shield Master! +10 points!"),0xffba00ff,capgrpAmmoinfo) + +----------------- +capgrpVolume +----------------- +AddCaption(loc("Boom! +25 points!"),0xffba00ff,capgrpVolume) +AddCaption(loc("BOOM! +50 points!"),0xffba00ff,capgrpVolume) +AddCaption(loc("BOOM! BOOM! BOOM! +100 points!"),0xffba00ff,capgrpVolume) +AddCaption(loc("Accuracy Bonus! +15 points!"),0xffba00ff,capgrpVolume) + +----------------- +capgrpMessage +----------------- +AddCaption(loc("Ammo Depleted!"),0xff0000ff,capgrpMessage) +AddCaption(loc("Ammo: ") .. primShotsLeft) +AddCaption("Shield Depleted",0xff0000ff,capgrpMessage) +AddCaption( loc("Shield ON:") .. " " .. shieldHealth - 80 .. " " .. loc("Power Remaining") ) +AddCaption(loc("Shield OFF:") .. " " .. shieldHealth - 80 .. " " .. loc("Power Remaining") ) + +AddCaption(loc("Time Extended!") .. "+" .. 4 .. loc("s"), 0xff0000ff,capgrpMessage ) +AddCaption("+" .. 3 .. " " .. loc("Ammo"), 0x00ff00ff,capgrpMessage) +AddCaption(loc("Shield boosted! +30 power"), 0xff00ffff,capgrpMessage) +AddCaption(loc("Shield is fully recharged!"), 0xffae00ff,capgrpMessage) +AddCaption(loc("Boss defeated! +50 points!"), 0x0050ffff,capgrpMessage) + +AddCaption(loc("GOTCHA!")) +AddCaption(loc("Kamikaze Expert! +15 points!"),0xffba00ff,capgrpMessage) +AddCaption(loc("Depleted Kamikaze! +5 points!"),0xffba00ff,capgrpMessage) +AddCaption(loc("Timed Kamikaze! +10 points!"),0xffba00ff,capgrpMessage) + +----------------- +capgrpMessage2 +----------------- +AddCaption(loc("Drone Hunter! +10 points!"),0xffba00ff,capgrpMessage2) +AddCaption(loc("Ammo Maniac! +5 points!"),0xffba00ff,capgrpMessage2) +AddCaption(loc("Shield Seeker! +10 points!"),0xffba00ff,capgrpMessage2) +AddCaption(loc("Boss Slayer! +25 points!"),0xffba00ff,capgrpMessage2) +]] + +---------------------------------- +-- so I herd u liek wariables +---------------------------------- + +--local fMod = 1 -- for use in .15 single player only, otherwise desync +local fMod = 1000000 -- use this for dev and .16+ games + +-- some console stuff +local shellID = 0 +local explosivesID = 0 +local luaGameTicks = 0 + +-- gaudyRacer +local roundLimit = 3 -- no longer set here (see version history) +local roundNumber = 0 +local firstClan = 10 +local gameOver = false +local gameBegun = false + +local bestClan = 10 +local bestScore = 0 +local sdScore = {} +local sdName = {} +local sdKills = {} + +-------------------------- +-- hog and team tracking variales +-------------------------- + +local numhhs = 0 +local hhs = {} + +local numTeams +local teamNameArr = {} +local teamClan = {} +local teamSize = {} +local teamIndex = {} + +local teamComment = {} +local teamScore = {} +local teamCircsKilled = {} + +-- stats variables +--local teamRed = {} +--local teamBlue = {} +--local teamOrange = {} +--local teamGreen = {} +local RK = 0 +local GK = 0 +local BK = 0 +local OK = 0 +local SK = 0 +local shieldMiser = true +local chainCounter = 0 +local chainLength = 0 +local shotsFired = 0 +local shotsHit = 0 + +--------------------- +-- tumbler goods +--------------------- + +local moveTimer = 0 +local leftOn = false +local rightOn = false +local upOn = false +local downOn = false + +local primShotsMax = 5 +local primShotsLeft = 0 + +local TimeLeftCounter = 0 +local TimeLeft = 0 +local stopMovement = false +local tumbleStarted = false + +local beam = false +local pShield +local shieldHealth + +local Timer100 = 0 + + +----------------------------------------------- +-- CIRCLY GOODIES +----------------------------------------------- + +local CirclesAreGo = false +local playerIsFine = true +local targetHit = false + +local FadeAlpha = 0 -- used to fade the circles out gracefully when player dies +local pTimer = 0 -- tracking projectiles following player + +local circAdjustTimer = 0 -- handle adjustment of circs direction +local m2Count = 0 -- handle speed of circs + +local vCirc = {} +local vCCount = 0 + +local vCircActive = {} +local vCircHealth = {} +local vType = {} +local vCounter = {} -- how often this circ gets to "fire" etc +local vCounterLim = {} -- when vCounter == vCounterLim circle performs its special +local vCircScore = {} -- how many points killing this invader gives + +local vCircRadMax = {} +local vCircRadMin = {} +local vCircRadDir = {} +local vCircRadCounter = {} + +local vCircDX = {} +local vCircDY = {} + +local vCircX = {} +local vCircY = {} +local vCircMinA = {} +local vCircMaxA = {} +local vCircType = {} +local vCircPulse = {} +local vCircFuckAll = {} +local vCircRadius = {} +local vCircWidth = {} +local vCircCol = {} + +------------------------------------------- +-- some lazy copypasta/modified methods +------------------------------------------- + +function RebuildTeamInfo() + + -- make a list of individual team names + for i = 0, (TeamsCount-1) do + teamNameArr[i] = " " -- = i + teamSize[i] = 0 + teamIndex[i] = 0 + teamScore[i] = 0 + teamCircsKilled[i] = 0 + end + numTeams = 0 + + for i = 0, (numhhs-1) do + + z = 0 + unfinished = true + while(unfinished == true) do + + newTeam = true + tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name + + if tempHogTeamName == teamNameArr[z] then + newTeam = false + unfinished = false + end + + z = z + 1 + + if z == (TeamsCount-1) then + unfinished = false + if newTeam == true then + teamNameArr[numTeams] = tempHogTeamName + numTeams = numTeams + 1 + end + end + + end + + end + + -- find out how many hogs per team, and the index of the first hog in hhs + for i = 0, (TeamsCount-1) do + + for z = 0, (numhhs-1) do + if GetHogTeamName(hhs[z]) == teamNameArr[i] then + teamClan[i] = GetHogClan(hhs[z]) + if teamSize[i] == 0 then + teamIndex[i] = z -- should give starting index + end + teamSize[i] = teamSize[i] + 1 + --add a pointer so this hog appears at i in hhs + end + end + + end + +end + +-- control +function AwardPoints(p) + + for i = 0,(TeamsCount-1) do + if teamClan[i] == GetHogClan(CurrentHedgehog) then + teamScore[i] = teamScore[i] + p + end + end + +end + +function AwardKills(t) + + for i = 0,(TeamsCount-1) do + if teamClan[i] == GetHogClan(CurrentHedgehog) then + teamCircsKilled[i] = teamCircsKilled[i] + 1 + + if teamCircsKilled[i] == 10 then + AddCaption(loc("Boom! +25 points!"),0xffba00ff,capgrpVolume) + AwardPoints(25) + elseif teamCircsKilled[i] == 25 then + AddCaption(loc("BOOM! +50 points!"),0xffba00ff,capgrpVolume) + AwardPoints(50) + elseif teamCircsKilled[i] == 50 then + AddCaption(loc("BOOM! BOOM! BOOM! +100 points!"),0xffba00ff,capgrpVolume) + AwardPoints(100) + end + + --[[ + if t == "R" then + redCircsKilled[i] = redCircsKilled[i] + 1 + end + --etc + --etc + ]] + end + end + +end + +----------------- + +function bubbleSort(table) + + for i = 1, #table do + for j = 2, #table do + if table[j] < table[j-1] then + + temp = table[j-1] + t2 = sdName[j-1] + t3 = sdKills[j-1] + + table[j-1] = table[j] + sdName[j-1] = sdName[j] + sdKills[j-1] = sdKills[j] + + table[j] = temp + sdName[j] = t2 + sdKills[j] = t3 + + end + end + end + + return + +end + +----------------- + +function CommentOnScore() + + for i = 0,(TeamsCount-1) do + sdScore[i] = teamScore[i] + sdKills[i] = teamCircsKilled[i] + sdName[i] = teamNameArr[i] + end + + --bubbleSort(sdScore) + + for i = 0,(TeamsCount-1) do + if sdName[i] ~= " " then + teamComment[i] = sdName[i] .. " |" .. + loc("SCORE: ") .. sdScore[i] .. loc (" points|") .. + loc("KILLS: ") .. sdKills[i] .. loc (" invaders destroyed|") .. + " " .. "|" + elseif sdName[i] == " " then + teamComment[i] = "|" + end + end + + entireC = "" + for i = (TeamsCount-1),0,-1 do + entireC = entireC .. teamComment[i] + end + + ShowMission(loc("SPACE INVASION"), loc("STATUS UPDATE"), loc("Rounds Complete: ") .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" .. loc("Team Scores: ") .. "|" ..entireC, 4, 1) + +end + +-- gaudy racer +function CheckForNewRound() + + if GetHogClan(CurrentHedgehog) == firstClan then + + roundNumber = roundNumber + 1 + + CommentOnScore() + + -- end game if its at round limit + if roundNumber == roundLimit then + + for i = 0, (TeamsCount-1) do + if teamScore[i] > bestScore then + bestScore = teamScore[i] + bestClan = teamClan[i] + end + end + + for i = 0, (numhhs-1) do + if GetHogClan(hhs[i]) ~= bestClan then + SetEffect(hhs[i], heResurrectable, false) + SetHealth(hhs[i],0) + end + end + gameOver = true + TurnTimeLeft = 0 --1 + TimeLeft = 0 + end + + end + +end + + +---------------------------------------- +-- some tumbler/space invaders methods +---------------------------------------- + +function isATrackedGear(gear) + if (GetGearType(gear) == gtExplosives) or + (GetGearType(gear) == gtShell) or + (GetGearType(gear) == gtFlame) or-- new -- gtBall + (GetGearType(gear) == gtBall) + then + return(true) + else + return(false) + end +end + +function setNewGearValues(gear) + + if GetGearType(gear) == gtShell then + lfs = 50 -- roughly 5 seconds + shellID = shellID + 1 + setGearValue(gear,"ID",shellID) + --nw WriteLnToConsole("Just assigned ID " .. getGearValue(gear,"ID") .. " to this shell") + elseif GetGearType(gear) == gtBall then + lfs = 70 -- 7s + elseif GetGearType(gear) == gtExplosives then + lfs = 15 -- 1.5s + explosivesID = explosivesID + 1 + setGearValue(gear,"ID",explosivesID) + --nw WriteLnToConsole("Just assigned ID " .. getGearValue(gear,"ID") .. " to this explosives") + elseif GetGearType(gear) == gtFlame then + lfs = 5 -- 0.5s + else + lfs = 100 + end + + setGearValue(gear,"lifespan",lfs) + --WriteLnToConsole("I also set its lifespan to " .. lfs) + + +end + +function HandleLifeSpan(gear) + + decreaseGearValue(gear,"lifespan") + + --WriteLnToConsole("Just decreased the lifespan of a gear to " .. getGearValue(gear,"lifespan")) + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + + if getGearValue(gear,"lifespan") == 0 then + + if GetGearType(gear) == gtShell then + AddVisualGear(GetX(gear), GetY(gear), vgtExplosion, 0, false) + WriteLnToConsole("about to delete a shell due to lifespan == 0") + --elseif GetGearType(gear) == gtBall then + -- AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, true) + elseif GetGearType(gear) == gtExplosives then + AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) + --nw WriteLnToConsole("about to delete a explosive due to lifespan == 0") + elseif GetGearType(gear) == gtFlame then + AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, false) + --WriteLnToConsole("about to delete flame due to lifespan == 0") + end + + DeleteGear(gear) + + end + +end + +-- this prevents ugly barrel clipping sounds when a barrel flies off map limits +function DeleteFarFlungBarrel(gear) + + if GetGearType(gear) == gtExplosives then + if (GetX(gear) < -1900) or + (GetX(gear) > 6200) or + (GetY(gear) < -3400) + then + AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) + DeleteGear(gear) + --SetHealth(gear, 0) + --WriteLnToConsole("I'm setting barrel ID " .. getGearValue(gear,"ID") .. " to 0 health because it's been flung too close to the map edges. at Game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + end + + end + +end + +----------------------- +--EVENT HANDLERS +-- action keys +----------------------- + +-- o rite dis wan iz liek synched n stuff hope full lee +function onPrecise() + + --WriteLnToConsole("onPrecise event handler at Game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + -- Fire Barrel + if (primShotsLeft > 0) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then + + shotsFired = shotsFired +1 + + morte = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtExplosives, 0, 0, 0, 1) + + primShotsLeft = primShotsLeft - 1 + + if primShotsLeft == 0 then + PlaySound(sndSuddenDeath) + AddCaption(loc("Ammo Depleted!"),0xff0000ff,capgrpMessage) + else + AddCaption(loc("Ammo: ") .. primShotsLeft) + end + + CopyPV(CurrentHedgehog, morte) -- new addition + x,y = GetGearVelocity(morte) + --WriteLnToConsole("I'm going to shoot a barrel so I just got the velocity of currenthedgehog. It is dx: " .. x .. "; dy: " .. y) + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + + + x = x*2 + y = y*2 + SetGearVelocity(morte, x, y) + + --WriteLnToConsole("I just SET the velocity of a barrel I created. It is now dx: " .. x .. "; dy: " .. y) + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + + + elseif (primShotsLeft == 0) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then + AddCaption(loc("Ammo Depleted!"),0xff0000ff,capgrpMessage) + end + + +end + +function onLJump() + + if (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then + shieldMiser = false + if shieldHealth == 80 then + AddCaption("Shield Depleted",0xff0000ff,capgrpMessage) + PlaySound(sndMineTick) + PlaySound(sndSwitchHog) + elseif (beam == false) and (shieldHealth > 80) then + beam = true + SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), 40, 255, 1, 10, 0, 300, 1, 0xa800ffff) + AddCaption( loc("Shield ON:") .. " " .. shieldHealth - 80 .. " " .. loc("Power Remaining") ) + PlaySound(sndWarp) + else + beam = false + SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), 0, 0, 1, 10, 0, 0, 0, 0xa800ffff) + AddCaption(loc("Shield OFF:") .. " " .. shieldHealth - 80 .. " " .. loc("Power Remaining") ) + end + end +end + +----------------- +-- movement keys +----------------- + +function onLeft() + leftOn = true +end + +function onRight() + rightOn = true +end + +function onUp() + upOn = true +end + +function onDown() + downOn = true +end + +function onDownUp() + downOn = false +end + +function onUpUp() + upOn = false +end + +function onLeftUp() + leftOn = false +end + +function onRightUp() + rightOn = false +end + +-------------------------- +-- other event handlers +-------------------------- + +function onGameInit() + GameFlags = 0 + gfRandomOrder + Theme = "EarthRise" + CaseFreq = 0 + HealthCaseProb = 0 + MinesNum = 0 + Explosives = 0 +end + +function onGameStart() + + if (MinesTime == -1000) or (MinesTime == 0) then + roundLimit = 3 + else + roundLimit = (MinesTime / 1000) + end + + ShowMission ( + loc("SPACE INVASION"), + loc("a Hedgewars mini-game"), + + loc("Destroy invaders to score points.") .. "|" .. + " " .. "|" .. + + loc("Round Limit:") .. " " .. roundLimit .. "|" .. + loc("Turn Time:") .. " " .. (TurnTime/1000) .. loc("s") .. "|" .. + " " .. "|" .. + + loc("Movement: [Up], [Down], [Left], [Right]") .. "|" .. + loc("Fire:") .. " " .. loc("[Left Shift]") .. "|" .. + loc("Toggle Shield:") .. " " .. loc("[Enter]") .. "|" .. + + --" " .. "|" .. + --loc("Invaders List: ") .. "|" .. + --loc("Blue Jabberwock: (50 points)") .. "|" .. + --loc("Red Warbler: (10 points)") .. "|" .. + --loc("Orange Gob: (5 points)") .. "|" .. + --loc("Green Wrangler: (3 points)") .. "|" .. + + + "", 4, 4000 + ) + + CreateMeSomeCircles() + RebuildTeamInfo() -- control + +end + + +function onNewTurn() + + primShotsLeft = primShotsMax + stopMovement = false + tumbleStarted = false + beam = false + shieldHealth = 30 + 80 -- 50 = 5 secs, roughly + + RK = 0 + GK = 0 + BK = 0 + OK = 0 + SK = 0 + shieldMiser = true + shotsFired = 0 + shotsHit = 0 + chainLength = 0 + chainCounter = 0 + + ------------------------- + -- gaudy racer + ------------------------- + CheckForNewRound() + + -- Handle Starting Stage of Game + if (gameOver == false) and (gameBegun == false) then + gameBegun = true + roundNumber = 0 -- 0 + firstClan = GetHogClan(CurrentHedgehog) + end + + if gameOver == true then + gameBegun = false + stopMovement = true + tumbleStarted = false + SetMyCircles(false) + end + --------------- + --------------- + --AddCaption("num g: " .. numGears() ) + + --WriteLnToConsole("onNewTurn, I just set a bunch of variables to their necessary states. This was done at:") + --WriteLnToConsole("The above occured at Game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + +end + +function ThingsToBeRunOnGears(gear) + + HandleLifeSpan(gear) + DeleteFarFlungBarrel(gear) + + if CirclesAreGo == true then + CheckVarious(gear) + ProjectileTrack(gear) + end + +end + + +function onGameTick() + + + --WriteLnToConsole("Start of GameTick") + luaGameTicks = luaGameTicks + 1 -- GameTime + + HandleCircles() + + Timer100 = Timer100 + 1 + if Timer100 >= 100 then + Timer100 = 0 + + if beam == true then + shieldHealth = shieldHealth - 1 + if shieldHealth <= 80 then + shieldHealth = 80 + beam = false + AddCaption(loc("Shield Depleted"),0xff0000ff,capgrpMessage) + PlaySound(sndMineTick) + PlaySound(sndSwitchHog) + end + end + + + --nw WriteLnToConsole("Starting ThingsToBeRunOnGears()") + + runOnGears(ThingsToBeRunOnGears) + + --nw WriteLnToConsole("Finished ThingsToBeRunOnGears()") + + --runOnGears(HandleLifeSpan) + --runOnGears(DeleteFarFlungBarrel) + + if CirclesAreGo == true then + CheckDistances() + --runOnGears(CheckVarious) -- used to be in handletracking for some bizarre reason + --runOnGears(ProjectileTrack) + end + + -- white smoke trail as player falls from the sky + if (TimeLeft <= 0) and (stopMovement == true) and (CurrentHedgehog ~= nil) then + j,k = GetGearVelocity(CurrentHedgehog) + if (j ~= 0) and (k ~= 0) then + AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmoke, 0, true) + end + end + + --nw WriteLnToConsole("Finished 100Timer") + + end + + + -- start the player tumbling with a boom once their turn has actually begun + if (tumbleStarted == false) and (gameOver == false) then + if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then + --AddCaption(loc("Good to go!")) + tumbleStarted = true + TimeLeft = (TurnTime/1000) --45 + FadeAlpha = 0 + AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1) + SetMyCircles(true) + end + end + + --WriteLnToConsole("Finished initial check") + + if (CurrentHedgehog ~= nil) and (tumbleStarted == true) then + + --AddCaption(GetX(CurrentHedgehog) .. ";" .. GetY(CurrentHedgehog) ) + + -- Calculate and display turn time + TimeLeftCounter = TimeLeftCounter + 1 + if TimeLeftCounter == 1000 then + TimeLeftCounter = 0 + TimeLeft = TimeLeft - 1 + + if TimeLeft >= 0 then + --AddCaption(loc("Time Left: ") .. TimeLeft) + end + + end + + --WriteLnToConsole("Finished timeleft calculations") + + ------------------------------- + -- Player has run out of luck (out of time or hit by gtShell) + ------------------------------- + -- checks in FloatyThings + if PlayerIsFine() == false then + TimeLeft = 0 + end + + --WriteLnToConsole("successfully checked playerIsFine") + + if (TimeLeft == 0) then + if (stopMovement == false) then --time to stop the player + stopMovement = true + beam = false + upOn = false + down = false + leftOn = false + rightOn = false + SetMyCircles(false) + --nw WriteLnToConsole("Player is out of luck") + + if shieldMiser == true then + AddCaption(loc("Shield Miser! +20 points!"),0xffba00ff,capgrpAmmoinfo) + AwardPoints(20) + end + + if ((shotsHit / shotsFired * 100) >= 80) and (shotsFired > 4) then + AddCaption(loc("Accuracy Bonus! +15 points!"),0xffba00ff,capgrpVolume) + AwardPoints(15) + end + + end + else -- remove this if you want tumbler to fall slowly on death + ------------------------------- + -- Player is still in luck + ------------------------------- + + + --WriteLnToConsole("about to do chainCounter checks") + if chainCounter > 0 then + chainCounter = chainCounter -1 + if chainCounter == 0 then + chainLength = 0 + end + end + + -- handle movement based on IO + moveTimer = moveTimer + 1 + if moveTimer == 100 then -- 100 + --nw WriteLnToConsole("Start of Player MoveTimer") + moveTimer = 0 + + --------------- + -- new trail code + --------------- + -- the trail lets you know you have 5s left to pilot, akin to birdy feathers + if (TimeLeft <= 5) and (TimeLeft > 0) then --vgtSmoke + tempE = AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmoke, 0, true) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) + SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, GetClanColor(GetHogClan(CurrentHedgehog)) ) + end + -------------- + -------------- + + dx, dy = GetGearVelocity(CurrentHedgehog) + + --WriteLnToConsole("I just got the velocity of currenthedgehog. It is dx: " .. dx .. "; dy: " .. dy) + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + + dxlimit = 0.4*fMod + dylimit = 0.4*fMod + + if dx > dxlimit then + dx = dxlimit + end + if dy > dylimit then + dy = dylimit + end + if dx < -dxlimit then + dx = -dxlimit + end + if dy < -dylimit then + dy = -dylimit + end + + + if leftOn == true then + dx = dx - 0.1*fMod + end + if rightOn == true then + dx = dx + 0.1*fMod + end + + if upOn == true then + dy = dy - 0.1*fMod + end + if downOn == true then + dy = dy + 0.1*fMod + end + + SetGearVelocity(CurrentHedgehog, dx, dy) + + --WriteLnToConsole("I just SET the velocity of currenthedgehog. It is now dx: " .. dx .. "; dy: " .. dy) + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + --nw WriteLnToConsole("End of Player MoveTimer") + + end + + end -- new end I put here to check if he's still alive or not + + end + + --WriteLnToConsole("End of GameTick") + +end + +function onGearResurrect(gear) + + -- did I fall into the water? well, that was a stupid thing to do + if gear == CurrentHedgehog then + TimeLeft = 0 + --WriteLnToConsole("Current hedgehog just drowned himself") + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + end + +end + +function onGearAdd(gear) + + if isATrackedGear(gear) then + trackGear(gear) + setNewGearValues(gear) + end + + --if GetGearType(gear) == gtBall then + -- SetTimer(gear, 5000) + --end + + if GetGearType(gear) == gtHedgehog then + SetEffect(gear, heResurrectable, true) + + ----------- + -- control + hhs[numhhs] = gear + numhhs = numhhs + 1 + ----------- + end + +end + +function onGearDelete(gear) + + if GetGearType(gear) == gtShell then + --nw WriteLnToConsole("on GearDelete call. Shell ID: " .. getGearValue(gear,"ID")) + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + --if CurrentHedgehog ~= nil then + -- WriteLnToConsole("As it happens, player is at: " .. GetX(CurrentHedgehog) .. "; " .. GetY(CurrentHedgehog)) + --end + elseif GetGearType(gear) == gtExplosives then + --nw WriteLnToConsole("on GearDelete call. Explosives ID: " .. getGearValue(gear,"ID")) + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + --if CurrentHedgehog ~= nil then + -- WriteLnToConsole("As it happens, player is at: " .. GetX(CurrentHedgehog) .. "; " .. GetY(CurrentHedgehog)) + --end + elseif GetGearType(gear) == gtFlame then + --WriteLnToConsole("on GearDelete flame") + end + + + + + + if isATrackedGear(gear) then + trackDeletion(gear) + end + + if CurrentHedgehog ~= nil then + FollowGear(CurrentHedgehog) + end + +end + + + +------------------------------------------------------------ +------------------------------------------------------------ +------------------------------------------------------------ +------------------------------------------------------------ +-- FLOATY THINGS +-- "I'll make this into a generic library and code properly +-- when I have more time and feel less lazy" +------------------------------------------------------------ +------------------------------------------------------------ +------------------------------------------------------------ +------------------------------------------------------------ + + + + +function PlayerIsFine() + return (playerIsFine) +end + +function GetDistFromGearToGear(gear, gear2) + + g1X, g1Y = GetGearPosition(gear) + g2X, g2Y = GetGearPosition(gear2) + q = g1X - g2X + w = g1Y - g2Y + + + --[[ + WriteLnToConsole("I just got the position of two gears and calculated the distance betwen them") + if gear == CurrentHedgehog then + WriteLnToConsole("Gear 1 is CurrentHedgehog.") + end + if gear2 == CurrentHedgehog then + WriteLnToConsole("Gear 2 is CurrentHedgehog.") + end + WriteLnToConsole("G1X: " .. g1X .. "; G1Y: " .. g1Y) + WriteLnToConsole("G2X: " .. g2X .. "; G2Y: " .. g2Y) + WriteLnToConsole("Their distance is " .. (q*q) + (w*w) ) + WriteLnToConsole("The above events occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) +]] + + + return ( (q*q) + (w*w) ) + +end + +function GetDistFromGearToXY(gear, g2X, g2Y) + + g1X, g1Y = GetGearPosition(gear) + q = g1X - g2X + w = g1Y - g2Y + + + --[[WriteLnToConsole("I just got the position of a gear and calculated the distance betwen it and another xy") + if gear == CurrentHedgehog then + WriteLnToConsole("Gear 1 is CurrentHedgehog.") + end + + WriteLnToConsole("G1X: " .. g1X .. "; G1Y: " .. g1Y) + WriteLnToConsole("Other X: " .. g2X .. "; Other Y: " .. g2Y) + WriteLnToConsole("Their distance is " .. (q*q) + (w*w) ) + WriteLnToConsole("The above events occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) +]] + + + return ( (q*q) + (w*w) ) + + +end + +function CreateMeSomeCircles() + + for i = 0, 7 do + vCCount = vCCount +1 + vCirc[i] = AddVisualGear(0,0,vgtCircle,0,true) + + vCircDX[i] = 0 + vCircDY[i] = 0 + + vType[i] = "generic" + vCounter[i] = 0 + vCounterLim[i] = 3000 + vCircScore[i] = 0 + vCircHealth[i] = 1 + + vCircMinA[i] = 80 --80 --20 + vCircMaxA[i] = 255 + vCircType[i] = 1 --1 + vCircPulse[i] = 10 + vCircFuckAll[i] = 0 + vCircRadius[i] = 0 + vCircWidth[i] = 3 --5 + + vCircRadMax[i] = 0 + vCircRadMin[i] = 0 + vCircRadDir[i] = -1 + vCircRadCounter[i] = 0 + + vCircX[i], vCircY[i] = 0,0 + + vCircCol[i] = 0xff00ffff + + SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], vCircMinA[i], vCircMaxA[i], vCircType[i], vCircPulse[i], vCircFuckAll[i], vCircRadius[i], vCircWidth[i], vCircCol[i]) + end + + pShield = AddVisualGear(0,0,vgtCircle,0,true) + --SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), 80, 200, 1, 10, 0, 200, 5, 0xff00ffff) + + +end + +function IGotMeASafeXYValue(i) + + acceptibleDistance = 800 + + -- put this in here to thwart attempts at repositioning and test sanity limit + --vCircX[i] = GetX(CurrentHedgehog)+250 + --vCircY[i] = GetY(CurrentHedgehog)+250 + + vCircX[i] = GetRandom(5000) + vCircY[i] = GetRandom(2000) + dist = GetDistFromGearToXY(CurrentHedgehog, vCircX[i], vCircY[i]) + if dist > acceptibleDistance*acceptibleDistance then + return(true) + else + return(false) + end + +end + +function CircleDamaged(i) + + res = "" + vCircHealth[i] = vCircHealth[i] -1 + + if vCircHealth[i] <= 0 then + -- circle is dead, do death effects/consequences + + vCircActive[i] = false + + if (vType[i] == "drone") then + PlaySound(sndHellishImpact4) + TimeLeft = TimeLeft + 4 + AddCaption(loc("Time Extended!") .. "+" .. 4 .. loc("s"), 0xff0000ff,capgrpMessage ) + + morte = AddGear(vCircX[i], vCircY[i], gtExplosives, 0, 0, 0, 1) + SetHealth(morte, 0) + + RK = RK + 1 + if RK == 5 then + RK = 0 + AddCaption(loc("Drone Hunter! +10 points!"),0xffba00ff,capgrpMessage2) + AwardPoints(10) + end + + elseif (vType[i] == "ammo") then + AddVisualGear(vCircX[i], vCircY[i], vgtExplosion, 0, false) + PlaySound(sndExplosion) + PlaySound(sndShotgunReload) + primShotsLeft = primShotsLeft + 3 + AddCaption("+" .. 3 .. " " .. loc("Ammo"), 0x00ff00ff,capgrpMessage) + + GK = GK + 1 + if GK == 3 then + GK = 0 + AddCaption(loc("Ammo Maniac! +5 points!"),0xffba00ff,capgrpMessage2) + AwardPoints(5) + end + + elseif (vType[i] == "bonus") then + + AddVisualGear(vCircX[i], vCircY[i], vgtExplosion, 0, false) + PlaySound(sndExplosion) + + AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false) + AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false) + AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false) + AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false) + AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false) + AddVisualGear(vCircX[i], vCircY[i], vgtSmoke, 0, false) + + PlaySound(sndVaporize) + --sndWarp sndMineTick --sndSwitchHog --sndSuddenDeath + + shieldHealth = shieldHealth + 30 + AddCaption(loc("Shield boosted! +30 power"), 0xa800ffff,capgrpMessage) + if shieldHealth >= 250 then + shieldHealth = 250 + AddCaption(loc("Shield is fully recharged!"),0xa800ffff,capgrpMessage) + end + + OK = OK + 1 + if OK == 3 then + OK = 0 + AddCaption(loc("Shield Seeker! + 10 points!"),0xffba00ff,capgrpMessage2) + AwardPoints(10) + end + + elseif (vType[i] == "blueboss") then + PlaySound(sndHellishImpact3) + AddCaption(loc("Boss defeated! +50 points!"), 0x0050ffff,capgrpMessage) + + morte = AddGear(vCircX[i], vCircY[i], gtExplosives, 0, 0, 0, 1) + SetHealth(morte, 0) + + BK = BK + 1 + if BK == 2 then + BK = 0 + AddCaption(loc("Boss Slayer! +25 points!"),0xffba00ff,capgrpMessage2) + AwardPoints(25) + end + + end + + AwardPoints(vCircScore[i]) + AwardKills() + SetUpCircle(i) + res = "fatal" + + chainCounter = 3000 + chainLength = chainLength + 1 + if chainLength > 1 then + AddCaption( chainLength .. loc("-Hit Combo! +") .. chainLength*2 .. loc(" points!"),0xffba00ff,capgrpAmmostate) + AwardPoints(chainLength*2) + end + + else + -- circle is merely damaged + -- do damage effects/sounds + AddVisualGear(vCircX[i], vCircY[i], vgtSteam, 0, false) + r = GetRandom(4) + if r == 0 then + PlaySound(sndHellishImpact1) + elseif r == 1 then + PlaySound(sndHellishImpact2) + elseif r == 2 then + PlaySound(sndHellishImpact3) + elseif r == 3 then + PlaySound(sndHellishImpact4) + end + res = "non-fatal" + + end + + return(res) + +end + +function SetUpCircle(i) + + + r = GetRandom(10) + --r = 8 + -- 80% of spawning either red/green + if r <= 7 then + + --r = GetRandom(5) + r = GetRandom(2) + --r = 1 + if r == 0 then + --if r <= 2 then + vCircCol[i] = 0xff0000ff -- red + vType[i] = "drone" + vCircRadMin[i] = 50 *5 + vCircRadMax[i] = 90 *5 + vCounterLim[i] = 3000 + vCircScore[i] = 10 + vCircHealth[i] = 1 + --else + elseif r == 1 then + vCircCol[i] = 0x00ff00ff -- green + vType[i] = "ammo" + vCircRadMin[i] = 25 *7 + vCircRadMax[i] = 30 *7 + vCircScore[i] = 3 + vCircHealth[i] = 1 + end + + -- 20% chance of spawning boss or bonus + else + r = GetRandom(5) + --r = GetRandom(2) + --r = 0 + if r <= 1 then + --if r == 0 then + vCircCol[i] = 0x0050ffff -- sexy blue + vType[i] = "blueboss" + vCircRadMin[i] = 100*5 + vCircRadMax[i] = 180*5 + vCircWidth[i] = 1 + vCounterLim[i] = 2000 + vCircScore[i] = 50 + vCircHealth[i] = 3 + else + --elseif r == 1 then + --vCircCol[i] = 0xffae00ff -- orange + vCircCol[i] = 0xa800ffff -- purp + vType[i] = "bonus" + vCircRadMin[i] = 20 *7 + vCircRadMax[i] = 40 *7 + vCircScore[i] = 5 + vCircHealth[i] = 1 + end + + end + + -- regenerate circle xy if too close to player or until sanity limit kicks in + reN = 0 + --zzz = 0 + while (reN < 10) do + if IGotMeASafeXYValue(i) == false then + reN = reN + 1 + --zzz = zzz + 1 + else + reN = 15 + end + end + --AddCaption("Took me this many retries: " .. zzz) -- number of times it took to work + + vCircRadius[i] = vCircRadMax[i] - GetRandom(vCircRadMin[i]) + + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i]) + SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], g3, g4, g5, g6, g7, vCircRadius[i], vCircWidth[i], vCircCol[i]-0x000000ff) + -- - -0x000000ff + vCircActive[i] = true -- new + + --nw WriteLnToConsole("CIRC " .. i .. ": X: " .. vCircX[i] .. "; Y: " .. vCircY[i]) + --nw WriteLnToConsole("CIRC " .. i .. ": dX: " .. vCircDX[i] .. "; dY: " .. vCircDY[i]) + --nw WriteLnToConsole("CIRC " .. i .. ": RAD:" .. vCircRadius[i]) + +end + +function SetMyCircles(s) + + CirclesAreGo = s + playerIsFine = s + + if s == true then + --nw WriteLnToConsole("About to set up all circles, old values are here:") + for i = 0,(vCCount-1) do + --nw WriteLnToConsole("CIRC " .. i .. ": X: " .. vCircX[i] .. "; Y: " .. vCircY[i]) + --nw WriteLnToConsole("CIRC " .. i .. ": dX: " .. vCircDX[i] .. "; dY: " .. vCircDY[i]) + --nw WriteLnToConsole("CIRC " .. i .. ": RAD:" .. vCircRadius[i]) + end + --nw WriteLnToConsole("Old values given, new values to follow...") + end + + for i = 0,(vCCount-1) do + + if s == false then + --vCircCol[i] = 0xffffffff + vCircActive[i] = false + elseif s == true then + SetUpCircle(i) + end + + end + +end + +function WellHeAintGonnaJumpNoMore(x,y) + + AddVisualGear(x, y, vgtBigExplosion, 0, false) + playerIsFine = false + AddCaption(loc("GOTCHA!")) + PlaySound(sndExplosion) + PlaySound(sndHellish) + + targetHit = true + +end + +--- collision detection for weapons fire +function CheckVarious(gear) + + --if (GetGearType(gear) == gtExplosives) then + --nw WriteLnToConsole("Start of CheckVarious(): Exp ID: " .. getGearValue(gear,"ID")) + --elseif (GetGearType(gear) == gtShell) then + --nw WriteLnToConsole("Start of CheckVarious(): Shell ID: " .. getGearValue(gear,"ID")) + --end + + + + + targetHit = false + + -- if circle is hit by player fire + if (GetGearType(gear) == gtExplosives) then + circsHit = 0 + + for i = 0,(vCCount-1) do + + --nw WriteLnToConsole("Is it neccessary to check for collision with circ " .. i) + + --if (vCircActive[i] == true) and ( (vType[i] == "drone") ) then + + --nw WriteLnToConsole("YES. about to calc distance between gtExplosives and circ " .. i) + + dist = GetDistFromGearToXY(gear, vCircX[i], vCircY[i]) + + -- calculate my real radius if I am an aura + if vCircType[i] == 0 then + NR = vCircRadius[i] + else + NR = (48/100*vCircRadius[i])/2 + end + + if dist <= NR*NR then + + --nw WriteLnToConsole("Collision confirmed. The gtExplosives is within the circ radius!") + + --SetGearPosition(gear, vCircX[i], vCircY[i]) + --WriteLnToConsole("set the gtExplosives to be in the center of circ") + AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) + + targetHit = true + --DeleteGear(gear) + --SetHealth(gear,0) + --WriteLnToConsole("set " .. "Exp ID: " .. getGearValue(gear,"ID") .. " health to 0") + --WriteLnToConsole("targetHit set to true, explosive is at distance " .. dist .. "(within range " .. NR*NR.. ") of circ" ) + + CircleDamaged(i) + + circsHit = circsHit + 1 + if circsHit > 1 then + AddCaption(loc("Multi-shot! +5 points!"),0xffba00ff,capgrpAmmostate) + end + + shotsHit = shotsHit + 1 + + end + + --end + + end + + -- if player is hit by circle bazooka + elseif (GetGearType(gear) == gtShell) or (GetGearType(gear) == gtBall) then + + dist = GetDistFromGearToGear(gear, CurrentHedgehog) + + if beam == true then + + if dist < 3000 then + tempE = AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, true) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) + SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, 0xff00ffff ) + PlaySound(sndVaporize) + DeleteGear(gear) + + SK = SK + 1 + if SK == 5 then + SK = 0 + AddCaption(loc("Shield Master! +10 points!"),0xffba00ff,capgrpAmmoinfo) + AwardPoints(10) + end + end + + elseif dist < 1600 then + WellHeAintGonnaJumpNoMore(GetX(gear), GetY(gear)) + end + + --[[if targetHit == true then + WriteLnToConsole("about to delete shell due to targetHit being set to true earlier") + DeleteGear(gear) + WriteLnToConsole("there, I deleted it") + end]] + + + end + + if targetHit == true then + --nw WriteLnToConsole("about to delete something due to targetHit being set to true earlier") + DeleteGear(gear) + --nw WriteLnToConsole("there, I deleted it") + end + + --nw WriteLnToConsole("End of CheckVarious()") + +end + +-- collision detection for player entering a circle +function CheckDistances() + + --nw WriteLnToConsole("Start of CheckDistances()") + + for i = 0,(vCCount-1) do + + + --nw WriteLnToConsole("Attempting to calculate dist of circ " .. i) + + g1X, g1Y = GetGearPosition(CurrentHedgehog) + g2X, g2Y = vCircX[i], vCircY[i] + + g1X = g1X - g2X + g1Y = g1Y - g2Y + dist = (g1X*g1X) + (g1Y*g1Y) + + --nw WriteLnToConsole("Calcs done. Dist to CurrentHedgehog is " .. dist) + + -- calculate my real radius if I am an aura + if vCircType[i] == 0 then + NR = vCircRadius[i] + else + NR = (48/100*vCircRadius[i])/2 + end + + if dist <= NR*NR then + + if (vCircActive[i] == true) and + ((vType[i] == "ammo") or (vType[i] == "bonus") ) + then + + CircleDamaged(i) + + elseif (vCircActive[i] == true) and + ( (vType[i] == "drone") or (vType[i] == "blueboss") ) + then + + ss = CircleDamaged(i) + WellHeAintGonnaJumpNoMore(GetX(CurrentHedgehog),GetY(CurrentHedgehog)) + + if ss == "fatal" then + if (primShotsLeft == 0) and (TimeLeft <= 9) then + AddCaption(loc("Kamikaze Expert! +15 points!"),0xffba00ff,capgrpMessage) + AwardPoints(15) + elseif (primShotsLeft == 0) then + AddCaption(loc("Depleted Kamikaze! +5 points!"),0xffba00ff,capgrpMessage) + AwardPoints(5) + elseif TimeLeft <= 9 then + AddCaption(loc("Timed Kamikaze! +10 points!"),0xffba00ff,capgrpMessage) + AwardPoints(10) + end + end + + end + + + end + + end + + --nw WriteLnToConsole("End of CheckDistances()") + +end + +function HandleCircles() + + + --[[if CirclesAreGo == true then + + --CheckDistances() + --runOnGears(CheckVarious) -- used to be in handletracking for some bizarre reason + + --pTimer = pTimer + 1 + --if pTimer == 100 then + -- pTimer = 0 + -- runOnGears(ProjectileTrack) + --end + + end]] + + for i = 0,(vCCount-1) do + + vCounter[i] = vCounter[i] + 1 + if vCounter[i] >= vCounterLim[i] then + + vCounter[i] = 0 + + if ((vType[i] == "drone") or (vType[i] == "blueboss") ) and + (vCircActive[i] == true) then + AddGear(vCircX[i], vCircY[i], gtShell, 0, 0, 0, 1) + + --WriteLnToConsole("Circle " .. i .. " just fired/added a gtShell") + --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + + --elseif (vType[i] == "bluebottle") and (vCircActive[i] == true) then + -- AddGear(vCircX[i], vCircY[i]-vCircRadius[i], gtBall, 0, 0, 0, 1) + -- AddGear(vCircX[i], vCircY[i]+vCircRadius[i], gtBall, 0, 0, 0, 1) + -- AddGear(vCircX[i]-vCircRadius[i], vCircY[i], gtBall, 0, 0, 0, 1) + -- AddGear(vCircX[i]+vCircRadius[i], vCircY[i], gtBall, 0, 0, 0, 1) + end + + end + + if (vCircActive[i] == true) then + + vCircRadCounter[i] = vCircRadCounter[i] + 1 + if vCircRadCounter[i] == 100 then + + vCircRadCounter[i] = 0 + + -- make my radius increase/decrease faster if I am an aura + if vCircType[i] == 0 then + M = 1 + else + M = 10 + end + + vCircRadius[i] = vCircRadius[i] + vCircRadDir[i] + if vCircRadius[i] > vCircRadMax[i] then + vCircRadDir[i] = -M + elseif vCircRadius[i] < vCircRadMin[i] then + vCircRadDir[i] = M + end + + + -- random effect test + -- maybe use this to tell the difference between circs + -- you can kill by shooting or not + --vgtSmoke vgtSmokeWhite + --vgtSteam -- nice long trail + --vgtDust -- short trail on earthrise + --vgtSmokeTrace + if vType[i] == "ammo" then + + tempE = AddVisualGear(vCircX[i], vCircY[i], vgtSmoke, 0, true) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff + SetVisualGearValues(tempE, vCircX[i], vCircY[i], g3, g4, g5, g6, g7, g8, g9, vCircCol[i] ) + + --AddVisualGear(vCircX[i], vCircY[i], vgtDust, 0, true) + + elseif vType[i] == "bonus" then + + tempE = AddVisualGear(vCircX[i], vCircY[i], vgtDust, 0, true) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff --vCircCol[i] + SetVisualGearValues(tempE, vCircX[i], vCircY[i], g3, g4, g5, g6, g7, 1, g9, 0xff00ffff ) + + + elseif vType[i] == "blueboss" then + + k = 25 + g = vgtSteam + trailColour = 0xae00ffff + + -- 0xffae00ff -- orange + -- 0xae00ffff -- purp + + tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff + SetVisualGearValues(tempE, vCircX[i], vCircY[i]+k, g3, g4, g5, g6, g7, g8, g9, trailColour-75 ) + + tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff + SetVisualGearValues(tempE, vCircX[i]+k, vCircY[i]-k, g3, g4, g5, g6, g7, g8, g9, trailColour-75 ) + + tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff + SetVisualGearValues(tempE, vCircX[i]-k, vCircY[i]-k, g3, g4, g5, g6, g7, g8, g9, trailColour-75 ) + + + end + + + end + + end + + + end + + -- alter the circles velocities + circAdjustTimer = circAdjustTimer + 1 + if circAdjustTimer == 2000 then + + circAdjustTimer = 0 + + for i = 0,(vCCount-1) do + + -- bounce the circles off the edges if they go too far + -- or make them move in random directions + + if vCircX[i] > 5500 then + vCircDX[i] = -5 --5 circmovchange + elseif vCircX[i] < -1500 then + vCircDX[i] = 5 --5 circmovchange + else + + z = GetRandom(2) + if z == 1 then + z = 1 + else + z = -1 + end + vCircDX[i] = vCircDX[i] + GetRandom(3)*z --3 circmovchange + end + + if vCircY[i] > 1500 then + vCircDY[i] = -5 --5 circmovchange + elseif vCircY[i] < -2900 then + vCircDY[i] = 5 --5 circmovchange + else + z = GetRandom(2) + if z == 1 then + z = 1 + else + z = -1 + end + vCircDY[i] = vCircDY[i] + GetRandom(3)*z --3 circmovchange + end + + end + + end + + -- move the circles according to their current velocities + m2Count = m2Count + 1 + if m2Count == 25 then --25 circmovchange + + m2Count = 0 + for i = 0,(vCCount-1) do + vCircX[i] = vCircX[i] + vCircDX[i] + vCircY[i] = vCircY[i] + vCircDY[i] + end + + if (TimeLeft == 0) and (tumbleStarted == true) then + + FadeAlpha = FadeAlpha + 1 + if FadeAlpha >= 255 then + FadeAlpha = 255 + end + + --new + --if FadeAlpha == 1 then + -- AddCaption("GOT IT") + -- for i = 0,(vCCount-1) do + -- g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i]) + -- vCircCol[i] = g10 + -- end + --end + + end + + end + + for i = 0,(vCCount-1) do + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i]) -- vCircCol[i] g10 + SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], g3, g4, g5, g6, g7, vCircRadius[i], g9, g10) + end + + if (TimeLeft == 0) or + ((tumbleStarted == false)) then + for i = 0,(vCCount-1) do + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i]) -- vCircCol[i] g10 + SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], g3, g4, g5, g6, g7, vCircRadius[i], g9, (vCircCol[i]-FadeAlpha)) + end + end + + + if (CurrentHedgehog ~= nil) and (beam == true) then + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(pShield) + --SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, 200, g9, g10 ) + SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, 200, g9, 0xa800ffff-0x000000ff - -shieldHealth ) + else + SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, 0, g9, g10 ) + end + +end + +function ProjectileTrack(gear) + + if (GetGearType(gear) == gtShell) then + + --nw WriteLnToConsole("ProjectileTrack() for Shell ID: " .. getGearValue(gear,"ID")) + + -- newnew + if (GetGearType(gear) == gtShell) then + turningSpeed = 0.1*fMod + --elseif (GetGearType(gear) == gtBall) then + -- turningSpeed = 0.2*fMod + end + + dx, dy = GetGearVelocity(gear) + + --WriteLnToConsole("I'm trying to track currenthedge with shell ID: " .. getGearValue(gear,"ID")) + --WriteLnToConsole("I just got the velocity of the shell. It is dx: " .. dx .. "; dy: " .. dy) + --WriteLnToConsole("CurrentHedgehog is at X: " .. GetX(CurrentHedgehog) .. "; Y: " .. GetY(CurrentHedgehog) ) + + if GetX(gear) > GetX(CurrentHedgehog) then + dx = dx - turningSpeed--0.1 + else + dx = dx + turningSpeed--0.1 + end + + if GetY(gear) > GetY(CurrentHedgehog) then + dy = dy - turningSpeed--0.1 + else + dy = dy + turningSpeed--0.1 + end + + + if (GetGearType(gear) == gtShell) then + dxlimit = 0.4*fMod + dylimit = 0.4*fMod + --elseif (GetGearType(gear) == gtBall) then + -- dxlimit = 0.5 -- 0.5 is about the same + -- dylimit = 0.5 -- 0.6 is faster than player + end + + if dx > dxlimit then + dx = dxlimit + end + if dy > dylimit then + dy = dylimit + end + if dx < -dxlimit then + dx = -dxlimit + end + if dy < -dylimit then + dy = -dylimit + end + + SetGearVelocity(gear, dx, dy) + + --WriteLnToConsole("I just SET the velocity of shell towards currenthegdge. It is now dx: " .. dx .. "; dy: " .. dy) + --WriteLnToConsole("The above events occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks) + --nw WriteLnToConsole("ProjectileTrack() finished successfully") + + end + +end + diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua Thu Jun 23 21:19:43 2011 +0400 @@ -0,0 +1,256 @@ +---------------------------------- +-- THE SPECIALISTS MODE 0.2 +-- by mikade +---------------------------------- + +-- version history +----------------- +-- version 0.1 +----------------- +-- concept test + +---------------- +-- version 0.2 +---------------- +-- added gfRandomOrder to gameflags +-- removed some deprecated variables/methods +-- fixed lack of portal reset + +-------------------- +--TO DO +-------------------- + +-- add proper gameflag checking, maybe +-- set crate drops etc. +-- assuming place hog mode + gfinfattack doesn't get the fix: somehow end turn after teleport + +loadfile(GetDataPath() .. "Scripts/Locale.lua")() + +local numhhs = 0 +local hhs = {} + +local currName +local lastName + +function CreateTeam() + + currTeam = "" + lastTeam = "" + z = 0 + + for i = 0, (numhhs-1) do + + currTeam = GetHogTeamName(hhs[i]) + + if currTeam == lastTeam then + z = z + 1 + else + z = 1 + end + + if z == 1 then + + SetHogName(hhs[i],"Soldier") + SetHogHat(hhs[i], "Vega") + SetHealth(hhs[i],200) + + elseif z == 2 then + + SetHogHat(hhs[i], "Glasses") + SetHogName(hhs[i],"Engineer") + + elseif z == 3 then + + SetHogName(hhs[i],"Ninja") + SetHogHat(hhs[i], "NinjaFull") + SetHealth(hhs[i],80) + + elseif z == 4 then + + SetHogName(hhs[i],"Demo") + SetHogHat(hhs[i], "Skull") + SetHealth(hhs[i],200) + + elseif z == 5 then + + SetHogName(hhs[i],"Sniper") + SetHogHat(hhs[i], "Sniper") + SetHealth(hhs[i],120) + + elseif z == 6 then + + SetHogName(hhs[i],"Saint") + SetHogHat(hhs[i], "angel") + SetHealth(hhs[i],300) + + elseif z == 7 then + + SetHogName(hhs[i],"Pyro") + SetHogHat(hhs[i], "Gasmask") + SetHealth(hhs[i],150) + + elseif z == 8 then + + SetHogName(hhs[i],"Loon") + SetHogHat(hhs[i], "clown") + SetHealth(hhs[i],100) + + end + + lastTeam = GetHogTeamName(hhs[i]) + + end + +end + +function ResetAllAmmo() + + AddAmmo(CurrentHedgehog, amBazooka, 0) + AddAmmo(CurrentHedgehog, amGrenade, 0) + AddAmmo(CurrentHedgehog, amShotgun, 0) + + AddAmmo(CurrentHedgehog, amGirder, 0) + AddAmmo(CurrentHedgehog, amBlowTorch, 0) + AddAmmo(CurrentHedgehog, amPickHammer, 0) + AddAmmo(CurrentHedgehog, amSwitch, 0) + + AddAmmo(CurrentHedgehog, amRope, 0) + AddAmmo(CurrentHedgehog, amParachute, 0) + AddAmmo(CurrentHedgehog, amFirePunch, 0) + + AddAmmo(CurrentHedgehog, amDynamite, 0) + AddAmmo(CurrentHedgehog, amDrill, 0) + AddAmmo(CurrentHedgehog, amMine, 0) + + AddAmmo(CurrentHedgehog, amSniperRifle, 0) + AddAmmo(CurrentHedgehog, amDEagle, 0) + AddAmmo(CurrentHedgehog, amPortalGun, 0) + + AddAmmo(CurrentHedgehog, amSeduction, 0) + AddAmmo(CurrentHedgehog, amResurrector, 0) + AddAmmo(CurrentHedgehog, amInvulnerable, 0) + + AddAmmo(CurrentHedgehog, amFlamethrower, 0) + AddAmmo(CurrentHedgehog, amMolotov, 0) + AddAmmo(CurrentHedgehog, amNapalm, 0) + + AddAmmo(CurrentHedgehog, amBaseballBat, 0) + AddAmmo(CurrentHedgehog, amGasBomb, 0) + AddAmmo(CurrentHedgehog, amKamikaze, 0) + +end + +function AssignAmmo() + + ResetAllAmmo() + n = GetHogName(CurrentHedgehog) + + AddAmmo(CurrentHedgehog, amSkip,100) + + if n == "Soldier" then + AddAmmo(CurrentHedgehog, amBazooka,1) + AddAmmo(CurrentHedgehog, amGrenade,1) + AddAmmo(CurrentHedgehog, amShotgun,1) + elseif n == "Engineer" then + AddAmmo(CurrentHedgehog, amGirder, 2) + AddAmmo(CurrentHedgehog, amBlowTorch, 1) + AddAmmo(CurrentHedgehog, amPickHammer, 1) + AddAmmo(CurrentHedgehog, amSwitch, 2) + elseif n == "Ninja" then + AddAmmo(CurrentHedgehog, amRope, 100) + AddAmmo(CurrentHedgehog, amParachute, 100) + AddAmmo(CurrentHedgehog, amFirePunch, 1) + elseif n == "Demo" then + AddAmmo(CurrentHedgehog, amDynamite, 1) + AddAmmo(CurrentHedgehog, amMine, 1) + AddAmmo(CurrentHedgehog, amDrill, 1) + elseif n == "Sniper" then + AddAmmo(CurrentHedgehog, amSniperRifle, 1) + AddAmmo(CurrentHedgehog, amDEagle, 1) + AddAmmo(CurrentHedgehog, amPortalGun, 2) + elseif n == "Saint" then + AddAmmo(CurrentHedgehog, amSeduction, 100) + AddAmmo(CurrentHedgehog, amResurrector, 1) + AddAmmo(CurrentHedgehog, amInvulnerable, 1) + elseif n == "Pyro" then + AddAmmo(CurrentHedgehog, amFlamethrower, 1) + AddAmmo(CurrentHedgehog, amMolotov, 1) + AddAmmo(CurrentHedgehog, amNapalm, 1) + elseif n == "Loon" then + AddAmmo(CurrentHedgehog, amBaseballBat, 1) + AddAmmo(CurrentHedgehog, amGasBomb, 1) + AddAmmo(CurrentHedgehog, amKamikaze, 1) + end + +end + +function onGameInit() + GameFlags = gfRandomOrder + gfResetWeps + gfInfAttack + gfPlaceHog + Delay = 10 +end + +function onGameStart() + + CreateTeam() + + ShowMission ( + loc("THE SPECIALISTS"), + loc("a Hedgewars mini-game"), + + loc("Eliminate the enemy specialists.") .. "|" .. + " " .. "|" .. + + loc("Game Modifiers: ") .. "|" .. + loc("Per-Hog Ammo") .. "|" .. + loc("Weapons Reset") .. "|" .. + loc("Unlimited Attacks") .. "|" .. + + "", 4, 4000 + ) + +end + + +function onNewTurn() + currName = GetHogName(CurrentHedgehog) + lastName = GetHogName(CurrentHedgehog) + AssignAmmo() + AddAmmo(CurrentHedgehog, amSwitch, 1) +end + +function onGameTick() + + if (CurrentHedgehog ~= nil) then + + currName = GetHogName(CurrentHedgehog) + + if currName ~= lastName then + AddCaption(loc("Switched to ") .. currName .. "!") + AssignAmmo() + end + + lastName = currName + + end + +end + +function onGearAdd(gear) + + if GetGearType(gear) == gtHedgehog then + hhs[numhhs] = gear + numhhs = numhhs + 1 + end + +end + +function onGearDelete(gear) +-- +end + +function onAmmoStoreInit() + +end + + + diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Art/Clouds.png Binary file share/hedgewars/Data/Themes/Art/Clouds.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Art/Flake.png Binary file share/hedgewars/Data/Themes/Art/Flake.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Bamboo/SkyL.png Binary file share/hedgewars/Data/Themes/Bamboo/SkyL.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Bamboo/SkyR.png Binary file share/hedgewars/Data/Themes/Bamboo/SkyR.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/Flake.png Binary file share/hedgewars/Data/Themes/Blox/Flake.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/Sky.png Binary file share/hedgewars/Data/Themes/Blox/Sky.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/icon.png Binary file share/hedgewars/Data/Themes/Blox/icon.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/icon@2x.png Binary file share/hedgewars/Data/Themes/Blox/icon@2x.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/plant1.png Binary file share/hedgewars/Data/Themes/Blox/plant1.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/plant2.png Binary file share/hedgewars/Data/Themes/Blox/plant2.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/plant3.png Binary file share/hedgewars/Data/Themes/Blox/plant3.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/plant4.png Binary file share/hedgewars/Data/Themes/Blox/plant4.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Blox/tmp.png Binary file share/hedgewars/Data/Themes/Blox/tmp.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/CMakeLists.txt --- a/share/hedgewars/Data/Themes/CMakeLists.txt Tue Jun 21 16:43:05 2011 +0400 +++ b/share/hedgewars/Data/Themes/CMakeLists.txt Thu Jun 23 21:19:43 2011 +0400 @@ -30,5 +30,3 @@ ) add_subdirectory(${dir}) endforeach(dir) - -install(FILES themes.cfg DESTINATION ${SHAREPATH}Data/Themes) diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Cake/Clouds.png Binary file share/hedgewars/Data/Themes/Cake/Clouds.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Cake/icon.png Binary file share/hedgewars/Data/Themes/Cake/icon.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Cake/icon@2x.png Binary file share/hedgewars/Data/Themes/Cake/icon@2x.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Cake/plant4.png Binary file share/hedgewars/Data/Themes/Cake/plant4.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Cake/theme.cfg --- a/share/hedgewars/Data/Themes/Cake/theme.cfg Tue Jun 21 16:43:05 2011 +0400 +++ b/share/hedgewars/Data/Themes/Cake/theme.cfg Thu Jun 23 21:19:43 2011 +0400 @@ -8,5 +8,4 @@ object = plant1, 3, 83, 215, 92, 35, 1, 0, 0, 250, 190 object = plant2, 3, 118, 115, 41, 20, 1, 0, 0, 159, 110 object = plant3, 3, 0, 115, 70, 40, 1, 8, 0, 60, 100 -object = plant4, 3, 20, 200, 25, 5, 1, 0, 0, 70, 150 flakes = 20, 100, 0, 30, 250 diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Cheese/Flake.png Binary file share/hedgewars/Data/Themes/Cheese/Flake.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/CrazyMission/Flake.png Binary file share/hedgewars/Data/Themes/CrazyMission/Flake.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/CrazyMission/horizont.png Binary file share/hedgewars/Data/Themes/CrazyMission/horizont.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Deepspace/Clouds.png Binary file share/hedgewars/Data/Themes/Deepspace/Clouds.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Deepspace/horizont.png Binary file share/hedgewars/Data/Themes/Deepspace/horizont.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/EarthRise/Clouds.png Binary file share/hedgewars/Data/Themes/EarthRise/Clouds.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/EarthRise/horizontL.png Binary file share/hedgewars/Data/Themes/EarthRise/horizontL.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/EarthRise/horizontR.png Binary file share/hedgewars/Data/Themes/EarthRise/horizontR.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Halloween/SkyL.png Binary file share/hedgewars/Data/Themes/Halloween/SkyL.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Halloween/SkyR.png Binary file share/hedgewars/Data/Themes/Halloween/SkyR.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Jungle/SkyL.png Binary file share/hedgewars/Data/Themes/Jungle/SkyL.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Jungle/SkyR.png Binary file share/hedgewars/Data/Themes/Jungle/SkyR.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/Planes/Flake.png Binary file share/hedgewars/Data/Themes/Planes/Flake.png has changed diff -r bf6d4bc531d2 -r 67278f1cba2c share/hedgewars/Data/Themes/themes.cfg --- a/share/hedgewars/Data/Themes/themes.cfg Tue Jun 21 16:43:05 2011 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -Art -Bamboo -Bath -Brick -Castle -Cheese -Christmas -City -Compost -Desert -EarthRise -Freeway -Halloween -Hell -Island -Jungle -Nature -Olympics -Sheep -Snow -Stage -Underwater diff -r bf6d4bc531d2 -r 67278f1cba2c share/hwico.icns Binary file share/hwico.icns has changed