summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c9
-rw-r--r--src/common/mmo.h2
-rw-r--r--src/config/const.h5
-rw-r--r--src/map/battle.c17
-rw-r--r--src/map/clif.c29
-rw-r--r--src/map/itemdb.h3
-rw-r--r--src/map/pc.c23
-rw-r--r--src/map/skill.c148
-rw-r--r--src/map/skill.h3
-rw-r--r--src/map/status.c18
-rw-r--r--src/map/status.h3
11 files changed, 198 insertions, 62 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 7dfb6861c..edc73223a 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -3620,7 +3620,7 @@ static void char_delete2_req(int fd, struct char_session_data* sd)
static void char_delete2_accept(int fd, struct char_session_data* sd)
{// CH: <0829>.W <char id>.L <birth date:YYMMDD>.6B
char birthdate[8+1];
- int char_id, i, k;
+ int char_id, i;
unsigned int base_level;
char* data;
time_t delete_date;
@@ -3683,11 +3683,8 @@ static void char_delete2_accept(int fd, struct char_session_data* sd)
}
// refresh character list cache
- for(k = i; k < MAX_CHARS-1; k++) {
- sd->found_char[k] = sd->found_char[k+1];
- }
- sd->found_char[MAX_CHARS-1] = -1;
-
+ sd->found_char[i] = -1;
+
char_delete2_accept_ack(fd, char_id, 1);
}
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 17caf917a..34a79bbb2 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -113,7 +113,7 @@
#define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan]
#define MAX_GUILDLEVEL 50
#define MAX_GUARDIANS 8 // Local max per castle. [Skotlex]
-#define MAX_QUEST_DB 2410 // Max quests that the server will load
+#define MAX_QUEST_DB 2662 // Max quests that the server will load
#define MAX_QUEST_OBJECTIVES 3 // Max quest objectives for a quest
#define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95]
diff --git a/src/config/const.h b/src/config/const.h
index d8e397b1e..b51db97e5 100644
--- a/src/config/const.h
+++ b/src/config/const.h
@@ -62,6 +62,11 @@
#ifdef RENEWAL
#define MOB_FLEE(mob) ( mob->lv + mob->status.agi + 100 )
#define MOB_HIT(mob) ( mob->lv + mob->status.dex + 150 )
+ #define RE_SKILL_REDUCTION(){ \
+ wd.damage = battle->calc_elefix(src, target, skill_id, skill_lv, battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag), nk, n_ele, s_ele, s_ele_, false, flag.arrow); \
+ if( flag.lh ) \
+ wd.damage2 = battle->calc_elefix(src, target, skill_id, skill_lv, battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag), nk, n_ele, s_ele, s_ele_, true, flag.arrow); \
+ }
#else
#define MOB_FLEE(mob) ( mob->lv + mob->status.agi )
#define MOB_HIT(mob) ( mob->lv + mob->status.dex )
diff --git a/src/map/battle.c b/src/map/battle.c
index 1d14c1828..31a4ddc89 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -443,9 +443,8 @@ int battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uin
eatk += 200;
#ifdef RENEWAL_EDP
if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ){
- eatk = eatk * sc->data[SC_EDP]->val3 / 100; // 400%
- damage = damage * sc->data[SC_EDP]->val4 / 100; // 500%
- damage--; // temporary until we find the correct formula [malufett]
+ eatk = eatk * sc->data[SC_EDP]->val4 / 100;
+ damage += damage * sc->data[SC_EDP]->val3 / 100;
}
#endif
}
@@ -4401,11 +4400,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD(-totaldef);
if( is_boss(target) )
ATK_RATE(50);
+ RE_SKILL_REDUCTION();
}
break;
case NJ_SYURIKEN: // [malufett]
GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
wd.damage += battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon) - status_get_total_def(target);
+ RE_SKILL_REDUCTION();
break;
case MO_EXTREMITYFIST: // [malufett]
{
@@ -4415,6 +4416,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
wd.damage = (250 + 150 * skill_lv) + (10 * (status_get_sp(src)+1) * wd.damage / 100) + (8 * wd.damage);
ATK_ADD(-totaldef);
}
+ RE_SKILL_REDUCTION();
}
#endif
break;
@@ -4708,7 +4710,12 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
ATK_RATE(i);
-
+#ifdef RENEWAL
+ if( skill_id && (wd.damage+wd.damage2) ){
+ RE_SKILL_REDUCTION();
+ }
+#endif
+
if( sd ) {
if (skill_id && (i = pc->skillatk_bonus(sd, skill_id)))
ATK_ADDRATE(i);
@@ -4813,7 +4820,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
#ifndef RENEWAL
wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
- if( flag.lh)
+ if( flag.lh )
wd.damage2 = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage2, wd.div_, 1, flag.weapon);
#else
if( sd && flag.cri )
diff --git a/src/map/clif.c b/src/map/clif.c
index f925fcf55..d08bb3868 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -10503,11 +10503,13 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
return;
}
- // if player ignores the source character
- ARR_FIND(0, MAX_IGNORE_LIST, i, dstsd->ignore[i].name[0] == '\0' || strcmp(dstsd->ignore[i].name, sd->status.name) == 0);
- if(i < MAX_IGNORE_LIST && dstsd->ignore[i].name[0] != '\0') { // source char present in ignore list
- clif->wis_end(fd, 2); // 2: ignored by target
- return;
+ if( pc->get_group_level(sd) <= pc->get_group_level(dstsd) ) {
+ // if player ignores the source character
+ ARR_FIND(0, MAX_IGNORE_LIST, i, dstsd->ignore[i].name[0] == '\0' || strcmp(dstsd->ignore[i].name, sd->status.name) == 0);
+ if(i < MAX_IGNORE_LIST && dstsd->ignore[i].name[0] != '\0') { // source char present in ignore list
+ clif->wis_end(fd, 2); // 2: ignored by target
+ return;
+ }
}
// notify sender of success
@@ -11170,6 +11172,13 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
if( sd && pc->checkskill(sd, MC_CHANGECART) < 1 )
return;
+#ifdef RENEWAL
+ if( sd->npc_id || sd->state.workinprogress&1 ){
+ clif->msg(sd, 0x783);
+ return;
+ }
+#endif
+
type = (int)RFIFOW(fd,2);
#ifdef NEW_CARTS
if( (type == 9 && sd->status.base_level > 131) ||
@@ -11423,6 +11432,13 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski
clif->pUseSkillToPos_mercenary(sd->md, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo);
return;
}
+
+#ifdef RENEWAL
+ if( sd->state.workinprogress&1 ){
+ clif->msg(sd, 0x783); // TODO look for the client date that has this message.
+ return;
+ }
+#endif
//Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
sd->idletime = last_tick;
@@ -11527,7 +11543,9 @@ void clif_parse_UseSkillMap(int fd, struct map_session_data* sd)
{
uint16 skill_id = RFIFOW(fd,2);
char map_name[MAP_NAME_LENGTH];
+
mapindex_getmapname((char*)RFIFOP(fd,4), map_name);
+ sd->state.workinprogress = 0;
if(skill_id != sd->menuskill_id)
return;
@@ -11780,6 +11798,7 @@ void clif_parse_AutoSpell(int fd,struct map_session_data *sd)
return;
skill->autospell(sd,RFIFOL(fd,2));
clif_menuskill_clear(sd);
+ sd->state.workinprogress = 0;
}
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index dcd0ae644..db1330344 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -63,6 +63,7 @@ enum {
ITEMID_THURISAZ,
ITEMID_WYRD,
ITEMID_HAGALAZ,
+ ITEMID_LUX_ANIMA = 22540,
} rune_list;
/**
@@ -226,7 +227,7 @@ struct item_package {
#define itemdb_available(n) (itemdb->search(n)->flag.available)
#define itemdb_viewid(n) (itemdb->search(n)->view_id)
#define itemdb_autoequip(n) (itemdb->search(n)->flag.autoequip)
-#define itemdb_is_rune(n) (n >= ITEMID_NAUTHIZ && n <= ITEMID_HAGALAZ)
+#define itemdb_is_rune(n) ((n >= ITEMID_NAUTHIZ && n <= ITEMID_HAGALAZ) || n == ITEMID_LUX_ANIMA)
#define itemdb_is_element(n) (n >= 990 && n <= 993)
#define itemdb_is_spellbook(n) (n >= 6188 && n <= 6205)
#define itemdb_is_poison(n) (n >= 12717 && n <= 12724)
diff --git a/src/map/pc.c b/src/map/pc.c
index 3ddae9222..f2c0ddc37 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -861,11 +861,15 @@ int pc_isequip(struct map_session_data *sd,int n)
if(item == NULL)
return 0;
- if(item->elv && sd->status.base_level < (unsigned int)item->elv)
+ if(item->elv && sd->status.base_level < (unsigned int)item->elv){
+ clif->msg(sd, 0x6ED);
return 0;
+ }
#ifdef RENEWAL
- if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax)
+ if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax){
+ clif->msg(sd, 0x6ED);
return 0;
+ }
#endif
if(item->sex != 2 && sd->status.sex != item->sex)
return 0;
@@ -4113,7 +4117,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
return 0;
if( (item->item_usage.flag&NOUSE_SITTING) && (pc_issit(sd) == 1) && (pc->get_group_level(sd) < item->item_usage.override) ) {
- clif->msgtable(sd->fd,664);
+ clif->msgtable(sd->fd,0x297);
//clif->colormes(sd->fd,COLOR_WHITE,msg_txt(1474));
return 0; // You cannot use this item while sitting.
}
@@ -4218,12 +4222,16 @@ int pc_isUseitem(struct map_session_data *sd,int n)
if(item->sex != 2 && sd->status.sex != item->sex)
return 0;
//Required level check
- if(item->elv && sd->status.base_level < (unsigned int)item->elv)
+ if(item->elv && sd->status.base_level < (unsigned int)item->elv){
+ clif->msg(sd, 0x6EE);
return 0;
+ }
#ifdef RENEWAL
- if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax)
+ if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax){
+ clif->msg(sd, 0x6EE);
return 0;
+ }
#endif
//Not equipable by class. [Skotlex]
@@ -4775,6 +4783,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
sd->state.changemap = (sd->mapindex != mapindex);
sd->state.warping = 1;
+ sd->state.workinprogress = 0;
if( sd->state.changemap ) { // Misc map-changing settings
int i;
sd->state.pmap = sd->bl.m;
@@ -6607,8 +6616,10 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
skill->sit(sd,0);
}
- if( sd->progressbar.npc_id )
+ if( sd->progressbar.npc_id ){
clif->progressbar_abort(sd);
+ sd->state.workinprogress = 0;
+ }
if( sd->status.pet_id > 0 && sd->pd && battle_config.pet_damage_support )
pet_target_check(sd,src,1);
diff --git a/src/map/skill.c b/src/map/skill.c
index dc89f3170..9823fec0a 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1056,7 +1056,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
case LK_SPIRALPIERCE:
case ML_SPIRALPIERCE:
- sc_start(bl,SC_STOP,(15+skill_lv*5),0,skill->get_time2(skill_id,skill_lv));
+ sc_start(bl,SC_ANKLESNARE,100,0,skill->get_time2(skill_id,skill_lv));
break;
case ST_REJECTSWORD:
@@ -1387,6 +1387,10 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
case MH_NEEDLE_OF_PARALYZE:
sc_start(bl, SC_NEEDLE_OF_PARALYZE, 40 + (5*skill_lv), skill_lv, skill->get_time(skill_id, skill_lv));
break;
+ case GN_ILLUSIONDOPING:
+ if( sc_start(bl, SC_ILLUSIONDOPING, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)) ) //custom rate.
+ sc_start(bl, SC_ILLUSION, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ break;
}
if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai)
@@ -3238,6 +3242,13 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
}
}
break;
+ case SC_ESCAPE:
+ if( skl->type < 4+skl->skill_lv ){
+ clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,5);
+ skill->blown(src,src,1,unit_getdir(src),0);
+ skill->addtimerskill(src,tick+80,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type+1,0);
+ }
+ break;
case CH_PALMSTRIKE:
{
struct status_change* tsc = status_get_sc(target);
@@ -3745,6 +3756,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case KO_HUUMARANKA:
case KO_MUCHANAGE:
case KO_BAKURETSU:
+ case GN_ILLUSIONDOPING:
if( flag&1 ) {//Recursive invocation
// skill_area_temp[0] holds number of targets in area
// skill_area_temp[1] holds the id of the original target
@@ -5658,6 +5670,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case MC_CHANGECART:
+ if( sd )
+ sd->state.workinprogress = 3;
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
@@ -6778,9 +6792,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case SA_AUTOSPELL:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- if(sd)
+ if(sd){
+ sd->state.workinprogress = 3;
clif->autospell(sd,skill_lv);
- else {
+ }else {
int maxlv=1,spellid=0;
static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT };
if(skill_lv >= 10) {
@@ -7799,6 +7814,67 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
clif->skill_nodamage(src,bl,skill_id,1,1);
break;
+
+ case RK_LUXANIMA:
+ if( sd == NULL || sd->status.party_id == 0 || flag&1 ){
+ if( src == bl )
+ break;
+ while( skill_area_temp[5] >= 0x10 ){
+ type = SC_NONE;
+ i = 0;
+ if( skill_area_temp[5]&0x10 ){
+ if( dstsd ){
+ i = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2);
+ clif->millenniumshield(dstsd,i);
+ skill_area_temp[5] &= ~0x10;
+ type = SC_MILLENNIUMSHIELD;
+ }
+ }else if( skill_area_temp[5]&0x20 ){
+ i = status_get_max_hp(bl) * 25 / 100;
+ status_change_clear_buffs(bl,4);
+ skill_area_temp[5] &= ~0x20;
+ status_heal(bl,i,0,1);
+ type = SC_REFRESH;
+ }else if( skill_area_temp[5]&0x40 ){
+ skill_area_temp[5] &= ~0x40;
+ type = SC_GIANTGROWTH;
+ }else if( skill_area_temp[5]&0x80 ){
+ if( dstsd ){
+ i = sstatus->hp / 4;
+ if( status_charge(bl,i,0) )
+ type = SC_STONEHARDSKIN;
+ skill_area_temp[5] &= ~0x80;
+ }
+ }else if( skill_area_temp[5]&0x100 ){
+ skill_area_temp[5] &= ~0x100;
+ type = SC_VITALITYACTIVATION;
+ }else if( skill_area_temp[5]&0x200 ){
+ skill_area_temp[5] &= ~0x200;
+ type = SC_ABUNDANCE;
+ }
+ if( type > SC_NONE )
+ clif->skill_nodamage(bl, bl, skill_id, skill_lv,
+ sc_start4(bl, type, 100, skill_lv, i, 0, 1, skill->get_time(skill_id, skill_lv)));
+ }
+ }else if( sd ){
+ if( tsc && tsc->count ){
+ if(tsc->data[SC_MILLENNIUMSHIELD])
+ skill_area_temp[5] |= 0x10;
+ if(tsc->data[SC_REFRESH])
+ skill_area_temp[5] |= 0x20;
+ if(tsc->data[SC_GIANTGROWTH])
+ skill_area_temp[5] |= 0x40;
+ if(tsc->data[SC_STONEHARDSKIN])
+ skill_area_temp[5] |= 0x80;
+ if(tsc->data[SC_VITALITYACTIVATION])
+ skill_area_temp[5] |= 0x100;
+ if(tsc->data[SC_ABUNDANCE])
+ skill_area_temp[5] |= 0x200;
+ }
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ party_foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
+ }
+ break;
/**
* Guilotine Cross
**/
@@ -7891,15 +7967,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AB_CLEMENTIA:
case AB_CANTO:
- {
- int bless_lv = pc->checkskill(sd,AL_BLESSING) + (sd->status.job_level / 10);
- int agi_lv = pc->checkskill(sd,AL_INCAGI) + (sd->status.job_level / 10);
- if( sd == NULL || sd->status.party_id == 0 || flag&1 )
- clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl,type,100,
- (skill_id == AB_CLEMENTIA)? bless_lv : (skill_id == AB_CANTO)? agi_lv : skill_lv, skill->get_time(skill_id,skill_lv)));
- else if( sd )
+ if( sd )
+ i = skill_id == AB_CLEMENTIA ? pc->checkskill(sd,AL_BLESSING) : pc->checkskill(sd,AL_INCAGI);
+ if( sd == NULL || sd->status.party_id == 0 || flag&1 )
+ clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl, type, 100, i + (sd?(sd->status.job_level / 10):0), skill->get_time(skill_id,skill_lv)));
+ else if( sd )
+ if( !i )
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL,0);
+ else
party_foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
- }
break;
case AB_PRAEFATIO:
@@ -8853,7 +8929,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SO_EL_ACTION:
if( sd ) {
- int duration = 3000;
+ int duration = 3000;
if( !sd->ed ) break;
sd->skill_id_old = skill_id;
elemental_action(sd->ed, bl, tick);
@@ -8890,6 +8966,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
+ case SO_ELEMENTAL_SHIELD:
+ if( !sd->ed ) break;
+ elemental_delete(sd->ed, 0);
+ if( sd == NULL || sd->status.party_id == 0 || flag&1 )
+ skill->unitsetting(src,MG_SAFETYWALL,skill_lv,bl->x,bl->y,0);
+ else if( sd )
+ party_foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
+ break;
+
case GN_CHANGEMATERIAL:
case SO_EL_ANALYSIS:
if( sd ) {
@@ -9528,7 +9613,6 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
unsigned short mapindex;
mapindex = mapindex_name2id((char*)map);
- sd->state.workinprogress = 0;
if(!mapindex) { //Given map not found?
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
skill_failed(sd);
@@ -9626,6 +9710,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case CR_CULTIVATION:
case HW_GANBANTEIN:
case LG_EARTHDRIVE:
+ case SC_ESCAPE:
break; //Effect is displayed on respective switch case.
default:
if(skill->get_inf(skill_id)&INF_SELF_SKILL)
@@ -10161,6 +10246,12 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
skill->castend_nodamage_id(src,src,TF_HIDING,1,tick,0x2);
break;
+ case SC_ESCAPE:
+ clif->skill_nodamage(src,src,skill_id,-1,1);
+ skill->unitsetting(src,HT_ANKLESNARE,skill_lv,x,y,2);
+ skill->addtimerskill(src,tick,src->id,0,0,skill_id,skill_lv,0,0);
+ break;
+
case LG_OVERBRAND:
{
int width;//according to data from irowiki it actually is a square
@@ -10321,15 +10412,13 @@ int skill_dance_overlap_sub(struct block_list* bl, va_list ap) {
int skill_dance_overlap(struct skill_unit* unit, int flag) {
if (!unit || !unit->group || !(unit->group->state.song_dance&0x1))
return 0;
- if (!flag && !(unit->val2&UF_ENSEMBLE))
- return 0; //Nothing to remove, this unit is not overlapped.
-
+
if (unit->val1 != unit->group->skill_id) {
//Reset state
unit->val1 = unit->group->skill_id;
unit->val2 &= ~UF_ENSEMBLE;
}
-
+
return iMap->foreachincell(skill->dance_overlap_sub, unit->bl.m,unit->bl.x,unit->bl.y,BL_SKILL, unit,flag);
}
@@ -10500,6 +10589,9 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
&& (src->type&battle_config.vs_traps_bctall))
target = BCT_ALL;
break;
+ case HT_ANKLESNARE:
+ if( flag&2 )
+ val3 = SC_ESCAPE;
case HT_SHOCKWAVE:
val1=skill_lv*15+10;
case HT_SANDMAN:
@@ -10509,7 +10601,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
case MA_SKIDTRAP:
case HT_LANDMINE:
case MA_LANDMINE:
- case HT_ANKLESNARE:
case HT_FLASHER:
case HT_FREEZINGTRAP:
case MA_FREEZINGTRAP:
@@ -15452,7 +15543,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
case UNT_ANKLESNARE:
case UNT_ELECTRICSHOCKER:
- if( group->val2 > 0 ) {
+ if( group->val2 > 0 || group->val3 == SC_ESCAPE ) {
// Used Trap don't returns back to item
skill->delunit(unit);
break;
@@ -16129,6 +16220,7 @@ int skill_produce_mix (struct map_session_data *sd, uint16 skill_id, int nameid,
case ITEMID_URUZ:
D -= 500; //Rank A
case ITEMID_BERKANA:
+ case ITEMID_LUX_ANIMA:
D -= 500; //Rank S
}
make_per = A + B + C - D;
@@ -16870,7 +16962,7 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
if (!sd) return 0;
if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0;
- if( ( cd = idb_get(skillcd_db,sd->status.char_id) ) ) {
+ if( ( cd = idb_get(skill->cd_db,sd->status.char_id) ) ) {
int i,cursor;
ARR_FIND( 0, cd->cursor+1, cursor, cd->skidx[cursor] == data );
cd->duration[cursor] = 0;
@@ -16896,7 +16988,7 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
cursor++;
}
if( cursor == 0 )
- idb_remove(skillcd_db,sd->status.char_id);
+ idb_remove(skill->cd_db,sd->status.char_id);
else
cd->cursor = cursor;
}
@@ -16931,9 +17023,9 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick,
clif->skill_cooldown(sd, skill_id, tick);
if( !load ) {// not being loaded initially so ensure the skill delay is recorded
- if( !(cd = idb_get(skillcd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
+ if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
CREATE( cd, struct skill_cd, 1 );
- idb_put( skillcd_db, sd->status.char_id, cd );
+ idb_put( skill->cd_db, sd->status.char_id, cd );
}
// record the skill duration in the database map
@@ -17447,7 +17539,7 @@ void skill_cooldown_save(struct map_session_data * sd) {
// always check to make sure the session properly exists
nullpo_retv(sd);
- if( !(cd = idb_get(skillcd_db, sd->status.char_id)) ) {// no skill cooldown is associated with this character
+ if( !(cd = idb_get(skill->cd_db, sd->status.char_id)) ) {// no skill cooldown is associated with this character
return;
}
@@ -17471,7 +17563,7 @@ void skill_cooldown_load(struct map_session_data * sd) {
// always check to make sure the session properly exists
nullpo_retv(sd);
- if( !(cd = idb_get(skillcd_db, sd->status.char_id)) ) {// no skill cooldown is associated with this character
+ if( !(cd = idb_get(skill->cd_db, sd->status.char_id)) ) {// no skill cooldown is associated with this character
return;
}
@@ -17955,7 +18047,7 @@ int do_init_skill (void) {
group_db = idb_alloc(DB_OPT_BASE);
skillunit_db = idb_alloc(DB_OPT_BASE);
- skillcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ skill->cd_db = idb_alloc(DB_OPT_RELEASE_DATA);
skillusave_db = idb_alloc(DB_OPT_RELEASE_DATA);
skill_unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE);
skill_timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE);
@@ -17976,7 +18068,7 @@ int do_final_skill(void)
db_destroy(skilldb_name2id);
db_destroy(group_db);
db_destroy(skillunit_db);
- db_destroy(skillcd_db);
+ db_destroy(skill->cd_db);
db_destroy(skillusave_db);
ers_destroy(skill_unit_ers);
ers_destroy(skill_timer_ers);
@@ -17989,6 +18081,8 @@ void skill_defaults(void) {
skill->final = do_final_skill;
skill->reload = skill_reload;
skill->read_db = skill_readdb;
+ /* */
+ skill->cd_db = NULL;
/* accesssors */
skill->get_index = skill_get_index;
skill->get_type = skill_get_type;
diff --git a/src/map/skill.h b/src/map/skill.h
index fceef5556..a2eed585f 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1736,7 +1736,6 @@ struct skill_cd {
extern int enchant_eff[5];
extern int deluge_eff[5];
DBMap* skilldb_name2id;
-DBMap* skillcd_db; // char_id -> struct skill_cd
/**
* Skill.c Interface
@@ -1746,6 +1745,8 @@ struct skill_interface {
int (*final) (void);
void (*reload) (void);
void (*read_db) (void);
+ /* */
+ DBMap* cd_db; // char_id -> struct skill_cd
/* accesssors */
int (*get_index) ( uint16 skill_id );
int (*get_type) ( uint16 skill_id );
diff --git a/src/map/status.c b/src/map/status.c
index 64c591b3b..fb843da0c 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -782,6 +782,8 @@ void initChangeTables(void) {
add_sc( NPC_WIDE_DEEP_SLEEP , SC_DEEP_SLEEP );
add_sc( NPC_WIDESIREN , SC_SIREN );
+ set_sc_with_vfx( GN_ILLUSIONDOPING , SC_ILLUSIONDOPING , SI_ILLUSIONDOPING , SCB_HIT );
+
// Storing the target job rather than simply SC_SOULLINK simplifies code later on.
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
@@ -4749,8 +4751,10 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
if(sc->data[SC_FEAR])
hit -= hit * 20 / 100;
- if (sc->data[SC_VOLCANIC_ASH])
+ if(sc->data[SC_VOLCANIC_ASH])
hit /= 2;
+ if(sc->data[SC_ILLUSIONDOPING])
+ hit -= hit * (5 + sc->data[SC_ILLUSIONDOPING]->val1) / 100; //custom
return (short)cap_value(hit,1,SHRT_MAX);
}
@@ -6712,11 +6716,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 0;
case SC_INC_AGI:
- if(sd && pc_issit(sd)){
- pc->setstand(sd);
- clif->standing(&sd->bl);
- }
-
case SC_CONCENTRATION:
case SC_SPEARQUICKEN:
case SC_TRUESIGHT:
@@ -7338,11 +7337,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_EDP: // [Celest]
val2 = val1 + 2; //Chance to Poison enemies.
+ val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
#ifdef RENEWAL_EDP
- val3 = 50*(val1+3);
val4 = 100 * ((val1 + 1)/2 + 2);
- #else
- val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
#endif
if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
@@ -11085,6 +11082,9 @@ int status_change_clear_buffs (struct block_list* bl, int type)
continue;
sc->data[i]->val2 = 0;
break;
+ default:
+ if(type&4)
+ continue;
}
status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
diff --git a/src/map/status.h b/src/map/status.h
index 380b49879..7c9c16a0e 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -673,6 +673,7 @@ typedef enum sc_type {
SC_MONSTER_TRANSFORM,
SC_ANGEL_PROTECT,
+ SC_ILLUSIONDOPING,
SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type;
@@ -1405,7 +1406,7 @@ enum si_type {
SI_2013_VALENTINE1 = 731,
SI_2013_VALENTINE2 = 732,
SI_2013_VALENTINE3 = 733,
- //SI_ = 734,
+ SI_ILLUSIONDOPING = 734,
//SI_ = 735,
SI_CHILL = 736,
SI_BURNT = 737,