void cTrade::trademsg(int s) { P_ITEM cont1, cont2; cont1 = cont2 = NULL ; switch(buffer[s][3]) { case 0://Start trade - Never happens, sent out by the server only. break; case 2://Change check marks. Possibly conclude trade cont1 = FindItemBySerPtr(&buffer[s][4]); if (cont1 != NULL) cont2 = FindItemBySerial(calcserial(cont1->moreb1, cont1->moreb2, cont1->moreb3, cont1->moreb4)); else cont2 = NULL; if (cont2 != NULL) // lb crashfix { cont1->morez=buffer[s][11]; sendtradestatus(cont1, cont2); if (cont1->morez && cont2->morez) { dotrade(cont1, cont2); endtrade(calcserial(buffer[s][4], buffer[s][5], buffer[s][6], buffer[s][7])); } } break; case 1://Cancel trade. Send each person cancel messages, move items. endtrade(calcserial(buffer[s][4], buffer[s][5], buffer[s][6], buffer[s][7])); break; default: clConsole.send("ERROR: Fallout of switch statement without default. wolfpack.cpp, trademsg()\n"); //Morrolan } }
// guildrecruit() Let the guild members recruit some player into the guild. // Checks the guild database if "to be recruited" player already in any other guild. // puts a tag with players serial number into the guilds recruit database. void cGuildStone::Recruit(UOXSOCKET s) { if ( currchar[s]->guildstone() == INVALID_SERIAL ) { sysmessage(s,"you are in no guild"); return; } if(buffer[s][11]==0xFF && buffer[s][12]==0xFF && buffer[s][13]==0xFF && buffer[s][14]==0xFF) return; // check if user canceled operation - Morrolan int serial = calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); P_CHAR pc = FindCharBySerial( serial ); if(pc != NULL) { if (pc->guildstone() != INVALID_SERIAL) sysmessage(s,"This person is already in a guild."); else { if (pc->isPlayer()) { this->recruit.push_back(pc->serial); } else sysmessage(s,"This is not a player."); } //break; //} for } this->Menu(s,1); return; }
// opens old (readonly) books == old, bugfixed readbook function void cBooks::openbook_old(UOXSOCKET s, P_ITEM pBook) { unsigned char bookopen[10]="\x93\x40\x01\x02\x03\x00\x00\x00\x02"; //LB 7'th dec 1999, making it client 1.26 complaint unsigned char booktitle[61]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; unsigned char bookauthor[31]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; unsigned long loopexit=0; openscript("misc.scp"); sprintf((char*)temp, "BOOK %i", calcserial(pBook->more1, pBook->more2, pBook->more3, pBook->more4)); if (!i_scripts[misc_script]->find((char*)temp)) { closescript(); return; } LongToCharPtr(pBook->serial, &bookopen[1]); do { read2(); } while ( (strcmp((char*)script1, "PAGES")) && (++loopexit < MAXLOOPS) ); bookopen[8] = (char) str2num(script2); // LB, bugfixing old code loopexit=0; do { read2(); } while ( (strcmp((char*)script1, "TITLE")) && (++loopexit < MAXLOOPS) ); strcpy((char*)(booktitle), script2); loopexit=0; do { read2(); } while ( (strcmp((char*)script1, "AUTHOR")) && (++loopexit < MAXLOOPS) ); strcpy((char*)(bookauthor), script2); Xsend(s, bookopen, 9); // LB, bugfixing of old code Xsend(s, booktitle, 60); Xsend(s, bookauthor, 30); closescript(); }
void cCommands::DyeItem(int s) // Rehue an item { int body,c1,c2,b,k; int serial=calcserial(buffer[s][1],buffer[s][2],buffer[s][3],buffer[s][4]); P_ITEM pi = FindItemBySerial(serial); if (pi != NULL) { c1=buffer[s][7]; c2=buffer[s][8]; if(!(dyeall[s])) { if ((((c1<<8)+c2)<0x0002) || (((c1<<8)+c2)>0x03E9)) { c1=0x03; c2=0xE9; } } b=((((c1<<8)+c2)&0x4000)>>14)+((((c1<<8)+c2)&0x8000)>>15); if (!b) { pi->color1=c1; pi->color2=c2; } if (((c1<<8)+c2)==17969) { pi->color1=c1; pi->color2=c2; } RefreshItem(pi);//AntiChrist soundeffect( s, 0x02, 0x3e ); // plays the dye sound, LB return; }
// New Class implementation void cDragItems::grabItem( cUOSocket *socket, cUORxDragItem *packet ) { // Get our character P_PLAYER pChar = socket->player(); if( !pChar ) return; UINT32 weight = pChar->weight(); // Fetch the grab information UI16 amount = packet->amount(); if( !amount ) amount = 1; P_ITEM pItem = FindItemBySerial( packet->serial() ); // If it's an invalid pointer we can't even bounce if( !pItem ) return; // Are we already dragging an item ? // Bounce it and reject the move // (Logged out while dragging an item) if( socket->dragging() ) { socket->bounceItem( socket->dragging(), BR_ALREADY_DRAGGING ); return; } if( pItem->onPickup( pChar ) ) return; if( pChar->onPickup( pItem ) ) return; // Do we really want to let him break his meditation // When he picks up an item ? // Maybe a meditation check here ?!? pChar->disturbMed(); // Meditation P_CHAR itemOwner = pItem->getOutmostChar(); // Try to pick something out of another characters posessions if( !pChar->isGM() && itemOwner && ( itemOwner != pChar ) && ( itemOwner->objectType() == enNPC && dynamic_cast<P_NPC>(itemOwner)->owner() != pChar ) ) { socket->bounceItem( pItem, BR_BELONGS_TO_SOMEONE_ELSE ); return; } // Check if the user can grab the item if( !pChar->canPickUp( pItem ) ) { socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP ); return; } // The user can't see the item // Basically thats impossible as the socket should deny moving the item // if it's not in line of sight but to prevent exploits /*if( !line_of_sight( socket->socket(), pChar->pos, pItem->pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) ) { socket->sysMessage( "You can't see the item." ); bounceItem( socket, pItem, true ); return; }*/ P_ITEM outmostCont = pItem->getOutmostItem(); // If it's a trade-window, reset the ack-status if( outmostCont && ( outmostCont->container() == pChar ) && ( 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->setMoreZ(0); outmostCont->setMoreZ(0); // sendtradestatus( tradeWindow, outmostCont ); } } // If the top-most container ( thats important ) is a corpse // and looting is a crime, flag the character criminal. if( !pChar->isGM() && 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, outmostCont->owner() ) != 0 ); if( ( outmostCont->more2() == 1 ) && !pChar->Owns( outmostCont ) && !sameGuild ) { // pChar->karma -= 5; pChar->setKarma( pChar->karma() - 5 ); pChar->setCriminalTime( uiCurrentTime + SrvParams->crimtime() * MY_CLOCKS_PER_SEC ); socket->sysMessage( tr("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->container() && pItem->container()->isChar() ) { P_CHAR wearer = dynamic_cast<P_CHAR>( pItem->container() ); if( wearer ) wearer->removeItemBonus( pItem ); // resend the stat window if( wearer && wearer->objectType() == enPlayer ) { P_PLAYER pp = dynamic_cast<P_PLAYER>(wearer); if( pp->socket() ) pp->socket()->sendStatWindow(); } } // Send the user a pickup sound if we're picking it up // From a container/paperdoll if( !pItem->isInWorld() ) socket->soundEffect( 0x57, pItem ); // If we're picking up a specific amount of what we got // Take that into account if( amount < pItem->amount() ) { UI32 pickedAmount = QMIN( 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( World::instance()->findItemSerial() ); splitItem->setAmount( pItem->amount() - pickedAmount ); P_ITEM pContainer = dynamic_cast<P_ITEM>(pItem->container()); if ( pContainer ) pContainer->addItem( splitItem, false ); splitItem->SetOwnSerial( pItem->ownSerial() ); splitItem->SetSpawnSerial( pItem->spawnserial ); // He needs to see the new item splitItem->update(); // 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 ); } } // *normally* we should exclude the dragging socket here. but it works so as well. pItem->removeFromView( true ); // Remove it from the World if it is in world, otherwise remove it from it's current container if( pItem->isInWorld() ) MapObjects::instance()->remove( pItem ); else pItem->removeFromCont( true ); // The item was in a multi if( pItem->multis() != INVALID_SERIAL ) { cMulti* pMulti = dynamic_cast< cMulti* >( FindItemBySerial( pItem->multis() ) ); if( pMulti ) pMulti->removeItem( pItem ); } pChar->addItem( cBaseChar::Dragging, pItem ); if( weight != pChar->weight() ) socket->sendStatWindow(); }
void cDragItems::dropOnItem( cUOSocket *socket, P_ITEM pItem, P_ITEM pCont, const Coord_cl &dropPos ) { P_PLAYER pChar = socket->player(); if( pItem->isMulti() ) { socket->sysMessage( tr( "You cannot put houses in containers" ) ); cUOTxBounceItem bounce; bounce.setReason( BR_NO_REASON ); socket->send( &bounce ); Items->DeleItem( pItem ); return; } if( pItem->onDropOnItem( pCont ) ) { if( socket->dragging() ) socket->bounceItem( socket->dragging(), BR_NO_REASON ); return; } else if( pCont->onDropOnItem( pItem ) ) { if( socket->dragging() ) socket->bounceItem( socket->dragging(), BR_NO_REASON ); return; } // If the target belongs to another character // It needs to be our vendor or else it's denied P_CHAR packOwner = pCont->getOutmostChar(); if( ( packOwner ) && ( packOwner != pChar ) && !pChar->isGM() ) { // For each item someone puts into there // He needs to do a snoop-check if( pChar->maySnoop() ) { if( !pChar->checkSkill( SNOOPING, 0, 1000 ) ) { socket->sysMessage( tr( "You fail to put that into %1's pack" ).arg( packOwner->name() ) ); socket->bounceItem( pItem, BR_NO_REASON ); return; } } if( packOwner->objectType() == enPlayer || ( packOwner->objectType() == enNPC && dynamic_cast<P_NPC>(packOwner)->owner() != pChar ) ) { socket->sysMessage( tr("You cannot put that into the belongings of another player") ); socket->bounceItem( pItem, BR_NO_REASON ); return; } } // If we put the item into a trade-window // Reset the trade-status for both players if( pCont->layer() == 0 && pCont->id() == 0x1E5E && pChar->Wears( pCont ) ) { // Trade window??? P_ITEM tradeWindow = FindItemBySerial( calcserial( pCont->moreb1(), pCont->moreb2(), pCont->moreb3(), pCont->moreb4() ) ); // If it *IS* a trade-window, replace the status if( tradeWindow && ( pCont->morez() || tradeWindow->morez() ) ) { tradeWindow->setMoreZ(0); pCont->setMoreZ(0); // sendtradestatus( tradeWindow, pCont ); } } if( !pChar->canPickUp( pItem ) ) { socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP ); return; } // Trash can if( pCont->type()==87 ) { Items->DeleItem( pItem ); socket->sysMessage( tr( "As you let go of the item it disappears." ) ); return; } // Spell Book cSpellBook *pBook = dynamic_cast< cSpellBook* >( pCont ); if( pBook ) { SI08 spellId = NewMagic->calcSpellId( pItem->id() ); if( pItem->type() != 1105 || spellId < 0 ) { socket->sysMessage( tr( "You can only put scrolls into a spellbook" ) ); socket->bounceItem( pItem, BR_NO_REASON ); return; } if( pBook->hasSpell( spellId ) ) { socket->sysMessage( tr( "That spellbook already contains this spell" ) ); socket->bounceItem( pItem, BR_NO_REASON ); return; } if( pItem->amount() > 1 ) { socket->sysMessage( tr( "You can only put 1 scroll into a spellbook at a time" ) ); socket->bounceItem( pItem, BR_NO_REASON ); return; } else { pBook->addSpell( spellId ); Items->DeleItem( pItem ); pBook->update( socket ); return; } } // We drop something on the belongings of one of our playervendors /* if( ( packOwner != NULL ) && ( packOwner->npcaitype() == 17 ) && packOwner->owner() == pChar ) { socket->sysMessage( tr( "You drop something into your playervendor (unimplemented)" ) ); socket->bounceItem( pItem, BR_NO_REASON ); return; }*/ // Playervendors (chest equipped by the vendor - opened to the client) /*if( !( pCont->pileable() && pItem->pileable() && pCont->id() == pItem->id() || ( pCont->type() != 1 && pCont->type() != 9 ) ) ) { P_CHAR pc_j = GetPackOwner(pCont); if (pc_j != NULL) { if (pc_j->npcaitype() == 17 && pc_j->isNpc() && pChar->Owns(pc_j)) { pChar->inputitem = pItem->serial; pChar->inputmode = cChar::enPricing; sysmessage(s, "Set a price for this item."); } } */ // We may also drop into *any* locked chest // So we can have post-boxes ;o) // Spellbooks are containers for us as well if( pCont->type() == 1 || pCont->type() == 8 || pCont->type() == 63 || pCont->type() == 65 || pCont->type() == 66 ) { // If we're dropping it onto the closed container if( dropPos.distance( pCont->pos() ) == 0 ) { pCont->addItem( pItem ); } else { pCont->addItem( pItem, false ); pItem->setPos( dropPos ); } // Dropped on another Container/in another Container pChar->soundEffect( 0x57 ); pItem->update(); return; } // Item matching needs to be extended !!! at least Color! (for certain types) else if ( pCont->isPileable() && pItem->isPileable() && ( pCont->id() == pItem->id() ) ) { if( pCont->amount() + pItem->amount() <= 65535 ) { pCont->setAmount( pCont->amount() + pItem->amount() ); Items->DeleItem( pItem ); pCont->update(); // Need to update the amount return; } // We have to *keep* our current item else { pCont->setAmount( 65535 ); // Max out the amount pCont->update(); // The delta between 65535 and pCont->amount() sub our Amount is the // new amount pItem->setAmount( pItem->amount() - ( 65535 - pCont->amount() ) ); } } // We dropped the item NOT on a container // And were *un*able to stack it (!) // >> Set it to the location of the item we dropped it on and stack it up by 2 pItem->moveTo( pCont->pos() ); pItem->setPos( pItem->pos() + Coord_cl(0, 0, 2) ); pItem->update(); /* // This needs to be checked // It annoyingly shows the spellbook // whenever you add a scroll // << could it be that addItemToContainer is enough?? >> if( pCont->type() == 9 ) Magic->openSpellBook( pChar, pCont );*/ }
void get_item(P_CLIENT ps) // Client grabs an item { int x, npc=-1, c, amount, update = 0, serial; // tile_st tile; int z;// antichrist for trade fix UOXSOCKET s = ps->GetSocket(); int cc = ps->GetCurrChar(); P_CHAR pc_currchar = MAKE_CHARREF_LR(cc); serial = calcserial(buffer[s][1], buffer[s][2], buffer[s][3], buffer[s][4]); if (serial == INVALID_SERIAL || buffer[s][1] < 0x40) return; // landscape or a character P_ITEM pi = FindItemBySerial(serial); if (pi == NULL) return; pc_currchar->disturbMed(s); // Meditation // Zippy's stealing changes x = DEREF_P_ITEM(pi); if (!items[x].isInWorld()) // Find character owning item { int loopexit = 0; do // Find character owning item { if (isCharSerial(items[x].contserial)) { npc = calcCharFromSer(items[x].contserial); } else // its an item { if (items[x].isInWorld()) { npc=-1; break; } x = calcItemFromSer(items[x].contserial); // ANTICHRIST -- SECURE TRADE FIX if (x!=-1) // LB overwriting x is essential here, dont change it!!! { if (items[x].layer == 0 && items[x].id() == 0x1E5E) { // Trade window??? serial = calcserial(items[x].moreb1, items[x].moreb2, items[x].moreb3, items[x].moreb4); if (serial == INVALID_SERIAL) return; z = calcItemFromSer(serial); if (z!=-1) if ((items[z].morez || items[x].morez)) { items[z].morez = 0; items[x].morez = 0; sendtradestatus(z, x); } } // Blackwinds Looting is crime implementation // changed slightly by Ripper if (items[x].corpse != 0 && !pc_currchar->Owns(&items[x])) { P_CHAR co = FindCharBySerial(items[x].ownserial); if (items[x].more2 == 1 && Guilds->Compare(cc, DEREF_P_CHAR(co)) == 0) { pc_currchar->karma -= 5; criminal(cc); sysmessage(s, "You lost some karma!"); } npc = 0; } // Criminal stuff if (items[x].corpse != 0) npc = 0; } // end if x!=-1 if (x==-1) npc = 0; } } while ((npc==-1) &&(++loopexit < MAXLOOPS)); } if (npc>0) // 0=corpse, hence >0 .. { if (!(pc_currchar->isGM()) && npc != cc && ! pc_currchar->Owns(&chars[npc])) {// Own serial stuff by Zippy -^ Pack aniamls and vendors. bounce[1] = 0; Xsend(s, bounce, 2); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce3(pi); pi->magic = 3; } return; } } // End Zippy's change // Boats-> if (x!=-1 && npc!=-1) { if (items[x].multis>0) imultisp.remove(items[x].multis, items[x].serial); items[x].startDecay(); // End Boats Change // AntiChrist -- for poisoned items if (items[x].layer>0) { chars[npc].removeItemBonus(&items[x]); // remove BONUS STATS given by equipped special items } if ((items[x].trigon==1) && (items[x].layer != 0) && (items[x].layer != 15) && (items[x].layer < 19))// -Frazurbluu- Trigger Type 2 is my new trigger type *- { triggerwitem(s, DEREF_P_ITEM(pi), 1); // trigger is fired } // AntiChrist -- for poisoned items if (items[x].poisoned) { chars[npc].poison -= items[x].poisoned; if (chars[npc].poison < 0) chars[npc].poison = 0; } } if (pi != NULL) { if (pi->corpse != 1) { UpdateStatusWindow(s, pi); if (!pc_currchar->canPickUp(pi)) { bounce[1] = 0; Xsend(s, bounce, 2); if (ps->IsDragging()) // only restore item if it got draggged before !!! { ps->ResetDragging(); item_bounce4(s, pi); } } else { // AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing ) DRAGGED[s] = 1; pi->oldx = pi->pos.x; // first let's save the position pi->oldy = pi->pos.y; pi->oldz = pi->pos.z; pi->oldcontserial = pi->contserial; // then let's save the container pi->oldlayer = pi->layer; // then the layer pi->layer = 0; if (!pi->isInWorld()) soundeffect(s, 0x00, 0x57); if (pi->amount>1) { amount = (buffer[s][5] << 8) + buffer[s][6]; if (amount>pi->amount) amount = pi->amount; if (amount < pi->amount) { c=Items->MemItemFree(); items[c].Init(0); memcpy(&items[c], pi, sizeof(cItem)); // Tauriel reduce code faster too items[c].SetSerial(itemcount2); itemcount2++; items[c].amount = pi->amount - amount; // Tauriel sorry, there is no way to make this call the item creation stuff // Why doing it twice? // setptr(&itemsp[itemcount2%HASHMAX], c); // itemcount2++; // important bugfix for items disappearing, lb if (!items[c].isInWorld()) contsp.insert(items[c].contserial, items[c].serial); if (items[c].ownserial!=-1) setptr(&ownsp[items[c].ownserial%HASHMAX], c); if (items[c].spawnserial!=-1) setptr(&spawnsp[items[c].spawnserial%HASHMAX], c); statwindow(s,cc); RefreshItem(c);//AntiChrist } if (pi->id() == 0x0EED) // gold coin { int packnum = packitem(currchar[s]); if (packnum!=-1) // lb if (pi->contserial == items[packnum].serial) update = 1; } pi->amount = amount; } // Tauriel remove item from world mapcells mapRegions->Remove(pi); // remove this item from a map cell pi->pos.x = 0; pi->pos.y = 0; pi->pos.z = 0; pi->flags.isBeeingDragged=true; pi->SetContSerial(-1); if (pi != NULL) // Ripper...adds weight to the players cursor when carrying a item. { int amt = 0, wgt; wgt = (int)Weight->LockeddownWeight(pi, &amt, 0); pc_currchar->weight += wgt; update = 1; } } } } // end of if i!=-1 if (update) statwindow(s, DEREF_P_CHAR(pc_currchar)); }
void cTrade::buyaction(int s) { char clearmsg[8]; int clear, i, j; P_ITEM buyit[256]; int amount[512]; int layer[512]; int playergoldtotal; int goldtotal; int itemtotal; int soldout; int tmpvalue=0; // Fixed for adv trade system -- Magius(CHE) § // CHARACTER cc=currchar[s]; P_CHAR pc_currchar = currchar[s]; P_ITEM pi_pack = Packitem(pc_currchar); if (pi_pack == NULL) return; //LB no player-pack - no buy action possible - and no crash too ;-) P_CHAR npc = FindCharBySerial(calcserial(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6])); if (npc <= 0) return; clear=0; goldtotal=0; soldout=0; itemtotal=(((256*(buffer[s][1]))+buffer[s][2])-8)/7; if (itemtotal>256) return; //LB for(i = 0; i < itemtotal; i++) { layer[i]=buffer[s][8+(7*i)]; buyit[i] = FindItemBySerial(calcserial(buffer[s][8+(7*i)+1], buffer[s][8+(7*i)+2], buffer[s][8+(7*i)+3], buffer[s][8+(7*i)+4])); amount[i]=(256*(buffer[s][8+(7*i)+5]))+buffer[s][8+(7*i)+6]; if (buyit[i] != NULL) { buyit[i]->rank=10; // Fixed for adv trade system -- Magius(CHE) § tmpvalue = buyit[i]->value; tmpvalue = calcValue(buyit[i], tmpvalue); if (SrvParams->trade_system()==1) tmpvalue = calcGoodValue(pc_currchar, buyit[i], tmpvalue,0); goldtotal += (amount[i]*tmpvalue); // End Fix for adv trade system -- Magius(CHE) § } } bool useBank; useBank = (goldtotal >= SrvParams->checkBank() ); if( useBank ) playergoldtotal = GetBankCount( pc_currchar, 0x0EED ); else playergoldtotal = pc_currchar->CountGold(); if ((playergoldtotal>=goldtotal)||(pc_currchar->isGM())) { for (i = 0; i < itemtotal; i++) { if (buyit[i] != NULL) { if (buyit[i]->amount < amount[i]) { soldout = 1; } } } if (soldout) { npctalk(s, npc, "Alas, I no longer have all those goods in stock. Let me know if there is something else thou wouldst buy.",0); clear = 1; } else { if (pc_currchar->isGM()) { sprintf((char*)temp, "Here you are, %s. Someone as special as thee will receive my wares for free of course.", pc_currchar->name.c_str()); } else { if(useBank) { sprintf((char*)temp, "Here you are, %s. %d gold coin%s will be deducted from your bank account. I thank thee for thy business.", pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s"); goldsfx(s, goldtotal); } else { sprintf((char*)temp, "Here you are, %s. That will be %d gold coin%s. I thank thee for thy business.", pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s"); goldsfx(s, goldtotal); // Dupois, SFX for gold movement. Added Oct 08, 1998 } } npctalkall(npc, (char*)temp, 0); npcaction(npc, 0x20); // bow (Duke, 17.3.2001) clear = 1; if( !(pc_currchar->isGM() ) ) { if( useBank ) DeleBankItem( pc_currchar, 0x0EED, 0, goldtotal ); else delequan( pc_currchar, 0x0EED, goldtotal, NULL ); } for (i=0;i<itemtotal;i++) { P_ITEM pi = buyit[i]; if (pi != NULL) { if (pi->amount>amount[i]) { if (pi->pileable) { Commands->DupeItem(s, buyit[i], amount[i]); } else { for (j=0;j<amount[i];j++) { Commands->DupeItem(s, buyit[i], 1); } } pi->amount-=amount[i]; pi->restock+=amount[i]; } else { switch(layer[i]) { case 0x1A: if (pi->pileable) { Commands->DupeItem(s, buyit[i], amount[i]); } else { for (j=0;j<amount[i];j++) { Commands->DupeItem(s, buyit[i], 1); } } pi->amount=pi->amount-amount[i]; pi->restock=pi->restock+amount[i]; break; case 0x1B: if (pi->pileable) { pi->SetContSerial(pi_pack->serial); RefreshItem(buyit[i]);//AntiChrist } else { for (j=0;j<amount[i]-1;j++) { Commands->DupeItem(s, buyit[i], 1); } pi->SetContSerial(pi_pack->serial); pi->amount = 1; RefreshItem(buyit[i]);//AntiChrist } break; default: clConsole.send("ERROR: Fallout of switch statement without default. wolfpack.cpp, buyaction()\n"); //Morrolan } } } } } } else { npctalkall(npc, "Alas, thou dost not possess sufficient gold for this purchase!",0); } if (clear) { clearmsg[0]=0x3B; clearmsg[1]=0x00; clearmsg[2]=0x08; clearmsg[3]=buffer[s][3]; clearmsg[4]=buffer[s][4]; clearmsg[5]=buffer[s][5]; clearmsg[6]=buffer[s][6]; clearmsg[7]=0x00; Xsend(s, clearmsg, 8); } Weight->NewCalc(pc_currchar); // Ison 2-20-99 statwindow(s, pc_currchar); }
void cTrade::sellaction(int s) { int i, amt, value=0, totgold=0; P_ITEM pRestock = NULL; P_ITEM pNoRestock = NULL; P_ITEM pSellCont = NULL; if (buffer[s][8]!=0) { P_CHAR pc_n = FindCharBySerial(calcserial(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6])); if (pc_n == NULL) return; P_ITEM pi; unsigned int ci; vector<SERIAL> vecContainer = contsp.getData(pc_n->serial); for ( ci = 0; ci < vecContainer.size(); ci++) { pi = FindItemBySerial(vecContainer[ci]); if (pi->layer==0x1A) pRestock = pi; // Buy Restock container else if (pi->layer==0x1B) pNoRestock = pi; // Buy no restock container else if (pi->layer==0x1C) pSellCont = pi; // Sell container } // Pre Calculate Total Amount of selling items to STOPS if the items if greater than SELLMAXITEM - Magius(CHE) int maxsell=0; i=buffer[s][8]; if (i>256) return; for (i=0;i<buffer[s][8];i++) { amt=ShortFromCharPtr(buffer[s]+9+(6*i)+4); maxsell+=amt; } if (maxsell>SrvParams->sellmaxitem()) { char tmpmsg[256]; sprintf(tmpmsg,"Sorry %s but i can buy only %i items at time!",currchar[s]->name.c_str(),SrvParams->sellmaxitem()); npctalkall(pc_n, tmpmsg,0); return; } for (i=0;i<buffer[s][8];i++) { P_ITEM pSell=FindItemBySerPtr(buffer[s]+9+(6*i)); // the item to sell if (!pSell) continue; amt=ShortFromCharPtr(buffer[s]+9+(6*i)+4); // player may have taken items out of his bp while the sell menu was up ;-) if (pSell->amount<amt) { npctalkall(pc_n, "Cheating scum! Leave now, before I call the guards!",0); return; } // Search the buy restock Container P_ITEM join = NULL; ci=0; P_ITEM pi; vector<SERIAL> vecContainer = contsp.getData(pRestock->serial); for ( ci = 0; ci < vecContainer.size(); ci++) { pi = FindItemBySerial(vecContainer[ci]); if (items_match(pi,pSell)) join = pi; } // Search the sell Container to determine the price ci=0; vecContainer.clear(); vecContainer = contsp.getData(pSellCont->serial); for ( ci = 0; ci < vecContainer.size(); ci++) { pi = FindItemBySerial(vecContainer[ci]); if (items_match(pi,pSell)) { value=pi->value; value=calcValue(pSell, value); if (SrvParams->trade_system()==1) value=calcGoodValue(currchar[s], pSell, value, 1); // Fixed for adv trade --- by Magius(CHE) § break; // let's take the first match } } totgold+=(amt*value); // add to the bill if (join != NULL) // The item goes to the container with restockable items { join->amount+=amt; join->restock-=amt; pSell->ReduceAmount(amt); } else { pSell->SetContSerial(pNoRestock->serial); SndRemoveitem(pSell->serial); if (pSell->amount!=amt) Commands->DupeItem(s, pSell, pSell->amount-amt); } } addgold(s, totgold); goldsfx(s, totgold); // Dupois, SFX for gold movement // Added Oct 08, 1998 } char clearmsg[9]; clearmsg[0]=0x3B; clearmsg[1]=0x00; clearmsg[2]=0x08; clearmsg[3]=buffer[s][3]; clearmsg[4]=buffer[s][4]; clearmsg[5]=buffer[s][5]; clearmsg[6]=buffer[s][6]; clearmsg[7]=0x00; Xsend(s, clearmsg, 8); }
/*! \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); } }
bool cBoat::Block(P_ITEM pBoat, short int xmove, short int ymove, int dir)//Check to see if the boat is blocked in front of, behind, or next to it (Depending on direction) // PARAM WARNING: xmove and ymove is unreferenced { int ser, sz, zt, loopexit=0; short x = 0, y = 0, c; bool blocked = false; char type, size = 0, typ = 0; map_st map; land_st land; tile_st tile; ser = calcserial(pBoat->moreb1, pBoat->moreb2, pBoat->moreb3, pBoat->moreb4); P_ITEM t = FindItemBySerial( ser ); P_ITEM p1 = FindItemBySerial( pBoat->morex ); P_ITEM p2 = FindItemBySerial( pBoat->morey ); P_ITEM h = FindItemBySerial( pBoat->morez ); switch(dir) { case 6: // L case 7: // U & L case 0: // U case 1: // U & R x = min( t->pos.x, min( h->pos.x, min( p1->pos.x, p2->pos.x ) ) ); y = min( t->pos.y, min( h->pos.y, min( p1->pos.y, p2->pos.y ) ) ); if ( dir != 6 ) type = 1; else if ( dir == 0 ) type = 2; else type = 3; break; case 2: // R case 3: // D & R case 4: // D case 5: // D & L x = max( t->pos.x, max( h->pos.x, max( p1->pos.x, p2->pos.x ) ) ); y = min( t->pos.y, min( h->pos.y, min( p1->pos.y, p2->pos.y ) ) ); if ( dir != 2 ) type = 1; else if ( dir == 4 ) type = 2; else type = 3; break; } //small = 10x5, med = 11x5 large = 12x5 switch(pBoat->more1)//Now set what size boat it is and move the specail items { case 0x00: case 0x04: if ( type == 1 ) size = 10; else if ( type == 2 ) size = 5; else size = 7; case 0x08: case 0x0C: if ( type == 1 ) size = 11; else if ( type == 2 ) size = 5; else size = 7; case 0x10: case 0x14: if ( type == 1 ) size = 12; else if ( type == 2 ) size = 5; else size = 7; break; } if ( type == 1) y -= (size/2)-1; else x -= (size/2)-1; for ( c=0 ; c<size ; c++ ) { if ( type == 1 ) y++; else if ( type == 2 ) x++; else // type == 3 { x++; y++; } sz = Map->StaticTop(Coord_cl(x,y, pBoat->pos.z, pBoat->pos.map ) ); if (sz==illegal_z) typ=0; //0: map-tile else typ=1; //1: static-tile if (typ==0) { map=Map->SeekMap( Coord_cl( x, y, 0, pBoat->pos.map ) ); Map->SeekLand(map.id, &land); //clConsole.send("map type, water bit: %i\n",land.flag1&0x80); if (!(land.flag1&0x80)) blocked = true; } else { // go through all statics of a given x,y... MapStaticIterator msi(Coord_cl( x, y, 0, pBoat->pos.map )); staticrecord *stat; while ( (stat = msi.Next()) && (++loopexit < MAXLOOPS) ) { msi.GetTile(&tile); zt=stat->zoff+tile.height; //for this part...: Bridges can be shown not valid, //so we will keep setting false until we hit a valid point, //when we hit a valid place, we'll stop, leave block as it was, //if all points are invalid, block is true and we exit as normal. if (!(tile.flag1&0x80) && zt<=70) blocked = true; else if (strcmp((char*)tile.name, "water")) blocked = true; //if (zt>70) water = 1; // every static til with z>70 (mast height?) doesnt block, no matter what water-bit is has } }//if type.... if ( blocked ) return true; }//for c=soze return false; }
void pack_item(P_CLIENT ps, PKGx08 *pp) // Item is put into container { int j, serial; bool abort=false; UOXSOCKET s=ps->GetSocket(); CHARACTER cc=ps->GetCurrChar(); P_CHAR pc_currchar = MAKE_CHARREF_LR(cc); serial=pp->Tserial; if(serial == INVALID_SERIAL) abort=true; const P_ITEM pCont= FindItemBySerial( serial ); serial=pp->Iserial; if(serial == INVALID_SERIAL) abort=true; const P_ITEM pItem = FindItemBySerial( serial ); if (pCont == NULL) { RefreshItem(pCont);//AntiChrist return; } if (pItem == NULL || pCont == NULL) return; //LB pItem->flags.isBeeingDragged=false; if (pItem->id1>=0x40) { abort=true; // LB crashfix that prevents moving multi objcts in BP's sysmessage(s,"Hey, putting houses in your pack crashes your back and client!"); } j=DEREF_P_CHAR(GetPackOwner(pCont)); if (j>-1) if (chars[j].npcaitype==17 && chars[j].isNpc() && !pc_currchar->Owns(&chars[j])) { abort=true; sysmessage(s, "This aint your vendor!"); } if(abort) {//AntiChrist to preview item disappearing item_bounce6(ps,pItem); return; } if (pCont->layer==0 && pCont->id() == 0x1E5E && pc_currchar->Wears(pCont)) { // Trade window??? serial=calcserial(pCont->moreb1, pCont->moreb2, pCont->moreb3, pCont->moreb4); if(serial == INVALID_SERIAL) return; P_ITEM pi_z = FindItemBySerial( serial ); if (pi_z != NULL) if ((pi_z->morez || pCont->morez)) { pi_z->morez=0; pCont->morez=0; sendtradestatus(pi_z, pCont); } } // //AntiChrist - Special Bank Stuff // //if morey==123 - gold only bank // if(SrvParms->usespecialbank)//only if special bank is activated { if(pCont->morey==123 && pCont->morex==1 && pCont->type==1) { if ( pItem->id() == 0x0EED ) {//if they're gold ok goldsfx(s, 2); } else {//if they're not gold..bounce on ground sysmessage(s,"You can only put golds in this bank box!"); pItem->SetContSerial(-1); pItem->MoveTo(pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z); RefreshItem(pItem);//AntiChrist itemsfx(s,pItem->id()); return; } } } //testing UOP Blocking Tauriel 1-12-99 if (!pItem->isInWorld()) { item_bounce6(ps,pItem); return; } if (!pc_currchar->canPickUp(pItem)) { Sndbounce5(s); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce3(pItem); if (pCont->id1>=0x40) senditem(s, pCont); } return; } // - Trash container if (pCont->type==87) { Items->DeleItem(pItem); sysmessage(s, "As you let go of the item it disappears."); return; } // - Spell Book if (pCont->type==9) { if (!IsSpellScroll72(pItem->id())) { sysmessage(s, "You can only place spell scrolls in a spellbook!"); Sndbounce5(s); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce3(pItem); } if (pCont->id1>=0x40) senditem(s, pCont); return; } P_ITEM pBackpack = Packitem(pc_currchar); if (pBackpack != NULL) // lb { if (!pc_currchar->Wears(pCont) && (!(pCont->contserial==pBackpack->serial)) && (!(pc_currchar->canSnoop()))) { sysmessage(s, "You cannot place spells in other peoples spellbooks."); item_bounce6(ps,pItem); return; } if(pItem->name[0]=='#') pItem->getName(temp2); else strcpy((char*)temp2,pItem->name); vector<SERIAL> vecContainer = contsp.getData(pCont->serial); for (unsigned int i = 0; i < vecContainer.size(); i++) // antichrist , bugfix for inscribing scrolls { P_ITEM pi = FindItemBySerial(vecContainer[i]); if (pi != NULL) { if(pi->name[0]=='#') pi->getName(temp); else strcpy((char*)temp, pi->name); if(!(strcmp((char*)temp,(char*)temp2)) || !(strcmp((char*)temp,"All-Spell Scroll"))) { sysmessage(s,"You already have that spell!"); item_bounce6(ps,pItem); return; } } } } } // player run vendors if (!(pCont->pileable && pItem->pileable && pCont->id()==pItem->id() || (pCont->type!=1 && pCont->type!=9))) { j=DEREF_P_CHAR(GetPackOwner(pCont)); if (j>-1) // bugkilling, LB, was j=!-1, arghh, C !!! { if (chars[j].npcaitype==17 && chars[j].isNpc() && pc_currchar->Owns(&chars[j])) { pc_currchar->inputitem = pItem->serial; pc_currchar->inputmode = cChar::enPricing; sysmessage(s, "Set a price for this item."); } } short xx=pp->TxLoc; short yy=pp->TyLoc; pCont->AddItem(pItem,xx,yy); itemsfx(s, pItem->id());// see itemsfx() for details - Dupois Added Oct 09, 1998 statwindow(s,DEREF_P_CHAR(pc_currchar)); } // end of player run vendors else // - Unlocked item spawner or unlockable item spawner if (pCont->type==63 || pCont->type==65 || pCont->type==66) { pItem->SetContSerial(pp->Tserial); // lb bugfix pItem->pos.x=pp->TxLoc; pItem->pos.y=pp->TyLoc; pItem->pos.z=pp->TzLoc; SndRemoveitem(pItem->serial); RefreshItem(pItem);//AntiChrist itemsfx(s, pItem->id()); } else // - Pileable if (pCont->pileable && pItem->pileable && pCont->id()==pItem->id()) { if ((pCont->amount+pItem->amount) > 65535) { pItem->amount -= (65535-pCont->amount); Commands->DupeItem(s, pCont, pItem->amount); pCont->amount = 65535; Items->DeleItem(pItem); } else { pCont->amount=pCont->amount+pItem->amount; itemsfx(s, pItem->id()); Items->DeleItem(pItem); } SndRemoveitem(pItem->serial); RefreshItem(pCont);//AntiChrist } else { pItem->pos.x=pp->TxLoc; pItem->pos.y=pp->TyLoc; pItem->pos.z=pp->TzLoc; // pItem->SetContSerial(-1); pItem->SetContSerial(pp->Tserial); // Tauriel add item to world mapcells mapRegions->Add(pItem); //add this item to a map cell SndRemoveitem(pItem->serial); RefreshItem(pCont);//AntiChrist } // - Spell Book if (pCont->type==9) Magic->SpellBook(s, pCont); // LB, bugfix for showing(!) the wrong spell (clumsy) when a new spell is put into opened spellbook if (pItem->glow>0) // LB's glowing items stuff { int p = DEREF_P_CHAR(GetPackOwner(pCont)); pc_currchar->removeHalo(pItem); // if gm put glowing object in another pack, handle glowsp correctly ! if (p!=-1) { chars[p].addHalo(pItem); chars[p].glowHalo(pItem); } } }
void cDragdrop::get_item(P_CLIENT ps) // Client grabs an item { int npc=-1, amount, update = 0, serial; UOXSOCKET s = ps->GetSocket(); int cc = ps->GetCurrChar(); P_CHAR pc_currchar = MAKE_CHARREF_LR(cc); serial = calcserial(buffer[s][1], buffer[s][2], buffer[s][3], buffer[s][4]); if (serial == INVALID_SERIAL || buffer[s][1] < 0x40) return; // landscape or a character P_ITEM pi = FindItemBySerial(serial); if (pi == NULL) return; pc_currchar->disturbMed(s); // Meditation // Zippy's stealing changes P_ITEM px = pi; if (!px->isInWorld()) // Find character owning item { unsigned long loopexit = 0; do // Find character owning item { if (isCharSerial(px->contserial)) { npc = calcCharFromSer(px->contserial); } else // its an item { if (px->isInWorld()) { npc=-1; break; } px = FindItemBySerial(px->contserial); // ANTICHRIST -- SECURE TRADE FIX if (px != NULL) // LB overwriting x is essential here, dont change it!!! { if (px->layer == 0 && px->id() == 0x1E5E) { // Trade window??? serial = calcserial(px->moreb1, px->moreb2, px->moreb3, px->moreb4); if (serial == INVALID_SERIAL) return; P_ITEM pi_z = FindItemBySerial(serial); if ( pi_z != NULL ) if ((pi_z->morez || px->morez)) { pi_z->morez = 0; px->morez = 0; sendtradestatus(pi_z, px); } } // Blackwinds Looting is crime implementation // changed slightly by Ripper if (px->corpse != 0 && !pc_currchar->Owns(px)) { P_CHAR co = FindCharBySerial(px->ownserial); if (px->more2 == 1 && Guilds->Compare(DEREF_P_CHAR(pc_currchar), DEREF_P_CHAR(co)) == 0) { pc_currchar->karma -= 5; criminal(DEREF_P_CHAR(pc_currchar)); sysmessage(s, "You lost some karma!"); } npc = 0; } // Criminal stuff if (px->corpse != 0) npc = 0; } // end if x!=-1 if (px == NULL) npc = 0; } } while ((npc==-1) &&(++loopexit < MAXLOOPS)); } if (npc>0) // 0=corpse, hence >0 .. { if (!(pc_currchar->isGM()) && npc != DEREF_P_CHAR(pc_currchar) && ! pc_currchar->Owns(&chars[npc])) {// Own serial stuff by Zippy -^ Pack aniamls and vendors. bounce[1] = 0; Xsend(s, bounce, 2); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce3(pi); pi->magic = 3; } return; } } // End Zippy's change // Boats-> if (px != NULL && npc!=-1) { if (px->multis>0) imultisp.remove(px->multis, px->serial); px->startDecay(); // End Boats Change // AntiChrist -- for poisoned items if (px->layer>0) { chars[npc].removeItemBonus(px); // remove BONUS STATS given by equipped special items } if ((px->trigon==1) && (px->layer != 0) && (px->layer != 15) && (px->layer < 19))// -Frazurbluu- Trigger Type 2 is my new trigger type *- { Trig->triggerwitem(s, pi, 1); // trigger is fired } } if (pi != NULL) { if (pi->corpse != 1) { UpdateStatusWindow(s, pi); if (!pc_currchar->canPickUp(pi)) { bounce[1] = 0; Xsend(s, bounce, 2); if (ps->IsDragging()) // only restore item if it got draggged before !!! { ps->ResetDragging(); item_bounce4(s, pi); } } else { // AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing ) DRAGGED[s] = 1; pi->oldx = pi->pos.x; // first let's save the position pi->oldy = pi->pos.y; pi->oldz = pi->pos.z; pi->oldcontserial = pi->contserial; // then let's save the container pi->oldlayer = pi->layer; // then the layer pi->layer = 0; if (!pi->isInWorld()) soundeffect(s, 0x00, 0x57); if (pi->amount>1) { amount = (buffer[s][5] << 8) + buffer[s][6]; if (amount>pi->amount) amount = pi->amount; if (amount < pi->amount) { P_ITEM pi_c = Items->MemItemFree(); // pi_c->Init(0); #pragma note("Replace by a copy constructor before finishing items[]") memcpy(pi_c, pi, sizeof(cItem)); // Tauriel reduce code faster too pi_c->SetSerial(cItemsManager::getItemsManager().getUnusedSerial()); pi_c->amount = pi->amount - amount; pi_c->SetContSerial(pi_c->contserial); pi_c->SetOwnSerial(pi_c->ownserial); pi_c->SetSpawnSerial(pi_c->spawnserial); statwindow(s,DEREF_P_CHAR(pc_currchar)); RefreshItem(pi_c);//AntiChrist } if (pi->id() == 0x0EED) // gold coin { P_ITEM packnum = packitem(currchar[s]); if (packnum != NULL) // lb if (pi->contserial == packnum->serial) update = 1; } pi->amount = amount; } /* int amt = 0, wgt; bool tooheavy=false; wgt = (int)Weight->LockeddownWeight(pi, &amt, 0); if(pi->contserial>0) { if (( (pc_currchar->weight+wgt) > (pc_currchar->st*WEIGHT_PER_STR)+30)) // LB -> added: drop item if too heavy { float res=float( (pc_currchar->weight+wgt) - ((pc_currchar->st*WEIGHT_PER_STR)+30))*2; int diff = pc_currchar->st; diff -= (int)res; if (diff<=0 && !pc_currchar->isGM() ) { tooheavy=true; bounce[1] = 0; Xsend(s, bounce, 2); if (ps->IsDragging()) // only restore item if it got dragged before !!! { ps->ResetDragging(); item_bounce4(s, pi); } sysmessage(s, "you can't pick this up, this is too heavy"); return; } } } if (!tooheavy) pc_currchar->weight+=wgt; update = 1; */ // LB remark: drop item if too heavy is a good solution, // but there's still a small bug remaining. // added weight from items picked up, but not put to bp, pd, in other words hold in ones hand, // is NOT subtracted when being dropped again to ground/other chars/other chars' bp's. // but this bug doesnt show up becasue weight is re-calculated automatically all 10 secs. // without adding weight of the item curently carrying in hand. // a correct solutions need the weight of item in hand being stored // , added to auto-re-calculation all x-secs code, and being subtracted if dropped. // because it's now only happening for leight weight items, because heavy weight itms cant be picke up anymore // I haven't corrected this yet. // Tauriel remove item from world mapcells mapRegions->Remove(pi); // remove this item from a map cell pi->pos.x = 0; pi->pos.y = 0; pi->pos.z = 0; pi->flags.isBeeingDragged=true; pi->SetContSerial(-1); } } } // end of if i!=-1 if (update) statwindow(s, DEREF_P_CHAR(pc_currchar)); }
// 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::dropOnItem( P_CLIENT client, P_ITEM pItem, P_ITEM pCont, const Coord_cl &dropPos ) { P_CHAR pChar = client->player(); if( pItem->isMulti() ) { client->sysMessage( "You cannot put houses in containers" ); bounceItem( client, pItem ); return; } // If the target belongs to another character // It needs to be our vendor or else it's denied P_CHAR packOwner = GetPackOwner( pCont ); if( ( packOwner != NULL ) && ( packOwner != pChar ) ) { // For each item someone puts into there // He needs to do a snoop-check if( pChar->canSnoop() ) { if( !Skills->CheckSkill( pChar, SNOOPING, 0, 1000 ) ) { client->sysMessage( QString( "You fail to put that into %1's pack" ).arg( packOwner->name.c_str() ) ); bounceItem( client, pItem ); return; } } if( !packOwner->isNpc() || ( packOwner->npcaitype() != 17 ) || !pChar->Owns( packOwner ) ) { client->sysMessage( "You cannot put that into the belongings of another player" ); bounceItem( client, pItem ); return; } } // If we put the item into a trade-window // Reset the trade-status for both players if( pCont->layer() == 0 && pCont->id() == 0x1E5E && pChar->Wears( pCont ) ) { // Trade window??? P_ITEM tradeWindow = FindItemBySerial( calcserial( pCont->moreb1(), pCont->moreb2(), pCont->moreb3(), pCont->moreb4() ) ); // If it *IS* a trade-window, replace the status if( tradeWindow && ( pCont->morez || tradeWindow->morez ) ) { tradeWindow->morez = 0; pCont->morez = 0; sendtradestatus( tradeWindow, pCont ); } } if( !pChar->canPickUp( pItem ) ) { bounceItem( client, pItem ); return; } // Trash can if( pCont->type()==87 ) { Items->DeleItem( pItem ); client->sysMessage( "As you let go of the item it disappears." ); return; } // Spell Book if( pCont->type() == 9 ) { UI08 spellId = Magic->calcSpellId( pItem->id() ); if( spellId < 0 ) { client->sysMessage( "You can only put scrolls into a spellbook" ); bounceItem( client, pItem ); return; } if( Magic->hasSpell( pCont, spellId ) ) { client->sysMessage( "That spellbook already contains this spell" ); bounceItem( client, pItem ); return; } } // We drop something on the belongings of one of our playervendors if( ( packOwner != NULL ) && ( packOwner->npcaitype() == 17 ) && pChar->Owns( packOwner ) ) { client->sysMessage( "You drop something into your playervendor" ); bounceItem( client, pItem ); return; } // Playervendors (chest equipped by the vendor - opened to the client) /*if( !( pCont->pileable() && pItem->pileable() && pCont->id() == pItem->id() || ( pCont->type() != 1 && pCont->type() != 9 ) ) ) { P_CHAR pc_j = GetPackOwner(pCont); if (pc_j != NULL) { if (pc_j->npcaitype() == 17 && pc_j->isNpc() && pChar->Owns(pc_j)) { pChar->inputitem = pItem->serial; pChar->inputmode = cChar::enPricing; sysmessage(s, "Set a price for this item."); } } */ // We may also drop into *any* locked chest // So we can have post-boxes ;o) // Spellbooks are containers for us as well if( pCont->type() == 9 || pCont->type() == 1 || pCont->type() == 8 || pCont->type() == 63 || pCont->type() == 65 || pCont->type() == 66 ) { pItem->setContSerial( pCont->serial ); pItem->setLayer( 0 ); // Remove it from our drag-layer // Huh ? - Make that random will you! pItem->pos = dropPos; SndRemoveitem( pItem->serial ); RefreshItem( pItem ); // Dropped on another Container/in another Container soundeffect2( pChar, 0x57 ); return; } // Item matching needs to be extended !!! at least Color! (for certain types) else if ( pCont->isPileable() && pItem->isPileable() && ( pCont->id() == pItem->id() ) ) { if( pCont->amount() + pItem->amount() <= 65535 ) { pCont->setAmount( pCont->amount() + pItem->amount() ); Items->DeleItem( pItem ); RefreshItem( pCont ); // Need to update the amount return; } // We have to *keep* our current item else { pCont->setAmount( 65535 ); // Max out the amount RefreshItem( pCont ); // The delta between 65535 and pCont->amount() sub our Amount is the // new amount pItem->setAmount( pItem->amount() - ( 65535 - pCont->amount() ) ); } } // We dropped the item NOT on a container // And were *un*able to stack it (!) // >> Set it to the location of the item we dropped it on and stack it up by 1 pItem->moveTo( pCont->pos ); pItem->pos.z++; // Increase z by 1 pItem->pos.y++; // To get it visualized do that with y as well pItem->setLayer( 0 ); pItem->setContSerial( pCont->contserial ); RefreshItem( pItem ); // This needs to be checked // It annoyingly shows the spellbook // whenever you add a scroll if( pCont->type() == 9 ) Magic->openSpellBook( pChar, pCont ); // Glowing Objects moved between chars if( pItem->glow != INVALID_SERIAL ) { pChar->removeHalo( pItem ); if( packOwner != NULL ) { packOwner->addHalo(pItem); packOwner->glowHalo(pItem); } } }
void cDragItems::dropOnChar( P_CLIENT client, P_ITEM pItem, P_CHAR pOtherChar ) { // Three possibilities: // If we're dropping it on ourself: packintobackpack // If we're dropping it on some other player: trade-window // If we're dropping it on some NPC: checkBehaviours // If not handeled: Equip the item if the NPC is owned by us P_CHAR pChar = client->player(); // Dropped on ourself if( pChar == pOtherChar ) { pItem->setLayer( 0 ); pItem->setContSerial( INVALID_SERIAL ); pItem->toBackpack( pChar ); return; } // Are we in range of our target if( !inrange1p( pChar, pOtherChar ) ) { client->sysMessage( "You are too far away from that character." ); bounceItem( client, pItem ); return; } // Can wee see our target if( !line_of_sight( client->socket(), pChar->pos, pOtherChar->pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) ) { client->sysMessage( "You can't see this character" ); bounceItem( client, pItem ); return; } // Open a secure trading window if( !pOtherChar->isNpc() && online( pOtherChar ) ) { // Check if we're already trading, // if not create a new window vector< SERIAL > equipment = contsp.getData( pChar->serial ); P_ITEM tradeWindow = NULL; for( UI16 i = 0; i < equipment.size(); i++ ) { P_ITEM pEquip = FindItemBySerial( equipment[ i ] ); // Is it a trade-window ? if( ( pEquip->layer() == 0 ) && ( pEquip->id() == 0x1E5E ) ) { P_ITEM tradeWindow = FindItemBySerial( calcserial( pEquip->moreb1(), pEquip->moreb2(), pEquip->moreb3(), pEquip->moreb4() ) ); if( tradeWindow && ( tradeWindow->contserial == pOtherChar->serial ) ) { tradeWindow = pEquip; break; } } } if( !tradeWindow ) tradeWindow = Trade->tradestart( client->socket(), pOtherChar ); pItem->setContSerial( tradeWindow->serial); pItem->pos.x = rand() % 60; pItem->pos.y = rand() % 60; pItem->pos.z = 9; pItem->setLayer( 0 ); SndRemoveitem( pItem->serial ); RefreshItem( pItem ); return; } // For our hirelings we have a special function if( pChar->Owns( pOtherChar ) ) { dropOnPet( client, pItem, pOtherChar ); return; } // Dropping based on AI Type switch( pOtherChar->npcaitype() ) { case 4: dropOnGuard( client, pItem, pOtherChar ); break; case 5: dropOnBeggar( client, pItem, pOtherChar ); break; case 8: dropOnBanker( client, pItem, pOtherChar ); break; case 19: dropOnBroker( client, pItem, pOtherChar ); break; }; // Try to train - works for any NPC if( pOtherChar->cantrain() ) if( pChar->trainer() == pOtherChar->serial ) dropOnTrainer( client, pItem, pOtherChar ); else pOtherChar->talk( "You need to tell me what you want to learn first" ); bounceItem( client, pItem ); return; }
// old readbook function void cBooks::readbook_readonly_old(UOXSOCKET s, P_ITEM pBook, int p) { int x, y, pos, j; unsigned char bookpage[14]="\x66\x01\x02\x40\x01\x02\x03\x00\x01\x00\x01\x00\x01"; unsigned long loopexit=0,loopexit2=0; openscript("misc.scp"); sprintf((char*)temp, "BOOK %i", calcserial(pBook->more1, pBook->more2, pBook->more3, pBook->more4)); if (!i_scripts[misc_script]->find((char*)temp)) { closescript(); return; } x=p; do { loopexit=0; do { read2(); } while ( (strcmp((char*)script1, "PAGE")) && (++loopexit < MAXLOOPS) ); x--; } while ( (x>0) && (++loopexit2 < 6666 )); closescript(); openscript("misc.scp"); sprintf((char*)temp, "PAGE %s", script2); if (!i_scripts[misc_script]->find((char*)temp)) { closescript(); return; } pos=ftell(scpfile); x=-1; y=-2; loopexit=0; do { read1(); x++; y+=strlen((char*)script1)+1; } while ( (strcmp((char*)script1, "}")) && (++loopexit < MAXLOOPS) ); y+=13; fseek(scpfile, pos, SEEK_SET); bookpage[1]=y>>8; bookpage[2]=y%256; LongToCharPtr(pBook->serial, &bookpage[3]); bookpage[9]=p>>8; bookpage[10]=p%256; bookpage[11]=x>>8; bookpage[12]=x%256; Xsend(s, bookpage, 13); for (j=0;j<x;j++) { read1(); Xsend(s, script1, strlen((char*)script1)+1); } closescript(); }
void cBoat::Turn(P_ITEM pBoat, int turn)//Turn the boat item, and send all the people/items on the boat to turnboatstuff() { if (pBoat == NULL) return; int id2 = pBoat->id2 ,olddir = pBoat->dir; unsigned short int Send[MAXCLIENT]; SERIAL serial; int a,dir, d=0; for (a = 0; a < now; ++a) { if (iteminrange(a, pBoat, BUILDRANGE) && perm[a]) { Send[d]=a; Xsend(a,wppause,2); d++; } } //Of course we need the boat items! serial = calcserial(pBoat->moreb1,pBoat->moreb2,pBoat->moreb3,pBoat->moreb4); if(serial == INVALID_SERIAL) return; P_ITEM pTiller = FindItemBySerial( serial ); if(pTiller == NULL) return; P_ITEM pi_p1 = FindItemBySerial( pBoat->morex ); if(pi_p1 == NULL) return; P_ITEM pi_p2 = FindItemBySerial( pBoat->morey ); if(pi_p2 == NULL) return; P_ITEM pi_hold = FindItemBySerial( pBoat->morez ); if(pi_hold == NULL) return; if(turn)//Right { pBoat->dir+=2; id2++; } else {//Left pBoat->dir-=2; id2--; } if(pBoat->dir>7) pBoat->dir-=4;//Make sure we dont have any DIR errors //if(pBoat->dir<0) pBoat->dir+=4; if(id2<pBoat->more1) id2+=4;//make sure we don't have any id errors either if(id2>pBoat->more2) id2-=4;//Now you know what the min/max id is for :-) pBoat->id2=id2;//set the id if(pBoat->id2==pBoat->more1) pBoat->dir=0;//extra DIR error checking if(pBoat->id2==pBoat->more2) pBoat->dir=6; if( Block( pBoat, 0, 0, pBoat->dir ) ) { pBoat->dir = olddir; for( a = 0; a < d; a++ ) { Xsend( Send[a], restart, 2 ); itemtalk( Send[a], pTiller, "Arr, something's in the way!" ); } return; } pBoat->id2=id2;//set the id if(pBoat->id2==pBoat->more1) pBoat->dir=0;//extra DIR error checking if(pBoat->id2==pBoat->more2) pBoat->dir=6; serial=pBoat->serial; // lb !!! unsigned int ci; vector<SERIAL> vecEntries = imultisp.getData(serial); for (ci = 0; ci < vecEntries.size(); ci++) { P_ITEM pi = FindItemBySerial(vecEntries[ci]); if (pi != NULL) TurnStuff(pBoat, pi, turn); } vecEntries.clear(); vecEntries = cmultisp.getData(serial); for (ci = 0; ci < vecEntries.size(); ci++) { P_CHAR pc = FindCharBySerial(vecEntries[ci]); if (pc != NULL) TurnStuff(pBoat, pc, turn); } //Set the DIR for use in the Offsets/IDs array dir = (pBoat->dir&0x0F)/2; //set it's Z to 0,0 inside the boat pi_p1->MoveTo(pBoat->pos.x,pBoat->pos.y,pi_p1->pos.z); pi_p1->id2 = cShipItems[dir][PORT_P_C];//change the ID pi_p2->MoveTo(pBoat->pos.x,pBoat->pos.y,pi_p2->pos.z); pi_p2->id2=cShipItems[dir][STAR_P_C]; pTiller->MoveTo(pBoat->pos.x,pBoat->pos.y, pTiller->pos.z); pTiller->id2=cShipItems[dir][TILLERID]; pi_hold->MoveTo(pBoat->pos.x,pBoat->pos.y, pi_hold->pos.z); pi_hold->id2=cShipItems[dir][HOLDID]; switch(pBoat->more1)//Now set what size boat it is and move the specail items { case 0x00: case 0x04: pi_p1->moveTo(pi_p1->pos + Coord_cl(iSmallShipOffsets[dir][PORT_PLANK][X], iSmallShipOffsets[dir][PORT_PLANK][Y], 0)); pi_p2->moveTo(pi_p2->pos + Coord_cl(iSmallShipOffsets[dir][STARB_PLANK][X], iSmallShipOffsets[dir][STARB_PLANK][Y], 0)); pTiller->moveTo(pTiller->pos + Coord_cl(iSmallShipOffsets[dir][TILLER][X], iSmallShipOffsets[dir][TILLER][Y], 0)); pi_hold->moveTo(pi_hold->pos + Coord_cl(iSmallShipOffsets[dir][HOLD][X], iSmallShipOffsets[dir][HOLD][Y], 0)); break; case 0x08: case 0x0C: pi_p1->moveTo(pi_p1->pos + Coord_cl(iMediumShipOffsets[dir][PORT_PLANK][X], iMediumShipOffsets[dir][PORT_PLANK][Y], 0) ); pi_p2->moveTo(pi_p2->pos + Coord_cl(iMediumShipOffsets[dir][STARB_PLANK][X], iMediumShipOffsets[dir][STARB_PLANK][Y], 0) ); pTiller->moveTo(pTiller->pos + Coord_cl(iMediumShipOffsets[dir][TILLER][X], iMediumShipOffsets[dir][TILLER][Y], 0) ); pi_hold->moveTo(pi_hold->pos + Coord_cl(iMediumShipOffsets[dir][HOLD][X], iMediumShipOffsets[dir][HOLD][Y], 0) ); break; case 0x10: case 0x14: pi_p1->moveTo(pi_p1->pos + Coord_cl(iLargeShipOffsets[dir][PORT_PLANK][X], iLargeShipOffsets[dir][PORT_PLANK][Y], 0) ); pi_p2->moveTo(pi_p2->pos + Coord_cl(iLargeShipOffsets[dir][STARB_PLANK][X], iLargeShipOffsets[dir][STARB_PLANK][Y], 0 ) ); pTiller->moveTo(pTiller->pos + Coord_cl(iLargeShipOffsets[dir][TILLER][X], iLargeShipOffsets[dir][TILLER][Y], 0 ) ); pi_hold->moveTo(pi_hold->pos + Coord_cl(iLargeShipOffsets[dir][HOLD][X], iLargeShipOffsets[dir][HOLD][Y], 0 ) ); break; default: { sprintf((char*)temp,"Turnboatstuff() more1 error! more1 = %c not found!\n",pBoat->more1); LogWarning((char*)temp); } } sendinrange(pi_p1); sendinrange(pi_p2); sendinrange(pi_hold); sendinrange(pTiller); for (a = 0; a < d; ++a) { Xsend(Send[a],restart,2); } }
void cDragdrop::wear_item(P_CLIENT ps) // Item is dropped on paperdoll { int j, k; tile_st tile; int serial, serhash, ci, letsbounce=0; // AntiChrist (5) - new ITEMHAND system UOXSOCKET s=ps->GetSocket(); int cc=ps->GetCurrChar(); P_CHAR pc_currchar = MAKE_CHARREF_LR(cc); int cserial=calcserial(buffer[s][6],buffer[s][7],buffer[s][8],buffer[s][9]); if(cserial==-1) return; k=calcCharFromSer( cserial ); if( chars[k].dead ) //Exploit fix: Dead ppl can't equip anything. return; P_ITEM pi=FindItemBySerPtr(buffer[s]+1); if (!pi) return; pi->flags.isBeeingDragged=false; // if (clientDimension[s]==3) // { Map->SeekTile(pi->id(), &tile); // sprintf(temp, "Tiledata: name: %s flag1: %i flag2: %i flag3: %i flag4: %i layer: %i\n", tile.name, tile.flag1, tile.flag2, tile.flag3, tile.flag4, tile.layer); // clConsole.send(temp); if (tile.layer==0) { sysmessage(s,"You can't wear that"); Sndbounce5(s); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce4(s,pi); UpdateStatusWindow(s,pi); } return; } // } if (pi->id1>=0x40) return; // LB, client crashfix if multi-objects are moved to PD if (k==DEREF_P_CHAR(pc_currchar) || pc_currchar->isGM()) { if (k!=-1) //lb if (k==DEREF_P_CHAR(pc_currchar) && pi->st>chars[k].st) { sysmessage(s,"You are not strong enough to use that."); Sndbounce5(s); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce4(s,pi); UpdateStatusWindow(s,pi); } return; } if (pc_currchar->id1==0x01 && pc_currchar->id2==0x90) // Ripper...so males cant wear female armor if (pi->id1==0x1c && ( pi->id2==0x00 || pi->id2==0x02 || pi->id2==0x04 || pi->id2==0x06 || pi->id2==0x08 || pi->id2==0x0a || pi->id2==0x0c)) { sysmessage(s,"You cant wear female armor!"); Sndbounce5(s); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce4(s,pi); UpdateStatusWindow(s,pi); } return; } // if (clientDimension[s]==2) Map->SeekTile(pi->id(), &tile); if ((((pi->magic==2)||((tile.weight==255)&&(pi->magic!=1)))&&((pc_currchar->priv2&1)==0)) || ( (pi->magic==3|| pi->magic==4) && !pc_currchar->Owns(pi))) { item_bounce6(ps,pi); return; } // - AntiChrist (4) - checks for new ITEMHAND system // - now you can't equip 2 hnd weapons with 1hnd weapons nor shields!! serial=pc_currchar->serial; vector<SERIAL> vecContainer = contsp.getData(serial); for (ci=0;ci<vecContainer.size();ci++) { P_ITEM pi2 = FindItemBySerial(vecContainer[ci]); if (pi2 != NULL && pi2->contserial == serial) { if (pi2->itmhand==1 && pi->itmhand==1) { sysmessage(s,"You already have a weapon equipped!"); letsbounce=1; } else if (pi2->itmhand==2 && pi->itmhand==1) { sysmessage(s,"Your hands are both occupied!"); letsbounce=1; } else if (pi2->itmhand==1 && pi->itmhand==2) { sysmessage(s,"You cannot equip a two handed weapon with a weapon equipped!"); letsbounce=1; } else if (pi2->itmhand==2 && pi->itmhand==2) { sysmessage(s,"You cannot equip a two handed weapon with a two handed weapon equipped!"); letsbounce=1; } else if (pi2->itmhand==2 && pi->itmhand==3) { sysmessage(s,"You cannot equip a shield with a two handed weapon equipped!"); letsbounce=1; } else if (pi2->itmhand==3 && pi->itmhand==2) { sysmessage(s,"You cannot equip a two handed weapon with a shield equipped!"); letsbounce=1; } else if (pi2->layer == tile.layer) { sysmessage(s, "You already have an armor equipped!"); letsbounce = 1; } } if(letsbounce)//Let's bounce the item { Sndbounce5(s); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce4(s,pi); UpdateStatusWindow(s,pi); itemsfx(s, pi->id()); // antichrist } return; } } if (!(pc_currchar->isGM())) //Ripper..players cant equip items on other players or npc`s paperdolls. { if ((k != DEREF_P_CHAR(pc_currchar)) && (!chars[k].isNpc())) { sysmessage(s, "You cant put items on other players!"); item_bounce6(ps,pi); return; } } pi->SetContSerial(LongFromCharPtr(buffer[s]+6)); pi->layer=buffer[s][5]; // AntiChrist - now the STAT BONUS works - pc_currchar->st = (pc_currchar->st + pi->st2); pc_currchar->chgDex(pi->dx2); pc_currchar->in = (pc_currchar->in + pi->in2); if (pi->trigtype==2) // -Frazurbluu- Trigger Type 2 is my new trigger type *- { Trig->triggerwitem(s, pi, 1); // trigger is fired } // AntiChrist -- for poisoned items if (showlayer) clConsole.send("Item equipped on layer %i.\n",pi->layer); SndRemoveitem(pi->serial); LongToCharPtr(pi->serial,wearitem+1); ShortToCharPtr(pi->id(),wearitem+5); wearitem[8]=pi->layer; LongToCharPtr(pi->contserial,wearitem+9); wearitem[13]=pi->color1; wearitem[14]=pi->color2; Xsend(s, wearitem, 15); wornitems(s, k);//send update to current socket // -Frazurbluu- Worn item triggers will need code here // Trigger cod ewill also need the adjustments made for skill adding // An apply/unapply type of variable must be added for skill gains // Spell Item will have to be considered, like a necklace of reflection for (j=0;j<now;j++) { if (perm[j] && inrange1p(k, currchar[j]) && (j!=s))//and to all inrange sockets (without re-sending to current socket)//AntiChrist wornitems(j, k); } itemsfx(s, pi->id()); // Dupois - see itemsfx() for details // Added Oct 09, 1998 Weight->NewCalc(DEREF_P_CHAR(pc_currchar)); // Ison 2-20-99 statwindow(s,DEREF_P_CHAR(pc_currchar)); if (pi->glow>0) { pc_currchar->removeHalo(pi); // if gm equips on differnt player it needs to be deleted out of the hashteble chars[k].addHalo(pi); chars[k].glowHalo(pi); } } }
pi->color1=c1; pi->color2=c2; } if (((c1<<8)+c2)==17969) { pi->color1=c1; pi->color2=c2; } RefreshItem(pi);//AntiChrist soundeffect( s, 0x02, 0x3e ); // plays the dye sound, LB return; } serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); P_CHAR pc = FindCharBySerial(serial); if (pc != NULL) { P_CHAR pc_currchar = MAKE_CHARREF_LR(currchar[s]); if( !(pc_currchar->isGM() ) ) return; // Only gms dye characters k=(buffer[s][7]<<8)+buffer[s][8]; body=(pc->id1<<8)+pc->id2; b=k&0x4000; if( ( ( k>>8 ) < 0x80 ) && body >= 0x0190 && body <= 0x0193 ) k+= 0x8000; if (b==16384 && (body >=0x0190 && body<=0x03e1)) k=0xf000; // but assigning the only "transparent" value that works, namly semi-trasnparency.
void cBoat::Move(UOXSOCKET s, int dir, P_ITEM pBoat) {//Move the boat and all it's items 1 square int tx=0,ty=0; int serial; if (pBoat == NULL) return; serial = calcserial(pBoat->moreb1, pBoat->moreb2, pBoat->moreb3, pBoat->moreb4); if (serial == INVALID_SERIAL) return; P_ITEM pTiller = FindItemBySerial( serial ); if(pTiller == NULL) return; P_ITEM pi_p1 = FindItemBySerial( pBoat->morex ); if(pi_p1 == NULL) return; P_ITEM pi_p2 = FindItemBySerial( pBoat->morey ); if(pi_p2 == NULL) return; P_ITEM pHold = FindItemBySerial( pBoat->morez ); if(pHold == NULL) return; Xsend(s,wppause,2); switch(dir&0x0F)//Which DIR is it going in? { case '\x00' : ty--; break; case '\x01' : tx++; ty--; break; case '\x02' : tx++; break; case '\x03' : tx++; ty++; break; case '\x04' : ty++; break; case '\x05' : tx--; ty++; break; case '\x06' : tx--; break; case '\x07' : tx--; ty--; break; default: { sprintf((char*)temp,"warning: Boat direction error: %i int boat %i\n",pBoat->dir&0x0F,pBoat->serial); LogWarning((char*)temp); break; } } if((pBoat->pos.x+tx<=200 || pBoat->pos.x+tx>=6000) && (pBoat->pos.y+ty<=200 || pBoat->pos.y+ty>=4900)) //bugfix LB { pBoat->type2=0; itemtalk(s, pTiller, "Arr, Sir, we've hit rough waters!"); Xsend(s,restart,2); return; } if(Block(pBoat,tx,ty,dir)) { pBoat->type2=0; itemtalk(s, pTiller, "Arr, somethings in the way!"); Xsend(s,restart,2); return; } //Move all the special items Coord_cl desloc(tx, ty, 0); pBoat->moveTo(pBoat->pos + desloc); pTiller->moveTo(pTiller->pos + desloc); pi_p1->moveTo(pi_p1->pos + desloc); pi_p2->moveTo(pi_p2->pos + desloc); pHold->moveTo(pHold->pos + desloc); serial = pBoat->serial; unsigned int a; vector<SERIAL> vecEntries = imultisp.getData(pBoat->serial); for (a = 0; a < vecEntries.size(); a++) { P_ITEM pi = FindItemBySerial(vecEntries[a]); if(pi != NULL) { pi->MoveTo(pi->pos.x+=tx, pi->pos.y+=ty, pi->pos.z); sendinrange(pi); } } vecEntries.clear(); vecEntries = cmultisp.getData(pBoat->serial); for (a = 0; a < vecEntries.size(); a++) { P_CHAR pc_c = FindCharBySerial(vecEntries[a]); if (pc_c != NULL) { pc_c->moveTo(pc_c->pos + desloc); teleport((pc_c)); } } Xsend(s,restart,2); }
void RcvAttack(P_CLIENT ps) { UOXSOCKET s = ps->GetSocket(); P_CHAR pc_currchar = ps->getPlayer(); int j; SERIAL serial=calcserial(buffer[s][1],buffer[s][2],buffer[s][3],buffer[s][4]); if(serial == INVALID_SERIAL) return; P_CHAR pc_i = FindCharBySerPtr(&buffer[s][1]); if(pc_i == NULL) return; //to avoid problems if(pc_currchar->dead)//AntiChrist stuff { if(SrvParams->persecute()) {//start persecute stuff - AntiChrist pc_currchar->targ = pc_i->serial; if(pc_currchar->targ==INVALID_SERIAL) return; else Skills->Persecute(s); return; } else { sysmessage(s,"You are dead and cannot do that."); return; } } if(pc_currchar->cell>0) { sysmessage(s,"There is no fighting in the jail cells!"); return; } if(!pc_currchar->dead) { pc_currchar->targ = serial; pc_currchar->unhide(); pc_currchar->disturbMed(s); if(pc_i->dead || pc_i->hp<=0)//AntiChrist { sysmessage(s,"That person is already dead!"); return; } if (pc_i->npcaitype==17)//PlayerVendors { sprintf((char*)temp, "%s cannot be harmed.",pc_i->name.c_str()); sysmessage(s, (char*)temp); return; } SndAttackOK(s, pc_i->serial); //keep the target highlighted if (!(pc_i->targ == INVALID_SERIAL)) { pc_i->attacker = pc_currchar->serial; pc_i->resetAttackFirst(); } pc_currchar->setAttackFirst(); pc_currchar->attacker = pc_i->serial; pc_currchar->dir = chardir(pc_currchar, pc_i); // turn to attacker, LB (& Duke) updatechar(pc_currchar); if( pc_i->guarded ) { AllCharsIterator iter_char; for (iter_char.Begin(); !iter_char.atEnd(); iter_char++) { P_CHAR toCheck = iter_char.GetData(); if (pc_i->Owns(toCheck) && toCheck->npcaitype == 32 && chardist( pc_currchar, toCheck )<= 10 ) { npcattacktarget( pc_currchar, toCheck ); } } } if (pc_i->inGuardedArea() && SrvParams->guardsActive()) { if (pc_i->isPlayer() && pc_i->isInnocent() && GuildCompare( pc_currchar, pc_i )==0) //REPSYS { criminal( pc_currchar ); Combat->SpawnGuard(pc_currchar, pc_i ,pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z); } else if( pc_i->isNpc() && pc_i->isInnocent() && !pc_i->isHuman() && pc_i->npcaitype!=4 ) { criminal( pc_currchar ); Combat->SpawnGuard(pc_currchar, pc_i, pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z); } else if( pc_i->isNpc() && pc_i->isInnocent() && pc_i->isHuman() && pc_i->npcaitype!=4 ) { npctalkall(pc_i, "Help! Guards! I've been attacked!", 1); criminal( pc_currchar ); callguards(pc_i); } else if( pc_i->isNpc() && pc_i->npcaitype==4) { criminal( pc_currchar ); npcattacktarget(pc_i, pc_currchar); } else if ((pc_i->isNpc() || pc_i->tamed) && !pc_i->war && pc_i->npcaitype!=4) // changed from 0x40 to 4, cauz 0x40 was removed LB { npcToggleCombat(pc_i); pc_i->setNextMoveTime(); } else { pc_i->setNextMoveTime(); } sprintf((char*)temp, "You see %s attacking %s!", pc_currchar->name.c_str(), pc_i->name.c_str()); for (j=0;j<now;j++) { if((inrange1(s, j) && perm[j]) && (s!=j)) { pc_i->emotecolor = 0x0026; npcemote(j, pc_currchar, (char*)temp,1); } } } else // not a guarded area { if (pc_i->isInnocent()) { if (pc_i->isPlayer() && GuildCompare( pc_currchar, pc_i )==0) { criminal( pc_currchar ); } else if (pc_i->isNpc() && pc_i->tamed) { criminal( pc_currchar ); npcattacktarget(pc_i, pc_currchar); } else if (pc_i->isNpc()) { criminal( pc_currchar ); npcattacktarget(pc_i, pc_currchar); if (pc_i->isHuman() ) { npctalkall(pc_i, "Help! Guards! Tis a murder being commited!", 1); } } } } } }
char cBoat::Speech(UOXSOCKET s, const QString& msg)//See if they said a command. msg must already be capitalized { P_CHAR pc_currchar = currchar[s]; P_ITEM boat = GetBoat(pc_currchar); if(boat == NULL) return 0; int dir = boat->dir&0x0F; int serial; char msg2[512]; if (s == INVALID_UOXSOCKET) return 0; //get the tiller man's item # serial=calcserial(boat->moreb1, boat->moreb2, boat->moreb3, boat->moreb4); if ( serial == INVALID_SERIAL ) return 0; P_ITEM tiller = FindItemBySerial(serial); if ( tiller == NULL ) return 0; if((msg.find("FORWARD")!= string::npos) || (msg.find("UNFURL SAIL")!=string::npos)) { boat->type2=1;//Moving Move(s,dir, boat); itemtalk(s, tiller, "Aye, sir."); return 1; } else if(msg.find("BACKWARD")!= string::npos) { boat->type2=2;//Moving backward if(dir >= 4) dir-=4; else dir+=4; Move(s,dir, boat); itemtalk(s, tiller, "Aye, sir."); return 1; } else if((msg.find("ONE")!= string::npos) || (msg.find("DRIFT")!=string::npos)) { if(msg.find("LEFT")!=string::npos) { dir-=2; if(dir<0) dir+=8; Move(s, dir, boat); itemtalk(s, tiller, "Aye, sir."); return 1; } else if(msg.find("RIGHT")!=string::npos) { dir+=2; if(dir>=8) dir-=8; Move(s,dir,boat); itemtalk(s, tiller, "Aye, sir."); return 1; } } else if((msg.find("STOP")!=string::npos) || (msg.find("FURL SAIL")!=string::npos)) { boat->type2=0; itemtalk(s, tiller, "Aye, sir."); }//Moving is type2 1 and 2, so stop is 0 :-) else if(((msg.find("TURN")!=string::npos) && ((msg.find("AROUND")!=string::npos) || (msg.find("LEFT")!=string::npos) || (msg.find("RIGHT")!=string::npos))) || (msg.find("PORT")!=string::npos) || (msg.find("STARBOARD")!=string::npos) || (msg.find("COME ABOUT")!=string::npos)) { if((msg.find("RIGHT")!=string::npos) || (msg.find("STARBOARD")!=string::npos)) { dir-=2; if(dir<0) dir+=8; int tx=0,ty=0; switch(dir&0x0F) // little reminder for myself: move this swtich to a function to have less code ... LB { case '\x00' : ty--; break; case '\x01' : tx++; ty--; break; case '\x02' : tx++; break; case '\x03' : tx++; ty++; break; case '\x04' : ty++; break; case '\x05' : tx--; ty++; break; case '\x06' : tx--; break; case '\x07' : tx--; ty--; break; } if (!Block(boat,tx,ty,dir)) { Turn(boat,1); itemtalk(s, tiller, "Aye, sir."); return 1; } else { boat->type2 = 0; itemtalk(s, tiller, "Arr,somethings in the way"); return 1; } } else if((msg.find("LEFT")!=string::npos) || (msg.find("PORT")!=string::npos)) { dir+=2; if(dir>7) dir-=8; int tx=0,ty=0; switch(dir&0x0F) { case '\x00' : ty--; break; case '\x01' : tx++; ty--; break; case '\x02' : tx++; break; case '\x03' : tx++; ty++; break; case '\x04' : ty++; break; case '\x05' : tx--; ty++; break; case '\x06' : tx--; break; case '\x07' : tx--; ty--; break; } if (!Block(boat,tx,ty,dir)) { Turn(boat,0); itemtalk(s, tiller, "Aye, sir."); return 1; } else { boat->type2 = 0; itemtalk(s, tiller, "Arr,somethings in the way"); return 1; } } else if((msg.find("COME ABOUT")!=string::npos) || (msg.find("AROUND")!=string::npos)) { Turn(boat, 1); Turn(boat, 1); itemtalk(s, tiller, "Aye, sir."); return 1; } } else if(msg.find("SET NAME")!=string::npos) { tiller->name = "a ship named "; tiller->name += msg2+8; return 1; } return 0; }
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(); } }