# HG changeset patch # User smxx # Date 1265316303 0 # Node ID 7889a3a9724f78c2f3efd39107beaafc8a1783f9 # Parent 55593f8a490b17eec870193ea45e05c668aa31be Server: * Added support for flags (this still needs further adjustments to restore compatibility with older versions (team datasets)!) Engine: * Added support for flags * Added weapon tooltips * Moved SplitBySpace to uMisc * Set file operations to readonly to avoid conflicts running multiple copies networked and synced on one (fast) machine * Flash active team while green arrow is shown (waiting for input or camera centered on active hog) * Updated English locale Frontend: * Added support for flags * Added flag selection to edit team page * Added checkbox for weapon tooltips in options * "Random team" button may now be translated * Disabled "official server" button till protocol is handled for all versions (see above; nemo's server is updated to new protocol) Graphics: * Added basic set of example flags diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/game.cpp --- a/QTfrontend/game.cpp Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/game.cpp Thu Feb 04 20:45:03 2010 +0000 @@ -290,6 +290,7 @@ #else arguments << "0"; #endif + arguments << (config->isWeaponTooltip() ? "1" : "0"); arguments << tr("en.txt"); arguments << QString::number(config->volume()); // sound volume arguments << QString::number(config->timerInterval()); diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/gameuiconfig.cpp --- a/QTfrontend/gameuiconfig.cpp Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/gameuiconfig.cpp Thu Feb 04 20:45:03 2010 +0000 @@ -39,6 +39,8 @@ //Form->resize(value("window/width", 640).toUInt(), value("window/height", 450).toUInt()); resizeToConfigValues(); + Form->ui.pageOptions->WeaponTooltip->setChecked(value("misc/WeaponTooltip", true).toBool()); + int t = Form->ui.pageOptions->CBResolution->findText(value("video/resolution").toString()); Form->ui.pageOptions->CBResolution->setCurrentIndex((t < 0) ? 0 : t); Form->ui.pageOptions->CBFullscreen->setChecked(value("video/fullscreen", false).toBool()); @@ -111,6 +113,8 @@ setValue("video/frontendeffects", isFrontendEffects()); + setValue("misc/WeaponTooltip", isWeaponTooltip()); + bool ffscr = isFrontendFullscreen(); setValue("video/frontendfullscreen", ffscr); emit frontendFullscreen(ffscr); @@ -171,6 +175,11 @@ return Form->ui.pageOptions->CBFrontendEffects->isChecked(); } +bool GameUIConfig::isWeaponTooltip() const +{ + return Form->ui.pageOptions->WeaponTooltip->isChecked(); +} + bool GameUIConfig::isFrontendFullscreen() const { return Form->ui.pageOptions->CBFrontendFullscreen->isChecked(); diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/gameuiconfig.h --- a/QTfrontend/gameuiconfig.h Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/gameuiconfig.h Thu Feb 04 20:45:03 2010 +0000 @@ -50,6 +50,7 @@ bool isReducedQuality() const; bool isFrontendEffects() const; bool isFrontendFullscreen() const; + bool isWeaponTooltip() const; void resizeToConfigValues(); #ifdef __APPLE__ diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/newnetclient.cpp --- a/QTfrontend/newnetclient.cpp Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/newnetclient.cpp Thu Feb 04 20:45:03 2010 +0000 @@ -111,6 +111,7 @@ team.Grave + delimeter + team.Fort + delimeter + team.Voicepack + delimeter + + team.Flag + delimeter + QString::number(team.difficulty); for(int i = 0; i < 8; ++i) @@ -322,7 +323,7 @@ } if (lst[0] == "ADD_TEAM") { - if(lst.size() != 23) + if(lst.size() != 24) { qWarning("Net: Bad ADDTEAM message"); return; diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/pages.cpp --- a/QTfrontend/pages.cpp Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/pages.cpp Thu Feb 04 20:45:03 2010 +0000 @@ -155,7 +155,7 @@ } - randTeamButton = addButton("Random Team", GBHLayout, 9, false); + randTeamButton = addButton(QPushButton::tr("Random Team"), GBHLayout, 9, false); vbox1->addWidget(GBoxHedgehogs); @@ -184,6 +184,11 @@ CBGrave->setIconSize(QSize(32, 32)); GBTLayout->addWidget(CBGrave); + CBFlag = new QComboBox(GBoxTeam); + CBFlag->setMaxCount(65535); + CBFlag->setIconSize(QSize(22, 15)); + GBTLayout->addWidget(CBFlag); + { QHBoxLayout * hbox = new QHBoxLayout(); CBVoicepack = new QComboBox(GBoxTeam); @@ -232,6 +237,16 @@ CBGrave->addItem(icon, (*it).replace(QRegExp("^(.*)\\.png"), "\\1")); } + tmpdir.cd(datadir->absolutePath()); + tmpdir.cd("Graphics/Flags"); + list = tmpdir.entryList(QStringList("*.png")); + for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) + { + QPixmap pix(datadir->absolutePath() + "/Graphics/Flags/" + *it); + QIcon icon(pix.copy(0, 0, 22, 15)); + CBFlag->addItem(icon, (*it).replace(QRegExp("^(.*)\\.png"), "\\1")); + } + vbox1->addStretch(); vbox2->addStretch(); // vbox3->addStretch(); @@ -388,6 +403,11 @@ WeaponsName = new QComboBox(this); WeaponsLayout->addWidget(WeaponsName, 0, 0, 1, 2); WeaponEdit = addButton(tr("Edit"), WeaponsLayout, 1, 1); + + WeaponTooltip = new QCheckBox(this); + WeaponTooltip->setText(QCheckBox::tr("Show ammo menu tooltips")); + WeaponsLayout->addWidget(WeaponTooltip, 2, 0, 1, 2); + gbTBLayout->addWidget(groupWeapons, 1, 0); } @@ -1293,5 +1313,8 @@ BtnLAN = addButton(tr("LAN game"), pageLayout, 1, 2); BtnOfficialServer = addButton(tr("Official server"), pageLayout, 2, 2); + // hack: temporary deactivated - requires server modifications that aren't backward compatible (yet) + BtnOfficialServer->setEnabled(false); + BtnBack = addButton(":/res/Exit.png", pageLayout, 4, 0, true); } diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/pages.h --- a/QTfrontend/pages.h Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/pages.h Thu Feb 04 20:45:03 2010 +0000 @@ -156,6 +156,7 @@ QComboBox *CBFort; SquareLabel *FortPreview; QComboBox *CBGrave; + QComboBox *CBFlag; QComboBox *CBTeamLvl; QComboBox *CBVoicepack; QGroupBox *GBoxBinds; @@ -200,9 +201,10 @@ public: PageOptions(QWidget* parent = 0); - QPushButton* WeaponsButt; - QPushButton* WeaponEdit; - QComboBox* WeaponsName; + QPushButton *WeaponsButt; + QPushButton *WeaponEdit; + QComboBox *WeaponsName; + QCheckBox *WeaponTooltip; QPushButton *BtnBack; IconedGroupBox *teamsBox; diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/team.cpp --- a/QTfrontend/team.cpp Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/team.cpp Thu Feb 04 20:45:03 2010 +0000 @@ -42,6 +42,7 @@ Grave = "Statue"; Fort = "Plane"; Voicepack = "Default"; + Flag = "hedgewars"; for(int i = 0; i < BINDS_NUMBER; i++) { binds[i].action = cbinds[i].action; @@ -54,17 +55,18 @@ m_isNetTeam(true) { // net teams are configured from QStringList - if(strLst.size() != 22) throw HWTeamConstructException(); + if(strLst.size() != 23) throw HWTeamConstructException(); TeamName = strLst[0]; Grave = strLst[1]; Fort = strLst[2]; Voicepack = strLst[3]; - Owner = strLst[4]; - difficulty = strLst[5].toUInt(); + Flag = strLst[4]; + Owner = strLst[5]; + difficulty = strLst[6].toUInt(); for(int i = 0; i < 8; i++) { - HHName[i]=strLst[i * 2 + 6]; - HHHat[i]=strLst[i * 2 + 7]; + HHName[i]=strLst[i * 2 + 7]; + HHHat[i]=strLst[i * 2 + 8]; } } @@ -83,6 +85,7 @@ Grave = QString("Simple"); // default Fort = QString("Island"); // default Voicepack = "Default"; + Flag = "hedgewars"; for(int i = 0; i < BINDS_NUMBER; i++) { @@ -137,6 +140,11 @@ str.remove(0, 5); Fort = str; } else + if (str.startsWith("flag ")) + { + str.remove(0, 5); + Flag = str; + } else if (str.startsWith("voicepack ")) { str.remove(0, 10); @@ -188,6 +196,7 @@ stream << "grave " << Grave << endl; stream << "fort " << Fort << endl; stream << "voicepack " << Voicepack << endl; + stream << "flag " << Flag << endl; for(int i = 0; i < BINDS_NUMBER; i++) { stream << "bind " << binds[i].strbind << " " << binds[i].action << endl; @@ -207,6 +216,7 @@ hwform->ui.pageEditTeam->HHHats[i]->setCurrentIndex(hwform->ui.pageEditTeam->HHHats[i]->findData(HHHat[i], Qt::DisplayRole)); } hwform->ui.pageEditTeam->CBGrave->setCurrentIndex(hwform->ui.pageEditTeam->CBGrave->findText(Grave)); + hwform->ui.pageEditTeam->CBFlag->setCurrentIndex(hwform->ui.pageEditTeam->CBFlag->findText(Flag)); hwform->ui.pageEditTeam->CBFort->setCurrentIndex(hwform->ui.pageEditTeam->CBFort->findText(Fort)); hwform->ui.pageEditTeam->CBVoicepack->setCurrentIndex(hwform->ui.pageEditTeam->CBVoicepack->findText(Voicepack)); @@ -231,6 +241,7 @@ Grave = hwform->ui.pageEditTeam->CBGrave->currentText(); Fort = hwform->ui.pageEditTeam->CBFort->currentText(); Voicepack = hwform->ui.pageEditTeam->CBVoicepack->currentText(); + Flag = hwform->ui.pageEditTeam->CBFlag->currentText(); for(int i = 0; i < BINDS_NUMBER; i++) { binds[i].strbind = hwform->ui.pageEditTeam->CBBind[i]->itemData(hwform->ui.pageEditTeam->CBBind[i]->currentIndex()).toString(); @@ -248,6 +259,7 @@ sl.push_back(QString("egrave " + Grave)); sl.push_back(QString("efort " + Fort)); sl.push_back(QString("evoicepack " + Voicepack)); + sl.push_back(QString("eflag " + Flag)); if (!m_isNetTeam) for(int i = 0; i < BINDS_NUMBER; i++) diff -r 55593f8a490b -r 7889a3a9724f QTfrontend/team.h --- a/QTfrontend/team.h Thu Feb 04 18:46:49 2010 +0000 +++ b/QTfrontend/team.h Thu Feb 04 20:45:03 2010 +0000 @@ -45,6 +45,7 @@ QString HHHat[8]; QString Grave; QString Fort; + QString Flag; QString Voicepack; QString Owner; unsigned int difficulty; diff -r 55593f8a490b -r 7889a3a9724f gameServer/CoreTypes.hs --- a/gameServer/CoreTypes.hs Thu Feb 04 18:46:49 2010 +0000 +++ b/gameServer/CoreTypes.hs Thu Feb 04 20:45:03 2010 +0000 @@ -55,6 +55,7 @@ teamgrave :: String, teamfort :: String, teamvoicepack :: String, + teamflag :: String, difficulty :: Int, hhnum :: Int, hedgehogs :: [HedgehogInfo] diff -r 55593f8a490b -r 7889a3a9724f gameServer/HWProtoInRoomState.hs --- a/gameServer/HWProtoInRoomState.hs Thu Feb 04 18:46:49 2010 +0000 +++ b/gameServer/HWProtoInRoomState.hs Thu Feb 04 20:45:03 2010 +0000 @@ -42,7 +42,7 @@ where client = clients IntMap.! clID -handleCmd_inRoom clID clients rooms ("ADD_TEAM" : name : color : grave : fort : voicepack : difStr : hhsInfo) +handleCmd_inRoom clID clients rooms ("ADD_TEAM" : name : color : grave : fort : voicepack : flag : difStr : hhsInfo) | length hhsInfo /= 16 = [] | length (teams room) == 6 = [Warning "too many teams"] | canAddNumber <= 0 = [Warning "too many hedgehogs"] @@ -61,7 +61,7 @@ room = rooms IntMap.! (roomID client) canAddNumber = 48 - (sum . map hhnum $ teams room) findTeam = find (\t -> name == teamname t) $ teams room - newTeam = (TeamInfo clID (nick client) name color grave fort voicepack difficulty newTeamHHNum (hhsList hhsInfo)) + newTeam = (TeamInfo clID (nick client) name color grave fort voicepack flag difficulty newTeamHHNum (hhsList hhsInfo)) difficulty = fromMaybe 0 (maybeRead difStr :: Maybe Int) hhsList [] = [] hhsList (n:h:hhs) = HedgehogInfo n h : hhsList hhs diff -r 55593f8a490b -r 7889a3a9724f gameServer/HWProtoNEState.hs --- a/gameServer/HWProtoNEState.hs Thu Feb 04 18:46:49 2010 +0000 +++ b/gameServer/HWProtoNEState.hs Thu Feb 04 20:45:03 2010 +0000 @@ -13,7 +13,7 @@ handleCmd_NotEntered clID clients _ ["NICK", newNick] | not . null $ nick client = [ProtocolError "Nickname already chosen"] - | haveSameNick = [AnswerThisClient ["WARNING", "Nickname collision"], ByeClient ""] + | haveSameNick = [AnswerThisClient ["WARNING", "Nickname already in use"], ByeClient ""] | illegalName newNick = [ByeClient "Illegal nickname"] | otherwise = ModifyClient (\c -> c{nick = newNick}) : diff -r 55593f8a490b -r 7889a3a9724f gameServer/Utils.hs --- a/gameServer/Utils.hs Thu Feb 04 18:46:49 2010 +0000 +++ b/gameServer/Utils.hs Thu Feb 04 20:45:03 2010 +0000 @@ -59,6 +59,7 @@ teamgrave team, teamfort team, teamvoicepack team, + teamflag team, teamowner team, show $ difficulty team ] diff -r 55593f8a490b -r 7889a3a9724f hedgewars/CCHandlers.inc --- a/hedgewars/CCHandlers.inc Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/CCHandlers.inc Thu Feb 04 20:45:03 2010 +0000 @@ -123,6 +123,14 @@ CurrentTeam^.voicepack:= AskForVoicepack(s) end; +procedure chFlag(var s: shortstring); +begin +if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/flag"', true); +if s[1]='"' then Delete(s, 1, 1); +if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1); +CurrentTeam^.flag:= s +end; + procedure chAddHH(var id: shortstring); var s: shortstring; Gear: PGear; diff -r 55593f8a490b -r 7889a3a9724f hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/hwengine.pas Thu Feb 04 20:45:03 2010 +0000 @@ -440,7 +440,7 @@ begin case ParamCount of - 17: begin + 18: begin val(ParamStr(2), cScreenWidth); val(ParamStr(3), cScreenHeight); cInitWidth:= cScreenWidth; @@ -451,15 +451,16 @@ cFullScreen:= ParamStr(6) = '1'; isSoundEnabled:= ParamStr(7) = '1'; cVSyncInUse:= ParamStr(8) = '1'; - cLocaleFName:= ParamStr(9); - val(ParamStr(10), cInitVolume); - val(ParamStr(11), cTimerInterval); - PathPrefix:= ParamStr(12); - cShowFPS:= ParamStr(13) = '1'; - cAltDamage:= ParamStr(14) = '1'; - UserNick:= DecodeBase64(ParamStr(15)); - isMusicEnabled:= ParamStr(16) = '1'; - cReducedQuality:= ParamStr(17) = '1'; + cWeaponTooltips:= ParamStr(9) = '1'; + cLocaleFName:= ParamStr(10); + val(ParamStr(11), cInitVolume); + val(ParamStr(12), cTimerInterval); + PathPrefix:= ParamStr(13); + cShowFPS:= ParamStr(14) = '1'; + cAltDamage:= ParamStr(15) = '1'; + UserNick:= DecodeBase64(ParamStr(16)); + isMusicEnabled:= ParamStr(17) = '1'; + cReducedQuality:= ParamStr(18) = '1'; end; 3: begin val(ParamStr(2), ipcPort); diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uConsole.pas --- a/hedgewars/uConsole.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uConsole.pas Thu Feb 04 20:45:03 2010 +0000 @@ -33,7 +33,6 @@ procedure ParseCommand(CmdStr: shortstring; TrustedSource: boolean); procedure StopMessages(Message: Longword); function GetLastConsoleLine: shortstring; -procedure SplitBySpace(var a, b: shortstring); procedure doPut(putX, putY: LongInt; fromAI: boolean); @@ -99,19 +98,6 @@ end; end; -procedure SplitBySpace(var a, b: shortstring); -var i, t: LongInt; -begin -i:= Pos(' ', a); -if i > 0 then - begin - for t:= 1 to Pred(i) do - if (a[t] >= 'A')and(a[t] <= 'Z') then Inc(a[t], 32); - b:= copy(a, i + 1, Length(a) - i); - byte(a[0]):= Pred(i) - end else b:= ''; -end; - procedure WriteToConsole(s: shortstring); var Len: LongInt; done: boolean; @@ -318,6 +304,7 @@ RegisterVariable('-cur_l' , vtCommand, @chCurL_m , true ); RegisterVariable('+cur_r' , vtCommand, @chCurR_p , true ); RegisterVariable('-cur_r' , vtCommand, @chCurR_m , true ); + RegisterVariable('flag' , vtCommand, @chFlag , false); end; procedure free_uConsole; diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uConsts.pas Thu Feb 04 20:45:03 2010 +0000 @@ -45,7 +45,7 @@ TPathType = (ptNone, ptData, ptGraphics, ptThemes, ptCurrTheme, ptTeams, ptMaps, ptMapCurrent, ptDemos, ptSounds, ptGraves, ptFonts, ptForts, - ptLocale, ptAmmoMenu, ptHedgehog, ptVoices, ptHats); + ptLocale, ptAmmoMenu, ptHedgehog, ptVoices, ptHats, ptFlags); TSprite = (sprWater, sprCloud, sprBomb, sprBigDigit, sprFrame, sprLag, sprArrow, sprGrenade, sprTargetP, sprUFO, @@ -182,9 +182,10 @@ cWhiteColorChannels : TSDL_Color = (r:$FF; g:$FF; b:$FF; unused:$FF); cNearBlackColorChannels : TSDL_Color = (r:$00; g:$00; b:$10; unused:$FF); - cWhiteColor : Longword = $FFFFFFFF; - cYellowColor : Longword = $FFFFFF00; - cExplosionBorderColor : LongWord = $FF808080; + cWhiteColor : Longword = $FFFFFFFF; + cYellowColor : Longword = $FFFFFF00; + cNearBlackColor : Longword = $FF000010; + cExplosionBorderColor : LongWord = $FF808080; {$WARNINGS OFF} cAirPlaneSpeed: hwFloat = (isNegative: false; QWordValue: 3006477107); // 1.4 @@ -352,7 +353,8 @@ ammoprop_AltUse = $00000400; ammoprop_NotBorder = $00000800; ammoprop_Utility = $00001000; - + ammoprop_NoRoundEndHint=$10000000; + AMMO_INFINITE = 100; EXPLAllDamageInRadius = $00000001; @@ -493,7 +495,7 @@ (FileName: 'AmmoName'; Path: ptAmmoMenu; AltPath: ptNone; Texture: nil; Surface: nil; Width: 202; Height: 33; imageWidth: 0; imageHeight: 0; saveSurf: false),// sprAMSlotName (FileName: 'Ammos'; Path: ptAmmoMenu; AltPath: ptNone; Texture: nil; Surface: nil; - Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false),// sprAMAmmos + Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: true),// sprAMAmmos (FileName: 'SlotKeys'; Path: ptAmmoMenu; AltPath: ptNone; Texture: nil; Surface: nil; Width: 32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false),// sprAMSlotKeys (FileName: 'Selection'; Path: ptAmmoMenu; AltPath: ptNone; Texture: nil; Surface: nil; @@ -918,13 +920,16 @@ NameTex: nil; Probability: 100; NumberInCase: 3; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_AttackInMove or ammoprop_AltAttack; - Count: 5; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amRope; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_ForwMsgs or + ammoprop_AttackInMove or + ammoprop_AltAttack; + Count: 5; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amRope; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -1051,7 +1056,8 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_ForwMsgs or ammoprop_AttackInMove or ammoprop_NoCrosshair or ammoprop_DontHold or @@ -1139,13 +1145,16 @@ NameTex: nil; Probability: 150; NumberInCase: 3; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_NeedTarget or ammoprop_AttackingPut; - Count: 1; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amGirder; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_NoCrosshair or + ammoprop_NeedTarget or + ammoprop_AttackingPut; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amGirder; + AttackVoice: sndNone); Slot: 6; TimeAfterTurn: 3000; minAngle: 0; @@ -1181,13 +1190,16 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_NoCrosshair or ammoprop_DontHold; - Count: 3; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amSwitch; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_ForwMsgs or + ammoprop_NoCrosshair or + ammoprop_DontHold; + Count: 3; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amSwitch; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1396,13 +1408,17 @@ NameTex: nil; Probability: 20; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_AltUse or ammoprop_Utility; - Count: 1; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amLowGravity; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_NoCrosshair or + ammoprop_DontHold or + ammoprop_AltUse or + ammoprop_Utility; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amLowGravity; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1415,13 +1431,17 @@ NameTex: nil; Probability: 15; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_AltUse or ammoprop_Utility; - Count: 1; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amExtraDamage; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_NoCrosshair or + ammoprop_DontHold or + ammoprop_AltUse or + ammoprop_Utility; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amExtraDamage; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1434,13 +1454,17 @@ NameTex: nil; Probability: 20; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_AltUse or ammoprop_Utility; - Count: 1; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amInvulnerable; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_NoCrosshair or + ammoprop_DontHold or + ammoprop_AltUse or + ammoprop_Utility; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amInvulnerable; + AttackVoice: sndNone); Slot: 8; TimeAfterTurn: 0; minAngle: 0; @@ -1453,13 +1477,17 @@ NameTex: nil; Probability: 30; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_AltUse or ammoprop_Utility; - Count: 1; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amExtraTime; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_NoCrosshair or + ammoprop_DontHold or + ammoprop_AltUse or + ammoprop_Utility; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amExtraTime; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -1472,13 +1500,17 @@ NameTex: nil; Probability: 15; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_AltUse or ammoprop_Utility; - Count: 1; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amLaserSight; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_NoCrosshair or + ammoprop_DontHold or + ammoprop_AltUse or + ammoprop_Utility; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amLaserSight; + AttackVoice: sndNone); Slot: 7; TimeAfterTurn: 0; minAngle: 0; @@ -1491,13 +1523,17 @@ NameTex: nil; Probability: 15; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_AltUse or ammoprop_Utility; - Count: 1; - NumPerTurn: 0; - Timer: 0; - Pos: 0; - AmmoType: amVampiric; - AttackVoice: sndNone); + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_NoCrosshair or + ammoprop_DontHold or + ammoprop_AltUse or + ammoprop_Utility; + Count: 1; + NumPerTurn: 0; + Timer: 0; + Pos: 0; + AmmoType: amVampiric; + AttackVoice: sndNone); Slot: 6; TimeAfterTurn: 0; minAngle: 0; @@ -1529,7 +1565,8 @@ NameTex: nil; Probability: 20; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or + Ammo: (Propz: ammoprop_NoRoundEndHint or + ammoprop_ForwMsgs or ammoprop_AttackInMove or ammoprop_NoCrosshair or ammoprop_DontHold or @@ -1548,7 +1585,6 @@ SkipTurns: 0; PosCount: 1; PosSprite: sprWater), - (NameId: sidMolotov; NameTex: nil; Probability: 0; @@ -1623,7 +1659,8 @@ 'Graphics/AmmoMenu', // ptAmmoMenu 'Graphics/Hedgehog', // ptHedgehog 'Sounds/voices', // ptVoices - 'Graphics/Hats' // ptHats + 'Graphics/Hats', // ptHats + 'Graphics/Flags' // ptFlags ); begin PathPrefix := './'; diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uLand.pas --- a/hedgewars/uLand.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uLand.pas Thu Feb 04 20:45:03 2010 +0000 @@ -730,6 +730,7 @@ s:= Pathz[ptMapCurrent] + '/map.cfg'; WriteLnToConsole('Fetching map HH limit'); Assign(f, s); +filemode:= 0; // readonly Reset(f); Readln(f); if not eof(f) then Readln(f, MaxHedgehogs); diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uLandObjects.pas --- a/hedgewars/uLandObjects.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uLandObjects.pas Thu Feb 04 20:45:03 2010 +0000 @@ -371,6 +371,7 @@ WriteLnToConsole('Reading objects info...'); Assign(f, s); {$I-} +filemode:= 0; // readonly Reset(f); // read sky and explosion border colors diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uLocale.pas --- a/hedgewars/uLocale.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uLocale.pas Thu Feb 04 20:45:03 2010 +0000 @@ -31,14 +31,17 @@ sidLaserSight, sidVampiric, sidSniperRifle, sidJetpack, sidMolotov); TMsgStrId = (sidStartFight, sidDraw, sidWinner, sidVolume, sidPaused, - sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync); + sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync, + sidNoEndTurn, sidNotYetAvailable); TEventId = (eidDied, eidDrowned, eidRoundStart, eidRoundWin, eidRoundDraw, eidNewHealthPack, eidNewAmmoPack, eidNewUtilityPack, eidTurnSkipped, eidHurtSelf, - eidHomerun); + eidHomerun, eidFrozen); const MAX_EVENT_STRINGS = 100; var trammo: array[TAmmoStrId] of string; + trammoc: array[TAmmoStrId] of string; + trammod: array[TAmmoStrId] of string; trmsg: array[TMsgStrId] of string; procedure LoadLocale(FileName: string); @@ -65,9 +68,9 @@ for e:= Low(TEventId) to High(TEventId) do first[e]:= true; {$I-} // iochecks off +Assign(f, FileName); filemode:= 0; // readonly -Assign(f, FileName); -reset(f); +Reset(f); if IOResult = 0 then loaded:= true; TryDo(loaded, 'Cannot load locale "' + FileName + '"', false); if loaded then @@ -98,6 +101,8 @@ trevt[TEventId(b)][trevt_n[TEventId(b)]]:= s; inc(trevt_n[TEventId(b)]); end; + 3: if (b >=0) and (b <= ord(High(TAmmoStrId))) then trammoc[TAmmoStrId(b+1)]:= s; + 4: if (b >=0) and (b <= ord(High(TAmmoStrId))) then trammod[TAmmoStrId(b+1)]:= s; end; end; Close(f) diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uMisc.pas Thu Feb 04 20:45:03 2010 +0000 @@ -108,6 +108,8 @@ cLaserSighting : boolean; cVampiric : boolean; cArtillery : boolean; + WeaponTooltipTex : PTexture; + cWeaponTooltips: boolean; flagMakeCapture : boolean; @@ -125,6 +127,8 @@ procedure init_uMisc; procedure free_uMisc; +procedure SplitBySpace(var a, b: shortstring); +procedure SplitByChar(var a, b: string; c: char); procedure movecursor(dx, dy: Integer); function hwSign(r: hwFloat): LongInt; function Min(a, b: LongInt): LongInt; @@ -166,6 +170,31 @@ f: textfile; {$ENDIF} +// should this include "strtolower()" for the split string? +procedure SplitBySpace(var a, b: shortstring); +var i, t: LongInt; +begin +i:= Pos(' ', a); +if i > 0 then + begin + for t:= 1 to Pred(i) do + if (a[t] >= 'A')and(a[t] <= 'Z') then Inc(a[t], 32); + b:= copy(a, i + 1, Length(a) - i); + byte(a[0]):= Pred(i) + end else b:= ''; +end; + +procedure SplitByChar(var a, b: string; c: char); +var i: LongInt; +begin +i:= Pos(c, a); +if i > 0 then + begin + b:= copy(a, i + 1, Length(a) - i); + byte(a[0]):= Pred(i) + end else b:= ''; +end; + procedure movecursor(dx, dy: Integer); var x, y: LongInt; begin diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uStore.pas --- a/hedgewars/uStore.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uStore.pas Thu Feb 04 20:45:03 2010 +0000 @@ -77,7 +77,9 @@ function LoadImage(const filename: string; imageFlags: LongInt): PSDL_Surface; procedure SetupOpenGL; procedure SetScale(f: GLfloat); - +procedure RenderWeaponTooltip(atype: TAmmoType); +procedure ShowWeaponTooltip(x, y: LongInt); +procedure FreeWeaponTooltip; implementation uses uMisc, uConsole, uLand, uLocale, uWorld{$IFDEF IPHONEOS}, PascalExports{$ENDIF}; @@ -145,6 +147,32 @@ WriteInRoundRect:= finalRect; end; +function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: string): TSDL_Rect; +var w, h: LongInt; + tmpsurf: PSDL_Surface; + clr: TSDL_Color; + finalRect: TSDL_Rect; +begin +TTF_SizeUTF8(Fontz[Font].Handle, Str2PChar(s), w, h); +finalRect.x:= X + FontBorder + 2; +finalRect.y:= Y + FontBorder; +finalRect.w:= w + FontBorder * 2 + 4; +finalRect.h:= h + FontBorder * 2; +clr.r:= Color shr 16; +clr.g:= (Color shr 8) and $FF; +clr.b:= Color and $FF; +tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(s), clr); +tmpsurf:= doSurfaceConversion(tmpsurf); +SDLTry(tmpsurf <> nil, true); +SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect); +SDL_FreeSurface(tmpsurf); +finalRect.x:= X; +finalRect.y:= Y; +finalRect.w:= w + FontBorder * 2 + 4; +finalRect.h:= h + FontBorder * 2; +WriteInRect:= finalRect +end; + procedure StoreLoad; var s: string; @@ -153,7 +181,7 @@ i: LongInt; r, rr: TSDL_Rect; drY: LongInt; - texsurf: PSDL_Surface; + texsurf, flagsurf: PSDL_Surface; begin r.x:= 0; r.y:= 0; @@ -177,6 +205,34 @@ HealthTex:= Surface2Tex(texsurf, false); SDL_FreeSurface(texsurf); + r.x:= 0; + r.y:= 0; + r.w:= 32; + r.h:= 32; + texsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 32, RMask, GMask, BMask, AMask); + TryDo(texsurf <> nil, errmsgCreateSurface, true); + TryDo(SDL_SetColorKey(texsurf, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); + + r.w:= 26; + r.h:= 19; + + DrawRoundRect(@r, cWhiteColor, cNearBlackColor, texsurf, true); + + flagsurf:= LoadImage(Pathz[ptFlags] + '/' + Flag, ifNone); + if flagsurf = nil then + flagsurf:= LoadImage(Pathz[ptFlags] + '/hedgewars', ifNone); + TryDo(flagsurf <> nil, 'Failed to load flag "' + Flag + '" as well as the default flag', true); + copyToXY(flagsurf, texsurf, 2, 2); + SDL_FreeSurface(flagsurf); + + // restore black border pixels inside the flag + PLongwordArray(texsurf^.pixels)^[32 * 2 + 2]:= cNearBlackColor; + PLongwordArray(texsurf^.pixels)^[32 * 2 + 23]:= cNearBlackColor; + PLongwordArray(texsurf^.pixels)^[32 * 16 + 2]:= cNearBlackColor; + PLongwordArray(texsurf^.pixels)^[32 * 16 + 23]:= cNearBlackColor; + + FlagTex:= Surface2Tex(texsurf, false); + dec(drY, r.h + 2); DrawHealthY:= drY; for i:= 0 to 7 do @@ -1316,6 +1372,183 @@ end; end; +function RenderHelpWindow(caption, subcaption, description, extra: shortstring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture; +var tmpsurf: PSDL_SURFACE; + w, h, i, j: LongInt; + font: THWFont; + r, r2: TSDL_Rect; + wa, ha: LongInt; + tmpline, tmpline2, tmpdesc: shortstring; +begin +font:= fnt16; + +// make sure there is a caption as well as a sub caption - description is optional +if caption = '' then caption:= '???'; +if subcaption = '' then subcaption:= ' '; + +w:= 0; +h:= 0; +wa:= FontBorder * 2 + 4; +ha:= FontBorder * 2; + +// TODO: Recheck height/position calculation + +// get caption's dimensions +TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(caption), i, j); +// width adds 36 px (image + space) +w:= i + 36 + wa; +h:= j + ha; + +// get sub caption's dimensions +TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(subcaption), i, j); +// width adds 36 px (image + space) +if w < (i + 36 + wa) then w:= i + 36 + wa; +inc(h, j + ha); + +// get description's dimensions +tmpdesc:= description; +while tmpdesc <> '' do + begin + tmpline:= tmpdesc; + SplitByChar(tmpline, tmpdesc, '|'); + if tmpline <> '' then + begin + TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(tmpline), i, j); + if w < (i + wa) then w:= i + wa; + inc(h, j + ha) + end + end; + +if extra <> '' then + begin + // get extra label's dimensions + TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(extra), i, j); + if w < (i + wa) then w:= i + wa; + inc(h, j + ha); + end; + +// add borders space +inc(w, wa); +inc(h, ha + 8); + +tmpsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask); +TryDo(tmpsurf <> nil, 'RenderHelpWindow: fail to create surface', true); + +// render border and background +r.x:= 0; +r.y:= 0; +r.w:= w; +r.h:= h; +DrawRoundRect(@r, cWhiteColor, cNearBlackColor, tmpsurf, true); + +// render caption +r:= WriteInRect(tmpsurf, 36 + FontBorder + 2, ha, $ffffffff, font, caption); +// render sub caption +r:= WriteInRect(tmpsurf, 36 + FontBorder + 2, r.y + r.h, $ffc7c7c7, font, subcaption); + +// render all description lines +tmpdesc:= description; +while tmpdesc <> '' do + begin + tmpline:= tmpdesc; + SplitByChar(tmpline, tmpdesc, '|'); + r2:= r; + if tmpline <> '' then + begin + r:= WriteInRect(tmpsurf, FontBorder + 2, r.y + r.h, $ff707070, font, tmpline); + + // render highlighted caption (if there's a ':') + SplitByChar(tmpline, tmpline2, ':'); + if tmpline2 <> '' then + WriteInRect(tmpsurf, FontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, tmpline + ':'); + end + end; + +if extra <> '' then + r:= WriteInRect(tmpsurf, FontBorder + 2, r.y + r.h, extracolor, font, extra); + +r.x:= FontBorder + 6; +r.y:= FontBorder + 4; +r.w:= 32; +r.h:= 32; +SDL_FillRect(tmpsurf, @r, $ffffffff); +SDL_UpperBlit(iconsurf, iconrect, tmpsurf, @r); + +RenderHelpWindow:= Surface2Tex(tmpsurf, true); +SDL_FreeSurface(tmpsurf) +end; + +procedure RenderWeaponTooltip(atype: TAmmoType); +var r: TSDL_Rect; + i: LongInt; + extra: string; + extracolor: LongInt; +begin +{$IFNDEF IPHONEOS} +// don't do anything if the window shouldn't be shown +if not cWeaponTooltips then + begin +{$ENDIF} + WeaponTooltipTex:= nil; +{$IFNDEF IPHONEOS} + exit + end; + +// free old texture +FreeWeaponTooltip; + +// image region +i:= LongInt(atype) - 1; +r.x:= (i shr 5) * 32; +r.y:= (i mod 32) * 32; +r.w:= 32; +r.h:= 32; + +// default (no extra text) +extra:= ''; +extracolor:= 0; + +if (CurrentTeam <> nil) and (Ammoz[atype].SkipTurns >= CurrentTeam^.Clan^.TurnNumber) then // weapon or utility is not yet available + begin + extra:= trmsg[sidNotYetAvailable]; + extracolor:= LongInt($ffc77070); + end +else if (Ammoz[atype].Ammo.Propz and ammoprop_NoRoundEndHint) <> 0 then // weapon or utility won't end your turn + begin + extra:= trmsg[sidNoEndTurn]; + extracolor:= LongInt($ff70c770); + end +else + begin + extra:= ''; + extracolor:= 0; + end; + +// render window and return the texture +WeaponTooltipTex:= RenderHelpWindow(trammo[Ammoz[atype].NameId], trammoc[Ammoz[atype].NameId], trammod[Ammoz[atype].NameId], extra, extracolor, SpritesData[sprAMAmmos].Surface, @r) +{$ENDIF} +end; + +procedure ShowWeaponTooltip(x, y: LongInt); +begin +{$IFNDEF IPHONEOS} +// draw the texture if it exists +if WeaponTooltipTex <> nil then + DrawTexture(x, y, WeaponTooltipTex) +{$ENDIF} +end; + +procedure FreeWeaponTooltip; +begin +{$IFNDEF IPHONEOS} +// free the existing texture (if there's any) +if WeaponTooltipTex = nil then + exit; +FreeTexture(WeaponTooltipTex); +WeaponTooltipTex:= nil +{$ENDIF} +end; + procedure init_uStore; begin PixelFormat:= nil; diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uTeams.pas Thu Feb 04 20:45:03 2010 +0000 @@ -65,7 +65,9 @@ NameTagTex: PTexture; CrosshairTex, GraveTex, - HealthTex: PTexture; + HealthTex, + FlagTex: PTexture; + Flag: string; GraveName: string; FortName: string; TeamHealth: LongInt; @@ -259,6 +261,7 @@ FillChar(team^, sizeof(TTeam), 0); team^.AttackBar:= 2; team^.CurrHedgehog:= cMaxHHIndex; +team^.Flag:= 'hedgewars'; TeamsArray[TeamsCount]:= team; inc(TeamsCount); diff -r 55593f8a490b -r 7889a3a9724f hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Thu Feb 04 18:46:49 2010 +0000 +++ b/hedgewars/uWorld.pas Thu Feb 04 20:45:03 2010 +0000 @@ -65,6 +65,7 @@ CountTicks: Longword; SoundTimerTicks: Longword; prevPoint: TPoint; + amSel: TAmmoType = amNothing; procedure InitWorld; var i, t: LongInt; @@ -183,21 +184,33 @@ DrawSprite(sprAMBorders, x, y, 0); if (Pos >= 0) then + begin if (Ammo^[Slot, Pos].Count > 0) and (Ammo^[Slot, Pos].AmmoType <> amNothing) then - begin - DrawTexture(cScreenWidth div 2 - 200 + AMxShift, cScreenHeight - 68, Ammoz[Ammo^[Slot, Pos].AmmoType].NameTex); + if (amSel <> Ammo^[Slot, Pos].AmmoType) or (WeaponTooltipTex = nil) then + begin + amSel:= Ammo^[Slot, Pos].AmmoType; + RenderWeaponTooltip(amSel) + end; + + DrawTexture(cScreenWidth div 2 - 200 + AMxShift, cScreenHeight - 68, Ammoz[Ammo^[Slot, Pos].AmmoType].NameTex); - if Ammo^[Slot, Pos].Count < AMMO_INFINITE then - DrawTexture(cScreenWidth div 2 + AMxShift - 35, cScreenHeight - 68, CountTexz[Ammo^[Slot, Pos].Count]); + if Ammo^[Slot, Pos].Count < AMMO_INFINITE then + DrawTexture(cScreenWidth div 2 + AMxShift - 35, cScreenHeight - 68, CountTexz[Ammo^[Slot, Pos].Count]); - if bSelected and (Ammoz[Ammo^[Slot, Pos].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber < 0) then - begin - bShowAmmoMenu:= false; - SetWeapon(Ammo^[Slot, Pos].AmmoType); - bSelected:= false; - exit - end; - end; + if bSelected and (Ammoz[Ammo^[Slot, Pos].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber < 0) then + begin + bShowAmmoMenu:= false; + SetWeapon(Ammo^[Slot, Pos].AmmoType); + bSelected:= false; + FreeWeaponTooltip; + exit + end; + end + else + FreeWeaponTooltip; + + if (WeaponTooltipTex <> nil) and (AMxShift = 0) then + ShowWeaponTooltip(x - WeaponTooltipTex^.w - 3, y); end; bSelected:= false; @@ -341,6 +354,7 @@ tdx, tdy: Double; grp: TCapGroup; s: string[15]; + highlight: Boolean; offset: LongInt; scale: GLfloat; begin @@ -518,22 +532,40 @@ end; // Teams Healths + for t:= 0 to Pred(TeamsCount) do with TeamsArray[t]^ do begin - DrawTexture(- NameTagTex^.w - 3, cScreenHeight + DrawHealthY, NameTagTex); - + highlight:= bShowFinger and (CurrentTeam = TeamsArray[t]) and ((RealTicks mod 1000) < 500); + + if highlight then + glColor4f(((Clan^.Color shr 16) and $ff) / $ff, ((Clan^.Color shr 8) and $ff) / $ff, (Clan^.Color and $ff) / $ff, 1); + DrawTexture(- NameTagTex^.w - 16, cScreenHeight + DrawHealthY, NameTagTex); + r.x:= 0; r.y:= 0; + + r.w:= 26; + r.h:= 19; + DrawFromRect(-14, cScreenHeight + DrawHealthY, @r, FlagTex); + r.w:= 2 + TeamHealthBarWidth; r.h:= HealthTex^.h; - - DrawFromRect(0, cScreenHeight + DrawHealthY, @r, HealthTex); + DrawFromRect(14, cScreenHeight + DrawHealthY, @r, HealthTex); inc(r.x, cTeamHealthWidth + 2); r.w:= 3; - DrawFromRect(TeamHealthBarWidth + 2, cScreenHeight + DrawHealthY, @r, HealthTex); + DrawFromRect(TeamHealthBarWidth + 16, cScreenHeight + DrawHealthY, @r, HealthTex); + if highlight then // if highlighted, draw flag again to keep its colors + begin + r.x:= 2; + r.y:= 2; + r.w:= 22; + r.h:= 15; + glColor4f(1, 1, 1, 1); + DrawFromRect(-12, cScreenHeight + DrawHealthY + 2, @r, FlagTex); + end; end; // Lag alert diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/CMakeLists.txt --- a/share/hedgewars/Data/Graphics/CMakeLists.txt Thu Feb 04 18:46:49 2010 +0000 +++ b/share/hedgewars/Data/Graphics/CMakeLists.txt Thu Feb 04 20:45:03 2010 +0000 @@ -1,4 +1,5 @@ add_subdirectory(AmmoMenu) +add_subdirectory(Flags) add_subdirectory(Graves) add_subdirectory(Hats) add_subdirectory(Hedgehog) diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/Flags/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Graphics/Flags/CMakeLists.txt Thu Feb 04 20:45:03 2010 +0000 @@ -0,0 +1,5 @@ +file(GLOB FlagTemplates *.png) + +install(FILES + ${FlagTemplates} + DESTINATION ${SHAREPATH}Data/Graphics/Flags) diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/Flags/france.png Binary file share/hedgewars/Data/Graphics/Flags/france.png has changed diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/Flags/germany.png Binary file share/hedgewars/Data/Graphics/Flags/germany.png has changed diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/Flags/hedgewars.png Binary file share/hedgewars/Data/Graphics/Flags/hedgewars.png has changed diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/Flags/italy.png Binary file share/hedgewars/Data/Graphics/Flags/italy.png has changed diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/Flags/united_kingdom.png Binary file share/hedgewars/Data/Graphics/Flags/united_kingdom.png has changed diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Graphics/Flags/united_states.png Binary file share/hedgewars/Data/Graphics/Flags/united_states.png has changed diff -r 55593f8a490b -r 7889a3a9724f share/hedgewars/Data/Locale/en.txt --- a/share/hedgewars/Data/Locale/en.txt Thu Feb 04 18:46:49 2010 +0000 +++ b/share/hedgewars/Data/Locale/en.txt Thu Feb 04 20:45:03 2010 +0000 @@ -52,6 +52,10 @@ 01:07=%1 remaining 01:08=Fuel 01:09=Synchronizing... +01:10=Using this utility won't end your turn! +01:11=This weapon or utility is not yet available! +01:10=Using this utility won't end your turn! +01:11=This weapon or utility is not yet available! ; Event messages ; Hog (%1) died @@ -348,3 +352,179 @@ 02:10=Home Run! 02:10=A bird, a plane, ... 02:10=That one is out! +; Hog (%1) is frozen and misses his turn +02:11=%1 is cool as ice! + +; Weapon Categories +03:00=Timed Grenade +03:01=Timed Grenade +03:02=Ballistic Weapon +03:03=Guided Weapon +03:04=Gun (multiple shots) +03:05=Digging Tool +03:06=Action +03:07=Transport Utility +03:08=Proximity Bomb +03:09=Gun (multiple shots) +03:10=BOOM! +03:11=Bonk! +03:12=Martial Arts +03:13=UNUSED +03:14=Transport Utility +03:15=Airborne Attack +03:16=Airborne Attack +03:17=Digging Utility +03:18=Utility +03:19=Transport Utility +03:20=Action +03:21=Ballistic Weapon +03:22=Call me Indiana! +03:23=(Really) Martial Arts +03:24=The cake is NOT a lie! +03:25=Costume Kit +03:26=Juicy Grenade +03:27=Fiery Grenade +03:28=Ballistic Weapon +03:29=Ballistic Weapon +03:30=Airborne Attack +03:31=Remote Controlled Bomb +03:32=Temporary Effect +03:33=Temporary Effect +03:34=Temporary Effect +03:35=Temporary Effect +03:36=Temporary Effect +03:37=Temporary Effect +03:38=Gun (one shot) +03:39=Transport Utility +03:40=Incinerating Grenade + +; Weapon Descriptions (use | as line breaks) +04:00=Attack your enemies using a simple grenade.|It will explode once its timer reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power +04:01=Attack your enemies using a cluster bomb.|It will split into smaller bombs once its timer|reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power +04:02=Attack your enemies using a ballistic projectile|that might be influenced by wind.|Attack: Hold to shoot with more power +04:03=Launch a guided bomb that while home into|the selected target. Don't shoot with full power|to improve its precision.|Cursor: Pick target|Attack: Hold to shoot with more power +04:04=Attack your enemy using a shotgun with two shots.|Thanks to its spread you don't need direct hits|to harm your opponents.|Attack: Shoot (multiple times) +04:05=Move underground! Use the pickhammer to drill|a hole into the ground and reach other areas.|Attack: Start or stop digging +04:06=Bored? No way to attack? Save your ammo?|No problem! Just skip your turn, coward!|Attack: Skip your turn without fighting +04:07=Bridge huge distances using timed shots with the|rope. Use your momentum to slide into other hogs|or drop grenades and other weapons on them.|Attack: Shoot or release the rope|Long Jump: Drop grenades or similar weapons +04:08=Keep your enemies away by dropping a mine in|narrow passages or right below their feet. Be|sure to retreat before you trigger it yourself!|Attack: Drop mine next to your feet +04:09=Not sure about your aiming? Use the Desert|Eagle to attack using up to five shots.|Attack: Shoot (multiple times) +04:10=Brute force is always an option. Drop this classic|explosive next to your enemies and retreat.|Attack: Drop dynamite next to your feet +04:11=Get rid of enemy hogs by batting them over|the map borders or into water. Or how about|knocking some mines to your friends?|Attack: Bat everything in front of you +04:12=Get close and personal to unleash the power of|this almost deadly martial arts technique.|Attack: Perform the Fire Punch +04:13=UNUSED +04:14=Fear of heights? Better grab a parachute.|It will unfold once|you fall too far and|save your hog from taking fall damage.|Attack: Unfold the parachute +04:15=Call in an airplane to attack your enemies|using a bombing run.|Left/Right: Determine attack direction|Cursor: Select target region +04:16=Call in an airplane to drop several mines|in the target area.|Left/Right: Determine attack direction|Cursor: Select target region +04:17=Need shelter? Use the blow torch to dig|a tunnel into solid ground granting you|cover.|Attack: Start or stop digging +04:18=Need additional protection or want to pass|unpassable ground? Place some girders as you|like.|Left/Right: Select girder to place|Cursor: Place girder in a valid position +04:19=Used at the right moment teleportation can|be more powerful than almost all weapons as|it allows you to save hogs from dangerous|situations within seconds.|Cursor: Select target region +04:20=Allows you to play the current turn with|a different hog.|Attack: Enable switching hogs +04:21=Shoot a grenade-like projectile that will|release multiple bombs upon impact.|Attack: Shoot at full power +04:22=Not just for Indiana Jones! The whip is an|useful weapon in many situations. Especially|when you'd like to shove someone off a cliff.|Attack: Strike everything in front of you +04:23=If you have nothing to lose, this might be|quite handy. Sacrifice your hog by launching|it into a specific direction hurting everything|on his way and exploding at the end.|Attack: Launch the devastating and deadly attack +04:24=Happy Birthday! Launch this cake, let it walk right|next to your enemies and let them have an explosive|party. The cake is able to pass almost all terrain|but he might detonate earlier this way.|Attack: Start the cake or let it stop and explode +04:25=Use this disguise kit to get your enemies to jump|towards your hog (and into some gap or hole).|Attack: Use the kit and try to seduce another hog +04:26=Throw this juicy water melon at your enemies. Once|the timer expires, it will split into several|explosive pieces.|Attack: Hold to shoot with more power +04:27=Let hellfire rain onto your opponents by using|this fiendish explosive. Don't get too close to|the explosion as smaller fires might last longer.|Attack: Hold to shoot with more power +04:28=Short time after launching this rocket, it will|start drilling through solid ground and explode|once its fuse is triggered or it resurfaces again.|Attack: Hold to shoot with more power +04:29=This is nothing for small kids! The ball gun fires|tons of small colored balls filled with explosives.|Attack: Shoot at full power|Up/Down: Continue aiming +04:30=Call in an airplane to launch a powerful napalm|strike. With proper aiming this attack can eradicate|huge parts of landscape including unlucky hogs|sitting there.|Left/Right: Determine attack direction|Cursor: Select target region +04:31=The RC plane is the ideal weapon to collect crates or|attack far away hogs. Either steer it into enemies or|drop some bombs first.|Attack: Launch the plane or drop bombs|Long Jump: Let the valkyries ride into battle|Up/Down: Steer the plane +04:32=Low gravity is more effective than any diet! Jump|higher and over greater distances or let your enemies|fly even further.|Attack: Activate +04:33=Sometimes you just need that little extra boost to|deal some more damage.|Attack: Activate +04:34=Can't touch me!|Attack: Activate +04:35=Sometimes time's running too fast. Grab some extra|seconds to finish your attack.|Attack: Activate +04:36=Well, sometimes you're just too bad in aiming. Get|some assistance using modern day technology.|Attack: Activate +04:37=Don't fear the daylight. It will just last one turn|but will enable you to absorb the damage you do to|other hogs.|Attack: Activate +04:38=The sniper rifle can be the most devastating weapon|in your whole arsenal, however it's very ineffective|at close quarters. The damage dealt increases with|the distance to its target.|Attack: Shoot (once) +04:39=Fly to other parts of the map using the flying|saucer. This hard to master utility is able to|bring you to almost any position on the battlefield.|Attack: Activate|Up/Left/Right: Apply force into one direction +04:40=Set some ground on fire using this bottle filled|with (soon to be) burning liquid.|Attack: Hold to shoot with more power +; Hog (%1) is frozen and misses his turn +02:11=%1 is cool as ice! + +; Weapon Categories +03:00=Timed Grenade +03:01=Timed Grenade +03:02=Ballistic Weapon +03:03=Guided Weapon +03:04=Gun (multiple shots) +03:05=Digging Tool +03:06=Action +03:07=Transport Utility +03:08=Proximity Bomb +03:09=Gun (multiple shots) +03:10=BOOM! +03:11=Bonk! +03:12=Martial Arts +03:13=UNUSED +03:14=Transport Utility +03:15=Airborne Attack +03:16=Airborne Attack +03:17=Digging Utility +03:18=Utility +03:19=Transport Utility +03:20=Action +03:21=Ballistic Weapon +03:22=Call me Indiana! +03:23=(Really) Martial Arts +03:24=The cake is NOT a lie! +03:25=Costume Kit +03:26=Juicy Grenade +03:27=Fiery Grenade +03:28=Ballistic Weapon +03:29=Ballistic Weapon +03:30=Airborne Attack +03:31=Remote Controlled Bomb +03:32=Temporary Effect +03:33=Temporary Effect +03:34=Temporary Effect +03:35=Temporary Effect +03:36=Temporary Effect +03:37=Temporary Effect +03:38=Gun (one shot) +03:39=Transport Utility +03:40=Incinerating Grenade + +; Weapon Descriptions (use | as line breaks) +04:00=Attack your enemies using a simple grenade.|It will explode once its timer reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power +04:01=Attack your enemies using a cluster bomb.|It will split into smaller bombs once its timer|reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power +04:02=Attack your enemies using a ballistic projectile|that might be influenced by wind.|Attack: Hold to shoot with more power +04:03=Launch a guided bomb that while home into|the selected target. Don't shoot with full power|to improve its precision.|Cursor: Pick target|Attack: Hold to shoot with more power +04:04=Attack your enemy using a shotgun with two shots.|Thanks to its spread you don't need direct hits|to harm your opponents.|Attack: Shoot (multiple times) +04:05=Move underground! Use the pickhammer to drill|a hole into the ground and reach other areas.|Attack: Start or stop digging +04:06=Bored? No way to attack? Save your ammo?|No problem! Just skip your turn, coward!|Attack: Skip your turn without fighting +04:07=Bridge huge distances using timed shots with the|rope. Use your momentum to slide into other hogs|or drop grenades and other weapons on them.|Attack: Shoot or release the rope|Long Jump: Drop grenades or similar weapons +04:08=Keep your enemies away by dropping a mine in|narrow passages or right below their feet. Be|sure to retreat before you trigger it yourself!|Attack: Drop mine next to your feet +04:09=Not sure about your aiming? Use the Desert|Eagle to attack using up to five shots.|Attack: Shoot (multiple times) +04:10=Brute force is always an option. Drop this classic|explosive next to your enemies and retreat.|Attack: Drop dynamite next to your feet +04:11=Get rid of enemy hogs by batting them over|the map borders or into water. Or how about|knocking some mines to your friends?|Attack: Bat everything in front of you +04:12=Get close and personal to unleash the power of|this almost deadly martial arts technique.|Attack: Perform the Fire Punch +04:13=UNUSED +04:14=Fear of heights? Better grab a parachute.|It will unfold once|you fall too far and|save your hog from taking fall damage.|Attack: Unfold the parachute +04:15=Call in an airplane to attack your enemies|using a bombing run.|Left/Right: Determine attack direction|Cursor: Select target region +04:16=Call in an airplane to drop several mines|in the target area.|Left/Right: Determine attack direction|Cursor: Select target region +04:17=Need shelter? Use the blow torch to dig|a tunnel into solid ground granting you|cover.|Attack: Start or stop digging +04:18=Need additional protection or want to pass|unpassable ground? Place some girders as you|like.|Left/Right: Select girder to place|Cursor: Place girder in a valid position +04:19=Used at the right moment teleportation can|be more powerful than almost all weapons as|it allows you to save hogs from dangerous|situations within seconds.|Cursor: Select target region +04:20=Allows you to play the current turn with|a different hog.|Attack: Enable switching hogs +04:21=Shoot a grenade-like projectile that will|release multiple bombs upon impact.|Attack: Shoot at full power +04:22=Not just for Indiana Jones! The whip is an|useful weapon in many situations. Especially|when you'd like to shove someone off a cliff.|Attack: Strike everything in front of you +04:23=If you have nothing to lose, this might be|quite handy. Sacrifice your hog by launching|it into a specific direction hurting everything|on his way and exploding at the end.|Attack: Launch the devastating and deadly attack +04:24=Happy Birthday! Launch this cake, let it walk right|next to your enemies and let them have an explosive|party. The cake is able to pass almost all terrain|but he might detonate earlier this way.|Attack: Start the cake or let it stop and explode +04:25=Use this disguise kit to get your enemies to jump|towards your hog (and into some gap or hole).|Attack: Use the kit and try to seduce another hog +04:26=Throw this juicy water melon at your enemies. Once|the timer expires, it will split into several|explosive pieces.|Attack: Hold to shoot with more power +04:27=Let hellfire rain onto your opponents by using|this fiendish explosive. Don't get too close to|the explosion as smaller fires might last longer.|Attack: Hold to shoot with more power +04:28=Short time after launching this rocket, it will|start drilling through solid ground and explode|once its fuse is triggered or it resurfaces again.|Attack: Hold to shoot with more power +04:29=This is nothing for small kids! The ball gun fires|tons of small colored balls filled with explosives.|Attack: Shoot at full power|Up/Down: Continue aiming +04:30=Call in an airplane to launch a powerful napalm|strike. With proper aiming this attack can eradicate|huge parts of landscape including unlucky hogs|sitting there.|Left/Right: Determine attack direction|Cursor: Select target region +04:31=The RC plane is the ideal weapon to collect crates or|attack far away hogs. Either steer it into enemies or|drop some bombs first.|Attack: Launch the plane or drop bombs|Long Jump: Let the valkyries ride into battle|Up/Down: Steer the plane +04:32=Low gravity is more effective than any diet! Jump|higher and over greater distances or let your enemies|fly even further.|Attack: Activate +04:33=Sometimes you just need that little extra boost to|deal some more damage.|Attack: Activate +04:34=Can't touch me!|Attack: Activate +04:35=Sometimes time's running too fast. Grab some extra|seconds to finish your attack.|Attack: Activate +04:36=Well, sometimes you're just too bad in aiming. Get|some assistance using modern day technology.|Attack: Activate +04:37=Don't fear the daylight. It will just last one turn|but will enable you to absorb the damage you do to|other hogs.|Attack: Activate +04:38=The sniper rifle can be the most devastating weapon|in your whole arsenal, however it's very ineffective|at close quarters. The damage dealt increases with|the distance to its target.|Attack: Shoot (once) +04:39=Fly to other parts of the map using the flying|saucer. This hard to master utility is able to|bring you to almost any position on the battlefield.|Attack: Activate|Up/Left/Right: Apply force into one direction +04:40=Set some ground on fire using this bottle filled|with (soon to be) burning liquid.|Attack: Hold to shoot with more power