View Single Post
  #19  
Old 07-10-2011, 07:16 PM
Criimson
Hill Giant
 
Join Date: Sep 2006
Posts: 172
Default

Well after running some tests I think I may have the chater mezzing working better.

Here is a log file from the last fight after several tests.
Edited to only show damage taken and Gilandra casting (she's my chanter)

Code:
<<After several tests I decide to log one>>

<<This is me running past the first mob - a grimling overseer - towards an add mob - a grimling mystic>>
 
[Sun Jul 10 15:52:52 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:52:52 2011] A grimling overseer was burned.
[Sun Jul 10 15:52:52 2011] A grimling overseer tries to hit YOU, but YOUR magical skin absorbs the blow!
[Sun Jul 10 15:52:52 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:52:52 2011] A grimling overseer was burned.
[Sun Jul 10 15:52:52 2011] A grimling overseer tries to hit YOU, but YOUR magical skin absorbs the blow!
[Sun Jul 10 15:52:52 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:52:52 2011] A grimling overseer was burned.
[Sun Jul 10 15:52:52 2011] A grimling overseer tries to kick YOU, but YOUR magical skin absorbs the blow!

<<I reach the second mob>>

[Sun Jul 10 15:52:55 2011] a grimling mystic was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:52:55 2011] A grimling mystic was burned.

[Sun Jul 10 15:52:55 2011] The shimmer of runes fades.

[Sun Jul 10 15:52:55 2011] A grimling mystic hits YOU for 19 points of damage.

[Sun Jul 10 15:52:57 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:52:57 2011] A grimling overseer was burned.
[Sun Jul 10 15:52:57 2011] A grimling overseer hits YOU for 31 points of damage.
[Sun Jul 10 15:52:57 2011] A grimling overseer tries to kick YOU, but YOU parry!
[Sun Jul 10 15:52:57 2011] a grimling mystic begins to cast a spell.

[Sun Jul 10 15:52:57 2011] Gilandra begins to cast a spell.
[Sun Jul 10 15:52:57 2011] Auto attack is on.

[Sun Jul 10 15:52:58 2011] You feel a fever settle upon you.

[Sun Jul 10 15:52:59 2011] a grimling mystic was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:52:59 2011] A grimling mystic was burned.
[Sun Jul 10 15:52:59 2011] A grimling mystic hits YOU for 38 points of damage.

[Sun Jul 10 15:53:00 2011] A light shimmer of runes surrounds you.
.
[Sun Jul 10 15:53:00 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:53:00 2011] A grimling overseer was burned.
[Sun Jul 10 15:53:00 2011] A grimling overseer tries to hit YOU, but YOUR magical skin absorbs the blow!
[Sun Jul 10 15:53:00 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:53:00 2011] A grimling overseer was burned.
[Sun Jul 10 15:53:00 2011] The shimmer of runes fades.
[Sun Jul 10 15:53:00 2011] A grimling overseer hits YOU for 33 points of damage.

[Sun Jul 10 15:53:02 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:53:02 2011] A grimling overseer was burned.
[Sun Jul 10 15:53:02 2011] A grimling overseer bashes YOU for 15 points of damage.

[Sun Jul 10 15:53:02 2011] Gilandra begins to cast a spell.

[Sun Jul 10 15:53:03 2011] a grimling mystic was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:53:03 2011] A grimling mystic was burned.
[Sun Jul 10 15:53:03 2011] A grimling mystic hits YOU for 17 points of damage.

[Sun Jul 10 15:53:04 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:53:04 2011] A grimling overseer was burned.
[Sun Jul 10 15:53:04 2011] A grimling overseer hits YOU for 24 points of damage.
[Sun Jul 10 15:53:04 2011] a grimling overseer was hit by non-melee for 6 points of damage.
[Sun Jul 10 15:53:04 2011] A grimling overseer was burned.
[Sun Jul 10 15:53:04 2011] A grimling overseer hits YOU for 15 points of damage.

[Sun Jul 10 15:53:04 2011] A grimling mystic has been enthralled.
Only cast a rune and then mezzed the add.

Sorry for the fast update and to have to recompile but the idea came to me and I had to try it

This is the up to date version

Code:
Index: bot.cpp
===================================================================
--- bot.cpp	(revision 1958)
+++ bot.cpp	(working copy)
@@ -1212,7 +1212,8 @@
 			mitigation += GetLevel() * 13/10;	//the 13/10 might be wrong, but it is close...
 	}
 	int displayed = 0;
-	displayed += ((avoidance+mitigation)*1000)/847;	//natural AC
+	//displayed += ((avoidance+mitigation)*1000)/847;
+	displayed += ((avoidance+mitigation)*500)/950;	//natural AC
 
 	//Iksar AC, untested
 	if(GetRace() == IKSAR)
@@ -10076,6 +10077,7 @@
 		c->Message(0, "#bot botgroup help - Displays the commands available to manage BOT ONLY groups.");
 		c->Message(0, "#bot mana [<bot name or target> | all] - Displays a mana report for all your spawned bots.");
 		c->Message(0, "#bot [hair|haircolor|beard|beardcolor|face|eyes|heritage|tattoo|details <value>] - Change your BOTs appearance.");
+		c->Message(0, "#bot setfollowdistance ### - sets target bots follow distance to ### (ie 30 or 250).");
 		// TODO:
 		// c->Message(0, "#bot illusion <bot/client name or target> - Enchanter Bot cast an illusion buff spell on you or your target.");
 		c->Message(0, "#bot pull [<bot name>] [target] - Bot Pulling Target NPC's");
@@ -10453,6 +10455,31 @@
 		return;
 	}
 
+	//Criimson added Bot follow distance - SetFollowDistance
+	if(!strcasecmp(sep->arg[1], "setfollowdistance")) {
+		if((c->GetTarget() == NULL) || (c->GetTarget() == c) || (!c->GetTarget()->IsBot()) ) {
+			c->Message(15, "You must target a bot!");
+		}
+		else {
+			int32 BotFollowDistance = atoi(sep->arg[2]);
+			c->GetTarget()->SetFollowDistance(BotFollowDistance);
+		}
+
+		return;
+	}
+
+
+	if(!strcasecmp(sep->arg[1], "picklock")) {
+		if((c->GetTarget() == NULL) || (c->GetTarget() == c) || !c->GetTarget()->IsBot() || (c->GetTarget()->GetClass() != ROGUE)) {
+			c->Message(15, "You must target a rogue bot!");
+		}
+		else {
+			entity_list.BotPickLock(c->GetTarget()->CastToBot());
+		}
+
+		return;
+	}
+
 	if(!strcasecmp(sep->arg[1], "archery")) {
 		if((c->GetTarget() == NULL) || (c->GetTarget() == c) || !c->GetTarget()->IsBot()) {
 			c->Message(15, "You must target a bot!");
@@ -10910,6 +10937,14 @@
 							Tracker = g->members[i];
 							TrackerClass = RANGER;
 							break;
+							//Criimson: Reordered code - was giving priority to bard
+						case DRUID:
+							// Unless we have a ranger, druid is next best.
+							if(TrackerClass != RANGER) {
+								Tracker = g->members[i];
+								TrackerClass = DRUID;
+							}
+							break;
 						case BARD:
 							// If we haven't found a tracker yet, use bard.
 							if(TrackerClass == 0) {
@@ -10917,13 +10952,7 @@
 								TrackerClass = BARD;
 							}
 							break;
-						case DRUID:
-							// Unless we have a ranger, druid is next best.
-							if(TrackerClass != RANGER) {
-								Tracker = g->members[i];
-								TrackerClass = DRUID;
-							}
-							break;
+			
 						default:
 							break;
 					}
@@ -11346,9 +11375,17 @@
 		else {
 			if(c->IsGrouped()) {
 				Group *g = c->GetGroup();
+				bool DoesGroupHaveEnchanter = false;
 
 				for(int i=0; i<MAX_GROUP_MEMBERS; i++) {
-					if(g && g->members[i] && g->members[i]->IsBot() && ((g->members[i]->GetClass() == ENCHANTER) || g->members[i]->GetClass() == CLERIC)) {
+					if(g && g->members[i] && g->members[i]->IsBot() && (g->members[i]->GetClass() == ENCHANTER)) {
+						DoesGroupHaveEnchanter = true;
+					}
+				}
+
+				for(int i=0; i<MAX_GROUP_MEMBERS; i++) {
+					//Criimson - seperated cleric and chanter so chanter is primary
+					if(g && g->members[i] && g->members[i]->IsBot() && (g->members[i]->GetClass() == ENCHANTER)) {
 						Bot *pacer = g->members[i]->CastToBot();
 						pacer->Say("Trying to pacify %s \n", target->GetCleanName());
 
@@ -11356,12 +11393,29 @@
 							if(target->FindType(SE_Lull) || target->FindType(SE_Harmony) || target->FindType(SE_Calm))
 							//if(pacer->IsPacified(target))
 								c->Message(0, "I have successfully pacified %s.", target->GetCleanName());
+								return;
 							/*else
 								c->Message(0, "I failed to pacify %s.", target->GetCleanName());*/
 						}
 						else
 							c->Message(0, "I failed to pacify %s.", target->GetCleanName());
 					}
+					//Criimson - seperated cleric and chanter so chanter is primary
+					if(g && g->members[i] && g->members[i]->IsBot() && (g->members[i]->GetClass() == CLERIC) && (DoesGroupHaveEnchanter == false)) {
+						Bot *pacer = g->members[i]->CastToBot();
+						pacer->Say("Trying to pacify %s \n", target->GetCleanName());
+
+						if(pacer->Bot_Command_CalmTarget(target)) {
+							if(target->FindType(SE_Lull) || target->FindType(SE_Harmony) || target->FindType(SE_Calm))
+							//if(pacer->IsPacified(target))
+								c->Message(0, "I have successfully pacified %s.", target->GetCleanName());
+								return;
+							/*else
+								c->Message(0, "I failed to pacify %s.", target->GetCleanName());*/
+						}
+						else
+							c->Message(0, "I failed to pacify %s.", target->GetCleanName());
+					}
 					/*else
 						c->Message(15, "You must have an Enchanter or Cleric in your group.");*/
 				}
@@ -13255,7 +13309,8 @@
 
 	int8 botCasterClass = caster->GetClass();
 
-	if( botCasterClass == CLERIC || botCasterClass == DRUID || botCasterClass == SHAMAN || botCasterClass == PALADIN || botCasterClass == BEASTLORD || botCasterClass == RANGER) {
+	//CRIIMSON: Changed so heal based on health percentage is different for hybrids
+	if( botCasterClass == CLERIC || botCasterClass == DRUID || botCasterClass == SHAMAN) {
 		//If AI_EngagedCastCheck() said to the healer that he had to heal
 		if( iSpellTypes == SpellType_Heal )	{
 			// check in group
@@ -13300,6 +13355,52 @@
 		}
 	}
 
+		//CRIIMSON: Changed so heal based on health percentage is different for hybrids
+		if( botCasterClass == PALADIN || botCasterClass == BEASTLORD || botCasterClass == RANGER) {
+		//If AI_EngagedCastCheck() said to the healer that he had to heal
+		if( iSpellTypes == SpellType_Heal )	{
+			// check in group
+			if(caster->HasGroup()) {
+				Group *g = caster->GetGroup();
+				
+				if(g) {
+					for(int i = 0; i < MAX_GROUP_MEMBERS; i++) {
+						if(g->members[i] && !g->members[i]->qglobal) {
+							if(g->members[i]->IsClient() && g->members[i]->GetHPRatio() < 20) {
+								if(caster->AICastSpell(g->members[i], iChance, SpellType_Heal))
+									return true;
+							}
+							else if((g->members[i]->GetClass() ==  WARRIOR || g->members[i]->GetClass() == PALADIN || g->members[i]->GetClass() == SHADOWKNIGHT) &&
+								g->members[i]->GetHPRatio() < 20) 
+							{
+								if(caster->AICastSpell(g->members[i], 100, SpellType_Heal))
+									return true;
+							}
+							else if(g->members[i]->GetClass() ==  ENCHANTER && g->members[i]->GetHPRatio() < 20) {
+								if(caster->AICastSpell(g->members[i], 100, SpellType_Heal))
+									return true;
+							}
+							else if(g->members[i]->GetHPRatio() < 20) {
+								if(caster->AICastSpell(g->members[i], 100, SpellType_Heal))
+									return true;
+							}
+						}
+
+						if(g->members[i] && !g->members[i]->qglobal && g->members[i]->HasPet() && g->members[i]->GetPet()->GetHPRatio() < 20) {
+							if(g->members[i]->GetPet()->GetOwner() != caster && caster->IsEngaged() && g->members[i]->IsCasting() && g->members[i]->GetClass() != ENCHANTER )
+								continue;
+
+							if(caster->AICastSpell(g->members[i]->GetPet(), 100, SpellType_Heal))
+								return true;
+						}
+					}
+				}
+			}
+
+			// TODO: raid heals
+		}
+	}
+	
 	//Ok for the buffs..
 	if( iSpellTypes == SpellType_Buff) {
 		// Let's try to make Bard working...
@@ -13332,6 +13433,7 @@
 	return false;
 }
 
+
 Mob* EntityList::GetMobByBotID(uint32 botID) {
 	Mob* Result = 0;
 
Index: bot.h
===================================================================
--- bot.h	(revision 1958)
+++ bot.h	(working copy)
@@ -292,6 +292,7 @@
 	static bool GroupHasClericClass(Group* group) { return GroupHasClass(group, CLERIC); }
 	static bool GroupHasDruidClass(Group* group) { return GroupHasClass(group, DRUID); }
 	static bool GroupHasShamanClass(Group* group) { return GroupHasClass(group, SHAMAN); }
+	static bool GroupHasEnchanterClass(Group* group) { return GroupHasClass(group, ENCHANTER); }
 	static bool GroupHasPriestClass(Group* group) { return GroupHasClass(group, CLERIC | DRUID | SHAMAN); }
 
 	// "GET" Class Methods
Index: botspellsai.cpp
===================================================================
--- botspellsai.cpp	(revision 1958)
+++ botspellsai.cpp	(working copy)
@@ -40,6 +40,34 @@
 	botSpell.ManaCost = 0;
 
 	switch (iSpellTypes) {
+		case SpellType_Mez: {
+			if (tar->GetBodyType() != BT_Giant) {
+					if(!checked_los) {
+						if(!CheckLosFN(tar))
+							break;	//cannot see target... we assume that no spell is going to work since we will only be casting detrimental spells in this call
+						
+						checked_los = true;
+					}
+					
+					botSpell = GetBestBotSpellForMez(this);
+
+					if(botSpell.SpellId == 0)
+						break;
+
+					Mob* addMob = GetFirstIncomingMobToMez(this, botSpell);
+
+					if(!addMob){
+						//Say("!addMob.");
+						break;}
+
+					if(!(!addMob->IsImmuneToSpell(botSpell.SpellId, this) && addMob->CanBuffStack(botSpell.SpellId, botLevel, true) >= 0))
+						break;
+					
+					castedSpell = AIDoSpellCast(botSpell.SpellIndex, addMob, botSpell.ManaCost);
+
+			}
+			break;
+			}
 		case SpellType_Heal: {
 			if (tar->DontHealMeBefore() < Timer::GetCurrentTime()) {
 				int8 hpr = (int8)tar->GetHPRatio();
@@ -186,7 +214,7 @@
 				}
 			}
 			break;
-							 }
+			}
 		case SpellType_Root: {
 			if (!tar->IsRooted() && tar->DontRootMeBefore() < Timer::GetCurrentTime()) {
 					if(!checked_los) {
@@ -214,7 +242,7 @@
 						tar->SetDontRootMeBefore(TempDontRootMeBefore);
 			}
 			break;
-							 }
+			}
 		case SpellType_Buff: {
 			if (tar->DontBuffMeBefore() < Timer::GetCurrentTime()) {
 				std::list<BotSpell> buffSpellList = GetBotSpellsBySpellType(this, SpellType_Buff);
@@ -253,6 +281,29 @@
 							continue;
 					}
 
+					switch(tar->GetArchetype())
+					{
+						case ARCHETYPE_CASTER:
+							//TODO: probably more caster specific spell effects in here
+							if(IsEffectInSpell(selectedBotSpell.SpellId, SE_AttackSpeed) || IsEffectInSpell(selectedBotSpell.SpellId, SE_ATK) ||
+								 IsEffectInSpell(selectedBotSpell.SpellId, SE_STR) || IsEffectInSpell(selectedBotSpell.SpellId, SE_ReverseDS))
+							{
+								continue;
+							}
+							break;
+						case ARCHETYPE_MELEE:
+							//TODO: Include mana regen (breeze/clarity/etc), I don't know what spell effect it is
+							if(IsEffectInSpell(selectedBotSpell.SpellId, SE_IncreaseSpellHaste) || IsEffectInSpell(selectedBotSpell.SpellId, SE_ManaPool))
+							{
+								continue;
+							}
+							break;
+						case ARCHETYPE_HYBRID:
+							//Hybrids get all buffs
+						default:
+							break;
+					}
+
 					if(CheckSpellRecastTimers(this, itr->SpellIndex))
 					{
 
@@ -269,7 +320,7 @@
 				}
 			}
 			break;
-							 }
+			}
 		case SpellType_Escape: {
 			int8 hpr = (int8)GetHPRatio();
 #ifdef IPC          
@@ -286,7 +337,7 @@
 				castedSpell = AIDoSpellCast(botSpell.SpellIndex, this, botSpell.ManaCost);
 			}
 			break;
-							   }
+			}
 		case SpellType_Nuke: {
 			if((tar->GetHPRatio() <= 95.0f) || ((botClass == BARD) || (botClass == SHAMAN) || (botClass == ENCHANTER)))
 			{
@@ -297,6 +348,17 @@
 					checked_los = true;
 				}
 
+				if(botClass == CLERIC && this->GetManaRatio() <= 75.0f)
+				{
+					//If we're at 75% mana or below, don't nuke as a cleric or 50% as enchanter
+					break;
+				}
+				if(botClass == ENCHANTER && this->GetManaRatio() <= 50.0f)
+				{
+					//If we're at 75% mana or below, don't nuke as a cleric or 50% as enchanter
+					break;
+				}
+
 				if(botClass == MAGICIAN || botClass == SHADOWKNIGHT || botClass == NECROMANCER || botClass == PALADIN || botClass == RANGER || botClass == DRUID || botClass == CLERIC) {
 					if(tar->GetBodyType() == BT_Undead || tar->GetBodyType() == BT_SummonedUndead || tar->GetBodyType() == BT_Vampire)
 						botSpell = GetBestBotSpellForNukeByTargetType(this, ST_Undead);
@@ -341,7 +403,7 @@
 				castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
 			}
 			break;
-							 }
+			}
 		case SpellType_Dispel: {
 			if(tar->GetHPRatio() > 95.0f) {
 				if(!checked_los) {
@@ -363,7 +425,7 @@
 				}
 			}
 			break;
-							   }
+			}
 		case SpellType_Pet: {
 				//keep mobs from recasting pets when they have them.
 				if (!IsPet() && !GetPetID() && !IsBotCharmer()) {
@@ -378,7 +440,7 @@
 					castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
 				}
 				break;
-							}
+				}
 		case SpellType_Lifetap: {
 			if (GetHPRatio() < 90.0f) {
 				if(!checked_los) {
@@ -399,7 +461,7 @@
 				castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
 			}
 			break;
-								}
+			}
 		case SpellType_Snare: {
 			if (tar->DontSnareMeBefore() < Timer::GetCurrentTime()) {
 					if(!checked_los) {
@@ -425,7 +487,7 @@
 						tar->SetDontSnareMeBefore(TempDontSnareMeBefore);
 			}
 			break;
-							  }
+			}
 		case SpellType_DOT: {
 			if ((tar->GetHPRatio() <= 98.0f) && (tar->DontDotMeBefore() < Timer::GetCurrentTime()) && (tar->GetHPRatio() > 15.0f)) {
 				if(!checked_los) {
@@ -467,7 +529,7 @@
 				}
 			}
 			break;
-							}
+			}
 		case SpellType_Slow: {
 			if (tar->GetHPRatio() <= 99.0f) {
 					if(!checked_los) {
@@ -493,7 +555,7 @@
 					castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
 			}
 			break;
-							}
+			}
 		case SpellType_Debuff: {
 			if((tar->GetHPRatio() <= 99.0f) || ((botClass == BARD) || (botClass == SHAMAN) || (botClass == ENCHANTER) || (botClass == DRUID)) && (tar->GetHPRatio() > 25.0f))
 			{
@@ -515,33 +577,8 @@
 				castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
 			}
 			break;
-							 }
-		case SpellType_Mez: {
-			if (tar->GetBodyType() != BT_Giant) {
-					if(!checked_los) {
-						if(!CheckLosFN(tar))
-							break;	//cannot see target... we assume that no spell is going to work since we will only be casting detrimental spells in this call
-						
-						checked_los = true;
-					}
-					
-					botSpell = GetBestBotSpellForMez(this);
-
-					if(botSpell.SpellId == 0)
-						break;
-
-					Mob* addMob = GetFirstIncomingMobToMez(this, botSpell);
-
-					if(!addMob)
-						break;
-
-					if(!(!addMob->IsImmuneToSpell(botSpell.SpellId, this) && addMob->CanBuffStack(botSpell.SpellId, botLevel, true) >= 0))
-						break;
-					
-					castedSpell = AIDoSpellCast(botSpell.SpellIndex, addMob, botSpell.ManaCost);
 			}
-			break;
-							}
+		
 		default: {
 			break;
 					  }
@@ -722,6 +759,8 @@
 
 		mlog(AI__SPELLS, "Engaged autocast check triggered (BOTS). Trying to cast healing spells then maybe offensive spells.");
 
+
+
 		if(botClass == CLERIC) {
 			if(!AICastSpell(this, 100, SpellType_Heal)) {
 				if(!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
@@ -1311,7 +1350,7 @@
 
 		std::list<NPC*> npc_list;
 		entity_list.GetNPCList(npc_list);
-
+		
 		for(std::list<NPC*>::iterator itr = npc_list.begin(); itr != npc_list.end(); itr++) {
 			NPC* npc = *itr;
 
Index: mob.cpp
===================================================================
--- mob.cpp	(revision 1958)
+++ mob.cpp	(working copy)
@@ -672,6 +672,53 @@
 	}
 }
 
+uint8 Mob::GetArchetype() const {
+	switch(class_)
+	{
+	case PALADIN:
+	case RANGER:
+	case SHADOWKNIGHT:
+	case BARD:
+	case BEASTLORD:
+	case PALADINGM:
+	case RANGERGM:
+	case SHADOWKNIGHTGM:
+	case BARDGM:
+	case BEASTLORDGM:
+		return ARCHETYPE_HYBRID;
+		break;
+	case CLERIC:
+	case DRUID:
+	case SHAMAN:
+	case NECROMANCER:
+	case WIZARD:
+	case MAGICIAN:
+	case ENCHANTER:
+	case CLERICGM:
+	case DRUIDGM:
+	case SHAMANGM:
+	case NECROMANCERGM:
+	case WIZARDGM:
+	case MAGICIANGM:
+	case ENCHANTERGM:
+		return ARCHETYPE_CASTER;
+		break;
+	case WARRIOR:
+	case MONK:
+	case ROGUE:
+	case BERSERKER:
+	case WARRIORGM:
+	case MONKGM:
+	case ROGUEGM:
+	case BERSERKERGM:
+		return ARCHETYPE_MELEE;
+		break;
+	default:
+		return ARCHETYPE_HYBRID;
+		break;
+	}
+}
+
 void Mob::CreateSpawnPacket(EQApplicationPacket* app, Mob* ForWho) {
 	app->SetOpcode(OP_NewSpawn);
 	app->size = sizeof(NewSpawn_Struct);
Index: mob.h
===================================================================
--- mob.h	(revision 1958)
+++ mob.h	(working copy)
@@ -52,6 +52,18 @@
 #define CON_YELLOW		15
 #define CON_RED			13
 
+#define APPEAR_HEIGHT	0x001d
+#define	APPEAR_HP_TIC	0x0011
+ 
+#define ARCHETYPE_HYBRID	1
+#define ARCHETYPE_CASTER	2
+#define ARCHETYPE_MELEE		3
+
+#define CON_GREEN		2
+#define CON_LIGHTBLUE	18
+#define CON_BLUE		4
+
+
 //LOS Parameters:
 #define HEAD_POSITION 0.9f	//ratio of GetSize() where NPCs see from
 #define SEE_POSITION 0.5f	//ratio of GetSize() where NPCs try to see for LOS
@@ -669,9 +681,10 @@
 	void			SetZone(int32 zone_id, int32 instance_id);
 
 	// neotokyo: moved from client to use in NPC too
-	char GetCasterClass() const;
-	virtual sint32 CalcMaxMana();
-
+ 	char GetCasterClass() const;
+	uint8 GetArchetype() const;
+ 	virtual sint32 CalcMaxMana();
+ 
 	inline virtual sint16	GetAC()		const { return AC + itembonuses.AC + spellbonuses.AC; } // Quagmire - this is NOT the right math
 	inline virtual sint16	GetATK()	const { return ATK + itembonuses.ATK + spellbonuses.ATK; }
 	inline virtual sint16	GetATKBonus()	const { return itembonuses.ATK + spellbonuses.ATK; }
Criimson
Reply With Quote