Jump to content

Koran

Member
  • Posts

    3
  • Joined

  • Last visited

  • Feedback

    0%

Posts posted by Koran

  1. 5 hours ago, iMerv3 said:

    Hi, upload char_battle.cpp (or whole Damage func). Nvm is old 🙂

    Sure, see my CHARACTER::Damage:

    Spoiler
    bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // returns true if dead
    {
    #ifdef ENABLE_AFK_MODE_SYSTEM
    	if (pAttacker && pAttacker->IsPC() && pAttacker->IsAway())
    	{
    		if(IsPC())
    			return false;
    	}
    #endif
    	if (DAMAGE_TYPE_MAGIC == type)
    	{
    		dam = (int)((float)dam * (100 + (pAttacker->GetPoint(POINT_MAGIC_ATT_BONUS_PER) + pAttacker->GetPoint(POINT_MELEE_MAGIC_ATT_BONUS_PER))) / 100.f + 0.5f);
    	}
    	if (GetRaceNum() == 5001)
    	{
    		bool bDropMoney = false;
    		int iPercent = (GetHP() * 100) / GetMaxHP();
    
    		if (iPercent <= 10 && GetMaxSP() < 5)
    		{
    			SetMaxSP(5);
    			bDropMoney = true;
    		}
    		else if (iPercent <= 20 && GetMaxSP() < 4)
    		{
    			SetMaxSP(4);
    			bDropMoney = true;
    		}
    		else if (iPercent <= 40 && GetMaxSP() < 3)
    		{
    			SetMaxSP(3);
    			bDropMoney = true;
    		}
    		else if (iPercent <= 60 && GetMaxSP() < 2)
    		{
    			SetMaxSP(2);
    			bDropMoney = true;
    		}
    		else if (iPercent <= 80 && GetMaxSP() < 1)
    		{
    			SetMaxSP(1);
    			bDropMoney = true;
    		}
    
    		if (bDropMoney)
    		{
    			DWORD dwGold = 1000;
    			int iSplitCount = number(10, 13);
    
    			sys_log(0, "WAEGU DropGoldOnHit %d times", GetMaxSP());
    
    			for (int i = 1; i <= iSplitCount; ++i)
    			{
    				PIXEL_POSITION pos;
    				LPITEM item;
    
    				if ((item = ITEM_MANAGER::instance().CreateItem(1, dwGold / iSplitCount)))
    				{
    					if (i != 0)
    					{
    						pos.x = (number(-14, 14) + number(-14, 14)) * 20;
    						pos.y = (number(-14, 14) + number(-14, 14)) * 20;
    
    						pos.x += GetX();
    						pos.y += GetY();
    					}
    
    					item->AddToGround(GetMapIndex(), pos);
    					item->StartDestroyEvent();
    				}
    			}
    		}
    	}
    
    	// 평타가 아닐 때는 공포 처리
    	if (type != DAMAGE_TYPE_NORMAL && type != DAMAGE_TYPE_NORMAL_RANGE)
    	{
    		if (IsAffectFlag(AFF_TERROR))
    		{
    			int pct = GetSkillPower(SKILL_TERROR) / 400;
    
    			if (number(1, 100) <= pct)
    				return false;
    		}
    	}
    
    	int iCurHP = GetHP();
    	int iCurSP = GetSP();
    
    	bool IsCritical = false;
    	bool IsPenetrate = false;
    	bool IsDeathBlow = false;
    
    	enum DamageFlag
    	{
    		DAMAGE_NORMAL	= (1 << 0),
    		DAMAGE_POISON	= (1 << 1),
    		DAMAGE_DODGE	= (1 << 2),
    		DAMAGE_BLOCK	= (1 << 3),
    		DAMAGE_PENETRATE= (1 << 4),
    		DAMAGE_CRITICAL = (1 << 5),
    	};
    
    	//PROF_UNIT puAttr("Attr");
    
    	//
    	// 마법형 스킬과, 레인지형 스킬은(궁자객) 크리티컬과, 관통공격 계산을 한다.
    	// 원래는 하지 않아야 하는데 Nerf(다운밸런스)패치를 할 수 없어서 크리티컬과
    	// 관통공격의 원래 값을 쓰지 않고, /2 이상하여 적용한다.
    	// 
    	// 무사 이야기가 많아서 밀리 스킬도 추가
    	//
    	// 20091109 : 무사가 결과적으로 엄청나게 강해진 것으로 결론남, 독일 기준 무사 비율 70% 육박
    	//
    	if (type == DAMAGE_TYPE_MELEE || type == DAMAGE_TYPE_RANGE || type == DAMAGE_TYPE_MAGIC)
    	{
    		if (pAttacker)
    		{
    			// 크리티컬
    			int iCriticalPct = pAttacker->GetPoint(POINT_CRITICAL_PCT);
    
    			if (!IsPC())
    				iCriticalPct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_CRITICAL_BONUS);
    
    			if (iCriticalPct)
    			{
    				if (iCriticalPct >= 10) // 10보다 크면 5% + (4마다 1%씩 증가), 따라서 수치가 50이면 20%
    					iCriticalPct = 5 + (iCriticalPct - 10) / 4;
    				else // 10보다 작으면 단순히 반으로 깎음, 10 = 5%
    					iCriticalPct /= 2;
    
    				//크리티컬 저항 값 적용.
    				iCriticalPct -= GetPoint(POINT_RESIST_CRITICAL);
    
    				if (number(1, 100) <= iCriticalPct)
    				{
    					IsCritical = true;
    					dam *= 2;
    					EffectPacket(SE_CRITICAL);
    
    					if (IsAffectFlag(AFF_MANASHIELD))
    					{
    						RemoveAffect(AFF_MANASHIELD);
    					}
    				}
    			}
    
    			// 관통공격
    			int iPenetratePct = pAttacker->GetPoint(POINT_PENETRATE_PCT);
    
    			if (!IsPC())
    				iPenetratePct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_PENETRATE_BONUS);
    
    
    			if (iPenetratePct)
    			{
    				{
    					CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_RESIST_PENETRATE);
    
    					if (NULL != pkSk)
    					{
    						pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_RESIST_PENETRATE) / 100.0f);
    
    						iPenetratePct -= static_cast<int>(pkSk->kPointPoly.Eval());
    					}
    				}
    
    				if (iPenetratePct >= 10)
    				{
    					// 10보다 크면 5% + (4마다 1%씩 증가), 따라서 수치가 50이면 20%
    					iPenetratePct = 5 + (iPenetratePct - 10) / 4;
    				}
    				else
    				{
    					// 10보다 작으면 단순히 반으로 깎음, 10 = 5%
    					iPenetratePct /= 2;
    				}
    
    				//관통타격 저항 값 적용.
    				iPenetratePct -= GetPoint(POINT_RESIST_PENETRATE);
    
    				if (number(1, 100) <= iPenetratePct)
    				{
    					IsPenetrate = true;
    
    					if (test_server)
    						ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관통 추가 데미지 %d"), GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100);
    
    					dam += GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100;
    
    					if (IsAffectFlag(AFF_MANASHIELD))
    					{
    						RemoveAffect(AFF_MANASHIELD);
    					}
    				}
    			}
    		}
    	}
    	// 
    	// 콤보 공격, 활 공격, 즉 평타 일 때만 속성값들을 계산을 한다.
    	//
    	else if (type == DAMAGE_TYPE_NORMAL || type == DAMAGE_TYPE_NORMAL_RANGE)
    	{
    		if (type == DAMAGE_TYPE_NORMAL)
    		{
    			// 근접 평타일 경우 막을 수 있음
    			if (GetPoint(POINT_BLOCK) && number(1, 100) <= GetPoint(POINT_BLOCK))
    			{
    				if (test_server)
    				{
    					pAttacker->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 블럭! (%d%%)"), GetName(), GetPoint(POINT_BLOCK));
    					ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 블럭! (%d%%)"), GetName(), GetPoint(POINT_BLOCK));
    				}
    
    				SendDamagePacket(pAttacker, 0, DAMAGE_BLOCK);
    				return false;
    			}
    		}
    		else if (type == DAMAGE_TYPE_NORMAL_RANGE)
    		{
    			// 원거리 평타의 경우 피할 수 있음
    			if (GetPoint(POINT_DODGE) && number(1, 100) <= GetPoint(POINT_DODGE))
    			{
    				if (test_server)
    				{
    					pAttacker->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 회피! (%d%%)"), GetName(), GetPoint(POINT_DODGE));
    					ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 회피! (%d%%)"), GetName(), GetPoint(POINT_DODGE));
    				}
    
    				SendDamagePacket(pAttacker, 0, DAMAGE_DODGE);
    				return false;
    			}
    		}
    
    		if (IsAffectFlag(AFF_JEONGWIHON))
    			dam = (int) (dam * (100 + GetSkillPower(SKILL_JEONGWI) * 25 / 100) / 100);
    
    		if (IsAffectFlag(AFF_TERROR))
    			dam = (int) (dam * (95 - GetSkillPower(SKILL_TERROR) / 5) / 100);
    
    		if (IsAffectFlag(AFF_HOSIN))
    			dam = dam * (100 - GetPoint(POINT_RESIST_NORMAL_DAMAGE)) / 100;
    
    		//
    		// 공격자 속성 적용
    		//
    		if (pAttacker)
    		{
    			if (type == DAMAGE_TYPE_NORMAL)
    			{
    				// 반사
    				if (GetPoint(POINT_REFLECT_MELEE))
    				{
    					int reflectDamage = dam * GetPoint(POINT_REFLECT_MELEE) / 100;
    
    					// NOTE: 공격자가 IMMUNE_REFLECT 속성을 갖고있다면 반사를 안 하는 게 
    					// 아니라 1/3 데미지로 고정해서 들어가도록 기획에서 요청.
    					if (pAttacker->IsImmune(IMMUNE_REFLECT))
    						reflectDamage = int(reflectDamage / 3.0f + 0.5f);
    
    					pAttacker->Damage(this, reflectDamage, DAMAGE_TYPE_SPECIAL);
    				}
    			}
    
    			// 크리티컬
    			int iCriticalPct = pAttacker->GetPoint(POINT_CRITICAL_PCT);
    
    			if (!IsPC())
    				iCriticalPct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_CRITICAL_BONUS);
    
    			if (iCriticalPct)
    			{
    				//크리티컬 저항 값 적용.
    				iCriticalPct -= GetPoint(POINT_RESIST_CRITICAL);
    
    				if (number(1, 100) <= iCriticalPct)
    				{
    					IsCritical = true;
    					dam *= 2;
    					EffectPacket(SE_CRITICAL);
    				}
    			}
    
    			// 관통공격
    			int iPenetratePct = pAttacker->GetPoint(POINT_PENETRATE_PCT);
    
    			if (!IsPC())
    				iPenetratePct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_PENETRATE_BONUS);
    
    			{
    				CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_RESIST_PENETRATE);
    
    				if (NULL != pkSk)
    				{
    					pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_RESIST_PENETRATE) / 100.0f);
    
    					iPenetratePct -= static_cast<int>(pkSk->kPointPoly.Eval());
    				}
    			}
    
    
    			if (iPenetratePct)
    			{
    				
    				//관통타격 저항 값 적용.
    				iPenetratePct -= GetPoint(POINT_RESIST_PENETRATE);
    
    				if (number(1, 100) <= iPenetratePct)
    				{
    					IsPenetrate = true;
    
    					if (test_server)
    						ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관통 추가 데미지 %d"), GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100);
    					dam += GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100;
    				}
    			}
    
    			// HP 스틸
    			if (pAttacker->GetPoint(POINT_STEAL_HP))
    			{
    				int pct = 1;
    
    				if (number(1, 10) <= pct)
    				{
    					int iHP = MIN(dam, MAX(0, iCurHP)) * pAttacker->GetPoint(POINT_STEAL_HP) / 100;
    
    					if (iHP > 0 && GetHP() >= iHP)
    					{
    						CreateFly(FLY_HP_SMALL, pAttacker);
    						pAttacker->PointChange(POINT_HP, iHP);
    						PointChange(POINT_HP, -iHP);
    					}
    				}
    			}
    
    			// SP 스틸
    			if (pAttacker->GetPoint(POINT_STEAL_SP))
    			{
    				int pct = 1;
    
    				if (number(1, 10) <= pct)
    				{
    					int iCur;
    
    					if (IsPC())
    						iCur = iCurSP;
    					else
    						iCur = iCurHP;
    
    					int iSP = MIN(dam, MAX(0, iCur)) * pAttacker->GetPoint(POINT_STEAL_SP) / 100;
    
    					if (iSP > 0 && iCur >= iSP)
    					{
    						CreateFly(FLY_SP_SMALL, pAttacker);
    						pAttacker->PointChange(POINT_SP, iSP);
    
    						if (IsPC())
    							PointChange(POINT_SP, -iSP);
    					}
    				}
    			}
    
    			// 돈 스틸
    			if (pAttacker->GetPoint(POINT_STEAL_GOLD))
    			{
    				if (number(1, 100) <= pAttacker->GetPoint(POINT_STEAL_GOLD))
    				{
    					int iAmount = number(1, GetLevel());
    					pAttacker->PointChange(POINT_GOLD, iAmount);
    					DBManager::instance().SendMoneyLog(MONEY_LOG_MISC, 1, iAmount);
    				}
    			}
    
    			// 칠 때마다 HP회복
    			if (pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) && number(0, 4) > 0) // 80% 확률
    			{
    				// int i = MIN(dam, iCurHP) * pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) / 100;
    				int i = ((iCurHP>=0)?MIN(dam, iCurHP):dam) * pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) / 100; // Fix
    
    				if (i)
    				{
    					CreateFly(FLY_HP_SMALL, pAttacker);
    					pAttacker->PointChange(POINT_HP, i);
    				}
    			}
    
    			// 칠 때마다 SP회복
    			if (pAttacker->GetPoint(POINT_HIT_SP_RECOVERY) && number(0, 4) > 0) // 80% 확률
    			{
    				// int i = MIN(dam, iCurHP) * pAttacker->GetPoint(POINT_HIT_SP_RECOVERY) / 100;
    				int i = ((iCurHP>=0)?MIN(dam, iCurHP):dam) * pAttacker->GetPoint(POINT_HIT_SP_RECOVERY) / 100; // Fix
    
    				if (i)
    				{
    					CreateFly(FLY_SP_SMALL, pAttacker);
    					pAttacker->PointChange(POINT_SP, i);
    				}
    			}
    
    			// 상대방의 마나를 없앤다.
    			if (pAttacker->GetPoint(POINT_MANA_BURN_PCT))
    			{
    				if (number(1, 100) <= pAttacker->GetPoint(POINT_MANA_BURN_PCT))
    					PointChange(POINT_SP, -50);
    			}
    		}
    	}
    
    	//
    	// 평타 또는 스킬로 인한 보너스 피해/방어 계산
    	// 
    	switch (type)
    	{
    		case DAMAGE_TYPE_NORMAL:
    		case DAMAGE_TYPE_NORMAL_RANGE:
    			if (pAttacker)
    				if (pAttacker->GetPoint(POINT_NORMAL_HIT_DAMAGE_BONUS))
    					dam = dam * (100 + pAttacker->GetPoint(POINT_NORMAL_HIT_DAMAGE_BONUS)) / 100;
    
    			dam = dam * (100 - MIN(99, GetPoint(POINT_NORMAL_HIT_DEFEND_BONUS))) / 100;
    			break;
    
    		case DAMAGE_TYPE_MELEE:
    		case DAMAGE_TYPE_RANGE:
    		case DAMAGE_TYPE_FIRE:
    		case DAMAGE_TYPE_ICE:
    		case DAMAGE_TYPE_ELEC:
    		case DAMAGE_TYPE_MAGIC:
    			if (pAttacker)
    				if (pAttacker->GetPoint(POINT_SKILL_DAMAGE_BONUS))
    					dam = dam * (100 + pAttacker->GetPoint(POINT_SKILL_DAMAGE_BONUS)) / 100;
    
    			dam = dam * (100 - MIN(99, GetPoint(POINT_SKILL_DEFEND_BONUS))) / 100;
    			break;
    
    		default:
    			break;
    	}
    
    	//
    	// 마나쉴드(흑신수호)
    	//
    	if (IsAffectFlag(AFF_MANASHIELD))
    	{
    		// POINT_MANASHIELD 는 작아질수록 좋다
    		int iDamageSPPart = dam / 3;
    		int iDamageToSP = iDamageSPPart * GetPoint(POINT_MANASHIELD) / 100;
    		int iSP = GetSP();
    
    		// SP가 있으면 무조건 데미지 절반 감소
    		if (iDamageToSP <= iSP)
    		{
    			PointChange(POINT_SP, -iDamageToSP);
    			dam -= iDamageSPPart;
    		}
    		else
    		{
    			// 정신력이 모자라서 피가 더 깍여야할
    			PointChange(POINT_SP, -GetSP());
    			dam -= iSP * 100 / MAX(GetPoint(POINT_MANASHIELD), 1);
    		}
    	}
    
    	//
    	// 전체 방어력 상승 (몰 아이템)
    	// 
    	if (GetPoint(POINT_MALL_DEFBONUS) > 0)
    	{
    		int dec_dam = MIN(200, dam * GetPoint(POINT_MALL_DEFBONUS) / 100);
    		dam -= dec_dam;
    	}
    
    	if (pAttacker)
    	{
    		//
    		// 전체 공격력 상승 (몰 아이템)
    		//
    		if (pAttacker->GetPoint(POINT_MALL_ATTBONUS) > 0)
    		{
    			int add_dam = MIN(300, dam * pAttacker->GetLimitPoint(POINT_MALL_ATTBONUS) / 100);
    			dam += add_dam;
    		}
    
    		//
    		// 제국으로 인한 보너스 (한국 올드 버전만 적용)
    		//
    		int iEmpire = GetEmpire();
    		long lMapIndex = GetMapIndex();
    		int iMapEmpire = SECTREE_MANAGER::instance().GetEmpireFromMapIndex(lMapIndex);
    
    		if (LC_IsYMIR() == true)
    		{
    			if (iEmpire && iMapEmpire && iEmpire != iMapEmpire)
    			{
    				dam += (dam * 30) / 100;
    			}
    		}
    
    		if (pAttacker->IsPC())
    		{
    			iEmpire = pAttacker->GetEmpire();
    			lMapIndex = pAttacker->GetMapIndex();
    			iMapEmpire = SECTREE_MANAGER::instance().GetEmpireFromMapIndex(lMapIndex);
    
    			// 다른 제국 사람인 경우 데미지 10% 감소
    			if (iEmpire && iMapEmpire && iEmpire != iMapEmpire)
    			{
    				int percent = 10;
    				
    				if (184 <= lMapIndex && lMapIndex <= 189)
    				{
    					if (LC_IsYMIR() == true)
    						percent = 7;
    					else
    						percent = 9;
    				}
    				else
    				{
    					if (LC_IsYMIR() == true)
    						percent = 8;
    					else
    						percent = 9;
    				}
    
    				dam = dam * percent / 10;
    			}
    
    			if (!IsPC() && GetMonsterDrainSPPoint())
    			{
    				int iDrain = GetMonsterDrainSPPoint();
    
    				if (iDrain <= pAttacker->GetSP())
    					pAttacker->PointChange(POINT_SP, -iDrain);
    				else
    				{
    					int iSP = pAttacker->GetSP();
    					pAttacker->PointChange(POINT_SP, -iSP);
    				}
    			}
    
    		}
    		else if (pAttacker->IsGuardNPC())
    		{
    			SET_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD);
    			Stun();
    			return true;
    		}
    
    		//
    		// 군주의 금강권 & 사자후 
    		//
    		if (pAttacker->IsPC() && CMonarch::instance().IsPowerUp(pAttacker->GetEmpire()))
    		{
    			// 10% 피해 증가
    			dam += dam / 10;
    		}
    
    		if (IsPC() && CMonarch::instance().IsDefenceUp(GetEmpire()))
    		{
    			// 10% 피해 감소
    			dam -= dam / 10;
    		}
    	}
    	//puAttr.Pop();
    
    	if (!GetSectree() || GetSectree()->IsAttr(GetX(), GetY(), ATTR_BANPK))
    		return false;
    
    	if (!IsPC())
    	{
    		if (m_pkParty && m_pkParty->GetLeader())
    			m_pkParty->GetLeader()->SetLastAttacked(get_dword_time());
    		else
    			SetLastAttacked(get_dword_time());
    
    		// 몬스터 대사 : 맞을 때
    		MonsterChat(MONSTER_CHAT_ATTACKED);
    	}
    
    	if (IsStun())
    	{
    		Dead(pAttacker);
    		return true;
    	}
    
    	if (IsDead())
    		return true;
    
    	// 독 공격으로 죽지 않도록 함.
    	if (type == DAMAGE_TYPE_POISON)
    	{
    		if (GetHP() - dam <= 0)
    		{
    			dam = GetHP() - 1;
    		}
    	}
    
    	// ------------------------
    	// 독일 프리미엄 모드 
    	// -----------------------
    	if (LC_IsGermany() && pAttacker && pAttacker->IsPC())
    	{
    		int iDmgPct = CHARACTER_MANAGER::instance().GetUserDamageRate(pAttacker);
    		dam = dam * iDmgPct / 100;
    	}
    
    	// STONE SKIN : 피해 반으로 감소
    	if (IsMonster() && IsStoneSkinner())
    	{
    		if (GetHPPct() < GetMobTable().bStoneSkinPoint)
    			dam /= 2;
    	}
    
    	//PROF_UNIT puRest1("Rest1");
    	if (pAttacker)
    	{
    		// DEATH BLOW : 확률 적으로 4배 피해 (!? 현재 이벤트나 공성전용 몬스터만 사용함)
    		if (pAttacker->IsMonster() && pAttacker->IsDeathBlower())
    		{
    			if (pAttacker->IsDeathBlow())
    			{
    				if (number(1, 4) == GetJob())
    				{
    					IsDeathBlow = true;
    					dam = dam * 4;
    				}
    			}
    		}
    
    		dam = BlueDragon_Damage(this, pAttacker, dam);
    
    		BYTE damageFlag = 0;
    
    		if (type == DAMAGE_TYPE_POISON)
    			damageFlag = DAMAGE_POISON;
    		else
    			damageFlag = DAMAGE_NORMAL;
    
    		if (IsCritical == true)
    			damageFlag |= DAMAGE_CRITICAL;
    
    		if (IsPenetrate == true)
    			damageFlag |= DAMAGE_PENETRATE;
    
    
    		//최종 데미지 보정
    		float damMul = this->GetDamMul();
    		float tempDam = dam;
    		dam = tempDam * damMul + 0.5f;
    
    
    		if (pAttacker)
    			SendDamagePacket(pAttacker, dam, damageFlag);
    
    		if (test_server)
    		{
    			if(pAttacker)
    			{
    				pAttacker->ChatPacket(CHAT_TYPE_INFO, "-> %s, DAM %d HP %d(%d%%) %s%s",
    						GetName(), 
    						dam, 
    						GetHP(),
    						(GetHP() * 100) / GetMaxHP(),
    						IsCritical ? "crit " : "",
    						IsPenetrate ? "pene " : "",
    						IsDeathBlow ? "deathblow " : "");
    			}
    
    			ChatPacket(CHAT_TYPE_PARTY, "<- %s, DAM %d HP %d(%d%%) %s%s",
    					pAttacker ? pAttacker->GetName() : 0,
    					dam, 
    					GetHP(),
    					(GetHP() * 100) / GetMaxHP(),
    					IsCritical ? "crit " : "",
    					IsPenetrate ? "pene " : "",
    					IsDeathBlow ? "deathblow " : "");
    		}
    
    		if (m_bDetailLog)
    		{
    			ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s[%d]가 공격 위치: %d %d"), pAttacker->GetName(), (DWORD) pAttacker->GetVID(), pAttacker->GetX(), pAttacker->GetY());
    		}
    	}
    
    #ifdef ENABLE_EXTENDED_BATTLE_PASS
    	if (type != DAMAGE_TYPE_POISON && type != DAMAGE_TYPE_FIRE)
    	{
    		if (IsPC())
    			pAttacker->UpdateExtBattlePassMissionProgress(DAMAGE_PLAYER, dam, GetLevel());
    		else
    			pAttacker->UpdateExtBattlePassMissionProgress(DAMAGE_MONSTER, dam, GetRaceNum());
    	}
    #endif
    
    	//
    	// !!!!!!!!! 실제 HP를 줄이는 부분 !!!!!!!!!
    	//
    	if (!cannot_dead)
    	{
    		PointChange(POINT_HP, -dam, false);
    	}
    
    	//puRest1.Pop();
    
    	//PROF_UNIT puRest2("Rest2");
    	if (pAttacker && dam > 0 && IsNPC())
    	{
    		//PROF_UNIT puRest20("Rest20");
    		TDamageMap::iterator it = m_map_kDamage.find(pAttacker->GetVID());
    
    		if (it == m_map_kDamage.end())
    		{
    			m_map_kDamage.insert(TDamageMap::value_type(pAttacker->GetVID(), TBattleInfo(dam, 0)));
    			it = m_map_kDamage.find(pAttacker->GetVID());
    		}
    		else
    		{
    			it->second.iTotalDamage += dam;
    		}
    		//puRest20.Pop();
    
    		//PROF_UNIT puRest21("Rest21");
    		StartRecoveryEvent(); // 몬스터는 데미지를 입으면 회복을 시작한다.
    		//puRest21.Pop();
    
    		//PROF_UNIT puRest22("Rest22");
    		UpdateAggrPointEx(pAttacker, type, dam, it->second);
    		//puRest22.Pop();
    	}
    	//puRest2.Pop();
    
    	//PROF_UNIT puRest3("Rest3");
    	if (GetHP() <= 0)
    	{
    		if (pAttacker && !pAttacker->IsNPC())
    			m_dwKillerPID = pAttacker->GetPlayerID();
    		else
    			m_dwKillerPID = 0;
    
    		Stun(true);
    	}
    
    	return false;
    }

     

     

  2. See this error on client 'syserr'?

    ResourceManager::GetResourcePointer: NOT SUPPORT FILE d:\project\metin2\main\assets\npc\lion\lion.psd

    I faced this problem using UltharV2 SF

     

    How to fix it?
     

    1. Download "Granny Texture Path Changer" by Helia01:

    2. Unpack your 'npc' folder that contains 'lion' folder inside and search for: "combo_attack1.gr2"
    3. Open Granny Texture Path Changer and change the .PSD texture to: "D:\Ymir Work\npc\lion\lion.dds"
    4. Pack your files

    And done!

    Sorry if someone has already posted this before, I didn't find a solution on the forum.

    • Metin2 Dev 2
    • muscle 1
    • Love 2
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.