X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_gfx.pas;h=e49a72cdaf286758c9a048d96a40b7e26259f3bd;hb=15ef0fb2d44e381afb8d0ea07cdb31fd3903ba7b;hp=d3cc071ad5f4a0a4c1598884ad276bb2176ac699;hpb=6927c30da0ee60acd089fdbed9b1de52692060de;p=d2df-sdl.git diff --git a/src/game/g_gfx.pas b/src/game/g_gfx.pas index d3cc071..e49a72c 100644 --- a/src/game/g_gfx.pas +++ b/src/game/g_gfx.pas @@ -121,6 +121,8 @@ type procedure freeze (); inline; // remove velocities and acceleration procedure sleep (); inline; // switch to sleep mode + function checkAirStreams (): Boolean; // `true`: affected by air stream + function alive (): Boolean; inline; procedure die (); inline; procedure think (); inline; @@ -228,11 +230,50 @@ begin end; +// `true`: affected by air stream +function TParticle.checkAirStreams (): Boolean; +var + pan: TPanel; +begin + pan := g_Map_PanelAtPoint(x, y, GridTagLift); + result := (pan <> nil); + 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; + end; + // awake + if result and (state = TPartState.Sleeping) then state := TPartState.Normal; + end; +end; + + // switch to sleep mode procedure TParticle.sleep (); inline; begin - state := TPartState.Sleeping; - freeze(); + if not checkAirStreams() then + begin + state := TPartState.Sleeping; + freeze(); + end; end; @@ -383,41 +424,6 @@ procedure TParticle.thinkerBloodAndWater (); if result then begin velY := 0.5; accelY := 0.15; end; end; - // `true`: affected by air stream - function checkAirStreams (): Boolean; - var - pan: TPanel; - begin - pan := g_Map_PanelAtPoint(x, y, GridTagLift); - result := (pan <> nil); - 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; - end; - // awake - if result and (state = TPartState.Sleeping) then state := TPartState.Normal; - end; - end; - // switch to freefall mode procedure freefall (); begin @@ -447,13 +453,14 @@ var pan: TPanel; dX, dY: SmallInt; ex, ey: Integer; + checkEnv: Boolean; begin if not gpart_dbg_phys_enabled then goto _done; if gAdvBlood then begin - // still check for air streams when sleeping - if (state = TPartState.Sleeping) then begin checkAirStreams(); goto _done; end; // so blood will dissolve + // still check for air streams when sleeping (no) + if (state = TPartState.Sleeping) then begin {checkAirStreams();} goto _done; end; // so blood will dissolve // process stuck particles if (state = TPartState.Stuck) then @@ -524,6 +531,8 @@ begin dX := round(velX); dY := round(velY); + if (state = TPartState.Normal) then checkAirStreams(); + // gravity, if not stuck if (state <> TPartState.Stuck) and (abs(velX) < 0.1) and (abs(velY) < 0.1) then begin @@ -562,15 +571,21 @@ begin begin // has some horizontal velocity pan := g_Map_traceToNearest(x, y, x+dX, y+dY, GridTagObstacle, @ex, @ey); - if (x <> ex) then begin floorY := Unknown; ceilingY := Unknown; end; // dunno yet + checkEnv := (x <> ex); x := ex; y := ey; + if checkEnv then + begin + // dunno yet + floorY := Unknown; + ceilingY := Unknown; + // check environment (air/liquid) + if (g_Map_PanelAtPoint(x, y, GridTagLiquid) <> nil) then env := TEnvType.ELiquid else env := TEnvType.EAir; + 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 environment (air/liquid) - if (g_Map_PanelAtPoint(x, y, GridTagLiquid) <> nil) then env := TEnvType.ELiquid else env := TEnvType.EAir; // 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 @@ -602,6 +617,7 @@ begin begin // falling down if (floorY = Unknown) then findFloor(); // need to do this anyway + if (floorType = TFloorType.LiquidOut) then env := TEnvType.ELiquid else env := TEnvType.EAir; y += dY; //e_LogWritefln('floorY=%s; newy=%s; dY=%s; floorType=%s', [floorY, y, dY, floorType]); if (y >= floorY) then @@ -670,16 +686,22 @@ _done: time += 1; if (liveTime <= 0) then begin die(); exit; end; ex := 255-trunc(255.0*time/liveTime); - if (ex >= 250) then begin die(); exit; end; - if (ex < 0) then ex := 0; + if (ex <= 10) then begin die(); exit; end; + if (ex > 250) then ex := 255; alpha := Byte(ex); end; end else begin - // water will disappear in water (?) - if (env = TEnvType.ELiquid) then die(); + // water will disappear in any liquid + if (env = TEnvType.ELiquid) then begin die(); exit; end; time += 1; + // dry water + if (liveTime <= 0) then begin die(); exit; end; + ex := 255-trunc(255.0*time/liveTime); + if (ex <= 10) then begin die(); exit; end; + if (ex > 250) then ex := 255; + alpha := Byte(ex); end; end; @@ -835,19 +857,19 @@ begin // check for level bounds 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)); - if (pan <> nil) then + // this hack will allow water spawned in water to fly out + // it can happen when player fell from a huge height (see "DOOM2D.WAD:\MAP03", for example) + if (fVelY >= 0) then begin - // either in a wall, or in a liquid - //if ((pan.tag and GridTagObstacle) <> 0) then continue; // don't spawn in walls - //env := TEnvType.ELiquid; - continue; + // in what environment we are starting in? + pan := g_Map_PanelAtPoint(x, y, (GridTagObstacle or GridTagLiquid)); end else begin - env := TEnvType.EAir; + pan := g_Map_PanelAtPoint(x, y, GridTagObstacle); end; + if (pan <> nil) then continue; + env := TEnvType.EAir; // color case color of @@ -1045,12 +1067,13 @@ begin if (dX <> 0) then begin // has some horizontal velocity - pan := g_Map_traceToNearest(x, y, x+dX, y+dY, GridTagObstacle, @ex, @ey); + pan := g_Map_traceToNearest(x, y, x+dX, y+dY, (GridTagObstacle or GridTagLiquid), @ex, @ey); if (x <> ex) then begin floorY := Unknown; ceilingY := Unknown; end; // dunno yet x := ex; y := ey; if (pan <> nil) then begin + if ((pan.tag and GridTagLiquid) <> 0) then begin die(); exit; end; // die in liquid // hit the wall; falling down vertically velX := 0; accelX := 0; @@ -1466,7 +1489,7 @@ begin if alive and (x >= sX) and (y >= sY) and (x <= sX+sWidth) and (sY <= sY+sHeight) then begin glColor4ub(red, green, blue, alpha); - glVertex2i(x, y); + glVertex2f(x+0.37, y+0.37); end; end; end;