Browse Source

Refurbished hat effects

Follow up to 5da49b8
Thanks to @cydh for the good base in #1465.

Renamed the function from itemeffect to hateffect.
The effects now get sent to other players as well.
You can enable or disable one effect at a time with the script command now.
Lemongrass3110 8 years ago
parent
commit
ede39b1730
7 changed files with 84 additions and 30 deletions
  1. 1 1
      doc/script_commands.txt
  2. 36 14
      src/map/clif.c
  3. 2 1
      src/map/clif.h
  4. 3 0
      src/map/pc.c
  5. 5 0
      src/map/pc.h
  6. 31 14
      src/map/script.c
  7. 6 0
      src/map/unit.c

+ 1 - 1
doc/script_commands.txt

@@ -9161,7 +9161,7 @@ solution rather than sending the map and the monster_id.
 
 
 ---------------------------------------
 ---------------------------------------
 
 
-*itemeffect(<State>,<Hat Effect ID>{, Hat Effect ID2, ... });
+*hateffect(<Hat Effect ID>,<State>);
 
 
 This will set a Hat Effect onto the player. The state field allows you to
 This will set a Hat Effect onto the player. The state field allows you to
 enable (true) or disable (false) the effect on the player.
 enable (true) or disable (false) the effect on the player.

+ 36 - 14
src/map/clif.c

@@ -1444,6 +1444,7 @@ int clif_spawn(struct block_list *bl)
 			if (sd->status.robe)
 			if (sd->status.robe)
 				clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
 				clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
 			clif_efst_status_change_sub(sd, bl, AREA);
 			clif_efst_status_change_sub(sd, bl, AREA);
+			clif_hat_effects(sd,bl,AREA);
 		}
 		}
 		break;
 		break;
 	case BL_MOB:
 	case BL_MOB:
@@ -4548,6 +4549,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
 			if ( tsd->status.robe )
 			if ( tsd->status.robe )
 				clif_refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF);
 				clif_refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF);
 			clif_efst_status_change_sub(sd, bl, SELF);
 			clif_efst_status_change_sub(sd, bl, SELF);
+			clif_hat_effects(sd,bl,SELF);
 		}
 		}
 		break;
 		break;
 	case BL_MER: // Devotion Effects
 	case BL_MER: // Devotion Effects
@@ -18745,37 +18747,57 @@ void clif_navigateTo(struct map_session_data *sd, const char* mapname, uint16 x,
 
 
 /// Send hat effects to the client (ZC_HAT_EFFECT).
 /// Send hat effects to the client (ZC_HAT_EFFECT).
 /// 0A3B <Length>.W <AID>.L <Status>.B { <HatEffectId>.W }
 /// 0A3B <Length>.W <AID>.L <Status>.B { <HatEffectId>.W }
-void clif_item_effects( struct block_list* bl, bool enable, short effects[], int count ){
+void clif_hat_effects( struct map_session_data* sd, struct block_list* bl, enum send_target target ){
 #if PACKETVER >= 20150513
 #if PACKETVER >= 20150513
 	unsigned char* buf;
 	unsigned char* buf;
 	int len,i;
 	int len,i;
+	struct map_session_data *tsd;
+	struct block_list* tbl;
 
 
-	nullpo_retv(bl);
+	if( target == SELF ){
+		tsd = BL_CAST(BL_PC,bl);
+		tbl = &sd->bl;
+	}else{
+		tsd = sd;
+		tbl = bl;
+	}
+
+	if( !tsd->hatEffectCount )
+		return;
 
 
-	len = 9 + count * 2;
+	len = 9 + tsd->hatEffectCount * 2;
 
 
 	buf = (unsigned char*)aMalloc( len );
 	buf = (unsigned char*)aMalloc( len );
 
 
 	WBUFW(buf,0) = 0xa3b;
 	WBUFW(buf,0) = 0xa3b;
 	WBUFW(buf,2) = len;
 	WBUFW(buf,2) = len;
-	WBUFL(buf,4) = bl->id;
-	WBUFB(buf,8) = enable;
+	WBUFL(buf,4) = tsd->bl.id;
+	WBUFB(buf,8) = 1;
 
 
-	for( i = 0; i < count; i++ ){
-		WBUFW(buf,9+i*2) = effects[i];
+	for( i = 0; i < tsd->hatEffectCount; i++ ){
+		WBUFW(buf,9+i*2) = tsd->hatEffectIDs[i];
 	}
 	}
 
 
-	clif_send(buf, len,bl,SELF);
-
-	if( disguised(bl) ){
-		WBUFL(buf,4) = -bl->id;
-		clif_send(buf, len,bl,SELF);
-	}
+	clif_send(buf, len,tbl,target);
 
 
 	aFree(buf);
 	aFree(buf);
 #endif
 #endif
 }
 }
 
 
+void clif_hat_effect_single( struct map_session_data* sd, uint16 effectId, bool enable ){
+#if PACKETVER >= 20150513
+	unsigned char buf[13];
+
+	WBUFW(buf,0) = 0xa3b;
+	WBUFW(buf,2) = 13;
+	WBUFL(buf,4) = sd->bl.id;
+	WBUFB(buf,8) = enable;
+	WBUFL(buf,9) = effectId;
+
+	clif_send(buf,13,&sd->bl,AREA);
+#endif
+}
+
 /*==========================================
 /*==========================================
  * Main client packet processing function
  * Main client packet processing function
  *------------------------------------------*/
  *------------------------------------------*/
@@ -19176,7 +19198,7 @@ void packetdb_readdb(bool reload)
 	  269,  0,  0,  2,  6, 48,  6,  9, 26, 45, 47, 47, 56, -1,  14,  0,
 	  269,  0,  0,  2,  6, 48,  6,  9, 26, 45, 47, 47, 56, -1,  14,  0,
 #endif
 #endif
 		-1,  0,  0, 26,  0,  0,  0,  0,  14,  2, 23,  2, -1,  2,  3,  2,
 		-1,  0,  0, 26,  0,  0,  0,  0,  14,  2, 23,  2, -1,  2,  3,  2,
-	   21,  3,  5,  0, 66,  0,  0,  8,  3,  0,  0,  0,  0,  -1,  0,  0,
+	   21,  3,  5,  0, 66,  0,  0,  8,  3,  0,  0,  -1,  0,  -1,  0,  0,
  		0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  		0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	};
 	};
 	struct {
 	struct {

+ 2 - 1
src/map/clif.h

@@ -679,7 +679,8 @@ void clif_item_repair_list(struct map_session_data *sd, struct map_session_data
 void clif_item_repaireffect(struct map_session_data *sd, int idx, int flag);
 void clif_item_repaireffect(struct map_session_data *sd, int idx, int flag);
 void clif_item_damaged(struct map_session_data* sd, unsigned short position);
 void clif_item_damaged(struct map_session_data* sd, unsigned short position);
 void clif_item_refine_list(struct map_session_data *sd);
 void clif_item_refine_list(struct map_session_data *sd);
-void clif_item_effects( struct block_list* bl, bool enable, short effects[], int count );
+void clif_hat_effects( struct map_session_data* sd, struct block_list* bl, enum send_target target );
+void clif_hat_effect_single( struct map_session_data* sd, uint16 effectId, bool enable );
 
 
 void clif_item_skill(struct map_session_data *sd,uint16 skill_id,uint16 skill_lv);
 void clif_item_skill(struct map_session_data *sd,uint16 skill_id,uint16 skill_lv);
 
 

+ 3 - 0
src/map/pc.c

@@ -1269,6 +1269,9 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
 	sd->bonus_script.head = NULL;
 	sd->bonus_script.head = NULL;
 	sd->bonus_script.count = 0;
 	sd->bonus_script.count = 0;
 
 
+	sd->hatEffectIDs = NULL;
+	sd->hatEffectCount = 0;
+
 	// Check EXP overflow, since in previous revision EXP on Max Level can be more than 'official' Max EXP
 	// Check EXP overflow, since in previous revision EXP on Max Level can be more than 'official' Max EXP
 	if (pc_is_maxbaselv(sd) && sd->status.base_exp > MAX_LEVEL_BASE_EXP) {
 	if (pc_is_maxbaselv(sd) && sd->status.base_exp > MAX_LEVEL_BASE_EXP) {
 		sd->status.base_exp = MAX_LEVEL_BASE_EXP;
 		sd->status.base_exp = MAX_LEVEL_BASE_EXP;

+ 5 - 0
src/map/pc.h

@@ -685,6 +685,11 @@ struct map_session_data {
 	} roulette;
 	} roulette;
 
 
 	unsigned short instance_id;
 	unsigned short instance_id;
+
+#if PACKETVER >= 20150513
+	uint32* hatEffectIDs;
+	uint8 hatEffectCount;
+#endif
 };
 };
 
 
 struct eri *pc_sc_display_ers; /// Player's SC display table
 struct eri *pc_sc_display_ers; /// Player's SC display table

+ 31 - 14
src/map/script.c

@@ -21482,31 +21482,48 @@ BUILDIN_FUNC(recalculatestat) {
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
-BUILDIN_FUNC(itemeffect){
+BUILDIN_FUNC(hateffect){
 #if PACKETVER >= 20150513
 #if PACKETVER >= 20150513
 	struct map_session_data* sd = script_rid2sd(st);
 	struct map_session_data* sd = script_rid2sd(st);
 	bool enable;
 	bool enable;
-	short *effects;
-	int i, count;
+	int i, effectID;
 
 
 	if( sd == NULL )
 	if( sd == NULL )
 		return SCRIPT_CMD_FAILURE;
 		return SCRIPT_CMD_FAILURE;
 
 
-	enable = script_getnum(st,2) ? true : false;
+	effectID = script_getnum(st,2);
+	enable = script_getnum(st,3) ? true : false;
 
 
-	if( !script_hasdata(st,3) ){
-		ShowError( "buildin_itemeffect: You need to specify a hat effect id.\n" );
-		return SCRIPT_CMD_FAILURE;
-	}
+	ARR_FIND( 0, sd->hatEffectCount, i, sd->hatEffectIDs[i] == effectID );
 
 
-	count = st->end - 3;
-	effects = (short*)aMalloc(count*sizeof(short));
+	if( enable ){
+		if( i < sd->hatEffectCount ){
+			return SCRIPT_CMD_SUCCESS;
+		}
 
 
-	for( i = 0; i < count; i++ ){
-		effects[i] = script_getnum(st,3+i);
+		RECREATE(sd->hatEffectIDs,uint32,sd->hatEffectCount+1);
+		sd->hatEffectIDs[sd->hatEffectCount] = effectID;
+		sd->hatEffectCount++;
+	}else{
+		if( i == sd->hatEffectCount ){
+			return SCRIPT_CMD_SUCCESS;
+		}
+
+		for( ; i < sd->hatEffectCount - 1; i++ ){
+			sd->hatEffectIDs[i] = sd->hatEffectIDs[i+1];
+		}
+
+		sd->hatEffectCount--;
+
+		if( !sd->hatEffectCount ){
+			aFree(sd->hatEffectIDs);
+			sd->hatEffectIDs = NULL;
+		}
 	}
 	}
 
 
-	clif_item_effects( &sd->bl, enable, effects, count );
+	if( !sd->state.connect_new ){
+		clif_hat_effect_single( sd, effectID, enable );
+	}
 
 
 #endif
 #endif
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
@@ -22090,7 +22107,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(adopt,"vv"),
 	BUILDIN_DEF(adopt,"vv"),
 	BUILDIN_DEF(getexp2,"ii?"),
 	BUILDIN_DEF(getexp2,"ii?"),
 	BUILDIN_DEF(recalculatestat,""),
 	BUILDIN_DEF(recalculatestat,""),
-	BUILDIN_DEF(itemeffect,"ii*"),
+	BUILDIN_DEF(hateffect,"ii"),
 
 
 #include "../custom/script_def.inc"
 #include "../custom/script_def.inc"
 
 

+ 6 - 0
src/map/unit.c

@@ -3211,6 +3211,12 @@ int unit_free(struct block_list *bl, clr_type clrtype)
 			}
 			}
 			sd->qi_count = 0;
 			sd->qi_count = 0;
 
 
+			if( sd->hatEffectCount > 0 ){
+				aFree(sd->hatEffectIDs);
+				sd->hatEffectIDs = NULL;
+				sd->hatEffectCount = 0;
+			}
+
 			// Clearing...
 			// Clearing...
 			if (sd->bonus_script.head)
 			if (sd->bonus_script.head)
 				pc_bonus_script_clear(sd, BSF_REM_ALL);
 				pc_bonus_script_clear(sd, BSF_REM_ALL);