Example #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;
}
Example #2
0
STDMETHODIMP CJavaObject::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
                                        UINT cNames, LCID lcid, DISPID* rgdispid)
{
  USES_CONVERSION;
  // Stack-allocated
  return GetDispID(OLE2BSTR(*rgszNames), 0, rgdispid);
}
Example #3
0
// Create the char corpse when i die (STATF_DEAD) or fall asleep (STATF_Sleeping)
// Summoned (STATF_Conjured) and some others creatures have no corpse.
CItemCorpse * CChar::MakeCorpse( bool fFrontFall )
{
	ADDTOCALLSTACK("CChar::MakeCorpse");

	word wFlags = (word)(m_TagDefs.GetKeyNum("DEATHFLAGS", true));
	if (wFlags & DEATH_NOCORPSE)
		return( NULL );
	if (IsStatFlag(STATF_Conjured) && !(wFlags & (DEATH_NOCONJUREDEFFECT|DEATH_HASCORPSE)))
	{
		Effect(EFFECT_XYZ, ITEMID_FX_SPELL_FAIL, this, 1, 30);
		return( NULL );
	}

	CItemCorpse *pCorpse = dynamic_cast<CItemCorpse *>(CItem::CreateScript(ITEMID_CORPSE, this));
	if (pCorpse == NULL)	// weird internal error
		return( NULL );

	tchar *pszMsg = Str_GetTemp();
	sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_MSG_CORPSE_OF), GetName());
	pCorpse->SetName(pszMsg);
	pCorpse->SetHue(GetHue());
	pCorpse->SetCorpseType(GetDispID());
	pCorpse->SetAttr(ATTR_MOVE_NEVER);
	pCorpse->m_itCorpse.m_BaseID = m_prev_id;	// id the corpse type here !
	pCorpse->m_itCorpse.m_facing_dir = m_dirFace;
	pCorpse->m_uidLink = GetUID();

	// TO-DO: Fix corpses always turning to the same dir (DIR_N) after resend it to clients

	if (fFrontFall)
		pCorpse->m_itCorpse.m_facing_dir = static_cast<DIR_TYPE>(m_dirFace|0x80);

	int iDecayTimer = -1;	// never decay
	if (IsStatFlag(STATF_DEAD))
	{
		iDecayTimer = (m_pPlayer) ? g_Cfg.m_iDecay_CorpsePlayer : g_Cfg.m_iDecay_CorpseNPC;
		pCorpse->SetTimeStamp(CServerTime::GetCurrentTime().GetTimeRaw());	// death time
		if (Attacker_GetLast())
			pCorpse->m_itCorpse.m_uidKiller = Attacker_GetLast()->GetUID();
		else
			pCorpse->m_itCorpse.m_uidKiller.InitUID();
	}
	else	// sleeping (not dead)
	{
		pCorpse->SetTimeStamp(0);
		pCorpse->m_itCorpse.m_uidKiller = GetUID();
	}

	if ((m_pNPC && m_pNPC->m_bonded) || IsStatFlag(STATF_Conjured|STATF_Sleeping))
		pCorpse->m_itCorpse.m_carved = 1;	// corpse of bonded and summoned creatures (or sleeping players) can't be carved

	if ( !(wFlags & DEATH_NOLOOTDROP) )		// move non-newbie contents of the pack to corpse
		DropAll( pCorpse );

	pCorpse->SetKeyNum("OVERRIDE.MAXWEIGHT", g_Cfg.Calc_MaxCarryWeight(this) / 10);		// set corpse maxweight to prevent weird exploits like when someone place many items on an player corpse just to make this player get stuck on resurrect
	pCorpse->MoveToDecay(GetTopPoint(), iDecayTimer);
	return( pCorpse );
}
Example #4
0
bool CChar::NPC_CheckWalkHere( const CPointBase & pt, const CRegionBase * pArea, WORD wBlockFlags ) const
{
	ADDTOCALLSTACK("CChar::NPC_CheckWalkHere");
	UNREFERENCED_PARAMETER(wBlockFlags);
	// Does the NPC want to walk here ? step on this item ?
	if ( !m_pNPC )
		return false;
	if ( !pt.IsValidXY() )
		return true;

	if ( m_pArea != NULL )
	{
		if ( m_pNPC->m_Brain == NPCBRAIN_GUARD && !IsStatFlag(STATF_War) )	// guards will want to stay in guard range
		{
			if ( m_pArea->IsGuarded() && !pArea->IsGuarded() )
				return false;
		}

		if ( Noto_IsCriminal() )
		{
			if ( !m_pArea->IsGuarded() && pArea->IsGuarded() )
				return false;
		}
	}

	// Is there a nasty object here that will hurt us ?
	CWorldSearch AreaItems(pt);
	for (;;)
	{
		CItem * pItem = AreaItems.GetItem();
		if ( pItem == NULL )
			break;

		if ( abs(pItem->GetTopZ() - pt.m_z) > 5 )
			continue;

		switch ( pItem->GetType() )
		{
			case IT_WEB:
				return (GetDispID() == CREID_GIANT_SPIDER) ? true : false;
			case IT_FIRE:
				return Can(CAN_C_FIRE_IMMUNE);
			case IT_TRAP:
			case IT_TRAP_ACTIVE:
			case IT_MOONGATE:
			case IT_TELEPAD:
				return false;
			default:
				break;
		}
	}
	return true;
}
/******************************************************************************
*   GetIDsOfNames -- Takes an array of strings and returns an array of DISPID's
*   which correspond to the methods or properties indicated.  In real life,
*   If the name is not recognized, then DISP_E_UNKNOWNNAME is returned.
*   However, this is T-Rexx, we know every thing.  Log the name that is being
*   sought, and return a bogus DispID.
******************************************************************************/
STDMETHODIMP OrxScript::GetIDsOfNames(REFIID riid,
                                          OLECHAR **pNames,
                                          UINT pNamesCount,  LCID plcid,
                                          DISPID *pbDispID)
{
    HRESULT RetCode = S_OK,RC;
    UINT    i;
    char    lIID[100];


    StringFromGUID2(riid,(LPOLESTR)lIID,sizeof(lIID)/2);
    FPRINTF(logfile,"OrxScript::GetIDsOfNames\n");
    FPRINTF2(logfile,"pNamesCount %d   riid %S \n",pNamesCount,lIID);

    //check parameters
    if (riid != IID_NULL)
    {
        RetCode = E_INVALIDARG;
    }

    else
    {
        //loop through all the pNames that were passed in, and pass
        //them to the routine that deals with one name at a time.
        for (i = 0; i < pNamesCount; i++)
        {

            RC = GetDispID(pNames[i],fdexNameCaseInsensitive,&pbDispID[i]);
            if (RC != S_OK)
            {
                RetCode = RC;     //  The only returns the last bad error code.
            }

        }
    }

    //  RetCode = S_OK;
    return RetCode;
}
//---------------------------------------------------------------------------
//
//	Invoke the method on the given object
//
//---------------------------------------------------------------------------
HRESULT
CMethod::Invoke(
	IDispatch*	pDisp )
{
	HRESULT rc = E_FAIL;
	if ( pDisp )
	{
		// get the dispatch ID
		vector<VARIANTARG>	vargs;
		CopyVariantList(vargs, m_params);
		DISPPARAMS dp;
		dp.cArgs = vargs.size();
		dp.rgvarg = &(vargs[0]);
		dp.cNamedArgs = 0;
		dp.rgdispidNamedArgs = NULL;
		DISPID did = GetDispID(pDisp);

		VARIANT vtRes;
		::VariantInit( &vtRes );
		EXCEPINFO ei;
		UINT argErr;
		rc = pDisp->Invoke(
			did,
			IID_NULL,
			LOCALE_USER_DEFAULT,
			m_wInvokeFlags,
			&dp,
			&vtRes,
			&ei,
			&argErr );

		// print out results if you want here

		// cleanup
		::VariantClear( &vtRes );
		DeleteVariantList(vargs);
	}
	return rc;
}
Example #7
0
void CItemMulti::Multi_Create( CChar * pChar, DWORD dwKeyCode )
{
	// Create house or Ship extra stuff.
	// ARGS:
	//  dwKeyCode = set the key code for the doors/sides to this in case it's a drydocked ship.
	// NOTE: 
	//  This can only be done after the house is given location.

	const CItemBaseMulti * pMultiDef = Multi_GetDef();
	// We are top level.
	if ( pMultiDef == NULL ||
		! IsTopLevel())
		return;

	if ( dwKeyCode == UID_CLEAR )
		dwKeyCode = GetUID();

	// ??? SetTimeout( GetDecayTime()); house decay ?

	bool fNeedKey = false;
	int iQty = pMultiDef->m_Components.GetCount();
	for ( int i=0; i<iQty; i++ )
	{
		fNeedKey |= Multi_CreateComponent( (ITEMID_TYPE) pMultiDef->m_Components[i].m_id,
			pMultiDef->m_Components[i].m_dx,
			pMultiDef->m_Components[i].m_dy,
			pMultiDef->m_Components[i].m_dz,
			dwKeyCode );
	}

#if 0
	const CGrayMulti * pMultiMul = g_World.GetMultiItemDefs( GetDispID());
	if ( pMultiMul )
	{
		iQty = pMultiMul->GetItemCount();
		for ( int i=0; iQty--; i++ )
		{
			const CUOMultiItemRec * pMultiItem = pMultiMul->GetItem(i);
			ASSERT(pMultiItem);
			if ( pMultiItem->m_visible )	// client side.
				continue;
			fNeedKey |= Multi_CreateComponent( pMultiItem->GetDispID(),
				pMultiItem->m_dx,
				pMultiItem->m_dy,
				pMultiItem->m_dz,
				dwKeyCode );
		}
	}
#endif

	CItem * pKey = NULL;
	if ( fNeedKey )
	{
		// Create the key to the door.
		ITEMID_TYPE id = IsAttr(ATTR_MAGIC) ? ITEMID_KEY_MAGIC : ITEMID_KEY_COPPER ;
		pKey = CreateScript( id, pChar );
		ASSERT(pKey);
		pKey->SetType(IT_KEY);
		if ( g_Cfg.m_fAutoNewbieKeys )
			pKey->SetAttr(ATTR_NEWBIE);
		pKey->SetAttr(m_Attr&ATTR_MAGIC);
		pKey->m_itKey.m_lockUID.SetPrivateUID( dwKeyCode );
		pKey->m_uidLink = GetUID();	
	}

	Multi_GetSign();	// set the m_uidLink

	if ( pChar != NULL )
	{
		m_itShip.m_UIDCreator = pChar->GetUID();
		CItemMemory * pMemory = pChar->Memory_AddObjTypes( this, MEMORY_GUARD );

		if ( pKey )
		{
			// Put in your pack
			pChar->GetPackSafe()->ContentAdd( pKey );

			// Put dupe key in the bank.
			pKey = CreateDupeItem( pKey );
			pChar->GetBank()->ContentAdd( pKey );
			pChar->SysMessage( "The duplicate key is in your bank account" );
		}
	}
	else
	{
		// Just put the key on the front step ?
		DEBUG_CHECK( 0 );
	}
}
Example #8
0
bool CChar::Use_Item_Web( CItem * pItemWeb )
{
	ADDTOCALLSTACK("CChar::Use_Item_Web");
	// IT_WEB
	// IT_EQ_STUCK
	// Try to break out of the web.
	// Or just try to damage it.
	//
	// RETURN: true = held in place.
	//  false = walk thru it.

	if ( GetDispID() == CREID_GIANT_SPIDER || !pItemWeb || !pItemWeb->IsTopLevel() || IsStatFlag(STATF_DEAD|STATF_Insubstantial) || IsPriv(PRIV_GM) )
		return false;	// just walk through it

	// Try to break it.
	int iStr = pItemWeb->m_itWeb.m_Hits_Cur;
	if ( iStr == 0 )
		iStr = pItemWeb->m_itWeb.m_Hits_Cur = 60 + Calc_GetRandVal(250);

	// Since broken webs become spider silk, we should get out of here now if we aren't in a web.
	CItem *pFlag = LayerFind(LAYER_FLAG_Stuck);
	if ( CanMove(pItemWeb, false) )
	{
		if ( pFlag )
			pFlag->Delete();
		return false;
	}

	if ( pFlag )
	{
		if ( pFlag->IsTimerSet() )	// don't allow me to try to damage it too often
			return true;
	}

	int iDmg = pItemWeb->OnTakeDamage(Stat_GetAdjusted(STAT_STR), this);
	switch ( iDmg )
	{
		case 0:			// damage blocked
		case 1:			// web survived
		default:		// unknown
			if ( GetTopPoint() == pItemWeb->GetTopPoint() )		// is character still stuck on the web?
				break;

		case 2:			// web turned into silk
		case INT_MAX:	// web destroyed
			if ( pFlag )
				pFlag->Delete();
			return false;
	}

	// Stuck in it still.
	if ( !pFlag )
	{
		if ( iDmg < 0 )
			return false;

		// First time message.
		pFlag = CItem::CreateBase(ITEMID_WEB1_1);
		ASSERT(pFlag);
		pFlag->SetAttr(ATTR_DECAY);
		pFlag->SetType(IT_EQ_STUCK);
		pFlag->m_uidLink = pItemWeb->GetUID();
		pFlag->SetTimeout(pItemWeb->GetTimerDAdjusted());
		LayerAdd(pFlag, LAYER_FLAG_Stuck);
	}
	else
	{
		if ( iDmg < 0 )
		{
			pFlag->Delete();
			return false;
		}
		SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SWEB_STUCK), pItemWeb->GetName());
	}

	return true;
}
Example #9
0
int CChar::Do_Use_Item(CItem *pItem, bool fLink)
{
	ADDTOCALLSTACK("CChar::Do_Use_Item");
	if (!pItem)
		return false;

	if (m_pNPC && (IsTrigUsed(TRIGGER_DCLICK) ||
	               IsTrigUsed(TRIGGER_ITEMDCLICK)))        // for players, DClick was called before this function
	{
		if (pItem->OnTrigger(ITRIG_DCLICK, this) == TRIGRET_RET_TRUE)
			return false;
	}

	CItemSpawn *pSpawn = static_cast<CItemSpawn *>(pItem->m_uidSpawnItem.ItemFind());
	if (pSpawn)
		pSpawn->DelObj(pItem->GetUID());    // remove this item from it's spawn when DClicks it

	int fAction = true;
	switch(pItem->GetType()) {
		case IT_ITEM_STONE: {
			// Give them this item
			if (pItem->m_itItemStone.m_wAmount == USHRT_MAX) {
				SysMessageDefault(DEFMSG_MSG_IT_IS_DEAD);
				return true;
			}
			if (pItem->m_itItemStone.m_wRegenTime) {
				if (pItem->IsTimerSet()) {
					SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_MSG_STONEREG_TIME), pItem->GetTimerDiff() / TICK_PER_SEC);
					return true;
				}
				pItem->SetTimeout(pItem->m_itItemStone.m_wRegenTime * TICK_PER_SEC);
			}
			ItemBounce(CItem::CreateTemplate(pItem->m_itItemStone.m_ItemID, GetPackSafe(), this));
			if (pItem->m_itItemStone.m_wAmount != 0) {
				pItem->m_itItemStone.m_wAmount--;
				if (pItem->m_itItemStone.m_wAmount == 0)
					pItem->m_itItemStone.m_wAmount = USHRT_MAX;
			}
			return true;
		}

		case IT_SEED:
			return Use_Seed(pItem, NULL);

		case IT_BEDROLL:
			return Use_BedRoll(pItem);

		case IT_KINDLING:
			return Use_Kindling(pItem);

		case IT_SPINWHEEL: {
			if (fLink)
				return false;

			// Just make them spin
			pItem->SetAnim(static_cast<ITEMID_TYPE>(pItem->GetID() + 1), 2 * TICK_PER_SEC);
			SysMessageDefault(DEFMSG_ITEMUSE_SPINWHEEL);
			return true;
		}

		case IT_TRAIN_DUMMY: {
			if (fLink)
				return false;

			Use_Train_Dummy(pItem, true);
			return true;
		}

		case IT_TRAIN_PICKPOCKET: {
			if (fLink)
				return false;

			Use_Train_PickPocketDip(pItem, true);
			return true;
		}

		case IT_ARCHERY_BUTTE: {
			if (fLink)
				return false;

			Use_Train_ArcheryButte(pItem, true);
			return true;
		}

		case IT_LOOM: {
			if (fLink)
				return false;

			SysMessageDefault(DEFMSG_ITEMUSE_LOOM);
			return true;
		}

		case IT_BEE_HIVE: {
			if (fLink)
				return false;

			// Get honey from it
			ITEMID_TYPE id = ITEMID_NOTHING;
			if (!pItem->m_itBeeHive.m_honeycount)
				SysMessageDefault(DEFMSG_ITEMUSE_BEEHIVE);
			else {
				switch(Calc_GetRandVal(3)) {
					case 1:
						id = ITEMID_JAR_HONEY;
						break;
					case 2:
						id = ITEMID_BEE_WAX;
						break;
				}
			}
			if (id) {
				ItemBounce(CItem::CreateScript(id, this));
				pItem->m_itBeeHive.m_honeycount--;
			}
			else {
				SysMessageDefault(DEFMSG_ITEMUSE_BEEHIVE_STING);
				OnTakeDamage(Calc_GetRandVal(5), this, DAMAGE_POISON | DAMAGE_GENERAL);
			}
			pItem->SetTimeout(15 * 60 * TICK_PER_SEC);
			return true;
		}

		case IT_MUSICAL: {
			if (!Skill_Wait(SKILL_MUSICIANSHIP)) {
				m_Act_Targ = pItem->GetUID();
				Skill_Start(SKILL_MUSICIANSHIP);
			}
			break;
		}

		case IT_CROPS:
		case IT_FOLIAGE: {
			// Pick cotton/hay/etc
			fAction = pItem->Plant_Use(this);
			break;
		}

		case IT_FIGURINE: {
			// Create the creature here
			if (Use_Figurine(pItem) != NULL)
				pItem->Delete();
			return true;
		}

		case IT_TRAP:
		case IT_TRAP_ACTIVE: {
			// Activate the trap (plus any linked traps)
			int iDmg = pItem->Use_Trap();
			if (CanTouch(pItem->GetTopLevelObj()->GetTopPoint()))
				OnTakeDamage(iDmg, NULL, DAMAGE_HIT_BLUNT | DAMAGE_GENERAL);
			break;
		}

		case IT_SWITCH: {
			// Switches can be linked to gates and doors and such.
			// Flip the switch graphic.
			pItem->SetSwitchState();
			break;
		}

		case IT_PORT_LOCKED:
			if (!fLink && !IsPriv(PRIV_GM)) {
				SysMessageDefault(DEFMSG_ITEMUSE_PORT_LOCKED);
				return true;
			}
		case IT_PORTCULIS:
			// Open a metal gate vertically
			pItem->Use_Portculis();
			break;

		case IT_DOOR_LOCKED:
			if (!ContentFindKeyFor(pItem)) {
				SysMessageDefault(DEFMSG_MSG_KEY_DOORLOCKED);
				if (!pItem->IsTopLevel())
					return false;
				if (pItem->IsAttr(ATTR_MAGIC))    // show it's magic face
				{
					ITEMID_TYPE id = (GetDispID() & DOOR_NORTHSOUTH) ? ITEMID_DOOR_MAGIC_SI_NS
					                                                 : ITEMID_DOOR_MAGIC_SI_EW;
					CItem *pFace = CItem::CreateBase(id);
					ASSERT(pFace);
					pFace->MoveToDecay(pItem->GetTopPoint(), 4 * TICK_PER_SEC);
				}
				if (!IsPriv(PRIV_GM))
					return true;
			}
		case IT_DOOR_OPEN:
		case IT_DOOR: {
			bool fOpen = pItem->Use_DoorNew(fLink);
			if (fLink || !fOpen)    // don't link if we are just closing the door
				return true;
		}
			break;

		case IT_SHIP_PLANK: {
			// Close the plank if I'm inside the ship
			if (m_pArea->IsFlag(REGION_FLAG_SHIP) && m_pArea->GetResourceID() == pItem->m_uidLink) {
				if (pItem->m_itShipPlank.m_itSideType == IT_SHIP_SIDE_LOCKED && !ContentFindKeyFor(pItem)) {
					SysMessageDefault(DEFMSG_ITEMUSE_SHIPSIDE);
					return true;
				}
				return pItem->Ship_Plank(false);
			}
			else if (pItem->IsTopLevel()) {
				// Teleport to plank if I'm outside the ship
				CPointMap pntTarg = pItem->GetTopPoint();
				pntTarg.m_z++;
				Spell_Teleport(pntTarg, true, false, false);
			}
			return true;
		}

		case IT_SHIP_SIDE_LOCKED:
			if (!ContentFindKeyFor(pItem)) {
				SysMessageDefault(DEFMSG_ITEMUSE_SHIPSIDE);
				return true;
			}
		case IT_SHIP_SIDE:
			// Open the plank
			pItem->Ship_Plank(true);
			return true;

		case IT_GRAIN:
		case IT_GRASS:
		case IT_GARBAGE:
		case IT_FRUIT:
		case IT_FOOD:
		case IT_FOOD_RAW:
		case IT_MEAT_RAW: {
			if (fLink)
				return false;

			Use_Eat(pItem);
			return true;
		}

		case IT_POTION:
		case IT_DRINK:
		case IT_PITCHER:
		case IT_WATER_WASH:
		case IT_BOOZE: {
			if (fLink)
				return false;

			Use_Drink(pItem);
			return true;
		}

		case IT_LIGHT_OUT:        // can the light be lit?
		case IT_LIGHT_LIT:        // can the light be doused?
			fAction = pItem->Use_Light();
			break;

		case IT_CLOTHING:
		case IT_ARMOR:
		case IT_ARMOR_LEATHER:
		case IT_SHIELD:
		case IT_WEAPON_MACE_CROOK:
		case IT_WEAPON_MACE_PICK:
		case IT_WEAPON_MACE_SMITH:
		case IT_WEAPON_MACE_SHARP:
		case IT_WEAPON_SWORD:
		case IT_WEAPON_FENCE:
		case IT_WEAPON_BOW:
		case IT_WEAPON_AXE:
		case IT_WEAPON_XBOW:
		case IT_WEAPON_MACE_STAFF:
		case IT_JEWELRY:
		case IT_WEAPON_THROWING: {
			if (fLink)
				return false;

			return ItemEquip(pItem);
		}

		case IT_WEB: {
			if (fLink)
				return false;

			Use_Item_Web(pItem);
			return true;
		}

		case IT_SPY_GLASS: {
			if (fLink)
				return false;

			// Spyglass will tell you the moon phases
			static LPCTSTR const sm_sPhases[8] =
					{
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M1),
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M2),
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M3),
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M4),
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M5),
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M6),
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M7),
							g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_M8)
					};
			SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_TR), sm_sPhases[g_World.GetMoonPhase(false)]);
			SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SPYGLASS_FE), sm_sPhases[g_World.GetMoonPhase(true)]);

			if (m_pArea && m_pArea->IsFlag(REGION_FLAG_SHIP))
				ObjMessage(pItem->Use_SpyGlass(this), this);
			return true;
		}

		case IT_SEXTANT: {
			if (fLink)
				return false;

			if ((GetTopPoint().m_map <= 1) && (GetTopPoint().m_x > UO_SIZE_X_REAL))    // dungeons and T2A lands
				ObjMessage(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SEXTANT_T2A), this);
			else {
				TCHAR *pszMsg = Str_GetTemp();
				sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SEXTANT), m_pArea->GetName(),
				        pItem->Use_Sextant(GetTopPoint()));
				ObjMessage(pszMsg, this);
			}
			return true;
		}

		default:
			fAction = false;
	}
	return fAction | MASK_RETURN_FOLLOW_LINKS;
}
Example #10
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 );
}
Example #11
0
CPointMap CItemContainer::GetRandContainerLoc() const
{
	ADDTOCALLSTACK("CItemContainer::GetRandContainerLoc");
	// Max/Min Container Sizes.

	static const struct // we can probably get this from MUL file some place.
	{
		GUMP_TYPE m_gump;
		WORD m_minx;
		WORD m_miny;
		WORD m_maxx;
		WORD m_maxy;
	} sm_ContSize[] =
	{
		{ GUMP_RESERVED, 40, 50, 100, 100 },		// default.
		{ GUMP_CORPSE, 20, 85, 80, 185 },
		{ GUMP_PACK, 44, 65, 142, 150 },			// Open backpack
		{ GUMP_BAG, 29, 34, 93, 119 },				// Leather Bag
		{ GUMP_BARREL, 33, 36, 98, 139 },			// Barrel
		{ GUMP_BASKET_SQ, 19, 47, 138, 114 },		// Square picknick Basket
		{ GUMP_BOX_WOOD, 16, 51, 140, 115 },		// small wood box with a lock
		{ GUMP_BASKET_RO, 33, 36,  98, 134 },		// Round Basket
		{ GUMP_CHEST_GO_SI, 18, 105, 118, 169 },	// Gold and Silver Chest.
		{ GUMP_BOX_WOOD_OR, 16, 51, 140, 115 },		// Small wood box (ornate)(no lock)
		{ GUMP_CRATE, 20, 10, 126, 91 },			// Wood Crate
		{ GUMP_DRAWER_DK, 16, 17, 110, 85 },
		{ GUMP_CHEST_WO_GO, 18, 105, 118, 169 },	// Wood with gold trim.
		{ GUMP_CHEST_SI, 18, 105, 118, 169 },		// silver chest.
		{ GUMP_BOX_GO_LO, 16, 51, 140, 115 },		// Gold/Brass box with a lock.
		{ GUMP_SHIP_HOLD, 46, 74, 152, 175 },
		{ GUMP_BOOK_SHELF, 76, 12, 96, 59 },
		{ GUMP_CABINET_DK, 24, 96, 91, 143 },
		{ GUMP_CABINET_LT, 24, 96, 91, 143 },
		{ GUMP_DRAWER_LT, 16, 17, 110, 85 },
		{ GUMP_GIFT_BOX, 35, 10, 155, 85 },
		{ GUMP_ARMOIRE_RED, 10, 10, 150, 95 },
		{ GUMP_ARMOIRE_MAPLE, 10, 10, 150, 95 },
		{ GUMP_ARMOIRE_CHERRY, 10, 10, 150, 95 },
		{ GUMP_BASKET_TALL, 10, 10, 116, 71 },
		{ GUMP_CHEST_WOOD_PLAIN, 10, 10, 150, 95 },
		{ GUMP_CHEST_WOOD_GILDED, 10, 10, 150, 95 },
		{ GUMP_CHEST_WOOD_ORNATE, 10, 10, 150, 95 },
		{ GUMP_TALL_CABINET, 10, 10, 150, 95 },
		{ GUMP_CHEST_WOOD_FINISH, 10, 10, 150, 95 },
		{ GUMP_HEART_SHAPED, 56, 30, 102, 74},
		{ GUMP_SECURE_TRADE, 1, 1, 66, 26 },
		{ GUMP_GAME_BOARD,	 4, 10, 220, 185 },		// Chess or checker board.
		{ GUMP_GAME_BACKGAM, 4, 10, 220, 185 },
	};

	// ??? pItemDef->m_ttContainer.m_dwMinXY to m_dwMaxXY
	// Get a random location in the container.

	CItemBase * pItemDef = Item_GetDef();
	GUMP_TYPE gump = pItemDef->IsTypeContainer();

	// check for custom values in TDATA3/TDATA4
	if ( pItemDef->m_ttContainer.m_dwMaxXY )
	{
		int tmp_MinX = (pItemDef->m_ttContainer.m_dwMinXY & 0xFFFF0000) >> 16;
		int tmp_MinY = (pItemDef->m_ttContainer.m_dwMinXY & 0xFFFF);
		int tmp_MaxX = (pItemDef->m_ttContainer.m_dwMaxXY & 0xFFFF0000) >> 16;
		int tmp_MaxY = (pItemDef->m_ttContainer.m_dwMaxXY & 0xFFFF);
		DEBUG_WARN(("Custom container gump id %d for 0%x\n", gump, GetDispID()));
		return( CPointMap(
			static_cast<WORD>(tmp_MinX + Calc_GetRandVal(tmp_MaxX - tmp_MinX)),
			static_cast<WORD>(tmp_MinY + Calc_GetRandVal(tmp_MaxY - tmp_MinY)),
			0 ));
	}