# HG changeset patch # User nemo # Date 1303061626 14400 # Node ID 589f69a9665c9b46d015a88d5bc6e31f5d0b6cf1 # Parent cbadb9fa52fc38c231b80b550488c3f3cc65f3cd# Parent 18f9546acb41483dc7a3c71c6191741cf2423657 merge in japanese updates diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/chatwidget.cpp --- 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 items = chatNicks->findItems(nick, Qt::MatchExactly); - for(QList::iterator it=items.begin(); it!=items.end();) { - chatNicks->takeItem(chatNicks->row(*it)); - ++it; - } + QListIterator it(items); + while(it.hasNext()) chatNicks->takeItem(chatNicks->row(it.next())); lblCount->setText(QString::number(chatNicks->count())); } diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/game.cpp --- 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 teams = m_pTeamSelWidget->getPlayingTeams(); - for(QList::iterator it = teams.begin(); it != teams.end(); ++it) + QListIterator 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 teams = m_pTeamSelWidget->getPlayingTeams(); - for(QList::iterator it = teams.begin(); it != teams.end(); ++it) - HWProto::addStringToBuffer(buf, QString("eteamgone %1").arg((*it).TeamName)); + QListIterator it(m_pTeamSelWidget->getPlayingTeams()); + while(it.hasNext()) + HWProto::addStringToBuffer(buf, QString("eteamgone %1").arg(it.next().TeamName)); RawSendIPC(buf); } } diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/hwform.cpp --- 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 teams = curTeamSelWidget->getDontPlayingTeams(); QStringList tmnames; - for(QList::iterator it = teams.begin(); it != teams.end(); ++it) { - tmnames += it->TeamName; - } + QListIterator it(curTeamSelWidget->getDontPlayingTeams()); + while(it.hasNext()) tmnames += it.next().TeamName; + //UpdateTeamsLists(&tmnames); // FIXME: still need more work if teamname is updated while configuring UpdateTeamsLists(); diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/netudpserver.cpp --- 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); } } } diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/netudpserver.h --- 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 diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/netudpwidget.cpp --- 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); } } diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/pageconnecting.cpp --- 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())); } diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/pages.h --- 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 diff -r 18f9546acb41 -r 589f69a9665c QTfrontend/teamselect.cpp --- 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& teamslist) { - QList::iterator it; //for(it=curPlayingTeams.begin(); it!=curPlayingTeams.end(); it++) { //framePlaying->removeTeam(*it); //} @@ -256,9 +255,8 @@ frameDontPlaying->resetTeams(); curDontPlayingTeams.clear(); - for (QList::ConstIterator it = teamslist.begin(); it != teamslist.end(); ++it ) { - addTeam(*it); - } + QListIterator it(teamslist); + while(it.hasNext()) addTeam(it.next()); } bool TeamSelWidget::isPlaying(HWTeam team) const diff -r 18f9546acb41 -r 589f69a9665c gameServer/Actions.hs --- 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 diff -r 18f9546acb41 -r 589f69a9665c gameServer/CoreTypes.hs --- 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 diff -r 18f9546acb41 -r 589f69a9665c gameServer/HWProtoInRoomState.hs --- 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, diff -r 18f9546acb41 -r 589f69a9665c gameServer/OfficialServer/GameReplayStore.hs --- /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 diff -r 18f9546acb41 -r 589f69a9665c hedgewars/ArgParsers.inc --- 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; diff -r 18f9546acb41 -r 589f69a9665c hedgewars/GSHandlers.inc --- 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 diff -r 18f9546acb41 -r 589f69a9665c hedgewars/HHHandlers.inc --- 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^) diff -r 18f9546acb41 -r 589f69a9665c hedgewars/VGSHandlers.inc --- 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 diff -r 18f9546acb41 -r 589f69a9665c hedgewars/hwengine.pas --- 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(); diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uAI.pas --- 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^); diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uAIAmmoTests.pas --- 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; diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uAmmos.pas --- 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; diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uConsole.pas --- 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; diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uFloat.pas --- 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 diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uGame.pas --- 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 diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uGears.pas --- 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); diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uGearsRender.pas --- 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); diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uIO.pas --- 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); diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uSound.pas --- 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); diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uStats.pas --- 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; diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uStore.pas --- 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))) + ')'); diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uTypes.pas --- 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 diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uUtils.pas --- 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; diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uVariables.pas --- 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; diff -r 18f9546acb41 -r 589f69a9665c hedgewars/uVisualGears.pas --- 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 diff -r 18f9546acb41 -r 589f69a9665c share/hedgewars/Data/Fonts/DejaVuSans-Bold.ttf Binary file share/hedgewars/Data/Fonts/DejaVuSans-Bold.ttf has changed diff -r 18f9546acb41 -r 589f69a9665c share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua --- 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 diff -r 18f9546acb41 -r 589f69a9665c share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua --- 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 diff -r 18f9546acb41 -r 589f69a9665c share/hedgewars/Data/Scripts/Tracker.lua --- 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