From bf3d3e0f5d72f015fa229c382b622d02c458d089 Mon Sep 17 00:00:00 2001 From: Tahsin Date: Fri, 11 Apr 2025 10:24:36 +0200 Subject: [PATCH] Simple 1097 lootbox --- src/game/GameProcMain.cpp | 23 +++++- src/game/GameProcMain.h | 15 ++-- src/game/ItemBundleMgr.cpp | 114 ++++++++++++++++++++++++++ src/game/ItemBundleMgr.h | 75 +++++++++++++++++ src/game/KnightOnLine.vcxproj | 2 + src/game/KnightOnLine.vcxproj.filters | 2 + 6 files changed, 221 insertions(+), 10 deletions(-) create mode 100644 src/game/ItemBundleMgr.cpp create mode 100644 src/game/ItemBundleMgr.h diff --git a/src/game/GameProcMain.cpp b/src/game/GameProcMain.cpp index c0052dcd..f30c7ef5 100644 --- a/src/game/GameProcMain.cpp +++ b/src/game/GameProcMain.cpp @@ -14,6 +14,7 @@ #include "PlayerMySelf.h" #include "PlayerOtherMgr.h" +#include "ItemBundleMgr.h" #include "ServerMesh.h" #include "N3FXMgr.h" @@ -131,6 +132,7 @@ CGameProcMain::CGameProcMain() // r기본 생성자.. 각 변수의 역활은 m_iExitCurCountDown = SECONDS_TO_EXIT_GAME_AFTER_ATTACK; m_fExitCurCountDownToReach = -1.0f; + m_pItemBundleMgr = new CItemBundleMgr(); //UI m_pUIMsgDlg = new CUIMessageWnd; m_pUIChatDlg = new CUIChat(); @@ -222,6 +224,7 @@ CGameProcMain::~CGameProcMain() { delete m_pTargetSymbol; // 플레이어가 타겟으로 잡은 캐릭터의 위치위에 그리면 된다.. delete m_pLightMgr; + delete m_pItemBundleMgr; } void CGameProcMain::Release() { @@ -420,6 +423,7 @@ void CGameProcMain::Tick() { s_pPlayer->Tick(); // 플레이어 틱(갱신) s_pWorldMgr->Tick(); s_pOPMgr->Tick(s_pPlayer->Position()); // 다른 유저 관리자 틱(갱신) + m_pItemBundleMgr->Tick(); // s_pFX->Tick(); //내부에서 카메라 값을 쓸 경우 위치가 오차가 생겨 Render()함수 안으로 옮김... __Vector3 ListenerPos = s_pPlayer->Position(); @@ -617,8 +621,9 @@ void CGameProcMain::Render() { CN3Base::s_lpD3DDev->SetSamplerState(1, D3DSAMP_MIPFILTER, dwFilter); // 텍스쳐를 줄여서 찍었을 경우 픽셀이 깨진것처럼 보이는 것 방지 - ACT_WORLD->RenderTerrain(); // 지형 렌더.. - ACT_WORLD->RenderShape(); // 물체 렌더.. + ACT_WORLD->RenderTerrain(); // 지형 렌더.. + ACT_WORLD->RenderShape(); // 물체 렌더.. + m_pItemBundleMgr->Render(); s_pOPMgr->Render(fSunAngle); // 다른 플레이어 렌더.. s_pPlayer->Render(fSunAngle); // 플레이어 렌더.. @@ -3314,6 +3319,7 @@ bool CGameProcMain::MsgRecv_ItemBundleDrop(DataPack * pDataPack, int & iOffset) if (pCorpse) { pCorpse->m_iDroppedItemID = iItemID; // 떨어트린 아이템 아이디 뭉치 + m_pItemBundleMgr->Add(pCorpse->Position(), iID, 12); } return true; @@ -7183,7 +7189,12 @@ bool CGameProcMain::OnMouseLBtnPress(POINT ptCur, POINT ptPrev) { s_pPlayer->m_pObjectTarget = ACT_WORLD->PickWithShape(ptCur.x, ptCur.y, true, &m_vMouseLBClickedPos); // 찍힌 위치를 저장한다.. - if (NULL == s_pPlayer->m_pObjectTarget) // 타겟도 없으면.. + CItemBundle * pItemBundle = m_pItemBundleMgr->Pick(ptCur.x, ptCur.y); + if (pItemBundle) { + int test = pItemBundle->GetItemID(); + this->MsgSend_RequestItemBundleOpen(dynamic_cast(s_pOPMgr->CorpseGetByID(test))); + } + if (NULL == s_pPlayer->m_pObjectTarget) // 타겟도 없으면.. { // 시체 뒤저서 아이템 상자 열기.. CPlayerNPC * pCorpse = s_pOPMgr->PickCorpse(ptCur.x, ptCur.y, iID); // 픽킹.. @@ -7338,6 +7349,12 @@ bool CGameProcMain::OnMouseRBtnPress(POINT ptCur, POINT ptPrev) { int iID = -1; CPlayerNPC * pNPC = s_pOPMgr->PickNPC(ptCur.x, ptCur.y, iID); // 픽킹.. + CItemBundle * pItemBundle = m_pItemBundleMgr->Pick(ptCur.x, ptCur.y); + if (pItemBundle) { + int test = pItemBundle->GetItemID(); + this->MsgSend_RequestItemBundleOpen(dynamic_cast(s_pOPMgr->CorpseGetByID(test))); + } + if (NULL == pNPC) { CPlayerNPC * pCorpse = s_pOPMgr->PickCorpse(ptCur.x, ptCur.y, iID); // 픽킹.. if (false == this->MsgSend_RequestItemBundleOpen(pCorpse)) // 시체 뒤저서 아이템 상자 열기.. diff --git a/src/game/GameProcMain.h b/src/game/GameProcMain.h index 1ca2d090..1ceaea9c 100644 --- a/src/game/GameProcMain.h +++ b/src/game/GameProcMain.h @@ -21,13 +21,14 @@ class CGameProcMain : public CGameProcedure { #ifdef _N3_64GRID_ CServerMesh * m_pSMesh; // 서버에게 필요한 메쉬 클래스.. #endif - class CUIInventory * m_pUIInventory; // 인벤토리 - class CUIVarious * m_pUIVar; // 캐릭터 상태창, 기사단 관리 등이 페이지로 들어간 다용도 UI - class CUIChat * m_pUIChatDlg; // 채팅 입출력 대화상자.. - class CUIMessageWnd * m_pUIMsgDlg; // 게임 메시지 출력 상자. - class CUIStateBar * m_pUIStateBarAndMiniMap; // mp,hp,exp, minimap.... - class CUICmd * m_pUICmd; // 왼쪽 하단의 명령버튼 창.. - class CUITargetBar * m_pUITargetBar; // 타겟 상태창.. + class CItemBundleMgr * m_pItemBundleMgr; + class CUIInventory * m_pUIInventory; // 인벤토리 + class CUIVarious * m_pUIVar; // 캐릭터 상태창, 기사단 관리 등이 페이지로 들어간 다용도 UI + class CUIChat * m_pUIChatDlg; // 채팅 입출력 대화상자.. + class CUIMessageWnd * m_pUIMsgDlg; // 게임 메시지 출력 상자. + class CUIStateBar * m_pUIStateBarAndMiniMap; // mp,hp,exp, minimap.... + class CUICmd * m_pUICmd; // 왼쪽 하단의 명령버튼 창.. + class CUITargetBar * m_pUITargetBar; // 타겟 상태창.. class CUITransactionDlg * m_pUITransactionDlg; class CUIDroppedItemDlg * m_pUIDroppedItemDlg; class CSubProcPerTrade * m_pSubProcPerTrade; diff --git a/src/game/ItemBundleMgr.cpp b/src/game/ItemBundleMgr.cpp new file mode 100644 index 00000000..4fd0d05a --- /dev/null +++ b/src/game/ItemBundleMgr.cpp @@ -0,0 +1,114 @@ +// ItemBundleMgr.cpp: implementation of the CItemBundleMgr class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ItemBundleMgr.h" +#include "GameProcMain.h" +#include "N3Terrain.h" +#include "APISocket.h" +#include "PacketDef.h" +#include "N3TerrainManager.h" +#include "N3WorldManager.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CItemBundle::CItemBundle(int iBundleID, float fTimeToLive) { + m_iBundleID = iBundleID; + m_fTimeToLive = fTimeToLive; +} + +CItemBundle::~CItemBundle() {} + +void CItemBundle::Tick() { + m_fTimeToLive -= s_fSecPerFrm; + if (IsAlive()) { + CN3Shape::Tick(); + } +} + +CItemBundleMgr::CItemBundleMgr() {} + +CItemBundleMgr::~CItemBundleMgr() { + ReleaseBundles(); +} + +void CItemBundleMgr::Release() { + ReleaseBundles(); +} + +void CItemBundleMgr::ReleaseBundles() { + CItemBundle * pItem = NULL; + it_ItemBundle it = m_Bundles.begin(), itEnd = m_Bundles.end(); + for (; it != itEnd; it++) { + pItem = (*it).second; + delete pItem; + } + m_Bundles.clear(); +} + +void CItemBundleMgr::Tick() { + CItemBundle * pItem = NULL; + it_ItemBundle it = m_Bundles.begin(), itEnd = m_Bundles.end(); + for (; it != itEnd;) { + pItem = (*it).second; + + pItem->Tick(); + if (pItem->IsAlive()) { + it++; + } else { + delete pItem; + it = m_Bundles.erase(it); + } + } +} + +void CItemBundleMgr::Render() { + CItemBundle * pItem = NULL; + it_ItemBundle it = m_Bundles.begin(), itEnd = m_Bundles.end(); + for (; it != itEnd; it++) { + pItem = (*it).second; + pItem->Render(); + } +} + +CItemBundle * CItemBundleMgr::Pick(int ixScreen, int iyScreen) { + CItemBundle * pItemBundle = NULL; + CN3VMesh * pVMesh = NULL; + it_ItemBundle it = m_Bundles.begin(), itEnd = m_Bundles.end(); + + __Vector3 vPos, vDir; + ::_Convert2D_To_3DCoordinate(ixScreen, iyScreen, s_CameraData.mtxView, s_CameraData.mtxProjection, s_CameraData.vp, + vPos, vDir); + + for (; it != itEnd; it++) { + pItemBundle = (*it).second; + + CN3VMesh * pvMesh = pItemBundle->CollisionMesh(); + if (NULL != pvMesh && pvMesh->Pick(pItemBundle->m_Matrix, vPos, vDir)) { + return pItemBundle; + } + } + + return NULL; +} + +bool CItemBundleMgr::Add(__Vector3 vPos, int iBundleID, float fTimeToLive) { + if (m_Bundles.end() != m_Bundles.find(iBundleID)) { + return false; + } + if (fTimeToLive <= 0.0f) { + return false; + } + + CItemBundle * pIB = new CItemBundle(iBundleID, fTimeToLive); + pIB->LoadFromFile("Misc\\itembox.n3shape"); + + vPos.y = ACT_WORLD->GetHeightWithTerrain(vPos.x, vPos.z); + pIB->PosSet(vPos.x, vPos.y + 0.01, vPos.z); + + m_Bundles.insert(std::map::value_type(iBundleID, pIB)); + return true; +} diff --git a/src/game/ItemBundleMgr.h b/src/game/ItemBundleMgr.h new file mode 100644 index 00000000..334a28d2 --- /dev/null +++ b/src/game/ItemBundleMgr.h @@ -0,0 +1,75 @@ +// ItemBundleMgr.h: interface for the CItemBundleMgr class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_ITEMBUNDLEMGR_H__943C585B_1D84_4B91_A578_AA1B228B2809__INCLUDED_) +#define AFX_ITEMBUNDLEMGR_H__943C585B_1D84_4B91_A578_AA1B228B2809__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "..\engine\N3Base\N3Shape.h" +#include "GameBase.h" + +class DataPack; +class CItemBundle : public CN3Shape { + public: + CItemBundle(int iBundleID, float fTimeToLive); + virtual ~CItemBundle(); + + protected: + int m_iBundleID; + float m_fTimeToLive; // ¾ÆÀÌÅÛÀÌ ¸¸µé¾îÁø ½Ã°£.. + public: + virtual void Tick(); + bool IsAlive() const { return m_fTimeToLive > 0.0f; } + int GetItemID() const { return m_iBundleID; } +}; + +typedef std::map::iterator it_ItemBundle; + +class CItemBundleMgr : public CGameBase { + public: + CItemBundleMgr(); + virtual ~CItemBundleMgr(); + + protected: + std::map m_Bundles; + + public: + CItemBundle * Pick(int ixScreen, int iyScreen); + bool Add(__Vector3 vPos, int iBundleID, float fTimeToLive); + bool Add(CItemBundle * pIB) { + if (!pIB) { + return false; + } + m_Bundles.insert(std::map::value_type(pIB->GetItemID(), pIB)); + return true; + } + bool Remove(int iBundleID) { + it_ItemBundle it = m_Bundles.find(iBundleID); + if (m_Bundles.end() == it) { + return false; + } + delete (*it).second; + m_Bundles.erase(it); + return true; + } + + CItemBundle * Get(int iBundleID) { + it_ItemBundle it = m_Bundles.find(iBundleID); + if (m_Bundles.end() == it) { + return NULL; + } + return (*it).second; + } + + void Tick(); + void Render(); + + void Release(); + void ReleaseBundles(); +}; + +#endif // !defined(AFX_ITEMBUNDLEMGR_H__943C585B_1D84_4B91_A578_AA1B228B2809__INCLUDED_) diff --git a/src/game/KnightOnLine.vcxproj b/src/game/KnightOnLine.vcxproj index fc069f12..e5a5bcb8 100644 --- a/src/game/KnightOnLine.vcxproj +++ b/src/game/KnightOnLine.vcxproj @@ -222,6 +222,7 @@ + @@ -402,6 +403,7 @@ + diff --git a/src/game/KnightOnLine.vcxproj.filters b/src/game/KnightOnLine.vcxproj.filters index 3ee873ab..0eb719cd 100644 --- a/src/game/KnightOnLine.vcxproj.filters +++ b/src/game/KnightOnLine.vcxproj.filters @@ -642,6 +642,7 @@ N3Base\Core + @@ -1146,6 +1147,7 @@ Procedure - Main\UI +