Browse Source

spell concentration fix + no_interrupt in info struct

Fix #259 - spell concentration now adds/subtracts correctly, synched with client.

Fix #153 - Info struct has new UInt no_interrupt
Image 3 years ago
parent
commit
7ea4b3d51f

+ 3 - 0
EQ2/source/WorldServer/Combat.cpp

@@ -1111,6 +1111,9 @@ bool Entity::CheckInterruptSpell(Entity* attacker) {
 	if(!spell || spell->GetSpellData()->interruptable == 0)
 		return false;
 
+	if(GetInfoStruct()->get_no_interrupt())
+		return false;
+		
 	//originally base of 30 percent chance to continue casting if attacked
 	//modified to 50% and added global rule, 30% was too small at starting levels
 	int8 percent = rule_manager.GetGlobalRule(R_Spells, NoInterruptBaseChance)->GetInt32();

+ 6 - 2
EQ2/source/WorldServer/Entity.cpp

@@ -248,6 +248,8 @@ void Entity::MapInfoStruct()
 	
 	get_int8_funcs["water_type"] = l::bind(&InfoStruct::get_water_type, &info_struct);
 	get_int8_funcs["flying_type"] = l::bind(&InfoStruct::get_flying_type, &info_struct);
+	
+	get_int8_funcs["no_interrupt"] = l::bind(&InfoStruct::get_no_interrupt, &info_struct);
 
 
 /** SETS **/
@@ -391,6 +393,8 @@ void Entity::MapInfoStruct()
 	
 	set_int8_funcs["water_type"] = l::bind(&InfoStruct::set_water_type, &info_struct, l::_1);
 	set_int8_funcs["flying_type"] = l::bind(&InfoStruct::set_flying_type, &info_struct, l::_1);
+	
+	set_int8_funcs["no_interrupt"] = l::bind(&InfoStruct::set_no_interrupt, &info_struct, l::_1);
 
 }
 
@@ -762,8 +766,8 @@ void Entity::AddMaintainedSpell(LuaSpell* luaspell){
 		MMaintainedSpells.writelock(__FUNCTION__, __LINE__);
 		effect->spell = luaspell;
 		effect->spell_id = spell->GetSpellData()->id;
-		LogWrite(NPC__SPELLS, 5, "NPC", "AddMaintainedSpell Spell ID: %u", spell->GetSpellData()->id);
-		effect->conc_used = spell->GetSpellData()->req_concentration / 256;
+		LogWrite(NPC__SPELLS, 5, "NPC", "AddMaintainedSpell Spell ID: %u, Concentration: %u", spell->GetSpellData()->id, spell->GetSpellData()->req_concentration);
+		effect->conc_used = spell->GetSpellData()->req_concentration;
 		effect->total_time = spell->GetSpellDuration() / 10;
 		effect->tier = spell->GetSpellData()->tier;
 		if (spell->GetSpellData()->duration_until_cancel)

+ 72 - 14
EQ2/source/WorldServer/Entity.h

@@ -254,6 +254,8 @@ struct InfoStruct{
 
 		water_type_ = 0;
 		flying_type_ = 0;
+
+		no_interrupt_ = 0;
 	}
 
 
@@ -403,6 +405,8 @@ struct InfoStruct{
 
 		water_type_ = oldStruct->get_water_type();
 		flying_type_ = oldStruct->get_flying_type();
+
+		no_interrupt_ = oldStruct->get_no_interrupt();
 	}
 
 	//mutable std::shared_mutex mutex_;
@@ -545,23 +549,25 @@ struct InfoStruct{
 	int32	 get_pet_id() { std::lock_guard<std::mutex> lk(classMutex); return pet_id_; }
 
 	std::string get_pet_name() { std::lock_guard<std::mutex> lk(classMutex); return pet_name_; }
-	float	 get_pet_health_pct() { std::lock_guard<std::mutex> lk(classMutex); return pet_health_pct_; }
-	float	 get_pet_power_pct() { std::lock_guard<std::mutex> lk(classMutex); return pet_power_pct_; }
-	int8	 get_pet_movement() { std::lock_guard<std::mutex> lk(classMutex); return pet_movement_; }
-	int8	 get_pet_behavior() { std::lock_guard<std::mutex> lk(classMutex); return pet_behavior_; }
-	int8	 get_vision() { std::lock_guard<std::mutex> lk(classMutex); return vision_; }
-	int8	 get_breathe_underwater() { std::lock_guard<std::mutex> lk(classMutex); return breathe_underwater_; }
+	float	get_pet_health_pct() { std::lock_guard<std::mutex> lk(classMutex); return pet_health_pct_; }
+	float	get_pet_power_pct() { std::lock_guard<std::mutex> lk(classMutex); return pet_power_pct_; }
+	int8	get_pet_movement() { std::lock_guard<std::mutex> lk(classMutex); return pet_movement_; }
+	int8	get_pet_behavior() { std::lock_guard<std::mutex> lk(classMutex); return pet_behavior_; }
+	int8	get_vision() { std::lock_guard<std::mutex> lk(classMutex); return vision_; }
+	int8	get_breathe_underwater() { std::lock_guard<std::mutex> lk(classMutex); return breathe_underwater_; }
 	std::string get_biography() { std::lock_guard<std::mutex> lk(classMutex); return biography_; }
-	float	 get_drunk() { std::lock_guard<std::mutex> lk(classMutex); return drunk_; }
+	float	get_drunk() { std::lock_guard<std::mutex> lk(classMutex); return drunk_; }
+
+	sint16	get_power_regen() { std::lock_guard<std::mutex> lk(classMutex); return power_regen_; }
+	sint16	get_hp_regen() { std::lock_guard<std::mutex> lk(classMutex); return hp_regen_; }
 
-	sint16	 get_power_regen() { std::lock_guard<std::mutex> lk(classMutex); return power_regen_; }
-	sint16	 get_hp_regen() { std::lock_guard<std::mutex> lk(classMutex); return hp_regen_; }
+	int8	get_power_regen_override() { std::lock_guard<std::mutex> lk(classMutex); return power_regen_override_; }
+	int8	get_hp_regen_override() { std::lock_guard<std::mutex> lk(classMutex); return hp_regen_override_; }
 
-	int8	 get_power_regen_override() { std::lock_guard<std::mutex> lk(classMutex); return power_regen_override_; }
-	int8	 get_hp_regen_override() { std::lock_guard<std::mutex> lk(classMutex); return hp_regen_override_; }
+	int8	get_water_type() { std::lock_guard<std::mutex> lk(classMutex); return water_type_; }
+	int8	get_flying_type() { std::lock_guard<std::mutex> lk(classMutex); return flying_type_; }
 
-	int8	 get_water_type() { std::lock_guard<std::mutex> lk(classMutex); return water_type_; }
-	int8	 get_flying_type() { std::lock_guard<std::mutex> lk(classMutex); return flying_type_; }
+	int8	get_no_interrupt() { std::lock_guard<std::mutex> lk(classMutex); return no_interrupt_; }
 
 	void	set_name(std::string value) { std::lock_guard<std::mutex> lk(classMutex); name_ = value; }
 	
@@ -805,6 +811,8 @@ struct InfoStruct{
 	void	set_water_type(int8 value) { std::lock_guard<std::mutex> lk(classMutex); water_type_ = value; }
 	void	set_flying_type(int8 value) { std::lock_guard<std::mutex> lk(classMutex); flying_type_ = value; }
 
+	void	set_no_interrupt(int8 value) { std::lock_guard<std::mutex> lk(classMutex); no_interrupt_ = value; }
+
 	void	ResetEffects(Spawn* spawn)
 	{
 		for(int i=0;i<45;i++){
@@ -970,6 +978,8 @@ private:
 
 	int8			water_type_;
 	int8			flying_type_;
+
+	int8			no_interrupt_;
 	// when PacketStruct is fixed for C++17 this should become a shared_mutex and handle read/write lock
 	std::mutex		classMutex;
 };
@@ -1258,21 +1268,51 @@ public:
 	void SetHairType(int16 new_val, bool setUpdateFlags = true){
 		SetInfo(&features.hair_type, new_val, setUpdateFlags);
 	}
+	void SetHairColor1(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.hair_color1, new_val, setUpdateFlags);
+	}
+	void SetHairColor2(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.hair_color2, new_val, setUpdateFlags);
+	}
+	void SetSogaHairColor1(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.soga_hair_color1, new_val, setUpdateFlags);
+	}
+	void SetSogaHairColor2(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.soga_hair_color2, new_val, setUpdateFlags);
+	}
+	void SetHairHighlightColor(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.hair_highlight_color, new_val, setUpdateFlags);
+	}
+	void SetSogaHairHighlightColor(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.soga_hair_highlight_color, new_val, setUpdateFlags);
+	}
 	void SetHairColor(EQ2_Color new_val, bool setUpdateFlags = true){
 		SetInfo(&features.hair_type_color, new_val, setUpdateFlags);
 	}
-	void SetHairHighlightColor(EQ2_Color new_val, bool setUpdateFlags = true){
+	void SetSogaHairColor(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.soga_hair_type_color, new_val, setUpdateFlags);
+	}
+	void SetHairTypeHighlightColor(EQ2_Color new_val, bool setUpdateFlags = true){
 		SetInfo(&features.hair_type_highlight_color, new_val, setUpdateFlags);
 	}
+	void SetSogaHairTypeHighlightColor(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.soga_hair_type_highlight_color, new_val, setUpdateFlags);
+	}
 	void SetFacialHairType(int16 new_val, bool setUpdateFlags = true){
 		SetInfo(&features.hair_face_type, new_val, setUpdateFlags);
 	}
 	void SetFacialHairColor(EQ2_Color new_val, bool setUpdateFlags = true){
 		SetInfo(&features.hair_face_color, new_val, setUpdateFlags);
 	}
+	void SetSogaFacialHairColor(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.soga_hair_face_color, new_val, setUpdateFlags);
+	}
 	void SetFacialHairHighlightColor(EQ2_Color new_val, bool setUpdateFlags = true){
 		SetInfo(&features.hair_face_highlight_color, new_val, setUpdateFlags);
 	}
+	void SetSogaFacialHairHighlightColor(EQ2_Color new_val, bool setUpdateFlags = true){
+		SetInfo(&features.soga_hair_face_highlight_color, new_val, setUpdateFlags);
+	}
 	void SetWingType(int16 new_val, bool setUpdateFlags = true){
 		SetInfo(&features.wing_type, new_val, setUpdateFlags);
 	}
@@ -1303,6 +1343,15 @@ public:
 	void SetSkinColor(EQ2_Color color){
 		SetInfo(&features.skin_color, color);
 	}
+	void SetSogaSkinColor(EQ2_Color color){
+		SetInfo(&features.soga_skin_color, color);
+	}
+	void SetModelColor(EQ2_Color color){
+		SetInfo(&features.model_color, color);
+	}
+	void SetSogaModelColor(EQ2_Color color){
+		SetInfo(&features.soga_model_color, color);
+	}
 	void SetCombatVoice(int16 val, bool setUpdateFlags = true) { 
 		SetInfo(&features.combat_voice, val, setUpdateFlags); 
 	}
@@ -1321,6 +1370,9 @@ public:
 	void SetEyeColor(EQ2_Color eye_color){
 		SetInfo(&features.eye_color, eye_color);
 	}
+	void SetSogaEyeColor(EQ2_Color eye_color){
+		SetInfo(&features.soga_eye_color, eye_color);
+	}
 	int16 GetHairType(){
 		return features.hair_type;
 	}
@@ -1351,6 +1403,12 @@ public:
 	EQ2_Color* GetSkinColor(){
 		return &features.skin_color;
 	}
+	EQ2_Color* GetModelColor(){
+		return &features.model_color;
+	}
+	EQ2_Color* GetSogaModelColor(){
+		return &features.soga_model_color;
+	}
 	EQ2_Color* GetEyeColor(){
 		return &features.eye_color;
 	}

+ 19 - 15
EQ2/source/WorldServer/SpellProcess.cpp

@@ -364,6 +364,20 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason){
 			active_spells.Remove(spell);
 		if (spell->caster) {
 			if (spell->spell->GetSpellData()->cast_type == SPELL_CAST_TYPE_TOGGLE){
+				
+				int8 actual_concentration = spell->spell->GetSpellData()->req_concentration;
+
+				if (actual_concentration > 0)
+				{
+					int8 curConcentration = spell->caster->GetInfoStruct()->get_cur_concentration();
+					if(curConcentration >= actual_concentration)
+					{
+						spell->caster->GetInfoStruct()->set_cur_concentration(curConcentration - actual_concentration);
+						if (spell->caster->IsPlayer())
+							spell->caster->GetZone()->TriggerCharSheetTimer();
+					}
+				}
+				
 				CheckRecast(spell->spell, spell->caster);
 				if (spell->caster && spell->caster->IsPlayer())
 					SendSpellBookUpdate(spell->caster->GetZone()->GetClientBySpawn(spell->caster));
@@ -643,7 +657,7 @@ bool SpellProcess::TakeHP(LuaSpell* spell) {
 
 bool SpellProcess::CheckConcentration(LuaSpell* spell) {
 	if (spell && spell->caster) {
-		int8 req = spell->spell->GetSpellData()->req_concentration / 256;
+		int8 req = spell->spell->GetSpellData()->req_concentration;
 		int8 current_avail = 5 - spell->caster->GetConcentrationCurrent();
 		if (current_avail >= req)
 			return true;
@@ -653,10 +667,10 @@ bool SpellProcess::CheckConcentration(LuaSpell* spell) {
 
 bool SpellProcess::AddConcentration(LuaSpell* spell) {
 	if (spell && spell->caster) {
-		int8 req = spell->spell->GetSpellData()->req_concentration / 256;
-		int8 current_avail = 5 - spell->caster->GetConcentrationCurrent();
+		int8 req = spell->spell->GetSpellData()->req_concentration;
+		int8 curConcentration = spell->caster->GetInfoStruct()->get_cur_concentration();
+		int8 current_avail = 5 - curConcentration;
 		if (current_avail >= req) {
-			int8 curConcentration = spell->caster->GetInfoStruct()->get_cur_concentration();
 			spell->caster->GetInfoStruct()->set_cur_concentration(curConcentration + req);
 			if (spell->caster->IsPlayer())
 				spell->caster->GetZone()->TriggerCharSheetTimer();
@@ -925,19 +939,9 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
 		if (spell->GetSpellData()->cast_type == SPELL_CAST_TYPE_TOGGLE)
 		{
 			bool ret_val = DeleteCasterSpell(caster, spell, "purged");
-
+			
 			if (ret_val)
 			{
-				int8 actual_concentration = spell->GetSpellData()->req_concentration / 256;
-
-				if (actual_concentration > 0)
-				{
-					int8 curConcentration = caster->GetInfoStruct()->get_cur_concentration();
-					caster->GetInfoStruct()->set_cur_concentration(curConcentration - actual_concentration);
-					if (caster->IsPlayer())
-						caster->GetZone()->TriggerCharSheetTimer();
-				}
-
 				lua_spell->caster->GetZone()->GetSpellProcess()->RemoveSpellScriptTimerBySpell(lua_spell);
 				DeleteSpell(lua_spell);
 				return;