--- a/QTfrontend/chatwidget.cpp Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/chatwidget.cpp Sun Apr 17 13:33:46 2011 -0400
@@ -409,10 +409,8 @@
void HWChatWidget::nickRemoved(const QString& nick)
{
QList<QListWidgetItem *> items = chatNicks->findItems(nick, Qt::MatchExactly);
- for(QList<QListWidgetItem *>::iterator it=items.begin(); it!=items.end();) {
- chatNicks->takeItem(chatNicks->row(*it));
- ++it;
- }
+ QListIterator<QListWidgetItem *> it(items);
+ while(it.hasNext()) chatNicks->takeItem(chatNicks->row(it.next()));
lblCount->setText(QString::number(chatNicks->count()));
}
--- a/QTfrontend/game.cpp Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/game.cpp Sun Apr 17 13:33:46 2011 -0400
@@ -82,8 +82,8 @@
if (m_pTeamSelWidget)
{
- QList<HWTeam> teams = m_pTeamSelWidget->getPlayingTeams();
- for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it)
+ QListIterator<HWTeam> it(m_pTeamSelWidget->getPlayingTeams());
+ while(it.hasNext())
{
HWProto::addStringToBuffer(buf, QString("eammloadt %1").arg(ammostr.mid(0, cAmmoNumber)));
HWProto::addStringToBuffer(buf, QString("eammprob %1").arg(ammostr.mid(cAmmoNumber, cAmmoNumber)));
@@ -91,7 +91,8 @@
HWProto::addStringToBuffer(buf, QString("eammreinf %1").arg(ammostr.mid(3 * cAmmoNumber, cAmmoNumber)));
if(!gamecfg->schemeData(21).toBool()) HWProto::addStringToBuffer(buf, QString("eammstore"));
HWProto::addStringListToBuffer(buf,
- (*it).TeamGameConfig(gamecfg->getInitHealth()));
+ it.next().TeamGameConfig(gamecfg->getInitHealth()));
+ ;
}
}
RawSendIPC(buf);
@@ -389,9 +390,9 @@
if (m_pTeamSelWidget)
{
QByteArray buf;
- QList<HWTeam> teams = m_pTeamSelWidget->getPlayingTeams();
- for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it)
- HWProto::addStringToBuffer(buf, QString("eteamgone %1").arg((*it).TeamName));
+ QListIterator<HWTeam> it(m_pTeamSelWidget->getPlayingTeams());
+ while(it.hasNext())
+ HWProto::addStringToBuffer(buf, QString("eteamgone %1").arg(it.next().TeamName));
RawSendIPC(buf);
}
}
--- a/QTfrontend/hwform.cpp Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/hwform.cpp Sun Apr 17 13:33:46 2011 -0400
@@ -244,6 +244,8 @@
connect(ui.pageDrawMap->BtnBack, SIGNAL(clicked()), this, SLOT(GoBack()));
+ connect(ui.pageConnecting, SIGNAL(cancelConnection()), this, SLOT(GoBack()));
+
ammoSchemeModel = new AmmoSchemeModel(this, cfgdir->absolutePath() + "/schemes.ini");
ui.pageScheme->setModel(ammoSchemeModel);
@@ -550,7 +552,7 @@
if (id == ID_PAGE_NETGAME || id == ID_PAGE_NETGAME)
GoBack();
- if (curid == ID_PAGE_ROOMSLIST) NetDisconnect();
+ if (curid == ID_PAGE_ROOMSLIST || curid == ID_PAGE_CONNECTING) NetDisconnect();
if (curid == ID_PAGE_NETGAME && hwnet) hwnet->partRoom();
// need to work on this, can cause invalid state for admin quit trying to prevent bad state message on kick
//if (curid == ID_PAGE_NETGAME && (!game || game->gameState != gsStarted)) hwnet->partRoom();
@@ -593,11 +595,10 @@
curTeamSelWidget = ui.pageNetGame->pNetTeamsWidget;
}
- QList<HWTeam> teams = curTeamSelWidget->getDontPlayingTeams();
QStringList tmnames;
- for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it) {
- tmnames += it->TeamName;
- }
+ QListIterator<HWTeam> it(curTeamSelWidget->getDontPlayingTeams());
+ while(it.hasNext()) tmnames += it.next().TeamName;
+
//UpdateTeamsLists(&tmnames); // FIXME: still need more work if teamname is updated while configuring
UpdateTeamsLists();
--- a/QTfrontend/netudpserver.cpp Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/netudpserver.cpp Sun Apr 17 13:33:46 2011 -0400
@@ -22,7 +22,8 @@
#include "netudpserver.h"
HWNetUdpServer::HWNetUdpServer(QObject *parent, const QString & descr, quint16 port) :
- HWNetRegisterServer(parent, descr, port)
+ HWNetRegisterServer(parent, descr, port),
+ m_descr(descr)
{
pUdpSocket = new QUdpSocket(this);
pUdpSocket->bind(46631);
@@ -37,9 +38,9 @@
QHostAddress clientAddr;
quint16 clientPort;
pUdpSocket->readDatagram(datagram.data(), datagram.size(), &clientAddr, &clientPort);
- if(QString("%1").arg(datagram.data())==QString("hedgewars client")) {
+ if(datagram.startsWith("hedgewars client")) {
// send answer to client
- pUdpSocket->writeDatagram("hedgewars server", clientAddr, clientPort);
+ pUdpSocket->writeDatagram(QString("hedgewars server\n%1").arg(m_descr).toUtf8(), clientAddr, clientPort);
}
}
}
--- a/QTfrontend/netudpserver.h Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/netudpserver.h Sun Apr 17 13:33:46 2011 -0400
@@ -40,6 +40,7 @@
private:
QUdpSocket* pUdpSocket;
+ QString m_descr;
};
#endif // _NET_UDPSERVER_INCLUDED
--- a/QTfrontend/netudpwidget.cpp Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/netudpwidget.cpp Sun Apr 17 13:33:46 2011 -0400
@@ -49,9 +49,10 @@
pUdpSocket->readDatagram(datagram.data(), datagram.size(), &clientAddr, &clientPort);
- if(QString("%1").arg(datagram.data())==QString("hedgewars server")) {
+ QString packet = QString::fromUtf8(datagram.data());
+ if(packet.startsWith("hedgewars server")) {
QStringList sl;
- sl << "-" << clientAddr.toString() << "46631";
+ sl << packet.remove(0, 17) << clientAddr.toString() << "46631";
games.append(sl);
}
}
--- a/QTfrontend/pageconnecting.cpp Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/pageconnecting.cpp Sun Apr 17 13:33:46 2011 -0400
@@ -29,4 +29,9 @@
QLabel * lblConnecting = new QLabel(this);
lblConnecting->setText(tr("Connecting..."));
pageLayout->addWidget(lblConnecting);
+
+ QPushButton * pbCancel = new QPushButton(this);
+ pbCancel->setText(tr("Cancel"));
+ pageLayout->addWidget(pbCancel);
+ connect(pbCancel, SIGNAL(clicked()), this, SIGNAL(cancelConnection()));
}
--- a/QTfrontend/pages.h Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/pages.h Sun Apr 17 13:33:46 2011 -0400
@@ -476,6 +476,9 @@
public:
PageConnecting(QWidget* parent = 0);
+
+signals:
+ void cancelConnection();
};
class PageScheme : public AbstractPage
--- a/QTfrontend/teamselect.cpp Mon Apr 11 20:53:55 2011 +0000
+++ b/QTfrontend/teamselect.cpp Sun Apr 17 13:33:46 2011 -0400
@@ -243,7 +243,6 @@
void TeamSelWidget::resetPlayingTeams(const QList<HWTeam>& teamslist)
{
- QList<HWTeam>::iterator it;
//for(it=curPlayingTeams.begin(); it!=curPlayingTeams.end(); it++) {
//framePlaying->removeTeam(*it);
//}
@@ -256,9 +255,8 @@
frameDontPlaying->resetTeams();
curDontPlayingTeams.clear();
- for (QList<HWTeam>::ConstIterator it = teamslist.begin(); it != teamslist.end(); ++it ) {
- addTeam(*it);
- }
+ QListIterator<HWTeam> it(teamslist);
+ while(it.hasNext()) addTeam(it.next());
}
bool TeamSelWidget::isPlaying(HWTeam team) const
--- a/gameServer/Actions.hs Mon Apr 11 20:53:55 2011 +0000
+++ b/gameServer/Actions.hs Sun Apr 17 13:33:46 2011 -0400
@@ -17,6 +17,7 @@
import Data.Unique
import Control.Arrow
import Control.Exception
+import OfficialServer.GameReplayStore
-----------------------------
import CoreTypes
import Utils
@@ -60,6 +61,7 @@
| AddNick2Bans B.ByteString B.ByteString UTCTime
| AddIP2Bans B.ByteString B.ByteString UTCTime
| CheckBanned
+ | SaveReplay
type CmdHandler = [B.ByteString] -> Reader (ClientIndex, IRnC) [Action]
@@ -470,3 +472,10 @@
throw RestartException
else
processAction $ ModifyServerInfo (\s -> s{restartPending=True})
+
+processAction SaveReplay = do
+ ri <- clientRoomA
+ rnc <- gets roomsClients
+ io $ do
+ r <- room'sM rnc id ri
+ saveReplay r
--- a/gameServer/CoreTypes.hs Mon Apr 11 20:53:55 2011 +0000
+++ b/gameServer/CoreTypes.hs Sun Apr 17 13:33:46 2011 -0400
@@ -44,6 +44,7 @@
data HedgehogInfo =
HedgehogInfo B.ByteString B.ByteString
+ deriving (Show, Read)
data TeamInfo =
TeamInfo
@@ -60,6 +61,7 @@
hhnum :: Int,
hedgehogs :: [HedgehogInfo]
}
+ deriving (Show, Read)
data RoomInfo =
RoomInfo
--- a/gameServer/HWProtoInRoomState.hs Mon Apr 11 20:53:55 2011 +0000
+++ b/gameServer/HWProtoInRoomState.hs Sun Apr 17 13:33:46 2011 -0400
@@ -205,7 +205,8 @@
chans <- roomClientsChans
if isMaster cl && gameinprogress rm then
- return $ ModifyRoom
+ return $
+ ModifyRoom
(\r -> r{
gameinprogress = False,
readyPlayers = 0,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gameServer/OfficialServer/GameReplayStore.hs Sun Apr 17 13:33:46 2011 -0400
@@ -0,0 +1,19 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+module OfficialServer.GameReplayStore where
+
+import CoreTypes
+import Data.Time
+import Control.Exception as E
+import qualified Data.Map as Map
+import Data.Sequence()
+import System.Log.Logger
+
+saveReplay :: RoomInfo -> IO ()
+saveReplay r = do
+ time <- getCurrentTime
+ let fileName = "replays/" ++ show time
+ let replayInfo = (teamsAtStart r, Map.toList $ mapParams r, Map.toList $ params r, roundMsgs r)
+ E.catch
+ (writeFile fileName (show replayInfo))
+ (\(e :: IOException) -> warningM "REPLAYS" $ "Couldn't write to " ++ fileName ++ ": " ++ show e)
+
\ No newline at end of file
--- a/hedgewars/ArgParsers.inc Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/ArgParsers.inc Sun Apr 17 13:33:46 2011 -0400
@@ -16,12 +16,19 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*)
+procedure playReplayFileWithParameters(); forward;
+
procedure internalSetGameTypeLandPreviewFromParameters();
begin
- val(ParamStr(2), ipcPort);
- GameType:= gmtLandPreview;
- if ParamStr(3) <> 'landpreview' then
- GameType:= gmtSyntax
+ if ParamStr(3) = '--stats-only' then
+ playReplayFileWithParameters()
+ else
+ begin
+ val(ParamStr(2), ipcPort);
+ GameType:= gmtLandPreview;
+ if ParamStr(3) <> 'landpreview' then
+ GameType:= gmtSyntax
+ end
end;
procedure internalStartGameWithParameters();
@@ -210,10 +217,19 @@
paramIndex:= paramIndex + 13
end
else
- begin
- wrongParameter:= true;
- GameType:= gmtSyntax
- end
+ if ParamStr(paramIndex) = '--stats-only' then
+ begin
+ cOnlyStats:= true;
+ isSoundEnabled:= false;
+ isMusicEnabled:= false;
+ cReducedQuality:= $FFFFFFFF xor rqLowRes; // HACK
+ paramIndex:= paramIndex + 1
+ end
+ else
+ begin
+ wrongParameter:= true;
+ GameType:= gmtSyntax
+ end
end
end;
--- a/hedgewars/GSHandlers.inc Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/GSHandlers.inc Sun Apr 17 13:33:46 2011 -0400
@@ -176,8 +176,8 @@
particle := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), cWaterLine, vgtDroplet);
if particle <> nil then
begin
- particle^.dX := particle^.dX - (Gear^.dX.QWordValue / 42949672960);
- particle^.dY := particle^.dY - (Gear^.dY.QWordValue / 21474836480)
+ particle^.dX := particle^.dX - hwFloat2Float(Gear^.dX);
+ particle^.dY := particle^.dY - hwFloat2Float(Gear^.dY)
end
end
end;
@@ -380,7 +380,7 @@
dec(Gear^.Timer);
if Gear^.Timer = 1000 then // might need adjustments
case Gear^.Kind of
- gtBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50);
+ gtGrenade: makeHogsWorry(Gear^.X, Gear^.Y, 50);
gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90);
@@ -404,7 +404,7 @@
if Gear^.Timer = 0 then
begin
case Gear^.Kind of
- gtBomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound);
gtClusterBomb:
begin
@@ -1549,7 +1549,7 @@
HHGear^.dY := HHGear^.dY * len;
end;
- haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)] and $FF00) <> 0);
+ haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)]) <> 0);
if not haveCollision then
begin
@@ -1564,13 +1564,13 @@
Gear^.Y:= RopePoints.ar[0].Y;
end;
- CheckCollisionWithLand(Gear);
+ CheckCollision(Gear);
// if we haven't found any collision yet then check the otheer side too
if (Gear^.State and gstCollision) = 0 then
begin
Gear^.dX.isNegative:= not Gear^.dX.isNegative;
Gear^.dY.isNegative:= not Gear^.dY.isNegative;
- CheckCollisionWithLand(Gear);
+ CheckCollision(Gear);
Gear^.dX.isNegative:= not Gear^.dX.isNegative;
Gear^.dY.isNegative:= not Gear^.dY.isNegative;
end;
@@ -1678,7 +1678,7 @@
end;
end;
- CheckCollisionWithLand(Gear);
+ CheckCollision(Gear);
if (Gear^.State and gstCollision) <> 0 then
if Gear^.Elasticity < _10 then
@@ -1930,7 +1930,7 @@
^.dY := _0;
if hwAbs(Gear^.dX) < _0_001 then Gear^.dX := _0;
- if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
+ if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
if (cBarrelHealth div Gear^.Health) > 2 then
AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
else
@@ -1970,7 +1970,7 @@
if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02))
then Gear^.doStep := @doStepRollingBarrel;
- if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
+ if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
if (cBarrelHealth div Gear^.Health) > 2 then
AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
else
--- a/hedgewars/HHHandlers.inc Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/HHHandlers.inc Sun Apr 17 13:33:46 2011 -0400
@@ -90,14 +90,7 @@
if i <= cMaxSlotAmmoIndex then ammoidx:= i
else ammoidx:= -1
end;
- if ammoidx >= 0 then
- begin
- CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
- if (CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) then
- ShowCrosshair:= (Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoCrossHair) = 0
- else
- ShowCrosshair:= (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoCrosshair) = 0;
- end
+ if ammoidx >= 0 then CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
end
end;
@@ -211,7 +204,7 @@
end;
case CurAmmoType of
- amGrenade: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtBomb, 0, newDx, newDy, CurWeapon^.Timer);
+ amGrenade: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade, 0, newDx, newDy, CurWeapon^.Timer);
amMolotov: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov, 0, newDx, newDy, 0);
amClusterBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, newDx, newDy, CurWeapon^.Timer);
amGasBomb: FollowGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb, 0, newDx, newDy, CurWeapon^.Timer);
@@ -390,9 +383,6 @@
begin
if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
- if (CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) then
- ShowCrosshair:= (Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoCrossHair) = 0
- else ShowCrosshair:= false;
end;
if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) then State:= State or gstAttacked;
if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then ApplyAmmoChanges(CurrentHedgehog^)
--- a/hedgewars/VGSHandlers.inc Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/VGSHandlers.inc Sun Apr 17 13:33:46 2011 -0400
@@ -106,7 +106,7 @@
// up-and-down-bounce magic
s := (GameTicks + Gear^.Timer) mod 4096;
-t := 8 * AngleSin(s mod 2048).QWordValue / 4294967296;
+t := 8 * hwFloat2Float(AngleSin(s mod 2048));
if (s < 2048) then t := -t;
Gear^.Y := LAND_HEIGHT - 1184 + LongInt(Gear^.Timer mod 8) + t;
@@ -465,8 +465,8 @@
if (Gear^.Hedgehog^.Gear <> nil) then
begin
- Gear^.X:= Gear^.Hedgehog^.Gear^.X.QWordValue/4294967296 + (Gear^.Tex^.w div 2 - Gear^.FrameTicks);
- Gear^.Y:= Gear^.Hedgehog^.Gear^.Y.QWordValue/4294967296 - (16 + Gear^.Tex^.h);
+ Gear^.X:= hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + (Gear^.Tex^.w div 2 - Gear^.FrameTicks);
+ Gear^.Y:= hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) - (16 + Gear^.Tex^.h);
end;
if Gear^.Timer = 0 then
--- a/hedgewars/hwengine.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/hwengine.pas Sun Apr 17 13:33:46 2011 -0400
@@ -437,6 +437,7 @@
WriteLn(' --set-other [language file] [full screen] [show FPS]');
WriteLn(' --set-multimedia [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen]');
WriteLn(' --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]');
+ WriteLn(' --stats-only');
WriteLn();
WriteLn('Read documentation online at http://code.google.com/p/hedgewars/wiki/CommandLineOptions for more information');
WriteLn();
--- a/hedgewars/uAI.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uAI.pas Sun Apr 17 13:33:46 2011 -0400
@@ -208,6 +208,9 @@
BestRate:= RatePlace(Me);
BaseRate:= Max(BestRate, 0);
+if (Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
+ AddAction(Actions, aia_Weapon, Longword(amNothing), 100 + random(200), 0, 0);
+
while (Stack.Count > 0) and (not StopThinking) and (GameFlags and gfArtillery = 0) do
begin
Pop(ticks, Actions, Me^);
--- a/hedgewars/uAIAmmoTests.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uAIAmmoTests.pas Sun Apr 17 13:33:46 2011 -0400
@@ -115,58 +115,60 @@
implementation
uses uAIMisc, uVariables, uUtils;
-function Metric(x1, y1, x2, y2: LongInt): LongInt;
+function Metric(x1, y1, x2, y2: LongInt): LongInt; inline;
begin
Metric:= abs(x1 - x2) + abs(y1 - y2)
end;
function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-var Vx, Vy, r: hwFloat;
+var Vx, Vy, r, mX, mY: real;
rTime: LongInt;
Score, EX, EY: LongInt;
valueResult: LongInt;
function CheckTrace: LongInt;
- var x, y, dX, dY: hwFloat;
+ var x, y, dX, dY: real;
t: LongInt;
value: LongInt;
begin
- x:= Me^.X;
- y:= Me^.Y;
+ x:= mX;
+ y:= mY;
dX:= Vx;
dY:= -Vy;
t:= rTime;
repeat
x:= x + dX;
y:= y + dY;
- dX:= dX + cWindSpeed;
- dY:= dY + cGravity;
+ dX:= dX + cWindSpeedf;
+ dY:= dY + cGravityf;
dec(t)
- until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0);
- EX:= hwRound(x);
- EY:= hwRound(y);
+ until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0);
+ EX:= trunc(x);
+ EY:= trunc(y);
value:= RateExplosion(Me, EX, EY, 101);
if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
CheckTrace:= value;
end;
begin
+mX:= hwFloat2Float(Me^.X);
+mY:= hwFloat2Float(Me^.Y);
ap.Time:= 0;
rTime:= 350;
ap.ExplR:= 0;
valueResult:= BadTurn;
repeat
rTime:= rTime + 300 + Level * 50 + random(300);
- Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X + AIrndSign(2)) - Me^.X) / int2hwFloat(rTime);
- Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime);
- r:= Distance(Vx, Vy);
- if not (r > _1) then
+ Vx:= - cWindSpeedf * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Y - mY) / rTime;
+ r:= sqrt(sqr(Vx) + sqr(Vy));
+ if not (r > 1) then
begin
Score:= CheckTrace;
if valueResult <= Score then
begin
ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
- ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
+ ap.Power:= trunc(r * cMaxPower) - random((Level - 1) * 17 + 1);
ap.ExplR:= 100;
ap.ExplX:= EX;
ap.ExplY:= EY;
--- a/hedgewars/uAmmos.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uAmmos.pas Sun Apr 17 13:33:46 2011 -0400
@@ -228,7 +228,6 @@
begin
PackAmmo(Ammo, Ammoz[AmmoType].Slot);
//SwitchNotHeldAmmo(Hedgehog);
- ShowCrossHair:= false;
CurAmmoType:= amNothing
end
end
@@ -295,10 +294,6 @@
end;
TryDo(slot <= cMaxSlotIndex, 'Ammo slot index overflow', true);
CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
- if (CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) then
- ShowCrosshair:= (Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoCrossHair) = 0
- else
- ShowCrosshair:= (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoCrosshair) = 0;
end
end;
--- a/hedgewars/uConsole.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uConsole.pas Sun Apr 17 13:33:46 2011 -0400
@@ -53,7 +53,7 @@
begin
{$IFNDEF NOCONSOLE}
AddFileLog('[Con] ' + s);
-Write(s);
+Write(stderr, s);
done:= false;
while not done do
@@ -76,7 +76,7 @@
begin
{$IFNDEF NOCONSOLE}
WriteToConsole(s);
-WriteLn;
+WriteLn(stderr);
inc(CurrLine);
if CurrLine = cLinesCount then
CurrLine:= 0;
--- a/hedgewars/uFloat.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uFloat.pas Sun Apr 17 13:33:46 2011 -0400
@@ -58,6 +58,7 @@
// Returns an hwFloat that represents the value of integer parameter i
function int2hwFloat (const i: LongInt) : hwFloat; inline;
+function hwFloat2Float (const i: hwFloat) : extended; inline;
// The implemented operators
@@ -188,6 +189,12 @@
int2hwFloat.Frac:= 0
end;
+function hwFloat2Float (const i: hwFloat) : extended;
+begin
+hwFloat2Float:= i.QWordValue / $100000000;
+if i.isNegative then hwFloat2Float:=hwFloat2Float*-1;
+end;
+
operator + (const z1, z2: hwFloat) z : hwFloat;
begin
if z1.isNegative = z2.isNegative then
--- a/hedgewars/uGame.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uGame.pas Sun Apr 17 13:33:46 2011 -0400
@@ -40,7 +40,11 @@
end;
if Lag > 100 then Lag:= 100
else if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then Lag:= 2500;
-if (GameType = gmtDemo) and isSpeed then Lag:= Lag * 10;
+
+if (GameType = gmtDemo) then
+ if isSpeed then Lag:= Lag * 10
+ else
+ if cOnlyStats then Lag:= High(LongInt);
i:= 1;
while (GameState <> gsExit) and (i <= Lag) do
--- a/hedgewars/uGears.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uGears.pas Sun Apr 17 13:33:46 2011 -0400
@@ -228,7 +228,7 @@
end;
case Kind of
- gtBomb,
+ gtGrenade,
gtClusterBomb,
gtGasBomb: begin
gear^.ImpactSound:= sndGrenadeImpact;
@@ -1242,7 +1242,7 @@
gtStructure: begin
// Run the calcs only once we know we have a type that will need damage
if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
- dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY));
+ dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius);
if dmg > 1 then
begin
dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
--- a/hedgewars/uGearsRender.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uGearsRender.pas Sun Apr 17 13:33:46 2011 -0400
@@ -258,9 +258,12 @@
if (Gear^.State and gstHHDriven) <> 0 then
begin
- if ((Gear^.State and gstHHThinking) = 0) and
- ShowCrosshair and
- ((Gear^.State and gstAnimation) = 0) then
+ if ((Gear^.State and (gstHHThinking or gstAnimation)) = 0) and
+/// If current ammo is active, and current ammo has alt attack and uses a crosshair (rope, basically, right now, with no crosshair for parachute/saucer
+ (((CurAmmoGear <> nil) and //((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) and
+ ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoCrossHair) = 0)) or
+/// If no current ammo is active, and the selected ammo uses a crosshair
+ ((CurAmmoGear = nil) and ((Ammoz[HH^.CurAmmoType].Ammo.Propz and ammoprop_NoCrosshair) = 0) and ((Gear^.State and gstAttacked) = 0))) then
begin
(* These calculations are a little complex for a few reasons:
1: I need to draw the laser from weapon origin to nearest land
@@ -868,7 +871,7 @@
startX, endX, startY, endY: LongInt;
begin
case Gear^.Kind of
- gtBomb: DrawRotated(sprBomb, x, y, 0, Gear^.DirAngle);
+ gtGrenade: DrawRotated(sprBomb, x, y, 0, Gear^.DirAngle);
gtSnowball: DrawRotated(sprSnowball, x, y, 0, Gear^.DirAngle);
gtGasBomb: DrawRotated(sprCheese, x, y, 0, Gear^.DirAngle);
gtMolotov: DrawRotated(sprMolotov, x, y, 0, Gear^.DirAngle);
--- a/hedgewars/uIO.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uIO.pas Sun Apr 17 13:33:46 2011 -0400
@@ -178,10 +178,12 @@
// set RDNLY on file open
filemode:= 0;
-
+{$I-}
assign(f, fileName);
reset(f, 1);
+tryDo(IOResult = 0, 'Error opening file ' + fileName, true);
+
i:= 0; // avoid compiler hints
buf[0]:= 0;
repeat
@@ -199,6 +201,7 @@
until i = 0;
close(f)
+{$I+}
end;
procedure SendStat(sit: TStatInfoType; s: shortstring);
--- a/hedgewars/uSound.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uSound.pas Sun Apr 17 13:33:46 2011 -0400
@@ -19,33 +19,71 @@
{$INCLUDE "options.inc"}
unit uSound;
+(*
+ * This unit controls the sounds and music of the game.
+ * Doesn't really do anything if isSoundEnabled = false.
+ *
+ * There are three basic types of sound controls:
+ * Music - The background music of the game:
+ * * will only be played if isMusicEnabled = true
+ * * can be started, changed, paused and resumed
+ * Sound - Can be started and stopped
+ * Looped Sound - Subtype of sound: plays in a loop using a
+ * "channel", of which the id is returned on start.
+ * The channel id can be used to stop a specific sound loop.
+ *)
interface
uses SDLh, uConsts, uTypes, sysutils;
-var MusicFN: shortstring;
+var MusicFN: shortstring; // music file name
procedure initModule;
procedure freeModule;
-procedure InitSound;
-procedure ReleaseSound;
-procedure SoundLoad;
+procedure InitSound; // Initiates sound-system if isSoundEnabled.
+procedure ReleaseSound; // Releases sound-system and used resources.
+procedure SoundLoad; // Preloads some sounds for performance reasons.
+
+
+// MUSIC
+
+// Obvious music commands for music track specified in MusicFN.
+procedure PlayMusic;
+procedure PauseMusic;
+procedure ResumeMusic;
+procedure ChangeMusic; // Replaces music track with current MusicFN and plays it.
+
+
+// SOUNDS
+
+// Plays the sound snd [from a given voicepack],
+// if keepPlaying is given and true,
+// then the sound's playback won't be interrupted if asked to play again.
procedure PlaySound(snd: TSound);
procedure PlaySound(snd: TSound; keepPlaying: boolean);
procedure PlaySound(snd: TSound; voicepack: PVoicepack);
procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
+
+// Plays sound snd [of voicepack] in a loop, but starts with fadems milliseconds of fade-in.
+// Returns sound channel of the looped sound.
function LoopSound(snd: TSound): LongInt;
function LoopSound(snd: TSound; fadems: LongInt): LongInt;
-function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
+function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt; // WTF?
function LoopSound(snd: TSound; voicepack: PVoicepack; fadems: LongInt): LongInt;
-procedure PlayMusic;
-procedure PauseMusic;
-procedure ResumeMusic;
-procedure ChangeMusic;
+
+// Stops the normal/looped sound of the given type/in the given channel
+// [with a fade-out effect for fadems milliseconds].
procedure StopSound(snd: TSound);
procedure StopSound(chn: LongInt);
procedure StopSound(chn, fadems: LongInt);
+
+
+// MISC
+
+// Modifies the sound volume of the game by voldelta and returns the new volume level.
function ChangeVolume(voldelta: LongInt): LongInt;
+
+// Returns a pointer to the voicepack with the given name.
function AskForVoicepack(name: shortstring): Pointer;
@@ -366,6 +404,7 @@
if (MusicFN = '') or (not isMusicEnabled) then
exit;
+ // get rid of current music
if Mus <> nil then
Mix_FreeMusic(Mus);
--- a/hedgewars/uStats.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uStats.pas Sun Apr 17 13:33:46 2011 -0400
@@ -66,16 +66,16 @@
if Gear^.Health <= Gear^.Damage then
begin
- inc(CurrentHedgehog^.stats.StepKills);
+ inc(Attacker^.stats.StepKills);
inc(Kills);
inc(KillsTotal);
- inc(CurrentHedgehog^.Team^.stats.Kills);
- if (CurrentHedgehog^.Team^.TeamName =
+ inc(Attacker^.Team^.stats.Kills);
+ if (Attacker^.Team^.TeamName =
Gear^.Hedgehog^.Team^.TeamName) then begin
- inc(CurrentHedgehog^.Team^.stats.TeamKills);
- inc(CurrentHedgehog^.Team^.stats.TeamDamage, Gear^.Damage);
+ inc(Attacker^.Team^.stats.TeamKills);
+ inc(Attacker^.Team^.stats.TeamDamage, Gear^.Damage);
end;
- if CurrentHedgehog^.Team^.Clan = Gear^.Hedgehog^.Team^.Clan then inc(KillsClan);
+ if Attacker^.Team^.Clan = Gear^.Hedgehog^.Team^.Clan then inc(KillsClan);
end;
inc(Gear^.Hedgehog^.stats.StepDamageRecv, Gear^.Damage);
@@ -184,6 +184,7 @@
maxTurnSkipsName : shortstring;
maxTeamDamage : Longword;
maxTeamDamageName : shortstring;
+ winnersClan : PClan;
begin
msd:= 0; msdhh:= nil;
msk:= 0; mskhh:= nil;
@@ -191,6 +192,7 @@
maxTeamKills := 0;
maxTurnSkips := 0;
maxTeamDamage := 0;
+winnersClan:= nil;
for t:= 0 to Pred(TeamsCount) do
with TeamsArray[t]^ do
@@ -216,6 +218,7 @@
{ send player stats for winner teams }
if Clan^.ClanHealth > 0 then begin
+ winnersClan:= Clan;
SendStat(siPlayerKills, IntToStr(Clan^.Color) + ' ' +
IntToStr(stats.Kills) + ' ' + TeamName);
end;
@@ -259,6 +262,16 @@
SendStat(siMaxTeamDamage, IntToStr(maxTeamDamage) + ' ' + maxTeamDamageName);
if KilledHHs > 0 then SendStat(siKilledHHs, IntToStr(KilledHHs));
+
+// now to console
+if winnersClan <> nil then
+ begin
+ writeln('WINNERS');
+ for t:= 0 to winnersClan^.TeamsNumber - 1 do
+ writeln(winnersClan^.Teams[t]^.TeamName);
+ writeln;
+ end else
+ writeln('DRAW');
end;
procedure initModule;
--- a/hedgewars/uStore.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uStore.pas Sun Apr 17 13:33:46 2011 -0400
@@ -943,8 +943,11 @@
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
{$ELSE}
- SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, cBits, flags);
- SDLTry(SDLPrimSurface <> nil, true);
+ if not cOnlyStats then
+ begin
+ SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, cBits, flags);
+ SDLTry(SDLPrimSurface <> nil, true);
+ end;
{$ENDIF}
AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')');
--- a/hedgewars/uTypes.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uTypes.pas Sun Apr 17 13:33:46 2011 -0400
@@ -86,7 +86,7 @@
);
// Gears that interact with other Gears and/or Land
- TGearType = (gtBomb, gtHedgehog, gtShell, gtGrave, gtBee, // 4
+ TGearType = (gtGrenade, gtHedgehog, gtShell, gtGrave, gtBee, // 4
gtShotgunShot, gtPickHammer, gtRope, gtMine, gtCase, // 9
gtDEagleShot, gtDynamite, gtClusterBomb, gtCluster, gtShover, // 14
gtFlame, gtFirePunch, gtATStartGame, gtATSmoothWindCh, // 18
--- a/hedgewars/uUtils.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uUtils.pas Sun Apr 17 13:33:46 2011 -0400
@@ -42,6 +42,7 @@
function DxDy2Angle(const _dY, _dX: hwFloat): GLfloat;
function DxDy2Angle32(const _dY, _dX: hwFloat): LongInt;
function DxDy2AttackAngle(const _dY, _dX: hwFloat): LongInt;
+function DxDy2AttackAngle(const _dY, _dX: extended): LongInt;
procedure SetLittle(var r: hwFloat);
@@ -182,6 +183,11 @@
DxDy2AttackAngle:= trunc(arctan2(dY, dX) * MaxAngleDivPI)
end;
+function DxDy2AttackAngle(const _dY, _dX: extended): LongInt; inline;
+begin
+DxDy2AttackAngle:= trunc(arctan2(_dY, _dX) * (cMaxAngle/pi))
+end;
+
procedure SetLittle(var r: hwFloat);
begin
@@ -338,23 +344,27 @@
if (ParamStr(1) <> '') and (ParamStr(2) <> '') then
if (ParamCount <> 3) and (ParamCount <> cDefaultParamNum) then
begin
- for i:= 0 to 7 do
+ i:= 0;
+ while(i < 7) do
begin
assign(f, ExtractFileDir(ParamStr(2)) + '/' + cLogfileBase + inttostr(i) + '.log');
rewrite(f);
if IOResult = 0 then break;
+ inc(i)
end;
- if IOResult <> 0 then f:= stderr; // if everything fails, write to stderr
+ if i = 7 then f:= stderr; // if everything fails, write to stderr
end
else
begin
- for i:= 0 to 7 do
+ i:= 0;
+ while(i < 7) do
begin
assign(f, ParamStr(1) + '/Logs/' + cLogfileBase + inttostr(i) + '.log');
rewrite(f);
if IOResult = 0 then break;
+ inc(i)
end;
- if IOResult <> 0 then f:= stderr; // if everything fails, write to stderr
+ if i = 7 then f:= stderr; // if everything fails, write to stderr
end
else
f:= stderr;
--- a/hedgewars/uVariables.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uVariables.pas Sun Apr 17 13:33:46 2011 -0400
@@ -45,6 +45,7 @@
cReadyDelay : Longword = 5000;
cLogfileBase : shortstring = 'debug';
cStereoMode : TStereoMode = smNone;
+ cOnlyStats : boolean = False;
//////////////////////////
alsoShutdownFrontend: boolean = false;
@@ -123,7 +124,7 @@
bBetweenTurns : boolean;
bWaterRising : boolean;
- ShowCrosshair : boolean;
+ //ShowCrosshair : boolean; This variable is inconvenient to set. Easier to decide when rendering
CursorMovementX : LongInt;
CursorMovementY : LongInt;
cDrownSpeed : hwFloat;
--- a/hedgewars/uVisualGears.pas Mon Apr 11 20:53:55 2011 +0000
+++ b/hedgewars/uVisualGears.pas Sun Apr 17 13:33:46 2011 -0400
@@ -183,8 +183,8 @@
vgtExplPart2: begin
t:= random(1024);
sp:= 0.001 * (random(95) + 70);
- dx:= AngleSin(t).QWordValue/4294967296 * sp;
- dy:= AngleCos(t).QWordValue/4294967296 * sp;
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
if random(2) = 0 then dx := -dx;
if random(2) = 0 then dy := -dy;
Frame:= 7 - random(3);
@@ -193,8 +193,8 @@
vgtFire: begin
t:= random(1024);
sp:= 0.001 * (random(85) + 95);
- dx:= AngleSin(t).QWordValue/4294967296 * sp;
- dy:= AngleCos(t).QWordValue/4294967296 * sp;
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
if random(2) = 0 then dx := -dx;
if random(2) = 0 then dy := -dy;
FrameTicks:= 650 + random(250);
@@ -203,8 +203,8 @@
vgtEgg: begin
t:= random(1024);
sp:= 0.001 * (random(85) + 95);
- dx:= AngleSin(t).QWordValue/4294967296 * sp;
- dy:= AngleCos(t).QWordValue/4294967296 * sp;
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
if random(2) = 0 then dx := -dx;
if random(2) = 0 then dy := -dy;
FrameTicks:= 650 + random(250);
@@ -284,8 +284,8 @@
vgtFeather: begin
t:= random(1024);
sp:= 0.001 * (random(85) + 95);
- dx:= AngleSin(t).QWordValue/4294967296 * sp;
- dy:= AngleCos(t).QWordValue/4294967296 * sp;
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
if random(2) = 0 then dx := -dx;
if random(2) = 0 then dy := -dy;
FrameTicks:= 650 + random(250);
@@ -309,8 +309,8 @@
gear^.Frame:= random(4);
t:= random(1024);
sp:= 0.001 * (random(85) + 47);
- dx:= AngleSin(t).QWordValue/4294967296 * sp;
- dy:= AngleCos(t).QWordValue/4294967296 * sp * -2;
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp * -2;
if random(2) = 0 then dx := -dx;
end;
vgtNote: begin
Binary file share/hedgewars/Data/Fonts/DejaVuSans-Bold.ttf has changed
--- a/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua Mon Apr 11 20:53:55 2011 +0000
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua Sun Apr 17 13:33:46 2011 -0400
@@ -1,4 +1,5 @@
loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
local weapons = { amGrenade, amClusterBomb, amBazooka, amBee, amShotgun, amMine, amDEagle, amDynamite, amFirePunch, amWhip, amPickHammer, amBaseballBat, amMortar, amCake, amSeduction, amWatermelon, amHellishBomb, amDrill, amBallgun, amRCPlane, amSniperRifle, amMolotov, amBirdy, amBlowTorch, amGasBomb, amFlamethrower, amSMine, amKamikaze }
@@ -15,12 +16,89 @@
-- T,G,S,L,R,R,P,J,P,S
local utilities_values = {1,2,2,1,2,2,1,2,2,2}
+function randomAmmo()
+ local n = 3 --"points" to be allocated on weapons
+
+ --pick random weapon and subtract cost
+ local r = GetRandom(table.maxn(weapons_values)) + 1
+ local picked_items = {}
+ table.insert(picked_items, weapons[r])
+ n = n - weapons_values[r]
+
+
+ --choose any weapons or utilities to use up remaining n
+
+ while n > 0 do
+ local items = {}
+ local items_values = {}
+
+ for i, w in pairs(weapons_values) do
+ local used = false
+ if w <= n then
+ --check that this weapon hasn't been given already
+ for j, k in pairs(picked_items) do
+ if weapons[i] == k then
+ used = true
+ end
+ end
+ if not used then
+ table.insert(items_values, w)
+ table.insert(items, weapons[i])
+ end
+ end
+ end
+
+ for i, w in pairs(utilities_values) do
+ local used = false
+ if w <= n then
+ --check that this weapon hasn't been given already
+ for j, k in pairs(picked_items) do
+ if utilities[i] == k then
+ used = true
+ end
+ end
+ if not used then
+ table.insert(items_values, w)
+ table.insert(items, utilities[i])
+ end
+ end
+ end
+
+ local r = GetRandom(table.maxn(items_values)) + 1
+ table.insert(picked_items, items[r])
+ n = n - items_values[r]
+ end
+
+ return picked_items
+end
+
+function assignAmmo(hog)
+ local name = GetHogTeamName(hog)
+ local processed = getTeamValue(name, "processed")
+ if processed == nil or not processed then
+ local ammo = getTeamValue(name, "ammo")
+ if ammo == nil then
+ ammo = randomAmmo()
+ setTeamValue(name, "ammo", ammo)
+ end
+ for i, w in pairs(ammo) do
+ AddAmmo(hog, w)
+ end
+ setTeamValue(name, "processed", true)
+ end
+end
+
+function reset(hog)
+ setTeamValue(GetHogTeamName(hog), "processed", false)
+end
+
function onGameInit()
GameFlags = band(bor(GameFlags, gfResetWeps), bnot(gfPerHogAmmo))
- Goals = loc("Each turn you get 1-3 random weapons|The stronger they are, the fewer you get")
+ Goals = loc("Each turn you get 1-3 random weapons")
end
function onGameStart()
+ trackTeams()
if MapHasBorder() == false then
for i, w in pairs(airweapons) do
table.insert(weapons, w)
@@ -29,8 +107,6 @@
table.insert(weapons_values, w)
end
end
-
- --ShowMission(loc("Balanced Random Weapons"), loc("A game of luck"), loc("Each turn you'll get a weapon, and if it sucks you'll get some more!"), -amSkip, 0)
end
function onAmmoStoreInit()
@@ -56,57 +132,17 @@
end
function onNewTurn()
- local n = 3 --"points" to be allocated on weapons
-
- --pick random weapon and subtract cost
- local r = GetRandom(table.maxn(weapons_values)) + 1
- AddAmmo(CurrentHedgehog, weapons[r])
- local items_used = {}
- items_used[1] = weapons[r]
- n = n - weapons_values[r]
-
-
- --choose any weapons or utilities to use up remaining n
-
- while n > 0 do
- local items = {}
- local items_values = {}
+ runOnGears(assignAmmo)
+ runOnGears(reset)
+ setTeamValue(GetHogTeamName(CurrentHedgehog), "ammo", nil)
+end
- for i, w in pairs(weapons_values) do
- local used = false
- if w <= n then
- --check that this weapon hasn't been given already
- for j = 1, table.maxn(items_used) do
- if weapons[i] == items_used[j] then
- used = true
- end
- end
- if not used then
- table.insert(items_values, w)
- table.insert(items, weapons[i])
- end
- end
- end
-
- for i, w in pairs(utilities_values) do
- local used = false
- if w <= n then
- --check that this weapon hasn't been given already
- for j = 1, table.maxn(items_used) do
- if utilities[i] == items_used[j] then
- used = true
- end
- end
- if not used then
- table.insert(items_values, w)
- table.insert(items, utilities[i])
- end
- end
- end
-
- local r = GetRandom(table.maxn(items_values)) + 1
- AddAmmo(CurrentHedgehog, items[r])
- table.insert(items_used, items[r])
- n = n - items_values[r]
+function onGearAdd(gear)
+ if GetGearType(gear) == gtHedgehog then
+ trackGear(gear)
end
end
+
+function onGearDelete(gear)
+ trackDeletion(gear)
+end
--- a/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua Mon Apr 11 20:53:55 2011 +0000
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua Sun Apr 17 13:33:46 2011 -0400
@@ -1,32 +1,72 @@
+-- Random Weapons, example for gameplay scripts
+
+-- Load the library for localisation ("loc" function)
loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+-- Load the gear tracker
+loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+
+-- List of available weapons
local weapons = { amGrenade, amClusterBomb, amBazooka, amBee, amShotgun,
amMine, amDEagle, amDynamite, amFirePunch, amWhip, amPickHammer,
amBaseballBat, amTeleport, amMortar, amCake, amSeduction,
amWatermelon, amHellishBomb, amDrill, amBallgun, amRCPlane,
amSniperRifle, amMolotov, amBirdy, amBlowTorch, amGasBomb,
- amFlamethrower, amSMine, amHammer, amSnowball, amTardis, amStructure }
+ amFlamethrower, amSMine, amHammer }
+-- List of weapons that attack from the air
local airweapons = { amAirAttack, amMineStrike, amNapalm, amDrillStrike }
+-- Function that assigns the team their weapon
+function assignAmmo(hog)
+ -- Get name of the current team
+ local name = GetHogTeamName(hog)
+ -- Get whither the team has been processed
+ local processed = getTeamValue(name, "processed")
+ -- If it has not, process it
+ if processed == nil or not processed then
+ -- Get the ammo for this hog's team
+ local ammo = getTeamValue(name, "ammo")
+ -- If there is no ammo, get a random one from the list and store it
+ if ammo == nil then
+ ammo = weapons[GetRandom(table.maxn(weapons)) + 1]
+ setTeamValue(name, "ammo", ammo)
+ end
+ -- Add the ammo for the hog
+ AddAmmo(hog, ammo)
+ -- Mark as processed
+ setTeamValue(name, "processed", true)
+ end
+end
+
+-- Mark team as not processed
+function reset(hog)
+ setTeamValue(GetHogTeamName(hog), "processed", false)
+end
function onGameInit()
+ -- Limit flags that can be set, but allow game schemes to be used
GameFlags = band(bor(GameFlags, gfResetWeps), bnot(gfInfAttack + gfPerHogAmmo))
+ -- Set a custom game goal that will show together with the scheme ones
Goals = loc("Each turn you get one random weapon")
end
function onGameStart()
+ -- Initialize the tracking of hogs and teams
+ trackTeams()
+ -- Add air weapons to the game if the border is not active
if MapHasBorder() == false then
for i, w in pairs(airweapons) do
table.insert(weapons, w)
end
end
- --ShowMission(loc("Random Weapons"), loc("A game of luck"), loc("There has been a mix-up with your gear and now you|have to utilize whatever is coming your way!"), -amSkip, 0)
end
function onAmmoStoreInit()
+ -- Allow skip at all times
SetAmmo(amSkip, 9, 0, 0, 0)
+ -- Let utilities be available through crates
SetAmmo(amParachute, 0, 1, 0, 1)
SetAmmo(amGirder, 0, 1, 0, 2)
SetAmmo(amSwitch, 0, 1, 0, 1)
@@ -40,15 +80,34 @@
SetAmmo(amPortalGun, 0, 1, 0, 1)
SetAmmo(amResurrector, 0, 1, 0, 1)
+ -- Allow weapons to be used
for i, w in pairs(weapons) do
SetAmmo(w, 0, 0, 0, 1)
end
+ -- Allow air weapons to be used
for i, w in pairs(airweapons) do
SetAmmo(w, 0, 0, 0, 1)
end
end
function onNewTurn()
- AddAmmo(CurrentHedgehog, weapons[GetRandom(table.maxn(weapons)) + 1])
+ -- Give every team their weapons, so one can plan during anothers turn
+ runOnGears(assignAmmo)
+ -- Mark all teams as not processed
+ runOnGears(reset)
+ -- Set the current teams weapons to nil so they will get new after the turn has ended
+ setTeamValue(GetHogTeamName(CurrentHedgehog), "ammo", nil)
end
+
+function onGearAdd(gear)
+ -- Catch hedgehogs for the tracker
+ if GetGearType(gear) == gtHedgehog then
+ trackGear(gear)
+ end
+end
+
+function onGearDelete(gear)
+ -- Remove hogs that are gone
+ trackDeletion(gear)
+end
--- a/share/hedgewars/Data/Scripts/Tracker.lua Mon Apr 11 20:53:55 2011 +0000
+++ b/share/hedgewars/Data/Scripts/Tracker.lua Sun Apr 17 13:33:46 2011 -0400
@@ -274,15 +274,3 @@
end
end
end
-
-function numGears()
- return table.maxn(gears)
-end
-
-function numTeams()
- num = 0
- for team, hogs in pairs(teams) do
- num = num + 1
- end
- return num
-end