guild.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618
  1. // $Id: guild.c,v 1.5 2004/09/25 05:32:18 MouseJstr Exp $
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "guild.h"
  6. #include "storage.h"
  7. #include "db.h"
  8. #include "timer.h"
  9. #include "socket.h"
  10. #include "nullpo.h"
  11. #include "malloc.h"
  12. #include "battle.h"
  13. #include "npc.h"
  14. #include "pc.h"
  15. #include "map.h"
  16. #include "mob.h"
  17. #include "intif.h"
  18. #include "clif.h"
  19. #include "skill.h"
  20. #include "showmsg.h"
  21. #ifdef MEMWATCH
  22. #include "memwatch.h"
  23. #endif
  24. static struct dbt *guild_db;
  25. static struct dbt *castle_db;
  26. static struct dbt *guild_expcache_db;
  27. static struct dbt *guild_infoevent_db;
  28. static struct dbt *guild_castleinfoevent_db;
  29. struct eventlist {
  30. char name[50];
  31. struct eventlist *next;
  32. };
  33. // ギルドのEXPキャッシュのフラッシュに関連する定数
  34. #define GUILD_PAYEXP_INVERVAL 10000 // 間隔(キャッシュの最大生存時間、ミリ秒)
  35. #define GUILD_PAYEXP_LIST 8192 // キャッシュの最大数
  36. // ギルドのEXPキャッシュ
  37. struct guild_expcache {
  38. int guild_id, account_id, char_id, exp;
  39. };
  40. // ギルドスキルdbのアクセサ(今は直打ちで代用)
  41. int guild_skill_get_inf(int id) { // Modified for new skills [Sara]
  42. if (id==GD_BATTLEORDER) return 4;
  43. else if (id==GD_REGENERATION) return 4;
  44. else if (id==GD_RESTORE) return 4;
  45. else if (id==GD_EMERGENCYCALL) return 4;
  46. else return 0;
  47. }
  48. int guild_skill_get_sp(int id,int lv){ return 0; }
  49. int guild_skill_get_range(int id){ return 0; }
  50. int guild_skill_get_max(int id) { // Modified for new skills [Sara]
  51. switch (id) {
  52. case GD_GUARDUP:
  53. return 3;
  54. case GD_EXTENSION:
  55. return 10;
  56. case GD_LEADERSHIP:
  57. case GD_GLORYWOUNDS:
  58. case GD_SOULCOLD:
  59. case GD_HAWKEYES:
  60. return 5;
  61. case GD_REGENERATION:
  62. return 3;
  63. default:
  64. return 1;
  65. }
  66. }
  67. // ギルドスキルがあるか確認
  68. int guild_checkskill(struct guild *g,int id)
  69. {
  70. int idx = id-GD_SKILLBASE;
  71. if (idx < 0 || idx >= MAX_GUILDSKILL)
  72. return 0;
  73. return g->skill[idx].lv;
  74. }
  75. int guild_payexp_timer(int tid,unsigned int tick,int id,int data);
  76. int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data);
  77. static int guild_read_castledb(void)
  78. {
  79. FILE *fp;
  80. char line[1024];
  81. int j,ln=0;
  82. char *str[32],*p;
  83. struct guild_castle *gc;
  84. if( (fp=fopen("db/castle_db.txt","r"))==NULL){
  85. printf("can't read db/castle_db.txt\n");
  86. return -1;
  87. }
  88. while(fgets(line,1020,fp)){
  89. if(line[0]=='/' && line[1]=='/')
  90. continue;
  91. memset(str,0,sizeof(str));
  92. gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle));
  93. for(j=0,p=line;j<6 && p;j++){
  94. str[j]=p;
  95. p=strchr(p,',');
  96. if(p) *p++=0;
  97. }
  98. gc->guild_id=0; // <Agit> Clear Data for Initialize
  99. gc->economy=0; gc->defense=0; gc->triggerE=0; gc->triggerD=0; gc->nextTime=0; gc->payTime=0;
  100. gc->createTime=0; gc->visibleC=0; gc->visibleG0=0; gc->visibleG1=0; gc->visibleG2=0;
  101. gc->visibleG3=0; gc->visibleG4=0; gc->visibleG5=0; gc->visibleG6=0; gc->visibleG7=0;
  102. gc->Ghp0=0; gc->Ghp1=0; gc->Ghp2=0; gc->Ghp3=0; gc->Ghp4=0; gc->Ghp5=0; gc->Ghp6=0; gc->Ghp7=0; // guardian HP [Valaris]
  103. gc->castle_id=atoi(str[0]);
  104. memcpy(gc->map_name,str[1],24);
  105. memcpy(gc->castle_name,str[2],24);
  106. memcpy(gc->castle_event,str[3],24);
  107. numdb_insert(castle_db,gc->castle_id,gc);
  108. //intif_guild_castle_info(gc->castle_id);
  109. ln++;
  110. }
  111. fclose(fp);
  112. sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/castle_db.txt");
  113. ShowStatus(tmp_output);
  114. return 0;
  115. }
  116. // 初期化
  117. void do_init_guild(void)
  118. {
  119. guild_db=numdb_init();
  120. castle_db=numdb_init();
  121. guild_expcache_db=numdb_init();
  122. guild_infoevent_db=numdb_init();
  123. guild_castleinfoevent_db=numdb_init();
  124. guild_read_castledb();
  125. add_timer_func_list(guild_gvg_eliminate_timer,"guild_gvg_eliminate_timer");
  126. add_timer_func_list(guild_payexp_timer,"guild_payexp_timer");
  127. add_timer_interval(gettick()+GUILD_PAYEXP_INVERVAL,guild_payexp_timer,0,0,GUILD_PAYEXP_INVERVAL);
  128. }
  129. // 検索
  130. struct guild *guild_search(int guild_id)
  131. {
  132. return numdb_search(guild_db,guild_id);
  133. }
  134. int guild_searchname_sub(void *key,void *data,va_list ap)
  135. {
  136. struct guild *g=(struct guild *)data,**dst;
  137. char *str;
  138. str=va_arg(ap,char *);
  139. dst=va_arg(ap,struct guild **);
  140. if(strcmpi(g->name,str)==0)
  141. *dst=g;
  142. return 0;
  143. }
  144. // ギルド名検索
  145. struct guild* guild_searchname(char *str)
  146. {
  147. struct guild *g=NULL;
  148. numdb_foreach(guild_db,guild_searchname_sub,str,&g);
  149. return g;
  150. }
  151. struct guild_castle *guild_castle_search(int gcid)
  152. {
  153. return numdb_search(castle_db,gcid);
  154. }
  155. // mapnameに対応したアジトのgcを返す
  156. struct guild_castle *guild_mapname2gc(char *mapname)
  157. {
  158. int i;
  159. struct guild_castle *gc=NULL;
  160. for(i=0;i<MAX_GUILDCASTLE;i++){
  161. gc=guild_castle_search(i);
  162. if(!gc) continue;
  163. if(strcmp(gc->map_name,mapname)==0) return gc;
  164. }
  165. return NULL;
  166. }
  167. // ログイン中のギルドメンバーの1人のsdを返す
  168. struct map_session_data *guild_getavailablesd(struct guild *g)
  169. {
  170. int i;
  171. nullpo_retr(NULL, g);
  172. for(i=0;i<g->max_member;i++)
  173. if(g->member[i].sd!=NULL)
  174. return g->member[i].sd;
  175. return NULL;
  176. }
  177. // ギルドメンバーのインデックスを返す
  178. int guild_getindex(struct guild *g,int account_id,int char_id)
  179. {
  180. int i;
  181. if(g==NULL)
  182. return -1;
  183. for(i=0;i<g->max_member;i++)
  184. if( g->member[i].account_id==account_id &&
  185. g->member[i].char_id==char_id )
  186. return i;
  187. return -1;
  188. }
  189. // ギルドメンバーの役職を返す
  190. int guild_getposition(struct map_session_data *sd,struct guild *g)
  191. {
  192. int i;
  193. nullpo_retr(-1, sd);
  194. if(g==NULL && (g=guild_search(sd->status.guild_id))==NULL)
  195. return -1;
  196. for(i=0;i<g->max_member;i++)
  197. if( g->member[i].account_id==sd->status.account_id &&
  198. g->member[i].char_id==sd->status.char_id )
  199. return g->member[i].position;
  200. return -1;
  201. }
  202. // メンバー情報の作成
  203. void guild_makemember(struct guild_member *m,struct map_session_data *sd)
  204. {
  205. nullpo_retv(sd);
  206. memset(m,0,sizeof(struct guild_member));
  207. m->account_id =sd->status.account_id;
  208. m->char_id =sd->status.char_id;
  209. m->hair =sd->status.hair;
  210. m->hair_color =sd->status.hair_color;
  211. m->gender =sd->sex;
  212. m->class_ =sd->status.class_;
  213. m->lv =sd->status.base_level;
  214. m->exp =0;
  215. m->exp_payper =0;
  216. m->online =1;
  217. m->position =MAX_GUILDPOSITION-1;
  218. memcpy(m->name,sd->status.name,24);
  219. return;
  220. }
  221. // ギルド競合確認
  222. int guild_check_conflict(struct map_session_data *sd)
  223. {
  224. nullpo_retr(0, sd);
  225. intif_guild_checkconflict(sd->status.guild_id,
  226. sd->status.account_id,sd->status.char_id);
  227. return 0;
  228. }
  229. // ギルドのEXPキャッシュをinter鯖にフラッシュする
  230. int guild_payexp_timer_sub(void *key,void *data,va_list ap)
  231. {
  232. int i, *dellist,*delp, dataid=(int)key;
  233. struct guild_expcache *c;
  234. struct guild *g;
  235. nullpo_retr(0, ap);
  236. nullpo_retr(0, c=(struct guild_expcache *)data);
  237. nullpo_retr(0, dellist=va_arg(ap,int *));
  238. nullpo_retr(0, delp=va_arg(ap,int *));
  239. if( *delp>=GUILD_PAYEXP_LIST || (g=guild_search(c->guild_id))==NULL )
  240. return 0;
  241. if( ( i=guild_getindex(g,c->account_id,c->char_id) )<0 )
  242. return 0;
  243. g->member[i].exp+=c->exp;
  244. intif_guild_change_memberinfo(g->guild_id,c->account_id,c->char_id,
  245. GMI_EXP,&g->member[i].exp,sizeof(g->member[i].exp));
  246. c->exp=0;
  247. dellist[(*delp)++]=dataid;
  248. aFree(c);
  249. return 0;
  250. }
  251. int guild_payexp_timer(int tid,unsigned int tick,int id,int data)
  252. {
  253. int dellist[GUILD_PAYEXP_LIST],delp=0,i;
  254. numdb_foreach(guild_expcache_db,guild_payexp_timer_sub,
  255. dellist,&delp);
  256. for(i=0;i<delp;i++)
  257. numdb_erase(guild_expcache_db,dellist[i]);
  258. // if(battle_config.etc_log)
  259. // printf("guild exp %d charactor's exp flushed !\n",delp);
  260. return 0;
  261. }
  262. //------------------------------------------------------------------------
  263. // 作成要求
  264. int guild_create(struct map_session_data *sd,char *name)
  265. {
  266. nullpo_retr(0, sd);
  267. if(sd->status.guild_id==0){
  268. if(!battle_config.guild_emperium_check || pc_search_inventory(sd,714) >= 0) {
  269. struct guild_member m;
  270. guild_makemember(&m,sd);
  271. m.position=0;
  272. intif_guild_create(name,&m);
  273. } else
  274. clif_guild_created(sd,3); // エンペリウムがいない
  275. }else
  276. clif_guild_created(sd,1); // すでに所属している
  277. return 0;
  278. }
  279. // 作成可否
  280. int guild_created(int account_id,int guild_id)
  281. {
  282. struct map_session_data *sd=map_id2sd(account_id);
  283. if(sd==NULL)
  284. return 0;
  285. if(guild_id>0) {
  286. struct guild *g;
  287. sd->status.guild_id=guild_id;
  288. sd->guild_sended=0;
  289. if((g=numdb_search(guild_db,guild_id))!=NULL){
  290. printf("guild: id already exists!\n");
  291. exit(1);
  292. }
  293. clif_guild_created(sd,0);
  294. if(battle_config.guild_emperium_check)
  295. pc_delitem(sd,pc_search_inventory(sd,714),1,0); // エンペリウム消耗
  296. } else {
  297. clif_guild_created(sd,2); // 作成失敗(同名ギルド存在)
  298. }
  299. return 0;
  300. }
  301. // 情報要求
  302. int guild_request_info(int guild_id)
  303. {
  304. // if(battle_config.etc_log)
  305. // printf("guild_request_info\n");
  306. return intif_guild_request_info(guild_id);
  307. }
  308. // イベント付き情報要求
  309. int guild_npc_request_info(int guild_id,const char *event)
  310. {
  311. struct eventlist *ev;
  312. if( guild_search(guild_id) ){
  313. if(event && *event)
  314. npc_event_do(event);
  315. return 0;
  316. }
  317. if(event==NULL || *event==0)
  318. return guild_request_info(guild_id);
  319. ev=(struct eventlist *)aCalloc(1,sizeof(struct eventlist));
  320. memcpy(ev->name,event,strlen(event));
  321. ev->next=(struct eventlist *)numdb_search(guild_infoevent_db,guild_id);
  322. numdb_insert(guild_infoevent_db,guild_id,ev);
  323. return guild_request_info(guild_id);
  324. }
  325. // 所属キャラの確認
  326. int guild_check_member(const struct guild *g)
  327. {
  328. int i;
  329. struct map_session_data *sd;
  330. nullpo_retr(0, g);
  331. for(i=0;i<fd_max;i++){
  332. if(session[i] && (sd=session[i]->session_data) && sd->state.auth){
  333. if(sd->status.guild_id==g->guild_id){
  334. int j,f=1;
  335. for(j=0;j<MAX_GUILD;j++){ // データがあるか
  336. if( g->member[j].account_id==sd->status.account_id &&
  337. g->member[j].char_id==sd->status.char_id)
  338. f=0;
  339. }
  340. if(f){
  341. sd->status.guild_id=0;
  342. sd->guild_sended=0;
  343. sd->guild_emblem_id=0;
  344. if(battle_config.error_log)
  345. printf("guild: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name);
  346. }
  347. }
  348. }
  349. }
  350. return 0;
  351. }
  352. // 情報所得失敗(そのIDのキャラを全部未所属にする)
  353. int guild_recv_noinfo(int guild_id)
  354. {
  355. int i;
  356. struct map_session_data *sd;
  357. for(i=0;i<fd_max;i++){
  358. if(session[i] && (sd=session[i]->session_data) && sd->state.auth){
  359. if(sd->status.guild_id==guild_id)
  360. sd->status.guild_id=0;
  361. }
  362. }
  363. return 0;
  364. }
  365. // 情報所得
  366. int guild_recv_info(struct guild *sg)
  367. {
  368. struct guild *g,before;
  369. int i,bm,m;
  370. struct eventlist *ev,*ev2;
  371. nullpo_retr(0, sg);
  372. if((g=numdb_search(guild_db,sg->guild_id))==NULL){
  373. g=(struct guild *)aCalloc(1,sizeof(struct guild));
  374. numdb_insert(guild_db,sg->guild_id,g);
  375. before=*sg;
  376. // 最初のロードなのでユーザーのチェックを行う
  377. guild_check_member(sg);
  378. }else
  379. before=*g;
  380. memcpy(g,sg,sizeof(struct guild));
  381. for(i=bm=m=0;i<g->max_member;i++){ // sdの設定と人数の確認
  382. if(g->member[i].account_id>0){
  383. struct map_session_data *sd = map_id2sd(g->member[i].account_id);
  384. g->member[i].sd=(sd!=NULL &&
  385. sd->status.char_id==g->member[i].char_id &&
  386. sd->status.guild_id==g->guild_id)? sd:NULL;
  387. m++;
  388. }else
  389. g->member[i].sd=NULL;
  390. if(before.member[i].account_id>0)
  391. bm++;
  392. }
  393. for(i=0;i<g->max_member;i++){ // 情報の送信
  394. struct map_session_data *sd = g->member[i].sd;
  395. if( sd==NULL )
  396. continue;
  397. if( before.guild_lv!=g->guild_lv || bm!=m ||
  398. before.max_member!=g->max_member ){
  399. clif_guild_basicinfo(sd); // 基本情報送信
  400. clif_guild_emblem(sd,g); // エンブレム送信
  401. }
  402. if(bm!=m){ // メンバー情報送信
  403. clif_guild_memberlist(g->member[i].sd);
  404. }
  405. if( before.skill_point!=g->skill_point)
  406. clif_guild_skillinfo(sd); // スキル情報送信
  407. if( sd->guild_sended==0){ // 未送信なら所属情報も送る
  408. clif_guild_belonginfo(sd,g);
  409. clif_guild_notice(sd,g);
  410. sd->guild_emblem_id=g->emblem_id;
  411. sd->guild_sended=1;
  412. }
  413. }
  414. // イベントの発生
  415. if( (ev=numdb_search(guild_infoevent_db,sg->guild_id))!=NULL ){
  416. numdb_erase(guild_infoevent_db,sg->guild_id);
  417. for(;ev;ev2=ev->next,aFree(ev),ev=ev2){
  418. npc_event_do(ev->name);
  419. }
  420. }
  421. return 0;
  422. }
  423. // ギルドへの勧誘
  424. int guild_invite(struct map_session_data *sd,int account_id)
  425. {
  426. struct map_session_data *tsd;
  427. struct guild *g;
  428. int i;
  429. nullpo_retr(0, sd);
  430. tsd= map_id2sd(account_id);
  431. g=guild_search(sd->status.guild_id);
  432. if(tsd==NULL || g==NULL)
  433. return 0;
  434. if(!battle_config.invite_request_check) {
  435. if (tsd->party_invite>0 || tsd->trade_partner) { // 相手が取引中かどうか
  436. clif_guild_inviteack(sd,0);
  437. return 0;
  438. }
  439. }
  440. if( tsd->status.guild_id>0 || tsd->guild_invite>0 ){ // 相手の所属確認
  441. clif_guild_inviteack(sd,0);
  442. return 0;
  443. }
  444. // 定員確認
  445. for(i=0;i<g->max_member;i++)
  446. if(g->member[i].account_id==0)
  447. break;
  448. if(i==g->max_member){
  449. clif_guild_inviteack(sd,3);
  450. return 0;
  451. }
  452. tsd->guild_invite=sd->status.guild_id;
  453. tsd->guild_invite_account=sd->status.account_id;
  454. clif_guild_invite(tsd,g);
  455. return 0;
  456. }
  457. // ギルド勧誘への返答
  458. int guild_reply_invite(struct map_session_data *sd,int guild_id,int flag)
  459. {
  460. struct map_session_data *tsd;
  461. nullpo_retr(0, sd);
  462. nullpo_retr(0, tsd= map_id2sd( sd->guild_invite_account ));
  463. if(sd->guild_invite!=guild_id) // 勧誘とギルドIDが違う
  464. return 0;
  465. if(flag==1){ // 承諾
  466. struct guild_member m;
  467. struct guild *g;
  468. int i;
  469. // 定員確認
  470. if( (g=guild_search(tsd->status.guild_id))==NULL ){
  471. sd->guild_invite=0;
  472. sd->guild_invite_account=0;
  473. return 0;
  474. }
  475. for(i=0;i<g->max_member;i++)
  476. if(g->member[i].account_id==0)
  477. break;
  478. if(i==g->max_member){
  479. sd->guild_invite=0;
  480. sd->guild_invite_account=0;
  481. clif_guild_inviteack(tsd,3);
  482. return 0;
  483. }
  484. //inter鯖へ追加要求
  485. guild_makemember(&m,sd);
  486. intif_guild_addmember( sd->guild_invite, &m );
  487. return 0;
  488. }else{ // 拒否
  489. sd->guild_invite=0;
  490. sd->guild_invite_account=0;
  491. if(tsd==NULL)
  492. return 0;
  493. clif_guild_inviteack(tsd,1);
  494. }
  495. return 0;
  496. }
  497. // ギルドメンバが追加された
  498. int guild_member_added(int guild_id,int account_id,int char_id,int flag)
  499. {
  500. struct map_session_data *sd= map_id2sd(account_id),*sd2;
  501. struct guild *g;
  502. if( (g=guild_search(guild_id))==NULL )
  503. return 0;
  504. if((sd==NULL || sd->guild_invite==0) && flag==0){
  505. // キャラ側に登録できなかったため脱退要求を出す
  506. if(battle_config.error_log)
  507. printf("guild: member added error %d is not online\n",account_id);
  508. intif_guild_leave(guild_id,account_id,char_id,0,"**登録失敗**");
  509. return 0;
  510. }
  511. sd->guild_invite=0;
  512. sd->guild_invite_account=0;
  513. sd2=map_id2sd(sd->guild_invite_account);
  514. if(flag==1){ // 失敗
  515. if( sd2!=NULL )
  516. clif_guild_inviteack(sd2,3);
  517. return 0;
  518. }
  519. // 成功
  520. sd->guild_sended=0;
  521. sd->status.guild_id=guild_id;
  522. if( sd2!=NULL )
  523. clif_guild_inviteack(sd2,2);
  524. // いちおう競合確認
  525. guild_check_conflict(sd);
  526. return 0;
  527. }
  528. // ギルド脱退要求
  529. int guild_leave(struct map_session_data *sd,int guild_id,
  530. int account_id,int char_id,const char *mes)
  531. {
  532. struct guild *g;
  533. int i;
  534. nullpo_retr(0, sd);
  535. g = guild_search(sd->status.guild_id);
  536. if(g==NULL)
  537. return 0;
  538. if( sd->status.account_id!=account_id ||
  539. sd->status.char_id!=char_id || sd->status.guild_id!=guild_id)
  540. return 0;
  541. for(i=0;i<g->max_member;i++){ // 所属しているか
  542. if( g->member[i].account_id==sd->status.account_id &&
  543. g->member[i].char_id==sd->status.char_id ){
  544. intif_guild_leave(g->guild_id,sd->status.account_id,sd->status.char_id,0,mes);
  545. return 0;
  546. }
  547. }
  548. return 0;
  549. }
  550. // ギルド追放要求
  551. int guild_explusion(struct map_session_data *sd,int guild_id,
  552. int account_id,int char_id,const char *mes)
  553. {
  554. struct guild *g;
  555. int i,ps;
  556. nullpo_retr(0, sd);
  557. g = guild_search(sd->status.guild_id);
  558. if(g==NULL)
  559. return 0;
  560. if( sd->status.guild_id!=guild_id)
  561. return 0;
  562. if( (ps=guild_getposition(sd,g))<0 || !(g->position[ps].mode&0x0010) )
  563. return 0; // 処罰権限無し
  564. for(i=0;i<g->max_member;i++){ // 所属しているか
  565. if( g->member[i].account_id==account_id &&
  566. g->member[i].char_id==char_id ){
  567. intif_guild_leave(g->guild_id,account_id,char_id,1,mes);
  568. return 0;
  569. }
  570. }
  571. return 0;
  572. }
  573. // ギルドメンバが脱退した
  574. int guild_member_leaved(int guild_id,int account_id,int char_id,int flag,
  575. const char *name,const char *mes)
  576. {
  577. struct map_session_data *sd=map_id2sd(account_id);
  578. struct guild *g=guild_search(guild_id);
  579. int i;
  580. if(g!=NULL){
  581. int i;
  582. for(i=0;i<g->max_member;i++)
  583. if( g->member[i].account_id==account_id &&
  584. g->member[i].char_id==char_id ){
  585. struct map_session_data *sd2=sd;
  586. if(sd2==NULL)
  587. sd2=guild_getavailablesd(g);
  588. else
  589. {
  590. if(flag==0)
  591. clif_guild_leave(sd2,name,mes);
  592. else
  593. clif_guild_explusion(sd2,name,mes,account_id);
  594. }
  595. g->member[i].account_id=0;
  596. g->member[i].sd=NULL;
  597. }
  598. }
  599. if(sd!=NULL && sd->status.guild_id==guild_id){
  600. sd->status.guild_id=0;
  601. sd->guild_emblem_id=0;
  602. sd->guild_sended=0;
  603. }
  604. // メンバーリストを全員に再通知
  605. for(i=0;i<g->max_member;i++){
  606. if( g->member[i].sd!=NULL )
  607. clif_guild_memberlist(g->member[i].sd);
  608. }
  609. return 0;
  610. }
  611. // ギルドメンバのオンライン状態/Lv更新送信
  612. int guild_send_memberinfoshort(struct map_session_data *sd,int online)
  613. {
  614. struct guild *g;
  615. nullpo_retr(0, sd);
  616. if(sd->status.guild_id<=0)
  617. return 0;
  618. g=guild_search(sd->status.guild_id);
  619. if(g==NULL)
  620. return 0;
  621. intif_guild_memberinfoshort(g->guild_id,
  622. sd->status.account_id,sd->status.char_id,online,sd->status.base_level,sd->status.class_);
  623. if( !online ){ // ログアウトするならsdをクリアして終了
  624. int i=guild_getindex(g,sd->status.account_id,sd->status.char_id);
  625. if(i>=0)
  626. g->member[i].sd=NULL;
  627. return 0;
  628. }
  629. if( sd->guild_sended!=0 ) // ギルド初期送信データは送信済み
  630. return 0;
  631. // 競合確認
  632. guild_check_conflict(sd);
  633. // あるならギルド初期送信データ送信
  634. if( (g=guild_search(sd->status.guild_id))!=NULL ){
  635. guild_check_member(g); // 所属を確認する
  636. if(sd->status.guild_id==g->guild_id){
  637. clif_guild_belonginfo(sd,g);
  638. clif_guild_notice(sd,g);
  639. sd->guild_sended=1;
  640. sd->guild_emblem_id=g->emblem_id;
  641. }
  642. }
  643. return 0;
  644. }
  645. // ギルドメンバのオンライン状態/Lv更新通知
  646. int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_)
  647. {
  648. int i,alv,c,idx=0,om=0,oldonline=-1;
  649. struct guild *g=guild_search(guild_id);
  650. if(g==NULL)
  651. return 0;
  652. for(i=0,alv=0,c=0,om=0;i<g->max_member;i++){
  653. struct guild_member *m=&g->member[i];
  654. if(m->account_id==account_id && m->char_id==char_id ){
  655. oldonline=m->online;
  656. m->online=online;
  657. m->lv=lv;
  658. m->class_=class_;
  659. idx=i;
  660. }
  661. if(m->account_id>0){
  662. alv+=m->lv;
  663. c++;
  664. }
  665. if(m->online)
  666. om++;
  667. }
  668. if(idx==g->max_member){
  669. if(battle_config.error_log)
  670. printf("guild: not found member %d,%d on %d[%s]\n", account_id,char_id,guild_id,g->name);
  671. return 0;
  672. }
  673. g->average_lv=alv/c;
  674. g->connect_member=om;
  675. if(oldonline!=online) // オンライン状態が変わったので通知
  676. clif_guild_memberlogin_notice(g,idx,online);
  677. for(i=0;i<g->max_member;i++){ // sd再設定
  678. struct map_session_data *sd= map_id2sd(g->member[i].account_id);
  679. g->member[i].sd=(sd!=NULL &&
  680. sd->status.char_id==g->member[i].char_id &&
  681. sd->status.guild_id==guild_id)?sd:NULL;
  682. }
  683. // ここにクライアントに送信処理が必要
  684. return 0;
  685. }
  686. // ギルド会話送信
  687. int guild_send_message(struct map_session_data *sd,char *mes,int len)
  688. {
  689. nullpo_retr(0, sd);
  690. if(sd->status.guild_id==0)
  691. return 0;
  692. intif_guild_message(sd->status.guild_id,sd->status.account_id,mes,len);
  693. guild_recv_message(sd->status.guild_id,sd->status.account_id,mes,len);
  694. return 0;
  695. }
  696. // ギルド会話受信
  697. int guild_recv_message(int guild_id,int account_id,char *mes,int len)
  698. {
  699. struct guild *g;
  700. if( (g=guild_search(guild_id))==NULL)
  701. return 0;
  702. clif_guild_message(g,account_id,mes,len);
  703. return 0;
  704. }
  705. // ギルドメンバの役職変更
  706. int guild_change_memberposition(int guild_id,int account_id,int char_id,int idx)
  707. {
  708. return intif_guild_change_memberinfo(
  709. guild_id,account_id,char_id,GMI_POSITION,&idx,sizeof(idx));
  710. }
  711. // ギルドメンバの役職変更通知
  712. int guild_memberposition_changed(struct guild *g,int idx,int pos)
  713. {
  714. nullpo_retr(0, g);
  715. g->member[idx].position=pos;
  716. clif_guild_memberpositionchanged(g,idx);
  717. return 0;
  718. }
  719. // ギルド役職変更
  720. int guild_change_position(struct map_session_data *sd,int idx,
  721. int mode,int exp_mode,const char *name)
  722. {
  723. struct guild_position p;
  724. nullpo_retr(0, sd);
  725. if(exp_mode>battle_config.guild_exp_limit)
  726. exp_mode=battle_config.guild_exp_limit;
  727. if(exp_mode<0)exp_mode=0;
  728. p.mode=mode;
  729. p.exp_mode=exp_mode;
  730. memcpy(p.name,name,24);
  731. return intif_guild_position(sd->status.guild_id,idx,&p);
  732. }
  733. // ギルド役職変更通知
  734. int guild_position_changed(int guild_id,int idx,struct guild_position *p)
  735. {
  736. struct guild *g=guild_search(guild_id);
  737. if(g==NULL)
  738. return 0;
  739. memcpy(&g->position[idx],p,sizeof(struct guild_position));
  740. clif_guild_positionchanged(g,idx);
  741. return 0;
  742. }
  743. // ギルド告知変更
  744. int guild_change_notice(struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2)
  745. {
  746. nullpo_retr(0, sd);
  747. if(guild_id!=sd->status.guild_id)
  748. return 0;
  749. return intif_guild_notice(guild_id,mes1,mes2);
  750. }
  751. // ギルド告知変更通知
  752. int guild_notice_changed(int guild_id,const char *mes1,const char *mes2)
  753. {
  754. int i;
  755. struct map_session_data *sd;
  756. struct guild *g=guild_search(guild_id);
  757. if(g==NULL)
  758. return 0;
  759. memcpy(g->mes1,mes1,60);
  760. memcpy(g->mes2,mes2,120);
  761. for(i=0;i<g->max_member;i++){
  762. if((sd=g->member[i].sd)!=NULL)
  763. clif_guild_notice(sd,g);
  764. }
  765. return 0;
  766. }
  767. // ギルドエンブレム変更
  768. int guild_change_emblem(struct map_session_data *sd,int len,const char *data)
  769. {
  770. struct guild *g = NULL;
  771. nullpo_retr(0, sd);
  772. if ((g = guild_search(sd->status.guild_id)) && guild_checkskill(g, GD_GLORYGUILD)>0)
  773. return intif_guild_emblem(sd->status.guild_id,len,data);
  774. clif_skill_fail(sd,GD_GLORYGUILD,0,0);
  775. return 0;
  776. }
  777. // ギルドエンブレム変更通知
  778. int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data)
  779. {
  780. int i;
  781. struct map_session_data *sd;
  782. struct guild *g=guild_search(guild_id);
  783. if(g==NULL)
  784. return 0;
  785. memcpy(g->emblem_data,data,len);
  786. g->emblem_len=len;
  787. g->emblem_id=emblem_id;
  788. for(i=0;i<g->max_member;i++){
  789. if((sd=g->member[i].sd)!=NULL){
  790. sd->guild_emblem_id=emblem_id;
  791. clif_guild_belonginfo(sd,g);
  792. clif_guild_emblem(sd,g);
  793. }
  794. }
  795. return 0;
  796. }
  797. // ギルドのEXP上納
  798. int guild_payexp(struct map_session_data *sd,int exp)
  799. {
  800. struct guild *g;
  801. struct guild_expcache *c;
  802. int per,exp2;
  803. nullpo_retr(0, sd);
  804. if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL )
  805. return 0;
  806. if( (per=g->position[guild_getposition(sd,g)].exp_mode)<=0 )
  807. return 0;
  808. if( per>100 )per=100;
  809. if( (exp2=exp*per/100)<=0 )
  810. return 0;
  811. if( (c=numdb_search(guild_expcache_db,sd->status.char_id))==NULL ){
  812. c=(struct guild_expcache *)aCallocA(1,sizeof(struct guild_expcache));
  813. c->guild_id=sd->status.guild_id;
  814. c->account_id=sd->status.account_id;
  815. c->char_id=sd->status.char_id;
  816. c->exp=exp2;
  817. numdb_insert(guild_expcache_db,c->char_id,c);
  818. }else{
  819. c->exp+=exp2;
  820. }
  821. return exp2;
  822. }
  823. // Celest
  824. int guild_getexp(struct map_session_data *sd,int exp)
  825. {
  826. struct guild *g;
  827. struct guild_expcache *c;
  828. nullpo_retr(0, sd);
  829. if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL )
  830. return 0;
  831. if( (c=numdb_search(guild_expcache_db,sd->status.char_id))==NULL ){
  832. c=(struct guild_expcache *)aCallocA(1,sizeof(struct guild_expcache));
  833. c->guild_id=sd->status.guild_id;
  834. c->account_id=sd->status.account_id;
  835. c->char_id=sd->status.char_id;
  836. c->exp=exp;
  837. numdb_insert(guild_expcache_db,c->char_id,c);
  838. }else{
  839. c->exp+=exp;
  840. }
  841. return exp;
  842. }
  843. // スキルポイント割り振り
  844. int guild_skillup(struct map_session_data *sd,int skill_num,int flag)
  845. {
  846. struct guild *g;
  847. int idx = skill_num - GD_SKILLBASE;
  848. nullpo_retr(0, sd);
  849. if(idx < 0 || idx >= MAX_GUILDSKILL)
  850. return 0;
  851. if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL)
  852. return 0;
  853. if(strcmp(sd->status.name,g->master))
  854. return 0;
  855. if( (g->skill_point>0 || flag&1) &&
  856. g->skill[idx].id!=0 &&
  857. g->skill[idx].lv < guild_skill_get_max(skill_num) ){
  858. intif_guild_skillup(g->guild_id,skill_num,sd->status.account_id,flag);
  859. }
  860. pc_calcstatus (sd, 0); // Celest
  861. return 0;
  862. }
  863. // スキルポイント割り振り通知
  864. int guild_skillupack(int guild_id,int skill_num,int account_id)
  865. {
  866. struct map_session_data *sd=map_id2sd(account_id);
  867. struct guild *g=guild_search(guild_id);
  868. int i;
  869. if(g==NULL)
  870. return 0;
  871. if(sd!=NULL)
  872. clif_guild_skillup(sd,skill_num,g->skill[skill_num-GD_SKILLBASE].lv);
  873. // 全員に通知
  874. for(i=0;i<g->max_member;i++)
  875. if((sd=g->member[i].sd)!=NULL)
  876. clif_guild_skillinfo(sd);
  877. return 0;
  878. }
  879. // ギルド同盟数所得
  880. int guild_get_alliance_count(struct guild *g,int flag)
  881. {
  882. int i,c;
  883. nullpo_retr(0, g);
  884. for(i=c=0;i<MAX_GUILDALLIANCE;i++){
  885. if( g->alliance[i].guild_id>0 &&
  886. g->alliance[i].opposition==flag )
  887. c++;
  888. }
  889. return c;
  890. }
  891. // ギルド同盟要求
  892. int guild_reqalliance(struct map_session_data *sd,int account_id)
  893. {
  894. struct map_session_data *tsd= map_id2sd(account_id);
  895. struct guild *g[2];
  896. int i;
  897. if(agit_flag) { // Disable alliance creation during woe [Valaris]
  898. clif_displaymessage(sd->fd,"Alliances cannot be made during Guild Wars!");
  899. return 0;
  900. } // end addition [Valaris]
  901. nullpo_retr(0, sd);
  902. if(tsd==NULL || tsd->status.guild_id<=0)
  903. return 0;
  904. g[0]=guild_search(sd->status.guild_id);
  905. g[1]=guild_search(tsd->status.guild_id);
  906. if(g[0]==NULL || g[1]==NULL)
  907. return 0;
  908. if( guild_get_alliance_count(g[0],0)>3 ) // 同盟数確認
  909. clif_guild_allianceack(sd,4);
  910. if( guild_get_alliance_count(g[1],0)>3 )
  911. clif_guild_allianceack(sd,3);
  912. if( tsd->guild_alliance>0 ){ // 相手が同盟要請状態かどうか確認
  913. clif_guild_allianceack(sd,1);
  914. return 0;
  915. }
  916. for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに同盟状態か確認
  917. if( g[0]->alliance[i].guild_id==tsd->status.guild_id &&
  918. g[0]->alliance[i].opposition==0){
  919. clif_guild_allianceack(sd,0);
  920. return 0;
  921. }
  922. }
  923. tsd->guild_alliance=sd->status.guild_id;
  924. tsd->guild_alliance_account=sd->status.account_id;
  925. clif_guild_reqalliance(tsd,sd->status.account_id,g[0]->name);
  926. return 0;
  927. }
  928. // ギルド勧誘への返答
  929. int guild_reply_reqalliance(struct map_session_data *sd,int account_id,int flag)
  930. {
  931. struct map_session_data *tsd;
  932. nullpo_retr(0, sd);
  933. nullpo_retr(0, tsd= map_id2sd( account_id ));
  934. if(sd->guild_alliance!=tsd->status.guild_id) // 勧誘とギルドIDが違う
  935. return 0;
  936. if(flag==1){ // 承諾
  937. int i;
  938. struct guild *g; // 同盟数再確認
  939. if( (g=guild_search(sd->status.guild_id))==NULL ||
  940. guild_get_alliance_count(g,0)>3 ){
  941. clif_guild_allianceack(sd,4);
  942. clif_guild_allianceack(tsd,3);
  943. return 0;
  944. }
  945. if( (g=guild_search(tsd->status.guild_id))==NULL ||
  946. guild_get_alliance_count(g,0)>3 ){
  947. clif_guild_allianceack(sd,3);
  948. clif_guild_allianceack(tsd,4);
  949. return 0;
  950. }
  951. // 敵対関係なら敵対を止める
  952. if((g=guild_search(sd->status.guild_id)) == NULL)
  953. return 0;
  954. for(i=0;i<MAX_GUILDALLIANCE;i++){
  955. if( g->alliance[i].guild_id==tsd->status.guild_id &&
  956. g->alliance[i].opposition==1)
  957. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  958. sd->status.account_id,tsd->status.account_id,9 );
  959. }
  960. if((g=guild_search(tsd->status.guild_id)) == NULL)
  961. return 0;
  962. for(i=0;i<MAX_GUILDALLIANCE;i++){
  963. if( g->alliance[i].guild_id==sd->status.guild_id &&
  964. g->alliance[i].opposition==1)
  965. intif_guild_alliance( tsd->status.guild_id,sd->status.guild_id,
  966. tsd->status.account_id,sd->status.account_id,9 );
  967. }
  968. // inter鯖へ同盟要請
  969. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  970. sd->status.account_id,tsd->status.account_id,0 );
  971. return 0;
  972. }else{ // 拒否
  973. sd->guild_alliance=0;
  974. sd->guild_alliance_account=0;
  975. if(tsd!=NULL)
  976. clif_guild_allianceack(tsd,3);
  977. }
  978. return 0;
  979. }
  980. // ギルド関係解消
  981. int guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
  982. {
  983. if(agit_flag) { // Disable alliance breaking during woe [Valaris]
  984. clif_displaymessage(sd->fd,"Alliances cannot be broken during Guild Wars!");
  985. return 0;
  986. } // end addition [Valaris]
  987. nullpo_retr(0, sd);
  988. intif_guild_alliance( sd->status.guild_id,guild_id,
  989. sd->status.account_id,0,flag|8 );
  990. return 0;
  991. }
  992. // ギルド敵対
  993. int guild_opposition(struct map_session_data *sd,int char_id)
  994. {
  995. struct map_session_data *tsd=map_id2sd(char_id);
  996. struct guild *g;
  997. int i;
  998. nullpo_retr(0, sd);
  999. g=guild_search(sd->status.guild_id);
  1000. if(g==NULL || tsd==NULL)
  1001. return 0;
  1002. if( guild_get_alliance_count(g,1)>3 ) // 敵対数確認
  1003. clif_guild_oppositionack(sd,1);
  1004. for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに関係を持っているか確認
  1005. if(g->alliance[i].guild_id==tsd->status.guild_id){
  1006. if(g->alliance[i].opposition==1){ // すでに敵対
  1007. clif_guild_oppositionack(sd,2);
  1008. return 0;
  1009. }else // 同盟破棄
  1010. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  1011. sd->status.account_id,tsd->status.account_id,8 );
  1012. }
  1013. }
  1014. // inter鯖に敵対要請
  1015. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id,
  1016. sd->status.account_id,tsd->status.account_id,1 );
  1017. return 0;
  1018. }
  1019. // ギルド同盟/敵対通知
  1020. int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id2,
  1021. int flag,const char *name1,const char *name2)
  1022. {
  1023. struct guild *g[2];
  1024. int guild_id[2];
  1025. const char *guild_name[2];
  1026. struct map_session_data *sd[2];
  1027. int j,i;
  1028. guild_id[0] = guild_id1;
  1029. guild_id[1] = guild_id2;
  1030. guild_name[0] = name1;
  1031. guild_name[1] = name2;
  1032. sd[0] = map_id2sd(account_id1);
  1033. sd[1] = map_id2sd(account_id2);
  1034. g[0]=guild_search(guild_id1);
  1035. g[1]=guild_search(guild_id2);
  1036. if(sd[0]!=NULL && (flag&0x0f)==0){
  1037. sd[0]->guild_alliance=0;
  1038. sd[0]->guild_alliance_account=0;
  1039. }
  1040. if(flag&0x70){ // 失敗
  1041. for(i=0;i<2-(flag&1);i++)
  1042. if( sd[i]!=NULL )
  1043. clif_guild_allianceack(sd[i],((flag>>4)==i+1)?3:4);
  1044. return 0;
  1045. }
  1046. // if(battle_config.etc_log)
  1047. // printf("guild alliance_ack %d %d %d %d %d %s %s\n",guild_id1,guild_id2,account_id1,account_id2,flag,name1,name2);
  1048. if(!(flag&0x08)){ // 関係追加
  1049. for(i=0;i<2-(flag&1);i++)
  1050. if(g[i]!=NULL)
  1051. for(j=0;j<MAX_GUILDALLIANCE;j++)
  1052. if(g[i]->alliance[j].guild_id==0){
  1053. g[i]->alliance[j].guild_id=guild_id[1-i];
  1054. memcpy(g[i]->alliance[j].name,guild_name[1-i],24);
  1055. g[i]->alliance[j].opposition=flag&1;
  1056. break;
  1057. }
  1058. }else{ // 関係解消
  1059. for(i=0;i<2-(flag&1);i++){
  1060. if(g[i]!=NULL)
  1061. for(j=0;j<MAX_GUILDALLIANCE;j++)
  1062. if( g[i]->alliance[j].guild_id==guild_id[1-i] &&
  1063. g[i]->alliance[j].opposition==(flag&1)){
  1064. g[i]->alliance[j].guild_id=0;
  1065. break;
  1066. }
  1067. if( sd[i]!=NULL ) // 解消通知
  1068. clif_guild_delalliance(sd[i],guild_id[1-i],(flag&1));
  1069. }
  1070. }
  1071. if((flag&0x0f)==0){ // 同盟通知
  1072. if( sd[1]!=NULL )
  1073. clif_guild_allianceack(sd[1],2);
  1074. }else if((flag&0x0f)==1){ // 敵対通知
  1075. if( sd[0]!=NULL )
  1076. clif_guild_oppositionack(sd[0],0);
  1077. }
  1078. for(i=0;i<2-(flag&1);i++){ // 同盟/敵対リストの再送信
  1079. struct map_session_data *sd;
  1080. if(g[i]!=NULL)
  1081. for(j=0;j<g[i]->max_member;j++)
  1082. if((sd=g[i]->member[j].sd)!=NULL)
  1083. clif_guild_allianceinfo(sd);
  1084. }
  1085. return 0;
  1086. }
  1087. // ギルド解散通知用
  1088. int guild_broken_sub(void *key,void *data,va_list ap)
  1089. {
  1090. struct guild *g=(struct guild *)data;
  1091. int guild_id=va_arg(ap,int);
  1092. int i,j;
  1093. struct map_session_data *sd=NULL;
  1094. nullpo_retr(0, g);
  1095. for(i=0;i<MAX_GUILDALLIANCE;i++){ // 関係を破棄
  1096. if(g->alliance[i].guild_id==guild_id){
  1097. for(j=0;j<g->max_member;j++)
  1098. if( (sd=g->member[j].sd)!=NULL )
  1099. clif_guild_delalliance(sd,guild_id,g->alliance[i].opposition);
  1100. g->alliance[i].guild_id=0;
  1101. }
  1102. }
  1103. return 0;
  1104. }
  1105. // ギルド解散通知
  1106. int guild_broken(int guild_id,int flag)
  1107. {
  1108. struct guild *g=guild_search(guild_id);
  1109. struct map_session_data *sd;
  1110. int i;
  1111. if(flag!=0 || g==NULL)
  1112. return 0;
  1113. for(i=0;i<g->max_member;i++){ // ギルド解散を通知
  1114. if((sd=g->member[i].sd)!=NULL){
  1115. if(sd->state.storage_flag)
  1116. storage_guild_storage_quit(sd,1);
  1117. sd->status.guild_id=0;
  1118. sd->guild_sended=0;
  1119. clif_guild_broken(g->member[i].sd,0);
  1120. }
  1121. }
  1122. numdb_foreach(guild_db,guild_broken_sub,guild_id);
  1123. numdb_erase(guild_db,guild_id);
  1124. guild_storage_delete(guild_id);
  1125. aFree(g);
  1126. return 0;
  1127. }
  1128. // ギルド解散
  1129. int guild_break(struct map_session_data *sd,char *name)
  1130. {
  1131. struct guild *g;
  1132. int i;
  1133. nullpo_retr(0, sd);
  1134. if( (g=guild_search(sd->status.guild_id))==NULL )
  1135. return 0;
  1136. if(strcmp(g->name,name)!=0)
  1137. return 0;
  1138. if(strcmp(sd->status.name,g->master)!=0)
  1139. return 0;
  1140. for(i=0;i<g->max_member;i++){
  1141. if( g->member[i].account_id>0 && (
  1142. g->member[i].account_id!=sd->status.account_id ||
  1143. g->member[i].char_id!=sd->status.char_id ))
  1144. break;
  1145. }
  1146. if(i<g->max_member){
  1147. clif_guild_broken(sd,2);
  1148. return 0;
  1149. }
  1150. intif_guild_break(g->guild_id);
  1151. return 0;
  1152. }
  1153. // ギルド城データ要求
  1154. int guild_castledataload(int castle_id,int index)
  1155. {
  1156. return intif_guild_castle_dataload(castle_id,index);
  1157. }
  1158. // ギルド城情報所得時イベント追加
  1159. int guild_addcastleinfoevent(int castle_id,int index,const char *name)
  1160. {
  1161. struct eventlist *ev;
  1162. int code=castle_id|(index<<16);
  1163. if( name==NULL || *name==0 )
  1164. return 0;
  1165. ev=(struct eventlist *)aCalloc(1,sizeof(struct eventlist));
  1166. memcpy(ev->name,name,sizeof(ev->name));
  1167. ev->next=numdb_search(guild_castleinfoevent_db,code);
  1168. numdb_insert(guild_castleinfoevent_db,code,ev);
  1169. return 0;
  1170. }
  1171. // ギルド城データ要求返信
  1172. int guild_castledataloadack(int castle_id,int index,int value)
  1173. {
  1174. struct guild_castle *gc=guild_castle_search(castle_id);
  1175. int code=castle_id|(index<<16);
  1176. struct eventlist *ev,*ev2;
  1177. if(gc==NULL){
  1178. return 0;
  1179. }
  1180. switch(index){
  1181. case 1: gc->guild_id = value; break;
  1182. case 2: gc->economy = value; break;
  1183. case 3: gc->defense = value; break;
  1184. case 4: gc->triggerE = value; break;
  1185. case 5: gc->triggerD = value; break;
  1186. case 6: gc->nextTime = value; break;
  1187. case 7: gc->payTime = value; break;
  1188. case 8: gc->createTime = value; break;
  1189. case 9: gc->visibleC = value; break;
  1190. case 10: gc->visibleG0 = value; break;
  1191. case 11: gc->visibleG1 = value; break;
  1192. case 12: gc->visibleG2 = value; break;
  1193. case 13: gc->visibleG3 = value; break;
  1194. case 14: gc->visibleG4 = value; break;
  1195. case 15: gc->visibleG5 = value; break;
  1196. case 16: gc->visibleG6 = value; break;
  1197. case 17: gc->visibleG7 = value; break;
  1198. case 18: gc->Ghp0 = value; break; // guardian HP [Valaris]
  1199. case 19: gc->Ghp1 = value; break;
  1200. case 20: gc->Ghp2 = value; break;
  1201. case 21: gc->Ghp3 = value; break;
  1202. case 22: gc->Ghp4 = value; break;
  1203. case 23: gc->Ghp5 = value; break;
  1204. case 24: gc->Ghp6 = value; break;
  1205. case 25: gc->Ghp7 = value; break; // end additions [Valaris]
  1206. default:
  1207. printf("guild_castledataloadack ERROR!! (Not found index=%d)\n", index);
  1208. return 0;
  1209. }
  1210. if( (ev=numdb_search(guild_castleinfoevent_db,code))!=NULL ){
  1211. numdb_erase(guild_castleinfoevent_db,code);
  1212. for(;ev;ev2=ev->next,aFree(ev),ev=ev2){
  1213. npc_event_do(ev->name);
  1214. }
  1215. }
  1216. return 1;
  1217. }
  1218. // ギルド城データ変更要求
  1219. int guild_castledatasave(int castle_id,int index,int value)
  1220. {
  1221. return intif_guild_castle_datasave(castle_id,index,value);
  1222. }
  1223. // ギルド城データ変更通知
  1224. int guild_castledatasaveack(int castle_id,int index,int value)
  1225. {
  1226. struct guild_castle *gc=guild_castle_search(castle_id);
  1227. if(gc==NULL){
  1228. return 0;
  1229. }
  1230. switch(index){
  1231. case 1: gc->guild_id = value; break;
  1232. case 2: gc->economy = value; break;
  1233. case 3: gc->defense = value; break;
  1234. case 4: gc->triggerE = value; break;
  1235. case 5: gc->triggerD = value; break;
  1236. case 6: gc->nextTime = value; break;
  1237. case 7: gc->payTime = value; break;
  1238. case 8: gc->createTime = value; break;
  1239. case 9: gc->visibleC = value; break;
  1240. case 10: gc->visibleG0 = value; break;
  1241. case 11: gc->visibleG1 = value; break;
  1242. case 12: gc->visibleG2 = value; break;
  1243. case 13: gc->visibleG3 = value; break;
  1244. case 14: gc->visibleG4 = value; break;
  1245. case 15: gc->visibleG5 = value; break;
  1246. case 16: gc->visibleG6 = value; break;
  1247. case 17: gc->visibleG7 = value; break;
  1248. case 18: gc->Ghp0 = value; break; // guardian HP [Valaris]
  1249. case 19: gc->Ghp1 = value; break;
  1250. case 20: gc->Ghp2 = value; break;
  1251. case 21: gc->Ghp3 = value; break;
  1252. case 22: gc->Ghp4 = value; break;
  1253. case 23: gc->Ghp5 = value; break;
  1254. case 24: gc->Ghp6 = value; break;
  1255. case 25: gc->Ghp7 = value; break; // end additions [Valaris]
  1256. default:
  1257. printf("guild_castledatasaveack ERROR!! (Not found index=%d)\n", index);
  1258. return 0;
  1259. }
  1260. return 1;
  1261. }
  1262. // ギルドデータ一括受信(初期化時)
  1263. int guild_castlealldataload(int len,struct guild_castle *gc)
  1264. {
  1265. int i;
  1266. int n = (len-4) / sizeof(struct guild_castle), ev = -1;
  1267. nullpo_retr(0, gc);
  1268. // イベント付きで要求するデータ位置を探す(最後の占拠データ)
  1269. for(i = 0; i < n; i++) {
  1270. if ((gc + i)->guild_id)
  1271. ev = i;
  1272. }
  1273. // 城データ格納とギルド情報要求
  1274. for(i = 0; i < n; i++, gc++) {
  1275. struct guild_castle *c = guild_castle_search(gc->castle_id);
  1276. if (!c) {
  1277. printf("guild_castlealldataload ??\n");
  1278. continue;
  1279. }
  1280. memcpy(&c->guild_id,&gc->guild_id,
  1281. sizeof(struct guild_castle) - ((int)&c->guild_id - (int)c) );
  1282. if( c->guild_id ){
  1283. if(i!=ev)
  1284. guild_request_info(c->guild_id);
  1285. else
  1286. guild_npc_request_info(c->guild_id, "::OnAgitInit");
  1287. }
  1288. }
  1289. if (ev == -1)
  1290. npc_event_doall("OnAgitInit");
  1291. return 0;
  1292. }
  1293. int guild_agit_start(void)
  1294. { // Run All NPC_Event[OnAgitStart]
  1295. int c = npc_event_doall("OnAgitStart");
  1296. printf("NPC_Event:[OnAgitStart] Run (%d) Events by @AgitStart.\n",c);
  1297. return 0;
  1298. }
  1299. int guild_agit_end(void)
  1300. { // Run All NPC_Event[OnAgitEnd]
  1301. int c = npc_event_doall("OnAgitEnd");
  1302. printf("NPC_Event:[OnAgitEnd] Run (%d) Events by @AgitEnd.\n",c);
  1303. return 0;
  1304. }
  1305. int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data)
  1306. { // Run One NPC_Event[OnAgitEliminate]
  1307. size_t len = strlen((const char*)data);
  1308. char *evname=(char*)aCallocA(len + 4,sizeof(char));
  1309. int c=0;
  1310. if(!agit_flag) return 0; // Agit already End
  1311. memcpy(evname,(const char *)data,len - 5);
  1312. strcpy(evname + len - 5,"Eliminate");
  1313. c = npc_event_do(evname);
  1314. printf("NPC_Event:[%s] Run (%d) Events.\n",evname,c);
  1315. return 0;
  1316. }
  1317. int guild_agit_break(struct mob_data *md)
  1318. { // Run One NPC_Event[OnAgitBreak]
  1319. char *evname;
  1320. nullpo_retr(0, md);
  1321. evname=(char *)aCallocA(strlen(md->npc_event) + 1, sizeof(char));
  1322. strcpy(evname,md->npc_event);
  1323. // Now By User to Run [OnAgitBreak] NPC Event...
  1324. // It's a little impossible to null point with player disconnect in this!
  1325. // But Script will be stop, so nothing...
  1326. // Maybe will be changed in the futher..
  1327. // int c = npc_event_do(evname);
  1328. if(!agit_flag) return 0; // Agit already End
  1329. add_timer(gettick()+battle_config.gvg_eliminate_time,guild_gvg_eliminate_timer,md->bl.m,(int)evname);
  1330. return 0;
  1331. }
  1332. // [MouseJstr]
  1333. // How many castles does this guild have?
  1334. int guild_checkcastles(struct guild *g) {
  1335. int i,nb_cas=0, id,cas_id=0;
  1336. struct guild_castle *gc;
  1337. id=g->guild_id;
  1338. for(i=0;i<MAX_GUILDCASTLE;i++){
  1339. gc=guild_castle_search(i);
  1340. cas_id=gc->guild_id;
  1341. if(g->guild_id==cas_id)
  1342. nb_cas=nb_cas+1;
  1343. } //end for
  1344. return nb_cas;
  1345. }
  1346. // [MouseJstr]
  1347. // is this guild allied with this castle?
  1348. int guild_isallied(struct guild *g, struct guild_castle *gc)
  1349. {
  1350. int i;
  1351. nullpo_retr(0, g);
  1352. if(g->guild_id == gc->guild_id)
  1353. return 1;
  1354. if (gc->guild_id == 0)
  1355. return 0;
  1356. for(i=0;i<MAX_GUILDALLIANCE;i++)
  1357. if(g->alliance[i].guild_id == gc->guild_id) {
  1358. if(g->alliance[i].opposition == 0)
  1359. return 1;
  1360. else
  1361. return 0;
  1362. }
  1363. return 0;
  1364. }
  1365. static int guild_db_final(void *key,void *data,va_list ap)
  1366. {
  1367. struct guild *g=data;
  1368. aFree(g);
  1369. return 0;
  1370. }
  1371. static int castle_db_final(void *key,void *data,va_list ap)
  1372. {
  1373. struct guild_castle *gc=data;
  1374. aFree(gc);
  1375. return 0;
  1376. }
  1377. static int guild_expcache_db_final(void *key,void *data,va_list ap)
  1378. {
  1379. struct guild_expcache *c=data;
  1380. aFree(c);
  1381. return 0;
  1382. }
  1383. static int guild_infoevent_db_final(void *key,void *data,va_list ap)
  1384. {
  1385. struct eventlist *ev=data;
  1386. aFree(ev);
  1387. return 0;
  1388. }
  1389. void do_final_guild(void)
  1390. {
  1391. if(guild_db)
  1392. numdb_final(guild_db,guild_db_final);
  1393. if(castle_db)
  1394. numdb_final(castle_db,castle_db_final);
  1395. if(guild_expcache_db)
  1396. numdb_final(guild_expcache_db,guild_expcache_db_final);
  1397. if(guild_infoevent_db)
  1398. numdb_final(guild_infoevent_db,guild_infoevent_db_final);
  1399. if(guild_castleinfoevent_db)
  1400. numdb_final(guild_castleinfoevent_db,guild_infoevent_db_final);
  1401. }