* Updated Silent Breeze effect, only gives chance to give silence status to target and the caster (Eira), bugreport:8529, http://rathena.org/board/tracker/issue-8529-homunculus-s-eira-silent-breeze/

* Follow up 80f7984, and some minors

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh 2014-01-24 22:44:26 +07:00
parent 5a1f3f95c4
commit a0760f171b
8 changed files with 89 additions and 95 deletions

View File

@ -8066,6 +8066,8 @@ ACMD_FUNC(cash)
}
else clif_displaymessage(fd, msg_txt(sd,149)); // Unable to decrease the number/value.
} else {
if (-value > sd->cashPoints) //By command, if cash < value, force it to remove all
value = -sd->cashPoints;
if( (ret=pc_paycash(sd, -value, 0, LOG_TYPE_COMMAND)) >= 0){
// If this option is set, the message is already sent by pc function
if( !battle_config.cashshop_show_points ){

View File

@ -190,22 +190,26 @@ static void cashshop_read_db( void ){
}
}
/*
* Attempts to purchase a cashshop item from the list.
/** Attempts to purchase a cashshop item from the list.
* Checks if the transaction is valid and if the user has enough inventory space to receive the item.
* If yes, take cashpoints and give items;
* else return clif_error.
* If yes, take cashpoints and give items; else return clif_error.
* @param sd Player that request to buy item(s)
* @param kafrapoints
* @param n Count of item list
* @param item_list Array of item ID
* @return true: success, false: fail
*/
void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list ){
bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list ){
uint32 totalcash = 0;
uint32 totalweight = 0;
int i,new_;
if( sd == NULL || item_list == NULL ){
return;
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_UNKNOWN );
return false;
}else if( sd->state.trading ){
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_PC_STATE );
return;
return false;
}
new_ = 0;
@ -218,14 +222,14 @@ void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
if( tab > CASHSHOP_TAB_SEARCH ){
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKNOWN );
return;
return false;
}
ARR_FIND( 0, cash_shop_items[tab].count, j, nameid == cash_shop_items[tab].item[j]->nameid );
if( j == cash_shop_items[tab].count || !itemdb_exists( nameid ) ){
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKNOWN );
return;
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKONWN_ITEM );
return false;
}else if( !itemdb_isstackable( nameid ) && quantity > 1 ){
uint32* quantity_ptr = (uint32*)item_list + i * 5 + 2;
ShowWarning( "Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable cash item %d!\n", sd->status.name, sd->status.account_id, sd->status.char_id, quantity, nameid );
@ -242,7 +246,7 @@ void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
case CHKADDITEM_OVERAMOUNT:
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT );
return;
return false;
}
totalcash += cash_shop_items[tab].item[j]->price * quantity;
@ -251,15 +255,15 @@ void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
if( ( totalweight + sd->weight ) > sd->max_weight ){
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT );
return;
return false;
}else if( pc_inventoryblank( sd ) < new_ ){
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT );
return;
return false;
}
if(pc_paycash( sd, totalcash, kafrapoints, LOG_TYPE_CASH ) < 0){
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_SHORTTAGE_CASH );
return;
return false;
}
for( i = 0; i < n; ++i ){
@ -278,21 +282,22 @@ void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
switch( pc_additem( sd, &item_tmp, quantity, LOG_TYPE_CASH ) ){
case ADDITEM_OVERWEIGHT:
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT );
return;
return false;
case ADDITEM_OVERITEM:
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT );
return;
return false;
case ADDITEM_OVERAMOUNT:
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT );
return;
return false;
case ADDITEM_STACKLIMIT:
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_RUNE_OVERCOUNT );
return;
return false;
}
}
}
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_SUCCESS );
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_SUCCESS ); //Doesn't show any message?
return true;
}
/*

View File

@ -10,7 +10,7 @@
int do_init_cashshop( void );
int do_final_cashshop( void );
void cashshop_reloaddb( void );
void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list );
bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list );
// Taken from AEGIS
enum CASH_SHOP_TAB_CODE{

View File

@ -14965,8 +14965,6 @@ void clif_cashshop_result( struct map_session_data *sd, uint16 item_id, uint16 r
/// 0288 <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W }.4B*count (PACKETVER >= 20100803)
/// 0848 <packet len>.W <count>.W <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W <tab>.W }.6B*count (PACKETVER >= 20130000)
void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){
int fail = 0;
struct s_packet_db* info;
int cmd = RFIFOW(fd,0);
@ -14974,16 +14972,17 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){
info = &packet_db[sd->packet_ver][cmd];
if( sd->state.trading || !sd->npc_shopid )
fail = 1;
if( sd->state.trading || !sd->npc_shopid ) {
clif_cashshop_ack(sd,1);
return;
}
else {
#if PACKETVER < 20101116
short nameid = RFIFOW(fd,info->pos[0]);
short amount = RFIFOW(fd,info->pos[1]);
int points = RFIFOL(fd,info->pos[2]);
fail = npc_cashshop_buy(sd, nameid, amount, points);
clif_cashshop_ack(sd,fail);
clif_cashshop_ack(sd,npc_cashshop_buy(sd, nameid, amount, points));
#else
int s_itl = (cmd==0x848)?10:4; //item _list size (depend on cmd even for 2013+)
int len = RFIFOW(fd,info->pos[0]);
@ -14996,13 +14995,15 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){
return;
}
if(cmd==0x848){
cashshop_buylist( sd, points, count, item_list);
if (cashshop_buylist( sd, points, count, item_list))
clif_cashshop_ack(sd,0);
return;
} else {
fail = npc_cashshop_buylist(sd,points,count,item_list);
clif_cashshop_ack(sd,npc_cashshop_buylist(sd,points,count,item_list));
return;
}
#endif
}
clif_cashshop_ack(sd,fail);
}
/// Adoption System

View File

@ -8,33 +8,30 @@
#include "../common/mmo.h" // ITEM_NAME_LENGTH
#include "map.h"
// 32k array entries in array (the rest goes to the db)
/// 32k array entries in array (the rest goes to the db)
#define MAX_ITEMDB 0x8000
//Use apple for unknown items.
///Use apple for unknown items.
#define UNKNOWN_ITEM_ID 512
// The maximum number of item delays
/// The maximum number of item delays
#define MAX_ITEMDELAYS 10
#define MAX_SEARCH 5 //Designed for search functions, species max number of matches to display.
/* maximum amount of items a combo may require */
///Designed for search functions, species max number of matches to display.
#define MAX_SEARCH 5
///Maximum amount of items a combo may require
#define MAX_ITEMS_PER_COMBO 6
//The only item group required by the code to be known. See const.txt for the full list.
#define IG_FINDINGORE 6
#define IG_POTION 37
#define MAX_ITEMGROUP 390 ///The max. item group count (increase this when needed). TODO: Remove this limit and use dynamic allocaton
#define MAX_ITEMGROUP 390 ///The max. item group count (increase this when needed). TODO: Remove this limit and use dynamic allocaton if needed
#define MAX_ITEMGROUP_RANDGROUP 4 ///Max group for random item (increase this when needed).
#define MAX_ITEMGROUP_RANDGROUP 4 ///Max group for random item (increase this when needed). TODO: Remove this limit and use dynamic allocaton if needed
#define CARD0_FORGE 0x00FF
#define CARD0_CREATE 0x00FE
#define CARD0_PET ((short)0xFF00)
//Marks if the card0 given is "special" (non-item id used to mark pets/created items. [Skotlex]
///Marks if the card0 given is "special" (non-item id used to mark pets/created items. [Skotlex]
#define itemdb_isspecial(i) (i == CARD0_FORGE || i == CARD0_CREATE || i == CARD0_PET)
///Enum of item id (for hardcoded purpose)
@ -120,9 +117,7 @@ enum item_itemid {
ITEMID_JOB_MANUAL50 = 14592,
};
/**
* Mercenary Scrolls
*/
///Mercenary Scrolls
enum mercenary_scroll_item_list {
ITEMID_BOW_MERCENARY_SCROLL1 = 12153,
ITEMID_BOW_MERCENARY_SCROLL2,
@ -156,9 +151,7 @@ enum mercenary_scroll_item_list {
ITEMID_SPEARMERCENARY_SCROLL10,
};
/**
* Rune Knight
*/
///Rune Knight
enum rune_item_list {
ITEMID_NAUTHIZ = 12725,
ITEMID_RAIDO,
@ -172,9 +165,7 @@ enum rune_item_list {
ITEMID_LUX_ANIMA = 22540,
};
/**
* Mechanic
*/
///Mechanic
enum mechanic_item_list {
ITEMID_ACCELERATOR = 2800,
ITEMID_HOVERING_BOOSTER,
@ -193,9 +184,7 @@ enum mechanic_item_list {
ITEMID_LIME_GREEN_PTS,
};
/**
* Genetic
*/
///Genetic
enum genetic_item_list {
ITEMID_SEED_OF_HORNY_PLANT = 6210,
ITEMID_BLOODSUCK_PLANT_SEED = 6211,
@ -250,9 +239,7 @@ enum genetic_item_list {
ITEMID_BLACK_THING_TO_THROW,
};
/**
* Guillotine Cross
*/
///Guillotine Cross
enum poison_item_list {
ITEMID_PARALYSE = 12717,
ITEMID_LEECHESEND,
@ -264,9 +251,7 @@ enum poison_item_list {
ITEMID_VENOMBLEED,
};
/**
* Spell Books
*/
///Spell Books
enum spell_book_item_list {
ITEMID_MAGIC_BOOK_FB = 6189,
ITEMID_MAGIC_BOOK_CB,
@ -287,9 +272,7 @@ enum spell_book_item_list {
ITEMID_MAGIC_BOOK_DL,
};
/**
* Cash Food
*/
///Cash Food
enum cash_food_item_list {
ITEMID_STR_DISH10_ = 12202,
ITEMID_AGI_DISH10_,
@ -299,10 +282,12 @@ enum cash_food_item_list {
ITEMID_VIT_DISH10_,
};
///Item No Use List
enum item_nouse_list {
NOUSE_SITTING = 0x01,
};
///Item job
enum e_item_job {
ITEMJ_NORMAL = 0x01,
ITEMJ_UPPER = 0x02,
@ -312,6 +297,7 @@ enum e_item_job {
ITEMJ_THIRD_BABY = 0x20,
};
///Item combo struct
struct item_combo {
struct script_code *script;
unsigned short *nameid;/* nameid array */
@ -320,6 +306,7 @@ struct item_combo {
bool isRef;/* whether this struct is a reference or the master */
};
///Main item data struct
struct item_data {
uint16 nameid;
char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
@ -386,7 +373,7 @@ struct item_data {
/* Struct of item group entry */
struct s_item_group {
uint16 nameid, ///item id
duration; ///duration if item as rental item
duration; ///duration if item as rental item (in minute)
uint16 amount; ///amount of item will be obtained
bool isAnnounced, ///broadcast if player get this item
isNamed; ///named the item (if possible)
@ -403,7 +390,7 @@ struct s_item_group_random {
struct s_item_group_db {
struct s_item_group *must;
uint16 must_qty;
struct s_item_group_random random[MAX_ITEMGROUP_RANDGROUP]; //! TODO: Move this fixed array to dynamic allocation!
struct s_item_group_random random[MAX_ITEMGROUP_RANDGROUP]; //! TODO: Move this fixed array to dynamic allocation if needed.
};
struct item_data* itemdb_searchname(const char *name);

View File

@ -3854,10 +3854,14 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
return 0;
}
/*==========================================
* Cash Shop
*------------------------------------------*/
/** Makes player pays by using cash points
* @param sd Player who pays
* @param price How many point player has to pay
* @param points
* @param type e_log_pick_type
* @return -2: Paying negative points, -1: Not enough points, otherwise is succes (cash+points)
*/
int pc_paycash(struct map_session_data *sd, int price, int points, e_log_pick_type type ){
int cash;
nullpo_retr(-1,sd);

View File

@ -507,6 +507,9 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
if (skill_id == AL_TELEPORT && sd->skillitem == skill_id && sd->skillitemlv > 2)
return false; // Teleport lv 3 bypasses this check.[Inkfish]
if (map[m].flag.noskill)
return true;
// Epoque:
// This code will compare the player's attack motion value which is influenced by ASPD before
// allowing a skill to be cast. This is to prevent no-delay ACT files from spamming skills such as
@ -643,7 +646,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
break;
}
return (map[m].flag.noskill);
return false;
}
/** Check if the homunculus skill is ok to be processed
@ -9789,32 +9792,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
case MH_SILENT_BREEZE: {
struct status_change *ssc = status_get_sc(src);
struct block_list *m_bl = battle_get_master(src);
int heal;
if(tsc){
const enum sc_type scs[] = {
SC_MANDRAGORA, SC_HARMONIZE, SC_DEEPSLEEP, SC_VOICEOFSIREN, SC_SLEEP, SC_CONFUSION, SC_HALLUCINATION
};
for (i = 0; i < ARRAYLENGTH(scs); i++) {
if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
}
if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target
status_change_start(src,bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill_get_time(skill_id, skill_lv),1|2|8);
}
heal = status_get_sp(src) + status_get_lv(src); //cur_sp+blvl @TODO need real value
status_heal(bl, heal, 0, 7);
case MH_SILENT_BREEZE:
{
//Silences the homunculus and target
status_change_start(src,src,SC_SILENCE,10000,skill_lv,0,0,0,skill_get_time(skill_id,skill_lv),0);
status_change_start(src,bl,SC_SILENCE,10000,skill_lv,0,0,0,skill_get_time(skill_id,skill_lv),0);
//now inflict silence on everyone
if(ssc && !ssc->data[SC_SILENCE]) //put inavoidable silence on homun
status_change_start(src, src, SC_SILENCE, 100, skill_lv, 0,0,0, skill_get_time(skill_id, skill_lv),1|2|8);
if(m_bl) {
struct status_change *msc = status_get_sc(m_bl);
if(msc && !msc->data[SC_SILENCE]) //put inavoidable silence on master
status_change_start(src, m_bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill_get_time(skill_id, skill_lv),1|2|8);
}
if (hd)
//Recover the target's HP
status_heal(bl,status_get_lv(src)+status_get_sp(src),0,3); //(custom)
//Removes these SC from target
if (tsc) {
const enum sc_type scs[] = {
SC_MANDRAGORA, SC_HARMONIZE, SC_DEEPSLEEP, SC_VOICEOFSIREN, SC_SLEEP, SC_CONFUSION, SC_HALLUCINATION
};
for (i = 0; i < ARRAYLENGTH(scs); i++)
if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
}
if (hd)
skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
}
break;
@ -11864,7 +11859,7 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
int alive = 1;
// are the coordinates out of range?
if( ux <= 0 || uy <= 0 || ux >= map[sd->bl.m].xs || uy >= map[sd->bl.m].ys ){
if( ux <= 0 || uy <= 0 || ux >= map[src->m].xs || uy >= map[src->m].ys ){
continue;
}

View File

@ -7221,7 +7221,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
* @param src: Source of the status change [PC|MOB|HOM|MER|ELEM|NPC]
* @param bl: Target of the status change (See: enum sc_type)
* @param type: Status change (SC_*)
* @param rate: Initial percentage rate of affecting bl
* @param rate: Initial percentage rate of affecting bl (0~10000)
* @param val1~4: Depends on type of status change
* @param tick: Initial duration that the status change affects bl
* @param flag: Value which determines what parts to calculate