From e0d7329905d74095190107bacc790521f69b9811 Mon Sep 17 00:00:00 2001 From: wyatt Date: Sat, 18 Oct 2025 04:37:34 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E8=BF=87GAS=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=8B=90=E7=8B=B8=E7=9A=84=E6=8A=80=E8=83=BD=EF=BC=8C=E8=BF=98?= =?UTF-8?q?=E5=B7=AE=E7=A2=B0=E6=92=9E=E3=80=81=E5=8F=82=E6=95=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=8C=96=E3=80=81=E6=B6=88=E8=80=97=E5=92=8C=E5=86=B7?= =?UTF-8?q?=E5=8D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Config/DefaultGameplayTags.ini | 5 + .../BP_BusyLevelPlayerController.uasset | Bin 21929 -> 22353 bytes .../GameMode/BP_BusyLevelPlayerState.uasset | Bin 21506 -> 21351 bytes .../Input/Level/IMC_PlayerInputContext.uasset | Bin 9051 -> 9051 bytes Content/Data/Level/LevelRoleBaseConfig.uasset | Bin 2771 -> 2962 bytes .../Ability/Role/Fox/GA_FoxUltimate.uasset | Bin 0 -> 21842 bytes .../Gas/Effects/Role/Fox/GE_Accelerate.uasset | Bin 0 -> 13667 bytes .../Effects/Role/Fox/GE_UltimateRecast.uasset | Bin 0 -> 7622 bytes Content/Lua/@types/BusyGameplayLibrary.d.lua | 1 + Content/Lua/@types/UE.d.lua | 7 + .../Lua/Gas/Ability/Common/MoveAbility.lua | 4 + .../Lua/Gas/Ability/Role/Fox/FoxUltimate.lua | 153 ++++++++++++++++++ .../Ability/Role/Rabbit/RabbitUltimate.lua | 4 + Content/Resource/Spine/Role/Fox/Fox.uasset | Bin 3287 -> 3287 bytes .../Resource/Spine/Role/Fox/FoxData.uasset | Bin 6732 -> 6688 bytes .../Spine/Role/Fox/Textures/Fox.uasset | Bin 122616 -> 122616 bytes .../Private/BusyGameplayLibrary.cpp | 17 ++ .../AbilitySystemComponentBinding.cpp | 27 ++++ .../Private/CppBindings/DataTableBindings.cpp | 37 +---- .../Private/Gas/BusyGameAbility.cpp | 33 ++++ .../Private/Level/Actor/BusyPawnBase.cpp | 42 +++-- .../Private/Level/Actor/BusyPlayerRole.cpp | 49 ++---- .../Actor/Components/BusyPawnMovement.cpp | 34 +++- .../Private/Level/LevelPlayerController.cpp | 34 ++++ .../BusyRabbit/Public/BusyGameplayLibrary.h | 8 + .../BusyRabbit/Public/Gas/BusyGameAbility.h | 30 ++++ .../Public/Level/Actor/BusyPawnBase.h | 12 +- .../Public/Level/Actor/BusyPlayerRole.h | 3 +- .../Components/BusyAbilitySystemComponent.h | 2 +- .../Level/Actor/Components/BusyPawnMovement.h | 30 +++- .../Public/Level/LevelPlayerController.h | 35 +++- 31 files changed, 465 insertions(+), 102 deletions(-) create mode 100644 Content/Gas/Ability/Role/Fox/GA_FoxUltimate.uasset create mode 100644 Content/Gas/Effects/Role/Fox/GE_Accelerate.uasset create mode 100644 Content/Gas/Effects/Role/Fox/GE_UltimateRecast.uasset create mode 100644 Content/Lua/Gas/Ability/Common/MoveAbility.lua create mode 100644 Content/Lua/Gas/Ability/Role/Fox/FoxUltimate.lua create mode 100644 Content/Lua/Gas/Ability/Role/Rabbit/RabbitUltimate.lua create mode 100644 Source/BusyRabbit/Private/CppBindings/AbilitySystemComponentBinding.cpp create mode 100644 Source/BusyRabbit/Private/Gas/BusyGameAbility.cpp create mode 100644 Source/BusyRabbit/Public/Gas/BusyGameAbility.h diff --git a/Config/DefaultGameplayTags.ini b/Config/DefaultGameplayTags.ini index e1885d6..017d2ed 100644 --- a/Config/DefaultGameplayTags.ini +++ b/Config/DefaultGameplayTags.ini @@ -8,11 +8,14 @@ FastReplication=False InvalidTagCharacters="\"\'," NumBitsForContainerSize=6 NetIndexFirstBitSegment=16 ++GameplayTagList=(Tag="Ability.Block.UltimatePlaying",DevComment="大招正在释放中") ++GameplayTagList=(Tag="Ability.Flags.Recast",DevComment="可以再次释放技能的标记") +GameplayTagList=(Tag="Ability.Role.AttributeConsume",DevComment="角色属性损耗debuff") +GameplayTagList=(Tag="Ability.Role.EatFood",DevComment="干饭") +GameplayTagList=(Tag="Ability.Role.Pick",DevComment="角色采集物品") +GameplayTagList=(Tag="Ability.Role.Recover",DevComment="角色状态恢复技能") +GameplayTagList=(Tag="Ability.Role.Roll",DevComment="角色无敌翻滚") ++GameplayTagList=(Tag="Ability.Role.Ultimate",DevComment="角色大招") +GameplayTagList=(Tag="Buff.Indispersible.HungerConsume",DevComment="饥饿值消耗,不可被驱散") +GameplayTagList=(Tag="Buff.RoleConsume.Health",DevComment="角色因饥饿掉血的debuff") +GameplayTagList=(Tag="Buff.RoleConsume.Hunger",DevComment="角色每秒钟的饥饿消耗") @@ -25,6 +28,8 @@ NetIndexFirstBitSegment=16 +GameplayTagList=(Tag="CookProcess.Diced",DevComment="切丁") +GameplayTagList=(Tag="CookProcess.Mashed",DevComment="切泥") +GameplayTagList=(Tag="CookProcess.Sliced",DevComment="切片操作") ++GameplayTagList=(Tag="Effect.Duration",DevComment="效果的持续时长") ++GameplayTagList=(Tag="Effect.Factor",DevComment="效果的乘法系数") +GameplayTagList=(Tag="GameItem.Building",DevComment="建筑物") +GameplayTagList=(Tag="GameItem.Food",DevComment="游戏内的可食用物品") +GameplayTagList=(Tag="Ingredient",DevComment="烹饪食材") diff --git a/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerController.uasset b/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerController.uasset index b55e2a41345739e3a9b04e0402b180828b05548d..ed262c6ed4c95d75b63ab6d066e64d9f7b37aad9 100644 GIT binary patch delta 4773 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 N>6aqmhUB&GzX5;dG0Fe{ diff --git a/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerState.uasset b/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerState.uasset index 275078bb4cd1d67c8c09aa4e998a31444a696dd6..66b284b55196a9bd87f5980e84e7208a3aff9680 100644 GIT binary patch delta 1140 zcmZ{jT}TvB6vxk<)lJK_UDNf!P-JSR)U?uws9kmaSW6dM1?kJwK2}Xrd+8-8h=Bnaql)4|JX~G3phO1eU??g`8NUM#stsvj1s-1~w#*Sotx!VNs zjupzUL=M}?5gTc=krOu3Wh328b}a3MpB0k(DwdJMA(^+!$g4lbm7)`?-MXt&at;S2 zA8_k5`^BwiTW9&ZvRS+T#zK$EKS4N@iDx}|+AnG!BVUvP9F<8T#n&?bT!Mq%O#I;4 z<86^>7sW1_KP$y;K^>b?GV)JJG;Qg~KSMS?#<0m|o-QU*G8`W?=b%Qo#k+bADYsof~=a?D5?XcOsJ5ALlEpk3H-Q-J) z8JF@`i}E*Vs`!Zxuc}1r%=%jI6H$P!bf0rKov{g@u|K^?U&SXk981Ptzbaxz)IY0; z7(OU%5L4&~P(ljZMtP3h%7hEvdjo1Hn>~9bk%4|qw-zLd@n8PLj@TY)ThSr zgMzsM7T*Z6Xx#!&H_dn9KPl$)cBRs^hybc zNs@C$BPD!>bZ8mqyCNB5xur0K(%%{>{qj1{)%jD3w7wM5Y!aV_R+~eR${=W)>x*dE`PWCJbd=YG7fX_gyn92V_uUH5z-Z%qJ46i^) ztTZfRhHqF*#q}UxhGp*rpO?pd6CA^E-USRW?n{yV1z)&f9>w`!vFE^EDO>J4vZB(b TMVT=MdgNpXyOZUxzmfk3c8NPl diff --git a/Content/Data/Input/Level/IMC_PlayerInputContext.uasset b/Content/Data/Input/Level/IMC_PlayerInputContext.uasset index 384d22c5348eef4a9a5029d8ff5e049ff4b0dee3..b510dc7bab4cb390c8d23b97af89e85178a80511 100644 GIT binary patch delta 27 lcmV+$0ObGMM%zY^%Mg=*q+8FG;zp1LLAO4#TKlovfFjCV4ov_6 delta 27 jcmccZcH3>jX@PLVr1;ZC_k7mLc2uhW`pC5Lc7qZCydn*3 diff --git a/Content/Data/Level/LevelRoleBaseConfig.uasset b/Content/Data/Level/LevelRoleBaseConfig.uasset index e70f4bb1e80e76cc2177127dfe5a34a112475852..8c0ee63e1d48ec3c80d4659b1dace13f966d9521 100644 GIT binary patch delta 664 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 KpR02U`2Pzip|_O) literal 0 HcmV?d00001 diff --git a/Content/Lua/@types/BusyGameplayLibrary.d.lua b/Content/Lua/@types/BusyGameplayLibrary.d.lua index 6d7ddee..15f0fe0 100644 --- a/Content/Lua/@types/BusyGameplayLibrary.d.lua +++ b/Content/Lua/@types/BusyGameplayLibrary.d.lua @@ -1,3 +1,4 @@ --- @class BusyGameplayLibrary --- @field K2_GetWorld fun(obj:table):table +--- @field RequestGameplayTag fun(TagName:string):GameplayTag local BusyGameplayLibrary = {} \ No newline at end of file diff --git a/Content/Lua/@types/UE.d.lua b/Content/Lua/@types/UE.d.lua index 9b37218..faa53ab 100644 --- a/Content/Lua/@types/UE.d.lua +++ b/Content/Lua/@types/UE.d.lua @@ -29,7 +29,14 @@ KismetSystemLibrary = { } +--- @class GameplayTag +local GameplayTag + --- @class GameplayStatics --- @field GetPlayerController fun(uobj:table,idx:number):table --- @field GetGameState fun(uobj:table):table local GameplayStatics + +--- @class AbilitySystemBlueprintLibrary +--- @field AssignTagSetByCallerMagnitude fun(SpecHandle:table, DataTag:GameplayTag, Magnitude:number) +local AbilitySystemBlueprintLibrary diff --git a/Content/Lua/Gas/Ability/Common/MoveAbility.lua b/Content/Lua/Gas/Ability/Common/MoveAbility.lua new file mode 100644 index 0000000..72d69ca --- /dev/null +++ b/Content/Lua/Gas/Ability/Common/MoveAbility.lua @@ -0,0 +1,4 @@ +local MoveAbility = {} + + +return Class(nil, nil, MoveAbility) \ No newline at end of file diff --git a/Content/Lua/Gas/Ability/Role/Fox/FoxUltimate.lua b/Content/Lua/Gas/Ability/Role/Fox/FoxUltimate.lua new file mode 100644 index 0000000..0d4d74b --- /dev/null +++ b/Content/Lua/Gas/Ability/Role/Fox/FoxUltimate.lua @@ -0,0 +1,153 @@ +local GameplayStatics = import("GameplayStatics") +local AbilitySystemBlueprintLibrary = import("AbilitySystemBlueprintLibrary") +local BusyGameplayLibrary = import("BusyGameplayLibrary") + +--- @class FoxUltimate +--- @field RecastWindow number +local FoxUltimate = {} + + +function FoxUltimate:ctor() + self.ultimate_phase = 1 -- 大招阶段 + self.active_recast_handle = nil + self.active_accelerate_handle = nil +end + + +function FoxUltimate:K2_ActivateAbilityFromEvent(EventData) + print("FoxUltimate:K2_ActivateAbilityFromEvent", self.ultimate_phase) + + local owner = self:GetOwningActorFromActorInfo() + self.movement = owner.MovementComponent + self.animation = owner.SpineAnimationComponent + self.asc = AbilitySystemBlueprintLibrary.GetAbilitySystemComponent(owner) + self.recast_tag = BusyGameplayLibrary.RequestGameplayTag("Ability.Flags.Recast") + + local asc = self.asc + + if self.ultimate_phase == 1 or asc:HasMatchingGameplayTag(self.recast_tag) then + print("triggered") + self:TriggerUltimate(asc) + else + self:K2_EndAbility() + end + + +end + +function FoxUltimate:TriggerUltimate(asc) + if self.ultimate_phase == 1 then + -- 第一次释放大招,添加一个可以再次释放的Tag + local _, recast_effect = self:GetAbilityEffectSpecHandle("Recast", asc, 1, nil) + self.active_recast_handle = asc:BP_ApplyGameplayEffectSpecToSelf(recast_effect) + elseif self.ultimate_phase == 2 then + -- 第二次激活,移除可重复释放的tag + self.asc:RemoveActiveGameplayEffect(self.active_recast_handle, -1) + local _, recast_effect = self:GetAbilityEffectSpecHandle("Recast", asc, 1, nil) + self.active_recast_handle = asc:BP_ApplyGameplayEffectSpecToSelf(recast_effect) + elseif self.ultimate_phase == 3 then + self.asc:RemoveActiveGameplayEffect(self.active_recast_handle, -1) + end + + -- 播放动画,并监听动画完成的事件 + self:PlayAnimation() +end + + +function FoxUltimate:GetAnimationName(direction) + local animation_name_prefix + if direction.X >= 0 then + animation_name_prefix = "Ultimate/Right/" + else + animation_name_prefix = "Ultimate/Left/" + end + + if self.ultimate_phase == 1 then + return animation_name_prefix .. "UltimateStage1" + elseif self.ultimate_phase == 2 then + return animation_name_prefix .. "UltimateStage2" + elseif self.ultimate_phase == 3 then + return animation_name_prefix .. "UltimateStage3" + end + return nil +end + + +function FoxUltimate:K2_OnEndAbility(bWasCancelled) + print("FoxUltimate:K2_OnEndAbility") +end + + +function FoxUltimate:GetSprintSpeedFactor() + if self.ultimate_phase == 1 then + return 2.5 + elseif self.ultimate_phase == 2 then + return 2.8 + elseif self.ultimate_phase == 3 then + return 3.0 + end +end + +function FoxUltimate:PlayAnimation() + + local animation = self.animation + local PC = GameplayStatics.GetPlayerController(self, 0) + + local result, ability_direction = PC:GetCursorDirection(nil) -- 获取技能的朝向 + if not result then + print("FoxUltimate:TriggerPrimaryPhase can't find direction") + return + end + local anim_name = self:GetAnimationName(ability_direction) -- 获取技能动画名称 + if not anim_name then + print("FoxUltimate:TriggerPrimaryPhase can't get animation", self.ultimate_phase) + return + end + + local anim_entry = animation:SetAnimation(0, anim_name, false) + anim_entry.AnimationComplete:Add(function(entry) self:OnAnimationComplete(entry) end) + anim_entry.AnimationEvent:Add(function(entry, event) self:OnAnimationEvent(entry, event) end) + + local anim_total_time = anim_entry:GetAnimationEnd() -- 获取技能动画时长 + + -- 附加加速buff + self:MakeAccelerate(self:GetSprintSpeedFactor(), anim_total_time) + self.movement:ActivateSprint(ability_direction, anim_total_time) +end + + +function FoxUltimate:MakeAccelerate(speed_factor, total_time) + local _, accelerate_effect = self:GetAbilityEffectSpecHandle("Accelerate", self.asc, 1, nil) + AbilitySystemBlueprintLibrary.AssignTagSetByCallerMagnitude( + accelerate_effect, + BusyGameplayLibrary.RequestGameplayTag("Effect.Factor"), + speed_factor + ) + + AbilitySystemBlueprintLibrary.AssignTagSetByCallerMagnitude( + accelerate_effect, + BusyGameplayLibrary.RequestGameplayTag("Effect.Duration"), + total_time + ) + return self.asc:BP_ApplyGameplayEffectSpecToSelf(accelerate_effect) +end + + +function FoxUltimate:OnAnimationComplete(entry) + self.ultimate_phase = self.ultimate_phase + 1 + entry.AnimationComplete:Clear() + entry.AnimationEvent:Clear() + self:K2_EndAbility() +end + +function FoxUltimate:OnAnimationEvent(entry, event) + if event.Name == "OnSpeedChange" then + self.active_accelerate_handle = self:MakeAccelerate(8.0, 0.5) + elseif event.Name == "OnSpeedReset" then + self.asc:RemoveActiveGameplayEffect(self.active_accelerate_handle, -1) + end +end + + + +return Class(nil, nil, FoxUltimate) \ No newline at end of file diff --git a/Content/Lua/Gas/Ability/Role/Rabbit/RabbitUltimate.lua b/Content/Lua/Gas/Ability/Role/Rabbit/RabbitUltimate.lua new file mode 100644 index 0000000..baad620 --- /dev/null +++ b/Content/Lua/Gas/Ability/Role/Rabbit/RabbitUltimate.lua @@ -0,0 +1,4 @@ +local RabbitUltimate = {} + + +return Class(nil, nil, RabbitUltimate) \ No newline at end of file diff --git a/Content/Resource/Spine/Role/Fox/Fox.uasset b/Content/Resource/Spine/Role/Fox/Fox.uasset index 8372f7d6d0bdd53881b90f0293026fd57d41cb5b..2e01784e8d65a6ead0e092682f07714cdb1b136c 100644 GIT binary patch delta 27 jcmcaEd0leCWr6l-nrhEqS$oV+-n4OIWw!Um$6vSsyE_fc delta 27 jcmcaEd0leCWr4$7s<-4{g}LvWqRsKA|6%;b$6vSswUP~~ diff --git a/Content/Resource/Spine/Role/Fox/FoxData.uasset b/Content/Resource/Spine/Role/Fox/FoxData.uasset index bff54a54d4e5ce53cfde07289d1b671d907b58e1..7bf38b4bf160261006e98bc7efdafc306551f5de 100644 GIT binary patch delta 133 zcmX?OvcP1*b%EyxX084oSmnH}bJI={2Gy$*pBKozkz_yt|A8Qooq>S|DEdKib19=S z3**|!D_OmnRtioIWEG#Bz{;^%lr4ivP(cu=Lk delta 167 zcmZ2ra>iuBbphYCch=QTzv|m+-er`({;21~=LK>SQVb~IKM(}6GcfP~MP;Nmmogf& zFy5TJlGU5(s^H{6R`JORtQ?y~*)o^}eFT9@Jb=V9Mvs-(tQ`$E_i-fi@UVf5V*(Kj g43ithby)2~L&KOSzY$g5Y%S`_ghPJwa`8$g02^E?NdN!< diff --git a/Content/Resource/Spine/Role/Fox/Textures/Fox.uasset b/Content/Resource/Spine/Role/Fox/Textures/Fox.uasset index ffb672b00b37927f65c7347167eb5185c82c0522..8e2127c5d1cd75aef431a3d49c9aa9373c8ae2ae 100644 GIT binary patch delta 102 zcmeydm;J|H_6;nI0{tN|3#Kktb82|3<}7q2a{6Ww#%dJ~GXryDLt{&m$s8Jfo1dym zGr>hRb7)9%Fd9x)GAL!V+&se|l2>4zsFi1Bw~5q delta 102 zcmeydm;J|H_6;nI0v0simc{k+HeKWDX6#%}-UO zncyOuIW#0W7!4*X8I&@bY@T5d$t&(TEXT("CookMaterialStateConfig"), RowName, RowData); } + +FGameplayTag UBusyGameplayLibrary::RequestGameplayTag(const FName& TagName) +{ + return FGameplayTag::RequestGameplayTag(TagName); +} + +#pragma optimize("",off) +FGameplayTagContainer UBusyGameplayLibrary::RequestGameplayTags(const TArray& TagNames) +{ + TArray GameplayTags; + for (const FName& TagName : TagNames) + { + GameplayTags.Add(FGameplayTag::RequestGameplayTag(TagName)); + } + return FGameplayTagContainer::CreateFromArray(GameplayTags); +} +#pragma optimize("",on) diff --git a/Source/BusyRabbit/Private/CppBindings/AbilitySystemComponentBinding.cpp b/Source/BusyRabbit/Private/CppBindings/AbilitySystemComponentBinding.cpp new file mode 100644 index 0000000..2601650 --- /dev/null +++ b/Source/BusyRabbit/Private/CppBindings/AbilitySystemComponentBinding.cpp @@ -0,0 +1,27 @@ +#include "LuaCppBinding.h" +#include "AbilitySystemComponent.h" +#include "GameplayTagContainer.h" +using slua::lua_State, slua::LuaObject, slua::LuaStruct; +using namespace slua; + + +#pragma optimize( "", off ) + + +bool HasMatchingGameplayTag(const UAbilitySystemComponent& Asc, const FName& TagName) +{ + // return Asc.HasMatchingGameplayTag(FGameplayTag::RequestGameplayTag(TagName)); + return true; +} + + +extern void RegisterAbilitySystemComponentExtension() { + REG_EXTENSION_METHOD_LAMBDA(UAbilitySystemComponent, "AHasMatchingGameplayTag", false, + [](UAbilitySystemComponent* ASC, const FName& Tag) -> bool { + return true; + } + ); +} + +#pragma optimize( "", on) + diff --git a/Source/BusyRabbit/Private/CppBindings/DataTableBindings.cpp b/Source/BusyRabbit/Private/CppBindings/DataTableBindings.cpp index 63fbf44..5752890 100644 --- a/Source/BusyRabbit/Private/CppBindings/DataTableBindings.cpp +++ b/Source/BusyRabbit/Private/CppBindings/DataTableBindings.cpp @@ -1,30 +1,6 @@ #include "LuaCppBinding.h" - using namespace slua; -//static int LuaBinding_FindRow(lua_State* L) { -// UDataTable* DataTable = LuaObject::checkUD(L, 1); -// FName RowName = LuaObject::checkValue(L, 2); -// -// UScriptStruct* RowStruct = (UScriptStruct*)DataTable->GetRowStruct(); -// -// uint8* RowData = DataTable->FindRowUnchecked(RowName); -// -// if (RowData && RowStruct) { -// // LuaStruct װ -// uint32 size = RowStruct->GetStructureSize() ? RowStruct->GetStructureSize() : 1; -// uint8* buf = (uint8*)FMemory::Malloc(size); -// RowStruct->InitializeStruct(buf); -// RowStruct->CopyScriptStruct(buf, RowData); -// -// LuaStruct* ls = new LuaStruct(); -// ls->Init(buf, size, RowStruct, false); -// return LuaObject::push(L, ls); -// } -// else { -// return LuaObject::pushNil(L); -// } -//} static int LuaBinding_FindRow(lua_State* L) { UDataTable* DataTable = LuaObject::checkUD(L, 1); @@ -37,24 +13,13 @@ static int LuaBinding_FindRow(lua_State* L) { LuaStruct* luaStruct = new LuaStruct(); luaStruct->Init((uint8*)TableRow, rowStruct->GetStructureSize(), (UScriptStruct*)rowStruct, true); - LuaObject::addLink(L, TableRow); // ȷ + LuaObject::addLink(L, TableRow); //auto ret = LuaObject::push(L, luaStruct); return LuaObject::pushReference(L, luaStruct, TableRow); } -//FTableRowBase* tableRow = DataTable->FindRow(RowName, TEXT("")); -// -//UScriptStruct* rowStruct = DataTable->GetRowStruct(); -// -//LuaStruct* luaStruct = new LuaStruct(); -//luaStruct->Init((uint8*)tableRow, rowStruct->GetStructureSize(), rowStruct, true); -// -//int ret = LuaObject::push(L, luaStruct); - - - extern void RegisterDataTableExtension() { REG_EXTENSION_METHOD_IMP(UDataTable, "FindRow", { return LuaBinding_FindRow(L); }); } diff --git a/Source/BusyRabbit/Private/Gas/BusyGameAbility.cpp b/Source/BusyRabbit/Private/Gas/BusyGameAbility.cpp new file mode 100644 index 0000000..d1ec3f0 --- /dev/null +++ b/Source/BusyRabbit/Private/Gas/BusyGameAbility.cpp @@ -0,0 +1,33 @@ +#include "Gas/BusyGameAbility.h" +#include "AbilitySystemBlueprintLibrary.h" +#include "AbilitySystemComponent.h" + +UBusyGameAbility::UBusyGameAbility() +{ + bHasBlueprintActivateFromEvent = true; +} + +FString UBusyGameAbility::GetLuaFilePath_Implementation()const +{ + return LuaFilePath; +} + +bool UBusyGameAbility::GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level, + FGameplayEffectSpecHandle& Handle) const +{ + // 1. 查找对应的GameplayEffectClass + const TSubclassOf *EffectClass = AbilityEffects.Find(EffectName); + if (!EffectClass) return false; + + // 2. 创建并设置GameplayEffect上下文 + FGameplayEffectContextHandle EffectContextHandle = Asc->MakeEffectContext(); + + // 3. 将当前对象设置为效果来源 + EffectContextHandle.AddSourceObject(this); + + // 4. 创建GameplayEffectSpecHandle + Handle = Asc->MakeOutgoingSpec(*EffectClass, 1.f, EffectContextHandle); // 这里的1.f是等级 + + return Handle.IsValid(); +} + diff --git a/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp b/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp index c238cd2..a871dad 100644 --- a/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp @@ -1,8 +1,12 @@ #include "Level/Actor/BusyPawnBase.h" + +#include "BusyGameplayLibrary.h" #include "Components/SphereComponent.h" #include "SpineSkeletonRendererComponent.h" #include "SpineSkeletonAnimationComponent.h" +#include "Gas/BusyGameAbility.h" #include "Level/Actor/Components/BusyPawnMovement.h" +#include "Tables/BusyPawnConfig.h" DEFINE_LOG_CATEGORY(LogBusyPawn) @@ -30,38 +34,46 @@ void ABusyPawnBase::BeginPlay() { Super::BeginPlay(); - // for (UClass* AbilityClass : Row->DefaultAbilities) { - // if (AbilityClass) { - // AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(AbilityClass)); - // } - // } + if (const UDataTable* DataTable = UBusyGameplayLibrary::GetGameDataTable("LevelRoleBaseConfig")) + { + const FBusyPawnBaseConfig* Config = DataTable->FindRow( + PawnName, FString::Printf(TEXT("ABusyPawnBase::BeginPlay Find %s in LevelRoleBaseConfig"), *PawnName.ToString()) + ); + if (Config) + { + InitPawnAbilities(*+Config); + InitPawnAttributes(*Config); + } + } } float ABusyPawnBase::GetSpeed_Implementation()const { - if (Attribute) + if (Attributes) { - return Attribute->GetMoveSpeed(); + return Attributes->GetMoveSpeed(); } return 0.f; } -void ABusyPawnBase::InitMoveSpeed(const float MoveSpeed)const +void ABusyPawnBase::InitPawnAttributes(const FBusyPawnBaseConfig& Config) { - if (Attribute) + if (Attributes) { - Attribute->InitMoveSpeed(MoveSpeed); + Attributes->InitHealth(Config.Health); + Attributes->InitMaxHealth(Config.Health); + Attributes->InitMoveSpeed(Config.MoveSpeed); + Attributes->InitDamage(Config.Damage); + Attributes->InitDefense(Config.Defense); } } -void ABusyPawnBase::InitHealth(const float Health, const float MaxHealth) const +void ABusyPawnBase::InitPawnAbilities(const FBusyPawnBaseConfig& Config)const { - if (Attribute) + for (const TSubclassOf& Ability : Config.DefaultAbilities) { - Attribute->InitHealth(Health); - Attribute->InitMaxHealth(MaxHealth); + AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(Ability)); } } - diff --git a/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp b/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp index 07bec3d..dfad955 100644 --- a/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp @@ -19,46 +19,31 @@ ABusyPlayerRole::ABusyPlayerRole() SpringArmComponent->SetRelativeRotation(FRotator(0, -90.0, 0.0)); - Attribute = CreateDefaultSubobject(TEXT("Attribute")); - - InitMoveSpeed(200); - InitHealth(100, 100); + Attributes = CreateDefaultSubobject(TEXT("Attribute")); } void ABusyPlayerRole::BeginPlay() { Super::BeginPlay(); - InitRoleAttributes(); } -bool ABusyPlayerRole::InitRoleAttributes() +void ABusyPlayerRole::InitPawnAttributes(const struct FBusyPawnBaseConfig& Config) { - if (!PawnName.IsValid()) return false; - const UDataTable* ConfigTable = UBusyGameplayLibrary::GetGameDataTable(TEXT("LevelRoleBaseConfig")); - if (!ConfigTable) - { - UE_LOG(LogBusyPawn, Log, TEXT("ABusyPlayerRole::InitRoleAttributes Can't find config table: LevelRoleBaseConfig")) - return false; - } - - const FBusyRoleBaseConfig* Result = ConfigTable->FindRow( - PawnName, - *FString::Printf(TEXT("ABusyPlayerRole::InitRoleAttributes, PawnName: %ls"), *PawnName.ToString()) - ); - if (Result) - { - UBusyPlayerRoleAttributeSet* RoleAttributes = Cast(Attribute); - RoleAttributes->InitHealth(Result->Health); - RoleAttributes->InitMaxHealth(Result->Health); - RoleAttributes->InitMoveSpeed(Result->MoveSpeed); - - RoleAttributes->InitHunger(Result->Hunger); - RoleAttributes->InitMaxHunger(Result->Hunger); - RoleAttributes->InitHungerConsume(Result->HungerConsume); + Super::InitPawnAttributes(Config); + UBusyPlayerRoleAttributeSet* RoleAttributes = Cast(Attributes); - RoleAttributes->InitDamage(Result->Damage); - RoleAttributes->InitDefense(Result->Defense); - return true; + if (RoleAttributes && Config.StaticStruct() == FBusyRoleBaseConfig::StaticStruct()) + { + const FBusyRoleBaseConfig* RoleConfig = static_cast(&Config); + RoleAttributes->InitHunger(RoleConfig->Hunger); + RoleAttributes->InitMaxHunger(RoleConfig->Hunger); + RoleAttributes->InitHungerConsume(RoleConfig->HungerConsume); + } + else + { + UE_LOG(LogBusyPawn, Warning, TEXT("ABusyPlayerRole::InitPawnAttributes Failed, RoleAttribute: %p, ConfigName: %s"), + RoleAttributes, *Config.StaticStruct()->GetFName().ToString() + ); } - return false; } + diff --git a/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp b/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp index 87a8aeb..2cdcd2d 100644 --- a/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp @@ -24,6 +24,22 @@ void UBusyPawnMovement::SprintTo(const float Distance, const float SpeedRate) } } +void UBusyPawnMovement::ActivateSprint(const FVector2D& Direction, const float TotalTime) +{ + SprintSpeed = 0.f; + SprintDirection = Direction; + SprintTotalTime = SprintRemainTime = TotalTime; + BusyMoveState = EBusyMoveState::Sprint; +} + +void UBusyPawnMovement::ActivateSprintWithSpeed(const FVector2D& Direction, const float TotalTime, const float Speed) +{ + SprintSpeed = Speed; + SprintDirection = Direction; + SprintTotalTime = SprintRemainTime = TotalTime; + BusyMoveState = EBusyMoveState::Sprint; +} + FVector2D UBusyPawnMovement::GetMoveDirection()const { if (AActor *Owner = GetOwner()) @@ -119,14 +135,24 @@ void UBusyPawnMovement::SprintTick(const float DeltaTime) const FVector CurrentLocation = Owner->GetActorLocation(); const FVector2D CurrentLocation2D = FVector2D(CurrentLocation); - const float MoveDistance = DeltaTime * Movable->Execute_GetSpeed(Owner) * SprintSpeedRate; - const FVector2D NewLocation = CurrentLocation2D + ForwardDirection * MoveDistance; + float SprintDeltaTime = DeltaTime; + if (SprintRemainTime <= DeltaTime) + { + SprintDeltaTime = SprintRemainTime; + SprintRemainTime = 0.f; + } + else + { + SprintRemainTime -= DeltaTime; + } + const float MoveDistance = SprintDeltaTime * (SprintSpeed == 0.f ? Movable->Execute_GetSpeed(Owner) : SprintSpeed); + const FVector2D NewLocation = CurrentLocation2D + SprintDirection * MoveDistance; Owner->SetActorLocation(FVector(NewLocation, CurrentLocation.Z), true); - if (FVector2D::Distance(NewLocation, SprintStartLocation) >= SprintDistance) + if (SprintRemainTime == 0.f) { - BusyMoveState = EBusyMoveState::None; // 这里不对,需要栈来做 + BusyMoveState = EBusyMoveState::None; } } diff --git a/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp b/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp index 9019da8..3dca737 100644 --- a/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp +++ b/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp @@ -1,5 +1,6 @@ #include "Level/LevelPlayerController.h" #include "Level/Actor/BusyPlayerRole.h" +#include "AbilitySystemBlueprintLibrary.h" #include "EnhancedInput/Public/EnhancedInputSubsystems.h" #include "Level/LevelPlayerState.h" #include "EnhancedInput/Public/EnhancedInputComponent.h" @@ -52,6 +53,14 @@ void ALevelPlayerController::SetupInputComponent() BindEnhancedInputAction(EnhancedInput, PrimarySkillAction, this, "OnPrimarySkill"); BindEnhancedInputAction(EnhancedInput, UltimateSkillAction, this, "OnUltimateSkill"); BindEnhancedInputAction(EnhancedInput, SwitchRoleAction, this, "OnSwitchRole"); + + for (const FBusySkillActionConfig& ActionConfig : RoleSkillActions) + { + EnhancedInput->BindAction(ActionConfig.InputAction, ETriggerEvent::Triggered, this, + &ALevelPlayerController::OnRoleSkillTriggered, + ActionConfig.ActionTag + ); + } } void ALevelPlayerController::Tick(float DeltaTime) @@ -107,6 +116,20 @@ bool ALevelPlayerController::GetCursorPosition(FVector2D& Position) const return false; } +bool ALevelPlayerController::GetCursorDirection(FVector2D& Direction) const +{ + const AActor *ControlledRole = GetControlledRole(); + if (!ControlledRole) return false; + + if (FVector2D CursorPosition; GetCursorPosition(CursorPosition)) + { + FVector2D &&RoleLocation = FVector2D(ControlledRole->GetActorLocation()); + Direction = (CursorPosition - RoleLocation).GetSafeNormal(); + return true; + } + return false; +} + void ALevelPlayerController::GetCursorHitResult(TArray& Results) const { } @@ -192,3 +215,14 @@ void ALevelPlayerController::OnSwitchRole(const FInputActionValue& Value) SwitchControlledRole(ControlledRole); } } + +void ALevelPlayerController::OnRoleSkillTriggered(FGameplayTag GameplayTag) +{ + AActor* ControlledRole = GetControlledRole(); + if (!ControlledRole) return; + if (UAbilitySystemComponent* Asc = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControlledRole)) + { + FGameplayEventData EventData = FGameplayEventData(); + Asc->HandleGameplayEvent(GameplayTag, &EventData); + } +} diff --git a/Source/BusyRabbit/Public/BusyGameplayLibrary.h b/Source/BusyRabbit/Public/BusyGameplayLibrary.h index f8ec65a..373874b 100644 --- a/Source/BusyRabbit/Public/BusyGameplayLibrary.h +++ b/Source/BusyRabbit/Public/BusyGameplayLibrary.h @@ -53,4 +53,12 @@ public: UFUNCTION(BlueprintPure) static bool GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData); +public: + UFUNCTION(BlueprintPure) + static FGameplayTag RequestGameplayTag(const FName& TagName); + + UFUNCTION(BlueprintCallable) + static FGameplayTagContainer RequestGameplayTags(const TArray& TagNames); + + }; diff --git a/Source/BusyRabbit/Public/Gas/BusyGameAbility.h b/Source/BusyRabbit/Public/Gas/BusyGameAbility.h new file mode 100644 index 0000000..875dc31 --- /dev/null +++ b/Source/BusyRabbit/Public/Gas/BusyGameAbility.h @@ -0,0 +1,30 @@ +#pragma once +#include "slua.h" +#include "Abilities/GameplayAbility.h" +#include "BusyGameAbility.generated.h" + + + +UCLASS(Blueprintable, BlueprintType) +class UBusyGameAbility : public UGameplayAbility, public ILuaOverriderInterface +{ + GENERATED_BODY() +public: + + UBusyGameAbility(); + + virtual FString GetLuaFilePath_Implementation()const override; + + +public: + UFUNCTION(BlueprintCallable) + bool GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level, FGameplayEffectSpecHandle& Handle)const; + + +public: + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) + FString LuaFilePath; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, DisplayName="技能效果") + TMap> AbilityEffects; +}; diff --git a/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h b/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h index 162b9fb..32041dc 100644 --- a/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h +++ b/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h @@ -6,6 +6,7 @@ class USphereComponent; +struct FBusyPawnBaseConfig; class USpineBoneFollowerComponent; class USpineSkeletonRendererComponent; class USpineSkeletonAnimationComponent; @@ -63,14 +64,9 @@ public: virtual float GetSpeed_Implementation()const override; public: - virtual bool InitRoleAttributes() { return false; } + virtual void InitPawnAttributes(const FBusyPawnBaseConfig& Config); + virtual void InitPawnAbilities(const FBusyPawnBaseConfig& Config) const; -protected: - UFUNCTION(BlueprintCallable) - void InitMoveSpeed(const float MoveSpeed)const; - - UFUNCTION(BlueprintCallable) - void InitHealth(const float Health, const float MaxHealth)const; protected: UPROPERTY(EditDefaultsOnly) @@ -111,7 +107,7 @@ public: protected: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) - TObjectPtr Attribute = nullptr; + TObjectPtr Attributes = nullptr; protected: diff --git a/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h b/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h index 5152007..0cbed04 100644 --- a/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h +++ b/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h @@ -46,7 +46,8 @@ public: virtual void BeginPlay() override; - virtual bool InitRoleAttributes()override; + virtual void InitPawnAttributes(const struct FBusyPawnBaseConfig& Config)override; + protected: diff --git a/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h b/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h index 6d0cb43..fe57bc1 100644 --- a/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h +++ b/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h @@ -9,7 +9,7 @@ class UBusyAbilitySystemComponent : public UAbilitySystemComponent, public ILuaO { GENERATED_BODY() public: - virtual FString GetLuaFilePath_Implementation() const override; + virtual FString GetLuaFilePath_Implementation() const override; protected: diff --git a/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h b/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h index 91bb497..7c0a910 100644 --- a/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h +++ b/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h @@ -54,6 +54,23 @@ public: UFUNCTION(BlueprintCallable) void SprintTo(const float Distance, const float SpeedRate); + /** + * 以角色自身的速度向某个方向进行冲刺,受角色速度变化的影响 + * @param Direction 冲刺方向 + * @param TotalTime 冲刺的时间(s) + */ + UFUNCTION(BlueprintCallable) + void ActivateSprint(const FVector2D &Direction, const float TotalTime); + + /** + * 以指定速度向某个方向冲刺,无视角色速度 + * @param Direction + * @param TotalTime + * @param Speed + */ + UFUNCTION(BlueprintCallable) + void ActivateSprintWithSpeed(const FVector2D &Direction, const float TotalTime, const float Speed); + /** * 获取当前移动的方向 * @return 返回朝向的单位向量,如果没动返回(0,0) @@ -97,10 +114,17 @@ protected: UPROPERTY(EditAnywhere, BlueprintReadOnly) FVector2D ForwardDirection; + +// 冲刺相关 +protected: - - -protected: // 冲刺相关 + + FVector2D SprintDirection; // 冲刺的方向 + float SprintTotalTime; // 冲刺总时长 + float SprintRemainTime; // 冲刺的剩余时间 + float SprintSpeed; // 指定的冲刺速度, 为0表示使用自己的速度 + + float SprintSpeedRate = 1.f; float SprintDistance = 100.f; FVector2D SprintStartLocation; diff --git a/Source/BusyRabbit/Public/Level/LevelPlayerController.h b/Source/BusyRabbit/Public/Level/LevelPlayerController.h index e805fe4..7859247 100644 --- a/Source/BusyRabbit/Public/Level/LevelPlayerController.h +++ b/Source/BusyRabbit/Public/Level/LevelPlayerController.h @@ -1,16 +1,18 @@ #pragma once #include "LuaPlayerController.h" +#include "GameplayTagContainer.h" +#include "InputAction.h" #include "LevelPlayerController.generated.h" + UINTERFACE(MinimalAPI, Blueprintable) class UBusyControllable: public UInterface { GENERATED_BODY() }; - class IBusyControllable { GENERATED_BODY() @@ -29,8 +31,22 @@ public: }; -struct FInputActionValue; class ABusyPlayerRole; +struct FInputActionValue; + + +USTRUCT(BlueprintType) +struct FBusySkillActionConfig +{ + GENERATED_BODY() + UPROPERTY(EditAnywhere, BlueprintReadOnly) + FGameplayTag ActionTag; + UPROPERTY(EditAnywhere, BlueprintReadOnly) + UInputAction* InputAction; +}; + + + UCLASS() class ALevelPlayerController : public ALuaPlayerController @@ -48,6 +64,14 @@ public: UFUNCTION(BlueprintCallable, Category = "Controller") bool GetCursorPosition(FVector2D& Position) const; + /** + * 获取光标相对于所控制的人物的方向 + * @param Direction + * @return false -> 获取失败, 没有角色或者鼠标不在游戏内 + */ + UFUNCTION(BlueprintCallable, Category = "Controller") + bool GetCursorDirection(FVector2D& Direction) const; + UFUNCTION(BlueprintCallable, Category = "Controller") ABusyPlayerRole* GetControlledRole() const; @@ -88,6 +112,10 @@ public: // 输入相关 UPROPERTY(EditDefaultsOnly, Category = "Input") TObjectPtr SwitchRoleAction; // 切换控制的角色 + + UPROPERTY(EditDefaultsOnly, Category = "Input") + TArray RoleSkillActions; + public: UFUNCTION() void OnMove(const FInputActionValue& Value)const; @@ -104,6 +132,9 @@ public: UFUNCTION() void OnSwitchRole(const FInputActionValue& Value); + UFUNCTION() + void OnRoleSkillTriggered(FGameplayTag GameplayTag); + protected: UPROPERTY()