summaryrefslogtreecommitdiff
path: root/src/map/pc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/pc.c')
-rw-r--r--src/map/pc.c99
1 files changed, 83 insertions, 16 deletions
diff --git a/src/map/pc.c b/src/map/pc.c
index 67c49b9fe..a81300b9e 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -73,6 +73,19 @@ const struct sg_data sg_info[MAX_PC_FEELHATE] = {
{ SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star }
};
+/**
+ * Item Cool Down Delay Saving
+ * Struct item_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* itemcd_db = NULL; // char_id -> struct skill_cd
+struct item_cd {
+ unsigned int tick[MAX_ITEMDELAYS];//tick
+ short nameid[MAX_ITEMDELAYS];//skill id
+};
+
+
//Converts a class to its array index for CLASS_COUNT defined arrays.
//Note that it does not do a validity check for speed purposes, where parsing
//player input make sure to use a pcdb_checkid first!
@@ -1072,6 +1085,11 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
**/
skill_cooldown_load(sd);
+ /**
+ * Check if player have any item cooldowns on
+ **/
+ pc_itemcd_do(sd,true);
+
// Request all registries (auth is considered completed whence they arrive)
intif_request_registry(sd,7);
return true;
@@ -3995,23 +4013,36 @@ int pc_useitem(struct map_session_data *sd,int n)
if( sd->inventory_data[n]->delay > 0 ) { // Check if there is a delay on this item [Paradox924X]
ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid || !sd->item_delay[i].nameid);
- if( i < MAX_ITEMDELAYS )
- {
- if( sd->item_delay[i].nameid )
- {// found
- if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 )
+ if( i < MAX_ITEMDELAYS ) {
+ if( sd->item_delay[i].nameid ) {// found
+ if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
+ int e_tick = DIFF_TICK(sd->item_delay[i].tick, tick)/1000;
+ char e_msg[100];
+ if( e_tick > 99 )
+ sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %.1f minutes.",
+ itemdb_jname(sd->status.inventory[n].nameid),
+ (double)e_tick / 60);
+ else
+ sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %d seconds.",
+ itemdb_jname(sd->status.inventory[n].nameid),
+ e_tick);
+ clif_colormes(sd,COLOR_RED,e_msg);
return 0; // Delay has not expired yet
- }
- else
- {// not yet used item (all slots are initially empty)
+ }
+ } else {// not yet used item (all slots are initially empty)
sd->item_delay[i].nameid = nameid;
}
sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay;
- }
- else
- {// should not happen
+ } else {// should not happen
ShowError("pc_useitem: Exceeded item delay array capacity! (nameid=%d, char_id=%d)\n", nameid, sd->status.char_id);
}
+ //clean up used delays so we can give room for more
+ for(i = 0; i < MAX_ITEMDELAYS; i++) {
+ if( DIFF_TICK(sd->item_delay[i].tick, tick) <= 0 ) {
+ sd->item_delay[i].tick = 0;
+ sd->item_delay[i].nameid = 0;
+ }
+ }
}
sd->itemid = sd->status.inventory[n].nameid;
@@ -8700,18 +8731,54 @@ int pc_read_motd(void)
return 0;
}
-
+void pc_itemcd_do(struct map_session_data *sd, bool load) {
+ int i,cursor = 0;
+ struct item_cd* cd = NULL;
+
+ if( load ) {
+ if( !(cd = idb_get(itemcd_db, sd->status.char_id)) ) {
+ // no skill cooldown is associated with this character
+ return;
+ }
+ for(i = 0; i < MAX_ITEMDELAYS; i++) {
+ if( cd->nameid[i] && DIFF_TICK(gettick(),cd->tick[i]) < 0 ) {
+ sd->item_delay[cursor].tick = cd->tick[i];
+ sd->item_delay[cursor].nameid = cd->nameid[i];
+ cursor++;
+ }
+ }
+ idb_remove(itemcd_db,sd->status.char_id);
+ } else {
+ if( !(cd = idb_get(itemcd_db,sd->status.char_id)) ) {
+ // create a new skill cooldown object for map storage
+ CREATE( cd, struct item_cd, 1 );
+ idb_put( itemcd_db, sd->status.char_id, cd );
+ }
+ for(i = 0; i < MAX_ITEMDELAYS; i++) {
+ if( sd->item_delay[i].nameid && DIFF_TICK(gettick(),sd->item_delay[i].tick) < 0 ) {
+ cd->tick[cursor] = sd->item_delay[i].tick;
+ cd->nameid[cursor] = sd->item_delay[i].nameid;
+ cursor++;
+ }
+ }
+ }
+ return;
+}
/*==========================================
* pc? ŒW‰Šú‰»
*------------------------------------------*/
-void do_final_pc(void)
-{
+void do_final_pc(void) {
+
+ db_destroy(itemcd_db);
+
do_final_pc_groups();
return;
}
-int do_init_pc(void)
-{
+int do_init_pc(void) {
+
+ itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
+
pc_readdb();
pc_read_motd(); // Read MOTD [Valaris]