// --------------------------------------------------------- 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 ) 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->m_pClient->GetSocketID(), pFrom->GetName(), szText, pTo ? pTo->GetName() : "all"); sprintf(szText, g_Cfg.GetDefaultMsg(DEFMSG_PARTY_MSG), pText); PacketPartyChat cmd(pFrom, pText); if ( pTo ) SendMemberMsg(pTo, &cmd); else SendAll(&cmd); return true; }
bool CClient::Cmd_Skill_Tracking( unsigned int track_sel, bool fExec ) { ADDTOCALLSTACK("CClient::Cmd_Skill_Tracking"); // look around for stuff. ASSERT(m_pChar); if ( track_sel == UINT_MAX ) { // Tacking (unlike other skills) is used during menu setup. m_pChar->Skill_Cleanup(); // clean up current skill. CMenuItem item[6]; item[0].m_sText = g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_SKILLMENU_TITLE ); item[1].m_id = ITEMID_TRACK_HORSE; item[1].m_color = 0; item[1].m_sText = g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_SKILLMENU_ANIMALS ); item[2].m_id = ITEMID_TRACK_OGRE; item[2].m_color = 0; item[2].m_sText = g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_SKILLMENU_MONSTERS ); item[3].m_id = ITEMID_TRACK_MAN; item[3].m_color = 0; item[3].m_sText = g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_SKILLMENU_HUMANS ); item[4].m_id = ITEMID_TRACK_WOMAN; item[4].m_color = 0; item[4].m_sText = g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_SKILLMENU_PLAYERS ); m_tmMenu.m_Item[0] = 0; addItemMenu( CLIMODE_MENU_SKILL_TRACK_SETUP, item, 4 ); return( true ); } if ( track_sel > 0 ) // Not Cancelled { ASSERT( track_sel < COUNTOF( m_tmMenu.m_Item )); if ( fExec ) { // Tracking menu got us here. Start tracking the selected creature. m_pChar->SetTimeout( 1*TICK_PER_SEC ); m_pChar->m_Act_Targ = m_tmMenu.m_Item[track_sel]; // selected UID m_pChar->Skill_Start( SKILL_TRACKING ); return true; } static const NPCBRAIN_TYPE sm_Track_Brain[] = { NPCBRAIN_QTY, // not used here. NPCBRAIN_ANIMAL, NPCBRAIN_MONSTER, NPCBRAIN_HUMAN, NPCBRAIN_NONE // players }; if ( track_sel >= COUNTOF(sm_Track_Brain)) track_sel = COUNTOF(sm_Track_Brain)-1; NPCBRAIN_TYPE track_type = sm_Track_Brain[ track_sel ]; CMenuItem item[ minimum( MAX_MENU_ITEMS, COUNTOF( m_tmMenu.m_Item )) ]; size_t count = 0; item[0].m_sText = g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_SKILLMENU_TITLE ); m_tmMenu.m_Item[0] = track_sel; CWorldSearch AreaChars( m_pChar->GetTopPoint(), m_pChar->Skill_GetBase(SKILL_TRACKING)/10 + 10 ); for (;;) { CChar * pChar = AreaChars.GetChar(); if ( pChar == NULL ) break; if ( m_pChar == pChar ) continue; if ( GetPrivLevel() < pChar->GetPrivLevel() && pChar->IsStatFlag(STATF_Insubstantial) ) continue; CCharBase * pCharDef = pChar->Char_GetDef(); NPCBRAIN_TYPE basic_type = pChar->GetNPCBrain(); if ( basic_type == NPCBRAIN_DRAGON ) basic_type = NPCBRAIN_MONSTER; if ( track_type != basic_type && track_type != NPCBRAIN_QTY ) { if ( track_type != NPCBRAIN_NONE ) // no match. continue; if ( pChar->IsStatFlag( STATF_DEAD )) // can't track ghosts continue; if ( ! pChar->m_pPlayer ) continue; // Check action difficulty when trying to track players int tracking = m_pChar->Skill_GetBase( SKILL_TRACKING ); int detectHidden = m_pChar->Skill_GetBase( SKILL_DETECTINGHIDDEN ); if ( g_Cfg.m_iFeatureML & FEATURE_ML_RACIAL_BONUS && pChar->IsElf() ) tracking /= 2; // elves are more difficult to track (Difficult to Track racial trait) int hiding = pChar->Skill_GetBase( SKILL_HIDING ); int stealth = pChar->Skill_GetBase( SKILL_STEALTH ); int divisor = maximum(hiding + stealth, 1); int chance; if ( g_Cfg.m_iFeatureSE & FEATURE_SE_UPDATE ) chance = 50 * (tracking * 2 + detectHidden) / divisor; else chance = 50 * (tracking + detectHidden + 10 * Calc_GetRandVal(20) ) / divisor; if ( Calc_GetRandVal(100) > chance ) continue; } count ++; item[count].m_id = static_cast<WORD>(pCharDef->m_trackID); item[count].m_color = 0; item[count].m_sText = pChar->GetName(); m_tmMenu.m_Item[count] = pChar->GetUID(); if ( count >= (COUNTOF( item )-1) ) break; } // Some credit for trying. if ( count > 0 ) { m_pChar->Skill_UseQuick( SKILL_TRACKING, 20 + Calc_GetRandLLVal( 30 )); ASSERT(count < COUNTOF(item)); addItemMenu( CLIMODE_MENU_SKILL_TRACK, item, count ); return( true ); } else { m_pChar->Skill_UseQuick( SKILL_TRACKING, 10 + Calc_GetRandLLVal( 30 )); } } // Tracking failed or was cancelled. static LPCTSTR const sm_Track_FailMsg[] = { g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_CANCEL ), g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_FAIL_ANIMAL ), g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_FAIL_MONSTER ), g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_FAIL_HUMAN ), g_Cfg.GetDefaultMsg( DEFMSG_TRACKING_FAIL_HUMAN ) }; if (track_sel >= COUNTOF(sm_Track_FailMsg)) track_sel = COUNTOF(sm_Track_FailMsg) - 1; SysMessage( sm_Track_FailMsg[track_sel] ); return( false ); }
bool CChar::NPC_OnHearPetCmdTarg( int iCmd, CChar *pSrc, CObjBase *pObj, const CPointMap &pt, LPCTSTR pszArgs ) { ADDTOCALLSTACK("CChar::NPC_OnHearPetCmdTarg"); // Pet commands that required a target. if ( m_fIgnoreNextPetCmd ) { m_fIgnoreNextPetCmd = false; return false; } switch ( iCmd ) { case PC_FOLLOW: case PC_STAY: case PC_STOP: { // Pet friends can use only these commands if ( Memory_FindObjTypes(pSrc, MEMORY_FRIEND) ) break; } default: { // All others commands are avaible only to pet owner if ( !NPC_IsOwnedBy(pSrc, true) ) return false; } } if ( IsStatFlag(STATF_DEAD) ) { // Bonded NPCs still placed on world even when dead. // They can listen to commands, but not to these commands below if ( iCmd == PC_GUARD || iCmd == PC_GUARD_ME || iCmd == PC_ATTACK || iCmd == PC_KILL || iCmd == PC_TRANSFER || iCmd == PC_DROP || iCmd == PC_DROP_ALL ) return true; } bool bSuccess = false; CItem *pItemTarg = dynamic_cast<CItem *>(pObj); CChar *pCharTarg = dynamic_cast<CChar *>(pObj); switch ( iCmd ) { case PC_ATTACK: case PC_KILL: { if ( !pCharTarg || pCharTarg == pSrc ) break; bSuccess = pCharTarg->OnAttackedBy(pSrc, 1, true); // we know who told them to do this. if ( bSuccess ) bSuccess = Fight_Attack(pCharTarg, true); break; } case PC_FOLLOW: if ( !pCharTarg ) break; m_Act_Targ = pCharTarg->GetUID(); bSuccess = Skill_Start(NPCACT_FOLLOW_TARG); break; case PC_FRIEND: { if ( !pCharTarg || !pCharTarg->m_pPlayer || pCharTarg == pSrc ) { Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED)); break; } CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND); if ( pMemory ) { pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_ALREADY)); break; } pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS1), GetName(), pCharTarg->GetName()); pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS2), pSrc->GetName(), GetName()); Memory_AddObjTypes(pCharTarg, MEMORY_FRIEND); m_Act_Targ = pCharTarg->GetUID(); bSuccess = Skill_Start(NPCACT_FOLLOW_TARG); break; } case PC_UNFRIEND: { if ( !pCharTarg || !pCharTarg->m_pPlayer ) { Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED)); break; } CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND); if ( !pMemory ) { pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_NOTFRIEND)); break; } pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS1), GetName(), pCharTarg->GetName()); pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS2), pSrc->GetName(), GetName()); pMemory->Delete(); m_Act_Targ = pSrc->GetUID(); bSuccess = Skill_Start(NPCACT_FOLLOW_TARG); break; } case PC_GO: if ( !pt.IsValidPoint() ) break; m_Act_p = pt; bSuccess = Skill_Start(NPCACT_GOTO); break; case PC_GUARD: if ( !pCharTarg ) break; pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_GUARD_SUCCESS), GetName()); m_Act_Targ = pCharTarg->GetUID(); bSuccess = Skill_Start(NPCACT_GUARD_TARG); break; case PC_TRANSFER: if ( !pCharTarg || !pCharTarg->IsClient() ) break; if ( IsSetOF(OF_PetSlots) ) { if ( !pCharTarg->FollowersUpdate(this, static_cast<short>(maximum(1, GetDefNum("FOLLOWERSLOTS", true, true))), true) ) { pSrc->SysMessageDefault(DEFMSG_PETSLOTS_TRY_TRANSFER); break; } } bSuccess = NPC_PetSetOwner( pCharTarg ); break; case PC_PRICE: // "PRICE" the vendor item. if ( !pItemTarg || !NPC_IsVendor() || !pSrc->IsClient() ) break; if ( IsDigit(pszArgs[0]) ) // did they name a price return NPC_SetVendorPrice(pItemTarg, ATOI(pszArgs)); if ( !NPC_SetVendorPrice(pItemTarg, -1) ) // test if it can be priced return false; pSrc->m_pClient->addPromptConsole(CLIMODE_PROMPT_VENDOR_PRICE, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_SETPRICE_2), pItemTarg->GetUID(), GetUID()); return true; default: break; } // Make some sound to confirm we heard it NPC_OnPetCommand(bSuccess, pSrc); return bSuccess; }
int CChar::NPC_GetHostilityLevelToward( const CChar * pCharTarg ) const { ADDTOCALLSTACK("CChar::NPC_GetHostilityLevelToward"); // What is my general hostility level toward this type of creature ? // // based on: // npc vs player, (evil npc's don't like players regurdless of align, xcept in town) // karma (we are of different alignments) // creature body type. (allie groups) // hunger, (they could be food) // memories of this creature. // // DO NOT consider: // strength, he is far stronger or waeker than me. // health, i may be near death. // location (guarded area), (xcept in the case that evil people like other evils in town) // loot, etc. // // RETURN: // 100 = extreme hatred. // 0 = neutral. // -100 = love them // if ( !pCharTarg || !m_pNPC ) return 0; int iHostility = 0; // if it is a pet - register it the same as it's master. CChar * pCharOwn = pCharTarg->NPC_PetGetOwner(); if ( pCharOwn != NULL && pCharOwn != this ) { static int sm_iReentrant = 0; if (sm_iReentrant > 32) { DEBUG_ERR(("Too many owners (circular ownership?) to continue acquiring hostility level towards %s uid=0%lx\n", pCharOwn->GetName(), pCharOwn->GetUID().GetPrivateUID())); return 0; } ++sm_iReentrant; iHostility = NPC_GetHostilityLevelToward( pCharOwn ); --sm_iReentrant; return iHostility; } int iKarma = Stat_GetAdjusted(STAT_KARMA); bool fDoMemBase = false; if ( Noto_IsEvil() && // i am evil. (m_pArea && !m_pArea->IsGuarded()) && // we are not in an evil town. pCharTarg->m_pPlayer ) // my target is a player. { // If i'm evil i give no benefit to players with bad karma. // I hate all players. // Unless i'm in a guarded area. then they are cool. iHostility = 51; } else if ( m_pNPC->m_Brain == NPCBRAIN_BERSERK ) // i'm beserk. { // beserks just hate everyone all the time. iHostility = 100; } else if ( pCharTarg->m_pNPC && // my target is an NPC pCharTarg->m_pNPC->m_Brain != NPCBRAIN_BERSERK && // ok to hate beserks. ! g_Cfg.m_fMonsterFight ) // monsters are not supposed to fight other monsters ! { iHostility = -50; fDoMemBase = true; // set this low in case we are defending ourselves. but not attack for hunger. } else { // base hostillity on karma diff. int iKarmaTarg = pCharTarg->Stat_GetAdjusted(STAT_KARMA); if ( Noto_IsEvil()) { // I'm evil. if ( iKarmaTarg > 0 ) { iHostility += ( iKarmaTarg ) / 1024; } } else if ( iKarma > 300 ) { // I'm good and my target is evil. if ( iKarmaTarg < -100 ) { iHostility += ( -iKarmaTarg ) / 1024; } } } // Based on just creature type. if ( ! fDoMemBase ) { if ( pCharTarg->m_pNPC ) { // Human NPC's will attack humans . if ( GetDispID() == pCharTarg->GetDispID()) { // I will never attack those of my own kind...even if starving iHostility -= 100; } else if ( NPC_GetAllyGroupType( GetDispID()) == NPC_GetAllyGroupType(pCharTarg->GetDispID())) { iHostility -= 50; } else if ( pCharTarg->m_pNPC->m_Brain == m_pNPC->m_Brain ) // My basic kind { // Won't attack other monsters. (unless very hungry) iHostility -= 30; } } else { // Not immediately hostile if looks the same as me. if ( ! IsPlayableCharacter() && NPC_GetAllyGroupType( GetDispID()) == NPC_GetAllyGroupType(pCharTarg->GetDispID())) { iHostility -= 51; } } } // I have been attacked/angered by this creature before ? CItemMemory * pMemory = Memory_FindObjTypes( pCharTarg, MEMORY_FIGHT|MEMORY_HARMEDBY|MEMORY_IRRITATEDBY|MEMORY_SAWCRIME|MEMORY_AGGREIVED ); if ( pMemory ) { iHostility += 50; } #ifdef _ALPHASPHERE /* foes or allies? Defined by tag.ff_group, tag.ff_foe and/or tag.ff_ally */ CVarDefCont *pVar, *pVarTarg; int iffCounter=0, iffGroup=0; pVarTarg = pCharTarg->m_TagDefs.GetKey("FF_GROUP"); if ( pVarTarg ) { iffGroup = pVarTarg->GetValNum(); pVar = m_TagDefs.GetKey("FF_FOE"); if ( pVar ) { iffCounter = pVar->GetValNum(); if ( iffCounter & iffGroup ) { // is an enemy iHostility += 70; } } else { pVar = m_TagDefs.GetKey("FF_ALLY"); if ( pVar ) { iffCounter = pVar->GetValNum(); if ( iffCounter & iffGroup ) { // is an ally iHostility -= 70; } } } if ( iHostility > 100 ) iHostility = 100; else if ( iHostility < -100 ) iHostility = -100; TCHAR *pszTmp = Str_GetTemp(); sprintf(pszTmp,"char = %s, target = %s, iHostility = %d, iffGroup = %d, iffCounter = %d\n",GetName(),pCharTarg->GetName(),iHostility,iffGroup,iffCounter); DEBUG_WARN((pszTmp)); } #endif return( iHostility ); }
bool CSector::OnTick() { ADDTOCALLSTACK("CSector::OnTick"); /*Ticking sectors from CWorld * Timer is automatically updated at the end with a 30 seconds default delay * Any return before it will threat this CSector as Sleep and will make it * not tick again until a new player enters (WARNING: even if there are * players already inside). */ EXC_TRY("Tick"); // do not tick sectors on maps not supported by server if ( !g_MapList.m_maps[m_map] ) return true; EXC_SET_BLOCK("light change"); // Check for light change before putting the sector to sleep, since in other case the // world light levels will be shitty bool fEnvironChange = false; bool fLightChange = false; // check for local light level change ? byte bLightPrv = m_Env.m_Light; m_Env.m_Light = GetLightCalc( false ); if ( m_Env.m_Light != bLightPrv ) { fEnvironChange = true; fLightChange = true; } EXC_SET_BLOCK("sector sleeping?"); bool fCanSleep = CanSleep(true); int64 iCurTime = CServerTime::GetCurrentTime().GetTimeRaw(); // Put the sector to sleep if no clients been here in a while. if (fCanSleep && (g_Cfg._iSectorSleepDelay > 0)) { if (!IsSleeping()) { GoSleep(); } return true; } EXC_SET_BLOCK("sound effects"); // random weather noises and effects. SOUND_TYPE sound = 0; bool fWeatherChange = false; int iRegionPeriodic = 0; WEATHER_TYPE weatherprv = m_Env.m_Weather; if ( ! Calc_GetRandVal( 30 )) // change less often { m_Env.m_Weather = GetWeatherCalc(); if ( weatherprv != m_Env.m_Weather ) { fWeatherChange = true; fEnvironChange = true; } } // Random area noises. Only do if clients about. if ( GetClientsNumber() > 0 ) { iRegionPeriodic = 2; static const SOUND_TYPE sm_SfxRain[] = { 0x10, 0x11 }; static const SOUND_TYPE sm_SfxWind[] = { 0x14, 0x15, 0x16 }; static const SOUND_TYPE sm_SfxThunder[] = { 0x28, 0x29 , 0x206 }; // Lightning ? // wind, rain, switch ( GetWeather() ) { case WEATHER_CLOUDY: break; case WEATHER_SNOW: if ( ! Calc_GetRandVal(5) ) sound = sm_SfxWind[ Calc_GetRandVal( CountOf( sm_SfxWind )) ]; break; case WEATHER_RAIN: { int iVal = Calc_GetRandVal(30); if ( iVal < 5 ) { // Mess up the light levels for a sec.. LightFlash(); sound = sm_SfxThunder[ Calc_GetRandVal( CountOf( sm_SfxThunder )) ]; } else if ( iVal < 10 ) sound = sm_SfxRain[ Calc_GetRandVal( CountOf( sm_SfxRain )) ]; else if ( iVal < 15 ) sound = sm_SfxWind[ Calc_GetRandVal( CountOf( sm_SfxWind )) ]; } break; default: break; } } // Check environ changes and inform clients of it. ProfileTask charactersTask(PROFILE_CHARS); CChar * pCharNext = nullptr; CChar * pChar = static_cast <CChar*>( m_Chars_Active.GetHead()); for ( ; pChar != nullptr; pChar = pCharNext ) { EXC_TRYSUB("TickChar"); pCharNext = pChar->GetNext(); if (( fEnvironChange ) && ( IsTrigUsed(TRIGGER_ENVIRONCHANGE) )) pChar->OnTrigger(CTRIG_EnvironChange, pChar); if ( pChar->IsClient()) { CClient * pClient = pChar->GetClient(); ASSERT( pClient ); if ( sound ) pClient->addSound(sound, pChar); if ( fLightChange && ! pChar->IsStatFlag( STATF_DEAD | STATF_NIGHTSIGHT )) pClient->addLight(); if ( fWeatherChange ) pClient->addWeather(GetWeather()); if ( iRegionPeriodic && pChar->m_pArea ) { if ( ( iRegionPeriodic == 2 ) && IsTrigUsed(TRIGGER_REGPERIODIC)) { pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_REGPERIODIC ); --iRegionPeriodic; } if ( IsTrigUsed(TRIGGER_CLIPERIODIC) ) pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_CLIPERIODIC ); } } EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventDebug("#0 char 0%x '%s'\n", (dword)(pChar->GetUID()), pChar->GetName()); g_Log.EventDebug("#0 sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; } ProfileTask overheadTask(PROFILE_OVERHEAD); EXC_SET_BLOCK("check map cache"); if (fCanSleep && m_iMapBlockCacheTime < iCurTime) // Only if the sector can sleep. { // delete the static CServerMapBlock items that have not been used recently. m_iMapBlockCacheTime = CServerTime::GetCurrentTime().GetTimeRaw() + g_Cfg.m_iMapCacheTime ; CheckMapBlockCache(); } EXC_CATCH; SetTimeoutS(30); // Sector is Awake, make it tick after 30 seconds. EXC_DEBUG_START; CPointMap pt = GetBasePoint(); g_Log.EventError("#4 sector #%d [%hd,%hd,%hhd,%hhu]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUG_END; return true; }
bool CChar::Use_CarveCorpse( CItemCorpse * pCorpse ) { ADDTOCALLSTACK("CChar::Use_CarveCorpse"); CREID_TYPE CorpseID = pCorpse->m_itCorpse.m_BaseID; CCharBase *pCorpseDef = CCharBase::FindCharBase(CorpseID); if ( !pCorpseDef || pCorpse->m_itCorpse.m_carved ) { SysMessageDefault(DEFMSG_CARVE_CORPSE_NOTHING); return false; } CChar *pChar = pCorpse->m_uidLink.CharFind(); CPointMap pnt = pCorpse->GetTopLevelObj()->GetTopPoint(); UpdateAnimate(ANIM_BOW); if ( pCorpse->m_TagDefs.GetKeyNum("BLOOD") ) { CItem *pBlood = CItem::CreateBase(ITEMID_BLOOD4); ASSERT(pBlood); pBlood->SetHue(pCorpseDef->m_wBloodHue); pBlood->MoveToDecay(pnt, 5 * TICK_PER_SEC); } size_t iItems = 0; for ( size_t i = 0; i < pCorpseDef->m_BaseResources.GetCount(); i++ ) { long long iQty = pCorpseDef->m_BaseResources[i].GetResQty(); RESOURCE_ID rid = pCorpseDef->m_BaseResources[i].GetResourceID(); if ( rid.GetResType() != RES_ITEMDEF ) continue; ITEMID_TYPE id = static_cast<ITEMID_TYPE>(rid.GetResIndex()); if ( id == ITEMID_NOTHING ) break; iItems++; CItem *pPart = CItem::CreateTemplate(id, NULL, this); ASSERT(pPart); switch ( pPart->GetType() ) { case IT_FOOD: case IT_FOOD_RAW: case IT_MEAT_RAW: SysMessageDefault(DEFMSG_CARVE_CORPSE_MEAT); //pPart->m_itFood.m_MeatType = CorpseID; break; case IT_HIDE: SysMessageDefault(DEFMSG_CARVE_CORPSE_HIDES); //pPart->m_itSkin.m_creid = CorpseID; if ( (g_Cfg.m_iRacialFlags & RACIALF_HUMAN_WORKHORSE) && IsHuman() ) // humans always find 10% bonus when gathering hides, ores and logs (Workhorse racial trait) iQty = iQty * 110 / 100; break; case IT_FEATHER: SysMessageDefault(DEFMSG_CARVE_CORPSE_FEATHERS); //pPart->m_itSkin.m_creid = CorpseID; break; case IT_WOOL: SysMessageDefault(DEFMSG_CARVE_CORPSE_WOOL); //pPart->m_itSkin.m_creid = CorpseID; break; /*case IT_DRAGON_SCALE: // TO-DO (typedef IT_DRAGON_SCALE doesn't exist yet) SysMessageDefault(DEFMSG_CARVE_CORPSE_SCALES); //pPart->m_itSkin.m_creid = CorpseID; break;*/ default: break; } if ( iQty > 1 ) pPart->SetAmount(static_cast<WORD>(iQty)); if ( pChar && pChar->m_pPlayer ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_CORPSE_NAME), pPart->GetName(), pChar->GetName()); pPart->SetName(pszMsg); pPart->m_uidLink = pChar->GetUID(); pPart->MoveToDecay(pnt, pPart->GetDecayTime()); continue; } pCorpse->ContentAdd(pPart); } if ( iItems < 1 ) SysMessageDefault(DEFMSG_CARVE_CORPSE_NOTHING); CheckCorpseCrime(pCorpse, false, false); pCorpse->m_itCorpse.m_carved = 1; // mark as been carved pCorpse->m_itCorpse.m_uidKiller = GetUID(); // by you if ( pChar && pChar->m_pPlayer ) pCorpse->SetTimeout(0); // reset corpse timer to make it turn bones return true; }
bool CChar::NPC_OnHearPetCmdTarg(int iCmd, CChar *pSrc, CObjBase *pObj, const CPointMap &pt, LPCTSTR pszArgs) { ADDTOCALLSTACK("CChar::NPC_OnHearPetCmdTarg"); // Pet commands that required a target. if ( m_fIgnoreNextPetCmd ) { m_fIgnoreNextPetCmd = false; return false; } if ( !NPC_PetCheckAccess(iCmd, pSrc) ) return true; bool bSuccess = false; CItem *pItemTarg = dynamic_cast<CItem *>(pObj); CChar *pCharTarg = dynamic_cast<CChar *>(pObj); switch ( iCmd ) { case PC_ATTACK: case PC_KILL: { if ( !pCharTarg || (pCharTarg == this) || (pCharTarg == pSrc) ) break; bSuccess = pCharTarg->OnAttackedBy(pSrc, true); if ( bSuccess ) bSuccess = Fight_Attack(pCharTarg, true); break; } case PC_FOLLOW: if ( !pCharTarg || (pCharTarg == this) ) break; m_Act_Targ = pCharTarg->GetUID(); bSuccess = Skill_Start(NPCACT_FOLLOW_TARG); break; case PC_FRIEND: { if ( !pCharTarg || !pCharTarg->m_pPlayer || (pCharTarg == pSrc) ) { Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED)); break; } CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND); if ( pMemory ) { pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_ALREADY)); break; } pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS1), GetName(), pCharTarg->GetName()); pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUCCESS2), pSrc->GetName(), GetName()); Memory_AddObjTypes(pCharTarg, MEMORY_FRIEND); m_Act_Targ = pCharTarg->GetUID(); bSuccess = Skill_Start(NPCACT_FOLLOW_TARG); break; } case PC_UNFRIEND: { if ( !pCharTarg || !pCharTarg->m_pPlayer ) { Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CONFUSED)); break; } CItemMemory *pMemory = Memory_FindObjTypes(pCharTarg, MEMORY_FRIEND); if ( !pMemory ) { pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_NOTFRIEND)); break; } pSrc->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS1), GetName(), pCharTarg->GetName()); pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND_SUCCESS2), pSrc->GetName(), GetName()); pMemory->Delete(); m_Act_Targ = pSrc->GetUID(); bSuccess = Skill_Start(NPCACT_FOLLOW_TARG); break; } case PC_GO: if ( !pt.IsValidPoint() ) break; m_Act_p = pt; bSuccess = Skill_Start(NPCACT_GOTO); break; case PC_GUARD: if ( !pCharTarg || (pCharTarg == this) ) break; pCharTarg->SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_GUARD_SUCCESS), GetName()); m_Act_Targ = pCharTarg->GetUID(); bSuccess = Skill_Start(NPCACT_GUARD_TARG); break; case PC_TRANSFER: if ( !pCharTarg || !pCharTarg->m_pClient ) break; if ( IsSetOF(OF_PetSlots) ) { if ( !pCharTarg->FollowersUpdate(this, static_cast<short>(maximum(1, GetDefNum("FOLLOWERSLOTS", true))), true) ) { pSrc->SysMessageDefault(DEFMSG_PETSLOTS_TRY_TRANSFER); break; } } bSuccess = NPC_PetSetOwner(pCharTarg); break; case PC_PRICE: if ( !pItemTarg || !NPC_IsVendor() || !pSrc->m_pClient ) break; if ( IsDigit(pszArgs[0]) ) // did they name a price return NPC_SetVendorPrice(pItemTarg, ATOI(pszArgs)); if ( !NPC_SetVendorPrice(pItemTarg, -1) ) // test if it can be priced return false; pSrc->m_pClient->addPromptConsole(CLIMODE_PROMPT_VENDOR_PRICE, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_SETPRICE_2), pItemTarg->GetUID(), GetUID()); return true; default: break; } // Make some sound to confirm we heard it NPC_PetConfirmCommand(bSuccess, pSrc); return bSuccess; }
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 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; }
//o---------------------------------------------------------------------------o //| Function : void buyItem(CSocket *mSock) //| Date : Unknown //| Programmer : UOX3 DevTeam //o---------------------------------------------------------------------------o //| Purpose : Called when player buys an item from a vendor //o---------------------------------------------------------------------------o bool CPIBuyItem::Handle(void) { UI16 i; UI32 playergoldtotal, goldtotal = 0; bool soldout = false, clear = false; CChar *mChar = tSock->CurrcharObj(); CItem *p = mChar->GetPackItem(); if (!ValidateObject(p)) return true; ITEMLIST bitems; std::vector<UI08> layer; std::vector<UI16> amount; // vector for storing all objects that actually end up in user backpack std::vector< CItem * > boughtItems; CChar *npc = calcCharObjFromSer(tSock->GetDWord(3)); UI16 itemtotal = static_cast<UI16>((tSock->GetWord(1) - 8) / 7); if (itemtotal > 511) return true; boughtItems.reserve(itemtotal); bitems.resize(itemtotal); amount.resize(itemtotal); layer.resize(itemtotal); int baseOffset = 0; for (i = 0; i < itemtotal; ++i) { baseOffset = 7 * i; layer[i] = tSock->GetByte(8 + baseOffset); bitems[i] = calcItemObjFromSer(tSock->GetDWord(9 + baseOffset)); amount[i] = tSock->GetWord(13 + baseOffset); goldtotal += (amount[i] * (bitems[i]->GetBuyValue())); } bool useBank = (goldtotal >= static_cast<UI32>(cwmWorldState->ServerData()->BuyThreshold())); if (useBank) playergoldtotal = GetBankCount(mChar, 0x0EED); else playergoldtotal = GetItemAmount(mChar, 0x0EED); if (playergoldtotal >= goldtotal || mChar->IsGM()) { for (i = 0; i < itemtotal; ++i) { if (bitems[i]->GetAmount() < amount[i]) soldout = true; // Check if onBuyFromVendor JS event is present for each item being purchased // If true, and a return false has been returned from the script, halt the purchase UI16 targTrig = bitems[i]->GetScriptTrigger(); cScript *toExecute = JSMapping->GetScript(targTrig); if (toExecute != NULL) if (toExecute->OnBuyFromVendor(tSock, npc, bitems[i])) { bitems.clear(); //needed??? return true; } } if (soldout) { npc->TextMessage(tSock, 1336, TALK, false); clear = true; } else { if (mChar->IsGM()) npc->TextMessage(NULL, 1337, TALK, false, mChar->GetName().c_str()); else { if (goldtotal == 1) npc->TextMessage(NULL, 1338, TALK, false, mChar->GetName().c_str(), goldtotal); else npc->TextMessage(NULL, 1339, TALK, false, mChar->GetName().c_str(), goldtotal); Effects->goldSound(tSock, goldtotal); } clear = true; if (!mChar->IsGM()) if (useBank) DeleteBankItem(mChar, goldtotal, 0x0EED); else DeleteItemAmount(mChar, goldtotal, 0x0EED); CItem *biTemp; CItem *iMade = NULL; UI16 j; for (i = 0; i < itemtotal; ++i) { biTemp = bitems[i]; iMade = NULL; if (biTemp->GetAmount() > amount[i]) { if (biTemp->isPileable()) { iMade = Items->DupeItem(tSock, biTemp, amount[i]); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } else { for (j = 0; j < amount[i]; ++j) { iMade = Items->DupeItem(tSock, biTemp, 1); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } } biTemp->IncAmount(-amount[i], true); biTemp->SetRestock(biTemp->GetRestock() + amount[i]); } else { switch(layer[i]) { case 0x1A: // Sell Container if (biTemp->isPileable()) { iMade = Items->DupeItem(tSock, biTemp, amount[i]); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } else { for (j = 0; j < amount[i]; ++j) { iMade = Items->DupeItem(tSock, biTemp, 1); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } } biTemp->IncAmount(-amount[i], true); biTemp->SetRestock(biTemp->GetRestock() + amount[i]); break; case 0x1B: // Bought Container if (biTemp->isPileable()) { biTemp->SetCont(p); boughtItems.push_back(biTemp); } else { for (j = 0; j < amount[i]-1; ++j) { iMade = Items->DupeItem(tSock, biTemp, 1); if (iMade != NULL) { iMade->SetCont(p); iMade->PlaceInPack(); boughtItems.push_back(iMade); } } biTemp->SetCont(p); biTemp->SetAmount(1); boughtItems.push_back(biTemp); } break; default: Console.Error(" Fallout of switch statement without default. vendor.cpp, buyItem()"); break; } } } for (i = 0; i < boughtItems.size(); ++i) { if (boughtItems[i]) { cScript *toGrab = JSMapping->GetScript(boughtItems[i]->GetScriptTrigger()); if (toGrab != NULL) toGrab->OnBoughtFromVendor(tSock, npc, boughtItems[i]); } } } } else npc->TextMessage(NULL, 1340, TALK, false); if (clear) { CPBuyItem clrSend; clrSend.Serial(tSock->GetDWord(3)); tSock->Send(&clrSend); } return true; }
//o---------------------------------------------------------------------------o //| Function : void sellItem(CSocket *mSock) //| Date : Unknown //| Programmer : UOX3 DevTeam //o---------------------------------------------------------------------------o //| Purpose : Player sells an item to the vendor //o---------------------------------------------------------------------------o bool CPISellItem::Handle(void) { if (tSock->GetByte(8) != 0) { CChar *mChar = tSock->CurrcharObj(); CChar *n = calcCharObjFromSer(tSock->GetDWord(3)); if (!ValidateObject(n) || !ValidateObject(mChar)) return true; CItem *buyPack = n->GetItemAtLayer(IL_BUYCONTAINER); CItem *boughtPack = n->GetItemAtLayer(IL_BOUGHTCONTAINER); CItem *sellPack = n->GetItemAtLayer(IL_SELLCONTAINER); if (!ValidateObject(buyPack) || !ValidateObject(sellPack) || !ValidateObject(boughtPack)) return true; CItem *j = NULL, *k = NULL, *l = NULL; UI16 amt = 0, maxsell = 0; UI08 i = 0; UI32 totgold = 0, value = 0; for (i = 0; i < tSock->GetByte(8); ++i) { j = calcItemObjFromSer(tSock->GetDWord(9 + (6*i))); amt = tSock->GetWord(13 + (6*i)); maxsell += amt; } if (maxsell > cwmWorldState->ServerData()->SellMaxItemsStatus()) { n->TextMessage(NULL, 1342, TALK, false, mChar->GetName().c_str(), cwmWorldState->ServerData()->SellMaxItemsStatus()); return true; } for (i = 0; i < tSock->GetByte(8); ++i) { j = calcItemObjFromSer(tSock->GetDWord(9 + (6*i))); amt = tSock->GetWord(13 + (6*i)); if (ValidateObject(j)) { if (j->GetAmount() < amt || FindItemOwner(j) != mChar) { n->TextMessage(NULL, 1343, TALK, false); return true; } // Check if onSellToVendor JS event is present for each item being sold // If true, and a value of "false" has been returned from the script, halt the sale UI16 targTrig = j->GetScriptTrigger(); cScript *toExecute = JSMapping->GetScript(targTrig); if (toExecute != NULL) if (toExecute->OnSellToVendor(tSock, n, j)) return true; CItem *join = NULL; CDataList<CItem *> *pCont = boughtPack->GetContainsList(); for (k = pCont->First(); !pCont->Finished(); k = pCont->Next()) if (ValidateObject(k)) if (k->GetID() == j->GetID() && j->GetType() == k->GetType()) join = k; pCont = buyPack->GetContainsList(); for (k = pCont->First(); !pCont->Finished(); k = pCont->Next()) if (ValidateObject(k)) if (k->GetID() == j->GetID() && j->GetType() == k->GetType()) value = calcValue(j, k->GetSellValue()); // If an object already exist in the boughtPack that this one can be joined to... if (ValidateObject(join)) { join->IncAmount(amt); join->SetRestock(join->GetRestock() - amt); l = join; totgold += (amt * value); if (j->GetAmount() == amt) j->Delete(); else j->IncAmount(-amt); } else { //Otherwise, move this item to the vendor's boughtPack totgold += (amt * value); if (j->GetAmount() != amt) { l = Items->DupeItem(tSock, j, amt); j->SetAmount(j->GetAmount() - amt); } else l = j; if (ValidateObject(l)) l->SetCont(boughtPack); } if (l) { cScript *toGrab = JSMapping->GetScript(l->GetScriptTrigger()); if (toGrab != NULL) toGrab->OnSoldToVendor(tSock, n, l); } } } Effects->goldSound(tSock, totgold); while (totgold > MAX_STACK) { Items->CreateScriptItem(tSock, mChar, "0x0EED", MAX_STACK, OT_ITEM, true); totgold -= MAX_STACK; } if (totgold > 0) Items->CreateScriptItem(tSock, mChar, "0x0EED", totgold, OT_ITEM, true); } CPBuyItem clrSend; clrSend.Serial(tSock->GetDWord(3)); tSock->Send(&clrSend); return true; }
int CChar::NPC_GetHostilityLevelToward(const CChar *pCharTarg) const { ADDTOCALLSTACK("CChar::NPC_GetHostilityLevelToward"); // What is my general hostility level toward this type of creature ? // // based on: // npc vs player (evil npc's don't like players) // creature body type (allie groups) // // RETURN: // 100 = extreme hatred. // 0 = neutral. // -100 = love them if ( !m_pNPC || !pCharTarg ) return 0; // If it's a pet, inherit hostility from it's master CChar *pCharOwn = pCharTarg->NPC_PetGetOwner(); if ( pCharOwn && (pCharOwn != this) ) { static int sm_iReentrant = 0; if ( sm_iReentrant > 32 ) { DEBUG_ERR(("Too many owners (circular ownership?) to continue acquiring hostility level towards %s uid=0%lx\n", pCharOwn->GetName(), pCharOwn->GetUID().GetPrivateUID())); return 0; } ++sm_iReentrant; int iHostility = NPC_GetHostilityLevelToward(pCharOwn); --sm_iReentrant; return iHostility; } if ( m_pNPC->m_Brain == NPCBRAIN_BERSERK ) // Beserks always hate everyone return 100; if ( pCharTarg->m_pPlayer ) return 100; if ( pCharTarg->m_pNPC ) { if ( !g_Cfg.m_fMonsterFight ) // Monsters are not supposed to fight other monsters! return 0; if ( GetDispID() == pCharTarg->GetDispID() ) // I will never attack those of my own kind return -100; else if ( NPC_GetAllyGroupType(GetDispID()) == NPC_GetAllyGroupType(pCharTarg->GetDispID()) ) return -50; else if ( m_pNPC->m_Brain == pCharTarg->m_pNPC->m_Brain ) return -30; return 100; } return 0; }
void CSector::OnTick(int iPulseCount) { ADDTOCALLSTACK_INTENSIVE("CSector::OnTick"); // CWorld gives OnTick() to all CSectors. EXC_TRY("Tick"); EXC_SET("light change"); // do not tick sectors on maps not supported by server if ( !g_MapList.m_maps[m_map] ) return; // Check for light change before putting the sector to sleep, since in other case the // world light levels will be shitty bool fEnvironChange = false; bool fLightChange = false; bool fSleeping = false; if ( ! ( iPulseCount & 0x7f )) // 30 seconds or so. { // check for local light level change ? BYTE blightprv = m_Env.m_Light; m_Env.m_Light = GetLightCalc( false ); if ( m_Env.m_Light != blightprv ) { fEnvironChange = true; fLightChange = true; } } EXC_SET("sector sleeping?"); size_t clients = m_Chars_Active.HasClients(); if ( clients <= 0 ) // having no clients inside { // Put the sector to sleep if no clients been here in a while. fSleeping = IsSectorSleeping(); if ( fSleeping ) { if ( !g_Cfg.m_iSectorSleepMask ) return; if (( iPulseCount & g_Cfg.m_iSectorSleepMask ) != ( GetIndex() & g_Cfg.m_iSectorSleepMask )) return; } } EXC_SET("sound effects"); // random weather noises and effects. SOUND_TYPE sound = 0; bool fWeatherChange = false; int iRegionPeriodic = 0; if ( ! ( iPulseCount & 0x7f )) // 30 seconds or so. { // Only do this every x minutes or so (TICK_PER_SEC) // check for local weather change ? WEATHER_TYPE weatherprv = m_Env.m_Weather; if ( ! Calc_GetRandVal( 30 )) // change less often { m_Env.m_Weather = GetWeatherCalc(); if ( weatherprv != m_Env.m_Weather ) { fWeatherChange = true; fEnvironChange = true; } } // Random area noises. Only do if clients about. if ( clients > 0 ) { iRegionPeriodic = 2; static const SOUND_TYPE sm_SfxRain[] = { 0x10, 0x11 }; static const SOUND_TYPE sm_SfxWind[] = { 0x14, 0x15, 0x16 }; static const SOUND_TYPE sm_SfxThunder[] = { 0x28, 0x29 , 0x206 }; // Lightning ? // wind, rain, switch ( GetWeather() ) { case WEATHER_CLOUDY: break; case WEATHER_SNOW: if ( ! Calc_GetRandVal(5) ) sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ]; break; case WEATHER_RAIN: { int iVal = Calc_GetRandVal(30); if ( iVal < 5 ) { // Mess up the light levels for a sec.. LightFlash(); sound = sm_SfxThunder[ Calc_GetRandVal( COUNTOF( sm_SfxThunder )) ]; } else if ( iVal < 10 ) sound = sm_SfxRain[ Calc_GetRandVal( COUNTOF( sm_SfxRain )) ]; else if ( iVal < 15 ) sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ]; } break; default: break; } } } // regen all creatures and do AI ProfileTask charactersTask(PROFILE_CHARS); CChar * pCharNext = NULL; CChar * pChar = static_cast<CChar *>(m_Chars_Active.GetHead()); for ( ; pChar != NULL; pChar = pCharNext ) { EXC_TRYSUB("TickChar"); pCharNext = pChar->GetNext(); if ( fEnvironChange && IsTrigUsed(TRIGGER_ENVIRONCHANGE) ) pChar->OnTrigger(CTRIG_EnvironChange, pChar); if ( pChar->m_pClient ) { if ( sound ) pChar->m_pClient->addSound(sound, pChar); if ( fLightChange && !pChar->IsStatFlag(STATF_DEAD|STATF_NightSight) ) pChar->m_pClient->addLight(); if ( fWeatherChange ) pChar->m_pClient->addWeather(GetWeather()); if ( iRegionPeriodic && pChar->m_pArea ) { if ( (iRegionPeriodic == 2) && IsTrigUsed(TRIGGER_REGPERIODIC) ) { pChar->m_pArea->OnRegionTrigger(pChar, RTRIG_REGPERIODIC); iRegionPeriodic--; } if ( IsTrigUsed(TRIGGER_CLIPERIODIC) ) pChar->m_pArea->OnRegionTrigger(pChar, RTRIG_CLIPERIODIC); } } // Can only die on your own tick. if ( !pChar->OnTick() ) pChar->Delete(); EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventDebug("char 0%lx '%s'\n", static_cast<DWORD>(pChar->GetUID()), pChar->GetName()); g_Log.EventDebug("sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; } // decay items on ground = time out spells / gates etc.. etc.. // No need to check these so often ! ProfileTask itemsTask(PROFILE_ITEMS); CItem * pItemNext = NULL; CItem * pItem = dynamic_cast <CItem*>( m_Items_Timer.GetHead()); for ( ; pItem != NULL; pItem = pItemNext ) { EXC_TRYSUB("TickItem"); pItemNext = pItem->GetNext(); EXC_SETSUB("TimerExpired"); if ( pItem->IsTimerExpired() ) { EXC_SETSUB("ItemTick"); if ( !pItem->OnTick() ) { EXC_SETSUB("ItemDelete"); pItem->Delete(); } else { EXC_SETSUB("TimerExpired2"); if ( pItem->IsTimerExpired() ) // forgot to clear the timer.? strange. { EXC_SETSUB("SetTimeout"); pItem->SetTimeout(-1); } } } EXC_SETSUB("UpdateFlags"); pItem->OnTickStatusUpdate(); #ifdef _WIN32 EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventError("item 0%lx '%s' [timer=%lld, type=%lld]\n", static_cast<DWORD>(pItem->GetUID()), pItem->GetName(), pItem->GetTimerAdjusted(), static_cast<int>(pItem->GetType())); g_Log.EventError("sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; #else } #ifndef _DEBUG catch ( const CGrayError& e )
void CConsole::Process( int c ) { char outputline[128], temp[1024]; bool kill = false; int indexcount = 0; int j; int keyresp; CSocket *tSock = NULL; if( c == '*' ) { if( cwmWorldState->GetSecure() ) messageLoop << "Secure mode disabled. Press ? for a commands list"; else messageLoop << "Secure mode re-enabled"; cwmWorldState->SetSecure( !cwmWorldState->GetSecure() ); return; } else { if( cwmWorldState->GetSecure() ) { messageLoop << "Secure mode prevents keyboard commands! Press '*' to disable"; return; } JSCONSOLEKEYMAP_ITERATOR toFind = JSKeyHandler.find( c ); if( toFind != JSKeyHandler.end() ) { if( toFind->second.isEnabled ) { cScript *toExecute = JSMapping->GetScript( toFind->second.scriptID ); if( toExecute != NULL ) { // All commands that execute are of the form: command_commandname (to avoid possible clashes) #if defined( UOX_DEBUG_MODE ) Print( "Executing JS keystroke %c %s\n", c, toFind->second.cmdName.c_str() ); #endif toExecute->CallParticularEvent( toFind->second.cmdName.c_str(), NULL, 0 ); } return; } } switch( c ) { case '!': // Force server to save accounts file messageLoop << "CMD: Saving Accounts... "; Accounts->Save(); messageLoop << MSG_PRINTDONE; break; case '@': // Force server to save all files.(Manual save) messageLoop << MSG_WORLDSAVE; break; case 'Y': std::cout << "System: "; while( !kill ) { keyresp = cl_getch(); switch( keyresp ) { case -1: // no key pressed case 0: break; case 0x1B: memset( outputline, 0x00, sizeof( outputline ) ); indexcount = 0; kill = true; std::cout << std::endl; messageLoop << "CMD: System broadcast canceled."; break; case 0x08: --indexcount; if( indexcount < 0 ) indexcount = 0; else std::cout << "\b \b"; break; case 0x0A: case 0x0D: outputline[indexcount] = 0; messageLoop.NewMessage( MSG_CONSOLEBCAST, outputline ); indexcount = 0; kill = true; std::cout << std::endl; sprintf( temp, "CMD: System broadcast sent message \"%s\"", outputline ); memset( outputline, 0x00, sizeof( outputline ) ); messageLoop << temp; break; default: if( static_cast<size_t>(indexcount) < sizeof( outputline ) ) { outputline[indexcount++] = (UI08)(keyresp); std::cout << (char)keyresp; } break; } keyresp = 0x00; } break; case '[': { // We want to group all the contents of the multimap container numerically by group. We rely on the self ordering in the multimap implementation to do this. messageLoop << " "; messageLoop << "Auto-AddMenu Statistics"; messageLoop << " "; char szBuffer[128]; // We need to get an iteration into the map first of all the top level ULONGs then we can get an equal range. std::map< UI32, UI08 > localMap; localMap.clear(); for( ADDMENUMAP_CITERATOR CJ = g_mmapAddMenuMap.begin(); CJ != g_mmapAddMenuMap.end(); CJ++ ) { // check to see if the group id has been checked already if( localMap.find( CJ->first ) == localMap.end() ) { localMap.insert( std::make_pair( CJ->first, 0 ) ); memset( szBuffer, 0x00, sizeof( szBuffer ) ); sprintf( szBuffer, "AddMenuGroup %lu:", CJ->first ); messageLoop << szBuffer; std::pair< ADDMENUMAP_CITERATOR, ADDMENUMAP_CITERATOR > pairRange = g_mmapAddMenuMap.equal_range( CJ->first ); int count = 0; for( ADDMENUMAP_CITERATOR CI=pairRange.first;CI != pairRange.second; CI++ ) { count++; } memset( szBuffer, 0x00, sizeof( szBuffer ) ); sprintf( szBuffer, " Found %i Auto-AddMenu Item(s).", count ); messageLoop << szBuffer; } } messageLoop << MSG_SECTIONBEGIN; break; } case '<': messageLoop << "Function not implemented."; break; case '>': messageLoop << "Function not implemented."; break; case 0x1B: case 'Q': messageLoop << MSG_SECTIONBEGIN; messageLoop << "CMD: Immediate Shutdown initialized!"; messageLoop << MSG_SHUTDOWN; break; case '0': if( !cwmWorldState->GetReloadingScripts() ) { cwmWorldState->SetReloadingScripts( true ); // Reload all the files. If there are issues with these files change the order reloaded from here first. cwmWorldState->ServerData()->Load(); messageLoop << "CMD: Loading All"; messageLoop << " Server INI... "; // Reload accounts, and update Access.adm if new accounts available. messageLoop << " Loading Accounts... "; Accounts->Load(); messageLoop << MSG_PRINTDONE; // Reload Region Files messageLoop << " Loading Regions... "; UnloadRegions(); LoadRegions(); messageLoop << MSG_PRINTDONE; // Reload the serve spawn regions messageLoop << " Loading Spawn Regions... "; UnloadSpawnRegions(); LoadSpawnRegions(); messageLoop << MSG_PRINTDONE; // Reload the server command list messageLoop << " Loading commands... "; Commands->Load(); messageLoop << MSG_PRINTDONE; // Reload DFN's messageLoop << " Loading Server DFN... "; FileLookup->Reload(); LoadTeleportLocations(); messageLoop << MSG_PRINTDONE; // messageLoop access is REQUIRED, as this function is executing in a different thread, so we need thread safety messageLoop << " Loading JSE Scripts... "; // Reload the current Spells messageLoop << " Loading spells... "; Magic->LoadScript(); messageLoop << MSG_PRINTDONE; // Reload the HTML output templates messageLoop << " Loading HTML Templates... "; HTMLTemplates->Unload(); HTMLTemplates->Load(); cwmWorldState->SetReloadingScripts( false ); messageLoop << MSG_PRINTDONE; } else messageLoop << "Server can only load one script at a time"; break; case 'T': // Timed shut down(10 minutes) messageLoop << "CMD: 10 Minute Server Shutdown Announced(Timed)"; cwmWorldState->SetEndTime( BuildTimeValue( 600 ) ); endmessage(0); break; case 'D': // Disconnect account 0 (useful when client crashes) for( tSock = Network->LastSocket(); tSock != NULL; tSock = Network->PrevSocket() ) { if( tSock->AcctNo() == 0 ) Network->Disconnect( tSock ); } messageLoop << "CMD: Socket Disconnected(Account 0)."; break; case 'K': { for( tSock = Network->FirstSocket(); !Network->FinishedSockets(); tSock = Network->NextSocket() ) { Network->Disconnect( tSock ); } messageLoop << "CMD: All Connections Closed."; } break; case 'P': { UI32 networkTimeCount = cwmWorldState->ServerProfile()->NetworkTimeCount(); UI32 timerTimeCount = cwmWorldState->ServerProfile()->TimerTimeCount(); UI32 autoTimeCount = cwmWorldState->ServerProfile()->AutoTimeCount(); UI32 loopTimeCount = cwmWorldState->ServerProfile()->LoopTimeCount(); // 1/13/2003 - Dreoth - Log Performance Information enhancements LogEcho( true ); Log( "--- Starting Performance Dump ---", "performance.log"); Log( "\tPerformace Dump:", "performance.log"); Log( "\tNetwork code: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->NetworkTime()/(R32)networkTimeCount), networkTimeCount); Log( "\tTimer code: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->TimerTime()/(R32)timerTimeCount), timerTimeCount); Log( "\tAuto code: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->AutoTime()/(R32)autoTimeCount), autoTimeCount); Log( "\tLoop Time: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->LoopTime()/(R32)loopTimeCount), loopTimeCount); ObjectFactory *ourFac = ObjectFactory::getSingletonPtr(); Log( "\tCharacters: %i/%i - Items: %i/%i (Dynamic)", "performance.log", ourFac->CountOfObjects( OT_CHAR ), ourFac->SizeOfObjects( OT_CHAR ), ourFac->CountOfObjects( OT_ITEM ), ourFac->SizeOfObjects( OT_ITEM ) ); Log( "\tSimulation Cycles: %f per sec", "performance.log", (1000.0*(1.0/(R32)((R32)cwmWorldState->ServerProfile()->LoopTime()/(R32)loopTimeCount)))); Log( "\tBytes sent: %i", "performance.log", cwmWorldState->ServerProfile()->GlobalSent()); Log( "\tBytes Received: %i", "performance.log", cwmWorldState->ServerProfile()->GlobalReceived()); Log( "--- Performance Dump Complete ---", "performance.log"); LogEcho( false ); break; } case 'W': // Display logged in chars messageLoop << "CMD: Current Users in the World:"; j = 0; CSocket *iSock; Network->PushConn(); for( iSock = Network->FirstSocket(); !Network->FinishedSockets(); iSock = Network->NextSocket() ) { ++j; CChar *mChar = iSock->CurrcharObj(); sprintf( temp, " %i) %s [%x %x %x %x]", j - 1, mChar->GetName().c_str(), mChar->GetSerial( 1 ), mChar->GetSerial( 2 ), mChar->GetSerial( 3 ), mChar->GetSerial( 4 ) ); messageLoop << temp; } Network->PopConn(); sprintf( temp, " Total users online: %i", j ); messageLoop << temp; break; case 'M': size_t tmp, total; total = 0; tmp = 0; messageLoop << "CMD: UOX Memory Information:"; messageLoop << " Cache:"; sprintf( temp, " Tiles: %u bytes", Map->GetTileMem() ); messageLoop << temp; sprintf( temp, " Multis: %u bytes", Map->GetMultisMem() ); messageLoop << temp; size_t m, n; m = ObjectFactory::getSingleton().SizeOfObjects( OT_CHAR ); total += tmp = m + m*sizeof( CTEffect ) + m*sizeof(char) + m*sizeof(int)*5; sprintf( temp, " Characters: %u bytes [%u chars ( %u allocated )]", tmp, ObjectFactory::getSingleton().CountOfObjects( OT_CHAR ), m ); messageLoop << temp; n = ObjectFactory::getSingleton().SizeOfObjects( OT_ITEM ); total += tmp = n + n * sizeof( int ) * 4; sprintf( temp, " Items: %u bytes [%u items ( %u allocated )]", tmp, ObjectFactory::getSingleton().CountOfObjects( OT_ITEM ), n ); messageLoop << temp; sprintf( temp, " You save I: %i & C: %i bytes!", m * sizeof(CItem) - ObjectFactory::getSingleton().CountOfObjects( OT_ITEM ), m * sizeof( CChar ) - ObjectFactory::getSingleton().CountOfObjects( OT_CHAR ) ); total += tmp = 69 * sizeof( SpellInfo ); sprintf( temp, " Spells: %i bytes", tmp ); messageLoop << " Sizes:"; sprintf( temp, " CItem : %i bytes", sizeof( CItem ) ); messageLoop << temp; sprintf( temp, " CChar : %i bytes", sizeof( CChar ) ); messageLoop << temp; sprintf( temp, " TEffect: %i bytes (%i total)", sizeof( CTEffect ), sizeof( CTEffect ) * cwmWorldState->tempEffects.Num() ); messageLoop << temp; total += tmp = Map->GetTileMem() + Map->GetMultisMem(); sprintf( temp, " Approximate Total: %i bytes", total ); messageLoop << temp; break; case '?': messageLoop << MSG_SECTIONBEGIN; messageLoop << "Console commands:"; messageLoop << MSG_SECTIONBEGIN; messageLoop << " ShardOP:"; messageLoop << " * - Lock/Unlock Console ? - Commands list(this)"; messageLoop << " C - Configuration H - Unused"; messageLoop << " Y - Console Broadcast Q - Quit/Exit "; messageLoop << " Load Commands:"; messageLoop << " 1 - Ini 2 - Accounts"; messageLoop << " 3 - Regions 4 - Spawn Regions"; messageLoop << " 5 - Spells 6 - Commands"; messageLoop << " 7 - Dfn's 8 - JavaScript"; messageLoop << " 9 - HTML Templates 0 - ALL(1-9)"; messageLoop << " Save Commands:"; messageLoop << " ! - Accounts @ - World(w/AccountImport)"; messageLoop << " # - Unused $ - Unused"; messageLoop << " % - Unused ^ - Unused"; messageLoop << " & - Unused ( - Unused"; messageLoop << " ) - Unused"; messageLoop << " Server Maintenence:"; messageLoop << " P - Performance W - Characters Online"; messageLoop << " M - Memory Information T - 10 Minute Shutdown"; messageLoop << " V - Dump Lookups(Devs) F - Display Priority Maps"; messageLoop << " Network Maintenence:"; messageLoop << " D - Disconnect Acct0 K - Disconnect All"; messageLoop << " Z - Socket Logging "; messageLoop << MSG_SECTIONBEGIN; break; case 'v': case 'V': // Dump look up data to files so developers working with extending the ini will have a table to use messageLoop << "| CMD: Creating Server.scp and Uox3.ini Tag Lookup files(For Developers)...."; cwmWorldState->ServerData()->dumpLookup( 0 ); cwmWorldState->ServerData()->save( "./uox.tst.ini" ); messageLoop << MSG_PRINTDONE; break; case 'z': case 'Z': { // Log socket activity Network->PushConn(); bool loggingEnabled = false; CSocket *snSock = Network->FirstSocket(); if( snSock != NULL ) loggingEnabled = !snSock->Logging(); for( ; !Network->FinishedSockets(); snSock = Network->NextSocket() ) { if( snSock != NULL ) snSock->Logging( !snSock->Logging() ); } Network->PopConn(); if( loggingEnabled ) messageLoop << "CMD: Network Logging Enabled."; else messageLoop << "CMD: Network Logging Disabled."; break; } case 'c': case 'C': // Shows a configuration header DisplaySettings(); break; case 'f': case 'F': FileLookup->DisplayPriorityMap(); break; default: sprintf( temp, "Key \'%c\' [%i] does not perform a function", (char)c, c ); messageLoop << temp; break; } } }