/*! \brief Add item to container \author Endymion \param pItem the item to add \param xx the x location or INVALID if use rand pos \param yy the y location or INVALID if use rand pos */ LOGICAL cItem::AddItem(P_ITEM pItem, short xx, short yy) { VALIDATEPIR(pItem,false); NxwSocketWrapper sw; sw.fillOnline( pItem ); for( sw.rewind(); !sw.isEmpty(); sw++ ) SendDeleteObjectPkt(sw.getSocket(), pItem->getSerial32() ); if (xx!=-1) // use the given position { pItem->setContSerial( getSerial32() ); pItem->setPosition(xx, yy, 9); } else // no pos given { if( !ContainerPileItem(pItem) ) { // try to pile pItem->SetRandPosInCont(this); // not piled, random pos pItem->setContSerial( getSerial32() ); } else return true; //Luxor: we cannot do a refresh because item was piled } pItem->Refresh(); return true; }
// Name: item_bounce3 // Purpose: holds some statements that were COPIED some 50 times // Remarks: temporary functions to revamp the 30 occurences of the 'bouncing bugfix' // History: init Duke, 10.8.2000 / bugfix for bonus stats, Xanathar, 05-aug-2001 static void item_bounce3(const P_ITEM pi) { VALIDATEPI( pi ); pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer=pi->oldlayer; P_CHAR pc = pointers::findCharBySerial( pi->getContSerial(true) ); if(pc==NULL) return ; VALIDATEPC( pc ); if ( pi->layer > 0 ) { // Xanathar -- add BONUS STATS given by equipped special items pc->setStrength( pc->getStrength() + pi->st2, true ); //pc->st += pi->st2; pc->dx += pi->dx2; pc->in += pi->in2; // Xanathar -- for poisoned items if (pi->poisoned) { pc->poison += pi->poisoned; if ( pc->poison < 0) pc->poison = 0; } } }
/*! \brief Get an item \author Unknow, revamped by Endymion \param client the client */ void get_item( NXWCLIENT client ) // Client grabs an item { if ( client == NULL) return; P_CHAR pc_currchar = client->currChar(); VALIDATEPC( pc_currchar ); NXWSOCKET s = client->toInt(); P_ITEM pi = pointers::findItemBySerPtr(buffer[s]+1); VALIDATEPI(pi); //Luxor: not-movable items /*if (pi->magic == 2 || (isCharSerial(pi->getContSerial()) && pi->getContSerial() != pc_currchar->getSerial32()) ) { if (isCharSerial(pi->getContSerial())) { P_CHAR pc_i = pointers::findCharBySerial(pi->getContSerial()); if (ISVALIDPC(pc_i)) pc_i->sysmsg("Warning, backpack bug located!"); } if (client->isDragging()) { client->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; }*/ pc_currchar->disturbMed(); // Meditation tile_st item; data::seekTile( pi->getId(), item ); // Check if item is equiped if( pi->getContSerial() == pc_currchar->getSerial32() && pi->layer == item.quality ) { if( pc_currchar->UnEquip( pi, 1 ) == 1 ) // bypass called { if( client->isDragging() ) { UI08 cmd[1]= {0x29}; client->resetDragging(); Xsend(s, cmd, 1); UpdateStatusWindow(s,pi); //AoS/ Network->FlushBuffer(s); } return; } } P_CHAR owner=NULL; P_ITEM container=NULL; if ( !pi->isInWorld() ) { // Find character owning item if ( isCharSerial( pi->getContSerial())) { owner = pointers::findCharBySerial( pi->getContSerial()); } else // its an item { //Endymion Bugfix: //before check the container.. but if this cont is a subcont? //so get the outmostcont and check it else: //can loot without lose karma in subcont //can steal in trade ecc //not very good :P container = pi->getOutMostCont(); if( isCharSerial( container->getContSerial() ) ) owner=pointers::findCharBySerial( container->getContSerial() ); } if ( ISVALIDPC( owner ) && owner->getSerial32()!=pc_currchar->getSerial32() ) { if ( !pc_currchar->IsGM() && owner->getOwnerSerial32() != pc_currchar->getSerial32() ) {// Own serial stuff by Zippy -^ Pack aniamls and vendors. UI08 bounce[2]= { 0x27, 0x00 }; Xsend(s, bounce, 2); //AoS/ Network->FlushBuffer(s); if (client->isDragging()) { client->resetDragging(); pi->setContSerial(pi->getContSerial(),true,false); item_bounce3(pi); UpdateStatusWindow(s,pi); } return; } } } if ( ISVALIDPI( container ) ) { if ( container->layer == 0 && container->getId() == 0x1E5E) { // Trade window??? SERIAL serial = calcserial( pi->moreb1, pi->moreb2, pi->moreb3, pi->moreb4); if ( serial == INVALID ) return; P_ITEM piz = pointers::findItemBySerial(serial ); if ( ISVALIDPI( piz ) ) if ( piz->morez || container->morez ) { piz->morez = 0; container->morez = 0; sendtradestatus( piz, container ); } //<Luxor> if (pi->amxevents[EVENT_ITAKEFROMCONTAINER]!=NULL) { g_bByPass = false; pi->amxevents[EVENT_ITAKEFROMCONTAINER]->Call( pi->getSerial32(), pi->getContSerial(), pc_currchar->getSerial32() ); if (g_bByPass) { Sndbounce5(s); if (client->isDragging()) { client->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } } //</Luxor> /* //<Luxor> g_bByPass = false; pi->runAmxEvent( EVENT_ITAKEFROMCONTAINER, pi->getSerial32(), pi->getContSerial(), s ); if (g_bByPass) { Sndbounce5(s); if (client->isDragging()) { client->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } //</Luxor> */ if ( container->corpse ) { if ( container->getOwnerSerial32() != pc_currchar->getSerial32()) { //Looter :P pc_currchar->unHide(); bool bCanLoot = false; if( pc_currchar->party!=INVALID ) { P_CHAR dead = pointers::findCharBySerial( container->getOwnerSerial32() ) ; if( ISVALIDPC( dead ) && dead->party==pc_currchar->party ) { P_PARTY party = Partys.getParty( pc_currchar->party ); if( party!=NULL ) { P_PARTY_MEMBER member = party->getMember( pc_currchar->getSerial32() ); if( member!=NULL ) bCanLoot = member->canLoot; } } } if ( !bCanLoot && container->more2==1 ) { pc_currchar->IncreaseKarma(-5); setCrimGrey(pc_currchar, ServerScp::g_nLootingWillCriminal); pc_currchar->sysmsg( TRANSLATE("You are loosing karma!")); } } } // corpse stuff container->SetMultiSerial(INVALID); //at end reset decay of container container->setDecayTime(); } // end cont valid } if ( !pi->corpse ) { UpdateStatusWindow(s, pi); tile_st tile; data::seekTile( pi->getId(), tile); if (!pc_currchar->IsGM() && (( pi->magic == 2 || ((tile.weight == 255) && ( pi->magic != 1))) && !pc_currchar->canAllMove() ) || (( pi->magic == 3|| pi->magic == 4) && !pc_currchar->isOwnerOf( pi ))) { UI08 bounce[2]={ 0x27, 0x00 }; Xsend(s, bounce, 2); //AoS/ Network->FlushBuffer(s); if (client->isDragging()) // only restore item if it got draggged before !!! { client->resetDragging(); item_bounce4(s, pi ); } } // end of can't get else { // AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing ) client->setDragging(); pi->setOldPosition( pi->getPosition() ); // first let's save the position pi->oldlayer = pi->layer; // then the layer pi->layer = 0; if (!pi->isInWorld()) pc_currchar->playSFX(0x0057); if (pi->amount>1) { UI16 amount = ShortFromCharPtr(buffer[s] +5); if (amount > pi->amount) amount = pi->amount; else if (amount < pi->amount) { //get not all but a part of item ( piled? ), but anyway make a new one item P_ITEM pin =archive::item::New(); (*pin)=(*pi); pin->amount = (UI16)( pi->amount - amount); pin->setContSerial(pi->getContSerial()); //Luxor pin->setPosition( pi->getPosition() ); /*if( !pin->isInWorld() && isItemSerial( pin->getContSerial() ) ) pin->SetRandPosInCont( (P_ITEM)pin->getContainer() );*/ if ( pin->getOwnerSerial32() != INVALID ) pin->setOwnerSerial32( pi->getOwnerSerial32() ); statwindow(pc_currchar,pc_currchar); pin->Refresh();//AntiChrist } if ( pi->getId() == ITEMID_GOLD) { P_ITEM pack= pc_currchar->getBackpack(); if (ISVALIDPI(pack)) // lb if ( pi->getContSerial() == pack->getSerial32()) statwindow(pc_currchar, pc_currchar); } pi->amount = amount; } // end if corpse #ifdef SPAR_I_LOCATION_MAP pointers::delFromLocationMap( pi ); #else mapRegions->remove( pi ); #endif pi->setPosition( 0, 0, 0 ); pi->setContSerial( INVALID, false ); } } int amt = 0, wgt; if ( container == NULL ) { wgt = (int)weights::LockeddownWeight( pi, &amt); pc_currchar->weight += wgt; statwindow(pc_currchar, pc_currchar); } }
void pack_item(NXWCLIENT ps, PKGx08 *pp) // Item is put into container { if (ps == NULL) return; char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var char temp2[TEMP_STR_SIZE]; //xan -> this overrides the global temp var int serial/*, serhash*/; tile_st tile; // bool abort=false; NXWSOCKET s=ps->toInt(); P_CHAR pc=ps->currChar(); VALIDATEPC(pc); Location charpos= pc->getPosition(); P_ITEM pack; P_ITEM pCont = pointers::findItemBySerial(pp->Tserial); VALIDATEPI(pCont); P_ITEM pItem = pointers::findItemBySerial(pp->Iserial); VALIDATEPI(pItem); if (pItem->getId() >= 0x4000) { // abort=true; // LB crashfix that prevents moving multi objcts in BP's ps->sysmsg(TRANSLATE("Hey, putting houses in your pack crashes your back and client!")); } //ndEndy recurse only a time P_ITEM contOutMost = pCont->getOutMostCont(); P_CHAR contOwner = ( !contOutMost->isInWorld() )? pointers::findCharBySerial( contOutMost->getContSerial() ) : NULL; if( ISVALIDPC(contOwner) ) { //if ((contOwner->npcaitype==NPCAI_PLAYERVENDOR) && (contOwner->npc) && (contOwner->getOwnerSerial32()!=pc->getSerial32()) ) if ( contOwner->getSerial32() != pc->getSerial32() && contOwner->getOwnerSerial32() != pc->getSerial32() && !pc->IsGM() ) { // Luxor ps->sysmsg(TRANSLATE("This aint your backpack!")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); item_bounce3(pItem); if (pCont->getId() >= 0x4000) senditem(s, pCont); } return; } } if (pCont->amxevents[EVENT_IONPUTITEM]!=NULL) { g_bByPass = false; pCont->amxevents[EVENT_IONPUTITEM]->Call( pCont->getSerial32(), pItem->getSerial32(), pc->getSerial32() ); if (g_bByPass) { item_bounce6(ps,pItem); return; } } /* g_bByPass = false; pCont->runAmxEvent( EVENT_IONPUTITEM, pCont->getSerial32(), pItem->getSerial32(), pc->getSerial32() ); if (g_bByPass) { //AntiChrist to preview item disappearing item_bounce6(ps,pItem); return; } */ if (pCont->layer==0 && pCont->getId() == 0x1E5E && pCont->getContSerial()==pc->getSerial32()) { // Trade window??? serial=calcserial(pCont->moreb1, pCont->moreb2, pCont->moreb3, pCont->moreb4); if(serial==-1) return; P_ITEM pi_z = pointers::findItemBySerial(serial); if (ISVALIDPI(pi_z)) if ((pi_z->morez || pCont->morez)) { pi_z->morez=0; pCont->morez=0; sendtradestatus( pi_z, pCont ); } } if(SrvParms->usespecialbank)//only if special bank is activated { if(pCont->morey==MOREY_GOLDONLYBANK && pCont->morex==MOREX_BANK && pCont->type==ITYPE_CONTAINER) { if ( pItem->getId() == ITEMID_GOLD ) {//if they're gold ok pc->playSFX( goldsfx(2) ); } else {//if they're not gold..bounce on ground ps->sysmsg(TRANSLATE("You can only put golds in this bank box!")); pItem->setContSerial(-1); pItem->MoveTo( charpos ); pItem->Refresh(); pc->playSFX( itemsfx(pItem->getId()) ); return; } } } // Xanathars's Bank Limit Code if (ServerScp::g_nBankLimit != 0) { if( ISVALIDPI( contOutMost ) && contOutMost->morex==MOREX_BANK ) { int n = contOutMost->CountItems( INVALID, INVALID, false); n -= contOutMost->CountItems( ITEMID_GOLD, INVALID, false); if( pItem->type == ITYPE_CONTAINER ) n += pItem->CountItems( INVALID, INVALID, false); else ++n; if( n > ServerScp::g_nBankLimit ) { ps->sysmsg(TRANSLATE("You exceeded the number of maximimum items in bank of %d"), ServerScp::g_nBankLimit); item_bounce6(ps,pItem); return; } } } //ndEndy this not needed because when is dragging cont serial is INVALID //testing UOP Blocking Tauriel 1-12-99 if (!pItem->isInWorld()) { item_bounce6(ps,pItem); return; } data::seekTile(pItem->getId(), tile); if (( ( (pItem->magic==2) || ( (tile.weight==255) && (pItem->magic != 1 ) ) ) && !pc->canAllMove()) || ( (pItem->magic==3|| pItem->magic==4) && !(pItem->getOwnerSerial32()==pc->getSerial32()))) { Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); item_bounce3(pItem); if (pCont->getId() >= 0x4000) senditem(s, pCont); } return; } // - Trash container if( pCont->type==ITYPE_TRASH) { pItem->Delete(); ps->sysmsg(TRANSLATE("As you let go of the item it disappears.")); return; } // - Spell Book if (pCont->type==ITYPE_SPELLBOOK) { if (!pItem->IsSpellScroll72()) { ps->sysmsg(TRANSLATE("You can only place spell scrolls in a spellbook!")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); item_bounce3(pItem); } if (pCont->getId() >= 0x4000) senditem(s, pCont); return; } pack= pc->getBackpack(); if(ISVALIDPI(pack)) { if ((!(pCont->getContSerial()==pc->getSerial32())) && (!(pCont->getContSerial()==pack->getSerial32())) && (!(pc->CanSnoop()))) { ps->sysmsg(TRANSLATE("You cannot place spells in other peoples spellbooks.")); item_bounce6(ps,pItem); return; } if( strncmp(pItem->getCurrentNameC(), "#", 1) ) pItem->getName(temp2); else strcpy(temp2,pItem->getCurrentNameC()); NxwItemWrapper sii; sii.fillItemsInContainer( pCont, false ); for( sii.rewind(); !sii.isEmpty(); sii++ ) { P_ITEM pi_ci=sii.getItem(); if (ISVALIDPI(pi_ci)) { if( strncmp(pi_ci->getCurrentNameC(), "#", 1) ) pi_ci->getName(temp); else strcpy(temp,pi_ci->getCurrentNameC()); if(!(strcmp(temp,temp2)) || !(strcmp(temp,"All-Spell Scroll"))) { ps->sysmsg(TRANSLATE("You already have that spell!")); item_bounce6(ps,pItem); return; } } // Juliunus, to prevent ppl from wasting scrolls. if (pItem->amount > 1) { ps->sysmsg(TRANSLATE("You can't put more than one scroll at a time in your book.")); item_bounce6(ps,pItem); return; } } } pCont->AddItem( pItem ); ps->sendSpellBook(pCont); return; } if (pCont->type == ITYPE_CONTAINER) { if ( ISVALIDPC(contOwner) ) { if ( (contOwner->npcaitype==NPCAI_PLAYERVENDOR) && (contOwner->npc) && (contOwner->getOwnerSerial32()==pc->getSerial32()) ) { pc->fx1= DEREF_P_ITEM(pItem); pc->fx2=17; pc->sysmsg(TRANSLATE("Set a price for this item.")); } } short xx=pp->TxLoc; short yy=pp->TyLoc; pCont->AddItem(pItem,xx,yy); pc->playSFX( itemsfx(pItem->getId()) ); statwindow(pc,pc); } // end of player run vendors else // - Unlocked item spawner or unlockable item spawner if (pCont->type==ITYPE_UNLOCKED_CONTAINER || pCont->type==ITYPE_NODECAY_ITEM_SPAWNER || pCont->type==ITYPE_DECAYING_ITEM_SPAWNER) { pCont->AddItem(pItem, pp->TxLoc, pp->TyLoc); //Luxor pc->playSFX( itemsfx(pItem->getId()) ); } else // - Pileable if (pCont->pileable && pItem->pileable) { if ( !pCont->PileItem( pItem ) ) { item_bounce6(ps,pItem); return; } } else { if( pItem->getContSerial( true )==INVALID ) //current cont serial is invalid because is dragging { NxwSocketWrapper sw; sw.fillOnline( pItem->getPosition() ); for( sw.rewind(); !sw.isEmpty(); sw++ ) SendDeleteObjectPkt(sw.getSocket(), pItem->getSerial32() ); mapRegions->remove(pItem); } pItem->setPosition( pp->TxLoc, pp->TyLoc, pp->TzLoc); pItem->setContSerial( pCont->getContSerial() ); pItem->Refresh(); } }