Various cleanups.

* Added and cleaned up comments.
* Added checks to prevent map server crashes.
* Cleaned up some reports from CPPCheck.
* Other various stylization cleanups.
This commit is contained in:
aleos89 2014-10-02 09:16:52 -04:00
parent ce090ce916
commit 2b870c24d5
15 changed files with 2036 additions and 1855 deletions

View File

@ -44,23 +44,33 @@ static struct eri *delay_damage_ers; //For battle delay damage structures.
#define DAMAGE_SUBRATE(a) { damage -= (int64)damage * (a) / 100; } #define DAMAGE_SUBRATE(a) { damage -= (int64)damage * (a) / 100; }
#define DAMAGE_ADDRATE(a) { damage += (int64)damage * (a) / 100; } #define DAMAGE_ADDRATE(a) { damage += (int64)damage * (a) / 100; }
int battle_getcurrentskill(struct block_list *bl) { //Returns the current/last skill in use by this bl. /**
* Returns the current/list skill used by the bl
* @param bl
* @return skill_id
*/
int battle_getcurrentskill(struct block_list *bl)
{
struct unit_data *ud; struct unit_data *ud;
if( bl->type == BL_SKILL ) { if( bl->type == BL_SKILL ) {
struct skill_unit *su = (struct skill_unit*)bl; struct skill_unit *su = (struct skill_unit*)bl;
return su->group?su->group->skill_id:0; return (su && su->group?su->group->skill_id:0);
} }
ud = unit_bl2ud(bl); ud = unit_bl2ud(bl);
return ud?ud->skill_id:0; return (ud?ud->skill_id:0);
} }
/*========================================== /**
* Get random targetting enemy * Get random targeting enemy
*------------------------------------------*/ * @param bl
static int battle_gettargeted_sub(struct block_list *bl, va_list ap) { * @param ap
* @return Found target (1) or not found (0)
*/
static int battle_gettargeted_sub(struct block_list *bl, va_list ap)
{
struct block_list **bl_list; struct block_list **bl_list;
struct unit_data *ud; struct unit_data *ud;
int target_id; int target_id;
@ -87,7 +97,13 @@ static int battle_gettargeted_sub(struct block_list *bl, va_list ap) {
return 0; return 0;
} }
struct block_list* battle_gettargeted(struct block_list *target) { /**
* Returns list of targets
* @param target
* @return Target list
*/
struct block_list* battle_gettargeted(struct block_list *target)
{
struct block_list *bl_list[24]; struct block_list *bl_list[24];
int c = 0; int c = 0;
nullpo_retr(NULL, target); nullpo_retr(NULL, target);
@ -101,9 +117,14 @@ struct block_list* battle_gettargeted(struct block_list *target) {
return bl_list[rnd()%c]; return bl_list[rnd()%c];
} }
/**
//Returns the id of the current targetted character of the passed bl. [Skotlex] * Returns the ID of the current targeted character of the passed bl
int battle_gettarget(struct block_list* bl) { * @param bl
* @return Target Unit ID
* @author [Skotlex]
*/
int battle_gettarget(struct block_list* bl)
{
switch (bl->type) { switch (bl->type) {
case BL_PC: return ((struct map_session_data*)bl)->ud.target; case BL_PC: return ((struct map_session_data*)bl)->ud.target;
@ -117,7 +138,14 @@ int battle_gettarget(struct block_list* bl) {
return 0; return 0;
} }
static int battle_getenemy_sub(struct block_list *bl, va_list ap) { /**
* Get random enemy
* @param bl
* @param ap
* @return Found target (1) or not found (0)
*/
static int battle_getenemy_sub(struct block_list *bl, va_list ap)
{
struct block_list **bl_list; struct block_list **bl_list;
struct block_list *target; struct block_list *target;
int *c; int *c;
@ -143,8 +171,16 @@ static int battle_getenemy_sub(struct block_list *bl, va_list ap) {
return 0; return 0;
} }
// Picks a random enemy of the given type (BL_PC, BL_CHAR, etc) within the range given. [Skotlex] /**
struct block_list* battle_getenemy(struct block_list *target, int type, int range) { * Returns list of enemies within given range
* @param target
* @param type
* @param range
* @return Target list
* @author [Skotlex]
*/
struct block_list* battle_getenemy(struct block_list *target, int type, int range)
{
struct block_list *bl_list[24]; struct block_list *bl_list[24];
int c = 0; int c = 0;
@ -159,7 +195,15 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang
return bl_list[rnd()%c]; return bl_list[rnd()%c];
} }
static int battle_getenemyarea_sub(struct block_list *bl, va_list ap) {
/**
* Get random enemy within area
* @param bl
* @param ap
* @return Found target (1) or not found (0)
*/
static int battle_getenemyarea_sub(struct block_list *bl, va_list ap)
{
struct block_list **bl_list, *src; struct block_list **bl_list, *src;
int *c, ignore_id; int *c, ignore_id;
@ -185,8 +229,18 @@ static int battle_getenemyarea_sub(struct block_list *bl, va_list ap) {
return 0; return 0;
} }
// Pick a random enemy /**
struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id) { * Returns list of enemies within an area
* @param src
* @param x
* @param y
* @param range
* @param type
* @param ignore_id
* @return Target list
*/
struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id)
{
struct block_list *bl_list[24]; struct block_list *bl_list[24];
int c = 0; int c = 0;
@ -201,7 +255,7 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int
return bl_list[rnd()%c]; return bl_list[rnd()%c];
} }
// Damage delayed info /// Damage Delayed Structure
struct delay_damage { struct delay_damage {
int src_id; int src_id;
int target_id; int target_id;
@ -216,7 +270,8 @@ struct delay_damage {
enum bl_type src_type; enum bl_type src_type;
}; };
int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data)
{
struct delay_damage *dat = (struct delay_damage *)data; struct delay_damage *dat = (struct delay_damage *)data;
if ( dat ) { if ( dat ) {
@ -246,10 +301,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
if( dat->dmg_lv > ATK_BLOCK && dat->attack_type ) if( dat->dmg_lv > ATK_BLOCK && dat->attack_type )
skill_counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick); skill_counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
map_freeblock_unlock(); map_freeblock_unlock();
} else if( !src && dat->skill_id == CR_REFLECTSHIELD ) { } else if( !src && dat->skill_id == CR_REFLECTSHIELD ) { // it was monster reflected damage, and the monster died, we pass the damage to the character as expected
/**
* it was monster reflected damage, and the monster died, we pass the damage to the character as expected
**/
map_freeblock_lock(); map_freeblock_lock();
status_fix_damage(target, target, dat->damage, dat->delay); status_fix_damage(target, target, dat->damage, dat->delay);
map_freeblock_unlock(); map_freeblock_unlock();
@ -322,11 +374,18 @@ int battle_attr_ratio(int atk_elem,int def_type, int def_lv) {
return attr_fix_table[def_lv-1][atk_elem][def_type]; return attr_fix_table[def_lv-1][atk_elem][def_type];
} }
/*========================================== /**
* Does attribute fix modifiers. * Does attribute fix modifiers.
* Added passing of the chars so that the status changes can affect it. [Skotlex] * Added passing of the chars so that the status changes can affect it. [Skotlex]
* Note: Passing src/target == NULL is perfectly valid, it skips SC_ checks. * Note: Passing src/target == NULL is perfectly valid, it skips SC_ checks.
*------------------------------------------*/ * @param src
* @param target
* @param damage
* @param atk_elem
* @param def_type
* @param def_lv
* @return damage
*/
int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv) int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv)
{ {
struct status_change *sc = NULL, *tsc = NULL; struct status_change *sc = NULL, *tsc = NULL;
@ -339,7 +398,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
atk_elem = rnd()%ELE_ALL; atk_elem = rnd()%ELE_ALL;
if (!CHK_ELEMENT(def_type) || !CHK_ELEMENT_LEVEL(def_lv)) { if (!CHK_ELEMENT(def_type) || !CHK_ELEMENT_LEVEL(def_lv)) {
ShowError("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv); ShowError("battle_attr_fix: unknown attribute type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv);
return damage; return damage;
} }
@ -360,6 +419,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
break; break;
} }
} }
if( target && target->type == BL_SKILL ) { if( target && target->type == BL_SKILL ) {
if( atk_elem == ELE_FIRE && battle_getcurrentskill(target) == GN_WALLOFTHORN ) { if( atk_elem == ELE_FIRE && battle_getcurrentskill(target) == GN_WALLOFTHORN ) {
struct skill_unit *su = (struct skill_unit*)target; struct skill_unit *su = (struct skill_unit*)target;
@ -381,7 +441,6 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
} }
} }
if( tsc && tsc->count ) { //increase dmg by target status if( tsc && tsc->count ) { //increase dmg by target status
switch(atk_elem) { switch(atk_elem) {
case ELE_FIRE: case ELE_FIRE:
@ -424,9 +483,19 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
return (int64)damage*ratio/100; return (int64)damage*ratio/100;
} }
/*========================================== /**
* Calculates card bonuses damage adjustments. * Calculates card bonuses damage adjustments.
*------------------------------------------*/ * @param attack_type
* @param src
* @param target
* @param nk
* @param s_ele
* @param s_ele_
* @param damage
* @param left
* @param flag
* @return damage
*/
int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int64 damage, int left, int flag){ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int64 damage, int left, int flag){
struct map_session_data *sd, *tsd; struct map_session_data *sd, *tsd;
short cardfix = 1000, t_class, s_class, s_race2, t_race2; short cardfix = 1000, t_class, s_class, s_race2, t_race2;
@ -718,11 +787,18 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
return (int)(damage - original_damage); return (int)(damage - original_damage);
} }
/*========================================== /**
* Check damage through status. * Check damage through status.
* ATK may be MISS, BLOCKED FAIL, reduc, increase, end status... * ATK may be MISS, BLOCKED FAIL, reduc, increase, end status.
* After this we apply bg/gvg reduction * After this we apply bg/gvg reduction
*------------------------------------------*/ * @param src
* @param bl
* @param d
* @param damage
* @param skill_id
* @param skill_lv
* @return damage
*/
int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv) int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv)
{ {
struct map_session_data *sd = NULL; struct map_session_data *sd = NULL;
@ -764,10 +840,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if (skill_id == PA_PRESSURE) if (skill_id == PA_PRESSURE)
return damage; //This skill bypass everything else. return damage; //This skill bypass everything else.
if( sc && sc->count ) { if( sc && sc->count ) { // SC_* that reduce damage to 0.
/**
* SC_* that reduce damage to 0.
**/
if( sc->data[SC_BASILICA] && !(status_get_mode(src)&MD_BOSS) ) { if( sc->data[SC_BASILICA] && !(status_get_mode(src)&MD_BOSS) ) {
d->dmg_lv = ATK_BLOCK; d->dmg_lv = ATK_BLOCK;
return 0; return 0;
@ -1010,9 +1083,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER); status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER);
} }
/** // Damage reductions
* Damage reductions
**/
// Assumptio doubles the def & mdef on RE mode, otherwise gives a reduction on the final damage. [Igniz] // Assumptio doubles the def & mdef on RE mode, otherwise gives a reduction on the final damage. [Igniz]
#ifndef RENEWAL #ifndef RENEWAL
if( sc->data[SC_ASSUMPTIO] ) { if( sc->data[SC_ASSUMPTIO] ) {
@ -1286,9 +1357,14 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
return damage; return damage;
} }
/*========================================== /**
* Calculates BG related damage adjustments. * Calculates BG related damage adjustments.
*------------------------------------------ * @param src
* @param bl
* @param damage
* @param skill_id
* @param flag
* @return damage
* Credits: * Credits:
* Original coder Skoltex * Original coder Skoltex
* Initial refactoring by Baalberith * Initial refactoring by Baalberith
@ -1326,6 +1402,14 @@ int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64
return damage; return damage;
} }
/**
* Determines whether target can be hit
* @param src
* @param bl
* @param skill_id
* @param flag
* @return Can be hit (true) or can't be hit (false)
*/
bool battle_can_hit_gvg_target(struct block_list *src,struct block_list *bl,uint16 skill_id,int flag) bool battle_can_hit_gvg_target(struct block_list *src,struct block_list *bl,uint16 skill_id,int flag)
{ {
struct mob_data* md = BL_CAST(BL_MOB, bl); struct mob_data* md = BL_CAST(BL_MOB, bl);
@ -1347,9 +1431,15 @@ bool battle_can_hit_gvg_target(struct block_list *src,struct block_list *bl,uint
return true; return true;
} }
/*========================================== /**
* Calculates GVG related damage adjustments. * Calculates GVG related damage adjustments.
*------------------------------------------*/ * @param src
* @param bl
* @param damage
* @param skill_id
* @param flag
* @return damage
*/
int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag) int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag)
{ {
if (!damage) //No reductions to make. if (!damage) //No reductions to make.
@ -1381,9 +1471,13 @@ int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64
return damage; return damage;
} }
/*========================================== /**
* HP/SP drain calculation * HP/SP drain calculation
*------------------------------------------*/ * @param damage
* @param rate
* @param per
* @return diff
*/
static int battle_calc_drain(int64 damage, int rate, int per) static int battle_calc_drain(int64 damage, int rate, int per)
{ {
int64 diff = 0; int64 diff = 0;
@ -1400,9 +1494,14 @@ static int battle_calc_drain(int64 damage, int rate, int per)
return (int)diff; return (int)diff;
} }
/*========================================== /**
* Passive skill damage increases * Passive skill damage increases
*------------------------------------------*/ * @param sd
* @param target
* @param dmg
* @param type
* @return damage
*/
int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,int64 dmg,int type) int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,int64 dmg,int type)
{ {
int64 damage; int64 damage;
@ -1517,7 +1616,6 @@ int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,in
break; break;
} }
if(sd->sc.data[SC_GN_CARTBOOST]) // cart boost adds mastery type damage if(sd->sc.data[SC_GN_CARTBOOST]) // cart boost adds mastery type damage
damage += 10*sd->sc.data[SC_GN_CARTBOOST]->val1; damage += 10*sd->sc.data[SC_GN_CARTBOOST]->val1;
@ -1750,11 +1848,12 @@ static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id)
return 0; return 0;
} }
/** Damage calculation for adjusting skill damage /**
* Damage calculation for adjusting skill damage
* @param caster Applied caster type for damage skill * @param caster Applied caster type for damage skill
* @param type BL_Type of attacker * @param type BL_Type of attacker
* @author [Lilith] for the first release of this, [Cydh] * @author [Lilith] for the first release of this, [Cydh]
**/ */
#ifdef ADJUST_SKILL_DAMAGE #ifdef ADJUST_SKILL_DAMAGE
static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) { static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) {
if (caster == 0) if (caster == 0)
@ -1771,7 +1870,8 @@ static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) {
return false; return false;
} }
/** Gets skill damage rate from a skill (based on skill_damage_db.txt) /**
* Gets skill damage rate from a skill (based on skill_damage_db.txt)
* @param src * @param src
* @param target * @param target
* @param skill_id * @param skill_id
@ -1813,7 +1913,8 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
return 0; return 0;
} }
/** Gets skill damage rate from a skill (based on 'skill_damage' mapflag) /**
* Gets skill damage rate from a skill (based on 'skill_damage' mapflag)
* @param src * @param src
* @param target * @param target
* @param skill_id * @param skill_id
@ -1868,7 +1969,8 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
return rate; return rate;
} }
/** Check skill damage adjustment based on mapflags and skill_damage_db.txt for specified skill /**
* Check skill damage adjustment based on mapflags and skill_damage_db.txt for specified skill
* @param src * @param src
* @param target * @param target
* @param skill_id * @param skill_id
@ -1919,7 +2021,7 @@ static bool target_has_infinite_defense(struct block_list *target, int skill_id)
if(target->type == BL_SKILL) { if(target->type == BL_SKILL) {
TBL_SKILL *su = ((TBL_SKILL*)target); TBL_SKILL *su = ((TBL_SKILL*)target);
if (su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD)) if (su && su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD))
return true; return true;
} }
return (tstatus->mode&MD_PLANT && skill_id != RA_CLUSTERBOMB return (tstatus->mode&MD_PLANT && skill_id != RA_CLUSTERBOMB
@ -3419,9 +3521,6 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
skillratio = 50 * skill_lv + 10 * (sd ? pc_checkskill(sd,KN_SPEARMASTERY) : 5); skillratio = 50 * skill_lv + 10 * (sd ? pc_checkskill(sd,KN_SPEARMASTERY) : 5);
RE_LVL_DMOD(150); // Base level bonus. RE_LVL_DMOD(150); // Base level bonus.
break; break;
/**
* GC Guilotine Cross
**/
case GC_CROSSIMPACT: case GC_CROSSIMPACT:
skillratio += 900 + 100 * skill_lv; skillratio += 900 + 100 * skill_lv;
RE_LVL_DMOD(120); RE_LVL_DMOD(120);
@ -3447,15 +3546,9 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
case GC_DARKCROW: case GC_DARKCROW:
skillratio += 100 * (skill_lv - 1); skillratio += 100 * (skill_lv - 1);
break; break;
/**
* Arch Bishop
**/
case AB_DUPLELIGHT_MELEE: case AB_DUPLELIGHT_MELEE:
skillratio += 10 * skill_lv; skillratio += 10 * skill_lv;
break; break;
/**
* Ranger
**/
case RA_ARROWSTORM: case RA_ARROWSTORM:
skillratio += 900 + 80 * skill_lv; skillratio += 900 + 80 * skill_lv;
RE_LVL_DMOD(100); RE_LVL_DMOD(100);
@ -3484,9 +3577,6 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
case RA_SENSITIVEKEEN: case RA_SENSITIVEKEEN:
skillratio += 50 * skill_lv; skillratio += 50 * skill_lv;
break; break;
/**
* Mechanic
**/
case NC_BOOSTKNUCKLE: case NC_BOOSTKNUCKLE:
skillratio += 100 + 100 * skill_lv + status_get_dex(src); skillratio += 100 + 100 * skill_lv + status_get_dex(src);
RE_LVL_DMOD(120); RE_LVL_DMOD(120);
@ -3862,9 +3952,6 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
skillratio += -100 + 100 * skill_lv + 3 * status_get_lv(src); skillratio += -100 + 100 * skill_lv + 3 * status_get_lv(src);
skillratio = (skillratio * status_get_lv(src)) / 120; skillratio = (skillratio * status_get_lv(src)) / 120;
break; break;
/**
* Rebellion
**/
case RL_MASS_SPIRAL: case RL_MASS_SPIRAL:
// 200%:400%:600%:800%:1000% // 200%:400%:600%:800%:1000%
skillratio += -100 + (200 * skill_lv); skillratio += -100 + (200 * skill_lv);
@ -4294,7 +4381,7 @@ struct Damage battle_calc_defense_reduction(struct Damage wd, struct block_list
* RE DEF Reduction * RE DEF Reduction
* Damage = Attack * (4000+eDEF)/(4000+eDEF*10) - sDEF * Damage = Attack * (4000+eDEF)/(4000+eDEF*10) - sDEF
* Pierce defence gains 1 atk per def/2 * Pierce defence gains 1 atk per def/2
**/ */
if( def1 == -400 ) /* being hit by a gazillion units, -400 creates a division by 0 and subsequently crashes */ if( def1 == -400 ) /* being hit by a gazillion units, -400 creates a division by 0 and subsequently crashes */
def1 = -399; def1 = -399;
ATK_ADD2(wd.damage, wd.damage2, ATK_ADD2(wd.damage, wd.damage2,
@ -4591,13 +4678,8 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
hp = 2*hp/100; //2% hp loss per hit hp = 2*hp/100; //2% hp loss per hit
status_zap(src, hp, 0); status_zap(src, hp, 0);
} }
/** // affecting non-skills
* affecting non-skills
**/
if( !skill_id ) { if( !skill_id ) {
/**
* RK Enchant Blade
**/
if( sc->data[SC_ENCHANTBLADE] && sd && ( (is_attack_right_handed(src, skill_id) && sd->weapontype1) || (is_attack_left_handed(src, skill_id) && sd->weapontype2) ) ) { if( sc->data[SC_ENCHANTBLADE] && sd && ( (is_attack_right_handed(src, skill_id) && sd->weapontype1) || (is_attack_left_handed(src, skill_id) && sd->weapontype2) ) ) {
//[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt //[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt
ATK_ADD(wd.damage, wd.damage2, ( sc->data[SC_ENCHANTBLADE]->val1*20+100 ) * status_get_lv(src) / 150 + status_get_int(src) ); ATK_ADD(wd.damage, wd.damage2, ( sc->data[SC_ENCHANTBLADE]->val1*20+100 ) * status_get_lv(src) / 150 + status_get_int(src) );
@ -4743,7 +4825,7 @@ struct block_list *battle_check_devotion(struct block_list *bl) {
return d_bl; return d_bl;
} }
/* /**
* Check if we should reflect the damage and calculate it if so * Check if we should reflect the damage and calculate it if so
* @param attack_type : BL_WEAPON,BL_MAGIC or BL_MISC * @param attack_type : BL_WEAPON,BL_MAGIC or BL_MISC
* @param wd : weapon damage * @param wd : weapon damage
@ -5218,7 +5300,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
flag.infdef=(tstatus->mode&MD_PLANT?1:0); flag.infdef=(tstatus->mode&MD_PLANT?1:0);
if( target->type == BL_SKILL) { if( target->type == BL_SKILL) {
TBL_SKILL *su = (TBL_SKILL*)target; TBL_SKILL *su = (TBL_SKILL*)target;
if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
if( su && su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
flag.infdef = 1; flag.infdef = 1;
} }
@ -5257,9 +5340,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case AL_HEAL: case AL_HEAL:
case PR_BENEDICTIO: case PR_BENEDICTIO:
case PR_SANCTUARY: case PR_SANCTUARY:
/**
* Arch Bishop
**/
case AB_HIGHNESSHEAL: case AB_HIGHNESSHEAL:
ad.damage = skill_calc_heal(src, target, skill_id, skill_lv, false); ad.damage = skill_calc_heal(src, target, skill_id, skill_lv, false);
break; break;
@ -5295,9 +5375,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case PF_SOULBURN: case PF_SOULBURN:
ad.damage = tstatus->sp * 2; ad.damage = tstatus->sp * 2;
break; break;
/**
* Arch Bishop
**/
case AB_RENOVATIO: case AB_RENOVATIO:
ad.damage = status_get_lv(src) * 10 + sstatus->int_; ad.damage = status_get_lv(src) * 10 + sstatus->int_;
break; break;
@ -5360,9 +5437,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
} }
break; break;
case MG_THUNDERSTORM: case MG_THUNDERSTORM:
/** // in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
* in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
**/
#ifndef RENEWAL #ifndef RENEWAL
skillratio -= 20; skillratio -= 20;
#endif #endif
@ -5455,9 +5530,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio += 20*skill_lv-20; skillratio += 20*skill_lv-20;
break; break;
#endif #endif
/**
* Arch Bishop
**/
case AB_JUDEX: case AB_JUDEX:
skillratio += 200 + 20 * skill_lv; skillratio += 200 + 20 * skill_lv;
RE_LVL_DMOD(100); RE_LVL_DMOD(100);
@ -5469,9 +5541,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case AB_DUPLELIGHT_MAGIC: case AB_DUPLELIGHT_MAGIC:
skillratio += 100 + 20 * skill_lv; skillratio += 100 + 20 * skill_lv;
break; break;
/**
* Warlock
**/
case WL_SOULEXPANSION: case WL_SOULEXPANSION:
skillratio += 300 + 100 * skill_lv + status_get_int(src); skillratio += 300 + 100 * skill_lv + status_get_int(src);
RE_LVL_DMOD(100); RE_LVL_DMOD(100);
@ -5793,7 +5862,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
/** /**
* RE MDEF Reduction * RE MDEF Reduction
* Damage = Magic Attack * (1000+eMDEF)/(1000+eMDEF) - sMDEF * Damage = Magic Attack * (1000+eMDEF)/(1000+eMDEF) - sMDEF
**/ */
if (mdef < -99) if (mdef < -99)
mdef = -99; // Avoid divide by 0 mdef = -99; // Avoid divide by 0
@ -6250,7 +6319,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
} }
} else if( target->type == BL_SKILL ) { } else if( target->type == BL_SKILL ) {
TBL_SKILL *su = (TBL_SKILL*)target; TBL_SKILL *su = (TBL_SKILL*)target;
if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
if( su && su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
md.damage = 1; md.damage = 1;
} }
@ -6678,7 +6748,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
/** /**
* We need to calculate the DMG before the hp reduction, because it can kill the source. * We need to calculate the DMG before the hp reduction, because it can kill the source.
* For further information: bugreport:4950 * For further information: bugreport:4950
**/ */
ret_val = (damage_lv)skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,skill_lv,tick,0); ret_val = (damage_lv)skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,skill_lv,tick,0);
status_zap(src, sstatus->max_hp*9/100, 0);//Damage to self is always 9% status_zap(src, sstatus->max_hp*9/100, 0);//Damage to self is always 9%
@ -6765,7 +6835,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if ( target->type == BL_SKILL && damage > 0 ) { if ( target->type == BL_SKILL && damage > 0 ) {
TBL_SKILL *su = (TBL_SKILL*)target; TBL_SKILL *su = (TBL_SKILL*)target;
if (su->group) { if (su && su->group) {
if (su->group->skill_id == HT_BLASTMINE) if (su->group->skill_id == HT_BLASTMINE)
skill_blown(src, target, 3, -1, 0); skill_blown(src, target, 3, -1, 0);
if (su->group->skill_id == GN_WALLOFTHORN) { if (su->group->skill_id == GN_WALLOFTHORN) {
@ -7077,9 +7147,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
case BL_SKILL: case BL_SKILL:
{ {
TBL_SKILL *su = (TBL_SKILL*)target; TBL_SKILL *su = (TBL_SKILL*)target;
if( !su->group )
return 0; if( su && su->group && skill_get_inf2(su->group->skill_id)&INF2_TRAP ) { //Only a few skills can target traps...
if( skill_get_inf2(su->group->skill_id)&INF2_TRAP ) { //Only a few skills can target traps...
switch( battle_getcurrentskill(src) ) { switch( battle_getcurrentskill(src) ) {
case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps
case RK_DRAGONBREATH_WATER: case RK_DRAGONBREATH_WATER:
@ -7183,10 +7252,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
break; break;
case BL_SKILL: { case BL_SKILL: {
struct skill_unit *su = (struct skill_unit *)src; struct skill_unit *su = (struct skill_unit *)src;
if (!su->group)
return 0;
if (su->group->src_id == target->id) { if (su && su->group && su->group->src_id == target->id) {
int inf2 = skill_get_inf2(su->group->skill_id); int inf2 = skill_get_inf2(su->group->skill_id);
if (inf2&INF2_NO_TARGET_SELF) if (inf2&INF2_NO_TARGET_SELF)
return -1; return -1;
@ -7754,9 +7821,7 @@ static const struct _battle_data {
{ "bg_magic_attack_damage_rate", &battle_config.bg_magic_damage_rate, 60, 0, INT_MAX, }, { "bg_magic_attack_damage_rate", &battle_config.bg_magic_damage_rate, 60, 0, INT_MAX, },
{ "bg_misc_attack_damage_rate", &battle_config.bg_misc_damage_rate, 60, 0, INT_MAX, }, { "bg_misc_attack_damage_rate", &battle_config.bg_misc_damage_rate, 60, 0, INT_MAX, },
{ "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, }, { "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, },
/** // rAthena
* rAthena
**/
{ "max_third_parameter", &battle_config.max_third_parameter, 135, 10, SHRT_MAX, }, { "max_third_parameter", &battle_config.max_third_parameter, 135, 10, SHRT_MAX, },
{ "max_baby_third_parameter", &battle_config.max_baby_third_parameter, 108, 10, SHRT_MAX, }, { "max_baby_third_parameter", &battle_config.max_baby_third_parameter, 108, 10, SHRT_MAX, },
{ "max_trans_parameter", &battle_config.max_trans_parameter, 99, 10, SHRT_MAX, }, { "max_trans_parameter", &battle_config.max_trans_parameter, 99, 10, SHRT_MAX, },
@ -7837,10 +7902,9 @@ static const struct _battle_data {
{ "devotion_rdamage_skill_only", &battle_config.devotion_rdamage_skill_only, 1, 0, 1, }, { "devotion_rdamage_skill_only", &battle_config.devotion_rdamage_skill_only, 1, 0, 1, },
{ "max_extended_aspd", &battle_config.max_extended_aspd, 193, 100, 199, }, { "max_extended_aspd", &battle_config.max_extended_aspd, 193, 100, 199, },
}; };
#ifndef STATS_OPT_OUT #ifndef STATS_OPT_OUT
/** // rAthena anonymous statistic usage report -- packet is built here, and sent to char server to report.
* rAthena anonymous statistic usage report -- packet is built here, and sent to char server to report.
**/
void rAthena_report(char* date, char *time_c) { void rAthena_report(char* date, char *time_c) {
int i, rev = 0, bd_size = ARRAYLENGTH(battle_data); int i, rev = 0, bd_size = ARRAYLENGTH(battle_data);
unsigned int config = 0; unsigned int config = 0;
@ -7933,7 +7997,6 @@ void rAthena_report(char* date, char *time_c) {
CREATE(buf, char, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 ); CREATE(buf, char, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 );
/* build packet */ /* build packet */
WBUFW(buf,0) = 0x3000; WBUFW(buf,0) = 0x3000;
WBUFW(buf,2) = 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ); WBUFW(buf,2) = 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) );
WBUFW(buf,4) = 0x9c; WBUFW(buf,4) = 0x9c;

View File

@ -27,15 +27,20 @@ static unsigned int bg_team_counter = 0; // Next bg_id
struct battleground_data* bg_team_search(int bg_id) struct battleground_data* bg_team_search(int bg_id)
{ // Search a BG Team using bg_id { // Search a BG Team using bg_id
if( !bg_id ) return NULL; if( !bg_id )
return NULL;
return (struct battleground_data *)idb_get(bg_team_db, bg_id); return (struct battleground_data *)idb_get(bg_team_db, bg_id);
} }
struct map_session_data* bg_getavailablesd(struct battleground_data *bg) struct map_session_data* bg_getavailablesd(struct battleground_data *bg)
{ {
int i; int i;
nullpo_retr(NULL, bg); nullpo_retr(NULL, bg);
ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd != NULL); ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd != NULL);
return ( i < MAX_BG_MEMBERS ) ? bg->members[i].sd : NULL; return ( i < MAX_BG_MEMBERS ) ? bg->members[i].sd : NULL;
} }
@ -44,9 +49,10 @@ int bg_team_delete(int bg_id)
int i; int i;
struct battleground_data *bg = bg_team_search(bg_id); struct battleground_data *bg = bg_team_search(bg_id);
if( bg == NULL ) return 0; if( bg == NULL )
for( i = 0; i < MAX_BG_MEMBERS; i++ ) return 0;
{
for( i = 0; i < MAX_BG_MEMBERS; i++ ) {
struct map_session_data *sd; struct map_session_data *sd;
if( (sd = bg->members[i].sd) == NULL ) if( (sd = bg->members[i].sd) == NULL )
@ -55,7 +61,9 @@ int bg_team_delete(int bg_id)
bg_send_dot_remove(sd); bg_send_dot_remove(sd);
sd->bg_id = 0; sd->bg_id = 0;
} }
idb_remove(bg_team_db, bg_id); idb_remove(bg_team_db, bg_id);
return 1; return 1;
} }
@ -63,7 +71,10 @@ int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y)
{ // Warps a Team { // Warps a Team
int i; int i;
struct battleground_data *bg = bg_team_search(bg_id); struct battleground_data *bg = bg_team_search(bg_id);
if( bg == NULL ) return 0;
if( bg == NULL )
return 0;
for( i = 0; i < MAX_BG_MEMBERS; i++ ) for( i = 0; i < MAX_BG_MEMBERS; i++ )
if( bg->members[i].sd != NULL ) pc_setpos(bg->members[i].sd, mapindex, x, y, CLR_TELEPORT); if( bg->members[i].sd != NULL ) pc_setpos(bg->members[i].sd, mapindex, x, y, CLR_TELEPORT);
return 1; return 1;
@ -81,10 +92,12 @@ int bg_team_join(int bg_id, struct map_session_data *sd)
int i; int i;
struct battleground_data *bg = bg_team_search(bg_id); struct battleground_data *bg = bg_team_search(bg_id);
if( bg == NULL || sd == NULL || sd->bg_id ) return 0; if( bg == NULL || sd == NULL || sd->bg_id )
return 0;
ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL); ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL);
if( i == MAX_BG_MEMBERS ) return 0; // No free slots if( i == MAX_BG_MEMBERS )
return 0; // No free slots
sd->bg_id = bg_id; sd->bg_id = bg_id;
bg->members[i].sd = sd; bg->members[i].sd = sd;
@ -94,8 +107,7 @@ int bg_team_join(int bg_id, struct map_session_data *sd)
guild_send_dot_remove(sd); guild_send_dot_remove(sd);
for( i = 0; i < MAX_BG_MEMBERS; i++ ) for( i = 0; i < MAX_BG_MEMBERS; i++ ) {
{
struct map_session_data *pl_sd; struct map_session_data *pl_sd;
if( (pl_sd = bg->members[i].sd) != NULL && pl_sd != sd ) if( (pl_sd = bg->members[i].sd) != NULL && pl_sd != sd )
@ -126,12 +138,14 @@ int bg_team_leave(struct map_session_data *sd, int flag)
ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd); ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd);
if( i < MAX_BG_MEMBERS ) // Removes member from BG if( i < MAX_BG_MEMBERS ) // Removes member from BG
memset(&bg->members[i], 0, sizeof(bg->members[0])); memset(&bg->members[i], 0, sizeof(bg->members[0]));
bg->count--; bg->count--;
if( flag ) if( flag )
sprintf(output, "Server : %s has quit the game...", sd->status.name); sprintf(output, "Server : %s has quit the game...", sd->status.name);
else else
sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name); sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name);
clif_bg_message(bg, 0, "Server", output, strlen(output) + 1); clif_bg_message(bg, 0, "Server", output, strlen(output) + 1);
if( bg->logout_event[0] && flag ) if( bg->logout_event[0] && flag )
@ -143,10 +157,13 @@ int bg_team_leave(struct map_session_data *sd, int flag)
int bg_member_respawn(struct map_session_data *sd) int bg_member_respawn(struct map_session_data *sd)
{ // Respawn after killed { // Respawn after killed
struct battleground_data *bg; struct battleground_data *bg;
if( sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bg = bg_team_search(sd->bg_id)) == NULL ) if( sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bg = bg_team_search(sd->bg_id)) == NULL )
return 0; return 0;
if( bg->mapindex == 0 ) if( bg->mapindex == 0 )
return 0; // Respawn not handled by Core return 0; // Respawn not handled by Core
pc_setpos(sd, bg->mapindex, bg->x, bg->y, CLR_OUTSIGHT); pc_setpos(sd, bg->mapindex, bg->x, bg->y, CLR_OUTSIGHT);
status_revive(&sd->bl, 1, 100); status_revive(&sd->bl, 1, 100);
@ -176,20 +193,20 @@ int bg_create(unsigned short mapindex, short rx, short ry, const char *ev, const
int bg_team_get_id(struct block_list *bl) int bg_team_get_id(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
switch( bl->type ) switch( bl->type ) {
{
case BL_PC: case BL_PC:
return ((TBL_PC*)bl)->bg_id; return ((TBL_PC*)bl)->bg_id;
case BL_PET: case BL_PET:
if( ((TBL_PET*)bl)->master ) if( ((TBL_PET*)bl)->master )
return ((TBL_PET*)bl)->master->bg_id; return ((TBL_PET*)bl)->master->bg_id;
break; break;
case BL_MOB: case BL_MOB: {
{
struct map_session_data *msd; struct map_session_data *msd;
struct mob_data *md = (TBL_MOB*)bl; struct mob_data *md = (TBL_MOB*)bl;
if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL ) if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL )
return msd->bg_id; return msd->bg_id;
return md->bg_id; return md->bg_id;
} }
case BL_HOM: case BL_HOM:
@ -212,9 +229,12 @@ int bg_send_message(struct map_session_data *sd, const char *mes, int len)
struct battleground_data *bg; struct battleground_data *bg;
nullpo_ret(sd); nullpo_ret(sd);
if( sd->bg_id == 0 || (bg = bg_team_search(sd->bg_id)) == NULL ) if( sd->bg_id == 0 || (bg = bg_team_search(sd->bg_id)) == NULL )
return 0; return 0;
clif_bg_message(bg, sd->bl.id, sd->status.name, mes, len); clif_bg_message(bg, sd->bl.id, sd->status.name, mes, len);
return 0; return 0;
} }
@ -226,24 +246,27 @@ int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap)
struct battleground_data *bg = db_data2ptr(data); struct battleground_data *bg = db_data2ptr(data);
struct map_session_data *sd; struct map_session_data *sd;
int i; int i;
nullpo_ret(bg); nullpo_ret(bg);
for( i = 0; i < MAX_BG_MEMBERS; i++ )
{ for( i = 0; i < MAX_BG_MEMBERS; i++ ) {
if( (sd = bg->members[i].sd) == NULL ) if( (sd = bg->members[i].sd) == NULL )
continue; continue;
if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y )
{ // xy update if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y ) { // xy update
bg->members[i].x = sd->bl.x; bg->members[i].x = sd->bl.x;
bg->members[i].y = sd->bl.y; bg->members[i].y = sd->bl.y;
clif_bg_xy(sd); clif_bg_xy(sd);
} }
} }
return 0; return 0;
} }
int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{ {
bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick); bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick);
return 0; return 0;
} }

View File

@ -496,11 +496,14 @@ int channel_display_list(struct map_session_data *sd, char *options){
clif_displaymessage(sd->fd, msg_txt(sd,1476)); // You have not joined any channels. clif_displaymessage(sd->fd, msg_txt(sd,1476)); // You have not joined any channels.
else { else {
unsigned char k; unsigned char k;
struct Channel *channel;
for(k = 0; k < sd->channel_count; k++) { for(k = 0; k < sd->channel_count; k++) {
char output[128]; char output[128];
struct Channel *channel;
if (!(channel = sd->channels[k])) if (!(channel = sd->channels[k]))
continue; continue;
sprintf(output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users) sprintf(output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users)
clif_displaymessage(sd->fd, output); clif_displaymessage(sd->fd, output);
} }

View File

@ -17373,7 +17373,8 @@ void clif_crimson_marker(struct map_session_data *sd, struct block_list *bl, boo
//void clif_broadcast_obtain_special_item() {} //void clif_broadcast_obtain_special_item() {}
#ifdef DUMP_UNKNOWN_PACKET #ifdef DUMP_UNKNOWN_PACKET
void DumpUnknow(int fd,TBL_PC *sd,int cmd,int packet_len){ void DumpUnknown(int fd,TBL_PC *sd,int cmd,int packet_len)
{
const char* packet_txt = "save/packet.txt"; const char* packet_txt = "save/packet.txt";
FILE* fp; FILE* fp;
time_t time_server; time_t time_server;
@ -17527,7 +17528,7 @@ static int clif_parse(int fd)
packet_db[packet_ver][cmd].func(fd, sd); packet_db[packet_ver][cmd].func(fd, sd);
} }
#ifdef DUMP_UNKNOWN_PACKET #ifdef DUMP_UNKNOWN_PACKET
else DumpUnknow(fd,sd,cmd,packet_len); else DumpUnknown(fd,sd,cmd,packet_len);
#endif #endif
RFIFOSKIP(fd, packet_len); RFIFOSKIP(fd, packet_len);
}; // main loop end }; // main loop end
@ -17540,7 +17541,6 @@ static int clif_parse(int fd)
*------------------------------------------*/ *------------------------------------------*/
void packetdb_readdb(void) void packetdb_readdb(void)
{ {
FILE *fp;
char line[1024]; char line[1024];
int cmd,i,j; int cmd,i,j;
int max_cmd=-1; int max_cmd=-1;
@ -18039,6 +18039,7 @@ void packetdb_readdb(void)
clif_config.packet_db_ver = MAX_PACKET_VER; clif_config.packet_db_ver = MAX_PACKET_VER;
for(f = 0; f < ARRAYLENGTH(filename); f++) { for(f = 0; f < ARRAYLENGTH(filename); f++) {
FILE *fp;
int ln = 0; int ln = 0;
int entries = 0; int entries = 0;
char *str[64], *p, *str2[64], *p2; char *str[64], *p, *str2[64], *p2;

View File

@ -29,7 +29,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static DBMap* party_db; // int party_id -> struct party_data* (releases data) static DBMap* party_db; // int party_id -> struct party_data* (releases data)
static DBMap* party_booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria] static DBMap* party_booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria]
static unsigned long party_booking_nextid = 1; static unsigned long party_booking_nextid = 1;
@ -53,39 +52,44 @@ static void party_fill_member(struct party_member* member, struct map_session_da
member->leader = leader; member->leader = leader;
} }
/// Get the member_id of a party member. /// Get the member_id of a party member.
/// Return -1 if not in party. /// Return -1 if not in party.
int party_getmemberid(struct party_data* p, struct map_session_data* sd) int party_getmemberid(struct party_data* p, struct map_session_data* sd)
{ {
int member_id; int member_id;
nullpo_retr(-1, p); nullpo_retr(-1, p);
if( sd == NULL ) if( sd == NULL )
return -1; // no player return -1; // no player
ARR_FIND(0, MAX_PARTY, member_id, ARR_FIND(0, MAX_PARTY, member_id,
p->party.member[member_id].account_id == sd->status.account_id && p->party.member[member_id].account_id == sd->status.account_id &&
p->party.member[member_id].char_id == sd->status.char_id); p->party.member[member_id].char_id == sd->status.char_id);
if( member_id == MAX_PARTY ) if( member_id == MAX_PARTY )
return -1; // not found return -1; // not found
return member_id; return member_id;
} }
/*========================================== /*==========================================
* Request an available sd of this party * Request an available sd of this party
*------------------------------------------*/ *------------------------------------------*/
struct map_session_data* party_getavailablesd(struct party_data *p) struct map_session_data* party_getavailablesd(struct party_data *p)
{ {
int i; int i;
nullpo_retr(NULL, p); nullpo_retr(NULL, p);
ARR_FIND(0, MAX_PARTY, i, p->data[i].sd != NULL); ARR_FIND(0, MAX_PARTY, i, p->data[i].sd != NULL);
return( i < MAX_PARTY ) ? p->data[i].sd : NULL; return( i < MAX_PARTY ) ? p->data[i].sd : NULL;
} }
/*========================================== /*==========================================
* Retrieves and validates the sd pointer for this party member [Skotlex] * Retrieves and validates the sd pointer for this party member [Skotlex]
*------------------------------------------*/ *------------------------------------------*/
static TBL_PC* party_sd_check(int party_id, int account_id, int char_id) static TBL_PC* party_sd_check(int party_id, int account_id, int char_id)
{ {
TBL_PC* sd = map_id2sd(account_id); TBL_PC* sd = map_id2sd(account_id);
@ -95,8 +99,8 @@ static TBL_PC* party_sd_check(int party_id, int account_id, int char_id)
if( sd->status.party_id == 0 ) if( sd->status.party_id == 0 )
sd->status.party_id = party_id; // auto-join if not in a party sd->status.party_id = party_id; // auto-join if not in a party
if (sd->status.party_id != party_id)
{ //If player belongs to a different party, kick him out. if (sd->status.party_id != party_id) { // If player belongs to a different party, kick him out.
intif_party_leave(party_id,account_id,char_id); intif_party_leave(party_id,account_id,char_id);
return NULL; return NULL;
} }
@ -113,6 +117,7 @@ void do_final_party(void)
party_db->destroy(party_db,NULL); party_db->destroy(party_db,NULL);
party_booking_db->destroy(party_booking_db,NULL); // Party Booking [Spiria] party_booking_db->destroy(party_booking_db,NULL); // Party Booking [Spiria]
} }
// Constructor, init vars // Constructor, init vars
void do_init_party(void) void do_init_party(void)
{ {
@ -127,6 +132,7 @@ struct party_data* party_search(int party_id)
{ {
if(!party_id) if(!party_id)
return NULL; return NULL;
return (struct party_data*)idb_get(party_db,party_id); return (struct party_data*)idb_get(party_db,party_id);
} }
@ -136,8 +142,7 @@ struct party_data* party_searchname(const char* str)
struct party_data* p; struct party_data* p;
DBIterator *iter = db_iterator(party_db); DBIterator *iter = db_iterator(party_db);
for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) ) for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) ) {
{
if( strncmpi(p->party.name,str,NAME_LENGTH) == 0 ) if( strncmpi(p->party.name,str,NAME_LENGTH) == 0 )
break; break;
} }
@ -154,21 +159,16 @@ int party_create(struct map_session_data *sd,char *name,int item,int item2)
safestrncpy(tname, name, NAME_LENGTH); safestrncpy(tname, name, NAME_LENGTH);
trim(tname); trim(tname);
if( !tname[0] ) if( !tname[0] ) // empty name
{// empty name
return 0; return 0;
}
if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating ) if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating ) { // already associated with a party
{// already associated with a party
clif_party_created(sd,2); clif_party_created(sd,2);
return -2; return -2;
} }
sd->party_creating = true; sd->party_creating = true;
party_fill_member(&leader, sd, 1); party_fill_member(&leader, sd, 1);
intif_create_party(&leader,name,item,item2); intif_create_party(&leader,name,item,item2);
return 1; return 1;
} }
@ -176,10 +176,10 @@ int party_create(struct map_session_data *sd,char *name,int item,int item2)
void party_created(int account_id,int char_id,int fail,int party_id,char *name) void party_created(int account_id,int char_id,int fail,int party_id,char *name)
{ {
struct map_session_data *sd; struct map_session_data *sd;
sd = map_id2sd(account_id); sd = map_id2sd(account_id);
if (!sd || sd->status.char_id != char_id || !sd->party_creating ) if (!sd || sd->status.char_id != char_id || !sd->party_creating ) { // Character logged off before creation ack?
{ //Character logged off before creation ack?
if (!fail) // break up party since player could not be added to it. if (!fail) // break up party since player could not be added to it.
intif_party_leave(party_id,account_id,char_id); intif_party_leave(party_id,account_id,char_id);
return; return;
@ -190,13 +190,13 @@ void party_created(int account_id,int char_id,int fail,int party_id,char *name)
if( !fail ) { if( !fail ) {
sd->status.party_id = party_id; sd->status.party_id = party_id;
clif_party_created(sd,0); // Success message clif_party_created(sd,0); // Success message
// We don't do any further work here because the char-server sends a party info packet right after creating the party // We don't do any further work here because the char-server sends a party info packet right after creating the party
if(party_create_byscript) { // returns party id in $@party_create_id if party is created by script if(party_create_byscript) { // returns party id in $@party_create_id if party is created by script
mapreg_setreg(add_str("$@party_create_id"),party_id); mapreg_setreg(add_str("$@party_create_id"),party_id);
party_create_byscript = 0; party_create_byscript = 0;
} }
} } else
else
clif_party_created(sd,1); // "party name already exists" clif_party_created(sd,1); // "party name already exists"
} }
@ -209,13 +209,15 @@ int party_request_info(int party_id, int char_id)
int party_recv_noinfo(int party_id, int char_id) int party_recv_noinfo(int party_id, int char_id)
{ {
party_broken(party_id); party_broken(party_id);
if( char_id != 0 )// requester if( char_id != 0 ) { // requester
{
struct map_session_data* sd; struct map_session_data* sd;
sd = map_charid2sd(char_id); sd = map_charid2sd(char_id);
if( sd && sd->status.party_id == party_id ) if( sd && sd->status.party_id == party_id )
sd->status.party_id = 0; sd->status.party_id = 0;
} }
return 0; return 0;
} }
@ -223,9 +225,10 @@ static void party_check_state(struct party_data *p)
{ {
int i; int i;
memset(&p->state, 0, sizeof(p->state)); memset(&p->state, 0, sizeof(p->state));
for (i = 0; i < MAX_PARTY; i ++) for (i = 0; i < MAX_PARTY; i ++) {
{ if (!p->party.member[i].online)
if (!p->party.member[i].online) continue; //Those not online shouldn't aport to skill usage and all that. continue; //Those not online shouldn't aport to skill usage and all that.
switch (p->party.member[i].class_) { switch (p->party.member[i].class_) {
case JOB_MONK: case JOB_MONK:
case JOB_BABY_MONK: case JOB_BABY_MONK:
@ -262,79 +265,90 @@ int party_recv_info(struct party* sp, int char_id)
nullpo_ret(sp); nullpo_ret(sp);
p = (struct party_data*)idb_get(party_db, sp->party_id); p = (struct party_data*)idb_get(party_db, sp->party_id);
if( p != NULL )// diff members
{ if( p != NULL ) { // diff members
int i; int i;
for( member_id = 0; member_id < MAX_PARTY; ++member_id ) for( member_id = 0; member_id < MAX_PARTY; ++member_id ) {
{
member = &p->party.member[member_id]; member = &p->party.member[member_id];
if( member->char_id == 0 ) if( member->char_id == 0 )
continue; // empty continue; // empty
ARR_FIND(0, MAX_PARTY, i, ARR_FIND(0, MAX_PARTY, i,
sp->member[i].account_id == member->account_id && sp->member[i].account_id == member->account_id &&
sp->member[i].char_id == member->char_id); sp->member[i].char_id == member->char_id);
if( i == MAX_PARTY ) if( i == MAX_PARTY )
removed[removed_count++] = member_id; removed[removed_count++] = member_id;
} }
for( member_id = 0; member_id < MAX_PARTY; ++member_id )
{ for( member_id = 0; member_id < MAX_PARTY; ++member_id ) {
member = &sp->member[member_id]; member = &sp->member[member_id];
if( member->char_id == 0 ) if( member->char_id == 0 )
continue; // empty continue; // empty
ARR_FIND(0, MAX_PARTY, i, ARR_FIND(0, MAX_PARTY, i,
p->party.member[i].account_id == member->account_id && p->party.member[i].account_id == member->account_id &&
p->party.member[i].char_id == member->char_id); p->party.member[i].char_id == member->char_id);
if( i == MAX_PARTY ) if( i == MAX_PARTY )
added[added_count++] = member_id; added[added_count++] = member_id;
} }
} } else {
else
{
for( member_id = 0; member_id < MAX_PARTY; ++member_id ) for( member_id = 0; member_id < MAX_PARTY; ++member_id )
if( sp->member[member_id].char_id != 0 ) if( sp->member[member_id].char_id != 0 )
added[added_count++] = member_id; added[added_count++] = member_id;
CREATE(p, struct party_data, 1); CREATE(p, struct party_data, 1);
idb_put(party_db, sp->party_id, p); idb_put(party_db, sp->party_id, p);
} }
while( removed_count > 0 )// no longer in party while( removed_count > 0 ) { // no longer in party
{
member_id = removed[--removed_count]; member_id = removed[--removed_count];
sd = p->data[member_id].sd; sd = p->data[member_id].sd;
if( sd == NULL ) if( sd == NULL )
continue; // not online continue; // not online
party_member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id); party_member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id);
} }
memcpy(&p->party, sp, sizeof(struct party)); memcpy(&p->party, sp, sizeof(struct party));
memset(&p->state, 0, sizeof(p->state)); memset(&p->state, 0, sizeof(p->state));
memset(&p->data, 0, sizeof(p->data)); memset(&p->data, 0, sizeof(p->data));
for( member_id = 0; member_id < MAX_PARTY; member_id++ )
{ for( member_id = 0; member_id < MAX_PARTY; member_id++ ) {
member = &p->party.member[member_id]; member = &p->party.member[member_id];
if ( member->char_id == 0 ) if ( member->char_id == 0 )
continue;// empty continue;// empty
p->data[member_id].sd = party_sd_check(sp->party_id, member->account_id, member->char_id); p->data[member_id].sd = party_sd_check(sp->party_id, member->account_id, member->char_id);
} }
party_check_state(p); party_check_state(p);
while( added_count > 0 )// new in party
{ while( added_count > 0 ) { // new in party
member_id = added[--added_count]; member_id = added[--added_count];
sd = p->data[member_id].sd; sd = p->data[member_id].sd;
if( sd == NULL ) if( sd == NULL )
continue;// not online continue;// not online
clif_charnameupdate(sd); //Update other people's display. [Skotlex] clif_charnameupdate(sd); //Update other people's display. [Skotlex]
clif_party_member_info(p,sd); clif_party_member_info(p,sd);
clif_party_option(p,sd,0x100); clif_party_option(p,sd,0x100);
clif_party_info(p,NULL); clif_party_info(p,NULL);
if( p->instance_id != 0 ) if( p->instance_id != 0 )
instance_reqinfo(sd,p->instance_id); instance_reqinfo(sd,p->instance_id);
} }
if( char_id != 0 )// requester
{ if( char_id != 0 ) { // requester
sd = map_charid2sd(char_id); sd = map_charid2sd(char_id);
if( sd && sd->status.party_id == sp->party_id && party_getmemberid(p,sd) == -1 ) if( sd && sd->status.party_id == sp->party_id && party_getmemberid(p,sd) == -1 )
sd->status.party_id = 0;// was not in the party sd->status.party_id = 0;// was not in the party
} }
return 0; return 0;
} }
@ -405,29 +419,28 @@ int party_reply_invite(struct map_session_data *sd,int party_id,int flag)
struct map_session_data* tsd; struct map_session_data* tsd;
struct party_member member; struct party_member member;
if( sd->party_invite != party_id ) if( sd->party_invite != party_id ) { // forged
{// forged
sd->party_invite = 0; sd->party_invite = 0;
sd->party_invite_account = 0; sd->party_invite_account = 0;
return 0; return 0;
} }
tsd = map_id2sd(sd->party_invite_account); tsd = map_id2sd(sd->party_invite_account);
if( flag == 1 && !sd->party_creating && !sd->party_joining ) if( flag == 1 && !sd->party_creating && !sd->party_joining ) { // accepted and allowed
{// accepted and allowed
sd->party_joining = true; sd->party_joining = true;
party_fill_member(&member, sd, 0); party_fill_member(&member, sd, 0);
intif_party_addmember(sd->party_invite, &member); intif_party_addmember(sd->party_invite, &member);
return 1; return 1;
} } else { // rejected or failure
else
{// rejected or failure
sd->party_invite = 0; sd->party_invite = 0;
sd->party_invite_account = 0; sd->party_invite_account = 0;
if( tsd != NULL ) if( tsd != NULL )
clif_party_inviteack(tsd,sd->status.name,1); clif_party_inviteack(tsd,sd->status.name,1);
return 0; return 0;
} }
return 0; return 0;
} }
@ -439,19 +452,20 @@ void party_member_joined(struct map_session_data *sd)
{ {
struct party_data* p = party_search(sd->status.party_id); struct party_data* p = party_search(sd->status.party_id);
int i; int i;
if (!p)
{ if (!p) {
party_request_info(sd->status.party_id, sd->status.char_id); party_request_info(sd->status.party_id, sd->status.char_id);
return; return;
} }
ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id ); ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id );
if (i < MAX_PARTY)
{ if (i < MAX_PARTY) {
p->data[i].sd = sd; p->data[i].sd = sd;
if( p->instance_id ) if( p->instance_id )
instance_reqinfo(sd,p->instance_id); instance_reqinfo(sd,p->instance_id);
} } else
else
sd->status.party_id = 0; //He does not belongs to the party really? sd->status.party_id = 0; //He does not belongs to the party really?
} }
@ -481,8 +495,7 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
return 0; return 0;
} }
if( flag ) if( flag ) { // failed
{// failed
if( sd2 != NULL ) if( sd2 != NULL )
clif_party_inviteack(sd2,sd->status.name,3); clif_party_inviteack(sd2,sd->status.name,3);
return 0; return 0;
@ -497,12 +510,13 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
if( sd2 != NULL ) if( sd2 != NULL )
clif_party_inviteack(sd2,sd->status.name,2); clif_party_inviteack(sd2,sd->status.name,2);
for( i = 0; i < ARRAYLENGTH(p->data); ++i ) for( i = 0; i < ARRAYLENGTH(p->data); ++i ) { // hp of the other party members
{// hp of the other party members
sd2 = p->data[i].sd; sd2 = p->data[i].sd;
if( sd2 && sd2->status.account_id != account_id && sd2->status.char_id != char_id ) if( sd2 && sd2->status.account_id != account_id && sd2->status.char_id != char_id )
clif_hpmeter_single(sd->fd, sd2->bl.id, sd2->battle_status.hp, sd2->battle_status.max_hp); clif_hpmeter_single(sd->fd, sd2->bl.id, sd2->battle_status.hp, sd2->battle_status.max_hp);
} }
clif_party_hp(sd); clif_party_hp(sd);
clif_party_xy(sd); clif_party_xy(sd);
clif_charnameupdate(sd); //Update char name's display [Skotlex] clif_charnameupdate(sd); //Update char name's display [Skotlex]
@ -520,6 +534,7 @@ int party_removemember(struct map_session_data* sd, int account_id, char* name)
int i; int i;
p = party_search(sd->status.party_id); p = party_search(sd->status.party_id);
if( p == NULL ) if( p == NULL )
return 0; return 0;
@ -535,6 +550,7 @@ int party_removemember(struct map_session_data* sd, int account_id, char* name)
return 0; // no such char in party return 0; // no such char in party
intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id); intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id);
return 1; return 1;
} }
@ -543,7 +559,9 @@ int party_removemember2(struct map_session_data *sd,int char_id,int party_id)
if( sd ) { if( sd ) {
if( !sd->status.party_id ) if( !sd->status.party_id )
return -3; return -3;
intif_party_leave(sd->status.party_id,sd->status.account_id,sd->status.char_id); intif_party_leave(sd->status.party_id,sd->status.account_id,sd->status.char_id);
return 1; return 1;
} else { } else {
int i; int i;
@ -557,8 +575,10 @@ int party_removemember2(struct map_session_data *sd,int char_id,int party_id)
return -1; return -1;
intif_party_leave(party_id,p->party.member[i].account_id,char_id); intif_party_leave(party_id,p->party.member[i].account_id,char_id);
return 1; return 1;
} }
return 0; return 0;
} }
@ -569,6 +589,7 @@ int party_leave(struct map_session_data *sd)
int i; int i;
p = party_search(sd->status.party_id); p = party_search(sd->status.party_id);
if( p == NULL ) if( p == NULL )
return 0; return 0;
@ -588,6 +609,7 @@ int party_member_withdraw(int party_id, int account_id, int char_id)
if( p ) { if( p ) {
int i; int i;
ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id ); ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id );
if( i < MAX_PARTY ) { if( i < MAX_PARTY ) {
clif_party_withdraw(p,sd,account_id,p->party.member[i].name,0x0); clif_party_withdraw(p,sd,account_id,p->party.member[i].name,0x0);
@ -602,13 +624,17 @@ int party_member_withdraw(int party_id, int account_id, int char_id)
#ifdef BOUND_ITEMS #ifdef BOUND_ITEMS
int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion
int j,i; int j,i;
j = pc_bound_chk(sd,3,idxlist); j = pc_bound_chk(sd,3,idxlist);
for(i = 0; i < j; i++) for(i = 0; i < j; i++)
pc_delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER); pc_delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER);
#endif #endif
sd->status.party_id = 0; sd->status.party_id = 0;
clif_charnameupdate(sd); //Update name display [Skotlex] clif_charnameupdate(sd); //Update name display [Skotlex]
//TODO: hp bars should be cleared too //TODO: hp bars should be cleared too
if( p->instance_id ) { if( p->instance_id ) {
int16 m = sd->bl.m; int16 m = sd->bl.m;
@ -631,25 +657,24 @@ int party_broken(int party_id)
int i; int i;
p = party_search(party_id); p = party_search(party_id);
if( p == NULL ) if( p == NULL )
return 0; return 0;
if( p->instance_id ) if( p->instance_id ) {
{
instance_data[p->instance_id].party_id = 0; instance_data[p->instance_id].party_id = 0;
instance_destroy( p->instance_id ); instance_destroy( p->instance_id );
} }
for( i = 0; i < MAX_PARTY; i++ ) for( i = 0; i < MAX_PARTY; i++ ) {
{ if( p->data[i].sd != NULL ) {
if( p->data[i].sd!=NULL )
{
clif_party_withdraw(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10); clif_party_withdraw(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10);
p->data[i].sd->status.party_id=0; p->data[i].sd->status.party_id=0;
} }
} }
idb_remove(party_db,party_id); idb_remove(party_db,party_id);
return 1; return 1;
} }
@ -659,7 +684,9 @@ int party_changeoption(struct map_session_data *sd,int exp,int item)
if( sd->status.party_id == 0 ) if( sd->status.party_id == 0 )
return -3; return -3;
intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item); intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item);
return 0; return 0;
} }
@ -667,9 +694,11 @@ int party_changeoption(struct map_session_data *sd,int exp,int item)
int party_setoption(struct party_data *party, int option, int flag) int party_setoption(struct party_data *party, int option, int flag)
{ {
int i; int i;
ARR_FIND(0,MAX_PARTY,i,party->party.member[i].leader); ARR_FIND(0,MAX_PARTY,i,party->party.member[i].leader);
if(i >= MAX_PARTY) if(i >= MAX_PARTY)
return 0; return 0;
switch(option) { switch(option) {
case 0: case 0:
intif_party_changeoption(party->party.party_id,party->party.member[i].account_id,flag,party->party.item); intif_party_changeoption(party->party.party_id,party->party.member[i].account_id,flag,party->party.item);
@ -688,6 +717,7 @@ int party_setoption(struct party_data *party, int option, int flag)
return 0; return 0;
break; break;
} }
return 1; return 1;
} }
@ -695,6 +725,7 @@ int party_optionchanged(int party_id,int account_id,int exp,int item,int flag)
{ {
struct party_data *p; struct party_data *p;
struct map_session_data *sd=map_id2sd(account_id); struct map_session_data *sd=map_id2sd(account_id);
if( (p = party_search(party_id)) == NULL) if( (p = party_search(party_id)) == NULL)
return 0; return 0;
@ -706,6 +737,7 @@ int party_optionchanged(int party_id,int account_id,int exp,int item,int flag)
} }
clif_party_option(p,sd,flag); clif_party_option(p,sd,flag);
return 0; return 0;
} }
@ -714,7 +746,6 @@ int party_changeleader(struct map_session_data *sd, struct map_session_data *tsd
int mi, tmi; int mi, tmi;
if ( !p ) { if ( !p ) {
if (!sd || !sd->status.party_id) if (!sd || !sd->status.party_id)
return -1; return -1;
@ -723,8 +754,7 @@ int party_changeleader(struct map_session_data *sd, struct map_session_data *tsd
return -3; return -3;
} }
if ( map[sd->bl.m].flag.partylock ) if ( map[sd->bl.m].flag.partylock ) {
{
clif_displaymessage(sd->fd, msg_txt(sd,287)); clif_displaymessage(sd->fd, msg_txt(sd,287));
return 0; return 0;
} }
@ -736,8 +766,7 @@ int party_changeleader(struct map_session_data *sd, struct map_session_data *tsd
if (mi == MAX_PARTY) if (mi == MAX_PARTY)
return 0; // Shouldn't happen return 0; // Shouldn't happen
if (!p->party.member[mi].leader) if (!p->party.member[mi].leader) { // Need to be a party leader.
{ //Need to be a party leader.
clif_displaymessage(sd->fd, msg_txt(sd,282)); clif_displaymessage(sd->fd, msg_txt(sd,282));
return 0; return 0;
} }
@ -745,24 +774,26 @@ int party_changeleader(struct map_session_data *sd, struct map_session_data *tsd
ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd); ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
if (tmi == MAX_PARTY) if (tmi == MAX_PARTY)
return 0; // Shouldn't happen return 0; // Shouldn't happen
} } else {
else {
ARR_FIND(0,MAX_PARTY,mi,p->party.member[mi].leader); ARR_FIND(0,MAX_PARTY,mi,p->party.member[mi].leader);
ARR_FIND(0,MAX_PARTY,tmi,p->data[tmi].sd == tsd); ARR_FIND(0,MAX_PARTY,tmi,p->data[tmi].sd == tsd);
} }
// Change leadership. // Change leadership.
p->party.member[mi].leader = 0; p->party.member[mi].leader = 0;
if (p->data[mi].sd && p->data[mi].sd->fd) if (p->data[mi].sd && p->data[mi].sd->fd)
clif_displaymessage(p->data[mi].sd->fd, msg_txt(sd,284)); clif_displaymessage(p->data[mi].sd->fd, msg_txt(sd,284));
p->party.member[tmi].leader = 1; p->party.member[tmi].leader = 1;
if (p->data[tmi].sd && p->data[tmi].sd->fd) if (p->data[tmi].sd && p->data[tmi].sd->fd)
clif_displaymessage(p->data[tmi].sd->fd, msg_txt(sd,285)); clif_displaymessage(p->data[tmi].sd->fd, msg_txt(sd,285));
// Update info. // Update info.
intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id);
clif_party_info(p,NULL); clif_party_info(p,NULL);
return 1; return 1;
} }
@ -777,12 +808,12 @@ int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short m
int i; int i;
p = party_search(party_id); p = party_search(party_id);
if( p == NULL ) if( p == NULL )
return 0; return 0;
ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id ); ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id );
if( i == MAX_PARTY ) if( i == MAX_PARTY ) {
{
ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id); ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id);
return 0; return 0;
} }
@ -795,6 +826,7 @@ int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short m
p->data[i].sd = party_sd_check(party_id, account_id, char_id); p->data[i].sd = party_sd_check(party_id, account_id, char_id);
clif_party_info(p,NULL); clif_party_info(p,NULL);
return 0; return 0;
} }
@ -802,13 +834,15 @@ void party_send_movemap(struct map_session_data *sd)
{ {
struct party_data *p; struct party_data *p;
if( sd->status.party_id==0 ) if( !sd->status.party_id )
return; return;
intif_party_changemap(sd,1); intif_party_changemap(sd,1);
p = party_search(sd->status.party_id); p = party_search(sd->status.party_id);
if (!p) return;
if (!p)
return;
if(sd->state.connect_new) { if(sd->state.connect_new) {
//Note that this works because this function is invoked before connect_new is cleared. //Note that this works because this function is invoked before connect_new is cleared.
@ -847,7 +881,9 @@ int party_send_logout(struct map_session_data *sd)
intif_party_changemap(sd,0); intif_party_changemap(sd,0);
p = party_search(sd->status.party_id); p = party_search(sd->status.party_id);
if(!p) return 0;
if(!p)
return 0;
ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == sd ); ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == sd );
if( i < MAX_PARTY ) if( i < MAX_PARTY )
@ -862,6 +898,7 @@ int party_send_message(struct map_session_data *sd,const char *mes,int len)
{ {
if(sd->status.party_id == 0) if(sd->status.party_id == 0)
return 0; return 0;
intif_party_message(sd->status.party_id,sd->status.account_id,mes,len); intif_party_message(sd->status.party_id,sd->status.account_id,mes,len);
party_recv_message(sd->status.party_id,sd->status.account_id,mes,len); party_recv_message(sd->status.party_id,sd->status.account_id,mes,len);
@ -874,9 +911,12 @@ int party_send_message(struct map_session_data *sd,const char *mes,int len)
int party_recv_message(int party_id,int account_id,const char *mes,int len) int party_recv_message(int party_id,int account_id,const char *mes,int len)
{ {
struct party_data *p; struct party_data *p;
if( (p = party_search(party_id)) == NULL) if( (p = party_search(party_id)) == NULL)
return 0; return 0;
clif_party_message(p,account_id,mes,len); clif_party_message(p,account_id,mes,len);
return 0; return 0;
} }
@ -888,6 +928,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
if(!party_id || (p = party_search(party_id)) == NULL) if(!party_id || (p = party_search(party_id)) == NULL)
return 0; return 0;
switch(skill_id) { switch(skill_id) {
case TK_COUNTER: //Increase Triple Attack rate of Monks. case TK_COUNTER: //Increase Triple Attack rate of Monks.
if (!p->state.monk) return 0; if (!p->state.monk) return 0;
@ -906,8 +947,10 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
for(i = 0; i < MAX_PARTY; i++) { for(i = 0; i < MAX_PARTY; i++) {
if ((p_sd = p->data[i].sd) == NULL) if ((p_sd = p->data[i].sd) == NULL)
continue; continue;
if (sd->bl.m != p_sd->bl.m) if (sd->bl.m != p_sd->bl.m)
continue; continue;
switch(skill_id) { switch(skill_id) {
case TK_COUNTER: //Increase Triple Attack rate of Monks. case TK_COUNTER: //Increase Triple Attack rate of Monks.
if((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK if((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK
@ -928,6 +971,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
break; break;
} }
} }
return 0; return 0;
} }
@ -936,30 +980,28 @@ int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
struct party_data* p; struct party_data* p;
DBIterator *iter = db_iterator(party_db); DBIterator *iter = db_iterator(party_db);
// for each existing party,
for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) ) // for each existing party
{ for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) ) {
int i; int i;
if( !p->party.count ) if( !p->party.count ) // no online party members so do not iterate
{// no online party members so do not iterate
continue; continue;
}
// for each member of this party, // for each member of this party
for( i = 0; i < MAX_PARTY; i++ ) for( i = 0; i < MAX_PARTY; i++ ) {
{
struct map_session_data* sd = p->data[i].sd; struct map_session_data* sd = p->data[i].sd;
if( !sd ) continue;
if( p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y ) if( !sd )
{// perform position update continue;
if( p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y ) { // perform position update
clif_party_xy(sd); clif_party_xy(sd);
p->data[i].x = sd->bl.x; p->data[i].x = sd->bl.x;
p->data[i].y = sd->bl.y; p->data[i].y = sd->bl.y;
} }
if (battle_config.party_hp_mode && p->data[i].hp != sd->battle_status.hp)
{// perform hp update if (battle_config.party_hp_mode && p->data[i].hp != sd->battle_status.hp) { // perform hp update
clif_party_hp(sd); clif_party_hp(sd);
p->data[i].hp = sd->battle_status.hp; p->data[i].hp = sd->battle_status.hp;
} }
@ -977,7 +1019,9 @@ int party_send_xy_clear(struct party_data *p)
nullpo_ret(p); nullpo_ret(p);
for(i = 0; i < MAX_PARTY; i++) { for(i = 0; i < MAX_PARTY; i++) {
if(!p->data[i].sd) continue; if(!p->data[i].sd)
continue;
p->data[i].hp = 0; p->data[i].hp = 0;
p->data[i].x = 0; p->data[i].x = 0;
p->data[i].y = 0; p->data[i].y = 0;
@ -993,6 +1037,7 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b
#ifdef RENEWAL_EXP #ifdef RENEWAL_EXP
uint32 base_exp_bonus, job_exp_bonus; uint32 base_exp_bonus, job_exp_bonus;
#endif #endif
nullpo_ret(p); nullpo_ret(p);
// count the number of players eligible for exp sharing // count the number of players eligible for exp sharing
@ -1008,9 +1053,9 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b
job_exp/=c; job_exp/=c;
zeny/=c; zeny/=c;
if (battle_config.party_even_share_bonus && c > 1) if (battle_config.party_even_share_bonus && c > 1) {
{
double bonus = 100 + battle_config.party_even_share_bonus*(c-1); double bonus = 100 + battle_config.party_even_share_bonus*(c-1);
if (base_exp) if (base_exp)
base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX); base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX);
if (job_exp) if (job_exp)
@ -1018,10 +1063,12 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b
if (zeny) if (zeny)
zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX); zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX);
} }
#ifdef RENEWAL_EXP #ifdef RENEWAL_EXP
base_exp_bonus = base_exp; base_exp_bonus = base_exp;
job_exp_bonus = job_exp; job_exp_bonus = job_exp;
#endif #endif
for (i = 0; i < c; i++) { for (i = 0; i < c; i++) {
#ifdef RENEWAL_EXP #ifdef RENEWAL_EXP
if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) ) { if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) ) {
@ -1036,11 +1083,13 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b
job_exp = (unsigned int)cap_value(job_exp_bonus * rate / 100, 1, UINT_MAX); job_exp = (unsigned int)cap_value(job_exp_bonus * rate / 100, 1, UINT_MAX);
} }
#endif #endif
pc_gainexp(sd[i], src, base_exp, job_exp, false); pc_gainexp(sd[i], src, base_exp, job_exp, false);
if (zeny) // zeny from mobs [Valaris] if (zeny) // zeny from mobs [Valaris]
pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL); pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL);
} }
return 0; return 0;
} }
@ -1049,13 +1098,14 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
{ {
TBL_PC* target = NULL; TBL_PC* target = NULL;
int i; int i;
if (p && p->party.item&2 && (first_charid || !(battle_config.party_share_type&1)))
{ if (p && p->party.item&2 && (first_charid || !(battle_config.party_share_type&1))) {
//item distribution to party members. //item distribution to party members.
if (battle_config.party_share_type&2) if (battle_config.party_share_type&2) { // Round Robin
{ //Round Robin
TBL_PC* psd; TBL_PC* psd;
i = p->itemc; i = p->itemc;
do { do {
i++; i++;
if (i >= MAX_PARTY) if (i >= MAX_PARTY)
@ -1072,11 +1122,10 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
target = psd; target = psd;
break; break;
} while (i != p->itemc); } while (i != p->itemc);
} } else { // Random pick
else
{ //Random pick
TBL_PC* psd[MAX_PARTY]; TBL_PC* psd[MAX_PARTY];
int count = 0; int count = 0;
//Collect pick candidates //Collect pick candidates
for (i = 0; i < MAX_PARTY; i++) { for (i = 0; i < MAX_PARTY; i++) {
if( (psd[count] = p->data[i].sd) == NULL || psd[count]->bl.m != sd->bl.m || pc_isdead(psd[count]) || (battle_config.idle_no_share && pc_isidle(psd[count])) ) if( (psd[count] = p->data[i].sd) == NULL || psd[count]->bl.m != sd->bl.m || pc_isdead(psd[count]) || (battle_config.idle_no_share && pc_isidle(psd[count])) )
@ -1084,10 +1133,11 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
count++; count++;
} }
while (count > 0) { //Pick a random member. while (count > 0) { //Pick a random member.
i = rnd()%count; i = rnd()%count;
if (pc_additem(psd[i],item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER))
{ //Discard this receiver. if (pc_additem(psd[i],item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER)) { // Discard this receiver.
psd[i] = psd[count-1]; psd[i] = psd[count-1];
count--; count--;
} else { // Successful pick. } else { // Successful pick.
@ -1100,6 +1150,7 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
if (!target) { if (!target) {
target = sd; //Give it to the char that picked it up target = sd; //Give it to the char that picked it up
if ((i = pc_additem(sd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER))) if ((i = pc_additem(sd,item_data,item_data->amount,LOG_TYPE_PICKDROP_PLAYER)))
return i; return i;
} }
@ -1114,6 +1165,7 @@ int party_send_dot_remove(struct map_session_data *sd)
{ {
if (sd->status.party_id) if (sd->status.party_id)
clif_party_xy_remove(sd); clif_party_xy_remove(sd);
return 0; return 0;
} }
@ -1169,23 +1221,26 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess
x1 = sd->bl.x+range; x1 = sd->bl.x+range;
y1 = sd->bl.y+range; y1 = sd->bl.y+range;
for(i=0;i<MAX_PARTY;i++) for(i = 0; i < MAX_PARTY; i++) {
{
struct map_session_data *psd = p->data[i].sd; struct map_session_data *psd = p->data[i].sd;
if(!psd) continue;
if(!psd)
continue;
if(psd->bl.m!=sd->bl.m || !psd->bl.prev) if(psd->bl.m!=sd->bl.m || !psd->bl.prev)
continue; continue;
if(range && if(range &&
(psd->bl.x<x0 || psd->bl.y<y0 || (psd->bl.x<x0 || psd->bl.y<y0 ||
psd->bl.x>x1 || psd->bl.y>y1 ) ) psd->bl.x>x1 || psd->bl.y>y1 ) )
continue; continue;
list[blockcount++]=&psd->bl; list[blockcount++]=&psd->bl;
} }
map_freeblock_lock(); map_freeblock_lock();
for(i=0;i<blockcount;i++) for(i = 0; i < blockcount; i++) {
{
va_list ap; va_list ap;
va_start(ap, range); va_start(ap, range);
total += func(list[i], ap); total += func(list[i], ap);
@ -1200,12 +1255,13 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess
/*========================================== /*==========================================
* Party Booking in KRO [Spiria] * Party Booking in KRO [Spiria]
*------------------------------------------*/ *------------------------------------------*/
static struct party_booking_ad_info* create_party_booking_data(void) static struct party_booking_ad_info* create_party_booking_data(void)
{ {
struct party_booking_ad_info *pb_ad; struct party_booking_ad_info *pb_ad;
CREATE(pb_ad, struct party_booking_ad_info, 1); CREATE(pb_ad, struct party_booking_ad_info, 1);
pb_ad->index = party_booking_nextid++; pb_ad->index = party_booking_nextid++;
return pb_ad; return pb_ad;
} }
@ -1216,13 +1272,10 @@ void party_booking_register(struct map_session_data *sd, short level, short mapi
pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id); pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id);
if( pb_ad == NULL ) if( pb_ad == NULL ) {
{
pb_ad = create_party_booking_data(); pb_ad = create_party_booking_data();
idb_put(party_booking_db, sd->status.char_id, pb_ad); idb_put(party_booking_db, sd->status.char_id, pb_ad);
} } else { // already registered
else
{// already registered
clif_PartyBookingRegisterAck(sd, 2); clif_PartyBookingRegisterAck(sd, 2);
return; return;
} }
@ -1256,7 +1309,8 @@ void party_booking_update(struct map_session_data *sd, short* job)
for(i = 0; i < PARTY_BOOKING_JOBS; i++) for(i = 0; i < PARTY_BOOKING_JOBS; i++)
if(job[i] != 0xFF) if(job[i] != 0xFF)
pb_ad->p_detail.job[i] = job[i]; pb_ad->p_detail.job[i] = job[i];
else pb_ad->p_detail.job[i] = -1; else
pb_ad->p_detail.job[i] = -1;
clif_PartyBookingUpdateNotify(sd, pb_ad); clif_PartyBookingUpdateNotify(sd, pb_ad);
} }
@ -1271,14 +1325,15 @@ void party_booking_search(struct map_session_data *sd, short level, short mapid,
memset(result_list, 0, sizeof(result_list)); memset(result_list, 0, sizeof(result_list));
for( pb_ad = dbi_first(iter); dbi_exists(iter); pb_ad = dbi_next(iter) ) for( pb_ad = dbi_first(iter); dbi_exists(iter); pb_ad = dbi_next(iter) ) {
{
if (pb_ad->index < lastindex || (level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level))) if (pb_ad->index < lastindex || (level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level)))
continue; continue;
if (count >= PARTY_BOOKING_RESULTS) { if (count >= PARTY_BOOKING_RESULTS) {
more_result = true; more_result = true;
break; break;
} }
if (mapid == 0 && job == -1) if (mapid == 0 && job == -1)
result_list[count] = pb_ad; result_list[count] = pb_ad;
else if (mapid == 0) { else if (mapid == 0) {
@ -1289,11 +1344,11 @@ void party_booking_search(struct map_session_data *sd, short level, short mapid,
if (pb_ad->p_detail.mapid == mapid) if (pb_ad->p_detail.mapid == mapid)
result_list[count] = pb_ad; result_list[count] = pb_ad;
} }
if( result_list[count] ) if( result_list[count] )
{
count++; count++;
} }
}
dbi_destroy(iter); dbi_destroy(iter);
clif_PartyBookingSearchAck(sd->fd, result_list, count, more_result); clif_PartyBookingSearchAck(sd->fd, result_list, count, more_result);
} }
@ -1302,10 +1357,10 @@ bool party_booking_delete(struct map_session_data *sd)
{ {
struct party_booking_ad_info* pb_ad; struct party_booking_ad_info* pb_ad;
if((pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id))!=NULL) if((pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id)) != NULL) {
{
clif_PartyBookingDeleteNotify(sd, pb_ad->index); clif_PartyBookingDeleteNotify(sd, pb_ad->index);
idb_remove(party_booking_db,sd->status.char_id); idb_remove(party_booking_db,sd->status.char_id);
} }
return true; return true;
} }

View File

@ -254,7 +254,7 @@ static int add_path(struct node_heap *heap, struct path_node *tp, int16 x, int16
*------------------------------------------*/ *------------------------------------------*/
bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int flag, cell_chk cell) bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int flag, cell_chk cell)
{ {
register int i, j, x, y, dx = 0, dy = 0; register int i, x, y, dx = 0, dy = 0;
struct map_data *md; struct map_data *md;
struct walkpath_data s_wpd; struct walkpath_data s_wpd;
@ -263,6 +263,7 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
if (!map[m].cell) if (!map[m].cell)
return false; return false;
md = &map[m]; md = &map[m];
#ifdef CELL_NOSTACK #ifdef CELL_NOSTACK
@ -288,8 +289,7 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
x = x0; // Current position = starting cell x = x0; // Current position = starting cell
y = y0; y = y0;
i = 0; i = 0;
while( i < ARRAYLENGTH(wpd->path) ) while( i < ARRAYLENGTH(wpd->path) ) {
{
wpd->path[i] = walk_choices[-dy + 1][dx + 1]; wpd->path[i] = walk_choices[-dy + 1][dx + 1];
i++; i++;
@ -305,16 +305,14 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
break; // obstacle = failure break; // obstacle = failure
} }
if( x == x1 && y == y1 ) if( x == x1 && y == y1 ) { // easy path successful.
{ // easy path successful.
wpd->path_len = i; wpd->path_len = i;
wpd->path_pos = 0; wpd->path_pos = 0;
return true; return true;
} }
return false; // easy path unsuccessful return false; // easy path unsuccessful
} } else { // !(flag&1)
else { // !(flag&1)
// A* (A-star) pathfinding // A* (A-star) pathfinding
// We always use A* for finding walkpaths because it is what game client uses. // We always use A* for finding walkpaths because it is what game client uses.
// Easy pathfinding cuts corners of non-walkable cells, but client always walks around it. // Easy pathfinding cuts corners of non-walkable cells, but client always walks around it.
@ -329,6 +327,8 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
int xs = md->xs - 1; int xs = md->xs - 1;
int ys = md->ys - 1; int ys = md->ys - 1;
int len = 0; int len = 0;
int j;
memset(tp, 0, sizeof(tp)); memset(tp, 0, sizeof(tp));
// Start node // Start node
@ -341,8 +341,8 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
tp[i].flag = SET_OPEN; tp[i].flag = SET_OPEN;
heap_push_node(&open_set, &tp[i]); // Put start node to 'open' set heap_push_node(&open_set, &tp[i]); // Put start node to 'open' set
for(;;)
{ for(;;) {
int e = 0; // error flag int e = 0; // error flag
// Saves allowed directions for the current cell. Diagonal directions // Saves allowed directions for the current cell. Diagonal directions
@ -407,18 +407,19 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
} }
for (it = current; it->parent != NULL; it = it->parent, len++); for (it = current; it->parent != NULL; it = it->parent, len++);
if (len > sizeof(wpd->path)) { if (len > sizeof(wpd->path))
return false; return false;
}
// Recreate path // Recreate path
wpd->path_len = len; wpd->path_len = len;
wpd->path_pos = 0; wpd->path_pos = 0;
for (it = current, j = len-1; j >= 0; it = it->parent, j--) { for (it = current, j = len-1; j >= 0; it = it->parent, j--) {
dx = it->x - it->parent->x; dx = it->x - it->parent->x;
dy = it->y - it->parent->y; dy = it->y - it->parent->y;
wpd->path[j] = walk_choices[-dy + 1][dx + 1]; wpd->path[j] = walk_choices[-dy + 1][dx + 1];
} }
return true; return true;
} // A* end } // A* end

View File

@ -10870,7 +10870,7 @@ int pc_autotrade_timer(int tid, unsigned int tick, int id, intptr_t data) {
buyingstore_reopen(sd); buyingstore_reopen(sd);
vending_reopen(sd); vending_reopen(sd);
if (sd && !sd->vender_id && !sd->buyer_id) { if (!sd->vender_id && !sd->buyer_id) {
sd->state.autotrade = 0; sd->state.autotrade = 0;
map_quit(sd); map_quit(sd);
} }

View File

@ -38,9 +38,11 @@
* @param quest_id ID to lookup * @param quest_id ID to lookup
* @return Quest entry (equals to &quest_dummy if the ID is invalid) * @return Quest entry (equals to &quest_dummy if the ID is invalid)
*/ */
struct quest_db *quest_db(int quest_id) { struct quest_db *quest_db(int quest_id)
{
if( quest_id < 0 || quest_id > MAX_QUEST_DB || quest_db_data[quest_id] == NULL ) if( quest_id < 0 || quest_id > MAX_QUEST_DB || quest_db_data[quest_id] == NULL )
return &quest_dummy; return &quest_dummy;
return quest_db_data[quest_id]; return quest_db_data[quest_id];
} }
@ -50,7 +52,8 @@ struct quest_db *quest_db(int quest_id) {
* @param sd Player's data * @param sd Player's data
* @return 0 in case of success, nonzero otherwise (i.e. the player has no quests) * @return 0 in case of success, nonzero otherwise (i.e. the player has no quests)
*/ */
int quest_pc_login(TBL_PC *sd) { int quest_pc_login(TBL_PC *sd)
{
int i; int i;
if( sd->avail_quests == 0 ) if( sd->avail_quests == 0 )
@ -75,7 +78,8 @@ int quest_pc_login(TBL_PC *sd) {
* @param quest_id ID of the quest to add. * @param quest_id ID of the quest to add.
* @return 0 in case of success, nonzero otherwise * @return 0 in case of success, nonzero otherwise
*/ */
int quest_add(TBL_PC *sd, int quest_id) { int quest_add(TBL_PC *sd, int quest_id)
{
int n; int n;
struct quest_db *qi = quest_db(quest_id); struct quest_db *qi = quest_db(quest_id);
@ -125,7 +129,8 @@ int quest_add(TBL_PC *sd, int quest_id) {
* @param qid2 New quest to add * @param qid2 New quest to add
* @return 0 in case of success, nonzero otherwise * @return 0 in case of success, nonzero otherwise
*/ */
int quest_change(TBL_PC *sd, int qid1, int qid2) { int quest_change(TBL_PC *sd, int qid1, int qid2)
{
int i; int i;
struct quest_db *qi = quest_db(qid2); struct quest_db *qi = quest_db(qid2);
@ -152,8 +157,10 @@ int quest_change(TBL_PC *sd, int qid1, int qid2) {
memset(&sd->quest_log[i], 0, sizeof(struct quest)); memset(&sd->quest_log[i], 0, sizeof(struct quest));
sd->quest_log[i].quest_id = qi->id; sd->quest_log[i].quest_id = qi->id;
if( qi->time ) if( qi->time )
sd->quest_log[i].time = (unsigned int)(time(NULL) + qi->time); sd->quest_log[i].time = (unsigned int)(time(NULL) + qi->time);
sd->quest_log[i].state = Q_ACTIVE; sd->quest_log[i].state = Q_ACTIVE;
sd->save_quest = true; sd->save_quest = true;
@ -175,7 +182,8 @@ int quest_change(TBL_PC *sd, int qid1, int qid2) {
* @param quest_id ID of the quest to remove * @param quest_id ID of the quest to remove
* @return 0 in case of success, nonzero otherwise * @return 0 in case of success, nonzero otherwise
*/ */
int quest_delete(TBL_PC *sd, int quest_id) { int quest_delete(TBL_PC *sd, int quest_id)
{
int i; int i;
//Search for quest //Search for quest
@ -184,15 +192,19 @@ int quest_delete(TBL_PC *sd, int quest_id) {
ShowError("quest_delete: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id); ShowError("quest_delete: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id);
return -1; return -1;
} }
if( sd->quest_log[i].state != Q_COMPLETE ) if( sd->quest_log[i].state != Q_COMPLETE )
sd->avail_quests--; sd->avail_quests--;
if( i < --sd->num_quests ) //Compact the array if( i < --sd->num_quests ) //Compact the array
memmove(&sd->quest_log[i], &sd->quest_log[i + 1], sizeof(struct quest) * (sd->num_quests - i)); memmove(&sd->quest_log[i], &sd->quest_log[i + 1], sizeof(struct quest) * (sd->num_quests - i));
if( sd->num_quests == 0 ) { if( sd->num_quests == 0 ) {
aFree(sd->quest_log); aFree(sd->quest_log);
sd->quest_log = NULL; sd->quest_log = NULL;
} else } else
RECREATE(sd->quest_log, struct quest, sd->num_quests); RECREATE(sd->quest_log, struct quest, sd->num_quests);
sd->save_quest = true; sd->save_quest = true;
clif_quest_delete(sd, quest_id); clif_quest_delete(sd, quest_id);
@ -211,7 +223,8 @@ int quest_delete(TBL_PC *sd, int quest_id) {
* int Party ID * int Party ID
* int Mob ID * int Mob ID
*/ */
int quest_update_objective_sub(struct block_list *bl, va_list ap) { int quest_update_objective_sub(struct block_list *bl, va_list ap)
{
struct map_session_data *sd; struct map_session_data *sd;
int mob, party; int mob, party;
@ -237,7 +250,8 @@ int quest_update_objective_sub(struct block_list *bl, va_list ap) {
* @param sd Character's data * @param sd Character's data
* @param mob_id Monster ID * @param mob_id Monster ID
*/ */
void quest_update_objective(TBL_PC *sd, int mob) { void quest_update_objective(TBL_PC *sd, int mob)
{
int i, j; int i, j;
for( i = 0; i < sd->avail_quests; i++ ) { for( i = 0; i < sd->avail_quests; i++ ) {
@ -268,7 +282,8 @@ void quest_update_objective(TBL_PC *sd, int mob) {
* @param qs New quest state * @param qs New quest state
* @return 0 in case of success, nonzero otherwise * @return 0 in case of success, nonzero otherwise
*/ */
int quest_update_status(TBL_PC *sd, int quest_id, enum quest_state status) { int quest_update_status(TBL_PC *sd, int quest_id, enum quest_state status)
{
int i; int i;
ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == quest_id); ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == quest_id);
@ -317,7 +332,8 @@ int quest_update_status(TBL_PC *sd, int quest_id, enum quest_state status) {
* 1 if the quest's timeout has expired * 1 if the quest's timeout has expired
* 0 otherwise * 0 otherwise
*/ */
int quest_check(TBL_PC *sd, int quest_id, enum quest_check_type type) { int quest_check(TBL_PC *sd, int quest_id, enum quest_check_type type)
{
int i; int i;
ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id); ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
@ -354,7 +370,8 @@ int quest_check(TBL_PC *sd, int quest_id, enum quest_check_type type) {
* *
* @return Number of loaded quests, or -1 if the file couldn't be read. * @return Number of loaded quests, or -1 if the file couldn't be read.
*/ */
int quest_read_db(void) { int quest_read_db(void)
{
const char* dbsubpath[] = { const char* dbsubpath[] = {
"", "",
DBIMPORT"/", DBIMPORT"/",
@ -373,11 +390,14 @@ int quest_read_db(void) {
if( (fp = fopen(filename, "r")) == NULL ) { if( (fp = fopen(filename, "r")) == NULL ) {
if (f == 0) if (f == 0)
ShowError("Can't read %s\n", filename); ShowError("Can't read %s\n", filename);
return -1; return -1;
} }
while( fgets(line, sizeof(line), fp) ) { while( fgets(line, sizeof(line), fp) ) {
if( line[0] == '/' && line[1] == '/' ) if( line[0] == '/' && line[1] == '/' )
continue; continue;
memset(str, 0, sizeof(str)); memset(str, 0, sizeof(str));
for( i = 0, p = line; i < 8; i++ ) { for( i = 0, p = line; i < 8; i++ ) {
@ -392,6 +412,7 @@ int quest_read_db(void) {
continue; continue;
} }
} }
if( str[0] == NULL ) if( str[0] == NULL )
continue; continue;
@ -422,6 +443,7 @@ int quest_read_db(void) {
memcpy(quest_db_data[entry.id], &entry, sizeof(struct quest_db)); memcpy(quest_db_data[entry.id], &entry, sizeof(struct quest_db));
count++; count++;
} }
fclose(fp); fclose(fp);
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename); ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename);
} }
@ -437,7 +459,8 @@ int quest_read_db(void) {
* @see map_foreachpc * @see map_foreachpc
* @param ap Ignored * @param ap Ignored
*/ */
int quest_reload_check_sub(struct map_session_data *sd, va_list ap) { int quest_reload_check_sub(struct map_session_data *sd, va_list ap)
{
int i, j; int i, j;
nullpo_ret(sd); nullpo_ret(sd);
@ -451,12 +474,15 @@ int quest_reload_check_sub(struct map_session_data *sd, va_list ap) {
clif_quest_delete(sd, sd->quest_log[i].quest_id); clif_quest_delete(sd, sd->quest_log[i].quest_id);
continue; continue;
} }
if( i != j ) { if( i != j ) {
//Move entries if there's a gap to fill //Move entries if there's a gap to fill
memcpy(&sd->quest_log[j], &sd->quest_log[i], sizeof(struct quest)); memcpy(&sd->quest_log[j], &sd->quest_log[i], sizeof(struct quest));
} }
j++; j++;
} }
sd->num_quests = j; sd->num_quests = j;
ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].state == Q_COMPLETE); ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].state == Q_COMPLETE);
sd->avail_quests = i; sd->avail_quests = i;
@ -467,7 +493,8 @@ int quest_reload_check_sub(struct map_session_data *sd, va_list ap) {
/** /**
* Clears the quest database for shutdown or reload. * Clears the quest database for shutdown or reload.
*/ */
void quest_clear_db(void) { void quest_clear_db(void)
{
int i; int i;
for( i = 0; i < MAX_QUEST_DB; i++ ) { for( i = 0; i < MAX_QUEST_DB; i++ ) {
@ -481,14 +508,16 @@ void quest_clear_db(void) {
/** /**
* Initializes the quest interface. * Initializes the quest interface.
*/ */
void do_init_quest(void) { void do_init_quest(void)
{
quest_read_db(); quest_read_db();
} }
/** /**
* Finalizes the quest interface before shutdown. * Finalizes the quest interface before shutdown.
*/ */
void do_final_quest(void) { void do_final_quest(void)
{
memset(&quest_dummy, 0, sizeof(quest_dummy)); memset(&quest_dummy, 0, sizeof(quest_dummy));
quest_clear_db(); quest_clear_db();
@ -497,7 +526,8 @@ void do_final_quest(void) {
/** /**
* Reloads the quest database. * Reloads the quest database.
*/ */
void do_reload_quest(void) { void do_reload_quest(void)
{
memset(&quest_dummy, 0, sizeof(quest_dummy)); memset(&quest_dummy, 0, sizeof(quest_dummy));
quest_clear_db(); quest_clear_db();

View File

@ -7538,12 +7538,12 @@ BUILDIN_FUNC(getpartyname)
BUILDIN_FUNC(getpartymember) BUILDIN_FUNC(getpartymember)
{ {
struct party_data *p; struct party_data *p;
int type = 0;
unsigned char j = 0; unsigned char j = 0;
p = party_search(script_getnum(st,2)); p = party_search(script_getnum(st,2));
if (p != NULL) { if (p != NULL) {
int type = 0;
unsigned char i; unsigned char i;
if (script_hasdata(st,3)) if (script_hasdata(st,3))
@ -7562,10 +7562,12 @@ BUILDIN_FUNC(getpartymember)
mapreg_setregstr(reference_uid(add_str("$@partymembername$"), j),p->party.member[i].name); mapreg_setregstr(reference_uid(add_str("$@partymembername$"), j),p->party.member[i].name);
break; break;
} }
j++; j++;
} }
} }
} }
mapreg_setreg(add_str("$@partymembercount"),j); mapreg_setreg(add_str("$@partymembercount"),j);
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
} }
@ -14328,7 +14330,6 @@ BUILDIN_FUNC(unequip) {
BUILDIN_FUNC(equip) { BUILDIN_FUNC(equip) {
unsigned short nameid = 0; unsigned short nameid = 0;
int i;
TBL_PC *sd; TBL_PC *sd;
struct item_data *item_data; struct item_data *item_data;
@ -14337,6 +14338,8 @@ BUILDIN_FUNC(equip) {
nameid = script_getnum(st,2); nameid = script_getnum(st,2);
if ((item_data = itemdb_exists(nameid))) { if ((item_data = itemdb_exists(nameid))) {
int i;
ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid ); ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid );
if (i < MAX_INVENTORY) { if (i < MAX_INVENTORY) {
pc_equipitem(sd,i,item_data->equip); pc_equipitem(sd,i,item_data->equip);
@ -14584,7 +14587,6 @@ BUILDIN_FUNC(substr)
char *output; char *output;
int start = script_getnum(st,3); int start = script_getnum(st,3);
int end = script_getnum(st,4); int end = script_getnum(st,4);
int len = 0; int len = 0;
if(start >= 0 && end < strlen(str) && start <= end) { if(start >= 0 && end < strlen(str) && start <= end) {
@ -14613,17 +14615,13 @@ BUILDIN_FUNC(explode)
size_t len = strlen(str); size_t len = strlen(str);
int i = 0, j = 0; int i = 0, j = 0;
int start; int start;
char *temp; char *temp;
const char* name; const char* name;
TBL_PC* sd = NULL; TBL_PC* sd = NULL;
temp = (char*)aMalloc(len + 1); temp = (char*)aMalloc(len + 1);
if( !data_isreference(data) ) if( !data_isreference(data) ) {
{
ShowError("script:explode: not a variable\n"); ShowError("script:explode: not a variable\n");
script_reportdata(data); script_reportdata(data);
st->state = END; st->state = END;
@ -14634,24 +14632,21 @@ BUILDIN_FUNC(explode)
start = reference_getindex(data); start = reference_getindex(data);
name = reference_getname(data); name = reference_getname(data);
if( not_array_variable(*name) ) if( not_array_variable(*name) ) {
{
ShowError("script:explode: illegal scope\n"); ShowError("script:explode: illegal scope\n");
script_reportdata(data); script_reportdata(data);
st->state = END; st->state = END;
return 1;// not supported return 1;// not supported
} }
if( !is_string_variable(name) ) if( !is_string_variable(name) ) {
{
ShowError("script:explode: not string array\n"); ShowError("script:explode: not string array\n");
script_reportdata(data); script_reportdata(data);
st->state = END; st->state = END;
return 1;// data type mismatch return 1;// data type mismatch
} }
if( not_server_variable(*name) ) if( not_server_variable(*name) ) {
{
sd = script_rid2sd(st); sd = script_rid2sd(st);
if( sd == NULL ) if( sd == NULL )
return 0;// no player attached return 0;// no player attached
@ -14667,6 +14662,7 @@ BUILDIN_FUNC(explode)
temp[j++] = str[i++]; temp[j++] = str[i++];
} }
} }
//set last string //set last string
temp[j] = '\0'; temp[j] = '\0';
set_reg(st, sd, reference_uid(id, start), name, (void*)temp, reference_getref(data)); set_reg(st, sd, reference_uid(id, start), name, (void*)temp, reference_getref(data));
@ -14684,13 +14680,9 @@ BUILDIN_FUNC(implode)
struct script_data* data = script_getdata(st, 2); struct script_data* data = script_getdata(st, 2);
const char *name; const char *name;
int32 glue_len = 0, array_size, id; int32 glue_len = 0, array_size, id;
TBL_PC* sd = NULL;
char *output; char *output;
if( !data_isreference(data) ) if( !data_isreference(data) ) {
{
ShowError("script:implode: not a variable\n"); ShowError("script:implode: not a variable\n");
script_reportdata(data); script_reportdata(data);
st->state = END; st->state = END;
@ -14700,25 +14692,23 @@ BUILDIN_FUNC(implode)
id = reference_getid(data); id = reference_getid(data);
name = reference_getname(data); name = reference_getname(data);
if( not_array_variable(*name) ) if( not_array_variable(*name) ) {
{
ShowError("script:implode: illegal scope\n"); ShowError("script:implode: illegal scope\n");
script_reportdata(data); script_reportdata(data);
st->state = END; st->state = END;
return 1;// not supported return 1;// not supported
} }
if( !is_string_variable(name) ) if( !is_string_variable(name) ) {
{
ShowError("script:implode: not string array\n"); ShowError("script:implode: not string array\n");
script_reportdata(data); script_reportdata(data);
st->state = END; st->state = END;
return 1;// data type mismatch return 1;// data type mismatch
} }
if( not_server_variable(*name) ) if( not_server_variable(*name) ) {
{ TBL_PC* sd = script_rid2sd(st);
sd = script_rid2sd(st);
if( sd == NULL ) if( sd == NULL )
return 0;// no player attached return 0;// no player attached
} }
@ -14726,8 +14716,7 @@ BUILDIN_FUNC(implode)
//count chars //count chars
array_size = getarraysize(st, id, reference_getindex(data), is_string_variable(name), reference_getref(data)) - 1; array_size = getarraysize(st, id, reference_getindex(data), is_string_variable(name), reference_getref(data)) - 1;
if(array_size == -1) //empty array check (AmsTaff) if(array_size == -1) { //empty array check (AmsTaff)
{
ShowWarning("script:implode: array length = 0\n"); ShowWarning("script:implode: array length = 0\n");
output = (char*)aMalloc(sizeof(char)*5); output = (char*)aMalloc(sizeof(char)*5);
sprintf(output,"%s","NULL"); sprintf(output,"%s","NULL");
@ -14756,18 +14745,20 @@ BUILDIN_FUNC(implode)
len = strlen(temp); len = strlen(temp);
memcpy(&output[k], temp, len); memcpy(&output[k], temp, len);
k += len; k += len;
if(glue_len != 0) { if(glue_len != 0) {
memcpy(&output[k], glue, glue_len); memcpy(&output[k], glue, glue_len);
k += glue_len; k += glue_len;
} }
script_removetop(st, -1, 0); script_removetop(st, -1, 0);
} }
temp = (char*) get_val2(st, reference_uid(id, array_size), reference_getref(data)); temp = (char*) get_val2(st, reference_uid(id, array_size), reference_getref(data));
len = strlen(temp); len = strlen(temp);
memcpy(&output[k], temp, len); memcpy(&output[k], temp, len);
k += len; k += len;
script_removetop(st, -1, 0); script_removetop(st, -1, 0);
output[k] = '\0'; output[k] = '\0';
} }
@ -14821,26 +14812,32 @@ BUILDIN_FUNC(sprintf)
while((p = strchr(q, '%')) != NULL) { while((p = strchr(q, '%')) != NULL) {
if(p != q) { if(p != q) {
len = p - q + 1; len = p - q + 1;
if(buf2_len < len) { if(buf2_len < len) {
RECREATE(buf2, char, len); RECREATE(buf2, char, len);
buf2_len = len; buf2_len = len;
} }
safestrncpy(buf2, q, len); safestrncpy(buf2, q, len);
StringBuf_AppendStr(&final_buf, buf2); StringBuf_AppendStr(&final_buf, buf2);
q = p; q = p;
} }
p = q + 1; p = q + 1;
if(*p == '%') { // %% if(*p == '%') { // %%
StringBuf_AppendStr(&final_buf, "%"); StringBuf_AppendStr(&final_buf, "%");
q+=2; q+=2;
continue; continue;
} }
if(*p == 'n') { // %n if(*p == 'n') { // %n
ShowWarning("buildin_sprintf: Format %%n not supported! Skipping...\n"); ShowWarning("buildin_sprintf: Format %%n not supported! Skipping...\n");
script_reportsrc(st); script_reportsrc(st);
q+=2; q+=2;
continue; continue;
} }
if(arg >= argc) { if(arg >= argc) {
ShowError("buildin_sprintf: Not enough arguments passed!\n"); ShowError("buildin_sprintf: Not enough arguments passed!\n");
if(buf) aFree(buf); if(buf) aFree(buf);
@ -14849,14 +14846,17 @@ BUILDIN_FUNC(sprintf)
script_pushconststr(st,""); script_pushconststr(st,"");
return 1; return 1;
} }
if((p = strchr(q+1, '%'))==NULL){
if((p = strchr(q+1, '%')) == NULL)
p = strchr(q, 0); // EOS p = strchr(q, 0); // EOS
}
len = p - q + 1; len = p - q + 1;
if(buf2_len < len) { if(buf2_len < len) {
RECREATE(buf2, char, len); RECREATE(buf2, char, len);
buf2_len = len; buf2_len = len;
} }
safestrncpy(buf2, q, len); safestrncpy(buf2, q, len);
q = p; q = p;
@ -14866,17 +14866,18 @@ BUILDIN_FUNC(sprintf)
// but it would behave in normal code the same way so it's // but it would behave in normal code the same way so it's
// the scripter's responsibility. // the scripter's responsibility.
data = script_getdata(st, arg+3); data = script_getdata(st, arg+3);
if(data_isstring(data)){ // String
if(data_isstring(data)) // String
StringBuf_Printf(&final_buf, buf2, script_getstr(st, arg+3)); StringBuf_Printf(&final_buf, buf2, script_getstr(st, arg+3));
}else if(data_isint(data)){ // Number else if(data_isint(data)) // Number
StringBuf_Printf(&final_buf, buf2, script_getnum(st, arg+3)); StringBuf_Printf(&final_buf, buf2, script_getnum(st, arg+3));
}else if(data_isreference(data)){ // Variable else if(data_isreference(data)) { // Variable
char* name = reference_getname(data); char* name = reference_getname(data);
if(name[strlen(name)-1]=='$'){ // var Str
if(name[strlen(name)-1]=='$') // var Str
StringBuf_Printf(&final_buf, buf2, script_getstr(st, arg+3)); StringBuf_Printf(&final_buf, buf2, script_getstr(st, arg+3));
}else{ // var Int else // var Int
StringBuf_Printf(&final_buf, buf2, script_getnum(st, arg+3)); StringBuf_Printf(&final_buf, buf2, script_getnum(st, arg+3));
}
} else { // Unsupported type } else { // Unsupported type
ShowError("buildin_sprintf: Unknown argument type!\n"); ShowError("buildin_sprintf: Unknown argument type!\n");
if(buf) aFree(buf); if(buf) aFree(buf);
@ -14885,13 +14886,13 @@ BUILDIN_FUNC(sprintf)
script_pushconststr(st,""); script_pushconststr(st,"");
return 1; return 1;
} }
arg++; arg++;
} }
// Append anything left // Append anything left
if(*q){ if(*q)
StringBuf_AppendStr(&final_buf, q); StringBuf_AppendStr(&final_buf, q);
}
// Passed more, than needed // Passed more, than needed
if(arg < argc) { if(arg < argc) {
@ -15663,13 +15664,11 @@ BUILDIN_FUNC(npcshopdelitem)
{ {
const char* npcname = script_getstr(st,2); const char* npcname = script_getstr(st,2);
struct npc_data* nd = npc_name2id(npcname); struct npc_data* nd = npc_name2id(npcname);
unsigned short nameid;
int n, i; int n, i;
int amount; int amount;
int size; int size;
if( !nd || ( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) ) if( !nd || ( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) ) { // Not found.
{ //Not found.
script_pushint(st,0); script_pushint(st,0);
return 0; return 0;
} }
@ -15678,13 +15677,11 @@ BUILDIN_FUNC(npcshopdelitem)
size = nd->u.shop.count; size = nd->u.shop.count;
// remove specified items from the shop item list // remove specified items from the shop item list
for( i = 3; i < 3 + amount; i++ ) for( i = 3; i < 3 + amount; i++ ) {
{ unsigned short nameid = script_getnum(st,i);
nameid = script_getnum(st,i);
ARR_FIND( 0, size, n, nd->u.shop.shop_item[n].nameid == nameid ); ARR_FIND( 0, size, n, nd->u.shop.shop_item[n].nameid == nameid );
if( n < size ) if( n < size ) {
{
memmove(&nd->u.shop.shop_item[n], &nd->u.shop.shop_item[n+1], sizeof(nd->u.shop.shop_item[0])*(size-n)); memmove(&nd->u.shop.shop_item[n], &nd->u.shop.shop_item[n+1], sizeof(nd->u.shop.shop_item[0])*(size-n));
size--; size--;
} }

View File

@ -12,7 +12,8 @@
/// failure constants for clif functions /// failure constants for clif functions
enum e_searchstore_failure { enum e_searchstore_failure
{
SSI_FAILED_NOTHING_SEARCH_ITEM = 0, // "No matching stores were found." SSI_FAILED_NOTHING_SEARCH_ITEM = 0, // "No matching stores were found."
SSI_FAILED_OVER_MAXCOUNT = 1, // "There are too many results. Please enter more detailed search term." SSI_FAILED_OVER_MAXCOUNT = 1, // "There are too many results. Please enter more detailed search term."
SSI_FAILED_SEARCH_CNT = 2, // "You cannot search anymore." SSI_FAILED_SEARCH_CNT = 2, // "You cannot search anymore."
@ -20,81 +21,75 @@ enum e_searchstore_failure {
SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE = 4, // "No sale (purchase) information available." SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE = 4, // "No sale (purchase) information available."
}; };
enum e_searchstore_searchtype
enum e_searchstore_searchtype { {
SEARCHTYPE_VENDING = 0, SEARCHTYPE_VENDING = 0,
SEARCHTYPE_BUYING_STORE = 1, SEARCHTYPE_BUYING_STORE = 1,
}; };
enum e_searchstore_effecttype { enum e_searchstore_effecttype
{
EFFECTTYPE_NORMAL = 0, EFFECTTYPE_NORMAL = 0,
EFFECTTYPE_CASH = 1, EFFECTTYPE_CASH = 1,
EFFECTTYPE_MAX EFFECTTYPE_MAX
}; };
/// type for shop search function /// type for shop search function
typedef bool (*searchstore_search_t)(struct map_session_data* sd, unsigned short nameid); typedef bool (*searchstore_search_t)(struct map_session_data* sd, unsigned short nameid);
typedef bool (*searchstore_searchall_t)(struct map_session_data* sd, const struct s_search_store_search* s); typedef bool (*searchstore_searchall_t)(struct map_session_data* sd, const struct s_search_store_search* s);
/// retrieves search function by type /// retrieves search function by type
static searchstore_search_t searchstore_getsearchfunc(unsigned char type) static searchstore_search_t searchstore_getsearchfunc(unsigned char type)
{ {
switch( type ) switch( type ) {
{
case SEARCHTYPE_VENDING: return &vending_search; case SEARCHTYPE_VENDING: return &vending_search;
case SEARCHTYPE_BUYING_STORE: return &buyingstore_search; case SEARCHTYPE_BUYING_STORE: return &buyingstore_search;
} }
return NULL; return NULL;
} }
/// retrieves search-all function by type /// retrieves search-all function by type
static searchstore_searchall_t searchstore_getsearchallfunc(unsigned char type) static searchstore_searchall_t searchstore_getsearchallfunc(unsigned char type)
{ {
switch( type ) switch( type ) {
{
case SEARCHTYPE_VENDING: return &vending_searchall; case SEARCHTYPE_VENDING: return &vending_searchall;
case SEARCHTYPE_BUYING_STORE: return &buyingstore_searchall; case SEARCHTYPE_BUYING_STORE: return &buyingstore_searchall;
} }
return NULL; return NULL;
} }
/// checks if the player has a store by type /// checks if the player has a store by type
static bool searchstore_hasstore(struct map_session_data* sd, unsigned char type) static bool searchstore_hasstore(struct map_session_data* sd, unsigned char type)
{ {
switch( type ) switch( type ) {
{
case SEARCHTYPE_VENDING: return sd->state.vending; case SEARCHTYPE_VENDING: return sd->state.vending;
case SEARCHTYPE_BUYING_STORE: return sd->state.buyingstore; case SEARCHTYPE_BUYING_STORE: return sd->state.buyingstore;
} }
return false; return false;
} }
/// returns player's store id by type /// returns player's store id by type
static int searchstore_getstoreid(struct map_session_data* sd, unsigned char type) static int searchstore_getstoreid(struct map_session_data* sd, unsigned char type)
{ {
switch( type ) switch( type ) {
{
case SEARCHTYPE_VENDING: return sd->vender_id; case SEARCHTYPE_VENDING: return sd->vender_id;
case SEARCHTYPE_BUYING_STORE: return sd->buyer_id; case SEARCHTYPE_BUYING_STORE: return sd->buyer_id;
} }
return 0; return 0;
} }
bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect)
bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect) { {
if( !battle_config.feature_search_stores || sd->searchstore.open ) { if( !battle_config.feature_search_stores || sd->searchstore.open )
return false; return false;
}
if( !uses || effect >= EFFECTTYPE_MAX ) {// invalid input if( !uses || effect >= EFFECTTYPE_MAX ) // invalid input
return false; return false;
}
sd->searchstore.open = true; sd->searchstore.open = true;
sd->searchstore.uses = uses; sd->searchstore.uses = uses;
@ -105,7 +100,6 @@ bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned s
return true; return true;
} }
void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count) void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count)
{ {
unsigned int i; unsigned int i;
@ -115,13 +109,11 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
searchstore_searchall_t store_searchall; searchstore_searchall_t store_searchall;
time_t querytime; time_t querytime;
if( !battle_config.feature_search_stores ) { if( !battle_config.feature_search_stores )
return; return;
}
if( !sd->searchstore.open ) { if( !sd->searchstore.open )
return; return;
}
if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL ) { if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL ) {
ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id); ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id);
@ -156,9 +148,8 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
} }
} }
if( max_price < min_price ) { if( max_price < min_price )
swap(min_price, max_price); swap(min_price, max_price);
}
sd->searchstore.uses--; sd->searchstore.uses--;
sd->searchstore.type = type; sd->searchstore.type = type;
@ -181,9 +172,8 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
iter = db_iterator((type == SEARCHTYPE_VENDING) ? vending_getdb() : buyingstore_getdb()); iter = db_iterator((type == SEARCHTYPE_VENDING) ? vending_getdb() : buyingstore_getdb());
for( pl_sd = dbi_first(iter); dbi_exists(iter); pl_sd = dbi_next(iter) ) { for( pl_sd = dbi_first(iter); dbi_exists(iter); pl_sd = dbi_next(iter) ) {
if( sd == pl_sd ) {// skip own shop, if any if( sd == pl_sd ) // skip own shop, if any
continue; continue;
}
if( !store_searchall(pl_sd, &s) ) { // exceeded result size if( !store_searchall(pl_sd, &s) ) { // exceeded result size
clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT); clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT);
@ -214,18 +204,17 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
} }
} }
/// checks whether or not more results are available for the client /// checks whether or not more results are available for the client
bool searchstore_querynext(struct map_session_data* sd) { bool searchstore_querynext(struct map_session_data* sd)
if( sd->searchstore.count && ( sd->searchstore.count-1 )/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages ) { {
if( sd->searchstore.count && ( sd->searchstore.count-1 )/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages )
return true; return true;
}
return false; return false;
} }
void searchstore_next(struct map_session_data* sd)
void searchstore_next(struct map_session_data* sd) { {
if( !battle_config.feature_search_stores || !sd->searchstore.open || sd->searchstore.count <= sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE ) if( !battle_config.feature_search_stores || !sd->searchstore.open || sd->searchstore.count <= sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE )
{// nothing (more) to display {// nothing (more) to display
return; return;
@ -238,8 +227,8 @@ void searchstore_next(struct map_session_data* sd) {
sd->searchstore.pages++; sd->searchstore.pages++;
} }
void searchstore_clear(struct map_session_data* sd)
void searchstore_clear(struct map_session_data* sd) { {
searchstore_clearremote(sd); searchstore_clearremote(sd);
if( sd->searchstore.items ) { // release results if( sd->searchstore.items ) { // release results
@ -252,7 +241,8 @@ void searchstore_clear(struct map_session_data* sd) {
} }
void searchstore_close(struct map_session_data* sd) { void searchstore_close(struct map_session_data* sd)
{
if( sd->searchstore.open ) { if( sd->searchstore.open ) {
searchstore_clear(sd); searchstore_clear(sd);
@ -262,14 +252,14 @@ void searchstore_close(struct map_session_data* sd) {
} }
void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid) { void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid)
{
unsigned int i; unsigned int i;
struct map_session_data* pl_sd; struct map_session_data* pl_sd;
searchstore_search_t store_search; searchstore_search_t store_search;
if( !battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count ) { if( !battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count )
return; return;
}
searchstore_clearremote(sd); searchstore_clearremote(sd);
@ -285,8 +275,7 @@ void searchstore_click(struct map_session_data* sd, int account_id, int store_id
return; return;
} }
if( !searchstore_hasstore(pl_sd, sd->searchstore.type) || searchstore_getstoreid(pl_sd, sd->searchstore.type) != store_id ) if( !searchstore_hasstore(pl_sd, sd->searchstore.type) || searchstore_getstoreid(pl_sd, sd->searchstore.type) != store_id ) { // no longer vending/buying or not same shop
{// no longer vending/buying or not same shop
clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
return; return;
} }
@ -301,26 +290,20 @@ void searchstore_click(struct map_session_data* sd, int account_id, int store_id
switch( sd->searchstore.effect ) { switch( sd->searchstore.effect ) {
case EFFECTTYPE_NORMAL: case EFFECTTYPE_NORMAL:
// display coords // display coords
if( sd->bl.m != pl_sd->bl.m ) // not on same map, wipe previous marker
if( sd->bl.m != pl_sd->bl.m ) {// not on same map, wipe previous marker
clif_search_store_info_click_ack(sd, -1, -1); clif_search_store_info_click_ack(sd, -1, -1);
} else { else
clif_search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y); clif_search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y);
}
break; break;
case EFFECTTYPE_CASH: case EFFECTTYPE_CASH:
// open remotely // open remotely
// to bypass range checks // to bypass range checks
sd->searchstore.remote_id = account_id; sd->searchstore.remote_id = account_id;
switch( sd->searchstore.type ) switch( sd->searchstore.type ) {
{
case SEARCHTYPE_VENDING: vending_vendinglistreq(sd, account_id); break; case SEARCHTYPE_VENDING: vending_vendinglistreq(sd, account_id); break;
case SEARCHTYPE_BUYING_STORE: buyingstore_open(sd, account_id); break; case SEARCHTYPE_BUYING_STORE: buyingstore_open(sd, account_id); break;
} }
break; break;
default: default:
// unknown // unknown
@ -328,27 +311,25 @@ void searchstore_click(struct map_session_data* sd, int account_id, int store_id
} }
} }
/// checks whether or not sd has opened account_id's shop remotely /// checks whether or not sd has opened account_id's shop remotely
bool searchstore_queryremote(struct map_session_data* sd, int account_id) { bool searchstore_queryremote(struct map_session_data* sd, int account_id)
{
return (bool)( sd->searchstore.open && sd->searchstore.count && sd->searchstore.remote_id == account_id ); return (bool)( sd->searchstore.open && sd->searchstore.count && sd->searchstore.remote_id == account_id );
} }
/// removes range-check bypassing for remotely opened stores /// removes range-check bypassing for remotely opened stores
void searchstore_clearremote(struct map_session_data* sd) { void searchstore_clearremote(struct map_session_data* sd)
{
sd->searchstore.remote_id = 0; sd->searchstore.remote_id = 0;
} }
/// receives results from a store-specific callback /// receives results from a store-specific callback
bool searchstore_result(struct map_session_data* sd, int store_id, int account_id, const char* store_name, unsigned short nameid, unsigned short amount, unsigned int price, const unsigned short* card, unsigned char refine) bool searchstore_result(struct map_session_data* sd, int store_id, int account_id, const char* store_name, unsigned short nameid, unsigned short amount, unsigned int price, const unsigned short* card, unsigned char refine)
{ {
struct s_search_store_info_item* ssitem; struct s_search_store_info_item* ssitem;
if( sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults ) {// no more if( sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults ) // no more
return false; return false;
}
ssitem = &sd->searchstore.items[sd->searchstore.count++]; ssitem = &sd->searchstore.items[sd->searchstore.count++];
ssitem->store_id = store_id; ssitem->store_id = store_id;

File diff suppressed because it is too large Load Diff

View File

@ -104,7 +104,7 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned
* Returns the status change associated with a skill. * Returns the status change associated with a skill.
* @param skill The skill to look up * @param skill The skill to look up
* @return The status registered for this skill * @return The status registered for this skill
**/ */
sc_type status_skill2sc(int skill) sc_type status_skill2sc(int skill)
{ {
int idx = skill_get_index(skill); int idx = skill_get_index(skill);
@ -120,7 +120,7 @@ sc_type status_skill2sc(int skill)
* Utilized for various duration lookups. Use with caution! * Utilized for various duration lookups. Use with caution!
* @param sc The status to look up * @param sc The status to look up
* @return A skill associated with the status * @return A skill associated with the status
**/ */
int status_sc2skill(sc_type sc) int status_sc2skill(sc_type sc)
{ {
if( sc < 0 || sc >= SC_MAX ) { if( sc < 0 || sc >= SC_MAX ) {
@ -135,7 +135,7 @@ int status_sc2skill(sc_type sc)
* Returns the status calculation flag associated with a given status change. * Returns the status calculation flag associated with a given status change.
* @param sc The status to look up * @param sc The status to look up
* @return The scb_flag registered for this status (see enum scb_flag) * @return The scb_flag registered for this status (see enum scb_flag)
**/ */
unsigned int status_sc2scb_flag(sc_type sc) unsigned int status_sc2scb_flag(sc_type sc)
{ {
if( sc < 0 || sc >= SC_MAX ) { if( sc < 0 || sc >= SC_MAX ) {
@ -150,7 +150,7 @@ unsigned int status_sc2scb_flag(sc_type sc)
* Returns the bl types which require a status change packet to be sent for a given client status identifier. * Returns the bl types which require a status change packet to be sent for a given client status identifier.
* @param type The client-side status identifier to look up (see enum si_type) * @param type The client-side status identifier to look up (see enum si_type)
* @return The bl types relevant to the type (see enum bl_type) * @return The bl types relevant to the type (see enum bl_type)
**/ */
int status_type2relevant_bl_types(int type) int status_type2relevant_bl_types(int type)
{ {
if( type < 0 || type >= SI_MAX ) { if( type < 0 || type >= SI_MAX ) {
@ -1244,7 +1244,7 @@ static void initDummyData(void)
* For copying a status_data structure from b to a, without overwriting current Hp and Sp * For copying a status_data structure from b to a, without overwriting current Hp and Sp
* @param a: Status data structure to copy from * @param a: Status data structure to copy from
* @param b: Status data structure to copy to * @param b: Status data structure to copy to
**/ */
static inline void status_cpy(struct status_data* a, const struct status_data* b) static inline void status_cpy(struct status_data* a, const struct status_data* b)
{ {
memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp))); memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
@ -1258,7 +1258,7 @@ static inline void status_cpy(struct status_data* a, const struct status_data* b
* @param flag: Used in case final value is higher than current * @param flag: Used in case final value is higher than current
* Use 2 to display healing effect * Use 2 to display healing effect
* @return heal or zapped HP if valid * @return heal or zapped HP if valid
**/ */
int status_set_hp(struct block_list *bl, unsigned int hp, int flag) int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
{ {
struct status_data *status; struct status_data *status;
@ -1281,7 +1281,7 @@ int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
* @param flag: Used in case final value is higher than current * @param flag: Used in case final value is higher than current
* Use 2 to display healing effect * Use 2 to display healing effect
* @return heal or zapped SP if valid * @return heal or zapped SP if valid
**/ */
int status_set_sp(struct block_list *bl, unsigned int sp, int flag) int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
{ {
struct status_data *status; struct status_data *status;
@ -1305,7 +1305,7 @@ int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
* @return hp+sp through status_damage() * @return hp+sp through status_damage()
* Note: HP/SP are integer values, not percentages. Values should be * Note: HP/SP are integer values, not percentages. Values should be
* calculated either within function call or before * calculated either within function call or before
**/ */
int64 status_charge(struct block_list* bl, int64 hp, int64 sp) int64 status_charge(struct block_list* bl, int64 hp, int64 sp)
{ {
if(!(bl->type&BL_CONSUME)) if(!(bl->type&BL_CONSUME))
@ -1328,7 +1328,7 @@ int64 status_charge(struct block_list* bl, int64 hp, int64 sp)
* @return hp+sp * @return hp+sp
* Note: HP/SP are integer values, not percentages. Values should be * Note: HP/SP are integer values, not percentages. Values should be
* calculated either within function call or before * calculated either within function call or before
**/ */
int status_damage(struct block_list *src,struct block_list *target,int64 dhp, int64 dsp, int walkdelay, int flag) int status_damage(struct block_list *src,struct block_list *target,int64 dhp, int64 dsp, int walkdelay, int flag)
{ {
struct status_data *status; struct status_data *status;
@ -1558,7 +1558,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
* @param flag: Whether it's Forced(&1) or gives HP/SP(&2) heal effect \n * @param flag: Whether it's Forced(&1) or gives HP/SP(&2) heal effect \n
* Forced healing overrides heal impedement statuses (Berserk) * Forced healing overrides heal impedement statuses (Berserk)
* @return hp+sp * @return hp+sp
**/ */
int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag) int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
{ {
struct status_data *status; struct status_data *status;
@ -1640,7 +1640,7 @@ int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
* 0: Heal target \n * 0: Heal target \n
* 2: Target must not die from subtraction * 2: Target must not die from subtraction
* @return hp+sp through status_heal() * @return hp+sp through status_heal()
**/ */
int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag) int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag)
{ {
struct status_data *status; struct status_data *status;
@ -1706,7 +1706,7 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe
* @param per_hp: Percentage of HP to revive with * @param per_hp: Percentage of HP to revive with
* @param per_sp: Percentage of SP to revive with * @param per_sp: Percentage of SP to revive with
* @return Successful (1) or Invalid target (0) * @return Successful (1) or Invalid target (0)
**/ */
int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp) int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
{ {
struct status_data *status; struct status_data *status;
@ -1743,7 +1743,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
return 1; return 1;
} }
/** [Skotlex] /**
* Checks whether the src can use the skill on the target, * Checks whether the src can use the skill on the target,
* taking into account status/option of both source/target * taking into account status/option of both source/target
* @param src: Object using skill on target [PC|MOB|PET|HOM|MER|ELEM] * @param src: Object using skill on target [PC|MOB|PET|HOM|MER|ELEM]
@ -1756,7 +1756,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
* 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones * 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones
* @return src can use skill (1) or cannot use skill (0) * @return src can use skill (1) or cannot use skill (0)
* @author [Skotlex] * @author [Skotlex]
**/ */
bool status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag) { bool status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag) {
struct status_data *status; struct status_data *status;
struct status_change *sc = NULL, *tsc; struct status_change *sc = NULL, *tsc;
@ -1981,7 +1981,7 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
* @param target: Object being targeted by src [PC|MOB|HOM|MER|ELEM] * @param target: Object being targeted by src [PC|MOB|HOM|MER|ELEM]
* @return src can see (1) or target is invisible (0) * @return src can see (1) or target is invisible (0)
* @author [Skotlex] * @author [Skotlex]
**/ */
int status_check_visibility(struct block_list *src, struct block_list *target) int status_check_visibility(struct block_list *src, struct block_list *target)
{ {
int view_range; int view_range;
@ -2032,7 +2032,7 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
* @param status: Player status * @param status: Player status
* @return base amotion after single/dual weapon and shield adjustments [RENEWAL] * @return base amotion after single/dual weapon and shield adjustments [RENEWAL]
* base amotion after single/dual weapon and stats adjustments [PRE-RENEWAL] * base amotion after single/dual weapon and stats adjustments [PRE-RENEWAL]
**/ */
int status_base_amotion_pc(struct map_session_data* sd, struct status_data* status) int status_base_amotion_pc(struct map_session_data* sd, struct status_data* status)
{ {
int amotion; int amotion;
@ -2080,7 +2080,7 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
* @param status: Object status * @param status: Object status
* @return base attack * @return base attack
* Note: Function only calculates Homunculus bATK in RENEWAL * Note: Function only calculates Homunculus bATK in RENEWAL
**/ */
static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status) static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status)
{ {
int flag = 0, str, dex, int flag = 0, str, dex,
@ -2144,7 +2144,7 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
* @param wa: Weapon attack * @param wa: Weapon attack
* @param status: Player status * @param status: Player status
* @return weapon attack * @return weapon attack
**/ */
unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status) unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status)
{ {
float str = status->str; float str = status->str;
@ -2166,7 +2166,7 @@ unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status)
* Fills in the misc data that can be calculated from the other status info (except for level) * Fills in the misc data that can be calculated from the other status info (except for level)
* @param bl: Object to calculate status on [PC|MOB|PET|HOM|MERC|ELEM] * @param bl: Object to calculate status on [PC|MOB|PET|HOM|MERC|ELEM]
* @param status: Player status * @param status: Player status
**/ */
void status_calc_misc(struct block_list *bl, struct status_data *status, int level) void status_calc_misc(struct block_list *bl, struct status_data *status, int level)
{ {
int stat; int stat;
@ -2273,13 +2273,14 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
status_calc_regen(bl, status, status_get_regen_data(bl)); status_calc_regen(bl, status, status_get_regen_data(bl));
} }
/** [Skotlex] /**
* Calculates the initial status for the given mob * Calculates the initial status for the given mob
* @param md: Mob object * @param md: Mob object
* @param opt: Whether or not it is the first calculation * @param opt: Whether or not it is the first calculation
This will only be false when a mob levels up (Regular and WoE Guardians) This will only be false when a mob levels up (Regular and WoE Guardians)
* @return 1 for calculated special statuses or 0 for none * @return 1 for calculated special statuses or 0 for none
**/ * @author [Skotlex]
*/
int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt)
{ {
struct status_data *status; struct status_data *status;
@ -2476,13 +2477,14 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt)
return 1; return 1;
} }
/** [Skotlex] /**
* Calculates the stats of the given pet * Calculates the stats of the given pet
* @param pd: Pet object * @param pd: Pet object
* @param opt: Whether or not it is the first calculation * @param opt: Whether or not it is the first calculation
This will only be false when a pet levels up This will only be false when a pet levels up
* @return 1 * @return 1
**/ * @author [Skotlex]
*/
int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt) int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
{ {
nullpo_ret(pd); nullpo_ret(pd);
@ -2549,11 +2551,12 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
return 1; return 1;
} }
/** [Cydh] /**
* Get HP bonus modifiers * Get HP bonus modifiers
* @param bl: block_list that will be checked * @param bl: block_list that will be checked
* @param type: type of e_status_bonus (STATUS_BONUS_FIX or STATUS_BONUS_RATE) * @param type: type of e_status_bonus (STATUS_BONUS_FIX or STATUS_BONUS_RATE)
* @return bonus: total bonus for HP * @return bonus: total bonus for HP
* @author [Cydh]
*/ */
static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) { static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
int bonus = 0; int bonus = 0;
@ -2661,11 +2664,12 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
return min(bonus,INT_MAX); return min(bonus,INT_MAX);
} }
/** [Cydh] /**
* Get SP bonus modifiers * Get SP bonus modifiers
* @param bl: block_list that will be checked * @param bl: block_list that will be checked
* @param type: type of e_status_bonus (STATUS_BONUS_FIX or STATUS_BONUS_RATE) * @param type: type of e_status_bonus (STATUS_BONUS_FIX or STATUS_BONUS_RATE)
* @return bonus: total bonus for SP * @return bonus: total bonus for SP
* @author [Cydh]
*/ */
static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) { static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
int bonus = 0; int bonus = 0;
@ -2742,7 +2746,7 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
* @param stat Vit/Int of player as param modifier * @param stat Vit/Int of player as param modifier
* @param isHP true - calculates Max HP, false - calculated Max SP * @param isHP true - calculates Max HP, false - calculated Max SP
* @return max The max value of HP or SP * @return max The max value of HP or SP
**/ */
static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned int stat, bool isHP) { static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned int stat, bool isHP) {
double max = 0; double max = 0;
uint16 idx, level, job_id; uint16 idx, level, job_id;
@ -2773,7 +2777,7 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned
* @param sd: Player object * @param sd: Player object
* @param opt: Whether it is first calc (login) or not * @param opt: Whether it is first calc (login) or not
* @return (-1) for too many recursive calls, (1) recursive call, (0) success * @return (-1) for too many recursive calls, (1) recursive call, (0) success
**/ */
int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
{ {
static int calculating = 0; ///< Check for recursive call preemption. [Skotlex] static int calculating = 0; ///< Check for recursive call preemption. [Skotlex]
@ -3607,7 +3611,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
* @param md: Mercenary object * @param md: Mercenary object
* @param opt: Whether it is first calc or not (0 on level up or status) * @param opt: Whether it is first calc or not (0 on level up or status)
* @return 0 * @return 0
**/ */
int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt) int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt)
{ {
struct status_data *status = &md->base_status; struct status_data *status = &md->base_status;
@ -3636,7 +3640,7 @@ int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt
* @param hd: Homunculus object * @param hd: Homunculus object
* @param opt: Whether it is first calc or not (0 on level up or status) * @param opt: Whether it is first calc or not (0 on level up or status)
* @return 1 * @return 1
**/ */
int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
{ {
struct status_data *status = &hd->base_status; struct status_data *status = &hd->base_status;
@ -3734,7 +3738,7 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
* @param ed: Elemental object * @param ed: Elemental object
* @param opt: Whether it is first calc or not (0 on status change) * @param opt: Whether it is first calc or not (0 on status change)
* @return 0 * @return 0
**/ */
int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt) int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt)
{ {
struct status_data *status = &ed->base_status; struct status_data *status = &ed->base_status;
@ -3784,7 +3788,7 @@ int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt
* @param nd: NPC object * @param nd: NPC object
* @param opt: Whether it is first calc or not (what?) * @param opt: Whether it is first calc or not (what?)
* @return 0 * @return 0
**/ */
int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
{ {
struct status_data *status = &nd->status; struct status_data *status = &nd->status;
@ -3827,7 +3831,7 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
* @param bl: Object to calculate regen for [PC|HOM|MER|ELEM] * @param bl: Object to calculate regen for [PC|HOM|MER|ELEM]
* @param status: Object's status * @param status: Object's status
* @param regen: Object's base regeneration data * @param regen: Object's base regeneration data
**/ */
void status_calc_regen(struct block_list *bl, struct status_data *status, struct regen_data *regen) void status_calc_regen(struct block_list *bl, struct status_data *status, struct regen_data *regen)
{ {
struct map_session_data *sd; struct map_session_data *sd;
@ -3931,7 +3935,7 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
* @param bl: Object to calculate regen for [PC|HOM|MER|ELEM] * @param bl: Object to calculate regen for [PC|HOM|MER|ELEM]
* @param regen: Object's base regeneration data * @param regen: Object's base regeneration data
* @param sc: Object's status change data * @param sc: Object's status change data
**/ */
void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc) void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
{ {
if (!(bl->type&BL_REGEN) || !regen) if (!(bl->type&BL_REGEN) || !regen)
@ -4021,7 +4025,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
* @param sc: Object's status change data * @param sc: Object's status change data
* @param flag: Which state to apply to bl * @param flag: Which state to apply to bl
* @param start: (1) start state, (0) remove state * @param start: (1) start state, (0) remove state
**/ */
void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start ) void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start )
{ {
@ -4090,7 +4094,7 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
* See [set_sc] [add_sc] * See [set_sc] [add_sc]
* @param bl: Object whose status has changed [PC|MOB|HOM|MER|ELEM] * @param bl: Object whose status has changed [PC|MOB|HOM|MER|ELEM]
* @param flag: Which status has changed on bl * @param flag: Which status has changed on bl
**/ */
void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
{ {
const struct status_data *b_status = status_get_base_status(bl); const struct status_data *b_status = status_get_base_status(bl);
@ -4546,7 +4550,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
* @param bl: Object whose status has changed [PC|MOB|HOM|MER|ELEM] * @param bl: Object whose status has changed [PC|MOB|HOM|MER|ELEM]
* @param flag: Which status has changed on bl * @param flag: Which status has changed on bl
* @param opt: If true, will cause status_calc_* functions to run their base status initialization code * @param opt: If true, will cause status_calc_* functions to run their base status initialization code
**/ */
void status_calc_bl_(struct block_list* bl, enum scb_flag flag, enum e_status_calc_opt opt) void status_calc_bl_(struct block_list* bl, enum scb_flag flag, enum e_status_calc_opt opt)
{ {
struct status_data b_status; // Previous battle status struct status_data b_status; // Previous battle status
@ -4728,7 +4732,7 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, enum e_status_ca
* @param sc: Object's status change information * @param sc: Object's status change information
* @param str: Initial str * @param str: Initial str
* @return modified str with cap_value(str,0,USHRT_MAX) * @return modified str with cap_value(str,0,USHRT_MAX)
**/ */
static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str) static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -4796,7 +4800,7 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param agi: Initial agi * @param agi: Initial agi
* @return modified agi with cap_value(agi,0,USHRT_MAX) * @return modified agi with cap_value(agi,0,USHRT_MAX)
**/ */
static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi) static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -4860,7 +4864,7 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param vit: Initial vit * @param vit: Initial vit
* @return modified vit with cap_value(vit,0,USHRT_MAX) * @return modified vit with cap_value(vit,0,USHRT_MAX)
**/ */
static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit) static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -4918,7 +4922,7 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param int_: Initial int * @param int_: Initial int
* @return modified int with cap_value(int_,0,USHRT_MAX) * @return modified int with cap_value(int_,0,USHRT_MAX)
**/ */
static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_) static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -4987,7 +4991,7 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param dex: Initial dex * @param dex: Initial dex
* @return modified dex with cap_value(dex,0,USHRT_MAX) * @return modified dex with cap_value(dex,0,USHRT_MAX)
**/ */
static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex) static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5054,7 +5058,7 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param luk: Initial luk * @param luk: Initial luk
* @return modified luk with cap_value(luk,0,USHRT_MAX) * @return modified luk with cap_value(luk,0,USHRT_MAX)
**/ */
static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk) static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5111,7 +5115,7 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param batk: Initial batk * @param batk: Initial batk
* @return modified batk with cap_value(batk,0,USHRT_MAX) * @return modified batk with cap_value(batk,0,USHRT_MAX)
**/ */
static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk) static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5188,7 +5192,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
* @param sc: Object's status change information * @param sc: Object's status change information
* @param watk: Initial watk * @param watk: Initial watk
* @return modified watk with cap_value(watk,0,USHRT_MAX) * @return modified watk with cap_value(watk,0,USHRT_MAX)
**/ */
static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk) static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5281,7 +5285,7 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
* @param sc: Object's status change information * @param sc: Object's status change information
* @param matk: Initial matk * @param matk: Initial matk
* @return modified matk with cap_value(matk,0,USHRT_MAX) * @return modified matk with cap_value(matk,0,USHRT_MAX)
**/ */
static unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk) static unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
{ {
if (!sc || !sc->count) if (!sc || !sc->count)
@ -5328,7 +5332,7 @@ static unsigned short status_calc_ematk(struct block_list *bl, struct status_cha
* @param sc: Object's status change information * @param sc: Object's status change information
* @param matk: Initial matk * @param matk: Initial matk
* @return modified matk with cap_value(matk,0,USHRT_MAX) * @return modified matk with cap_value(matk,0,USHRT_MAX)
**/ */
static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk) static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5384,7 +5388,7 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan
* @param sc: Object's status change information * @param sc: Object's status change information
* @param critical: Initial critical * @param critical: Initial critical
* @return modified critical with cap_value(critical,10,USHRT_MAX) * @return modified critical with cap_value(critical,10,USHRT_MAX)
**/ */
static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical) static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5422,7 +5426,7 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
* @param sc: Object's status change information * @param sc: Object's status change information
* @param hit: Initial hit * @param hit: Initial hit
* @return modified hit with cap_value(hit,1,USHRT_MAX) * @return modified hit with cap_value(hit,1,USHRT_MAX)
**/ */
static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit) static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5473,7 +5477,7 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
* @param sc: Object's status change information * @param sc: Object's status change information
* @param flee: Initial flee * @param flee: Initial flee
* @return modified flee with cap_value(flee,1,USHRT_MAX) * @return modified flee with cap_value(flee,1,USHRT_MAX)
**/ */
static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee) static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee)
{ {
if( bl->type == BL_PC ) { if( bl->type == BL_PC ) {
@ -5575,7 +5579,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
* @param sc: Object's status change information * @param sc: Object's status change information
* @param flee2: Initial flee2 * @param flee2: Initial flee2
* @return modified flee2 with cap_value(flee2,10,USHRT_MAX) * @return modified flee2 with cap_value(flee2,10,USHRT_MAX)
**/ */
static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2) static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5597,7 +5601,7 @@ static signed short status_calc_flee2(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param def: Initial def * @param def: Initial def
* @return modified def with cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX) * @return modified def with cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX)
**/ */
static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def) static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5692,7 +5696,7 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
* @param sc: Object's status change information * @param sc: Object's status change information
* @param def2: Initial def2 * @param def2: Initial def2
* @return modified def2 with cap_value(def2,SHRT_MIN,SHRT_MAX) * @return modified def2 with cap_value(def2,SHRT_MIN,SHRT_MAX)
**/ */
static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2) static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5761,7 +5765,7 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
* @param sc: Object's status change information * @param sc: Object's status change information
* @param mdef: Initial mdef * @param mdef: Initial mdef
* @return modified mdef with cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX) * @return modified mdef with cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX)
**/ */
static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef) static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5820,7 +5824,7 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
* @param sc: Object's status change information * @param sc: Object's status change information
* @param mdef2: Initial mdef2 * @param mdef2: Initial mdef2
* @return modified mdef2 with cap_value(mdef2,SHRT_MIN,SHRT_MAX) * @return modified mdef2 with cap_value(mdef2,SHRT_MIN,SHRT_MAX)
**/ */
static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2) static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -5859,7 +5863,7 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang
* @param sc: Object's status change information * @param sc: Object's status change information
* @param speed: Initial speed * @param speed: Initial speed
* @return modified speed with cap_value(speed,10,USHRT_MAX) * @return modified speed with cap_value(speed,10,USHRT_MAX)
**/ */
static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed) static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
{ {
TBL_PC* sd = BL_CAST(BL_PC, bl); TBL_PC* sd = BL_CAST(BL_PC, bl);
@ -6040,7 +6044,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
* @param flag: flag&1 - fixed value [malufett] * @param flag: flag&1 - fixed value [malufett]
* flag&2 - percentage value * flag&2 - percentage value
* @return modified aspd * @return modified aspd
**/ */
static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag) static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag)
{ {
int i, pots = 0, skills1 = 0, skills2 = 0; int i, pots = 0, skills1 = 0, skills2 = 0;
@ -6173,7 +6177,7 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
* @param sc: Object's status change information * @param sc: Object's status change information
* @param aspd: Object's current ASPD * @param aspd: Object's current ASPD
* @return modified aspd * @return modified aspd
**/ */
static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd) static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd)
{ {
if (!sc || !sc->count) if (!sc || !sc->count)
@ -6200,7 +6204,7 @@ static short status_calc_fix_aspd(struct block_list *bl, struct status_change *s
* @param sc: Object's status change information * @param sc: Object's status change information
* @param aspd_rate: Object's current ASPD * @param aspd_rate: Object's current ASPD
* @return modified aspd_rate * @return modified aspd_rate
**/ */
static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate) static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
{ {
int i; int i;
@ -6342,7 +6346,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
* @param sc: Object's status change information * @param sc: Object's status change information
* @param dmotion: Object's current damage delay * @param dmotion: Object's current damage delay
* @return modified delay rate * @return modified delay rate
**/ */
static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion) static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
{ {
if( !sc || !sc->count || map_flag_gvg(bl->m) || map[bl->m].flag.battleground ) if( !sc || !sc->count || map_flag_gvg(bl->m) || map[bl->m].flag.battleground )
@ -6363,7 +6367,7 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c
* @param bl: Object's block_list data * @param bl: Object's block_list data
* @param maxhp: Object's current max HP * @param maxhp: Object's current max HP
* @return modified maxhp * @return modified maxhp
**/ */
static unsigned int status_calc_maxhp(struct block_list *bl, uint64 maxhp) static unsigned int status_calc_maxhp(struct block_list *bl, uint64 maxhp)
{ {
int rate = 100; int rate = 100;
@ -6382,7 +6386,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, uint64 maxhp)
* @param bl: Object's block_list data * @param bl: Object's block_list data
* @param maxsp: Object's current max SP * @param maxsp: Object's current max SP
* @return modified maxsp * @return modified maxsp
**/ */
static unsigned int status_calc_maxsp(struct block_list *bl, uint64 maxsp) static unsigned int status_calc_maxsp(struct block_list *bl, uint64 maxsp)
{ {
int rate = 100; int rate = 100;
@ -6401,7 +6405,7 @@ static unsigned int status_calc_maxsp(struct block_list *bl, uint64 maxsp)
* @param sc: Object's status change information * @param sc: Object's status change information
* @param element: Object's current element * @param element: Object's current element
* @return new element * @return new element
**/ */
static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element) static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -6429,7 +6433,7 @@ static unsigned char status_calc_element(struct block_list *bl, struct status_ch
* @param sc: Object's status change information * @param sc: Object's status change information
* @param lv: Object's current element level * @param lv: Object's current element level
* @return new element level * @return new element level
**/ */
static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv) static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -6459,7 +6463,7 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status
* @param sc: Object's status change information * @param sc: Object's status change information
* @param element: Object's current attack element * @param element: Object's current attack element
* @return new attack element * @return new attack element
**/ */
unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element) unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -6499,7 +6503,7 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
* @param sc: Object's status change data * @param sc: Object's status change data
* @param mode: Original mode * @param mode: Original mode
* @return mode with cap_value(mode,0,USHRT_MAX) * @return mode with cap_value(mode,0,USHRT_MAX)
**/ */
static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode) static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode)
{ {
if(!sc || !sc->count) if(!sc || !sc->count)
@ -6519,7 +6523,7 @@ static unsigned short status_calc_mode(struct block_list *bl, struct status_chan
* Gets the name of the given bl * Gets the name of the given bl
* @param bl: Object whose name to get [PC|MOB|PET|HOM|NPC] * @param bl: Object whose name to get [PC|MOB|PET|HOM|NPC]
* @return name or "Unknown" if any other bl->type than noted above * @return name or "Unknown" if any other bl->type than noted above
**/ */
const char* status_get_name(struct block_list *bl) const char* status_get_name(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6537,7 +6541,7 @@ const char* status_get_name(struct block_list *bl)
* Gets the class/sprite id of the given bl * Gets the class/sprite id of the given bl
* @param bl: Object whose class to get [PC|MOB|PET|HOM|MER|NPC|ELEM] * @param bl: Object whose class to get [PC|MOB|PET|HOM|MER|NPC|ELEM]
* @return class or 0 if any other bl->type than noted above * @return class or 0 if any other bl->type than noted above
**/ */
int status_get_class(struct block_list *bl) int status_get_class(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6557,7 +6561,7 @@ int status_get_class(struct block_list *bl)
* Gets the base level of the given bl * Gets the base level of the given bl
* @param bl: Object whose base level to get [PC|MOB|PET|HOM|MER|NPC|ELEM] * @param bl: Object whose base level to get [PC|MOB|PET|HOM|MER|NPC|ELEM]
* @return base level or 1 if any other bl->type than noted above * @return base level or 1 if any other bl->type than noted above
**/ */
int status_get_lv(struct block_list *bl) int status_get_lv(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6577,7 +6581,7 @@ int status_get_lv(struct block_list *bl)
* Gets the regeneration info of the given bl * Gets the regeneration info of the given bl
* @param bl: Object whose regen info to get [PC|HOM|MER|ELEM] * @param bl: Object whose regen info to get [PC|HOM|MER|ELEM]
* @return regen data or NULL if any other bl->type than noted above * @return regen data or NULL if any other bl->type than noted above
**/ */
struct regen_data *status_get_regen_data(struct block_list *bl) struct regen_data *status_get_regen_data(struct block_list *bl)
{ {
nullpo_retr(NULL, bl); nullpo_retr(NULL, bl);
@ -6595,7 +6599,7 @@ struct regen_data *status_get_regen_data(struct block_list *bl)
* Gets the status data of the given bl * Gets the status data of the given bl
* @param bl: Object whose status to get [PC|MOB|PET|HOM|MER|ELEM|NPC] * @param bl: Object whose status to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
* @return status or "dummy_status" if any other bl->type than noted above * @return status or "dummy_status" if any other bl->type than noted above
**/ */
struct status_data *status_get_status_data(struct block_list *bl) struct status_data *status_get_status_data(struct block_list *bl)
{ {
nullpo_retr(&dummy_status, bl); nullpo_retr(&dummy_status, bl);
@ -6617,7 +6621,7 @@ struct status_data *status_get_status_data(struct block_list *bl)
* Gets the base status data of the given bl * Gets the base status data of the given bl
* @param bl: Object whose status to get [PC|MOB|PET|HOM|MER|ELEM|NPC] * @param bl: Object whose status to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
* @return base_status or NULL if any other bl->type than noted above * @return base_status or NULL if any other bl->type than noted above
**/ */
struct status_data *status_get_base_status(struct block_list *bl) struct status_data *status_get_base_status(struct block_list *bl)
{ {
nullpo_retr(NULL, bl); nullpo_retr(NULL, bl);
@ -6638,7 +6642,7 @@ struct status_data *status_get_base_status(struct block_list *bl)
* Gets the defense of the given bl * Gets the defense of the given bl
* @param bl: Object whose defense to get [PC|MOB|HOM|MER|ELEM] * @param bl: Object whose defense to get [PC|MOB|HOM|MER|ELEM]
* @return defense with cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX) * @return defense with cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX)
**/ */
defType status_get_def(struct block_list *bl) defType status_get_def(struct block_list *bl)
{ {
struct unit_data *ud; struct unit_data *ud;
@ -6655,7 +6659,7 @@ defType status_get_def(struct block_list *bl)
* Gets the walking speed of the given bl * Gets the walking speed of the given bl
* @param bl: Object whose speed to get [PC|MOB|PET|HOM|MER|ELEM|NPC] * @param bl: Object whose speed to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
* @return speed * @return speed
**/ */
unsigned short status_get_speed(struct block_list *bl) unsigned short status_get_speed(struct block_list *bl)
{ {
if(bl->type==BL_NPC)// Only BL with speed data but no status_data [Skotlex] if(bl->type==BL_NPC)// Only BL with speed data but no status_data [Skotlex]
@ -6667,7 +6671,7 @@ unsigned short status_get_speed(struct block_list *bl)
* Gets the party ID of the given bl * Gets the party ID of the given bl
* @param bl: Object whose party ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM] * @param bl: Object whose party ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM]
* @return party ID * @return party ID
**/ */
int status_get_party_id(struct block_list *bl) int status_get_party_id(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6710,7 +6714,7 @@ int status_get_party_id(struct block_list *bl)
* Gets the guild ID of the given bl * Gets the guild ID of the given bl
* @param bl: Object whose guild ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM|NPC] * @param bl: Object whose guild ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM|NPC]
* @return guild ID * @return guild ID
**/ */
int status_get_guild_id(struct block_list *bl) int status_get_guild_id(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6757,7 +6761,7 @@ int status_get_guild_id(struct block_list *bl)
* Gets the guild emblem ID of the given bl * Gets the guild emblem ID of the given bl
* @param bl: Object whose emblem ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM|NPC] * @param bl: Object whose emblem ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM|NPC]
* @return guild emblem ID * @return guild emblem ID
**/ */
int status_get_emblem_id(struct block_list *bl) int status_get_emblem_id(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6805,7 +6809,7 @@ int status_get_emblem_id(struct block_list *bl)
* Gets the race of a mob or pet * Gets the race of a mob or pet
* @param bl: Object whose race to get [MOB|PET] * @param bl: Object whose race to get [MOB|PET]
* @return race * @return race
**/ */
int status_get_race2(struct block_list *bl) int status_get_race2(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6820,7 +6824,7 @@ int status_get_race2(struct block_list *bl)
* Checks if an object is dead * Checks if an object is dead
* @param bl: Object to check [PC|MOB|HOM|MER|ELEM] * @param bl: Object to check [PC|MOB|HOM|MER|ELEM]
* @return 1: Is dead or 0: Is alive * @return 1: Is dead or 0: Is alive
**/ */
int status_isdead(struct block_list *bl) int status_isdead(struct block_list *bl)
{ {
nullpo_ret(bl); nullpo_ret(bl);
@ -6831,7 +6835,7 @@ int status_isdead(struct block_list *bl)
* Checks if an object is immune to magic * Checks if an object is immune to magic
* @param bl: Object to check [PC|MOB|HOM|MER|ELEM] * @param bl: Object to check [PC|MOB|HOM|MER|ELEM]
* @return value of magic damage to be blocked * @return value of magic damage to be blocked
**/ */
int status_isimmune(struct block_list *bl) int status_isimmune(struct block_list *bl)
{ {
struct status_change *sc =status_get_sc(bl); struct status_change *sc =status_get_sc(bl);
@ -6848,7 +6852,7 @@ int status_isimmune(struct block_list *bl)
* Get view data of an object * Get view data of an object
* @param bl: Object whose view data to get [PC|MOB|PET|HOM|MER|ELEM|NPC] * @param bl: Object whose view data to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
* @return view data structure bl->vd * @return view data structure bl->vd
**/ */
struct view_data* status_get_viewdata(struct block_list *bl) struct view_data* status_get_viewdata(struct block_list *bl)
{ {
nullpo_retr(NULL, bl); nullpo_retr(NULL, bl);
@ -6870,7 +6874,7 @@ struct view_data* status_get_viewdata(struct block_list *bl)
* SC views are set in clif_getareachar_unit() * SC views are set in clif_getareachar_unit()
* @param bl: Object whose view data to set [PC|MOB|PET|HOM|MER|ELEM|NPC] * @param bl: Object whose view data to set [PC|MOB|PET|HOM|MER|ELEM|NPC]
* @param class_: class of the object * @param class_: class of the object
**/ */
void status_set_viewdata(struct block_list *bl, int class_) void status_set_viewdata(struct block_list *bl, int class_)
{ {
struct view_data* vd; struct view_data* vd;
@ -7012,7 +7016,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
* Get status change data of an object * Get status change data of an object
* @param bl: Object whose sc data to get [PC|MOB|HOM|MER|ELEM|NPC] * @param bl: Object whose sc data to get [PC|MOB|HOM|MER|ELEM|NPC]
* @return status change data structure bl->sc * @return status change data structure bl->sc
**/ */
struct status_change *status_get_sc(struct block_list *bl) struct status_change *status_get_sc(struct block_list *bl)
{ {
if( bl ) if( bl )
@ -7030,7 +7034,7 @@ struct status_change *status_get_sc(struct block_list *bl)
/** /**
* Initiate (memset) the status change data of an object * Initiate (memset) the status change data of an object
* @param bl: Object whose sc data to memset [PC|MOB|HOM|MER|ELEM|NPC] * @param bl: Object whose sc data to memset [PC|MOB|HOM|MER|ELEM|NPC]
**/ */
void status_change_init(struct block_list *bl) void status_change_init(struct block_list *bl)
{ {
struct status_change *sc = status_get_sc(bl); struct status_change *sc = status_get_sc(bl);
@ -7048,7 +7052,7 @@ void status_change_init(struct block_list *bl)
* @param tick: Initial duration that the status change affects bl * @param tick: Initial duration that the status change affects bl
* @param flag: Value which determines what parts to calculate. See e_status_change_start_flags * @param flag: Value which determines what parts to calculate. See e_status_change_start_flags
* @return adjusted duration based on flag values * @return adjusted duration based on flag values
**/ */
int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, unsigned char flag) int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, unsigned char flag)
{ {
/// Resistance rate: 10000 = 100% /// Resistance rate: 10000 = 100%
@ -7386,7 +7390,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
* @param type: Status change (SC_*) * @param type: Status change (SC_*)
* @param dval1~3: Depends on type of status change * @param dval1~3: Depends on type of status change
* Author: Ind * Author: Ind
**/ */
void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) { void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) {
struct sc_display_entry *entry; struct sc_display_entry *entry;
int i; int i;
@ -7419,7 +7423,7 @@ void status_display_add(struct map_session_data *sd, enum sc_type type, int dval
* @param sd: Source to remove effect [PC] * @param sd: Source to remove effect [PC]
* @param type: Status change (SC_*) * @param type: Status change (SC_*)
* Author: Ind * Author: Ind
**/ */
void status_display_remove(struct map_session_data *sd, enum sc_type type) { void status_display_remove(struct map_session_data *sd, enum sc_type type) {
int i; int i;
@ -7463,7 +7467,7 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type) {
* @param tick: Initial duration that the status change affects bl * @param tick: Initial duration that the status change affects bl
* @param flag: Value which determines what parts to calculate. See e_status_change_start_flags * @param flag: Value which determines what parts to calculate. See e_status_change_start_flags
* @return adjusted duration based on flag values * @return adjusted duration based on flag values
**/ */
int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,unsigned char flag) { int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,unsigned char flag) {
struct map_session_data *sd = NULL; struct map_session_data *sd = NULL;
struct status_change* sc; struct status_change* sc;
@ -10370,7 +10374,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
* 2: Do clif_changeoption() * 2: Do clif_changeoption()
* 3: Do not remove some permanent/time-independent effects * 3: Do not remove some permanent/time-independent effects
* @return 1: Success 0: Fail * @return 1: Success 0: Fail
**/ */
int status_change_clear(struct block_list* bl, int type) int status_change_clear(struct block_list* bl, int type)
{ {
struct status_change* sc; struct status_change* sc;
@ -10504,7 +10508,7 @@ int status_change_clear(struct block_list* bl, int type)
* @param file: Used for dancing save * @param file: Used for dancing save
* @param line: Used for dancing save * @param line: Used for dancing save
* @return 1: Success 0: Fail * @return 1: Success 0: Fail
**/ */
int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line) int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
{ {
struct map_session_data *sd; struct map_session_data *sd;
@ -11239,7 +11243,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
* @param id: ID of character * @param id: ID of character
* @param data: Information passed through the timer call * @param data: Information passed through the timer call
* @return 1: Success 0: Fail * @return 1: Success 0: Fail
**/ */
int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data) int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{ {
struct block_list *bl; struct block_list *bl;
@ -11276,13 +11280,13 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
/** /**
* Resets timers for statuses * Resets timers for statuses
* Used with reoccuring status effects, such as dropping SP every 5 seconds * Used with reoccurring status effects, such as dropping SP every 5 seconds
* @param tid: Timer ID * @param tid: Timer ID
* @param tick: How long before next call * @param tick: How long before next call
* @param id: ID of character * @param id: ID of character
* @param data: Information passed through the timer call * @param data: Information passed through the timer call
* @return 1: Success 0: Fail * @return 1: Success 0: Fail
**/ */
int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
{ {
enum sc_type type = (sc_type)data; enum sc_type type = (sc_type)data;
@ -11477,7 +11481,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
if( sd && --(sce->val4) >= 0 ) { if( sd && --(sce->val4) >= 0 ) {
struct mob_data *boss_md = map_id2boss(sce->val1); struct mob_data *boss_md = map_id2boss(sce->val1);
if( boss_md && sd->bl.m == boss_md->bl.m ) { if( boss_md && sd->bl.m == boss_md->bl.m ) {
clif_bossmapinfo(sd->fd, boss_md, 1); // Update X - Y on minimap clif_bossmapinfo(sd->fd, boss_md, 1); // Update X, Y on minimap
if (boss_md->bl.prev != NULL) { if (boss_md->bl.prev != NULL) {
sc_timer_next(5000 + tick, status_change_timer, bl->id, data); sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
return 0; return 0;
@ -12151,7 +12155,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
* For each iteration of repetitive status * For each iteration of repetitive status
* @param bl: Object [PC|MOB|HOM|MER|ELEM] * @param bl: Object [PC|MOB|HOM|MER|ELEM]
* @param ap: va_list arguments (src, sce, type, tick) * @param ap: va_list arguments (src, sce, type, tick)
**/ */
int status_change_timer_sub(struct block_list* bl, va_list ap) int status_change_timer_sub(struct block_list* bl, va_list ap)
{ {
struct status_change* tsc; struct status_change* tsc;
@ -12229,7 +12233,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
* &1: Clear Buffs * &1: Clear Buffs
* $2: Clear Debuffs * $2: Clear Debuffs
* &4: Specific debuffs with a refresh * &4: Specific debuffs with a refresh
**/ */
void status_change_clear_buffs (struct block_list* bl, int type) void status_change_clear_buffs (struct block_list* bl, int type)
{ {
int i; int i;
@ -12404,7 +12408,7 @@ void status_change_clear_buffs (struct block_list* bl, int type)
* @param src: Object initiating change on bl [PC|MOB|HOM|MER|ELEM] * @param src: Object initiating change on bl [PC|MOB|HOM|MER|ELEM]
* @param bl: Object to change * @param bl: Object to change
* @return 1: Success 0: Fail * @return 1: Success 0: Fail
**/ */
int status_change_spread( struct block_list *src, struct block_list *bl ) int status_change_spread( struct block_list *src, struct block_list *bl )
{ {
int i, flag = 0; int i, flag = 0;
@ -12506,7 +12510,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl )
* @param bl: Object applying bonuses to [PC|HOM|MER|ELEM] * @param bl: Object applying bonuses to [PC|HOM|MER|ELEM]
* @param args: va_list arguments * @param args: va_list arguments
* @return which regeneration bonuses have been applied (flag) * @return which regeneration bonuses have been applied (flag)
**/ */
static unsigned int natural_heal_prev_tick,natural_heal_diff_tick; static unsigned int natural_heal_prev_tick,natural_heal_diff_tick;
static int status_natural_heal(struct block_list* bl, va_list args) static int status_natural_heal(struct block_list* bl, va_list args)
{ {
@ -12692,7 +12696,7 @@ static int status_natural_heal(struct block_list* bl, va_list args)
* @param id: Object ID to heal * @param id: Object ID to heal
* @param data: data pushed through timer function * @param data: data pushed through timer function
* @return 0 * @return 0
**/ */
static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data) static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{ {
natural_heal_diff_tick = DIFF_TICK(tick,natural_heal_prev_tick); natural_heal_diff_tick = DIFF_TICK(tick,natural_heal_prev_tick);
@ -12706,7 +12710,7 @@ static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_
* @param wlv: The weapon type of the item to refine (see see enum refine_type) * @param wlv: The weapon type of the item to refine (see see enum refine_type)
* @param refine: The target's refine level * @param refine: The target's refine level
* @return The chance to refine the item, in percent (0~100) * @return The chance to refine the item, in percent (0~100)
**/ */
int status_get_refine_chance(enum refine_type wlv, int refine) int status_get_refine_chance(enum refine_type wlv, int refine)
{ {
@ -12722,7 +12726,7 @@ int status_get_refine_chance(enum refine_type wlv, int refine)
* @param columns: Columns passed from sv_readdb function call * @param columns: Columns passed from sv_readdb function call
* @param current: Current row being read into atkmods array * @param current: Current row being read into atkmods array
* @return True * @return True
**/ */
static bool status_readdb_sizefix(char* fields[], int columns, int current) static bool status_readdb_sizefix(char* fields[], int columns, int current)
{ {
unsigned int i; unsigned int i;
@ -12739,7 +12743,7 @@ static bool status_readdb_sizefix(char* fields[], int columns, int current)
* @param columns: Columns passed from sv_readdb function call * @param columns: Columns passed from sv_readdb function call
* @param current: Current row being read into refine_info array * @param current: Current row being read into refine_info array
* @return True * @return True
**/ */
static bool status_readdb_refine(char* fields[], int columns, int current) static bool status_readdb_refine(char* fields[], int columns, int current)
{ {
int i, bonus_per_level, random_bonus, random_bonus_start_level; int i, bonus_per_level, random_bonus, random_bonus_start_level;
@ -12777,7 +12781,7 @@ static bool status_readdb_refine(char* fields[], int columns, int current)
* Read attribute fix database for attack calculations * Read attribute fix database for attack calculations
* Function stores information in the attr_fix_table * Function stores information in the attr_fix_table
* @return True * @return True
**/ */
static bool status_readdb_attrfix(const char *basedir,bool silent) static bool status_readdb_attrfix(const char *basedir,bool silent)
{ {
FILE *fp; FILE *fp;
@ -12837,7 +12841,7 @@ static bool status_readdb_attrfix(const char *basedir,bool silent)
* size_fix.txt: Size adjustment table for weapons * size_fix.txt: Size adjustment table for weapons
* refine_db.txt: Refining data table * refine_db.txt: Refining data table
* @return 0 * @return 0
**/ */
int status_readdb(void) int status_readdb(void)
{ {
int i, j, k; int i, j, k;
@ -12895,7 +12899,7 @@ int status_readdb(void)
/** /**
* Status db init and destroy. * Status db init and destroy.
**/ */
int do_init_status(void) int do_init_status(void)
{ {
add_timer_func_list(status_change_timer,"status_change_timer"); add_timer_func_list(status_change_timer,"status_change_timer");

View File

@ -41,8 +41,7 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
return; return;
} }
if (target_sd->npc_id) if (target_sd->npc_id) { // Trade fails if you are using an NPC.
{ //Trade fails if you are using an NPC.
clif_tradestart(sd, 2); clif_tradestart(sd, 2);
return; return;
} }
@ -56,6 +55,7 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
if ( sd->trade_partner != 0 ) { // If a character tries to trade to another one then cancel the previous one if ( sd->trade_partner != 0 ) { // If a character tries to trade to another one then cancel the previous one
struct map_session_data *previous_sd = map_id2sd(sd->trade_partner); struct map_session_data *previous_sd = map_id2sd(sd->trade_partner);
if( previous_sd ){ if( previous_sd ){
previous_sd->trade_partner = 0; previous_sd->trade_partner = 0;
clif_tradecancelled(previous_sd); clif_tradecancelled(previous_sd);
@ -69,8 +69,7 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
return; return;
} }
if (!pc_can_give_items(sd) || !pc_can_give_items(target_sd)) //check if both GMs are allowed to trade if (!pc_can_give_items(sd) || !pc_can_give_items(target_sd)) { // check if both GMs are allowed to trade
{
clif_displaymessage(sd->fd, msg_txt(sd,246)); clif_displaymessage(sd->fd, msg_txt(sd,246));
clif_tradestart(sd, 2); // GM is not allowed to trade clif_tradestart(sd, 2); // GM is not allowed to trade
return; return;
@ -104,19 +103,19 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
void trade_tradeack(struct map_session_data *sd, int type) void trade_tradeack(struct map_session_data *sd, int type)
{ {
struct map_session_data *tsd; struct map_session_data *tsd;
nullpo_retv(sd); nullpo_retv(sd);
if (sd->state.trading || !sd->trade_partner) if (sd->state.trading || !sd->trade_partner)
return; // Already trading or no partner set. return; // Already trading or no partner set.
if ((tsd = map_id2sd(sd->trade_partner)) == NULL) { if ((tsd = map_id2sd(sd->trade_partner)) == NULL) {
clif_tradestart(sd, 1); // character does not exist clif_tradestart(sd, 1); // Character does not exist
sd->trade_partner=0; sd->trade_partner=0;
return; return;
} }
if (tsd->state.trading || tsd->trade_partner != sd->bl.id) if (tsd->state.trading || tsd->trade_partner != sd->bl.id) {
{
clif_tradestart(sd, 2); clif_tradestart(sd, 2);
sd->trade_partner=0; sd->trade_partner=0;
return; // Already trading or wrong partner. return; // Already trading or wrong partner.
@ -147,8 +146,7 @@ void trade_tradeack(struct map_session_data *sd, int type)
// Check if you can start trade. // Check if you can start trade.
if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag || if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag ||
tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag) tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag) { // Fail
{ //Fail
clif_tradestart(sd, 2); clif_tradestart(sd, 2);
clif_tradestart(tsd, 2); clif_tradestart(tsd, 2);
sd->state.deal_locked = 0; sd->state.deal_locked = 0;
@ -183,8 +181,7 @@ int impossible_trade_check(struct map_session_data *sd)
nullpo_retr(1, sd); nullpo_retr(1, sd);
if(sd->deal.zeny > sd->status.zeny) if(sd->deal.zeny > sd->status.zeny) {
{
pc_setglobalreg(sd,"ZENY_HACKER",1); pc_setglobalreg(sd,"ZENY_HACKER",1);
return -1; return -1;
} }
@ -192,9 +189,9 @@ int impossible_trade_check(struct map_session_data *sd)
// get inventory of player // get inventory of player
memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY); memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
// remove this part: arrows can be trade and equiped // remove this part: arrows can be trade and equipped
// re-added! [celest] // re-added! [celest]
// remove equiped items (they can not be trade) // remove equipped items (they can not be trade)
for (i = 0; i < MAX_INVENTORY; i++) for (i = 0; i < MAX_INVENTORY; i++)
if (inventory[i].nameid > 0 && inventory[i].equip && !(inventory[i].equip & EQP_AMMO)) if (inventory[i].nameid > 0 && inventory[i].equip && !(inventory[i].equip & EQP_AMMO))
memset(&inventory[i], 0, sizeof(struct item)); memset(&inventory[i], 0, sizeof(struct item));
@ -203,9 +200,10 @@ int impossible_trade_check(struct map_session_data *sd)
for(i = 0; i < 10; i++) { for(i = 0; i < 10; i++) {
if (!sd->deal.item[i].amount) if (!sd->deal.item[i].amount)
continue; continue;
index = sd->deal.item[i].index; index = sd->deal.item[i].index;
if (inventory[index].amount < sd->deal.item[i].amount)
{ // if more than the player have -> hack if (inventory[index].amount < sd->deal.item[i].amount) { // if more than the player have -> hack
sprintf(message_to_gm, msg_txt(sd,538), sd->status.name, sd->status.account_id); // Hack on trade: character '%s' (account: %d) try to trade more items that he has. sprintf(message_to_gm, msg_txt(sd,538), sd->status.name, sd->status.account_id); // Hack on trade: character '%s' (account: %d) try to trade more items that he has.
intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm); intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
sprintf(message_to_gm, msg_txt(sd,539), inventory[index].amount, inventory[index].nameid, sd->deal.item[i].amount); // This player has %d of a kind of item (id: %d), and try to trade %d of them. sprintf(message_to_gm, msg_txt(sd,539), inventory[index].amount, inventory[index].nameid, sd->deal.item[i].amount); // This player has %d of a kind of item (id: %d), and try to trade %d of them.
@ -229,6 +227,7 @@ int impossible_trade_check(struct map_session_data *sd)
intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm); intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
return 1; return 1;
} }
inventory[index].amount -= sd->deal.item[i].amount; // remove item from inventory inventory[index].amount -= sd->deal.item[i].amount; // remove item from inventory
} }
return 0; return 0;
@ -247,7 +246,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
struct item_data *data; struct item_data *data;
int trade_i, i, n; int trade_i, i, n;
// check zenys value against hackers (Zeny was already checked on time of adding, but you never know when you lost some zeny since then. // check zeny value against hackers (Zeny was already checked on time of adding, but you never know when you lost some zeny since then.
if(sd->deal.zeny > sd->status.zeny || (tsd->status.zeny > MAX_ZENY - sd->deal.zeny)) if(sd->deal.zeny > sd->status.zeny || (tsd->status.zeny > MAX_ZENY - sd->deal.zeny))
return 0; return 0;
if(tsd->deal.zeny > tsd->status.zeny || (sd->status.zeny > MAX_ZENY - tsd->deal.zeny)) if(tsd->deal.zeny > tsd->status.zeny || (sd->status.zeny > MAX_ZENY - tsd->deal.zeny))
@ -262,10 +261,12 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
short amount; short amount;
amount = sd->deal.item[trade_i].amount; amount = sd->deal.item[trade_i].amount;
if (amount) { if (amount) {
n = sd->deal.item[trade_i].index; n = sd->deal.item[trade_i].index;
if (amount > inventory[n].amount) if (amount > inventory[n].amount)
return 0; //qty Exploit? return 0; // Quantity Exploit?
data = itemdb_search(inventory[n].nameid); data = itemdb_search(inventory[n].nameid);
i = MAX_INVENTORY; i = MAX_INVENTORY;
@ -276,6 +277,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
inventory2[i].card[2] == inventory[n].card[2] && inventory2[i].card[3] == inventory[n].card[3]) { inventory2[i].card[2] == inventory[n].card[2] && inventory2[i].card[3] == inventory[n].card[3]) {
if (inventory2[i].amount + amount > MAX_AMOUNT) if (inventory2[i].amount + amount > MAX_AMOUNT)
return 0; return 0;
inventory2[i].amount += amount; inventory2[i].amount += amount;
inventory[n].amount -= amount; inventory[n].amount -= amount;
break; break;
@ -286,20 +288,27 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
for(i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++); for(i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++);
if (i == MAX_INVENTORY) if (i == MAX_INVENTORY)
return 0; return 0;
memcpy(&inventory2[i], &inventory[n], sizeof(struct item)); memcpy(&inventory2[i], &inventory[n], sizeof(struct item));
inventory2[i].amount = amount; inventory2[i].amount = amount;
inventory[n].amount -= amount; inventory[n].amount -= amount;
} }
} }
amount = tsd->deal.item[trade_i].amount; amount = tsd->deal.item[trade_i].amount;
if (!amount) if (!amount)
continue; continue;
n = tsd->deal.item[trade_i].index; n = tsd->deal.item[trade_i].index;
if (amount > inventory2[n].amount) if (amount > inventory2[n].amount)
return 0; return 0;
// search if it's possible to add item (for full inventory) // search if it's possible to add item (for full inventory)
data = itemdb_search(inventory2[n].nameid); data = itemdb_search(inventory2[n].nameid);
i = MAX_INVENTORY; i = MAX_INVENTORY;
if (itemdb_isstackable2(data)) { if (itemdb_isstackable2(data)) {
for(i = 0; i < MAX_INVENTORY; i++) for(i = 0; i < MAX_INVENTORY; i++)
if (inventory[i].nameid == inventory2[n].nameid && if (inventory[i].nameid == inventory2[n].nameid &&
@ -307,15 +316,18 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
inventory[i].card[2] == inventory2[n].card[2] && inventory[i].card[3] == inventory2[n].card[3]) { inventory[i].card[2] == inventory2[n].card[2] && inventory[i].card[3] == inventory2[n].card[3]) {
if (inventory[i].amount + amount > MAX_AMOUNT) if (inventory[i].amount + amount > MAX_AMOUNT)
return 0; return 0;
inventory[i].amount += amount; inventory[i].amount += amount;
inventory2[n].amount -= amount; inventory2[n].amount -= amount;
break; break;
} }
} }
if (i == MAX_INVENTORY) { if (i == MAX_INVENTORY) {
for(i = 0; i < MAX_INVENTORY && inventory[i].nameid; i++); for(i = 0; i < MAX_INVENTORY && inventory[i].nameid; i++);
if (i == MAX_INVENTORY) if (i == MAX_INVENTORY)
return 0; return 0;
memcpy(&inventory[i], &inventory2[n], sizeof(struct item)); memcpy(&inventory[i], &inventory2[n], sizeof(struct item));
inventory[i].amount = amount; inventory[i].amount = amount;
inventory2[n].amount -= amount; inventory2[n].amount -= amount;
@ -339,17 +351,16 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
int src_lv, dst_lv; int src_lv, dst_lv;
nullpo_retv(sd); nullpo_retv(sd);
if( !sd->state.trading || sd->state.deal_locked > 0 ) if( !sd->state.trading || sd->state.deal_locked > 0 )
return; // Can't add stuff. return; // Can't add stuff.
if( (target_sd = map_id2sd(sd->trade_partner)) == NULL ) if( (target_sd = map_id2sd(sd->trade_partner)) == NULL ) {
{
trade_tradecancel(sd); trade_tradecancel(sd);
return; return;
} }
if( amount == 0 ) if( !amount ) { // Why do this.. ~.~ just send an ack, the item won't display on the trade window.
{ //Why do this.. ~.~ just send an ack, the item won't display on the trade window.
clif_tradeitemok(sd, index, 0); clif_tradeitemok(sd, index, 0);
return; return;
} }
@ -365,16 +376,15 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
item = &sd->status.inventory[index]; item = &sd->status.inventory[index];
src_lv = pc_get_group_level(sd); src_lv = pc_get_group_level(sd);
dst_lv = pc_get_group_level(target_sd); dst_lv = pc_get_group_level(target_sd);
if( !itemdb_cantrade(item, src_lv, dst_lv) && // Can't trade if( !itemdb_cantrade(item, src_lv, dst_lv) && // Can't trade
(pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) //Can't partner-trade (pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) { // Can't partner-trade
{
clif_displaymessage (sd->fd, msg_txt(sd,260)); clif_displaymessage (sd->fd, msg_txt(sd,260));
clif_tradeitemok(sd, index+2, 1); clif_tradeitemok(sd, index+2, 1);
return; return;
} }
if( item->expire_time ) if( item->expire_time ) { // Rental System
{ // Rental System
clif_displaymessage (sd->fd, msg_txt(sd,260)); clif_displaymessage (sd->fd, msg_txt(sd,260));
clif_tradeitemok(sd, index+2, 1); clif_tradeitemok(sd, index+2, 1);
return; return;
@ -388,33 +398,29 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
// Locate a trade position // Locate a trade position
ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 ); ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 );
if( trade_i == 10 ) //No space left if( trade_i == 10 ) { // No space left
{
clif_tradeitemok(sd, index+2, 1); clif_tradeitemok(sd, index+2, 1);
return; return;
} }
trade_weight = sd->inventory_data[index]->weight * amount; trade_weight = sd->inventory_data[index]->weight * amount;
if( target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight ) if( target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight ) { // fail to add item -- the player was over weighted.
{ //fail to add item -- the player was over weighted.
clif_tradeitemok(sd, index+2, 1); clif_tradeitemok(sd, index+2, 1);
return; return;
} }
if( sd->deal.item[trade_i].index == index ) if( sd->deal.item[trade_i].index == index ) { // The same item as before is being readjusted.
{ //The same item as before is being readjusted. if( sd->deal.item[trade_i].amount + amount > sd->status.inventory[index].amount ) { // packet deal exploit check
if( sd->deal.item[trade_i].amount + amount > sd->status.inventory[index].amount )
{ //packet deal exploit check
amount = sd->status.inventory[index].amount - sd->deal.item[trade_i].amount; amount = sd->status.inventory[index].amount - sd->deal.item[trade_i].amount;
trade_weight = sd->inventory_data[index]->weight * amount; trade_weight = sd->inventory_data[index]->weight * amount;
} }
sd->deal.item[trade_i].amount += amount; sd->deal.item[trade_i].amount += amount;
} } else { // New deal item
else
{ //New deal item
sd->deal.item[trade_i].index = index; sd->deal.item[trade_i].index = index;
sd->deal.item[trade_i].amount = amount; sd->deal.item[trade_i].amount = amount;
} }
sd->deal.weight += trade_weight; sd->deal.weight += trade_weight;
clif_tradeitemok(sd, index+2, 0); // Return the index as it was received clif_tradeitemok(sd, index+2, 0); // Return the index as it was received
@ -431,19 +437,18 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
void trade_tradeaddzeny(struct map_session_data* sd, int amount) void trade_tradeaddzeny(struct map_session_data* sd, int amount)
{ {
struct map_session_data* target_sd; struct map_session_data* target_sd;
nullpo_retv(sd); nullpo_retv(sd);
if( !sd->state.trading || sd->state.deal_locked > 0 ) if( !sd->state.trading || sd->state.deal_locked > 0 )
return; //Can't add stuff. return; //Can't add stuff.
if( (target_sd = map_id2sd(sd->trade_partner)) == NULL ) if( (target_sd = map_id2sd(sd->trade_partner)) == NULL ) {
{
trade_tradecancel(sd); trade_tradecancel(sd);
return; return;
} }
if( amount < 0 || amount > sd->status.zeny || amount > MAX_ZENY - target_sd->status.zeny ) if( amount < 0 || amount > sd->status.zeny || amount > MAX_ZENY - target_sd->status.zeny ) { // invalid values, no appropriate packet for it => abort
{ // invalid values, no appropriate packet for it => abort
trade_tradecancel(sd); trade_tradecancel(sd);
return; return;
} }
@ -467,6 +472,7 @@ void trade_tradeok(struct map_session_data *sd)
trade_tradecancel(sd); trade_tradecancel(sd);
return; return;
} }
sd->state.deal_locked = 1; sd->state.deal_locked = 1;
clif_tradeitemok(sd, 0, 0); clif_tradeitemok(sd, 0, 0);
clif_tradedeal_lock(sd, 0); clif_tradedeal_lock(sd, 0);
@ -484,8 +490,7 @@ void trade_tradecancel(struct map_session_data *sd)
target_sd = map_id2sd(sd->trade_partner); target_sd = map_id2sd(sd->trade_partner);
if(!sd->state.trading) if(!sd->state.trading) { // Not trade accepted
{ // Not trade acepted
if( target_sd ) { if( target_sd ) {
target_sd->trade_partner = 0; target_sd->trade_partner = 0;
clif_tradecancelled(target_sd); clif_tradecancelled(target_sd);
@ -498,10 +503,12 @@ void trade_tradecancel(struct map_session_data *sd)
for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual) for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
if (!sd->deal.item[trade_i].amount) if (!sd->deal.item[trade_i].amount)
continue; continue;
clif_additem(sd, sd->deal.item[trade_i].index, sd->deal.item[trade_i].amount, 0); clif_additem(sd, sd->deal.item[trade_i].index, sd->deal.item[trade_i].amount, 0);
sd->deal.item[trade_i].index = 0; sd->deal.item[trade_i].index = 0;
sd->deal.item[trade_i].amount = 0; sd->deal.item[trade_i].amount = 0;
} }
if (sd->deal.zeny) { if (sd->deal.zeny) {
clif_updatestatus(sd, SP_ZENY); clif_updatestatus(sd, SP_ZENY);
sd->deal.zeny = 0; sd->deal.zeny = 0;
@ -527,6 +534,7 @@ void trade_tradecancel(struct map_session_data *sd)
clif_updatestatus(target_sd, SP_ZENY); clif_updatestatus(target_sd, SP_ZENY);
target_sd->deal.zeny = 0; target_sd->deal.zeny = 0;
} }
target_sd->state.deal_locked = 0; target_sd->state.deal_locked = 0;
target_sd->trade_partner = 0; target_sd->trade_partner = 0;
target_sd->state.trading = 0; target_sd->state.trading = 0;
@ -562,11 +570,13 @@ void trade_tradecommit(struct map_session_data *sd)
trade_tradecancel(sd); trade_tradecancel(sd);
return; return;
} }
// check exploit (trade more items that you have) // check exploit (trade more items that you have)
if (impossible_trade_check(tsd)) { if (impossible_trade_check(tsd)) {
trade_tradecancel(tsd); trade_tradecancel(tsd);
return; return;
} }
// check for full inventory (can not add traded items) // check for full inventory (can not add traded items)
if (!trade_check(sd,tsd)) { // check the both players if (!trade_check(sd,tsd)) { // check the both players
trade_tradecancel(sd); trade_tradecancel(sd);
@ -574,12 +584,11 @@ void trade_tradecommit(struct map_session_data *sd)
} }
// trade is accepted and correct. // trade is accepted and correct.
for( trade_i = 0; trade_i < 10; trade_i++ ) for( trade_i = 0; trade_i < 10; trade_i++ ) {
{
int n; int n;
unsigned char flag = 0; unsigned char flag = 0;
if (sd->deal.item[trade_i].amount)
{ if (sd->deal.item[trade_i].amount) {
n = sd->deal.item[trade_i].index; n = sd->deal.item[trade_i].index;
flag = pc_additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE); flag = pc_additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
@ -590,8 +599,8 @@ void trade_tradecommit(struct map_session_data *sd)
sd->deal.item[trade_i].index = 0; sd->deal.item[trade_i].index = 0;
sd->deal.item[trade_i].amount = 0; sd->deal.item[trade_i].amount = 0;
} }
if (tsd->deal.item[trade_i].amount)
{ if (tsd->deal.item[trade_i].amount) {
n = tsd->deal.item[trade_i].index; n = tsd->deal.item[trade_i].index;
flag = pc_additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE); flag = pc_additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
@ -610,6 +619,7 @@ void trade_tradecommit(struct map_session_data *sd)
sd->deal.zeny = 0; sd->deal.zeny = 0;
} }
if ( tsd->deal.zeny) { if ( tsd->deal.zeny) {
pc_payzeny(tsd,tsd->deal.zeny,LOG_TYPE_TRADE, sd); pc_payzeny(tsd,tsd->deal.zeny,LOG_TYPE_TRADE, sd);
pc_getzeny(sd ,tsd->deal.zeny,LOG_TYPE_TRADE, tsd); pc_getzeny(sd ,tsd->deal.zeny,LOG_TYPE_TRADE, tsd);
@ -628,8 +638,7 @@ void trade_tradecommit(struct map_session_data *sd)
clif_tradecompleted(tsd, 0); clif_tradecompleted(tsd, 0);
// save both player to avoid crash: they always have no advantage/disadvantage between the 2 players // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
if (save_settings&1) if (save_settings&1) {
{
chrif_save(sd,0); chrif_save(sd,0);
chrif_save(tsd,0); chrif_save(tsd,0);
} }

View File

@ -53,6 +53,7 @@ const short diry[8]={1,1,0,-1,-1,-1,0,1}; ///lookup to know where will move to y
static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data); static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data);
static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data); static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data);
int unit_unattackable(struct block_list *bl); int unit_unattackable(struct block_list *bl);
/** /**
* Get the unit_data related to the bl * Get the unit_data related to the bl
* @param bl : Object to get the unit_data from * @param bl : Object to get the unit_data from
@ -131,7 +132,6 @@ int unit_walktoxy_sub(struct block_list *bl)
return 1; return 1;
} }
/** /**
* Retrieve the direct master of a bl if one exists. * Retrieve the direct master of a bl if one exists.
* @param bl: char to get his master [HOM|ELEM|PET|MER] * @param bl: char to get his master [HOM|ELEM|PET|MER]
@ -189,8 +189,7 @@ int unit_teleport_timer(int tid, unsigned int tick, int id, intptr_t data)
if(msd && !check_distance_bl(&msd->bl, bl, data)) { if(msd && !check_distance_bl(&msd->bl, bl, data)) {
*mast_tid = INVALID_TIMER; *mast_tid = INVALID_TIMER;
unit_warp(bl, msd->bl.m, msd->bl.x, msd->bl.y, CLR_TELEPORT ); unit_warp(bl, msd->bl.m, msd->bl.x, msd->bl.y, CLR_TELEPORT );
} } else // No timer needed
else // No timer needed
*mast_tid = INVALID_TIMER; *mast_tid = INVALID_TIMER;
} }
return 0; return 0;
@ -227,6 +226,7 @@ int unit_check_start_teleport_timer(struct block_list *sbl)
// If there is a master and it's a valid type // If there is a master and it's a valid type
if(msd && max_dist) { if(msd && max_dist) {
int *msd_tid = unit_get_masterteleport_timer(sbl); int *msd_tid = unit_get_masterteleport_timer(sbl);
if(msd_tid == NULL) return 0; if(msd_tid == NULL) return 0;
if (!check_distance_bl(&msd->bl, sbl, max_dist)) { if (!check_distance_bl(&msd->bl, sbl, max_dist)) {
if(*msd_tid == INVALID_TIMER || *msd_tid == 0) if(*msd_tid == INVALID_TIMER || *msd_tid == 0)
@ -704,7 +704,7 @@ int unit_run(struct block_list *bl)
} }
/** /**
* Char movement with wugdash * Character movement with Warg Dash
* @author [Jobbie/3CeAM] * @author [Jobbie/3CeAM]
* @param bl: Object that is dashing * @param bl: Object that is dashing
* @param sd: Player * @param sd: Player
@ -1276,6 +1276,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
int combo = 0, range; int combo = 0, range;
nullpo_ret(src); nullpo_ret(src);
if(status_isdead(src)) if(status_isdead(src))
return 0; // Do not continue source is dead return 0; // Do not continue source is dead
@ -1481,14 +1482,14 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
ud->state.skillcastcancel = castcancel; ud->state.skillcastcancel = castcancel;
// temp: Used to signal force cast now. // Combo: Used to signal force cast now.
combo = 0; combo = 0;
switch(skill_id) { switch(skill_id) {
case ALL_RESURRECTION: case ALL_RESURRECTION:
if(battle_check_undead(tstatus->race,tstatus->def_ele)) { if(battle_check_undead(tstatus->race,tstatus->def_ele))
combo = 1; combo = 1;
} else if (!status_isdead(target)) else if (!status_isdead(target))
return 0; // Can't cast on non-dead characters. return 0; // Can't cast on non-dead characters.
break; break;
case MO_FINGEROFFENSIVE: case MO_FINGEROFFENSIVE:
@ -1703,7 +1704,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
/** /**
* Pneuma cannot be cancelled past this point, the client displays the animation even, * Pneuma cannot be cancelled past this point, the client displays the animation even,
* if we cancel it from nodamage_id, so it has to be here for it to not display the animation. * if we cancel it from nodamage_id, so it has to be here for it to not display the animation.
**/ */
if( skill_id == AL_PNEUMA && map_getcell(src->m, skill_x, skill_y, CELL_CHKLANDPROTECTOR) ) { if( skill_id == AL_PNEUMA && map_getcell(src->m, skill_x, skill_y, CELL_CHKLANDPROTECTOR) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0; return 0;
@ -2197,7 +2198,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
/** /**
* Applied when you're unable to attack (e.g. out of ammo) * Applied when you're unable to attack (e.g. out of ammo)
* We should stop here otherwise timer keeps on and this happens endlessly * We should stop here otherwise timer keeps on and this happens endlessly
**/ */
if( ud->attacktarget_lv == ATK_NONE ) if( ud->attacktarget_lv == ATK_NONE )
return 1; return 1;

View File

@ -58,7 +58,8 @@ static void do_final_vending_autotrade(void);
* Lookup to get the vending_db outside module * Lookup to get the vending_db outside module
* @return the vending_db * @return the vending_db
*/ */
DBMap * vending_getdb(){ DBMap * vending_getdb()
{
return vending_db; return vending_db;
} }
@ -66,7 +67,8 @@ DBMap * vending_getdb(){
* Create an unique vending shop id. * Create an unique vending shop id.
* @return the next vending_id * @return the next vending_id
*/ */
static int vending_getuid(void){ static int vending_getuid(void)
{
return ++vending_nextid; return ++vending_nextid;
} }
@ -106,8 +108,7 @@ void vending_vendinglistreq(struct map_session_data* sd, int id)
if( !vsd->state.vending ) if( !vsd->state.vending )
return; // not vending return; // not vending
if (!pc_can_give_items(sd) || !pc_can_give_items(vsd)) //check if both GMs are allowed to trade if (!pc_can_give_items(sd) || !pc_can_give_items(vsd)) { //check if both GMs are allowed to trade
{ // GM is not allowed to trade
clif_displaymessage(sd->fd, msg_txt(sd,246)); clif_displaymessage(sd->fd, msg_txt(sd,246));
return; return;
} }
@ -177,13 +178,11 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
vend_list[i] = j; vend_list[i] = j;
z += ((double)vsd->vending[j].value * (double)amount); z += ((double)vsd->vending[j].value * (double)amount);
if( z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY ) if( z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY ) {
{
clif_buyvending(sd, idx, amount, 1); // you don't have enough zeny clif_buyvending(sd, idx, amount, 1); // you don't have enough zeny
return; return;
} }
if( z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle_config.vending_over_max ) if( z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle_config.vending_over_max ) {
{
clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow
return; return;
@ -200,8 +199,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
// if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples). // if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples).
// here, we check cumulative amounts // here, we check cumulative amounts
if( vending[j].amount < amount ) if( vending[j].amount < amount ) {
{
// send more quantity is not a hack (an other player can have buy items just before) // send more quantity is not a hack (an other player can have buy items just before)
clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // not enough quantity clif_buyvending(sd, idx, vsd->vending[j].amount, 4); // not enough quantity
return; return;
@ -270,6 +268,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
cursor++; cursor++;
} }
vsd->vend_num = cursor; vsd->vend_num = cursor;
//Always save BOTH: customer (buyer) and vender //Always save BOTH: customer (buyer) and vender
@ -299,7 +298,8 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
* @param count : number of different items * @param count : number of different items
* @return 0 If success, 1 - Cannot open (die, not state.prevend, trading), 2 - No cart, 3 - Count issue, 4 - Cart data isn't saved yet, 5 - No valid item found * @return 0 If success, 1 - Cannot open (die, not state.prevend, trading), 2 - No cart, 3 - Count issue, 4 - Cart data isn't saved yet, 5 - No valid item found
*/ */
char vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) { char vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count)
{
int i, j; int i, j;
int vending_skill_lvl; int vending_skill_lvl;
char message_sql[MESSAGE_SIZE*2]; char message_sql[MESSAGE_SIZE*2];
@ -319,8 +319,7 @@ char vending_openvending(struct map_session_data* sd, const char* message, const
} }
// check number of items in shop // check number of items in shop
if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) { // invalid item count
{ // invalid item count
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
return 3; return 3;
} }
@ -372,6 +371,7 @@ char vending_openvending(struct map_session_data* sd, const char* message, const
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
return 5; return 5;
} }
sd->state.prevend = 0; sd->state.prevend = 0;
sd->state.vending = true; sd->state.vending = true;
sd->vender_id = vending_getuid(); sd->vender_id = vending_getuid();
@ -406,7 +406,8 @@ char vending_openvending(struct map_session_data* sd, const char* message, const
* @param nameid : item id * @param nameid : item id
* @return 0:not selling it, 1: yes * @return 0:not selling it, 1: yes
*/ */
bool vending_search(struct map_session_data* sd, unsigned short nameid) { bool vending_search(struct map_session_data* sd, unsigned short nameid)
{
int i; int i;
if( !sd->state.vending ) { // not vending if( !sd->state.vending ) { // not vending
@ -421,15 +422,14 @@ bool vending_search(struct map_session_data* sd, unsigned short nameid) {
return true; return true;
} }
/** /**
* Searches for all items in a vending, that match given ids, price and possible cards. * Searches for all items in a vending, that match given ids, price and possible cards.
* @param sd : The vender session to search into * @param sd : The vender session to search into
* @param s : parameter of the search (see s_search_store_search) * @param s : parameter of the search (see s_search_store_search)
* @return Whether or not the search should be continued. * @return Whether or not the search should be continued.
*/ */
bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s) { bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s)
{
int i, c, slot; int i, c, slot;
unsigned int idx, cidx; unsigned int idx, cidx;
struct item* it; struct item* it;
@ -460,8 +460,7 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
for( c = 0; c < slot && it->card[c]; c ++ ) { for( c = 0; c < slot && it->card[c]; c ++ ) {
ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx] == it->card[c] ); ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx] == it->card[c] );
if( cidx != s->card_count ) if( cidx != s->card_count ) { // found
{// found
break; break;
} }
} }
@ -471,8 +470,7 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
} }
} }
if( !searchstore_result(s->search_sd, sd->vender_id, sd->status.account_id, sd->message, it->nameid, sd->vending[i].amount, sd->vending[i].value, it->card, it->refine) ) if( !searchstore_result(s->search_sd, sd->vender_id, sd->status.account_id, sd->message, it->nameid, sd->vending[i].amount, sd->vending[i].value, it->card, it->refine) ) { // result set full
{// result set full
return false; return false;
} }
} }
@ -484,7 +482,8 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
* Open vending for Autotrader * Open vending for Autotrader
* @param sd Player as autotrader * @param sd Player as autotrader
*/ */
void vending_reopen( struct map_session_data* sd ){ void vending_reopen( struct map_session_data* sd )
{
nullpo_retv(sd); nullpo_retv(sd);
// Ready to open vending for this char // Ready to open vending for this char
@ -534,8 +533,7 @@ void vending_reopen( struct map_session_data* sd ){
// Set him to autotrade // Set him to autotrade
if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1, `body_direction` = '%d', `head_direction` = '%d', `sit` = '%d' " if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1, `body_direction` = '%d', `head_direction` = '%d', `sit` = '%d' "
"WHERE `id` = %d;", "WHERE `id` = %d;",
vendings_db, autotraders[i]->dir, autotraders[i]->head_dir, autotraders[i]->sit, sd->vender_id ) != SQL_SUCCESS ) vendings_db, autotraders[i]->dir, autotraders[i]->head_dir, autotraders[i]->sit, sd->vender_id ) != SQL_SUCCESS ) {
{
Sql_ShowDebug( mmysql_handle ); Sql_ShowDebug( mmysql_handle );
} }
@ -571,7 +569,8 @@ void vending_reopen( struct map_session_data* sd ){
/** /**
* Initializing autotraders from table * Initializing autotraders from table
*/ */
void do_init_vending_autotrade( void ) { void do_init_vending_autotrade(void)
{
if (battle_config.feature_autotrade) { if (battle_config.feature_autotrade) {
uint16 i, items = 0; uint16 i, items = 0;
autotrader_count = autotrader_loaded_count = 0; autotrader_count = autotrader_loaded_count = 0;
@ -583,8 +582,7 @@ void do_init_vending_autotrade( void ) {
"FROM `%s` " "FROM `%s` "
"WHERE `autotrade` = 1 AND (SELECT COUNT(`vending_id`) FROM `%s` WHERE `vending_id` = `id`) > 0 " "WHERE `autotrade` = 1 AND (SELECT COUNT(`vending_id`) FROM `%s` WHERE `vending_id` = `id`) > 0 "
"ORDER BY `id`;", "ORDER BY `id`;",
vendings_db, vending_items_db ) != SQL_SUCCESS ) vendings_db, vending_items_db ) != SQL_SUCCESS ) {
{
Sql_ShowDebug(mmysql_handle); Sql_ShowDebug(mmysql_handle);
return; return;
} }
@ -649,8 +647,7 @@ void do_init_vending_autotrade( void ) {
"FROM `%s` " "FROM `%s` "
"WHERE `vending_id` = %d " "WHERE `vending_id` = %d "
"ORDER BY `index` ASC;", "ORDER BY `index` ASC;",
vending_items_db, at->vendor_id ) ) vending_items_db, at->vendor_id ) ) {
{
Sql_ShowDebug(mmysql_handle); Sql_ShowDebug(mmysql_handle);
continue; continue;
} }
@ -684,8 +681,7 @@ void do_init_vending_autotrade( void ) {
// Everything is loaded fine, their entries will be reinserted once they are loaded // Everything is loaded fine, their entries will be reinserted once they are loaded
if (Sql_Query( mmysql_handle, "DELETE FROM `%s`;", vendings_db ) != SQL_SUCCESS || if (Sql_Query( mmysql_handle, "DELETE FROM `%s`;", vendings_db ) != SQL_SUCCESS ||
Sql_Query( mmysql_handle, "DELETE FROM `%s`;", vending_items_db ) != SQL_SUCCESS) Sql_Query( mmysql_handle, "DELETE FROM `%s`;", vending_items_db ) != SQL_SUCCESS) {
{
Sql_ShowDebug(mmysql_handle); Sql_ShowDebug(mmysql_handle);
} }
} }
@ -694,7 +690,8 @@ void do_init_vending_autotrade( void ) {
* Clear all autotraders * Clear all autotraders
* @author [Cydh] * @author [Cydh]
*/ */
void do_final_vending_autotrade(void) { void do_final_vending_autotrade(void)
{
if (autotrader_count && autotraders) { if (autotrader_count && autotraders) {
uint16 i = 0; uint16 i = 0;
while (i < autotrader_count) { //Free the autotrader while (i < autotrader_count) { //Free the autotrader
@ -723,7 +720,8 @@ void do_final_vending_autotrade(void) {
* Initialise the vending module * Initialise the vending module
* called in map::do_init * called in map::do_init
*/ */
void do_final_vending(void) { void do_final_vending(void)
{
db_destroy(vending_db); db_destroy(vending_db);
do_final_vending_autotrade(); //Make sure everything is cleared [Cydh] do_final_vending_autotrade(); //Make sure everything is cleared [Cydh]
} }
@ -732,7 +730,8 @@ void do_final_vending(void) {
* Destory the vending module * Destory the vending module
* called in map::do_final * called in map::do_final
*/ */
void do_init_vending(void) { void do_init_vending(void)
{
vending_db = idb_alloc(DB_OPT_BASE); vending_db = idb_alloc(DB_OPT_BASE);
vending_nextid = 0; vending_nextid = 0;
} }