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
--- 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());
--- 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();
--- 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__
--- 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;
--- 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);
}
--- 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;
--- 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++)
--- 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;
--- 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]
--- 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
--- 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}) :
--- 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
]
--- 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;
--- 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);
--- 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;
--- 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 := './';
--- 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);
--- 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
--- 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)
--- 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
--- 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;
--- 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);
--- 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
--- 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)
--- /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)
Binary file share/hedgewars/Data/Graphics/Flags/france.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/germany.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/hedgewars.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/italy.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/united_kingdom.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/united_states.png has changed
--- 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