5527 lines
156 KiB
C++
5527 lines
156 KiB
C++
//------------------------------------------------------------------------------
|
|
// GameFunc.cpp
|
|
// (C) 2005 Webzen Sunstudio
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "SunClientPrecompiledHeader.h"
|
|
#include "globalfunc.h"
|
|
#include "Object.h"
|
|
#include "character.h"
|
|
#include "Hero.h"
|
|
#include "gamefunc.h"
|
|
#include "ObjectManager.h"
|
|
#include "Map.h"
|
|
#include "Monster.h"
|
|
#include "WeaponSoundInfoParser.h"
|
|
#include "MouseCursor.h"
|
|
#include "HeroActionInput.h"
|
|
#include "MouseHandler.h"
|
|
#include "mapObject.h"
|
|
#include "OptimizationManager.h"
|
|
#include "ShopDialog.h"
|
|
#include "GmManager.h"
|
|
#include "StyleInfoParser.h"
|
|
#include "ChatDialog.h"
|
|
#include "uiVendorBuy/uiVendorBuy.h"
|
|
#include "uiTrade/uiTrade.h"
|
|
#include "uiTradeMan/uiTradeMan.h"
|
|
#include "uiPartyLeavePopup/uiPartyLeavePopup.h"
|
|
#include "uiVendorMan/uiVendorMan_def.h"
|
|
#include "uiVendorSell/uiVendorSell.h"
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
#include "GuildSystem/GuildSystemFunction.h"
|
|
#include "GuildSystem/uiGuildMan.h"
|
|
#include "GuildSystem/uiGuildMenu.h"
|
|
#else
|
|
#include "uiGuildMan/uiGuildMan.h"
|
|
#include "uiGuildMenu/uiGuildMenu.h"
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
#include "quickslot.h"
|
|
#include "Map.h"
|
|
#include "Camera.h"
|
|
#ifdef _NA_003923_20120130_GUILD_RENEWAL_MOD_WAREHOUSE_SLOT_NUM
|
|
#include "uiBankMan/uiBankDef.h"
|
|
#include "uiBankMan/uiBankDialog.h"
|
|
#else
|
|
#include "BankDialog.h"
|
|
#endif //_NA_003923_20120130_GUILD_RENEWAL_MOD_WAREHOUSE_SLOT_NUM
|
|
#include "MouseCursor.h"
|
|
#include "HeroVoiceInfoParser.h"
|
|
#include "SoundEffect.h"
|
|
#include "NPCPortalDialog.h"
|
|
#include "quickcontainer.h"
|
|
#include "uiHelpMan/uiHelpMan.h"
|
|
#include "GameFramework.h"
|
|
#include "BattleScene.h"
|
|
#include "ProjectileManagerEx.h"
|
|
#include "SkillInfoParser.h"
|
|
#include "SkillEffectInfoParser.h"
|
|
#include "SelectCompositeMenu.h"
|
|
#include "uiQuestMan/uiQuestMan.h"
|
|
#include "uiPartyMan/uiPartyMan.h"
|
|
#include "NPCInfoParser.h"
|
|
#include "uiEventMan/uiEventMan.h"
|
|
#include "uiEventWindow/uiEventWindow.h"
|
|
#include "QuestManager_Concrete.h"
|
|
#include "CompositeNPCInfoParser.h"
|
|
#include "uiitemcompositeman/uiItemCompositeMan.h"
|
|
#include "uiItemTotalComposite/uiItemTotalComposite.h"
|
|
#include "uiBattleZoneReadyCHuntingConfig/uiBattleZoneReadyCHuntingConfig.h"
|
|
#include "CursorChangeTransact.h"
|
|
#include "GameFramework.h"
|
|
#if defined(_NA_006802_20130704_REORGANIZATION_RANK_SYSTEM)
|
|
#include "uiMissionRankMan2/uiMissionRankMan2.h"
|
|
#include "uiMissionRankList2/uiMissionRankList2.h"
|
|
#else
|
|
#include "uiMissionRankMan/uiMissionRankMan.h"
|
|
#include "uiMissionRankList/uiMissionRankList.h"
|
|
#endif // _NA_006802_20130704_REORGANIZATION_RANK_SYSTEM
|
|
#include "uiVendorList/uiVendorList.h"
|
|
#include "ItemManager.h"
|
|
#include "uiCashItemShopMan/uiCashItemShopMan.h"
|
|
#include "uiCashItemShopNpcPopup/uiCashItemShopNpcPopup.h"
|
|
#include "PlayerMonster.h"
|
|
#include "uiCashItemShopPresentDlg/uiCashItemShopPresentDlg.h"
|
|
#include "uiCashItemShopPresentCheck/uiCashItemShopPresentCheck.h"
|
|
#include "uiCashItemShopPresentComplete/uiCashItemShopPresentComplete.h"
|
|
#include "uiCashItemShopPackageDlg/uiCashItemShopPackageDlg.h"
|
|
#include "uiCashItemShopPackageCheck/uiCashItemShopPackageCheck.h"
|
|
#include "uicashItemShopPackageComplete/uicashItemShopPackageComplete.h"
|
|
#include "uiPasswordDlg/uiPasswordDlg.h"
|
|
#include "EquipmentContainer.h"
|
|
|
|
#include "uiContinentMapEP2/ContinentMapEp2Dialog.h"
|
|
|
|
#include "ContinentMapDlg.h"
|
|
#include "uiRadarMan/uiRadarMan.h"
|
|
|
|
#ifdef __NA_001027_20080423_RANDOM_REWARD_EVENT_
|
|
#include "uiGuildEventDialog/uiGuildEventDialog.h"
|
|
#endif
|
|
|
|
#include "NPC.h"
|
|
|
|
#include "ui_XMas_DonationConfirm/ui_XMas_DonationConfirm.h"
|
|
#include "ui_XMas_Confirm/ui_XMas_Confirm.h"
|
|
#include "ui_XMas_SantaDlg/ui_XMas_SantaDlg.h"
|
|
#include "SunEventInfoParser.h"
|
|
#include "RewardInfoList.h"
|
|
#include "ItemInfoParser.h"
|
|
#include "uiSystemMan/uiSystemMan.h"
|
|
|
|
#ifdef _YJ_FISHING_SYSTEM_000933
|
|
#include "uiFishingShop/uiFishingShop.h"
|
|
#endif //_YJ_FISHING_SYSTEM_000933
|
|
|
|
#include "uiQuestCommonForward/uiQuestCommonForward.h"
|
|
#include "uiBattleZoneMan/uiBattleZoneMan_def.h"
|
|
#include "NpcImageInfo.h"
|
|
#include "uiBuffEvent/uiBuffEvent.h"
|
|
|
|
#include "uiLottoMan/uiLottoMan.h"
|
|
#include "uiLottoWindow/uiLottoWindow.h"
|
|
|
|
#include "PKScriptParser.h"
|
|
|
|
#include "uiEventFriendWindow.h"
|
|
#include "uiCharCustomizeMan/uiCharCustomizeMan.h"
|
|
#include "uiCharCustomizeDlg/uiCharCustomizeDlg.h"
|
|
#ifdef _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
|
|
#include "ChaosSystem/ChaosSystemData.h"
|
|
#endif //_NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
|
|
#include "OptionListParser.h"
|
|
|
|
#include "Define.ShopServer.h"
|
|
|
|
#ifdef _NA_005988_20120901_VENDOR_SEARCH_SYSTEM
|
|
#include "../Interface/uiVendorMan/uiVendorSearch/uiVendorSearch.h"
|
|
#endif //_NA_005988_20120901_VENDOR_SEARCH_SYSTEM
|
|
#ifdef _NA_006826_20130722_DOMINATION_RENEWAL
|
|
#include "uiDominationTowerMan/uiDominationTowerMan.h"
|
|
#endif //_NA_006826_20130722_DOMINATION_RENEWAL
|
|
#ifdef _NA_000000_20140120_SMART_NPC_SYSTEM
|
|
#include "PacketStruct_CG_SmartNPC.h"
|
|
#endif //_NA_000000_20140120_SMART_NPC_SYSTEM
|
|
#ifdef _NA_008016_20150203_SUN_RANKING_SYSTEM_STATUE
|
|
#include "StatuePlayer.h"
|
|
#endif // _NA_008016_20150203_SUN_RANKING_SYSTEM_STATUE
|
|
|
|
eZONETYPE GameFunc::ConvertServerZoneType(SCENE_TYPE eSceneType)
|
|
{
|
|
//매칭 되는 타입이 없을 경우 서버에서 디폴트로 사용 된다.
|
|
eZONETYPE eServerSceneType=eZONETYPE_MAX;
|
|
|
|
switch(eSceneType)
|
|
{
|
|
case SCENE_TYPE_LOBBY:
|
|
{
|
|
eServerSceneType=eZONETYPE_LOBBY;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_VILLAGE:
|
|
{
|
|
eServerSceneType=eZONETYPE_VILLAGE;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_CHARSELECT:
|
|
{
|
|
eServerSceneType=eZONETYPE_CHARSELECT;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_MISSION:
|
|
{
|
|
eServerSceneType=eZONETYPE_MISSION;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_PVP:
|
|
{
|
|
eServerSceneType=eZONETYPE_PVP;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_EVENT:
|
|
{
|
|
eServerSceneType=eZONETYPE_EVENT;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_FIELD:
|
|
{
|
|
eServerSceneType=eZONETYPE_FIELD;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_CHUNTING:
|
|
{
|
|
eServerSceneType=eZONETYPE_CHUNTING;
|
|
}
|
|
break;
|
|
|
|
case SCENE_TYPE_INSTANCE_DUNGEON:
|
|
case SCENE_TYPE_DOMINATION:
|
|
#ifdef _NA_008334_20150608_SONNENSCHEIN
|
|
case SCENE_TYPE_SONNENSCHEIN:
|
|
#endif //_NA_008334_20150608_SONNENSCHEIN
|
|
|
|
{
|
|
eServerSceneType=eZONETYPE_INSTANCE;
|
|
}
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
return eServerSceneType;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
Character* GameFunc::GetPickedCharacter(WzRay *pRay,DWORD dwPickingOption)
|
|
{
|
|
if (g_pMap)
|
|
{
|
|
if (VectorLength2(&pRay->m_wvDirection) >= 0.04f)
|
|
{
|
|
return g_pMap->GetPickedCharacter(pRay,dwPickingOption);
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
Item * GameFunc::GetPickedItem(WzRay* pRay)
|
|
{
|
|
if (g_pMap)
|
|
{
|
|
if (VectorLength2(&pRay->m_wvDirection) >= 0.04f)
|
|
{
|
|
return g_pMap->GetPickedItem(pRay);
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
MapObject *
|
|
GameFunc::GetPickedMapUnitObject(WzRay* pRay)
|
|
{
|
|
if (g_pMap)
|
|
{
|
|
if (VectorLength2(&pRay->m_wvDirection) >= 0.04f)
|
|
{
|
|
return g_pMap->GetPickedUnitMapObject(pRay);
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
BOOL GameFunc::GetClickedPosition(WzVector* OUT pPosition)
|
|
{
|
|
// mouse ray를 잘못넣어서 뻑나지 않도록.
|
|
if (VectorLength2(&g_wrMouseRay.m_wvDirection) <= 0.04f)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
float fT;
|
|
|
|
|
|
if(SCENE_TYPE_DOMINATION == GameFramework::GetCurScene()
|
|
#ifdef _NA_008334_20150608_SONNENSCHEIN
|
|
|| SCENE_TYPE_SONNENSCHEIN == GameFramework::GetCurScene()
|
|
#endif //_NA_008334_20150608_SONNENSCHEIN
|
|
)
|
|
{
|
|
int iTile = g_pSunTerrain->PickPathTile(&g_wrMouseRay, &fT);
|
|
if(0 > iTile)
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
WzVector wvNormal;
|
|
int iTerrainMeshFocussing = g_pSunTerrain->PickTerrainMesh( &g_wrMouseRay, &fT ,TRUE,TMGO_HAZE, &wvNormal);
|
|
if( iTerrainMeshFocussing < 0 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
*pPosition = g_wrMouseRay.m_wvOrigin + g_wrMouseRay.m_wvDirection * fT;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
/** 길찾기 위치에서 실제 포지션을 얻어온다.
|
|
*/
|
|
BOOL GameFunc::GetVisiblePosition(WzVector * IN OUT pInOutVisiblePos )
|
|
{
|
|
// 타겟 위치 알기
|
|
BOOL bRet = FALSE;
|
|
float fT = 0.f;
|
|
|
|
if ( !g_pMap || !pInOutVisiblePos )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
int iMesh =
|
|
g_pMap->GetWorldBase()->PathExp_GetMeshToStand(*pInOutVisiblePos, &fT, 10.f);
|
|
|
|
//딛을수 있는 곳인가
|
|
if ( iMesh >= 0 && fT )
|
|
{
|
|
pInOutVisiblePos->z -= fT;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetGuildRelationShip( Player * pPlayer, BOOL bForceEnemy )
|
|
{
|
|
#ifdef _NA_003923_20120222_GUILD_RENEWAL_UI_RENEWAL
|
|
if( pPlayer->GetGuildRenderInfo().m_RelationType == eGUILD_RELATION_BOTH_HOSTILITY )
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
#else
|
|
if( pPlayer->GetGuildRenderInfo().m_RelationType == eGUILD_RELATION_BOTH_HOSTILITY ||
|
|
pPlayer->GetGuildRenderInfo().m_RelationType == eGUILD_RELATION_PROCLAIM_HOSTILITY )
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if( pPlayer->GetGuildRenderInfo().m_RelationType == eGUILD_RELATION_ONE_SIDE_HOSTILITY )
|
|
{
|
|
if( bForceEnemy )
|
|
return RELATIONKIND::Enemy;
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120222_GUILD_RENEWAL_UI_RENEWAL
|
|
else if( pPlayer->GetGuildRenderInfo().m_RelationType == eGUILD_RELATION_ALLIENCE )
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
|
|
BOOL GameFunc::IsFriendShip( Player * pPlayer )
|
|
{
|
|
uiPartyMan * partyMan = GET_DIALOG_MANAGER( uiPartyMan, UIMAN_PARTY );
|
|
|
|
if (partyMan)
|
|
{
|
|
if( partyMan->IsPartyMember( pPlayer->GetObjectKey() ) )
|
|
return TRUE;
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return TRUE;
|
|
}
|
|
#else
|
|
uiGuildMan * guildMan = GET_DIALOG_MANAGER( uiGuildMan, UIMAN_GUILD );
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return TRUE;
|
|
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL GameFunc::GetCheckPlayerOnTile( DWORD dwPlayerTile, DWORD dwHeroTile, DWORD dwTileAttr )
|
|
{
|
|
if( BIT_CHECK( dwPlayerTile, dwTileAttr ) && BIT_CHECK( dwHeroTile, dwTileAttr ) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationOfMonster( Monster * pMonster, BOOL bForceEnemy )
|
|
{
|
|
#ifdef _NA001415_091123_CHANGE_MOB_AI_IN_SAFETY_AREA_
|
|
if (g_pHero != NULL && pMonster != NULL)
|
|
{
|
|
DWORD dwMonsterAtt = pMonster->GetCurrentTileAtt(FALSE);
|
|
DWORD dwHeroAtt = g_pHero->GetCurrentTileAtt(FALSE);
|
|
|
|
if (BIT_CHECK(dwHeroAtt,PTA_SAFETY_ZONE) || BIT_CHECK(dwMonsterAtt, PTA_SAFETY_ZONE))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
#endif //_NA001415_091123_CHANGE_MOB_AI_IN_SAFETY_AREA_
|
|
// _NA_0_20100222_UNIT_TRIGGERS_FRIEND_MONSTER
|
|
BASE_NPCINFO* npc_info = pMonster->GetMonsterInfo();
|
|
if (npc_info != NULL)
|
|
{
|
|
if ((npc_info->m_byGrade == eNPC_FRIEND_MAPOBJECT_NPC) ||
|
|
(npc_info->m_byGrade == eNPC_FRIEND_MONSTER))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
|
|
if( pMonster->GetMonsterType() == MONSTER_TYPE_TOTEM )
|
|
return RELATIONKIND::None;
|
|
|
|
if(MONSTER_TYPE_SETTING_MAPOBJECT == pMonster->GetMonsterType()) //설치형 몬스터라면
|
|
{
|
|
Object* pTemp = g_ObjectManager.GetObject(MAP_OBJECT_KEY + pMonster->GetMapObjectKey());
|
|
if(pTemp && pTemp->IsKindOfObject(MAP_OBJECT))
|
|
{
|
|
//해당 설치형 몬스터와 엮여있는 맵오브젝트가 때릴수 없는 상태라면
|
|
MapObject* pMapObj = (MapObject*)pTemp;
|
|
if(false == pMapObj->GetbCanHit())
|
|
return RELATIONKIND::None;
|
|
}
|
|
}
|
|
|
|
if( pMonster->GetParentId() )
|
|
{
|
|
Player * pPlayer = (Player *)g_ObjectManager.GetObject( pMonster->GetParentId() );
|
|
|
|
if( pPlayer )//주인이 있다면 주인과의 관계를 본다.
|
|
{
|
|
return GameFunc::GetRelationOfPlayer(pPlayer, bForceEnemy);
|
|
}
|
|
}
|
|
else if( (g_pHero->GetGuildRenderInfo().m_GuildGuid!=INVALID_GUILDGUID) && g_pHero->GetGuildRenderInfo().m_GuildGuid == pMonster->GetMasterGuildID())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
|
|
/*
|
|
* GameFunc::GetRelationOfPlayer() 함수는 타일별 룰을 통한 플레이어간의 관계를 얻기 위해서 사용된다.
|
|
* 현재 GetRelationKindOfPlayerInField() - FiledScene
|
|
* GetRelationKindOfPlayerInDominationWar() - DominationWarScene
|
|
* GetRelationOfMonster()
|
|
* 함수에서 호출되거 있으며 GetRelationOfMonster() 에서는 소환수의 주인과의 관계를 알기위해 호출됨
|
|
*/
|
|
RELATIONKIND::TYPE GameFunc::GetRelationOfPlayer( Player * pPlayer, BOOL bForceEnemy )
|
|
{
|
|
#ifdef _NA001415_091123_CHANGE_MOB_AI_IN_SAFETY_AREA_
|
|
// 자신이거나 상대가 개인상점 상태일 경우
|
|
if( g_pHero && g_pHero->GetObjectKey() == pPlayer->GetObjectKey() )
|
|
return RELATIONKIND::Friend;
|
|
ePLAYER_BEHAVE_STATE behaveState = pPlayer->GetBeHaveState();
|
|
if( behaveState == PLAYER_BEHAVE_VENDOR_ESTABLISHER_STATE )
|
|
return RELATIONKIND::Vendor;
|
|
|
|
// PKScript 정보
|
|
PKOptionInfo& PKInfo = PKScriptParser::Instance()->GetPKOptionInfo();
|
|
|
|
// PK룰 객체 생성
|
|
static PKRuleForTile PKRuleforTile;
|
|
|
|
// 각플레이어 속성으로 체크로 적용할 룰 선택 & 관계를 얻음
|
|
bool bForce = (TRUE == bForceEnemy);
|
|
RELATIONKIND::TYPE relationType = PKRuleforTile.CheckRelationTileAttr(pPlayer, &PKInfo, bForce);
|
|
|
|
return relationType;
|
|
#else
|
|
if( g_pHero && g_pHero->GetObjectKey() == pPlayer->GetObjectKey() )
|
|
return RELATIONKIND::Friend;
|
|
|
|
ePLAYER_BEHAVE_STATE behaveState = pPlayer->GetBeHaveState();
|
|
|
|
if( behaveState == PLAYER_BEHAVE_VENDOR_ESTABLISHER_STATE )
|
|
return RELATIONKIND::Vendor;
|
|
|
|
if( !g_isPkServer )
|
|
return RELATIONKIND::Friend;
|
|
|
|
DWORD dwPlayerAtt = pPlayer->GetCurrentTileAtt(FALSE);
|
|
DWORD dwHeroAtt = g_pHero->GetCurrentTileAtt(FALSE);
|
|
|
|
|
|
PKOptionInfo& PKInfo = PKScriptParser::Instance()->GetPKOptionInfo();
|
|
BYTE IgnorePKTile = PKInfo.m_IgnorePKTile;
|
|
|
|
if (bForceEnemy && GetCheckPlayerOnTile(dwPlayerAtt, dwHeroAtt, PTA_FREE_CONFLICT_TILE) && !(IgnorePKTile&PKOptionInfo::ignore_FreePart))
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
if (IsFriendShip(pPlayer))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
#ifdef __LTJ_RELATION_OF_PLAYER_BUGFIX
|
|
// no operation
|
|
#else //__LTJ_RELATION_OF_PLAYER_BUGFIX
|
|
RELATIONKIND::TYPE state = GetGuildRelationShip( pPlayer, bForceEnemy );
|
|
|
|
if( state != RELATIONKIND::None )
|
|
return state;
|
|
|
|
if( bForceEnemy )
|
|
return RELATIONKIND::Enemy;
|
|
#endif //__LTJ_RELATION_OF_PLAYER_BUGFIX
|
|
|
|
if( GetCheckPlayerOnTile( dwPlayerAtt, dwHeroAtt, PTA_FREE_CONFLICT_TILE ) && !(IgnorePKTile&PKOptionInfo::ignore_FreePart) )
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if( GetCheckPlayerOnTile( dwPlayerAtt, dwHeroAtt, PTA_CONFLICT_TILE ) && !(IgnorePKTile&PKOptionInfo::ignore_NomalPart) )
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if( GetCheckPlayerOnTile( dwPlayerAtt, dwHeroAtt, PTA_PK_TILE ) && !(IgnorePKTile&PKOptionInfo::ignore_BoundaryPart) )
|
|
{
|
|
#ifdef __LTJ_RELATION_OF_PLAYER_BUGFIX
|
|
|
|
RELATIONKIND::TYPE state = GetGuildRelationShip( pPlayer, bForceEnemy );
|
|
|
|
if( state != RELATIONKIND::None )
|
|
return state;
|
|
|
|
#endif //__LTJ_RELATION_OF_PLAYER_BUGFIX
|
|
if( g_pHero->GetLevel() < PKInfo.m_PKAllowableLV || pPlayer->GetLevel() < PKInfo.m_PKProtectLV )
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
#ifdef _CHINA
|
|
if( pPlayer->GetChaoState() == eCHAO_STATE_CHAO )
|
|
#else
|
|
if( pPlayer->GetChaoState() == eCHAO_STATE_CHAO || pPlayer->IsAttackBeginPlayer() )
|
|
#endif
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
#ifdef __LTJ_RELATION_OF_PLAYER_BUGFIX
|
|
if( bForceEnemy )
|
|
return RELATIONKIND::Enemy;
|
|
#endif //__LTJ_RELATION_OF_PLAYER_BUGFIX
|
|
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if (GetCheckPlayerOnTile( dwPlayerAtt, dwHeroAtt, PTA_DOMINATION_WAR_TILE ))
|
|
{
|
|
if(pPlayer->IsExistGuild())
|
|
{
|
|
if( eGUILD_RELATION_ALLIENCE == pPlayer->GetGuildRenderInfo().m_RelationType )
|
|
return RELATIONKIND::Friend;
|
|
else if(eGUILD_RELATION_NONE == pPlayer->GetGuildRenderInfo().m_RelationType )
|
|
return RELATIONKIND::None;
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RELATIONKIND::TYPE state = GetGuildRelationShip( pPlayer, bForceEnemy );
|
|
|
|
if( state != RELATIONKIND::None )
|
|
return state;
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
#endif //_NA001415_091123_CHANGE_MOB_AI_IN_SAFETY_AREA_
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
YH2DO 나중에는 NPC나 파티설정등이 추가 되면 체계적으로 정리해야 함
|
|
*/
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfHero(Character* pObject,BOOL bForceEnemy)
|
|
{
|
|
if (pObject->IsKindOfObject(PLAYER_OBJECT))
|
|
{
|
|
Player *pPlayer = (Player *)pObject;
|
|
|
|
ePLAYER_BEHAVE_STATE behaveState = pPlayer->GetBeHaveState();
|
|
|
|
if (behaveState == PLAYER_BEHAVE_VENDOR_ESTABLISHER_STATE)
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
if (g_pHero)
|
|
{
|
|
if(pPlayer->GetObjectKey() == g_pHero->GetObjectKey())//이거 먼저 검사해야하지 않나?
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
|
|
if ( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_PVP )
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
|
|
if(partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if ( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_SSQ )
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_VILLAGE)
|
|
{
|
|
if(!g_isPkServer)
|
|
return RELATIONKIND::Friend;
|
|
DWORD dwPlayerAtt=pPlayer->GetCurrentTileAtt(FALSE);
|
|
DWORD dwHeroAtt=g_pHero->GetCurrentTileAtt(FALSE);
|
|
|
|
//Todo:공격할수 있는 유저 레벨이 20 공격 받는 유저 레벨이 20일때 공격
|
|
if(BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE))
|
|
{
|
|
if(g_pHero->GetLevel()<20||pPlayer->GetLevel()<20)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(BIT_CHECK(dwPlayerAtt,PTA_FREE_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_FREE_CONFLICT_TILE))//자유 분쟁지역일때
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
|
|
}//일반 분쟁 지역일때
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_CONFLICT_TILE))
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE))
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
//카오 상태지만 길드원이나 파티원은 친구
|
|
if(pPlayer->GetChaoState()==eCHAO_STATE_CHAO || pPlayer->IsAttackBeginPlayer())
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
//Todo:강제 공격
|
|
if(bForceEnemy)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
return RELATIONKIND::Friend;
|
|
|
|
}
|
|
else if( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_FIELD)
|
|
{
|
|
|
|
if(!g_isPkServer)
|
|
return RELATIONKIND::Friend;
|
|
DWORD dwPlayerAtt=pPlayer->GetCurrentTileAtt(FALSE);
|
|
DWORD dwHeroAtt=g_pHero->GetCurrentTileAtt(FALSE);
|
|
|
|
if(BIT_CHECK(dwPlayerAtt,PTA_FREE_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_FREE_CONFLICT_TILE))
|
|
{
|
|
|
|
if(bForceEnemy)
|
|
return RELATIONKIND::Enemy;
|
|
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_CONFLICT_TILE))
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE))
|
|
{
|
|
if(pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_BOTH_HOSTILITY||
|
|
pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_PROCLAIM_HOSTILITY)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_ONE_SIDE_HOSTILITY)
|
|
{
|
|
if(bForceEnemy)
|
|
return RELATIONKIND::Enemy;
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if(pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_ALLIENCE)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
// 길드원이나 파티원은 친구
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
//레벨이 카오나 ctrl보다 우선순위가 높아야한다.
|
|
if(BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE))
|
|
{
|
|
if(g_pHero->GetLevel()<20||pPlayer->GetLevel()<20)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
|
|
#ifdef _CHINA
|
|
if(pPlayer->GetChaoState()==eCHAO_STATE_CHAO)
|
|
#else
|
|
if(pPlayer->GetChaoState()==eCHAO_STATE_CHAO || pPlayer->IsAttackBeginPlayer())
|
|
#endif//_CHINA:중국에서는 프리카오시 자동타켓딩되지않는다.(0814시요청)
|
|
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
//Todo:강제 공격
|
|
if(bForceEnemy)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
|
|
if(pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_BOTH_HOSTILITY||
|
|
pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_PROCLAIM_HOSTILITY)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_ONE_SIDE_HOSTILITY)
|
|
{
|
|
if(bForceEnemy)
|
|
return RELATIONKIND::Enemy;
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if(pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_ALLIENCE)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
else if ( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_CHUNTING )
|
|
{
|
|
#if !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
uiBattleZoneReadyCHuntingConfig* cfg = GET_CAST_DIALOG( uiBattleZoneReadyCHuntingConfig,
|
|
IM_BATTLEZONE_MANAGER::BATTLEZONE_READY_CHUNTING_CFG );
|
|
|
|
assert (cfg);
|
|
if (cfg->GetCfgs().compModeType == eCOMPETITION_MODE_SURVIVAL ||
|
|
// FIXME: 2006년 5월 6일 - 타임 어택에선 서로 공격 할 수 없다.
|
|
// cfg->GetCfgs().compModeType == eCOMPETITION_MODE_TIME_ATTACK ||
|
|
cfg->GetCfgs().compModeType == eCOMPETITION_MODE_DEATH_MATCH) //pvp모드 일때
|
|
{
|
|
//Todo: 파티가 다르면 적,파티가 같으면 프렌드
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
|
|
if(partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
// FIXME: 2006년 5월 6일 - 타임 어택에선 서로 공격할 수 없으므로 Friend로 설정
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
return RELATIONKIND::Friend;
|
|
#endif //#if !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
}
|
|
else if (pObject->IsKindOfObject(MONSTER_OBJECT))//Todo:주인과의 관계로 변경
|
|
{
|
|
Monster *pMonster = (Monster *)pObject;
|
|
|
|
if(pMonster->GetMonsterType()==MONSTER_TYPE_TOTEM)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if(pMonster->GetParentId())
|
|
{
|
|
Player * pPlayer = (Player *)g_ObjectManager.GetObject( pMonster->GetParentId() );
|
|
|
|
if(pPlayer)//주인이 있다면 주인과의 관계를 본다.
|
|
{
|
|
ePLAYER_BEHAVE_STATE behaveState = pPlayer->GetBeHaveState();
|
|
|
|
if (behaveState == PLAYER_BEHAVE_VENDOR_ESTABLISHER_STATE)
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
if(pPlayer->GetObjectKey() == g_pHero->GetObjectKey())//이거 먼저 검사해야하지 않나?
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
|
|
if ( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_PVP )
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
|
|
if(partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_VILLAGE)//&&!pPlayer->GetGMGrade()
|
|
{
|
|
if(!g_isPkServer)
|
|
return RELATIONKIND::Friend;
|
|
|
|
DWORD dwPlayerAtt=pPlayer->GetCurrentTileAtt(FALSE);
|
|
DWORD dwHeroAtt=g_pHero->GetCurrentTileAtt(FALSE);
|
|
|
|
if(BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE))
|
|
{
|
|
if(g_pHero->GetLevel()<20||pPlayer->GetLevel()<20)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(BIT_CHECK(dwPlayerAtt,PTA_FREE_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_FREE_CONFLICT_TILE))
|
|
{
|
|
if( bForceEnemy )
|
|
return RELATIONKIND::Enemy;
|
|
|
|
if( IsFriendShip( pPlayer ) )
|
|
return RELATIONKIND::Friend;
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_CONFLICT_TILE))
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE))
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
if(pPlayer->GetChaoState()==eCHAO_STATE_CHAO || pPlayer->IsAttackBeginPlayer())
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
//Todo:강제 공격
|
|
if(bForceEnemy)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
}
|
|
else if( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_FIELD)
|
|
{
|
|
if(!g_isPkServer)
|
|
return RELATIONKIND::Friend;
|
|
|
|
if(pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_BOTH_HOSTILITY||
|
|
pPlayer->GetGuildRenderInfo().m_RelationType==eGUILD_RELATION_PROCLAIM_HOSTILITY)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if( pPlayer->GetGuildRenderInfo().m_RelationType == eGUILD_RELATION_ALLIENCE )
|
|
{
|
|
if( bForceEnemy )
|
|
return RELATIONKIND::Enemy;
|
|
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
|
|
DWORD dwPlayerAtt=pPlayer->GetCurrentTileAtt(FALSE);
|
|
DWORD dwHeroAtt=g_pHero->GetCurrentTileAtt(FALSE);
|
|
|
|
if( BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE) )
|
|
{
|
|
if( g_pHero->GetLevel() < 20 || pPlayer->GetLevel() < 20 )
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
|
|
if(BIT_CHECK(dwPlayerAtt,PTA_FREE_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_FREE_CONFLICT_TILE))
|
|
{
|
|
if( bForceEnemy )
|
|
return RELATIONKIND::Enemy;
|
|
|
|
if( IsFriendShip( pPlayer ) )
|
|
return RELATIONKIND::Friend;
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_CONFLICT_TILE)&&BIT_CHECK(dwHeroAtt,PTA_CONFLICT_TILE))
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(BIT_CHECK(dwPlayerAtt,PTA_PK_TILE)&&BIT_CHECK(dwHeroAtt,PTA_PK_TILE))
|
|
{
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
if (partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
if (GuildSystem::Function::IsGuildMember(pPlayer->GetGuildName()) == true)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
if(guildMan)
|
|
{
|
|
if(guildMan->IsGuildMember(pPlayer->GetGuildName()))
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
|
|
if(pPlayer->GetChaoState()==eCHAO_STATE_CHAO || pPlayer->IsAttackBeginPlayer())
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
//Todo:강제 공격
|
|
if(bForceEnemy)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
else if ( GameFramework::GetCurrentScene()->GetType() == SCENE_TYPE_CHUNTING )
|
|
{
|
|
#if !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
uiBattleZoneReadyCHuntingConfig* cfg = GET_CAST_DIALOG( uiBattleZoneReadyCHuntingConfig,
|
|
IM_BATTLEZONE_MANAGER::BATTLEZONE_READY_CHUNTING_CFG );
|
|
|
|
assert (cfg);
|
|
if (cfg->GetCfgs().compModeType == eCOMPETITION_MODE_SURVIVAL ||
|
|
cfg->GetCfgs().compModeType == eCOMPETITION_MODE_TIME_ATTACK ||
|
|
cfg->GetCfgs().compModeType == eCOMPETITION_MODE_DEATH_MATCH)
|
|
{
|
|
//Todo: 파티가 다르면 적,파티가 같으면 프렌드
|
|
uiPartyMan* partyMan =
|
|
static_cast<uiPartyMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_PARTY));
|
|
|
|
if(partyMan)
|
|
{
|
|
if(partyMan->IsPartyMember(pPlayer->GetObjectKey()))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
|
|
|
|
}
|
|
|
|
#else
|
|
return RELATIONKIND::Enemy;
|
|
#endif //#if !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
|
|
}
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
|
|
}
|
|
else if(pObject->IsKindOfObject( PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject( NPC_OBJECT) || pObject->IsKindOfObject( LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject( MERCHANT_OBJECT ))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
//#endif
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
DWORD GameFunc::GetAttackTargetWithinRange(WzVector vPos,float fRange,DWORD *pObjectKeys,DWORD exception)
|
|
{
|
|
DWORD ret = 0;
|
|
Object_Map_Itr itr = g_ObjectManager.GetBegin();
|
|
|
|
for (; itr != g_ObjectManager.GetEnd(); itr++)
|
|
{
|
|
Object * pObject = static_cast<Object *>(itr->second);
|
|
if (!pObject)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(MONSTER_OBJECT ))
|
|
{
|
|
Monster *pMonster = static_cast<Monster *>(itr->second);
|
|
|
|
if (pMonster->GetObjectKey() == exception)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
WzVector vDistance = vPos - pMonster->GetPosition();
|
|
float fLength = VectorLength2(&vDistance);
|
|
if (fLength <= fRange * fRange)
|
|
{
|
|
vDistance.z = 0.0f;
|
|
if (pMonster->CanBeAttackTarget())
|
|
{
|
|
pObjectKeys[ret] = pMonster->GetObjectKey();
|
|
ret++;
|
|
if (ret >= 12) break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
DWORD GameFunc::GetAttackTargetWithinLine(WzVector vPos,WzVector vDest,float fRange,DWORD *pObjectKeys,DWORD exception)
|
|
{
|
|
DWORD ret = 0;
|
|
Object_Map_Itr itr = g_ObjectManager.GetBegin();
|
|
|
|
// 사각형의 축 두개를 만든다.
|
|
vPos.z = 0.0f;
|
|
vDest.z = 0.0f;
|
|
|
|
WzVector vDiff = vPos - vDest;
|
|
WzVector vCenter = (vPos + vDest) * 0.5f;
|
|
|
|
// 두좌표가 차이가없으면 타겟이 없음을 리턴
|
|
if (vDiff.x == 0 && vDiff.y == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
float fLength = VectorLength(&vDiff);
|
|
|
|
VectorNormalize(&vDiff,&vDiff);
|
|
|
|
float fAxis1X = vDiff.x;
|
|
float fAxis1Y = vDiff.y;
|
|
|
|
float fAxis2X = vDiff.y;
|
|
float fAxis2Y = -vDiff.x;
|
|
|
|
|
|
for (; itr != g_ObjectManager.GetEnd(); itr++)
|
|
{
|
|
Object * pObject = static_cast<Object *>(itr->second);
|
|
if (!pObject)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(MONSTER_OBJECT))
|
|
{
|
|
Monster *pMonster = static_cast<Monster *>(itr->second);
|
|
|
|
if (pMonster->GetObjectKey() == exception)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (pMonster->CanBeAttackTarget())
|
|
{
|
|
|
|
WzVector vOffset = pMonster->GetPosition() - vCenter;
|
|
|
|
// 축변환~
|
|
float fNewAxisX = -(vOffset.x * fAxis2Y + vOffset.y * -fAxis1Y);
|
|
float fNewAxisY = -(vOffset.x * -fAxis2X + vOffset.y * fAxis1X);
|
|
|
|
float fDet = fAxis1X * fAxis2Y - fAxis1Y * fAxis2X;
|
|
|
|
// 변환된 축좌표가 사각형안에 들어가는지 체크
|
|
if (fabs(fNewAxisX) <= fLength * 0.5f + 1.0f)
|
|
{
|
|
if (fabs(fNewAxisY) <= fRange )
|
|
{
|
|
pObjectKeys[ret] = pMonster->GetObjectKey();
|
|
ret++;
|
|
|
|
if (ret >= 12)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
BOOL GameFunc::IsMove(WzVector vPos,WzVector vDest,BOOL bCheckMakePath,DWORD dwMaxNode)
|
|
{
|
|
assert(g_pPathExplorer);//초기 시작시 생성함으로 널일이유가 없겠지만..
|
|
assert(g_pMap);
|
|
|
|
if(!g_pPathExplorer || !g_pMap)
|
|
return FALSE;
|
|
|
|
g_pPathExplorer->Stop();
|
|
|
|
g_pSunTerrain->PathExp_Reset(g_pPathExplorer, &vPos, -1);
|
|
|
|
// 대상 Tile 얻기
|
|
int iTileFocussing = -1;
|
|
iTileFocussing = g_pSunTerrain->x_pPathFinder->GetTileToStand( vDest, NULL, -1.0f, 100.0f );
|
|
|
|
if( iTileFocussing < 0 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// 갈수 없는 타일로 가는 명령은 무시
|
|
if (g_pMap->GetWorldBase()->x_pPathFinder->GetAttribute(iTileFocussing) & (PTA_ONLY_JUMP |PTA_NO_WALK))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (vPos == vDest)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (bCheckMakePath) //이동경로까지 검사 할경우
|
|
{
|
|
// 디폴트 이동 제약 타일
|
|
WORD wAttr = PTA_ONLY_JUMP | PTA_NO_WALK | PTA_PLAYER_FALLDOWN_TILE;
|
|
|
|
ENUM_FINDPATH_RESULT rt = g_pSunTerrain->PathExp_FindPath(g_pPathExplorer, vDest, iTileFocussing, wAttr, dwMaxNode);
|
|
|
|
if (rt != EFR_SUCCESS)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void ClampAngle(float* pAngle)
|
|
{
|
|
float fNewAngle = *pAngle;
|
|
fNewAngle = fmod(fNewAngle,WZ_PI * 2.0f);
|
|
|
|
if (fNewAngle < 0.0f)
|
|
{
|
|
fNewAngle += WZ_PI * 2.0f;
|
|
}
|
|
|
|
*pAngle = fNewAngle;
|
|
}
|
|
|
|
void RenderOutLinedText(TCHAR *pText,RECT *prc,WzColor color, BYTE alpha/* = 255*/)
|
|
{
|
|
if(prc)
|
|
{
|
|
RECT rc = *prc;
|
|
BOOL bTest = g_pSunRenderer->IsEnableZTest();
|
|
g_pSunRenderer->SetZBufferTest(FALSE);
|
|
|
|
WzColor wzColor = WzColor_RGBA(0,0,0,alpha);
|
|
|
|
g_pSunRenderer->x_pManagerTextOut->DrawText(pText,
|
|
&rc,
|
|
color,
|
|
WzColor_RGBA(0,0,0,0),
|
|
TP_HLEFT,
|
|
ETS_OUTLINE,
|
|
wzColor);
|
|
|
|
g_pSunRenderer->SetZBufferTest(bTest);
|
|
}
|
|
|
|
}
|
|
//Todo:현재 감마에 적용
|
|
void SetGamma(DWORD dwRamp)
|
|
{
|
|
dwRamp=min(255,dwRamp);
|
|
dwRamp=max(0,dwRamp);
|
|
float fPercent = (float)dwRamp / 255;
|
|
|
|
WORD wSred[256];
|
|
WORD wSgreen[256];
|
|
WORD wSblue[256];
|
|
|
|
|
|
for(int i=0;i<256;i++)
|
|
{
|
|
wSred[i] =WORD(g_D3dGammaRamp.red[i] * fPercent);
|
|
wSred[i]=min(65535,wSred[i]);
|
|
|
|
wSgreen[i] = WORD(g_D3dGammaRamp.green[i] * fPercent);
|
|
wSgreen[i]=min(65535,wSgreen[i]);
|
|
|
|
wSblue[i] = WORD(g_D3dGammaRamp.blue[i] * fPercent);
|
|
wSblue[i]=min(65535,wSblue[i]);
|
|
|
|
}
|
|
|
|
g_pSunRenderer->SetGammaRamp(wSred,wSgreen,wSblue);
|
|
}
|
|
|
|
DWORD GetGamma()
|
|
{
|
|
|
|
return 255;
|
|
}
|
|
|
|
|
|
|
|
void RenderShadowedText(TCHAR *pText,RECT *prc,WzColor color)
|
|
{
|
|
if(prc)
|
|
{
|
|
RECT rc = *prc;
|
|
BOOL bTest = g_pSunRenderer->IsEnableZTest();
|
|
g_pSunRenderer->SetZBufferTest(FALSE);
|
|
|
|
g_pSunRenderer->x_pManagerTextOut->DrawText(pText,
|
|
&rc,
|
|
color,
|
|
WzColor_RGBA(0,0,0,0),
|
|
TP_HLEFT,
|
|
ETS_SHADOW
|
|
);
|
|
|
|
g_pSunRenderer->SetZBufferTest(bTest);
|
|
}
|
|
|
|
}
|
|
|
|
void RenderBlockedText(TCHAR *pText,RECT *prc,WzColor color,WzColor BackColor)
|
|
{
|
|
if(prc)
|
|
{
|
|
RECT rc = *prc;
|
|
BOOL bTest = g_pSunRenderer->IsEnableZTest();
|
|
g_pSunRenderer->SetZBufferTest(FALSE);
|
|
|
|
SIZE szBox;
|
|
RECT rcBox;
|
|
|
|
g_pSunRenderer->x_pManagerTextOut->GetTextExtentPoint(pText,_tcslen(pText),&szBox);
|
|
|
|
rcBox.left = rc.left - 1;
|
|
rcBox.right = rc.left + szBox.cx + 1;
|
|
rcBox.top = rc.top;
|
|
rcBox.bottom = rc.top + szBox.cy + 1;
|
|
|
|
g_InterfaceManager.RenderRect( rcBox, BackColor );
|
|
|
|
g_pSunRenderer->x_pManagerTextOut->DrawText(pText,rc.left,rc.top,color);
|
|
g_pSunRenderer->SetZBufferTest(bTest);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderBlockedTextWithDepthTest(LPCTSTR pText,RECT *prc,WzColor color,WzColor BackColor,float fDepthTest, bool bPlayer /*= false*/)
|
|
{
|
|
if(prc)
|
|
{
|
|
RECT rc = *prc;
|
|
BOOL bTest = g_pSunRenderer->IsEnableZTest();
|
|
g_pSunRenderer->SetZBufferTest(TRUE);
|
|
|
|
if(false == bPlayer)
|
|
{
|
|
SIZE szBox;
|
|
RECT rcBox;
|
|
|
|
g_pSunRenderer->x_pManagerTextOut->GetTextExtentPoint((TCHAR*)pText,_tcslen(pText),&szBox); // 글로벌 엔진버전이 낮아서 error발생 (TCHAR*)필요 추후 제거 요망
|
|
|
|
rcBox.left = rc.left - 1;
|
|
rcBox.right = rc.left + szBox.cx + 1;
|
|
rcBox.top = rc.top;
|
|
|
|
rcBox.bottom = rc.top + szBox.cy + 1;
|
|
|
|
g_InterfaceManager.RenderRectWithZTest(rcBox,BackColor,fDepthTest);
|
|
}
|
|
|
|
g_pSunRenderer->x_pManagerTextOut->BeginSpriteTextWithDepth(fDepthTest);
|
|
g_pSunRenderer->x_pManagerTextOut->DrawText((TCHAR*)pText,rc.left,rc.top,color); // 글로벌 엔진버전이 낮아서 error발생 (TCHAR*)필요 추후 제거 요망
|
|
g_pSunRenderer->x_pManagerTextOut->EndSpriteTextWithDepth();
|
|
g_pSunRenderer->SetZBufferTest(bTest);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
eWEAPONSOUNDKIND GameFunc::GetWeaponSoundKind(eWEAPONTYPE eType)
|
|
{
|
|
switch(eType)
|
|
{
|
|
case eWEAPONTYPE_TWOHANDAXE:
|
|
case eWEAPONTYPE_TWOHANDSWORD:
|
|
return eWEAPONSOUNDKIND_TWOHANDED;
|
|
case eWEAPONTYPE_ONEHANDSWORD:
|
|
return eWEAPONSOUNDKIND_ONEHANDSWORD;
|
|
case eWEAPONTYPE_SPEAR:
|
|
return eWEAPONSOUNDKIND_SPEAR;
|
|
case eWEAPONTYPE_ONEHANDCROSSBOW:
|
|
return eWEAPONSOUNDKIND_ARROW;
|
|
case eWEAPONTYPE_ETHERWEAPON:
|
|
return eWEAPONSOUNDKIND_ETHERBULLET;
|
|
case eWEAPONTYPE_STAFF:
|
|
return eWEAPONSOUNDKIND_STAFF;
|
|
case eWEAPONTYPE_DAGGER:
|
|
return eWEAPONSOUNDKIND_DAGGER;
|
|
case eWEAPONTYPE_WHIP:
|
|
return eWEAPONSOUNDKIND_WHIP;
|
|
case eWEAPONTYPE_ORB:
|
|
return eWEAPONSOUNDKIND_MAGICBULLET;
|
|
//_NA_004965_20120613_NEW_CHARACTER_MYSTIC
|
|
case eWEAPONTYPE_GUNTLET:
|
|
return eWEAPONSOUNDKIND_GUNTLET;
|
|
case eWEAPONTYPE_POLEARM:
|
|
return eWEAPONSOUNDKIND_POLEARM;
|
|
//_NA_000000_20130812_NEW_CHARACTER_HELLROID
|
|
case eWEAPONTYPE_HELLROID_1:
|
|
return eWEAPONSOUNDKIND_HELLROIDWEAPON_1;
|
|
//_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
|
|
case eWEAPONTYPE_ARCBLADE:
|
|
return eWEAPONSOUNDKIND_ARCBLADE;
|
|
default:
|
|
case eWEAPONTYPE_PUNCH:
|
|
#ifdef _YJ_FISHING_SYSTEM_000933
|
|
case eWEAPONTYPE_FISHING_POLE:
|
|
#endif //_YJ_FISHING_SYSTEM_000933
|
|
{
|
|
return eWEAPONSOUNDKIND_UNDEFINED;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL GameFunc::GetBonePos(CWzUnitDraw *pSkeleton, int index, WzVector *pVector)
|
|
{
|
|
if (pSkeleton && pVector && pSkeleton->GetWzUnit())
|
|
{
|
|
WzMatrix * pBoneMatrix = pSkeleton->GetTransformBuffer();
|
|
|
|
if (pBoneMatrix)
|
|
{
|
|
HANDLE handle = pSkeleton->GetWzUnit()->GetWzdHandle();
|
|
|
|
if (handle != INVALID_HANDLE_VALUE)
|
|
{
|
|
CWzdBase * pBase = g_pSunRenderer->x_pManagerWzdLoader->GetWzd(handle);
|
|
|
|
if ( pBase )
|
|
{
|
|
if (index >= 0 && index < pBase->GetNumNode())
|
|
{
|
|
pVector->x = pBoneMatrix[index]._41;
|
|
pVector->y = pBoneMatrix[index]._42;
|
|
pVector->z = pBoneMatrix[index]._43;
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL GameFunc::GetBoneMatrix( CWzUnitDraw* pSkeleton, int index, WzMatrix* pMatrix )
|
|
{
|
|
if( pSkeleton && pMatrix )
|
|
{
|
|
MatrixIdentity( pMatrix );
|
|
|
|
if( WzMatrix* pBoneMatrix = pSkeleton->GetTransformBuffer() )
|
|
{
|
|
if( index >= 0 && index < pSkeleton->GetTransformBufferSize() )
|
|
{
|
|
*pMatrix = pBoneMatrix[index];
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL GameFunc::UpdateCursorByPickedObject(Object * pObject)
|
|
{
|
|
if (!g_pHero)
|
|
return FALSE;
|
|
|
|
if (MouseHandler::Instance()->IsExistItemAtHand())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (!pObject)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(MAP_OBJECT))
|
|
{
|
|
MapObject * pMapObject = (MapObject *)pObject;
|
|
|
|
if(FALSE == pMapObject->GetShow())
|
|
return FALSE;
|
|
|
|
if (pMapObject->CheckTriggerActive())
|
|
{
|
|
if (pMapObject->IsTriggerOperating())
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Operating_switch_Highlight );
|
|
}
|
|
else
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Operating_switch );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
else if(pMapObject->IsWayPointObj()
|
|
|| pMapObject->IsDominationObject()
|
|
|| pMapObject->IsAirShipObject())
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Conversation );
|
|
return TRUE;
|
|
|
|
}
|
|
else if(INVALID_WZID != pMapObject->GetCollectionID())
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_PickAxe );
|
|
return TRUE;
|
|
}
|
|
#ifdef _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
|
|
else if (pMapObject->IsBattleGroundResurrectionObject())
|
|
{
|
|
if (ChaosSystem::GetBattleGroundData().player_state() == kPlayerStateStandbyResurectionRefuse)
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Operating_switch );
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
#endif //_NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
|
|
|
|
}
|
|
else if (pObject->IsKindOfObject(ITEM_OBJECT))
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Open_Box );
|
|
return TRUE;
|
|
}
|
|
#ifdef _NA_008016_20150203_SUN_RANKING_SYSTEM_STATUE
|
|
else if (pObject->IsKindOfObject(STATUE_PLAYER_OBJECT))
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Conversation );
|
|
return TRUE;
|
|
}
|
|
#endif // _NA_008016_20150203_SUN_RANKING_SYSTEM_STATUE
|
|
else
|
|
{
|
|
Character * pPickedCharacter = static_cast<Character *>(pObject);
|
|
assert(pPickedCharacter);
|
|
switch( GameFramework::GetCurrentScene()->GetRelationKindOfCharacter( pPickedCharacter, g_HeroInput.lsForceAttack() ) )
|
|
{
|
|
case RELATIONKIND::Enemy:
|
|
{
|
|
if (g_HeroInput.IsAttackSkillArea())
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Magic_Scope_Highlight );
|
|
}
|
|
else
|
|
{
|
|
if (g_pHero->GetTargetObject() &&
|
|
g_pHero->GetTargetObject() == pObject)
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Attack_Target_Highlight );
|
|
}
|
|
else
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Attack_Target );
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case RELATIONKIND::Friend:
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case RELATIONKIND::Vendor:
|
|
case RELATIONKIND::Assistant:
|
|
{
|
|
NPC* pNPC = (NPC*)pObject;
|
|
switch(pNPC->GetExtraInfo()->m_eNPCTYPE)
|
|
{
|
|
case eNPC_TYPE_EVENT_DONATION:
|
|
{
|
|
if (g_pHero->GetTargetObject() &&
|
|
g_pHero->GetTargetObject() == pObject)
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction(MouseCursor::eMouseCursor_Donation_Highlight);
|
|
}
|
|
else
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction(MouseCursor::eMouseCursor_Donation);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_EVENT_BUFF:
|
|
{
|
|
if (g_pHero->GetTargetObject() &&
|
|
g_pHero->GetTargetObject() == pObject)
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction(MouseCursor::eMouseCursor_Operating_switch_Highlight);
|
|
}
|
|
else
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction(MouseCursor::eMouseCursor_Operating_switch);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
CursorChangeTransact::Instance()->ChangeTranaction( MouseCursor::eMouseCursor_Conversation );
|
|
}
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case RELATIONKIND::None:
|
|
default:
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
SolarDialog* GameFunc::NPCMeetWithForward(MAPID MapID, FIELDID FieldID, CODETYPE NpcCode, DWORD dwNPCKey /*= 0*/)
|
|
{
|
|
uiQuestMan * pQuestMan =
|
|
(uiQuestMan * )g_InterfaceManager.GetUserInterfaceManager(UIMAN_QUEST);
|
|
|
|
if ( pQuestMan )
|
|
{
|
|
return pQuestMan->OpenForwardWindow(MapID, FieldID, NpcCode, dwNPCKey);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
SolarDialog *
|
|
GameFunc::OpenNPCMeetDialog(MAPID MapID, FIELDID FieldID, CODETYPE NpcCode)
|
|
{
|
|
EXTRA_NPCINFO_SET * pInfoSet =
|
|
NPCInfoParser::Instance()->GetExtraInfoSetFromFieldID( (MAPCODE)MapID , (FIELDID)FieldID);
|
|
|
|
vector<EXTRA_NPCINFO*>::iterator itr;
|
|
|
|
EXTRA_NPCINFO * pInfo = NULL;
|
|
EXTRA_NPCINFO * pFindInfo = NULL;
|
|
|
|
for ( itr = pInfoSet->GetBegin(); itr != pInfoSet->GetEnd(); itr ++)
|
|
{
|
|
pInfo = *itr;
|
|
if ( pInfo->m_NPCCODE == NpcCode )
|
|
{
|
|
pFindInfo = pInfo;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (pFindInfo)
|
|
{
|
|
switch (pFindInfo->m_eNPCTYPE)
|
|
{
|
|
case eNPC_TYPE_GUARD:
|
|
{
|
|
uiQuestCommonForward* pQuestCommonForward = GET_CAST_DIALOG( uiQuestCommonForward, IM_QUEST_MANAGER::QUEST_COMMON_FORWARD );
|
|
|
|
if(pQuestCommonForward)
|
|
{
|
|
pQuestCommonForward->ShowInterfaceWithSound(TRUE);
|
|
|
|
keyMsg msg;
|
|
ZeroMemory(&msg,sizeof(msg));
|
|
msg.dwType = eDoType_dialog_Quest_NPC;
|
|
msg.wParam = QUEST_WINDOW_NPC;
|
|
msg.DoSomething = GlobalFunc::DoShowQuestWindow;
|
|
g_KeyQueueManager.PushBack(msg);
|
|
|
|
return (SolarDialog*)pQuestCommonForward;
|
|
}
|
|
}
|
|
break;
|
|
case eNPC_TYPE_MAKE_ZONE:
|
|
{
|
|
// 미션 보상을 받지 않은 상태이면.
|
|
if (BattleScene::m_bMissionReward)
|
|
{
|
|
TCHAR szText[512];
|
|
|
|
const int CANNOT_ENTER_BATTLEZONE_CODE = 5368;
|
|
|
|
g_InterfaceManager.GetInterfaceString(CANNOT_ENTER_BATTLEZONE_CODE,szText,512);
|
|
|
|
GlobalFunc::OutputMsg_Error(eOUTPUT_MSG_TOP_SHOW,szText);
|
|
return NULL;
|
|
|
|
}
|
|
|
|
g_InterfaceManager.HideAllWindows();
|
|
g_HeroInput.SetCurrentTarget(0);
|
|
|
|
// 배틀존 리스트 UI 띄우기
|
|
uiBase* pUIBase = GET_DIALOG( IM_BATTLEZONE_MANAGER::BATTLEZONE_LIST );
|
|
|
|
if (pUIBase)
|
|
{
|
|
if(g_pMap->GetOriginWeather())
|
|
{
|
|
g_pMap->SetRenderWeather(FALSE);
|
|
}
|
|
|
|
BOOL bShow = !pUIBase->IsVisible();
|
|
pUIBase->ShowInterfaceWithSound(bShow);
|
|
}
|
|
|
|
return (SolarDialog *)pUIBase;
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_BANK://1
|
|
{
|
|
#ifdef _NA_003923_20120130_GUILD_RENEWAL_MOD_WAREHOUSE_SLOT_NUM
|
|
uiBankDialog *pBankDlg = GET_CAST_DIALOG(uiBankDialog, IM_BANK_MANAGER::BANK_DIALOG);
|
|
#else
|
|
BankDialog *pBankDlg = GET_CAST_DIALOG(BankDialog, IM_BANK_MANAGER::BANK_DIALOG);
|
|
#endif //_NA_003923_20120130_GUILD_RENEWAL_MOD_WAREHOUSE_SLOT_NUM
|
|
|
|
if (pBankDlg && !pBankDlg->IsVisibleWindow())
|
|
{
|
|
pBankDlg->SendWareHouseStart();
|
|
return (SolarDialog*)pBankDlg;
|
|
}
|
|
|
|
return pBankDlg;
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_STORE:
|
|
{
|
|
ShopDialog * pShopDlg = (ShopDialog *)g_InterfaceManager.GetDialog(InterfaceManager::DIALOG_SHOP);
|
|
if ( pShopDlg && !pShopDlg->IsVisibleWindow() )
|
|
{
|
|
pShopDlg->SetShopID( NpcCode );
|
|
g_InterfaceManager.ShowDialog(InterfaceManager::DIALOG_SHOP, TRUE);
|
|
return (SolarDialog *)pShopDlg;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_GUILD:
|
|
{
|
|
#ifdef _NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
uiGuildMenu* guild_menu = GET_CAST_DIALOG(uiGuildMenu, uiGuildMenu::kDialog_ID);
|
|
if (guild_menu != NULL)
|
|
{
|
|
guild_menu->ShowInterfaceWithSound(TRUE);
|
|
return (SolarDialog *)guild_menu;
|
|
}
|
|
#else
|
|
// 길드 메뉴
|
|
uiGuildMan* guildMan =
|
|
static_cast<uiGuildMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_GUILD));
|
|
|
|
uiBase * guildMenu = GET_DIALOG( IM_GUILD_MANAGER::GUILD_MENU );
|
|
|
|
if (guildMan)
|
|
{
|
|
if (guildMenu)
|
|
{
|
|
guildMenu->ShowInterfaceWithSound(TRUE);
|
|
return (SolarDialog *)guildMenu;
|
|
}
|
|
}
|
|
#endif //_NA_003923_20120217_GUILD_RENEWAL_UI_GUILD_MANAGER
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_EVENT:
|
|
{
|
|
// 이벤트 메뉴
|
|
uiEventMan* eventMan = static_cast<uiEventMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_EVENT));
|
|
|
|
uiEventWindow * eventDlg = GET_CAST_DIALOG( uiEventWindow, IM_EVENT_MANAGER::EVENT_WINDOW );
|
|
|
|
if(eventMan && eventDlg)
|
|
{
|
|
eventMan->SendEventTimePeriod();
|
|
return (SolarDialog *)eventDlg;
|
|
}
|
|
}
|
|
break;
|
|
|
|
#ifdef __NA_001027_20080423_RANDOM_REWARD_EVENT_
|
|
case eNPC_TYPE_GUILD_EVENT:
|
|
{
|
|
uiEventMan* eventMan = static_cast<uiEventMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_EVENT));
|
|
|
|
uiGuildEventDialog * pGuildEvent = GET_CAST_DIALOG( uiGuildEventDialog, IM_EVENT_MANAGER::GUILD_EVENT );
|
|
|
|
if( eventMan && pGuildEvent )
|
|
{
|
|
pGuildEvent->ShowInterface(TRUE);
|
|
return (SolarDialog *)pGuildEvent;
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
#ifdef _NA_008016_20150202_OLD_RANKING_SYSTEM
|
|
case eNPC_TYPE_MISSION_RANK:
|
|
{
|
|
#if defined(_NA_006802_20130704_REORGANIZATION_RANK_SYSTEM)
|
|
uiMissionRankMan2* rank_manager_ptr2 = GET_DIALOG_MANAGER( uiMissionRankMan2, UIMAN_MISSION_RANK );
|
|
uiBase* rank_list_ptr2 = GET_DIALOG( IM_MISSION_RANK_MANAGER::MissionRankList );
|
|
|
|
if ( rank_manager_ptr2 && rank_list_ptr2 )
|
|
{
|
|
rank_manager_ptr2->ShowRankList( TRUE );
|
|
|
|
return static_cast<SolarDialog*>(rank_list_ptr2);
|
|
}
|
|
#else
|
|
uiMissionRankMan* pRankMan = GET_DIALOG_MANAGER( uiMissionRankMan, UIMAN_MISSION_RANK );
|
|
|
|
uiBase * pRankMenu = GET_DIALOG( IM_MISSION_RANK_MANAGER::RankMenu );
|
|
|
|
if( pRankMan && pRankMenu )
|
|
{
|
|
pRankMan->ShowRankMenu( TRUE );
|
|
|
|
return (SolarDialog *)pRankMenu;
|
|
}
|
|
#endif // _NA_006802_20130704_REORGANIZATION_RANK_SYSTEM
|
|
}
|
|
break;
|
|
#endif // _NA_008016_20150202_OLD_RANKING_SYSTEM
|
|
|
|
|
|
case eNPC_TYPE_POINT_RANK:
|
|
{
|
|
// 포인트랭킹 NPC
|
|
#if !defined(_NA_006802_20130704_REORGANIZATION_RANK_SYSTEM)
|
|
uiMissionRankMan* pRankMan = GET_DIALOG_MANAGER( uiMissionRankMan, UIMAN_MISSION_RANK );
|
|
|
|
uiMissionRankList* pRankList = GET_CAST_DIALOG( uiMissionRankList, IM_MISSION_RANK_MANAGER::MissionRankList );
|
|
|
|
if(pRankMan && pRankList)
|
|
{
|
|
pRankMan->ShowRankList(eRANKING_TYPE_POINT);
|
|
return (SolarDialog *)pRankList;
|
|
}
|
|
#endif // _NA_006802_20130704_REORGANIZATION_RANK_SYSTEM
|
|
}
|
|
break;
|
|
|
|
|
|
case eNPC_TYPE_VENDOR_LIST:
|
|
{
|
|
// #ifdef _NA_005988_20120901_VENDOR_SEARCH_SYSTEM
|
|
// uiVendorSearch * pVendorSearch = GET_CAST_DIALOG( uiVendorSearch, IM_VENDOR_MANAGER::VENDOR_SEARCH );
|
|
// if( pVendorSearch && !pVendorSearch->IsVisibleWindow())
|
|
// {
|
|
// g_InterfaceManager.ShowDialog(IM_VENDOR_MANAGER::VENDOR_SEARCH, TRUE);
|
|
//
|
|
// return (SolarDialog *) pVendorSearch;
|
|
// }
|
|
// #else
|
|
uiVendorList * pVendorList = GET_CAST_DIALOG( uiVendorList, IM_VENDOR_MANAGER::VENDOR_LIST );
|
|
if( pVendorList )
|
|
{
|
|
pVendorList->NET_SEND_CG_VENDOR_LIST_START_SYN();
|
|
return (SolarDialog *) pVendorList;
|
|
}
|
|
// #endif
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_ITEM_MIX:
|
|
{
|
|
#if ITEM_COMPOSITE_APPLY
|
|
BOOL bTotalComposite = FALSE;
|
|
BASE_CompositeNPCInfo * pInfo =
|
|
CompositeNPCInfoParser::Instance()->GetCompositeNPCInfo(NpcCode);
|
|
for (int i = 0; i < MAX_COMPOSE_PARAM; ++i)
|
|
{
|
|
if(pInfo->m_dwParams[i] == eITEMCOPOSITE_TOTAL)
|
|
{
|
|
bTotalComposite = TRUE;
|
|
}
|
|
}
|
|
if(bTotalComposite)
|
|
{
|
|
uiItemCompositeMan * pCompositeMan =
|
|
(uiItemCompositeMan *)g_InterfaceManager.GetUserInterfaceManager(UIMAN_ITEM_COMPOSITE);
|
|
|
|
|
|
uiItemTotalcomposite * pTotalComposite = GET_CAST_DIALOG( uiItemTotalcomposite, IM_ITEM_COMPOSITE_MANAGER::ITEM_TOTAL_COMPOSITE );
|
|
if( pCompositeMan )
|
|
{
|
|
if(!pTotalComposite->IsVisible())
|
|
{
|
|
pCompositeMan->ShowItemComposite( ITEM_COMPOSITE_CATEGORY_TOTAL_COMPOSITE,
|
|
(eITEMCOMPOSITECODE) pTotalComposite->GetCurrentSelectItemCode());
|
|
|
|
return (SolarDialog *)pTotalComposite;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SelectCompositeMenu * pDlg =
|
|
(SelectCompositeMenu *)g_InterfaceManager.GetDialog(InterfaceManager::DIALOG_SELECT_COMPOSITE_MENU);
|
|
|
|
if (pDlg && !pDlg->IsVisibleWindow())
|
|
{
|
|
pDlg->SetOpenNPC(NpcCode);
|
|
g_InterfaceManager.ShowDialog(InterfaceManager::DIALOG_SELECT_COMPOSITE_MENU, TRUE);
|
|
|
|
return (SolarDialog *)pDlg;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_VILLAGE_PORTAL:
|
|
{
|
|
SolarDialog * pDlg =
|
|
g_InterfaceManager.GetDialog(InterfaceManager::DIALOG_NPC_PORTAL);
|
|
|
|
if (pDlg && !pDlg->IsVisibleWindow())
|
|
{
|
|
NPCPortalDialog * pNPCPortalDlg = (NPCPortalDialog *)pDlg;
|
|
|
|
pNPCPortalDlg->SetCurVillageCode(
|
|
NpcCode,
|
|
(MAPCODE)g_pMap->GetMapID()
|
|
);
|
|
g_InterfaceManager.ShowDialog(InterfaceManager::DIALOG_NPC_PORTAL, TRUE);
|
|
|
|
return (SolarDialog *)pDlg;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_QUEST:
|
|
{
|
|
return NULL;
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_EVENT_DONATION: //기부관련
|
|
{
|
|
ui_XMas_DonationConfirm * pDonationConfirm = GET_CAST_DIALOG( ui_XMas_DonationConfirm, IM_EVENT_MANAGER::EVENT_X_MAS_DONATION_CONFIRM );
|
|
|
|
if(pDonationConfirm)
|
|
{
|
|
pDonationConfirm->ShowInterface(TRUE);
|
|
return (SolarDialog*)pDonationConfirm;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_EVENT_PERIOD_ITEM: //기간제 아이템 관련
|
|
{
|
|
DWORD dwRewardCode = 0;
|
|
DWORD dwItemCode[2] = {0,0};
|
|
EVENT_INFO_VEC* pEventInfoVec = SunEventInfoParser::Instance()->FindEventInfoFromNpcType(eNPC_TYPE_EVENT_PERIOD_ITEM);
|
|
//해당이벤트가 현재 맵상에 무조건 "1개" 라고 가정하자.
|
|
if(NULL != pEventInfoVec)
|
|
{
|
|
EVENT_INFO* pEventInfo = pEventInfoVec->back();
|
|
|
|
if(pEventInfo)
|
|
{
|
|
dwRewardCode = pEventInfo->m_dwRewardInfo[0];
|
|
RewardInfo* pRewardInfo = RewardInfoList::Instance()->FindRewardInfo(dwRewardCode);
|
|
|
|
if(pRewardInfo)
|
|
{
|
|
dwItemCode[0] = pRewardInfo->GetTypeCode(0);
|
|
dwItemCode[1] = pRewardInfo->GetTypeCode(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
SCSlotContainer *pContainer = g_pHero->GetSlotContainer(SI_INVENTORY);
|
|
POSTYPE start = 0;
|
|
POSTYPE total = 0;
|
|
if (pContainer)
|
|
{
|
|
total = pContainer->GetMaxSlotNum();
|
|
}
|
|
|
|
BOOL bVal = FALSE;
|
|
|
|
for (POSTYPE i = start; i < total; ++i)
|
|
{
|
|
if ( !pContainer->IsEmpty(i) )
|
|
{
|
|
SCSlot& rSlot = pContainer->GetSlot(i);
|
|
BASE_ITEMINFO* pItemInfo = ItemInfoParser::Instance()->GetItemInfo( rSlot.GetCode() );
|
|
if(pItemInfo)
|
|
{
|
|
if(pItemInfo->m_Code == dwItemCode[0] || pItemInfo->m_Code == dwItemCode[1])
|
|
{
|
|
bVal = TRUE;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
bVal = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bVal)
|
|
{
|
|
uiSystemMan* pSysMan = (uiSystemMan*)g_InterfaceManager.GetUserInterfaceManager(UIMAN_SYSTEM);
|
|
if(pSysMan)
|
|
{
|
|
TCHAR szMessage[INTERFACE_STRING_LENGTH + 1] = {0,};
|
|
//203101 뱃지는 쓸만한가? 큰맘 먹고 준 선물이니 아껴쓰라구
|
|
g_InterfaceManager.GetInterfaceString(203101, szMessage, INTERFACE_STRING_LENGTH);
|
|
pSysMan->Sys_Verify(szMessage);
|
|
}
|
|
|
|
//등록은 하되 보여주진 않는다.
|
|
ui_XMas_Confirm* pXMasConfirm = GET_CAST_DIALOG( ui_XMas_Confirm, IM_EVENT_MANAGER::EVENT_X_MAS_CONFIRM );
|
|
|
|
|
|
if(pXMasConfirm)
|
|
{
|
|
pXMasConfirm->SetDlgType(ui_XMas_Confirm::eXMAS_DLG_TYPE_PERIOD_ITEM);
|
|
pXMasConfirm->ShowInterface(FALSE);
|
|
return (SolarDialog*)pXMasConfirm;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ui_XMas_Confirm * pXMasConfirm = GET_CAST_DIALOG( ui_XMas_Confirm, IM_EVENT_MANAGER::EVENT_X_MAS_CONFIRM );
|
|
|
|
if(pXMasConfirm)
|
|
{
|
|
pXMasConfirm->SetDlgType(ui_XMas_Confirm::eXMAS_DLG_TYPE_PERIOD_ITEM);
|
|
pXMasConfirm->ShowInterface(TRUE);
|
|
return (SolarDialog*)pXMasConfirm;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_EVENT_SANTA://산타관련
|
|
{
|
|
ui_XMas_SantaDlg* pSantaDlg = GET_CAST_DIALOG( ui_XMas_SantaDlg, IM_EVENT_MANAGER::EVENT_X_MAS_SANTA_DLG );
|
|
if(pSantaDlg)
|
|
{
|
|
pSantaDlg->ShowInterface(TRUE);
|
|
return (SolarDialog*)pSantaDlg;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_EVENT_BUFF:
|
|
{
|
|
Object_Map_Itr found_itr = g_ObjectManager.GetBegin();
|
|
Object_Map_Itr end_itr = g_ObjectManager.GetEnd();
|
|
for ( ; found_itr != end_itr; ++found_itr)
|
|
{
|
|
|
|
Object* pObject = found_itr->second;
|
|
if (pObject == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
eOBJECT_TYPE eObjectType = pObject->GetSCObject().GetObjectType();
|
|
if (eObjectType != NPC_OBJECT)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
NPC* pNPC = static_cast<NPC*>(pObject);
|
|
if (pNPC)
|
|
{
|
|
if (pFindInfo->m_NPCCODE == pNPC->GetExtraInfo()->m_NPCCODE)
|
|
{
|
|
uiBuffEvent* pDlg = GET_CAST_DIALOG(uiBuffEvent, IM_EVENT_MANAGER::EVENT_BUFF);
|
|
if (pDlg)
|
|
{
|
|
pDlg->ShowInterface(TRUE);
|
|
}
|
|
|
|
return (SolarDialog*)pDlg;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
break;
|
|
|
|
#ifdef _YJ_FISHING_SYSTEM_000933
|
|
case eNPC_TYPE_FISHING:
|
|
{
|
|
uiFishingShop* pFishingShop = (uiFishingShop*)g_InterfaceManager.GetDialog(InterfaceManager::DIALOG_FISHING_SHOP);
|
|
if(pFishingShop)
|
|
{
|
|
pFishingShop->ShowInterface(TRUE);
|
|
return (SolarDialog*)pFishingShop;
|
|
}
|
|
}
|
|
break;
|
|
#endif //_YJ_FISHING_SYSTEM_000933
|
|
|
|
case eNPC_TYPE_AIRSHIP_MOVE:
|
|
{
|
|
int continent_number = 1;
|
|
if(g_pHero && g_pMap)
|
|
{
|
|
const sMAPINFO* map_info = MapInfoParser::Instance()->FindMapInfo((MAPCODE)g_pMap->GetMapID());
|
|
if(map_info)
|
|
{
|
|
continent_number = map_info->ContienetNumber;
|
|
}
|
|
}
|
|
ContinentEp2MapDlg* continent_map_ep2_dialog =
|
|
GET_CAST_DIALOG(ContinentEp2MapDlg, IM_RADAR_MANAGER::CONTINENT_MAP_EP2_DLG);
|
|
|
|
ContinentMapDlg* continent_map = GET_CAST_DIALOG(ContinentMapDlg,
|
|
IM_RADAR_MANAGER::CONTINENT_MAP_DLG);
|
|
|
|
if (continent_number == 1 && continent_map != NULL)
|
|
{
|
|
continent_map->ShowInterface(TRUE);
|
|
continent_map->SetAirShipMode();
|
|
}
|
|
else if (continent_number == 2 && continent_map_ep2_dialog != NULL)
|
|
{
|
|
continent_map_ep2_dialog->ShowInterface(TRUE);
|
|
continent_map_ep2_dialog->SetAirShipMode();
|
|
}
|
|
}
|
|
break;
|
|
case eNPC_TYPE_LOTTO:
|
|
{
|
|
#ifdef _DH_UNUSE_LOTTO
|
|
#else
|
|
uiLottoWindow* pLottoWindow= GET_CAST_DIALOG( uiLottoWindow, IM_LOTTO_MANAGER::LOTTO_WINDOW_DLG );
|
|
|
|
if(pLottoWindow)
|
|
{
|
|
if(pLottoWindow->IsVisible())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
//나의 로또응모정보를 요청한다
|
|
uiLottoMan* pLottoMan = GET_DIALOG_MANAGER(uiLottoMan, UIMAN_LOTTO_MAN);
|
|
|
|
if(pLottoMan && pLottoMan->GetWaitPacket()==FALSE)
|
|
{
|
|
pLottoMan->SEND_LOTTO_INFO_SYN();
|
|
}
|
|
#endif//_DH_UNUSE_LOTTO
|
|
}
|
|
break;
|
|
|
|
case eNPC_TYPE_EVENT_FRIENDINVITATION:
|
|
{
|
|
uiEventMan* eventMan = static_cast<uiEventMan *>(g_InterfaceManager.GetUserInterfaceManager(UIMAN_EVENT));
|
|
uiEventFriend * eventDlg = GET_CAST_DIALOG( uiEventFriend, IM_EVENT_MANAGER::EVENT_FRIEND );
|
|
|
|
if(eventMan && eventDlg && !eventDlg->IsVisible())
|
|
{
|
|
eventMan->SendEventFriend();
|
|
return (SolarDialog *)eventDlg;
|
|
}
|
|
}
|
|
break;
|
|
#ifdef _NA_000000_20140120_SMART_NPC_SYSTEM
|
|
case eNPC_TYPE_SMARTNPC:
|
|
{
|
|
// 지능형 엔피씨일 경우 패킷 전송
|
|
MSG_CG_NPCDIALOG_OPERATION_CMD send_packet(g_pHero->GetObjectKey(), NpcCode, 0, 0);
|
|
GlobalFunc::SendPacket(CI_GAMESERVERIDX, &send_packet, sizeof(send_packet));
|
|
}
|
|
break;
|
|
#endif //_NA_000000_20140120_SMART_NPC_SYSTEM
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
BOOL GameFunc::CheckHeroInAreaForQuest(DWORD areaID)
|
|
{
|
|
if (g_pMap == NULL || g_pHero == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
eTRIGGER_STATE TrigerState, HeroTrigerState;
|
|
|
|
WzSpecialArea* pAreaInfo = g_pMap->GetMapArea(areaID);
|
|
if (pAreaInfo == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
TrigerState = TRIGGER_STATE_LEAVE_AREA;
|
|
|
|
switch (pAreaInfo->m_wbvRegion.m_eBvType)
|
|
{
|
|
case BVT_AABB:
|
|
{
|
|
if (TRUE == Contain_AABB_Vertex(&pAreaInfo->m_wbvRegion.m_aabb, g_pHero->GetPosition()))
|
|
{
|
|
TrigerState = TRIGGER_STATE_ENTER_AREA;
|
|
}
|
|
}
|
|
break;
|
|
case BVT_PATH_TILE_INDEX:
|
|
{
|
|
int iTile = g_pHero->GetPathExplorer()->GetTile();
|
|
for (int i = 0; i < static_cast<int>(pAreaInfo->m_wbvRegion.m_BvPathTileIndex.m_nCount); ++i)
|
|
{
|
|
if (iTile == pAreaInfo->m_wbvRegion.m_BvPathTileIndex.m_pdwData[i])
|
|
{
|
|
TrigerState = TRIGGER_STATE_ENTER_AREA;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case BVT_SPHERE:
|
|
{
|
|
if (TRUE == Contain_Sphere_Vertex(&pAreaInfo->m_wbvRegion.m_BvSphere, g_pHero->GetPosition()))
|
|
{
|
|
TrigerState = TRIGGER_STATE_ENTER_AREA;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
HeroTrigerState = g_pHero->GetTriggerState(areaID);
|
|
if (HeroTrigerState != TrigerState)
|
|
{
|
|
// 들어갔을땐 언제나 패킷을 보낸다!!!
|
|
if (TrigerState == TRIGGER_STATE_ENTER_AREA)
|
|
{
|
|
//< 플레이어가 들어왔다.
|
|
// Quest Event
|
|
QUEST_AREA_MSG QuestAreaMsg;
|
|
QuestAreaMsg.m_AreaID = areaID;
|
|
g_pQMGR_Real->Event(QUEST_EVENT_AREA, &QuestAreaMsg);
|
|
}
|
|
g_pHero->SetTriggerState( areaID,TrigerState );
|
|
}
|
|
|
|
if (TrigerState == TRIGGER_STATE_ENTER_AREA)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
BOOL
|
|
GameFunc::IsHeroInAreaForQuest(DWORD areaID)
|
|
{
|
|
if ( !g_pMap || !g_pHero )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WzSpecialArea *pAreaInfo = g_pMap->GetMapArea( areaID );
|
|
if ( !pAreaInfo )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
if( pAreaInfo->m_wbvRegion.m_eBvType == BVT_AABB )
|
|
{
|
|
|
|
if( TRUE == Contain_AABB_Vertex( &pAreaInfo->m_wbvRegion.m_aabb, g_pHero->GetPosition() ) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
if( pAreaInfo->m_wbvRegion.m_eBvType == BVT_PATH_TILE_INDEX )
|
|
{
|
|
int iTile = g_pHero->GetPathExplorer()->GetTile();
|
|
|
|
for( int i = 0 ; i < int(pAreaInfo->m_wbvRegion.m_BvPathTileIndex.m_nCount) ; ++i )
|
|
{
|
|
if( iTile == pAreaInfo->m_wbvRegion.m_BvPathTileIndex.m_pdwData[i] )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void GameFunc::GetPlayerSkill(int charType,Character *pChar,Character * pTarget,PLAYER_ACTION &action)
|
|
{
|
|
action.ActionID = ACTION_SKILL;
|
|
action.SKILL.dwTargetID = pTarget->GetObjectKey();
|
|
action.SKILL.dwAttackSerial = 0;
|
|
action.SKILL.vCurPos.wvPos =pChar->GetPosition();
|
|
action.SKILL.vCurPos.wTile = -1;
|
|
action.SKILL.vDestPos.wvPos =pChar->GetPosition();
|
|
|
|
|
|
if (charType == eCHAR_BERSERKER)
|
|
{
|
|
action.SKILL.vDestPos.wvPos =pTarget->GetPosition();//태클
|
|
|
|
action.SKILL.dwSkillID= 2061;
|
|
}
|
|
else if (charType == eCHAR_DRAGON)
|
|
{
|
|
action.SKILL.dwSkillID= 4061;
|
|
|
|
action.SKILL.vDestPos.wvPos =pTarget->GetPosition();//일루젼댄스
|
|
}
|
|
else if (charType == eCHAR_VALKYRIE)
|
|
{
|
|
action.SKILL.dwSkillID= 7130;
|
|
|
|
}
|
|
else if (charType == eCHAR_ELEMENTALIST)
|
|
{
|
|
action.SKILL.dwSkillID= 10262;
|
|
action.SKILL.vTargePos=pTarget->GetPosition();//화이어스피어
|
|
|
|
}
|
|
}
|
|
|
|
|
|
Player * GameFunc::SpawnPlayer(BYTE bCharType)
|
|
{
|
|
if(g_pHero)
|
|
{
|
|
|
|
static int iCount=0;
|
|
iCount++;
|
|
char temp[256];
|
|
sprintf(temp,"%d플레이어",iCount);
|
|
g_InterfaceManager.ShowMessageBox(temp,5000,NULL,0);
|
|
Player *pPlayer = (Player *)g_ObjectManager.Add(
|
|
g_ObjectManager.GenerateKeyAtSingleMode(PLAYER_OBJECT),
|
|
PLAYER_OBJECT,
|
|
bCharType,
|
|
FALSE);
|
|
|
|
PLAYER_RENDER_INFO_EX info;
|
|
ZeroMemory(&info,sizeof(PLAYER_RENDER_INFO_EX));
|
|
info.char_class=bCharType;
|
|
pPlayer->SetPlayerInfo(&info);
|
|
pPlayer->Rotate(0.0f);
|
|
pPlayer->SetHP(100);
|
|
pPlayer->SetMP(100);
|
|
pPlayer->SetPartVariation(PLAYER_VARIATION_HAIR,rand()%4+1);
|
|
pPlayer->SetPartVariation(PLAYER_VARIATION_FACE,rand()%4+1);
|
|
pPlayer->RefreshAppearRender();
|
|
WzVector wvPos = g_pHero->GetVisiblePos();
|
|
|
|
|
|
if(rand()%2)
|
|
pPlayer->SetLevel(19);
|
|
else
|
|
pPlayer->SetLevel(20);
|
|
|
|
pPlayer->SetName(temp);
|
|
pPlayer->SetPosition( wvPos );
|
|
|
|
|
|
if(pPlayer)
|
|
{
|
|
EquipmentContainer* pContainer = static_cast<EquipmentContainer *>(pPlayer->GetSlotContainer(SI_EQUIPMENT));
|
|
SCItemSlot ItemSlot;
|
|
ALL_ARMOR_CODE temp;
|
|
|
|
if(pContainer)
|
|
{
|
|
g_OptimizationManager.GetAllPartInfo(pPlayer->GetClass(),temp);
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwArmorCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_ARMOR, ItemSlot);
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwProtectorCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_PROTECTOR, ItemSlot);
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwHelmetCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_HELMET, ItemSlot);
|
|
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwPantsCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_PANTS, ItemSlot);
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwBootsCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_BOOTS, ItemSlot);
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwGloveCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_GLOVE, ItemSlot);
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwBeltCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_BELT, ItemSlot);
|
|
|
|
ItemSlot.SetCode((WORD)temp.dwShirtsCode); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_SHIRTS, ItemSlot);
|
|
}
|
|
|
|
pPlayer->RefreshAppearRender();
|
|
pPlayer->SetNextState(STATE::IDLE,g_CurTime);
|
|
pPlayer->CommitChangeState(g_CurTime);
|
|
pPlayer->SetMoveSpeedRatio(100);
|
|
|
|
return pPlayer;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void GameFunc::SpawnFullsetPlayer(BYTE bCharType , BYTE bySetType)
|
|
{
|
|
if(g_pHero)
|
|
{
|
|
|
|
static int iCount=0;
|
|
iCount++;
|
|
char temp[256];
|
|
sprintf(temp,"%d마리",iCount);
|
|
g_InterfaceManager.ShowMessageBox(temp,5000,NULL,0);
|
|
Player *pPlayer = (Player *)g_ObjectManager.Add(
|
|
g_ObjectManager.GenerateKeyAtSingleMode(PLAYER_OBJECT),
|
|
PLAYER_OBJECT,
|
|
eCHAR_BERSERKER,
|
|
FALSE);
|
|
|
|
PLAYER_RENDER_INFO_EX info;
|
|
ZeroMemory(&info,sizeof(PLAYER_RENDER_INFO_EX));
|
|
info.char_class=eCHAR_BERSERKER;
|
|
|
|
pPlayer->SetPlayerInfo(&info);
|
|
pPlayer->Rotate(0.0f);
|
|
pPlayer->SetHP(100);
|
|
pPlayer->SetMP(100);
|
|
pPlayer->SetPartVariation(PLAYER_VARIATION_HAIR,rand()%4+1);
|
|
pPlayer->SetPartVariation(PLAYER_VARIATION_FACE,rand()%4+1);
|
|
WzVector wvPos = g_pHero->GetVisiblePos();
|
|
|
|
|
|
pPlayer->SetPosition( wvPos );
|
|
|
|
|
|
if(pPlayer)
|
|
{
|
|
EquipmentContainer* pContainer = static_cast<EquipmentContainer *>(pPlayer->GetSlotContainer(SI_EQUIPMENT));
|
|
SCItemSlot ItemSlot;
|
|
|
|
if(pContainer)
|
|
{
|
|
ItemSlot.SetCode(bySetType);
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_WEAPON1, ItemSlot);
|
|
|
|
ItemSlot.SetCode(1000 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_ARMOR, ItemSlot);
|
|
|
|
ItemSlot.SetCode(1050 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_PROTECTOR, ItemSlot);
|
|
|
|
ItemSlot.SetCode(1100 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_HELMET, ItemSlot);
|
|
|
|
|
|
ItemSlot.SetCode(1150 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_PANTS, ItemSlot);
|
|
|
|
ItemSlot.SetCode(1200 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_BOOTS, ItemSlot);
|
|
|
|
ItemSlot.SetCode(1250 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_GLOVE, ItemSlot);
|
|
|
|
ItemSlot.SetCode(1300 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_BELT, ItemSlot);
|
|
|
|
ItemSlot.SetCode(1350 + bySetType); //
|
|
pContainer->JustInsertSlot(EquipmentContainer::EQUIP_SHIRTS, ItemSlot);
|
|
}
|
|
|
|
pPlayer->RefreshAppearRender();
|
|
pPlayer->SetNextState(STATE::IDLE,g_CurTime);
|
|
pPlayer->CommitChangeState(g_CurTime);
|
|
|
|
pPlayer->SetMoveSpeedRatio(100);
|
|
pPlayer->SetAttackSpeedRatio(100);
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
void GameFunc::SetPlayerMonsterAttackStyle(PlayerMonster* player_monster)
|
|
{
|
|
DWORD weapon_style = player_monster->GetWeaponKind();
|
|
BYTE class_code = player_monster->GetClass();
|
|
|
|
DWORD style_code;
|
|
player_monster->SetCurrentNomalAttackStyle(weapon_style);
|
|
style_code = player_monster->GetCurrentAttackStyle();
|
|
player_monster->SetCurrentAttackStyle(style_code, FALSE);
|
|
}
|
|
|
|
DWORD GameFunc::GetRandomStyle(DWORD dwWeaponStyle,BYTE bClassCode)
|
|
{
|
|
DWORD dwStyle=0;
|
|
int iRand=0;
|
|
iRand=rand()%3;
|
|
|
|
switch(dwWeaponStyle)
|
|
{
|
|
case eWEAPONTYPE_TWOHANDAXE:
|
|
{
|
|
if(iRand==0)
|
|
dwStyle=eSTYLE_FUSS_BREAKER;
|
|
else if(iRand==1)
|
|
dwStyle=eSTYLE_HACKSTER_KNOCKBACK_AXE;
|
|
else
|
|
dwStyle=eSTYLE_ROLLANDS_DOWN;
|
|
}
|
|
break;
|
|
|
|
case eWEAPONTYPE_TWOHANDSWORD:
|
|
{
|
|
if(iRand==0)
|
|
dwStyle=eSTYLE_BALTURS_DEFENCE;
|
|
else if(iRand==1)
|
|
dwStyle=eSTYLE_HACKSTER_KNOCKBACK_TWOHAND;
|
|
else
|
|
dwStyle=eSTYLE_RUDBIGS_STUN;
|
|
}
|
|
break;
|
|
|
|
|
|
case eWEAPONTYPE_ONEHANDSWORD:
|
|
{
|
|
|
|
if(iRand==0)
|
|
dwStyle=eSTYLE_RESTROS_SPEED;
|
|
else if(iRand==1)
|
|
dwStyle=eSTYLE_TORES_CRITICAL;
|
|
else
|
|
dwStyle=eSTYLE_ELEMEOUS_KNOCKBACK_ONEHAND;
|
|
|
|
}
|
|
break;
|
|
|
|
case eWEAPONTYPE_SPEAR:
|
|
{
|
|
if(iRand==0)
|
|
dwStyle=eSTYLE_ALRESTER_DAMAGE;
|
|
else if(iRand==1)
|
|
dwStyle=eSTYLE_ELEMEOUS_KNOCKBACK_LANCE;
|
|
else
|
|
dwStyle=eSTYLE_FLABIOUS_PIERCING;
|
|
}
|
|
break;
|
|
|
|
case eWEAPONTYPE_ONEHANDCROSSBOW:
|
|
{
|
|
dwStyle=eSTYLE_ONEHANDCROSSBOW_NORMAL;
|
|
}
|
|
break;
|
|
|
|
case eWEAPONTYPE_ETHERWEAPON:
|
|
{
|
|
dwStyle=eSTYLE_ETHER_NORMAL;
|
|
}
|
|
break;
|
|
|
|
|
|
case eWEAPONTYPE_STAFF:
|
|
{
|
|
dwStyle=eSTYLE_STAFF_NORMAL;
|
|
}
|
|
break;
|
|
|
|
case eWEAPONTYPE_ORB:
|
|
{
|
|
dwStyle=eSTYLE_ORB_NORMAL;
|
|
}
|
|
break;
|
|
|
|
case eWEAPONTYPE_DAGGER:
|
|
{
|
|
dwStyle=eSTYLE_SHADOW_DAGGER_NORMAL;
|
|
}
|
|
break;
|
|
|
|
case eWEAPONTYPE_WHIP:
|
|
{
|
|
dwStyle=eSTYLE_SHADOW_WHIP_NORMAL;
|
|
}
|
|
break;
|
|
case eWEAPONTYPE_PUNCH:
|
|
{
|
|
if(bClassCode==eCHAR_BERSERKER)
|
|
{
|
|
dwStyle=eSTYLE_BERSERKER_PUNCH;
|
|
}
|
|
else if(bClassCode==eCHAR_DRAGON)
|
|
{
|
|
dwStyle=eSTYLE_DRAGON_PUNCH;
|
|
}
|
|
else if(bClassCode==eCHAR_SHADOW)
|
|
{
|
|
dwStyle=eSTYLE_SHADOW_PUNCH;
|
|
}
|
|
else if(bClassCode==eCHAR_VALKYRIE)
|
|
{
|
|
dwStyle=eSTYLE_VALKYRIE_PUNCH;
|
|
}
|
|
else if(bClassCode==eCHAR_MAGICIAN)
|
|
{
|
|
dwStyle=eSTYLE_MAGICIAN_PUNCH;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return dwStyle;
|
|
}
|
|
|
|
Monster* GameFunc::SpawnMonster(CODETYPE MonsterCode, size_t MonsterCount /* = 1 */, WzVector* wzVec /* = NULL*/, DWORD dwMaster /* = 0*/)
|
|
{
|
|
if (!g_pHero)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
BASE_NPCINFO* pNpcInfo = NPCInfoParser::Instance()->GetNPCInfo(MonsterCode);
|
|
|
|
WzVector wvPos;
|
|
if (NULL == wzVec)
|
|
{
|
|
wvPos = g_pHero->GetVisiblePos();
|
|
}
|
|
else
|
|
{
|
|
wvPos = *wzVec;
|
|
}
|
|
|
|
Monster* pMonster = NULL;
|
|
|
|
|
|
if (pNpcInfo && pNpcInfo->m_wNpcImageIndex)
|
|
{
|
|
BASE_NPCImageInfo* pNpcImageInfo = NPCImageInfoParser::Instance()->GetNpcImageInfo(pNpcInfo->m_wNpcImageIndex);
|
|
|
|
if (pNpcImageInfo)
|
|
{
|
|
PlayerMonster* pPlayerMonster = (PlayerMonster*)g_ObjectManager.Add(g_ObjectManager.GenerateKeyAtSingleMode(MONSTER_OBJECT), SSQMONSTER_OBJECT, pNpcImageInfo->bClassCode, FALSE);
|
|
|
|
// 저탑 보스 등으로 등장하는 플레이어형몬스터의 경우 MONSTER_OBJECT 세팅
|
|
pPlayerMonster->SetMonsterInfo(pNpcInfo);
|
|
|
|
//PLAYER_RENDER_INFO_EX info;
|
|
//ZeroMemory(&info, sizeof(PLAYER_RENDER_INFO_EX));
|
|
//info.char_class = pNpcImageInfo->bClassCode;
|
|
//info.level = 10;
|
|
//info.hp = 100;
|
|
//info.max_hp = 200;
|
|
//info.move_speed_ratio = 100;
|
|
//info.attack_speed_ratio = 100;
|
|
|
|
//pPlayerMonster->SetPlayerInfo(&info);
|
|
srand(MonsterCode);
|
|
if (pPlayerMonster)
|
|
{
|
|
// 외형세팅
|
|
pPlayerMonster->SetPartVariation(PLAYER_VARIATION_HAIR, pNpcImageInfo->hairImageID);
|
|
pPlayerMonster->SetPartVariation(PLAYER_VARIATION_FACE, pNpcImageInfo->faceImageID);
|
|
BOOL is_hide_helmet = (pNpcImageInfo->showhelmet == 1) ? false : true;
|
|
pPlayerMonster->HideHelmet(is_hide_helmet, FALSE);
|
|
|
|
NPC::InitNpcImageInfo(pPlayerMonster, pPlayerMonster->GetMonsterInfo());
|
|
GameFunc::SetPlayerMonsterAttackStyle(pPlayerMonster);
|
|
|
|
|
|
pPlayerMonster->RefreshEquipData();
|
|
pPlayerMonster->SetNextState(STATE::IDLE, g_CurTime);
|
|
pPlayerMonster->CommitChangeState(g_CurTime);
|
|
|
|
pPlayerMonster->SetMoveSpeedRatio(100);
|
|
pPlayerMonster->SetAttackSpeedModifier(100);
|
|
|
|
pPlayerMonster->SetPosition(wvPos);
|
|
tempId = pPlayerMonster->GetObjectKey();
|
|
m_dwTestMonsterId = tempId;
|
|
|
|
}
|
|
|
|
return pPlayerMonster;
|
|
}
|
|
else
|
|
{
|
|
pMonster = (Monster*)g_ObjectManager.Add(g_ObjectManager.GenerateKeyAtSingleMode(MONSTER_OBJECT), MONSTER_OBJECT, MonsterCode);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
pMonster = (Monster*)g_ObjectManager.Add(g_ObjectManager.GenerateKeyAtSingleMode(MONSTER_OBJECT), MONSTER_OBJECT, MonsterCode);
|
|
PLAYER_ACTION idleaction;
|
|
|
|
if (pNpcInfo)
|
|
{
|
|
idleaction.SPAWN.dwEndTime = pNpcInfo->m_dwSpawnTime + g_CurTime;
|
|
}
|
|
|
|
pMonster->SetCurrentAction(&idleaction);
|
|
pMonster->SetNextState(STATE::SPAWN,g_CurTime);
|
|
pMonster->SetAttackSpeedRatio(100);
|
|
|
|
WzVector vTemp;
|
|
vTemp.x = 56.0f;
|
|
vTemp.y = 57.0f;
|
|
vTemp.z = 0.0f;
|
|
pMonster->SetDirection(vTemp);
|
|
pMonster->SetHP(pMonster->GetMonsterInfo()->m_dwMaxHP);
|
|
|
|
|
|
}
|
|
|
|
if (pMonster)
|
|
{
|
|
pMonster->SetPosition(wvPos);
|
|
|
|
if (g_pHero && (eNPC_CRYSTAL_WARP == pMonster->GetMonsterInfo()->m_byGrade))
|
|
{
|
|
if (RELATIONKIND::Enemy == GameFramework::GetCurrentScene()->GetRelationKindOfCharacter(pMonster, g_HeroInput.lsForceAttack()))
|
|
{
|
|
//빨강
|
|
pMonster->SetParentId(0, 0, TRUE);
|
|
pMonster->CreateCrystalWarpEffect(StrToWzID("O078"));
|
|
}
|
|
else
|
|
{
|
|
//파랑
|
|
pMonster->SetParentId(0, 0, FALSE);
|
|
pMonster->CreateCrystalWarpEffect(StrToWzID("O081"));
|
|
}
|
|
|
|
pMonster->SetMasterGuildID(g_pHero->GetPlayerGuildID());
|
|
g_pHero->SetCrystalWarpKey(pMonster->GetObjectKey());
|
|
}
|
|
|
|
tempId = pMonster->GetObjectKey();
|
|
m_dwTestMonsterId = tempId;
|
|
}
|
|
|
|
return pMonster;
|
|
}
|
|
|
|
WzVector GameFunc::FindStandPosition(WzVector vSrc,WzVector vDest)
|
|
{
|
|
WzVector vTemp;
|
|
float fRate=1.0f;
|
|
|
|
//최대 10회까지만 찾는다
|
|
for(int i=0;i<10;i++)
|
|
{
|
|
vTemp = vSrc* (1.0f - fRate) + vDest* (fRate);
|
|
|
|
if(g_pSunTerrain)
|
|
{
|
|
int iTileFocussing = -1;
|
|
float fT=0.0f;
|
|
iTileFocussing = g_pSunTerrain->x_pPathFinder->GetAllowTileToStand( vTemp, &fT, -1.0f, 10.0f );
|
|
|
|
if(iTileFocussing >=0)
|
|
{
|
|
|
|
if(g_pPathExplorer)
|
|
{
|
|
g_pPathExplorer->Stop();
|
|
g_pSunTerrain->PathExp_Reset(g_pPathExplorer, &vTemp, -1);
|
|
return g_pPathExplorer->GetVisiblePos();
|
|
|
|
}
|
|
else
|
|
{
|
|
vTemp.z-=fT;
|
|
return vTemp;
|
|
}
|
|
}
|
|
}
|
|
|
|
fRate-=0.1f;
|
|
}
|
|
|
|
return vSrc;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
/** 특정 위치에서 특정 범위안에 있는 이동가능한 타일의 위치를 얻어온다.
|
|
*/
|
|
BOOL GameFunc::GetValidPosForRange(WzVector & rwzPos, WzVector & OUT rOutwzReturn, float fRangeLength /* = 10.f */ )
|
|
{
|
|
if (fRangeLength <= 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL bRand = FALSE;
|
|
if ( 1 == (rand() % 2) )
|
|
{
|
|
bRand = TRUE;
|
|
}
|
|
|
|
float fStartAngle = 0.f;
|
|
|
|
if (bRand)
|
|
{
|
|
fStartAngle = WZ_PI;
|
|
}
|
|
|
|
for ( float fRange = fRangeLength; fRange > 0.f; fRange -= 5.0f)
|
|
{
|
|
for ( float fAngle = fStartAngle; fAngle < 2 * WZ_PI; fAngle += (WZ_PI / 6.f) )
|
|
{
|
|
rOutwzReturn = rwzPos;
|
|
|
|
rOutwzReturn.x += sinf(fAngle) * fRangeLength;
|
|
rOutwzReturn.y += cosf(fAngle) * fRangeLength;
|
|
rOutwzReturn.z += 3.0f;
|
|
|
|
int iTileFocussing = -1;
|
|
float fT=0.0f;
|
|
iTileFocussing = g_pSunTerrain->x_pPathFinder->GetTileToStand( rOutwzReturn, &fT, -1.0f, 10.0f );
|
|
|
|
if(iTileFocussing >= 0)
|
|
{
|
|
rOutwzReturn.z -= fT;
|
|
}
|
|
|
|
if( IsMove(rwzPos,rOutwzReturn) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL GameFunc::PickTerrainMesh( const WzVector & IN vOrigin,WzVector & OUT vPickPos, BYTE CheckType, float height )
|
|
{
|
|
WzRay ray;
|
|
ray.m_wvOrigin = vOrigin;
|
|
ray.m_wvOrigin.z += height;
|
|
ray.m_wvDirection.x = 0.0f;
|
|
ray.m_wvDirection.y = 0.0f;
|
|
ray.m_wvDirection.z = -1.0f;
|
|
|
|
float fT;
|
|
BOOL bFind=TRUE;
|
|
int iTerrainMeshFocussing = g_pSunTerrain->PickTerrainMesh( &ray, &fT, TRUE, CheckType);
|
|
if( iTerrainMeshFocussing < 0 )
|
|
{
|
|
ray.m_wvOrigin = vOrigin;
|
|
ray.m_wvOrigin.z += height;
|
|
ray.m_wvDirection.x = 0.0f;
|
|
ray.m_wvDirection.y = 0.0f;
|
|
ray.m_wvDirection.z = +1.0f;
|
|
|
|
if( iTerrainMeshFocussing = g_pSunTerrain->PickTerrainMesh( &ray, &fT, FALSE, CheckType ) >=0 )
|
|
{
|
|
vPickPos = ray.m_wvOrigin + ray.m_wvDirection * fT;
|
|
|
|
}
|
|
else
|
|
{
|
|
vPickPos=vOrigin;
|
|
bFind=FALSE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
vPickPos = ray.m_wvOrigin + ray.m_wvDirection * fT;
|
|
}
|
|
|
|
return bFind;
|
|
}
|
|
|
|
BOOL
|
|
GameFunc::GetValidPosForRange(WzVector & IN rwzPos, float IN fAngle, WzVector & OUT rOutwzReturn, float fRangeLength /*= 10.f*/)
|
|
{
|
|
if (fRangeLength <= 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WzVector wvDir;
|
|
|
|
int iCount = int(360 / 15);
|
|
float fAngleBasic = fAngle;
|
|
|
|
for ( float fRange = fRangeLength; fRange > 0.f; fRange -= 3.0f)
|
|
{
|
|
fAngle = fAngleBasic;
|
|
for ( int i = 0; i < iCount; ++i )
|
|
{
|
|
fAngle = fAngle + i * (15 * WZ_PI / 180.f);
|
|
|
|
wvDir.x = cosf(fAngle);
|
|
wvDir.y = sinf(fAngle);
|
|
wvDir.z = 0.f;
|
|
|
|
rOutwzReturn = rwzPos + wvDir * fRange;
|
|
rOutwzReturn.z += 3.f;
|
|
|
|
int iTileFocussing = -1;
|
|
float fT = 0.0f;
|
|
iTileFocussing = g_pSunTerrain->x_pPathFinder->GetTileToStand( rOutwzReturn, &fT, -1.0f, 10.0f );
|
|
|
|
if(iTileFocussing >= 0)
|
|
{
|
|
rOutwzReturn.z -= fT;
|
|
}
|
|
|
|
if( IsMove(rwzPos,rOutwzReturn) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
float LerfFloat(float fNumber,float fNumber2,float fRate)
|
|
{
|
|
if (fRate >= 1.0f)
|
|
{
|
|
fRate = 1.0f;
|
|
}
|
|
|
|
if (fRate < 0.0f)
|
|
{
|
|
fRate = 0.0f;
|
|
}
|
|
|
|
float fRet = fNumber * (1.0f - fRate) + fNumber2 * fRate;
|
|
return fRet;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInField( Character* pObject, BOOL bForceEnemy )
|
|
{
|
|
if( pObject->IsKindOfObject( PLAYER_OBJECT ) )
|
|
{
|
|
if( !g_isPkServer )
|
|
return RELATIONKIND::Friend;
|
|
|
|
Player * pPlayer = (Player *)pObject;
|
|
//에소드는 필드지만 마을로 간주되기에 PK막는다
|
|
if(g_pMap && g_pMap->IsEsodeMap())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
return GetRelationOfPlayer( pPlayer, bForceEnemy );
|
|
|
|
}
|
|
else if( pObject->IsKindOfObject( MONSTER_OBJECT ) )
|
|
{
|
|
Monster * pMonster = (Monster *)pObject;
|
|
|
|
return GetRelationOfMonster( pMonster, bForceEnemy );
|
|
}
|
|
else if(pObject->IsKindOfObject( PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject( NPC_OBJECT) || pObject->IsKindOfObject( LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject( MERCHANT_OBJECT ))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInVillage( Character* pObject, BOOL bForceEnemy )
|
|
{
|
|
if( pObject->IsKindOfObject( PLAYER_OBJECT ) )
|
|
{
|
|
Player * pPlayer = (Player *)pObject;
|
|
|
|
if( g_pHero && g_pHero->GetObjectKey() == pPlayer->GetObjectKey() )
|
|
return RELATIONKIND::Friend;
|
|
|
|
ePLAYER_BEHAVE_STATE behaveState = pPlayer->GetBeHaveState();
|
|
|
|
if( behaveState == PLAYER_BEHAVE_VENDOR_ESTABLISHER_STATE )
|
|
return RELATIONKIND::Vendor;
|
|
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if( pObject->IsKindOfObject( MONSTER_OBJECT ) )
|
|
{
|
|
Monster * pMonster = (Monster *)pObject;
|
|
|
|
return GetRelationOfMonster( pMonster, bForceEnemy );
|
|
|
|
}
|
|
else if(pObject->IsKindOfObject( PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject( NPC_OBJECT) || pObject->IsKindOfObject( LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject( MERCHANT_OBJECT ))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInPVPZone( Character* pObject,BOOL bForceEnemy )
|
|
{
|
|
if (pObject->IsKindOfObject(PLAYER_OBJECT))
|
|
{
|
|
if( g_pHero && g_pHero->GetObjectKey() == pObject->GetObjectKey() )
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
if ((pObject->GetObjectKey() == EQUIPMENT_CHARACTER_KEY) ||
|
|
(pObject->GetObjectKey() == CUSTOMIZE_CHARACTER_KEY))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
if (GlobalFunc::IsParty(pObject->GetObjectKey()) == TRUE)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
else if( pObject->IsKindOfObject( MONSTER_OBJECT ) )
|
|
{
|
|
Monster * pMon= (Monster *)pObject;
|
|
|
|
if( g_pHero && g_pHero->GetObjectKey()==pMon->GetParentId())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(pObject->IsKindOfObject( PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject( NPC_OBJECT) || pObject->IsKindOfObject( LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject( MERCHANT_OBJECT ))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInSSQZone( Character* pObject,BOOL bForceEnemy )
|
|
{
|
|
if( g_pHero && g_pHero->GetObjectKey() == pObject->GetObjectKey() )
|
|
return RELATIONKIND::Friend;
|
|
|
|
if( pObject->IsKindOfObject( MAP_OBJECT ) )
|
|
return RELATIONKIND::None;
|
|
|
|
if( pObject->IsKindOfObject( MONSTER_OBJECT ) )
|
|
{
|
|
Monster *pMonster = (Monster *)pObject;
|
|
|
|
if( pMonster->GetMonsterType() == MONSTER_TYPE_TOTEM )
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
Player * pPlayer = (Player *)g_ObjectManager.GetObject( pMonster->GetParentId() );
|
|
|
|
if( pPlayer )
|
|
{
|
|
if( pPlayer->GetObjectKey() == g_pHero->GetObjectKey() )
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
}
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInHuntingZone( Character* pObject,BOOL bForceEnemy )
|
|
{
|
|
if( pObject->IsKindOfObject( PLAYER_OBJECT ) )
|
|
{
|
|
if( g_pHero && g_pHero->GetObjectKey() == pObject->GetObjectKey() )
|
|
return RELATIONKIND::Friend;
|
|
|
|
#if !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
uiBattleZoneReadyCHuntingConfig * cfg = GET_CAST_DIALOG( uiBattleZoneReadyCHuntingConfig,
|
|
IM_BATTLEZONE_MANAGER::BATTLEZONE_READY_CHUNTING_CFG );
|
|
|
|
assert (cfg);
|
|
|
|
if( cfg->GetCfgs().compModeType == eCOMPETITION_MODE_SURVIVAL ||
|
|
cfg->GetCfgs().compModeType == eCOMPETITION_MODE_DEATH_MATCH )
|
|
{
|
|
|
|
if( GlobalFunc::IsParty( pObject->GetObjectKey() ) )
|
|
return RELATIONKIND::Friend;
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
return RELATIONKIND::Friend;
|
|
#endif // !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
}
|
|
else if( pObject->IsKindOfObject( MONSTER_OBJECT ) )
|
|
{
|
|
Monster *pMonster = (Monster *)pObject;
|
|
|
|
if( pMonster->GetMonsterType() == MONSTER_TYPE_TOTEM )
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if( pMonster->GetParentId() )
|
|
{
|
|
Player * pPlayer = (Player *)g_ObjectManager.GetObject( pMonster->GetParentId() );
|
|
|
|
if( pPlayer )//주인이 있다면 주인과의 관계를 본다.
|
|
{
|
|
#if !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
|
|
uiBattleZoneReadyCHuntingConfig * cfg = GET_CAST_DIALOG( uiBattleZoneReadyCHuntingConfig,
|
|
IM_BATTLEZONE_MANAGER::BATTLEZONE_READY_CHUNTING_CFG );
|
|
assert (cfg);
|
|
|
|
if (cfg->GetCfgs().compModeType == eCOMPETITION_MODE_SURVIVAL ||
|
|
cfg->GetCfgs().compModeType == eCOMPETITION_MODE_TIME_ATTACK ||
|
|
cfg->GetCfgs().compModeType == eCOMPETITION_MODE_DEATH_MATCH)
|
|
{
|
|
if( GlobalFunc::IsParty( pPlayer->GetObjectKey() ) )
|
|
return RELATIONKIND::Friend;
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#else
|
|
return RELATIONKIND::Friend;
|
|
#endif//#if !defined(_NA_006774_20130617_ARRANGE_UNNECESSARY_RESOURCES)
|
|
}
|
|
}
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if(pObject->IsKindOfObject( PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject( NPC_OBJECT) || pObject->IsKindOfObject( LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject( MERCHANT_OBJECT ))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInMissionZone( Character* pObject,BOOL bForceEnemy )
|
|
{
|
|
if( pObject->IsKindOfObject( PLAYER_OBJECT ) )
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if( pObject->IsKindOfObject( MONSTER_OBJECT ) )
|
|
{
|
|
Monster * pMonster = (Monster *)pObject;
|
|
|
|
return GetRelationOfMonster( pMonster, bForceEnemy );
|
|
}
|
|
else if(pObject->IsKindOfObject( PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject( NPC_OBJECT) || pObject->IsKindOfObject( LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject( MERCHANT_OBJECT ))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInInstanceDungeon( Character* pObject,BOOL bForceEnemy )
|
|
{
|
|
return GetRelationKindOfPlayerInMissionZone( pObject,bForceEnemy );
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInDominationWar( Character* pObject, BOOL bForceEnemy /*= FALSE*/ )
|
|
{
|
|
if(pObject->IsKindOfObject( PLAYER_OBJECT ))
|
|
{
|
|
Player* pPlayer = (Player*)pObject;
|
|
if (pPlayer->IsExistGuild())
|
|
{
|
|
return GetRelationOfPlayer(pPlayer, bForceEnemy);
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
else if(pObject->IsKindOfObject( MONSTER_OBJECT ))
|
|
{
|
|
Monster * pMonster = (Monster *)pObject;
|
|
|
|
#ifdef _NA_006826_20130722_DOMINATION_RENEWAL
|
|
// 기본적으론 보통 피아식별과 같지만, 수성 오브젝트를 수성연합에게도 아군으로 인식하게 한다.
|
|
// 자신이 수성 연합이라면
|
|
uiDominationTowerMan* ui_domination_manager = GET_DIALOG_MANAGER(uiDominationTowerMan, UIMAN_DOMINATIONWAR_TOWER);
|
|
if (ui_domination_manager &&
|
|
ui_domination_manager->IsDefenceGuildAlliance(g_pHero->GetGuildRenderInfo().m_GuildGuid))
|
|
{
|
|
// 수성 오브젝트는 아군이다.
|
|
DOMINATION_GUILD_INFO* domination_info = ui_domination_manager->GetDominationGuildInfo();
|
|
if (domination_info->m_GuildGuid == pMonster->GetMasterGuildID())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
}
|
|
|
|
#endif //_NA_006826_20130722_DOMINATION_RENEWAL
|
|
|
|
return GetRelationOfMonster( pMonster, bForceEnemy );
|
|
}
|
|
#ifdef _NA_008243_20150422_DOMINATION_SCENE_OPEN_NPC_STORE
|
|
else if (pObject->IsKindOfObject( NPC_OBJECT) || pObject->IsKindOfObject( LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
#endif // _NA_008243_20150422_DOMINATION_SCENE_OPEN_NPC_STORE
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInBattleGround(Character* pObject, BOOL bForceEnemy /*= FALSE*/)
|
|
{
|
|
#ifdef _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
|
|
if (g_pHero == NULL)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(PLAYER_OBJECT))
|
|
{
|
|
if (g_pHero->GetObjectKey() == pObject->GetObjectKey())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
Player* player = static_cast<Player*>(pObject);
|
|
if (player->GetTeam() == INVALID_TEAM)
|
|
{
|
|
// 팀 설정이 안되있으면 전장인포에서 가져와서 저장한다.
|
|
WORD team_code = ChaosSystem::GetBattleGroundData().GetBattleGroundTeamForPlayerName(player->GetName());
|
|
if (team_code != 0)
|
|
{
|
|
player->SetTeam(team_code);
|
|
}
|
|
}
|
|
|
|
if (player->GetTeam() <= 0)
|
|
{
|
|
if (GlobalFunc::IsParty(player->GetObjectKey()) == TRUE)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
}
|
|
#ifdef _NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
|
|
else if (player->GetTeam() == kObserve)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
#endif //_NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
|
|
else if (g_pHero->GetTeam() == player->GetTeam())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
else if (pObject->IsKindOfObject(MONSTER_OBJECT))
|
|
{
|
|
Monster* monster = static_cast<Monster*>(pObject);
|
|
|
|
if (monster->GetMonsterType() == MONSTER_TYPE_TOTEM)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (monster->GetParentId())
|
|
{
|
|
Player* player = static_cast<Player*>(g_ObjectManager.GetObject(monster->GetParentId()));
|
|
if (player != NULL)//주인이 있다면 주인과의 관계를 본다.
|
|
{
|
|
if (player->GetTeam() == INVALID_TEAM)
|
|
{
|
|
// 팀 설정이 안되있으면 전장인포에서 가져와서 저장한다.
|
|
WORD team_code = ChaosSystem::GetBattleGroundData().GetBattleGroundTeamForPlayerName(player->GetName());
|
|
player->SetTeam(team_code);
|
|
}
|
|
|
|
if (player->GetTeam() <= 0)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
#ifdef _NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
|
|
else if (player->GetTeam() == kObserve)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
#endif //_NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
|
|
else if (g_pHero->GetTeam() == player->GetTeam())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
}
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if (pObject->IsKindOfObject(PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject(NPC_OBJECT) || pObject->IsKindOfObject(LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject(MERCHANT_OBJECT))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
#endif //_NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
#ifdef _NA_007114_20140313_CHAOSZONE_GOLDRUSH
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInGoldRush(Character* pObject, BOOL bForceEnemy /*= FALSE*/)
|
|
{
|
|
if (g_pHero == NULL)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(PLAYER_OBJECT))
|
|
{
|
|
if (g_pHero->GetObjectKey() == pObject->GetObjectKey())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
Player* player = static_cast<Player*>(pObject);
|
|
if (player->GetTeam() == INVALID_TEAM)
|
|
{
|
|
// 팀 설정이 안되있으면 골드러시인포에서 가져와서 저장한다.
|
|
WORD team_code = ChaosSystem::GetGoldRushData().GetGoldRushTeamForPlayerName(player->GetName());
|
|
if (team_code != 0)
|
|
{
|
|
player->SetTeam(team_code);
|
|
}
|
|
}
|
|
|
|
if (player->GetTeam() <= 0)
|
|
{
|
|
if (GlobalFunc::IsParty(player->GetObjectKey()) == TRUE)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
}
|
|
else if (player->GetTeam() == kObserve)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (g_pHero->GetTeam() == player->GetTeam())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
else if (pObject->IsKindOfObject(MONSTER_OBJECT))
|
|
{
|
|
Monster* monster = static_cast<Monster*>(pObject);
|
|
|
|
if (monster->GetMonsterType() == MONSTER_TYPE_TOTEM)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (monster->GetParentId())
|
|
{
|
|
Player* player = static_cast<Player*>(g_ObjectManager.GetObject(monster->GetParentId()));
|
|
if (player != NULL)//주인이 있다면 주인과의 관계를 본다.
|
|
{
|
|
if (player->GetTeam() == INVALID_TEAM)
|
|
{
|
|
// 팀 설정이 안되있으면 골드러시인포에서 가져와서 저장한다.
|
|
WORD team_code = ChaosSystem::GetGoldRushData().GetGoldRushTeamForPlayerName(player->GetName());
|
|
player->SetTeam(team_code);
|
|
}
|
|
|
|
if (player->GetTeam() <= 0)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (player->GetTeam() == kObserve)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (g_pHero->GetTeam() == player->GetTeam())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
}
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if (pObject->IsKindOfObject(PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject(NPC_OBJECT) || pObject->IsKindOfObject(LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject(MERCHANT_OBJECT))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
#endif // _NA_007114_20140313_CHAOSZONE_GOLDRUSH
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInFreePVP(Character* pObject, BOOL bForceEnemy /*= FALSE*/)
|
|
{
|
|
#ifdef _NA_006088_20120910_CHAOS_ZONE_FREE_PVP
|
|
if (g_pHero == NULL)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
// 인벤 캐릭터와 상대방 정보보기 캐릭터가 미니맵에 나오는 현상 수정
|
|
if ((pObject->GetObjectKey() > ONLYCLIENT_OBJECT_KEY) &&
|
|
(pObject->GetObjectKey() < MAX_OBJECT_KEY))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(PLAYER_OBJECT))
|
|
{
|
|
if (g_pHero && g_pHero->GetObjectKey() == pObject->GetObjectKey())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
if (GlobalFunc::IsParty(pObject->GetObjectKey()) == TRUE)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
}
|
|
else if (pObject->IsKindOfObject(MONSTER_OBJECT))
|
|
{
|
|
Monster* monster = static_cast<Monster*>(pObject);
|
|
|
|
if (g_pHero && g_pHero->GetObjectKey() == monster->GetParentId())
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if (GlobalFunc::IsParty(monster->GetParentId()))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
else if (pObject->IsKindOfObject(PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject(NPC_OBJECT) || pObject->IsKindOfObject(LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject(MERCHANT_OBJECT))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
#endif //_NA_006088_20120910_CHAOS_ZONE_FREE_PVP
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInSpa(Character* pObject, BOOL bForceEnemy /*= FALSE*/)
|
|
{
|
|
#ifdef _NA_008069_20150210_ADD_SPA_SYSTEM
|
|
if (g_pHero == NULL)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
// 인벤 캐릭터와 상대방 정보보기 캐릭터가 미니맵에 나오는 현상 수정
|
|
if ((pObject->GetObjectKey() > ONLYCLIENT_OBJECT_KEY) &&
|
|
(pObject->GetObjectKey() < MAX_OBJECT_KEY))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(PLAYER_OBJECT))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if (pObject->IsKindOfObject(MONSTER_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject(PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject(NPC_OBJECT) || pObject->IsKindOfObject(LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject(MERCHANT_OBJECT))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
#endif //_NA_008069_20150210_ADD_SPA_SYSTEM
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
#ifdef _NA_008543_20151027_ONE_DAYS_GUILD_MISSION
|
|
RELATIONKIND::TYPE GameFunc::GetRelationKindOfPlayerInGuildMission(Character* pObject, BOOL bForceEnemy /*= FALSE*/)
|
|
{
|
|
if (g_pHero == NULL)
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
// 인벤 캐릭터와 상대방 정보보기 캐릭터가 미니맵에 나오는 현상 수정
|
|
if ((pObject->GetObjectKey() > ONLYCLIENT_OBJECT_KEY) &&
|
|
(pObject->GetObjectKey() < MAX_OBJECT_KEY))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
|
|
if (pObject->IsKindOfObject(PLAYER_OBJECT))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
else if (pObject->IsKindOfObject(MONSTER_OBJECT))
|
|
{
|
|
Monster* monster = static_cast<Monster*>(pObject);
|
|
|
|
return GetRelationOfMonster( monster, bForceEnemy );
|
|
}
|
|
else if (pObject->IsKindOfObject(PET_OBJECT))
|
|
{
|
|
return RELATIONKIND::None;
|
|
}
|
|
else if (pObject->IsKindOfObject(NPC_OBJECT) || pObject->IsKindOfObject(LOTTO_NPC_OBJECT))
|
|
{
|
|
return RELATIONKIND::Assistant;
|
|
}
|
|
else if (pObject->IsKindOfObject(MERCHANT_OBJECT))
|
|
{
|
|
return RELATIONKIND::Vendor;
|
|
}
|
|
|
|
return RELATIONKIND::None;
|
|
}
|
|
#endif //_NA_008543_20151027_ONE_DAYS_GUILD_MISSION
|
|
//--------------------------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
bool GameFunc::IsCheckItem(SCSlot& slot)
|
|
{
|
|
SCItemSlot& item_slot = static_cast<SCItemSlot&>(slot);
|
|
if (item_slot.IsContainValidItem())
|
|
{
|
|
if (item_slot.IsEtheriaItem())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (item_slot.GetImageCode() != item_slot.GetCode())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (item_slot.IsShellItem())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
//--------------------------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
CODETYPE GameFunc::GetImagecode(SCItemSlot* item_slot, CODETYPE base_code)
|
|
{
|
|
if (item_slot &&
|
|
item_slot->IsContainValidItem())
|
|
{
|
|
//에테리아 조합아이템의경우
|
|
if (item_slot->GetImageCode() != base_code)
|
|
{
|
|
return item_slot->GetImageCode();
|
|
}
|
|
else if (item_slot->IsLimited())
|
|
{
|
|
return item_slot->GetLimitedIndex();
|
|
}
|
|
}
|
|
|
|
return base_code;
|
|
}
|
|
//--------------------------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
BOOL GameFunc::IsLimitedItem(SCItemSlot* item_slot, CODETYPE base_code)
|
|
{
|
|
if (item_slot &&
|
|
item_slot->IsContainValidItem())
|
|
{
|
|
if (item_slot->GetImageCode() != base_code)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else if (item_slot->IsLimited())
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
//--------------------------------------------------------------------------------------------------
|
|
/** 아이템커스터마이징 활성화 여부
|
|
*/
|
|
bool GameFunc::IsActiveCharCustomize(POSTYPE pos)
|
|
{
|
|
uiCharCustomizeDlg* custom_dlg = GET_CAST_DIALOG(uiCharCustomizeDlg,
|
|
IM_CHAR_CUSTOMIZE_MGR::CHAR_CUSTOMIZE_DLG);
|
|
|
|
if (custom_dlg == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return custom_dlg->IsActiveSlot(pos);
|
|
}
|
|
//--------------------------------------------------------------------------------------------------
|
|
/** 아이템슬롯, 아이템인포가 유효해야 네임을 얻을수있다.
|
|
*/
|
|
void GameFunc::GetRealItemName(SCItemSlot* slot_item,
|
|
const BASE_ITEMINFO* item_info,
|
|
TCHAR* name ,
|
|
int size)
|
|
{
|
|
if (item_info == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int string_code =item_info->m_NCode;
|
|
// 소켓(쟈드 아이템)
|
|
if(item_info->m_wType == eITEMTYPE_SOCKET_ZARD && item_info->zard_grade > 0)
|
|
{
|
|
// 12119 : 하급, 12120 중급 12121 상급 12122 최상급
|
|
TCHAR temp_name[128] = {0,};
|
|
TCHAR copy_name[MAX_ITEMNAME_LENGTH] = {0,};
|
|
g_InterfaceManager.GetInterfaceString(string_code, copy_name, size - 1);// 아이템 이름
|
|
|
|
string_code = 12118 + item_info->zard_grade;
|
|
g_InterfaceManager.GetInterfaceString(string_code, temp_name, size - 1);// 등급 추가
|
|
_snprintf(name, size - 1, "%s %s", temp_name, copy_name);
|
|
return;
|
|
}
|
|
|
|
if ((slot_item != NULL) &&
|
|
(slot_item->IsContainValidItem() == TRUE))
|
|
{
|
|
// 무기에테리아일땐 등급표시
|
|
BOOL is_grade_show = (item_info->IsWeapon() ||
|
|
item_info->IsArmor());
|
|
|
|
if (slot_item->IsEtheriaItem())
|
|
{
|
|
if (is_grade_show)
|
|
{
|
|
WORD item_level = slot_item->GetItemInfo()->m_LV;
|
|
string_code = GetItemGradeStringCode(name, item_level, item_info->sub_type_detailed);
|
|
if (string_code == kNormalItemResultStringCode)
|
|
{
|
|
return; // 0 이면 일반 아이템
|
|
}
|
|
/*
|
|
if (item_level < 17)
|
|
{
|
|
TCHAR grade[128] ={0,};
|
|
// 30422 %d 등급
|
|
g_InterfaceManager.GetInterfaceString(30422, grade, 127);
|
|
_snprintf(name, size -1 , grade, item_level);
|
|
return;
|
|
}//얼티메이트
|
|
else if (item_level == 17)
|
|
{
|
|
string_code = 30424;
|
|
}//엘리트 1등급
|
|
else if (item_level == 21)
|
|
{
|
|
// 30428 : 타락한 엘리트1등급
|
|
string_code = (item_info->m_wSubType == 3) ? (30428):(30423);
|
|
}//엘리트 1.5등급
|
|
else if (item_level == 25)
|
|
{
|
|
string_code = 30425;
|
|
}//엘리트 2등급
|
|
else if (item_level == 26)
|
|
{
|
|
string_code = 30426;
|
|
}*/
|
|
}
|
|
|
|
}//에테리아 조합아이템을 경우 이미지네임을 따라간다
|
|
else if(slot_item->GetImageItemInfo()->m_Code != item_info->m_Code)
|
|
{
|
|
string_code = slot_item->GetImageItemInfo()->m_NCode;
|
|
}
|
|
}
|
|
g_InterfaceManager.GetInterfaceString(string_code, name, size - 1);
|
|
|
|
}
|
|
//--------------------------------------------------------------------------------------------------
|
|
/** 커스텀 아이템일경우 추가스트링을 붙여준다
|
|
*/
|
|
void GameFunc::GetCustomizeInfo(SCItemSlot* slot_item, TCHAR* name)
|
|
{
|
|
if (slot_item == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (slot_item->IsContainValidItem() == FALSE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (slot_item->IsShellItem() ||
|
|
slot_item->IsEtheriaItem())
|
|
{
|
|
TCHAR add_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
int string_code = slot_item->IsShellItem() ? (30472) : (30421);
|
|
// 30421: 에테리아
|
|
// 30427: 껍데기
|
|
g_InterfaceManager.GetInterfaceString(string_code, add_string, INTERFACE_STRING_LENGTH);
|
|
_tcscat(name, _T(" "));
|
|
_tcscat(name, add_string);
|
|
}
|
|
}
|
|
|
|
void GameFunc::GetItemName(SCItemSlot* slot_item,
|
|
const BASE_ITEMINFO* item_info,
|
|
TCHAR* name ,
|
|
int size)
|
|
{
|
|
TCHAR first_name[INTERFACE_STRING_LENGTH] = {0, };
|
|
TCHAR second_name[INTERFACE_STRING_LENGTH] = {0, };
|
|
|
|
GameFunc::GetRealItemName(slot_item, item_info, first_name, INTERFACE_STRING_LENGTH);
|
|
|
|
if (item_info->IsWeapon() ||
|
|
item_info->IsArmor())
|
|
{
|
|
g_InterfaceManager.GetInterfaceString(item_info->m_SCNCode, second_name, MAX_PATH);
|
|
#ifdef _RUSSIA
|
|
Snprintf(name, (size - 1), "%s %s", second_name, first_name);
|
|
#else
|
|
Snprintf(name, (size - 1), "%s %s", first_name, second_name);
|
|
#endif //_RUSSIA
|
|
}
|
|
else
|
|
{
|
|
Snprintf(name, (size - 1), "%s", first_name);
|
|
}
|
|
GameFunc::GetCustomizeInfo(slot_item, name);
|
|
}
|
|
|
|
void GameFunc::GetItemDescription(TCHAR* desc_string, SCItemSlot* item_slot, const BASE_ITEMINFO* item_info)
|
|
{
|
|
if ((desc_string == NULL) ||
|
|
(item_info == NULL))
|
|
{
|
|
return;
|
|
}
|
|
|
|
g_InterfaceManager.GetInterfaceString(item_info->m_TDNCode, desc_string, INTERFACE_STRING_LENGTH);
|
|
|
|
if (item_info->m_dwExp > 0)
|
|
{
|
|
TCHAR buffer_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
Snprintf(buffer_string, INTERFACE_STRING_LENGTH - 1, desc_string, item_info->m_dwExp);
|
|
strcpy(desc_string, buffer_string);
|
|
}
|
|
else if ((item_slot != NULL) &&
|
|
(item_slot->IsZardItem() == true))
|
|
{
|
|
SOCKETINDEX zard_option_index = item_slot->GetExtendData();
|
|
if (zard_option_index == SocketOptionParser::kInvalidSocketOptionIndex)
|
|
{
|
|
const SocketOptionParser* const zard_option_parser = SocketOptionParser::Instance();
|
|
zard_option_index = zard_option_parser->GetFixedZardOption(item_slot->GetCode());// 옵션이 하나뿐인 쟈드 옵션을 얻어와서 세팅
|
|
}
|
|
|
|
if (zard_option_index != SocketOptionParser::kInvalidSocketOptionIndex)
|
|
{
|
|
bool is_check = false;
|
|
|
|
const SocketOptionParser* const zard_option_parser = SocketOptionParser::Instance();
|
|
const sSOCKET_OPTION* const zard_option =
|
|
zard_option_parser->FindSocketOption(zard_option_index);
|
|
|
|
int socket_option_name_code = 0;
|
|
const int zard_options_max = sSOCKET_OPTION::OptionPointInfo::kMaxListSize;
|
|
if (zard_option != NULL)
|
|
{
|
|
TCHAR socket_buffer_string[zard_options_max][INTERFACE_STRING_LENGTH] = {0,};
|
|
TCHAR socket_options_string[INTERFACE_STRING_LENGTH] = {0};
|
|
TCHAR buffer_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
TCHAR option_format_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
// 12118: [%s %d 포인트]
|
|
g_InterfaceManager.GetInterfaceString(12118, option_format_string);
|
|
|
|
// 소켓 옵션의 각 옵션 포인트에 대해
|
|
for (sSOCKET_OPTION::OptionPointInfo::ListSizeType i = 0;
|
|
i < zard_option->option_point_list_size; ++i)
|
|
{
|
|
socket_buffer_string[i][0] = '\0';//초기화 ""
|
|
// 포인트 정보가 유효한지 검사한다.
|
|
const sSOCKET_OPTION::OptionPointInfo* const option_point_info = zard_option->GetPointInfo(i);
|
|
if (option_point_info == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// 옵션 정보가 유효한지 검사한다.
|
|
const ZardOptionInfo* const zard_option_info = option_point_info->zard_option;
|
|
if (zard_option_info == NULL ||
|
|
zard_option_info->attr_option_code == eATTR_TYPE_INVALID ||
|
|
zard_option_info->item_option_code == eATTR_TYPE_INVALID)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const BASE_OptionList* const zard_option_desc = OptionListParser::Instance()->GetOptionList(zard_option_info->item_option_code);
|
|
if (zard_option_desc == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
// %s에 들어갈 옵션 종류 이름
|
|
socket_option_name_code = zard_option_desc->mdwNameCode;
|
|
//option_point_info->option_point; // %d에 들어갈 옵션 포인트
|
|
TCHAR option_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
TCHAR comma_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
|
|
g_InterfaceManager.GetInterfaceString(socket_option_name_code, option_string);
|
|
sprintf(comma_string, "%c%s", (is_check && i < (zard_options_max - 1))?',':' ', option_format_string);
|
|
sprintf(socket_buffer_string[i], comma_string, option_string, option_point_info->option_point);
|
|
is_check = true;
|
|
}
|
|
|
|
if (is_check == false)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
sprintf(socket_options_string, "%s%s%s%s%s", socket_buffer_string[0], socket_buffer_string[1],
|
|
socket_buffer_string[2],socket_buffer_string[3],socket_buffer_string[4]);
|
|
// 12161: 무기나 방어구의 소켓에 %s를 부여합니다.<더블클릭으로 사용>
|
|
g_InterfaceManager.GetInterfaceString(12161, buffer_string);
|
|
sprintf(desc_string, buffer_string, socket_options_string);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 상점 아이템인데 옵션이 여러개라서 메시지를 다르게 출력하는 경우를 여기에 구현하면 된다.
|
|
const BASE_ITEMINFO* const zard = item_slot->GetItemInfo();
|
|
if (zard != NULL)
|
|
{
|
|
const BASE_OptionList* const zard_option_desc = OptionListParser::Instance()->GetOptionList((DWORD)zard->zard_item_option_kind);
|
|
if (zard_option_desc != NULL)
|
|
{
|
|
TCHAR buffer_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
TCHAR option_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
TCHAR socket_options_string[INTERFACE_STRING_LENGTH] = {0};
|
|
int socket_option_name_code = 0;
|
|
// %s에 들어갈 옵션 종류 이름
|
|
socket_option_name_code = zard_option_desc->mdwNameCode;
|
|
g_InterfaceManager.GetInterfaceString(socket_option_name_code, option_string);
|
|
// 12169: [%s]
|
|
g_InterfaceManager.GetInterfaceString(12169, buffer_string);
|
|
sprintf(socket_options_string, buffer_string, option_string);
|
|
|
|
// 12161: 무기나 방어구의 소켓에 %s를 부여합니다.<더블클릭으로 사용>
|
|
g_InterfaceManager.GetInterfaceString(12161, buffer_string);
|
|
sprintf(desc_string, buffer_string, socket_options_string);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ((item_info != NULL) &&
|
|
(item_info->m_wType == eITEMTYPE_SOCKET_COMPOSE_ADDITIVE))
|
|
{
|
|
TCHAR buffer_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
TCHAR option_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
sprintf(buffer_string, desc_string, (int)(item_info->zard_success_per/10));
|
|
strcpy(desc_string, buffer_string);
|
|
}
|
|
else if (item_info->m_wType == eITEMTYPE_SOCKETEXTRACT)//소켓 제거 아이템
|
|
{
|
|
TCHAR buffer_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
DWORD string_code = 0;
|
|
float zard_success_per = item_info->zard_success_per;//쟈드 회수 확률
|
|
zard_success_per /= 10;
|
|
if (zard_success_per > 0)
|
|
{
|
|
string_code = 159049; // 무기나 방어구의 소켓에 장착되어 있는 쟈드를 빼냅니다. %d%%의 확률로 쟈드가 온전히 분리됩니다.
|
|
g_InterfaceManager.GetInterfaceString(string_code, buffer_string);
|
|
sprintf(desc_string, buffer_string, (int)zard_success_per);
|
|
}
|
|
else
|
|
{
|
|
string_code = 159022; // 무기나 방어구의 소켓에 장착되어 있는 쟈드를 빼냅니다. 쟈드는 소멸됩니다.
|
|
g_InterfaceManager.GetInterfaceString(string_code, desc_string);
|
|
}
|
|
}
|
|
else if (item_info->m_wType == eITEMTYPE_DOMINATION_BUFF)
|
|
{
|
|
// ... SkillCode - Ability1Parameter1/Ability1Parameter2
|
|
SkillScriptInfo* skill_info = SkillInfoParser::Instance()->GetSkillInfo(item_info->m_wSkillCode);
|
|
BASE_ABILITYINFO* ability_info = NULL;
|
|
if (skill_info != NULL)
|
|
{
|
|
ability_info = skill_info->GetAbilityInfoByIndex(0);
|
|
}
|
|
if (ability_info != NULL)
|
|
{
|
|
TCHAR buffer_string[INTERFACE_STRING_LENGTH] = {0,};
|
|
|
|
if (ability_info->m_iParam[0] == VALUE_TYPE_VALUE)
|
|
{
|
|
sprintf(buffer_string, desc_string, ability_info->m_iParam[1]);
|
|
}
|
|
else
|
|
{
|
|
sprintf(buffer_string, desc_string, (ability_info->m_iParam[1] / 10));
|
|
}
|
|
strcpy(desc_string, buffer_string);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef _NA001415_091123_CHANGE_MOB_AI_IN_SAFETY_AREA_
|
|
// 안전지대 추가 및 코드 정리
|
|
// 타일 속성별 룰 테이블
|
|
// 안전지대 경계지역 분쟁지역 자유분쟁 점령전
|
|
// x Ctrl(파티,길드 및 20렙이하 불가) O(파티,길드원 불가) O,Ctrl(파티,길드원) 길드관계(공/방)
|
|
// 길드관계 우선
|
|
// *서로 다른 속성타일에 있을 경우 공격불가
|
|
RELATIONKIND::TYPE PKRuleForTile::PKTile(Player* pPlayer, PKOptionInfo* pPKInfo, bool bForceEnemy)
|
|
{
|
|
// 경계지역 - 길드관계가 최우선
|
|
RELATIONKIND::TYPE state = GameFunc::GetGuildRelationShip( pPlayer, bForceEnemy );
|
|
if( state != RELATIONKIND::None )
|
|
return state;
|
|
|
|
// 파티원이나 길드원일 경우 Ctrl키를 눌러도 공격 불가
|
|
if( GameFunc::IsFriendShip( pPlayer ) )
|
|
return RELATIONKIND::Friend;
|
|
|
|
// 20렙 미만이면 Ctrl키를 눌러도 공격 불가(레벨은 스크립트로 제어)
|
|
if( g_pHero->GetLevel() < pPKInfo->m_PKAllowableLV || pPlayer->GetLevel() < pPKInfo->m_PKProtectLV )
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
// 카오 및 보라돌이 처리
|
|
#ifdef _CHINA
|
|
if( pPlayer->GetChaoState() == eCHAO_STATE_CHAO )
|
|
#else
|
|
if( pPlayer->GetChaoState() == eCHAO_STATE_CHAO || pPlayer->IsAttackBeginPlayer() )
|
|
#endif
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
|
|
// 이외의 상황에서 Ctrl키 누름 - 공격
|
|
if (bForceEnemy)
|
|
{
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
RELATIONKIND::TYPE PKRuleForTile::ConflictTile(Player* pPlayer, PKOptionInfo* pPKInfo, bool bForceEnemy)
|
|
{
|
|
// 파티원이나 길드원일 경우 Ctrl키를 눌러도 공격 불가
|
|
if(GameFunc::IsFriendShip( pPlayer ))
|
|
return RELATIONKIND::Friend;
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
RELATIONKIND::TYPE PKRuleForTile::FreeConflictTile(Player* pPlayer, PKOptionInfo* pPKInfo, bool bForceEnemy)
|
|
{
|
|
// 파티원이나 길드원일 경우 Ctrl키를 누르면 공격가능(누르지 않으면 공격불가)
|
|
if(GameFunc::IsFriendShip( pPlayer ) && false == bForceEnemy)
|
|
return RELATIONKIND::Friend;
|
|
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
RELATIONKIND::TYPE PKRuleForTile::DominationTile(Player* pPlayer, PKOptionInfo* pPKInfo, bool bForceEnemy)
|
|
{
|
|
// 점령전 플레이어 체크
|
|
if(pPlayer->IsExistGuild())
|
|
{
|
|
if( eGUILD_RELATION_ALLIENCE == pPlayer->GetGuildRenderInfo().m_RelationType )
|
|
return RELATIONKIND::Friend;
|
|
else if(eGUILD_RELATION_NONE == pPlayer->GetGuildRenderInfo().m_RelationType )
|
|
return RELATIONKIND::None;
|
|
else
|
|
return RELATIONKIND::Enemy;
|
|
}
|
|
return RELATIONKIND::None;
|
|
}
|
|
RELATIONKIND::TYPE PKRuleForTile::CheckRelationTileAttr(Player* pPlayer, PKOptionInfo* pPKInfo, bool bForce)
|
|
{
|
|
if (NULL == g_pHero)
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
|
|
// 자신과 상대 플레이어의 타일 속성을 가져온다.
|
|
DWORD dwHeroAtt = g_pHero->GetCurrentTileAtt(FALSE);
|
|
DWORD dwPlayerAtt = pPlayer->GetCurrentTileAtt(FALSE);
|
|
|
|
if (GameFunc::GetCheckPlayerOnTile(dwHeroAtt, dwPlayerAtt, PTA_PK_TILE) && !(pPKInfo->m_IgnorePKTile&PKOptionInfo::ignore_BoundaryPart))
|
|
{
|
|
return PKTile(pPlayer, pPKInfo, bForce);
|
|
}
|
|
if (GameFunc::GetCheckPlayerOnTile(dwHeroAtt, dwPlayerAtt, PTA_CONFLICT_TILE) && !(pPKInfo->m_IgnorePKTile&PKOptionInfo::ignore_NomalPart))
|
|
{
|
|
return ConflictTile(pPlayer, pPKInfo, bForce);
|
|
}
|
|
if (GameFunc::GetCheckPlayerOnTile(dwHeroAtt, dwPlayerAtt, PTA_FREE_CONFLICT_TILE) && !(pPKInfo->m_IgnorePKTile&PKOptionInfo::ignore_FreePart))
|
|
{
|
|
return FreeConflictTile(pPlayer, pPKInfo, bForce);
|
|
}
|
|
if (GameFunc::GetCheckPlayerOnTile(dwHeroAtt, dwPlayerAtt, PTA_DOMINATION_WAR_TILE))
|
|
{
|
|
return DominationTile(pPlayer, pPKInfo, bForce);
|
|
}
|
|
if (BIT_CHECK(dwHeroAtt,PTA_SAFETY_ZONE) || BIT_CHECK(dwPlayerAtt, PTA_SAFETY_ZONE))
|
|
{
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
return RELATIONKIND::Friend;
|
|
}
|
|
#endif //_NA001415_091123_CHANGE_MOB_AI_IN_SAFETY_AREA_
|
|
|
|
int GameFunc::CheckLODLevelByPlayerCount(int player_count, int option_lod_level)
|
|
{
|
|
const int lod_count[4] = {17,20,32,35};
|
|
static int lod_of_player_count = 0;
|
|
|
|
int lod_level = 2;
|
|
for (int i = 1; i < 4; i += 2)
|
|
{
|
|
if (player_count <= lod_count[i])
|
|
{
|
|
int temp_Level = (i >> 1);
|
|
if ((lod_of_player_count == (temp_Level + 1)) &&
|
|
(player_count > lod_count[i - 1]))
|
|
{
|
|
lod_level = lod_of_player_count;
|
|
}
|
|
else
|
|
{
|
|
lod_level = temp_Level;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
lod_level = max(lod_level, option_lod_level);
|
|
lod_of_player_count = lod_level;
|
|
|
|
return lod_level;
|
|
}
|
|
|
|
void GameFunc::ApplyLODDistance(int lod_level)
|
|
{
|
|
switch (lod_level)
|
|
{
|
|
case eOPTION_LEVEL_HIGH:
|
|
{
|
|
float fLODDistance[4] = {20.0f, 21.0f, 30.0f, 31.0f};
|
|
g_pSunRenderer->x_pManagerUnitLOD->SetDistanceOfLOD(fLODDistance, 4);
|
|
}
|
|
break;
|
|
case eOPTION_LEVEL_MIDDLE:
|
|
{
|
|
float fLODDistance[4] = {15.0f, 16.0f, 20.0f, 21.0f};
|
|
g_pSunRenderer->x_pManagerUnitLOD->SetDistanceOfLOD(fLODDistance, 4);
|
|
}
|
|
break;
|
|
case eOPTION_LEVEL_LOW:
|
|
{
|
|
float fLODDistance[4] = {10.0f, 11.0f, 15.0f, 16.0f};
|
|
g_pSunRenderer->x_pManagerUnitLOD->SetDistanceOfLOD(fLODDistance, 4);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GameFunc::ApplyEffectLODDistance(int lod_level)
|
|
{
|
|
if( g_pEffectManager != NULL )
|
|
{
|
|
switch (lod_level)
|
|
{
|
|
case eOPTION_LEVEL_HIGH:
|
|
{
|
|
g_pEffectManager->ClearEffectLODParams();
|
|
g_pEffectManager->AddEffectLODParam(30.0f, 40);
|
|
g_pEffectManager->AddEffectLODParam(20.0f, 60);
|
|
g_pEffectManager->AddEffectLODParam(15.0f, 70);
|
|
g_pEffectManager->AddEffectLODParam(10.0f, 80);
|
|
}
|
|
break;
|
|
case eOPTION_LEVEL_MIDDLE:
|
|
{
|
|
g_pEffectManager->ClearEffectLODParams();
|
|
g_pEffectManager->AddEffectLODParam(30.0f, 20);
|
|
g_pEffectManager->AddEffectLODParam(20.0f, 40);
|
|
g_pEffectManager->AddEffectLODParam(15.0f, 60);
|
|
g_pEffectManager->AddEffectLODParam(10.0f, 80);
|
|
}
|
|
break;
|
|
case eOPTION_LEVEL_LOW:
|
|
{
|
|
g_pEffectManager->ClearEffectLODParams();
|
|
g_pEffectManager->AddEffectLODParam(30.0f, 10);
|
|
g_pEffectManager->AddEffectLODParam(20.0f, 20);
|
|
g_pEffectManager->AddEffectLODParam(15.0f, 30);
|
|
g_pEffectManager->AddEffectLODParam(10.0f, 50);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int GameFunc::GetNearestTile(const WzVector& pos)
|
|
{
|
|
float backup_length = 10000000.0f;
|
|
|
|
int tile_no = -1;
|
|
|
|
int tile_num = g_pSunTerrain->x_pPathFinder->GetNumPathTile();
|
|
for (int i = 0; i < tile_num; ++i)
|
|
{
|
|
WzVector v = g_pSunTerrain->x_pPathFinder->GetNearestPointToTarget(i, pos);
|
|
WzVector gab = v - pos;
|
|
float length = VectorLength(&gab);
|
|
if (length < backup_length)
|
|
{
|
|
tile_no = i;
|
|
backup_length = length;
|
|
}
|
|
}
|
|
|
|
return tile_no;
|
|
}
|
|
|
|
bool GameFunc::FindMoveableNearestTile( const WzVector& StartPosition, WzVector& DestPosition, int& tile_number )
|
|
{
|
|
int StartTileIndex = g_pSunTerrain->x_pPathFinder->GetTileToStand( StartPosition );
|
|
if( StartTileIndex == -1 )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool empty_tile = false;
|
|
int DestTileIndex = g_pSunTerrain->x_pPathFinder->GetTileToStand( DestPosition );
|
|
if( DestTileIndex == -1 )
|
|
{
|
|
empty_tile = true;
|
|
DestTileIndex = GetNearestTile( DestPosition, PTA_ONLY_JUMP | PTA_NO_WALK );
|
|
if( DestTileIndex == -1 )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#ifdef _NA_008721_20160308_AUTOMOVE_TO_PORTAL_BUG_FIX
|
|
bool block_tile = false;
|
|
if (g_pSunTerrain->x_pPathFinder->GetAttribute(DestTileIndex) & (PTA_ONLY_JUMP | PTA_NO_WALK))
|
|
{
|
|
// 갈수 없는 타일을 가려고 할 경우
|
|
block_tile = true;
|
|
}
|
|
#endif //_NA_008721_20160308_AUTOMOVE_TO_PORTAL_BUG_FIX
|
|
|
|
|
|
WzVector start = StartPosition;
|
|
WzVector dest = DestPosition;
|
|
int num_result;
|
|
int result[1024];
|
|
ENUM_FINDPATH_RESULT Result = g_pSunTerrain->x_pPathFinder->FindPath( StartTileIndex, DestTileIndex, &start, &dest,
|
|
result, 1024, &num_result,
|
|
0, 200000 );
|
|
|
|
if( Result == EFR_SUCCESS )
|
|
{
|
|
for( int i=num_result-1; i>=0; --i )
|
|
{
|
|
WORD attrib = g_pSunTerrain->x_pPathFinder->GetAttribute( result[i] );
|
|
if( attrib & PTA_NO_WALK )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if( attrib & PTA_ONLY_JUMP )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
tile_number = result[i];
|
|
|
|
#ifdef _NA_008721_20160308_AUTOMOVE_TO_PORTAL_BUG_FIX
|
|
if (empty_tile == true || block_tile == true)
|
|
{
|
|
// 목적지를 목적타일의 중심으로 바꿔줌
|
|
// 위의 empty_tile은 GetNearestPointToTarget()에서 나온 좌표가 tile_number 타일을 벗어난 값이 나오는 경우가 종종있어서 오동작함
|
|
// 어쨋든 block_tile 타일로 가려고 한 경우는 여기서 처리
|
|
WzVector out_vec[3];
|
|
WzVector center_vec;
|
|
g_pSunTerrain->x_pPathFinder->GetTileVertexInfo(out_vec, tile_number);
|
|
|
|
center_vec = out_vec[0] + out_vec[1] + out_vec[2];
|
|
|
|
center_vec.x *= ( 1.0f / 3.0f);
|
|
center_vec.y *= ( 1.0f / 3.0f);
|
|
center_vec.z *= ( 1.0f / 3.0f);
|
|
|
|
DestPosition = center_vec;
|
|
}
|
|
#else
|
|
if( empty_tile == true )
|
|
{
|
|
DestPosition = g_pSunTerrain->x_pPathFinder->GetNearestPointToTarget(tile_number, DestPosition);
|
|
}
|
|
#endif //_NA_008721_20160308_AUTOMOVE_TO_PORTAL_BUG_FIX
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
int GameFunc::GetNearestTile(const WzVector& pos, WORD restrict_tile_attribute)
|
|
{
|
|
WORD attribute = 0;
|
|
int tile_no = g_pSunTerrain->x_pPathFinder->GetTileToStand(pos, NULL, -1.0f, -1.0f, &attribute);
|
|
if (tile_no >= 0)
|
|
{
|
|
if ((attribute & restrict_tile_attribute) == FALSE)
|
|
{
|
|
return tile_no;
|
|
}
|
|
}
|
|
|
|
float backup_length = 10000000.0f;
|
|
|
|
tile_no = -1;
|
|
|
|
int tile_num = g_pSunTerrain->x_pPathFinder->GetNumPathTile();
|
|
for (int i = 0; i < tile_num; ++i)
|
|
{
|
|
if (g_pSunTerrain->x_pPathFinder->CheckAttribute(i, restrict_tile_attribute) == TRUE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
WzVector v = g_pSunTerrain->x_pPathFinder->GetNearestPointToTarget(i, pos);
|
|
WzVector gab = v - pos;
|
|
float length = VectorLength(&gab);
|
|
if (length < backup_length)
|
|
{
|
|
tile_no = i;
|
|
backup_length = length;
|
|
}
|
|
}
|
|
|
|
return tile_no;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
MapObject* GameFunc::GetWaypoint()
|
|
{
|
|
Object_Map::iterator begin = g_ObjectManager.GetBegin();
|
|
Object_Map::iterator end = g_ObjectManager.GetEnd();
|
|
for (; begin != end; ++ begin)
|
|
{
|
|
Object* object = begin->second;
|
|
if ((object == NULL) || (object->IsKindOfObject(MAP_OBJECT) == FALSE))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MapObject* map_object = static_cast<MapObject*>(object);
|
|
|
|
if (map_object->IsWayPointObj() == TRUE)
|
|
{
|
|
return map_object;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
NPC* GameFunc::GetNearestShopNpcByItem(SLOTCODE item_code)
|
|
{
|
|
std::list<NPC*> npc_list;
|
|
|
|
{
|
|
// 상점 npc 리스트 만듬
|
|
Object_Map::iterator begin = g_ObjectManager.GetBegin();
|
|
Object_Map::iterator end = g_ObjectManager.GetEnd();
|
|
for (; begin != end; ++ begin)
|
|
{
|
|
Object* object = begin->second;
|
|
if ((object == NULL) || (object->IsKindOfObject(NPC_OBJECT) == FALSE))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
EXTRA_NPCINFO* extra_info = static_cast<NPC*>(object)->GetExtraInfo();
|
|
if (extra_info->m_eNPCTYPE != eNPC_TYPE_STORE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( ShopInfoParser::Instance()->HasSellItemByItemCode( extra_info->m_NPCCODE, item_code ) == true )
|
|
{
|
|
npc_list.push_back(static_cast<NPC*>(object));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//가장 가까운 npc
|
|
NPC* nearest_npc = NULL;
|
|
|
|
{
|
|
std::list<NPC*>::iterator begin = npc_list.begin();
|
|
std::list<NPC*>::iterator end = npc_list.end();
|
|
|
|
for (; begin != end; ++ begin)
|
|
{
|
|
if (nearest_npc == NULL)
|
|
{
|
|
nearest_npc = *begin;
|
|
}
|
|
else
|
|
{
|
|
WzVector gab1 = nearest_npc->GetPosition() - g_pHero->GetPosition();
|
|
WzVector gab2 = (*begin)->GetPosition() - g_pHero->GetPosition();
|
|
|
|
if (VectorLength(&gab1) > VectorLength(&gab2))
|
|
{
|
|
nearest_npc = *begin;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nearest_npc;
|
|
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
NPC* GameFunc::GetNearestShopNpc(eITEMTYPE sell_item_type)
|
|
{
|
|
std::list<NPC*> npc_list;
|
|
npc_list.clear();
|
|
|
|
{
|
|
// 상점 npc 리스트 만듬
|
|
Object_Map::iterator begin = g_ObjectManager.GetBegin();
|
|
Object_Map::iterator end = g_ObjectManager.GetEnd();
|
|
for (; begin != end; ++ begin)
|
|
{
|
|
Object* object = begin->second;
|
|
if ((object == NULL) || (object->IsKindOfObject(NPC_OBJECT) == FALSE))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
EXTRA_NPCINFO* extra_info = static_cast<NPC*>(object)->GetExtraInfo();
|
|
if (extra_info->m_eNPCTYPE != eNPC_TYPE_STORE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( ShopInfoParser::Instance()->HasSellItemByItemType( extra_info->m_NPCCODE, sell_item_type ) == true )
|
|
{
|
|
npc_list.push_back(static_cast<NPC*>(object));
|
|
}
|
|
}
|
|
}
|
|
|
|
//가장 가까운 npc
|
|
NPC* nearest_npc = NULL;
|
|
|
|
{
|
|
std::list<NPC*>::iterator begin = npc_list.begin();
|
|
std::list<NPC*>::iterator end = npc_list.end();
|
|
|
|
for (; begin != end; ++ begin)
|
|
{
|
|
if (nearest_npc == NULL)
|
|
{
|
|
nearest_npc = *begin;
|
|
}
|
|
else
|
|
{
|
|
WzVector gab1 = nearest_npc->GetPosition() - g_pHero->GetPosition();
|
|
WzVector gab2 = (*begin)->GetPosition() - g_pHero->GetPosition();
|
|
|
|
if (VectorLength(&gab1) > VectorLength(&gab2))
|
|
{
|
|
nearest_npc = *begin;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nearest_npc;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
int GameFunc::GetMonstetListTargetPlayer(OUT vector<DWORD>& monster_vector, DWORD object_key)
|
|
{
|
|
Object_Map::iterator begin = g_ObjectManager.GetBegin();
|
|
Object_Map::iterator end = g_ObjectManager.GetEnd();
|
|
for (; begin != end; ++ begin)
|
|
{
|
|
Object* object = begin->second;
|
|
if ((object == NULL) || (object->IsKindOfObject(MONSTER_OBJECT) == FALSE))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Monster* monster = static_cast<Monster*>(object);
|
|
|
|
if (monster->GetTargetID() == object_key)
|
|
{
|
|
monster_vector.push_back(monster->GetObjectKey());
|
|
}
|
|
}
|
|
|
|
return static_cast<int>(monster_vector.size());
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
int GameFunc::GetInterpolationValue(int small_value, int big_value, float ratio)
|
|
{
|
|
return (int)(small_value + ((big_value - small_value) * ratio));
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
float GameFunc::GetInterpolationValue(float small_value, float big_value, float ratio)
|
|
{
|
|
return (small_value + ((big_value - small_value) * ratio));
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
RECT GameFunc::GetInterpolationValue(RECT& small_value, RECT& big_value, float ratio)
|
|
{
|
|
RECT v;
|
|
v.left = static_cast<LONG>(small_value.left + ((big_value.left - small_value.left) * ratio));
|
|
v.top = static_cast<LONG>(small_value.top + ((big_value.top - small_value.top) * ratio));
|
|
v.right = static_cast<LONG>(small_value.right + ((big_value.right - small_value.right) * ratio));
|
|
v.bottom = static_cast<LONG>(small_value.bottom + ((big_value.bottom - small_value.bottom) * ratio));
|
|
|
|
return v;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
bool GameFunc::IsPossibleStand(WzVector& pos, float height, WORD restrict_tile_attribute)
|
|
{
|
|
WzRay ray;
|
|
ray.m_wvOrigin = pos;
|
|
ray.m_wvOrigin.z += height;
|
|
ray.m_wvDirection.x = 0.0f;
|
|
ray.m_wvDirection.y = 0.0f;
|
|
ray.m_wvDirection.z = -1.0f;
|
|
|
|
bool is_find = true;
|
|
float fT;
|
|
if (g_pSunTerrain->PickTerrainMesh(&ray, &fT ,TRUE, TMGO_NO_COLLISION) < 0)
|
|
{
|
|
ray.m_wvOrigin.z += height;
|
|
ray.m_wvDirection.x = 0.0f;
|
|
ray.m_wvDirection.y = 0.0f;
|
|
ray.m_wvDirection.z = 1.0f;
|
|
|
|
if(g_pSunTerrain->PickTerrainMesh(&ray, &fT , FALSE,TMGO_NO_COLLISION) < 0)
|
|
{
|
|
is_find = false;
|
|
}
|
|
}
|
|
|
|
if (is_find)
|
|
{
|
|
WzVector dest_pos = ray.m_wvOrigin + ray.m_wvDirection * fT;
|
|
g_pPathExplorer->Stop();
|
|
|
|
g_pSunTerrain->PathExp_Reset(g_pPathExplorer, &dest_pos, -1);
|
|
|
|
int tile_no = g_pPathExplorer->GetTile();
|
|
if ((tile_no >= 0) &&
|
|
((g_pSunTerrain->x_pPathFinder->GetAttribute(tile_no) & restrict_tile_attribute) == false))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
bool GameFunc::IsIntersect(WzVector& scr, WzVector& dst)
|
|
{
|
|
const float HEIGHT = 2.8f;
|
|
|
|
WzRay ray;
|
|
WzVector vDistance = dst - scr;
|
|
float fDistance = VectorLength(&vDistance);
|
|
ray.m_wvOrigin = scr;
|
|
ray.m_wvOrigin.z +=0.2f;
|
|
ray.m_wvDirection = dst - ray.m_wvOrigin;
|
|
|
|
VectorNormalize(&ray.m_wvDirection,&ray.m_wvDirection);
|
|
|
|
if (g_pMap->IntersectTree_Ray_Bv(&ray,fDistance) == TRUE)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
WzVector vObjPosition;
|
|
|
|
if (g_pMap->IntersectMapObject_Ray_Bv(&ray, fDistance, HEIGHT, vObjPosition) == TRUE)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
float fT;
|
|
|
|
WzVector tempDest = dst;
|
|
WzVector tempSrc = scr;
|
|
|
|
tempSrc.z +=2.5f;
|
|
tempDest.z = tempSrc.z;
|
|
|
|
vDistance = tempDest - tempSrc;
|
|
fDistance = VectorLength(&vDistance);
|
|
ray.m_wvOrigin = tempSrc;
|
|
ray.m_wvDirection = tempDest - ray.m_wvOrigin;
|
|
VectorNormalize(&ray.m_wvDirection,&ray.m_wvDirection);
|
|
|
|
//Todo:뒷면 지형 체크 옵션 바꾸기
|
|
int iTerrainMeshFocussing = g_pSunTerrain->PickTerrainMesh(&ray, &fT, FALSE,TMGO_NO_COLLISION);
|
|
if (iTerrainMeshFocussing >= 0 && fT <= fDistance)
|
|
{
|
|
//지형과 충돌
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
BodyPart GameFunc::EquipToBodyPart(eEQUIPCONTAINER_POS equip_pos/*item_info->m_wEqPos*/)
|
|
{
|
|
BodyPart bodypart_index = BP_COUNT;
|
|
switch (equip_pos)
|
|
{
|
|
case eEQUIPCONTAINER_WEAPON: bodypart_index = BP_WEAPON;break;
|
|
case eEQUIPCONTAINER_BOOTS: bodypart_index = BP_BOOTS;break;
|
|
case eEQUIPCONTAINER_PANTS: bodypart_index = BP_PANTS;break;
|
|
case eEQUIPCONTAINER_ARMOR: bodypart_index = BP_ARMOR;break;
|
|
case eEQUIPCONTAINER_HELMET:bodypart_index = BP_HELM; break;
|
|
case eEQUIPCONTAINER_GLOVE: bodypart_index = BP_GLOVE; break;
|
|
case eEQUIPCONTAINER_SACCESSORY1: bodypart_index = BP_SPECIAL_ACCESSORY1; break;
|
|
case eEQUIPCONTAINER_SACCESSORY2: bodypart_index = BP_SPECIAL_ACCESSORY2; break;
|
|
case eEQUIPCONTAINER_SACCESSORY3: bodypart_index = BP_SPECIAL_ACCESSORY3; break;
|
|
case eEQUIPCONTAINER_PROTECTOR:
|
|
case eEQUIPCONTAINER_BELT:
|
|
case eEQUIPCONTAINER_SHIRTS:
|
|
case eEQUIPCONTAINER_RING1:
|
|
case eEQUIPCONTAINER_RING2:
|
|
case eEQUIPCONTAINER_NECKLACE:
|
|
default:
|
|
break; //return false;
|
|
}
|
|
|
|
return bodypart_index;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
int GameFunc::GetItemGradeStringCode(TCHAR *item_name, WORD item_level, ItemSubTypeDetail item_subtype)
|
|
{
|
|
int string_code = 0;
|
|
|
|
switch (item_subtype.value)
|
|
{
|
|
case ItemSubTypeDetail::kSuperJapan:
|
|
string_code = 30424; // 30424 얼티메이트 (일본 최강)
|
|
break;
|
|
case ItemSubTypeDetail::kElite1_0st:
|
|
string_code = 30423; // 30423 엘리트 1차
|
|
break;
|
|
case ItemSubTypeDetail::kCurruptTemple:
|
|
string_code = 30428; // 30428 저주받은 엘리트 1차
|
|
break;
|
|
case ItemSubTypeDetail::kElite1_5st:
|
|
string_code = 30425; // 30425 엘리트 1.5차
|
|
break;
|
|
case ItemSubTypeDetail::kElite2_0st:
|
|
string_code = 30426; // 30426 엘리트 2차
|
|
break;
|
|
case ItemSubTypeDetail::kElite2_5st:
|
|
string_code = 30434; // - 엘리트 2.5차
|
|
break;
|
|
case ItemSubTypeDetail::kElite3_0st:
|
|
string_code = 30435; // - 엘리트 3차
|
|
break;
|
|
case ItemSubTypeDetail::kElite3_5st:
|
|
string_code = 30451; // - 엘리트 3.5차
|
|
break;
|
|
case ItemSubTypeDetail::kElite4_0st:
|
|
string_code = 30452; // - 엘리트 4차
|
|
break;
|
|
case ItemSubTypeDetail::kUnique1_0st:
|
|
string_code = 30429; // - 유니크 1차
|
|
break;
|
|
case ItemSubTypeDetail::kUnique1_5st:
|
|
string_code = 30453; // - 유니크 1.5차
|
|
break;
|
|
case ItemSubTypeDetail::kUnique2_0st:
|
|
string_code = 30430; // - 유니크 2차
|
|
break;
|
|
case ItemSubTypeDetail::kUnique2_5st:
|
|
string_code = 30454; // - 유니크 2.5차
|
|
break;
|
|
case ItemSubTypeDetail::kFigter_Elite2_0st:
|
|
string_code = 30433; // - 투사 엘리트 2차
|
|
break;
|
|
case ItemSubTypeDetail::kFigter_Elite3_0st:
|
|
string_code = 30436; // - 투사 엘리트 3차
|
|
break;
|
|
|
|
default: // kItemLevelNormal
|
|
{
|
|
TCHAR grade[INTERFACE_STRING_LENGTH] ={0,};
|
|
// 30422 %d 등급, (item_level)
|
|
g_InterfaceManager.GetInterfaceString(30422, grade, 127);
|
|
_snprintf(item_name, INTERFACE_STRING_LENGTH-1, grade, item_level);
|
|
}
|
|
break;
|
|
}
|
|
return string_code;
|
|
}
|
|
|
|
|
|
////------------------------------------------------------------------------------
|
|
// 남과장님 요청한 예제 함수
|
|
////------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------
|
|
bool GameFunc::Tile_CrossCheck(WzVector *pwvFrom, WzVector *pwvTo, WzVector *pwvEdge1, WzVector *pwvEdge2, float *pfDist, WzVector* pwvCross)
|
|
{
|
|
Wz2DLine w2l, w2lEdge;
|
|
As2D_GetLine(&w2l, pwvFrom, pwvTo);
|
|
As2D_GetLine(&w2lEdge, pwvEdge1, pwvEdge2);
|
|
|
|
// 교차점 얻기
|
|
WzVector wvCross;
|
|
As2D_GetCrossPointOfTwoLine(&wvCross, &w2l, &w2lEdge);
|
|
|
|
// 두 Edge 사이를 통과 하고 있는가?
|
|
float fVectorDist[2];
|
|
fVectorDist[0] = As2D_Distance_Line_Vertex(&w2l, *pwvEdge1);
|
|
fVectorDist[1] = As2D_Distance_Line_Vertex(&w2l, *pwvEdge2);
|
|
fVectorDist[0] = (fabs(fVectorDist[0])>0.0001f)?fVectorDist[0]:0.0f;
|
|
fVectorDist[1] = (fabs(fVectorDist[1])>0.0001f)?fVectorDist[1]:0.0f;
|
|
|
|
if (fabs(fVectorDist[0]) > WZ_EPSILON && fabs(fVectorDist[1]) > WZ_EPSILON && 0.0f < (fVectorDist[0] * fVectorDist[1]))
|
|
{
|
|
//두 Edge가 직선의 Nomal 방향(또는 Nomal 반대 방향)에 같이 위치 하고 있어 교차점이 없다.
|
|
return false;
|
|
}
|
|
|
|
fVectorDist[0] = As2D_Distance_Line_Vertex(&w2lEdge, *pwvTo);
|
|
if (0.0f < fVectorDist[0])
|
|
{
|
|
//pwvFrom 과 pwvTo가 모두 w2lEdge의 노말 방향에 위치 하고 있어 교차점이 없다.
|
|
return false;
|
|
}
|
|
|
|
WzVector wvDIst = wvCross - *pwvFrom;
|
|
*pfDist = VectorLength(&wvDIst);
|
|
|
|
if (pwvCross)
|
|
{
|
|
*pwvCross = wvCross;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
//! Returns: bool true : 삼각형 접선에 충돌
|
|
//! Qualifier: 진행방향에 따른 삼각형 선분 방향 구하는 함수
|
|
//! Parameter: WzVector * triangle_vector_list : 삼각형 3점 배열 3개짜리
|
|
//! Parameter: WzVector & from : 캐릭터 이동 시작 위치
|
|
//! Parameter: WzVector & to : 이후 캐릭터 이동 될 위치
|
|
//! Parameter: OUT WzVector & out_dir : 선분 방향
|
|
//! Parameter: OUT float & dot_product_value : dot product 한 값.
|
|
//------------------------------------------------------------------------------
|
|
bool GameFunc::GetTangentDirection(WzVector* triangle_vector_list,
|
|
WzVector& from,
|
|
WzVector& to,
|
|
OUT WzVector& out_dir,
|
|
OUT float& dot_product_value)
|
|
{
|
|
if (triangle_vector_list == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
WzVector start_pos, end_pos, cross_pos;
|
|
float cross_dist = 1000000000.0f;
|
|
|
|
|
|
float temp_dist = 0.0f;
|
|
WzVector temp_cross;
|
|
|
|
bool is_col = false;
|
|
for(int i = 0; i < 3; ++i)
|
|
{
|
|
WzVector line0 = triangle_vector_list[i];
|
|
WzVector line1 = triangle_vector_list[( i + 1) % 3];
|
|
|
|
if (Tile_CrossCheck(&from, &to, &line0, &line1, &temp_dist, &temp_cross) == true)
|
|
{
|
|
if ((is_col == false) || (temp_dist < cross_dist))
|
|
{
|
|
start_pos = line0;
|
|
end_pos = line1;
|
|
cross_pos = temp_cross;
|
|
cross_dist = temp_dist;
|
|
|
|
is_col = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_col == true)
|
|
{
|
|
WzVector move_dir = to - from;
|
|
WzVector line_dir = end_pos - start_pos;
|
|
|
|
WzVector player_dir;
|
|
WzVector tangent_dir;
|
|
VectorNormalize(&player_dir, &move_dir);
|
|
VectorNormalize(&tangent_dir, &line_dir);
|
|
|
|
dot_product_value = VectorDotProduct(&player_dir, &tangent_dir);
|
|
if (dot_product_value > 0 && dot_product_value <= 1)
|
|
{
|
|
//예각이니깐
|
|
out_dir = line_dir;
|
|
}
|
|
else if (dot_product_value < 0 && dot_product_value >= -1)
|
|
{
|
|
//둔각이니깐
|
|
out_dir = -line_dir;
|
|
}
|
|
else
|
|
{
|
|
//나머진 90.
|
|
out_dir.x = 0;
|
|
out_dir.y = 0;
|
|
out_dir.z = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void GameFunc::ExamplePlayerNextDirection(Player* player, DWORD elapse_tick)
|
|
{
|
|
//! 초기 값
|
|
float fMoveSpeed = player->GetMoveSpeed() * (float)elapse_tick;
|
|
WzVector offset = player->GetDirection() * fMoveSpeed;
|
|
WzVector from = player->GetPosition();
|
|
WzVector to = from + offset;
|
|
|
|
//------------------------------------------------------------------------------
|
|
//! 타일의 3점을 얻어 온다.
|
|
WzVector out_vec[3];
|
|
g_pSunTerrain->x_pPathFinder->GetTileVertexInfo(out_vec, player->GetPathExplorer()->GetTile());
|
|
|
|
//------------------------------------------------------------------------------
|
|
//! 캐릭터 이동 방향으로 걸린 삼각형의 선분을 구해옴
|
|
WzVector move_dir;
|
|
float dot_product_value = 0.0f;
|
|
if (GameFunc::GetTangentDirection(out_vec, from, to, OUT move_dir, OUT dot_product_value) == true)
|
|
{
|
|
//move_dir
|
|
//확인 사살(실제 값이 맞는지 확인
|
|
WzVector temp_move_dir = to - from;
|
|
|
|
WzVector player_dir;
|
|
WzVector tangent_dir;
|
|
VectorNormalize(&player_dir, &temp_move_dir);
|
|
VectorNormalize(&tangent_dir, &move_dir);
|
|
float temp = VectorDotProduct(&player_dir, &tangent_dir);
|
|
}
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
Player* GameFunc::MakeBattleZonePlayer(PLAYER_RENDER_INFO_EX& render_info_ex,
|
|
ETC_STATE_TOTAL_INFO* state_total_info,
|
|
VENDOR_RENDER_INFO* vendor_render_info,
|
|
EQUIP_ITEM_BASEINFO* equip_item_info,
|
|
sMSG_RENDER_EFFECT_ITEM_LIST* effect_item_info)
|
|
{
|
|
DWORD object_key = g_ObjectManager.GenerateKeyByBattleZonePlayer(PLAYER_OBJECT);
|
|
if (object_key <= 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (g_ObjectManager.GetObject(object_key) != NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
render_info_ex.hp = 1;
|
|
render_info_ex.is_riding = 0;
|
|
render_info_ex.spread_wings = 0;
|
|
render_info_ex.char_condition = 0;
|
|
|
|
ClassCodeEx class_code_ex(render_info_ex.char_class, render_info_ex.gender);
|
|
Player* player = (Player*)g_ObjectManager.Add(object_key, PLAYER_OBJECT, class_code_ex.class_code, FALSE);
|
|
if (player == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
player->HideHelmet(render_info_ex.helmet != 0, FALSE);
|
|
#ifdef _NA_000000_20120420_EQUIPMENTS_VISIBLE_WING
|
|
player->HideWing(render_info_ex.wing != 0, FALSE);
|
|
#endif//_NA_000000_20120420_EQUIPMENTS_VISIBLE_WING
|
|
#ifdef _NA_006683_20130502_EQUIPMENTS_VISIBLE_COSTUME
|
|
player->HideCostume(render_info_ex.costume);
|
|
#endif
|
|
player->SetRandomAngle();
|
|
player->SetPlayerInfo(&render_info_ex);
|
|
player->SetCurrentAttackStyle(render_info_ex.selected_style_code);
|
|
player->SetHeightVariation(2);
|
|
|
|
|
|
for( int a = 0; a < state_total_info->m_Count; ++a )
|
|
{
|
|
ETC_STATE_INFO& state_info = state_total_info->m_Slot[a];
|
|
SKILL_EFFECT* skill_effect = SKILL_EFFECT::CreateStatusEffect(state_info.m_wStateCode, state_info.m_iLeavedTime);
|
|
|
|
player->AddSkillEffect(skill_effect);
|
|
}
|
|
|
|
if (vendor_render_info != NULL)
|
|
{
|
|
// 벤드 정보
|
|
player->SetMarketTitle(vendor_render_info->m_tszVendorTitle, vendor_render_info->m_byTitleLength);
|
|
}
|
|
|
|
if (equip_item_info != NULL)
|
|
{
|
|
//이큅정보
|
|
EQUIP_ITEM_BASEINFO::data_type* item_slot = (EQUIP_ITEM_BASEINFO::data_type*)((BYTE*)(equip_item_info) + sizeof(EQUIP_ITEM_BASEINFO));
|
|
player->SetEquipItemBaseInfo(equip_item_info->m_Count, item_slot);
|
|
}
|
|
|
|
RESOURCECODE resource_code = 0;
|
|
DWORD skill_code = 0;
|
|
eTRANSFORM_TYPE transform_type = eTRANSFORM_TYPE_NONE;
|
|
if (GameFunc::IsTransform(render_info_ex, resource_code, skill_code, transform_type))
|
|
{
|
|
player->GetTransformData().SetTransFormType(transform_type);
|
|
player->GetTransformData().SetTransFormResourceCode(resource_code);
|
|
player->SetTransSkillCode(skill_code);
|
|
player->ForceTransFrom();
|
|
}
|
|
|
|
if (effect_item_info != NULL)
|
|
{
|
|
//이펙트 정보
|
|
player->RefreshRenderEffectItem(player, &(effect_item_info->m_ItemCodes[0]), effect_item_info->m_ItemCount);
|
|
}
|
|
|
|
player->RefreshAppearRender();
|
|
|
|
// 기본 에니메이션
|
|
player->SetColor(WzColor_RGBA(255,255,255,255));
|
|
player->SetFreeMove(TRUE);
|
|
player->ProcessAnimation(0);
|
|
player->SetAnimation("N002", TRUE);
|
|
|
|
return player;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
Player* GameFunc::MakePlayer(const DWORD object_key, Player* base_player, bool is_with_equip)
|
|
{
|
|
if (object_key <= 0 || base_player == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (g_ObjectManager.GetObject(object_key) != NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Player* player = (Player*)g_ObjectManager.Add(object_key, PLAYER_OBJECT, base_player->GetClassCode(), FALSE);
|
|
if (player != NULL)
|
|
{
|
|
CLIENT_CHARACTER_PART character_part;
|
|
ZeroMemory(&character_part,sizeof(character_part));
|
|
character_part.m_byClass = base_player->GetClass();
|
|
character_part.m_bySlot = 0;
|
|
character_part.m_byFace = base_player->GetPartVariation(PLAYER_VARIATION_FACE);
|
|
character_part.m_byHair = base_player->GetPartVariation(PLAYER_VARIATION_HAIR);
|
|
|
|
#ifdef _NA_000000_20120420_EQUIPMENTS_VISIBLE_WING
|
|
player->SetHideHelmet(base_player->IsHideHelmet() );
|
|
player->SetHideWing(base_player->IsHideWing() );
|
|
#endif//_NA_000000_20120420_EQUIPMENTS_VISIBLE_WING
|
|
#ifdef _NA_006683_20130502_EQUIPMENTS_VISIBLE_COSTUME
|
|
player->SetHideCostume(base_player->isHideCostume());
|
|
#endif
|
|
player->SetClientChar(character_part);
|
|
player->SetAnimation("N002", TRUE);
|
|
player->SetColor(WzColor_RGBA(255,255,255,255));
|
|
player->SetFreeMove(TRUE);
|
|
player->ProcessAnimation(0);
|
|
player->SetName(base_player->GetName());
|
|
player->SetLevel(base_player->GetLevel());
|
|
player->SetHeightVariation(2);
|
|
#ifdef _NA_004035_20120227_COSTUME_ITEM
|
|
player->SetCostumeItemCode(base_player->GetCostumeItemCode());
|
|
#endif//_NA_004035_20120227_COSTUME_ITEM
|
|
#ifdef _NA_008633_20160104_ADD_DECORATECOSTUME
|
|
player->SetDecorateCostumeItemCode(base_player->GetDecorateCostumeItemCode());
|
|
#endif // _NA_008633_20160104_ADD_DECORATECOSTUME
|
|
|
|
if (is_with_equip)
|
|
{
|
|
EQUIP_ITEM_INFO out;
|
|
base_player->GetEquipItemTotalInfoByCheckValidItem(OUT out);
|
|
player->SetEquipItemTotalInfo(out);
|
|
}
|
|
player->RefreshAppearRender();
|
|
}
|
|
|
|
return player;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
bool GameFunc::IsTransform(PLAYER_RENDER_INFO_EX& render_info_ex,
|
|
OUT RESOURCECODE& resource_code,
|
|
OUT DWORD& skill_code,
|
|
OUT eTRANSFORM_TYPE& transform_type)
|
|
{
|
|
for (int j = 0; j < render_info_ex.state_total_info.m_Count; ++j)
|
|
{
|
|
STATE_INFO& state_info = render_info_ex.state_total_info.m_Slot[j];
|
|
|
|
SkillScriptInfo* skill_script_Info = SkillInfoParser::Instance()->GetSkillInfo((SLOTCODE)state_info.m_SkillCode);
|
|
if (skill_script_Info == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
BASE_ABILITYINFO* ability_info = skill_script_Info->GetAbilityInfo(eABILITY_DRAGON_TRANSFORMATION1);
|
|
if (ability_info != NULL)
|
|
{
|
|
skill_code=state_info.m_SkillCode;
|
|
resource_code = ability_info->m_iOption1;
|
|
transform_type= static_cast<eTRANSFORM_TYPE>(ability_info->m_iOption2);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#ifdef _NA_008016_20150203_SUN_RANKING_SYSTEM_STATUE
|
|
StatuePlayer* GameFunc::MakeStatuePlayer( const WzVector& position, const WzVector& direction, const float& scale_value, StatueInfo statue_info )
|
|
{
|
|
// index 범위 : 0 ~ 11
|
|
if (statue_info.statue_index < 0 || statue_info.statue_index > 11)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
CLIENT_CHARACTER_PART client_character_part;
|
|
ZeroMemory(&client_character_part, sizeof(client_character_part));
|
|
client_character_part = statue_info.client_character_part;
|
|
|
|
StatuePlayer* statue_player = static_cast<StatuePlayer*>(g_ObjectManager.Add(STATUE_OBJECT_CHARACTER_KEY1 + statue_info.statue_index,
|
|
STATUE_PLAYER_OBJECT,
|
|
client_character_part.m_byClass,
|
|
FALSE));
|
|
|
|
statue_player->SetClass((eCHAR_TYPE)client_character_part.m_byClass);
|
|
statue_player->SetGender((GenderType::Value)client_character_part.gender);
|
|
statue_player->RefreshApperBronzePlayer();
|
|
|
|
// 외형세팅
|
|
statue_player->SetPartVariation(PLAYER_VARIATION_HAIR, client_character_part.m_byHair);
|
|
statue_player->SetPartVariation(PLAYER_VARIATION_FACE, client_character_part.m_byFace);
|
|
|
|
statue_player->SetClientChar(client_character_part);
|
|
statue_player->HideHelmet(false, FALSE);
|
|
statue_player->SetShow(TRUE);
|
|
statue_player->SetHideWing(TRUE);
|
|
|
|
EquipmentContainer* equipment_container = statue_player->GetEquipmentContainer();
|
|
EquipmentContainer* statue_equip_container = statue_player->get_statue_equip_container_();
|
|
|
|
SCItemSlot* item_slot;
|
|
SCItemSlot copy_slot;
|
|
for ( int i = EquipmentContainer::EQUIP_WEAPON1; i <= EquipmentContainer::EQUIP_SHIRTS; ++i )
|
|
{
|
|
item_slot = equipment_container->GetItemSlot(i);
|
|
if ( item_slot )
|
|
{
|
|
copy_slot.Copy(*item_slot);
|
|
copy_slot.SetEnchant(0);
|
|
statue_equip_container->JustInsertSlot(i, copy_slot);
|
|
}
|
|
}
|
|
|
|
statue_player->set_equip_container_(statue_player->get_statue_equip_container_());
|
|
statue_player->RefreshAppearRender();
|
|
|
|
statue_player->SetScale(scale_value);
|
|
statue_player->SetVisiblePos(position.x, position.y, position.z);
|
|
statue_player->SetPosition(position);
|
|
statue_player->SetDirection(direction);
|
|
|
|
statue_player->SetName(client_character_part.m_tszCharName);
|
|
statue_player->SetShowName(TRUE);
|
|
|
|
StatueGuildInfo statue_guild_info;
|
|
ZeroMemory(&statue_guild_info, sizeof(statue_guild_info));
|
|
StrNCpy(statue_guild_info.guild_name, statue_info.guild_name, MAX_GUILDNAME_LENGTH-1);
|
|
statue_guild_info.guild_mark_pattern_idx = statue_info.pattern_mark_index;
|
|
statue_guild_info.guild_mark_background_idx = statue_info.background_mark_index;
|
|
statue_player->set_statue_guild_info(statue_guild_info);
|
|
|
|
// 기본자세
|
|
WzID animationID = 0;
|
|
|
|
char animation_code[5];
|
|
// 무기에따라서 기본자세가 바뀝니다.
|
|
|
|
ZeroMemory(animation_code,sizeof(animation_code));
|
|
|
|
animation_code[0] = 'N';
|
|
animation_code[1] = '0';
|
|
animation_code[2] = '3';
|
|
animation_code[3] = '0';
|
|
animation_code[1] = statue_player->GetWeaponAnimationCode();
|
|
|
|
statue_player->set_stand_animation_id_(animation_code);
|
|
|
|
statue_player->SetItemScore((DWORD)statue_info.total_equip_score);
|
|
|
|
PLAYER_ACTION action;
|
|
ZeroMemory(&action, sizeof(action));
|
|
action.ActionID = ACTION_STATUE_STAND;
|
|
statue_player->DoAction(&action);
|
|
|
|
return statue_player;
|
|
}
|
|
#endif // _NA_008016_20150203_SUN_RANKING_SYSTEM_STATUE
|
|
|
|
int GameFunc::GetDayOfTheWeek(int year, int month, int day)
|
|
{
|
|
// return -> 0:일요일 1:월요일, 2:화요일, .. , 6:토요일, -1:날짜x
|
|
if (!(year > 0 && month > 0 && month < 13 && day > 0))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int last_day = GetLastDayOfTheMonth(year, month);
|
|
|
|
if (last_day < 0 || day > last_day)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
// 요일 구하기 (제라의공식)
|
|
if (month < 3)
|
|
{
|
|
--year;
|
|
month += 12;
|
|
}
|
|
|
|
return (21*(year/100)/4 + 5*(year%100)/4 + 26*(month+1)/10 + day - 1) % 7;
|
|
}
|
|
|
|
int GameFunc::GetLastDayOfTheMonth(int year, int month)
|
|
{
|
|
if (month > 12)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
|
|
|
// 윤달 계산
|
|
if (month == 2 && (!(year%4) && (year%100) || !(year%400)))
|
|
{
|
|
return 29;
|
|
}
|
|
|
|
return days[month-1];
|
|
|
|
} |