/* ***********************************************************************
* Those wonderful cyberspace routines go here. *
* written by Christopher J. Dickey, Rift, et al. *
* matrix.cc (c) 1995 Christopher J. Dickey, (c)1997-1999 Andrew *
* Hynek, (c)2001 The AwakeMUD Consortium *
*********************************************************************** */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "structs.h"
#include "awake.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "screen.h"
#include "boards.h"
int matrix_combat_util(struct char_data * ch, struct char_data * vict,
struct obj_data *program);
int execution_test(struct char_data *persona, struct obj_data *program,
struct char_data *vict);
int find_node_required(struct char_data *persona);
void matrix_fight(struct char_data *ch, struct char_data *victim);
void sleaze_ic(struct char_data *persona, struct obj_data *program);
void do_ic_response(struct char_data *ic, struct char_data *persona);
void deceive_ic(struct char_data *persona, struct obj_data *program, struct char_data *ic);
void check_trace(struct char_data *ic);
int check_shield(struct char_data *persona, int dam);
int find_smoke(struct char_data *persona);
/* extern vars */
extern int dice(int number, int size);
extern int is_blocker(struct char_data *ic);
extern int reverse_web(struct char_data *ch, int &skill, int &target);
extern struct room_data *world;
extern struct index_data *obj_index;
extern struct index_data *mob_index;
extern struct descriptor_data *descriptor_list;
extern struct zone_data *zone_table;
extern struct char_data *character_list;
extern void obj_to_cyberware(struct obj_data * object, struct char_data * ch);
extern void obj_from_cyberware(struct obj_data * cyber);
extern void look_at_room(struct char_data * ch, int ignore_brief);
extern void update_pos(struct char_data * victim);
extern void dam_message(int dam, struct char_data * ch, struct char_data *victim, int w_type);
extern int calc_karma(struct char_data *ch, struct char_data *vict);
extern void appear(struct char_data * ch);
extern void die(struct char_data * ch);
extern void set_attacking(struct char_data *ch, struct char_data *vict,
const char *file, int line);
extern void hunt_victim(struct char_data * ch);
extern void docwagon(struct char_data *ch);
extern void remember(struct char_data * ch, struct char_data * victim);
/* Well, here it goes, the way to get into the matrix --cjd */
#define PERSONA 20
struct obj_data *get_program(struct obj_data *cyberdeck, int type)
{
struct obj_data *prog;
for (prog = cyberdeck->contains; prog; prog = prog->next_content)
if (GET_OBJ_TYPE(prog) == ITEM_PROGRAM && GET_OBJ_VAL(prog, 0) == type)
return prog;
return NULL;
}
struct obj_data *create_matrix_item(struct obj_data * prog)
{
struct obj_data *obj;
if (GET_OBJ_TYPE(prog) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(prog, 0) == TYPE_FILE) {
obj = read_object(prog->item_number, REAL);
GET_OBJ_WEAR(obj) = ITEM_WEAR_TAKE;
return obj;
}
if ((GET_PROG_TYPE(prog) == PROG_BOD) || (GET_PROG_TYPE(prog) == PROG_EVASION) ||
(GET_PROG_TYPE(prog) == PROG_MASKING) || (GET_PROG_TYPE(prog) == PROG_SENSOR))
return NULL;
obj = read_object(prog->item_number, REAL);
return obj;
}
void create_persona(struct char_data * ch, struct char_data * persona,
struct obj_data *cyberdeck)
{
struct obj_data *program, *obj;
bool have_deck = TRUE;
if (cyberdeck == NULL) {
send_to_char("You must either be a great hacker or insane to jack into the net without\r\na cyberdeck!\r\n", ch);
have_deck = FALSE;
}
/* the basic modifications for the persona go below */
if (have_deck) {
persona->real_abils.wil = GET_OBJ_VAL(cyberdeck, 0);
GET_WIL(persona) = GET_OBJ_VAL(cyberdeck, 0);
GET_BALLISTIC(persona) = GET_OBJ_VAL(cyberdeck, 1);
GET_ACTIVE(persona) = MIN(30000, GET_OBJ_VAL(cyberdeck, 2));
GET_STORAGE(persona) = MIN(30000, GET_OBJ_VAL(cyberdeck, 3));
GET_LOAD_SPEED(persona) = MIN(30000, GET_OBJ_VAL(cyberdeck, 4));
GET_IO_SPEED(persona) = MIN(30000, GET_OBJ_RENT(cyberdeck));
/* next the persona programs are loaded and the persona is modified */
program = get_program(cyberdeck, PROG_BOD);
if (program) {
persona->real_abils.bod = GET_PROG_RATING(program);
GET_BOD(persona) = GET_PROG_RATING(program);
} else {
persona->real_abils.bod = 1;
GET_BOD(persona) = 1;
}
program = get_program(cyberdeck, PROG_EVASION);
if (program) {
persona->real_abils.qui = GET_PROG_RATING(program);
GET_QUI(persona) = GET_PROG_RATING(program);
} else {
persona->real_abils.qui = 1;
GET_QUI(persona) = 1;
}
program = get_program(cyberdeck, PROG_MASKING);
if (program) {
persona->real_abils.cha = GET_PROG_RATING(program);
GET_CHA(persona) = GET_PROG_RATING(program);
} else {
persona->real_abils.cha = 1;
GET_CHA(persona) = 1;
}
program = get_program(cyberdeck, PROG_SENSOR);
if (program) {
persona->real_abils.intel = GET_PROG_RATING(program);
GET_INT(persona) = GET_PROG_RATING(program);
} else {
persona->real_abils.intel = 1;
GET_INT(persona) = 1;
}
/* here's the fun part, programs are loaded as useable items in the matrix */
for (program = cyberdeck->contains; program; program = program->next_content) {
if (GET_OBJ_TYPE(program) == ITEM_DECK_ACCESSORY &&
GET_OBJ_VAL(program, 0) == TYPE_UPGRADE &&
GET_OBJ_VAL(program, 1) == 5) {
switch(GET_OBJ_VAL(program, 2)) {
case 1:
persona->real_abils.rea = 2;
GET_REA(persona) = persona->real_abils.rea;
GET_INIT_DICE(persona) = 1;
break;
case 2:
persona->real_abils.rea = 4;
GET_REA(persona) = persona->real_abils.rea;
GET_INIT_DICE(persona) = 2;
break;
case 3:
persona->real_abils.rea = 6;
GET_REA(persona) = persona->real_abils.rea;
GET_INIT_DICE(persona) = 3;
break;
}
} else {
obj = create_matrix_item(program);
if (obj) {
obj_to_char(obj, persona);
if (GET_OBJ_TYPE(obj) == ITEM_PROGRAM)
GET_STORAGE(persona) -= GET_OBJ_VAL(obj, 2);
if (GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(obj, 0) == TYPE_FILE)
GET_STORAGE(persona) -= GET_OBJ_VAL(obj, 1);
}
}
}
} else {
GET_WIL(persona) = GET_WIL(ch);
GET_BALLISTIC(persona) = 0;
GET_IO_SPEED(persona) = GET_INT(ch);
}
GET_HACKING(persona) = GET_HACKING(ch);
GET_SKILL(persona,SKILL_COMPUTER) = GET_SKILL(ch,SKILL_COMPUTER);
}
ACMD(do_connect)
{
struct char_data *persona, *temp;
struct obj_data *cyber, *obj, *cyberdeck = NULL;
int r_num, i;
bool has_datajack = FALSE;
one_argument(argument, arg);
if (IS_PERSONA(ch)) {
send_to_char("You're already connected.\r\n", ch);
return;
} else if (ch->desc->original) {
send_to_char("You can't connect now.\r\n", ch);
return;
} else if (IS_NPC(ch)) {
send_to_char("That won't work, for some reason.\r\n", ch);
return;
}
if (!EXIT(ch, MATRIX) || EXIT(ch, MATRIX)->to_room < 1) {
send_to_char("You cannot connect to the matrix from here.\r\n", ch);
return;
}
for (temp = world[ch->in_room].people; temp; temp = temp->next_in_room)
if (temp != ch && PLR_FLAGGED(temp, PLR_MATRIX)) {
send_to_char("The terminal is already in use.\r\n", ch);
return;
}
for (cyber = ch->cyberware; cyber; cyber = cyber->next_content)
if (GET_OBJ_VAL(cyber, 2) == CYB_DATAJACK)
has_datajack = TRUE;
if (!has_datajack && !access_level(ch, LVL_PRESIDENT)) {
send_to_char("You need at least a datajack to connect to the matrix.\r\n", ch);
return;
}
for (obj = ch->carrying; obj; obj = obj->next_content)
if (GET_OBJ_TYPE(obj) == ITEM_CYBERDECK)
cyberdeck = obj;
for (i = WEAR_LIGHT; !cyberdeck && i < NUM_WEARS; i++)
if (GET_EQ(ch, i) && GET_OBJ_TYPE(GET_EQ(ch, i)) == ITEM_CYBERDECK)
cyberdeck = GET_EQ(ch, i);
if (cyberdeck && GET_OBJ_VAL(cyberdeck, 0) == 0) {
send_to_char("You cannot connect to the Matrix with fried MPCP chips!\r\n", ch);
return;
}
if (cyberdeck && IS_OBJ_STAT(cyberdeck, ITEM_GODONLY) && GET_LEVEL(ch) < LVL_LEGEND) {
act("You do not understand how to operate $p.", FALSE, ch, cyberdeck, 0, TO_CHAR);
return;
}
if ((r_num = real_mobile(PERSONA)) < 0) {
log("No persona mob for matrix");
send_to_char("The matrix seems to be out of order right now.\r\n", ch);
return;
}
if (zone_table[world[EXIT(ch, MATRIX)->to_room].zone].alert > 2) {
send_to_char("It seems like that system has been shut down...\r\n", ch);
return;
} else if (zone_table[world[EXIT(ch, MATRIX)->to_room].zone].number == 31) {
sprintf(buf, "%s connected to MCN (#%d) from #%d", GET_NAME(ch),
EXIT(ch, MATRIX)->to_room_vnum, world[ch->in_room].number);
mudlog(buf, ch, LOG_MISCLOG, TRUE);
}
GET_POS(ch) = POS_SITTING;
if (!ch->player.mname)
ch->player.mname = str_dup("persona");
if (!ch->player.msdesc)
ch->player.msdesc = str_dup("a persona");
if (!ch->player.mdesc)
ch->player.mdesc = str_dup("A nondescript persona stands idly here.\r\n");
persona = read_mobile(r_num, REAL);
char_to_room(persona, EXIT(ch, MATRIX)->to_room);
create_persona(ch, persona, cyberdeck);
persona->player.name = ch->player.mname;
persona->player.short_descr = ch->player.msdesc;
persona->player.long_descr = ch->player.mdesc;
persona->player.description = ch->player.mldesc;
ch->desc->character = persona;
ch->desc->original = ch;
persona->desc = ch->desc;
ch->desc = NULL;
act("$n jacks into the Net.", TRUE, ch, 0, 0, TO_ROOM);
act("You jack into the Net.", FALSE, persona, 0, 0, TO_CHAR);
act("$n slowly pixellizes into view.", TRUE, persona, 0, 0, TO_ROOM);
SET_BIT(PLR_FLAGS(ch), PLR_MATRIX);
look_at_room(persona, 1);
}
ACMD(do_disconnect)
{
int i, success, stun;
struct obj_data *obj, *deck = NULL, *o;
struct char_data *temp;
if (IS_PERSONA(ch)) {
if (FIGHTING(ch) && GET_RACE(FIGHTING(ch)) == CLASS_BLACK && subcmd != SCMD_MORTED) {
success = success_test(GET_WIL(ch->desc->original), GET_LEVEL(FIGHTING(ch)) +
(zone_table[world[ch->in_room].zone].alert > 0 ? (GET_LEVEL(FIGHTING(ch)) / 2) : 0));
if (success < 1) {
send_to_char("You fail to escape!\r\n", ch);
return;
}
stun = convert_damage(stage(4 - success_test(GET_BOD(ch->desc->original), 4), MODERATE));
GET_MENTAL(ch->desc->original) -= stun * 100;
update_pos(ch->desc->original);
}
act("$n depixellizes.", FALSE, ch, 0, 0, TO_ROOM);
/* extract objects, if any */
while (ch->carrying) {
obj = ch->carrying;
obj_from_char(obj);
if (GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(obj, 0) == TYPE_FILE) {
for (o = ch->desc->original->carrying; o; o = o->next_content)
if (GET_OBJ_TYPE(o) == ITEM_CYBERDECK)
deck = o;
for (i = WEAR_LIGHT; !deck && i < NUM_WEARS; i++)
if (GET_EQ(ch->desc->original, i) && GET_OBJ_TYPE(GET_EQ(ch->desc->original, i)) == ITEM_CYBERDECK)
deck = GET_EQ(ch->desc->original, i);
obj_to_obj(obj, deck);
GET_OBJ_VAL(deck, 5) += GET_OBJ_VAL(obj, 1);
} else extract_obj(obj);
}
/* extract all cyberware */
while (ch->cyberware) {
obj = ch->cyberware;
obj_from_cyberware(obj);
extract_obj(obj);
}
/* extract equipment, if any */
for (i = 0; i < NUM_WEARS; i++)
if (ch->equipment[i])
extract_obj(unequip_char(ch, i));
REMOVE_BIT(PLR_FLAGS(ch->desc->original), PLR_MATRIX);
send_to_char("You feel disoriented as you jack out of the Net.\r\n", ch);
WAIT_STATE(ch, PULSE_VIOLENCE);
if (ch->desc->original->desc)
close_socket(ch->desc->original->desc);
temp = ch;
ch->desc->character = ch->desc->original;
ch->desc->original = NULL;
ch->desc->character->desc = ch->desc;
ch->desc = NULL;
extract_char(temp);
}
}
ACMD(do_software)
{
int i = 0, found = 0, mode;
struct obj_data *obj, *temp;
skip_spaces(&argument);
if (!IS_PERSONA(ch)) {
any_one_arg(argument, arg);
if (!*arg) {
send_to_char("List what's software?\r\n", ch);
return;
}
if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying)))
if (!(obj = get_object_in_equip_vis(ch, arg, ch->equipment, &i))) {
send_to_char(ch, "You don't seem to have a '%s'.\r\n", arg);
return;
}
act("$p contains:", FALSE, ch, obj, 0, TO_CHAR);
for (temp = obj->contains; temp; temp = temp->next_content) {
act(" $p", FALSE, ch, temp, 0, TO_CHAR);
found = 1;
}
if (!found)
send_to_char(" Nothing.\r\n", ch);
return;
}
if (!*argument || is_abbrev(argument, "all"))
mode = 1;
else if (is_abbrev(argument, "programs"))
mode = 2;
else if (is_abbrev(argument, "loaded"))
mode = 3;
else if (is_abbrev(argument, "files"))
mode = 4;
else if (is_abbrev(argument, "idle"))
mode = 5;
else {
send_to_char("Usage: software <all/programs/loaded/files/idle>\r\n", ch);
return;
}
if (mode == 4 || mode == 1) {
found = 0;
send_to_char("Data files:\r\n", ch);
for (obj = ch->carrying; obj; obj = obj->next_content)
if (GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(obj, 0) == TYPE_FILE) {
found = 1;
sprintf(buf, " %-25s\r\n", obj->short_description);
send_to_char(buf, ch);
}
if (!found)
send_to_char(" None.\r\n", ch);
if (is_abbrev(argument, "all"))
send_to_char("\r\n", ch);
}
if (mode == 2 || mode == 5 || mode == 1) {
found = 0;
send_to_char("Idle programs:\r\n", ch);
for (obj = ch->carrying; obj; obj = obj->next_content)
if (GET_OBJ_TYPE(obj) == ITEM_PROGRAM) {
found = 1;
sprintf(buf, " %-25s\r\n", obj->short_description);
send_to_char(buf, ch);
}
if (!found)
send_to_char(" None.\r\n", ch);
if (is_abbrev(argument, "programs") || is_abbrev(argument, "all"))
send_to_char("\r\n", ch);
}
if (mode == 2 || mode == 3 || mode == 1) {
found = 0;
send_to_char("Loaded programs:\r\n", ch);
for (i = 0; i < NUM_WEARS; i++) {
if (GET_EQ(ch, i)) {
sprintf(buf, " %-25s %s\r\n", GET_EQ(ch, i)->short_description,
(GET_OBJ_VAL(GET_EQ(ch, i), 9) ? "(running)" : ""));
found = 1;
send_to_char(buf, ch);
}
}
if (!found)
sprintf(buf, " None.\r\n");
}
}
struct obj_data *loaded_programs(struct char_data *ch, char *arg,
struct obj_data *equipment[])
{
int i;
for (i = 0; i < NUM_WEARS; i++)
if (equipment[i])
if (CAN_SEE_OBJ(ch, equipment[i]))
if (isname(arg, equipment[i]->name))
return (equipment[i]);
return NULL;
}
ACMD(do_run)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
extern struct index_data *mob_index;
struct char_data *vict = NULL;
struct obj_data *prog, *obj, *o = NULL;
int resist, success, i, pool;
if (!IS_PERSONA(ch)) {
send_to_char("But you aren't connected to the Matrix?!\r\n", ch);
return;
}
two_arguments(argument, arg1, arg2);
if (!*arg1) {
send_to_char("Run what?\r\n", ch);
return;
}
prog = loaded_programs(ch, arg1, ch->equipment);
if (!prog) {
send_to_char("You don't seem to have anything like that loaded.\r\n", ch);
return;
}
switch (GET_PROG_TYPE(prog)) {
case PROG_ATTACK:
if (!*arg2) {
send_to_char("Destroy what?\r\n", ch);
return;
}
if (!(vict = get_char_room_vis(ch, arg2)) ||
((vict = get_char_room_vis(ch, arg2)) && IS_NPC(vict) &&
(GET_RACE(vict) > CLASS_SCRAMBLE && !is_blocker(vict) &&
zone_table[world[ch->in_room].zone].alert < 2)))
send_to_char("They don't seem to be here.\r\n", ch);
else if (vict == ch) {
send_to_char("You hit yourself...OUCH!.\r\n", ch);
act("$n hits $mself, and says OUCH!", FALSE, ch, 0, vict, TO_ROOM);
} else if ((GET_POS(ch) == POS_STANDING) && (vict != FIGHTING(ch))) {
set_fighting(ch, vict);
GET_INIT_ROLL(ch) = MIN(28, (dice(1 + GET_INIT_DICE(ch), 6) + GET_REA(ch)));
if (!FIGHTING(vict)) {
if (IS_IC(vict))
GET_INIT_ROLL(vict) = GET_LEVEL(ch) + (zone_table[world[vict->in_room].zone].alert > 0 ? (GET_LEVEL(vict) / 2) : 0);
else GET_INIT_ROLL(vict) = MIN(28, (dice(1 + GET_INIT_DICE(vict), 6) + GET_REA(vict)));
}
matrix_fight(ch, vict);
GET_OBJ_VAL(prog, 9) = 1;
GET_INIT_ROLL(ch) -= 10;
WAIT_STATE(ch, PULSE_VIOLENCE + 2);
} else send_to_char("You do the best you can!\r\n", ch);
break;
case PROG_SLOW:
if (!*arg2) {
if (!FIGHTING(ch)) {
send_to_char("What do you want to slow?\r\n", ch);
return;
} else vict = FIGHTING(ch);
} else if (!FIGHTING(ch)) {
vict = get_char_room_vis(ch, arg2);
if (!vict || (vict && IS_NPC(vict) && !is_blocker(vict) &&
GET_RACE(vict) > CLASS_SCRAMBLE &&
zone_table[world[ch->in_room].zone].alert < 2)) {
send_to_char("They don't seem to be here.\r\n", ch);
return;
}
} else {
send_to_char("You can't focus on that right now.\r\n", ch);
return;
}
if (!IS_IC(vict)) {
send_to_char("You can only slow ICs.\r\n", ch);
return;
}
if (!execution_test(ch, GET_EQ(ch, WEAR_FEET), vict)) {
act("$p fails to execute!", FALSE, ch, GET_EQ(ch, WEAR_FEET), 0, TO_CHAR);
return;
}
if ((success = matrix_combat_util(ch, vict, GET_EQ(ch, WEAR_FEET))) < 1) {
send_to_char(ch, "%s seems to have no effect.\r\n",
CAP(GET_EQ(ch, WEAR_FEET)->short_description));
return;
}
if (!FIGHTING(vict)) {
switch(world[vict->in_room].sector_type) {
case SECT_GREEN:
GET_INIT_ROLL(vict) = 5 + GET_LEVEL(vict) +
(zone_table[world[vict->in_room].zone].alert > 0 ? (GET_LEVEL(vict) / 2) : 0);
break;
case SECT_ORANGE:
GET_INIT_ROLL(vict) = 7 + GET_LEVEL(vict) +
(zone_table[world[vict->in_room].zone].alert > 0 ? (GET_LEVEL(vict) / 2) : 0);
break;
case SECT_RED:
GET_INIT_ROLL(vict) = 9 + GET_LEVEL(vict) +
(zone_table[world[vict->in_room].zone].alert > 0 ? (GET_LEVEL(vict) / 2) : 0);
break;
case SECT_BLACK:
GET_INIT_ROLL(vict) = 10 + GET_LEVEL(vict) +
(zone_table[world[vict->in_room].zone].alert > 0 ? (GET_LEVEL(vict) / 2) : 0);
break;
default:
GET_INIT_ROLL(vict) = 0;
break;
}
set_fighting(vict, ch);
}
GET_INIT_ROLL(vict) -= GET_OBJ_VAL(prog, 1);
if (!AFF_FLAGGED(vict, AFF_COUNTER_ATT))
SET_BIT(AFF_FLAGS(vict), AFF_COUNTER_ATT);
if (GET_INIT_ROLL(vict) < 1) {
act("$n freezes and shatters into minute slivers.", FALSE, vict, 0, 0, TO_ROOM);
for (i = 0; i < NUM_WEARS; i++)
if (vict->equipment[i])
extract_obj(vict->equipment[i]);
for (obj = vict->carrying; obj; obj = obj->next_content) {
o = obj->next_content;
extract_obj(obj);
}
extract_char(vict);
}
break;
case PROG_DECRYPT:
if (FIGHTING(ch)) {
send_to_char("You can't use that program while fighting.\r\n", ch);
return;
}
if (!*arg2) {
send_to_char("Who do you want to decrypt?\r\n", ch);
return;
}
vict = get_char_room_vis(ch, arg2);
if (!vict || (vict && IS_NPC(vict) && GET_RACE(vict) > CLASS_SCRAMBLE &&
!is_blocker(vict) && zone_table[world[ch->in_room].zone].alert < 2)) {
send_to_char("They don't seem to be here.\r\n", ch);
return;
}
if (!IS_IC(vict) || (IS_IC(vict) && GET_RACE(vict) != CLASS_SCRAMBLE)) {
send_to_char("You can only decrypt scramble ICs.\r\n", ch);
return;
}
if (!execution_test(ch, prog, vict)) {
act("You fail to execute $p!", FALSE, ch, prog, 0, TO_CHAR);
do_ic_response(vict, ch);
} else {
pool = MIN((GET_HACKING(ch)), GET_PROG_RATING(prog));
success = success_test(GET_PROG_RATING(prog) + pool, GET_SECURITY(ch));
if (success < find_node_required(ch)) {
act("You feel the node absorb $p's effects!", FALSE, ch, prog, 0, TO_CHAR);
do_ic_response(vict, ch);
} else {
success -= success_test(GET_LEVEL(vict) + (zone_table[world[vict->in_room].zone].alert > 0 ?
(GET_LEVEL(vict) / 2) : 0), GET_QUI(ch));
if (success <= 0) {
act("$N resists the effects of $p!", FALSE, ch, prog, vict, TO_CHAR);
act("You resist $n's feeble attempt to decrypt you!", FALSE, ch, 0, vict, TO_VICT);
do_ic_response(vict, ch);
return;
}
act("$n dissolves into nothing.", FALSE, vict, 0, 0, TO_ROOM);
act("You feel yourself eaten away bit by bit.", FALSE, ch, 0, vict, TO_VICT);
for (i = 0; i < NUM_WEARS; i++)
if (vict->equipment[i])
extract_obj(vict->equipment[i]);
for (obj = vict->carrying; o; obj = o) {
o = obj->next_content;
extract_obj(obj);
}
extract_char(vict);
}
}
break;
case PROG_MIRRORS:
case PROG_SHIELD:
if (GET_OBJ_VAL(prog, 9)) {
act("$p is already running, it seems.", FALSE, ch, prog, 0, TO_CHAR);
return;
}
act("$n activates $p.", TRUE, ch, prog, 0, TO_ROOM);
act("You activate $p.", FALSE, ch, prog, 0, TO_CHAR);
GET_OBJ_VAL(prog, 9) = GET_OBJ_VAL(prog, 1);
if (GET_PROG_TYPE(prog) == PROG_MIRRORS)
GET_QUI(ch) += GET_OBJ_VAL(prog, 1);
if (FIGHTING(ch))
stop_fighting(ch);
break;
case PROG_MEDIC:
if (!GET_OBJ_VAL(prog, 1)) {
sprintf(buf, "%s has degraded beyond use.\r\n", CAP(prog->short_description));
send_to_char(buf, ch);
return;
}
if (GET_PHYSICAL(ch) < 500)
resist = 6;
else if (GET_PHYSICAL(ch) < 800)
resist = 5;
else resist = 4;
success = success_test(GET_OBJ_VAL(prog, 1), resist);
GET_OBJ_VAL(prog, 1)--;
if (success > 0) {
GET_PHYSICAL(ch) += success * 100;
if (GET_PHYSICAL(ch) > GET_MAX_PHYSICAL(ch))
GET_PHYSICAL(ch) = GET_MAX_PHYSICAL(ch);
act("You feel repaired!", FALSE, ch, 0, 0, TO_CHAR);
act("$n runs $p and appears better.", TRUE, ch, prog, 0, TO_ROOM);
} else act("$p can't seem to repair any damage.", FALSE, ch, prog, 0, TO_CHAR);
break;
case PROG_DECEPTION:
if (FIGHTING(ch)) {
send_to_char("You can't run that program while fighting.\r\n", ch);
return;
}
if (zone_table[world[ch->in_room].zone].alert == 2) {
send_to_char("You cannot deceive any ICs during an active alert.\r\n", ch);
return;
}
if (!*arg2) {
send_to_char("Deceive what?\r\n", ch);
return;
}
if (!(vict = get_char_room_vis(ch, arg2)) ||
((vict = get_char_room_vis(ch, arg2)) && IS_NPC(vict) &&
GET_RACE(vict) > CLASS_SCRAMBLE && !is_blocker(vict) &&
zone_table[world[ch->in_room].zone].alert < 2))
send_to_char("They don't seem to be here.\r\n", ch);
else if (vict == ch)
send_to_char("Try as hard as you might, you can't deceive yourself.\r\n", ch);
else if (!IS_IC(vict))
send_to_char("You can only deceive ICs.\r\n", ch);
else deceive_ic(ch, prog, vict);
break;
case PROG_SLEAZE:
if (GET_OBJ_VAL(prog, 9))
act("$p is already running, it seems.", FALSE, ch, prog, 0, TO_CHAR);
else if (FIGHTING(ch))
act("You can't run $p while fighting.", FALSE, ch, prog, 0, TO_CHAR);
else sleaze_ic(ch, prog);
break;
case PROG_SMOKE:
if (find_smoke(ch))
act("Smoke a smoked room?", FALSE, ch, 0, 0, TO_CHAR);
else {
GET_OBJ_VAL(prog, 9) = GET_OBJ_VAL(prog, 1);
send_to_room("Smoke suddenly rises in the node!\r\n", ch->in_room);
if (FIGHTING(ch)) {
stop_fighting(FIGHTING(ch));
stop_fighting(ch);
}
}
break;
default:
send_to_char("That program type has yet to be implemented.\r\n", ch);
break;
}
return;
}
void do_ic_response(struct char_data *ic, struct char_data *persona)
{
struct obj_data *obj, *next_obj = NULL;
switch(GET_RACE(ic)) {
case CLASS_ACCESS:
case CLASS_BARRIER:
if (!number(0, 2))
return;
if (!zone_table[world[ic->in_room].zone].alert) {
act("Yellow lights begin to flash throughout the system!", FALSE, ic, 0, 0, TO_ROOM);
act("You succeed in declaring a passive alert.", FALSE, ic, 0, 0, TO_CHAR);
zone_table[world[ic->in_room].zone].alert = 1;
} else if (zone_table[world[ic->in_room].zone].alert == 1 && !AFF_FLAGGED(ic, AFF_COUNTER_ATT) && !number(0,1)) {
act("The yellow lights become red, and sirens join in the cacophony!", FALSE, ic, 0, 0, TO_ROOM);
act("You succeed in changing the passive alert to active.", FALSE, ic, 0, 0, TO_CHAR);
zone_table[world[ic->in_room].zone].alert = 2;
}
break;
case CLASS_SCRAMBLE:
if (AFF_FLAGGED(ic, AFF_COUNTER_ATT) || (GET_EQ(persona, WEAR_WAIST) &&
GET_OBJ_VAL(GET_EQ(persona, WEAR_WAIST), 9)))
return;
act("$n glows brighter and emits a high-pitched sound!", FALSE, ic, 0, 0, TO_ROOM);
act("You glow brighter and emit a high-pitched sound!", FALSE, ic, 0, 0, TO_CHAR);
for (obj = world[ic->in_room].contents; obj; obj = next_obj) {
next_obj = obj->next_content;
if (GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(obj, 0) == TYPE_FILE) {
act("$p has been deleted!", FALSE, ic, obj, 0, TO_ROOM);
act("$p has been deleted!", FALSE, ic, obj, 0, TO_CHAR);
extract_obj(obj);
}
}
break;
case CLASS_KILLER:
case CLASS_BLASTER:
case CLASS_BLACK:
matrix_fight(ic, persona);
break;
case CLASS_TAR_BABY:
case CLASS_TAR_PIT:
if (!FIGHTING(ic))
set_fighting(ic, persona);
if (!FIGHTING(persona))
set_fighting(persona, ic);
if (zone_table[world[ic->in_room].zone].alert != 2) {
zone_table[world[ic->in_room].zone].alert = 2;
act("Flashing red lights scan the node as sirens blare!", FALSE, ic, 0, 0, TO_ROOM);
act("You set the system alert to active.", FALSE, ic, 0, 0, TO_CHAR);
}
break;
case CLASS_TRACE_BURN:
case CLASS_TRACE_REPORT:
case CLASS_TRACE_DUMP:
if (!FIGHTING(ic))
set_fighting(ic, persona);
if (!FIGHTING(persona))
set_fighting(persona, ic);
GET_MENTAL(ic) = 1000 - 100 * success_test((GET_LEVEL(ic) +
(zone_table[world[ic->in_room].zone].alert > 0 ? (GET_LEVEL(ic) / 2) : 0)), GET_CHA(persona));
if (GET_MENTAL(ic) < 0)
GET_MENTAL(ic) = 0;
break;
default:
break;
}
return;
}
int find_node_required(struct char_data *persona)
{
if (world[persona->in_room].sector_type == SECT_BLUE)
return 1;
else if (world[persona->in_room].sector_type == SECT_GREEN)
return 2;
else if (world[persona->in_room].sector_type == SECT_ORANGE)
return 3;
else if (world[persona->in_room].sector_type == SECT_RED)
return 4;
else if (world[persona->in_room].sector_type == SECT_BLACK)
return 4;
return 0;
}
int find_smoke(struct char_data *persona)
{
struct char_data *temp;
for (temp = world[persona->in_room].people; temp; temp = temp->next_in_room)
if (IS_PERSONA(temp) && GET_EQ(temp, WEAR_ARMS) &&
GET_OBJ_VAL(GET_EQ(temp, WEAR_ARMS), 9))
return(GET_OBJ_VAL(GET_EQ(temp, WEAR_ARMS), 9));
return 0;
}
int execution_test(struct char_data *persona, struct obj_data *program,
struct char_data *vict)
{
int rating, hacking_pool, targnum, char_success, vict_success, masking = 0;
int victrating, victtarg;
if (!IS_PERSONA(persona))
return 1;
else if (!program)
{
act( "Exec: No program. Failed.", 1, persona, NULL, NULL, TO_ROLLS );
return 0;
}
hacking_pool = MIN(GET_PROG_RATING(program), GET_HACKING(persona));
if (GET_PROG_TYPE(program) == PROG_DECEPTION ||
GET_PROG_TYPE(program) == PROG_SLEAZE)
masking = 1;
rating = GET_PROG_RATING(program) + hacking_pool;
targnum = (vict ? GET_QUI(vict) : GET_SECURITY(persona))
+ find_smoke(persona);
victrating = (vict ? GET_WIL(vict) : GET_SECURITY(persona));
victtarg = (masking ? GET_CHA(persona) : GET_QUI(persona))
+ find_smoke(persona);
char_success = success_test(rating, targnum);
vict_success = success_test(victrating, victtarg);
if(1)
{
char rbuf[MAX_STRING_LENGTH];
sprintf(rbuf,"Exec: Rating %d+%d=%d, Targ %d%c+%d=%d. VR %d%c, VT %d%c+%d=%d. %d-%d %d/%d",
GET_PROG_RATING(program), hacking_pool, rating,
(vict ? GET_QUI(vict) : GET_SECURITY(persona)),
(vict ? 'Q' : 'S'), find_smoke(persona), targnum,
victrating, (vict ? 'W' : 'S'),
masking ? GET_CHA(persona) : GET_QUI(persona),
masking ? 'C' : 'Q', find_smoke(persona), victtarg,
char_success, vict_success,
char_success,
masking ? 0 : find_node_required(persona));
act( rbuf, 1, persona, NULL, NULL, TO_ROLLS );
}
if (masking)
return (char_success - vict_success);
if (access_level(persona, LVL_OWNER))
return 1;
if (char_success < vict_success)
return 0;
if (char_success < find_node_required(persona))
return 0;
return 1;
}
void deceive_ic(struct char_data *persona, struct obj_data *program, struct char_data *ic)
{
int success, i;
struct obj_data *obj, *o = NULL;
success = execution_test(persona, program, ic);
if (success > 0) {
if (success > find_node_required(persona) && (GET_RACE(ic) != CLASS_BARRIER && GET_RACE(ic) != CLASS_BLACK)) {
act("You succeed in fooling $N.", FALSE, persona, 0, ic, TO_CHAR);
return;
} else act("Your attempt to fool $N fails.", FALSE, persona, 0, ic, TO_CHAR);
}
do_ic_response(ic, persona);
if (!number(0, 2) && GET_EQ(persona, WEAR_WAIST) && (GET_RACE(ic) == CLASS_TAR_BABY ||
GET_RACE(ic) == CLASS_TAR_PIT)) {
switch(GET_RACE(ic)) {
case CLASS_TAR_BABY:
act("As you fail to deceive $N, $E knocks $p out of active memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_CHAR);
act("As $n fails to deceive you, you knock $p out of $s active memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_VICT);
GET_ACTIVE(persona) += GET_OBJ_VAL(GET_EQ(persona, WEAR_WAIST), 2);
obj_to_char(unequip_char(persona, WEAR_WAIST), persona);
break;
case CLASS_TAR_PIT:
act("As you fail to deceive $N, $E knocks $p out of online memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_CHAR);
act("As $n fails to deceive you, you knock $p out of $s online memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_VICT);
GET_ACTIVE(persona) += GET_OBJ_VAL(GET_EQ(persona, WEAR_WAIST), 2);
extract_obj(unequip_char(persona, WEAR_WAIST));
break;
}
}
}
void sleaze_ic(struct char_data *persona, struct obj_data *program)
{
int success = 0, i;
struct char_data *ic;
struct obj_data *o, *obj;
for (ic = world[persona->in_room].people; ic; ic = ic->next_in_room)
if (IS_IC(ic)) {
success = execution_test(persona, program, ic);
if (success > 0) {
if (success > find_node_required(persona)) {
act("You feel your persona waver.", FALSE, persona, 0, ic, TO_CHAR);
act("$n wavers slightly.", TRUE, persona, 0, ic, TO_NOTVICT);
GET_OBJ_VAL(program, 9) = GET_OBJ_VAL(program, 1);
return;
} else {
act("Nothing seems to happen.", FALSE, persona, 0, 0, TO_CHAR);
return;
}
} else {
switch(GET_RACE(ic)) {
case CLASS_TAR_BABY:
case CLASS_TAR_PIT:
do_ic_response(ic, persona);
if (!number(0, 2) && GET_EQ(persona, WEAR_HEAD))
switch (GET_RACE(ic)) {
case CLASS_TAR_BABY:
act("As you fail to fool $N, $E knocks $p out of active memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_CHAR);
act("As $n fails to fool you, you knock $p out of $s active memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_VICT);
GET_ACTIVE(persona) += GET_OBJ_VAL(GET_EQ(persona, WEAR_HEAD), 2);
obj_to_char(unequip_char(persona, WEAR_HEAD), persona);
break;
case CLASS_TAR_PIT:
act("As you fail to damage $N, $E knocks $p out of online memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_CHAR);
act("As $n fails to damage you, you knock $p out of $s online memory!", FALSE, persona, GET_EQ(persona, WEAR_WIELD), ic, TO_VICT);
GET_ACTIVE(persona) += GET_OBJ_VAL(GET_EQ(persona, WEAR_HEAD), 2);
extract_obj(unequip_char(persona, WEAR_HEAD));
break;
}
break;
default:
do_ic_response(ic, persona);
break;
}
}
}
return;
}
int matrix_combat_util(struct char_data * ch, struct char_data * vict,
struct obj_data *program)
{
int successes, skill = SKILL_COMPUTER, i = 0;
int ch_dice = 0, res_dice = 0, ch_tar = 0, res_tar = 0;
if (IS_IC(ch) && GET_RACE(ch) == CLASS_BLACK && IS_PERSONA(vict)) {
ch_dice = GET_LEVEL(ch) + zone_table[world[ch->in_room].zone].alert > 0 ?
(int)(GET_LEVEL(ch) / 2) : 0;
res_dice = GET_BOD(vict->desc->original);
res_tar = GET_LEVEL(ch) + zone_table[world[ch->in_room].zone].alert > 0 ?
(int)(GET_LEVEL(ch) / 2) : 0;
ch_tar = GET_BOD(vict->desc->original);
ch_tar += find_smoke(ch);
res_tar += find_smoke(vict);
successes = resisted_test(ch_dice, ch_tar, res_dice, res_tar);
successes -= GET_BALLISTIC(vict);
for (; successes >= 0; successes -= 2)
i++;
return i;
}
if (IS_PERSONA(ch)) {
if (!GET_SKILL(ch->desc->original, skill))
reverse_web(ch->desc->original, skill, ch_tar);
else ch_dice = GET_SKILL(ch->desc->original, skill);
res_tar = ch_dice;
if (program)
ch_dice += MIN(GET_PROG_RATING(program), (int)(GET_HACKING(ch)));
} else {
ch_dice = GET_LEVEL(ch) + zone_table[world[ch->in_room].zone].alert > 0 ?
(int)(GET_LEVEL(ch) / 2) : 0;
res_tar = GET_SECURITY(ch);
}
if (IS_PERSONA(vict)) {
res_dice = GET_WIL(vict) + MIN(GET_WIL(vict), (int)(GET_HACKING(vict)));
ch_tar += GET_BOD(vict);
} else {
res_dice = GET_LEVEL(vict) + zone_table[world[vict->in_room].zone].alert > 0 ?
(int)(GET_LEVEL(vict) / 2) : 0;
ch_tar += GET_SECURITY(vict);
}
ch_tar += find_smoke(ch);
res_tar += find_smoke(vict);
successes = resisted_test(ch_dice, ch_tar, res_dice, res_tar);
if (IS_PERSONA(ch) && IS_IC(vict))
successes -= find_node_required(ch);
else if (IS_PERSONA(vict))
successes -= GET_BALLISTIC(vict);
return successes;
}
void check_trace(struct char_data *ic)
{
int mpcp, dir, room, distance, i, nextroom;
struct char_data *vict, *guard, *temp;
struct obj_data *obj, *o, *cyberdeck = NULL;
if (!FIGHTING(ic) && GET_MENTAL(ic) < GET_MAX_MENTAL(ic))
GET_MENTAL(ic) = GET_MAX_MENTAL(ic);
if (!FIGHTING(ic) || (FIGHTING(ic) && !IS_PERSONA(FIGHTING(ic))) ||
(GET_RACE(ic) != CLASS_TRACE_REPORT &&
GET_RACE(ic) != CLASS_TRACE_DUMP) || number(0, 2))
return;
vict = FIGHTING(ic);
if (GET_MENTAL(ic) > 0)
GET_MENTAL(ic) -= 100;
switch (GET_RACE(ic)) {
case CLASS_TRACE_REPORT:
case CLASS_TRACE_DUMP:
case CLASS_TRACE_BURN:
if (GET_MENTAL(ic) < 1) {
temp = vict->desc->original;
if (GET_RACE(ic) == CLASS_TRACE_DUMP)
do_disconnect(vict, "", 0, SCMD_MORTED);
else if (GET_RACE(ic) == CLASS_TRACE_BURN) {
mpcp = success_test(GET_LEVEL(ic), GET_WIL(vict)) - GET_BALLISTIC(vict);
if (mpcp > 0) {
act("You succeed in frying some of $N's MPCP chips.", FALSE, ic, 0, vict, TO_CHAR);
do_disconnect(vict, "", 0, SCMD_MORTED);
send_to_char("A faint stream of smoke rises from your cyberdeck.\r\n", temp);
for (obj = temp->carrying; obj; obj = obj->next_content)
if (GET_OBJ_TYPE(obj) == ITEM_CYBERDECK)
cyberdeck = obj;
for (i = WEAR_LIGHT; !cyberdeck && i < NUM_WEARS; i++)
if (GET_EQ(temp, i) && GET_OBJ_TYPE(GET_EQ(temp, i)) == ITEM_CYBERDECK)
cyberdeck = GET_EQ(temp, i);
if (cyberdeck) {
GET_OBJ_VAL(cyberdeck, 0) -= mpcp;
if (GET_OBJ_VAL(cyberdeck, 0) < 0)
GET_OBJ_VAL(cyberdeck, 0) = 0;
}
return;
}
}
room = temp->in_room;
for (guard = world[room].people; guard; guard = guard->next_in_room)
if (IS_NPC(guard) && MOB_FLAGGED(guard, MOB_GUARD)) {
SET_BIT(MOB_FLAGS(guard), MOB_TRACK);
HUNTING(guard) = temp;
set_fighting(guard, temp);
}
for (dir = 0; dir < (NUM_OF_DIRS - 1); dir++) {
room = temp->in_room;
if (CAN_GO2(room, dir))
nextroom = EXIT2(room, dir)->to_room;
else nextroom = NOWHERE;
for (distance = 1; ((nextroom != NOWHERE) && (distance <= 4)); distance++) {
for (guard = world[nextroom].people; guard; guard = guard->next_in_room)
if (IS_NPC(guard) && MOB_FLAGGED(guard, MOB_GUARD)) {
SET_BIT(MOB_FLAGS(guard), MOB_TRACK);
HUNTING(guard) = temp;
hunt_victim(guard);
}
room = nextroom;
if (CAN_GO2(room, dir))
nextroom = EXIT2(room, dir)->to_room;
else nextroom = NOWHERE;
}
}
GET_MENTAL(ic) = GET_MAX_MENTAL(ic);
}
break;
}
return;
}
void check_smoke(struct char_data *persona)
{
struct char_data *temp;
int i = 0;
for (temp = world[persona->in_room].people; temp; temp = temp->next_in_room)
if (IS_PERSONA(temp) && GET_EQ(temp, WEAR_ARMS) && GET_OBJ_VAL(GET_EQ(temp, WEAR_ARMS), 9)) {
GET_OBJ_VAL(GET_EQ(temp, WEAR_ARMS), 9)--;
if (!GET_OBJ_VAL(GET_EQ(temp, WEAR_ARMS), 9) && i == 0) {
send_to_room("The smoke clears.\r\n", persona->in_room);
i = 1;
}
}
return;
}
int check_shield(struct char_data *persona, int dam)
{
int damage;
bool found = FALSE;
if (!IS_PERSONA(persona))
return (dam);
if (GET_EQ(persona, WEAR_SHIELD) &&
GET_PROG_TYPE(GET_EQ(persona, WEAR_SHIELD)) == PROG_SHIELD &&
GET_OBJ_VAL(GET_EQ(persona, WEAR_SHIELD), 9)) {
GET_OBJ_VAL(GET_EQ(persona, WEAR_SHIELD), 9) -= dam;
found = TRUE;
if (GET_OBJ_VAL(GET_EQ(persona, WEAR_SHIELD), 9) <= 0) {
damage = -(GET_OBJ_VAL(GET_EQ(persona, WEAR_SHIELD), 9));
GET_OBJ_VAL(GET_EQ(persona, WEAR_SHIELD), 9) = 0;
act("Your shield program collapses from active use.", FALSE, persona, 0, 0, TO_CHAR);
act("$n's shield program collapses.", TRUE, persona, 0, 0, TO_ROOM);
GET_ACTIVE(persona) += GET_OBJ_VAL(GET_EQ(persona, WEAR_SHIELD), 2);
obj_to_char(unequip_char(persona, WEAR_SHIELD), persona);
return (damage);
}
}
if (!found)
return (dam);
return 0;
}
void check_mirrors(struct char_data *persona)
{
if (GET_EQ(persona, WEAR_HANDS) &&
GET_PROG_TYPE(GET_EQ(persona, WEAR_HANDS)) == PROG_MIRRORS &&
GET_OBJ_VAL(GET_EQ(persona, WEAR_HANDS), 9)) {
GET_OBJ_VAL(GET_EQ(persona, WEAR_HANDS), 9)--;
GET_QUI(persona)--;
if (GET_OBJ_VAL(GET_EQ(persona, WEAR_HANDS), 9) == 0) {
GET_QUI(persona) = persona->real_abils.qui;
act("Your $p stops running.",
FALSE, persona, GET_EQ(persona, WEAR_HANDS), 0, TO_CHAR);
}
return;
}
}
void check_sleaze(struct char_data *persona)
{
if (GET_EQ(persona, WEAR_HEAD) &&
GET_PROG_TYPE(GET_EQ(persona, WEAR_HEAD)) == PROG_MIRRORS &&
GET_OBJ_VAL(GET_EQ(persona, WEAR_HEAD), 9)) {
GET_OBJ_VAL(GET_EQ(persona, WEAR_HEAD), 9)--;
if (GET_OBJ_VAL(GET_EQ(persona, WEAR_HEAD), 9) == 0)
act("Your $p stops running.",
FALSE, persona, GET_EQ(persona, WEAR_HEAD), 0, TO_CHAR);
}
}
void matrix_fight(struct char_data *ch, struct char_data *victim)
{
int attacktype, dam, i, mpcp, exp;
struct obj_data *wielded, *obj, *o = NULL, *cyberdeck = NULL;
struct char_data *temp = NULL;
wielded = ch->equipment[WEAR_WIELD];
if (!IS_PERSONA(ch) && !IS_IC(ch))
return;
if (IS_IC(ch) & (GET_RACE(ch) != CLASS_KILLER && GET_RACE(ch) != CLASS_BLASTER &&
GET_RACE(ch) != CLASS_BLACK))
return;
if (IS_PERSONA(ch) && (!wielded || GET_OBJ_TYPE(wielded) != ITEM_PROGRAM ||
GET_PROG_TYPE(wielded) != PROG_ATTACK)) {
stop_fighting(ch);
return;
} else if (IS_IC(ch) && wielded)
wielded = NULL;
if (wielded) {
if (!execution_test(ch, wielded,
IS_PERSONA(victim) ? victim : (struct char_data *) NULL)) {
act("$p fails to execute!", FALSE, ch, wielded, 0, TO_CHAR);
return;
}
dam = matrix_combat_util(ch, victim, wielded);
} else dam = matrix_combat_util(ch, victim, NULL);
dam = MAX(0, dam);
if (victim != ch) {
if (!FIGHTING(ch))
set_fighting(ch, victim);
if (!FIGHTING(victim))
set_fighting(victim, ch);
}
if (IS_AFFECTED(ch, AFF_HIDE))
appear(ch);
if (IS_PERSONA(victim))
temp = victim->desc->original;
if (wielded)
attacktype = GET_OBJ_VAL(wielded, 3);
else {
if (IS_NPC(ch) && (ch->mob_specials.attack_type != 0))
attacktype = ch->mob_specials.attack_type;
else attacktype = TYPE_HIT;
}
if (IS_IC(ch) && GET_RACE(ch) == CLASS_BLACK && IS_PERSONA(victim)) {
if (!IS_WEAPON(attacktype))
skill_message(dam, ch, victim, attacktype);
else dam_message(dam, ch, victim, attacktype);
damage(ch, ch, dam, 0, TRUE);
return;
}
GET_PHYSICAL(victim) -= MAX(0, check_shield(victim, dam) * 100);
if (GET_PHYSICAL(victim) < 100)
GET_POS(victim) = POS_DEAD;
if (!IS_WEAPON(attacktype))
skill_message(dam, ch, victim, attacktype);
else {
if (GET_POS(victim) == POS_DEAD) {
if (!skill_message(dam, ch, victim, attacktype))
dam_message(dam, ch, victim, attacktype);
} else dam_message(dam, ch, victim, attacktype);
}
if (dam < 1 && IS_IC(victim) && GET_POS(victim) != POS_DEAD) {
if (GET_RACE(victim) != CLASS_BLASTER && GET_RACE(victim) != CLASS_KILLER &&
GET_RACE(victim) != CLASS_BLACK && GET_RACE(victim) != CLASS_TRACE_BURN &&
GET_RACE(victim) != CLASS_TRACE_REPORT && GET_RACE(victim) != CLASS_TRACE_DUMP)
do_ic_response(victim, ch);
if (!number(0, 2)) {
switch (GET_RACE(victim)) {
case CLASS_TAR_BABY:
act("As you fail to damage $N, $E knocks $p out of active memory!",
FALSE, ch, GET_EQ(ch, WEAR_WIELD), victim, TO_CHAR);
act("As $n fails to damage you, you knock $p out of $s active memory!",
FALSE, ch, GET_EQ(ch, WEAR_WIELD), victim, TO_VICT);
GET_ACTIVE(ch) += GET_OBJ_VAL(GET_EQ(ch, WEAR_WIELD), 2);
obj_to_char(unequip_char(ch, WEAR_WIELD), ch);
break;
case CLASS_TAR_PIT:
act("As you fail to damage $N, $E knocks $p out of online memory!",
FALSE, ch, GET_EQ(ch, WEAR_WIELD), victim, TO_CHAR);
act("As $n fails to damage you, you knock $p out of $s online memory!",
FALSE, ch, GET_EQ(ch, WEAR_WIELD), victim, TO_VICT);
GET_ACTIVE(ch) += GET_OBJ_VAL(GET_EQ(ch, WEAR_WIELD), 2);
extract_obj(GET_EQ(ch, WEAR_WIELD));
break;
}
}
}
if (GET_POS(victim) == POS_DEAD) {
/** CODE HERE TO CALCULATE KARMA **/
exp = calc_karma(ch, victim);
exp = exp + 300;
if ( ch && ch->desc && ch->desc->original )
exp = gain_exp(ch->desc->original, exp);
else
exp = gain_exp(ch, exp);
if (wielded)
GET_OBJ_VAL(wielded, 9) = 0;
act("$n shatters into a million pixels.", FALSE, victim, 0, 0, TO_ROOM);
send_to_char(ch, "You receive %0.2f karma.\r\n", ((float)exp / 100));
if (IS_PERSONA(victim) && IS_IC(ch) && GET_RACE(ch) == CLASS_BLASTER) {
mpcp = success_test(GET_LEVEL(ch), GET_WIL(victim)) - GET_BALLISTIC(victim);
if (mpcp > 0) {
act("You succeed in frying some of $N's MPCP chips.",
FALSE, ch, 0, victim, TO_CHAR);
do_disconnect(victim, "", 0, SCMD_MORTED);
send_to_char("A faint stream of smoke rises from your cyberdeck.\r\n", temp);
for (obj = temp->carrying; obj; obj = obj->next_content)
if (GET_OBJ_TYPE(obj) == ITEM_CYBERDECK)
cyberdeck = obj;
for (i = WEAR_LIGHT; !cyberdeck && i < NUM_WEARS; i++)
if (GET_EQ(temp, i) && GET_OBJ_TYPE(GET_EQ(temp, i)) == ITEM_CYBERDECK)
cyberdeck = GET_EQ(temp, i);
if (cyberdeck) {
GET_OBJ_VAL(cyberdeck, 0) -= mpcp;
if (GET_OBJ_VAL(cyberdeck, 0) < 0)
GET_OBJ_VAL(cyberdeck, 0) = 0;
}
return;
}
do_disconnect(victim, "", 0, SCMD_MORTED);
return;
}
for (i = 0; i < NUM_WEARS; i++)
if (victim->equipment[i])
extract_obj(victim->equipment[i]);
for (obj = victim->carrying; o; obj = o) {
o = obj->next_content;
extract_obj(obj);
}
extract_char(victim);
}
}
void matrix_update(void)
{
struct descriptor_data *d;
for (d = descriptor_list; d; d = d->next)
if (d->character && IS_PERSONA(d->character)) {
check_mirrors(d->character);
check_sleaze(d->character);
check_smoke(d->character);
if (!FIGHTING(d->character) && GET_EQ(d->character, WEAR_WIELD) &&
GET_OBJ_VAL(GET_EQ(d->character, WEAR_WIELD), 9))
GET_OBJ_VAL(GET_EQ(d->character, WEAR_WIELD), 9) = 0;
}
}