Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 07-07-2008, 07:12 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default Disable CotH on a Per-Zone Basis

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.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #2  
Old 07-07-2008, 04:56 PM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

I think we need a solution that works for areas of zones instead of just entire zones.
Reply With Quote
  #3  
Old 07-07-2008, 05:21 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Ya, that would be nice. That would go well beyond my coding skill level lol. IMO, disabling per zone should work well in most cases. I can't really think of many cases where I would like to have CotH available in a zone, but not in 1 section of it. In most cases, I think disabling for the entire zone would be just fine. Just my opinion though.

I am not really sure how you would disable it for a certain area. It seems like it would be very complex to add in a defined area to limit CotH.

IMO, the best way to remove CotH from a certain area would probably be to use quests instead of code. Then, just use a quest with a proximity that encompasses the entire area you want to remove coth from and use some kind of check for players casting spell 1771 within that proximity and have it duck the player or cancel the spell in another way.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #4  
Old 07-07-2008, 06:22 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

I was thinking a bit more about it and maybe the cancoth field could be set to allow more input. If it could be set so that 0 disables coth for the entire zone, and 1 enables it for the entire zone, and then have another option of setting which could be option 2,x,y,z,xr,yr,zr. If this option 2 could then have more information included with it, maybe you could set this up as a proximity to define areas.

It could pull the values from a comma separated input something like:

Code:
cancoth
2,0,0,0,50,50,25
Where, the first 2 is what tells the code that it is going to use the additional input that follows. Then, the 3 0s are the location of the center of the proximity you are setting. Then, the first 50 is for setting the X axis range of the proximity check. The next 50 is for setting the Y axis range, and the 25 sets the Z axis range.

I think the code I have posted here would do part of what is needed to get this set, but you would have to change the input type in the field to accept the additional input. There would also have to be some code added that will allow you to define the proximity. Maybe looking into the code for setting quest proximities would help to figure out what needs to be added to get it working to do this.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #5  
Old 07-07-2008, 06:53 PM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

Quote:
Originally Posted by trevius View Post
It could pull the values from a comma separated input something like:

Code:
cancoth
2,0,0,0,50,50,25
I personally think adding a table to the database for this would be better than using a text file. The only somewhat difficult part may be for areas that you want to block off that you don't really want rectangular for whatever reason. In reality though, it just means more entries in the database.

Then again, I think this could be taken a step further: why just CotH, Lev, & SoW manually blocked in the code? Why not make it apply to any spell you want?

Just thinking out loud, you could define a table, maybe blocked_spells, with the spell id, type of block (using 1 & 2 like you suggested), zone id, and coordinates/sizes. Here would be an example:

Code:
| id | spellid | type | zoneid |  x   |  y   |  z   |  l   |  w   |  h   |
|----+---------+------+--------+------+------+------+------+------+------|
| 1  |  1771   |  1   |   71   | NULL | NULL | NULL | NULL | NULL | NULL |
| 2  |  1771   |  2   |  202   | 978  |  0   | 425  |  50  |  50  |  35  |
This would block CotH from being used in airplane at all & poknowledge in the library tower.

In the code, you could then just run a check when the spell is cast to see if the spell is restricted in the table, and then if you are standing in the coordinates if they are defined. If you are, return false (causing the spell not to be cast) w/ an client that you can use that spell there. Hell, you could just define a message to the client in the same table.

Thoughts?
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
  #6  
Old 07-07-2008, 08:15 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Ya, another table would probably be best. I was just trying to avoid having to add another table to do this. Though, it would be nice to have the option to block any spell in any area.

From what I can tell, it looks like this is where set_proximity is defined for quests:

questmgr.cpp
Code:
void QuestManager::set_proximity(float minx, float maxx, float miny, float maxy, float minz, float maxz) {
	if(!owner->IsNPC())
		return;

	entity_list.AddProximity(owner->CastToNPC());

	owner->CastToNPC()->proximity->min_x = minx;
	owner->CastToNPC()->proximity->max_x = maxx;
	owner->CastToNPC()->proximity->min_y = miny;
	owner->CastToNPC()->proximity->max_y = maxy;
	owner->CastToNPC()->proximity->min_z = minz;
	owner->CastToNPC()->proximity->max_z = maxz;
}
Maybe that could be adjusted to be used without requiring an NPC and then make it a static proximity in the zone.

This is definitely getting beyond my level of code understanding though, lol. I can normally find where the code is or examples to work from, but as far as figuring out exactly what needs to be changed to get something working, I am not very good at that.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #7  
Old 07-07-2008, 11:19 PM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

Quote:
Originally Posted by trevius View Post
Maybe that could be adjusted to be used without requiring an NPC and then make it a static proximity in the zone.
That's the idea behind my... idea. Essentially you create a proximity (essentially a cube area) using coordinates stored in the database. That way, if you want to change it, you don't have to mess with moving an NPC, editing a quest, etc, you just change the value in the db.

I'd like to try & tackle this, but unfortunately I don't know if I have the time available right now to do so :-\ If I do get some extra time, I'll see what I can come up with
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
  #8  
Old 07-08-2008, 03:34 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

http://www.eqemulator.net/forums/showthread.php?t=24208

This never got added in, but roamboxes use a similar method for specifying a section of zone. Perhaps you can take a look at Ailia's code in there and see if you can adapt it to the zone part of the database, instead of roamboxes?


PS: off topic, but can we have advnpcspawn added? I'm tired of people using #npcspawn and not knowing how the schema works. It's more good as a learning tool than anything. It also adds roamboxes, which are a good replacement for grids.
Reply With Quote
  #9  
Old 07-26-2008, 05:02 PM
Angelox
AX Classic Developer
 
Join Date: May 2006
Location: filler
Posts: 2,049
Default

trevius;
Are you still using the original version of this fix, or have you changed it any?
Also, would an SQL of zones that use this be possible?

Thanks
Reply With Quote
  #10  
Old 07-26-2008, 09:23 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Ya, I am still using the original code change that I posted. I think it works just fine and I am pretty sure it was done on a per zone basis for EQLive. I wouldn't mind having a way to define proximities that stop certain spells from being casted. But, I think that the per zone limits meets any needs I would have for disabling CotH. I don't really need to be too specific about limiting it.

I don't have a list of which zones didn't allow it. The only one I can think of off the top of my head that I am pretty sure didn't allow CotH is Ssra Temple, but then again, that might have only been for the emperor area lol... Been too long.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #11  
Old 08-04-2008, 11:22 PM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

Quote:
Originally Posted by AndMetal View Post
If I do get some extra time, I'll see what I can come up with
I verified this compiles and it works as intended.

In zone/zonedb.h, after
Code:
   47 struct PetRecord {
   48 	uint32 npc_type;
   49 	bool temporary;
   50 };
add
Code:
// Spell Blocking by AndMetal
struct SpellBlocking_Struct{
	sint32	id;			// -1 = database error, 0 = no matches in the database, 1+ = id in the blocked_spells table
	int8	type;		// 0 = not blocked, 1 = zone wide, 2 = specific coords in the zone
	char*	message;	// Message to send to the client saying the message failed, for customizability
};
and a little farther down, after
Code:
  277 	/*
  278 	 * Misc stuff.
  279 	 * PLEASE DO NOT ADD TO THIS COLLECTION OF CRAP UNLESS YOUR METHOD
  280 	 * REALLY HAS NO BETTER SECTION
  281 	 */
  282 	bool    logevents(const char* accountname,int32 accountid,int8 status,const char* charname,const char* target, const char* descriptiontype, const char* description,int event_nid);
  283 	void	GetEventLogs(const char* name,char* target,int32 account_id=0,int8 eventid=0,char* detail=0,char* timestamp=0, CharacterEventLog_Struct* cel=0);
add
Code:
	// Spell Blocking by AndMetal
	SpellBlocking_Struct	GetSpellBlock(int16 spell_id, uint16 zone_id, float x, float y, float z);
In zone/zonedb.cpp, after
Code:
 1268 /*
 1269  solar: this is never actually called, client_process starts an async query
 1270  instead and uses GetAccountInfoForLogin_result to process it..
 1271  */
 1272 bool ZoneDatabase::GetAccountInfoForLogin(int32 account_id, sint16* admin, char* account_name, int32* lsaccountid, int8* gmspeed, bool* revoked,bool* gmhideme) {
 1273 	char errbuf[MYSQL_ERRMSG_SIZE];
 1274     char *query = 0;
 1275     MYSQL_RES *result;
 1276 
 1277 	if (RunQuery(query, MakeAnyLenString(&query, "SELECT status, name, lsaccount_id, gmspeed, revoked, hideme FROM account WHERE id=%i", account_id), errbuf, &result)) {
 1278 		safe_delete_array(query);
 1279 		bool ret = GetAccountInfoForLogin_result(result, admin, account_name, lsaccountid, gmspeed, revoked,gmhideme);
 1280 		mysql_free_result(result);
 1281 		return ret;
 1282 	}
 1283 	else
 1284 	{
 1285 		cerr << "Error in GetAccountInfoForLogin query '" << query << "' " << errbuf << endl;
 1286 		safe_delete_array(query);
 1287 		return false;
 1288 	}
 1289 
 1290 	return false;
 1291 }
add
Code:
/* Spell Blocking by AndMetal
To Do: load blocked_spells table into shared memory, should keep the database from exploding, but as-is allows for changes to take effect immediately
*/
SpellBlocking_Struct ZoneDatabase::GetSpellBlock(int16 spell_id, uint16 zone_id, float x, float y, float z) {
	// Database stuff
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;

	SpellBlocking_Struct blocked;
	blocked.id = 0;

	if(RunQuery(query, MakeAnyLenString(&query, "SELECT bs.id, bs.type, bs.message FROM blocked_spells bs "
		"WHERE bs.zoneid = %i "
		"AND bs.spellid = %i "
		// Create a virtual box of spell blockage, but still include NULLs
		"AND ((%i BETWEEN (bs.x - bs.x_diff) AND (bs.x + bs.x_diff)) OR (x IS NULL) OR (x_diff IS NULL)) " 
		"AND ((%i BETWEEN (bs.y - bs.y_diff) AND (bs.y + bs.y_diff)) OR (y IS NULL) OR (y_diff IS NULL))"
		"AND ((%i BETWEEN (bs.z - bs.z_diff) AND (bs.z + bs.z_diff)) OR (z IS NULL) OR (z_diff IS NULL))"
		// Type 2s first, in case there is a message to show for that specific spot in the zone
		"ORDER BY bs.type DESC, bs.id ASC LIMIT 1", zone_id, spell_id, x, y, z), errbuf, &result)) {
		safe_delete_array(query);
		if(mysql_num_rows(result) != 0) { // Did we get anything from the query?
			row = mysql_fetch_row(result);
			blocked.id = atoi(row[0]);
			blocked.type = atoi(row[1]);
			blocked.message = row[2];
			mysql_free_result(result);
		}
		else
			mysql_free_result(result);
	}
	else {
		blocked.id = -1;
		cerr << "Error in GetSpellBlock query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
	}
	return blocked;
}
Lastly, in zone/spells.cpp, after
Code:
 1254 	// angelox start
 1255 
 1256 	if(IsEffectInSpell(spell_id, SE_Levitate) && !zone->CanLevitate()){
 1257 			if(IsClient()){
 1258 				if(!CastToClient()->GetGM()){
 1259 					Message(13, "You can't levitate in this zone.");
 1260 					return false;
 1261 				}
 1262 			}
 1263 		}
add
Code:
	// Spell Blocking by AndMetal
	if(IsClient() && !CastToClient()->GetGM()) { // First the easy stuff, should pass over this if they're a regular mob
		SpellBlocking_Struct blocked = database.GetSpellBlock(spell_id, GetZoneID(), GetX(), GetY(), GetZ());
		if(blocked.id > 0) {
			if(blocked.message != NULL) 
				Message(13, blocked.message); // Output message from the DB
			else if(blocked.type == 2)
				Message(13, "You can't cast this spell here. Try somewhere else."); // Default client message, hinting that it's just that part of the zone
			else if(blocked.type == 1)
				Message(13, "You can't cast this spell here."); //Default client message
			return false; // Prevents the spell from casting
		}
	}
New table, blocked_spells
Code:
DROP TABLE IF EXISTS `blocked_spells`;
CREATE TABLE `blocked_spells` (
  `id` int(11) NOT NULL auto_increment,
  `spellid` mediumint(8) unsigned NOT NULL default '0',
  `type` tinyint(4) NOT NULL default '0',
  `zoneid` int(4) NOT NULL default '0',
  `x` float default NULL,
  `y` float default NULL,
  `z` float default NULL,
  `x_diff` float default NULL,
  `y_diff` float default NULL,
  `z_diff` float default NULL,
  `message` varchar(255) default NULL,
  `description` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;
and a starting value
Code:
INSERT INTO blocked_spells (spellid, type, zoneid, description) VALUES (1771, 1, 71, 'Prevent CoH in airplane')
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
  #12  
Old 08-04-2008, 11:49 PM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

Quote:
Originally Posted by AndMetal View Post
I verified this compiles and it works as intended.
Correction: the entire zone option works as intended, however the intra-zone option looks like it may need some debugging. As of right now, intra-zone doesn't work at all.
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
  #13  
Old 08-05-2008, 12:05 AM
Flare83
Sarnak
 
Join Date: Aug 2008
Location: usa
Posts: 43
Default

Quote:
Originally Posted by trevius View Post
Ya, I am still using the original code change that I posted. I think it works just fine and I am pretty sure it was done on a per zone basis for EQLive.
I think it was until PoP came out. i remember only being able to coth / necro summon people in the graveyard's in PoP zones.
Reply With Quote
  #14  
Old 08-05-2008, 04:53 AM
Garath
Fire Beetle
 
Join Date: Jun 2005
Posts: 5
Default

Just a quick note in case you want to use the same text as on live when CoH isn't working instead of a generic can't use message. It said:
A voice whispers in your mind: "There are no heroes here..."
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 07:03 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3