Browse Source

Bug Fixes
* Fixed mouse cursor displaying incorrectly for PvP scenarios. Thanks to Napster. (bugreport:8605)
* Fixed summons getting stuck when master gets too far off screen or changes maps. (bugreport:9152)
* Added a battle_config 'spawn_direction' for keeping a character's face direction when teleporting/changing maps/logging in. Default is always North (official). (bugreport:8754)
* Cast sensor mobs should always target the caster whenever any skill is used. (bugreport:8555)
* Added a packet version check to char_del_option based on client date. (bugreport:8521)
* Script command query_sql will now return -1 on an empty result or failed result. (bugreport:5937)

aleos89 10 years ago
parent
commit
60b0ed9c8b
9 changed files with 73 additions and 67 deletions
  1. 4 0
      conf/battle/client.conf
  2. 2 1
      conf/char_athena.conf
  3. 1 1
      doc/script_commands.txt
  4. 4 0
      src/char/char.c
  5. 1 0
      src/map/battle.c
  6. 1 0
      src/map/battle.h
  7. 22 21
      src/map/clif.c
  8. 2 2
      src/map/script.c
  9. 36 42
      src/map/unit.c

+ 4 - 0
conf/battle/client.conf

@@ -170,3 +170,7 @@ emblem_transparency_limit: 80
 //       So that will help client handling WPE - Maya Purple Hack stuff.
 //       But it will screw 'the game animation display' while players in invisible state.
 update_enemy_position: yes
+
+// When a player teleports, changes maps, or logs in, will they face the direction they were facing before warped?
+// Official: Disabled, players always face North.
+spawn_direction: no

+ 2 - 1
conf/char_athena.conf

@@ -155,8 +155,9 @@ char_del_delay: 86400
 // Restrict character deletion by email address or birthdate.
 // This restricts players from changing the langtype and deleting characters.
 // For birthdate, the client must be 20100803 or newer.
+// Defaults based on client date.
 // 1: Email address
-// 2: Birthdate (default)
+// 2: Birthdate
 // 3: Email address or Birthdate
 char_del_option: 2
 

+ 1 - 1
doc/script_commands.txt

@@ -7136,7 +7136,7 @@ Example:
 *query_logsql("your MySQL query"{, <array variable>{, <array variable>{, ...}}});
 
 Executes an SQL query. A 'select' query can fill array variables with up to 128 rows of values,
-and will return the number of rows (i.e. array size).
+and will return the number of rows (i.e. array size) or -1 on failure/empty array.
 
 Note that 'query_sql' runs on the main database while 'query_logsql' runs on the log database.
 

+ 4 - 0
src/char/char.c

@@ -2488,7 +2488,11 @@ void char_set_defaults(){
 	charserv_config.char_config.char_per_account = 0; //Maximum chars per account (default unlimited) [Sirius]
 	charserv_config.char_config.char_del_level = 0; //From which level u can delete character [Lupus]
 	charserv_config.char_config.char_del_delay = 86400;
+#if PACKETVER >= 20100803
 	charserv_config.char_config.char_del_option = 2;
+#else
+	charserv_config.char_config.char_del_option = 1;
+#endif
 
 //	charserv_config.userid[24];
 //	charserv_config.passwd[24];

+ 1 - 0
src/map/battle.c

@@ -7798,6 +7798,7 @@ static const struct _battle_data {
 	{ "mail_delay",                         &battle_config.mail_delay,                      1000,   1000,   INT_MAX,        },
 	{ "at_monsterignore",                   &battle_config.autotrade_monsterignore,         0,      0,      1,              },
 	{ "idletime_option",                    &battle_config.idletime_option,                 0x25,   1,      INT_MAX,        },
+	{ "spawn_direction",                    &battle_config.spawn_direction,                 0,      0,      1,              },
 };
 #ifndef STATS_OPT_OUT
 /**

+ 1 - 0
src/map/battle.h

@@ -566,6 +566,7 @@ extern struct Battle_Config
 	int mail_delay;
 	int autotrade_monsterignore;
 	int idletime_option;
+	int spawn_direction;
 } battle_config;
 
 void do_init_battle(void);

+ 22 - 21
src/map/clif.c

@@ -5726,27 +5726,27 @@ void clif_map_property(struct map_session_data* sd, enum map_property property)
 
 
 void clif_maptypeproperty2(struct block_list *bl,enum send_target t) {
-#if PACKETVER >= 20130000
-	uint8 buf[8];
-
-	WBUFW(buf,0)=0x99b; //2
-	WBUFW(buf,2)=0x28; //2
-
-	WBUFB(buf,4) = ((map_flag_vs(bl->m))?0x01:0); //tvt ?
-	WBUFB(buf,4) |= ((map_flag_gvg(bl->m))?0x02:0); //gvg
-	WBUFB(buf,4) |= ((map_flag_gvg2(bl->m))?0x04:0); //siege
-	WBUFB(buf,4) |= (map[bl->m].flag.nomineeffect || !map_flag_gvg2(bl->m))?0:0x08; //disable mine effect on nomineeffect map and enable it on gvgmap by default
-	WBUFB(buf,4) |= ((map[bl->m].flag.nolockon)?0x10:0); //nolockon 0x10 @FIXME what this do
-	WBUFB(buf,4) |= ((map[bl->m].flag.pvp)?0x20:0); //countpk
-	WBUFB(buf,4) |= 0; //nopartyformation 0x40
-	WBUFB(buf,4) |= ((map[bl->m].flag.battleground)?0x80:0); //battleground
-
-	WBUFB(buf,5) = ((map[bl->m].flag.noitemconsumption)?0x01:0); //noitemconsumption
-	WBUFB(buf,5) |= ((map[bl->m].flag.nousecart)?0:0x02); // usecart
-	WBUFB(buf,5) |= ((map[bl->m].flag.nosumstarmiracle)?0:0x04); //summonstarmiracle
-//	WBUFB(buf,5) |= RBUFB(buf,5)&0xf8;  //sparebit[0-4]
+#if PACKETVER >= 20121010
+	unsigned char buf[8];
 
-	WBUFW(buf,6) = 0; //sparebit [5-15], + extra[4]
+	unsigned int NotifyProperty =
+		((map[bl->m].flag.pvp?1:0)<<0)| // PARTY - Show attack cursor on non-party members (PvP)
+		((map_flag_gvg(bl->m)?1:0)<<1)| // GUILD - Show attack cursor on non-guild members (GvG)
+		((map_flag_gvg2(bl->m)?1:0)<<2)| // SIEGE - Show emblem over characters heads when in GvG (WoE castle)
+		((map[bl->m].flag.nomineeffect || !map_flag_gvg2(bl->m)?0:1)<<3)| // USE_SIMPLE_EFFECT - Automatically enable /mineffect
+		((map[bl->m].flag.nolockon?1:0)<<4)| // DISABLE_LOCKON - Unknown (By the name it might disable cursor lock-on)
+		((map[bl->m].flag.pvp?1:0)<<5)| // COUNT_PK - Show the PvP counter
+		((map[bl->m].flag.partylock?1:0)<<6)| // NO_PARTY_FORMATION - Prevents party creation/modification (Might be used for instance dungeons)
+		((map[bl->m].flag.battleground?1:0)<<7)| // BATTLEFIELD - Unknown (Does something for battlegrounds areas)
+		((map[bl->m].flag.noitemconsumption?1:0)<<8)| // DISABLE_COSTUMEITEM - Unknown - (Prevents wearing of costume items?)
+		((map[bl->m].flag.nousecart?0:1)<<9)| // USECART - Allow opening cart inventory (Well force it to always allow it)
+		((map[bl->m].flag.nosumstarmiracle?0:1)<<10); // SUNMOONSTAR_MIRACLE - Unknown - (Guessing it blocks Star Gladiator's Miracle from activating)
+		//(1<<11); // Unused bits. 1 - 10 is 0x1 length and 11 is 0x15 length. May be used for future settings.
+
+	WBUFW(buf,0)=0x99b;
+	WBUFW(buf,2)=0x28; // Type - What is it asking for? MAPPROPERTY? MAPTYPE? I don't know. Do we even need it? [Rytech]
+	WBUFL(buf,4)=NotifyProperty;
+	WBUFW(buf,6) = 0; // sparebit [5-15], + extra[4]
 
 	clif_send(buf,packet_len(0x99b),bl,t);
 #endif
@@ -9839,7 +9839,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		clif_clearunit_area(&sd->bl, CLR_DEAD);
 	else {
 		skill_usave_trigger(sd);
-		clif_changed_dir(&sd->bl, SELF);
+		if (battle_config.spawn_direction)
+			clif_changed_dir(&sd->bl, SELF);
 	}
 
 	// Trigger skill effects if you appear standing on them

+ 2 - 2
src/map/script.c

@@ -15344,13 +15344,13 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle)
 
 	if( SQL_ERROR == Sql_QueryStr(handle, query) ) {
 		Sql_ShowDebug(handle);
-		script_pushint(st, 0);
+		script_pushint(st, -1);
 		return 1;
 	}
 
 	if( Sql_NumRows(handle) == 0 ) { // No data received
 		Sql_FreeResult(handle);
-		script_pushint(st, 0);
+		script_pushint(st, -1);
 		return 0;
 	}
 

+ 36 - 42
src/map/unit.c

@@ -204,8 +204,9 @@ int unit_teleport_timer(int tid, unsigned int tick, int id, intptr_t data)
  */
 int unit_check_start_teleport_timer(struct block_list *sbl)
 {
-	TBL_PC *msd=NULL;
+	TBL_PC *msd = NULL;
 	int max_dist = 0;
+
 	switch(sbl->type) {
 		case BL_HOM:	
 		case BL_ELEM:	
@@ -216,7 +217,7 @@ int unit_check_start_teleport_timer(struct block_list *sbl)
 		default:
 			return 0;
 	}
-	
+
 	switch(sbl->type) {
 		case BL_HOM:	max_dist = AREA_SIZE;			break;
 		case BL_ELEM:	max_dist = MAX_ELEDISTANCE;		break;
@@ -319,17 +320,10 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
 				return 0;
 		} else
 			sd->areanpc_id=0;
-		/* WIP disable [Lighta], currently unsuported 
-		 * this was meant to start the timer if the player move but not his slave...
-		if(sd->md) unit_check_start_teleport_timer(&sd->md->bl);
-		if(sd->ed) unit_check_start_teleport_timer(&sd->ed->bl);
-		if(sd->hd) unit_check_start_teleport_timer(&sd->hd->bl);
-		if(sd->pd) unit_check_start_teleport_timer(&sd->pd->bl);
-		*/
 		pc_cell_basilica(sd);
 	}
 	break;
-	case BL_MOB: {
+	case BL_MOB:
 		if( map_getcell(bl->m,x,y,CELL_CHKNPC) ) {
 			if( npc_touch_areanpc2(md) )
 				return 0; // Warped
@@ -349,13 +343,6 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
 			// Resend walk packet for proper Self Destruction display.
 			clif_move(ud);
 		}
-	}
-	break;
-	case BL_HOM: 
-	case BL_ELEM:
-	case BL_PET:
-	case BL_MER:
-		unit_check_start_teleport_timer(bl);
 		break;
 	}
 
@@ -469,12 +456,16 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
 	struct unit_data* ud = NULL;
 	struct status_change* sc = NULL;
 	struct walkpath_data wpd;
+	TBL_PC *sd = NULL;
 
 	nullpo_ret(bl);
 
 	ud = unit_bl2ud(bl);
 
-	if( ud == NULL) return 0;
+	if (ud == NULL) return 0;
+
+	if (bl->type == BL_PC)
+		sd = BL_CAST(BL_PC, bl);
 
 	path_search(&wpd, bl->m, bl->x, bl->y, x, y, flag&1, CELL_CHKNOPASS); // Count walk path cells
 #ifdef OFFICIAL_WALKPATH
@@ -519,7 +510,13 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
 		delete_timer( ud->attacktimer, unit_attack_timer );
 		ud->attacktimer = INVALID_TIMER;
 	}
-	
+
+	// Start timer to recall summon
+	if (sd && sd->md) unit_check_start_teleport_timer(&sd->md->bl);
+	if (sd && sd->ed) unit_check_start_teleport_timer(&sd->ed->bl);
+	if (sd && sd->hd) unit_check_start_teleport_timer(&sd->hd->bl);
+	if (sd && sd->pd) unit_check_start_teleport_timer(&sd->pd->bl);
+
 	return unit_walktoxy_sub(bl);
 }
 
@@ -1544,31 +1541,28 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
 		unit_stop_walking(src,1);// Even though this is not how official works but this will do the trick. bugreport:6829
 	// In official this is triggered even if no cast time.
 	clif_skillcasting(src, src->id, target_id, 0,0, skill_id, skill_get_ele(skill_id, skill_lv), casttime);
-	if( casttime > 0 || combo ) {
-		if (sd && target->type == BL_MOB) {
-			TBL_MOB *md = (TBL_MOB*)target;
-			mobskill_event(md, src, tick, -1); // Cast targetted skill event.
-			if (tstatus->mode&(MD_CASTSENSOR_IDLE|MD_CASTSENSOR_CHASE) &&
-				battle_check_target(target, src, BCT_ENEMY) > 0)
-			{
-				switch (md->state.skillstate) {
-					case MSS_RUSH:
-					case MSS_FOLLOW:
-						if (!(tstatus->mode&MD_CASTSENSOR_CHASE))
-							break;
-						md->target_id = src->id;
-						md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
-						md->min_chase = md->db->range3;
+	if (sd && target->type == BL_MOB) {
+		TBL_MOB *md = (TBL_MOB*)target;
+
+		mobskill_event(md, src, tick, -1); // Cast targetted skill event.
+		if (tstatus->mode&(MD_CASTSENSOR_IDLE|MD_CASTSENSOR_CHASE) && battle_check_target(target, src, BCT_ENEMY) > 0) {
+			switch (md->state.skillstate) {
+				case MSS_RUSH:
+				case MSS_FOLLOW:
+					if (!(tstatus->mode&MD_CASTSENSOR_CHASE))
 						break;
-					case MSS_IDLE:
-					case MSS_WALK:
-						if (!(tstatus->mode&MD_CASTSENSOR_IDLE))
-							break;
-						md->target_id = src->id;
-						md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
-						md->min_chase = md->db->range3;
+					md->target_id = src->id;
+					md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
+					md->min_chase = md->db->range3;
+					break;
+				case MSS_IDLE:
+				case MSS_WALK:
+					if (!(tstatus->mode&MD_CASTSENSOR_IDLE))
 						break;
-				}
+					md->target_id = src->id;
+					md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
+					md->min_chase = md->db->range3;
+					break;
 			}
 		}
 	}