From b4cf8f280cc5cdd027685fb6dd2a2c5692e12115 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Wed, 14 Aug 2013 12:41:17 -0300 Subject: Fixed Bug #7646 Fixed changing map zones/flag of a instance map crashing, also added IOT_ (Instance Owner Type) constants to db/const.txt Special Thanks to purityz for all the help and test scenarios. http://hercules.ws/board/tracker/issue-7646-bg-mapflag-instance-reloadscript-mapserver-crash/ Signed-off-by: shennetsind --- src/map/instance.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/map.h | 48 ++++++++++++++++------------------------------- src/map/script.c | 8 ++++---- 3 files changed, 75 insertions(+), 36 deletions(-) diff --git a/src/map/instance.c b/src/map/instance.c index 3f4b29a89..84c0bd8e2 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -207,6 +207,37 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const memset(map[im].moblist, 0x00, sizeof(map[im].moblist)); map[im].mob_delete_timer = INVALID_TIMER; + //Mimic unit + if( map[m].unit_count ) { + map[im].unit_count = map[m].unit_count; + CREATE( map[im].units, struct mapflag_skill_adjust*, map[im].unit_count ); + + for(i = 0; i < map[im].unit_count; i++) { + CREATE( map[im].units[i], struct mapflag_skill_adjust, 1); + memcpy( map[im].units[i],map[m].units[i],sizeof(struct mapflag_skill_adjust)); + } + } + //Mimic skills + if( map[m].skill_count ) { + map[im].skill_count = map[m].skill_count; + CREATE( map[im].skills, struct mapflag_skill_adjust*, map[im].skill_count ); + + for(i = 0; i < map[im].skill_count; i++) { + CREATE( map[im].skills[i], struct mapflag_skill_adjust, 1); + memcpy( map[im].skills[i],map[m].skills[i],sizeof(struct mapflag_skill_adjust)); + } + } + //Mimic zone mf + if( map[m].zone_mf_count ) { + map[im].zone_mf_count = map[m].zone_mf_count; + CREATE( map[im].zone_mf, char *, map[im].zone_mf_count ); + + for(i = 0; i < map[im].zone_mf_count; i++) { + CREATE(map[im].zone_mf[i], char, MAP_ZONE_MAPFLAG_LENGTH); + safestrncpy(map[im].zone_mf[i],map[m].zone_mf[i],MAP_ZONE_MAPFLAG_LENGTH); + } + } + map[im].m = im; map[im].instance_id = instance_id; map[im].instance_src_map = m; @@ -353,6 +384,30 @@ void instance_del_map(int16 m) { aFree(map[m].block); aFree(map[m].block_mob); + if( map[m].unit_count ) { + for(i = 0; i < map[m].unit_count; i++) { + aFree(map[m].units[i]); + } + if( map[m].units ) + aFree(map[m].units); + } + + if( map[m].skill_count ) { + for(i = 0; i < map[m].skill_count; i++) { + aFree(map[m].skills[i]); + } + if( map[m].skills ) + aFree(map[m].skills); + } + + if( map[m].zone_mf_count ) { + for(i = 0; i < map[m].zone_mf_count; i++) { + aFree(map[m].zone_mf[i]); + } + if( map[m].zone_mf ) + aFree(map[m].zone_mf); + } + // Remove from instance for( i = 0; i < instances[map[m].instance_id].num_map; i++ ) { if( instances[map[m].instance_id].map[i] == m ) { diff --git a/src/map/map.h b/src/map/map.h index 4bee9c8ea..d372a68b6 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1,8 +1,10 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file // Portions Copyright (c) Athena Dev Teams + #ifndef _MAP_H_ #define _MAP_H_ + #include "../common/cbasetypes.h" #include "../common/core.h" // CORE_ST_LAST #include "../common/mmo.h" @@ -11,14 +13,17 @@ #include "../config/core.h" #include "atcommand.h" #include + struct npc_data; struct item_data; struct hChSysCh; + enum E_MAPSERVER_ST { MAPSERVER_ST_RUNNING = CORE_ST_LAST, MAPSERVER_ST_SHUTDOWN, MAPSERVER_ST_LAST }; + #define MAX_NPC_PER_MAP 512 #define AREA_SIZE battle_config.area_size #define DAMAGELOG_SIZE 30 @@ -34,6 +39,7 @@ enum E_MAPSERVER_ST { #define MAX_IGNORE_LIST 20 // official is 14 #define MAX_VENDING 12 #define MAX_MAP_SIZE 512*512 // Wasn't there something like this already? Can't find it.. [Shinryo] + // Added definitions for WoESE objects. [L0ne_W0lf] enum MOBID { MOBID_EMPERIUM = 1288, @@ -51,6 +57,7 @@ enum MOBID { MOBID_SILVERSNIPER = 2042, MOBID_MAGICDECOY_WIND = 2046, }; + // The following system marks a different job ID system used by the map server, // which makes a lot more sense than the normal one. [Skotlex] // These marks the "level" of the job. @@ -193,6 +200,7 @@ enum { MAPID_BABY_GENETIC, MAPID_BABY_CHASER, }; + // Max size for inputs to Graffiti, Talkie Box and Vending text prompts #define MESSAGE_SIZE (79 + 1) // String length you can write in the 'talking box' @@ -296,7 +304,6 @@ struct block_list { enum bl_type type; }; - // Mob List Held in memory for Dynamic Mobs [Wizputer] // Expanded to specify all mob-related spawn data by [Skotlex] struct spawn_data { @@ -449,8 +456,7 @@ typedef enum { } cell_chk; -struct mapcell -{ +struct mapcell { // terrain flags unsigned char walkable : 1, @@ -517,7 +523,10 @@ struct map_zone_skill_damage_cap_entry { #define MAP_ZONE_BG_NAME "Battlegrounds" #define MAP_ZONE_PK_NAME "PK Mode" #define MAP_ZONE_MAPFLAG_LENGTH 50 + +//TODO place it in iMap DBMap *zone_db;/* string => struct map_zone_data */ + struct map_zone_data { char name[MAP_ZONE_NAME_LENGTH];/* 20'd */ struct map_zone_disabled_skill_entry **disabled_skills; @@ -541,7 +550,6 @@ struct map_drop_list { int drop_per; }; - struct map_data { char name[MAP_NAME_LENGTH]; uint16 index; // The map index used by the mapindex* functions. @@ -691,26 +699,6 @@ struct map_data_other_server { struct map_data *map; - - - - - -//int map_foreachinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...); -//int map_foreachinshootrange(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...); -//int map_foreachinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...); -//int map_forcountinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int count, int type, ...); -//int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...); -//int map_foreachinmovearea(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...); -//int map_foreachincell(int (*func)(struct block_list*,va_list), int16 m, int16 x, int16 y, int type, ...); -//int map_foreachinpath(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...); -//int map_foreachinmap(int (*func)(struct block_list*,va_list), int16 m, int type, ...); -//int map_foreachininstance(int (*func)(struct block_list*,va_list), int16 instance_id, int type,...); -// - - - - #define map_id2index(id) map[(id)].index /// Bitfield of flags for the iterator. @@ -718,7 +706,9 @@ enum e_mapitflags { MAPIT_NORMAL = 0, // MAPIT_PCISPLAYING = 1,// Unneeded as pc_db/id_db will only hold auth'ed, active players. }; + struct s_mapiterator; + /* temporary until the map.c "Hercules Renewal Phase One" design is complete. */ struct mapit_interface { struct s_mapiterator* (*alloc) (enum e_mapitflags flags, enum bl_type types); @@ -729,19 +719,15 @@ struct mapit_interface { struct block_list* (*prev) (struct s_mapiterator* mapit); bool (*exists) (struct s_mapiterator* mapit); } mapit_s; + struct mapit_interface *mapit; + #define mapit_getallusers() mapit->alloc(MAPIT_NORMAL,BL_PC) #define mapit_geteachpc() mapit->alloc(MAPIT_NORMAL,BL_PC) #define mapit_geteachmob() mapit->alloc(MAPIT_NORMAL,BL_MOB) #define mapit_geteachnpc() mapit->alloc(MAPIT_NORMAL,BL_NPC) #define mapit_geteachiddb() mapit->alloc(MAPIT_NORMAL,BL_ALL) - - - - - - //Useful typedefs from jA [Skotlex] typedef struct map_session_data TBL_PC; typedef struct npc_data TBL_NPC; @@ -763,8 +749,6 @@ typedef struct elemental_data TBL_ELEM; extern Sql* mmysql_handle; extern Sql* logmysql_handle; - - /*===================================== * Interface : map.h * Generated by HerculesInterfaceMaker diff --git a/src/map/script.c b/src/map/script.c index 04ed0ccce..9e88714fe 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -2284,11 +2284,11 @@ void get_val(struct script_state* st, struct script_data* data) sd = script_rid2sd(st); if( sd == NULL ) {// needs player attached if( postfix == '$' ) {// string variable - ShowWarning("script:script->get_val: cannot access player variable '%s', defaulting to \"\"\n", name); + ShowWarning("script_get_val: cannot access player variable '%s', defaulting to \"\"\n", name); data->type = C_CONSTSTR; data->u.str = ""; } else {// integer variable - ShowWarning("script:script->get_val: cannot access player variable '%s', defaulting to 0\n", name); + ShowWarning("script_get_val: cannot access player variable '%s', defaulting to 0\n", name); data->type = C_INT; data->u.num = 0; } @@ -2327,7 +2327,7 @@ void get_val(struct script_state* st, struct script_data* data) if ( st->instance_id >= 0 ) { data->u.str = (char*)idb_get(instances[st->instance_id].vars,reference_getuid(data)); } else { - ShowWarning("script:script->get_val: cannot access instance variable '%s', defaulting to \"\"\n", name); + ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to \"\"\n", name); data->u.str = NULL; } break; @@ -2382,7 +2382,7 @@ void get_val(struct script_state* st, struct script_data* data) if( st->instance_id >= 0 ) data->u.num = (int)idb_iget(instances[st->instance_id].vars,reference_getuid(data)); else { - ShowWarning("script:script->get_val: cannot access instance variable '%s', defaulting to 0\n", name); + ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to 0\n", name); data->u.num = 0; } break; -- cgit v1.2.3-60-g2f50