예제 #1
0
inline INT64 CVarDefContStr::GetValNum() const
{
	LPCTSTR pszStr = m_sVal;
	return( Exp_GetVal(pszStr) );
}
예제 #2
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 iQty = 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 = (iQty > 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));
				}
			}
			else
			{
				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 idx = 0; idx < 4; ++idx )
			{
				if ( !IsStrNumeric(ppArgs[idx]) )
				{
					DEBUG_ERR(("Invalid AddBuff argument number %u\n", idx + 1));
					return true;
				}
				iArgs[idx] = Exp_GetVal(ppArgs[idx]);
			}
			if ( (iArgs[0] < BI_START) || (iArgs[0] > BI_QTY) )
			{
				DEBUG_ERR(("Invalid AddBuff icon ID\n"));
				break;
			}

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

			addBuff(static_cast<BUFF_ICONS>(iArgs[0]), iArgs[1], iArgs[2], static_cast<WORD>(iArgs[3]), Args, ArgsCount);
			break;
		}
		case CV_REMOVEBUFF:
		{
			BUFF_ICONS IconId = static_cast<BUFF_ICONS>(s.GetArgVal());
			if ( (IconId < BI_START) || (IconId > BI_QTY) )
			{
				DEBUG_ERR(("Invalid RemoveBuff icon ID\n"));
				break;
			}
			removeBuff(IconId);
			break;
		}
		case CV_ADDCLILOC:		// add cliloc in @ClientTooltip trigger
		{
			TCHAR *ppLocArgs[256];
			size_t qty = Str_ParseCmds(s.GetArgRaw(), ppLocArgs, COUNTOF(ppLocArgs), ",");
			DWORD clilocid = Exp_GetVal(ppLocArgs[0]);

			CGString LocArgs;
			for ( size_t y = 1; y < qty; y++ )
			{
				if ( LocArgs.GetLength() )
					LocArgs += "\t";
				LocArgs += (!strcmp(ppLocArgs[y], "NULL") ? " " : ppLocArgs[y]);
			}

			if ( g_Cfg.m_wDebugFlags & DEBUGF_SCRIPTS )
				g_Log.EventDebug("SCRIPT: addcliloc(%lu,'%s')\n", clilocid, static_cast<LPCTSTR>(LocArgs));
			m_TooltipData.Add(new CClientTooltip(clilocid, LocArgs));
			break;
		}
		case CV_ADDCONTEXTENTRY:
		{
			TCHAR *ppLocArgs[20];
			if ( Str_ParseCmds(s.GetArgRaw(), ppLocArgs, COUNTOF(ppLocArgs), ",") > 4 )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: Function takes maximum of 4 arguments!\n"));
				return true;
			}
			if ( m_pPopupPacket == NULL )
			{
				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(ppLocArgs[i]) )
					continue;

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

			int entrytag = Exp_GetVal(ppLocArgs[0]);
			if ( entrytag < 100 )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: TextEntry < 100 is reserved for server usage!\n"));
				return true;
			}
			m_pPopupPacket->addOption(static_cast<WORD>(entrytag), static_cast<DWORD>(Exp_GetVal(ppLocArgs[1])), static_cast<WORD>(Exp_GetVal(ppLocArgs[2])), static_cast<WORD>(Exp_GetVal(ppLocArgs[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]));
#ifdef _ALPHASPHERE
			// todo: should use a proper container for these, since the arrows are lost
			// when the client logs out, and also newer clients support multiple arrows
			if ( piVal[0] && piVal[1] && m_pChar )
			{
				m_pChar->SetKeyNum("ARROWQUEST_X", piVal[0]);
				m_pChar->SetKeyNum("ARROWQUEST_Y", piVal[1]);
			}
			else {
				m_pChar->DeleteKey("ARROWQUEST_X");
				m_pChar->DeleteKey("ARROWQUEST_Y");
			}
#endif
			break;
		}
		case CV_BADSPAWN:
		{
			// Loop the world searching for bad spawns
			bool bFound = false;
			for ( int m = 0; (m < 256) && !bFound; m++ )
			{
				if ( !g_MapList.m_maps[m] )
					continue;

				for ( int d = 0; (d < g_MapList.GetSectorQty(m)) && !bFound; d++ )
				{
					CSector *pSector = g_World.GetSector(m, d);
					if ( !pSector )
						continue;

					CItem *pItem = static_cast<CItem *>(pSector->m_Items_Inert.GetHead());
					for ( ; (pItem != NULL) && !bFound; pItem = pItem->GetNext() )
					{
						if ( pItem->IsType(IT_SPAWN_ITEM) || pItem->IsType(IT_SPAWN_CHAR) )
						{
							CItemSpawn *pSpawn = static_cast<CItemSpawn *>(pItem);
							CResourceDef *pDef = pSpawn->FixDef();
							if ( !pDef )
							{
								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));
								bFound = true;
							}
						}
					}
				}
			}
			if ( !bFound )
				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 skill;
				if ( !pSpellDef->GetPrimarySkill(&skill, 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>(skill));
				break;
			}
			else
				Cmd_Skill_Magery(spell, pObjSrc);
			break;
		}
		case CV_CHARLIST:		// usually just a gm command
		{
			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:
		{
			CChar *pChar = m_pChar;
			if ( s.HasArgs() )
			{
				CGrayUID uid = static_cast<CGrayUID>(s.GetArgVal());
				pChar = uid.CharFind();
			}
			if ( pChar )
				closeUIWindow(pChar, 0x1);
			break;
		}
		case CV_CLOSEPROFILE:
		{
			CChar *pChar = m_pChar;
			if ( s.HasArgs() )
			{
				CGrayUID uid = static_cast<CGrayUID>(s.GetArgVal());
				pChar = uid.CharFind();
			}
			if ( pChar )
				closeUIWindow(pChar, 0x8);
			break;
		}
		case CV_CLOSESTATUS:
		{
			CChar *pChar = m_pChar;
			if ( s.HasArgs() )
			{
				CGrayUID uid = static_cast<CGrayUID>(s.GetArgVal());
				pChar = uid.CharFind();
			}
			if ( pChar )
				closeUIWindow(pChar, 0x2);
			break;
		}
		case CV_DYE:
		{
			if ( s.HasArgs() )
			{
				CGrayUID uid = static_cast<CGrayUID>(s.GetArgVal());
				CObjBase *pObj = uid.ObjFind();
				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
			if ( !s.HasArgs() )
			{
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_EXTRACT_USAGE));
			}
			else
			{
				TCHAR *ppArgs[2];
				Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

				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
			if ( !s.HasArgs() )
			{
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_UNEXTRACT_USAGE));
			}
			else
			{
				TCHAR *ppArgs[2];
				Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

				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_MENU:
		{
			Menu_Setup(g_Cfg.ResourceGetIDType(RES_MENU, s.GetArgStr()));
			break;
		}
		case CV_MIDILIST:
		{
			INT64 piMidi[64];
			size_t iQty = Str_ParseCmds(s.GetArgStr(), piMidi, COUNTOF(piMidi));
			if ( iQty > 0 )
				addMusic(static_cast<MIDI_TYPE>(piMidi[Calc_GetRandVal(iQty)]));
			break;
		}
		case CV_NUDGE:
		{
			if ( !s.HasArgs() )
			{
				SysMessage("Usage: NUDGE dx dy dz");
			}
			else
			{
				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:
		{
			CChar *pChar = m_pChar;
			if ( s.HasArgs() )
			{
				CGrayUID uid = static_cast<CGrayUID>(s.GetArgVal());
				pChar = uid.CharFind();
			}
			if ( pChar )
				addCharPaperdoll(pChar);
			break;
		}
		case CV_OPENTRADEWINDOW:
		{
			TCHAR *ppArgs[2];
			Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

			CChar *pChar = NULL;
			CItem *pItem = NULL;
			if ( ppArgs[0] )
			{
				CGrayUID uidChar = static_cast<CGrayUID>(Exp_GetVal(ppArgs[0]));
				pChar = uidChar.CharFind();
			}
			if ( ppArgs[1] )
			{
				CGrayUID uidItem = static_cast<CGrayUID>(Exp_GetVal(ppArgs[1]));
				pItem = uidItem.ItemFind();
			}
			if ( pChar )
				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 pPrompt = g_Cfg.GetDefaultMsg(DEFMSG_SELECT_MAGIC_TARGET);
				if ( !pSpellDef->m_sTargetPrompt.IsEmpty() )
					pPrompt = pSpellDef->m_sTargetPrompt;

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

				addTarget(CLIMODE_TARG_SKILL_MAGERY, pPrompt, pSpellDef->IsSpellType(SPELLFLAG_TARG_XYZ), pSpellDef->IsSpellType(SPELLFLAG_HARM), SpellTimeout);
				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 skill;
					if ( !pSpellDef->GetPrimarySkill(&skill, NULL) )
						return false;

					m_pChar->Skill_Start(static_cast<SKILL_TYPE>(skill));
				}
			}
			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 *pszArgs[4];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), pszArgs, COUNTOF(pszArgs));
			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;
			}
			//strip quotes if any
			if ( *pszArgs[0] == '"' )
				pszArgs[0]++;
			for ( TCHAR *pEnd = pszArgs[0] + strlen(pszArgs[0]) - 1; pEnd >= pszArgs[0]; pEnd-- )
			{
				if ( *pEnd == '"' )
				{
					*pEnd = '\0';
					break;
				}
			}
			SysMessagef(pszArgs[0], pszArgs[1], pszArgs[2] ? pszArgs[2] : 0, pszArgs[3] ? pszArgs[3] : 0);
			break;
		}
		case CV_SMSGU:
		case CV_SYSMESSAGEUA:
		{
			TCHAR *pszArgs[5];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), pszArgs, COUNTOF(pszArgs));
			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), pszArgs[4], -1);

				addBarkUNICODE(szBuffer, NULL, static_cast<HUE_TYPE>(Exp_GetVal(pszArgs[0])), TALKMODE_SYSTEM, FONT_NORMAL, pszArgs[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 = -1;
				if ( ppArgs[0] )
					hue = Exp_GetVal(ppArgs[0]);
				if ( hue == -1 )
					hue = HUE_TEXT_DEF;

				DWORD iClilocId = Exp_GetVal(ppArgs[1]);

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

				addBarkLocalized(iClilocId, NULL, hue, TALKMODE_SYSTEM, FONT_NORMAL, CArgs.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 = -1;
				int affix = 0;
				if ( ppArgs[0] )
					hue = Exp_GetVal(ppArgs[0]);
				if ( hue == -1 )
					hue = HUE_TEXT_DEF;

				DWORD iClilocId = Exp_GetVal(ppArgs[1]);

				if ( ppArgs[2] )
					affix = Exp_GetVal(ppArgs[2]);

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

				addBarkLocalizedEx(iClilocId, NULL, hue, TALKMODE_SYSTEM, FONT_NORMAL, static_cast<AFFIX_TYPE>(affix), ppArgs[3], CArgs.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");
			}
			else
			{
				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:	// "SHOW 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) )
				{
					//if ( !s.IsKeyHead("CTAG.", 5) && !s.IsKeyHead("CTAG0.", 6) )	// We don't want output related to CTAG
					//	SysMessagef("%s = %s", s.GetKey(), static_cast<LPCTSTR>(sVal));	// feedback on what we just did.
					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;
}
예제 #3
0
bool CRandGroupDef::r_WriteVal( LPCTSTR pszKey, CGString &sVal, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CRandGroupDef::r_WriteVal");
	EXC_TRY("WriteVal");

	switch ( FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
		case RGC_CATEGORY:
			sVal = m_sCategory;
			break;
		case RGC_SUBSECTION:
			sVal = m_sSubsection;
			break;
		case RGC_DESCRIPTION:
			sVal = m_sDescription;
			break;
		case RGC_ID:
		case RGC_CONTAINER:
		{
			size_t i = GetRandMemberIndex();
			if ( i != BadMemberIndex() )
				sVal.FormatHex(GetMemberID(i) & 0xFFFFFF);
			break;
		}
		case RGC_CALCMEMBERINDEX:
		{
			pszKey += 15;
			GETNONWHITESPACE( pszKey );

			if ( pszKey[0] == '\0' )
			{
				sVal.FormatVal( GetRandMemberIndex(NULL, false) );
			}
			else
			{
				CGrayUID uidTofind = static_cast<DWORD>(Exp_GetVal(pszKey));
				CChar * pSend = uidTofind.CharFind();

				if ( pSend )
				{
					sVal.FormatVal( GetRandMemberIndex(pSend, false) );
				}
				else
				{
					return false;
				}
			}

		} break;

		case RGC_DEFNAME: // "DEFNAME"
			sVal = GetResourceName();
			break;

		case RGC_RESOURCES:
		{
			pszKey	+= 9;
			if ( *pszKey == '.' )
			{
				SKIP_SEPARATORS( pszKey );

				if ( !strnicmp( pszKey, "COUNT", 5 ))
				{
					sVal.FormatVal(m_Members.GetCount());
				}
				else
				{
					bool fQtyOnly = false;
					bool fKeyOnly = false;
					int index = Exp_GetVal( pszKey );
					SKIP_SEPARATORS( pszKey );

					if ( !strnicmp( pszKey, "KEY", 3 ))
						fKeyOnly = true;
					else if ( !strnicmp( pszKey, "VAL", 3 ))
						fQtyOnly = true;

					TCHAR *pszTmp = Str_GetTemp();
					m_Members.WriteKeys( pszTmp, index, fQtyOnly, fKeyOnly );
					if ( fQtyOnly && pszTmp[0] == '\0' )
						strcpy( pszTmp, "0" );

					sVal = pszTmp;
				}
			}
			else
			{
				TCHAR *pszTmp = Str_GetTemp();
				m_Members.WriteKeys( pszTmp );
				sVal = pszTmp;
			}
		} break;

		default:
			return( CResourceDef::r_WriteVal( pszKey, sVal, pSrc ));
	}

	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_KEYRET(pSrc);
	EXC_DEBUG_END;
	return false;
}
예제 #4
0
bool CRandGroupDef::r_LoadVal( CScript &s )
{
	ADDTOCALLSTACK("CRandGroupDef::r_LoadVal");
	EXC_TRY("LoadVal");
	// RES_SPAWN or RES_REGIONTYPE
	switch ( FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
		case RGC_CATEGORY:
			m_sCategory = s.GetArgStr();
			break;
		case RGC_SUBSECTION:
			m_sSubsection = s.GetArgStr();
			break;
		case RGC_DESCRIPTION:
			{
				m_sDescription = s.GetArgStr();
				if ( !strcmpi(m_sDescription, "@") )
					m_sDescription = m_sSubsection;
			}
			break;
		case RGC_DEFNAME: // "DEFNAME"
			return SetResourceName( s.GetArgStr());
		case RGC_ID:	// "ID"
		case RGC_CONTAINER:
			{
				TCHAR	*ppCmd[2];
				size_t iArgs = Str_ParseCmds(s.GetArgStr(), ppCmd, COUNTOF(ppCmd));
				CResourceQty rec;

				rec.SetResourceID(
					g_Cfg.ResourceGetID(RES_CHARDEF, const_cast<LPCTSTR &>(reinterpret_cast<LPTSTR &>(ppCmd[0]))),
					( iArgs > 1 && ppCmd[1][0] ) ? Exp_GetVal(ppCmd[1]) : 1 );
				m_iTotalWeight += static_cast<int>(rec.GetResQty());
				m_Members.Add(rec);
			}
			break;

		case RGC_RESOURCES:
			m_Members.Load(s.GetArgStr());
			CalcTotalWeight();
			break;

		case RGC_WEIGHT: // Modify the weight of the last item.
			if ( m_Members.GetCount() > 0 )
			{
				int iWeight = s.GetArgVal();
				m_Members[m_Members.GetCount() - 1].SetResQty(iWeight);
				CalcTotalWeight();
			}
			break;

		//default:
			//Ignore the rest
			//return( CResourceDef::r_LoadVal( s ));
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
예제 #5
0
bool CSpellDef::r_WriteVal( LPCTSTR pszKey, CGString & sVal, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CSpellDef::r_WriteVal");
	EXC_TRY("WriteVal");
	int index = FindTableSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 );
	if (index < 0)
	{
		if (!strnicmp( "RESOURCES.", pszKey, 10 ))
			index = SPC_RESOURCES;
	}
	switch (index)
	{
		case SPC_CAST_TIME:
			sVal = m_CastTime.Write();
			break;
		case SPC_DEFNAME:
			sVal = GetResourceName();
			break;
		case SPC_DURATION:
			sVal = m_Duration.Write();
			break;
		case SPC_EFFECT:
			sVal = m_Effect.Write();
			break;
		case SPC_EFFECT_ID:
			sVal.FormatVal( m_idEffect );
			break;
		case SPC_FLAGS:
			sVal.FormatVal( m_dwFlags );
			break;
		case SPC_GROUP:
			sVal.FormatVal( m_dwGroup );
			break;
		case SPC_INTERRUPT:
			sVal = m_Interrupt.Write();
			break;
		case SPC_LAYER:
			sVal.FormatVal(m_idLayer);
			break;
		case SPC_MANAUSE:
			sVal.FormatVal( m_wManaUse );
			break;
		case SPC_NAME:
			sVal = m_sName;
			break;
		case SPC_PROMPT_MSG:
			sVal	= m_sTargetPrompt;
			break;
		case SPC_RESOURCES:
			{
				pszKey	+= 9;
				// Check for "RESOURCES.*"
				if ( *pszKey == '.' )
				{
					bool fQtyOnly = false;
					bool fKeyOnly = false;
					SKIP_SEPARATORS( pszKey );
					// Determine the index of the resource
					// we wish to find
					index = Exp_GetVal( pszKey );
					SKIP_SEPARATORS( pszKey );

					// Check for "RESOURCES.x.KEY"
					if ( !strnicmp( pszKey, "KEY", 3 ))
						fKeyOnly = true;
					// Check for "RESORUCES.x.VAL"
					else if ( !strnicmp( pszKey, "VAL", 3 ))
						fQtyOnly = true;

					TCHAR *pszTmp = Str_GetTemp();
					m_Reags.WriteKeys( pszTmp, index, fQtyOnly, fKeyOnly );
					if ( fQtyOnly && pszTmp[0] == '\0' )
						strcpy( pszTmp, "0" ); // Return 0 for empty quantity
					sVal = pszTmp;
				}
				else
				{
					TCHAR *pszTmp = Str_GetTemp();
					m_Reags.WriteKeys( pszTmp );
					sVal = pszTmp;
				}
				break;
			}
		case SPC_RUNE_ITEM:
			sVal.FormatVal( m_idSpell );
			break;
		case SPC_RUNES:
			// This may only be basic chars !
			sVal = m_sRunes;
			break;
		case SPC_SCROLL_ITEM:
			sVal.FormatVal( m_idScroll );
			break;
		case SPC_SKILLREQ:
			{
				TCHAR *pszTmp = Str_GetTemp();
				m_SkillReq.WriteKeys( pszTmp );
				sVal = pszTmp;
			}
			break;
		case SPC_SOUND:
			sVal.FormatVal(m_sound);
			break;
		case SPC_TITHINGUSE:
			sVal.FormatVal(m_wTithingUse);
			break;
		default:
			return( CResourceDef::r_WriteVal( pszKey, sVal, pSrc ));
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_KEYRET(pSrc);
	EXC_DEBUG_END;
	return false;
}
예제 #6
0
파일: CBase.cpp 프로젝트: zolter/Source
bool CBaseBaseDef::r_WriteVal( LPCTSTR pszKey, CGString & sVal, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CBaseBaseDef::r_WriteVal");
	EXC_TRY("WriteVal");
	bool	fZero	= false;
	int index = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 );

	switch ( index )
	{
		//return as string or hex number or NULL if not set
		case OBC_CATEGORY:
		case OBC_DESCRIPTION:
		case OBC_SUBSECTION:
		case OBC_HITSPELL:
		case OBC_SLAYER:
		case OBC_SLAYERLESSER:
		case OBC_SLAYERMISC:
		case OBC_SLAYERSUPER:
		case OBC_ABILITYPRIMARY:
		case OBC_ABILITYSECONDARY:
		case OBC_MANABURST:
			sVal = GetDefStr(pszKey, false);
			break;
		//return as decimal number or 0 if not set
		case OBC_BALANCED:
		case OBC_BANE:
		case OBC_BATTLELUST:
		case OBC_BLOODDRINKER:
		case OBC_CASTINGFOCUS:
		case OBC_DAMCHAOS:
		case OBC_DAMCOLD:
		case OBC_DAMDIRECT:
		case OBC_DAMENERGY:
		case OBC_DAMFIRE:
		case OBC_DAMMODIFIER:
		case OBC_DAMPHYSICAL:
		case OBC_DECREASEHITCHANCE:
		case OBC_DAMPOISON:
		case OBC_EATERCOLD:
		case OBC_EATERDAM:
		case OBC_EATERENERGY:
		case OBC_EATERFIRE:
		case OBC_EATERKINETIC:
		case OBC_EATERPOISON:
		case OBC_ENHANCEPOTIONS:
		case OBC_EXPANSION:
		case OBC_FASTERCASTING:
		case OBC_FASTERCASTRECOVERY:
		case OBC_HITAREACOLD:
		case OBC_HITAREAENERGY:
		case OBC_HITAREAFIRE:
		case OBC_HITAREAPHYSICAL:
		case OBC_HITAREAPOISON:
		case OBC_HITCURSE:
		case OBC_HITDISPEL:
		case OBC_HITFATIGUE:
		case OBC_HITFIREBALL:
		case OBC_HITHARM:
		case OBC_HITLEECHLIFE:
		case OBC_HITLEECHMANA:
		case OBC_HITLEECHSTAM:
		case OBC_HITLIGHTNING:
		case OBC_HITLOWERATK:
		case OBC_HITLOWERDEF:
		case OBC_HITMAGICARROW:
		case OBC_HITMANADRAIN:
		case OBC_INCREASEDAM:
		case OBC_INCREASEDEFCHANCE:
		case OBC_INCREASEDEFCHANCEMAX:
		case OBC_INCREASEHITCHANCE:
		case OBC_INCREASEGOLD:
		case OBC_INCREASEKARMALOSS:
		case OBC_INCREASESPELLDAM:
		case OBC_INCREASESWINGSPEED:
		case OBC_LOWERAMMOCOST:
		case OBC_LOWERMANACOST:
		case OBC_LOWERREAGENTCOST:
		case OBC_LOWERREQ:
		case OBC_LUCK:
		case OBC_MANABURSTFREQUENCY:
		case OBC_MANABURSTKARMA:
		case OBC_NIGHTSIGHT:
		case OBC_RAGEFOCUS:
		case OBC_REACTIVEPARALYZE:
		case OBC_REFLECTPHYSICALDAM:
		case OBC_REGENFOOD:
		case OBC_REGENHITS:
		case OBC_REGENMANA:
		case OBC_REGENSTAM:
		case OBC_REGENVALFOOD:
		case OBC_REGENVALHITS:
		case OBC_REGENVALMANA:
		case OBC_REGENVALSTAM:
		case OBC_RESCOLD:
		case OBC_RESFIRE:
		case OBC_RESENERGY:
		case OBC_RESPHYSICAL:
		case OBC_RESPOISON:
		case OBC_RESCOLDMAX:
		case OBC_RESFIREMAX:
		case OBC_RESENERGYMAX:
		case OBC_RESPHYSICALMAX:
		case OBC_RESPOISONMAX:
		case OBC_RESONANCECOLD:
		case OBC_RESONANCEENERGY:
		case OBC_RESONANCEFIRE:
		case OBC_RESONANCEKINETIC:
		case OBC_RESONANCEPOISON:
		case OBC_SOULCHARGE:
		case OBC_SOULCHARGECOLD:
		case OBC_SOULCHARGEENERGY:
		case OBC_SOULCHARGEFIRE:
		case OBC_SOULCHARGEKINETIC:
		case OBC_SOULCHARGEPOISON:
		case OBC_SPELLCONSUMPTION:
		case OBC_SPELLFOCUSING:
		case OBC_SPLINTERINGWEAPON:
		case OBC_VELOCITY:
		case OBC_SPELLCHANNELING:
		case OBC_NAMELOC:
		case OBC_HITSPELLSTR:
		case OBC_WEIGHTREDUCTION:
		case OBC_COMBATBONUSSTAT:
		case OBC_COMBATBONUSPERCENT:
			sVal.FormatLLVal(GetDefNum(pszKey, true));
			break;

		case OBC_DEFNAME:
			sVal = GetResourceName();
			break;

		case OBC_ARMOR:
			{
				pszKey += strlen(sm_szLoadKeys[index]); // 9;
				if ( *pszKey == '.' )
				{
					SKIP_SEPARATORS( pszKey );

					if ( !strnicmp( pszKey, "LO", 2 ) )
					{
						sVal.Format( "%d", m_defenseBase );
					}
					else if ( !strnicmp( pszKey, "HI", 2 ) )
					{
						sVal.Format( "%d", m_defenseBase+m_defenseRange );
					}
				}
				else
				{
					sVal.Format( "%d,%d", m_defenseBase, m_defenseBase+m_defenseRange );
				}
			} break;
		case OBC_DAM:
			{
				pszKey += strlen(sm_szLoadKeys[index]); // 9;
				if ( *pszKey == '.' )
				{
					SKIP_SEPARATORS( pszKey );

					if ( !strnicmp( pszKey, "LO", 2 ) )
					{
						sVal.Format( "%d", m_attackBase );
					}
					else if ( !strnicmp( pszKey, "HI", 2 ) )
					{
						sVal.Format( "%d", m_attackBase+m_attackRange );
					}
				}
				else
				{
					sVal.Format( "%d,%d", m_attackBase, m_attackBase+m_attackRange );
				}
			} break;
		case OBC_BASEID:
			sVal = g_Cfg.ResourceGetName( GetResourceID());
			break;
		case OBC_CAN:
			sVal.FormatHex( m_Can );
			break;
		case OBC_HEIGHT:
			{
				//CBaseBaseDef * pBaseBaseDef = dynamic_cast<CBaseBaseDef*>(this);
				//DEBUG_ERR(("OBC_HEIGHT  -  m_dwDispIndex %d  GetHeight() %d  pBaseBaseDef->GetHeight() %d  pBaseBaseDef 0x%x\n",m_wDispIndex,GetHeight(),pBaseBaseDef->GetHeight(),pBaseBaseDef));
				sVal.FormatVal( GetHeight() );
			}
			break;
		case OBC_INSTANCES:
			sVal.FormatVal( GetRefInstances());
			break;
		case OBC_NAME:
			sVal = GetName();
			break;

		case OBC_RANGE:
			if ( RangeH() == 0 ) sVal.Format( "%d", RangeL() );
			else sVal.Format( "%d,%d", RangeH(), RangeL() );
			break;
		case OBC_RANGEL: // internally: rangel seems to be Range Highest value
			sVal.FormatVal( RangeH() );
			break;
		case OBC_RANGEH: // but rangeh seems to be the Range Lowest value.
			sVal.FormatVal( RangeL() );
			break;

		case OBC_RESOURCES:		// Print the resources
			{
				pszKey += strlen(sm_szLoadKeys[index]); // 9;
				if ( *pszKey == '.' )
				{
					SKIP_SEPARATORS( pszKey );

					if ( !strnicmp( pszKey, "COUNT", 5 ))
					{
						sVal.FormatVal(m_BaseResources.GetCount());
					}
					else
					{
						bool fQtyOnly = false;
						bool fKeyOnly = false;
						index = Exp_GetVal( pszKey );
						SKIP_SEPARATORS( pszKey );

						if ( !strnicmp( pszKey, "KEY", 3 ))
							fKeyOnly	= true;
						else if ( !strnicmp( pszKey, "VAL", 3 ))
							fQtyOnly	= true;

						TCHAR *pszTmp = Str_GetTemp();
						m_BaseResources.WriteKeys( pszTmp, index, fQtyOnly, fKeyOnly );
						if ( fQtyOnly && pszTmp[0] == '\0' )
							strcpy( pszTmp, "0" );

						sVal = pszTmp;
					}
				}
				else
				{
					TCHAR *pszTmp = Str_GetTemp();
					m_BaseResources.WriteKeys( pszTmp );
					sVal = pszTmp;
				}
			}
			break;
		case OBC_RESLEVEL:
			sVal.FormatVal( GetResLevel() );
			break;
		case OBC_RESDISPDNHUE:
			sVal.FormatHex( GetResDispDnHue() );
			break;
		case OBC_TAG0:
			fZero	= true;
			pszKey++;
		case OBC_TAG:			// "TAG" = get/set a local tag.
			if ( pszKey[3] != '.' )
				return( false );
			pszKey += 4;
			sVal = m_TagDefs.GetKeyStr(pszKey, fZero );
			break;
		case OBC_TEVENTS:
			m_TEvents.WriteResourceRefList( sVal );
			break;
		default:
			return false;
	}
	return true;
	EXC_CATCH;

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