/*! \brief gets world coordinates from a serial \author Xanathar \param sr serial \param px x coordinate \param py y coordinate \param pz z coordinate \param ch eventual index to char \param it eventual index to item */ void getWorldCoordsFromSerial (int sr, UI16& px, UI16& py, SI08& pz, int& ch, int& it) { int serial = sr; int loop = 0; it = ch = INVALID; P_CHAR pc=0; P_ITEM pi=0; while ((++loop) < 500) { pc=pointers::findCharBySerial(serial); ch = DEREF_P_CHAR(pc); pi=pointers::findItemBySerial(serial); it = DEREF_P_ITEM(pi); if (ISVALIDPI(pi)) { if (pi->getContSerial()!=INVALID) { serial = pi->getContSerial(); continue; } } break; } if (ISVALIDPC(pc)) { Location charpos= pc->getPosition(); px = charpos.x; py = charpos.y; pz = charpos.z; } else if ( ISVALIDPI(pi) && (pi->getContSerial()==INVALID)) { px = pi->getPosition("x"); py = pi->getPosition("y"); pz = pi->getPosition("z"); } else { px = 0; py = 0; pz = 0; } }
/*! \brief Double click \author Ripper, rewrite by Endymion \param ps client of player dbclick \note Completely redone by Morrolan 20-07-99 \warning I use a define CASE for make more readable the code, if you change name of P_ITEM pi chage also the macro \todo los */ void doubleclick(NXWCLIENT ps) { if(ps==NULL) return; P_CHAR pc = ps->currChar(); VALIDATEPC( pc ); NXWSOCKET s = ps->toInt(); // the 0x80 bit in the first byte is used later for "keyboard" and should be ignored SERIAL serial = LongFromCharPtr(buffer[s] +1) & 0x7FFFFFFF; if (isCharSerial(serial)) { P_CHAR pd=pointers::findCharBySerial(serial); if(ISVALIDPC(pd)) dbl_click_character(ps, pd); return; } P_ITEM pi = pointers::findItemBySerial(serial); VALIDATEPI(pi); if (pi->amxevents[EVENT_IONDBLCLICK]!=NULL) { g_bByPass = false; pi->amxevents[EVENT_IONDBLCLICK]->Call( pi->getSerial32(), pc->getSerial32() ); if (g_bByPass==true) return; } /* g_bByPass = false; pi->runAmxEvent( EVENT_IONDBLCLICK, pi->getSerial32(), s ); if (g_bByPass==true) return; */ if (!checkItemUsability(pc , pi, ITEM_USE_DBLCLICK)) return; Location charpos= pc->getPosition(); if (pc->IsHiddenBySpell()) return; //Luxor: cannot use items if under invisible spell if ( !pc->IsGM() && pc->objectdelay >= uiCurrentTime ) { pc->sysmsg(TRANSLATE("You must wait to perform another action.")); return; } else pc->objectdelay = SrvParms->objectdelay * MY_CLOCKS_PER_SEC + uiCurrentTime; ///MODIFY, CANT CLICK ITEM AT DISTANCE >2////////////// if ( (pc->distFrom(pi)>2) && !pc->IsGM() && !(pc->nxwflags[0] & cChar::flagSpellTelekinesys) ) //Luxor: let's check also for the telekinesys spell { pc->sysmsg( TRANSLATE("Must be closer to use this!")); pc->objectdelay=0; return; } //<Anthalir> VARIAIBLI tile_st item; P_ITEM pack= pc->getBackpack(); VALIDATEPI( pack ); data::seekTile( pi->getId(), item ); //////FINEVARIABILI if ( ServerScp::g_nEquipOnDclick ) { // equip the item only if it is in the backpack of the player if ((pi->getContSerial() == pack->getSerial32()) && (item.quality != 0) && (item.quality != LAYER_BACKPACK) && (item.quality != LAYER_MOUNT)) { int drop[2]= {-1, -1}; // list of items to drop, there no reason for it to be larger int curindex= 0; NxwItemWrapper wea; wea.fillItemWeared( pc, true, true, true ); for( wea.rewind(); !wea.isEmpty(); wea++ ) { P_ITEM pj=wea.getItem(); if(!ISVALIDPI(pj)) continue; if ((item.quality == LAYER_1HANDWEAPON) || (item.quality == LAYER_2HANDWEAPON))// 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 == item.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->UnEquip( p_drop ); } } } pc->playSFX( itemsfx(pi->getId()) ); pc->Equip( pi ); } else { if (drop[0] == -1) { pc->playSFX( itemsfx(pi->getId()) ); pc->Equip( pi ); } } return; } } // </Anthalir> //<Luxor>: Circle of transparency bug fix P_ITEM pCont; Location dst; pCont = pi->getOutMostCont(); if(pCont->isInWorld()) { dst = pCont->getPosition(); } else { P_CHAR pg_dst = pointers::findCharBySerial( pCont->getContSerial() ); VALIDATEPC(pg_dst); dst = pg_dst->getPosition(); } Location charPos = pc->getPosition(); charPos.z = dst.z; charPos.dispz = dst.dispz; if ( !pc->IsGM() && !lineOfSight( charPos, dst ) && !(pc->nxwflags[0] & cChar::flagSpellTelekinesys) ) { pc->sysmsg( TRANSLATE( "You cannot reach the item" ) ); return; } //</Luxor> P_CHAR itmowner = pi->getPackOwner(); if(!pi->isInWorld()) { if (isItemSerial(pi->getContSerial()) && pi->type != ITYPE_CONTAINER) {// Cant use stuff that isn't in your pack. if ( ISVALIDPC(itmowner) && (itmowner->getSerial32()!=pc->getSerial32()) ) return; } else if (isCharSerial(pi->getContSerial()) && pi->type!=(UI32)INVALID) {// in a character. P_CHAR wearedby = pointers::findCharBySerial(pi->getContSerial()); if (ISVALIDPC(wearedby)) if (wearedby->getSerial32()!=pc->getSerial32() && pi->layer!=LAYER_UNUSED_BP && pi->type!=ITYPE_CONTAINER) return; } } if ((pi->magic==4) && (pi->secureIt==1)) { if (!pc->isOwnerOf(pi) || !pc->IsGMorCounselor()) { pc->sysmsg( TRANSLATE("That is a secured chest!")); return; } } if (pi->magic == 4) { pc->sysmsg( TRANSLATE("That item is locked down.")); return; } if (pc->dead && pi->type!=ITYPE_RESURRECT) // if you are dead and it's not an ankh, FORGET IT! { pc->sysmsg(TRANSLATE("You may not do that as a ghost.")); return; } else if (!pc->IsGMorCounselor() && pi->layer!=0 && !pc->IsWearing(pi)) {// can't use other people's things! if (!(pi->layer==LAYER_BACKPACK && SrvParms->rogue==1)) // bugfix for snooping not working, LB { pc->sysmsg(TRANSLATE("You cannot use items equipped by other players.")); return; } } // Begin checking objects that we force an object delay for (std objects) // start trigger stuff if (pi->trigger > 0) { if (pi->trigtype == 0) { if ( TIMEOUT( pi->disabled ) ) // changed by Magius(CHE) § { triggerItem(s, pi, TRIGTYPE_DBLCLICK); // if players uses trigger return; } else { if ( pi->disabledmsg!=NULL ) pc->sysmsg("%s", pi->disabledmsg->c_str()); else pc->sysmsg(TRANSLATE("That doesnt seem to work right now.")); return; } } else { pc->sysmsg( TRANSLATE("You are not close enough to use that.")); return; } } // check this on trigger in the event that the .trigger property is not set on the item // trigger code. Check to see if item is envokable by id else if (checkenvoke( pi->getId() )) { pc->envokeitem = pi->getSerial32(); pc->envokeid = pi->getId(); P_TARGET targ = clientInfo[s]->newTarget( new cObjectTarget() ); targ->code_callback=target_envoke; targ->send( ps ); ps->sysmsg( TRANSLATE("What will you use this on?")); return; } // end trigger stuff // BEGIN Check items by type int los = 0; BYTE map1[20] = "\x90\x40\x01\x02\x03\x13\x9D\x00\x00\x00\x00\x13\xFF\x0F\xFF\x01\x90\x01\x90"; BYTE map2[12] = "\x56\x40\x01\x02\x03\x05\x00\x00\x00\x00\x00"; // By Polygon: This one is needed to show the location on treasure maps BYTE map3[12] = "\x56\x40\x01\x02\x03\x01\x00\x00\x00\x00\x00"; P_TARGET targ = NULL; switch (pi->type) { case ITYPE_RESURRECT: // Check for 'resurrect item type' this is the ONLY type one can use if dead. if (pc->dead) { pc->resurrect(); pc->sysmsg(TRANSLATE("You have been resurrected.")); return; } else { pc->sysmsg(TRANSLATE("You are already living!")); return; } case ITYPE_BOATS:// backpacks - snooping a la Zippy - add check for SrvParms->rogue later- Morrolan if (pi->type2 == 3) { switch( pi->getId() & 0xFF ) { case 0x84: case 0xD5: case 0xD4: case 0x89: Boats->PlankStuff(pc, pi); break; default: pc->sysmsg( TRANSLATE("That is locked.")); break; } return; } case ITYPE_CONTAINER: // bugfix for snooping not working, lb case ITYPE_UNLOCKED_CONTAINER: // Wintermute: GMs or Counselors should be able to open trapped containers always if (pi->moreb1 > 0 && !pc->IsGMorCounselor()) { magic::castAreaAttackSpell(pi->getPosition("x"), pi->getPosition("y"), magic::SPELL_EXPLOSION); pi->moreb1--; } //Magic->MagicTrap(currchar[s], pi); // added by AntiChrist // only 1 and 63 can be trapped, so pleaz leave it here :) - Anti case ITYPE_NODECAY_ITEM_SPAWNER: // nodecay item spawner..Ripper case ITYPE_DECAYING_ITEM_SPAWNER: // decaying item spawner..Ripper if (pi->isInWorld() || (pc->IsGMorCounselor()) || // Backpack in world - free access to everyone ( isCharSerial(pi->getContSerial()) && pi->getContSerial()==pc->getSerial32())) // primary pack { pc->showContainer(pi); pc->objectdelay=0; return; } else if( isItemSerial(pi->getContSerial()) ) { P_ITEM pio = pi->getOutMostCont(); if (pio->getContSerial()==pc->getSerial32() || pio->isInWorld() ) { pc->showContainer(pi); pc->objectdelay=0; return; } } if(ISVALIDPC(itmowner)) snooping(pc, pi ); return; case ITYPE_TELEPORTRUNE: targ = clientInfo[s]->newTarget( new cLocationTarget() ); targ->code_callback = target_tele; targ->send( ps ); ps->sysmsg( TRANSLATE("Select teleport target.")); return; case ITYPE_KEY: targ = clientInfo[s]->newTarget( new cItemTarget() ); targ->code_callback = target_key; targ->buffer[0]= pi->more1; targ->buffer[1]= pi->more2; targ->buffer[2]= pi->more3; targ->buffer[3]= pi->more4; targ->send( ps ); ps->sysmsg( TRANSLATE("Select item to use the key on.")); return; case ITYPE_LOCKED_ITEM_SPAWNER: case ITYPE_LOCKED_CONTAINER: // Added traps effects by AntiChrist // Wintermute: GMs or Counselors should be able to open locked containers always if ( !pc->IsGMorCounselor() ) { if (pi->moreb1 > 0 ) { magic::castAreaAttackSpell(pi->getPosition().x, pi->getPosition().y, magic::SPELL_EXPLOSION); pi->moreb1--; } pc->sysmsg(TRANSLATE("This item is locked.")); return; } else { pc->showContainer(pi); return; } case ITYPE_SPELLBOOK: if (ISVALIDPI(pack)) // morrolan if(pi->getContSerial()==pack->getSerial32() || pc->IsWearing(pi)) ps->sendSpellBook(pi); else pc->sysmsg(TRANSLATE("If you wish to open a spellbook, it must be equipped or in your main backpack.")); return; case ITYPE_MAP: LongToCharPtr(pi->getSerial32(), map1 +1); map2[1] = map1[1]; map2[2] = map1[2]; map2[3] = map1[3]; map2[4] = map1[4]; /* By Polygon: Assign areas and map size before sending */ map1[7] = pi->more1; // Assign topleft x map1[8] = pi->more2; map1[9] = pi->more3; // Assign topleft y map1[10] = pi->more4; map1[11] = pi->moreb1; // Assign lowright x map1[12] = pi->moreb2; map1[13] = pi->moreb3; // Assign lowright y map1[14] = pi->moreb4; int width, height; // Tempoary storage for w and h; width = 134 + (134 * pi->morez); // Calculate new w and h height = 134 + (134 * pi->morez); ShortToCharPtr(width, map1 +15); ShortToCharPtr(height, map1 +17); // END OF: By Polygon Xsend(s, map1, 19); //AoS/ Network->FlushBuffer(s); Xsend(s, map2, 11); //AoS/ Network->FlushBuffer(s); return; case ITYPE_BOOK: Books::DoubleClickBook(s, pi); return; case ITYPE_DOOR: dooruse(s, pi); return; case ITYPE_LOCKED_DOOR: // Wintermute: GMs or Counselors should be able to open locked doors always if ( pc->IsGMorCounselor()) { dooruse(s, pi); return; } if (ISVALIDPI(pack)) { NxwItemWrapper si; si.fillItemsInContainer( pack ); for( si.rewind(); !si.isEmpty(); si++ ) { P_ITEM pj = si.getItem(); if (ISVALIDPI(pj) && pj->type==ITYPE_KEY) if (((pj->more1 == pi->more1) && (pj->more2 == pi->more2) && (pj->more3 == pi->more3) && (pj->more4 == pi->more4)) ) { pc->sysmsg(TRANSLATE("You quickly unlock, use, and then relock the door.")); dooruse(s, pi); return; } } } pc->sysmsg(TRANSLATE("This door is locked.")); return; case ITYPE_FOOD: if (pc->hunger >= 6) { pc->sysmsg( TRANSLATE("You are simply too full to eat any more!")); return; } else { switch (RandomNum(0, 2)) { case 0: pc->playSFX(0x3A); break; case 1: pc->playSFX(0x3B); break; case 2: pc->playSFX(0x3C); break; } switch (pc->hunger) { case 0: pc->sysmsg( TRANSLATE("You eat the food, but are still extremely hungry.")); break; case 1: pc->sysmsg( TRANSLATE("You eat the food, but are still extremely hungry.")); break; case 2: pc->sysmsg( TRANSLATE("After eating the food, you feel much less hungry.")); break; case 3: pc->sysmsg( TRANSLATE("You eat the food, and begin to feel more satiated.")); break; case 4: pc->sysmsg( TRANSLATE("You feel quite full after consuming the food.")); break; case 5: pc->sysmsg( TRANSLATE("You are nearly stuffed, but manage to eat the food.")); break; default: pc->sysmsg( TRANSLATE("You are simply too full to eat any more!")); break; } if (pi->poisoned) { pc->sysmsg(TRANSLATE("The food was poisoned!")); pc->applyPoison(PoisonType(pi->poisoned)); } pi->ReduceAmount(1); pc->hunger++; } return; case ITYPE_WAND: // -Fraz- Modified and tuned up, Wands must now be equipped or in pack case ITYPE_MANAREQ_WAND: // magic items requiring mana (xan) if (ISVALIDPI(pack)) { if (pi->getContSerial() == pack->getSerial32() || pc->IsWearing(pi)) { if (pi->morez != 0) { pi->morez--; if (magic::beginCasting( static_cast<magic::SpellId>((8*(pi->morex - 1)) + pi->morey - 1), ps, (pi->type==ITYPE_WAND) ? magic::CASTINGTYPE_ITEM : magic::CASTINGTYPE_NOMANAITEM)) { if (pi->morez == 0) { pi->type = pi->type2; pi->morex = 0; pi->morey = 0; pi->offspell = 0; } } } } else { pc->sysmsg(TRANSLATE("If you wish to use this, it must be equipped or in your backpack.")); } } return; // case 15 (magic items) /*////////////////////REMOVE///////////////////////////////////// case 18: // crystal ball? switch (RandomNum(0, 9)) { case 0: itemmessage(s, TRANSLATE("Seek out the mystic llama herder."), pi->getSerial32()); break; case 1: itemmessage(s, TRANSLATE("Wherever you go, there you are."), pi->getSerial32()); break; case 4: itemmessage(s, TRANSLATE("The message appears to be too cloudy to make anything out of it."), pi->getSerial32()); break; case 5: itemmessage(s, TRANSLATE("You have just lost five strength.. not!"), pi->getSerial32()); break; case 6: itemmessage(s, TRANSLATE("You're really playing a game you know"), pi->getSerial32()); break; case 7: itemmessage(s, TRANSLATE("You will be successful in all you do."), pi->getSerial32()); break; case 8: itemmessage(s, TRANSLATE("You are a person of culture."), pi->getSerial32()); break; default: itemmessage(s, TRANSLATE("Give me a break! How much good fortune do you expect!"), pi->getSerial32()); break; }// switch soundeffect2(pc_currchar, 0x01EC); return;// case 18 (crystal ball?) */////////////////////ENDREMOVE///////////////////////////////////// case ITYPE_POTION: // potions if (pi->morey != 3) pc->drink(pi); //Luxor: delayed potions drinking else //explosion potion usepotion(pc, pi); return; case ITYPE_RUNE: if (pi->morex==0 && pi->morey==0 && pi->morez==0) { pc->sysmsg( TRANSLATE("That rune is not yet marked!")); } else { pc->runeserial = pi->getSerial32(); pc->sysmsg( TRANSLATE("Enter new rune name.")); } return; case ITYPE_SMOKE: pc->smoketimer = pi->morex*MY_CLOCKS_PER_SEC + getclock(); pi->ReduceAmount(1); return; case ITYPE_RENAME_DEED: pc->namedeedserial = pi->getSerial32(); pc->sysmsg( TRANSLATE("Enter your new name.")); pi->ReduceAmount(1); return; case ITYPE_POLYMORPH: pc->setId( pi->morex ); pc->teleport(); pi->type = ITYPE_POLYMORPH_BACK; return; case ITYPE_POLYMORPH_BACK: pc->setId( pc->getOldId() ); pc->teleport(); pi->type = ITYPE_POLYMORPH; return; case ITYPE_ARMY_ENLIST: enlist(s, pi->morex); pi->Delete(); return; case ITYPE_TELEPORT: pc->MoveTo( pi->morex,pi->morey,pi->morez ); pc->teleport(); return; case ITYPE_DRINK: switch (rand()%2) { case 0: pc->playSFX(0x0031); break; case 1: pc->playSFX(0x0030); break; } pi->ReduceAmount(1); pc->sysmsg( TRANSLATE("Gulp !")); return; case ITYPE_GUILDSTONE: if ( pi->getId() == 0x14F0 || pi->getId() == 0x1869 ) // Check for Deed/Teleporter + Guild Type { pc->fx1 = DEREF_P_ITEM(pi); Guilds->StonePlacement(s); return; } else if (pi->getId() == 0x0ED5) // Check for Guildstone + Guild Type { pc->fx1 = DEREF_P_ITEM(pi); Guilds->Menu(s, 1); return; } else WarnOut("Unhandled guild item type named: %s with ID of: %X\n", pi->getCurrentNameC(), pi->getId()); return; case ITYPE_PLAYER_VENDOR_DEED: // PlayerVendors deed { P_CHAR vendor = npcs::AddNPCxyz(-1, 2117, charpos.x, charpos.y, charpos.z); if ( !ISVALIDPC(vendor) ) { WarnOut("npc-script couldnt find vendor !\n"); return; } los = 0; vendor->npcaitype = NPCAI_PLAYERVENDOR; vendor->MakeInvulnerable(); vendor->unHide(); vendor->stealth=INVALID; vendor->dir = pc->dir; vendor->npcWander = WANDER_NOMOVE; vendor->SetInnocent(); vendor->setOwnerSerial32( pc->getSerial32() ); vendor->tamed = false; pi->Delete(); vendor->teleport(); char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var sprintf( temp, TRANSLATE("Hello sir! My name is %s and i will be working for you."), vendor->getCurrentNameC()); vendor->talk(s, temp, 0); return; } case ITYPE_TREASURE_MAP: Skills::Decipher(pi, s); return; case ITYPE_DECIPHERED_MAP: map1[ 1] = map2[1] = map3[1] = pi->getSerial().ser1; map1[ 2] = map2[2] = map3[2] = pi->getSerial().ser2; map1[ 3] = map2[3] = map3[3] = pi->getSerial().ser3; map1[ 4] = map2[4] = map3[4] = pi->getSerial().ser4; map1[ 7] = pi->more1; // Assign topleft x map1[ 8] = pi->more2; map1[ 9] = pi->more3; // Assign topleft y map1[10] = pi->more4; map1[11] = pi->moreb1; // Assign lowright x map1[12] = pi->moreb2; map1[13] = pi->moreb3; // Assign lowright y map1[14] = pi->moreb4; ShortToCharPtr(0x0100, map1 +15); // Let width and height be 256 ShortToCharPtr(0x0100, map1 +17); Xsend(s, map1, 19); //AoS/ Network->FlushBuffer(s); Xsend(s, map2, 11); //AoS/ Network->FlushBuffer(s); // Generate message to add a map point SI16 posx, posy; // tempoary storage for map point SI16 tlx, tly, lrx, lry; // tempoary storage for map extends tlx = (pi->more1 << 8) | pi->more2; tly = (pi->more3 << 8) | pi->more4; lrx = (pi->moreb1 << 8) | pi->moreb2; lry = (pi->moreb3 << 8) | pi->moreb4; posx = (256 * (pi->morex - tlx)) / (lrx - tlx); // Generate location for point posy = (256 * (pi->morey - tly)) / (lry - tly); ShortToCharPtr(posx, map3 +7); // Store the point position ShortToCharPtr(posy, map3 +9); Xsend(s, map3, 11); // Fire data to client :D //AoS/ Network->FlushBuffer(s); return; default: break; } ///END IDENTIFICATION BY TYPE /////////////////READ UP :D//////////////////////////////// ///BEGIN IDENTIFICATION BY ID if (pi->IsSpellScroll()) { if (ISVALIDPI(pack)) if( pi->getContSerial()==pack->getSerial32()) { magic::SpellId spn = magic::spellNumberFromScrollId(pi->getId()); // avoid reactive armor glitch if ((spn>=0)&&(magic::beginCasting(spn, ps, magic::CASTINGTYPE_SCROLL))) pi->ReduceAmount(1); // remove scroll if successful } else pc->sysmsg(TRANSLATE("The scroll must be in your backpack to envoke its magic.")); } CASE(IsAnvil) { targ = clientInfo[s]->newTarget( new cItemTarget() ); targ->code_callback=Skills::target_repair; targ->send( ps ); ps->sysmsg( TRANSLATE("Select item to be repaired.")); } CASE(IsAxe) { targ = clientInfo[s]->newTarget( new cTarget() ); targ->code_callback=target_axe; targ->buffer[0]=pi->getSerial32(); targ->send( ps ); ps->sysmsg( TRANSLATE("What would you like to use that on ?")); } CASEOR(IsFeather, IsShaft) { targ = clientInfo[s]->newTarget( new cItemTarget() ); targ->buffer[0]= pi->getSerial32(); targ->code_callback=Skills::target_fletching; targ->send( ps ); ps->sysmsg( TRANSLATE("What would you like to use this with?")); }
void wear_item(P_CLIENT ps) // Item is dropped on paperdoll { int j, k; tile_st tile; int serial, serhash, ci, i2, 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; // 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==cc || pc_currchar->isGM()) { if (k!=-1) //lb if (k==cc && 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; serhash=serial%HASHMAX; vector<SERIAL> vecContainer = contsp.getData(serial); for (ci=0;ci<vecContainer.size();ci++) { i2=calcItemFromSer(vecContainer[ci]); if (i2!=-1 && items[i2].contserial==serial) { if (items[i2].itmhand==1 && pi->itmhand==1) { sysmessage(s,"You already have a weapon equipped!"); letsbounce=1; } else if (items[i2].itmhand==2 && pi->itmhand==1) { sysmessage(s,"Your hands are both occupied!"); letsbounce=1; } else if (items[i2].itmhand==1 && pi->itmhand==2) { sysmessage(s,"You cannot equip a two handed weapon with a weapon equipped!"); letsbounce=1; } else if (items[i2].itmhand==2 && pi->itmhand==2) { sysmessage(s,"You cannot equip a two handed weapon with a two handed weapon equipped!"); letsbounce=1; } else if (items[i2].itmhand==2 && pi->itmhand==3) { sysmessage(s,"You cannot equip a shield with a two handed weapon equipped!"); letsbounce=1; } else if (items[i2].itmhand==3 && pi->itmhand==2) { sysmessage(s,"You cannot equip a two handed weapon with a shield equipped!"); letsbounce=1; } else if (items[i2].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; } } // - AntiChrist (5) - ITEMHAND CHECKS END - // probably these next checks could be removed with the ITEMHAND thing - AntiChrist /*if ( pc_currchar->getShield() && (buffer[s][5]==2) ) //Morrolan test { sysmessage(s, "You already have a shield equiped! You must unequip it to use this."); item_bounce6(ps,pi); return; } if ( pc_currchar->getWeapon() && (buffer[s][5]==1) )//Morrolan test { sysmessage(s, "You already have a weapon equiped!"); item_bounce6(ps,pi); return; }*/ if (!(pc_currchar->isGM())) //Ripper..players cant equip items on other players or npc`s paperdolls. { if ((k != cc) && (!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 *- { triggerwitem(s, DEREF_P_ITEM(pi), 1); // trigger is fired } // AntiChrist -- for poisoned items if(pi->poisoned) { if(pc_currchar->poisoned< (pi->poisoned)) pc_currchar->poisoned=pi->poisoned; } 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(cc); // Ison 2-20-99 statwindow(s,cc); 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); } } }
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 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 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 cTmpEff::Expire() { int mortar,k,ccc; int s=calcCharFromSer(getDest()); if ( num != 9 // grinding && num != 10 // create potion && num != 13 // door close && num != 14 // training dummy && num != 17) // explosion { //Added by TANiS to fix errors, memory corruption and door auto-close 10-6-98 // Check to see if it's a dead char and delete the wrong effect, or if it's just // a door auto-close effect and process it the right way. if ( s < 0 || s >= cmem ) { return; // just remove this effect } //End of TANiS' change } // P_CHAR pc_s = MAKE_CHARREF_LR(s); // enabling this reveals a nasty bug I have not found yet: some effects will not work (Duke,13.8.01) P_CHAR pc_s = MAKE_CHAR_REF(s); switch(num) { case 1: if (pc_s->priv2&0x02) { pc_s->priv2 &= 0xFD; int sk=calcSocketFromChar(s); if (sk!=-1) sysmessage(sk, "You are no longer frozen."); Magic->afterParticles(38, s); } break; case 2: pc_s->fixedlight='\xFF'; dolight(calcSocketFromChar(s), worldbrightlevel); break; case 3: pc_s->chgDex(more1); statwindow(calcSocketFromChar(s), s); break; case 4: pc_s->in+=more1; statwindow(calcSocketFromChar(s), s); break; case 5: pc_s->st+=more1; statwindow(calcSocketFromChar(s), s); break; case 6: pc_s->chgDex(-1 * more1); pc_s->stm=min(pc_s->stm, (int)pc_s->effDex()); statwindow(calcSocketFromChar(s), s); break; case 7: pc_s->in-=more1; pc_s->mn=min(pc_s->mn, pc_s->in); statwindow(calcSocketFromChar(s), s); break; case 8: pc_s->st-=more1; pc_s->hp=min(pc_s->hp, pc_s->st); statwindow(calcSocketFromChar(s), s); break; case 9: if (more1 == 0) { if (more2!=0) { sprintf((char*)temp, "*%s continues grinding.*", pc_s->name); npcemoteall(s, (char*)temp,1); } soundeffect2(s, 0x02, 0x42); } break; case 10: s=calcCharFromSer(getSour()); mortar=calcItemFromSer(getDest()); if(mortar>-1) //AntiChrist - to prevent crashes Skills->CreatePotion(s, more1, more2, mortar); break; case 11: pc_s->st-=more1; pc_s->hp=min(pc_s->hp, pc_s->st); pc_s->chgDex(-1 * more2); pc_s->stm=min(pc_s->stm, (int)pc_s->effDex()); pc_s->in-=more3; pc_s->mn=min(pc_s->mn, pc_s->in); statwindow(calcSocketFromChar(s), s); break; case 12: pc_s->st+=more1; pc_s->chgDex(more2); pc_s->in+=more3; statwindow(calcSocketFromChar(s), s); break; case 13: { P_ITEM pDoor = FindItemBySerial(getDest());// door if (pDoor) { if (pDoor->dooropen==0) break; pDoor->dooropen=0; dooruse(calcSocketFromChar(s), DEREF_P_ITEM(pDoor)); } break; } case 14: //- training dummies Tauriel check to see if item moved or not before searching for it { P_ITEM pTrainDummy = FindItemBySerial(getDest()); if (pTrainDummy) { if (pTrainDummy->id()==0x1071) { pTrainDummy->setId(0x1070); pTrainDummy->gatetime=0; RefreshItem(pTrainDummy);//AntiChrist } else if (pTrainDummy->id()==0x1075) { pTrainDummy->setId(0x1074); pTrainDummy->gatetime=0; RefreshItem(pTrainDummy);//AntiChrist } } } break; case 15: //reactive armor pc_s->ra=0; break; case 16: //Explosion potion messages Tauriel sprintf((char*)temp, "%i", more3); sysmessage(calcSocketFromChar(s), (char*)temp); // crashfix, LB break; case 17: //Explosion potion explosion Tauriel s=calcCharFromSer(getSour()); explodeitem(calcSocketFromChar(s), calcItemFromSer(getDest())); //explode this item break; case 18: //Polymorph spell by AntiChrist 9/99 if(pc_s->polymorph)//let's ensure it's under polymorph effect! { pc_s->id1=pc_s->xid1; pc_s->id2=pc_s->xid2; pc_s->polymorph=false; teleport(s); } break; case 19: //Incognito spell by AntiChrist 12/99 reverseIncognito(pc_s); break; case 20: // LSD potions, LB 5'th nov 1999 k=calcSocketFromChar(s); if (k==-1) return; LSD[k]=0; sysmessage(k,"LSD has worn off"); pc_s->stm=3; // stamina near 0 pc_s->mn=3; pc_s->hp=pc_s->hp/7; impowncreate(k,s,0); all_items(k); // absolutely necassairy here !!! for (ccc =0; ccc<charcount; ccc++) // that hurts, but there's no other good way { if (chardist(s,ccc)<15 && ( online(ccc) || chars[ccc].isNpc() ) ) updatechar(ccc); } break; case 21: int toDrop; toDrop = more1; //Effect->more1; if( ( pc_s->baseskill[PARRYING] - toDrop ) < 0 ) pc_s->baseskill[PARRYING] = 0; else pc_s->baseskill[PARRYING] -= toDrop; break; case 33: // delayed hiding for gms after flamestrike effect k=calcSocketFromChar(s); sysmessage(k,"You have hidden yourself well."); pc_s->hidden=1; updatechar(s); break; case 34: // delayed unhide for gms // Changed to be uniform with delayed hideing (Aldur) k = calcSocketFromChar(s); sysmessage(k, "You are now visible."); pc_s->hidden = 0; updatechar(s); break; case 35: //heals some pf - solarin int iHp; iHp=(int)more1; pc_s->hp+=iHp; updatestats(s, 0); if (!more2) tempeffect(s,s,35,more1+1,1,more3,0); break; default: LogErrorVar("Fallout of switch (num = %i).", num); break; } Items->CheckEquipment(s); //AntiChrist - checks equipments for stats requirements }