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

Comparing deliantra/server/server/monster.C (file contents):
Revision 1.78 by root, Sun Feb 7 04:22:33 2010 UTC vs.
Revision 1.84 by root, Sat Apr 10 04:42:44 2010 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 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 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.
277static int 277static int
278move_randomly (object *op) 278move_randomly (object *op)
279{ 279{
280 /* Give up to 15 chances for a monster to move randomly */ 280 /* Give up to 15 chances for a monster to move randomly */
281 for (int i = 0; i < 15; i++) 281 for (int i = 0; i < 15; i++)
282 if (move_object (op, rndm (8) + 1)) 282 if (op->move (rndm (8) + 1))
283 return 1; 283 return 1;
284 284
285 return 0; 285 return 0;
286} 286}
287 287
433 switch (tmp->type) 433 switch (tmp->type)
434 { 434 {
435 case T_HANDLE: 435 case T_HANDLE:
436 case TRIGGER: 436 case TRIGGER:
437 if (monster->will_apply & 1) 437 if (monster->will_apply & 1)
438 manual_apply (monster, tmp, 0); 438 monster->apply (tmp);
439 break; 439 break;
440 440
441 case TREASURE: 441 case TREASURE:
442 if (monster->will_apply & 2) 442 if (monster->will_apply & 2)
443 manual_apply (monster, tmp, 0); 443 monster->apply (tmp);
444 break; 444 break;
445 445
446 } 446 }
447 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 447 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
448 break; 448 break;
670 670
671 /* should only be applying this item, not unapplying it. 671 /* should only be applying this item, not unapplying it.
672 * also, ignore status of curse so they can take off old armour. 672 * also, ignore status of curse so they can take off old armour.
673 * monsters have some advantages after all. 673 * monsters have some advantages after all.
674 */ 674 */
675 manual_apply (mon, item, AP_APPLY | AP_IGNORE_CURSE); 675 mon->apply (item, AP_APPLY | AP_IGNORE_CURSE);
676} 676}
677 677
678static int 678static int
679can_hit (object *ob1, object *ob2, rv_vector * rv) 679can_hit (object *ob1, object *ob2, rv_vector * rv)
680{ 680{
786 static int circle[12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 }; 786 static int circle[12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 };
787 787
788 if (++ob->move_status > 11) 788 if (++ob->move_status > 11)
789 ob->move_status = 0; 789 ob->move_status = 0;
790 790
791 if (!(move_object (ob, circle[ob->move_status]))) 791 if (!(ob->move (circle[ob->move_status])))
792 move_object (ob, rndm (8) + 1); 792 ob->move (rndm (8) + 1);
793} 793}
794 794
795static void 795static void
796circ2_move (object *ob) 796circ2_move (object *ob)
797{ 797{
798 static int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 }; 798 static int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 };
799 799
800 if (++ob->move_status > 19) 800 if (++ob->move_status > 19)
801 ob->move_status = 0; 801 ob->move_status = 0;
802 802
803 if (!(move_object (ob, circle[ob->move_status]))) 803 if (!(ob->move (circle[ob->move_status])))
804 move_object (ob, rndm (8) + 1); 804 ob->move (rndm (8) + 1);
805} 805}
806 806
807static void 807static void
808pace_movev (object *ob) 808pace_movev (object *ob)
809{ 809{
810 if (ob->move_status++ > 6) 810 if (ob->move_status++ > 6)
811 ob->move_status = 0; 811 ob->move_status = 0;
812 812
813 if (ob->move_status < 4) 813 if (ob->move_status < 4)
814 move_object (ob, 5); 814 ob->move (5);
815 else 815 else
816 move_object (ob, 1); 816 ob->move (1);
817} 817}
818 818
819static void 819static void
820pace_moveh (object *ob) 820pace_moveh (object *ob)
821{ 821{
822 if (ob->move_status++ > 6) 822 if (ob->move_status++ > 6)
823 ob->move_status = 0; 823 ob->move_status = 0;
824 824
825 if (ob->move_status < 4) 825 if (ob->move_status < 4)
826 move_object (ob, 3); 826 ob->move (3);
827 else 827 else
828 move_object (ob, 7); 828 ob->move (7);
829} 829}
830 830
831static void 831static void
832pace2_movev (object *ob) 832pace2_movev (object *ob)
833{ 833{
834 if (ob->move_status++ > 16) 834 if (ob->move_status++ > 16)
835 ob->move_status = 0; 835 ob->move_status = 0;
836 836
837 if (ob->move_status < 6) 837 if (ob->move_status < 6)
838 move_object (ob, 5); 838 ob->move (5);
839 else if (ob->move_status < 8) 839 else if (ob->move_status < 8)
840 return; 840 return;
841 else if (ob->move_status < 13) 841 else if (ob->move_status < 13)
842 move_object (ob, 1); 842 ob->move (1);
843 else 843 else
844 return; 844 return;
845} 845}
846 846
847static void 847static void
849{ 849{
850 if (ob->move_status++ > 16) 850 if (ob->move_status++ > 16)
851 ob->move_status = 0; 851 ob->move_status = 0;
852 852
853 if (ob->move_status < 6) 853 if (ob->move_status < 6)
854 move_object (ob, 3); 854 ob->move (3);
855 else if (ob->move_status < 8) 855 else if (ob->move_status < 8)
856 return; 856 return;
857 else if (ob->move_status < 13) 857 else if (ob->move_status < 13)
858 move_object (ob, 7); 858 ob->move (7);
859 else 859 else
860 return; 860 return;
861} 861}
862 862
863static void 863static void
864rand_move (object *ob) 864rand_move (object *ob)
865{ 865{
866 if (ob->move_status < 1 || ob->move_status > 8 || !(move_object (ob, ob->move_status || !(rndm (9))))) 866 if (ob->move_status < 1 || ob->move_status > 8 || !(ob->move (ob->move_status || !(rndm (9)))))
867 for (int i = 0; i < 5; i++) 867 for (int i = 0; i < 5; i++)
868 if (move_object (ob, ob->move_status = rndm (8) + 1)) 868 if (ob->move (ob->move_status = rndm (8) + 1))
869 return; 869 return;
870} 870}
871 871
872#define MAX_KNOWN_SPELLS 20 872#define MAX_KNOWN_SPELLS 20
873 873
1060 } 1060 }
1061 1061
1062 if (QUERY_FLAG (head, FLAG_CONFUSED)) 1062 if (QUERY_FLAG (head, FLAG_CONFUSED))
1063 dir = absdir (dir + rndm (3) + rndm (3) - 2); 1063 dir = absdir (dir + rndm (3) + rndm (3) - 2);
1064 1064
1065 object *new_skill = 0;
1066
1065 /* skill selection - monster will use the next unused skill. 1067 // skill selection - monster will use the last unused skill
1066 * well...the following scenario will allow the monster to 1068 // and rotate, eventually cycling through all skills.
1067 * toggle between 2 skills. One day it would be nice to make
1068 * more skills available to monsters.
1069 */
1070 for (skill = head->inv; skill; skill = skill->below) 1069 for (skill = head->inv; skill; skill = skill->below)
1071 if (skill->type == SKILL && skill != head->chosen_skill) 1070 if (skill->type == SKILL && skill != head->chosen_skill)
1072 { 1071 new_skill = skill;
1072
1073 if (new_skill)
1073 head->chosen_skill = skill; 1074 splay (head->chosen_skill = new_skill);
1074 break;
1075 }
1076
1077 if (!skill && !head->chosen_skill) 1075 else if (!head->chosen_skill)
1078 { 1076 {
1079 LOG (llevDebug, "Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", &head->name, head->count); 1077 LOG (llevDebug, "Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", &head->name, head->count);
1080 CLEAR_FLAG (head, FLAG_READY_SKILL); 1078 CLEAR_FLAG (head, FLAG_READY_SKILL);
1081 return 0; 1079 return 0;
1082 } 1080 }
1288 { 1286 {
1289 /* last heal is in funny units. Dividing by speed puts 1287 /* last heal is in funny units. Dividing by speed puts
1290 * the regeneration rate on a basis of time instead of 1288 * the regeneration rate on a basis of time instead of
1291 * #moves the monster makes. The scaling by 8 is 1289 * #moves the monster makes. The scaling by 8 is
1292 * to capture 8th's of a hp fraction regens 1290 * to capture 8th's of a hp fraction regens
1293 *
1294 * Cast to sint32 before comparing to maxhp since otherwise an (sint16)
1295 * overflow might produce monsters with negative hp.
1296 */ 1291 */
1297 1292 uint32_t last_heal = op->last_heal + op->stats.Con * 8 / op->speed;
1298 op->last_heal += (int) ((float) (8 * op->stats.Con) / op->speed);
1299 op->stats.hp = min ((sint32) op->stats.hp + op->last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */ 1293 op->stats.hp = min (op->stats.hp + last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */
1300 op->last_heal %= 32; 1294 op->last_heal = last_heal % 32;
1301 1295
1302 /* So if the monster has gained enough HP that they are no longer afraid */ 1296 /* So if the monster has gained enough HP that they are no longer afraid */
1303 if (QUERY_FLAG (op, FLAG_RUN_AWAY) && op->stats.hp >= (signed short)(((float)op->run_away / 100.f) * (float)op->stats.maxhp)) 1297 if (op->flag [FLAG_RUN_AWAY] && op->stats.hp * 100 >= op->stats.maxhp * op->run_away)
1304 CLEAR_FLAG (op, FLAG_RUN_AWAY); 1298 op->flag [FLAG_RUN_AWAY] = false;
1305
1306 if (op->stats.hp > op->stats.maxhp)
1307 op->stats.hp = op->stats.maxhp;
1308 } 1299 }
1309 1300
1310 /* generate sp, if applicable */ 1301 /* generate sp, if applicable */
1311 if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp) 1302 if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp)
1312 { 1303 {
1313 /* last_sp is in funny units. Dividing by speed puts 1304 /* last_sp is in funny units. Dividing by speed puts
1314 * the regeneration rate on a basis of time instead of 1305 * the regeneration rate on a basis of time instead of
1315 * #moves the monster makes. The scaling by 8 is 1306 * #moves the monster makes. The scaling by 8 is
1316 * to capture 8th's of a sp fraction regens 1307 * to capture 8th's of a sp fraction regens
1317 *
1318 * Cast to sint32 before comparing to maxhp since otherwise an (sint16)
1319 * overflow might produce monsters with negative sp.
1320 */ 1308 */
1321 1309
1322 op->last_sp += (int) ((float) (8 * op->stats.Pow) / op->speed); 1310 uint32_t last_sp = op->last_sp + op->stats.Pow * 8 / op->speed;
1323 op->stats.sp = min (op->stats.sp + op->last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */ 1311 op->stats.sp = min (op->stats.sp + last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */
1324 op->last_sp %= 128; 1312 op->last_sp = last_sp % 128;
1325 } 1313 }
1326 1314
1327 /* this should probably get modified by many more values. 1315 /* this should probably get modified by many more values.
1328 * (eg, creatures resistance to fear, level, etc. ) 1316 * (eg, creatures resistance to fear, level, etc. )
1329 */ 1317 */
1580 if (!dir) 1568 if (!dir)
1581 return 0; 1569 return 0;
1582 1570
1583 if (!QUERY_FLAG (op, FLAG_STAND_STILL)) 1571 if (!QUERY_FLAG (op, FLAG_STAND_STILL))
1584 { 1572 {
1585 if (move_object (op, dir)) /* Can the monster move directly toward player? */ 1573 if (op->move (dir)) /* Can the monster move directly toward player? */
1586 { 1574 {
1587 /* elmex: Turn our monster after it moved if it has DISTATT attack */ 1575 /* elmex: Turn our monster after it moved if it has DISTATT attack */
1588 if ((op->attack_movement & LO4) == DISTATT) 1576 if ((op->attack_movement & LO4) == DISTATT)
1589 op->direction = pre_att_dir; 1577 op->direction = pre_att_dir;
1590 1578
1599 for (diff = 1; diff <= maxdiff; diff++) 1587 for (diff = 1; diff <= maxdiff; diff++)
1600 { 1588 {
1601 /* try different detours */ 1589 /* try different detours */
1602 int m = 1 - rndm (2) * 2; /* Try left or right first? */ 1590 int m = 1 - rndm (2) * 2; /* Try left or right first? */
1603 1591
1604 if (move_object (op, absdir (dir + diff * m)) || move_object (op, absdir (dir - diff * m))) 1592 if (op->move (absdir (dir + diff * m)) || op->move (absdir (dir - diff * m)))
1605 return 0; 1593 return 0;
1606 } 1594 }
1607 } 1595 }
1608 } /* if monster is not standing still */ 1596 } /* if monster is not standing still */
1609 1597

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines