void CStoneMember::SetTitle( LPCTSTR pTitle )
{
	ADDTOCALLSTACK("CStoneMember::SetTitle");
	m_sTitle = pTitle;
}
Example #2
0
bool CChat::JoinChannel(CChatChanMember * pMember, lpctstr pszChannel, lpctstr pszPassword)
{
	ADDTOCALLSTACK("CChat::JoinChannel");
	ASSERT(pMember != nullptr);
	CClient * pMemberClient = pMember->GetClient();
	ASSERT(pMemberClient != nullptr);

	// Are we in a channel now?
	CChatChannel * pCurrentChannel = pMember->GetChannel();
	if (pCurrentChannel != nullptr)
	{
		// Is it the same channel as the one I'm already in?
		if (strcmp(pszChannel, pCurrentChannel->GetName()) == 0)
		{
			// Tell them and return
			pMember->SendChatMsg(CHATMSG_AlreadyInConference, pszChannel);
			return false;
		}
	}

	CChatChannel * pNewChannel = FindChannel(pszChannel);
	if (pNewChannel == nullptr)
	{
		pMemberClient->addChatSystemMessage(CHATMSG_NoConference, pszChannel );
		return false;
	}

	// If there's a password, is it the correct one?
	if (strcmp(pNewChannel->GetPassword(), pszPassword) != 0)
	{
		pMemberClient->addChatSystemMessage(CHATMSG_IncorrectPassword);
		return false;
	}

	// Leave the old channel 1st
	// Remove from old channel (if any)
	if (pCurrentChannel != nullptr)
	{
		// Remove myself from the channels list of members
		pCurrentChannel->RemoveMember(pMember);

		// If noone is left, tell the chat system to delete it from memory
		if (pCurrentChannel->m_Members.size() <= 0)
		{
			// Am I the last one here? Delete it from all other clients?
			DeleteChannel(pCurrentChannel);
		}

		// Since we left, clear all members from our client that might be in our list from the channel we just left
		pMemberClient->addChatSystemMessage(CHATMSG_ClearMemberList);
	}

	// Now join a new channel
	// Add all the members of the channel to the clients list of channel participants
	pNewChannel->SendMembers(pMember);

	// Add ourself to the channels list of members
	if (!pNewChannel->AddMember(pMember))
		return false;

	// Set the channel name title bar
	pMemberClient->addChatSystemMessage(CHATMSG_UpdateChannelBar, pszChannel);

	// Now send out my name to all clients in this channel
	pNewChannel->SendThisMember(pMember);
	return true;
}
Example #3
0
void CItemVendable::SetPlayerVendorPrice( DWORD lPrice )
{
	ADDTOCALLSTACK("CItemVendable::SetPlayerVendorPrice");
	// This can only be inside a vendor container.
	m_price = maximum(lPrice, 0);
}
Example #4
0
bool CChar::Use_Eat( CItem * pItemFood, short iQty )
{
	ADDTOCALLSTACK("CChar::Use_Eat");
	// What we can eat should depend on body type.
	// How much we can eat should depend on body size and current fullness.
	//
	// ??? monsters should be able to eat corpses / raw meat
	// IT_FOOD or IT_FOOD_RAW
	// NOTE: Some foods like apples are stackable !

	if ( !CanMove(pItemFood) )
	{
		SysMessageDefault(DEFMSG_FOOD_CANTMOVE);
		return false;
	}

	if ( Stat_GetMax(STAT_FOOD) == 0 )
	{
		SysMessageDefault(DEFMSG_FOOD_CANTEAT);
		return false;
	}

	// Is this edible by me ?
	if ( !Food_CanEat(pItemFood) )
	{
		SysMessageDefault(DEFMSG_FOOD_RCANTEAT);
		return false;
	}

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

	Use_EatQty(pItemFood, iQty);

	LPCTSTR pMsg;
	int index = IMULDIV(Stat_GetVal(STAT_FOOD), 5, Stat_GetMax(STAT_FOOD));
	switch ( index )
	{
		case 0:
			pMsg = g_Cfg.GetDefaultMsg(DEFMSG_FOOD_FULL_1);
			break;
		case 1:
			pMsg = g_Cfg.GetDefaultMsg(DEFMSG_FOOD_FULL_2);
			break;
		case 2:
			pMsg = g_Cfg.GetDefaultMsg(DEFMSG_FOOD_FULL_3);
			break;
		case 3:
			pMsg = g_Cfg.GetDefaultMsg(DEFMSG_FOOD_FULL_4);
			break;
		case 4:
			pMsg = g_Cfg.GetDefaultMsg(DEFMSG_FOOD_FULL_5);
			break;
		case 5:
		default:
			pMsg = g_Cfg.GetDefaultMsg(DEFMSG_FOOD_FULL_6);
			break;
	}
	SysMessage(pMsg);
	return true;
}
Example #5
0
void CChat::DoCommand(CChatChanMember * pBy, lpctstr szMsg)
{
	ADDTOCALLSTACK("CChat::DoCommand");
	static lpctstr const sm_szCmd_Chat[] =
	{
		"ALLKICK",
		"BC",
		"BCALL",
		"CHATSOK",
		"CLEARIGNORE",
		"KILLCHATS",
		"NOCHATS",
		"SYSMSG",
		"WHEREIS"
	};

	ASSERT(pBy != nullptr);
	ASSERT(szMsg != nullptr);

	tchar buffer[2048];
	ASSERT(strlen(szMsg) < CountOf(buffer));
	strcpy(buffer, szMsg);

	tchar * pszCommand = buffer;
	tchar * pszText = nullptr;
	size_t iCommandLength = strlen(pszCommand);
	for (size_t i = 0; i < iCommandLength; i++)
	{
		ASSERT( i<CountOf(buffer));
		if (pszCommand[i] == ' ')
		{
			pszCommand[i] = 0;
			pszText = pszCommand + i + 1;
		}
	}

	CSString sFrom;
	CChatChannel * pChannel = pBy->GetChannel();
	CClient * pByClient = pBy->GetClient();
	ASSERT(pByClient != nullptr);

	switch ( FindTableSorted( pszCommand, sm_szCmd_Chat, CountOf(sm_szCmd_Chat)))
	{
		case 0: // "ALLKICK"
		{
			if (pChannel == nullptr)
			{
				pBy->SendChatMsg(CHATMSG_MustBeInAConference);
				return;
			}

			if (!pChannel->IsModerator(pBy->GetChatName()))
			{
				pBy->SendChatMsg(CHATMSG_MustHaveOps);
				return;
			}

			pChannel->KickAll(pBy);
			DecorateName(sFrom, nullptr, true);
			pBy->SendChatMsg(CHATMSG_PlayerTalk, sFrom, "All members have been kicked!", "");
			return;
		}
		case 1: // "BC"
		{
			if ( ! pByClient->IsPriv( PRIV_GM ))
			{
	need_gm_privs:
				DecorateName(sFrom, nullptr, true);
				pBy->SendChatMsg(CHATMSG_PlayerTalk, sFrom, "You need to have GM privs to use this command.");
				return;
			}

			Broadcast(pBy, pszText);
			return;
		}
		case 2: // "BCALL"
		{
			if ( ! pByClient->IsPriv( PRIV_GM ))
				goto need_gm_privs;

			Broadcast(pBy, pszText, "", true);
			return;
		}
		case 3: // "CHATSOK"
		{
			if ( ! pByClient->IsPriv( PRIV_GM ))
				goto need_gm_privs;

			if (!m_fChatsOK)
			{
				m_fChatsOK = true;
				Broadcast(nullptr, "Conference creation is enabled.");
			}
			return;
		}
		case 4: // "CLEARIGNORE"
		{
			pBy->ClearIgnoreList();
			return;
		}
		case 5: // "KILLCHATS"
		{
			if ( ! pByClient->IsPriv( PRIV_GM ))
				goto need_gm_privs;

			KillChannels();
			return;
		}
		case 6: // "NOCHATS"
		{
			if ( ! pByClient->IsPriv( PRIV_GM ))
				goto need_gm_privs;

			if (m_fChatsOK)
			{
				Broadcast(nullptr, "Conference creation is now disabled.");
				m_fChatsOK = false;
			}
			return;
		}
		case 7: // "SYSMSG"
		{
			if ( ! pByClient->IsPriv( PRIV_GM ))
				goto need_gm_privs;

			Broadcast(nullptr, pszText, "", true);
			return;
		}
		case 8:	// "WHEREIS"
		{
			WhereIs(pBy, pszText);
			return;
		}
		default:
		{
			tchar *pszMsg = Str_GetTemp();
			sprintf(pszMsg, "Unknown command: '%s'", pszCommand);

			DecorateName(sFrom, nullptr, true);
			pBy->SendChatMsg(CHATMSG_PlayerTalk, sFrom, pszMsg);
			return;
		}
	}
}
Example #6
0
bool CChar::Use_CarveCorpse( CItemCorpse * pCorpse )
{
	ADDTOCALLSTACK("CChar::Use_CarveCorpse");
	CREID_TYPE CorpseID = pCorpse->m_itCorpse.m_BaseID;
	CCharBase *pCorpseDef = CCharBase::FindCharBase(CorpseID);
	if ( !pCorpseDef || pCorpse->m_itCorpse.m_carved )
	{
		SysMessageDefault(DEFMSG_CARVE_CORPSE_NOTHING);
		return false;
	}

	CChar *pChar = pCorpse->m_uidLink.CharFind();
	CPointMap pnt = pCorpse->GetTopLevelObj()->GetTopPoint();

	UpdateAnimate(ANIM_BOW);
	if ( pCorpse->m_TagDefs.GetKeyNum("BLOOD") )
	{
		CItem *pBlood = CItem::CreateBase(ITEMID_BLOOD4);
		ASSERT(pBlood);
		pBlood->SetHue(pCorpseDef->m_wBloodHue);
		pBlood->MoveToDecay(pnt, 5 * TICK_PER_SEC);
	}

	size_t iItems = 0;
	for ( size_t i = 0; i < pCorpseDef->m_BaseResources.GetCount(); i++ )
	{
		long long iQty = pCorpseDef->m_BaseResources[i].GetResQty();
		RESOURCE_ID rid = pCorpseDef->m_BaseResources[i].GetResourceID();
		if ( rid.GetResType() != RES_ITEMDEF )
			continue;

		ITEMID_TYPE id = static_cast<ITEMID_TYPE>(rid.GetResIndex());
		if ( id == ITEMID_NOTHING )
			break;

		iItems++;
		CItem *pPart = CItem::CreateTemplate(id, NULL, this);
		ASSERT(pPart);
		switch ( pPart->GetType() )
		{
			case IT_FOOD:
			case IT_FOOD_RAW:
			case IT_MEAT_RAW:
				SysMessageDefault(DEFMSG_CARVE_CORPSE_MEAT);
				//pPart->m_itFood.m_MeatType = CorpseID;
				break;
			case IT_HIDE:
				SysMessageDefault(DEFMSG_CARVE_CORPSE_HIDES);
				//pPart->m_itSkin.m_creid = CorpseID;
				if ( (g_Cfg.m_iRacialFlags & RACIALF_HUMAN_WORKHORSE) && IsHuman() )	// humans always find 10% bonus when gathering hides, ores and logs (Workhorse racial trait)
					iQty = iQty * 110 / 100;
				break;
			case IT_FEATHER:
				SysMessageDefault(DEFMSG_CARVE_CORPSE_FEATHERS);
				//pPart->m_itSkin.m_creid = CorpseID;
				break;
			case IT_WOOL:
				SysMessageDefault(DEFMSG_CARVE_CORPSE_WOOL);
				//pPart->m_itSkin.m_creid = CorpseID;
				break;
			/*case IT_DRAGON_SCALE:			// TO-DO (typedef IT_DRAGON_SCALE doesn't exist yet)
				SysMessageDefault(DEFMSG_CARVE_CORPSE_SCALES);
				//pPart->m_itSkin.m_creid = CorpseID;
				break;*/
			default:
				break;
		}

		if ( iQty > 1 )
			pPart->SetAmount(static_cast<WORD>(iQty));

		if ( pChar && pChar->m_pPlayer )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_CORPSE_NAME), pPart->GetName(), pChar->GetName());
			pPart->SetName(pszMsg);
			pPart->m_uidLink = pChar->GetUID();
			pPart->MoveToDecay(pnt, pPart->GetDecayTime());
			continue;
		}
		pCorpse->ContentAdd(pPart);
	}

	if ( iItems < 1 )
		SysMessageDefault(DEFMSG_CARVE_CORPSE_NOTHING);

	CheckCorpseCrime(pCorpse, false, false);
	pCorpse->m_itCorpse.m_carved = 1;			// mark as been carved
	pCorpse->m_itCorpse.m_uidKiller = GetUID();	// by you

	if ( pChar && pChar->m_pPlayer )
		pCorpse->SetTimeout(0);		// reset corpse timer to make it turn bones
	return true;
}
Example #7
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 #8
0
bool CClient::r_WriteVal(LPCTSTR pszKey, CGString &sVal, CTextConsole *pSrc)
{
	ADDTOCALLSTACK("CClient::r_WriteVal");
	EXC_TRY("WriteVal");

	if ( !strnicmp("CTAG.", pszKey, 5) )
	{
		if ( pszKey[4] != '.' )
			return false;
		pszKey += 5;
		CVarDefCont *pVar = m_TagDefs.GetKey(pszKey);
		sVal = pVar ? pVar->GetValStr() : "";
		return true;
	}

	if ( !strnicmp("CTAG0.", pszKey, 6) )
	{
		if ( pszKey[5] != '.' )
			return false;
		pszKey += 6;
		CVarDefCont *pVar = m_TagDefs.GetKey(pszKey);
		sVal = pVar ? pVar->GetValStr() : "0";
		return true;
	}

	int index;
	if ( !strnicmp("TARGP", pszKey, 5) && ((pszKey[5] == '\0') || (pszKey[5] == '.')) )
		index = CC_TARGP;
	else if ( !strnicmp("SCREENSIZE", pszKey, 10) && ((pszKey[10] == '\0') || (pszKey[10] == '.')) )
		index = CC_SCREENSIZE;
	else if ( !strnicmp("REPORTEDCLIVER", pszKey, 14) && ((pszKey[14] == '\0') || (pszKey[14] == '.')) )
		index = CC_REPORTEDCLIVER;
	else
		index = FindTableSorted(pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys) - 1);

	switch ( index )
	{
		case CC_ALLMOVE:
			sVal.FormatVal(IsPriv(PRIV_ALLMOVE));
			break;
		case CC_ALLSHOW:
			sVal.FormatVal(IsPriv(PRIV_ALLSHOW));
			break;
		case CC_CLIENTIS3D:
			sVal.FormatVal(m_NetState->isClient3D());
			break;
		case CC_CLIENTISKR:
			sVal.FormatVal(m_NetState->isClientKR());
			break;
		case CC_CLIENTISSA:
			sVal.FormatVal(m_NetState->isClientEnhanced());
			break;
		case CC_CLIENTVERSION:
		{
			TCHAR szVersion[128];
			sVal = m_Crypt.WriteClientVerString(m_Crypt.GetClientVer(), szVersion);
			break;
		}
		case CC_DEBUG:
			sVal.FormatVal(IsPriv(PRIV_DEBUG));
			break;
		case CC_DETAIL:
			sVal.FormatVal(IsPriv(PRIV_DETAIL));
			break;
		case CC_GM:
			sVal.FormatVal(IsPriv(PRIV_GM));
			break;
		case CC_HEARALL:
			sVal.FormatVal(IsPriv(PRIV_HEARALL));
			break;
		case CC_LASTEVENT:
			sVal.FormatLLVal(m_timeLastEvent.GetTimeRaw());
			break;
		case CC_PRIVSHOW:
			sVal.FormatVal(!IsPriv(PRIV_PRIV_NOSHOW));
			break;
		case CC_REPORTEDCLIVER:
		{
			pszKey += 14;
			GETNONWHITESPACE(pszKey);

			DWORD dwCliVer = m_NetState->getReportedVersion();
			if ( pszKey[0] == '\0' )
			{
				// Return full version string (eg: 5.0.2d)
				TCHAR szVersion[128];
				sVal = CCrypt::WriteClientVerString(dwCliVer, szVersion);
			}
			else
			{
				// Return raw version number (eg: 5.0.2d = 5000204)
				sVal.FormatUVal(dwCliVer);
			}
			break;
		}
		case CC_SCREENSIZE:
		{
			if ( pszKey[10] == '.' )
			{
				pszKey += 10;
				SKIP_SEPARATORS(pszKey);

				if ( !strnicmp("X", pszKey, 1) )
					sVal.Format("%hu", m_ScreenSize.x);
				else if ( !strnicmp("Y", pszKey, 1) )
					sVal.Format("%hu", m_ScreenSize.y);
				else
					return false;
			}
			else
				sVal.Format("%hu,%hu", m_ScreenSize.x, m_ScreenSize.y);
			break;
		}
		case CC_TARG:
			sVal.FormatHex(m_Targ_UID);
			break;
		case CC_TARGP:
		{
			if ( pszKey[5] == '.' )
				return m_Targ_p.r_WriteVal(pszKey + 6, sVal);
			sVal = m_Targ_p.WriteUsed();
			break;
		}
		case CC_TARGPROP:
			sVal.FormatHex(m_Prop_UID);
			break;
		case CC_TARGPRV:
			sVal.FormatHex(m_Targ_PrvUID);
			break;
		case CC_TARGTXT:
			sVal = m_Targ_Text;
			break;
		default:
			return CScriptObj::r_WriteVal(pszKey, sVal, pSrc);
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_KEYRET(pSrc);
	EXC_DEBUG_END;
	return false;
}
Example #9
0
bool CClient::r_LoadVal(CScript &s)
{
	ADDTOCALLSTACK("CClient::r_LoadVal");
	EXC_TRY("LoadVal");
	if ( !m_pAccount )
		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:
		{
			m_pAccount->TogPrivFlags(PRIV_ALLMOVE, s.GetArgStr());
			addPlayerSee(NULL);
			if ( IsSetOF(OF_Command_Sysmsgs) )
				m_pChar->SysMessage(IsPriv(PRIV_ALLMOVE) ? "Allmove ON" : "Allmove OFF");
			break;
		}
		case CC_ALLSHOW:
		{
			if ( IsPriv(PRIV_ALLSHOW) )
				addRemoveAll(false, true);
			m_pAccount->TogPrivFlags(PRIV_ALLSHOW, s.GetArgStr());
			addPlayerSee(NULL);
			if ( IsSetOF(OF_Command_Sysmsgs) )
				m_pChar->SysMessage(IsPriv(PRIV_ALLSHOW) ? "Allshow ON" : "Allshow OFF");
			break;
		}
		case CC_DEBUG:
		{
			addRemoveAll(true, false);
			m_pAccount->TogPrivFlags(PRIV_DEBUG, s.GetArgStr());
			addPlayerSee(NULL);
			if ( IsSetOF(OF_Command_Sysmsgs) )
				m_pChar->SysMessage(IsPriv(PRIV_DEBUG) ? "Debug ON" : "Debug OFF");
			break;
		}
		case CC_DETAIL:
		{
			m_pAccount->TogPrivFlags(PRIV_DETAIL, s.GetArgStr());
			if ( IsSetOF(OF_Command_Sysmsgs) )
				m_pChar->SysMessage(IsPriv(PRIV_DETAIL) ? "Detail ON" : "Detail OFF");
			break;
		}
		case CC_GM:
		{
			if ( GetPrivLevel() >= PLEVEL_GM )
			{
				m_pAccount->TogPrivFlags(PRIV_GM, s.GetArgStr());
				m_pChar->UpdatePropertyFlag();
				addPlayerSee(NULL);
				if ( IsSetOF(OF_Command_Sysmsgs) )
					m_pChar->SysMessage(IsPriv(PRIV_GM) ? "GM ON" : "GM OFF");
			}
			break;
		}
		case CC_HEARALL:
		{
			m_pAccount->TogPrivFlags(PRIV_HEARALL, s.GetArgStr());
			if ( IsSetOF(OF_Command_Sysmsgs) )
				m_pChar->SysMessage(IsPriv(PRIV_HEARALL) ? "Hearall ON" : "Hearall OFF");
			break;
		}
		case CC_PRIVSHOW:
			if ( GetPrivLevel() >= PLEVEL_Counsel )
			{
				if ( !s.HasArgs() )
					m_pAccount->TogPrivFlags(PRIV_PRIV_NOSHOW, NULL);
				else if ( s.GetArgVal() )
					m_pAccount->ClearPrivFlags(PRIV_PRIV_NOSHOW);
				else
					m_pAccount->SetPrivFlags(PRIV_PRIV_NOSHOW);

				m_pChar->UpdatePropertyFlag();
				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;
}
Example #10
0
void CClient::UpdateFeatureFlags()
{
	ADDTOCALLSTACK("CClient::UpdateFeatureFlags");
	// Update ingame features enabled on this client
	// NOTE: Flags > 0x10000 requires at least client 6.0.14.2

	// 0x000001		Enable T2A features
	// 0x000002		Enable Renaissance features (play MP3 instead midi, ...)
	// 0x000004		Enable TD features
	// 0x000008		Enable LBR features
	// 0x000010		Enable AOS features (necro/paladin, house customization engine, ...)
	// 0x000020		Sixth character slot
	// 0x000040		Enable SE features
	// 0x000080		Enable ML features
	// 0x000100		8th age
	// 0x000200		9th age (enable crystal/shadow custom house tiles)
	// 0x000400		10th age
	// 0x000800		Increased house/bank storage
	// 0x001000		Seventh character slot
	// 0x002000		Enable extra roleplay face styles on character creation	(enhanced clients only)
	// 0x004000		Trial account
	// 0x008000		Live account (required on clients 4.0.0+, otherwise bits 3..14 will be ignored)
	// 0x010000		Enable SA features
	// 0x020000		Enable HS features
	// 0x040000		Enable gothic custom house tiles
	// 0x080000		Enable rustic custom house tiles
	// 0x100000		Enable jungle custom house tiles
	// 0x200000		Enable shadowguard custom house tiles
	// 0x400000		Enable TOL features
	// 0x800000		Free account (Endless Journey)

	if ( !m_pAccount )
		return;

	RESDISPLAY_VERSION iResDisp = static_cast<RESDISPLAY_VERSION>(m_pAccount->GetResDisp());
	BYTE bMaxChars = static_cast<BYTE>(maximum(m_pAccount->GetMaxChars(), m_pAccount->m_Chars.GetCharCount()));
	m_FeatureFlags = 0;

	// Expansion features
	if ( iResDisp >= RDS_T2A )
	{
		if ( g_Cfg.m_iFeatureT2A & FEATURE_T2A_UPDATE )
			m_FeatureFlags |= 0x4;
		if ( g_Cfg.m_iFeatureT2A & FEATURE_T2A_CHAT )
			m_FeatureFlags |= 0x1;
	}

	if ( iResDisp >= RDS_LBR )
	{
		if ( g_Cfg.m_iFeatureLBR & FEATURE_LBR_UPDATE )
			m_FeatureFlags |= 0x8;
		if ( g_Cfg.m_iFeatureLBR & FEATURE_LBR_SOUND )
			m_FeatureFlags |= 0x2;
	}

	if ( iResDisp >= RDS_AOS )
	{
		if ( g_Cfg.m_iFeatureAOS & FEATURE_AOS_UPDATE_A )
			m_FeatureFlags |= 0x10;
	}

	if ( iResDisp >= RDS_SE )
	{
		if ( g_Cfg.m_iFeatureSE & FEATURE_SE_UPDATE )
			m_FeatureFlags |= 0x40;
	}

	if ( iResDisp >= RDS_ML )
	{
		if ( g_Cfg.m_iFeatureML & FEATURE_ML_UPDATE )
			m_FeatureFlags |= 0x80;
	}

	if ( iResDisp >= RDS_SA )
	{
		if ( g_Cfg.m_iFeatureSA & FEATURE_SA_UPDATE )
			m_FeatureFlags |= 0x10000;
	}

	if ( iResDisp >= RDS_TOL )
	{
		if ( g_Cfg.m_iFeatureTOL & FEATURE_TOL_UPDATE )
			m_FeatureFlags |= 0x400000;
	}

	// Max character slots
	if ( bMaxChars > 6 )
		m_FeatureFlags |= 0x1000;
	if ( bMaxChars == 6 )
		m_FeatureFlags |= 0x20;

	// Extra housing features (enable expansion items on house customization engine)
	// PS: main expansion items are already enabled with flags 0x10 (AOS), 0x40 (SE), 0x80 (ML), 0x10000 (SA) and 0x400000 (TOL)
	if ( g_Cfg.m_iFeatureExtra & FEATURE_EXTRA_CRYSTAL )
		m_FeatureFlags |= 0x200;
	if ( g_Cfg.m_iFeatureExtra & FEATURE_EXTRA_GOTHIC )
		m_FeatureFlags |= 0x40000;
	if ( g_Cfg.m_iFeatureExtra & FEATURE_EXTRA_RUSTIC )
		m_FeatureFlags |= 0x80000;
	if ( g_Cfg.m_iFeatureExtra & FEATURE_EXTRA_JUNGLE )
		m_FeatureFlags |= 0x100000;
	if ( g_Cfg.m_iFeatureExtra & FEATURE_EXTRA_SHADOWGUARD )
		m_FeatureFlags |= 0x200000;

	// Misc
	if ( m_NetState->isClientKR() || m_NetState->isClientEnhanced() )
	{
		if ( g_Cfg.m_iFeatureExtra & FEATURE_EXTRA_ROLEPLAYFACES )
			m_FeatureFlags |= 0x2000;
	}
}
Example #11
0
void CClient::UpdateCharacterListFlags()
{
	ADDTOCALLSTACK("CClient::UpdateCharacterListFlags");
	// Update character list features enabled on this client

	// 0x0001		Unknown
	// 0x0002		Overwrite config buttons
	// 0x0004		Single character slot
	// 0x0008		Context menus
	// 0x0010		Limit character slots
	// 0x0020		Enable AOS features (tooltip, fight book)
	// 0x0040		Sixth character slot
	// 0x0080		Enable SE features
	// 0x0100		Enable ML features
	// 0x0200		Unknown (KR)
	// 0x0400		Enable KR/SA packet 0xE1 at character list (possibly other unknown effects)
	// 0x0800		Unknown (KR/SA)
	// 0x1000		Seventh character slot
	// 0x2000		Unknown (SA)
	// 0x4000		Enable new SA movement packets 0xF0 / 0xF1 / 0xF2
	// 0x8000		New Felucca areas / faction strongholds (uses map0x.mul, statics0x.mul, etc) - client 7.0.6+

	if ( !m_pAccount )
		return;

	RESDISPLAY_VERSION iResDisp = static_cast<RESDISPLAY_VERSION>(m_pAccount->GetResDisp());
	BYTE bMaxChars = static_cast<BYTE>(maximum(m_pAccount->GetMaxChars(), m_pAccount->m_Chars.GetCharCount()));
	m_CharacterListFlags = 0;

	// Expansion features
	if ( iResDisp >= RDS_AOS )
	{
		if ( g_Cfg.m_iFeatureAOS & FEATURE_AOS_UPDATE_B )
			m_CharacterListFlags |= 0x20;
		if ( g_Cfg.m_iFeatureAOS & FEATURE_AOS_POPUP )
			m_CharacterListFlags |= 0x8;
	}

	if ( iResDisp >= RDS_SE )
	{
		if ( g_Cfg.m_iFeatureSE & FEATURE_SE_NINJASAM )
			m_CharacterListFlags |= 0x80;
	}

	if ( iResDisp >= RDS_ML )
	{
		if ( g_Cfg.m_iFeatureML & FEATURE_ML_UPDATE )
			m_CharacterListFlags |= 0x100;
	}

	if ( iResDisp >= RDS_KR )
	{
		if ( g_Cfg.m_iFeatureKR & FEATURE_KR_UPDATE )
			m_CharacterListFlags |= 0x200;
	}

	if ( iResDisp >= RDS_SA )
	{
		if ( g_Cfg.m_iFeatureSA & FEATURE_SA_MOVEMENT )
			m_CharacterListFlags |= 0x4000;
	}

	// Max character slots
	if ( bMaxChars > 6 )
		m_CharacterListFlags |= 0x1000;
	else if ( bMaxChars == 6 )
		m_CharacterListFlags |= 0x40;
	else if ( bMaxChars == 1 )
		m_CharacterListFlags |= (0x10|0x4);

	// Misc
	if ( m_NetState->isClientKR() || m_NetState->isClientEnhanced() )		// tooltips must be always enabled on enhanced clients
		m_CharacterListFlags |= (0x400|0x200|0x20);
	m_TooltipEnabled = (m_CharacterListFlags & 0x20);
	m_ContainerGridEnabled = (m_NetState->isClientVersion(MINCLIVER_CONTAINERGRID) || m_NetState->isClientKR() || m_NetState->isClientEnhanced());
	m_UseNewChatSystem = m_NetState->isClientVersion(MINCLIVER_NEWCHATSYSTEM);
}
void CStoneMember::SetAccountGold( int iGold )
{
	ADDTOCALLSTACK("CStoneMember::SetAccountGold");
	m_Member.m_iAccountGold = iGold;
}
int CStoneMember::GetAccountGold() const
{
	ADDTOCALLSTACK("CStoneMember::GetAccountGold");
	return( m_Member.m_iAccountGold );
}
CGrayUID CStoneMember::GetLoyalToUID() const
{
	ADDTOCALLSTACK("CStoneMember::GetLoyalToUID");
	return( m_uidLoyalTo );
}
Example #15
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, GetContainerCreate(LAYER_PACK), 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;
					default:
						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) )
				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:
		{
			if ( fLink || !pItem->Use_DoorNew(fLink) )	// 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 #16
0
bool CClient::r_Verb(CScript &s, CTextConsole *pSrc) // Execute command from script
{
	ADDTOCALLSTACK("CClient::r_Verb");
	EXC_TRY("Verb");
	// NOTE: This can be called directly from a RES_WEBPAGE script.
	//  So do not assume we are a game client !
	// NOTE: Mostly called from CChar::r_Verb
	// NOTE: Little security here so watch out for dangerous scripts !

	ASSERT(pSrc);
	LPCTSTR pszKey = s.GetKey();

	// Old ver
	if ( s.IsKeyHead("SET", 3) && !g_Cfg.m_Functions.ContainsKey(pszKey) )
	{
		PLEVEL_TYPE ilevel = g_Cfg.GetPrivCommandLevel("SET");
		if ( ilevel > GetPrivLevel() )
			return false;

		ASSERT(m_pChar);
		addTargetVerb(pszKey + 3, s.GetArgRaw());
		return true;
	}

	if ( (toupper(pszKey[0]) == 'X') && !g_Cfg.m_Functions.ContainsKey(pszKey) )
	{
		PLEVEL_TYPE ilevel = g_Cfg.GetPrivCommandLevel("SET");
		if ( ilevel > GetPrivLevel() )
			return false;

		// Target this command verb on some other object.
		ASSERT(m_pChar);
		addTargetVerb(pszKey + 1, s.GetArgRaw());
		return true;
	}

	int index = FindTableSorted(s.GetKey(), sm_szVerbKeys, COUNTOF(sm_szVerbKeys) - 1);
	switch ( index )
	{
		case CV_ADD:
		{
			if ( s.HasArgs() )
			{
				TCHAR *ppArgs[2];
				size_t iArgQty = Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

				if ( !IsValidGameObjDef(static_cast<LPCTSTR>(ppArgs[0])) )
				{
					g_Log.EventWarn("Invalid ADD argument '%s'\n", ppArgs[0]);
					SysMessageDefault(DEFMSG_CMD_INVALID);
					return true;
				}

				RESOURCE_ID rid = g_Cfg.ResourceGetID(RES_QTY, const_cast<LPCTSTR &>(ppArgs[0]));
				m_tmAdd.m_id = rid.GetResIndex();
				m_tmAdd.m_amount = (iArgQty > 1) ? static_cast<WORD>(maximum(ATOI(ppArgs[1]), 1)) : 1;

				if ( (rid.GetResType() == RES_CHARDEF) || (rid.GetResType() == RES_SPAWN) )
				{
					m_Targ_PrvUID.InitUID();
					return addTargetChars(CLIMODE_TARG_ADDCHAR, static_cast<CREID_TYPE>(m_tmAdd.m_id), false);
				}
				else
					return addTargetItems(CLIMODE_TARG_ADDITEM, static_cast<ITEMID_TYPE>(m_tmAdd.m_id));
				break;
			}

			if ( IsValidDef("d_add") )
				Dialog_Setup(CLIMODE_DIALOG, g_Cfg.ResourceGetIDType(RES_DIALOG, "d_add"), 0, m_pChar);
			else
				Menu_Setup(g_Cfg.ResourceGetIDType(RES_MENU, "MENU_ADDITEM"));
			break;
		}
		case CV_ADDBUFF:
		{
			TCHAR *ppArgs[11];
			Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

			int iArgs[4];
			for ( int i = 0; i < 4; ++i )
			{
				if ( !IsStrNumeric(ppArgs[i]) )
				{
					DEBUG_ERR(("Invalid AddBuff argument number %u\n", i + 1));
					return true;
				}
				iArgs[i] = Exp_GetVal(ppArgs[i]);
			}
			if ( (iArgs[0] < 0) || (iArgs[0] > USHRT_MAX) )
			{
				DEBUG_ERR(("Invalid AddBuff icon ID\n"));
				break;
			}

			LPCTSTR pszArgs[7];
			size_t iArgQty = 0;
			for ( int i = 0; i < 7; ++i )
			{
				pszArgs[i] = ppArgs[i + 4];
				if ( pszArgs[i] != NULL )
					++iArgQty;
			}

			addBuff(static_cast<BUFF_ICONS>(iArgs[0]), static_cast<DWORD>(iArgs[1]), static_cast<DWORD>(iArgs[2]), static_cast<WORD>(iArgs[3]), pszArgs, iArgQty);
			break;
		}
		case CV_REMOVEBUFF:
		{
			BUFF_ICONS IconId = static_cast<BUFF_ICONS>(s.GetArgVal());
			if ( (IconId < 0) || (IconId > USHRT_MAX) )
			{
				DEBUG_ERR(("Invalid RemoveBuff icon ID\n"));
				break;
			}
			removeBuff(IconId);
			break;
		}
		case CV_ADDCLILOC:
		{
			// Add cliloc in @ClientTooltip trigger
			TCHAR *ppArgs[256];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",");
			DWORD dwClilocId = static_cast<DWORD>(Exp_GetLLVal(ppArgs[0]));

			CGString sVal;
			for ( size_t i = 1; i < iArgQty; ++i )
			{
				if ( sVal.GetLength() )
					sVal += "\t";
				sVal += !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i];
			}

			if ( g_Cfg.m_wDebugFlags & DEBUGF_SCRIPTS )
				g_Log.EventDebug("SCRIPT: addcliloc(%lu,'%s')\n", dwClilocId, static_cast<LPCTSTR>(sVal));
			m_TooltipData.Add(new CClientTooltip(dwClilocId, sVal));
			break;
		}
		case CV_ADDCONTEXTENTRY:
		{
			TCHAR *ppArgs[20];
			if ( Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",") > 4 )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: Function takes maximum of 4 arguments!\n"));
				return true;
			}
			if ( !m_pPopupPacket )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: Not used under a @ContextMenuRequest/@itemContextMenuRequest trigger!\n"));
				return true;
			}

			for ( int i = 0; i < 4; ++i )
			{
				if ( (i > 1) && IsStrEmpty(ppArgs[i]) )
					continue;

				if ( !IsStrNumeric(ppArgs[i]) )
				{
					DEBUG_ERR(("Bad AddContextEntry usage: Argument %d must be a number!\n", i + 1));
					return true;
				}
			}

			int iTextEntry = Exp_GetVal(ppArgs[0]);
			if ( iTextEntry < 100 )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: TextEntry < 100 is reserved for server usage!\n"));
				return true;
			}
			m_pPopupPacket->addOption(static_cast<WORD>(iTextEntry), static_cast<DWORD>(Exp_GetLLVal(ppArgs[1])), static_cast<WORD>(Exp_GetLLVal(ppArgs[2])), static_cast<WORD>(Exp_GetLLVal(ppArgs[3])));
			break;
		}
		case CV_ARROWQUEST:
		{
			INT64 piVal[3];
			Str_ParseCmds(s.GetArgRaw(), piVal, COUNTOF(piVal));
			addArrowQuest(static_cast<WORD>(piVal[0]), static_cast<WORD>(piVal[1]), static_cast<DWORD>(piVal[2]));
			break;
		}
		case CV_BADSPAWN:
		{
			// Loop the world searching for bad spawns
			bool fFound = false;
			CItem *pItem = NULL;
			CSector *pSector = NULL;
			CResourceDef *pSpawnDef = NULL;
			for ( int m = 0; (m < 256) && !fFound; ++m )
			{
				if ( !g_MapList.m_maps[m] )
					continue;

				for ( int s = 0; (s < g_MapList.GetSectorQty(m)) && !fFound; ++s )
				{
					pSector = g_World.GetSector(m, s);
					if ( !pSector )
						continue;

					for ( pItem = static_cast<CItem *>(pSector->m_Items_Timer.GetHead()); (pItem != NULL) && !fFound; pItem = pItem->GetNext() )
					{
						if ( pItem->IsType(IT_SPAWN_ITEM) || pItem->IsType(IT_SPAWN_CHAR) )
						{
							pSpawnDef = static_cast<CItemSpawn *>(pItem)->FixDef();
							if ( !pSpawnDef )
							{
								RESOURCE_ID_BASE rid = pItem->IsType(IT_SPAWN_ITEM) ? pItem->m_itSpawnItem.m_ItemID : pItem->m_itSpawnChar.m_CharID;
								CPointMap pt = pItem->GetTopPoint();
								m_pChar->Spell_Teleport(pt, true, false);
								m_pChar->m_Act_Targ = pItem->GetUID();
								SysMessagef("Bad spawn (0%lx, id=%s). Set as ACT", static_cast<DWORD>(pItem->GetUID()), g_Cfg.ResourceGetName(rid));
								fFound = true;
							}
						}
					}
				}
			}
			if ( !fFound )
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NO_BAD_SPAWNS));
			break;
		}
		case CV_BANKSELF:
		{
			addBankOpen(m_pChar, LAYER_BANKBOX);
			break;
		}
		case CV_CAST:
		{
			SPELL_TYPE spell = static_cast<SPELL_TYPE>(g_Cfg.ResourceGetIndexType(RES_SPELL, s.GetArgStr()));
			const CSpellDef *pSpellDef = g_Cfg.GetSpellDef(spell);
			if ( !pSpellDef )
				return true;

			CObjBase *pObjSrc = dynamic_cast<CObjBase *>(pSrc);
			if ( IsSetMagicFlags(MAGICF_PRECAST) && !pSpellDef->IsSpellType(SPELLFLAG_NOPRECAST) )
			{
				int iSkill;
				if ( !pSpellDef->GetPrimarySkill(&iSkill, NULL) )
					return true;

				m_tmSkillMagery.m_Spell = spell;	// m_atMagery.m_Spell
				m_pChar->m_atMagery.m_Spell = spell;
				if ( pObjSrc )
				{
					m_Targ_UID = pObjSrc->GetUID();	// default target.
					m_Targ_PrvUID = pObjSrc->GetUID();
				}
				else
				{
					m_Targ_UID.ClearUID();
					m_Targ_PrvUID.ClearUID();
				}
				m_pChar->Skill_Start(static_cast<SKILL_TYPE>(iSkill));
				break;
			}
			else
				Cmd_Skill_Magery(spell, pObjSrc);
			break;
		}
		case CV_CHANGEFACE:		// open 'face selection' dialog (enhanced clients only)
		{
			addGumpDialog(CLIMODE_DIALOG, NULL, 0, NULL, 0, 0, 0, m_pChar, CLIMODE_DIALOG_FACESELECTION);
			break;
		}
		case CV_CHARLIST:		// usually just a gm command
		{
			if ( !PacketChangeCharacter::CanSendTo(m_NetState) )
				break;
			new PacketChangeCharacter(this);
			CharDisconnect();	// since there is no undoing this in the client.
			SetTargMode(CLIMODE_SETUP_CHARLIST);
			break;
		}
		case CV_CTAGLIST:
		{
			if ( !strcmpi(s.GetArgStr(), "log") )
				pSrc = &g_Serv;
			m_TagDefs.DumpKeys(pSrc, "CTAG.");
			break;
		}
		case CV_CLEARCTAGS:
		{
			if ( s.HasArgs() )
			{
				LPCTSTR pszArgs = s.GetArgStr();
				SKIP_SEPARATORS(pszArgs);
				m_TagDefs.ClearKeys(pszArgs);
			}
			else
				m_TagDefs.ClearKeys();
			break;
		}
		case CV_CLOSEPAPERDOLL:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				closeUIWindow(pChar, 0x1);
			break;
		}
		case CV_CLOSEPROFILE:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				closeUIWindow(pChar, 0x8);
			break;
		}
		case CV_CLOSESTATUS:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				closeUIWindow(pChar, 0x2);
			break;
		}
		case CV_CODEXOFWISDOM:
		{
			INT64 piArgs[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), piArgs, COUNTOF(piArgs));
			if ( iArgQty < 1 )
			{
				SysMessage("Usage: CODEXOFWISDOM TopicID [ForceOpen]");
				break;
			}

			addCodexOfWisdom(static_cast<DWORD>(piArgs[0]), static_cast<bool>(piArgs[1]));
			break;
		}
		case CV_DYE:
		{
			const CObjBase *pObj = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).ObjFind() : NULL;
			if ( pObj )
				addDyeOption(pObj);
			break;
		}
		case CV_EVERBTARG:
		{
			m_Prompt_Text = s.GetArgStr();
			addPromptConsole(CLIMODE_PROMPT_TARG_VERB, m_Targ_Text.IsEmpty() ? "Enter the verb" : "Enter the text", m_Targ_UID);
			break;
		}
		case CV_EXTRACT:
		{
			// sort of like EXPORT but for statics.
			// Opposite of the "UNEXTRACT" command
			TCHAR *ppArgs[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty < 2 )
			{
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_EXTRACT_USAGE));
				break;
			}

			m_Targ_Text = ppArgs[0];				// point at the options (if any)
			m_tmTile.m_ptFirst.InitPoint();			// clear this first
			m_tmTile.m_Code = CV_EXTRACT;			// set extract code
			m_tmTile.m_id = Exp_GetVal(ppArgs[1]);	// extract id
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_EXTRACT_AREA), true);
			break;
		}
		case CV_UNEXTRACT:
		{
			// Create item from script.
			// Opposite of the "EXTRACT" command
			TCHAR *ppArgs[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty < 2 )
			{
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_UNEXTRACT_USAGE));
				break;
			}

			m_Targ_Text = ppArgs[0];				// point at the options (if any)
			m_tmTile.m_ptFirst.InitPoint();			// clear this first
			m_tmTile.m_Code = CV_UNEXTRACT;			// set extract code
			m_tmTile.m_id = Exp_GetVal(ppArgs[1]);	// extract id
			addTarget(CLIMODE_TARG_UNEXTRACT, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_MULTI_POS), true);
			break;
		}
		case CV_GMPAGE:
		{
			m_Targ_Text = s.GetArgStr();
			if ( !m_Targ_Text.IsEmpty() && !strnicmp(m_Targ_Text, "ADD ", 4) )
			{
				Cmd_GM_Page(m_Targ_Text + 4);
				break;
			}
			addPromptConsole(CLIMODE_PROMPT_GM_PAGE_TEXT, g_Cfg.GetDefaultMsg(DEFMSG_GMPAGE_PROMPT));
			break;
		}
		case CV_GOTARG:		// go to my (preselected) target.
		{
			ASSERT(m_pChar);
			CObjBase *pObj = m_Targ_UID.ObjFind();
			if ( pObj )
			{
				CPointMap pt = pObj->GetTopLevelObj()->GetTopPoint();
				m_pChar->m_dirFace = m_pChar->GetDir(pObj, m_pChar->m_dirFace);
				m_pChar->Spell_Teleport(pt, true, false);
			}
			break;
		}
		case CV_INFO:
		{
			// We could also get ground tile info.
			addTarget(CLIMODE_TARG_OBJ_INFO, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_ITEM_INFO), true, false);
			break;
		}
		case CV_INFORMATION:
		{
			SysMessage(g_Serv.GetStatusString(0x22));
			SysMessage(g_Serv.GetStatusString(0x24));
			break;
		}
		case CV_LAST:	// fake previous target
		{
			if ( GetTargMode() >= CLIMODE_MOUSE_TYPE )
			{
				ASSERT(m_pChar);
				CObjBase *pObj = m_pChar->m_Act_Targ.ObjFind();
				if ( pObj )
				{
					Event_Target(GetTargMode(), pObj->GetUID(), pObj->GetTopPoint());
					addTargetCancel();
				}
				break;
			}
			return false;
		}
		case CV_LINK:	// link doors
		{
			m_Targ_UID.InitUID();
			addTarget(CLIMODE_TARG_LINK, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_LINK_ITEM));
			break;
		}
		case CV_MAPWAYPOINT:
		{
			INT64 piVal[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), piVal, COUNTOF(piVal));
			if ( iArgQty < 2 )
			{
				SysMessage("Usage: MAPWAYPOINT uid type");
				break;
			}
			CObjBase *pObj = static_cast<CGrayUID>(piVal[0]).ObjFind();
			addMapWaypoint(pObj, static_cast<MAPWAYPOINT_TYPE>(piVal[1]));
			break;
		}
		case CV_MENU:
		{
			Menu_Setup(g_Cfg.ResourceGetIDType(RES_MENU, s.GetArgStr()));
			break;
		}
		case CV_MIDILIST:
		{
			INT64 piMidi[64];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), piMidi, COUNTOF(piMidi));
			if ( iArgQty > 0 )
				addMusic(static_cast<MIDI_TYPE>(piMidi[Calc_GetRandVal(iArgQty)]));
			break;
		}
		case CV_NUDGE:
		{
			if ( !s.HasArgs() )
			{
				SysMessage("Usage: NUDGE dx dy dz");
				break;
			}
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint();		// clear this first
			m_tmTile.m_Code = CV_NUDGE;
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_NUDGE_AREA), true);
			break;
		}
		case CV_NUKE:
		{
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint();		// clear this first
			m_tmTile.m_Code = CV_NUKE;			// set nuke code
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_NUKE_AREA), true);
			break;
		}
		case CV_NUKECHAR:
		{
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint();		// clear this first
			m_tmTile.m_Code = CV_NUKECHAR;		// set nuke code
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_NUKE_CHAR_AREA), true);
			break;
		}
		case CV_OPENPAPERDOLL:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				addCharPaperdoll(pChar);
			break;
		}
		case CV_OPENTRADEWINDOW:
		{
			TCHAR *ppArgs[2];
			Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

			CChar *pChar = ppArgs[0] ? static_cast<CGrayUID>(Exp_GetLLVal(ppArgs[0])).CharFind() : NULL;
			if ( pChar )
			{
				CItem *pItem = ppArgs[1] ? static_cast<CGrayUID>(Exp_GetLLVal(ppArgs[1])).ItemFind() : NULL;
				Cmd_SecureTrade(pChar, pItem);
			}
			break;
		}
		case CV_PAGE:
			Cmd_GM_PageCmd(s.GetArgStr());
			break;
		case CV_REPAIR:
			addTarget(CLIMODE_TARG_REPAIR, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_ITEM_REPAIR));
			break;
		case CV_FLUSH:
#ifndef _MTNETWORK
			g_NetworkOut.flush(this);
#else
			g_NetworkManager.flush(m_NetState);
#endif
			break;
		case CV_RESEND:
			addReSync();
			break;
		case CV_SAVE:
			g_World.Save(s.GetArgVal() != 0);
			break;
		case CV_SCROLL:
			// put a scroll up.
			addScrollResource(s.GetArgStr(), SCROLL_TYPE_UPDATES);
			break;
		case CV_SENDPACKET:
			SendPacket(s.GetArgStr());
			break;
		case CV_SELF:		// fake self target
			if ( GetTargMode() >= CLIMODE_MOUSE_TYPE )
			{
				ASSERT(m_pChar);
				Event_Target(GetTargMode(), m_pChar->GetUID(), m_pChar->GetTopPoint());
				addTargetCancel();
				break;
			}
			return false;
		case CV_SHOWSKILLS:
			addSkillWindow(static_cast<SKILL_TYPE>(g_Cfg.m_iMaxSkill));		// reload the real skills
			break;
		case CV_SKILLMENU:
			Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, s.GetArgStr()));
			break;
		case CV_SKILLSELECT:
			Event_Skill_Use(g_Cfg.FindSkillKey(s.GetArgStr()));
			break;
		case CV_SUMMON:
		{
			ASSERT(m_pChar);
			const CSpellDef *pSpellDef = g_Cfg.GetSpellDef(SPELL_Summon);
			if ( !pSpellDef )
				return false;

			m_pChar->m_Act_Targ = m_pChar->GetUID();
			m_pChar->m_Act_TargPrv = m_pChar->GetUID();

			if ( pSpellDef->IsSpellType(SPELLFLAG_TARG_OBJ|SPELLFLAG_TARG_XYZ) )
			{
				m_tmSkillMagery.m_Spell = SPELL_Summon;
				m_tmSkillMagery.m_SummonID = static_cast<CREID_TYPE>(g_Cfg.ResourceGetIndexType(RES_CHARDEF, s.GetArgStr()));

				LPCTSTR pszPrompt = g_Cfg.GetDefaultMsg(DEFMSG_SELECT_MAGIC_TARGET);
				if ( !pSpellDef->m_sTargetPrompt.IsEmpty() )
					pszPrompt = pSpellDef->m_sTargetPrompt;

				int iSpellTimeout = static_cast<int>(GetDefNum("SPELLTIMEOUT"));
				if ( !iSpellTimeout )
					iSpellTimeout = g_Cfg.m_iSpellTimeout * TICK_PER_SEC;

				addTarget(CLIMODE_TARG_SKILL_MAGERY, pszPrompt, pSpellDef->IsSpellType(SPELLFLAG_TARG_XYZ), pSpellDef->IsSpellType(SPELLFLAG_HARM), iSpellTimeout);
				break;
			}
			else
			{
				m_pChar->m_atMagery.m_Spell = SPELL_Summon;
				m_pChar->m_atMagery.m_SummonID = static_cast<CREID_TYPE>(g_Cfg.ResourceGetIndexType(RES_CHARDEF, s.GetArgStr()));

				if ( IsSetMagicFlags(MAGICF_PRECAST) && !pSpellDef->IsSpellType(SPELLFLAG_NOPRECAST) )
				{
					m_pChar->Spell_CastDone();
					break;
				}
				else
				{
					int iSkill;
					if ( !pSpellDef->GetPrimarySkill(&iSkill, NULL) )
						return false;

					m_pChar->Skill_Start(static_cast<SKILL_TYPE>(iSkill));
				}
			}
			break;
		}
		case CV_SMSG:
		case CV_SYSMESSAGE:
			SysMessage(s.GetArgStr());
			break;
		case CV_SYSMESSAGEF:	// there is still an issue with numbers not resolving properly when %i,%d,or other numeric format code is in use
		{
			TCHAR *ppArgs[4];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty < 2 )
			{
				g_Log.EventError("SysMessagef with less than 1 args for the given text\n");
				return false;
			}
			if ( iArgQty > 4 )
			{
				g_Log.EventError("Too many arguments given to SysMessagef (max = text + 3\n");
				return false;
			}
			if ( *ppArgs[0] == '"' )	// skip quotes
				++ppArgs[0];
			for ( TCHAR *pEnd = ppArgs[0] + strlen(ppArgs[0]) - 1; pEnd >= ppArgs[0]; --pEnd )
			{
				if ( *pEnd == '"' )		// skip quotes
				{
					*pEnd = '\0';
					break;
				}
			}
			SysMessagef(ppArgs[0], ppArgs[1], ppArgs[2] ? ppArgs[2] : 0, ppArgs[3] ? ppArgs[3] : 0);
			break;
		}
		case CV_SMSGU:
		case CV_SYSMESSAGEUA:
		{
			TCHAR *ppArgs[5];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty > 4 )
			{
				// Font and mode are actually ignored here, but they never made a difference anyway.. I'd like to keep the syntax similar to SAYUA
				NCHAR szBuffer[MAX_TALK_BUFFER];
				CvtSystemToNUNICODE(szBuffer, COUNTOF(szBuffer), ppArgs[4], -1);

				addBarkUNICODE(szBuffer, NULL, static_cast<HUE_TYPE>(Exp_GetLLVal(ppArgs[0])), TALKMODE_SYSTEM, FONT_NORMAL, ppArgs[3]);
			}
			break;
		}
		case CV_SMSGL:
		case CV_SYSMESSAGELOC:
		{
			TCHAR *ppArgs[256];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",");
			if ( iArgQty > 1 )
			{
				HUE_TYPE hue = HUE_TEXT_DEF;
				if ( ATOI(ppArgs[0]) > 0 )
					hue = static_cast<HUE_TYPE>(Exp_GetLLVal(ppArgs[0]));

				DWORD dwClilocId = static_cast<DWORD>(Exp_GetLLVal(ppArgs[1]));

				CGString sVal;
				for ( size_t i = 2; i < iArgQty; ++i )
				{
					if ( sVal.GetLength() )
						sVal += "\t";
					sVal += !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i];
				}

				addBarkLocalized(dwClilocId, NULL, hue, TALKMODE_SYSTEM, FONT_NORMAL, sVal.GetPtr());
			}
			break;
		}
		case CV_SMSGLEX:
		case CV_SYSMESSAGELOCEX:
		{
			TCHAR *ppArgs[256];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",");
			if ( iArgQty > 2 )
			{
				HUE_TYPE hue = HUE_TEXT_DEF;
				AFFIX_TYPE affix = AFFIX_APPEND;
				if ( ATOI(ppArgs[0]) > 0 )
					hue = static_cast<HUE_TYPE>(Exp_GetLLVal(ppArgs[0]));

				DWORD dwClilocId = static_cast<DWORD>(Exp_GetLLVal(ppArgs[1]));

				if ( ppArgs[2] )
					affix = static_cast<AFFIX_TYPE>(Exp_GetLLVal(ppArgs[2]));

				CGString sVal;
				for ( size_t i = 4; i < iArgQty; ++i )
				{
					if ( sVal.GetLength() )
						sVal += "\t";
					sVal += !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i];
				}

				addBarkLocalizedEx(dwClilocId, NULL, hue, TALKMODE_SYSTEM, FONT_NORMAL, affix, ppArgs[3], sVal.GetPtr());
			}
			break;
		}
		case CV_TELE:
			Cmd_Skill_Magery(SPELL_Teleport, dynamic_cast<CObjBase *>(pSrc));
			break;
		case CV_TILE:
			if ( !s.HasArgs() )
			{
				SysMessage("Usage: TILE z-height item1 item2 itemX");
				break;
			}
			m_Targ_Text = s.GetArgStr();	// point at the options
			m_tmTile.m_ptFirst.InitPoint();	// clear this first
			m_tmTile.m_Code = CV_TILE;
			addTarget(CLIMODE_TARG_TILE, "Pick 1st corner:", true);
			break;
		case CV_VERSION:
			SysMessage(g_szServerDescription);
			break;
		case CV_WEBLINK:
			addWebLaunch(s.GetArgStr());
			break;
		default:
			if ( r_LoadVal(s) )
			{
				CGString sVal;
				if ( r_WriteVal(s.GetKey(), sVal, pSrc) )
					return true;
			}
			return CScriptObj::r_Verb(s, pSrc);		// used in the case of web pages to access server level things
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPTSRC;
	EXC_DEBUG_END;
	return false;
}
Example #17
0
bool CChar::Use_Train_Dummy( CItem * pItem, bool fSetup )
{
	ADDTOCALLSTACK("CChar::Use_Train_Dummy");
	// IT_TRAIN_DUMMY
	// Dummy animation timer prevents over dclicking.

	ASSERT(pItem);
	SKILL_TYPE skill = Fight_GetWeaponSkill();
	if ( g_Cfg.IsSkillFlag(skill, SKF_RANGED) )		// do not allow archery training on dummys
	{
		SysMessageDefault(DEFMSG_ITEMUSE_TDUMMY_ARCH);
		return false;
	}

	char skilltag[32];
	sprintf(skilltag, "OVERRIDE.PracticeMax.SKILL_%d", skill &~0xD2000000);
	CVarDefCont *pSkillTag = pItem->GetKey(skilltag, true);
	WORD iMaxSkill = pSkillTag ? static_cast<WORD>(pSkillTag->GetValNum()) : g_Cfg.m_iSkillPracticeMax;

	if ( Skill_GetBase(skill) > iMaxSkill )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_TDUMMY_SKILL);
		return false;
	}
	if ( !pItem->IsTopLevel() )
	{
	baddumy:
		SysMessageDefault(DEFMSG_ITEMUSE_TDUMMY_P);
		return false ;
	}

	// Check location
	int dx = GetTopPoint().m_x - pItem->GetTopPoint().m_x;
	int dy = GetTopPoint().m_y - pItem->GetTopPoint().m_y;

	if ( pItem->GetDispID() == ITEMID_DUMMY1 )
	{
		if ( !(!dx && abs(dy) < 2) )
			goto baddumy;
	}
	else
	{
		if ( !(!dy && abs(dx) < 2) )
			goto baddumy;
	}

	if ( fSetup )
	{
		if ( Skill_GetActive() == NPCACT_TRAINING )
			return true;
		UpdateAnimate(ANIM_ATTACK_WEAPON);
		m_Act_TargPrv = m_uidWeapon;
		m_Act_Targ = pItem->GetUID();
		Skill_Start(NPCACT_TRAINING);
	}
	else
	{
		static const SOUND_TYPE sm_TrainingDummySounds[] = { 0x3A4, 0x3A6, 0x3A9, 0x3AE, 0x3B4, 0x3B6 };
		pItem->Sound(sm_TrainingDummySounds[Calc_GetRandVal(COUNTOF(sm_TrainingDummySounds))]);
		pItem->SetAnim(static_cast<ITEMID_TYPE>(pItem->GetID() + 1), 3 * TICK_PER_SEC);
		Skill_UseQuick(skill, Calc_GetRandLLVal(40));
	}
	return true;
}
Example #18
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;
}
Example #19
0
bool CChar::Use_Train_ArcheryButte( CItem * pButte, bool fSetup )
{
	ADDTOCALLSTACK("CChar::Use_Train_ArcheryButte");
	// IT_ARCHERY_BUTTE
	ASSERT(pButte);

	ITEMID_TYPE AmmoID;
	if ( GetDist(pButte) < 2 )		// if we are standing right next to the butte, retrieve the arrows/bolts
	{
		if ( pButte->m_itArcheryButte.m_AmmoCount == 0 )
		{
			SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_EMPTY);
			return true;
		}

		AmmoID = pButte->m_itArcheryButte.m_AmmoType;
		CItemBase *pAmmoDef = CItemBase::FindItemBase(AmmoID);
		if ( pAmmoDef )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REM), pAmmoDef->GetName(), (pButte->m_itArcheryButte.m_AmmoCount == 1) ? "" : g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REMS));
			Emote(pszMsg);

			CItem *pRemovedAmmo = CItem::CreateBase(AmmoID);
			ASSERT(pRemovedAmmo);
			pRemovedAmmo->SetAmount(pButte->m_itArcheryButte.m_AmmoCount);
			ItemBounce(pRemovedAmmo);
		}

		// Clear the target
		pButte->m_itArcheryButte.m_AmmoType = ITEMID_NOTHING;
		pButte->m_itArcheryButte.m_AmmoCount = 0;
		return true;
	}

	SKILL_TYPE skill = Fight_GetWeaponSkill();
	if ( !g_Cfg.IsSkillFlag(skill, SKF_RANGED) )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_WS);
		return true;
	}
	if ( Skill_GetBase(skill) > g_Cfg.m_iSkillPracticeMax )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_SKILL);
		return true;
	}

	// Make sure we have some ammo
	CItem *pWeapon = m_uidWeapon.ItemFind();
	ASSERT(pWeapon);
	const CItemBase *pWeaponDef = pWeapon->Item_GetDef();

	// Determine ammo type
	CVarDefCont *pVarAmmoType = pWeapon->GetDefKey("AMMOTYPE", true);
	RESOURCE_ID_BASE rid;
	LPCTSTR t_Str;

	if ( pVarAmmoType )
	{
		t_Str = pVarAmmoType->GetValStr();
		rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
	}
	else
	{
		rid = pWeaponDef->m_ttWeaponBow.m_idAmmo;
	}
	AmmoID = static_cast<ITEMID_TYPE>(rid.GetResIndex());

	// If there is a different ammo type on the butte currently, tell us to remove the current type first
	if ( (pButte->m_itArcheryButte.m_AmmoType != ITEMID_NOTHING) && (pButte->m_itArcheryButte.m_AmmoType != AmmoID) )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_X);
		return true;
	}

	// We need to be correctly aligned with the target before we can use it
	// For the south facing butte, we need to have the same X value and a Y > 2
	// For the east facing butte, we need to have the same Y value and an X > 2
	if ( !pButte->IsTopLevel() )
	{
	badalign:
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_P);
		return true;
	}

	int targDistX = GetTopPoint().m_x - pButte->GetTopPoint().m_x;
	int targDistY = GetTopPoint().m_y - pButte->GetTopPoint().m_y;

	if ( (pButte->GetID() == ITEMID_ARCHERYBUTTE_S) || (pButte->GetID() == ITEMID_MONGBATTARGET_S) )
	{
		if ( !(targDistX == 0 && targDistY > 2) )
			goto badalign;
	}
	else
	{
		if ( !(targDistY == 0 && targDistX > 2) )
			goto badalign;
	}

	if ( !CanSeeLOS(pButte, LOS_NB_WINDOWS) )	//we should be able to shoot through a window
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_BLOCK);
		return true;
	}

	if ( fSetup )
	{
		if ( Skill_GetActive() == NPCACT_TRAINING )
			return true;
		UpdateAnimate(ANIM_ATTACK_WEAPON);
		m_Act_TargPrv = m_uidWeapon;
		m_Act_Targ = pButte->GetUID();
		Skill_Start(NPCACT_TRAINING);
		return true;
	}

	CVarDefCont *pCont = pWeapon->GetDefKey("AMMOCONT",true);

	if ( m_pPlayer && AmmoID )
	{
		DWORD iFound = 1;
		if ( pCont )
		{
			//check for UID
			CGrayUID uidCont = static_cast<CGrayUID>(pCont->GetValNum());
			CItemContainer *pNewCont = dynamic_cast<CItemContainer *>(uidCont.ItemFind());
			if ( !pNewCont )	//if no UID, check for ITEMID_TYPE
			{
				t_Str = pCont->GetValStr();
				RESOURCE_ID_BASE rContid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
				ITEMID_TYPE ContID = static_cast<ITEMID_TYPE>(rContid.GetResIndex());
				if ( ContID )
					pNewCont = dynamic_cast<CItemContainer *>(ContentFind(rContid));
			}

			if ( pNewCont )
				iFound = pNewCont->ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
			else
				iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
		}
		else
			iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
		if ( iFound )
		{
			SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_NOAMMO);
			return true;
		}
	}

	// OK...go ahead and fire at the target
	// Check the skill
	bool fSuccess = Skill_UseQuick(skill, Calc_GetRandLLVal(40));

	// determine animation parameters
	CVarDefCont *pVarAnim = pWeapon->GetDefKey("AMMOANIM", true);
	CVarDefCont *pVarAnimColor = pWeapon->GetDefKey("AMMOANIMHUE", true);
	CVarDefCont *pVarAnimRender = pWeapon->GetDefKey("AMMOANIMRENDER", true);
	ITEMID_TYPE AmmoAnim;
	DWORD AmmoHue = pVarAnimColor ? static_cast<DWORD>(pVarAnimColor->GetValNum()) : 0;
	DWORD AmmoRender = pVarAnimRender ? static_cast<DWORD>(pVarAnimRender->GetValNum()) : 0;

	if ( pVarAnim )
	{
		t_Str = pVarAnim->GetValStr();
		rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
		AmmoAnim = static_cast<ITEMID_TYPE>(rid.GetResIndex());
	}
	else
		AmmoAnim = static_cast<ITEMID_TYPE>(pWeaponDef->m_ttWeaponBow.m_idAmmoX.GetResIndex());

	pButte->Effect(EFFECT_BOLT, AmmoAnim, this, 16, 0, false, AmmoHue, AmmoRender);
	pButte->Sound(SOUND_CROSSBOW);

	// Did we destroy the ammo?
	const CItemBase *pAmmoDef = NULL;
	if ( AmmoID )
		pAmmoDef = CItemBase::FindItemBase(AmmoID);

	if ( !fSuccess )
	{
		// Small chance of destroying the ammo
		if ( pAmmoDef && !Calc_GetRandVal(10) )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_DEST), pAmmoDef->GetName());
			Emote(pszMsg, NULL, true);
			return true;
		}

		static LPCTSTR const sm_Txt_ArcheryButte_Failure[] =
		{
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_1),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_2),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_3),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_4)
		};
		Emote(sm_Txt_ArcheryButte_Failure[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Failure))]);
	}
	else
	{
		// Very small chance of destroying another arrow
		if ( pAmmoDef && !Calc_GetRandVal(50) && pButte->m_itArcheryButte.m_AmmoCount )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_SPLIT), pAmmoDef->GetName());
			Emote(pszMsg, NULL, true);
			return true;
		}

		static LPCTSTR const sm_Txt_ArcheryButte_Success[] =
		{
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_1),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_2),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_3),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_4)
		};
		Emote(sm_Txt_ArcheryButte_Success[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Success))]);
	}

	// Update the target
	if ( AmmoID )
	{
		pButte->m_itArcheryButte.m_AmmoType = AmmoID;
		pButte->m_itArcheryButte.m_AmmoCount++;
	}
	return true;
}
Example #20
0
bool CChar::NPC_OnHearPetCmd( LPCTSTR pszCmd, CChar * pSrc, bool fAllPets )
{
	ADDTOCALLSTACK("CChar::NPC_OnHearPetCmd");
	// This should just be another speech block !!!

	// We own this char (pet or hireling)
	// pObjTarget = the m_ActTarg has been set for them to attack.
	// RETURN:
	//  true = we understand this. tho we may not do what we are told.
	//  false = this is not a command we know.
	//  if ( GetTargMode() == CLIMODE_TARG_PET_CMD ) it needs a target.

	static LPCTSTR const sm_Pet_table[] =
	{
		"ATTACK",
		"BOUGHT",
		"CASH",
		"COME",
		"DROP",	// "GIVE" ?
		"DROP ALL",
		"EQUIP",
		"FOLLOW",
		"FOLLOW ME",
		"FRIEND",
		"GO",
		"GUARD",
		"GUARD ME",
		"KILL",
		"PRICE",	// may have args ?
		"RELEASE",
		"SAMPLES",
		"SPEAK",
		"STATUS",
		"STAY",
		"STOCK",
		"STOP",
		"TRANSFER",
		"RELEASE"
	};

	// Kill me?
	// attack me?
	m_fIgnoreNextPetCmd = false;	// We clear this incase it's true from previous pet cmds.

	if ( !pSrc->IsClient() || m_pPlayer || !m_pNPC )
		return false;

	TALKMODE_TYPE	mode	= TALKMODE_SAY;
	if ( OnTriggerSpeech( true, pszCmd, pSrc, mode) )
	{
		m_fIgnoreNextPetCmd = !fAllPets;
		return true;
	}

	PC_TYPE iCmd = (PC_TYPE) FindTableSorted( pszCmd, sm_Pet_table, COUNTOF(sm_Pet_table));
	if ( iCmd < 0 )
	{
		if ( ! strnicmp( pszCmd, sm_Pet_table[PC_PRICE], 5 ))
			iCmd = PC_PRICE;
		else
			return false;
	}

	if ( iCmd == PC_FOLLOW || iCmd == PC_STAY || iCmd == PC_STOP )
	{
		// Pet friends can use only these commands
		if ( ! NPC_IsOwnedBy( pSrc, true ) && 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;
	}

	CCharBase * pCharDef = Char_GetDef();

	bool fTargAllowGround = false;
	bool fMayBeCrime = false;
	LPCTSTR pTargPrompt = NULL;

	switch ( iCmd )
	{
		case PC_ATTACK:
	do_attack:
			pTargPrompt = g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_TARG_ATT );
			fMayBeCrime = true;
			break;
		case PC_CASH:
			// Drop all we have.
			if ( ! NPC_IsVendor())
				return( false );
			{
				// Give up my cash total.
				CItemContainer * pBank = GetBank();
				if ( pBank )
				{
					unsigned int iWage = pCharDef->GetHireDayWage();
					TCHAR *pszMsg = Str_GetTemp();
					if ( pBank->m_itEqBankBox.m_Check_Amount > iWage )
					{
						sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_GETGOLD_1), pBank->m_itEqBankBox.m_Check_Amount - iWage);
						pSrc->AddGoldToPack( pBank->m_itEqBankBox.m_Check_Amount - iWage );
						pBank->m_itEqBankBox.m_Check_Amount = iWage;
					}
					else
						sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_GETGOLD_2), pBank->m_itEqBankBox.m_Check_Amount);
					Speak(pszMsg);
				}
				return true;
			}
			break;
		case PC_COME:
		case PC_GUARD_ME:
		case PC_FOLLOW_ME:
			m_Act_Targ = pSrc->GetUID();
			Skill_Start( NPCACT_FOLLOW_TARG );
			break;
		case PC_RELEASE:
			Skill_Start( SKILL_NONE );
			NPC_PetClearOwners();
			SoundChar( CRESND_RAND2 );	// No noise
			return( true );
		case PC_DROP:
			// Drop just the stuff we are carrying. (not wearing)
			// "GIVE" ?
			{
				CItemContainer * pPack = GetPack();
				if ( pPack )
				{
					if ( pPack->GetCount() > 0 )
					{
						pPack->ContentsDump( GetTopPoint(), ATTR_OWNED );
						break;
					}
				}
				if ( NPC_CanSpeak())
				{
					Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_CARRYNOTHING ) );
				}
				return( true );
			}
			break;
		case PC_DROP_ALL:
			DropAll( NULL, ATTR_OWNED );
			break;
		case PC_FOLLOW:
			pTargPrompt = g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_TARG_FOLLOW );
			break;
		case PC_FRIEND:
			pTargPrompt = g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_TARG_FRIEND );
			break;
		case PC_GO:
			pTargPrompt = g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_TARG_GO );
			fTargAllowGround = true;
			break;
		case PC_GUARD:
			pTargPrompt = g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_TARG_GUARD );
			fMayBeCrime = true;
			break;
		case PC_KILL:
			goto do_attack;
		case PC_PRICE:
			if ( ! NPC_IsVendor())
				return( false );
			pTargPrompt = g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_SETPRICE );
			break;
		case PC_SPEAK:
			NPC_OnPetCommand( true, pSrc );
			return( true );

		case PC_EQUIP:
			ItemEquipWeapon(false);
			ItemEquipArmor(false);
			break;

		case PC_STATUS:
			if ( NPC_CanSpeak() )
			{
				CItemContainer * pBank = GetBank();
				unsigned int iWage = pCharDef->GetHireDayWage();
				TCHAR *pszMsg = Str_GetTemp();
				if ( NPC_IsVendor() )
				{
					CItemContainer * pCont = GetBank(LAYER_VENDOR_STOCK);
					TCHAR *pszTemp1 = Str_GetTemp();
					TCHAR *pszTemp2 = Str_GetTemp();
					TCHAR *pszTemp3 = Str_GetTemp();
					if ( iWage )
					{
						sprintf(pszTemp1, g_Cfg.GetDefaultMsg( DEFMSG_NPC_VENDOR_STAT_GOLD_1 ), pBank->m_itEqBankBox.m_Check_Amount);
						sprintf(pszTemp2, g_Cfg.GetDefaultMsg( DEFMSG_NPC_VENDOR_STAT_GOLD_2 ), pBank->m_itEqBankBox.m_Check_Amount / iWage);
						sprintf(pszTemp3, g_Cfg.GetDefaultMsg( DEFMSG_NPC_VENDOR_STAT_GOLD_3 ), static_cast<int>(pCont->GetCount()) );
					}
					else
					{
						sprintf(pszTemp1, g_Cfg.GetDefaultMsg( DEFMSG_NPC_VENDOR_STAT_GOLD_1 ), pBank->m_itEqBankBox.m_Check_Amount );
						sprintf(pszTemp2, g_Cfg.GetDefaultMsg( DEFMSG_NPC_VENDOR_STAT_GOLD_4 ), pBank->m_itEqBankBox.m_Check_Restock, pBank->GetTimerAdjusted() / 60);
						sprintf(pszTemp3, g_Cfg.GetDefaultMsg( DEFMSG_NPC_VENDOR_STAT_GOLD_3 ), static_cast<int>(pCont->GetCount()) );
					}
					sprintf(pszMsg, "%s %s %s", pszTemp1, pszTemp2, pszTemp3);
				}
				else if ( iWage )
				{
					sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_DAYS_LEFT), pBank->m_itEqBankBox.m_Check_Amount / iWage);
				}
				Speak(pszMsg);
				return true;
			}
			break;
		case PC_STAY:
		case PC_STOP:
			Skill_Start( NPCACT_STAY );
			break;
		case PC_TRANSFER:
			pTargPrompt = g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_TARG_TRANSFER );
			break;

		case PC_STOCK:
			// Magic restocking container.
			if ( !NPC_IsVendor() || !pSrc->IsClient() )
				return false;
			Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_ITEMS_SELL ) );
			pSrc->GetClient()->addBankOpen( this, LAYER_VENDOR_STOCK );
			break;

		case PC_BOUGHT:
			if ( !NPC_IsVendor() || !pSrc->IsClient() )
				return false;
			Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_ITEMS_BUY ) );
			pSrc->GetClient()->addBankOpen( this, LAYER_VENDOR_EXTRA );
			break;

		case PC_SAMPLES:
			if ( !NPC_IsVendor() || !pSrc->IsClient() )
				return false;
			Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_ITEMS_SAMPLE ) );
			pSrc->GetClient()->addBankOpen( this, LAYER_VENDOR_BUYS );
			break;

		default:
			return( false );
	}

	if ( pTargPrompt )
	{
		pszCmd += strlen( sm_Pet_table[iCmd] );
		GETNONWHITESPACE( pszCmd );

		// I Need a target arg.

		if ( ! pSrc->IsClient())
			return( false );

		pSrc->m_pClient->m_tmPetCmd.m_iCmd = iCmd;
		pSrc->m_pClient->m_tmPetCmd.m_fAllPets = fAllPets;
		pSrc->m_pClient->m_Targ_UID = GetUID();
		pSrc->m_pClient->m_Targ_Text = pszCmd;

		pSrc->m_pClient->addTarget( CLIMODE_TARG_PET_CMD, pTargPrompt, fTargAllowGround, fMayBeCrime );
		return( true );
	}

	// make some sound to confirm we heard it.
	// Make the yes noise.
	NPC_OnPetCommand( true, pSrc );
	return( true );
}
Example #21
0
bool CChar::Use_Repair( CItem * pItemArmor )
{
	ADDTOCALLSTACK("CChar::Use_Repair");
	// Attempt to repair the item.
	// If it is repairable.

	if ( !pItemArmor || !pItemArmor->Armor_IsRepairable() )
	{
		SysMessageDefault(DEFMSG_REPAIR_NOT);
		return false;
	}

	if ( pItemArmor->IsItemEquipped() )
	{
		SysMessageDefault(DEFMSG_REPAIR_WORN);
		return false;
	}
	if ( !CanUse(pItemArmor, true) )
	{
		SysMessageDefault(DEFMSG_REPAIR_REACH);
		return false;
	}

	// Quickly use arms lore skill, but don't gain any skill until later on
	int iArmsLoreDiff = Calc_GetRandVal(30);
	if ( !Skill_UseQuick(SKILL_ARMSLORE, iArmsLoreDiff, false) )
	{
		// apply arms lore skillgain for failure
		Skill_Experience(SKILL_ARMSLORE, -iArmsLoreDiff);
		SysMessageDefault(DEFMSG_REPAIR_UNK);
		return false;
	}

	if ( pItemArmor->m_itArmor.m_Hits_Cur >= pItemArmor->m_itArmor.m_Hits_Max )
	{
		SysMessageDefault(DEFMSG_REPAIR_FULL);
		return false;
	}

	m_Act_p = g_World.FindItemTypeNearby(GetTopPoint(), IT_ANVIL, 2, false, true);
	if ( !m_Act_p.IsValidPoint() )
	{
		SysMessageDefault(DEFMSG_REPAIR_ANVIL);
		return false;
	}

	CItemBase *pItemDef = pItemArmor->Item_GetDef();
	ASSERT(pItemDef);

	// Use up some raw materials to repair.
	int iTotalHits = pItemArmor->m_itArmor.m_Hits_Max;
	int iDamageHits = pItemArmor->m_itArmor.m_Hits_Max - pItemArmor->m_itArmor.m_Hits_Cur;
	int iDamagePercent = IMULDIV(100, iDamageHits, iTotalHits);

	size_t iMissing = ResourceConsumePart(&(pItemDef->m_BaseResources), 1, iDamagePercent / 2, true);
	if ( iMissing != pItemDef->m_BaseResources.BadIndex() )
	{
		// Need this to repair.
		const CResourceDef *pCompDef = g_Cfg.ResourceGetDef(pItemDef->m_BaseResources.GetAt(iMissing).GetResourceID());
		SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_LACK_1), pCompDef ? pCompDef->GetName() : g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_LACK_2));
		return false;
	}

	UpdateDir(m_Act_p);
	UpdateAnimate(ANIM_ATTACK_1H_SLASH);

	// quarter the skill to make it.
	// + more damaged items should be harder to repair.
	// higher the percentage damage the closer to the skills to make it.

	size_t iRes = pItemDef->m_SkillMake.FindResourceType(RES_SKILL);
	if ( iRes == pItemDef->m_SkillMake.BadIndex() )
		return false;

	CResourceQty RetMainSkill = pItemDef->m_SkillMake[iRes];
	int iSkillLevel = static_cast<int>(RetMainSkill.GetResQty()) / 10;
	int iDifficulty = IMULDIV(iSkillLevel, iDamagePercent, 100);
	if ( iDifficulty < iSkillLevel / 4 )
		iDifficulty = iSkillLevel / 4;

	// apply arms lore skillgain now
	LPCTSTR pszText;
	Skill_Experience(SKILL_ARMSLORE, iArmsLoreDiff);
	bool fSuccess = Skill_UseQuick(static_cast<SKILL_TYPE>(RetMainSkill.GetResIndex()), iDifficulty);
	if ( fSuccess )
	{
		pItemArmor->m_itArmor.m_Hits_Cur = static_cast<WORD>(iTotalHits);
		pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_1);
	}
	else
	{
		/*****************************
		// not sure if this is working!
		******************************/
		// Failure
		if ( !Calc_GetRandVal(6) )
		{
			pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_2);
			pItemArmor->m_itArmor.m_Hits_Max--;
			pItemArmor->m_itArmor.m_Hits_Cur--;
		}
		else if ( !Calc_GetRandVal(3) )
		{
			pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_3);
			pItemArmor->m_itArmor.m_Hits_Cur--;
		}
		else
			pszText = g_Cfg.GetDefaultMsg( DEFMSG_REPAIR_4 );

		iDamagePercent = Calc_GetRandVal(iDamagePercent);	// some random amount
	}

	ResourceConsumePart(&(pItemDef->m_BaseResources), 1, iDamagePercent / 2, false);
	if ( pItemArmor->m_itArmor.m_Hits_Cur <= 0 )
		pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_5);

	TCHAR *pszMsg = Str_GetTemp();
	sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_MSG), pszText, pItemArmor->GetName());
	Emote(pszMsg);

	if ( pItemArmor->m_itArmor.m_Hits_Cur <= 0 )
		pItemArmor->Delete();
	else
		pItemArmor->UpdatePropertyFlag(AUTOTOOLTIP_FLAG_DURABILITY);

	return fSuccess;
}
Example #22
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) )
		{
			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);
	pPet->SoundChar(CRESND_RAND1);
	return pPet;
}
Example #23
0
bool 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 false;
	}

	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 false;
		}

		// 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"));
			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 false;
		}

		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);
	return true;
}
Example #24
0
bool CChar::Use_Key( CItem * pKey, CItem * pItemTarg )
{
	ADDTOCALLSTACK("CChar::Use_Key");
	ASSERT(pKey);
	ASSERT(pKey->IsType(IT_KEY));
	if ( !pItemTarg )
	{
		SysMessageDefault(DEFMSG_MSG_KEY_TARG);
		return false;
	}

	if ( pKey != pItemTarg && pItemTarg->IsType(IT_KEY) )
	{
		// We are trying to copy a key ?
		if ( !CanUse(pItemTarg, true) )
		{
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_REACH);
			return false;
		}

		if ( !pKey->m_itKey.m_lockUID && !pItemTarg->m_itKey.m_lockUID )
		{
			SysMessageDefault(DEFMSG_MSG_KEY_BLANKS);
			return false;
		}
		if ( pItemTarg->m_itKey.m_lockUID && pKey->m_itKey.m_lockUID )
		{
			SysMessageDefault(DEFMSG_MSG_KEY_NOTBLANKS);
			return false;
		}

		// Need tinkering tools ???
		if ( !Skill_UseQuick(SKILL_TINKERING, 30 + Calc_GetRandLLVal(40)) )
		{
			SysMessageDefault(DEFMSG_MSG_KEY_FAILC);
			return false;
		}
		if ( pItemTarg->m_itKey.m_lockUID )
			pKey->m_itKey.m_lockUID = pItemTarg->m_itKey.m_lockUID;
		else
			pItemTarg->m_itKey.m_lockUID = pKey->m_itKey.m_lockUID;
		return true;
	}

	if ( !pKey->m_itKey.m_lockUID )
	{
		SysMessageDefault(DEFMSG_MSG_KEY_ISBLANK);
		return false;
	}
	if ( pKey == pItemTarg )	// rename the key
	{
		if ( m_pClient )
			m_pClient->addPromptConsole(CLIMODE_PROMPT_NAME_KEY, g_Cfg.GetDefaultMsg(DEFMSG_MSG_KEY_SETNAME), pKey->GetUID());
		return false;
	}

	if ( !CanUse(pItemTarg, false) )
	{
		SysMessageDefault(DEFMSG_MSG_KEY_CANTREACH);
		return false;
	}

	if ( m_pArea->GetResourceID() == pKey->m_itKey.m_lockUID )
	{
		if ( Use_MultiLockDown(pItemTarg) )
			return true;
	}

	if ( !pItemTarg->m_itContainer.m_lockUID )	// or m_itContainer.m_lockUID
	{
		SysMessageDefault(DEFMSG_MSG_KEY_NOLOCK);
		return false;
	}
	if ( !pKey->IsKeyLockFit(pItemTarg->m_itContainer.m_lockUID) )	// or m_itKey
	{
		SysMessageDefault(DEFMSG_MSG_KEY_WRONGLOCK);
		return false;
	}

	return Use_KeyChange(pItemTarg);
}
Example #25
0
void CChat::DeleteChannel(CChatChannel * pChannel)
{
	ADDTOCALLSTACK("CChat::DeleteChannel");
	SendDeleteChannel(pChannel);	// tell everyone about it first.
	delete pChannel;
}
Example #26
0
bool CChar::Use_KeyChange( CItem * pItemTarg )
{
	ADDTOCALLSTACK("CChar::Use_KeyChange");
	// Lock or unlock the item.
	switch ( pItemTarg->GetType() )
	{
		case IT_SIGN_GUMP:
			// We may rename the sign.
			if ( m_pClient )
				m_pClient->addPromptConsole(CLIMODE_PROMPT_NAME_SIGN, g_Cfg.GetDefaultMsg(DEFMSG_MSG_KEY_TARG_SIGN), pItemTarg->GetUID());
			return true;
		case IT_CONTAINER:
			pItemTarg->SetType(IT_CONTAINER_LOCKED);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_CONT_LOCK);
			break;
		case IT_CONTAINER_LOCKED:
			pItemTarg->SetType(IT_CONTAINER);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_CONT_ULOCK);
			break;
		case IT_SHIP_HOLD:
			pItemTarg->SetType(IT_SHIP_HOLD_LOCK);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_HOLD_LOCK);
			break;
		case IT_SHIP_HOLD_LOCK:
			pItemTarg->SetType(IT_SHIP_HOLD);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_HOLD_ULOCK);
			break;
		case IT_DOOR:
		case IT_DOOR_OPEN:
			pItemTarg->SetType(IT_DOOR_LOCKED);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_DOOR_LOCK);
			break;
		case IT_DOOR_LOCKED:
			pItemTarg->SetType(IT_DOOR);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_DOOR_ULOCK);
			break;
		case IT_SHIP_TILLER:
			if ( m_pClient )
				m_pClient->addPromptConsole(CLIMODE_PROMPT_NAME_SHIP, g_Cfg.GetDefaultMsg(DEFMSG_MSG_SHIPNAME_PROMT), pItemTarg->GetUID());
			return true;
		case IT_SHIP_PLANK:
			pItemTarg->Ship_Plank(false);	// just close it.
			if ( pItemTarg->GetType() == IT_SHIP_SIDE_LOCKED )
			{
				pItemTarg->SetType(IT_SHIP_SIDE);
				SysMessageDefault(DEFMSG_MSG_KEY_TARG_SHIP_ULOCK);
				break;
			}
			// Then fall thru and lock it.
		case IT_SHIP_SIDE:
			pItemTarg->SetType(IT_SHIP_SIDE_LOCKED);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_SHIP_LOCK);
			break;
		case IT_SHIP_SIDE_LOCKED:
			pItemTarg->SetType(IT_SHIP_SIDE);
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_SHIP_ULOCK);
			break;
		default:
			SysMessageDefault(DEFMSG_MSG_KEY_TARG_NOLOCK);
			return false;
	}
	return true;
}
Example #27
0
void CChat::EventMsg( CClient * pClient, const nchar * pszText, int len, CLanguageID lang ) // Text from a client
{
	ADDTOCALLSTACK("CChat::EventMsg");
	// ARGS:
	//  len = length of the pszText string in nchar's.
	//

	CChatChanMember * pMe = pClient;
	ASSERT(pMe);

	// newer clients do not send the 'chat button' packet, leading to all kinds of problems
	// with the client not being initialised properly for chat (e.g. blank name and exceptions
	// when leaving a chat room) - if chat is not active then we must simulate the chat button
	// event before processing the chat message
	if (pMe->IsChatActive() == false)
	{
		// simulate the chat button being clicked
		pClient->Event_ChatButton(nullptr);

		// if chat isn't active now then cancel processing the event
		if (pMe->IsChatActive() == false)
			return;
	}

	CChatChannel * pChannel =  pMe->GetChannel();

	tchar szText[MAX_TALK_BUFFER * 2];
	CvtNUNICODEToSystem( szText, sizeof(szText), pszText, len );

	// The 1st character is a command byte, join channel, private message someone, etc etc
	tchar * szMsg = szText+1;
	switch ( szText[0] )
	{
	case 'a':	// a = client typed a plain message in the text entry area
	{
		// Check for a chat command here
		if (szMsg[0] == '/')
		{
			DoCommand(pMe, szMsg + 1);
			break;
		}
		if (!pChannel)
		{
not_in_a_channel:
			pMe->SendChatMsg(CHATMSG_MustBeInAConference);
			return;
		}
		// Not a chat command, must be speech
		pChannel->MemberTalk(pMe, szMsg, lang);
		break;
	};
	case 'A':	// A = change the channel password
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->ChangePassword(pMe, szMsg);
		break;
	};
	case 'b':	// b = client joining an existing channel
	{
		// Look for second double quote to separate channel from password
		size_t i = 1;
		for (; szMsg[i] != '\0'; i++)
			if (szMsg[i] == '"')
				break;
		szMsg[i] = '\0';
		tchar * pszPassword = szMsg + i + 1;
		if (pszPassword[0] == ' ') // skip leading space if any
			pszPassword++;
		JoinChannel( pMe, szMsg + 1, pszPassword);
		break;
	};
	case 'c':	// c = client creating (and joining) new channel
	{
		tchar * pszPassword = nullptr;
		size_t iMsgLength = strlen(szMsg);
		for (size_t i = 0; i < iMsgLength; i++)
		{
			if (szMsg[i] == '{') // OK, there's a password here
			{
				szMsg[i] = 0;
				pszPassword = szMsg + i + 1;
				size_t iPasswordLength = strlen(pszPassword);
				for (i = 0; i < iPasswordLength; i++)
				{
					if (pszPassword[i] == '}')
					{
						pszPassword[i] = '\0';
						break;
					}
				}
				break;
			}
		}
		CreateJoinChannel(pMe, szMsg, pszPassword);
		break;
	};
	case 'd':	// d = (/rename x) rename conference
	{
		if (!pChannel)
			goto not_in_a_channel;
		pMe->RenameChannel(szMsg);
		break;
	};
	case 'e':	// e = Send a private message to ....
	{
		if (!pChannel)
			goto not_in_a_channel;
		tchar buffer[2048];
		strcpy(buffer, szMsg);
		// Separate the recipient from the message (look for a space)
		size_t i = 0;
		size_t bufferLength = strlen(buffer);
		for (; i < bufferLength; i++)
		{
			if (buffer[i] == ' ')
			{
				buffer[i] = '\0';
				break;
			}
		}
		pChannel->SendPrivateMessage(pMe, buffer, buffer+i+1);
		break;
	};
	case 'f':	// f = (+ignore) ignore this person
	{
		pMe->Ignore(szMsg);
		break;
	};
	case 'g':	// g = (-ignore) don't ignore this person
	{
		pMe->DontIgnore(szMsg);
		break;
	};
	case 'h':	// h = toggle ignoring this person
	{
		pMe->ToggleIgnore(szMsg);
		break;
	};
	case 'i':	// i = grant speaking privs to this person
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->GrantVoice(pMe, szMsg);
		break;
	};
	case 'j':	// j = remove speaking privs from this person
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->RevokeVoice(pMe, szMsg);
		break;
	};
	case 'k':	// k = (/voice) toggle voice status
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->ToggleVoice(pMe, szMsg);
		break;
	};
	case 'l':	// l = grant moderator status to this person
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->GrantModerator(pMe, szMsg);
		break;
	};
	case 'm':	// m = remove moderator status from this person
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->RevokeModerator(pMe, szMsg);
		break;
	};
	case 'n':	// m = toggle the moderator status for this person
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->ToggleModerator(pMe, szMsg);
		break;
	}
	case 'o':	// o = turn on receiving private messages
	{
		pMe->SetReceiving(true);
		break;
	}
	case 'p':	// p = turn off receiving private messages
	{
		pMe->SetReceiving(false);
		break;
	}
	case 'q':	// q = toggle receiving messages
	{
		pMe->ToggleReceiving();
		break;
	};
	case 'r':	// r = (+showname) turn on showing character name
	{
		pMe->PermitWhoIs();
		break;
	};
	case 's':	// s = (-showname) turn off showing character name
	{
		pMe->ForbidWhoIs();
		break;
	};
	case 't':	// t = toggle showing character name
	{
		pMe->ToggleWhoIs();
		break;
	};
	case 'u':	// u = who is this player
	{
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->WhoIs(pMe->GetChatName(), szMsg);
		break;
	};
	case 'v':	// v = kick this person out of the conference
	{
		if (!pChannel)
			goto not_in_a_channel;

		CChatChanMember * pMember = pChannel->FindMember(szMsg);
		if (!pMember)
		{
			pMe->SendChatMsg(CHATMSG_NoPlayer, szMsg);
			break;
		}

		pChannel->KickMember(pMe, pMember);
		// If noone is left, tell the chat system to
		// delete it from memory (you can kick yourself)
		if (pChannel->m_Members.size() <= 0) // Kicked self
		{
			DeleteChannel(pChannel);
		}
		break;
	};
	case 'X':	// X = client quit chat
		QuitChat(pClient);
		break;
	case 'w':	// w = (+defaultvoice) make moderators be the only ones with a voice by default
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->DisableVoiceDefault(pMe->GetChatName());
		break;
	case 'x':	// x = (-defaultvoice) give everyone a voice by default
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->EnableVoiceDefault(pMe->GetChatName());
		break;
	case 'y':	// y = (/defaultvoice) toggle
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->ToggleVoiceDefault(pMe->GetChatName());
		break;
	case 'z':	// z = emote
		if (!pChannel)
			goto not_in_a_channel;
		pChannel->Emote(pMe->GetChatName(), szMsg, lang );
		break;
	};
}
Example #28
0
bool CChar::Use_Seed( CItem * pSeed, CPointMap * pPoint )
{
	ADDTOCALLSTACK("CChar::Use_Seed");
	// Use the seed at the current point on the ground or some new point that i can touch.
	// IT_SEED from IT_FRUIT

	ASSERT(pSeed);
	CPointMap pt;
	if ( pPoint )
		pt = *pPoint;
	else if ( pSeed->IsTopLevel() )
		pt = pSeed->GetTopPoint();
	else
		pt = GetTopPoint();

	if ( !CanTouch(pt) )
	{
		SysMessageDefault(DEFMSG_MSG_SEED_REACH);
		return false;
	}

	// is there soil here ? IT_DIRT
	if ( !IsPriv(PRIV_GM) && !g_World.IsItemTypeNear(pt, IT_DIRT, 0, false, true) )
	{
		SysMessageDefault(DEFMSG_MSG_SEED_TARGSOIL);
		return(false);
	}

	const CItemBase *pItemDef = pSeed->Item_GetDef();
	ITEMID_TYPE idReset = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttFruit.m_idReset));
	if ( idReset == 0 )
	{
		SysMessageDefault(DEFMSG_MSG_SEED_NOGOOD);
		return false;
	}

	// Already a plant here ?
	CWorldSearch AreaItems(pt);
	for (;;)
	{
		CItem *pItem = AreaItems.GetItem();
		if ( !pItem )
			break;
		if ( pItem->IsType(IT_TREE) || pItem->IsType(IT_FOLIAGE) )		// there's already a tree here
		{
			SysMessageDefault(DEFMSG_MSG_SEED_ATREE);
			return false;
		}
		if ( pItem->IsType(IT_CROPS) )		// there's already a plant here
			pItem->Delete();
	}

	// plant it and consume the seed.

	CItem *pPlant = CItem::CreateScript(idReset, this);
	ASSERT(pPlant);

	pPlant->MoveToUpdate(pt);
	if ( pPlant->IsType(IT_CROPS) || pPlant->IsType(IT_FOLIAGE) )
	{
		pPlant->m_itCrop.m_ReapFruitID = pSeed->GetID();
		pPlant->Plant_CropReset();
	}
	else
	{
		pPlant->SetDecayTime(10 * g_Cfg.m_iDecay_Item);
	}

	pSeed->ConsumeAmount();
	return true;
}
Example #29
0
DWORD CItemVendable::GetBasePrice() const
{
	ADDTOCALLSTACK("CItemVendable::GetBasePrice");
	// Get the price that the player set on his vendor
	return m_price;
}
bool CItemStone::r_WriteVal( LPCTSTR pszKey, CGString & sVal, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CItemStone::r_WriteVal");
	EXC_TRY("WriteVal");
	CChar * pCharSrc = pSrc->GetChar();

	if ( !strnicmp("member.",pszKey,7) )
	{
		LPCTSTR pszCmd = pszKey + 7;

		if ( !strnicmp("COUNT",pszCmd,5) )
		{
			pszCmd = pszCmd + 5;

			int i = 0;
			CStoneMember * pMember = STATIC_CAST <CStoneMember *>(GetHead());

			if ( *pszCmd )
			{
				SKIP_ARGSEP(pszCmd);
				STONEPRIV_TYPE iPriv = static_cast<STONEPRIV_TYPE>(Exp_GetVal(pszCmd));

				for (; pMember != NULL; pMember = pMember->GetNext())
				{
					if ( !pMember->GetLinkUID().IsChar() )
						continue;

					if ( pMember->GetPriv() != iPriv )
						continue;

					i++;
				}
			}
			else
			{
				for (; pMember != NULL; pMember = pMember->GetNext())
				{
					if (!pMember->GetLinkUID().IsChar()) 
						continue;

					i++;
				}
			}

			sVal.FormatVal(i);
			return true;
		}
		int nNumber = Exp_GetVal(pszCmd);
		SKIP_SEPARATORS(pszCmd);

		CStoneMember * pMember = STATIC_CAST <CStoneMember *>(GetHead());
		sVal.FormatVal(0);

		for ( int i = 0 ; pMember != NULL; pMember = pMember->GetNext() )
		{
			if (!pMember->GetLinkUID().IsChar()) 
				continue;
				
			if ( nNumber == i )
			{
				if (!pszCmd[0]) 
					return true;

				return pMember->r_WriteVal(pszCmd, sVal, pSrc);
			}

			i++;
		}

		return true;
	}
	else if ( !strnicmp("memberfromuid.", pszKey, 14) )
	{
		LPCTSTR pszCmd = pszKey + 14;
		sVal.FormatVal(0);

		if ( !pszCmd[0] )
			return true;

		CGrayUID pMemberUid = static_cast<DWORD>(Exp_GetVal(pszCmd));
		SKIP_SEPARATORS(pszCmd);

		CChar * pMemberChar = pMemberUid.CharFind();
		if ( pMemberChar )
		{
			CStoneMember * pMemberGuild = GetMember( pMemberChar );
			if ( pMemberGuild )
			{
				return pMemberGuild->r_WriteVal(pszCmd, sVal, pSrc);
			}
		}

		return true;
	}
	else if ( !strnicmp("guild.",pszKey,6) )
	{
		LPCTSTR pszCmd = pszKey + 6;

		if ( !strnicmp("COUNT",pszCmd,5) )
		{
			pszCmd = pszCmd + 5;

			int i = 0;
			CStoneMember * pMember = STATIC_CAST <CStoneMember *>(GetHead());

			if ( *pszCmd )
			{
				SKIP_ARGSEP(pszCmd);
				int iToCheck = Exp_GetVal(pszCmd);

				for (; pMember != NULL; pMember = pMember->GetNext())
				{
					if ( pMember->GetLinkUID().IsChar() )
						continue;

					if ( ( iToCheck == 1 ) && ( pMember->GetWeDeclared() && !pMember->GetTheyDeclared() ) )
						i++;
					else if ( ( iToCheck == 2 ) && ( !pMember->GetWeDeclared() && pMember->GetTheyDeclared() ) )
						i++;
					else if ( ( iToCheck == 3 ) && ( pMember->GetWeDeclared() && pMember->GetTheyDeclared() ) )
						i++;
				}
			}
			else
			{
				for (; pMember != NULL; pMember = pMember->GetNext())
				{
					if (pMember->GetLinkUID().IsChar()) 
						continue;

					i++;
				}
			}

			sVal.FormatVal(i);
			return true;
		}
		int nNumber = Exp_GetVal(pszCmd);
		SKIP_SEPARATORS(pszCmd);

		CStoneMember * pMember = STATIC_CAST <CStoneMember *>(GetHead());
		sVal.FormatVal(0);

		for ( int i = 0 ; pMember != NULL; pMember = pMember->GetNext() )
		{
			if (pMember->GetLinkUID().IsChar()) 
				continue;
				
			if ( nNumber == i )
			{
				if (!pszCmd[0]) 
					return true;

				return pMember->r_WriteVal(pszCmd, sVal, pSrc);
			}

			i++;
		}

		return true;
	}
	else if ( !strnicmp("guildfromuid.", pszKey, 13) )
	{
		LPCTSTR pszCmd = pszKey + 13;
		sVal.FormatVal(0);

		if ( !pszCmd[0] )
			return true;

		CGrayUID pGuildUid = static_cast<DWORD>(Exp_GetVal(pszCmd));
		SKIP_SEPARATORS(pszCmd);

		CItem * pMemberGuild = pGuildUid.ItemFind();
		if ( pMemberGuild )
		{
			CStoneMember * pGuild = GetMember( pMemberGuild );
			if ( pGuild )
			{
				return pGuild->r_WriteVal(pszCmd, sVal, pSrc);
			}
		}

		return true;
	}
	else if ( !strnicmp(sm_szLoadKeys[STC_CHARTER], pszKey, 7) )
	{
		LPCTSTR pszCmd = pszKey + 7;
		unsigned int i = ATOI(pszCmd);
		if ( i >= COUNTOF(m_sCharter))
			sVal = "";
		else
			sVal = m_sCharter[i];

		return( true );
	}


	STC_TYPE iIndex = (STC_TYPE) FindTableSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 );

	switch ( iIndex )
	{
		case STC_ABBREV: // "ABBREV"
			sVal = m_sAbbrev;
			return true;
		case STC_ALIGN:
			sVal.FormatVal( GetAlignType());
			return true;
		case STC_WEBPAGE: // "WEBPAGE"
			sVal = GetWebPageURL();
			return true;
		case STC_AbbreviationToggle:
			{
				CStoneMember * pMember = GetMember(pCharSrc);
				CVarDefCont * pResult = NULL;

				if ( pMember == NULL )
				{
					pResult = g_Exp.m_VarDefs.GetKey("STONECONFIG_VARIOUSNAME_NONMEMBER");
				}
				else
				{
					pResult = pMember->IsAbbrevOn() ? g_Exp.m_VarDefs.GetKey("STONECONFIG_VARIOUSNAME_ABBREVON") :
								g_Exp.m_VarDefs.GetKey("STONECONFIG_VARIOUSNAME_ABBREVOFF");
				}

				sVal = pResult ? pResult->GetValStr() : "";
			}
			return true;
		case STC_AlignType:
			sVal = GetAlignName();
			return true;

		case STC_LoyalTo:
			{
				CStoneMember * pMember = GetMember(pCharSrc);
				CVarDefCont * pResult = NULL;

				if ( pMember == NULL )
				{
					pResult = g_Exp.m_VarDefs.GetKey("STONECONFIG_VARIOUSNAME_NONMEMBER");
				}
				else
				{
					CChar * pLoyalTo = pMember->GetLoyalToUID().CharFind();
					if ((pLoyalTo == NULL) || (pLoyalTo == pCharSrc ))
					{
						pResult = g_Exp.m_VarDefs.GetKey("STONECONFIG_VARIOUSNAME_YOURSELF");
					}
					else
					{
						sVal = pLoyalTo->GetName();
						return true;
					}
				}

				sVal = pResult ? pResult->GetValStr() : "";
			}
			return( true );
	
		case STC_Master:
			{
				CChar * pMaster = GetMaster();
				sVal = (pMaster) ? pMaster->GetName() : g_Exp.m_VarDefs.GetKeyStr("STONECONFIG_VARIOUSNAME_PENDVOTE");
			}
			return( true );
	
		case STC_MasterGenderTitle:
			{
				CChar * pMaster = GetMaster();
				if ( pMaster == NULL )
					sVal = ""; // If no master (vote pending)
				else if ( pMaster->Char_GetDef()->IsFemale())
					sVal = g_Exp.m_VarDefs.GetKeyStr("STONECONFIG_VARIOUSNAME_MASTERGENDERFEMALE");
				else
					sVal = g_Exp.m_VarDefs.GetKeyStr("STONECONFIG_VARIOUSNAME_MASTERGENDERMALE");
			}
			return( true );
	
		case STC_MasterTitle:
			{
				CStoneMember * pMember = GetMasterMember();
				sVal = (pMember) ? pMember->GetTitle() : "";
			}
			return( true );
	
		case STC_MasterUid:
			{
				CChar * pMaster = GetMaster();
				if ( pMaster )
					sVal.FormatHex( (DWORD) pMaster->GetUID() );
				else
					sVal.FormatHex( (DWORD) 0 );
			}
			return( true );
			
		default:
			return( CItem::r_WriteVal( pszKey, sVal, pSrc ));
	}

	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_KEYRET(pSrc);
	EXC_DEBUG_END;
	return false;
}