[CF-Devel] Monsters not using wands/rods/horns
crossfire-devel at archives.real-time.com
crossfire-devel at archives.real-time.com
Sat May 8 05:21:32 CDT 2004
Hello.
I've noticed some monsters don't use wands/rods/horns anymore.
Tracking the issue, I found some hints:
* monster_check_apply, which is used when a just generated item is put
in monster inventory, will use manual_apply on the rod/wand/horn.
Which checks for skill, ie 'use magic item'. But sometimes the monster
doesn't have it yet (treasure list _after_ current one).
* even if the monster has it 'FLAG_CAN_USE_SKILL' is not set, so skill
can't be used.
* also, change_skill is called for monsters when applying item, thus
crash (who->contr == NULL)
I attached a patch that enables monsters to fire their favorite
wand/horn/rod :)
It's dirty, and probably has some redundance (like 'FLAG_APPLIED' is
set, but never really tested)
Basically i grabbed the wand/rod firing code from
server/player.c:fire_misc_object( ), and pasted it in
server/monster.c:monster_use_range( ) to actually fire rod/bow.
I think we should, at some point, use only one logic for players /
monsters when firing bow/range, and for skills/spells too.
Though java editor can't link between 'can use wands' flag and the
'use magic item' skill which is required, so that isn't great.
Ryo
-------------- next part --------------
Index: server/monster.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/monster.c,v
retrieving revision 1.69
diff -u -r1.69 monster.c
--- server/monster.c 14 Apr 2004 07:24:30 -0000 1.69
+++ server/monster.c 8 May 2004 10:05:59 -0000
@@ -894,8 +894,10 @@
/* Monster will use a ranged spell attack. */
-int monster_use_range(object *head,object *part,object *pl,int dir) {
+int monster_use_range(object *head,object *part,object *pl,int dir) + {
object *wand, *owner;
+ int at_least_one = 0;
if(!(dir=path_to_player(part,pl,0)))
return 0;
@@ -909,49 +911,54 @@
dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2);
for(wand=head->inv;wand!=NULL;wand=wand->below)
- if(QUERY_FLAG(wand,FLAG_APPLIED) &&
- (wand->type == WAND || wand->type == ROD || wand->type==HORN))
- break;
+ {
+ if (wand->type == WAND)
+ {
+ /* Found a wand, let's see if it has charges left */
+ at_least_one = 1;
+ if( wand->stats.food<=0 )
+ continue;
+
+ cast_spell( head, wand, dir, wand->inv, NULL );
+
+ if ( !( --wand->stats.food ) )
+ {
+ object *tmp;
+ if ( wand->arch )
+ {
+ CLEAR_FLAG(wand, FLAG_ANIMATE);
+ wand->face = wand->arch->clone.face;
+ wand->speed = 0;
+ update_ob_speed(wand);
+ }
+ }
+ /* Success */
+ return 1;
+ }
+ else if ( wand->type == ROD || wand->type==HORN )
+ {
+ /* Found rod/horn, let's use it if possible */
+ at_least_one = 1;
+ if( wand->stats.hp < MAX( wand->inv->stats.sp, wand->inv->stats.grace ) )
+ continue;
+
+ cast_spell( head, wand, dir, wand->inv, NULL );
+
+ drain_rod_charge( wand );
+
+ /* Success */
+ return 1;
+ }
+ }
+
+ if ( at_least_one )
+ return 0;
- if(wand==NULL) {
- LOG(llevError,"Error: Monster %s (%d) HAS_READY_RANG() without range.\n",
+ LOG(llevError,"Error: Monster %s (%d) HAS_READY_RANG() without wand/horn/rod.\n",
head->name,head->count);
CLEAR_FLAG(head, FLAG_READY_RANGE);
return 0;
}
- if (!wand->inv) {
- LOG(llevError,"Wand %s lacks spell\n", wand->name);
- return 0;
- }
- if (wand->type == WAND) {
- if(wand->stats.food<=0) {
- manual_apply(head,wand,0);
- CLEAR_FLAG(head, FLAG_READY_RANGE);
- if (wand->arch) {
- CLEAR_FLAG(wand, FLAG_ANIMATE);
- wand->face = wand->arch->clone.face;
- wand->speed = 0;
- update_ob_speed(wand);
- }
- return 0;
- }
- }
- else {
- if(wand->stats.hp<MAX(wand->inv->stats.sp, wand->inv->stats.grace))
- return 0; /* Not recharged enough yet */
- }
-
- /* Spell should be cast on caster (ie, heal, strength) */
- if (wand->inv->range==0)
- dir = 0;
-
- if(cast_spell(part,wand,dir,wand->inv,NULL)) {
- if (wand->type==WAND)
- wand->stats.food--;
- return 1;
- }
- return 0;
-}
int monster_use_bow(object *head, object *part, object *pl, int dir) {
object *owner;
@@ -1246,16 +1253,40 @@
else if (item->type == WEAPON) flag = check_good_weapon(mon,item);
else if (IS_ARMOR(item)) flag = check_good_armour(mon,item);
/* Should do something more, like make sure this is a better item */
- else if (item->type == SKILL || item->type == RING || item->type==WAND ||
- item->type == ROD || item->type==HORN) flag=1;
+ else if (item->type == RING)
+ flag=1;
+ else if ( item->type==WAND || item->type == ROD || item->type==HORN )
+ {
+ /* We never really 'ready' the wand/rod/horn, because that would mean the
+ * weapon would get undone.
+ */
+ if (!(can_apply_object(mon, item) & CAN_APPLY_NOT_MASK))
+ {
+ SET_FLAG(mon, FLAG_READY_RANGE);
+ SET_FLAG(item, FLAG_APPLIED);
+ }
+ return;
+ }
else if (item->type == BOW) {
- /* We never really 'ready' the bow, because that would mean the
- * weapon would get undone.
- */
- if (!(can_apply_object(mon, item) & CAN_APPLY_NOT_MASK))
- SET_FLAG(mon, FLAG_READY_BOW);
- return;
- }
+ /* We never really 'ready' the bow, because that would mean the
+ * weapon would get undone.
+ */
+ if (!(can_apply_object(mon, item) & CAN_APPLY_NOT_MASK))
+ SET_FLAG(mon, FLAG_READY_BOW);
+ return;
+ }
+ else if ( item->type == SKILL )
+ {
+ /*
+ * Ryo 2004-05-08
+ * skills are specials: monsters must have the 'FLAG_CAN_USE_SKILL' flag set,
+ * else they can't use the skill...
+ * Skills also don't need to get applied, so return now.
+ */
+ SET_FLAG( item, FLAG_CAN_USE_SKILL );
+ return;
+ }
+
/* if we don't match one of the above types, return now.
* can_apply_object will say that we can apply things like flesh,
@@ -1270,7 +1301,6 @@
*/
if (can_apply_object(mon, item) & CAN_APPLY_NOT_MASK) return;
-
/* should only be applying this item, not unapplying it.
* also, ignore status of curse so they can take off old armour.
* monsters have some advantages after all.
Index: server/skill_util.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/skill_util.c,v
retrieving revision 1.47
diff -u -r1.47 skill_util.c
--- server/skill_util.c 8 Apr 2004 06:48:51 -0000 1.47
+++ server/skill_util.c 8 May 2004 10:06:01 -0000
@@ -229,7 +229,12 @@
int change_skill (object *who, object *new_skill, int flag)
{
- int old_range = who->contr->shoottype;
+ int old_range;
+
+ if ( who->type != PLAYER )
+ return 0;
+
+ old_range = who->contr->shoottype;
if (who->chosen_skill && who->chosen_skill == new_skill)
{
-------------- next part --------------
_______________________________________________
crossfire-devel mailing list
crossfire-devel at lists.real-time.com
https://mailman.real-time.com/mailman/listinfo/crossfire-devel
More information about the crossfire
mailing list