void cWeight::NewCalc(P_CHAR pc) { float totalweight=0.0; //get weight for items on players unsigned int ci = 0; P_ITEM pi; vector<SERIAL> vecContainer = contsp.getData(pc->serial); for ( ci = 0; ci < vecContainer.size(); ci++) { pi = FindItemBySerial(vecContainer[ci]); if (pi == NULL || (pi != NULL && pi->id() == 0x1E5E)) // trade window ? continue; if ((pi->layer()!=0x0B) && (pi->layer()!=0x10) && //no weight for hair/beard (pi->layer()!=0x1D) && (pi->layer()!=0x19)) //no weight for steed/bank box { totalweight+=(pi->getWeight()/100.0f); } } // Items in players pack P_ITEM pBackpack = Packitem(pc); if (pBackpack != NULL) totalweight += RecursePacks(pBackpack); //LB pc->weight = (int)totalweight; return; }
////////////////// // name: RecursePacks // Purpose: recurses through the container given by bp to calculate the total weight // History: Ison 2-20-99 - rewrote by Tauriel 3/20/99 // rewritten by Duke 4.11.2k // float cWeight::RecursePacks(P_ITEM bp) { float totalweight=0.0; if (bp == NULL) return 0.0f; unsigned int ci = 0; vector<SERIAL> vecContainer = contsp.getData(bp->serial); for ( ci = 0; ci < vecContainer.size(); ci++) { P_ITEM pi = FindItemBySerial(vecContainer[ci]); if ( pi == NULL ) // Should never happen, but... { contsp.remove( bp->serial, vecContainer[ci]); // Remove the invalid Entrie. continue; // let's pick up next. } int itemsweight=pi->getWeight(); if( pi->type() == 1 ) //item is another container { totalweight += (itemsweight/100.0f); // the weight of container itself totalweight += RecursePacks(pi); //find the item's weight within this container } if (pi->id() == 0x0EED) totalweight += ( pi->amount() * SrvParams->goldWeight() ); else totalweight += (float)((itemsweight * pi->amount())/100.0f); } return totalweight; }
////////////////// // name: RecursePacks // Purpose: recurses through the container given by bp to calculate the total weight // History: Ison 2-20-99 - rewrote by Tauriel 3/20/99 // rewritten by Duke 4.11.2k // float cWeight::RecursePacks(P_ITEM bp) { float totalweight=0.0; if (bp == NULL) return 0.0f; unsigned int ci = 0; vector<SERIAL> vecContainer = contsp.getData(bp->serial); for ( ci = 0; ci < vecContainer.size(); ci++) { P_ITEM pi = FindItemBySerial(vecContainer[ci]); int itemsweight=pi->getWeight(); if (pi->type==1) //item is another container { totalweight += (itemsweight/100.0f); // the weight of container itself totalweight += RecursePacks(pi); //find the item's weight within this container } if (pi->id() == 0x0EED) totalweight += (pi->amount*SrvParms->goldweight); else totalweight += (float)((itemsweight*pi->amount)/100.0f); } return totalweight; }
// history: added containersearch Duke, 4.11.2k float cWeight::LockeddownWeight(P_ITEM pItem, int *total, int *total2 ) { float totalweight=0.0; if (!pItem) { *total=0; return 0.0; } unsigned int ci = 0; P_ITEM pi; vector<SERIAL> vecContainer = contsp.getData(pItem->serial); for ( ci = 0; ci < vecContainer.size(); ci++) { pi = FindItemBySerial(vecContainer[ci]); int itemsweight=pi->getWeight(); total2=total2+pi->amount(); *total=*total+1; if( pi->type() == 1 || pi->type() == 63 || pi->type() == 65 || pi->type() == 87) //item is another container { totalweight+=(itemsweight/100.0f); //(pi->weight/100); totalweight+=LockeddownWeight(pi, total, total2); //find the item's weight within this container } if ( pi->id() == 0x0EED ) totalweight+=(pi->amount()*SrvParams->goldWeight()); else totalweight+=(float)((itemsweight*pi->amount())/100.0f); //((pi->weight*pi->amount)/100); // Ison 2-21-99 } if (*total==0) { *total=pItem->amount(); *total=*total*-1; // Indicate that not a pack ! on osi servers in that case weigt/items count isnt shown // thus i set it negative, if you want to show it anyway, add something like if (weight<0) weight*=-1; return ((((float)pItem->getWeight())/100)*pItem->amount()); // if no pack return single item weight*/ } else return totalweight; }
void cDragItems::dropOnGround( P_CLIENT client, P_ITEM pItem, const Coord_cl &pos ) { P_CHAR pChar = client->player(); // Check if the destination is in line of sight if( !line_of_sight( client->socket(), pChar->pos, pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) ) { client->sysMessage( "You cannot see the target." ); bounceItem( client, pItem ); return; } if( !pChar->canPickUp( pItem ) ) { bounceItem( client, pItem ); return; } pItem->setContSerial( INVALID_SERIAL ); pItem->moveTo( pos ); pItem->setLayer( 0 ); RefreshItem( pItem ); // Send it to all clients in range pChar->weight -= pItem->getWeight(); statwindow( client->socket(), pChar ); // Update our weight-stats if( pItem->glow != INVALID_SERIAL ) { pChar->removeHalo( pItem ); pChar->glowHalo( pItem ); } // Multi handling (Hm i don't like that...) if( pChar->multis > 0 ) { P_ITEM pMulti = FindItemBySerial( pChar->multis ); if( pMulti != NULL ) { pMulti = findmulti( pItem->pos ); if( pItem != NULL ) pItem->SetMultiSerial( pMulti->serial ); } } }
// New Class implementation void cDragItems::grabItem( P_CLIENT client ) { // Get our character P_CHAR pChar = client->player(); if( pChar == NULL ) return; // Fetch the grab information SERIAL iSerial = LongFromCharPtr( &buffer[ client->socket() ][ 1 ] ); UI16 amount = ShortFromCharPtr( &buffer[ client->socket() ][ 5 ] ); P_ITEM pItem = FindItemBySerial( iSerial ); if( !pItem ) return; // Are we already dragging an item ? // Bounce it and reject the move // (Logged out while dragging an item) if( client->dragging() ) { bounceItem( client, client->dragging() ); bounceItem( client, pItem, true ); return; } // Do we really want to let him break his meditation // When he picks up an item ? // Maybe a meditation check here ?!? pChar->disturbMed( client->socket() ); // Meditation P_CHAR itemOwner = GetPackOwner( pItem, 64 ); // Try to pick something out of another characters posessions if( itemOwner && ( itemOwner != pChar ) && ( !pChar->Owns( itemOwner ) ) ) { client->sysMessage( QString( "You have to steal the %1 out of %2's posessions." ).arg( pItem->getName() ).arg( itemOwner->name.c_str() ) ); bounceItem( client, pItem, true ); return; } // Check if the user can grab the item if( !pChar->canPickUp( pItem ) ) { client->sysMessage( "You cannot pick that up." ); bounceItem( client, pItem, true ); return; } // The user can't see the item // Basically thats impossible as the client should deny moving the item // if it's not in line of sight but to prevent exploits if( !line_of_sight( client->socket(), pChar->pos, pItem->pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) ) { client->sysMessage( "You can't see the item." ); bounceItem( client, pItem, true ); return; } P_ITEM outmostCont = GetOutmostCont( pItem, 64 ); // If it's a trade-window, reset the ack-status if( outmostCont && ( outmostCont->contserial == pChar->serial ) && ( outmostCont->layer() == 0 ) && ( outmostCont->id() == 0x1E5E ) ) { // Get the other sides tradewindow P_ITEM tradeWindow = FindItemBySerial( calcserial( outmostCont->moreb1(), outmostCont->moreb2(), outmostCont->moreb3(), outmostCont->moreb4() ) ); // If one of the trade-windows has the ack-status reset it if( tradeWindow && ( tradeWindow->morez || outmostCont->morez ) ) { tradeWindow->morez = 0; outmostCont->morez = 0; sendtradestatus( tradeWindow, outmostCont ); } } // If the top-most container ( thats important ) is a corpse // and looting is a crime, flag the character criminal. if( outmostCont && outmostCont->corpse() ) { // For each item we take out we loose carma // if the corpse is innocent and not in our guild bool sameGuild = ( GuildCompare( pChar, FindCharBySerial( outmostCont->ownserial ) ) != 0 ); if( ( outmostCont->more2 == 1 ) && !pChar->Owns( outmostCont ) && !sameGuild ) { pChar->karma -= 5; criminal( pChar ); client->sysMessage( "You lost some karma." ); } } // Check if the item is too heavy //if( !pc_currchar->isGMorCounselor() ) //{ //} << Deactivated (DarkStorm) // ==== Grabbing the Item is allowed here ==== // Remove eventual item-bonusses if we're unequipping something if( pItem->layer() > 0 ) { P_CHAR wearer = FindCharBySerial( pItem->contserial ); if( wearer ) wearer->removeItemBonus( pItem ); } // Send the user a pickup sound if we're picking it up // From a container/paperdoll if( !pItem->isInWorld() ) soundeffect( client->socket(), 0x00, 0x57 ); // If we're picking up a specific amount of what we got // Take that into account if( pItem->amount() > 1 ) { UI32 pickedAmount = min( amount, pItem->amount() ); // We only have to split if we're not taking it all if( pickedAmount != pItem->amount() ) { P_ITEM splitItem = new cItem( *pItem ); // Create a new item to pick that up splitItem->SetSerial( cItemsManager::getInstance()->getUnusedSerial() ); splitItem->setAmount( pItem->amount() - pickedAmount ); splitItem->setContSerial( pItem->contserial ); splitItem->SetOwnSerial( pItem->ownserial ); splitItem->SetSpawnSerial( pItem->spawnserial ); // He needs to see the new item RefreshItem( splitItem ); // If we're taking something out of a spawn-region it's spawning "flag" is removed isn't it? pItem->SetSpawnSerial( INVALID_SERIAL ); pItem->setAmount( pickedAmount ); } } pItem->setContSerial( pChar->serial ); pItem->SetMultiSerial( INVALID_SERIAL ); pItem->setLayer( 0x1E ); // It's in the equipment of another character if( itemOwner && ( itemOwner != pChar ) ) { itemOwner->weight -= pItem->getWeight(); statwindow( calcSocketFromChar( itemOwner ), itemOwner ); } // If the item is in the bank or any sell-container it's NOT counted as char-weight bool inBank = ( outmostCont && ( outmostCont->contserial == pChar->serial ) && ( outmostCont->layer() >= 0x1A ) ); // Add the weight if: // - Picked from ground // - Picked out of another character // - Picked out of our bank or any other non-visible container if( ( itemOwner != pChar ) || !inBank ) { pChar->weight += pItem->getWeight(); statwindow( client->socket(), pChar ); } }
void cDragItems::equipItem( P_CLIENT client ) { // Get the packet information SERIAL itemId = LongFromCharPtr( &buffer[ client->socket() ][ 1 ] ); SERIAL playerId = LongFromCharPtr( &buffer[ client->socket() ][ 6 ] ); P_ITEM pItem = FindItemBySerial( itemId ); P_CHAR pWearer = FindCharBySerial( playerId ); if( !pItem || !pWearer ) return; P_CHAR pChar = client->player(); // We're dead and can't do that if( pChar->dead ) { client->sysMessage( "You are dead and can't do that." ); bounceItem( client, pItem ); return; } // Our target is dead if( ( pWearer != pChar ) && pWearer->dead ) { client->sysMessage( "You can't equip dead players." ); bounceItem( client, pItem ); return; } // Get our tile-information tile_st pTile; Map->SeekTile( pItem->id(), &pTile ); // Is the item wearable ? ( layer == 0 | equip-flag not set ) // Multis are not wearable are they :o) if( pTile.layer == 0 || !( pTile.flag3 & 0x40 ) || pItem->isMulti() ) { client->sysMessage( "This item cannot be equipped." ); bounceItem( client, pItem ); return; } // Required Strength if( pItem->st > pWearer->st ) { if( pWearer == pChar ) client->sysMessage( "You cannot wear that item, you seem not strong enough" ); else client->sysMessage( "This person can't wear that armor, it seems not strong enough" ); bounceItem( client, pItem ); return; } // Required Dexterity if( pItem->dx > pWearer->effDex() ) { if( pWearer == pChar ) client->sysMessage( "You cannot wear that item, you seem not agile enough" ); else client->sysMessage( "This person can't wear that armor, it seems not agile enough" ); bounceItem( client, pItem ); return; } // Required Intelligence if( pItem->in > pWearer->in ) { if( pWearer == pChar ) client->sysMessage( "You cannot wear that item, you seem not smart enough" ); else client->sysMessage( "This person can't wear that armor, it seems not smart enough" ); bounceItem( client, pItem ); return; } // Males can't wear female armor if( ( pChar->id() == 0x0190 ) && ( pItem->id() >= 0x1C00 ) && ( pItem->id() <= 0x1C0D ) ) { client->sysMessage( "You cannot wear female armor." ); bounceItem( client, pItem ); return; } // Needs a check (!) // Checks for equipment on the same layer // If there is any it tries to unequip it // If that fails it cancels UI08 layer = pItem->layer(); vector< SERIAL > equipment = contsp.getData( pWearer->serial ); for( UI32 i = 0; i < equipment.size(); i++ ) { P_ITEM pEquip = FindItemBySerial( equipment[ i ] ); if( pEquip ) continue; // We found an item which is on the same layer (!) // Unequip it if we can bool twoHanded = false; if( pEquip->twohanded() && ( layer == 1 || layer == 2 ) ) twoHanded = true; if( pItem->twohanded() && ( pEquip->layer() == 1 || pEquip->layer() == 2 ) ) twoHanded = true; if( ( pEquip->layer() == layer ) || twoHanded ) { if( pChar->canPickUp( pEquip ) ) // we're equipping so we do the check pEquip->toBackpack( pWearer ); // If it's still on the char: cancel equipment if( pEquip->contserial == pWearer->serial ) { client->sysMessage( "You already have an item on that layer." ); bounceItem( client, pItem ); return; } } } // At this point we're certain that we can wear the item pItem->setContSerial( playerId ); pItem->setLayer( pTile.layer ); // Don't trust the user input on this one // Handle the weight if the item is leaving our "body" if( pWearer != pChar ) { pChar->weight -= pItem->getWeight(); pWearer->weight += pItem->getWeight(); // Update the status-windows statwindow( client->socket(), pChar ); statwindow( calcSocketFromChar( pWearer ), pWearer ); } if( pTile.layer == 0x19 ) pWearer->setOnHorse( true ); // Apply the bonuses pWearer->st += pItem->st2; pWearer->chgDex( pItem->dx2 ); pWearer->in += pItem->in2; // Show debug information if requested if( showlayer ) clConsole.send( QString( "Item (%1) equipped on layer %2" ).arg( pItem->name() ).arg( pItem->layer() ) ); // I don't think we need to remove the item // as it's only visible to the current char // And he looses contact anyway // SndRemoveitem( pi->serial ); // Build our packets cWornItems wearItem( pWearer->serial, pItem->serial, pItem->layer(), pItem->id(), pItem->color() ); cSoundEffect soundEffect( 0x57, pWearer->pos ); // Send to all sockets in range // ONLY the new equipped item and the sound-effect for( UOXSOCKET s = 0; s < now; s++ ) if( perm[s] && inrange1p( pWearer, currchar[s] ) ) { soundEffect.send( s ); wearItem.send( s ); } // Lord Binaries Glow stuff if( pItem->glow != INVALID_SERIAL ) { pChar->removeHalo( pItem ); pWearer->addHalo( pItem ); pWearer->glowHalo( pItem ); } }