浏览代码

Added support for new carts (requires packetver 20120201 or newer). Super-Ultra-Plus thanks to Fatal Error and Judas.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16297 54d463be-8e91-2dee-dedb-b68131a5f0ec
shennetsind 13 年之前
父节点
当前提交
282892387f
共有 8 个文件被更改,包括 117 次插入34 次删除
  1. 3 6
      src/map/chrif.c
  2. 26 1
      src/map/clif.c
  3. 8 0
      src/map/config/const.h
  4. 53 18
      src/map/pc.c
  5. 7 1
      src/map/pc.h
  6. 4 1
      src/map/script.c
  7. 1 0
      src/map/status.c
  8. 15 7
      src/map/status.h

+ 3 - 6
src/map/chrif.c

@@ -1223,19 +1223,16 @@ int chrif_load_scdata(int fd)
 	cid = RFIFOL(fd,8); //Player Char ID
 	
 	sd = map_id2sd(aid);
-	if (!sd)
-	{
+	if (!sd) {
 		ShowError("chrif_load_scdata: Player of AID %d not found!\n", aid);
 		return -1;
 	}
-	if (sd->status.char_id != cid)
-	{
+	if (sd->status.char_id != cid) {
 		ShowError("chrif_load_scdata: Receiving data for account %d, char id does not matches (%d != %d)!\n", aid, sd->status.char_id, cid);
 		return -1;
 	}
 	count = RFIFOW(fd,12); //sc_count
-	for (i = 0; i < count; i++)
-	{
+	for (i = 0; i < count; i++) {
 		data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
 		status_change_start(&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
 	}

+ 26 - 1
src/map/clif.c

@@ -1353,6 +1353,10 @@ int clif_spawn(struct block_list *bl)
 				//New Mounts are not complaint to the original method, so we gotta tell this guy that he is mounting.
 				clif_status_load_notick(&sd->bl,SI_ALL_RIDING,2,1,0,0);
 			}
+		#ifdef NEW_CARTS
+			if( sd->sc.data[SC_PUSH_CART] )
+				clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2, sd->sc.data[SC_PUSH_CART]->val1, 0, 0);
+		#endif
 		#if PACKETVER <= 20120207
 			if (sd->status.robe)
 				clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);			
@@ -3998,6 +4002,10 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d
 		//New Mounts are not complaint to the original method, so we gotta tell this guy that I'm mounting.
 		clif_status_load_single(sd->fd,dstsd->bl.id,SI_ALL_RIDING,2,1,0,0);
 	}
+#ifdef NEW_CARTS
+	if( dstsd->sc.data[SC_PUSH_CART] )
+		clif_status_load_single(sd->fd, dstsd->bl.id, SI_ON_PUSH_CART, 2, dstsd->sc.data[SC_PUSH_CART]->val1, 0, 0);
+#endif
 	if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
 		(sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
 		pc_has_permission(sd, PC_PERM_VIEW_HPMETER)
@@ -10485,7 +10493,13 @@ void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
 	/**
 	 * Attempts to remove these options when this function is called (will remove all available)
 	 **/
+#ifdef NEW_CARTS
+	pc_setoption(sd,sd->sc.option&~(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
+	if( sd->sc.data[SC_PUSH_CART] )
+		pc_setcart(sd,0);	
+#else
 	pc_setoption(sd,sd->sc.option&~(OPTION_CART|OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
+#endif
 }
 
 
@@ -10499,12 +10513,23 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
 		return;
 
 	type = (int)RFIFOW(fd,2);
-
+#ifdef NEW_CARTS
+	if( (type == 9 && sd->status.base_level > 131) ||
+		(type == 8 && sd->status.base_level > 121) ||
+		(type == 7 && sd->status.base_level > 111) ||
+		(type == 6 && sd->status.base_level > 101) ||
+		(type == 5 && sd->status.base_level >  90) ||
+		(type == 4 && sd->status.base_level >  80) ||
+		(type == 3 && sd->status.base_level >  65) ||
+		(type == 2 && sd->status.base_level >  40) ||
+		(type == 1))	
+#else
 	if( (type == 5 && sd->status.base_level > 90) ||
 	    (type == 4 && sd->status.base_level > 80) ||
 	    (type == 3 && sd->status.base_level > 65) ||
 	    (type == 2 && sd->status.base_level > 40) ||
 	    (type == 1))
+#endif
 		pc_setcart(sd,type);
 }
 

+ 8 - 0
src/map/config/const.h

@@ -100,6 +100,14 @@
 	#define RE_LVL_TMDMOD()
 #endif
 
+/* Feb 1st 2012 */
+#ifdef PACKETVER >= 20120201
+	#define NEW_CARTS
+	#define MAX_CARTS 9
+#else
+	#define MAX_CARTS 5
+#endif
+
 /**
  * End of File
  **/

+ 53 - 18
src/map/pc.c

@@ -519,8 +519,11 @@ int pc_makesavestatus(struct map_session_data *sd)
 
   	//Only copy the Cart/Peco/Falcon options, the rest are handled via 
 	//status change load/saving. [Skotlex]
+#ifdef NEW_CARTS
+	sd->status.option = sd->sc.option&(OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_MADOGEAR|OPTION_MOUNTING);
+#else
 	sd->status.option = sd->sc.option&(OPTION_CART|OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_MADOGEAR|OPTION_MOUNTING);
-		
+#endif
 	if (sd->sc.data[SC_JAILED])
 	{	//When Jailed, do not move last point.
 		if(pc_isdead(sd)){
@@ -1003,6 +1006,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	pc_setequipindex(sd);
 
 	status_change_init(&sd->bl);
+	
 	if (pc_can_use_command(sd, "hide", COMMAND_ATCOMMAND))
 		sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE);
 	else
@@ -5992,8 +5996,6 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 		i = sd->sc.option;
 		if( i&OPTION_RIDING && pc_checkskill(sd, KN_RIDING) )
 			i &= ~OPTION_RIDING;
-		if( i&OPTION_CART && pc_checkskill(sd, MC_PUSHCART) )
-			i &= ~OPTION_CART;
 		if( i&OPTION_FALCON && pc_checkskill(sd, HT_FALCON) )
 			i &= ~OPTION_FALCON;
 		if( i&OPTION_DRAGON && pc_checkskill(sd, RK_DRAGONTRAINING) )
@@ -6006,6 +6008,13 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 			i &= ~OPTION_MADOGEAR;
 		if( i&OPTION_MOUNTING )
 			i &= ~OPTION_MOUNTING;
+#ifndef NEW_CARTS
+		if( i&OPTION_CART && pc_checkskill(sd, MC_PUSHCART) )
+			i &= ~OPTION_CART;
+#else
+		if( sd->sc.data[SC_PUSH_CART] )
+			pc_setcart(sd, 0);
+#endif
 		if( i != sd->sc.option )
 			pc_setoption(sd, i);
 
@@ -6953,11 +6962,9 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
 
 	//Remove peco/cart/falcon
 	i = sd->sc.option;
-	if(i&OPTION_RIDING && !pc_checkskill(sd, KN_RIDING))
+	if( i&OPTION_RIDING && !pc_checkskill(sd, KN_RIDING) )
 		i&=~OPTION_RIDING;
-	if(i&OPTION_CART && !pc_checkskill(sd, MC_PUSHCART))
-		i&=~OPTION_CART;
-	if(i&OPTION_FALCON && !pc_checkskill(sd, HT_FALCON))
+	if( i&OPTION_FALCON && !pc_checkskill(sd, HT_FALCON) )
 		i&=~OPTION_FALCON;
 	if( i&OPTION_DRAGON && !pc_checkskill(sd,RK_DRAGONTRAINING) )
 		i&=~OPTION_DRAGON;
@@ -6967,6 +6974,13 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
 		i&=~OPTION_WUG;
 	if( i&OPTION_MADOGEAR ) //You do not need a skill for this.
 		i&=~OPTION_MADOGEAR;
+#ifndef NEW_CARTS
+	if( i&OPTION_CART && !pc_checkskill(sd, MC_PUSHCART) )
+		i&=~OPTION_CART;
+#else
+	if( sd->sc.data[SC_PUSH_CART] && !pc_checkskill(sd, MC_PUSHCART) )
+		pc_setcart(sd, 0);
+#endif
 	if(i != sd->sc.option)
 		pc_setoption(sd, i);
 
@@ -7099,20 +7113,19 @@ int pc_setoption(struct map_session_data *sd,int type)
 		clif_status_load(&sd->bl,SI_RIDING,0);
 		status_calc_pc(sd,0);
 	}
-
-	if(type&OPTION_CART && !(p_type&OPTION_CART))
-  	{ //Cart On
+	
+#ifndef NEW_CARTS
+	if( type&OPTION_CART && !( p_type&OPTION_CART ) ) { //Cart On
 		clif_cartlist(sd);
 		clif_updatestatus(sd, SP_CARTINFO);
 		if(pc_checkskill(sd, MC_PUSHCART) < 10)
 			status_calc_pc(sd,0); //Apply speed penalty.
-	} else
-	if(!(type&OPTION_CART) && p_type&OPTION_CART)
-	{ //Cart Off
+	} else if( !( type&OPTION_CART ) && p_type&OPTION_CART ){ //Cart Off
 		clif_clearcart(sd->fd);
 		if(pc_checkskill(sd, MC_PUSHCART) < 10)
 			status_calc_pc(sd,0); //Remove speed penalty.
 	}
+#endif
 
 	if (type&OPTION_MOUNTING && !(p_type&OPTION_MOUNTING) ) {
 		clif_status_load_notick(&sd->bl,SI_ALL_RIDING,2,1,0,0);
@@ -7197,25 +7210,47 @@ int pc_setoption(struct map_session_data *sd,int type)
 /*==========================================
  * ƒJ?ƒg�Ý’è
  *------------------------------------------*/
-int pc_setcart(struct map_session_data *sd,int type)
-{
+int pc_setcart(struct map_session_data *sd,int type) {
+#ifndef NEW_CARTS
 	int cart[6] = {0x0000,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5};
 	int option;
-
+#endif
 	nullpo_ret(sd);
 
-	if( type < 0 || type > 5 )
+	if( type < 0 || type > MAX_CARTS )
 		return 1;// Never trust the values sent by the client! [Skotlex]
 
 	if( pc_checkskill(sd,MC_PUSHCART) <= 0 )
 		return 1;// Push cart is required
 
+#ifdef NEW_CARTS
+	
+	switch( type ) {
+		case 0:
+			if( !sd->sc.data[SC_PUSH_CART] )
+				return 0;
+			status_change_end(&sd->bl,SC_PUSH_CART,INVALID_TIMER);
+			clif_clearcart(sd->fd);
+			break;
+		default:/* everything else is an allowed ID so we can move on */
+			if( !sd->sc.data[SC_PUSH_CART] ) /* first time, so fill cart data */
+				clif_cartlist(sd);
+			clif_updatestatus(sd, SP_CARTINFO);
+			sc_start(&sd->bl, SC_PUSH_CART, 100, type, 0);
+			clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2, type, 0, 0);
+			break;
+	}
+	
+	if(pc_checkskill(sd, MC_PUSHCART) < 10)
+		status_calc_pc(sd,0); //Recalc speed penalty.
+#else
 	// Update option
 	option = sd->sc.option;
 	option &= ~OPTION_CART;// clear cart bits
 	option |= cart[type]; // set cart
 	pc_setoption(sd, option);
-
+#endif
+	
 	return 0;
 }
 

+ 7 - 1
src/map/pc.h

@@ -613,7 +613,13 @@ enum e_pc_permission {
 #define pc_ishiding(sd)       ( (sd)->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) )
 #define pc_iscloaking(sd)     ( !((sd)->sc.option&OPTION_CHASEWALK) && ((sd)->sc.option&OPTION_CLOAK) )
 #define pc_ischasewalk(sd)    ( (sd)->sc.option&OPTION_CHASEWALK )
-#define pc_iscarton(sd)       ( (sd)->sc.option&OPTION_CART )
+
+#ifdef NEW_CARTS
+	#define pc_iscarton(sd)       ( (sd)->sc.data[SC_PUSH_CART] )
+#else
+	#define pc_iscarton(sd)       ( (sd)->sc.option&OPTION_CART )
+#endif
+
 #define pc_isfalcon(sd)       ( (sd)->sc.option&OPTION_FALCON )
 #define pc_isriding(sd)       ( (sd)->sc.option&OPTION_RIDING )
 #define pc_isinvisible(sd)    ( (sd)->sc.option&OPTION_INVISIBLE )

+ 4 - 1
src/map/script.c

@@ -7748,7 +7748,10 @@ BUILDIN_FUNC(setoption)
 		flag = script_getnum(st,3);
 	else if( !option ){// Request to remove everything.
 		flag = 0;
-		option = OPTION_CART|OPTION_FALCON|OPTION_RIDING;
+		option = OPTION_FALCON|OPTION_RIDING;
+#ifndef NEW_CARTS
+		option |= OPTION_CART;
+#endif
 	}
 	if( flag ){// Add option
 		if( option&OPTION_WEDDING && !battle_config.wedding_modifydisplay )

+ 1 - 0
src/map/status.c

@@ -6992,6 +6992,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 		case SC_READYCOUNTER:
 		case SC_READYTURN:
 		case SC_DODGE:
+		case SC_PUSH_CART:
 			tick = -1;
 			break;
 

+ 15 - 7
src/map/status.h

@@ -598,6 +598,8 @@ typedef enum sc_type {
 	SC_WATER_INSIGNIA,
 	SC_WIND_INSIGNIA, //515
 	SC_EARTH_INSIGNIA,
+	/* new pushcart */
+	SC_PUSH_CART,
 	
 	SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
 } sc_type;
@@ -1368,14 +1370,9 @@ enum {
 	OPTION_SIGHT     = 0x00000001,
 	OPTION_HIDE      = 0x00000002,
 	OPTION_CLOAK     = 0x00000004,
-	OPTION_CART1     = 0x00000008,
 	OPTION_FALCON    = 0x00000010,
 	OPTION_RIDING    = 0x00000020,
 	OPTION_INVISIBLE = 0x00000040,
-	OPTION_CART2     = 0x00000080,
-	OPTION_CART3     = 0x00000100,
-	OPTION_CART4     = 0x00000200,
-	OPTION_CART5     = 0x00000400,
 	OPTION_ORCISH    = 0x00000800,
 	OPTION_WEDDING   = 0x00001000,
 	OPTION_RUWACH    = 0x00002000,
@@ -1392,9 +1389,20 @@ enum {
 	OPTION_DRAGON3   = 0x01000000,
 	OPTION_DRAGON4   = 0x02000000,
 	OPTION_DRAGON5   = 0x04000000,
-	OPTION_MOUNTING  = 0x08000000,//dull name (cuz ind named it :/)
-	// compound constants
+	OPTION_MOUNTING  = 0x08000000,
+	
+#ifndef NEW_CARTS
+	OPTION_CART1     = 0x00000008,
+	OPTION_CART2     = 0x00000080,
+	OPTION_CART3     = 0x00000100,
+	OPTION_CART4     = 0x00000200,
+	OPTION_CART5     = 0x00000400,
+	
+	/*  compound constant for older carts */
 	OPTION_CART      = OPTION_CART1|OPTION_CART2|OPTION_CART3|OPTION_CART4|OPTION_CART5,
+#endif
+	
+	// compound constants
 	OPTION_DRAGON    = OPTION_DRAGON1|OPTION_DRAGON2|OPTION_DRAGON3|OPTION_DRAGON4|OPTION_DRAGON5,
 	OPTION_MASK      = ~OPTION_INVISIBLE,
 };