git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@968 54d463be-8e91-2dee-dedb-b68131a5f0ec
179 lines
4.6 KiB
C
179 lines
4.6 KiB
C
// $Id: vending.c,v 1.2 2004/09/25 05:32:19 MouseJstr Exp $
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "clif.h"
|
|
#include "itemdb.h"
|
|
#include "map.h"
|
|
#include "vending.h"
|
|
#include "pc.h"
|
|
#include "skill.h"
|
|
#include "battle.h"
|
|
#include "nullpo.h"
|
|
#include "log.h"
|
|
|
|
/*==========================================
|
|
* 露店閉鎖
|
|
*------------------------------------------
|
|
*/
|
|
void vending_closevending(struct map_session_data *sd)
|
|
{
|
|
|
|
nullpo_retv(sd);
|
|
|
|
sd->vender_id=0;
|
|
clif_closevendingboard(&sd->bl,0);
|
|
}
|
|
|
|
/*==========================================
|
|
* 露店アイテムリスト要求
|
|
*------------------------------------------
|
|
*/
|
|
void vending_vendinglistreq(struct map_session_data *sd,int id)
|
|
{
|
|
struct map_session_data *vsd;
|
|
|
|
nullpo_retv(sd);
|
|
|
|
if( (vsd=map_id2sd(id)) == NULL )
|
|
return;
|
|
if(vsd->vender_id==0)
|
|
return;
|
|
clif_vendinglist(sd,id,vsd->vending);
|
|
}
|
|
|
|
/*==========================================
|
|
* 露店アイテム購入
|
|
*------------------------------------------
|
|
*/
|
|
void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned char *p)
|
|
{
|
|
int i, j, w, z, new_ = 0, blank, vend_list[12];
|
|
short amount, index;
|
|
struct map_session_data *vsd = map_id2sd(id);
|
|
|
|
nullpo_retv(sd);
|
|
|
|
blank = pc_inventoryblank(sd);
|
|
|
|
if (vsd == NULL)
|
|
return;
|
|
if (vsd->vender_id == 0)
|
|
return;
|
|
if (vsd->vender_id == sd->bl.id)
|
|
return;
|
|
for(i = 0, w = z = 0; 8 + 4 * i < len; i++) {
|
|
amount = *(short*)(p + 4 * i);
|
|
index = *(short*)(p + 2 + 4 * i) - 2;
|
|
|
|
if (amount < 0) return; // exploit
|
|
/* for(j = 0; j < vsd->vend_num; j++)
|
|
if (0 < vsd->vending[j].amount && amount <= vsd->vending[j].amount && vsd->vending[j].index == index)
|
|
break;
|
|
*/
|
|
//ADD_start
|
|
for(j = 0; j < vsd->vend_num; j++) {
|
|
if (0 < vsd->vending[j].amount && vsd->vending[j].index == index) {
|
|
if (amount > vsd->vending[j].amount || amount <= 0) {
|
|
clif_buyvending(sd,index,vsd->vending[j].amount, 4);
|
|
return;
|
|
}
|
|
if (amount <= vsd->vending[j].amount) break;
|
|
}
|
|
}
|
|
//ADD_end
|
|
if (j == vsd->vend_num)
|
|
return; // 売り切れ
|
|
vend_list[i] = j;
|
|
z += vsd->vending[j].value * amount;
|
|
if (z > sd->status.zeny){
|
|
clif_buyvending(sd, index, amount, 1);
|
|
return; // zeny不足
|
|
}
|
|
w += itemdb_weight(vsd->status.cart[index].nameid) * amount;
|
|
if (w + sd->weight > sd->max_weight) {
|
|
clif_buyvending(sd, index, amount, 2);
|
|
return; // 重量超過
|
|
}
|
|
switch(pc_checkadditem(sd, vsd->status.cart[index].nameid, amount)) {
|
|
case ADDITEM_EXIST:
|
|
break;
|
|
case ADDITEM_NEW:
|
|
new_++;
|
|
if (new_ > blank)
|
|
return; // 種類数超過
|
|
break;
|
|
case ADDITEM_OVERAMOUNT:
|
|
return; // アイテム数超過
|
|
}
|
|
}
|
|
if (z < 0 || z > MAX_ZENY) { // Zeny Bug Fixed by Darkchild
|
|
clif_tradecancelled(sd);
|
|
clif_tradecancelled(vsd);
|
|
return;
|
|
}
|
|
|
|
pc_payzeny(sd, z);
|
|
pc_getzeny(vsd, z);
|
|
for(i = 0; 8 + 4 * i < len; i++) {
|
|
amount = *(short*)(p + 4 *i);
|
|
index = *(short*)(p + 2 + 4 * i) - 2;
|
|
//if (amount < 0) break; // tested at start of the function
|
|
pc_additem(sd,&vsd->status.cart[index],amount);
|
|
vsd->vending[vend_list[i]].amount -= amount;
|
|
pc_cart_delitem(vsd, index, amount, 0);
|
|
clif_vendingreport(vsd, index, amount);
|
|
|
|
//log added by Lupus
|
|
#ifndef TXT_ONLY
|
|
if(log_config.vend > 0) {
|
|
log_vend(sd,vsd, index, amount, z); // for Item + Zeny. log.
|
|
//we log ZENY only with the 1st item. Then zero it for the rest items 8).
|
|
z = 0;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
/*==========================================
|
|
* 露店開設
|
|
*------------------------------------------
|
|
*/
|
|
void vending_openvending(struct map_session_data *sd,int len,char *message,int flag,unsigned char *p)
|
|
{
|
|
int i;
|
|
|
|
nullpo_retv(sd);
|
|
|
|
if(!pc_checkskill(sd,MC_VENDING) || !pc_iscarton(sd)) { // cart skill and cart check [Valaris]
|
|
clif_skill_fail(sd,MC_VENDING,0,0);
|
|
return;
|
|
}
|
|
|
|
if (flag) {
|
|
for(i = 0; (85 + 8 * i < len) && (i < MAX_VENDING); i++) {
|
|
sd->vending[i].index = *(short*)(p+8*i)-2;
|
|
sd->vending[i].amount = *(short*)(p+2+8*i);
|
|
sd->vending[i].value = *(int*)(p+4+8*i);
|
|
if(sd->vending[i].value > battle_config.vending_max_value)
|
|
sd->vending[i].value=battle_config.vending_max_value;
|
|
else if(sd->vending[i].value == 0)
|
|
sd->vending[i].value = 1000000; // auto set to 1 million [celest]
|
|
// カート内のアイテム数と販売するアイテム数に相違があったら中止
|
|
if(pc_cartitem_amount(sd, sd->vending[i].index, sd->vending[i].amount) < 0 || sd->vending[i].value < 0) { // fixes by Valaris and fritz
|
|
clif_skill_fail(sd, MC_VENDING, 0, 0);
|
|
return;
|
|
}
|
|
}
|
|
sd->vender_id = sd->bl.id;
|
|
sd->vend_num = i;
|
|
strcpy(sd->message,message);
|
|
if (clif_openvending(sd,sd->vender_id,sd->vending) > 0)
|
|
clif_showvendingboard(&sd->bl,message,0);
|
|
else
|
|
sd->vender_id = 0;
|
|
}
|
|
}
|
|
|