From 8550d85659ed51f4d6cb696e85e89f98b5de5edf Mon Sep 17 00:00:00 2001 From: Putoo <290555932@qq.com> Date: Tue, 2 Jun 2026 17:58:36 +0800 Subject: [PATCH] 222 --- .../game/user/unit_user_map.cs | 28 +++ .../model/MapTemp.cs | 9 + .../Application.Domain/Config/GameConfig.cs | 1 + Service/Application.Domain/Enum/GameEnum.cs | 1 + .../Services/Interface/Map/IGameMapService.cs | 2 + .../Services/Service/Map/GameMapService.cs | 36 ++++ .../Application.Domain/Tool/Base/GameTool.cs | 39 +++- .../Controllers/Map/MapController.cs | 182 +++++++++++++++++- Web/src/pages/map/run.vue | 1 + Web/src/pages/map/to.vue | 79 ++++++++ Web/src/services/map/MapService.ts | 16 ++ 11 files changed, 392 insertions(+), 2 deletions(-) create mode 100644 Service/Application.Domain.Entity/game/user/unit_user_map.cs create mode 100644 Service/Application.Domain.Entity/model/MapTemp.cs create mode 100644 Web/src/pages/map/run.vue create mode 100644 Web/src/pages/map/to.vue diff --git a/Service/Application.Domain.Entity/game/user/unit_user_map.cs b/Service/Application.Domain.Entity/game/user/unit_user_map.cs new file mode 100644 index 0000000..5958593 --- /dev/null +++ b/Service/Application.Domain.Entity/game/user/unit_user_map.cs @@ -0,0 +1,28 @@ +using SqlSugar; +using System; + +namespace Application.Domain.Entity +{ + [Tenant("Kg.SeaTime.Game")] + public class unit_user_map + { + /// + /// umId + /// + [SugarColumn(IsPrimaryKey = true, Length = 50)] + public string umId { get; set; } + + /// + /// userId + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? userId { get; set; } + + /// + /// cityId + /// + [SugarColumn(IsNullable = true)] + public int? cityId { get; set; } + + } +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/model/MapTemp.cs b/Service/Application.Domain.Entity/model/MapTemp.cs new file mode 100644 index 0000000..e5d3550 --- /dev/null +++ b/Service/Application.Domain.Entity/model/MapTemp.cs @@ -0,0 +1,9 @@ +namespace Application.Domain.Entity; + +public class MapTemp +{ + public int cityId { get; set; } + public string cityName { get; set; } + public int copper { get; set; } + public int distance { get; set; } +} \ No newline at end of file diff --git a/Service/Application.Domain/Config/GameConfig.cs b/Service/Application.Domain/Config/GameConfig.cs index 12de65c..afc29d8 100644 --- a/Service/Application.Domain/Config/GameConfig.cs +++ b/Service/Application.Domain/Config/GameConfig.cs @@ -15,4 +15,5 @@ public static class GameConfig public const int GameUserFriendMaxCount = 50;//好友最大上限人数 public const int GameAutoBagGoodsId = 10001;//百宝箱物品ID public const int GameAutoDrugGoodsId = 10001;//急救箱物品ID + public const int GameToMapNeedCopper = 5;//传送每海里费用 } \ No newline at end of file diff --git a/Service/Application.Domain/Enum/GameEnum.cs b/Service/Application.Domain/Enum/GameEnum.cs index c11bcbf..454aec9 100644 --- a/Service/Application.Domain/Enum/GameEnum.cs +++ b/Service/Application.Domain/Enum/GameEnum.cs @@ -50,5 +50,6 @@ public static class GameEnum RetBlood, RetMorale, RetVigour, + MapTo, } } \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs b/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs index 6b14d94..0dba7d9 100644 --- a/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs +++ b/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs @@ -23,6 +23,8 @@ public interface IGameMapService Task GetUserOnMapInfo(string userId); Task SetUserMapDefult(string userId); Task GetToMapInfo(string userId, string toMap, bool isUpUserMap = true, bool isChangeCity = false); + Task> GetUserCityMapData(string userId); + Task AddUserCityMap(string userId, int cityId); #endregion #region 其他相关 diff --git a/Service/Application.Domain/Services/Service/Map/GameMapService.cs b/Service/Application.Domain/Services/Service/Map/GameMapService.cs index 692f6d0..d824e64 100644 --- a/Service/Application.Domain/Services/Service/Map/GameMapService.cs +++ b/Service/Application.Domain/Services/Service/Map/GameMapService.cs @@ -290,6 +290,42 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame } } + public async Task> GetUserCityMapData(string userId) + { + string key = string.Format(UserCache.BaseCacheKey, "UserCityMap"); + if (await redis.HExistsHashAsync(key, userId)) + { + return await redis.GetHashAsync>(key, userId); + } + + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var data = await db.Queryable().Where(it => it.userId == userId).ToListAsync(); + await redis.AddHashAsync(key, userId, data); + return data; + } + + private async Task ClearUserCityMapCache(string userId) + { + string key = string.Format(UserCache.BaseCacheKey, "UserCityMap"); + await redis.DelHashAsync(key, userId); + } + + public async Task AddUserCityMap(string userId, int cityId) + { + unit_user_map map = new unit_user_map(); + map.umId = $"{userId}_{cityId}"; + map.userId = userId; + map.cityId = cityId; + var db = DbClient.AsTenant().GetConnectionWithAttr(); + bool result = await db.Storageable(map).ExecuteCommandAsync() > 0; + if (result) + { + await ClearUserCityMapCache(userId); + } + + return result; + } + #endregion #region 其他相关 diff --git a/Service/Application.Domain/Tool/Base/GameTool.cs b/Service/Application.Domain/Tool/Base/GameTool.cs index 4730921..7d0b368 100644 --- a/Service/Application.Domain/Tool/Base/GameTool.cs +++ b/Service/Application.Domain/Tool/Base/GameTool.cs @@ -1,4 +1,6 @@ -namespace Application.Domain; +using System.Drawing; + +namespace Application.Domain; public class GameTool { @@ -87,4 +89,39 @@ public class GameTool return weight; } + #region 距离计算 + + /// + /// 计算海里 + /// + /// + /// + /// + public static int ComputeMile(string onMap, string toMap) + { + string[] _OnMap = onMap.Split('_'); + int sx = Convert.ToInt32(_OnMap[0]); + int sy = Convert.ToInt32(_OnMap[1]); + string[] _ToMap = toMap.Split('_'); + int ex = Convert.ToInt32(_ToMap[0]); + int ey = Convert.ToInt32(_ToMap[1]); + return GetDistanceByLocation(sx, sy, ex, ey) * 10; + } + + private static int GetDistance(PointF start, PointF end) + { + double value = Math.Sqrt(Math.Abs(start.X - end.X) * Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y) * Math.Abs(start.Y - end.Y)); + + return Convert.ToInt32(value); + } + + private static int GetDistanceByLocation(int onX, int onY, int toX, int toY) + { + PointF start = new PointF(onX, onY); + PointF end = new PointF(toX, toY); + return GetDistance(start, end); + } + + #endregion 距离计算 + } \ No newline at end of file diff --git a/Service/Application.Web/Controllers/Map/MapController.cs b/Service/Application.Web/Controllers/Map/MapController.cs index 8bae3a3..5a5cbf1 100644 --- a/Service/Application.Web/Controllers/Map/MapController.cs +++ b/Service/Application.Web/Controllers/Map/MapController.cs @@ -16,17 +16,24 @@ public class MapController : ControllerBase private readonly IGameChatService _chatService; private readonly IUnitUserAttrService _attrService; private readonly IMessageService _messageService; + private readonly IUnitUserWeight _weightService; + private readonly IUnitUserAccService _accService; public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService, - IUnitUserAttrService attrService, IMessageService messageService) + IUnitUserAttrService attrService, IMessageService messageService, IUnitUserWeight weightService, + IUnitUserAccService accService) { _userService = userService; _mapService = mapService; _chatService = chatService; _attrService = attrService; _messageService = messageService; + _weightService = weightService; + _accService = accService; } + #region 地图相关 + /// /// 获取地图主页信息 /// @@ -167,6 +174,179 @@ public class MapController : ControllerBase } } + + /// + /// 获取传送/航海城市列表 + /// + /// + /// + /// + [HttpGet] + public async Task GetCityData(int npcId, int cityId) + { + string userId = StateHelper.userId; + + #region NPC验证 + + var npcInfo = await _mapService.GetNpcInfo(npcId); + if (npcInfo == null) + { + return PoAction.Message("Npc不存在!"); + } + + if (npcInfo.status != 1) + { + return PoAction.Message("Npc不存在!"); + } + + if (!npcInfo.bus.Any(it => it.code == nameof(GameEnum.NpcBusCode.MapTo))) + { + return PoAction.Message("业务不可用!"); + } + + var onMap = await _mapService.GetUserOnMapId(userId); + if (npcInfo.mapId != onMap) + { + return PoAction.Message("Npc不存在!"); + } + + #endregion + + var cityData = await _mapService.GetCityData(); + cityData = cityData.FindAll(it => it.type == "DEF_MAP"); + + List area = cityData.FindAll(it => it.parent == 0); + if (cityId == 0) + { + cityId = area[0].cityId; + } + + var onCityData = cityData.FindAll(it => it.parent == cityId); + var userCity = await _mapService.GetUserCityMapData(userId); + var AtCity = await _mapService.GetMapCityByMapId(onMap); + + List city = new List(); + onCityData.ForEach(item => + { + if (userCity.Any(it => it.cityId == item.cityId) && item.cityId != AtCity) + { + MapTemp temp = new MapTemp(); + temp.cityId = item.cityId; + temp.cityName = item.cityName; + temp.distance = GameTool.ComputeMile(onMap, item.toMap); + temp.copper = temp.distance * GameConfig.GameToMapNeedCopper; + city.Add(temp); + } + }); + string tips = $"*传送消耗:{GameConfig.GameToMapNeedCopper}铜贝/海里
*等级低于80级不需要传送费!"; + return PoAction.Ok(new { area, city, cityId, tips }); + } + + /// + /// 用户传送到地图 + /// + /// + /// + /// + [HttpGet] + public async Task UserToMap(int npcId, int cityId) + { + string userId = StateHelper.userId; + + #region NPC验证 + + var npcInfo = await _mapService.GetNpcInfo(npcId); + if (npcInfo == null) + { + return PoAction.Message("Npc不存在!"); + } + + if (npcInfo.status != 1) + { + return PoAction.Message("Npc不存在!"); + } + + if (!npcInfo.bus.Any(it => it.code == nameof(GameEnum.NpcBusCode.MapTo))) + { + return PoAction.Message("业务不可用!"); + } + + var onMap = await _mapService.GetUserOnMap(userId); + if (npcInfo.mapId != onMap.mapId) + { + return PoAction.Message("Npc不存在!"); + } + + #endregion + + var cityInfo = await _mapService.GetCityInfo(cityId); + if (cityInfo == null) + { + return PoAction.Message("城市不存在!"); + } + + var userWeight = await _weightService.GetUserWeightInfo(userId); + if (userWeight.shipOnWeight > 0) + { + return PoAction.Message("背包中存在货物,不可传送,你可以进行航行!"); + } + + var onMapInfo = await _mapService.GetMapInfo(onMap.mapId); + if (onMapInfo.cityId == cityId) + { + return PoAction.Message("您已在当前城市,无需传送!"); + } + + var MySeaMap = await _mapService.GetUserCityMapData(userId); + if (MySeaMap.Any(it => it.cityId == cityId)==false) + { + return PoAction.Message("您暂未获取该城市海图!"); + } + + bool isCanTo = false; + var MyLev = await _attrService.GetUserLev(userId); + if (MyLev < 80) + { + isCanTo = true; + } + + int need = 0; + if (isCanTo == false) //判断费用 + { + var myAcc = await _accService.GetUserAccInfo(userId, nameof(AccEnum.AccType.copper)); + need = GameTool.ComputeMile(onMap.mapId, cityInfo.toMap) * GameConfig.GameToMapNeedCopper; + if (myAcc < need) + { + return PoAction.Message("铜贝不足!"); + } + + isCanTo = true; + } + + if (isCanTo) + { + if (await _mapService.UpdateUserOnMap(onMap, cityInfo.toMap)) + { + if (need > 0) + { + await _accService.UpdateUserCopper(userId, 0, need, $"传送到【{cityInfo.cityName}】费用"); + } + + return PoAction.Ok(true); + } + else + { + return PoAction.Message("传送失败,请稍后尝试!"); + } + } + else + { + return PoAction.Message("传送失败,请稍后尝试!"); + } + } + + #endregion + #region npc相关 /// diff --git a/Web/src/pages/map/run.vue b/Web/src/pages/map/run.vue new file mode 100644 index 0000000..41a40c8 --- /dev/null +++ b/Web/src/pages/map/run.vue @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Web/src/pages/map/to.vue b/Web/src/pages/map/to.vue new file mode 100644 index 0000000..c053286 --- /dev/null +++ b/Web/src/pages/map/to.vue @@ -0,0 +1,79 @@ + + \ No newline at end of file diff --git a/Web/src/services/map/MapService.ts b/Web/src/services/map/MapService.ts index 7d8cd81..137c4c4 100644 --- a/Web/src/services/map/MapService.ts +++ b/Web/src/services/map/MapService.ts @@ -31,6 +31,22 @@ export class MapService { return await ApiService.Request("get", "/Map/Map/GetAutoMapPath", { toMap }); } + /** + * 获取传送/航海城市列表 + * GET /Map/Map/GetCityData + */ + static async GetCityData(npcId: number, cityId: number) { + return await ApiService.Request("get", "/Map/Map/GetCityData", { npcId, cityId }); + } + + /** + * 用户传送到地图 + * GET /Map/Map/UserToMap + */ + static async UserToMap(npcId: number, cityId: number) { + return await ApiService.Request("get", "/Map/Map/UserToMap", { npcId, cityId }); + } + /** * 获取NPC相关信息 * GET /Map/Map/GetNpcInfo