The platformer is also prevented from platforming if his first brick would cause him to turn around, even if it would place terrain. For obvious reasons, doing this with the builder would break a lot of levels. Removing such a thing with the platformer is perhaps more viable; it would improve consistency with far less breakage, but still wouldn't really fix the issue at hand.
It's mostly LemCanPlatform and AssignPlatformer that are relevant here, but I've pasted HandlePlatforming too just in case it helps.
function TLemmingGame.HandlePlatforming(L: TLemming): Boolean;
begin
Result := False;
with L do
begin
// sound
if (LemFrame = 10) and (LemNumberOfBricksLeft <= 3) then
CueSoundEffect(SFX_BUILDER_WARNING);
// lay brick
if (LemFrame = 9) then
begin
LemCouldPlatform := LemCanPlatform(L);
if not CheckGimmick(GIM_UNALTERABLE) then
LayBrick(L, 1);
if CheckGimmick(GIM_HARDWORK) then
LemNumberOfBricksLeft := 11;
if (CheckGimmick(GIM_LAZY)) and (LemNumberOfBricksLeft > 4) then
LemNumberOfBricksLeft := 4;
Exit;
end
else if (LemFrame = 15) and not (LemCouldPlatform) then
begin
Transition(L, baWalking, TRUE);
if (CheckGimmick(GIM_UNALTERABLE)) then Transition(L, baShrugging);
if CheckGimmick(GIM_BACKWARDS) and HasPixelAt(LemX, LemY-1) and not HasPixelAt(LemX + LemDx, LemY - 1) then
Inc(LemX, LemDx);
CheckForLevelTopBoundary(L);
Result := True;
Exit;
end
else if (LemFrame = 0) or (LemFrame = 15) then
begin
Inc(LemX, LemDx);
if (((HasPixelAt_ClipY(LemX+LemDx, LemY - 1, -1) = TRUE)
or (HasPixelAt_ClipY(LemX+LemDx, LemY - 2, -1) = TRUE))
and ((LemNumberOfBricksLeft > 1) or (LemFrame = 15))) then
begin
Transition(L, baWalking, TRUE); // turn around as well
if (CheckGimmick(GIM_UNALTERABLE)) then Transition(L, baShrugging);
if CheckGimmick(GIM_BACKWARDS) and HasPixelAt(LemX, LemY-1) and not HasPixelAt(LemX + LemDx, LemY - 1) then
Inc(LemX, LemDx);
CheckForLevelTopBoundary(L);
Result := True;
Exit;
end;
if LemFrame = 0 then
begin
Inc(LemX, LemDx);
if (((HasPixelAt_ClipY(LemX+LemDx, LemY - 1, -1) = TRUE)
or (HasPixelAt_ClipY(LemX+LemDx, LemY - 2, -1) = TRUE))) then
begin
if (LemNumberOfBricksLeft > 1) then
begin
Transition(L, baWalking, TRUE); // turn around as well
if (CheckGimmick(GIM_UNALTERABLE)) then Transition(L, baShrugging);
if CheckGimmick(GIM_BACKWARDS) and HasPixelAt(LemX, LemY-1) and not HasPixelAt(LemX + LemDx, LemY - 1) then
Inc(LemX, LemDx);
CheckForLevelTopBoundary(L);
Result := True;
Exit;
end else if HasPixelAt_ClipY(LemX, LemY - 1, -1) then
Dec(LemX, LemDx);
end;
Dec(LemNumberOfBricksLeft);
if (LemNumberOfBricksLeft = 0) then
begin
Transition(L, baShrugging);
CheckForLevelTopBoundary(L);
Result := True;
Exit;
end;
end;
Result := True;
Exit;
end
else begin
Result := True;
Exit;
end;
end; // with L
end;
function TLemmingGame.LemCanPlatform(L: TLemming): Boolean;
var
x, x2: Integer;
c2: Boolean;
begin
with L do
begin
x := LemX;
if LemDX < 0 then Dec(x, 5);
Result := false;
c2 := true;
for x2 := x to x+5 do
if not HasPixelAt(x2, LemY) then
begin
if x2 < 3 then c2 := false;
Result := true;
end;
if LemDX < 0 then Inc(x, 2);
if c2 and Result then
for x2 := x+1 to x+2 do
if HasPixelAt(x2, LemY-1) then
Result := false;
end;
end;
function TLemmingGame.AssignPlatformer(Lemming1, Lemming2: TLemming): Boolean;
const
ActionSet = [baWalking, baShrugging, baBuilding, baStacking, baBashing, baMining, baDigging];
begin
Result := False;
if not CheckSkillAvailable(baPlatforming) then
Exit;
if (Lemming1.LemAction in ActionSet) and LemCanPlatform(Lemming1) then
begin
if (fCheckWhichLemmingOnly) then
WhichLemming := Lemming1
else
begin
Transition(Lemming1, baPlatforming);
UpdateSkillCount(baPlatforming);
Result := True;
RecordSkillAssignment(Lemming1, baPlatforming);
if not fFreezeSkillCount then
begin
OnAssignSkill(Lemming1, baPlatforming);
GameResultRec.gScore := GameResultRec.gScore - SCS_PLATFORMER;
end;
end;
end
else if (Lemming2 <> nil) and (Lemming2.LemAction in ActionSet) and LemCanPlatform(Lemming2) then
begin
if (fCheckWhichLemmingOnly) then
WhichLemming := Lemming2
else
begin
Transition(Lemming2, baPlatforming);
UpdateSkillCount(baPlatforming);
Result := True;
RecordSkillAssignment(Lemming2, baPlatforming);
if not fFreezeSkillCount then
begin
OnAssignSkill(Lemming2, baPlatforming);
GameResultRec.gScore := GameResultRec.gScore - SCS_PLATFORMER;
end;
end;
end;
end;
One possible solution is simply to disallow both if there's a pixel at (LemX, LemY-1). Generally, in any state where this would be true, it would already be impossible to assign these skills anyway (as the lemming would generally be either climbing or jumping at such a time). The only exceptions are (a) the situation demonstrated in Glitchy Spikes, and (b) if a constructive skill had, in the frame immediately prior, placed a pixel at that location - most likely to happen with a stoner, but could theoretically happen with any of them.