After seeing a request by Kingmort to have a CotH version of the canlevitate and castoutdoor code for the Zone table, I thought that I could maybe handle writing this code. I work pretty well by example, so I looked at the code written by Magoth78 and by Qadar and it looked pretty straight forward.
I just changed what they had already done to add in a coth version. The only part that took any thinking on my end was figuring out how to get it to use a spell ID instead of the things they had it check for levitate and outdoor spells. The rest was pretty simple.
So, here is the code to allow you to restrict Call of the Hero from being used in any zone you desire:
In /zone/spells.cpp After:
Code:
if(IsEffectInSpell(spell_id, SE_Levitate) && !zone->CanLevitate()){
if(IsClient()){
if(!CastToClient()->GetGM()){
Message(13, "You can't levitate in this zone.");
return false;
}
}
}
Add the following:
Code:
if(spell_id == 1771 && !zone->CanCotH()){
if(IsClient()){
if(!CastToClient()->GetGM()){
Message(13, "You can't summon players in this zone.");
return false;
}
}
}
/zone/zone.h (note that you do NOT add the + sign, that just signifies the line to add)
Code:
After - bool CanCastOutdoor() const {return(can_castoutdoor);} //qadar
+bool CanCotH() const {return(can_coth); } //trevius
After - bool can_levitate;
+bool can_coth;
/zone/zone.cpp
Code:
- if(!database.GetZoneCFG(database.GetZoneID(filename), &newzone_data, can_bind, can_combat, can_levitate, can_castoutdoor, is_city)) {
+ if(!database.GetZoneCFG(database.GetZoneID(filename), &newzone_data, can_bind, can_combat, can_levitate, can_castoutdoor, is_city, can_coth)) {
/zone/zonedb.h
Code:
-bool GetZoneCFG(int32 zoneid, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city);
+bool GetZoneCFG(int32 zoneid, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &can_coth);
In /zone/zonedb.cpp Remove:
Code:
bool ZoneDatabase::GetZoneCFG(int32 zoneid, NewZone_Struct *zone_data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int i=0;
int b=0;
bool good = false;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT ztype,"
"fog_red,fog_green,fog_blue,fog_minclip,fog_maxclip,"
"fog_red2,fog_green2,fog_blue2,fog_minclip2,fog_maxclip2,"
"fog_red3,fog_green3,fog_blue3,fog_minclip3,fog_maxclip3,"
"fog_red4,fog_green4,fog_blue4,fog_minclip4,fog_maxclip4,"
"sky,zone_exp_multiplier,safe_x,safe_y,safe_z,underworld,"
"minclip,maxclip,time_type,canbind,cancombat,canlevitate,castoutdoor"
" from zone where zoneidnumber=%i",zoneid), errbuf, &result)) {
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
int r = 0;
memset(zone_data,0,sizeof(NewZone_Struct));
zone_data->ztype=atoi(row[r++]);
for(i=0;i<4;i++){
zone_data->fog_red[i]=atoi(row[r++]);
zone_data->fog_green[i]=atoi(row[r++]);
zone_data->fog_blue[i]=atoi(row[r++]);
zone_data->fog_minclip[i]=atof(row[r++]);
zone_data->fog_maxclip[i]=atof(row[r++]);
}
zone_data->sky=atoi(row[r++]);
zone_data->zone_exp_multiplier=atof(row[r++]);
zone_data->safe_x=atof(row[r++]);
zone_data->safe_y=atof(row[r++]);
zone_data->safe_z=atof(row[r++]);
zone_data->underworld=atof(row[r++]);
zone_data->minclip=atof(row[r++]);
zone_data->maxclip=atof(row[r++]);
zone_data->time_type=atoi(row[r++]);
//not in the DB yet:
zone_data->gravity = 0.4;
b = atoi(row[r++]);
can_bind = b==0?false:true;
is_city = b==2?true:false;
can_combat = atoi(row[r++])==0?false:true;
can_levitate = atoi(row[r++])==0?false:true;
can_castoutdoor = atoi(row[r++])==0?false:true;
good = true;
}
mysql_free_result(result);
}
else
LogFile->write(EQEMuLog::Error, "Error in GetZoneCFG query %s: %s", query, errbuf);
safe_delete_array(query);
zone_data->zone_id = zoneid;
return(good);
}
And in /zone/zonedb.cpp, replace what was just removed with:
Code:
bool ZoneDatabase::GetZoneCFG(int32 zoneid, NewZone_Struct *zone_data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &can_coth) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int i=0;
int b=0;
bool good = false;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT ztype,"
"fog_red,fog_green,fog_blue,fog_minclip,fog_maxclip,"
"fog_red2,fog_green2,fog_blue2,fog_minclip2,fog_maxclip2,"
"fog_red3,fog_green3,fog_blue3,fog_minclip3,fog_maxclip3,"
"fog_red4,fog_green4,fog_blue4,fog_minclip4,fog_maxclip4,"
"sky,zone_exp_multiplier,safe_x,safe_y,safe_z,underworld,"
"minclip,maxclip,time_type,canbind,cancombat,canlevitate,castoutdoor,cancoth"
" from zone where zoneidnumber=%i",zoneid), errbuf, &result)) {
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
int r = 0;
memset(zone_data,0,sizeof(NewZone_Struct));
zone_data->ztype=atoi(row[r++]);
for(i=0;i<4;i++){
zone_data->fog_red[i]=atoi(row[r++]);
zone_data->fog_green[i]=atoi(row[r++]);
zone_data->fog_blue[i]=atoi(row[r++]);
zone_data->fog_minclip[i]=atof(row[r++]);
zone_data->fog_maxclip[i]=atof(row[r++]);
}
zone_data->sky=atoi(row[r++]);
zone_data->zone_exp_multiplier=atof(row[r++]);
zone_data->safe_x=atof(row[r++]);
zone_data->safe_y=atof(row[r++]);
zone_data->safe_z=atof(row[r++]);
zone_data->underworld=atof(row[r++]);
zone_data->minclip=atof(row[r++]);
zone_data->maxclip=atof(row[r++]);
zone_data->time_type=atoi(row[r++]);
//not in the DB yet:
zone_data->gravity = 0.4;
b = atoi(row[r++]);
can_bind = b==0?false:true;
is_city = b==2?true:false;
can_combat = atoi(row[r++])==0?false:true;
can_levitate = atoi(row[r++])==0?false:true;
can_castoutdoor = atoi(row[r++])==0?false:true;
can_coth = atoi(row[r++])==0?false:true;
good = true;
}
mysql_free_result(result);
}
else
LogFile->write(EQEMuLog::Error, "Error in GetZoneCFG query %s: %s", query, errbuf);
safe_delete_array(query);
zone_data->zone_id = zoneid;
return(good);
}
Required SQL:
Code:
alter table `zone` add column `cancoth` tinyint (4) DEFAULT '1' NOT NULL after `castoutdoor`;
The default will be set to enabled for all zones. To disable a zone, you will simply open the zones table and change the "cancoth" field from 1 to 0.
I have tested this quickly just now after adding it and it seems to work as intended. I will keep an eye out for any further issues with this code. If anyone else wishes to try it, feel free, and post your results.