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