diff --git a/src/game/g_gfx.pas b/src/game/g_gfx.pas
index e4c46f199d17a9bf74a2180be95d1ff5e4fc0c4c..8094c4e4e1af00e578f2f6d82d70340e75c565f0 100644 (file)
--- a/src/game/g_gfx.pas
+++ b/src/game/g_gfx.pas
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
particleType: TPartType;
red, green, blue: Byte;
alpha: Byte;
particleType: TPartType;
red, green, blue: Byte;
alpha: Byte;
- time, liveTime: Word;
+ time, liveTime, waitTime: Word;
stickDX: Integer; // STATE_STICK: -1,1: stuck to a wall; 0: stuck to ceiling
justSticked: Boolean; // not used
floorY: Integer; // actually, floor-1; `Unknown`: unknown
stickDX: Integer; // STATE_STICK: -1,1: stuck to a wall; 0: stuck to ceiling
justSticked: Boolean; // not used
floorY: Integer; // actually, floor-1; `Unknown`: unknown
function TParticle.checkAirStreams (): Boolean;
var
pan: TPanel;
function TParticle.checkAirStreams (): Boolean;
var
pan: TPanel;
+ r: Integer;
begin
pan := g_Map_PanelAtPoint(x, y, GridTagLift);
begin
pan := g_Map_PanelAtPoint(x, y, GridTagLift);
- result := (pan <> nil);
+ result := (pan <> nil) and WordBool(pan.PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT));
+ r := Random(3);
if result then
begin
if result then
begin
- if ((pan.PanelType and PANEL_LIFTUP) <> 0) then
- begin
- if (velY > -4-Random(3)) then velY -= 0.8;
- if (abs(velX) > 0.1) then velX -= velX/10.0;
- velX += (Random-Random)*0.2;
- accelY := 0.15;
- end
- else if ((pan.PanelType and PANEL_LIFTLEFT) <> 0) then
- begin
- if (velX > -8-Random(3)) then velX -= 0.8;
- accelY := 0.15;
- end
- else if ((pan.PanelType and PANEL_LIFTRIGHT) <> 0) then
- begin
- if (velX < 8+Random(3)) then velX += 0.8;
- accelY := 0.15;
- end
- else
- begin
- result := false;
+ case pan.LiftType of
+ LIFTTYPE_UP:
+ begin
+ if (velY > -1-r) then velY -= 0.8;
+ if (abs(velX) > 0.1) then velX -= velX/10.0;
+ velX += (Random-Random)*0.2;
+ accelY := 0.15;
+ end;
+ LIFTTYPE_DOWN:
+ begin
+ if (velY < 1+r) then velY += 0.8;
+ accelY := 0.15;
+ end;
+ LIFTTYPE_LEFT:
+ begin
+ if (velX > -8-r) then velX -= (8+r) div 2;
+ accelY := 0.15;
+ end;
+ LIFTTYPE_RIGHT:
+ begin
+ if (velX < 8+r) then velX += (8+r) div 2;
+ accelY := 0.15;
+ end;
+ else
+ result := false;
end;
// awake
if result and (state = TPartState.Sleeping) then state := TPartState.Normal;
end;
// awake
if result and (state = TPartState.Sleeping) then state := TPartState.Normal;
ex: Integer;
begin
if (not force) and (ceilingY <> Unknown) then exit;
ex: Integer;
begin
if (not force) and (ceilingY <> Unknown) then exit;
- if (nil = g_Map_traceToNearest(x, y, x, g_Map_MinY, GridTagObstacle, @ex, @ceilingY)) then
+ if (nil = g_Map_traceToNearest(x, y, x, g_Map_MinY, GridTagSolid, @ex, @ceilingY)) then
begin
ceilingY := g_Map_MinY-2;
end;
begin
ceilingY := g_Map_MinY-2;
end;
pan: TPanel;
dx, dy: SmallInt;
ex, ey: Integer;
pan: TPanel;
dx, dy: SmallInt;
ex, ey: Integer;
- checkEnv: Boolean;
+ checkEnv, inAir, inStep: Boolean;
floorJustTraced: Boolean;
{$IF DEFINED(D2F_DEBUG_FALL_MPLAT)}
oldFloorY: Integer;
floorJustTraced: Boolean;
{$IF DEFINED(D2F_DEBUG_FALL_MPLAT)}
oldFloorY: Integer;
dx := round(velX);
dy := round(velY);
dx := round(velX);
dy := round(velY);
- if (state = TPartState.Normal) then checkAirStreams();
+ inAir := checkAirStreams();
// gravity, if not stuck
if (state <> TPartState.Stuck) and (abs(velX) < 0.1) and (abs(velY) < 0.1) then
// gravity, if not stuck
if (state <> TPartState.Stuck) and (abs(velX) < 0.1) and (abs(velY) < 0.1) then
if (dx <> 0) then
begin
// has some horizontal velocity
if (dx <> 0) then
begin
// has some horizontal velocity
- pan := g_Map_traceToNearest(x, y, x+dx, y+dy, GridTagObstacle, @ex, @ey);
+ inStep := False;
+ pan := g_Map_traceToNearest(x, y, x+dx, y+dy, GridTagSolid, @ex, @ey);
+ if (pan = nil) and (dy >= 0) then
+ begin
+ // do not stuck inside step
+ if g_Map_traceToNearest(x, y, x, y, GridTagStep, nil, nil) = nil then
+ // check for step panel below
+ pan := g_Map_traceToNearest(x, y, x, y+dy, GridTagStep, nil, @ey);
+ inStep := pan <> nil;
+ if inStep then
+ begin
+ // stick to panel edges
+ if ex < pan.X then
+ ex := pan.X
+ else if ex > pan.X + pan.Width - 1 then
+ ex := pan.X + pan.Width - 1;
+ end;
+ end;
checkEnv := (x <> ex);
x := ex;
y := ey;
checkEnv := (x <> ex);
x := ex;
y := ey;
end;
if (pan <> nil) then
begin
end;
if (pan <> nil) then
begin
- // we stuck
- // the only case when we can have both ceiling and wall is corner; stick to wall in this case
- // check if we stuck to a wall
- if (dx < 0) then dx := -1 else dx := 1;
- if (g_Map_PanelAtPoint(x+dx, y, GridTagObstacle) <> nil) then
- begin
- // stuck to a wall
- stickToWall(dx);
- end
+ if inStep then
+ stickToWall(dx)
else
begin
else
begin
- // stuck to a ceiling
- stickToCeiling();
+ // we stuck
+ // the only case when we can have both ceiling and wall is corner; stick to wall in this case
+ // check if we stuck to a wall
+ if (dx < 0) then dx := -1 else dx := 1;
+ if (g_Map_PanelAtPoint(x+dx, y, GridTagSolid) <> nil) then
+ begin
+ // stuck to a wall
+ stickToWall(dx);
+ end
+ else
+ begin
+ // stuck to a ceiling
+ stickToCeiling();
+ end;
end;
end;
end
end;
end;
end
if (y <> floorY) then continue;
end;
// environment didn't changed
if (y <> floorY) then continue;
end;
// environment didn't changed
- hitAFloor();
+ if not inAir then hitAFloor();
break; // done with vertical movement
end;
TFloorType.LiquidIn: // entering the liquid
break; // done with vertical movement
end;
TFloorType.LiquidIn: // entering the liquid
findFloor(true); // force rescan
if (floorType = TFloorType.Wall) and (floorY = y) then
begin
findFloor(true); // force rescan
if (floorType = TFloorType.Wall) and (floorY = y) then
begin
- hitAFloor();
+ if not inAir then hitAFloor();
break; // done with vertical movement
end;
end;
break; // done with vertical movement
end;
end;
begin
if (env = TEnvType.ELiquid) then
begin
begin
if (env = TEnvType.ELiquid) then
begin
- time += 1;
+ if waitTime > 0 then
+ waitTime -= 1
+ else
+ time += 1;
if (liveTime <= 0) then begin die(); exit; end;
ex := 255-trunc(255.0*time/liveTime);
if (ex <= 10) then begin die(); exit; end;
if (liveTime <= 0) then begin die(); exit; end;
ex := 255-trunc(255.0*time/liveTime);
if (ex <= 10) then begin die(); exit; end;
begin
// water will disappear in any liquid
if (env = TEnvType.ELiquid) then begin die(); exit; end;
begin
// water will disappear in any liquid
if (env = TEnvType.ELiquid) then begin die(); exit; end;
- time += 1;
+ if waitTime > 0 then
+ waitTime -= 1
+ else
+ time += 1;
// dry water
if (liveTime <= 0) then begin die(); exit; end;
ex := 255-trunc(255.0*time/liveTime);
// dry water
if (liveTime <= 0) then begin die(); exit; end;
ex := 255-trunc(255.0*time/liveTime);
if (x < g_Map_MinX) or (y < g_Map_MinY) or (x > g_Map_MaxX) or (y > g_Map_MaxY) then continue;
// in what environment we are starting in?
if (x < g_Map_MinX) or (y < g_Map_MinY) or (x > g_Map_MaxX) or (y > g_Map_MaxY) then continue;
// in what environment we are starting in?
- pan := g_Map_PanelAtPoint(x, y, (GridTagObstacle or GridTagLiquid));
+ pan := g_Map_PanelAtPoint(x, y, (GridTagSolid or GridTagLiquid));
if (pan <> nil) then
begin
// either in a wall, or in a liquid
if (pan <> nil) then
begin
// either in a wall, or in a liquid
- if ((pan.tag and GridTagObstacle) <> 0) then continue; // don't spawn in walls
+ if ((pan.tag and GridTagSolid) <> 0) then continue; // don't spawn in walls
env := TEnvType.ELiquid;
end
else
env := TEnvType.ELiquid;
end
else
state := TPartState.Normal;
time := 0;
liveTime := 120+Random(40);
state := TPartState.Normal;
time := 0;
liveTime := 120+Random(40);
+ waitTime := 20;
floorY := Unknown;
ceilingY := Unknown;
end;
floorY := Unknown;
ceilingY := Unknown;
end;
state := TPartState.Normal;
time := 0;
liveTime := 60+Random(60);
state := TPartState.Normal;
time := 0;
liveTime := 60+Random(60);
+ waitTime := 120;
floorY := Unknown;
ceilingY := Unknown;
end;
floorY := Unknown;
ceilingY := Unknown;
end;
if (velY > -4) then velY += accelY;
if (velY > -4) then velY += accelY;
- time += 1;
+ if waitTime > 0 then
+ waitTime -= 1
+ else
+ time += 1;
end;
end;
particleType := TPartType.Bubbles;
time := 0;
liveTime := 65535;
particleType := TPartType.Bubbles;
time := 0;
liveTime := 65535;
+ waitTime := 0;
end;
if (CurrentParticle >= MaxParticles-1) then CurrentParticle := 0 else CurrentParticle += 1;
end;
if (CurrentParticle >= MaxParticles-1) then CurrentParticle := 0 else CurrentParticle += 1;
if (dx <> 0) then
begin
// has some horizontal velocity
if (dx <> 0) then
begin
// has some horizontal velocity
- pan := g_Map_traceToNearest(x, y, x+dx, y+dy, (GridTagObstacle or GridTagLiquid), @ex, @ey);
+ pan := g_Map_traceToNearest(x, y, x+dx, y+dy, (GridTagSolid or GridTagLiquid), @ex, @ey);
if (x <> ex) then begin floorY := Unknown; ceilingY := Unknown; end; // dunno yet
x := ex;
y := ey;
if (x <> ex) then begin floorY := Unknown; ceilingY := Unknown; end; // dunno yet
x := ex;
y := ey;
//writeln('spark1: pos=(', x, ',', y, '); delta=(', velX:6:3, ',', velY:6:3, '); state=', state, '; ceilingY=', ceilingY, '; floorY=', floorY);
//writeln('spark1: pos=(', x, ',', y, '); delta=(', velX:6:3, ',', velY:6:3, '); state=', state, '; ceilingY=', ceilingY, '; floorY=', floorY);
- time += 1;
+ if waitTime > 0 then
+ waitTime -= 1
+ else
+ time += 1;
end;
end;
if (x < g_Map_MinX) or (y < g_Map_MinY) or (x > g_Map_MaxX) or (y > g_Map_MaxY) then continue;
// in what environment we are starting in?
if (x < g_Map_MinX) or (y < g_Map_MinY) or (x > g_Map_MaxX) or (y > g_Map_MaxY) then continue;
// in what environment we are starting in?
- pan := g_Map_PanelAtPoint(x, y, (GridTagObstacle or GridTagLiquid));
+ pan := g_Map_PanelAtPoint(x, y, (GridTagSolid or GridTagLiquid));
if (pan <> nil) then
begin
// either in a wall, or in a liquid
if (pan <> nil) then
begin
// either in a wall, or in a liquid
- //if ((pan.tag and GridTagObstacle) <> 0) then continue; // don't spawn in walls
+ //if ((pan.tag and GridTagSolid) <> 0) then continue; // don't spawn in walls
//env := TEnvType.ELiquid;
continue;
end
//env := TEnvType.ELiquid;
continue;
end
state := TPartState.Normal;
time := 0;
liveTime := 30+Random(60);
state := TPartState.Normal;
time := 0;
liveTime := 30+Random(60);
+ waitTime := 0;
floorY := Unknown;
ceilingY := Unknown;
end;
floorY := Unknown;
ceilingY := Unknown;
end;
if (x < g_Map_MinX) or (y < g_Map_MinY) or (x > g_Map_MaxX) or (y > g_Map_MaxY) then continue;
// in what environment we are starting in?
if (x < g_Map_MinX) or (y < g_Map_MinY) or (x > g_Map_MaxX) or (y > g_Map_MaxY) then continue;
// in what environment we are starting in?
- pan := g_Map_PanelAtPoint(x, y, (GridTagObstacle or GridTagLiquid));
+ pan := g_Map_PanelAtPoint(x, y, (GridTagSolid or GridTagLiquid));
if (pan <> nil) then
begin
// either in a wall, or in a liquid
if (pan <> nil) then
begin
// either in a wall, or in a liquid
- //if ((pan.tag and GridTagObstacle) <> 0) then continue; // don't spawn in walls
+ //if ((pan.tag and GridTagSolid) <> 0) then continue; // don't spawn in walls
//env := TEnvType.ELiquid;
continue;
end
//env := TEnvType.ELiquid;
continue;
end
state := TPartState.Normal;
time := 0;
liveTime := 30+Random(60);
state := TPartState.Normal;
time := 0;
liveTime := 30+Random(60);
+ waitTime := 0;
floorY := Unknown;
ceilingY := Unknown;
end;
floorY := Unknown;
ceilingY := Unknown;
end;
procedure g_GFX_Draw ();
var
a, len: Integer;
procedure g_GFX_Draw ();
var
a, len: Integer;
-{$IFDEF USE_NANOGL}
- type
- Vertex = record
- x, y: GLfloat;
- r, g, b, a: GLfloat;
- end;
- var
- count: Integer;
- v: array of Vertex;
-{$ENDIF}
begin
if not gpart_dbg_enabled then exit;
begin
if not gpart_dbg_enabled then exit;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-{$IFDEF USE_NANOGL}
- count := 0;
- SetLength(v, Length(Particles));
- for a := 0 to High(Particles) do
- begin
- with Particles[a] do
- begin
- if alive and (x >= sX) and (y >= sY) and (x <= sX + sWidth) and (sY <= sY + sHeight) then
- begin
- v[count].x := x + 0.37;
- v[count].y := y + 0.37;
- v[count].r := red / 255;
- v[count].g := green / 255;
- v[count].b := blue / 255;
- v[count].a := alpha / 255;
- Inc(count);
- end;
- end;
- end;
-
- glVertexPointer(2, GL_FLOAT, SizeOf(Vertex), @v[0].x);
- glColorPointer(4, GL_FLOAT, SizeOf(Vertex), @v[0].r);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_POINTS, 0, count);
-{$ELSE}
glBegin(GL_POINTS);
len := High(Particles);
glBegin(GL_POINTS);
len := High(Particles);
end;
glEnd();
end;
glEnd();
-{$ENDIF}
glDisable(GL_BLEND);
end;
glDisable(GL_BLEND);
end;