Rev [85]

Welcome in the osiRose emulator Project.

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

Rev [85]

Postby FransK on Thu May 16, 2013 8:07 pm

SVN location: https://osirosenew.googlecode.com/svn/trunk/

[REV 84](svn update 6)
- Includes the fix where repairing items now costs money. (FransK)
- Repair at Raffle in Zant now works properly. (FransK)

Because the code is usefull for i-rose, p-rose and e-rose servers, i will post the modifications below so you don't have to find out yourself.
Rip out the comments if you feel like, but i prefer to document alot.

I'm not much of a C++ coder, so if you can do better, please do.
enjoy
regards,
Frans.

Sources Added/Altered:
- Worldserver.h added function declaration
  1. // Repair Price (extrafunctions.cpp)
  2.     LONG Repairprice(UINT price, UINT durability, UINT lifespan);
  3.  


extrafunctions.cpp
Added function:
  1. LONG CWorldServer::Repairprice(UINT price, UINT durability, UINT lifespan){
  2.   /* ---------------------------------------------------------------------------------------------
  3.      Function RepairPrice()
  4.      Rev: 1.0, May 2013
  5.  
  6.      This is the amount of zuly you will pay to repair any item at the NPC.
  7.      Formula is reverse-engineered by Frans K, Converted to C++ from VB.net
  8.     -------------------------------------------------------------------------------------------------*/
  9.     double iDivisor        = 400;       // Constant, needed to get the pricefactor
  10.     double BaseFactor      = 0;         // Needed to compute the Increment and Start Offset.
  11.     double PriceFactor     = 0;         // Needed to rebuild the price to a constant factor
  12.     double PriceMultiplier = -1;            // Needed to compute the Multiplier Rate
  13.     double Incrementer     = 0;         // Incrementer, this is the repair price per percent loss of lifespan.
  14.     double retval          = 0;         // The value to be returned
  15.  
  16.  
  17.     // Get The Pricefactor and Multiplier
  18.     PriceFactor = double(price / iDivisor);         // Needed for calculation of the BaseFactor
  19.     PriceMultiplier = double(price) * 0.001;        // Needed for calculation of the Multiplier
  20.     PriceMultiplier = 1 / PriceMultiplier;          // Final Touch. C++ seems to have some trouble with math.
  21.  
  22.     // Get the Base Factor. these numbers are needed to get the increment and startoffset.
  23.     BaseFactor = (durability+10) * PriceFactor;
  24.     BaseFactor = BaseFactor/100;
  25.  
  26.     // Get the Incrementer.
  27.     //Incrementer = (double(PriceMultiplier) * double(BaseFactor)) + double(BaseFactor);
  28.     Incrementer = PriceMultiplier  * BaseFactor;
  29.     Incrementer +=BaseFactor;
  30.     // Now we know enough to calculate the repair price.
  31.     // Start Amount = 10x Incrementer
  32.     // You pay for the amount the item needs to be repaired, so 100-Lifespan * Incrementer
  33.     retval = ((100-lifespan) * Incrementer) + (10 * Incrementer);
  34.  
  35.     // Finally, round the number (just convert to long) and return it.
  36.     return long (retval);
  37. }


finally: worldserver.cpp; function PakRepairItem somewhere around line 3688
Replace the entire function with this code:
  1. bool CWorldServer::pakRepairItem( CPlayer* thisclient, CPacket* P )
  2. // FJMK May 2013: fixed the function, it now needs zulie.
  3. // Cost are calculated in function Repairprice, located in Extrafunctions.cpp
  4. {
  5.     BYTE action = GETBYTE((*P),0);
  6.     switch (action)
  7.     {
  8.     case 16:    // The weapon dude in zant (found by FransK)
  9.     case 108:   // The weapon dude in zant (found by FransK)
  10.     case 39:
  11.     case 97:
  12.     case 18:
  13.     case 129:
  14.     case 0x3d: //Ronk
  15.     case 0x39: //Ronk to
  16.     case 0x1c:
  17.     case 0x08:
  18.     case 0x74:
  19.     case 0x89:
  20.     case 0x43: //NPC Repair Item / Town
  21.     {
  22.         BYTE slot = GETBYTE((*P),2);
  23.         if (!CheckInventorySlot( thisclient, slot)) return false;
  24.         if (thisclient->items[slot].count<1) return true;
  25.  
  26.         CItem thisitem=thisclient->items[slot];
  27.         LONG bprice = EquipList[thisitem.itemtype].Index[thisitem.itemnum]->price;
  28.         // Get the repair cost.
  29.  
  30.         LONG bcost=Repairprice(bprice,thisitem.durability,thisitem.lifespan);
  31.  
  32.         if (thisclient->CharInfo->Zulies >= bcost){
  33.             // Client has enough zulies
  34.             // Take money and repair.
  35.             thisclient->CharInfo->Zulies -=bcost;
  36.             thisclient->items[slot].lifespan=100;
  37.             SendSysMsg( thisclient, "The item has been repaired." );
  38.         } else {
  39.             SendSysMsg( thisclient, "You don't have enough zuly to repair this item." );
  40.             return true;
  41.         }
  42.  
  43.         // Send Packet to client.
  44.         BEGINPACKET( pak, 0x7cd );
  45.         ADDQWORD   ( pak, thisclient->CharInfo->Zulies );
  46.         ADDBYTE    ( pak, 0x01 );
  47.         ADDBYTE    ( pak, slot );
  48.         ADDWORD   ( pak, BuildItemHead( thisclient->items[slot] ));
  49.         ADDDWORD   ( pak, BuildItemData( thisclient->items[slot] ));
  50.         ADDBYTE    ( pak, 0x00 );
  51.         thisclient->client->SendPacket( &pak );
  52.         thisclient->SetStats( );
  53.     }
  54.     break;
  55.     default:
  56.         Log( MSG_WARNING,"Repair Item unknown action: %i", action);
  57.     }
  58.     return true;
  59. }
Last edited by FransK on Thu May 16, 2013 10:36 pm, edited 2 times in total.
Reason: code syntax highlighting + textual
life's too short to complain.
User avatar
FransK
osiRose dev
osiRose dev
 
Posts: 24
Joined: Tue Apr 30, 2013 8:45 pm
Location: The Netherlands

Re: Rev [85]

Postby XxXshidoXxX on Thu May 16, 2013 8:12 pm

:D
My collection ( Tools, clients sources...)
https://mega.nz/#F!AdcFnQDL!sKp3O9tWGGdWvLEj_EYfwA
osrose mobile project
viewtopic.php?f=34&t=5787
OsRose Mobile development + Titan Rose redesign
https://github.com/shid0x
XxXshidoXxX
osiRose dev
osiRose dev
 
Posts: 445
Joined: Mon Aug 27, 2007 11:44 am

Re: Rev [85]

Postby Exordium on Thu May 16, 2013 9:05 pm

great job. hope OsiROSE will gonna be revive
Exordium
Smoulie
Smoulie
 
Posts: 67
Joined: Tue Sep 25, 2012 11:10 am

Re: Rev [85]

Postby FransK on Thu May 16, 2013 10:38 pm

Exordium wrote:great job. hope OsiROSE will gonna be revive

it already runs very very smoothly at my test server at home thanks to all the developers who build it in the firstplace. imo it's 99% finished, but that final 1%, that is the real bitch.

.frans.
life's too short to complain.
User avatar
FransK
osiRose dev
osiRose dev
 
Posts: 24
Joined: Tue Apr 30, 2013 8:45 pm
Location: The Netherlands

Re: Rev [85]

Postby rl2171 on Thu May 16, 2013 11:42 pm

[svn update 7]

Added the SQL version of the GO command (not my code)

It can be changed in SQL instead of recompiling the code.

With this, you can do the following:

Add Map locations
Turn on and off things as you want
set level restrictions (low and high)
set a name for the area (Say you want the island in Junon, you can called it Junon's Island)
Choose a location on where to teleport to

Code to replace the Go command in the gmcmds.cpp file is:

  1.  
  2.  
  3.     else if (strcmp(command, "go")==0) // Use SQL by Likol
  4.     {
  5.  
  6.         if(Config.Command_Go > thisclient->Session->accesslevel)
  7.         {
  8.         DB->QFree( );
  9.         return true;
  10.         }
  11.         if ((tmp = strtok(NULL, " ")) == NULL) tmp = 0;
  12.         int loc = atoi(tmp);
  13.         int x = 0;
  14.         int y = 0;
  15.         int map = 0;
  16.         MYSQL_ROW row;
  17.         MYSQL_RES *result = NULL;
  18.         result = DB->QStore("SELECT lvlmin,map,locx,locy,mapname,lvlmax FROM list_golist WHERE isactive=1 AND loc=%i",loc);
  19.         row = mysql_fetch_row(result);
  20.         if (row==NULL)
  21.         {
  22.             SendPM(thisclient, "Please input a number after the go command, below is a list of places and their appropriate number");
  23.             DB->QFree( );
  24.             result = DB->QStore("SELECT loc,mapname FROM list_golist WHERE isactive=1");
  25.             while(row = mysql_fetch_row(result)) SendPM(thisclient, "%i = %s",atoi(row[0]),row[1]);
  26.             SendPM(thisclient, "Example; /go 1");
  27.             DB->QFree( );
  28.             return true;
  29.         }
  30.         else
  31.         {
  32.             if (thisclient->Stats->Level<atoi(row[0]))
  33.             {
  34.                 SendPM(thisclient, "You need to be a least Level %i to visit %s!",atoi(row[0]),row[4]);
  35.                 DB->QFree( );
  36.                 return true;
  37.             }
  38.             if (thisclient->Stats->Level>atoi(row[5]))
  39.             {
  40.                 SendPM(thisclient, "You need to be between Level %i and %i to visit %s !",atoi(row[0]),atoi(row[5]),row[4]);
  41.                 DB->QFree( );
  42.                 return true;
  43.             }
  44.             if ( thisclient->Stats->HP < (thisclient->Stats->MaxHP / 2) || thisclient->Stats->HP < 1 || thisclient->Session->inGame == false )
  45.             {
  46.                     SendPM(thisclient, "You need at least 50% HP in order to warp");
  47.                     DB->QFree( );
  48.                     return true;
  49.             }
  50.        fPoint coord;
  51.             int map = atoi(row[1]);
  52.             coord.x = atoi(row[2]);
  53.             coord.y = atoi(row[3]);
  54.             SendPM(thisclient, "teleport to map: %i",map);
  55.             MapList.Index[map]->TeleportPlayer( thisclient, coord, false );
  56.             Log( MSG_GMACTION, " %s : /go %i" , thisclient->CharInfo->charname, loc);
  57.             DB->QFree( );
  58.             return true;
  59.  
  60.         }
  61.     }
  62.  
  63.  


Sql file also needed (list_golist.sql)

  1.  
  2. SET FOREIGN_KEY_CHECKS=0;
  3. -- ----------------------------
  4. -- Table structure for list_golist
  5. -- ----------------------------
  6. CREATE TABLE `list_golist` (
  7.   `id` int(11) NOT NULL auto_increment,
  8.   `loc` int(11) NOT NULL,
  9.   `mapname` varchar(50) character set utf8 NOT NULL,
  10.   `lvlmin` int(11) NOT NULL default '0',
  11.   `lvlmax` int(11) NOT NULL default '250',
  12.   `map` int(11) NOT NULL,
  13.   `locx` int(11) NOT NULL,
  14.   `locy` int(11) NOT NULL,
  15.   `isactive` int(11) NOT NULL,
  16.   `description` varchar(50) character set utf8 default NULL,
  17.   PRIMARY KEY  (`id`,`loc`)
  18. ) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1;
  19.  
  20. -- ----------------------------
  21. -- Records
  22. -- ----------------------------
  23. INSERT INTO `list_golist` VALUES ('1', '1', 'Adventure Plains', '0', '250', '22', '5731', '5194', '1', null);
  24. INSERT INTO `list_golist` VALUES ('2', '2', 'Canyon City of Zant', '0', '250', '1', '5240', '5192', '1', null);
  25. INSERT INTO `list_golist` VALUES ('3', '3', 'Junon Polis', '0', '250', '2', '5654', '5218', '1', null);
  26. INSERT INTO `list_golist` VALUES ('4', '4', 'Magic City of Eucar - Luna', '50', '250', '51', '5357', '5013', '1', null);
  27. INSERT INTO `list_golist` VALUES ('5', '5', 'Xita Refuge - Eldeon', '120', '250', '61', '5434', '4569', '1', null);
  28. INSERT INTO `list_golist` VALUES ('6', '6', 'Junon Clan Field', '0', '250', '11', '5512', '5019', '1', null);
  29. INSERT INTO `list_golist` VALUES ('7', '7', 'Training Grounds', '0', '250', '6', '5199', '5280', '1', null);
  30. INSERT INTO `list_golist` VALUES ('8', '8', 'Lions Plains', '0', '250', '8', '5160', '5080', '1', null);
  31. INSERT INTO `list_golist` VALUES ('9', '9', 'Luna Clan Field', '120', '250', '59', '5095', '5128', '1', null);
  32. INSERT INTO `list_golist` VALUES ('10', '10', 'Grand Ballroom', '0', '250', '40', '5184', '5211', '1', null);
  33. INSERT INTO `list_golist` VALUES ('11', '11', 'Santa Planetoid', '0', '250', '38', '5074', '5342', '1', null);
  34. INSERT INTO `list_golist` VALUES ('12', '12', 'Sunshine Coast', '0', '250', '37', '5117', '5303', '1', null);
  35. INSERT INTO `list_golist` VALUES ('13', '13', 'Birth Island', '0', '250', '20', '5685', '5210', '1', null);
  36. INSERT INTO `list_golist` VALUES ('14', '14', 'Junon Polis - Island', '0', '250', '2', '4879', '5073', '1', null);
  37. INSERT INTO `list_golist` VALUES ('15', '15', 'Title Map', '0', '250', '4', '5200', '5217', '1', null);
  38. INSERT INTO `list_golist` VALUES ('20', '20', 'Crystal Defenders', '0', '250', '131', '5197', '5184', '0', null);
  39. INSERT INTO `list_golist` VALUES ('21', '21', 'Cave of Ulverick', '0', '250', '138', '5084', '5040', '0', null);
  40. INSERT INTO `list_golist` VALUES ('22', '22', 'Halls of Oblivion', '0', '250', '143', '5020', '5250', '0', null);
  41. INSERT INTO `list_golist` VALUES ('23', '23', 'Sea of Dawn', '0', '250', '148', '5200', '4772', '0', null);
  42. INSERT INTO `list_golist` VALUES ('24', '24', 'Sunshine Coast - Event', '0', '250', '37', '5098', '5233', '0', null);
  43. INSERT INTO `list_golist` VALUES ('25', '25', 'Sikuku Underground Prison', '160', '250', '65', '5485', '5285', '0', null);
  44. INSERT INTO `list_golist` VALUES ('26', '26', 'Desert City of Muris - Oro', '180', '250', '71', '5199', '5236', '0', null);
  45. INSERT INTO `list_golist` VALUES ('27', '27', 'Desert of the Dead', '0', '250', '29', '5093', '5144', '0', null);
  46.  
Image
rl2171
Admin
Admin
 
Posts: 1706
Joined: Mon Aug 06, 2007 5:17 pm
Location: Sacramento, CA USA - GMT-8

Re: Rev [85]

Postby WiseGuy on Mon May 20, 2013 7:21 am

Trapper in case of price=0 (STB) if you do not want unexpected result in function RepairPrice:

before:
  1.    // Get The Pricefactor and Multiplier
  2.     PriceFactor = double(price / iDivisor);


added:
  1. if( price<1) price=1; 

that is not necessary, just to be make sure :lol:
It is nice to be important
but very very important to be nice
User avatar
WiseGuy
Pomic
Pomic
 
Posts: 112
Joined: Sat Nov 21, 2009 4:03 am
Location: Jakarta

Re: Rev [85]

Postby Circa on Mon May 20, 2013 7:51 am

WiseGuy wrote:Trapper in case of price=0 (STB) if you do not want unexpected result in function RepairPrice:

before:
  1.    // Get The Pricefactor and Multiplier
  2.     PriceFactor = double(price / iDivisor);


added:
  1. if( price<1) price=1; 

that is not necessary, just to be make sure :lol:


well nothing would happen, price = 0, then 0/iDivisor = 0, but if it was negative, then yeah, but might wanna LOG the msg, because price shouldn't be negative ever. problem would be if the iDivisor would ever be 0 or negative as well, but 0 would definitely cause problems.
Circa
Clown
Clown
 
Posts: 404
Joined: Sun Aug 23, 2009 5:52 am
Location: CA

Re: Rev [85]

Postby FransK on Mon May 20, 2013 11:18 am

Thanks for the review and feedback. I changed the code in the PakRepairItem from
  1. LONG bcost=Repairprice(bprice,thisitem.durability,thisitem.lifespan);
  2.  

to:
  1. // Make sure price is a valid number
  2.         // thx to WiseGuy and Circa
  3.         if( bprice<1){
  4.             bprice=1;
  5.             log(MSG_WARNING,"CHECK STB: 0 or negative item price for itemtype=%i, itemid=%i",thisitem.itemtype,thisitem.itemnum);
  6.         }
  7.  
  8.         LONG bcost=Repairprice(bprice,thisitem.durability,thisitem.lifespan);
  9.  


It will be in the next update.
thx!,
regards,
Frans.

Circa wrote:
WiseGuy wrote:Trapper in case of price=0 (STB) if you do not want unexpected result in function RepairPrice:

before:
  1.    // Get The Pricefactor and Multiplier
  2.     PriceFactor = double(price / iDivisor);


added:

that is not necessary, just to be make sure :lol:


well nothing would happen, price = 0, then 0/iDivisor = 0, but if it was negative, then yeah, but might wanna LOG the msg, because price shouldn't be negative ever. problem would be if the iDivisor would ever be 0 or negative as well, but 0 would definitely cause problems.
life's too short to complain.
User avatar
FransK
osiRose dev
osiRose dev
 
Posts: 24
Joined: Tue Apr 30, 2013 8:45 pm
Location: The Netherlands

Re: Rev [85]

Postby WiseGuy on Mon May 20, 2013 11:22 am

I try like this:
add this code to console.cpp:
  1.     if(strcasecmp( command, "bcost" )==0)
  2.     {
  3.         LONG bcost;
  4.         bcost=Repairprice(0,50,25);
  5.         Log( MSG_CONSOLE, "Price=0, bcost=%u", bcost );
  6.         bcost=Repairprice(1678,50,25);
  7.         Log( MSG_CONSOLE, "Price=1678, bcost=%u", bcost );
  8.         return true;
  9.     }
  10.  


return value:
Price=0, bcost= 2147483648
Price=1678, bcost= 341
It is nice to be important
but very very important to be nice
User avatar
WiseGuy
Pomic
Pomic
 
Posts: 112
Joined: Sat Nov 21, 2009 4:03 am
Location: Jakarta

Re: Rev [85]

Postby FransK on Mon May 20, 2013 11:33 am

Tbh i never tested with 0 or negative prices.

the number 2147483648 looks very familiar to me :)

I've already fixed the code, see post above. If an item costs 0, the item costs 1. that should prevent this little mishap.
thx-Frans

WiseGuy wrote:I try like this:
add this code to console.cpp:
  1.     if(strcasecmp( command, "bcost" )==0)
  2.     {
  3.         LONG bcost;
  4.         bcost=Repairprice(0,50,25);
  5.         Log( MSG_CONSOLE, "Price=0, bcost=%u", bcost );
  6.         bcost=Repairprice(1678,50,25);
  7.         Log( MSG_CONSOLE, "Price=1678, bcost=%u", bcost );
  8.         return true;
  9.     }
  10.  


return value:
Price=0, bcost= 2147483648
Price=1678, bcost= 341
life's too short to complain.
User avatar
FransK
osiRose dev
osiRose dev
 
Posts: 24
Joined: Tue Apr 30, 2013 8:45 pm
Location: The Netherlands


Return to Support - OsiRose Emulator

Who is online

Users browsing this forum: No registered users and 3 guests

cron