bool CChar::NPC_PetSetOwner( CChar * pChar )
{
	ADDTOCALLSTACK("CChar::NPC_PetSetOwner");
	// m_pNPC may not be set yet if this is a conjured creature.
	if ( m_pPlayer || pChar == this || pChar == NULL )
		return false;

	CChar * pOwner = NPC_PetGetOwner();
	if ( pOwner == pChar )
		return false;

	NPC_PetClearOwners();	// clear previous owner before set the new owner
	m_ptHome.InitPoint();	// no longer homed
	CItemSpawn * pSpawn = static_cast<CItemSpawn*>( m_uidSpawnItem.ItemFind() );
	if ( pSpawn )
		pSpawn->DelObj( GetUID() );
	Memory_AddObjTypes(pChar, MEMORY_IPET);
	NPC_Act_Follow();
	if ( NPC_IsVendor() )
	{
		// Clear my cash total.
		CItemContainer * pBank = GetBank();
		pBank->m_itEqBankBox.m_Check_Amount = 0;
		StatFlag_Set(STATF_INVUL);
	}

	if ( IsSetOF(OF_PetSlots) )
		pChar->FollowersUpdate(this, static_cast<short>(maximum(1, GetDefNum("FOLLOWERSLOTS", true, true))));

	return true;
}
Beispiel #2
0
void CChar::NPC_PetClearOwners(bool bResendTooltip)
{
	ADDTOCALLSTACK("CChar::NPC_PetClearOwners");
	CChar *pOwner = NPC_PetGetOwner();
	Memory_ClearTypes(MEMORY_IPET|MEMORY_FRIEND);

	if ( m_pNPC )
		m_pNPC->m_bonded = 0;	// pets without owner cannot be bonded

	if ( NPC_IsVendor() )
	{
		StatFlag_Clear(STATF_INVUL);
		if ( pOwner )	// give back to NPC owner all the stuff we are trying to sell
		{
			CItemContainer *pBankVendor = GetContainerCreate(LAYER_BANKBOX);
			CItemContainer *pBankOwner = pOwner->GetContainerCreate(LAYER_BANKBOX);
			pOwner->AddGoldToPack(pBankVendor->m_itEqBankBox.m_Check_Amount, pBankOwner);
			pBankVendor->m_itEqBankBox.m_Check_Amount = 0;

			for ( size_t i = 0; i < COUNTOF(sm_VendorLayers); i++ )
			{
				CItemContainer *pCont = GetContainerCreate(sm_VendorLayers[i]);
				if ( !pCont )
					continue;

				CItem *pItemNext = NULL;
				for ( CItem *pItem = pCont->GetContentHead(); pItem != NULL; pItem = pItemNext )
				{
					pItemNext = pItem->GetNext();
					pBankOwner->ContentAdd(pItem);
				}
			}
		}
	}

	if ( IsStatFlag(STATF_Ridden) )
	{
		CChar *pCharRider = Horse_GetMountChar();
		if ( pCharRider )
			pCharRider->Horse_UnMount();
	}

	if ( pOwner )
	{
		if ( IsSetOF(OF_PetSlots) )
			pOwner->FollowersUpdate(this, static_cast<short>(-maximum(1, GetDefNum("FOLLOWERSLOTS", true))));
		if ( bResendTooltip )
			ResendTooltip();
	}
}
Beispiel #3
0
void CClient::addSysMessage(lpctstr pszMsg) // System message (In lower left corner)
{
	ADDTOCALLSTACK("CClient::addSysMessage");
	if ( !pszMsg )
		return;

	if ( IsSetOF(OF_Flood_Protection) && ( GetPrivLevel() <= PLEVEL_Player )  )
	{
		if ( !strcmpi(pszMsg, m_zLastMessage) )
			return;

		if ( strlen(pszMsg) < SCRIPT_MAX_LINE_LEN )
			strcpy(m_zLastMessage, pszMsg);
	}

	addBarkParse(pszMsg, NULL, HUE_TEXT_DEF, TALKMODE_SYSTEM);
}
Beispiel #4
0
bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
{
	ADDTOCALLSTACK("CClient::Cmd_Use_Item");
	// Assume we can see the target.
	// called from Event_DoubleClick

	if ( !pItem )
		return false;

	if ( pItem->m_Can & CAN_I_FORCEDC )
		fTestTouch = false;

	if ( fTestTouch )
	{
		if ( !fScript )
		{
			CItemContainer *pContainer = dynamic_cast<CItemContainer *>(pItem->GetParent());
			if ( pContainer )
			{
				// protect from ,snoop - disallow picking from not opened containers
				bool isInOpenedContainer = false;
				if ( pContainer->GetType() == IT_EQ_TRADE_WINDOW )
					isInOpenedContainer = true;
				else
				{
					CClient::OpenedContainerMap_t::iterator itContainerFound = m_openedContainers.find(pContainer->GetUID().GetPrivateUID());
					if ( itContainerFound != m_openedContainers.end() )
					{
						DWORD dwTopContainerUID = (((*itContainerFound).second).first).first;
						DWORD dwTopMostContainerUID = (((*itContainerFound).second).first).second;
						CPointMap ptOpenedContainerPosition = ((*itContainerFound).second).second;
						const CObjBaseTemplate *pObjTop = pItem->GetTopLevelObj();
						const CObjBase *pObjParent = pContainer->GetParentObj();

						DWORD dwTopContainerUID_ToCheck = 0;
						if ( pObjParent )
							dwTopContainerUID_ToCheck = pObjParent->GetUID().GetPrivateUID();
						else
							dwTopContainerUID_ToCheck = pObjTop->GetUID().GetPrivateUID();

						if ( (dwTopMostContainerUID == pObjTop->GetUID().GetPrivateUID()) && (dwTopContainerUID == dwTopContainerUID_ToCheck) )
						{
							if ( pObjTop->IsChar() )
							{
								// probably a pickup check from pack if pCharTop != this?
								isInOpenedContainer = true;
							}
							else
							{
								const CItem *pItemTop = static_cast<const CItem *>(pObjTop);
								if ( pItemTop && (pItemTop->IsType(IT_SHIP_HOLD) || pItemTop->IsType(IT_SHIP_HOLD_LOCK)) && (pItemTop->GetTopPoint().GetRegion(REGION_TYPE_MULTI) == m_pChar->GetTopPoint().GetRegion(REGION_TYPE_MULTI)) )
									isInOpenedContainer = true;
								else if ( ptOpenedContainerPosition.GetDist(pObjTop->GetTopPoint()) <= 3 )
									isInOpenedContainer = true;
							}
						}
					}
				}

				if ( !isInOpenedContainer )
				{
					SysMessageDefault(DEFMSG_REACH_UNABLE);
					return false;
				}
			}
		}

		// CanTouch handles priv level compares for chars
		if ( !m_pChar->CanUse(pItem, false) )
		{
			if ( !m_pChar->CanTouch(pItem) )
				SysMessage((m_pChar->IsStatFlag(STATF_DEAD)) ? g_Cfg.GetDefaultMsg(DEFMSG_REACH_GHOST) : g_Cfg.GetDefaultMsg(DEFMSG_REACH_FAIL));
			else
				SysMessageDefault(DEFMSG_REACH_UNABLE);

			return false;
		}
	}

	if ( IsTrigUsed(TRIGGER_DCLICK) || IsTrigUsed(TRIGGER_ITEMDCLICK) )
	{
		if ( pItem->OnTrigger(ITRIG_DCLICK, m_pChar) == TRIGRET_RET_TRUE )
			return true;
	}

	CItemBase *pItemDef = pItem->Item_GetDef();
	bool bIsEquipped = pItem->IsItemEquipped();
	if ( pItemDef->IsTypeEquippable() && !bIsEquipped && pItemDef->GetEquipLayer() )
	{
		bool bMustEquip = true;
		if ( pItem->IsTypeSpellbook() )
			bMustEquip = false;
		else if ( (pItem->IsType(IT_LIGHT_OUT) || pItem->IsType(IT_LIGHT_LIT)) && !pItem->IsItemInContainer() )
			bMustEquip = false;

		if ( bMustEquip )
		{
			if ( !m_pChar->CanMove(pItem) )
				return false;

			if ( !m_pChar->CanCarry(pItem) )
			{
				SysMessageDefault(DEFMSG_MSG_HEAVY);
				return false;
			}

			if ( !m_pChar->ItemEquip(pItem, NULL, true) )
				return false;
		}
	}

	CItemSpawn *pSpawn = static_cast<CItemSpawn *>(pItem->m_uidSpawnItem.ItemFind());	// remove this item from its spawn when players DClick it from ground, no other way to take it out.
	if ( pSpawn )
		pSpawn->DelObj(pItem->GetUID());

	SetTargMode();
	m_Targ_PrvUID = m_Targ_UID;
	m_Targ_UID = pItem->GetUID();
	m_tmUseItem.m_pParent = pItem->GetParent();		// store item location to check later if it was not moved

	// Use types of items (specific to client)
	switch ( pItem->GetType() )
	{
		case IT_TRACKER:
		{
			if ( !m_pChar->Skill_Tracking(pItem->m_uidLink) )
			{
				if ( pItem->m_uidLink.IsValidUID() )
					SysMessageDefault(DEFMSG_TRACKING_UNABLE);
				addTarget(CLIMODE_TARG_LINK, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_TRACKER_ATTUNE));
			}
			return true;
		}

		case IT_SHAFT:
		case IT_FEATHER:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_bolts");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_bolts"));
		}

		case IT_FISH_POLE:	// Just be near water ?
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_FISHING_PROMT), true);
			return true;

		case IT_DEED:
			addTargetDeed(pItem);
			return true;

		case IT_EQ_BANK_BOX:
		case IT_EQ_VENDOR_BOX:
			if ( !fScript )
				g_Log.Event(LOGL_WARN|LOGM_CHEAT, "%lx:Cheater '%s' is using 3rd party tools to open bank box\n", GetSocketID(), m_pAccount->GetName());
			return false;

		case IT_CONTAINER_LOCKED:
		case IT_SHIP_HOLD_LOCK:
			if ( !m_pChar->GetContainerCreate(LAYER_PACK)->ContentFindKeyFor(pItem) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_LOCKED);
				if ( !IsPriv(PRIV_GM) )
					return false;
			}

		case IT_CORPSE:
		case IT_SHIP_HOLD:
		case IT_CONTAINER:
		case IT_TRASH_CAN:
		{
			CItemContainer *pPack = static_cast<CItemContainer *>(pItem);
			if ( !pPack )
				return false;

			if ( !m_pChar->Skill_Snoop_Check(pPack) )
			{
				if ( !addContainerSetup(pPack) )
					return false;
			}

			const CItemCorpse *pCorpseItem = static_cast<const CItemCorpse *>(pPack);
			if ( m_pChar->CheckCorpseCrime(pCorpseItem, true, true) )
				SysMessageDefault(DEFMSG_LOOT_CRIMINAL_ACT);
			return true;
		}

		case IT_GAME_BOARD:
		{
			if ( !pItem->IsTopLevel() )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_GAMEBOARD_FAIL);
				return false;
			}
			CItemContainer *pBoard = static_cast<CItemContainer *>(pItem);
			ASSERT(pBoard);
			pBoard->Game_Create();
			addContainerSetup(pBoard);
			return true;
		}

		case IT_BBOARD:
			addBulletinBoard(static_cast<CItemContainer *>(pItem));
			return true;

		case IT_SIGN_GUMP:
		{
			GUMP_TYPE gumpid = pItemDef->m_ttContainer.m_gumpid;
			if ( !gumpid )
				return false;
			addGumpTextDisp(pItem, gumpid, pItem->GetName(), pItem->IsIndividualName() ? pItem->GetName() : NULL);
			return true;
		}

		case IT_BOOK:
		case IT_MESSAGE:
		{
			if ( !addBookOpen(pItem) )
				SysMessageDefault(DEFMSG_ITEMUSE_BOOK_FAIL);
			return true;
		}

		case IT_STONE_GUILD:
		case IT_STONE_TOWN:
			return true;

		case IT_POTION:
		{
			if ( !m_pChar->CanMove(pItem) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_POTION_FAIL);
				return false;
			}
			if ( RES_GET_INDEX(pItem->m_itPotion.m_Type) == SPELL_Poison )
			{
				// If we click directly on poison potion, we will drink poison and get ill.
				// To use it on Poisoning skill, the skill will request to target the potion.
				m_pChar->OnSpellEffect(SPELL_Poison, m_pChar, pItem->m_itSpell.m_spelllevel, NULL);
				return true;
			}
			if ( RES_GET_INDEX(pItem->m_itPotion.m_Type) == SPELL_Explosion )
			{
				// Throw explosion potion
				if ( !m_pChar->ItemPickup(pItem, 1) )	// put the potion in our hand
					return false;

				pItem->m_itPotion.m_tick = 4;		// countdown to explode
				pItem->m_itPotion.m_ignited = 1;	// ignite it
				pItem->m_uidLink = m_pChar->GetUID();
				pItem->SetTimeout(TICK_PER_SEC);
				m_tmUseItem.m_pParent = pItem->GetParent();
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_POTION_TARGET), true, true, pItem->m_itPotion.m_tick * TICK_PER_SEC);
				return true;
			}
			m_pChar->Use_Drink(pItem);
			return true;
		}

		case IT_ANIM_ACTIVE:
			SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_ITEM_IN_USE));
			return false;

		case IT_CLOCK:
			addObjMessage(m_pChar->GetTopSector()->GetLocalGameTime(), pItem);
			return true;

		case IT_SPAWN_ITEM:
		case IT_SPAWN_CHAR:
		{
			pSpawn = static_cast<CItemSpawn *>(pItem);
			if ( !pSpawn )
				return false;

			if ( pSpawn->m_currentSpawned )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_SPAWN_NEG);
				pSpawn->KillChildren();		// Removing existing objects spawned from it ( RESET ).
			}
			else
			{
				SysMessageDefault(DEFMSG_ITEMUSE_SPAWN_RESET);
				pSpawn->OnTick(true);		// Forcing the spawn to work and create some objects ( START ).
			}
			return true;
		}

		case IT_SHRINE:
		{
			if ( m_pChar->OnSpellEffect(SPELL_Resurrection, m_pChar, 1000, pItem) )
				return true;
			SysMessageDefault(DEFMSG_ITEMUSE_SHRINE);
			return true;
		}

		case IT_SHIP_TILLER:
			pItem->Speak(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_TILLERMAN), HUE_TEXT_DEF, TALKMODE_SAY, FONT_NORMAL);
			return true;

		case IT_WAND:
		case IT_SCROLL:
		{
			SPELL_TYPE spell = static_cast<SPELL_TYPE>(RES_GET_INDEX(pItem->m_itWeapon.m_spell));
			CSpellDef *pSpellDef = g_Cfg.GetSpellDef(spell);
			if ( !pSpellDef )
				return false;

			if ( IsSetMagicFlags(MAGICF_PRECAST) && !pSpellDef->IsSpellType(SPELLFLAG_NOPRECAST) )
			{
				int skill;
				if ( !pSpellDef->GetPrimarySkill(&skill, NULL) )
					return false;

				m_tmSkillMagery.m_Spell = spell;	// m_atMagery.m_Spell
				m_pChar->m_atMagery.m_Spell = spell;
				m_pChar->Skill_Start(static_cast<SKILL_TYPE>(skill));
				return true;
			}
			return Cmd_Skill_Magery(spell, pItem);
		}

		case IT_RUNE:
		{
			if ( !m_pChar->CanMove(pItem, true) )
				return false;
			addPromptConsole(CLIMODE_PROMPT_NAME_RUNE, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_RUNE_NAME), pItem->GetUID());
			return true;
		}

		case IT_CARPENTRY:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_carpentry");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_carpentry"));
		}

		case IT_FORGE:
			// Solve for the combination of this item with another.
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_FORGE));
			return true;

		case IT_ORE:
			return m_pChar->Skill_Mining_Smelt(pItem, NULL);

		case IT_INGOT:
			return Cmd_Skill_Smith(pItem);

		case IT_KEY:
		case IT_KEYRING:
		{
			if ( pItem->GetTopLevelObj() != m_pChar && !m_pChar->IsPriv(PRIV_GM) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_KEY_FAIL);
				return false;
			}
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_KEY_PROMT), false, true);
			return true;
		}

		case IT_BANDAGE:		// SKILL_HEALING, or SKILL_VETERINARY
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_BANDAGE_PROMT), false, false);
			return true;

		case IT_BANDAGE_BLOOD:	// Clean the bandages.
		case IT_COTTON:			// use on a spinning wheel.
		case IT_WOOL:			// use on a spinning wheel.
		case IT_YARN:			// Use this on a loom.
		case IT_THREAD: 		// Use this on a loom.
		case IT_COMM_CRYSTAL:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_TARGET_PROMT), false, false);
			return true;

		case IT_CARPENTRY_CHOP:
		case IT_LOCKPICK:		// Use on a locked thing.
		case IT_SCISSORS:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_TARGET_PROMT), false, true);
			return true;

		case IT_WEAPON_MACE_PICK:
			if ( bIsEquipped || !IsSetOF(OF_NoDClickTarget) )
			{
				// Mine at the location
				TCHAR *pszTemp = Str_GetTemp();
				sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_MACEPICK_TARG), pItem->GetName());
				addTarget(CLIMODE_TARG_USE_ITEM, pszTemp, true, true);
				return true;
			}

		case IT_WEAPON_SWORD:
		case IT_WEAPON_FENCE:
		case IT_WEAPON_AXE:
		case IT_WEAPON_MACE_SHARP:
		case IT_WEAPON_MACE_STAFF:
		case IT_WEAPON_MACE_SMITH:
		{
			if ( bIsEquipped || !IsSetOF(OF_NoDClickTarget) )
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_WEAPON_PROMT), false, true);
			return true;
		}

		case IT_WEAPON_MACE_CROOK:
			if ( bIsEquipped || !IsSetOF(OF_NoDClickTarget) )
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CROOK_PROMT), false, true);
			return true;

		case IT_FISH:
			SysMessageDefault(DEFMSG_ITEMUSE_FISH_FAIL);
			return true;

		case IT_TELESCOPE:
			SysMessageDefault(DEFMSG_ITEMUSE_TELESCOPE);
			return true;

		case IT_MAP:
			addDrawMap(static_cast<CItemMap *>(pItem));
			return true;

		case IT_CANNON_BALL:
		{
			TCHAR *pszTemp = Str_GetTemp();
			sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CBALL_PROMT), pItem->GetName());
			addTarget(CLIMODE_TARG_USE_ITEM, pszTemp);
			return true;
		}

		case IT_CANNON_MUZZLE:
		{
			if ( !m_pChar->CanUse(pItem, false) )
				return false;

			// Make sure the cannon is loaded.
			if ( !(pItem->m_itCannon.m_Load & 1) )
			{
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CANNON_POWDER));
				return true;
			}
			if ( !(pItem->m_itCannon.m_Load & 2) )
			{
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CANNON_SHOT));
				return true;
			}
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CANNON_TARG), false, true);
			return true;
		}

		case IT_CRYSTAL_BALL:
			// Gaze into the crystal ball.
			return true;

		case IT_SEED:
		case IT_PITCHER_EMPTY:
		{
			TCHAR *pszTemp = Str_GetTemp();
			sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_PITCHER_TARG), pItem->GetName());
			addTarget(CLIMODE_TARG_USE_ITEM, pszTemp, true);
			return true;
		}

		case IT_SPELLBOOK:
			addSpellbookOpen(pItem);
			return true;

		case IT_SPELLBOOK_NECRO:
			addSpellbookOpen(pItem, 101);
			return true;

		case IT_SPELLBOOK_PALA:
			addSpellbookOpen(pItem, 201);
			return true;

		case IT_SPELLBOOK_BUSHIDO:
			addSpellbookOpen(pItem, 401);
			return true;

		case IT_SPELLBOOK_NINJITSU:
			addSpellbookOpen(pItem, 501);
			return true;

		case IT_SPELLBOOK_ARCANIST:
			addSpellbookOpen(pItem, 601);
			return true;

		case IT_SPELLBOOK_MYSTIC:
			addSpellbookOpen(pItem, 678);
			return true;

		case IT_SPELLBOOK_BARD:
			addSpellbookOpen(pItem, 701);
			return true;

		case IT_HAIR_DYE:
		{
			if ( !m_pChar->LayerFind(LAYER_BEARD) && !m_pChar->LayerFind(LAYER_HAIR) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_DYE_NOHAIR);
				return true;
			}
			Dialog_Setup(CLIMODE_DIALOG, g_Cfg.ResourceGetIDType(RES_DIALOG, "d_hair_dye"), 0, pItem);
			return true;
		}

		case IT_DYE:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_DYE_VAT));
			return true;

		case IT_DYE_VAT:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_DYE_TARG), false, true);
			return true;

		case IT_MORTAR:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_alchemy");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_alchemy"));
		}

		case IT_CARTOGRAPHY:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_cartography");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_cartography"));
		}

		case IT_COOKING:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_cooking");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_cooking"));
		}

		case IT_TINKER_TOOLS:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_tinker");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_tinker"));
		}

		case IT_SEWING_KIT:
		{
			TCHAR *pszTemp = Str_GetTemp();
			sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SEWKIT_PROMT), pItem->GetName());
			addTarget(CLIMODE_TARG_USE_ITEM, pszTemp);
			return true;
		}

		case IT_SCROLL_BLANK:
			Cmd_Skill_Inscription();
			return true;

		default:
		{
			// An NPC could use it this way.
			if ( m_pChar->Use_Item(pItem) )
				return true;
			break;
		}
	}

	SysMessageDefault(DEFMSG_ITEMUSE_CANTTHINK);
	return false;
}
Beispiel #5
0
bool CClient::r_LoadVal( CScript & s )
{
	ADDTOCALLSTACK("CClient::r_LoadVal");
	EXC_TRY("LoadVal");
	if ( GetAccount() == NULL )
		return( false );

	LPCTSTR pszKey = s.GetKey();

	if ( s.IsKeyHead( "CTAG.", 5 ) || s.IsKeyHead( "CTAG0.", 6 ) )
	{
		bool fZero = s.IsKeyHead( "CTAG0.", 6 );
		bool fQuoted = false;

		pszKey = pszKey + (fZero ? 6 : 5);
		m_TagDefs.SetStr( pszKey, fQuoted, s.GetArgStr( &fQuoted ), fZero );
		return( true );
	}

	switch ( FindTableSorted( pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys)-1 ))
	{
		case CC_ALLMOVE:
			addRemoveAll(true, false);
			GetAccount()->TogPrivFlags( PRIV_ALLMOVE, s.GetArgStr() );
			if ( IsSetOF( OF_Command_Sysmsgs ) )
				m_pChar->SysMessage( IsPriv(PRIV_ALLMOVE)? "Allmove ON" : "Allmove OFF" );
			addPlayerView(NULL);
			break;
		case CC_ALLSHOW:
			addRemoveAll(false, true);
			GetAccount()->TogPrivFlags( PRIV_ALLSHOW, s.GetArgStr() );
			if ( IsSetOF( OF_Command_Sysmsgs ) )
				m_pChar->SysMessage( IsPriv(PRIV_ALLSHOW)? "Allshow ON" : "Allshow OFF" );
			addPlayerView(NULL);
			break;
		case CC_DEBUG:
			addRemoveAll(true, false);
			GetAccount()->TogPrivFlags( PRIV_DEBUG, s.GetArgStr() );
			if ( IsSetOF( OF_Command_Sysmsgs ) )
					m_pChar->SysMessage( IsPriv(PRIV_DEBUG)? "Debug ON" : "Debug OFF" );
			addPlayerView(NULL);
			break;
		case CC_DETAIL:
			GetAccount()->TogPrivFlags( PRIV_DETAIL, s.GetArgStr() );
			if ( IsSetOF( OF_Command_Sysmsgs ) )
					m_pChar->SysMessage( IsPriv(PRIV_DETAIL)? "Detail ON" : "Detail OFF" );
			break;
		case CC_GM: // toggle your GM status on/off
			if ( GetPrivLevel() >= PLEVEL_GM )
			{
				GetAccount()->TogPrivFlags( PRIV_GM, s.GetArgStr() );
				m_pChar->ResendTooltip();
				if ( IsSetOF( OF_Command_Sysmsgs ) )
					m_pChar->SysMessage( IsPriv(PRIV_GM)? "GM ON" : "GM OFF" );
			}
			break;
		case CC_HEARALL:
			GetAccount()->TogPrivFlags( PRIV_HEARALL, s.GetArgStr() );
			if ( IsSetOF( OF_Command_Sysmsgs ) )
					m_pChar->SysMessage( IsPriv(PRIV_HEARALL)? "Hearall ON" : "Hearall OFF" );
			break;
		case CC_PRIVSHOW:
			// Hide my priv title.
			if ( GetPrivLevel() >= PLEVEL_Counsel )
			{
				if ( ! s.HasArgs())
				{
					GetAccount()->TogPrivFlags( PRIV_PRIV_NOSHOW, NULL );
				}
				else if ( s.GetArgVal() )
				{
					GetAccount()->ClearPrivFlags( PRIV_PRIV_NOSHOW );
				}
				else
				{
					GetAccount()->SetPrivFlags( PRIV_PRIV_NOSHOW );
				}
				m_pChar->ResendTooltip();
				if ( IsSetOF( OF_Command_Sysmsgs ) )
					m_pChar->SysMessage( IsPriv(PRIV_PRIV_NOSHOW)? "Privshow OFF" : "Privshow ON" );
			}
			break;

		case CC_TARG:
			m_Targ_UID = s.GetArgVal();
			break;
		case CC_TARGP:
			m_Targ_p.Read( s.GetArgRaw());
			if ( !m_Targ_p.IsValidPoint() )
			{
				m_Targ_p.ValidatePoint();
				SysMessagef( "Invalid point: %s", s.GetArgStr() );
			}
			break;
		case CC_TARGPROP:
			m_Prop_UID = s.GetArgVal();
			break;
		case CC_TARGPRV:
			m_Targ_PrvUID = s.GetArgVal();
			break;
		default:
			return( false );
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Beispiel #6
0
void CChar::Use_Drink( CItem * pItem )
{
	ADDTOCALLSTACK("CChar::Use_Drink");
	// IT_POTION:
	// IT_DRINK:
	// IT_PITCHER:
	// IT_WATER_WASH:
	// IT_BOOZE:

	if ( !CanMove(pItem) )
	{
		SysMessageDefault(DEFMSG_DRINK_CANTMOVE);
		return;
	}

	const CItemBase *pItemDef = pItem->Item_GetDef();
	ITEMID_TYPE idbottle = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttDrink.m_idEmpty));

	if ( pItem->IsType(IT_BOOZE) )
	{
		// Beer wine and liquor. vary strength of effect.
		int iAlcohol = Calc_GetRandVal(4);

		CItem *pDrunkLayer = LayerFind(LAYER_FLAG_Drunk);
		if ( !pDrunkLayer )
			pDrunkLayer = Spell_Effect_Create(SPELL_Liquor, LAYER_FLAG_Drunk, 0, 5 * TICK_PER_SEC, this);

		pDrunkLayer->m_itSpell.m_spellcharges += iAlcohol;
		if ( pDrunkLayer->m_itSpell.m_spellcharges > 60 )
			pDrunkLayer->m_itSpell.m_spellcharges = 60;
	}

	if ( pItem->IsType(IT_POTION) )
	{
		// Time limit on using potions.
		if ( LayerFind(LAYER_FLAG_PotionUsed) )
		{
			SysMessageDefault(DEFMSG_DRINK_POTION_DELAY);
			return;
		}

		// Convey the effect of the potion.
		int iSkillQuality = pItem->m_itPotion.m_skillquality;
		if ( g_Cfg.m_iFeatureAOS & FEATURE_AOS_UPDATE_B )
		{
			int iEnhance = static_cast<int>(GetDefNum("EnhancePotions", false));
			if ( iEnhance )
				iSkillQuality += IMULDIV(iSkillQuality, iEnhance, 100);
		}

		OnSpellEffect(static_cast<SPELL_TYPE>(RES_GET_INDEX(pItem->m_itPotion.m_Type)), this, iSkillQuality, pItem);

		// Give me the marker that i've used a potion.
		Spell_Effect_Create(SPELL_NONE, LAYER_FLAG_PotionUsed, iSkillQuality, 15 * TICK_PER_SEC, this);
	}

	if ( pItem->IsType(IT_DRINK) && IsSetOF(OF_DrinkIsFood) )
	{
		short iRestore = 0;
		if ( pItem->m_itDrink.m_foodval )
			iRestore = static_cast<short>(pItem->m_itDrink.m_foodval);
		else
			iRestore = static_cast<short>(pItem->Item_GetDef()->GetVolume());

		if ( iRestore < 1 )
			iRestore = 1;

		if ( Stat_GetVal(STAT_FOOD) >= Stat_GetMax(STAT_FOOD) )
		{
			SysMessageDefault(DEFMSG_DRINK_FULL);
			return;
		}

		Stat_SetVal(STAT_FOOD, Stat_GetVal(STAT_FOOD) + iRestore);
		if ( pItem->m_itFood.m_poison_skill )
			SetPoison(pItem->m_itFood.m_poison_skill * 10, 1 + (pItem->m_itFood.m_poison_skill / 50), this);
	}

	//Sound(sm_DrinkSounds[Calc_GetRandVal(COUNTOF(sm_DrinkSounds))]);
	UpdateAnimate(ANIM_EAT);
	pItem->ConsumeAmount();

	// Create the empty bottle ?
	if ( idbottle != ITEMID_NOTHING )
		ItemBounce(CItem::CreateScript(idbottle, this), false);
}
Beispiel #7
0
CChar * CChar::Use_Figurine( CItem * pItem, bool bCheckFollowerSlots )
{
	ADDTOCALLSTACK("CChar::Use_Figurine");
	// NOTE: The figurine is NOT destroyed.
	bool bCreatedNewNpc = false;
	if ( !pItem )
		return NULL;

	if ( pItem->m_uidLink.IsValidUID() && pItem->m_uidLink.IsChar() && pItem->m_uidLink != GetUID() && !IsPriv(PRIV_GM) )
	{
		SysMessageDefault(DEFMSG_MSG_FIGURINE_NOTYOURS);
		return NULL;
	}

	// Create a new NPC if there's no one linked to this figurine 
	CChar *pPet = pItem->m_itFigurine.m_UID.CharFind();
	if ( !pPet )
	{
		CREID_TYPE id = pItem->m_itFigurine.m_ID;
		if ( !id )
		{
			id = CItemBase::FindCharTrack(pItem->GetID());
			if ( !id )
			{
				DEBUG_ERR(("FIGURINE id 0%x, no creature\n", pItem->GetDispID()));
				return NULL;
			}
		}
		bCreatedNewNpc = true;
		pPet = CreateNPC(id);
		ASSERT(pPet);
		pPet->SetName(pItem->GetName());
		if ( pItem->GetHue() )
		{
			pPet->m_prev_Hue = pItem->GetHue();
			pPet->SetHue(pItem->GetHue());
		}
	}

	if ( bCheckFollowerSlots && IsSetOF(OF_PetSlots) )
	{
		if ( !FollowersUpdate(pPet, static_cast<short>(maximum(1, pPet->GetDefNum("FOLLOWERSLOTS", true, true))), true) )
		{
			SysMessageDefault(DEFMSG_PETSLOTS_TRY_CONTROL);
			if ( bCreatedNewNpc )
				pPet->Delete();
			return NULL;
		}
	}

	if ( pPet->IsDisconnected() )
		pPet->StatFlag_Clear(STATF_Ridden);		// pull the creature out of IDLE space

	pItem->m_itFigurine.m_UID.InitUID();
	pPet->m_dirFace = m_dirFace;
	pPet->NPC_PetSetOwner(this);
	pPet->MoveToChar(pItem->GetTopLevelObj()->GetTopPoint());
	pPet->Update();
	pPet->Skill_Start(SKILL_NONE);	// was NPCACT_RIDDEN
	pPet->SoundChar(CRESND_RAND1);
	return pPet;
}
bool CChar::NPC_OnHearPetCmdTarg( int iCmd, CChar *pSrc, CObjBase *pObj, const CPointMap &pt, LPCTSTR pszArgs )
{
	ADDTOCALLSTACK("CChar::NPC_OnHearPetCmdTarg");
	// Pet commands that required a target.

	if ( m_fIgnoreNextPetCmd )
	{
		m_fIgnoreNextPetCmd = false;
		return false;
	}

	switch ( iCmd )
	{
		case PC_FOLLOW:
		case PC_STAY:
		case PC_STOP:
		{
			// Pet friends can use only these commands
			if ( Memory_FindObjTypes(pSrc, MEMORY_FRIEND) )
				break;
		}
		default:
		{
			// All others commands are avaible only to pet owner
			if ( !NPC_IsOwnedBy(pSrc, true) )
				return false;
		}
	}

	if ( IsStatFlag(STATF_DEAD) )
	{
		// Bonded NPCs still placed on world even when dead.
		// They can listen to commands, but not to these commands below
		if ( iCmd == PC_GUARD || iCmd == PC_GUARD_ME || iCmd == PC_ATTACK || iCmd == PC_KILL || iCmd == PC_TRANSFER || iCmd == PC_DROP || iCmd == PC_DROP_ALL )
			return true;
	}

	bool bSuccess = false;
	CItem *pItemTarg = dynamic_cast<CItem *>(pObj);
	CChar *pCharTarg = dynamic_cast<CChar *>(pObj);

	switch ( iCmd )
	{
		case PC_ATTACK:
		case PC_KILL:
		{
			if ( !pCharTarg || pCharTarg == pSrc )
				break;
			bSuccess = pCharTarg->OnAttackedBy(pSrc, 1, true);	// we know who told them to do this.
			if ( bSuccess )
				bSuccess = Fight_Attack(pCharTarg, true);
			break;
		}

		case PC_FOLLOW:
			if ( !pCharTarg )
				break;
			m_Act_Targ = pCharTarg->GetUID();
			bSuccess = Skill_Start(NPCACT_FOLLOW_TARG);
			break;

		case PC_FRIEND:
		{
			if ( !pCharTarg || !pCharTarg->m_pPlayer || pCharTarg == pSrc )
			{
				Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED));
				break;
			}
			CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND);
			if ( pMemory )
			{
				pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_ALREADY));
				break;
			}
			pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS1), GetName(), pCharTarg->GetName());
			pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS2), pSrc->GetName(), GetName());
			Memory_AddObjTypes(pCharTarg, MEMORY_FRIEND);

			m_Act_Targ = pCharTarg->GetUID();
			bSuccess = Skill_Start(NPCACT_FOLLOW_TARG);
			break;
		}

		case PC_UNFRIEND:
		{
			if ( !pCharTarg || !pCharTarg->m_pPlayer )
			{
				Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED));
				break;
			}
			CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND);
			if ( !pMemory )
			{
				pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_NOTFRIEND));
				break;
			}
			pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS1), GetName(), pCharTarg->GetName());
			pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS2), pSrc->GetName(), GetName());
			pMemory->Delete();

			m_Act_Targ = pSrc->GetUID();
			bSuccess = Skill_Start(NPCACT_FOLLOW_TARG);
			break;
		}

		case PC_GO:
			if ( !pt.IsValidPoint() )
				break;
			m_Act_p = pt;
			bSuccess = Skill_Start(NPCACT_GOTO);
			break;

		case PC_GUARD:
			if ( !pCharTarg )
				break;
			pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_GUARD_SUCCESS), GetName());
			m_Act_Targ = pCharTarg->GetUID();
			bSuccess = Skill_Start(NPCACT_GUARD_TARG);
			break;

		case PC_TRANSFER:
			if ( !pCharTarg || !pCharTarg->IsClient() )
				break;
			if ( IsSetOF(OF_PetSlots) )
			{
				if ( !pCharTarg->FollowersUpdate(this, static_cast<short>(maximum(1, GetDefNum("FOLLOWERSLOTS", true, true))), true) )
				{
					pSrc->SysMessageDefault(DEFMSG_PETSLOTS_TRY_TRANSFER);
					break;
				}
			}
			bSuccess = NPC_PetSetOwner( pCharTarg );
			break;

		case PC_PRICE:	// "PRICE" the vendor item.
			if ( !pItemTarg || !NPC_IsVendor() || !pSrc->IsClient() )
				break;
			if ( IsDigit(pszArgs[0]) )	// did they name a price
				return NPC_SetVendorPrice(pItemTarg, ATOI(pszArgs));
			if ( !NPC_SetVendorPrice(pItemTarg, -1) )	// test if it can be priced
				return false;
			pSrc->m_pClient->addPromptConsole(CLIMODE_PROMPT_VENDOR_PRICE, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_SETPRICE_2), pItemTarg->GetUID(), GetUID());
			return true;

		default:
			break;
	}

	// Make some sound to confirm we heard it
	NPC_OnPetCommand(bSuccess, pSrc);
	return bSuccess;
}
bool CScriptObj::r_WriteVal( LPCTSTR pszKey, CGString &sVal, CTextConsole * pSrc )
{
	EXC_TRY(("r_WriteVal('%s',,%x)", pszKey, pSrc));
	CScriptObj * pRef;
	if ( r_GetRef( pszKey, pRef ))
	{
		if ( pRef == NULL )	// good command but bad link.
		{
			sVal = "0";
			return true;
		}
		if ( pszKey[0] == '\0' )	// we where just testing the ref.
		{
			CObjBase *	pObj	= dynamic_cast <CObjBase *> (pRef);
			if ( pObj )
				sVal.FormatHex( (DWORD) pObj->GetUID() );
			else
				sVal.FormatVal( 1 );
			return( true );
		}
		return pRef->r_WriteVal( pszKey, sVal, pSrc );
	}

	int i = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 );
	if ( i < 0 )
	{
		// <dSOMEVAL> same as <eval <SOMEVAL>> to get dec from the val
		if (( *pszKey == 'd' ) || ( *pszKey == 'D' ))
		{
			LPCTSTR arg = pszKey + 1;
			if ( r_WriteVal(arg, sVal, pSrc) )
			{
				if ( !IsStrNumericDec(sVal) ) // dValue dec -> hex fix
				{
					sVal.FormatVal(ahextoi(sVal));
				}
				return true;
			}
		}
		// <r>, <r15>, <r3,15> are shortcuts to rand(), rand(15) and rand(3,15)
		else if (( *pszKey == 'r' ) || ( *pszKey == 'R' ))
		{
			char	*zTemp = Str_GetTemp();
			strcpy(zTemp, pszKey+1);

			if (( *zTemp ) &&  (( *zTemp < '0' ) || ( *zTemp > '9' )) )
				goto badcmd;

			TCHAR	*ppCmd[2];
			int		qty = Str_ParseCmds(zTemp, ppCmd, COUNTOF(ppCmd));
			int		min = 0, max = 1000;

			if ( qty == 1 ) max = atoi(ppCmd[0]);
			else if ( qty == 2 )
			{
				min = g_Exp.GetVal(ppCmd[0]);
				max = g_Exp.GetVal(ppCmd[1]);
			}

			if ( min > max )
			{
				int a = min;
				min = max;
				max = a;
			}
			if ( min == max )
				sVal.FormatVal(min);
			else
				sVal.FormatVal(min + Calc_GetRandVal(max - min));

			return true;
		}
badcmd:
		return false;	// Bad command.
	}

	pszKey += strlen( sm_szLoadKeys[i] );
	SKIP_SEPERATORS(pszKey);
	bool	fZero	= false;

	switch ( i )
	{
	case SSC_LISTCOL:
		// Set the alternating color.
		sVal = (CWebPageDef::sm_iListIndex&1) ? "bgcolor=\"#E8E8E8\"" : "";
		return( true );
	case SSC_OBJ:
		if ( !g_World.m_uidObj.ObjFind() ) g_World.m_uidObj = 0;
		sVal.FormatHex((DWORD)g_World.m_uidObj);
		return true;
	case SSC_NEW:
		if ( !g_World.m_uidNew.ObjFind() ) g_World.m_uidNew = 0;
		sVal.FormatHex((DWORD)g_World.m_uidNew);
		return true;
	case SSC_SRC:
		if ( pSrc == NULL )
			pRef	= NULL;
		else
		{
			pRef = pSrc->GetChar();	// if it can be converted .
			if ( ! pRef )
				pRef = dynamic_cast <CScriptObj*> (pSrc);	// if it can be converted .
		}
		if ( ! pRef )
		{
			sVal.FormatVal( 0 );
			return true;
		}
		if ( !*pszKey )
		{
			CObjBase * pObj = dynamic_cast <CObjBase*> (pRef);	// if it can be converted .
			sVal.FormatHex( pObj ? (DWORD) pObj->GetUID() : 0 );
			return true;
		}
		return pRef->r_WriteVal( pszKey, sVal, pSrc );
	case SSC_VAR0:
		fZero	= true;
	case SSC_VAR:
		// "VAR." = get/set a system wide variable.
		{
			CVarDefBase * pVar = g_Exp.m_VarGlobals.GetKey(pszKey);
			if ( pVar )
				sVal	= pVar->GetValStr();
			else if ( fZero )
				sVal	= "0";
		}
		return true;
	case SSC_DEF0:
		fZero	= true;
	case SSC_DEF:
		{
			CVarDefBase * pVar = g_Exp.m_VarDefs.GetKey(pszKey);
			if ( pVar )
				sVal	= pVar->GetValStr();
			else if ( fZero )
				sVal	= "0";
		}
		return( true );
	case SSC_EVAL:
		sVal.FormatVal( Exp_GetVal( pszKey ));
		return( true );
	case SSC_FVAL:
		{
		int	iVal		= Exp_GetVal( pszKey );
		sVal.Format( "%i.%i", iVal/10, abs(iVal%10) );
		return true;
		}
	case SSC_HVAL:
		sVal.FormatHex( Exp_GetVal( pszKey ));
		return( true );
	case SSC_QVAL:
		{	// Do a switch ? type statement <QVAL conditional ? option1 : option2>
			TCHAR * ppCmds[3];
			ppCmds[0] = const_cast<TCHAR*>(pszKey);
			Str_Parse( ppCmds[0], &(ppCmds[1]), "?" );
			Str_Parse( ppCmds[1], &(ppCmds[2]), ":" );
			sVal = ppCmds[ Exp_GetVal( ppCmds[0] ) ? 1 : 2 ];
			if ( sVal.IsEmpty())
				sVal = " ";
		}
		return( true );
	case SSC_ISEMPTY:
		sVal.FormatVal( IsStrEmpty( pszKey ) );
		return true;
	case SSC_ISNUM:
		GETNONWHITESPACE( pszKey );
		sVal.FormatVal( IsStrNumeric( pszKey ) );
		return true;
	case SSC_StrRev:
		{
			GETNONWHITESPACE( pszKey );
			sVal = pszKey;
			sVal.Reverse();
			return true;
		}
	case SSC_StrPos:
		{
			GETNONWHITESPACE( pszKey );
			int	iPos	= Exp_GetVal( pszKey );
			TCHAR	ch;
			if ( isdigit( *pszKey) && isdigit( *(pszKey+1) ) )
				ch	= (TCHAR) Exp_GetVal( pszKey );
			else
			{
				ch	= *pszKey;
				pszKey++;
			}
			
			GETNONWHITESPACE( pszKey );
			int	iLen	= strlen( pszKey );
			if ( iPos < 0 )
				iPos	= iLen + iPos;
			if ( iPos < 0 )
				iPos	= 0;
			else if ( iPos > iLen )
				iPos	= iLen;

			TCHAR *	pszPos	= strchr( pszKey + iPos, ch );
			if ( !pszPos )
				sVal.FormatVal( -1 );
			else
				sVal.FormatVal( pszPos - pszKey );
		}
		return true;
	case SSC_StrSub:
		{
			int	iPos	= Exp_GetVal( pszKey );
			int	iCnt	= Exp_GetVal( pszKey );
			SKIP_ARGSEP( pszKey );
			GETNONWHITESPACE( pszKey );

			int	iLen	= strlen( pszKey );
			if ( iPos < 0 ) iPos += iLen;
			if ( iPos > iLen || iPos < 0 ) iPos = 0;

			if ( iPos + iCnt > iLen || iCnt == 0 )
				iCnt = iLen - iPos;

			TCHAR	*buf = Str_GetTemp();
			strncpy( buf, pszKey + iPos, iCnt );
			buf[iCnt] = '\0';
			sVal = buf;
		}
		return true;
	case SSC_StrArg:
		{
			TCHAR	*buf = Str_GetTemp();
			GETNONWHITESPACE( pszKey );
			if ( *pszKey == '"' )
				pszKey++;
			int	i	= 0;
			while ( *pszKey && !isspace( *pszKey ) && *pszKey != ',' )
			{
				buf[i]	= *pszKey;
				pszKey++;
				i++;
			}
			buf[i]	= '\0';
			sVal	= buf;
		}
		return true;
	case SSC_StrEat:
		{
			GETNONWHITESPACE( pszKey );
			while ( *pszKey && !isspace( *pszKey ) && *pszKey != ',' )
				pszKey++;
			SKIP_ARGSEP( pszKey );
			sVal	= pszKey;
		}
		return true;
	case SSC_ASC:
		{
			TCHAR	*buf = Str_GetTemp();
			REMOVE_QUOTES( pszKey );
			sVal.FormatHex( *pszKey );
			sprintf( buf, sVal );
			while ( *(++pszKey) )
			{
				if ( *pszKey == '"' ) break;
				sVal.FormatHex( *pszKey );
				strcat( buf, " " );
				strcat( buf, sVal );
			}
			sVal	= buf;
		}
		return true;

	case SSC_READFILE:
		{
			if ( !IsSetOF( OF_FileCommands ) ) 
				return false;

			TCHAR	*rfArgs[1];
			FILE	*rfFD;
			TCHAR	*buf = Str_GetTemp();

			int line;

			rfArgs[0] = const_cast<TCHAR*>(pszKey);
			Str_Parse( rfArgs[0], &(rfArgs[1]), " " );

			// Remove other junk
			Str_Parse( rfArgs[1], NULL, " " );

			line = atoi( rfArgs[1] );

			sVal = "";
			if ( rfFD = fopen( rfArgs[0], "r" ))
			{
				if ( line == -1 )	// First line of the file
					fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
				else if ( line == 0 )
				{
					// Last line of the file
					while ( ! feof( rfFD ) )
						fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
				}					
				else
				{
					// Line "line" of the file
					int x;
					for ( x = 1; x <= line; x++ )
					{
						if ( feof(rfFD) )
						{
							buf[0] = 0;
							break;
						}
						fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
					}
				}
				sVal = buf;
				fclose(rfFD);
			}
		}
		return true;
	case SSC_FILELINES:
		{
			if ( !IsSetOF( OF_FileCommands ) )
				return false;
			
			TCHAR	*buf = Str_GetTemp();
			FILE	*flFD;
			int		x(0);
			GETNONWHITESPACE( pszKey );
			if ( flFD = fopen( pszKey, "r" ) )
			{
				while ( ! feof(flFD) )
				{
					fgets(buf, SCRIPT_MAX_LINE_LEN, flFD );
					x++;
				}
				fclose(flFD);
			}
			sVal.FormatVal(x);
		}
		return true;
	case SSC_SYSCMD:
	case SSC_SYSSPAWN:
		{
			if ( !IsSetOF(OF_FileCommands) )
				return false;

			GETNONWHITESPACE(pszKey);
			TCHAR	*buf = Str_GetTemp();
			TCHAR	*Arg_ppCmd[10];		// limit to 9 arguments
			strcpy(buf, pszKey);
			int iQty = Str_ParseCmds(buf, Arg_ppCmd, COUNTOF(Arg_ppCmd));
			if ( iQty < 1 )
				return false;

#ifdef WIN32
			_spawnl(
				( i == SSC_SYSCMD ) ? _P_WAIT : _P_NOWAIT,
				Arg_ppCmd[0],
				Arg_ppCmd[0],
				Arg_ppCmd[1],
				Arg_ppCmd[2],
				Arg_ppCmd[3],
				Arg_ppCmd[4],
				Arg_ppCmd[5],
				Arg_ppCmd[6],
				Arg_ppCmd[7],
				Arg_ppCmd[8],
				Arg_ppCmd[9],
				NULL
			);
#else
			g_Log.EventError("sysspawn/syscmd is not available on unix builds." DEBUG_CR);
#endif
			return true;
		}

	default:
		StringFunction( i, pszKey, sVal );
		return true;
	}
	EXC_CATCH("CScriptObj");
	return false;
}
Beispiel #10
0
bool CChar::NPC_OnHearPetCmdTarg(int iCmd, CChar *pSrc, CObjBase *pObj, const CPointMap &pt, LPCTSTR pszArgs)
{
	ADDTOCALLSTACK("CChar::NPC_OnHearPetCmdTarg");
	// Pet commands that required a target.

	if ( m_fIgnoreNextPetCmd )
	{
		m_fIgnoreNextPetCmd = false;
		return false;
	}

	if ( !NPC_PetCheckAccess(iCmd, pSrc) )
		return true;

	bool bSuccess = false;
	CItem *pItemTarg = dynamic_cast<CItem *>(pObj);
	CChar *pCharTarg = dynamic_cast<CChar *>(pObj);

	switch ( iCmd )
	{
		case PC_ATTACK:
		case PC_KILL:
		{
			if ( !pCharTarg || (pCharTarg == this) || (pCharTarg == pSrc) )
				break;

			bSuccess = pCharTarg->OnAttackedBy(pSrc, true);
			if ( bSuccess )
				bSuccess = Fight_Attack(pCharTarg, true);
			break;
		}

		case PC_FOLLOW:
			if ( !pCharTarg || (pCharTarg == this) )
				break;
			m_Act_Targ = pCharTarg->GetUID();
			bSuccess = Skill_Start(NPCACT_FOLLOW_TARG);
			break;

		case PC_FRIEND:
		{
			if ( !pCharTarg || !pCharTarg->m_pPlayer || (pCharTarg == pSrc) )
			{
				Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED));
				break;
			}
			CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND);
			if ( pMemory )
			{
				pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_ALREADY));
				break;
			}
			pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS1), GetName(), pCharTarg->GetName());
			pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS2), pSrc->GetName(), GetName());
			Memory_AddObjTypes(pCharTarg, MEMORY_FRIEND);

			m_Act_Targ = pCharTarg->GetUID();
			bSuccess = Skill_Start(NPCACT_FOLLOW_TARG);
			break;
		}

		case PC_UNFRIEND:
		{
			if ( !pCharTarg || !pCharTarg->m_pPlayer )
			{
				Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED));
				break;
			}
			CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND);
			if ( !pMemory )
			{
				pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_NOTFRIEND));
				break;
			}
			pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS1), GetName(), pCharTarg->GetName());
			pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS2), pSrc->GetName(), GetName());
			pMemory->Delete();

			m_Act_Targ = pSrc->GetUID();
			bSuccess = Skill_Start(NPCACT_FOLLOW_TARG);
			break;
		}

		case PC_GO:
			if ( !pt.IsValidPoint() )
				break;
			m_Act_p = pt;
			bSuccess = Skill_Start(NPCACT_GOTO);
			break;

		case PC_GUARD:
			if ( !pCharTarg || (pCharTarg == this) )
				break;
			pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_GUARD_SUCCESS), GetName());
			m_Act_Targ = pCharTarg->GetUID();
			bSuccess = Skill_Start(NPCACT_GUARD_TARG);
			break;

		case PC_TRANSFER:
			if ( !pCharTarg || !pCharTarg->m_pClient )
				break;
			if ( IsSetOF(OF_PetSlots) )
			{
				if ( !pCharTarg->FollowersUpdate(this, static_cast<short>(maximum(1, GetDefNum("FOLLOWERSLOTS", true))), true) )
				{
					pSrc->SysMessageDefault(DEFMSG_PETSLOTS_TRY_TRANSFER);
					break;
				}
			}
			bSuccess = NPC_PetSetOwner(pCharTarg);
			break;

		case PC_PRICE:
			if ( !pItemTarg || !NPC_IsVendor() || !pSrc->m_pClient )
				break;
			if ( IsDigit(pszArgs[0]) )	// did they name a price
				return NPC_SetVendorPrice(pItemTarg, ATOI(pszArgs));
			if ( !NPC_SetVendorPrice(pItemTarg, -1) )	// test if it can be priced
				return false;
			pSrc->m_pClient->addPromptConsole(CLIMODE_PROMPT_VENDOR_PRICE, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_SETPRICE_2), pItemTarg->GetUID(), GetUID());
			return true;

		default:
			break;
	}

	// Make some sound to confirm we heard it
	NPC_PetConfirmCommand(bSuccess, pSrc);
	return bSuccess;
}
Beispiel #11
0
bool CChar::NPC_OnHearPetCmdTarg( int iCmd, CChar * pSrc, CObjBase * pObj, const CPointMap & pt, LPCTSTR pszArgs )
{
	ADDTOCALLSTACK("CChar::NPC_OnHearPetCmdTarg");
	// Pet commands that required a target.

	if ( iCmd == PC_FOLLOW || iCmd == PC_STAY || iCmd == PC_STOP )
	{
		// Pet friends can use only these commands
		if ( ! NPC_IsOwnedBy( pSrc ) && Memory_FindObjTypes( pSrc, MEMORY_FRIEND ) == NULL )
			return false;
	}
	else
	{
		// All others commands are avaible only to pet owner
		if ( ! NPC_IsOwnedBy( pSrc, true ) )
			return false;
	}

	if ( m_fIgnoreNextPetCmd == true )
	{
		m_fIgnoreNextPetCmd = false;
		return(false);
	}

	bool fSuccess = false;	// No they won't do it.

	// Could be NULL
	CItem * pItemTarg = dynamic_cast<CItem*>(pObj);
	CChar * pCharTarg = dynamic_cast<CChar*>(pObj);

	switch ( iCmd )
	{
		case PC_GO:
			// Go to the location x,y
			if ( ! pt.IsValidPoint())
				break;
			m_Act_p = pt;
			fSuccess = Skill_Start( NPCACT_GOTO );
			break;

		case PC_GUARD:
			if ( pObj == NULL )
				break;
			m_Act_Targ = pObj->GetUID();
			fSuccess = Skill_Start( NPCACT_GUARD_TARG );
			break;
		case PC_TRANSFER:
			// transfer ownership via the transfer command.
			if ( pCharTarg == NULL )
				break;
			if ( pCharTarg->IsClient() )
			{
				if ( IsSetOF(OF_PetSlots) )
				{
					if ( !pCharTarg->FollowersUpdate(this, static_cast<short>(maximum(1, GetDefNum("FOLLOWERSLOTS", true, true))), true) )
					{
						pSrc->SysMessageDefault( DEFMSG_PETSLOTS_TRY_TRANSFER );
						break;
					}
				}

				fSuccess = NPC_PetSetOwner( pCharTarg );
			}
			break;

		case PC_KILL:
		case PC_ATTACK:
			// Attack the target.
			if ( pCharTarg == NULL )
				break;
			// refuse to attack friends.
			if ( NPC_IsOwnedBy( pCharTarg, true ))
			{
				fSuccess = false;	// take no commands
				break;
			}
			fSuccess = pCharTarg->OnAttackedBy( pSrc, 1, true );	// we know who told them to do this.
			if ( fSuccess )
			{
				fSuccess = Fight_Attack( pCharTarg, true );
			}
			break;

		case PC_FOLLOW:
			if ( pCharTarg == NULL )
				break;
			m_Act_Targ = pCharTarg->GetUID();
			fSuccess = Skill_Start( NPCACT_FOLLOW_TARG );
			break;
		case PC_FRIEND:
			// Not the same as owner,
			if ( pCharTarg == NULL )
				break;
			Memory_AddObjTypes( pCharTarg, MEMORY_FRIEND );
			break;

		case PC_PRICE:	// "PRICE" the vendor item.
			if ( pItemTarg == NULL )
				break;
			if ( ! NPC_IsVendor())
				break;

			// did they name a price
			if ( IsDigit( pszArgs[0] ))
			{
				return NPC_SetVendorPrice( pItemTarg, ATOI(pszArgs) );
			}

			// test if it is pricable.
			if ( ! NPC_SetVendorPrice( pItemTarg, -1 ))
			{
				return false;
			}

			// Now set it's price.
			if ( ! pSrc->IsClient())
				break;
			
			pSrc->m_pClient->addPromptConsole( CLIMODE_PROMPT_VENDOR_PRICE, g_Cfg.GetDefaultMsg( DEFMSG_NPC_VENDOR_SETPRICE_2 ), pItemTarg->GetUID(), GetUID() );
			return( true );

		default:
			break;
	}

	// Make the yes/no noise.
	NPC_OnPetCommand( fSuccess, pSrc );
	return fSuccess;
}