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

Comparing deliantra/server/server/skills.C (file contents):
Revision 1.88 by root, Wed Apr 14 21:26:36 2010 UTC vs.
Revision 1.108 by root, Wed Dec 12 02:13:05 2012 UTC

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,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2003 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2003 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the Affero GNU General Public License 18 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 20 * <http://www.gnu.org/licenses/>.
21 * 21 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <object.h> 26#include <object.h>
281 281
282 /* For all the stacked objects at this point, attempt a steal */ 282 /* For all the stacked objects at this point, attempt a steal */
283 for (; tmp; tmp = next) 283 for (; tmp; tmp = next)
284 { 284 {
285 next = tmp->below; 285 next = tmp->below;
286 /* Minor hack--for multi square beings - make sure we get 286 /* Minor hack--for multi square beings - make sure we get
287 * the 'head' coz 'tail' objects have no inventory! - b.t. 287 * the 'head' coz 'tail' objects have no inventory! - b.t.
288 */ 288 */
289 if (tmp->head) 289 if (tmp->head)
290 tmp = tmp->head; 290 tmp = tmp->head;
291 291
292 if (tmp->type != PLAYER && !tmp->flag [FLAG_MONSTER]) 292 if (tmp->type != PLAYER && !tmp->flag [FLAG_MONSTER])
293 continue;
294
295 /* do not reveal hidden DMs */
296 if (tmp->type == PLAYER && tmp->flag [FLAG_WIZ] && tmp->contr->hidden)
297 continue; 293 continue;
298 294
299 if (attempt_steal (tmp, op, skill)) 295 if (attempt_steal (tmp, op, skill))
300 { 296 {
301 if (tmp->type == PLAYER) /* no xp for stealing from another player */ 297 if (tmp->type == PLAYER) /* no xp for stealing from another player */
355 351
356int 352int
357pick_lock (object *pl, int dir, object *skill) 353pick_lock (object *pl, int dir, object *skill)
358{ 354{
359 object *tmp; 355 object *tmp;
360 int x = pl->x + freearr_x[dir];
361 int y = pl->y + freearr_y[dir];
362 356
363 if (!dir) 357 if (!dir)
364 dir = pl->facing; 358 dir = pl->facing;
365 359
360 mapxy pos (pl); pos.move (dir);
361
366 /* For all the stacked objects at this point find a door */ 362 /* For all the stacked objects at this point find a door */
367 if (out_of_map (pl->map, x, y)) 363 if (!pos.normalise ())
368 { 364 {
369 pl->failmsg ("There is no lock there."); 365 pl->failmsg ("There is no lock there.");
370 return 0; 366 return 0;
371 } 367 }
372 368
373 for (tmp = GET_MAP_OB (pl->map, x, y); tmp; tmp = tmp->above) 369 for (tmp = pos->bot; tmp; tmp = tmp->above)
374 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) 370 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
375 break; 371 break;
376 372
377 if (!tmp) 373 if (!tmp)
378 { 374 {
519 } 515 }
520 516
521 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above) 517 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
522 { 518 {
523 /* Jump into creature */ 519 /* Jump into creature */
524 if (tmp->flag [FLAG_MONSTER] 520 if (tmp->flag [FLAG_MONSTER] || tmp->type == PLAYER)
525 || (tmp->type == PLAYER && (!tmp->flag [FLAG_WIZ] || !tmp->contr->hidden)))
526 { 521 {
527 new_draw_info_format (NDI_UNIQUE, 0, pl, "You jump into %s%s.", tmp->type == PLAYER ? "" : "the ", &tmp->name); 522 new_draw_info_format (NDI_UNIQUE, 0, pl, "You jump into %s%s.", tmp->type == PLAYER ? "" : "the ", &tmp->name);
528 523
529 stop_jump (pl, i, spaces); 524 stop_jump (pl, i, spaces);
530 525
587 } 582 }
588 583
589 return attempt_jump (pl, dir, spaces, skill); 584 return attempt_jump (pl, dir, spaces, skill);
590} 585}
591 586
592/* skill_ident() - this code is supposed to allow players to identify 587/* skill_ident() - this code is supposed to allow players to identify
593 * classes of objects with the various "auto-ident" skills. Player must 588 * classes of objects with the various "auto-ident" skills. Player must
594 * have unidentified objects of the right type in order for the skill 589 * have unidentified objects of the right type in order for the skill
595 * to work. While multiple classes of objects may be identified, 590 * to work. While multiple classes of objects may be identified,
596 * this code is kind of yucky -- it would be nice to make it a bit 591 * this code is kind of yucky -- it would be nice to make it a bit
597 * more generalized. Right now, skill indices are embedded in this routine. 592 * more generalized. Right now, skill indices are embedded in this routine.
598 * Returns amount of experience gained (on successful ident). 593 * Returns amount of experience gained (on successful ident).
599 * - b.t. (thomas@astro.psu.edu) 594 * - b.t. (thomas@astro.psu.edu)
600 */ 595 */
601static int 596static int
602do_skill_detect_curse (object *pl, object *skill) 597do_skill_detect_curse (object *pl, object *skill)
603{ 598{
604 object *tmp;
605 int success = 0; 599 int success = 0;
606 600
607 for (tmp = pl->inv; tmp; tmp = tmp->below) 601 for (object *tmp = pl->inv; tmp; tmp = tmp->below)
608 if (!tmp->invisible 602 if (!tmp->invisible
603 && tmp->need_identify ()
609 && !tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_KNOWN_CURSED] 604 && !tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_KNOWN_CURSED]
610 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]) && tmp->item_power < skill->level) 605 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])
606 && tmp->item_power < skill->level)
611 { 607 {
612 tmp->set_flag (FLAG_KNOWN_CURSED); 608 tmp->set_flag (FLAG_KNOWN_CURSED);
613 esrv_update_item (UPD_FLAGS, pl, tmp); 609 esrv_update_item (UPD_FLAGS, pl, tmp);
614 success += calc_skill_exp (pl, tmp, skill); 610 success += calc_skill_exp (pl, tmp, skill);
615 } 611 }
616 612
617 /* Check ground, too, but only objects the player could pick up */ 613 /* Check ground, too, but only objects the player could pick up */
618 for (tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp; tmp = tmp->above) 614 for (object *tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
619 if (can_pick (pl, tmp) && 615 if (can_pick (pl, tmp)
620 !tmp->flag [FLAG_IDENTIFIED] && 616 && tmp->need_identify ()
621 !tmp->flag [FLAG_KNOWN_CURSED] 617 && !tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_KNOWN_CURSED]
622 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]) && tmp->item_power < skill->level) 618 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])
619 && tmp->item_power < skill->level)
623 { 620 {
624 tmp->set_flag (FLAG_KNOWN_CURSED); 621 tmp->set_flag (FLAG_KNOWN_CURSED);
625 esrv_update_item (UPD_FLAGS, pl, tmp); 622 esrv_update_item (UPD_FLAGS, pl, tmp);
626 success += calc_skill_exp (pl, tmp, skill); 623 success += calc_skill_exp (pl, tmp, skill);
627 } 624 }
630} 627}
631 628
632static int 629static int
633do_skill_detect_magic (object *pl, object *skill) 630do_skill_detect_magic (object *pl, object *skill)
634{ 631{
635 object *tmp;
636 int success = 0; 632 int success = 0;
637 633
638 for (tmp = pl->inv; tmp; tmp = tmp->below) 634 for (object *tmp = pl->inv; tmp; tmp = tmp->below)
639 if (!tmp->invisible 635 if (!tmp->invisible
636 && tmp->need_identify ()
640 && !tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_KNOWN_MAGICAL] 637 && !tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_KNOWN_MAGICAL]
638 && is_magical (tmp)
641 && (is_magical (tmp)) && tmp->item_power < skill->level) 639 && tmp->item_power < skill->level)
642 { 640 {
643 tmp->set_flag (FLAG_KNOWN_MAGICAL); 641 tmp->set_flag (FLAG_KNOWN_MAGICAL);
644 esrv_update_item (UPD_FLAGS, pl, tmp); 642 esrv_update_item (UPD_FLAGS, pl, tmp);
645 success += calc_skill_exp (pl, tmp, skill); 643 success += calc_skill_exp (pl, tmp, skill);
646 } 644 }
647 645
648 /* Check ground, too, but like above, only if the object can be picked up */ 646 /* Check ground, too, but like above, only if the object can be picked up */
649 for (tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp; tmp = tmp->above) 647 for (object *tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
650 if (can_pick (pl, tmp) && 648 if (can_pick (pl, tmp)
651 !tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_KNOWN_MAGICAL] && (is_magical (tmp)) && tmp->item_power < skill->level) 649 && tmp->need_identify ()
650 && !tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_KNOWN_MAGICAL]
651 && is_magical (tmp)
652 && tmp->item_power < skill->level)
652 { 653 {
653 tmp->set_flag (FLAG_KNOWN_MAGICAL); 654 tmp->set_flag (FLAG_KNOWN_MAGICAL);
654 esrv_update_item (UPD_FLAGS, pl, tmp); 655 esrv_update_item (UPD_FLAGS, pl, tmp);
655 success += calc_skill_exp (pl, tmp, skill); 656 success += calc_skill_exp (pl, tmp, skill);
656 } 657 }
665do_skill_ident2 (object *tmp, object *pl, int obj_class, object *skill) 666do_skill_ident2 (object *tmp, object *pl, int obj_class, object *skill)
666{ 667{
667 int success = 0, chance; 668 int success = 0, chance;
668 int skill_value = skill->level * pl->stats.Int ? pl->stats.Int : 10; 669 int skill_value = skill->level * pl->stats.Int ? pl->stats.Int : 10;
669 670
670 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->flag [FLAG_NO_SKILL_IDENT] 671 if (!tmp->flag [FLAG_IDENTIFIED]
671 && need_identify (tmp) && !tmp->invisible && tmp->type == obj_class) 672 && !tmp->flag [FLAG_NO_SKILL_IDENT]
673 && tmp->need_identify ()
674 && !tmp->invisible
675 && tmp->type == obj_class)
672 { 676 {
673 chance = die_roll (3, 10, pl, PREFER_LOW) - 3 + rndm (0, (tmp->magic ? tmp->magic * 5 : 1) - 1); 677 chance = die_roll (3, 10, pl, PREFER_LOW) - 3 + rndm (0, (tmp->magic ? tmp->magic * 5 : 1) - 1);
674 678
675 if (skill_value >= chance) 679 if (skill_value >= chance)
676 { 680 {
770 break; 774 break;
771 775
772 default: 776 default:
773 LOG (llevError, "Error: bad call to skill_ident()\n"); 777 LOG (llevError, "Error: bad call to skill_ident()\n");
774 return 0; 778 return 0;
775 break;
776 } 779 }
777 780
778 if (!success) 781 if (!success)
779 new_draw_info (NDI_UNIQUE, 0, pl, "... and learn nothing more."); 782 new_draw_info (NDI_UNIQUE, 0, pl, "... and learn nothing more.");
780 783
922 * of anything better! -b.t. 925 * of anything better! -b.t.
923 */ 926 */
924int 927int
925singing (object *pl, int dir, object *skill) 928singing (object *pl, int dir, object *skill)
926{ 929{
927 int i, exp = 0; 930 int exp = 0;
928 object *tmp; 931 object *tmp;
929 maptile *m; 932 maptile *m;
930 sint16 x, y; 933 sint16 x, y;
931 934
932 if (pl->type != PLAYER) 935 if (pl->type != PLAYER)
1181 1184
1182 if (pl->type != PLAYER) 1185 if (pl->type != PLAYER)
1183 return; /* players only */ 1186 return; /* players only */
1184 1187
1185 /* check if pl has removed encumbering armour and weapons */ 1188 /* check if pl has removed encumbering armour and weapons */
1186 if (pl->flag [FLAG_READY_WEAPON] && (skill->level < 6)) 1189 if (pl->flag [FLAG_READY_WEAPON] && skill->level < 6)
1187 { 1190 {
1188 pl->failmsg ("You can't concentrate while wielding a weapon!\n"); 1191 pl->failmsg ("You can't concentrate while wielding a weapon!\n");
1189 return; 1192 return;
1190 } 1193 }
1191 else 1194 else
1205 1208
1206 /* ok let's meditate! Spell points are regained first, then once 1209 /* ok let's meditate! Spell points are regained first, then once
1207 * they are maxed we get back hp. Actual incrementing of values 1210 * they are maxed we get back hp. Actual incrementing of values
1208 * is handled by the do_some_living() (in player.c). This way magical 1211 * is handled by the do_some_living() (in player.c). This way magical
1209 * bonuses for healing/sp regeneration are included properly 1212 * bonuses for healing/sp regeneration are included properly
1210 * No matter what, we will eat up some playing time trying to 1213 * No matter what, we will eat up some playing time trying to
1211 * meditate. (see 'factor' variable for what sets the amount of time) 1214 * meditate. (see 'factor' variable for what sets the amount of time)
1212 */ 1215 */
1213 1216
1214 new_draw_info (NDI_BLACK, 0, pl, "You meditate."); 1217 new_draw_info (NDI_BLACK, 0, pl, "You meditate.");
1215 1218
1216 if (pl->stats.sp < pl->stats.maxsp) 1219 if (pl->stats.sp < pl->stats.maxsp)
1223 pl->stats.hp++; 1226 pl->stats.hp++;
1224 pl->last_heal = -1; 1227 pl->last_heal = -1;
1225 } 1228 }
1226} 1229}
1227 1230
1228/* write_note() - this routine allows players to inscribe messages in 1231/* write_note() - this routine allows players to inscribe messages in
1229 * ordinary inscribable 'books' (anything that is not a SPELL). b.t. 1232 * ordinary inscribable 'books' (anything that is not a SPELL). b.t.
1230 */ 1233 */
1231static int 1234static int
1232write_note (object *pl, object *item, const char *msg, object *skill) 1235write_note (object *pl, object *item, const char *msg, object *skill)
1233{ 1236{
1278 return 0; 1281 return 0;
1279} 1282}
1280 1283
1281/* write_scroll() - this routine allows players to inscribe spell scrolls 1284/* write_scroll() - this routine allows players to inscribe spell scrolls
1282 * of spells which they know. Backfire effects are possible with the 1285 * of spells which they know. Backfire effects are possible with the
1283 * severity of the backlash correlated with the difficulty of the scroll 1286 * severity of the backlash correlated with the difficulty of the scroll
1284 * that is attempted. -b.t. thomas@astro.psu.edu 1287 * that is attempted. -b.t. thomas@astro.psu.edu
1285 */ 1288 */
1286static int 1289static int
1287write_scroll (object *pl, object *scroll, object *skill) 1290write_scroll (object *pl, object *scroll, object *skill)
1288{ 1291{
1320 if (random_roll (0, chosen_spell->level * 4 - 1, pl, PREFER_LOW) < skill->level) 1323 if (random_roll (0, chosen_spell->level * 4 - 1, pl, PREFER_LOW) < skill->level)
1321 { 1324 {
1322 object *newscroll = scroll->other_arch->instance (); 1325 object *newscroll = scroll->other_arch->instance ();
1323 scroll->decrease (); 1326 scroll->decrease ();
1324 newscroll->nrof = 1; 1327 newscroll->nrof = 1;
1328 newscroll->randomitems = 0; // make sure randomitems doesn't destroy the scroll
1325 1329
1326 pl->contr->play_sound (sound_find ("inscribe_success")); 1330 pl->contr->play_sound (sound_find ("inscribe_success"));
1327 1331
1328 if (!confused) 1332 if (!confused)
1329 { 1333 {
1340 newscroll->level = max (skill->level, chosen_spell->level); 1344 newscroll->level = max (skill->level, chosen_spell->level);
1341 new_draw_info (NDI_UNIQUE, 0, pl, "In your confused state, you write down some odd spell."); 1345 new_draw_info (NDI_UNIQUE, 0, pl, "In your confused state, you write down some odd spell.");
1342 } 1346 }
1343 1347
1344 object *tmp = chosen_spell->clone (); 1348 object *tmp = chosen_spell->clone ();
1349 tmp->flag [FLAG_APPLIED] = false;
1345 insert_ob_in_ob (tmp, newscroll); 1350 insert_ob_in_ob (tmp, newscroll);
1346 1351
1347 /* Same code as from treasure.C - so they can better merge. 1352 /* Same code as from treasure.C - so they can better merge.
1348 * if players want to sell them, so be it. 1353 * if players want to sell them, so be it.
1349 */ 1354 */
1406 { 1411 {
1407 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write! H<You lack the literacy skill.>"); 1412 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write! H<You lack the literacy skill.>");
1408 return 0; 1413 return 0;
1409 } 1414 }
1410 1415
1411 object *item = find_marked_object (pl); 1416 object *item = pl->mark ();
1412 1417
1413 /* find an item of correct type to write on */ 1418 /* find an item of correct type to write on */
1414 if (!item) 1419 if (!item)
1415 { 1420 {
1416 new_draw_info (NDI_UNIQUE, 0, pl, "You don't have any marked item to write on. H<Use the mark command or the popup menu to make an item.>"); 1421 new_draw_info (NDI_UNIQUE, 0, pl, "You don't have any marked item to write on. H<Use the mark command or the popup menu to make an item.>");
1466 */ 1471 */
1467static object * 1472static object *
1468find_throw_ob (object *op, const char *request) 1473find_throw_ob (object *op, const char *request)
1469{ 1474{
1470 /* prefer marked item */ 1475 /* prefer marked item */
1471 object *tmp = find_marked_object (op); 1476 object *tmp = op->mark ();
1472 1477
1473 /* can't toss invisible or inv-locked items */ 1478 /* can't toss invisible or inv-locked items */
1474 if (tmp && (tmp->invisible || tmp->flag [FLAG_INV_LOCKED])) 1479 if (tmp && (tmp->invisible || tmp->flag [FLAG_INV_LOCKED]))
1475 tmp = 0; 1480 tmp = 0;
1476 1481
1783 throw_ob->speed_left = 0; 1788 throw_ob->speed_left = 0;
1784 throw_ob->map = part->map; 1789 throw_ob->map = part->map;
1785 1790
1786 throw_ob->move_type = MOVE_FLY_LOW; 1791 throw_ob->move_type = MOVE_FLY_LOW;
1787 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK; 1792 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK;
1793
1794 throw_ob->set_speed (throw_ob->speed);
1788 1795
1789#if 0 1796#if 0
1790 /* need to put in a good sound for this */ 1797 /* need to put in a good sound for this */
1791 play_sound_map (op->map, op->x, op->y, SOUND_THROW_OBJ); 1798 play_sound_map (op->map, op->x, op->y, SOUND_THROW_OBJ);
1792#endif 1799#endif
1819 throw_ob = find_mon_throw_ob (op); 1826 throw_ob = find_mon_throw_ob (op);
1820 1827
1821 return do_throw (op, part, throw_ob, dir, skill); 1828 return do_throw (op, part, throw_ob, dir, skill);
1822} 1829}
1823 1830
1831static void
1832give_player_quad_material_for (object *pl, object *ob)
1833{
1834 if (!ob->flag [FLAG_IS_QUAD] || !ob->other_arch)
1835 return;
1836
1837 object *t = ob->other_arch->instance ();
1838 pl->insert (t);
1839}
1840
1824bool 1841bool
1825skill_mining (object *who, object *tool, object *skill, int dir, const char *string) 1842skill_mining (object *who, object *tool, object *skill, int dir, const char *string)
1826{ 1843{
1827 if (!who->is_player ()) 1844 if (!who->is_player ())
1828 return 0; 1845 return 0;
1845 return 0; 1862 return 0;
1846 } 1863 }
1847 1864
1848 mapspace &ms = pos.ms (); 1865 mapspace &ms = pos.ms ();
1849 1866
1850 for (object *vein = pos.ms ().top; vein; vein = vein->below) 1867 for (object *mine_obj = pos.ms ().top; mine_obj; mine_obj = mine_obj->below)
1851 if (vein->type == VEIN) 1868 if (mine_obj->type == VEIN)
1852 { 1869 {
1853 who->speed_left -= who->speed / tool->speed; 1870 who->speed_left -= who->speed / tool->speed;
1854 1871
1855 who->play_sound (tool->sound); 1872 who->play_sound (tool->sound);
1856 1873
1857 if (rndm (100 - vein->stats.ac) > rndm (tool->stats.wc)) 1874 if (rndm (100 - mine_obj->stats.ac) > rndm (tool->stats.wc))
1858 who->failmsgf ( 1875 who->failmsgf (
1859 "You use your %s.... nothing. " 1876 "You use your %s.... nothing. "
1860 "H<Try again, perhaps?>", 1877 "H<Try again, perhaps?>",
1861 &tool->name 1878 &tool->name
1862 ); 1879 );
1863 else if (vein->race != tool->race) 1880 else if (mine_obj->race != tool->race)
1864 who->failmsgf ( 1881 who->failmsgf (
1865 "You use your %s.... but it doesn't work. " 1882 "You use your %s.... but it doesn't work. "
1866 "H<Maybe you are using the wrong tool?>", 1883 "H<Maybe you are using the wrong tool?>",
1867 &tool->name 1884 &tool->name
1868 ); 1885 );
1869 else if (!vein->stats.food) 1886 else if (!mine_obj->stats.food)
1870 who->failmsgf ( 1887 who->failmsgf (
1871 "You use your %s.... but there is nothing. " 1888 "You use your %s.... but there is nothing. "
1872 "H<This space is exhausted, you should try somewhere else.>", 1889 "H<This space is exhausted, you should try somewhere else.>",
1873 &tool->name 1890 &tool->name
1874 ); 1891 );
1875 else 1892 else
1876 { 1893 {
1877 --vein->stats.food; 1894 --mine_obj->stats.food;
1878 1895
1879 object *ore = vein->other_arch->instance (); 1896 object *ore = mine_obj->other_arch->instance ();
1880 1897
1881 who->statusmsg (format ( 1898 who->statusmsg (format (
1882 "You use your %s.... and find some %s!", 1899 "You use your %s.... and find some %s!",
1883 &tool->name, &ore->name 1900 &tool->name, &ore->name
1884 )); 1901 ));
1886 ore->insert_at (who); 1903 ore->insert_at (who);
1887 1904
1888 return true; 1905 return true;
1889 } 1906 }
1890 } 1907 }
1908 else if (mine_obj->flag [FLAG_IS_QUAD])
1909 {
1910 if (mine_obj->flag [FLAG_IS_FLOOR])
1911 {
1912 maptile *lower_floor = pos.m->tile_available (TILE_DOWN);
1913
1914 if (!lower_floor)
1915 {
1916 who->failmsgf (
1917 "Whoops, you failed to remove the %s. H<You may try again.>",
1918 &mine_obj->name
1919 );
1920 return false;
1921 }
1922
1923 mapxy below_pos (lower_floor, pos.x, pos.y);
1924
1925 if (!below_pos.normalise ())
1926 {
1927 who->failmsgf (
1928 "Whoops, you failed to remove the %s. H<You may try again.>",
1929 &mine_obj->name
1930 );
1931 return false;
1932 }
1933
1934 // first insert open space here:
1935 object *open_space_floor = archetype::get (shstr_quad_open_space);
1936 open_space_floor->stats.hp = pos.x;
1937 open_space_floor->stats.sp = pos.y;
1938 insert_ob_in_map_at (open_space_floor, pos.m, mine_obj,
1939 INS_BELOW_ORIGINATOR, pos.x, pos.y);
1940
1941 // next we will remove the wall in the lower layer:
1942 mapspace &below_ms = below_pos.ms ();
1943 for (object *quad_obj = below_ms.top; quad_obj; quad_obj = quad_obj->below)
1944 {
1945 if (quad_obj->flag [FLAG_IS_FLOOR])
1946 break;
1947
1948 if (quad_obj->flag [FLAG_IS_QUAD])
1949 {
1950 quad_obj->map->queue_physics_at (quad_obj->x, quad_obj->y);
1951 give_player_quad_material_for (who, quad_obj);
1952 quad_obj->destroy ();
1953 break;
1954 }
1955 }
1956 }
1957
1958 mine_obj->map->queue_physics_at (mine_obj->x, mine_obj->y);
1959
1960 // FIXME: there should be chance assigned, like above with veins!
1961 who->play_sound (tool->sound);
1962 give_player_quad_material_for (who, mine_obj);
1963 mine_obj->destroy ();
1964 who->contr->fire_on = 0; // TODO: stopgap, do not remove more than one per keypress
1965 return true;
1966 }
1891 1967
1892 return false; 1968 return false;
1893} 1969}
1894 1970
1895bool
1896skill_fishing (object *who, object *tool, object *skill, int dir, const char *string)
1897{
1898 printf ("******** fishing\n");
1899 return false;
1900}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines