优化角色系统、探索系统、魔法卡生成功能;添加酒馆功能和生成指定魔法卡功能

This commit is contained in:
milimoe 2025-07-17 01:20:52 +08:00
parent 485a8a0118
commit 5f52730115
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
5 changed files with 332 additions and 103 deletions

View File

@ -6,7 +6,7 @@ namespace Oshima.FunGame.OshimaModules.Characters
{
public class CustomCharacter : Character
{
public CustomCharacter(long user_id, string name, string firstname = "", string nickname = "") : base()
public CustomCharacter(long user_id, string name, string firstname = "", string nickname = "", PrimaryAttribute primaryAttribute = PrimaryAttribute.None) : base()
{
Id = user_id;
Name = name;
@ -17,8 +17,34 @@ namespace Oshima.FunGame.OshimaModules.Characters
InitialHP = Random.Shared.Next(40, 86);
InitialMP = Random.Shared.Next(20, 56);
int value = 31;
int valueGrowth = 31;
int reduce = 0;
int reduceGrowth = 0;
if (primaryAttribute != PrimaryAttribute.None)
{
int attribute= Random.Shared.Next(15, 31);
int growth = Random.Shared.Next(15, 31);
switch (primaryAttribute)
{
case PrimaryAttribute.STR:
InitialSTR = attribute;
STRGrowth = Calculation.Round(Convert.ToDouble(growth) / 10, 2);
break;
case PrimaryAttribute.AGI:
InitialAGI = attribute;
AGIGrowth = Calculation.Round(Convert.ToDouble(growth) / 10, 2);
break;
case PrimaryAttribute.INT:
InitialINT = attribute;
INTGrowth = Calculation.Round(Convert.ToDouble(growth) / 10, 2);
break;
}
PrimaryAttribute = primaryAttribute;
reduce = attribute;
reduceGrowth = growth;
}
int value = 31 - reduce;
int valueGrowth = 31 - reduceGrowth;
for (int i = 0; i < 3; i++)
{
if (value == 0) break;
@ -27,15 +53,18 @@ namespace Oshima.FunGame.OshimaModules.Characters
switch (i)
{
case 1:
if (primaryAttribute == PrimaryAttribute.AGI) continue;
InitialAGI = attribute;
AGIGrowth = Calculation.Round(Convert.ToDouble(growth) / 10, 2);
break;
case 2:
if (primaryAttribute == PrimaryAttribute.INT) continue;
InitialINT = attribute;
INTGrowth = Calculation.Round(Convert.ToDouble(growth) / 10, 2);
break;
case 0:
default:
if (primaryAttribute == PrimaryAttribute.STR) continue;
InitialSTR = attribute;
STRGrowth = Calculation.Round(Convert.ToDouble(growth) / 10, 2);
break;

View File

@ -24,7 +24,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description => $"每次普通攻击都将附带基于 {敏捷系数 * 100:0.##}% 敏捷 [ {敏捷伤害} ] 的魔法伤害。";
public override string Description => $"每次普通攻击都将附带基于 {敏捷系数 * 100:0.##}% 敏捷 [ {敏捷伤害:0.##} ] 点魔法伤害。";
private double => * Skill.Character?.AGI ?? 0;
private readonly double = 2.5;

View File

@ -122,96 +122,47 @@ namespace Oshima.FunGame.OshimaServers.Service
FunGameConstant.AllSkills.AddRange(FunGameConstant.SuperSkills);
}
public static List<Item> GenerateMagicCards(int count, QualityType? qualityType = null)
public static List<Item> GenerateMagicCards(int count, QualityType? qualityType = null, long[]? magicIds = null, (int str, int agi, int intelligence)[]? values = null)
{
List<Item> items = [];
for (int i = 0; i < count; i++)
{
items.Add(GenerateMagicCard(qualityType));
long magicId = 0;
if (magicIds != null && magicIds.Length > i) magicId = magicIds[i];
(int str, int agi, int intelligence) = (0, 0, 0);
if (values != null && values.Length > i)
{
str = values[i].str;
agi = values[i].agi;
intelligence = values[i].intelligence;
}
items.Add(GenerateMagicCard(qualityType, magicId, str, agi, intelligence));
}
return items;
}
public static Item GenerateMagicCard(QualityType? qualityType = null)
public static Item GenerateMagicCard(QualityType? qualityType = null, long magicId = 0, int str = 0, int agi = 0, int intelligence = 0)
{
Item item = Factory.GetItem();
item.Id = Convert.ToInt64("16" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 8));
item.Name = GenerateRandomChineseName();
item.ItemType = ItemType.MagicCard;
item.RemainUseTimes = 1;
if (qualityType != null) item.QualityType = qualityType.Value;
int total;
if (qualityType != null)
{
total = qualityType switch
{
QualityType.Green => Random.Shared.Next(7, 13),
QualityType.Blue => Random.Shared.Next(13, 19),
QualityType.Purple => Random.Shared.Next(19, 25),
QualityType.Orange => Random.Shared.Next(25, 31),
QualityType.Red => Random.Shared.Next(31, 37),
QualityType.Gold => Random.Shared.Next(37, 43),
_ => Random.Shared.Next(1, 7)
};
item.QualityType = (QualityType)qualityType;
}
else
{
total = Random.Shared.Next(1, 43);
if (total > 6 && total <= 12)
{
item.QualityType = QualityType.Green;
}
else if (total > 12 && total <= 18)
{
item.QualityType = QualityType.Blue;
}
else if (total > 18 && total <= 24)
{
item.QualityType = QualityType.Purple;
}
else if (total > 24 && total <= 30)
{
item.QualityType = QualityType.Orange;
}
else if (total > 30 && total <= 36)
{
item.QualityType = QualityType.Red;
}
else if (total > 36 && total <= 42)
{
item.QualityType = QualityType.Gold;
}
}
GenerateAndAddSkillToMagicCard(item, total);
GenerateAndAddSkillToMagicCard(item, magicId, str, agi, intelligence);
return item;
}
public static void GenerateAndAddSkillToMagicCard(Item item, int total)
public static void GenerateAndAddSkillToMagicCard(Item item, long magicId = 0, int str = 0, int agi = 0, int intelligence = 0)
{
Skill magic = FunGameConstant.Magics[Random.Shared.Next(FunGameConstant.Magics.Count)].Copy();
magic.Guid = item.Guid;
magic.Level = (int)item.QualityType switch
int total = str + agi + intelligence;
if (total == 0)
{
2 => 2,
3 => 2,
4 => 3,
5 => 4,
6 => 5,
_ => 1
};
if (magic.Level > 1)
{
item.Name += $" +{magic.Level - 1}";
}
item.Skills.Active = magic;
// 初始化属性值
int str = 0, agi = 0, intelligence = 0;
total = Random.Shared.Next(1, 43);
// 随机决定将多少个属性赋给其中一个属性,确保至少一个不为零
int nonZeroAttributes = Random.Shared.Next(1, Math.Min(4, total + 1)); // 随机决定非零属性的数量,确保在 total = 1 时最多只有1个非零属性
@ -271,6 +222,57 @@ namespace Oshima.FunGame.OshimaServers.Service
agi = Random.Shared.Next(1, total - str); // 第二个属性的值
intelligence = total - str - agi; // 剩下的值给第三个属性
}
}
if (item.QualityType == QualityType.White)
{
if (total > 6 && total <= 12)
{
item.QualityType = QualityType.Green;
}
else if (total > 12 && total <= 18)
{
item.QualityType = QualityType.Blue;
}
else if (total > 18 && total <= 24)
{
item.QualityType = QualityType.Purple;
}
else if (total > 24 && total <= 30)
{
item.QualityType = QualityType.Orange;
}
else if (total > 30 && total <= 36)
{
item.QualityType = QualityType.Red;
}
else if (total > 36)
{
item.QualityType = QualityType.Gold;
}
}
Skill? magic = null;
if (magicId != 0)
{
magic = FunGameConstant.Magics.FirstOrDefault(m => m.Id == magicId);
}
magic ??= FunGameConstant.Magics[Random.Shared.Next(FunGameConstant.Magics.Count)].Copy();
magic.Guid = item.Guid;
magic.Level = (int)item.QualityType switch
{
2 => 2,
3 => 2,
4 => 3,
5 => 4,
6 => 5,
_ => 1
};
if (magic.Level > 1)
{
item.Name += $" +{magic.Level - 1}";
}
item.Skills.Active = magic;
Skill skill = Factory.OpenFactory.GetInstance<Skill>(item.Id, item.Name, []);
GenerateAndAddEffectsToMagicCard(skill, str, agi, intelligence);
@ -424,9 +426,9 @@ namespace Oshima.FunGame.OshimaServers.Service
return null;
}
public static Item? GenerateMagicCardPack(int magicCardCount, QualityType? qualityType = null)
public static Item? GenerateMagicCardPack(int magicCardCount, QualityType? qualityType = null, long[]? magicIds = null, (int str, int agi, int intelligence)[]? values = null)
{
List<Item> magicCards = GenerateMagicCards(magicCardCount, qualityType);
List<Item> magicCards = GenerateMagicCards(magicCardCount, qualityType, magicIds, values);
Item? magicCardPack = ConflateMagicCardPack(magicCards);
return magicCardPack;
}
@ -1495,10 +1497,11 @@ namespace Oshima.FunGame.OshimaServers.Service
Item[] shoes = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("13") && (int)i.QualityType == 5)];
Item[] accessory = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("14") && (int)i.QualityType == 5)];
Item[] consumables = [.. FunGameConstant.AllItems.Where(i => i.ItemType == ItemType.Consumable && i.IsInGameItem)];
string[] regionsBossName = [.. FunGameConstant.Regions.SelectMany(r => r.Characters).Select(c => c.Name)];
for (int i = 0; i < genCount; i++)
{
int nowIndex = Bosses.Count > 0 ? Bosses.Keys.Max() + 1 : 1;
string bossName = GenerateRandomChineseUserName();
string bossName = regionsBossName[Random.Shared.Next(regionsBossName.Length)];
CustomCharacter boss = new(nowIndex, bossName, "", bossName);
int cutRate = Random.Shared.Next(3) switch
{
@ -1580,8 +1583,8 @@ namespace Oshima.FunGame.OshimaServers.Service
double exMP2 = 0.8;
if (!enhanceHPMP)
{
if (isUnit) exHP2 = -0.1;
else exHP2 = 0.5;
if (isUnit) exHP2 = 0.15;
else exHP2 = 0.01;
exMP2 = 0.2;
}
double exCR = 0.35;

View File

@ -2886,6 +2886,73 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
}
[HttpPost("createmagiccard")]
public string CreateMagicCard([FromQuery] long? uid = null, [FromQuery] long? target = null, [FromQuery] string? quality = null, [FromQuery] long magicId = 0, [FromQuery] int count = 1, [FromQuery] int str = 0, [FromQuery] int agi = 0, [FromQuery] int intelligence = 0)
{
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
if (count <= 0)
{
return "数量必须大于0";
}
long targetid = target ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = new("saved", userid.ToString());
pc.LoadConfig();
if (pc.Count > 0)
{
User user = FunGameService.GetUser(pc);
string msg = "";
if (user.IsAdmin || userid > 0)
{
PluginConfig pc2 = new("saved", targetid.ToString());
pc2.LoadConfig();
if (pc2.Count > 0)
{
User user2 = FunGameService.GetUser(pc2);
if (FunGameConstant.Magics.FirstOrDefault(m => m.Id == magicId) is Skill magic)
{
foreach (string type in ItemSet.QualityTypeNameArray)
{
if (type == quality)
{
for (int i = 0; i < count; i++)
{
Item item = FunGameService.GenerateMagicCard(ItemSet.GetQualityTypeFromName(type), magic.Id, str, agi, intelligence);
item.User = user2;
user2.Inventory.Items.Add(item);
}
msg = $"已为 [ {user2} ] 生成 {count} 张 [ {magic.Name} ] 魔法卡{(str + agi + intelligence > 0 ? $" +{str} +{agi} +{intelligence}" : "")}。";
break;
}
}
}
else
{
return $"游戏中不存在 ID 为 {magicId} 的魔法技能,生成失败!";
}
pc2.Add("user", user2);
pc2.SaveConfig();
}
else
{
return $"目标 UID 不存在!";
}
}
else
{
return $"你没有权限使用此指令!";
}
return msg;
}
else
{
return noSaved;
}
}
[HttpPost("decomposeitem")]
public string DecomposeItem([FromQuery] long? uid = null, [FromBody] int[]? items = null)
{
@ -5869,6 +5936,64 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
}
[HttpPost("pub")]
public string Pub([FromQuery] long? uid = null)
{
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = new("saved", userid.ToString());
pc.LoadConfig();
string msg = "";
if (pc.Count > 0)
{
User user = FunGameService.GetUser(pc);
int zero = user.Inventory.Characters.Count(c => c.EP <= 0);
int less100 = user.Inventory.Characters.Count(c => c.EP < 100 && c.EP > 0);
int less200 = user.Inventory.Characters.Count(c => c.EP >= 100 && c.EP < 200);
double zeroNeed = 1 * zero;
double less100Need = 0.6 * less100;
double less200Need = 0.2 * less200;
double total = zeroNeed + less100Need + less200Need;
if (total == 0)
{
msg = $"你暂时不需要酒馆的服务,欢迎下次光临。";
}
else if (user.Inventory.Materials >= total)
{
user.Inventory.Materials -= total;
foreach (Character character in user.Inventory.Characters)
{
character.EP = 200;
}
msg = $"欢迎来访酒馆,你的本次消费:{total} {General.GameplayEquilibriumConstant.InGameMaterial}。";
user.LastTime = DateTime.Now;
pc.Add("user", user);
pc.SaveConfig();
}
else
{
msg = $"你的 {General.GameplayEquilibriumConstant.InGameMaterial} 不足 {total} 呢!无法为你上酒!";
}
msg += $"{zero} 个 0 点能量值的角色,{less100} 个 100 点能量值以下的角色,{less200} 个 200 点能量值以下的角色)\r\n" +
$"收费标准:\r\n1 {General.GameplayEquilibriumConstant.InGameMaterial} / 0 点能量值的角色\r\n" +
$"0.6 {General.GameplayEquilibriumConstant.InGameMaterial} / 100 点能量值以下的角色\r\n" +
$"0.2 {General.GameplayEquilibriumConstant.InGameMaterial} / 200 点能量值以下的角色";
return msg;
}
else
{
return noSaved;
}
}
[HttpGet("getevents")]
public string GetEvents([FromQuery] long? id = null)
{

View File

@ -493,6 +493,68 @@ namespace Oshima.FunGame.WebAPI.Services
return result;
}
if (e.Detail.StartsWith("生成指定"))
{
e.UseNotice = false;
string pattern = @"生成指定(\w+)魔法卡\s*(\d+)\s*(?:(\d+)\s+(\d+)\s+(\d+)(?:\s+(\d+))?)?(?:\s+(\d+))?(?:\s*给\s*(\d+))?";
Regex regex = new(pattern, RegexOptions.IgnoreCase);
Match match = regex.Match(e.Detail);
if (match.Success)
{
string quality = match.Groups[1].Value;
long magicID = long.Parse(match.Groups[2].Value);
int paramCount = match.Groups.Cast<Group>().Count(g => g.Success && g.Index > match.Groups[2].Index && g.Index < (match.Groups[8].Success ? match.Groups[8].Index : int.MaxValue));
int str = 0, agi = 0, intelligence = 0, count = 1;
long targetUserID = uid;
// 检查参数数量的有效性
if (paramCount != 0 && paramCount != 1 && paramCount != 3 && paramCount != 4)
{
await SendAsync(e, "熟圣之力", "参数数量错误!可选参数必须为 1个count、3个str, agi, intelligence或4个str, agi, intelligence, count。");
return result;
}
if (paramCount == 1)
{
count = int.Parse(match.Groups[6].Success ? match.Groups[6].Value : match.Groups[7].Value);
}
else if (paramCount == 3 || paramCount == 4)
{
str = int.Parse(match.Groups[3].Value);
agi = int.Parse(match.Groups[4].Value);
intelligence = int.Parse(match.Groups[5].Value);
if (paramCount == 4)
{
count = int.Parse(match.Groups[6].Value);
}
}
if (count <= 0)
{
await SendAsync(e, "熟圣之力", "数量不能为 0 或负数,请重新输入。");
return result;
}
if (match.Groups[8].Success)
{
targetUserID = long.Parse(match.Groups[8].Value);
}
string msg = Controller.CreateMagicCard(uid, targetUserID, quality, magicID, count, str, agi, intelligence);
if (msg != "")
{
await SendAsync(e, "熟圣之力", msg);
}
}
else
{
await SendAsync(e, "熟圣之力", "指令格式错误!正确格式:生成指定<品质>魔法卡 <MagicID> [str agi intelligence] [count]");
}
return result;
}
if (e.Detail.StartsWith("生成"))
{
e.UseNotice = false;
@ -528,23 +590,23 @@ namespace Oshima.FunGame.WebAPI.Services
}
}
if (e.Detail == "生成魔法卡包")
if (e.Detail == "预览魔法卡包")
{
e.UseNotice = false;
string msg = Controller.GenerateMagicCardPack();
if (msg != "")
{
await SendAsync(e, "生成魔法卡包", msg);
await SendAsync(e, "预览魔法卡包", msg);
}
return result;
}
else if (e.Detail == "生成魔法卡")
else if (e.Detail == "预览魔法卡")
{
e.UseNotice = false;
string msg = Controller.GenerateMagicCard();
if (msg != "")
{
await SendAsync(e, "生成魔法卡", msg);
await SendAsync(e, "预览魔法卡", msg);
}
return result;
}
@ -2231,6 +2293,16 @@ namespace Oshima.FunGame.WebAPI.Services
return result;
}
if (e.Detail == "酒馆" || e.Detail == "上酒")
{
string msg = Controller.Pub(uid);
if (msg != "")
{
await SendAsync(e, "酒馆", string.Join("\r\n", msg));
}
return result;
}
if (e.Detail == "毕业礼包")
{
if (FunGameService.Activities.FirstOrDefault(a => a.Name == "毕业季") is Activity activity && activity.Status == ActivityState.InProgress)