From 3fefab81425004d67c61fb911a417ddfdd089693 Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 5 May 2006 23:22:16 +0000 Subject: - 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 --- src/map/clif.c | 11 +----- src/map/map.c | 14 ++------ src/map/mob.c | 17 ++-------- src/map/npc.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/map/npc.h | 13 ++++++++ src/map/pc.c | 61 ++++----------------------------- 6 files changed, 128 insertions(+), 92 deletions(-) (limited to 'src/map') diff --git a/src/map/clif.c b/src/map/clif.c index 95a3a5c29..f95c9aec0 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -8228,16 +8228,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) sc_start(&sd->bl,SC_NOCHAT,100,0,0); // Lance - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.loadmap_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.loadmap_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.loadmap_event_name, sd->bl.id), script_config.loadmap_event_name); - } + npc_script_event(sd, NPCE_LOADMAP); if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd)) clif_status_load(&sd->bl, SI_DEVIL, 1); //blindness [Komurka] diff --git a/src/map/map.c b/src/map/map.c index 6357d09d1..3b3944f0b 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1648,18 +1648,8 @@ int map_quit(struct map_session_data *sd) { if(!sd->state.waitingdisconnect) { if (sd->npc_timer_id != -1) //Cancel the event timer. npc_timerevent_quit(sd); - if (sd->state.event_disconnect) { - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.logout_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLogoutNPC - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.logout_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.logout_event_name, sd->bl.id), script_config.logout_event_name); - } - } + if (sd->state.event_disconnect) + npc_script_event(sd, NPCE_LOGOUT); if (sd->pd) unit_free(&sd->pd->bl); unit_free(&sd->bl); pc_clean_skilltree(sd); diff --git a/src/map/mob.c b/src/map/mob.c index 5e6c5765a..cc9b95083 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2119,21 +2119,10 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) else if(mvp_sd) npc_event(mvp_sd,md->npc_event,0); - } else if (mvp_sd) { - //lordalfa + } else if (mvp_sd) { //lordalfa pc_setglobalreg(mvp_sd,"killedrid",(md->class_)); - if(mvp_sd->state.event_kill_mob){ - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.kill_mob_event_name))) { - run_script(npc->u.scr.script,0,mvp_sd->bl.id,npc->bl.id); // PCKillNPC [Lance] - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n",script_config.kill_mob_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.kill_mob_event_name, mvp_sd->bl.id), script_config.kill_mob_event_name); - } - } + if(mvp_sd->state.event_kill_mob) + npc_script_event(mvp_sd, NPCE_KILLNPC); // PCKillNPC [Lance] } if(md->level) md->level=0; map_freeblock_unlock(); 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= 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(); diff --git a/src/map/npc.h b/src/map/npc.h index 2ee4999c6..035c6ecf8 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -20,6 +20,18 @@ void npc_chat_finalize(struct npc_data *nd); int mob_chat_sub(struct block_list *bl, va_list ap); #endif +//Script NPC events. +enum { + NPCE_LOGIN, + NPCE_LOGOUT, + NPCE_LOADMAP, + NPCE_BASELVUP, + NPCE_JOBLVUP, + NPCE_DIE, + NPCE_KILLPC, + NPCE_KILLNPC, + NPCE_MAX +}; struct view_data* npc_get_viewdata(int class_); int npc_chat_sub(struct block_list *bl, va_list ap); int npc_event_dequeue(struct map_session_data *sd); @@ -65,6 +77,7 @@ int npc_settimerevent_tick(struct npc_data *nd,int newtimer); int npc_remove_map(struct npc_data *nd); int npc_unload(struct npc_data *nd); int npc_reload(void); +int npc_script_event(TBL_PC* sd, int type); extern int dummy_npc_id; diff --git a/src/map/pc.c b/src/map/pc.c index ddf9a244e..c1bab8617 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -877,17 +877,7 @@ int pc_reg_received(struct map_session_data *sd) sd->state.event_kill_mob = 1; } - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.login_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLoginNPC - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.login_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.login_event_name, sd->bl.id), script_config.login_event_name); - } - + npc_script_event(sd, NPCE_LOGIN); return 0; } @@ -3786,17 +3776,7 @@ int pc_checkbaselevelup(struct map_session_data *sd) } clif_misceffect(&sd->bl,0); //LORDALFA - LVLUPEVENT - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.baselvup_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLvlUPNPC - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n",script_config.baselvup_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.baselvup_event_name, sd->bl.id), script_config.baselvup_event_name); - } - + npc_script_event(sd, NPCE_BASELVUP); return 1; } @@ -3827,17 +3807,7 @@ int pc_checkjoblevelup(struct map_session_data *sd) if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd)) clif_status_change(&sd->bl,SI_DEVIL, 1); //Permanent blind effect from SG_DEVIL. - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.joblvup_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLvlUPNPC - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n",script_config.joblvup_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.joblvup_event_name, sd->bl.id), script_config.joblvup_event_name); - } - + npc_script_event(sd, NPCE_JOBLVUP); return 1; } @@ -4569,16 +4539,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) pc_setglobalreg(sd,"killerrid",(ssd->status.account_id)); if (ssd->state.event_kill_pc) { pc_setglobalreg(ssd, "killedrid", sd->bl.id); - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.kill_pc_event_name))) { - run_script(npc->u.scr.script,0,ssd->bl.id,npc->bl.id); // PCKillPC [Lance] - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.kill_pc_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.kill_pc_event_name, ssd->bl.id), script_config.kill_pc_event_name); - } + npc_script_event(ssd, NPCE_KILLPC); } if (battle_config.pk_mode && ssd->status.manner >= 0 && battle_config.manner_system) { ssd->status.manner -= 5; @@ -4608,18 +4569,8 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) pc_setglobalreg(sd, "killerrid", 0); } - if (sd->state.event_death) { - if (script_config.event_script_type == 0) { - struct npc_data *npc; - if ((npc = npc_name2id(script_config.die_event_name))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCDeathNPC - ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.die_event_name); - } - } else { - ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n", - npc_event_doall_id(script_config.die_event_name, sd->bl.id), script_config.die_event_name); - } - } + if (sd->state.event_death) + npc_script_event(sd,NPCE_DIE); // PK/Karma system code (not enabled yet) [celest] /*if(sd->status.karma > 0) { -- cgit v1.2.3-60-g2f50