718 lines
32 KiB
Lua
718 lines
32 KiB
Lua
PlacementModeConfig = PlacementModeConfig or {}
|
||
require('Script.Common.ue_enum_custom')
|
||
|
||
-- 放置模式ModeID
|
||
PlacementModeConfig.PlaceModeID = 1002;
|
||
-- 游玩模式ModeID
|
||
PlacementModeConfig.PlayModeID = 1001;
|
||
-- 当前编解码使用的版本
|
||
PlacementModeConfig.PlaceCodeVersion = 1;
|
||
-- 当玩家没有保存地图的情况下使用默认地图
|
||
PlacementModeConfig.GlobalDefaultPlaceCode = "1141E0P0000021J0M0000021I0M0100021H0M0200021G0M0300021F0M0400021E0M0500021D0M0600021C0M0700021B0M0800021B0N0800021D0N0600021A0M0900021A0L0900000@0W0100001E0Q0100001D0L0100001E0M0100000@0E0100001E0L0100001E0O0100000@0F0100000@0G0100000@0H0100000@0Z0100000@0Y0100001E0N0100000@0X0100000@0V0100000@0I0100001E0R0100001E0S0100001D0S010001180N000001180Q0000011B0T0000011B0K00000";
|
||
-- 放置物带有的ActorTag
|
||
PlacementModeConfig.PlaceItemTag = "PlaceItem"
|
||
|
||
|
||
|
||
|
||
|
||
-- Path --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
-- Manager
|
||
PlacementModeConfig.PlaceManagerPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/BP_PlaceModeManager.BP_PlaceModeManager_C')
|
||
-- ItemBase
|
||
PlacementModeConfig.PlaceItemBasePath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/BP_PlaceItemBase.BP_PlaceItemBase_C')
|
||
-- 跑图的阻挡体Actor
|
||
PlacementModeConfig.PassagewayBlockPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/SceneActor/PlaceMode/BP_PassagewayBlock.BP_PassagewayBlock_C')
|
||
-- 可放置范围Actor
|
||
PlacementModeConfig.PlaceableAreaPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/SceneActor/PlaceMode/BP_PlaceableArea.BP_PlaceableArea_C')
|
||
-- 预览材质
|
||
PlacementModeConfig.PreviewMatPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Material/PlaceMat/MAT_ClientPreview.MAT_ClientPreview')
|
||
-- 防线路径
|
||
PlacementModeConfig.LineOfDefensePath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/SceneActor/PlaceMode/BP_LineOfDefense.BP_LineOfDefense_C')
|
||
|
||
-- Path End ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
PlacementModeConfig.PlacingAttr = {
|
||
-- 采用对象池放置时可以减少性能开销,但不能设置为不可移动因此不能攀爬
|
||
IsObjectPoolPlace = false;
|
||
-- 放置时单位点之间的距离
|
||
PositionSpacing = 100;
|
||
-- 设置旋转时的单位旋转间隔
|
||
RotationSpacing = 90;
|
||
-- 初始位置(即未放置时的单位位置)
|
||
SpawnPos = {X = 0, Y = 0, Z = -3000};
|
||
-- 保存的地图上限
|
||
MaxSavedMapNum = 6;
|
||
-- 保存的放置物命名utf-8字符串长度限制
|
||
PlaceMapNameLengthLimit = 6;
|
||
-- 代码长度上限
|
||
MaxPlaceCodeLen = 800;
|
||
----------------------------TraceParam
|
||
-- 启用检测时的绘制
|
||
EnableDrawDebug = false;
|
||
-- 检测位置的时间间隔
|
||
CheckPosTimeInterval = 0.0;
|
||
-- 检测位置的距离
|
||
TraceDis = 2000;
|
||
-- 检测移除Item的距离
|
||
TraceRemoveDis = 5000;
|
||
-- 移除时检测位置的时间间隔
|
||
CheckRemoveItemTimeInterval = 0.2;
|
||
-- 检测放置的碰撞类型
|
||
TraceObjType = {ECollisionChannel.ECC_WorldStatic, ECollisionChannel.ECC_WorldDynamic};
|
||
-- 检测移除的碰撞类型
|
||
RemoveTraceObjType = {ECollisionChannel.ECC_WorldStatic, ECollisionChannel.ECC_WorldDynamic,};
|
||
-- 可放置的颜色
|
||
CanPlaceColor = {R=0.000000,G=1.000000,B=0.838520,A=1.000000};
|
||
-- 不可放置的颜色
|
||
CanNotPlaceColor = {R=1.000000,G=0.000000,B=0.000000,A=1.000000};
|
||
----------------------------TraceParam End
|
||
|
||
----------------------------PlaceValue
|
||
-- 基础放置量
|
||
BasePlaceValue = 100;
|
||
-- 最大放置量
|
||
MaxPlaceValue = 300;
|
||
-- 每级增加放置量
|
||
LevelUpPlaceValue = 2;
|
||
----------------------------PlaceValue End
|
||
|
||
---------------------------- LineOfDefense
|
||
-- 每名玩家需要通过防线的次数
|
||
NumOfPlayerBreakingThroughDefenseLine = 3;
|
||
-- 击杀得分
|
||
KillAddScore = 2;
|
||
-- 助攻得分
|
||
AssistAddScore = 1;
|
||
-- 防守成功得分
|
||
DefendSucceedAddScore = 30;
|
||
-- 进入防线得分
|
||
EnterDefenseLineAddScore = 10;
|
||
-- 距离防线2D半径内不可放置物体
|
||
LineOfDefenseRadius = 300;
|
||
-- 高度不能在防线范围内
|
||
LineOfDefenseHeight = 500;
|
||
---------------------------- LineOfDefense End
|
||
|
||
-- Shop ---------------------------------------------------------
|
||
---------------------------- subscription ratio
|
||
-- 金币兑换Exp的比例
|
||
RatioGoldToExp = 1;
|
||
-- 金砖兑换金币的比例
|
||
RatioGoldBrickToGold = 10;
|
||
-- 绿洲币兑换金砖比例
|
||
RatioOasisCoinToGoldBrick = 1;
|
||
---------------------------- subscription ratio End
|
||
-- 金砖购买名
|
||
GoldBrickName = "GoldBrick";
|
||
-- 单次购买数量
|
||
BuyGoldBrickCount = 100;
|
||
-- Shop ---------------------------------------------------------
|
||
}
|
||
|
||
-- Enum ----------------------------------------------------------------------------------------------
|
||
-- 放置模式类型
|
||
PlacementModeConfig.EPlaceMode = {
|
||
None = 1;
|
||
PlaceMode = 2;
|
||
RemoveMode = 3;
|
||
}
|
||
|
||
|
||
-- 放置是否成功的回调类型
|
||
PlacementModeConfig.EPlaceCallback = {
|
||
Succeed = 1;
|
||
InsufficientPlaceValue = 2;
|
||
InsufficientNumberOfItem = 3;
|
||
LocationNotWithinRange = 4;
|
||
}
|
||
|
||
-- 加载已保存放置物的类型
|
||
PlacementModeConfig.LoadPlaceItemsType = {
|
||
None = 0,
|
||
Default = 1,
|
||
SavedMap = 2,
|
||
}
|
||
|
||
-- 放置地图类型
|
||
PlacementModeConfig.PlaceMapType = {
|
||
RelicDefenseLine = 1;
|
||
}
|
||
|
||
-- 得分类型
|
||
PlacementModeConfig.AddScoreType = {
|
||
KillAddScore = 1; -- 击杀得分
|
||
AssistAddScore = 2; -- 助攻得分
|
||
DefendSucceedAddScore = 3; -- 防守成功得分
|
||
EnterDefenseLineAddScore = 4; -- 进入防线得分
|
||
Dead = 5; -- 玩家死亡
|
||
}
|
||
|
||
-- 放置代码导入反馈类型
|
||
PlacementModeConfig.EPlaceDecodeCallback = {
|
||
Succeed = 1; -- 导入成功
|
||
VersionError = 2; -- 版本代码出错
|
||
CodeLengthError = 3; -- 代码长度异常
|
||
MapCodeError = 4; -- 地图类型错误
|
||
PlacePosRangeError = 5; -- 放置点位不在范围内
|
||
CharRangeError = 5; -- 代码字符存在异常字符
|
||
PlaceItemTypeError = 6; -- 放置物类型异常
|
||
}
|
||
|
||
-- 解锁物体类型
|
||
PlacementModeConfig.EUnlockType = {
|
||
None = 1;
|
||
Level = 2;
|
||
Gold = 3;
|
||
GoldBrick = 4;
|
||
}
|
||
|
||
-- Enum End ------------------------------------------------------------------------------------------
|
||
|
||
|
||
-- 放置失败的回调名
|
||
PlacementModeConfig.PlaceCallbackName = {
|
||
[PlacementModeConfig.EPlaceCallback.Succeed] = "放置成功";
|
||
[PlacementModeConfig.EPlaceCallback.InsufficientPlaceValue] = "放置空间不足";
|
||
[PlacementModeConfig.EPlaceCallback.InsufficientNumberOfItem] = "物品数量不足";
|
||
[PlacementModeConfig.EPlaceCallback.LocationNotWithinRange] = "该位置不在可放置范围内";
|
||
}
|
||
|
||
-- 地图信息
|
||
PlacementModeConfig.MapInfo = {
|
||
[PlacementModeConfig.PlaceMapType.RelicDefenseLine] = {
|
||
MapName = "遗迹防线";
|
||
-- 跑图测试的时间上限
|
||
BreakThroughTestTime = 20;
|
||
MapPlacingRange = {X = 2000, Y = 2000, Z = 2000};
|
||
DefaultPlaceCode = "1141E0P0000021J0M0000021I0M0100021H0M0200021G0M0300021F0M0400021E0M0500021D0M0600021C0M0700021B0M0800021B0N0800021D0N0600021A0M0900021A0L0900000@0W0100001E0Q0100001D0L0100001E0M0100000@0E0100001E0L0100001E0O0100000@0F0100000@0G0100000@0H0100000@0Z0100000@0Y0100001E0N0100000@0X0100000@0V0100000@0I0100001E0R0100001E0S0100001D0S010001180N000001180Q0000011B0T0000011B0K00000";
|
||
}
|
||
}
|
||
|
||
|
||
|
||
-- Item
|
||
PlacementModeConfig.ItemInfo = {
|
||
[EPlaceItemType.SmallBunker] = {
|
||
Name = "小型掩体";
|
||
Desc = "可以挡子弹或作为踏板。";
|
||
ItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/SmallBunker/BP_SmallBunker.BP_SmallBunker_C');
|
||
PreviewItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/SmallBunker/BP_Preview_SmallBunker.BP_Preview_SmallBunker_C');
|
||
SelectTex = UGCGameSystem.GetUGCResourcesFullPath('Asset/Texture/PlaceItem/T_SmallBunker.T_SmallBunker');
|
||
MaxCount = 50;
|
||
InitialCount = 20;
|
||
Cost = 2;
|
||
RemovePointToActor = false; -- 若为true则移除指针指向Actor根位置,反之则指向边框的中心点
|
||
IncrementInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Gold;
|
||
Cost = 500;
|
||
};
|
||
UnlockInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.None;
|
||
}
|
||
},
|
||
[EPlaceItemType.BigBunker] = {
|
||
Name = "大型掩体";
|
||
Desc = "比小型掩体大很多,可以阻挡敌人前进,在无协助攀爬的情况下无法直接爬上去。";
|
||
ItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/BigBanker/BP_BigBunker.BP_BigBunker_C');
|
||
PreviewItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/BigBanker/BP_Preview_BigBunker.BP_Preview_BigBunker_C');
|
||
SelectTex = UGCGameSystem.GetUGCResourcesFullPath('Asset/Texture/PlaceItem/T_BigBunker.T_BigBunker');
|
||
MaxCount = 10;
|
||
InitialCount = 4;
|
||
Cost = 5;
|
||
RemovePointToActor = false; -- 若为true则移除指针指向Actor根位置,反之则指向边框的中心点
|
||
IncrementInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Gold;
|
||
Cost = 1000;
|
||
};
|
||
UnlockInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.None;
|
||
}
|
||
},
|
||
[EPlaceItemType.Slope] = {
|
||
Name = "斜坡木板";
|
||
Desc = "可快速走到一定的高度。";
|
||
ItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/Slope/BP_Slope.BP_Slope_C');
|
||
PreviewItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/Slope/BP_Preview_Slope.BP_Preview_Slope_C');
|
||
SelectTex = UGCGameSystem.GetUGCResourcesFullPath('Asset/Texture/PlaceItem/T_Slope.T_Slope');
|
||
MaxCount = 40;
|
||
InitialCount = 15;
|
||
Cost = 2;
|
||
RemovePointToActor = false; -- 若为true则移除指针指向Actor根位置,反之则指向边框的中心点
|
||
IncrementInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Gold;
|
||
Cost = 500;
|
||
};
|
||
UnlockInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.None;
|
||
}
|
||
},
|
||
[EPlaceItemType.Launch] = {
|
||
Name = "蹦床";
|
||
Desc = "弹射玩家到一定的高度。";
|
||
ItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/Launch/BP_Launch.BP_Launch_C');
|
||
PreviewItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/Launch/BP_Preview_Launch.BP_Preview_Launch_C');
|
||
SelectTex = UGCGameSystem.GetUGCResourcesFullPath('Asset/Texture/PlaceItem/T_Launch.T_Launch');
|
||
MaxCount = 4;
|
||
InitialCount = 0;
|
||
Cost = 10;
|
||
RemovePointToActor = true; -- 若为true则移除指针指向Actor根位置,反之则指向边框的中心点
|
||
IncrementInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Gold;
|
||
Cost = 1500;
|
||
};
|
||
UnlockInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Level;
|
||
Cost = 3;
|
||
}
|
||
},
|
||
|
||
[EPlaceItemType.LandMine] = {
|
||
Name = "地雷";
|
||
Desc = "进攻玩家走入范围内会发生爆炸,造成80点伤害,10s冷却。";
|
||
ItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/LandMine/BP_LandMine.BP_LandMine_C');
|
||
PreviewItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/LandMine/BP_Preview_LandMine.BP_Preview_LandMine_C');
|
||
SelectTex = UGCGameSystem.GetUGCResourcesFullPath('Asset/Texture/PlaceItem/T_LandMine.T_LandMine');
|
||
MaxCount = 6;
|
||
InitialCount = 1;
|
||
Cost = 15;
|
||
RemovePointToActor = true; -- 若为true则移除指针指向Actor根位置,反之则指向边框的中心点
|
||
IncrementInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Gold;
|
||
Cost = 3000;
|
||
};
|
||
UnlockInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.None;
|
||
};
|
||
-- 其他参数
|
||
Param = { Damage = 80; CoolingTime = 10;}
|
||
},
|
||
[EPlaceItemType.Flamethrower] = {
|
||
Name = "喷火装置";
|
||
Desc = "对范围8m内最近的敌人造成范围伤害。";
|
||
ItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/Flamethrower/BP_Flamethrower.BP_Flamethrower_C');
|
||
PreviewItemPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/PlaceItems/Items/Flamethrower/BP_Preview_Flamethrower.BP_Preview_Flamethrower_C');
|
||
SelectTex = UGCGameSystem.GetUGCResourcesFullPath('Asset/Texture/PlaceItem/T_Framethrower.T_Framethrower');
|
||
MaxCount = 2;
|
||
InitialCount = 0;
|
||
Cost = 20;
|
||
RemovePointToActor = true; -- 若为true则移除指针指向Actor根位置,反之则指向边框的中心点
|
||
IncrementInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Gold;
|
||
Cost = 5000;
|
||
};
|
||
UnlockInfo = {
|
||
UnlockType = PlacementModeConfig.EUnlockType.Level;
|
||
Cost = 8;
|
||
};
|
||
-- 其他参数
|
||
Param = { Damage = 10; }
|
||
},
|
||
}
|
||
|
||
-- 得分数值
|
||
PlacementModeConfig.ScoreVal = {
|
||
[PlacementModeConfig.AddScoreType.KillAddScore] = 2; -- 击杀得分
|
||
[PlacementModeConfig.AddScoreType.AssistAddScore] = 1; -- 助攻得分
|
||
[PlacementModeConfig.AddScoreType.DefendSucceedAddScore] = 30; -- 防守成功得分
|
||
[PlacementModeConfig.AddScoreType.EnterDefenseLineAddScore] = 10; -- 进入防线得分
|
||
[PlacementModeConfig.AddScoreType.Dead] = 0; -- 玩家死亡
|
||
}
|
||
|
||
-- 得分名称
|
||
PlacementModeConfig.AddScoreName = {
|
||
[PlacementModeConfig.AddScoreType.KillAddScore] = "淘汰得分";
|
||
[PlacementModeConfig.AddScoreType.AssistAddScore] = "助攻得分";
|
||
[PlacementModeConfig.AddScoreType.DefendSucceedAddScore] = "防守成功";
|
||
[PlacementModeConfig.AddScoreType.EnterDefenseLineAddScore] = "突破得分";
|
||
}
|
||
|
||
PlacementModeConfig.UnlockName = {
|
||
[PlacementModeConfig.EUnlockType.None] = "";
|
||
[PlacementModeConfig.EUnlockType.Level] = "等级";
|
||
[PlacementModeConfig.EUnlockType.Gold] = "金币";
|
||
[PlacementModeConfig.EUnlockType.GoldBrick] = "金砖";
|
||
}
|
||
|
||
-- Function ============================================================================================================================================================================================
|
||
--- 获取放置控制器Manager
|
||
PlacementModeConfig.GetPlaceManager = function()
|
||
if not UE.IsValid(PlacementModeConfig.PlaceManager) then
|
||
PlacementModeConfig.PlaceManager = UGCSystemLibrary.GetUniqueInstanceFromPath(PlacementModeConfig.PlaceManagerPath)
|
||
end
|
||
return PlacementModeConfig.PlaceManager
|
||
end
|
||
|
||
--- 获取放置模式的父类Class
|
||
PlacementModeConfig.GetPlaceItemBaseClass = function()
|
||
if PlacementModeConfig.PlaceItemBaseClass == nil then
|
||
PlacementModeConfig.PlaceItemBaseClass = UE.LoadClass(PlacementModeConfig.PlaceItemBasePath)
|
||
end
|
||
return PlacementModeConfig.PlaceItemBaseClass
|
||
end
|
||
|
||
--- 是否为放置模式
|
||
PlacementModeConfig.IsPlaceMode = function()
|
||
return PlacementModeConfig.PlaceModeID == UGCMultiMode.GetModeID()
|
||
end
|
||
|
||
--- 通过当前在线的进攻玩家数,进行判断应该突破防线的次数
|
||
function PlacementModeConfig.GetNumOfBreakingThroughDefenseLine()
|
||
local PCNum = #UGCGameSystem.GetAllPlayerController()
|
||
return (PCNum - 1) * PlacementModeConfig.PlacingAttr.NumOfPlayerBreakingThroughDefenseLine
|
||
end
|
||
|
||
--- 获取放置物解锁条件信息
|
||
function PlacementModeConfig.GetPlaceItemUnlockInfo(PlaceItemType)
|
||
local PlaceItemInfo = PlacementModeConfig.ItemInfo[PlaceItemType]
|
||
if PlaceItemInfo then
|
||
return PlaceItemInfo.UnlockInfo.UnlockType, PlaceItemInfo.UnlockInfo.Cost
|
||
end
|
||
end
|
||
|
||
--- 获取放置物增量条件信息
|
||
function PlacementModeConfig.GetPlaceItemIncrementInfo(PlaceItemType)
|
||
local PlaceItemInfo = PlacementModeConfig.ItemInfo[PlaceItemType]
|
||
if PlaceItemInfo then
|
||
return PlaceItemInfo.IncrementInfo.UnlockType, PlaceItemInfo.IncrementInfo.Cost
|
||
end
|
||
end
|
||
|
||
--- 获取最大放置量
|
||
function PlacementModeConfig.GetPlaceMaxValue(InPlayerKey)
|
||
local Exp = ArchiveDataConfig.GetPlayerArchiveDataFromType(InPlayerKey, ArchiveDataConfig.EArchiveType.Exp)
|
||
Exp = Exp and Exp or 0
|
||
local Level = LevelConfig.GetLevel(Exp)
|
||
return PlacementModeConfig.PlacingAttr.BasePlaceValue + (Level - 1) * PlacementModeConfig.PlacingAttr.LevelUpPlaceValue
|
||
end
|
||
|
||
--- 设置所有放置机关的激活
|
||
function PlacementModeConfig.ActiveAllPlaceItem(IsActive)
|
||
local SceneAllPlaceItems = GameplayStatics.GetAllActorsOfClass(UGCGameSystem.GameState, PlacementModeConfig.GetPlaceItemBaseClass(), {})
|
||
for i, v in pairs(SceneAllPlaceItems) do
|
||
v:SetActive(IsActive)
|
||
end
|
||
end
|
||
|
||
--- 获取玩家可放置某物体的数量
|
||
function PlacementModeConfig.GetPlayerPlaceItemCount(PlayerKey, InItemType)
|
||
local ItemIncrement = ArchiveDataConfig.GetPlayerArchiveDataFromType(PlayerKey, ArchiveDataConfig.EArchiveType.ItemIncrement)
|
||
local ItemInfo = PlacementModeConfig.ItemInfo[InItemType]
|
||
if ItemIncrement and ItemIncrement[InItemType] then
|
||
return math.clamp(ItemIncrement[InItemType] + ItemInfo.InitialCount, 0, ItemInfo.MaxCount)
|
||
end
|
||
return ItemInfo.InitialCount
|
||
end
|
||
|
||
--- 获取放置代码中含有的物体数量
|
||
function PlacementModeConfig.GetPlaceCodeHaveItemCont(InCode)
|
||
local PlaceItemCount = {}
|
||
local DecodeResType, MapType, PlaceItemInfo = PlacementModeConfig.PlaceCodeDecode(InCode)
|
||
if DecodeResType == PlacementModeConfig.EPlaceDecodeCallback.Succeed then
|
||
for i, v in pairs(PlaceItemInfo) do
|
||
if PlaceItemCount[v.PlaceItemType] then
|
||
PlaceItemCount[v.PlaceItemType] = PlaceItemCount[v.PlaceItemType] + 1
|
||
else
|
||
PlaceItemCount[v.PlaceItemType] = 1
|
||
end
|
||
end
|
||
end
|
||
return DecodeResType, PlaceItemCount, PlaceItemInfo
|
||
end
|
||
|
||
--- 判断该代码是否满足该玩家可用的需求
|
||
---@return CanUse, PlaceCount, DecodeResType
|
||
function PlacementModeConfig.CheckPlayerCanUsePlaceCode(InCode, InPlayerKey)
|
||
local DecodeResType, PlaceItemCount, PlaceItemInfo = PlacementModeConfig.GetPlaceCodeHaveItemCont(InCode)
|
||
if DecodeResType == PlacementModeConfig.EPlaceDecodeCallback.Succeed then
|
||
local PlaceCount = 0
|
||
local CanPlace = true
|
||
for PlaceItemType, Count in pairs(PlaceItemCount) do
|
||
if CanPlace and PlacementModeConfig.GetPlayerPlaceItemCount(InPlayerKey, PlaceItemType) < Count then
|
||
CanPlace = false
|
||
end
|
||
PlaceCount = PlaceCount + PlacementModeConfig.ItemInfo[PlaceItemType].Cost * Count
|
||
end
|
||
if not CanPlace then
|
||
return false, PlaceCount, DecodeResType, PlaceItemInfo
|
||
end
|
||
if PlaceCount > PlacementModeConfig.GetPlaceMaxValue(InPlayerKey) then
|
||
return false, PlaceCount
|
||
end
|
||
return true, PlaceCount, DecodeResType, PlaceItemInfo
|
||
end
|
||
return false, 0, DecodeResType, PlaceItemInfo
|
||
end
|
||
|
||
function PlacementModeConfig.GetSimpleLineOfDefense()
|
||
if not UE.IsValid(PlacementModeConfig.SimpleLineOfDefense) then
|
||
PlacementModeConfig.SimpleLineOfDefense = UGCSystemLibrary.GetUniqueInstanceFromPath(PlacementModeConfig.LineOfDefensePath)
|
||
end
|
||
return PlacementModeConfig.SimpleLineOfDefense
|
||
end
|
||
|
||
-- 格式化坐标和旋转 ----------------------------------------------------------------------------------------------------------------------------------------------
|
||
---@param Vec FVector
|
||
PlacementModeConfig.VectorToUnitVector = function(Vec)
|
||
return {
|
||
X = KismetMathLibrary.Round(Vec.X / PlacementModeConfig.PlacingAttr.PositionSpacing),
|
||
Y = KismetMathLibrary.Round(Vec.Y / PlacementModeConfig.PlacingAttr.PositionSpacing),
|
||
Z = KismetMathLibrary.Round(Vec.Z / PlacementModeConfig.PlacingAttr.PositionSpacing),
|
||
}
|
||
end
|
||
|
||
---@param Vec FVector
|
||
PlacementModeConfig.UnitVectorToVector = function(Vec)
|
||
return {
|
||
X = Vec.X * PlacementModeConfig.PlacingAttr.PositionSpacing,
|
||
Y = Vec.Y * PlacementModeConfig.PlacingAttr.PositionSpacing,
|
||
Z = Vec.Z * PlacementModeConfig.PlacingAttr.PositionSpacing,
|
||
}
|
||
end
|
||
|
||
---@param Rot FRotator
|
||
PlacementModeConfig.RotatorToUnitRotator = function(Rot)
|
||
return {
|
||
Roll = KismetMathLibrary.Round((Rot.Roll % 360) / PlacementModeConfig.PlacingAttr.RotationSpacing),
|
||
Pitch = KismetMathLibrary.Round((Rot.Pitch % 360) / PlacementModeConfig.PlacingAttr.RotationSpacing),
|
||
Yaw = KismetMathLibrary.Round((Rot.Yaw % 360) / PlacementModeConfig.PlacingAttr.RotationSpacing),
|
||
}
|
||
end
|
||
|
||
---@param Rot FRotator
|
||
PlacementModeConfig.UnitRotatorToRotator = function(Rot)
|
||
return {
|
||
Roll = Rot.Roll * PlacementModeConfig.PlacingAttr.RotationSpacing,
|
||
Pitch = Rot.Pitch * PlacementModeConfig.PlacingAttr.RotationSpacing,
|
||
Yaw = Rot.Yaw * PlacementModeConfig.PlacingAttr.RotationSpacing,
|
||
}
|
||
end
|
||
|
||
-- 格式化坐标和旋转 End ------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
-- 单例预览材质 -------------------------------------------------------------------------------------------------------------------------------------------------
|
||
--- 获取放置时的动态材质
|
||
function PlacementModeConfig.GetPreviewDynamicMat()
|
||
if PlacementModeConfig.DynamicMaterial == nil then
|
||
local PreviewMat = UE.LoadObject(PlacementModeConfig.PreviewMatPath)
|
||
PlacementModeConfig.DynamicMaterial = KismetMaterialLibrary.CreateDynamicMaterialInstance(UGCGameSystem.GameState, PreviewMat);
|
||
end
|
||
return PlacementModeConfig.DynamicMaterial
|
||
end
|
||
|
||
--- 设置是否可放置
|
||
PlacementModeConfig.bCanPlace = true
|
||
function PlacementModeConfig.SetCanPlace(InCanPlace)
|
||
if InCanPlace ~= PlacementModeConfig.bCanPlace then
|
||
PlacementModeConfig.bCanPlace = InCanPlace
|
||
--- 设置预览放置物动态材质的颜色
|
||
if PlacementModeConfig.bCanPlace then
|
||
PlacementModeConfig.GetPreviewDynamicMat():SetVectorParameterValue("Diff_Light", PlacementModeConfig.PlacingAttr.CanPlaceColor)
|
||
else
|
||
PlacementModeConfig.GetPreviewDynamicMat():SetVectorParameterValue("Diff_Light", PlacementModeConfig.PlacingAttr.CanNotPlaceColor)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 单例预览材质 End ---------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
|
||
|
||
-- 导出/导入放置代码 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
--- 采用72进制作为编码
|
||
PlacementModeConfig.base72_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()"
|
||
PlacementModeConfig.StrToBase72 = {["0"] = 0, ["1"] = 1, ["2"] = 2, ["3"] = 3, ["4"] = 4, ["5"] = 5, ["6"] = 6, ["7"] = 7, ["8"] = 8, ["9"] = 9, ["A"] = 10, ["B"] = 11, ["C"] = 12, ["D"] = 13, ["E"] = 14, ["F"] = 15, ["G"] = 16, ["H"] = 17, ["I"] = 18, ["J"] = 19, ["K"] = 20, ["L"] = 21, ["M"] = 22, ["N"] = 23, ["O"] = 24, ["P"] = 25, ["Q"] = 26, ["R"] = 27, ["S"] = 28, ["T"] = 29, ["U"] = 30, ["V"] = 31, ["W"] = 32, ["X"] = 33, ["Y"] = 34, ["Z"] = 35, ["a"] = 36, ["b"] = 37, ["c"] = 38, ["d"] = 39, ["e"] = 40, ["f"] = 41, ["g"] = 42, ["h"] = 43, ["i"] = 44, ["j"] = 45, ["k"] = 46, ["l"] = 47, ["m"] = 48, ["n"] = 49, ["o"] = 50, ["p"] = 51, ["q"] = 52, ["r"] = 53, ["s"] = 54, ["t"] = 55, ["u"] = 56, ["v"] = 57, ["w"] = 58, ["x"] = 59, ["y"] = 60, ["z"] = 61, ["!"] = 62, ["@"] = 63, ["#"] = 64, ["$"] = 65, ["%"] = 66, ["^"] = 67, ["&"] = 68, ["*"] = 69, ["("] = 70, [")"] = 71, }
|
||
PlacementModeConfig.Base72ToStr = { [0] = "0", [1] = "1", [2] = "2", [3] = "3", [4] = "4", [5] = "5", [6] = "6", [7] = "7", [8] = "8", [9] = "9", [10] = "A", [11] = "B", [12] = "C", [13] = "D", [14] = "E", [15] = "F", [16] = "G", [17] = "H", [18] = "I", [19] = "J", [20] = "K", [21] = "L", [22] = "M", [23] = "N", [24] = "O", [25] = "P", [26] = "Q", [27] = "R", [28] = "S", [29] = "T", [30] = "U", [31] = "V", [32] = "W", [33] = "X", [34] = "Y", [35] = "Z", [36] = "a", [37] = "b", [38] = "c", [39] = "d", [40] = "e", [41] = "f", [42] = "g", [43] = "h", [44] = "i", [45] = "j", [46] = "k", [47] = "l", [48] = "m", [49] = "n", [50] = "o", [51] = "p", [52] = "q", [53] = "r", [54] = "s", [55] = "t", [56] = "u", [57] = "v", [58] = "w", [59] = "x", [60] = "y", [61] = "z", [62] = "!", [63] = "@", [64] = "#", [65] = "$", [66] = "%", [67] = "^", [68] = "&", [69] = "*", [70] = "(", [71] = ")", }
|
||
|
||
-- 十进制转换为72进制的函数
|
||
---@param n 十进制数
|
||
---@param CompletingDigits 需要补全的数字,为nil则不补全
|
||
function PlacementModeConfig.DToBase72(n, CompletingDigits)
|
||
local result = ""
|
||
if n == 0 then
|
||
result = "0"
|
||
else
|
||
local base = 72
|
||
-- UGCLogSystem.Log("[PlacementModeConfig_DToBase72] n:%s", tostring(n))
|
||
while n > 0 do
|
||
local remainder = n % base
|
||
-- UGCLogSystem.Log("[PlacementModeConfig_DToBase72]---- n:%s", tostring(n))
|
||
result = PlacementModeConfig.Base72ToStr[remainder] .. result
|
||
n = math.floor(n / base)
|
||
end
|
||
end
|
||
|
||
if CompletingDigits then
|
||
while string.len(result) < CompletingDigits do
|
||
result = "0" .. result
|
||
end
|
||
end
|
||
|
||
return result
|
||
end
|
||
|
||
-- 72进制转换为十进制的函数
|
||
function PlacementModeConfig.base72ToD(base72Str)
|
||
local Res = 0
|
||
local LenStr = string.len(base72Str)
|
||
for i = 1, LenStr, 1 do
|
||
local chr = string.sub(base72Str, LenStr - i + 1, LenStr - i + 1)
|
||
Res = Res + PlacementModeConfig.StrToBase72[chr] * 72 ^ (i - 1)
|
||
end
|
||
-- 四舍五入
|
||
return math.floor(Res + 0.5)
|
||
end
|
||
|
||
|
||
|
||
|
||
|
||
|
||
function PlacementModeConfig.PlaceCodeEncode(InMapType)
|
||
return PlacementModeConfig.PlaceCodeVersionFuncList[PlacementModeConfig.PlaceCodeVersion].Encode(InMapType)
|
||
end
|
||
|
||
--- 对放置代码进行验证并解码
|
||
---@return " EPlaceDecodeCallback, MapType, PlaceItemInfo = {PlaceItemType = PlaceItemType, UnitPos = UnitPos, UnitRot = UnitRot}"
|
||
function PlacementModeConfig.PlaceCodeDecode(PlaceCode)
|
||
local CodeLen = string.len(PlaceCode)
|
||
-- 检验字符范围是否在72个字符内
|
||
for i = 1, CodeLen do
|
||
local CodeStr = string.sub(PlaceCode, i, i)
|
||
if PlacementModeConfig.StrToBase72[CodeStr] == nil then
|
||
return PlacementModeConfig.EPlaceDecodeCallback.CharRangeError
|
||
end
|
||
end
|
||
|
||
-- 检验版本和地图的字符长度
|
||
if CodeLen < 2 or CodeLen > PlacementModeConfig.PlacingAttr.MaxPlaceCodeLen then
|
||
return PlacementModeConfig.EPlaceDecodeCallback.CodeLengthError
|
||
end
|
||
|
||
local Version = PlacementModeConfig.StrToBase72[string.sub(PlaceCode, 1, 1)]
|
||
local CodeFuncList = PlacementModeConfig.PlaceCodeVersionFuncList[Version]
|
||
|
||
-- 检验版本是否出错
|
||
if CodeFuncList == nil then
|
||
return PlacementModeConfig.EPlaceDecodeCallback.VersionError
|
||
end
|
||
|
||
return CodeFuncList.Decode(PlaceCode)
|
||
end
|
||
|
||
-- V1版本编码
|
||
--[[
|
||
地图编号1位72进制 -- 占位1位
|
||
放置物(类型1位,位置信息6位(XYZ各2位),旋转信息3位(RPY各1位)) -- 占位10位
|
||
]]
|
||
|
||
function PlacementModeConfig.PlaceCodeEncode_V01(MapType)
|
||
|
||
-- 编码版本 此函数版本为1
|
||
local ResString = PlacementModeConfig.Base72ToStr[1]
|
||
|
||
-- 地图占1位
|
||
ResString = ResString .. PlacementModeConfig.Base72ToStr[MapType]
|
||
|
||
-- 对场景中所有已激活的放置物进行编码
|
||
local SceneAllPlaceItems = GameplayStatics.GetAllActorsOfClass(UGCGameSystem.GameState, PlacementModeConfig.GetPlaceItemBaseClass(), {})
|
||
for i, v in pairs(SceneAllPlaceItems) do
|
||
-- 判断该物体是否激活
|
||
if v:GetIsPlaced() then
|
||
local AddStr = ""
|
||
-- 编码物体类型
|
||
local ItemType = v:GetPlaceItemType()
|
||
AddStr = AddStr .. PlacementModeConfig.DToBase72(ItemType)
|
||
--UGCLogSystem.Log("[PlacementModeConfig_PlaceCodeEncode_V01]_1 ResString:%s", ResString)
|
||
-- 编码物体位置和旋转
|
||
local Pos, Rot = v:GetPlacePosAndRot()
|
||
--UGCLogSystem.LogTree("[PlacementModeConfig_PlaceCodeEncode_V01] Pos", Pos)
|
||
--UGCLogSystem.LogTree("[PlacementModeConfig_PlaceCodeEncode_V01] Rot", Rot);
|
||
AddStr = AddStr .. PlacementModeConfig.DToBase72(Pos.X, 2)
|
||
AddStr = AddStr .. PlacementModeConfig.DToBase72(Pos.Y, 2)
|
||
AddStr = AddStr .. PlacementModeConfig.DToBase72(Pos.Z, 2)
|
||
--UGCLogSystem.Log("[PlacementModeConfig_PlaceCodeEncode_V01]_2 ResString:%s", ResString)
|
||
AddStr = AddStr .. PlacementModeConfig.DToBase72(Rot.Roll)
|
||
AddStr = AddStr .. PlacementModeConfig.DToBase72(Rot.Pitch)
|
||
AddStr = AddStr .. PlacementModeConfig.DToBase72(Rot.Yaw)
|
||
--UGCLogSystem.Log("[PlacementModeConfig_PlaceCodeEncode_V01]_3 ResString:%s", ResString)
|
||
ResString = ResString .. AddStr
|
||
UGCLogSystem.Log("[PlacementModeConfig_PlaceCodeEncode_V01]_4 Len:%d, AddStr:%s",string.len(AddStr), AddStr)
|
||
UGCLogSystem.Log("[PlacementModeConfig_PlaceCodeEncode_V01]_5 Len:%d, ResString:%s",string.len(ResString), ResString)
|
||
end
|
||
end
|
||
|
||
return ResString
|
||
end
|
||
|
||
|
||
-- V1版本解码
|
||
--[[
|
||
地图编号1位72进制 -- 占位1位
|
||
放置物(类型1位,位置信息6位(XYZ各2位),旋转信息3位(RPY各1位)) -- 占位10位
|
||
]]
|
||
function PlacementModeConfig.PlaceCodeDecode_V01(PlaceCode)
|
||
local LenPlaceCode = string.len(PlaceCode)
|
||
UGCLogSystem.Log("[PlacementModeConfig_PlaceCodeDecode_V01] LenPlaceCode:%s", tostring(LenPlaceCode))
|
||
|
||
-- 验证长度
|
||
if ((LenPlaceCode - 2) % 10) ~= 0 then
|
||
return PlacementModeConfig.EPlaceDecodeCallback.CodeLengthError
|
||
end
|
||
|
||
local Index = 2
|
||
local ReadCodeStr = function(InNum)
|
||
local Res = string.sub(PlaceCode, Index, Index + (InNum - 1))
|
||
Index = Index + InNum
|
||
return Res
|
||
end
|
||
|
||
local MapType = PlacementModeConfig.StrToBase72[ReadCodeStr(1)]
|
||
-- 验证Map类型是否符合
|
||
if PlacementModeConfig.MapInfo[MapType] == nil then
|
||
return PlacementModeConfig.EPlaceDecodeCallback.MapCodeError
|
||
end
|
||
|
||
-- 可放置范围
|
||
local MapPlacingRange = PlacementModeConfig.MapInfo[MapType].MapPlacingRange
|
||
|
||
local ResPlaceItemInfo = {}
|
||
for i = 1, math.floor((LenPlaceCode - 2) / 10 + 0.5) do
|
||
local PlaceItemType = PlacementModeConfig.base72ToD(ReadCodeStr(1))
|
||
if PlacementModeConfig.ItemInfo[PlaceItemType] == nil then
|
||
return PlacementModeConfig.EPlaceDecodeCallback.PlaceItemTypeError
|
||
end
|
||
local UnitX = PlacementModeConfig.base72ToD(ReadCodeStr(2))
|
||
local UnitY = PlacementModeConfig.base72ToD(ReadCodeStr(2))
|
||
local UnitZ = PlacementModeConfig.base72ToD(ReadCodeStr(2))
|
||
|
||
-- 检验放置范围是否异常
|
||
if UnitX > MapPlacingRange.X or UnitY > MapPlacingRange.Y or UnitZ > MapPlacingRange.Z then
|
||
return PlacementModeConfig.EPlaceDecodeCallback.PlacePosRangeError
|
||
end
|
||
|
||
local UnitPos = {X = UnitX, Y = UnitY, Z = UnitZ}
|
||
local UnitRot = {
|
||
Roll = PlacementModeConfig.StrToBase72[ReadCodeStr(1)],
|
||
Pitch = PlacementModeConfig.StrToBase72[ReadCodeStr(1)],
|
||
Yaw = PlacementModeConfig.StrToBase72[ReadCodeStr(1)]
|
||
}
|
||
ResPlaceItemInfo[#ResPlaceItemInfo + 1] = {PlaceItemType = PlaceItemType, UnitPos = UnitPos, UnitRot = UnitRot}
|
||
end
|
||
|
||
return PlacementModeConfig.EPlaceDecodeCallback.Succeed, MapType, ResPlaceItemInfo
|
||
end
|
||
|
||
-- 开头为编码的版号 -- 占位1位
|
||
PlacementModeConfig.PlaceCodeVersionFuncList = {
|
||
[1] = {Encode = PlacementModeConfig.PlaceCodeEncode_V01, Decode = PlacementModeConfig.PlaceCodeDecode_V01},
|
||
}
|
||
|
||
-- 导出/导入放置代码 End ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|