Jump to content
  • 0

killing a monster increase their item drop rates


alkhaleej

Question


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  58
  • Reputation:   5
  • Joined:  09/21/12
  • Last Seen:  

Is it possible to make a script with the following conditions?

1. I kill a poring - all of its item drop rate will be default %

2. I kill another poring - all of its item drop rate will have a total increase of 0.01%

3. I kill a fabre - all of its item drop rate will be default %

4. I kill another poring - all of its item drop rate will have a total increase of 0.02%

5. I kill another fabre - all of its item drop rate will have a total increase of 0.01%

6. I kill another poring - all of its item drop rate will have a total increase of 0.03%

thank you.

Link to comment
Share on other sites

12 answers to this question

Recommended Posts


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

This should do what you want (Havent Tested for Errors).

CREATE TABLE `ragnarok`.`custom_drop_rate` (
`char_id` INT(11) NOT NULL AUTO_INCREMENT ,
`mob_id` SMALLINT(6) UNSIGNED NULL ,
`kills` INT UNSIGNED NULL ,
PRIMARY KEY (`char_id`) );

- script CustomDropRates -1,{
OnNPCKillEvent:
callfunc "DropItemRate";
end;

function script DropItemRate {
set @i,0;
set @dropID,0;
set @j,0;
deletearray $@MobDrop_item[0],128;
deletearray $@MobDrop_rate[0],128;
getmobdrops(killedrid);
if($@MobDrop_count<=0){end;}
query_sql"SELECT `kills` FROM `custom_drop_rate` WHERE `mob_id`='"+killedrid+"' AND `char_id`='"+getcharid(0)+"'",.@kills;
iDropItemLoop:
set @i,rand(1,10000);
if(@dropID == $@MobDrop_count){dispbottom "Success"; end;}
//Checking to see if its an equipment type item.
if($@MobDrop_rate[@dropID]>=10000 && getiteminfo($@MobDrop_item[@dropID],2)==4 ||
  $@MobDrop_rate[@dropID]>=10000 && getiteminfo($@MobDrop_item[@dropID],2)==5)
//Deletes the "Equipment" type item if it had a normal Drop Rate of 100%
{delitem2 $@MobDrop_item[@dropID],1,0,0,0,0,0,0,0; goto iGetItem;}
//Deletes the specified item if it had a normal Drop rate of 100%
if($@MobDrop_rate[@dropID]>=10000){delitem $@MobDrop_item[@dropid],1; goto iGetItem;}
iGetItem:
//Checks to see if @i is <= Drop Chance OR if @i >= 100% drop.
//If all is true it will give you the item. So if the item was deleted from above,
//You got it back now.
if(@i <= ($@MobDrop_rate[@dropID] + .@kills) )
{getitem $@MobDrop_item[@dropID],1;
set @dropID,@dropID+1; goto iDropItemLoop;}
set @dropID,@dropID+1; goto iDropItemLoop;
end;
}

Note - If an item drops at 100% this script will delete it from your inventory, BUT it will give you another one back. (Assuming the script works as intended). Sorry, but there is no way around this. This is to ensure you don't kill a monster and get the drops twice. Example: Kill 1 Poring get 2 Poring Cards.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  58
  • Reputation:   5
  • Joined:  09/21/12
  • Last Seen:  

Thanks GmOcean. I'll test this right now. I will let u know the results soon.

Erm, it is not updating the sql table custom_drop_table.

I think the script needs an update function perhaps?

By the way, am I correct that the script needs a right curly after the first end; ?

- script CustomDropRates -1,{

OnNPCKillEvent:

callfunc "DropItemRate";

end;

}

Edited by alkhaleej
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

Oh yea sorry lol, forgot about that xD.

Your right lol. Looks like i forgot that as well... Well, you can look around or google how to do it, its not too hard. It'll be a good learnign experience.

Edited by GmOcean
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  141
  • Reputation:   15
  • Joined:  01/08/12
  • Last Seen:  

Nice script. I like to see this script completed by expert to reduce load in my mind.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  58
  • Reputation:   5
  • Joined:  09/21/12
  • Last Seen:  

query_sql"IF EXISTS(SELECT * FROM `custom_drop_rate` WHERE `char_id`='"+getcharid(0)+"', `mob_id`='"+killedrid+"') ||

UPDATE `custom_drop_rate` SET `kills` = `kills` + 1 WHERE `char_id`='"+getcharid(0)+"', `mob_id`='"+killedrid+"' ||

ELSE INSERT INTO `custom_drop_rate` VALUES ('"+getcharid(0)+"', '"+killedrid+"', 1)";

I just made this up I am a noob at this. I've just read some articles pertaining to SQL syntaxes. But I am getting errors. Can anyone suggest where I am wrong? Additionally, || - is this correct to have the query continue on the next line?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  72
  • Topics Per Day:  0.02
  • Content Count:  2997
  • Reputation:   1130
  • Joined:  05/27/12
  • Last Seen:  

Additionally, || - is this correct to have the query continue on the next line?

No, it's + (as with any other string).

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

I could write up a script to reduce the load by simply making it only ping SQL for information when they logout/in OR on first kill of that mob. But, that would mean storing most information into a variable/array. And as Euphy pointed out to me earlier today (since i forgot), Arrays can only hold upto 128 values. So either I would need to make multiple arrays/variables, or store the information into 1array using bit format, thus saving space and the load, but making the script very un-user friendly as only advanced/expert scripters would know how to make changes.

Edit: Though now that I think about it, you can't make this script 100% bug proof with script commands only. You would need a src edit. Because at the moment there is no possible way to detect if a player got a drop from a monster. You see in my script, i detect if an item drops at 100%, if it does, it deletes it. But i can't detect if it dropped at 1% and you got it. I could easily delete 1 of each item the mob will drop regardless, so, if they have it in their inventory its gone. Thing is though, if it didn't drop, they will be -1 of the item, and the chance of them getting it back depends on how many they killed OR just pure luck if its the first kill since you added in this script.

Edit2:

- script CustomDropRates -1,{
OnInit:
//Whether or not the script is Map Exclusive
set $@CDR_mode,1; // 0 = Disabled | 1 = Enabled
setarray $@MapOkay$[0],"Enter","Map","Names","Here";
end;
OnPCLoginEvent:
iLoop: //Incase there are more than 128 different mobs killed.
set .@total,(query_sql"SELECT `mob_id`,`kills` FROM `custom_drop_rate` WHERE `kills`>='1' LIMIT 128",@CDR_id,@CDR_kills);
for(set .@i,0; .@i<.@total; set .@i,.@i+1)
   {setd "@cdr_id_"+.@j+"["+.@i+"]",@CDR_id[.@i];
 setd "@cdr_kills_"+.@j+"["+.@i+"]",@CDR_kills[.@i];}
if(.@total<128){end;}
set .@j,.@j+1;
set @j,.@j; //Stores information for later use.
goto iLoop; //Loops back to create another temporary array if there are more than 128 mobs.
end;
OnPCLogoutEvent:
set .@a,@j;
iLoop2:
if(.@j>=.@a)
   {set .@send$,"))"; set .@query$,.@query$ + .@send$;
 query_sql""+.@query$+""; end;}
set .@query$,"(REPLACE INTO `custom_drop_rate` VALUES(";
for( set .@i,0; getarraysize(getd("@cdr_kills_"+.@j+"")); set .@i,.@i+1)
   {if(.@i>0){set .@query$, .@query$ +",";}
 set .@query$, .@query$ + "'"+ getd("@cdr_kills_"+.@j+"["+.@i+"]") +"'";}
set .@j,.@j+1;
goto iLoop2;
end;
OnNPCKillEvent:
set @mobid,killedrid;
if($@CDR_mode)
   {getmapxy(.@m$,.@x,.@y,0);
 for(set .@i,0; .@i<getarraysize($@MapOkay$[0]); set .@i,.@i+1)
	 {if( .@m$ == $@MapOkay$[.@i] ){callfunc "DropItemRate";}}
 end;}
callfunc "DropItemRate";
end;
}
function script DropItemRate {
set @i,0;
set @dropID,0;
deletearray $@MobDrop_item[0],128;
deletearray $@MobDrop_rate[0],128;
getmobdrops(@mobid);
if(!$@MobDrop_count){end;}
set .@count,$@MobDrop_count;
copyarray .@MobDrop_item[0],$@MobDrop_item[0],.@count;
copyarray .@MobDrop_rate[0],$@MobDrop_rate[0],.@count;
iForLoop: //This where we will get our monster's kill count. AND Updates it +1.
if(.@a >= @j && .@kd==1){goto iDropItemLoop;}
//Adds the monster to the database if its the first kill. And continues as normal.
if(.@a >= @j && .@kd!=1)
   {query_sql"INSERT INTO `mob_id`,`kills` VALUES('"+@mobid+"','1') FROM `custom_drop_rate` WHERE `char_id`='"+getcharid(0)+"'"; goto iDropItemLoop;}
for(set .@j,0; .@j<getarraysize(getd("@cdr_id_"+.@a+"")); set .@j,.@j+1;)
   {if( getd("@cdr_id_"+.@a+"["+.@j+"]") == @mobid )
	 {setd "@cdr_kills_"+.@a+"["+.@+"]",(getd("@cdr_kills_"+.@a+"["+.@j+"]")+1); set .@kills,getd("@cdr_kills_"+.@a+"["+.@j+"]"); set .@kd,1; goto iDropItemLoop;}}
set .@a,.@a+1;
goto iForLoop;
end;
iDropItemLoop:
set @i,rand(1,10000);
if(@dropID == .@count){/*dispbottom "Success"*/ end;}
//Checking to see if its an equipment type item.
if(.@MobDrop_rate[@dropID]>=10000 && getiteminfo(.@MobDrop_item[@dropID],2)==4 ||
.@MobDrop_rate[@dropID]>=10000 && getiteminfo(.@MobDrop_item[@dropID],2)==5)
//Deletes the "Equipment" type item if it had a normal Drop Rate of 100%
   {delitem2 .@MobDrop_item[@dropID],1,0,0,0,0,0,0,0; goto iGetItem;}
//Deletes the specified item if it had a normal Drop rate of 100%
if(.@MobDrop_rate[@dropID]>=10000){delitem .@MobDrop_item[@dropid],1; goto iGetItem;}
i//Deletes the specified item if it had a normal Drop rate of 100%
if(.@MobDrop_rate[@dropID]>=10000){delitem .@MobDrop_item[@dropid],1; goto iGetItem;}
iGetItem:
//Checks to see if @i is <= Drop Chance OR if @i >= 100% drop.
//If all is true it will give you the item. So if the item was deleted from above,
//You got it back now.
if(@i <= (.@MobDrop_rate[@dropID] + .@kills) )
   {getitem .@MobDrop_item[@dropID],1;
set @dropID,@dropID+1; goto iDropItemLoop;}
set @dropID,@dropID+1; goto iDropItemLoop;
end;
}

Note - Remeber that with current script commands we can't detect if a player recieved an item from a monster if its not 100% drop rate.

How it works.

Player Logs in -> Gets info from SQL -> stores information in variables -> player kills monster -> retrives kill count->updates kill count ->(if haven't killed the monster before-> add info to SQL ->) calculates drops -> gives items

Edited by GmOcean
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  58
  • Reputation:   5
  • Joined:  09/21/12
  • Last Seen:  

2. I kill another poring - all of its item drop rate will have a total increase of 0.01%

Erm I would just like to ask if the script does the above conditions with a detailed example:

Poring Drops based on kro renewal rates:

Apple 10%

Apple 1.5%

Unripe Apple 0.2%

Empty Bottle 15%

Jellopy 70%

Sticky Mucus 4%

Knife [4] 1%

Poring Card 0.01%

Each successful kill of Poring adds 0.01% on all of the item it drops. So at 9,999 kills of porings, I will get definitely one poring card since each kill adds 0.01% for all items (Poring will drop its card by 100% chance). By that time also, Poring will drop Knife [4] at 100.99% and Jellopy at 169.99%. To sum it up we increase all drop rates for 1 monster with a fixed amount of % each kill.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

Yes it does exactly that. Atleast it's supposed to. I have not tested the script, so if you would like to use it, i'm eager to here the results.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  58
  • Reputation:   5
  • Joined:  09/21/12
  • Last Seen:  

Adding it now and testing.

[sql]: DB error - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' `kills` VALUES('1002','1') FROM `custom_drop_rate` WHERE `char_id`='150000'' at line 1

I think the problem is:

 {query_sql"INSERT INTO `mob_id`,`kills` VALUES('"+@mobid+"','1') FROM `custom_drop_rate` WHERE `char_id`='"+getcharid(0)+"'"; goto iDropItemLoop;}

So I tried to change it to:

 {query_sql"INSERT INTO `custom_drop_rate`(`mob_id`,`kills`) VALUES('"+@mobid+"','1') WHERE `char_id`='"+getcharid(0)+"'"; goto iDropItemLoop;}

but still the same.

Edited by alkhaleej
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

I figured out the problem, however, it made me realize i was telling SQL to do something it can't. So, now we gotta decide, do 1 large query when they login/out. OR just update the database as they kill. I'll work on it later when I have time, but for now I'm thinking update as we go.

Okay, so i was going to fix this script till i discovered an exploit which can't be fixed by normal script commands at the moment. The exploit being, that if a player doesn't have @autoloot 100% on. Then they can litterally, get 2x drops from monsters. As the script will give them items, based on kills, and the mobs will drop them to the ground. Sorry, but until the src for monsters drops becomes more flexible, like lets say, stopping drops if monsters are listed in a certain db file, this exploit will continue to exist. Only alternativve would be to set all drop rates to 0, AFTER making a duplicate db with the same info as the mob_db.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  58
  • Reputation:   5
  • Joined:  09/21/12
  • Last Seen:  

Yes I noticed this. I killed a Poring and a get 2 Jellopies from killing just one. Anyway thanks for the support GmOcean. I'll try studying more about scripting from now on.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...