summaryrefslogtreecommitdiff
path: root/src/map/npc.c
diff options
context:
space:
mode:
authorglighta <glighta@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-12 00:06:25 +0000
committerglighta <glighta@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-12 00:06:25 +0000
commitae57ff81700dbe6714ef107b34510457e9c9c5b6 (patch)
treee624b5ac4214e5ac9e00aee596055ce19ff95be5 /src/map/npc.c
parent20e444cce123f97b5e2d60cfb4c134c08479fb41 (diff)
downloadhercules-ae57ff81700dbe6714ef107b34510457e9c9c5b6.tar.gz
hercules-ae57ff81700dbe6714ef107b34510457e9c9c5b6.tar.bz2
hercules-ae57ff81700dbe6714ef107b34510457e9c9c5b6.tar.xz
hercules-ae57ff81700dbe6714ef107b34510457e9c9c5b6.zip
-Add Homon-S skills, 1st implementation (all done except Eleanors)
--Upd Skill conf to set land-limit for homonculus by default (ground skill limit) --Mv MH_HEILIGE_STANGE and MH_ANGRIFFS_MODUS skill from Eleanor to Bayeri -Enforce all zeny transaction to use pc_payzeny and pc_getzeny handlers, (auto log and clif) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16914 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/npc.c')
-rw-r--r--src/map/npc.c140
1 files changed, 66 insertions, 74 deletions
diff --git a/src/map/npc.c b/src/map/npc.c
index 60f8b14ad..c23d67951 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -199,7 +199,7 @@ int npc_enable(const char* name, int flag)
} else
clif_changeoption(&nd->bl);
- if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) ) //check if player standing on a OnTouchArea
+ if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) ) //check if player standing on a OnTouchArea
map_foreachinarea( npc_enable_sub, nd->bl.m, nd->bl.x-nd->u.scr.xs, nd->bl.y-nd->u.scr.ys, nd->bl.x+nd->u.scr.xs, nd->bl.y+nd->u.scr.ys, BL_PC, nd );
return 0;
@@ -302,7 +302,7 @@ int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char
/**
* Exec name (NPC events) on player or global
- * Do on all NPC when called with foreach
+ * Do on all NPC when called with foreach
* @see DBApply
*/
int npc_event_doall_sub(DBKey key, DBData *data, va_list ap)
@@ -411,22 +411,22 @@ int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data)
case 6: day = "Sat"; break;
default:day = ""; break;
}
-
+
sprintf(buf,"OnMinute%02d",t->tm_min);
c += npc_event_doall(buf);
-
+
sprintf(buf,"OnClock%02d%02d",t->tm_hour,t->tm_min);
c += npc_event_doall(buf);
-
+
sprintf(buf,"On%s%02d%02d",day,t->tm_hour,t->tm_min);
c += npc_event_doall(buf);
}
-
+
if (t->tm_hour != ev_tm_b.tm_hour) {
sprintf(buf,"OnHour%02d",t->tm_hour);
c += npc_event_doall(buf);
}
-
+
if (t->tm_mday != ev_tm_b.tm_mday) {
sprintf(buf,"OnDay%02d%02d",t->tm_mon+1,t->tm_mday);
c += npc_event_doall(buf);
@@ -539,13 +539,13 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data)
sd->npc_timer_id = INVALID_TIMER;
else
nd->u.scr.timerid = INVALID_TIMER;
-
+
ers_free(timer_event_ers, ted);
}
// Run the script
run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id);
-
+
nd->u.scr.rid = old_rid; // Attached-rid should be restored anyway.
if( sd )
{ // Restore previous data, only if this timer is a player-attached one.
@@ -564,7 +564,7 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
unsigned int tick = gettick();
struct map_session_data *sd = NULL; //Player to whom script is attached.
struct timer_event_data *ted;
-
+
nullpo_ret(nd);
// Check if there is an OnTimer Event
@@ -584,7 +584,7 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
}
else if( nd->u.scr.timerid != INVALID_TIMER || nd->u.scr.timertick )
return 0;
-
+
if (j < nd->u.scr.timeramount)
{
// Arrange for the next event
@@ -606,7 +606,7 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
}
else if (!sd)
{
- nd->u.scr.timertick = tick;
+ nd->u.scr.timertick = tick;
}
return 0;
@@ -627,7 +627,7 @@ int npc_timerevent_stop(struct npc_data* nd)
ShowError("npc_timerevent_stop: Attached player not found!\n");
return 1;
}
-
+
tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid;
if( *tid == INVALID_TIMER && (sd || !nd->u.scr.timertick) ) // Nothing to stop
return 0;
@@ -700,7 +700,7 @@ void npc_timerevent_quit(struct map_session_data* sd)
nd->u.scr.rid = sd->bl.id;
nd->u.scr.timertick = gettick();
nd->u.scr.timer = ted->time;
-
+
//Execute label
run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
@@ -855,7 +855,7 @@ int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap)
xs = nd->u.scr.xs;
ys = nd->u.scr.ys;
- if( sd->bl.m != nd->bl.m ||
+ if( sd->bl.m != nd->bl.m ||
sd->bl.x < nd->bl.x - xs || sd->bl.x > nd->bl.x + xs ||
sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys ||
pc_ishiding(sd) || leavemap )
@@ -1012,7 +1012,7 @@ int npc_check_areanpc(int flag, int m, int x, int y, int range)
y0 = max(y-range, 0);
x1 = min(x+range, map[m].xs-1);
y1 = min(y+range, map[m].ys-1);
-
+
//First check for npc_cells on the range given
i = 0;
for (ys = y0; ys <= y1 && !i; ys++) {
@@ -1106,7 +1106,7 @@ void run_tomb(struct map_session_data* sd, struct npc_data* nd)
{
char buffer[200];
char time[10];
-
+
strftime(time, sizeof(time), "%H:%M", localtime(&nd->u.tomb.kill_time));
// TODO: Find exact color?
@@ -1117,7 +1117,7 @@ void run_tomb(struct map_session_data* sd, struct npc_data* nd)
snprintf(buffer, sizeof(buffer), msg_txt(659), time);
clif_scriptmes(sd, nd->bl.id, buffer);
-
+
clif_scriptmes(sd, nd->bl.id, msg_txt(660));
snprintf(buffer, sizeof(buffer), msg_txt(661), nd->u.tomb.killer_name[0] ? nd->u.tomb.killer_name : "Unknown");
@@ -1128,7 +1128,7 @@ void run_tomb(struct map_session_data* sd, struct npc_data* nd)
/*==========================================
* NPC 1st call when clicking on npc
- * Do specific action for NPC type (openshop, run scripts...)
+ * Do specific action for NPC type (openshop, run scripts...)
*------------------------------------------*/
int npc_click(struct map_session_data* sd, struct npc_data* nd)
{
@@ -1179,7 +1179,7 @@ int npc_scriptcont(struct map_session_data* sd, int id)
nd?(char*)nd->name:"'Unknown NPC'", (int)id);
return 1;
}
-
+
if(id != fake_nd->bl.id) { // Not item script
if ((npc_checknear(sd,map_id2bl(id))) == NULL){
ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
@@ -1218,7 +1218,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
if ((nd = npc_checknear(sd,map_id2bl(id))) == NULL)
return 1;
-
+
if (nd->subtype!=SHOP) {
ShowError("no such shop npc : %d\n",id);
if (sd->npc_id == id)
@@ -1459,7 +1459,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
int nameid, amount, value;
// find this entry in the shop's sell list
- ARR_FIND( 0, nd->u.shop.count, j,
+ ARR_FIND( 0, nd->u.shop.count, j,
item_list[i*2+1] == nd->u.shop.shop_item[j].nameid || //Normal items
item_list[i*2+1] == itemdb_viewid(nd->u.shop.shop_item[j].nameid) //item_avail replacement
);
@@ -1515,11 +1515,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
if( pc_inventoryblank(sd) < new_ )
return 3; // Not enough space to store items
- //Logs (S)hopping Zeny [Lupus]
- log_zeny(sd, LOG_TYPE_NPC, sd, -(int)z);
- //Logs
-
- pc_payzeny(sd,(int)z);
+ pc_payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
for( i = 0; i < n; ++i )
{
@@ -1584,7 +1580,7 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
script_cleararray_pc(sd, card_slot, (void*)0);
}
-
+
// save list of to be sold items
for( i = 0; i < n; i++ )
{
@@ -1598,7 +1594,7 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
script_setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->status.inventory[idx].refine, &key_refine);
script_setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute);
script_setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->status.inventory[idx].identify, &key_identify);
-
+
for( j = 0; j < MAX_SLOTS; j++ )
{// store each of the cards from the equipment in the array
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
@@ -1691,11 +1687,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
if( z > MAX_ZENY )
z = MAX_ZENY;
- //Logs (S)hopping Zeny [Lupus]
- log_zeny(sd, LOG_TYPE_NPC, sd, (int)z);
- //Logs
-
- pc_getzeny(sd, (int)z);
+ pc_getzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
// custom merchant shop exp bonus
if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
@@ -1793,13 +1785,13 @@ int npc_unload(struct npc_data* nd, bool single) {
if( nd->path && nd->path != npc_last_ref ) {
npd = strdb_get(npc_path_db, nd->path);
}
-
+
if( npd && --npd->references == 0 ) {
strdb_remove(npc_path_db, nd->path);/* remove from db */
aFree(nd->path);/* remove now that no other instances exist */
}
}
-
+
if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao]
aFree(nd->u.shop.shop_item);
else if( nd->subtype == SCRIPT ) {
@@ -1809,7 +1801,7 @@ int npc_unload(struct npc_data* nd, bool single) {
if( single )
ev_db->foreach(ev_db,npc_unload_ev,nd->exname); //Clean up all events related
- iter = mapit_geteachpc();
+ iter = mapit_geteachpc();
for( bl = (struct block_list*)mapit_first(iter); mapit_exists(iter); bl = (struct block_list*)mapit_next(iter) ) {
struct map_session_data *sd = ((TBL_PC*)bl);
if( sd && sd->npc_timer_id != INVALID_TIMER ) {
@@ -1823,13 +1815,13 @@ int npc_unload(struct npc_data* nd, bool single) {
delete_timer(sd->npc_timer_id, npc_timerevent);
sd->npc_timer_id = INVALID_TIMER;
}
- }
+ }
mapit_free(iter);
if (nd->u.scr.timerid != INVALID_TIMER) {
const struct TimerData *td = NULL;
td = get_timer(nd->u.scr.timerid);
- if (td && td->data)
+ if (td && td->data)
ers_free(timer_event_ers, (void*)td->data);
delete_timer(nd->u.scr.timerid, npc_timerevent);
}
@@ -1988,20 +1980,20 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta
ShowDebug("other npc in '%s' :\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n",dnd->path, dnd->name, dnd->exname, other_mapname, dnd->bl.x, dnd->bl.y);
safestrncpy(nd->exname, newname, sizeof(nd->exname));
}
-
+
if( npc_last_path != filepath ) {
struct npc_path_data * npd = NULL;
-
+
if( !(npd = strdb_get(npc_path_db,filepath) ) ) {
CREATE(npd, struct npc_path_data, 1);
strdb_put(npc_path_db, filepath, npd);
-
+
CREATE(npd->path, char, strlen(filepath)+1);
safestrncpy(npd->path, filepath, strlen(filepath)+1);
-
+
npd->references = 0;
}
-
+
nd->path = npd->path;
npd->references++;
@@ -2122,7 +2114,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
/// Parses a shop/cashshop npc.
static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
{
- //TODO: could be rewritten to NOT need this temp array [ultramage]
+ //TODO: could be rewritten to NOT need this temp array [ultramage]
#define MAX_SHOPITEM 100
struct npc_item_list items[MAX_SHOPITEM];
char *p;
@@ -2144,7 +2136,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
ShowError("npc_parse_shop: Invalid shop definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
return strchr(start,'\n');// skip and continue
}
-
+
m = map_mapname2mapid(mapname);
}
@@ -2464,17 +2456,17 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
if( runOnInit ) {
char evname[EVENT_NAME_LENGTH];
struct event_data *ev;
-
+
snprintf(evname, ARRAYLENGTH(evname), "%s::OnInit", nd->exname);
-
+
if( ( ev = (struct event_data*)strdb_get(ev_db, evname) ) ) {
-
+
//Execute OnInit
run_script(nd->u.scr.script,ev->pos,0,nd->bl.id);
-
+
}
}
-
+
return end;
}
@@ -2630,7 +2622,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
int npc_duplicate4instance(struct npc_data *snd, int m) {
char newname[NAME_LENGTH];
-
+
if( map[m].instance_id == 0 )
return 1;
@@ -2858,9 +2850,9 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c
// split atcmd parameters based on spaces
i = 0;
j = 0;
-
+
temp = (char*)aMalloc(strlen(message) + 1);
-
+
while( message[i] != '\0' ) {
if( message[i] == ' ' && k < 127 ) {
temp[j] = '\0';
@@ -3108,7 +3100,7 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
if (w4 && !strcmpi(w4, "off"))
state = 0; //Disable mapflag rather than enable it. [Skotlex]
-
+
if (!strcmpi(w3, "nosave")) {
char savemap[32];
int savex, savey;
@@ -3556,7 +3548,7 @@ void npc_read_event_script(void)
ShowWarning("npc_read_event_script: too many occurences of event '%s'!\n", config[i].event_name);
break;
}
-
+
if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 )
{
script_event[i].event[count] = ed;
@@ -3576,14 +3568,14 @@ void npc_read_event_script(void)
void npc_clear_pathlist(void) {
struct npc_path_data *npd = NULL;
- DBIterator *path_list = db_iterator(npc_path_db);
-
+ DBIterator *path_list = db_iterator(npc_path_db);
+
/* free all npc_path_data filepaths */
for( npd = dbi_first(path_list); dbi_exists(path_list); npd = dbi_next(path_list) ) {
if( npd->path )
aFree(npd->path);
}
-
+
dbi_destroy(path_list);
}
@@ -3596,12 +3588,12 @@ int npc_reload(void) {
struct block_list* bl;
npc_clear_pathlist();
-
+
db_clear(npc_path_db);
db_clear(npcname_db);
db_clear(ev_db);
-
+
//Remove all npcs/mobs. [Skotlex]
iter = mapit_geteachiddb();
@@ -3662,20 +3654,20 @@ int npc_reload(void) {
npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
do_final_instance();
-
+
for( i = 0; i < ARRAYLENGTH(instance); ++i )
instance_init(instance[i].instance_id);
//Re-read the NPC Script Events cache.
npc_read_event_script();
-
+
/* refresh guild castle flags on both woe setups */
npc_event_doall("OnAgitInit");
npc_event_doall("OnAgitInit2");
-
+
//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"));
-
+
// Execute rest of the startup events if connected to char-server. [Lance]
if(!CheckForCharServer()){
ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit"));
@@ -3689,7 +3681,7 @@ bool npc_unloadfile( const char* path ) {
DBIterator * iter = db_iterator(npcname_db);
struct npc_data* nd = NULL;
bool found = false;
-
+
for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) {
if( nd->path && strcasecmp(nd->path,path) == 0 ) {
found = true;
@@ -3697,12 +3689,12 @@ bool npc_unloadfile( const char* path ) {
npc_unload(nd, true);
}
}
-
+
dbi_destroy(iter);
-
+
if( found ) /* refresh event cache */
npc_read_event_script();
-
+
return found;
}
@@ -3712,7 +3704,7 @@ void do_clear_npc(void) {
}
/*==========================================
- * Destructor
+ * Destructor
*------------------------------------------*/
int do_final_npc(void) {
npc_clear_pathlist();
@@ -3770,15 +3762,15 @@ int do_init_npc(void)
//Stock view data for normal npcs.
memset(&npc_viewdb, 0, sizeof(npc_viewdb));
npc_viewdb[0].class_ = INVISIBLE_CLASS; //Invisible class is stored here.
- for( i = 1; i < MAX_NPC_CLASS; i++ )
+ for( i = 1; i < MAX_NPC_CLASS; i++ )
npc_viewdb[i].class_ = i;
ev_db = strdb_alloc((DBOptions)(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA),2*NAME_LENGTH+2+1);
npcname_db = strdb_alloc(DB_OPT_BASE,NAME_LENGTH);
npc_path_db = strdb_alloc(DB_OPT_BASE|DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,80);
-
+
timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE);
-
+
// process all npc files
ShowStatus("Loading NPCs...\r");
for( file = npc_src_files; file != NULL; file = file->next ) {
@@ -3822,6 +3814,6 @@ int do_init_npc(void)
fake_nd->u.scr.timerid = INVALID_TIMER;
map_addiddb(&fake_nd->bl);
// End of initialization
-
+
return 0;
}