diff options
Diffstat (limited to 'src/map/instance.c')
-rw-r--r-- | src/map/instance.c | 149 |
1 files changed, 111 insertions, 38 deletions
diff --git a/src/map/instance.c b/src/map/instance.c index a6700d486..1104b7e88 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team - * Copyright (C) Athena Dev Teams + * Copyright (C) 2012-2020 Hercules Dev Team + * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,7 @@ #include "map/npc.h" #include "map/party.h" #include "map/pc.h" +#include "map/quest.h" #include "common/HPM.h" #include "common/cbasetypes.h" #include "common/db.h" @@ -47,11 +48,12 @@ #include <string.h> #include <time.h> -struct instance_interface instance_s; +static struct instance_interface instance_s; struct instance_interface *instance; /// Checks whether given instance id is valid or not. -bool instance_is_valid(int instance_id) { +static bool instance_is_valid(int instance_id) +{ if( instance_id < 0 || instance_id >= instance->instances ) {// out of range return false; } @@ -69,7 +71,8 @@ bool instance_is_valid(int instance_id) { * -4 = already exists | -3 = no free instances | -2 = owner not found | -1 = invalid type * On success return instance_id *--------------------------------------*/ -int instance_create(int owner_id, const char *name, enum instance_owner_type type) { +static int instance_create(int owner_id, const char *name, enum instance_owner_type type) +{ struct map_session_data *sd = NULL; unsigned short *icptr = NULL; struct party_data *p = NULL; @@ -180,7 +183,8 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ * @retval -3 No more map indices available. * @retval -4 Source map is already an instance. **/ -int instance_add_map(const char *name, int instance_id, bool usebasename, const char *map_name) { +static int instance_add_map(const char *name, int instance_id, bool usebasename, const char *map_name) +{ int16 m = map->mapname2mapid(name); int i, im = -1; size_t num_cell, size, j; @@ -291,13 +295,6 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const } } - //Mimic questinfo - if( map->list[m].qi_count ) { - map->list[im].qi_count = map->list[m].qi_count; - CREATE( map->list[im].qi_data, struct questinfo, map->list[im].qi_count ); - memcpy( map->list[im].qi_data, map->list[m].qi_data, map->list[im].qi_count * sizeof(struct questinfo) ); - } - map->list[im].m = im; map->list[im].instance_id = instance_id; map->list[im].instance_src_map = m; @@ -317,7 +314,8 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const * party_id : source party of this instance * type : result (0 = map id | 1 = instance id) *--------------------------------------*/ -int instance_map2imap(int16 m, int instance_id) { +static int instance_map2imap(int16 m, int instance_id) +{ int i; if( !instance->valid(instance_id) ) { @@ -331,7 +329,8 @@ int instance_map2imap(int16 m, int instance_id) { return -1; } -int instance_mapname2imap(const char *map_name, int instance_id) { +static int instance_mapname2imap(const char *map_name, int instance_id) +{ int i; nullpo_retr(-1, map_name); @@ -351,7 +350,8 @@ int instance_mapname2imap(const char *map_name, int instance_id) { * instance_id : where to search * result : mapid of map "m" in this instance *--------------------------------------*/ -int instance_mapid2imapid(int16 m, int instance_id) { +static int instance_mapid2imapid(int16 m, int instance_id) +{ Assert_retr(-1, m >= 0 && m < map->count); if( map->list[m].flag.src4instance == 0 ) return m; // not instances found for this map @@ -369,7 +369,7 @@ int instance_mapid2imapid(int16 m, int instance_id) { /*-------------------------------------- * Used on Init instance. Duplicates each script on source map *--------------------------------------*/ -int instance_map_npcsub(struct block_list* bl, va_list args) +static int instance_map_npcsub(struct block_list *bl, va_list args) { struct npc_data *nd = NULL; int16 m = va_arg(args, int); // Destination Map @@ -384,7 +384,7 @@ int instance_map_npcsub(struct block_list* bl, va_list args) return 1; } -int instance_init_npc(struct block_list* bl, va_list args) +static int instance_init_npc(struct block_list *bl, va_list args) { struct npc_data *nd = NULL; struct event_data *ev; @@ -405,7 +405,8 @@ int instance_init_npc(struct block_list* bl, va_list args) /*-------------------------------------- * Init all map on the instance. Npcs are created here *--------------------------------------*/ -void instance_init(int instance_id) { +static void instance_init(int instance_id) +{ int i; if( !instance->valid(instance_id) ) @@ -424,7 +425,8 @@ void instance_init(int instance_id) { * Used on instance deleting process. * Warps all players on each instance map to its save points. *--------------------------------------*/ -int instance_del_load(struct map_session_data* sd, va_list args) { +static int instance_del_load(struct map_session_data *sd, va_list args) +{ int16 m = va_arg(args,int); if( !sd || sd->bl.m != m ) @@ -435,7 +437,8 @@ int instance_del_load(struct map_session_data* sd, va_list args) { } /* for npcs behave differently when being unloaded within a instance */ -int instance_cleanup_sub(struct block_list *bl, va_list ap) { +static int instance_cleanup_sub(struct block_list *bl, va_list ap) +{ nullpo_ret(bl); switch(bl->type) { @@ -443,7 +446,7 @@ int instance_cleanup_sub(struct block_list *bl, va_list ap) { map->quit(BL_UCAST(BL_PC, bl)); break; case BL_NPC: - npc->unload(BL_UCAST(BL_NPC, bl), true); + npc->unload(BL_UCAST(BL_NPC, bl), true, true); break; case BL_MOB: unit->free(bl,CLR_OUTSIGHT); @@ -465,7 +468,8 @@ int instance_cleanup_sub(struct block_list *bl, va_list ap) { /*-------------------------------------- * Removes a simple instance map *--------------------------------------*/ -void instance_del_map(int16 m) { +static void instance_del_map(int16 m) +{ int i; if( m <= 0 || map->list[m].instance_id == -1 ) { @@ -507,8 +511,7 @@ void instance_del_map(int16 m) { aFree(map->list[m].zone_mf); } - if( map->list[m].qi_data ) - aFree(map->list[m].qi_data); + VECTOR_CLEAR(map->list[m].qi_list); // Remove from instance for( i = 0; i < instance->list[map->list[m].instance_id].num_map; i++ ) { @@ -537,7 +540,8 @@ void instance_del_map(int16 m) { /*-------------------------------------- * Timer to destroy instance by process or idle *--------------------------------------*/ -int instance_destroy_timer(int tid, int64 tick, int id, intptr_t data) { +static int instance_destroy_timer(int tid, int64 tick, int id, intptr_t data) +{ instance->destroy(id); return 0; } @@ -545,13 +549,14 @@ int instance_destroy_timer(int tid, int64 tick, int id, intptr_t data) { /*-------------------------------------- * Removes a instance, all its maps and npcs. *--------------------------------------*/ -void instance_destroy(int instance_id) { +static void instance_destroy(int instance_id) +{ struct map_session_data *sd = NULL; unsigned short *icptr = NULL; struct party_data *p = NULL; struct guild *g = NULL; short *iptr = NULL; - int type, j; + int type; unsigned int now = (unsigned int)time(NULL); if( !instance->valid(instance_id) ) @@ -596,9 +601,10 @@ void instance_destroy(int instance_id) { } if( iptr != NULL ) { - ARR_FIND(0, *icptr, j, iptr[j] == instance_id); - if( j != *icptr ) - iptr[j] = -1; + int i; + ARR_FIND(0, *icptr, i, iptr[i] == instance_id); + if (i != *icptr) + iptr[i] = -1; } if (instance->list[instance_id].map) { @@ -635,7 +641,8 @@ void instance_destroy(int instance_id) { /*-------------------------------------- * Checks if there are users in the instance or not to start idle timer *--------------------------------------*/ -void instance_check_idle(int instance_id) { +static void instance_check_idle(int instance_id) +{ bool idle = true; unsigned int now = (unsigned int)time(NULL); @@ -660,7 +667,7 @@ void instance_check_idle(int instance_id) { /*-------------------------------------- * Set instance Timers *--------------------------------------*/ -void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout) +static void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout) { unsigned int now = (unsigned int)time(0); @@ -699,7 +706,8 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign /*-------------------------------------- * Checks if sd in on a instance and should be kicked from it *--------------------------------------*/ -void instance_check_kick(struct map_session_data *sd) { +static void instance_check_kick(struct map_session_data *sd) +{ int16 m = sd->bl.m; nullpo_retv(sd); @@ -712,7 +720,68 @@ void instance_check_kick(struct map_session_data *sd) { } } -void do_reload_instance(void) { +/** + * Look up existing memorial dungeon of the player and destroy it + * + * @param sd session data. + * + */ +static void instance_force_destroy(struct map_session_data *sd) +{ + nullpo_retv(sd); + + for (int i = 0; i < instance->instances; ++i) { + switch (instance->list[i].owner_type) { + case IOT_CHAR: + { + if (instance->list[i].owner_id != sd->status.char_id) + continue; + break; + } + case IOT_PARTY: + { + int party_id = sd->status.party_id; + if (instance->list[i].owner_id != party_id) + continue; + int j = 0; + struct party_data *pt = party->search(party_id); + nullpo_retv(pt); + + ARR_FIND(0, MAX_PARTY, j, pt->party.member[j].leader); + if (j == MAX_PARTY) { + ShowWarning("clif_parse_memorial_dungeon_command: trying to destroy a party instance, while the party has no leader."); + return; + } + if (pt->party.member[j].char_id != sd->status.char_id) { + ShowWarning("clif_parse_memorial_dungeon_command: trying to destroy a party instance, from a non party-leader player."); + return; + } + break; + } + case IOT_GUILD: + { + int guild_id = sd->status.guild_id; + if (instance->list[i].owner_id != guild_id) + continue; + struct guild *g = guild->search(guild_id); + nullpo_retv(g); + + if (g->member[0].char_id != sd->status.char_id) { + ShowWarning("clif_parse_memorial_dungeon_command: trying to destroy a guild instance, from a non guild-master player."); + return; + } + break; + } + default: + continue; + } + instance->destroy(instance->list[i].id); + return; + } +} + +static void do_reload_instance(void) +{ struct s_mapiterator *iter; struct map_session_data *sd; int i, k; @@ -742,7 +811,8 @@ void do_reload_instance(void) { mapit->free(iter); } -void do_final_instance(void) { +static void do_final_instance(void) +{ int i; for(i = 0; i < instance->instances; i++) { @@ -756,14 +826,16 @@ void do_final_instance(void) { instance->instances = 0; } -void do_init_instance(bool minimal) { +static void do_init_instance(bool minimal) +{ if (minimal) return; timer->add_func_list(instance->destroy_timer, "instance_destroy_timer"); } -void instance_defaults(void) { +void instance_defaults(void) +{ instance = &instance_s; instance->init = do_init_instance; @@ -791,4 +863,5 @@ void instance_defaults(void) { instance->set_timeout = instance_set_timeout; instance->valid = instance_is_valid; instance->destroy_timer = instance_destroy_timer; + instance->force_destroy = instance_force_destroy; } |