diff --git a/Service/Application.Domain.Entity/game/user/unit_user_monster.cs b/Service/Application.Domain.Entity/game/user/unit_user_monster.cs new file mode 100644 index 0000000..2a6a918 --- /dev/null +++ b/Service/Application.Domain.Entity/game/user/unit_user_monster.cs @@ -0,0 +1,69 @@ +using SqlSugar; +using System; + +namespace Application.Domain.Entity +{ + [Tenant("Kg.SeaTime.Game")] + public class unit_user_monster + { + /// + /// umId + /// + [SugarColumn(IsPrimaryKey = true, Length = 50)] + public string umId { get; set; } + + /// + /// userId + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? userId { get; set; } + + /// + /// areaCode + /// + [SugarColumn(Length = 255, IsNullable = true)] + public string? areaCode { get; set; } + + /// + /// mapId + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? mapId { get; set; } + + /// + /// monsterId + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? monsterId { get; set; } + + /// + /// monsterName + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? monsterName { get; set; } + + /// + /// code + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? code { get; set; } + + /// + /// par + /// + [SugarColumn(Length = 255, IsNullable = true)] + public string? par { get; set; } + + /// + /// addTime + /// + [SugarColumn(IsNullable = true)] + public long? addTime { get; set; } + + /// + /// endTime + /// + [SugarColumn(IsNullable = true)] + public long? endTime { get; set; } + } +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/model/MapMonsterModel.cs b/Service/Application.Domain.Entity/model/MapMonsterModel.cs new file mode 100644 index 0000000..2b58f98 --- /dev/null +++ b/Service/Application.Domain.Entity/model/MapMonsterModel.cs @@ -0,0 +1,11 @@ +namespace Application.Domain.Entity; + +public class MapMonsterModel +{ + public string monterId { get; set; } + public string name { get; set; } + /// + /// 0地图怪物 1生成怪物 + /// + public int type { get; set; } +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/resource/game/game_monster.cs b/Service/Application.Domain.Entity/resource/game/game_monster.cs new file mode 100644 index 0000000..abc3a76 --- /dev/null +++ b/Service/Application.Domain.Entity/resource/game/game_monster.cs @@ -0,0 +1,117 @@ +using SqlSugar; +using System; + +namespace Application.Domain.Entity +{ + [Tenant("Kg.SeaTime.Resource")] + public class game_monster + { + /// + /// monsterId + /// + [SugarColumn(IsPrimaryKey = true, Length = 50)] + public string monsterId { get; set; } + + /// + /// name + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? name { get; set; } + + /// + /// 怪物应用区域 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? code { get; set; } + + /// + /// lev + /// + [SugarColumn(IsNullable = true)] + public int? lev { get; set; } + + /// + /// exp + /// + [SugarColumn(IsNullable = true)] + public long? exp { get; set; } + + /// + /// copper + /// + [SugarColumn(IsNullable = true)] + public long? copper { get; set; } + + /// + /// petExp + /// + [SugarColumn(IsNullable = true)] + public long? petExp { get; set; } + + /// + /// minAtk + /// + [SugarColumn(IsNullable = true)] + public int? minAtk { get; set; } + + /// + /// maxAtk + /// + [SugarColumn(IsNullable = true)] + public int? maxAtk { get; set; } + + /// + /// defense + /// + [SugarColumn(IsNullable = true)] + public int? defense { get; set; } + + /// + /// agility + /// + [SugarColumn(IsNullable = true)] + public int? agility { get; set; } + + /// + /// blood + /// + [SugarColumn(Length = 62, IsNullable = true)] + public decimal? blood { get; set; } + + /// + /// 怪物属性 + /// + [SugarColumn(IsNullable = true,IsJson = true)] + public List attr { get; set; } + + /// + /// 怪物技能 + /// + [SugarColumn(IsNullable = true)] + public string? skill { get; set; } + + /// + /// award + /// + [SugarColumn(Length = 3000, IsNullable = true)] + public string? award { get; set; } + + /// + /// 支持复制战斗0不支持 1支持 + /// + [SugarColumn(IsNullable = true)] + public int? isCopy { get; set; } + + /// + /// 怪物说明 + /// + [SugarColumn(Length = 255, IsNullable = true)] + public string? remark { get; set; } + + /// + /// 用于后台操作标记,无其他作用 + /// + [SugarColumn(Length = 255, IsNullable = true)] + public string? markTips { get; set; } + } +} diff --git a/Service/Application.Domain.Entity/resource/game/game_monster_map.cs b/Service/Application.Domain.Entity/resource/game/game_monster_map.cs new file mode 100644 index 0000000..1d40beb --- /dev/null +++ b/Service/Application.Domain.Entity/resource/game/game_monster_map.cs @@ -0,0 +1,57 @@ +using SqlSugar; +using System; + +namespace Application.Domain.Entity +{ + [Tenant("Kg.SeaTime.Resource")] + public class game_monster_map + { + /// + /// mmId + /// + [SugarColumn(IsPrimaryKey = true, Length = 50)] + public string mmId { get; set; } + + /// + /// mapId + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? mapId { get; set; } + + /// + /// monsterId + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? monsterId { get; set; } + + /// + /// monsterName + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? monsterName { get; set; } + + /// + /// addCount + /// + [SugarColumn(IsNullable = true)] + public int? addCount { get; set; } + + /// + /// chance + /// + [SugarColumn(IsNullable = true)] + public int? chance { get; set; } + + /// + /// sTime + /// + [SugarColumn(IsNullable = true)] + public int? sTime { get; set; } + + /// + /// eTime + /// + [SugarColumn(IsNullable = true)] + public int? eTime { get; set; } + } +} \ No newline at end of file diff --git a/Service/Application.Domain/Enum/MonsterEnum.cs b/Service/Application.Domain/Enum/MonsterEnum.cs new file mode 100644 index 0000000..2ffb97d --- /dev/null +++ b/Service/Application.Domain/Enum/MonsterEnum.cs @@ -0,0 +1,15 @@ +namespace Application.Domain; + +public static class MonsterEnum +{ + public enum Code + { + + } + public enum AreaCode + { + Own,//个人怪物 + Public,//公共怪物 + Team,//队伍怪物 + } +} \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs b/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs index 9313e39..0015dff 100644 --- a/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs +++ b/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs @@ -12,7 +12,7 @@ public interface IGameEquService #region 用户装备 Task> GetUserEquData(string userId, int type, string equName, int PageIndex, int PageSize, - RefAsync Total, bool isRemOn = false); + RefAsync Total, bool isRemOn = false, bool isRemLock = false); Task> GetUserEquData(string userId, int equId); Task> GetUserEquData(string userId, string code, List noUeId); diff --git a/Service/Application.Domain/Services/Interface/Monster/IGameMonsterService.cs b/Service/Application.Domain/Services/Interface/Monster/IGameMonsterService.cs new file mode 100644 index 0000000..73df623 --- /dev/null +++ b/Service/Application.Domain/Services/Interface/Monster/IGameMonsterService.cs @@ -0,0 +1,15 @@ +namespace Application.Domain; + +public interface IGameMonsterService +{ + #region 地图怪物 + + Task> GetMonsterDataByMap(string mapId); + + Task CreateMonsterToMap(string userId, string mapId, string areaCode, string monsterId, + int count = 1, int time = 0, string par = ""); + + Task> GetMapMonster(string userId, string mapId, string teamId); + + #endregion +} \ No newline at end of file diff --git a/Service/Application.Domain/Services/Service/Equ/GameEquService.cs b/Service/Application.Domain/Services/Service/Equ/GameEquService.cs index 1962f3a..a03b4ca 100644 --- a/Service/Application.Domain/Services/Service/Equ/GameEquService.cs +++ b/Service/Application.Domain/Services/Service/Equ/GameEquService.cs @@ -39,7 +39,7 @@ public class GameEquService(ISqlSugarClient DbClient, IRedisCache redis) : IGame #region 用户装备 public async Task> GetUserEquData(string userId, int type, string equName, int PageIndex, - int PageSize, RefAsync Total, bool isRemOn = false) + int PageSize, RefAsync Total, bool isRemOn = false, bool isRemLock = false) { long onTime = TimeExtend.GetTimeStampSeconds; var db = DbClient.AsTenant().GetConnectionWithAttr(); @@ -48,6 +48,7 @@ public class GameEquService(ISqlSugarClient DbClient, IRedisCache redis) : IGame .WhereIF(type == 1, it => it.isOn == 1) .WhereIF(type == 3, it => it.isAppr == 0) .WhereIF(isRemOn, it => it.isOn == 0) + .WhereIF(isRemLock, it => it.isLock == 0) .WhereIF(!string.IsNullOrEmpty(equName), it => it.equName.Contains(equName) || it.unitEquName.Contains(equName)) .OrderByDescending(it => it.lev) diff --git a/Service/Application.Domain/Services/Service/Monster/GameMonsterService.cs b/Service/Application.Domain/Services/Service/Monster/GameMonsterService.cs new file mode 100644 index 0000000..603de1a --- /dev/null +++ b/Service/Application.Domain/Services/Service/Monster/GameMonsterService.cs @@ -0,0 +1,183 @@ +using Microsoft.VisualBasic.CompilerServices; + +namespace Application.Domain; + +public class GameMonsterService(ISqlSugarClient DbClient, IRedisCache redis) : IGameMonsterService, ITransient +{ + #region 基础资源库 + + public async Task GetMonsterInfo(string monsterId) + { + string key = string.Format(BaseCache.BaseCacheKeys, "MonsterData", "MonsterInfo"); + if (await redis.HExistsHashAsync(key, monsterId)) + { + return await redis.GetHashAsync(key, monsterId); + } + + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var data = await db.Queryable().Where(it => it.monsterId == monsterId).SingleAsync(); + await redis.AddHashAsync(key, monsterId, data); + return data; + } + + #endregion + + #region 地图怪物 + + public async Task> GetMonsterDataByMap(string mapId) + { + string key = string.Format(BaseCache.BaseCacheKeys, "MonsterData", "MonsterOnMap"); + if (await redis.HExistsHashAsync(key, mapId)) + { + return await redis.GetHashAsync>(key, mapId); + } + + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var data = await db.Queryable().Where(it => it.mapId == mapId).ToListAsync(); + await redis.AddHashAsync(key, mapId, data); + return data; + } + + public async Task CreateMonsterToMap(string userId, string mapId, string areaCode, string monsterId, + int count = 1, int time = 0, string par = "") + { + bool result = false; + var monsterInfo = await GetMonsterInfo(monsterId); + if (monsterInfo != null) + { + time = time <= 0 ? 7 * 24 * 60 : time; + long onTime = TimeExtend.GetTimeStampSeconds; + long endTime = onTime + time * 60; + List data = new List(); + for (int i = 0; i < count; i++) + { + data.Add(new unit_user_monster() + { + umId = StringAssist.NewGuid, + userId = userId, + areaCode = areaCode, + mapId = mapId, + monsterId = monsterId, + monsterName = monsterInfo.name, + code = monsterInfo.code, + par = par, + addTime = onTime, + endTime = endTime + }); + } + + if (data.Count > 0) + { + var createDb = DbClient.AsTenant().GetConnectionWithAttr(); + await createDb.Insertable(data).ExecuteCommandAsync(); + } + + result = true; + } + + if (result) + { + await ClearCreateMonster(mapId); + } + + return result; + } + + private async Task> GetCreateMonsterByMapId(string mapId) + { + string key = string.Format(BaseCache.BaseCacheKeys, "MonsterData", "CreateMonsterOnMap"); + if (await redis.HExistsHashAsync(key, mapId)) + { + return await redis.GetHashAsync>(key, mapId); + } + + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var data = await db.Queryable().Where(it => it.mapId == mapId).ToListAsync(); + await redis.AddHashAsync(key, mapId, data); + return data; + } + + private async Task ClearCreateMonster(string mapId) + { + string key = string.Format(BaseCache.BaseCacheKeys, "MonsterData", "CreateMonsterOnMap"); + await redis.DelHashAsync(key, mapId); + } + + public async Task> GetMapMonster(string userId, string mapId, string teamId) + { + List result = new List(); + var mapMonster = await GetMonsterDataByMap(mapId); + if (mapMonster.Count > 0) + { + int random = 0; //此处需要判断用户状态中的几率 + int onTime = TimeAssist.GetHourNum; + foreach (var item in mapMonster) + { + if (item.sTime < onTime && item.eTime > onTime) + { + if (RandomAssist.CheakRandom((int)item.chance + random)) + { + for (int i = 0; i < item.addCount; i++) + { + MapMonsterModel temp = new MapMonsterModel() + { + monterId = item.mmId, + name = item.monsterName, + type = 0 + }; + result.Add(temp); + } + } + } + } + } + + //此处追加个人生成怪物 + List createData = new List(); + var createMonster = await GetCreateMonsterByMapId(mapId); + if (createMonster.Count > 0) + { + long onTime = TimeExtend.GetTimeStampSeconds; + createMonster = createMonster.FindAll(it => it.endTime > onTime); + + createData.AddRange(createMonster.FindAll(it => + it.userId == userId || it.areaCode == nameof(MonsterEnum.AreaCode.Public))); + if (!string.IsNullOrEmpty(teamId) && teamId != "0") + { + var teamService = App.GetService(); + var teamMember = await teamService.GetTeamMember(teamId); + teamMember = teamMember.FindAll(it => it.userId != userId); + var onCreate = createMonster.FindAll(it => + teamMember.Any(team => + team.userId == it.userId && it.areaCode == nameof(MonsterEnum.AreaCode.Team))); + foreach (var item in onCreate) + { + if (createData.Any(it => it.umId == item.umId)) + { + continue; + } + + createData.Add(item); + } + } + } + + if (createData.Count > 0) + { + foreach (var item in createData) + { + MapMonsterModel temp = new MapMonsterModel() + { + monterId = item.umId, + name = item.monsterName, + type = 1 + }; + result.Add(temp); + } + } + + return result; + } + + #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 bbf8a73..4ac2652 100644 --- a/Service/Application.Web/Controllers/Map/MapController.cs +++ b/Service/Application.Web/Controllers/Map/MapController.cs @@ -21,9 +21,12 @@ public class MapController : ControllerBase private readonly IGameSkillService _skillService; private readonly IGameGoodsService _goodsService; private readonly IGameTeamService _teamService; + private readonly IGameMonsterService _monsterService; + public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService, IUnitUserAttrService attrService, IMessageService messageService, IUnitUserWeight weightService, - IUnitUserAccService accService, IGameSkillService skillService,IGameGoodsService goodsService,IGameTeamService teamService) + IUnitUserAccService accService, IGameSkillService skillService, IGameGoodsService goodsService, + IGameTeamService teamService, IGameMonsterService monsterService) { _userService = userService; _mapService = mapService; @@ -35,6 +38,7 @@ public class MapController : ControllerBase _skillService = skillService; _goodsService = goodsService; _teamService = teamService; + _monsterService = monsterService; } #region 地图相关 @@ -89,14 +93,17 @@ public class MapController : ControllerBase #endregion //公聊信息 - var myTeam = await _teamService.GetUserTeamData(userId); - string teamId =myTeam.teamId ; + var myTeam = await _teamService.GetUserTeamData(userId); + string teamId = myTeam.teamId; string groupId = ""; var chatData = await _chatService.GetChatTop(userId, area, 2, teamId, groupId); var npcData = await _mapService.GetMapNpc(mapInfo.mapId); //NPC信息 npcData = npcData.FindAll(it => GameTool.AreaVerify(StateHelper.areaId, it.areaId)); + + //获取怪物 + var monsterData = await _monsterService.GetMapMonster(userId, mapInfo.mapId, teamId); var nearUser = await _mapService.GetMapUser(mapInfo.mapId, area, (int)mapInfo.lookArea, [userId], 3); //获取附近的人 @@ -145,7 +152,8 @@ public class MapController : ControllerBase noReadMsg = noReadMsg[3], business, mapRes, - broadcast + broadcast, + monster = monsterData }; return PoAction.Ok(ret); diff --git a/Service/Application.Web/Controllers/Map/StoreController.cs b/Service/Application.Web/Controllers/Map/StoreController.cs index 7a2d084..6a4c20f 100644 --- a/Service/Application.Web/Controllers/Map/StoreController.cs +++ b/Service/Application.Web/Controllers/Map/StoreController.cs @@ -50,6 +50,7 @@ public class StoreController : ControllerBase { return PoAction.Message("Npc不存在!"); } + if (!npcInfo.bus.Any(it => it.code == nameof(GameEnum.NpcBusCode.Store))) { return PoAction.Message("业务不可用!"); @@ -88,6 +89,7 @@ public class StoreController : ControllerBase { return PoAction.Message("Npc不存在!"); } + if (!npcInfo.bus.Any(it => it.code == nameof(GameEnum.NpcBusCode.Store))) { return PoAction.Message("业务不可用!"); @@ -165,10 +167,12 @@ public class StoreController : ControllerBase { return PoAction.Message("Npc不存在!"); } + if (!npcInfo.bus.Any(it => it.code == nameof(GameEnum.NpcBusCode.Store))) { return PoAction.Message("业务不可用!"); } + var onMap = await _mapService.GetUserOnMapId(userId); if (npcInfo.mapId != onMap) { @@ -179,25 +183,25 @@ public class StoreController : ControllerBase if (type == 0) { - var data = await _equService.GetUserEquData(userId, 0, query, page, 10, total, true); - return PoAction.Ok(new { data, total.Value }); + var data = await _equService.GetUserEquData(userId, 0, query, page, 10, total, true, true); + return PoAction.Ok(new { data, total = total.Value }); } else if (type == 1) { List code = new List() { nameof(GoodsEnum.Code.Drug) }; var data = await _goodsService.GetUserGoodsData(userId, code, new List(), query, page, 10, total); - return PoAction.Ok(new { data, total.Value }); + return PoAction.Ok(new { data, total = total.Value }); } else if (type == 2) { List code = new List(); List noCode = new List() { nameof(GoodsEnum.Code.Drug) }; var data = await _goodsService.GetUserGoodsData(userId, code, noCode, query, page, 10, total); - return PoAction.Ok(new { data, total.Value }); + return PoAction.Ok(new { data, total = total.Value }); } else { - return PoAction.Ok(new { data = new List(), total.Value }); + return PoAction.Ok(new { data = new List(), total = total.Value }); } } @@ -229,7 +233,7 @@ public class StoreController : ControllerBase return PoAction.Message("Npc不存在!"); } - if (parms.type == 0)//装备 + if (parms.type == 0) //装备 { var equInfo = await _equService.GetUserEquInfo(parms.id); if (equInfo == null) @@ -259,7 +263,7 @@ public class StoreController : ControllerBase } else { - return PoAction.Message("出售失败,请稍后尝试!"); + return PoAction.Message("出售失败,请稍后尝试!"); } } else //物品 @@ -288,7 +292,7 @@ public class StoreController : ControllerBase } else { - return PoAction.Message("出售失败,请稍后尝试!"); + return PoAction.Message("出售失败,请稍后尝试!"); } } } diff --git a/Web/src/pages/map/index.vue b/Web/src/pages/map/index.vue index 25abd0b..edd122b 100644 --- a/Web/src/pages/map/index.vue +++ b/Web/src/pages/map/index.vue @@ -1,7 +1,7 @@