Files
git 9cb257e7ae Add GameClients drops and keep current 1602 source work.
CN1602 is the local client. KR is the official tree with unpacked Data, System, and Sound. Packed .wpk files stay off git.
2026-08-30 23:24:31 +03:00

5539 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;
// Ranking packets can arrive empty or misaligned; never summon a pet
// or walk a huge EQUIP_ITEM_INFO.m_Count on a bronze statue.
client_character_part.m_bSummoned = FALSE;
if (client_character_part.m_EquipItemInfo.m_Count > MAX_EQUIPMENT_SLOT_NUM)
{
client_character_part.m_EquipItemInfo.m_Count = MAX_EQUIPMENT_SLOT_NUM;
}
client_character_part.m_tszCharName[MAX_CHARNAME_LENGTH] = 0;
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));
if (statue_player == NULL)
{
return NULL;
}
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];
}