bool CItem::Ship_Plank( bool fOpen ) { // IT_SHIP_PLANK to IT_SHIP_SIDE and IT_SHIP_SIDE_LOCKED // This item is the ships plank. CItemBase * pItemDef = Item_GetDef(); ITEMID_TYPE idState = (ITEMID_TYPE) RES_GET_INDEX( pItemDef->m_ttShipPlank.m_idState ); if ( ! idState ) { // Broken ? return( false ); } if ( IsType(IT_SHIP_PLANK)) { if ( fOpen ) return( true ); } else { DEBUG_CHECK( IsType(IT_SHIP_SIDE) || IsType(IT_SHIP_SIDE_LOCKED)); if ( ! fOpen ) return( true ); } SetID( idState ); Update(); return( true ); }
// Pick cotton/hay/etc... // use the // IT_CROPS = transforms into a "ripe" variety then is used up on reaping. // IT_FOLIAGE = is not consumed on reap (unless eaten then will regrow invis) // bool CItem::Plant_Use(CChar *pChar) { ADDTOCALLSTACK("CItem::Plant_Use"); if ( !pChar ) return false; if ( !pChar->CanSeeItem(this) ) // might be invis underground return false; const CItemBase *pItemDef = Item_GetDef(); ITEMID_TYPE iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttCrops.m_idFruit)); // if it's reapable at this stage if ( iFruitID <= 0 ) { // not ripe. (but we could just eat it if we are herbivorous ?) pChar->SysMessageDefault(DEFMSG_CROPS_NOT_RIPE); return true; } if ( m_itCrop.m_ReapFruitID ) iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(m_itCrop.m_ReapFruitID)); if ( iFruitID ) { CItem *pItemFruit = CItem::CreateScript(iFruitID, pChar); if ( pItemFruit ) pChar->ItemBounce(pItemFruit); } else pChar->SysMessageDefault(DEFMSG_CROPS_NO_FRUIT); Plant_CropReset(); pChar->UpdateAnimate(ANIM_BOW); pChar->Sound(0x13e); return true; }
LONG CItemVendable::GetVendorPrice( int iConvertFactor ) { ADDTOCALLSTACK("CItemVendable::GetVendorPrice"); // Player is buying/selling from a vendor. // ASSUME this item is on the vendor ! // Consider: (if not on a player vendor) // Quality of the item. // rareity of the item. // ARGS: // iConvertFactor will consider: // Vendors Karma. // Players Karma // -100 = reduce price by 100% (player selling to vendor?) // 0 = base price // +100 = increase price by 100% (vendor selling to player?) INT64 lPrice = m_price; if ( lPrice <= 0 ) // set on player vendor. { if ( lPrice == 0 ) // set a new randomized price for the item { CItemBase * pItemDef; if ( IsType( IT_DEED )) { // Deeds just represent the item they are deeding. pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(m_itDeed.m_Type))); if ( pItemDef == NULL ) return( 1 ); } else { pItemDef = Item_GetDef(); } lPrice = pItemDef->GetMakeValue(GetQuality()); m_price = static_cast<long>(-lPrice); } else { lPrice = -lPrice; } } lPrice += IMULDIV( lPrice, maximum(iConvertFactor, -100), 100 ); if (lPrice > LONG_MAX) return LONG_MAX; else if (lPrice <= 0) return 0; return static_cast<long>(lPrice); }
bool CItem::Plant_Use( CChar * pChar ) { ADDTOCALLSTACK("CItem::Plant_Use"); // Pick cotton/hay/etc... // use the // IT_CROPS = transforms into a "ripe" variety then is used up on reaping. // IT_FOLIAGE = is not consumed on reap (unless eaten then will regrow invis) // if ( !pChar ) return false; if ( ! pChar->CanSeeItem(this)) // might be invis underground. return( false ); const CItemBase * pItemDef = Item_GetDef(); ITEMID_TYPE iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttCrops.m_idFruit)); // if it's reapable at this stage. if ( iFruitID <= 0 ) { // not ripe. (but we could just eat it if we are herbivorous ?) pChar->SysMessage( g_Cfg.GetDefaultMsg( DEFMSG_CROPS_NOT_RIPE ) ); return( true ); } if ( m_itCrop.m_ReapFruitID ) { iFruitID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(m_itCrop.m_ReapFruitID)); } if ( iFruitID > 0 ) { CItem * pItemFruit = CItem::CreateScript( iFruitID , pChar ); if ( pItemFruit) { pChar->ItemBounce( pItemFruit ); } } else { pChar->SysMessage( g_Cfg.GetDefaultMsg( DEFMSG_CROPS_NO_FRUIT ) ); } Plant_CropReset(); pChar->UpdateAnimate( ANIM_BOW ); pChar->Sound( 0x13e ); return true; }
bool CItem::Plant_Use( CChar * pChar ) { // Pick cotton/hay/etc... // use the // IT_CROPS = transforms into a "ripe" variety then is used up on reaping. // IT_FOLIAGE = is not consumed on reap (unless eaten then will regrow invis) // DEBUG_CHECK( IsType(IT_CROPS) || IsType(IT_FOLIAGE)); ASSERT(pChar); if ( ! pChar->CanSeeItem(this)) // might be invis underground. return( false ); CItemBase * pItemDef = Item_GetDef(); ITEMID_TYPE iFruitID = (ITEMID_TYPE) RES_GET_INDEX( pItemDef->m_ttCrops.m_idFruit ); // if it's reapable at this stage. if ( iFruitID <= 0 ) { // not ripe. (but we could just eat it if we are herbivorous ?) pChar->SysMessage( "None of the crops are ripe enough." ); return( true ); } if ( m_itCrop.m_ReapFruitID ) { iFruitID = (ITEMID_TYPE) RES_GET_INDEX( m_itCrop.m_ReapFruitID ); } if ( iFruitID > 0 ) { CItem * pItemFruit = CItem::CreateScript( iFruitID , pChar ); if ( pItemFruit) { pChar->ItemBounce( pItemFruit ); } } else { pChar->SysMessage( "The plant yields nothing useful" ); } Plant_CropReset(); pChar->UpdateAnimate( ANIM_BOW ); pChar->Sound( 0x13e ); return true; }
// Animals will eat crops before they are ripe, so we need a way to reset them prematurely void CItem::Plant_CropReset() { ADDTOCALLSTACK("CItem::Plant_CropReset"); if ( !IsType(IT_CROPS) && !IsType(IT_FOLIAGE) ) { // This isn't a crop, and since it just got eaten, we should delete it Delete(); return; } const CItemBase *pItemDef = Item_GetDef(); ITEMID_TYPE iResetID = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttCrops.m_idReset)); if ( iResetID != ITEMID_NOTHING ) SetID(iResetID); Plant_SetTimer(); RemoveFromView(); // remove from most screens. SetHue(HUE_RED_DARK); // Indicate to GM's that it is growing. SetAttr(ATTR_INVIS); // regrown invis. }
bool CItemVendable::IsValidNPCSaleItem() const { ADDTOCALLSTACK("CItemVendable::IsValidNPCSaleItem"); // This item is in an NPC's vendor box. // Is it a valid item that NPC's should be selling ? CItemBase * pItemDef = Item_GetDef(); if ( m_price <= 0 && pItemDef->GetMakeValue(0) <= 0 ) { DEBUG_ERR(( "Vendor uid=0%lx selling unpriced item %s='%s'\n", static_cast<DWORD>(GetTopLevelObj()->GetUID()), GetResourceName(), GetName())); return( false ); } if ( ! IsValidSaleItem( true )) { DEBUG_ERR(( "Vendor uid=0%lx selling bad item %s='%s'\n", static_cast<DWORD>(GetTopLevelObj()->GetUID()), GetResourceName(), GetName())); return( false ); } return( true ); }
void CItem::Plant_CropReset() { // Animals will eat crops before they are ripe, so we need a way to reset them prematurely if ( ! IsType(IT_CROPS) && ! IsType(IT_FOLIAGE)) { // This isn't a crop, and since it just got eaten, we should delete it Delete(); return; } CItemBase * pItemDef = Item_GetDef(); ITEMID_TYPE iResetID = (ITEMID_TYPE) RES_GET_INDEX( pItemDef->m_ttCrops.m_idReset ); if ( iResetID != ITEMID_NOTHING ) { SetID(iResetID); } Plant_SetTimer(); RemoveFromView(); // remove from most screens. SetHue( HUE_RED_DARK ); // Indicate to GM's that it is growing. SetAttr(ATTR_INVIS); // regrown invis. }
// 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; }
CPointMap CItemContainer::GetRandContainerLoc() const { ADDTOCALLSTACK("CItemContainer::GetRandContainerLoc"); // Max/Min Container Sizes. static const struct // we can probably get this from MUL file some place. { GUMP_TYPE m_gump; WORD m_minx; WORD m_miny; WORD m_maxx; WORD m_maxy; } sm_ContSize[] = { { GUMP_RESERVED, 40, 50, 100, 100 }, // default. { GUMP_CORPSE, 20, 85, 80, 185 }, { GUMP_PACK, 44, 65, 142, 150 }, // Open backpack { GUMP_BAG, 29, 34, 93, 119 }, // Leather Bag { GUMP_BARREL, 33, 36, 98, 139 }, // Barrel { GUMP_BASKET_SQ, 19, 47, 138, 114 }, // Square picknick Basket { GUMP_BOX_WOOD, 16, 51, 140, 115 }, // small wood box with a lock { GUMP_BASKET_RO, 33, 36, 98, 134 }, // Round Basket { GUMP_CHEST_GO_SI, 18, 105, 118, 169 }, // Gold and Silver Chest. { GUMP_BOX_WOOD_OR, 16, 51, 140, 115 }, // Small wood box (ornate)(no lock) { GUMP_CRATE, 20, 10, 126, 91 }, // Wood Crate { GUMP_DRAWER_DK, 16, 17, 110, 85 }, { GUMP_CHEST_WO_GO, 18, 105, 118, 169 }, // Wood with gold trim. { GUMP_CHEST_SI, 18, 105, 118, 169 }, // silver chest. { GUMP_BOX_GO_LO, 16, 51, 140, 115 }, // Gold/Brass box with a lock. { GUMP_SHIP_HOLD, 46, 74, 152, 175 }, { GUMP_BOOK_SHELF, 76, 12, 96, 59 }, { GUMP_CABINET_DK, 24, 96, 91, 143 }, { GUMP_CABINET_LT, 24, 96, 91, 143 }, { GUMP_DRAWER_LT, 16, 17, 110, 85 }, { GUMP_GIFT_BOX, 35, 10, 155, 85 }, { GUMP_ARMOIRE_RED, 10, 10, 150, 95 }, { GUMP_ARMOIRE_MAPLE, 10, 10, 150, 95 }, { GUMP_ARMOIRE_CHERRY, 10, 10, 150, 95 }, { GUMP_BASKET_TALL, 10, 10, 116, 71 }, { GUMP_CHEST_WOOD_PLAIN, 10, 10, 150, 95 }, { GUMP_CHEST_WOOD_GILDED, 10, 10, 150, 95 }, { GUMP_CHEST_WOOD_ORNATE, 10, 10, 150, 95 }, { GUMP_TALL_CABINET, 10, 10, 150, 95 }, { GUMP_CHEST_WOOD_FINISH, 10, 10, 150, 95 }, { GUMP_HEART_SHAPED, 56, 30, 102, 74}, { GUMP_SECURE_TRADE, 1, 1, 66, 26 }, { GUMP_GAME_BOARD, 4, 10, 220, 185 }, // Chess or checker board. { GUMP_GAME_BACKGAM, 4, 10, 220, 185 }, }; // ??? pItemDef->m_ttContainer.m_dwMinXY to m_dwMaxXY // Get a random location in the container. CItemBase * pItemDef = Item_GetDef(); GUMP_TYPE gump = pItemDef->IsTypeContainer(); // check for custom values in TDATA3/TDATA4 if ( pItemDef->m_ttContainer.m_dwMaxXY ) { int tmp_MinX = (pItemDef->m_ttContainer.m_dwMinXY & 0xFFFF0000) >> 16; int tmp_MinY = (pItemDef->m_ttContainer.m_dwMinXY & 0xFFFF); int tmp_MaxX = (pItemDef->m_ttContainer.m_dwMaxXY & 0xFFFF0000) >> 16; int tmp_MaxY = (pItemDef->m_ttContainer.m_dwMaxXY & 0xFFFF); DEBUG_WARN(("Custom container gump id %d for 0%x\n", gump, GetDispID())); return( CPointMap( static_cast<WORD>(tmp_MinX + Calc_GetRandVal(tmp_MaxX - tmp_MinX)), static_cast<WORD>(tmp_MinY + Calc_GetRandVal(tmp_MaxY - tmp_MinY)), 0 )); }