summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-06-30 15:34:50 -0300
committershennetsind <ind@henn.et>2013-06-30 15:34:50 -0300
commit19e25a2d18164ede743c79aba0c92b20ac17bdca (patch)
treef8cf124145d70a157c37bb81395d977f97d2f391
parent3e54d00ad3e1f6fd56aace6f227c66a5b67eb3ea (diff)
downloadhercules-19e25a2d18164ede743c79aba0c92b20ac17bdca.tar.gz
hercules-19e25a2d18164ede743c79aba0c92b20ac17bdca.tar.bz2
hercules-19e25a2d18164ede743c79aba0c92b20ac17bdca.tar.xz
hercules-19e25a2d18164ede743c79aba0c92b20ac17bdca.zip
Fixed Skill Cooldowns
Special Thanks to Vylow for bringing this to our attention. Also added support for the client-side cooldown left/total feature (packetver 20120604 and newer) Made Possible Thanks to Yommy =3 Signed-off-by: shennetsind <ind@henn.et>
-rw-r--r--src/common/mmo.h3
-rw-r--r--src/map/battleground.c6
-rw-r--r--src/map/clif.c36
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/map.c1
-rw-r--r--src/map/pc.h6
-rw-r--r--src/map/skill.c65
-rw-r--r--src/map/skill.h19
8 files changed, 111 insertions, 27 deletions
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 6e5dae099..17caf917a 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -92,6 +92,9 @@
#define MAX_CART 100
#define MAX_SKILL 1478
#define MAX_SKILL_ID 10015 // [Ind/Hercules] max used skill ID
+//Update this max as necessary. 55 is the value needed for Super Baby currently
+//Raised to 84 since Expanded Super Novice needs it.
+#define MAX_SKILL_TREE 84
#define GLOBAL_REG_NUM 256 // Max permanent character variables per char
#define ACCOUNT_REG_NUM 64 // Max permanent local account variables per account
#define ACCOUNT_REG2_NUM 16 // Max permanent global account variables per account
diff --git a/src/map/battleground.c b/src/map/battleground.c
index d54178347..3f0b9ee41 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -255,7 +255,7 @@ void bg_config_read(void) {
config_setting_t *settings = config_setting_get_elem(data, 0);
config_setting_t *arenas;
const char *delay_var;
- int i, arena_count = 0, total = 0, offline = 0;
+ int i, arena_count = 0, offline = 0;
if( !config_setting_lookup_string(settings, "global_delay_var", &delay_var) )
delay_var = "BG_Delay_Tick";
@@ -391,13 +391,11 @@ void bg_config_read(void) {
bg->arena[i]->fillup_timer = INVALID_TIMER;
bg->arena[i]->pregame_duration = pregame_duration;
bg->arena[i]->fillup_duration = fillup_duration;
-
- total++;
+
}
bg->arenas = arena_count;
}
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' arenas in '"CL_WHITE"%s"CL_RESET"'.\n", total, config_filename);
config_destroy(&bg_conf);
}
}
diff --git a/src/map/clif.c b/src/map/clif.c
index 373d510ba..0ad6fbd44 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -17478,6 +17478,41 @@ void clif_package_item_announce(struct map_session_data *sd, unsigned short name
clif->send(&p,sizeof(p), &sd->bl, ALL_CLIENT);
}
+/* [Ind/Hercules] special thanks to Yommy~! */
+void clif_skill_cooldown_list(int fd, struct skill_cd* cd) {
+#if PACKETVER >= 20120604
+ const int offset = 10;
+#else
+ const int offset = 6;
+#endif
+ int i, count = 0;
+
+ WFIFOHEAD(fd,4+(offset*cd->cursor));
+
+#if PACKETVER >= 20120604
+ WFIFOW(fd,0) = 0x985;
+#else
+ WFIFOW(fd,0) = 0x43e;
+#endif
+
+ for( i = 0; i < cd->cursor; i++ ) {
+ if( cd->duration[i] < 1 ) continue;
+#if PACKETVER >= 20120604
+ WFIFOW(fd, 4 + (i*10)) = cd->nameid[i];
+ WFIFOL(fd, 6 + (i*10)) = cd->total[i];
+ WFIFOL(fd, 10 + (i*10)) = cd->duration[i];
+#else
+ WFIFOW(fd, 4 + (i*6)) = cd->nameid[i];
+ WFIFOL(fd, 6 + (i*6)) = cd->duration[i];
+#endif
+ count++;
+ }
+
+ WFIFOW(fd,2) = 4+(offset*count);
+
+ WFIFOSET(fd,4+(offset*count));
+}
+
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
@@ -17944,6 +17979,7 @@ void clif_defaults(void) {
clif->sc_load = clif_status_change2;
clif->sc_end = clif_status_change_end;
clif->initialstatus = clif_initialstatus;
+ clif->cooldown_list = clif_skill_cooldown_list;
/* player-unit-specific-related */
clif->updatestatus = clif_updatestatus;
clif->changestatus = clif_changestatus;
diff --git a/src/map/clif.h b/src/map/clif.h
index 81376db15..c23db873e 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -38,6 +38,7 @@ struct quest;
struct party_booking_ad_info;
struct view_data;
struct eri;
+struct skill_cd;
/**
* Defines
@@ -632,6 +633,7 @@ struct clif_interface {
void (*sc_load) (struct block_list *bl, int tid, enum send_target target, int type, int val1, int val2, int val3);
void (*sc_end) (struct block_list *bl, int tid, enum send_target target, int type);
void (*initialstatus) (struct map_session_data *sd);
+ void (*cooldown_list) (int fd, struct skill_cd* cd);
/* player-unit-specific-related */
void (*updatestatus) (struct map_session_data *sd,int type);
void (*changestatus) (struct map_session_data* sd,int type,int val);
diff --git a/src/map/map.c b/src/map/map.c
index 99f585a8d..389c031bd 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1647,6 +1647,7 @@ int map_quit(struct map_session_data *sd) {
if( sd->bg_id )
bg_team_leave(sd,1);
+ skill->cooldown_save(sd);
pc->itemcd_do(sd,false);
for( i = 0; i < sd->queues_count; i++ ) {
diff --git a/src/map/pc.h b/src/map/pc.h
index 442b55965..8be2b7344 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -3,6 +3,7 @@
// Portions Copyright (c) Athena Dev Teams
#ifndef _PC_H_
#define _PC_H_
+
#include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus
#include "../common/ers.h"
#include "../common/timer.h" // INVALID_TIMER
@@ -20,9 +21,11 @@
#include "mob.h"
#include "log.h"
#include "pc_groups.h"
+
#define MAX_PC_BONUS 10
#define MAX_PC_SKILL_REQUIRE 5
#define MAX_PC_FEELHATE 3
+
//Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index
//where the arrows are equipped)
enum equip_index {
@@ -507,9 +510,6 @@ struct map_session_data {
struct eri *pc_sc_display_ers;
-//Update this max as necessary. 55 is the value needed for Super Baby currently
-//Raised to 84 since Expanded Super Novice needs it.
-#define MAX_SKILL_TREE 84
//Total number of classes (for data storage)
#define CLASS_COUNT (JOB_MAX - JOB_NOVICE_HIGH + JOB_MAX_BASIC)
diff --git a/src/map/skill.c b/src/map/skill.c
index 8cb82e3a6..4bd27f578 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -64,20 +64,6 @@ static struct eri *skill_timer_ers = NULL; //For handling skill_timerskills [Sko
DBMap* skillunit_db = NULL; // int id -> struct skill_unit*
/**
- * Skill Cool Down Delay Saving
- * Struct skill_cd is not a member of struct map_session_data
- * to keep cooldowns in memory between player log-ins.
- * All cooldowns are reset when server is restarted.
- **/
-DBMap* skillcd_db = NULL; // char_id -> struct skill_cd
-struct skill_cd {
- int duration[MAX_SKILL_TREE];//milliseconds
- short skidx[MAX_SKILL_TREE];//the skill index entries belong to
- short nameid[MAX_SKILL_TREE];//skill id
- unsigned char cursor;
-};
-
-/**
* Skill Unit Persistency during endack routes (mostly for songs see bugreport:4574)
**/
DBMap* skillusave_db = NULL; // char_id -> struct skill_usave
@@ -8050,9 +8036,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
else if(bl->type == BL_PC) rate += 20 + 10 * skill_lv; // On Players, (20 + 10 * Skill Level) %
else rate += 40 + 10 * skill_lv; // On Monsters, (40 + 10 * Skill Level) %
- if( sd )
- skill->blockpc_start(sd,skill_id,4000, false);
-
if( !(tsc && tsc->data[type]) ){
i = sc_start2(bl,type,rate,skill_lv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill->get_time(skill_id,skill_lv):skill->get_time2(skill_id, skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,i);
@@ -16888,16 +16871,24 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
int i,cursor;
ARR_FIND( 0, cd->cursor+1, cursor, cd->skidx[cursor] == data );
cd->duration[cursor] = 0;
+#if PACKETVER >= 20120604
+ cd->total[cursor] = 0;
+#endif
cd->skidx[cursor] = 0;
cd->nameid[cursor] = 0;
+ cd->started[cursor] = 0;
// compact the cool down list
for( i = 0, cursor = 0; i < cd->cursor; i++ ) {
if( cd->duration[i] == 0 )
continue;
if( cursor != i ) {
cd->duration[cursor] = cd->duration[i];
+#if PACKETVER >= 20120604
+ cd->total[cursor] = cd->total[i];
+#endif
cd->skidx[cursor] = cd->skidx[i];
cd->nameid[cursor] = cd->nameid[i];
+ cd->started[cursor] = cd->started[i];
}
cursor++;
}
@@ -16933,7 +16924,7 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick,
return -1;
}
- if( battle_config.display_status_timers )
+ if( !load && battle_config.display_status_timers )
clif->skill_cooldown(sd, skill_id, tick);
if( !load ) {// not being loaded initially so ensure the skill delay is recorded
@@ -16944,8 +16935,12 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick,
// record the skill duration in the database map
cd->duration[cd->cursor] = tick;
+#if PACKETVER >= 20120604
+ cd->total[cd->cursor] = tick;
+#endif
cd->skidx[cd->cursor] = idx;
cd->nameid[cd->cursor] = skill_id;
+ cd->started[cd->cursor] = iTimer->gettick();
cd->cursor++;
}
@@ -17438,13 +17433,37 @@ int skill_get_elemental_type( uint16 skill_id , uint16 skill_lv ) {
}
/**
+ * update stored skill cooldowns for player logout
+ * @param sd the affected player structure
+ */
+void skill_cooldown_save(struct map_session_data * sd) {
+ int i;
+ struct skill_cd* cd = NULL;
+ unsigned int now = 0;
+
+ // always check to make sure the session properly exists
+ nullpo_retv(sd);
+
+ if( !(cd = idb_get(skillcd_db, sd->status.char_id)) ) {// no skill cooldown is associated with this character
+ return;
+ }
+
+ now = iTimer->gettick();
+
+ // process each individual cooldown associated with the character
+ for( i = 0; i < cd->cursor; i++ ) {
+ cd->duration[i] = DIFF_TICK(cd->started[i]+cd->duration[i],now);
+ }
+}
+
+/**
* reload stored skill cooldowns when a player logs in.
* @param sd the affected player structure
*/
-void skill_cooldown_load(struct map_session_data * sd)
-{
+void skill_cooldown_load(struct map_session_data * sd) {
int i;
struct skill_cd* cd = NULL;
+ unsigned int now = 0;
// always check to make sure the session properly exists
nullpo_retv(sd);
@@ -17453,8 +17472,13 @@ void skill_cooldown_load(struct map_session_data * sd)
return;
}
+ clif->cooldown_list(sd->fd,cd);
+
+ now = iTimer->gettick();
+
// process each individual cooldown associated with the character
for( i = 0; i < cd->cursor; i++ ) {
+ cd->started[i] = now;
// block the skill from usage but ensure it is not recorded (load = true)
skill->blockpc_start( sd, cd->nameid[i], cd->duration[i], true );
}
@@ -18145,5 +18169,6 @@ void skill_defaults(void) {
skill->elementalanalysis = skill_elementalanalysis;
skill->changematerial = skill_changematerial;
skill->get_elemental_type = skill_get_elemental_type;
+ skill->cooldown_save = skill_cooldown_save;
}
diff --git a/src/map/skill.h b/src/map/skill.h
index 921a682a2..338537975 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1714,11 +1714,29 @@ struct s_skill_magicmushroom_db {
extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
/**
+ * Skill Cool Down Delay Saving
+ * Struct skill_cd is not a member of struct map_session_data
+ * to keep cooldowns in memory between player log-ins.
+ * All cooldowns are reset when server is restarted.
+ **/
+struct skill_cd {
+ int duration[MAX_SKILL_TREE];//milliseconds
+#if PACKETVER >= 20120604
+ int total[MAX_SKILL_TREE];
+#endif
+ short skidx[MAX_SKILL_TREE];//the skill index entries belong to
+ short nameid[MAX_SKILL_TREE];//skill id
+ unsigned int started[MAX_SKILL_TREE];
+ unsigned char cursor;
+};
+
+/**
* Vars
**/
extern int enchant_eff[5];
extern int deluge_eff[5];
DBMap* skilldb_name2id;
+DBMap* skillcd_db; // char_id -> struct skill_cd
/**
* Skill.c Interface
@@ -1917,6 +1935,7 @@ struct skill_interface {
int (*elementalanalysis) (struct map_session_data *sd, int n, uint16 skill_lv, unsigned short *item_list);
int (*changematerial) (struct map_session_data *sd, int n, unsigned short *item_list);
int (*get_elemental_type) (uint16 skill_id, uint16 skill_lv);
+ void (*cooldown_save) (struct map_session_data * sd);
} skill_s;
struct skill_interface *skill;