Jump to content
  • 0

callfunc on every attack you make, possible?


Gouki

Question


  • Group:  Members
  • Topic Count:  82
  • Topics Per Day:  0.06
  • Content Count:  241
  • Reputation:   11
  • Joined:  08/12/20
  • Last Seen:  

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?

Link to comment
Share on other sites

11 answers to this question

Recommended Posts

  • 0

  • Group:  Members
  • Topic Count:  16
  • Topics Per Day:  0.00
  • Content Count:  657
  • Reputation:   662
  • Joined:  11/12/12
  • Last Seen:  

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.

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  82
  • Topics Per Day:  0.06
  • Content Count:  241
  • Reputation:   11
  • Joined:  08/12/20
  • Last Seen:  

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.


 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  107
  • Topics Per Day:  0.02
  • Content Count:  770
  • Reputation:   69
  • Joined:  02/10/12
  • Last Seen:  

just use custom script command form tokei

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

}

Edited by LearningRO
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  82
  • Topics Per Day:  0.06
  • Content Count:  241
  • Reputation:   11
  • Joined:  08/12/20
  • Last Seen:  

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?

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  16
  • Topics Per Day:  0.00
  • Content Count:  657
  • Reputation:   662
  • Joined:  11/12/12
  • Last Seen:  

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
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  16
  • Topics Per Day:  0.00
  • Content Count:  657
  • Reputation:   662
  • Joined:  11/12/12
  • Last Seen:  

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.

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  82
  • Topics Per Day:  0.06
  • Content Count:  241
  • Reputation:   11
  • Joined:  08/12/20
  • Last Seen:  

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.

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  16
  • Topics Per Day:  0.00
  • Content Count:  657
  • Reputation:   662
  • Joined:  11/12/12
  • Last Seen:  

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);
			}
		}
	}

 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  82
  • Topics Per Day:  0.06
  • Content Count:  241
  • Reputation:   11
  • Joined:  08/12/20
  • Last Seen:  

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!

Link to comment
Share on other sites

  • 0

  • Group:  Content Moderator
  • Topic Count:  55
  • Topics Per Day:  0.02
  • Content Count:  1676
  • Reputation:   702
  • Joined:  12/21/14
  • Last Seen:  

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!

 

 

 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  53
  • Topics Per Day:  0.01
  • Content Count:  411
  • Reputation:   259
  • Joined:  04/25/12
  • Last Seen:  

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.

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