summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorgepard1984 <gepard1984@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-03-05 00:08:28 +0000
committergepard1984 <gepard1984@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-03-05 00:08:28 +0000
commita6325af8d937fbf600362bacde389e6fa7d02719 (patch)
treee6d526f4dd8ca73b757751039be5cfa388a994da /src/map
parent262e60ab0b9cfc1f942a7b3ef11f7ed3abc7b208 (diff)
downloadhercules-a6325af8d937fbf600362bacde389e6fa7d02719.tar.gz
hercules-a6325af8d937fbf600362bacde389e6fa7d02719.tar.bz2
hercules-a6325af8d937fbf600362bacde389e6fa7d02719.tar.xz
hercules-a6325af8d937fbf600362bacde389e6fa7d02719.zip
- 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
Diffstat (limited to 'src/map')
-rw-r--r--src/map/chrif.c3
-rw-r--r--src/map/guild.c156
-rw-r--r--src/map/guild.h3
-rw-r--r--src/map/intif.c10
-rw-r--r--src/map/mob.c28
-rw-r--r--src/map/mob.h2
-rw-r--r--src/map/script.c38
7 files changed, 116 insertions, 124 deletions
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;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);
+ }
}
// ギルドデータ一括受信(初期化時)
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;
}