summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-03-27 13:22:55 -0300
committershennetsind <ind@henn.et>2013-03-27 13:22:55 -0300
commit90f117f6b071c9c12bb8b521b6de46301639e75c (patch)
treeb9b7c509abe0d7009ab7483a9201f4bcb579bce1 /src
parentc58f741a0f2b807cbeb065c2dbbfe4f86dfb95b2 (diff)
downloadhercules-90f117f6b071c9c12bb8b521b6de46301639e75c.tar.gz
hercules-90f117f6b071c9c12bb8b521b6de46301639e75c.tar.bz2
hercules-90f117f6b071c9c12bb8b521b6de46301639e75c.tar.xz
hercules-90f117f6b071c9c12bb8b521b6de46301639e75c.zip
Introducing Hercules' Map Zone Database
Click the link for full info~! http://hercules.ws/board/topic/302-introducing-hercules-map-zone-database/ Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src')
-rw-r--r--src/map/atcommand.c32
-rw-r--r--src/map/clif.h4
-rw-r--r--src/map/itemdb.c22
-rw-r--r--src/map/itemdb.h3
-rw-r--r--src/map/map.c331
-rw-r--r--src/map/map.h33
-rw-r--r--src/map/mob.c3
-rw-r--r--src/map/npc.c66
-rw-r--r--src/map/npc.h1
-rw-r--r--src/map/pc.c23
-rw-r--r--src/map/script.c56
-rw-r--r--src/map/skill.c38
-rw-r--r--src/map/skill.h2
-rw-r--r--src/map/status.c47
14 files changed, 480 insertions, 181 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index d563ba126..2e7c74b94 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -3795,16 +3795,16 @@ ACMD_FUNC(reloadscript)
* 0 = no additional information
* 1 = Show users in that map and their location
* 2 = Shows NPCs in that map
- * 3 = Shows the shops/chats in that map (not implemented)
+ * 3 = Shows the chats in that map
+ TODO# add the missing mapflags e.g. adjust_skill_damage to display
*------------------------------------------*/
-ACMD_FUNC(mapinfo)
-{
+ACMD_FUNC(mapinfo) {
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
struct npc_data *nd = NULL;
struct chat_data *cd = NULL;
char direction[12];
- int i, m_id, chat_num, list = 0;
+ int i, m_id, chat_num = 0, list = 0, vend_num = 0;
unsigned short m_index;
char mapname[24];
@@ -3839,12 +3839,17 @@ ACMD_FUNC(mapinfo)
// count chats (for initial message)
chat_num = 0;
iter = mapit_getallusers();
- for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
- if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd )
- chat_num++;
+ for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) {
+ if( pl_sd->mapindex == m_index ) {
+ if( sd->state.vending )
+ vend_num++;
+ else if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && cd->usersd[0] == pl_sd )
+ chat_num++;
+ }
+ }
mapit_free(iter);
- sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].users, map[m_id].npc_num, chat_num); // Map Name: %s | Players In Map: %d | NPCs In Map: %d | Chats In Map: %d
+ sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].zone->name, map[m_id].users, map[m_id].npc_num, chat_num, vend_num); // Map: %s (Zone:%s) | Players: %d | NPCs: %d | Chats: %d | Vendings: %d
clif_displaymessage(fd, atcmd_output);
clif_displaymessage(fd, msg_txt(1041)); // ------ Map Flags ------
if (map[m_id].flag.town)
@@ -3932,11 +3937,6 @@ ACMD_FUNC(mapinfo)
strcat(atcmd_output, msg_txt(1077)); // Fireworks |
if (map[m_id].flag.leaves)
strcat(atcmd_output, msg_txt(1078)); // Leaves |
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //if (map[m_id].flag.rain)
- // strcat(atcmd_output, msg_txt(1079)); // Rain |
if (map[m_id].flag.nightenabled)
strcat(atcmd_output, msg_txt(1080)); // Displays Night |
clif_displaymessage(fd, atcmd_output);
@@ -7635,7 +7635,7 @@ ACMD_FUNC(mapflag) {
checkflag(fog); checkflag(fireworks); checkflag(sakura); checkflag(leaves);
checkflag(nogo); checkflag(nobaseexp);
checkflag(nojobexp); checkflag(nomobloot); checkflag(nomvploot); checkflag(nightenabled);
- checkflag(restricted); checkflag(nodrop); checkflag(novending); checkflag(loadevent);
+ checkflag(nodrop); checkflag(novending); checkflag(loadevent);
checkflag(nochat); checkflag(partylock); checkflag(guildlock); checkflag(src4instance);
clif_displaymessage(sd->fd," ");
clif_displaymessage(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
@@ -7654,7 +7654,7 @@ ACMD_FUNC(mapflag) {
setflag(fog); setflag(fireworks); setflag(sakura); setflag(leaves);
setflag(nogo); setflag(nobaseexp);
setflag(nojobexp); setflag(nomobloot); setflag(nomvploot); setflag(nightenabled);
- setflag(restricted); setflag(nodrop); setflag(novending); setflag(loadevent);
+ setflag(nodrop); setflag(novending); setflag(loadevent);
setflag(nochat); setflag(partylock); setflag(guildlock); setflag(src4instance);
clif_displaymessage(sd->fd,msg_txt(1314)); // Invalid flag name or flag.
@@ -7666,7 +7666,7 @@ ACMD_FUNC(mapflag) {
clif_displaymessage(sd->fd,"pvp_nocalcrank, gvg_castle, gvg, gvg_dungeon, gvg_noparty, battleground,");
clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,");
- clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,");
+ clif_displaymessage(sd->fd,"nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,");
clif_displaymessage(sd->fd,"guildlock, src4instance");
#undef checkflag
diff --git a/src/map/clif.h b/src/map/clif.h
index 8e0fc6629..1c04ae393 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -314,6 +314,10 @@ enum useskill_fail_cause
USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83,
};
+enum clif_messages {
+ SKILL_CANT_USE_AREA = 0x536,
+};
+
int clif_setip(const char* ip);
void clif_setbindip(const char* ip);
void clif_setport(uint16 port);
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 79d303085..a91946b2a 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -586,27 +586,6 @@ static void itemdb_read_itemgroup(void)
}
/*==========================================
- * Read item forbidden by mapflag (can't equip item)
- *------------------------------------------*/
-static bool itemdb_read_noequip(char* str[], int columns, int current)
-{// <nameid>,<mode>
- int nameid;
- struct item_data *id;
-
- nameid = atoi(str[0]);
-
- if( ( id = itemdb_exists(nameid) ) == NULL )
- {
- ShowWarning("itemdb_read_noequip: Invalid item id %d.\n", nameid);
- return false;
- }
-
- id->flag.no_equip |= atoi(str[1]);
-
- return true;
-}
-
-/*==========================================
* Reads item trade restrictions [Skotlex]
*------------------------------------------*/
static bool itemdb_read_itemtrade(char* str[], int columns, int current)
@@ -1310,7 +1289,6 @@ static void itemdb_read(void) {
itemdb_read_combos();
itemdb_read_itemgroup();
sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
- sv_readdb(db_path, DBPATH"item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip);
sv_readdb(db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
sv_readdb(db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay);
sv_readdb(db_path, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack);
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index e308b248b..06c95da8a 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -66,7 +66,7 @@ enum {
ITEMID_CAMOUFLAGE_GENERATOR,
ITEMID_HIGH_QUALITY_COOLER,
ITEMID_SPECIAL_COOLER,
- } mecha_item_list;
+} mecha_item_list;
//The only item group required by the code to be known. See const.txt for the full list.
#define IG_FINDINGORE 6
@@ -123,7 +123,6 @@ struct item_data {
struct script_code *unequip_script;//Script executed once when unequipping.
struct {
unsigned available : 1;
- short no_equip;
unsigned no_refine : 1; // [celest]
unsigned delay_consume : 1; // Signifies items that are not consumed immediately upon double-click [Skotlex]
unsigned trade_restriction : 9; //Item restrictions mask [Skotlex]
diff --git a/src/map/map.c b/src/map/map.c
index bd0d97ece..a7b8513f7 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -13,6 +13,7 @@
#include "../common/random.h"
#include "../common/strlib.h"
#include "../common/utils.h"
+#include "../common/conf.h"
#include "map.h"
#include "path.h"
@@ -2892,6 +2893,31 @@ int map_delmap(char* mapname)
}
return 0;
}
+void map_zone_db_clear(void) {
+ struct map_zone_data *zone;
+ int i;
+
+ DBIterator *iter = db_iterator(zone_db);
+ for(zone = dbi_first(iter); dbi_exists(iter); zone = dbi_next(iter)) {
+ aFree(zone->disabled_skills);
+ aFree(zone->disabled_items);
+ for(i = 0; i < zone->mapflags_count; i++) {
+ aFree(zone->mapflags[i]);
+ }
+ aFree(zone->mapflags);
+ }
+ dbi_destroy(iter);
+
+ db_destroy(zone_db);/* will aFree(zone) */
+
+ /* clear the main zone stuff */
+ aFree(map_zone_all.disabled_skills);
+ aFree(map_zone_all.disabled_items);
+ for(i = 0; i < map_zone_all.mapflags_count; i++) {
+ aFree(map_zone_all.mapflags[i]);
+ }
+ aFree(map_zone_all.mapflags);
+}
void do_final_maps(void) {
int i, v = 0;
@@ -2931,11 +2957,12 @@ void do_final_maps(void) {
}
map[i].skill_count = 0;
}
-
+
}
+ map_zone_db_clear();
+
}
-
/// Initializes map flags and adjusts them depending on configuration.
void map_flags_init(void) {
int i, v = 0;
@@ -2945,7 +2972,6 @@ void map_flags_init(void) {
memset(&map[i].flag, 0, sizeof(map[i].flag));
// additional mapflag data
- map[i].zone = 0; // restricted mapflag zone
map[i].nocommand = 0; // nocommand mapflag level
map[i].bexp = 100; // per map base exp multiplicator
map[i].jexp = 100; // per map job exp multiplicator
@@ -2968,10 +2994,12 @@ void map_flags_init(void) {
}
map[i].skills = NULL;
map[i].skill_count = 0;
-
+
// adjustments
if( battle_config.pk_mode )
map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
+ /* align with 'All' zone */
+ map[i].zone = &map_zone_all;
}
}
@@ -3533,6 +3561,296 @@ int log_sql_init(void)
#endif
return 0;
}
+void map_zone_apply(int m, struct map_zone_data *zone,char* w1, const char* start, const char* buffer, const char* filepath) {
+ int i;
+ char empty[1] = "\0";
+ map[m].zone = zone;
+ for(i = 0; i < zone->mapflags_count; i++) {
+ char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
+ int len = strlen(zone->mapflags[i]);
+ int k;
+ params[0] = '\0';
+ memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
+ for(k = 0; k < len; k++) {
+ if( flag[k] == '\t' ) {
+ memcpy(params, &flag[k+1], len - k);
+ flag[k] = '\0';
+ break;
+ }
+ }
+ npc_parse_mapflag(w1,empty,flag,params,start,buffer,filepath);
+ }
+}
+/* used on npc load and reload to apply all "Normal" zone */
+void map_zone_init(void) {
+ struct map_zone_data *zone;
+ char empty[1] = "\0";
+ int i,k,j;
+
+ zone = &map_zone_all;
+
+ for(i = 0; i < zone->mapflags_count; i++) {
+ char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
+ int len = strlen(zone->mapflags[i]);
+ params[0] = '\0';
+ memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
+ for(k = 0; k < len; k++) {
+ if( flag[k] == '\t' ) {
+ memcpy(params, &flag[k+1], len - k);
+ flag[k] = '\0';
+ break;
+ }
+ }
+ for(j = 0; j < map_num; j++) {
+ if( map[j].zone == &map_zone_all ) {
+ npc_parse_mapflag(map[j].name,empty,flag,params,empty,empty,empty);
+ }
+ }
+ }
+
+}
+void read_map_zone_db(void) {
+ config_t map_zone_db;
+ config_setting_t *zones = NULL;
+ /* TODO: #ifndef required for re/pre-re */
+#ifdef RENEWAL
+ const char *config_filename = "db/re/map_zone_db.txt"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/map_zone_db.txt"; // FIXME hardcoded name
+#endif
+ if (conf_read_file(&map_zone_db, config_filename))
+ return;
+
+ zones = config_lookup(&map_zone_db, "zones");
+
+ if (zones != NULL) {
+ struct map_zone_data *zone;
+ struct item_data *data;
+ config_setting_t *zone_e;
+ config_setting_t *skills;
+ config_setting_t *items;
+ config_setting_t *mapflags;
+ const char *name;
+ const char *zonename;
+ int i,h;
+ int zone_count = 0, disabled_skills_count = 0, disabled_items_count = 0, mapflags_count = 0;
+
+ zone_count = config_setting_length(zones);
+ for (i = 0; i < zone_count; ++i) {
+ bool is_all = false;
+
+ zone_e = config_setting_get_elem(zones, i);
+
+ if (!config_setting_lookup_string(zone_e, "name", &zonename)) {
+ ShowError("map_zone_db: missing zone name, skipping... (%s:%d)\n",
+ config_setting_source_file(zone_e), config_setting_source_line(zone_e));
+ config_setting_remove_elem(zones,i);/* remove from the tree */
+ --zone_count;
+ --i;
+ continue;
+ }
+
+ if( strdb_exists(zone_db, zonename) ) {
+ ShowError("map_zone_db: duplicate zone name '%s', skipping...\n",zonename);
+ config_setting_remove_elem(zones,i);/* remove from the tree */
+ --zone_count;
+ --i;
+ continue;
+ }
+
+ /* is this the global template? */
+ if( strncmpi(zonename,MAP_ZONE_ALL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) {
+ zone = &map_zone_all;
+ is_all = true;
+ } else {
+ CREATE( zone, struct map_zone_data, 1 );
+ zone->disabled_skills_count = 0;
+ zone->disabled_items_count = 0;
+ }
+ safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH);
+
+ if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) {
+ disabled_skills_count = config_setting_length(skills);
+ /* validate */
+ for(h = 0; h < config_setting_length(skills); h++) {
+ config_setting_t *skill = config_setting_get_elem(skills, h);
+ name = config_setting_name(skill);
+ if( !strdb_exists(skilldb_name2id,name) ) {
+ ShowError("map_zone_db: unknown skill (%s) in disabled_skills for zone '%s', skipping skill...\n",name,zone->name);
+ config_setting_remove_elem(skills,h);
+ --disabled_skills_count;
+ --h;
+ continue;
+ }
+ if( !config_setting_get_bool(skill) )/* 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++) {
+ config_setting_t *skill = config_setting_get_elem(skills, h);
+
+ name = config_setting_name(skill);
+
+ if( config_setting_get_bool(skill) )/* only add if enabled */
+ zone->disabled_skills[h] = strdb_iget(skilldb_name2id, name);
+
+ }
+ zone->disabled_skills_count = disabled_skills_count;
+ }
+
+ if( (items = config_setting_get_member(zone_e, "disabled_items")) != NULL ) {
+ disabled_items_count = config_setting_length(items);
+ /* validate */
+ for(h = 0; h < config_setting_length(items); h++) {
+ config_setting_t *item = config_setting_get_elem(items, h);
+ name = config_setting_name(item);
+ data = itemdb_searchname(name);
+ if( data == NULL ) {
+ ShowError("map_zone_db: unknown item (%s) in disabled_items for zone '%s', skipping item...\n",name,zone->name);
+ config_setting_remove_elem(items,h);
+ --disabled_items_count;
+ --h;
+ continue;
+ }
+ if( !config_setting_get_bool(item) )/* we dont remove it from the three due to inheritance */
+ --disabled_items_count;
+ }
+ /* all ok, process */
+ CREATE( zone->disabled_items, int, disabled_items_count );
+ for(h = 0; h < disabled_items_count; 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_count = disabled_items_count;
+ }
+
+ if( (mapflags = config_setting_get_member(zone_e, "mapflags")) != NULL ) {
+ mapflags_count = config_setting_length(mapflags);
+ /* mapflags are not validated here, so we save all anyway */
+ CREATE( zone->mapflags, char *, mapflags_count );
+ for(h = 0; h < mapflags_count; h++) {
+ CREATE( zone->mapflags[h], char, MAP_ZONE_MAPFLAG_LENGTH );
+
+ name = config_setting_get_string_elem(mapflags, h);
+
+ safestrncpy(zone->mapflags[h], name, MAP_ZONE_MAPFLAG_LENGTH);
+
+ }
+ zone->mapflags_count = mapflags_count;
+ }
+
+
+ if( !is_all ) /* global template doesn't go into db -- since it isn't a alloc'd piece of data */
+ strdb_put(zone_db, zonename, zone);
+
+ }
+
+ /* process inheritance, aka loop through the whole thing again :P */
+ for (i = 0; i < zone_count; ++i) {
+ config_setting_t *inherit_tree = NULL;
+
+ zone_e = config_setting_get_elem(zones, i);
+
+ if( (inherit_tree = config_setting_get_member(zone_e, "inherit")) != NULL ) {
+ int inherit_count = config_setting_length(inherit_tree);
+ for(h = 0; h < inherit_count; h++) {
+ struct map_zone_data *izone; /* inherit zone */
+ int disabled_skills_count_i = 0; /* disabled skill count from inherit zone */
+ int disabled_items_count_i = 0; /* disabled item count from inherit zone */
+ int mapflags_count_i = 0; /* mapflag count from inherit zone */
+ int j;
+
+ name = config_setting_get_string_elem(inherit_tree, h);
+ config_setting_lookup_string(zone_e, "name", &zonename);/* will succeed for we validated it earlier */
+
+ if( !(izone = strdb_get(zone_db, name)) ) {
+ ShowError("map_zone_db: Unknown zone '%s' being inherit by zone '%s', skipping...\n",name,zonename);
+ continue;
+ }
+
+ zone = strdb_get(zone_db, zonename);/* will succeed for we just put it in here */
+
+ disabled_skills_count_i = izone->disabled_skills_count;
+ disabled_items_count_i = izone->disabled_items_count;
+ mapflags_count_i = izone->mapflags_count;
+
+ /* process everything to override, paying attention to config_setting_get_bool */
+ if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) {
+ disabled_skills_count = config_setting_length(skills);
+ for(j = 0; j < disabled_skills_count_i; j++) {
+ 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;
+ 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];
+ }
+ }
+ }
+
+ if( (items = config_setting_get_member(zone_e, "disabled_items")) != NULL ) {
+ disabled_items_count = config_setting_length(items);
+ for(j = 0; j < disabled_items_count_i; j++) {
+ int k;
+ for(k = 0; k < disabled_items_count; k++) {
+ config_setting_t *item = config_setting_get_elem(items, k);
+
+ name = config_setting_name(item);
+ data = itemdb_searchname(name);
+
+ if( data->nameid == izone->disabled_items[j] ) {
+ if( config_setting_get_bool(item) )
+ continue;
+ break;
+ }
+ }
+ if( k == disabled_items_count ) {/* we didn't find it */
+ RECREATE( zone->disabled_items, int, ++zone->disabled_items_count );
+ zone->disabled_items[zone->disabled_items_count-1] = izone->disabled_items[j];
+ }
+ }
+ }
+
+ if( (mapflags = config_setting_get_member(zone_e, "mapflags")) != NULL ) {
+ mapflags_count = config_setting_length(mapflags);
+ for(j = 0; j < mapflags_count_i; j++) {
+ int k;
+ for(k = 0; k < mapflags_count; k++) {
+ name = config_setting_get_string_elem(mapflags, k);
+
+ if( strcmpi(name,izone->mapflags[j]) == 0 ) {
+ break;
+ }
+ }
+ if( k == mapflags_count ) {/* we didn't find it */
+ RECREATE( zone->mapflags, char*, ++zone->mapflags_count );
+ CREATE( zone->mapflags[zone->mapflags_count-1], char, MAP_ZONE_MAPFLAG_LENGTH );
+ safestrncpy(zone->mapflags[zone->mapflags_count-1], izone->mapflags[j], MAP_ZONE_MAPFLAG_LENGTH);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' zones in '"CL_WHITE"%s"CL_RESET"'.\n", zone_count, config_filename);
+ /* not supposed to go in here but in skill_final whatever */
+ config_destroy(&map_zone_db);
+ }
+}
/**
* @see DBApply
@@ -3632,7 +3950,7 @@ void do_final(void)
id_db->foreach(id_db,cleanup_db_sub);
chrif_char_reset_offline();
chrif_flush_fifo();
-
+
do_final_atcommand();
battle->final();
do_final_chrif();
@@ -3933,7 +4251,9 @@ int do_init(int argc, char *argv[])
regen_db = idb_alloc(DB_OPT_BASE); // efficient status_natural_heal processing
iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls
+ zone_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH);
+
map_sql_init();
if (log_config.sql_logs)
log_sql_init();
@@ -3957,6 +4277,7 @@ int do_init(int argc, char *argv[])
do_init_script();
do_init_itemdb();
skill->init();
+ read_map_zone_db();/* read after item and skill initalization */
do_init_mob();
do_init_pc();
do_init_status();
diff --git a/src/map/map.h b/src/map/map.h
index 38d9726cb..cd5983686 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -11,9 +11,6 @@
#include "../common/mapindex.h"
#include "../common/db.h"
-/**
- * [rAthena.org]
- **/
#include "../config/core.h"
#include <stdarg.h>
@@ -21,8 +18,7 @@
struct npc_data;
struct item_data;
-enum E_MAPSERVER_ST
-{
+enum E_MAPSERVER_ST {
MAPSERVER_ST_RUNNING = CORE_ST_LAST,
MAPSERVER_ST_SHUTDOWN,
MAPSERVER_ST_LAST
@@ -501,6 +497,28 @@ struct mapflag_skill_adjust {
unsigned short modifier;
};
+#define MAP_ZONE_NAME_LENGTH 30
+#define MAP_ZONE_ALL_NAME "Normal"
+#define MAP_ZONE_PVP_NAME "PvP"
+#define MAP_ZONE_GVG_NAME "GvG"
+#define MAP_ZONE_BG_NAME "Battlegrounds"
+#define MAP_ZONE_MAPFLAG_LENGTH 50
+DBMap *zone_db;/* string => struct map_zone_data */
+struct map_zone_data {
+ char name[MAP_ZONE_NAME_LENGTH];/* 20'd */
+ int *disabled_skills;
+ int disabled_skills_count;
+ int *disabled_items;
+ int disabled_items_count;
+ char **mapflags;
+ int mapflags_count;
+};
+void map_zone_init(void);
+void map_zone_apply(int m, struct map_zone_data *zone,char* w1, const char* start, const char* buffer, const char* filepath);
+
+struct map_zone_data map_zone_all;/* used as a base on all maps */
+
+
struct map_data {
char name[MAP_NAME_LENGTH];
uint16 index; // The map index used by the mapindex* functions.
@@ -559,7 +577,6 @@ struct map_data {
unsigned nomobloot : 1; // [Lorky]
unsigned nomvploot : 1; // [Lorky]
unsigned nightenabled :1; //For night display. [Skotlex]
- unsigned restricted : 1; // [Komurka]
unsigned nodrop : 1;
unsigned novending : 1;
unsigned loadevent : 1;
@@ -579,7 +596,6 @@ struct map_data {
struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer]
int mob_delete_timer; // [Skotlex]
- int zone; // zone number (for item/skill restrictions)
int jexp; // map experience multiplicator
int bexp; // map experience multiplicator
int nocommand; //Blocks @/# commands for non-gms. [Skotlex]
@@ -600,6 +616,9 @@ struct map_data {
/* adjust_skill_damage mapflag */
struct mapflag_skill_adjust **skills;
unsigned short skill_count;
+
+ /* Hercules nocast db overhaul */
+ struct map_zone_data *zone;
};
/// Stores information about a remote map (for multi-mapserver setups).
diff --git a/src/map/mob.c b/src/map/mob.c
index fa4bd5c7f..71b500491 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -3389,8 +3389,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) {
skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id;
if (!skill_id || sd->status.skill[skill_id].lv < 1 ||
- (skill->get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
- skill->get_nocast(skill_id)&16
+ (skill->get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL))
)
continue;
//Normal aggressive mob, disable skills that cannot help them fight
diff --git a/src/map/npc.c b/src/map/npc.c
index 0c9924d46..797fc7422 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -3157,14 +3157,12 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
return strchr(start,'\n');// continue
}
-
/*==========================================
* Set or disable mapflag on map
* eg : bat_c01 mapflag battleground 2
* also chking if mapflag conflict with another
*------------------------------------------*/
-static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
-{
+const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) {
int16 m;
char mapname[32];
int state = 1;
@@ -3231,19 +3229,21 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
map[m].flag.nozenypenalty=state;
}
else if (!strcmpi(w3,"pvp")) {
+ struct map_zone_data *zone;
map[m].flag.pvp = state;
- if( state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) )
- {
+ if( state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) {
map[m].flag.gvg = 0;
map[m].flag.gvg_dungeon = 0;
map[m].flag.gvg_castle = 0;
ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing GvG flags from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
}
- if( state && map[m].flag.battleground )
- {
+ if( state && map[m].flag.battleground ) {
map[m].flag.battleground = 0;
ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
}
+ if( (zone = strdb_get(zone_db, MAP_ZONE_GVG_NAME)) && map[m].zone != zone ) {
+ map_zone_apply(m,zone,w1,start,buffer,filepath);
+ }
}
else if (!strcmpi(w3,"pvp_noparty"))
map[m].flag.pvp_noparty=state;
@@ -3283,17 +3283,20 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
else if (!strcmpi(w3,"pvp_nocalcrank"))
map[m].flag.pvp_nocalcrank=state;
else if (!strcmpi(w3,"gvg")) {
+ struct map_zone_data *zone;
+
map[m].flag.gvg = state;
- if( state && map[m].flag.pvp )
- {
+ if( state && map[m].flag.pvp ) {
map[m].flag.pvp = 0;
ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
}
- if( state && map[m].flag.battleground )
- {
+ if( state && map[m].flag.battleground ) {
map[m].flag.battleground = 0;
ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
}
+ if( (zone = strdb_get(zone_db, MAP_ZONE_GVG_NAME)) && map[m].zone != zone ) {
+ map_zone_apply(m,zone,w1,start,buffer,filepath);
+ }
}
else if (!strcmpi(w3,"gvg_noparty"))
map[m].flag.gvg_noparty=state;
@@ -3306,28 +3309,29 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
if (state) map[m].flag.pvp=0;
}
else if (!strcmpi(w3,"battleground")) {
- if( state )
- {
+ struct map_zone_data *zone;
+ if( state ) {
if( sscanf(w4, "%d", &state) == 1 )
map[m].flag.battleground = state;
else
map[m].flag.battleground = 1; // Default value
- }
- else
+ } else
map[m].flag.battleground = 0;
- if( map[m].flag.battleground && map[m].flag.pvp )
- {
+ if( map[m].flag.battleground && map[m].flag.pvp ) {
map[m].flag.pvp = 0;
ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
}
- if( map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) )
- {
+ if( map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) {
map[m].flag.gvg = 0;
map[m].flag.gvg_dungeon = 0;
map[m].flag.gvg_castle = 0;
ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing GvG flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
}
+
+ if( (zone = strdb_get(zone_db, MAP_ZONE_BG_NAME)) && map[m].zone != zone ) {
+ map_zone_apply(m,zone,w1,start,buffer,filepath);
+ }
}
else if (!strcmpi(w3,"noexppenalty"))
map[m].flag.noexppenalty=state;
@@ -3391,16 +3395,6 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
} else
map[m].nocommand=0;
}
- else if (!strcmpi(w3,"restricted")) {
- if (state) {
- map[m].flag.restricted=1;
- sscanf(w4, "%d", &state);
- map[m].zone |= 1<<(state+1);
- } else {
- map[m].flag.restricted=0;
- map[m].zone = 0;
- }
- }
else if (!strcmpi(w3,"jexp")) {
map[m].jexp = (state) ? atoi(w4) : 100;
if( map[m].jexp < 0 ) map[m].jexp = 100;
@@ -3459,6 +3453,14 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
map[m].skills[idx]->skill_id = (unsigned short)skill_id;
map[m].skills[idx]->modifier = (unsigned short)atoi(mod);
}
+ } else if (!strcmpi(w3,"zone")) {
+ struct map_zone_data *zone;
+
+ if( !(zone = strdb_get(zone_db, w4)) ) {
+ ShowWarning("npc_parse_mapflag: Invalid zone '%s'! removing flag from %s (file '%s', line '%d').\n", w4, map[m].name, filepath, strline(buffer,start-buffer));
+ } else if( map[m].zone != zone ) { /* we do not override :P would mess everything */
+ map_zone_apply(m,zone,w1,start,buffer,filepath);
+ }
} else
ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
@@ -3792,12 +3794,14 @@ int npc_reload(void) {
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
"\t-'"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);
-
+
do_final_instance();
for( i = 0; i < ARRAYLENGTH(instance); ++i )
instance_init(instance[i].instance_id);
+ map_zone_init();
+
//Re-read the NPC Script Events cache.
npc_read_event_script();
@@ -3926,6 +3930,8 @@ int do_init_npc(void)
"\t-'"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);
+ map_zone_init();
+
// set up the events cache
memset(script_event, 0, sizeof(script_event));
npc_read_event_script();
diff --git a/src/map/npc.h b/src/map/npc.h
index 20ce34459..424ff9312 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -124,6 +124,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type);
int npc_buylist(struct map_session_data* sd,int n, unsigned short* item_list);
int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list);
void npc_parse_mob2(struct spawn_data* mob);
+const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath);
struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y);
int npc_globalmessage(const char* name,const char* mes);
diff --git a/src/map/pc.c b/src/map/pc.c
index 4bd66a67c..840bf0c03 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4227,12 +4227,13 @@ int pc_isUseitem(struct map_session_data *sd,int n)
int pc_useitem(struct map_session_data *sd,int n)
{
unsigned int tick = gettick();
- int amount, nameid;
+ int amount, nameid, i;
struct script_code *script;
nullpo_ret(sd);
if( sd->npc_id ){
+ /* TODO: add to clif_messages enum */
#ifdef RENEWAL
clif_msg(sd, 0x783); // TODO look for the client date that has this message.
#endif
@@ -4320,19 +4321,15 @@ int pc_useitem(struct map_session_data *sd,int n)
}
}
- /* on restricted maps the item is consumed but the effect is not used */
- if (
- (!map_flag_vs(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&1) || // Normal
- (map[sd->bl.m].flag.pvp && sd->inventory_data[n]->flag.no_equip&2) || // PVP
- (map_flag_gvg(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&4) || // GVG
- (map[sd->bl.m].flag.battleground && sd->inventory_data[n]->flag.no_equip&8) || // Battleground
- (map[sd->bl.m].flag.restricted && sd->inventory_data[n]->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction
- ) {
- if( battle_config.item_restricted_consumption_type ) {
- clif_useitemack(sd,n,sd->status.inventory[n].amount-1,true);
- pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME);
+ /* on restricted maps the item is consumed but the effect is not used */
+ for(i = 0; i < map[sd->bl.m].zone->disabled_items_count; i++) {
+ if( map[sd->bl.m].zone->disabled_items[i] == nameid ) {
+ if( battle_config.item_restricted_consumption_type ) {
+ clif_useitemack(sd,n,sd->status.inventory[n].amount-1,true);
+ pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME);
+ }
+ return 0;
}
- return 0;/* regardless, effect is not run */
}
sd->itemid = sd->status.inventory[n].nameid;
diff --git a/src/map/script.c b/src/map/script.c
index 4c913651a..0e45f4821 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -384,7 +384,7 @@ enum {
MF_NORETURN,
MF_NOWARPTO,
MF_NIGHTMAREDROP,
- MF_RESTRICTED,
+ MF_ZONE,
MF_NOCOMMAND,
MF_NODROP,
MF_JEXP,
@@ -9558,8 +9558,8 @@ static int buildin_announce_sub(struct block_list *bl, va_list ap)
return 0;
}
/* Runs item effect on attached character.
- * consumeitem <item id>;
- * consumeitem "<item name>"; */
+ * itemeffect <item id>;
+ * itemeffect "<item name>"; */
BUILDIN_FUNC(itemeffect) {
TBL_NPC *nd;
TBL_PC *sd;
@@ -9579,14 +9579,14 @@ BUILDIN_FUNC(itemeffect) {
ShowError( "buildin_itemeffect: Nonexistant item %s requested.\n", name );
return 1;
}
- }else if( data_isint( data ) ){
+ } else if( data_isint( data ) ){
int nameid = conv_num( st, data );
if( ( item_data = itemdb_exists( nameid ) ) == NULL ){
ShowError("buildin_itemeffect: Nonexistant item %d requested.\n", nameid );
return 1;
}
- }else{
+ } else {
ShowError("buildin_itemeffect: invalid data type for argument #1 (%d).", data->type );
return 1;
}
@@ -10707,10 +10707,6 @@ BUILDIN_FUNC(getmapflag)
case MF_FOG: script_pushint(st,map[m].flag.fog); break;
case MF_SAKURA: script_pushint(st,map[m].flag.sakura); break;
case MF_LEAVES: script_pushint(st,map[m].flag.leaves); break;
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //case MF_RAIN: script_pushint(st,map[m].flag.rain); break;
case MF_NOGO: script_pushint(st,map[m].flag.nogo); break;
case MF_CLOUDS: script_pushint(st,map[m].flag.clouds); break;
case MF_CLOUDS2: script_pushint(st,map[m].flag.clouds2); break;
@@ -10725,7 +10721,6 @@ BUILDIN_FUNC(getmapflag)
case MF_NORETURN: script_pushint(st,map[m].flag.noreturn); break;
case MF_NOWARPTO: script_pushint(st,map[m].flag.nowarpto); break;
case MF_NIGHTMAREDROP: script_pushint(st,map[m].flag.pvp_nightmaredrop); break;
- case MF_RESTRICTED: script_pushint(st,map[m].flag.restricted); break;
case MF_NOCOMMAND: script_pushint(st,map[m].nocommand); break;
case MF_NODROP: script_pushint(st,map[m].flag.nodrop); break;
case MF_JEXP: script_pushint(st,map[m].jexp); break;
@@ -10764,15 +10759,27 @@ static int script_mapflag_pvp_sub(struct block_list *bl,va_list ap) {
BUILDIN_FUNC(setmapflag)
{
int16 m,i;
- const char *str;
+ const char *str, *val2;
+ struct script_data* data;
int val=0;
str=script_getstr(st,2);
- i=script_getnum(st,3);
+
+ i = script_getnum(st, 3);
+
if(script_hasdata(st,4)){
- val=script_getnum(st,4);
+ data = script_getdata(st,4);
+ get_val(st, data);
+
+
+ if( data_isstring(data) )
+ val2 = script_getstr(st, 4);
+ else
+ val = script_getnum(st, 4);
+
}
m = map_mapname2mapid(str);
+
if(m >= 0) {
switch(i) {
case MF_NOMEMO: map[m].flag.nomemo = 1; break;
@@ -10821,9 +10828,13 @@ BUILDIN_FUNC(setmapflag)
case MF_NORETURN: map[m].flag.noreturn = 1; break;
case MF_NOWARPTO: map[m].flag.nowarpto = 1; break;
case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 1; break;
- case MF_RESTRICTED:
- map[m].zone |= 1<<(val+1);
- map[m].flag.restricted=1;
+ case MF_ZONE: {
+ char zone[6] = "zone\0";
+ char empty[1] = "\0";
+ char params[MAP_ZONE_MAPFLAG_LENGTH];
+ memcpy(params, val2, MAP_ZONE_MAPFLAG_LENGTH);
+ npc_parse_mapflag(map[m].name, empty, zone, params, empty, empty, empty);
+ }
break;
case MF_NOCOMMAND: map[m].nocommand = (val <= 0) ? 100 : val; break;
case MF_NODROP: map[m].flag.nodrop = 1; break;
@@ -10887,10 +10898,6 @@ BUILDIN_FUNC(removemapflag)
case MF_FOG: map[m].flag.fog = 0; break;
case MF_SAKURA: map[m].flag.sakura = 0; break;
case MF_LEAVES: map[m].flag.leaves = 0; break;
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //case MF_RAIN: map[m].flag.rain = 0; break;
case MF_NOGO: map[m].flag.nogo = 0; break;
case MF_CLOUDS: map[m].flag.clouds = 0; break;
case MF_CLOUDS2: map[m].flag.clouds2 = 0; break;
@@ -10905,11 +10912,8 @@ BUILDIN_FUNC(removemapflag)
case MF_NORETURN: map[m].flag.noreturn = 0; break;
case MF_NOWARPTO: map[m].flag.nowarpto = 0; break;
case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 0; break;
- case MF_RESTRICTED:
- map[m].zone ^= 1<<(val+1);
- if (map[m].zone == 0){
- map[m].flag.restricted=0;
- }
+ case MF_ZONE:/* reset zone state, mapflags cant be removed however */
+ map[m].zone = &map_zone_all;
break;
case MF_NOCOMMAND: map[m].nocommand = 0; break;
case MF_NODROP: map[m].flag.nodrop = 0; break;
@@ -17566,7 +17570,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(isloggedin,"i?"),
BUILDIN_DEF(setmapflagnosave,"ssii"),
BUILDIN_DEF(getmapflag,"si"),
- BUILDIN_DEF(setmapflag,"si?"),
+ BUILDIN_DEF(setmapflag,"sv?"),
BUILDIN_DEF(removemapflag,"si?"),
BUILDIN_DEF(pvpon,"s"),
BUILDIN_DEF(pvpoff,"s"),
diff --git a/src/map/skill.c b/src/map/skill.c
index 88111d898..3bd454357 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -212,7 +212,6 @@ int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_d
int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_db[skill_id].mhp[skill_lv-1], skill_id, skill_lv); }
int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_db[skill_id].castnodex[skill_lv-1], skill_id, skill_lv); }
int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ skill_get (skill_db[skill_id].delaynodex[skill_lv-1], skill_id, skill_lv); }
-int skill_get_nocast ( uint16 skill_id ) { skill_get (skill_db[skill_id].nocast, skill_id, 1); }
int skill_get_type( uint16 skill_id ) { skill_get (skill_db[skill_id].skill_type, skill_id, 1); }
int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill_db[skill_id].unit_id[flag], skill_id, 1); }
int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill_db[skill_id].unit_interval, skill_id, 1); }
@@ -478,6 +477,7 @@ 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);
@@ -501,25 +501,23 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
return 1;
}
- if (sd->blockskill[idx] > 0){
+ if (sd->blockskill[idx] > 0) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0);
return 1;
}
+
/**
- * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions above
+ * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions below
* Also, without this check, an exploit where an item casting + healing (or any other kind buff) isn't deleted after used on a restricted map
**/
if( sd->skillitem == skill_id )
return 0;
- /* TODO: these skill_get_nocast should be cached once instead of looking it up 5 times =_= */
- // Check skill restrictions [Celest]
- if( (!map_flag_vs(m) && skill->get_nocast (skill_id) & 1) ||
- (map[m].flag.pvp && skill->get_nocast (skill_id) & 2) ||
- (map_flag_gvg(m) && skill->get_nocast (skill_id) & 4) ||
- (map[m].flag.battleground && skill->get_nocast (skill_id) & 8) ||
- (map[m].flag.restricted && map[m].zone && skill->get_nocast (skill_id) & (8*map[m].zone)) ){
- clif_msg(sd, 0x536); // This skill cannot be used within this area
+
+ 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 )
@@ -17476,18 +17474,6 @@ bool skill_parse_row_castnodexdb(char* split[], int columns, int current) {
return true;
}
-bool skill_parse_row_nocastdb(char* split[], int columns, int current) {
-// skill_id,Flag
- uint16 skill_id = atoi(split[0]);
- uint16 idx = skill->get_index(skill_id);
- if( !idx ) // invalid skill id
- return false;
-
- skill_db[idx].nocast |= atoi(split[1]);
-
- return true;
-}
-
bool skill_parse_row_unitdb(char* split[], int columns, int current) {
// ID,unit ID,unit ID 2,layout,range,interval,target,flag
uint16 skill_id = atoi(split[0]);
@@ -17734,8 +17720,6 @@ void skill_readdb(void) {
sv_readdb(db_path, DBPATH"skill_castnodex_db.txt", ',', 2, 3, MAX_SKILL_DB, skill->parse_row_castnodexdb);
sv_readdb(db_path, DBPATH"skill_unit_db.txt" , ',', 8, 8, MAX_SKILL_DB, skill->parse_row_unitdb);
- sv_readdb(db_path, DBPATH"skill_nocast_db.txt" , ',', 2, 2, MAX_SKILL_DB, skill->parse_row_nocastdb);
-
skill->init_unit_layout();
sv_readdb(db_path, "produce_db.txt" , ',', 4, 4+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill->parse_row_producedb);
sv_readdb(db_path, "create_arrow_db.txt" , ',', 1+2, 1+2*MAX_ARROW_RESOURCE, MAX_SKILL_ARROW_DB, skill->parse_row_createarrowdb);
@@ -17747,7 +17731,6 @@ void skill_readdb(void) {
sv_readdb(db_path, "skill_reproduce_db.txt", ',', 1, 1, MAX_SKILL_DB, skill->parse_row_reproducedb);
sv_readdb(db_path, "skill_improvise_db.txt" , ',', 2, 2, MAX_SKILL_IMPROVISE_DB, skill->parse_row_improvisedb);
sv_readdb(db_path, "skill_changematerial_db.txt" , ',', 4, 4+2*5, MAX_SKILL_PRODUCE_DB, skill->parse_row_changematerialdb);
-
}
void skill_reload (void) {
@@ -17791,6 +17774,7 @@ int do_init_skill (void)
int do_final_skill(void)
{
db_destroy(skilldb_name2id);
+ /* TODO: ZONE_DB IS NOT PROPERLY CLEARED */
db_destroy(group_db);
db_destroy(skillunit_db);
db_destroy(skillcd_db);
@@ -17834,7 +17818,6 @@ void skill_defaults(void) {
skill->get_weapontype = skill_get_weapontype;
skill->get_ammotype = skill_get_ammotype;
skill->get_ammo_qty = skill_get_ammo_qty;
- skill->get_nocast = skill_get_nocast;
skill->get_unit_id = skill_get_unit_id;
skill->get_inf2 = skill_get_inf2;
skill->get_castcancel = skill_get_castcancel;
@@ -17967,7 +17950,6 @@ void skill_defaults(void) {
skill->parse_row_castdb = skill_parse_row_castdb;
skill->parse_row_castnodexdb = skill_parse_row_castnodexdb;
skill->parse_row_unitdb = skill_parse_row_unitdb;
- skill->parse_row_nocastdb = skill_parse_row_nocastdb;
skill->parse_row_producedb = skill_parse_row_producedb;
skill->parse_row_createarrowdb = skill_parse_row_createarrowdb;
skill->parse_row_abradb = skill_parse_row_abradb;
diff --git a/src/map/skill.h b/src/map/skill.h
index be5f0a54f..3e2fc7936 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1732,7 +1732,6 @@ struct skill_interface {
int (*get_weapontype) ( uint16 skill_id );
int (*get_ammotype) ( uint16 skill_id );
int (*get_ammo_qty) ( uint16 skill_id, uint16 skill_lv );
- int (*get_nocast) ( uint16 skill_id );
int (*get_unit_id) (uint16 skill_id,int flag);
int (*get_inf2) ( uint16 skill_id );
int (*get_castcancel) ( uint16 skill_id );
@@ -1866,7 +1865,6 @@ struct skill_interface {
bool (*parse_row_castdb) (char* split[], int columns, int current);
bool (*parse_row_castnodexdb) (char* split[], int columns, int current);
bool (*parse_row_unitdb) (char* split[], int columns, int current);
- bool (*parse_row_nocastdb) (char* split[], int columns, int current);
bool (*parse_row_producedb) (char* split[], int columns, int current);
bool (*parse_row_createarrowdb) (char* split[], int columns, int current);
bool (*parse_row_abradb) (char* split[], int columns, int current);
diff --git a/src/map/status.c b/src/map/status.c
index 64f7f81af..f356e4aa5 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -2228,7 +2228,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
const struct status_change *sc = &sd->sc;
struct s_skill b_skill[MAX_SKILL]; // previous skill tree
int b_weight, b_max_weight, b_cart_weight_max, // previous weight
- i, index, skill,refinedef=0;
+ i, k, index, skill,refinedef=0;
int64 i64;
if (++calculating > 10) //Too many recursive calls!
@@ -2392,19 +2392,14 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if(!sd->inventory_data[index])
continue;
- if(sd->inventory_data[index]->flag.no_equip) { // Items may be equipped, their effects however are nullified.
- if(map[sd->bl.m].flag.restricted && sd->inventory_data[index]->flag.no_equip&(8*map[sd->bl.m].zone))
- continue;
- if(!map_flag_vs(sd->bl.m) && sd->inventory_data[index]->flag.no_equip&1)
- continue;
- if(map[sd->bl.m].flag.pvp && sd->inventory_data[index]->flag.no_equip&2)
- continue;
- if(map_flag_gvg(sd->bl.m) && sd->inventory_data[index]->flag.no_equip&4)
- continue;
- if(map[sd->bl.m].flag.battleground && sd->inventory_data[index]->flag.no_equip&8)
- continue;
+ for(k = 0; k < map[sd->bl.m].zone->disabled_items_count; k++) {
+ if( map[sd->bl.m].zone->disabled_items[k] == sd->inventory_data[index]->nameid ) {
+ break;
+ }
}
-
+
+ if( k < map[sd->bl.m].zone->disabled_items_count )
+ continue;
status->def += sd->inventory_data[index]->def;
@@ -2540,28 +2535,24 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
data = itemdb_exists(c);
if(!data)
continue;
- if(first && data->equip_script)
- { //Execute equip-script on login
+ if(first && data->equip_script) {//Execute equip-script on login
run_script(data->equip_script,0,sd->bl.id,0);
if (!calculating)
return 1;
}
if(!data->script)
continue;
- if(data->flag.no_equip) { //Card restriction checks.
- if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone))
- continue;
- if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1)
- continue;
- if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2)
- continue;
- if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4)
- continue;
- if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8)
- continue;
+
+ for(k = 0; k < map[sd->bl.m].zone->disabled_items_count; k++) {
+ if( map[sd->bl.m].zone->disabled_items[k] == sd->inventory_data[index]->nameid ) {
+ break;
+ }
}
- if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L)
- { //Left hand status.
+
+ if( k < map[sd->bl.m].zone->disabled_items_count )
+ continue;
+
+ if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { //Left hand status.
sd->state.lr_flag = 1;
run_script(data->script,0,sd->bl.id,0);
sd->state.lr_flag = 0;