2 CHARACTER(alchemist
, humanoid
)
5 virtual void GetAICommand ();
6 int GetSpellAPCost () const;
14 void alchemist::GetAICommand () {
15 SeekLeader(GetLeader());
16 if (FollowLeader(GetLeader())) return;
18 character
*NearestEnemy
= 0;
19 sLong NearestEnemyDistance
= 0x7FFFFFFF;
22 for (int c
= 0; c
< game::GetTeams(); ++c
) {
23 if (GetTeam()->GetRelation(game::GetTeam(c
)) == HOSTILE
) {
24 for (std::list
<character
*>::const_iterator i
= game::GetTeam(c
)->GetMember().begin(); i
!= game::GetTeam(c
)->GetMember().end(); ++i
) {
25 if ((*i
)->IsEnabled()) {
26 sLong ThisDistance
= Max
<sLong
>(abs((*i
)->GetPos().X
- Pos
.X
), abs((*i
)->GetPos().Y
-Pos
.Y
));
28 if ((ThisDistance
< NearestEnemyDistance
|| (ThisDistance
== NearestEnemyDistance
&& !(RAND()%3))) && (*i
)->CanBeSeenBy(this)) {
30 NearestEnemyDistance
= ThisDistance
;
37 truth Interrupt
= false;
38 // here we insert code for the alchemy
39 if (NearestEnemy
&& !StateIsActivated(CONFUSED
) && !(RAND()%2)) {
40 if (NearestEnemy
->IsHumanoid()) {
43 CONST_S("killed by the spells of ") + GetName(INDEFINITE
),
47 lsquare
*Square
= NearestEnemy
->GetLSquareUnder();
48 EditAP(-GetSpellAPCost());
49 if (CanBeSeenByPlayer()) ADD_MESSAGE("%s invokes a spell!", CHAR_NAME(DEFINITE
));
50 Square
->DrawParticles(RED
);
51 Square
->SoftenMaterial(Beam
);
55 if (CanBeSeenByPlayer()) {
56 NearestEnemy
->DeActivateVoluntaryAction(CONST_S("The spell of ")+GetName(DEFINITE
)+CONST_S(" interrupts you."));
58 NearestEnemy
->DeActivateVoluntaryAction(CONST_S("The spell interrupts you."));
64 truth Changed = false;
67 int BodyPartToHit = NearestEnemy->GetRandomBodyPart();
69 switch(BodyPartToHit) // okay, this is broken because it seg-faults, it needs to be replaced by a BEAM, in lsquare.cpp, as per mage: LowerEnchantment(), say
72 MainArmor = NearestEnemy->GetEquipment(BODY_ARMOR_INDEX);
75 MainArmor = NearestEnemy->GetEquipment(HELMET_INDEX);
78 MainArmor = NearestEnemy->GetEquipment(RIGHT_GAUNTLET_INDEX);
81 MainArmor = NearestEnemy->GetEquipment(LEFT_GAUNTLET_INDEX);
84 MainArmor = NearestEnemy->GetEquipment(BELT_INDEX);
87 MainArmor = NearestEnemy->GetEquipment(RIGHT_BOOT_INDEX);
90 MainArmor = NearestEnemy->GetEquipment(LEFT_BOOT_INDEX);
100 MainArmor->AddName(Desc, UNARTICLED);
102 if((MainArmor->GetMainMaterial()->GetCategoryFlags() & IS_METAL) && (MainArmor->GetMainMaterial()->GetConfig() != TIN))
104 MainArmor->ChangeMainMaterial(MAKE_MATERIAL(TIN));
108 else if((MainArmor->GetMainMaterial()->GetCategoryFlags() & CAN_BE_TAILORED) && (MainArmor->GetMainMaterial()->GetConfig() != CLOTH))
110 MainArmor->ChangeMainMaterial(MAKE_MATERIAL(CLOTH));
115 if(Changed && NearestEnemy->IsPlayer())
117 ADD_MESSAGE("Your %s softens into %s!", Desc.CStr(), MainArmor->GetMainMaterial()->GetName(false, false).CStr());
120 ADD_MESSAGE("%s's %s softens into %s!", NearestEnemy->CHAR_DESCRIPTION(DEFINITE), Desc.CStr(), MainArmor->GetMainMaterial()->GetName(false, false).CStr());
122 if(!Changed) //may not need this message
123 if(NearestEnemy->IsPlayer())
125 ADD_MESSAGE("Your %s vibrates slightly but remains unchanged.", MainArmor->CHAR_NAME(UNARTICLED) );
128 ADD_MESSAGE("%s's %s vibrates slightly but remains unchanged.", NearestEnemy->CHAR_DESCRIPTION(DEFINITE), MainArmor->CHAR_NAME(UNARTICLED) );
131 if (NearestEnemy
&& (NearestEnemyDistance
< 10 || StateIsActivated(PANIC
)) && (RAND()&3)) {
132 SetGoingTo((Pos
<< 1)-NearestEnemy
->GetPos());
133 if (MoveTowardsTarget(true)) return;
136 if (CheckForUsefulItemsOnGround()) return;
137 if (CheckForDoors()) return;
138 if (CheckSadism()) return;
139 if (MoveRandomly()) return;
145 int alchemist::GetSpellAPCost () const {
146 //switch (GetConfig()) {
147 // case APPRENTICE_NECROMANCER: return 2000;
148 // case MASTER_NECROMANCER: return 1000;