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