Forráskód Böngészése

- Fixed txt-converter compilation.
- Added my_global.h include to login converter
- Removed sd->char_id since we can use sd->status.char_id instead.
- Small speedup in STRECOVERY, and made it not unlock a mob's target.
- Fixed GS_GROUNDDRIFT consuming ammo when it's time expires (so it was consuming 2 grenades instead of one). Also added a "explosion effect" when their time runs out.
- gvg_dungeon mapflag won't set pvp related mapflags anymore, pc_dead will force pvp ranking gain/loss on gvg_dungeon maps now.
- Now when coming out of hiding land-effects will trigger on the character.
- Made the pc_setpos message when being placed on an unwalkable tile tell you which player triggered it.
- Fixed land effects not taking effect inmediately on map-load when the invincible timer is disabled.


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

skotlex 18 éve
szülő
commit
2de8486627

+ 13 - 0
Changelog-Trunk.txt

@@ -3,6 +3,19 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2006/12/01
+	* Fixed txt-converter compilation. [Skotlex]
+	* STRECOVERYno longer makes a mob unlock it's target like Cure does.
+	  [Skotlex]
+	* Fixed GS_GROUNDDRIFT consuming ammo when it's time expires (so it was
+	  consuming 2 grenades instead of one). Also added a "explosion effect" when
+	  their time runs out. [Skotlex]
+	* gvg_dungeon mapflag won't set pvp related mapflags anymore, pc_dead will
+	  force pvp ranking gain/loss on gvg_dungeon maps now. [Skotlex]
+	* Now when coming out of hiding land-effects will trigger on the character.
+	  [Skotlex]
+	* Fixed land effects not taking effect inmediately on map-load when the
+	  invincible timer is disabled. [Skotlex]
 2006/11/29
 	* Probably fixed the Segmentation Faults we've been having. [FlavioJS]
 	  Description: A player quits and it's session is freed and set to NULL, 

+ 2 - 2
src/char/char.c

@@ -4121,13 +4121,13 @@ int char_config_read(const char *cfgName) {
 		remove_control_chars((unsigned char *)w2);
 		if(strcmpi(w1,"timestamp_format") == 0) {
 			strncpy(timestamp_format, w2, 20);
-		} else if(strcmpi(w1,"stdout_with_ansisequence")==0){
-			stdout_with_ansisequence = config_switch(w2);
 		} else if(strcmpi(w1,"console_silent")==0){
 			msg_silent = 0; //To always allow the next line to show up.
 			ShowInfo("Console Silent Setting: %d\n", atoi(w2));
 			msg_silent = atoi(w2);
 #ifndef TXT_SQL_CONVERT
+		} else if(strcmpi(w1,"stdout_with_ansisequence")==0){
+			stdout_with_ansisequence = config_switch(w2);
 		} else if (strcmpi(w1, "userid") == 0) {
 			strncpy(userid, w2, 24);
 		} else if (strcmpi(w1, "passwd") == 0) {

+ 2 - 2
src/char_sql/char.c

@@ -4050,12 +4050,12 @@ int char_config_read(const char *cfgName) {
 		remove_control_chars((unsigned char *) w2);
 		if(strcmpi(w1,"timestamp_format")==0) {
 			strncpy(timestamp_format, w2, 20);
-		} else if(strcmpi(w1,"stdout_with_ansisequence")==0){
-			stdout_with_ansisequence = config_switch(w2);
 		} else if(strcmpi(w1,"console_silent")==0){
 			msg_silent = 0; //To always allow the next line to show up.
 			ShowInfo("Console Silent Setting: %d\n", atoi(w2));
 			msg_silent = atoi(w2);
+		} else if(strcmpi(w1,"stdout_with_ansisequence")==0){
+			stdout_with_ansisequence = config_switch(w2);
 		} else if (strcmpi(w1, "userid") == 0) {
 			strncpy(userid, w2, 24);
 		} else if (strcmpi(w1, "passwd") == 0) {

+ 2 - 2
src/map/atcommand.c

@@ -3702,8 +3702,8 @@ int atcommand_produce(
 		tmp_item.card[0] = CARD0_FORGE;
 		tmp_item.card[1] = item_data->type==IT_WEAPON?
 			((star*5) << 8) + attribute:0;
-		tmp_item.card[2] = GetWord(sd->char_id, 0);
-		tmp_item.card[3] = GetWord(sd->char_id, 1);
+		tmp_item.card[2] = GetWord(sd->status.char_id, 0);
+		tmp_item.card[3] = GetWord(sd->status.char_id, 1);
 		clif_produceeffect(sd, 0, item_id);
 		clif_misceffect(&sd->bl, 3);
 

+ 5 - 5
src/map/chrif.c

@@ -211,7 +211,7 @@ int chrif_save(struct map_session_data *sd, int flag)
 		intif_saveregistry(sd, 1); //Save account2 regs
 #ifndef TXT_ONLY
 	if(charsave_method){ //New 'Local' save
-		charsave_savechar(sd->char_id, &sd->status);
+		charsave_savechar(sd->status.char_id, &sd->status);
 		if (flag) //Character final saved.
 			sd->state.finalsave = 1;
 		if (flag == 1)
@@ -222,8 +222,8 @@ int chrif_save(struct map_session_data *sd, int flag)
 	WFIFOHEAD(char_fd, sizeof(sd->status) + 13);
 	WFIFOW(char_fd,0) = 0x2b01;
 	WFIFOW(char_fd,2) = sizeof(sd->status) + 13;
-	WFIFOL(char_fd,4) = sd->bl.id;
-	WFIFOL(char_fd,8) = sd->char_id;
+	WFIFOL(char_fd,4) = sd->status.account_id;
+	WFIFOL(char_fd,8) = sd->status.char_id;
 	WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting.
 	memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status));
 	WFIFOSET(char_fd, WFIFOW(char_fd,2));
@@ -1147,10 +1147,10 @@ int chrif_updatefamelist(struct map_session_data *sd)
 
 	WFIFOHEAD(char_fd, 12);
 	WFIFOW(char_fd, 0) = 0x2b10;
-	WFIFOL(char_fd, 2) = sd->char_id;
+	WFIFOL(char_fd, 2) = sd->status.char_id;
 	WFIFOL(char_fd, 6) = sd->status.fame;
 	WFIFOB(char_fd, 10) = type;
-	WFIFOB(char_fd, 11) = pc_famerank(sd->char_id, sd->class_&MAPID_UPPERMASK);
+	WFIFOB(char_fd, 11) = pc_famerank(sd->status.char_id, sd->class_&MAPID_UPPERMASK);
 	WFIFOSET(char_fd, 12);
 
 	return 0;

+ 13 - 4
src/map/clif.c

@@ -8316,7 +8316,6 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		else
 			pc_setinvincibletimer(sd,battle_config.pc_invincible_time);
 	}
-
 	map_addblock(&sd->bl);	// ƒuƒ�ƒbƒN“o˜^
 	clif_spawn(&sd->bl);	// spawn
 
@@ -8347,7 +8346,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 	if(sd->duel_group)
 		clif_set0199(fd, 1);
 
-	if(map_flag_gvg(sd->bl.m) || map[sd->bl.m].flag.gvg_dungeon)
+	if (map[sd->bl.m].flag.gvg_dungeon)
+		clif_set0199(fd,2); //TODO: Figure out the real thing to do here.
+
+	if(map_flag_gvg(sd->bl.m))
 		clif_set0199(fd,3);
 
 	// pet
@@ -8357,6 +8359,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		clif_send_petdata(sd,0,0);
 		clif_send_petdata(sd,5,battle_config.pet_hair_style);
 		clif_send_petstatus(sd);
+//		skill_unit_move(&sd->pd->bl,gettick(),1);
 	}
 
 	//homunculus [blackhole89]
@@ -8370,6 +8373,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		//Homunc mimic their master's speed on each map change. [Skotlex]
 		if (battle_config.slaves_inherit_speed&1)
 			status_calc_bl(&sd->hd->bl, SCB_SPEED);
+//		Since hom is inmune to land effects, unneeded.
+//		skill_unit_move(&sd->hd->bl,gettick(),1);
 	}
 
 	if(sd->state.connect_new) {
@@ -8474,9 +8479,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
   	// If player is dead, and is spawned (such as @refresh) send death packet. [Valaris]
 	if(pc_isdead(sd))
 		clif_clearchar_area(&sd->bl,1);
+
 // Uncomment if you want to make player face in the same direction he was facing right before warping. [Skotlex]
 //	else
 //		clif_changed_dir(&sd->bl, SELF);
+//	Trigger skill effects if you appear standing on them
+	if(!battle_config.pc_invincible_time)
+		skill_unit_move(&sd->bl,gettick(),1);
 }
 
 /*==========================================
@@ -10912,7 +10921,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) {
 				if (pc_isGM(sd) > pc_isGM(tsd)) {
 					clif_GM_kick(sd, tsd, 1);
 					if((log_config.gm) && (get_atcommand_level(AtCommand_Kick) >= log_config.gm)) {
-						sprintf(message, "/kick %d", ((struct map_session_data*)target)->char_id);
+						sprintf(message, "/kick %d", tsd->status.char_id);
 						log_atcommand(sd, message);
 					}
 				} else
@@ -11832,7 +11841,7 @@ int clif_parse(int fd) {
 				clif_quitsave(fd, sd);
 			} else {
 				ShowInfo("Player AID:%d/CID:%d (not authenticated) logged off.\n",
-					sd->bl.id, sd->char_id);
+					sd->bl.id, sd->status.char_id);
 				map_quit(sd);
 			}
 		} else {

+ 1 - 1
src/map/guild.c

@@ -937,7 +937,7 @@ int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int onlin
 	if(idx == -1 || c == 0) {
 		// ギルドのメンバー外なので追放扱いする
 		struct map_session_data *sd = map_id2sd(account_id);
-		if(sd && sd->char_id == char_id) {
+		if(sd && sd->status.char_id == char_id) {
 			sd->status.guild_id=0;
 			sd->guild_emblem_id=0;
 			sd->state.guild_sent=0;

+ 5 - 5
src/map/log.c

@@ -120,11 +120,11 @@ int log_pick_pc(struct map_session_data *sd, const char *type, int nameid, int a
 		if (itm==NULL) {
 		//We log common item
 			sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%s')",
-			 log_config.log_pick_db, sd->char_id, type, nameid, amount, mapname);
+			 log_config.log_pick_db, sd->status.char_id, type, nameid, amount, mapname);
 		} else {
 		//We log Extended item
 			sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
-			 log_config.log_pick_db, sd->char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname);
+			 log_config.log_pick_db, sd->status.char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname);
 		}
 
 		if(mysql_query(&logmysql_handle, tmp_sql))
@@ -144,12 +144,12 @@ int log_pick_pc(struct map_session_data *sd, const char *type, int nameid, int a
 	if (itm==NULL) {
 	//We log common item
 		fprintf(logfp,"%s - %d\t%s\t%d,%d,%s%s",
-			timestring, sd->char_id, type, nameid, amount, mapname, RETCODE);
+			timestring, sd->status.char_id, type, nameid, amount, mapname, RETCODE);
 
 	} else {
 	//We log Extended item
 		fprintf(logfp,"%s - %d\t%s\t%d,%d,%d,%d,%d,%d,%d,%s%s",
-			timestring, sd->char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname, RETCODE);
+			timestring, sd->status.char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname, RETCODE);
 	}
 	fclose(logfp);
 	return 1; //Logged
@@ -223,7 +223,7 @@ int log_zeny(struct map_session_data *sd, char *type, struct map_session_data *s
 	if(log_config.sql_logs > 0)
 	{
 		sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%s')",
-			 log_config.log_zeny_db, sd->char_id, src_sd->char_id, type, amount, mapindex_id2name(sd->mapindex));
+			 log_config.log_zeny_db, sd->status.char_id, src_sd->status.char_id, type, amount, mapindex_id2name(sd->mapindex));
 		if(mysql_query(&logmysql_handle, tmp_sql))
 		{
 			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));

+ 1 - 1
src/map/map.h

@@ -610,7 +610,7 @@ struct map_session_data {
 		unsigned intravision : 1; // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
 		unsigned perfect_hiding : 1; // [Valaris]
 	} special_state;
-	int char_id, login_id1, login_id2, sex;
+	int login_id1, login_id2, sex;
 	unsigned short class_;	//This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex]
 
 	int packet_ver;  // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18

+ 2 - 2
src/map/mercenary.c

@@ -622,10 +622,10 @@ int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag)
 	sd = map_id2sd(account_id);
 	if(!sd)
 		return 0;
-	if (sd->char_id != sh->char_id)
+	if (sd->status.char_id != sh->char_id)
 	{
 		if (sd->status.hom_id == sh->hom_id)
-			sh->char_id = sd->char_id; //Correct char id.
+			sh->char_id = sd->status.char_id; //Correct char id.
 		else
 			return 0;
 	}

+ 1 - 4
src/map/npc.c

@@ -2452,10 +2452,7 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4)
 	}
 	else if (strcmpi(w3,"gvg_dungeon")==0) {
 		map[m].flag.gvg_dungeon=state;
-		map[m].flag.pvp=state;
-		map[m].flag.pvp_noparty=!state;
-		map[m].flag.pvp_noguild=!state;
-		map[m].flag.pvp_nocalcrank=state;
+		if (state) map[m].flag.pvp=0;
 	}
 	else if (strcmpi(w3,"gvg_castle")==0) {
 		map[m].flag.gvg_castle=state;

+ 8 - 7
src/map/pc.c

@@ -358,7 +358,8 @@ int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int lo
 	nullpo_retr(0, sd);
 
 	sd->bl.id        = account_id;
-	sd->char_id      = char_id;
+	sd->status.char_id      = account_id;
+	sd->status.char_id      = char_id;
 	sd->login_id1    = login_id1;
 	sd->login_id2    = 0; // at this point, we can not know the value :(
 	sd->client_tick  = client_tick;
@@ -970,7 +971,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
 			}
 		}
 	} while(flag);
-	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->char_id, MAPID_TAEKWON)) {
+	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON)) {
 		//Grant all Taekwon Tree, but only as bonus skills in case they drop from ranking. [Skotlex]
 		for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0;i++){
 			if ((skill_get_inf2(id)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)))
@@ -3357,7 +3358,7 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
 	){ //It is allowed on top of Moonlight/icewall tiles to prevent force-warping 'cheats' [Skotlex]
 		if(x||y) {
 			if(battle_config.error_log)
-				ShowError("pc_setpos: attempt to place player on non-walkable tile (%s-%d,%d)\n",mapindex_id2name(mapindex),x,y);
+				ShowError("pc_setpos: attempt to place player %s (%d:%d) on non-walkable tile (%s-%d,%d)\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex),x,y);
 		}
 		do {
 			x=rand()%(map[m].xs-2)+1;
@@ -4952,8 +4953,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 		item_tmp.identify=1;
 		item_tmp.card[0]=CARD0_CREATE;
 		item_tmp.card[1]=0;
-		item_tmp.card[2]=GetWord(sd->char_id,0); // CharId
-		item_tmp.card[3]=GetWord(sd->char_id,1);
+		item_tmp.card[2]=GetWord(sd->status.char_id,0); // CharId
+		item_tmp.card[3]=GetWord(sd->status.char_id,1);
 		map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
 	}
 
@@ -5071,8 +5072,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 	}
 	// pvp
 	// disable certain pvp functions on pk_mode [Valaris]
-	if (map[sd->bl.m].flag.pvp && !battle_config.pk_mode &&
-		(!map[sd->bl.m].flag.pvp_nocalcrank || map[sd->bl.m].flag.gvg_dungeon))
+	if (map[sd->bl.m].flag.gvg_dungeon ||
+		(map[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map[sd->bl.m].flag.pvp_nocalcrank))
 	{	//Pvp points always take effect on gvg_dungeon maps.
 		sd->pvp_point -= 5;
 		sd->pvp_lost++;

+ 4 - 4
src/map/script.c

@@ -2574,7 +2574,7 @@ int run_script_timer(int tid, unsigned int tick, int id, int data)
 	struct linkdb_node *node    = (struct linkdb_node *)sleep_db;
 	struct map_session_data *sd = map_id2sd(st->rid);
 
-	if((sd && sd->char_id != id) || (st->rid && !sd))
+	if((sd && sd->status.char_id != id) || (st->rid && !sd))
 	{	//Character mismatch. Cancel execution.
 		st->rid = 0;
 		st->state = END;
@@ -2722,7 +2722,7 @@ void run_script_main(struct script_state *st)
 
 	if(st->sleep.tick > 0) {
 		//Delay execution
-		st->sleep.charid = sd?sd->char_id:0;
+		st->sleep.charid = sd?sd->status.char_id:0;
 		st->sleep.timer  = add_timer(gettick()+st->sleep.tick,
 			run_script_timer, st->sleep.charid, (int)st);
 		linkdb_insert(&sleep_db, (void*)st->oid, st);
@@ -6184,7 +6184,7 @@ int buildin_successrefitem(struct script_state *st)
 		clif_misceffect(&sd->bl,3);
 		if(sd->status.inventory[i].refine == MAX_REFINE &&
 			sd->status.inventory[i].card[0] == CARD0_FORGE &&
-		  	sd->char_id == MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])
+		  	sd->status.char_id == MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])
 		){ // Fame point system [DracoRPG]
 	 		switch (sd->inventory_data[i]->wlv){
 				case 1:
@@ -12480,7 +12480,7 @@ int buildin_awake(struct script_state *st)
 				node = node->next;
 				continue;
 			}
-			if((sd && sd->char_id != tst->sleep.charid) || (tst->rid && !sd))
+			if((sd && sd->status.char_id != tst->sleep.charid) || (tst->rid && !sd))
 			{	//Cancel Execution
 				tst->state=END;
 				tst->rid = 0;

+ 26 - 32
src/map/skill.c

@@ -1944,7 +1944,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 			case TK_STORMKICK:
 			case TK_DOWNKICK:
 			case TK_COUNTER:
-				if (pc_famerank(sd->char_id,MAPID_TAEKWON))
+				if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
 			  	{	//Extend combo time.
 					sd->skillid_old = skillid; //Set as previous so you can't repeat
 					sd->skilllv_old = skilllv;
@@ -4132,9 +4132,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			if (!dstsd || !(
 				(sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_SOULLINKER) ||
 				(dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER ||
-				dstsd->char_id == sd->char_id ||
-				dstsd->char_id == sd->status.partner_id ||
-				dstsd->char_id == sd->status.child
+				dstsd->status.char_id == sd->status.char_id ||
+				dstsd->status.char_id == sd->status.partner_id ||
+				dstsd->status.char_id == sd->status.child
 			)) {
 				status_change_start(src,SC_STUN,10000,skilllv,0,0,0,500,8);
 				clif_skill_fail(sd,skillid,0,0);
@@ -4306,10 +4306,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			clif_skill_nodamage(src,bl,skillid,skilllv,0);
 			break;
 		}
-		status_change_end(bl, SC_FREEZE	, -1 );
-		status_change_end(bl, SC_STONE	, -1 );
-		status_change_end(bl, SC_SLEEP	, -1 );
-		status_change_end(bl, SC_STUN	, -1 );
+		if (tsc && tsc->opt1) {
+			status_change_end(bl, SC_FREEZE, -1 );
+			status_change_end(bl, SC_STONE, -1 );
+			status_change_end(bl, SC_SLEEP, -1 );
+			status_change_end(bl, SC_STUN, -1 );
+		}
 		//Is this equation really right? It looks so... special.
 		if(battle_check_undead(tstatus->race,tstatus->def_ele) )
 		{
@@ -4319,8 +4321,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				skill_get_time2(skillid, skilllv) * (100-(tstatus->int_+tstatus->vit)/2)/100,10);
 		}
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		if(dstmd)
-			mob_unlocktarget(dstmd,tick);
 		break;
 
 	case WZ_ESTIMATION:
@@ -6772,7 +6772,8 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid,
 	group->bl_flag= skill_get_unit_bl_target(skillid);
 	group->state.into_abyss = (sc && sc->data[SC_INTOABYSS].timer != -1); //Store into abyss state, to know it shouldn't give traps back. [Skotlex]
 	group->state.magic_power = (flag&2 || (sc && sc->data[SC_MAGICPOWER].timer != -1)); //Store the magic power flag. [Skotlex]
-	group->state.ammo_consume = (sd && sd->state.arrow_atk); //Store if this skill needs to consume ammo.
+	//Store if this skill needs to consume ammo.
+	group->state.ammo_consume = (sd && sd->state.arrow_atk && skillid != GS_GROUNDDRIFT);
 	group->state.song_dance = (unit_flag&(UF_DANCE|UF_SONG)?1:0)|(unit_flag&UF_ENSEMBLE?2:0); //Signals if this is a song/dance/duet
 
   	//if tick is greater than current, do not invoke onplace function just yet. [Skotlex]
@@ -8151,7 +8152,7 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t
 			return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
 		if(!sc || sc->data[SC_COMBO].timer == -1)
 			return 0; //Combo needs to be ready
-		if (pc_famerank(sd->char_id,MAPID_TAEKWON))
+		if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
 		{	//Unlimited Combo
 			if (skill == sd->skillid_old) {
 				status_change_end(&sd->bl, SC_COMBO, -1);
@@ -8971,7 +8972,7 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
 				clif_misceffect(&sd->bl,3);
 				if(item->refine == MAX_REFINE &&
 					item->card[0] == CARD0_FORGE &&
-					MakeDWord(item->card[2],item->card[3]) == sd->char_id)
+					MakeDWord(item->card[2],item->card[3]) == sd->status.char_id)
 				{ // Fame point system [DracoRPG]
 					switch(ditem->wlv){
 						case 1:
@@ -10045,8 +10046,13 @@ int skill_unit_timer_sub (struct block_list *bl, va_list ap)
 	if((DIFF_TICK(tick,group->tick)>=group->limit || DIFF_TICK(tick,group->tick)>=unit->limit)){
 		switch(group->unit_id){
 			case UNT_BLASTMINE:
+			case UNT_GROUNDDRIFT_WIND:
+			case UNT_GROUNDDRIFT_DARK:
+			case UNT_GROUNDDRIFT_POISON:
+			case UNT_GROUNDDRIFT_WATER:
+			case UNT_GROUNDDRIFT_FIRE:
 				group->unit_id = UNT_USED_TRAPS;
-				clif_changetraplook(bl, UNT_USED_TRAPS);
+				clif_changetraplook(bl, UNT_FIREPILLAR_ACTIVE);
 				group->limit=DIFF_TICK(tick+1500,group->tick);
 				unit->limit=DIFF_TICK(tick+1500,group->tick);
 				break;
@@ -10072,18 +10078,6 @@ int skill_unit_timer_sub (struct block_list *bl, va_list ap)
 					skill_delunit(unit, 0);
 				}
 				break;
-
-			case 0xc1:
-			case 0xc2:
-			case 0xc3:
-			case 0xc4:
-				{
-					struct block_list *src=map_id2bl(group->src_id);
-					if (src)
-						group->tick = tick;
-				}
-				break;
-
 			default:
 				skill_delunit(unit, 0);
 		}
@@ -10617,8 +10611,8 @@ int skill_produce_mix (struct map_session_data *sd, int skill_id, int nameid, in
 		if(equip){
 			tmp_item.card[0]=CARD0_FORGE;
 			tmp_item.card[1]=((sc*5)<<8)+ele;
-			tmp_item.card[2]=GetWord(sd->char_id,0); // CharId
-			tmp_item.card[3]=GetWord(sd->char_id,1);
+			tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
+			tmp_item.card[3]=GetWord(sd->status.char_id,1);
 		} else {
 			//Flag is only used on the end, so it can be used here. [Skotlex]
 			switch (skill_id) {
@@ -10641,8 +10635,8 @@ int skill_produce_mix (struct map_session_data *sd, int skill_id, int nameid, in
 			if (flag) {
 				tmp_item.card[0]=CARD0_CREATE;
 				tmp_item.card[1]=0;
-				tmp_item.card[2]=GetWord(sd->char_id,0); // CharId
-				tmp_item.card[3]=GetWord(sd->char_id,1);
+				tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
+				tmp_item.card[3]=GetWord(sd->status.char_id,1);
 			}
 		}
 
@@ -10785,8 +10779,8 @@ int skill_arrow_create (struct map_session_data *sd, int nameid)
 		if(battle_config.making_arrow_name_input) {
 			tmp_item.card[0]=CARD0_CREATE;
 			tmp_item.card[1]=0;
-			tmp_item.card[2]=GetWord(sd->char_id,0); // CharId
-			tmp_item.card[3]=GetWord(sd->char_id,1);
+			tmp_item.card[2]=GetWord(sd->status.char_id,0); // CharId
+			tmp_item.card[3]=GetWord(sd->status.char_id,1);
 		}
 		if(tmp_item.nameid <= 0 || tmp_item.amount <= 0)
 			continue;

+ 9 - 6
src/map/status.c

@@ -1494,7 +1494,7 @@ static unsigned int status_base_pc_maxhp(struct map_session_data* sd, struct sta
 		val += val * 25/100;
 	else if (sd->class_&JOBL_BABY)
 		val -= val * 30/100;
-	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->char_id, MAPID_TAEKWON))
+	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
 		val *= 3; //Triple max HP for top ranking Taekwons over level 90.
 	if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
 		val += 2000;
@@ -1511,7 +1511,7 @@ static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct sta
 		val += val * 25/100;
 	else if (sd->class_&JOBL_BABY)
 		val -= val * 30/100;
-	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->char_id, MAPID_TAEKWON))
+	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
 		val *= 3; //Triple max SP for top ranking Taekwons over level 90.
 	
 	return val;
@@ -6254,15 +6254,15 @@ int status_change_end( struct block_list* bl , int type,int tid )
 
 	case SC_HIDING:
 		sc->option &= ~OPTION_HIDE;
-		opt_flag = 2; //Check for warp trigger.
+		opt_flag|= 2|4; //Check for warp trigger + AoE trigger
 		break;
 	case SC_CLOAKING:
 		sc->option &= ~OPTION_CLOAK;
-		opt_flag = 2;
+		opt_flag|= 2;
 		break;
 	case SC_CHASEWALK:
 		sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
-		opt_flag = 2;
+		opt_flag|= 2;
 		break;
 	case SC_SIGHT:
 		sc->option &= ~OPTION_SIGHT;
@@ -6364,7 +6364,10 @@ int status_change_end( struct block_list* bl , int type,int tid )
 	if (calc_flag)
 		status_calc_bl(bl,calc_flag);
 
-	if(opt_flag == 2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
+	if(opt_flag&4) //Out of hiding, invoke on place.
+		skill_unit_move(bl,gettick(),1);
+
+	if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
 		npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event.
 
 	return 1;

+ 1 - 0
src/txt-converter/login-converter.c

@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <my_global.h>
 #include <mysql.h>
 
 #include "../common/core.h"