summaryrefslogtreecommitdiff
path: root/src/map/npc.c
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-05-05 23:22:16 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-05-05 23:22:16 +0000
commit3fefab81425004d67c61fb911a417ddfdd089693 (patch)
treec7e4062a46ca24a5681950abb9a16bb5e2c56f29 /src/map/npc.c
parent1db41fdf364af26b0600a43a167d15f2d2ef8244 (diff)
downloadhercules-3fefab81425004d67c61fb911a417ddfdd089693.tar.gz
hercules-3fefab81425004d67c61fb911a417ddfdd089693.tar.bz2
hercules-3fefab81425004d67c61fb911a417ddfdd089693.tar.xz
hercules-3fefab81425004d67c61fb911a417ddfdd089693.zip
- Added a npc-script-event cache to avoid looking up event-scripts every time they need to be executed. Events cached are all those defined in script_config.
- Since the cache holds direct pointers to the npcs/events, do NOT unload the related NPCs or you'll get dangling pointers. However, @reloadscript will work fine. - Set the etc_log to on to see a summary of npcs/events loaded for script execution on startup. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6494 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/npc.c')
-rw-r--r--src/map/npc.c104
1 files changed, 103 insertions, 1 deletions
diff --git a/src/map/npc.c b/src/map/npc.c
index e294f881b..5ff66ef7a 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -67,6 +67,14 @@ static struct eri *timer_event_ers; //For the npc timer data. [Skotlex]
//For holding the view data of npc classes. [Skotlex]
static struct view_data npc_viewdb[MAX_NPC_CLASS];
+static struct
+{ //Holds pointers to the commonly executed scripts for speedup. [Skotlex]
+ struct npc_data *nd;
+ struct event_data *event[UCHAR_MAX];
+ unsigned char *event_name[UCHAR_MAX];
+ unsigned char event_count;
+} script_event[NPCE_MAX];
+
struct view_data* npc_get_viewdata(int class_)
{ //Returns the viewdata for normal npc classes.
if (class_ == INVISIBLE_CLASS)
@@ -2535,6 +2543,96 @@ void npc_parsesrcfile (char *name)
return;
}
+int npc_script_event(TBL_PC* sd, int type) {
+ int i;
+ if (type < 0 || type >= NPCE_MAX)
+ return 0;
+ if (!sd) {
+ if (battle_config.error_log)
+ ShowError("npc_script_event: NULL sd. Event Type %d\n", type);
+ return 0;
+ }
+ if (script_event[type].nd) {
+ TBL_NPC *nd = script_event[type].nd;
+ run_script(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
+ return 1;
+ } else if (script_event[type].event_count) {
+ for (i = 0; i<script_event[type].event_count; i++) {
+ npc_event_sub(sd,script_event[type].event[i],script_event[type].event_name[i]);
+ }
+ return i;
+ }
+ return 0;
+}
+
+static int npc_read_event_script_sub(DBKey key,void *data,va_list ap)
+{
+ unsigned char *p = key.str;
+ unsigned char *name = va_arg(ap,unsigned char *);
+ struct event_data **event_buf = va_arg(ap,struct event_data**);
+ unsigned char **event_name = va_arg(ap,unsigned char **);
+ unsigned char *count = va_arg(ap,char *);;
+
+ if (*count >= UCHAR_MAX) return 0;
+
+ if((p=strchr(p,':')) && p && strcmpi(name,p)==0 )
+ {
+ event_buf[*count] = (struct event_data *)data;
+ event_name[*count] = key.str;
+ (*count)++;
+ return 1;
+ }
+ return 0;
+}
+
+static void npc_read_event_script(void)
+{
+ int i;
+ unsigned char buf[64]="::";
+ struct {
+ char *name;
+ char *event_name;
+ } config[] = {
+ {"Login Event",script_config.login_event_name},
+ {"Logout Event",script_config.logout_event_name},
+ {"Load Map Event",script_config.loadmap_event_name},
+ {"Base LV Up Event",script_config.baselvup_event_name},
+ {"Job LV Up Event",script_config.joblvup_event_name},
+ {"Die Event",script_config.die_event_name},
+ {"Kill PC Event",script_config.kill_pc_event_name},
+ {"Kill NPC Event",script_config.kill_mob_event_name},
+ };
+
+ for (i = 0; i < NPCE_MAX; i++) {
+ if (script_event[i].nd)
+ script_event[i].nd = NULL;
+ if (script_event[i].event_count)
+ script_event[i].event_count = 0;
+ if (!script_config.event_script_type) {
+ //Use a single NPC as event source.
+ script_event[i].nd = npc_name2id(config[i].event_name);
+ } else {
+ //Use an array of Events
+ strncpy(buf+2,config[i].event_name,62);
+ ev_db->foreach(ev_db,npc_read_event_script_sub,buf,
+ &script_event[i].event,
+ &script_event[i].event_name,
+ &script_event[i].event_count);
+ }
+ }
+ if (battle_config.etc_log) {
+ //Print summary.
+ for (i = 0; i < NPCE_MAX; i++) {
+ if(!script_config.event_script_type) {
+ if (script_event[i].nd)
+ ShowInfo("%s: Using NPC named '%s'.\n", config[i].name, config[i].event_name);
+ else
+ ShowInfo("%s: No NPC found with name '%s'.\n", config[i].name, config[i].event_name);
+ } else
+ ShowInfo("%s: %d '%s' events.\n", config[i].name, script_event[i].event_count, config[i].event_name);
+ }
+ }
+}
static int npc_read_indoors (void)
{
char *buf, *p;
@@ -2646,6 +2744,9 @@ int npc_reload (void)
CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - npc_new_min, "", npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
+ //Re-read the NPC Script Events cache.
+ npc_read_event_script();
+
//Execute the OnInit event for freshly loaded npcs. [Skotlex]
ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"
CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
@@ -2787,7 +2888,8 @@ int do_init_npc(void)
CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - START_NPC_NUM, "", npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-
+ memset(script_event, 0, sizeof(script_event));
+ npc_read_event_script();
//Debug function to locate all endless loop warps.
npc_debug_warps();