From a6325af8d937fbf600362bacde389e6fa7d02719 Mon Sep 17 00:00:00 2001 From: gepard1984 Date: Mon, 5 Mar 2012 00:08:28 +0000 Subject: - Guild Castle code cleanup: - all changes to guild castle data are now handled first by map-server and only sent to char-server for saving - ensured that changes made to guild castle during char-server disconnection time will be resent on reconnect - actually removed definition of `MAX_GUILDCASTLE` (r15657) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15658 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/chrif.c | 3 ++ src/map/guild.c | 156 +++++++++++++++++++++++++++++++++---------------------- src/map/guild.h | 3 +- src/map/intif.c | 10 +--- src/map/mob.c | 28 +++------- src/map/mob.h | 2 +- src/map/script.c | 38 +++----------- 7 files changed, 116 insertions(+), 124 deletions(-) (limited to 'src/map') diff --git a/src/map/chrif.c b/src/map/chrif.c index a75c48ecb..26c7b10cc 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -510,6 +510,9 @@ void chrif_on_ready(void) //Re-save any storages that were modified in the disconnection time. [Skotlex] do_reconnect_storage(); + + //Re-save any guild castles that were modified in the disconnection time. + guild_castle_reconnect(-1, 0, 0); } 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;imax_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); + } } // ギルドデータ一括受信(初期化時) diff --git a/src/map/guild.h b/src/map/guild.h index 3af5be6c4..ded8468d3 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -91,10 +91,9 @@ int guild_gm_change(int guild_id, struct map_session_data *sd); int guild_gm_changed(int guild_id, int account_id, int char_id); void guild_castle_map_init(void); -int guild_castledataload(int castle_id,int index); int guild_castledatasave(int castle_id,int index,int value); -int guild_castledatasaveack(int castle_id,int index,int value); int guild_castledataloadack(int len, struct guild_castle *gc); +void guild_castle_reconnect(int castle_id, int index, int value); int guild_agit_start(void); int guild_agit_end(void); diff --git a/src/map/intif.c b/src/map/intif.c index 20d686c11..c0d9050c5 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -36,7 +36,7 @@ static const int packet_len_table[]={ 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 - -1, 9, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840 + -1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840 -1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish] -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3870 Mercenaries [Zephyrus] @@ -749,7 +749,7 @@ int intif_guild_castle_datasave(int castle_id,int index, int value) WFIFOB(inter_fd,4)=index; WFIFOL(inter_fd,5)=value; WFIFOSET(inter_fd,9); - return 0; + return 1; } //----------------------------------------------------------------- @@ -1209,11 +1209,6 @@ int intif_parse_GuildCastleDataLoad(int fd) { return guild_castledataloadack(RFIFOW(fd,2), (struct guild_castle *)RFIFOP(fd,4)); } -// ギルド城データ変更通知 -int intif_parse_GuildCastleDataSave(int fd) -{ - return guild_castledatasaveack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); -} int intif_parse_GuildMasterChanged(int fd) { @@ -2037,7 +2032,6 @@ int intif_parse(int fd) case 0x383e: intif_parse_GuildNotice(fd); break; case 0x383f: intif_parse_GuildEmblem(fd); break; case 0x3840: intif_parse_GuildCastleDataLoad(fd); break; - case 0x3841: intif_parse_GuildCastleDataSave(fd); break; case 0x3843: intif_parse_GuildMasterChanged(fd); break; //Quest system diff --git a/src/map/mob.c b/src/map/mob.c index 73d752702..e1c324ba1 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -548,11 +548,8 @@ static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t d guild_castledatasave(md->guardian_data->castle->castle_id, 1, 0); } } else { - if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible ) - { //Safe removal of guardian. - md->guardian_data->castle->guardian[md->guardian_data->number].visible = 0; + if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible) guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); - } unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian. } return 0; @@ -2512,13 +2509,10 @@ void mob_revive(struct mob_data *md, unsigned int hp) clif_charnameack (0, &md->bl); } -int mob_guardian_guildchange(struct block_list *bl,va_list ap) +int mob_guardian_guildchange(struct mob_data *md) { - struct mob_data *md; - struct guild* g; - - nullpo_ret(bl); - nullpo_ret(md = (struct mob_data *)bl); + struct guild *g; + nullpo_ret(md); if (!md->guardian_data) return 0; @@ -2531,11 +2525,8 @@ int mob_guardian_guildchange(struct block_list *bl,va_list ap) md->guardian_data->emblem_id = 0; md->guardian_data->guild_name[0] = '\0'; } else { - if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible ) - { //Safe removal of guardian. - md->guardian_data->castle->guardian[md->guardian_data->number].visible = 0; - guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); - } + if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible) + guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0); unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian. } return 0; @@ -2545,11 +2536,8 @@ int mob_guardian_guildchange(struct block_list *bl,va_list ap) if (g == NULL) { //Properly remove guardian info from Castle data. ShowError("mob_guardian_guildchange: New Guild (id %d) does not exists!\n", md->guardian_data->guild_id); - if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS ) - { - md->guardian_data->castle->guardian[md->guardian_data->number].visible = 0; - guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); - } + if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS) + guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0); unit_free(&md->bl,CLR_OUTSIGHT); return 0; } diff --git a/src/map/mob.h b/src/map/mob.h index 0ad95ff19..be1c0220e 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -237,7 +237,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target); int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index); // Spawning Guardians [Valaris] int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id); -int mob_guardian_guildchange(struct block_list *bl,va_list ap); //Change Guardian's ownership. [Skotlex] +int mob_guardian_guildchange(struct mob_data *md); //Change Guardian's ownership. [Skotlex] int mob_randomwalk(struct mob_data *md,unsigned int tick); int mob_warpchase(struct mob_data *md, struct block_list *target); diff --git a/src/map/script.c b/src/map/script.c index 67e9e722e..3fa32d681 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10145,7 +10145,7 @@ BUILDIN_FUNC(getcastledata) if (gc == NULL) { script_pushint(st,0); - ShowWarning("builtin_setcastledata: guild castle for map '%s' not found\n", mapname); + ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname); return 1; } @@ -10182,43 +10182,21 @@ BUILDIN_FUNC(getcastledata) BUILDIN_FUNC(setcastledata) { - const char* mapname = mapindex_getmapname(script_getstr(st,2),NULL); + const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL); int index = script_getnum(st,3); int value = script_getnum(st,4); - struct guild_castle* gc = guild_mapname2gc(mapname); + struct guild_castle *gc = guild_mapname2gc(mapname); if (gc == NULL) { - ShowWarning("builtin_setcastledata: guild castle for map '%s' not found\n", mapname); + ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname); return 1; } - 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; - default: - if (index > 9 && index <= 9+MAX_GUARDIANS) { - gc->guardian[index-10].visible = value; - break; - } - ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index); - return 1; + if (index <= 0 || index > 9+MAX_GUARDIANS) { + ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index); + return 1; } + guild_castledatasave(gc->castle_id, index, value); return 0; } -- cgit v1.2.3-60-g2f50