1 1.9 dholland /* $NetBSD: ring.c,v 1.9 2008/01/14 03:50:02 dholland Exp $ */ 2 1.3 cgd 3 1.1 cgd /* 4 1.3 cgd * Copyright (c) 1988, 1993 5 1.3 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * This code is derived from software contributed to Berkeley by 8 1.1 cgd * Timothy C. Stoehr. 9 1.1 cgd * 10 1.1 cgd * Redistribution and use in source and binary forms, with or without 11 1.1 cgd * modification, are permitted provided that the following conditions 12 1.1 cgd * are met: 13 1.1 cgd * 1. Redistributions of source code must retain the above copyright 14 1.1 cgd * notice, this list of conditions and the following disclaimer. 15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 cgd * notice, this list of conditions and the following disclaimer in the 17 1.1 cgd * documentation and/or other materials provided with the distribution. 18 1.6 agc * 3. Neither the name of the University nor the names of its contributors 19 1.1 cgd * may be used to endorse or promote products derived from this software 20 1.1 cgd * without specific prior written permission. 21 1.1 cgd * 22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 cgd * SUCH DAMAGE. 33 1.1 cgd */ 34 1.1 cgd 35 1.4 lukem #include <sys/cdefs.h> 36 1.1 cgd #ifndef lint 37 1.3 cgd #if 0 38 1.3 cgd static char sccsid[] = "@(#)ring.c 8.1 (Berkeley) 5/31/93"; 39 1.3 cgd #else 40 1.9 dholland __RCSID("$NetBSD: ring.c,v 1.9 2008/01/14 03:50:02 dholland Exp $"); 41 1.3 cgd #endif 42 1.1 cgd #endif /* not lint */ 43 1.1 cgd 44 1.1 cgd /* 45 1.1 cgd * ring.c 46 1.1 cgd * 47 1.1 cgd * This source herein may be modified and/or distributed by anybody who 48 1.1 cgd * so desires, with the following restrictions: 49 1.1 cgd * 1.) No portion of this notice shall be removed. 50 1.1 cgd * 2.) Credit shall not be taken for the creation of this source. 51 1.1 cgd * 3.) This code is not to be traded, sold, or used for personal 52 1.1 cgd * gain or profit. 53 1.1 cgd * 54 1.1 cgd */ 55 1.1 cgd 56 1.1 cgd #include "rogue.h" 57 1.1 cgd 58 1.9 dholland static const char left_or_right[] = "left or right hand?"; 59 1.9 dholland static const char no_ring[] = "there's no ring on that hand"; 60 1.9 dholland 61 1.1 cgd short stealthy; 62 1.1 cgd short r_rings; 63 1.1 cgd short add_strength; 64 1.1 cgd short e_rings; 65 1.1 cgd short regeneration; 66 1.1 cgd short ring_exp; 67 1.1 cgd short auto_search; 68 1.1 cgd boolean r_teleport; 69 1.1 cgd boolean r_see_invisible; 70 1.1 cgd boolean sustain_strength; 71 1.1 cgd boolean maintain_armor; 72 1.1 cgd 73 1.4 lukem void 74 1.9 dholland put_on_ring(void) 75 1.1 cgd { 76 1.1 cgd short ch; 77 1.1 cgd char desc[DCOLS]; 78 1.1 cgd object *ring; 79 1.1 cgd 80 1.1 cgd if (r_rings == 2) { 81 1.7 dholland messagef(0, "wearing two rings already"); 82 1.1 cgd return; 83 1.1 cgd } 84 1.1 cgd if ((ch = pack_letter("put on what?", RING)) == CANCEL) { 85 1.1 cgd return; 86 1.1 cgd } 87 1.1 cgd if (!(ring = get_letter_object(ch))) { 88 1.7 dholland messagef(0, "no such item."); 89 1.1 cgd return; 90 1.1 cgd } 91 1.1 cgd if (!(ring->what_is & RING)) { 92 1.7 dholland messagef(0, "that's not a ring"); 93 1.1 cgd return; 94 1.1 cgd } 95 1.1 cgd if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) { 96 1.7 dholland messagef(0, "that ring is already being worn"); 97 1.1 cgd return; 98 1.1 cgd } 99 1.1 cgd if (r_rings == 1) { 100 1.1 cgd ch = (rogue.left_ring ? 'r' : 'l'); 101 1.1 cgd } else { 102 1.7 dholland messagef(0, "%s", left_or_right); 103 1.1 cgd do { 104 1.1 cgd ch = rgetchar(); 105 1.1 cgd } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') && 106 1.1 cgd (ch != '\r')); 107 1.1 cgd } 108 1.1 cgd if ((ch != 'l') && (ch != 'r')) { 109 1.1 cgd check_message(); 110 1.1 cgd return; 111 1.1 cgd } 112 1.1 cgd if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) { 113 1.1 cgd check_message(); 114 1.7 dholland messagef(0, "there's already a ring on that hand"); 115 1.1 cgd return; 116 1.1 cgd } 117 1.1 cgd if (ch == 'l') { 118 1.1 cgd do_put_on(ring, 1); 119 1.1 cgd } else { 120 1.1 cgd do_put_on(ring, 0); 121 1.1 cgd } 122 1.1 cgd ring_stats(1); 123 1.1 cgd check_message(); 124 1.7 dholland get_desc(ring, desc, sizeof(desc)); 125 1.7 dholland messagef(0, "%s", desc); 126 1.8 dholland (void)reg_move(); 127 1.1 cgd } 128 1.1 cgd 129 1.1 cgd /* 130 1.1 cgd * Do not call ring_stats() from within do_put_on(). It will cause 131 1.1 cgd * serious problems when do_put_on() is called from read_pack() in restore(). 132 1.1 cgd */ 133 1.1 cgd 134 1.4 lukem void 135 1.9 dholland do_put_on(object *ring, boolean on_left) 136 1.1 cgd { 137 1.1 cgd if (on_left) { 138 1.1 cgd ring->in_use_flags |= ON_LEFT_HAND; 139 1.1 cgd rogue.left_ring = ring; 140 1.1 cgd } else { 141 1.1 cgd ring->in_use_flags |= ON_RIGHT_HAND; 142 1.1 cgd rogue.right_ring = ring; 143 1.1 cgd } 144 1.1 cgd } 145 1.1 cgd 146 1.4 lukem void 147 1.9 dholland remove_ring(void) 148 1.1 cgd { 149 1.1 cgd boolean left = 0, right = 0; 150 1.1 cgd short ch; 151 1.1 cgd char buf[DCOLS]; 152 1.1 cgd object *ring; 153 1.1 cgd 154 1.4 lukem ring = NULL; 155 1.1 cgd if (r_rings == 0) { 156 1.1 cgd inv_rings(); 157 1.1 cgd } else if (rogue.left_ring && !rogue.right_ring) { 158 1.1 cgd left = 1; 159 1.1 cgd } else if (!rogue.left_ring && rogue.right_ring) { 160 1.1 cgd right = 1; 161 1.1 cgd } else { 162 1.7 dholland messagef(0, "%s", left_or_right); 163 1.1 cgd do { 164 1.1 cgd ch = rgetchar(); 165 1.1 cgd } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && 166 1.1 cgd (ch != '\n') && (ch != '\r')); 167 1.1 cgd left = (ch == 'l'); 168 1.1 cgd right = (ch == 'r'); 169 1.1 cgd check_message(); 170 1.1 cgd } 171 1.1 cgd if (left || right) { 172 1.1 cgd if (left) { 173 1.1 cgd if (rogue.left_ring) { 174 1.1 cgd ring = rogue.left_ring; 175 1.1 cgd } else { 176 1.7 dholland messagef(0, "%s", no_ring); 177 1.1 cgd } 178 1.1 cgd } else { 179 1.1 cgd if (rogue.right_ring) { 180 1.1 cgd ring = rogue.right_ring; 181 1.1 cgd } else { 182 1.7 dholland messagef(0, "%s", no_ring); 183 1.1 cgd } 184 1.1 cgd } 185 1.1 cgd if (ring->is_cursed) { 186 1.7 dholland messagef(0, "%s", curse_message); 187 1.1 cgd } else { 188 1.1 cgd un_put_on(ring); 189 1.7 dholland get_desc(ring, buf, sizeof(buf)); 190 1.7 dholland messagef(0, "removed %s", buf); 191 1.8 dholland (void)reg_move(); 192 1.1 cgd } 193 1.1 cgd } 194 1.1 cgd } 195 1.1 cgd 196 1.4 lukem void 197 1.9 dholland un_put_on(object *ring) 198 1.1 cgd { 199 1.1 cgd if (ring && (ring->in_use_flags & ON_LEFT_HAND)) { 200 1.1 cgd ring->in_use_flags &= (~ON_LEFT_HAND); 201 1.9 dholland rogue.left_ring = NULL; 202 1.1 cgd } else if (ring && (ring->in_use_flags & ON_RIGHT_HAND)) { 203 1.1 cgd ring->in_use_flags &= (~ON_RIGHT_HAND); 204 1.9 dholland rogue.right_ring = NULL; 205 1.1 cgd } 206 1.1 cgd ring_stats(1); 207 1.1 cgd } 208 1.1 cgd 209 1.4 lukem void 210 1.9 dholland gr_ring(object *ring, boolean assign_wk) 211 1.1 cgd { 212 1.1 cgd ring->what_is = RING; 213 1.1 cgd if (assign_wk) { 214 1.1 cgd ring->which_kind = get_rand(0, (RINGS - 1)); 215 1.1 cgd } 216 1.1 cgd ring->class = 0; 217 1.1 cgd 218 1.1 cgd switch(ring->which_kind) { 219 1.1 cgd /* 220 1.1 cgd case STEALTH: 221 1.1 cgd break; 222 1.1 cgd case SLOW_DIGEST: 223 1.1 cgd break; 224 1.1 cgd case REGENERATION: 225 1.1 cgd break; 226 1.1 cgd case R_SEE_INVISIBLE: 227 1.1 cgd break; 228 1.1 cgd case SUSTAIN_STRENGTH: 229 1.1 cgd break; 230 1.1 cgd case R_MAINTAIN_ARMOR: 231 1.1 cgd break; 232 1.1 cgd case SEARCHING: 233 1.1 cgd break; 234 1.1 cgd */ 235 1.1 cgd case R_TELEPORT: 236 1.1 cgd ring->is_cursed = 1; 237 1.1 cgd break; 238 1.1 cgd case ADD_STRENGTH: 239 1.1 cgd case DEXTERITY: 240 1.8 dholland while ((ring->class = (get_rand(0, 4) - 2)) == 0) 241 1.8 dholland ; 242 1.1 cgd ring->is_cursed = (ring->class < 0); 243 1.1 cgd break; 244 1.1 cgd case ADORNMENT: 245 1.1 cgd ring->is_cursed = coin_toss(); 246 1.1 cgd break; 247 1.1 cgd } 248 1.1 cgd } 249 1.1 cgd 250 1.4 lukem void 251 1.9 dholland inv_rings(void) 252 1.1 cgd { 253 1.1 cgd char buf[DCOLS]; 254 1.1 cgd 255 1.1 cgd if (r_rings == 0) { 256 1.7 dholland messagef(0, "not wearing any rings"); 257 1.1 cgd } else { 258 1.1 cgd if (rogue.left_ring) { 259 1.7 dholland get_desc(rogue.left_ring, buf, sizeof(buf)); 260 1.7 dholland messagef(0, "%s", buf); 261 1.1 cgd } 262 1.1 cgd if (rogue.right_ring) { 263 1.7 dholland get_desc(rogue.right_ring, buf, sizeof(buf)); 264 1.7 dholland messagef(0, "%s", buf); 265 1.1 cgd } 266 1.1 cgd } 267 1.1 cgd if (wizard) { 268 1.7 dholland messagef(0, "ste %d, r_r %d, e_r %d, r_t %d, s_s %d, a_s %d, reg %d, r_e %d, s_i %d, m_a %d, aus %d", 269 1.1 cgd stealthy, r_rings, e_rings, r_teleport, sustain_strength, 270 1.1 cgd add_strength, regeneration, ring_exp, r_see_invisible, 271 1.1 cgd maintain_armor, auto_search); 272 1.1 cgd } 273 1.1 cgd } 274 1.1 cgd 275 1.4 lukem void 276 1.9 dholland ring_stats(boolean pr) 277 1.1 cgd { 278 1.1 cgd short i; 279 1.1 cgd object *ring; 280 1.1 cgd 281 1.1 cgd stealthy = 0; 282 1.1 cgd r_rings = 0; 283 1.1 cgd e_rings = 0; 284 1.1 cgd r_teleport = 0; 285 1.1 cgd sustain_strength = 0; 286 1.1 cgd add_strength = 0; 287 1.1 cgd regeneration = 0; 288 1.1 cgd ring_exp = 0; 289 1.1 cgd r_see_invisible = 0; 290 1.1 cgd maintain_armor = 0; 291 1.1 cgd auto_search = 0; 292 1.1 cgd 293 1.1 cgd for (i = 0; i < 2; i++) { 294 1.1 cgd if (!(ring = ((i == 0) ? rogue.left_ring : rogue.right_ring))) { 295 1.1 cgd continue; 296 1.1 cgd } 297 1.1 cgd r_rings++; 298 1.1 cgd e_rings++; 299 1.1 cgd switch(ring->which_kind) { 300 1.1 cgd case STEALTH: 301 1.1 cgd stealthy++; 302 1.1 cgd break; 303 1.1 cgd case R_TELEPORT: 304 1.1 cgd r_teleport = 1; 305 1.1 cgd break; 306 1.1 cgd case REGENERATION: 307 1.1 cgd regeneration++; 308 1.1 cgd break; 309 1.1 cgd case SLOW_DIGEST: 310 1.1 cgd e_rings -= 2; 311 1.1 cgd break; 312 1.1 cgd case ADD_STRENGTH: 313 1.1 cgd add_strength += ring->class; 314 1.1 cgd break; 315 1.1 cgd case SUSTAIN_STRENGTH: 316 1.1 cgd sustain_strength = 1; 317 1.1 cgd break; 318 1.1 cgd case DEXTERITY: 319 1.1 cgd ring_exp += ring->class; 320 1.1 cgd break; 321 1.1 cgd case ADORNMENT: 322 1.1 cgd break; 323 1.1 cgd case R_SEE_INVISIBLE: 324 1.1 cgd r_see_invisible = 1; 325 1.1 cgd break; 326 1.1 cgd case MAINTAIN_ARMOR: 327 1.1 cgd maintain_armor = 1; 328 1.1 cgd break; 329 1.1 cgd case SEARCHING: 330 1.1 cgd auto_search += 2; 331 1.1 cgd break; 332 1.1 cgd } 333 1.1 cgd } 334 1.1 cgd if (pr) { 335 1.1 cgd print_stats(STAT_STRENGTH); 336 1.1 cgd relight(); 337 1.1 cgd } 338 1.1 cgd } 339