Jump to content
  • 0

callfunc on every attack you make, possible?


Question

Posted

Hi all,

Just wondering if it's possible to trigger a callfunc script on every time you damage a monster?

- could be inserted on a weapon script?
- npc script something like onNPCkill but while attacking not after killing the monster?

11 answers to this question

Recommended Posts

  • 0
Posted

It's possible, but it's also... very intensive for your server and I would highly recommend against it.

In battle.cpp, in battle_calc_damage, add the NPC call:

	if (bl->type == BL_PC) {
		npc_event_do_id("MyNPC::OnEvent", bl->id);
	}

And with the matching script:

-	script	MyNPC	-1,{
	end;
OnEvent:
	//callfunc("F_Function");
	dispbottom "You have attacked.";
	end;
}

 

It would be much better to add code in the source for what you want to do instead.

  • 0
Posted
1 hour ago, Tokei said:

It's possible, but it's also... very intensive for your server and I would highly recommend against it.

In battle.cpp, in battle_calc_damage, add the NPC call:


	if (bl->type == BL_PC) {
		npc_event_do_id("MyNPC::OnEvent", bl->id);
	}

And with the matching script:


-	script	MyNPC	-1,{
	end;
OnEvent:
	//callfunc("F_Function");
	dispbottom "You have attacked.";
	end;
}

 

It would be much better to add code in the source for what you want to do instead.

This script would be on a script generated monster spawn and not for all monster wide. Would there be a workaround for a script based structure without a source mod?

I'm also thinking of OnTouch behavior, however, there would be no stopping because for the callfunc to work it must be on a loop.

The end goal is while you are attacking (every hit), you get a chance to obtain certain item by chance.


 

  • 0
Posted
16 minutes ago, LearningRO said:

just use custom script command form tokei

OnEvent:
if (killerid == 1002(yourmobid) {
do script

}

Without the source mod? or still with it?

  • 0
Posted

You'd still need to modify your source to do that. You can be more restrictive as well and attach more "parameters". killerid won't work as it isn't added to the script yet. So something like...

	if (src && src->type == BL_PC && bl->type == BL_MOB && damage > 0) {
		struct mob_data *md = (struct mob_data *)bl;
		mapreg_setreg(reference_uid(add_str("$@attacked_mid"), 0), md->id);
		mapreg_setreg(reference_uid(add_str("$@attacked_gid"), 0), md->bl.id);
		npc_event_do_id("MyNPC::OnEvent", src->id);
	}
OnEvent:
	switch($@attacked_mid) {
		case 1002:
			if (rand(100) < 5) {
				getitem 501, 1;
			}
			
			break;
	}
	
	end;

 

  • Love 1
  • 0
Posted

Personally though, I'd say you should make a yaml conf file where you define drop groups with a chance, then assign a mob to a drop group in your mob_db.yml file instead. It's more work, but it's also much more effecient than running a script. Then again, that requires more source knowledge I suppose.

  • 0
Posted
Just now, Tokei said:

Personally though, I'd say you should make a yaml conf file where you define drop groups with a chance, then assign a mob to a drop group in your mob_db.yml file instead. It's more work, but it's also much more effecient than running a script. Then again, that requires more source knowledge I suppose.

that would be correct. yaml is just new to me still so I think I'll stick with the script.

However, question.. as long as other monsters are not included on the "case", they won't be triggered right? what I mean is that it won't affect the server load if you attack other monsters?

Thank you so much for the clarification and the assistance.

  • 0
Posted
1 hour ago, Almond Snicker said:

that would be correct. yaml is just new to me still so I think I'll stick with the script.

However, question.. as long as other monsters are not included on the "case", they won't be triggered right? what I mean is that it won't affect the server load if you attack other monsters?

Thank you so much for the clarification and the assistance.

It will affect your server load, yes. You would need to add a restriction in the source such as:
 

	if (src && src->type == BL_PC && bl->type == BL_MOB && damage > 0) {
		struct mob_data *md = (struct mob_data *)bl;
		
		if (md->id == 1002) {
			mapreg_setreg(reference_uid(add_str("$@attacked_mid"), 0), md->id);
			mapreg_setreg(reference_uid(add_str("$@attacked_gid"), 0), md->bl.id);
			npc_event_do_id("MyNPC::OnEvent", src->id);
		}
	}

That on its own would be more reasonable, but if you have... I don't know, 10 people attacking the mob with 193 aspd, I'd be concerned. You'd probably want to do it all in the source instead, or at the very least put the chance of drop in the source. Something like...

	if (src && src->type == BL_PC && bl->type == BL_MOB && damage > 0) {
		struct mob_data *md = (struct mob_data *)bl;
		struct map_session_data *sd = (struct map_session_data *)src;
		
		if (md->id == 1002 && (rnd() % 100) < 5) {	// 5% chance
			struct item it;
			t_itemid nameid = 501;
			int flag;
			
			memset(&it,0,sizeof(it));
			it.nameid = nameid;
			it.identify = 1;
			it.bound = BOUND_NONE;
			
			// Assuming it is not a pet egg, you can skip some checks. Up to you at this point.
			if ((flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT))) {
				clif_additem(sd, 0, 0, flag);
			}
		}
	}

 

  • 0
Posted
1 hour ago, Tokei said:

It will affect your server load, yes. You would need to add a restriction in the source such as:
 


	if (src && src->type == BL_PC && bl->type == BL_MOB && damage > 0) {
		struct mob_data *md = (struct mob_data *)bl;
		
		if (md->id == 1002) {
			mapreg_setreg(reference_uid(add_str("$@attacked_mid"), 0), md->id);
			mapreg_setreg(reference_uid(add_str("$@attacked_gid"), 0), md->bl.id);
			npc_event_do_id("MyNPC::OnEvent", src->id);
		}
	}

That on its own would be more reasonable, but if you have... I don't know, 10 people attacking the mob with 193 aspd, I'd be concerned. You'd probably want to do it all in the source instead, or at the very least put the chance of drop in the source. Something like...


	if (src && src->type == BL_PC && bl->type == BL_MOB && damage > 0) {
		struct mob_data *md = (struct mob_data *)bl;
		struct map_session_data *sd = (struct map_session_data *)src;
		
		if (md->id == 1002 && (rnd() % 100) < 5) {	// 5% chance
			struct item it;
			t_itemid nameid = 501;
			int flag;
			
			memset(&it,0,sizeof(it));
			it.nameid = nameid;
			it.identify = 1;
			it.bound = BOUND_NONE;
			
			// Assuming it is not a pet egg, you can skip some checks. Up to you at this point.
			if ((flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT))) {
				clif_additem(sd, 0, 0, flag);
			}
		}
	}

 

damn.. I really appreciate the effort @Tokei, I'll try everything out on my end. have a great day ahead!

  • 0
Posted

I had fun with that before

however , it's not recommended

i suggest to rethink your idea to make everything work inside the src

this will spam events in the player's queue if it's misused!

 

 

 

  • 0
Posted

If you wont do it in src its better to not do. 
When I had one of my first servers I went with the idea of doing this on a production server. The script was not that complex and lagged the entire server when players with a lot of aspd attacked the mob.

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.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...