--- a/QTfrontend/CMakeLists.txt Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/CMakeLists.txt Mon Oct 28 14:07:04 2013 +0100
@@ -13,6 +13,12 @@
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
+if(APPLE AND
+ ${QTVERSION} VERSION_GREATER "4.7.0" AND
+ ${QTVERSION} VERSION_LESS "4.7.4")
+ message(FATAL_ERROR "This version of QT is known *not* to work, please update or use a lower version")
+endif()
+
find_package(SDL REQUIRED) #video in SDLInteraction
find_package(SDL_mixer REQUIRED) #audio in SDLInteraction
--- a/QTfrontend/drawmapscene.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/drawmapscene.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -20,6 +20,8 @@
#include <QGraphicsPathItem>
#include <QtEndian>
#include <QDebug>
+#include <QTransform>
+#include <math.h>
#include "drawmapscene.h"
@@ -44,6 +46,8 @@
setBackgroundBrush(m_eraser);
m_isErasing = false;
+ m_pathType = Polyline;
+
m_pen.setWidth(76);
m_pen.setJoinStyle(Qt::RoundJoin);
m_pen.setCapStyle(Qt::RoundCap);
@@ -60,19 +64,45 @@
if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton))
{
QPainterPath path = m_currPath->path();
+ QPointF currentPos = mouseEvent->scenePos();
if(mouseEvent->modifiers() & Qt::ControlModifier)
+ currentPos = putSomeConstraints(paths.first().initialPoint, currentPos);
+
+ switch (m_pathType)
{
- int c = path.elementCount();
- QPointF pos = mouseEvent->scenePos();
- path.setElementPositionAt(c - 1, pos.x(), pos.y());
+ case Polyline:
+ if(mouseEvent->modifiers() & Qt::ControlModifier)
+ {
+ int c = path.elementCount();
+ path.setElementPositionAt(c - 1, currentPos.x(), currentPos.y());
+ }
+ else
+ {
+ path.lineTo(currentPos);
+ paths.first().points.append(mouseEvent->scenePos().toPoint());
+ }
+ break;
+ case Rectangle: {
+ path = QPainterPath();
+ QPointF p1 = paths.first().initialPoint;
+ QPointF p2 = currentPos;
+ path.moveTo(p1);
+ path.lineTo(p1.x(), p2.y());
+ path.lineTo(p2);
+ path.lineTo(p2.x(), p1.y());
+ path.lineTo(p1);
+ break;
+ }
+ case Ellipse: {
+ path = QPainterPath();
+ QList<QPointF> points = makeEllipse(paths.first().initialPoint, currentPos);
+ path.addPolygon(QPolygonF(QVector<QPointF>::fromList(points)));
+ break;
}
- else
- {
- path.lineTo(mouseEvent->scenePos());
- paths.first().points.append(mouseEvent->scenePos().toPoint());
}
+
m_currPath->setPath(path);
emit pathChanged();
@@ -96,7 +126,8 @@
PathParams params;
params.width = serializePenWidth(m_pen.width());
params.erasing = m_isErasing;
- params.points = QList<QPoint>() << mouseEvent->scenePos().toPoint();
+ params.initialPoint = mouseEvent->scenePos().toPoint();
+ params.points = QList<QPoint>() << params.initialPoint;
paths.prepend(params);
m_currPath->setPath(path);
@@ -107,14 +138,43 @@
{
if (m_currPath)
{
- QPainterPath path = m_currPath->path();
- path.lineTo(mouseEvent->scenePos());
- paths.first().points.append(mouseEvent->scenePos().toPoint());
- m_currPath->setPath(path);
+ QPointF currentPos = mouseEvent->scenePos();
+
+ if(mouseEvent->modifiers() & Qt::ControlModifier)
+ currentPos = putSomeConstraints(paths.first().initialPoint, currentPos);
- simplifyLast();
+ switch (m_pathType)
+ {
+ case Polyline: {
+ QPainterPath path = m_currPath->path();
+ path.lineTo(mouseEvent->scenePos());
+ paths.first().points.append(currentPos.toPoint());
+ m_currPath->setPath(path);
+ simplifyLast();
+ break;
+ }
+ case Rectangle: {
+ QPoint p1 = paths.first().initialPoint;
+ QPoint p2 = currentPos.toPoint();
+ QList<QPoint> rpoints;
+ rpoints << p1 << QPoint(p1.x(), p2.y()) << p2 << QPoint(p2.x(), p1.y()) << p1;
+ paths.first().points = rpoints;
+ break;
+ }
+ case Ellipse:
+ QPoint p1 = paths.first().initialPoint;
+ QPoint p2 = currentPos.toPoint();
+ QList<QPointF> points = makeEllipse(p1, p2);
+ QList<QPoint> epoints;
+ foreach(const QPointF & p, points)
+ epoints.append(p.toPoint());
+ paths.first().points = epoints;
+ break;
+ }
m_currPath = 0;
+
+ emit pathChanged();
}
}
@@ -156,7 +216,7 @@
if(m_isCursorShown)
return;
- if(items().size())
+ if(paths.size())
{
removeItem(items().first());
paths.removeFirst();
@@ -183,15 +243,18 @@
if(!items().size())
return;
+ m_specialPoints.clear();
oldItems.clear();
// do this since clear() would _destroy_ all items
- while(items().size())
+ for(int i = paths.size() - 1; i >= 0; --i)
{
oldItems.push_front(items().first());
removeItem(items().first());
}
+ items().clear();
+
oldPaths = paths;
paths.clear();
@@ -211,7 +274,7 @@
QByteArray DrawMapScene::encode()
{
- QByteArray b;
+ QByteArray b(m_specialPoints);
for(int i = paths.size() - 1; i >= 0; --i)
{
@@ -247,9 +310,12 @@
oldPaths.clear();
clear();
paths.clear();
+ m_specialPoints.clear();
PathParams params;
+ bool isSpecial = true;
+
while(data.size() >= 5)
{
qint16 px = qFromBigEndian(*(qint16 *)data.data());
@@ -258,9 +324,11 @@
data.remove(0, 2);
quint8 flags = *(quint8 *)data.data();
data.remove(0, 1);
-
+ qDebug() << px << py;
if(flags & 0x80)
{
+ isSpecial = false;
+
if(params.points.size())
{
addPath(pointsToPath(params.points), m_pen);
@@ -278,9 +346,23 @@
else
m_pen.setBrush(m_brush);
params.width = penWidth;
- }
+ } else
+ if(isSpecial)
+ {
+ QPainterPath path;
+ path.addEllipse(QPointF(px, py), 10, 10);
+
+ addPath(path);
- params.points.append(QPoint(px, py));
+ qint16 x = qToBigEndian(px);
+ qint16 y = qToBigEndian(py);
+ m_specialPoints.append((const char *)&x, 2);
+ m_specialPoints.append((const char *)&y, 2);
+ m_specialPoints.append((const char *)&flags, 1);
+ }
+
+ if(!isSpecial)
+ params.points.append(QPoint(px, py));
}
if(params.points.size())
@@ -323,8 +405,6 @@
QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[m_isCursorShown ? 1 : 0]);
pathItem->setPath(pointsToPath(paths[0].points));
}
-
- emit pathChanged();
}
int DrawMapScene::pointsCount()
@@ -361,3 +441,47 @@
{
return width * 10 + 6;
}
+
+void DrawMapScene::setPathType(PathType pathType)
+{
+ m_pathType = pathType;
+}
+
+QList<QPointF> DrawMapScene::makeEllipse(const QPointF ¢er, const QPointF &corner)
+{
+ QList<QPointF> l;
+ qreal rx = qAbs(center.x() - corner.x());
+ qreal ry = qAbs(center.y() - corner.y());
+ qreal r = qMax(rx, ry);
+
+ if(r < 4)
+ {
+ l.append(center);
+ } else
+ {
+ qreal angleDelta = qMax(0.1, qMin(0.7, 120 / r));
+ for(qreal angle = 0.0; angle < 2*M_PI; angle += angleDelta)
+ l.append(center + QPointF(rx * cos(angle), ry * sin(angle)));
+ l.append(l.first());
+ }
+
+ return l;
+}
+
+QPointF DrawMapScene::putSomeConstraints(const QPointF &initialPoint, const QPointF &point)
+{
+ QPointF vector = point - initialPoint;
+
+ for(int angle = 0; angle < 180; angle += 15)
+ {
+ QTransform transform;
+ transform.rotate(angle);
+
+ QPointF rotated = transform.map(vector);
+
+ if(rotated.x() == 0) return point;
+ if(qAbs(rotated.y() / rotated.x()) < 0.05) return initialPoint + transform.inverted().map(QPointF(rotated.x(), 0));
+ }
+
+ return point;
+}
--- a/QTfrontend/drawmapscene.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/drawmapscene.h Mon Oct 28 14:07:04 2013 +0100
@@ -29,6 +29,7 @@
{
quint8 width;
bool erasing;
+ QPoint initialPoint;
QList<QPoint> points;
};
@@ -38,6 +39,12 @@
{
Q_OBJECT
public:
+ enum PathType {
+ Polyline = 0,
+ Rectangle = 1,
+ Ellipse = 2
+ };
+
explicit DrawMapScene(QObject *parent = 0);
QByteArray encode();
@@ -54,6 +61,7 @@
void setErasing(bool erasing);
void showCursor();
void hideCursor();
+ void setPathType(PathType pathType);
private:
QPen m_pen;
@@ -66,6 +74,8 @@
QList<QGraphicsItem *> oldItems;
QGraphicsEllipseItem * m_cursor;
bool m_isCursorShown;
+ QByteArray m_specialPoints;
+ PathType m_pathType;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);
@@ -76,6 +86,8 @@
quint8 serializePenWidth(int width);
int deserializePenWidth(quint8 width);
+ QList<QPointF> makeEllipse(const QPointF & center, const QPointF & corner);
+ QPointF putSomeConstraints(const QPointF & initialPoint, const QPointF & point);
};
#endif // DRAWMAPSCENE_H
--- a/QTfrontend/game.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/game.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -89,18 +89,6 @@
SetGameState(gsStopped);
}
-void HWGame::addKeyBindings(QByteArray * buf)
-{
- for(int i = 0; i < BINDS_NUMBER; i++)
- {
- QString value = config->value(QString("Binds/%1").arg(cbinds[i].action), cbinds[i].strbind).toString();
- if (value.isEmpty() || value == "default") continue;
-
- QString bind = QString("edbind " + value + " " + cbinds[i].action);
- HWProto::addStringToBuffer(*buf, bind);
- }
-}
-
void HWGame::commonConfig()
{
QByteArray buf;
@@ -118,8 +106,6 @@
}
HWProto::addStringToBuffer(buf, gt);
- addKeyBindings(&buf);
-
buf += gamecfg->getFullConfig();
if (m_pTeamSelWidget)
@@ -132,7 +118,7 @@
HWProto::addStringToBuffer(buf, QString("eammreinf %1").arg(ammostr.mid(3 * cAmmoNumber, cAmmoNumber)));
if(gamecfg->schemeData(15).toBool() || !gamecfg->schemeData(21).toBool()) HWProto::addStringToBuffer(buf, QString("eammstore"));
HWProto::addStringListToBuffer(buf,
- team.teamGameConfig(gamecfg->getInitHealth(), config));
+ team.teamGameConfig(gamecfg->getInitHealth()));
;
}
}
@@ -150,8 +136,6 @@
QByteArray teamscfg;
ThemeModel * themeModel = DataManager::instance().themeModel();
- addKeyBindings(&teamscfg);
-
HWProto::addStringToBuffer(teamscfg, "TL");
HWProto::addStringToBuffer(teamscfg, QString("etheme %1")
.arg((themeModel->rowCount() > 0) ? themeModel->index(rand() % themeModel->rowCount()).data(ThemeModel::ActualNameRole).toString() : "steel"));
@@ -165,7 +149,7 @@
team1.setNumHedgehogs(4);
HWNamegen::teamRandomNames(team1,true);
HWProto::addStringListToBuffer(teamscfg,
- team1.teamGameConfig(100, config));
+ team1.teamGameConfig(100));
HWTeam team2;
team2.setDifficulty(4);
@@ -175,7 +159,7 @@
HWNamegen::teamRandomNames(team2,true);
while(!team2.name().compare(team1.name()) || !team2.hedgehog(0).Hat.compare(team1.hedgehog(0).Hat));
HWProto::addStringListToBuffer(teamscfg,
- team2.teamGameConfig(100, config));
+ team2.teamGameConfig(100));
HWProto::addStringToBuffer(teamscfg, QString("eammloadt %1").arg(cDefaultAmmoStore->mid(0, cAmmoNumber)));
HWProto::addStringToBuffer(teamscfg, QString("eammprob %1").arg(cDefaultAmmoStore->mid(cAmmoNumber, cAmmoNumber)));
@@ -194,8 +178,6 @@
HWProto::addStringToBuffer(traincfg, "eseed " + QUuid::createUuid().toString());
HWProto::addStringToBuffer(traincfg, "escript " + training);
- addKeyBindings(&traincfg);
-
RawSendIPC(traincfg);
}
@@ -207,8 +189,6 @@
HWProto::addStringToBuffer(campaigncfg, "escript " + campaignScript);
- addKeyBindings(&campaigncfg);
-
RawSendIPC(campaigncfg);
}
--- a/QTfrontend/game.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/game.h Mon Oct 28 14:07:04 2013 +0100
@@ -113,7 +113,6 @@
GameType gameType;
QByteArray m_netSendBuffer;
- void addKeyBindings(QByteArray * buf);
void commonConfig();
void SendConfig();
void SendQuickConfig();
--- a/QTfrontend/gameuiconfig.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/gameuiconfig.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -159,6 +159,8 @@
Form->ui.pageOptions->leProxyLogin->setText(value("proxy/login", "").toString());
Form->ui.pageOptions->leProxyPassword->setText(value("proxy/password", "").toString());
+ applyProxySettings();
+
{ // load colors
QStandardItemModel * model = DataManager::instance().colorsModel();
for(int i = model->rowCount() - 1; i >= 0; --i)
@@ -310,22 +312,7 @@
setValue("proxy/password", Form->ui.pageOptions->leProxyPassword->text());
}
- QNetworkProxy proxy;
-
- if(proxyType == PageOptions::SystemProxy)
- {
- // use system proxy settings
- proxy = QNetworkProxyFactory::systemProxyForQuery().at(0);
- } else
- {
- proxy.setType(proxyTypesMap[proxyType]);
- proxy.setHostName(Form->ui.pageOptions->leProxy->text());
- proxy.setPort(Form->ui.pageOptions->sbProxyPort->value());
- proxy.setUser(Form->ui.pageOptions->leProxyLogin->text());
- proxy.setPassword(Form->ui.pageOptions->leProxyPassword->text());
- }
-
- QNetworkProxy::setApplicationProxy(proxy);
+ applyProxySettings();
}
{ // save colors
@@ -665,3 +652,25 @@
m_binds[bindID].strbind = strbind;
setValue(QString("Binds/%1").arg(m_binds[bindID].action), strbind);
}
+
+void GameUIConfig::applyProxySettings()
+{
+ QNetworkProxy proxy;
+
+ int proxyType = Form->ui.pageOptions->cbProxyType->currentIndex();
+
+ if(proxyType == PageOptions::SystemProxy)
+ {
+ // use system proxy settings
+ proxy = QNetworkProxyFactory::systemProxyForQuery().at(0);
+ } else
+ {
+ proxy.setType(proxyTypesMap[proxyType]);
+ proxy.setHostName(Form->ui.pageOptions->leProxy->text());
+ proxy.setPort(Form->ui.pageOptions->sbProxyPort->value());
+ proxy.setUser(Form->ui.pageOptions->leProxyLogin->text());
+ proxy.setPassword(Form->ui.pageOptions->leProxyPassword->text());
+ }
+
+ QNetworkProxy::setApplicationProxy(proxy);
+}
--- a/QTfrontend/gameuiconfig.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/gameuiconfig.h Mon Oct 28 14:07:04 2013 +0100
@@ -99,6 +99,8 @@
bool eventFilter(QObject *object, QEvent *event);
QString temphash;
QList<BindAction> m_binds;
+
+ void applyProxySettings();
};
#endif
--- a/QTfrontend/hedgewars.qrc Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/hedgewars.qrc Mon Oct 28 14:07:04 2013 +0100
@@ -128,6 +128,7 @@
<file>res/iconMine.png</file>
<file>res/iconDud.png</file>
<file>res/iconRope.png</file>
+ <file>res/iconEarth.png</file>
<file>res/dice.png</file>
<file>res/Star.png</file>
<file>res/inverse-corner-bl.png</file>
@@ -179,5 +180,9 @@
<file>res/splash.png</file>
<file>res/html/about.html</file>
<file>res/xml/tips.xml</file>
+ <file>res/chat/hedgehogcontributor.png</file>
+ <file>res/chat/hedgehogcontributor_gray.png</file>
+ <file>res/chat/roomadmincontributor.png</file>
+ <file>res/chat/roomadmincontributor_gray.png</file>
</qresource>
</RCC>
--- a/QTfrontend/hwform.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/hwform.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -1130,7 +1130,7 @@
//ForcedDisconnect(tr("No nickname supplied."));
bool retry = RetryDialog(tr("Hedgewars - Empty nickname"), tr("No nickname supplied."));
GoBack();
- if (retry) {
+ if (retry && hwnet) {
if (hwnet->m_private_game) {
QStringList list = hwnet->getHost().split(":");
NetConnectServer(list.at(0), list.at(1).toShort());
@@ -1140,7 +1140,8 @@
return;
}
- hwnet->NewNick(newNick);
+ if(hwnet)
+ hwnet->NewNick(newNick);
config->setValue("net/nick", newNick);
config->updNetNick();
@@ -1164,6 +1165,13 @@
}
}
+void HWForm::askRoomPassword()
+{
+ QString password = QInputDialog::getText(this, tr("Room password"), tr("The room is protected with password.\nPlease, enter the password:"));
+ if(hwnet && !password.isEmpty())
+ hwnet->roomPasswordEntered(password);
+}
+
bool HWForm::RetryDialog(const QString & title, const QString & label)
{
QMessageBox retryMsg(this);
@@ -1243,6 +1251,7 @@
connect(hwnet, SIGNAL(NickTaken(const QString&)), this, SLOT(NetNickTaken(const QString&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(AuthFailed()), this, SLOT(NetAuthFailed()), Qt::QueuedConnection);
//connect(ui.pageNetGame->BtnBack, SIGNAL(clicked()), hwnet, SLOT(partRoom()));
+ connect(hwnet, SIGNAL(askForRoomPassword()), this, SLOT(askRoomPassword()), Qt::QueuedConnection);
ui.pageRoomsList->chatWidget->setUsersModel(hwnet->lobbyPlayersModel());
ui.pageNetGame->chatWidget->setUsersModel(hwnet->roomPlayersModel());
@@ -1257,10 +1266,10 @@
connect(hwnet, SIGNAL(serverMessage(const QString&)),
ui.pageRoomsList->chatWidget, SLOT(onServerMessage(const QString&)), Qt::QueuedConnection);
- connect(ui.pageRoomsList, SIGNAL(askForCreateRoom(const QString &)),
- hwnet, SLOT(CreateRoom(const QString&)));
- connect(ui.pageRoomsList, SIGNAL(askForJoinRoom(const QString &)),
- hwnet, SLOT(JoinRoom(const QString&)));
+ connect(ui.pageRoomsList, SIGNAL(askForCreateRoom(const QString &, const QString &)),
+ hwnet, SLOT(CreateRoom(const QString&, const QString &)));
+ connect(ui.pageRoomsList, SIGNAL(askForJoinRoom(const QString &, const QString &)),
+ hwnet, SLOT(JoinRoom(const QString&, const QString &)));
// connect(ui.pageRoomsList, SIGNAL(askForCreateRoom(const QString &)),
// this, SLOT(NetGameMaster()));
// connect(ui.pageRoomsList, SIGNAL(askForJoinRoom(const QString &)),
--- a/QTfrontend/hwform.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/hwform.h Mon Oct 28 14:07:04 2013 +0100
@@ -112,6 +112,7 @@
void NetNickNotRegistered(const QString & nick);
void NetNickTaken(const QString & nick);
void NetAuthFailed();
+ void askRoomPassword();
bool RetryDialog(const QString & title, const QString & label);
void NetTeamAccepted(const QString& team);
void AddNetTeam(const HWTeam& team);
--- a/QTfrontend/model/ammoSchemeModel.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/model/ammoSchemeModel.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -64,6 +64,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
AmmoSchemeModel::AmmoSchemeModel(QObject* parent, const QString & fileName) :
@@ -128,6 +129,7 @@
<< "healthdecrease" // 38
<< "ropepct" // 39
<< "getawaytime" // 40
+ << "worldedge" // 41
;
QList<QVariant> proMode;
@@ -173,6 +175,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> shoppa;
@@ -218,6 +221,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> cleanslate;
@@ -263,6 +267,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> minefield;
@@ -308,6 +313,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> barrelmayhem;
@@ -353,6 +359,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> tunnelhogs;
@@ -398,6 +405,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> forts;
@@ -443,6 +451,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> timeless;
@@ -488,6 +497,7 @@
<< QVariant(0) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> thinkingportals;
@@ -533,6 +543,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
QList<QVariant> kingmode;
@@ -578,6 +589,7 @@
<< QVariant(5) // health dec amt 38
<< QVariant(100) // rope modfier 39
<< QVariant(100) // get away time 40
+ << QVariant(0) // world edge 41
;
--- a/QTfrontend/model/playerslistmodel.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/model/playerslistmodel.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -11,7 +11,8 @@
PlayersListModel::PlayersListModel(QObject *parent) :
QAbstractListModel(parent)
{
-
+ m_fontInRoom = QFont();
+ m_fontInRoom.setItalic(true);
}
@@ -223,6 +224,7 @@
<< index.data(Ignore).toBool()
<< index.data(InGame).toBool()
<< index.data(RoomFilterRole).toBool()
+ << index.data(InRoom).toBool()
;
for(int i = flags.size() - 1; i >= 0; --i)
@@ -253,16 +255,26 @@
else
painter.drawPixmap(0, 0, 16, 16, QPixmap(":/res/chat/lamp_off.png"));
}
+ } else
+ { // we're in lobby
+ if(!index.data(InRoom).toBool())
+ painter.drawPixmap(0, 0, 16, 16, QPixmap(":/res/Flake.png"));
}
QString mainIconName(":/res/chat/");
- if(index.data(RoomAdmin).toBool())
- mainIconName += "roomadmin";
- else if(index.data(ServerAdmin).toBool())
+ if(index.data(ServerAdmin).toBool())
mainIconName += "serveradmin";
else
- mainIconName += "hedgehog";
+ {
+ if(index.data(RoomAdmin).toBool())
+ mainIconName += "roomadmin";
+ else
+ mainIconName += "hedgehog";
+
+ if(index.data(Contributor).toBool())
+ mainIconName += "contributor";
+ }
if(!index.data(Registered).toBool())
mainIconName += "_gray";
--- a/QTfrontend/model/playerslistmodel.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/model/playerslistmodel.h Mon Oct 28 14:07:04 2013 +0100
@@ -6,6 +6,7 @@
#include <QIcon>
#include <QModelIndex>
#include <QSet>
+#include <QFont>
class PlayersListModel : public QAbstractListModel
{
@@ -19,7 +20,9 @@
Registered = Qt::UserRole + 3,
Friend = Qt::UserRole + 4,
Ignore = Qt::UserRole + 5,
- InGame = Qt::UserRole + 6
+ InGame = Qt::UserRole + 6,
+ InRoom = Qt::UserRole + 7,
+ Contributor = Qt::UserRole + 8
};
enum SpecialRoles {
@@ -61,6 +64,7 @@
QList<DataEntry> m_data;
QSet<QString> m_friendsSet, m_ignoredSet;
QString m_nickname;
+ QFont m_fontInRoom;
void updateIcon(const QModelIndex & index);
void updateSortData(const QModelIndex & index);
--- a/QTfrontend/net/newnetclient.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/net/newnetclient.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -94,7 +94,7 @@
NetSocket.disconnectFromHost();
}
-void HWNewNet::CreateRoom(const QString & room)
+void HWNewNet::CreateRoom(const QString & room, const QString & password)
{
if(netClientState != InLobby)
{
@@ -104,11 +104,15 @@
myroom = room;
- RawSendNet(QString("CREATE_ROOM%1%2").arg(delimeter).arg(room));
+ if(password.isEmpty())
+ RawSendNet(QString("CREATE_ROOM%1%2").arg(delimeter).arg(room));
+ else
+ RawSendNet(QString("CREATE_ROOM%1%2%1%3").arg(delimeter).arg(room).arg(password));
+
isChief = true;
}
-void HWNewNet::JoinRoom(const QString & room)
+void HWNewNet::JoinRoom(const QString & room, const QString &password)
{
if(netClientState != InLobby)
{
@@ -118,7 +122,11 @@
myroom = room;
- RawSendNet(QString("JOIN_ROOM%1%2").arg(delimeter).arg(room));
+ if(password.isEmpty())
+ RawSendNet(QString("JOIN_ROOM%1%2").arg(delimeter).arg(room));
+ else
+ RawSendNet(QString("JOIN_ROOM%1%2%1%3").arg(delimeter).arg(room).arg(password));
+
isChief = false;
}
@@ -436,6 +444,16 @@
foreach(const QString & nick, nicks)
m_playersModel->setFlag(nick, PlayersListModel::Registered, setFlag);
break;
+ // flag indicating if a player is in room
+ case 'i':
+ foreach(const QString & nick, nicks)
+ m_playersModel->setFlag(nick, PlayersListModel::InRoom, setFlag);
+ break;
+ // flag indicating if a player is contributor
+ case 'c':
+ foreach(const QString & nick, nicks)
+ m_playersModel->setFlag(nick, PlayersListModel::InRoom, setFlag);
+ break;
// flag indicating if a player has engine running
case 'g':
if(inRoom)
@@ -1055,10 +1073,11 @@
switch(n)
{
case 0:
- {
emit NickTaken(mynick);
break;
- }
+ case 2:
+ emit askForRoomPassword();
+ break;
}
}
@@ -1076,3 +1095,9 @@
{
return m_roomPlayersModel;
}
+
+void HWNewNet::roomPasswordEntered(const QString &password)
+{
+ if(!myroom.isEmpty())
+ JoinRoom(myroom, password);
+}
--- a/QTfrontend/net/newnetclient.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/net/newnetclient.h Mon Oct 28 14:07:04 2013 +0100
@@ -76,6 +76,7 @@
PlayersListModel * m_playersModel;
QSortFilterProxyModel * m_lobbyPlayersModel;
QSortFilterProxyModel * m_roomPlayersModel;
+ QString m_lastRoom;
QStringList cmdbuf;
@@ -103,6 +104,7 @@
void adminAccess(bool);
void roomMaster(bool);
void roomNameUpdated(const QString & name);
+ void askForRoomPassword();
void netSchemeConfig(QStringList &);
void paramChanged(const QString & param, const QStringList & value);
@@ -153,8 +155,8 @@
void setLatestProtocolVar(int proto);
void askServerVars();
- void JoinRoom(const QString & room);
- void CreateRoom(const QString & room);
+ void JoinRoom(const QString & room, const QString & password);
+ void CreateRoom(const QString & room, const QString &password);
void updateRoomName(const QString &);
void askRoomsList();
void gameFinished(bool correcly);
@@ -173,6 +175,7 @@
void removeBan(const QString &);
void banIP(const QString & ip, const QString & reason, int seconds);
void banNick(const QString & nick, const QString & reason, int seconds);
+ void roomPasswordEntered(const QString & password);
private slots:
void ClientRead();
Binary file QTfrontend/res/chat/hedgehogcontributor.png has changed
Binary file QTfrontend/res/chat/hedgehogcontributor_gray.png has changed
Binary file QTfrontend/res/chat/roomadmincontributor.png has changed
Binary file QTfrontend/res/chat/roomadmincontributor_gray.png has changed
Binary file QTfrontend/res/iconEarth.png has changed
--- a/QTfrontend/team.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/team.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -261,7 +261,7 @@
return true;
}
-QStringList HWTeam::teamGameConfig(quint32 InitHealth, GameUIConfig * config) const
+QStringList HWTeam::teamGameConfig(quint32 InitHealth) const
{
QStringList sl;
if (m_isNetTeam)
--- a/QTfrontend/team.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/team.h Mon Oct 28 14:07:04 2013 +0100
@@ -93,7 +93,7 @@
void incWins();
// convert team info into strings for further computation
- QStringList teamGameConfig(quint32 InitHealth, GameUIConfig * config) const;
+ QStringList teamGameConfig(quint32 InitHealth) const;
// comparison operators
bool operator == (const HWTeam& t1) const;
--- a/QTfrontend/ui/mouseoverfilter.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/mouseoverfilter.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -49,8 +49,6 @@
{
SDLInteraction::instance().playSoundFile("/Sounds/steps.ogg");
}
-
- return true;
}
else if (event->type() == QEvent::Leave)
{
@@ -63,7 +61,6 @@
else
abstractpage->setButtonDescription("");
}
-
return false;
}
--- a/QTfrontend/ui/page/pagedrawmap.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pagedrawmap.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -20,6 +20,7 @@
#include <QPushButton>
#include <QFileDialog>
#include <QCheckBox>
+#include <QRadioButton>
#include "pagedrawmap.h"
#include "drawmapwidget.h"
@@ -32,12 +33,22 @@
cbEraser = new QCheckBox(tr("Eraser"), this);
pageLayout->addWidget(cbEraser, 0, 0);
pbUndo = addButton(tr("Undo"), pageLayout, 1, 0);
- pbClear = addButton(tr("Clear"), pageLayout, 2, 0);
- pbLoad = addButton(tr("Load"), pageLayout, 3, 0);
- pbSave = addButton(tr("Save"), pageLayout, 4, 0);
+
+ rbPolyline = new QRadioButton(tr("Polyline"), this);
+ pageLayout->addWidget(rbPolyline, 2, 0);
+ rbRectangle = new QRadioButton(tr("Rectangle"), this);
+ pageLayout->addWidget(rbRectangle, 3, 0);
+ rbEllipse = new QRadioButton(tr("Ellipse"), this);
+ pageLayout->addWidget(rbEllipse, 4, 0);
+
+ rbPolyline->setChecked(true);
+
+ pbClear = addButton(tr("Clear"), pageLayout, 5, 0);
+ pbLoad = addButton(tr("Load"), pageLayout, 6, 0);
+ pbSave = addButton(tr("Save"), pageLayout, 7, 0);
drawMapWidget = new DrawMapWidget(this);
- pageLayout->addWidget(drawMapWidget, 0, 1, 6, 1);
+ pageLayout->addWidget(drawMapWidget, 0, 1, 9, 1);
return pageLayout;
}
@@ -49,6 +60,10 @@
connect(pbClear, SIGNAL(clicked()), drawMapWidget, SLOT(clear()));
connect(pbLoad, SIGNAL(clicked()), this, SLOT(load()));
connect(pbSave, SIGNAL(clicked()), this, SLOT(save()));
+
+ connect(rbPolyline, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool)));
+ connect(rbRectangle, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool)));
+ connect(rbEllipse, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool)));
}
PageDrawMap::PageDrawMap(QWidget* parent) : AbstractPage(parent)
@@ -71,3 +86,13 @@
if(!fileName.isEmpty())
drawMapWidget->save(fileName);
}
+
+void PageDrawMap::pathTypeSwitched(bool b)
+{
+ if(b)
+ {
+ if(rbPolyline->isChecked()) drawMapWidget->setPathType(DrawMapScene::Polyline);
+ else if(rbRectangle->isChecked()) drawMapWidget->setPathType(DrawMapScene::Rectangle);
+ else if(rbEllipse->isChecked()) drawMapWidget->setPathType(DrawMapScene::Ellipse);
+ }
+}
--- a/QTfrontend/ui/page/pagedrawmap.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pagedrawmap.h Mon Oct 28 14:07:04 2013 +0100
@@ -22,6 +22,7 @@
#include "AbstractPage.h"
class DrawMapWidget;
+class QRadioButton;
class PageDrawMap : public AbstractPage
{
@@ -42,10 +43,14 @@
QPushButton * pbLoad;
QPushButton * pbSave;
QCheckBox * cbEraser;
+ QRadioButton * rbPolyline;
+ QRadioButton * rbRectangle;
+ QRadioButton * rbEllipse;
private slots:
void load();
void save();
+ void pathTypeSwitched(bool b);
};
#endif
--- a/QTfrontend/ui/page/pageeditteam.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pageeditteam.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -203,12 +203,18 @@
{
initPage();
- QRegExp pngSuffix("\\.png$");
+ m_playerHash = "0000000000000000000000000000000000000000";
+ m_loaded = false;
+}
- m_playerHash = "0000000000000000000000000000000000000000";
+void PageEditTeam::lazyLoad()
+{
+ if(m_loaded) return;
+ m_loaded = true;
+ qDebug("[LAZYNESS] PageEditTeam::lazyLoad()");
+ QRegExp pngSuffix("\\.png$");
DataManager & dataMgr = DataManager::instance();
-
QStringList list;
@@ -236,7 +242,7 @@
pix = pix.copy(0, 0, 32, 32);
QIcon icon(pix);
- QString grave = QString(file).remove(pngSuffix);
+ QString grave = file.remove(pngSuffix);
CBGrave->addItem(icon, grave);
}
@@ -327,6 +333,8 @@
void PageEditTeam::createTeam(const QString & name, const QString & playerHash)
{
m_playerHash = playerHash;
+ lazyLoad();
+
HWTeam newTeam(name);
loadTeam(newTeam);
}
@@ -334,6 +342,8 @@
void PageEditTeam::editTeam(const QString & name, const QString & playerHash)
{
m_playerHash = playerHash;
+ lazyLoad();
+
HWTeam team(name);
team.loadFromFile();
loadTeam(team);
--- a/QTfrontend/ui/page/pageeditteam.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pageeditteam.h Mon Oct 28 14:07:04 2013 +0100
@@ -66,6 +66,7 @@
HWTeam data();
QString m_playerHash;
KeyBinder * binder;
+ bool m_loaded;
QLayout * bodyLayoutDefinition();
QLayout * footerLayoutDefinition();
@@ -78,6 +79,8 @@
QPushButton * btnRandomTeam;
QPushButton * btnTestSound;
+ void lazyLoad();
+
private slots:
void saveTeam();
void setRandomNames();
--- a/QTfrontend/ui/page/pageroomslist.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pageroomslist.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -531,17 +531,17 @@
void PageRoomsList::onCreateClick()
{
- RoomNamePrompt prompt(parentWidget()->parentWidget(), m_gameSettings->value("frontend/lastroomname", QString()).toString());
- connect(&prompt, SIGNAL(roomNameChosen(const QString &)), this, SLOT(onRoomNameChosen(const QString &)));
- prompt.exec();
+ RoomNamePrompt prompt(this, m_gameSettings->value("frontend/lastroomname", QString()).toString());
+ if(prompt.exec())
+ onRoomNameChosen(prompt.getRoomName(), prompt.getPassword());
}
-void PageRoomsList::onRoomNameChosen(const QString & roomName)
+void PageRoomsList::onRoomNameChosen(const QString & roomName, const QString & password)
{
if (!roomName.trimmed().isEmpty())
{
m_gameSettings->setValue("frontend/lastroomname", roomName);
- emit askForCreateRoom(roomName);
+ emit askForCreateRoom(roomName, password);
}
else
{
@@ -570,7 +570,7 @@
if (!gameInLobby)
emit askJoinConfirmation(roomName);
else
- emit askForJoinRoom(roomName);
+ emit askForJoinRoom(roomName, QString());
}
void PageRoomsList::onRefreshClick()
@@ -600,7 +600,7 @@
if (reallyJoinMsg.exec() == QMessageBox::Ok)
{
- emit askForJoinRoom(room);
+ emit askForJoinRoom(room, QString());
}
}
--- a/QTfrontend/ui/page/pageroomslist.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pageroomslist.h Mon Oct 28 14:07:04 2013 +0100
@@ -70,8 +70,8 @@
void updateNickCounter(int cnt);
signals:
- void askForCreateRoom(const QString &);
- void askForJoinRoom(const QString &);
+ void askForCreateRoom(const QString &, const QString &);
+ void askForJoinRoom(const QString &, const QString &);
void askForRoomList();
void askJoinConfirmation(const QString &);
@@ -89,7 +89,7 @@
void onSortIndicatorChanged(int logicalIndex, Qt::SortOrder order);
void onFilterChanged();
void saveHeaderState();
- void onRoomNameChosen(const QString &);
+ void onRoomNameChosen(const QString &, const QString &password);
void roomSelectionChanged(const QModelIndex &, const QModelIndex &);
void moveSelectionUp();
void moveSelectionDown();
--- a/QTfrontend/ui/page/pagescheme.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pagescheme.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -383,6 +383,23 @@
glBSLayout->addWidget(SB_GetAwayTime,14,2,1,1);
l = new QLabel(gbBasicSettings);
+ l->setText(QLabel::tr("World Edge"));
+ l->setWordWrap(true);
+ glBSLayout->addWidget(l,15,0,1,1);
+ l = new QLabel(gbBasicSettings);
+ l->setFixedSize(32,32);
+ l->setPixmap(QPixmap(":/res/iconEarth.png"));
+ glBSLayout->addWidget(l,15,1,1,1);
+ CB_WorldEdge = new QComboBox(gbBasicSettings);
+ CB_WorldEdge->insertItem(0, tr("None (Default)"));
+ CB_WorldEdge->insertItem(1, tr("Wrap (World wraps)"));
+ CB_WorldEdge->insertItem(2, tr("Bounce (Edges reflect)"));
+ CB_WorldEdge->insertItem(3, tr("Sea (Edges connect to sea)"));
+ /* CB_WorldEdge->insertItem(4, tr("Skybox")); */
+ glBSLayout->addWidget(CB_WorldEdge,15,2,1,1);
+
+
+ l = new QLabel(gbBasicSettings);
l->setText(QLabel::tr("Scheme Name:"));
LE_name = new QLineEdit(this);
@@ -471,6 +488,7 @@
mapper->addMapping(SB_HealthDecrease, 38);
mapper->addMapping(SB_RopeModifier, 39);
mapper->addMapping(SB_GetAwayTime, 40);
+ mapper->addMapping(CB_WorldEdge, 41, "currentIndex");
mapper->toFirst();
}
--- a/QTfrontend/ui/page/pagescheme.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/page/pagescheme.h Mon Oct 28 14:07:04 2013 +0100
@@ -91,6 +91,7 @@
QSpinBox * SB_Explosives;
QSpinBox * SB_RopeModifier;
QSpinBox * SB_GetAwayTime;
+ QComboBox * CB_WorldEdge;
QLineEdit * LE_name;
QGroupBox * gbGameModes;
--- a/QTfrontend/ui/widget/chatwidget.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/chatwidget.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -930,3 +930,17 @@
chatText->verticalScrollBar()->setValue(m_scrollBarPos);
}
}
+
+void HWChatWidget::resizeEvent(QResizeEvent * event)
+{
+ Q_UNUSED(event);
+
+ afterContentAdd();
+}
+
+void HWChatWidget::showEvent(QShowEvent * event)
+{
+ Q_UNUSED(event);
+
+ afterContentAdd();
+}
--- a/QTfrontend/ui/widget/chatwidget.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/chatwidget.h Mon Oct 28 14:07:04 2013 +0100
@@ -68,6 +68,8 @@
protected:
virtual void dragEnterEvent(QDragEnterEvent * event);
virtual void dropEvent(QDropEvent * event);
+ virtual void resizeEvent(QResizeEvent * event);
+ virtual void showEvent(QShowEvent * event);
private:
static QString * s_styleSheet;
--- a/QTfrontend/ui/widget/drawmapwidget.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/drawmapwidget.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -123,6 +123,11 @@
if(m_scene) m_scene->setErasing(erasing);
}
+void DrawMapWidget::setPathType(DrawMapScene::PathType pathType)
+{
+ if(m_scene) m_scene->setPathType(pathType);
+}
+
void DrawMapWidget::save(const QString & fileName)
{
if(m_scene)
@@ -160,6 +165,7 @@
}
else
m_scene->decode(qUncompress(QByteArray::fromBase64(f.readAll())));
+ //m_scene->decode(f.readAll());
}
}
@@ -191,7 +197,7 @@
QGraphicsView::setScene(scene);
}
-// Why don't I ever recieve this event?
+// Why don't I ever receive this event?
void DrawMapView::enterEvent(QEvent *event)
{
if(m_scene)
--- a/QTfrontend/ui/widget/drawmapwidget.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/drawmapwidget.h Mon Oct 28 14:07:04 2013 +0100
@@ -100,6 +100,7 @@
void setErasing(bool erasing);
void save(const QString & fileName);
void load(const QString & fileName);
+ void setPathType(DrawMapScene::PathType pathType);
protected:
void changeEvent(QEvent *e);
--- a/QTfrontend/ui/widget/gamecfgwidget.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/gamecfgwidget.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -321,6 +321,7 @@
bcfg << QString("e$healthdec %1").arg(schemeData(38).toInt()).toUtf8();
bcfg << QString("e$ropepct %1").arg(schemeData(39).toInt()).toUtf8();
bcfg << QString("e$getawaytime %1").arg(schemeData(40).toInt()).toUtf8();
+ bcfg << QString("e$worldedge %1").arg(schemeData(41).toInt()).toUtf8();
bcfg << QString("e$template_filter %1").arg(pMapContainer->getTemplateFilter()).toUtf8();
bcfg << QString("e$mapgen %1").arg(mapgen).toUtf8();
--- a/QTfrontend/ui/widget/roomnameprompt.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/roomnameprompt.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -23,6 +23,7 @@
#include <QLineEdit>
#include <QLabel>
#include <QDebug>
+#include <QCheckBox>
#include "roomnameprompt.h"
@@ -32,24 +33,34 @@
setWindowFlags(Qt::Sheet);
setWindowModality(Qt::WindowModal);
setMinimumSize(360, 130);
- resize(360, 130);
+ resize(360, 180);
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
// Layout
QVBoxLayout * dialogLayout = new QVBoxLayout(this);
// Label
- label = new QLabel(tr("Enter a name for your room."));
+ label = new QLabel(tr("Enter a name for your room."), this);
label->setWordWrap(true);
- dialogLayout->addWidget(label, 0);
+ dialogLayout->addWidget(label);
// Input box
- editBox = new QLineEdit();
- editBox->setText(roomName);
- editBox->setMaxLength(59); // It didn't like 60 :(
- editBox->setStyleSheet("QLineEdit { padding: 3px; }");
- editBox->selectAll();
- dialogLayout->addWidget(editBox, 1);
+ leRoomName = new QLineEdit(this);
+ leRoomName->setText(roomName);
+ leRoomName->setMaxLength(59); // It didn't like 60 :(
+ leRoomName->setStyleSheet("QLineEdit { padding: 3px; }");
+ leRoomName->selectAll();
+ dialogLayout->addWidget(leRoomName);
+
+ cbSetPassword = new QCheckBox(this);
+ cbSetPassword->setText(tr("set password"));
+ dialogLayout->addWidget(cbSetPassword);
+
+ lePassword = new QLineEdit(this);
+ lePassword->setMaxLength(30);
+ lePassword->setStyleSheet("QLineEdit { padding: 3px; }");
+ lePassword->setEnabled(false);
+ dialogLayout->addWidget(lePassword);
dialogLayout->addStretch(1);
@@ -73,10 +84,20 @@
setStyleSheet("QPushButton { padding: 5px; }");
- connect(btnOkay, SIGNAL(clicked()), this, SLOT(setRoomName()));
+ connect(cbSetPassword, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled()));
+}
+
+QString RoomNamePrompt::getRoomName()
+{
+ return leRoomName->text();
}
-void RoomNamePrompt::setRoomName()
+QString RoomNamePrompt::getPassword()
{
- emit roomNameChosen(editBox->text());
+ return lePassword->text();
}
+
+void RoomNamePrompt::checkBoxToggled()
+{
+ lePassword->setEnabled(cbSetPassword->isChecked());
+}
--- a/QTfrontend/ui/widget/roomnameprompt.h Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/roomnameprompt.h Mon Oct 28 14:07:04 2013 +0100
@@ -23,6 +23,7 @@
class QLineEdit;
class QLabel;
+class QCheckBox;
class RoomNamePrompt : public QDialog
{
@@ -30,16 +31,17 @@
public:
RoomNamePrompt(QWidget* parent, const QString & roomName);
+ QString getRoomName();
+ QString getPassword();
- signals:
- void roomNameChosen(const QString & roomName);
+ private:
+ QLineEdit * leRoomName;
+ QLabel * label;
+ QCheckBox * cbSetPassword;
+ QLineEdit * lePassword;
private slots:
- void setRoomName();
-
- private:
- QLineEdit * editBox;
- QLabel * label;
+ void checkBoxToggled();
};
#endif // ROOMNAMEPROMPT_H
--- a/QTfrontend/ui/widget/teamselhelper.cpp Wed Sep 25 05:42:16 2013 +0300
+++ b/QTfrontend/ui/widget/teamselhelper.cpp Mon Oct 28 14:07:04 2013 +0100
@@ -55,7 +55,7 @@
butt = new QPushButton(difficultyIcon, team.name().replace("&","&&"), this);
butt->setFlat(true);
- butt->setWhatsThis(tr("%1's team").arg(team.owner()));
+ butt->setToolTip(team.owner());
mainLayout.addWidget(butt);
butt->setStyleSheet("QPushButton{"
"icon-size: 48px;"
--- a/cmake_modules/CMakeDeterminePascalCompiler.cmake Wed Sep 25 05:42:16 2013 +0300
+++ b/cmake_modules/CMakeDeterminePascalCompiler.cmake Mon Oct 28 14:07:04 2013 +0100
@@ -5,6 +5,9 @@
# the cmake variable CMAKE_GENERATOR_PASCAL which can be defined by a generator
# as a default compiler
+# NOTE: on Darwin cmake >= 2.8.11 until cmake <= 2.8.12.1 will add an incompatible
+# -F flag to <FLAGS> so you won't be able to use those versions with this script
+
if(NOT CMAKE_Pascal_COMPILER)
# prefer the environment variable FPC
if($ENV{FPC} MATCHES ".+")
--- a/cmake_modules/CMakePascalInformation.cmake Wed Sep 25 05:42:16 2013 +0300
+++ b/cmake_modules/CMakePascalInformation.cmake Mon Oct 28 14:07:04 2013 +0100
@@ -2,6 +2,7 @@
# It also loads the available platform file for the system-compiler
# if it exists.
+# in case fpc ever becomes included in cmake
get_filename_component(CMAKE_BASE_NAME ${CMAKE_Pascal_COMPILER} NAME_WE)
set(CMAKE_SYSTEM_AND_Pascal_COMPILER_INFO_FILE
${CMAKE_ROOT}/Modules/Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}.cmake)
@@ -33,17 +34,18 @@
# No flags supported during linking as a shell script takes care of it
# however to avoid interferences we escape -Wl flags to the Pascal -k
-if(NOT CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS)
-#-shared
- string(REGEX REPLACE "-Wl," "-k" CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
-endif(NOT CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS)
+#if(NOT CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS)
+#-shared (linux) / -dynamiclib -Wl,-headerpad_max_install_names (darwin)
+# string(REGEX REPLACE "-Wl," "-k" CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
+#endif(NOT CMAKE_SHARED_LIBRARY_CREATE_Pascal_FLAGS)
if(NOT CMAKE_SHARED_LIBRARY_Pascal_FLAGS AND CMAKE_SHARED_LIBRARY_C_FLAGS)
+#-fPIC
string(REGEX REPLACE "-Wl," "-k" CMAKE_SHARED_LIBRARY_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
endif()
if(NOT CMAKE_SHARED_LIBRARY_LINK_Pascal_FLAGS AND CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
-#-rdynamic
+#-rdynamic (linux) / (empty on darwin)
string(REGEX REPLACE "-Wl," "-k" CMAKE_SHARED_LIBRARY_LINK_Pascal_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS})
endif()
@@ -70,9 +72,10 @@
endif(NOT CMAKE_MODULE_EXISTS)
# repeat for modules
-if(NOT CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS)
+if(NOT CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS AND CMAKE_SHARED_MODULE_CREATE_C_FLAGS)
+# ? (linux) / -bundle -Wl,-headerpad_max_install_names (darwin)
string(REGEX REPLACE "-Wl," "-k" CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS ${CMAKE_SHARED_MODULE_CREATE_C_FLAGS})
-endif(NOT CMAKE_SHARED_MODULE_CREATE_Pascal_FLAGS)
+endif()
if(NOT CMAKE_SHARED_MODULE_Pascal_FLAGS AND CMAKE_SHARED_MODULE_C_FLAGS)
string(REGEX REPLACE "-Wl," "-k" CMAKE_SHARED_MODULE_Pascal_FLAGS ${CMAKE_SHARED_MODULE_C_FLAGS})
@@ -86,6 +89,7 @@
set(CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG_SEP ${CMAKE_SHARED_MODULE_RUNTIME_C_FLAG_SEP})
endif(NOT CMAKE_SHARED_MODULE_RUNTIME_Pascal_FLAG_SEP)
+# now other system things
if(NOT CMAKE_INCLUDE_FLAG_Pascal)
#amazing, fpc: -I<x> Add <x> to include path
set(CMAKE_INCLUDE_FLAG_Pascal ${CMAKE_INCLUDE_FLAG_C})
@@ -95,8 +99,14 @@
set(CMAKE_INCLUDE_FLAG_SEP_Pascal ${CMAKE_INCLUDE_FLAG_SEP_C})
endif(NOT CMAKE_INCLUDE_FLAG_SEP_Pascal)
+if(NOT CMAKE_Pascal_FRAMEWORK_SEARCH_FLAG)
+ #however -F won't work, -Ff is Pascal equivalent
+ set(CMAKE_Pascal_FRAMEWORK_SEARCH_FLAG "-Ff")
+endif(NOT CMAKE_Pascal_FRAMEWORK_SEARCH_FLAG)
+
# Copy C version of this flag which is normally determined in platform file.
if(NOT CMAKE_SHARED_LIBRARY_SONAME_Pascal_FLAG)
+#-soname (linux) / -install-name (dawin)
set(CMAKE_SHARED_LIBRARY_SONAME_Pascal_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_C_FLAG})
endif(NOT CMAKE_SHARED_LIBRARY_SONAME_Pascal_FLAG)
--- a/cmake_modules/platform.cmake Wed Sep 25 05:42:16 2013 +0300
+++ b/cmake_modules/platform.cmake Mon Oct 28 14:07:04 2013 +0100
@@ -1,5 +1,10 @@
if(APPLE)
+ if(${CMAKE_VERSION} VERSION_GREATER "2.8.10.2" AND
+ ${CMAKE_VERSION} VERSION_LESS "2.8.12.1")
+ message(FATAL_ERROR "This version of CMake is known *not* to work, please update or use a lower version")
+ endif()
+
set(CMAKE_FIND_FRAMEWORK "FIRST")
#what system are we building for
--- a/gameServer/Actions.hs Wed Sep 25 05:42:16 2013 +0300
+++ b/gameServer/Actions.hs Mon Oct 28 14:07:04 2013 +0100
@@ -456,6 +456,7 @@
processAction JoinLobby = do
chan <- client's sendChan
+ rnc <- gets roomsClients
clientNick <- client's nick
isAuthenticated <- liftM (not . B.null) $ client's webPassword
isAdmin <- client's isAdministrator
@@ -465,6 +466,10 @@
let authenticatedNicks = L.map nick . L.filter (not . B.null . webPassword) $ loggedInClients
let adminsNicks = L.map nick . L.filter isAdministrator $ loggedInClients
let contrNicks = L.map nick . L.filter isContributor $ loggedInClients
+ inRoomNicks <- io $
+ allClientsM rnc
+ >>= filterM (liftM ((/=) lobbyId) . clientRoomM rnc)
+ >>= mapM (client'sM rnc nick)
let clFlags = B.concat . L.concat $ [["u" | isAuthenticated], ["a" | isAdmin], ["c" | isContr]]
mapM_ processAction . concat $ [
[AnswerClients clientsChans ["LOBBY:JOINED", clientNick]]
@@ -472,6 +477,7 @@
, [AnswerClients [chan] ("CLIENT_FLAGS" : "+u" : authenticatedNicks) | not $ null authenticatedNicks]
, [AnswerClients [chan] ("CLIENT_FLAGS" : "+a" : adminsNicks) | not $ null adminsNicks]
, [AnswerClients [chan] ("CLIENT_FLAGS" : "+c" : contrNicks) | not $ null contrNicks]
+ , [AnswerClients [chan] ("CLIENT_FLAGS" : "+i" : inRoomNicks) | not $ null inRoomNicks]
, [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags]
, [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})]
, [SendServerMessage]
--- a/gameServer/CoreTypes.hs Wed Sep 25 05:42:16 2013 +0300
+++ b/gameServer/CoreTypes.hs Mon Oct 28 14:07:04 2013 +0100
@@ -101,7 +101,6 @@
logonPassed :: Bool,
isVisible :: Bool,
clientProto :: !Word16,
- roomID :: RoomIndex,
pingsQueue :: !Word,
isMaster :: Bool,
isReady :: !Bool,
--- a/gameServer/NetRoutines.hs Wed Sep 25 05:42:16 2013 +0300
+++ b/gameServer/NetRoutines.hs Mon Oct 28 14:07:04 2013 +0100
@@ -36,7 +36,6 @@
False
False
0
- lobbyId
0
False
False
--- a/gameServer/OfficialServer/checker.hs Wed Sep 25 05:42:16 2013 +0300
+++ b/gameServer/OfficialServer/checker.hs Mon Oct 28 14:07:04 2013 +0100
@@ -171,7 +171,7 @@
Right (login, password) <- runErrorT $ do
d <- liftIO $ getHomeDirectory
- conf <- join . liftIO . CF.readfile CF.emptyCP $ d ++ "/.hedgewars/hedgewars.ini"
+ conf <- join . liftIO . CF.readfile CF.emptyCP $ d ++ "/.hedgewars/settings.ini"
l <- CF.get conf "net" "nick"
p <- CF.get conf "net" "passwordhash"
return (B.pack l, B.pack p)
--- a/hedgewars/hwengine.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/hwengine.pas Mon Oct 28 14:07:04 2013 +0100
@@ -32,7 +32,7 @@
uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler
, uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uAILandMarks, uLandTexture, uCollisions
, SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
- , uPhysFSLayer, uCursor, uRandom, ArgParsers, uVisualGearsHandlers
+ , uPhysFSLayer, uCursor, uRandom, ArgParsers, uVisualGearsHandlers, uTextures
{$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF}
{$IFDEF USE_TOUCH_INTERFACE}, uTouch {$ENDIF}
{$IFDEF ANDROID}, GLUnit{$ENDIF}
@@ -441,9 +441,10 @@
if complete then
begin
uPhysFSLayer.initModule;
+ uTextures.initModule;
{$IFDEF ANDROID}GLUnit.initModule;{$ENDIF}
{$IFDEF USE_TOUCH_INTERFACE}uTouch.initModule;{$ENDIF}
-{$IFDEF USE_VIDEO_RECORDING}uVideoRec.initModule;{$ENDIF} //stub
+{$IFDEF USE_VIDEO_RECORDING}uVideoRec.initModule;{$ENDIF}
uAI.initModule;
uAIMisc.initModule;
uAILandMarks.initModule; //stub
@@ -453,7 +454,7 @@
uChat.initModule;
uCollisions.initModule;
uGears.initModule;
- uInputHandler.initModule; //stub
+ uInputHandler.initModule;
uMisc.initModule;
uLandTexture.initModule; //stub
uScript.initModule;
@@ -493,6 +494,7 @@
{$IFDEF USE_VIDEO_RECORDING}uVideoRec.freeModule;{$ENDIF}
{$IFDEF USE_TOUCH_INTERFACE}uTouch.freeModule;{$ENDIF} //stub
{$IFDEF ANDROID}GLUnit.freeModule;{$ENDIF}
+ uTextures.freeModule;
uPhysFSLayer.freeModule;
end;
--- a/hedgewars/uAI.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uAI.pas Mon Oct 28 14:07:04 2013 +0100
@@ -106,7 +106,7 @@
procedure TestAmmos(var Actions: TActions; Me: PGear; rareChecks: boolean);
var BotLevel: Byte;
ap: TAttackParams;
- Score, i, dAngle: LongInt;
+ Score, i, t, n, dAngle: LongInt;
a, aa: TAmmoType;
begin
BotLevel:= Me^.Hedgehog^.BotLevel;
@@ -182,7 +182,15 @@
end else
if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then
begin
+ if (AmmoTests[a].flags and amtest_MultipleAttacks) = 0 then
+ n:= 1 else n:= ap.AttacksNum;
+
AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0);
+ for t:= 2 to n do
+ begin
+ AddAction(BestActions, aia_attack, aim_push, 150, 0, 0);
+ AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
+ end;
AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
end;
--- a/hedgewars/uAIAmmoTests.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uAIAmmoTests.pas Mon Oct 28 14:07:04 2013 +0100
@@ -22,13 +22,14 @@
interface
uses uConsts, uFloat, uTypes, uAIMisc;
const
- amtest_Rare = $00000001; // check only several positions
- amtest_NoTarget = $00000002; // each pos, but no targetting
+ amtest_Rare = $00000001; // check only several positions
+ amtest_NoTarget = $00000002; // each pos, but no targetting
+ amtest_MultipleAttacks = $00000004; // test could result in multiple attacks, set AttacksNum
var windSpeed: real;
type TAttackParams = record
- Time: Longword;
+ Time, AttacksNum: Longword;
Angle, Power: LongInt;
ExplX, ExplY, ExplR: LongInt;
AttackPutX, AttackPutY: LongInt;
@@ -72,7 +73,7 @@
(proc: nil; flags: 0), // amSkip
(proc: nil; flags: 0), // amRope
(proc: nil; flags: 0), // amMine
- (proc: @TestDesertEagle; flags: 0), // amDEagle
+ (proc: @TestDesertEagle; flags: amtest_MultipleAttacks), // amDEagle
(proc: nil; flags: 0), // amDynamite
(proc: @TestFirePunch; flags: amtest_NoTarget), // amFirePunch
(proc: @TestWhip; flags: amtest_NoTarget), // amWhip
@@ -715,8 +716,13 @@
or (d > 48);
if Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 5 then
- valueResult:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, 7, 20, vX*0.125, vY*0.125, afTrackFall)
-else valueResult:= BadTurn;
+ begin
+ ap.AttacksNum:= 1 + (d + 8) div 12;
+ valueResult:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, 7, 20, vX*0.125, vY*0.125, afTrackFall) - ap.AttacksNum
+ end
+else
+ valueResult:= BadTurn;
+
TestDesertEagle:= valueResult
end;
--- a/hedgewars/uChat.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uChat.pas Mon Oct 28 14:07:04 2013 +0100
@@ -41,7 +41,7 @@
Width: LongInt;
s: shortstring;
end;
- TChatCmd = (quit, pause, finish, fullscreen);
+ TChatCmd = (quit, pause, finish, showhistory, fullscreen);
var Strs: array[0 .. MaxStrIndex] of TChatLine;
MStrs: array[0 .. MaxStrIndex] of shortstring;
@@ -73,6 +73,7 @@
(ChatCmd: '/quit'; ProcedureCallChatCmd: 'halt'),
(ChatCmd: '/pause'; ProcedureCallChatCmd: 'pause'),
(ChatCmd: '/finish'; ProcedureCallChatCmd: 'finish'),
+ (ChatCmd: '/history'; ProcedureCallChatCmd: 'history'),
(ChatCmd: '/fullscreen'; ProcedureCallChatCmd: 'fullscr')
);
--- a/hedgewars/uCommandHandlers.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uCommandHandlers.pas Mon Oct 28 14:07:04 2013 +0100
@@ -797,6 +797,11 @@
CampaignVariable := s;
end;
+procedure chWorldEdge(var s: shortstring);
+begin
+WorldEdge:= TWorldEdge(StrToInt(s))
+end;
+
procedure initModule;
begin
//////// Begin top sorted by freq analysis not including chatmsg
@@ -882,6 +887,7 @@
RegisterVariable('-cur_r' , @chCurR_m , true );
RegisterVariable('campvar' , @chCampVar , true );
RegisterVariable('record' , @chRecord , true );
+ RegisterVariable('worldedge',@chWorldEdge , false);
end;
procedure freeModule;
--- a/hedgewars/uConsts.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uConsts.pas Mon Oct 28 14:07:04 2013 +0100
@@ -250,6 +250,8 @@
ammoprop_NeedTarget = $00000004;
ammoprop_ForwMsgs = $00000008;
ammoprop_AttackInMove = $00000010;
+ ammoprop_DoesntStopTimerWhileAttacking
+ = $00000020;
ammoprop_NoCrosshair = $00000040;
ammoprop_AttackingPut = $00000080;
ammoprop_DontHold = $00000100;
@@ -263,6 +265,8 @@
ammoprop_OscAim = $00010000;
ammoprop_NoMoveAfter = $00020000;
ammoprop_Track = $00040000;
+ ammoprop_DoesntStopTimerInMultiShoot
+ = $00080000;
ammoprop_NoRoundEnd = $10000000;
AMMO_INFINITE = 100;
--- a/hedgewars/uGears.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uGears.pas Mon Oct 28 14:07:04 2013 +0100
@@ -401,7 +401,8 @@
if (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.State and gstAttacked = 0)
and (CurAmmoGear = nil) then
SweepDirty;
- CheckNoDamage;
+ if (CurrentHedgehog^.Gear = nil) or (CurrentHedgehog^.Gear^.State and gstHHDriven = 0) or (CurrentHedgehog^.Gear^.Damage = 0) then
+ CheckNoDamage;
AliveCount:= 0; // shorter version of check for win to allow typical step activity to proceed
for i:= 0 to Pred(ClansCount) do
if ClansArray[i]^.ClanHealth > 0 then
@@ -419,8 +420,10 @@
if TurnTimeLeft > 0 then
if CurrentHedgehog^.Gear <> nil then
- if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) and
- not(isInMultiShoot and (CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])) then
+ if (((CurrentHedgehog^.Gear^.State and gstAttacking) = 0)
+ or (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_DoesntStopTimerWhileAttacking <> 0))
+ and not(isInMultiShoot and ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_DoesntStopTimerInMultiShoot) <> 0)) then
+ //(CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])
begin
if (TurnTimeLeft = 5000)
and (cHedgehogTurnTime >= 10000)
--- a/hedgewars/uGearsHandlersMess.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uGearsHandlersMess.pas Mon Oct 28 14:07:04 2013 +0100
@@ -280,10 +280,18 @@
var
isFalling: boolean;
//tmp: QWord;
- tdX, tdY: hwFloat;
+ tX, tdX, tdY: hwFloat;
collV, collH: LongInt;
land: word;
begin
+ tX:= Gear^.X;
+ if (Gear^.Kind <> gtGenericFaller) and WorldWrap(Gear) and (WorldEdge = weWrap) and (Gear^.AdvBounce <> 0) and
+ (TestCollisionXwithGear(Gear, 1) or TestCollisionXwithGear(Gear, -1)) then
+ begin
+ Gear^.X:= tX;
+ Gear^.dX.isNegative:= (hwRound(tX) > leftX+Gear^.Radius*2)
+ end;
+
// clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
if Gear^.dX.Round > 2 then
Gear^.dX.QWordValue:= 8589934592;
@@ -302,8 +310,6 @@
tdX := Gear^.dX;
tdY := Gear^.dY;
-
-
// might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
@@ -384,8 +390,7 @@
Gear^.X := Gear^.X + Gear^.dX;
Gear^.Y := Gear^.Y + Gear^.dY;
- if Gear^.Kind <> gtBee then
- CheckGearDrowning(Gear);
+ CheckGearDrowning(Gear);
//if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then
Gear^.State := Gear^.State and (not gstMoving)
@@ -695,6 +700,13 @@
draw:= true;
xx:= hwRound(Gear^.X);
yy:= hwRound(Gear^.Y);
+ if draw and (WorldEdge = weWrap) and ((xx < leftX+3) or (xx > rightX-3)) then
+ begin
+ if xx < leftX+3 then
+ xx:= rightX-3
+ else xx:= leftX+3;
+ Gear^.X:= int2hwFloat(xx)
+ end
end
else if GameTicks and $7 = 0 then
begin
@@ -889,6 +901,7 @@
flower: PVisualGear;
begin
+ WorldWrap(Gear);
AllInactive := false;
gX := hwRound(Gear^.X);
gY := hwRound(Gear^.Y);
@@ -968,6 +981,7 @@
dec(Gear^.Timer)
else
begin
+ Gear^.State:= Gear^.State and not gstSubmersible;
if nuw then
begin
StopSoundChan(Gear^.SoundChannel);
@@ -1055,6 +1069,7 @@
repeat
Gear^.X := Gear^.X + Gear^.dX;
Gear^.Y := Gear^.Y + Gear^.dY;
+ WorldWrap(Gear);
CheckCollision(Gear);
if (Gear^.State and gstCollision) <> 0 then
begin
@@ -1120,7 +1135,7 @@
procedure doStepBulletWork(Gear: PGear);
var
i, x, y: LongWord;
- oX, oY: hwFloat;
+ oX, oY, tX, tY, cX, cY: hwFloat;
VGear: PVisualGear;
begin
AllInactive := false;
@@ -1131,6 +1146,22 @@
repeat
Gear^.X := Gear^.X + Gear^.dX;
Gear^.Y := Gear^.Y + Gear^.dY;
+ tX:= Gear^.X;
+ tY:= Gear^.Y;
+ if (Gear^.PortalCounter < 30) and WorldWrap(Gear) then
+ begin
+ cX:= Gear^.X;
+ cY:= Gear^.Y;
+ Gear^.X:= tX;
+ Gear^.Y:= tY;
+ SpawnBulletTrail(Gear);
+ Gear^.X:= cX;
+ Gear^.Y:= cY;
+ inc(Gear^.PortalCounter);
+ Gear^.Elasticity:= Gear^.X;
+ Gear^.Friction:= Gear^.Y;
+ SpawnBulletTrail(Gear);
+ end;
x := hwRound(Gear^.X);
y := hwRound(Gear^.Y);
@@ -1305,6 +1336,7 @@
HHGear: PGear;
begin
AllInactive := false;
+ WorldWrap(Gear);
HHGear := Gear^.Hedgehog^.Gear;
dec(Gear^.Timer);
if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
@@ -1428,6 +1460,7 @@
prevX: LongInt;
begin
AllInactive := false;
+ WorldWrap(Gear);
dec(Gear^.Timer);
if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
dec(TurnTimeLeft);
@@ -2013,6 +2046,7 @@
tdX,tdY: HWFloat;
landPixel: Word;
begin
+ WorldWrap(Gear);
sticky:= (Gear^.State and gsttmpFlag) <> 0;
if not sticky then AllInactive := false;
@@ -2378,6 +2412,7 @@
var
HHGear: PGear;
x, y, tx, ty: hwFloat;
+ rx: LongInt;
begin
AllInactive := false;
@@ -2386,8 +2421,13 @@
ty := int2hwFloat(Gear^.Target.Y);
x := HHGear^.X;
y := HHGear^.Y;
-
- if (Distance(tx - x, ty - y) > _256)
+ rx:= hwRound(x);
+
+ if ((Distance(tx - x, ty - y) > _256) and ((WorldEdge <> weWrap) or
+ (
+ (Distance(tx - int2hwFloat(rightX+(rx-leftX)), ty - y) > _256) and
+ (Distance(tx - int2hwFloat(leftX-(rightX-rx)), ty - y) > _256)
+ )))
or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false)) then
begin
PlaySound(sndDenied);
@@ -3187,11 +3227,26 @@
var
HHGear: PGear;
i: LongInt;
- dX, dY: hwFloat;
+ dX, dY, X, Y : hwFloat;
fChanged: boolean;
trueAngle: Longword;
t: PGear;
begin
+ if WorldWrap(Gear) and (WorldEdge <> weWrap) then
+ begin
+ Y.isNegative:= false;
+ Y.QWordValue:= 4294967296 * 112;
+ X.isNegative:= false;
+ X.QWordValue:= 4294967296 * 35;
+ dX.isNegative:= false;
+ dX.QWordValue:= 4294967296 * 1152;
+
+ dY:=hwAbs(Gear^.dX*4);
+ dY:= dY + hwPow(dY,3)/_6 + _3 * hwPow(dY,5) / _40 + _5 * hwPow(dY,7) / Y + X * hwPow(dY,9) / dX;
+ Gear^.Angle:= hwRound(dY*_2048 / _PI);
+ if not Gear^.dY.isNegative then Gear^.Angle:= 2048-Gear^.Angle;
+ if Gear^.dX.isNegative then Gear^.Angle:= 4096-Gear^.Angle;
+ end;
AllInactive := false;
HHGear := Gear^.Hedgehog^.Gear;
@@ -3201,7 +3256,7 @@
dec(Gear^.Timer);
fChanged := false;
- if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then
+ if (HHGear = nil) or ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then
begin
fChanged := true;
if Gear^.Angle > 2048 then
@@ -3246,7 +3301,7 @@
else
AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
- if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
+ if (HHGear <> nil) and ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
begin
HHGear^.Message := HHGear^.Message and (not gmAttack);
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
@@ -3254,7 +3309,7 @@
dec(Gear^.Health)
end;
- if ((HHGear^.Message and gmLJump) <> 0) and ((Gear^.State and gsttmpFlag) = 0) then
+ if (HHGear <> nil) and ((HHGear^.Message and gmLJump) <> 0) and ((Gear^.State and gsttmpFlag) = 0) then
begin
Gear^.State := Gear^.State or gsttmpFlag;
PauseMusic;
@@ -4044,7 +4099,8 @@
if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil)
and (iterator = CurrentHedgehog^.Gear)
and (CurAmmoGear <> nil)
- and (CurAmmoGear^.Kind =gtRope) then
+ and (CurAmmoGear^.Kind = gtRope)
+ and (CurAmmoGear^.Elasticity <> _0) then
CurAmmoGear^.PortalCounter:= 1;
if not isbullet and (iterator^.State and gstInvisible = 0)
@@ -4097,6 +4153,7 @@
x, y, tx, ty: LongInt;
s: hwFloat;
begin
+ WorldWrap(Gear);
x := hwRound(Gear^.X);
y := hwRound(Gear^.Y);
tx := 0;
@@ -4637,6 +4694,7 @@
////////////////////////////////////////////////////////////////////////////////
procedure doStepPoisonCloud(Gear: PGear);
begin
+ WorldWrap(Gear);
if Gear^.Timer = 0 then
begin
DeleteGear(Gear);
@@ -5117,11 +5175,12 @@
begin
cnt:= 0;
for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
- for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
- if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
- and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0)
- and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then
- inc(cnt);
+ with HH^.Team^.Clan^.Teams[j]^ do
+ for i:= 0 to Pred(HedgehogsNumber) do
+ if (Hedgehogs[i].Gear <> nil)
+ and ((Hedgehogs[i].Gear^.State and gstDrowning) = 0)
+ and (Hedgehogs[i].Gear^.Health > Hedgehogs[i].Gear^.Damage) then
+ inc(cnt);
if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
begin
if HH^.GearHidden <> nil then
--- a/hedgewars/uGearsHandlersRope.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uGearsHandlersRope.pas Mon Oct 28 14:07:04 2013 +0100
@@ -31,8 +31,17 @@
procedure doStepRopeAfterAttack(Gear: PGear);
var
HHGear: PGear;
+ tX: hwFloat;
begin
HHGear := Gear^.Hedgehog^.Gear;
+ tX:= HHGear^.X;
+ if WorldWrap(HHGear) and (WorldEdge = weWrap) and
+ (TestCollisionXwithGear(HHGear, 1) or TestCollisionXwithGear(HHGear, -1)) then
+ begin
+ HHGear^.X:= tX;
+ HHGear^.dX.isNegative:= (hwRound(tX) > leftX+HHGear^.Radius*2)
+ end;
+
if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then
begin
DeleteGear(Gear);
@@ -116,8 +125,20 @@
HHGear := Gear^.Hedgehog^.Gear;
- if ((HHGear^.State and gstHHDriven) = 0)
- or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then
+ tX:= HHGear^.X;
+ if WorldWrap(HHGear) and (WorldEdge = weWrap) and
+ (TestCollisionXwithGear(HHGear, 1) or TestCollisionXwithGear(HHGear, -1)) then
+ begin
+ PlaySound(sndRopeRelease);
+ RopeDeleteMe(Gear, HHGear);
+ HHGear^.X:= tX;
+ HHGear^.dX.isNegative:= (hwRound(tX) > leftX+HHGear^.Radius*2);
+ exit
+ end;
+
+ tX:= HHGear^.X;
+ if ((HHGear^.State and gstHHDriven) = 0) or
+ (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then
begin
PlaySound(sndRopeRelease);
RopeDeleteMe(Gear, HHGear);
--- a/hedgewars/uGearsHedgehog.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uGearsHedgehog.pas Mon Oct 28 14:07:04 2013 +0100
@@ -116,7 +116,7 @@
// Try again in the next slot
if CurAmmoType = prevAmmo then
begin
- if slot >= cMaxSlotIndex then slot:= 0 else inc(slot);
+ if slot < cMaxSlotIndex then inc(slot);
HHGear^.MsgParam:= slot;
ChangeAmmo(HHGear)
end
@@ -848,10 +848,12 @@
if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
Gear^.dY:= _0;
Gear^.State:= Gear^.State or gstMoving;
- if (CurrentHedgehog^.Gear = Gear)
- and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
+ if (CurrentHedgehog^.Gear = Gear) and (CurrentHedgehog^.Gear^.State and gstHHDriven <> 0) and
+ (not CurrentTeam^.ExtDriven) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
begin
// TODO: why so aggressive at setting FollowGear when falling?
+ // because hog was being yanked out of frame by other stuff when doing a complicated jump/chute/saucer/roping.
+ // added a couple more conditions to make it a bit less aggressive, at cost of possibly spectator failing to follow a maneuver
FollowGear:= Gear;
end;
if isUnderwater then
@@ -1273,7 +1275,21 @@
////////////////////////////////////////////////////////////////////////////////
procedure doStepHedgehog(Gear: PGear);
+var tX: hwFloat;
begin
+tX:= Gear^.X;
+if WorldWrap(Gear) then
+ begin
+ if (WorldEdge <> weBounce) and (Gear = CurrentHedgehog^.Gear) and
+ (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) and (CurAmmoGear^.Elasticity <> _0) then
+ CurAmmoGear^.PortalCounter:= 1;
+ if (WorldEdge = weWrap) and (TestCollisionXwithGear(Gear, 1) or TestCollisionXwithGear(Gear, -1)) then
+ begin
+ Gear^.X:= tX;
+ Gear^.dX.isNegative:= (hwRound(tX) > leftX+Gear^.Radius*2)
+ end
+ end;
+
CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
if (Gear^.Message and gmDestroy) <> 0 then
begin
--- a/hedgewars/uGearsList.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uGearsList.pas Mon Oct 28 14:07:04 2013 +0100
@@ -281,6 +281,7 @@
gear^.RenderTimer:= true;
gear^.Elasticity:= _0_9;
gear^.Tag:= 0;
+ gear^.State:= Gear^.State or gstSubmersible
end;
gtSeduction: begin
gear^.Radius:= 250;
--- a/hedgewars/uGearsRender.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uGearsRender.pas Mon Oct 28 14:07:04 2013 +0100
@@ -671,6 +671,25 @@
end;
amGirder: begin
DrawSpriteRotated(sprHandConstruction, hx, hy, sign, aangle);
+ if WorldEdge = weWrap then
+ begin
+ if hwRound(Gear^.X) < leftX+256 then
+ DrawSpriteClipped(sprGirder,
+ rightX+(ox-leftX)-256,
+ oy-256,
+ LongInt(topY)+WorldDy,
+ LongInt(rightX)+WorldDx,
+ cWaterLine+WorldDy,
+ LongInt(leftX)+WorldDx);
+ if hwRound(Gear^.X) > rightX-256 then
+ DrawSpriteClipped(sprGirder,
+ leftX-(rightX-ox)-256,
+ oy-256,
+ LongInt(topY)+WorldDy,
+ LongInt(rightX)+WorldDx,
+ cWaterLine+WorldDy,
+ LongInt(leftX)+WorldDx)
+ end;
DrawSpriteClipped(sprGirder,
ox-256,
oy-256,
--- a/hedgewars/uGearsUtils.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uGearsUtils.pas Mon Oct 28 14:07:04 2013 +0100
@@ -53,13 +53,14 @@
function GetAmmo(Hedgehog: PHedgehog): TAmmoType;
function GetUtility(Hedgehog: PHedgehog): TAmmoType;
+function WorldWrap(var Gear: PGear): boolean;
+
function MakeHedgehogsStep(Gear: PGear) : boolean;
var doStepHandlers: array[TGearType] of TGearStepProcedure;
-
implementation
uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc,
uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore,
@@ -486,7 +487,10 @@
CurAmmoGear^.Pos := 1000
end
else
- CheckGearDrowning := false;
+ begin
+ if not (Gear^.Kind in [gtJetpack, gtBee]) then Gear^.State:= Gear^.State and not gstSubmersible; // making it temporary for most gears is more attractive I think
+ CheckGearDrowning := false
+ end
end;
@@ -589,6 +593,11 @@
ignoreNearObjects:= false; // try not skipping proximity at first
ignoreOverlap:= false; // this not only skips proximity, but allows overlapping objects (barrels, mines, hogs, crates). Saving it for a 3rd pass. With this active, winning AI Survival goes back to virtual impossibility
tryAgain:= true;
+if WorldEdge <> weNone then
+ begin
+ Left:= max(Left,leftX+Gear^.Radius);
+ Right:= min(Right,rightX-Gear^.Radius)
+ end;
while tryAgain do
begin
delta:= LAND_WIDTH div 16;
@@ -1198,5 +1207,79 @@
GetUtility:= i
end;
+(*
+Intended to check Gear X/Y against the map left/right edges and apply one of the world modes
+* Normal - infinite world, do nothing
+* Wrap (entering left edge exits at same height on right edge)
+* Bounce (striking edge is treated as a 100% elasticity bounce)
+* From the depths (same as from sky, but from sea, with submersible flag set)
+
+Trying to make the checks a little broader than on first pass to catch things that don't move normally.
+*)
+function WorldWrap(var Gear: PGear): boolean;
+var tdx: hwFloat;
+begin
+WorldWrap:= false;
+if WorldEdge = weNone then exit(false);
+if (hwRound(Gear^.X)-Gear^.Radius < leftX) or
+ (hwRound(Gear^.X)+Gear^.Radius > rightX) then
+ begin
+ if WorldEdge = weWrap then
+ begin
+ if (hwRound(Gear^.X)-Gear^.Radius < leftX) then
+ Gear^.X:= int2hwfloat(rightX-Gear^.Radius)
+ else Gear^.X:= int2hwfloat(leftX+Gear^.Radius);
+ LeftImpactTimer:= 150;
+ RightImpactTimer:= 150
+ end
+ else if WorldEdge = weBounce then
+ begin
+ if (hwRound(Gear^.X)-Gear^.Radius < leftX) then
+ begin
+ LeftImpactTimer:= 333;
+ Gear^.dX.isNegative:= false;
+ Gear^.X:= int2hwfloat(leftX+Gear^.Radius)
+ end
+ else
+ begin
+ RightImpactTimer:= 333;
+ Gear^.dX.isNegative:= true;
+ Gear^.X:= int2hwfloat(rightX-Gear^.Radius)
+ end;
+ if (Gear^.Radius > 2) and (Gear^.dX.QWordValue > _0_001.QWordValue) then
+ PlaySound(sndMelonImpact)
+ end
+ else if WorldEdge = weSea then
+ begin
+ if (hwRound(Gear^.Y) > cWaterLine) and (Gear^.State and gstSubmersible <> 0) then
+ Gear^.State:= Gear^.State and not gstSubmersible
+ else
+ begin
+ Gear^.State:= Gear^.State or gstSubmersible;
+ Gear^.X:= int2hwFloat(PlayWidth)*int2hwFloat(min(max(0,hwRound(Gear^.Y)),PlayHeight))/PlayHeight;
+ Gear^.Y:= int2hwFloat(cWaterLine+cVisibleWater+Gear^.Radius*2);
+ tdx:= Gear^.dX;
+ Gear^.dX:= -Gear^.dY;
+ Gear^.dY:= tdx;
+ Gear^.dY.isNegative:= true
+ end
+ end;
+(*
+* Window in the sky (Gear moved high into the sky, Y is used to determine X) [unfortunately, not a safe thing to do. shame, I thought aerial bombardment would be kinda neat
+This one would be really easy to freeze game unless it was flagged unfortunately.
+
+ else
+ begin
+ Gear^.X:= int2hwFloat(PlayWidth)*int2hwFloat(min(max(0,hwRound(Gear^.Y)),PlayHeight))/PlayHeight;
+ Gear^.Y:= -_2048-_256-_256;
+ tdx:= Gear^.dX;
+ Gear^.dX:= Gear^.dY;
+ Gear^.dY:= tdx;
+ Gear^.dY.isNegative:= false
+ end
+*)
+ WorldWrap:= true
+ end;
+end;
end.
--- a/hedgewars/uInputHandler.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uInputHandler.pas Mon Oct 28 14:07:04 2013 +0100
@@ -40,6 +40,8 @@
procedure SetBinds(var binds: TBinds);
procedure SetDefaultBinds;
procedure chDefaultBind(var id: shortstring);
+procedure loadBinds(cmd, s: shortstring);
+procedure addBind(var binds: TBinds; var id: shortstring);
procedure ControllerInit;
procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
@@ -47,7 +49,7 @@
procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean);
implementation
-uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug;
+uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug, uPhysFSLayer;
const
LSHIFT = $0200;
@@ -70,7 +72,6 @@
//ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer;
//ControllerHats: array[0..5] of array[0..19] of Byte;
//ControllerButtons: array[0..5] of array[0..19] of Byte;
- usingDBinds: boolean;
function KeyNameToCode(name: shortstring): LongInt; inline;
begin
@@ -314,6 +315,8 @@
DefaultBinds[KeyNameToCode('j0a1d')]:= '+down';
for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i);
for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i);
+
+loadBinds('dbind', cPathz[ptData] + '/settings.ini');
end;
procedure SetBinds(var binds: TBinds);
@@ -447,22 +450,68 @@
ProcessKey(k + ControllerNumAxes[joy]*2 + ControllerNumHats[joy]*4 + button, pressed);
end;
-// Bind that isn't a team bind, but overrides defaultbinds.
-// When first called, DefaultBinds is cleared, because we assume we are getting a full list of dbinds.
-procedure chDefaultBind(var id: shortstring);
+procedure loadBinds(cmd, s: shortstring);
+var i: LongInt;
+ f: PFSFile;
+ p, l: shortstring;
+ b: byte;
+begin
+ AddFileLog('[BINDS] Loading binds from: ' + s);
+
+ l:= '';
+ if pfsExists(s) then
+ begin
+ f:= pfsOpenRead(s);
+ while (not pfsEOF(f)) and (l <> '[Binds]') do
+ pfsReadLn(f, l);
+
+ while (not pfsEOF(f)) and (l <> '') do
+ begin
+ pfsReadLn(f, l);
+
+ p:= '';
+ i:= 1;
+ while (i <= length(l)) and (l[i] <> '=') do
+ begin
+ if l[i] <> '%' then
+ begin
+ p:= p + l[i];
+ inc(i)
+ end else
+ begin
+ l[i]:= '$';
+ val(copy(l, i, 3), b);
+ p:= p + char(b);
+ inc(i, 3)
+ end;
+ end;
+
+ if i < length(l) then
+ begin
+ l:= copy(l, i + 1, length(l) - i);
+ if l <> 'default' then
+ begin
+ p:= cmd + ' ' + l + ' ' + p;
+ ParseCommand(p, true)
+ end
+ end
+ end;
+
+ pfsClose(f)
+ end
+ else
+ AddFileLog('[BINDS] file not found');
+end;
+
+
+procedure addBind(var binds: TBinds; var id: shortstring);
var KeyName, Modifier, tmp: shortstring;
- b: LongInt;
+ i, b: LongInt;
begin
KeyName:= '';
Modifier:= '';
-if (not usingDBinds) then
- begin
- usingDBinds:= true;
- FillByte(DefaultBinds, SizeOf(DefaultBinds), 0);
- end;
-
-if (Pos('mod:', id) <> 0) then
+if(Pos('mod:', id) <> 0)then
begin
tmp:= '';
SplitBySpace(id, tmp);
@@ -479,12 +528,27 @@
if b = 0 then
OutError(errmsgUnknownVariable + ' "' + id + '"', false)
else
- DefaultBinds[b]:= KeyName;
+ begin
+ // add bind: first check if this cmd is already bound, and remove old bind
+ i:= cKbdMaxIndex;
+ repeat
+ dec(i)
+ until (i < 0) or (binds[i] = KeyName);
+ if (i >= 0) then
+ binds[i]:= '';
+
+ binds[b]:= KeyName;
+ end
+end;
+
+// Bind that isn't a team bind, but overrides defaultbinds.
+procedure chDefaultBind(var id: shortstring);
+begin
+ addBind(DefaultBinds, id)
end;
procedure initModule;
begin
- usingDBinds:= false;
RegisterVariable('dbind', @chDefaultBind, true );
end;
--- a/hedgewars/uLand.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uLand.pas Mon Oct 28 14:07:04 2013 +0100
@@ -729,26 +729,27 @@
// also try basing cave dimensions on map/template dimensions, if they exist
for w:= 0 to 5 do // width of 3 allowed hogs to be knocked through with grenade
begin
- for y:= topY to LAND_HEIGHT - 1 do
- begin
- Land[y, leftX + w]:= lfIndestructible;
- Land[y, rightX - w]:= lfIndestructible;
- if (y + w) mod 32 < 16 then
- c:= AMask
- else
- c:= AMask or RMask or GMask; // FF00FFFF
+ if (WorldEdge <> weBounce) and (WorldEdge <> weWrap) then
+ for y:= topY to LAND_HEIGHT - 1 do
+ begin
+ Land[y, leftX + w]:= lfIndestructible;
+ Land[y, rightX - w]:= lfIndestructible;
+ if (y + w) mod 32 < 16 then
+ c:= AMask
+ else
+ c:= AMask or RMask or GMask; // FF00FFFF
- if (cReducedQuality and rqBlurryLand) = 0 then
- begin
- LandPixels[y, leftX + w]:= c;
- LandPixels[y, rightX - w]:= c;
- end
- else
- begin
- LandPixels[y div 2, (leftX + w) div 2]:= c;
- LandPixels[y div 2, (rightX - w) div 2]:= c;
+ if (cReducedQuality and rqBlurryLand) = 0 then
+ begin
+ LandPixels[y, leftX + w]:= c;
+ LandPixels[y, rightX - w]:= c;
+ end
+ else
+ begin
+ LandPixels[y div 2, (leftX + w) div 2]:= c;
+ LandPixels[y div 2, (rightX - w) div 2]:= c;
+ end;
end;
- end;
for x:= leftX to rightX do
begin
--- a/hedgewars/uLandPainted.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uLandPainted.pas Mon Oct 28 14:07:04 2013 +0100
@@ -27,7 +27,7 @@
procedure freeModule;
implementation
-uses uLandGraphics, uConsts, uVariables, uUtils, SDLh, uCommands, uDebug;
+uses uLandGraphics, uConsts, uVariables, uUtils, SDLh, uCommands, uDebug, uScript;
type PointRec = packed record
X, Y: SmallInt;
@@ -88,7 +88,11 @@
radius:= 0;
pe:= pointsListHead;
- TryDo((pe = nil) or (pe^.point.flags and $80 <> 0), 'Corrupted draw data', true);
+ while (pe <> nil) and (pe^.point.flags and $80 = 0) do
+ begin
+ ScriptCall('onSpecialPoint', pe^.point.X, pe^.point.Y, pe^.point.flags);
+ pe:= pe^.next;
+ end;
while(pe <> nil) do
begin
@@ -110,7 +114,7 @@
end;
prevPoint:= pe^.point;
- pe:= pe^.next;
+ pe:= pe^.next;
end;
end;
--- a/hedgewars/uPhysFSLayer.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uPhysFSLayer.pas Mon Oct 28 14:07:04 2013 +0100
@@ -145,10 +145,12 @@
AddFileLog('[PhysFS] mount ' + PathPrefix + ': ' + inttostr(i));
i:= PHYSFS_mount(Str2PChar(UserPathPrefix + '/Data'), nil, false);
AddFileLog('[PhysFS] mount ' + UserPathPrefix + '/Data: ' + inttostr(i));
- i:= PHYSFS_mount(Str2PChar(UserPathPrefix + '/Teams'), '/Teams', false);
- AddFileLog('[PhysFS] mount ' + UserPathPrefix + '/Teams: ' + inttostr(i));
hedgewarsMountPackages;
+
+ i:= PHYSFS_mount(Str2PChar(UserPathPrefix), nil, false);
+ // need access to teams and frontend configs (for bindings)
+ AddFileLog('[PhysFS] mount ' + UserPathPrefix + ': ' + inttostr(i));
end;
procedure freeModule;
--- a/hedgewars/uRender.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uRender.pas Mon Oct 28 14:07:04 2013 +0100
@@ -44,6 +44,7 @@
procedure DrawCircle (X, Y, Radius, Width: LongInt);
procedure DrawCircle (X, Y, Radius, Width: LongInt; r, g, b, a: Byte);
+procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline;
procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
procedure DrawFillRect (r: TSDL_Rect);
procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
@@ -348,6 +349,11 @@
DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale)
end;
+procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline;
+begin
+DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF)
+end;
+
procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
var VertexBuffer: array [0..1] of TVertex2f;
begin
@@ -533,7 +539,7 @@
procedure Tint(r, g, b, a: Byte); inline;
var nc, tw: Longword;
begin
- nc:= (a shl 24) or (b shl 16) or (g shl 8) or r;
+ nc:= (r shl 24) or (g shl 16) or (b shl 8) or a;
if nc = lastTint then
exit;
@@ -554,6 +560,7 @@
procedure Tint(c: Longword); inline;
begin
+ if c = lastTint then exit;
Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF))
end;
--- a/hedgewars/uScript.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uScript.pas Mon Oct 28 14:07:04 2013 +0100
@@ -95,6 +95,7 @@
ScriptAmmoDelay : shortstring;
ScriptAmmoReinforcement : shortstring;
ScriptLoaded : boolean;
+ mapDims : boolean;
procedure ScriptPrepareAmmoStore; forward;
procedure ScriptApplyAmmoStore; forward;
@@ -2065,7 +2066,8 @@
end;
ScriptSetInteger('ClansCount', ClansCount);
-ScriptSetInteger('TeamsCount', TeamsCount)
+ScriptSetInteger('TeamsCount', TeamsCount);
+mapDims:= false
end;
@@ -2088,7 +2090,10 @@
begin
s:= cPathz[ptData] + name;
if not pfsExists(s) then
+ begin
+ AddFileLog('[LUA] Script not found: ' + name);
exit;
+ end;
f:= pfsOpenRead(s);
if f = nil then
@@ -2119,8 +2124,9 @@
ScriptSetInteger('GameTime', GameTicks);
ScriptSetInteger('TotalRounds', TotalRounds);
ScriptSetInteger('WaterLine', cWaterLine);
-if GameTicks = 0 then
+if not mapDims then
begin
+ mapDims:= true;
ScriptSetInteger('LAND_WIDTH', LAND_WIDTH);
ScriptSetInteger('LAND_HEIGHT', LAND_HEIGHT);
ScriptSetInteger('LeftX', leftX);
@@ -2622,6 +2628,7 @@
procedure initModule;
begin
+mapDims:= false;
end;
procedure freeModule;
--- a/hedgewars/uStore.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uStore.pas Mon Oct 28 14:07:04 2013 +0100
@@ -704,20 +704,20 @@
end;
procedure SetupOpenGL;
-var name: array[byte] of char;
+var buf: array[byte] of char;
AuxBufNum: LongInt = 0;
tmpstr: AnsiString;
tmpint: LongInt;
tmpn: LongInt;
begin
{$IFDEF SDL2}
- name:= SDL_GetCurrentVideoDriver();
+ AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')');
{$ELSE}
- name:= SDL_VideoDriverName(name, sizeof(name));
+ buf[0]:= char(0); // avoid compiler hint
+ AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')');
{$ENDIF}
AuxBufNum:= AuxBufNum;
- AddFileLog('Setting up OpenGL (using driver: ' + shortstring(name) + ')');
{$IFDEF MOBILE}
// TODO: this function creates an opengles1.1 context
--- a/hedgewars/uTeams.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uTeams.pas Mon Oct 28 14:07:04 2013 +0100
@@ -43,7 +43,7 @@
implementation
uses uLocale, uAmmos, uChat, uVariables, uUtils, uIO, uCaptions, uCommands, uDebug,
- uGearsUtils, uGearsList, uVisualGearsList, uPhysFSLayer
+ uGearsUtils, uGearsList, uVisualGearsList, uTextures
{$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF};
var MaxTeamHealth: LongInt;
@@ -570,57 +570,13 @@
procedure loadTeamBinds(s: shortstring);
var i: LongInt;
- f: PFSFile;
- p, l: shortstring;
- b: byte;
begin
- l:= '';
-
for i:= 1 to length(s) do
if s[i] in ['\', '/', ':'] then s[i]:= '_';
-
- s:= cPathz[ptTeams] + '/' + s + '.hwt';
- if pfsExists(s) then
- begin
- AddFileLog('Loading binds from: ' + s);
- f:= pfsOpenRead(s);
- while (not pfsEOF(f)) and (l <> '[Binds]') do
- pfsReadLn(f, l);
-
- while (not pfsEOF(f)) and (l <> '') do
- begin
- pfsReadLn(f, l);
- p:= '';
- i:= 1;
- while (i <= length(l)) and (l[i] <> '=') do
- begin
- if l[i] <> '%' then
- begin
- p:= p + l[i];
- inc(i)
- end else
- begin
- l[i]:= '$';
- val(copy(l, i, 3), b);
- p:= p + char(b);
- inc(i, 3)
- end;
- end;
+ s:= cPathz[ptTeams] + '/' + s + '.hwt';
- if i < length(l) then
- begin
- l:= copy(l, i + 1, length(l) - i);
- if l <> 'default' then
- begin
- p:= 'bind ' + l + ' ' + p;
- ParseCommand(p, true)
- end
- end
- end;
-
- pfsClose(f)
- end
+ loadBinds('bind', s);
end;
procedure chAddTeam(var s: shortstring);
@@ -665,43 +621,11 @@
end;
procedure chBind(var id: shortstring);
-var KeyName, Modifier, tmp: shortstring;
- i, b: LongInt;
begin
-KeyName:= '';
-Modifier:= '';
-
-if CurrentTeam = nil then
- exit;
-
-if(Pos('mod:', id) <> 0)then
- begin
- tmp:= '';
- SplitBySpace(id, tmp);
- Modifier:= id;
- id:= tmp;
- end;
+ if CurrentTeam = nil then
+ exit;
-SplitBySpace(id, KeyName);
-if KeyName[1]='"' then
- Delete(KeyName, 1, 1);
-if KeyName[byte(KeyName[0])]='"' then
- Delete(KeyName, byte(KeyName[0]), 1);
-b:= KeyNameToCode(id, Modifier);
-if b = 0 then
- OutError(errmsgUnknownVariable + ' "' + id + '"', false)
-else
- begin
- // add bind: first check if this cmd is already bound, and remove old bind
- i:= cKbdMaxIndex;
- repeat
- dec(i)
- until (i < 0) or (CurrentTeam^.Binds[i] = KeyName);
- if (i >= 0) then
- CurrentTeam^.Binds[i]:= '';
-
- CurrentTeam^.Binds[b]:= KeyName;
- end
+ addBind(CurrentTeam^.Binds, id)
end;
procedure chTeamGone(var s:shortstring);
@@ -790,8 +714,26 @@
for i:= 0 to Pred(TeamsCount) do
begin
for h:= 0 to cMaxHHIndex do
- if TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil then
- Dispose(TeamsArray[i]^.Hedgehogs[h].GearHidden);
+ with TeamsArray[i]^.Hedgehogs[h] do
+ begin
+ if GearHidden <> nil then
+ Dispose(GearHidden);
+
+ FreeTexture(NameTagTex);
+ FreeTexture(HealthTagTex);
+ FreeTexture(HatTex);
+ end;
+
+ with TeamsArray[i]^ do
+ begin
+ FreeTexture(NameTagTex);
+ FreeTexture(CrosshairTex);
+ FreeTexture(GraveTex);
+ FreeTexture(HealthTex);
+ FreeTexture(AIKillsTex);
+ FreeTexture(FlagTex);
+ end;
+
Dispose(TeamsArray[i]);
end;
for i:= 0 to Pred(ClansCount) do
--- a/hedgewars/uTypes.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uTypes.pas Mon Oct 28 14:07:04 2013 +0100
@@ -173,6 +173,8 @@
TRenderMode = (rmDefault, rmLeftEye, rmRightEye);
TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, smHorizontal, smVertical);
+ TWorldEdge = (weNone, weWrap, weBounce, weSea, weSky);
+
THHFont = record
Handle: PTTF_Font;
Height: LongInt;
--- a/hedgewars/uVariables.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uVariables.pas Mon Oct 28 14:07:04 2013 +0100
@@ -82,6 +82,9 @@
GameType : TGameType;
InputMask : LongWord;
GameFlags : Longword;
+ WorldEdge : TWorldEdge;
+ LeftImpactTimer : LongWord;
+ RightImpactTimer: LongWord;
TurnTimeLeft : Longword;
TagTurnTimeLeft : Longword;
ReadyTimeLeft : Longword;
@@ -841,7 +844,8 @@
Probability: 0;
NumberInCase: 1;
Ammo: (Propz: ammoprop_ForwMsgs or
- ammoprop_NeedUpDown;
+ ammoprop_NeedUpDown or
+ ammoprop_DoesntStopTimerInMultiShoot;
Count: AMMO_INFINITE;
NumPerTurn: 1;
Timer: 0;
@@ -922,7 +926,8 @@
ammoprop_AttackInMove or
ammoprop_Utility or
ammoprop_AltAttack or
- ammoprop_NeedUpDown;
+ ammoprop_NeedUpDown or
+ ammoprop_DoesntStopTimerWhileAttacking;
Count: 5;
NumPerTurn: 0;
Timer: 0;
@@ -974,7 +979,7 @@
NameTex: nil;
Probability: 20;
NumberInCase: 2;
- Ammo: (Propz: ammoprop_NeedUpDown;
+ Ammo: (Propz: ammoprop_NeedUpDown or ammoprop_DoesntStopTimerInMultiShoot;
Count: 3;
NumPerTurn: 3;
Timer: 0;
@@ -1736,9 +1741,10 @@
NameTex: nil;
Probability: 20;
NumberInCase: 2;
- Ammo: (Propz: ammoprop_NeedUpDown or
+ Ammo: (Propz: ammoprop_NeedUpDown or
ammoprop_OscAim or
- ammoprop_NoMoveAfter;
+ ammoprop_NoMoveAfter or
+ ammoprop_DoesntStopTimerInMultiShoot;
Count: 2;
NumPerTurn: 1;
Timer: 0;
@@ -2446,6 +2452,9 @@
InputMask := $FFFFFFFF;
GameFlags := 0;
+ WorldEdge := weNone;
+ LeftImpactTimer := 0;
+ RightImpactTimer := 0;
TurnTimeLeft := 0;
TagTurnTimeLeft := 0;
cSuddenDTurns := 15;
--- a/hedgewars/uVideoRec.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uVideoRec.pas Mon Oct 28 14:07:04 2013 +0100
@@ -367,6 +367,10 @@
procedure initModule;
begin
+ // we need to make sure these variables are initialized before the main loop
+ // or the wrapper will keep the default values of preinit
+ cScreenWidth:= max(cWindowedWidth, 640);
+ cScreenHeight:= max(cWindowedHeight, 480);
end;
procedure freeModule;
--- a/hedgewars/uWorld.pas Wed Sep 25 05:42:16 2013 +0300
+++ b/hedgewars/uWorld.pas Mon Oct 28 14:07:04 2013 +0100
@@ -85,6 +85,7 @@
AmmoMenuTex : PTexture;
HorizontOffset: LongInt;
cOffsetY: LongInt;
+ WorldEnd, WorldFade : array[0..3] of HwColor4f;
const cStereo_Sky = 0.0500;
cStereo_Horizon = 0.0250;
@@ -1129,6 +1130,8 @@
highlight: Boolean;
smallScreenOffset, offsetX, offsetY, screenBottom: LongInt;
VertexBuffer: array [0..3] of TVertex2f;
+ lw, lh: GLfloat;
+ c1, c2: LongWord; // couple of colours for edges
begin
if (cReducedQuality and rqNoBackground) = 0 then
begin
@@ -1235,6 +1238,106 @@
end;
{$WARNINGS ON}
+if WorldEdge <> weNone then
+ begin
+(* I think for a bounded world, will fill the left and right areas with black or something. Also will probably want various border effects/animations based on border type. Prob also, say, trigger a border animation timer on an impact. *)
+
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glPushMatrix;
+ glTranslatef(WorldDx, WorldDy, 0);
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]);
+
+ VertexBuffer[0].X:= leftX-20;
+ VertexBuffer[0].Y:= -3000;
+ VertexBuffer[1].X:= leftX-20;
+ VertexBuffer[1].Y:= cWaterLine+cVisibleWater;
+ VertexBuffer[2].X:= leftX+30;
+ VertexBuffer[2].Y:= cWaterLine+cVisibleWater;
+ VertexBuffer[3].X:= leftX+30;
+ VertexBuffer[3].Y:= -3000;
+
+ glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
+
+ VertexBuffer[0].X:= rightX+20;
+ VertexBuffer[1].X:= rightX+20;
+ VertexBuffer[2].X:= rightX-30;
+ VertexBuffer[3].X:= rightX-30;
+
+ glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
+
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldEnd[0]);
+
+ VertexBuffer[0].X:= -5000;
+ VertexBuffer[1].X:= -5000;
+ VertexBuffer[2].X:= leftX-20;
+ VertexBuffer[3].X:= leftX-20;
+
+ glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
+
+ VertexBuffer[0].X:= rightX+5000;
+ VertexBuffer[1].X:= rightX+5000;
+ VertexBuffer[2].X:= rightX+20;
+ VertexBuffer[3].X:= rightX+20;
+
+ glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
+
+ glPopMatrix;
+ glDisableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
+ glEnable(GL_TEXTURE_2D);
+
+ // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer
+ if WorldEdge = weBounce then
+ begin
+ // could maybe alternate order of these on a bounce, or maybe drop the outer ones.
+ if LeftImpactTimer mod 2 = 0 then
+ begin
+ c1:= $5454FFFF; c2:= $FFFFFFFF;
+ end
+ else begin
+ c1:= $FFFFFFFF; c2:= $5454FFFF;
+ end;
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 7.0, c1);
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, c2);
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 3.0, c1);
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 1.0, c2);
+ if RightImpactTimer mod 2 = 0 then
+ begin
+ c1:= $5454FFFF; c2:= $FFFFFFFF;
+ end
+ else begin
+ c1:= $FFFFFFFF; c2:= $5454FFFF;
+ end;
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 7.0, c1);
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, c2);
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 3.0, c1);
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 1.0, c2)
+ end
+ else if WorldEdge = weWrap then
+ begin
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-LeftImpactTimer));
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 2.0, $FF0000FF);
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-RightImpactTimer));
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 2.0, $FF0000FF);
+ end
+ else
+ begin
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $2E8B5780);
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $2E8B5780)
+ end;
+ if LeftImpactTimer > Lag then dec(LeftImpactTimer,Lag) else LeftImpactTimer:= 0;
+ if RightImpactTimer > Lag then dec(RightImpactTimer,Lag) else RightImpactTimer:= 0
+ end;
+
// this scale is used to keep the various widgets at the same dimension at all zoom levels
SetScale(cDefaultZoomLevel);
@@ -1631,7 +1734,7 @@
DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8)
end
end;
-isFirstFrame:= false
+isFirstFrame:= false;
end;
var PrevSentPointTime: LongWord = 0;
@@ -1899,6 +2002,16 @@
AMState:= AMHidden;
isFirstFrame:= true;
stereoDepth:= stereoDepth; // avoid hint
+
+ FillChar(WorldFade, sizeof(WorldFade), 0);
+ WorldFade[0].a:= 255;
+ WorldFade[1].a:= 255;
+ FillChar(WorldEnd, sizeof(WorldEnd), 0);
+ WorldEnd[0].a:= 255;
+ WorldEnd[1].a:= 255;
+ WorldEnd[2].a:= 255;
+ WorldEnd[3].a:= 255;
+
end;
procedure freeModule;
--- a/project_files/hedgewars.pro Wed Sep 25 05:42:16 2013 +0300
+++ b/project_files/hedgewars.pro Mon Oct 28 14:07:04 2013 +0100
@@ -87,7 +87,6 @@
../QTfrontend/achievements.h \
../QTfrontend/binds.h \
../QTfrontend/ui_hwform.h \
- ../QTfrontend/KB.h \
../QTfrontend/hwconsts.h \
../QTfrontend/sdlkeys.h \
../QTfrontend/ui/mouseoverfilter.h \
--- a/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua Wed Sep 25 05:42:16 2013 +0300
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua Mon Oct 28 14:07:04 2013 +0100
@@ -92,6 +92,10 @@
local currY = {}
local currCount = 0
+local specialPointsX = {}
+local specialPointsY = {}
+local specialPointsCount = 0
+
--------------------------
-- hog and team tracking variales
--------------------------
@@ -489,6 +493,10 @@
lastRound = TotalRounds
RoundHasChanged = false -- true
+ for i = 0, (specialPointsCount-1) do
+ PlaceWayPoint(specialPointsX[i], specialPointsY[i])
+ end
+
RebuildTeamInfo()
ShowMission (
@@ -501,7 +509,7 @@
"", 4, 4000
)
- TryRepositionHogs()
+ TryRepositionHogs()
end
@@ -524,10 +532,16 @@
end
+function onSpecialPoint(x,y,flag)
+ specialPointsX[specialPointsCount] = x
+ specialPointsY[specialPointsCount] = y
+ specialPointsCount = specialPointsCount + 1
+end
+
function onNewTurn()
CheckForNewRound()
- TryRepositionHogs()
+ TryRepositionHogs()
racerActive = false