From: Sammy Subject: Archer spec_proc I got a couple of requests for an archer spec_proc last week while it was being discussed here so I'm posting it as promised. It's not too big but I apologize if it annoys anyone :) I tried to make it as generic and flexible as possible. I set some rooms up as an example, so if you use this code unchanged, and assign the proc to cityguards, then if they stand inside the east or west gate of midgaard (where you can usually find at least one or two), any PC within 2 rooms outside the gate will be fired on randomly. You can easily change the -1 rooms to the rooms 3 away from the guards, and if you want to fire on more than 3 rooms from a single archer room you'll have to extend the array. If you're standing in the same room as the archer, you'll see the hit/miss messages. This wasn't intended at first, but it could provide some entertainment for players who hang out with the guards and place bets on who gets hit next :) #define NUM_ARCHERS 2 /* # of rooms archers can shoot from */ #define NUM_TARGETS 3 /* # of rooms an archer can shoot at */ #define HIT_CHANCE 30 /* accuracy 30% chance to hit */ #define ARCHER_NUM_DICE 2 /* archer damage dice */ #define ARCHER_SIZE_DICE 5 /* archer does 2d5 each hit */ SPECIAL(archer) { struct char_data *targ; int i, j, k; int damage; sh_int to_from_rooms[NUM_ARCHERS][NUM_TARGETS + 1] = { /* archer room target room #1 #2 #3 */ { 3040, 3052, 6092, -1}, /* archer room #1 */ { 3041, 3053, 3503, -1} /* room #2 */ }; char *mssgs[] = { "You feel a sharp pain in your side as an arrow finds its mark!", "You hear a dull thud as an arrow pierces $N!", "An arrow whistles by your ear, barely missing you!", "An arrow narrowly misses $N!" }; if(cmd) return FALSE; if(GET_POS(ch) != POS_STANDING) return FALSE; for(i = 0; i < NUM_ARCHERS; i++) { if(real_room(to_from_rooms[i][0]) == ch->in_room) { for(j = 1; j <= NUM_TARGETS; j++) { if((k = real_room(to_from_rooms[i][j])) >= 0) { for(targ = world[k].people; targ; targ = targ->next_in_room) { if(!IS_NPC(targ) && (GET_LEVEL(targ) < LVL_IMMORT) && (!number(0, 4))) { if(number(1, 100) <= HIT_CHANCE) { act(mssgs[0], 1, ch, 0, targ, TO_VICT); act(mssgs[1], 1, ch, 0, targ, TO_NOTVICT); damage = number(5, 50); GET_HIT(targ) -= damage + (number(1, 5)); /* these above numbers can be changed for different * damage levels. */ update_pos(targ); return TRUE; } else { act(mssgs[2], 1, ch, 0, targ, TO_VICT); act(mssgs[3], 1, ch, 0, targ, TO_NOTVICT); return TRUE; } } } } } } } return FALSE; }