Skip to content

Implemented/Fixed Mine Door rotation - #58

Open
KSunyo wants to merge 18 commits into
Warlander:masterfrom
KSunyo:master
Open

Implemented/Fixed Mine Door rotation#58
KSunyo wants to merge 18 commits into
Warlander:masterfrom
KSunyo:master

Conversation

@KSunyo

@KSunyo KSunyo commented Jan 25, 2026

Copy link
Copy Markdown
Collaborator
  • Created a new enum called DoorDirection
  • Added a new property to GroundData.cs called IsCaveDoor as the main condition for rotation related methods
    • I check if ShortName matches any predefined String.
  • Added DoorDirection public property in Ground.cs, which is by default DoorDirection.N, and added it to the ground constructor and to other methods as parameter.
  • Added doorDirectionsArray in GroundMesh.cs.
  • Added UpdateDoorDirection method being responsible of calculating the relevant orientation and RefreshDoorOrientation method which is called in the Refresh method.
  • Added ApplyUvRotation method in GroundMesh.cs, that when a rotation is applicable manipulates the meshUVs.
  • Extended SetGroundData in GroundMesh.cs.

This PR is related to issue #7 .

Issue Warlander/DeedPlanner3 Warlander#7
@KSunyo KSunyo linked an issue Jan 25, 2026 that may be closed by this pull request
@KSunyo KSunyo added bug Something isn't working enhancement New feature or request labels Jan 25, 2026

@Warlander Warlander left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think door direction rotation should be happening on graphics level only, without Ground model needing to be aware of it as we only really need it for rendering - and it shouldn't be a performance issue given we only need this info if something is changing with the ground.

ground.data = newData;
ground.Tile.Map.Ground.SetGroundData(ground.Tile.X, ground.Tile.Y, ground.data, ground.RoadDirection);
ground.DoorDirection = ground.Tile.UpdateDoorDirection();
ground.Tile.Map.Ground.SetGroundData(ground.Tile.X, ground.Tile.Y, ground.data, ground.RoadDirection, ground.DoorDirection);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to serialize it?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not serialized anymore

@KSunyo
KSunyo requested a review from Warlander January 27, 2026 04:09
Tex2d = tex2d;
Tex3d = tex3d;
Diagonal = diagonal;
IsCaveDoor = ShortName is "wcaDoor" or "gcaDoor" or "scaDoor" or "mcaDoor";

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would lean more towards optional XML tag here, similar to how openings and diagonal-enabled ground types are defined.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As cave doors are the only ground types that can rotate, I used the "Cave door" category name to set it to true

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the category name is a better way to check this as it is already documented in objects.xml whether it is a cave door or not, and this way we require no extra tag.

// Cave.Initialize(this, Database.DefaultCaveData);
}

public DoorDirection UpdateDoorDirection()

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update would indicate something within the tile changes but it's not the case, the door direction seems to be calculated here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed it to CalculateDoorOrientation

// Rotating vectors based on DoorDirection
if (dir == DoorDirection.E)
{
(v00, v10, v11, v01) = (v10, v11, v01, v00);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's interesting syntax, honestly it makes lots of sense here! 👀

DoorDirection doorDir = doorDirectionsArray[x, y];
Vector2Int selfCoords = new Vector2Int(x, y);

int westSlot = vertexIndex;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think syntax where these values are only initialized once would be easier to read here.

@KSunyo KSunyo Jan 27, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the newest commit I changed it a bit:

var (wOffset, nOffset, eOffset, sOffset) = (data.IsCaveDoor ? doorOrientation : DoorOrientation.N) switch
{
DoorOrientation.E => (9, 0, 3, 6),
DoorOrientation.S => (6, 9, 0, 3),
DoorOrientation.W => (3, 6, 9, 0),
_ => (0, 3, 6, 9),
};
int westSlot = vertexIndex + wOffset;
int northSlot = vertexIndex + nOffset;
int eastSlot = vertexIndex + eOffset;
int southSlot = vertexIndex + sOffset;

private int[,] slopesArray;
private GroundData[,] dataArray;
private RoadDirection[,] directionsArray;
private DoorDirection[,] doorDirectionsArray;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a sanity check, is it guaranteed to be correct initially? All door directions will be set to N by default.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For cave doors it is guaranteed to be incorrect almost always initially. But then it should almost immediately correct itself as of the current version.

private bool needsUvUpdate = false;

public void Initialize(int width, int height, OverlayMesh newOverlayMesh)
public void Initialize(Map map, int width, int height, OverlayMesh newOverlayMesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of map knowing about GroundMesh and GroundMesh about the map, but this entire part of code needs later refactor anyway so I'm ok with it for now.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be a problem now, groundMesh just gets the orientation, doesn't initiate calculating it.

Ground.cs:
New CalculateOrientationFor method using Tile.CalculateDoorOrientation, method is being used in setting orientation into ground data. Also added old/new state switches to execute, undo

GroundMesh.cs
Pretty much same as was before, I just had to re-add it after merge conflict overwrite. Except GroundMesh now doesn't know about map.cs

TIle.cs
Calculate orientation inside refreshorientation method now, rather than calculating it at groundMesh, so now when it is called in ground this both calculates it and sets it into groundData.
@KSunyo KSunyo self-assigned this Aug 28, 2026
@KSunyo
KSunyo requested a review from Warlander August 28, 2026 21:00
break;
case "category":
categories.Add(child.InnerText.Split('/'));
caveDoor = (child.InnerText == "Cave doors") ? true : false;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Project convention is to use XML tags for this kind of data - check "diagonal" for example. :)

meshUvs[vertexIndex + 10] = v00;
meshUvs[vertexIndex + 11] = vCenter;

RenderMesh.uv = meshUvs;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an expensive call, but we already have needsUvUpdate flag to make sure it gets triggered once per frame at most

tile.Map.GetRelativeTile(tile, -1, 0)?.RefreshSurfaceEntities();
tile.Map.GetRelativeTile(tile, 0, -1)?.RefreshSurfaceEntities();
tile.Map.GetRelativeTile(tile, -1, -1)?.RefreshSurfaceEntities();
t10?.RefreshSurfaceEntities();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something about this change that requires refreshing surface entities on nearby tiles?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is actually not changed just added the Tile variables. Before the PR it looked like this:
tile.RefreshSurfaceEntities(); tile.Map.GetRelativeTile(tile, -1, 0)?.RefreshSurfaceEntities(); tile.Map.GetRelativeTile(tile, 0, -1)?.RefreshSurfaceEntities(); tile.Map.GetRelativeTile(tile, -1, -1)?.RefreshSurfaceEntities();

I would assume this is to set walls and fences properly on neighboring tiles when the slope changes.

{
ground.data = oldData;
ground.Tile.Map.Ground.SetGroundData(ground.Tile.X, ground.Tile.Y, ground.data, ground.RoadDirection);
DoorOrientation orientation = CalculateOrientationFor(ground, newData);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we pass new data in undo? May be worth testing if that's the correct behavior

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this, this should definitely be oldData 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mine Doors flipped and flipped.

2 participants