inline INT64 CVarDefContStr::GetValNum() const { LPCTSTR pszStr = m_sVal; return( Exp_GetVal(pszStr) ); }
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; }
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; }
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; }
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; }
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; }