summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/battle.c6
-rw-r--r--src/map/skill.c30
-rw-r--r--src/map/skill.h3
-rw-r--r--src/map/status.c12
-rw-r--r--src/map/unit.c1
5 files changed, 48 insertions, 4 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 688f8febc..1064cf8a8 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -3694,6 +3694,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
//Damage calculation from iRO wiki. [Jobbie]
ad.damage = status->get_lv(src) * 10 + sstatus->int_;
break;
+ /**
+ * Summoner
+ */
+ case SU_SV_ROOTTWIST_ATK:
+ ad.damage = 100;
+ break;
default: {
unsigned int skillratio = 100; //Skill dmg modifiers.
MATK_ADD( status->get_matk(src, 2) );
diff --git a/src/map/skill.c b/src/map/skill.c
index 315d0f7f5..b109378a4 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -5054,6 +5054,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data)
return skill->castend_pos(tid,tick,id,data);
case GN_WALLOFTHORN:
case SU_CN_POWDERING:
+ case SU_SV_ROOTTWIST:
ud->skillx = target->x;
ud->skilly = target->y;
ud->skilltimer = tid;
@@ -8967,6 +8968,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case LG_TRAMPLE:
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->destroy_trap,bl,skill->get_splash(skill_id,skill_lv),BL_SKILL,tick);
+ status_change_end(bl, SC_SV_ROOTTWIST, INVALID_TIMER);
break;
case LG_REFLECTDAMAGE:
@@ -10597,6 +10599,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case RL_B_TRAP:
case MH_XENO_SLASHER:
case SU_CN_POWDERING:
+ case SU_SV_ROOTTWIST:
flag |= 1; // Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
FALLTHROUGH
case GS_GROUNDDRIFT: //Ammo should be deleted right away.
@@ -12252,6 +12255,9 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
map->freeblock_unlock();
}
break;
+ case WZ_HEAVENDRIVE:
++ status_change_end(bl, SC_SV_ROOTTWIST, INVALID_TIMER);
++ break;
/**
* The storm gust counter was dropped in renewal
**/
@@ -12836,6 +12842,30 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
status->change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0,
skill->get_time2(sg->skill_id, sg->skill_lv), SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
break;
+ case UNT_SV_ROOTTWIST:
+ if (status_get_mode(bl)&MD_BOSS) {
+ break;
+ }
+ if (tsc) {
+ if (!sg->val2) {
+ int sec = skill->get_time(sg->skill_id, sg->skill_lv);
+
+ if (sc_start2(ss, bl, type, 100, sg->skill_lv, sg->group_id, sec)) {
+ const struct TimerData* td = ((tsc->data[type])? timer->get(tsc->data[type]->timer) : NULL);
+
+ if (td != NULL)
+ sec = DIFF_TICK32(td->tick, tick);
+ clif->fixpos(bl);
+ sg->val2 = bl->id;
+ } else { // Couldn't trap it?
+ sec = 7000;
+ }
+ sg->limit = DIFF_TICK32(tick, sg->tick) + sec;
+ } else if (tsc->data[type] && bl->id == sg->val2) {
+ skill->attack(skill->get_type(SU_SV_ROOTTWIST_ATK), ss, &src->bl, bl, SU_SV_ROOTTWIST_ATK, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION);
+ }
+ }
+ break;
default:
skill->unit_onplace_timer_unknown(src, bl, &tick);
break;
diff --git a/src/map/skill.h b/src/map/skill.h
index 6cc4d32ff..b27d7ac3a 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1696,6 +1696,9 @@ enum {
UNT_B_TRAP,
UNT_FIRE_RAIN,
+ UNT_CATNIPPOWDER,
+ UNT_SV_ROOTTWIST,
+
/**
* Guild Auras
**/
diff --git a/src/map/status.c b/src/map/status.c
index 462112006..f1423d3c6 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -729,6 +729,7 @@ void initChangeTables(void)
add_sc(SU_SV_STEMSPEAR, SC_BLOODING);
status->set_sc(SU_CN_POWDERING, SC_CATNIPPOWDER, SI_CATNIPPOWDER, SCB_WATK | SCB_SPEED | SCB_REGEN);
add_sc(SU_CN_METEOR, SC_CURSE);
+ set_sc_with_vfx(SU_SV_ROOTTWIST, SC_SV_ROOTTWIST, SI_SV_ROOTTWIST, SCB_NONE);
// Elemental Spirit summoner's 'side' status changes.
status->set_sc( EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SI_CIRCLE_OF_FIRE_OPTION, SCB_NONE );
@@ -7805,12 +7806,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_OBLIVIONCURSE:
case SC_LEECHESEND:
- // Ranger Effects
+ // Ranger Effects
case SC_WUGBITE:
case SC_ELECTRICSHOCKER:
case SC_MAGNETICFIELD:
- // Masquerades
+ // Masquerades
case SC__ENERVATION:
case SC__GROOMY:
case SC__LAZINESS:
@@ -7822,6 +7823,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_VACUUM_EXTREME:
case SC_NETHERWORLD:
case SC_FRESHSHRIMP:
+ case SC_SV_ROOTTWIST:
return 0;
}
}
@@ -10011,6 +10013,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_NEEDLE_OF_PARALYZE:
case SC_DEATHBOUND:
case SC_NETHERWORLD:
+ case SC_SV_ROOTTWIST:
unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
break;
case SC_ANKLESNARE:
@@ -10869,10 +10872,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_NEUTRALBARRIER_MASTER:
case SC_STEALTHFIELD_MASTER:
- if( sce->val2 ) {
+ case SC_SV_ROOTTWIST:
+ if (sce->val2) {
struct skill_unit_group* group = skill->id2group(sce->val2);
sce->val2 = 0;
- if( group ) /* might have been cleared before status ended, e.g. land protector */
+ if (group) /* might have been cleared before status ended, e.g. land protector */
skill->del_unitgroup(group,ALC_MARK);
}
break;
diff --git a/src/map/unit.c b/src/map/unit.c
index d652df07e..0f3631792 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2466,6 +2466,7 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
status_change_end(bl, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); //callme before warp
status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER);
status_change_end(bl, SC_SUHIDE, INVALID_TIMER);
+ status_change_end(bl, SC_SV_ROOTTWIST, INVALID_TIMER);
}
if (bl->type&(BL_CHAR|BL_PET)) {