diff options
author | celest <celest@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2004-12-21 12:27:02 +0000 |
---|---|---|
committer | celest <celest@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2004-12-21 12:27:02 +0000 |
commit | 99ebdaf8e77e81e43d39825163837d6f4b2bc07a (patch) | |
tree | 5edaf24d7e804ab58c98897ea31e81af6277215d /src/map/skill.c | |
parent | 45544327c64939d9e7ac9578cb476ff497c6c3ce (diff) | |
download | hercules-99ebdaf8e77e81e43d39825163837d6f4b2bc07a.tar.gz hercules-99ebdaf8e77e81e43d39825163837d6f4b2bc07a.tar.bz2 hercules-99ebdaf8e77e81e43d39825163837d6f4b2bc07a.tar.xz hercules-99ebdaf8e77e81e43d39825163837d6f4b2bc07a.zip |
* Updated most of map-server to 1082
* Removed my own additions for skill delays using aspd
* Adapted skill_range_leniency to jA's code
* Fixed drop rates only limited to multiples of 100's
* Added missing code for castle_defense_rate
* Removed pc_undead_nofreeze
* Updated unrefineable items table
* Added 3 new script commands
* Added SC_SpeedUp0
* Merged itemdb_read for SQL and TXT
* Removed itemdb_read_cardillustnametable limited to TXT only
* Added reading itemslotcounttable.txt from the GRF to auto set number of slots per item
* Added a display message when reading itemslottable from the GRF
* Added options in battle_athena.conf to enable/disable reading the GRF
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@699 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/skill.c')
-rw-r--r-- | src/map/skill.c | 286 |
1 files changed, 145 insertions, 141 deletions
diff --git a/src/map/skill.c b/src/map/skill.c index dacd08e88..21c5bd954 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -231,7 +231,8 @@ int SkillStatusChangeTable[]={ /* skill.hのenumのSC_***とあわせること */ SC_BASILICA, -1,-1,-1, SC_MAGICPOWER, - -1,-1, + -1, + SC_SACRIFICE, SC_GOSPEL, /* 370- */ -1,-1,-1,-1,-1,-1,-1,-1, @@ -2335,7 +2336,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s case LK_HEADCRUSH: /* ヘッドクラッシュ */ case LK_JOINTBEAT: /* ジョイントビ?ト */ case PA_PRESSURE: /* プレッシャ? */ - case PA_SACRIFICE: /* サクリファイス */ +// case PA_SACRIFICE: /* サクリファイス */ case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */ case CG_ARROWVULCAN: /* アロ?バルカン */ case ASC_BREAKER: /* ソウルブレ?カ? */ @@ -2538,12 +2539,11 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s /* 個別にダメ?ジを?える */ if(bl->id!=skill_area_temp[1]) skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0x0500); - } - else { - int damage; + } else { +/* int damage; map_freeblock_lock(); damage = skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0); - if(damage > 0) { + if(damage > 0) {*/ int i,c; /* 他人から聞いた動きなので間違ってる可能性大&?率が?いっす>< */ c = skill_get_blewcount(skillid,skilllv); if(map[bl->m].flag.gvg) c = 0; @@ -2565,16 +2565,18 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s skill_area_temp[1]=bl->id; skill_area_temp[2]=bl->x; skill_area_temp[3]=bl->y; + skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0); + /* その後タ?ゲット以外の範??の敵全?に?理を行う */ map_foreachinarea(skill_area_sub, bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - battle_damage(src,bl,damage,1); +/* battle_damage(src,bl,damage,1); if(rdamage > 0) battle_damage(bl,src,rdamage,0); } - map_freeblock_unlock(); + map_freeblock_unlock();*/ } break; @@ -2597,7 +2599,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s case WZ_EARTHSPIKE: /* アーススパイク */ case AL_HEAL: /* ヒール */ case AL_HOLYLIGHT: /* ホーリーライト */ - case MG_FROSTDIVER: /* フロストダイバー */ +// case MG_FROSTDIVER: /* フロストダイバー */ case WZ_JUPITEL: /* ユピテルサンダー */ case NPC_DARKJUPITEL: /*闇ユピテル*/ case NPC_MAGICALATTACK: /* MOB:魔法打?攻? */ @@ -2606,6 +2608,28 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); break; + case MG_FROSTDIVER: /* フロストダイバー */ + { + struct status_change *sc_data = battle_get_sc_data(bl); + int sc_def_mdef, rate, damage; + sc_def_mdef = 100 - (3 + battle_get_mdef(bl) + battle_get_luk(bl)/3); + rate = (skilllv*3+35)*sc_def_mdef/100-(battle_get_int(bl)+battle_get_luk(bl))/15; + rate = rate<=5?5:rate; + if (sc_data && sc_data[SC_FREEZE].timer != -1) { + skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); + } else if (sd) { + clif_skill_fail(sd,skillid,0,0); + break; + } + damage = skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); + if (battle_get_hp(bl) > 0 && damage > 0 && rand()%100 < rate) { + skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + } else if (sd) { + clif_skill_fail(sd,skillid,0,0); + } + break; + } + case WZ_WATERBALL: /* ウォ?タ?ボ?ル */ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); if(skilllv>1) @@ -2849,7 +2873,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int struct mob_data *md=NULL; struct mob_data *dstmd=NULL; int i,abra_skillid=0,abra_skilllv; - int sc_def_vit,sc_def_mdef,strip_fix,strip_time,strip_per; + int sc_def_vit,sc_def_mdef,strip_time,strip_per; int sc_dex,sc_luk; //クラスチェンジ用ボスモンスタ?ID int changeclass[]={1038,1039,1046,1059,1086,1087,1112,1115 @@ -2872,7 +2896,6 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int sc_def_vit = 100 - (3 + battle_get_vit(bl) + battle_get_luk(bl)/3); //sc_def_vit = 100 - (3 + battle_get_vit(bl) + battle_get_luk(bl)/3); sc_def_mdef = 100 - (3 + battle_get_mdef(bl) + battle_get_luk(bl)/3); - strip_fix = battle_get_dex(src) - battle_get_dex(bl); if(bl->type==BL_PC){ nullpo_retr(1, dstsd=(struct map_session_data *)bl); @@ -2887,8 +2910,6 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int sc_def_vit=0; if(sc_def_mdef < 0) sc_def_mdef=0; - if(strip_fix < 0) - strip_fix=0; if(bl == NULL || bl->prev == NULL) return 1; @@ -3231,6 +3252,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int case ST_REJECTSWORD: /* リジェクトソ?ド */ case HW_MAGICPOWER: /* 魔法力?幅 */ case PF_MEMORIZE: /* メモライズ */ + case PA_SACRIFICE: case ASC_EDP: // [Celest] clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); @@ -3713,6 +3735,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int case MG_STONECURSE: /* スト?ンカ?ス */ { + struct status_change *sc_data = battle_get_sc_data(bl); // Level 6-10 doesn't consume a red gem if it fails [celest] int i, gem_flag = 1; if (bl->type==BL_MOB && battle_get_mode(bl)&0x20) { @@ -3722,7 +3745,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int clif_skill_nodamage(src,bl,skillid,skilllv,1); if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage ) break; - if( rand()%100 < skilllv*4+20 && !battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) + if (sc_data && sc_data[SC_STONE].timer != -1) { + skill_status_change_end(bl,SC_STONE,-1); + if (sd) + clif_skill_fail(sd,skillid,0,0); + } + else if( rand()%100 < skilllv*4+20 && !battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) skill_status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); else if(sd) { if (skilllv > 5) gem_flag = 0; @@ -3876,105 +3904,67 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; case RG_STRIPWEAPON: /* ストリップウェポン */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_WEAPON].timer != -1 ) + case RG_STRIPSHIELD: /* ストリップシールド */ + case RG_STRIPARMOR: /* ストリップアーマー */ + case RG_STRIPHELM: /* ストリップヘルム */ + { + struct status_change *tsc_data = battle_get_sc_data(bl); + int scid, equip, strip_fix; + scid = SkillStatusChangeTable[skillid]; + switch (skillid) { + case RG_STRIPWEAPON: + equip = EQP_WEAPON; break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0002){ - pc_unequipitem(dstsd,i,3); - break; - } - } - } - } - } - break; - - case RG_STRIPSHIELD: /* ストリップシ?ルド */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_SHIELD].timer != -1 ) + case RG_STRIPSHIELD: + equip = EQP_SHIELD; break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0020){ - pc_unequipitem(dstsd,i,3); - break; - } - } - } - } - } - break; - - case RG_STRIPARMOR: /* ストリップア?マ? */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_ARMOR].timer != -1 ) + case RG_STRIPARMOR: + equip = EQP_ARMOR; break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0010){ - pc_unequipitem(dstsd,i,3); - break; - } - } - } - } + case RG_STRIPHELM: + equip = EQP_HELM; + break; + default: + return 1; } - break; - case RG_STRIPHELM: /* ストリップヘルム */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_HELM].timer != -1 ) - break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0100){ - pc_unequipitem(dstsd,i,3); - break; - } - } + if (tsc_data && tsc_data[scid].timer != -1) + break; + + strip_fix = battle_get_dex(src) - battle_get_dex(bl); + if(strip_fix < 0) + strip_fix=0; + strip_per = 5+2*skilllv+strip_fix/5; + if (rand()%100 >= strip_per) + break; + + if (dstsd) { + for (i=0;i<MAX_INVENTORY;i++) { + if (dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & equip){ + pc_unequipitem(dstsd,i,0); + break; } } + if (i == MAX_INVENTORY) + break; } + clif_skill_nodamage(src,bl,skillid,skilllv,1); + strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; + skill_status_change_start(bl,scid,skilllv,0,0,0,strip_time,0 ); break; + } // Full Strip [Celest] case ST_FULLSTRIP: { struct status_change *tsc_data = battle_get_sc_data(bl); - int c=0, i, j; + int c=0, i, j, strip_fix; int striplist[2][4] = { { 0, 0, 0, 0 }, { 0x0002, 0x0020, 0x0010, 0x0100 } }; + strip_fix = battle_get_dex(src) - battle_get_dex(bl); + if(strip_fix < 0) + strip_fix=0; strip_per = 5+2*skilllv+strip_fix/5; strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; for (i=0; i<4; i++) { @@ -5170,13 +5160,14 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma case AL_WARP: /* ワ?プポ?タル */ { - const struct point *p[]={ - &sd->status.save_point,&sd->status.memo_point[0], - &sd->status.memo_point[1],&sd->status.memo_point[2], - }; + const struct point *p[4]; struct skill_unit_group *group; int i; int maxcount=0; + p[0] = &sd->status.save_point; + p[1] = &sd->status.memo_point[0]; + p[2] = &sd->status.memo_point[1]; + p[3] = &sd->status.memo_point[2]; if((maxcount = skill_get_maxcount(sd->skillid)) > 0) { int c; @@ -7390,6 +7381,11 @@ int skill_castfix( struct block_list *bl, int time ) castnodex=skill_get_castnodex(skill, lv); + /* サフラギウム */ + if(sc_data && sc_data[SC_SUFFRAGIUM].timer!=-1 ) + time=time*(100-sc_data[SC_SUFFRAGIUM].val1*15)/100; + skill_status_change_end( bl, SC_SUFFRAGIUM, -1); + if(time==0) return 0; if(castnodex > 0 && bl->type==BL_PC) @@ -7400,17 +7396,10 @@ int skill_castfix( struct block_list *bl, int time ) time=time*battle_config.cast_rate/100; } - /* サフラギウム */ - if(sc_data) { - if ( sc_data[SC_SUFFRAGIUM].timer!=-1 ){ - time=time*(100-sc_data[SC_SUFFRAGIUM].val1*15)/100; - skill_status_change_end( bl, SC_SUFFRAGIUM, -1); - } - /* ブラギの詩 */ - if( sc_data[SC_POEMBRAGI].timer!=-1 ) - time=time*(100-(sc_data[SC_POEMBRAGI].val1*3+sc_data[SC_POEMBRAGI].val2 - +(sc_data[SC_POEMBRAGI].val3>>16)))/100; - } + /* ブラギの詩 */ + if(sc_data && sc_data[SC_POEMBRAGI].timer!=-1) + time=time*(100-(sc_data[SC_POEMBRAGI].val1*3+sc_data[SC_POEMBRAGI].val2 + +(sc_data[SC_POEMBRAGI].val3>>16)))/100; return (time>0)?time:0; } @@ -7426,7 +7415,8 @@ int skill_delayfix( struct block_list *bl, int time ) sc_data = battle_get_sc_data(bl); if(time<=0) - return 0; + return ( battle_get_adelay(bl) / 2 ); + if(bl->type == BL_PC) { if( battle_config.delay_dependon_dex ) /* dexの影響を計算する */ @@ -7629,7 +7619,7 @@ int skill_use_id( struct map_session_data *sd, int target_id, range = skill_get_range(skill_num,skill_lv); if(range < 0) range = battle_get_range(&sd->bl) - (range + 1); - if(!battle_check_range(&sd->bl,bl,range) ) + if(!battle_check_range(&sd->bl,bl,range + 1) ) return 0; if(bl->type==BL_PC) { @@ -7721,6 +7711,9 @@ int skill_use_id( struct map_session_data *sd, int target_id, case PF_MEMORIZE: /* メモライズ */ casttime = 12000; break; + case HW_MAGICPOWER: + casttime = 700; + break; case GD_BATTLEORDER: case GD_REGENERATION: case GD_RESTORE: @@ -7736,11 +7729,6 @@ int skill_use_id( struct map_session_data *sd, int target_id, skill_status_change_end(&sd->bl, SC_MEMORIZE, -1); } - // instant cast attack skills depend on aspd as delay [celest] - if (casttime == 0 && delay == 0 && skill_db[skill_num].skill_type == BF_WEAPON) { - delay = battle_get_adelay (&sd->bl) * battle_config.delay_rate / 100; - } - if(battle_config.pc_skill_log) printf("PC %d skill use target_id=%d skill=%d lv=%d cast=%d\n",sd->bl.id,target_id,skill_num,skill_lv,casttime); @@ -7787,10 +7775,6 @@ int skill_use_id( struct map_session_data *sd, int target_id, skill_castend_id(sd->skilltimer,tick,sd->bl.id,0); } - //マジックパワ?の?果終了 - //if(sc_data && sc_data[SC_MAGICPOWER].timer != -1 && skill_num != HW_MAGICPOWER) - // skill_status_change_end(&sd->bl,SC_MAGICPOWER,-1); // moved - return 0; } @@ -7877,6 +7861,9 @@ int skill_use_pos( struct map_session_data *sd, range = skill_get_range(skill_num,skill_lv); if(range < 0) range = battle_get_range(&sd->bl) - (range + 1); +// be lenient if the skill was cast before we have moved to the correct position [Celest] + if (sd->walktimer != -1) + range += battle_config.skill_range_leniency; if(!battle_check_range(&sd->bl,&bl,range) ) return 0; @@ -8693,6 +8680,7 @@ int skill_status_change_end(struct block_list* bl, int type, int tid) case SC_MARIONETTE: case SC_MARIONETTE2: case SC_SLOWDOWN: + case SC_SPEEDUP0: /* case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD: @@ -8980,23 +8968,10 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data) break; case SC_SIGHT: /* サイト */ - { - const int range=7; - map_foreachinarea( skill_status_change_timer_sub, - bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0, - bl,type,tick); - - if( (--sc_data[type].val2)>0 ){ - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 250+tick, skill_status_change_timer, - bl->id, data); - return 0; - } - } - break; case SC_RUWACH: /* ルアフ */ { - const int range=5; + int range = 5; + if ( type == SC_SIGHT ) range = 7; map_foreachinarea( skill_status_change_timer_sub, bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0, bl,type,tick); @@ -9215,6 +9190,7 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data) case SC_MEMORIZE: /* メモライズ */ case SC_BROKNWEAPON: case SC_BROKNARMOR: + case SC_SACRIFICE: // if(sc_data[type].timer==tid) sc_data[type].timer=add_timer( 1000*600+tick,skill_status_change_timer, bl->id, data ); return 0; @@ -9679,6 +9655,13 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val if(sc_data[SC_CARTBOOST].timer!=-1 ) /* カ?トブ?スト */ skill_status_change_end(bl,SC_CARTBOOST,-1); break; + case SC_MAGICPOWER: + calc_flag = 1; + val2 = 1; + break; + case SC_SACRIFICE: + val2 = 5; + break; case SC_FLAMELAUNCHER: /* フレ?ムランチャ? */ skill_encchant_eremental_end(bl,SC_FLAMELAUNCHER); break; @@ -9919,9 +9902,29 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val } break; - /* option2 */ - case SC_POISON: /* 毒 */ + /* option2 */ case SC_DPOISON: /* 猛毒 */ + { + int mhp = battle_get_max_hp(bl); + int hp = battle_get_hp(bl); + // MHP?1/4???????? + if (hp > mhp>>2) { + if(bl->type == BL_PC) { + int diff = mhp*10/100; + if (hp - diff < mhp>>2) + hp = hp - (mhp>>2); + pc_heal((struct map_session_data *)bl, -hp, 0); + } else if(bl->type == BL_MOB) { + struct mob_data *md = (struct mob_data *)bl; + hp -= mhp*15/100; + if (hp > mhp>>2) + md->hp = hp; + else + md->hp = mhp>>2; + } + } + } // fall through + case SC_POISON: /* 毒 */ calc_flag = 1; if(!(flag&2)) { int sc_def = 100 - (battle_get_vit(bl) + battle_get_luk(bl)/5); @@ -10127,7 +10130,6 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val case SC_CARTBOOST: /* カ?トブ?スト */ case SC_TRUESIGHT: /* トゥル?サイト */ case SC_SPIDERWEB: /* スパイダ?ウェッブ */ - case SC_MAGICPOWER: /* 魔法力?幅 */ calc_flag = 1; break; @@ -10161,6 +10163,7 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val break; case SC_SLOWDOWN: + case SC_SPEEDUP0: calc_flag = 1; break; @@ -12049,7 +12052,8 @@ void skill_reload(void) int do_init_skill(void) { skill_readdb(); - skill_read_skillspamount(); + if (battle_config.skill_sp_override_grffile) + skill_read_skillspamount(); add_timer_func_list(skill_unit_timer,"skill_unit_timer"); add_timer_func_list(skill_castend_id,"skill_castend_id"); |