* 데미지 로직 수정
공격 가능 도구 관련 코드
-- 로컬 변수 정의, 바인드 --------------------------------------------------------------------------------------------
local ServerStorage = game:GetService("ServerStorage")
local ServerModuleFacade = require(ServerStorage:WaitForChild("ServerModuleFacade"))
local Utility = ServerModuleFacade.Utility
local Debug = ServerModuleFacade.Debug
local ServerConstant = ServerModuleFacade.ServerConstant
local ServerGlobalStorage = ServerModuleFacade.ServerGlobalStorage
local GameDataType = ServerModuleFacade.ServerEnum.GameDataType
local ToolBase = Utility.DeepCopy(require(ServerModuleFacade.ToolModule:WaitForChild("ToolBase")))
local Tool = script.Parent
local Anim1 = Tool.anim1
local isAttacking = false
ToolBase:InitializeAll(GameDataType.Tool, Tool)
-- 함수 정의 ------------------------------------------------------------------------------------------------------
function CanAttack(otherPart)
if not otherPart then
Debug.Assert(false, "대상이 존재하지 않습니다.")
return false
end
local otherModel = otherPart.Parent
if not otherModel then
Debug.Assert(false, "모델이 존재하지 않습니다.")
return false
end
if not Tool then
Debug.Assert(false, "도구가 없습니다.")
return false
end
local toolParent = Tool.Parent
-- 자기자신인 경우
if toolParent == otherModel then
return false
end
local toolParentClassName = toolParent.ClassName
if not toolParentClassName
or toolParentClassName == "Workspace" -- 필드에 존재
or toolParentClassName == "Backpack" then -- 가방에 존재
Debug.Assert(false, "비정상입니다.")
return false
end
return true
end
function CalcDamage(attackerCharacter, attackeeCharacter)
local attackerSTR = 0
local attackeeDEF = 0
-- ==== 캐릭터 계산 ====
local attackerCharacterGameData = ServerGlobalStorage:GetGameData(attackerCharacter, GameDataType.Character)
local attackeeCharacterGameData = ServerGlobalStorage:GetGameData(attackeeCharacter, GameDataType.Character)
-- 캐릭터 공격 데이터
if not attackerCharacterGameData then
Debug.Assert(false, "캐릭터 정보가 없습니다." .. attackerCharacter.Name)
return 0
else
attackerSTR += attackerCharacterGameData.STR
end
-- 캐릭터 방어 데이터
if not attackeeCharacterGameData then
Debug.Assert(false, "캐릭터 정보가 없습니다." .. attackeeCharacter.Name)
return 0
else
attackeeDEF += attackeeCharacterGameData.DEF
end
-- ==== 도구 계산 =====
local attackerToolGameData = ServerGlobalStorage:GetGameData(attackerCharacter, GameDataType.Tool)
local attackeeToolGameData = ServerGlobalStorage:GetGameData(attackeeCharacter, GameDataType.Tool)
-- 도구 공격 데이터
if attackerToolGameData and attackerToolGameData.STR then
attackerSTR += attackerToolGameData.STR
end
-- 도구 방어 데이터
if attackeeToolGameData and attackeeToolGameData.DEF then
attackeeDEF += attackeeToolGameData.DEF
end
local finalDamage = ServerConstant.DefaultAttackPoint + (attackerSTR * ServerConstant.DefaultSTRFactor) - attackeeDEF
finalDamage = math.clamp(finalDamage, 0, 100)
return finalDamage
end
function AttackCharacter(attackerCharacter, attackeeCharacter)
local damage = CalcDamage(attackerCharacter, attackeeCharacter)
Debug.Log("Damage : ".. tostring(damage))
if damage == 0 then
return
end
local attackeeCharacterHumanoid = attackeeCharacter:FindFirstChild("Humanoid")
if not attackeeCharacterHumanoid then
Debug.Assert(false, "Humanoid가 없습니다.")
return
end
attackeeCharacterHumanoid:TakeDamage(damage)
end
function Attack(attackeePart)
if CanAttack(attackeePart) == false then
--Debug.Assert(false, "공격할 수 없습니다.")
return
end
local attackeePlayer = game.Players:GetPlayerFromCharacter(attackeePart.Parent)
--print(attackeePlayer)
--print(attackeePart)
--print(attackeePart.Parent)
if not attackeePlayer then
-- 추가해야한다.
Debug.Log("플레이어가 아닙니다.")
else
local attackerCharacter = Tool.Parent
local attackeeCharacter = attackeePart.Parent
AttackCharacter(attackerCharacter, attackeeCharacter)
end
end
function onTouched(otherPart)
if isAttacking == false then return end
isAttacking = false
Attack(otherPart)
end
function onActivated()
isAttacking = true
local humanoid = Tool.Parent:FindFirstChild("Humanoid")
local anim1Track = humanoid:LoadAnimation(Anim1)
anim1Track:Play()
anim1Track.Stopped:Connect(function() isAttacking = false end)
end
-- 이벤트 바인드
Tool.Activated:Connect(onActivated)
Tool.Attacker.Touched:Connect(onTouched)
객체 기본 코드 추가
function ObjectBase:Initialize(objectGameDataType, objectRoot)
if not objectRoot then
Debug.Assert(false, "입력이 비정상입니다. GameDataType => " .. tostring(objectGameDataType))
return
end
if not objectGameDataType or type(objectGameDataType) ~= "number" then
Debug.Assert(false, "입력이 비정상입니다.")
return
end
local objectGameDataKey = objectRoot:FindFirstChild("Key")
if not objectGameDataKey then
Debug.Assert(false, "객체에 키 태그가 존재하지 않습니다.")
return
end
objectGameDataKey = objectGameDataKey.Value
local objectGameData = GameDataManager[objectGameDataType]:Get(objectGameDataKey)
if not objectGameData then
Debug.Assert(false, "데이터가 존재하지 않습니다.")
return
end
local interalData = {
root = objectRoot,
gameDataType = objectGameDataType,
gameDataKey = objectGameDataKey,
gameData = objectGameData,
}
self.Root = function()
Debug.Assert(interalData.root, "ObjectRoot가 존재하지 않습니다. 초기화 해주세요.")
return interalData.root
end
self.GetGameDataType = function()
Debug.Assert(interalData.root, "ObjectRoot가 존재하지 않습니다. 초기화 해주세요.")
Debug.Assert(interalData.gameDataType, "GameDataType이 존재하지 않습니다. 초기화 해주세요.")
return interalData.gameDataType
end
self.GetGameDataKey = function()
Debug.Assert(interalData.root, "ObjectRoot가 존재하지 않습니다. 초기화 해주세요.")
Debug.Assert(interalData.gameDataType, "GameDataType이 존재하지 않습니다. 초기화 해주세요.")
Debug.Assert(interalData.gameDataKey, "GameDataKey가 존재하지 않습니다. 초기화 해주세요.")
return interalData.gameDataKey
end
self.GetGameData = function()
Debug.Assert(interalData.root, "ObjectRoot가 존재하지 않습니다. 초기화 해주세요.")
Debug.Assert(interalData.gameDataType, "GameDataType이 존재하지 않습니다. 초기화 해주세요.")
Debug.Assert(interalData.gameData, "GameData가 존재하지 않습니다. 초기화 해주세요.")
return interalData.gameData
end
end
* 기타 수정
- 서버
* 서버 전역 저장소 기능 추가 및 정리, 캐릭터마다 저장한 게임 데이터를 관리할 수 있도록 수정 완료
// static private 변수와 효과가 비슷한 내부 local 변수를 사용 , 무조건 싱클톤으로만 사용해야됨
- 객체
* ObjectBase 기능 추가, 공용으로 사용할 수 있는 기능들 추가(Root, GetGameData 등), 함수를 통해서만 접근가능하도록 설계
- 도구
* 도구와 캐릭터의 게임 데이터를 통해 공격력, 방어력 반영
* 도구와 기타 정보들을 서버에서 로드해서 생성하여 플레이어에게 제공, 정적인 도구라면 그냥 서버 스토리지에서 찾아서 제공
- 기타
* Debug.Assert, Log에 콜스택 찍히도록 수정
* Debug 모듈에 Print 함수 추가
* 각 게임 데이터에서 게임 데이터 타입 받아올 수 있도록 수정
'Lua in Roblox' 카테고리의 다른 글
| [Lua / Roblox] 미니 배틀 로얄 게임 #8 : 중간 완료된 작업(기록용) (0) | 2022.07.21 |
|---|---|
| [Lua / Roblox] 로블록스 클라이언트 서버 모델 분석 (0) | 2022.07.19 |
| [Lua / Roblox] 미니 배틀 로얄 게임 #6 : 구조 정리, 모듈 추가 (0) | 2022.07.15 |
| [Lua / Roblox] 미니 배틀 로얄 게임 #5 : 게임 데이터 매니저 (0) | 2022.07.14 |
| [Lua] 클래스 구현(접근 제어, 상속, 리플렉션, 캐스팅 등 지원) (0) | 2022.07.13 |