Instructions for adding semi-intelligent mob use of weapons. By Mark Garringer -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The idea here is that mobs should try to make use of better weapons they are carrying around in their inventories. Rather than continuing to wield a dagger it was loaded with, if it finds a long sword for example. There are some changes that have been made to my code base that are no standard to Circle. First and foremost, I have made changes in mobact.c to allow aggressive mobs to fight with each other instead of just with PCs. In mobile_activity look for /* Aggressive Mobs */ and change the line: if (IS_NPC(vict) || !CAN_SEE(ch, vict) || PRF_FLAGGED(vict, PRF_NOHASSLE)) to: if (!CAN_SEE(ch, vict) || (!IS_NPC(vict) && PRF_FLAGGED(vict, PRF_NOHASSLE))) you should also add this: if (vict == ch) continue; Below so that aggressive mobs will not try to kill themselves. Ok, now you are off and running. Mobs are fighting each other! You might also want to add something near your AUTOLOOT/AUTOGOLD checks so that mobs are doing corpse looting of their own. (Usually in fight.c) My own code base allows for mobs defined as race types considered to be humanoid to loot corpses. (Thus animals, snakes, fish, insects etc, are not trying to get stuff they have no logical use for.) Of course my mobs are all loaded with a race and class as well, but that is something else entirely. So given this, you now have mobs fighting each other, collecting equipment and looting the corpse of players they have killed. (This pisses off players to no end, especially since shortly we are going to allow mobs to start using better equipment they find.) Towards the end of mobile_activity it says to /* Add new mobile actions here */ Insert the following: if (IS_HUMANOID(ch) && ((ch)->mob_specials.newitem != 0) && ! (mob_index[GET_MOB_RNUM(ch)].func == shop_keeper) ) { if (IS_WIELDING(ch)) { wield_obj = ch->equipment[WEAR_WIELD]; best_obj = wield_obj; for (i = 0; i < MAX_OBJ_AFFECT; i++) { if (wield_obj->affected[i].location == APPLY_DAMROLL) a1 = wield_obj->affected[i].modifier; } max =(((GET_OBJ_VAL(wield_obj, 2)+a1+1)/2.0) * GET_OBJ_VAL(wield_obj, 1)); } else { wield_obj = NULL; best_obj = NULL; max = 1; } a1 = 0; a2 = 0; for (obj = ch->carrying; obj; obj = obj-> next_content) { if (GET_OBJ_TYPE(obj) == ITEM_WEAPON) { for (i = 0; i < MAX_OBJ_AFFECT; i++) { if (obj->affected[i].location == APPLY_DAMROLL) a2 = obj->affected[i].modifier; } dam2 =(((GET_OBJ_VAL(obj, 2)+a2+ 1) / 2.0) * GET_OBJ_VAL(obj, 1)); if (dam2 > max) { if (!invalid_align(ch, obj) && !invalid_class(ch, obj)) { best_obj = obj; for (i = 0; i < MAX_OBJ_AFFECT; i++) { if (best_obj->affected[i].location == APPLY_DAMROLL) a2 = best_obj->affected[i].modifier; } max=(((GET_OBJ_VAL(best_obj,2)+a2+1)/2.0)*GET_OBJ_VAL(best_obj, 1)); } } else (ch)->mob_specials.newitem = 0; } } if (IS_WIELDING(ch)) { if (wield_obj != best_obj) { perform_remove(ch, WEAR_WIELD); perform_wear(ch, best_obj, WEAR_WIELD); (ch)->mob_specials.newitem = 0; } } else { if (best_obj != NULL) perform_wear(ch, best_obj, WEAR_WIELD); (ch)->mob_specials.newitem = 0; } } You will need to add the following to the top of mobact.c: void perform_wear(struct char_data * ch, struct obj_data * obj, int where); void perform_remove(struct char_data * ch, int pos); int invalid_class(struct char_data *ch, struct obj_data *obj); SPECIAL(shop_keeper); *Note* You only need to add invalid_class if you are using classes for your mobs which I highly recommend. You will also have to add these to mobile_activity: (can be appended to other defines of the same types) struct obj_data *wield_obj; int i, a1 = 0, a2 = 0; float max, dam2; /* Thanks to Chet Kress for fixing this! */ You might be saying to yourself at this point, where the hell did mob_specials.newitem come from and what is it for? Well, this is to limit the looping of mobs checking their inventory to see if they should change weapons. In structs.h add the following of mob_special_data: int newitem; /* Check if mob has new inv item */ You also need to make some change to act.item.c so when I mob gets or is given a weapon it changes the value of newitem so it then knows it is ok to see if it now has a better weapon. In perform_get_from_room add: if (IS_NPC(ch) && GET_OBJ_TYPE(obj) == ITEM_WEAPON) (ch)->mob_specials.newitem = 1; After the two act statements will be just fine. Still in act.item.c in perform_give add: if (IS_NPC(vict) && GET_OBJ_TYPE(obj) == ITEM_WEAPON) (vict)->mob_specials.newitem = 1; Again, after the act statements is fine. Finally (I think) you should initialize newitem to 0 when the mobs are loaded in db.c add: mob_proto[i].mob_specials.newitem = 0; After where it sets weight and height for mobs is fine. If you have questions or even modifications/bug reports for this code please send them to me. If you have problems I can try to help you, but my C is not that hot so my support is limited. I think this is all. My MUD had quite a few non-standard modifications so if this does not plug right in I am sorry. I have spent a lot of time on this code, and even though it is ugly in some spots it seems to work VERY well. If you use it, please give me some props in your credits file or something: Zizazat Lazuras (zizazat@hotmail.com)