bool CItemMulti::Ship_SetMoveDir( DIR_TYPE dir ) { // Set the direction we will move next time we get a tick. int iSpeed = 1; if ( m_itShip.m_DirMove == dir && m_itShip.m_fSail ) { if ( m_itShip.m_DirFace == m_itShip.m_DirMove && m_itShip.m_fSail == 1 ) { iSpeed = 2; } else return( false ); } if ( ! IsAttr(ATTR_MAGIC )) // make sound. { if ( ! Calc_GetRandVal(10)) { Sound( Calc_GetRandVal(2)?0x12:0x13 ); } } m_itShip.m_DirMove = dir; m_itShip.m_fSail = iSpeed; GetTopSector()->SetSectorWakeStatus(); // may get here b4 my client does. SetTimeout(( m_itShip.m_fSail == 1 ) ? 1*TICK_PER_SEC : (TICK_PER_SEC/5)); return( true ); }
bool CItemMulti::Ship_CanMoveTo( const CPointMap & pt ) const { // Can we move to the new location ? all water type ? if ( IsAttr(ATTR_MAGIC )) return( true ); // Run into other ships ? ignore my own region. /* const CRegionBase * pRegionOther = pt.GetRegion( REGION_TYPE_MULTI ); if ( pRegionOther == m_pRegion ) pRegionOther = NULL; */ WORD wBlockFlags = CAN_I_WATER; signed char z = g_World.GetHeightPoint( pt, wBlockFlags, true ); if ( ! ( wBlockFlags & CAN_I_WATER )) { return( false ); } return( true ); }
CCharBase * CItem::Spawn_SetTrackID() { if ( ! IsType(IT_SPAWN_CHAR)) return NULL; CCharBase * pCharDef = NULL; RESOURCE_ID_BASE rid = m_itSpawnChar.m_CharID; if ( rid.GetResType() == RES_CHARDEF ) { CREID_TYPE id = (CREID_TYPE) rid.GetResIndex(); pCharDef = CCharBase::FindCharBase( id ); } if ( pCharDef ) SetAttr( ATTR_INVIS ); if ( IsAttr(ATTR_INVIS)) // They must want it to look like this. { SetDispID( ( pCharDef == NULL ) ? ITEMID_TRACK_WISP : pCharDef->m_trackID ); if ( GetHue() == 0 ) SetHue( HUE_RED_DARK ); // Indicate to GM's that it is invis. } return( pCharDef ); }
bool CItemVendable::IsValidSaleItem( bool fBuyFromVendor ) const { ADDTOCALLSTACK("CItemVendable::IsValidSaleItem"); // Can this individual item be sold or bought ? if ( ! IsMovableType()) { if ( fBuyFromVendor ) { DEBUG_ERR(( "Vendor uid=0%lx selling unmovable item %s='%s'\n", static_cast<DWORD>(GetTopLevelObj()->GetUID()), GetResourceName(), GetName())); } return( false ); } if ( ! fBuyFromVendor ) { // cannot sell these to a vendor. if ( IsAttr(ATTR_NEWBIE|ATTR_MOVE_NEVER)) return( false ); // spellbooks ! } if ( IsType(IT_COIN)) return( false ); return( true ); }
bool CItemMulti::r_Verb( CScript & s, CTextConsole * pSrc ) // Execute command from script { LOCKDATA; EXC_TRY(("r_Verb('%s %s',%x)", s.GetKey(), s.GetArgStr(), pSrc)); // Speaking in this ships region. // return: true = command for the ship. //"One (direction*)", " (Direction*), one" Moves ship one tile in desired direction and stops. //"Slow (direction*)" Moves ship slowly in desired direction (see below for possible directions). int iCmd = FindTableSorted( s.GetKey(), sm_szVerbKeys, COUNTOF( sm_szVerbKeys )-1 ); if ( iCmd < 0 ) { return( CItem::r_Verb( s, pSrc )); } if ( ! pSrc ) return( false ); switch ( iCmd ) { case SHV_MULTICREATE: { CGrayUID uid( s.GetArgVal() ); CChar * pSrc = uid.CharFind(); Multi_Create( pSrc, 0 ); } return true; } if ( IsAttr(ATTR_MOVE_NEVER) || ! IsTopLevel() ) return false; CChar * pChar = pSrc->GetChar(); // Only key holders can command the ship ??? // if ( pChar && pChar->ContentFindKeyFor( pItem )) // Find the tiller man object. CItem * pTiller = Multi_GetSign(); ASSERT( pTiller ); // Get current facing dir. DIR_TYPE DirFace = sm_Ship_FaceDir[ Ship_GetFaceOffset() ]; int DirMoveChange; LPCTSTR pszSpeak = NULL; switch ( iCmd ) { case SHV_SHIPSTOP: // "Furl sail" // "Stop" Stops current ship movement. if ( ! m_itShip.m_fSail ) return( false ); Ship_Stop(); break; case SHV_SHIPFACE: // Face this direction. do not change the direction of movement. if ( ! s.HasArgs()) return( false ); return Ship_Face( GetDirStr( s.GetArgStr())); case SHV_SHIPMOVE: // Move one space in this direction. // Does NOT protect against exploits ! if ( ! s.HasArgs()) return( false ); m_itShip.m_DirMove = GetDirStr( s.GetArgStr()); return Ship_Move( (DIR_TYPE) m_itShip.m_DirMove ); case SHV_SHIPGATE: // Move the whole ship and contents to another place. if ( ! s.HasArgs()) return( false ); { CPointMap ptdelta = g_Cfg.GetRegionPoint( s.GetArgStr()); if ( ! ptdelta.IsValidPoint()) return( false ); ptdelta -= GetTopPoint(); return Ship_MoveDelta( ptdelta ); } break; case SHV_SHIPTURNLEFT: // "Port", // "Turn Left", DirMoveChange = -2; doturn: if ( m_itShip.m_fAnchored ) { anchored: pszSpeak = "The anchor is down <SEX Sir/Mam>!"; break; } m_itShip.m_DirMove = GetDirTurn( DirFace, DirMoveChange ); Ship_Face( (DIR_TYPE) m_itShip.m_DirMove ); break; case SHV_SHIPTURNRIGHT: // "Turn Right", // "Starboard", // Turn Right DirMoveChange = 2; goto doturn; case SHV_SHIPDRIFTLEFT: // "Left", // "Drift Left", DirMoveChange = -2; dodirmovechange: if ( m_itShip.m_fAnchored ) goto anchored; if ( ! Ship_SetMoveDir( GetDirTurn( DirFace, DirMoveChange ))) return( false ); break; case SHV_SHIPDRIFTRIGHT: // "Right", // "Drift Right", DirMoveChange = 2; goto dodirmovechange; case SHV_SHIPBACK: // "Back", // Move ship backwards // "Backward", // Move ship backwards // "Backwards", // Move ship backwards DirMoveChange = 4; goto dodirmovechange; case SHV_SHIPFORE: // "Forward" // "Foreward", // Moves ship forward. // "Unfurl sail", // Moves ship forward. DirMoveChange = 0; goto dodirmovechange; case SHV_SHIPFORELEFT: // "Forward left", DirMoveChange = -1; goto dodirmovechange; case SHV_SHIPFORERIGHT: // "forward right", DirMoveChange = 1; goto dodirmovechange; case SHV_SHIPBACKLEFT: // "backward left", // "back left", DirMoveChange = -3; goto dodirmovechange; case SHV_SHIPBACKRIGHT: // "backward right", // "back right", DirMoveChange = 3; goto dodirmovechange; case SHV_SHIPANCHORRAISE: // "Raise Anchor", if ( ! m_itShip.m_fAnchored ) { pszSpeak = "The anchor is already up <SEX Sir/Mam>"; break; } m_itShip.m_fAnchored = false; break; case SHV_SHIPANCHORDROP: // "Drop Anchor", if ( m_itShip.m_fAnchored ) { pszSpeak = "The anchor is already down <SEX Sir/Mam>"; break; } m_itShip.m_fAnchored = true; Ship_Stop(); break; case SHV_SHIPTURN: // "Turn around", // Turns ship around and proceeds. // "Come about", // Turns ship around and proceeds. DirMoveChange = 4; goto doturn; case SHV_SHIPUP: // "Up" { if ( ! IsAttr(ATTR_MAGIC )) return( false ); CPointMap pt; pt.m_z = PLAYER_HEIGHT; if ( Ship_MoveDelta( pt )) { pszSpeak = "As you command <SEX Sir/Mam>"; } else { pszSpeak = "Can't do that <SEX Sir/Mam>"; } } break; case SHV_SHIPDOWN: // "Down" { if ( ! IsAttr(ATTR_MAGIC )) return( false ); CPointMap pt; pt.m_z = -PLAYER_HEIGHT; if ( Ship_MoveDelta( pt )) { pszSpeak = "As you command <SEX Sir/Mam>"; } else { pszSpeak = "Can't do that <SEX Sir/Mam>"; } } break; case SHV_SHIPLAND: // "Land" { if ( ! IsAttr(ATTR_MAGIC )) return( false ); signed char zold = GetTopZ(); CPointMap pt = GetTopPoint(); pt.m_z = zold; SetTopZ( -UO_SIZE_Z ); // bottom of the world where i won't get in the way. WORD wBlockFlags = CAN_I_WATER; signed char z = g_World.GetHeightPoint( pt, wBlockFlags ); SetTopZ( zold ); // restore z for now. pt.InitPoint(); pt.m_z = z - zold; if ( pt.m_z ) { Ship_MoveDelta( pt ); pszSpeak = "As you command <SEX Sir/Mam>"; } else { pszSpeak = "We have landed <SEX Sir/Mam>"; } } break; default: return( false ); } if ( pChar ) { if ( pszSpeak == NULL ) { static LPCTSTR const sm_pszAye[] = { "Aye", "Aye Cap'n", "Aye <SEX Sir/Mam>", }; pszSpeak = sm_pszAye[ Calc_GetRandVal( COUNTOF( sm_pszAye )) ]; } TCHAR szText[ MAX_TALK_BUFFER ]; strcpy( szText, pszSpeak ); pChar->ParseText( szText, &g_Serv ); pTiller->Speak( szText, 0, TALKMODE_SAY, FONT_NORMAL ); } return false; EXC_CATCH("CItemMulti"); return true; }
void CItemMulti::Multi_Create( CChar * pChar, DWORD dwKeyCode ) { // Create house or Ship extra stuff. // ARGS: // dwKeyCode = set the key code for the doors/sides to this in case it's a drydocked ship. // NOTE: // This can only be done after the house is given location. const CItemBaseMulti * pMultiDef = Multi_GetDef(); // We are top level. if ( pMultiDef == NULL || ! IsTopLevel()) return; if ( dwKeyCode == UID_CLEAR ) dwKeyCode = GetUID(); // ??? SetTimeout( GetDecayTime()); house decay ? bool fNeedKey = false; int iQty = pMultiDef->m_Components.GetCount(); for ( int i=0; i<iQty; i++ ) { fNeedKey |= Multi_CreateComponent( (ITEMID_TYPE) pMultiDef->m_Components[i].m_id, pMultiDef->m_Components[i].m_dx, pMultiDef->m_Components[i].m_dy, pMultiDef->m_Components[i].m_dz, dwKeyCode ); } #if 0 const CGrayMulti * pMultiMul = g_World.GetMultiItemDefs( GetDispID()); if ( pMultiMul ) { iQty = pMultiMul->GetItemCount(); for ( int i=0; iQty--; i++ ) { const CUOMultiItemRec * pMultiItem = pMultiMul->GetItem(i); ASSERT(pMultiItem); if ( pMultiItem->m_visible ) // client side. continue; fNeedKey |= Multi_CreateComponent( pMultiItem->GetDispID(), pMultiItem->m_dx, pMultiItem->m_dy, pMultiItem->m_dz, dwKeyCode ); } } #endif CItem * pKey = NULL; if ( fNeedKey ) { // Create the key to the door. ITEMID_TYPE id = IsAttr(ATTR_MAGIC) ? ITEMID_KEY_MAGIC : ITEMID_KEY_COPPER ; pKey = CreateScript( id, pChar ); ASSERT(pKey); pKey->SetType(IT_KEY); if ( g_Cfg.m_fAutoNewbieKeys ) pKey->SetAttr(ATTR_NEWBIE); pKey->SetAttr(m_Attr&ATTR_MAGIC); pKey->m_itKey.m_lockUID.SetPrivateUID( dwKeyCode ); pKey->m_uidLink = GetUID(); } Multi_GetSign(); // set the m_uidLink if ( pChar != NULL ) { m_itShip.m_UIDCreator = pChar->GetUID(); CItemMemory * pMemory = pChar->Memory_AddObjTypes( this, MEMORY_GUARD ); if ( pKey ) { // Put in your pack pChar->GetPackSafe()->ContentAdd( pKey ); // Put dupe key in the bank. pKey = CreateDupeItem( pKey ); pChar->GetBank()->ContentAdd( pKey ); pChar->SysMessage( "The duplicate key is in your bank account" ); } } else { // Just put the key on the front step ? DEBUG_CHECK( 0 ); } }
// timer expired, should I grow? bool CItem::Plant_OnTick() { ADDTOCALLSTACK("CItem::Plant_OnTick"); ASSERT(IsType(IT_CROPS) || IsType(IT_FOLIAGE)); // If it is in a container, kill it. if ( !IsTopLevel() ) return false; // Make sure the darn thing isn't moveable SetAttr(ATTR_MOVE_NEVER); Plant_SetTimer(); // No tree stuff below here if ( IsAttr(ATTR_INVIS) ) // if it's invis, take care of it here and return { SetHue(HUE_DEFAULT); ClrAttr(ATTR_INVIS); Update(); return true; } const CItemBase *pItemDef = Item_GetDef(); ITEMID_TYPE iGrowID = pItemDef->m_ttCrops.m_idGrow; if ( iGrowID == -1 ) { // Some plants generate a fruit on the ground when ripe. ITEMID_TYPE iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttCrops.m_idGrow)); if ( m_itCrop.m_ReapFruitID ) iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(m_itCrop.m_ReapFruitID)); if ( !iFruitID ) return true; // Put a fruit on the ground if not already here. CWorldSearch AreaItems(GetTopPoint()); for (;;) { CItem *pItem = AreaItems.GetItem(); if ( !pItem ) { CItem *pItemFruit = CItem::CreateScript(iFruitID); ASSERT(pItemFruit); pItemFruit->MoveToDecay(GetTopPoint(), 10 * g_Cfg.m_iDecay_Item); break; } if ( pItem->IsType(IT_FRUIT) || pItem->IsType(IT_REAGENT_RAW) ) break; } // NOTE: ??? The plant should cycle here as well ! iGrowID = pItemDef->m_ttCrops.m_idReset; } if ( iGrowID ) { SetID(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iGrowID))); Update(); return true; } // some plants go dormant again ? // m_itCrop.m_Fruit_ID = iTemp; return true; }
CStoneMember * CItemStone::AddRecruit(const CChar * pChar, STONEPRIV_TYPE iPriv, bool bFull) { ADDTOCALLSTACK("CItemStone::AddRecruit"); // CLIMODE_TARG_STONE_RECRUIT // Set as member or candidate. if ( !pChar || !pChar->m_pPlayer ) { Speak( "Only players can be members!"); return NULL; } TCHAR * z = Str_GetTemp(); const CItemStone * pStone = pChar->Guild_Find( GetMemoryType()); if ( pStone && pStone != this ) { sprintf(z, "%s appears to belong to %s. Must resign previous %s", static_cast<LPCTSTR>(pChar->GetName()), static_cast<LPCTSTR>(pStone->GetName()), static_cast<LPCTSTR>(GetTypeName())); Speak(z); return NULL; } if ( IsType(IT_STONE_TOWN) && IsAttr(ATTR_OWNED) && iPriv == STONEPRIV_CANDIDATE ) { // instant member. iPriv = STONEPRIV_MEMBER; } CStoneMember * pMember = GetMember(pChar); if ( pMember ) { // I'm already a member of some sort. if ( pMember->GetPriv() == iPriv || iPriv == STONEPRIV_CANDIDATE ) { sprintf(z, "%s is already %s %s.", static_cast<LPCTSTR>(pChar->GetName()), static_cast<LPCTSTR>(pMember->GetPrivName()), static_cast<LPCTSTR>(GetName())); Speak(z); return NULL; } pMember->SetPriv( iPriv ); } else { pMember = new CStoneMember(this, pChar->GetUID(), iPriv); if ( bFull ) // full join means becoming a full member already { pMember->SetPriv(STONEPRIV_MEMBER); pMember->SetAbbrev(true); } } if ( pMember->IsPrivMember()) { pMember->SetLoyalTo(pChar); ElectMaster(); // just in case this is the first. } sprintf(z, "%s is now %s %s", static_cast<LPCTSTR>(pChar->GetName()), static_cast<LPCTSTR>(pMember->GetPrivName()), static_cast<LPCTSTR>(GetName())); Speak(z); return pMember; }