Skip to content

Commit b9b39bb

Browse files
fboucherCopilot
andauthored
v0.2.1 - Refactors and improves game functionality (#145)
* Adds room editing dialog Adds a dialog to edit room properties, specifically the position of doors. This allows users to adjust room layouts and door placements after a room has been created. * Enables door repositioning in room editor Implements functionality to move door positions within the room editor dialog. This allows users to fine-tune door placement within a room, enhancing the level design process. It dynamically shows the correct axes of movement by looking at door direction and only displaying the perpendicular movement axes. * Enables moving exits in room editor Allows adjusting the position of exits on walls within the room editor. This change introduces functionality to dynamically update exit positions, providing a more intuitive and interactive editing experience. The "Modal" property of the dialog was set to false to allow background interaction. * Improves door placement in room editor Replaces directional buttons with a slider for precise door positioning on walls. This change allows users to visually adjust the door's location within the room editor dialog, enhancing the user experience. * add id on div to identify map context menu * Improves map menu placement. Makes the map menu stick to the top of the screen to prevent it from scrolling off-screen during gameplay. * Initial plan * Implement maps-menu enable/disable based on nextRoom draft state Co-authored-by: FBoucher <2404846+FBoucher@users.noreply.github.com> * When dialogue cancelled nextroom should be set to null * Disables room buttons when no room exists Disables the "Add Room" and "Edit Room" buttons when there isn't a room to add or edit. This prevents the user from interacting with those features when they are not available and improves the user experience. * Corrects door placement on the map Adjusts the positioning of doors on the map to ensure they are placed outside the adjacent room's boundary. Simplifies door drawing logic, ensuring doors are consistently drawn as full squares. * Fixes typo in new room dialog Corrects a typo in the new room dialog where "gameTurn" should be "get". This improves the readability of the generated room description for the user. * Corrects door placement on the map Adjusts the door coordinate calculation to ensure doors are placed correctly relative to rooms. The canvas drawing logic was also reviewed, and unnecessary offset code for vertical doors was removed. * Updates save game count to use adventure previews fixes #119 Changes the implementation of GetSaveGameCount to utilize the GetAdventurePreviews method, providing a more accurate count of saved games. Adds .gitignore file for Rider IDE to ignore IDE specific files. * Adds adventure deletion functionality Implements the ability to delete saved adventures. This change introduces a delete endpoint in the service and a corresponding button in the adventure picker component. When a user clicks the delete button, the selected adventure is removed and the adventure list is refreshed. * Fixes adventure deletion event handling Stops event propagation on the adventure deletion button to prevent unintended row selection when deleting an adventure. Also, adds project-level IDE configuration files. * Refactors adventure preview loading Improves the adventure picker component by extracting the adventure preview loading logic into a separate method. This change enhances code readability and maintainability. Also, this fixes a potential UI update issue by explicitly calling StateHasChanged after loading previews when deleting an adventure. * Adds adventurer deletion functionality Enables the deletion of adventurers, ensuring that an adventurer can only be deleted if it is not currently associated with any existing adventures. This prevents data integrity issues and provides a safeguard against accidentally deleting adventurers that are actively used in a game. * Add "Start a new fight" button to reset combat screen - fixes #116 (#124) * Initial analysis of issue #116 - combat screen reset functionality Co-authored-by: FBoucher <2404846+FBoucher@users.noreply.github.com> * Implement "Start a new fight" button to reset combat screen - fixes #116 Co-authored-by: FBoucher <2404846+FBoucher@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: FBoucher <2404846+FBoucher@users.noreply.github.com> * Add adventure name property and use adventurer ID reference (#126) * Initial plan * Add adventure name feature - update domain models and services Co-authored-by: FBoucher <2404846+FBoucher@users.noreply.github.com> * Remove foreign key constraint from adventures table Co-authored-by: FBoucher <2404846+FBoucher@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: FBoucher <2404846+FBoucher@users.noreply.github.com> * Add complete Dungeon theme with custom backgrounds, text, and accent colors (#128) * Initial plan * Add Dungeon theme option to Settings page Co-authored-by: fboucher <2404846+fboucher@users.noreply.github.com> * Address code review feedback - improve theme persistence Co-authored-by: fboucher <2404846+fboucher@users.noreply.github.com> * Updates Aspire SDK and package versions Updates the Aspire.AppHost.Sdk version in the AppHost project file. Adds a Directory.Packages.props file to manage package versions centrally, and updates various Aspire and related package versions to their latest releases, ensuring consistency and compatibility across the solution. * Implement full Dungeon theme with custom backgrounds and text colors Co-authored-by: fboucher <2404846+fboucher@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: fboucher <2404846+fboucher@users.noreply.github.com> Co-authored-by: fboucher <fboucher@outlook.com> * Implement door type drawing functions with lock/unlock feature for dungeon map (#129) * Implement door details with different door types (Archway, Wooden, Metal, Reinforced, Curtain, Portcullis, Stone Slab) Co-authored-by: fboucher <2404846+fboucher@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: fboucher <2404846+fboucher@users.noreply.github.com> * Fix: Addresses combobox selection and map debug issues (#130) Addresses an issue where combobox selections were not handled correctly. Now correctly passes the selected object instead of just the ID. Also adds debug logging to help resolve an intermittent map drawing issue. * Upgrades .NET and Aspire dependencies (#132) * upgrade in progress * feat(dab): Configure connection string via environment variable Configures the Data API Builder (DAB) connection string using an environment variable. This change ensures that the connection string for the database is properly set within the DAB configuration, especially during upgrade scenarios. It removes the port from the DAB template and constructs the connection string dynamically in code, referencing the MySQL resource's properties. * Replaces bind mount with file copy Replaces the bind mount approach for database initialization with a simpler file copy mechanism. This change simplifies the setup process, especially during upgrades, by ensuring that database scripts are copied directly into the container. * Implements combat turn management. (#134) Adds logic to manage combat turns, including identifying the current fighter and alternating turns between adventurer and creature. Introduces a dialog to select the first fighter and displays the current turn information. Fixes: #133 * Implements game over and victory conditions (#136) Adds logic to handle adventurer and creature defeats, displaying appropriate messages. Disables user interaction after combat ends to prevent further actions. Resets health depletion flags and UI elements on new fight start. Fixes #135 * Adds damage dice rolling functionality (#138) Implements the ability to roll damage dice within the combat page. This allows players to simulate damage rolls using 1D6 or 2D6 dice. Issue #137 * Removes seed adventurers from database (#139) * Removes demo adventurers from seed data Removes the demo adventurers from the database seed data. This prevents the creation of unnecessary or test adventurers when the database is initialized, ensuring a cleaner and more realistic initial state. * Removes demo adventurers from seed data The demo adventurers are no longer needed in the database seed data. This commit removes them. * Enables local Docker deployment (#140) * Adds Docker configuration for local development Sets up Docker Compose to orchestrate the application, database, and data api builder services for local development. Includes Dockerfile for the web client. Ensures database creation if it doesn't exist. Includes `.dockerignore` to exclude unnecessary files during image builds. Sets up `.env.example` with required environment variables * Enables running the app locally with Docker Provides a `docker-compose.yml` file for easy local deployment using Docker. Adds Dockerfiles for the database, Data API Builder (DAB), and web app components. Includes an `.env.example` file with configurable environment variables. Publishes images to Docker Hub upon tagging a commit. Fixes #91 * Improves adventurer creation flow (#143) * Improves adventurer creation experience Enhances the adventurer creation page by: - Removing unnecessary conditional rendering for weapons, streamlining the weapon selection process. - Updates the manoeuvre selection to provide more guidance to the user, including a dynamic placeholder text and label displaying the current weapon. - Sets default values to avoid null reference exceptions, improving robustness. - Sets default row size on the AdventurerPicker component to medium for better UI consistency Fixes #142 * Navigates to adventure page after character creation Updates the character creation process to navigate to the adventure page with the newly created adventurer's ID. This enables a smoother transition to gameplay. Adds auto-selection of the created adventurer. Fixes #142 * Renames Preview classes to DTO (#144) Renames the `*Preview` classes to `*DTO` to better reflect their purpose as Data Transfer Objects. This change improves clarity and consistency in the codebase. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 4c7c61a commit b9b39bb

File tree

15 files changed

+122
-100
lines changed

15 files changed

+122
-100
lines changed

src/2d6-dungeon-service/Services/D6Service.cs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ public async Task<int> GetSaveGameCount()
3232
return games?.value?.Count() ?? 0;
3333
}
3434

35-
public async Task<AdventurePreviewList?> GetAdventurePreviews()
35+
public async Task<AdventureDTOList?> GetAdventurePreviews()
3636
{
37-
return await httpClient.GetFromJsonAsync<AdventurePreviewList?>("api/adventure?$select=id,name,adventurer_id,level,last_saved_datetime");
37+
return await httpClient.GetFromJsonAsync<AdventureDTOList?>("api/adventure?$select=id,name,adventurer_id,level,last_saved_datetime");
3838
}
3939

4040
public async Task<Adventure> GetAdventure(int id)
4141
{
42-
var result = await httpClient.GetFromJsonAsync<AdventurePreviewList>($"api/adventure/id/{id.ToString()}");
43-
var adventurePrev = result!.value.First<AdventurePreview>();
42+
var result = await httpClient.GetFromJsonAsync<AdventureDTOList>($"api/adventure/id/{id.ToString()}");
43+
var adventurePrev = result!.value.First<AdventureDTO>();
4444

4545
Adventure loadedGame = new Adventure(adventurePrev);
4646
if(loadedGame.Id == 0)
@@ -51,19 +51,19 @@ public async Task<Adventure> GetAdventure(int id)
5151

5252
private async Task<int> AdventureCreate(Adventure game)
5353
{
54-
AdventurePreview draftSavedGame = new AdventurePreview();
54+
AdventureDTO draftSavedGame = new AdventureDTO();
5555
draftSavedGame.name = game.Name;
5656
draftSavedGame.adventurer_id = game.Adventurer.Id;
5757
draftSavedGame.last_saved_datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
5858

59-
var response = await httpClient.PostAsJsonAsync<AdventurePreview>($"api/adventure", draftSavedGame);
59+
var response = await httpClient.PostAsJsonAsync<AdventureDTO>($"api/adventure", draftSavedGame);
6060
var status = response.EnsureSuccessStatusCode();
6161

6262
if (!status.IsSuccessStatusCode)
6363
throw new Exception("Problem Saving the Game");
6464

65-
var returnedList = await response.Content.ReadFromJsonAsync<AdventurePreviewList>();
66-
return returnedList!.value.First<AdventurePreview>().id;
65+
var returnedList = await response.Content.ReadFromJsonAsync<AdventureDTOList>();
66+
return returnedList!.value.First<AdventureDTO>().id;
6767
}
6868

6969
public async Task<Adventure> AdventureSave(Adventure game)
@@ -72,10 +72,10 @@ public async Task<Adventure> AdventureSave(Adventure game)
7272
game.Id = await AdventureCreate(game);
7373
}
7474

75-
var serializedGame = new AdventurePreview(game);
75+
var serializedGame = new AdventureDTO(game);
7676
serializedGame.last_saved_datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
7777

78-
var response = await httpClient.PutAsJsonAsync<AdventurePreview>($"api/adventure/id/{game.Id.ToString()}", serializedGame);
78+
var response = await httpClient.PutAsJsonAsync<AdventureDTO>($"api/adventure/id/{game.Id.ToString()}", serializedGame);
7979
var status = response.EnsureSuccessStatusCode();
8080

8181
if (!status.IsSuccessStatusCode)
@@ -101,39 +101,41 @@ public async Task<bool> AdventureDelete(int id)
101101
#region == Adventurer =====
102102
public async Task<Adventurer> GetAdventurer(int id)
103103
{
104-
var result = await httpClient.GetFromJsonAsync<AdventurerPreviewList>($"api/adventurer/id/{id.ToString()}");
105-
var adventurerPrev = result!.value.First<AdventurerPreview>();
104+
var result = await httpClient.GetFromJsonAsync<AdventurerDTOList>($"api/adventurer/id/{id.ToString()}");
105+
var adventurerPrev = result!.value.First<AdventurerDTO>();
106106

107107
return new Adventurer(adventurerPrev);
108108
}
109109

110-
public async Task<AdventurerPreviewList?> GetAdventurerPreviews()
110+
public async Task<AdventurerDTOList?> GetAdventurerPreviews()
111111
{
112-
return await httpClient.GetFromJsonAsync<AdventurerPreviewList?>("api/adventurer?$select=id,name,xp,level");
112+
return await httpClient.GetFromJsonAsync<AdventurerDTOList?>("api/adventurer?$select=id,name,xp,level");
113113
}
114114

115115
public async Task<bool> SaveAdventurer(Adventurer player)
116116
{
117-
var dbPlayer = new AdventurerPreview(player);
117+
var dbPlayer = new AdventurerDTO(player);
118118

119-
var response = await httpClient.PutAsJsonAsync<AdventurerPreview>($"api/adventurer/id/{player.Id.ToString()}", dbPlayer);
119+
var response = await httpClient.PutAsJsonAsync<AdventurerDTO>($"api/adventurer/id/{player.Id.ToString()}", dbPlayer);
120120
var status = response.EnsureSuccessStatusCode();
121121

122122
if (status.IsSuccessStatusCode)
123123
return true;
124124
return false;
125125
}
126126

127-
public async Task<bool> AdventurerCreate(Adventurer player)
127+
public async Task<int> AdventurerCreate(Adventurer player)
128128
{
129-
var dbPlayer = new AdventurerPreview(player);
129+
var dbPlayer = new AdventurerDTO(player);
130130

131-
var response = await httpClient.PostAsJsonAsync<AdventurerPreview>($"api/adventurer", dbPlayer);
131+
var response = await httpClient.PostAsJsonAsync<AdventurerDTO>($"api/adventurer", dbPlayer);
132132
var status = response.EnsureSuccessStatusCode();
133133

134-
if (status.IsSuccessStatusCode)
135-
return true;
136-
return false;
134+
if (!status.IsSuccessStatusCode)
135+
return 0;
136+
137+
var returnedList = await response.Content.ReadFromJsonAsync<AdventurerDTOList>();
138+
return returnedList!.value.First<AdventurerDTO>().id;
137139
}
138140

139141
public async Task<bool> AdventurerDelete(int id)

src/2d6-dungeon-service/Services/ID6Service.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ public interface ID6Service
77
{
88
// Adventure
99
Task<int> GetSaveGameCount();
10-
Task<AdventurePreviewList?> GetAdventurePreviews();
10+
Task<AdventureDTOList?> GetAdventurePreviews();
1111
Task<Adventure> GetAdventure(int id);
1212
Task<Adventure> AdventureSave(Adventure game);
1313
Task<bool> AdventureDelete(int id);
1414

1515
// Adventurer
16-
Task<AdventurerPreviewList?> GetAdventurerPreviews();
16+
Task<AdventurerDTOList?> GetAdventurerPreviews();
1717
Task<Adventurer> GetAdventurer(int id);
1818
Task<bool> SaveAdventurer(Adventurer player);
19-
Task<bool> AdventurerCreate(Adventurer player);
19+
Task<int> AdventurerCreate(Adventurer player);
2020
Task<bool> AdventurerDelete(int id);
2121

2222
// Creature

src/2d6-dungeon-service/domain/Adventure.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public Adventure()
2020
Name = $"{Adventurer.Name} adventure";
2121
}
2222

23-
public Adventure(AdventurePreview preview){
23+
public Adventure(AdventureDTO preview){
2424

2525
Adventurer = new Adventurer();
2626
Dungeon = new Dungeon();

src/2d6-dungeon-service/domain/AdventurePreview.cs renamed to src/2d6-dungeon-service/domain/AdventureDTO.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace c5m._2d6Dungeon;
55

66
//lowercase to match the database
7-
public class AdventurePreview
7+
public class AdventureDTO
88
{
99
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
1010
public int id { get; set; } = 0;
@@ -14,9 +14,9 @@ public class AdventurePreview
1414
public string last_saved_datetime { get; set; } = string.Empty;
1515
public string serialiazedObj { get; set; } = string.Empty;
1616

17-
public AdventurePreview(){}
17+
public AdventureDTO(){}
1818

19-
public AdventurePreview(Adventure a)
19+
public AdventureDTO(Adventure a)
2020
{
2121
id = 0;
2222
name = a.Name;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace c5m._2d6Dungeon;
2+
3+
public class AdventureDTOList
4+
{
5+
public List<AdventureDTO> value { get; set; } = new List<AdventureDTO>();
6+
}

src/2d6-dungeon-service/domain/AdventurePreviewList.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/2d6-dungeon-service/domain/Adventurer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public Adventurer(string name)
8282
Rations = 3;
8383
}
8484

85-
public Adventurer(AdventurerPreview preview){
85+
public Adventurer(AdventurerDTO preview){
8686
if(string.IsNullOrEmpty(preview.serialiazedObj)){
8787

8888
Id = preview.id;

src/2d6-dungeon-service/domain/AdventurerPreview.cs renamed to src/2d6-dungeon-service/domain/AdventurerDTO.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace c5m._2d6Dungeon;
66

77
//lowercase to match the database
8-
public class AdventurerPreview
8+
public class AdventurerDTO
99
{
1010
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
1111
public int id { get; set; } = 0;
@@ -14,9 +14,9 @@ public class AdventurerPreview
1414
public int xp { get; set; }
1515
public string serialiazedObj { get; set; } = string.Empty;
1616

17-
public AdventurerPreview(){}
17+
public AdventurerDTO(){}
1818

19-
public AdventurerPreview(Adventurer a)
19+
public AdventurerDTO(Adventurer a)
2020
{
2121
id = 0;
2222
name = a.Name;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace c5m._2d6Dungeon;
2+
3+
public class AdventurerDTOList
4+
{
5+
public List<AdventurerDTO> value { get; set; } = new List<AdventurerDTO>();
6+
}

src/2d6-dungeon-service/domain/AdventurerPreviewList.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)