Stygia: End of Day 3

Slow-going today (see my updates here), but here’s a pretty screenshot to keep your interest up, showing an independent lightsource, other than the @’s torch:

Tomorrow I hope to finish items/inventory handling*, and start work on creatures that you can kill and take their stuff!

*I’ve previously developed an algorithm (on paper) that can give each item a reasonably intelligible but randomly-generated fluff description such as:

This ruby-encrusted spear was formerly the prized weapon of JoeBloggs the Hero of Xyzzy. He used it mainly in the war 600 years ago against the Goblins of Zzyyyzzzy. He fell in battle against Bob the Goblin Chief and the weapon was subsequently lost. What it was doing in the hands of a common goblin you have no idea.

Hopefully I’ll get it coded and setup as part of the 7DRL!

 

Day 3 in the Oubliette

Very slow day today, not much done, movement is working right but some walls don’t show up where they should and are still not shaded (see screenshot.) I need to get this working quickly tomorrow so that I can add the fun game stuff and improve the dungeon generation. I have added a 2D view on top of the 3D view to verify the correctness of the display; this might come back at some point in the game: for instance, a potion could give an overview of the world, or something like that.

And I have a title and a theme: you are thrown into the Oubliette. And you need to get out.

EDIT: Also, note that the keys in the corner are buttons that you press on the ipad; I’m still not quite sure how to deal with key bindings for movement. The left/right arrows are for turning, but I may want to keep the Dungeon Master moveset.

Pitman – third day, still alive

So, not only the @ is walking, but also some of the monsters! And they are attacking, too! Jana worked on some decoration objects the last day which will make the dungeons more interesting.

Of course, the whole game logic is still missing – use of the skills, leveling, inventory/items, magic, etc. Hopefully the last three days will be productive! (Yes, only three, because RealLife shows its ugly head on friday, when we attend a weekly training course for startups.)

You can test the current state on Dropbox. It only features two enemies and nothing more, but you can also extent the dungeon if you place the main character at the border of a card.

Legend of the Cheese Golem, day 4

Progress could be a lot better but I’ve done a lot considering how long I’ve had to spend on it. Real life and all that.

All the basic code for walking around/blocking/fov etc. is there. The client/server stuff for c# at the back and javascript at the front is there but slightly broken at the moment so working with the standard console version.

World is generating, saving/loading etc. Not so much to do now there.

Forest is generated using perlin noise:

Which gives me a map vaguely like this (only forest, mountains and a path so far):

A slightly older screenshot which includes rivers:

Anyway, I’m behind my plan but I’m still moderately confident of finishing, albeit without the level of polish I’d like 🙂

 

Vicious Orcs, Day 4

Day 4 complete. I’ve written all the text for the people and items now populating the world. As usual, data entry is the hard part of roguelike design. Just discovered the Yetis were doing 10d4 damage rather than 1d4+10 due to a bug in my dice parser!

I’m quite happy with the look – things will likely not change much for the release. Just have to keep filing off those edges and tweaking the difficulty.

Biggest TODO? Throwing potions.

FOV Errors holding me down

Today I worked on implementing FOV using the recursive shadowcasting improved as described at Roguebasin. It even had a link to a C# implementation. I have it working but there is an error in Octant 7, maybe 6 as well. I have all the code for it posted in a post Here

The red should be lit just like the green is.

 

protected bool In_Range(int x1, int y1, int x2, int y2, int Range)
{
try
{
char i = map.tile[y1, x1].Symbol;
i = map.tile[y2, x2].Symbol;
if (x1 == x2) { return Math.Abs(y1 – y2) <= Range; }
if (y1 == y2) { return Math.Abs(x1 – x2) <= Range; }
return (Math.Pow((x1 – x2), 2) + Math.Pow((y1 – y2), 2)) <= Math.Pow(Range, 2);
}
catch
{
return false;
}
}
private double Get_Slope(double x1, double y1, double x2, double y2)
{
return (x1 – x2) / (y1 – y2);
}
private double Get_SlopeInv(double x1, double y1, double x2, double y2)
{
return (y1 – y2) / (x1 – x2);
}
protected void Set_Visible(int Depth, int Octant, double StartSlope, double EndSlope)
{
int x = 0;
int y = 0;
switch (Octant)
{
case 1:
y = player.Location.Y – Depth;
x = player.Location.X – Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x – 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x – 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x – 1].Seethrough)
{
StartSlope = Get_Slope(x – 0.5, y – 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x++;
}
x–;
break;
case 2:
y = player.Location.Y – Depth;
x = player.Location.X + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x + 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x + 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x + 1].Seethrough)
{
StartSlope = -Get_Slope(x + 0.5, y – 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x–;
}
x++;
break;
case 3:
x = player.Location.X + Depth;
y = player.Location.Y – Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y – 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x – 0.5, y – 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y – 1, x].Seethrough)
{
StartSlope = -Get_SlopeInv(x + 0.5, y – 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y++;
}
y–;
break;
case 4:
x = player.Location.X + Depth;
y = player.Location.Y + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y + 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_SlopeInv(x – 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y + 1, x].Seethrough)
{
StartSlope = Get_SlopeInv(x + 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y–;
}
y++;
break;
case 5:
y = player.Location.Y + Depth;
x = player.Location.X + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x + 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x + 0.5, y – 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x + 1].Seethrough)
{
StartSlope = Get_Slope(x + 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x–;
}
x++;
break;
case 6:
y = player.Location.Y + Depth;
x = player.Location.X – Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x – 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x – 0.5, y – 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x – 1].Seethrough)
{
StartSlope = -Get_Slope(x – 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x++;
}
x–;
break;
case 7:
x = player.Location.X – Depth;
y = player.Location.Y + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y + 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_SlopeInv(x + 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y + 1, x].Seethrough)
{
StartSlope = Get_SlopeInv(x – 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y–;
}
y++;
break;
case 8:
x = player.Location.X – Depth;
y = player.Location.Y – Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y – 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_SlopeInv(x + 0.5, y – 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y – 1, x].Seethrough)
{
StartSlope = Get_SlopeInv(x – 0.5, y – 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y++;
}
y–;
break;
}
if (x < 0) x = 0;
if (x >= map.Width) x = map.Width – 1;
if (y < 0) y = 0;
if (y >= map.Height) y = map.Height – 1;
if[1] && (map.tile[y, x].Seethrough))
{
Set_Visible(Depth + 1, Octant, StartSlope, EndSlope);
}
}
public void Calculate_Sight()
{
for (int y = 0; y < map.Height; y++)
{
for (int x = 0; x < map.Width; x++)
{
map.tile[y, x].Visible = false;
}
}
for (int Octant = 1; Octant < 9; Octant++)
{
Set_Visible(1, Octant, 1.0, 0.0);
}
}
  1. In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range []