Browse Source

Updated Giant Fly Wing behavior (#2098)

* Party members should be recalled to their own positions in a 3x3 area around the party leader.
* Added two missing client messages.
* Adjusted script command warpparty to support range values.
* Adjusted script command warpparty to not warp the party leader if "Leader" is passed as the map.
Aleos 8 năm trước cách đây
mục cha
commit
10b512b859
5 tập tin đã thay đổi với 55 bổ sung13 xóa
  1. 7 3
      doc/script_commands.txt
  2. 3 5
      npc/other/CashShop_Functions.txt
  3. 2 0
      src/map/clif.h
  4. 23 0
      src/map/pc.c
  5. 20 5
      src/map/script.c

+ 7 - 3
doc/script_commands.txt

@@ -3916,9 +3916,9 @@ current map if you give the 'to map name' as "Random".
 See also 'warp'.
 
 ---------------------------------------
- 
-*warpparty "<to_mapname>",<x>,<y>,<party_id>,{"<from_mapname>"};
- 
+
+*warpparty "<to_mapname>",<x>,<y>,<party_id>,{"<from_mapname>",<range x>,<range y>};
+
 Warps a party to specified map and coordinate given the party ID, which you can get with
 getcharid(1). You can also request another party id given a member's name with getcharid(1,<player_name>).
 
@@ -3933,6 +3933,10 @@ Leader:       All party members are warped to the leader's position. The leader
 
 If you specify a from_mapname, 'warpparty' will only affect those on that map.
 
+The <range x> and <range y> optional values allow for a randomization with the
+player's warp point. The values will randomly add or subtract from the given <x>
+and <y> coordinates.
+
 Example:
 	mes "[Party Warper]";
 	mes "Here you go!";

+ 3 - 5
npc/other/CashShop_Functions.txt

@@ -48,14 +48,12 @@ function	script	F_CashStore	{
 // Giant Fly Wing
 //============================================================ 
 // - Warp party leader to random spot on the map.
-// - Summon Party members on party leader map to that location.
+// - Summon Party members on party leader map to a 3x3 location around the leader.
 // - No arguments.
 function	script	F_CashPartyCall	{
 	warp "Random",0,0;
-	if(getpartyleader(getcharid(1),2) == getcharid(0)) {
-		getmapxy .@mapl$, .@xl, .@yl, UNITTYPE_PC;
-		warpparty .@mapl$, .@xl, .@yl, getcharid(1), .@mapl$;
-	}
+	if(getpartyleader(getcharid(1),2) == getcharid(0))
+		warpparty "Leader", 0, 0, getcharid(1), strcharinfo(3), 3, 3;
 	return;
 }
 

+ 2 - 0
src/map/clif.h

@@ -475,6 +475,8 @@ enum clif_messages {
 	//! NOTE: These values below need client version validation
 	ITEM_CANT_OBTAIN_WEIGHT = 0x34, /* You cannot carry more items because you are overweight. */
 	ITEM_NOUSE_SITTING = 0x297,
+	ITEM_PARTY_MEMBER_NOT_SUMMONED = 0x4c5, ///< "The party member was not summoned because you are not the party leader."
+	ITEM_PARTY_NO_MEMBER_IN_MAP = 0x4c6, ///< "There is no party member to summon in the current map."
 	MERC_MSG_BASE = 0x4f2,
 	SKILL_CANT_USE_AREA = 0x536,
 	ITEM_CANT_USE_AREA =  0x537,

+ 23 - 0
src/map/pc.c

@@ -4757,6 +4757,29 @@ bool pc_isUseitem(struct map_session_data *sd,int n)
 				clif_skill_teleportmessage(sd,0);
 				return false;
 			}
+			if (nameid == ITEMID_GIANT_FLY_WING) {
+				struct party_data *pd = party_search(sd->status.party_id);
+
+				if (pd) {
+					int i;
+
+					ARR_FIND(0, MAX_PARTY, i, pd->data[i].sd == sd && pd->party.member[i].leader);
+					if (i == MAX_PARTY) { // User is not party leader
+						clif_msg(sd, ITEM_PARTY_MEMBER_NOT_SUMMONED);
+						break;
+					}
+
+					ARR_FIND(0, MAX_PARTY, i, pd->data[i].sd && pd->data[i].sd != sd && pd->data[i].sd->bl.m == sd->bl.m && !pc_isdead(pd->data[i].sd));
+					if (i == MAX_PARTY) { // No party members found on same map
+						clif_msg(sd, ITEM_PARTY_NO_MEMBER_IN_MAP);
+						break;
+					}
+				} else {
+					clif_msg(sd, ITEM_PARTY_MEMBER_NOT_SUMMONED);
+					break;
+				}
+			}
+		// Fall through
 		case ITEMID_WING_OF_BUTTERFLY:
 		case ITEMID_N_BUTTERFLY_WING:
 		case ITEMID_DUN_TELE_SCROLL1:

+ 20 - 5
src/map/script.c

@@ -5781,7 +5781,7 @@ BUILDIN_FUNC(areapercentheal)
 
 /*==========================================
  * Warpparty - [Fredzilla] [Paradox924X]
- * Syntax: warpparty "to_mapname",x,y,Party_ID,{"from_mapname"};
+ * Syntax: warpparty "to_mapname",x,y,Party_ID,{<"from_mapname">,<range x>,<range y>};
  * If 'from_mapname' is specified, only the party members on that map will be warped
  *------------------------------------------*/
 BUILDIN_FUNC(warpparty)
@@ -5789,9 +5789,7 @@ BUILDIN_FUNC(warpparty)
 	TBL_PC *sd = NULL;
 	TBL_PC *pl_sd;
 	struct party_data* p;
-	int type;
-	int mapindex = 0, m = -1;
-	int i;
+	int type, mapindex = 0, m = -1, i, rx = 0, ry = 0;
 
 	const char* str = script_getstr(st,2);
 	int x = script_getnum(st,3);
@@ -5800,6 +5798,10 @@ BUILDIN_FUNC(warpparty)
 	const char* str2 = NULL;
 	if ( script_hasdata(st,6) )
 		str2 = script_getstr(st,6);
+	if (script_hasdata(st, 7))
+		rx = script_getnum(st, 7);
+	if (script_hasdata(st, 8))
+		ry = script_getnum(st, 8);
 
 	p = party_search(p_id);
 	if(!p)
@@ -5863,7 +5865,20 @@ BUILDIN_FUNC(warpparty)
 				pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
 		break;
 		case 3: // Leader
+			if (p->party.member[i].leader)
+				continue;
 		case 4: // m,x,y
+			if (rx || ry) {
+				int x1 = x + rx, y1 = y + ry,
+					x0 = x - rx, y0 = y - ry;
+				uint8 attempts = 10;
+
+				do {
+					x = x0 + rnd()%(x1 - x0 + 1);
+					y = y0 + rnd()%(y1 - y0 + 1);
+				} while ((--attempts) > 0 && !map_getcell(m, x, y, CELL_CHKPASS));
+			}
+
 			if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pl_sd->group_level))
 				pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
 		break;
@@ -22894,7 +22909,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(warp,"sii?"),
 	BUILDIN_DEF2(warp, "warpchar", "sii?"),
 	BUILDIN_DEF(areawarp,"siiiisii??"),
-	BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X]
+	BUILDIN_DEF(warpparty,"siii???"), // [Fredzilla] [Paradox924X]
 	BUILDIN_DEF(warpguild,"siii"), // [Fredzilla]
 	BUILDIN_DEF(setlook,"ii?"),
 	BUILDIN_DEF(changelook,"ii?"), // Simulates but don't Store it