static str packmethod (const rpc_decl *d, str argname) { if (d->type == "string") { return strbuf () << "p.pack_string(" << argname << ")"; } else if (d->type == "opaque") { switch (d->qual) { case rpc_decl::ARRAY: return strbuf () << "p.pack_fopaque(" << d->bound << ", " << argname << ")"; break; case rpc_decl::VEC: return strbuf () << "p.pack_opaque(" << argname << ")"; break; default: panic ("bad rpc_decl qual for opaque (%d)\n", d->qual); break; } } else { switch (d->qual) { case rpc_decl::SCALAR: return packitem(d->type, argname); break; case rpc_decl::PTR: return strbuf () << "pack_ptr(p, " << argname << ", lambda x: " << packitem(d->type, "x") << ")"; break; case rpc_decl::ARRAY: return strbuf () << "p.pack_farray(" << d->bound << ", " << argname << ", lambda x: " << packitem(d->type, "x") << ")"; break; case rpc_decl::VEC: return strbuf () << "p.pack_array(" << argname << ", lambda x: " << packitem(d->type, "x") << ")"; break; default: panic ("bad rpc_decl qual (%d)\n", d->qual); } } }
static bool ItemDroppedOnSelf(P_CLIENT ps, PKGx08 *pp, P_ITEM pi) { UOXSOCKET s=ps->GetSocket(); CHARACTER cc=ps->GetCurrChar(); P_CHAR pc_currchar = MAKE_CHARREF_LRV(cc,true); if (pi->id1>=0x40) // crashfix , prevents putting multi-objects ni your backback { sysmessage(s,"Hey, putting houses in your pack crashes your back and client !"); pi->MoveTo(pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z); RefreshItem(pi);//AntiChrist return true; } if (pi->glow>0) // glowing items { pc_currchar->addHalo(pi); pc_currchar->glowHalo(pi); } int pack=packitem(cc); // LB ... if (pack==-1) // if player has no pack, put it at its feet { pi->MoveTo(pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z); RefreshItem(pi);//AntiChrist } else { items[pack].AddItem(pi); // player has a pack, put it in there Weight->NewCalc(cc);//AntiChrist bugfixes statwindow(s,cc); itemsfx(s, pi->id()); } return true; }
void UpdateStatusWindow(UOXSOCKET s, P_ITEM pi) { P_ITEM packnum = packitem(currchar[s]); if (CheckWhereItem(packnum, pi, s)) statwindow(s,currchar[s]); }
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)); }
void pack_item(P_CLIENT ps, PKGx08 *pp) // Item is put into container { int nCont=-1, nItem=-1; int j, z, serial, serhash; // tile_st tile; 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; serhash=serial%HASHMAX; nCont = calcItemFromSer( serial ); serial=pp->Iserial; if(serial == INVALID_SERIAL) abort=true; serhash=serial%HASHMAX; nItem = calcItemFromSer( serial ); if (nCont==-1) { RefreshItem(nCont);//AntiChrist return; } if (nItem==-1) return; //LB const P_ITEM pCont=MAKE_ITEMREF_LR(nCont); // on error return (This one could be const ! Duke) const P_ITEM pItem=MAKE_ITEMREF_LR(nItem); // on error return 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=GetPackOwner(nCont); 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; z = calcItemFromSer( serial ); if (z!=-1) if ((items[z].morez || pCont->morez)) { items[z].morez=0; pCont->morez=0; sendtradestatus(z, nCont); } } // //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(nItem);//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, nCont); } return; } // - Trash container if (pCont->type==87) { Items->DeleItem(nItem); 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, nCont); return; } z=packitem(cc); if (z!=-1) // lb { if (!pc_currchar->Wears(pCont) && (!(pCont->contserial==items[z].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 (int i=0;i<vecContainer.size();i++) // antichrist , bugfix for inscribing scrolls { int ci=calcItemFromSer(vecContainer[i]); if (ci!=-1) { if(items[ci].name[0]=='#') items[ci].getName(temp); else strcpy((char*)temp,items[ci].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=GetPackOwner(nCont); 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=nItem; pc_currchar->inputmode=1; 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,cc); } // 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(nItem);//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, nCont, pItem->amount); pCont->amount = 65535; Items->DeleItem(nItem); } else { pCont->amount=pCont->amount+pItem->amount; itemsfx(s, pItem->id()); Items->DeleItem(nItem); } SndRemoveitem(pItem->serial); RefreshItem(nCont);//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(nCont);//AntiChrist } // - Spell Book if (pCont->type==9) Magic->SpellBook(s,nCont); // 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=GetPackOwner(nCont); pc_currchar->removeHalo(pItem); // if gm put glowing object in another pack, handle glowsp correctly ! //removefromptr(&glowsp[pc_currchar->serial%HASHMAX],nItem); if (p!=-1) { chars[p].addHalo(pItem); chars[p].glowHalo(pItem); } } }
static bool ItemDroppedOnChar(P_CLIENT ps, PKGx08 *pp, P_ITEM pi) { UOXSOCKET s=ps->GetSocket(); CHARACTER cc=ps->GetCurrChar(); P_CHAR pc_currchar = MAKE_CHARREF_LRV(cc,true); P_CHAR pTC=FindCharBySerial(pp->Tserial); // the targeted character if (!pTC) return true; if (DEREF_P_CHAR(pTC)!=cc) { if (pTC->isNpc()) { if(!pTC->isHuman()) { ItemDroppedOnPet( ps, pp, pi); } else // Item dropped on a Human character { // Item dropped on a Guard (possible bounty quest) if( ( pTC->isNpc() ) && ( pTC->npcaitype == 4 ) ) { ItemDroppedOnGuard( ps, pp, pi); } if ( pTC->npcaitype == 5 ) { ItemDroppedOnBeggar( ps, pp, pi); } //This crazy training stuff done by Anthracks ([email protected]) if(pc_currchar->trainer!=pTC->serial) { npctalk(s, DEREF_P_CHAR(pTC), "Thank thee kindly, but I have done nothing to warrant a gift.",0); Sndbounce5(s); if (ps->IsDragging()) { ps->ResetDragging(); item_bounce5(s,pi); } return true; } else // The player is training from this NPC { ItemDroppedOnTrainer( ps, pp, pi); } }//if human or not } else // dropped on another player { // By Polygon: Avoid starting the trade if GM drops item on logged on char (crash fix) if ((pc_currchar->isGM()) && !online(DEREF_P_CHAR(pTC))) { // Drop the item in the players pack instead // Get the pack int pack = packitem(DEREF_P_CHAR(pTC)); if (pack != -1) // Valid pack? { items[pack].AddItem(pi); // Add it Weight->NewCalc(DEREF_P_CHAR(pTC)); } else // No pack, give it back to the GM { pack = packitem(DEREF_P_CHAR(pc_currchar)); if (pack != -1) // Valid pack? { items[pack].AddItem(pi); // Add it Weight->NewCalc(DEREF_P_CHAR(pc_currchar)); } else // Even GM has no pack? { // Drop it to it's feet pi->MoveTo(pc_currchar->pos.x, pc_currchar->pos.y, pc_currchar->pos.z); RefreshItem(pi); } } } else { int j=tradestart(s, DEREF_P_CHAR(pTC)); //trade-stuff pi->SetContSerial(items[j].serial); pi->pos.x=30; pi->pos.y=30; pi->pos.z=9; SndRemoveitem(pi->serial); RefreshItem(pi); } } } else // dumping stuff to his own backpack ! { ItemDroppedOnSelf( ps, pp, pi); } return true; }
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)); }
static void dumpunion (const rpc_sym *s) { // TODO: create __init__ // TODO: check that no two slots have the same name rpc_utag *thedefault = NULL; const rpc_union *rs = s->sunion.addr (); aout << "class " << mangle(rs->id) << "(object):\n"; // class slots aout << "\t__slots__ = [ " << "'" << rs->tagid << "'"; for (const rpc_utag *rt = rs->cases.base (); rt < rs->cases.lim (); rt++) { if (!rt->tagvalid) continue; if (!rt->swval) thedefault = const_cast<rpc_utag *>(rt); if (rt->tag.type != "void") aout << ", '" << rt->tag.id << "'"; } aout << " ]\n"; // check method aout << "\tdef check(self):\n" << "\t\tpass\n"; if (!thedefault) aout << "\t\tassert self." << rs->tagid << " is not None\n"; bool first = true; for (const rpc_utag *rt = rs->cases.base (); rt < rs->cases.lim (); rt++) { if (!rt->tagvalid || rt->tag.type == "void" || !rt->swval) continue; if (first) { aout << "\t\tif "; first = false; } else { aout << "\t\telif "; } aout << "self." << rs->tagid << " == " << rt->swval << ":\n" << "\t\t\tassert self." << rt->tag.id << " is not None\n"; } if (thedefault && thedefault->tag.type != "void") { if (rs->cases.size() > 1) aout << "\telse:\n\t"; aout << "\t\tassert self." << thedefault->tag.id << " is not None\n"; } // __eq__ and __ne__ methods aout << "\tdef __eq__(self, other):\n" << "\t\tif not self." << rs->tagid << " == other." << rs->tagid << ": return 0\n"; first = true; for (const rpc_utag *rt = rs->cases.base (); rt < rs->cases.lim (); rt++) { if (!rt->tagvalid || rt->tag.type == "void" || !rt->swval) continue; if (first) { aout << "\t\tif "; first = false; } else { aout << "\t\telif "; } aout << "self." << rs->tagid << " == " << rt->swval << ":\n" << "\t\t\tif not self." << rt->tag.id << " == other." << rt->tag.id << ": return 0\n"; } if (thedefault && thedefault->tag.type != "void") { if (rs->cases.size() > 1) aout << "\telse:\n\t"; aout << "\t\tif not self." << thedefault->tag.id << " == other." << thedefault->tag.id << ": return 0\n"; } aout << "\t\treturn 1\n" << "\tdef __ne__(self, other):\n" << "\t\treturn not self == other\n"; // pack method aout << "def pack_" << mangle(rs->id) << "(p, o):\n" << "\to.check()\n" << "\t" << packitem(rs->tagtype, strbuf() << "o." << rs->tagid) << "\n"; first = true; for (const rpc_utag *rt = rs->cases.base (); rt < rs->cases.lim (); rt++) { if (!rt->tagvalid || rt->tag.type == "void" || !rt->swval) continue; if (first) { aout << "\tif "; first = false; } else { aout << "\telif "; } aout << "o." << rs->tagid << " == " << rt->swval << ":\n" << "\t\t" << packmethod(&rt->tag, strbuf() << "o." << rt->tag.id) << "\n"; } if (thedefault && thedefault->tag.type != "void") { if (rs->cases.size() > 1) aout << "\telse:\n\t"; aout << "\t" << packmethod(&thedefault->tag, strbuf() << "o." << thedefault->tag.id) << "\n"; } // unpack method aout << "def unpack_" << mangle(rs->id) << "(u):\n" << "\to = " << mangle(rs->id) << "()\n" << "\to." << rs->tagid << " = " << unpackitem(rs->tagtype) << "\n"; first = true; for (const rpc_utag *rt = rs->cases.base (); rt < rs->cases.lim (); rt++) { if (!rt->tagvalid || rt->tag.type == "void" || !rt->swval) continue; if (first) { aout << "\tif "; first = false; } else { aout << "\telif "; } aout << "o." << rs->tagid << " == " << rt->swval << ":\n" << "\t\to." << rt->tag.id << " = " << unpackmethod(&rt->tag) << "\n"; } if (thedefault && thedefault->tag.type != "void") { if (rs->cases.size() > 1) aout << "\telse:\n\t"; aout << "\to." << thedefault->tag.id << " = " << unpackmethod(&thedefault->tag) << "\n"; } aout << "\to.check()\n" << "\treturn o\n"; }