guild.c 51 KB

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