Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead)
- {
- if (IsDead())
- return;
- {
- if (IsHorseRiding())
- {
- StopRiding();
- }
- else if (GetMountVnum())
- {
- RemoveAffect(AFFECT_MOUNT_BONUS);
- LPITEM item = GetWear(WEAR_UNIQUE1);
- LPITEM item2 = GetWear(WEAR_UNIQUE2);
- LPITEM item3 = GetWear(WEAR_COSTUME_MOUNT);
- if (item && item->IsRideItem())
- UnequipItem(item);
- if (item2 && item2->IsRideItem())
- UnequipItem(item2);
- if (item3 && item3->IsRideItem())
- UnequipItem(item3);
- m_dwMountVnum = 0;
- UnEquipSpecialRideUniqueItem();
- UpdatePacket();
- }
- }
- if (!pkKiller && m_dwKillerPID)
- pkKiller = CHARACTER_MANAGER::instance().FindByPID(m_dwKillerPID);
- m_dwKillerPID = 0; // 반드시 초기화 해야함 DO NOT DELETE THIS LINE UNLESS YOU ARE 1000000% SURE
- bool isAgreedPVP = false;
- bool isUnderGuildWar = false;
- bool isDuel = false;
- bool isForked = false;
- if (pkKiller && pkKiller->IsPC())
- {
- if (pkKiller->m_pkChrTarget == this)
- pkKiller->SetTarget(NULL);
- if (!IsPC() && pkKiller->GetDungeon())
- pkKiller->GetDungeon()->IncKillCount(pkKiller, this);
- isAgreedPVP = CPVPManager::instance().Dead(this, pkKiller->GetPlayerID());
- isDuel = CArenaManager::instance().OnDead(pkKiller, this);
- #ifdef ENABLE_PVP_ADVANCED
- if (isAgreedPVP || isDuel)
- {
- const char* szTableStaticPvP[] = {BLOCK_CHANGEITEM, BLOCK_BUFF, BLOCK_POTION, BLOCK_RIDE, BLOCK_PET, BLOCK_POLY, BLOCK_PARTY, BLOCK_EXCHANGE_, CHECK_IS_FIGHT};
- for (int i = 0; i < _countof(szTableStaticPvP); i++) {
- char pkCh_Buf[CHAT_MAX_LEN + 1], pkKiller_Buf[CHAT_MAX_LEN + 1];
- snprintf(pkCh_Buf, sizeof(pkCh_Buf), "BINARY_Duel_Delete");
- snprintf(pkKiller_Buf, sizeof(pkKiller_Buf), "BINARY_Duel_Delete");
- ChatPacket(CHAT_TYPE_COMMAND, pkCh_Buf);
- SetQuestFlag(szTableStaticPvP[i], 0);
- pkKiller->ChatPacket(CHAT_TYPE_COMMAND, pkKiller_Buf);
- pkKiller->SetQuestFlag(szTableStaticPvP[i], 0);
- }
- }
- #endif
- #ifdef __NEW_SKILLTREE__
- if (pkKiller->IsPC() && (IsMonster() || IsStone()))
- {
- if (GetRaceNum() == SKILLTREE_MONSTER_RACE)
- {
- pkKiller->SetMobKills(pkKiller->GetMobKills() + 1);
- if (pkKiller->GetMobKills() == SKILLTREE_MONSTER_KILL_TO_ONE_POINT)
- {
- pkKiller->PointChange(POINT_SKILL_TREE, 1);
- pkKiller->ChatPacket(CHAT_TYPE_COMMAND, "RefreshSkillTree ");
- pkKiller->SetMobKills(0);
- }
- }
- }
- #endif
- if (IsPC())
- {
- CGuild * g1 = GetGuild();
- CGuild * g2 = pkKiller->GetGuild();
- if (g1 && g2)
- if (g1->UnderWar(g2->GetID()))
- isUnderGuildWar = true;
- pkKiller->SetQuestNPCID(GetVID());
- quest::CQuestManager::instance().Kill(pkKiller->GetPlayerID(), quest::QUEST_NO_NPC, GetPlayerID());;
- CGuildManager::instance().Kill(pkKiller, this);
- }
- }
- //CHECK_FORKEDROAD_WAR
- if (IsPC())
- {
- if (CThreeWayWar::instance().IsThreeWayWarMapIndex(GetMapIndex()))
- isForked = true;
- }
- //END_CHECK_FORKEDROAD_WAR
- if (pkKiller &&
- !isAgreedPVP &&
- !isUnderGuildWar &&
- IsPC() &&
- !isDuel &&
- !isForked &&
- !IS_CASTLE_MAP(GetMapIndex()))
- {
- if (GetGMLevel() == GM_PLAYER || test_server)
- {
- //ItemDropPenalty(pkKiller);
- }
- }
- // CASTLE_SIEGE
- if (IS_CASTLE_MAP(GetMapIndex()))
- {
- if (CASTLE_FROG_VNUM == GetRaceNum())
- castle_frog_die(this, pkKiller);
- else if (castle_is_guard_vnum(GetRaceNum()))
- castle_guard_die(this, pkKiller);
- else if (castle_is_tower_vnum(GetRaceNum()))
- castle_tower_die(this, pkKiller);
- }
- // CASTLE_SIEGE
- if (true == isForked)
- {
- CThreeWayWar::instance().onDead( this, pkKiller );
- }
- SetPosition(POS_DEAD);
- ClearAffect(true);
- if (pkKiller && IsPC())
- {
- if (!pkKiller->IsPC())
- {
- if (!isForked)
- {
- sys_log(1, "DEAD: %s %p WITH PENALTY", GetName(), this);
- SET_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_DEATH_PENALTY);
- LogManager::instance().CharLog(this, pkKiller->GetRaceNum(), "DEAD_BY_NPC", pkKiller->GetName());
- }
- }
- else
- {
- sys_log(1, "DEAD_BY_PC: %s %p KILLER %s %p", GetName(), this, pkKiller->GetName(), get_pointer(pkKiller));
- REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_DEATH_PENALTY);
- if (GetEmpire() != pkKiller->GetEmpire())
- {
- int iEP = MIN(GetPoint(POINT_EMPIRE_POINT), pkKiller->GetPoint(POINT_EMPIRE_POINT));
- PointChange(POINT_EMPIRE_POINT, -(iEP / 10));
- pkKiller->PointChange(POINT_EMPIRE_POINT, iEP / 5);
- if (GetPoint(POINT_EMPIRE_POINT) < 10)
- {
- // TODO : 입구로 날리는 코드를 넣어야 한다.
- }
- char buf[256];
- snprintf(buf, sizeof(buf),
- "%d %d %d %s %d %d %d %s",
- GetEmpire(), GetAlignment(), GetPKMode(), GetName(),
- pkKiller->GetEmpire(), pkKiller->GetAlignment(), pkKiller->GetPKMode(), pkKiller->GetName());
- LogManager::instance().CharLog(this, pkKiller->GetPlayerID(), "DEAD_BY_PC", buf);
- }
- else
- {
- if (!isAgreedPVP && !isUnderGuildWar && !IsKillerMode() && GetAlignment() >= 0 && !isDuel && !isForked)
- {
- int iNoPenaltyProb = 0;
- if (g_iUseLocale)
- {
- if (pkKiller->GetAlignment() >= 0) // 1/3 percent down
- iNoPenaltyProb = 33;
- else // 4/5 percent down
- iNoPenaltyProb = 20;
- }
- if (number(1, 100) < iNoPenaltyProb)
- pkKiller->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("용신의 보호로 아이템이 떨어지지 않았습니다."));
- else
- {
- if (g_iUseLocale && pkKiller->GetParty())
- {
- FPartyAlignmentCompute f(0, pkKiller->GetX(), pkKiller->GetY());
- pkKiller->GetParty()->ForEachOnlineMember(f);
- if (f.m_iCount == 0)
- pkKiller->UpdateAlignment(0);
- else
- {
- sys_log(0, "ALIGNMENT PARTY count %d amount %d", f.m_iCount, f.m_iAmount);
- f.m_iStep = 1;
- pkKiller->GetParty()->ForEachOnlineMember(f);
- }
- }
- else
- pkKiller->UpdateAlignment(0);
- }
- }
- char buf[256];
- snprintf(buf, sizeof(buf),
- "%d %d %d %s %d %d %d %s",
- GetEmpire(), GetAlignment(), GetPKMode(), GetName(),
- pkKiller->GetEmpire(), pkKiller->GetAlignment(), pkKiller->GetPKMode(), pkKiller->GetName());
- LogManager::instance().CharLog(this, pkKiller->GetPlayerID(), "DEAD_BY_PC", buf);
- }
- }
- }
- else
- {
- sys_log(1, "DEAD: %s %p", GetName(), this);
- REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_DEATH_PENALTY);
- }
- ClearSync();
- //sys_log(1, "stun cancel %s[%d]", GetName(), (DWORD)GetVID());
- event_cancel(&m_pkStunEvent); // 기절 이벤트는 죽인다.
- if (IsPC())
- {
- m_dwLastDeadTime = get_dword_time();
- SetKillerMode(false);
- GetDesc()->SetPhase(PHASE_DEAD);
- }
- else
- {
- // 가드에게 공격받은 몬스터는 보상이 없어야 한다.
- if (!IS_SET(m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD))
- {
- if (!(pkKiller && pkKiller->IsPC() && pkKiller->GetGuild() && pkKiller->GetGuild()->UnderAnyWar(GUILD_WAR_TYPE_FIELD)))
- {
- // 부활하는 몬스터는 보상을 주지 않는다.
- if (GetMobTable().dwResurrectionVnum)
- {
- // DUNGEON_MONSTER_REBIRTH_BUG_FIX
- LPCHARACTER chResurrect = CHARACTER_MANAGER::instance().SpawnMob(GetMobTable().dwResurrectionVnum, GetMapIndex(), GetX(), GetY(), GetZ(), true, (int) GetRotation());
- if (GetDungeon() && chResurrect)
- {
- chResurrect->SetDungeon(GetDungeon());
- }
- // END_OF_DUNGEON_MONSTER_REBIRTH_BUG_FIX
- Reward(false);
- }
- else if (IsRevive() == true)
- {
- Reward(false);
- }
- else
- {
- Reward(true); // Drops gold, item, etc..
- }
- }
- else
- {
- if (pkKiller->m_dwUnderGuildWarInfoMessageTime < get_dword_time())
- {
- pkKiller->m_dwUnderGuildWarInfoMessageTime = get_dword_time() + 60000;
- pkKiller->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드전중에는 사냥에 따른 이익이 없습니다."));
- }
- }
- }
- }
- // BOSS_KILL_LOG
- if (GetMobRank() >= MOB_RANK_BOSS && pkKiller && pkKiller->IsPC())
- {
- char buf[51];
- snprintf(buf, sizeof(buf), "%d %ld", g_bChannel, pkKiller->GetMapIndex());
- if (IsStone())
- LogManager::instance().CharLog(pkKiller, GetRaceNum(), "STONE_KILL", buf);
- else
- LogManager::instance().CharLog(pkKiller, GetRaceNum(), "BOSS_KILL", buf);
- }
- // END_OF_BOSS_KILL_LOG
- TPacketGCDead pack;
- pack.header = HEADER_GC_DEAD;
- pack.vid = m_vid;
- PacketAround(&pack, sizeof(pack));
- REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);
- // 플레이어 캐릭터이면
- if (GetDesc() != NULL) {
- //
- // 클라이언트에 에펙트 패킷을 다시 보낸다.
- //
- itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
- while (it != m_list_pkAffect.end())
- SendAffectAddPacket(GetDesc(), *it++);
- }
- //
- // Dead 이벤트 생성,
- //
- // Dead 이벤트에서는 몬스터의 경우 몇초 후에 Destroy 되도록 해주며,
- // PC의 경우 3분 있다가 마을에서 나오도록 해 준다. 3분 내에는 유저로부터
- // 마을에서 시작할 건지, 여기서 시작할 건지 결정을 받는다.
- if (isDuel == false)
- {
- if (m_pkDeadEvent)
- {
- sys_log(1, "DEAD_EVENT_CANCEL: %s %p %p", GetName(), this, get_pointer(m_pkDeadEvent));
- event_cancel(&m_pkDeadEvent);
- }
- if (IsStone())
- ClearStone();
- if (GetDungeon())
- {
- GetDungeon()->DeadCharacter(this);
- }
- SCharDeadEventInfo* pEventInfo = AllocEventInfo<SCharDeadEventInfo>();
- if (IsPC())
- {
- pEventInfo->isPC = true;
- pEventInfo->dwID = this->GetPlayerID();
- m_pkDeadEvent = event_create(dead_event, pEventInfo, PASSES_PER_SEC(180));
- }
- else
- {
- pEventInfo->isPC = false;
- pEventInfo->dwID = this->GetVID();
- if (IsRevive() == false && HasReviverInParty() == true)
- {
- m_pkDeadEvent = event_create(dead_event, pEventInfo, bImmediateDead ? 1 : PASSES_PER_SEC(3));
- }
- else
- {
- m_pkDeadEvent = event_create(dead_event, pEventInfo, bImmediateDead ? 1 : PASSES_PER_SEC(5));
- }
- }
- sys_log(1, "DEAD_EVENT_CREATE: %s %p %p", GetName(), this, get_pointer(m_pkDeadEvent));
- }
- if (m_pkExchange != NULL)
- {
- m_pkExchange->Cancel();
- }
- if (IsCubeOpen() == true)
- {
- Cube_close(this);
- }
- #ifdef __SASH_SYSTEM__
- if (IsPC())
- CloseSash();
- #endif
- CShopManager::instance().StopShopping(this);
- CloseMyShop();
- CloseSafebox();
- if (true == IsMonster() && 2493 == GetMobTable().dwVnum)
- {
- if (NULL != pkKiller && NULL != pkKiller->GetGuild())
- {
- CDragonLairManager::instance().OnDragonDead( this, pkKiller->GetGuild()->GetID() );
- }
- else
- {
- sys_err("DragonLair: Dragon killed by nobody");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement