stwe / MDCII

An unofficial project making from scratch to create an editable Anno 1602 world.
GNU General Public License v2.0
7 stars 2 forks source link

Bug: strange positioning behavior #20

Closed siredmar closed 8 months ago

siredmar commented 1 year ago

Hi!

I just checked your latest commit (aa3dc6c) and seen something strange in positioning. See for yourself: Bild bug-2022-11-21_07.34.72d8w.gif auf abload.de

stwe commented 1 year ago

The behavior is the expected behavior based on the current implementation - so no bug. However, I have to admit that it could be better and is not optimal. Maybe it's not comfortable. Let me explain how this is implemented.

In the example map in rotation DEG0 we have the following initial situation:


c = coast
b = bakery
f = fishing hut

     0   1   2   3   4   5   6   7
   ---------------------------------
0  | c | c | c | c | c | c | c | c |
   ---------------------------------
1  | c |   |   |   |   |   |   | c |
   ---------------------------------
2  | c |   |   |   |   | b | b | c |
   ---------------------------------
3  | c |   |   |   |   | b | b | c |
   ---------------------------------
4  | c |   |   |   |   |   |   | c |
   ---------------------------------
5  | c |   |   |   |   |   |   | c |
   ---------------------------------
6  | c |   |   |   |   |   |   | c |
   ---------------------------------
7  | c |   |   |   |   |   |   | c |
   ---------------------------------
8  | c |   |   |   |   |   |   | c |
   ---------------------------------
9  | c |   |   |   |   |   |   | c |
   ---------------------------------
10 | c |   |   |   |   |   |   | c |
   ---------------------------------
11 | c | f | c | c | c | c | c | c |
   ---------------------------------

Now, if we want to put a 2x2 sized building (for example) on the map, we have to keep in mind:

There are, of course, buildings that have other peculiarities. But that's not the topic for now.

A 2x2 building has its own coordinate system xy in the range 0 to 1. In the example above it looks like this:

     0            1         2         3         4         5        6         7
   --------------------------------------------------------------------------------
0  |    c    |    c    |    c    |    c    |    c    |    c   |    c    |    c    |
   --------------------------------------------------------------------------------
1  |    c    |         |         |         |         |        |         |    c    |
   --------------------------------------------------------------------------------
2  |    c    |         |         |         |         | (0, 0) | (1, 0)  |    c    |
   --------------------------------------------------------------------------------
3  |    c    |         |         |         |         | (0, 1) | (1, 1)  |    c    |
   --------------------------------------------------------------------------------
4  |    c    |         |         |         |         |        |         |    c    |
   --------------------------------------------------------------------------------

// ...

Bakery: World Space (5, 2) - Object Space (0, 0) World Space (6, 2) - Object Space (1, 0) World Space (5, 3) - Object Space (0, 1) World Space (6, 3) - Object Space (1, 1)

If you now click anywhere in the world with the mouse, this is the starting position for checking whether the building can be built. For this, each position of the object space is added to the starting position of the world.

https://github.com/stwe/MDCII/blob/main/src/world/World.cpp#L714 https://github.com/stwe/MDCII/blob/main/src/world/World.cpp#L736 https://github.com/stwe/MDCII/blob/main/src/world/World.cpp#L419

for (auto y{ 0 }; y < t_building.size.h; ++y)
{
    for (auto x{ 0 }; x < t_building.size.w; ++x)
    {
        auto rp{ world::rotate_position(x, y, t_building.size.h, t_building.size.w, t_buildingRotation) };
        if (t_buildingRotation == world::Rotation::DEG0 || t_buildingRotation == world::Rotation::DEG180)
        {
            rp = world::rotate_position(x, y, t_building.size.w, t_building.size.h, t_buildingRotation);
        }

        if (!IsPositionInWorld(t_x + rp.x, t_y + rp.y))
        {
            return true;
        }
    }
}

The strange behavior mentioned here can result from the fact that the object space is always iterated at (0, 0) -> (1,1). If the building cannot be built like this, we should perhaps iterate through the loop differently. If that doesn't work either, return false.

Back to the example above. In the following map all positions are marked with an "x", from which no 2x2 building can be built.

     0   1   2   3   4   5   6   7
   ---------------------------------
0  | x | x | x | x | x | x | x | x |
   ---------------------------------
1  | x |   |   |   | x | x | x | x |
   ---------------------------------
2  | x |   |   |   | x | x | x | x |
   ---------------------------------
3  | x |   |   |   | x | x | x | x |
   ---------------------------------
4  | x |   |   |   |   |   | x | x |
   ---------------------------------
5  | x |   |   |   |   |   | x | x |
   ---------------------------------
6  | x |   |   |   |   |   | x | x |
   ---------------------------------
7  | x |   |   |   |   |   | x | x |
   ---------------------------------
8  | x |   |   |   |   |   | x | x |
   ---------------------------------
9  | x |   |   |   |   |   | x | x |
   ---------------------------------
10 | x | x | x | x | x | x | x | x |
   ---------------------------------
11 | x | x | x | x | x | x | x | x |
   ---------------------------------

E.g. it would be correct to be able to build a building by clicking on (4, 1), (4, 2) or (4, 3).

siredmar commented 1 year ago

I don't know if this is a new issue or just shows the same symptoms: The cursor has different offsets for different buildings when placing them. image Also i noticed, that placing the fisher hut and the warehouse coast cannot be placed on the shore. I guess this is simply not implemented yet.

stwe commented 8 months ago

see 5052856