Explorar o código

* 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

celest %!s(int64=20) %!d(string=hai) anos
pai
achega
1f3ab48426
Modificáronse 7 ficheiros con 124 adicións e 24 borrados
  1. 5 0
      Changelog.txt
  2. 3 2
      src/map/clif.c
  3. 1 0
      src/map/map.h
  4. 8 6
      src/map/mob.h
  5. 35 0
      src/map/pc.c
  6. 1 0
      src/map/pc.h
  7. 71 16
      src/map/skill.c

+ 5 - 0
Changelog.txt

@@ -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]

+ 3 - 2
src/map/clif.c

@@ -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 ||	//バーサーク

+ 1 - 0
src/map/map.h

@@ -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;

+ 8 - 6
src/map/mob.h

@@ -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);

+ 35 - 0
src/map/pc.c

@@ -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;
+}
+
 /*==========================================
  *
  *------------------------------------------

+ 1 - 0
src/map/pc.h

@@ -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*);

+ 71 - 16
src/map/skill.c

@@ -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)) {