Mobprogs addon v1.1 by Kracus Credit for Mobprogs: Originally appeared in: Merc release 2.2 Wednesday 24 November 1993 N'atas-Ha natasha@gs118.sp.cs.cmu.edu Kahn Modified for ROM 2.4 in January 1996 Newt@Imperium Gothique Thanks to Newt for the rewrite of Mobprogs for Rom2.4! In the sections below is the provided additions to the Mobprogs code. There are also some bug fixes which are commented. To add the bugfixes just replace the older code with the code provided below or if a + appears in the code add those lines to your code in the specified section of code. These are simple, but nice additions to the Mobprog Code. With the affected2 check it allows you to check for any affects2 if you installed affects2 instead of an array system for bits. The manacnt and movecnt are useful for determining the mana or movement of a character($n/$q) and if their mana or movement is low a Mob(Mobprog) could use mob cast to use a spell and restore the character's mana or movement. + Means to add that line of code in - Means to delete that line of code -Kracus FILE: mob_prog.c Kracus- add these defines in for new Mobprog checks + #define CHK_AFFECTED2 (52) + #define CHK_MANACNT (53) + #define CHK_MOVECNT (54) ========================= Kracus- in const char * fn_keyword[] add these... === + "affected2", /* if affected2 $n affect2name - is $n affected2 by an affect2 */ + "manacnt", /* if manacnt $i > 30 - mana point percent check */ + "movecnt", /* if movecnt $i > 30 - move point percent check */ ========================= Kracus- in int cmd_eval() add these...=== ALSO NOTE: several bugfixes included for class && money=== Add this in below case CHK_AFFECTED + case CHK_AFFECTED2: // Kracus- check for affects2 if you have them + return( lval_char != NULL + && IS_SET(lval_char->affected2_by, flag_lookup(buf, affect2_flags)) ); Replace case CHK_CLASS with the below code + // Kracus- bugfix for case class + case CHK_CLASS: + return( lval_char != NULL && lval_char->class == class_lookup( buf ) ); Add these in below case CHK_HPCNT + case CHK_MANACNT: // Kracus- check for mana + if ( lval_char != NULL ) lval = (lval_char->mana * 100)/(UMAX(1,lval_char->max_mana)); break; + case CHK_MOVECNT: // Kracus- check for movement + if ( lval_char != NULL ) lval = (lval_char->move * 100)/(UMAX(1,lval_char->max_move)); break; Replace case CHK_MONEY with the below code + // Kracus- bugfix where silver and gold were switched around + case CHK_MONEY: // Money check, gold converted to silver ratio 100silver = 1gold + if ( lval_char != NULL ) + lval = lval_char->silver + (lval_char->gold * 100); break; ========================= Kracus- bugfix if you have OLC for Mobprog note triggers ADD in +lines below in your mp_act_trigger if you have OLC void mp_act_trigger( char *argument, CHAR_DATA *mob, CHAR_DATA *ch, const void *arg1, const void *arg2, int type ) { MPROG_LIST *prg; + // bugfix for note and act_new if Ivan's OLC + if(!IS_NPC(ch)) + return; for ( prg = mob->pIndexData->mprogs; prg != NULL; prg = prg->next ) { if ( prg->trig_type == type && strstr( argument, prg->trig_phrase ) != NULL ) { program_flow( prg->vnum, prg->code, mob, ch, arg1, arg2 ); break; } } return; } ========================= END for FILE: mob_prog.c FILE: mob_cmds.c Kracus- coded new mptranfer and mpgtranfer These 2 functions take into account for pets and also a group transfer function that works better Replace old mptransfer and mpgtransfer with the code below // Kracus- Mobile Transfer: // -victin and ach has to be in same room as Mob for 'all' // -victim(char being transferred) // -victim->pet(char's pet being transferred, set to TRUE) // -ach(all char in original room as victim) // -ach->pet(all char's pets NOT transferred) //Note: 'all' argument transfers all characters in the room //Syntax: mob transfer [target|'all'] [location] void do_mptransfer( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; CHAR_DATA *ach; CHAR_DATA *ach_next; ROOM_INDEX_DATA *location; ROOM_INDEX_DATA *room; bool mptransfer_pet; argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (arg1[0] == '\0') { bug("Mptransfer - Bad syntax from vnum %d.", IS_NPC(ch) ? ch->pIndexData->vnum : 0); return; } room = ch->in_room; if (!str_cmp(arg1, "all")) { if (arg2[0] == '\0') { location = ch->in_room; } else { if ((location = find_location(ch, arg2)) == NULL) { bug("Mptransfer - No such location from vnum %d.", IS_NPC(ch) ? ch->pIndexData->vnum : 0); return; } if (room_is_private(location)) return; } if ((victim = get_char_world(ch, arg1)) == NULL) return; if (victim->in_room == NULL) return; if (victim->pet != NULL && victim->in_room == victim->pet->in_room) mptransfer_pet = FALSE; // Set to TRUE if you want pets to gate else mptransfer_pet = FALSE; if (IS_NPC(victim)) return; if (victim->fighting != NULL) stop_fighting(victim, TRUE); char_from_room(victim); char_to_room(victim, location); do_look(victim, "auto"); // Transfer the victim's pet if (mptransfer_pet) { char_from_room(victim->pet); char_to_room(victim->pet, location); do_look(victim->pet, "auto"); } // Transfer all people that were in the original room as the victim for (ach = room->people; ach != NULL; ach = ach_next) { ach_next = ach->next_in_room; // Stop the ach if he is in a fight if (ach != victim && ach->fighting != NULL) stop_fighting(ach, TRUE); if (ach != victim && !IS_NPC(ach)) { char_from_room(ach); char_to_room(ach, location); do_look(ach, "auto"); } } return; } // end str_cmp 'all' // Thanks to Grodyn for the optional location parameter. if (arg2[0] == '\0') { location = ch->in_room; } else { if ((location = find_location(ch, arg2)) == NULL) { bug("Mptransfer - No such location from vnum %d.", IS_NPC(ch) ? ch->pIndexData->vnum : 0); return; } if (room_is_private(location)) return; } if ((victim = get_char_world(ch, arg1)) == NULL) return; if (victim->in_room == NULL) return; if (victim->fighting != NULL) stop_fighting(victim, TRUE); char_from_room(victim); char_to_room(victim, location); do_look(victim, "auto"); return; } // Kracus- Group Transfer: victin and gch has to be in same room as Mob // -victim(char being transferred) // -victim->pet(char's pet being transferred, set TRUE) // -gch(group members of victim) // -gch->pet(group member's pet NOT transferred) // Syntax: mob gtransfer [victim] [location] void do_mpgtransfer( CHAR_DATA *ch, char *argument ) { char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; CHAR_DATA *gch; CHAR_DATA *gch_next; CHAR_DATA *victim; ROOM_INDEX_DATA *room; ROOM_INDEX_DATA *location; bool mpgtransfer_pet; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if (arg1[0] == '\0') { bug("Mpgtransfer - Bad syntax from vnum %d.", IS_NPC(ch) ? ch->pIndexData->vnum : 0); return; } if ((victim = get_char_room( ch, arg1 )) == NULL) return; if (victim->pet != NULL && victim->in_room == victim->pet->in_room) mpgtransfer_pet = FALSE; // Set to TRUE if you want pet transfer else mpgtransfer_pet = FALSE; // Save roommates of the victim for group gate room = victim->in_room; if (arg2[0] == '\0') { location = ch->in_room; } else { if ((location = find_location(ch, arg2)) == NULL) { bug("Mptransfer - No such location from vnum %d.", IS_NPC(ch) ? ch->pIndexData->vnum : 0); return; } if (room_is_private(location)) return; } if (victim->in_room == NULL) return; // Stop the victim if he is in a fight if (victim->fighting != NULL) stop_fighting(victim, TRUE); if(victim->position != POS_STANDING) return; // Transfer the victim char_from_room(victim); char_to_room(victim, location); do_look(victim, "auto"); // Transfer the victim's pet if (mpgtransfer_pet) { char_from_room(victim->pet); char_to_room(victim->pet, location); do_look(victim->pet, "auto"); } // Transfer all group member's of the victim that were in the original room for (gch = room->people; gch != NULL; gch = gch_next) { gch_next = gch->next_in_room; // Stop the gch if he is in a fight if (gch != victim && gch->fighting != NULL) stop_fighting(gch, TRUE); if (gch != victim && (gch->position == POS_STANDING) && is_same_group(gch, victim)) { char_from_room(gch); char_to_room(gch, location); do_look(gch, "auto"); } } return; } ========================= Kracus- bugfix for mpremove calling unequip_char and logging a bug when it did not need to. Since, unequip_char logs a bug whenever it tries to unequip the char and the char is not equipped, the mpremove function did not check for wear_loc != -1, and not do an equip_char. ADD in +lines below into your mpremove function void do_mpremove( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; OBJ_DATA *obj, *obj_next; sh_int vnum = 0; bool fAll = FALSE; char arg[ MAX_INPUT_LENGTH ]; argument = one_argument( argument, arg ); if ( ( victim = get_char_room( ch, arg ) ) == NULL ) return; one_argument( argument, arg ); if ( !str_cmp( arg, "all" ) ) fAll = TRUE; else if ( !is_number( arg ) ) { bug ( "MpRemove: Invalid object from vnum %d.", IS_NPC(ch) ? ch->pIndexData->vnum : 0 ); return; } else vnum = atoi( arg ); for ( obj = victim->carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if ( fAll || obj->pIndexData->vnum == vnum ) { + // Kracus- check for wear_loc if not wearing unequip, extract + if (obj->wear_loc != -1) + { unequip_char( ch, obj ); obj_from_char (obj ); extract_obj( obj ); + } + else // Kracus- else if not wearing, but in inventory extract + { + obj_from_char( obj ); + extract_obj( obj ); + } } } } ======================== END for FILE: mob_cmds.c