1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2003,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2003,2007 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify |
8 | * Deliantra is free software: you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
9 | * it under the terms of the GNU General Public License as published by |
… | |
… | |
41 | /* Only prohibit stealing if the player does not have a free |
41 | /* Only prohibit stealing if the player does not have a free |
42 | * hand available and in fact does have hands. |
42 | * hand available and in fact does have hands. |
43 | */ |
43 | */ |
44 | if (op->type == PLAYER && op->slot[body_arm].used <= 0 && op->slot[body_arm].info) |
44 | if (op->type == PLAYER && op->slot[body_arm].used <= 0 && op->slot[body_arm].info) |
45 | { |
45 | { |
46 | new_draw_info (NDI_UNIQUE, 0, op, "But you have no free hands to steal with!"); |
46 | new_draw_info (NDI_UNIQUE, 0, op, "But you have no free hands to steal with! " |
|
|
47 | "H<Try to unapply weapons or things you hold in your hands, use the C<body> command.>"); |
47 | return -1; |
48 | return -1; |
48 | } |
49 | } |
49 | |
50 | |
50 | /* ADJUSTMENTS */ |
51 | /* ADJUSTMENTS */ |
51 | |
52 | |
… | |
… | |
101 | { |
102 | { |
102 | object *success = NULL, *tmp = NULL, *next; |
103 | object *success = NULL, *tmp = NULL, *next; |
103 | int roll = 0, chance = 0, stats_value; |
104 | int roll = 0, chance = 0, stats_value; |
104 | rv_vector rv; |
105 | rv_vector rv; |
105 | |
106 | |
106 | stats_value = ((who->stats.Dex + who->stats.Int) * 3) / 2; |
107 | stats_value = (who->stats.Dex + who->stats.Int) * 3 / 2; |
107 | |
108 | |
108 | /* if the victim is aware of a thief in the area (FLAG_NO_STEAL set on them) |
109 | /* if the victim is aware of a thief in the area (FLAG_NO_STEAL set on them) |
109 | * they will try to prevent stealing if they can. Only unseen theives will |
110 | * they will try to prevent stealing if they can. Only unseen theives will |
110 | * have much chance of success. |
111 | * have much chance of success. |
111 | */ |
112 | */ |
112 | if (op->type != PLAYER && QUERY_FLAG (op, FLAG_NO_STEAL)) |
113 | if (!op->is_player () && op->flag [FLAG_NO_STEAL]) |
113 | { |
114 | { |
114 | if (can_detect_enemy (op, who, &rv)) |
115 | if (can_detect_enemy (op, who, &rv)) |
115 | { |
116 | { |
116 | npc_call_help (op); |
117 | npc_call_help (op); |
117 | CLEAR_FLAG (op, FLAG_UNAGGRESSIVE); |
118 | CLEAR_FLAG (op, FLAG_UNAGGRESSIVE); |
118 | new_draw_info (NDI_UNIQUE, 0, who, "Your attempt is prevented!"); |
119 | new_draw_info (NDI_UNIQUE, 0, who, "Your attempt is prevented!"); |
119 | return 0; |
120 | return 0; |
120 | } |
121 | } |
121 | else /* help npc to detect thief next time by raising its wisdom */ |
122 | else /* help npc to detect thief next time by raising its wisdom */ |
122 | op->stats.Wis += (op->stats.Int / 5) + 1; |
123 | op->stats.Wis += (op->stats.Int / 5) + 1; |
|
|
124 | |
123 | if (op->stats.Wis > MAX_STAT) |
125 | if (op->stats.Wis > MAX_STAT) |
124 | op->stats.Wis = MAX_STAT; |
126 | op->stats.Wis = MAX_STAT; |
125 | } |
127 | } |
126 | |
128 | |
127 | if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ)) |
129 | if (op->is_player () && op->flag [FLAG_WIZ]) |
128 | { |
130 | { |
129 | new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from the dungeon master!\n"); |
131 | new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from the dungeon master!\n"); |
130 | return 0; |
132 | return 0; |
131 | } |
133 | } |
132 | |
134 | |
133 | // only allow stealing between hostile players (TODO: probably should change) |
135 | // only allow stealing between hostile players (TODO: probably should change) |
134 | if (op->type == PLAYER && who->type == PLAYER && (who->contr->peaceful || op->contr->peaceful)) |
136 | if (op->is_player () && who->is_player () && (who->contr->peaceful || op->contr->peaceful)) |
135 | { |
137 | { |
136 | new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n"); |
138 | new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n"); |
137 | return 0; |
139 | return 0; |
138 | } |
140 | } |
139 | |
141 | |
… | |
… | |
200 | |
202 | |
201 | if ((roll >= skill->level) || !chance |
203 | if ((roll >= skill->level) || !chance |
202 | || (tmp && tmp->weight > (250 * (random_roll (0, stats_value + skill->level * 10 - 1, who, PREFER_LOW))))) |
204 | || (tmp && tmp->weight > (250 * (random_roll (0, stats_value + skill->level * 10 - 1, who, PREFER_LOW))))) |
203 | { |
205 | { |
204 | /* victim figures out where the thief is! */ |
206 | /* victim figures out where the thief is! */ |
205 | if (who->hide) |
207 | if (who->flag [FLAG_HIDDEN]) |
206 | make_visible (who); |
208 | make_visible (who); |
207 | |
209 | |
208 | if (op->type != PLAYER) |
210 | if (op->type != PLAYER) |
209 | { |
211 | { |
210 | /* The unaggressives look after themselves 8) */ |
212 | /* The unaggressives look after themselves 8) */ |
… | |
… | |
428 | op->invisible += 100; /* set the level of 'hiddeness' */ |
430 | op->invisible += 100; /* set the level of 'hiddeness' */ |
429 | |
431 | |
430 | if (op->type == PLAYER) |
432 | if (op->type == PLAYER) |
431 | op->contr->tmp_invis = 1; |
433 | op->contr->tmp_invis = 1; |
432 | |
434 | |
433 | op->hide = 1; |
435 | op->flag [FLAG_HIDDEN] = 1; |
434 | return 1; |
436 | return 1; |
435 | } |
437 | } |
436 | |
438 | |
437 | return 0; |
439 | return 0; |
438 | } |
440 | } |
… | |
… | |
447 | if (QUERY_FLAG (op, FLAG_MAKE_INVIS)) |
449 | if (QUERY_FLAG (op, FLAG_MAKE_INVIS)) |
448 | { |
450 | { |
449 | new_draw_info (NDI_UNIQUE, 0, op, "You don't need to hide while invisible!"); |
451 | new_draw_info (NDI_UNIQUE, 0, op, "You don't need to hide while invisible!"); |
450 | return 0; |
452 | return 0; |
451 | } |
453 | } |
452 | else if (!op->hide && op->invisible > 0 && op->type == PLAYER) |
454 | else if (!op->flag [FLAG_HIDDEN] && op->invisible > 0 && op->type == PLAYER) |
453 | { |
455 | { |
454 | new_draw_info (NDI_UNIQUE, 0, op, "Your attempt to hide breaks the invisibility spell!"); |
456 | new_draw_info (NDI_UNIQUE, 0, op, "Your attempt to hide breaks the invisibility spell!"); |
455 | make_visible (op); |
457 | make_visible (op); |
456 | } |
458 | } |
457 | |
459 | |
… | |
… | |
532 | || (pl->type == PLAYER && tmp->type == PLAYER && pl->contr->party != tmp->contr->party)) |
534 | || (pl->type == PLAYER && tmp->type == PLAYER && pl->contr->party != tmp->contr->party)) |
533 | exp = skill_attack (tmp, pl, pl->facing, "kicked", skill); /* pl makes an attack */ |
535 | exp = skill_attack (tmp, pl, pl->facing, "kicked", skill); /* pl makes an attack */ |
534 | |
536 | |
535 | return exp; /* note that calc_skill_exp() is already called by skill_attack() */ |
537 | return exp; /* note that calc_skill_exp() is already called by skill_attack() */ |
536 | } |
538 | } |
537 | |
|
|
538 | /* If the space has fly on set (no matter what the space is), |
|
|
539 | * we should get the effects - after all, the player is |
|
|
540 | * effectively flying. |
|
|
541 | */ |
|
|
542 | if (tmp->move_on & MOVE_FLY_LOW) |
|
|
543 | { |
|
|
544 | pl->x = x; |
|
|
545 | pl->y = y; |
|
|
546 | pl->map = m; |
|
|
547 | stop_jump (pl, i, spaces); |
|
|
548 | |
|
|
549 | return calc_skill_exp (pl, NULL, skill); |
|
|
550 | } |
|
|
551 | } |
539 | } |
552 | |
540 | |
553 | if (OB_TYPE_MOVE_BLOCK (pl, GET_MAP_MOVE_BLOCK (m, x, y))) |
541 | if (OB_TYPE_MOVE_BLOCK (pl, GET_MAP_MOVE_BLOCK (m, x, y))) |
554 | { |
542 | { |
555 | new_draw_info (NDI_UNIQUE, 0, pl, "Your jump is blocked."); |
543 | new_draw_info (NDI_UNIQUE, 0, pl, "Your jump is blocked."); |
… | |
… | |
558 | } |
546 | } |
559 | |
547 | |
560 | pl->x = x; |
548 | pl->x = x; |
561 | pl->y = y; |
549 | pl->y = y; |
562 | pl->map = m; |
550 | pl->map = m; |
|
|
551 | |
|
|
552 | if (m->at (x, y).move_on & pl->move_type) |
|
|
553 | { |
|
|
554 | new_draw_info (NDI_UNIQUE, 0, pl, "Your jump is stopped."); |
|
|
555 | stop_jump (pl, i, spaces); |
|
|
556 | return 0; |
|
|
557 | } |
563 | } |
558 | } |
564 | |
559 | |
565 | stop_jump (pl, i, spaces); |
560 | stop_jump (pl, i, spaces); |
566 | |
561 | |
567 | return calc_skill_exp (pl, NULL, skill); |
562 | return calc_skill_exp (pl, NULL, skill); |
… | |
… | |
1485 | for (tmp = op->inv; tmp != NULL; tmp = tmp->below) |
1480 | for (tmp = op->inv; tmp != NULL; tmp = tmp->below) |
1486 | { |
1481 | { |
1487 | /* can't toss invisible or inv-locked items */ |
1482 | /* can't toss invisible or inv-locked items */ |
1488 | if (tmp->invisible || QUERY_FLAG (tmp, FLAG_INV_LOCKED)) |
1483 | if (tmp->invisible || QUERY_FLAG (tmp, FLAG_INV_LOCKED)) |
1489 | continue; |
1484 | continue; |
1490 | if (!request || !strcmp (query_name (tmp), request) || !strcmp (tmp->name, request)) |
1485 | if (!request || !strcmp (query_name (tmp), request) || !strcmp (&tmp->name, request)) |
1491 | break; |
1486 | break; |
1492 | } |
1487 | } |
1493 | } |
1488 | } |
1494 | |
1489 | |
1495 | /* this should prevent us from throwing away |
1490 | /* this should prevent us from throwing away |
… | |
… | |
1726 | { |
1721 | { |
1727 | throw_ob->last_sp += eff_str / 3; /* fly a little further */ |
1722 | throw_ob->last_sp += eff_str / 3; /* fly a little further */ |
1728 | throw_ob->stats.dam += throw_ob->inv->stats.dam + throw_ob->magic + 2; |
1723 | throw_ob->stats.dam += throw_ob->inv->stats.dam + throw_ob->magic + 2; |
1729 | throw_ob->stats.wc -= throw_ob->magic + throw_ob->inv->stats.wc; |
1724 | throw_ob->stats.wc -= throw_ob->magic + throw_ob->inv->stats.wc; |
1730 | /* only throw objects get directional faces */ |
1725 | /* only throw objects get directional faces */ |
1731 | if (GET_ANIM_ID (throw_ob) && NUM_ANIMATIONS (throw_ob)) |
1726 | if (throw_ob->has_anim () && throw_ob->anim_frames ()) |
1732 | SET_ANIMATION (throw_ob, dir); |
1727 | throw_ob->set_anim_frame (dir); |
1733 | } |
1728 | } |
1734 | else |
1729 | else |
1735 | { |
1730 | { |
1736 | uint16 mat = throw_ob->materials; |
1731 | uint16 mat = throw_ob->materials; |
1737 | |
1732 | |