Bug Fixes

* Fixes #479 - Fixed the unique item ID system not giving new items their unique ID. Blame 7295bdc.
* Fixes #488 - Fixed Water Barrier, Zephyr, and Power of Gaia not being applied to targets walking into the area of effect.
* Fixes #500 - Cursed Circle will now properly release targets if the caster moves out of AREA_SIZE.
* Fixes #501 - Reverberation can be placed an unlimited amount of times. The magic part now only deals neutral damage.
* Fixes #506 - Magnetic Field will now affect others in PvP maps, except for the caster. Thanks to @exneval.
* Fixes #527 - The Roulette item database will not be loaded at all if the feature is disabled.
* Fixed a small typo for 'unitwalk' and 'unitwalkto' script commands.
This commit is contained in:
aleos89 2015-07-22 17:46:38 -04:00
parent 89c9b7b92c
commit 51f6465709
10 changed files with 116 additions and 65 deletions

View File

@ -1140,9 +1140,9 @@
// WM Wanderer/Minstrel
2412,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0x0, WM_LESSON,Lesson
2413,9,8,1,-1,0,0,5,-2:-2:-3:-3:-4,yes,0,0,0,magic,0,0x0, WM_METALICSOUND,Metallic Sound
2414,9,6,2,-1,0x3,1,5,1,yes,0,0x80,3,none,0,0x0, WM_REVERBERATION,Reverberation
2414,9,6,2,-1,0x3,1,5,1,yes,0,0x80,0,none,0,0x0, WM_REVERBERATION,Reverberation
2415,0,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, WM_REVERBERATION_MELEE,Reverberation Melee
2416,0,6,1,-1,0,0,5,1,no,0,0,0,magic,0,0x0, WM_REVERBERATION_MAGIC,Reverberation Magic
2416,0,6,1,0,0,0,5,1,no,0,0,0,magic,0,0x0, WM_REVERBERATION_MAGIC,Reverberation Magic
2417,11,6,2,0,0x3,5,1,1,no,0,0,0,none,0,0x0, WM_DOMINION_IMPULSE,Dominion Impulse
2418,9,6,2,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, WM_SEVERE_RAINSTORM,Severe Rainstorm
2419,9,6,2,0,0x3,1,5,1,yes,0,0x80,5,none,0,0x0, WM_POEMOFNETHERWORLD,Poem of The Netherworld

View File

@ -185,9 +185,9 @@
8212,0x97, , 0, 1,1000,enemy, 0x006 //MA_FREEZINGTRAP
8403,0xed, , -1, 1,1000,enemy, 0x018 //EL_FIRE_MANTLE
8406,0xee, , 0, 1, -1,friend,0x018 //EL_WATER_BARRIER
8409,0xef, , 0, 1,1000,friend,0x018 //EL_ZEPHYR
8412,0xf0, , 0, 1, -1,friend,0x018 //EL_POWER_OF_GAIA
8406,0xee, , 1, 0, -1,friend,0x2018 //EL_WATER_BARRIER
8409,0xef, , 1, 0, -1,friend,0x2018 //EL_ZEPHYR
8412,0xf0, , 1, 0, -1,friend,0x2018 //EL_POWER_OF_GAIA
10006,0xc1, , 2, 0, -1,guild, 0x040 //GD_LEADERSHIP
10007,0xc2, , 2, 0, -1,guild, 0x040 //GD_GLORYWOUNDS

View File

@ -1140,9 +1140,9 @@
// WM Wanderer/Minstrel
2412,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0x0, WM_LESSON,Lesson
2413,9,8,1,-1,0,0,5,-2:-2:-3:-3:-4,yes,0,0,0,magic,0,0x0, WM_METALICSOUND,Metallic Sound
2414,9,6,2,-1,0x3,1,5,1,yes,0,0x80,3,none,0,0x0, WM_REVERBERATION,Reverberation
2414,9,6,2,-1,0x3,1,5,1,yes,0,0x80,0,none,0,0x0, WM_REVERBERATION,Reverberation
2415,0,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, WM_REVERBERATION_MELEE,Reverberation Melee
2416,0,6,1,-1,0,0,5,1,no,0,0,0,magic,0,0x0, WM_REVERBERATION_MAGIC,Reverberation Magic
2416,0,6,1,0,0,0,5,1,no,0,0,0,magic,0,0x0, WM_REVERBERATION_MAGIC,Reverberation Magic
2417,11,6,2,0,0x3,5,1,1,no,0,0,0,none,0,0x0, WM_DOMINION_IMPULSE,Dominion Impulse
2418,9,6,2,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, WM_SEVERE_RAINSTORM,Severe Rainstorm
2419,9,6,2,0,0x3,1,5,1,yes,0,0x80,5,none,0,0x0, WM_POEMOFNETHERWORLD,Poem of The Netherworld

View File

@ -187,9 +187,9 @@
8212,0x97, , 0, 1,1000,enemy, 0x8006 //MA_FREEZINGTRAP
8403,0xed, , -1, 1,1000,enemy, 0x018 //EL_FIRE_MANTLE
8406,0xee, , 0, 1, -1,friend,0x018 //EL_WATER_BARRIER
8409,0xef, , 0, 1,1000,friend,0x018 //EL_ZEPHYR
8412,0xf0, , 0, 1, -1,friend,0x018 //EL_POWER_OF_GAIA
8406,0xee, , 1, 0, -1,friend,0x2018 //EL_WATER_BARRIER
8409,0xef, , 1, 0, -1,friend,0x2018 //EL_ZEPHYR
8412,0xf0, , 1, 0, -1,friend,0x2018 //EL_POWER_OF_GAIA
10006,0xc1, , 2, 0, -1,guild, 0x040 //GD_LEADERSHIP
10007,0xc2, , 2, 0, -1,guild, 0x040 //GD_GLORYWOUNDS

View File

@ -1688,14 +1688,15 @@ void itemdb_reload(void) {
itemdb_group->clear(itemdb_group, itemdb_group_free);
itemdb->clear(itemdb, itemdb_final_sub);
db_clear(itemdb_combo);
if (battle_config.feature_roulette)
itemdb_roulette_free();
// read new data
itemdb_read();
cashshop_reloaddb();
if (!itemdb_parse_roulette_db())
battle_config.feature_roulette = 0;
if (battle_config.feature_roulette)
itemdb_parse_roulette_db();
//Epoque's awesome @reloaditemdb fix - thanks! [Ind]
//- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data
@ -1756,6 +1757,7 @@ void do_final_itemdb(void) {
itemdb_group->destroy(itemdb_group, itemdb_group_free);
itemdb->destroy(itemdb, itemdb_final_sub);
destroy_item_data(dummy_item);
if (battle_config.feature_roulette)
itemdb_roulette_free();
}
@ -1769,6 +1771,6 @@ void do_init_itemdb(void) {
itemdb_create_dummy();
itemdb_read();
if (!itemdb_parse_roulette_db())
battle_config.feature_roulette = 0;
if (battle_config.feature_roulette)
itemdb_parse_roulette_db();
}

View File

@ -4328,9 +4328,7 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p
if( sd->status.inventory[i].nameid == item->nameid &&
sd->status.inventory[i].bound == item->bound &&
sd->status.inventory[i].expire_time == 0 &&
#ifdef ENABLE_ITEM_GUID
sd->status.inventory[i].unique_id == item->unique_id &&
#endif
memcmp(&sd->status.inventory[i].card, &item->card, sizeof(item->card)) == 0
)
{
@ -4343,8 +4341,7 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p
}
}
if( i >= MAX_INVENTORY )
{
if (i >= MAX_INVENTORY) {
i = pc_search_inventory(sd,0);
if( i < 0 )
return ADDITEM_OVERITEM;
@ -4361,8 +4358,10 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p
sd->last_addeditem_index = i;
clif_additem(sd,i,amount,0);
}
if( !itemdb_isstackable2(id) && !item->unique_id )
item->unique_id = pc_generate_unique_id(sd);
if (!itemdb_isstackable2(id) && !item->unique_id)
sd->status.inventory[i].unique_id = pc_generate_unique_id(sd);
log_pick_pc(sd, log_type, amount, &sd->status.inventory[i]);
sd->weight += w;
@ -4896,9 +4895,7 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int
for (i = 0; i < MAX_CART; i++) {
if (sd->status.cart[i].nameid == item->nameid
&& sd->status.cart[i].bound == item->bound
#ifdef ENABLE_ITEM_GUID
&& sd->status.cart[i].unique_id == item->unique_id
#endif
&& memcmp(sd->status.cart[i].card, item->card, sizeof(item->card)) == 0
)
break;

View File

@ -17102,7 +17102,7 @@ BUILDIN_FUNC(unitwalk)
ud = unit_bl2ud(bl);
if (strcmp(cmd,"unitwalk")) {
if (!strcmp(cmd,"unitwalk")) {
int x = script_getnum(st,3);
int y = script_getnum(st,4);
@ -17117,7 +17117,7 @@ BUILDIN_FUNC(unitwalk)
return SCRIPT_CMD_FAILURE;
} else if (script_pushint(st, unit_can_reach_bl(bl, tbl, distance_bl(bl, tbl)+1, 0, NULL, NULL)))
add_timer(gettick()+50, unit_delay_walktobl_timer, bl->id, tbl->id); // Need timer to avoid mismatches
off = 3;
off = 4;
}
if (ud && script_hasdata(st, off)) {
@ -17247,7 +17247,6 @@ BUILDIN_FUNC(unitstopattack)
struct block_list* bl;
unit_id = script_getnum(st,2);
bl = map_id2bl(unit_id);
if (bl != NULL) {
@ -17268,14 +17267,10 @@ BUILDIN_FUNC(unitstopwalk)
struct block_list* bl;
unit_id = script_getnum(st,2);
bl = map_id2bl(unit_id);
if (bl != NULL) {
unit_stop_walking(bl,4);
if (bl->type == BL_MOB)
((TBL_MOB*)bl)->target_id = 0;
}
if (bl != NULL)
unit_stop_walking(bl, 0);
return SCRIPT_CMD_SUCCESS;
}
@ -20741,7 +20736,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(setunitname,"is"),
BUILDIN_DEF(getunitdata,"i*"),
BUILDIN_DEF(setunitdata,"iii"),
BUILDIN_DEF(unitwalk,"ii??"),
BUILDIN_DEF(unitwalk,"iii?"),
BUILDIN_DEF2(unitwalk,"unitwalkto","ii?"),
BUILDIN_DEF(unitkill,"i"),
BUILDIN_DEF(unitwarp,"isii"),

View File

@ -5221,7 +5221,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case NC_MAGNETICFIELD:
if( flag&1 && !map[src->m].flag.pvp ) // Doesn't affect enemies on PvP maps
sc_start2(src,bl,SC_MAGNETICFIELD,100,skill_lv,src->id,skill_get_time(skill_id,skill_lv));
break;
case SC_FATALMENACE:
@ -9176,13 +9175,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case NC_MAGNETICFIELD:
if( (i = sc_start2(src,bl,type,100,skill_lv,src->id,skill_get_time(skill_id,skill_lv))) )
{
map_foreachinrange(skill_area_sub,src,skill_get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill_castend_damage_id);
clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
if (sd) pc_overheat(sd,1);
}
clif_skill_nodamage(src,src,skill_id,skill_lv,i);
clif_skill_damage(src,bl,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,DMG_SKILL);
if (map_flag_vs(src->m)) // Doesn't affect the caster in non-PVP maps [exneval]
sc_start2(src,bl,type,100,skill_lv,src->id,skill_get_time(skill_id,skill_lv));
map_foreachinrange(skill_area_sub,bl,skill_get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill_castend_damage_id);
if (sd)
pc_overheat(sd,1);
break;
case NC_REPAIR:
@ -9453,7 +9451,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sc_start2(src,bl, type, 100, skill_lv, src->id, skill_get_time(skill_id, skill_lv))) {
if( bl->type == BL_MOB )
mob_unlocktarget((TBL_MOB*)bl,gettick());
unit_stop_attack(bl);
clif_bladestop(src, bl->id, 1);
map_freeblock_unlock();
return 1;
@ -10052,7 +10049,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case EL_WATER_BARRIER:
case EL_ZEPHYR:
case EL_POWER_OF_GAIA:
clif_skill_nodamage(src,src,skill_id,skill_lv,1);
clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
skill_unitsetting(src,skill_id,skill_lv,bl->x,bl->y,0);
break;
@ -10420,9 +10416,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
return 1;
}
if(skill_id != SR_CURSEDCIRCLE){
if (skill_id != SR_CURSEDCIRCLE) {
struct status_change *sc = status_get_sc(src);
if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] )//Should only remove after the skill had been casted.
if (sc && sc->data[SC_CURSEDCIRCLE_ATKER]) // Should only remove after the skill had been casted.
status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
}
@ -12687,6 +12684,15 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, un
sc_start(ss, bl,type,100,sg->skill_lv,sg->limit);
break;
case UNT_WATER_BARRIER:
case UNT_ZEPHYR:
case UNT_POWER_OF_GAIA:
if (bl->id == ss->id)
break; // Doesn't affect the Elemental
if (!sce)
sc_start(ss, bl, type, 100, sg->skill_lv, sg->limit);
break;
case UNT_SUITON:
if(!sce)
sc_start4(ss, bl,type,100,sg->skill_lv,
@ -14738,6 +14744,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
if (map_foreachinrange(mob_count_sub, &sd->bl, skill_get_splash(skill_id, skill_lv), BL_MOB,
MOBID_EMPERIUM, MOBID_GUARDIAN_STONE1, MOBID_GUARDIAN_STONE2)) {
char output[128];
sprintf(output,"%s",msg_txt(sd,382)); // You're too close to a stone or emperium to use this skill.
clif_colormes(sd->fd,color_table[COLOR_RED], output);
return false;

View File

@ -11232,7 +11232,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_CURSEDCIRCLE_ATKER:
if( sce->val2 ) // Used the default area size cause there is a chance the caster could knock back and can't clear the target.
map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
map_foreachinrange(status_change_timer_sub, bl, AREA_SIZE + 3, BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
break;
case SC_RAISINGDRAGON:
if( sd && sce->val2 && !pc_isdead(sd) ) {
@ -11249,9 +11249,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
{
struct block_list *src = map_id2bl(sce->val2);
struct status_change *sc2 = status_get_sc(src);
if( sc2 && sc2->data[SC_CURSEDCIRCLE_ATKER] && --(sc2->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ) {
status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
clif_bladestop(bl, sce->val2, 0);
status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
}
}
break;

View File

@ -1359,8 +1359,8 @@ enum si_type {
SI_SET_NUM_MDEF = 639,
SI_SET_PER_DEF = 640,
SI_SET_PER_MDEF = 641,
SI_PARTYBOOKING_SEARCH_DEALY = 642,
SI_PARTYBOOKING_REGISTER_DEALY = 643,
SI_PARTYBOOKING_SEARCH_DELAY = 642,
SI_PARTYBOOKING_REGISTER_DELAY = 643,
SI_PERIOD_TIME_CHECK_DETECT_SKILL = 644,
SI_KO_JYUMONJIKIRI = 645,
SI_MEIKYOUSISUI = 646,
@ -1576,10 +1576,58 @@ enum si_type {
SI_DRESS_UP = 856,
SI_MAPLE_FALLS = 857,
SI_ALL_NIFLHEIM_RECALL = 858,
SI_MTF_MARIONETTE = 860,
SI_MTF_LUDE = 861,
SI_MTF_CRUISER = 862,
SI_DRACULA_CARD = 865,
SI_LIMIT_POWER_BOOSTER = 867,
SI_TIME_ACCESSORY = 872,
SI_EP16_DEF = 873,
SI_BODYSTATE_STONECURSE = 875,
SI_BODYSTATE_FREEZING = 876,
SI_BODYSTATE_STUN = 877,
SI_BODYSTATE_SLEEP = 878,
SI_BODYSTATE_UNDEAD = 879,
SI_BODYSTATE_STONECURSE_ING = 880,
SI_BODYSTATE_BURNNING = 881,
SI_BODYSTATE_IMPRISON = 882,
SI_HEALTHSTATE_POISON = 883,
SI_HEALTHSTATE_CURSE = 884,
SI_HEALTHSTATE_SILENCE = 885,
SI_HEALTHSTATE_CONFUSION = 886,
SI_HEALTHSTATE_BLIND = 887,
SI_HEALTHSTATE_ANGELUS = 888,
SI_HEALTHSTATE_BLOODING = 889,
SI_HEALTHSTATE_HEAVYPOISON = 890,
SI_HEALTHSTATE_FEAR = 891,
SI_ATTACK_PROPERTY_NOTHING = 897,
SI_ATTACK_PROPERTY_WATER = 898,
SI_ATTACK_PROPERTY_GROUND = 899,
SI_ATTACK_PROPERTY_FIRE = 900,
SI_ATTACK_PROPERTY_WIND = 901,
SI_ATTACK_PROPERTY_POISON = 902,
SI_ATTACK_PROPERTY_SAINT = 903,
SI_ATTACK_PROPERTY_DARKNESS = 904,
SI_ATTACK_PROPERTY_TELEKINESIS = 905,
SI_ATTACK_PROPERTY_UNDEAD = 906,
SI_RESIST_PROPERTY_NOTHING = 907,
SI_RESIST_PROPERTY_WATER = 908,
SI_RESIST_PROPERTY_GROUND = 909,
SI_RESIST_PROPERTY_FIRE = 910,
SI_RESIST_PROPERTY_WIND = 911,
SI_RESIST_PROPERTY_POISON = 912,
SI_RESIST_PROPERTY_SAINT = 913,
SI_RESIST_PROPERTY_DARKNESS = 914,
SI_RESIST_PROPERTY_TELEKINESIS = 915,
SI_RESIST_PROPERTY_UNDEAD = 916,
SI_RUNEHELM = 925,
SI_HELM_VERKANA = 926,
SI_HELM_RHYDO = 927,
SI_HELM_TURISUS = 928,
SI_HELM_HAGALAS = 929,
SI_HELM_ISIA = 930,
SI_HELM_ASIR = 931,
SI_HELM_URJ = 932,
SI_MAX,
};
@ -1632,25 +1680,26 @@ enum e_mode {
//Status change option definitions (options are what makes status changes visible to chars
//who were not on your field of sight when it happened)
///opt1: Non stackable status changes.
///opt1: (BODYSTATE_*) Non stackable status changes.
enum sc_opt1 {
OPT1_STONE = 1, //Petrified
OPT1_FREEZE,
OPT1_STUN,
OPT1_SLEEP,
//Aegis uses OPT1 = 5 to identify undead enemies (which also grants them immunity to the other opt1 changes)
OPT1_STONEWAIT=6, //Petrifying
OPT1_STONEWAIT = 6, //Petrifying
OPT1_BURNING,
OPT1_FREEZING,
OPT1_IMPRISON,
OPT1_CRYSTALIZE,
};
///opt2: Stackable status changes.
///opt2: (HEALTHSTATE_*) Stackable status changes.
enum sc_opt2 {
OPT2_POISON = 0x0001,
OPT2_CURSE = 0x0002,
OPT2_SILENCE = 0x0004,
OPT2_SIGNUMCRUCIS = 0x0008,
OPT2_SIGNUMCRUCIS = 0x0008, //Confusion
OPT2_BLIND = 0x0010,
OPT2_ANGELUS = 0x0020,
OPT2_BLEEDING = 0x0040,
@ -1681,7 +1730,7 @@ enum sc_opt3 {
OPT3_CONTRACT = 0x00020000,
};
///Option
///Option (EFFECTSTATE_*)
enum e_option {
OPTION_NOTHING = 0x00000000,
OPTION_SIGHT = 0x00000001,