祝福系统基础逻辑
This commit is contained in:
gechangfu 2025-08-12 19:27:44 +08:00
parent 879ae4efb8
commit af4fc50c38
10 changed files with 176 additions and 38 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,33 +1,33 @@
[
{"id":1,"type":1,"effectAttribute":"attack","battleValue":[1,15],"iconId":1,"nameId":201},
{"id":2,"type":1,"effectAttribute":"hp","battleValue":[1,1],"iconId":2,"nameId":202},
{"id":3,"type":1,"effectAttribute":"swordAtk","battleValue":[1,10],"iconId":3,"nameId":203},
{"id":4,"type":2,"effectAttribute":"swordWearBase","battleValue":[1,10],"iconId":4,"nameId":204},
{"id":5,"type":2,"effectAttribute":"swordWearSpe","battleValue":[1,10],"iconId":5,"nameId":205},
{"id":6,"type":2,"effectAttribute":"fireAtk","battleValue":[1,10],"iconId":6,"nameId":206},
{"id":7,"type":2,"effectAttribute":"iceAtk","battleValue":[1,10],"iconId":7,"nameId":207},
{"id":8,"type":2,"effectAttribute":"lightAtk","battleValue":[1,10],"iconId":8,"nameId":208},
{"id":9,"type":2,"effectAttribute":"shadowAtk","battleValue":[1,10],"iconId":9,"nameId":209},
{"id":10,"type":1,"effectAttribute":"fireDef","battleValue":[1,10],"iconId":10,"nameId":210},
{"id":11,"type":1,"effectAttribute":"iceDef","battleValue":[1,10],"iconId":11,"nameId":211},
{"id":12,"type":1,"effectAttribute":"lightDef","battleValue":[1,10],"iconId":12,"nameId":212},
{"id":13,"type":1,"effectAttribute":"shadowDef","battleValue":[1,10],"iconId":13,"nameId":213},
{"id":14,"type":2,"effectAttribute":"attackRate","battleValue":[1,10],"iconId":14,"nameId":214},
{"id":15,"type":2,"effectAttribute":"hpRate","battleValue":[1,10],"iconId":15,"nameId":215},
{"id":16,"type":2,"effectAttribute":"atkSpeed","battleValue":[1,10],"iconId":16,"nameId":216},
{"id":20,"type":2,"effectAttribute":"critRate","battleValue":[1,10],"iconId":17,"nameId":220},
{"id":21,"type":2,"effectAttribute":"critDamageRate","battleValue":[1,10],"iconId":18,"nameId":221},
{"id":22,"type":2,"effectAttribute":"atkSpeedRate","battleValue":[1,10],"iconId":19,"nameId":222},
{"id":23,"type":2,"effectAttribute":"cdRate","battleValue":[1,10],"iconId":20,"nameId":223},
{"id":24,"type":1,"effectAttribute":"mpBonus","battleValue":[1,10],"iconId":21,"nameId":224},
{"id":25,"type":2,"effectAttribute":"mpReduceRate","battleValue":[1,10],"iconId":22,"nameId":225},
{"id":26,"type":1,"effectAttribute":"mpRecoverBonus","battleValue":[1,10],"iconId":23,"nameId":226},
{"id":27,"type":2,"effectAttribute":"vampireRate","battleValue":[1,10],"iconId":24,"nameId":227},
{"id":28,"type":2,"effectAttribute":"coinBonus","battleValue":[1,10],"iconId":25,"nameId":228},
{"id":50,"type":1,"effectAttribute":"wearNumber","battleValue":[1,10],"iconId":26,"nameId":250},
{"id":51,"type":1,"effectAttribute":"skillNumber","battleValue":[1,10],"iconId":27,"nameId":251},
{"id":52,"type":1,"effectAttribute":"extraAttributeNumber","battleValue":[1,10],"iconId":28,"nameId":252},
{"id":53,"type":1,"effectAttribute":"elementNumber","battleValue":[1,10],"iconId":29,"nameId":253},
{"id":54,"type":1,"effectAttribute":"elementDefNumber","battleValue":[1,10],"iconId":30,"nameId":254},
{"id":55,"type":1,"effectAttribute":"gemNumber","battleValue":[1,10],"iconId":31,"nameId":255}
{"id":1,"type":1,"specialType":null,"effectAttribute":"attack","battleValue":[1,15],"iconId":1,"nameId":201},
{"id":2,"type":1,"specialType":null,"effectAttribute":"hp","battleValue":[1,1],"iconId":2,"nameId":202},
{"id":3,"type":1,"specialType":null,"effectAttribute":"swordAtk","battleValue":[1,10],"iconId":3,"nameId":203},
{"id":4,"type":2,"specialType":null,"effectAttribute":"swordWearBase","battleValue":[1,10],"iconId":4,"nameId":204},
{"id":5,"type":2,"specialType":null,"effectAttribute":"swordWearSpe","battleValue":[1,10],"iconId":5,"nameId":205},
{"id":6,"type":2,"specialType":2,"effectAttribute":"fireAtk","battleValue":[1,10],"iconId":6,"nameId":206},
{"id":7,"type":2,"specialType":2,"effectAttribute":"iceAtk","battleValue":[1,10],"iconId":7,"nameId":207},
{"id":8,"type":2,"specialType":2,"effectAttribute":"lightAtk","battleValue":[1,10],"iconId":8,"nameId":208},
{"id":9,"type":2,"specialType":2,"effectAttribute":"shadowAtk","battleValue":[1,10],"iconId":9,"nameId":209},
{"id":10,"type":1,"specialType":3,"effectAttribute":"fireDef","battleValue":[1,10],"iconId":10,"nameId":210},
{"id":11,"type":1,"specialType":3,"effectAttribute":"iceDef","battleValue":[1,10],"iconId":11,"nameId":211},
{"id":12,"type":1,"specialType":3,"effectAttribute":"lightDef","battleValue":[1,10],"iconId":12,"nameId":212},
{"id":13,"type":1,"specialType":3,"effectAttribute":"shadowDef","battleValue":[1,10],"iconId":13,"nameId":213},
{"id":14,"type":2,"specialType":null,"effectAttribute":"attackRate","battleValue":[1,10],"iconId":14,"nameId":214},
{"id":15,"type":2,"specialType":null,"effectAttribute":"hpRate","battleValue":[1,10],"iconId":15,"nameId":215},
{"id":16,"type":2,"specialType":null,"effectAttribute":"atkSpeed","battleValue":[1,10],"iconId":16,"nameId":216},
{"id":20,"type":2,"specialType":1,"effectAttribute":"critRate","battleValue":[1,10],"iconId":17,"nameId":220},
{"id":21,"type":2,"specialType":1,"effectAttribute":"critDamageRate","battleValue":[1,10],"iconId":18,"nameId":221},
{"id":22,"type":2,"specialType":1,"effectAttribute":"atkSpeedRate","battleValue":[1,10],"iconId":19,"nameId":222},
{"id":23,"type":2,"specialType":null,"effectAttribute":"cdRate","battleValue":[1,10],"iconId":20,"nameId":223},
{"id":24,"type":1,"specialType":null,"effectAttribute":"mpBonus","battleValue":[1,10],"iconId":21,"nameId":224},
{"id":25,"type":2,"specialType":null,"effectAttribute":"mpReduceRate","battleValue":[1,10],"iconId":22,"nameId":225},
{"id":26,"type":1,"specialType":null,"effectAttribute":"mpRecoverBonus","battleValue":[1,10],"iconId":23,"nameId":226},
{"id":27,"type":2,"specialType":null,"effectAttribute":"vampireRate","battleValue":[1,10],"iconId":24,"nameId":227},
{"id":28,"type":2,"specialType":null,"effectAttribute":"coinBonus","battleValue":[1,10],"iconId":25,"nameId":228},
{"id":50,"type":1,"specialType":null,"effectAttribute":"wearNumber","battleValue":[1,10],"iconId":26,"nameId":250},
{"id":51,"type":1,"specialType":null,"effectAttribute":"skillNumber","battleValue":[1,10],"iconId":27,"nameId":251},
{"id":52,"type":1,"specialType":null,"effectAttribute":"extraAttributeNumber","battleValue":[1,10],"iconId":28,"nameId":252},
{"id":53,"type":1,"specialType":null,"effectAttribute":"elementNumber","battleValue":[1,10],"iconId":29,"nameId":253},
{"id":54,"type":1,"specialType":null,"effectAttribute":"elementDefNumber","battleValue":[1,10],"iconId":30,"nameId":254},
{"id":55,"type":1,"specialType":null,"effectAttribute":"gemNumber","battleValue":[1,10],"iconId":31,"nameId":255}
]

View File

@ -0,0 +1,5 @@
[
{"id":1000,"type":1,"effect":14,"minRate":5,"maxRate":100},
{"id":1001,"type":1,"effect":15,"minRate":5,"maxRate":100},
{"id":2000,"type":2,"effect":20001,"minRate":5,"maxRate":100}
]

View File

@ -3,6 +3,9 @@
{"id":2,"type":1,"typeArgs":[],"quality":2,"iconId":2,"nameId":10002,"textId":20002,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":3,"type":1,"typeArgs":[],"quality":2,"iconId":3,"nameId":10003,"textId":20003,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":11,"type":1,"typeArgs":[],"quality":1,"iconId":11,"nameId":10011,"textId":20011,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":20,"type":1,"typeArgs":[],"quality":4,"iconId":20,"nameId":10020,"textId":20020,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":21,"type":1,"typeArgs":[],"quality":4,"iconId":21,"nameId":10021,"textId":20021,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":22,"type":1,"typeArgs":[],"quality":4,"iconId":22,"nameId":10022,"textId":20022,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":10000,"type":4,"typeArgs":[],"quality":1,"iconId":12,"nameId":20000,"textId":30000,"buyPrice":[11,10],"sellPrice":[11,10],"use":[],"showPackage":null},
{"id":10001,"type":4,"typeArgs":[],"quality":2,"iconId":13,"nameId":20001,"textId":30001,"buyPrice":[11,20],"sellPrice":[11,20],"use":[],"showPackage":null},
{"id":10002,"type":4,"typeArgs":[],"quality":3,"iconId":14,"nameId":20002,"textId":30002,"buyPrice":[11,30],"sellPrice":[11,30],"use":[],"showPackage":null},

View File

@ -117,6 +117,22 @@ function Utils:GetRandomIdFromJsonWithType(JsonData: table, Type: number, Except
return randomId
end
-- 获取随机idExceptIdList为可选参数如果传入则排除ExceptIdList中的id
function Utils:GetRandomIdFromJsonWithSpecialKey(JsonData: table, Key: string, Value: string, ExceptIdList: table?)
local result = {}
for _, item in ipairs(JsonData) do
if item[Key] == Value then
table.insert(result, item.id)
end
end
local rng = Random.new()
local randomId = rng:NextInteger(1, #result)
while ExceptIdList and table.find(ExceptIdList, randomId) do
randomId = rng:NextInteger(1, #result)
end
return randomId
end
-- 随机获取权重Index
function Utils:GetRandomWeightIndex(WeightTable: table)
local totalWeight = 0

View File

@ -6,6 +6,7 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
--> Variables
local Rng = require(ReplicatedStorage.Tools.Rng)
local Utils = require(ReplicatedStorage.Tools.Utils)
local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy)
@ -13,6 +14,8 @@ local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy)
local JsonItem = require(ReplicatedStorage.Json.ItemProp)
local JsonGem = require(ReplicatedStorage.Json.Gem)
local JsonParam = require(ReplicatedStorage.Json.Param)
local JsonBlessing = require(ReplicatedStorage.Json.Blessing)
local JsonEquipment = require(ReplicatedStorage.Json.Equipment)
--> Events
local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip
@ -123,6 +126,63 @@ function BookProxy:IsBookUnlocked(Player: Player, BookId: number)
return ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[tostring(BookId)]
end
--------------------------------------------------------------------------------
-- 祝福相关功能
function BookProxy:BlessingBook(Player: Player, BookId: number, BlessingType: number, BlessingCount: number)
local BookId = tostring(BookId)
-- 临时设置为1之后优化再说
local BlessingCount = 1
local pData = Utils:GetPlayerDataFolder(Player)
if not pData then return end
-- 类型排除
if BlessingType < 1 or BlessingType > 3 then return end
local BlessingCostItemId = 20 + BlessingType - 1
local PlayerInfoProxy = require(ServerStorage.Proxy.PlayerInfoProxy)
local hasEnoughItem = PlayerInfoProxy:HasEnoughItem(Player, BlessingCostItemId, BlessingCount)
if not hasEnoughItem then warn("没有足够货币, 无法祝福") return end
-- 消耗祝福道具
PlayerInfoProxy:ChangeItemCount(Player, BlessingCostItemId, -BlessingCount)
-- 获取祝福
local EquipmentData = Utils:GetIdDataFromJson(JsonEquipment, BookId)
if not EquipmentData then warn("获取装备数据失败") return end
-- 如果类型相同,则直接定向
local isNotDefine = true
local BlessingData = nil
if EquipmentData.specialType == BlessingType then
-- 定向
BlessingData = Utils:GetSpecialKeyDataFromJson(JsonBlessing, "effect", EquipmentData.specialRequire)
if BlessingData then
isNotDefine = false
end
end
-- 没有定向的话, 就随机
if isNotDefine then
-- 随机
BlessingData = Utils:GetRandomIdFromJsonWithType(JsonBlessing, BlessingType)
if not BlessingData then warn("获取祝福数据失败, 请检查配置表内容", BlessingType) return end
end
-- 设置祝福属性
ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].blessingId = BlessingData.id
ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].blessingRate = Rng:GetRandomInt(BlessingData.minRate, BlessingData.maxRate)
-- 设置祝福成功,向前端发送信息
end
-- 获取祝福信息
function BookProxy:GetBlessingInfo(Player: Player, BookId: number)
local BookData = ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[tostring(BookId)]
if not BookData then return end
return BookData.blessingId, BookData.blessingRate
end
--------------------------------------------------------------------------------
-- TODO: 获取玩家属性(之后要是图鉴加属性就在这)

View File

@ -18,6 +18,7 @@ local JsonEquipment = require(ReplicatedStorage.Json.Equipment)
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
local JsonExAttributes = require(ReplicatedStorage.Json.ExAttributes)
local JsonParam = require(ReplicatedStorage.Json.Param)
local JsonBlessing = require(ReplicatedStorage.Json.Blessing)
local JsonForge = require(ReplicatedStorage.Json.Forge)
local JsonQualityEffect = require(ReplicatedStorage.Json.QualityEffect)
@ -143,7 +144,7 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
if exAttributeNumber > 0 then
local spawnExAttributesId = {}
for i = 1, exAttributeNumber do
local newExAttributeId = Utils:GetRandomIdFromJsonWithType(JsonExAttributes, 1, spawnExAttributesId)
local newExAttributeId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonExAttributes, "specialType", 1, spawnExAttributesId)
table.insert(spawnExAttributesId, newExAttributeId)
local ExAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newExAttributeId)
@ -164,7 +165,7 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
if elementNumber > 0 then
local spawnElementsId = {}
for i = 1, elementNumber do
local newElementAttributeId = Utils:GetRandomIdFromJsonWithType(JsonExAttributes, 1, spawnElementsId)
local newElementAttributeId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonExAttributes, "specialType", 2, spawnElementsId)
table.insert(spawnElementsId, newElementAttributeId)
local ElementAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementAttributeId)
@ -185,7 +186,7 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
if elementDefNumber > 0 then
local spawnElementDefId = {}
for i = 1, elementDefNumber do
local newElementDefId = Utils:GetRandomIdFromJsonWithType(JsonExAttributes, 1, spawnElementDefId)
local newElementDefId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonExAttributes, "specialType", 3, spawnElementDefId)
table.insert(spawnElementDefId, newElementDefId)
local ElementDefAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementDefId)
@ -198,6 +199,52 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
end
end
-- 属性祝福处理
local BookProxy = require(ServerStorage.Proxy.BookProxy)
local blessingId, blessingRate = BookProxy:GetBlessingInfo(Player, EquipmentId)
local blessingType, blessingEffect
local blessingTableName
local isNotTrigger = true
if blessingId then
local blessingData = Utils:GetIdDataFromJson(JsonBlessing, blessingId)
blessingType = blessingData.type
blessingEffect = blessingData.effect
end
if blessingType == 1 then
-- 找到对应祝福所属的表名
local attributeData = Utils:GetIdDataFromJson(JsonAttributes, blessingEffect)
if attributeData.specialType then
if attributeData.specialType == 1 then
blessingTableName = "exAttributes"
elseif attributeData.specialType == 2 then
blessingTableName = "elements"
elseif attributeData.specialType == 3 then
blessingTableName = "elementDef"
end
end
-- 如果表名存在,进行下一步处理
if blessingTableName then
-- 不存在该属性时,且有其他属性时
if not ResultData[blessingTableName][attributeData.effectAttribute] and #ResultData[blessingTableName] > 0 then
-- 随机替换功能是否触发
local isTrigger = Rng:GetRandomInt(1, 100) <= blessingRate
if isTrigger and isNotTrigger then
-- 将第一个属性替换为祝福属性,保留对应的随机值,只替换属性名
local oldAttributeValue
for key, value in ResultData[blessingTableName] do
oldAttributeValue = value
ResultData[blessingTableName][key] = nil
break
end
ResultData[blessingTableName][attributeData.effectAttribute] = oldAttributeValue
isNotTrigger = false
end
end
end
end
------------------------------------------------------------
ArchiveProxy.pData[Player.UserId][STORE_NAME][UniqueId] = ResultData
@ -215,7 +262,17 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
if abilityNumber > 0 then
local spawnAbilitiesId = {}
for i = 1, abilityNumber do
local newAbilityId = AbilityProxy:GetRandomAbilityId(spawnAbilitiesId)
-- 技能祝福处理
local specialAbilityId
if blessingType == 2 and isNotTrigger then
-- 没触发过中了概率就指定技能id
local isTrigger = Rng:GetRandomInt(1, 100) <= blessingRate
if isTrigger then
specialAbilityId = blessingEffect
isNotTrigger = false
end
end
local newAbilityId = specialAbilityId or AbilityProxy:GetRandomAbilityId(spawnAbilitiesId)
table.insert(spawnAbilitiesId, newAbilityId)
local newAbilityData, newAbilityInstance = AbilityProxy:AddAbility(Player, newAbilityId)
AbilityProxy:WearAbility(Player, newAbilityData.id, UniqueId)
@ -339,7 +396,6 @@ function EquipmentProxy:UnwearEquipment(Player: Player, EquipmentId: number)
-- 更新玩家数据
PlayerFightProxy:UpdatePlayerFightData(Player)
end
-- 获取穿戴中的装备UniqueId
@ -387,7 +443,6 @@ function EquipmentProxy:GetPlayerAttributes(Player: Player)
-- print("属性表", AttributesData)
-- 计算特殊词条加成是否激活
if EquipmentData.specialType then
local isActive = false
-- 属性类型加成
if EquipmentData.specialType == 1 then

View File

@ -97,7 +97,6 @@ function PlayerInfoProxy:InitPlayer(Player: Player)
-- 新玩家数据初始化
local isNew = false
if not ArchiveProxy.pData[Player.UserId][STORE_NAME] then
print("新玩家数据初始化", Player.UserId)
ArchiveProxy.pData[Player.UserId][STORE_NAME] = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Stats = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Items = {}