* 데미지 로직 수정

 

공격 가능 도구 관련 코드

-- 로컬 변수 정의, 바인드 --------------------------------------------------------------------------------------------

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 함수 추가
* 각 게임 데이터에서 게임 데이터 타입 받아올 수 있도록 수정

 

 

+ Recent posts