[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