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.94 by root, Sun May 2 20:57:53 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 int success = 0; 599 int success = 0;
930 * of anything better! -b.t. 925 * of anything better! -b.t.
931 */ 926 */
932int 927int
933singing (object *pl, int dir, object *skill) 928singing (object *pl, int dir, object *skill)
934{ 929{
935 int i, exp = 0; 930 int exp = 0;
936 object *tmp; 931 object *tmp;
937 maptile *m; 932 maptile *m;
938 sint16 x, y; 933 sint16 x, y;
939 934
940 if (pl->type != PLAYER) 935 if (pl->type != PLAYER)
1213 1208
1214 /* ok let's meditate! Spell points are regained first, then once 1209 /* ok let's meditate! Spell points are regained first, then once
1215 * they are maxed we get back hp. Actual incrementing of values 1210 * they are maxed we get back hp. Actual incrementing of values
1216 * 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
1217 * bonuses for healing/sp regeneration are included properly 1212 * bonuses for healing/sp regeneration are included properly
1218 * 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
1219 * meditate. (see 'factor' variable for what sets the amount of time) 1214 * meditate. (see 'factor' variable for what sets the amount of time)
1220 */ 1215 */
1221 1216
1222 new_draw_info (NDI_BLACK, 0, pl, "You meditate."); 1217 new_draw_info (NDI_BLACK, 0, pl, "You meditate.");
1223 1218
1224 if (pl->stats.sp < pl->stats.maxsp) 1219 if (pl->stats.sp < pl->stats.maxsp)
1231 pl->stats.hp++; 1226 pl->stats.hp++;
1232 pl->last_heal = -1; 1227 pl->last_heal = -1;
1233 } 1228 }
1234} 1229}
1235 1230
1236/* write_note() - this routine allows players to inscribe messages in 1231/* write_note() - this routine allows players to inscribe messages in
1237 * ordinary inscribable 'books' (anything that is not a SPELL). b.t. 1232 * ordinary inscribable 'books' (anything that is not a SPELL). b.t.
1238 */ 1233 */
1239static int 1234static int
1240write_note (object *pl, object *item, const char *msg, object *skill) 1235write_note (object *pl, object *item, const char *msg, object *skill)
1241{ 1236{
1286 return 0; 1281 return 0;
1287} 1282}
1288 1283
1289/* write_scroll() - this routine allows players to inscribe spell scrolls 1284/* write_scroll() - this routine allows players to inscribe spell scrolls
1290 * of spells which they know. Backfire effects are possible with the 1285 * of spells which they know. Backfire effects are possible with the
1291 * severity of the backlash correlated with the difficulty of the scroll 1286 * severity of the backlash correlated with the difficulty of the scroll
1292 * that is attempted. -b.t. thomas@astro.psu.edu 1287 * that is attempted. -b.t. thomas@astro.psu.edu
1293 */ 1288 */
1294static int 1289static int
1295write_scroll (object *pl, object *scroll, object *skill) 1290write_scroll (object *pl, object *scroll, object *skill)
1296{ 1291{
1328 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)
1329 { 1324 {
1330 object *newscroll = scroll->other_arch->instance (); 1325 object *newscroll = scroll->other_arch->instance ();
1331 scroll->decrease (); 1326 scroll->decrease ();
1332 newscroll->nrof = 1; 1327 newscroll->nrof = 1;
1328 newscroll->randomitems = 0; // make sure randomitems doesn't destroy the scroll
1333 1329
1334 pl->contr->play_sound (sound_find ("inscribe_success")); 1330 pl->contr->play_sound (sound_find ("inscribe_success"));
1335 1331
1336 if (!confused) 1332 if (!confused)
1337 { 1333 {
1348 newscroll->level = max (skill->level, chosen_spell->level); 1344 newscroll->level = max (skill->level, chosen_spell->level);
1349 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.");
1350 } 1346 }
1351 1347
1352 object *tmp = chosen_spell->clone (); 1348 object *tmp = chosen_spell->clone ();
1349 tmp->flag [FLAG_APPLIED] = false;
1353 insert_ob_in_ob (tmp, newscroll); 1350 insert_ob_in_ob (tmp, newscroll);
1354 1351
1355 /* Same code as from treasure.C - so they can better merge. 1352 /* Same code as from treasure.C - so they can better merge.
1356 * if players want to sell them, so be it. 1353 * if players want to sell them, so be it.
1357 */ 1354 */
1829 throw_ob = find_mon_throw_ob (op); 1826 throw_ob = find_mon_throw_ob (op);
1830 1827
1831 return do_throw (op, part, throw_ob, dir, skill); 1828 return do_throw (op, part, throw_ob, dir, skill);
1832} 1829}
1833 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
1834bool 1841bool
1835skill_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)
1836{ 1843{
1837 if (!who->is_player ()) 1844 if (!who->is_player ())
1838 return 0; 1845 return 0;
1855 return 0; 1862 return 0;
1856 } 1863 }
1857 1864
1858 mapspace &ms = pos.ms (); 1865 mapspace &ms = pos.ms ();
1859 1866
1860 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)
1861 if (vein->type == VEIN) 1868 if (mine_obj->type == VEIN)
1862 { 1869 {
1863 who->speed_left -= who->speed / tool->speed; 1870 who->speed_left -= who->speed / tool->speed;
1864 1871
1865 who->play_sound (tool->sound); 1872 who->play_sound (tool->sound);
1866 1873
1867 if (rndm (100 - vein->stats.ac) > rndm (tool->stats.wc)) 1874 if (rndm (100 - mine_obj->stats.ac) > rndm (tool->stats.wc))
1868 who->failmsgf ( 1875 who->failmsgf (
1869 "You use your %s.... nothing. " 1876 "You use your %s.... nothing. "
1870 "H<Try again, perhaps?>", 1877 "H<Try again, perhaps?>",
1871 &tool->name 1878 &tool->name
1872 ); 1879 );
1873 else if (vein->race != tool->race) 1880 else if (mine_obj->race != tool->race)
1874 who->failmsgf ( 1881 who->failmsgf (
1875 "You use your %s.... but it doesn't work. " 1882 "You use your %s.... but it doesn't work. "
1876 "H<Maybe you are using the wrong tool?>", 1883 "H<Maybe you are using the wrong tool?>",
1877 &tool->name 1884 &tool->name
1878 ); 1885 );
1879 else if (!vein->stats.food) 1886 else if (!mine_obj->stats.food)
1880 who->failmsgf ( 1887 who->failmsgf (
1881 "You use your %s.... but there is nothing. " 1888 "You use your %s.... but there is nothing. "
1882 "H<This space is exhausted, you should try somewhere else.>", 1889 "H<This space is exhausted, you should try somewhere else.>",
1883 &tool->name 1890 &tool->name
1884 ); 1891 );
1885 else 1892 else
1886 { 1893 {
1887 --vein->stats.food; 1894 --mine_obj->stats.food;
1888 1895
1889 object *ore = vein->other_arch->instance (); 1896 object *ore = mine_obj->other_arch->instance ();
1890 1897
1891 who->statusmsg (format ( 1898 who->statusmsg (format (
1892 "You use your %s.... and find some %s!", 1899 "You use your %s.... and find some %s!",
1893 &tool->name, &ore->name 1900 &tool->name, &ore->name
1894 )); 1901 ));
1896 ore->insert_at (who); 1903 ore->insert_at (who);
1897 1904
1898 return true; 1905 return true;
1899 } 1906 }
1900 } 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 }
1901 1967
1902 return false; 1968 return false;
1903} 1969}
1904 1970

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines