void CItemSpawn::DelObj(CGrayUID uid) { ADDTOCALLSTACK("CitemSpawn:DelObj"); if ( !uid.IsValidUID() ) return; BYTE iMax = GetCount(); for ( BYTE i = 0; i < iMax; i++ ) { if ( m_obj[i] != uid ) continue; CObjBase *pObj = uid.ObjFind(); pObj->m_uidSpawnItem.InitUID(); m_currentSpawned--; if ( GetType() == IT_SPAWN_CHAR ) uid.CharFind()->StatFlag_Clear(STATF_Spawned); while ( m_obj[i + 1].IsValidUID() ) // searching for any entry higher than this one... { m_obj[i] = m_obj[i + 1]; // and moving it 1 position to keep values 'together'. i++; } m_obj[i].InitUID(); // Finished moving higher entries (if any) so we free the last entry. break; } ResendTooltip(); }
// Storing one UID in Spawn's m_obj[] void CItemSpawn::AddObj( CGrayUID uid ) { ADDTOCALLSTACK("CitemSpawn:AddObj"); unsigned char iMax = GetAmount() > 0 ? static_cast<unsigned char>(GetAmount()) : 1; iMax += 1; // We must give a +1 to create a 'free slot' bool bIsSpawnChar = GetType() == IT_SPAWN_CHAR; if (bIsSpawnChar ) { if (!uid || !uid.CharFind()->m_pNPC) // Only adding UIDs... return; } if ( uid.ObjFind()->m_uidSpawnItem.ItemFind() ) //... which doesn't have a SpawnItem already return; for ( unsigned char i = 0; i < iMax; i++ ) { if ( m_obj[i] == uid ) // Not adding me again return; if ( !m_obj[i].ObjFind() ) { m_obj[i] = uid; if (bIsSpawnChar) { m_itSpawnChar.m_current++; uid.CharFind()->StatFlag_Set(STATF_Spawned); } uid.ObjFind()->m_uidSpawnItem = GetUID(); break; } } }
void CItemSpawn::AddObj( CGrayUID uid ) { ADDTOCALLSTACK("CitemSpawn:AddObj"); unsigned char iMax = GetAmount() > 0 ? static_cast<unsigned char>(GetAmount()) : 1; bool bIsSpawnChar = GetType() == IT_SPAWN_CHAR; if (!uid) return; if ( bIsSpawnChar ) { if ( !uid.CharFind()->m_pNPC) // Only adding NPCs to IT_SPAWN_CHAR.. return; if ( uid.CharFind()->m_uidSpawnItem.ItemFind() ) //... if they doesn't have a SpawnItem already. return; } else if( !uid.ItemFind() ) // Only adding Items to IT_SPAWN_ITEM return; for ( unsigned char i = 0; i < iMax; i++ ) { if ( m_obj[i] == uid ) // Not adding me again return; if ( !m_obj[i].ObjFind() ) { m_obj[i] = uid; if (bIsSpawnChar) { m_itSpawnChar.m_current++; uid.CharFind()->StatFlag_Set(STATF_Spawned); } uid.ObjFind()->m_uidSpawnItem = GetUID(); break; } } }
bool CClient::addGumpDialogProps( CGrayUID uid ) { ADDTOCALLSTACK("CClient::addGumpDialogProps"); // put up a prop dialog for the object. CObjBase * pObj = uid.ObjFind(); if ( pObj == NULL ) return false; if ( m_pChar == NULL ) return( false ); if ( ! m_pChar->CanTouch( pObj )) // probably a security issue. return( false ); m_Prop_UID = m_Targ_UID = uid; if ( uid.IsChar() ) addSkillWindow(static_cast<SKILL_TYPE>(g_Cfg.m_iMaxSkill), true); TCHAR *pszMsg = Str_GetTemp(); strcpy(pszMsg, pObj->IsItem() ? "d_ITEMPROP1" : "d_CHARPROP1" ); RESOURCE_ID rid = g_Cfg.ResourceGetIDType(RES_DIALOG, pszMsg); if ( ! rid.IsValidUID()) return false; Dialog_Setup( CLIMODE_DIALOG, rid, 0, pObj ); return( true ); }
bool CPartyDef::RemoveMember( CGrayUID uidRemove, CGrayUID uidCommand ) { ADDTOCALLSTACK("CPartyDef::RemoveMember"); // ARGS: // uidRemove = Who is being removed. // uidCommand = who removed this person (only the master or self can remove) // // NOTE: remove of the master will cause the party to disband. if ( m_Chars.GetCharCount() <= 0 ) return false; CGrayUID uidMaster = GetMaster(); if ( (uidRemove != uidCommand) && (uidCommand != uidMaster) ) return false; CChar *pCharRemove = uidRemove.CharFind(); if ( !pCharRemove ) return false; if ( !IsInParty(pCharRemove) ) return false; if ( uidRemove == uidMaster ) return Disband(uidMaster); CChar *pSrc = uidCommand.CharFind(); if ( pSrc && IsTrigUsed(TRIGGER_PARTYREMOVE) ) { CScriptTriggerArgs args; if ( pCharRemove->OnTrigger(CTRIG_PartyRemove, pSrc, &args) == TRIGRET_RET_TRUE ) return false; } if ( IsTrigUsed(TRIGGER_PARTYLEAVE) ) { if ( pCharRemove->OnTrigger(CTRIG_PartyLeave, pCharRemove, 0) == TRIGRET_RET_TRUE ) return false; } // Remove it from the party SendRemoveList(pCharRemove, true); DetachChar(pCharRemove); pCharRemove->SysMessageDefault(DEFMSG_PARTY_LEAVE_2); TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_PARTY_LEAVE_1), pCharRemove->GetName()); SysMessageAll(pszMsg); if ( m_Chars.GetCharCount() <= 1 ) { // Disband the party SysMessageAll(g_Cfg.GetDefaultMsg(DEFMSG_PARTY_LEAVE_LAST_PERSON)); return Disband(uidMaster); } return true; }
// --------------------------------------------------------- bool CPartyDef::DeclineEvent( CChar * pCharDecline, CGrayUID uidInviter ) // static { ADDTOCALLSTACK("CPartyDef::DeclineEvent"); // This should happen after a timeout as well. // " You notify %s that you do not wish to join the party" CChar * pCharInviter = uidInviter.CharFind(); if ( !pCharInviter || !pCharDecline ) return( false ); if ( uidInviter == pCharDecline->GetUID() ) return( false ); CVarDefCont * sTempVal = pCharInviter->GetTagDefs()->GetKey("PARTY_LASTINVITE"); if ( !sTempVal ) return( false ); if ((DWORD)sTempVal->GetValNum() != (DWORD)pCharDecline->GetUID()) return( false ); // Remove the key pCharInviter->DeleteKey("PARTY_LASTINVITE"); TCHAR * sTemp = Str_GetTemp(); sprintf(sTemp, g_Cfg.GetDefaultMsg(DEFMSG_PARTY_DECLINE_2), static_cast<LPCTSTR>(pCharInviter->GetName())); pCharDecline->SysMessage( sTemp ); sTemp = Str_GetTemp(); sprintf(sTemp, g_Cfg.GetDefaultMsg(DEFMSG_PARTY_DECLINE_1), static_cast<LPCTSTR>(pCharDecline->GetName())); pCharInviter->SysMessage( sTemp ); return( true ); }
// --------------------------------------------------------- bool CPartyDef::MessageEvent( CGrayUID uidDst, CGrayUID uidSrc, const NCHAR * pText, int ilenmsg ) { ADDTOCALLSTACK("CPartyDef::MessageEvent"); UNREFERENCED_PARAMETER(ilenmsg); if ( pText == NULL ) return( false ); if ( uidDst && !IsInParty( uidDst.CharFind() ) ) return( false ); CChar * pFrom = uidSrc.CharFind(); CChar * pTo = NULL; if ( uidDst != (DWORD) 0 ) pTo = uidDst.CharFind(); TCHAR * szText = Str_GetTemp(); CvtNUNICODEToSystem( szText, MAX_TALK_BUFFER, pText, MAX_TALK_BUFFER ); if ( ! m_pSpeechFunction.IsEmpty() ) { TRIGRET_TYPE tr = TRIGRET_RET_FALSE; CScriptTriggerArgs Args; Args.m_iN1 = uidSrc; Args.m_iN2 = uidDst; Args.m_s1 = szText; Args.m_s1_raw = szText; if ( r_Call(m_pSpeechFunction, &g_Serv, &Args, NULL, &tr) ) { if ( tr == TRIGRET_RET_TRUE ) return( false ); } } if ( g_Log.IsLoggedMask( LOGM_PLAYER_SPEAK )) g_Log.Event( LOGM_PLAYER_SPEAK, "%lx:'%s' Says '%s' in party to '%s'\n", pFrom->GetClient()->GetSocketID(), pFrom->GetName(), szText, pTo ? pTo->GetName() : "all" ); sprintf(szText, g_Cfg.GetDefaultMsg( DEFMSG_PARTY_MSG ), pText); PacketPartyChat cmd(pFrom, pText); if ( pTo != NULL ) SendMemberMsg(pTo, &cmd); else SendAll(&cmd); return( true ); }
bool CItemSpawn::r_LoadVal(CScript & s) { ADDTOCALLSTACK("CitemSpawn:r_LoadVal"); EXC_TRY("LoadVal"); if (g_Serv.IsLoading()) { if (!strnicmp(s.GetKey(), "more2", 5)) //More2 shouldn't be loaded as it's being set with ADDOBJ return true; } int iCmd = FindTableSorted(s.GetKey(), sm_szLoadKeys, COUNTOF(sm_szLoadKeys) - 1); if (iCmd < 0) return CItem::r_LoadVal(s); switch (iCmd) { case ISPW_ADDOBJ: { CGrayUID uid = static_cast<CGrayUID>(s.GetArgVal()); if ( uid.ObjFind() ) AddObj(uid); return true; } case ISPW_DELOBJ: { CGrayUID uid = static_cast<CGrayUID>(s.GetArgVal()); if (uid.ObjFind()) DelObj(uid); return true; } case ISPW_RESET: KillChildren(); return true; case ISPW_START: SetTimeout(0); return true; case ISPW_STOP: KillChildren(); SetTimeout(-1); return true; default: break; } EXC_CATCH; return false; }
unsigned char CItemSpawn::GetCount() { ADDTOCALLSTACK("CitemSpawn:GetCount"); if ( GetType() == IT_SPAWN_CHAR ) return static_cast<unsigned char>(m_itSpawnChar.m_current); else if ( GetType() == IT_SPAWN_ITEM ) { unsigned char iCount = 0; unsigned char i = 0; while ( m_obj[i].ItemFind() ) { CGrayUID spawn = m_obj[i].ItemFind()->m_uidSpawnItem; if (spawn.IsValidUID() && spawn == GetUID()) iCount++; i++; } return iCount; } return 0; }
void CItemSpawn::DelObj( CGrayUID uid ) { ADDTOCALLSTACK("CitemSpawn:DelObj"); if ( !uid.IsValidUID() ) return; for ( unsigned char i = 0; i < GetCount(); i++ ) { if ( m_obj[i].IsValidUID() && m_obj[i] == uid ) // found this uid, proceeding to clear it { if (GetType() == IT_SPAWN_CHAR) // IT_SPAWN_ITEM uses 'more2' to store how much items to spawn at once, so we must not touch it. m_itSpawnChar.m_current--; // found this UID in the spawn's list, decreasing CChar's count only in this case while ( m_obj[i + 1].IsValidUID() ) // searching for any entry higher than this one... { m_obj[i] = m_obj[i + 1]; // and moving it 1 position to keep values 'together'. i++; } m_obj[i].InitUID(); // Finished moving higher entries (if any) so we free the last entry. break; } } if (uid.ItemFind()) uid.ItemFind()->m_uidSpawnItem.InitUID(); else if (uid.CharFind()) { uid.CharFind()->m_uidSpawnItem.InitUID(); uid.CharFind()->StatFlag_Clear(STATF_Spawned); } }
void CItemSpawn::AddObj(CGrayUID uid) { ADDTOCALLSTACK("CitemSpawn:AddObj"); // NOTE: This function is also called when loading spawn items // on server startup. In this case, some objs UID still invalid // (not loaded yet) so just proceed without any checks. bool bIsSpawnChar = IsType(IT_SPAWN_CHAR); if ( !g_Serv.IsLoading() ) { if ( !uid.IsValidUID() ) return; if ( bIsSpawnChar ) // IT_SPAWN_CHAR can only spawn NPCs { CChar *pChar = uid.CharFind(); if ( !pChar || !pChar->m_pNPC ) return; } else if ( !uid.ItemFind() ) // IT_SPAWN_ITEM can only spawn items return; CItemSpawn *pPrevSpawn = static_cast<CItemSpawn*>(uid.ObjFind()->m_uidSpawnItem.ItemFind()); if ( pPrevSpawn ) { if ( pPrevSpawn == this ) // obj already linked to this spawn return; pPrevSpawn->DelObj(uid); // obj linked to other spawn, remove the link before proceed } } BYTE iMax = maximum(GetAmount(), 1); for (BYTE i = 0; i < iMax; i++ ) { if ( !m_obj[i].IsValidUID() ) { m_obj[i] = uid; m_currentSpawned++; // objects are linked to the spawn at each server start if ( !g_Serv.IsLoading() ) { uid.ObjFind()->m_uidSpawnItem = GetUID(); if ( bIsSpawnChar ) { CChar *pChar = uid.CharFind(); ASSERT(pChar->m_pNPC); pChar->StatFlag_Set(STATF_Spawned); pChar->m_ptHome = GetTopPoint(); pChar->m_pNPC->m_Home_Dist_Wander = static_cast<WORD>(m_itSpawnChar.m_DistMax); } } break; } } if ( !g_Serv.IsLoading() ) ResendTooltip(); }
bool CScriptObj::r_GetRef( LPCTSTR & pszKey, CScriptObj * & pRef ) { // A key name that just links to another object. if ( !strnicmp(pszKey, "SERV.", 5) && strnicmp(pszKey, "SERV.NEW", 8) ) { pszKey += 5; pRef = &g_Serv; return true; } else if ( !strnicmp(pszKey, "UID.", 4) ) { pszKey += 4; CGrayUID uid = (DWORD)Exp_GetVal(pszKey); SKIP_SEPERATORS(pszKey); pRef = uid.ObjFind(); return true; } else if ( ! strnicmp( pszKey, "OBJ.", 4 )) { pszKey += 4; pRef = ( (DWORD)g_World.m_uidObj ) ? g_World.m_uidObj.ObjFind() : NULL; return true; } else if ( !strnicmp(pszKey, "NEW.", 4) ) { pszKey += 4; pRef = ( (DWORD)g_World.m_uidNew ) ? g_World.m_uidNew.ObjFind() : NULL; return true; } else if ( !strnicmp(pszKey, "I.", 2) ) { pszKey += 2; pRef = this; return true; } return false; }
void CItemStone::WeDeclarePeace(CGrayUID uid, bool fForcePeace) { ADDTOCALLSTACK("CItemStone::WeDeclarePeace"); CItemStone * pEnemyStone = dynamic_cast <CItemStone*>( uid.ItemFind()); if (!pEnemyStone) return; CStoneMember * pMember = GetMember(pEnemyStone); if ( ! pMember ) // No such member return; // Set my flags on the subject. if (!pMember->GetTheyDeclared() || fForcePeace) // If they're not at war with us, delete this record delete pMember; else pMember->SetWeDeclared(false); pEnemyStone->TheyDeclarePeace( this, fForcePeace ); }
bool CPartyDef::Disband( CGrayUID uidMaster ) { ADDTOCALLSTACK("CPartyDef::Disband"); // Make sure i am the master. if ( m_Chars.GetCharCount() <= 0 ) return false; if ( GetMaster() != uidMaster ) return false; CChar *pMaster = GetMaster().CharFind(); if ( pMaster && IsTrigUsed(TRIGGER_PARTYDISBAND) ) { CScriptTriggerArgs args; if ( pMaster->OnTrigger(CTRIG_PartyDisband, pMaster, &args) == TRIGRET_RET_TRUE ) return false; } SysMessageAll(g_Cfg.GetDefaultMsg(DEFMSG_PARTY_DISBANDED)); CChar *pSrc = uidMaster.CharFind(); size_t iQty = m_Chars.GetCharCount(); ASSERT(iQty > 0); CChar *pChar = NULL; for ( size_t i = 0; i < iQty; i++ ) { pChar = m_Chars.GetChar(i).CharFind(); if ( !pChar ) continue; if ( IsTrigUsed(TRIGGER_PARTYREMOVE) ) { CScriptTriggerArgs args; args.m_iN1 = 1; pChar->OnTrigger(CTRIG_PartyRemove, pSrc, &args); } SendRemoveList(pChar, true); DetachChar(pChar); } delete this; // should remove itself from the world list. return true; }
CStoneMember::CStoneMember( CItemStone * pStone, CGrayUID uid, STONEPRIV_TYPE iType, LPCTSTR pTitle, CGrayUID loyaluid, bool fVal1, bool fVal2, int nAccountGold) { m_uidLinkTo = uid; m_sTitle = pTitle; m_iPriv = iType; m_uidLoyalTo = loyaluid; // union. if ( iType == STONEPRIV_ENEMY ) { m_Enemy.m_fTheyDeclared = fVal1; m_Enemy.m_fWeDeclared = fVal2; } else { m_Member.m_fAbbrev = fVal1; m_Member.m_iVoteTally = fVal2; // Temporary space to calculate votes. } m_Member.m_iAccountGold = nAccountGold; if ( ! g_Serv.IsLoading() && pStone->GetMemoryType()) { CChar * pChar = uid.CharFind(); if ( pChar != NULL ) { pChar->Memory_AddObjTypes(pStone, static_cast<WORD>(pStone->GetMemoryType())); if ( pStone->IsTopLevel()) { pChar->m_ptHome = pStone->GetTopPoint(); // Our new home. } } } pStone->InsertTail( this ); }
bool CItemStone::r_Verb( CScript & s, CTextConsole * pSrc ) // Execute command from script { ADDTOCALLSTACK("CItemStone::r_Verb"); EXC_TRY("Verb"); // NOTE:: ONLY CALL this from CChar::r_Verb !!! // Little to no security checking here !!! ASSERT(pSrc); int index = FindTableSorted( s.GetKey(), sm_szVerbKeys, COUNTOF(sm_szVerbKeys)-1 ); if ( index < 0 ) { return( CItem::r_Verb( s, pSrc )); } CChar * pCharSrc = pSrc->GetChar(); CStoneMember * pMember = GetMember(pCharSrc); switch ( index ) { case ISV_ALLGUILDS: { if ( s.HasArgs() ) { TCHAR * pszArgs = s.GetArgRaw(); int iFlags = Exp_GetVal(pszArgs); SKIP_ARGSEP(pszArgs); if ( iFlags < 0 ) { g_Log.EventError("ItemStone::AllGuilds invalid parameter '%i'.\n", iFlags); return false; } else { if ( pszArgs[0] != '\0' ) { pMember = STATIC_CAST <CStoneMember *>(GetHead()); CScript scriptVerb( pszArgs ); for (; pMember != NULL; pMember = pMember->GetNext()) { if ( pMember->GetLinkUID().IsChar() ) continue; if ( !iFlags ) { pMember->r_Verb(scriptVerb, pSrc); } else if ( ( iFlags == 1 ) && ( pMember->GetWeDeclared() && !pMember->GetTheyDeclared() ) ) { pMember->r_Verb(scriptVerb, pSrc); } else if ( ( iFlags == 2 ) && ( !pMember->GetWeDeclared() && pMember->GetTheyDeclared() ) ) { pMember->r_Verb(scriptVerb, pSrc); } else if ( ( iFlags == 3 ) && ( pMember->GetWeDeclared() && pMember->GetTheyDeclared() ) ) { pMember->r_Verb(scriptVerb, pSrc); } } } else { g_Log.EventError("ItemStone::AllGuilds empty args.\n"); return false; } } } } break; case ISV_ALLMEMBERS: { if ( s.HasArgs() ) { TCHAR * pszArgs = s.GetArgRaw(); int iFlags = Exp_GetVal(pszArgs); SKIP_ARGSEP(pszArgs); if (( iFlags < -1 ) || ( iFlags > STONEPRIV_ACCEPTED )) { g_Log.EventError("ItemStone::AllMembers invalid parameter '%i'.\n", iFlags); return false; } else { if ( pszArgs[0] != '\0' ) { pMember = STATIC_CAST <CStoneMember *>(GetHead()); CScript scriptVerb( pszArgs ); for (; pMember != NULL; pMember = pMember->GetNext()) { if ( !pMember->GetLinkUID().IsChar() ) continue; if ( iFlags == -1 ) { pMember->r_Verb(scriptVerb, pSrc); } else if ( pMember->GetPriv() == static_cast<STONEPRIV_TYPE>(iFlags) ) { pMember->r_Verb(scriptVerb, pSrc); } } } else { g_Log.EventError("ItemStone::AllMembers empty args.\n"); return false; } } } } break; case ISV_APPLYTOJOIN: if ( s.HasArgs()) { CGrayUID pMemberUid = s.GetArgVal(); CChar * pMemberChar = pMemberUid.CharFind(); if ( pMemberChar ) { AddRecruit( pMemberChar, STONEPRIV_CANDIDATE ); } } break; case ISV_CHANGEALIGN: if ( s.HasArgs()) { SetAlignType(static_cast<STONEALIGN_TYPE>(s.GetArgVal())); TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, "%s is now a %s %s\n", static_cast<LPCTSTR>(GetName()), static_cast<LPCTSTR>(GetAlignName()), static_cast<LPCTSTR>(GetTypeName())); Speak(pszMsg); } break; case ISV_DECLAREPEACE: if ( s.HasArgs()) { CGrayUID pMemberUid = s.GetArgVal(); WeDeclarePeace(pMemberUid); } break; case ISV_DECLAREWAR: if ( s.HasArgs()) { CGrayUID pMemberUid = s.GetArgVal(); CItem * pEnemyItem = pMemberUid.ItemFind(); if ( pEnemyItem ) { CItemStone * pNewEnemy = dynamic_cast<CItemStone*>(pEnemyItem); if ( pNewEnemy ) { WeDeclareWar(pNewEnemy); } } } break; case ISV_ELECTMASTER: ElectMaster(); break; // Need to change FixWeirdness or rewrite how cstonemember guilds are handled. case ISV_INVITEWAR: { if ( s.HasArgs() ) { INT64 piCmd[2]; size_t iArgQty = Str_ParseCmds( s.GetArgStr(), piCmd, COUNTOF(piCmd)); if ( iArgQty == 2 ) { CGrayUID pGuildUid = static_cast<unsigned long>(piCmd[0]); bool bWeDeclared = (piCmd[1] != 0); CItem * pEnemyItem = pGuildUid.ItemFind(); if ( pEnemyItem && (pEnemyItem->IsType(IT_STONE_GUILD) || pEnemyItem->IsType(IT_STONE_TOWN)) ) { CStoneMember * pMemberGuild = GetMember( pEnemyItem ); if ( !pMemberGuild ) pMemberGuild = new CStoneMember(this, pGuildUid, STONEPRIV_ENEMY); if ( bWeDeclared ) pMemberGuild->SetWeDeclared(true); else pMemberGuild->SetTheyDeclared(true); } } } } break; case ISV_JOINASMEMBER: if ( s.HasArgs()) { CGrayUID pMemberUid = s.GetArgVal(); CChar * pMemberChar = pMemberUid.CharFind(); if ( pMemberChar ) { AddRecruit( pMemberChar, STONEPRIV_MEMBER ); } } break; case ISV_RESIGN: if ( s.HasArgs()) { CGrayUID pMemberUid = s.GetArgVal(); CChar * pMemberChar = pMemberUid.CharFind(); if ( pMemberChar ) { CStoneMember * pMemberGuild = GetMember( pMemberChar ); if ( pMemberGuild ) { delete pMemberGuild; } } } else { if ( pMember != NULL ) delete pMember; } break; case ISV_TOGGLEABBREVIATION: { CGrayUID pMemberUid = pMember->GetLinkUID(); if ( s.HasArgs() ) pMemberUid = s.GetArgVal(); CChar * pMemberChar = pMemberUid.CharFind(); if ( pMemberChar ) { CStoneMember * pMemberGuild = GetMember( pMemberChar ); if ( pMemberGuild ) { pMemberGuild->ToggleAbbrev(); pMemberChar->ResendTooltip(); } } } break; default: return( false ); } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_SCRIPTSRC; EXC_DEBUG_END; return false; }
bool CItemStone::r_GetRef( LPCTSTR & pszKey, CScriptObj * & pRef ) { ADDTOCALLSTACK("CItemStone::r_GetRef"); if ( !strnicmp("member.", pszKey, 7) ) { pszKey = pszKey + 7; if ( !pszKey[0] ) return false; int nNumber = Exp_GetVal(pszKey); SKIP_SEPARATORS(pszKey); CStoneMember * pMember = STATIC_CAST <CStoneMember *>(GetHead()); for ( int i = 0; pMember != NULL; pMember = pMember->GetNext() ) { if ( !pMember->GetLinkUID().IsChar() ) continue; if ( nNumber == i ) { pRef = pMember; return true; } i++; } } else if ( !strnicmp("memberfromuid.", pszKey, 14) ) { pszKey = pszKey + 14; if ( !pszKey[0] ) return false; CGrayUID pMemberUid = static_cast<DWORD>(Exp_GetVal(pszKey)); SKIP_SEPARATORS(pszKey); CChar * pMemberChar = pMemberUid.CharFind(); if ( pMemberChar ) { CStoneMember * pMemberGuild = GetMember( pMemberChar ); if ( pMemberGuild ) { pRef = pMemberGuild; return true; } } } else if ( !strnicmp("guild.", pszKey, 6) ) { pszKey = pszKey + 6; if ( !pszKey[0] ) return false; int nNumber = Exp_GetVal(pszKey); SKIP_SEPARATORS(pszKey); CStoneMember * pMember = STATIC_CAST <CStoneMember *>(GetHead()); for ( int i = 0; pMember != NULL; pMember = pMember->GetNext() ) { if ( pMember->GetLinkUID().IsChar() ) continue; if ( nNumber == i ) { pRef = pMember; return true; } i++; } } else if ( !strnicmp("guildfromuid.", pszKey, 13) ) { pszKey = pszKey + 13; if ( !pszKey[0] ) return false; CGrayUID pGuildUid = static_cast<DWORD>(Exp_GetVal(pszKey)); SKIP_SEPARATORS(pszKey); CItem * pMemberGuild = pGuildUid.ItemFind(); if ( pMemberGuild ) { CStoneMember * pGuild = GetMember( pMemberGuild ); if ( pGuild ) { pRef = pGuild; return true; } } } return CItem::r_GetRef( pszKey, pRef ); }
bool CItemStone::r_LoadVal( CScript & s ) // Load an item Script { ADDTOCALLSTACK("CItemStone::r_LoadVal"); EXC_TRY("LoadVal"); switch ( FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 )) { case STC_ABBREV: // "ABBREV" m_sAbbrev = s.GetArgStr(); return true; case STC_ALIGN: // "ALIGN" SetAlignType(static_cast<STONEALIGN_TYPE>(s.GetArgVal())); return true; case STC_MasterUid: { if ( s.HasArgs() ) { CGrayUID pNewMasterUid = (DWORD) s.GetArgVal(); CChar * pChar = pNewMasterUid.CharFind(); if ( !pChar ) { DEBUG_ERR(( "MASTERUID called on non char 0%lx uid.\n", (DWORD)pNewMasterUid )); return( false ); } CStoneMember * pNewMaster = GetMember( pChar ); if ( !pNewMaster ) { DEBUG_ERR(( "MASTERUID called on char 0%lx (%s) that is not a valid member of stone with 0x%lx uid.\n", (DWORD)pNewMasterUid, pChar->GetName(), (DWORD)GetUID() )); return( false ); } CStoneMember * pMaster = GetMasterMember(); if ( pMaster ) { if ( pMaster->GetLinkUID() == pNewMasterUid ) return( true ); pMaster->SetPriv(STONEPRIV_MEMBER); //pMaster->SetLoyalTo(pChar); } //pNewMaster->SetLoyalTo(pChar); pNewMaster->SetPriv(STONEPRIV_MASTER); } else { DEBUG_ERR(( "MASTERUID called without arguments.\n" )); return( false ); } } return( true ); case STC_MEMBER: // "MEMBER" { TCHAR *Arg_ppCmd[8]; // Maximum parameters in one line size_t Arg_Qty = Str_ParseCmds( s.GetArgStr(), Arg_ppCmd, COUNTOF( Arg_ppCmd ), "," ); if (Arg_Qty < 1) // must at least provide the member uid return false; new CStoneMember( this, ahextoi(Arg_ppCmd[0]), // Member's UID Arg_Qty > 2 ? static_cast<STONEPRIV_TYPE>(ATOI(Arg_ppCmd[2])) : STONEPRIV_CANDIDATE, // Members priv level (use as a type) Arg_Qty > 1 ? Arg_ppCmd[1] : "", // Title ahextoi(Arg_ppCmd[3]), // Member is loyal to this Arg_Qty > 4 ? (ATOI( Arg_ppCmd[4] ) != 0) : 0, // Paperdoll stone abbreviation (also if they declared war) Arg_Qty > 5 ? (ATOI( Arg_ppCmd[5] ) != 0) : 0, // If we declared war Arg_Qty > 6 ? ATOI( Arg_ppCmd[6] ) : 0); // AccountGold } return true; case STC_WEBPAGE: // "WEBPAGE" m_sWebPageURL = s.GetArgStr(); return true; } if ( s.IsKeyHead( sm_szLoadKeys[STC_CHARTER], 7 )) { unsigned int i = ATOI(s.GetKey() + 7); if ( i >= COUNTOF(m_sCharter)) return( false ); m_sCharter[i] = s.GetArgStr(); return( true ); } return CItem::r_LoadVal(s); EXC_CATCH; EXC_DEBUG_START; EXC_ADD_SCRIPT; EXC_DEBUG_END; return false; }
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 ) { int iFound = 1; if ( pCont ) { //check for UID CGrayUID uidCont = static_cast<DWORD>(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; DWORD AmmoRender; 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()); AmmoHue = pVarAnimColor ? static_cast<DWORD>(pVarAnimColor->GetValNum()) : 0; AmmoRender = pVarAnimRender ? static_cast<DWORD>(pVarAnimRender->GetValNum()) : 0; pButte->Effect(EFFECT_BOLT, AmmoAnim, this, 16, 0, false, AmmoHue, AmmoRender); pButte->Sound(0x224); // 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; }
bool CPartyDef::r_Verb( CScript &s, CTextConsole *pSrc ) { ADDTOCALLSTACK("CPartyDef::r_Verb"); EXC_TRY("Verb"); ASSERT(pSrc); LPCTSTR pszKey = s.GetKey(); CScriptObj *pRef; if ( r_GetRef(pszKey, pRef) ) { if ( pszKey[0] ) { if ( !pRef ) return true; CScript script(pszKey, s.GetArgStr()); return pRef->r_Verb(script, pSrc); } } int iIndex = FindTableSorted(pszKey, sm_szVerbKeys, COUNTOF(sm_szVerbKeys) - 1); switch ( iIndex ) { case PDV_ADDMEMBER: case PDV_ADDMEMBERFORCED: { bool bForced = (iIndex == PDV_ADDMEMBERFORCED); CGrayUID toAdd = static_cast<CGrayUID>(s.GetArgVal()); CChar *pCharAdd = toAdd.CharFind(); CChar *pCharMaster = GetMaster().CharFind(); if ( !pCharAdd || IsInParty(pCharAdd) ) return false; if ( pCharMaster && !bForced ) pCharMaster->SetKeyNum("PARTY_LASTINVITE", (long long)toAdd); return CPartyDef::AcceptEvent(pCharAdd, GetMaster(), bForced); } break; case PDV_CLEARTAGS: { LPCTSTR pszArg = s.GetArgStr(); SKIP_SEPARATORS(pszArg); m_TagDefs.ClearKeys(pszArg); } break; case PDV_CREATE: return true; case PDV_DISBAND: return Disband(GetMaster()); case PDV_MESSAGE: break; case PDV_REMOVEMEMBER: { CGrayUID toRemove; LPCTSTR pszArg = s.GetArgStr(); if ( *pszArg == '@' ) { pszArg++; size_t nMember = Exp_GetVal(pszArg); if ( !m_Chars.IsValidIndex(nMember) ) return false; toRemove = m_Chars.GetChar(nMember); } else toRemove = static_cast<CGrayUID>(s.GetArgVal()); if ( toRemove ) return RemoveMember(toRemove, GetMaster()); return false; } break; case PDV_SETMASTER: { CGrayUID newMaster; LPCTSTR pszArg = s.GetArgStr(); if ( *pszArg == '@' ) { pszArg++; size_t nMember = Exp_GetVal(pszArg); if ( nMember == 0 || !m_Chars.IsValidIndex(nMember) ) return false; newMaster = m_Chars.GetChar(nMember); } else newMaster = static_cast<CGrayUID>(s.GetArgVal()); if ( newMaster ) return SetMaster(newMaster.CharFind()); return false; } break; case PDV_SYSMESSAGE: { CGrayUID toSysmessage; LPCTSTR pszArg = s.GetArgStr(); TCHAR *pUid = Str_GetTemp(); size_t x = 0; if ( *pszArg == '@' ) { pszArg++; if ( *pszArg != '@' ) { LPCTSTR __pszArg = pszArg; while ( *pszArg != ' ' ) { pszArg++; x++; } strcpylen(pUid, __pszArg, ++x); size_t nMember = Exp_GetVal(pUid); if ( !m_Chars.IsValidIndex(nMember) ) return false; toSysmessage = m_Chars.GetChar(nMember); } } else { LPCTSTR __pszArg = pszArg; while ( *pszArg != ' ' ) { pszArg++; x++; } strcpylen(pUid, __pszArg, ++x); toSysmessage = static_cast<CGrayUID>(Exp_GetVal(pUid)); } SKIP_SEPARATORS(pszArg); if ( toSysmessage ) { CChar *pSend = toSysmessage.CharFind(); pSend->SysMessage(pszArg); } else SysMessageAll(pszArg); } break; case PDV_TAGLIST: m_TagDefs.DumpKeys(pSrc, "TAG."); break; default: return false; } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_SCRIPTSRC; EXC_DEBUG_END; return false; }
bool CPartyDef::r_WriteVal( LPCTSTR pszKey, CGString &sVal, CTextConsole *pSrc ) { ADDTOCALLSTACK("CPartyDef::r_WriteVal"); EXC_TRY("WriteVal"); CScriptObj *pRef; if ( r_GetRef(pszKey, pRef) ) { if ( pRef == NULL ) // good command but bad link. { sVal = "0"; return true; } if ( pszKey[0] == '\0' ) // we where just testing the ref. { CObjBase *pObj = dynamic_cast<CObjBase *>(pRef); if ( pObj ) sVal.FormatHex(static_cast<DWORD>(pObj->GetUID())); else sVal.FormatVal(1); return true; } return pRef->r_WriteVal(pszKey, sVal, pSrc); } bool fZero = false; switch ( FindTableHeadSorted(pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys) - 1) ) { case PDC_ISSAMEPARTYOF: { pszKey += 13; GETNONWHITESPACE(pszKey); if ( pszKey[0] != '\0' ) { CGrayUID uidToCheck = static_cast<CGrayUID>(Exp_GetVal(pszKey)); CChar *pCharToCheck = uidToCheck.CharFind(); sVal.FormatVal(pCharToCheck && (pCharToCheck->m_pParty == this)); } else return false; } break; case PDC_MEMBERS: sVal.FormatVal(m_Chars.GetCharCount()); break; case PDC_SPEECHFILTER: sVal = m_pSpeechFunction.IsEmpty() ? "" : m_pSpeechFunction; break; case PDC_TAG0: fZero = true; pszKey++; case PDC_TAG: { if ( pszKey[3] != '.' ) return false; pszKey += 4; sVal = m_TagDefs.GetKeyStr(pszKey, fZero); } break; case PDC_TAGAT: { pszKey += 5; // eat the 'TAGAT' if ( *pszKey == '.' ) // do we have an argument? { SKIP_SEPARATORS(pszKey); size_t iQty = static_cast<size_t>(Exp_GetVal(pszKey)); if ( iQty >= m_TagDefs.GetCount() ) return false; // trying to get non-existant tag CVarDefCont *pTagAt = m_TagDefs.GetAt(iQty); if ( !pTagAt ) return false; // trying to get non-existant tag SKIP_SEPARATORS(pszKey); if ( !*pszKey ) { sVal.Format("%s=%s", pTagAt->GetKey(), pTagAt->GetValStr()); return true; } else if ( !strnicmp(pszKey, "KEY", 3) ) { sVal = pTagAt->GetKey(); return true; } else if ( !strnicmp(pszKey, "VAL", 3) ) { sVal = pTagAt->GetValStr(); return true; } } return false; } case PDC_TAGCOUNT: sVal.FormatVal(m_TagDefs.GetCount()); break; default: return false; } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_KEYRET(pSrc); EXC_DEBUG_END; return false; }
bool CPartyDef::AcceptEvent( CChar *pCharAccept, CGrayUID uidInviter, bool bForced ) // static { ADDTOCALLSTACK("CPartyDef::AcceptEvent"); // We are accepting the invite to join a party // No security checks if bForced -> true !!! // Party master is only one that can add ! GetChar(0) CChar *pCharInviter = uidInviter.CharFind(); if ( !pCharInviter || !pCharInviter->m_pClient || !pCharAccept || !pCharAccept->m_pClient || (pCharInviter == pCharAccept) ) return false; CPartyDef *pParty = pCharInviter->m_pParty; if ( !bForced ) { CVarDefCont *sTempVal = pCharInviter->GetTagDefs()->GetKey("PARTY_LASTINVITE"); if ( !sTempVal || (static_cast<CGrayUID>(sTempVal->GetValNum()) != pCharAccept->GetUID()) ) return false; pCharInviter->DeleteKey("PARTY_LASTINVITE"); if ( !pCharInviter->CanSee(pCharAccept) ) return false; } if ( pCharAccept->m_pParty ) // already in a party { if ( pParty == pCharAccept->m_pParty ) // already in this party return true; if ( bForced ) { pCharAccept->m_pParty->RemoveMember(pCharAccept->GetUID(), pCharAccept->GetUID()); pCharAccept->m_pParty = NULL; } else return false; } TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_PARTY_JOINED), pCharAccept->GetName()); if ( !pParty ) { // Create the party now. pParty = new CPartyDef(pCharInviter, pCharAccept); ASSERT(pParty); g_World.m_Parties.InsertHead(pParty); pCharInviter->SysMessage(pszMsg); } else { // Add to existing party if ( pParty->IsPartyFull() || (!bForced && !pParty->IsPartyMaster(pCharInviter)) ) return false; pParty->SysMessageAll(pszMsg); // tell everyone already in the party about this pParty->AcceptMember(pCharAccept); } pCharAccept->SysMessageDefault(DEFMSG_PARTY_ADDED); return true; }
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; }
bool CStoneMember::r_LoadVal( CScript & s ) // Load an item Script { ADDTOCALLSTACK("CStoneMember::r_LoadVal"); EXC_TRY("LoadVal"); STMM_TYPE iIndex = (STMM_TYPE) FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ); if ( GetLinkUID().IsChar() ) { switch ( iIndex ) { case STMM_ACCOUNTGOLD: SetAccountGold(s.GetArgVal()); break; case STMM_LOYALTO: { CGrayUID uid = s.GetArgVal(); SetLoyalTo(uid.CharFind()); } break; case STMM_PRIV: SetPriv(static_cast<STONEPRIV_TYPE>(s.GetArgVal())); break; case STMM_TITLE: SetTitle(s.GetArgStr()); break; case STMM_SHOWABBREV: SetAbbrev( s.GetArgVal() ? 1 : 0 ); break; default: return false; } } else if ( GetLinkUID().IsItem() ) { switch ( iIndex ) { case STMM_GUILD_THEYALLIANCE: break; case STMM_GUILD_THEYWAR: SetTheyDeclared(s.GetArgVal() ? true : false); break; case STMM_GUILD_WEALLIANCE: break; case STMM_GUILD_WEWAR: SetWeDeclared(s.GetArgVal() ? true : false); break; default: return false; } } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_SCRIPT; EXC_DEBUG_END; return false; }
TRIGRET_TYPE CScriptObj::OnTriggerRun( CScript &s, TRIGRUN_TYPE trigrun, CTextConsole * pSrc, CScriptTriggerArgs * pArgs, CGString * pResult ) { // ARGS: // TRIGRUN_SECTION_SINGLE = just this 1 line. // RETURN: // TRIGRET_RET_FALSE = 0 = return and continue processing. // TRIGRET_RET_TRUE = 1 = return and handled. (halt further processing) // TRIGRET_RET_DEFAULT = 2 = if process returns nothing specifically. // CScriptFileContext set g_Log.m_pObjectContext is the current context (we assume) // DEBUGCHECK( this == g_Log.m_pObjectContext ); static LPCTSTR const m_ExcKeys[] = { "parsing", "parsing IF statement", "parsing begin/loop cycle", "foritem", "forchar", "forclients", "forobjs", "forplayers", "for", "while", "forcharlayer/memorytype", "forcont", "forcontid/type", "dorand/doswitch", "return", "CALLing a subfunction", "VERBing a value", }; #ifdef WIN32 EXC_TRY(("OnTriggerRun(%x,%i,%x,%x,%x)", s.GetKey(), trigrun, pSrc, pArgs, pResult)); #else EXC_TRY(("OnTriggerRun(??,%i,%x,%x,%x)", trigrun, pSrc, pArgs, pResult)); #endif bool fSectionFalse = (trigrun == TRIGRUN_SECTION_FALSE || trigrun == TRIGRUN_SINGLE_FALSE); if ( trigrun == TRIGRUN_SECTION_EXEC || trigrun == TRIGRUN_SINGLE_EXEC ) // header was already read in. goto jump_in; EXC_SET(m_ExcKeys[0]); while ( s.ReadKeyParse()) { // Hit the end of the next trigger. if ( s.IsKeyHead( "ON", 2 )) // done with this section. break; jump_in: SK_TYPE iCmd = (SK_TYPE) FindTableSorted( s.GetKey(), sm_szScriptKeys, COUNTOF( sm_szScriptKeys )-1 ); TRIGRET_TYPE iRet; switch ( iCmd ) { case SK_ENDIF: case SK_END: case SK_ENDDO: case SK_ENDFOR: case SK_ENDRAND: case SK_ENDSWITCH: case SK_ENDWHILE: return( TRIGRET_ENDIF ); case SK_ELIF: case SK_ELSEIF: return( TRIGRET_ELSEIF ); case SK_ELSE: return( TRIGRET_ELSE ); } if ( fSectionFalse ) { // Ignoring this whole section. don't bother parsing it. switch ( iCmd ) { case SK_IF: EXC_SET(m_ExcKeys[1]); do { iRet = OnTriggerRun( s, TRIGRUN_SECTION_FALSE, pSrc, pArgs, pResult ); } while ( iRet == TRIGRET_ELSEIF || iRet == TRIGRET_ELSE ); break; case SK_WHILE: case SK_FOR: case SK_FORCHARLAYER: case SK_FORCHARMEMORYTYPE: case SK_FORCHAR: case SK_FORCLIENTS: case SK_FORCONT: case SK_FORCONTID: case SK_FORCONTTYPE: case SK_FORITEM: case SK_FOROBJ: case SK_FORPLAYERS: case SK_DORAND: case SK_DOSWITCH: case SK_BEGIN: EXC_SET(m_ExcKeys[2]); iRet = OnTriggerRun( s, TRIGRUN_SECTION_FALSE, pSrc, pArgs, pResult ); break; } if ( trigrun >= TRIGRUN_SINGLE_EXEC ) return( TRIGRET_RET_DEFAULT ); continue; // just ignore it. } switch ( iCmd ) { case SK_FORITEM: EXC_SET(m_ExcKeys[3]); iRet = OnTriggerForLoop( s, 1, pSrc, pArgs, pResult ); break; case SK_FORCHAR: EXC_SET(m_ExcKeys[4]); iRet = OnTriggerForLoop( s, 2, pSrc, pArgs, pResult ); break; case SK_FORCLIENTS: EXC_SET(m_ExcKeys[5]); iRet = OnTriggerForLoop( s, 0x12, pSrc, pArgs, pResult ); break; case SK_FOROBJ: EXC_SET(m_ExcKeys[6]); iRet = OnTriggerForLoop( s, 3, pSrc, pArgs, pResult ); break; case SK_FORPLAYERS: EXC_SET(m_ExcKeys[7]); iRet = OnTriggerForLoop( s, 0x22, pSrc, pArgs, pResult ); break; case SK_FOR: EXC_SET(m_ExcKeys[8]); iRet = OnTriggerForLoop( s, 4, pSrc, pArgs, pResult ); break; case SK_WHILE: EXC_SET(m_ExcKeys[9]); iRet = OnTriggerForLoop( s, 8, pSrc, pArgs, pResult ); break; case SK_FORCHARLAYER: case SK_FORCHARMEMORYTYPE: { EXC_SET(m_ExcKeys[10]); CChar * pCharThis = dynamic_cast <CChar *> (this); if ( pCharThis ) { if ( s.HasArgs() ) { if ( iCmd == SK_FORCHARLAYER ) iRet = pCharThis->OnCharTrigForLayerLoop( s, pSrc, pArgs, pResult, (LAYER_TYPE) s.GetArgVal() ); else iRet = pCharThis->OnCharTrigForMemTypeLoop( s, pSrc, pArgs, pResult, s.GetArgVal() ); break; } } } case SK_FORCONT: { EXC_SET(m_ExcKeys[11]); if ( s.HasArgs() ) { TCHAR * ppArgs[2]; TCHAR * tempPoint; TCHAR *porigValue = Str_GetTemp(); int iArgQty = Str_ParseCmds( (TCHAR*) s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), " \t," ); if ( iArgQty >= 1 ) { strcpy(porigValue, ppArgs[0]); tempPoint = porigValue; ParseText( tempPoint, pSrc, 0, pArgs ); CGrayUID pCurUid = (DWORD) Exp_GetVal(tempPoint); if ( pCurUid.IsValidUID() ) { CObjBase * pObj = pCurUid.ObjFind(); if ( pObj && pObj->IsContainer() ) { CContainer * pContThis = dynamic_cast <CContainer *> (pObj); CScriptLineContext StartContext = s.GetContext(); CScriptLineContext EndContext = StartContext; iRet = pContThis->OnGenericContTriggerForLoop( s, pSrc, pArgs, pResult, StartContext, EndContext, ppArgs[1] != NULL ? Exp_GetVal(ppArgs[1]) : 255 ); break; } } } } } case SK_FORCONTID: case SK_FORCONTTYPE: { EXC_SET(m_ExcKeys[12]); CContainer * pCont = dynamic_cast <CContainer *> (this); if ( pCont ) { if ( s.HasArgs() ) { LPCTSTR pszKey = s.GetArgRaw(); SKIP_SEPERATORS(pszKey); TCHAR * ppArgs[2]; Str_ParseCmds( (TCHAR*) pszKey, ppArgs, COUNTOF(ppArgs), " \t," ); CScriptLineContext StartContext = s.GetContext(); CScriptLineContext EndContext = StartContext; #ifdef _WIN32 iRet = pCont->OnContTriggerForLoop( s, pSrc, pArgs, pResult, StartContext, EndContext, g_Cfg.ResourceGetID( ( iCmd == SK_FORCONTID ) ? RES_ITEMDEF : RES_TYPEDEF, ppArgs[0] ), 0, ppArgs[1] != NULL ? Exp_GetVal( ppArgs[1] ) : 255 ); #else iRet = pCont->OnContTriggerForLoop( s, pSrc, pArgs, pResult, StartContext, EndContext, g_Cfg.ResourceGetID( ( iCmd == SK_FORCONTID ) ? RES_ITEMDEF : RES_TYPEDEF, (const char*&) ppArgs[0] ), 0, ppArgs[1] != NULL ? Exp_GetVal( ppArgs[1] ) : 255 ); #endif break; } } } default: // Parse out any variables in it. (may act like a verb sometimes?) EXC_SET(m_ExcKeys[0]); ParseText( s.GetArgRaw(), pSrc, 0, pArgs ); } switch ( iCmd ) { case SK_FORITEM: case SK_FORCHAR: case SK_FORCHARLAYER: case SK_FORCHARMEMORYTYPE: case SK_FORCLIENTS: case SK_FORCONT: case SK_FORCONTID: case SK_FORCONTTYPE: case SK_FOROBJ: case SK_FORPLAYERS: case SK_FOR: case SK_WHILE: if ( iRet != TRIGRET_ENDIF ) { if ( iRet > TRIGRET_RET_DEFAULT ) { DEBUG_MSG(( "WARNING: Trigger Bad For Ret %d '%s','%s'\n", iRet, s.GetKey(), s.GetArgStr())); } return( iRet ); } break; case SK_DORAND: // Do a random line in here. case SK_DOSWITCH: { EXC_SET(m_ExcKeys[13]); int iVal = s.GetArgVal(); if ( iCmd == SK_DORAND ) iVal = Calc_GetRandVal(iVal); for ( ;true; iVal-- ) { iRet = OnTriggerRun( s, (!iVal) ? TRIGRUN_SINGLE_TRUE : TRIGRUN_SINGLE_FALSE, pSrc, pArgs, pResult ); if ( iRet == TRIGRET_RET_DEFAULT ) continue; if ( iRet == TRIGRET_ENDIF ) break; if ( iRet > TRIGRET_RET_DEFAULT ) { DEBUG_MSG(( "WARNING: Trigger Bad Ret %d '%s','%s'\n", iRet, s.GetKey(), s.GetArgStr())); } return( iRet ); } } break; case SK_RETURN: // Process the trigger. EXC_SET(m_ExcKeys[14]); if ( pResult ) { pResult->Copy( s.GetArgStr() ); return (TRIGRET_TYPE) 1; } return ( (TRIGRET_TYPE) s.GetArgVal() ); case SK_IF: { EXC_SET(m_ExcKeys[1]); bool fTrigger = s.GetArgVal() ? true : false; bool fBeenTrue = false; while (true) { iRet = OnTriggerRun( s, fTrigger ? TRIGRUN_SECTION_TRUE : TRIGRUN_SECTION_FALSE, pSrc, pArgs, pResult ); if ( iRet < TRIGRET_ENDIF ) return( iRet ); if ( iRet == TRIGRET_ENDIF ) break; fBeenTrue |= fTrigger; if ( fBeenTrue ) fTrigger = false; else if ( iRet == TRIGRET_ELSE ) fTrigger = true; else if ( iRet == TRIGRET_ELSEIF ) { ParseText( s.GetArgStr(), pSrc, 0, pArgs ); fTrigger = s.GetArgVal() ? true : false; } } } break; case SK_BEGIN: // Do this block here. { EXC_SET(m_ExcKeys[2]); iRet = OnTriggerRun( s, TRIGRUN_SECTION_TRUE, pSrc, pArgs, pResult ); if ( iRet != TRIGRET_ENDIF ) { if ( iRet > TRIGRET_RET_DEFAULT ) { DEBUG_MSG(( "WARNING: Trigger Bad Ret %d '%s','%s'\n", iRet, s.GetKey(), s.GetArgStr())); } return( iRet ); } } break; default: if ( IsSetEF( EF_Scripts_Parse_Verbs ) ) { EXC_SET(m_ExcKeys[0]); ParseText( s.GetKeyBuffer(), pSrc, 0, pArgs ); } EXC_SET(m_ExcKeys[0]); if ( pArgs && pArgs->r_Verb( s, pSrc ) ) ; else { bool fRes; if ( !strcmpi( (char *)s.GetKey(), "call" ) ) { EXC_SET(m_ExcKeys[15]); LPCTSTR pszArgs = strchr( s.GetArgRaw(), ' ' ); if ( pszArgs ) GETNONWHITESPACE( pszArgs ); if ( !pszArgs || !*pszArgs ) { fRes = this->r_Call( s.GetArgRaw(), pSrc, pArgs ); } else { CScriptTriggerArgs Args( pszArgs ); if ( pArgs ) Args.m_VarsLocal = pArgs->m_VarsLocal; fRes = this->r_Call( s.GetArgRaw(), pSrc, &Args ); if ( pArgs ) pArgs->m_VarsLocal = Args.m_VarsLocal; } } else { EXC_SET(m_ExcKeys[16]); fRes = r_Verb( s, pSrc ); } if ( !fRes ) { DEBUG_MSG(( "WARNING: Trigger Bad Verb '%s','%s'\n", s.GetKey(), s.GetArgStr())); } } break; } if ( trigrun >= TRIGRUN_SINGLE_EXEC ) return( TRIGRET_RET_DEFAULT ); } EXC_CATCH("running trigger line"); return( TRIGRET_RET_DEFAULT ); }
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 ) == false ) ) { 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 ) == false ) ) { 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()) { // FindItemName ??? TCHAR * pszArgs = s.GetArgStr(); if ( !IsValidGameObjDef( static_cast<LPCTSTR>(pszArgs) ) ) { g_Log.EventWarn("Invalid ADD argument '%s'\n", pszArgs); SysMessageDefault( DEFMSG_CMD_INVALID ); return true; } RESOURCE_ID rid = g_Cfg.ResourceGetID( RES_QTY, const_cast<LPCTSTR &>(reinterpret_cast<LPTSTR &>(pszArgs))); if (( rid.GetResType() == RES_CHARDEF ) || ( rid.GetResType() == RES_SPAWN )) { m_Targ_PrvUID.InitUID(); return Cmd_CreateChar(static_cast<CREID_TYPE>(rid.GetResIndex()), SPELL_Summon, false ); } ITEMID_TYPE id = static_cast<ITEMID_TYPE>(rid.GetResIndex()); return Cmd_CreateItem( id ); } else { if ( IsValidDef( "d_add" ) ) Dialog_Setup( CLIMODE_DIALOG, g_Cfg.ResourceGetIDType(RES_DIALOG, "d_add"), 0, this->GetChar() ); 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/* || iArgs[0] == 0x3EB || iArgs[0] == 0x3EC*/) { // 0x3eb and 0x3ec among some others does not exists now, which doesn't mean they won't fill them and, since nothing happens when wrong id is sent, we can let them be sent. 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/* || IconId == 0x3EB || IconId == 0x3EC*/) { 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)); this->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<int>(piVal[0]), static_cast<int>(piVal[1]), static_cast<int>(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 fFound = false; for ( int m = 0; m < 256 && !fFound; m++ ) { if ( !g_MapList.m_maps[m] ) continue; for ( int d = 0; d < g_MapList.GetSectorQty(m) && !fFound; d++ ) { CSector *pSector = g_World.GetSector(m, d); if ( !pSector ) continue; CItem *pNext; CItem *pItem = STATIC_CAST <CItem*>(pSector->m_Items_Inert.GetHead()); for ( ; pItem != NULL && !fFound; pItem = pNext ) { pNext = 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", (DWORD)pItem->GetUID(), g_Cfg.ResourceGetName(rid)); fFound = true; } } } } } if ( ! fFound ) SysMessage(g_Cfg.GetDefaultMsg( DEFMSG_NO_BAD_SPAWNS )); } break; case CV_BANKSELF: // open my own bank addBankOpen( m_pChar, static_cast<LAYER_TYPE>(s.GetArgVal())); 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 == NULL) 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 != NULL) { 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 = s.GetArgVal(); pChar = uid.CharFind(); } if ( pChar ) closeUIWindow(pChar, 0x01); } break; case CV_CLOSEPROFILE: { CChar *pChar = m_pChar; if ( s.HasArgs() ) { CGrayUID uid = s.GetArgVal(); pChar = uid.CharFind(); } if ( pChar ) closeUIWindow(pChar, 0x08); } break; case CV_CLOSESTATUS: { CChar *pChar = m_pChar; if ( s.HasArgs() ) { CGrayUID uid = s.GetArgVal(); pChar = uid.CharFind(); } if ( pChar ) closeUIWindow(pChar, 0x02); } break; case CV_DYE: if ( s.HasArgs() ) { CGrayUID uid(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 != NULL ) { CPointMap po = pObj->GetTopLevelObj()->GetTopPoint(); CPointMap pnt = po; pnt.MoveN( DIR_W, 3 ); DWORD wBlockFlags = m_pChar->GetMoveBlockFlags(); pnt.m_z = g_World.GetHeightPoint2( pnt, wBlockFlags ); // ??? Get Area m_pChar->m_dirFace = pnt.GetDir( po, m_pChar->m_dirFace ); // Face the player m_pChar->Spell_Teleport( pnt, 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 != NULL ) { Event_Target(GetTargMode(), pObj->GetUID(), pObj->GetUnkPoint()); 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 = s.GetArgVal(); pChar = uid.CharFind(); } if ( pChar ) addCharPaperdoll(pChar); } 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(GetNetState()); #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: // Just put up another menu. 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: // from the spell skill script. // m_Targ_PrvUID should already be set. return Cmd_CreateChar(static_cast<CREID_TYPE>(g_Cfg.ResourceGetIndexType( RES_CHARDEF, s.GetArgStr())), SPELL_Summon, true ); 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 ) { int hue = -1; if ( ppArgs[0] ) hue = Exp_GetVal( ppArgs[0] ); int iClilocId = Exp_GetVal( ppArgs[1] ); if ( hue == -1 ) hue = HUE_TEXT_DEF; 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, static_cast<HUE_TYPE>(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 ) { int hue = -1; int affix = 0; if ( ppArgs[0] ) hue = Exp_GetVal( ppArgs[0] ); int iClilocId = Exp_GetVal( ppArgs[1] ); if ( ppArgs[2] ) affix = Exp_GetVal( ppArgs[2] ); if ( hue == -1 ) hue = HUE_TEXT_DEF; 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, static_cast<HUE_TYPE>(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", (LPCTSTR) s.GetKey(), (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; }