1 /* $NetBSD: ring.c,v 1.5 1998/11/10 13:01:32 hubertf 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 #include <sys/cdefs.h> 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)ring.c 8.1 (Berkeley) 5/31/93"; 43 #else 44 __RCSID("$NetBSD: ring.c,v 1.5 1998/11/10 13:01:32 hubertf Exp $"); 45 #endif 46 #endif /* not lint */ 47 48 /* 49 * ring.c 50 * 51 * This source herein may be modified and/or distributed by anybody who 52 * so desires, with the following restrictions: 53 * 1.) No portion of this notice shall be removed. 54 * 2.) Credit shall not be taken for the creation of this source. 55 * 3.) This code is not to be traded, sold, or used for personal 56 * gain or profit. 57 * 58 */ 59 60 #include "rogue.h" 61 62 const char *left_or_right = "left or right hand?"; 63 const char *no_ring = "there's no ring on that hand"; 64 short stealthy; 65 short r_rings; 66 short add_strength; 67 short e_rings; 68 short regeneration; 69 short ring_exp; 70 short auto_search; 71 boolean r_teleport; 72 boolean r_see_invisible; 73 boolean sustain_strength; 74 boolean maintain_armor; 75 76 void 77 put_on_ring() 78 { 79 short ch; 80 char desc[DCOLS]; 81 object *ring; 82 83 if (r_rings == 2) { 84 message("wearing two rings already", 0); 85 return; 86 } 87 if ((ch = pack_letter("put on what?", RING)) == CANCEL) { 88 return; 89 } 90 if (!(ring = get_letter_object(ch))) { 91 message("no such item.", 0); 92 return; 93 } 94 if (!(ring->what_is & RING)) { 95 message("that's not a ring", 0); 96 return; 97 } 98 if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) { 99 message("that ring is already being worn", 0); 100 return; 101 } 102 if (r_rings == 1) { 103 ch = (rogue.left_ring ? 'r' : 'l'); 104 } else { 105 message(left_or_right, 0); 106 do { 107 ch = rgetchar(); 108 } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') && 109 (ch != '\r')); 110 } 111 if ((ch != 'l') && (ch != 'r')) { 112 check_message(); 113 return; 114 } 115 if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) { 116 check_message(); 117 message("there's already a ring on that hand", 0); 118 return; 119 } 120 if (ch == 'l') { 121 do_put_on(ring, 1); 122 } else { 123 do_put_on(ring, 0); 124 } 125 ring_stats(1); 126 check_message(); 127 get_desc(ring, desc); 128 message(desc, 0); 129 (void) reg_move(); 130 } 131 132 /* 133 * Do not call ring_stats() from within do_put_on(). It will cause 134 * serious problems when do_put_on() is called from read_pack() in restore(). 135 */ 136 137 void 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 void 152 remove_ring() 153 { 154 boolean left = 0, right = 0; 155 short ch; 156 char buf[DCOLS]; 157 object *ring; 158 159 ring = NULL; 160 if (r_rings == 0) { 161 inv_rings(); 162 } else if (rogue.left_ring && !rogue.right_ring) { 163 left = 1; 164 } else if (!rogue.left_ring && rogue.right_ring) { 165 right = 1; 166 } else { 167 message(left_or_right, 0); 168 do { 169 ch = rgetchar(); 170 } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && 171 (ch != '\n') && (ch != '\r')); 172 left = (ch == 'l'); 173 right = (ch == 'r'); 174 check_message(); 175 } 176 if (left || right) { 177 if (left) { 178 if (rogue.left_ring) { 179 ring = rogue.left_ring; 180 } else { 181 message(no_ring, 0); 182 } 183 } else { 184 if (rogue.right_ring) { 185 ring = rogue.right_ring; 186 } else { 187 message(no_ring, 0); 188 } 189 } 190 if (ring->is_cursed) { 191 message(curse_message, 0); 192 } else { 193 un_put_on(ring); 194 (void) strcpy(buf, "removed "); 195 get_desc(ring, buf + 8); 196 message(buf, 0); 197 (void) reg_move(); 198 } 199 } 200 } 201 202 void 203 un_put_on(ring) 204 object *ring; 205 { 206 if (ring && (ring->in_use_flags & ON_LEFT_HAND)) { 207 ring->in_use_flags &= (~ON_LEFT_HAND); 208 rogue.left_ring = 0; 209 } else if (ring && (ring->in_use_flags & ON_RIGHT_HAND)) { 210 ring->in_use_flags &= (~ON_RIGHT_HAND); 211 rogue.right_ring = 0; 212 } 213 ring_stats(1); 214 } 215 216 void 217 gr_ring(ring, assign_wk) 218 object *ring; 219 boolean assign_wk; 220 { 221 ring->what_is = RING; 222 if (assign_wk) { 223 ring->which_kind = get_rand(0, (RINGS - 1)); 224 } 225 ring->class = 0; 226 227 switch(ring->which_kind) { 228 /* 229 case STEALTH: 230 break; 231 case SLOW_DIGEST: 232 break; 233 case REGENERATION: 234 break; 235 case R_SEE_INVISIBLE: 236 break; 237 case SUSTAIN_STRENGTH: 238 break; 239 case R_MAINTAIN_ARMOR: 240 break; 241 case SEARCHING: 242 break; 243 */ 244 case R_TELEPORT: 245 ring->is_cursed = 1; 246 break; 247 case ADD_STRENGTH: 248 case DEXTERITY: 249 while ((ring->class = (get_rand(0, 4) - 2)) == 0) ; 250 ring->is_cursed = (ring->class < 0); 251 break; 252 case ADORNMENT: 253 ring->is_cursed = coin_toss(); 254 break; 255 } 256 } 257 258 void 259 inv_rings() 260 { 261 char buf[DCOLS]; 262 263 if (r_rings == 0) { 264 message("not wearing any rings", 0); 265 } else { 266 if (rogue.left_ring) { 267 get_desc(rogue.left_ring, buf); 268 message(buf, 0); 269 } 270 if (rogue.right_ring) { 271 get_desc(rogue.right_ring, buf); 272 message(buf, 0); 273 } 274 } 275 if (wizard) { 276 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", 277 stealthy, r_rings, e_rings, r_teleport, sustain_strength, 278 add_strength, regeneration, ring_exp, r_see_invisible, 279 maintain_armor, auto_search); 280 message(buf, 0); 281 } 282 } 283 284 void 285 ring_stats(pr) 286 boolean pr; 287 { 288 short i; 289 object *ring; 290 291 stealthy = 0; 292 r_rings = 0; 293 e_rings = 0; 294 r_teleport = 0; 295 sustain_strength = 0; 296 add_strength = 0; 297 regeneration = 0; 298 ring_exp = 0; 299 r_see_invisible = 0; 300 maintain_armor = 0; 301 auto_search = 0; 302 303 for (i = 0; i < 2; i++) { 304 if (!(ring = ((i == 0) ? rogue.left_ring : rogue.right_ring))) { 305 continue; 306 } 307 r_rings++; 308 e_rings++; 309 switch(ring->which_kind) { 310 case STEALTH: 311 stealthy++; 312 break; 313 case R_TELEPORT: 314 r_teleport = 1; 315 break; 316 case REGENERATION: 317 regeneration++; 318 break; 319 case SLOW_DIGEST: 320 e_rings -= 2; 321 break; 322 case ADD_STRENGTH: 323 add_strength += ring->class; 324 break; 325 case SUSTAIN_STRENGTH: 326 sustain_strength = 1; 327 break; 328 case DEXTERITY: 329 ring_exp += ring->class; 330 break; 331 case ADORNMENT: 332 break; 333 case R_SEE_INVISIBLE: 334 r_see_invisible = 1; 335 break; 336 case MAINTAIN_ARMOR: 337 maintain_armor = 1; 338 break; 339 case SEARCHING: 340 auto_search += 2; 341 break; 342 } 343 } 344 if (pr) { 345 print_stats(STAT_STRENGTH); 346 relight(); 347 } 348 } 349