summaryrefslogtreecommitdiff
path: root/src/map/guild.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/guild.c')
-rw-r--r--src/map/guild.c156
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);
+ }
}
// ギルドデータ一括受信(初期化時)