'lo... After looking at the weapon spell addition, I didn't particularly like the way it worked, too limiting. So here's how I did it. Hope you enjoy it. In db.c ------ in char *parse_object() -------------- case 'S': /* Weapon Spells Can pick a different letter if you used that. */ if(!get_line(obj_f,line)) { log("SYSERR: Format error in 'S' field, %s. Expecting numeric constants, but file ended!",buf2); exit(1); } if((retval=sscanf(line, " %d %d %d ", t, t+1, t+2))!=3) { log("SYSERR: Format error in 'S' field, %s expecting 3 numeric args, got %d. line: '%s'",buf2,retval,line); exit(1); } obj_proto[i].has_spells = TRUE; obj_proto[i].wpn_spells[wsplnum].spellnum=t[0]; obj_proto[i].wpn_spells[wsplnum].level=t[1]; obj_proto[i].wpn_spells[wsplnum].percent=t[2]; wsplnum++; break; ----------------- Next, in fight.c ----- in void hit() ------- Add the variable: hit=FALSE; // I added a fn for multiple hits per round, but only want the weapon to go off once at the end. after /* okay, we know the guy has been hit */ hit=TRUE; At the end of the function (I made it the last line) add: if(hit&&(type!=SKILL_BACKSTAB)) weapon_spells(ch,victim,wielded); -------------------------- Add the function: void weapon_spells(struct char_data *ch, struct char_data *vict, struct obj_data *wpn) { int i=0, rndm; if(wpn&&HAS_SPELLS(wpn)) { while(GET_WEAPON_SPELL(wpn,i)&&iin_room != vict->in_room) { if (FIGHTING(ch) && FIGHTING(ch) == vict) stop_fighting(ch); return; } rndm=number(1,100); if(GET_WEAPON_SPELL_PCT(wpn,i)>=rndm) { act("$p leaps to action with an attack of its own.",TRUE,ch,wpn,0,TO_CHAR); act("$p leaps to action with an attack of its own.",TRUE,ch,wpn,0,TO_ROOM); if(call_magic(ch,vict,NULL,GET_WEAPON_SPELL(wpn,i),GET_WEAPON_SPELL_LVL(wpn,i),CAST_WAND)<0) return; } i++; } } } that's all for fight.c --------------------------- In utils.h, add the following defines. /* For weapon spells. */ #define HAS_SPELLS(obj) ((obj)->has_spells) #define GET_WEAPON_SPELL(obj,i) ((obj)->wpn_spells[i].spellnum) #define GET_WEAPON_SPELL_LVL(obj,i) ((obj)->wpn_spells[i].level) #define GET_WEAPON_SPELL_PCT(obj,i) ((obj)->wpn_spells[i].percent) ----------------------------- In structs.h: #define MAX_WEAPON_SPELLS 3 // Change if desired. /* For weapon spells. */ struct weapon_spells { int spellnum; int level; int percent; }; in struct obj_data { add: bool has_spells; struct weapon_spells wpn_spells[MAX_WEAPON_SPELLS]; ----------------------------- For oasis... in oedit.c : ---------- void oedit_save_to_disk() ------------- Immediately after the /* Do we have affects */ section of code, add: for(counter2=0;counter2wpn_spells[counter2].spellnum) fprintf(fp,"S\n" "%d %d %d\n", obj->wpn_spells[counter2].spellnum, obj->wpn_spells[counter2].level, obj->wpn_spells[counter2].percent); ------------------- Add the following function.. /* * Weapon Spells. */ void oedit_disp_weapon_spells(struct descriptor_data *d) { int counter; get_char_cols(d->character); #if defined(CLEAR_SCREEN) send_to_char("", d->character); #endif for(counter=0;counterwpn_spells[counter].spellnum].name, nrm, cyn, OLC_OBJ(d)->wpn_spells[counter].level, nrm, cyn, OLC_OBJ(d)->wpn_spells[counter].percent, nrm); send_to_char(buf,d->character); } send_to_char("Enter spell to edit : ",d->character); } ------- in void oedit_disp_menu() ----------- In the part /* Build the second half */ "%sB%s) Timer : %s%d\r\n" "%sC%s) Values : %s%d %d %d %d\r\n" "%sD%s) Applies menu\r\n" "%sE%s) Extra descriptions menu\r\n" "%sS%s) Script : %s%s\r\n" -----> "%sM%s) Wpn Spells : %s%s\r\n" "%sQ%s) Quit\r\n" "Enter choice : ", grn, nrm, cyn, buf1, grn, nrm, cyn, GET_OBJ_WEIGHT(obj), grn, nrm, cyn, GET_OBJ_COST(obj), grn, nrm, cyn, GET_OBJ_RENT(obj), grn, nrm, cyn, GET_OBJ_TIMER(obj), grn, nrm, cyn, GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3), grn, nrm, grn, nrm, grn, nrm, cyn, obj->proto_script?"Set.":"Not Set.", -----> grn, nrm, cyn, HAS_SPELLS(obj)?"Set.":"Not set.", grn, nrm); ---------- -------- in oedit_parse() -------- before default: oedit_disp_menu(d); break; } return; add: case 'm': case 'M': oedit_disp_weapon_spells(d); OLC_MODE(d)=OEDIT_WEAPON_SPELL_MENU; break; after the whole: case OEDIT_VALUE_4: block, add: case OEDIT_WEAPON_SPELL_MENU: if((number=atoi(arg))==0) break; else if(number<0 || number>MAX_WEAPON_SPELLS) { oedit_disp_weapon_spells(d); return; } OLC_VAL(d)=number-1; OLC_MODE(d)=OEDIT_WEAPON_SPELLS; oedit_disp_spells_menu(d); return; case OEDIT_WEAPON_SPELLS: if((number=atoi(arg)) == 0) break; else if(number<1||number>MAX_SPELLS) { oedit_disp_spells_menu(d); return; } OLC_OBJ(d)->wpn_spells[OLC_VAL(d)].spellnum=number; OLC_MODE(d)=OEDIT_WEAPON_SPELL_LEVEL; send_to_char("At what level should it be cast: ",d->character); return; case OEDIT_WEAPON_SPELL_LEVEL: number=atoi(arg); if(number<1) { send_to_char("Invalid level.\r\n",d->character); send_to_char("What level should the spell be cast at: ",d->character); return; } OLC_OBJ(d)->wpn_spells[OLC_VAL(d)].level=number; send_to_char("What percent of rounds should it go off: ",d->character); OLC_MODE(d)=OEDIT_WEAPON_SPELL_PERCENT; return; case OEDIT_WEAPON_SPELL_PERCENT: number=atoi(arg); if(number<0 || number>100) { send_to_char("Invalid percent, must be 0-100.\r\nPlease enter the percent: ",d->character); return; } OLC_OBJ(d)->wpn_spells[OLC_VAL(d)].percent=number; OLC_OBJ(d)->has_spells = TRUE; /* Got the last of it, now go back in case of more */ OLC_MODE(d)=OEDIT_WEAPON_SPELL_MENU; oedit_disp_weapon_spells(d); return; ------------------------ In olc.h: add: You will probably need to change these numbers. #define OEDIT_WEAPON_SPELL_MENU 36 #define OEDIT_WEAPON_SPELLS 37 #define OEDIT_WEAPON_SPELL_PERCENT 38 #define OEDIT_WEAPON_SPELL_LEVEL 39 ------------------------ If you're not using olc to edit the stuff, the structure in the .obj files is: . . . S [#1] [#2] [#3] . Where: #1 = Spell Number #2 = The level the spell should be cast at #3 = What percent chance it has to go off when there's a successful hit. That's about it.. Some little things I left out were: Doesn't check what the item type you put the spells on.. could be a problem for some of you, but I didn't need it. If your builders put spells on wrong items, it just chews up a little bit of space, doesn't do anything else.. and perhaps it might even be useful. I didn't check for weapon spells that were helpful to the wielder. That might be something you want, and could be handled pretty easily in the function: void weapon_spells(). As with anything else you do, make backups before you use this, and no, I'm not responsible for anything that happens (Unless you live in hawaii and want to buy me plane tickets so I can come and fix it personally. -- just kidding :) All I ask is the usual, Shove my name in somewhere and drop me an email if you use it.. like it, hate it, wish I was dead for coming up with the idea.. whatever. If you have any problems, drop me a note and I'll try to help ya. Enjoy. ------------------ Mike Stilson "I sincerely apologize if the voices in my head were disturbing you."