summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/mapflag/zone.txt53
-rw-r--r--npc/guild2/agit_main_se.txt2
-rw-r--r--src/map/atcommand.c30
-rw-r--r--src/map/map.c792
-rw-r--r--src/map/map.h8
-rw-r--r--src/map/npc.c77
-rw-r--r--src/map/script.c10
7 files changed, 893 insertions, 79 deletions
diff --git a/conf/mapflag/zone.txt b/conf/mapflag/zone.txt
index ced22128a..62047effa 100644
--- a/conf/mapflag/zone.txt
+++ b/conf/mapflag/zone.txt
@@ -32,18 +32,6 @@ force_1-2 mapflag zone Izlude Battle Arena
force_1-3 mapflag zone Izlude Battle Arena
prt_are_in mapflag zone Izlude Battle Arena
-//WoE:SE Maps
-schg_cas01 mapflag zone GvG2
-schg_cas02 mapflag zone GvG2
-schg_cas03 mapflag zone GvG2
-schg_cas04 mapflag zone GvG2
-schg_cas05 mapflag zone GvG2
-arug_cas01 mapflag zone GvG2
-arug_cas02 mapflag zone GvG2
-arug_cas03 mapflag zone GvG2
-arug_cas04 mapflag zone GvG2
-arug_cas05 mapflag zone GvG2
-
//Sealed Shrine ==================
1@cata mapflag zone Sealed Shrine
2@cata mapflag zone Sealed Shrine
@@ -119,43 +107,4 @@ splendide mapflag zone Towns
umbala mapflag zone Towns
veins mapflag zone Towns
xmas mapflag zone Towns
-yuno mapflag zone Towns
-
-//Temporary Fix (the real deal is being designed)
-bat_c01 mapflag zone Battlegrounds
-bat_c02 mapflag zone Battlegrounds
-bat_c03 mapflag zone Battlegrounds
-bat_b01 mapflag zone Battlegrounds
-bat_b02 mapflag zone Battlegrounds
-bat_a01 mapflag zone Battlegrounds
-bat_a02 mapflag zone Battlegrounds
-aldeg_cas01 mapflag zone GvG
-aldeg_cas02 mapflag zone GvG
-aldeg_cas03 mapflag zone GvG
-aldeg_cas04 mapflag zone GvG
-aldeg_cas05 mapflag zone GvG
-gefg_cas01 mapflag zone GvG
-gefg_cas02 mapflag zone GvG
-gefg_cas03 mapflag zone GvG
-gefg_cas04 mapflag zone GvG
-gefg_cas05 mapflag zone GvG
-payg_cas01 mapflag zone GvG
-payg_cas02 mapflag zone GvG
-payg_cas03 mapflag zone GvG
-payg_cas04 mapflag zone GvG
-payg_cas05 mapflag zone GvG
-prtg_cas01 mapflag zone GvG
-prtg_cas02 mapflag zone GvG
-prtg_cas03 mapflag zone GvG
-prtg_cas04 mapflag zone GvG
-prtg_cas05 mapflag zone GvG
-schg_cas01 mapflag zone GvG2
-schg_cas02 mapflag zone GvG2
-schg_cas03 mapflag zone GvG2
-schg_cas04 mapflag zone GvG2
-schg_cas05 mapflag zone GvG2
-arug_cas01 mapflag zone GvG2
-arug_cas02 mapflag zone GvG2
-arug_cas03 mapflag zone GvG2
-arug_cas04 mapflag zone GvG2
-arug_cas05 mapflag zone GvG2
+yuno mapflag zone Towns \ No newline at end of file
diff --git a/npc/guild2/agit_main_se.txt b/npc/guild2/agit_main_se.txt
index 45c847d5d..cea4d2223 100644
--- a/npc/guild2/agit_main_se.txt
+++ b/npc/guild2/agit_main_se.txt
@@ -48,6 +48,7 @@ OnAgitStart2:
if (agitcheck2()) {
maprespawnguildid strnpcinfo(2),getcastledata(strnpcinfo(2),1),2;
gvgon strnpcinfo(2);
+ setmapflag strnpcinfo(2),mf_zone,"GvG2";
donpcevent strnpcinfo(0)+"::OnStart";
}
else for(set .@i,0; .@i<4; set .@i,.@i+1)
@@ -57,6 +58,7 @@ OnAgitStart2:
OnAgitEnd2:
if (strnpcinfo(2) == "template") end;
gvgoff strnpcinfo(2);
+ removemapflag strnpcinfo(2),mf_zone;
if (getcastledata(strnpcinfo(2),1)) {
set .@str$,substr(strnpcinfo(2),0,1)+substr(strnpcinfo(2),8,9);
killmonster strnpcinfo(2),"Steward#"+.@str$+"::OnStartArena";
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index f52e245ea..d9c01b0fb 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1531,6 +1531,7 @@ ACMD_FUNC(pvpoff)
return -1;
}
+ map_zone_change2(sd->bl.m,map[sd->bl.m].prev_zone);
map[sd->bl.m].flag.pvp = 0;
if (!battle_config.pk_mode)
@@ -1566,11 +1567,11 @@ ACMD_FUNC(pvpon)
clif->message(fd, msg_txt(161)); // PvP is already On.
return -1;
}
-
+
+ map_zone_change2(sd->bl.m,strdb_get(zone_db, MAP_ZONE_PVP_NAME));
map[sd->bl.m].flag.pvp = 1;
- if (!battle_config.pk_mode)
- {// display pvp circle and rank
+ if (!battle_config.pk_mode) {// display pvp circle and rank
clif->map_property_mapall(sd->bl.m, MAPPROPERTY_FREEPVPZONE);
map_foreachinmap(atcommand_pvpon_sub,sd->bl.m, BL_PC);
}
@@ -1592,6 +1593,7 @@ ACMD_FUNC(gvgoff)
return -1;
}
+ map_zone_change2(sd->bl.m,map[sd->bl.m].prev_zone);
map[sd->bl.m].flag.gvg = 0;
clif->map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0);
@@ -1611,7 +1613,8 @@ ACMD_FUNC(gvgon)
clif->message(fd, msg_txt(163)); // GvG is already On.
return -1;
}
-
+
+ map_zone_change2(sd->bl.m,strdb_get(zone_db, MAP_ZONE_GVG_NAME));
map[sd->bl.m].flag.gvg = 1;
clif->map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE);
clif->message(fd, msg_txt(34)); // GvG: On.
@@ -7668,6 +7671,23 @@ ACMD_FUNC(mapflag) {
}
for (i = 0; flag_name[i]; i++) flag_name[i] = (char)tolower(flag_name[i]); //lowercase
+ if ( strcmp( flag_name , "gvg" ) == 0 ) {
+ if( flag && !map[sd->bl.m].flag.gvg )
+ map_zone_change2(sd->bl.m,strdb_get(zone_db, MAP_ZONE_GVG_NAME));
+ else if ( !flag && map[sd->bl.m].flag.gvg )
+ map_zone_change2(sd->bl.m,map[sd->bl.m].prev_zone);
+ } else if ( strcmp( flag_name , "pvp" ) == 0 ) {
+ if( flag && !map[sd->bl.m].flag.pvp )
+ map_zone_change2(sd->bl.m,strdb_get(zone_db, MAP_ZONE_PVP_NAME));
+ else if ( !flag && map[sd->bl.m].flag.pvp )
+ map_zone_change2(sd->bl.m,map[sd->bl.m].prev_zone);
+ } else if ( strcmp( flag_name , "battleground" ) == 0 ) {
+ if( flag && !map[sd->bl.m].flag.battleground )
+ map_zone_change2(sd->bl.m,strdb_get(zone_db, MAP_ZONE_BG_NAME));
+ else if ( !flag && map[sd->bl.m].flag.battleground )
+ map_zone_change2(sd->bl.m,map[sd->bl.m].prev_zone);
+ }
+
setflag(autotrade); setflag(allowks); setflag(nomemo); setflag(noteleport);
setflag(noreturn); setflag(monster_noteleport);setflag(nosave); setflag(nobranch);
setflag(noexppenalty); setflag(pvp); setflag(pvp_noparty); setflag(pvp_noguild);
@@ -7680,7 +7700,7 @@ ACMD_FUNC(mapflag) {
setflag(nojobexp); setflag(nomobloot); setflag(nomvploot); setflag(nightenabled);
setflag(nodrop); setflag(novending); setflag(loadevent);
setflag(nochat); setflag(partylock); setflag(guildlock); setflag(src4instance);
-
+
clif->message(sd->fd,msg_txt(1314)); // Invalid flag name or flag.
clif->message(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
clif->message(sd->fd,msg_txt(1315)); // Available Flags:
diff --git a/src/map/map.c b/src/map/map.c
index 656ddb6d0..779070f0e 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1712,6 +1712,10 @@ int map_quit(struct map_session_data *sd) {
}
}
+ if( hChSys.local && map[sd->bl.m].channel && idb_exists(map[sd->bl.m].channel->users, sd->status.char_id) ) {
+ clif->chsys_left(map[sd->bl.m].channel,sd);
+ }
+
if( sd->channel_count ) {
for( i = 0; i < sd->channel_count; i++ ) {
if( sd->channels[i] != NULL )
@@ -2985,6 +2989,18 @@ void do_final_maps(void) {
}
map[i].skill_count = 0;
}
+
+ if( map[i].zone_mf_count ) {
+ for(v = 0; v < map[i].zone_mf_count; v++) {
+ aFree(map[i].zone_mf[v]);
+ }
+ if( map[i].zone_mf ) {
+ aFree(map[i].zone_mf);
+ map[i].zone_mf = NULL;
+ }
+ map[i].zone_mf_count = 0;
+ }
+
if( map[i].channel )
clif->chsys_delete(map[i].channel);
}
@@ -3031,6 +3047,17 @@ void map_flags_init(void) {
} else /* align with 'All' zone */
map[i].zone = &map_zone_all;
+ if( map[i].zone_mf_count ) {
+ for(v = 0; v < map[i].zone_mf_count; v++) {
+ aFree(map[i].zone_mf[v]);
+ }
+ aFree(map[i].zone_mf);
+ }
+
+ map[i].zone_mf = NULL;
+ map[i].zone_mf_count = 0;
+ map[i].prev_zone = map[i].zone;
+
map[i].invincible_time_inc = 0;
map[i].weapon_damage_rate = 100;
@@ -3598,12 +3625,759 @@ 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) {
+void map_zone_change2(int m, struct map_zone_data *zone) {
+ char empty[1] = "\0";
+
+ map[m].prev_zone = map[m].zone;
+
+ if( map[m].zone_mf_count )
+ map_zone_remove(m);
+
+ map_zone_apply(m,zone,empty,empty,empty);
+}
+/* when changing from a mapflag to another during runtime */
+void map_zone_change(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath) {
+ map[m].prev_zone = map[m].zone;
+
+ if( map[m].zone_mf_count )
+ map_zone_remove(m);
+ map_zone_apply(m,zone,start,buffer,filepath);
+}
+/* removes previous mapflags from this map */
+void map_zone_remove(int m) {
+ char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
+ unsigned short k;
+ char empty[1] = "\0";
+ for(k = 0; k < map[m].zone_mf_count; k++) {
+ int len = strlen(map[m].zone_mf[k]),j;
+ params[0] = '\0';
+ memcpy(flag, map[m].zone_mf[k], MAP_ZONE_MAPFLAG_LENGTH);
+ for(j = 0; j < len; j++) {
+ if( flag[j] == '\t' ) {
+ memcpy(params, &flag[j+1], len - j);
+ flag[j] = '\0';
+ break;
+ }
+ }
+
+ npc_parse_mapflag(map[m].name,empty,flag,params,empty,empty,empty);
+ aFree(map[m].zone_mf[k]);
+ map[m].zone_mf[k] = NULL;
+ }
+
+ aFree(map[m].zone_mf);
+ map[m].zone_mf = NULL;
+ map[m].zone_mf_count = 0;
+}
+static inline void map_zone_mf_cache_add(int m, char *rflag) {
+ RECREATE(map[m].zone_mf, char *, ++map[m].zone_mf_count);
+ CREATE(map[m].zone_mf[map[m].zone_mf_count - 1], char, MAP_ZONE_MAPFLAG_LENGTH);
+ safestrncpy(map[m].zone_mf[map[m].zone_mf_count - 1], rflag, MAP_ZONE_MAPFLAG_LENGTH);
+}
+/* TODO: introduce enumerations to each mapflag so instead of reading the string a number of times we read it only once and use its value wherever we need */
+/* cache previous values to revert */
+bool map_zone_mf_cache(int m, char *flag, char *params) {
+ char rflag[MAP_ZONE_MAPFLAG_LENGTH];
+ int state = 1;
+
+ if (params[0] != '\0' && !strcmpi(params, "off"))
+ state = 0;
+
+ if (!strcmpi(flag, "nosave")) {
+ ;/* not yet supported to be reversed */
+ /*
+ char savemap[32];
+ int savex, savey;
+ if (state == 0) {
+ if( map[m].flag.nosave ) {
+ sprintf(rflag, "nosave SavePoint");
+ map_zone_mf_cache_add(m,nosave);
+ }
+ } else if (!strcmpi(params, "SavePoint")) {
+ if( map[m].save.map ) {
+ sprintf(rflag, "nosave %s,%d,%d",mapindex_id2name(map[m].save.map),map[m].save.x,map[m].save.y);
+ } else
+ sprintf(rflag, "nosave %s,%d,%d",mapindex_id2name(map[m].save.map),map[m].save.x,map[m].save.y);
+ map_zone_mf_cache_add(m,nosave);
+ } else if (sscanf(params, "%31[^,],%d,%d", savemap, &savex, &savey) == 3) {
+ if( map[m].save.map ) {
+ sprintf(rflag, "nosave %s,%d,%d",mapindex_id2name(map[m].save.map),map[m].save.x,map[m].save.y);
+ map_zone_mf_cache_add(m,nosave);
+ }
+ }*/
+ } else if (!strcmpi(flag,"autotrade")) {
+ if( state && map[m].flag.autotrade )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"autotrade off");
+ else if( !map[m].flag.autotrade )
+ map_zone_mf_cache_add(m,"autotrade");
+ }
+ } else if (!strcmpi(flag,"allowks")) {
+ if( state && map[m].flag.allowks )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"allowks off");
+ else if( !map[m].flag.allowks )
+ map_zone_mf_cache_add(m,"allowks");
+ }
+ } else if (!strcmpi(flag,"town")) {
+ if( state && map[m].flag.town )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"town off");
+ else if( !map[m].flag.town )
+ map_zone_mf_cache_add(m,"town");
+ }
+ } else if (!strcmpi(flag,"nomemo")) {
+ if( state && map[m].flag.nomemo )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nomemo off");
+ else if( !map[m].flag.nomemo )
+ map_zone_mf_cache_add(m,"nomemo");
+ }
+ } else if (!strcmpi(flag,"noteleport")) {
+ if( state && map[m].flag.noteleport )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noteleport off");
+ else if( !map[m].flag.noteleport )
+ map_zone_mf_cache_add(m,"noteleport");
+ }
+ } else if (!strcmpi(flag,"nowarp")) {
+ if( state && map[m].flag.nowarp )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nowarp off");
+ else if( !map[m].flag.nowarp )
+ map_zone_mf_cache_add(m,"nowarp");
+ }
+ } else if (!strcmpi(flag,"nowarpto")) {
+ if( state && map[m].flag.nowarpto )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nowarpto off");
+ else if( !map[m].flag.nowarpto )
+ map_zone_mf_cache_add(m,"nowarpto");
+ }
+ } else if (!strcmpi(flag,"noreturn")) {
+ if( state && map[m].flag.noreturn )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noreturn off");
+ else if( map[m].flag.noreturn )
+ map_zone_mf_cache_add(m,"noreturn");
+ }
+ } else if (!strcmpi(flag,"monster_noteleport")) {
+ if( state && map[m].flag.monster_noteleport )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"monster_noteleport off");
+ else if( map[m].flag.monster_noteleport )
+ map_zone_mf_cache_add(m,"monster_noteleport");
+ }
+ } else if (!strcmpi(flag,"nobranch")) {
+ if( state && map[m].flag.nobranch )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nobranch off");
+ else if( map[m].flag.nobranch )
+ map_zone_mf_cache_add(m,"nobranch");
+ }
+ } else if (!strcmpi(flag,"nopenalty")) {
+ if( state && map[m].flag.noexppenalty ) /* they are applied together, no need to check both */
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nopenalty off");
+ else if( map[m].flag.noexppenalty )
+ map_zone_mf_cache_add(m,"nopenalty");
+ }
+ } else if (!strcmpi(flag,"pvp")) {
+ if( state && map[m].flag.pvp )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"pvp off");
+ else if( map[m].flag.pvp )
+ map_zone_mf_cache_add(m,"pvp");
+ }
+ }
+ else if (!strcmpi(flag,"pvp_noparty")) {
+ if( state && map[m].flag.pvp_noparty )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"pvp_noparty off");
+ else if( map[m].flag.pvp_noparty )
+ map_zone_mf_cache_add(m,"pvp_noparty");
+ }
+ } else if (!strcmpi(flag,"pvp_noguild")) {
+ if( state && map[m].flag.pvp_noguild )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"pvp_noguild off");
+ else if( map[m].flag.pvp_noguild )
+ map_zone_mf_cache_add(m,"pvp_noguild");
+ }
+ } else if (!strcmpi(flag, "pvp_nightmaredrop")) {
+ if( state && map[m].flag.pvp_nightmaredrop )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"pvp_nightmaredrop off");
+ else if( map[m].flag.pvp_nightmaredrop )
+ map_zone_mf_cache_add(m,"pvp_nightmaredrop");
+ }
+ /* not yet fully supported */
+ /*char drop_arg1[16], drop_arg2[16];
+ int drop_per = 0;
+ if (sscanf(w4, "%[^,],%[^,],%d", drop_arg1, drop_arg2, &drop_per) == 3) {
+ int drop_id = 0, drop_type = 0;
+ if (!strcmpi(drop_arg1, "random"))
+ drop_id = -1;
+ else if (itemdb_exists((drop_id = atoi(drop_arg1))) == NULL)
+ drop_id = 0;
+ if (!strcmpi(drop_arg2, "inventory"))
+ drop_type = 1;
+ else if (!strcmpi(drop_arg2,"equip"))
+ drop_type = 2;
+ else if (!strcmpi(drop_arg2,"all"))
+ drop_type = 3;
+
+ if (drop_id != 0){
+ int i;
+ for (i = 0; i < MAX_DROP_PER_MAP; i++) {
+ if (map[m].drop_list[i].drop_id == 0){
+ map[m].drop_list[i].drop_id = drop_id;
+ map[m].drop_list[i].drop_type = drop_type;
+ map[m].drop_list[i].drop_per = drop_per;
+ break;
+ }
+ }
+ map[m].flag.pvp_nightmaredrop = 1;
+ }
+ } else if (!state) //Disable
+ map[m].flag.pvp_nightmaredrop = 0;
+ */
+ } else if (!strcmpi(flag,"pvp_nocalcrank")) {
+ if( state && map[m].flag.pvp_nocalcrank )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"pvp_nocalcrank off");
+ else if( map[m].flag.pvp_nocalcrank )
+ map_zone_mf_cache_add(m,"pvp_nocalcrank");
+ }
+ } else if (!strcmpi(flag,"gvg")) {
+ if( state && map[m].flag.gvg )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"gvg off");
+ else if( map[m].flag.gvg )
+ map_zone_mf_cache_add(m,"gvg");
+ }
+ } else if (!strcmpi(flag,"gvg_noparty")) {
+ if( state && map[m].flag.gvg_noparty )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"gvg_noparty off");
+ else if( map[m].flag.gvg_noparty )
+ map_zone_mf_cache_add(m,"gvg_noparty");
+ }
+ } else if (!strcmpi(flag,"gvg_dungeon")) {
+ if( state && map[m].flag.gvg_dungeon )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"gvg_dungeon off");
+ else if( map[m].flag.gvg_dungeon )
+ map_zone_mf_cache_add(m,"gvg_dungeon");
+ }
+ }
+ else if (!strcmpi(flag,"gvg_castle")) {
+ if( state && map[m].flag.gvg_castle )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"gvg_castle off");
+ else if( map[m].flag.gvg_castle )
+ map_zone_mf_cache_add(m,"gvg_castle");
+ }
+ }
+ else if (!strcmpi(flag,"battleground")) {
+ if( state && map[m].flag.battleground )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"battleground off");
+ else if( map[m].flag.battleground )
+ map_zone_mf_cache_add(m,"battleground");
+ }
+ } else if (!strcmpi(flag,"noexppenalty")) {
+ if( state && map[m].flag.noexppenalty )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noexppenalty off");
+ else if( map[m].flag.noexppenalty )
+ map_zone_mf_cache_add(m,"noexppenalty");
+ }
+ } else if (!strcmpi(flag,"nozenypenalty")) {
+ if( state && map[m].flag.nozenypenalty )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nozenypenalty off");
+ else if( map[m].flag.nozenypenalty )
+ map_zone_mf_cache_add(m,"nozenypenalty");
+ }
+ } else if (!strcmpi(flag,"notrade")) {
+ if( state && map[m].flag.notrade )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"notrade off");
+ else if( map[m].flag.notrade )
+ map_zone_mf_cache_add(m,"notrade");
+ }
+ } else if (!strcmpi(flag,"novending")) {
+ if( state && map[m].flag.novending )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"novending off");
+ else if( map[m].flag.novending )
+ map_zone_mf_cache_add(m,"novending");
+ }
+ } else if (!strcmpi(flag,"nodrop")) {
+ if( state && map[m].flag.nodrop )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nodrop off");
+ else if( map[m].flag.nodrop )
+ map_zone_mf_cache_add(m,"nodrop");
+ }
+ } else if (!strcmpi(flag,"noskill")) {
+ if( state && map[m].flag.noskill )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noskill off");
+ else if( map[m].flag.noskill )
+ map_zone_mf_cache_add(m,"noskill");
+ }
+ } else if (!strcmpi(flag,"noicewall")) {
+ if( state && map[m].flag.noicewall )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noicewall off");
+ else if( map[m].flag.noicewall )
+ map_zone_mf_cache_add(m,"noicewall");
+ }
+ } else if (!strcmpi(flag,"snow")) {
+ if( state && map[m].flag.snow )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"snow off");
+ else if( map[m].flag.snow )
+ map_zone_mf_cache_add(m,"snow");
+ }
+ } else if (!strcmpi(flag,"clouds")) {
+ if( state && map[m].flag.clouds )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"clouds off");
+ else if( map[m].flag.clouds )
+ map_zone_mf_cache_add(m,"clouds");
+ }
+ } else if (!strcmpi(flag,"clouds2")) {
+ if( state && map[m].flag.clouds2 )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"clouds2 off");
+ else if( map[m].flag.clouds2 )
+ map_zone_mf_cache_add(m,"clouds2");
+ }
+ } else if (!strcmpi(flag,"fog")) {
+ if( state && map[m].flag.fog )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"fog off");
+ else if( map[m].flag.fog )
+ map_zone_mf_cache_add(m,"fog");
+ }
+ } else if (!strcmpi(flag,"fireworks")) {
+ if( state && map[m].flag.fireworks )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"fireworks off");
+ else if( map[m].flag.fireworks )
+ map_zone_mf_cache_add(m,"fireworks");
+ }
+ } else if (!strcmpi(flag,"sakura")) {
+ if( state && map[m].flag.sakura )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"sakura off");
+ else if( map[m].flag.sakura )
+ map_zone_mf_cache_add(m,"sakura");
+ }
+ } else if (!strcmpi(flag,"leaves")) {
+ if( state && map[m].flag.leaves )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"leaves off");
+ else if( map[m].flag.leaves )
+ map_zone_mf_cache_add(m,"leaves");
+ }
+ } else if (!strcmpi(flag,"nightenabled")) {
+ if( state && map[m].flag.nightenabled )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nightenabled off");
+ else if( map[m].flag.nightenabled )
+ map_zone_mf_cache_add(m,"nightenabled");
+ }
+ } else if (!strcmpi(flag,"nogo")) {
+ if( state && map[m].flag.nogo )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nogo off");
+ else if( map[m].flag.nogo )
+ map_zone_mf_cache_add(m,"nogo");
+ }
+ } else if (!strcmpi(flag,"noexp")) {
+ if( state && map[m].flag.nobaseexp )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noexp off");
+ else if( map[m].flag.nobaseexp )
+ map_zone_mf_cache_add(m,"noexp");
+ }
+ }
+ else if (!strcmpi(flag,"nobaseexp")) {
+ if( state && map[m].flag.nobaseexp )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nobaseexp off");
+ else if( map[m].flag.nobaseexp )
+ map_zone_mf_cache_add(m,"nobaseexp");
+ }
+ } else if (!strcmpi(flag,"nojobexp")) {
+ if( state && map[m].flag.nojobexp )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nojobexp off");
+ else if( map[m].flag.nojobexp )
+ map_zone_mf_cache_add(m,"nojobexp");
+ }
+ } else if (!strcmpi(flag,"noloot")) {
+ if( state && map[m].flag.nomobloot )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noloot off");
+ else if( map[m].flag.nomobloot )
+ map_zone_mf_cache_add(m,"noloot");
+ }
+ } else if (!strcmpi(flag,"nomobloot")) {
+ if( state && map[m].flag.nomobloot )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nomobloot off");
+ else if( map[m].flag.nomobloot )
+ map_zone_mf_cache_add(m,"nomobloot");
+ }
+ } else if (!strcmpi(flag,"nomvploot")) {
+ if( state && map[m].flag.nomvploot )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nomvploot off");
+ else if( map[m].flag.nomvploot )
+ map_zone_mf_cache_add(m,"nomvploot");
+ }
+ } else if (!strcmpi(flag,"nocommand")) {
+ /* implementation may be incomplete */
+ if( state && sscanf(params, "%d", &state) == 1 ) {
+ sprintf(rflag, "nocommand %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ } else if( !state && map[m].nocommand ) {
+ sprintf(rflag, "nocommand %d",map[m].nocommand);
+ map_zone_mf_cache_add(m,rflag);
+ } else if( map[m].nocommand ) {
+ map_zone_mf_cache_add(m,"nocommand off");
+ }
+ } else if (!strcmpi(flag,"jexp")) {
+ if( !state ) {
+ if( map[m].jexp != 100 ) {
+ sprintf(rflag,"jexp %d",map[m].jexp);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].jexp ) {
+ sprintf(rflag,"jexp %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if (!strcmpi(flag,"bexp")) {
+ if( !state ) {
+ if( map[m].bexp != 100 ) {
+ sprintf(rflag,"bexp %d",map[m].jexp);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].bexp ) {
+ sprintf(rflag,"bexp %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if (!strcmpi(flag,"loadevent")) {
+ if( state && map[m].flag.loadevent )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"loadevent off");
+ else if( map[m].flag.loadevent )
+ map_zone_mf_cache_add(m,"loadevent");
+ }
+ } else if (!strcmpi(flag,"nochat")) {
+ if( state && map[m].flag.nochat )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nochat off");
+ else if( map[m].flag.nochat )
+ map_zone_mf_cache_add(m,"nochat");
+ }
+ } else if (!strcmpi(flag,"partylock")) {
+ if( state && map[m].flag.partylock )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"partylock off");
+ else if( map[m].flag.partylock )
+ map_zone_mf_cache_add(m,"partylock");
+ }
+ } else if (!strcmpi(flag,"guildlock")) {
+ if( state && map[m].flag.guildlock )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"guildlock off");
+ else if( map[m].flag.guildlock )
+ map_zone_mf_cache_add(m,"guildlock");
+ }
+ } else if (!strcmpi(flag,"reset")) {
+ if( state && map[m].flag.reset )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"reset off");
+ else if( map[m].flag.reset )
+ map_zone_mf_cache_add(m,"reset");
+ }
+ } else if (!strcmpi(flag,"adjust_unit_duration")) {
+ int skill_id, k;
+ char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH];
+ int len = strlen(params);
+
+ modifier[0] = '\0';
+ memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH);
+
+ for(k = 0; k < len; k++) {
+ if( skill_name[k] == '\t' ) {
+ memcpy(modifier, &skill_name[k+1], len - k);
+ skill_name[k] = '\0';
+ break;
+ }
+ }
+
+ if( modifier[0] == '\0' || !( skill_id = skill->name2id(skill_name) ) || !skill->get_unit_id( skill->name2id(skill_name), 0) || atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) {
+ ;/* we dont mind it, the server will take care of it next. */
+ } else {
+ int idx = map[m].unit_count;
+
+ k = 0;
+ ARR_FIND(0, idx, k, map[m].units[k]->skill_id == skill_id);
+
+ if( k < idx ) {
+ if( atoi(modifier) != map[m].units[k]->modifier ) {
+ sprintf(rflag,"adjust_unit_duration %s %d",skill_name,map[m].units[k]->modifier);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } else {
+ sprintf(rflag,"adjust_unit_duration %s 100",skill_name);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if (!strcmpi(flag,"adjust_skill_damage")) {
+ int skill_id, k;
+ char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH];
+ int len = strlen(params);
+
+ modifier[0] = '\0';
+ memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH);
+
+ for(k = 0; k < len; k++) {
+ if( skill_name[k] == '\t' ) {
+ memcpy(modifier, &skill_name[k+1], len - k);
+ skill_name[k] = '\0';
+ break;
+ }
+ }
+
+ if( modifier[0] == '\0' || !( skill_id = skill->name2id(skill_name) ) || atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) {
+ ;/* we dont mind it, the server will take care of it next. */
+ } else {
+ int idx = map[m].skill_count;
+
+ k = 0;
+ ARR_FIND(0, idx, k, map[m].skills[k]->skill_id == skill_id);
+
+ if( k < idx ) {
+ if( atoi(modifier) != map[m].skills[k]->modifier ) {
+ sprintf(rflag,"adjust_skill_damage %s %d",skill_name,map[m].skills[k]->modifier);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } else {
+ sprintf(rflag,"adjust_skill_damage %s 100",skill_name);
+ map_zone_mf_cache_add(m,rflag);
+ }
+
+ }
+ } else if (!strcmpi(flag,"zone")) {
+ ShowWarning("You can't add a zone through a zone! ERROR, skipping for '%s'...\n",map[m].name);
+ return true;
+ } else if ( !strcmpi(flag,"nomapchannelautojoin") ) {
+ if( state && map[m].flag.chsysnolocalaj )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nomapchannelautojoin off");
+ else if( map[m].flag.chsysnolocalaj )
+ map_zone_mf_cache_add(m,"nomapchannelautojoin");
+ }
+ } else if ( !strcmpi(flag,"invincible_time_inc") ) {
+ if( !state ) {
+ if( map[m].invincible_time_inc != 0 ) {
+ sprintf(rflag,"invincible_time_inc %d",map[m].invincible_time_inc);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].invincible_time_inc ) {
+ sprintf(rflag,"invincible_time_inc %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if ( !strcmpi(flag,"noknockback") ) {
+ if( state && map[m].flag.noknockback )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"noknockback off");
+ else if( map[m].flag.noknockback )
+ map_zone_mf_cache_add(m,"noknockback");
+ }
+ } else if ( !strcmpi(flag,"weapon_damage_rate") ) {
+ if( !state ) {
+ if( map[m].weapon_damage_rate != 100 ) {
+ sprintf(rflag,"weapon_damage_rate %d",map[m].weapon_damage_rate);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].weapon_damage_rate ) {
+ sprintf(rflag,"weapon_damage_rate %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if ( !strcmpi(flag,"magic_damage_rate") ) {
+ if( !state ) {
+ if( map[m].magic_damage_rate != 100 ) {
+ sprintf(rflag,"magic_damage_rate %d",map[m].magic_damage_rate);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].magic_damage_rate ) {
+ sprintf(rflag,"magic_damage_rate %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if ( !strcmpi(flag,"misc_damage_rate") ) {
+ if( !state ) {
+ if( map[m].misc_damage_rate != 100 ) {
+ sprintf(rflag,"misc_damage_rate %d",map[m].misc_damage_rate);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].misc_damage_rate ) {
+ sprintf(rflag,"misc_damage_rate %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if ( !strcmpi(flag,"short_damage_rate") ) {
+ if( !state ) {
+ if( map[m].short_damage_rate != 100 ) {
+ sprintf(rflag,"short_damage_rate %d",map[m].short_damage_rate);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].short_damage_rate ) {
+ sprintf(rflag,"short_damage_rate %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ } else if ( !strcmpi(flag,"long_damage_rate") ) {
+ if( !state ) {
+ if( map[m].long_damage_rate != 100 ) {
+ sprintf(rflag,"long_damage_rate %d",map[m].long_damage_rate);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ } if( sscanf(params, "%d", &state) == 1 ) {
+ if( state != map[m].long_damage_rate ) {
+ sprintf(rflag,"long_damage_rate %s",params);
+ map_zone_mf_cache_add(m,rflag);
+ }
+ }
+ }
+ return false;
+}
+void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath) {
int i;
char empty[1] = "\0";
+ char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
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';
@@ -3615,11 +4389,16 @@ void map_zone_apply(int m, struct map_zone_data *zone,char* w1, const char* star
break;
}
}
- npc_parse_mapflag(w1,empty,flag,params,start,buffer,filepath);
+
+ if( map_zone_mf_cache(m,flag,params) )
+ continue;
+
+ npc_parse_mapflag(map[m].name,empty,flag,params,start,buffer,filepath);
}
}
/* used on npc load and reload to apply all "Normal" and "PK Mode" zones */
void map_zone_init(void) {
+ char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
struct map_zone_data *zone;
char empty[1] = "\0";
int i,k,j;
@@ -3627,7 +4406,6 @@ void map_zone_init(void) {
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);
@@ -3638,8 +4416,11 @@ void map_zone_init(void) {
break;
}
}
+
for(j = 0; j < map_num; j++) {
if( map[j].zone == zone ) {
+ if( map_zone_mf_cache(j,flag,params) )
+ break;
npc_parse_mapflag(map[j].name,empty,flag,params,empty,empty,empty);
}
}
@@ -3648,7 +4429,6 @@ void map_zone_init(void) {
if( battle_config.pk_mode ) {
zone = &map_zone_pk;
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);
@@ -3661,6 +4441,8 @@ void map_zone_init(void) {
}
for(j = 0; j < map_num; j++) {
if( map[j].zone == zone ) {
+ if( map_zone_mf_cache(j,flag,params) )
+ break;
npc_parse_mapflag(map[j].name,empty,flag,params,empty,empty,empty);
}
}
diff --git a/src/map/map.h b/src/map/map.h
index 6f1a51e9f..dd0a47aaf 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -520,7 +520,10 @@ struct map_zone_data {
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);
+void map_zone_remove(int m);
+void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath);
+void map_zone_change(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath);
+void map_zone_change2(int m, struct map_zone_data *zone);
struct map_zone_data map_zone_all;/* used as a base on all maps */
struct map_zone_data map_zone_pk;/* used for (pk_mode) */
@@ -624,6 +627,9 @@ struct map_data {
/* Hercules nocast db overhaul */
struct map_zone_data *zone;
+ char **zone_mf;/* used to store this map's zone mapflags that should be re-applied once zone is removed */
+ unsigned short zone_mf_count;
+ struct map_zone_data *prev_zone;
/* Hercules Local Chat */
struct hChSysCh *channel;
diff --git a/src/map/npc.c b/src/map/npc.c
index b16c8b13c..aa44d8840 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -3242,7 +3242,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
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( state && (zone = strdb_get(zone_db, MAP_ZONE_PVP_NAME)) && map[m].zone != zone ) {
- map_zone_apply(m,zone,w1,start,buffer,filepath);
+ map_zone_change(m,zone,start,buffer,filepath);
} else if ( !state ) {
map[m].zone = &map_zone_pk;
}
@@ -3297,7 +3297,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
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( state && (zone = strdb_get(zone_db, MAP_ZONE_GVG_NAME)) && map[m].zone != zone ) {
- map_zone_apply(m,zone,w1,start,buffer,filepath);
+ map_zone_change(m,zone,start,buffer,filepath);
}
}
else if (!strcmpi(w3,"gvg_noparty"))
@@ -3332,7 +3332,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
}
if( state && (zone = strdb_get(zone_db, MAP_ZONE_BG_NAME)) && map[m].zone != zone ) {
- map_zone_apply(m,zone,w1,start,buffer,filepath);
+ map_zone_change(m,zone,start,buffer,filepath);
}
}
else if (!strcmpi(w3,"noexppenalty"))
@@ -3436,10 +3436,35 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
ShowWarning("npc_parse_mapflag: Invalid modifier '%d' for skill '%s' for 'adjust_unit_duration' flag! removing flag from %s (file '%s', line '%d').\n", atoi(modifier), skill_name, map[m].name, filepath, strline(buffer,start-buffer));
} else {
int idx = map[m].unit_count;
- RECREATE(map[m].units, struct mapflag_skill_adjust*, ++map[m].unit_count);
- CREATE(map[m].units[idx],struct mapflag_skill_adjust,1);
- map[m].units[idx]->skill_id = (unsigned short)skill_id;
- map[m].units[idx]->modifier = (unsigned short)atoi(modifier);
+
+ ARR_FIND(0, idx, k, map[m].units[k]->skill_id == skill_id);
+
+ if( k < idx ) {
+ if( atoi(modifier) != 100 )
+ map[m].units[k]->modifier = (unsigned short)atoi(modifier);
+ else { /* remove */
+ int cursor = 0;
+ aFree(map[m].units[k]);
+ map[m].units[k] = NULL;
+ for( k = 0; k < idx; k++ ) {
+ if( map[m].units[k] == NULL )
+ continue;
+
+ memmove(&map[m].units[cursor], &map[m].units[k], sizeof(struct mapflag_skill_adjust));
+
+ cursor++;
+ }
+ if( !( map[m].unit_count = cursor ) ) {
+ aFree(map[m].units);
+ map[m].units = NULL;
+ }
+ }
+ } else if( atoi(modifier) != 100 ) {
+ RECREATE(map[m].units, struct mapflag_skill_adjust*, ++map[m].unit_count);
+ CREATE(map[m].units[idx],struct mapflag_skill_adjust,1);
+ map[m].units[idx]->skill_id = (unsigned short)skill_id;
+ map[m].units[idx]->modifier = (unsigned short)atoi(modifier);
+ }
}
} else if (!strcmpi(w3,"adjust_skill_damage")) {
int skill_id, k;
@@ -3465,18 +3490,44 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
ShowWarning("npc_parse_mapflag: Invalid modifier '%d' for skill '%s' for 'adjust_skill_damage' flag! removing flag from %s (file '%s', line '%d').\n", atoi(modifier), skill_name, map[m].name, filepath, strline(buffer,start-buffer));
} else {
int idx = map[m].skill_count;
- RECREATE(map[m].skills, struct mapflag_skill_adjust*, ++map[m].skill_count);
- CREATE(map[m].skills[idx],struct mapflag_skill_adjust,1);
- map[m].skills[idx]->skill_id = (unsigned short)skill_id;
- map[m].skills[idx]->modifier = (unsigned short)atoi(modifier);
+
+ ARR_FIND(0, idx, k, map[m].skills[k]->skill_id == skill_id);
+
+ if( k < idx ) {
+ if( atoi(modifier) != 100 )
+ map[m].skills[k]->modifier = (unsigned short)atoi(modifier);
+ else { /* remove */
+ int cursor = 0;
+ aFree(map[m].skills[k]);
+ map[m].skills[k] = NULL;
+ for( k = 0; k < idx; k++ ) {
+ if( map[m].skills[k] == NULL )
+ continue;
+
+ memmove(&map[m].skills[cursor], &map[m].skills[k], sizeof(struct mapflag_skill_adjust));
+
+ cursor++;
+ }
+ if( !( map[m].skill_count = cursor ) ) {
+ aFree(map[m].skills);
+ map[m].skills = NULL;
+ }
+ }
+ } else if( atoi(modifier) != 100 ) {
+ RECREATE(map[m].skills, struct mapflag_skill_adjust*, ++map[m].skill_count);
+ CREATE(map[m].skills[idx],struct mapflag_skill_adjust,1);
+ map[m].skills[idx]->skill_id = (unsigned short)skill_id;
+ map[m].skills[idx]->modifier = (unsigned short)atoi(modifier);
+ }
+
}
} 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 if( map[m].zone != zone ) {
+ map_zone_change(m,zone,start,buffer,filepath);
}
} else if ( !strcmpi(w3,"nomapchannelautojoin") ) {
map[m].flag.chsysnolocalaj = state;
diff --git a/src/map/script.c b/src/map/script.c
index 5b076aeff..3e51859d1 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -10906,8 +10906,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_ZONE:/* reset zone state, mapflags cant be removed however */
- map[m].zone = ( battle_config.pk_mode && map[m].flag.pvp ) ? &map_zone_pk : &map_zone_all;
+ case MF_ZONE:
+ map_zone_change2(m, map[m].prev_zone);
break;
case MF_NOCOMMAND: map[m].nocommand = 0; break;
case MF_NODROP: map[m].flag.nodrop = 0; break;
@@ -10943,6 +10943,7 @@ BUILDIN_FUNC(pvpon)
if( m < 0 || map[m].flag.pvp )
return 0; // nothing to do
+ map_zone_change2(m, strdb_get(zone_db, MAP_ZONE_PVP_NAME));
map[m].flag.pvp = 1;
clif->map_property_mapall(m, MAPPROPERTY_FREEPVPZONE);
@@ -10987,7 +10988,8 @@ BUILDIN_FUNC(pvpoff)
m = map_mapname2mapid(str);
if(m < 0 || !map[m].flag.pvp)
return 0; //fixed Lupus
-
+
+ map_zone_change2(m, map[m].prev_zone);
map[m].flag.pvp = 0;
clif->map_property_mapall(m, MAPPROPERTY_NOTHING);
@@ -11006,6 +11008,7 @@ BUILDIN_FUNC(gvgon)
str=script_getstr(st,2);
m = map_mapname2mapid(str);
if(m >= 0 && !map[m].flag.gvg) {
+ map_zone_change2(m, strdb_get(zone_db, MAP_ZONE_GVG_NAME));
map[m].flag.gvg = 1;
clif->map_property_mapall(m, MAPPROPERTY_AGITZONE);
}
@@ -11020,6 +11023,7 @@ BUILDIN_FUNC(gvgoff)
str=script_getstr(st,2);
m = map_mapname2mapid(str);
if(m >= 0 && map[m].flag.gvg) {
+ map_zone_change2(m, map[m].prev_zone);
map[m].flag.gvg = 0;
clif->map_property_mapall(m, MAPPROPERTY_NOTHING);
}