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

Reply
 
Thread Tools Display Modes
  #1  
Old 11-24-2012, 11:35 AM
Weldarr
Sarnak
 
Join Date: Oct 2005
Posts: 45
Default /pet no cast and /pet focus

Took a little time to dig through the opcodes and figured out how the /pet commands are handled for the newer clients.

Here are the base changes required for /pet no cast and /pet focus to work similar to EQLive for all clients up to Underfoot.

Required Code:

Code:
Index: common/patches/Underfoot.cpp
===================================================================
--- common/patches/Underfoot.cpp	(revision 2260)
+++ common/patches/Underfoot.cpp	(working copy)
@@ -3260,6 +3260,15 @@
 		case 0x1d:
 			emu->command = 0x02;	// Leave/Go Away
 			break;
+		case 0x15:
+			emu->command = 0x12;	// No Cast - /command
+			break;
+		case 0x16:
+			emu->command = 0x12;	// No Cast - Pet Window
+			break;
+		case 0x18:
+			emu->command = 0x13;	// Focus - Pet Window
+			break;
 		default:
 			emu->command = eq->command;
 	}
Code:
Index: zone/attack.cpp
===================================================================
--- zone/attack.cpp	(revision 2260)
+++ zone/attack.cpp	(working copy)
@@ -2265,6 +2265,7 @@
 	Mob* owner = other->GetOwner();
 	Mob* mypet = this->GetPet();
 	Mob* myowner = this->GetOwner();
+	Mob* targetmob = this->GetTarget();
 	
 	if(other){
 		AddRampage(other);
@@ -2274,10 +2275,15 @@
 		hate = ((hate * (hatemod))/100);
 	}
 	
-	if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld()){
+	if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && !IsFocused()) { //ignore aggro if hold and !focus
 		return; 
-	}	
+	}
 
+	if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && GetOwner()->GetAA(aaAdvancedPetDiscipline) >= 1 && IsFocused()) {
+		if (!targetmob)
+			return;
+	}
+
 	if(IsClient() && !IsAIControlled())
 		return;
 
@@ -3214,10 +3220,12 @@
 		Mob *pet = GetPet();
 		if (pet && !pet->IsFamiliar() && !pet->SpecAttacks[IMMUNE_AGGRO] && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse()) 
 		{
-			mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
-			pet->AddToHateList(attacker, 1);
-			pet->SetTarget(attacker);
-			Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+			if (!pet->IsHeld()) {
+				mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
+				pet->AddToHateList(attacker, 1);
+				pet->SetTarget(attacker);
+				Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+			}
 		}	
 	
 		//see if any runes want to reduce this damage
Code:
Index: zone/client_packet.cpp
===================================================================
--- zone/client_packet.cpp	(revision 2260)
+++ zone/client_packet.cpp	(working copy)
@@ -6864,9 +6864,15 @@
 
 		if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
 			if (GetTarget() != this && mypet->DistNoRootNoZ(*GetTarget()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
-				mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
-				if(mypet->GetPetOrder() != SPO_Guard)
-					mypet->SetPetOrder(SPO_Follow);
+				if (mypet->IsHeld()) {
+					if (!mypet->IsFocused()) {
+						mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
+						if(mypet->GetPetOrder() != SPO_Guard)
+							mypet->SetPetOrder(SPO_Follow);
+					} else {
+						mypet->SetTarget(GetTarget());
+					}
+				}
 				zone->AddAggroMob();
 				mypet->AddToHateList(GetTarget(), 1);
 				Message_StringID(10, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
@@ -7012,6 +7018,60 @@
 		}
 		break;
 	}
+	case PET_NOCAST: {
+		if(GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsNoCast()) {
+				Message(0,"%s says, 'I will now cast spells, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetNoCast(false);
+			} else {
+				Message(0,"%s says, 'I will no longer cast spells, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetNoCast(true);
+			}
+		}
+		break;
+	}
+ 	case PET_FOCUS: {
+		if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsFocused()) {
+				Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(false);
+			} else {
+				Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(true);
+			}
+		}
+		break;
+	}
+ 	case PET_FOCUS_ON: {
+		if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsFocused()) {
+				Message(0,"%s says, 'I am already focused, Master!",mypet->GetCleanName());
+			} else {
+				Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(true);
+			}
+		}
+		break;
+	}
+ 	case PET_FOCUS_OFF: {
+		if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsFocused()) {
+				Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(false);
+			} else {
+				Message(0,"%s says, 'I am already not focused, Master!",mypet->GetCleanName());
+			}
+		}
+		break;
+	}
 	default:
 		printf("Client attempted to use a unknown pet command:\n");
 		break;
Code:
Index: zone/mob.cpp
===================================================================
--- zone/mob.cpp	(revision 2260)
+++ zone/mob.cpp	(working copy)
@@ -306,6 +306,8 @@
 	typeofpet = petCharmed;		//default to charmed...
 	petpower = 0;
 	held = false;
+	nocast = false;
+	focused = false;
 	
 	attacked_count = 0;
 	mezzed = false;
@@ -2741,6 +2743,10 @@
 	if(spell_id == SPELL_UNKNOWN || on->SpecAttacks[NO_HARM_FROM_CLIENT]){ //This is so 65535 doesn't get passed to the client message and to logs because it is not relavant information for debugging.
 				return;
 	}
+
+	if (IsNoCast())
+		return;
+
 	if(!IsValidSpell(spell_id)){ // Check for a valid spell otherwise it will crash through the function
 		if(this->IsClient()){
 			this->Message(0, "Invalid spell proc %u", spell_id);
Code:
Index: zone/mob.h
===================================================================
--- zone/mob.h	(revision 2260)
+++ zone/mob.h	(working copy)
@@ -1100,6 +1100,10 @@
 	inline const eStandingPetOrder GetPetOrder() const { return pStandingPetOrder; }
 	inline void			SetHeld(bool nState) { held = nState; }
 	inline const bool	IsHeld() const { return held; }
+	inline void			SetNoCast(bool nState) { nocast = nState; }
+	inline const bool	IsNoCast() const { return nocast; }
+	inline void			SetFocused(bool nState) { focused = nState; }
+	inline const bool	IsFocused() const { return focused; }
 	inline const bool	IsRoamer() const { return roamer; }
 	inline const bool   IsRooted() const { return rooted || permarooted; }
 	inline const bool   HasVirus() const { return has_virus; }
@@ -1332,6 +1336,8 @@
 	float	runspeed;
 	int32 pLastChange;
 	bool held;
+	bool nocast;
+	bool focused;
 	void CalcSpellBonuses(StatBonuses* newbon);
 	virtual void CalcBonuses();
 	void TrySkillProc(Mob *on, int16 skill, float chance);
Code:
Index: zone/MobAI.cpp
===================================================================
--- zone/MobAI.cpp	(revision 2260)
+++ zone/MobAI.cpp	(working copy)
@@ -58,6 +58,9 @@
 	if (!tar)
 		return false;
 
+	if (IsNoCast())
+		return false;
+
 	if(AI_HasSpells() == false)
 		return false;
 
@@ -1064,7 +1067,14 @@
 		{
 			if(AItarget_check_timer->Check())
 			{
-				SetTarget(hate_list.GetTop(this));
+				if (IsFocused()) {
+					if (!target) {
+						SetTarget(hate_list.GetTop(this));
+					}
+				} else {
+					SetTarget(hate_list.GetTop(this));
+				}
+
 			}
 		}
Code:
Index: zone/pets.h
===================================================================
--- zone/pets.h	(revision 2260)
+++ zone/pets.h	(working copy)
@@ -15,6 +15,10 @@
 	#define PET_NOTAUNT			14
 	#define PET_LEADER			16
 	#define	PET_SLUMBER			17	
+	#define	PET_NOCAST			18	
+	#define	PET_FOCUS			19	
+	#define	PET_FOCUS_ON		25	
+	#define	PET_FOCUS_OFF		26	
 	
 	class Pet : public NPC {
 	public:

Required SQL:

Code:
DELETE FROM `aa_effects` WHERE aaid = 288 or aaid = 1129 or aaid = 1130;
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '288', '1', '267', '1', '15');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1129', '1', '267', '1', '0');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1129', '2', '267', '1', '24');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1130', '1', '267', '1', '21');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1130', '2', '267', '1', '24');

Vaion
Reply With Quote
  #2  
Old 11-24-2012, 01:05 PM
ghanja's Avatar
ghanja
Dragon
 
Join Date: Aug 2012
Location: Hershey, PA
Posts: 499
Default

Not quite sure if replies by those other than the contributor and/or emu devs is 'allowed' but this is one addition/fix I have to thank you for. It -was- a project I was in the middle of attempting to resolve as well, appreciate reducing my labor.
Reply With Quote
  #3  
Old 11-24-2012, 01:40 PM
sorvani
Dragon
 
Join Date: May 2010
Posts: 965
Default

i started to look into this once myself and realized i need to understand eqemu source better unfortunately.
This is built with no errors for me on my test server.

I find it easier to make and apply a single diff for large patches like this.
Code:
Index: trunk/EQEmuServer/common/patches/Underfoot.cpp
===================================================================
--- trunk/EQEmuServer/common/patches/Underfoot.cpp	(revision 2260)
+++ trunk/EQEmuServer/common/patches/Underfoot.cpp	(working copy)
@@ -3260,6 +3260,15 @@
 		case 0x1d:
 			emu->command = 0x02;	// Leave/Go Away
 			break;
+		case 0x15:
+			emu->command = 0x12;	// No Cast - /command
+			break;
+		case 0x16:
+			emu->command = 0x12;	// No Cast - Pet Window
+			break;
+		case 0x18:
+			emu->command = 0x13;	// Focus - Pet Window
+			break;
 		default:
 			emu->command = eq->command;
 	}
Index: trunk/EQEmuServer/zone/attack.cpp
===================================================================
--- trunk/EQEmuServer/zone/attack.cpp	(revision 2260)
+++ trunk/EQEmuServer/zone/attack.cpp	(working copy)
@@ -2265,6 +2265,7 @@
 	Mob* owner = other->GetOwner();
 	Mob* mypet = this->GetPet();
 	Mob* myowner = this->GetOwner();
+	Mob* targetmob = this->GetTarget();
 	
 	if(other){
 		AddRampage(other);
@@ -2274,10 +2275,15 @@
 		hate = ((hate * (hatemod))/100);
 	}
 	
-	if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld()){
+	if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && !IsFocused()) { //ignore aggro if hold and !focus
 		return; 
-	}	
+	}
 
+	if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && GetOwner()->GetAA(aaAdvancedPetDiscipline) >= 1 && IsFocused()) {
+		if (!targetmob)
+			return;
+	}
+
 	if(IsClient() && !IsAIControlled())
 		return;
 
@@ -3214,10 +3220,12 @@
 		Mob *pet = GetPet();
 		if (pet && !pet->IsFamiliar() && !pet->SpecAttacks[IMMUNE_AGGRO] && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse()) 
 		{
-			mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
-			pet->AddToHateList(attacker, 1);
-			pet->SetTarget(attacker);
-			Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+			if (!pet->IsHeld()) {
+				mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
+				pet->AddToHateList(attacker, 1);
+				pet->SetTarget(attacker);
+				Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+			}
 		}	
 	
 		//see if any runes want to reduce this damage
Index: trunk/EQEmuServer/zone/client_packet.cpp
===================================================================
--- trunk/EQEmuServer/zone/client_packet.cpp	(revision 2260)
+++ trunk/EQEmuServer/zone/client_packet.cpp	(working copy)
@@ -6864,9 +6864,15 @@
 
 		if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
 			if (GetTarget() != this && mypet->DistNoRootNoZ(*GetTarget()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
-				mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
-				if(mypet->GetPetOrder() != SPO_Guard)
-					mypet->SetPetOrder(SPO_Follow);
+				if (mypet->IsHeld()) {
+					if (!mypet->IsFocused()) {
+						mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
+						if(mypet->GetPetOrder() != SPO_Guard)
+							mypet->SetPetOrder(SPO_Follow);
+					} else {
+						mypet->SetTarget(GetTarget());
+					}
+				}
 				zone->AddAggroMob();
 				mypet->AddToHateList(GetTarget(), 1);
 				Message_StringID(10, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
@@ -7012,6 +7018,60 @@
 		}
 		break;
 	}
+	case PET_NOCAST: {
+		if(GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsNoCast()) {
+				Message(0,"%s says, 'I will now cast spells, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetNoCast(false);
+			} else {
+				Message(0,"%s says, 'I will no longer cast spells, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetNoCast(true);
+			}
+		}
+		break;
+	}
+ 	case PET_FOCUS: {
+		if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsFocused()) {
+				Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(false);
+			} else {
+				Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(true);
+			}
+		}
+		break;
+	}
+ 	case PET_FOCUS_ON: {
+		if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsFocused()) {
+				Message(0,"%s says, 'I am already focused, Master!",mypet->GetCleanName());
+			} else {
+				Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(true);
+			}
+		}
+		break;
+	}
+ 	case PET_FOCUS_OFF: {
+		if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+			if (mypet->IsFeared())
+				break;
+			if (mypet->IsFocused()) {
+				Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+				mypet->CastToNPC()->SetFocused(false);
+			} else {
+				Message(0,"%s says, 'I am already not focused, Master!",mypet->GetCleanName());
+			}
+		}
+		break;
+	}
 	default:
 		printf("Client attempted to use a unknown pet command:\n");
 		break;
Index: trunk/EQEmuServer/zone/mob.cpp
===================================================================
--- trunk/EQEmuServer/zone/mob.cpp	(revision 2260)
+++ trunk/EQEmuServer/zone/mob.cpp	(working copy)
@@ -306,6 +306,8 @@
 	typeofpet = petCharmed;		//default to charmed...
 	petpower = 0;
 	held = false;
+	nocast = false;
+	focused = false;
 	
 	attacked_count = 0;
 	mezzed = false;
@@ -2741,6 +2743,10 @@
 	if(spell_id == SPELL_UNKNOWN || on->SpecAttacks[NO_HARM_FROM_CLIENT]){ //This is so 65535 doesn't get passed to the client message and to logs because it is not relavant information for debugging.
 				return;
 	}
+
+	if (IsNoCast())
+		return;
+
 	if(!IsValidSpell(spell_id)){ // Check for a valid spell otherwise it will crash through the function
 		if(this->IsClient()){
 			this->Message(0, "Invalid spell proc %u", spell_id);
Index: trunk/EQEmuServer/zone/mob.h
===================================================================
--- trunk/EQEmuServer/zone/mob.h	(revision 2260)
+++ trunk/EQEmuServer/zone/mob.h	(working copy)
@@ -1100,6 +1100,10 @@
 	inline const eStandingPetOrder GetPetOrder() const { return pStandingPetOrder; }
 	inline void			SetHeld(bool nState) { held = nState; }
 	inline const bool	IsHeld() const { return held; }
+	inline void			SetNoCast(bool nState) { nocast = nState; }
+	inline const bool	IsNoCast() const { return nocast; }
+	inline void			SetFocused(bool nState) { focused = nState; }
+	inline const bool	IsFocused() const { return focused; }
 	inline const bool	IsRoamer() const { return roamer; }
 	inline const bool   IsRooted() const { return rooted || permarooted; }
 	inline const bool   HasVirus() const { return has_virus; }
@@ -1332,6 +1336,8 @@
 	float	runspeed;
 	int32 pLastChange;
 	bool held;
+	bool nocast;
+	bool focused;
 	void CalcSpellBonuses(StatBonuses* newbon);
 	virtual void CalcBonuses();
 	void TrySkillProc(Mob *on, int16 skill, float chance);
Index: trunk/EQEmuServer/zone/MobAI.cpp
===================================================================
--- trunk/EQEmuServer/zone/MobAI.cpp	(revision 2260)
+++ trunk/EQEmuServer/zone/MobAI.cpp	(working copy)
@@ -58,6 +58,9 @@
 	if (!tar)
 		return false;
 
+	if (IsNoCast())
+		return false;
+
 	if(AI_HasSpells() == false)
 		return false;
 
@@ -1064,7 +1067,14 @@
 		{
 			if(AItarget_check_timer->Check())
 			{
-				SetTarget(hate_list.GetTop(this));
+				if (IsFocused()) {
+					if (!target) {
+						SetTarget(hate_list.GetTop(this));
+					}
+				} else {
+					SetTarget(hate_list.GetTop(this));
+				}
+
 			}
 		}
Index: trunk/EQEmuServer/zone/pets.h
===================================================================
--- trunk/EQEmuServer/zone/pets.h	(revision 2260)
+++ trunk/EQEmuServer/zone/pets.h	(working copy)
@@ -15,6 +15,10 @@
 	#define PET_NOTAUNT			14
 	#define PET_LEADER			16
 	#define	PET_SLUMBER			17	
+	#define	PET_NOCAST			18	
+	#define	PET_FOCUS			19	
+	#define	PET_FOCUS_ON		25	
+	#define	PET_FOCUS_OFF		26	
 	
 	class Pet : public NPC {
 	public:
Reply With Quote
  #4  
Old 11-24-2012, 01:42 PM
Weldarr
Sarnak
 
Join Date: Oct 2005
Posts: 45
Default

Aye I had it as a single patch, but figured it would be easier for people to read through if I separated it.
Reply With Quote
  #5  
Old 11-24-2012, 01:53 PM
sorvani
Dragon
 
Join Date: May 2010
Posts: 965
Default

damn was going to test it and realized i lost my x64 test box when i decided to rebuild a new web server.
rebuilding x32 and installing everything on a different test box
Reply With Quote
  #6  
Old 11-24-2012, 04:11 PM
sorvani
Dragon
 
Join Date: May 2010
Posts: 965
Default

was confused why it did not work then realized i was level 65. upped the level to 70 on my test server and it worked fine.

committed asrev 2262
Reply With Quote
  #7  
Old 11-24-2012, 04:26 PM
sorvani
Dragon
 
Join Date: May 2010
Posts: 965
Default

on this same subject, one would then assume that the /pet hold toggle would be found around here then. before I go look at how the source is handling it, have you already solved that one too?
Reply With Quote
  #8  
Old 11-24-2012, 09:43 PM
Weldarr
Sarnak
 
Join Date: Oct 2005
Posts: 45
Default

Pet hold was already fixed awhile back. There were a few modification that I made with the SQL to clean up the AA effects that were not required for anything.

In the SQL the effect 267 with base 15 is the pet hold command for the UF client. So this fix already incorporates pet hold.

To use it you just need to purchase the pet discipline AA. To use focus/no cast you need to purchase the advanced pet discipline AAs.
Reply With Quote
  #9  
Old 11-25-2012, 09:15 PM
sorvani
Dragon
 
Join Date: May 2010
Posts: 965
Default

with a default PEQ database pet hold does not toggle. i tested that to make sure before I posted. Yes pet hold works. no it does not toggle.
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 01:26 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