diff options
Diffstat (limited to 'src/map/guild.c')
-rw-r--r-- | src/map/guild.c | 156 |
1 files changed, 93 insertions, 63 deletions
diff --git a/src/map/guild.c b/src/map/guild.c index 75f63b2ae..70f5361bb 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1530,16 +1530,21 @@ int guild_broken_sub(DBKey key,void *data,va_list ap) } //Invoked on Castles when a guild is broken. [Skotlex] -int castle_guild_broken_sub(DBKey key,void *data,va_list ap) +int castle_guild_broken_sub(DBKey key, void *data, va_list ap) { - struct guild_castle *gc=(struct guild_castle *)data; - int guild_id=va_arg(ap,int); + char name[EVENT_NAME_LENGTH]; + struct guild_castle *gc = data; + int guild_id = va_arg(ap, int); nullpo_ret(gc); - if (gc->guild_id == guild_id) - { //Save the new 'owner', this should invoke guardian clean up and other such things. - gc->guild_id = 0; + if (gc->guild_id == guild_id) { + // We call castle_event::OnGuildBreak of all castles of the guild + // You can set all castle_events in the 'db/castle_db.txt' + safestrncpy(name, gc->castle_event, sizeof(name)); + npc_event_do(strcat(name, "::OnGuildBreak")); + + //Save the new 'owner', this should invoke guardian clean up and other such things. guild_castledatasave(gc->castle_id, 1, 0); } return 0; @@ -1549,26 +1554,12 @@ int castle_guild_broken_sub(DBKey key,void *data,va_list ap) int guild_broken(int guild_id,int flag) { struct guild *g = guild_search(guild_id); - struct guild_castle *gc = NULL; - DBIterator *iter = NULL; struct map_session_data *sd = NULL; int i; - char name[EVENT_NAME_LENGTH]; if(flag!=0 || g==NULL) return 0; - //we call castle_event::OnGuildBreak of all castles of the guild - //you can set all castle_events in the castle_db.txt - iter = db_iterator(castle_db); - for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) { - if (gc->guild_id == guild_id) { - safestrncpy(name, gc->castle_event, sizeof(name)); - npc_event_do(strcat(name, "::OnGuildBreak")); - } - } - dbi_destroy(iter); - for(i=0;i<g->max_member;i++){ // ギルド解散を通知 if((sd=g->member[i].sd)!=NULL){ if(sd->state.storage_flag == 2) @@ -1716,60 +1707,99 @@ void guild_castle_map_init(void) } } -// ギルド城データ変更要求 -int guild_castledatasave(int castle_id,int index,int value) +/** + * Setter function for members of guild_castle struct. + * Handles all side-effects, like updating guardians. + * Sends updated info to char-server for saving. + * @param castle_id Castle ID + * @param index Type of data to change + * @param value New value + */ +int guild_castledatasave(int castle_id, int index, int value) { - if( index == 1 ) - { //The castle's owner has changed? Update Guardian ownership, too. [Skotlex] - struct guild_castle *gc = guild_castle_search(castle_id); - int m = -1; - if (gc) m = map_mapindex2mapid(gc->mapindex); - if (m != -1) - map_foreachinmap(mob_guardian_guildchange, m, BL_MOB); //FIXME: why not iterate over gc->guardian[i].id ? - } - else - if( index == 3 ) - { // defense invest change -> recalculate guardian hp - struct guild_castle* gc = guild_castle_search(castle_id); - if( gc ) - { - int i; - struct mob_data* gd; - for( i = 0; i < MAX_GUARDIANS; i++ ) - if( gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL ) - status_calc_mob(gd,0); - } - } - - return intif_guild_castle_datasave(castle_id, index, value); // FIXME: it may fail if char-server is disconnected -} + struct guild_castle *gc = guild_castle_search(castle_id); -// ギルド城データ変更通知 -int guild_castledatasaveack(int castle_id,int index,int value) -{ - struct guild_castle *gc=guild_castle_search(castle_id); - if(gc==NULL){ + if (gc == NULL) { + ShowWarning("guild_castledatasave: guild castle '%d' not found\n", castle_id); return 0; } - switch(index){ - case 1: gc->guild_id = value; break; - case 2: gc->economy = value; break; - case 3: gc->defense = value; break; - case 4: gc->triggerE = value; break; - case 5: gc->triggerD = value; break; - case 6: gc->nextTime = value; break; - case 7: gc->payTime = value; break; - case 8: gc->createTime = value; break; - case 9: gc->visibleC = value; break; + + switch (index) { + case 1: // The castle's owner has changed? Update or remove Guardians too. [Skotlex] + { + int i; + struct mob_data *gd; + gc->guild_id = value; + for (i = 0; i < MAX_GUARDIANS; i++) + if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL) + mob_guardian_guildchange(gd); + break; + } + case 2: + gc->economy = value; break; + case 3: // defense invest change -> recalculate guardian hp + { + int i; + struct mob_data *gd; + gc->defense = value; + for (i = 0; i < MAX_GUARDIANS; i++) + if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL) + status_calc_mob(gd, 0); + break; + } + case 4: + gc->triggerE = value; break; + case 5: + gc->triggerD = value; break; + case 6: + gc->nextTime = value; break; + case 7: + gc->payTime = value; break; + case 8: + gc->createTime = value; break; + case 9: + gc->visibleC = value; break; default: if (index > 9 && index <= 9+MAX_GUARDIANS) { gc->guardian[index-10].visible = value; break; } - ShowError("guild_castledatasaveack: not found index=%d\n", index); + ShowWarning("guild_castledatasave: index = '%d' is out of allowed range\n", index); return 0; } - return 1; + + if (!intif_guild_castle_datasave(castle_id, index, value)) { + guild_castle_reconnect(castle_id, index, value); + } + return 0; +} + +void guild_castle_reconnect_sub(void *key, void *data, va_list ap) +{ + int castle_id = GetWord((int)key, 0); + int index = GetWord((int)key, 1); + intif_guild_castle_datasave(castle_id, index, *(int *)data); + aFree(data); +} + +/** + * Saves pending guild castle data changes when char-server is + * disconnected. + * On reconnect pushes all changes to char-server for saving. + */ +void guild_castle_reconnect(int castle_id, int index, int value) +{ + static struct linkdb_node *gc_save_pending = NULL; + + if (castle_id < 0) { // char-server reconnected + linkdb_foreach(&gc_save_pending, guild_castle_reconnect_sub); + linkdb_final(&gc_save_pending); + } else { + int *data; + CREATE(data, int, 1); + *data = value; + linkdb_replace(&gc_save_pending, (void*)(MakeDWord(castle_id, index)), data); + } } // ギルドデータ一括受信(初期化時) |