storage.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. // $Id: storage.c,v 1.3 2004/09/25 02:05:22 MouseJstr Exp $
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "db.h"
  6. #include "itemdb.h"
  7. #include "clif.h"
  8. #include "intif.h"
  9. #include "pc.h"
  10. #include "storage.h"
  11. #include "guild.h"
  12. #include "nullpo.h"
  13. #ifdef MEMWATCH
  14. #include "memwatch.h"
  15. #endif
  16. static struct dbt *storage_db;
  17. static struct dbt *guild_storage_db;
  18. /*==========================================
  19. * 倉庫内アイテムソート
  20. *------------------------------------------
  21. */
  22. int storage_comp_item(const void *_i1, const void *_i2){
  23. struct item *i1=(struct item *)_i1;
  24. struct item *i2=(struct item *)_i2;
  25. if (i1->nameid == i2->nameid) {
  26. return 0;
  27. } else if (!(i1->nameid) || !(i1->amount)){
  28. return 1;
  29. } else if (!(i2->nameid) || !(i2->amount)){
  30. return -1;
  31. } else {
  32. return i1->nameid - i2->nameid;
  33. }
  34. }
  35. void sortage_sortitem(struct storage* stor){
  36. nullpo_retv(stor);
  37. qsort(stor->storage, MAX_STORAGE, sizeof(struct item), storage_comp_item);
  38. }
  39. void sortage_gsortitem(struct guild_storage* gstor){
  40. nullpo_retv(gstor);
  41. qsort(gstor->storage, MAX_GUILD_STORAGE, sizeof(struct item), storage_comp_item);
  42. }
  43. /*==========================================
  44. * 初期化とか
  45. *------------------------------------------
  46. */
  47. int do_init_storage(void) // map.c::do_init()から呼ばれる
  48. {
  49. storage_db=numdb_init();
  50. guild_storage_db=numdb_init();
  51. return 1;
  52. }
  53. void do_final_storage(void) // map.c::do_final()から呼ばれる
  54. {
  55. }
  56. struct storage *account2storage(int account_id)
  57. {
  58. struct storage *stor;
  59. stor=numdb_search(storage_db,account_id);
  60. if(stor == NULL) {
  61. stor = calloc(sizeof(struct storage), 1);
  62. if(stor == NULL){
  63. printf("storage: out of memory!\n");
  64. exit(0);
  65. }
  66. memset(stor,0,sizeof(struct storage));
  67. stor->account_id=account_id;
  68. numdb_insert(storage_db,stor->account_id,stor);
  69. }
  70. return stor;
  71. }
  72. // Just to ask storage, without creation
  73. struct storage *account2storage2(int account_id) {
  74. return numdb_search(storage_db, account_id);
  75. }
  76. int storage_delete(int account_id)
  77. {
  78. struct storage *stor = numdb_search(storage_db,account_id);
  79. if(stor) {
  80. numdb_erase(storage_db,account_id);
  81. free(stor);
  82. }
  83. return 0;
  84. }
  85. /*==========================================
  86. * カプラ倉庫を開く
  87. *------------------------------------------
  88. */
  89. int storage_storageopen(struct map_session_data *sd)
  90. {
  91. struct storage *stor;
  92. nullpo_retr(0, sd);
  93. if((stor = numdb_search(storage_db,sd->status.account_id)) != NULL) {
  94. stor->storage_status = 1;
  95. sd->state.storage_flag = 0;
  96. clif_storageitemlist(sd,stor);
  97. clif_storageequiplist(sd,stor);
  98. clif_updatestorageamount(sd,stor);
  99. return 0;
  100. } else
  101. intif_request_storage(sd->status.account_id);
  102. return 1;
  103. }
  104. int storage_storageopen2(struct map_session_data *sd, struct map_session_data *pl_sd)
  105. {
  106. struct storage *stor;
  107. if(sd == NULL || pl_sd == NULL)
  108. {
  109. printf("storage_storageopen nullpo\n");
  110. return 0;
  111. }
  112. if((stor = numdb_search(storage_db,pl_sd->status.account_id)) != NULL)
  113. {
  114. clif_storageitemlist(sd,stor);
  115. clif_storageequiplist(sd,stor);
  116. clif_updatestorageamount(sd,stor);
  117. return 1;
  118. }
  119. return 0;
  120. }
  121. /*==========================================
  122. * カプラ倉庫へアイテム追加
  123. *------------------------------------------
  124. */
  125. int storage_additem(struct map_session_data *sd,struct storage *stor,struct item *item_data,int amount)
  126. {
  127. struct item_data *data;
  128. int i;
  129. nullpo_retr(1, sd);
  130. nullpo_retr(1, stor);
  131. nullpo_retr(1, item_data);
  132. if(item_data->nameid <= 0 || amount <= 0)
  133. return 1;
  134. nullpo_retr(1, data = itemdb_search(item_data->nameid));
  135. i=MAX_STORAGE;
  136. if(!itemdb_isequip2(data)){
  137. // 装備品ではないので、既所有品なら個数のみ変化させる
  138. for(i=0;i<MAX_STORAGE;i++){
  139. if(stor->storage[i].nameid == item_data->nameid &&
  140. stor->storage[i].card[0] == item_data->card[0] && stor->storage[i].card[1] == item_data->card[1] &&
  141. stor->storage[i].card[2] == item_data->card[2] && stor->storage[i].card[3] == item_data->card[3]){
  142. if(stor->storage[i].amount+amount > MAX_AMOUNT)
  143. return 1;
  144. stor->storage[i].amount+=amount;
  145. clif_storageitemadded(sd,stor,i,amount);
  146. break;
  147. }
  148. }
  149. }
  150. if(i>=MAX_STORAGE){
  151. // 装備品か未所有品だったので空き欄へ追加
  152. for(i=0;i<MAX_STORAGE;i++){
  153. if(stor->storage[i].nameid==0){
  154. memcpy(&stor->storage[i],item_data,sizeof(stor->storage[0]));
  155. stor->storage[i].amount=amount;
  156. stor->storage_amount++;
  157. clif_storageitemadded(sd,stor,i,amount);
  158. clif_updatestorageamount(sd,stor);
  159. break;
  160. }
  161. }
  162. if(i>=MAX_STORAGE)
  163. return 1;
  164. }
  165. return 0;
  166. }
  167. /*==========================================
  168. * カプラ倉庫アイテムを減らす
  169. *------------------------------------------
  170. */
  171. int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int amount)
  172. {
  173. nullpo_retr(1, sd);
  174. nullpo_retr(1, stor);
  175. if(stor->storage[n].nameid==0 || stor->storage[n].amount<amount)
  176. return 1;
  177. stor->storage[n].amount-=amount;
  178. if(stor->storage[n].amount==0){
  179. memset(&stor->storage[n],0,sizeof(stor->storage[0]));
  180. stor->storage_amount--;
  181. clif_updatestorageamount(sd,stor);
  182. }
  183. clif_storageitemremoved(sd,n,amount);
  184. return 0;
  185. }
  186. /*==========================================
  187. * カプラ倉庫へ入れる
  188. *------------------------------------------
  189. */
  190. int storage_storageadd(struct map_session_data *sd,int index,int amount)
  191. {
  192. struct storage *stor;
  193. nullpo_retr(0, sd);
  194. nullpo_retr(0, stor=account2storage(sd->status.account_id));
  195. if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open
  196. if(index>=0 && index<MAX_INVENTORY) { // valid index
  197. if( (amount <= sd->status.inventory[index].amount) && (amount > 0) ) { //valid amount
  198. if(storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
  199. // remove item from inventory
  200. pc_delitem(sd,index,amount,0);
  201. } // valid amount
  202. }// valid index
  203. }// storage not full & storage open
  204. return 0;
  205. }
  206. /*==========================================
  207. * カプラ倉庫から出す
  208. *------------------------------------------
  209. */
  210. int storage_storageget(struct map_session_data *sd,int index,int amount)
  211. {
  212. struct storage *stor;
  213. int flag;
  214. nullpo_retr(0, sd);
  215. nullpo_retr(0, stor=account2storage(sd->status.account_id));
  216. if(stor->storage_status == 1) { // storage open
  217. if(index>=0 && index<MAX_STORAGE) { // valid index
  218. if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
  219. if((flag = pc_additem(sd,&stor->storage[index],amount)) == 0)
  220. storage_delitem(sd,stor,index,amount);
  221. else
  222. clif_additem(sd,0,0,flag);
  223. } // valid amount
  224. }// valid index
  225. }// storage open
  226. return 0;
  227. }
  228. /*==========================================
  229. * カプラ倉庫へカートから入れる
  230. *------------------------------------------
  231. */
  232. int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount)
  233. {
  234. struct storage *stor;
  235. nullpo_retr(0, sd);
  236. nullpo_retr(0, stor=account2storage(sd->status.account_id));
  237. if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open
  238. if(index>=0 && index<MAX_INVENTORY) { // valid index
  239. if( (amount <= sd->status.cart[index].amount) && (amount > 0) ) { //valid amount
  240. if(storage_additem(sd,stor,&sd->status.cart[index],amount)==0)
  241. pc_cart_delitem(sd,index,amount,0);
  242. } // valid amount
  243. }// valid index
  244. }// storage not full & storage open
  245. return 0;
  246. }
  247. /*==========================================
  248. * カプラ倉庫からカートへ出す
  249. *------------------------------------------
  250. */
  251. int storage_storagegettocart(struct map_session_data *sd,int index,int amount)
  252. {
  253. struct storage *stor;
  254. nullpo_retr(0, sd);
  255. nullpo_retr(0, stor=account2storage(sd->status.account_id));
  256. if(stor->storage_status == 1) { // storage open
  257. if(index>=0 && index<MAX_STORAGE) { // valid index
  258. if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
  259. if(pc_cart_additem(sd,&stor->storage[index],amount)==0){
  260. storage_delitem(sd,stor,index,amount);
  261. }
  262. } // valid amount
  263. }// valid index
  264. }// storage open
  265. return 0;
  266. }
  267. /*==========================================
  268. * カプラ倉庫を閉じる
  269. *------------------------------------------
  270. */
  271. int storage_storageclose(struct map_session_data *sd)
  272. {
  273. struct storage *stor;
  274. nullpo_retr(0, sd);
  275. nullpo_retr(0, stor=account2storage(sd->status.account_id));
  276. stor->storage_status=0;
  277. sd->state.storage_flag = 0;
  278. clif_storageclose(sd);
  279. sortage_sortitem(stor);
  280. return 0;
  281. }
  282. /*==========================================
  283. * ログアウト時開いているカプラ倉庫の保存
  284. *------------------------------------------
  285. */
  286. int storage_storage_quit(struct map_session_data *sd)
  287. {
  288. struct storage *stor;
  289. nullpo_retr(0, sd);
  290. stor = numdb_search(storage_db,sd->status.account_id);
  291. if(stor) stor->storage_status = 0;
  292. return 0;
  293. }
  294. int storage_storage_save(struct map_session_data *sd)
  295. {
  296. struct storage *stor;
  297. nullpo_retr(0, sd);
  298. stor=numdb_search(storage_db,sd->status.account_id);
  299. if(stor) intif_send_storage(stor);
  300. return 0;
  301. }
  302. struct guild_storage *guild2storage(int guild_id)
  303. {
  304. struct guild_storage *gs = NULL;
  305. if(guild_search(guild_id) != NULL) {
  306. gs=numdb_search(guild_storage_db,guild_id);
  307. if(gs == NULL) {
  308. gs = calloc(sizeof(struct guild_storage), 1);
  309. if(gs==NULL){
  310. printf("storage: out of memory!\n");
  311. exit(0);
  312. }
  313. gs->guild_id=guild_id;
  314. numdb_insert(guild_storage_db,gs->guild_id,gs);
  315. }
  316. }
  317. return gs;
  318. }
  319. int guild_storage_delete(int guild_id)
  320. {
  321. struct guild_storage *gstor = numdb_search(guild_storage_db,guild_id);
  322. if(gstor) {
  323. numdb_erase(guild_storage_db,guild_id);
  324. free(gstor);
  325. }
  326. return 0;
  327. }
  328. int storage_guild_storageopen(struct map_session_data *sd)
  329. {
  330. struct guild_storage *gstor;
  331. nullpo_retr(0, sd);
  332. if(sd->status.guild_id <= 0)
  333. return 2;
  334. if((gstor = numdb_search(guild_storage_db,sd->status.guild_id)) != NULL) {
  335. if(gstor->storage_status)
  336. return 1;
  337. gstor->storage_status = 1;
  338. sd->state.storage_flag = 1;
  339. clif_guildstorageitemlist(sd,gstor);
  340. clif_guildstorageequiplist(sd,gstor);
  341. clif_updateguildstorageamount(sd,gstor);
  342. return 0;
  343. }
  344. else {
  345. gstor = guild2storage(sd->status.guild_id);
  346. gstor->storage_status = 1;
  347. intif_request_guild_storage(sd->status.account_id,sd->status.guild_id);
  348. }
  349. return 0;
  350. }
  351. int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount)
  352. {
  353. struct item_data *data;
  354. int i;
  355. nullpo_retr(1, sd);
  356. nullpo_retr(1, stor);
  357. nullpo_retr(1, item_data);
  358. nullpo_retr(1, data = itemdb_search(item_data->nameid));
  359. if(item_data->nameid <= 0 || amount <= 0)
  360. return 1;
  361. i=MAX_GUILD_STORAGE;
  362. if(!itemdb_isequip2(data)){
  363. // 装備品ではないので、既所有品なら個数のみ変化させる
  364. for(i=0;i<MAX_GUILD_STORAGE;i++){
  365. if(stor->storage[i].nameid == item_data->nameid &&
  366. stor->storage[i].card[0] == item_data->card[0] && stor->storage[i].card[1] == item_data->card[1] &&
  367. stor->storage[i].card[2] == item_data->card[2] && stor->storage[i].card[3] == item_data->card[3]){
  368. if(stor->storage[i].amount+amount > MAX_AMOUNT)
  369. return 1;
  370. stor->storage[i].amount+=amount;
  371. clif_guildstorageitemadded(sd,stor,i,amount);
  372. break;
  373. }
  374. }
  375. }
  376. if(i>=MAX_GUILD_STORAGE){
  377. // 装備品か未所有品だったので空き欄へ追加
  378. for(i=0;i<MAX_GUILD_STORAGE;i++){
  379. if(stor->storage[i].nameid==0){
  380. memcpy(&stor->storage[i],item_data,sizeof(stor->storage[0]));
  381. stor->storage[i].amount=amount;
  382. stor->storage_amount++;
  383. clif_guildstorageitemadded(sd,stor,i,amount);
  384. clif_updateguildstorageamount(sd,stor);
  385. break;
  386. }
  387. }
  388. if(i>=MAX_GUILD_STORAGE)
  389. return 1;
  390. }
  391. return 0;
  392. }
  393. int guild_storage_delitem(struct map_session_data *sd,struct guild_storage *stor,int n,int amount)
  394. {
  395. nullpo_retr(1, sd);
  396. nullpo_retr(1, stor);
  397. if(stor->storage[n].nameid==0 || stor->storage[n].amount<amount)
  398. return 1;
  399. stor->storage[n].amount-=amount;
  400. if(stor->storage[n].amount==0){
  401. memset(&stor->storage[n],0,sizeof(stor->storage[0]));
  402. stor->storage_amount--;
  403. clif_updateguildstorageamount(sd,stor);
  404. }
  405. clif_storageitemremoved(sd,n,amount);
  406. return 0;
  407. }
  408. int storage_guild_storageadd(struct map_session_data *sd,int index,int amount)
  409. {
  410. struct guild_storage *stor;
  411. nullpo_retr(0, sd);
  412. if((stor=guild2storage(sd->status.guild_id)) != NULL) {
  413. if( (stor->storage_amount <= MAX_GUILD_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open
  414. if(index>=0 && index<MAX_INVENTORY) { // valid index
  415. if( (amount <= sd->status.inventory[index].amount) && (amount > 0) ) { //valid amount
  416. if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
  417. // remove item from inventory
  418. pc_delitem(sd,index,amount,0);
  419. } // valid amount
  420. }// valid index
  421. }// storage not full & storage open
  422. }
  423. return 0;
  424. }
  425. int storage_guild_storageget(struct map_session_data *sd,int index,int amount)
  426. {
  427. struct guild_storage *stor;
  428. int flag;
  429. nullpo_retr(0, sd);
  430. if((stor=guild2storage(sd->status.guild_id)) != NULL) {
  431. if(stor->storage_status == 1) { // storage open
  432. if(index>=0 && index<MAX_GUILD_STORAGE) { // valid index
  433. if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
  434. if((flag = pc_additem(sd,&stor->storage[index],amount)) == 0)
  435. guild_storage_delitem(sd,stor,index,amount);
  436. else
  437. clif_additem(sd,0,0,flag);
  438. } // valid amount
  439. }// valid index
  440. }// storage open
  441. }
  442. return 0;
  443. }
  444. int storage_guild_storageaddfromcart(struct map_session_data *sd,int index,int amount)
  445. {
  446. struct guild_storage *stor;
  447. nullpo_retr(0, sd);
  448. if((stor=guild2storage(sd->status.guild_id)) != NULL) {
  449. if( (stor->storage_amount <= MAX_GUILD_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open
  450. if(index>=0 && index<MAX_INVENTORY) { // valid index
  451. if( (amount <= sd->status.cart[index].amount) && (amount > 0) ) { //valid amount
  452. if(guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0)
  453. pc_cart_delitem(sd,index,amount,0);
  454. } // valid amount
  455. }// valid index
  456. }// storage not full & storage open
  457. }
  458. return 0;
  459. }
  460. int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amount)
  461. {
  462. struct guild_storage *stor;
  463. nullpo_retr(0, sd);
  464. if((stor=guild2storage(sd->status.guild_id)) != NULL) {
  465. if(stor->storage_status == 1) { // storage open
  466. if(index>=0 && index<MAX_GUILD_STORAGE) { // valid index
  467. if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
  468. if(pc_cart_additem(sd,&stor->storage[index],amount)==0){
  469. guild_storage_delitem(sd,stor,index,amount);
  470. }
  471. } // valid amount
  472. }// valid index
  473. }// storage open
  474. }
  475. return 0;
  476. }
  477. int storage_guild_storageclose(struct map_session_data *sd)
  478. {
  479. struct guild_storage *stor;
  480. nullpo_retr(0, sd);
  481. if((stor=guild2storage(sd->status.guild_id)) != NULL) {
  482. intif_send_guild_storage(sd->status.account_id,stor);
  483. stor->storage_status = 0;
  484. sd->state.storage_flag = 0;
  485. sortage_gsortitem(stor);
  486. }
  487. clif_storageclose(sd);
  488. return 0;
  489. }
  490. int storage_guild_storage_quit(struct map_session_data *sd,int flag)
  491. {
  492. struct guild_storage *stor;
  493. nullpo_retr(0, sd);
  494. stor = numdb_search(guild_storage_db,sd->status.guild_id);
  495. if(stor) {
  496. if(!flag)
  497. intif_send_guild_storage(sd->status.account_id,stor);
  498. stor->storage_status = 0;
  499. sd->state.storage_flag = 0;
  500. }
  501. return 0;
  502. }