* Updated Stone Curse

* Implemented Confusion (50%)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@487 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
celest 2004-12-07 13:50:56 +00:00
parent 28efb08b71
commit 1f3ab48426
7 changed files with 124 additions and 24 deletions

View File

@ -3,8 +3,13 @@ Date Added
* Skill Updates [celest]
- Arrow Shower, Double Strafing, Charge Arrow, Throw Arrow, Sharp Shooting,
Arrow Vulcan, and Musical Strike now take arrows when used
- Level 6-10 Stone Curse will not consume a red gem now when it fails
- Players should be able to use items when they're stoned but not yet
completely petrified
* Added 'guildgetexp' script command [celest]
* Added bLongAtkRate item effect [celest]
* Implemented Confusion (50%) - still need more info on how monsters act
when they're confused [celest]
12/6
* Fixed file props for new npcs [MouseJstr]

View File

@ -7462,7 +7462,8 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) {
sd->sc_data[SC_TRICKDEAD].timer !=-1 || //死んだふり
sd->sc_data[SC_BLADESTOP].timer !=-1 || //白刃取り
sd->sc_data[SC_SPIDERWEB].timer !=-1 || //スパイダーウェッブ
(sd->sc_data[SC_DANCING].timer !=-1 && sd->sc_data[SC_DANCING].val4)) //合奏スキル演奏中は動けない
(sd->sc_data[SC_DANCING].timer !=-1 && sd->sc_data[SC_DANCING].val4) || //合奏スキル演奏中は動けない
sd->sc_data[SC_CONFUSION].timer !=-1)
return;
if ((sd->status.option & 2) && pc_checkskill(sd, RG_TUNNELDRIVE) <= 0)
return;
@ -8192,7 +8193,7 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd) {
clif_clearchar_area(&sd->bl, 1);
return;
}
if (sd->npc_id!=0 || sd->vender_id != 0 || sd->opt1 > 0 ||
if (sd->npc_id!=0 || sd->vender_id != 0 || (sd->opt1 > 0 && sd->opt1 != 6) ||
(sd->sc_data && (sd->sc_data[SC_TRICKDEAD].timer != -1 || //死んだふり
sd->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り
sd->sc_data[SC_BERSERK].timer!=-1 || //バーサーク

View File

@ -169,6 +169,7 @@ struct map_session_data {
unsigned int client_tick,server_tick;
struct walkpath_data walkpath;
int walktimer;
int next_walktime;
int npc_id,areanpc_id,npc_shopid;
int npc_pos;
int npc_menu;

View File

@ -72,12 +72,12 @@ enum {
};
enum {
MSS_IDLE, // 待機
MSS_WALK, // 移動
MSS_ATTACK, // 攻撃
MSS_DEAD, // 死亡
MSS_LOOT, // ルート
MSS_CHASE, // 突撃
MSS_IDLE, // ?@
MSS_WALK, // ?
MSS_ATTACK, // U
MSS_DEAD, // S
MSS_LOOT, // [g
MSS_CHASE, // ?
};
int mobdb_searchname(const char *str);
@ -93,6 +93,8 @@ int mob_spawn_guardian(struct map_session_data *sd,char *mapname, // Spawning Gu
int mob_walktoxy(struct mob_data *md,int x,int y,int easy);
//int mob_randomwalk(struct mob_data *md,int tick);
//int mob_can_move(struct mob_data *md);
int mob_target(struct mob_data *md,struct block_list *bl,int dist);
int mob_stop_walking(struct mob_data *md,int type);

View File

@ -685,6 +685,7 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
sd->head_dir = 0;
sd->state.auth = 1;
sd->walktimer = -1;
sd->next_walktime = -1;
sd->attacktimer = -1;
sd->followtimer = -1; // [MouseJstr]
sd->skilltimer = -1;
@ -4211,6 +4212,40 @@ int pc_stop_walking(struct map_session_data *sd,int type)
return 0;
}
/*==========================================
* Random walk
*------------------------------------------
*/
int pc_randomwalk(struct map_session_data *sd,int tick)
{
const int retrycount = 20;
nullpo_retr(0, sd);
if(DIFF_TICK(sd->next_walktime,tick)<0){
int i,x,y,c,d;
d = rand()%7+5;
for(i=0;i<retrycount;i++){ // Search of a movable place
int r=rand();
x=sd->bl.x+r%(d*2+1)-d;
y=sd->bl.y+r/(d*2+1)%(d*2+1)-d;
if((c=map_getcell(sd->bl.m,x,y))!=1 && c!=5 && pc_walktoxy(sd,x,y)==0){
break;
}
}
// Working on this part later [celest]
/*for(i=c=0;i<sd->walkpath.path_len;i++){ // The next walk start time is calculated.
if(sd->walkpath.path[i]&1)
c+=sd->speed*14/10;
else
c+=sd->speed;
}
sd->next_walktime = (d=tick+rand()%3000+c);
return d;*/
return 1;
}
return 0;
}
/*==========================================
*
*------------------------------------------

View File

@ -57,6 +57,7 @@ int pc_setpos(struct map_session_data*,char*,int,int,int);
int pc_setsavepoint(struct map_session_data*,char*,int,int);
int pc_randomwarp(struct map_session_data *sd,int type);
int pc_memo(struct map_session_data *sd,int i);
int pc_randomwalk(struct map_session_data*,int tick);
int pc_checkadditem(struct map_session_data*,int,int);
int pc_inventoryblank(struct map_session_data*);

View File

@ -1,4 +1,4 @@
// $Id: skill.c,v 1.8 2004/12/3 7:53:42 PM Celestia Exp $
// $Id: skill.c,v 1.8 2004/12/7 9:42:00 PM Celestia Exp $
/* スキル?係 */
#include <stdio.h>
@ -3693,19 +3693,32 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case MG_STONECURSE: /* スト?ンカ?ス */
if (bl->type==BL_MOB && battle_get_mode(bl)&0x20) {
clif_skill_fail(sd,sd->skillid,0,0);
break;
{
// 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) {
clif_skill_fail(sd,sd->skillid,0,0);
break;
}
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)))
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;
clif_skill_fail(sd,skillid,0,0);
}
if (dstmd)
mob_target(dstmd,src,skill_get_range(skillid,skilllv));
if (sd && gem_flag) {
if ((i=pc_search_inventory(sd, skill_db[skillid].itemid[0])) < 0 ) {
clif_skill_fail(sd,sd->skillid,0,0);
break;
}
pc_delitem(sd, i, skill_db[skillid].amount[0], 0);
}
}
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)))
skill_status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
else if(sd)
clif_skill_fail(sd,skillid,0,0);
if (dstmd)
mob_target(dstmd,src,skill_get_range(skillid,skilllv));
break;
case NV_FIRSTAID: /* ?急手? */
@ -7204,7 +7217,9 @@ int skill_check_condition(struct map_session_data *sd,int type)
if(!(type&1))
return 1;
if(skill != AM_POTIONPITCHER) {
if(skill != AM_POTIONPITCHER &&
skill != CR_SLIMPITCHER &&
skill != MG_STONECURSE) {
if(skill == AL_WARP && !(type&2))
return 1;
for(i=0;i<10;i++) {
@ -8659,6 +8674,16 @@ int skill_status_change_end(struct block_list* bl, int type, int tid)
case SC_CURSE:
calc_flag = 1;
break;
// celest
case SC_CONFUSION:
{
struct map_session_data *sd=NULL;
if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){
sd->next_walktime = -1;
}
}
break;
}
if(bl->type==BL_PC && type<SC_SENDMAX)
@ -9195,9 +9220,31 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data)
bl->id, data);
}
break;
}
// Celest
case SC_CONFUSION:
{
int i = 3000;
//struct mob_data *md;
if (sd) {
pc_randomwalk (sd, gettick());
sd->next_walktime = tick + (i=1000 + rand()%1000);
} /*else if (bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->mode&1 && mob_can_move(md)) {
md->state.state=MS_WALK;
if( DIFF_TICK(md->next_walktime,tick) > + 7000 &&
(md->walkpath.path_len==0 || md->walkpath.path_pos>=md->walkpath.path_len) )
md->next_walktime = tick + 3000*rand()%2000;
mob_randomwalk(md,tick);
}*/
if ((sc_data[type].val2 -= 1000) > 0) {
sc_data[type].timer = add_timer(
i + tick, skill_status_change_timer,
bl->id, data);
return 0;
}
}
break;
}
return skill_status_change_end( bl,type,tid );
}
@ -9752,6 +9799,14 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val
tick = tick * sc_def / 100;
}
break;
case SC_CONFUSION:
val2 = tick;
tick = 100;
clif_emotion(bl,1);
if (sd) {
pc_stop_walking (sd, 0);
}
break;
case SC_BLIND: /* 暗? */
calc_flag = 1;
if(!(flag&2)) {