summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-07-08 22:40:21 -0300
committershennetsind <ind@henn.et>2013-07-08 22:40:21 -0300
commit629fbd735a2a09d865dda51f0d128fc90039ea5a (patch)
tree46d69c137a1b2f7e0980bf42aa34922e5e72d91e /src
parenta2eacedd5df4a0bea47a15fa3a7f92e36f901b9f (diff)
downloadhercules-629fbd735a2a09d865dda51f0d128fc90039ea5a.tar.gz
hercules-629fbd735a2a09d865dda51f0d128fc90039ea5a.tar.bz2
hercules-629fbd735a2a09d865dda51f0d128fc90039ea5a.tar.xz
hercules-629fbd735a2a09d865dda51f0d128fc90039ea5a.zip
For Bug #7494
Modified skill cool down storage (also interfaced the remaining 2 static ers) http://hercules.ws/board/tracker/issue-7494-crash-crash-crash/ Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src')
-rw-r--r--src/map/clif.c13
-rw-r--r--src/map/skill.c136
-rw-r--r--src/map/skill.h23
3 files changed, 105 insertions, 67 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 4233e86e8..f17766f50 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -17565,15 +17565,14 @@ void clif_skill_cooldown_list(int fd, struct skill_cd* cd) {
#endif
for( i = 0; i < cd->cursor; i++ ) {
- if( cd->duration[i] < 1 ) continue;
+ if( cd->entry[i]->duration < 1 ) continue;
+
+ WFIFOW(fd, 4 + (count*offset)) = cd->entry[i]->skill_id;
+ WFIFOL(fd, 6 + (count*offset)) = cd->entry[i]->duration;
#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];
+ WFIFOL(fd, 10 + (count*offset)) = cd->entry[i]->duration;
#endif
+
count++;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index caee534ba..5df3596da 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -58,8 +58,6 @@
#if GD_SKILLRANGEMAX > 999
#error GD_SKILLRANGEMAX is greater than 999
#endif
-static struct eri *skill_unit_ers = NULL; //For handling skill_unit's [Skotlex]
-static struct eri *skill_timer_ers = NULL; //For handling skill_timerskills [Skotlex]
DBMap* skillunit_db = NULL; // int id -> struct skill_unit*
@@ -3290,7 +3288,7 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
}
} while (0);
//Free skl now that it is no longer needed.
- ers_free(skill_timer_ers, skl);
+ ers_free(skill->timer_ers, skl);
return 0;
}
@@ -3310,7 +3308,7 @@ int skill_addtimerskill (struct block_list *src, unsigned int tick, int target,
ARR_FIND( 0, MAX_SKILLTIMERSKILL, i, ud->skilltimerskill[i] == 0 );
if( i == MAX_SKILLTIMERSKILL ) return 1;
- ud->skilltimerskill[i] = ers_alloc(skill_timer_ers, struct skill_timerskill);
+ ud->skilltimerskill[i] = ers_alloc(skill->timer_ers, struct skill_timerskill);
ud->skilltimerskill[i]->timer = iTimer->add_timer(tick, skill->timerskill, src->id, i);
ud->skilltimerskill[i]->src_id = src->id;
ud->skilltimerskill[i]->target_id = target;
@@ -3338,7 +3336,7 @@ int skill_cleartimerskill (struct block_list *src)
for(i=0;i<MAX_SKILLTIMERSKILL;i++) {
if(ud->skilltimerskill[i]) {
iTimer->delete_timer(ud->skilltimerskill[i]->timer, skill->timerskill);
- ers_free(skill_timer_ers, ud->skilltimerskill[i]);
+ ers_free(skill->timer_ers, ud->skilltimerskill[i]);
ud->skilltimerskill[i]=NULL;
}
}
@@ -15268,7 +15266,7 @@ struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count,
i = MAX_SKILLUNITGROUP-1;
}
- group = ers_alloc(skill_unit_ers, struct skill_unit_group);
+ group = ers_alloc(skill->unit_ers, struct skill_unit_group);
group->src_id = src->id;
group->party_id = iStatus->get_party_id(src);
group->guild_id = iStatus->get_guild_id(src);
@@ -15426,7 +15424,7 @@ int skill_delunitgroup(struct skill_unit_group *group, const char* file, int lin
if( i < MAX_SKILLUNITGROUP ) {
ud->skillunit[i] = ud->skillunit[j];
ud->skillunit[j] = NULL;
- ers_free(skill_unit_ers, group);
+ ers_free(skill->unit_ers, group);
} else
ShowError("skill_delunitgroup: Group not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id);
@@ -16969,34 +16967,35 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0;
if( ( cd = idb_get(skill->cd_db,sd->status.char_id) ) ) {
- 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];
+ int i;
+
+ for( i = 0; i < cd->cursor; i++ ) {
+ if( cd->entry[i]->skidx == data )
+ break;
+ }
+
+ if( i == cd->cursor ) {
+ ShowError("skill_blockpc_end: '%s' : no data found for '%d'\n",sd->status.name,data);
+ } else {
+ int cursor = 0;
+
+ ers_free(skill->cd_entry_ers, cd->entry[i]);
+
+ cd->entry[i] = NULL;
+
+ for( i = 0, cursor = 0; i < cd->cursor; i++ ) {
+ if( !cd->entry[i] )
+ continue;
+ if( cursor != i )
+ cd->entry[cursor] = cd->entry[i];
+ cursor++;
+ }
+
+ if( (cd->cursor = cursor) == 0 ) {
+ idb_remove(skill->cd_db,sd->status.char_id);
+ ers_free(skill->cd_ers, cd);
}
- cursor++;
}
- if( cursor == 0 )
- idb_remove(skill->cd_db,sd->status.char_id);
- else
- cd->cursor = cursor;
}
sd->blockskill[data] = 0;
@@ -17012,7 +17011,6 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
* @return 0 if successful, -1 otherwise
*/
int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick, bool load) {
- struct skill_cd* cd = NULL;
uint16 idx = skill->get_index(skill_id);
nullpo_retr (-1, sd);
@@ -17029,20 +17027,38 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick,
clif->skill_cooldown(sd, skill_id, tick);
if( !load ) {// not being loaded initially so ensure the skill delay is recorded
- if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
- CREATE( cd, struct skill_cd, 1 );
+ struct skill_cd* cd = NULL;
+ int i;
+
+ if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
+ cd = ers_alloc(skill->cd_ers, struct skill_cd);
+
+ cd->cursor = 0;
+ memset(cd->entry, 0, sizeof(cd->entry));
+
idb_put( skill->cd_db, sd->status.char_id, cd );
}
- // record the skill duration in the database map
- cd->duration[cd->cursor] = tick;
+ for(i = 0; i < MAX_SKILL_TREE; i++) {
+ if( !cd->entry[i] )
+ break;
+ }
+
+ if( i == MAX_SKILL_TREE ) {
+ ShowError("skill_blockpc_start: '%s' got over '%d' skill cooldowns, no room to save!\n",sd->status.name,MAX_SKILL_TREE);
+ } else {
+ cd->entry[i] = ers_alloc(skill->cd_entry_ers,struct skill_cd_entry);
+
+ cd->entry[i]->duration = tick;
#if PACKETVER >= 20120604
- cd->total[cd->cursor] = tick;
+ cd->entry[i]->total = tick;
#endif
- cd->skidx[cd->cursor] = idx;
- cd->nameid[cd->cursor] = skill_id;
- cd->started[cd->cursor] = iTimer->gettick();
- cd->cursor++;
+ cd->entry[i]->skidx = idx;
+ cd->entry[i]->skill_id = skill_id;
+ cd->entry[i]->started = iTimer->gettick();
+
+ cd->cursor++;
+ }
}
sd->blockskill[idx] = 0x1|(0xFE&iTimer->add_timer(iTimer->gettick()+tick,skill->blockpc_end,sd->bl.id,idx));
@@ -17553,7 +17569,7 @@ void skill_cooldown_save(struct map_session_data * sd) {
// 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);
+ cd->entry[i]->duration = DIFF_TICK(cd->entry[i]->started+cd->entry[i]->duration,now);
}
}
@@ -17579,9 +17595,9 @@ void skill_cooldown_load(struct map_session_data * sd) {
// process each individual cooldown associated with the character
for( i = 0; i < cd->cursor; i++ ) {
- cd->started[i] = now;
+ cd->entry[i]->started = 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 );
+ skill->blockpc_start( sd, cd->entry[i]->skill_id, cd->entry[i]->duration, true );
}
}
@@ -18053,11 +18069,17 @@ int do_init_skill (void) {
group_db = idb_alloc(DB_OPT_BASE);
skillunit_db = idb_alloc(DB_OPT_BASE);
- skill->cd_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ skill->cd_db = idb_alloc(DB_OPT_BASE);
skillusave_db = idb_alloc(DB_OPT_RELEASE_DATA);
- skill_unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE);
- skill_timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE);
+
+ skill->unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE);
+ skill->timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE);
+ skill->cd_ers = ers_new(sizeof(struct skill_cd),"skill.c::skill_cd_ers",ERS_OPT_CLEAR);
+ skill->cd_entry_ers = ers_new(sizeof(struct skill_cd_entry),"skill.c::skill_cd_entry_ers",ERS_OPT_CLEAR);
+ ers_chunk_size(skill->cd_ers, 25);
+ ers_chunk_size(skill->cd_entry_ers, 100);
+
iTimer->add_timer_func_list(skill->unit_timer,"skill_unit_timer");
iTimer->add_timer_func_list(skill->castend_id,"skill_castend_id");
iTimer->add_timer_func_list(skill->castend_pos,"skill_castend_pos");
@@ -18069,15 +18091,18 @@ int do_init_skill (void) {
return 0;
}
-int do_final_skill(void)
-{
+int do_final_skill(void) {
+
db_destroy(skilldb_name2id);
db_destroy(group_db);
db_destroy(skillunit_db);
db_destroy(skill->cd_db);
db_destroy(skillusave_db);
- ers_destroy(skill_unit_ers);
- ers_destroy(skill_timer_ers);
+
+ ers_destroy(skill->unit_ers);
+ ers_destroy(skill->timer_ers);
+ ers_destroy(skill->cd_ers);
+ ers_destroy(skill->cd_entry_ers);
return 0;
}
/* initialize the interface */
@@ -18089,6 +18114,11 @@ void skill_defaults(void) {
skill->read_db = skill_readdb;
/* */
skill->cd_db = NULL;
+ /* */
+ skill->unit_ers = NULL;
+ skill->timer_ers = NULL;
+ skill->cd_ers = NULL;
+ skill->cd_entry_ers = NULL;
/* accesssors */
skill->get_index = skill_get_index;
skill->get_type = skill_get_type;
diff --git a/src/map/skill.h b/src/map/skill.h
index 35cb36809..1ca5f235a 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1713,6 +1713,16 @@ struct s_skill_magicmushroom_db {
};
extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
+struct skill_cd_entry {
+ int duration;//milliseconds
+#if PACKETVER >= 20120604
+ int total;
+#endif
+ short skidx;//the skill index entries belong to
+ unsigned int started;
+ uint16 skill_id;//skill id
+};
+
/**
* Skill Cool Down Delay Saving
* Struct skill_cd is not a member of struct map_session_data
@@ -1720,13 +1730,7 @@ extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUS
* 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];
+ struct skill_cd_entry *entry[MAX_SKILL_TREE];
unsigned char cursor;
};
@@ -1747,6 +1751,11 @@ struct skill_interface {
void (*read_db) (void);
/* */
DBMap* cd_db; // char_id -> struct skill_cd
+ /* */
+ struct eri *unit_ers; //For handling skill_unit's [Skotlex]
+ struct eri *timer_ers; //For handling skill_timerskills [Skotlex]
+ struct eri *cd_ers; // ERS Storage for skill cool down managers [Ind/Hercules]
+ struct eri *cd_entry_ers; // ERS Storage for skill cool down entries [Ind/Hercules]
/* accesssors */
int (*get_index) ( uint16 skill_id );
int (*get_type) ( uint16 skill_id );