2 * Iter Vehemens ad Necem (IVAN)
3 * Copyright (C) Timo Kiviluoto
4 * Released under the GNU General
7 * See LICENSING which should be included
8 * along with this file for more details
41 static void cstrTrim (char *buf
) {
43 while (*p
&& *((unsigned char *)(p
)) <= ' ') p
++;
44 if (!p
[0]) { buf
[0] = '\0'; return; } /* empty line */
45 if (p
> buf
) { t
= buf
; while (*p
) *t
++ = *p
++; }
46 p
= buf
+strlen(buf
)-1;
47 while (p
>= buf
&& *((unsigned char *)(p
)) <= ' ') p
--;
48 if (p
< buf
) { buf
[0] = '\0'; return; } /* empty line */
53 command::command(truth (*LinkedFunction
)(character
*), cchar
*Description
, char Key1
, char Key2
, truth UsableInWilderness
, truth WizardModeFunction
) :
54 LinkedFunction(LinkedFunction
),
55 Description(Description
),
56 Key1(Key1
), Key2(Key2
),
57 UsableInWilderness(UsableInWilderness
),
58 WizardModeFunction(WizardModeFunction
)
63 char command::GetKey () const { return !ivanconfig::GetUseAlternativeKeys() ? Key1
: Key2
; }
66 static const char *adirNames
[9] = {
80 void commandsystem::ConfigureKeys () {
85 fname
<< ivanconfig::GetMyDir();
87 fname
<< getenv("HOME");
90 FILE *fl
= fopen(fname
.CStr(), "r");
92 while (fgets(buf
, 510, fl
)) {
94 char k1
= 0, k2
= 0, i1
;
97 } else if (buf
[2] != '=') {
98 if (buf
[1] != '=') continue;
106 for (int f
= 1; (cmd
= commandsystem::GetCommand(f
)) != 0; f
++) {
107 if (!strcmp(buf
+i1
, cmd
->GetDescription())) cmd
->SetKeys(k1
, k2
);
109 for (int f
= 0; f
<= 8; f
++) if (!strcmp(buf
+i1
, adirNames
[f
])) game::SetAbnormalMoveKey(f
, k1
);
115 void commandsystem::SaveKeys (truth forced
) {
120 fname
<< ivanconfig::GetMyDir();
122 fname
<< getenv("HOME");
124 fname
<< "/.keys.rc";
126 if (inputfile::fileExists(fname
)) return;
128 FILE *fl
= fopen(fname
.CStr(), "w");
130 for (; isWizard
< 2; isWizard
++) {
131 fputs(isWizard
? "\n# wizard actions\n" : "# actions\n", fl
);
132 for (int f
= 1; (cmd
= commandsystem::GetCommand(f
)) != 0; f
++) {
133 if (cmd
->IsWizardModeFunction()) {
134 if (!isWizard
) continue;
136 if (isWizard
) continue;
138 cchar
*dsc
= cmd
->GetDescription();
139 char k1
= cmd
->GetKey1(), k2
= cmd
->GetKey2();
140 if (!dsc
|| !dsc
[0]) continue;
141 if (k1
&& k2
&& k1
!= k2
) fprintf(fl
, "%c%c", k1
, k2
);
142 else if (k1
) fprintf(fl
, "%c", k1
);
143 else if (k2
) fprintf(fl
, "%c", k2
);
144 fprintf(fl
, "=%s\n", dsc
);
147 fputs("\n# alternate movement\n", fl
);
148 for (int f
= 0; f
<= 8; f
++) {
149 char ch
= game::GetAbnormalMoveKey(f
);
150 if (ch
) fputc(ch
, fl
);
151 fprintf(fl
, "=%s\n", adirNames
[f
]);
158 command
*commandsystem::Command
[] = {
160 /* Sort according to description */
161 new command(&Apply
, "apply", 'a', 'a', false),
162 new command(&Talk
, "chat", 'C', 'C', false),
163 new command(&Close
, "close", 'c', 'c', false),
164 new command(&Dip
, "dip", '!', '!', false),
165 new command(&Dump
, "dump potion/can contents", 'U', 'U', false),
166 new command(&Drink
, "drink", 'D', 'D', true),
167 new command(&Drop
, "drop", 'd', 'd', true),
168 new command(&Eat
, "eat", 'e', 'e', true),
169 new command(&WhatToEngrave
, "engrave", 'G', 'G', false),
170 new command(&EquipmentScreen
, "equipment menu", 'E', 'E', true),
171 new command(&Go
, "go", 'g', 'g', false),
172 new command(&GoDown
, "go down/enter area", '>', '>', true),
173 new command(&GoUp
, "go up", '<', '<', true),
174 new command(&IssueCommand
, "issue command(s) to team member(s)", 'I', 'I', false),
175 new command(&Kick
, "kick", 'k', 'K', false),
176 new command(&Look
, "look", 'l', 'L', true),
177 new command(&AssignName
, "name", 'n', 'n', false),
178 new command(&Offer
, "offer", 'O', 'f', false),
179 new command(&Open
, "open", 'o', 'O', false),
180 new command(&PickUp
, "pick up", ',', ',', false),
181 new command(&Pray
, "pray", 'p', 'p', false),
182 new command(&Quit
, "quit", 'Q', 'Q', true),
183 new command(&Read
, "read", 'r', 'r', false),
184 new command(&Rest
, "rest/heal", 'h', 'h', true),
185 new command(&Save
, "save game", 'S', 'S', true),
186 new command(&ScrollMessagesDown
, "scroll messages down", '+', '+', true),
187 new command(&ScrollMessagesUp
, "scroll messages up", '-', '-', true),
188 new command(&ShowConfigScreen
, "show config screen", '\\', '\\', true),
189 new command(&ShowInventory
, "show inventory", 'i', 'i', true),
190 new command(&ShowKeyLayout
, "show key layout", '?', '?', true),
191 new command(&DrawMessageHistory
, "show message history", 'M', 'M', true),
192 new command(&ShowWeaponSkills
, "show weapon skills", '@', '@', true),
193 new command(&Search
, "search", 's', 's', false),
194 new command(&Sit
, "sit", '_', '_', false),
195 new command(&Throw
, "throw", 't', 't', false),
196 new command(&ToggleRunning
, "toggle running", 'u', 'U', true),
197 new command(&ForceVomit
, "vomit", 'V', 'V', false),
198 new command(&NOP
, "wait", '.', '.', true),
199 new command(&WieldInRightArm
, "wield in right arm", 'w', 'w', true),
200 new command(&WieldInLeftArm
, "wield in left arm", 'W', 'W', true),
201 new command(&Burn
, "burn", 'B', 'B', false),
203 new command(&WizardMode
, "wizard mode activation", 'X', 'X', true),
205 new command(&Zap
, "zap", 'z', 'z', false),
207 /* Sort according to key */
208 new command(&RaiseStats
, "raise stats", '1', '1', true, true),
209 new command(&LowerStats
, "lower stats", '2', '2', true, true),
210 new command(&SeeWholeMap
, "see whole map", '3', '3', true, true),
211 new command(&WalkThroughWalls
, "toggle walk through walls mode", '4', '4', true, true),
212 new command(&RaiseGodRelations
, "raise your relations to the gods", '5', '5', true, true),
213 new command(&LowerGodRelations
, "lower your relations to the gods", '6', '6', true, true),
214 new command(&WizardWish
, "wish something", '=', '=', true, true),
215 new command(&GainDivineKnowledge
, "gain knowledge of all gods", '\"', '\"', true, true),
216 new command(&GainAllItems
, "gain all items", '$', '$', true, true),
217 new command(&SecretKnowledge
, "reveal secret knowledge", '*', '*', true, true),
218 new command(&DetachBodyPart
, "detach a limb", '0', '0', true, true),
219 new command(&SummonMonster
, "summon monster", '&', '&', false, true),
220 new command(&LevelTeleport
, "level teleport", '|', '|', false, true),
221 new command(&Possess
, "possess creature", '{', '{', false, true),
222 new command(&Polymorph
, "polymorph", '[', '[', true, true),
223 new command(&GetScroll
, "get scroll", 'R', 'R', true, true),
224 new command(&OpenMondedr
, "open Mondedr", 'm', 'm', true, true),
225 new command(&ShowCoords
, "show current coordinates", '(', '(', true, true),
226 new command(&WizardHeal
, "wizard healing", 'H', 'H', true, true),
232 truth
commandsystem::GoUp (character
*Char
) {
233 if (!Char
->TryToUnStickTraps(ZERO_V2
)) return false;
234 /*if(!game::IsInWilderness() && game::WizardModeIsActive() && game::GetCurrentLevelIndex() >= 1)
235 if(game::TryTravel(game::GetCurrentDungeonIndex(), game::GetCurrentLevelIndex() - 1, RANDOM, true))
237 oterrain
*Terrain
= Char
->GetSquareUnder()->GetOTerrain();
239 if (game::IsInWilderness()) {
240 if (!Char
->IsFlying()) ADD_MESSAGE("You jump into the air. For some reason you don't get too far above.");
241 else ADD_MESSAGE("You fly around for some time.");
242 } else ADD_MESSAGE("You can't go up.");
245 if (Terrain
->Enter(true)) {
246 Char
->EditExperience(LEG_STRENGTH
, 150, 1<<6);
248 Char
->EditAP(-100000/APBonus(Char
->GetAttribute(AGILITY
)));
255 truth
commandsystem::GoDown (character
*Char
) {
256 if (!Char
->TryToUnStickTraps(ZERO_V2
)) return false;
257 /*if(!game::IsInWilderness() && game::WizardModeIsActive() && game::GetCurrentLevelIndex() < game::GetLevels() - 1)
258 if(game::TryTravel(game::GetCurrentDungeonIndex(), game::GetCurrentLevelIndex() + 1, RANDOM, true))
260 oterrain
*Terrain
= Char
->GetSquareUnder()->GetOTerrain();
262 if (game::IsInWilderness()) ADD_MESSAGE("There seems to be nothing of interest here.");
263 else ADD_MESSAGE("You can't go down.");
266 if (Terrain
->Enter(false)) {
267 Char
->EditExperience(AGILITY
, 150, 1<<6);
269 Char
->EditAP(-100000/APBonus(Char
->GetAttribute(AGILITY
)));
276 truth
commandsystem::Open (character
*Char
) {
277 if (Char
->CanOpen()) {
279 truth OpenableItems
= Char
->GetStack()->SortedItems(Char
, &item::IsOpenable
);
282 Key
= game::AskForKeyPress(CONST_S("What do you wish to open? [press a direction key, space or i]"));
284 Key
= game::AskForKeyPress(CONST_S("What do you wish to open? [press a direction key or space]"));
287 if (OpenableItems
&& (Key
== 'i' || Key
== 'I')) {
288 item
*Item
= Char
->GetStack()->DrawContents(Char
, CONST_S("What do you want to open?"), 0, &item::IsOpenable
);
289 return Item
&& Item
->Open(Char
);
291 v2 DirVect
= game::GetDirectionVectorForKey(Key
);
292 if (DirVect
!= ERROR_V2
&& Char
->GetArea()->IsValidPos(Char
->GetPos()+DirVect
)) return Char
->GetNearLSquare(Char
->GetPos()+DirVect
)->Open(Char
);
294 ADD_MESSAGE("This monster type cannot open anything.");
300 truth
commandsystem::Close (character
*Char
) {
301 if (Char
->CanOpen()) {
302 int Dir
= game::DirectionQuestion(CONST_S("What do you wish to close? [press a direction key]"), false);
303 if (Dir
!= DIR_ERROR
&& Char
->GetArea()->IsValidPos(Char
->GetPos()+game::GetMoveVector(Dir
)))
304 return Char
->GetNearLSquare(Char
->GetPos()+game::GetMoveVector(Dir
))->Close(Char
);
306 ADD_MESSAGE("This monster type cannot close anything.");
312 truth
commandsystem::Drop (character
*Char
) {
313 if (!Char
->GetStack()->GetItems()) {
314 ADD_MESSAGE("You have nothing to drop!");
317 truth Success
= false;
318 stack::SetSelected(0);
321 game::DrawEverythingNoBlit();
322 Char
->GetStack()->DrawContents(ToDrop
, Char
, CONST_S("What do you want to drop?"), REMEMBER_SELECTED
);
323 if (ToDrop
.empty()) break;
324 if (game::IsInWilderness()) {
325 for (uInt c
= 0; c
< ToDrop
.size(); ++c
) {
326 if (game::TruthQuestion(CONST_S("Are you sure? You will never see ")+ToDrop
[c
]->CHAR_NAME(DEFINITE
)+" again! [y/N]")) {
327 ADD_MESSAGE("You drop %s.", ToDrop
[c
]->CHAR_NAME(DEFINITE
));
328 ToDrop
[c
]->RemoveFromSlot();
329 ToDrop
[c
]->SendToHell();
332 } else if (!Char
->GetRoom() || Char
->GetRoom()->DropItem(Char
, ToDrop
[0], ToDrop
.size())) {
333 ADD_MESSAGE("%s dropped.", ToDrop
[0]->GetName(INDEFINITE
, ToDrop
.size()).CStr());
334 for (uInt c
= 0; c
< ToDrop
.size(); ++c
) ToDrop
[c
]->MoveTo(Char
->GetStackUnder());
339 Char
->DexterityAction(2);
346 truth
commandsystem::Eat (character
*Char
) {
347 if (!Char
->CheckConsume(CONST_S("eat"))) return false;
348 lsquare
*Square
= Char
->GetLSquareUnder();
349 if (!game::IsInWilderness() && Square
->GetOLTerrain() && Square
->GetOLTerrain()->HasEatEffect()) {
350 if (Square
->GetOLTerrain()->Eat(Char
)) return true;
352 return Consume(Char
, "eat", &item::IsEatable
);
356 truth
commandsystem::Drink (character
*Char
) {
357 if (!Char
->CheckConsume(CONST_S("drink"))) return false;
358 lsquare
*Square
= Char
->GetLSquareUnder();
359 if (!game::IsInWilderness() && Square
->GetOLTerrain() && Square
->GetOLTerrain()->HasDrinkEffect()) {
360 if (Square
->GetOLTerrain()->Drink(Char
)) return true;
362 return Consume(Char
, "drink", &item::IsDrinkable
);
366 truth
commandsystem::Consume (character
* Char
, cchar
*ConsumeVerb
, sorter Sorter
) {
367 lsquare
*Square
= Char
->GetLSquareUnder();
368 stack
*Inventory
= Char
->GetStack();
369 stack
*StackUnder
= Square
->GetStack();
370 if ((game::IsInWilderness() || !StackUnder
->SortedItems(Char
, Sorter
)) && !Inventory
->SortedItems(Char
, Sorter
)) {
371 ADD_MESSAGE("You have nothing to %s!", ConsumeVerb
);
375 festring Question
= CONST_S("What do you wish to ")+ConsumeVerb
+'?';
376 if (!game::IsInWilderness() && StackUnder
->SortedItems(Char
, Sorter
))
377 Inventory
->DrawContents(Item
, StackUnder
, Char
, Question
, CONST_S("Items in your inventory"), CONST_S("Items on the ground"), CONST_S(""), 0, NO_MULTI_SELECT
, Sorter
);
379 Inventory
->DrawContents(Item
, Char
, Question
, NO_MULTI_SELECT
, Sorter
);
380 return !Item
.empty() ? Char
->ConsumeItem(Item
[0], ConsumeVerb
+CONST_S("ing")) : false;
384 truth
commandsystem::ShowInventory (character
*Char
) {
385 festring
Title("Your inventory (total weight: ");
386 Title
<< Char
->GetStack()->GetWeight();
388 Char
->GetStack()->DrawContents(Char
, Title
, NO_SELECT
);
393 truth
commandsystem::PickUp (character
*Char
) {
394 if (!Char
->GetStackUnder()->GetVisibleItems(Char
)) {
395 ADD_MESSAGE("There is nothing here to pick up!");
398 itemvectorvector PileVector
;
399 Char
->GetStackUnder()->Pile(PileVector
, Char
, CENTER
);
400 for (int c
= 0; c
< 4; ++c
) {
401 stack
*Stack
= Char
->GetLSquareUnder()->GetStackOfAdjacentSquare(c
);
402 if (Stack
) Stack
->Pile(PileVector
, Char
, 3-c
);
404 if (PileVector
.size() == 1) {
405 if (PileVector
[0][0]->CanBePickedUp()) {
406 int Amount
= PileVector
[0].size();
407 if (Amount
> 1) Amount
= game::ScrollBarQuestion(CONST_S("How many ")+PileVector
[0][0]->GetName(PLURAL
)+'?', Amount
, 1, 0, Amount
, 0, WHITE
, LIGHT_GRAY
, DARK_GRAY
);
408 if (!Amount
) return false;
409 if ((!PileVector
[0][0]->GetRoom() ||
410 PileVector
[0][0]->GetRoom()->PickupItem(Char
, PileVector
[0][0], Amount
)) &&
411 PileVector
[0][0]->CheckPickUpEffect(Char
)) {
412 if (PileVector
[0][0]->IsCorpse() && ivanconfig::GetConfirmCorpses()) {
413 //if (!game::TruthQuestion(CONST_S("Do you really want to pick up the corpse? [y/N]"))) return false;
415 game::DrawEverythingNoBlit();
416 Char
->GetStackUnder()->DrawContents(ToPickup
, Char
, CONST_S("Do you really want to pick up the corpse?"), REMEMBER_SELECTED
);
417 if (ToPickup
.empty()) return false;
419 for (int c
= 0; c
< Amount
; ++c
) PileVector
[0][c
]->MoveTo(Char
->GetStack());
420 ADD_MESSAGE("%s picked up.", PileVector
[0][0]->GetName(INDEFINITE
, Amount
).CStr());
421 Char
->DexterityAction(2);
426 ADD_MESSAGE("%s too large to pick up!", PileVector
[0].size() == 1 ? "It is" : "They are");
430 truth Success
= false;
431 stack::SetSelected(0);
434 game::DrawEverythingNoBlit();
435 Char
->GetStackUnder()->DrawContents(ToPickup
, Char
, CONST_S("What do you want to pick up?"), REMEMBER_SELECTED
);
436 if (ToPickup
.empty()) break;
437 if (ToPickup
[0]->CanBePickedUp()) {
438 if ((!ToPickup
[0]->GetRoom() || ToPickup
[0]->GetRoom()->PickupItem(Char
, ToPickup
[0], ToPickup
.size())) &&
439 ToPickup
[0]->CheckPickUpEffect(Char
)) {
440 for (uInt c
= 0; c
< ToPickup
.size(); ++c
) ToPickup
[c
]->MoveTo(Char
->GetStack());
441 ADD_MESSAGE("%s picked up.", ToPickup
[0]->GetName(INDEFINITE
, ToPickup
.size()).CStr());
444 } else ADD_MESSAGE("%s too large to pick up!", ToPickup
.size() == 1 ? "It is" : "They are");
447 Char
->DexterityAction(2);
454 truth
commandsystem::Quit (character
*Char
) {
455 if (game::TruthQuestion(CONST_S("Your quest is not yet compeleted! Really quit? [y/N]"))) {
456 Char
->ShowAdventureInfo();
457 festring Msg
= CONST_S("cowardly quit the game");
458 Char
->AddScoreEntry(Msg
, 0.75);
459 game::End(Msg
, !game::WizardModeIsActive() || game::TruthQuestion(CONST_S("Remove saves? [y/N]")));
466 truth
commandsystem::Talk (character
*Char
) {
467 if (!Char
->CheckTalk()) return false;
468 character
*ToTalk
= 0;
470 for (int d
= 0; d
< 8; ++d
) {
471 lsquare
*Square
= Char
->GetNaturalNeighbourLSquare(d
);
473 character
*Dude
= Square
->GetCharacter();
481 ADD_MESSAGE("Find yourself someone to talk to first!");
484 if (Characters
== 1) return ToTalk
->ChatMenu();
485 int Dir
= game::DirectionQuestion(CONST_S("To whom do you wish to talk to? [press a direction key]"), false, true);
486 if (Dir
== DIR_ERROR
|| !Char
->GetArea()->IsValidPos(Char
->GetPos()+game::GetMoveVector(Dir
))) return false;
487 character
*Dude
= Char
->GetNearSquare(Char
->GetPos()+game::GetMoveVector(Dir
))->GetCharacter();
489 ADD_MESSAGE("You talk to yourself for some time.");
490 Char
->EditExperience(WISDOM
, -50, 1<<7);
494 if (Dude
) return Dude
->ChatMenu();
495 ADD_MESSAGE("You get no response.");
500 truth
commandsystem::NOP (character
*Char
) {
501 Char
->EditExperience(DEXTERITY
, -25, 1<<3);
502 Char
->EditExperience(AGILITY
, -25, 1<<3);
503 Char
->EditAP(-Char
->GetStateAPGain(1000));
508 truth
commandsystem::Save (character
*) {
509 if (game::TruthQuestion(CONST_S("Do you truly wish to save and flee? [y/N]"))) {
511 if (game::WizardModeIsActive()) {
512 if (!game::TruthQuestion(CONST_S("Do you want to exit, cheater? [y/N]"))) return false;
514 game::End("", false);
521 truth
commandsystem::Read (character
*Char
) {
522 if (!Char
->CanRead() && !game::GetSeeWholeMapCheatMode()) {
523 ADD_MESSAGE("You can't read.");
526 if (!Char
->GetStack()->SortedItems(Char
, &item::IsReadable
)) {
527 ADD_MESSAGE("You have nothing to read!");
530 if (Char
->GetLSquareUnder()->IsDark() && !game::GetSeeWholeMapCheatMode()) {
531 ADD_MESSAGE("It is too dark to read.");
534 item
*Item
= Char
->GetStack()->DrawContents(Char
, CONST_S("What do you want to read?"), 0, &item::IsReadable
);
536 if (ivanconfig::GetConfirmScrollReading() && Item
->IsScroll()) {
537 if (!game::TruthQuestion(festring("Do you really want to read ")+Item
->CHAR_NAME(DEFINITE
)+"? [y/n]")) return false;
539 return Char
->ReadItem(Item
);
545 truth
commandsystem::Dip (character
*Char
) {
546 if (!Char
->GetStack()->SortedItems(Char
, &item::IsDippable
) && !Char
->EquipsSomething(&item::IsDippable
)) {
547 ADD_MESSAGE("You have nothing to dip!");
550 truth HasDipDestination
= Char
->PossessesItem(&item::IsDipDestination
);
551 truth DipDestinationNear
= false;
552 for (int d
= 0; d
< 9; ++d
) {
553 lsquare
*Square
= Char
->GetNaturalNeighbourLSquare(d
);
554 if (Square
&& Square
->IsDipDestination()) DipDestinationNear
= true;
556 if (!HasDipDestination
&& !DipDestinationNear
) {
557 ADD_MESSAGE("There is nothing to dip anything into.");
560 item
*Item
= Char
->SelectFromPossessions(CONST_S("What do you want to dip?"), &item::IsDippable
);
562 if (!HasDipDestination
|| (DipDestinationNear
&& game::TruthQuestion(CONST_S("Do you wish to dip in a nearby square? [y/N]")))) {
563 int Dir
= game::DirectionQuestion(CONST_S("Where do you want to dip ")+Item
->GetName(DEFINITE
)+"? [press a direction key or '.']", false, true);
564 v2 Pos
= Char
->GetPos()+game::GetMoveVector(Dir
);
565 if (Dir
== DIR_ERROR
|| !Char
->GetArea()->IsValidPos(Pos
) || !Char
->GetNearLSquare(Pos
)->IsDipDestination()) return false;
566 return Char
->GetNearLSquare(Pos
)->DipInto(Item
, Char
);
568 item
*DipTo
= Char
->SelectFromPossessions(CONST_S("Into what do you wish to dip it?"), &item::IsDipDestination
);
571 ADD_MESSAGE("Very funny...");
574 //fprintf(stderr, "BSM: %p\n", DipTo->GetSecondaryMaterial());
575 Item
->DipInto(DipTo
->CreateDipLiquid(), Char
);
576 //fprintf(stderr, "ASM: %p\n", DipTo->GetSecondaryMaterial());
577 if (!game::IsInWilderness() && !DipTo
->GetSecondaryMaterial()) {
578 // container is empty
579 if ((DipTo
->IsBottle() && ivanconfig::GetAutoDropBottles()) ||
580 (DipTo
->IsCan() && ivanconfig::GetAutoDropCans())) {
582 if (!Char
->GetRoom() || Char
->GetRoom()->DropItem(Char
, DipTo
, 1)) {
583 ADD_MESSAGE("%s dropped.", DipTo
->GetName(INDEFINITE
, 1).CStr());
584 DipTo
->MoveTo(Char
->GetStackUnder());
585 Char
->DexterityAction(2);
596 truth
commandsystem::ShowKeyLayout (character
*) {
597 felist
List(CONST_S("Keyboard Layout"));
598 List
.AddDescription(CONST_S(""));
599 List
.AddDescription(CONST_S("Key Description"));
601 for (int c
= 1; GetCommand(c
); ++c
) {
602 if (!GetCommand(c
)->IsWizardModeFunction()) {
604 Buffer
<< GetCommand(c
)->GetKey();
606 List
.AddEntry(Buffer
+GetCommand(c
)->GetDescription(), LIGHT_GRAY
);
609 if (game::WizardModeIsActive()) {
610 List
.AddEntry(CONST_S(""), WHITE
);
611 List
.AddEntry(CONST_S("Wizard mode functions:"), WHITE
);
612 List
.AddEntry(CONST_S(""), WHITE
);
613 for (int c
= 1; GetCommand(c
); ++c
) {
614 if (GetCommand(c
)->IsWizardModeFunction()) {
616 Buffer
<< GetCommand(c
)->GetKey();
618 List
.AddEntry(Buffer
+GetCommand(c
)->GetDescription(), LIGHT_GRAY
);
622 game::SetStandardListAttributes(List
);
628 truth
commandsystem::Look (character
*Char
) {
630 if (!game::IsInWilderness()) Char
->GetLevel()->AddSpecialCursors();
631 if (!game::IsInWilderness())
632 Msg
= CONST_S("Direction keys move cursor, ESC exits, 'i' examines items, 'c' examines a character.");
634 Msg
= CONST_S("Direction keys move cursor, ESC exits, 'c' examines a character.");
635 game::PositionQuestion(Msg
, Char
->GetPos(), &game::LookHandler
, &game::LookKeyHandler
, ivanconfig::GetLookZoom());
636 game::RemoveSpecialCursors();
641 truth
commandsystem::WhatToEngrave (character
*Char
) {
642 if (!Char
->CanRead()) {
643 ADD_MESSAGE("You can't even read.");
646 Char
->GetNearLSquare(Char
->GetPos())->Engrave(game::StringQuestion(CONST_S("What do you want to engrave here?"), WHITE
, 0, 80, true));
651 truth
commandsystem::Pray (character
*Char
) {
652 felist
Panthenon(CONST_S("To Whom you want to address your prayers?"));
653 Panthenon
.SetEntryDrawer(game::GodEntryDrawer
);
656 int DivineMaster
= Char
->GetLSquareUnder()->GetDivineMaster();
657 if (DivineMaster
== ATHEIST
) {
658 ADD_MESSAGE("Somehow you feel that no god will help you here.");
662 for (int c
= 1; c
<= GODS
; ++c
) {
663 if (game::GetGod(c
)->IsKnown()) {
664 Panthenon
.AddEntry(game::GetGod(c
)->GetCompleteDescription(), LIGHT_GRAY
, 20, c
);
668 } else if (game::GetGod(DivineMaster
)->IsKnown()) {
669 Panthenon
.AddEntry(game::GetGod(DivineMaster
)->GetCompleteDescription(), LIGHT_GRAY
, 20, DivineMaster
);
670 Known
[0] = DivineMaster
;
672 ADD_MESSAGE("Somehow you feel that no deity you know can hear your prayers from this place.");
675 game::SetStandardListAttributes(Panthenon
);
676 Panthenon
.AddFlags(SELECTABLE
);
677 int Select
= Panthenon
.Draw();
678 if (Select
== LIST_WAS_EMPTY
) {
679 ADD_MESSAGE("You do not know any gods.");
682 if (Select
& FELIST_ERROR_BIT
) return false;
683 if (Char
->GetLSquareUnder()->GetDivineMaster()) {
685 if (game::TruthQuestion(CONST_S("Do you really wish to pray to ")+game::GetGod(Char
->GetLSquareUnder()->GetDivineMaster())->GetName()+"? [y/N]"))
686 game::GetGod(Char
->GetLSquareUnder()->GetDivineMaster())->Pray();
691 if (game::TruthQuestion(CONST_S("Do you really wish to pray to ")+game::GetGod(Known
[Select
])->GetName()+"? [y/N]")) {
692 if (Char
->StateIsActivated(CONFUSED
) && !(RAND() & 7)) {
694 for (Index
= 1+RAND()%GODS
; Index
== Known
[Select
]; Index
= 1+RAND()%GODS
);
695 if (game::GetGod(Index
)->IsKnown())
696 ADD_MESSAGE("You feel something went wrong in the rituals. You have accidentally prayed to %s!", game::GetGod(Index
)->GetName());
698 ADD_MESSAGE("Your rituals were seriously incorrect. You have accidentally prayed to an unknown god, but have no idea how!");
699 game::GetGod(Index
)->Pray();
701 game::GetGod(Known
[Select
])->Pray();
712 truth
commandsystem::Kick (character
*Char
) {
713 /** No multi-tile support */
714 if (!Char
->CheckKick()) return false;
715 if (Char
->GetBurdenState() == OVER_LOADED
) {
716 ADD_MESSAGE("You try to kick, but you collapse under your load.");
717 Char
->EditAP(-100000/APBonus(Char
->GetAttribute(AGILITY
)));
720 int Dir
= game::DirectionQuestion(CONST_S("In what direction do you wish to kick? [press a direction key]"), false);
721 if (Dir
== DIR_ERROR
|| !Char
->GetArea()->IsValidPos(Char
->GetPos()+game::GetMoveVector(Dir
))) return false;
722 lsquare
*Square
= Char
->GetNearLSquare(Char
->GetPos()+game::GetMoveVector(Dir
));
723 if (!Square
->CheckKick(Char
)) return false;
724 character
*Enemy
= Square
->GetCharacter();
725 if (Enemy
&& !(Enemy
->IsMasochist() && Char
->GetRelation(Enemy
) == FRIEND
) && Char
->GetRelation(Enemy
) != HOSTILE
) {
726 if (!game::TruthQuestion(CONST_S("This might cause a hostile reaction. Are you sure? [y/N]"))) return false;
728 game::ClearEventData();
729 game::mActor
= Square
->GetCharacter();
730 game::mSecondActor
= Char
;
731 if (game::RunOnCharEvent(Char
, CONST_S("before_kick"))) { game::ClearEventData(); return game::mResult
!= 0; }
732 game::ClearEventData();
734 game::mSecondActor
= Square
->GetCharacter();
735 if (game::RunOnCharEvent(Square
->GetCharacter(), CONST_S("before_kicked_by"))) { game::ClearEventData(); return game::mResult
!= 0; }
736 game::ClearEventData();
737 Char
->Hostility(Square
->GetCharacter());
738 Char
->Kick(Square
, Dir
);
743 truth
commandsystem::Offer (character
*Char
) {
744 if (!Char
->CheckOffer()) return false;
745 lsquare
*Square
= Char
->GetLSquareUnder();
746 if (Square
->GetOLTerrain() && Square
->GetOLTerrain()->AcceptsOffers()) {
747 if (!Char
->GetStack()->GetItems()) {
748 ADD_MESSAGE("You have nothing to offer!");
751 item
*Item
= Char
->GetStack()->DrawContents(Char
, CONST_S("What do you want to offer?"));
753 if (game::GetGod(Square
->GetDivineMaster())->ReceiveOffer(Item
)) {
754 Item
->RemoveFromSlot();
756 Char
->DexterityAction(5); /** C **/
763 ADD_MESSAGE("There isn't any altar here!");
768 truth
commandsystem::DrawMessageHistory (character
*) {
769 msgsystem::DrawMessageHistory();
774 truth
commandsystem::Throw (character
*Char
) {
775 if (!Char
->CheckThrow()) return false;
776 if (!Char
->GetStack()->GetItems()) {
777 ADD_MESSAGE("You have nothing to throw!");
780 item
*Item
= Char
->GetStack()->DrawContents(Char
, CONST_S("What do you want to throw?"));
782 int Answer
= game::DirectionQuestion(CONST_S("In what direction do you wish to throw? [press a direction key]"), false);
783 if (Answer
== DIR_ERROR
) return false;
784 Char
->ThrowItem(Answer
, Item
);
785 Char
->EditExperience(ARM_STRENGTH
, 75, 1 << 8);
786 Char
->EditExperience(DEXTERITY
, 75, 1 << 8);
787 Char
->EditExperience(PERCEPTION
, 75, 1 << 8);
789 Char
->DexterityAction(5);
796 truth
commandsystem::Apply (character
*Char
) {
797 if (!Char
->CanApply()) {
798 ADD_MESSAGE("This monster type cannot apply.");
801 if (!Char
->CheckApply()) return false;
802 if (!Char
->PossessesItem(&item::IsAppliable
)) {
803 ADD_MESSAGE("You have nothing to apply!");
806 item
*Item
= Char
->SelectFromPossessions(CONST_S("What do you want to apply?"), &item::IsAppliable
);
807 return Item
&& Item
->Apply(Char
);
811 truth
commandsystem::ForceVomit (character
*Char
) {
812 if (Char
->CanForceVomit()) {
813 int Dir
= game::DirectionQuestion(CONST_S("Where do you wish to vomit? [press a direction key]"), false, true);
814 if (Dir
!= DIR_ERROR
) {
815 v2 VomitPos
= Char
->GetPos()+game::GetMoveVector(Dir
);
816 if (Char
->GetArea()->IsValidPos(VomitPos
)) {
817 ccharacter
*Other
= Char
->GetArea()->GetSquare(VomitPos
)->GetCharacter();
818 if (Other
&& Other
->GetTeam() != Char
->GetTeam() &&
819 Other
->GetRelation(Char
) != HOSTILE
&&
820 Other
->CanBeSeenBy(Char
) &&
821 !game::TruthQuestion("Do you really want to vomit at "+Other
->GetObjectPronoun()+"? [y/N]")) return false;
822 ADD_MESSAGE("%s", Char
->GetForceVomitMessage().CStr());
823 Char
->Vomit(Char
->GetPos() + game::GetMoveVector(Dir
), 500 + RAND() % 500, false);
828 } else ADD_MESSAGE("You can't vomit.");
834 truth
commandsystem::Zap (character
*Char
) {
835 if (!Char
->CheckZap()) return false;
836 if (!Char
->PossessesItem(&item::IsZappable
)) {
837 ADD_MESSAGE("You have nothing to zap with, %s.", game::Insult());
840 item
*Item
= Char
->SelectFromPossessions(CONST_S("What do you want to zap with?"), &item::IsZappable
);
842 int Answer
= game::DirectionQuestion(CONST_S("In what direction do you wish to zap? [press a direction key or '.']"), false, true);
843 if (Answer
== DIR_ERROR
) return false;
844 if (Item
->Zap(Char
, Char
->GetPos(), Answer
)) {
845 Char
->EditAP(-100000/APBonus(Char
->GetAttribute(PERCEPTION
)));
854 truth
commandsystem::Rest (character
*Char
) {
855 if (Char
->StateIsActivated(PANIC
)) {
856 ADD_MESSAGE("You are too scared to rest.");
860 if (Char
->GetHP() == Char
->GetMaxHP()) {
861 ADD_MESSAGE("You HP is already at its maximum.");
863 } else if (!Char
->CanHeal()) {
864 ADD_MESSAGE("You cannot heal.");
868 sLong MinutesToRest
= game::NumberQuestion(CONST_S("How many minutes to wait?"), WHITE
, true);
869 if (MinutesToRest
> 0) {
870 oterrain
*Terrain
= Char
->GetSquareUnder()->GetOTerrain();
871 if (Terrain
) Terrain
->ShowRestMessage(Char
);
872 rest
*Rest
= rest::Spawn(Char
);
873 Rest
->SetMinToStop(game::GetTotalMinutes()+MinutesToRest
);
875 Char
->SetAction(Rest
);
880 sLong HPToRest
= game::ScrollBarQuestion(CONST_S("How many hit points you desire?"), Char
->GetMaxHP(), 1, 0, Char
->GetMaxHP(), 0, WHITE
, LIGHT_GRAY
, DARK_GRAY
);
881 if (HPToRest
<= Char
->GetHP()) {
882 if (HPToRest
!= 0) ADD_MESSAGE("Your HP is already %d.", Char
->GetHP());
885 oterrain
*Terrain
= Char
->GetSquareUnder()->GetOTerrain();
886 if (Terrain
) Terrain
->ShowRestMessage(Char
);
887 rest
*Rest
= rest::Spawn(Char
);
888 Rest
->SetMinToStop(0);
889 Rest
->SetGoalHP(HPToRest
);
890 Char
->SetAction(Rest
);
895 truth
commandsystem::Sit (character
*Char
) {
896 lsquare
*Square
= Char
->GetLSquareUnder();
897 return (Square
->GetOLTerrain() && Square
->GetOLTerrain()->SitOn(Char
)) || Square
->GetGLTerrain()->SitOn(Char
);
901 truth
commandsystem::Go (character
*Char
) {
902 int Dir
= game::DirectionQuestion(CONST_S("In what direction do you want to go? [press a direction key]"), false);
903 if (Dir
== DIR_ERROR
) return false;
904 go
*Go
= go::Spawn(Char
);
905 Go
->SetDirection(Dir
);
906 Go
->SetPrevWasTurn(false);
908 int OKDirectionsCounter = 0;
909 for (int d = 0; d < Char->GetNeighbourSquares(); ++d) {
910 lsquare *Square = Char->GetNeighbourLSquare(d);
911 if (Square && Char->CanMoveOn(Square)) ++OKDirectionsCounter;
913 Go->SetIsWalkingInOpen(OKDirectionsCounter > 2);
916 Char
->EditAP(Char
->GetStateAPGain(100)); // gum solution
917 Char
->GoOn(Go
, true);
918 return truth(Char
->GetAction());
922 truth
commandsystem::ShowConfigScreen (character
*) {
928 truth
commandsystem::AssignName (character
*) {
929 game::NameQuestion();
934 truth
commandsystem::EquipmentScreen (character
*Char
) {
935 return Char
->EquipmentScreen(Char
->GetStack(), 0);
939 truth
commandsystem::ScrollMessagesDown (character
*) {
940 msgsystem::ScrollDown();
945 truth
commandsystem::ScrollMessagesUp (character
*) {
946 msgsystem::ScrollUp();
951 truth
commandsystem::ShowWeaponSkills (character
*Char
) {
952 felist
List(CONST_S("Your experience in weapon categories"));
953 List
.AddDescription(CONST_S(""));
954 List
.AddDescription(CONST_S("Category name Level Points Needed Battle bonus"));
955 truth Something
= false;
957 for (int c
= 0; c
< Char
->GetAllowedWeaponSkillCategories(); ++c
) {
958 cweaponskill
*Skill
= Char
->GetCWeaponSkill(c
);
959 if (Skill
->GetHits()/100 || (Char
->IsUsingWeaponOfCategory(c
))) {
960 Buffer
= Skill
->GetName(c
);
962 Buffer
<< Skill
->GetLevel();
964 Buffer
<< Skill
->GetHits()/100;
966 if (Skill
->GetLevel() != 20) Buffer
<< (Skill
->GetLevelMap(Skill
->GetLevel()+1)-Skill
->GetHits())/100;
969 Buffer
<< '+' << (Skill
->GetBonus()-1000)/10;
970 if (Skill
->GetBonus() % 10) Buffer
<< '.' << Skill
->GetBonus()%10;
972 List
.AddEntry(Buffer
, Char
->IsUsingWeaponOfCategory(c
) ? WHITE
: LIGHT_GRAY
);
976 if (Char
->AddSpecialSkillInfo(List
)) Something
= true;
978 game::SetStandardListAttributes(List
);
981 ADD_MESSAGE("You are not experienced in any weapon skill yet!");
987 truth
commandsystem::WieldInRightArm (character
*Char
) {
988 if (!Char
->CanUseEquipment()) ADD_MESSAGE("You cannot wield anything.");
989 else if (Char
->TryToChangeEquipment(Char
->GetStack(), 0, RIGHT_WIELDED_INDEX
)) {
990 Char
->DexterityAction(5);
997 truth
commandsystem::WieldInLeftArm (character
*Char
) {
998 if (!Char
->CanUseEquipment()) ADD_MESSAGE("You cannot wield anything.");
999 else if (Char
->TryToChangeEquipment(Char
->GetStack(), 0, LEFT_WIELDED_INDEX
)) {
1000 Char
->DexterityAction(5);
1007 truth
commandsystem::Search (character
*Char
) {
1008 Char
->Search(Char
->GetAttribute(PERCEPTION
) << 2);
1014 truth
commandsystem::WizardMode (character
*Char
) {
1015 if (!game::WizardModeIsActive()) {
1016 if (game::TruthQuestion(CONST_S("Do you want to cheat, cheater? This action cannot be undone. [y/N]"))) {
1017 game::ActivateWizardMode();
1018 ADD_MESSAGE("Wizard mode activated.");
1019 if (!game::IsInWilderness()) game::LoadWorldMap();
1020 v2 ElpuriCavePos
= game::GetWorldMap()->GetEntryPos(0, ELPURI_CAVE
);
1021 game::GetWorldMap()->GetWSquare(ElpuriCavePos
)->ChangeOWTerrain(elpuricave::Spawn());
1022 game::GetWorldMap()->RevealEnvironment(ElpuriCavePos
, 1);
1023 if (game::IsInWilderness()) game::GetWorldMap()->SendNewDrawRequest(); else game::SaveWorldMap();
1025 game::Save(game::GetAutoSaveFileName());
1030 if (game::GetPlayerName() == "_k8_" && game::TruthQuestion(CONST_S("Do you want to uncheat, cheater? [y/N]"))) {
1031 game::DeactivateWizardMode();
1032 ADD_MESSAGE("You are the ordinary mortal again.");
1034 if (PLAYER
->GetVirtualHead()) {
1035 ADD_MESSAGE("spillfluid.");
1036 //PLAYER->GetVirtualHead()->SpillFluid(0, liquid::Spawn(GetBloodMaterial(), 1000));
1037 PLAYER
->GetVirtualHead()->SpillBlood(1000);
1044 truth
commandsystem::RaiseStats (character
*Char
) {
1045 Char
->EditAllAttributes(1);
1050 truth
commandsystem::LowerStats (character
*Char
) {
1051 Char
->EditAllAttributes(-1);
1056 truth
commandsystem::GainAllItems (character
*Char
) {
1057 itemvectorvector AllItems
;
1058 protosystem::CreateEveryItem(AllItems
);
1059 stack
*Stack
= game::IsInWilderness() ? Char
->GetStack() : Char
->GetStackUnder();
1060 for (uInt c
= 0; c
< AllItems
.size(); ++c
) Stack
->AddItem(AllItems
[c
][0]);
1065 truth
commandsystem::SeeWholeMap (character
*) {
1066 game::SeeWholeMap();
1071 truth
commandsystem::WalkThroughWalls (character
*) {
1072 game::GoThroughWalls();
1077 truth
commandsystem::RaiseGodRelations (character
*) {
1078 for (int c
= 1; c
<= GODS
; ++c
) game::GetGod(c
)->AdjustRelation(50);
1083 truth
commandsystem::LowerGodRelations (character
*) {
1084 for (int c
= 1; c
<= GODS
; ++c
) game::GetGod(c
)->AdjustRelation(-50);
1089 truth
commandsystem::GainDivineKnowledge (character
*) {
1090 for (int c
= 1; c
<= GODS
; ++c
) game::LearnAbout(game::GetGod(c
));
1095 truth
commandsystem::SecretKnowledge (character
*Char
) {
1096 felist
List(CONST_S("Knowledge of the ancients"));
1097 List
.AddEntry(CONST_S("Character attributes"), LIGHT_GRAY
);
1098 List
.AddEntry(CONST_S("Character attack info"), LIGHT_GRAY
);
1099 List
.AddEntry(CONST_S("Character defence info"), LIGHT_GRAY
);
1100 List
.AddEntry(CONST_S("Character danger values"), LIGHT_GRAY
);
1101 List
.AddEntry(CONST_S("Item attack info"), LIGHT_GRAY
);
1102 List
.AddEntry(CONST_S("Miscellaneous item info"), LIGHT_GRAY
);
1103 List
.AddEntry(CONST_S("Material info"), LIGHT_GRAY
);
1104 game::SetStandardListAttributes(List
);
1105 List
.AddFlags(SELECTABLE
);
1106 uInt c
, Chosen
= List
.Draw();
1108 if (Chosen
& FELIST_ERROR_BIT
) return false;
1110 List
.RemoveFlags(SELECTABLE
);
1112 charactervector
&Character
= game::GetCharacterDrawVector();
1114 for (std::list
<character
*>::const_iterator i
= Char
->GetTeam()->GetMember().begin(); i
!= Char
->GetTeam()->GetMember().end(); ++i
) {
1115 if ((*i
)->IsEnabled()) {
1116 Character
.push_back(*i
);
1120 protosystem::CreateEveryCharacter(Character
);
1121 List
.SetEntryDrawer(game::CharacterEntryDrawer
);
1124 List
.AddDescription(CONST_S(" AS LS DX AG EN PE IN WI CH MA"));
1125 for (c
= 0; c
< Character
.size(); ++c
) {
1127 Character
[c
]->AddName(Entry
, UNARTICLED
);
1128 Character
[c
]->AddAttributeInfo(Entry
);
1129 List
.AddEntry(Entry
, LIGHT_GRAY
, 0, c
);
1131 List
.SetPageLength(15);
1134 List
.AddDescription(CONST_S(" BD THV APC"));
1135 for (c
= 0; c
< Character
.size(); ++c
) {
1137 Character
[c
]->AddName(Entry
, UNARTICLED
);
1138 List
.AddEntry(Entry
, LIGHT_GRAY
, 0, c
);
1139 Character
[c
]->AddAttackInfo(List
);
1141 List
.SetPageLength(20);
1144 List
.AddDescription(CONST_S(" DV/BV HP AV/BS"));
1145 for (c
= 0; c
< Character
.size(); ++c
) {
1147 Character
[c
]->AddName(Entry
, UNARTICLED
);
1149 Entry
<< int(Character
[c
]->GetDodgeValue());
1151 Entry
<< Character
[c
]->GetMaxHP();
1152 List
.AddEntry(Entry
, LIGHT_GRAY
, 0, c
);
1153 Character
[c
]->AddDefenceInfo(List
);
1155 List
.SetPageLength(25);
1158 List
.AddDescription(CONST_S(" Danger NGM EGM"));
1159 for (c
= 0; c
< Character
.size(); ++c
) {
1161 Character
[c
]->AddName(Entry
, UNARTICLED
);
1163 Entry
<< int(Character
[c
]->GetRelativeDanger(Char
, true) * 1000);
1165 const dangerid
& DI
= game::GetDangerMap().find(configid(Character
[c
]->GetType(), Character
[c
]->GetConfig()))->second
;
1166 Entry
<< int(DI
.NakedDanger
* 1000);
1168 Entry
<< int(DI
.EquippedDanger
* 1000);
1169 List
.AddEntry(Entry
, LIGHT_GRAY
, 0, c
);
1171 List
.SetPageLength(15);
1175 for (c
= TeamSize
; c
< Character
.size(); ++c
) delete Character
[c
];
1176 game::ClearCharacterDrawVector();
1177 } else if (Chosen
< 6) {
1178 itemvectorvector
&Item
= game::GetItemDrawVector();
1179 protosystem::CreateEveryItem(Item
);
1180 List
.SetEntryDrawer(game::ItemEntryDrawer
);
1181 List
.SetPageLength(20);
1184 List
.AddDescription(CONST_S(" Weight Size SR DAM"));
1185 for (c
= 0; c
< Item
.size(); ++c
) {
1187 Item
[c
][0]->AddName(Entry
, UNARTICLED
);
1188 List
.AddEntry(Entry
, LIGHT_GRAY
, 0, c
, true);
1189 Item
[c
][0]->AddAttackInfo(List
);
1193 List
.AddDescription(CONST_S(" \177 OV NV"));
1194 for (c
= 0; c
< Item
.size(); ++c
) {
1196 Item
[c
][0]->AddName(Entry
, UNARTICLED
);
1197 List
.AddEntry(Entry
, LIGHT_GRAY
, 0, c
, true);
1198 Item
[c
][0]->AddMiscellaneousInfo(List
);
1203 for (c
= 0; c
< Item
.size(); ++c
) delete Item
[c
][0];
1204 game::ClearItemDrawVector();
1205 } else if (Chosen
< 7) {
1206 std::vector
<material
*> Material
;
1207 protosystem::CreateEveryMaterial(Material
);
1208 List
.SetPageLength(30);
1209 List
.AddDescription(CONST_S(" Strength Flexibility Density"));
1210 for (c
= 0; c
< Material
.size(); ++c
) {
1212 Material
[c
]->AddName(Entry
, false, false);
1214 Entry
<< Material
[c
]->GetStrengthValue();
1216 Entry
<< int(Material
[c
]->GetFlexibility());
1218 Entry
<< int(Material
[c
]->GetDensity());
1219 List
.AddEntry(Entry
, Material
[c
]->GetColor());
1222 for (c
= 0; c
< Material
.size(); ++c
) delete Material
[c
];
1224 List
.PrintToFile(game::GetHomeDir()+"secret"+Chosen
+".txt");
1225 ADD_MESSAGE("Info written also to %ssecret%d.txt.", game::GetHomeDir().CStr(), Chosen
);
1230 truth
commandsystem::DetachBodyPart (character
*Char
) {
1231 Char
->DetachBodyPart();
1236 truth
commandsystem::SummonMonster (character
*Char
) {
1237 character
*Summoned
= 0;
1240 festring Temp
= game::DefaultQuestion(CONST_S("Summon which monster?"), game::GetDefaultSummonMonster());
1242 if (Temp
== "none") return false;
1243 Summoned
= protosystem::CreateMonster(Temp
);
1245 Summoned
->SetTeam(game::GetTeam(MONSTER_TEAM
));
1246 Summoned
->PutNear(Char
->GetPos());
1251 truth
commandsystem::LevelTeleport (character
*) {
1252 sLong Level
= game::NumberQuestion(CONST_S("To which level?"), WHITE
);
1253 if (Level
<= 0 || Level
> game::GetLevels()) {
1254 ADD_MESSAGE("There is no level %d in this dungeon, %s!", Level
, game::Insult());
1257 if (Level
== game::GetCurrentLevelIndex()+1) {
1258 ADD_MESSAGE("You are already here, %s!", game::Insult());
1261 return game::TryTravel(game::GetCurrentDungeonIndex(), Level
-1, RANDOM
, true);
1265 truth
commandsystem::Possess (character
*Char
) {
1266 int Dir
= game::DirectionQuestion(CONST_S("Choose creature to possess. [press a direction key]"), false);
1267 if (Dir
== DIR_ERROR
|| !Char
->GetArea()->IsValidPos(Char
->GetPos() + game::GetMoveVector(Dir
))) return false;
1268 character
*ToPossess
= Char
->GetNearLSquare(Char
->GetPos() + game::GetMoveVector(Dir
))->GetCharacter();
1270 Char
->RemoveFlags(C_PLAYER
);
1271 game::SetPlayer(ToPossess
);
1273 ADD_MESSAGE("There's no one to possess, %s!", game::Insult());
1275 return true; // The old player's turn must end
1279 truth
commandsystem::Polymorph (character
*Char
) {
1281 if (!Char
->GetNewFormForPolymorphWithControl(NewForm
)) return true;
1282 Char
->Polymorph(NewForm
, game::NumberQuestion(CONST_S("For how long?"), WHITE
));
1287 truth
commandsystem::GetScroll (character
*Char
) {
1289 int sel
= game::ListSelector(-1, CONST_S("Select scroll to add"),
1290 "Scroll of Wishing",
1291 "Scroll of Charging",
1293 "Scroll of Change Material",
1294 "Scroll of Enchant Weapon",
1295 "Scroll of Enchant Armor",
1297 "Scroll of Teleportation",
1298 "Scroll of Detect Material",
1299 "Scroll of Harden Material",
1300 "Scroll of Golem Creation",
1305 sLong amount
= game::NumberQuestion(CONST_S("How many scrolls do you want?"), WHITE
, true);
1306 if (amount
< 1) amount
= 1;
1307 for (sLong f
= amount
; f
> 0; --f
) {
1309 case 0: sname
= "Wishing"; Char
->GetStack()->AddItem(scrollofwishing::Spawn()); break;
1310 case 1: sname
= "Charging"; Char
->GetStack()->AddItem(scrollofcharging::Spawn()); break;
1311 case 2: sname
= "Repair"; Char
->GetStack()->AddItem(scrollofrepair::Spawn()); break;
1312 case 3: sname
= "Change Material"; Char
->GetStack()->AddItem(scrollofchangematerial::Spawn()); break;
1313 case 4: sname
= "Enchant Weapon"; Char
->GetStack()->AddItem(scrollofenchantweapon::Spawn()); break;
1314 case 5: sname
= "Enchant Armor"; Char
->GetStack()->AddItem(scrollofenchantarmor::Spawn()); break;
1315 case 6: sname
= "Taming"; Char
->GetStack()->AddItem(scrolloftaming::Spawn()); break;
1316 case 7: sname
= "Teleportation"; Char
->GetStack()->AddItem(scrollofteleportation::Spawn()); break;
1317 case 8: sname
= "Detect Material"; Char
->GetStack()->AddItem(scrollofdetectmaterial::Spawn()); break;
1318 case 9: sname
= "Harden Material"; Char
->GetStack()->AddItem(scrollofhardenmaterial::Spawn()); break;
1319 case 10: sname
= "Golem Creation"; Char
->GetStack()->AddItem(scrollofgolemcreation::Spawn()); break;
1320 default: sel
= 666; break;
1325 ADD_MESSAGE("Got Scroll of %s.", sname
.CStr());
1327 ADD_MESSAGE("Got %d Scrolls of %s.", amount
, sname
.CStr());
1336 truth
commandsystem::WizardWish (character
*Char
) {
1337 if (!game::Wish(PLAYER
, "%s appears from nothing!", "Two %s appear from nothing!", true)) {
1338 ADD_MESSAGE("You changed your mind, didn't you, %s?", game::Insult());
1344 truth
commandsystem::OpenMondedr (character
*Char
) {
1345 if (!game::GetMondedrPass()) {
1346 if (!game::IsInWilderness()) game::LoadWorldMap();
1347 v2 MondedrPos
= game::GetWorldMap()->GetEntryPos(0, MONDEDR
);
1348 game::GetWorldMap()->GetWSquare(MondedrPos
)->ChangeOWTerrain(mondedr::Spawn());
1349 game::GetWorldMap()->RevealEnvironment(MondedrPos
, 1);
1350 if (game::IsInWilderness()) game::GetWorldMap()->SendNewDrawRequest(); else game::SaveWorldMap();
1351 game::SetMondedrPass(1);
1353 game::Save(game::GetAutoSaveFileName());
1354 ADD_MESSAGE("Mondedr opened.");
1356 ADD_MESSAGE("Mondedr already opened.");
1362 truth
commandsystem::ShowCoords (character
*Char
) {
1363 v2 xy
= Char
->GetPos();
1364 ADD_MESSAGE("Coordinates: X=%d; Y=%d", xy
.X
, xy
.Y
);
1370 static void dbp (character *Char, int idx) {
1371 if (Char->GetBodyPart(idx)) {
1372 festring NameOfDropped = Char->GetBodyPart(idx)->GetBodyPartName();
1373 item *dropped = Char->SevereBodyPart(idx);
1375 //Char->GetStack()->AddItem(dropped);
1376 dropped->DropEquipment();
1377 dropped->SendToHell();
1378 ADD_MESSAGE("Suddenly, %s snaps off.", NameOfDropped.CStr());
1385 truth
commandsystem::WizardHeal (character
*Char
) {
1387 truth newbp = game::TruthQuestion(CONST_S("Do you want completely new body? [y/N]"));
1389 dbp(Char, LEFT_ARM_INDEX);
1390 //dbp(Char, RIGHT_ARM_INDEX);
1391 //dbp(Char, LEFT_LEG_INDEX);
1392 //dbp(Char, RIGHT_LEG_INDEX);
1393 //dbp(Char, HEAD_INDEX);
1394 //dbp(Char, TORSO_INDEX);
1397 for (int c
= 0; c
< Char
->GetBodyParts(); ++c
) {
1398 if (Char
->GetBodyPart(c
)) {
1399 Char
->GetBodyPart(c
)->RemoveAllFluids();
1400 } else if (Char
->CanCreateBodyPart(c
)) {
1401 const std::list
<feuLong
> &obp
= Char
->GetOriginalBodyPartID(c
);
1403 for (std::list
<feuLong
>::const_iterator i
= obp
.begin(); i
!= obp
.end(); ++i
) {
1404 bodypart
*OldBodyPart
= static_cast<bodypart
*>(PLAYER
->SearchForItem(*i
));
1406 if (OldBodyPart
&& OldBodyPart
->CanRegenerate()) {
1407 OldBodyPart
->RemoveAllFluids();
1408 OldBodyPart
->SetHP(1);
1409 OldBodyPart
->RemoveFromSlot();
1410 Char
->AttachBodyPart(OldBodyPart
);
1413 Char
->CreateBodyPart(c
);
1414 Char
->GetBodyPart(c
)->SetHP(1);
1421 if (Char
->TemporaryStateIsActivated(POISONED
)) Char
->DeActivateTemporaryState(POISONED
);
1422 if (Char
->TemporaryStateIsActivated(PARASITIZED
)) Char
->DeActivateTemporaryState(PARASITIZED
);
1423 if (Char
->TemporaryStateIsActivated(LEPROSY
)) Char
->DeActivateTemporaryState(LEPROSY
);
1424 if (Char
->TemporaryStateIsActivated(LYCANTHROPY
)) Char
->DeActivateTemporaryState(LYCANTHROPY
);
1425 if (Char
->TemporaryStateIsActivated(VAMPIRISM
)) Char
->DeActivateTemporaryState(VAMPIRISM
);
1427 ADD_MESSAGE("Wizard healing...");
1433 truth
commandsystem::ToggleRunning (character
*Char
) {
1434 if (game::PlayerIsRunning() && PLAYER
->StateIsActivated(PANIC
) && PLAYER
->GetTirednessState() != FAINTING
) {
1435 ADD_MESSAGE("You are too scared to move at normal pace.");
1438 if (!Char
->CanMove()) {
1439 ADD_MESSAGE("Well, well, aren't we funny today, eh?");
1442 game::SetPlayerIsRunning(!game::PlayerIsRunning());
1447 truth
commandsystem::Burn (character
*Char
) {
1448 if (!Char
->PossessesItem(&item::IsFlaming
)) {
1449 ADD_MESSAGE("You have no flaming items, %s.", game::Insult());
1452 item
*Item
= Char
->SelectFromPossessions(CONST_S("What do you want to use?"), &item::IsFlaming
);
1454 int Answer
= game::DirectionQuestion(CONST_S("In what direction do you wish to burn? [press a direction key]"), false);
1455 if (Answer
== DIR_ERROR
) return false;
1456 if (Item
->Burn(Char
, Char
->GetPos(), Answer
)) {
1458 Char
->EditExperience(AGILITY
, 150, 1<<6);
1460 Char
->EditAP(-100000/APBonus(Char
->GetAttribute(AGILITY
)));
1469 //FIXME: check for actor in that direction
1470 //FIXME: made actor/room owner hostile when containing material is acid, etc
1471 //FIXME: ÓÐÏÓÏ ×ÙÌÉÔØ ÔÏÞÎÏ ÎÁ ÐÏÌ ÉÌÉ ÎÁ ÍÏÎÓÔÒÉËÁ (ÚÁ×ÉÓÉÔ ÏÔ ÌÏ×ËÏÓÔÉ?)
1472 truth
commandsystem::Dump (character
*Char
) {
1473 if (!Char
->GetStack()->SortedItems(Char
, &item::IsDumpable
) && !Char
->EquipsSomething(&item::IsDumpable
)) {
1474 ADD_MESSAGE("You have nothing to dump!");
1477 item
*Item
= Char
->SelectFromPossessions(CONST_S("What do you want to dump?"), &item::IsDumpable
);
1479 int Dir
= game::DirectionQuestion(CONST_S("In what direction do you wish to dump it? [press a direction key or '.']"), false, true);
1480 if (Dir
== DIR_ERROR
) return false;
1481 v2 Pos
= Char
->GetPos()+game::GetMoveVector(Dir
);
1482 return Item
->DumpTo(Char
, Pos
);
1488 truth
commandsystem::IssueCommand (character
*Char
) {
1489 if (!Char
->CheckTalk()) return false;
1490 return game::CommandQuestion();