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.32 by root, Thu May 17 14:14:55 2007 UTC vs.
Revision 1.37 by root, Mon Jun 4 13:04:00 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (C) 2003 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2003,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software; you can redistribute it and/or modify it
9 * it under the terms of the GNU General Public License as published by 9 * under the terms of the GNU General Public License as published by the Free
10 * the Free Software Foundation; either version 2 of the License, or 10 * Software Foundation; either version 2 of the License, or (at your option)
11 * (at your option) any later version. 11 * 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, but
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * GNU General Public License for more details. 16 * for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License along
19 * along with this program; if not, write to the Free Software 19 * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * 21 *
22 * The authors can be reached via e-mail to <crossfire@schmorp.de> 22 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <object.h> 26#include <object.h>
409 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to pick the lock."); 409 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to pick the lock.");
410 return 0; 410 return 0;
411 } 411 }
412} 412}
413 413
414
415/* HIDE CODE. The user becomes undetectable (not just 'invisible') for 414/* HIDE CODE. The user becomes undetectable (not just 'invisible') for
416 * a short while (success and duration dependant on player SK_level, 415 * a short while (success and duration dependant on player SK_level,
417 * dexterity, charisma, and map difficulty). 416 * dexterity, charisma, and map difficulty).
418 * Players have a good chance of becoming 'unhidden' if they move 417 * Players have a good chance of becoming 'unhidden' if they move
419 * and like invisiblity will be come visible if they attack 418 * and like invisiblity will be come visible if they attack
420 * Implemented by b.t. (thomas@astro.psu.edu) 419 * Implemented by b.t. (thomas@astro.psu.edu)
421 * July 7, 1995 - made hiding possible for monsters. -b.t. 420 * July 7, 1995 - made hiding possible for monsters. -b.t.
422 */ 421 */
423
424static int 422static int
425attempt_hide (object *op, object *skill) 423attempt_hide (object *op, object *skill)
426{ 424{
427 int number, difficulty = op->map->difficulty; 425 int number, difficulty = op->map->difficulty;
428 int terrain = hideability (op); 426 int terrain = hideability (op);
431 return 0; 429 return 0;
432 430
433 /* Hiding success and duration dependant on skill level, 431 /* Hiding success and duration dependant on skill level,
434 * op->stats.Dex, map difficulty and terrain. 432 * op->stats.Dex, map difficulty and terrain.
435 */ 433 */
436
437 number = (die_roll (2, 25, op, PREFER_LOW) - 2) / 2; 434 number = (die_roll (2, 25, op, PREFER_LOW) - 2) / 2;
435
438 if (!stand_near_hostile (op) && (number < (op->stats.Dex + skill->level + terrain - difficulty))) 436 if (!stand_near_hostile (op) && (number < (op->stats.Dex + skill->level + terrain - difficulty)))
439 { 437 {
440 op->invisible += 100; /* set the level of 'hiddeness' */ 438 op->invisible += 100; /* set the level of 'hiddeness' */
439
441 if (op->type == PLAYER) 440 if (op->type == PLAYER)
442 op->contr->tmp_invis = 1; 441 op->contr->tmp_invis = 1;
442
443 op->hide = 1; 443 op->hide = 1;
444 return 1; 444 return 1;
445 } 445 }
446
446 return 0; 447 return 0;
447} 448}
448 449
449/* patched this to take terrain into consideration */ 450/* patched this to take terrain into consideration */
450int 451int
451hide (object *op, object *skill) 452hide (object *op, object *skill)
452{ 453{
453
454 /* the preliminaries -- Can we really hide now? */ 454 /* the preliminaries -- Can we really hide now? */
455 /* this keeps monsters from using invisibilty spells and hiding */ 455 /* this keeps monsters from using invisibilty spells and hiding */
456 456
457 if (QUERY_FLAG (op, FLAG_MAKE_INVIS)) 457 if (QUERY_FLAG (op, FLAG_MAKE_INVIS))
458 { 458 {
463 { 463 {
464 new_draw_info (NDI_UNIQUE, 0, op, "Your attempt to hide breaks the invisibility spell!"); 464 new_draw_info (NDI_UNIQUE, 0, op, "Your attempt to hide breaks the invisibility spell!");
465 make_visible (op); 465 make_visible (op);
466 } 466 }
467 467
468 if (op->invisible > (50 * skill->level)) 468 if (op->invisible > 50 * skill->level)
469 { 469 {
470 new_draw_info (NDI_UNIQUE, 0, op, "You are as hidden as you can get."); 470 new_draw_info (NDI_UNIQUE, 0, op, "You are as hidden as you can get.");
471 return 0; 471 return 0;
472 } 472 }
473 473
475 { 475 {
476 new_draw_info (NDI_UNIQUE, 0, op, "You hide in the shadows."); 476 new_draw_info (NDI_UNIQUE, 0, op, "You hide in the shadows.");
477 update_object (op, UP_OBJ_FACE); 477 update_object (op, UP_OBJ_FACE);
478 return calc_skill_exp (op, NULL, skill); 478 return calc_skill_exp (op, NULL, skill);
479 } 479 }
480
480 new_draw_info (NDI_UNIQUE, 0, op, "You fail to conceal yourself."); 481 new_draw_info (NDI_UNIQUE, 0, op, "You fail to conceal yourself.");
481 return 0; 482 return 0;
482} 483}
483
484 484
485/* stop_jump() - End of jump. Clear flags, restore the map, and 485/* stop_jump() - End of jump. Clear flags, restore the map, and
486 * freeze the jumper a while to simulate the exhaustion 486 * freeze the jumper a while to simulate the exhaustion
487 * of jumping. 487 * of jumping.
488 */ 488 */
808 * -b.t. (thomas@astro.psu.edu) 808 * -b.t. (thomas@astro.psu.edu)
809 */ 809 */
810int 810int
811use_oratory (object *pl, int dir, object *skill) 811use_oratory (object *pl, int dir, object *skill)
812{ 812{
813 sint16 x = pl->x + freearr_x[dir], y = pl->y + freearr_y[dir];
814 int mflags, chance;
815 object *tmp;
816 maptile *m;
817
818 if (pl->type != PLAYER) 813 if (pl->type != PLAYER)
819 return 0; /* only players use this skill */ 814 return 0; /* only players use this skill */
815
816 sint16 x = pl->x + freearr_x[dir],
817 y = pl->y + freearr_y[dir];
820 m = pl->map; 818 maptile *m = pl->map;
819
821 mflags = get_map_flags (m, &m, x, y, &x, &y); 820 int mflags = get_map_flags (m, &m, x, y, &x, &y);
822 if (mflags & P_OUT_OF_MAP) 821 if (mflags & P_OUT_OF_MAP)
823 return 0; 822 return 0;
824 823
825 /* Save some processing - we have the flag already anyways 824 /* Save some processing - we have the flag already anyways
826 */ 825 */
828 { 827 {
829 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to."); 828 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to.");
830 return 0; 829 return 0;
831 } 830 }
832 831
832 object *tmp;
833 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above) 833 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
834 { 834 {
835 /* can't persuade players - return because there is nothing else 835 /* can't persuade players - return because there is nothing else
836 * on that space to charm. Same for multi space monsters and 836 * on that space to charm. Same for multi space monsters and
837 * special monsters - we don't allow them to be charmed, and there 837 * special monsters - we don't allow them to be charmed, and there
838 * is no reason to do further processing since they should be the 838 * is no reason to do further processing since they should be the
839 * only monster on the space. 839 * only monster on the space.
840 */ 840 */
841 if (tmp->type == PLAYER) 841 if (tmp->type == PLAYER
842 return 0; 842 || tmp->more || tmp->head_ () != tmp
843 if (tmp->more || tmp->head) 843 || tmp->msg)
844 return 0;
845 if (tmp->msg)
846 return 0; 844 return 0;
847 845
848 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 846 if (QUERY_FLAG (tmp, FLAG_MONSTER))
849 break; 847 break;
850 } 848 }
865 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp)); 863 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp));
866 return 0; 864 return 0;
867 } 865 }
868 866
869 /* it's already allied! */ 867 /* it's already allied! */
870 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && (tmp->attack_movement == PETMOVE)) 868 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->attack_movement == PETMOVE)
871 { 869 {
872 if (tmp->owner == pl) 870 if (tmp->owner == pl)
873 { 871 {
874 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n"); 872 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n");
875 return 0; 873 return 0;
878 { 876 {
879 /* you steal the follower. Perhaps we should really look at the 877 /* you steal the follower. Perhaps we should really look at the
880 * level of the owner above? 878 * level of the owner above?
881 */ 879 */
882 tmp->set_owner (pl); 880 tmp->set_owner (pl);
881 tmp->skill = skill->skill;
882
883 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to follow you instead!\n", query_name (tmp)); 883 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to follow you instead!\n", query_name (tmp));
884 /* Abuse fix - don't give exp since this can otherwise 884 /* Abuse fix - don't give exp since this can otherwise
885 * be used by a couple players to gets lots of exp. 885 * be used by a couple players to gets lots of exp.
886 */ 886 */
887 return 0; 887 return 0;
891 /* In this case, you can't steal it from the other player */ 891 /* In this case, you can't steal it from the other player */
892 return 0; 892 return 0;
893 } 893 }
894 } /* Creature was already a pet of someone */ 894 } /* Creature was already a pet of someone */
895 895
896 chance = skill->level * 2 + (pl->stats.Cha - 2 * tmp->stats.Int) / 2; 896 int level = skill->level + (pl->stats.Cha - tmp->stats.Int) / 2;
897 897
898 /* Ok, got a 'sucker' lets try to make them a follower */ 898 /* Ok, got a 'sucker' lets try to make them a follower */
899 if (chance > 0 && tmp->level < (random_roll (0, chance - 1, pl, PREFER_HIGH) - 1)) 899 if (level > 0 && tmp->level < (random_roll (0, level - 1, pl, PREFER_HIGH) - 1))
900 { 900 {
901 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to become your follower.\n", query_name (tmp)); 901 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to become your follower.\n", query_name (tmp));
902 902
903 tmp->set_owner (pl); 903 tmp->set_owner (pl);
904 tmp->skill = skill->skill;
904 tmp->stats.exp = 0; 905 tmp->stats.exp = 0;
905 add_friendly_object (tmp); 906 add_friendly_object (tmp);
906 tmp->attack_movement = PETMOVE; 907 tmp->attack_movement = PETMOVE;
907 return calc_skill_exp (pl, tmp, skill); 908 return calc_skill_exp (pl, tmp, skill);
908 } 909 }
909
910 /* Charm failed. Creature may be angry now */ 910 /* Charm failed. Creature may be angry now */
911 else if ((skill->level + ((pl->stats.Cha - 10) / 2)) < random_roll (1, 2 * tmp->level, pl, PREFER_LOW)) 911 else if ((skill->level + ((pl->stats.Cha - 10) / 2)) < random_roll (1, 2 * tmp->level, pl, PREFER_LOW))
912 { 912 {
913 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your speech angers the %s!\n", query_name (tmp)); 913 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your speech angers the %s!\n", query_name (tmp));
914 if (QUERY_FLAG (tmp, FLAG_FRIENDLY)) 914 if (QUERY_FLAG (tmp, FLAG_FRIENDLY))
931 * successfully pacified the creature gets Int=1. Thus, a player 931 * successfully pacified the creature gets Int=1. Thus, a player
932 * may only pacify a creature once. 932 * may only pacify a creature once.
933 * BTW, I appologize for the naming of the skill, I couldnt think 933 * BTW, I appologize for the naming of the skill, I couldnt think
934 * of anything better! -b.t. 934 * of anything better! -b.t.
935 */ 935 */
936
937int 936int
938singing (object *pl, int dir, object *skill) 937singing (object *pl, int dir, object *skill)
939{ 938{
940 int i, exp = 0, chance, mflags; 939 int i, exp = 0;
941 object *tmp; 940 object *tmp;
942 maptile *m; 941 maptile *m;
943 sint16 x, y; 942 sint16 x, y;
944 943
945 if (pl->type != PLAYER) 944 if (pl->type != PLAYER)
950 { 949 {
951 x = pl->x + freearr_x[i]; 950 x = pl->x + freearr_x[i];
952 y = pl->y + freearr_y[i]; 951 y = pl->y + freearr_y[i];
953 m = pl->map; 952 m = pl->map;
954 953
955 mflags = get_map_flags (m, &m, x, y, &x, &y); 954 int mflags = get_map_flags (m, &m, x, y, &x, &y);
956 if (mflags & P_OUT_OF_MAP) 955 if (mflags & P_OUT_OF_MAP)
957 continue; 956 continue;
958 if (!(mflags & P_IS_ALIVE)) 957 if (!(mflags & P_IS_ALIVE))
959 continue; 958 continue;
960 959
979 978
980 /* stealing isn't really related (although, maybe it should 979 /* stealing isn't really related (although, maybe it should
981 * be). This is mainly to prevent singing to the same monster 980 * be). This is mainly to prevent singing to the same monster
982 * over and over again and getting exp for it. 981 * over and over again and getting exp for it.
983 */ 982 */
984 chance = skill->level * 2 + (pl->stats.Cha - 5 - tmp->stats.Int) / 2; 983 int level = skill->level + (pl->stats.Cha - 5 - tmp->stats.Int) / 2;
984
985 if (chance && tmp->level * 2 < random_roll (0, chance - 1, pl, PREFER_HIGH)) 985 if (level && tmp->level < random_roll (0, level - 1, pl, PREFER_HIGH))
986 { 986 {
987 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 987 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
988 new_draw_info_format (NDI_UNIQUE, 0, pl, "You calm down the %s\n", query_name (tmp)); 988 new_draw_info_format (NDI_UNIQUE, 0, pl, "You calm down the %s\n", query_name (tmp));
989 /* Give exp only if they are not aware */ 989 /* Give exp only if they are not aware */
990
990 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL)) 991 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL))
991 exp += calc_skill_exp (pl, tmp, skill); 992 exp += calc_skill_exp (pl, tmp, skill);
993
992 SET_FLAG (tmp, FLAG_NO_STEAL); 994 SET_FLAG (tmp, FLAG_NO_STEAL);
993 } 995 }
994 else 996 else
995 { 997 {
996 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp)); 998 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp));
1193 return; 1195 return;
1194 } 1196 }
1195 else 1197 else
1196 { 1198 {
1197 for (tmp = pl->inv; tmp; tmp = tmp->below) 1199 for (tmp = pl->inv; tmp; tmp = tmp->below)
1198 if (((tmp->type == ARMOUR && skill->level < 12) 1200 if (((tmp->type == ARMOUR && skill->level < 12)
1199 || (tmp->type == HELMET && skill->level < 10) 1201 || (tmp->type == HELMET && skill->level < 10)
1200 || (tmp->type == SHIELD && skill->level < 6) 1202 || (tmp->type == SHIELD && skill->level < 6)
1201 || (tmp->type == BOOTS && skill->level < 4) || (tmp->type == GLOVES && skill->level < 2)) && QUERY_FLAG (tmp, FLAG_APPLIED)) 1203 || (tmp->type == BOOTS && skill->level < 4)
1204 || (tmp->type == GLOVES && skill->level < 2))
1205 && QUERY_FLAG (tmp, FLAG_APPLIED))
1202 { 1206 {
1203 new_draw_info (NDI_UNIQUE, 0, pl, "You can't concentrate while wearing so much armour!\n"); 1207 new_draw_info (NDI_UNIQUE, 0, pl, "You can't concentrate while wearing so much armour!\n");
1204 return; 1208 return;
1205 } 1209 }
1206 } 1210 }
1383 insert_ob_in_ob (tmp, newscroll); 1387 insert_ob_in_ob (tmp, newscroll);
1384 1388
1385 /* Same code as from treasure.c - so they can better merge. 1389 /* Same code as from treasure.c - so they can better merge.
1386 * if players want to sell them, so be it. 1390 * if players want to sell them, so be it.
1387 */ 1391 */
1388 newscroll->value = newscroll->arch->clone.value * newscroll->inv->value * (newscroll->level + 50) / (newscroll->inv->level + 50); 1392 newscroll->value = newscroll->arch->value * newscroll->inv->value * (newscroll->level + 50) / (newscroll->inv->level + 50);
1389 newscroll->stats.exp = newscroll->value / 5; 1393 newscroll->stats.exp = newscroll->value / 5;
1390 1394
1391 /* wait until finished manipulating the scroll before inserting it */ 1395 /* wait until finished manipulating the scroll before inserting it */
1392 if (newscroll == scroll) 1396 if (newscroll == scroll)
1393 { 1397 {
1450 } 1454 }
1451 1455
1452 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY); 1456 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY);
1453 1457
1454 /* Need to be able to read before we can write! */ 1458 /* Need to be able to read before we can write! */
1455 if (!find_skill_by_name (pl, skat->clone.skill)) 1459 if (!find_skill_by_name (pl, skat->skill))
1456 { 1460 {
1457 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write!"); 1461 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write!");
1458 return 0; 1462 return 0;
1459 } 1463 }
1460 1464

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines