diff --git a/src/map/skill.c b/src/map/skill.c index 34361153ec..6074e545be 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -8406,7 +8406,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case CG_TAROTCARD: { - int count = -1; + int card = -1; + if (tsc && tsc->data[SC_TAROTCARD]) { + //Target currently has the SUN tarot card effect and is immune to any other effect + map_freeblock_unlock(); + return 0; + } if( rnd() % 100 > skill_lv * 8 || (tsc && tsc->data[SC_BASILICA]) || (dstmd && ((dstmd->guardian_data && dstmd->mob_id == MOBID_EMPERIUM) || status_get_class_(bl) == CLASS_BATTLEFIELD)) ) { if( sd ) @@ -8416,85 +8421,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui return 0; } status_zap(src,0,skill_get_sp(skill_id,skill_lv)); // consume sp only if succeeded [Inkfish] - do { - int eff = rnd() % 14; - clif_specialeffect(bl, 523 + eff, AREA); - switch (eff) - { - case 0: // heals SP to 0 - status_percent_damage(src, bl, 0, 100, false); - break; - case 1: // matk halved - sc_start(src,bl,SC_INCMATKRATE,100,-50,skill_get_time2(skill_id,skill_lv)); - break; - case 2: // all buffs removed - status_change_clear_buffs(bl, SCCB_BUFFS|SCCB_CHEM_PROTECT); - break; - case 3: // 1000 damage, random armor destroyed - { - status_fix_damage(src, bl, 1000, 0); - clif_damage(src,bl,tick,0,0,1000,0,DMG_NORMAL,0,false); - if( !status_isdead(bl) ) { - int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT }; - skill_break_equip(src,bl, where[rnd()%5], 10000, BCT_ENEMY); - } - } - break; - case 4: // atk halved - sc_start(src,bl,SC_INCATKRATE,100,-50,skill_get_time2(skill_id,skill_lv)); - break; - case 5: // 2000HP heal, random teleported - status_heal(src, 2000, 0, 0); - if( !map_flag_vs(bl->m) ) - unit_warp(bl, -1,-1,-1, CLR_TELEPORT); - break; - case 6: // random 2 other effects - if (count == -1) - count = 3; - else - count++; //Should not retrigger this one. - break; - case 7: // stop freeze or stoned - { - enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE }; - uint8 rand_eff = rnd()%3; - - sc_start2(src,bl,sc[rand_eff],100,skill_lv,(rand_eff == 2 ? src->id : 0),skill_get_time2(skill_id,skill_lv)); - } - break; - case 8: // curse coma and poison - status_change_start(src, bl, SC_COMA, 10000, skill_lv, 0, src->id, 0, 0, SCSTART_NONE); - sc_start(src,bl,SC_CURSE,100,skill_lv,skill_get_time2(skill_id,skill_lv)); - sc_start2(src,bl,SC_POISON,100,skill_lv,src->id,skill_get_time2(skill_id,skill_lv)); - break; - case 9: // confusion - sc_start(src,bl,SC_CONFUSION,100,skill_lv,skill_get_time2(skill_id,skill_lv)); - break; - case 10: // 6666 damage, atk matk halved, cursed - status_fix_damage(src, bl, 6666, 0); - clif_damage(src,bl,tick,0,0,6666,0,DMG_NORMAL,0,false); - sc_start(src,bl,SC_INCATKRATE,100,-50,skill_get_time2(skill_id,skill_lv)); - sc_start(src,bl,SC_INCMATKRATE,100,-50,skill_get_time2(skill_id,skill_lv)); - sc_start(src,bl,SC_CURSE,skill_lv,100,skill_get_time2(skill_id,skill_lv)); - break; - case 11: // 4444 damage - status_fix_damage(src, bl, 4444, 0); - clif_damage(src,bl,tick,0,0,4444,0,DMG_NORMAL,0,false); - break; - case 12: // stun - sc_start(src,bl,SC_STUN,100,skill_lv,5000); - break; - case 13: // atk,matk,hit,flee,def reduced - sc_start(src,bl,SC_INCATKRATE,100,-20,skill_get_time2(skill_id,skill_lv)); - sc_start(src,bl,SC_INCMATKRATE,100,-20,skill_get_time2(skill_id,skill_lv)); - sc_start(src,bl,SC_INCHITRATE,100,-20,skill_get_time2(skill_id,skill_lv)); - sc_start(src,bl,SC_INCFLEERATE,100,-20,skill_get_time2(skill_id,skill_lv)); - sc_start(src,bl,SC_INCDEFRATE,100,-20,skill_get_time2(skill_id,skill_lv)); - break; - default: - break; - } - } while ((--count) > 0); + card = skill_tarotcard(src, bl, skill_id, skill_lv, tick); // actual effect is executed here + if(card == 6) + clif_specialeffect(src, 522 + card, AREA); + else + clif_specialeffect(bl, 522 + card, AREA); clif_skill_nodamage(src,bl,skill_id,skill_lv,1); } break; @@ -16900,6 +16831,110 @@ int skill_greed(struct block_list *bl, va_list ap) return 0; } +/*========================================== [Playtester] +* Process tarot card's effects +* @ param src: Source of the tarot card effect +* @ param target: Target of the tartor card effect +* @ param skill_id: ID of the skill used +* @ param skill_lv: Level of the skill used +* @ param tick: Processing tick time +* @ return Card number +*------------------------------------------*/ +static int skill_tarotcard(struct block_list* src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int tick) +{ + int rate = rnd() % 100; + + if (rate < 10) // THE FOOL - heals SP to 0 + { + status_percent_damage(src, target, 0, 100, false); + return 1; + } + else if (rate < 20) // THE MAGICIAN - matk halved + { + sc_start(src, target, SC_INCMATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv)); + return 2; + } + else if (rate < 30) // THE HIGH PRIESTESS - all buffs removed + { + status_change_clear_buffs(target, SCCB_BUFFS | SCCB_CHEM_PROTECT); + return 3; + } + else if (rate < 37) // THE CHARIOT - 1000 damage, random armor destroyed + { + status_fix_damage(src, target, 1000, 0); + clif_damage(src, target, tick, 0, 0, 1000, 0, DMG_NORMAL, 0, false); + if (!status_isdead(target)) + { + unsigned short where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM }; + skill_break_equip(src, target, where[rnd() % 3], 10000, BCT_ENEMY); + } + return 4; + } + else if (rate < 47) // STRENGTH - atk halved + { + sc_start(src, target, SC_INCATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv)); + return 5; + } + else if (rate < 62) // THE LOVERS - 2000HP heal, random teleported + { + status_heal(target, 2000, 0, 0); + if (!map_flag_vs(target->m)) + unit_warp(target, -1, -1, -1, CLR_TELEPORT); + return 6; + } + else if (rate < 63) // WHEEL OF FORTUNE - random 2 other effects + { + // Recursive call + skill_tarotcard(src, target, skill_id, skill_lv, tick); + skill_tarotcard(src, target, skill_id, skill_lv, tick); + return 7; + } + else if (rate < 69) // THE HANGED MAN - stop, freeze or stoned + { + enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE }; + uint8 rand_eff = rnd() % 3; + sc_start2(src, target, sc[rand_eff], 100, skill_lv, (rand_eff == 2 ? src->id : 0), skill_get_time2(skill_id, skill_lv)); + return 8; + } + else if (rate < 74) // DEATH - curse, coma and poison + { + status_change_start(src, target, SC_COMA, 10000, skill_lv, 0, src->id, 0, 0, SCSTART_NONE); + sc_start(src, target, SC_CURSE, 100, skill_lv, skill_get_time2(skill_id, skill_lv)); + sc_start2(src, target, SC_POISON, 100, skill_lv, src->id, skill_get_time2(skill_id, skill_lv)); + return 9; + } + else if (rate < 82) // TEMPERANCE - confusion + { + sc_start(src, target, SC_CONFUSION, 100, skill_lv, skill_get_time2(skill_id, skill_lv)); + return 10; + } + else if (rate < 83) // THE DEVIL - 6666 damage, atk and matk halved, cursed + { + status_fix_damage(src, target, 6666, 0); + clif_damage(src, target, tick, 0, 0, 6666, 0, DMG_NORMAL, 0, false); + sc_start(src, target, SC_INCATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv)); + sc_start(src, target, SC_INCMATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv)); + sc_start(src, target, SC_CURSE, skill_lv, 100, skill_get_time2(skill_id, skill_lv)); + return 11; + } + else if (rate < 85) // THE TOWER - 4444 damage + { + status_fix_damage(src, target, 4444, 0); + clif_damage(src, target, tick, 0, 0, 4444, 0, DMG_NORMAL, 0, false); + return 12; + } + else if (rate < 90) // THE STAR - stun + { + sc_start(src, target, SC_STUN, 100, skill_lv, 5000); + return 13; + } + else // THE SUN - atk, matk, hit, flee and def reduced, immune to more tarot card effects + { + sc_start(src, target, SC_TAROTCARD, 100, skill_lv, skill_get_time2(skill_id, skill_lv)); + return 14; + } +} + /// Ranger's Detonator [Jobbie/3CeAM] int skill_detonator(struct block_list *bl, va_list ap) { diff --git a/src/map/status.c b/src/map/status.c index 0c9cc5fc47..1f4a538652 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -473,6 +473,7 @@ void initChangeTables(void) set_sc( WS_OVERTHRUSTMAX , SC_MAXOVERTHRUST , SI_MAXOVERTHRUST , SCB_NONE ); set_sc( CG_LONGINGFREEDOM , SC_LONGING , SI_LONGING , SCB_SPEED|SCB_ASPD ); set_sc( CG_HERMODE , SC_HERMODE , SI_HERMODE , SCB_NONE ); + set_sc( CG_TAROTCARD , SC_TAROTCARD , SI_TAROT , SCB_NONE ); set_sc( ITEM_ENCHANTARMS , SC_ENCHANTARMS , SI_BLANK , SCB_ATK_ELE ); set_sc( SL_HIGH , SC_SPIRIT , SI_SPIRIT , SCB_ALL ); set_sc( KN_ONEHAND , SC_ONEHAND , SI_ONEHAND , SCB_ASPD ); @@ -9542,6 +9543,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty } break; + case SC_TAROTCARD: + sc_start(src, bl, SC_INCATKRATE, 100, -20, tick); + sc_start(src, bl, SC_INCMATKRATE, 100, -20, tick); + sc_start(src, bl, SC_INCHITRATE, 100, -20, tick); + sc_start(src, bl, SC_INCFLEERATE, 100, -20, tick); + sc_start(src, bl, SC_INCDEFRATE, 100, -20, tick); + break; + case SC_MARIONETTE: { int stat; diff --git a/src/map/status.h b/src/map/status.h index 77c0ff1365..a4545aa86c 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -786,6 +786,8 @@ typedef enum sc_type { SC_CROSSBOWCLAN, SC_JUMPINGCLAN, + SC_TAROTCARD, + #ifdef RENEWAL SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled #endif