guild.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <limits.h>
  7. #include "../common/timer.h"
  8. #include "../common/nullpo.h"
  9. #include "../common/malloc.h"
  10. #include "../common/showmsg.h"
  11. #include "../common/ers.h"
  12. #include "map.h"
  13. #include "guild.h"
  14. #include "storage.h"
  15. #include "battle.h"
  16. #include "npc.h"
  17. #include "pc.h"
  18. #include "status.h"
  19. #include "mob.h"
  20. #include "intif.h"
  21. #include "clif.h"
  22. #include "skill.h"
  23. #include "log.h"
  24. static DB guild_db;
  25. static DB castle_db;
  26. static DB guild_expcache_db;
  27. static DB guild_infoevent_db;
  28. static DB guild_castleinfoevent_db;
  29. struct eventlist {
  30. char name[50];
  31. struct eventlist *next;
  32. };
  33. // ギルドのEXPキャッシュのフラッシュに関連する定数
  34. #define GUILD_SEND_XY_INVERVAL 5000 // 座標やHP送信の間隔
  35. #define GUILD_PAYEXP_INVERVAL 10000 // 間隔(キャッシュの最大生存時間、ミリ秒)
  36. #define GUILD_PAYEXP_LIST 8192 // キャッシュの最大数
  37. // ギルドのEXPキャッシュ
  38. struct guild_expcache {
  39. int guild_id, account_id, char_id;
  40. unsigned int exp;
  41. };
  42. static struct eri *expcache_ers; //For handling of guild exp payment.
  43. struct{
  44. int id;
  45. int max;
  46. struct{
  47. short id;
  48. short lv;
  49. }need[6];
  50. } guild_skill_tree[MAX_GUILDSKILL];
  51. // timer for auto saving guild data during WoE
  52. #define GUILD_SAVE_INTERVAL 300000
  53. int guild_save_timer = -1;
  54. int guild_payexp_timer(int tid,unsigned int tick,int id,int data);
  55. int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data);
  56. int guild_save_sub(int tid,unsigned int tick,int id,int data);
  57. static int guild_send_xy_timer(int tid,unsigned int tick,int id,int data);
  58. // Modified [Komurka]
  59. int guild_skill_get_max (int id)
  60. {
  61. if (id < GD_SKILLBASE || id > GD_SKILLBASE+MAX_GUILDSKILL)
  62. return 0;
  63. return guild_skill_tree[id-GD_SKILLBASE].max;
  64. }
  65. // ギルドスキルがあるか確認
  66. int guild_checkskill(struct guild *g,int id)
  67. {
  68. int idx = id-GD_SKILLBASE;
  69. if (idx < 0 || idx >= MAX_GUILDSKILL)
  70. return 0;
  71. return g->skill[idx].lv;
  72. }
  73. /*==========================================
  74. * guild_skill_tree.txt reading - from jA [Komurka]
  75. *------------------------------------------
  76. */
  77. int guild_read_guildskill_tree_db(void)
  78. {
  79. int i,k,id=0,ln=0;
  80. FILE *fp;
  81. char line[1024],*p;
  82. malloc_set(guild_skill_tree,0,sizeof(guild_skill_tree));
  83. sprintf(line, "%s/guild_skill_tree.txt", db_path);
  84. if( (fp=fopen(line,"r"))==NULL){
  85. ShowError("can't read %s\n", line);
  86. return -1;
  87. }
  88. while(fgets(line,1020,fp)){
  89. char *split[50];
  90. if(line[0]=='/' && line[1]=='/')
  91. continue;
  92. for(i=0,p=line;i<12 && p;i++){
  93. split[i]=p;
  94. p=strchr(p,',');
  95. if(p) *p++=0;
  96. }
  97. if(i<12)
  98. continue;
  99. id = atoi(split[0]) - GD_SKILLBASE;
  100. if(id<0 || id>=MAX_GUILDSKILL)
  101. continue;
  102. guild_skill_tree[id].id=atoi(split[0]);
  103. guild_skill_tree[id].max=atoi(split[1]);
  104. if (guild_skill_tree[id].id==GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max==0) guild_skill_tree[id].max=1;
  105. for(k=0;k<5;k++){
  106. guild_skill_tree[id].need[k].id=atoi(split[k*2+2]);
  107. guild_skill_tree[id].need[k].lv=atoi(split[k*2+3]);
  108. }
  109. ln++;
  110. }
  111. fclose(fp);
  112. ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"guild_skill_tree.txt");
  113. return 0;
  114. }
  115. /*==========================================
  116. * Guild skill check - from jA [Komurka]
  117. *------------------------------------------
  118. */
  119. int guild_check_skill_require(struct guild *g,int id)
  120. {
  121. int i;
  122. int idx = id-GD_SKILLBASE;
  123. if(g == NULL)
  124. return 0;
  125. if (idx < 0 || idx >= MAX_GUILDSKILL)
  126. return 0;
  127. for(i=0;i<5;i++)
  128. {
  129. if(guild_skill_tree[idx].need[i].id == 0) break;
  130. if(guild_skill_tree[idx].need[i].lv > guild_checkskill(g,guild_skill_tree[idx].need[i].id))
  131. return 0;
  132. }
  133. return 1;
  134. }
  135. static int guild_read_castledb(void)
  136. {
  137. FILE *fp;
  138. char line[1024];
  139. int j,ln=0;
  140. char *str[32],*p;
  141. struct guild_castle *gc;
  142. sprintf(line, "%s/castle_db.txt", db_path);
  143. if( (fp=fopen(line,"r"))==NULL){
  144. ShowError("can't read %s\n", line);
  145. return -1;
  146. }
  147. while(fgets(line,1020,fp)){
  148. if(line[0]=='/' && line[1]=='/')
  149. continue;
  150. malloc_tsetdword(str,0,sizeof(str));
  151. for(j=0,p=line;j<6 && p;j++){
  152. str[j]=p;
  153. p=strchr(p,',');
  154. if(p) *p++=0;
  155. }
  156. if (j < 4) //Insufficient data for castle. [Skotlex]
  157. {
  158. ShowError("castle_db.txt: invalid line '%s'\n", line);
  159. continue;
  160. }
  161. gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle));
  162. gc->castle_id=atoi(str[0]);
  163. memcpy(gc->map_name,str[1],MAP_NAME_LENGTH-1);
  164. memcpy(gc->castle_name,str[2],NAME_LENGTH-1);
  165. memcpy(gc->castle_event,str[3],NAME_LENGTH-1);
  166. idb_put(castle_db,gc->castle_id,gc);
  167. //intif_guild_castle_info(gc->castle_id);
  168. ln++;
  169. }
  170. fclose(fp);
  171. ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"castle_db.txt");
  172. return 0;
  173. }
  174. // 初期化
  175. void do_init_guild(void)
  176. {
  177. guild_db=db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
  178. castle_db=db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
  179. guild_expcache_db=db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_BASE,sizeof(int));
  180. guild_infoevent_db=db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_BASE,sizeof(int));
  181. expcache_ers = ers_new(sizeof(struct guild_expcache));
  182. guild_castleinfoevent_db=db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_BASE,sizeof(int));
  183. guild_read_castledb();
  184. guild_read_guildskill_tree_db(); //guild skill tree [Komurka]
  185. add_timer_func_list(guild_gvg_eliminate_timer,"guild_gvg_eliminate_timer");
  186. add_timer_func_list(guild_payexp_timer,"guild_payexp_timer");
  187. add_timer_func_list(guild_save_sub, "guild_save_sub");
  188. add_timer_func_list(guild_send_xy_timer, "guild_send_xy_timer");
  189. add_timer_interval(gettick()+GUILD_PAYEXP_INVERVAL,guild_payexp_timer,0,0,GUILD_PAYEXP_INVERVAL);
  190. add_timer_interval(gettick()+GUILD_SEND_XY_INVERVAL,guild_send_xy_timer,0,0,GUILD_SEND_XY_INVERVAL);
  191. }
  192. // 検索
  193. struct guild *guild_search(int guild_id)
  194. {
  195. return idb_get(guild_db,guild_id);
  196. }
  197. int guild_searchname_sub(DBKey key,void *data,va_list ap)
  198. {
  199. struct guild *g=(struct guild *)data,**dst;
  200. char *str;
  201. str=va_arg(ap,char *);
  202. dst=va_arg(ap,struct guild **);
  203. if(strcmpi(g->name,str)==0)
  204. *dst=g;
  205. return 0;
  206. }
  207. // ギルド名検索
  208. struct guild* guild_searchname(char *str)
  209. {
  210. struct guild *g=NULL;
  211. guild_db->foreach(guild_db,guild_searchname_sub,str,&g);
  212. return g;
  213. }
  214. struct guild_castle *guild_castle_search(int gcid)
  215. {
  216. return idb_get(castle_db,gcid);
  217. }
  218. // mapnameに対応したアジトのgcを返す
  219. struct guild_castle *guild_mapname2gc(char *mapname)
  220. {
  221. int i;
  222. struct guild_castle *gc=NULL;
  223. for(i=0;i<MAX_GUILDCASTLE;i++){
  224. gc=guild_castle_search(i);
  225. if(!gc) continue;
  226. if(strcmp(gc->map_name,mapname)==0) return gc;
  227. }
  228. return NULL;
  229. }
  230. struct guild_castle *guild_mapindex2gc(short mapname)
  231. {
  232. int i;
  233. struct guild_castle *gc=NULL;
  234. for(i=0;i<MAX_GUILDCASTLE;i++){
  235. gc=guild_castle_search(i);
  236. if(!gc) continue;
  237. if(strcmp(gc->map_name,mapindex_id2name(mapname))==0) return gc;
  238. }
  239. return NULL;
  240. }
  241. // ログイン中のギルドメンバーの1人のsdを返す
  242. struct map_session_data *guild_getavailablesd(struct guild *g)
  243. {
  244. int i;
  245. nullpo_retr(NULL, g);
  246. for(i=0;i<g->max_member;i++)
  247. if(g->member[i].sd!=NULL)
  248. return g->member[i].sd;
  249. return NULL;
  250. }
  251. // ギルドメンバーのインデックスを返す
  252. int guild_getindex(struct guild *g,int account_id,int char_id)
  253. {
  254. int i;
  255. if(g==NULL)
  256. return -1;
  257. for(i=0;i<g->max_member;i++)
  258. if( g->member[i].account_id==account_id &&
  259. g->member[i].char_id==char_id )
  260. return i;
  261. return -1;
  262. }
  263. // ギルドメンバーの役職を返す
  264. int guild_getposition(struct map_session_data *sd,struct guild *g)
  265. {
  266. int i;
  267. nullpo_retr(-1, sd);
  268. if(g==NULL && (g=guild_search(sd->status.guild_id))==NULL)
  269. return -1;
  270. for(i=0;i<g->max_member;i++)
  271. if( g->member[i].account_id==sd->status.account_id &&
  272. g->member[i].char_id==sd->status.char_id )
  273. return g->member[i].position;
  274. return -1;
  275. }
  276. // メンバー情報の作成
  277. void guild_makemember(struct guild_member *m,struct map_session_data *sd)
  278. {
  279. nullpo_retv(sd);
  280. malloc_set(m,0,sizeof(struct guild_member));
  281. m->account_id =sd->status.account_id;
  282. m->char_id =sd->status.char_id;
  283. m->hair =sd->status.hair;
  284. m->hair_color =sd->status.hair_color;
  285. m->gender =sd->status.sex;
  286. m->class_ =sd->status.class_;
  287. m->lv =sd->status.base_level;
  288. // m->exp =0;
  289. // m->exp_payper =0;
  290. m->online =1;
  291. m->position =MAX_GUILDPOSITION-1;
  292. memcpy(m->name,sd->status.name,NAME_LENGTH-1);
  293. return;
  294. }
  295. // ギルド競合確認
  296. int guild_check_conflict(struct map_session_data *sd)
  297. {
  298. nullpo_retr(0, sd);
  299. intif_guild_checkconflict(sd->status.guild_id,
  300. sd->status.account_id,sd->status.char_id);
  301. return 0;
  302. }
  303. // ギルドのEXPキャッシュをinter鯖にフラッシュする
  304. int guild_payexp_timer_sub(DBKey dataid, void *data, va_list ap)
  305. {
  306. int i;
  307. struct guild_expcache *c;
  308. struct guild *g;
  309. c = (struct guild_expcache *)data;
  310. if (
  311. (g = guild_search(c->guild_id)) == NULL ||
  312. (i = guild_getindex(g, c->account_id, c->char_id)) < 0
  313. ) {
  314. ers_free(expcache_ers, data);
  315. return 0;
  316. }
  317. if (g->member[i].exp > UINT_MAX - c->exp)
  318. g->member[i].exp = UINT_MAX;
  319. else
  320. g->member[i].exp+= c->exp;
  321. intif_guild_change_memberinfo(g->guild_id,c->account_id,c->char_id,
  322. GMI_EXP,&g->member[i].exp,sizeof(g->member[i].exp));
  323. c->exp=0;
  324. ers_free(expcache_ers, data);
  325. return 0;
  326. }
  327. int guild_payexp_timer(int tid, unsigned int tick, int id, int data)
  328. {
  329. guild_expcache_db->clear(guild_expcache_db,guild_payexp_timer_sub);
  330. return 0;
  331. }
  332. //Taken from party_send_xy_timer_sub. [Skotlex]
  333. int guild_send_xy_timer_sub(DBKey key,void *data,va_list ap)
  334. {
  335. struct guild *g=(struct guild *)data;
  336. int i;
  337. nullpo_retr(0, g);
  338. for(i=0;i<g->max_member;i++){
  339. struct map_session_data *sd;
  340. if((sd=g->member[i].sd)!=NULL){
  341. if(sd->guild_x!=sd->bl.x || sd->guild_y!=sd->bl.y){
  342. clif_guild_xy(sd);
  343. sd->guild_x=sd->bl.x;
  344. sd->guild_y=sd->bl.y;
  345. }
  346. }
  347. }
  348. return 0;
  349. }
  350. //Code from party_send_xy_timer [Skotlex]
  351. static int guild_send_xy_timer(int tid,unsigned int tick,int id,int data)
  352. {
  353. guild_db->foreach(guild_db,guild_send_xy_timer_sub,tick);
  354. return 0;
  355. }
  356. int guild_send_dot_remove(struct map_session_data *sd)
  357. {
  358. if (sd->status.guild_id)
  359. clif_guild_xy_remove(sd);
  360. return 0;
  361. }
  362. //------------------------------------------------------------------------
  363. // 作成要求
  364. int guild_create(struct map_session_data *sd,char *name)
  365. {
  366. nullpo_retr(0, sd);
  367. if(sd->status.guild_id)
  368. {
  369. clif_guild_created(sd,1); // すでに所属している
  370. return 0;
  371. }
  372. if(!battle_config.guild_emperium_check || pc_search_inventory(sd,714) >= 0) {
  373. struct guild_member m;
  374. guild_makemember(&m,sd);
  375. m.position=0;
  376. intif_guild_create(name,&m);
  377. return 1;
  378. }
  379. clif_guild_created(sd,3); // エンペリウムがいない
  380. return 0;
  381. }
  382. // 作成可否
  383. int guild_created(int account_id,int guild_id)
  384. {
  385. struct map_session_data *sd=map_id2sd(account_id);
  386. if(sd==NULL)
  387. return 0;
  388. if(!guild_id) {
  389. clif_guild_created(sd,2); // 作成失敗(同名ギルド存在)
  390. return 0;
  391. }
  392. //struct guild *g;
  393. sd->status.guild_id=guild_id;
  394. sd->state.guild_sent=0;
  395. clif_guild_created(sd,0);
  396. if(battle_config.guild_emperium_check)
  397. pc_delitem(sd,pc_search_inventory(sd,714),1,0); // エンペリウム消耗
  398. return 0;
  399. }
  400. // 情報要求
  401. int guild_request_info(int guild_id)
  402. {
  403. // if(battle_config.etc_log)
  404. // printf("guild_request_info\n");
  405. return intif_guild_request_info(guild_id);
  406. }
  407. // イベント付き情報要求
  408. int guild_npc_request_info(int guild_id,const char *event)
  409. {
  410. struct eventlist *ev;
  411. if( guild_search(guild_id) ){
  412. if(event && *event)
  413. npc_event_do(event);
  414. return 0;
  415. }
  416. if(event==NULL || *event==0)
  417. return guild_request_info(guild_id);
  418. ev=(struct eventlist *)aCalloc(sizeof(struct eventlist),1);
  419. memcpy(ev->name,event,strlen(event));
  420. //The one in the db becomes the next event from this.
  421. ev->next=idb_put(guild_infoevent_db,guild_id,ev);
  422. return guild_request_info(guild_id);
  423. }
  424. // 所属キャラの確認
  425. int guild_check_member(struct guild *g)
  426. {
  427. int i, j, users;
  428. struct map_session_data *sd, **all_sd;
  429. nullpo_retr(0, g);
  430. all_sd = map_getallusers(&users);
  431. for(i=0;i<users;i++){
  432. sd=all_sd[i];
  433. if(sd->status.guild_id==g->guild_id){
  434. j=guild_getindex(g,sd->status.account_id,sd->status.char_id);
  435. if (j < 0) {
  436. sd->status.guild_id=0;
  437. sd->state.guild_sent=0;
  438. sd->guild_emblem_id=0;
  439. if(battle_config.error_log)
  440. ShowWarning("guild: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name);
  441. }
  442. }
  443. }
  444. return 0;
  445. }
  446. // 情報所得失敗(そのIDのキャラを全部未所属にする)
  447. int guild_recv_noinfo(int guild_id)
  448. {
  449. int i, users;
  450. struct map_session_data *sd, **all_sd;
  451. all_sd = map_getallusers(&users);
  452. for(i=0;i<users;i++){
  453. if((sd=all_sd[i])){
  454. if(sd->status.guild_id==guild_id)
  455. sd->status.guild_id=0;
  456. }
  457. }
  458. return 0;
  459. }
  460. // 情報所得
  461. int guild_recv_info(struct guild *sg)
  462. {
  463. struct guild *g,before;
  464. int i,bm,m;
  465. struct eventlist *ev,*ev2;
  466. nullpo_retr(0, sg);
  467. if((g=idb_get(guild_db,sg->guild_id))==NULL){
  468. struct map_session_data *sd;
  469. g=(struct guild *)aCalloc(1,sizeof(struct guild));
  470. idb_put(guild_db,sg->guild_id,g);
  471. before=*sg;
  472. // 最初のロードなのでユーザーのチェックを行う
  473. guild_check_member(sg);
  474. //If the guild master is online the first time the guild_info is received, that means he was the first to join,
  475. //and as such, his guild skills should be blocked to avoid login/logout abuse [Skotlex]
  476. if ((sd = map_nick2sd(sg->master)) != NULL)
  477. {
  478. guild_block_skill(sd, 300000);
  479. //Also set the guild master flag.
  480. sd->state.gmaster_flag = g;
  481. clif_charnameupdate(sd); // [LuzZza]
  482. }
  483. }else
  484. before=*g;
  485. memcpy(g,sg,sizeof(struct guild));
  486. if(g->max_member > MAX_GUILD)
  487. {
  488. if (battle_config.error_log)
  489. ShowError("guild_recv_info: Received guild with %d members, but MAX_GUILD is only %d. Extra guild-members have been lost!\n", g->max_member, MAX_GUILD);
  490. g->max_member = MAX_GUILD;
  491. }
  492. for(i=bm=m=0;i<g->max_member;i++){ // sdの設定と人数の確認
  493. if(g->member[i].account_id>0){
  494. struct map_session_data *sd = map_id2sd(g->member[i].account_id);
  495. if (sd && sd->status.char_id == g->member[i].char_id &&
  496. sd->status.guild_id == g->guild_id &&
  497. !sd->state.waitingdisconnect) {
  498. g->member[i].sd = sd;
  499. clif_charnameupdate(sd); // [LuzZza]
  500. } else g->member[i].sd = NULL;
  501. m++;
  502. }else
  503. g->member[i].sd=NULL;
  504. if(before.member[i].account_id>0)
  505. bm++;
  506. }
  507. for(i=0;i<g->max_member;i++){ // 情報の送信
  508. struct map_session_data *sd = g->member[i].sd;
  509. if( sd==NULL )
  510. continue;
  511. if( before.guild_lv!=g->guild_lv || bm!=m ||
  512. before.max_member!=g->max_member ){
  513. clif_guild_basicinfo(sd); // 基本情報送信
  514. clif_guild_emblem(sd,g); // エンブレム送信
  515. }
  516. if(bm!=m){ // メンバー情報送信
  517. clif_guild_memberlist(g->member[i].sd);
  518. }
  519. if( before.skill_point!=g->skill_point)
  520. clif_guild_skillinfo(sd); // スキル情報送信
  521. if( sd->state.guild_sent==0){ // 未送信なら所属情報も送る
  522. clif_guild_belonginfo(sd,g);
  523. clif_guild_notice(sd,g);
  524. sd->guild_emblem_id=g->emblem_id;
  525. sd->state.guild_sent=1;
  526. }
  527. }
  528. // イベントの発生
  529. if( (ev=idb_remove(guild_infoevent_db,sg->guild_id))!=NULL ){
  530. while(ev){
  531. npc_event_do(ev->name);
  532. ev2=ev->next;
  533. aFree(ev);
  534. ev=ev2;
  535. }
  536. }
  537. return 0;
  538. }
  539. // ギルドへの勧誘
  540. int guild_invite(struct map_session_data *sd,struct map_session_data *tsd)
  541. {
  542. struct guild *g;
  543. int i;
  544. nullpo_retr(0, sd);
  545. g=guild_search(sd->status.guild_id);
  546. if(tsd==NULL || g==NULL)
  547. return 0;
  548. if( (i=guild_getposition(sd,g))<0 || !(g->position[i].mode&0x0001) )
  549. return 0; //Invite permission.
  550. if(!battle_config.invite_request_check) {
  551. if (tsd->party_invite>0 || tsd->trade_partner) { // 相手が取引中かどうか
  552. clif_guild_inviteack(sd,0);
  553. return 0;
  554. }
  555. }
  556. if(tsd->status.guild_id>0 ||
  557. tsd->guild_invite>0 ||
  558. map[tsd->bl.m].flag.gvg_castle)
  559. { //Can't invite people inside castles. [Skotlex]
  560. clif_guild_inviteack(sd,0);
  561. return 0;
  562. }
  563. // 定員確認
  564. for(i=0;i<g->max_member;i++)
  565. if(g->member[i].account_id==0)
  566. break;
  567. if(i==g->max_member){
  568. clif_guild_inviteack(sd,3);
  569. return 0;
  570. }
  571. tsd->guild_invite=sd->status.guild_id;
  572. tsd->guild_invite_account=sd->status.account_id;
  573. clif_guild_invite(tsd,g);
  574. return 0;
  575. }
  576. // ギルド勧誘への返答
  577. int guild_reply_invite(struct map_session_data *sd,int guild_id,int flag)
  578. {
  579. struct map_session_data *tsd;
  580. nullpo_retr(0, sd);
  581. //nullpo_retr(0, tsd= map_id2sd( sd->guild_invite_account ));
  582. //I checked the code, and there's no "check" for the case where the guy
  583. //that invites another to a guild quits the map-server before being replied.
  584. //Hence that's a valid null pointer scenario. :) [Skotlex]
  585. if ((tsd= map_id2sd( sd->guild_invite_account )) == NULL)
  586. { //Do we send a "invitation failed" msg or something to the player?
  587. //Or should we accept the invitation and add it to the guild anyway?
  588. //afterall, guild_invite holds the guild id that the player was invited to.
  589. sd->guild_invite=0;
  590. sd->guild_invite_account=0;
  591. return 0;
  592. }
  593. if(sd->guild_invite!=guild_id) // 勧誘とギルドIDが違う
  594. return 0;
  595. if(flag==1){ // 承諾
  596. struct guild_member m;
  597. struct guild *g;
  598. int i;
  599. // 定員確認
  600. if( (g=guild_search(tsd->status.guild_id))==NULL ){
  601. sd->guild_invite=0;
  602. sd->guild_invite_account=0;
  603. return 0;
  604. }
  605. for(i=0;i<g->max_member;i++)
  606. if(g->member[i].account_id==0)
  607. break;
  608. if(i==g->max_member){
  609. sd->guild_invite=0;
  610. sd->guild_invite_account=0;
  611. clif_guild_inviteack(tsd,3);
  612. return 0;
  613. }
  614. //inter鯖へ追加要求
  615. guild_makemember(&m,sd);
  616. intif_guild_addmember( sd->guild_invite, &m );
  617. return 0;
  618. }else{ // 拒否
  619. sd->guild_invite=0;
  620. sd->guild_invite_account=0;
  621. clif_guild_inviteack(tsd,1);
  622. }
  623. return 0;
  624. }
  625. // ギルドメンバが追加された
  626. int guild_member_added(int guild_id,int account_id,int char_id,int flag)
  627. {
  628. struct map_session_data *sd= map_id2sd(account_id),*sd2;
  629. struct guild *g;
  630. if( (g=guild_search(guild_id))==NULL )
  631. return 0;
  632. if(sd==NULL || sd->guild_invite==0){
  633. // キャラ側に登録できなかったため脱退要求を出す
  634. if (flag == 0) {
  635. if(battle_config.error_log)
  636. ShowError("guild: member added error %d is not online\n",account_id);
  637. intif_guild_leave(guild_id,account_id,char_id,0,"**登録失敗**");
  638. }
  639. return 0;
  640. }
  641. sd2 = map_id2sd(sd->guild_invite_account);
  642. sd->guild_invite = 0;
  643. sd->guild_invite_account = 0;
  644. if(flag==1){ // 失敗
  645. if( sd2!=NULL )
  646. clif_guild_inviteack(sd2,3);
  647. return 0;
  648. }
  649. // 成功
  650. sd->state.guild_sent=0;
  651. sd->status.guild_id=guild_id;
  652. if( sd2!=NULL )
  653. clif_guild_inviteack(sd2,2);
  654. // いちおう競合確認
  655. guild_check_conflict(sd);
  656. //Next line commented because it do nothing, look at guild_recv_info [LuzZza]
  657. //clif_charnameupdate(sd); //Update display name [Skotlex]
  658. return 0;
  659. }
  660. // ギルド脱退要求
  661. int guild_leave(struct map_session_data *sd,int guild_id,
  662. int account_id,int char_id,const char *mes)
  663. {
  664. struct guild *g;
  665. nullpo_retr(0, sd);
  666. g = guild_search(sd->status.guild_id);
  667. if(g==NULL)
  668. return 0;
  669. if(sd->status.account_id!=account_id ||
  670. sd->status.char_id!=char_id || sd->status.guild_id!=guild_id ||
  671. map[sd->bl.m].flag.gvg_castle) //Can't leave inside guild castles.
  672. return 0;
  673. intif_guild_leave(sd->status.guild_id, sd->status.account_id, sd->status.char_id,0,mes);
  674. return 0;
  675. }
  676. // ギルド追放要求
  677. int guild_expulsion(struct map_session_data *sd,int guild_id,
  678. int account_id,int char_id,const char *mes)
  679. {
  680. struct guild *g;
  681. int i,ps;
  682. nullpo_retr(0, sd);
  683. g = guild_search(sd->status.guild_id);
  684. if(g==NULL)
  685. return 0;
  686. if(sd->status.guild_id!=guild_id || map[sd->bl.m].flag.gvg_castle) //Can't leave inside guild castles.
  687. return 0;
  688. if( (ps=guild_getposition(sd,g))<0 || !(g->position[ps].mode&0x0010) )
  689. return 0; //Expulsion permission
  690. for(i=0;i<g->max_member;i++){ // 所属しているか
  691. if(g->member[i].account_id==account_id &&
  692. g->member[i].char_id==char_id ){
  693. if(!strcmp(g->member[i].name,g->master))
  694. return 0; //Can't expel the GM!
  695. intif_guild_leave(g->guild_id,account_id,char_id,1,mes);
  696. return 0;
  697. }
  698. }
  699. return 0;
  700. }
  701. int guild_member_leaved(int guild_id,int account_id,int char_id,int flag,
  702. const char *name,const char *mes) // rewrote [LuzZza]
  703. {
  704. int i;
  705. struct guild *g = guild_search(guild_id);
  706. struct map_session_data *sd = map_charid2sd(char_id);
  707. struct map_session_data *online_member_sd;
  708. if(g == NULL)
  709. return 0;
  710. for(i=0;i<g->max_member;i++) {
  711. if( g->member[i].account_id == account_id &&
  712. g->member[i].char_id == char_id ){
  713. if((online_member_sd = guild_getavailablesd(g)) == NULL)
  714. return 0;
  715. if(!flag)
  716. clif_guild_leave(online_member_sd, name, mes);
  717. else
  718. clif_guild_expulsion(online_member_sd, name, mes, account_id);
  719. malloc_set(&g->member[i],0,sizeof(struct guild_member));
  720. clif_guild_memberlist(online_member_sd);
  721. if(sd != NULL && sd->status.guild_id == guild_id) {
  722. if (sd->state.storage_flag == 2) //Close the guild storage.
  723. storage_guild_storageclose(sd);
  724. sd->status.guild_id=0;
  725. sd->guild_emblem_id=0;
  726. sd->state.guild_sent=0;
  727. guild_send_dot_remove(sd);
  728. clif_charnameupdate(sd); //Update display name [Skotlex]
  729. }
  730. return 0;
  731. }
  732. }
  733. return 0;
  734. }
  735. int guild_send_memberinfoshort(struct map_session_data *sd,int online)
  736. { // cleaned up [LuzZza]
  737. struct guild *g;
  738. nullpo_retr(0, sd);
  739. if(!(g = guild_search(sd->status.guild_id)))
  740. return 0;
  741. //Moved to place before intif_guild_memberinfoshort because
  742. //If it's not a member, needn't send it's info to intif. [LuzZza]
  743. guild_check_member(g);
  744. if(sd->status.guild_id <= 0)
  745. return 0;
  746. intif_guild_memberinfoshort(g->guild_id,
  747. sd->status.account_id,sd->status.char_id,online,sd->status.base_level,sd->status.class_);
  748. if(!online){
  749. int i=guild_getindex(g,sd->status.account_id,sd->status.char_id);
  750. if(i>=0)
  751. g->member[i].sd=NULL;
  752. return 0;
  753. }
  754. if(sd->state.guild_sent)
  755. return 0;
  756. clif_guild_belonginfo(sd,g);
  757. clif_guild_notice(sd,g);
  758. sd->state.guild_sent = 1;
  759. sd->guild_emblem_id = g->emblem_id;
  760. return 0;
  761. }
  762. int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_)
  763. { // cleaned up [LuzZza]
  764. int i,alv,c,idx=-1,om=0,oldonline=-1;
  765. struct guild *g = guild_search(guild_id);
  766. if(g == NULL)
  767. return 0;
  768. for(i=0,alv=0,c=0,om=0;i<g->max_member;i++){
  769. struct guild_member *m=&g->member[i];
  770. if(m->account_id==account_id && m->char_id==char_id ){
  771. oldonline=m->online;
  772. m->online=online;
  773. m->lv=lv;
  774. m->class_=class_;
  775. idx=i;
  776. }
  777. if(m->account_id>0){
  778. alv+=m->lv;
  779. c++;
  780. }
  781. if(m->online)
  782. om++;
  783. }
  784. if(idx == -1 || c == 0) {
  785. // ギルドのメンバー外なので追放扱いする
  786. struct map_session_data *sd = map_id2sd(account_id);
  787. if(sd && sd->status.char_id == char_id) {
  788. sd->status.guild_id=0;
  789. sd->guild_emblem_id=0;
  790. sd->state.guild_sent=0;
  791. }
  792. if(battle_config.error_log)
  793. ShowWarning("guild: not found member %d,%d on %d[%s]\n", account_id,char_id,guild_id,g->name);
  794. return 0;
  795. }
  796. g->average_lv=alv/c;
  797. g->connect_member=om;
  798. for(i=0;i<g->max_member;i++) {
  799. struct map_session_data *sd= map_id2sd(g->member[i].account_id);
  800. g->member[i].sd = (sd && sd->status.char_id == g->member[i].char_id &&
  801. sd->status.guild_id == g->guild_id && !sd->state.waitingdisconnect) ? sd : NULL;
  802. }
  803. if(oldonline!=online)
  804. clif_guild_memberlogin_notice(g, idx, online);
  805. if(!g->member[idx].sd)
  806. return 0;
  807. //Send XY dot updates. [Skotlex]
  808. //Moved from guild_send_memberinfoshort [LuzZza]
  809. for(i=0; i < g->max_member; i++) {
  810. if(!g->member[i].sd || i == idx ||
  811. g->member[i].sd->bl.m != g->member[idx].sd->bl.m)
  812. continue;
  813. clif_guild_xy_single(g->member[idx].sd->fd, g->member[i].sd);
  814. }
  815. return 0;
  816. }
  817. // ギルド会話送信
  818. int guild_send_message(struct map_session_data *sd,char *mes,int len)
  819. {
  820. nullpo_retr(0, sd);
  821. if(sd->status.guild_id==0)
  822. return 0;
  823. intif_guild_message(sd->status.guild_id,sd->status.account_id,mes,len);
  824. guild_recv_message(sd->status.guild_id,sd->status.account_id,mes,len);
  825. //Chatlogging type 'G'
  826. if(log_config.chat&1 //we log everything then
  827. || ( log_config.chat&8 //if Guild bit is on
  828. && ( !agit_flag || !(log_config.chat&16) ))) //if WOE ONLY flag is off or AGIT is OFF
  829. log_chat("G", sd->status.guild_id, sd->status.char_id, sd->status.account_id, (char*)mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, mes);
  830. return 0;
  831. }
  832. // ギルド会話受信
  833. int guild_recv_message(int guild_id,int account_id,char *mes,int len)
  834. {
  835. struct guild *g;
  836. if( (g=guild_search(guild_id))==NULL)
  837. return 0;
  838. clif_guild_message(g,account_id,mes,len);
  839. return 0;
  840. }
  841. // ギルドメンバの役職変更
  842. int guild_change_memberposition(int guild_id,int account_id,int char_id,int idx)
  843. {
  844. return intif_guild_change_memberinfo(
  845. guild_id,account_id,char_id,GMI_POSITION,&idx,sizeof(idx));
  846. }
  847. // ギルドメンバの役職変更通知
  848. int guild_memberposition_changed(struct guild *g,int idx,int pos)
  849. {
  850. nullpo_retr(0, g);
  851. g->member[idx].position=pos;
  852. clif_guild_memberpositionchanged(g,idx);
  853. // Update char position in client [LuzZza]
  854. if(g->member[idx].sd != NULL)
  855. clif_charnameupdate(g->member[idx].sd);
  856. return 0;
  857. }
  858. // ギルド役職変更
  859. int guild_change_position(int guild_id,int idx,
  860. int mode,int exp_mode,const char *name)
  861. {
  862. struct guild_position p;
  863. exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit);
  864. //Mode 0x01 <- Invite
  865. //Mode 0x10 <- Expel.
  866. p.mode=mode&0x11;
  867. p.exp_mode=exp_mode;
  868. memcpy(p.name,name,NAME_LENGTH-1);
  869. p.name[NAME_LENGTH-1] = '\0'; //Security check... [Skotlex]
  870. return intif_guild_position(guild_id,idx,&p);
  871. }
  872. // ギルド役職変更通知
  873. int guild_position_changed(int guild_id,int idx,struct guild_position *p)
  874. {
  875. struct guild *g=guild_search(guild_id);
  876. int i;
  877. if(g==NULL)
  878. return 0;
  879. memcpy(&g->position[idx],p,sizeof(struct guild_position));
  880. clif_guild_positionchanged(g,idx);
  881. // Update char name in client [LuzZza]
  882. for(i=0;i<g->max_member;i++)
  883. if(g->member[i].position == idx && g->member[i].sd != NULL)
  884. clif_charnameupdate(g->member[i].sd);
  885. return 0;
  886. }
  887. // ギルド告知変更
  888. int guild_change_notice(struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2)
  889. {
  890. nullpo_retr(0, sd);
  891. if(guild_id!=sd->status.guild_id)
  892. return 0;
  893. return intif_guild_notice(guild_id,mes1,mes2);
  894. }
  895. // ギルド告知変更通知
  896. int guild_notice_changed(int guild_id,const char *mes1,const char *mes2)
  897. {
  898. int i;
  899. struct map_session_data *sd;
  900. struct guild *g=guild_search(guild_id);
  901. if(g==NULL)
  902. return 0;
  903. memcpy(g->mes1,mes1,60);
  904. memcpy(g->mes2,mes2,120);
  905. for(i=0;i<g->max_member;i++){
  906. if((sd=g->member[i].sd)!=NULL)
  907. clif_guild_notice(sd,g);
  908. }
  909. return 0;
  910. }
  911. // ギルドエンブレム変更
  912. int guild_change_emblem(struct map_session_data *sd,int len,const char *data)
  913. {
  914. struct guild *g;
  915. nullpo_retr(0, sd);
  916. if (battle_config.require_glory_guild &&
  917. !((g = guild_search(sd->status.guild_id)) && guild_checkskill(g, GD_GLORYGUILD)>0)) {
  918. clif_skill_fail(sd,GD_GLORYGUILD,0,0);
  919. return 0;
  920. }
  921. return intif_guild_emblem(sd->status.guild_id,len,data);
  922. }
  923. // ギルドエンブレム変更通知
  924. int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data)
  925. {
  926. int i;
  927. struct map_session_data *sd;
  928. struct guild *g=guild_search(guild_id);
  929. if(g==NULL)
  930. return 0;
  931. memcpy(g->emblem_data,data,len);
  932. g->emblem_len=len;
  933. g->emblem_id=emblem_id;
  934. for(i=0;i<g->max_member;i++){
  935. if((sd=g->member[i].sd)!=NULL){
  936. sd->guild_emblem_id=emblem_id;
  937. clif_guild_belonginfo(sd,g);
  938. clif_guild_emblem(sd,g);
  939. }
  940. }
  941. return 0;
  942. }
  943. static void* create_expcache(DBKey key, va_list args) {
  944. struct guild_expcache *c;
  945. struct map_session_data *sd = va_arg(args, struct map_session_data*);
  946. c = ers_alloc(expcache_ers, struct guild_expcache);
  947. c->guild_id = sd->status.guild_id;
  948. c->account_id = sd->status.account_id;
  949. c->char_id = sd->status.char_id;
  950. c->exp = 0;
  951. return c;
  952. }
  953. // ギルドのEXP上納
  954. unsigned int guild_payexp(struct map_session_data *sd,unsigned int exp)
  955. {
  956. struct guild *g;
  957. struct guild_expcache *c;
  958. int per;
  959. nullpo_retr(0, sd);
  960. if (!exp) return 0;
  961. if (sd->status.guild_id == 0 ||
  962. (g = guild_search(sd->status.guild_id)) == NULL ||
  963. (per = guild_getposition(sd,g)) < 0 ||
  964. (per = g->position[per].exp_mode) < 1)
  965. return 0;
  966. if (per < 100)
  967. exp = (unsigned int) exp * per / 100;
  968. //Otherwise tax everything.
  969. c = guild_expcache_db->ensure(guild_expcache_db, i2key(sd->status.char_id), create_expcache, sd);
  970. if (c->exp > UINT_MAX - exp)
  971. c->exp = UINT_MAX;
  972. else
  973. c->exp += exp;
  974. return exp;
  975. }
  976. // Celest
  977. int guild_getexp(struct map_session_data *sd,int exp)
  978. {
  979. struct guild *g;
  980. struct guild_expcache *c;
  981. nullpo_retr(0, sd);
  982. if (sd->status.guild_id == 0 || (g = guild_search(sd->status.guild_id)) == NULL)
  983. return 0;
  984. c = guild_expcache_db->ensure(guild_expcache_db, i2key(sd->status.char_id), create_expcache, sd);
  985. if (c->exp > UINT_MAX - exp)
  986. c->exp = UINT_MAX;
  987. else
  988. c->exp += exp;
  989. return exp;
  990. }
  991. // スキルポイント割り振り
  992. int guild_skillup(struct map_session_data *sd,int skill_num,int flag)
  993. {
  994. struct guild *g;
  995. int idx = skill_num - GD_SKILLBASE;
  996. nullpo_retr(0, sd);
  997. if(idx < 0 || idx >= MAX_GUILDSKILL)
  998. return 0;
  999. if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL)
  1000. return 0;
  1001. if(strcmp(sd->status.name,g->master))
  1002. return 0;
  1003. if( (g->skill_point>0 || flag&1) &&
  1004. g->skill[idx].id!=0 &&
  1005. g->skill[idx].lv < guild_skill_get_max(skill_num) ){
  1006. intif_guild_skillup(g->guild_id,skill_num,sd->status.account_id,flag);
  1007. }
  1008. return 0;
  1009. }
  1010. // スキルポイント割り振り通知
  1011. int guild_skillupack(int guild_id,int skill_num,int account_id)
  1012. {
  1013. struct map_session_data *sd=map_id2sd(account_id);
  1014. struct guild *g=guild_search(guild_id);
  1015. int i;
  1016. if(g==NULL)
  1017. return 0;
  1018. if(sd!=NULL)
  1019. clif_guild_skillup(sd,skill_num,g->skill[skill_num-GD_SKILLBASE].lv);
  1020. // 全員に通知
  1021. for(i=0;i<g->max_member;i++)
  1022. if((sd=g->member[i].sd)!=NULL)
  1023. clif_guild_skillinfo(sd);
  1024. return 0;
  1025. }
  1026. // ギルド同盟数所得
  1027. int guild_get_alliance_count(struct guild *g,int flag)
  1028. {
  1029. int i,c;
  1030. nullpo_retr(0, g);
  1031. for(i=c=0;i<MAX_GUILDALLIANCE;i++){
  1032. if( g->alliance[i].guild_id>0 &&
  1033. g->alliance[i].opposition==flag )
  1034. c++;
  1035. }
  1036. return c;
  1037. }
  1038. // Blocks all guild skills which have a common delay time.
  1039. void guild_block_skill(struct map_session_data *sd, int time) {
  1040. int skill_num[] = { GD_BATTLEORDER, GD_REGENERATION, GD_RESTORE, GD_EMERGENCYCALL };
  1041. int i;
  1042. for (i = 0; i < 4; i++)
  1043. skill_blockpc_start(sd, skill_num[i], time);
  1044. }
  1045. // 同盟関係かどうかチェック
  1046. // 同盟なら1、それ以外は0
  1047. int guild_check_alliance(int guild_id1, int guild_id2, int flag)
  1048. {
  1049. struct guild *g;
  1050. int i;
  1051. g = guild_search(guild_id1);
  1052. if (g == NULL)
  1053. return 0;
  1054. for (i=0; i<MAX_GUILDALLIANCE; i++)
  1055. if ((g->alliance[i].guild_id == guild_id2) && (g->alliance[i].opposition == flag))
  1056. return 1;
  1057. return 0;
  1058. }
  1059. // ギルド同盟要求
  1060. int guild_reqalliance(struct map_session_data *sd,struct map_session_data *tsd)
  1061. {
  1062. struct guild *g[2];
  1063. int i;
  1064. if(agit_flag) { // Disable alliance creation during woe [Valaris]
  1065. clif_displaymessage(sd->fd,"Alliances cannot be made during Guild Wars!");
  1066. return 0;
  1067. } // end addition [Valaris]
  1068. nullpo_retr(0, sd);
  1069. if(tsd==NULL || tsd->status.guild_id<=0)
  1070. return 0;
  1071. g[0]=guild_search(sd->status.guild_id);
  1072. g[1]=guild_search(tsd->status.guild_id);
  1073. if(g[0]==NULL || g[1]==NULL)
  1074. return 0;
  1075. // Prevent creation alliance with same guilds [LuzZza]
  1076. if(sd->status.guild_id == tsd->status.guild_id)
  1077. return 0;
  1078. if( guild_get_alliance_count(g[0],0)>=3 ) {
  1079. clif_guild_allianceack(sd,4);
  1080. return 0;
  1081. }
  1082. if( guild_get_alliance_count(g[1],0)>=3 ) {
  1083. clif_guild_allianceack(sd,3);
  1084. return 0;
  1085. }
  1086. if( tsd->guild_alliance>0 ){
  1087. clif_guild_allianceack(sd,1);
  1088. return 0;
  1089. }
  1090. for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに同盟状態か確認
  1091. if( g[0]->alliance[i].guild_id==tsd->status.guild_id &&
  1092. g[0]->alliance[i].opposition==0){
  1093. clif_guild_allianceack(sd,0);
  1094. return 0;
  1095. }
  1096. }
  1097. tsd->guild_alliance=sd->status.guild_id;
  1098. tsd->guild_alliance_account=sd->status.account_id;
  1099. clif_guild_reqalliance(tsd,sd->status.account_id,g[0]->name);
  1100. return 0;
  1101. }
  1102. // ギルド勧誘への返答
  1103. int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag)
  1104. {
  1105. struct map_session_data *tsd;
  1106. nullpo_retr(0, sd);
  1107. tsd= map_id2sd( account_id );
  1108. if (!tsd) { //Character left? Cancel alliance.
  1109. clif_guild_allianceack(sd,3);
  1110. return 0;
  1111. }
  1112. if(sd->guild_alliance!=tsd->status.guild_id) // 勧誘とギルドIDが違う
  1113. return 0;
  1114. if(flag==1){ // 承諾
  1115. int i;
  1116. struct guild *g,*tg; // 同盟数再確認
  1117. g=guild_search(sd->status.guild_id);
  1118. tg=guild_search(tsd->status.guild_id);
  1119. if(g==NULL || guild_get_alliance_count(g,0)>=3){
  1120. clif_guild_allianceack(sd,4);
  1121. clif_guild_allianceack(tsd,3);
  1122. return 0;
  1123. }
  1124. if(tg==NULL || guild_get_alliance_count(tg,0)>=3){
  1125. clif_guild_allianceack(sd,3);
  1126. clif_guild_allianceack(tsd,4);
  1127. return 0;
  1128. }
  1129. for(i=0;i<MAX_GUILDALLIANCE;i++){
  1130. if(g->alliance[i].guild_id==tsd->status.guild_id &&
  1131. g->alliance[i].opposition==1)
  1132. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  1133. sd->status.account_id,tsd->status.account_id,9 );
  1134. }
  1135. for(i=0;i<MAX_GUILDALLIANCE;i++){
  1136. if(tg->alliance[i].guild_id==sd->status.guild_id &&
  1137. tg->alliance[i].opposition==1)
  1138. intif_guild_alliance( tsd->status.guild_id,sd->status.guild_id,
  1139. tsd->status.account_id,sd->status.account_id,9 );
  1140. }
  1141. // inter鯖へ同盟要請
  1142. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  1143. sd->status.account_id,tsd->status.account_id,0 );
  1144. return 0;
  1145. }else{ // 拒否
  1146. sd->guild_alliance=0;
  1147. sd->guild_alliance_account=0;
  1148. if(tsd!=NULL)
  1149. clif_guild_allianceack(tsd,3);
  1150. }
  1151. return 0;
  1152. }
  1153. // ギルド関係解消
  1154. int guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
  1155. {
  1156. nullpo_retr(0, sd);
  1157. if(agit_flag) { // Disable alliance breaking during woe [Valaris]
  1158. clif_displaymessage(sd->fd,"Alliances cannot be broken during Guild Wars!");
  1159. return 0;
  1160. } // end addition [Valaris]
  1161. intif_guild_alliance( sd->status.guild_id,guild_id,
  1162. sd->status.account_id,0,flag|8 );
  1163. return 0;
  1164. }
  1165. // ギルド敵対
  1166. int guild_opposition(struct map_session_data *sd,struct map_session_data *tsd)
  1167. {
  1168. struct guild *g;
  1169. int i;
  1170. nullpo_retr(0, sd);
  1171. g=guild_search(sd->status.guild_id);
  1172. if(g==NULL || tsd==NULL)
  1173. return 0;
  1174. // Prevent creation opposition with same guilds [LuzZza]
  1175. if(sd->status.guild_id == tsd->status.guild_id)
  1176. return 0;
  1177. if( guild_get_alliance_count(g,1)>=3 ) {
  1178. clif_guild_oppositionack(sd,1);
  1179. return 0;
  1180. }
  1181. if(agit_flag) {
  1182. clif_displaymessage(sd->fd,"You cannot make oppositions during Guild Wars!");
  1183. return 0;
  1184. }
  1185. for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに関係を持っているか確認
  1186. if(g->alliance[i].guild_id==tsd->status.guild_id){
  1187. if(g->alliance[i].opposition==1){ // すでに敵対
  1188. clif_guild_oppositionack(sd,2);
  1189. return 0;
  1190. }
  1191. //Change alliance to opposition.
  1192. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  1193. sd->status.account_id,tsd->status.account_id,8 );
  1194. }
  1195. }
  1196. // inter鯖に敵対要請
  1197. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  1198. sd->status.account_id,tsd->status.account_id,1 );
  1199. return 0;
  1200. }
  1201. // ギルド同盟/敵対通知
  1202. int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id2,
  1203. int flag,const char *name1,const char *name2)
  1204. {
  1205. struct guild *g[2];
  1206. int guild_id[2];
  1207. const char *guild_name[2];
  1208. struct map_session_data *sd[2];
  1209. int j,i;
  1210. guild_id[0] = guild_id1;
  1211. guild_id[1] = guild_id2;
  1212. guild_name[0] = name1;
  1213. guild_name[1] = name2;
  1214. sd[0] = map_id2sd(account_id1);
  1215. sd[1] = map_id2sd(account_id2);
  1216. g[0]=guild_search(guild_id1);
  1217. g[1]=guild_search(guild_id2);
  1218. if(sd[0]!=NULL && (flag&0x0f)==0){
  1219. sd[0]->guild_alliance=0;
  1220. sd[0]->guild_alliance_account=0;
  1221. }
  1222. if(flag&0x70){ // 失敗
  1223. for(i=0;i<2-(flag&1);i++)
  1224. if( sd[i]!=NULL )
  1225. clif_guild_allianceack(sd[i],((flag>>4)==i+1)?3:4);
  1226. return 0;
  1227. }
  1228. // if(battle_config.etc_log)
  1229. // printf("guild alliance_ack %d %d %d %d %d %s %s\n",guild_id1,guild_id2,account_id1,account_id2,flag,name1,name2);
  1230. if(!(flag&0x08)){ // 関係追加
  1231. for(i=0;i<2-(flag&1);i++)
  1232. if(g[i]!=NULL)
  1233. for(j=0;j<MAX_GUILDALLIANCE;j++)
  1234. if(g[i]->alliance[j].guild_id==0){
  1235. g[i]->alliance[j].guild_id=guild_id[1-i];
  1236. memcpy(g[i]->alliance[j].name,guild_name[1-i],NAME_LENGTH-1);
  1237. g[i]->alliance[j].opposition=flag&1;
  1238. break;
  1239. }
  1240. }else{ // 関係解消
  1241. for(i=0;i<2-(flag&1);i++){
  1242. if(g[i]!=NULL)
  1243. for(j=0;j<MAX_GUILDALLIANCE;j++)
  1244. if( g[i]->alliance[j].guild_id==guild_id[1-i] &&
  1245. g[i]->alliance[j].opposition==(flag&1)){
  1246. g[i]->alliance[j].guild_id=0;
  1247. break;
  1248. }
  1249. if( sd[i]!=NULL ) // 解消通知
  1250. clif_guild_delalliance(sd[i],guild_id[1-i],(flag&1));
  1251. }
  1252. }
  1253. if((flag&0x0f)==0){ // 同盟通知
  1254. if( sd[1]!=NULL )
  1255. clif_guild_allianceack(sd[1],2);
  1256. }else if((flag&0x0f)==1){ // 敵対通知
  1257. if( sd[0]!=NULL )
  1258. clif_guild_oppositionack(sd[0],0);
  1259. }
  1260. for(i=0;i<2-(flag&1);i++){ // 同盟/敵対リストの再送信
  1261. struct map_session_data *sd;
  1262. if(g[i]!=NULL)
  1263. for(j=0;j<g[i]->max_member;j++)
  1264. if((sd=g[i]->member[j].sd)!=NULL)
  1265. clif_guild_allianceinfo(sd);
  1266. }
  1267. return 0;
  1268. }
  1269. // ギルド解散通知用
  1270. int guild_broken_sub(DBKey key,void *data,va_list ap)
  1271. {
  1272. struct guild *g=(struct guild *)data;
  1273. int guild_id=va_arg(ap,int);
  1274. int i,j;
  1275. struct map_session_data *sd=NULL;
  1276. nullpo_retr(0, g);
  1277. for(i=0;i<MAX_GUILDALLIANCE;i++){ // 関係を破棄
  1278. if(g->alliance[i].guild_id==guild_id){
  1279. for(j=0;j<g->max_member;j++)
  1280. if( (sd=g->member[j].sd)!=NULL )
  1281. clif_guild_delalliance(sd,guild_id,g->alliance[i].opposition);
  1282. intif_guild_alliance(g->guild_id, guild_id,0,0,g->alliance[i].opposition|8);
  1283. g->alliance[i].guild_id=0;
  1284. }
  1285. }
  1286. return 0;
  1287. }
  1288. //Invoked on Castles when a guild is broken. [Skotlex]
  1289. int castle_guild_broken_sub(DBKey key,void *data,va_list ap)
  1290. {
  1291. struct guild_castle *gc=(struct guild_castle *)data;
  1292. int guild_id=va_arg(ap,int);
  1293. nullpo_retr(0, gc);
  1294. if (gc->guild_id == guild_id)
  1295. { //Save the new 'owner', this should invoke guardian clean up and other such things.
  1296. gc->guild_id = 0;
  1297. guild_castledatasave(gc->castle_id, 1, 0);
  1298. }
  1299. return 0;
  1300. }
  1301. //Innvoked on /breakguild "Guild name"
  1302. int guild_broken(int guild_id,int flag)
  1303. {
  1304. struct guild *g=guild_search(guild_id);
  1305. // struct guild_castle *gc=NULL;
  1306. struct map_session_data *sd;
  1307. int i;
  1308. // char *name;;
  1309. if(flag!=0 || g==NULL)
  1310. return 0;
  1311. //we call castle_event::OnGuildBreak of all castlesof the guild
  1312. //you can set all castle_events in the castle_db.txt
  1313. /* name=(char *)aCalloc(50,sizeof(char)); //24 char = event name, + space for "::OnGuildBreak"
  1314. for(i=0;i<MAX_GUILDCASTLE;i++){
  1315. if( (gc=guild_castle_search(i)) != NULL ){
  1316. if(gc->guild_id == guild_id){
  1317. memcpy(name,gc->castle_event,50);
  1318. npc_event_do(strcat(name,"::OnGuildBreak"));
  1319. }
  1320. }
  1321. }
  1322. free(name);
  1323. */
  1324. for(i=0;i<g->max_member;i++){ // ギルド解散を通知
  1325. if((sd=g->member[i].sd)!=NULL){
  1326. if(sd->state.storage_flag == 2)
  1327. storage_guild_storage_quit(sd,1);
  1328. sd->status.guild_id=0;
  1329. sd->state.guild_sent=0;
  1330. clif_guild_broken(g->member[i].sd,0);
  1331. clif_charnameupdate(sd); // [LuzZza]
  1332. }
  1333. }
  1334. guild_db->foreach(guild_db,guild_broken_sub,guild_id);
  1335. castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id);
  1336. guild_storage_delete(guild_id);
  1337. idb_remove(guild_db,guild_id);
  1338. return 0;
  1339. }
  1340. //Changes the Guild Master to the specified player. [Skotlex]
  1341. int guild_gm_change(int guild_id, struct map_session_data *sd)
  1342. {
  1343. struct guild *g;
  1344. nullpo_retr(0, sd);
  1345. if (sd->status.guild_id != guild_id)
  1346. return 0;
  1347. g=guild_search(guild_id);
  1348. nullpo_retr(0, g);
  1349. if (strcmp(g->master, sd->status.name) == 0) //Nothing to change.
  1350. return 0;
  1351. //Notify servers that master has changed.
  1352. intif_guild_change_gm(guild_id, sd->status.name, strlen(sd->status.name));
  1353. return 1;
  1354. }
  1355. //Notification from Char server that a guild's master has changed. [Skotlex]
  1356. int guild_gm_changed(int guild_id, int pos)
  1357. {
  1358. struct guild *g;
  1359. struct guild_member gm;
  1360. g=guild_search(guild_id);
  1361. if (!g || pos < 0 || pos > g->max_member)
  1362. return 0;
  1363. memcpy(&gm, &g->member[pos], sizeof (struct guild_member));
  1364. memcpy(&g->member[pos], &g->member[0], sizeof(struct guild_member));
  1365. memcpy(&g->member[0], &gm, sizeof(struct guild_member));
  1366. g->member[pos].position = g->member[0].position;
  1367. g->member[0].position = 0; //Position 0: guild Master.
  1368. strcpy(g->master, g->member[0].name);
  1369. if (g->member[pos].sd && g->member[pos].sd->fd)
  1370. {
  1371. clif_displaymessage(g->member[pos].sd->fd, "You no longer are the Guild Master.");
  1372. g->member[pos].sd->state.gmaster_flag = 0;
  1373. }
  1374. if (g->member[0].sd && g->member[0].sd->fd)
  1375. {
  1376. clif_displaymessage(g->member[0].sd->fd, "You have become the Guild Master!");
  1377. g->member[0].sd->state.gmaster_flag = g;
  1378. //Block his skills for 5 minutes to prevent abuse.
  1379. guild_block_skill(g->member[0].sd, 300000);
  1380. }
  1381. return 1;
  1382. }
  1383. // ギルド解散
  1384. int guild_break(struct map_session_data *sd,char *name)
  1385. {
  1386. struct guild *g;
  1387. int i;
  1388. nullpo_retr(0, sd);
  1389. if( (g=guild_search(sd->status.guild_id))==NULL )
  1390. return 0;
  1391. if(strcmp(g->name,name)!=0)
  1392. return 0;
  1393. if(!sd->state.gmaster_flag)
  1394. return 0;
  1395. for(i=0;i<g->max_member;i++){
  1396. if( g->member[i].account_id>0 && (
  1397. g->member[i].account_id!=sd->status.account_id ||
  1398. g->member[i].char_id!=sd->status.char_id ))
  1399. break;
  1400. }
  1401. if(i<g->max_member){
  1402. clif_guild_broken(sd,2);
  1403. return 0;
  1404. }
  1405. intif_guild_break(g->guild_id);
  1406. return 0;
  1407. }
  1408. // ギルド城データ要求
  1409. int guild_castledataload(int castle_id,int index)
  1410. {
  1411. return intif_guild_castle_dataload(castle_id,index);
  1412. }
  1413. // ギルド城情報所得時イベント追加
  1414. int guild_addcastleinfoevent(int castle_id,int index,const char *name)
  1415. {
  1416. struct eventlist *ev;
  1417. int code=castle_id|(index<<16);
  1418. if( name==NULL || *name==0 )
  1419. return 0;
  1420. ev=(struct eventlist *)aMalloc(sizeof(struct eventlist));
  1421. memcpy(ev->name,name,sizeof(ev->name));
  1422. //The next event becomes whatever was currently stored.
  1423. ev->next= idb_put(guild_castleinfoevent_db,code,ev);
  1424. return 0;
  1425. }
  1426. // ギルド城データ要求返信
  1427. int guild_castledataloadack(int castle_id,int index,int value)
  1428. {
  1429. struct guild_castle *gc=guild_castle_search(castle_id);
  1430. int code=castle_id|(index<<16);
  1431. struct eventlist *ev,*ev2;
  1432. if(gc==NULL){
  1433. return 0;
  1434. }
  1435. switch(index){
  1436. case 1:
  1437. gc->guild_id = value;
  1438. if (value && guild_search(value)==NULL) //Request guild data which will be required for spawned guardians. [Skotlex]
  1439. guild_request_info(value);
  1440. break;
  1441. case 2: gc->economy = value; break;
  1442. case 3: gc->defense = value; break;
  1443. case 4: gc->triggerE = value; break;
  1444. case 5: gc->triggerD = value; break;
  1445. case 6: gc->nextTime = value; break;
  1446. case 7: gc->payTime = value; break;
  1447. case 8: gc->createTime = value; break;
  1448. case 9: gc->visibleC = value; break;
  1449. case 10:
  1450. case 11:
  1451. case 12:
  1452. case 13:
  1453. case 14:
  1454. case 15:
  1455. case 16:
  1456. case 17:
  1457. gc->guardian[index-10].visible = value; break;
  1458. case 18:
  1459. case 19:
  1460. case 20:
  1461. case 21:
  1462. case 22:
  1463. case 23:
  1464. case 24:
  1465. case 25:
  1466. gc->guardian[index-18].hp = value; break;
  1467. default:
  1468. ShowError("guild_castledataloadack ERROR!! (Not found index=%d)\n", index);
  1469. return 0;
  1470. }
  1471. if( (ev=idb_remove(guild_castleinfoevent_db,code))!=NULL ){
  1472. while(ev){
  1473. npc_event_do(ev->name);
  1474. ev2=ev->next;
  1475. aFree(ev);
  1476. ev=ev2;
  1477. }
  1478. }
  1479. return 1;
  1480. }
  1481. // ギルド城データ変更要求
  1482. int guild_castledatasave(int castle_id,int index,int value)
  1483. {
  1484. if (index == 1)
  1485. { //The castle's owner has changed? Update Guardian ownership, too. [Skotlex]
  1486. struct guild_castle *gc = guild_castle_search(castle_id);
  1487. int m = -1;
  1488. if (gc) m = map_mapname2mapid(gc->map_name);
  1489. if (m != -1)
  1490. map_foreachinmap(mob_guardian_guildchange, m, BL_MOB);
  1491. }
  1492. return intif_guild_castle_datasave(castle_id,index,value);
  1493. }
  1494. // ギルド城データ変更通知
  1495. int guild_castledatasaveack(int castle_id,int index,int value)
  1496. {
  1497. struct guild_castle *gc=guild_castle_search(castle_id);
  1498. if(gc==NULL){
  1499. return 0;
  1500. }
  1501. switch(index){
  1502. case 1: gc->guild_id = value; break;
  1503. case 2: gc->economy = value; break;
  1504. case 3: gc->defense = value; break;
  1505. case 4: gc->triggerE = value; break;
  1506. case 5: gc->triggerD = value; break;
  1507. case 6: gc->nextTime = value; break;
  1508. case 7: gc->payTime = value; break;
  1509. case 8: gc->createTime = value; break;
  1510. case 9: gc->visibleC = value; break;
  1511. case 10:
  1512. case 11:
  1513. case 12:
  1514. case 13:
  1515. case 14:
  1516. case 15:
  1517. case 16:
  1518. case 17:
  1519. gc->guardian[index-10].visible = value; break;
  1520. case 18:
  1521. case 19:
  1522. case 20:
  1523. case 21:
  1524. case 22:
  1525. case 23:
  1526. case 24:
  1527. case 25:
  1528. gc->guardian[index-18].hp = value; break;
  1529. default:
  1530. ShowError("guild_castledatasaveack ERROR!! (Not found index=%d)\n", index);
  1531. return 0;
  1532. }
  1533. return 1;
  1534. }
  1535. // ギルドデータ一括受信(初期化時)
  1536. int guild_castlealldataload(int len,struct guild_castle *gc)
  1537. {
  1538. int i;
  1539. int n = (len-4) / sizeof(struct guild_castle), ev = -1;
  1540. nullpo_retr(0, gc);
  1541. //Last owned castle in the list invokes ::OnAgitinit
  1542. for(i = 0; i < n; i++) {
  1543. if ((gc + i)->guild_id)
  1544. ev = i;
  1545. }
  1546. // 城データ格納とギルド情報要求
  1547. for(i = 0; i < n; i++, gc++) {
  1548. struct guild_castle *c = guild_castle_search(gc->castle_id);
  1549. if (!c) {
  1550. ShowError("guild_castlealldataload Castle id=%d not found.\n", gc->castle_id);
  1551. continue;
  1552. }
  1553. memcpy(&c->guild_id,&gc->guild_id,
  1554. sizeof(struct guild_castle) - ((int)&c->guild_id - (int)c) );
  1555. if( c->guild_id ){
  1556. if(i!=ev)
  1557. guild_request_info(c->guild_id);
  1558. else
  1559. guild_npc_request_info(c->guild_id, "::OnAgitInit");
  1560. }
  1561. }
  1562. if (ev == -1) //No castles owned, invoke OnAgitInit as it is.
  1563. npc_event_doall("OnAgitInit");
  1564. return 0;
  1565. }
  1566. int guild_agit_start(void)
  1567. { // Run All NPC_Event[OnAgitStart]
  1568. int c = npc_event_doall("OnAgitStart");
  1569. ShowStatus("NPC_Event:[OnAgitStart] Run (%d) Events by @AgitStart.\n",c);
  1570. // Start auto saving
  1571. guild_save_timer = add_timer_interval (gettick() + GUILD_SAVE_INTERVAL, guild_save_sub, 0, 0, GUILD_SAVE_INTERVAL);
  1572. return 0;
  1573. }
  1574. int guild_agit_end(void)
  1575. { // Run All NPC_Event[OnAgitEnd]
  1576. int c = npc_event_doall("OnAgitEnd");
  1577. ShowStatus("NPC_Event:[OnAgitEnd] Run (%d) Events by @AgitEnd.\n",c);
  1578. // Stop auto saving
  1579. delete_timer (guild_save_timer, guild_save_sub);
  1580. return 0;
  1581. }
  1582. int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data)
  1583. { // Run One NPC_Event[OnAgitEliminate]
  1584. char *name = (char*)data;
  1585. size_t len = (name) ? strlen(name) : 0;
  1586. // the rest is dangerous, but let it crash,
  1587. // if this happens, it's ruined anyway
  1588. int c=0;
  1589. if(agit_flag) // Agit not already End
  1590. {
  1591. char *evname=(char*)aMalloc( (len + 10) * sizeof(char));
  1592. memcpy(evname,name,len - 5);
  1593. strcpy(evname + len - 5,"Eliminate");
  1594. c = npc_event_do(evname);
  1595. ShowStatus("NPC_Event:[%s] Run (%d) Events.\n",evname,c);
  1596. aFree(evname); // [Lance] Should fix this
  1597. }
  1598. if(name) aFree(name);
  1599. return 0;
  1600. }
  1601. static int Ghp[MAX_GUILDCASTLE][MAX_GUARDIANS]; // so save only if HP are changed // experimental code [Yor]
  1602. static int Gid[MAX_GUILDCASTLE];
  1603. int guild_save_sub(int tid,unsigned int tick,int id,int data)
  1604. {
  1605. struct guild_castle *gc;
  1606. int i,j;
  1607. for(i = 0; i < MAX_GUILDCASTLE; i++) { // [Yor]
  1608. gc = guild_castle_search(i);
  1609. if (!gc) continue;
  1610. if (gc->guild_id != Gid[i]) {
  1611. // Re-save guild id if its owner guild has changed
  1612. guild_castledatasave(gc->castle_id, 1, gc->guild_id);
  1613. Gid[i] = gc->guild_id;
  1614. }
  1615. for (j = 0; j < MAX_GUARDIANS; j++)
  1616. {
  1617. if (gc->guardian[j].visible && Ghp[i][j] != gc->guardian[j].hp)
  1618. guild_castledatasave(gc->castle_id, 18+j, gc->guardian[j].hp);
  1619. }
  1620. }
  1621. return 0;
  1622. }
  1623. int guild_agit_break(struct mob_data *md)
  1624. { // Run One NPC_Event[OnAgitBreak]
  1625. char *evname;
  1626. nullpo_retr(0, md);
  1627. evname=(char *)aMallocA((strlen(md->npc_event) + 1)*sizeof(char));
  1628. strcpy(evname,md->npc_event);
  1629. // Now By User to Run [OnAgitBreak] NPC Event...
  1630. // It's a little impossible to null point with player disconnect in this!
  1631. // But Script will be stop, so nothing...
  1632. // Maybe will be changed in the futher..
  1633. // int c = npc_event_do(evname);
  1634. if(!agit_flag) return 0; // Agit already End
  1635. add_timer(gettick()+battle_config.gvg_eliminate_time,guild_gvg_eliminate_timer,md->bl.m,(int)evname);
  1636. return 0;
  1637. }
  1638. // [MouseJstr]
  1639. // How many castles does this guild have?
  1640. int guild_checkcastles(struct guild *g) {
  1641. int i,nb_cas=0, id,cas_id=0;
  1642. struct guild_castle *gc;
  1643. id=g->guild_id;
  1644. for(i=0;i<MAX_GUILDCASTLE;i++){
  1645. gc=guild_castle_search(i);
  1646. cas_id=gc->guild_id;
  1647. if(g->guild_id==cas_id)
  1648. nb_cas=nb_cas+1;
  1649. } //end for
  1650. return nb_cas;
  1651. }
  1652. // [MouseJstr]
  1653. // is this guild allied with this castle?
  1654. int guild_isallied(struct guild *g, struct guild_castle *gc)
  1655. {
  1656. int i;
  1657. nullpo_retr(0, g);
  1658. if(g->guild_id == gc->guild_id)
  1659. return 1;
  1660. if (gc->guild_id == 0)
  1661. return 0;
  1662. for(i=0;i<MAX_GUILDALLIANCE;i++)
  1663. if(g->alliance[i].guild_id == gc->guild_id) {
  1664. if(g->alliance[i].opposition == 0)
  1665. return 1;
  1666. else
  1667. return 0;
  1668. }
  1669. return 0;
  1670. }
  1671. int guild_idisallied(int guild_id, int guild_id2)
  1672. {
  1673. int i;
  1674. struct guild *g;
  1675. if (guild_id <= 0 || guild_id2 <= 0)
  1676. return 0;
  1677. if(guild_id == guild_id2)
  1678. return 1;
  1679. g = guild_search(guild_id);
  1680. nullpo_retr(0, g);
  1681. for(i=0;i<MAX_GUILDALLIANCE;i++)
  1682. if(g->alliance[i].guild_id == guild_id2) {
  1683. if(g->alliance[i].opposition == 0)
  1684. return 1;
  1685. else
  1686. return 0;
  1687. }
  1688. return 0;
  1689. }
  1690. static int guild_infoevent_db_final(DBKey key,void *data,va_list ap)
  1691. {
  1692. aFree(data);
  1693. return 0;
  1694. }
  1695. static int guild_expcache_db_final(DBKey key,void *data,va_list ap)
  1696. {
  1697. ers_free(expcache_ers, data);
  1698. return 0;
  1699. }
  1700. void do_final_guild(void)
  1701. {
  1702. guild_db->destroy(guild_db,NULL);
  1703. castle_db->destroy(castle_db,NULL);
  1704. guild_expcache_db->destroy(guild_expcache_db,guild_expcache_db_final);
  1705. guild_infoevent_db->destroy(guild_infoevent_db,guild_infoevent_db_final);
  1706. guild_castleinfoevent_db->destroy(guild_castleinfoevent_db,guild_infoevent_db_final);
  1707. ers_destroy(expcache_ers);
  1708. }