# HG changeset patch # User unc0rr # Date 1423340774 -10800 # Node ID 48a53259fad892cac38f93e8f23c42483338494d # Parent f71275973737672bccf9971de9b4aeec487372b1# Parent 37410518628e541b25918ed8c80933b6b28005cb merge with default diff -r f71275973737 -r 48a53259fad8 .travis.yml --- a/.travis.yml Mon Feb 02 23:12:56 2015 +0300 +++ b/.travis.yml Sat Feb 07 23:26:14 2015 +0300 @@ -11,13 +11,13 @@ # Debug build - BUILD_ARGS="-DCMAKE_BUILD_TYPE=Debug" # Everything that's optional + - BUILD_ARGS="-DBUILD_ENGINE_C=1" - BUILD_ARGS="-DNOPNG=1" - BUILD_ARGS="-DNOVIDEOREC=1" - BUILD_ARGS="-DNOSERVER=1" - BUILD_ARGS="-DLUA_SYSTEM=0" - BUILD_ARGS="-DPHYSFS_SYSTEM=0" - BUILD_ARGS="-DGL2=1" - - BUILD_ARGS="-DBUILD_ENGINE_C=1" matrix: allow_failures: # Failures we expect here @@ -27,10 +27,12 @@ script: - mkdir build && cd build && cmake $BUILD_ARGS .. && make VERBOSE=1 && make test_verbose notifications: + email: false irc: channels: - "chat.freenode.net#hedgewars" template: - "hw-build #%{build_number} (%{commit} by %{author}): %{message}" - "See details at %{build_url}" - email: false + on_success: change + on_failure: always diff -r f71275973737 -r 48a53259fad8 CMakeLists.txt --- a/CMakeLists.txt Mon Feb 02 23:12:56 2015 +0300 +++ b/CMakeLists.txt Sat Feb 07 23:26:14 2015 +0300 @@ -51,8 +51,8 @@ #versioning set(CPACK_PACKAGE_VERSION_MAJOR 0) set(CPACK_PACKAGE_VERSION_MINOR 9) -set(CPACK_PACKAGE_VERSION_PATCH 21) -set(HEDGEWARS_PROTO_VER 48) +set(CPACK_PACKAGE_VERSION_PATCH 22) +set(HEDGEWARS_PROTO_VER 50) set(HEDGEWARS_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") include(${CMAKE_MODULE_PATH}/revinfo.cmake) @@ -70,12 +70,13 @@ if(CMAKE_BUILD_TYPE) string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) if(NOT((CMAKE_BUILD_TYPE MATCHES "RELEASE") OR - (CMAKE_BUILD_TYPE MATCHES "DEBUG"))) - set(CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Build type (Debug/Release)" FORCE) - message(STATUS "Unknown build type, using default (${default_build_type})") + (CMAKE_BUILD_TYPE MATCHES "DEBUG") OR + (CMAKE_BUILD_TYPE MATCHES "RELWITHDEBINFO"))) + set(CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Build type (Debug/Release/RelWithDebInfo)" FORCE) + message(STATUS "Unknown build type ${CMAKE_BUILD_TYPE}, using default (${default_build_type})") endif() else(CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Build type (Debug/Release)" FORCE) + set(CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Build type (Debug/Release/RelWithDebInfo)" FORCE) endif(CMAKE_BUILD_TYPE) @@ -232,7 +233,7 @@ enable_testing() -add_custom_target(test COMMAND ${CMAKE_CTEST_COMMAND} -E '^todo/' --timeout 300 --schedule-random) +add_custom_target(test_normal COMMAND ${CMAKE_CTEST_COMMAND} -E '^todo/' --timeout 300 --schedule-random) add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} -E '^todo/' --timeout 300 --schedule-random -V) set(LUATESTS_DIR "${CMAKE_SOURCE_DIR}/tests/lua") diff -r f71275973737 -r 48a53259fad8 QTfrontend/CMakeLists.txt --- a/QTfrontend/CMakeLists.txt Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/CMakeLists.txt Sat Feb 07 23:26:14 2015 +0300 @@ -190,9 +190,9 @@ #when debugging, always prompt a console to see fronted messages #TODO: check it doesn't interfere on UNIX -if(CMAKE_BUILD_TYPE MATCHES "RELEASE") +if(CMAKE_BUILD_TYPE MATCHES "RELEASE" OR CMAKE_BUILD_TYPE MATCHES "RELWITHDEBINFO") set(console_access "WIN32") -endif(CMAKE_BUILD_TYPE MATCHES "RELEASE") +endif(CMAKE_BUILD_TYPE MATCHES "RELEASE" OR CMAKE_BUILD_TYPE MATCHES "RELWITHDEBINFO") add_executable(hedgewars ${console_access} ${hwfr_src} diff -r f71275973737 -r 48a53259fad8 QTfrontend/hedgewars.qrc --- a/QTfrontend/hedgewars.qrc Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/hedgewars.qrc Sat Feb 07 23:26:14 2015 +0300 @@ -124,7 +124,11 @@ res/iconHealth.png res/iconSuddenDeath.png res/iconDamage.png + res/iconDamageLockG.png + res/iconDamageLockR.png res/iconTime.png + res/iconTimeLockG.png + res/iconTimeLockR.png res/iconMine.png res/iconDud.png res/iconRope.png diff -r f71275973737 -r 48a53259fad8 QTfrontend/hwform.cpp --- a/QTfrontend/hwform.cpp Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/hwform.cpp Sat Feb 07 23:26:14 2015 +0300 @@ -1839,7 +1839,7 @@ ui.pageNetGame->setRoomName(hwnet->getRoom()); ui.pageNetGame->pGameCFG->GameSchemes->view()->disconnect(hwnet); - connect(hwnet, SIGNAL(netSchemeConfig(QStringList &)), + connect(hwnet, SIGNAL(netSchemeConfig(QStringList)), this, SLOT(selectFirstNetScheme())); } diff -r f71275973737 -r 48a53259fad8 QTfrontend/model/ammoSchemeModel.cpp diff -r f71275973737 -r 48a53259fad8 QTfrontend/model/ammoSchemeModel.h diff -r f71275973737 -r 48a53259fad8 QTfrontend/model/playerslistmodel.cpp --- a/QTfrontend/model/playerslistmodel.cpp Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/model/playerslistmodel.cpp Sat Feb 07 23:26:14 2015 +0300 @@ -237,6 +237,7 @@ << index.data(InGame).toBool() << index.data(RoomFilterRole).toBool() << index.data(InRoom).toBool() + << index.data(Contributor).toBool() ; for(int i = flags.size() - 1; i >= 0; --i) diff -r f71275973737 -r 48a53259fad8 QTfrontend/model/playerslistmodel.h --- a/QTfrontend/model/playerslistmodel.h Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/model/playerslistmodel.h Sat Feb 07 23:26:14 2015 +0300 @@ -23,6 +23,8 @@ InGame = Qt::UserRole + 6, InRoom = Qt::UserRole + 7, Contributor = Qt::UserRole + 8 + // if you add a role that will affect the player icon, + // then also add it to the flags Qlist in updateIcon()! }; enum SpecialRoles { diff -r f71275973737 -r 48a53259fad8 QTfrontend/model/roomslistmodel.cpp --- a/QTfrontend/model/roomslistmodel.cpp Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/model/roomslistmodel.cpp Sat Feb 07 23:26:14 2015 +0300 @@ -108,22 +108,38 @@ if (role == Qt::DecorationRole) { const QIcon roomBusyIcon(":/res/iconDamage.png"); + const QIcon roomBusyIconGreen(":/res/iconDamageLockG.png"); + const QIcon roomBusyIconRed(":/res/iconDamageLockR.png"); const QIcon roomWaitingIcon(":/res/iconTime.png"); + const QIcon roomWaitingIconGreen(":/res/iconTimeLockG.png"); + const QIcon roomWaitingIconRed(":/res/iconTimeLockR.png"); + + QString flags = m_data.at(row).at(StateColumn); - if (m_data.at(row).at(0).isEmpty()) - return QVariant(roomWaitingIcon); + if (flags.contains("g")) + { + if (flags.contains("j")) + return QVariant(roomBusyIconRed); + else if (flags.contains("p")) + return QVariant(roomBusyIconGreen); + else + return QVariant(roomBusyIcon); + } else - return QVariant(roomBusyIcon); + { + if (flags.contains("j")) + return QVariant(roomWaitingIconRed); + else if (flags.contains("p")) + return QVariant(roomWaitingIconGreen); + else + return QVariant(roomWaitingIcon); + } } QString content = m_data.at(row).at(column); if (role == Qt::DisplayRole) { - // supply in progress flag as bool - if (column == 0) - return QVariant(QString(!content.isEmpty())); - // display room names if (column == 5) { @@ -190,7 +206,7 @@ l.append(rooms[i + t]); } - m_data.append(roomInfo2RoomRecord(l)); + m_data.append(l); } endResetModel(); @@ -201,7 +217,7 @@ { beginInsertRows(QModelIndex(), 0, 0); - m_data.prepend(roomInfo2RoomRecord(info)); + m_data.prepend(info); endInsertRows(); } @@ -250,25 +266,7 @@ if (i < 0) return; - m_data[i] = roomInfo2RoomRecord(info); + m_data[i] = info; emit dataChanged(index(i, 0), index(i, columnCount(QModelIndex()) - 1)); } - - -QStringList RoomsListModel::roomInfo2RoomRecord(const QStringList & info) -{ - QStringList result; - - result = info; - - QString flags = info[StateColumn]; - // for matters of less memory usage and quicker access store - // the boolean string as either "t" or empty - if (flags.contains('g')) - result[StateColumn] = "t"; - else - result[StateColumn] = QString(); - - return result; -} diff -r f71275973737 -r 48a53259fad8 QTfrontend/model/roomslistmodel.h --- a/QTfrontend/model/roomslistmodel.h Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/model/roomslistmodel.h Sat Feb 07 23:26:14 2015 +0300 @@ -66,8 +66,6 @@ QStringList m_headerData; MapModel * m_staticMapModel; MapModel * m_missionMapModel; - - QStringList roomInfo2RoomRecord(const QStringList & info); }; #endif // HEDGEWARS_ROOMSLISTMODEL_H diff -r f71275973737 -r 48a53259fad8 QTfrontend/net/newnetclient.h diff -r f71275973737 -r 48a53259fad8 QTfrontend/res/html/about.html --- a/QTfrontend/res/html/about.html Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/res/html/about.html Sat Feb 07 23:26:14 2015 +0300 @@ -76,7 +76,7 @@ French: Antoine Turmel <geekshadow@gmail.com>, Clement Woitrain <sphrixclement@gmail.com>, Matisumi
German: Peter Hüwe <PeterHuewe@gmx.de>, Mario Liebisch <mario.liebisch@gmail.com>, Richard Karolyi <sheepluva@ercatec.net>, Wuzzy <almikes@aol.com>
Greek: <talos_kriti@yahoo.gr>
- Italian: Luca Bonora <bonora.luca@gmail.com>, Marco Bresciani <m.bresciani@email.it>
+ Italian: Luca Bonora <bonora.luca@gmail.com>, Marco Bresciani <m.bresciani@email.it>, Gianfranco Costamagna <costamagnagianfranco@yahoo.it>
Japanese: ADAM Etienne <etienne.adam@gmail.com>, Marco Bresciani <m.bresciani@email.it>
Korean: Anthony Bellew <anthonyreflected@gmail.com>
Lithuanian: Lukas Urbonas <lukasu08@gmail.com>
diff -r f71275973737 -r 48a53259fad8 QTfrontend/res/iconDamageLockG.png Binary file QTfrontend/res/iconDamageLockG.png has changed diff -r f71275973737 -r 48a53259fad8 QTfrontend/res/iconDamageLockR.png Binary file QTfrontend/res/iconDamageLockR.png has changed diff -r f71275973737 -r 48a53259fad8 QTfrontend/res/iconTimeLockG.png Binary file QTfrontend/res/iconTimeLockG.png has changed diff -r f71275973737 -r 48a53259fad8 QTfrontend/res/iconTimeLockR.png Binary file QTfrontend/res/iconTimeLockR.png has changed diff -r f71275973737 -r 48a53259fad8 QTfrontend/res/locks.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/res/locks.svg Sat Feb 07 23:26:14 2015 +0300 @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Open and closed lock + 2013-11-07T10:50:32 + Set of 2 locks, one opened and one closed. + https://openclipart.org/detail/188421/open-and-closed-lock-by-iyo-188421 + + + Iyo + + + + + closed + lock + locks + open + pic + pictogram + sign + + + + + + + + + + + diff -r f71275973737 -r 48a53259fad8 QTfrontend/ui/page/pageroomslist.cpp --- a/QTfrontend/ui/page/pageroomslist.cpp Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/ui/page/pageroomslist.cpp Sat Feb 07 23:26:14 2015 +0300 @@ -77,8 +77,16 @@ showGamesInProgress = new QAction(QAction::tr("Show games in-progress"), stateMenu); showGamesInProgress->setCheckable(true); showGamesInProgress->setChecked(true); + showPassword = new QAction(QAction::tr("Show password protected"), stateMenu); + showPassword->setCheckable(true); + showPassword->setChecked(true); + showJoinRestricted = new QAction(QAction::tr("Show join restricted"), stateMenu); + showJoinRestricted->setCheckable(true); + showJoinRestricted->setChecked(true); stateMenu->addAction(showGamesInLobby); stateMenu->addAction(showGamesInProgress); + stateMenu->addAction(showPassword); + stateMenu->addAction(showJoinRestricted); btnState->setMenu(stateMenu); // Help/prompt message at top @@ -186,6 +194,8 @@ connect(roomsList, SIGNAL(clicked (const QModelIndex &)), searchText, SLOT(setFocus())); connect(showGamesInLobby, SIGNAL(triggered()), this, SLOT(onFilterChanged())); connect(showGamesInProgress, SIGNAL(triggered()), this, SLOT(onFilterChanged())); + connect(showPassword, SIGNAL(triggered()), this, SLOT(onFilterChanged())); + connect(showJoinRestricted, SIGNAL(triggered()), this, SLOT(onFilterChanged())); connect(searchText, SIGNAL(textChanged (const QString &)), this, SLOT(onFilterChanged())); connect(this, SIGNAL(askJoinConfirmation (const QString &)), this, SLOT(onJoinConfirmation(const QString &)), Qt::QueuedConnection); @@ -630,13 +640,29 @@ bool stateLobby = showGamesInLobby->isChecked(); bool stateProgress = showGamesInProgress->isChecked(); + bool statePassword = showPassword->isChecked(); + bool stateJoinRestricted = showJoinRestricted->isChecked(); - if (stateLobby && stateProgress) - stateFilteredModel->setFilterFixedString(QString()); // "any" - else if (stateLobby != stateProgress) - stateFilteredModel->setFilterFixedString(QString(stateProgress)); + QString filter; + if (!stateLobby && !stateProgress) + filter = "O_o"; + else if (stateLobby && stateProgress && statePassword && stateJoinRestricted) + filter = ""; else - stateFilteredModel->setFilterFixedString(QString("none")); // Basically, none. + { + QString exclude = "[^"; + if (!stateProgress) exclude += "g"; + if (!statePassword) exclude += "p"; + if (!stateJoinRestricted) exclude += "j"; + exclude += "]*"; + if (stateProgress && statePassword && stateJoinRestricted) exclude = ".*"; + filter = "^" + exclude; + if (!stateLobby) filter += "g" + exclude; + filter += "$"; + } + //qDebug() << filter; + + stateFilteredModel->setFilterRegExp(filter); } void PageRoomsList::setSettings(QSettings *settings) diff -r f71275973737 -r 48a53259fad8 QTfrontend/ui/page/pageroomslist.h --- a/QTfrontend/ui/page/pageroomslist.h Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/ui/page/pageroomslist.h Sat Feb 07 23:26:14 2015 +0300 @@ -96,6 +96,8 @@ QSortFilterProxyModel * stateFilteredModel; QAction * showGamesInLobby; QAction * showGamesInProgress; + QAction * showPassword; + QAction * showJoinRestricted; QSplitter * m_splitter; AmmoSchemeModel * ammoSchemeModel; diff -r f71275973737 -r 48a53259fad8 QTfrontend/ui/widget/feedbackdialog.cpp --- a/QTfrontend/ui/widget/feedbackdialog.cpp Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/ui/widget/feedbackdialog.cpp Sat Feb 07 23:26:14 2015 +0300 @@ -268,7 +268,7 @@ number_of_cores += QString::number(sysconf(_SC_NPROCESSORS_ONLN)) + "\n"; quint32 pages = sysconf(_SC_PHYS_PAGES); quint32 page_size = sysconf(_SC_PAGE_SIZE); - quint32 total = pages * page_size / 1024 / 1024; + quint64 total = (quint64)pages * page_size / 1024 / 1024; total_ram += QString::number(total) + " MB\n"; os_version += "GNU/Linux or BSD\n"; #endif diff -r f71275973737 -r 48a53259fad8 QTfrontend/weapons.h --- a/QTfrontend/weapons.h Mon Feb 02 23:12:56 2015 +0300 +++ b/QTfrontend/weapons.h Sat Feb 07 23:26:14 2015 +0300 @@ -22,60 +22,60 @@ //structure------------------------------------------------------------------| -#define AMMOLINE_DEFAULT_QT "93919294221991210322351110012000000002111001010111110001" -#define AMMOLINE_DEFAULT_PROB "04050405416006555465544647765766666661555101011154111111" -#define AMMOLINE_DEFAULT_DELAY "00000000000002055000000400070040000000002200000006000200" -#define AMMOLINE_DEFAULT_CRATE "13111103121111111231141111111111111112111111011111111111" +#define AMMOLINE_DEFAULT_QT "939192942219912103223511100120000000021110010101111100010" +#define AMMOLINE_DEFAULT_PROB "040504054160065554655446477657666666615551010111541111111" +#define AMMOLINE_DEFAULT_DELAY "000000000000020550000004000700400000000022000000060002000" +#define AMMOLINE_DEFAULT_CRATE "131111031211111112311411111111111111121111110111111111111" -#define AMMOLINE_CRAZY_QT "99999999999999999929999999999999992999999999099999929991" -#define AMMOLINE_CRAZY_PROB "11111101111111111111111111111111111111111111011111111111" -#define AMMOLINE_CRAZY_DELAY "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_CRAZY_CRATE "13111103121111111231141111111111111112111101011111111111" +#define AMMOLINE_CRAZY_QT "999999999999999999299999999999999929999999990999999299919" +#define AMMOLINE_CRAZY_PROB "111111011111111111111111111111111111111111110111111111111" +#define AMMOLINE_CRAZY_DELAY "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_CRAZY_CRATE "131111031211111112311411111111111111121111010111111111111" -#define AMMOLINE_PROMODE_QT "90900090000000000000090000000000000000000000000000000000" -#define AMMOLINE_PROMODE_PROB "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_PROMODE_DELAY "00000000000002055000000400070040000000002000000000000200" -#define AMMOLINE_PROMODE_CRATE "11111101111111111111111111111111111111111001011111111111" +#define AMMOLINE_PROMODE_QT "909000900000000000000900000000000000000000000000000000000" +#define AMMOLINE_PROMODE_PROB "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_PROMODE_DELAY "000000000000020550000004000700400000000020000000000002000" +#define AMMOLINE_PROMODE_CRATE "111111011111111111111111111111111111111110010111111111111" -#define AMMOLINE_SHOPPA_QT "00000099000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPA_PROB "44444100442444022101121212224220000000020004000100110010" -#define AMMOLINE_SHOPPA_DELAY "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPA_CRATE "11111101111111111111111111111111111111111011011111111110" +#define AMMOLINE_SHOPPA_QT "000000990000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPA_PROB "444441004424440221011212122242200000000200040001001100101" +#define AMMOLINE_SHOPPA_DELAY "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPA_CRATE "111111011111111111111111111111111111111110110111111111101" -#define AMMOLINE_CLEAN_QT "10100090000100000110000000000000000000000000000010000000" -#define AMMOLINE_CLEAN_PROB "04050405416006555465544647765766666661555101011154111211" -#define AMMOLINE_CLEAN_DELAY "00000000000000000000000000000000000000000000000000000200" -#define AMMOLINE_CLEAN_CRATE "13111103121111111231141111111111111112111111011111111111" +#define AMMOLINE_CLEAN_QT "101000900001000001100000000000000000000000000000100000000" +#define AMMOLINE_CLEAN_PROB "040504054160065554655446477657666666615551010111541112111" +#define AMMOLINE_CLEAN_DELAY "000000000000000000000000000000000000000000000000000002000" +#define AMMOLINE_CLEAN_CRATE "131111031211111112311411111111111111121111110111111111111" -#define AMMOLINE_MINES_QT "00000099000900000003000000000000000000000000000000000000" -#define AMMOLINE_MINES_PROB "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_MINES_DELAY "00000000000002055000000400070040000000002000000006000200" -#define AMMOLINE_MINES_CRATE "11111101111111111111111111111111111111111111011111111111" +#define AMMOLINE_MINES_QT "000000990009000000030000000000000000000000000000000000000" +#define AMMOLINE_MINES_PROB "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_MINES_DELAY "000000000000020550000004000700400000000020000000060002000" +#define AMMOLINE_MINES_CRATE "111111011111111111111111111111111111111111110111111111111" -#define AMMOLINE_PORTALS_QT "90000090020000000021000000000000001100000900000000000000" -#define AMMOLINE_PORTALS_PROB "04050405416006555465544647765766666661555101011154111211" -#define AMMOLINE_PORTALS_DELAY "00000000000002055000000400070040000000002000000006000200" -#define AMMOLINE_PORTALS_CRATE "13111103121111111231141111111111111112111111011111111111" +#define AMMOLINE_PORTALS_QT "900000900200000000210000000000000011000009000000000000000" +#define AMMOLINE_PORTALS_PROB "040504054160065554655446477657666666615551010111541112111" +#define AMMOLINE_PORTALS_DELAY "000000000000020550000004000700400000000020000000060002000" +#define AMMOLINE_PORTALS_CRATE "131111031211111112311411111111111111121111110111111111111" -#define AMMOLINE_ONEEVERY_QT "11111191111111111111111111111111111111111111111111111111" -#define AMMOLINE_ONEEVERY_PROB "11111101111111111111111111111111111111111111111111111111" -#define AMMOLINE_ONEEVERY_DELAY "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_ONEEVERY_CRATE "11111101111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_QT "111111911111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_PROB "111111011111111111111111111111111111111111111111111111111" +#define AMMOLINE_ONEEVERY_DELAY "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_ONEEVERY_CRATE "111111011111111111111111111111111111111111111111111111111" -#define AMMOLINE_HIGHLANDER_QT "11111191111111111111019111111111100101111101111011001101" -#define AMMOLINE_HIGHLANDER_PROB "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_HIGHLANDER_DELAY "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_HIGHLANDER_CRATE "00000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HIGHLANDER_QT "111111911111111111110191111111111001011111011110110011010" +#define AMMOLINE_HIGHLANDER_PROB "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HIGHLANDER_DELAY "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_HIGHLANDER_CRATE "000000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_CONSTRUCTION_QT "11000190000000100100000000000000000000000000000000000000" -#define AMMOLINE_CONSTRUCTION_PROB "11111101111111111111111111111111111111111111111111111111" -#define AMMOLINE_CONSTRUCTION_DELAY "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_CONSTRUCTION_CRATE "11111101111111111111111111111111111111111111111111111111" +#define AMMOLINE_CONSTRUCTION_QT "110001900000001001000000000000000000000000000000000000000" +#define AMMOLINE_CONSTRUCTION_PROB "111111011111111111111111111111111111111111111111111111110" +#define AMMOLINE_CONSTRUCTION_DELAY "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_CONSTRUCTION_CRATE "111111011111111111111111111111111111111111111111111111110" -#define AMMOLINE_SHOPPAPRO_QT "00000099000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPAPRO_PROB "44444000440444000000000000004000000000000000000000000000" -#define AMMOLINE_SHOPPAPRO_DELAY "00000000000000000000000000000000000000000000000000000000" -#define AMMOLINE_SHOPPAPRO_CRATE "11111101111111111111111111111111111111111011011111111211" +#define AMMOLINE_SHOPPAPRO_QT "000000990000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPAPRO_PROB "444440004404440000000000000040000000000000000000000000000" +#define AMMOLINE_SHOPPAPRO_DELAY "000000000000000000000000000000000000000000000000000000000" +#define AMMOLINE_SHOPPAPRO_CRATE "111111011111111111111111111111111111111110110111111112110" //When adding new weapons also insert one element in cDefaultAmmos list (hwconsts.cpp.in) diff -r f71275973737 -r 48a53259fad8 cmake_modules/FindLua.cmake --- a/cmake_modules/FindLua.cmake Mon Feb 02 23:12:56 2015 +0300 +++ b/cmake_modules/FindLua.cmake Sat Feb 07 23:26:14 2015 +0300 @@ -17,7 +17,7 @@ find_path(LUA_INCLUDE_DIR lua.h PATHS /usr/include /usr/local/include /usr/pkg/include - PATH_SUFFIXES lua5.1 lua51) + PATH_SUFFIXES lua5.1 lua51 lua-5.1) find_library(LUA_LIBRARY NAMES lua51 lua5.1 lua-5.1 lua PATHS /lib /usr/lib /usr/local/lib /usr/pkg/lib) diff -r f71275973737 -r 48a53259fad8 cmake_modules/compilerchecks.cmake --- a/cmake_modules/compilerchecks.cmake Mon Feb 02 23:12:56 2015 +0300 +++ b/cmake_modules/compilerchecks.cmake Sat Feb 07 23:26:14 2015 +0300 @@ -62,7 +62,7 @@ endif() endif() - if(CMAKE_BUILD_TYPE MATCHES "RELEASE") + if(CMAKE_BUILD_TYPE MATCHES "RELEASE" OR CMAKE_BUILD_TYPE MATCHES "RELWITHDEBINFO") set(CMAKE_REQUIRED_FLAGS "-Wl,--as-needed") check_c_compiler_flag("" HAVE_ASNEEDED) if(HAVE_ASNEEDED) diff -r f71275973737 -r 48a53259fad8 gameServer/Actions.hs --- a/gameServer/Actions.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/gameServer/Actions.hs Sat Feb 07 23:26:14 2015 +0300 @@ -356,6 +356,9 @@ ) joinedMidGame ) ri + rteams <- io $ room'sM rnc (L.nub . rejoinedTeams . fromJust . gameInfo) ri + mapM_ (processAction . RemoveTeam) rteams + mapM_ processAction $ ( SaveReplay : ModifyRoom @@ -425,6 +428,15 @@ mapM_ processAction removeTeamActions +processAction SetRandomSeed = do + ri <- clientRoomA + thisRoomChans <- liftM (map sendChan) $ roomClientsS ri + seed <- liftM showB $ io $ (randomRIO (0, 10^9) :: IO Int) + mapM_ processAction [ + ModifyRoom (\r -> r{mapParams = Map.insert "SEED" seed $ mapParams r}) + , AnswerClients thisRoomChans ["CFG", "SEED", seed] + ] + processAction CheckRegistered = do (Just ci) <- gets clientIndex diff -r f71275973737 -r 48a53259fad8 gameServer/CoreTypes.hs --- a/gameServer/CoreTypes.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/gameServer/CoreTypes.hs Sat Feb 07 23:26:14 2015 +0300 @@ -101,6 +101,7 @@ | LoadRoom B.ByteString | ReactCmd [B.ByteString] | CheckVotes + | SetRandomSeed data Event = LobbyChatMessage @@ -110,7 +111,7 @@ type EventsInfo = [(Int, UTCTime)] newEventsInfo :: EventsInfo -newEventsInfo = [] +newEventsInfo = [] type ClientChan = Chan [B.ByteString] @@ -185,6 +186,7 @@ roundMsgs :: [B.ByteString], lastFilteredTimedMsg :: Maybe B.ByteString, leftTeams :: [B.ByteString], + rejoinedTeams :: [B.ByteString], -- for 0.9.21 frontend workaround teamsAtStart :: [TeamInfo], teamsInGameNumber :: Int, allPlayersHaveRegisteredAccounts :: !Bool, @@ -205,6 +207,7 @@ [] Nothing [] + [] data RoomInfo = @@ -222,6 +225,7 @@ isRestrictedTeams :: Bool, isRegisteredOnly :: Bool, isSpecial :: Bool, + defaultHedgehogsNumber :: Int, greeting :: B.ByteString, voting :: Maybe Voting, roomBansList :: ![B.ByteString], @@ -245,6 +249,7 @@ False False False + 4 "" Nothing [] @@ -319,6 +324,8 @@ data VoteType = VoteKick B.ByteString | VoteMap B.ByteString | VotePause + | VoteNewSeed + | VoteHedgehogsPerTeam Int newVoting :: VoteType -> Voting diff -r f71275973737 -r 48a53259fad8 gameServer/EngineInteraction.hs --- a/gameServer/EngineInteraction.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/gameServer/EngineInteraction.hs Sat Feb 07 23:26:14 2015 +0300 @@ -104,6 +104,7 @@ , schemeFlags , schemeAdditional , [eml ["e$template_filter ", mParams Map.! "TEMPLATE"]] + , [eml ["e$feature_size ", mParams Map.! "FEATURE_SIZE"]] , [eml ["e$mapgen ", mapgen]] , mapgenSpecific , concatMap teamSetup ti @@ -112,21 +113,21 @@ ] where keys1, keys2 :: Set.Set B.ByteString - keys1 = Set.fromList ["MAP", "MAPGEN", "MAZE_SIZE", "SEED", "TEMPLATE"] + keys1 = Set.fromList ["FEATURE_SIZE", "MAP", "MAPGEN", "MAZE_SIZE", "SEED", "TEMPLATE"] keys2 = Set.fromList ["AMMO", "SCHEME", "SCRIPT", "THEME"] sane = Set.null (keys1 Set.\\ Map.keysSet mParams) && Set.null (keys2 Set.\\ Map.keysSet prms) - && (not . null . drop 40 $ scheme) + && (not . null . drop 41 $ scheme) && (not . null . tail $ prms Map.! "AMMO") - mapGenTypes = ["+rnd+", "+maze+", "+drawn+"] + mapGenTypes = ["+rnd+", "+maze+", "+drawn+", "+perlin+"] maybeScript = let s = head . fromMaybe ["Normal"] $ Map.lookup "SCRIPT" prms in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]] maybeMap = let m = mParams Map.! "MAP" in if m `elem` mapGenTypes then [] else [eml ["emap ", m]] scheme = tail $ prms Map.! "SCHEME" mapgen = mParams Map.! "MAPGEN" + templateFilterMsg = eml ["e$maze_size ", mParams Map.! "MAZE_SIZE"] mapgenSpecific = case mapgen of - "1" -> [eml ["e$maze_size ", mParams Map.! "MAZE_SIZE"]] - "2" -> let d = head . fromMaybe [""] $ Map.lookup "DRAWNMAP" prms in if BW.length d <= 4 then [] else drawnMapData d - _ -> [] + "3" -> let d = head . fromMaybe [""] $ Map.lookup "DRAWNMAP" prms in if BW.length d <= 4 then [] else drawnMapData d + _ -> [templateFilterMsg] gameFlags :: Word32 gameFlags = foldl (\r (b, f) -> if b == "false" then r else r .|. f) 0 $ zip scheme gameFlagConsts schemeFlags = map (\(v, (n, m)) -> eml [n, " ", showB $ (readInt_ v) * m]) diff -r f71275973737 -r 48a53259fad8 gameServer/HWProtoInRoomState.hs --- a/gameServer/HWProtoInRoomState.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/gameServer/HWProtoInRoomState.hs Sat Feb 07 23:26:14 2015 +0300 @@ -105,14 +105,12 @@ handleCmd_inRoom ("ADD_TEAM" : tName : color : grave : fort : voicepack : flag : difStr : hhsInfo) | length hhsInfo /= 16 = return [ProtocolError $ loc "Corrupted hedgehogs info"] | otherwise = do - (ci, _) <- ask rm <- thisRoom cl <- thisClient clNick <- clientNick clChan <- thisClientChans othChans <- roomOthersChans roomChans <- roomClientsChans - cl <- thisClient let isRegistered = (<) 0 . B.length . webPassword $ cl teamColor <- if clientProto cl < 42 then @@ -120,7 +118,11 @@ else liftM (head . (L.\\) (map B.singleton ['0'..]) . map teamcolor . teams) thisRoom let roomTeams = teams rm - let hhNum = let p = if not $ null roomTeams then minimum [hhnum $ head roomTeams, canAddNumber roomTeams] else 4 in newTeamHHNum roomTeams p + let hhNum = newTeamHHNum roomTeams $ + if not $ null roomTeams then + minimum [hhnum $ head roomTeams, canAddNumber roomTeams] + else + defaultHedgehogsNumber rm let newTeam = clNick `seq` TeamInfo clNick tName teamColor grave fort voicepack flag isRegistered dif hhNum (hhsList hhsInfo) return $ if not . null . drop (maxTeams rm - 1) $ roomTeams then @@ -401,11 +403,13 @@ handleCmd_inRoom ["CALLVOTE"] = do cl <- thisClient - return [AnswerClients [sendChan cl] ["CHAT", "[server]", "Available callvote commands: kick , map , pause"]] + return [AnswerClients [sendChan cl] + ["CHAT", "[server]", loc "Available callvote commands: kick , map , pause, newseed, hedgehogs"] + ] handleCmd_inRoom ["CALLVOTE", "KICK"] = do cl <- thisClient - return [AnswerClients [sendChan cl] ["CHAT", "[server]", "callvote kick: specify nickname"]] + return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "callvote kick: specify nickname"]] handleCmd_inRoom ["CALLVOTE", "KICK", nickname] = do (thisClientId, rnc) <- ask @@ -421,7 +425,7 @@ if isJust maybeClientId && sameRoom then startVote $ VoteKick nickname else - return [AnswerClients [sendChan cl] ["CHAT", "[server]", "callvote kick: no such user"]] + return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "callvote kick: no such user"]] handleCmd_inRoom ["CALLVOTE", "MAP"] = do @@ -437,16 +441,37 @@ if Map.member roomSave $ roomSaves rm then startVote $ VoteMap roomSave else - return [AnswerClients [sendChan cl] ["CHAT", "[server]", "callvote map: no such map"]] + return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "callvote map: no such map"]] + handleCmd_inRoom ["CALLVOTE", "PAUSE"] = do cl <- thisClient rm <- thisRoom if isJust $ gameInfo rm then - startVote VotePause + startVote VotePause else - return [AnswerClients [sendChan cl] ["CHAT", "[server]", "callvote pause: no game in progress"]] + return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "callvote pause: no game in progress"]] + + +handleCmd_inRoom ["CALLVOTE", "NEWSEED"] = do + startVote VoteNewSeed + + +handleCmd_inRoom ["CALLVOTE", "HEDGEHOGS"] = do + cl <- thisClient + return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "callvote hedgehogs: specify number from 1 to 8"]] + + +handleCmd_inRoom ["CALLVOTE", "HEDGEHOGS", hhs] = do + cl <- thisClient + let h = readInt_ hhs + + if h > 0 && h <= 8 then + startVote $ VoteHedgehogsPerTeam h + else + return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "callvote hedgehogs: specify number from 1 to 8"]] + handleCmd_inRoom ["VOTE", m] = do cl <- thisClient diff -r f71275973737 -r 48a53259fad8 gameServer/HWProtoLobbyState.hs --- a/gameServer/HWProtoLobbyState.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/gameServer/HWProtoLobbyState.hs Sat Feb 07 23:26:14 2015 +0300 @@ -105,7 +105,7 @@ : AnswerClients chans ["CLIENT_FLAGS", "-r", nick cl] : [(AnswerClients [sendChan cl] $ "JOINED" : nicks) | not $ null nicks] ) - -- ++ [ModifyRoom (\r -> let (t', g') = moveTeams clTeams . fromJust $ gameInfo r in r{gameInfo = Just g', teams = t'}) | not $ null clTeams] + ++ [ModifyRoom (\r -> let (t', g') = moveTeams clTeams . fromJust $ gameInfo r in r{gameInfo = Just g', teams = t'}) | not $ null clTeams] ++ [AnswerClients [sendChan cl] ["CLIENT_FLAGS", "+h", nick $ fromJust owner] | isJust owner] ++ [sendStateFlags cl jRoomClients | not $ null jRoomClients] ++ answerFullConfig cl jRoom @@ -117,7 +117,7 @@ where moveTeams :: [B.ByteString] -> GameInfo -> ([TeamInfo], GameInfo) moveTeams cts g = (deleteFirstsBy2 (\a b -> teamname a == b) (teamsAtStart g) (leftTeams g \\ cts) - , g{leftTeams = leftTeams g \\ cts, teamsInGameNumber = teamsInGameNumber g + length cts}) + , g{leftTeams = leftTeams g \\ cts, rejoinedTeams = rejoinedTeams g ++ cts, teamsInGameNumber = teamsInGameNumber g + length cts}) sendStateFlags cl clients = AnswerClients [sendChan cl] . concat . intersperse [""] . filter (not . null) . concat $ [f "+r" ready, f "-r" unready, f "+g" ingame, f "-g" inroomlobby] where diff -r f71275973737 -r 48a53259fad8 gameServer/Votes.hs --- a/gameServer/Votes.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/gameServer/Votes.hs Sat Feb 07 23:26:14 2015 +0300 @@ -49,7 +49,7 @@ return [AnswerClients [sendChan cl] ["CHAT", "[server]", loc "You already have voted"]] else actOnVoting $ voting{votes = (uid, vote):votes voting} - + where actOnVoting :: Voting -> Reader (ClientIndex, IRnC) [Action] actOnVoting vt = do @@ -107,8 +107,24 @@ chans <- roomClientsChans let modifyGameInfo f room = room{gameInfo = fmap f $ gameInfo room} return [ModifyRoom (modifyGameInfo $ \g -> g{isPaused = not $ isPaused g}), - AnswerClients chans ["CHAT", "[server]", "Pause toggled"], + AnswerClients chans ["CHAT", "[server]", loc "Pause toggled"], AnswerClients chans ["EM", toEngineMsg "I"]] + act (VoteNewSeed) = + return [SetRandomSeed] + act (VoteHedgehogsPerTeam h) = do + rm <- thisRoom + chans <- roomClientsChans + let answers = concatMap (\t -> + [ModifyRoom $ modifyTeam t{hhnum = h} + , AnswerClients chans ["HH_NUM", teamname t, showB h]] + ) + $ + if isJust $ gameInfo rm then + teamsAtStart . fromJust . gameInfo $ rm + else + teams rm + + return $ ModifyRoom (\r -> r{defaultHedgehogsNumber = h}) : answers startVote :: VoteType -> Reader (ClientIndex, IRnC) [Action] @@ -154,3 +170,5 @@ voteInfo (VoteKick n) = B.concat [loc "kick", " ", n] voteInfo (VoteMap n) = B.concat [loc "map", " ", n] voteInfo (VotePause) = B.concat [loc "pause"] +voteInfo (VoteNewSeed) = B.concat [loc "new seed"] +voteInfo (VoteHedgehogsPerTeam i) = B.concat [loc "number of hedgehogs in team", " ", showB i] diff -r f71275973737 -r 48a53259fad8 hedgewars/CMakeLists.txt --- a/hedgewars/CMakeLists.txt Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/CMakeLists.txt Sat Feb 07 23:26:14 2015 +0300 @@ -21,12 +21,16 @@ endif(UNIX) # convert list into pascal array -list(LENGTH FONTS_DIRS ndirs) -set(FONTS_DIRS_ARRAY "array [0..${ndirs}] of PChar = (") -foreach(fontdir ${FONTS_DIRS}) - set(FONTS_DIRS_ARRAY "${FONTS_DIRS_ARRAY}\n'${fontdir}',") -endforeach(fontdir) -set(FONTS_DIRS_ARRAY "${FONTS_DIRS_ARRAY}\nnil);\n") +if(FONTS_DIRS) + list(LENGTH FONTS_DIRS ndirs) + set(FONTS_DIRS_ARRAY "array [0..${ndirs}] of PChar = (") + foreach(fontdir ${FONTS_DIRS}) + set(FONTS_DIRS_ARRAY "${FONTS_DIRS_ARRAY}\n_P'${fontdir}',") + endforeach(fontdir) + set(FONTS_DIRS_ARRAY "${FONTS_DIRS_ARRAY}\nnil);\n") +else(FONTS_DIRS) + set(FONTS_DIRS_ARRAY "array [0..1] of PChar = (nil, nil);") +endif(FONTS_DIRS) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc) include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff -r f71275973737 -r 48a53259fad8 hedgewars/config.inc.in --- a/hedgewars/config.inc.in Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/config.inc.in Sat Feb 07 23:26:14 2015 +0300 @@ -26,8 +26,4 @@ cRevisionString = '${HEDGEWARS_REVISION}'; cHashString = '${HEDGEWARS_HASH}'; cDefaultPathPrefix = '${HEDGEWARS_FULL_DATADIR}/Data'; -{$IFDEF PAS2C} - cFontsPaths: array[0..1] of PChar = (nil, nil); -{$ELSE} cFontsPaths: ${FONTS_DIRS_ARRAY} -{$ENDIF} diff -r f71275973737 -r 48a53259fad8 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uAIAmmoTests.pas Sat Feb 07 23:26:14 2015 +0300 @@ -122,7 +122,8 @@ (proc: nil; flags: 0), // amLandGun (proc: nil; flags: 0), // amIceGun (proc: nil; flags: 0), // amKnife - (proc: nil; flags: 0) // amGirder + (proc: nil; flags: 0), // amRubber + (proc: nil; flags: 0) // amAirMine ); implementation diff -r f71275973737 -r 48a53259fad8 hedgewars/uChat.pas --- a/hedgewars/uChat.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uChat.pas Sat Feb 07 23:26:14 2015 +0300 @@ -32,7 +32,7 @@ procedure SendHogSpeech(s: shortstring); implementation -uses SDLh, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript; +uses SDLh, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils; const MaxStrIndex = 27; @@ -91,8 +91,6 @@ dstrect : TSDL_Rect; // destination rectangle for blitting font : THWFont; const - shadowcolor: TSDL_Color = (r:$00; g:$00; b:$00; a:$FF); - //shadowcolor: TSDL_Color = (r:$00; g:$00; b:$00; a:$80); shadowint = $80 shl AShift; begin @@ -117,23 +115,11 @@ // draw background SDL_FillRect(resSurface, @dstrect, shadowint); -dstrect.x:= Padding + 1; -dstrect.y:= Padding + 1; -// doesn't matter if .w and .h still include padding, SDL_UpperBlit will clip - - -// create and blit text shadow -strSurface:= TTF_RenderUTF8_Solid(Fontz[font].Handle, Str2PChar(str), shadowcolor); -SDL_UpperBlit(strSurface, nil, resSurface, @dstrect); -SDL_FreeSurface(strSurface); - -// non-shadow text starts at padding -dstrect.x:= Padding; -dstrect.y:= Padding; // create and blit text strSurface:= TTF_RenderUTF8_Blended(Fontz[font].Handle, Str2PChar(str), cl.color); -SDL_UpperBlit(strSurface, nil, resSurface, @dstrect); +//SDL_UpperBlit(strSurface, nil, resSurface, @dstrect); +if strSurface <> nil then copyTOXY(strSurface, resSurface, Padding, Padding); SDL_FreeSurface(strSurface); cl.Tex:= Surface2Tex(resSurface, false); diff -r f71275973737 -r 48a53259fad8 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uConsts.pas Sat Feb 07 23:26:14 2015 +0300 @@ -231,6 +231,7 @@ gstInvisible = $00200000; gstSubmersible = $00400000; gstFrozen = $00800000; + gstNoGravity = $01000000; // gear messages gmLeft = $00000001; diff -r f71275973737 -r 48a53259fad8 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uGears.pas Sat Feb 07 23:26:14 2015 +0300 @@ -991,7 +991,8 @@ @doStepIceGun, @doStepAddAmmo, @doStepGenericFaller, - @doStepKnife); + @doStepKnife, + @doStepAirMine); begin doStepHandlers:= handlers; diff -r f71275973737 -r 48a53259fad8 hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uGearsHandlersMess.pas Sat Feb 07 23:26:14 2015 +0300 @@ -57,6 +57,7 @@ procedure doStepBlowTorchWork(Gear: PGear); procedure doStepBlowTorch(Gear: PGear); procedure doStepMine(Gear: PGear); +procedure doStepAirMine(Gear: PGear); procedure doStepSMine(Gear: PGear); procedure doStepDynamite(Gear: PGear); procedure doStepRollingBarrel(Gear: PGear); @@ -446,7 +447,8 @@ if isFalling then begin - Gear^.dY := Gear^.dY + cGravity; + if Gear^.State and gstNoGravity = 0 then + Gear^.dY := Gear^.dY + cGravity; if (GameFlags and gfMoreWind) <> 0 then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density end; @@ -1661,6 +1663,7 @@ Gear^.doStep := @doStepBlowTorchWork end; + //////////////////////////////////////////////////////////////////////////////// procedure doStepMine(Gear: PGear); var vg: PVisualGear; @@ -1749,6 +1752,165 @@ Gear^.State := Gear^.State or gsttmpFlag; end; +(* +Just keeping track for my own benefit. +Every second, locate new target. Clear if target radius has been set to 0 or no target in range. +Every... 16 milliseconds? Update vector to target. +*) + +procedure doStepAirMine(Gear: PGear); +var i,t,targDist,tmpDist: LongWord; + targ, tmpG: PGear; + trackSpeed, airFriction, tX, tY: hwFloat; +begin + if Gear^.Pos > 0 then + begin + airFriction:= _1; + dec(airFriction.QWordValue,Gear^.Pos); + Gear^.dX:= Gear^.dX*airFriction; + Gear^.dY:= Gear^.dY*airFriction + end; + doStepFallingGear(Gear); + if (TurnTimeLeft = 0) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) > _0_02.QWordValue) then + AllInactive := false; + + if (TurnTimeLeft = 0) or (Gear^.Angle = 0) or (Gear^.Hedgehog = nil) or (Gear^.Hedgehog^.Gear = nil) then + begin + Gear^.Hedgehog:= nil; + targ:= nil; + end + else if Gear^.Hedgehog <> nil then + targ:= Gear^.Hedgehog^.Gear; + if targ <> nil then + begin + tX:=Gear^.X-targ^.X; + tY:=Gear^.Y-targ^.Y; + // allow escaping - should maybe flag this too + if (GameTicks > Gear^.FlightTime+10000) or + ((tX.Round+tY.Round > Gear^.Angle*6) and + (hwRound(hwSqr(tX) + hwSqr(tY)) > sqr(Gear^.Angle*6))) then + targ:= nil + end; + + // If in ready timer, or after turn, or in first 5 seconds of turn (really a window due to extra time utility) + // or mine is inactive due to lack of gsttmpflag or hunting is disabled due to seek radius of 0 + // then we aren't hunting + if (ReadyTimeLeft > 0) or (TurnTimeLeft = 0) or + ((TurnTimeLeft < cHedgehogTurnTime) and (cHedgehogTurnTime-TurnTimeLeft < 5000)) or + (Gear^.State and gsttmpFlag = 0) or + (Gear^.Angle = 0) then + gear^.State:= gear^.State and (not gstHHChooseTarget) + else if + // todo, allow not finding new target, set timeout on target retention + (Gear^.State and gstAttacking = 0) and + ((GameTicks and $FF) = 17) and + (GameTicks > Gear^.FlightTime) then // recheck hunted hog + begin + gear^.State:= gear^.State or gstHHChooseTarget; + if targ <> nil then + targDist:= Distance(Gear^.X-targ^.X,Gear^.Y-targ^.Y).Round + else targDist:= 0; + for t:= 0 to Pred(TeamsCount) do + with TeamsArray[t]^ do + for i:= 0 to cMaxHHIndex do + if Hedgehogs[i].Gear <> nil then + begin + tmpG:= Hedgehogs[i].Gear; + tX:=Gear^.X-tmpG^.X; + tY:=Gear^.Y-tmpG^.Y; + if (Gear^.Angle = $FFFFFFFF) or + ((tX.Round+tY.Round < Gear^.Angle) and + (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Angle))) then + begin + if targ <> nil then tmpDist:= Distance(tX,tY).Round; + if (targ = nil) or (tmpDist < targDist) then + begin + if targ = nil then targDist:= Distance(tX,tY).Round + else targDist:= tmpDist; + Gear^.Hedgehog:= @Hedgehogs[i]; + targ:= tmpG; + end + end + end; + if targ <> nil then Gear^.FlightTime:= GameTicks + 5000 + end; + if targ <> nil then + begin + trackSpeed:= _0; + trackSpeed.QWordValue:= Gear^.Power; + if (Gear^.X < targ^.X) and (Gear^.dX < _0_1) then + Gear^.dX:= Gear^.dX+trackSpeed + else if (Gear^.X > targ^.X) and (Gear^.dX > -_0_1) then + Gear^.dX:= Gear^.dX-trackSpeed; + if (Gear^.Y < targ^.Y) and (Gear^.dY < _0_1) then + Gear^.dY:= Gear^.dY+trackSpeed + else if (Gear^.Y > targ^.Y) and (Gear^.dY > -_0_1) then + Gear^.dY:= Gear^.dY-trackSpeed + end + else Gear^.Hedgehog:= nil; + + if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then + begin + if ((Gear^.State and gstAttacking) = 0) then + begin + if ((GameTicks and $1F) = 0) then + begin + if targ <> nil then + begin + tX:=Gear^.X-targ^.X; + tY:=Gear^.Y-targ^.Y; + if (tX.Round+tY.Round < Gear^.Karma) and + (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Karma)) then + Gear^.State := Gear^.State or gstAttacking + end + else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Karma, Gear^.Karma) <> nil) then + Gear^.State := Gear^.State or gstAttacking + end + end + else // gstAttacking <> 0 + begin + AllInactive := false; + if (Gear^.Timer and $FF) = 0 then + PlaySound(sndMineTick); + if Gear^.Timer = 0 then + begin + // recheck + if targ <> nil then + begin + tX:=Gear^.X-targ^.X; + tY:=Gear^.Y-targ^.Y; + if (tX.Round+tY.Round < Gear^.Karma) and + (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Karma)) then + begin + Gear^.Hedgehog:= CurrentHedgehog; + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Karma, Gear^.Hedgehog, EXPLAutoSound); + DeleteGear(Gear); + exit + end + end + else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Karma, Gear^.Karma) <> nil) then + begin + Gear^.Hedgehog:= CurrentHedgehog; + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Karma, Gear^.Hedgehog, EXPLAutoSound); + DeleteGear(Gear); + exit + end; + Gear^.State:= Gear^.State and (not gstAttacking); + Gear^.Timer:= Gear^.WDTimer + end; + dec(Gear^.Timer); + end + end + else // gsttmpFlag = 0 + if (TurnTimeLeft = 0) + or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) + or (CurrentHedgehog^.Gear = nil) then + begin + Gear^.FlightTime:= GameTicks; + Gear^.State := Gear^.State or gsttmpFlag + end +end; + //////////////////////////////////////////////////////////////////////////////// procedure doStepSMine(Gear: PGear); var land: Word; diff -r f71275973737 -r 48a53259fad8 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uGearsHedgehog.pas Sat Feb 07 23:26:14 2015 +0300 @@ -290,6 +290,7 @@ case CurAmmoType of amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade, 0, newDx, newDy, CurWeapon^.Timer); + amAirMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtAirMine, 0, newDx, newDy, 0); amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov, 0, newDx, newDy, 0); amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, newDx, newDy, CurWeapon^.Timer); amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb, 0, newDx, newDy, CurWeapon^.Timer); @@ -425,7 +426,8 @@ amBazooka, amSnowball, amBee, amSMine, amMortar, amWatermelon, - amHellishBomb, amDrill: FollowGear:= newGear; + amHellishBomb, amDrill, + amAirMine: FollowGear:= newGear; amShotgun, amPickHammer, amRope, amDEagle, @@ -443,9 +445,10 @@ amTardis, amPiano, amIceGun, amRubber: CurAmmoGear:= newGear; end; - if CurAmmoType = amCake then FollowGear:= newGear; + if CurAmmoType = amCake then FollowGear:= newGear; + if CurAmmoType = amAirMine then newGear^.Hedgehog:= nil; - if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then + if ((CurAmmoType = amMine) or (CurAmmoType = amSMine) or (CurAmmoType = amAirMine)) and (GameFlags and gfInfAttack <> 0) then newGear^.FlightTime:= GameTicks + 1000 else if CurAmmoType = amDrill then newGear^.FlightTime:= GameTicks + 250; diff -r f71275973737 -r 48a53259fad8 hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uGearsList.pas Sat Feb 07 23:26:14 2015 +0300 @@ -103,6 +103,7 @@ (* gtAddAmmo *) , amNothing (* gtGenericFaller *) , amNothing (* gtKnife *) , amKnife +(* gtAirMine *) , amAirMine ); @@ -359,6 +360,28 @@ gear^.Timer:= cMinesTime end end; + gtAirMine: begin + gear^.ImpactSound:= sndDenied; + gear^.nImpactSounds:= 1; + gear^.Health:= 30; + gear^.State:= gear^.State or gstMoving or gstNoGravity; + gear^.Radius:= 8; + gear^.Elasticity:= _0_55; + gear^.Friction:= _0_995; + gear^.Density:= _1; + gear^.Angle:= 175; // Radius at which air bombs will start "seeking". $FFFFFFFF = unlimited. check is skipped. + gear^.Power:= cMaxWindSpeed.QWordValue div 2; // hwFloat converted. 1/2 g default. defines the "seek" speed when a gear is in range. + gear^.Pos:= cMaxWindSpeed.QWordValue; // air friction. slows it down when not hitting stuff + gear^.Karma:= 30; // damage + if gear^.Timer = 0 then + begin + if cMinesTime < 0 then + gear^.Timer:= getrandom(13)*100 + else + gear^.Timer:= cMinesTime div 4 + end; + gear^.WDTimer:= gear^.Timer + end; gtSMine: begin gear^.Health:= 10; gear^.State:= gear^.State or gstMoving; diff -r f71275973737 -r 48a53259fad8 hedgewars/uGearsRender.pas --- a/hedgewars/uGearsRender.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uGearsRender.pas Sat Feb 07 23:26:14 2015 +0300 @@ -684,6 +684,7 @@ amHellishBomb: DrawSpriteRotated(sprHandHellish, hx, hy, sign, aangle); amGasBomb: DrawSpriteRotated(sprHandCheese, hx, hy, sign, aangle); amMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle); + amAirMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle); amSMine: DrawSpriteRotated(sprHandSMine, hx, hy, sign, aangle); amKnife: DrawSpriteRotatedF(sprHandKnife, hx, hy, 0, sign, aangle); amSeduction: begin @@ -1119,6 +1120,18 @@ DrawSpriteRotated(sprMineOn, x, y, 0, Gear^.DirAngle) else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle); end; + gtAirMine: if Gear^.State and gstTmpFlag = 0 then // mine is inactive + begin + Tint(150,150,150,255); + DrawSprite(sprAirMine, x-16, y-16, 15); + untint + end + else if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) then // mine is chasing a hog + DrawSprite(sprAirMine, x-16, y-16, (RealTicks div 25) mod 16) + else if Gear^.State and gstHHChooseTarget <> 0 then // mine is seeking for hogs + DrawSprite(sprAirMine, x-16, y-16, (RealTicks div 125) mod 16) + else + DrawSprite(sprAirMine, x-16, y-16, 4); // mine is active but not seeking gtSMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then DrawSpriteRotated(sprSMineOff, x, y, 0, Gear^.DirAngle) diff -r f71275973737 -r 48a53259fad8 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uGearsUtils.pas Sat Feb 07 23:26:14 2015 +0300 @@ -127,6 +127,7 @@ gtClusterBomb, // gtCluster, too game breaking I think gtSMine, + gtAirMine, gtCase, gtTarget, gtFlame, diff -r f71275973737 -r 48a53259fad8 hedgewars/uLandTemplates.pas --- a/hedgewars/uLandTemplates.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uLandTemplates.pas Sat Feb 07 23:26:14 2015 +0300 @@ -1805,8 +1805,38 @@ (x:1005; y: 805; w: 0; h: 0) ); + +const Template46Points: array[0..19] of TSDL_Rect = + ( + (x: 800; y: 1424; w: 1; h: 1), + (x: 800; y: 1224; w: 1; h: 1), + (x: 2200; y: 1224; w: 1; h: 1), + (x: 2200; y: 1424; w: 1; h: 1), + (x: NTPX; y: 0; w: 1; h: 1), + (x: 800; y: 1024; w: 1; h: 1), + (x: 800; y: 844; w: 1; h: 1), + (x: 2200; y: 844; w: 1; h: 1), + (x: 2200; y: 1024; w: 1; h: 1), + (x: NTPX; y: 0; w: 1; h: 1), + (x: 800; y: 664; w: 1; h: 1), + (x: 800; y: 484; w: 1; h: 1), + (x: 2200; y: 484; w: 1; h: 1), + (x: 2200; y: 664; w: 1; h: 1), + (x: NTPX; y: 0; w: 1; h: 1), + (x: 800; y: 304; w: 1; h: 1), + (x: 800; y: 104; w: 1; h: 1), + (x: 2200; y: 104; w: 1; h: 1), + (x: 2200; y: 304; w: 1; h: 1), + (x: NTPX; y: 0; w: 1; h: 1) + + ); + Template46FPoints: array[0..0] of TPoint = + ( + (x: 1023; y: 0) + ); + //////////////////////////////////////////////////////////////////////// -var EdgeTemplates: array[0..45] of TEdgeTemplate = +var EdgeTemplates: array[0..46] of TEdgeTemplate = ( (BasePoints: PPointArray(@Template0Points); BasePointsCount: Succ(High(Template0Points)); @@ -2313,11 +2343,22 @@ canMirror: false; canFlip: false; isNegative: true; canInvert: false; hasGirders: false; MaxHedgeHogs: 48; + ), + (BasePoints: PPointArray(@Template46Points); + BasePointsCount: Succ(High(Template46Points)); + FillPoints: PPointArray(@Template46FPoints); + FillPointsCount: Succ(High(Template46FPoints)); + BezierizeCount: 2; + RandPassesCount: 8; + TemplateHeight: 1424; TemplateWidth: 3072; + canMirror: true; canFlip: false; isNegative: false; canInvert: false; + hasGirders: true; + MaxHedgeHogs: 18; ) ); const SmallTemplates: array[0..2] of Longword = ( 39, 40, 42 ); -const MediumTemplates: array[0..17] of Longword = - ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ); +const MediumTemplates: array[0..18] of Longword = + ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 46 ); const LargeTemplates: array[0..20] of Longword = ( 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, diff -r f71275973737 -r 48a53259fad8 hedgewars/uRender.pas --- a/hedgewars/uRender.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uRender.pas Sat Feb 07 23:26:14 2015 +0300 @@ -534,11 +534,14 @@ end; procedure openglRotatef(RotX, RotY, RotZ: GLfloat; dir: LongInt); inline; +{ workaround for pascal bug http://bugs.freepascal.org/view.php?id=27222 } +var tmpdir: LongInt; begin +tmpdir:=dir; {$IFDEF GL2} - hglRotatef(RotX, RotY, RotZ, dir); + hglRotatef(RotX, RotY, RotZ, tmpdir); {$ELSE} - glRotatef(RotX, RotY, RotZ, dir); + glRotatef(RotX, RotY, RotZ, tmpdir); {$ENDIF} end; diff -r f71275973737 -r 48a53259fad8 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uScript.pas Sat Feb 07 23:26:14 2015 +0300 @@ -836,33 +836,119 @@ lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); end; - lc_getvisualgearvalues:= 10; + lc_getvisualgearvalues:= 10 end; function lc_setvisualgearvalues(L : Plua_State) : LongInt; Cdecl; var vg : PVisualGear; begin - if CheckLuaParamCount(L, 11, 'SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint') then - begin +// Param count can be 1-11 at present +// if CheckLuaParamCount(L, 11, 'SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint') then +// begin vg:= VisualGearByUID(lua_tointeger(L, 1)); if vg <> nil then begin - vg^.X:= lua_tointeger(L, 2); - vg^.Y:= lua_tointeger(L, 3); - vg^.dX:= lua_tonumber(L, 4); - vg^.dY:= lua_tonumber(L, 5); - vg^.Angle:= lua_tonumber(L, 6); - vg^.Frame:= lua_tointeger(L, 7); - if lua_tointeger(L, 8) <> 0 then - vg^.FrameTicks:= lua_tointeger(L, 8); // find a better way to do this. maybe need to break all these up. - vg^.State:= lua_tointeger(L, 9); - vg^.Timer:= lua_tointeger(L, 10); - vg^.Tint:= lua_tointeger(L, 11); + if not lua_isnoneornil(L, 2) then + vg^.X:= lua_tointeger(L, 2); + if not lua_isnoneornil(L, 3) then + vg^.Y:= lua_tointeger(L, 3); + if not lua_isnoneornil(L, 4) then + vg^.dX:= lua_tonumber(L, 4); + if not lua_isnoneornil(L, 5) then + vg^.dY:= lua_tonumber(L, 5); + if not lua_isnoneornil(L, 6) then + vg^.Angle:= lua_tonumber(L, 6); + if not lua_isnoneornil(L, 7) then + vg^.Frame:= lua_tointeger(L, 7); + if not lua_isnoneornil(L, 8) then + vg^.FrameTicks:= lua_tointeger(L, 8); + if not lua_isnoneornil(L, 9) then + vg^.State:= lua_tointeger(L, 9); + if not lua_isnoneornil(L, 10) then + vg^.Timer:= lua_tointeger(L, 10); + if not lua_isnoneornil(L, 11) then + vg^.Tint:= lua_tointeger(L, 11) + end; +// end +// else +// lua_pushnil(L); // return value on stack (nil) + lc_setvisualgearvalues:= 0 +end; + +// so. going to use this to get/set some of the more obscure gear values which weren't already exposed elsewhere +// can keep adding things in the future. isnoneornil makes it safe +function lc_getgearvalues(L : Plua_State) : LongInt; Cdecl; +var gear: PGear; +begin + if CheckLuaParamCount(L, 1, 'GetGearValues', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + begin + lua_pushinteger(L, gear^.Angle); + lua_pushinteger(L, gear^.Power); + lua_pushinteger(L, gear^.WDTimer); + lua_pushinteger(L, gear^.Radius); + lua_pushinteger(L, hwRound(gear^.Density * _10000)); + lua_pushinteger(L, gear^.Karma); + lua_pushnumber(L, gear^.DirAngle); + lua_pushinteger(L, gear^.AdvBounce); + lua_pushinteger(L, Integer(gear^.ImpactSound)); + lua_pushinteger(L, gear^.nImpactSounds); + lua_pushinteger(L, gear^.Tint) + end + else + begin + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L) end end else - lua_pushnil(L); // return value on stack (nil) - lc_setvisualgearvalues:= 0; + begin + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L) + end; + lc_getgearvalues:= 11 +end; + +function lc_setgearvalues(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin +// Currently allows 1-12 params +// if CheckLuaParamCount(L, 12, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint') then +// begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + begin + if not lua_isnoneornil(L, 2) then + gear^.Angle := lua_tointeger(L, 2); + if not lua_isnoneornil(L, 3) then + gear^.Power := lua_tointeger(L, 3); + if not lua_isnoneornil(L, 4) then + gear^.WDTimer := lua_tointeger(L, 4); + if not lua_isnoneornil(L, 5) then + gear^.Radius := lua_tointeger(L, 5); + if not lua_isnoneornil(L, 6) then + gear^.Density:= int2hwFloat(lua_tointeger(L, 6)) / 10000; + if not lua_isnoneornil(L, 7) then + gear^.Karma := lua_tointeger(L, 7); + if not lua_isnoneornil(L, 8) then + gear^.DirAngle:= lua_tonumber(L, 8); + if not lua_isnoneornil(L, 9) then + gear^.AdvBounce := lua_tointeger(L, 9); + if not lua_isnoneornil(L, 10) then + gear^.ImpactSound := TSound(lua_tointeger(L, 10)); + if not lua_isnoneornil(L, 11) then + gear^.nImpactSounds := lua_tointeger(L, 11); + if not lua_isnoneornil(L, 12) then + gear^.Tint := lua_tointeger(L, 12) + end; +// end +// else +// lua_pushnil(L); // return value on stack (nil) + lc_setgearvalues:= 0 end; function lc_getfollowgear(L : Plua_State) : LongInt; Cdecl; @@ -927,6 +1013,46 @@ lc_getgearelasticity:= 1 end; +function lc_setgearelasticity(L : Plua_State) : LongInt; Cdecl; +var gear: PGear; +begin + if CheckLuaParamCount(L, 2, 'SetGearElasticity', 'gearUid, Elasticity') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + gear^.Elasticity:= int2hwFloat(lua_tointeger(L, 2)) / 10000 + end; + lc_setgearelasticity:= 0 +end; + +function lc_getgearfriction(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if CheckLuaParamCount(L, 1, 'GetGearFriction', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + lua_pushinteger(L, hwRound(gear^.friction * _10000)) + else + lua_pushnil(L); + end + else + lua_pushnil(L); // return value on stack (nil) + lc_getgearfriction:= 1 +end; + +function lc_setgearfriction(L : Plua_State) : LongInt; Cdecl; +var gear: PGear; +begin + if CheckLuaParamCount(L, 2, 'SetGearFriction', 'gearUid, Friction') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + gear^.Friction:= int2hwFloat(lua_tointeger(L, 2)) / 10000 + end; + lc_setgearfriction:= 0 +end; + function lc_setgearmessage(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin @@ -2947,6 +3073,8 @@ lua_register(luaState, _P'DeleteVisualGear', @lc_deletevisualgear); lua_register(luaState, _P'GetVisualGearValues', @lc_getvisualgearvalues); lua_register(luaState, _P'SetVisualGearValues', @lc_setvisualgearvalues); +lua_register(luaState, _P'GetGearValues', @lc_getgearvalues); +lua_register(luaState, _P'SetGearValues', @lc_setgearvalues); lua_register(luaState, _P'SpawnHealthCrate', @lc_spawnhealthcrate); lua_register(luaState, _P'SpawnAmmoCrate', @lc_spawnammocrate); lua_register(luaState, _P'SpawnUtilityCrate', @lc_spawnutilitycrate); @@ -3011,6 +3139,9 @@ lua_register(luaState, _P'CampaignLock', @lc_campaignlock); lua_register(luaState, _P'CampaignUnlock', @lc_campaignunlock); lua_register(luaState, _P'GetGearElasticity', @lc_getgearelasticity); +lua_register(luaState, _P'SetGearElasticity', @lc_setgearelasticity); +lua_register(luaState, _P'GetGearFriction', @lc_getgearfriction); +lua_register(luaState, _P'SetGearFriction', @lc_setgearfriction); lua_register(luaState, _P'GetGearRadius', @lc_getgearradius); lua_register(luaState, _P'GetGearMessage', @lc_getgearmessage); lua_register(luaState, _P'SetGearMessage', @lc_setgearmessage); diff -r f71275973737 -r 48a53259fad8 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uTypes.pas Sat Feb 07 23:26:14 2015 +0300 @@ -87,7 +87,8 @@ sprHandResurrector, sprCross, sprAirDrill, sprNapalmBomb, sprBulletHit, sprSnowball, sprHandSnowball, sprSnow, sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis, - sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2 + sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, + sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2, sprAirMine ); // Gears that interact with other Gears and/or Land @@ -104,7 +105,7 @@ gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 50 gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 55 gtNapalmBomb, gtSnowball, gtFlake, {gtStructure,} gtLandGun, gtTardis, // 61 - gtIceGun, gtAddAmmo, gtGenericFaller, gtKnife); // 65 + gtIceGun, gtAddAmmo, gtGenericFaller, gtKnife, gtAirMine); // 66 // Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.) TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire, @@ -154,7 +155,8 @@ amRCPlane, amLowGravity, amExtraDamage, amInvulnerable, amExtraTime, // 35 amLaserSight, amVampiric, amSniperRifle, amJetpack, amMolotov, amBirdy, amPortalGun, // 42 amPiano, amGasBomb, amSineGun, amFlamethrower, amSMine, amHammer, // 48 - amResurrector, amDrillStrike, amSnowball, amTardis, {amStructure,} amLandGun, amIceGun, amKnife, amRubber); // 56 + amResurrector, amDrillStrike, amSnowball, amTardis, {amStructure,} amLandGun, // 53 + amIceGun, amKnife, amRubber, amAirMine); // 57 // Different kind of crates that e.g. hedgehogs can pick up TCrateType = (HealthCrate, AmmoCrate, UtilityCrate); @@ -247,6 +249,7 @@ CollisionIndex: LongInt; // Position in collision array Message: LongWord; // Game messages are stored here. See gm bitmasks in uConsts uid: Longword; // Lua use this to reference gears + Hedgehog: PHedgehog; // set to CurrentHedgehog on gear creation. uStats damage code appears to assume it will never be nil and never be changed. If you override it, make sure it is set to a non-nil PHedgehog before dealing damage. // Strongly recommended not to override these. Will mess up generic operations like portaling X : hwFloat; // X/Y/dX/dY are position/velocity. People count on these having semi-normal values Y : hwFloat; @@ -278,7 +281,6 @@ Tex: PTexture; // A texture created by the gear. Shouldn't use for anything but textures Tint: LongWord; // Used to colour a texture LinkedGear: PGear; // Used to track a related gear. Portal pairs for example. - Hedgehog: PHedgehog; // set to CurrentHedgehog on gear creation SoundChannel: LongInt; // Used to track a sound the gear started end; TPGearArray = array of PGear; @@ -445,7 +447,7 @@ sidMolotov, sidBirdy, sidPortalGun, sidPiano, sidGasBomb, sidSineGun, sidFlamethrower,sidSMine, sidHammer, sidResurrector, sidDrillStrike, sidSnowball, sidNothing, sidTardis, - {sidStructure,} sidLandGun, sidIceGun, sidKnife, sidRubber); + {sidStructure,} sidLandGun, sidIceGun, sidKnife, sidRubber, sidAirMine); TMsgStrId = (sidStartFight, sidDraw, sidWinner, sidVolume, sidPaused, sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync, diff -r f71275973737 -r 48a53259fad8 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uVariables.pas Sat Feb 07 23:26:14 2015 +0300 @@ -699,7 +699,9 @@ (FileName: 'custom1'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil; Width: 0; Height: 0; imageWidth: 0; imageHeight: 0; saveSurf: true; priority: tpLow; getDimensions: true; getImageDimensions: true), // sprCustom1 (FileName: 'custom2'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil; - Width: 0; Height: 0; imageWidth: 0; imageHeight: 0; saveSurf: true; priority: tpLow; getDimensions: true; getImageDimensions: true) // sprCustom2 + Width: 0; Height: 0; imageWidth: 0; imageHeight: 0; saveSurf: true; priority: tpLow; getDimensions: true; getImageDimensions: true), // sprCustom2 + (FileName: 'AirMine'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; + Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true)// sprAirMine ); const @@ -2298,6 +2300,31 @@ PosCount: 4; PosSprite: sprAmRubber; ejectX: 0; + ejectY: 0), +// Air Mine + (NameId: sidAirMine; + NameTex: nil; + Probability: 100; + NumberInCase: 1; + Ammo: (Propz: ammoprop_Power or + ammoprop_AltUse or + ammoprop_NeedUpDown; + Count: 2; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amAirMine; + AttackVoice: sndLaugh; + Bounciness: 1000); + Slot: 5; + TimeAfterTurn: 5000; + minAngle: 0; + maxAngle: 0; + isDamaging: true; + SkipTurns: 0; + PosCount: 1; + PosSprite: sprWater; + ejectX: 0; ejectY: 0) ); diff -r f71275973737 -r 48a53259fad8 hedgewars/uVisualGearsHandlers.pas --- a/hedgewars/uVisualGearsHandlers.pas Mon Feb 02 23:12:56 2015 +0300 +++ b/hedgewars/uVisualGearsHandlers.pas Sat Feb 07 23:26:14 2015 +0300 @@ -125,7 +125,7 @@ if (round(X) >= cLeftScreenBorder) and (round(X) <= cRightScreenBorder) - and (round(Y) - 75 <= LAND_HEIGHT) + and (round(Y) - 250 <= LAND_HEIGHT) and (Timer > 0) and (Timer-Steps > 0) then begin if tdX > 0 then @@ -152,23 +152,31 @@ X:= X + cScreenSpace; moved:= true end - else - if round(X) > cRightScreenBorder then - begin - X:= X - cScreenSpace; - moved:= true - end; + else if round(X) > cRightScreenBorder then + begin + X:= X - cScreenSpace; + moved:= true + end; // if round(Y) < (LAND_HEIGHT - 1024 - 75) then Y:= Y + 25.0; // For if flag is set for flakes rising upwards? - if (Gear^.Layer = 2) and (round(Y) - 225 > LAND_HEIGHT) then + if (Gear^.Layer = 2) and (round(Y) - 400 > LAND_HEIGHT) and (cGravityf >= 0) then begin X:= cLeftScreenBorder + random(cScreenSpace); - Y:= Y - (1024 + 250 + random(50)); // TODO - configure in theme (jellies for example could use limited range) + Y:= Y-(1024 + 400 + random(50)); // TODO - configure in theme (jellies for example could use limited range) moved:= true end - else if (Gear^.Layer <> 2) and (round(Y) + 50 > LAND_HEIGHT) then + else if (Gear^.Layer <> 2) and (round(Y) - 150 > LAND_HEIGHT) and (cGravityf >= 0) then begin X:= cLeftScreenBorder + random(cScreenSpace); - Y:= Y - (1024 + random(25)); + Y:= Y-(1024 + 200 + random(50)); + moved:= true + end + else if (round(Y) < LAND_HEIGHT-1200) and (cGravityf < 0) then // gravity can make flakes move upwards + begin + X:= cLeftScreenBorder + random(cScreenSpace); + if Gear^.Layer = 2 then + Y:= Y+(1024 + 150 + random(100)) + else + Y:= Y+(1024 + random(50)); moved:= true end; if moved then diff -r f71275973737 -r 48a53259fad8 project_files/hwc/CMakeLists.txt --- a/project_files/hwc/CMakeLists.txt Mon Feb 02 23:12:56 2015 +0300 +++ b/project_files/hwc/CMakeLists.txt Sat Feb 07 23:26:14 2015 +0300 @@ -16,6 +16,18 @@ include_directories(${SDL_INCLUDE_DIR}) add_subdirectory(rtl) +# convert list into pascal array +if(FONTS_DIRS) + list(LENGTH FONTS_DIRS ndirs) + set(FONTS_DIRS_ARRAY "array [0..${ndirs}] of PChar = (") + foreach(fontdir ${FONTS_DIRS}) + set(FONTS_DIRS_ARRAY "${FONTS_DIRS_ARRAY}\n_P'${fontdir}',") + endforeach(fontdir) + set(FONTS_DIRS_ARRAY "${FONTS_DIRS_ARRAY}\nnil);\n") +else(FONTS_DIRS) + set(FONTS_DIRS_ARRAY "array [0..1] of PChar = (nil, nil);") +endif(FONTS_DIRS) + configure_file(${CMAKE_SOURCE_DIR}/hedgewars/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc) #get the list of pas files that are going to be converted and compiled diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Graphics/AirMine.png Binary file share/hedgewars/Data/Graphics/AirMine.png has changed diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png has changed diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png has changed diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/en.txt --- a/share/hedgewars/Data/Locale/en.txt Mon Feb 02 23:12:56 2015 +0300 +++ b/share/hedgewars/Data/Locale/en.txt Sat Feb 07 23:26:14 2015 +0300 @@ -59,6 +59,7 @@ 00:55=Freezer 00:56=Cleaver 00:57=Rubber +00:58=Air Mine 01:00=Let's fight! 01:01=Round draw diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_ar.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_bg.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_cs.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_da.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_de.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_el.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_en.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_es.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_fi.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_fr.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_gl.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_hu.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_it.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_ja.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_ko.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_lt.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_ms.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_nl.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_pl.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_pt_BR.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_pt_PT.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_ro.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_ru.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_sk.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_sv.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_tr_TR.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_uk.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_zh_CN.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Locale/hedgewars_zh_TW.ts diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Maps/ClimbHome/map.lua --- a/share/hedgewars/Data/Maps/ClimbHome/map.lua Mon Feb 02 23:12:56 2015 +0300 +++ b/share/hedgewars/Data/Maps/ClimbHome/map.lua Sat Feb 07 23:26:14 2015 +0300 @@ -1,5 +1,6 @@ HedgewarsScriptLoad("/Scripts/Locale.lua") HedgewarsScriptLoad("/Scripts/Utils.lua") +HedgewarsScriptLoad("/Scripts/Params.lua") local hTag = nil local hTagHeight = 33000 @@ -25,6 +26,7 @@ local WaterRise = nil local Cake = nil local CakeTries = 0 +local addCake = true local Stars = {} local tauntNoo = false local jokeAwardNavy = nil @@ -36,6 +38,30 @@ local scaleGraph = false local dummyHog = nil local dummySkip = 0 +local baseWaterSpeed = 2 +local waterSpeed = 0 +local waterAccel = 0 +local delayHeight = 32000 +local delayTime = 0 + +function onParameters() + parseParams() + + if params["speed"] ~= nil then + baseWaterSpeed = params["speed"] + end + if params["accel"] ~= nil then + waterAccel = params["accel"] + if waterAccel ~= 0 then waterAccel = div(32640000,waterAccel) end + end + if params["delaytime"] ~= nil then + delayTime = params["delaytime"] + end + if params["delaytime"] ~= nil then + delayHeight = 32768-params["delayheight"] + end + if params["nocake"] ~= nil then addCake = false end +end function onGameInit() -- Ensure people get same map for same theme @@ -237,7 +263,15 @@ end if CurrentHedgehog ~= nil and TurnTimeLeft > 0 and band(GetState(CurrentHedgehog),gstHHDriven) ~= 0 then - if MaxHeight < 32000 and MaxHeight > 286 and WaterLine > 286 then SetWaterLine(WaterLine-2) end + if MaxHeight < delayHeight and + TurnTimeLeft<(999999999-delayTime) and + MaxHeight > 286 and WaterLine > 286 then + if waterAccel ~= 0 then + SetWaterLine(WaterLine-(baseWaterSpeed+div(getActualHeight(MaxHeight)*100,waterAccel))) + else + SetWaterLine(WaterLine-baseWaterSpeed) + end + end if y > 0 and y < 30000 and MaxHeight > 286 and math.random(y) < 500 then local s = AddVisualGear(0, 0, vgtStraightShot, 0, true) local c = div(250000,y) @@ -371,7 +405,7 @@ end end - if CakeTries < 10 and y < 32600 and y > 3000 and Cake == nil and band(GetState(CurrentHedgehog),gstHHDriven) ~= 0 then + if addCake and CakeTries < 10 and y < 32600 and y > 3000 and Cake == nil and band(GetState(CurrentHedgehog),gstHHDriven) ~= 0 then -- doing this just after the start the first time to take advantage of randomness sources -- Pick a clear y to start with if y > 31000 then cy = 24585 elseif diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Maps/ClimbHome/mask.png Binary file share/hedgewars/Data/Maps/ClimbHome/mask.png has changed diff -r f71275973737 -r 48a53259fad8 share/hedgewars/Data/Scripts/Multiplayer/Gravity.lua --- a/share/hedgewars/Data/Scripts/Multiplayer/Gravity.lua Mon Feb 02 23:12:56 2015 +0300 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Gravity.lua Sat Feb 07 23:26:14 2015 +0300 @@ -41,7 +41,7 @@ if delta == nil then if periodtimer == 0 then periodtimer = period * 2 - SetGravity(div(GetRandom(maxgravity - mingravity) + mingravity, mln)) + SetGravity(div(GetRandom(maxgravity - mingravity + 1) + mingravity, mln)) else periodtimer = periodtimer - 1 end diff -r f71275973737 -r 48a53259fad8 tools/pas2c/Pas2C.hs --- a/tools/pas2c/Pas2C.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/tools/pas2c/Pas2C.hs Sat Feb 07 23:26:14 2015 +0300 @@ -668,6 +668,7 @@ initExpr2C' (InitHexNumber s) = return $ text "0x" <> (text . map toLower $ s) initExpr2C' (InitString [a]) = return . quotes $ text [a] initExpr2C' (InitString s) = return $ strInit s +initExpr2C' (InitPChar s) = return $ doubleQuotes (text $ escapeStr s) initExpr2C' (InitChar a) = return $ text "0x" <> text (showHex (read a) "") initExpr2C' (InitReference i) = id2C IOLookup i initExpr2C' (InitRecord fields) = do diff -r f71275973737 -r 48a53259fad8 tools/pas2c/PascalParser.hs --- a/tools/pas2c/PascalParser.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/tools/pas2c/PascalParser.hs Sat Feb 07 23:26:14 2015 +0300 @@ -629,6 +629,8 @@ , try $ integer pas >>= \i -> notFollowedBy (char' '.') >> (return . InitNumber . show) i , try $ float pas >>= return . InitFloat . show , try $ integer pas >>= return . InitNumber . show + , try (string' "_S" >> stringLiteral pas) >>= return . InitString + , try (string' "_P" >> stringLiteral pas) >>= return . InitPChar , stringLiteral pas >>= return . InitString , char' '#' >> many digit >>= \c -> comments >> return (InitChar c) , char' '$' >> many hexDigit >>= \h -> comments >> return (InitHexNumber h) diff -r f71275973737 -r 48a53259fad8 tools/pas2c/PascalUnitSyntaxTree.hs --- a/tools/pas2c/PascalUnitSyntaxTree.hs Mon Feb 02 23:12:56 2015 +0300 +++ b/tools/pas2c/PascalUnitSyntaxTree.hs Sat Feb 07 23:26:14 2015 +0300 @@ -89,6 +89,7 @@ | InitNumber String | InitHexNumber String | InitString String + | InitPChar String | InitChar String | BuiltInFunction String [InitExpression] | InitSet [InitExpression]