Added classic spell level support (aka mini ding spells) like warrior getting knee break at lvl 19.6
This commit is contained in:
parent
9b60035656
commit
82a1885887
@ -154,9 +154,9 @@ void Bot::MessageGroup(string msg) {
|
|||||||
|
|
||||||
void Bot::GetNewSpells() {
|
void Bot::GetNewSpells() {
|
||||||
vector<Spell*> spells;
|
vector<Spell*> spells;
|
||||||
vector<Spell*>* spells1 = master_spell_list.GetSpellListByAdventureClass(GetAdventureClass(), GetLevel(), 1);
|
vector<Spell*>* spells1 = master_spell_list.GetSpellListByAdventureClass(GetAdventureClass(), (double)GetLevel(), 1);
|
||||||
vector<Spell*>* spells2 = master_spell_list.GetSpellListByAdventureClass(classes.GetBaseClass(GetAdventureClass()), GetLevel(), 1);
|
vector<Spell*>* spells2 = master_spell_list.GetSpellListByAdventureClass(classes.GetBaseClass(GetAdventureClass()), (double)GetLevel(), 1);
|
||||||
vector<Spell*>* spells3 = master_spell_list.GetSpellListByAdventureClass(classes.GetSecondaryBaseClass(GetAdventureClass()), GetLevel(), 1);
|
vector<Spell*>* spells3 = master_spell_list.GetSpellListByAdventureClass(classes.GetSecondaryBaseClass(GetAdventureClass()), (double)GetLevel(), 1);
|
||||||
|
|
||||||
spells.insert(spells.end(), spells1->begin(), spells1->end());
|
spells.insert(spells.end(), spells1->begin(), spells1->end());
|
||||||
spells.insert(spells.end(), spells2->begin(), spells2->end());
|
spells.insert(spells.end(), spells2->begin(), spells2->end());
|
||||||
|
@ -2505,8 +2505,11 @@ void Entity::CureDetrimentByType(int8 cure_count, int8 det_type, string cure_nam
|
|||||||
bool has_level_checks = false;
|
bool has_level_checks = false;
|
||||||
for (int32 x = 0; x < levels->size(); x++){
|
for (int32 x = 0; x < levels->size(); x++){
|
||||||
has_level_checks = true;
|
has_level_checks = true;
|
||||||
|
int8 use_classic_lvls = rule_manager.GetGlobalRule(R_Spells, UseClassicSpellLevel)->GetInt8();
|
||||||
|
if(levels->at(x)->classic_spell_level == 0.0f)
|
||||||
|
use_classic_lvls = 0;
|
||||||
// class checks are worthless we can't guarantee the caster is that class
|
// class checks are worthless we can't guarantee the caster is that class
|
||||||
if (!cure_level || cure_level >= (levels->at(x)->spell_level / 10)){
|
if (!cure_level || (use_classic_lvls && cure_level >= std::floor(levels->at(x)->classic_spell_level)) || (!use_classic_lvls && cure_level >= (levels->at(x)->spell_level / 10))){
|
||||||
pass_level_check = true;
|
pass_level_check = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2555,7 +2558,10 @@ void Entity::CureDetrimentByControlEffect(int8 cure_count, int8 control_type, st
|
|||||||
info_struct = det->caster->GetInfoStruct();
|
info_struct = det->caster->GetInfoStruct();
|
||||||
pass_level_check = false;
|
pass_level_check = false;
|
||||||
for (int32 x = 0; x < levels->size(); x++){
|
for (int32 x = 0; x < levels->size(); x++){
|
||||||
if (!cure_level || cure_level >= (levels->at(x)->spell_level / 10)){
|
int8 use_classic_lvls = rule_manager.GetGlobalRule(R_Spells, UseClassicSpellLevel)->GetInt8();
|
||||||
|
if(levels->at(x)->classic_spell_level == 0.0f)
|
||||||
|
use_classic_lvls = 0;
|
||||||
|
if (!cure_level || (use_classic_lvls && cure_level >= std::floor(levels->at(x)->classic_spell_level)) || (!use_classic_lvls && cure_level >= (levels->at(x)->spell_level / 10))){
|
||||||
pass_level_check = true;
|
pass_level_check = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4490,6 +4490,8 @@ bool Player::AddXP(int32 xp_amount){
|
|||||||
GetPlayerInfo()->CalculateXPPercentages();
|
GetPlayerInfo()->CalculateXPPercentages();
|
||||||
current_xp_percent = ((float)GetXP()/(float)GetNeededXP())*100;
|
current_xp_percent = ((float)GetXP()/(float)GetNeededXP())*100;
|
||||||
if(current_xp_percent >= miniding_min_percent){
|
if(current_xp_percent >= miniding_min_percent){
|
||||||
|
if(GetClient() && rule_manager.GetGlobalRule(R_Spells, UseClassicSpellLevel)->GetInt8())
|
||||||
|
GetClient()->SendNewAdventureSpells(); // mini ding involves checking spells again in classic level settings
|
||||||
SetHP(GetTotalHP());
|
SetHP(GetTotalHP());
|
||||||
SetPower(GetTotalPower());
|
SetPower(GetTotalPower());
|
||||||
GetZone()->SendCastSpellPacket(332, this, this); //send mini level up spell effect
|
GetZone()->SendCastSpellPacket(332, this, this); //send mini level up spell effect
|
||||||
|
@ -394,6 +394,7 @@ void RuleManager::Init()
|
|||||||
RULE_INIT(R_Spells, MinistrationPowerReductionMax, "15.0"); // max percentage of power reduction for spells with ministration mastery skill (default is 15.0 for 15%)
|
RULE_INIT(R_Spells, MinistrationPowerReductionMax, "15.0"); // max percentage of power reduction for spells with ministration mastery skill (default is 15.0 for 15%)
|
||||||
RULE_INIT(R_Spells, MinistrationPowerReductionSkill, "25"); // divides by integer value to establish how much skill req for higher power reduction
|
RULE_INIT(R_Spells, MinistrationPowerReductionSkill, "25"); // divides by integer value to establish how much skill req for higher power reduction
|
||||||
RULE_INIT(R_Spells, MasterSkillReduceSpellResist, "25"); // divides by integer value to establish how much skill bonus for reducing spell resistance on target
|
RULE_INIT(R_Spells, MasterSkillReduceSpellResist, "25"); // divides by integer value to establish how much skill bonus for reducing spell resistance on target
|
||||||
|
RULE_INIT(R_Spells, UseClassicSpellLevel, "0"); // Uses fractional spell levels (eg. you gain spells inbetween levels).
|
||||||
|
|
||||||
RULE_INIT(R_Expansion, GlobalExpansionFlag, "0");
|
RULE_INIT(R_Expansion, GlobalExpansionFlag, "0");
|
||||||
RULE_INIT(R_Expansion, GlobalHolidayFlag, "0");
|
RULE_INIT(R_Expansion, GlobalHolidayFlag, "0");
|
||||||
|
@ -240,6 +240,7 @@ enum RuleType {
|
|||||||
MinistrationPowerReductionMax,
|
MinistrationPowerReductionMax,
|
||||||
MinistrationPowerReductionSkill,
|
MinistrationPowerReductionSkill,
|
||||||
MasterSkillReduceSpellResist,
|
MasterSkillReduceSpellResist,
|
||||||
|
UseClassicSpellLevel,
|
||||||
|
|
||||||
/* ZONE TIMERS */
|
/* ZONE TIMERS */
|
||||||
RegenTimer,
|
RegenTimer,
|
||||||
|
@ -167,7 +167,7 @@ Spell::Spell(Spell* host_spell, bool unique_spell)
|
|||||||
for (itr = host_spell->levels.begin(); itr != host_spell->levels.end(); itr++)
|
for (itr = host_spell->levels.begin(); itr != host_spell->levels.end(); itr++)
|
||||||
{
|
{
|
||||||
LevelArray* lvlArray = *itr;
|
LevelArray* lvlArray = *itr;
|
||||||
AddSpellLevel(lvlArray->adventure_class, lvlArray->tradeskill_class, lvlArray->spell_level);
|
AddSpellLevel(lvlArray->adventure_class, lvlArray->tradeskill_class, lvlArray->spell_level, lvlArray->classic_spell_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SpellDisplayEffect*>::iterator sdeitr;
|
std::vector<SpellDisplayEffect*>::iterator sdeitr;
|
||||||
@ -295,6 +295,9 @@ int16 Spell::GetLevelRequired(Player* player){
|
|||||||
for(itr = levels.begin(); itr != levels.end(); itr++){
|
for(itr = levels.begin(); itr != levels.end(); itr++){
|
||||||
level = *itr;
|
level = *itr;
|
||||||
if(level && level->adventure_class == player->GetAdventureClass()){
|
if(level && level->adventure_class == player->GetAdventureClass()){
|
||||||
|
if(rule_manager.GetGlobalRule(R_Spells, UseClassicSpellLevel)->GetInt8() && level->classic_spell_level > 0.0f)
|
||||||
|
ret = std::floor(level->classic_spell_level);
|
||||||
|
else
|
||||||
ret = level->spell_level/10;
|
ret = level->spell_level/10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -722,8 +725,13 @@ void Spell::AppendLevelInformation(PacketStruct* packet) {
|
|||||||
LevelArray* levelData = tmpArray->at(i);
|
LevelArray* levelData = tmpArray->at(i);
|
||||||
packet->setArrayDataByName("adventure_class", levelData->adventure_class, i);
|
packet->setArrayDataByName("adventure_class", levelData->adventure_class, i);
|
||||||
packet->setArrayDataByName("tradeskill_class", levelData->tradeskill_class, i);
|
packet->setArrayDataByName("tradeskill_class", levelData->tradeskill_class, i);
|
||||||
|
if(rule_manager.GetGlobalRule(R_Spells, UseClassicSpellLevel)->GetInt8() && levelData->classic_spell_level) {
|
||||||
|
packet->setArrayDataByName("spell_level", (int16)(levelData->classic_spell_level * 10.0f), i);
|
||||||
|
}
|
||||||
|
else {
|
||||||
packet->setArrayDataByName("spell_level", levelData->spell_level, i);
|
packet->setArrayDataByName("spell_level", levelData->spell_level, i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sint16 Spell::TranslateClientSpellIcon(int16 version) {
|
sint16 Spell::TranslateClientSpellIcon(int16 version) {
|
||||||
@ -1270,12 +1278,13 @@ const char* Spell::GetDescription(){
|
|||||||
return spell->description.data.c_str();
|
return spell->description.data.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::AddSpellLevel(int8 adventure_class, int8 tradeskill_class, int16 level){
|
void Spell::AddSpellLevel(int8 adventure_class, int8 tradeskill_class, int16 level, float classic_spell_level){
|
||||||
std::unique_lock lock(MSpellInfo);
|
std::unique_lock lock(MSpellInfo);
|
||||||
LevelArray* lvl = new LevelArray;
|
LevelArray* lvl = new LevelArray;
|
||||||
lvl->adventure_class = adventure_class;
|
lvl->adventure_class = adventure_class;
|
||||||
lvl->tradeskill_class = tradeskill_class;
|
lvl->tradeskill_class = tradeskill_class;
|
||||||
lvl->spell_level = level;
|
lvl->spell_level = level;
|
||||||
|
lvl->classic_spell_level = classic_spell_level;
|
||||||
|
|
||||||
levels.push_back(lvl);
|
levels.push_back(lvl);
|
||||||
}
|
}
|
||||||
@ -2169,14 +2178,15 @@ vector <LevelArray*>* Spell::GetSpellLevels(){
|
|||||||
bool Spell::ScribeAllowed(Player* player){
|
bool Spell::ScribeAllowed(Player* player){
|
||||||
std::shared_lock lock(MSpellInfo);
|
std::shared_lock lock(MSpellInfo);
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
double current_xp_percent = ((double)player->GetXP()/(double)player->GetNeededXP())*100;
|
||||||
if(player){
|
if(player){
|
||||||
for(int32 i=0;!ret && i<levels.size();i++){
|
for(int32 i=0;!ret && i<levels.size();i++){
|
||||||
int16 mylevel = player->GetLevel();
|
bool classiclevelmatch = ((double)player->GetLevel()+current_xp_percent) >= levels[i]->classic_spell_level;
|
||||||
int16 spelllevels = levels[i]->spell_level;
|
bool classic_match_only = false;
|
||||||
bool advlev = player->GetAdventureClass() == levels[i]->adventure_class;
|
if(levels[i]->classic_spell_level > 0.0f && rule_manager.GetGlobalRule(R_Spells, UseClassicSpellLevel)->GetInt8()) {
|
||||||
bool tslev = player->GetTradeskillClass() == levels[i]->tradeskill_class;
|
classic_match_only = true;
|
||||||
bool levelmatch = player->GetLevel() >= levels[i]->spell_level;
|
}
|
||||||
if((player->GetAdventureClass() == levels[i]->adventure_class || player->GetTradeskillClass() == levels[i]->tradeskill_class) && player->GetLevel() >= levels[i]->spell_level/10)
|
if((player->GetAdventureClass() == levels[i]->adventure_class || player->GetTradeskillClass() == levels[i]->tradeskill_class) && ((!classic_match_only && player->GetLevel() >= levels[i]->spell_level/10) || (classic_match_only && classiclevelmatch)))
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2332,12 +2342,13 @@ EQ2Packet* MasterSpellList::GetSpecialSpellPacket(int32 id, int8 tier, Client* c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Spell*>* MasterSpellList::GetSpellListByAdventureClass(int8 class_id, int16 max_level, int8 max_tier){
|
vector<Spell*>* MasterSpellList::GetSpellListByAdventureClass(int8 class_id, double max_level_classic, int8 max_tier){
|
||||||
vector<Spell*>* ret = new vector<Spell*>;
|
vector<Spell*>* ret = new vector<Spell*>;
|
||||||
if(class_id >= MAX_CLASSES) {
|
if(class_id >= MAX_CLASSES) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8 use_classic_levels = rule_manager.GetGlobalRule(R_Spells, UseClassicSpellLevel)->GetInt8();
|
||||||
Spell* spell = 0;
|
Spell* spell = 0;
|
||||||
vector<LevelArray*>* levels = 0;
|
vector<LevelArray*>* levels = 0;
|
||||||
LevelArray* level = 0;
|
LevelArray* level = 0;
|
||||||
@ -2345,7 +2356,7 @@ vector<Spell*>* MasterSpellList::GetSpellListByAdventureClass(int8 class_id, int
|
|||||||
MMasterSpellList.lock();
|
MMasterSpellList.lock();
|
||||||
map<int32, map<int32, Spell*> >::iterator iter;
|
map<int32, map<int32, Spell*> >::iterator iter;
|
||||||
map<int32, Spell*>::iterator iter2;
|
map<int32, Spell*>::iterator iter2;
|
||||||
max_level *= 10; //convert to client level format, which is 10 times higher
|
int16 max_level = std::floor(max_level_classic) * 10; //convert to client level format, which is 10 times higher
|
||||||
for(iter = class_spell_list[class_id].begin();iter != class_spell_list[class_id].end(); iter++){
|
for(iter = class_spell_list[class_id].begin();iter != class_spell_list[class_id].end(); iter++){
|
||||||
for(iter2 = iter->second.begin();iter2 != iter->second.end(); iter2++){
|
for(iter2 = iter->second.begin();iter2 != iter->second.end(); iter2++){
|
||||||
spell = iter2->second;
|
spell = iter2->second;
|
||||||
@ -2354,10 +2365,16 @@ vector<Spell*>* MasterSpellList::GetSpellListByAdventureClass(int8 class_id, int
|
|||||||
levels = spell->GetSpellLevels();
|
levels = spell->GetSpellLevels();
|
||||||
for(level_itr = levels->begin(); level_itr != levels->end(); level_itr++){
|
for(level_itr = levels->begin(); level_itr != levels->end(); level_itr++){
|
||||||
level = *level_itr;
|
level = *level_itr;
|
||||||
if(level->spell_level <= max_level && level->adventure_class == class_id){
|
if(level->adventure_class == class_id){
|
||||||
|
if((!use_classic_levels || level->classic_spell_level == 0.0f) && level->spell_level <= max_level) {
|
||||||
ret->push_back(spell);
|
ret->push_back(spell);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if(use_classic_levels && level->classic_spell_level <= max_level_classic) {
|
||||||
|
ret->push_back(spell);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,6 +218,7 @@ struct LevelArray{
|
|||||||
int8 adventure_class;
|
int8 adventure_class;
|
||||||
int8 tradeskill_class;
|
int8 tradeskill_class;
|
||||||
int16 spell_level;
|
int16 spell_level;
|
||||||
|
float classic_spell_level;
|
||||||
};
|
};
|
||||||
struct SpellDisplayEffect{
|
struct SpellDisplayEffect{
|
||||||
int8 percentage;
|
int8 percentage;
|
||||||
@ -328,7 +329,7 @@ public:
|
|||||||
EQ2Packet* SerializeSpell(Client* client, bool display, bool trait_display = false, int8 packet_type = 0, int8 sub_packet_type = 0, const char* struct_name = 0, bool send_partial_packet = false);
|
EQ2Packet* SerializeSpell(Client* client, bool display, bool trait_display = false, int8 packet_type = 0, int8 sub_packet_type = 0, const char* struct_name = 0, bool send_partial_packet = false);
|
||||||
EQ2Packet* SerializeSpecialSpell(Client* client, bool display, int8 packet_type = 0, int8 sub_packet_type = 0);
|
EQ2Packet* SerializeSpecialSpell(Client* client, bool display, int8 packet_type = 0, int8 sub_packet_type = 0);
|
||||||
EQ2Packet* SerializeAASpell(Client* client,int8 tier, AltAdvanceData* data, bool display, bool trait_display = false, int8 packet_type = 0, int8 sub_packet_type = 0, const char* struct_name = 0);
|
EQ2Packet* SerializeAASpell(Client* client,int8 tier, AltAdvanceData* data, bool display, bool trait_display = false, int8 packet_type = 0, int8 sub_packet_type = 0, const char* struct_name = 0);
|
||||||
void AddSpellLevel(int8 adventure_class, int8 tradeskill_class, int16 level);
|
void AddSpellLevel(int8 adventure_class, int8 tradeskill_class, int16 level, float classic_spell_level);
|
||||||
void AddSpellEffect(int8 percentage, int8 subbullet, string description);
|
void AddSpellEffect(int8 percentage, int8 subbullet, string description);
|
||||||
void AddSpellLuaData(int8 type, int int_value, int int_value2, float float_value, float float_value2, bool bool_value, string string_value,string string_value2, string helper);
|
void AddSpellLuaData(int8 type, int int_value, int int_value2, float float_value, float float_value2, bool bool_value, string string_value,string string_value2, string helper);
|
||||||
void AddSpellLuaDataInt(int value, int value2, string helper);
|
void AddSpellLuaDataInt(int value, int value2, string helper);
|
||||||
@ -402,7 +403,7 @@ public:
|
|||||||
map<int32, map<int32, Spell* > > class_spell_list[MAX_CLASSES];
|
map<int32, map<int32, Spell* > > class_spell_list[MAX_CLASSES];
|
||||||
map<int32, Spell*> spell_soecrc_map;
|
map<int32, Spell*> spell_soecrc_map;
|
||||||
Spell* GetSpell(int32 id, int8 tier);
|
Spell* GetSpell(int32 id, int8 tier);
|
||||||
vector<Spell*>* GetSpellListByAdventureClass(int8 class_id, int16 max_level, int8 max_tier);
|
vector<Spell*>* GetSpellListByAdventureClass(int8 class_id, double max_level, int8 max_tier);
|
||||||
vector<Spell*>* GetSpellListByTradeskillClass(int8 class_id, int16 max_level, int8 max_tier);
|
vector<Spell*>* GetSpellListByTradeskillClass(int8 class_id, int16 max_level, int8 max_tier);
|
||||||
Spell* GetSpellByName(const char* name);
|
Spell* GetSpellByName(const char* name);
|
||||||
Spell* GetSpellByCRC(int32 spell_crc);
|
Spell* GetSpellByCRC(int32 spell_crc);
|
||||||
|
@ -4872,7 +4872,7 @@ void WorldDatabase::SaveQuickBar(int32 char_id, vector<QuickBarItem*>* quickbar_
|
|||||||
map<int32, vector<LevelArray*> >* WorldDatabase::LoadSpellClasses(){
|
map<int32, vector<LevelArray*> >* WorldDatabase::LoadSpellClasses(){
|
||||||
map<int32, vector<LevelArray*> >* ret = new map<int32, vector<LevelArray*> >();
|
map<int32, vector<LevelArray*> >* ret = new map<int32, vector<LevelArray*> >();
|
||||||
Query query;
|
Query query;
|
||||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT spell_id, adventure_class_id, tradeskill_class_id, level FROM spell_classes");
|
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT spell_id, adventure_class_id, tradeskill_class_id, level, classic_level FROM spell_classes");
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
LevelArray* level = 0;
|
LevelArray* level = 0;
|
||||||
while(result && (row = mysql_fetch_row(result))){
|
while(result && (row = mysql_fetch_row(result))){
|
||||||
@ -4880,6 +4880,7 @@ map<int32, vector<LevelArray*> >* WorldDatabase::LoadSpellClasses(){
|
|||||||
level->adventure_class = atoi(row[1]);
|
level->adventure_class = atoi(row[1]);
|
||||||
level->tradeskill_class = atoi(row[2]);
|
level->tradeskill_class = atoi(row[2]);
|
||||||
level->spell_level = atoi(row[3]);
|
level->spell_level = atoi(row[3]);
|
||||||
|
level->classic_spell_level = atof(row[4]);
|
||||||
(*ret)[atoul(row[0])].push_back(level);
|
(*ret)[atoul(row[0])].push_back(level);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -5101,7 +5102,7 @@ void WorldDatabase::LoadSpells()
|
|||||||
|
|
||||||
for(int8 i=0; i<level_array->size(); i++)
|
for(int8 i=0; i<level_array->size(); i++)
|
||||||
{
|
{
|
||||||
spell->AddSpellLevel(level_array->at(i)->adventure_class, level_array->at(i)->tradeskill_class, level_array->at(i)->spell_level*10);
|
spell->AddSpellLevel(level_array->at(i)->adventure_class, level_array->at(i)->tradeskill_class, level_array->at(i)->spell_level*10, level_array->at(i)->classic_spell_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10167,8 +10167,9 @@ void Client::ProcessTeleportLocation(EQApplicationPacket* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendNewSpells(int8 class_id) {
|
void Client::SendNewSpells(int8 class_id) {
|
||||||
if (class_id > 0) {
|
if (class_id > 0 && player) {
|
||||||
vector<Spell*>* spells = master_spell_list.GetSpellListByAdventureClass(class_id, player->GetLevel(), 1);
|
double current_xp_percent = ((double)player->GetXP()/(double)player->GetNeededXP())*100;
|
||||||
|
vector<Spell*>* spells = master_spell_list.GetSpellListByAdventureClass(class_id, (double)player->GetLevel()+current_xp_percent, 1);
|
||||||
AddSendNewSpells(spells);
|
AddSendNewSpells(spells);
|
||||||
safe_delete(spells);
|
safe_delete(spells);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user