summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c5
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/map.h2
-rw-r--r--src/map/pc.c30
-rw-r--r--src/map/skill.c2
5 files changed, 22 insertions, 18 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 15dabe24d..408a2fa31 100644
--- a/src/map/battle.c
+++ b/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;
diff --git a/src/map/battle.h b/src/map/battle.h
index ce1468151..d0511eb53 100644
--- a/src/map/battle.h
+++ b/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]
diff --git a/src/map/map.h b/src/map/map.h
index 38e4d02a4..e7e821bc1 100644
--- a/src/map/map.h
+++ b/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;
diff --git a/src/map/pc.c b/src/map/pc.c
index 81a687f06..90f3fa001 100644
--- a/src/map/pc.c
+++ b/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;
diff --git a/src/map/skill.c b/src/map/skill.c
index 5696c82c5..5034febed 100644
--- a/src/map/skill.c
+++ b/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);