/*! \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; }
/*! \brief Do periodical checks for weather change \author Xanatar */ void check_region_weatherchange () { int r,sn=0, rn=0, dr=0, sm, i; outInfo("performing weather change..."); //! \todo revisit this part for (i=0;i<256;i++) { region_st ®ionRef = region[i]; if ((regionRef.keepchance==0)&&(regionRef.drychance==0)) continue; r = rand()%100; if ((r<=regionRef.keepchance)||(regionRef.keepchance==100)) continue; //we're here, let's change the weeeeather dr = (regionRef.wtype==0) ? 0 : regionRef.drychance; rn = (regionRef.wtype==1) ? 0 : regionRef.rainchance; sn = (regionRef.wtype==2) ? 0 : regionRef.snowchance; if (!regionRef.ignoreseason) { //! \todo actually the calendar system for weather variation during the year wasn't a bad idea, but it should NOT involve 3 float multiplications + 3 float to int and 3 int to float conversions for each region every weathercheck dr = static_cast<int>(static_cast<float>(dr) * Calendar::g_fCurDryMod); rn = static_cast<int>(static_cast<float>(rn) * Calendar::g_fCurRainMod); sn = static_cast<int>(static_cast<float>(sn) * Calendar::g_fCurSnowMod); } sm = dr+rn+sn; r = rand()%sm; if (r < dr) regionRef.wtype = 0; else if (r < (rn+dr)) regionRef.wtype = 1; else regionRef.wtype = 2; } // Chronodt 17/8/04 - begun additional weathercode //! \todo sobstitute temporary region subnames with the true ones when regions redone //! \todo a for cycle with all the regions (cregion is the region currently esamined) //for (whatever will cycle all region, with cregion as index or iterator) { Climates climate = region[cregion].climate; if (climate == clNone) continue; //no weather change for a dungeon WeatherType current = region[cregion].weatherCurrent; sint16_t oldintensity = region[cregion].weatherIntensity; sint16_t newintensity = oldintensity; //Getting the 4 adiacent regions. getXXXXregion should return invalid if such region does not exist uint16_t nregion = getNorthRegion(cregion); uint16_t eregion = getEastRegion(cregion); uint16_t sregion = getSouthRegion(cregion); uint16_t wregion = getWestRegion(cregion); // modifying the intensity by surrounding squares (obiously the old status) newintensity += getIntensityModifier(cregion, nregion); newintensity += getIntensityModifier(cregion, eregion); newintensity += getIntensityModifier(cregion, sregion); newintensity += getIntensityModifier(cregion, wregion); // adding intensity by random raincheck (based on region configuration) //! \todo modify these with new region parameters uint8_t dry = region[cregion].drychance; uint8_t rain = region[cregion].rainchance; uint8_t snow = region[cregion].snowchance; uint8_t r = rand()%100; if (r < dry) newintensity -= (dry - r) * 5; r = rand()%100; if (r < rain) newintensity += (rain - r) * 5; if (newintensity > 140) newintensity = 140; if (newintensity < 0) newintensity = 0; bool snow = false; string message = ""; //! \todo insert a maxlight to limit light in bad beather (but nightvision should counter this) switch (current) //select message type to send clients based on previous weather in region. Also checking if weather change is too sudden, and if so lessen the impact :D { case wtSun: // intensity 0 - 20 if (newintensity > 40) { newintensity = 40; //If it was so clear, we need at least a few clouds in the sky before it can rain (or snow) message = "You see some clouds closing in"; } break; case wtCloud: // intensity 21 - 40 if (newintensity > 90) // to have more than a light rain we need heavier clouds first { newintensity = 70; message = "Cloud covering thickens visibly. You hear rumbling in the distance"; } else if (newintensity <= 20) message = "The sky clears off and the sun shines again"; else if (newintensity > 70) { //snow check r = rand()%100; if (r < snow) snow = true; } break; case wtStormCloud: // intensity 41 - 70 //from this weather type, we can reach every other, since from here it can start raining with any intensity. Or it can snow or even clear up if (newintensity <= 40 && newintensity > 20) message = "The sky begins to clear off"; else if (newintensity <= 20) message = "Strong winds clear away the thick clouds, until the sun shines again"; else if (newintensity > 70) { //snow check r = rand()%100; if (r < snow) snow = true; } break; case wtLightRain: // intensity 71 - 90 if (newintensity < 71) { if (newintensity > 20) message = "The rain is stopping"; else message = "The rain is stopping and the sky clears up"; } else message = "The rain gets stronger"; r = rand()%100; if (climate == clArtic && r < (snow/4)) snow = true; //If artic climate and raining, check if rain becomes snow (at 1/4 of normal snow chance) break; case wtMediumRain: // intensity 91 - 110 if (newintensity <71) { if (newintensity > 40) message = "The rain is stopping"; else { newintensity = 41; message = "The rain is stopping and the sky begins to clear up"; } } else message = "The rain gets stronger"; r = rand()%100; if (climate == clArtic && r < (snow/4)) snow = true; //If artic climate and raining, check if rain becomes snow (at 1/4 of normal snow chance) break; case wtHeavyRain: // intensity 111 - 140 if (newintensity <111) { if (newintensity > 70) message = "The rain begins to slow down"; else { newintensity = 71; message = "The rain has stopped falling, but the sky is still covered up"; } } else message = "The rain gets stronger"; r = rand()%100; if (climate == clArtic && r < (snow/4)) snow = true; //If artic climate and raining, check if rain becomes snow (at 1/4 of normal snow chance) break; case wtLightSnow: // intensity 71 - 90 if (newintensity < 71) { if (newintensity > 20) message = "The snow is stopping"; else message = "The snow is stopping and the sky clears up"; } else message = "The snow gets stronger"; r = rand()%100; if (climate != clNormal || r > ((100 - snow)/4)) snow = true; //If normal climate and snowing, check if snow becomes rain (at 1/4 of normal snow_to_rain chance, the complementary of snow chance) break; case wtMediumSnow: // intensity 91 - 110 if (newintensity <71) { if (newintensity > 40) message = "The snow is stopping"; else { newintensity = 41; message = "The snow is stopping and the sky begins to clear up"; } } else message = "The snow gets stronger"; r = rand()%100; if (climate != clNormal || r > ((100 - snow)/4)) snow = true; //If normal climate and snowing, check if snow becomes rain (at 1/4 of normal snow_to_rain chance, the complementary of snow chance) break; case wtHeavySnow: // intensity 111 - 140 snow = true; if (newintensity <111) { if (newintensity > 70) message = "The snow begins to slow down"; else { newintensity = 71; message = "The snow has stopped falling, but the sky is still covered up"; } } else message = "The snow gets stronger"; r = rand()%100; if (climate != clNormal || r > ((100 - snow)/4)) snow = true; //If normal climate and snowing, check if snow becomes rain (at 1/4 of normal snow_to_rain chance, the complementary of snow chance) break; } if (newintensity <= 20) region[cregion].weatherNew = wtSun; else if (newintensity <= 40) region[cregion].weatherNew = wtCloud; else if (newintensity <= 70) region[cregion].weatherNew = wtStormCloud; else if (newintensity <= 90 && !snow) region[cregion].weatherNew = wtLightRain; else if (newintensity <= 110 && !snow) region[cregion].weatherNew = wtMediumRain; else if (!snow) region[cregion].weatherNew = wtHeavyRain; else if (newintensity <= 90 && snow) region[cregion].weatherNew = wtLightSnow; else if (newintensity <= 110 && snow) region[cregion].weatherNew = wtMediumSnow; else region[cregion].weatherNew = wtHeavySnow; region[cregion].weatherIntensityNew = newintensity; uint8_t weather = 0; is (snow) weather = 0x02; //snow effect if (newintensity <=70) weather = 0xff; //No weather uint8_t intensity = (newintensity > 70) ? newintensity - 70 : newintensity; uint8_t intensity2 = intensity; bool mixedweather = false; if ( ((current == wtLightRain || current == wtMediumRain || current == wtHeavyRain) && snow) || // Rain has just become snow or... ((current == wtLightSnow || current == wtMediumSnow || current == wtHeavySnow) && !snow)) // Snow has just become rain { intensity = rand() % intensity; // randomize % of snow ... intensity2 -= intensity; // ...and the remaining intensity goes to rain weather = 0x2; // snow weather2 = 0x0; // rain mixedweather = true; } //! \todo the limit of light level by weather (it is best to modify existing code in timers.cpp) nPackets::Sent::Weather pk( weather, intensity); nPackets::Sent::Weather pk2( weather2, intensity2); NxwSocketWrapper sw; sw.fillOnline( pos ); //!< \todo change with something like fillOnlineInRegion for( sw.rewind(); !sw.isEmpty(); sw++ ) { pClient j =sw.getSocket(); if( j ) { j->sendPacket(&pk); if (mixedweather) j->sendPacket(&pk2); j->sysmessage(message); } } } // End region for cycle. Now we must build another one to update the weatherIntensity and weatherCurrent of all regions // if you ask why, think of what would happen if you changed them as you process them, since each region takes a little info // from each adiacent region.... :) (yes, this is a system with a memory :D) //! \todo an online iteration of all online chars in region //for (whatever will cycle all regions) { region[cregion].weatherCurrent = region[cregion].weatherNew; region[cregion].weatherIntensity = region[cregion].weatherIntensityNew; } outPlain("[ OK ]\n"); }
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(); } }
void wear_item(NXWCLIENT ps) // Item is dropped on paperdoll { if ( ps == NULL ) return; NXWSOCKET s = ps->toInt(); if (s < 0) return; P_CHAR pc=ps->currChar(); VALIDATEPC( pc ); P_CHAR pck = pointers::findCharBySerPtr(buffer[s]+6); VALIDATEPC( pck ); if( pck->dead ) //Exploit fix: Dead ppl can't equip anything. return; P_ITEM pi=pointers::findItemBySerPtr(buffer[s]+1); VALIDATEPI(pi); bool resetDragging = false; if( (pi->getId()>>8) >= 0x40) // LB, client crashfix if multi-objects are moved to PD resetDragging = true; tile_st tile; int serial/*, letsbounce=0*/; // AntiChrist (5) - new ITEMHAND system data::seekTile(pi->getId(), tile); if( ( clientDimension[s]==3 ) && (tile.quality==0) ) { ps->sysmsg(TRANSLATE("You can't wear that")); resetDragging = true; } else { P_ITEM outmost = pi->getOutMostCont(); P_CHAR vendor = pointers::findCharBySerial( outmost->getContSerial() ); if( ISVALIDPC( vendor ) && ( vendor->getOwnerSerial32() != pc->getSerial32() ) ) { resetDragging = true; } } if( resetDragging ) { Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); item_bounce4(s,pi); UpdateStatusWindow(s,pi); } return; } if ( pck->getSerial32() == pc->getSerial32() || pc->IsGM() ) { if ( !pc->IsGM() && pi->st > pck->getStrength() && !pi->isNewbie() ) // now you can equip anything if it's newbie { ps->sysmsg(TRANSLATE("You are not strong enough to use that.")); resetDragging = true; } else if ( !pc->IsGM() && !checkItemUsability(pc, pi, ITEM_USE_WEAR) ) { resetDragging = true; } else if ( (pc->getId() == BODY_MALE) && ( pi->getId()==0x1c00 || pi->getId()==0x1c02 || pi->getId()==0x1c04 || pi->getId()==0x1c06 || pi->getId()==0x1c08 || pi->getId()==0x1c0a || pi->getId()==0x1c0c ) ) // Ripper...so males cant wear female armor { ps->sysmsg(TRANSLATE("You cant wear female armor!")); resetDragging = true; } else if ((((pi->magic==2)||((tile.weight==255)&&(pi->magic!=1))) && !pc->canAllMove()) || ( (pi->magic==3|| pi->magic==4) && !(pi->getOwnerSerial32()==pc->getSerial32()))) { resetDragging = true; } if( resetDragging ) { Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); item_bounce4(s,pi); UpdateStatusWindow(s,pi); } return; } // - AntiChrist (4) - checks for new ITEMHAND system // - now you can't equip 2 hnd weapons with 1hnd weapons nor shields!! serial= pck->getSerial32(); //xan -> k not cc :) P_ITEM pj = NULL; P_CHAR pc_currchar= pck; // P_ITEM pack= pc_currchar->getBackpack(); //<Luxor> P_ITEM pW = pc_currchar->getWeapon(); if (tile.quality == 1 || tile.quality == 2) { //weapons layers if ( (pi->layer == LAYER_2HANDWEAPON && ISVALIDPI(pc_currchar->getShield())) ) { ps->sysmsg(TRANSLATE("You cannot wear two weapons.")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } if (ISVALIDPI(pW)) { if (pi->itmhand != 3 && pi->lodamage != 0 && pi->itmhand == pW->itmhand) { ps->sysmsg(TRANSLATE("You cannot wear two weapons.")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } } } //</Luxor> int drop[2]= {-1, -1}; // list of items to drop // there no reason for it to be larger int curindex= 0; NxwItemWrapper si; si.fillItemWeared( pc_currchar, false, true, true ); for( si.rewind(); !si.isEmpty(); si++ ) { // we CANNOT directly bounce the item, or the containersearch() function will not work // so we store the item ID in letsbounce, and at the end we bounce the item pj=si.getItem(); if(!ISVALIDPI(pj)) continue; if ((tile.quality == 1) || (tile.quality == 2))// weapons { if (pi->itmhand == 2) // two handed weapons or shield { if (pj->itmhand == 2) drop[curindex++]= DEREF_P_ITEM(pj); if ( (pj->itmhand == 1) || (pj->itmhand == 3) ) drop[curindex++]= DEREF_P_ITEM(pj); } if (pi->itmhand == 3) { if ((pj->itmhand == 2) || pj->itmhand == 3) drop[curindex++]= DEREF_P_ITEM(pj); } if ((pi->itmhand == 1) && ((pj->itmhand == 2) || (pj->itmhand == 1))) drop[curindex++]= DEREF_P_ITEM(pj); } else // not a weapon { if (pj->layer == tile.quality) drop[curindex++]= DEREF_P_ITEM(pj); } } if (ServerScp::g_nUnequipOnReequip) { if (drop[0] > -1) // there is at least one item to drop { for (int i= 0; i< 2; i++) { if (drop[i] > -1) { P_ITEM p_drop=MAKE_ITEM_REF(drop[i]); if(ISVALIDPI(p_drop)) pc_currchar->UnEquip( p_drop, 0); } } } pc->playSFX( itemsfx(pi->getId()) ); // pc_currchar->Equip(pi, 1); // Item is equipped twice ???? } else { if (drop[0] == -1) { pc->playSFX( itemsfx(pi->getId()) ); // pc_currchar->Equip(pi, 1);// Item is equipped twice ???? } else { ps->sysmsg("You cannot wear two weapons."); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } } if (!(pc->IsGM())) //Ripper..players cant equip items on other players or npc`s paperdolls. { if ((pck->getSerial32() != pc->getSerial32())/*&&(chars[s].npc!=k)*/) //-> really don't understand this! :|, xan { ps->sysmsg(TRANSLATE("You can't put items on other people!")); item_bounce6(ps,pi); return; } } NxwSocketWrapper sws; sws.fillOnline( pi ); for( sws.rewind(); !sws.isEmpty(); sws++ ) SendDeleteObjectPkt( sws.getSocket(), pi->getSerial32() ); pi->layer=buffer[s][5]; pi->setContSerial(LongFromCharPtr(buffer[s] +6)); if (g_nShowLayers) InfoOut("Item equipped on layer %i.\n",pi->layer); wearIt(s,pi); NxwSocketWrapper sw; sw.fillOnline( pck, false ); for( sw.rewind(); !sw.isEmpty(); sw++ ) { NXWSOCKET j=sw.getSocket(); if( j!=INVALID ) wornitems(j, pck ); } pc->playSFX( itemsfx(pi->getId()) ); weights::NewCalc(pc); // Ison 2-20-99 statwindow(pc_currchar,pc_currchar); // if (pi->glow>0) // { // pc->removeHalo(pi); // if gm equips on differnt player it needs to be deleted out of the hashteble // pck->addHalo(pi); // pck->glowHalo(pi); // } if ( pck->Equip(pi, 1) == 2) // bypass called { P_ITEM pack = pck->getBackpack(); pc->playSFX( itemsfx(pi->getId()) ); pi->layer= 0; pi->setContSerial( pack->getSerial32() ); sendbpitem(s, pi); return; } } }
void dump_item(NXWCLIENT ps, PKGx08 *pp) // Item is dropped on ground or a character { if (ps == NULL) return; tile_st tile; NXWSOCKET s=ps->toInt(); P_CHAR pc=ps->currChar(); VALIDATEPC(pc); P_ITEM pi=pointers::findItemBySerial(pp->Iserial); if (!ISVALIDPI(pi)) { LogError("client sent bad itemserial %d",pp->Iserial); return; } if ( isCharSerial(pi->getContSerial()) && pi->getContSerial() != pc->getSerial32() ) { P_CHAR pc_i = pointers::findCharBySerial(pi->getContSerial()); if (ISVALIDPC(pc_i)) pc_i->sysmsg("Warning, backpack disappearing bug located!"); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); } if (pi->magic == 2) { //Luxor -- not movable objects if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->MoveTo( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } if(pi!=NULL) { weights::NewCalc(pc); statwindow(pc,pc); } //Ripper...so order/chaos shields disappear when on ground. if( pi->getId()==0x1BC3 || pi->getId()==0x1BC4 ) { pc->playSFX( 0x01FE); staticeffect(DEREF_P_CHAR(pc), 0x37, 0x2A, 0x09, 0x06); pi->Delete(); return; } //test UOP blocking Tauriel 1-12-99 if (!pi->isInWorld()) { item_bounce6(ps,pi); return; } data::seekTile(pi->getId(), tile); if (!pc->IsGM() && ((pi->magic==2 || (tile.weight==255 && pi->magic!=1))&&!pc->canAllMove()) || ( (pi->magic==3 || pi->magic==4) && !(pi->getOwnerSerial32()==pc->getSerial32()))) { item_bounce6(ps,pi); return; } if (buffer[s][5]!=(unsigned char)'\xFF') { if (pi->amxevents[EVENT_IDROPINLAND]!=NULL) { g_bByPass = false; pi->MoveTo(pp->TxLoc,pp->TyLoc,pp->TzLoc); pi->amxevents[EVENT_IDROPINLAND]->Call( pi->getSerial32(), pc->getSerial32() ); if (g_bByPass) { pi->Refresh(); return; } } /* //<Luxor> g_bByPass = false; pi->runAmxEvent( EVENT_IDROPINLAND, pi->getSerial32(), pc->getSerial32() ); if (g_bByPass) { pi->Refresh(); return; } //</Luxor> */ NxwSocketWrapper sw; sw.fillOnline( pi ); for( sw.rewind(); !sw.isEmpty(); sw++ ) { SendDeleteObjectPkt( sw.getSocket(), pi->getSerial32() ); } pi->MoveTo(pp->TxLoc,pp->TyLoc,pp->TzLoc); pi->setContSerial(-1); P_ITEM p_boat = Boats->GetBoat(pi->getPosition()); if(ISVALIDPI(p_boat)) { pi->SetMultiSerial(p_boat->getSerial32()); } pi->Refresh(); } else { if ( !ItemDroppedOnChar(ps, pp, pi) ) { //<Luxor>: Line of sight check //This part avoids the circle of transparency walls bug //----- if ( !lineOfSight( pc->getPosition(), Loc( pp->TxLoc, pp->TyLoc, pp->TzLoc ) ) ) { ps->sysmsg(TRANSLATE("You cannot place an item there!")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } //</Luxor> //<Luxor> Items count check if (!pc->IsGM()) { NxwItemWrapper si; si.fillItemsAtXY( pp->TxLoc, pp->TyLoc ); if (si.size() >= 2) { //Only 2 items permitted ps->sysmsg(TRANSLATE("There is not enough space there!")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } if (ISVALIDPI(pc->getBackpack())) { pi->setCont(pc->getBackpack()); pi->SetRandPosInCont(pc->getBackpack()); } else { pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); } pi->layer = pi->oldlayer; pi->Refresh(); return; } } //</Luxor> } weights::NewCalc(pc); // Ison 2-20-99 statwindow(pc,pc); pc->playSFX( itemsfx(pi->getId()) ); //Boats ! if (pc->getMultiSerial32() > 0) //How can they put an item in a multi if they aren't in one themselves Cut lag by not checking everytime something is put down { P_ITEM multi = pointers::findItemBySerial( pc->getMultiSerial32() ); if (ISVALIDPI(multi)) { //setserial(DEREF_P_ITEM(pi),DEREF_P_ITEM(multi),7); pi->SetMultiSerial(multi->getSerial32()); } } //End Boats } }