Skip to content

Commit

Permalink
Move check cards related code into separate functions.
Browse files Browse the repository at this point in the history
This remove code duplicates and improve a bit code.
  • Loading branch information
4144 committed Jul 18, 2015
1 parent 88bf50a commit f26152a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 70 deletions.
56 changes: 14 additions & 42 deletions src/map/clif.c
Expand Up @@ -5715,54 +5715,30 @@ void clif_solved_charname(int fd, int charid, const char* name)
/// 017b <packet len>.W { <name id>.W }*
void clif_use_card(struct map_session_data *sd,int idx)
{
int i,c,ep;
int fd=sd->fd;
int i, c;
int fd;

nullpo_retv(sd);
if (idx < 0 || idx >= MAX_INVENTORY) //Crash-fix from bad packets.
fd = sd->fd;
if (sd->state.trading != 0)
return;
if (!pc->can_insert_card(sd, idx))
return;

if (!sd->inventory_data[idx] || sd->inventory_data[idx]->type != IT_CARD)
return; //Avoid parsing invalid item indexes (no card/no item)

ep=sd->inventory_data[idx]->equip;
WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
WFIFOW(fd,0)=0x17b;

for(i=c=0;i<MAX_INVENTORY;i++){
int j;

if(sd->inventory_data[i] == NULL)
continue;
if(sd->inventory_data[i]->type!=IT_WEAPON && sd->inventory_data[i]->type!=IT_ARMOR)
continue;
if(itemdb_isspecial(sd->status.inventory[i].card[0])) //Can't slot it
continue;

if (sd->status.inventory[i].identify == 0) //Not identified
continue;

if ((sd->inventory_data[i]->equip&ep) == 0) //Not equippable on this part.
continue;

if(sd->inventory_data[i]->type==IT_WEAPON && ep==EQP_SHIELD) //Shield card won't go on left weapon.
continue;

ARR_FIND( 0, sd->inventory_data[i]->slot, j, sd->status.inventory[i].card[j] == 0 );
if (j == sd->inventory_data[i]->slot) // No room
continue;
WFIFOHEAD(fd, MAX_INVENTORY * 2 + 4);
WFIFOW(fd, 0) = 0x17b;

if( sd->status.inventory[i].equip > 0 ) // Do not check items that are already equipped
for (i = c = 0; i < MAX_INVENTORY; i++) {
if (!pc->can_insert_card_into(sd, idx, i))
continue;

WFIFOW(fd,4+c*2)=i+2;
WFIFOW(fd, 4 + c * 2) = i + 2;
c++;
}

if( !c ) return; // no item is available for card insertion
if (!c) return; // no item is available for card insertion

WFIFOW(fd,2)=4+c*2;
WFIFOSET(fd,WFIFOW(fd,2));
WFIFOW(fd, 2) = 4 + c * 2;
WFIFOSET(fd, WFIFOW(fd, 2));
}


Expand Down Expand Up @@ -11394,8 +11370,6 @@ void clif_parse_AutoSpell(int fd,struct map_session_data *sd)
/// 017a <card index>.W
void clif_parse_UseCard(int fd,struct map_session_data *sd)
{
if (sd->state.trading != 0)
return;
clif->use_card(sd,RFIFOW(fd,2)-2);
}

Expand All @@ -11404,8 +11378,6 @@ void clif_parse_UseCard(int fd,struct map_session_data *sd)
/// 017c <card index>.W <equip index>.W
void clif_parse_InsertCard(int fd,struct map_session_data *sd)
{
if (sd->state.trading != 0)
return;
pc->insert_card(sd,RFIFOW(fd,2)-2,RFIFOW(fd,4)-2);
}

Expand Down
98 changes: 70 additions & 28 deletions src/map/pc.c
Expand Up @@ -4059,42 +4059,78 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
}
return 1;
}

/**
* Checks if the given card can be inserted into the given equipment piece.
*
* @param sd The current character.
* @param idx_card The card's inventory index (note: it must be a valid index and can be checked by pc_can_insert_card)
* @param idx_equip The target equipment's inventory index.
* @retval true if the card can be inserted.
*/
bool pc_can_insert_card_into(struct map_session_data* sd, int idx_card, int idx_equip)
{
int i;

nullpo_ret(sd);

if (idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL)
return false; //Invalid item index.
if (sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1)
return false; // target item missing
if (sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR)
return false; // only weapons and armor are allowed
if (sd->status.inventory[idx_equip].identify == 0)
return false; // target must be identified
if (itemdb_isspecial(sd->status.inventory[idx_equip].card[0]))
return false; // card slots reserved for other purposes
if (sd->status.inventory[idx_equip].equip != 0)
return false; // item must be unequipped
if ((sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0)
return false; // card cannot be compounded on this item type
if (sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD)
return false; // attempted to place shield card on left-hand weapon.

ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0);
if (i == sd->inventory_data[idx_equip]->slot)
return false; // no free slots
return true;
}

/**
* Checks if the given item is card and it can be inserted into some equipment.
*
* @param sd The current character.
* @param idx_card The card's inventory index.
* @retval true if the card can be inserted.
*/
bool pc_can_insert_card(struct map_session_data* sd, int idx_card)
{
nullpo_ret(sd);

if (idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL)
return false; //Invalid card index.
if (sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1)
return false; // target card missing
if (sd->inventory_data[idx_card]->type != IT_CARD)
return false; // must be a card
return true;
}

/*==========================================
* Append a card to an item ?
*------------------------------------------*/
int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
{
int i;
int nameid;

nullpo_ret(sd);

if( idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL )
return 0; //Invalid item index.
if( idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL )
return 0; //Invalid card index.
if( sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1 )
return 0; // target item missing
if( sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1 )
return 0; // target card missing
if( sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR )
return 0; // only weapons and armor are allowed
if( sd->inventory_data[idx_card]->type != IT_CARD )
return 0; // must be a card
if( sd->status.inventory[idx_equip].identify == 0 )
return 0; // target must be identified
if( itemdb_isspecial(sd->status.inventory[idx_equip].card[0]) )
return 0; // card slots reserved for other purposes
if( (sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0 )
return 0; // card cannot be compounded on this item type
if( sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD )
return 0; // attempted to place shield card on left-hand weapon.
if( sd->status.inventory[idx_equip].equip != 0 )
return 0; // item must be unequipped

ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0 );
if( i == sd->inventory_data[idx_equip]->slot )
return 0; // no free slots
if (sd->state.trading != 0)
return 0;

if (!pc->can_insert_card(sd, idx_card) || !pc->can_insert_card_into(sd, idx_card, idx_equip))
return 0;

// remember the card id to insert
nameid = sd->status.inventory[idx_card].nameid;
Expand All @@ -4105,6 +4141,10 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
}
else
{// success
int i;
ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0);
if (i == sd->inventory_data[idx_equip]->slot)
return 0; // no free slots
logs->pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]);
sd->status.inventory[idx_equip].card[i] = nameid;
logs->pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]);
Expand Down Expand Up @@ -11497,7 +11537,9 @@ void pc_defaults(void) {
pc->skill = pc_skill;

pc->insert_card = pc_insert_card;

pc->can_insert_card = pc_can_insert_card;
pc->can_insert_card_into = pc_can_insert_card_into;

pc->steal_item = pc_steal_item;
pc->steal_coin = pc_steal_coin;

Expand Down
2 changes: 2 additions & 0 deletions src/map/pc.h
Expand Up @@ -880,6 +880,8 @@ END_ZEROED_BLOCK; /* End */
int (*skill) (struct map_session_data *sd, int id, int level, int flag);

int (*insert_card) (struct map_session_data *sd,int idx_card,int idx_equip);
bool (*can_insert_card) (struct map_session_data* sd, int idx_card);
bool (*can_insert_card_into) (struct map_session_data* sd, int idx_card, int idx_equip);

int (*steal_item) (struct map_session_data *sd,struct block_list *bl, uint16 skill_lv);
int (*steal_coin) (struct map_session_data *sd,struct block_list *bl);
Expand Down

0 comments on commit f26152a

Please sign in to comment.