From e6320b892516ba49af88bb4cc616952fa7cab6cd Mon Sep 17 00:00:00 2001 From: shennetsind Date: Tue, 2 Apr 2013 19:21:01 -0300 Subject: Updated Map Zone Database Introducing unit-type-based skill restrictions, details in the link http://hercules.ws/board/topic/302-introducing-hercules-map-zone-database/?p=2227 Special Thanks to lighta and Muad_Dib Signed-off-by: shennetsind --- src/map/map.c | 73 +++++++++++++++++++++++++++++++++++++++++++++----------- src/map/map.h | 10 ++++---- src/map/skill.c | 8 ------- src/map/status.c | 54 +++++++++++++++++++++++++---------------- 4 files changed, 97 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/map/map.c b/src/map/map.c index 8622aadb5..acfdd643b 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -2911,6 +2911,9 @@ void map_zone_db_clear(void) { DBIterator *iter = db_iterator(zone_db); for(zone = dbi_first(iter); dbi_exists(iter); zone = dbi_next(iter)) { + for(i = 0; i < zone->disabled_skills_count; i++) { + aFree(zone->disabled_skills[i]); + } aFree(zone->disabled_skills); aFree(zone->disabled_items); for(i = 0; i < zone->mapflags_count; i++) { @@ -2923,6 +2926,9 @@ void map_zone_db_clear(void) { db_destroy(zone_db);/* will aFree(zone) */ /* clear the main zone stuff */ + for(i = 0; i < map_zone_all.disabled_skills_count; i++) { + aFree(map_zone_all.disabled_skills[i]); + } aFree(map_zone_all.disabled_skills); aFree(map_zone_all.disabled_items); for(i = 0; i < map_zone_all.mapflags_count; i++) { @@ -3621,6 +3627,36 @@ void map_zone_init(void) { } } +enum bl_type map_zone_bl_type(const char *entry) { + char temp[200], *parse; + enum bl_type bl; + safestrncpy(temp, entry, 200); + + parse = strtok(temp,"|"); + + while (parse != NULL) { + normalize_name(parse," "); + if( strcmpi(parse,"player") == 0 ) + bl |= BL_PC; + else if( strcmpi(parse,"homun") == 0 ) + bl |= BL_HOM; + else if( strcmpi(parse,"mercenary") == 0 ) + bl |= BL_MER; + else if( strcmpi(parse,"monster") == 0 ) + bl |= BL_MOB; + else if( strcmpi(parse,"elemental") == 0 ) + bl |= BL_ELEM; + else if( strcmpi(parse,"all") == 0 ) + bl |= BL_ALL; + else if( strcmpi(parse,"none") == 0 ) { + bl = 0; + } else { + ShowError("map_zone_db: '%s' unknown type, skipping...\n",parse); + } + parse = strtok(NULL,"|"); + } + return bl; +} void read_map_zone_db(void) { config_t map_zone_db; config_setting_t *zones = NULL; @@ -3644,7 +3680,7 @@ void read_map_zone_db(void) { config_setting_t *mapflags; const char *name; const char *zonename; - int i,h; + int i,h,v; int zone_count = 0, disabled_skills_count = 0, disabled_items_count = 0, mapflags_count = 0; zone_count = config_setting_length(zones); @@ -3694,18 +3730,25 @@ void read_map_zone_db(void) { --h; continue; } - if( !config_setting_get_bool(skill) )/* we dont remove it from the three due to inheritance */ + if( !map_zone_bl_type(config_setting_get_string_elem(skills,h)) )/* we dont remove it from the three due to inheritance */ --disabled_skills_count; } /* all ok, process */ - CREATE( zone->disabled_skills, int, disabled_skills_count ); - for(h = 0; h < disabled_skills_count; h++) { + CREATE( zone->disabled_skills, struct map_zone_disabled_skill_entry *, disabled_skills_count ); + for(h = 0, v = 0; h < config_setting_length(skills); h++) { config_setting_t *skill = config_setting_get_elem(skills, h); - + struct map_zone_disabled_skill_entry * entry; + enum bl_type type; name = config_setting_name(skill); - if( config_setting_get_bool(skill) )/* only add if enabled */ - zone->disabled_skills[h] = strdb_iget(skilldb_name2id, name); + if( (type = map_zone_bl_type(config_setting_get_string_elem(skills,h))) ) { /* only add if enabled */ + CREATE( entry, struct map_zone_disabled_skill_entry, 1 ); + + entry->nameid = strdb_iget(skilldb_name2id, name); + entry->type = type; + + zone->disabled_skills[v++] = entry; + } } zone->disabled_skills_count = disabled_skills_count; @@ -3730,13 +3773,13 @@ void read_map_zone_db(void) { } /* all ok, process */ CREATE( zone->disabled_items, int, disabled_items_count ); - for(h = 0; h < disabled_items_count; h++) { + for(h = 0, v = 0; h < config_setting_length(items); h++) { config_setting_t *item = config_setting_get_elem(items, h); if( config_setting_get_bool(item) ) { /* only add if enabled */ name = config_setting_name(item); data = itemdb_searchname(name); - zone->disabled_items[h] = data->nameid; + zone->disabled_items[v++] = data->nameid; } } @@ -3800,15 +3843,17 @@ void read_map_zone_db(void) { int k; for(k = 0; k < disabled_skills_count; k++) { config_setting_t *skill = config_setting_get_elem(skills, k); - if( strdb_iget(skilldb_name2id, config_setting_name(skill)) == izone->disabled_skills[j] ) { - if( config_setting_get_bool(skill) ) - continue; + if( strdb_iget(skilldb_name2id, config_setting_name(skill)) == izone->disabled_skills[j]->nameid ) { break; } } if( k == disabled_skills_count ) {/* we didn't find it */ - RECREATE( zone->disabled_skills, int, ++zone->disabled_skills_count ); - zone->disabled_skills[zone->disabled_skills_count-1] = izone->disabled_skills[j]; + struct map_zone_disabled_skill_entry *entry; + RECREATE( zone->disabled_skills, struct map_zone_disabled_skill_entry *, ++zone->disabled_skills_count ); + CREATE( entry, struct map_zone_disabled_skill_entry, 1 ); + entry->nameid = izone->disabled_skills[j]->nameid; + entry->type = izone->disabled_skills[j]->type; + zone->disabled_skills[zone->disabled_skills_count-1] = entry; } } } diff --git a/src/map/map.h b/src/map/map.h index 7892cbfdc..7af3a184c 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -497,6 +497,10 @@ struct mapflag_skill_adjust { unsigned short skill_id; unsigned short modifier; }; +struct map_zone_disabled_skill_entry { + unsigned short nameid; + enum bl_type type; +}; #define MAP_ZONE_NAME_LENGTH 30 #define MAP_ZONE_ALL_NAME "Normal" @@ -507,7 +511,7 @@ struct mapflag_skill_adjust { DBMap *zone_db;/* string => struct map_zone_data */ struct map_zone_data { char name[MAP_ZONE_NAME_LENGTH];/* 20'd */ - int *disabled_skills; + struct map_zone_disabled_skill_entry **disabled_skills; int disabled_skills_count; int *disabled_items; int disabled_items_count; @@ -568,10 +572,6 @@ struct map_data { unsigned fireworks : 1; unsigned sakura : 1; // [Valaris] unsigned leaves : 1; // [Valaris] - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //unsigned rain : 1; // [Valaris] unsigned nogo : 1; // [Valaris] unsigned nobaseexp : 1; // [Lorky] added by Lupus unsigned nojobexp : 1; // [Lorky] diff --git a/src/map/skill.c b/src/map/skill.c index 77c5f99a2..ca3b28656 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -477,7 +477,6 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b int skillnotok (uint16 skill_id, struct map_session_data *sd) { int16 idx,m; - int i; nullpo_retr (1, sd); m = sd->bl.m; idx = skill->get_index(skill_id); @@ -513,13 +512,6 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd) if( sd->skillitem == skill_id ) return 0; - for(i = 0; i < map[m].zone->disabled_skills_count; i++) { - if( skill_id == map[m].zone->disabled_skills[i] ) { - clif->msg(sd, SKILL_CANT_USE_AREA); // This skill cannot be used within this area - return 1; - } - } - if( sd->sc.option&OPTION_MOUNTING ) return 1;//You can't use skills while in the new mounts (The client doesn't let you, this is to make cheat-safe) diff --git a/src/map/status.c b/src/map/status.c index 809fac4c5..8589a54e7 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1494,28 +1494,40 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; } - switch( skill_id ) { - case PA_PRESSURE: - if( flag && target ) { - //Gloria Avoids pretty much everything.... - tsc = status_get_sc(target); - if(tsc && tsc->option&OPTION_HIDE) - return 0; - } - break; - case GN_WALLOFTHORN: - if( target && status_isdead(target) ) - return 0; - break; - case AL_TELEPORT: - //Should fail when used on top of Land Protector [Skotlex] - if (src && map_getcell(src->m, src->x, src->y, CELL_CHKLANDPROTECTOR) - && !(status->mode&MD_BOSS) - && (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_id)) + if( skill_id ) { + int i; + + for(i = 0; i < map[src->m].zone->disabled_skills_count; i++) { + if( skill_id == map[src->m].zone->disabled_skills[i]->nameid && (map[src->m].zone->disabled_skills[i]->type&src->type) ) { + if( src->type == BL_PC ) + clif->msg((TBL_PC*)src, SKILL_CANT_USE_AREA); // This skill cannot be used within this area return 0; - break; - default: - break; + } + } + + switch( skill_id ) { + case PA_PRESSURE: + if( flag && target ) { + //Gloria Avoids pretty much everything.... + tsc = status_get_sc(target); + if(tsc && tsc->option&OPTION_HIDE) + return 0; + } + break; + case GN_WALLOFTHORN: + if( target && status_isdead(target) ) + return 0; + break; + case AL_TELEPORT: + //Should fail when used on top of Land Protector [Skotlex] + if (src && map_getcell(src->m, src->x, src->y, CELL_CHKLANDPROTECTOR) + && !(status->mode&MD_BOSS) + && (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_id)) + return 0; + break; + default: + break; + } } if ( src ) sc = status_get_sc(src); -- cgit v1.2.3-70-g09d2