1 // Hyperbolic Rogue - items
2 // Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details
3
4 /** \file item.cpp
5 * \brief routines related to items
6 */
7
8 #include "hyper.h"
9
10 namespace hr {
11
12 EX int currentLocalTreasure;
13
14 /** for treasures, the number collected; for orbs, the number of charges */
15 EX array<int, ittypes> items;
16
17 EX map<modecode_t, array<int, ittypes> > hiitems;
18
cannotPickupItem(cell * c,bool telekinesis)19 EX bool cannotPickupItem(cell *c, bool telekinesis) {
20 return itemHidden(c) && !telekinesis && !(isWatery(c) && markOrb(itOrbFish));
21 }
22
canPickupItemWithMagnetism(cell * c,cell * from)23 EX bool canPickupItemWithMagnetism(cell *c, cell *from) {
24 if(!c->item || c->item == itOrbYendor || isWall(c) || cannotPickupItem(c, false))
25 return false;
26 if(c->item == itCompass && from->item)
27 return false;
28 return true;
29 }
30
doPickupItemsWithMagnetism(cell * c)31 EX bool doPickupItemsWithMagnetism(cell *c) {
32 /* repulsion works first -- Magnetism will collect the item if not repulsed */
33 if(items[itCurseRepulsion])
34 forCellIdEx(c3, i, c) if(c3->item) {
35 cellwalker cw(c, i);
36 cw += wstep;
37 for(int j=1; j<c3->type; j++) {
38 cell *c4 = (cw+j).peek();
39 if(!isNeighbor(c, c4) && c3->item && !c4->item && passable(c4, c3, ZERO)) {
40 changes.ccell(c3);
41 changes.ccell(c4);
42 c4->item = c3->item;
43 moveEffect(movei(c3, c4, (cw+j).spin), moDeadBird);
44 c3->item = itNone;
45 }
46 }
47 }
48 cell *csaf = NULL;
49 if(items[itOrbMagnetism])
50 forCellEx(c3, c) if(canPickupItemWithMagnetism(c3, c)) {
51 changes.ccell(c3);
52 changes.ccell(c);
53 if(c3->item == itCompass) {
54 if(!c->item)
55 moveItem(c3, c, false);
56 }
57 else if(c3->item == itOrbSafety || c3->item == itBuggy || c3->item == itBuggy2)
58 csaf = c3;
59 else if(markOrb(itOrbMagnetism))
60 collectItem(c3, false);
61 }
62 if(csaf)
63 return collectItem(csaf, false);
64 return false;
65 }
66
pickupMovedItems(cell * c)67 EX void pickupMovedItems(cell *c) {
68 if(!c->item) return;
69 if(c->item == itOrbSafety) return;
70 if(isPlayerOn(c)) collectItem(c, true);
71 if(items[itOrbMagnetism])
72 forCellEx(c2, c)
73 if(isPlayerOn(c2) && canPickupItemWithMagnetism(c, c2)) {
74 changes.ccell(c2);
75 changes.ccell(c);
76 collectItem(c, true);
77 }
78 }
79
in_lovasz()80 EX bool in_lovasz() {
81 return specialland == laMotion && bounded && ls::single() && !daily::on;
82 }
83
collectItem(cell * c2,bool telekinesis IS (false))84 EX bool collectItem(cell *c2, bool telekinesis IS(false)) {
85
86 bool dopickup = true;
87 bool had_choice = false;
88
89 if(cannotPickupItem(c2, telekinesis))
90 return false;
91
92 if(items[itCurseGluttony] && c2->item) {
93 addMessage(XLAT("%The1 is consumed!", c2->item));
94 playSound(c2, "apple");
95 items[itCurseGluttony] = 0;
96 c2->item = itNone;
97 return false;
98 }
99
100 /* if(c2->item == itHolyGrail && telekinesis)
101 return false; */
102
103 if(c2->item) {
104 invismove = false;
105 if(shmup::on) shmup::visibleFor(2000);
106 string s0 = "";
107
108 if(c2->item == itPalace && items[c2->item] == 12)
109 changes.value_set(princess::forceVizier, true);
110
111 if(!cantGetGrimoire(c2, false)) collectMessage(c2, c2->item);
112 if(c2->item == itDodeca && peace::on) peace::simon::extend();
113 }
114
115 #if CAP_COMPLEX2
116 if(c2->land == laHunting && c2->item && !inv::activating) {
117 ambush::ambush(c2, ambush::size(c2, c2->item));
118 }
119 #endif
120
121 if(isRevivalOrb(c2->item) && multi::revive_queue.size()) {
122 multiRevival(cwt.at, c2);
123 }
124 else if(isShmupLifeOrb(c2->item) && shmup::on) {
125 playSound(c2, "pickup-orb"); // TODO summon
126 gainLife();
127 }
128 else if(orbcharges(c2->item)) {
129 eItem it = c2->item;
130 if(it == itOrbRecall && !dual::state) {
131 cellwalker cw2 = cwt;
132 cw2++;
133 cw2.at = c2;
134 saveRecall(cw2);
135 }
136 if(it == itOrbFire) playSound(c2, "fire");
137 else if(it == itOrbFire) playSound(c2, "fire");
138 else if(it == itOrbWinter) playSound(c2, "pickup-winter");
139 else if(it == itOrbSpeed) playSound(c2, "pickup-speed");
140 else if(it == itRevolver) playSound(c2, "pickup-key");
141 else playSound(c2, "pickup-orb");
142 if(items[itOrbChoice]) items[itOrbChoice] = 0, had_choice = true;
143 int oc = orbcharges(it);
144 if(dual::state && among(it, itOrbTeleport, itOrbFrog, itOrbPhasing, itOrbDash, itOrbRecall)) {
145 oc = 10;
146 it = itOrbSpeed;
147 }
148 if(c2->land == laAsteroids) oc = 10;
149 if(markOrb(itOrbIntensity)) oc = intensify(oc);
150 if(!items[it]) items[it]++;
151 items[it] += oc;
152
153 if(it == itOrbPurity) {
154 bool no_curses = true;
155 for(cell *c: dcal) if(c->land == laCursed) no_curses = false;
156 if(no_curses) {
157 items[itOrbSpeed] += 5;
158 items[itOrbWinter] += 5;
159 items[itOrbSlaying] += 5;
160 items[itOrbTime] += 5;
161 items[itOrbMagnetism] += 5;
162 items[itOrbChoice] += 5;
163 }
164 }
165 }
166 else if(c2->item == itOrbLife) {
167 playSound(c2, "pickup-orb"); // TODO summon
168 placeGolem(cwt.at, c2, moGolem);
169 if(cwt.at->monst == moGolem) cwt.at->stuntime = 0;
170 }
171 else if(c2->item == itOrbFriend) {
172 playSound(c2, "pickup-orb"); // TODO summon
173 placeGolem(cwt.at, c2, moTameBomberbird);
174 if(cwt.at->monst == moTameBomberbird) cwt.at->stuntime = 0;
175 }
176 #if CAP_TOUR
177 else if(tour::on && (c2->item == itOrbSafety || c2->item == itOrbRecall)) {
178 addMessage(XLAT("This Orb is not compatible with the Tutorial."));
179 if(changes.on) changes.rollback();
180 return true;
181 }
182 #endif
183 else if(c2->item == itOrbSafety) {
184
185 if(changes.on) {
186 if(changes.checking) {
187 changes.rollback();
188 return true;
189 }
190 changes.commit();
191 }
192
193 playSound(c2, "pickup-orb"); // TODO safety
194 if(!dual::state) items[c2->item] = 7;
195 if(shmup::on || multi::players > 1) {
196 shmup::delayed_safety = true;
197 shmup::delayed_safety_land = c2->land;
198 }
199 else
200 activateSafety(c2->land);
201 return true;
202 }
203 else if(c2->item == itBabyTortoise) {
204 using namespace tortoise;
205 int bnew = babymap[c2];
206 changes.map_value(babymap, c2);
207 babymap.erase(c2);
208 int bold = seekbits;
209 changes.value_set(tortoise::seekbits, bnew);
210 changes.value_set(tortoise::last, seekbits);
211 if(seek()) {
212 cell *c = passable(cwt.at, NULL, 0) ? cwt.at : c2;
213 changes.ccell(c);
214 c->item = itBabyTortoise;
215 if(c == c2) dopickup = false;
216 changes.map_value(babymap, c);
217 babymap[c] = bold;
218 }
219 else items[itBabyTortoise]++;
220 }
221 else if(c2->item == itOrbYendor && peace::on) {
222 if(!items[itDodeca]) {
223 addMessage(XLAT("Collect as many Dodecahedra as you can, then return here!"));
224 }
225 else {
226 addMessage(XLAT("Your score: %1", its(items[itDodeca])));
227 peace::simon::restore();
228 }
229 dopickup = false;
230 }
231 else if(c2->item == itOrbYendor && yendor::state(c2) != yendor::ysUnlocked) {
232 dopickup = false;
233 }
234 else if(c2->item == itOrbYendor)
235 yendor::collected(c2);
236 else if(c2->item == itHolyGrail) {
237 playSound(c2, "tada");
238 int v = newRoundTableRadius() + 12;
239 items[itOrbTeleport] += v;
240 items[itOrbSpeed] += v;
241 items[itHolyGrail]++;
242 addMessage(XLAT("Congratulations! You have found the Holy Grail!"));
243 if(!eubinary) changes.value_keep(c2->master->alt->emeraldval);
244 if(!eubinary) c2->master->alt->emeraldval |= GRAIL_FOUND;
245 achievement_collection(c2->item);
246 }
247 else if(c2->item == itKey) {
248 playSound(c2, "pickup-key");
249 for(int i=0; i<isize(yendor::yi); i++) if(yendor::yi[i].actual_key() == c2)
250 changes.value_set(yendor::yi[i].found, true);
251 items[itKey]++;
252 }
253 else if(!telekinesis && cantGetGrimoire(c2)) {
254 // telekinesis checks the condition earlier
255 dopickup = false;
256 }
257 else if(c2->item == itCompass) {
258 dopickup = false;
259 }
260 else if(c2->item == itBuggy || c2->item == itBuggy2) {
261
262 if(changes.on) {
263 if(changes.checking) {
264 changes.rollback();
265 return true;
266 }
267 changes.commit();
268 }
269
270 items[itOrbSafety] += 7;
271 if(shmup::on)
272 shmup::delayed_safety = true;
273 else {
274 buggyGeneration = false;
275 activateSafety(laCrossroads);
276 }
277 return true;
278 }
279 else if(c2->item == itTreat) {
280 playSound(c2, "pickup-scroll");
281 halloween::getTreat(c2);
282 }
283 else {
284 if(c2->item == itBarrow)
285 for(int i=0; i<c2->landparam; i++) gainItem(c2->item);
286 else if(c2->item) gainItem(c2->item);
287
288 if(c2->item && (vid.bubbles_all || (among(items[c2->item], 5, 10, 25, 50, 100, 250, 500) && vid.bubbles_threshold))) {
289 drawBubble(c2, iinf[c2->item].color, its(items[c2->item]), 0.5);
290 }
291
292 if(c2->item) {
293 char ch = iinf[c2->item].glyph;
294 if(ch == '*') playSound(c2, "pickup-gem");
295 else if(ch == '$' || ch == 'x') playSound(c2, "pickup-gold");
296 else if(ch == '%' || ch == ';') playSound(c2, "pickup-potion");
297 else if(c2->item == itApple) playSound(c2, "apple");
298 else playSound(c2, "pickup-scroll");
299 }
300 }
301
302 if(dopickup && c2->item) {
303 #if CAP_HISTORY
304 // temporary variable to avoid the "cannot bind bitfield" problem in C++11
305 eItem dummy = c2->item;
306 history::findhistory.emplace_back(c2, dummy);
307 #endif
308
309 if(c2->item == itBombEgg && c2->land == laMinefield) {
310 c2->landparam |= 2;
311 c2->landparam &= ~1;
312 }
313
314 if(!had_choice)
315 c2->item = itNone;
316 }
317 // if(c2->land == laHive)
318 // c2->heat = 1;
319
320 int numOrb = 0;
321 for(int i=0; i<ittypes; i++)
322 if(itemclass(eItem(i)) == IC_ORB && items[i])
323 numOrb++;
324 if(numOrb) achievement_count("ORB", numOrb, 0);
325
326 if(princess::reviveAt && gold(NO_LOVE) >= princess::reviveAt && !inv::on) {
327 changes.value_set(princess::reviveAt, 0);
328 items[itSavedPrincess] = 1;
329 addMessage("You have enough treasure now to revive the Princess!");
330 }
331
332 return false;
333 }
334
glance_message()335 EX void glance_message() {
336 if(gold() >= 300)
337 addMessage(XLAT("You feel great, like a true treasure hunter."));
338 else if(gold() >= 200)
339 addMessage(XLAT("Your eyes shine like gems."));
340 else if(gold() >= 100)
341 addMessage(XLAT("Your eyes shine as you glance at your precious treasures."));
342 else if(gold() >= 50)
343 addMessage(XLAT("You glance at your great treasures."));
344 else if(gold() >= 10)
345 addMessage(XLAT("You glance at your precious treasures."));
346 else if(gold() > 0)
347 addMessage(XLAT("You glance at your precious treasure."));
348 else
349 addMessage(XLAT("Your inventory is empty."));
350 }
351
dropGreenStone(cell * c)352 EX void dropGreenStone(cell *c) {
353 if(items[itGreenStone] && !passable(c, NULL, P_MONSTER)) {
354 // NOTE: PL/CZ translations assume that itGreenStone is dropped to avoid extra forms!
355 addMessage(XLAT("Cannot drop %the1 here!", itGreenStone));
356 return;
357 }
358 if(items[itGreenStone] && c->item == itNone) {
359 changes.ccell(c);
360 changes.value_keep(items[itGreenStone]);
361 items[itGreenStone]--;
362 if(false) {
363 c->item = itNone;
364 spill(c, eWall(c->wall ^ waFloorA ^ waFloorB), 3);
365 addMessage(XLAT("The slime reacts with %the1!", itGreenStone));
366 }
367 else {
368 c->item = itGreenStone;
369 addMessage(XLAT("You drop %the1.", itGreenStone));
370 if(isHaunted(cwt.at->land))
371 fail_survivalist();
372 }
373 }
374 else {
375 if(items[itGreenStone] && c->item == itGreenStone)
376 addMessage(XLAT("You juggle the Dead Orbs."));
377 else if(items[itGreenStone] && c->item)
378 addMessage(XLAT("You give %the1 a grim look.", c->item));
379 else if(items[itGreenStone]) {
380 addMessage(XLAT("Cannot drop %the1 here!", itGreenStone));
381 return;
382 }
383 else glance_message();
384 }
385 }
386
moveItem1(cell * from,cell * to,bool activateYendor)387 EX void moveItem1(cell *from, cell *to, bool activateYendor) {
388 if(from->item == itOrbYendor) {
389 bool xnew = true;
390 for(int i=0; i<isize(yendor::yi); i++)
391 if(yendor::yi[i].path[0] == from) xnew = false;
392 if(xnew && activateYendor) yendor::check(from);
393 for(int i=0; i<isize(yendor::yi); i++)
394 if(yendor::yi[i].path[0] == from)
395 changes.value_set(yendor::yi[i].path[0], to);
396 }
397
398 if(from->item == itKey) {
399 for(int i=0; i<isize(yendor::yi); i++) if(yendor::yi[i].path[YDIST-1] == from) {
400 changes.value_set(yendor::yi[i].path[YDIST-1], to);
401 }
402 for(int i=0; i<isize(yendor::yi); i++) if(yendor::yi[i].actualKey == from)
403 changes.value_set(yendor::yi[i].actualKey, to);
404 }
405
406 if(from->item == itBabyTortoise || to->item == itBabyTortoise) {
407 tortoise::move_baby(from, to);
408 }
409
410 eItem i = to->item;
411 to->item = from->item;
412 from->item = i;
413 }
414
moveItem(cell * from,cell * to,bool activateYendor)415 EX void moveItem (cell *from, cell *to, bool activateYendor) {
416 static cell dummy;
417 dummy.item = itNone;
418 moveItem1(from, &dummy, activateYendor);
419 moveItem1(to, from, activateYendor);
420 moveItem1(&dummy, to, activateYendor);
421 }
422
itemHidden(cell * c)423 EX bool itemHidden(cell *c) {
424 return isWatery(c) && !(shmup::on && shmup::boatAt(c));
425 }
426
localTreasureType()427 EX eItem localTreasureType() {
428 lastland = singlepos()->land;
429 return treasureType(lastland);
430 }
431
countLocalTreasure()432 EX void countLocalTreasure() {
433 eItem i = localTreasureType();
434 currentLocalTreasure = i ? items[i] : 0;
435 if(i != itHyperstone) for(int i=0; i<isize(dcal); i++) {
436 cell *c2 = dcal[i];
437 if(c2->cpdist > 3) break;
438 eItem i2 = treasureType(c2->land);
439 if(i2 && items[i2] < currentLocalTreasure)
440 currentLocalTreasure = items[i2];
441 }
442 }
443
444 #if HDR
445 static const int NO_TREASURE = 1;
446 static const int NO_YENDOR = 2;
447 static const int NO_GRAIL = 4;
448 static const int NO_LOVE = 8;
449 #endif
450
451 EX int gold(int no IS(0)) {
452 int i = 0;
453 if(!(no & NO_YENDOR)) i += items[itOrbYendor] * 50;
454 if(!(no & NO_GRAIL)) i += items[itHolyGrail] * 10;
455 if(!(no & NO_LOVE)) {
456 bool love = items[itOrbLove];
457 #if CAP_INV
458 if(inv::on && inv::remaining[itOrbLove])
459 love = true;
460 #endif
461 #if CAP_DAILY
462 if(daily::on) love = false;
463 #endif
464 if(love) i += 30;
465 }
466
467 if(!(no & NO_TREASURE))
468 for(int t=0; t<ittypes; t++)
469 if(itemclass(eItem(t)) == IC_TREASURE)
470 i += items[t];
471 return i;
472 }
473
maxgold()474 EX int maxgold() {
475 int mg = 0;
476 for(int i=0; i<ittypes; i++)
477 if(itemclass(eItem(i)) == IC_TREASURE && items[i] > mg)
478 mg = items[i];
479 return mg;
480 }
481
updateHi_for_code(eItem it,int v,modecode_t xcode)482 EX void updateHi_for_code(eItem it, int v, modecode_t xcode) {
483 if(!yendor::on)
484 if(v > hiitems[xcode][it])
485 changes.value_set(hiitems[xcode][it], v);
486 }
487
updateHi(eItem it,int v)488 EX void updateHi(eItem it, int v) {
489 updateHi_for_code(it, v, modecode());
490 }
491
gainItem(eItem it)492 EX void gainItem(eItem it) {
493 int g = gold();
494 bool lhu = landUnlocked(laHell);
495 items[it]++; if(it != itLotus) updateHi(it, items[it]);
496 if(it == itRevolver && items[it] > 6) items[it] = 6;
497 achievement_collection(it);
498 multi::treasures[multi::cpid]++;
499 #if CAP_DAILY
500 if(daily::on) achievement_final(false);
501 #endif
502
503 int g2 = gold();
504 if(items[itFireShard] && items[itAirShard] && items[itWaterShard] && items[itEarthShard]) {
505 items[itFireShard]--;
506 items[itAirShard]--;
507 items[itWaterShard]--;
508 items[itEarthShard]--;
509 gainItem(itElemental);
510 gainItem(itElemental);
511 gainItem(itElemental);
512 gainItem(itElemental);
513 addMessage(XLAT("You construct some Elemental Gems!", it) + itemcounter(items[itElemental]));
514 playSound(cwt.at, "elementalgem");
515 }
516
517 if(it == itBounty)
518 items[itRevolver] = 6;
519
520 if(it == itHyperstone && items[itHyperstone] == 10)
521 achievement_victory(true);
522
523 if(ls::any_chaos() && gold() >= 300)
524 achievement_gain_once("CHAOS", rg::chaos);
525
526 #if ISMOBILE
527 if(g < lastsafety + R30*3/2 && g2 >= lastsafety + R30*3/2)
528 addMessage(XLAT("The Orb of Safety from the Land of Eternal Motion might save you."));
529 #endif
530
531 #define IF(x) if(g < (x) && g2 >= x && !peace::on)
532
533 if(in_full_game()) {
534 IF(R60/4)
535 addMessage(XLAT("Collect treasure to access more different lands..."));
536 IF(R30)
537 addMessage(XLAT("You feel that you have enough treasure to access new lands!"));
538 IF(R30*3/2)
539 addMessage(XLAT("Collect more treasures, there are still more lands waiting..."));
540 IF(R60)
541 addMessage(XLAT("You feel that the stars are right, and you can access R'Lyeh!"));
542 IF(R30*5/2)
543 addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell..."));
544 IF(R10 * 9)
545 addMessage(XLAT("To access Hell, collect %1 treasures each of 9 kinds...", its(R10)));
546 if(landUnlocked(laHell) && !lhu) {
547 addMessage(XLAT("Abandon all hope, the gates of Hell are opened!"));
548 addMessage(XLAT("And the Orbs of Yendor await!"));
549 }
550 }
551 }
552
itemcounter(int qty)553 EX string itemcounter(int qty) {
554 string s = ""; s += " ("; s += its(qty); s += ")"; return s;
555 }
556
gainShard(cell * c2,const char * msg)557 EX void gainShard(cell *c2, const char *msg) {
558 invismove = false;
559 string s = XLAT(msg);
560 if(is_mirrorland(c2) && !peace::on) {
561 collectMessage(c2, itShard);
562 gainItem(itShard);
563 s += itemcounter(items[itShard]);
564 }
565 addMessage(s);
566 c2->wall = waNone;
567 invismove = false;
568 }
569
placeItems(int qty,eItem it)570 EX void placeItems(int qty, eItem it) {
571 int dcs = isize(dcal);
572 for(int i=1; qty && i<dcs; i++) {
573 cell *c = dcal[i];
574 if(!c->monst && !c->item && passable(c, NULL, 0))
575 c->item = it, qty--;
576 }
577 }
578
cantGetGrimoire(cell * c2,bool verbose IS (true))579 EX bool cantGetGrimoire(cell *c2, bool verbose IS(true)) {
580 if(ls::any_chaos()) return false;
581 if(!eubinary && !c2->master->alt) return false;
582 if(c2->item == itGrimoire && items[itGrimoire] > celldistAlt(c2)/-temple_layer_size()) {
583 if(verbose)
584 addMessage(XLAT("You already have this Grimoire! Seek new tomes in the inner circles."));
585 return true;
586 }
587 return false;
588 }
589
gainLife()590 EX void gainLife() {
591 items[itOrbLife] ++;
592 if(items[itOrbLife] > 5 && !inv::on) items[itOrbLife] = 5;
593 }
594
collectMessage(cell * c2,eItem which)595 EX void collectMessage(cell *c2, eItem which) {
596 bool specialmode = yendor::on || princess::challenge || cheater || !in_full_game();
597
598 if(which == itDodeca && peace::on) return;
599 if(which == itTreat) ;
600 else if(isElementalShard(which)) {
601 int tsh =
602 items[itFireShard] + items[itAirShard] + items[itWaterShard] + items[itEarthShard] +
603 items[itElemental];
604 if(tsh == 0) {
605 addMessage(XLAT("Collect four different Elemental Shards!"));
606 addMessage(XLAT("Unbalanced shards in your inventory are dangerous."));
607 }
608 else {
609 string t = XLAT("You collect %the1. (%2)", which, its(items[which]+1));
610 addMessage(t);
611 }
612 }
613 else if(which == itKey) {
614 addMessage(XLAT("You have found the Key! Now unlock this Orb of Yendor!"));
615 }
616 else if(which == itGreenStone && !items[itGreenStone])
617 addMessage(XLAT("This orb is dead..."));
618 else if(which == itGreenStone)
619 addMessage(XLAT("Another Dead Orb."));
620 else if(itemclass(which) != IC_TREASURE) {
621 if(!inv::activating)
622 addMessage(XLAT("You have found %the1!", which));
623 }
624 else if(which == itBabyTortoise) {
625 playSound(c2, playergender() ? "speak-princess" : "speak-prince");
626 addMessage(XLAT("Aww, poor %1... where is your family?", which));
627 }
628 else if(gold() == 0 && !specialmode)
629 addMessage(XLAT("Wow! %1! This trip should be worth it!", which));
630 else if(gold() == 1 && !specialmode)
631 addMessage(XLAT("For now, collect as much treasure as possible..."));
632 else if(gold() == 2 && !specialmode)
633 addMessage(XLAT("Prove yourself here, then find new lands, with new quests..."));
634 else if(!items[which] && itemclass(which) == IC_TREASURE)
635 addMessage(XLAT("You collect your first %1!", which));
636 else if(items[which] == 4 && maxgold() == U5-1 && !specialmode) {
637 addMessage(XLAT("You feel that %the2 become%s2 more dangerous.", which, c2->land));
638 addMessage(XLAT("With each %1 you collect...", which, c2->land));
639 }
640 else if(items[which] == 9 && maxgold() == 9 && !specialmode) {
641 if(inv::on) {
642 addMessage(XLAT("The treasure gives your magical powers!", c2->land));
643 if(!ISMOBILE)
644 addMessage(XLAT("Press 'i' to access your magical powers.", c2->land));
645 }
646 else
647 addMessage(XLAT("Are there any magical orbs in %the1?...", c2->land));
648 }
649 else if(items[which] == R10 && maxgold() == R10 && !specialmode && !inv::on) {
650 addMessage(XLAT("You feel that %the1 slowly become%s1 dangerous...", c2->land));
651 addMessage(XLAT("Better find some other place."));
652 }
653 else if(which == itHunting && items[itHunting] == 4 && !specialmode && !ISMOBWEB)
654 addMessage(XLAT("Hint: hold Alt to highlights enemies and other important features."));
655 else if(which == itSpice && items[itSpice] == U10*7/10 && !specialmode && isLandIngame(laHell))
656 addMessage(XLAT("You have a vision of the future, fighting demons in Hell..."));
657 else if(which == itSpice && items[itSpice] == U10-1 && !specialmode && isLandIngame(laRedRock))
658 addMessage(XLAT("You will be fighting red rock snakes, too..."));
659 else if(which == itKraken && items[itKraken] == U10-1 && !specialmode)
660 addMessage(XLAT("You feel that a magical weapon is waiting for you..."));
661 // else if(which == itFeather && items[itFeather] == 10)
662 // addMessage(XLAT("There should be a Palace somewhere nearby..."));
663 else if(which == itElixir && items[itElixir] == U5-1 && !specialmode)
664 addMessage(XLAT("With this Elixir, your life should be long and prosperous..."));
665 else if(which == itRuby && items[itRuby] == U5-1 && !specialmode && isLandIngame(laMountain)) {
666 addMessage(XLAT("You feel something strange about gravity here..."));
667 }
668 else if(which == itPalace && items[itPalace] == U5-1 && !specialmode && isLandIngame(laDungeon)) {
669 addMessage(XLAT("The rug depicts a man in a deep dungeon, unable to leave."));
670 }
671 else if(which == itFeather && items[itFeather] == 25-1 && !specialmode && inv::on && !ls::any_chaos())
672 addMessage(XLAT("You feel the presence of free saves on the Crossroads."));
673 else if(which == itHell && items[itHell] == 25-1 && !specialmode && inv::on && !ls::any_chaos())
674 addMessage(XLAT("You feel the Orbs of Yendor nearby..."));
675 else if(which == itHell && items[itHell] == 50-1 && !specialmode && inv::on && !ls::any_chaos())
676 addMessage(XLAT("You feel the Orbs of Yendor in the Crossroads..."));
677 else if(which == itHell && items[itHell] == 100-1 && !specialmode && inv::on && !ls::any_chaos())
678 addMessage(XLAT("You feel the Orbs of Yendor everywhere..."));
679 else if(which == itBone && items[itBone] % 25 == 24 && !specialmode && inv::on)
680 addMessage(XLAT("You have gained an offensive power!"));
681 else if(which == itHell && items[itHell] >= 100 && items[itHell] % 25 == 24 && !specialmode && inv::on)
682 addMessage(XLAT("A small reward for braving the Hell."));
683 else if(which == itIvory && items[itIvory] == U5-1 && !specialmode && (isLandIngame(laMountain) || isLandIngame(laDungeon))) {
684 addMessage(XLAT("You feel attuned to gravity, ready to face mountains and dungeons."));
685 }
686 else if(which == itBone && items[itBone] == U5+1 && !specialmode && isLandIngame(laHell))
687 addMessage(XLAT("The Necromancer's Totem contains hellish incantations..."));
688 else if(which == itStatue && items[itStatue] == U5+1 && !specialmode)
689 addMessage(XLAT("The inscriptions on the Statue of Cthulhu point you toward your destiny..."));
690 else if(which == itStatue && items[itStatue] == U5-1 && isLandIngame(laTemple))
691 addMessage(XLAT("There must be some temples of Cthulhu in R'Lyeh..."));
692 else if(which == itDiamond && items[itDiamond] == U10-2 && !specialmode)
693 addMessage(XLAT("Still, even greater treasures lie ahead..."));
694 else if(which == itFernFlower && items[itFernFlower] == U5-1 && isLandIngame(laEmerald))
695 addMessage(XLAT("You overheard Hedgehog Warriors talking about emeralds..."));
696 else if(which == itEmerald && items[itEmerald] == U5-1 && !specialmode && isLandIngame(laCamelot))
697 addMessage(XLAT("You overhear miners talking about a castle..."));
698 else if(which == itEmerald && items[itEmerald] == U5 && !specialmode && isLandIngame(laCamelot))
699 addMessage(XLAT("A castle in the Crossroads..."));
700 else if(which == itShard) ;
701 else {
702 int qty = (which == itBarrow) ? c2->landparam : 1;
703 string t;
704 if(which == itBarrow && items[which] < 25 && items[which] + qty >= 25)
705 t = XLAT("Your energy swords get stronger!");
706 else if(maxgold() < 25 && items[which] + qty >= 25)
707 t = XLAT("You feel even more attuned to the magic of this land!");
708 else t = XLAT("You collect %the1. (%2)", which, its(items[which]+qty));
709 addMessage(t);
710 }
711 }
712
itemHiddenFromSight(cell * c)713 EX bool itemHiddenFromSight(cell *c) {
714 return isWatery(c) && !items[itOrbInvis] && !(items[itOrbFish] && playerInWater())
715 && !(shmup::on && shmup::boatAt(c));
716 }
717
718 }
719