Skip to content
Permalink
Browse files
Added skill_duration mapflag. (#2171)
* Added skill_duration mapflag.
* This mapflag sets a skill unit time limit to n% of original duration.
* Implemented mapflags for Hunter's Traps in GVG, BG, and Novice Guild maps.

Signed-off-by: Cydh Ramdh <cydh@pservero.com>
  • Loading branch information
secretdataz authored and aleos89 committed Oct 26, 2018
1 parent 2140722 commit 84b4f0987460de02de1b085181819381522480cb
@@ -1060,7 +1060,10 @@
1050: Other Flags:
1051: Other Flags2:
1052: Skill Damage Adjustments:
//1053-1064 free
1053: > [Map] %d%%, %d%%, %d%%, %d%% | Caster:%d
1054: > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster
1055: Skill Duration Adjustments:
//1056-1064 free
1065: No Exp Penalty: %s | No Zeny Penalty: %s
1066: On
1067: Off
@@ -321,6 +321,16 @@ This mapflag can also be used to adjust the damage of one skill by a percentage:

---------------------------------------

*skill_duration skill_name,percentage

Sets skill (trap-type) time limit to n% of original duration.

// Example:
// Makes HT_ANKLESNARE's lifetime in the castle 4x longer than other maps.
prtg_cas01 mapflag skill_duration HT_ANKLESNARE,400

---------------------------------------

==================
| 3. Map Effects |
==================
@@ -7121,6 +7121,9 @@ For 'skill_damage' mapflag:
- Setting the flag here will adjust the global (all skills) damage on the map.
- <zone> is the -100 to 100000 damage adjustment value of the skills.
- See 'getmapflag' for the different <type> values.
For 'skill_duration' mapflag:
- <zone> is the skill ID to adjust.
- <type> is the percentage of adjustment from 0 to 100000.

---------------------------------------

Large diffs are not rendered by default.

@@ -0,0 +1,121 @@
//===== rAthena Mapflag ======================================
//= Sets skill time limit on specified map.
//===== Structure ============================================
//= mapname skill_duration skill_name,percentage
//============================================================

//============================================================
// Gloria Castles
//============================================================
te_prtcas01 mapflag skill_duration HT_SKIDTRAP,400
te_prtcas01 mapflag skill_duration HT_LANDMINE,400
te_prtcas01 mapflag skill_duration HT_ANKLESNARE,400
te_prtcas01 mapflag skill_duration HT_SHOCKWAVE,400
te_prtcas01 mapflag skill_duration HT_SANDMAN,400
te_prtcas01 mapflag skill_duration HT_FLASHER,400
te_prtcas01 mapflag skill_duration HT_FREEZINGTRAP,400
te_prtcas01 mapflag skill_duration HT_BLASTMINE,400
te_prtcas01 mapflag skill_duration HT_CLAYMORETRAP,400
te_prtcas01 mapflag skill_duration HT_TALKIEBOX,400

te_prtcas02 mapflag skill_duration HT_SKIDTRAP,400
te_prtcas02 mapflag skill_duration HT_LANDMINE,400
te_prtcas02 mapflag skill_duration HT_ANKLESNARE,400
te_prtcas02 mapflag skill_duration HT_SHOCKWAVE,400
te_prtcas02 mapflag skill_duration HT_SANDMAN,400
te_prtcas02 mapflag skill_duration HT_FLASHER,400
te_prtcas02 mapflag skill_duration HT_FREEZINGTRAP,400
te_prtcas02 mapflag skill_duration HT_BLASTMINE,400
te_prtcas02 mapflag skill_duration HT_CLAYMORETRAP,400
te_prtcas02 mapflag skill_duration HT_TALKIEBOX,400

te_prtcas03 mapflag skill_duration HT_SKIDTRAP,400
te_prtcas03 mapflag skill_duration HT_LANDMINE,400
te_prtcas03 mapflag skill_duration HT_ANKLESNARE,400
te_prtcas03 mapflag skill_duration HT_SHOCKWAVE,400
te_prtcas03 mapflag skill_duration HT_SANDMAN,400
te_prtcas03 mapflag skill_duration HT_FLASHER,400
te_prtcas03 mapflag skill_duration HT_FREEZINGTRAP,400
te_prtcas03 mapflag skill_duration HT_BLASTMINE,400
te_prtcas03 mapflag skill_duration HT_CLAYMORETRAP,400
te_prtcas03 mapflag skill_duration HT_TALKIEBOX,400

te_prtcas04 mapflag skill_duration HT_SKIDTRAP,400
te_prtcas04 mapflag skill_duration HT_LANDMINE,400
te_prtcas04 mapflag skill_duration HT_ANKLESNARE,400
te_prtcas04 mapflag skill_duration HT_SHOCKWAVE,400
te_prtcas04 mapflag skill_duration HT_SANDMAN,400
te_prtcas04 mapflag skill_duration HT_FLASHER,400
te_prtcas04 mapflag skill_duration HT_FREEZINGTRAP,400
te_prtcas04 mapflag skill_duration HT_BLASTMINE,400
te_prtcas04 mapflag skill_duration HT_CLAYMORETRAP,400
te_prtcas04 mapflag skill_duration HT_TALKIEBOX,400

te_prtcas05 mapflag skill_duration HT_SKIDTRAP,400
te_prtcas05 mapflag skill_duration HT_LANDMINE,400
te_prtcas05 mapflag skill_duration HT_ANKLESNARE,400
te_prtcas05 mapflag skill_duration HT_SHOCKWAVE,400
te_prtcas05 mapflag skill_duration HT_SANDMAN,400
te_prtcas05 mapflag skill_duration HT_FLASHER,400
te_prtcas05 mapflag skill_duration HT_FREEZINGTRAP,400
te_prtcas05 mapflag skill_duration HT_BLASTMINE,400
te_prtcas05 mapflag skill_duration HT_CLAYMORETRAP,400
te_prtcas05 mapflag skill_duration HT_TALKIEBOX,400

//============================================================
// Kafragaten Castles
//============================================================
te_aldecas1 mapflag skill_duration HT_SKIDTRAP,400
te_aldecas1 mapflag skill_duration HT_LANDMINE,400
te_aldecas1 mapflag skill_duration HT_ANKLESNARE,400
te_aldecas1 mapflag skill_duration HT_SHOCKWAVE,400
te_aldecas1 mapflag skill_duration HT_SANDMAN,400
te_aldecas1 mapflag skill_duration HT_FLASHER,400
te_aldecas1 mapflag skill_duration HT_FREEZINGTRAP,400
te_aldecas1 mapflag skill_duration HT_BLASTMINE,400
te_aldecas1 mapflag skill_duration HT_CLAYMORETRAP,400
te_aldecas1 mapflag skill_duration HT_TALKIEBOX,400

te_aldecas2 mapflag skill_duration HT_SKIDTRAP,400
te_aldecas2 mapflag skill_duration HT_LANDMINE,400
te_aldecas2 mapflag skill_duration HT_ANKLESNARE,400
te_aldecas2 mapflag skill_duration HT_SHOCKWAVE,400
te_aldecas2 mapflag skill_duration HT_SANDMAN,400
te_aldecas2 mapflag skill_duration HT_FLASHER,400
te_aldecas2 mapflag skill_duration HT_FREEZINGTRAP,400
te_aldecas2 mapflag skill_duration HT_BLASTMINE,400
te_aldecas2 mapflag skill_duration HT_CLAYMORETRAP,400
te_aldecas2 mapflag skill_duration HT_TALKIEBOX,400

te_aldecas3 mapflag skill_duration HT_SKIDTRAP,400
te_aldecas3 mapflag skill_duration HT_LANDMINE,400
te_aldecas3 mapflag skill_duration HT_ANKLESNARE,400
te_aldecas3 mapflag skill_duration HT_SHOCKWAVE,400
te_aldecas3 mapflag skill_duration HT_SANDMAN,400
te_aldecas3 mapflag skill_duration HT_FLASHER,400
te_aldecas3 mapflag skill_duration HT_FREEZINGTRAP,400
te_aldecas3 mapflag skill_duration HT_BLASTMINE,400
te_aldecas3 mapflag skill_duration HT_CLAYMORETRAP,400
te_aldecas3 mapflag skill_duration HT_TALKIEBOX,400

te_aldecas4 mapflag skill_duration HT_SKIDTRAP,400
te_aldecas4 mapflag skill_duration HT_LANDMINE,400
te_aldecas4 mapflag skill_duration HT_ANKLESNARE,400
te_aldecas4 mapflag skill_duration HT_SHOCKWAVE,400
te_aldecas4 mapflag skill_duration HT_SANDMAN,400
te_aldecas4 mapflag skill_duration HT_FLASHER,400
te_aldecas4 mapflag skill_duration HT_FREEZINGTRAP,400
te_aldecas4 mapflag skill_duration HT_BLASTMINE,400
te_aldecas4 mapflag skill_duration HT_CLAYMORETRAP,400
te_aldecas4 mapflag skill_duration HT_TALKIEBOX,400

te_aldecas5 mapflag skill_duration HT_SKIDTRAP,400
te_aldecas5 mapflag skill_duration HT_LANDMINE,400
te_aldecas5 mapflag skill_duration HT_ANKLESNARE,400
te_aldecas5 mapflag skill_duration HT_SHOCKWAVE,400
te_aldecas5 mapflag skill_duration HT_SANDMAN,400
te_aldecas5 mapflag skill_duration HT_FLASHER,400
te_aldecas5 mapflag skill_duration HT_FREEZINGTRAP,400
te_aldecas5 mapflag skill_duration HT_BLASTMINE,400
te_aldecas5 mapflag skill_duration HT_CLAYMORETRAP,400
te_aldecas5 mapflag skill_duration HT_TALKIEBOX,400
@@ -18,3 +18,4 @@ npc: npc/re/mapflag/night.txt
npc: npc/re/mapflag/restricted.txt
npc: npc/re/mapflag/town.txt
npc: npc/re/mapflag/reset.txt
npc: npc/re/mapflag/skill_duration.txt
@@ -28,3 +28,4 @@ npc: npc/mapflag/battleground.txt
npc: npc/mapflag/skill_damage.txt
npc: npc/mapflag/town.txt
npc: npc/mapflag/nocostume.txt
npc: npc/mapflag/skill_duration.txt
@@ -4043,16 +4043,16 @@ ACMD_FUNC(mapinfo) {

/* Skill damage adjustment info [Cydh] */
if (mapdata->flag[MF_SKILL_DAMAGE]) {
clif_displaymessage(fd,msg_txt(sd,1052)); // Skill Damage Adjustments:
sprintf(atcmd_output," > [Map] %d%%, %d%%, %d%%, %d%% | Caster:%d",
clif_displaymessage(fd,msg_txt(sd,1052)); // Skill Damage Adjustments:
sprintf(atcmd_output, msg_txt(sd, 1053), // > [Map] %d%%, %d%%, %d%%, %d%% | Caster:%d
mapdata->damage_adjust.rate[SKILLDMG_PC],
mapdata->damage_adjust.rate[SKILLDMG_MOB],
mapdata->damage_adjust.rate[SKILLDMG_BOSS],
mapdata->damage_adjust.rate[SKILLDMG_OTHER],
mapdata->damage_adjust.caster);
clif_displaymessage(fd, atcmd_output);
if (!mapdata->skill_damage.empty()) {
clif_displaymessage(fd," > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster");
clif_displaymessage(fd, msg_txt(sd, 1054)); // > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster
for (auto skilldmg : mapdata->skill_damage) {
sprintf(atcmd_output," %s : %d%%, %d%%, %d%%, %d%% | %d",
skill_get_name(skilldmg.first),
@@ -4066,6 +4066,14 @@ ACMD_FUNC(mapinfo) {
}
}

if (map_getmapflag(m_id, MF_SKILL_DURATION)) {
clif_displaymessage(fd, msg_txt(sd, 1055)); // Skill Duration Adjustments:
for (const auto &it : mapdata->skill_duration) {
sprintf(atcmd_output, " > %s : %d%%", skill_get_name(it.first), it.second);
clif_displaymessage(fd, atcmd_output);
}
}

strcpy(atcmd_output,msg_txt(sd,1046)); // PvP Flags:
if (map_getmapflag(m_id, MF_PVP))
strcat(atcmd_output, " Pvp ON |");
@@ -8163,7 +8171,8 @@ ACMD_FUNC(mapflag) {
MF_BEXP,
MF_JEXP,
MF_BATTLEGROUND,
MF_SKILL_DAMAGE };
MF_SKILL_DAMAGE,
MF_SKILL_DURATION };

if (flag && std::find(disabled_mf.begin(), disabled_mf.end(), mapflag) != disabled_mf.end()) {
sprintf(atcmd_output,"[ @mapflag ] %s flag cannot be enabled as it requires unique values.", flag_name);
@@ -3569,6 +3569,7 @@ void map_flags_init(void){
// Clear adjustment data, will be reset after loading NPC
mapdata->damage_adjust = {};
mapdata->skill_damage.clear();
mapdata->skill_duration.clear();
map_free_questinfo(mapdata);

if (instance_start && i >= instance_start)
@@ -3594,6 +3595,7 @@ void map_data_copy(struct map_data *dst_map, struct map_data *src_map) {

dst_map->flag.insert(src_map->flag.begin(), src_map->flag.end());
dst_map->skill_damage.insert(src_map->skill_damage.begin(), src_map->skill_damage.end());
dst_map->skill_duration.insert(src_map->skill_duration.begin(), src_map->skill_duration.end());

dst_map->zone = src_map->zone;
dst_map->qi_count = 0;
@@ -4457,6 +4459,19 @@ void map_skill_damage_add(struct map_data *m, uint16 skill_id, int rate[SKILLDMG
m->skill_damage.insert({ skill_id, entry });
}

/**
* Add new skill duration adjustment entry for a map
* @param mapd: Map data
* @param skill_id: Skill ID to adjust
* @param per: Skill duration adjustment value in percent
*/
void map_skill_duration_add(struct map_data *mapd, uint16 skill_id, uint16 per) {
if (mapd->skill_duration.find(skill_id) != mapd->skill_duration.end()) // Entry exists
mapd->skill_duration[skill_id] += per;
else // Update previous entry
mapd->skill_duration.insert({ skill_id, per });
}

/**
* PvP timer handling (starting)
* @param bl: Player block object
@@ -4833,6 +4848,16 @@ bool map_setmapflag_sub(int16 m, enum e_mapflag mapflag, bool status, union u_ma
}
mapdata->flag[mapflag] = status;
break;
case MF_SKILL_DURATION:
if (!status)
mapdata->skill_duration.clear();
else {
nullpo_retr(false, args);

map_skill_duration_add(mapdata, args->skill_duration.skill_id, args->skill_duration.per);
}
mapdata->flag[mapflag] = status;
break;
default:
mapdata->flag[mapflag] = status;
break;
@@ -578,6 +578,7 @@ enum e_mapflag : int16 {
MF_NOEXP,
MF_PRIVATEAIRSHIP_SOURCE,
MF_PRIVATEAIRSHIP_DESTINATION,
MF_SKILL_DURATION,
MF_MAX
};

@@ -598,6 +599,12 @@ struct s_skill_damage {
int rate[SKILLDMG_MAX]; ///< Used for when all skills are adjusted
};

/// Struct of MF_SKILL_DURATION
struct s_skill_duration {
uint16 skill_id; ///< Skill ID
uint16 per; ///< Rate
};

/// Enum for item drop type for MF_PVP_NIGHTMAREDROP
enum e_nightmare_drop_type : uint8 {
NMDT_INVENTORY = 0x1,
@@ -617,6 +624,7 @@ union u_mapflag_args {
struct point nosave;
struct s_drop_list nightmaredrop;
struct s_skill_damage skill_damage;
struct s_skill_duration skill_duration;
int flag_val;
};

@@ -729,6 +737,7 @@ struct map_data {
uint32 zone; // zone number (for item/skill restrictions)
struct s_skill_damage damage_adjust; // Used for overall skill damage adjustment
std::unordered_map<uint16, s_skill_damage> skill_damage; // Used for single skill damage adjustment
std::unordered_map<uint16, int> skill_duration;

struct npc_data *npc[MAX_NPC_PER_MAP];
struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer]
@@ -1116,6 +1125,7 @@ void map_addmap2db(struct map_data *m);
void map_removemapdb(struct map_data *m);

void map_skill_damage_add(struct map_data *m, uint16 skill_id, int rate[SKILLDMG_MAX], uint16 caster);
void map_skill_duration_add(struct map_data *mapd, uint16 skill_id, uint16 per);

enum e_mapflag map_getmapflag_by_name(char* name);
bool map_getmapflag_name(enum e_mapflag mapflag, char* output);
@@ -4129,7 +4129,7 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
args.skill_damage.caster = BL_ALL;

for (int i = 0; i < SKILLDMG_MAX; i++)
args.skill_damage.rate[i] = cap_value(args.skill_damage.rate[i], -100, INT_MAX);
args.skill_damage.rate[i] = cap_value(args.skill_damage.rate[i], -100, 100000);

if (strcmp(skill_name, "all") == 0) // Adjust damage for all skills
map_setmapflag_sub(m, MF_SKILL_DAMAGE, true, &args);
@@ -4145,6 +4145,28 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
break;
}

case MF_SKILL_DURATION: {
union u_mapflag_args args = {};

if (!state)
map_setmapflag_sub(m, MF_SKILL_DURATION, false, &args);
else {
char skill_name[SKILL_NAME_LENGTH];

if (sscanf(w4, "%30[^,],%5hu[^\n]", skill_name, &args.skill_duration.per) == 2) {
args.skill_duration.skill_id = skill_name2id(skill_name);

if (!args.skill_duration.skill_id)
ShowError("npc_parse_mapflag: skill_duration: Invalid skill name '%s' for Skill Duration mapflag. Skipping (file '%s', line '%d')\n", skill_name, filepath, strline(buffer, start - buffer));
else {
args.skill_duration.per = cap_value(args.skill_duration.per, 0, UINT16_MAX);
map_setmapflag_sub(m, MF_SKILL_DURATION, true, &args);
}
}
}
break;
}

// All others do not need special treatment
default:
map_setmapflag(m, mapflag, state);
@@ -12448,6 +12448,20 @@ BUILDIN_FUNC(setmapflag)
return SCRIPT_CMD_FAILURE;
}
break;
case MF_SKILL_DURATION:
if (script_hasdata(st, 4) && script_hasdata(st, 5)) {
args.skill_duration.skill_id = script_getnum(st, 4);

if (!skill_get_index(args.skill_duration.skill_id)) {
ShowError("buildin_setmapflag: Invalid skill ID %d for skill_duration mapflag.\n", args.skill_duration.skill_id);
return SCRIPT_CMD_FAILURE;
}
args.skill_duration.per = script_getnum(st, 5);
} else {
ShowWarning("buildin_setmapflag: Unable to set skill_duration mapflag as flag data is missing.\n");
return SCRIPT_CMD_FAILURE;
}
break;
case MF_NOSAVE: // Assume setting "SavePoint"
args.nosave.map = 0;
args.nosave.x = -1;
@@ -455,6 +455,7 @@
export_constant(MF_NOEXP);
export_constant(MF_PRIVATEAIRSHIP_SOURCE);
export_constant(MF_PRIVATEAIRSHIP_DESTINATION);
export_constant(MF_SKILL_DURATION);

/* setcell types */
export_constant(CELL_WALKABLE);

0 comments on commit 84b4f09

Please sign in to comment.