Lua SPell targeting Discussion

EQ2Emulator Development forum.

Moderator: Team Members

User avatar
Ememjr
Team Member
Posts: 975
Joined: Wed Mar 15, 2017 9:41 am
EQ2Emu Server: Perseverance

Re: Lua SPell targeting Discussion

Post by Ememjr » Tue May 07, 2019 4:14 am

so still looking at this and started coding on my end to test our theories, and my idea would work perfect on a lifetap spell where no matter the
spells target does damage( then a secondary heal or damage to the caster or a different target) but would still have an issue with
holy circle,
since there are not to many holy circle type spells that i know of

aoe damage and a group heal
(aself heal would be handled by new code mentioned before)

Holy Circle can actually be done with no additional code changes right now

spelldamage(targetlist, damagetype damage) will damage the aoe
for the heal portion can easily be done by

Code: Select all

 var = GetGroup(Caster)
        for k,v in ipairs(var) do
        spellheal(v,"heal",100)
       
    end
*** on a side note , how are we currently handling heal that use a percentage, Heals group members (AE) for Y% of max health, i guess like this will work

Code: Select all

 var = GetGroup(Caster)
        for k,v in ipairs(var) do
        spellheal(v,"heal",GetMaxHP(v) * .10 )
       
    end

Jabantiz
Lead Developer
Posts: 2912
Joined: Wed Jul 25, 2007 2:52 pm
Location: California

Re: Lua SPell targeting Discussion

Post by Jabantiz » Tue May 07, 2019 12:35 pm

Ememjr wrote: Tue May 07, 2019 4:14 am how are we currently handling heal that use a percentage, Heals group members (AE) for Y% of max health
Yea we have to calculate it in the lua script. It might be a good idea to add another type of heal (the string param) something like "heal%" and then pass the percentages to the function and let the server calculate it for each target.

As of now a normal group heal that heals by percentage will be an issue as we would need to do the loop over the group like you posted but the odds are one of those will be the initial target causing it to heal every one else as well when that target is passed.

User avatar
Ememjr
Team Member
Posts: 975
Joined: Wed Mar 15, 2017 9:41 am
EQ2Emu Server: Perseverance

Re: Lua SPell targeting Discussion

Post by Ememjr » Tue May 07, 2019 2:52 pm

Jabantiz wrote: Tue May 07, 2019 12:35 pm
Ememjr wrote: Tue May 07, 2019 4:14 am how are we currently handling heal that use a percentage, Heals group members (AE) for Y% of max health
Yea we have to calculate it in the lua script. It might be a good idea to add another type of heal (the string param) something like "heal%" and then pass the percentages to the function and let the server calculate it for each target.

As of now a normal group heal that heals by percentage will be an issue as we would need to do the loop over the group like you posted but the odds are one of those will be the initial target causing it to heal every one else as well when that target is passed.
i would agree using a spell string of "heal%", would by wise, and adding a "power%" as well, while we are at it

i have started redoing the lua functions on my test server

these are the 4 i am changing, will add more as i notice them
AddSpellBonus
AddSKillBonus
SpellDamage
SpellHeal

i think we will need
ProcDamage as well , we should keep it as in a Proc that needs to proc against a group will have a new target list anyway( at least it should),
ie.. you could have a damage proc goin off against the current group of mobs, and then you attack another group with an AOE and that group will then have a proc against it ( if there are even any procs against multiple targets

User avatar
Ememjr
Team Member
Posts: 975
Joined: Wed Mar 15, 2017 9:41 am
EQ2Emu Server: Perseverance

Re: Lua SPell targeting Discussion

Post by Ememjr » Wed May 08, 2019 3:55 am

another thing i notice after looking even deeper

SpellHeal was modify a while back which move target to the 4th param(optional), and it appears to work like that no target specified it goes to target list, target specified it then goes to target,

so for now i will not be modifying SpellHeal, until the time we say lets change it to be like SpellDamage , at which time we would have to change all the spell scripts that use it (almost wish SPellDamage worked the same way)

SpellHeal should not need changing(except to add "heal%" capability, it will work with lifetap as is
holy circle with a group iteration will be fine
here is SpellDamage with my changes
you will see i have also added functionality for race(working), and faction(not complete, haven't figure a good use case yet)

Code: Select all

int EQ2Emu_lua_SpellDamage(lua_State* state){
	if(!lua_interface)
		return 0;
	Spawn* target = lua_interface->GetSpawn(state);
	int32 target_id = target->GetID();
	LuaSpell* luaspell = lua_interface->GetCurrentSpell(state);
	if(!luaspell)
		return 0;
	Spawn* caster = luaspell->caster;
	sint32 type = lua_interface->GetSInt32Value(state, 2);
	int32 min_damage = lua_interface->GetInt32Value(state, 3);
	int32 max_damage = lua_interface->GetInt32Value(state, 4);
	int8 crit_mod = lua_interface->GetInt32Value(state, 5);
	bool no_calcs = lua_interface->GetInt32Value(state, 6) == 1;
	//lua_interface->ResetFunctionStack(state);
	int32 class_id = lua_interface->GetInt32Value(state, 7);
	vector<int16> faction_req;
	vector<int16> race_req;
	int32 class_req = 0;
	int32 i = 0;
	int8 f = 0;
	int8 r = 0;
	while ((class_id = lua_interface->GetInt32Value(state, 7 + i))) {
		if (class_id < 100) {
			class_req += pow(2.0, double(class_id - 1));
		}
		else if (class_id > 100 && class_id < 1000) {
			race_req.push_back(class_id);
			r++;
		}
		else {
			faction_req.push_back(class_id);
			f++;
		}
		i++;
	}
	if(caster && caster->IsEntity()){
		bool race_match = false;
		bool success = false;
		luaspell->resisted = false;
		if (luaspell->initial_target == target_id) {
			int xxx = 0;
		}
		if (luaspell->targets.size() > 0 && (luaspell->initial_target != target_id)) {
			ZoneServer* zone = luaspell->caster->GetZone();
			Spawn* target = 0;
			luaspell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
			for (int32 i = 0; i < luaspell->targets.size(); i++) {
				if ((target = zone->GetSpawnByID(luaspell->targets[i]))) {

					if (race_req.size() > 0) {
						for (int8 i=0; i < race_req.size(); i++) {

							int32 xxx = target->GetLuaRaceId();
							if (target->GetLuaRaceId() == race_req[i]) {
								race_match = true;
							}
						}
					}
					else
						race_match = true; // if the race_req.size = 0 then there is no race requirement and the race_match will be true
					if (race_match == true) {
						float distance = caster->GetDistance(target, true);
						distance -= caster->appearance.pos.collision_radius / 10;
						distance -= target->appearance.pos.collision_radius / 10;
						((Entity*)caster)->SpellAttack(target, distance, luaspell, type, min_damage, max_damage, crit_mod, no_calcs);
					}
				}
			}
			success = true;
			luaspell->MSpellTargets.releasereadlock(__FUNCTION__, __LINE__);
		}
		else if (target) {

			//check class and race/faction here
			if (race_req.size() > 0) {
				for (int8 i; i < race_req.size(); i++) {
					if (target->GetLuaRaceId() == race_req[i]) {
						race_match = true;
					}
				}
			}
			else
				race_match = true; // if the race_req.size = 0 then there is no race requirement and the race_match will be true
			if (race_match == true) {
				float distance = caster->GetDistance(target, true);
				distance -= caster->appearance.pos.collision_radius / 10;
				distance -= target->appearance.pos.collision_radius / 10;
				if (((Entity*)caster)->SpellAttack(target, distance, luaspell, type, min_damage, max_damage, crit_mod, no_calcs))
					success = true;
			}
		}
		if (success) {
			Spell* spell = luaspell->spell;
			if(caster->IsPlayer() && spell && spell->GetSpellData()->target_type == 1 && spell->GetSpellData()->spell_book_type == 1){ //offense combat art
				((Player*)caster)->InCombat(true);
				if(caster->GetZone())
					caster->GetZone()->TriggerCharSheetTimer();
			}
		}
	}
	return 0;
}
for the new support to check the target to see if it is initial target is if (luaspell->targets.size() > 0 && (luaspell->initial_target != target_id)) {

so if there is a target list and the target specified is not the initial target then it will run through the target list otherwise it will use the specified target

the new race id works almost like the class_is so when you specifiy a class 0r classes the in lua function the damage will only take effect on that class

race works the same way, you still have multiples and the param takes both race and class even intermixed just
spelldamage would then be applied to those classes and races send from lua

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest