summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-04-07 21:04:28 +0000
committerFlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-04-07 21:04:28 +0000
commit1792fa7dcbae6d0678d9672ccb38eba88e87c757 (patch)
tree24189c639a4ac9a340a3c0dfd9060630e779b157 /src
parent44f46558e22a2b6c7287a233767bbcb713e25f55 (diff)
downloadhercules-1792fa7dcbae6d0678d9672ccb38eba88e87c757.tar.gz
hercules-1792fa7dcbae6d0678d9672ccb38eba88e87c757.tar.bz2
hercules-1792fa7dcbae6d0678d9672ccb38eba88e87c757.tar.xz
hercules-1792fa7dcbae6d0678d9672ccb38eba88e87c757.zip
* Made script command 'flagemblem' and guild_emblem_change send an update of the emblem_id to the players in the area.
- known bug: ui components that are displaying the emblem at the time (emblem in flag npc and emblem over head in gvg maps) are not updated, but putting the mouse over the target shows the new emblem * Modified script command 'guardian': - returns the id of the guardian - if guardian index isn't supplied, it generates a temporary guardian * Implemented support for temporary guardians (not saved with castle). * Added missing includes from r12520. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12525 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/common/mmo.h2
-rw-r--r--src/map/clif.c16
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/guild.c54
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/mob.c47
-rw-r--r--src/map/mob.h2
-rw-r--r--src/map/npc.c1
-rw-r--r--src/map/script.c27
-rw-r--r--src/map/trade.c1
-rw-r--r--src/map/unit.c16
11 files changed, 146 insertions, 22 deletions
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 18fda4bee..1c3d1e53a 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -425,6 +425,8 @@ struct guild_castle {
unsigned visible : 1;
int id; // object id
} guardian[MAX_GUARDIANS];
+ int* temp_guardians; // ids of temporary guardians (mobs)
+ int temp_guardians_max;
};
// for Brandish Spear calculations
diff --git a/src/map/clif.c b/src/map/clif.c
index 56a46a015..12c43972f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -6327,6 +6327,22 @@ int clif_guild_emblem(struct map_session_data *sd,struct guild *g)
return 0;
}
+/// Sends update of the guild id/emblem id to everyone in the area.
+void clif_guild_emblem_area(struct block_list* bl)
+{
+ char buf[12];
+
+ nullpo_retv(bl);
+
+ // TODO this packet doesn't force the update of ui components that have the emblem visible
+ // (emblem in the flag npcs and emblem over the head in agit maps) [FlavioJS]
+ WBUFW(buf,0) = 0x1B4;
+ WBUFL(buf,2) = bl->id;
+ WBUFL(buf,6) = status_get_guild_id(bl);
+ WBUFW(buf,10) = status_get_emblem_id(bl);
+ clif_send(buf, 12, bl, AREA_WOS);
+}
+
/*==========================================
* Send guild skills
*------------------------------------------*/
diff --git a/src/map/clif.h b/src/map/clif.h
index 0c0e9b04d..382e399bb 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -307,6 +307,7 @@ int clif_guild_expulsion(struct map_session_data *sd,const char *name,const char
int clif_guild_positionchanged(struct guild *g,int idx);
int clif_guild_memberpositionchanged(struct guild *g,int idx);
int clif_guild_emblem(struct map_session_data *sd,struct guild *g);
+void clif_guild_emblem_area(struct block_list* bl);
int clif_guild_notice(struct map_session_data *sd,struct guild *g);
int clif_guild_message(struct guild *g,int account_id,const char *mes,int len);
int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv);
diff --git a/src/map/guild.c b/src/map/guild.c
index f02deb16c..473599cc7 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -1103,8 +1103,49 @@ int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data)
sd->guild_emblem_id=emblem_id;
clif_guild_belonginfo(sd,g);
clif_guild_emblem(sd,g);
+ clif_guild_emblem_area(&sd->bl);
}
}
+ {// update guardians (mobs)
+ DBIterator* iter = db_iterator(castle_db);
+ struct guild_castle* gc;
+ for( gc = (struct guild_castle*)dbi_first(iter) ; dbi_exists(iter); gc = (struct guild_castle*)dbi_next(iter) )
+ {
+ if( gc->guild_id != guild_id )
+ continue;
+ // update permanent guardians
+ for( i = 0; i < ARRAYLENGTH(gc->guardian); ++i )
+ {
+ TBL_MOB* md = (gc->guardian[i].id ? map_id2md(gc->guardian[i].id) : NULL);
+ if( md == NULL || md->guardian_data == NULL )
+ continue;
+ md->guardian_data->emblem_id = emblem_id;
+ clif_guild_emblem_area(&md->bl);
+ }
+ // update temporary guardians
+ for( i = 0; i < gc->temp_guardians_max; ++i )
+ {
+ TBL_MOB* md = (gc->temp_guardians[i] ? map_id2md(gc->temp_guardians[i]) : NULL);
+ if( md == NULL || md->guardian_data == NULL )
+ continue;
+ md->guardian_data->emblem_id = emblem_id;
+ clif_guild_emblem_area(&md->bl);
+ }
+ }
+ dbi_destroy(iter);
+ }
+ {// update npcs (flags or other npcs that used flagemblem to attach to this guild)
+ // TODO this is not efficient [FlavioJS]
+ struct s_mapiterator* iter = mapit_geteachnpc();
+ TBL_NPC* nd;
+ for( nd = (TBL_NPC*)mapit_first(iter) ; mapit_exists(iter); nd = (TBL_NPC*)mapit_next(iter) )
+ {
+ if( nd->subtype != SCRIPT || nd->u.scr.guild_id != guild_id )
+ continue;
+ clif_guild_emblem_area(&nd->bl);
+ }
+ mapit_free(iter);
+ }
return 0;
}
@@ -1909,10 +1950,19 @@ static int guild_expcache_db_final(DBKey key,void *data,va_list ap)
return 0;
}
+static int guild_castle_db_final(DBKey key, void* data,va_list ap)
+{
+ struct guild_castle* gc = (struct guild_castle*)data;
+ if( gc->temp_guardians )
+ aFree(gc->temp_guardians);
+ aFree(data);
+ return 0;
+}
+
void do_init_guild(void)
{
guild_db=idb_alloc(DB_OPT_RELEASE_DATA);
- castle_db=idb_alloc(DB_OPT_RELEASE_DATA);
+ castle_db=idb_alloc(DB_OPT_BASE);
guild_expcache_db=idb_alloc(DB_OPT_BASE);
guild_infoevent_db=idb_alloc(DB_OPT_BASE);
expcache_ers = ers_new(sizeof(struct guild_expcache));
@@ -1932,7 +1982,7 @@ void do_init_guild(void)
void do_final_guild(void)
{
guild_db->destroy(guild_db,NULL);
- castle_db->destroy(castle_db,NULL);
+ castle_db->destroy(castle_db,guild_castle_db_final);
guild_expcache_db->destroy(guild_expcache_db,guild_expcache_db_final);
guild_infoevent_db->destroy(guild_infoevent_db,guild_infoevent_db_final);
guild_castleinfoevent_db->destroy(guild_castleinfoevent_db,guild_infoevent_db_final);
diff --git a/src/map/map.h b/src/map/map.h
index 1dbc4581a..2bf12e366 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -584,6 +584,7 @@ bool mapit_exists(struct s_mapiterator* mapit);
#define mapit_getallusers() mapit_alloc(MAPIT_NORMAL,BL_PC)
#define mapit_geteachpc() mapit_alloc(MAPIT_NORMAL,BL_PC)
#define mapit_geteachmob() mapit_alloc(MAPIT_NORMAL,BL_MOB)
+#define mapit_geteachnpc() mapit_alloc(MAPIT_NORMAL,BL_NPC)
#define mapit_geteachiddb() mapit_alloc(MAPIT_NORMAL,BL_ALL)
// ‚»‚Ì‘¼
diff --git a/src/map/mob.c b/src/map/mob.c
index 6463c2103..b62006d0b 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -677,6 +677,7 @@ static int mob_spawn_guardian_sub(int tid,unsigned int tick,int id,int data)
struct block_list* bl = map_id2bl(id);
struct mob_data* md;
struct guild* g;
+ int guardup_lv;
if (bl == NULL) //It is possible mob was already removed from map when the castle has no owner. [Skotlex]
return 0;
@@ -703,7 +704,7 @@ static int mob_spawn_guardian_sub(int tid,unsigned int tick,int id,int data)
guild_castledatasave(md->guardian_data->castle->castle_id, 1, 0);
}
} else {
- if (md->guardian_data->castle->guardian[md->guardian_data->number].visible)
+ 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);
@@ -712,10 +713,11 @@ static int mob_spawn_guardian_sub(int tid,unsigned int tick,int id,int data)
}
return 0;
}
+ guardup_lv = guild_checkskill(g,GD_GUARDUP);
md->guardian_data->emblem_id = g->emblem_id;
- memcpy (md->guardian_data->guild_name, g->name, NAME_LENGTH);
- md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
- if(md->guardian_data->guardup_lv)
+ memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
+ md->guardian_data->guardup_lv = guardup_lv;
+ if( guardup_lv )
status_calc_mob(md, 0); //Give bonuses.
return 0;
}
@@ -723,7 +725,7 @@ static int mob_spawn_guardian_sub(int tid,unsigned int tick,int id,int data)
/*==========================================
* Summoning Guardians [Valaris]
*------------------------------------------*/
-int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian)
+int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index)
{
struct mob_data *md=NULL;
struct spawn_data data;
@@ -749,7 +751,11 @@ int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobnam
data.class_ = class_;
- if(guardian < 0 || guardian >= MAX_GUARDIANS)
+ if( !has_index )
+ {
+ guardian = -1;
+ }
+ else if( guardian < 0 || guardian >= MAX_GUARDIANS )
{
ShowError("mob_spawn_guardian: Invalid guardian index %d for guardian %d (castle map %s)\n", guardian, class_, map[m].name);
return 0;
@@ -778,7 +784,7 @@ int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobnam
else
g = guild_search(gc->guild_id);
- if (gc->guardian[guardian].id)
+ if( has_index && gc->guardian[guardian].id )
{ //Check if guardian already exists, refuse to spawn if so.
struct mob_data *md2 = (TBL_MOB*)map_id2bl(gc->guardian[guardian].id);
if (md2 && md2->bl.type == BL_MOB &&
@@ -794,7 +800,21 @@ int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobnam
md->guardian_data->number = guardian;
md->guardian_data->guild_id = gc->guild_id;
md->guardian_data->castle = gc;
- gc->guardian[guardian].id = md->bl.id;
+ if( has_index )
+ {// permanent guardian
+ gc->guardian[guardian].id = md->bl.id;
+ }
+ else
+ {// temporary guardian
+ int i;
+ ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == 0);
+ if( i == gc->temp_guardians_max )
+ {
+ ++(gc->temp_guardians_max);
+ RECREATE(gc->temp_guardians, int, gc->temp_guardians_max);
+ }
+ gc->temp_guardians[i] = md->bl.id;
+ }
if (g)
{
md->guardian_data->emblem_id = g->emblem_id;
@@ -2077,7 +2097,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
status = &md->status;
- if(md->guardian_data && md->guardian_data->number < MAX_GUARDIANS)
+ if( md->guardian_data && 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);
md->state.skillstate = MSS_DEAD;
@@ -2588,7 +2608,7 @@ 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->castle->guardian[md->guardian_data->number].visible)
+ 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);
@@ -2602,8 +2622,11 @@ 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);
- 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 = 0;
+ guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
+ }
unit_free(&md->bl,0);
return 0;
}
diff --git a/src/map/mob.h b/src/map/mob.h
index b8a8a2394..bad4b6088 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -227,7 +227,7 @@ void mob_barricade_destroy(short m, const char *event);
void mob_barricade_get(struct map_session_data *sd);
void mod_barricade_clearall(void);
-int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian); // Spawning Guardians [Valaris]
+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_guardian_guildchange(struct block_list *bl,va_list ap); //Change Guardian's ownership. [Skotlex]
int mob_randomwalk(struct mob_data *md,unsigned int tick);
diff --git a/src/map/npc.c b/src/map/npc.c
index 78a7390cd..703e4faf6 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -10,6 +10,7 @@
#include "../common/utils.h"
#include "../common/ers.h"
#include "../common/db.h"
+#include "../common/socket.h"
#include "map.h"
#include "log.h"
#include "clif.h"
diff --git a/src/map/script.c b/src/map/script.c
index 15e83aeec..4cfde66f9 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -9165,14 +9165,30 @@ BUILDIN_FUNC(agitcheck)
return 0;
}
+/// Sets the guild_id of this npc.
+///
+/// flagemblem <guild_id>;
BUILDIN_FUNC(flagemblem)
{
+ TBL_NPC* nd;
int g_id=script_getnum(st,2);
if(g_id < 0) return 0;
-// ShowMessage("Script.c: [FlagEmblem] GuildID=%d, Emblem=%d.\n", g->guild_id, g->emblem_id);
- ((struct npc_data *)map_id2bl(st->oid))->u.scr.guild_id = g_id;
+ nd = (TBL_NPC*)map_id2nd(st->oid);
+ if( nd == NULL )
+ {
+ ShowError("script:flagemblem: npc %d not found\n", st->oid);
+ }
+ else if( nd->subtype != SCRIPT )
+ {
+ ShowError("script:flagemblem: unexpected subtype %d for npc %d '%s'\n", nd->subtype, st->oid, nd->exname);
+ }
+ else
+ {
+ nd->u.scr.guild_id = g_id;
+ clif_guild_emblem_area(&nd->bl);
+ }
return 0;
}
@@ -9743,13 +9759,14 @@ BUILDIN_FUNC(strmobinfo)
/*==========================================
* Summon guardians [Valaris]
- * guardian "<map name>",<x>,<y>,"<name to show>",<mob id>,{,"<event label>"}{,<guardian index>};
+ * guardian("<map name>",<x>,<y>,"<name to show>",<mob id>{,"<event label>"}{,<guardian index>}) -> <id>
*------------------------------------------*/
BUILDIN_FUNC(guardian)
{
int class_=0,x=0,y=0,guardian=0;
const char *str,*map,*evt="";
struct script_data *data;
+ bool has_index = false;
map =script_getstr(st,2);
x =script_getnum(st,3);
@@ -9761,6 +9778,7 @@ BUILDIN_FUNC(guardian)
{// "<event label>",<guardian index>
evt=script_getstr(st,7);
guardian=script_getnum(st,8);
+ has_index = true;
} else if( script_hasdata(st,7) ){
data=script_getdata(st,7);
get_val(st,data);
@@ -9770,6 +9788,7 @@ BUILDIN_FUNC(guardian)
} else if( data_isint(data) )
{// <guardian index>
guardian=script_getnum(st,7);
+ has_index = true;
} else {
ShowError("script:guardian: invalid data type for argument #6 (from 1)\n");
script_reportdata(data);
@@ -9778,7 +9797,7 @@ BUILDIN_FUNC(guardian)
}
check_event(st, evt);
- mob_spawn_guardian(map,x,y,str,class_,evt,guardian);
+ script_pushint(st, mob_spawn_guardian(map,x,y,str,class_,evt,guardian,has_index));
return 0;
}
diff --git a/src/map/trade.c b/src/map/trade.c
index e94bb5a0d..880657ff0 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -2,6 +2,7 @@
// For more information, see LICENCE in the main folder
#include "../common/nullpo.h"
+#include "../common/socket.h"
#include "clif.h"
#include "itemdb.h"
#include "map.h"
diff --git a/src/map/unit.c b/src/map/unit.c
index b8a5d327a..88bfaab47 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1950,10 +1950,20 @@ int unit_free(struct block_list *bl, int clrtype)
aFree(md->lootitem);
md->lootitem=NULL;
}
- if(md->guardian_data)
+ if( md->guardian_data )
{
- if (md->guardian_data->number < MAX_GUARDIANS)
- md->guardian_data->castle->guardian[md->guardian_data->number].id = 0;
+ struct guild_castle* gc = md->guardian_data->castle;
+ if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS )
+ {
+ gc->guardian[md->guardian_data->number].id = 0;
+ }
+ else
+ {
+ int i;
+ ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == md->bl.id);
+ if( i < gc->temp_guardians_max )
+ gc->temp_guardians[i] = 0;
+ }
aFree(md->guardian_data);
md->guardian_data = NULL;
}