help zuly fix on paknpcsell

How do you use the forum? Also Technical News.

Moderators: osRose dev team, ospRose dev team, osiRose dev team, Moderators

Forum rules
This forum is NOT a forum where you post a technical questions about osRose, osiRose or ospRose. Use the dedicated forum for that!

help zuly fix on paknpcsell

Postby stefan1994 on Sat Nov 04, 2017 3:29 pm

hey every one we are bussy whit a new server we need one fix and its the zuly sell count can some one help us whit that its dev 4 based

we have the following code

  1. for (int i=0; i<sellcount; i++)
  2.     {
  3.         BYTE slotid = GETBYTE((*P), 8+(buycount*4)+(i*3));
  4.         WORD count = GETWORD((*P), 9+(buycount*4)+(i*3));
  5.         if (thisclient->items[slotid].count < count)
  6.            return true;
  7.         CItem thisitem = thisclient->items[slotid];
  8.         thisitem.count = count;
  9.  
  10.         if (thisclient->items[slotid].count<thisitem.count)
  11.         {
  12.           Log(MSG_HACK, "[NPC-SELL] Player %s tryes to sell %i [%i:%i], but has only %i",thisclient->CharInfo->charname,thisitem.count,thisitem.itemtype,thisitem.itemnum,thisclient->items[slotid].count);
  13.           return true;
  14.         }
  15.  
  16.         switch(thisitem.itemtype)
  17.         {
  18.             case 1:
  19.             case 2:
  20.             case 3:
  21.             case 4:
  22.             case 5:
  23.             case 6:
  24.             case 8:
  25.             case 9:
  26.             case 14:
  27.             {
  28.                 float price = 0;
  29.                 price = 7.142857E-05F * 5000;
  30.                 if(thisitem.itemtype<10)
  31.                 {
  32.                     price *= EquipList[thisitem.itemtype].Index[thisitem.itemnum]->price;
  33.                 }
  34.                 else
  35.                 {
  36.                     price *= PatList.Index[thisitem.itemnum]->price;
  37.                 }
  38.                 price *= thisitem.durability + 0xc8;
  39.                 price *= 40;
  40.                 price *= 0xc8 - 0x62; //town rate
  41.                 price *= 1.000000E-06;
  42.                     //Should fix the merchandising skill
  43.                     for(int i = 0;i<MAX_CLASS_SKILL;i++)
  44.                     {
  45.                         if(thisclient->cskills[i].id == 2286)
  46.                         {
  47.                             price += (((price * thisclient->cskills[i].thisskill->value2[0]) / 100));
  48.                             Log(MSG_INFO,"%i percent added to selling price.", thisclient->cskills[i].thisskill->value2[0]);
  49.                         }
  50.                     }
  51.                 price = (float)floor(price);
  52.                 Log( MSG_INFO, "%s:: Item Sold: itemnum %i, itemtype %i, itemcount %i, price %0.0f",thisclient->CharInfo->charname,thisitem.itemnum, thisitem.itemtype, thisitem.count, price);
  53.                 thisclient->CharInfo->Zulies += (long int)price*count;
  54.             }
  55.             break;
  56.             case 10:
  57.             case 12:
  58.             {
  59.                 // this values are the same from packet 753
  60.                 BYTE values[11] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
  61.                 UINT type = 0;
  62.                 UINT bprice = 0;
  63.                 UINT pricerate = 0;
  64.                 UINT pvalue = 0;
  65.                 if(thisitem.itemtype==10)
  66.                 {
  67.                    type = UseList.Index[thisitem.itemnum]->type;
  68.                    bprice = UseList.Index[thisitem.itemnum]->price;
  69.                    pricerate = UseList.Index[thisitem.itemnum]->pricerate;
  70.                    pvalue = UseList.Index[thisitem.itemnum]->pricevalue;
  71.                 }
  72.                 else
  73.                 {
  74.                    type = NaturalList.Index[thisitem.itemnum]->type;
  75.                    bprice = NaturalList.Index[thisitem.itemnum]->price;
  76.                    pricerate = NaturalList.Index[thisitem.itemnum]->pricerate;
  77.                    pvalue = NaturalList.Index[thisitem.itemnum]->pricevalue;
  78.                 }
  79.                 unsigned int value = 0;
  80.                 float price = 0;
  81.                 bool flag;
  82.                 if(type<421)
  83.                 {
  84.                     if(type<311)
  85.                         flag = false;
  86.                     else
  87.                         if(type>312)
  88.                             flag = false;
  89.                         else
  90.                             flag = true;
  91.                 }
  92.                 else
  93.                 {
  94.                     if(type<=428)
  95.                         flag = true;
  96.                     else
  97.                         if(type<311)
  98.                             flag = false;
  99.                         else
  100.                             flag = true;
  101.                 }
  102.  
  103.                 //Some items don't sell for right price o.O
  104.                 if(type == 437 || type == 429 || type == 435 || type == 442)
  105.                     flag = false;
  106.  
  107.                 if(flag)
  108.                 {
  109.                     value = pvalue;
  110.                     if(value>=11)
  111.                         value ^= 0xffffffff;
  112.                     else
  113.                         value = values[value];
  114.                     value -= 0x32;
  115.                     value *= pricerate;
  116.                     value += 1000;
  117.                     value *= bprice;
  118.                     value *= (200 - 0x62); //town rate ( 100)
  119.                     price = value * 5.555555555555556E-06;
  120.                     //Should fix the merchandising skill
  121.                     for(int i = 0;i<MAX_CLASS_SKILL;i++)
  122.                     {
  123.                         if(thisclient->cskills[i].id == 2286)
  124.                         {
  125.                             price += (((price * thisclient->cskills[i].thisskill->value2[0]) / 100));
  126.                             Log(MSG_INFO,"%i percent added to selling price.", thisclient->cskills[i].thisskill->value2[0]);
  127.                         }
  128.                     }
  129.                     price = (float)floor(price);
  130.                     Log( MSG_INFO, "%s:: Item Sold: itemnum %i, itemtype %i, itemcount %i, price %0.0f",thisclient->CharInfo->charname,thisitem.itemnum, thisitem.itemtype, thisitem.count, price);
  131.                     thisclient->CharInfo->Zulies += (long int)price*count;
  132.                 }
  133.                 else
  134.                 {
  135.                     float price = pricerate;
  136.                     unsigned int value = 0x61 - 0x32; // misc rate -0x32
  137.                     price *= value;
  138.                     price += 1000;
  139.                     price *= bprice;
  140.                     price *= (200 - 0x62); //town rate ( 100)
  141.                     price *= 5.555555555555556E-06;
  142.                     //Should fix the merchandising skill
  143.                     for(int i = 0;i<MAX_CLASS_SKILL;i++)
  144.                     {
  145.                         if(thisclient->cskills[i].id == 2286)
  146.                         {
  147.                             price += (((price * thisclient->cskills[i].thisskill->value2[0]) / 100));
  148.                             Log(MSG_INFO,"%i percent added to selling price.", thisclient->cskills[i].thisskill->value2[0]);
  149.                         }
  150.                     }
  151.                     price = (float)floor(price);
  152.                     Log( MSG_INFO, "%s:: Item Sold: itemnum %i, itemtype %i, itemcount %i, price %0.0f",thisclient->CharInfo->charname,thisitem.itemnum, thisitem.itemtype, thisitem.count, price);
  153.                     thisclient->CharInfo->Zulies += (long int)price*count;
  154.                 }
  155.             }
  156.             break;
  157.             case 7:
  158.             case 11:
  159.             case 13:
  160.             {
  161.                 float price = 0;
  162.                 UINT bprice = 0;
  163.                 UINT pricerate = 0;
  164.                 switch(thisitem.itemtype)
  165.                 {
  166.                     case 7:
  167.                         pricerate = EquipList[thisitem.itemtype].Index[thisitem.itemnum]->pricerate;
  168.                         bprice = EquipList[thisitem.itemtype].Index[thisitem.itemnum]->price;
  169.                     break;
  170.                     case 11:
  171.                         pricerate = JemList.Index[thisitem.itemnum]->pricerate;
  172.                         bprice = JemList.Index[thisitem.itemnum]->price;
  173.                     break;
  174.                     case 13:continue;//can we sell quest items? :S
  175.  
  176.                 }
  177.                 price = pricerate;
  178.                 price *= 0x61 - 0x32;   // misc rate -0x32
  179.                 price += 1000;
  180.                 price *= bprice;
  181.                 price *= (200 - 0x62); //town rate ( 100)
  182.                 price *= 5.555555555555556E-06;
  183.                 //Should fix the merchandising skill
  184.                     for(int i = 0;i<MAX_CLASS_SKILL;i++)
  185.                     {
  186.                         if(thisclient->cskills[i].id == 2286)
  187.                         {
  188.                             price += (((price * thisclient->cskills[i].thisskill->value2[0]) / 100));
  189.                             Log(MSG_INFO,"%i percent added to selling price.", thisclient->cskills[i].thisskill->value2[0]);
  190.                         }
  191.                     }
  192.                 price = (float)floor(price);
  193.                 Log( MSG_INFO, "%s:: Item Sold: itemnum %i, itemtype %i, itemcount %i, price %0.0f",thisclient->CharInfo->charname,thisitem.itemnum, thisitem.itemtype, thisitem.count, price);
  194.                 thisclient->CharInfo->Zulies += (long int)price*count;
  195.             }
  196.             break;
  197.             default:
  198.                 Log( MSG_WARNING, "Invalid Item Type: %i", thisitem.itemtype );
  199.         }
  200.         thisclient->items[slotid].count -= count;
  201.         if( thisclient->items[slotid].count <=0 )
  202.             ClearItem( thisclient->items[slotid] );
  203.         ADDWORD( pak, slotid );
  204.         ADDDWORD( pak, BuildItemHead( thisclient->items[slotid] ) );
  205.         ADDDWORD( pak, BuildItemData( thisclient->items[slotid] ) );
  206.         ADDDWORD( pak, 0x00000000 );
  207.         ADDWORD ( pak, 0x0000 );
  208.  
  209.         ncount++;
  210.        //Saving item in database now.
  211.        thisclient->SaveSlot41(slotid);
  212.     }
  213.  
  214.     SETQWORD( pak, 0, thisclient->CharInfo->Zulies );
  215.     SETBYTE( pak, 8, ncount );
  216.     thisclient->client->SendPacket( &pak );
  217.  
  218.  
  219.     return true;
  220. }


the problem is that it give not stable zuly and not the right count of zully could one of u help us whit it?

hanks alot for reading and take the time to see the code message me if u go a solution or add me on discord stefan#3662

kind regards stefan from FrozenRose
stefan1994
Little soul
Little soul
 
Posts: 9
Joined: Fri Aug 18, 2017 8:47 pm
Location: netherlands

Re: help zuly fix on paknpcsell

Postby lazypenguin on Sat Nov 04, 2017 4:27 pm

Firstly, I think you posted this in the wrong section but I'm not even sure if that matters anymore:

Forum rules
This forum is NOT a forum where you post a technical questions about osRose, osiRose or ospRose. Use the dedicated forum for that!


Secondly, that is an UGLY function. It would be helpful if you could narrow down which case seems to be causing the problems. I suspect it might be floating-point rounding issues with all these ugly numbers floating around:

  1. price = 7.142857E-05F * 5000;
lazypenguin
Smoulie
Smoulie
 
Posts: 68
Joined: Mon Aug 10, 2009 6:51 am

Re: help zuly fix on paknpcsell

Postby AnimalCrackerz on Sat Nov 04, 2017 5:06 pm

  1. {
  2.             case 1:
  3.             case 2:
  4.             case 3:
  5.             case 4:
  6.             case 5:
  7.             case 6:
  8.             case 8:
  9.             case 9:
  10.             case 14:
  11.             {
  12.                 float price = 0;
  13.                 price = 7.142857E-05F * 5000;
  14.                 if(thisitem.itemtype<10)
  15.                 {
  16.                     price *= EquipList[thisitem.itemtype].Index[thisitem.itemnum]->price;
  17.                 }
  18.                 else
  19.                 {
  20.                     price *= PatList.Index[thisitem.itemnum]->price;
  21.                 }
  22.                 price *= thisitem.durability + 0xc8;
  23.                 price *= 40;
  24.                 price *= 0xc8 - 0x62; //town rate
  25.                 price *= 1.000000E-06;


it is this case where it decides the npc buy price for equip items....what it's doing is in the client it says it will buy for x amount of zuly...but here in the server it gives a differnt buy amount. So ingame the player is recieving less when he sells to these case items to the NPC. In Dev rev II it works out the same in client and in server but the price= has been changed to this number price = 7.142857E-05F * 5000; which you pointed out would make it act wonky. I asked around and it seems that the town/world rate had been added too(changed?) in the client source in either stb or a zon value giving a new value to the caluclation.

and I think this is how it looks in the client source
  1. switch( sITEM.m_cType ) {
  2.                 case ITEM_TYPE_FACE_ITEM:  
  3.                 case ITEM_TYPE_HELMET   :  
  4.                 case ITEM_TYPE_ARMOR    :  
  5.                 case ITEM_TYPE_GAUNTLET :  
  6.                 case ITEM_TYPE_BOOTS    :  
  7.                 case ITEM_TYPE_KNAPSACK :  
  8.                 case ITEM_TYPE_WEAPON   :
  9.                 case ITEM_TYPE_SUBWPN   :
  10.                 case ITEM_TYPE_RIDE_PART:
  11.                         // 추가옵션은 보석과 같이
  12.                         iPrice = (int) (
  13.                                                 (float)ITEM_BASE_PRICE( sITEM.GetTYPE(), sITEM.GetItemNO() ) *
  14.                                                 (float)( 40 + sITEM.GetGrade() ) *
  15.                                                 (float)( 200 + sITEM.GetDurability() ) *
  16.                                                 (float)( 200 - Get_WorldRATE() ) *
  17.                                                 (float)( 1 + nSellSkillVALUE * 0.01f ) / 1000000.f *
  18.                                                 (float)( (4000+sITEM.GetLife()) / 14000.f ) +
  19.                                                 (float)( sITEM.IsAppraisal() * GEMITEM_BASE_PRICE( sITEM.GetOption() ) * 0.2f )
  20.                                         ) ;
  21.                         break;
AnimalCrackerz
Pomic
Pomic
 
Posts: 101
Joined: Tue Apr 20, 2010 1:58 pm

Re: help zuly fix on paknpcsell

Postby lazypenguin on Sat Nov 04, 2017 8:11 pm

Ideally you'd want to debug by isolating what is the actual difference between the two numbers.
  1. price = 7.142857E-05F * 50000.
is a weird constant and evaluates to 0.35714285. It's not clear why it is needed...seems like it might be a magic fix someone inserted a while ago.

Furthermore in the server the price is multiplied by 40 here: but on the client it's multiplied by 40 + item grade:
  1. (float)( 40 + sITEM.GetGrade() )
....

If you can edit the client, you're better off re-writing both those calculations from scratch IMO
lazypenguin
Smoulie
Smoulie
 
Posts: 68
Joined: Mon Aug 10, 2009 6:51 am

Re: help zuly fix on paknpcsell

Postby hoegarden31 on Sun Nov 05, 2017 12:58 pm

That client code is that to calculate the resell value ?
I'm the one and only. In heaven and on earth.
Image
hoegarden31
Rackie
Rackie
 
Posts: 150
Joined: Sun Nov 13, 2011 7:13 pm

Re: help zuly fix on paknpcsell

Postby PurpleYouko on Sun Nov 05, 2017 5:06 pm

I'll have a bit of a look at it on Monday when I have my sources in front of me. Can't do a lot from home at the weekend
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4691
Joined: Fri Aug 10, 2007 2:05 pm

Re: help zuly fix on paknpcsell

Postby hoegarden31 on Sun Nov 05, 2017 5:15 pm

It looks like the resell factor now is 0.35714285. But that doesn't match with the client's number. So i was wondering how the display value is calculated in the client. The server only knows the price...
I'm the one and only. In heaven and on earth.
Image
hoegarden31
Rackie
Rackie
 
Posts: 150
Joined: Sun Nov 13, 2011 7:13 pm

Re: help zuly fix on paknpcsell

Postby PurpleYouko on Mon Nov 06, 2017 7:28 pm

OMG!!

This has really opened up a can of worms.
I started by taking a closer look at the code posted above by AnimalCrackerz.
Here is that client side function with the comments translated.
  1. int CEconomy::Get_ItemSellPRICE (tagITEM &sITEM, short nSellSkillVALUE)
  2. {
  3.     int iPrice = 0;
  4.     int iItemRate, iPriceRate;
  5.  
  6.     switch( sITEM.m_cType ) {
  7.         case ITEM_TYPE_FACE_ITEM:  
  8.         case ITEM_TYPE_HELMET   :  
  9.         case ITEM_TYPE_ARMOR    :  
  10.         case ITEM_TYPE_GAUNTLET :  
  11.         case ITEM_TYPE_BOOTS    :  
  12.         case ITEM_TYPE_KNAPSACK :  
  13.         case ITEM_TYPE_WEAPON   :
  14.         case ITEM_TYPE_SUBWPN   :
  15.         case ITEM_TYPE_RIDE_PART:
  16.             // Additional options like jewelry
  17.             iPrice = (int) (
  18.                         (float)ITEM_BASE_PRICE( sITEM.GetTYPE(), sITEM.GetItemNO() ) *      // base price from STB
  19.                         (float)( 40 + sITEM.GetGrade() ) *                                  // refine level
  20.                         (float)( 200 + sITEM.GetDurability() ) *                            // durability
  21.                         (float)( 200 - Get_WorldRATE() ) *                                  // world rate
  22.                         (float)( 1 + nSellSkillVALUE * 0.01f ) / 1000000.f *                // dealer discount skill
  23.                         (float)( (4000+sITEM.GetLife()) / 14000.f ) +                       // item lifespan
  24.                         (float)( sITEM.IsAppraisal() * GEMITEM_BASE_PRICE( sITEM.GetOption() ) * 0.2f )     // value multiplier
  25.                     ) ;
  26.             break;
  27.  
  28.         case ITEM_TYPE_USE      :
  29.         case ITEM_TYPE_NATURAL  :
  30.             if ( IsEssentialGoods( ITEM_TYPE( sITEM.m_cType, sITEM.m_nItemNo ) ) ) {
  31.                 iItemRate  = this->Get_ItemRATE( ITEM_RATE_TYPE( sITEM.m_cType, sITEM.m_nItemNo ) );
  32.                 iPriceRate = ITEM_PRICE_RATE( sITEM.m_cType, sITEM.m_nItemNo );
  33.                 // daily necessity.
  34.                 // Sale Price = ITEM_BASE * { 1000 + (ITEM_RATE - 50) * ITEM_FLUC } * (1 + Sales skill level * 0.02) * (200- WORLD_RATE) / 200000
  35.                 iPrice = (int) (
  36.                     ITEM_BASE_PRICE( sITEM.m_cType, sITEM.m_nItemNo) *
  37.                     ( 1000 + ( iItemRate-50 ) * iPriceRate ) *
  38.                     ( 1 + nSellSkillVALUE * 0.01 ) * ( 200 - Get_WorldRATE() ) / 180000.f
  39.                     ) ;
  40.                 break;
  41.             }
  42.  
  43.         case ITEM_TYPE_JEWEL    :
  44.         case ITEM_TYPE_GEM      :
  45.         case ITEM_TYPE_QUEST    :
  46.             // 2003.08.018 Other items.
  47.             // Sale Price = ITEM_BASE * { 1000 + (TOWN_RATE - 50) * ITEM_FLUC } * (1 + Sales skill level * 0.02) * (200- WORLD_RATE) / 200000
  48.             iPriceRate = ITEM_PRICE_RATE( sITEM.m_cType, sITEM.m_nItemNo );
  49.             iPrice = (int) (
  50.                     ITEM_BASE_PRICE( sITEM.m_cType, sITEM.m_nItemNo) *
  51.                     ( 1000 + ( this->Get_TownRATE() - 50 ) * iPriceRate ) *
  52.                     ( 1 + nSellSkillVALUE * 0.01 ) * ( 200 - Get_WorldRATE() ) / 180000.f
  53.                     ) ;
  54.             break;
  55.     }
  56.  
  57.     return iPrice;
  58. }

I included the whole function since it seems that the formulas are different depending on the item type. Also added some of my own comments to make it easier to follow.
Most of the formula is pretty straight forward except for the bits related to WORLD_RATE. We don't use that in our servers at all so it gets sent in a very mixed up 0x0753 packet in worldpackets.cpp when a player joins a map.
And that is where the problems start....
The packet formula used in our servers doesn't mesh at all well with the client source code. At first I thought it might be possible that stuff has been added to NARose clients over the years and had gradually been added to the server by lmame (or somebody other than myself) to keep up with changes. Could that have made the current servers incompatible with the packet structures needed by the client source (V 137) which is kind of old?
But then I traced the history of the 0x0753 packet way back to the early OsIrose servers. It's exactly the same in those so it definitely hasn't slowly evolved over the years.
Which means....
It's just.... WRONG and apparently always has been.

so here is the deal. I've summarized the needed format for the the NARose client.
  1.  
  2. 0x0753  player joins a map                                         
  3.     struct gsv_JOIN_ZONE : public t_PACKETHEADER                                           
  4.     WORD        m_wServerObjectIndex;                                  
  5.     short       m_nCurHP;                                  
  6.     short       m_nCurMP;                                  
  7.     long        m_lCurEXP;                                 
  8.     long        m_lPenalEXP;                                   
  9.     tagVAR_GLOBAL       m_VAR;          // Structure containing world economy rates                    
  10.         struct tagVAR_GLOBAL                                       
  11.         {                                      
  12.             short   m_nWorld_PRODUCT;                   // Manufacturing Related           
  13.             DWORD   m_dwUpdateTIME;             // The updated time.           
  14.             short   m_nWorld_RATE;                  // Economy:: the world's waterfront. 80~140        
  15.             BYTE    m_btTOWN_RATE;                  // The village waterfront.          80~140
  16.             BYTE    m_btItemRATE[ MAX_PRICE_TYPE ];                 // Aitembyeol waterfront.           1~127
  17.             DWORD   m_dwGlobalFLAGS;                               
  18.         } ;                                    
  19.     DWORD       m_dwAccWorldTIME;           // World time accumulated after the first game server operation                    
  20.     int     m_iTeamNO;          // Set on the server side code                     
  21.  

But that isn't what we are sending....
here is the packet that we send
  1.  
  2. server example                         
  3. BEGINPACKET( pak, 0x753 );                         
  4. ADDWORD    ( pak, thisclient->clientid );                       // USER ID 
  5. ADDWORD    ( pak, thisclient->Stats->HP );                      // CURRENT HP   
  6. ADDWORD    ( pak, thisclient->Stats->MP );                      // CURRENT MP   
  7. ADDDWORD   ( pak, thisclient->CharInfo->Exp );                      // CURRENT EXP 
  8. ADDDWORD   ( pak, 0x00000000 );                     // LVL EXP (UNSUSED)   
  9.                            
  10.                            
  11.                            
  12. ADDWORD    ( pak, 0x0063 );                         // World Rate   
  13. ADDBYTE    ( pak, 0x70 );                          
  14. ADDBYTE    ( pak, 0x69 );                          
  15. ADDBYTE    ( pak, 0x68 );                          
  16. ADDBYTE    ( pak, 0x67 );                          
  17. ADDWORD    ( pak, 0x0062 );                          // Town rate   
  18. ADDBYTE    ( pak, 0x61 );                        // misc rate   
  19. ADDBYTE    ( pak, 0x32 );  //1                         
  20. ADDBYTE    ( pak, 0x32 );  //2                         
  21. ADDBYTE    ( pak, 0x32 );  //3                         
  22. ADDBYTE    ( pak, 0x32 );  //4                         
  23. ADDBYTE    ( pak, 0x32 );  //5                         
  24. ADDBYTE    ( pak, 0x32 );  //6                         
  25. ADDBYTE    ( pak, 0x32 );  //7                         
  26. ADDBYTE    ( pak, 0x32 );  //8                         
  27. ADDBYTE    ( pak, 0x32 );  //9                         
  28. ADDBYTE    ( pak, 0x32 );  //10                        
  29. ADDBYTE    ( pak, 0x32 );  //11                        
  30. ADDWORD  (pak, 0x0000);                     pvp flag   
  31. ADDWORD    (pak, 0x0000 );                      ?   
  32. ADDDWORD( pak, map->MapTime );                         
  33. ADDWORD(pak,thisclient->pvp_id);                           
  34. ADDWORD(pak, 0x0000 );                      why did lmame add this? 
  35.  

The client end needs to receive 34 bytes as far as I can tell. The server sends it 46 bytes so half the stuff just falls off the end and beyond the first section, nothing lines up.
That DWORD that the client calls m_lPenalEXP is really the last thing that lines up at all.
The value that the server calls World Rate is actually a production rate variable that seems to have been intended to be used to control the production of items in the world. possibly to control NPC inventory level? I have no idea really. there are so many things that exist as embryos of ideas that go nowhere when i trace them through.

Most of the stuff sent in this packet does absolutely nothing in the client anyway so it's kind of a moot point really so I'm not going to worry about that for now..
The real point I was getting at though is the WORLD_RATE which we do send to the client every time a player enters a map.
the client reads this value in as a short made up of bytes 21 and 22 in the 0x0753 packet.
Now what do you think we might have on those two bytes of our packet?
As it happens it lines up nicely with
  1. ADDWORD    ( pak, 0x0062 );         //Town rate
  2.  
which while completely WRONG, still kind of works
That's a value of 98 in decimal. the default value in the client is 100 so we got lucky there. It's pretty close. Since we never change it in the server this can be treated as a constant.

So anyway I reworked the formula for the server based on the one in the client. The first case (items 1 through 10 (no 7) + 14) evaluates out to this
  1.  
  2. float price = 0;
  3.                 //price = 7.142857E-05F * 5000;
  4.                 if(thisitem.itemtype<10)
  5.                 {
  6.                     price *= EquipList[thisitem.itemtype].Index[thisitem.itemnum]->price;
  7.                 }
  8.                 else
  9.                 {
  10.                     price *= PatList.Index[thisitem.itemnum]->price;
  11.                 }
  12.  
  13.                 price *= (40 + thisitem.refine);
  14.                 price *= (200 + thisitem.durability);
  15.                 price *= 102;           //200 - world rate 0f 0x062 (98)
  16.                 for(int i = 0;i<MAX_CLASS_SKILL;i++)
  17.                 {
  18.                     if(thisclient->cskills[i].id == 2286)
  19.                     {
  20.                         price *= (1 + thisclient->cskills[i].thisskill->value2[0] * 0.01f) / 1000000;
  21.                     }
  22.                 }
  23.                 price *= ((4000 + thisitem.lifespan) / 14000.f );
  24.                 if (thisitem.appraised)
  25.                     price += (EquipList[7].Index[thisitem.gem]->price * 0.2f);
  26.                 price = (float)floor(price);
  27.  
  28.                 //price *= thisitem.durability + 0xc8;
  29.                 //price *= 40;
  30.                 //price *= 0xc8 - 0x62; //town rate
  31.                 //price *= 1.000000E-06;
  32.                     //Should fix the merchandising skill
  33.  
  34.                 //price = (float)floor(price);
  35.                 Log( MSG_INFO, "%s:: Item Sold: itemnum %i, itemtype %i, itemcount %i, price %0.0f",thisclient->CharInfo->charname,thisitem.itemnum, thisitem.itemtype, thisitem.count, price);
  36.                 thisclient->CharInfo->Zulies += (long int)price*count;

The old code is mostly still there just commented out except for the skill loop which I physically moved into my new code.
This code is untested. It does compile in the RoseZA server. I'm not putting it into dev rev 4 because as I've pointed out repeatedly, you have a very small chance of ever getting the timed quests working in that server so it's kind of pointless
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classes
Formatting fixed for different resolutions
Image

"A Gazelle is nothing but a giraffe plotted logarithmicaly"
User avatar
PurpleYouko
Rose Guru
Rose Guru
 
Posts: 4691
Joined: Fri Aug 10, 2007 2:05 pm

Re: help zuly fix on paknpcsell

Postby hoegarden31 on Mon Nov 06, 2017 7:42 pm

Damn so close... I got some stuff wrong. I was using the grade of the item on the server side, but quickly noticed that it was not the correct one. (Value went up like a rocket)
And for testing purpose i just made the World-rate 100.
Not sure who thought about using a town rate... As far as I could see the sell price was in all towns the same.

I will test this. Is there any chance we can just make it a database field and give that value to the client ?
I'm the one and only. In heaven and on earth.
Image
hoegarden31
Rackie
Rackie
 
Posts: 150
Joined: Sun Nov 13, 2011 7:13 pm

Re: help zuly fix on paknpcsell

Postby lazypenguin on Mon Nov 06, 2017 8:39 pm

Would would this community do without @PY...
lazypenguin
Smoulie
Smoulie
 
Posts: 68
Joined: Mon Aug 10, 2009 6:51 am

Next

Return to Some Help / News

Who is online

Users browsing this forum: No registered users and 1 guest