Преглед изворни кода

- Corrected traps
- Some minor changes to Hiding, Cloaking and Chasewalk
- Corrected Cannibalize
- Updated Marionette Control, Berserk
* Changed the weather gm commands to be able to toggle on and off
* Added Jawaii and Ayothaya to @go list
* Changed the default values for ranged, magic and misc damage rate in battle_athena
* Removed redundant 'berserkdamagetick'
* Added changes to map.h according to Shinomori
* Changed Parasite in mob_db

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@570 54d463be-8e91-2dee-dedb-b68131a5f0ec

celest пре 20 година
родитељ
комит
99bd6edb6e
8 измењених фајлова са 156 додато и 68 уклоњено
  1. 16 0
      Changelog.txt
  2. 3 3
      conf-tmpl/battle_athena.conf
  3. 2 0
      db/Changelog.txt
  4. 1 1
      db/mob_db.txt
  5. 53 27
      src/map/atcommand.c
  6. 3 2
      src/map/map.h
  7. 33 9
      src/map/pc.c
  8. 45 26
      src/map/skill.c

+ 16 - 0
Changelog.txt

@@ -1,4 +1,20 @@
 Date	Added
+12/15
+        * Skill Updates [celest]
+          - Corrected traps to last longer in GvG
+          - Some minor changes to Hiding, Cloaking and Chasewalk to prevent it from
+            not working if sc_data is null
+          - Corrected an error in Cannibalize
+          - Updated Marionette Control to check its range from the partner
+          - Updated Berserk to disable hp and sp regen for 5 minutes after the skill
+        * Changed the weather gm commands to be able to toggle on and off. For example,
+          use @snow once to turn it on, reuse it again to turn it off. [celest]
+        * Added Jawaii and Ayothaya to @go list [celest]
+        * Changed the default values for ranged, magic and misc damage rate in
+          battle_athena to 60, 50 and 60 [celest]
+        * Removed redundant 'berserkdamagetick' from map_session_data [celest]
+        * Added changes to map.h according to Shinomori [celest]
+
 12/14
 	* Changed "Map-server can't connect to char-server" message to reduce output spamming and set it to
 	  display only once [MC Cameri]

+ 3 - 3
conf-tmpl/battle_athena.conf

@@ -473,13 +473,13 @@ monster_cloak_check_type: no
 gvg_short_attack_damage_rate: 100
 
 // Ranged damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
-gvg_long_attack_damage_rate: 100
+gvg_long_attack_damage_rate: 60
 
 // Magic damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
-gvg_magic_attack_damage_rate: 100
+gvg_magic_attack_damage_rate: 50
 
 // Misc damage adjustments for WoE battles (Guild Vs Guild) (Note 2)
-gvg_misc_attack_damage_rate: 100
+gvg_misc_attack_damage_rate: 60
 
 // When the empelium is broken with WoE mode on, How Long Before The Declaration Of Castle Owner
 // and Removal of Monsters/Players from Castle. (in milliseconds)

+ 2 - 0
db/Changelog.txt

@@ -5,6 +5,8 @@
 	Ayathoya items == Added but no effect ( all are "ect" itens)
 	Skill databases == celest working on them i believe.
 
+12/14   * Changed 'Parasite' to non-moving [celest]
+
 12/12   * Removed unuseable skills from skill_tree.txt [celest]
 
 12/11   * Corrected item_db - Wedding rings should give all 3 skills [celest]

+ 1 - 1
db/mob_db.txt

@@ -494,7 +494,7 @@
 1497,WOODEN_GOLEM,Wooden Golem,51,9200,0,1926,1353,1,570,657,32,36,1,41,69,5,85,41,10,12,2,3,42,149,200,1152,1584,400,7188,6500,7189,5000,757,120,604,100,2270,3,921,1000,7201,900,0,0,0,0,0,0,0,0,0,0,,
 1498,WOODEN_SHOOTER,Wooden Shooter,39,3977,0,886,453,9,224,271,10,28,1,35,29,15,120,42,10,12,1,7,42,133,200,1152,1152,384,7049,1000,513,1000,7195,4500,7200,3500,512,100,512,0,512,0,512,0,0,0,0,0,0,0,0,0,,
 1499,WOODEN_FIGHTER,Wooden Fighter,41,4457,0,1790,833,1,395,480,30,19,1,41,31,10,67,30,10,12,1,7,43,149,200,1152,1152,384,517,4700,7196,4000,513,1000,7198,900,1801,5,1812,3,512,0,512,0,0,0,0,0,0,0,0,0,,
-1500,PARASITE,Parasite,37,3090,0,1098,478,9,175,215,5,19,1,40,20,10,90,25,10,12,1,3,44,149,200,1152,1152,384,7194,2000,7186,3500,7193,6700,711,2300,7198,1000,2270,20,1957,1,0,0,0,0,0,0,0,0,,
+1500,PARASITE,Parasite,37,3090,0,1098,478,9,175,215,5,19,1,40,20,10,90,25,10,12,1,3,44,148,200,1152,1152,384,7194,2000,7186,3500,7193,6700,711,2300,7198,1000,2270,20,1957,1,0,0,0,0,0,0,0,0,,
 1502,FIRE_PORING,Fire Poring,1,50,0,2,1,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,131,400,1872,672,480,909,7000,1202,100,938,400,512,1000,713,1500,741,5,619,20,4001,20,0,0,0,0,0,0,0,0,,
 1503,GIBBET,Gibbet,58,6841,0,4011,1824,3,238,418,28,31,1,42,42,27,46,28,10,12,2,6,27,149,150,1152,1584,400,7218,5500,7212,2000,7222,1000,604,100,716,100,724,10,512,0,512,0,0,0,0,0,0,0,0,0,,
 1504,DULLAHAN,Dullahan,62,12437,0,4517,2963,3,418,647,47,38,1,30,5,45,62,22,10,12,1,1,49,149,155,1152,1152,428,7210,5500,7209,2000,2505,100,2506,2,2614,5,512,0,512,0,512,0,0,0,0,0,0,0,0,0,,

+ 53 - 27
src/map/atcommand.c

@@ -2900,6 +2900,8 @@ int atcommand_go(
 	       { "louyang.gat",  217,  40  },	//	14=Lou Yang
 	       { "new_1-1.gat",   53, 111  },	//	15=Start point
 	       { "sec_pri.gat",   23,  61  },	//	16=Prison
+           { "jawaii.gat",   249, 127  },	//  17=Jawaii
+		   { "ayothaya.gat", 151, 117  },	//  18=Ayothaya
 	};
 
 	nullpo_retr(-1, sd);
@@ -2925,7 +2927,8 @@ int atcommand_go(
 		clif_displaymessage(fd, " 0=Prontera         7=Lutie         14=Lou Yang");
 		clif_displaymessage(fd, " 1=Morroc           8=Comodo        15=Start point");
 		clif_displaymessage(fd, " 2=Geffen           9=Yuno          16=Prison");
-		clif_displaymessage(fd, " 3=Payon           10=Amatsu");
+		clif_displaymessage(fd, " 3=Payon           10=Amatsu        17=Jawaii");
+		clif_displaymessage(fd, "                                    18=Ayothaya");
 		return -1;
 	} else {
 		// get possible name of the city and add .gat if not in the name
@@ -2980,6 +2983,12 @@ int atcommand_go(
 		           strncmp(map_name, "prison.gat", 3) == 0 || // name of the position (3 first characters)
 		           strncmp(map_name, "jails.gat", 3) == 0) { // name of the position
 			town = 16;
+		} else if (strncmp(map_name, "jawaii.gat", 3) == 0 || // 3 first characters
+		           strncmp(map_name, "jawai.gat", 3) == 0) { // writing error (3 first characters)
+			town = 17;
+		} else if (strncmp(map_name, "ayothaya.gat", 4) == 0 || // 3 first characters
+		           strncmp(map_name, "ayotaya.gat", 4) == 0) { // writing error (3 first characters)
+			town = 18;
 		}
 
 		if (town >= -3 && town <= -1) {
@@ -7601,11 +7610,14 @@ atcommand_rain(
 	int effno = 0;
 	nullpo_retr(-1, sd);
 	effno = 161;
-	if (effno < 0 || map[sd->bl.m].flag.rain)
-		return -1;
-
-	map[sd->bl.m].flag.rain=1;
-	clif_specialeffect(&sd->bl,effno,2);
+	if (map[sd->bl.m].flag.rain) {
+		map[sd->bl.m].flag.rain=0;
+		clif_displaymessage(fd, "The rain has stopped.");
+	} else {
+		map[sd->bl.m].flag.rain=1;
+		clif_specialeffect(&sd->bl,effno,2);
+		clif_displaymessage(fd, "It is made to rain.");		
+	}
 	return 0;
 }
 /*==========================================
@@ -7620,11 +7632,15 @@ atcommand_snow(
 	int effno = 0;
 	effno = 162;
 	nullpo_retr(-1, sd);
-	if (effno < 0 || map[sd->bl.m].flag.snow)
-		return -1;
-
-	map[sd->bl.m].flag.snow=1;
-	clif_specialeffect(&sd->bl,effno,2);
+	if (map[sd->bl.m].flag.snow) {
+		map[sd->bl.m].flag.snow=0;
+		clif_displaymessage(fd, "Snow has stopped falling.");
+	} else {
+		map[sd->bl.m].flag.snow=1;
+		clif_specialeffect(&sd->bl,effno,2);
+		clif_displaymessage(fd, "It is made to snow.");
+	}
+	
 	return 0;
 }
 
@@ -7640,11 +7656,14 @@ atcommand_sakura(
 	int effno = 0;
 	effno = 163;
 	nullpo_retr(-1, sd);
-	if (effno < 0 || map[sd->bl.m].flag.sakura)
-		return -1;
-
-	map[sd->bl.m].flag.sakura=1;
-	clif_specialeffect(&sd->bl,effno,2);
+	if (map[sd->bl.m].flag.sakura) {
+		map[sd->bl.m].flag.sakura=0;
+		clif_displaymessage(fd, "Cherry tree leaves is made to fall.");
+	} else {
+		map[sd->bl.m].flag.sakura=1;
+		clif_specialeffect(&sd->bl,effno,2);
+		clif_displaymessage(fd, "Cherry tree leaves is made to fall.");
+	}
 	return 0;
 }
 
@@ -7660,11 +7679,14 @@ atcommand_fog(
 	int effno = 0;
 	effno = 233;
 	nullpo_retr(-1, sd);
-	if (effno < 0 || map[sd->bl.m].flag.fog)
-		return -1;
-	
-	map[sd->bl.m].flag.fog=1;
-	clif_specialeffect(&sd->bl,effno,2);
+	if (map[sd->bl.m].flag.fog) {
+		map[sd->bl.m].flag.fog=0;
+		clif_displaymessage(fd, "The fog has gone.");
+	} else {
+		map[sd->bl.m].flag.fog=1;
+		clif_specialeffect(&sd->bl,effno,2);
+		clif_displaymessage(fd, "Fog hangs over.");
+	}
 
 	return 0;
 }
@@ -7681,11 +7703,15 @@ atcommand_leaves(
 	int effno = 0;
 	effno = 333;
 	nullpo_retr(-1, sd);
-	if (effno < 0 || map[sd->bl.m].flag.leaves)
-		return -1;
+	if (map[sd->bl.m].flag.leaves) {
+		map[sd->bl.m].flag.leaves=0;
+		clif_displaymessage(fd, "Leaves no longer fall.");
+	} else {
+		map[sd->bl.m].flag.leaves=1;
+		clif_specialeffect(&sd->bl,effno,2);
+		clif_displaymessage(fd, "Fallen leaves fall.");
+	}
 
-	map[sd->bl.m].flag.leaves=1;
-	clif_specialeffect(&sd->bl,effno,2);
 	return 0;
 }
 
@@ -7698,14 +7724,14 @@ atcommand_clearweather(
    const int fd, struct map_session_data* sd,
    const char* command, const char* message)
 {
-	int effno = 0;
+	//int effno = 0;
 	nullpo_retr(-1, sd);
 	map[sd->bl.m].flag.rain=0;
 	map[sd->bl.m].flag.snow=0;
 	map[sd->bl.m].flag.sakura=0;
 	map[sd->bl.m].flag.fog=0;
 	map[sd->bl.m].flag.leaves=0;
-	clif_specialeffect(&sd->bl,effno,2);
+	//clif_specialeffect(&sd->bl,effno,2); // not required. [celest]
 	return 0;
 } 
 

+ 3 - 2
src/map/map.h

@@ -212,10 +212,11 @@ struct map_session_data {
 	unsigned int canact_tick;
 	unsigned int canmove_tick;
 	unsigned int canlog_tick;
+	unsigned int canregen_tick;
 	int hp_sub,sp_sub;
 	int inchealhptick,inchealsptick,inchealspirithptick,inchealspiritsptick;
 // -- moonsoul (new tick for berserk self-damage)
-	int berserkdamagetick;
+//	int berserkdamagetick;
 	int fame;
 
 	short view_class;
@@ -481,8 +482,8 @@ enum { ATK_LUCKY=1,ATK_FLEE,ATK_DEF};	// 
 
 struct map_data {
 	char name[24];
-	char *alias; // [MouseJstr]
 	unsigned char *gat;	// NULL‚Ȃ牺‚Ìmap_data_other_server‚Æ‚µ‚Ĉµ‚¤
+	char *alias; // [MouseJstr]	
 	struct block_list **block;
 	struct block_list **block_mob;
 	int *block_count,*block_mob_count;

+ 33 - 9
src/map/pc.c

@@ -1559,15 +1559,18 @@ int pc_calcstatus(struct map_session_data* sd,int first)
 			sd->paramb[5]+= 5;
 		}
 		if(sd->sc_data[SC_MARIONETTE].timer!=-1){
-			sd->paramb[0]-= sd->status.str/2;	// bonuses not included
-			sd->paramb[1]-= sd->status.agi/2;
-			sd->paramb[2]-= sd->status.vit/2;
-			sd->paramb[3]-= sd->status.int_/2;
-			sd->paramb[4]-= sd->status.dex/2;
-			sd->paramb[5]-= sd->status.luk/2;
+			struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3);
+			if (psd) {	// if partner is found
+				sd->paramb[0]-= sd->status.str/2;	// bonuses not included
+				sd->paramb[1]-= sd->status.agi/2;
+				sd->paramb[2]-= sd->status.vit/2;
+				sd->paramb[3]-= sd->status.int_/2;
+				sd->paramb[4]-= sd->status.dex/2;
+				sd->paramb[5]-= sd->status.luk/2;
+			}
 		}
 		else if(sd->sc_data[SC_MARIONETTE2].timer!=-1){
-			struct map_session_data *psd = (struct map_session_data *)map_id2bl(sd->sc_data[SC_MARIONETTE2].val3);
+			struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3);
 			if (psd) {	// if partner is found
 				sd->paramb[0] += sd->status.str+psd->status.str/2 > 99 ? 99-sd->status.str : psd->status.str/2;
 				sd->paramb[1] += sd->status.agi+psd->status.agi/2 > 99 ? 99-sd->status.agi : psd->status.agi/2;
@@ -4080,6 +4083,7 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
 		sd->bl.y = y;
 		if(moveblock) map_addblock(&sd->bl);
 
+	#if 0
 		if (sd->status.guild_id > 0) {
 			struct skill_unit *su;
 			if (sd->sc_data[SC_LEADERSHIP].val4 && (su=(struct skill_unit *)sd->sc_data[SC_LEADERSHIP].val4)) {
@@ -4095,6 +4099,7 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
 				skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
 			}
 		}
+	#endif
 
 		map_foreachinmovearea(clif_pcinsight,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,0,sd);
 		sd->walktimer = -1;
@@ -4200,6 +4205,22 @@ int pc_walktoxy(struct map_session_data *sd,int x,int y)
 		pc_walktoxy_sub(sd);
 	}
 
+	if (sd->sc_data && sd->status.guild_id > 0) {
+		struct skill_unit *su;
+		if (sd->sc_data[SC_LEADERSHIP].val4 && (su=(struct skill_unit *)sd->sc_data[SC_LEADERSHIP].val4)) {
+			skill_unit_move_unit_group(su->group,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
+		}
+		if (sd->sc_data[SC_GLORYWOUNDS].val4 && (su=(struct skill_unit *)sd->sc_data[SC_GLORYWOUNDS].val4)) {
+			skill_unit_move_unit_group(su->group,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
+		}
+		if (sd->sc_data[SC_SOULCOLD].val4 && (su=(struct skill_unit *)sd->sc_data[SC_SOULCOLD].val4)) {
+			skill_unit_move_unit_group(su->group,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
+		}
+		if (sd->sc_data[SC_HAWKEYES].val4 && (su=(struct skill_unit *)sd->sc_data[SC_HAWKEYES].val4)) {
+			skill_unit_move_unit_group(su->group,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
+		}
+	}
+
 	return 0;
 }
 
@@ -7450,13 +7471,16 @@ static int pc_natural_heal_sub(struct map_session_data *sd,va_list ap) {
 	if ((battle_config.natural_heal_weight_rate > 100 || sd->weight*100/sd->max_weight < battle_config.natural_heal_weight_rate) &&
 		!pc_isdead(sd) && 
 		!pc_ishiding(sd) && 
-		!(sd->sc_data[SC_POISON].timer != -1 && sd->sc_data[SC_SLOWPOISON].timer == -1) &&
-		sd->sc_data[SC_BERSERK].timer == -1 ) {
+	//-- cannot regen for 5 minutes after using Berserk --- [Celest]
+		DIFF_TICK (gettick(), sd->canregen_tick)>=0 &&
+		(sd->sc_data && !(sd->sc_data[SC_POISON].timer != -1 && sd->sc_data[SC_SLOWPOISON].timer == -1) &&
+		sd->sc_data[SC_BERSERK].timer == -1 )) {
 		pc_natural_heal_hp(sd);
 		if( sd->sc_data && sd->sc_data[SC_EXTREMITYFIST].timer == -1 &&	//阿修羅?態ではSPが回復しない
 			sd->sc_data[SC_DANCING].timer == -1 && //ダンス?態ではSPが回復しない
 			sd->sc_data[SC_BERSERK].timer == -1 )   //バ?サ?ク?態ではSPが回復しない
 			pc_natural_heal_sp(sd);
+		sd->canregen_tick = gettick();
 	} else {
 		sd->hp_sub = sd->inchealhptick = 0;
 		sd->sp_sub = sd->inchealsptick = 0;

+ 45 - 26
src/map/skill.c

@@ -1,4 +1,4 @@
-// $Id: skill.c,v 1.8 2004/12/13 7:22:51 PM Celestia $
+// $Id: skill.c,v 1.8 2004/12/15 8:56:46 PM Celestia $
 /* スキル?係 */
 
 #include <stdio.h>
@@ -3579,14 +3579,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 			struct status_change *tsc_data = battle_get_sc_data(bl);
 			int sc=SkillStatusChangeTable[skillid];
 			clif_skill_nodamage(src,bl,skillid,-1,1);
-			if( tsc_data ){
-				if( tsc_data[sc].timer==-1 )
-				/* 付加する */
-				skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
-			else
+			if(tsc_data && tsc_data[sc].timer!=-1 )
 				/* 解除する */
 				skill_status_change_end(bl, sc, -1);
-		}
+			else
+				/* 付加する */
+				skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
 		}
 		break;
 
@@ -3595,14 +3593,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 			struct status_change *tsc_data = battle_get_sc_data(bl);
 			int sc=SkillStatusChangeTable[skillid];
 			clif_skill_nodamage(src,bl,skillid,skilllv,1);
-			if( tsc_data ){
-				if( tsc_data[sc].timer==-1 )
-				/* 付加する */
-				skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
-			else
+			if(tsc_data && tsc_data[sc].timer!=-1 )
 				/* 解除する */
 				skill_status_change_end(bl, sc, -1);
-			}
+			else
+				/* 付加する */
+				skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
 			//skill_check_cloaking(bl);
 		}
 		break;
@@ -3612,14 +3608,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 			struct status_change *tsc_data = battle_get_sc_data(bl);
 			int sc=SkillStatusChangeTable[skillid];
 			clif_skill_nodamage(src,bl,skillid,-1,1);
-			if( tsc_data ){
-				if( tsc_data[sc].timer==-1 )
-					/* 付加する */
-					skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
-				else
-					/* 解除する */
-					skill_status_change_end(bl, sc, -1);
-			}
+			if(tsc_data && tsc_data[sc].timer!=-1 )
+				/* 解除する */
+				skill_status_change_end(bl, sc, -1);
+			else
+				/* 付加する */
+				skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
 		}
 		break;
 
@@ -5060,7 +5054,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
 			mx = x;// + (rand()%10 - 5);
 			my = y;// + (rand()%10 - 5);
 			
-			id=mob_once_spawn(sd,"this",mx,my,"--ja--", summons[skilllv] ,1,"");
+			id=mob_once_spawn(sd,"this",mx,my,"--ja--", summons[skilllv-1] ,1,"");
 			if( (md=(struct mob_data *)map_id2bl(id)) !=NULL ){
 				md->master_id=sd->bl.id;
 				md->hp=2210+skilllv*200;
@@ -5359,6 +5353,8 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,
 	case HT_SANDMAN:			/* サンドマン */
 	case HT_CLAYMORETRAP:		/* クレイモア?トラップ */
 		limit=skill_get_time(skillid,skilllv);
+		// longer trap times in WOE [celest]
+		if (map[src->m].flag.gvg) limit *= 4;
 		range=2;
 		break;
 	case HT_SKIDTRAP:			/* スキッドトラップ */
@@ -5369,6 +5365,9 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,
 	case HT_FREEZINGTRAP:		/* フリ?ジングトラップ */
 	case HT_BLASTMINE:			/* ブラストマイン */
 		limit=skill_get_time(skillid,skilllv);
+		// longer trap times in WOE [celest]
+		if (skillid != PF_SPIDERWEB && map[src->m].flag.gvg)
+			limit *= 4;
 		range=1;
 		break;
 
@@ -7115,7 +7114,7 @@ int skill_check_condition(struct map_session_data *sd,int type)
 			int c=0;
 			int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
 			int maxcount = (skill==AM_CANNIBALIZE)? 6-lv : skill_get_maxcount(skill);
-			int mob_class = (skill==AM_CANNIBALIZE)? summons[lv] :1142;
+			int mob_class = (skill==AM_CANNIBALIZE)? summons[lv-1] :1142;
 			if(battle_config.pc_land_skill_limit && maxcount>0) {
 				map_foreachinarea(skill_check_condition_mob_master_sub ,sd->bl.m, 0, 0, map[sd->bl.m].xs, map[sd->bl.m].ys, BL_MOB, sd->bl.id, mob_class,&c );
 				if(c >= maxcount){
@@ -8670,7 +8669,7 @@ int skill_status_change_end(struct block_list* bl, int type, int tid)
 				break;
 			case SC_BERSERK:			/* バ?サ?ク */
 				calc_flag = 1;
-				clif_status_change(bl,SC_INCREASEAGI,0);	/* アイコン消去 */
+				clif_status_change(bl,SC_INCREASEAGI,0);	/* アイコン消去 */					
 				break;
 			case SC_DEVOTION:		/* ディボ?ション */
 				{
@@ -9292,6 +9291,21 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data)
 				return 0;
 		}
 		break;
+
+	case SC_MARIONETTE:		/* マリオネットコントロ?ル */
+	case SC_MARIONETTE2:
+		{
+			struct block_list *pbl = map_id2bl(sc_data[type].val3);
+			if (pbl && battle_check_range(bl, pbl, 7) &&
+				(sc_data[type].val2 -= 1000)>0) {
+				sc_data[type].timer = add_timer(
+					1000 + tick, skill_status_change_timer,
+					bl->id, data);
+					return 0;
+			}				
+		}
+		break;
+
 	case SC_LEADERSHIP:
 	case SC_GLORYWOUNDS:
 	case SC_SOULCOLD:
@@ -10038,10 +10052,11 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val
 		case SC_BERSERK:		/* バ?サ?ク */
 			if(sd){
 				sd->status.hp = sd->status.max_hp * 3;
-				sd->status.sp = 0;				
+				sd->status.sp = 0;
 				clif_updatestatus(sd,SP_HP);
 				clif_updatestatus(sd,SP_SP);
-				clif_status_change(bl,SC_INCREASEAGI,1);	/* アイコン表示 */				
+				clif_status_change(bl,SC_INCREASEAGI,1);	/* アイコン表示 */
+				sd->canregen_tick = gettick() + 300000;
 			}
 			*opt3 |= 128;
 			tick = 10000;
@@ -10060,6 +10075,10 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val
 
 		case SC_MARIONETTE:		/* マリオネットコントロ?ル */
 		case SC_MARIONETTE2:
+			val2 = tick;
+			if (!val3)
+				return 0;
+			tick = 1000;
 			calc_flag = 1;
 			*opt3 |= 1024;
 			break;