Pārlūkot izejas kodu

Updated STEAL skill (WIP), added a battle config option: 'skill_steal_max_tries' to set max number of stealing tries. It could help to fix stealing exploit on mobs with few drops

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@6367 54d463be-8e91-2dee-dedb-b68131a5f0ec
Lupus 19 gadi atpakaļ
vecāks
revīzija
687b2210a7
7 mainītis faili ar 32 papildinājumiem un 18 dzēšanām
  1. 3 0
      Changelog-Trunk.txt
  2. 7 0
      conf-tmpl/battle/skill.conf
  3. 5 0
      src/map/battle.c
  4. 1 0
      src/map/battle.h
  5. 1 1
      src/map/map.h
  6. 14 16
      src/map/pc.c
  7. 1 1
      src/map/skill.c

+ 3 - 0
Changelog-Trunk.txt

@@ -4,6 +4,9 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/04/29
+	* Updated STEAL skill (WIP), added a battle config option: [Lupus]
+	  'skill_steal_max_tries' to set max number of stealing tries.
+	  It could help to fix stealing exploit on mobs with few drops
 	* Added support for packet 0x229 (clif_changeoption). [Skotlex]
 	* Bumped up PACKETVER to 7 to enable use of packets 0x229 and 0x22c
 	  [Skotlex]

+ 7 - 0
conf-tmpl/battle/skill.conf

@@ -205,6 +205,13 @@ backstab_bow_penalty: yes
 // Use kRO new steal formula?
 skill_steal_type: yes
 
+// How many times you could try to steal from a mob.
+// Note: It might help to close stealing exploit on monstewrs with few/rare items
+// 0 = you can't steal at all
+// 1..255 = exact numbel of tries
+// 256 = there's no stealing tries limit
+skill_steal_max_tries: 256
+
 // Can Rogues plagiarize advanced job skills           
 // 0 = no restriction
 // 1 = only stalker may plagiarize advanced skills       

+ 5 - 0
src/map/battle.c

@@ -3826,6 +3826,7 @@ static const struct battle_data_short {
 	{ "pk_min_level",                      &battle_config.pk_min_level}, // [celest]
 	{ "skill_steal_type",                  &battle_config.skill_steal_type}, // [celest]
 	{ "skill_steal_rate",                  &battle_config.skill_steal_rate}, // [celest]
+	{ "skill_steal_max_tries",			&battle_config.skill_steal_max_tries}, // [Lupus]
 //	{ "night_darkness_level",              &battle_config.night_darkness_level}, // [celest]
 	{ "motd_type",                         &battle_config.motd_type}, // [celest]
 	{ "allow_atcommand_when_mute",         &battle_config.allow_atcommand_when_mute}, // [celest]
@@ -4226,6 +4227,7 @@ void battle_set_defaults() {
 	battle_config.pk_min_level = 55;
 	battle_config.skill_steal_type = 1;
 	battle_config.skill_steal_rate = 100;
+	battle_config.skill_steal_max_tries = 256;
 //	battle_config.night_darkness_level = 9;
 	battle_config.motd_type = 0;
 	battle_config.allow_atcommand_when_mute = 0;
@@ -4489,6 +4491,9 @@ void battle_validate_conf() {
 	if (battle_config.sg_miracle_skill_ratio > 10000)
 		battle_config.sg_miracle_skill_ratio = 10000;
 
+	if (battle_config.skill_steal_max_tries > 256)
+		battle_config.skill_steal_max_tries = 256;	
+
 #ifdef CELL_NOSTACK
 	if (battle_config.cell_stack_limit < 1)
 	  	battle_config.cell_stack_limit = 1;

+ 1 - 0
src/map/battle.h

@@ -353,6 +353,7 @@ extern struct Battle_Config {
 	unsigned short pk_min_level; // [celest]
 	unsigned short skill_steal_type; // [celest]
 	unsigned short skill_steal_rate; // [celest]
+	unsigned short skill_steal_max_tries; //max steal skill tries on a mob. if=256, then w/o limit [Lupus]
 //	unsigned short night_darkness_level; // [celest]
 	unsigned short motd_type; // [celest]
 	unsigned short allow_atcommand_when_mute; // [celest]

+ 1 - 1
src/map/map.h

@@ -880,7 +880,7 @@ struct mob_data {
 	struct {
 		unsigned skillstate : 8;
 		unsigned aggressive : 1; //Signals whether the mob AI is in aggressive mode or reactive mode. [Skotlex]
-		unsigned steal_flag : 1;
+		unsigned steal_flag : 8; //number of steal tries (to prevent steal exploit on mobs with few items) [Lupus]
 		unsigned steal_coin_flag : 1;
 		unsigned soul_change_flag : 1; // Celest
 		unsigned alchemist: 1;

+ 14 - 16
src/map/pc.c

@@ -2928,11 +2928,12 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl)
 	
 	md=(struct mob_data *)bl;
 
-	if(md->state.steal_flag || status_get_mode(bl)&MD_BOSS || md->master_id ||
+
+	if(md->state.steal_flag>battle_config.skill_steal_max_tries || status_get_mode(bl)&MD_BOSS || md->master_id ||
 		(md->class_>=1324 && md->class_<1364) || // prevent stealing from treasure boxes [Valaris]
 		map[md->bl.m].flag.nomobloot ||        // check noloot map flag [Lorky]
 		md->sc.data[SC_STONE].timer != -1 || md->sc.data[SC_FREEZE].timer != -1 //status change check
-  )
+  	)
 		return 0;
 	
 	skill = battle_config.skill_steal_type == 1
@@ -2942,24 +2943,21 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl)
 	if (skill < 1)
 		return 0;
 
-	j = i = rand()%MAX_MOB_DROP; //Pick one mobs drop slot.
-	do {
-		//if it's empty, we check one by one, till find an item
-		i--;
-		if(i<0)
-		i=MAX_MOB_DROP-1; 
+	for(i = 0; i<MAX_MOB_DROP; i++)//Pick one mobs drop slot.
+	{
 		itemid = md->db->dropitem[i].nameid;
-		//now try all 10 slots till success
-		if(itemid <= 0 || (itemdb_type(itemid) == 6 && pc_checkskill(sd,TF_STEAL) <= 5))
-			continue;
-	} while (i != j &&
-		rand() % 10000 > ((md->db->dropitem[i].p * skill) / 100 + sd->add_steal_rate)); //fixed rate. From Freya [Lupus]
 
-	if (i == j)
+		if(itemid <= 0 || (itemid>4000 && itemid<5000 && pc_checkskill(sd,TF_STEAL) <= 5))
+			continue;
+		if(rand() % 10000 > ((md->db->dropitem[i].p * skill) / 100 + sd->add_steal_rate))
+			break;
+	}
+	if (i == MAX_MOB_DROP)
 		return 0;
 
-	md->state.steal_flag = 1;
-	
+	if(md->state.steal_flag < battle_config.skill_steal_max_tries)
+		md->state.steal_flag++;
+
 	memset(&tmp_item,0,sizeof(tmp_item));
 	tmp_item.nameid = itemid;
 	tmp_item.amount = 1;

+ 1 - 1
src/map/skill.c

@@ -967,7 +967,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 				skill_castend_damage_id(src,bl,HT_BLITZBEAT,(skill<lv)?skill:lv,tick,0xf00000);
 			}
 			// Gank
-			if(dstmd && !dstmd->state.steal_flag && sd->status.weapon != W_BOW && (skill=pc_checkskill(sd,RG_SNATCHER)) > 0 &&
+			if(dstmd && dstmd->state.steal_flag<battle_config.skill_steal_max_tries && sd->status.weapon != W_BOW && (skill=pc_checkskill(sd,RG_SNATCHER)) > 0 &&
 				(skill*15 + 55) + (skill2 = pc_checkskill(sd,TF_STEAL))*10 > rand()%1000) {
 				if(pc_steal_item(sd,bl))
 					clif_skill_nodamage(src,bl,TF_STEAL,skill2,1);