--- a/hedgewars/uWorld.pas Wed May 16 18:22:28 2018 +0200
+++ b/hedgewars/uWorld.pas Wed Jul 31 23:14:27 2019 +0200
@@ -31,8 +31,9 @@
procedure DrawWorld(Lag: LongInt);
procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);
+procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt; forceDisplay : boolean);
procedure HideMission;
-procedure SetAmmoTexts(ammoType: TAmmoType; name: ansistring; caption: ansistring; description: ansistring);
+procedure SetAmmoTexts(ammoType: TAmmoType; name: ansistring; caption: ansistring; description: ansistring; autoLabels: boolean);
procedure ShakeCamera(amount: LongInt);
procedure InitCameraBorders;
procedure InitTouchInterface;
@@ -41,6 +42,7 @@
procedure MoveCamera;
procedure onFocusStateChanged;
procedure updateCursorVisibility;
+procedure updateTouchWidgets(ammoType: TAmmoType);
implementation
uses
@@ -62,6 +64,7 @@
, uCommands
, uTeams
, uDebug
+ , uInputHandler
{$IFDEF USE_VIDEO_RECORDING}
, uVideoRec
{$ENDIF}
@@ -75,7 +78,7 @@
timeTexture: PTexture;
FPS: Longword;
CountTicks: Longword;
- prevPoint{, prevTargetPoint}: TPoint;
+ prevPoint: TPoint;
amSel: TAmmoType = amNothing;
missionTex: PTexture;
missionTimer: LongInt;
@@ -104,7 +107,6 @@
AMTypeMaskX = $00000001;
AMTypeMaskY = $00000002;
AMTypeMaskAlpha = $00000004;
- //AMTypeMaskSlide = $00000008;
{$IFDEF MOBILE}
AMSlotSize = 48;
@@ -113,6 +115,22 @@
{$ENDIF}
AMSlotPadding = (AMSlotSize - 32) shr 1;
+{$IFDEF USE_LANDSCAPE_AMMOMENU}
+ amNumOffsetX = 0;
+ {$IFDEF USE_AM_NUMCOLUMN}
+ amNumOffsetY = AMSlotSize;
+ {$ELSE}
+ amNumOffsetY = 0;
+ {$ENDIF}
+{$ELSE}
+ amNumOffsetY = 0;
+ {$IFDEF USE_AM_NUMCOLUMN}
+ amNumOffsetX = AMSlotSize;
+ {$ELSE}
+ amNumOffsetX = 0;
+ {$ENDIF}
+{$ENDIF}
+
cSendCursorPosTime = 50;
cCursorEdgesDist = 100;
@@ -120,22 +138,18 @@
function AddGoal(s: ansistring; gf: longword; si: TGoalStrId; i: LongInt): ansistring;
var t: ansistring;
begin
-{$IFNDEF PAS2C}
if (GameFlags and gf) <> 0 then
begin
t:= inttostr(i);
s:= s + FormatA(trgoal[si], t) + '|'
end;
-{$ENDIF}
AddGoal:= s;
end;
function AddGoal(s: ansistring; gf: longword; si: TGoalStrId): ansistring;
begin
-{$IFNDEF PAS2C}
if (GameFlags and gf) <> 0 then
s:= s + trgoal[si] + '|';
-{$ENDIF}
AddGoal:= s;
end;
@@ -158,15 +172,14 @@
ClansArray[t]:= cp;
ClansArray[t]^.ClanIndex:= t;
ClansArray[0]^.ClanIndex:= 0;
- if (LocalClan = t) then
- LocalClan:= 0
- else if (LocalClan = 0) then
- LocalClan:= t
end;
end;
CurrentTeam:= ClansArray[0]^.Teams[0];
end;
+if (GameFlags and gfInvulnerable) <> 0 then
+ cTagsMask:= cTagsMask and (not htHealth);
+
// if special game flags/settings are changed, add them to the game mode notice window and then show it
g:= ''; // no text/things to note yet
@@ -175,10 +188,10 @@
g:= LuaGoals + '|';
// check different game flags
-g:= AddGoal(g, gfPlaceHog, gidPlaceHog); // placement?
g:= AddGoal(g, gfKing, gidKing); // king?
if ((GameFlags and gfKing) <> 0) and ((GameFlags and gfPlaceHog) = 0) then
g:= AddGoal(g, gfAny, gidPlaceKing);
+g:= AddGoal(g, gfPlaceHog, gidPlaceHog); // placement?
g:= AddGoal(g, gfTagTeam, gidTagTeam); // tag team mode?
g:= AddGoal(g, gfSharedAmmo, gidSharedAmmo); // shared ammo?
g:= AddGoal(g, gfPerHogAmmo, gidPerHogAmmo);
@@ -216,19 +229,21 @@
// if the string has been set, show it for (default timeframe) seconds
if length(g) > 0 then
- ShowMission(trgoal[gidCaption], trgoal[gidSubCaption], g, 1, 0);
+ // choose icon
+ if ((GameFlags and gfKing) <> 0) then
+ // crown icon for King Mode
+ ShowMission(trgoal[gidCaption], trgoal[gidSubCaption], g, 0, 0)
+ else
+ // target icon for anything else
+ ShowMission(trgoal[gidCaption], trgoal[gidSubCaption], g, 1, 0);
-//cWaveWidth:= SpritesData[sprWater].Width;
-//cWaveHeight:= SpritesData[sprWater].Height;
cWaveHeight:= 32;
InitCameraBorders();
uCursor.init();
prevPoint.X:= 0;
prevPoint.Y:= cScreenHeight div 2;
-//prevTargetPoint.X:= 0;
-//prevTargetPoint.Y:= 0;
-WorldDx:= -(LongInt(leftX + (playWidth div 2))); // -(LAND_WIDTH div 2);// + cScreenWidth div 2;
+WorldDx:= -(LongInt(leftX + (playWidth div 2)));
WorldDy:= -(LAND_HEIGHT - (playHeight div 2)) + (cScreenHeight div 2);
//aligns it to the bottom of the screen, minus the border
@@ -398,6 +413,28 @@
source.y:= frame.y;
end;
end;
+
+with utilityWidget2 do
+ begin
+ show:= false;
+ sprite:= sprBounceButton;
+ frame.w:= Round(spritesData[sprite].Texture^.w * buttonScale);
+ frame.h:= Round(spritesData[sprite].Texture^.h * buttonScale);
+ frame.x:= utilityWidget.frame.x + Round(frame.w * 1.25);
+ frame.y:= arrowLeft.frame.y - Round(frame.h * 1.25);
+ active.x:= frame.x;
+ active.y:= frame.y;
+ active.w:= frame.w;
+ active.h:= frame.h;
+ with moveAnim do
+ begin
+ target.x:= frame.x;
+ target.y:= frame.y;
+ source.x:= frame.x;
+ source.y:= frame.y;
+ end;
+ end;
+
{$ENDIF}
end;
@@ -418,7 +455,10 @@
STurns: LongInt;
amSurface: PSDL_Surface;
AMRect: TSDL_Rect;
-{$IFDEF USE_AM_NUMCOLUMN}tmpsurf: PSDL_Surface;{$ENDIF}
+{$IFDEF USE_AM_NUMCOLUMN}
+ tmpsurf: PSDL_Surface;
+ usesDefaultSlotKeys: boolean;
+{$ENDIF}
begin
if cOnlyStats then exit(nil);
@@ -454,6 +494,9 @@
x:= AMRect.x;
y:= AMRect.y;
+{$IFDEF USE_AM_NUMCOLUMN}
+ usesDefaultSlotKeys:= CheckDefaultSlotKeys;
+{$ENDIF USE_AM_NUMCOLUMN}
for i:= 0 to cMaxSlotIndex do
if (i <> cHiddenSlotIndex) and (Ammo^[i, 0].Count > 0) then
begin
@@ -463,7 +506,13 @@
x:= AMRect.x;
{$ENDIF}
{$IFDEF USE_AM_NUMCOLUMN}
- tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar('F' + IntToStr(i+1)), cWhiteColorChannels);
+ // Ammo slot number column
+ if usesDefaultSlotKeys then
+ // F1, F2, F3, F4, ...
+ tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar('F'+IntToStr(i+1)), cWhiteColorChannels)
+ else
+ // 1, 2, 3, 4, ...
+ tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i+1)), cWhiteColorChannels);
copyToXY(tmpsurf, amSurface,
x + AMSlotPadding + (AMSlotSize shr 1) - (tmpsurf^.w shr 1),
y + AMSlotPadding + (AMSlotSize shr 1) - (tmpsurf^.h shr 1));
@@ -603,12 +652,16 @@
if AMState = AMShowingUp then // show ammo menu
begin
- if (cReducedQuality and rqSlowMenu) <> 0 then
+ // No "appear" animation in low quality or playing with very short turn time.
+ if ((cReducedQuality and rqSlowMenu) <> 0) or (cHedgehogTurnTime <= 10000) then
begin
AMShiftX:= 0;
AMShiftY:= 0;
+ CursorPoint.X:= AmmoRect.x + AmmoRect.w - 3;
+ CursorPoint.Y:= cScreenHeight - AmmoRect.y - amNumOffsetY - 1;
AMState:= AMShowing;
end
+ // "Appear" animation
else
if AMAnimState < 1 then
begin
@@ -621,19 +674,22 @@
begin
AMShiftX:= 0;
AMShiftY:= 0;
- CursorPoint.X:= AmmoRect.x + AmmoRect.w;
- CursorPoint.Y:= AmmoRect.y;
+ CursorPoint.X:= AmmoRect.x + AmmoRect.w - 3;
+ CursorPoint.Y:= cScreenHeight - AmmoRect.y - amNumOffsetY - 1;
AMState:= AMShowing;
end;
end;
if AMState = AMHiding then // hide ammo menu
begin
- if (cReducedQuality and rqSlowMenu) <> 0 then
+ // No "disappear" animation (see above)
+ if ((cReducedQuality and rqSlowMenu) <> 0) or (cHedgehogTurnTime <= 10000) then
begin
AMShiftX:= AMShiftTargetX;
AMShiftY:= AMShiftTargetY;
+ prevPoint:= CursorPoint;
AMState:= AMHidden;
end
+ // "Disappear" animation
else
if AMAnimState < 1 then
begin
@@ -647,7 +703,6 @@
AMShiftX:= AMShiftTargetX;
AMShiftY:= AMShiftTargetY;
prevPoint:= CursorPoint;
- //prevTargetPoint:= TargetCursorPoint;
AMState:= AMHidden;
end;
end;
@@ -736,7 +791,7 @@
Ammoz[Ammo^[Slot, Pos].AmmoType].NameTex);
if Ammo^[Slot, Pos].Count < AMMO_INFINITE then
DrawTexture(AmmoRect.x + AmmoRect.w - 20 - (CountTexz[Ammo^[Slot, Pos].Count]^.w),
- AmmoRect.y + AmmoRect.h - BORDERSIZE - (AMslotSize shr 1) - (CountTexz[Ammo^[Slot, Pos].Count]^.w shr 1),
+ AmmoRect.y + AmmoRect.h - BORDERSIZE - (AMslotSize shr 1) - (CountTexz[Ammo^[Slot, Pos].Count]^.h shr 1),
CountTexz[Ammo^[Slot, Pos].Count]);
if bSelected and (Ammoz[Ammo^[Slot, Pos].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber < 0) then
@@ -745,23 +800,7 @@
SetWeapon(Ammo^[Slot, Pos].AmmoType);
bSelected:= false;
FreeAndNilTexture(WeaponTooltipTex);
-{$IFDEF USE_TOUCH_INTERFACE}//show the aiming buttons + animation
- if (Ammo^[Slot, Pos].Propz and ammoprop_NeedUpDown) <> 0 then
- begin
- if (not arrowUp.show) then
- begin
- animateWidget(@arrowUp, true, true);
- animateWidget(@arrowDown, true, true);
- end;
- end
- else
- if arrowUp.show then
- begin
- animateWidget(@arrowUp, true, false);
- animateWidget(@arrowDown, true, false);
- end;
- SetUtilityWidgetState(Ammo^[Slot, Pos].AmmoType);
-{$ENDIF}
+ updateTouchWidgets(Ammo^[Slot, Pos].AmmoType);
exit
end;
end
@@ -883,10 +922,8 @@
procedure RenderWorldEdge;
var
- //VertexBuffer: array [0..3] of TVertex2f;
tmp, w: LongInt;
rect: TSDL_Rect;
- //c1, c2: LongWord; // couple of colours for edges
begin
if (WorldEdge <> weNone) and (WorldEdge <> weSea) then
begin
@@ -894,7 +931,7 @@
rect.y:= ViewTopY;
rect.h:= ViewHeight;
- tmp:= LongInt(leftX) + WorldDx;
+ tmp:= leftX + WorldDx;
w:= tmp - ViewLeftX;
if w > 0 then
@@ -906,7 +943,7 @@
DrawLineOnScreen(tmp - 1, ViewTopY, tmp - 1, ViewBottomY, 2, $54, $54, $FF, $FF);
end;
- tmp:= LongInt(rightX) + WorldDx;
+ tmp:= rightX + WorldDx;
w:= ViewRightX - tmp;
if w > 0 then
@@ -918,110 +955,6 @@
DrawLineOnScreen(tmp - 1, ViewTopY, tmp - 1, ViewBottomY, 2, $54, $54, $FF, $FF);
end;
- (*
- WARNING: the following render code is outdated and does not work with
- current Render.pas ! - don't just uncomment without fixing it first
-
- glDisable(GL_TEXTURE_2D);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- if (WorldEdge = weWrap) or (worldEdge = weBounce) then
- glColor4ub($00, $00, $00, $40)
- else
- begin
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]);
- end;
-
- glPushMatrix;
- glTranslatef(WorldDx, WorldDy, 0);
-
- VertexBuffer[0].X:= leftX-20;
- VertexBuffer[0].Y:= -3500;
- VertexBuffer[1].X:= leftX-20;
- VertexBuffer[1].Y:= cWaterLine+cVisibleWater;
- VertexBuffer[2].X:= leftX+30;
- VertexBuffer[2].Y:= cWaterLine+cVisibleWater;
- VertexBuffer[3].X:= leftX+30;
- VertexBuffer[3].Y:= -3500;
-
- glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
- glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
-
- VertexBuffer[0].X:= rightX+20;
- VertexBuffer[1].X:= rightX+20;
- VertexBuffer[2].X:= rightX-30;
- VertexBuffer[3].X:= rightX-30;
-
- glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
- glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
-
- glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldEnd[0]);
-
- VertexBuffer[0].X:= -5000;
- VertexBuffer[1].X:= -5000;
- VertexBuffer[2].X:= leftX-20;
- VertexBuffer[3].X:= leftX-20;
-
- glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
- glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
-
- VertexBuffer[0].X:= rightX+5000;
- VertexBuffer[1].X:= rightX+5000;
- VertexBuffer[2].X:= rightX+20;
- VertexBuffer[3].X:= rightX+20;
-
- glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
- glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
-
- glPopMatrix;
- glDisableClientState(GL_COLOR_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
- glEnable(GL_TEXTURE_2D);
-
- // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer
- if WorldEdge = weBounce then
- begin
- // could maybe alternate order of these on a bounce, or maybe drop the outer ones.
- if LeftImpactTimer mod 2 = 0 then
- begin
- c1:= $5454FFFF; c2:= $FFFFFFFF;
- end
- else begin
- c1:= $FFFFFFFF; c2:= $5454FFFF;
- end;
- DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 7.0, c1);
- DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, c2);
- DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 3.0, c1);
- DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 1.0, c2);
- if RightImpactTimer mod 2 = 0 then
- begin
- c1:= $5454FFFF; c2:= $FFFFFFFF;
- end
- else begin
- c1:= $FFFFFFFF; c2:= $5454FFFF;
- end;
- DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 7.0, c1);
- DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, c2);
- DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 3.0, c1);
- DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 1.0, c2)
- end
- else if WorldEdge = weWrap then
- begin
- DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-LeftImpactTimer));
- DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 2.0, $FF0000FF);
- DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-RightImpactTimer));
- DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 2.0, $FF0000FF);
- end
- else
- begin
- DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $2E8B5780);
- DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $2E8B5780)
- end;
- if LeftImpactTimer > Lag then dec(LeftImpactTimer,Lag) else LeftImpactTimer:= 0;
- if RightImpactTimer > Lag then dec(RightImpactTimer,Lag) else RightImpactTimer:= 0
- *)
end;
end;
@@ -1075,25 +1008,29 @@
TeamHealthBarWidth:= cTeamHealthWidth * TeamHealthBarHealth div MaxTeamHealth;
- // draw health bar
+ // draw team health bar
r.x:= 0;
r.y:= 0;
r.w:= 2 + TeamHealthBarWidth;
r.h:= htex^.h;
DrawTextureFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, htex);
- // draw health bars right border
+ // draw health bar's right border
inc(r.x, cTeamHealthWidth + 2);
r.w:= 3;
DrawTextureFromRect(TeamHealthBarWidth + 15, cScreenHeight + DrawHealthY + smallScreenOffset, @r, htex);
+ // draw hedgehog health separators in team health bar
h:= 0;
if not hasGone then
for i:= 0 to cMaxHHIndex do
begin
inc(h, Hedgehogs[i].HealthBarHealth);
if (h < TeamHealthBarHealth) and (Hedgehogs[i].HealthBarHealth > 0) then
- DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture);
+ if (IsTooDarkToRead(Clan^.Color)) then
+ DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture)
+ else
+ DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSliderInverted].Texture);
end;
// draw Lua value, if set
@@ -1149,7 +1086,13 @@
h:= -NameTagTex^.w - 24;
if OwnerTex <> nil then
h:= h - OwnerTex^.w - 4;
+ if (IsTooDarkToRead(TeamsArray[t]^.Clan^.Color)) then
+ DrawSpriteRotatedF(sprFingerBackInv, h, cScreenHeight + DrawHealthY + smallScreenOffset + 2 + SpritesData[sprFingerBackInv].Width div 4, 0, 1, -90)
+ else
+ DrawSpriteRotatedF(sprFingerBack, h, cScreenHeight + DrawHealthY + smallScreenOffset + 2 + SpritesData[sprFingerBack].Width div 4, 0, 1, -90);
+ Tint(TeamsArray[t]^.Clan^.Color shl 8 or $FF);
DrawSpriteRotatedF(sprFinger, h, cScreenHeight + DrawHealthY + smallScreenOffset + 2 + SpritesData[sprFinger].Width div 4, 0, 1, -90);
+ untint;
end;
end;
end;
@@ -1162,6 +1105,24 @@
VisibleTeamsCount:= v;
end;
+procedure RenderAttackBar();
+var i: LongInt;
+ tdx, tdy: Double;
+begin
+ if CurrentTeam <> nil then
+ case AttackBar of
+ 2: with CurrentHedgehog^ do
+ begin
+ tdx:= hwSign(Gear^.dX) * Sin(Gear^.Angle * Pi / cMaxAngle);
+ tdy:= - Cos(Gear^.Angle * Pi / cMaxAngle);
+ for i:= (Gear^.Power * 24) div cPowerDivisor downto 0 do
+ DrawSprite(sprPower,
+ hwRound(Gear^.X) + GetLaunchX(CurAmmoType, hwSign(Gear^.dX), Gear^.Angle) + LongInt(round(WorldDx + tdx * (24 + i * 2))) - 16,
+ hwRound(Gear^.Y) + GetLaunchY(CurAmmoType, Gear^.Angle) + LongInt(round(WorldDy + tdy * (24 + i * 2))) - 16,
+ i)
+ end;
+ end;
+end;
var preShiftWorldDx: LongInt;
@@ -1181,10 +1142,9 @@
var i, t: LongInt;
spr: TSprite;
r: TSDL_Rect;
- tdx, tdy: Double;
s: shortstring;
offsetX, offsetY, screenBottom: LongInt;
- replicateToLeft, replicateToRight, tmp: boolean;
+ replicateToLeft, replicateToRight, isNotHiddenByCinematic: boolean;
{$IFDEF USE_VIDEO_RECORDING}
a: Byte;
{$ENDIF}
@@ -1196,8 +1156,8 @@
end
else
begin
- replicateToLeft := (LongInt(leftX) + WorldDx > ViewLeftX);
- replicateToRight:= (LongInt(rightX) + WorldDx < ViewRightX);
+ replicateToLeft := (leftX + WorldDx > ViewLeftX);
+ replicateToRight:= (rightX + WorldDx < ViewRightX);
end;
ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
@@ -1205,6 +1165,7 @@
// note: offsetY is negative!
offsetY:= 10 * Min(0, -145 - ScreenBottom); // TODO limit this in the other direction too
+// Sky and horizont
if (cReducedQuality and rqNoBackground) = 0 then
begin
// Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
@@ -1224,9 +1185,9 @@
untint;
end;
-DrawVisualGears(0);
+DrawVisualGears(0, false);
ChangeDepth(RM, -cStereo_MidDistance);
-DrawVisualGears(4);
+DrawVisualGears(4, false);
if (cReducedQuality and rq2DWater) = 0 then
begin
@@ -1245,7 +1206,7 @@
DrawWaves(-1, 100, - cWaveHeight div 2, - cWaveHeight div 2, 0);
ChangeDepth(RM, cStereo_Land);
-DrawVisualGears(5);
+DrawVisualGears(5, false);
DrawLand(WorldDx, WorldDy);
if replicateToLeft then
@@ -1264,56 +1225,27 @@
DrawWater(255, 0, 0);
-(*
-// Attack bar
- if CurrentTeam <> nil then
- case AttackBar of
- //1: begin
- //r:= StuffPoz[sPowerBar];
- //{$WARNINGS OFF}
- //r.w:= (CurrentHedgehog^.Gear^.Power * 256) div cPowerDivisor;
- //{$WARNINGS ON}
- //DrawSpriteFromRect(r, cScreenWidth - 272, cScreenHeight - 48, 16, 0, Surface);
- //end;
- 2: with CurrentHedgehog^ do
- begin
- tdx:= hwSign(Gear^.dX) * Sin(Gear^.Angle * Pi / cMaxAngle);
- tdy:= - Cos(Gear^.Angle * Pi / cMaxAngle);
- for i:= (Gear^.Power * 24) div cPowerDivisor downto 0 do
- DrawSprite(sprPower,
- hwRound(Gear^.X) + GetLaunchX(CurAmmoType, hwSign(Gear^.dX), Gear^.Angle) + LongInt(round(WorldDx + tdx * (24 + i * 2))) - 16,
- hwRound(Gear^.Y) + GetLaunchY(CurAmmoType, Gear^.Angle) + LongInt(round(WorldDy + tdy * (24 + i * 2))) - 16,
- i)
- end
- end;
-*)
-
-tmp:= bShowFinger;
-bShowFinger:= false;
-
if replicateToLeft then
begin
ShiftWorld(-1);
- DrawVisualGears(1);
+ DrawVisualGears(1, true);
DrawGears();
- DrawVisualGears(6);
+ DrawVisualGears(6, true);
UnshiftWorld();
end;
if replicateToRight then
begin
ShiftWorld(1);
- DrawVisualGears(1);
+ DrawVisualGears(1, true);
DrawGears();
- DrawVisualGears(6);
+ DrawVisualGears(6, true);
UnshiftWorld();
end;
-bShowFinger:= tmp;
-
-DrawVisualGears(1);
+DrawVisualGears(1, false);
DrawGears;
-DrawVisualGears(6);
+DrawVisualGears(6, false);
if SuddenDeathDmg then
@@ -1321,13 +1253,12 @@
else
DrawWater(WaterOpacity, 0, 0);
- // Waves
+// Waves
ChangeDepth(RM, cStereo_Water_near);
DrawWaves( 1, 25 - WorldDx div 9, 0, 0, 12);
if (cReducedQuality and rq2DWater) = 0 then
begin
- //DrawWater(WaterOpacity, - offsetY div 40);
ChangeDepth(RM, cStereo_Water_near);
DrawWaves(-1, 50 + WorldDx div 6, - offsetY div 40, 23, 8);
if SuddenDeathDmg then
@@ -1346,7 +1277,27 @@
else
DrawWaves(-1, 50, cWaveHeight div 2, cWaveHeight div 2, 0);
-DrawGearsTimers;
+// line at airplane height for certain airstrike types (when spawning height is important)
+with CurrentHedgehog^ do
+ if (isCursorVisible) and ((CurAmmoType = amNapalm) or (CurAmmoType = amMineStrike) or (((GameFlags and gfMoreWind) <> 0) and ((CurAmmoType = amDrillStrike) or (CurAmmoType = amAirAttack)))) then
+ DrawLine(-3000, topY-300, 7000, topY-300, 3.0, (Team^.Clan^.Color shr 16), (Team^.Clan^.Color shr 8) and $FF, Team^.Clan^.Color and $FF, $FF);
+
+// gear HUD extras (fuel indicator, secondary ammo, etc.)
+if replicateToLeft then
+ begin
+ ShiftWorld(-1);
+ DrawGearsGui();
+ UnshiftWorld();
+ end;
+
+if replicateToRight then
+ begin
+ ShiftWorld(1);
+ DrawGearsGui();
+ UnshiftWorld();
+ end;
+
+DrawGearsGui();
// everything after this ChangeDepth will be drawn outside the screen
// note: negative parallax gears should last very little for a smooth stereo effect
@@ -1355,18 +1306,18 @@
if replicateToLeft then
begin
ShiftWorld(-1);
- DrawVisualGears(2);
+ DrawVisualGears(2, true);
UnshiftWorld();
end;
if replicateToRight then
begin
ShiftWorld(1);
- DrawVisualGears(2);
+ DrawVisualGears(2, true);
UnshiftWorld();
end;
- DrawVisualGears(2);
+ DrawVisualGears(2, false);
// everything after this ResetDepth will be drawn at screen level (depth = 0)
// note: everything that needs to be readable should be on this level
@@ -1375,39 +1326,101 @@
if replicateToLeft then
begin
ShiftWorld(-1);
- DrawVisualGears(3);
+ DrawVisualGears(3, true);
UnshiftWorld();
end;
if replicateToRight then
begin
ShiftWorld(1);
- DrawVisualGears(3);
+ DrawVisualGears(3, true);
UnshiftWorld();
end;
- DrawVisualGears(3);
+ DrawVisualGears(3, false);
-{$WARNINGS OFF}
-// Target
+// Target (e.g. air attack, bee, ...)
if (TargetPoint.X <> NoPointX) and (CurrentTeam <> nil) and (CurrentHedgehog <> nil) then
begin
with PHedgehog(CurrentHedgehog)^ do
begin
if CurAmmoType = amBee then
- DrawSpriteRotatedF(sprTargetBee, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
+ spr:= sprTargetBee
else
- DrawSpriteRotatedF(sprTargetP, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
- end
+ spr:= sprTargetP;
+ if replicateToLeft then
+ begin
+ ShiftWorld(-1);
+ if spr = sprTargetP then
+ begin
+ if IsTooDarkToRead(Team^.Clan^.Color) then
+ DrawSpriteRotatedF(sprTargetPBackInv, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
+ else
+ DrawSpriteRotatedF(sprTargetPBack, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
+ Tint(Team^.Clan^.Color shl 8 or $FF);
+ end;
+ DrawSpriteRotatedF(spr, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
+ if spr = sprTargetP then
+ untint;
+ UnshiftWorld();
+ end;
+
+ if replicateToRight then
+ begin
+ ShiftWorld(1);
+ if spr = sprTargetP then
+ begin
+ if IsTooDarkToRead(Team^.Clan^.Color) then
+ DrawSpriteRotatedF(sprTargetPBackInv, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
+ else
+ DrawSpriteRotatedF(sprTargetPBack, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
+ Tint(Team^.Clan^.Color shl 8 or $FF);
+ end;
+ DrawSpriteRotatedF(spr, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
+ if spr = sprTargetP then
+ untint;
+ UnshiftWorld();
+ end;
+
+ if spr = sprTargetP then
+ begin
+ if IsTooDarkToRead(Team^.Clan^.Color) then
+ DrawSpriteRotatedF(sprTargetPBackInv, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
+ else
+ DrawSpriteRotatedF(sprTargetPBack, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
+ Tint(Team^.Clan^.Color shl 8 or $FF);
+ end;
+ DrawSpriteRotatedF(spr, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
+ if spr = sprTargetP then
+ untint;
+ end;
end;
-{$WARNINGS ON}
+
+// Attack bar
+if replicateToLeft then
+ begin
+ ShiftWorld(-1);
+ RenderAttackBar();
+ UnshiftWorld();
+ end;
+if replicateToRight then
+ begin
+ ShiftWorld(1);
+ RenderAttackBar();
+ UnshiftWorld();
+ end;
+
+RenderAttackBar();
+
+// World edge
RenderWorldEdge();
-// this scale is used to keep the various widgets at the same dimension at all zoom levels
+// This scale is used to keep the various widgets at the same dimension at all zoom levels
SetScale(cDefaultZoomLevel);
-// cinematic effects
+isNotHiddenByCinematic:= true;
+// Cinematic Mode: Determine effects and state
if CinematicScript or (InCinematicMode and autoCameraOn
and ((CurrentHedgehog = nil) or CurrentHedgehog^.Team^.ExtDriven
or (CurrentHedgehog^.BotLevel <> 0) or (GameType = gmtDemo))) then
@@ -1416,7 +1429,10 @@
begin
inc(CinematicSteps, Lag);
if CinematicSteps > 300 then
- CinematicSteps:= 300;
+ begin
+ CinematicSteps:= 300;
+ isNotHiddenByCinematic:= false;
+ end;
end;
end
else if CinematicSteps > 0 then
@@ -1426,22 +1442,8 @@
CinematicSteps:= 0;
end;
-// render black bars
-if CinematicSteps > 0 then
- begin
- r.x:= ViewLeftX;
- r.w:= ViewWidth;
- r.y:= ViewTopY;
- CinematicBarH:= (ViewHeight * CinematicSteps) div 2048;
- r.h:= CinematicBarH;
- DrawRect(r, 0, 0, 0, $FF, true);
- r.y:= ViewBottomY - r.h;
- DrawRect(r, 0, 0, 0, $FF, true);
- end;
-
-
// Turn time
-if UIDisplay <> uiNone then
+if (UIDisplay <> uiNone) and (isNotHiddenByCinematic) then
begin
{$IFDEF USE_TOUCH_INTERFACE}
offsetX:= cScreenHeight - 13;
@@ -1480,33 +1482,79 @@
DrawSprite(sprFrame, -(cScreenWidth shr 1) + t - 4 + offsetY, cScreenHeight - offsetX, 0);
end;
-// Captions
- DrawCaptions
end;
+// Team bars
+if (UIDisplay = uiAll) and (isNotHiddenByCinematic) then
+ RenderTeamsHealth;
+
+// Current hedgehog health in top left corner
+if ((UIDisplay = uiAll) or (UIDisplay = uiNoTeams)) and (isNotHiddenByCinematic) and
+ (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and
+ (CurrentHedgehog^.HealthTagTex <> nil) and
+ ((CurrentHedgehog^.Gear^.State and gstHHDriven) <> 0) then
+ begin
+ t:= 11;
+ i:= t;
{$IFDEF USE_TOUCH_INTERFACE}
-// Draw buttons Related to the Touch interface
-DrawScreenWidget(@arrowLeft);
-DrawScreenWidget(@arrowRight);
-DrawScreenWidget(@arrowUp);
-DrawScreenWidget(@arrowDown);
-
-DrawScreenWidget(@fireButton);
-DrawScreenWidget(@jumpWidget);
-DrawScreenWidget(@AMWidget);
-DrawScreenWidget(@pauseButton);
-DrawScreenWidget(@utilityWidget);
+ i:= t + pauseButton.frame.y + pauseButton.frame.h;
{$ENDIF}
-if UIDisplay = uiAll then
- RenderTeamsHealth;
+ // Hide health and healh icons in gfInvulnerable mode (except heResurrectable)
+ if ((GameFlags and gfInvulnerable) = 0) then
+ begin
+ // Health tag
+ DrawTexture(cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - 16, i, CurrentHedgehog^.HealthTagTex);
+ inc(t, CurrentHedgehog^.HealthTagTex^.h);
+ cDemoClockFPSOffsetY:= t;
+
+ t:= SpritesData[sprHealthHud].Width + 18;
+ // Main health icon. Appearance depends on game mode and poisoning state
+ if ((GameFlags and gfResetHealth) = 0) then
+ if (CurrentHedgehog^.Effects[hePoisoned] <> 0) then
+ DrawSprite(sprHealthPoisonHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t), i, 0)
+ else
+ DrawSprite(sprHealthHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t), i, 0)
+ else
+ if (CurrentHedgehog^.Effects[hePoisoned] <> 0) then
+ DrawSprite(sprMedicPoisonHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t), i, 0)
+ else
+ DrawSprite(sprMedicHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t), i, 0);
+ // Put halo above health icon for resurrectable hog
+ if (CurrentHedgehog^.Effects[heResurrectable] <> 0) then
+ DrawSprite(sprHaloHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t - 2), i - SpritesData[sprHaloHud].Height + 1, 0);
-// Lag alert
-if isInLag then
- DrawSprite(sprLag, 32 - (cScreenWidth shr 1), 32, (RealTicks shr 7) mod 12);
+ // Additional health-related states
+ inc(t, 2);
+ // Invulnerable
+ if (CurrentHedgehog^.Effects[heInvulnerable] <> 0) then
+ begin
+ inc(t, SpritesData[sprInvulnHud].Width + 2);
+ DrawSprite(sprInvulnHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t), i, 0)
+ end
+ // Karma
+ else if ((GameFlags and gfKarma) <> 0) then
+ begin
+ inc(t, SpritesData[sprKarmaHud].Width + 2);
+ DrawSprite(sprKarmaHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t), i, 0)
+ end;
+ // Vampirism
+ if cVampiric then
+ begin
+ inc(t, SpritesData[sprVampHud].Width + 2);
+ DrawSprite(sprVampHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t), i, 0);
+ end;
+ end
+ // in gfInvulnerable mode ...
+ else if (CurrentHedgehog^.Effects[heResurrectable] <> 0) then
+ // show halo for resurrectable hog
+ DrawSprite(sprHaloHud, (cScreenWidth div 2 - CurrentHedgehog^.HealthTagTex^.w - t - 2), i, 0);
+ end
+else
+ cDemoClockFPSOffsetY:= 0;
// Wind bar
-if UIDisplay <> uiNone then
+if (UIDisplay <> uiNone) and (isNotHiddenByCinematic) then
begin
{$IFDEF USE_TOUCH_INTERFACE}
offsetX:= cScreenHeight - 13;
@@ -1519,7 +1567,7 @@
if WindBarWidth > 0 then
begin
{$WARNINGS OFF}
- r.x:= 8 - (RealTicks shr 6) mod 8;
+ r.x:= 8 - (RealTicks shr 6) mod 9;
{$WARNINGS ON}
r.y:= 0;
r.w:= WindBarWidth;
@@ -1530,7 +1578,7 @@
if WindBarWidth < 0 then
begin
{$WARNINGS OFF}
- r.x:= (Longword(WindBarWidth) + RealTicks shr 6) mod 8;
+ r.x:= (Longword(WindBarWidth) + RealTicks shr 6) mod 9;
{$WARNINGS ON}
r.y:= 0;
r.w:= - WindBarWidth;
@@ -1539,28 +1587,97 @@
end
end;
-{$IFNDEF USE_TOUCH_INTERFACE}
// Indicators for global effects (extra damage, low gravity)
-// TODO: Add support for touch interface (need to find out correct offset)
-if UIDisplay <> uiNone then
+if (UIDisplay <> uiNone) and (isNotHiddenByCinematic) then
begin
+{$IFDEF USE_TOUCH_INTERFACE}
+ offsetX:= (cScreenWidth shr 1) - 95;
+ offsetY:= cScreenHeight - 21;
+{$ELSE}
offsetX:= 45;
offsetY:= 51;
+{$ENDIF}
if cDamageModifier = _1_5 then
begin
DrawTextureF(ropeIconTex, 1, (cScreenWidth shr 1) - offsetX, cScreenHeight - offsetY, 0, 1, 32, 32);
DrawTextureF(SpritesData[sprAMAmmos].Texture, 0.90, (cScreenWidth shr 1) - offsetX, cScreenHeight - offsetY, ord(amExtraDamage) - 1, 1, 32, 32);
+{$IFDEF USE_TOUCH_INTERFACE}
+ offsetX := offsetX - 33
+{$ELSE}
offsetX := offsetX + 33
+{$ENDIF}
end;
if (cLowGravity) or ((GameFlags and gfLowGravity) <> 0) then
begin
DrawTextureF(ropeIconTex, 1, (cScreenWidth shr 1) - offsetX, cScreenHeight - offsetY, 0, 1, 32, 32);
DrawTextureF(SpritesData[sprAMAmmos].Texture, 0.90, (cScreenWidth shr 1) - offsetX, cScreenHeight - offsetY, ord(amLowGravity) - 1, 1, 32, 32);
+{$IFDEF USE_TOUCH_INTERFACE}
+ offsetX := offsetX - 33
+{$ELSE}
+ offsetX := offsetX + 33
+{$ENDIF}
+ end;
+ if cLaserSighting then
+ begin
+ DrawTextureF(ropeIconTex, 1, (cScreenWidth shr 1) - offsetX, cScreenHeight - offsetY, 0, 1, 32, 32);
+ DrawTextureF(SpritesData[sprAMAmmos].Texture, 0.90, (cScreenWidth shr 1) - offsetX, cScreenHeight - offsetY, ord(amLaserSight) - 1, 1, 32, 32);
end;
end;
+
+// Cinematic Mode: Render black bars
+if CinematicSteps > 0 then
+ begin
+ r.x:= ViewLeftX;
+ r.w:= ViewWidth;
+ r.y:= ViewTopY;
+ CinematicBarH:= (ViewHeight * CinematicSteps) div 2048;
+ r.h:= CinematicBarH;
+ DrawRect(r, 0, 0, 0, $FF, true);
+ r.y:= ViewBottomY - r.h;
+ DrawRect(r, 0, 0, 0, $FF, true);
+ end;
+
+// Touchscreen interface widgets
+{$IFDEF USE_TOUCH_INTERFACE}
+DrawScreenWidget(@arrowLeft);
+DrawScreenWidget(@arrowRight);
+DrawScreenWidget(@arrowUp);
+DrawScreenWidget(@arrowDown);
+
+DrawScreenWidget(@fireButton);
+DrawScreenWidget(@jumpWidget);
+DrawScreenWidget(@AMWidget);
+DrawScreenWidget(@utilityWidget);
+DrawScreenWidget(@utilityWidget2);
+DrawScreenWidget(@pauseButton);
{$ENDIF}
+// Captions
+if UIDisplay <> uiNone then
+ DrawCaptions;
+
+// Lag alert
+if isInLag then
+ DrawSprite(sprLag, 32 - (cScreenWidth shr 1), 32, (RealTicks shr 7) mod 12);
+
+// Chat
+DrawChat;
+
+
+// Mission panel
+if not isFirstFrame and (missionTimer <> 0) or isShowMission or isPaused or fastUntilLag or (GameState = gsConfirm) then
+ begin
+ if (ReadyTimeLeft = 0) and (missionTimer > 0) then
+ dec(missionTimer, Lag);
+ if missionTimer < 0 then
+ missionTimer:= 0; // avoid subtracting below 0
+ if missionTex <> nil then
+ DrawTextureCentered(0, Min((cScreenHeight shr 1) + 100, cScreenHeight - 48 - missionTex^.h), missionTex);
+ end;
+if missionTimer = 0 then
+ isForceMission := false;
+
// AmmoMenu
if bShowAmmoMenu and ((AMState = AMHidden) or (AMState = AMHiding)) then
begin
@@ -1582,44 +1699,33 @@
if bShowAmmoMenu or (AMState = AMHiding) then
ShowAmmoMenu;
+// Centered status/menu messages (synchronizing, auto skip, pause, etc.)
+if fastUntilLag then
+ DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture)
+else if isAFK then
+ DrawTextureCentered(0, (cScreenHeight shr 1), AFKTexture)
+else if isPaused then
+ DrawTextureCentered(0, (cScreenHeight shr 1), PauseTexture);
+
// Cursor
if isCursorVisible and bShowAmmoMenu then
DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8);
-// Chat
-DrawChat;
-
-
-// various captions
-if fastUntilLag then
- DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture);
-if isPaused then
- DrawTextureCentered(0, (cScreenHeight shr 1), PauseTexture);
-if isAFK then
- DrawTextureCentered(0, (cScreenHeight shr 1), AFKTexture);
-if not isFirstFrame and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then
- begin
- if (ReadyTimeLeft = 0) and (missionTimer > 0) then
- dec(missionTimer, Lag);
- if missionTimer < 0 then
- missionTimer:= 0; // avoid subtracting below 0
- if missionTex <> nil then
- DrawTextureCentered(0, Min((cScreenHeight shr 1) + 100, cScreenHeight - 48 - missionTex^.h), missionTex);
- end;
-
-// fps
+// FPS and demo replay time
{$IFDEF USE_TOUCH_INTERFACE}
-offsetX:= pauseButton.frame.y + pauseButton.frame.h + 12;
+offsetY:= cDemoClockFPSOffsetY + 10 + pauseButton.frame.y + pauseButton.frame.h;
{$ELSE}
-offsetX:= 10;
+offsetY:= cDemoClockFPSOffsetY + 10;
{$ENDIF}
-offsetY:= cOffsetY;
+offsetX:= cOffsetY;
if (RM = rmDefault) or (RM = rmRightEye) then
begin
inc(Frames);
if cShowFPS or (GameType = gmtDemo) then
inc(CountTicks, Lag);
+
+ // Demo replay time
if (GameType = gmtDemo) and (CountTicks >= 1000) then
begin
i:= GameTicks div 1000;
@@ -1642,29 +1748,36 @@
SDL_FreeSurface(tmpSurface)
end;
- if timeTexture <> nil then
- DrawTexture((cScreenWidth shr 1) - 20 - timeTexture^.w - offsetY, offsetX + timeTexture^.h+5, timeTexture);
+ if (timeTexture <> nil) and (UIDisplay <> uiNone) then
+ DrawTexture((cScreenWidth shr 1) - 20 - timeTexture^.w - offsetX, offsetY, timeTexture);
- if cShowFPS then
+ // FPS counter
+ if cShowFPS and (UIDisplay <> uiNone) then
begin
if CountTicks >= 1000 then
begin
FPS:= Frames;
Frames:= 0;
CountTicks:= 0;
- s:= Format(trmsg[sidFPS], inttostr(FPS));
- tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
+ s:= Format(shortstring(trmsg[sidFPS]), inttostr(FPS));
+ tmpSurface:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trmsg[sidFPS],fnt16)].Handle, Str2PChar(s), cWhiteColorChannels);
tmpSurface:= doSurfaceConversion(tmpSurface);
FreeAndNilTexture(fpsTexture);
fpsTexture:= Surface2Tex(tmpSurface, false);
SDL_FreeSurface(tmpSurface)
end;
if fpsTexture <> nil then
- DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
+ begin
+ if timeTexture <> nil then
+ i:= fpsTexture^.h + 5
+ else
+ i:= 0;
+ DrawTexture((cScreenWidth shr 1) - 20 - fpsTexture^.w - offsetX, offsetY + i, fpsTexture);
+ end;
end;
end;
-
+// Quit Y/N question
if GameState = gsConfirm then
DrawTextureCentered(0, (cScreenHeight shr 1)-40, ConfirmTexture);
@@ -1699,7 +1812,7 @@
end;
{$IFDEF USE_VIDEO_RECORDING}
-// during video prerecording draw red blinking circle and text 'rec'
+// During video prerecording draw red blinking circle and text 'rec'
if flagPrerecording then
begin
if recTexture = nil then
@@ -1713,8 +1826,8 @@
end;
DrawTexture( -(cScreenWidth shr 1) + 50, 20, recTexture);
- //a:= Byte(Round(127*(1 + sin(RealTicks*0.007))));
- a:= Byte(min(255, abs(-255 + ((RealTicks div 2) and 511))));
+ t:= -255 + ((RealTicks div 2) and 511);
+ a:= Byte(min(255, abs(t)));
// draw red circle
DrawCircleFilled(-(cScreenWidth shr 1) + 30, 35, 10, $FF, $00, $00, a);
@@ -1723,29 +1836,6 @@
SetScale(zoom);
-// Attack bar
- if CurrentTeam <> nil then
- case AttackBar of
-(* 1: begin
- r:= StuffPoz[sPowerBar];
- {$WARNINGS OFF}
- r.w:= (CurrentHedgehog^.Gear^.Power * 256) div cPowerDivisor;
- {$WARNINGS ON}
- DrawSpriteFromRect(r, cScreenWidth - 272, cScreenHeight - 48, 16, 0, Surface);
- end;*)
- 2: with CurrentHedgehog^ do
- begin
- tdx:= hwSign(Gear^.dX) * Sin(Gear^.Angle * Pi / cMaxAngle);
- tdy:= - Cos(Gear^.Angle * Pi / cMaxAngle);
- for i:= (Gear^.Power * 24) div cPowerDivisor downto 0 do
- DrawSprite(sprPower,
- hwRound(Gear^.X) + GetLaunchX(CurAmmoType, hwSign(Gear^.dX), Gear^.Angle) + LongInt(round(WorldDx + tdx * (24 + i * 2))) - 16,
- hwRound(Gear^.Y) + GetLaunchY(CurAmmoType, Gear^.Angle) + LongInt(round(WorldDy + tdy * (24 + i * 2))) - 16,
- i)
- end
- end;
-
-
// Cursor
if isCursorVisible and (not bShowAmmoMenu) then
begin
@@ -1753,11 +1843,9 @@
with CurrentHedgehog^ do
if (Gear <> nil) and ((Gear^.State and gstChooseTarget) <> 0) then
begin
- if (CurAmmoType = amNapalm) or (CurAmmoType = amMineStrike) or (((GameFlags and gfMoreWind) <> 0) and ((CurAmmoType = amDrillStrike) or (CurAmmoType = amAirAttack))) then
- DrawLine(-3000, topY-300, 7000, topY-300, 3.0, (Team^.Clan^.Color shr 16), (Team^.Clan^.Color shr 8) and $FF, Team^.Clan^.Color and $FF, $FF);
i:= GetCurAmmoEntry(CurrentHedgehog^)^.Pos;
with Ammoz[CurAmmoType] do
- if PosCount > 1 then
+ if PosCount > 0 then
begin
if (CurAmmoType = amGirder) or (CurAmmoType = amTeleport) then
begin
@@ -1769,9 +1857,15 @@
end;
DrawSprite(PosSprite, TargetCursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i);
Untint();
+ if (WorldEdge = weWrap) and (CurAmmoType = amBee) then
+ begin
+ if (TargetCursorPoint.X - WorldDx > rightX) then
+ DrawSprite(sprThroughWrap, TargetCursorPoint.X - (SpritesData[sprThroughWrap].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1) - SpritesData[sprThroughWrap].Height - 2, 0)
+ else if (TargetCursorPoint.X - WorldDx < leftX) then
+ DrawSprite(sprThroughWrap, TargetCursorPoint.X - (SpritesData[sprThroughWrap].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1) - SpritesData[sprThroughWrap].Height - 2, 1);
+ end;
end;
end;
- //DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8)
DrawTextureF(SpritesData[sprArrow].Texture, cDefaultZoomLevel / cScaleFactor, TargetCursorPoint.X + round(SpritesData[sprArrow].Width / cScaleFactor), cScreenHeight + round(SpritesData[sprArrow].Height / cScaleFactor) - TargetCursorPoint.Y, (RealTicks shr 6) mod 8, 1, SpritesData[sprArrow].Width, SpritesData[sprArrow].Height);
end;
@@ -1791,7 +1885,7 @@
var PrevSentPointTime: LongWord = 0;
procedure MoveCamera;
-var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY, dstX: LongInt;
+var EdgesDist, wdy, shs,z, dstX: LongInt;
inbtwnTrgtAttks: Boolean;
begin
{$IFNDEF MOBILE}
@@ -1813,9 +1907,9 @@
if (WorldEdge = weWrap) then
begin
- if dstX - prevPoint.X < (LongInt(leftX) - rightX) div 2 then
+ if dstX - prevPoint.X < (leftX - rightX) div 2 then
CursorPoint.X:= (prevPoint.X * 7 + dstX - (leftX - rightX)) div 8
- else if dstX - prevPoint.X > (LongInt(rightX) - leftX) div 2 then
+ else if dstX - prevPoint.X > (rightX - leftX) div 2 then
CursorPoint.X:= (prevPoint.X * 7 + dstX - (rightX - leftX)) div 8
else
CursorPoint.X:= (prevPoint.X * 7 + dstX) div 8;
@@ -1834,9 +1928,9 @@
if (WorldEdge = weWrap) then
begin
if -WorldDx < leftX then
- WorldDx:= WorldDx - LongInt(rightX) + leftX
+ WorldDx:= WorldDx - rightX + leftX
else if -WorldDx > rightX then
- WorldDx:= WorldDx + LongInt(rightX) - leftX;
+ WorldDx:= WorldDx + rightX - leftX;
end;
wdy:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine - (cVisibleWater + trunc(CinematicBarH / (cScaleFactor / 2.0)));
@@ -1848,22 +1942,6 @@
if (AMState = AMShowingUp) or (AMState = AMShowing) then
begin
-{$IFDEF USE_LANDSCAPE_AMMOMENU}
- amNumOffsetX:= 0;
- {$IFDEF USE_AM_NUMCOLUMN}
- amNumOffsetY:= AMSlotSize;
- {$ELSE}
- amNumOffsetY:= 0;
- {$ENDIF}
-{$ELSE}
- amNumOffsetY:= 0;
- {$IFDEF USE_AM_NUMCOLUMN}
- amNumOffsetX:= AMSlotSize;
- {$ELSE}
- amNumOffsetX:= 0;
- {$ENDIF}
-
-{$ENDIF}
if CursorPoint.X < AmmoRect.x + amNumOffsetX + 3 then//check left
CursorPoint.X:= AmmoRect.x + amNumOffsetX + 3;
if CursorPoint.X > AmmoRect.x + AmmoRect.w - 3 then//check right
@@ -1873,7 +1951,6 @@
if CursorPoint.Y < cScreenHeight - (AmmoRect.y + AmmoRect.h - AMSlotSize - 5) then//check bottom
CursorPoint.Y:= cScreenHeight - (AmmoRect.y + AmmoRect.h - AMSlotSize - 5);
prevPoint:= CursorPoint;
- //if cHasFocus then SDL_WarpMouse(CursorPoint.X + cScreenWidth div 2, cScreenHeight - CursorPoint.Y);
exit
end;
@@ -1929,7 +2006,6 @@
// this moves the camera according to CursorPoint X and Y
prevPoint:= CursorPoint;
-//if cHasFocus then SDL_WarpMouse(CursorPoint.X + (cScreenWidth shr 1), cScreenHeight - CursorPoint.Y);
if WorldDy > LAND_HEIGHT + 1024 then
WorldDy:= LAND_HEIGHT + 1024;
if WorldDy < wdy then
@@ -1941,6 +2017,11 @@
end;
procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);
+begin
+ ShowMission(caption, subcaption, text, icon, time, false);
+end;
+
+procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt; forceDisplay : boolean);
var r: TSDL_Rect;
begin
if cOnlyStats then exit;
@@ -1948,6 +2029,10 @@
r.w:= 32;
r.h:= 32;
+// If true, then mission panel cannot be hidden by releasing the mission panel key.
+// Is in effect until timer runs out, is hidden with HideMission or ShowMission is called with forceDisplay=false.
+isForceMission := forceDisplay;
+
if time = 0 then
time:= 5000;
missionTimer:= time;
@@ -1970,14 +2055,17 @@
procedure HideMission;
begin
missionTimer:= 0;
+ isForceMission:= false;
end;
-procedure SetAmmoTexts(ammoType: TAmmoType; name: ansistring; caption: ansistring; description: ansistring);
+procedure SetAmmoTexts(ammoType: TAmmoType; name: ansistring; caption: ansistring; description: ansistring; autoLabels: boolean);
var
ammoStrId: TAmmoStrId;
ammoStr: ansistring;
tmpsurf: PSDL_Surface;
begin
+ if cOnlyStats then exit;
+
ammoStrId := Ammoz[ammoType].NameId;
trluaammo[ammoStrId] := name;
@@ -1987,7 +2075,7 @@
ammoStr:= trammo[ammoStrId];
if checkFails(length(ammoStr) > 0,'No default text/translation found for ammo type #' + intToStr(ord(ammoType)) + '!',true) then exit;
-
+
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(ammoStr,fnt16)].Handle, PChar(ammoStr), cWhiteColorChannels);
if checkFails(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ammoType)) + ' failed!',true) then exit;
tmpsurf:= doSurfaceConversion(tmpsurf);
@@ -1997,6 +2085,7 @@
trluaammoc[ammoStrId] := caption;
trluaammod[ammoStrId] := description;
+ trluaammoe[ammoStrId] := autoLabels;
end;
procedure ShakeCamera(amount: LongInt);
@@ -2006,19 +2095,19 @@
amount:= Max(1, round(amount*zoom/2));
WorldDx:= WorldDx - amount + LongInt(random(1 + amount * 2));
WorldDy:= WorldDy - amount + LongInt(random(1 + amount * 2));
-//CursorPoint.X:= CursorPoint.X - amount + LongInt(random(1 + amount * 2));
-//CursorPoint.Y:= CursorPoint.Y - amount + LongInt(random(1 + amount * 2))
end;
procedure onFocusStateChanged;
begin
-if (not cHasFocus) and (GameState <> gsConfirm) then
- ParseCommand('quit', true);
{$IFDEF MOBILE}
+if (not cHasFocus) and (not isPaused) then
+ ParseCommand('pause', true);
// when created SDL receives an exposure event that calls UndampenAudio at full power, muting audio
exit;
{$ENDIF}
+if (not cHasFocus) and (GameState <> gsConfirm) then
+ ParseCommand('quit', true);
{$IFDEF USE_VIDEO_RECORDING}
// do not change volume during prerecording as it will affect sound in video file
@@ -2032,10 +2121,51 @@
procedure updateCursorVisibility;
begin
- if isPaused or isAFK then
- SDL_ShowCursor(1)
+ if isPaused or isAFK or (GameState = gsConfirm) then
+ begin
+{$IFNDEF USE_TOUCH_INTERFACE}
+ SDL_SetRelativeMouseMode(SDL_FALSE);
+{$ENDIF}
+ if SDL_ShowCursor(SDL_QUERY) = SDL_DISABLE then
+ begin
+ uCursor.resetPosition;
+{$IFNDEF USE_TOUCH_INTERFACE}
+ SDL_ShowCursor(SDL_ENABLE);
+{$ENDIF}
+ end;
+ end
else
- SDL_ShowCursor(ord(GameState = gsConfirm))
+ begin
+ uCursor.resetPositionDelta;
+{$IFNDEF USE_TOUCH_INTERFACE}
+ SDL_ShowCursor(SDL_DISABLE);
+ SDL_SetRelativeMouseMode(SDL_TRUE);
+{$ENDIF}
+ end;
+end;
+
+procedure updateTouchWidgets(ammoType: TAmmoType);
+begin
+{$IFDEF USE_TOUCH_INTERFACE}
+//show the aiming buttons + animation
+if (Ammoz[ammoType].Ammo.Propz and ammoprop_NeedUpDown) <> 0 then
+ begin
+ if (not arrowUp.show) then
+ begin
+ animateWidget(@arrowUp, true, true);
+ animateWidget(@arrowDown, true, true);
+ end;
+ end
+else
+ if arrowUp.show then
+ begin
+ animateWidget(@arrowUp, true, false);
+ animateWidget(@arrowDown, true, false);
+ end;
+SetUtilityWidgetState(ammoType);
+{$ELSE}
+ammoType:= ammoType; // avoid hint
+{$ENDIF}
end;
procedure SetUtilityWidgetState(ammoType: TAmmoType);
@@ -2048,20 +2178,32 @@
if ((Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0) and (ammoType <> amDrillStrike) then
begin
utilityWidget.sprite:= sprTimerButton;
- animateWidget(@utilityWidget, true, true);
+ if (not utilityWidget.show) then
+ animateWidget(@utilityWidget, true, true);
end
else if (Ammoz[ammoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
begin
utilityWidget.sprite:= sprTargetButton;
- animateWidget(@utilityWidget, true, true);
+ if (not utilityWidget.show) then
+ animateWidget(@utilityWidget, true, true);
end
else if ammoType = amSwitch then
begin
utilityWidget.sprite:= sprSwitchButton;
- animateWidget(@utilityWidget, true, true);
+ if (not utilityWidget.show) then
+ animateWidget(@utilityWidget, true, true);
end
else if utilityWidget.show then
animateWidget(@utilityWidget, true, false);
+
+ if ((Ammoz[ammoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
+ begin
+ utilityWidget2.sprite:= sprBounceButton;
+ if (not utilityWidget2.show) then
+ animateWidget(@utilityWidget2, true, true);
+ end
+ else if utilityWidget2.show then
+ animateWidget(@utilityWidget2, true, false);
{$ELSE}
ammoType:= ammoType; // avoid hint
{$ENDIF}