Sand Pourer, Glue Pourer, Filler: I’ve always found the Glue Pourer the most versatile of these three, since it can act as a Filler and a Platformer, depending on the terrain. If there’s some predictable way in which the Glue could be made to “pile up”, the Sand Pourer’s uses could be implemented in the same skill.
In short: I think there should only be one of these three. But in order to be considered worthy of inclusion, it would probably have to be at least versatile enough to feature aspects of all three of these skills.
---
In the past, we contemplated the idea of the Roper being used as a downward Builder, specifically. Meaning, it should not be able to aim upwards, as it can in L2: The Tribes.
If the latter, then perhaps we can merge these two ideas into one skill: the Pourer's liquid could have an always-diagonally-downwards trajectory, essentially creating a slide/ramp of terrain.
As I’ve outlined in the parallel thread, my exception to this just-invented principle of making a skill more versatile would be the vertical Digger (Twister). Since we already have two diagonally upwards-moving destructive skills.
But a downward Builder is indeed something we’re still sorely lacking ... Of course, there is the Freezer (former Stoner), but they are notorious for creating backroutes, especially when it comes to breaking large falls.
you could send a lemming up (with a Climber / Glider / Shimmier / Jumper, possibly Ballooner / Twister), and then build (=pour) a path downward. We could group these types of levels into the category “Rapunzel levels”. ^^
I see little benefit in changing the existing Laserer to a vertical skill
---
Why are we discussing this in the Pourer thread, though?
The only caveat with both is that turning them into personified skill names doesn’t roll off the tongue as easily (“Ladder-rer”, “Propeller-rer” etc.). But then again, the “Laser-rer” has a similar problem. :evil:
With regards to the sprites, I would prefer the one on the right, where the steps are laid down from the top, rather than “swinging into position” from below.
We’ve moved pretty quickly from “let’s go back from the Hoverboarder to the Runner” to “drop the Runner entirely”, so that nobody had time to respond in between. ;)
So now I guess the frame where the brick swings into position from below refers to the vertical bricks of the ladder, whereas the bricks that swing into place from above are the horizontal bricks? ;)
procedure TLemmingGame.LayLadder(L: TLemming);
var
X, Y: Integer;
begin
case L.LemPhysicsFrame of
9: begin
for X := 1 to 5 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY -1, BrickPixelColors[9]);
end;
11:begin
X := 5;
for Y := 0 to 1 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + Y, BrickPixelColors[9]);
end;
12:begin
for X := 5 to 8 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + 2, BrickPixelColors[9]);
end;
13:begin
X := 8;
for Y := 3 to 4 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + Y, BrickPixelColors[9]);
end;
14:begin
for X := 8 to 11 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + 5, BrickPixelColors[9]);
end;
15:begin
X := 11;
for Y := 6 to 7 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + Y, BrickPixelColors[9]);
end;
16:begin
for X := 11 to 14 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + 8, BrickPixelColors[9]);
end;
17:begin
X := 14;
for Y := 9 to 10 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + Y, BrickPixelColors[9]);
end;
18:begin
for X := 14 to 17 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + 11, BrickPixelColors[9]);
end;
19:begin
X := 17;
for Y := 12 to 13 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + Y, BrickPixelColors[9]);
end;
20:begin
for X := 17 to 20 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + 14, BrickPixelColors[9]);
end;
21:begin
X := 20;
for Y := 15 to 16 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + Y, BrickPixelColors[9]);
end;
22:begin
for X := 20 to 23 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + 17, BrickPixelColors[9]);
end;
23:begin
X := 23;
for Y := 18 to 19 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + Y, BrickPixelColors[9]);
end;
24:begin
for X := 23 to 26 do
AddConstructivePixel(L.LemX + X * L.LemDx, L.LemY + 20, BrickPixelColors[9]);
end;
end;
end;
simplify this procedure by using a formula or algorithm to calculate the X and Y values relative to each LemPhysicsFrame?
2 calls - one for the horizontally-drawn pixels, and one for the vertically-drawn pixels.
for odd frames, do this, and for even frames, do this
While the cloned behaviour does look odd, indeed, it’s precisely how it affects the Stacker, too: If you clone a Stacker mid-performance, only the upper parts of the stack will be built
Ignore frame 9, complete your desired refactrorings for frames >= 11, then see how to marry the old code for frame 9 into the refactored code.
---
One idea: Create two local procedures, one for a vertical brick and one for a horizontal brick. Both will take as input only a starting point. Both will contain the loop and compute the end point for the loop from the passed starting point.
procedure TLemmingGame.LayLadder(L: TLemming);
var
i: Integer;
PosX, PosY: Integer;
FrameOffset: Integer;
const
VerticalBrick: array[0..3, 0..1] of Integer = (
(4, 0),
(4, 1),
(4, 2),
(4, 3));
HorizontalBrick: array[0..3, 0..1] of Integer = (
(1, 0), (2, 0), (3, 0), (4, 0));
begin
PosX := L.LemX + L.LemDX;
PosY := L.LemY;
/// Horizontal bricks
for i := 0 to Length(HorizontalBrick) - 1 do
begin
// First ladder frame need an extra pixel at lem's foot position
if L.LemPhysicsFrame = 10 then
AddConstructivePixel(PosX, PosY, BrickPixelColors[9]);
// Only draw horizontal bricks on the following frames
if L.LemPhysicsFrame in [10, 12, 14, 16, 18, 20, 22, 24] then
begin
case L.LemPhysicsFrame of
10: FrameOffset := 0;
12: FrameOffset := 3;
14: FrameOffset := 6;
16: FrameOffset := 9;
18: FrameOffset := 12;
20: FrameOffset := 15;
22: FrameOffset := 18;
24: FrameOffset := 21;
end;
if L.LemDX > 0 then
AddConstructivePixel((PosX + FrameOffset) + HorizontalBrick[i, 0],
(PosY + FrameOffset) + HorizontalBrick[i, 1], BrickPixelColors[9])
else
AddConstructivePixel((PosX - FrameOffset) - HorizontalBrick[i, 0],
(PosY + FrameOffset) + HorizontalBrick[i, 1], BrickPixelColors[9]);
end;
end;
/// Vertical bricks
for i := 0 to Length(VerticalBrick) - 1 do
begin
// Only draw vertical bricks on the following frames
if L.LemPhysicsFrame in [11, 13, 15, 17, 19, 21, 23] then
begin
case L.LemPhysicsFrame of
11: FrameOffset := 0;
13: FrameOffset := 3;
15: FrameOffset := 6;
17: FrameOffset := 9;
19: FrameOffset := 12;
21: FrameOffset := 15;
23: FrameOffset := 18;
end;
if L.LemDX > 0 then
AddConstructivePixel((PosX + FrameOffset) + VerticalBrick[i, 0],
(PosY + FrameOffset) + VerticalBrick[i, 1], BrickPixelColors[9])
else
AddConstructivePixel((PosX - FrameOffset) - VerticalBrick[i, 0],
(PosY + FrameOffset) + VerticalBrick[i, 1], BrickPixelColors[9]);
end;
end;
end;
Maybe you can produce a pixel more in frames 11, 13, 15, ..., too, and then they'll match the idea behind frame 9.
I think the ladder should start at the same height as the platformer brick.
Could use the L2 orange sack color, like the stacker?
The sound is pretty good. Seems loud. (I would have tried a higher-pitched dominoes-like click)
I'm wondering if you stand at the end of the ladder and begin another ladder if it'll continue as one single long ladder?
I think a purple sack would get lost in the purple button color. Green and blue would get lost in the lemming colors. Teal sounds okay, or a light blue.
I’m sorry for potentially having created additional workload for you, WillLem. ;) However, if there is popular demand for the Ladderer being a 45° slope, then it would be more efficient to change the behaviour now than at some undefined later point in time
With the Ladderer, if the staircase is angular, it should basically never be possible for a lemming to pass through the staircase from the other side
There are also plenty of levels where such slopes are part of the terrain, of course (think of the blue lines in the Crystal tileset). The ladder would then behave the same way
I don't see anything about this that I don't like.
2) Lems can currently ladder through existing ladders, Builder bridges and other thin diagonal platforms. Do we want this? Personally, I think it's desirable, but I can see a case for it not being so:
1) The Ladderer currently stops when the end of the ladder hits terrain; they should also stop when hitting one-way-fields/Blockers. Turning wouldn't work unfortunately (for many reasons), but stopping seems appropriate.
I've noticed something similar with the Laserer, who will not cut through a Builder staircase if assigned on the last pixel before stepping through the staircase. The reason for that is that he actually holds the cannon above the staircase, so it makes sense he can't shoot through it. A similar behaviour can be exploited in NeoLemmix by having a Shimmier jump through a low-hanging Platformer bridge (the Reacher state takes him above the bridge, so that he then lands on top of it).
So I don't think this is a problem either. In fact, it can be useful to connect Builder staircases and ladders in a zig-zag pattern. :thumbsup:
However, what happens when you assign a Blocker in front of a Ladderer to turn the lemming himself around mid-performance? Here I'd expect the same behaviour as when turning a Laserer with a Blocker mid-shooting ... Meaning, the Ladderer would create the lower part of the ladder in the opposite direction - similar to what happens when you clone a Ladderer.
Also, I just want to say I like the skill panel icon![/b] :thumbsup: It's just a little strange to me that the downward staircase in the icon looks like a Builder staircase, i.e., more "step-like", and at a flatter angle. I assume this might just be a preliminary version of the icon, and the final version will have the actual angle the skill uses?
procedure TLemmingGame.LayLadder(L: TLemming);
var
i: Integer;
PosX, PosY: Integer;
FrameOffset: Integer;
const
LadderBrick: array[0..8, 0..1] of Integer = (
(0, 0), (1, 0), (2, 0),
(1, 1), (2, 1), (3, 1),
(2, 2), (3, 2),(4, 2)
);
begin
PosX := L.LemX + L.LemDX;
PosY := L.LemY;
for i := 0 to Length(LadderBrick) - 1 do
begin
if L.LemPhysicsFrame in [10, 12, 14, 16, 18, 20, 22, 24] then
begin
case L.LemPhysicsFrame of
10: FrameOffset := 0;
12: FrameOffset := 3;
14: FrameOffset := 6;
16: FrameOffset := 9;
18: FrameOffset := 12;
20: FrameOffset := 15;
22: FrameOffset := 18;
24: FrameOffset := 21;
else Exit;
end;
if L.LemDX > 0 then
AddConstructivePixel((PosX + FrameOffset) + LadderBrick[i, 0],
(PosY + FrameOffset) + LadderBrick[i, 1], BrickPixelColors[FrameOffset div 2])
else
AddConstructivePixel((PosX - FrameOffset) - LadderBrick[i, 0],
(PosY + FrameOffset) + LadderBrick[i, 1], BrickPixelColors[FrameOffset div 2]);
end;
end;
end;