nonhumans separation
[k8-i-v-a-n.git] / src / game / humans / humanoid_necromancer.cpp
blobfbf90f8ae233b2763c14f9a4c9e4e012711d7fd9
1 #ifdef HEADER_PHASE
2 CHARACTER(necromancer, humanoid)
4 public:
5 virtual truth TryToRaiseZombie();
6 virtual void RaiseSkeleton();
7 protected:
8 virtual void GetAICommand();
9 int GetSpellAPCost() const;
13 #else
17 void necromancer::GetAICommand()
19 SeekLeader(GetLeader());
21 if(FollowLeader(GetLeader()))
22 return;
24 character* NearestEnemy = 0;
25 sLong NearestEnemyDistance = 0x7FFFFFFF;
26 v2 Pos = GetPos();
28 for(int c = 0; c < game::GetTeams(); ++c)
29 if(GetTeam()->GetRelation(game::GetTeam(c)) == HOSTILE)
31 for(std::list<character*>::const_iterator i = game::GetTeam(c)->GetMember().begin(); i != game::GetTeam(c)->GetMember().end(); ++i)
32 if((*i)->IsEnabled())
34 sLong ThisDistance = Max<sLong>(abs((*i)->GetPos().X - Pos.X), abs((*i)->GetPos().Y - Pos.Y));
36 if((ThisDistance < NearestEnemyDistance || (ThisDistance == NearestEnemyDistance && !(RAND() % 3))) && (*i)->CanBeSeenBy(this))
38 NearestEnemy = *i;
39 NearestEnemyDistance = ThisDistance;
44 if(NearestEnemy && NearestEnemy->GetPos().IsAdjacent(Pos))
46 if(GetConfig() == MASTER_NECROMANCER && !(RAND() & 3))
48 if(CanBeSeenByPlayer())
49 ADD_MESSAGE("%s invokes a spell and disappears.", CHAR_NAME(DEFINITE));
51 TeleportRandomly(true);
52 EditAP(-GetSpellAPCost());
53 return;
55 else if(NearestEnemy->IsSmall()
56 && GetAttribute(WISDOM) < NearestEnemy->GetAttackWisdomLimit()
57 && !(RAND() & 3)
58 && Hit(NearestEnemy, NearestEnemy->GetPos(), game::GetDirectionForVector(NearestEnemy->GetPos() - GetPos())))
59 return;
62 if(!NearestEnemy)
64 if(!RAND_N(3) && TryToRaiseZombie())
65 return;
67 else
69 if(!RAND_N(6) && TryToRaiseZombie())
70 return;
73 if(NearestEnemy && !(RAND() % (GetConfig() == APPRENTICE_NECROMANCER ? 3 : 2)))
75 lsquare* Square = NearestEnemy->GetLSquareUnder();
76 EditAP(-GetSpellAPCost());
78 if(CanBeSeenByPlayer())
79 ADD_MESSAGE("%s invokes a spell!", CHAR_NAME(DEFINITE));
81 truth Interrupt = false;
83 switch(GetConfig())
85 case APPRENTICE_NECROMANCER:
86 RaiseSkeleton();
87 break;
88 case MASTER_NECROMANCER:
89 if(RAND() % 5)
90 RaiseSkeleton();
91 else
93 Square->DrawLightning(v2(8, 8), WHITE, YOURSELF);
95 beamdata Beam
97 this,
98 CONST_S("killed by the spells of ") + GetName(INDEFINITE),
99 YOURSELF,
103 Square->Lightning(Beam);
104 Interrupt = true;
107 break;
110 if(Interrupt) {
111 if(CanBeSeenByPlayer())
112 NearestEnemy->DeActivateVoluntaryAction(CONST_S("The spell of ") + GetName(DEFINITE) + CONST_S(" interrupts you."));
113 else
114 NearestEnemy->DeActivateVoluntaryAction(CONST_S("The spell interrupts you."));
116 return;
119 if(NearestEnemy && (NearestEnemyDistance < 10 || StateIsActivated(PANIC)) && RAND() & 3)
121 SetGoingTo((Pos << 1) - NearestEnemy->GetPos());
123 if(MoveTowardsTarget(true))
124 return;
127 if(CheckForDoors())
128 return;
130 if(CheckSadism())
131 return;
133 if(MoveRandomly())
134 return;
136 EditAP(-1000);
141 truth necromancer::TryToRaiseZombie()
143 for(int c = 0; c < game::GetTeams(); ++c)
144 for(std::list<character*>::const_iterator i = game::GetTeam(c)->GetMember().begin();
145 i != game::GetTeam(c)->GetMember().end(); ++i)
146 if(!(*i)->IsEnabled() && (*i)->GetMotherEntity()
147 && (*i)->GetMotherEntity()->Exists()
148 && (GetConfig() == MASTER_NECROMANCER
149 || (*i)->GetMotherEntity()->GetSquareUnderEntity()->CanBeSeenBy(this)))
151 character* Zombie = (*i)->GetMotherEntity()->TryNecromancy(this);
153 if(Zombie)
155 if(Zombie->CanBeSeenByPlayer())
156 ADD_MESSAGE("%s calls %s back to cursed undead life.", CHAR_DESCRIPTION(DEFINITE), Zombie->CHAR_NAME(INDEFINITE));
157 else if(CanBeSeenByPlayer())
158 ADD_MESSAGE("%s casts a spell, but you notice no effect.", CHAR_NAME(DEFINITE));
160 EditAP(-GetSpellAPCost());
161 return true;
165 return false;
170 void necromancer::RaiseSkeleton()
172 /* Gum solution */
174 const database* WarLordDataBase;
175 databasecreator<character>::FindDataBase(WarLordDataBase, &skeleton::ProtoType, WAR_LORD);
176 skeleton* Skeleton;
178 if(GetConfig() == MASTER_NECROMANCER && !(WarLordDataBase->Flags & HAS_BEEN_GENERATED) && !(RAND() % 250))
180 Skeleton = skeleton::Spawn(WAR_LORD);
181 Skeleton->SetTeam(GetTeam());
182 Skeleton->PutNear(GetPos());
183 Skeleton->SignalGeneration();
185 if(Skeleton->CanBeSeenByPlayer())
186 ADD_MESSAGE("The whole area trembles terribly as %s emerges from the ground.", Skeleton->CHAR_NAME(DEFINITE));
187 else if(CanBeSeenByPlayer())
188 ADD_MESSAGE("%s casts a powerful spell which makes the whole area tremble.", CHAR_NAME(DEFINITE));
189 else
190 ADD_MESSAGE("You feel the presence of an ancient evil being awakened from its long slumber. You shiver.");
192 else
194 Skeleton = skeleton::Spawn(GetConfig() == APPRENTICE_NECROMANCER ? 0 : WARRIOR, NO_EQUIPMENT);
195 Skeleton->SetTeam(GetTeam());
196 Skeleton->PutNear(GetPos());
198 if(Skeleton->CanBeSeenByPlayer())
199 ADD_MESSAGE("The ground shakes and %s emerges from it.", Skeleton->CHAR_NAME(INDEFINITE));
200 else if(CanBeSeenByPlayer())
201 ADD_MESSAGE("%s casts a spell, but you notice no effect.", CHAR_NAME(DEFINITE));
204 Skeleton->SetGenerationDanger(GetGenerationDanger());
205 EditAP(-GetSpellAPCost());
210 int necromancer::GetSpellAPCost() const
212 switch(GetConfig())
214 case APPRENTICE_NECROMANCER: return 2000;
215 case MASTER_NECROMANCER: return 1000;
218 return 4000;
220 #endif