Jump to content
  • 0

[SOLVED] HELP Change Steal Skill Limitation


namerpus18

Question


  • Group:  Members
  • Topic Count:  38
  • Topics Per Day:  0.07
  • Content Count:  95
  • Reputation:   1
  • Joined:  11/15/22
  • Last Seen:  

Notes

  • Only items dropped by monsters can be stolen.
  • A successful attempt will not affect what is dropped when the monster dies.
  • Counter-intuitively, this skill cannot be used while in stealth. All robberies must be done out in the open.
  • After success, it is not possible to steal again from the same target. 
  • Boss monsters cannot be stolen from.

//=========================================================================

//** Do i need to change this value to 255?

//from "skill.c"

// How many times you could try to steal from a mob.
// Note: It helps to avoid stealing exploit on monsters with few rare items
// Use 0 to disable (Max allowed value is 255)
skill_steal_max_tries: 0


//==========================================================================

//*==========================================

// How can i make it work that i can use steal until mob dies. You can obtain same items again and again. I dont know but i think there is this thing called "skill_steal_max success" that is located somewhere i cannot find that also limit the skill to be used only once per monster. And someone told me i need to make the conf to the "conf/import/battle.conf". I am planning to make a new skill from it.

Thank you so much, total noob here
 

//from "pc.c"

 * Steal an item from bl (mob).
 * Return:
 *   0 = fail
 *   1 = succes
 *------------------------------------------*/
static int pc_steal_item(struct map_session_data *sd, struct block_list *bl, uint16 skill_lv)
{
    int i,itemid,flag;
    int rate;
    struct status_data *sd_status, *md_status;
    struct mob_data *md = BL_CAST(BL_MOB, bl);
    struct item tmp_item;
    struct item_data *data = NULL;

    if (sd == NULL || md == NULL)
        return 0;

    if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
        return 0;

    sd_status= status->get_status_data(&sd->bl);
    md_status= status->get_status_data(bl);

    if (md->master_id || md_status->mode&MD_BOSS || mob_is_treasure(md) ||
        map->list[bl->m].flag.nomobloot || // check noloot map flag [Lorky]
        (battle_config.skill_steal_max_tries && //Reached limit of steal attempts. [Lupus]
            md->state.steal_flag++ >= battle_config.skill_steal_max_tries)
    ) { //Can't steal from
        md->state.steal_flag = UCHAR_MAX;
        return 0;
    }

    // base skill success chance (percentual)
    rate = (sd_status->dex - md_status->dex)/2 + skill_lv*6 + 4 + sd->bonus.add_steal_rate;

    if( rate < 1 )
        return 0;

    // Try dropping one item, in the order from first to last possible slot.
    // Droprate is affected by the skill success rate.
    for (i = 0; i < MAX_MOB_DROP; i++) {
        if (md->db->dropitem[i].nameid == 0)
            continue;
        if ((data = itemdb->exists(md->db->dropitem[i].nameid)) == NULL)
            continue;
        if (data->type == IT_CARD)
            continue;
        if (rnd() % 10000 < apply_percentrate(md->db->dropitem[i].p, rate, 100))
            break;
    }
    if (i == MAX_MOB_DROP)
        return 0;

    itemid = md->db->dropitem[i].nameid;
    memset(&tmp_item,0,sizeof(tmp_item));
    tmp_item.nameid = itemid;
    tmp_item.amount = 1;
    tmp_item.identify = itemdb->isidentified2(data);
    flag = pc->additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER);

    //TODO: Should we disable stealing when the item you stole couldn't be added to your inventory? Perhaps players will figure out a way to exploit this behaviour otherwise?
    //md->state.steal_flag = UCHAR_MAX; //you can't steal from this mob any more

    if(flag) { //Failed to steal due to overweight
        clif->additem(sd,0,0,flag);
        return 0;
    }

    if(battle_config.show_steal_in_same_party)
        party->foreachsamemap(pc->show_steal,sd,AREA_SIZE,sd,tmp_item.nameid);

    //Logs items, Stolen from mobs [Lupus]
    logs->pick_mob(md, LOG_TYPE_STEAL, -1, &tmp_item, data);

    return 1;
}

 

Edited by namerpus18
Link to comment
Share on other sites

9 answers to this question

Recommended Posts

  • 0

  • Group:  Members
  • Topic Count:  8
  • Topics Per Day:  0.01
  • Content Count:  58
  • Reputation:   112
  • Joined:  10/01/22
  • Last Seen:  

This is the line that blocks the steal attempt

if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
        return 0;

In particular, md->state.steal_flag is set to UCHAR_MAX after a successful steal.  You could simply remove that part of the line to allow stealing from that monster again and again.

 

if(( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
        return 0;

Or you can just remove that code entirely if you don't want anything to block stealing attempts.

 

Also, leave the configuration for steal_max_tries at 0, that disables it.

Edited by Tero
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  38
  • Topics Per Day:  0.07
  • Content Count:  95
  • Reputation:   1
  • Joined:  11/15/22
  • Last Seen:  

21 hours ago, Tero said:

This is the line that blocks the steal attempt

if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
        return 0;

In particular, md->state.steal_flag is set to UCHAR_MAX after a successful steal.  You could simply remove that part of the line to allow stealing from that monster again and again.

 

if(( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
        return 0;

Or you can just remove that code entirely if you don't want anything to block stealing attempts.

 

Also, leave the configuration for steal_max_tries at 0, that disables it.

Hello, I tried this last night wasn't able to make it work. Got curious a bit I even tried editing return 1 to return 0 but it still make SUCCESS steal. As script return 1 = success and return 0 = fail as far as I understand the script. 

I saw something called skill_steal_max_success somewhere i cant remember where exactly though ?

 

Thank you

 

Edited by namerpus18
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  8
  • Topics Per Day:  0.01
  • Content Count:  58
  • Reputation:   112
  • Joined:  10/01/22
  • Last Seen:  

You don't actually want it to return at all at that point (regardless of the return status), the actual giving of the item is done near the end of the procedure, so if it returns early, you won't get an item. 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  38
  • Topics Per Day:  0.07
  • Content Count:  95
  • Reputation:   1
  • Joined:  11/15/22
  • Last Seen:  

4 hours ago, Tero said:

You don't actually want it to return at all at that point (regardless of the return status), the actual giving of the item is done near the end of the procedure, so if it returns early, you won't get an item. 

* Steal an item from bl (mob).
 * Return:
 *   0 = fail
 *   1 = succes
 *------------------------------------------*/
static int pc_steal_item(struct map_session_data *sd, struct block_list *bl, uint16 skill_lv)
{
	int i,itemid,flag;
	int rate;
	struct status_data *sd_status, *md_status;
	struct mob_data *md = BL_CAST(BL_MOB, bl);
	struct item tmp_item;
	struct item_data *data = NULL;

	if (sd == NULL || md == NULL)
		return 0;

	if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
		return 0;

	sd_status= status->get_status_data(&sd->bl);
	md_status= status->get_status_data(bl);

	if (md->master_id || md_status->mode&MD_BOSS || mob_is_treasure(md) ||
		map->list[bl->m].flag.nomobloot || // check noloot map flag [Lorky]
		(battle_config.skill_steal_max_tries && //Reached limit of steal attempts. [Lupus]
			md->state.steal_flag++ >= battle_config.skill_steal_max_tries)
	) 
	{ //Can't steal from
		md->state.steal_flag = UCHAR_MAX;
		return 0;
	}

	// base skill success chance (percentual)
	rate = (sd_status->dex - md_status->dex)/2 + skill_lv*6 + 4 + sd->bonus.add_steal_rate;

	if( rate < 1 )
		return 0;

	// Try dropping one item, in the order from first to last possible slot.
	// Droprate is affected by the skill success rate.
	for (i = 0; i < MAX_MOB_DROP; i++) {
		if (md->db->dropitem[i].nameid == 0)
			continue;
		if ((data = itemdb->exists(md->db->dropitem[i].nameid)) == NULL)
			continue;
		if (data->type == IT_CARD)
			continue;
		if (rnd() % 10000 < apply_percentrate(md->db->dropitem[i].p, rate, 100))
			break;
	}
	if (i == MAX_MOB_DROP)
		return 0;

	itemid = md->db->dropitem[i].nameid;
	memset(&tmp_item,0,sizeof(tmp_item));
	tmp_item.nameid = itemid;
	tmp_item.amount = 1;
	tmp_item.identify = itemdb->isidentified2(data);
	flag = pc->additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER);

	//TODO: Should we disable stealing when the item you stole couldn't be added to your inventory? Perhaps players will figure out a way to exploit this behaviour otherwise?
	md->state.steal_flag = UCHAR_MAX; //you can't steal from this mob any more

	if(flag) { //Failed to steal due to overweight
		clif->additem(sd,0,0,flag);
		return 0;
	}

	if(battle_config.show_steal_in_same_party)
		//party->foreachsamemap(pc->show_steal,sd,AREA_SIZE,sd,tmp_item.nameid);

	Logs items, Stolen from mobs [Lupus]
	logs->pick_mob(md, LOG_TYPE_STEAL, -1, &tmp_item, data);

	return 1;
}
 

What i have done so far from analyzing the best as i can are:

1.

//I removed this
if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check
		return 0;

2.

//I  also removed this

{ //Can't steal from
		md->state.steal_flag = UCHAR_MAX;
		return 0;
	}

3.

//I also removed this one

//TODO: Should we disable stealing when the item you stole couldn't be added to your inventory? Perhaps players will figure out a way to exploit this behaviour otherwise?
	md->state.steal_flag = UCHAR_MAX; //you can't steal from this mob any more

 

I'm very doubtful of what im doing and feeling sorry for the codes im messing out. feels like i am murdering them ?

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  8
  • Topics Per Day:  0.01
  • Content Count:  58
  • Reputation:   112
  • Joined:  10/01/22
  • Last Seen:  

I don't think you should need to remove sections 2 and 3, but it looks like it should work.  You recompiled your server and restarted after making the change and it still doesn't work?

 

Just tested it myself, with the change I suggested in the first post, it works, I can now steal repeatedly from the same enemy.

Edited by Tero
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  38
  • Topics Per Day:  0.07
  • Content Count:  95
  • Reputation:   1
  • Joined:  11/15/22
  • Last Seen:  

5 hours ago, Tero said:

I don't think you should need to remove sections 2 and 3, but it looks like it should work.  You recompiled your server and restarted after making the change and it still doesn't work?

 

Just tested it myself, with the change I suggested in the first post, it works, I can now steal repeatedly from the same enemy.

You mean to recompiling the server is to rerun "run-server.bat " right after I edited the script using notepad? Ya i did that after editing the "pc.c" can you do me a favor to copy yours? I really dont know what i did wrong I carefully check it and it still wont work. Thank you

Edited by namerpus18
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  8
  • Topics Per Day:  0.01
  • Content Count:  58
  • Reputation:   112
  • Joined:  10/01/22
  • Last Seen:  

You have to recompile the server using visual studio after making changes to the source code.  If you have visual studio already, just open up rathena.sln and select to "Build Solution", otherwise you might have to download it (it's free).  Make sure to install the files to compile C++.  I'm pretty sure there's guides on it somewhere.

  • Upvote 1
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  3
  • Reputation:   0
  • Joined:  11/20/22
  • Last Seen:  

thank you i am working on it. though i could not find a noob friend guide to make it work via VS and Cmd. I tried cmder but i think its not working anymore.

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  38
  • Topics Per Day:  0.07
  • Content Count:  95
  • Reputation:   1
  • Joined:  11/15/22
  • Last Seen:  

[SOLVED]

Thank you everyone.

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...