Compatibility with old-but-newer-than-C89 compilers.
[rogue-pphs.git] / romance.c
1 /*
2 * Functions for dealing with problems of the heart
3 *
4 * @(#)romance.c 3.2 (Berkeley) 6/15/81
5 *
6 * Rogue: Exploring the Cavern of Cuties
7 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include "curses.h"
14 #include <ctype.h>
15 #include <string.h>
16 #include "rogue.h"
17
18 count_bits_set(v)
19 unsigned v; // count bits set in this (32-bit value)
20 {
21 unsigned c = v - ((v >> 1) & 0x55555555);
22 c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
23 c = ((c >> 4) + c) & 0x0F0F0F0F;
24 c = ((c >> 8) + c) & 0x00FF00FF;
25 c = ((c >> 16) + c) & 0x0000FFFF;
26 return c;
27 }
28
29 /*
30 * flirt:
31 * Make eyes in the given direction
32 */
33
34 flirt(ydelta, xdelta)
35 int ydelta, xdelta;
36 {
37 register struct linked_list *mob;
38 struct object obj = {};
39
40 obj.o_pos = hero;
41 obj.o_type = '~';
42 do_motion(&obj, ydelta, xdelta);
43 mvwaddch(cw, hero.y, hero.x, PLAYER);
44 if ((mob = find_mons(obj.o_pos.y, obj.o_pos.x)) == NULL)
45 {
46 const char *msgs[] = {
47 "You wink at nothing in particular.",
48 "You smile suggestively at the wall.",
49 "Unprompted, you suddenly blush.",
50 };
51 msg(rndchoice(msgs));
52 }
53 else
54 {
55 register struct thing *tp = (struct thing *) ldata(mob);
56 int attr = count_bits_set(tp->t_stats.s_ont ^ player.t_stats.s_ont);
57 attr += tp->t_stats.s_int - 2;
58 if (rnd(NUM_FEATURES) < attr)
59 {
60 tp->t_stats.s_int++;
61 const char *msgs[] = {
62 "The %s smiles back at you.",
63 "You catch the %s staring at you out of the corner of eir eye.",
64 "The %s blushes and waves cautiously.",
65 };
66 msg(rndchoice(msgs), killname(tp->t_type));
67 }
68 else if (attr <= 0)
69 {
70 tp->t_stats.s_int--;
71 const char *msgs[] = {
72 "The %s scowls at you.",
73 "The %s tells you to stop it.",
74 "The %s is sick of your crap.",
75 };
76 msg(rndchoice(msgs), killname(tp->t_type));
77 wake_monster(tp->t_pos.y, tp->t_pos.x);
78 }
79 else
80 {
81 const char *msgs[] = {
82 "The %s ignores you.",
83 "The %s is completely uninterested in you.",
84 "The %s acts like it can't hear you.",
85 "The %s doesn't care.",
86 };
87 msg(rndchoice(msgs), killname(tp->t_type));
88 }
89 }
90 }
91
92 gift(ydelta, xdelta)
93 int ydelta, xdelta;
94 {
95 register struct linked_list *obj, *nobj;
96 register struct linked_list *mob;
97 register struct object *op;
98 register struct thing *tp;
99 register int liking;
100
101 if ((mob = find_mons(hero.y + ydelta, hero.x + xdelta)) == NULL)
102 {
103 msg("There's no-one around here.");
104 return(0);
105 }
106 tp = (struct thing *) ldata(mob);
107
108 if ((obj = get_item("give", 0)) == NULL)
109 return;
110 op = (struct object *) ldata(obj);
111 if (!dropcheck(op))
112 return;
113
114 liking = count_bits_set(
115 hash(op->o_type * op->o_which) & tp->t_stats.s_ont) - 1;
116 if ((liking == 0 || liking == -1)
117 || liking > 0 && tp->t_stats.s_int <= MAYBE_INTERESTED)
118 {
119 const char *msgs[] = {
120 "The %s ignores %s",
121 "The %s doesn't care for %s",
122 "The %s isn't interested in %s",
123 };
124 msg(rndchoice(msgs), killname(tp->t_type), inv_name(op, TRUE));
125 return;
126 }
127 else if (liking > 0)
128 {
129 const char *msgs[] = {
130 "The %s accepts %s.",
131 "The %s smiles and takes %s.",
132 };
133 msg(rndchoice(msgs), killname(tp->t_type), inv_name(op, TRUE));
134 tp->t_stats.s_int += liking * 10;
135 }
136 else
137 {
138 const char *msgs[] = {
139 "The %s throws away %s.",
140 "The %s breaks %s.",
141 "The %s hates %s.",
142 };
143 msg(rndchoice(msgs), killname(tp->t_type), inv_name(op, TRUE));
144 tp->t_stats.s_int -= liking * 2;
145 wake_monster(tp->t_pos.y, tp->t_pos.x);
146 }
147
148 /*
149 * Take it out of the pack
150 */
151 if (op->o_count >= 2 && op->o_type != WEAPON)
152 {
153 nobj = new_item(sizeof *op);
154 op->o_count--;
155 op = (struct object *) ldata(nobj);
156 *op = *((struct object *) ldata(obj));
157 op->o_count = 1;
158 obj = nobj;
159 if (op->o_group != 0)
160 inpack++;
161 }
162 else
163 detach(pack, obj);
164 inpack--;
165 }
166
167 embrace()
168 {
169 register struct thing *tp = NULL;
170 register int liking;
171 register int dx, dy;
172
173 for (dx = -1; dx <= 1; ++dx)
174 {
175 for (dy = -1; dy <= 1; ++dy)
176 {
177 register struct linked_list *mob;
178 if ((mob = find_mons(hero.y + dy, hero.x + dx)))
179 {
180 register struct thing *atp = (struct thing *)ldata(mob);
181 if (!tp || atp->t_stats.s_int > tp->t_stats.s_int)
182 tp = atp;
183 }
184 }
185 }
186
187
188 if (tp == NULL)
189 {
190 msg("You wrap your arms around yourself.");
191 return;
192 }
193 else if (tp->t_stats.s_int < READY)
194 {
195 if (tp->t_stats.s_int > 0)
196 tp->t_stats.s_int /= 2;
197 else
198 tp->t_stats.s_int--;
199 msg("The %s dodges out of the way.", killname(tp->t_type));
200 return;
201 }
202
203 if (amulet)
204 {
205 total_winner(tp->t_type);
206 }
207 else
208 {
209 mostly_winner(tp->t_type);
210 }
211 }