Beispiel #1
0
int 
ParseBLOCK(ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
  int Value, i;
  
  if (InRecord->Extend && !InRecord->IndexValid)
    {
      strcpy(OutRecord->ErrorMessage, "Illegally preceded by EXTEND.");
      OutRecord->Fatal = 1;
      OutRecord->Extend = 0;
    }

  if (InRecord->IndexValid)
    {
      strcpy(OutRecord->ErrorMessage, "Illegally preceded by INDEX.");
      OutRecord->Fatal = 1;
      OutRecord->Index = 0;
    }

  i = GetOctOrDec(InRecord->Operand, &Value);
  if (!i)
    {
      if (Value == 0 || Value == 2 || Value == 3)
        {
          Value = GetBankCount(Value) + Value * 02000;
          OutRecord->ProgramCounter = (const Address_t) { 0 };
          OutRecord->ProgramCounter.Address = 1;
          OutRecord->ProgramCounter.SReg = Value;

          if (Value == 0)
              OutRecord->ProgramCounter.Erasable = 1;
          else
              OutRecord->ProgramCounter.Fixed = 1;  

          OutRecord->ProgramCounter.Unbanked = 1;
          OutRecord->ProgramCounter.Value = Value;

          if (Value == 0)
              OutRecord->EBank.current = OutRecord->ProgramCounter;
        }
      else
        {
          strcpy(OutRecord->ErrorMessage, "BLOCK operand must be 0, 2, or 3.");
          OutRecord->ProgramCounter = (const Address_t) { 0 };
          OutRecord->ProgramCounter.Invalid = 1;
        }
    } 
  else 
    {  
void cTrade::buyaction(int s)
{
	char clearmsg[8];
	int clear, i, j;
	P_ITEM buyit[256];
	int amount[512];
	int layer[512];
	int playergoldtotal;
	int goldtotal;
	int itemtotal;
	int soldout;
	int tmpvalue=0; // Fixed for adv trade system -- Magius(CHE) §
//	CHARACTER cc=currchar[s];
	P_CHAR pc_currchar = currchar[s];
	P_ITEM pi_pack = Packitem(pc_currchar);
	if (pi_pack == NULL)
		return; //LB no player-pack - no buy action possible - and no crash too ;-)
	P_CHAR npc = FindCharBySerial(calcserial(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6]));

	if (npc <= 0) return;

	clear=0;
	goldtotal=0;
	soldout=0;
	itemtotal=(((256*(buffer[s][1]))+buffer[s][2])-8)/7;
	if (itemtotal>256) return; //LB

	for(i = 0; i < itemtotal; i++)
	{
		layer[i]=buffer[s][8+(7*i)];
		buyit[i] = FindItemBySerial(calcserial(buffer[s][8+(7*i)+1], buffer[s][8+(7*i)+2], buffer[s][8+(7*i)+3], buffer[s][8+(7*i)+4]));
		amount[i]=(256*(buffer[s][8+(7*i)+5]))+buffer[s][8+(7*i)+6];

		if (buyit[i] != NULL)
		{
			buyit[i]->rank=10;
			// Fixed for adv trade system -- Magius(CHE) §
			tmpvalue = buyit[i]->value;
			tmpvalue = calcValue(buyit[i], tmpvalue);
			if (SrvParams->trade_system()==1)
				tmpvalue = calcGoodValue(pc_currchar, buyit[i], tmpvalue,0);
			goldtotal += (amount[i]*tmpvalue);
			// End Fix for adv trade system -- Magius(CHE) §
		}
	}

	bool useBank;
	useBank = (goldtotal >= SrvParams->checkBank() );

	if( useBank )
		playergoldtotal = GetBankCount( pc_currchar, 0x0EED );
	else
		playergoldtotal = pc_currchar->CountGold();

	if ((playergoldtotal>=goldtotal)||(pc_currchar->isGM()))
	{
		for (i = 0; i < itemtotal; i++)
		{
			if (buyit[i] != NULL)
			{
				if (buyit[i]->amount < amount[i])
				{
					soldout = 1;
				}
			}
		}
		if (soldout)
		{
			npctalk(s, npc, "Alas, I no longer have all those goods in stock. Let me know if there is something else thou wouldst buy.",0);
			clear = 1;
		}
		else
		{
			if (pc_currchar->isGM())
			{
				sprintf((char*)temp, "Here you are, %s. Someone as special as thee will receive my wares for free of course.", pc_currchar->name.c_str());
			}
			else
			{
				if(useBank)
				{
					sprintf((char*)temp, "Here you are, %s. %d gold coin%s will be deducted from your bank account.  I thank thee for thy business.",
					pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s");
				    goldsfx(s, goldtotal);
				}
			    else
				{
				    sprintf((char*)temp, "Here you are, %s.  That will be %d gold coin%s.  I thank thee for thy business.",
					pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s");
				    goldsfx(s, goldtotal);	// Dupois, SFX for gold movement. Added Oct 08, 1998
				}
			}
			npctalkall(npc, (char*)temp, 0);
			npcaction(npc, 0x20);		// bow (Duke, 17.3.2001)

			clear = 1;
			if( !(pc_currchar->isGM() ) )
			{
				if( useBank )
					DeleBankItem( pc_currchar, 0x0EED, 0, goldtotal );
				else
					delequan( pc_currchar, 0x0EED, goldtotal, NULL );
			}
			for (i=0;i<itemtotal;i++)
			{
				P_ITEM pi = buyit[i];
				if (pi != NULL)
				{
					if (pi->amount>amount[i])
					{
						if (pi->pileable)
						{
							Commands->DupeItem(s, buyit[i], amount[i]);
						}
						else
						{
							for (j=0;j<amount[i];j++)
							{
								Commands->DupeItem(s, buyit[i], 1);
							}
						}
						pi->amount-=amount[i];
						pi->restock+=amount[i];
					}
					else
					{
						switch(layer[i])
						{
						case 0x1A:
							if (pi->pileable)
							{
								Commands->DupeItem(s, buyit[i], amount[i]);
							}
							else
							{
								for (j=0;j<amount[i];j++)
								{
									Commands->DupeItem(s, buyit[i], 1);
								}
							}
							pi->amount=pi->amount-amount[i];
							pi->restock=pi->restock+amount[i];
							break;
						case 0x1B:
							if (pi->pileable)
							{
								pi->SetContSerial(pi_pack->serial);
								RefreshItem(buyit[i]);//AntiChrist
							}
							else
							{
								for (j=0;j<amount[i]-1;j++)
								{
									Commands->DupeItem(s, buyit[i], 1);
								}
								pi->SetContSerial(pi_pack->serial);
								pi->amount = 1;
								RefreshItem(buyit[i]);//AntiChrist
							}
							break;
						default:
							clConsole.send("ERROR: Fallout of switch statement without default. wolfpack.cpp, buyaction()\n"); //Morrolan
						}
					}
				}
			}
		}
	}
	else
	{
		npctalkall(npc, "Alas, thou dost not possess sufficient gold for this purchase!",0);
	}

	if (clear)
	{
		clearmsg[0]=0x3B;
		clearmsg[1]=0x00;
		clearmsg[2]=0x08;
		clearmsg[3]=buffer[s][3];
		clearmsg[4]=buffer[s][4];
		clearmsg[5]=buffer[s][5];
		clearmsg[6]=buffer[s][6];
		clearmsg[7]=0x00;
		Xsend(s, clearmsg, 8);
	}
	Weight->NewCalc(pc_currchar);	// Ison 2-20-99
	statwindow(s, pc_currchar);
}
Beispiel #3
0
//o---------------------------------------------------------------------------o
//|   Function   : void buyItem(CSocket *mSock)
//|   Date       : Unknown
//|   Programmer : UOX3 DevTeam
//o---------------------------------------------------------------------------o
//|   Purpose    : Called when player buys an item from a vendor
//o---------------------------------------------------------------------------o
bool CPIBuyItem::Handle(void)
{
    UI16 i;
    UI32 playergoldtotal, goldtotal = 0;
    bool soldout = false, clear = false;
    CChar *mChar = tSock->CurrcharObj();
    CItem *p = mChar->GetPackItem();

    if (!ValidateObject(p)) 
        return true;

    ITEMLIST bitems;
    std::vector<UI08> layer;
    std::vector<UI16> amount;

    // vector for storing all objects that actually end up in user backpack
    std::vector< CItem * > boughtItems;

    CChar *npc = calcCharObjFromSer(tSock->GetDWord(3));
    UI16 itemtotal = static_cast<UI16>((tSock->GetWord(1) - 8) / 7);
    if (itemtotal > 511) 
        return true;

    boughtItems.reserve(itemtotal);
    bitems.resize(itemtotal);
    amount.resize(itemtotal);
    layer.resize(itemtotal);
    int baseOffset = 0;
    for (i = 0; i < itemtotal; ++i)
    {
        baseOffset = 7 * i;
        layer[i] = tSock->GetByte(8 + baseOffset);
        bitems[i] = calcItemObjFromSer(tSock->GetDWord(9 + baseOffset));
        amount[i] = tSock->GetWord(13 + baseOffset);
        goldtotal += (amount[i] * (bitems[i]->GetBuyValue()));
    }

    bool useBank = (goldtotal >= static_cast<UI32>(cwmWorldState->ServerData()->BuyThreshold()));
    if (useBank)
        playergoldtotal = GetBankCount(mChar, 0x0EED);
    else
        playergoldtotal = GetItemAmount(mChar, 0x0EED);
    if (playergoldtotal >= goldtotal || mChar->IsGM())
    {
        for (i = 0; i < itemtotal; ++i)
        {
            if (bitems[i]->GetAmount() < amount[i])
                soldout = true;

            // Check if onBuyFromVendor JS event is present for each item being purchased
            // If true, and a return false has been returned from the script, halt the purchase
            UI16 targTrig = bitems[i]->GetScriptTrigger();
            cScript *toExecute = JSMapping->GetScript(targTrig);

            if (toExecute != NULL)
                if (toExecute->OnBuyFromVendor(tSock, npc, bitems[i]))
                {
                    bitems.clear(); //needed???
                    return true;
                }
        }

        if (soldout)
        {
            npc->TextMessage(tSock, 1336, TALK, false);
            clear = true;
        }
        else
        {
            if (mChar->IsGM())
                npc->TextMessage(NULL, 1337, TALK, false, mChar->GetName().c_str());
            else
            {
                if (goldtotal == 1)
                    npc->TextMessage(NULL, 1338, TALK, false, mChar->GetName().c_str(), goldtotal);
                else
                    npc->TextMessage(NULL, 1339, TALK, false, mChar->GetName().c_str(), goldtotal);

                Effects->goldSound(tSock, goldtotal);
            }
            
            clear = true;
            if (!mChar->IsGM()) 
                if (useBank)
                    DeleteBankItem(mChar, goldtotal, 0x0EED);
                else
                    DeleteItemAmount(mChar, goldtotal, 0x0EED);

            CItem *biTemp;
            CItem *iMade = NULL;
            UI16 j;
            for (i = 0; i < itemtotal; ++i)
            {
                biTemp = bitems[i];
                iMade = NULL;
                if (biTemp->GetAmount() > amount[i])
                {
                    if (biTemp->isPileable())
                    {
                        iMade = Items->DupeItem(tSock, biTemp, amount[i]);
                        if (iMade != NULL)
                        {
                            iMade->SetCont(p);
                            iMade->PlaceInPack();
                            boughtItems.push_back(iMade);
                        }
                    }
                    else
                    {
                        for (j = 0; j < amount[i]; ++j)
                        {
                            iMade = Items->DupeItem(tSock, biTemp, 1);
                            if (iMade != NULL)
                            {
                                iMade->SetCont(p);
                                iMade->PlaceInPack();
                                boughtItems.push_back(iMade);
                            }
                        }
                    }
                    biTemp->IncAmount(-amount[i], true);
                    biTemp->SetRestock(biTemp->GetRestock() + amount[i]);
                }
                else
                {
                    switch(layer[i])
                    {
                        case 0x1A: // Sell Container
                            if (biTemp->isPileable())
                            {
                                iMade = Items->DupeItem(tSock, biTemp, amount[i]);
                                if (iMade != NULL)
                                {
                                    iMade->SetCont(p);
                                    iMade->PlaceInPack();
                                    boughtItems.push_back(iMade);
                                }
                            }
                            else
                            {
                                for (j = 0; j < amount[i]; ++j)
                                {
                                    iMade = Items->DupeItem(tSock, biTemp, 1);
                                    if (iMade != NULL)
                                    {
                                        iMade->SetCont(p);
                                        iMade->PlaceInPack();
                                        boughtItems.push_back(iMade);
                                    }
                                }
                            }
                            biTemp->IncAmount(-amount[i], true);
                            biTemp->SetRestock(biTemp->GetRestock() + amount[i]);
                            break;
                        case 0x1B: // Bought Container
                            if (biTemp->isPileable())
                            {
                                biTemp->SetCont(p);
                                boughtItems.push_back(biTemp);
                            }
                            else
                            {
                                for (j = 0; j < amount[i]-1; ++j)
                                {
                                    iMade = Items->DupeItem(tSock, biTemp, 1);
                                    if (iMade != NULL)
                                    {
                                        iMade->SetCont(p);
                                        iMade->PlaceInPack();
                                        boughtItems.push_back(iMade);
                                    }
                                }
                                biTemp->SetCont(p);
                                biTemp->SetAmount(1);
                                boughtItems.push_back(biTemp);
                            }
                            break;
                        default:
                            Console.Error(" Fallout of switch statement without default. vendor.cpp, buyItem()");
                            break;
                    }
                }
            }

            for (i = 0; i < boughtItems.size(); ++i)
            {
                if (boughtItems[i])
                {
                    cScript *toGrab = JSMapping->GetScript(boughtItems[i]->GetScriptTrigger());
                    if (toGrab != NULL)
                        toGrab->OnBoughtFromVendor(tSock, npc, boughtItems[i]);
                }
            }
        }
    }
    else
        npc->TextMessage(NULL, 1340, TALK, false);

    if (clear)
    {
        CPBuyItem clrSend;
        clrSend.Serial(tSock->GetDWord(3));
        tSock->Send(&clrSend);
    }
    return true;
}