Exemple #1
0
int CChar::NPC_GetHostilityLevelToward(const CChar *pCharTarg) const
{
	ADDTOCALLSTACK("CChar::NPC_GetHostilityLevelToward");
	// What is my general hostility level toward this type of creature ?
	//
	// based on:
	//  npc vs player (evil npc's don't like players)
	//  creature body type (allie groups)
	//
	// RETURN:
	//   100 = extreme hatred.
	//   0 = neutral.
	//   -100 = love them

	if ( !m_pNPC || !pCharTarg )
		return 0;

	// If it's a pet, inherit hostility from it's master
	CChar *pCharOwn = pCharTarg->NPC_PetGetOwner();
	if ( pCharOwn && (pCharOwn != this) )
	{
		static int sm_iReentrant = 0;
		if ( sm_iReentrant > 32 )
		{
			DEBUG_ERR(("Too many owners (circular ownership?) to continue acquiring hostility level towards %s uid=0%lx\n", pCharOwn->GetName(), pCharOwn->GetUID().GetPrivateUID()));
			return 0;
		}

		++sm_iReentrant;
		int iHostility = NPC_GetHostilityLevelToward(pCharOwn);
		--sm_iReentrant;
		return iHostility;
	}

	if ( m_pNPC->m_Brain == NPCBRAIN_BERSERK )		// Beserks always hate everyone
		return 100;
	if ( pCharTarg->m_pPlayer )
		return 100;

	if ( pCharTarg->m_pNPC )
	{
		if ( !g_Cfg.m_fMonsterFight )	// Monsters are not supposed to fight other monsters!
			return 0;
		if ( GetDispID() == pCharTarg->GetDispID() )	// I will never attack those of my own kind
			return -100;
		else if ( NPC_GetAllyGroupType(GetDispID()) == NPC_GetAllyGroupType(pCharTarg->GetDispID()) )
			return -50;
		else if ( m_pNPC->m_Brain == pCharTarg->m_pNPC->m_Brain )
			return -30;

		return 100;
	}

	return 0;
}
Exemple #2
0
int CChar::NPC_GetVendorMarkup( const CChar * pChar ) const
{
	ADDTOCALLSTACK("CChar::NPC_GetVendorMarkup");
	// This vendor marks stuff up/down this percentage.
	// Base this on KARMA. Random is calculated at Restock time
	// When vendor sells to players this is the markup value.
	// fBuy: Client buying
	// RETURN:
	//  0-100

	if ( !pChar || IsStatFlag(STATF_Pet) )	// Not on a hired vendor.
		return( 0 );

	CVarDefCont	*pVar = NULL, *pVarCharDef = NULL;
	CCharBase * pCharDef = Char_GetDef();
	
	if ( pCharDef )
	{
		// get markup value of NPC-chardef
		pVarCharDef = pCharDef->m_TagDefs.GetKey("VENDORMARKUP");
	}

	int iHostility = maximum(NPC_GetHostilityLevelToward(pChar), 0);
	iHostility = minimum(iHostility + 15, 100);

	pVar = m_TagDefs.GetKey("VENDORMARKUP");
	if ( pVar )
	{
		iHostility += static_cast<int>(pVar->GetValNum());
		// add NPC's markup to hostility made by karma difference
	}
	else
	{
		pVar = GetRegion()->m_TagDefs.GetKey("VENDORMARKUP");
		if ( pVar )
		{
			iHostility += static_cast<int>(pVar->GetValNum());
			// if NPC is unmarked, look if the region is
		}
		else
		{
			// neither NPC nor REGION are marked, so look for the chardef
			if ( pVarCharDef )
			{
				iHostility += static_cast<int>(pVarCharDef->GetValNum());
			}
		}
	}

	return( iHostility );
}
Exemple #3
0
int CChar::NPC_GetAttackMotivation(CChar *pChar) const
{
	ADDTOCALLSTACK("CChar::NPC_GetAttackMotivation");
	// Some sort of monster.
	// Am I stronger than he is ? Should I continue fighting ?
	// Take into consideration AC, health, skills, etc..
	// RETURN:
	//   < 0 = dead meat. (run away)
	//   0 = I'm have no interest.
	//   50 = even match.
	//   100 = he's a push over.

	if ( !m_pNPC || !pChar || !pChar->m_pArea )
		return 0;
	if ( pChar->m_pArea->IsFlag(REGION_FLAG_SAFE) )
		return 0;

	int iMotivation = NPC_GetHostilityLevelToward(pChar);
	if ( iMotivation <= 0 )
		return iMotivation;

	if ( !pChar->Fight_IsAttackable() )
		return 0;
	if ( (m_pNPC->m_Brain == NPCBRAIN_BERSERK) || (m_pNPC->m_Brain == NPCBRAIN_GUARD) )
		return 100;

	// Try to stay on one target
	if ( Fight_IsActive() && (m_Act_Targ == pChar->GetUID()) )
		iMotivation += 10;

	// Less interested the further away they are
	iMotivation -= GetDist(pChar);

	if ( g_Cfg.m_fMonsterFear )
	{
		if ( GetHealthPercent() < 50 )
			iMotivation -= 50 + (Stat_GetAdjusted(STAT_INT) / 16);
	}
	return iMotivation;
}
Exemple #4
0
int CChar::NPC_GetAttackMotivation( CChar * pChar, int iMotivation ) const
{
	ADDTOCALLSTACK("CChar::NPC_GetAttackMotivation");
	// Some sort of monster.
	// Am I stronger than he is ? Should I continue fighting ?
	// Take into consideration AC, health, skills, etc..
	// RETURN:
	// <-1 = dead meat. (run away)
	// 0 = I'm have no interest.
	// 50 = even match.
	// 100 = he's a push over.

	if ( !m_pNPC || !pChar || !pChar->m_pArea )
		return 0;
	if ( Stat_GetVal(STAT_STR) <= 0 )
		return -1;		// I'm dead
	// Is the target interesting ?
	if ( pChar->m_pArea->IsFlag( REGION_FLAG_SAFE ))	// universal
		return 0;
	if ( pChar->IsStatFlag(STATF_DEAD) && pChar->m_pNPC && pChar->m_pNPC->m_bonded )
		return 0;
	// If the area is guarded then think better of this.
	if ( pChar->m_pArea->IsGuarded() && m_pNPC->m_Brain != NPCBRAIN_GUARD )		// too smart for this.
	{
		iMotivation -= Stat_GetAdjusted(STAT_INT) / 20;
	}

	// Owned by or is one of my kind ?

	iMotivation += NPC_GetHostilityLevelToward( pChar );

	if ( iMotivation > 0 )
	{
		// Am i injured etc ?
		iMotivation = NPC_GetAttackContinueMotivation( pChar, iMotivation );
	}
	return iMotivation;
}
Exemple #5
0
int CChar::NPC_GetHostilityLevelToward( const CChar * pCharTarg ) const
{
	ADDTOCALLSTACK("CChar::NPC_GetHostilityLevelToward");
	// What is my general hostility level toward this type of creature ?
	//
	// based on:
	//  npc vs player, (evil npc's don't like players regurdless of align, xcept in town)
	//  karma (we are of different alignments)
	//  creature body type. (allie groups)
	//  hunger, (they could be food)
	//  memories of this creature.
	//
	// DO NOT consider:
	//   strength, he is far stronger or waeker than me.
	//	 health, i may be near death.
	//   location (guarded area), (xcept in the case that evil people like other evils in town)
	//   loot, etc.
	//
	// RETURN:
	//   100 = extreme hatred.
	//   0 = neutral.
	//   -100 = love them
	//


	if ( !pCharTarg || !m_pNPC )
		return 0;

	int iHostility = 0;

	// if it is a pet - register it the same as it's master.
	CChar * pCharOwn = pCharTarg->NPC_PetGetOwner();
	if ( pCharOwn != NULL && pCharOwn != this )
	{
		static int sm_iReentrant = 0;
		if (sm_iReentrant > 32)
		{
			DEBUG_ERR(("Too many owners (circular ownership?) to continue acquiring hostility level towards %s uid=0%lx\n", pCharOwn->GetName(), pCharOwn->GetUID().GetPrivateUID()));
			return 0;
		}

		++sm_iReentrant;
		iHostility = NPC_GetHostilityLevelToward( pCharOwn );
		--sm_iReentrant;

		return iHostility;
	}

	int iKarma = Stat_GetAdjusted(STAT_KARMA);

	bool fDoMemBase = false;

	if ( Noto_IsEvil() &&	// i am evil.
		(m_pArea && !m_pArea->IsGuarded()) &&	// we are not in an evil town.
		pCharTarg->m_pPlayer )	// my target is a player.
	{
		// If i'm evil i give no benefit to players with bad karma.
		// I hate all players.
		// Unless i'm in a guarded area. then they are cool.
		iHostility = 51;
	}
	else if ( m_pNPC->m_Brain == NPCBRAIN_BERSERK )	// i'm beserk.
	{
		// beserks just hate everyone all the time.
		iHostility = 100;
	}
	else if ( pCharTarg->m_pNPC &&	// my target is an NPC
		pCharTarg->m_pNPC->m_Brain != NPCBRAIN_BERSERK &&	// ok to hate beserks.
		! g_Cfg.m_fMonsterFight )		// monsters are not supposed to fight other monsters !
	{
		iHostility = -50;
		fDoMemBase = true;	// set this low in case we are defending ourselves. but not attack for hunger.
	}
	else
	{
		// base hostillity on karma diff.

		int iKarmaTarg = pCharTarg->Stat_GetAdjusted(STAT_KARMA);

		if ( Noto_IsEvil())
		{
			// I'm evil.
			if ( iKarmaTarg > 0 )
			{
				iHostility += ( iKarmaTarg ) / 1024;
			}
		}
		else if ( iKarma > 300 )
		{
			// I'm good and my target is evil.
			if ( iKarmaTarg < -100 )
			{
				iHostility += ( -iKarmaTarg ) / 1024;
			}
		}
	}

	// Based on just creature type.

	if ( ! fDoMemBase )
	{
		if ( pCharTarg->m_pNPC )
		{
			// Human NPC's will attack humans .

			if ( GetDispID() == pCharTarg->GetDispID())
			{
				// I will never attack those of my own kind...even if starving
				iHostility -= 100;
			}
			else if ( NPC_GetAllyGroupType( GetDispID()) == NPC_GetAllyGroupType(pCharTarg->GetDispID()))
			{
				iHostility -= 50;
			}
			else if ( pCharTarg->m_pNPC->m_Brain == m_pNPC->m_Brain )	// My basic kind
			{
				// Won't attack other monsters. (unless very hungry)
				iHostility -= 30;
			}
		}
		else
		{
			// Not immediately hostile if looks the same as me.
			if ( ! IsPlayableCharacter() && NPC_GetAllyGroupType( GetDispID()) == NPC_GetAllyGroupType(pCharTarg->GetDispID()))
			{
				iHostility -= 51;
			}
		}
	}

	// I have been attacked/angered by this creature before ?
	CItemMemory * pMemory = Memory_FindObjTypes( pCharTarg, MEMORY_FIGHT|MEMORY_HARMEDBY|MEMORY_IRRITATEDBY|MEMORY_SAWCRIME|MEMORY_AGGREIVED );
	if ( pMemory )
	{
		iHostility += 50;
	}

#ifdef _ALPHASPHERE
	/* 
		foes or allies? 
		Defined by tag.ff_group, tag.ff_foe and/or tag.ff_ally
	*/
	CVarDefCont	*pVar, *pVarTarg;
	int iffCounter=0, iffGroup=0;

	pVarTarg = pCharTarg->m_TagDefs.GetKey("FF_GROUP");
	if ( pVarTarg )
	{
		iffGroup = pVarTarg->GetValNum();
		pVar = m_TagDefs.GetKey("FF_FOE");
		if ( pVar )
		{
			iffCounter = pVar->GetValNum();
			if ( iffCounter & iffGroup )
			{
				// is an enemy
				iHostility += 70;
			}
		} else {
			pVar = m_TagDefs.GetKey("FF_ALLY");
			if ( pVar )
			{
				iffCounter = pVar->GetValNum();
				if ( iffCounter & iffGroup )
				{
					// is an ally
					iHostility -= 70;
				}
			}
		}

		if ( iHostility > 100 )
			iHostility = 100;
		else if ( iHostility < -100 )
			iHostility = -100;
		TCHAR *pszTmp = Str_GetTemp();
		sprintf(pszTmp,"char = %s, target = %s, iHostility = %d, iffGroup = %d, iffCounter = %d\n",GetName(),pCharTarg->GetName(),iHostility,iffGroup,iffCounter);
		DEBUG_WARN((pszTmp));
	}
#endif

	return( iHostility );
}
Exemple #6
0
int CChar::NPC_GetVendorMarkup( const CChar * pChar ) const
{
	ADDTOCALLSTACK("CChar::NPC_GetVendorMarkup");
	// This vendor marks stuff up/down this percentage.
	// Base this on KARMA. Random is calculated at Restock time
	// When vendor sells to players this is the markup value.
	// fBuy: Client buying
	// RETURN:
	//  0-100

	if ( !pChar || IsStatFlag(STATF_Pet) )	// Not on a hired vendor.
		return( 0 );

	CVarDefCont	*pVarRegion = NULL, *pVarCharDef = NULL, *pVarNPC = NULL, *pVarPlayer = NULL;
	CCharBase * pCharDef = Char_GetDef();	// NPC CharDef
	int iMarkUp = 0;
	
	if ( pCharDef )
	{
		// get markup value of NPC-chardef
		pVarCharDef = pCharDef->m_TagDefs.GetKey("VENDORMARKUP");
	}

	pVarPlayer = pChar->m_TagDefs.GetKey("VENDORMARKUP");

	int iHostility = maximum(NPC_GetHostilityLevelToward(pChar), 0);
	iHostility = minimum(iHostility + 15, 100);

	// go thru all possible tweaks

	// Region's markup
	pVarRegion = GetRegion()->m_TagDefs.GetKey("VENDORMARKUP");
	if ( pVarRegion )
	{
		iMarkUp = pVarRegion->GetValNum();
	}

	// NPC's CharDef's markup
	if ( pVarCharDef )
	{
		iMarkUp += pVarCharDef->GetValNum();
	}

	// NPC's personal markup
	pVarNPC = m_TagDefs.GetKey("VENDORMARKUP");
	if ( pVarNPC )
	{
		iMarkUp += pVarNPC->GetValNum();
	}

	// finally: Player char's markup
	pVarPlayer = pChar->m_TagDefs.GetKey("VENDORMARKUP");
	if ( pVarPlayer )
	{
		iMarkUp += pVarPlayer->GetValNum();
	}

	// ensure that the return value is between -100 or positive
	iMarkUp += iHostility;
	if ( iMarkUp < -100 )
		return (-100);
	else
		return ( iMarkUp );
}