1/*	$OpenBSD: command1.c,v 1.1 2020/12/15 00:38:18 daniel Exp $	*/
2/*	$NetBSD: com1.c,v 1.3 1995/03/21 15:06:51 cgd Exp $	*/
3
4/*
5 * Copyright (c) 1983, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <unistd.h>
36
37#include "extern.h"
38
39int
40moveplayer(int thataway, int token)
41{
42	wordnumber++;
43	if ((!notes[CANTMOVE] && !notes[LAUNCHED]) ||
44	    TestBit(location[position].objects, LAND) ||
45	    (fuel > 0 && notes[LAUNCHED])) {
46		if (thataway) {
47			position = thataway;
48			newway(token);
49			ourtime++;
50		} else {
51			puts("You can't go this way.");
52			newway(token);
53			whichway(location[position]);
54			return (0);
55		}
56	} else
57		if (notes[CANTMOVE] && !notes[LAUNCHED])
58			puts("You aren't able to move; you better drop something.");
59		else
60			puts("You are out of fuel; now you will rot in space forever!");
61	return (1);
62}
63
64/*
65 * Converts day to night and vice versa.
66 * Day objects are permanent.  Night objects
67 * are added at dusk, and subtracted at dawn.
68 */
69void
70convert(int tothis)
71{
72	const struct objs *p;
73	unsigned int i, j;
74
75	if (tothis == TONIGHT) {
76		for (i = 1; i <= NUMOFROOMS; i++)
77			for (j = 0; j < NUMOFWORDS; j++)
78				nightfile[i].objects[j] = dayfile[i].objects[j];
79		for (p = nightobjs; p->room != 0; p++)
80			SetBit(nightfile[p->room].objects, p->obj);
81		location = nightfile;
82	} else {
83		for (i = 1; i <= NUMOFROOMS; i++)
84			for (j = 0; j < NUMOFWORDS; j++)
85				dayfile[i].objects[j] = nightfile[i].objects[j];
86		for (p = nightobjs; p->room != 0; p++)
87			ClearBit(dayfile[p->room].objects, p->obj);
88		location = dayfile;
89	}
90}
91
92void
93news(void)
94{
95	int     n;
96	int     hurt;
97
98	if (ourtime > 30 && position < 32) {
99		puts("An explosion of shuddering magnitude splinters bulkheads and");
100		puts("ruptures the battlestar's hull.  You are sucked out into the");
101		puts("frozen void of space and killed.");
102		die(0);
103	}
104	if (ourtime > 20 && position < 32)
105		puts("Explosions rock the battlestar.");
106	if (ourtime > snooze) {
107		puts("You drop from exhaustion...");
108		zzz();
109	}
110	if (ourtime > snooze - 5)
111		puts("You're getting tired.");
112	if (ourtime > (rythmn + CYCLE)) {
113		if (location == nightfile) {
114			convert(TODAY);
115			if (OUTSIDE && ourtime - rythmn - CYCLE < 10) {
116				puts("Dew lit sunbeams stretch out from a watery sunrise and herald the dawn.");
117				puts("You awake from a misty dream-world into stark reality.");
118				puts("It is day.");
119			}
120		} else {
121			convert(TONIGHT);
122			ClearBit(location[POOLS].objects, BATHGOD);
123			if (OUTSIDE && ourtime - rythmn - CYCLE < 10) {
124				puts("The dying sun sinks into the ocean, leaving a blood-stained sunset.");
125				puts("The sky slowly fades from orange to violet to black.  A few stars");
126				puts("flicker on, and it is night.");
127				puts("The world seems completely different at night.");
128			}
129		}
130		rythmn = ourtime - ourtime % CYCLE;
131	}
132	if (!tempwiz)
133		if ((TestBit(inven, TALISMAN) || TestBit(wear, TALISMAN)) && (TestBit(inven, MEDALION) || TestBit(wear, MEDALION)) && (TestBit(inven, AMULET) || TestBit(wear, AMULET))) {
134			tempwiz = 1;
135			puts("The three amulets glow and reenforce each other in power.\nYou are now a wizard.");
136		}
137	if (TestBit(location[position].objects, ELF)) {
138		printf("%s\n", objdes[ELF]);
139		fight(ELF, rnd(30));
140	}
141	if (TestBit(location[position].objects, DARK)) {
142		printf("%s\n", objdes[DARK]);
143		fight(DARK, 100);
144	}
145	if (TestBit(location[position].objects, WOODSMAN)) {
146		printf("%s\n", objdes[WOODSMAN]);
147		fight(WOODSMAN, 50);
148	}
149	switch (position) {
150
151	case 267:
152	case 257:		/* entering a cave */
153	case 274:
154	case 246:
155		notes[CANTSEE] = 1;
156		break;
157	case 160:
158	case 216:		/* leaving a cave */
159	case 230:
160	case 231:
161	case 232:
162		notes[CANTSEE] = 0;
163		break;
164	}
165	if (TestBit(location[position].objects, GIRL))
166		meetgirl = 1;
167	if (meetgirl && CYCLE * 1.5 - ourtime < 10) {
168		SetBit(location[GARDEN].objects, GIRLTALK);
169		SetBit(location[GARDEN].objects, LAMPON);
170		SetBit(location[GARDEN].objects, ROPE);
171	}
172	if (position == DOCK && (beenthere[position] || ourtime > CYCLE)) {
173		ClearBit(location[DOCK].objects, GIRL);
174		ClearBit(location[DOCK].objects, MAN);
175	}
176	if (meetgirl && ourtime - CYCLE * 1.5 > 10) {
177		ClearBit(location[GARDEN].objects, GIRLTALK);
178		ClearBit(location[GARDEN].objects, LAMPON);
179		ClearBit(location[GARDEN].objects, ROPE);
180		meetgirl = 0;
181	}
182	if (TestBit(location[position].objects, CYLON)) {
183		puts("Oh my God, you're being shot at by an alien spacecraft!");
184		printf("The targeting computer says we have %d seconds to attack!\n",
185		    ourclock);
186		fflush(stdout);
187		sleep(1);
188		if (!visual()) {
189			hurt = rnd(NUMOFINJURIES);
190			injuries[hurt] = 1;
191			puts("Laser blasts sear the cockpit, and the alien veers off in a victory roll.");
192			puts("The viper shudders under a terrible explosion.");
193			printf("I'm afraid you have suffered %s.\n", ouch[hurt]);
194		} else
195			ClearBit(location[position].objects, CYLON);
196	}
197	if (injuries[SKULL] && injuries[INCISE] && injuries[NECK]) {
198		puts("I'm afraid you have suffered fatal injuries.");
199		die(0);
200	}
201	for (n = 0; n < NUMOFINJURIES; n++)
202		if (injuries[n] == 1) {
203			injuries[n] = 2;
204			if (WEIGHT > 5)
205				WEIGHT -= 5;
206			else
207				WEIGHT = 0;
208		}
209	if (injuries[ARM] == 2) {
210		if (CUMBER > 5)
211			CUMBER -= 5;
212		else
213			CUMBER = 0;
214		injuries[ARM]++;
215	}
216	if (injuries[RIBS] == 2) {
217		if (CUMBER > 2)
218			CUMBER -= 2;
219		else
220			CUMBER = 0;
221		injuries[RIBS]++;
222	}
223	if (injuries[SPINE] == 2) {
224		WEIGHT = 0;
225		injuries[SPINE]++;
226	}
227	if (carrying > WEIGHT || encumber > CUMBER)
228		notes[CANTMOVE] = 1;
229	else
230		notes[CANTMOVE] = 0;
231}
232
233void
234crash(void)
235{
236	int     hurt1, hurt2;
237
238	fuel--;
239	if (!location[position].flyhere ||
240	    (TestBit(location[position].objects, LAND) && fuel <= 0)) {
241		if (!location[position].flyhere)
242			puts("You're flying too low.  We're going to crash!");
243		else {
244			puts("You're out of fuel.  We'll have to crash land!");
245			if (!location[position].down) {
246				puts("Your viper strikes the ground and explodes into fiery fragments.");
247				puts("Thick black smoke billows up from the wreckage.");
248				die(0);
249			}
250			position = location[position].down;
251		}
252		notes[LAUNCHED] = 0;
253		SetBit(location[position].objects, CRASH);
254		ourtime += rnd(CYCLE / 4);
255		puts("The viper explodes into the ground and you lose consciousness...");
256		zzz();
257		hurt1 = rnd(NUMOFINJURIES - 2) + 2;
258		hurt2 = rnd(NUMOFINJURIES - 2) + 2;
259		injuries[hurt1] = 1;
260		injuries[hurt2] = 1;
261		injuries[0] = 1;	/* abrasions */
262		injuries[1] = 1;	/* lacerations */
263		printf("I'm afraid you have suffered %s and %s.\n",
264		    ouch[hurt1], ouch[hurt2]);
265	}
266}
267
268void
269newlocation(void)
270{
271	news();
272	if (beenthere[position] <= ROOMDESC)
273	     beenthere[position]++;
274	if (notes[LAUNCHED])
275		crash();	/* decrements fuel & crash */
276	if (matchlight) {
277		puts("Your match splutters out.");
278		matchlight = 0;
279	}
280	if (!notes[CANTSEE] || TestBit(inven, LAMPON) ||
281	    TestBit(location[position].objects, LAMPON)) {
282		writedes();
283		printobjs();
284	} else
285		puts("It's too dark to see anything in here!");
286	whichway(location[position]);
287}
288