diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/mmo.h | 2 | ||||
-rw-r--r-- | src/map/clif.c | 16 | ||||
-rw-r--r-- | src/map/clif.h | 1 | ||||
-rw-r--r-- | src/map/guild.c | 54 | ||||
-rw-r--r-- | src/map/map.h | 1 | ||||
-rw-r--r-- | src/map/mob.c | 47 | ||||
-rw-r--r-- | src/map/mob.h | 2 | ||||
-rw-r--r-- | src/map/npc.c | 1 | ||||
-rw-r--r-- | src/map/script.c | 27 | ||||
-rw-r--r-- | src/map/trade.c | 1 | ||||
-rw-r--r-- | src/map/unit.c | 16 |
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; } |