Broke fixes, 1h/2h equip fixes, swapping equip works, more crash fixes
Partial Address Issue #328 - tier 0 items display, 2h now display Fix #298 - can't equip a 1h while 2h is equipped. Swapping equipment slots now works for both combat/appearance equip. Fix #201 - when scribing, new tier spell will display on hover over of spellbook or hotbar Fixed a crash with spell conflict doing double delete on lua spell Fix #152 - addressed divine awakening, via new target_type (10) SPELL_TARGET_ALLGROUPTARGETS - this will call cast for each player instead of just the direct target righteousness and decree now supported as a group target AE Better connection closure from client to world on camping/zoning out
This commit is contained in:
parent
a972bf9325
commit
4c9197f54e
15 changed files with 199 additions and 59 deletions
|
@ -1773,7 +1773,11 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
player->item_list.RemoveItem(item, true);
|
||||
client->QueuePacket(player->GetSpellBookUpdatePacket(client->GetVersion()));
|
||||
client->QueuePacket(player->SendInventoryUpdate(client->GetVersion()));
|
||||
}
|
||||
|
||||
// force purge client cache and display updated spell for hover over
|
||||
EQ2Packet* app = spell->SerializeSpell(client, false, false);
|
||||
client->QueuePacket(app);
|
||||
}
|
||||
}
|
||||
else
|
||||
LogWrite(COMMAND__ERROR, 0, "Command", "Unknown spell ID: %u and tier: %u", item->skill_info->spell_id, item->skill_info->spell_tier);
|
||||
|
@ -3669,6 +3673,8 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
if(sep && sep->arg[0][0]){
|
||||
const char* values = sep->argplus[0];
|
||||
if(values){
|
||||
LogWrite(ITEM__WARNING, 0, "Item", "SearchStores: %s", values);
|
||||
|
||||
map<string, string> str_values = TranslateBrokerRequest(values);
|
||||
vector<Item*>* items = master_item_list.GetItems(str_values);
|
||||
if(items){
|
||||
|
@ -6177,7 +6183,11 @@ void Commands::Command_Inventory(Client* client, Seperator* sep, EQ2_RemoteComma
|
|||
LogWrite(MISC__TODO, 1, "TODO", " fix this, need to get how live does it\n\t(%s, function: %s, line #: %i)", __FILE__, __FUNCTION__, __LINE__);
|
||||
int16 index1 = atoi(sep->arg[1]);
|
||||
int16 index2 = atoi(sep->arg[2]);
|
||||
EQ2Packet* outapp = client->GetPlayer()->SwapEquippedItems(index1, index2, client->GetVersion());
|
||||
int8 type = 0;
|
||||
if(sep->IsNumber(3))
|
||||
type = atoul(sep->arg[3]); // type 0 is combat, 3 = appearance
|
||||
|
||||
EQ2Packet* outapp = client->GetPlayer()->SwapEquippedItems(index1, index2, client->GetVersion(), type);
|
||||
|
||||
if(outapp)
|
||||
client->QueuePacket(outapp);
|
||||
|
|
|
@ -88,7 +88,7 @@ MasterItemList::~MasterItemList(){
|
|||
RemoveAll();
|
||||
}
|
||||
|
||||
vector<Item*>* MasterItemList::GetItems(string name, int32 itype, int32 ltype, int32 btype, int64 minprice, int64 maxprice, int8 minskill, int8 maxskill, string seller, string adornment, int8 mintier, int8 maxtier, int16 minlevel, int16 maxlevel, sint8 itemclass){
|
||||
vector<Item*>* MasterItemList::GetItems(string name, int64 itype, int32 ltype, int32 btype, int64 minprice, int64 maxprice, int8 minskill, int8 maxskill, string seller, string adornment, int8 mintier, int8 maxtier, int16 minlevel, int16 maxlevel, sint8 itemclass){
|
||||
vector<Item*>* ret = new vector<Item*>;
|
||||
map<int32,Item*>::iterator iter;
|
||||
Item* item = 0;
|
||||
|
@ -101,11 +101,12 @@ vector<Item*>* MasterItemList::GetItems(string name, int32 itype, int32 ltype, i
|
|||
// chkseller = seller.c_str();
|
||||
//if(adornment.length() > 0)
|
||||
// chkadornment = adornment.c_str();
|
||||
LogWrite(ITEM__WARNING, 0, "Item", "Get Items: %s (itype: %llu, ltype: %u, btype: %u, minskill: %u, maxskill: %u, mintier: %u, maxtier: %u, minlevel: %u, maxlevel: %u itemclass %i)", name.c_str(), itype, ltype, btype, minskill, maxskill, mintier, maxtier, minlevel, maxlevel, itemclass);
|
||||
bool should_add = true;
|
||||
for(iter = items.begin();iter != items.end(); iter++){
|
||||
item = iter->second;
|
||||
if(item){
|
||||
if(itype != ITEM_BROKER_TYPE_ANY){
|
||||
if(itype != ITEM_BROKER_TYPE_ANY && itype != ITEM_BROKER_TYPE_ANY64BIT){
|
||||
should_add = false;
|
||||
switch(itype){
|
||||
case ITEM_BROKER_TYPE_ADORNMENT:{
|
||||
|
@ -253,6 +254,18 @@ vector<Item*>* MasterItemList::GetItems(string name, int32 itype, int32 ltype, i
|
|||
should_add = true;
|
||||
break;
|
||||
}
|
||||
case ITEM_BROKER_TYPE_2H_CRUSH:{
|
||||
should_add = item->IsWeapon() && item->weapon_info->wield_type == ITEM_WIELD_TYPE_TWO_HAND && item->generic_info.skill_req1 == SKILL_ID_STAFF;
|
||||
break;
|
||||
}
|
||||
case ITEM_BROKER_TYPE_2H_PIERCE:{
|
||||
should_add = item->IsWeapon() && item->weapon_info->wield_type == ITEM_WIELD_TYPE_TWO_HAND && item->generic_info.skill_req1 == SKILL_ID_GREATSPEAR;
|
||||
break;
|
||||
}
|
||||
case ITEM_BROKER_TYPE_2H_SLASH:{
|
||||
should_add = item->IsWeapon() && item->weapon_info->wield_type == ITEM_WIELD_TYPE_TWO_HAND && item->generic_info.skill_req1 == SKILL_ID_GREATSWORD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!should_add)
|
||||
continue;
|
||||
|
@ -635,7 +648,8 @@ vector<Item*>* MasterItemList::GetItems(string name, int32 itype, int32 ltype, i
|
|||
if(maxlevel > 0 && ((item->generic_info.adventure_default_level > 0 && item->generic_info.adventure_default_level > maxlevel) || (item->generic_info.tradeskill_default_level > 0 && item->generic_info.tradeskill_default_level > maxlevel)))
|
||||
continue;
|
||||
}
|
||||
if(mintier > 0 && item->details.tier < mintier)
|
||||
// mintier of 1 is 'ANY'
|
||||
if(mintier > 1 && item->details.tier < mintier)
|
||||
continue;
|
||||
if(maxtier > 0 && item->details.tier > maxtier)
|
||||
continue;
|
||||
|
@ -651,7 +665,7 @@ vector<Item*>* MasterItemList::GetItems(string name, int32 itype, int32 ltype, i
|
|||
|
||||
vector<Item*>* MasterItemList::GetItems(map<string, string> criteria){
|
||||
string name, seller, adornment;
|
||||
int32 itype = 0xFFFFFFFF;
|
||||
int64 itype = 0xFFFFFFFFFFFFFFFF;
|
||||
int32 ltype = 0xFFFFFFFF;
|
||||
int32 btype = 0xFFFFFFFF;
|
||||
int64 minprice = 0;
|
||||
|
@ -691,7 +705,7 @@ vector<Item*>* MasterItemList::GetItems(map<string, string> criteria){
|
|||
if(criteria.count("MAXLEVEL") > 0)
|
||||
maxlevel = (int16)ParseIntValue(criteria["MAXLEVEL"]);
|
||||
if(criteria.count("ITYPE") > 0)
|
||||
itype = ParseIntValue(criteria["ITYPE"]);
|
||||
itype = ParseLongLongValue(criteria["ITYPE"]);
|
||||
if(criteria.count("LTYPE") > 0)
|
||||
ltype = ParseIntValue(criteria["LTYPE"]);
|
||||
if(criteria.count("BTYPE") > 0)
|
||||
|
@ -3910,6 +3924,12 @@ bool EquipmentItemList::CheckEquipSlot(Item* tmp, int8 slot){
|
|||
if(tmp->slot_data[i] == slot){
|
||||
Item* tmp_item = GetItem(tmp->slot_data[i]);
|
||||
if(!tmp_item || tmp_item->details.item_id == 0){
|
||||
if(slot == EQ2_SECONDARY_SLOT)
|
||||
{
|
||||
Item* primary = GetItem(EQ2_PRIMARY_SLOT);
|
||||
if(primary && primary->weapon_info->wield_type == ITEM_WIELD_TYPE_TWO_HAND)
|
||||
continue;
|
||||
}
|
||||
MEquipmentItems.unlock();
|
||||
return true;
|
||||
}
|
||||
|
@ -3927,6 +3947,12 @@ int8 EquipmentItemList::GetFreeSlot(Item* tmp, int8 slot_id){
|
|||
if(slot_id == 255 || slot == slot_id){
|
||||
Item* tmp_item = GetItem(slot);
|
||||
if(!tmp_item || tmp_item->details.item_id == 0){
|
||||
if(slot == EQ2_SECONDARY_SLOT)
|
||||
{
|
||||
Item* primary = GetItem(EQ2_PRIMARY_SLOT);
|
||||
if(primary && primary->weapon_info->wield_type == ITEM_WIELD_TYPE_TWO_HAND)
|
||||
continue;
|
||||
}
|
||||
MEquipmentItems.unlock();
|
||||
return slot;
|
||||
}
|
||||
|
|
|
@ -264,6 +264,7 @@ extern MasterItemList master_item_list;
|
|||
#define ITEM_TAG_MYTHICAL 12
|
||||
|
||||
#define ITEM_BROKER_TYPE_ANY 0xFFFFFFFF
|
||||
#define ITEM_BROKER_TYPE_ANY64BIT 0xFFFFFFFFFFFFFFFF
|
||||
#define ITEM_BROKER_TYPE_ADORNMENT 134217728
|
||||
#define ITEM_BROKER_TYPE_AMMO 1024
|
||||
#define ITEM_BROKER_TYPE_ATTUNEABLE 16384
|
||||
|
@ -294,6 +295,10 @@ extern MasterItemList master_item_list;
|
|||
#define ITEM_BROKER_TYPE_TINKERED 268435456
|
||||
#define ITEM_BROKER_TYPE_TRADESKILL 256
|
||||
|
||||
#define ITEM_BROKER_TYPE_2H_CRUSH 17179869184
|
||||
#define ITEM_BROKER_TYPE_2H_PIERCE 34359738368
|
||||
#define ITEM_BROKER_TYPE_2H_SLASH 8589934592
|
||||
|
||||
#define ITEM_BROKER_SLOT_ANY 0xFFFFFFFF
|
||||
#define ITEM_BROKER_SLOT_AMMO 65536
|
||||
#define ITEM_BROKER_SLOT_CHARM 524288
|
||||
|
@ -988,7 +993,7 @@ public:
|
|||
Item* GetItemByName(const char *name);
|
||||
ItemStatsValues* CalculateItemBonuses(int32 item_id, Entity* entity = 0);
|
||||
ItemStatsValues* CalculateItemBonuses(Item* desc, Entity* entity = 0, ItemStatsValues* values = 0);
|
||||
vector<Item*>* GetItems(string name, int32 itype, int32 ltype, int32 btype, int64 minprice, int64 maxprice, int8 minskill, int8 maxskill, string seller, string adornment, int8 mintier, int8 maxtier, int16 minlevel, int16 maxlevel, sint8 itemclass);
|
||||
vector<Item*>* GetItems(string name, int64 itype, int32 ltype, int32 btype, int64 minprice, int64 maxprice, int8 minskill, int8 maxskill, string seller, string adornment, int8 mintier, int8 maxtier, int16 minlevel, int16 maxlevel, sint8 itemclass);
|
||||
vector<Item*>* GetItems(map<string, string> criteria);
|
||||
void AddItem(Item* item);
|
||||
bool IsBag(int32 item_id);
|
||||
|
|
|
@ -535,7 +535,7 @@ bool LuaInterface::LoadRegionScript(string name) {
|
|||
return LoadRegionScript(name.c_str());
|
||||
}
|
||||
|
||||
std::string LuaInterface::AddSpawnPointers(LuaSpell* spell, bool first_cast, bool precast, const char* function, SpellScriptTimer* timer, bool passLuaSpell) {
|
||||
std::string LuaInterface::AddSpawnPointers(LuaSpell* spell, bool first_cast, bool precast, const char* function, SpellScriptTimer* timer, bool passLuaSpell, Spawn* altTarget) {
|
||||
std::string functionCalled = string("");
|
||||
if (function)
|
||||
{
|
||||
|
@ -578,7 +578,11 @@ std::string LuaInterface::AddSpawnPointers(LuaSpell* spell, bool first_cast, boo
|
|||
if (temp_spawn)
|
||||
SetSpawnValue(spell->state, temp_spawn);
|
||||
else {
|
||||
if(spell->caster && spell->caster->GetZone() != nullptr && spell->initial_target)
|
||||
if(altTarget)
|
||||
{
|
||||
SetSpawnValue(spell->state, altTarget);
|
||||
}
|
||||
else if(spell->caster && spell->caster->GetZone() != nullptr && spell->initial_target)
|
||||
{
|
||||
// easier to debug target id as ptr
|
||||
Spawn* new_target = spell->caster->GetZone()->GetSpawnByID(spell->initial_target);
|
||||
|
|
|
@ -233,7 +233,7 @@ public:
|
|||
void SetConversationValue(lua_State* state, vector<ConversationOption>* conversation);
|
||||
void SetOptionWindowValue(lua_State* state, vector<OptionWindowOption>* optionWindow);
|
||||
|
||||
std::string AddSpawnPointers(LuaSpell* spell, bool first_cast, bool precast = false, const char* function = 0, SpellScriptTimer* timer = 0, bool passLuaSpell=false);
|
||||
std::string AddSpawnPointers(LuaSpell* spell, bool first_cast, bool precast = false, const char* function = 0, SpellScriptTimer* timer = 0, bool passLuaSpell=false, Spawn* altTarget = 0);
|
||||
LuaSpell* GetCurrentSpell(lua_State* state);
|
||||
bool CallSpellProcess(LuaSpell* spell, int8 num_parameters, std::string functionCalled);
|
||||
LuaSpell* GetSpell(const char* name);
|
||||
|
|
|
@ -2016,19 +2016,42 @@ void Player::SetEquippedItemAppearances(){
|
|||
GetZone()->SendSpawnChanges(this);
|
||||
}
|
||||
|
||||
EQ2Packet* Player::SwapEquippedItems(int8 slot1, int8 slot2, int16 version){
|
||||
Item* item_from = equipment_list.items[slot1];
|
||||
Item* item_to = equipment_list.items[slot2];
|
||||
if(item_from && equipment_list.CanItemBeEquippedInSlot(item_from, slot2)){
|
||||
EQ2Packet* Player::SwapEquippedItems(int8 slot1, int8 slot2, int16 version, int16 equip_type){
|
||||
EquipmentItemList* equipList = &equipment_list;
|
||||
|
||||
// right now client seems to pass 3 for this? Not sure why when other fields has appearance equipment as type 1
|
||||
if(equip_type == 3)
|
||||
equipList = &appearance_equipment_list;
|
||||
|
||||
Item* item_from = equipList->items[slot1];
|
||||
Item* item_to = equipList->items[slot2];
|
||||
if(item_from && equipList->CanItemBeEquippedInSlot(item_from, slot2)){
|
||||
if(item_to){
|
||||
if(!equipment_list.CanItemBeEquippedInSlot(item_to, slot1))
|
||||
if(!equipList->CanItemBeEquippedInSlot(item_to, slot1))
|
||||
return 0;
|
||||
item_to->details.slot_id = slot1;
|
||||
}
|
||||
equipList->items[slot1] = nullptr;
|
||||
equipList->SetItem(slot2, item_from);
|
||||
if(item_to)
|
||||
{
|
||||
equipList->SetItem(slot1, item_to);
|
||||
item_to->save_needed = true;
|
||||
}
|
||||
item_from->save_needed = true;
|
||||
item_from->details.slot_id = slot2;
|
||||
return equipment_list.serialize(version, this);
|
||||
|
||||
if (GetClient())
|
||||
{
|
||||
//EquipmentItemList* equipList = &equipment_list;
|
||||
|
||||
//if(appearance_type)
|
||||
// equipList = &appearance_equipment_list;
|
||||
|
||||
if(item_to)
|
||||
GetClient()->QueuePacket(item_to->serialize(version, false, this));
|
||||
GetClient()->QueuePacket(item_from->serialize(version, false, this));
|
||||
GetClient()->QueuePacket(item_list.serialize(this, version));
|
||||
}
|
||||
return equipList->serialize(version, this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -453,7 +453,7 @@ public:
|
|||
vector<EQ2Packet*> UnequipItem(int16 index, sint32 bag_id, int8 slot, int16 version, int8 appearance_type = 0);
|
||||
int8 ConvertSlotToClient(int8 slot, int16 version);
|
||||
int8 ConvertSlotFromClient(int8 slot, int16 version);
|
||||
EQ2Packet* SwapEquippedItems(int8 slot1, int8 slot2, int16 version);
|
||||
EQ2Packet* SwapEquippedItems(int8 slot1, int8 slot2, int16 version, int16 equiptype);
|
||||
EQ2Packet* RemoveInventoryItem(int8 bag_slot, int8 slot);
|
||||
EQ2Packet* SendInventoryUpdate(int16 version);
|
||||
EQ2Packet* SendBagUpdate(int32 bag_unique_id, int16 version);
|
||||
|
|
|
@ -66,6 +66,10 @@
|
|||
#define SKILL_ID_DESTROYING 3429135390
|
||||
#define SKILL_ID_MAGIC_AFFINITY 2072844078
|
||||
|
||||
#define SKILL_ID_GREATSWORD 2292577688 // aka 2h slashing
|
||||
#define SKILL_ID_GREATSPEAR 2380184628 // aka 2h piercing
|
||||
#define SKILL_ID_STAFF 3180399725 // aka 2h crushing
|
||||
|
||||
/* Each SkillBonus is comprised of multiple possible skill bonus values. This is so one spell can modify
|
||||
more than one skill */
|
||||
struct SkillBonusValue {
|
||||
|
|
|
@ -447,44 +447,69 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removi
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool SpellProcess::ProcessSpell(LuaSpell* spell, bool first_cast, const char* function, SpellScriptTimer* timer) {
|
||||
bool SpellProcess::ProcessSpell(LuaSpell* spell, bool first_cast, const char* function, SpellScriptTimer* timer, bool all_targets) {
|
||||
bool ret = false;
|
||||
if(!spell->state)
|
||||
{
|
||||
LogWrite(SPELL__ERROR, 0, "Spell", "Error: State is NULL! SpellProcess::ProcessSpell for Spell '%s'", (spell->spell != nullptr) ? spell->spell->GetName() : "Unknown");
|
||||
}
|
||||
else if(lua_interface && !spell->interrupted){
|
||||
std::string functionCall = lua_interface->AddSpawnPointers(spell, first_cast, false, function, timer);
|
||||
vector<LUAData*>* data = spell->spell->GetLUAData();
|
||||
for(int32 i=0;i<data->size();i++){
|
||||
switch(data->at(i)->type){
|
||||
case 0:{
|
||||
lua_interface->SetSInt32Value(spell->state, data->at(i)->int_value);
|
||||
break;
|
||||
}
|
||||
case 1:{
|
||||
lua_interface->SetFloatValue(spell->state, data->at(i)->float_value);
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
lua_interface->SetBooleanValue(spell->state, data->at(i)->bool_value);
|
||||
break;
|
||||
}
|
||||
case 3:{
|
||||
lua_interface->SetStringValue(spell->state, data->at(i)->string_value.c_str());
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
LogWrite(SPELL__ERROR, 0, "Spell", "Error: Unknown LUA Type '%i' in SpellProcess::ProcessSpell for Spell '%s'", (int)data->at(i)->type, spell->spell->GetName());
|
||||
return false;
|
||||
if(all_targets)
|
||||
{
|
||||
for(int t=0;t<spell->targets.size();t++)
|
||||
{
|
||||
Spawn* altSpawn = spell->caster->GetZone()->GetSpawnByID(spell->targets[t]);
|
||||
if(altSpawn)
|
||||
{
|
||||
std::string functionCall = ApplyLuaFunction(spell, first_cast, function, timer, altSpawn);
|
||||
if(functionCall.length() < 1)
|
||||
ret = false;
|
||||
else
|
||||
ret = lua_interface->CallSpellProcess(spell, 2 + spell->spell->GetLUAData()->size(), functionCall);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ret = lua_interface->CallSpellProcess(spell, 2 + data->size(), functionCall);
|
||||
std::string functionCall = ApplyLuaFunction(spell, first_cast, function, timer);
|
||||
if(functionCall.length() < 1)
|
||||
ret = false;
|
||||
else
|
||||
ret = lua_interface->CallSpellProcess(spell, 2 + spell->spell->GetLUAData()->size(), functionCall);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string SpellProcess::ApplyLuaFunction(LuaSpell* spell, bool first_cast, const char* function, SpellScriptTimer* timer, Spawn* altTarget)
|
||||
{
|
||||
std::string functionCall = lua_interface->AddSpawnPointers(spell, first_cast, false, function, timer, false, altTarget);
|
||||
vector<LUAData*>* data = spell->spell->GetLUAData();
|
||||
for(int32 i=0;i<data->size();i++){
|
||||
switch(data->at(i)->type){
|
||||
case 0:{
|
||||
lua_interface->SetSInt32Value(spell->state, data->at(i)->int_value);
|
||||
break;
|
||||
}
|
||||
case 1:{
|
||||
lua_interface->SetFloatValue(spell->state, data->at(i)->float_value);
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
lua_interface->SetBooleanValue(spell->state, data->at(i)->bool_value);
|
||||
break;
|
||||
}
|
||||
case 3:{
|
||||
lua_interface->SetStringValue(spell->state, data->at(i)->string_value.c_str());
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
LogWrite(SPELL__ERROR, 0, "Spell", "Error: Unknown LUA Type '%i' in SpellProcess::ProcessSpell for Spell '%s'", (int)data->at(i)->type, spell->spell->GetName());
|
||||
return string("");
|
||||
}
|
||||
}
|
||||
}
|
||||
return functionCall;
|
||||
}
|
||||
|
||||
bool SpellProcess::CastPassives(Spell* spell, Entity* caster, bool remove) {
|
||||
CastInstant(spell, caster, caster, remove, true);
|
||||
return true;
|
||||
|
@ -1050,14 +1075,12 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
|
|||
else if(lua_spell->spell->GetSpellData()->spell_type == SPELL_TYPE_DEBUFF)
|
||||
{
|
||||
SpellCannotStack(zone, client, lua_spell->caster, lua_spell, conflictSpell);
|
||||
DeleteSpell(lua_spell);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SpellCannotStack(zone, client, lua_spell->caster, lua_spell, conflictSpell);
|
||||
DeleteSpell(lua_spell);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1102,7 +1125,7 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
|
|||
return;
|
||||
}
|
||||
|
||||
if (target_type != SPELL_TARGET_SELF && target_type != SPELL_TARGET_GROUP_AE && target_type != SPELL_TARGET_NONE && spell->GetSpellData()->max_aoe_targets == 0)
|
||||
if (target_type != SPELL_TARGET_SELF && target_type != SPELL_TARGET_GROUP_AE && target_type != SPELL_TARGET_ALLGROUPTARGETS && target_type != SPELL_TARGET_NONE && spell->GetSpellData()->max_aoe_targets == 0)
|
||||
{
|
||||
LogWrite(SPELL__DEBUG, 1, "Spell", "%s: Not Self, Not Group AE, Not None, Max Targets = 0", spell->GetName());
|
||||
|
||||
|
@ -1562,8 +1585,10 @@ bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_her
|
|||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
bool allTargets = (spell->spell->GetSpellData()->target_type == SPELL_TARGET_ALLGROUPTARGETS);
|
||||
if (!processedSpell)
|
||||
processedSpell = ProcessSpell(spell);
|
||||
processedSpell = ProcessSpell(spell, true, 0, 0, allTargets);
|
||||
|
||||
// Quick hack to prevent a crash on spells that zones the caster (Gate)
|
||||
if (!spell->caster)
|
||||
|
@ -2000,26 +2025,48 @@ void SpellProcess::GetSpellTargets(LuaSpell* luaspell)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (target_type == SPELL_TARGET_GROUP_AE || target_type == SPELL_TARGET_RAID_AE) {
|
||||
else if (target_type == SPELL_TARGET_GROUP_AE || target_type == SPELL_TARGET_ALLGROUPTARGETS || target_type == SPELL_TARGET_RAID_AE) {
|
||||
|
||||
// player handling
|
||||
if (target)
|
||||
{
|
||||
if (data->icon_backdrop == 316) // using TARGET backdrop icon
|
||||
if (data->icon_backdrop == 316 || data->icon_backdrop == 312) // using TARGET backdrop icon
|
||||
{
|
||||
// PLAYER LOGIC:
|
||||
if ((target->IsPlayer() && luaspell->caster->IsPlayer() && target != luaspell->caster && ((Player*)target)->GetGroupMemberInfo() != NULL && ((Player*)luaspell->caster)->GetGroupMemberInfo() != NULL
|
||||
if ((data->friendly_spell && (target->IsPlayer() && luaspell->caster->IsPlayer() && target != luaspell->caster && ((Player*)target)->GetGroupMemberInfo() != NULL && ((Player*)luaspell->caster)->GetGroupMemberInfo() != NULL
|
||||
&& ((Player*)target)->GetGroupMemberInfo()->group_id == ((Player*)luaspell->caster)->GetGroupMemberInfo()->group_id))
|
||||
|| (!data->friendly_spell && (target->IsPlayer() && luaspell->caster->IsPlayer() && target != luaspell->caster && ((Player*)target)->GetGroupMemberInfo() != NULL)))
|
||||
{
|
||||
GetPlayerGroupTargets((Player*)target, caster, luaspell, true, false);
|
||||
}//TODO: NEED RAID SUPPORT
|
||||
}
|
||||
//TODO: NEED RAID SUPPORT
|
||||
|
||||
// NPC LOGIC:
|
||||
else if (target->group_id > 0 && target->group_id == luaspell->caster->group_id)
|
||||
else if (target->IsNPC())
|
||||
{
|
||||
// Check to see if the npc is a spawn group by getting the group and checikng if valid
|
||||
vector<Spawn*>* group = ((NPC*)target)->GetSpawnGroup();
|
||||
if (group)
|
||||
{
|
||||
vector<Spawn*>::iterator itr;
|
||||
|
||||
// iterate through spawn group members
|
||||
for (itr = group->begin(); itr != group->end(); itr++)
|
||||
{
|
||||
Spawn* group_member = *itr;
|
||||
|
||||
// if NPC group member is (still) an NPC (wtf?) and is alive, send the NPC group member back as a successful target of non-friendly spell group_member->Alive()
|
||||
if (group_member->GetZone() == caster->GetZone() &&
|
||||
group_member->IsNPC() && group_member->Alive() && !((Entity*)group_member)->IsAOEImmune() && (!((Entity*)group_member)->IsMezzed() || group_member == target))
|
||||
luaspell->targets.push_back(group_member->GetID());
|
||||
|
||||
// note: this should generate some hate towards the caster
|
||||
}
|
||||
} // end is spawngroup
|
||||
else
|
||||
luaspell->targets.push_back(target->GetID()); // return single target NPC for non-friendly spell
|
||||
}
|
||||
else
|
||||
else if(data->friendly_spell)
|
||||
{
|
||||
// add self
|
||||
target = NULL;
|
||||
|
@ -2060,7 +2107,7 @@ void SpellProcess::GetSpellTargets(LuaSpell* luaspell)
|
|||
|
||||
luaspell->MSpellTargets.writelock(__FUNCTION__, __LINE__);
|
||||
// Group AE type NOTE: Add support for RAID AE to affect raid members once raids have been completed
|
||||
if (target_type == SPELL_TARGET_GROUP_AE || target_type == SPELL_TARGET_RAID_AE)
|
||||
if (target_type == SPELL_TARGET_GROUP_AE || target_type == SPELL_TARGET_ALLGROUPTARGETS || target_type == SPELL_TARGET_RAID_AE)
|
||||
{
|
||||
if (data->icon_backdrop == 316) // single target in a group/raid
|
||||
{
|
||||
|
|
|
@ -385,7 +385,8 @@ public:
|
|||
|
||||
void SpellCannotStack(ZoneServer* zone, Client* client, Entity* caster, LuaSpell* lua_spell, LuaSpell* conflictSpell);
|
||||
|
||||
bool ProcessSpell(LuaSpell* spell, bool first_cast = true, const char* function = 0, SpellScriptTimer* timer = 0);
|
||||
bool ProcessSpell(LuaSpell* spell, bool first_cast = true, const char* function = 0, SpellScriptTimer* timer = 0, bool all_targets = false);
|
||||
std::string ApplyLuaFunction(LuaSpell* spell, bool first_cast, const char* function, SpellScriptTimer* timer, Spawn* altTarget = 0);
|
||||
|
||||
void AddActiveSpell(LuaSpell* spell);
|
||||
static void AddSelfAndPet(LuaSpell* spell, Spawn* caster, bool onlyPet=false);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define SPELL_TARGET_NONE 7
|
||||
#define SPELL_TARGET_RAID_AE 8
|
||||
#define SPELL_TARGET_OTHER_GROUP_AE 9
|
||||
#define SPELL_TARGET_ALLGROUPTARGETS 10 // use this with cast/tick only containing DIRECT target/spawn.
|
||||
|
||||
|
||||
#define SPELL_BOOK_TYPE_SPELL 0
|
||||
|
|
|
@ -7405,7 +7405,7 @@ void WorldDatabase::LoadCharacterSpellEffects(int32 char_id, Client* client, int
|
|||
if(custom_spell)
|
||||
{
|
||||
if((lua_spell = lua_interface->GetSpell(lua_file.c_str())) == nullptr)
|
||||
{
|
||||
{
|
||||
LogWrite(LUA__WARNING, 0, "LUA", "WorldDatabase::LoadCharacterSpellEffects: GetSpell(%u, %u, '%s'), custom lua script not loaded, when attempting to load.", spell_id, tier, lua_file.c_str());
|
||||
lua_interface->LoadLuaSpell(lua_file);
|
||||
}
|
||||
|
@ -7458,6 +7458,9 @@ void WorldDatabase::LoadCharacterSpellEffects(int32 char_id, Client* client, int
|
|||
else if(db_spell_type == DB_TYPE_MAINTAINEDEFFECTS)
|
||||
{
|
||||
safe_delete(lua_spell);
|
||||
if(!target_char_id)
|
||||
continue;
|
||||
|
||||
lua_spell = lua_interface->GetSpell(spell->GetSpellData()->lua_script.c_str());
|
||||
if(lua_spell)
|
||||
lua_spell->spell = spell;
|
||||
|
|
|
@ -3241,7 +3241,7 @@ void ClientList::RemoveConnection(EQStream* eqs) {
|
|||
for (client_iter = client_list.begin(); client_iter != client_list.end(); client_iter++) {
|
||||
client = *client_iter;
|
||||
if (client->getConnection() == eqs)
|
||||
client->Disconnect(false);
|
||||
client->Disconnect(true);
|
||||
}
|
||||
MClients.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
|
|
@ -568,6 +568,21 @@ int32 ParseIntValue(string input){
|
|||
return ret;
|
||||
}
|
||||
|
||||
int64 ParseLongLongValue(string input){
|
||||
int64 ret = 0xFFFFFFFFFFFFFFFF;
|
||||
try{
|
||||
if(input.length() > 0){
|
||||
#ifdef WIN32
|
||||
ret = _strtoui64(input.c_str(), NULL, 10);
|
||||
#else
|
||||
ret = strtoull(input.c_str(), 0, 10);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch(...){}
|
||||
return ret;
|
||||
}
|
||||
|
||||
map<string, string> TranslateBrokerRequest(string request){
|
||||
map<string, string> ret;
|
||||
string key;
|
||||
|
|
|
@ -67,6 +67,7 @@ void Decode(uchar* dst, uchar* src, int16 len);
|
|||
string ToUpper(string input);
|
||||
string ToLower(string input);
|
||||
int32 ParseIntValue(string input);
|
||||
int64 ParseLongLongValue(string input);
|
||||
map<string, string> TranslateBrokerRequest(string request);
|
||||
void MovementDecode(uchar* dst, uchar* newval, uchar* orig, int16 len);
|
||||
vector<string>* SplitString(string str, char delim);
|
||||
|
|
Loading…
Add table
Reference in a new issue