|
Fire Weapons [by Gary Barnett] |
|
|
|
Posted Wednesday, August 12th @ 11:27:51 PM, by George Greer in the Commands dept.
Updated Dec 5, 1996. Click the link below to read it or download it.
From: gbarnett@polarnet.com
Subject: Fireweapons
I'd like to take this opportunity to contribute something to the list.
Any constructive criticism is welcome.
This code implements ranged combat using the FIREWEAPON and MISSILE item
types. Included is the do_fire procedure, the message data structure, the
do_load_weapon procedure, and an update to look_in_obj.
Not included: How to add the skill SHOOT and the interpreter stuff for the
load/reload and shoot/fire commands.
I would appreciate an email if you use the code.. I'm intersted in
knowing if anyone found it useful.. and more to the point..written well
enough to use..even as a starting point .. :)
A couple notes: This is built on the assumption of 1-100 stats.. You'll
want to modify the 'if we hit' section to suit your mud's specific
stat/skill setup. No flames on the method of calculating a hit, please..
it'll be changed on my mud too.. once I finalize all the balance issues...
Fireweapon Item setup
Value 0: Missile Type
1: missile vnum (unused)
2: Max ammo
3: Current Ammo
Missile Item setup
Value 0: Missile Type
1: Quality (unused)
2: Missile Action (unused)
3: Current Ammo
gbarnett@polarnet.com
- http://www.polarnet.com/Users/gbarnett/ - telnet:mud.polarnet.com (4000)
----
To start, in act.info.c, this section of code should be added to
look_in_obj:
} else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) &&
(GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) &&
(GET_OBJ_TYPE(obj) != ITEM_CONTAINER))
+ {
+
if ( (GET_OBJ_TYPE(obj) == ITEM_FIREWEAPON) ||
+ (GET_OBJ_TYPE(obj) == ITEM_MISSILE) ) {
+
sprintf(buf, "It contains %d units of ammunition.\r\n", GET_OBJ_VAL(obj,3))
;
+
send_to_char(buf,ch);
+
} else {
+
send_to_char("There's nothing inside that!\r\n", ch);
+ }
} else {
if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) {
if (IS_SET(GET_OBJ_VAL(obj, 1), CONT_CLOSED))
----
In constant.c:
const char *shot_types[] = {
"a missile",
"a bullet",
"an arrow",
"a bolt",
"a shell",
"a rocket",
"\n"
};
const int shot_damage[] = {
25,
35,
25,
35,
50,
75,
0
};
----
Then in act.other.c or fight.c, put these two functions:
ACMD(do_load_weapon)
{
/* arg1 = fire weapon arg2 = missiles */
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
struct obj_data *missile;
struct obj_data *weapon = GET_EQ(ch, WEAR_HOLD);
int num_needed = 0;
int num_left = 0;
int num_ammo = 0;
two_arguments(argument, arg1, arg2);
if (!*arg1 || !*arg2) {
send_to_char("Usage LOAD|RELOAD <weapon> <ammo>",ch);
return;
}
if (!weapon) {
send_to_char("You must hold the weapon to load it.",ch);
return;
}
if (GET_OBJ_TYPE(weapon) != ITEM_FIREWEAPON) {
send_to_char("That item doesn't use ammunition!",ch);
return;
}
missile = get_obj_in_list_vis(ch, arg2, ch->carrying);
if (!missile) {
send_to_char("What are you trying to use as ammunition?",ch);
return;
}
if (GET_OBJ_TYPE(missile) != ITEM_MISSILE) {
send_to_char("That isn't ammunition!",ch);
return;
}
if (GET_OBJ_VAL(missile,0) != GET_OBJ_VAL(weapon,0)) {
send_to_char("The ammunition won't fit in the weapon!",ch);
return;
}
num_needed = GET_OBJ_VAL(weapon,2) - GET_OBJ_VAL(weapon,3);
if (!num_needed) {
send_to_char("It's already fully loaded.",ch);
return;
}
num_ammo = GET_OBJ_VAL(missile,3);
if (!num_ammo) {
/* shouldn't really get here.. this one's for Murphy :) */
send_to_char("It's empty!",ch);
extract_obj(missile);
return;
}
if (num_ammo <= num_needed) {
GET_OBJ_VAL(weapon,3) += num_ammo;
extract_obj(missile);
} else {
GET_OBJ_VAL(weapon,3) += num_needed;
GET_OBJ_VAL(missile,3) -= num_needed;
}
act("You load $p", FALSE, ch, weapon, 0, TO_CHAR);
act("$n loads $p", FALSE, ch, weapon, 0, TO_ROOM);
}
ACMD(do_fire)
{ /* fire <weapon> <mob> [direction] */
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char argt[MAX_INPUT_LENGTH];
struct obj_data *weapon;
struct char_data *vict;
int target_room = -1;
int source_room = -1;
int far_room = 0;
int num1 = 0;
int num2 = 0;
int roll = 0;
int dmg = 0;
half_chop(argument, arg1, argt);
half_chop(argt, arg2, arg3);
/* arg1 = weapon arg2= victim arg3= direction */
if (!*arg1 || !*arg2) {
send_to_char("Usage: FIRE <item> <victim> [direction]",ch);
return;
}
if (ROOM_FLAGGED(ch->in_room, ROOM_PEACEFUL)) {
send_to_char("This room just has such a peaceful, easy feeling...\r\n", ch
);
return;
}
if (!GET_SKILL(ch, SKILL_SHOOT)) {
send_to_char("You aren't trained in the use of this weapon.",ch);
return;
}
weapon = GET_EQ(ch, WEAR_HOLD);
if (!weapon) {
sprintf(buf2, "You aren't holding %s!\r\n",arg1);
send_to_char(buf2, ch);
return;
}
if ( (GET_OBJ_TYPE(weapon) != ITEM_FIREWEAPON) ) {
send_to_char("You can't fire that!",ch);
return;
}
if ( !GET_OBJ_VAL(weapon, 3) ) {
send_to_char("It isn't loaded.",ch);
return;
}
if (*arg3) { /* attempt to fire direction x */
far_room = -1;
switch (arg3[0]) {
case 'n':
case 'N':
far_room = 0;
break;
case 'e':
case 'E':
far_room = 1;
break;
case 's':
case 'S':
far_room = 2;
break;
case 'w':
case 'W':
far_room = 3;
break;
case 'u':
case 'U':
far_room = 4;
break;
case 'd':
case 'D':
far_room = 5;
break;
}
if (far_room == -1 ) {
send_to_char("Invalid direction given. Valid values are N, E, S, W, U, D.",ch
);
return;
}
if (CAN_GO(ch, far_room)) {
target_room = world[ch->in_room].dir_option[far_room]->to_room;
}
if (target_room == -1) {
send_to_char("You can't find anything worth firing at in that direction.",ch)
;
return;
}
source_room = ch->in_room;
ch->in_room = target_room;
vict = get_char_room_vis(ch, arg2);
ch->in_room = source_room;
if (!vict) {
sprintf(buf, "There doesn't seem to be a %s that way.",arg2);
send_to_char(buf, ch);
return;
}
} else {
vict = get_char_room_vis(ch, arg2);
if ((!*arg2) || (!vict)) {
act("Who are you trying to fire $p at?", FALSE, ch, weapon, 0, TO_CHAR);
return;
}
}
/* ok.. got a loaded weapon, the victim is identified */
GET_OBJ_VAL(weapon, 3) -= 1;
num1 = GET_DEX(ch) - GET_DEX(vict);
if (num1 > 25) num1 = 25;
if (num1 < -25) num1 = -25;
num2 = GET_SKILL(ch, SKILL_SHOOT);
num2 = (int)(num2 * .75);
if (num2 < 1) num2 = 1;
roll = number(1, 101);
/* strcpy(argt, shot_types[GET_OBJ_VAL(weapon, 0)]); */
sprintbit((long) GET_OBJ_VAL(weapon, 0), shot_types, argt);
if ( (num1+num2) >= roll ) {
/* we hit
1) print message in room.
2) print rush message for mob in mob's room.
3) trans mob
4) set mob to fighting ch
*/
sprintf(buf, "You hit $N with %s fired from $p!", argt);
act(buf, FALSE, ch, weapon, vict, TO_CHAR);
sprintf(buf, "$n hit you with %s fired from $p!", argt);
act(buf, FALSE, ch, weapon, vict, TO_VICT);
sprintf(buf, "$n hit $N with %s fired from $p!", argt);
act(buf, FALSE, ch, weapon, vict, TO_NOTVICT);
act("$n rushes at $N and attacks!",FALSE, vict, 0, ch, TO_NOTVICT);
act("$n rushes at you and attacks!",FALSE, vict, 0, ch, TO_VICT);
act("You rush at $N and attack!",FALSE, vict, 0, ch, TO_CHAR);
char_from_room(vict);
char_to_room(vict, ch->in_room);
act("$n rushes at $N and attacks!",FALSE, vict, 0, ch, TO_NOTVICT);
dmg = shot_damage[GET_OBJ_VAL(weapon, 0)];
damage(ch, vict, dmg, TYPE_UNDEFINED);
} else {
/* we missed
1) print miss message
*/
sprintf(buf, "You fire %s at $N and miss!", argt);
act(buf, FALSE, ch, weapon, vict, TO_CHAR);
sprintf(buf, "$n fires %s at you and misses!", argt);
act(buf, FALSE, ch, weapon, vict, TO_VICT);
sprintf(buf, "$n fires %s at $N and misses!", argt);
act(buf, FALSE, ch, weapon, vict, TO_NOTVICT);
}
}
<< File Viewing Utility [by Haddixx] | Reply | View as text | Flattened | Forage Skill [by Chuck Carson] >> |
|
Related Links |
|
|
|
CircleMUD Snippets |
|
|
Note: Not all of these snippets will work perfectly with
your version of code, so be prepared to fix one
or two bugs that may arise, and please let me know
what you needed to do to fix it. Sending a corrected
version is always welcome.
|
Finally, if you wish to use any of the snippets from this
page, you are more than welcome, just mention the
authors in your credits. If you wish to release any
of these snippets to the public on another site,
contact me FIRST.
|
|
|
|
|
|
|