Jump to content
AnnieRuru

OnPCStatCalcEvent

Recommended Posts

rathena already has this by default -> https://github.com/rathena/rathena/commit/27a0f3f
someone else has tried to pull request in hercules, -> https://github.com/HerculesWS/Hercules/pull/351
but it was denied, so have to leave this as plugin

UPDATE: rathena has taken out -> https://github.com/rathena/rathena/commit/b65443d8f564175196d57ef9bc1d000a5661fbdc

 

Download : 2.1
plugin

 

Tested with:

conf\import\OnPCStatCalcEvent.conf

both `@reloadscript` and `@reloadonpcstatcalcevent` command can reload conf\import\OnPCStatCalcEvent.conf file 

 

`@reloadscript` = reload everything -> cause destruction on live server

`@reloadonpcstatcalcevent` = only reload conf\import\OnPCStatCalcEvent.conf file , combine with `@reloadnpc` command -> not so destructive

script: (
{ // give GM permanent bonus ?
OnPCStatCalcEvent:
	<"
		bonus bVit, 1234;
		end;
	">
},

{ // for xxx event
OnPCStatCalcEvent:
	<"
		skill TF_HIDING, 1;
		end;
	">
},

{ // npc/custom/xxxevent.txt
OnPCStatCalcEvent:
	<"
		if (@a) {
			bonus bStr, 1000;
			skill WZ_ICEWALL, 1;
		}
		end;
	">
},

)

script

prontera,158,185,5	script	djk2sfhsd	1_F_MARIA,{
	@a ^= 1;
	mes "hmm...";
	recalculatestat();
	next;
	mes "what ?";
	@a ^= 1;
	recalculatestat();
	next;
	mes "maybe...";
	@a ^= 1;
	recalculatestat();
	next;
	mes "probably...";
	@a ^= 1;
	recalculatestat();
	next;
	mes "yeah...";
	@a ^= 1;
	recalculatestat();
	close;
}

yes, this actually works !!

 

with version 2.0 onwards,

no more spamming <npc name>::OnPCStatCalcEvent !!

and even `*skill` working perfectly fine now

 

Spoiler

1.0 - plugin

 

1.1 - plugin
- found a way to get *recalculatestat working, although its not thread-safe, but meh ~

 

1.2 - plugin
- remove some nullpo

 

1.3 - plugin

- update to latest hercules revision

 

2.0 - plugin

- overhaul the way how to give player permanent bonus, now no more using npc label, but using an external file

- fix `*skill` doesn't work correctly previously

- `*recalculatestat` no longer using addtimer hack

- no more spamming "<npc name>::OnPCStatCalcEvent" anymore !!! yes tested !!

 

2.1 - plugin

- add `@reloadonpcstatcalcevent` to safely reload only OnPCStatCalcEvent.conf file without using the destructive `@reloadscript`

 

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
Annie is gone, so I was in doubt about where to post, but here it is.
 
Note: I updated the plugin for the latest version of hercules.

 

 

 

//===== Hercules Plugin ======================================
//= OnPCStatCalcEvent
//===== By: ==================================================
//= AnnieRuru
//= originally by QQfoolsorellina
//===== Current Version: =====================================
//= 1.0
//===== Compatible With: ===================================== 
//= Hercules 2015-11-29
//===== Description: =========================================
//= give player permanent bonus
//===== Topic ================================================
//= http://herc.ws/board/topic/11292-onpcstatcalcevent/
//===== Additional Comments: =================================  
//= stat_recalc script command doesn't really work, I dunno why
//============================================================


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "common/hercules.h"
#include "map/pc.h"
#include "map/npc.h"
//#include "map/script.h"
#include "map/status.h"
#include "common/nullpo.h"
#include "plugins/HPMHooking.h"
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"OnPCStatCalcEvent", // Plugin name
	SERVER_TYPE_MAP,// Which server types this plugin works with?
	"1.0",			// Plugin version
	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)
};

void status_calc_pc_additional_pre( struct map_session_data *sd, enum e_status_calc_opt *opt ) {
	nullpo_retv(sd);
	npc->event_doall_id( "OnPCStatCalcEvent", sd->bl.id );
	return;
}

/*	this stupid command doesn't work
BUILDIN(stat_recalc) {
	TBL_PC* sd;
	if ( script_hasdata(st,2) ) {
		if ( data_isstring( script_getdata(st,2) ) )
			sd = map->nick2sd( script_getstr(st,2) );
		else
			sd = map->id2sd( script_getnum(st,2) );
	} else
		sd = script->rid2sd(st);
	if (sd) {
//		status_calc_pc(sd, SCO_NONE);
//		status->calc_pc_(sd, SCO_NONE);
//		status->calc_pc_(sd, SCO_FORCE);
		status_calc_pc(sd, SCO_FORCE);
		ShowDebug( "run" );
	}
	return true;
}
*/
HPExport void plugin_init (void) {
	addHookPre(status, calc_pc_additional, status_calc_pc_additional_pre );
//	addScriptCommand( "stat_recalc", "?", stat_recalc );
}

 

 

 

Errors:

[Error]: --- nullpo info --------------------------------------------
[Error]: hercules\src\map\npc.c:841: 'sd' in function `unknown'
[Error]: --- end nullpo info ----------------------------------------
[Error]: --- nullpo info --------------------------------------------
[Error]: hercules\src\map\npc.c:841: 'sd' in function `unknown'
[Error]: --- end nullpo info ----------------------------------------
[Error]: --- nullpo info --------------------------------------------
[Error]: hercules\src\map\npc.c:841: 'sd' in function `unknown'
[Error]: --- end nullpo info ----------------------------------------
[Error]: --- nullpo info --------------------------------------------
[Error]: hercules\src\map\npc.c:841: 'sd' in function `unknown'
[Error]: --- end nullpo info ----------------------------------------

Share this post


Link to post
Share on other sites

1.1
plugin
- found a way to get *recalculatestat working, although its not thread-safe, but meh ~

Share this post


Link to post
Share on other sites

Found an issue. Console getting spammed with this:

[Mar/29 14:50:41][Warning]: npc_event: player's event queue is full, can't add event 'RecalcStat::OnPCStatCalcEvent' !

Share this post


Link to post
Share on other sites
15 hours ago, Myriad said:

Found an issue. Console getting spammed with this:

 


[Mar/29 14:50:41][Warning]: npc_event: player's event queue is full, can't add event 'RecalcStat::OnPCStatCalcEvent' !

 

this isn't an issue, it just say it runs this event too many times
probably having some scripts runs jobchange + statusup +equip + .... etc stuffs

I remember you said something about having a refiner script runs in loop ... probably caused by that
and even that ... it shouldn't effect anything ... just an error message

Share this post


Link to post
Share on other sites

@AnnieRuru I tried to work with more unsuccessful consumables

where am i going wrong?

 

Item:

{
	Id: 32247
	AegisName: "Dark_Elf_Potion"
	Name: "Dark Elf Potion"
	Type: "IT_USABLE"
	Weight: 100
	BuyingStore: true
	Trade: {
		nodrop: true
		noselltonpc: true
		nomail: true
		noauction: true
	}
	Script: <" callfunc "Dark_Elf"; ">
},

Function:

function	script	Dark_Elf	{

@a ^= 1;
recalculatestat(); // if player under a dialog, MUST use close2; then only recalculate

OnPCStatCalcEvent:
	if ( @a )
		bonus bDex, 10;
		bonus bInt, 20;
		bonus bAgi, 5;
		bonus bMatk, 100;
	end;

}

 

Share this post


Link to post
Share on other sites

update to version 1.3

plugin

 

On 12/24/2019 at 3:38 AM, Mihael said:

@AnnieRuru I tried to work with more unsuccessful consumables

where am i going wrong?

consumables should be done with *sc_start something

{
	Id: 32247
	AegisName: "Dark_Elf_Potion"
	Name: "Dark Elf Potion"
	Type: "IT_USABLE"
	Weight: 100
	BuyingStore: true
	Trade: {
		nodrop: true
		noselltonpc: true
		nomail: true
		noauction: true
	}
	Script: <" 
      	sc_start SC_INCDEX, 500, 10;
		sc_start SC_INCINT, 500, 20;
		sc_start SC_INCAGI, 500, 5;
		sc_start SC_INCMATKRATE, 500, 10;
  		">
},

seems unrelated to what this modification does ... though

Share this post


Link to post
Share on other sites

2.0 - plugin

- overhaul the way how to give player permanent bonus, now no more using npc label, but using an external file

- fix `*skill` doesn't work correctly previously

- `*recalculatestat` no longer using addtimer hack

- no more spamming "<npc name>::OnPCStatCalcEvent" anymore !!! yes tested !!

 

as like before, `@reloadscript` command can reload conf\import\OnPCStatCalcEvent.conf file

 


 

and if you guys didn't know, rAthena removed OnPCStatCalcEvent !!! MUAHAHAHA !!!

https://github.com/rathena/rathena/commit/b65443d8f564175196d57ef9bc1d000a5661fbdc

why cause headache ? I just live with it

 

https://github.com/rathena/rathena/issues/4812

cast blessing will make OnPCStatCalcEvent bonus disappear ?

I just tested on version 2.0, no problem :hum:

 


 

2.1 - plugin

- add `@reloadonpcstatcalcevent` to safely reload only OnPCStatCalcEvent.conf file without using the destructive `@reloadscript`

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
On 11/30/2015 at 1:07 AM, AnnieRuru said:

script: ( { // give GM permanent bonus ? OnPCStatCalcEvent: <" bonus bVit, 1234; end; "> }, { // for xxx event OnPCStatCalcEvent: <" skill TF_HIDING, 1; end; "> }, { // npc/custom/xxxevent.txt OnPCStatCalcEvent: <" if (@a) { bonus bStr, 1000; skill WZ_ICEWALL, 1; } end; "> }, )

Is there still support on this? How do i access them separately? let's say i decalred 3 OnPCStatCalcEvent here and i need 1 npc to just access 3 of those 6? 

Share this post


Link to post
Share on other sites
Posted (edited)

nvm, I fixed mine.

 

hello can anyone help me decode which part when I relogin/logout the OnPCStatCalcEvent bonus stats disappear? I want to turn that off.

 

//===== Hercules Plugin ======================================
//= OnPCStatCalcEvent
//===== By: ==================================================
//= AnnieRuru
//= originally by QQfoolsorellina
//===== Current Version: =====================================
//= 2.0
//===== Compatible With: ===================================== 
//= Hercules 2020-11-12
//===== Description: =========================================
//= give player permanent bonus
//===== Topic ================================================
//= http://herc.ws/board/topic/11292-onpcstatcalcevent/
//===== Additional Comments: =================================  
//= fix `*skill` doesn't work correctly by using an external file
//============================================================

#include "common/hercules.h"
#include "map/pc.h"
#include "map/script.h"
#include "map/status.h"
#include "common/conf.h"
#include "common/memmgr.h"
#include "plugins/HPMHooking.h"
#include "common/HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"OnPCStatCalcEvent",
	SERVER_TYPE_MAP,
	"2.0",
	HPM_VERSION,
};

VECTOR_DECL(struct script_code *)statcalcevent;

int read_onpcstatcalcevent(void) {
	const char *confpath = "conf/import/OnPCStatCalcEvent.conf";
	struct config_t onpcstatcalcevent_conf;
	if (!libconfig->load_file(&onpcstatcalcevent_conf, confpath)) {
		ShowError("can't read %s, file not found !\n", confpath);
		return -1;
	}

	struct config_setting_t *config_db = libconfig->setting_get_member(onpcstatcalcevent_conf.root, "script");
	if (config_db == NULL) {
		ShowError("can't read %s\n", confpath);
		libconfig->destroy(&onpcstatcalcevent_conf);
		return -1;
	}

	struct config_setting_t *config = NULL;
	int i = 0;
	struct script_code *tmp;
	const char *string = NULL;
	VECTOR_INIT(statcalcevent);
	while ((config = libconfig->setting_get_elem(config_db, i++))) {
		if (libconfig->setting_lookup_string(config, "OnPCStatCalcEvent", &string)) {
			tmp = script->parse(string, "OnPCStatCalcEvent", 0, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL);
			VECTOR_ENSURE(statcalcevent, 1, 1);
			VECTOR_PUSH(statcalcevent, tmp);
		}
		else
			ShowError("Invalid Type on entry no."CL_WHITE"%d"CL_RESET" in '"CL_WHITE"%s"CL_RESET"'.\n", i, confpath);
	}

//	ShowDebug("%d\n", VECTOR_LENGTH(statcalcevent));
//	for (i = 0; i < VECTOR_LENGTH(statcalcevent); i++) {
//		ShowDebug("%s\n", VECTOR_INDEX(statcalcevent, i));
//		ShowDebug("%s\n", VECTOR_INDEX(statcalcevent, i)->script_buf);
//	}

	libconfig->destroy(&onpcstatcalcevent_conf);
	ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", VECTOR_LENGTH(statcalcevent), confpath);
	return VECTOR_LENGTH(statcalcevent);
}

void status_calc_pc_additional_post(struct map_session_data *sd, enum e_status_calc_opt opt) {
	if (sd == NULL)
		return;
	for (int i = 0; i < VECTOR_LENGTH(statcalcevent); i++)
		script->run(VECTOR_INDEX(statcalcevent, i), 0, sd->bl.id, 0);
	return;
}

BUILDIN(recalculatestat) {
	struct map_session_data *sd;
	if (script_hasdata(st,2)) {
		if (data_isstring(script_getdata(st,2)))
			sd = map->nick2sd(script_getstr(st,2), true);
		else
			sd = map->id2sd(script_getnum(st,2));
	}
	else
		sd = script->rid2sd(st);
	if (sd)
		status_calc_pc(sd, SCO_FORCE);
	return true;
}

void clean_onpcstatcalcevent(void) {
	for (int i = 0; i < VECTOR_LENGTH(statcalcevent); ++i) {
		VECTOR_CLEAR(VECTOR_INDEX(statcalcevent, i)->script_buf);
		aFree(VECTOR_INDEX(statcalcevent, i));
	}
	VECTOR_CLEAR(statcalcevent);
	return;
}

int script_reload_post(int retVal) {
	clean_onpcstatcalcevent();
	read_onpcstatcalcevent();
	return retVal;
}

HPExport void plugin_init(void) {
	addHookPost(status, calc_pc_additional, status_calc_pc_additional_post);
	addScriptCommand("recalculatestat", "?", recalculatestat);
	addHookPost(script, reload, script_reload_post);
}

HPExport void server_online(void) {
	read_onpcstatcalcevent();
}

HPExport void plugin_final(void) {
	clean_onpcstatcalcevent();
}
Edited by Louis T Steinhil

Share this post


Link to post
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
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  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.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.