ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/apply.C
(Generate patch)

Comparing deliantra/server/server/apply.C (file contents):
Revision 1.172 by root, Mon Sep 29 10:32:50 2008 UTC vs.
Revision 1.183 by root, Thu Jan 8 04:35:04 2009 UTC

160 * matching item. 160 * matching item.
161 **/ 161 **/
162void 162void
163handle_apply_yield (object *tmp) 163handle_apply_yield (object *tmp)
164{ 164{
165 if (shstr yield = tmp->kv (shstr_on_use_yield)) 165 if (shstr_tmp yield = tmp->kv (shstr_on_use_yield))
166 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); 166 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR);
167} 167}
168 168
169/** 169/**
170 * Handles applying a potion. 170 * Handles applying a potion.
406 406
407/** 407/**
408 * This returns the sum of nrof of item (arch name). 408 * This returns the sum of nrof of item (arch name).
409 */ 409 */
410static int 410static int
411check_item (object *op, const char *item) 411check_item (object *op, shstr_cmp item)
412{ 412{
413 int count = 0; 413 int count = 0;
414 414
415 if (!item) 415 if (!item)
416 return 0; 416 return 0;
417 417
418 for (op = op->below; op; op = op->below) 418 for (op = op->below; op; op = op->below)
419 {
420 if (strcmp (op->arch->archname, item) == 0) 419 if (op->arch->archname == item)
421 {
422 if (!QUERY_FLAG (op, FLAG_CURSED) && !QUERY_FLAG (op, FLAG_DAMNED) 420 if (!QUERY_FLAG (op, FLAG_CURSED) && !QUERY_FLAG (op, FLAG_DAMNED)
423 /* Loophole bug? -FD- */ && !QUERY_FLAG (op, FLAG_UNPAID)) 421 && /* Loophole bug? -FD- */ !QUERY_FLAG (op, FLAG_UNPAID))
424 {
425 if (op->nrof == 0) /* this is necessary for artifact sacrifices --FD-- */
426 count++;
427 else
428 count += op->nrof; 422 count += op->number_of ();
429 }
430 }
431 }
432 423
433 return count; 424 return count;
434} 425}
435 426
436/** 427/**
438 * op is typically the player, which is only 429 * op is typically the player, which is only
439 * really used to determine what space to look at. 430 * really used to determine what space to look at.
440 * Modified to only eat 'nrof' of objects. 431 * Modified to only eat 'nrof' of objects.
441 */ 432 */
442static void 433static void
443eat_item (object *op, const char *item, uint32 nrof) 434eat_item (object *op, shstr_cmp item, uint32 nrof)
444{ 435{
445 object *prev; 436 object *prev;
446 437
447 prev = op; 438 prev = op;
448 op = op->below; 439 op = op->below;
449 440
450 while (op) 441 while (op)
451 { 442 {
452 if (strcmp (op->arch->archname, item) == 0) 443 if (op->arch->archname == item)
453 { 444 {
454 if (op->nrof >= nrof) 445 if (op->nrof >= nrof)
455 { 446 {
456 op->decrease (nrof); 447 op->decrease (nrof);
457 return; 448 return;
995 item->nrof = give; 986 item->nrof = give;
996 987
997 if (nr) 988 if (nr)
998 item->nrof *= nr; 989 item->nrof *= nr;
999 990
1000 if (is_in_shop (converter)) 991 if (converter->flag [FLAG_PRECIOUS])
1001 SET_FLAG (item, FLAG_UNPAID); 992 SET_FLAG (item, FLAG_UNPAID);
993
994 if (is_in_shop (converter))
995 {
996 // converters on shop floors don't work anymore, bug lets check for it
997 // and report in case someone still does it.
998 LOG (llevDebug, "ITEMBUG: broken converter, converters on shop floor don't work: %s\n",
999 converter->debug_desc ());
1000 SET_FLAG (item, FLAG_UNPAID);
1001 }
1002 else if (price_in < sint64 (item->nrof) * item->value) 1002 else if (price_in < sint64 (item->nrof) * item->value)
1003 { 1003 {
1004 LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", 1004 LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n",
1005 &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); 1005 &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name);
1006 /** 1006 /**
1117/* push_button (altar);*/ 1117/* push_button (altar);*/
1118 } 1118 }
1119 else 1119 else
1120 { 1120 {
1121 altar->value = 1; /* works only once */ 1121 altar->value = 1; /* works only once */
1122 push_button (altar); 1122 push_button (altar, originator);
1123 } 1123 }
1124 1124
1125 return !sacrifice; 1125 return !sacrifice;
1126 } 1126 }
1127 else 1127 else
1153 { 1153 {
1154 has_unpaid = true; 1154 has_unpaid = true;
1155 break; 1155 break;
1156 } 1156 }
1157 1157
1158 if (op->type != PLAYER) 1158 if (!op->is_player ())
1159 { 1159 {
1160 /* Remove all the unpaid objects that may be carried here. 1160 /* Remove all the unpaid objects that may be carried here.
1161 * This could be pets or monsters that are somehow in 1161 * This could be pets or monsters that are somehow in
1162 * the shop. 1162 * the shop.
1163 */ 1163 */
1167 1167
1168 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 1168 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1169 { 1169 {
1170 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 1170 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
1171 1171
1172 if (i >= 0)
1172 tmp->remove (); 1173 tmp->move (i);
1173
1174 if (i == -1)
1175 i = 0;
1176
1177 tmp->map = op->map;
1178 tmp->x = op->x + freearr_x[i];
1179 tmp->y = op->y + freearr_y[i];
1180 insert_ob_in_map (tmp, op->map, op, 0);
1181 } 1174 }
1182 } 1175 }
1183 1176
1184 /* Don't teleport things like spell effects */ 1177 /* Don't teleport things like spell effects */
1185 if (QUERY_FLAG (op, FLAG_NO_PICK)) 1178 if (QUERY_FLAG (op, FLAG_NO_PICK))
1196 if (i != -1) 1189 if (i != -1)
1197 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); 1190 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat);
1198 1191
1199 return 0; 1192 return 0;
1200 } 1193 }
1194
1201 /* Removed code that checked for multipart objects - it appears that 1195 /* Removed code that checked for multipart objects - it appears that
1202 * the teleport function should be able to handle this just fine. 1196 * the teleport function should be able to handle this just fine.
1203 */ 1197 */
1204 rv = teleport (shop_mat, SHOP_MAT, op); 1198 rv = teleport (shop_mat, SHOP_MAT, op);
1205 } 1199 }
1260 * Handles applying a sign. 1254 * Handles applying a sign.
1261 */ 1255 */
1262static void 1256static void
1263apply_sign (object *op, object *sign, int autoapply) 1257apply_sign (object *op, object *sign, int autoapply)
1264{ 1258{
1259 if (!op->is_player())
1260 return;
1261
1265 if (sign->has_dialogue ()) 1262 if (sign->has_dialogue ())
1266 { 1263 {
1267 op->statusmsg (form ("Maybe you should I<talk> to the %s instead?", &sign->name)); 1264 op->statusmsg (format ("Maybe you should I<talk> to the %s instead?", &sign->name));
1268 return; 1265 return;
1269 } 1266 }
1270 1267
1271 if (!sign->msg) 1268 if (!sign->msg)
1272 { 1269 {
1273 op->statusmsg ("Nothing is written on it."); 1270 op->contr->infobox (MSG_CHANNEL ("examine"),
1271 format ("T<%s>\n\n Nothing %sis written on it.",
1272 &sign->name,
1273 sign->name == sign->arch->name ? "" : "else "));
1274 return; 1274 return;
1275 } 1275 }
1276 1276
1277 if (sign->stats.food) 1277 if (sign->stats.food)
1278 { 1278 {
1279 if (sign->last_eat >= sign->stats.food) 1279 if (sign->last_eat >= sign->stats.food)
1280 { 1280 {
1281 if (!sign->move_on) 1281 if (!sign->move_on)
1282 op->statusmsg ("You cannot read it anymore."); 1282 op->failmsg ("You cannot read it anymore.");
1283 1283
1284 return; 1284 return;
1285 } 1285 }
1286 1286
1287 if (!QUERY_FLAG (op, FLAG_WIZPASS)) 1287 if (!QUERY_FLAG (op, FLAG_WIZPASS))
1305 if (sign->sound) 1305 if (sign->sound)
1306 ns->play_sound (sign->sound); 1306 ns->play_sound (sign->sound);
1307 else if (autoapply) 1307 else if (autoapply)
1308 ns->play_sound (sound_find ("msg_voice")); 1308 ns->play_sound (sound_find ("msg_voice"));
1309 1309
1310 if (ns->can_msg)
1311 op->contr->infobox (MSG_CHANNEL ("examine"), format ("T<%s>\n\n%s", &sign->name, &sign->msg)); 1310 op->contr->infobox (MSG_CHANNEL ("examine"), format ("T<%s>\n\n%s", &sign->name, &sign->msg));
1312 else
1313 {
1314 readable_message_type *msgType = get_readable_message_type (sign);
1315 const char *somemsg = format ("%u %s", autoapply ? 1 : 0, &sign->msg);
1316 draw_ext_info (NDI_UNIQUE | NDI_NAVY, 0, op, msgType->message_type, msgType->message_subtype, somemsg, &sign->msg);
1317 }
1318 } 1311 }
1319} 1312}
1320 1313
1321static void 1314static void
1322move_apply_hole (object *trap, object *victim) 1315move_apply_hole (object *trap, object *victim)
1430 } 1423 }
1431 goto leave; 1424 goto leave;
1432 1425
1433 case BUTTON: 1426 case BUTTON:
1434 case PEDESTAL: 1427 case PEDESTAL:
1435 update_button (trap); 1428 update_button (trap, originator);
1436 goto leave; 1429 goto leave;
1437 1430
1438 case ALTAR: 1431 case ALTAR:
1439 /* sacrifice victim on trap */ 1432 /* sacrifice victim on trap */
1440 apply_altar (trap, victim, originator); 1433 apply_altar (trap, victim, originator);
1533 if (victim->type == PLAYER && EXIT_PATH (trap)) 1526 if (victim->type == PLAYER && EXIT_PATH (trap))
1534 { 1527 {
1535 /* Basically, don't show exits leading to random maps the 1528 /* Basically, don't show exits leading to random maps the
1536 * players output. 1529 * players output.
1537 */ 1530 */
1538 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2)) 1531 if (trap->msg && !EXIT_PATH (trap).starts_with ("/!"))
1539 victim->statusmsg (trap->msg, NDI_NAVY); 1532 victim->statusmsg (trap->msg, NDI_NAVY);
1540 1533
1541 trap->play_sound (trap->sound); 1534 trap->play_sound (trap->sound);
1542 victim->enter_exit (trap); 1535 victim->enter_exit (trap);
1543 } 1536 }
1626 1619
1627 readable_message_type *msgType = get_readable_message_type (tmp); 1620 readable_message_type *msgType = get_readable_message_type (tmp);
1628 1621
1629 if (player *pl = op->contr) 1622 if (player *pl = op->contr)
1630 if (client *ns = pl->ns) 1623 if (client *ns = pl->ns)
1631 if (ns->can_msg)
1632 pl->infobox (MSG_CHANNEL ("book"), format ("T<%s>\n\n%s", (char *)long_desc (tmp, op), &tmp->msg)); 1624 pl->infobox (MSG_CHANNEL ("book"), format ("T<%s>\n\n%s", (char *)long_desc (tmp, op), &tmp->msg));
1633 else
1634 draw_ext_info_format (NDI_UNIQUE | NDI_NAVY, 0, op,
1635 msgType->message_type, msgType->message_subtype,
1636 "You open the %s and start reading.\n%s", (char *)"%s\n%s",
1637 long_desc (tmp, op), &tmp->msg);
1638 1625
1639 /* gain xp from reading */ 1626 /* gain xp from reading */
1640 if (!QUERY_FLAG (tmp, FLAG_NO_SKILL_IDENT)) 1627 if (!QUERY_FLAG (tmp, FLAG_NO_SKILL_IDENT))
1641 { /* only if not read before */ 1628 { /* only if not read before */
1642 int exp_gain = calc_skill_exp (op, tmp, skill_ob); 1629 int exp_gain = calc_skill_exp (op, tmp, skill_ob);
2170 op->statusmsg (buf); 2157 op->statusmsg (buf);
2171 2158
2172 /* now choose a winner if we have any */ 2159 /* now choose a winner if we have any */
2173 i = -1; 2160 i = -1;
2174 if (winners > 0) 2161 if (winners > 0)
2175 i = atnr_winner[RANDOM () % winners]; 2162 i = atnr_winner [rndm (winners)];
2176 2163
2177 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95) 2164 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95)
2178 { 2165 {
2179 /* resistance increased! */ 2166 /* resistance increased! */
2180 skin->resist[i]++; 2167 skin->resist[i]++;
2397 op->play_sound (sound_find ("turn_handle")); 2384 op->play_sound (sound_find ("turn_handle"));
2398 op->statusmsg ("You turn the handle."); 2385 op->statusmsg ("You turn the handle.");
2399 tmp->value = tmp->value ? 0 : 1; 2386 tmp->value = tmp->value ? 0 : 1;
2400 SET_ANIMATION (tmp, tmp->value); 2387 SET_ANIMATION (tmp, tmp->value);
2401 update_object (tmp, UP_OBJ_FACE); 2388 update_object (tmp, UP_OBJ_FACE);
2402 push_button (tmp); 2389 push_button (tmp, op);
2403 return 1; 2390 return 1;
2404 2391
2405 case TRIGGER: 2392 case TRIGGER:
2406 if (check_trigger (tmp, op)) 2393 if (check_trigger (tmp, op))
2407 { 2394 {
2420 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp)) 2407 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2421 op->failmsg (format ("The %s is closed.", query_name (tmp))); 2408 op->failmsg (format ("The %s is closed.", query_name (tmp)));
2422 else 2409 else
2423 { 2410 {
2424 /* Don't display messages for random maps. */ 2411 /* Don't display messages for random maps. */
2425 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2)) 2412 if (tmp->msg && !EXIT_PATH (tmp).starts_with ("/!"))
2426 op->statusmsg (tmp->msg, NDI_NAVY); 2413 op->statusmsg (tmp->msg, NDI_NAVY);
2427 2414
2428 op->enter_exit (tmp); 2415 op->enter_exit (tmp);
2429 } 2416 }
2430 2417
2660 * person moving on it, also activate. Added code to make it 2647 * person moving on it, also activate. Added code to make it
2661 * so that at least one of players movement types be that which 2648 * so that at least one of players movement types be that which
2662 * the item needs. 2649 * the item needs.
2663 */ 2650 */
2664 if (!tmp->invisible || (tmp->move_on & pl->move_type)) 2651 if (!tmp->invisible || (tmp->move_on & pl->move_type))
2665 {
2666 if (player_apply (pl, tmp, 0, 1) == 1) 2652 if (player_apply (pl, tmp, 0, 1) == 1)
2667 return; 2653 return;
2668 } 2654
2669 if (floors >= 2) 2655 if (floors >= 2)
2670 return; /* process at most two floor objects */ 2656 return; /* process at most two floor objects */
2671 } 2657 }
2672} 2658}
2673 2659
2767 op->destroy (); 2753 op->destroy ();
2768 who->insert (tmp2); 2754 who->insert (tmp2);
2769 who->update_stats (); 2755 who->update_stats ();
2770 2756
2771 if (who->contr) 2757 if (who->contr)
2772 {
2773 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 2758 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2774 { 2759 {
2775 who->failmsg ("Oops, it feels deadly cold!"); 2760 who->failmsg ("Oops, it feels deadly cold!");
2776 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 2761 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2777 } 2762 }
2778 }
2779 } 2763 }
2780 2764
2781 return 1; /* otherwise, an attempt to drop causes problems */ 2765 return 1; /* otherwise, an attempt to drop causes problems */
2782 2766
2783 case BOW: 2767 case BOW:
3226 return 1; 3210 return 1;
3227 } 3211 }
3228 3212
3229 //TODO: this obviously fails for players using a shorter prefix 3213 //TODO: this obviously fails for players using a shorter prefix
3230 // i.e. "R" can use Ragnarok's sword. 3214 // i.e. "R" can use Ragnarok's sword.
3231 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3215 if (op->level && !op->name.starts_with (who->name))
3232 { 3216 {
3233 /* if the weapon does not have the name as the character, can't use it. */ 3217 /* if the weapon does not have the name as the character, can't use it. */
3234 /* (Ragnarok's sword attempted to be used by Foo: won't work) */ 3218 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3235 who->failmsg ("The weapon does not recognize you as its owner. H<Its name indicates that it belongs to somebody else.>"); 3219 who->failmsg ("The weapon does not recognize you as its owner. H<Its name indicates that it belongs to somebody else.>");
3236 3220
3305 who->update_stats (); 3289 who->update_stats ();
3306 3290
3307 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3291 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3308 if (who->type == PLAYER) 3292 if (who->type == PLAYER)
3309 { 3293 {
3310 who->failmsg ("Oops, it feels deadly cold! H<Maybe it wasn't such a bright idea to apply this cursed/damned item.>"); 3294 who->failmsg ("Oops, it feels deadly cold! H<Maybe it wasn't such a bright (hrhrhr) idea to apply this cursed or damned item.>");
3311 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 3295 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
3312 } 3296 }
3313 3297
3314 return 0; 3298 return 0;
3315 3299
3409 insert_ob_in_ob (tmp, who); 3393 insert_ob_in_ob (tmp, who);
3410 3394
3411 return 1; 3395 return 1;
3412 } 3396 }
3413 3397
3414 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3398 if (op->level && !op->name.starts_with (who->name))
3415 { 3399 {
3416 who->failmsg ("The weapon does not recognize you as its owner. " 3400 who->failmsg ("The weapon does not recognize you as its owner. "
3417 "H<Its name indicates that it belongs to somebody else.>"); 3401 "H<Its name indicates that it belongs to somebody else.>");
3418 if (tmp) 3402 if (tmp)
3419 insert_ob_in_ob (tmp, who); 3403 insert_ob_in_ob (tmp, who);
3493 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3477 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3494 if (who->type == PLAYER) 3478 if (who->type == PLAYER)
3495 { 3479 {
3496 who->failmsg ( 3480 who->failmsg (
3497 "Oops, it feels deadly cold! " 3481 "Oops, it feels deadly cold! "
3498 "H<Maybe it wasn't such a bright idea to apply this cursed/damned item.>" 3482 "H<Maybe it wasn't such a bright idea to apply this cursed or damned item.>"
3499 ); 3483 );
3500 SET_FLAG (op, FLAG_KNOWN_CURSED); 3484 SET_FLAG (op, FLAG_KNOWN_CURSED);
3501 } 3485 }
3502 3486
3503 if (object *pl = op->visible_to ()) 3487 if (object *pl = op->visible_to ())
3930 } 3914 }
3931 3915
3932 /* insert the randomitems from the change's treasurelist into 3916 /* insert the randomitems from the change's treasurelist into
3933 * the player ref: player.c 3917 * the player ref: player.c
3934 */ 3918 */
3935 if (change->randomitems != NULL) 3919 if (change->randomitems)
3936 give_initial_items (pl, change->randomitems); 3920 give_initial_items (pl, change->randomitems);
3937 3921
3938 /* set up the face, for some races. */ 3922 /* set up the face, for some races. */
3939 3923
3940 /* first, look for the force object banning 3924 /* first, look for the force object banning
3941 * changing the face. Certain races never change face with class. 3925 * changing the face. Certain races never change face with class.
3942 */ 3926 */
3943 for (walk = pl->inv; walk != NULL; walk = walk->below) 3927 for (walk = pl->inv; walk; walk = walk->below)
3944 if (!strcmp (walk->name, "NOCLASSFACECHANGE")) 3928 if (walk->name == shstr_NOCLASSFACECHANGE)
3945 flag_change_face = 0; 3929 flag_change_face = 0;
3946 3930
3947 if (flag_change_face) 3931 if (flag_change_face)
3948 { 3932 {
3949 pl->face = change->face; 3933 pl->face = change->face;
3951 pl->flag [FLAG_ANIMATE] = change->flag [FLAG_ANIMATE]; 3935 pl->flag [FLAG_ANIMATE] = change->flag [FLAG_ANIMATE];
3952 } 3936 }
3953 3937
3954 /* check the special case of can't use weapons */ 3938 /* check the special case of can't use weapons */
3955 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */ 3939 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */
3956 if (!strcmp (change->name, "monk")) 3940 if (change->name == shstr_monk)
3957 CLEAR_FLAG (pl, FLAG_USE_WEAPON); 3941 CLEAR_FLAG (pl, FLAG_USE_WEAPON);
3958 3942
3959 break; 3943 break;
3960 } 3944 }
3961 } 3945 }
3998 pl->failmsg (format ("You can't use the %s with your %s!", query_name (transformer), query_name (marked))); 3982 pl->failmsg (format ("You can't use the %s with your %s!", query_name (transformer), query_name (marked)));
3999 return; 3983 return;
4000 } 3984 }
4001 3985
4002 /* check whether they are compatible or not */ 3986 /* check whether they are compatible or not */
4003 find = strstr (marked->slaying, transformer->arch->archname); 3987 find = strstr (&marked->slaying, transformer->arch->archname);
4004 if (!find || (*(find + strlen (transformer->arch->archname)) != ':')) 3988 if (!find || (*(find + strlen (transformer->arch->archname)) != ':'))
4005 { 3989 {
4006 pl->failmsg (format ("You can't use the %s with your %s!", query_name (transformer), query_name (marked))); 3990 pl->failmsg (format ("You can't use the %s with your %s!", query_name (transformer), query_name (marked)));
4007 return; 3991 return;
4008 } 3992 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines