Advertisement
Guest User

Untitled

a guest
Jul 20th, 2019
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.67 KB | None | 0 0
  1. void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead)
  2. {
  3.     if (IsDead())
  4.         return;
  5.  
  6.     {
  7.         if (IsHorseRiding())
  8.         {
  9.             StopRiding();
  10.         }
  11.         else if (GetMountVnum())
  12.         {
  13.             RemoveAffect(AFFECT_MOUNT_BONUS);
  14.             LPITEM item = GetWear(WEAR_UNIQUE1);
  15.             LPITEM item2 = GetWear(WEAR_UNIQUE2);
  16.             LPITEM item3 = GetWear(WEAR_COSTUME_MOUNT);
  17.  
  18.             if (item && item->IsRideItem())
  19.                 UnequipItem(item);
  20.  
  21.             if (item2 && item2->IsRideItem())
  22.                 UnequipItem(item2);
  23.  
  24.             if (item3 && item3->IsRideItem())
  25.                 UnequipItem(item3);
  26.  
  27.             m_dwMountVnum = 0;
  28.             UnEquipSpecialRideUniqueItem();
  29.  
  30.             UpdatePacket();
  31.         }
  32.     }
  33.  
  34.     if (!pkKiller && m_dwKillerPID)
  35.         pkKiller = CHARACTER_MANAGER::instance().FindByPID(m_dwKillerPID);
  36.  
  37.     m_dwKillerPID = 0; // 반드시 초기화 해야함 DO NOT DELETE THIS LINE UNLESS YOU ARE 1000000% SURE
  38.  
  39.     bool isAgreedPVP = false;
  40.     bool isUnderGuildWar = false;
  41.     bool isDuel = false;
  42.     bool isForked = false;
  43.  
  44.     if (pkKiller && pkKiller->IsPC())
  45.     {
  46.         if (pkKiller->m_pkChrTarget == this)
  47.             pkKiller->SetTarget(NULL);
  48.  
  49.         if (!IsPC() && pkKiller->GetDungeon())
  50.             pkKiller->GetDungeon()->IncKillCount(pkKiller, this);
  51.  
  52.         isAgreedPVP = CPVPManager::instance().Dead(this, pkKiller->GetPlayerID());
  53.         isDuel = CArenaManager::instance().OnDead(pkKiller, this);
  54.        
  55.         #ifdef ENABLE_PVP_ADVANCED
  56.         if (isAgreedPVP || isDuel)
  57.         {  
  58.             const char* szTableStaticPvP[] = {BLOCK_CHANGEITEM, BLOCK_BUFF, BLOCK_POTION, BLOCK_RIDE, BLOCK_PET, BLOCK_POLY, BLOCK_PARTY, BLOCK_EXCHANGE_, CHECK_IS_FIGHT};
  59.            
  60.             for (int i = 0; i < _countof(szTableStaticPvP); i++) { 
  61.                 char pkCh_Buf[CHAT_MAX_LEN + 1], pkKiller_Buf[CHAT_MAX_LEN + 1];
  62.                
  63.                 snprintf(pkCh_Buf, sizeof(pkCh_Buf), "BINARY_Duel_Delete");
  64.                 snprintf(pkKiller_Buf, sizeof(pkKiller_Buf), "BINARY_Duel_Delete");
  65.                
  66.                 ChatPacket(CHAT_TYPE_COMMAND, pkCh_Buf);   
  67.                 SetQuestFlag(szTableStaticPvP[i], 0);
  68.                
  69.                 pkKiller->ChatPacket(CHAT_TYPE_COMMAND, pkKiller_Buf); 
  70.                 pkKiller->SetQuestFlag(szTableStaticPvP[i], 0);
  71.             }
  72.         }
  73.         #endif
  74.         #ifdef __NEW_SKILLTREE__
  75.         if (pkKiller->IsPC() && (IsMonster() || IsStone()))
  76.         {
  77.             if (GetRaceNum() == SKILLTREE_MONSTER_RACE)
  78.             {
  79.                 pkKiller->SetMobKills(pkKiller->GetMobKills() + 1);
  80.                 if (pkKiller->GetMobKills() == SKILLTREE_MONSTER_KILL_TO_ONE_POINT)
  81.                 {
  82.                     pkKiller->PointChange(POINT_SKILL_TREE, 1);
  83.                     pkKiller->ChatPacket(CHAT_TYPE_COMMAND, "RefreshSkillTree ");
  84.                     pkKiller->SetMobKills(0);
  85.                 }
  86.             }
  87.         }
  88.         #endif
  89.  
  90.         if (IsPC())
  91.         {
  92.             CGuild * g1 = GetGuild();
  93.             CGuild * g2 = pkKiller->GetGuild();
  94.  
  95.             if (g1 && g2)
  96.                 if (g1->UnderWar(g2->GetID()))
  97.                     isUnderGuildWar = true;
  98.  
  99.             pkKiller->SetQuestNPCID(GetVID());
  100.             quest::CQuestManager::instance().Kill(pkKiller->GetPlayerID(), quest::QUEST_NO_NPC, GetPlayerID());;
  101.             CGuildManager::instance().Kill(pkKiller, this);
  102.         }
  103.     }
  104.  
  105.     //CHECK_FORKEDROAD_WAR
  106.     if (IsPC())
  107.     {
  108.         if (CThreeWayWar::instance().IsThreeWayWarMapIndex(GetMapIndex()))
  109.             isForked = true;
  110.     }
  111.     //END_CHECK_FORKEDROAD_WAR
  112.  
  113.     if (pkKiller &&
  114.             !isAgreedPVP &&
  115.             !isUnderGuildWar &&
  116.             IsPC() &&
  117.             !isDuel &&
  118.             !isForked &&
  119.             !IS_CASTLE_MAP(GetMapIndex()))
  120.     {
  121.         if (GetGMLevel() == GM_PLAYER || test_server)
  122.         {
  123.             //ItemDropPenalty(pkKiller);
  124.         }
  125.     }
  126.  
  127.     // CASTLE_SIEGE
  128.     if (IS_CASTLE_MAP(GetMapIndex()))
  129.     {
  130.         if (CASTLE_FROG_VNUM == GetRaceNum())
  131.             castle_frog_die(this, pkKiller);
  132.         else if (castle_is_guard_vnum(GetRaceNum()))
  133.             castle_guard_die(this, pkKiller);
  134.         else if (castle_is_tower_vnum(GetRaceNum()))
  135.             castle_tower_die(this, pkKiller);
  136.     }
  137.     // CASTLE_SIEGE
  138.  
  139.     if (true == isForked)
  140.     {
  141.         CThreeWayWar::instance().onDead( this, pkKiller );
  142.     }
  143.  
  144.     SetPosition(POS_DEAD);
  145.     ClearAffect(true);
  146.  
  147.     if (pkKiller && IsPC())
  148.     {
  149.         if (!pkKiller->IsPC())
  150.         {
  151.             if (!isForked)
  152.             {
  153.                 sys_log(1, "DEAD: %s %p WITH PENALTY", GetName(), this);
  154.                 SET_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_DEATH_PENALTY);
  155.                 LogManager::instance().CharLog(this, pkKiller->GetRaceNum(), "DEAD_BY_NPC", pkKiller->GetName());
  156.             }
  157.         }
  158.         else
  159.         {
  160.             sys_log(1, "DEAD_BY_PC: %s %p KILLER %s %p", GetName(), this, pkKiller->GetName(), get_pointer(pkKiller));
  161.             REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_DEATH_PENALTY);
  162.  
  163.             if (GetEmpire() != pkKiller->GetEmpire())
  164.             {
  165.                 int iEP = MIN(GetPoint(POINT_EMPIRE_POINT), pkKiller->GetPoint(POINT_EMPIRE_POINT));
  166.  
  167.                 PointChange(POINT_EMPIRE_POINT, -(iEP / 10));
  168.                 pkKiller->PointChange(POINT_EMPIRE_POINT, iEP / 5);
  169.  
  170.                 if (GetPoint(POINT_EMPIRE_POINT) < 10)
  171.                 {
  172.                     // TODO : 입구로 날리는 코드를 넣어야 한다.
  173.                 }
  174.  
  175.                 char buf[256];
  176.                 snprintf(buf, sizeof(buf),
  177.                         "%d %d %d %s %d %d %d %s",
  178.                         GetEmpire(), GetAlignment(), GetPKMode(), GetName(),
  179.                         pkKiller->GetEmpire(), pkKiller->GetAlignment(), pkKiller->GetPKMode(), pkKiller->GetName());
  180.  
  181.                 LogManager::instance().CharLog(this, pkKiller->GetPlayerID(), "DEAD_BY_PC", buf);
  182.             }
  183.             else
  184.             {
  185.                 if (!isAgreedPVP && !isUnderGuildWar && !IsKillerMode() && GetAlignment() >= 0 && !isDuel && !isForked)
  186.                 {
  187.                     int iNoPenaltyProb = 0;
  188.  
  189.                     if (g_iUseLocale)
  190.                     {
  191.                         if (pkKiller->GetAlignment() >= 0)  // 1/3 percent down
  192.                             iNoPenaltyProb = 33;
  193.                         else                // 4/5 percent down
  194.                             iNoPenaltyProb = 20;
  195.                     }
  196.  
  197.                     if (number(1, 100) < iNoPenaltyProb)
  198.                         pkKiller->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("용신의 보호로 아이템이 떨어지지 않았습니다."));
  199.                     else
  200.                     {
  201.                         if (g_iUseLocale && pkKiller->GetParty())
  202.                         {
  203.                             FPartyAlignmentCompute f(0, pkKiller->GetX(), pkKiller->GetY());
  204.                             pkKiller->GetParty()->ForEachOnlineMember(f);
  205.  
  206.                             if (f.m_iCount == 0)
  207.                                 pkKiller->UpdateAlignment(0);
  208.                             else
  209.                             {
  210.                                 sys_log(0, "ALIGNMENT PARTY count %d amount %d", f.m_iCount, f.m_iAmount);
  211.  
  212.                                 f.m_iStep = 1;
  213.                                 pkKiller->GetParty()->ForEachOnlineMember(f);
  214.                             }
  215.                         }
  216.                         else
  217.                             pkKiller->UpdateAlignment(0);
  218.                     }
  219.                 }
  220.  
  221.                 char buf[256];
  222.                 snprintf(buf, sizeof(buf),
  223.                         "%d %d %d %s %d %d %d %s",
  224.                         GetEmpire(), GetAlignment(), GetPKMode(), GetName(),
  225.                         pkKiller->GetEmpire(), pkKiller->GetAlignment(), pkKiller->GetPKMode(), pkKiller->GetName());
  226.  
  227.                 LogManager::instance().CharLog(this, pkKiller->GetPlayerID(), "DEAD_BY_PC", buf);
  228.             }
  229.         }
  230.     }
  231.     else
  232.     {
  233.         sys_log(1, "DEAD: %s %p", GetName(), this);
  234.         REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_DEATH_PENALTY);
  235.     }
  236.  
  237.     ClearSync();
  238.  
  239.     //sys_log(1, "stun cancel %s[%d]", GetName(), (DWORD)GetVID());
  240.     event_cancel(&m_pkStunEvent); // 기절 이벤트는 죽인다.
  241.  
  242.     if (IsPC())
  243.     {
  244.         m_dwLastDeadTime = get_dword_time();
  245.         SetKillerMode(false);
  246.         GetDesc()->SetPhase(PHASE_DEAD);
  247.     }
  248.     else
  249.     {
  250.         // 가드에게 공격받은 몬스터는 보상이 없어야 한다.
  251.         if (!IS_SET(m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD))
  252.         {
  253.             if (!(pkKiller && pkKiller->IsPC() && pkKiller->GetGuild() && pkKiller->GetGuild()->UnderAnyWar(GUILD_WAR_TYPE_FIELD)))
  254.             {
  255.                 // 부활하는 몬스터는 보상을 주지 않는다.
  256.                 if (GetMobTable().dwResurrectionVnum)
  257.                 {
  258.                     // DUNGEON_MONSTER_REBIRTH_BUG_FIX
  259.                     LPCHARACTER chResurrect = CHARACTER_MANAGER::instance().SpawnMob(GetMobTable().dwResurrectionVnum, GetMapIndex(), GetX(), GetY(), GetZ(), true, (int) GetRotation());
  260.                     if (GetDungeon() && chResurrect)
  261.                     {
  262.                         chResurrect->SetDungeon(GetDungeon());
  263.                     }
  264.                     // END_OF_DUNGEON_MONSTER_REBIRTH_BUG_FIX
  265.  
  266.                     Reward(false);
  267.                 }
  268.                 else if (IsRevive() == true)
  269.                 {
  270.                     Reward(false);
  271.                 }
  272.                 else
  273.                 {
  274.                     Reward(true); // Drops gold, item, etc..
  275.                 }
  276.             }
  277.             else
  278.             {
  279.                 if (pkKiller->m_dwUnderGuildWarInfoMessageTime < get_dword_time())
  280.                 {
  281.                     pkKiller->m_dwUnderGuildWarInfoMessageTime = get_dword_time() + 60000;
  282.                     pkKiller->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드전중에는 사냥에 따른 이익이 없습니다."));
  283.                 }
  284.             }
  285.         }
  286.     }
  287.  
  288.     // BOSS_KILL_LOG
  289.     if (GetMobRank() >= MOB_RANK_BOSS && pkKiller && pkKiller->IsPC())
  290.     {
  291.         char buf[51];
  292.         snprintf(buf, sizeof(buf), "%d %ld", g_bChannel, pkKiller->GetMapIndex());
  293.         if (IsStone())
  294.             LogManager::instance().CharLog(pkKiller, GetRaceNum(), "STONE_KILL", buf);
  295.         else
  296.             LogManager::instance().CharLog(pkKiller, GetRaceNum(), "BOSS_KILL", buf);
  297.     }
  298.     // END_OF_BOSS_KILL_LOG
  299.  
  300.     TPacketGCDead pack;
  301.     pack.header = HEADER_GC_DEAD;
  302.     pack.vid    = m_vid;
  303.     PacketAround(&pack, sizeof(pack));
  304.  
  305.     REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);
  306.  
  307.     // 플레이어 캐릭터이면
  308.     if (GetDesc() != NULL) {
  309.         //
  310.         // 클라이언트에 에펙트 패킷을 다시 보낸다.
  311.         //
  312.         itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
  313.  
  314.         while (it != m_list_pkAffect.end())
  315.             SendAffectAddPacket(GetDesc(), *it++);
  316.     }
  317.  
  318.     //
  319.     // Dead 이벤트 생성,
  320.     //
  321.     // Dead 이벤트에서는 몬스터의 경우 몇초 후에 Destroy 되도록 해주며,
  322.     // PC의 경우 3분 있다가 마을에서 나오도록 해 준다. 3분 내에는 유저로부터
  323.     // 마을에서 시작할 건지, 여기서 시작할 건지 결정을 받는다.
  324.     if (isDuel == false)
  325.     {
  326.         if (m_pkDeadEvent)
  327.         {
  328.             sys_log(1, "DEAD_EVENT_CANCEL: %s %p %p", GetName(), this, get_pointer(m_pkDeadEvent));
  329.             event_cancel(&m_pkDeadEvent);
  330.         }
  331.  
  332.         if (IsStone())
  333.             ClearStone();
  334.  
  335.         if (GetDungeon())
  336.         {
  337.             GetDungeon()->DeadCharacter(this);
  338.         }
  339.  
  340.         SCharDeadEventInfo* pEventInfo = AllocEventInfo<SCharDeadEventInfo>();
  341.  
  342.         if (IsPC())
  343.         {
  344.             pEventInfo->isPC = true;
  345.             pEventInfo->dwID = this->GetPlayerID();
  346.  
  347.             m_pkDeadEvent = event_create(dead_event, pEventInfo, PASSES_PER_SEC(180));
  348.         }
  349.         else
  350.         {
  351.             pEventInfo->isPC = false;
  352.             pEventInfo->dwID = this->GetVID();
  353.  
  354.             if (IsRevive() == false && HasReviverInParty() == true)
  355.             {
  356.                 m_pkDeadEvent = event_create(dead_event, pEventInfo, bImmediateDead ? 1 : PASSES_PER_SEC(3));
  357.             }
  358.             else
  359.             {
  360.                 m_pkDeadEvent = event_create(dead_event, pEventInfo, bImmediateDead ? 1 : PASSES_PER_SEC(5));
  361.             }
  362.         }
  363.  
  364.         sys_log(1, "DEAD_EVENT_CREATE: %s %p %p", GetName(), this, get_pointer(m_pkDeadEvent));
  365.     }
  366.  
  367.     if (m_pkExchange != NULL)
  368.     {
  369.         m_pkExchange->Cancel();
  370.     }
  371.  
  372.     if (IsCubeOpen() == true)
  373.     {
  374.         Cube_close(this);
  375.     }
  376.    
  377.     #ifdef __SASH_SYSTEM__
  378.     if (IsPC())
  379.         CloseSash();
  380.     #endif
  381.    
  382.     CShopManager::instance().StopShopping(this);
  383.     CloseMyShop();
  384.     CloseSafebox();
  385.  
  386.     if (true == IsMonster() && 2493 == GetMobTable().dwVnum)
  387.     {
  388.         if (NULL != pkKiller && NULL != pkKiller->GetGuild())
  389.         {
  390.             CDragonLairManager::instance().OnDragonDead( this, pkKiller->GetGuild()->GetID() );
  391.         }
  392.         else
  393.         {
  394.             sys_err("DragonLair: Dragon killed by nobody");
  395.         }
  396.     }
  397. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement