/*	$NetBSD: command5.c,v 1.6 2021/05/02 12:50:43 rillig Exp $	*/

/*
 * Copyright (c) 1983, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)com5.c	8.2 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: command5.c,v 1.6 2021/05/02 12:50:43 rillig Exp $");
#endif
#endif				/* not lint */

#include "extern.h"

void
kiss(void)
{
	while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount)
		continue;
	/* The goddess must be "taken" first if bathing. */
	if (wordtype[wordnumber] == NOUNS && wordvalue[wordnumber] == NORMGOD
	    && testbit(location[position].objects, BATHGOD)) {
		wordvalue[--wordnumber] = TAKE;
		cypher();
		return;
	}
	if (wordtype[wordnumber] == NOUNS) {
		if (testbit(location[position].objects,
		    wordvalue[wordnumber])) {
			pleasure++;
			printf("Kissed.\n");
			switch (wordvalue[wordnumber]) {
			case NORMGOD:
				switch (godready++) {
				case 0:
					printf("She squirms and avoids your ");
					puts("advances.");
					break;
				case 1:
					puts("She is coming around; she ");
					puts("didn't fight it as much.");
					break;
				case 2:
					puts("She's beginning to like it.");
					break;
				default:
					puts("She's gone limp.");

				}
				break;
			case NATIVE:
				printf("Her lips are warm and her body ");
				printf("robust.  She pulls you down to ");
				puts("the ground.");
				break;
			case TIMER:
				puts("The old man blushes.");
				break;
			case MAN:
				puts("The dwarf punches you in the kneecap.");
				break;
			default:
				pleasure--;
			}
		} else
			puts("I see nothing like that here.");
	} else
		puts("I'd prefer not to.");
}

void
love(void)
{
	int     n;

	while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount)
		continue;
	if (wordtype[wordnumber] == NOUNS) {
		if ((testbit(location[position].objects, BATHGOD) ||
		    testbit(location[position].objects, NORMGOD)) &&
		    wordvalue[wordnumber] == NORMGOD) {
			if (loved) {
				printf("Loved.\n");
				return;
			}
			if (godready >= 2) {
				printf("She cuddles up to you, and her mouth ");
				printf("starts to work:\n'That was my ");
				printf("sister's amulet.  The lovely ");
				printf("goddess, Purl, was she.  The Empire\n");
				printf("captured her just after the Darkness ");
				printf("came.  My other sister, Vert, was ");
				printf("killed\nby the Dark Lord himself.  ");
				printf("He took her amulet and warped its ");
				printf("power.\nYour quest was foretold by ");
				printf("my father before he died, but to get ");
				printf("the Dark Lord's\namulet you must use ");
				printf("cunning and skill.  I will leave you ");
				puts("my amulet,");
				printf("which you may use as you wish.  As ");
				printf("for me, I am the last goddess of ");
				printf("the\nwaters.  My father was the ");
				printf("Island King, and the rule is ");
				printf("rightfully mine.'\n\nShe pulls the ");
				puts("throne out into a large bed.");
				power++;
				pleasure += 15;
				ego++;
				if (card(injuries, NUMOFINJURIES)) {
					printf("Her kisses revive you; your ");
					printf("wounds are healed.\n");
					for (n = 0; n < NUMOFINJURIES; n++)
						injuries[n] = 0;
					WEIGHT = MAXWEIGHT;
					CUMBER = MAXCUMBER;
				}
				printf("Goddess:\n");
				if (!loved)
					setbit(location[position].objects,
					    MEDALION);
				loved = 1;
				ourtime += 10;
				printf("Loved.\n");
				zzz();
				return;
			} else {
				puts("You wish!");
				return;
			}
		}
		if (testbit(location[position].objects,
		    wordvalue[wordnumber])) {
			if (wordvalue[wordnumber] == NATIVE) {
				printf("The girl is easy prey.  She peels ");
				puts("off her sarong and indulges you.");
				power++;
				pleasure += 5;
				printf("Girl:\n");
				ourtime += 10;
				printf("Loved.\n");
				zzz();
			}
			if (wordvalue[wordnumber] == MAN ||
			    wordvalue[wordnumber] == BODY ||
			    wordvalue[wordnumber] == ELF ||
			    wordvalue[wordnumber] == TIMER)
				puts("Kinky!");
			else
				puts("It doesn't seem to work.");
		} else
			puts("Where's your lover?");
	} else
		puts("It doesn't seem to work.");
}

int
zzz(void)
{
	int     oldtime;
	int     n;
	int zzztime;

	zzztime = (3 * CYCLE) / 4;

	oldtime = ourtime;
	if ((snooze - ourtime) < zzztime) {
		ourtime += zzztime - (snooze - ourtime);
		printf("<zzz>");
		for (n = 0; n < ourtime - oldtime; n++)
			printf(".");
		printf("\n");
		snooze += 3 * (ourtime - oldtime);
		if (notes[LAUNCHED]) {
			fuel -= (ourtime - oldtime);
			if (location[position].down) {
				position = location[position].down;
				crash();
			} else
				notes[LAUNCHED] = 0;
		}
		if (OUTSIDE && rnd(100) < 50) {
			printf("You are awakened abruptly by the sound ");
			puts("of someone nearby.");
			switch (rnd(4)) {
			case 0:
				if (ucard(inven)) {
					n = rnd(NUMOFOBJECTS);
					while (!testbit(inven, n))
						n = rnd(NUMOFOBJECTS);
					clearbit(inven, n);
					if (n != AMULET && n != MEDALION &&
					    n != TALISMAN)
						setbit(
						    location[position].objects,
						    n);
					carrying -= objwt[n];
					encumber -= objcumber[n];
				}
				printf("A fiendish little Elf is stealing ");
				puts("your treasures!");
				fight(ELF, 10);
				break;
			case 1:
				setbit(location[position].objects, DEADWOOD);
				break;
			case 2:
				setbit(location[position].objects, HALBERD);
				break;
			default:
				break;
			}
		}
	} else
		return (0);
	return (1);
}

void
chime(void)
{
	if ((ourtime / CYCLE + 1) % 2 && OUTSIDE)
		switch ((ourtime % CYCLE) / (CYCLE / 7)) {
		case 0:
			puts("It is just after sunrise.");
			break;
		case 1:
			puts("It is early morning.");
			break;
		case 2:
			puts("It is late morning.");
			break;
		case 3:
			puts("It is near noon.");
			break;
		case 4:
			puts("It is early afternoon.");
			break;
		case 5:
			puts("It is late afternoon.");
			break;
		case 6:
			puts("It is near sunset.");
			break;
		}
	else if (OUTSIDE)
		switch ((ourtime % CYCLE) / (CYCLE / 7)) {
		case 0:
			puts("It is just after sunset.");
			break;
		case 1:
			puts("It is early evening.");
			break;
		case 2:
			puts("The evening is getting old.");
			break;
		case 3:
			puts("It is near midnight.");
			break;
		case 4:
			puts("These are the wee hours of the morning.");
			break;
		case 5:
			puts("The night is waning.");
			break;
		case 6:
			puts("It is almost morning.");
			break;
		}
	else
		puts("I can't tell the time in here.");
}

int
give(void)
{
	int     obj = -1, result = -1, person = 0, firstnumber, last1, last2;

	last1 = last2 = 0;
	firstnumber = wordnumber;
	while (wordtype[++wordnumber] != OBJECT &&
	    wordvalue[wordnumber] != AMULET &&
	    wordvalue[wordnumber] != MEDALION &&
	    wordvalue[wordnumber] != TALISMAN && wordnumber <= wordcount)
		continue;
	if (wordnumber <= wordcount) {
		obj = wordvalue[wordnumber];
		if (obj == EVERYTHING)
			wordtype[wordnumber] = -1;
		last1 = wordnumber;
	}
	wordnumber = firstnumber;
	while ((wordtype[++wordnumber] != NOUNS ||
	    wordvalue[wordnumber] == obj) && wordnumber <= wordcount);
	if (wordtype[wordnumber] == NOUNS) {
		person = wordvalue[wordnumber];
		last2 = wordnumber;
	}
	/* Setting wordnumber to last1 - 1 looks wrong if last1 is 0, e.g.,
	 * plain `give'.  However, detecting this case is liable to detect
	 * `give foo' as well, which would give a confusing error.  We
	 * need to make sure the -1 value can cause no problems if it arises.
	 * If in the below we get to the drop("Given") then drop will look
	 * at word 0 for an object to give, and fail, which is OK; then
	 * result will be -1 and we get to the end, where wordnumber gets
	 * set to something more sensible.  If we get to "I don't think
	 * that is possible" then again wordnumber is set to something
	 * sensible.  The wordnumber we leave with still isn't right if
	 * you include words the game doesn't know in your command, but
	 * that's no worse than what other commands than give do in
	 * the same place.  */
	wordnumber = last1 - 1;
	if (person && testbit(location[position].objects, person)) {
		if (person == NORMGOD && godready < 2 &&
		    !(obj == RING || obj == BRACELET))
			puts("The goddess won't look at you.");
		else
			result = drop("Given");
	} else {
		puts("I don't think that is possible.");
		wordnumber = max(last1, last2) + 1;
		return (0);
	}
	if (result != -1 && (testbit(location[position].objects, obj) ||
	    obj == AMULET || obj == MEDALION || obj == TALISMAN)) {
		clearbit(location[position].objects, obj);
		ourtime++;
		ego++;
		switch (person) {
		case NATIVE:
			puts("She accepts it shyly.");
			ego += 2;
			break;
		case NORMGOD:
			if (obj == RING || obj == BRACELET) {
				printf("She takes the charm and puts it on.");
				puts("  A little kiss on the cheek is");
				puts("your reward.");
				ego += 5;
				godready += 3;
			}
			if (obj == AMULET || obj == MEDALION ||
			    obj == TALISMAN) {
				win++;
				ego += 5;
				power -= 5;
				if (win >= 3) {
					printf("The powers of the earth are ");
					printf("now legitimate.  You have ");
					puts("destroyed the Darkness");
					printf("and restored the goddess to ");
					printf("her throne.  The entire ");
					puts("island celebrates with");
					printf("dancing and spring feasts.  ");
					printf("As a measure of her ");
					puts("gratitude, the goddess weds you");
					printf("in the late summer and ");
					printf("crowns you Prince Liverwort, ");
					puts("Lord of Fungus.");
					printf("\nBut, as the year wears on ");
					printf("and autumn comes along, you ");
					puts("become restless and");
					printf("yearn for adventure.  The ");
					printf("goddess, too, realizes that ");
					puts("the marriage can't last.");
					printf("She becomes bored and takes ");
					printf("several more natives as ");
					puts("husbands.  One evening,");
					printf("after having been out ");
					printf("drinking with the girls, she ");
					puts("kicks the throne particularly");
					printf("hard and wakes you up.  (If ");
					printf("you want to win this game, ");
					printf("you're going to have to\n");
					puts("shoot her!)");
					clearbit(location[position].objects,
					    MEDALION);
					wintime = ourtime;
				}
			}
			break;
		case TIMER:
			if (obj == COINS) {
				printf("He fingers the coins for a moment ");
				printf("and then looks up agape.  `Kind you ");
				puts("are and");
				printf("I mean to repay you as best I can.'  ");
				printf("Grabbing a pencil and cocktail ");
				puts("napkin...\n");
				printf("+-----------------------------------");
				printf("------------------------------------");
				printf("------+\n");
				printf("|				   xxxxxxxx\\				      |\n");
				printf("|				       xxxxx\\	CLIFFS			      |\n");
				printf("|		FOREST			  xxx\\				      |\n");
				printf("|				\\\\	     x\\        	OCEAN		      |\n");
				printf("|				||	       x\\			      |\n");
				printf("|				||  ROAD	x\\			      |\n");
				printf("|				||		x\\			      |\n");
				printf("|		SECRET		||	  .........			      |\n");
				printf("|		 - + -		||	   ........			      |\n");
				printf("|		ENTRANCE	||		...      BEACH		      |\n");
				printf("|				||		...		  E	      |\n");
				printf("|				||		...		  |	      |\n");
				printf("|				//		...	    N <-- + --- S     |\n");
				printf("|		PALM GROVE     //		...		  |	      |\n");
				printf("|			      //		...		  W	      |\n");
				printf("+");
				printf("---------------------------------");
				printf("---------------------------------");
				printf("-----------+\n");
				printf("\n`This map shows a secret entrance ");
				puts("to the catacombs.");
				printf("You will know when you arrive ");
				printf("because I left an old pair of shoes ");
				puts("there.'");
			}
			break;
		}
	}
	wordnumber = max(last1, last2) + 1;
	return (firstnumber);
}
