Browse Source

LUA SpawnSet and SpellHeal updates

SpawnSet(NPC, "skin_color", "255 0 0", false, true)

skin_color takes in 3 arguments as a string, R G B
two new parameters after value:
- no_update, when set to true (default false, its an inverse flag of send_update) we will not send update of spawn changes
- temporary_flag, when set to true database is not update (default false again to keep compat with LUA scripts).

SpellHeal(Spawn, "heal", min, max, NPC, 0, 0, "New Spell Name")
image 4 năm trước cách đây
mục cha
commit
81aa1f23e3

+ 2 - 2
EQ2/source/WorldServer/Combat.cpp

@@ -545,7 +545,7 @@ bool Entity::ProcAttack(Spawn* victim, int8 damage_type, int32 low_damage, int32
 	return true;
 }
 
-bool Entity::SpellHeal(Spawn* target, float distance, LuaSpell* luaspell, string heal_type, int32 low_heal, int32 high_heal, int8 crit_mod, bool no_calcs){
+bool Entity::SpellHeal(Spawn* target, float distance, LuaSpell* luaspell, string heal_type, int32 low_heal, int32 high_heal, int8 crit_mod, bool no_calcs, string custom_spell_name){
 	 if(!target || !luaspell || !luaspell->spell)
 		return false;
 
@@ -673,7 +673,7 @@ bool Entity::SpellHeal(Spawn* target, float distance, LuaSpell* luaspell, string
 
 	target->GetZone()->TriggerCharSheetTimer();
 	if (heal_amt > 0)
-		GetZone()->SendHealPacket(this, target, type, heal_amt, luaspell->spell->GetName());
+		GetZone()->SendHealPacket(this, target, type, heal_amt, custom_spell_name.length() > 0 ? (char*)custom_spell_name.c_str() : luaspell->spell->GetName());
 	CheckProcs(PROC_TYPE_HEALING, target);
 	CheckProcs(PROC_TYPE_BENEFICIAL, target);
 

+ 48 - 6
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -154,6 +154,7 @@ Commands::Commands(){
 	spawn_set_values["holiday_flag"] = SPAWN_SET_VALUE_HOLIDAY_FLAG;
 	spawn_set_values["merchant_min_level"] = SPAWN_SET_VALUE_MERCHANT_MIN_LEVEL;
 	spawn_set_values["merchant_max_level"] = SPAWN_SET_VALUE_MERCHANT_MAX_LEVEL;
+	spawn_set_values["skin_color"] = SPAWN_SET_SKIN_COLOR;
 
 	zone_set_values["expansion_id"] = ZONE_SET_VALUE_EXPANSION_ID;
 	zone_set_values["name"] = ZONE_SET_VALUE_NAME;
@@ -197,7 +198,9 @@ bool Commands::SetSpawnCommand(Client* client, Spawn* target, int8 type, const c
 		return false;
 	int32 val = 0;
 	try{
-		if(type != SPAWN_SET_VALUE_NAME && !(type >= SPAWN_SET_VALUE_SPAWN_SCRIPT && type <= SPAWN_SET_VALUE_SUB_TITLE) && !(type >= SPAWN_SET_VALUE_PREFIX && type <= SPAWN_SET_VALUE_EXPANSION_FLAG || type == SPAWN_SET_VALUE_HOLIDAY_FLAG))
+		if(type != SPAWN_SET_VALUE_NAME && 
+			!(type >= SPAWN_SET_VALUE_SPAWN_SCRIPT && type <= SPAWN_SET_VALUE_SUB_TITLE) && !(type >= SPAWN_SET_VALUE_PREFIX && type <= SPAWN_SET_VALUE_EXPANSION_FLAG || type == SPAWN_SET_VALUE_HOLIDAY_FLAG)
+			&& type != SPAWN_SET_SKIN_COLOR)
 			val = atoul(value);
 	}
 	catch(...){
@@ -205,7 +208,7 @@ bool Commands::SetSpawnCommand(Client* client, Spawn* target, int8 type, const c
 			client->Message(CHANNEL_COLOR_RED, "Invalid numeric spawn value: %s", value);
 		return false;
 	}
-	if(temporary && temp_value){
+	if(temporary){
 		char tmp[128] = {0};
 		switch(type){
 			case SPAWN_SET_VALUE_NAME:{
@@ -500,8 +503,26 @@ bool Commands::SetSpawnCommand(Client* client, Spawn* target, int8 type, const c
 				target->SetMerchantLevelRange(target->GetMerchantMinLevel(), atoul(value));
 				break;
 			}
+			case SPAWN_SET_SKIN_COLOR: {
+				if (target->IsNPC())
+				{
+					Seperator* skinsep = new Seperator(value, ' ', 3, 500, true);
+					if (skinsep->IsNumber(0) && skinsep->IsNumber(1) && skinsep->IsNumber(2))
+					{
+						EQ2_Color clr;
+						clr.red = atoul(skinsep->arg[0]);
+						clr.green = atoul(skinsep->arg[1]);
+						clr.blue = atoul(skinsep->arg[2]);
+
+						((Entity*)target)->SetSkinColor(clr);
+					}
+					safe_delete(skinsep);
+				}
+				break;
+			}
 
-			*temp_value = string(tmp);
+			if(temp_value)
+				*temp_value = string(tmp);
 		}
 	}
 	else{
@@ -838,7 +859,28 @@ bool Commands::SetSpawnCommand(Client* client, Spawn* target, int8 type, const c
 				else
 					target->SetSpawnScript(value);
 				break;
-												   }
+			}
+
+			case SPAWN_SET_SKIN_COLOR: {
+				if (target->IsNPC())
+				{
+					Seperator* skinsep = new Seperator(value, ' ', 3, 500, true);
+					if (skinsep->IsNumber(0) && skinsep->IsNumber(1) && skinsep->IsNumber(2))
+					{
+						EQ2_Color clr;
+						clr.red = atoul(skinsep->arg[0]);
+						clr.green = atoul(skinsep->arg[1]);
+						clr.blue = atoul(skinsep->arg[2]);
+
+						((Entity*)target)->SetSkinColor(clr);
+						Query replaceSkinQuery;
+						replaceSkinQuery.AddQueryAsync(0, &database, Q_DELETE, "delete from npc_appearance where spawn_id=%u and type='skin_color'", target->GetDatabaseID());
+						replaceSkinQuery.AddQueryAsync(0, &database, Q_DELETE, "insert into npc_appearance set spawn_id=%u, type='skin_color', red=%u, green=%u, blue=%u", target->GetDatabaseID(), clr.red, clr.green, clr.blue);
+					}
+					safe_delete(skinsep);
+				}
+				break;
+			}
 		}
 	}
 	return true;
@@ -3649,7 +3691,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 					else
 					{
 						string name = string(spawn->GetName());
-						if(SetSpawnCommand(client, spawn, set_type, sep->arg[1]))
+						if(SetSpawnCommand(client, spawn, set_type, sep->argplus[1]))
 						{
 							if (set_type == SPAWN_SET_VALUE_EXPANSION_FLAG || set_type == SPAWN_SET_VALUE_HOLIDAY_FLAG)
 							{
@@ -3680,7 +3722,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 								}
 								default:
 								{
-									client->GetCurrentZone()->ApplySetSpawnCommand(client, spawn, set_type, sep->arg[1]);
+									client->GetCurrentZone()->ApplySetSpawnCommand(client, spawn, set_type, sep->argplus[1]);
 									break;
 								}
 							}

+ 1 - 0
EQ2/source/WorldServer/Commands/Commands.h

@@ -555,6 +555,7 @@ private:
 #define SPAWN_SET_VALUE_MERCHANT_MIN_LEVEL  60
 #define SPAWN_SET_VALUE_MERCHANT_MAX_LEVEL  61
 #define SPAWN_SET_VALUE_HOLIDAY_FLAG		62
+#define SPAWN_SET_SKIN_COLOR				63
 
 #define ZONE_SET_VALUE_EXPANSION_ID			0
 #define ZONE_SET_VALUE_NAME					1

+ 1 - 1
EQ2/source/WorldServer/Entity.h

@@ -472,7 +472,7 @@ public:
 	void			RangeAttack(Spawn* victim, float distance, Item* weapon, Item* ammo, bool multi_attack = false);
 	bool			SpellAttack(Spawn* victim, float distance, LuaSpell* luaspell, int8 damage_type, int32 low_damage, int32 high_damage, int8 crit_mod = 0, bool no_calcs = false);
 	bool			ProcAttack(Spawn* victim, int8 damage_type, int32 low_damage, int32 high_damage, string name, string success_msg, string effect_msg);
-	bool            SpellHeal(Spawn* target, float distance, LuaSpell* luaspell, string heal_type, int32 low_heal, int32 high_heal, int8 crit_mod = 0, bool no_calcs = false);
+	bool            SpellHeal(Spawn* target, float distance, LuaSpell* luaspell, string heal_type, int32 low_heal, int32 high_heal, int8 crit_mod = 0, bool no_calcs = false, string custom_spell_name="");
 	int8			DetermineHit(Spawn* victim, int8 damage_type, float ToHitBonus, bool spell);
 	float			GetDamageTypeResistPercentage(int8 damage_type);
 	Skill*			GetSkillByWeaponType(int8 type, bool update);

+ 6 - 3
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -236,9 +236,11 @@ int EQ2Emu_lua_SpawnSet(lua_State* state) {
 	Spawn* spawn = lua_interface->GetSpawn(state);
 	string variable = lua_interface->GetStringValue(state, 2);
 	string value = lua_interface->GetStringValue(state, 3);
+	bool no_update = lua_interface->GetBooleanValue(state, 4); // send update is true by default in SetSpawnCommand, so allow user to specify 'true' to disable send update.
+	bool temporary_flag = lua_interface->GetBooleanValue(state, 5); // default false as originally designed, allow user to set temporary_flag true to not update DB
 	int32 type = commands.GetSpawnSetType(variable);
 	if (type != 0xFFFFFFFF && value.length() > 0 && spawn)
-		commands.SetSpawnCommand(0, spawn, type, value.c_str());
+		commands.SetSpawnCommand(0, spawn, type, value.c_str(), !no_update, temporary_flag);
 	return 0;
 }
 
@@ -895,13 +897,14 @@ int EQ2Emu_lua_SpellHeal(lua_State* state) {
 	Spawn* target = lua_interface->GetSpawn(state, 4);
 	int8 crit_mod = lua_interface->GetInt32Value(state, 5);
 	bool no_calcs = lua_interface->GetInt32Value(state, 6) == 1;
+	string custom_spell_name = lua_interface->GetStringValue(state, 7);//custom spell name
 	lua_interface->ResetFunctionStack(state);
 	if (caster && caster->IsEntity()) {
 		bool success = false;
 		luaspell->resisted = false;
 		if (target) {
 			float distance = caster->GetDistance(target, true);
-			if (((Entity*)caster)->SpellHeal(target, distance, luaspell, heal_type, min_heal, max_heal, crit_mod, no_calcs))
+			if (((Entity*)caster)->SpellHeal(target, distance, luaspell, heal_type, min_heal, max_heal, crit_mod, no_calcs, custom_spell_name))
 				success = true;
 		}
 		if (luaspell->targets.size() > 0) {
@@ -911,7 +914,7 @@ int EQ2Emu_lua_SpellHeal(lua_State* state) {
 			for (int32 i = 0; i < luaspell->targets.size(); i++) {
 				if ((target = zone->GetSpawnByID(luaspell->targets[i]))) {
 					float distance = caster->GetDistance(target, true);
-					((Entity*)caster)->SpellHeal(target, distance, luaspell, heal_type, min_heal, max_heal, crit_mod, no_calcs);
+					((Entity*)caster)->SpellHeal(target, distance, luaspell, heal_type, min_heal, max_heal, crit_mod, no_calcs, custom_spell_name);
 				}
 			}
 			luaspell->MSpellTargets.releasereadlock(__FUNCTION__, __LINE__);

+ 1 - 1
EQ2/source/WorldServer/zoneserver.cpp

@@ -3708,7 +3708,7 @@ void ZoneServer::SetSpawnCommand(int32 spawn_id, int8 type, char* value, Client*
 	LogWrite(MISC__TODO, 1, "TODO", "%s does nothing!\n%s, %i", __FUNCTION__, __FILE__, __LINE__);
 }
 
-void ZoneServer::ApplySetSpawnCommand(Client* client, Spawn* target, int8 type, char* value){
+void ZoneServer::ApplySetSpawnCommand(Client* client, Spawn* target, int8 type, const char* value){
 	// This will apply the /spawn set command to all the spawns in the zone with the same DB ID, we do not want to set
 	// location values (x, y, z, heading, grid) for all spawns in the zone with the same DB ID, only the targeted spawn
 	if(type == SPAWN_SET_VALUE_SPAWNENTRY_SCRIPT || type == SPAWN_SET_VALUE_SPAWNLOCATION_SCRIPT || (type >= SPAWN_SET_VALUE_X && type <= SPAWN_SET_VALUE_LOCATION) ||

+ 1 - 1
EQ2/source/WorldServer/zoneserver.h

@@ -258,7 +258,7 @@ public:
 	
 	int16	SetSpawnTargetable(Spawn* spawn, float distance);
 	int16	SetSpawnTargetable(int32 spawn_id);
-	void	ApplySetSpawnCommand(Client* client, Spawn* target, int8 type, char* value);
+	void	ApplySetSpawnCommand(Client* client, Spawn* target, int8 type, const char* value);
 	void	SetSpawnCommand(Spawn* spawn, int8 type, char* value, Client* client = 0);
 	void	SetSpawnCommand(int32 spawn_id, int8 type, char* value, Client* client = 0);
 	void	AddLoot(NPC* npc);