/* * Alert: As of bpl14, this function returns the following codes: * < 0 Victim died. * = 0 No damage. * > 0 How much damage done. */ int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype) { if (GET_POS(victim) <= POS_DEAD) { /* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */ if (PLR_FLAGGED(victim, PLR_NOTDEADYET) || MOB_FLAGGED(victim, MOB_NOTDEADYET)) return (-1); log("SYSERR: Attempt to damage corpse '%s' in room #%d by '%s'.", GET_NAME(victim), GET_ROOM_VNUM(IN_ROOM(victim)), GET_NAME(ch)); die(victim); return (-1); /* -je, 7/7/92 */ } /* peaceful rooms */ if (ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n"); return (0); } /* shopkeeper protection */ if (!ok_damage_shopkeeper(ch, victim)) return (0); /* You can't damage an immortal! */ if (!IS_NPC(victim) && (GET_LEVEL(victim) >= LVL_IMMORT)) dam = 0; if (victim != ch) { /* Start the attacker fighting the victim */ if (GET_POS(ch) > POS_STUNNED && (FIGHTING(ch) == NULL)) set_fighting(ch, victim); /* Start the victim fighting the attacker */ if (GET_POS(victim) > POS_STUNNED && (FIGHTING(victim) == NULL)) { set_fighting(victim, ch); if (MOB_FLAGGED(victim, MOB_MEMORY) && !IS_NPC(ch)) remember(victim, ch); } } /* If you attack a pet, it hates your guts */ if (victim->master == ch) stop_follower(victim); /* If the attacker is invisible, he becomes visible */ if (AFF_FLAGGED(ch, AFF_INVISIBLE | AFF_HIDE)) appear(ch); /* Cut damage in half if victim has sanct, to a minimum 1 */ if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2) dam /= 2; /* Check for PK if this is not a PK MUD */ if (!pk_allowed) { check_killer(ch, victim); if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim)) dam = 0; } /* Set the maximum damage per round and subtract the hit points */ dam = MAX(MIN(dam, 100), 0); GET_HIT(victim) -= dam; /* Gain exp for the hit */ if (ch != victim) gain_exp(ch, GET_LEVEL(victim) * dam); update_pos(victim); /* * skill_message sends a message from the messages file in lib/misc. * dam_message just sends a generic "You hit $n extremely hard.". * skill_message is preferable to dam_message because it is more * descriptive. * * If we are _not_ attacking with a weapon (i.e. a spell), always use * skill_message. If we are attacking with a weapon: If this is a miss or a * death blow, send a skill_message if one exists; if not, default to a * dam_message. Otherwise, always send a dam_message. */ if (!IS_WEAPON(attacktype)) skill_message(dam, ch, victim, attacktype); else { if (GET_POS(victim) == POS_DEAD || dam == 0) { if (!skill_message(dam, ch, victim, attacktype)) dam_message(dam, ch, victim, attacktype); } else { dam_message(dam, ch, victim, attacktype); } } /* Use send_to_char -- act() doesn't send message if you are DEAD. */ switch (GET_POS(victim)) { case POS_MORTALLYW: act("$n is mortally wounded, and will die soon, if not aided.", TRUE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You are mortally wounded, and will die soon, if not aided.\r\n"); break; case POS_INCAP: act("$n is incapacitated and will slowly die, if not aided.", TRUE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You are incapacitated an will slowly die, if not aided.\r\n"); break; case POS_STUNNED: act("$n is stunned, but will probably regain consciousness again.", TRUE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You're stunned, but will probably regain consciousness again.\r\n"); break; case POS_DEAD: act("$n is dead! R.I.P.", FALSE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You are dead! Sorry...\r\n"); break; default: /* >= POSITION SLEEPING */ if (dam > (GET_MAX_HIT(victim) / 4)) send_to_char(victim, "That really did HURT!\r\n"); if (GET_HIT(victim) < (GET_MAX_HIT(victim) / 4)) { send_to_char(victim, "%sYou wish that your wounds would stop BLEEDING so much!%s\r\n", CCRED(victim, C_SPR), CCNRM(victim, C_SPR)); if (ch != victim && MOB_FLAGGED(victim, MOB_WIMPY)) do_flee(victim, NULL, 0, 0); } if (!IS_NPC(victim) && GET_WIMP_LEV(victim) && (victim != ch) && GET_HIT(victim) < GET_WIMP_LEV(victim) && GET_HIT(victim) > 0) { send_to_char(victim, "You wimp out, and attempt to flee!\r\n"); do_flee(victim, NULL, 0, 0); } break; } /* Help out poor linkless people who are attacked */ if (!IS_NPC(victim) && !(victim->desc) && GET_POS(victim) > POS_STUNNED) { do_flee(victim, NULL, 0, 0); if (!FIGHTING(victim)) { act("$n is rescued by divine forces.", FALSE, victim, 0, 0, CommTarget::TO_ROOM); GET_WAS_IN(victim) = IN_ROOM(victim); char_from_room(victim); char_to_room(victim, 0); } } /* stop someone from fighting if they're stunned or worse */ if (GET_POS(victim) <= POS_STUNNED && FIGHTING(victim) != NULL) stop_fighting(victim); /* Uh oh. Victim died. */ if (GET_POS(victim) == POS_DEAD) { if (ch != victim && (IS_NPC(victim) || victim->desc)) { if (AFF_FLAGGED(ch, AFF_GROUP)) group_gain(ch, victim); else solo_gain(ch, victim); } if (!IS_NPC(victim)) { mudlog(BRF, LVL_IMMORT, TRUE, "%s killed by %s at %s", GET_NAME(victim), GET_NAME(ch), world[IN_ROOM(victim)].name); if (MOB_FLAGGED(ch, MOB_MEMORY)) forget(ch, victim); } die(victim); return (-1); } return (dam); }
static void MVD_Stats_Gather_AlivePlayer(int player_index) { int x; // item index int z; // item index int i = player_index; int killdiff; int taken = 0; int ammotaken[AMMO_TYPES] = {0, 0, 0, 0}; qbool had_mega; qbool has_mega; for (x=GA_INFO;x<=RA_INFO && mvd_cg_info.deathmatch!=4;x++){ if(mvd_new_info[i].p_info->stats[STAT_ITEMS] & mvd_wp_info[x].it) { if (!mvd_new_info[i].mvdinfo.itemstats[x].has) { taken |= (1 << x); MVD_Set_Armor_Stats(x,i); mvd_new_info[i].mvdinfo.itemstats[x].count++; mvd_new_info[i].mvdinfo.itemstats[x].lost=mvd_new_info[i].p_info->stats[STAT_ARMOR]; mvd_new_info[i].mvdinfo.itemstats[x].has=1; mvd_new_info[i].mvdinfo.itemstats[x].starttime = cls.demotime; } if (mvd_new_info[i].mvdinfo.itemstats[x].lost < mvd_new_info[i].p_info->stats[STAT_ARMOR]) { taken |= (1 << x); mvd_new_info[i].mvdinfo.itemstats[x].count++; mvd_new_info[i].mvdinfo.itemstats[x].starttime = cls.demotime; } mvd_new_info[i].mvdinfo.itemstats[x].lost=mvd_new_info[i].p_info->stats[STAT_ARMOR]; } } for (x=RING_INFO;x<=PENT_INFO && mvd_cg_info.deathmatch!=4;x++){ if(!mvd_new_info[i].mvdinfo.itemstats[x].has && mvd_new_info[i].p_info->stats[STAT_ITEMS] & mvd_wp_info[x].it){ taken |= (1 << x); mvd_new_info[i].mvdinfo.itemstats[x].has = 1; if (x==PENT_INFO && (powerup_cam_active == 3 || powerup_cam_active == 2)){ pent_mentioned=0; pent_is_active=1; powerup_cam_active-=2; } if (x==QUAD_INFO && (powerup_cam_active == 3 || powerup_cam_active == 1)){ quad_mentioned=0; quad_is_active=1; powerup_cam_active-=1; } mvd_new_info[i].mvdinfo.itemstats[x].starttime = cls.demotime; mvd_new_info[i].mvdinfo.itemstats[x].count++; } if (mvd_new_info[i].mvdinfo.itemstats[x].has && !(mvd_new_info[i].p_info->stats[STAT_ITEMS] & mvd_wp_info[x].it)){ mvd_new_info[i].mvdinfo.itemstats[x].has = 0; if (x==QUAD_INFO && quad_is_active){ quad_is_active=0; } if (x==PENT_INFO && pent_is_active){ pent_is_active=0; } mvd_new_info[i].mvdinfo.itemstats[x].runs[mvd_new_info[i].mvdinfo.itemstats[x].run].starttime = mvd_new_info[i].mvdinfo.itemstats[x].starttime; mvd_new_info[i].mvdinfo.itemstats[x].runs[mvd_new_info[i].mvdinfo.itemstats[x].run].time = cls.demotime - mvd_new_info[i].mvdinfo.itemstats[x].starttime; mvd_new_info[i].mvdinfo.itemstats[x].run++; } } had_mega = mvd_new_info[i].mvdinfo.itemstats[MH_INFO].has > 0; has_mega = mvd_new_info[i].p_info->stats[STAT_ITEMS] & IT_SUPERHEALTH; if (!had_mega && has_mega) { // Picked up mega mvd_new_info[i].mvdinfo.itemstats[MH_INFO].mention = 1; mvd_new_info[i].mvdinfo.itemstats[MH_INFO].has = 1; mvd_new_info[i].mvdinfo.itemstats[MH_INFO].count++; mvd_new_info[i].mvdinfo.itemstats[MH_INFO].starttime = cls.demotime; } else if (has_mega && mvd_new_info[i].mvdinfo.itemstats[MH_INFO].lost < mvd_new_info[i].p_info->stats[STAT_HEALTH] && mvd_new_info[i].p_info->stats[STAT_HEALTH] > 100) { // They already had mega health but health increased - must have been another mega mvd_new_info[i].mvdinfo.itemstats[MH_INFO].mention = 1; mvd_new_info[i].mvdinfo.itemstats[MH_INFO].has++; mvd_new_info[i].mvdinfo.itemstats[MH_INFO].count++; mvd_new_info[i].mvdinfo.itemstats[MH_INFO].starttime = cls.demotime; } mvd_new_info[i].mvdinfo.itemstats[MH_INFO].lost = mvd_new_info[i].p_info->stats[STAT_HEALTH]; if (had_mega && !has_mega) { // Might have had two megas ticking down, create as many clocks as necessary while (mvd_new_info[i].mvdinfo.itemstats[MH_INFO].has--) { MVD_ClockStart(MH_INFO); } } for (z=RING_INFO;z<=PENT_INFO;z++){ if (mvd_new_info[i].mvdinfo.itemstats[z].has == 1){ mvd_new_info[i].mvdinfo.itemstats[z].runs[mvd_new_info[i].mvdinfo.itemstats[z].run].starttime = mvd_new_info[i].mvdinfo.itemstats[z].starttime; mvd_new_info[i].mvdinfo.itemstats[z].runs[mvd_new_info[i].mvdinfo.itemstats[z].run].time = cls.demotime - mvd_new_info[i].mvdinfo.itemstats[z].starttime; } } if (mvd_new_info[i].mvdinfo.lastfrags != mvd_new_info[i].p_info->frags ){ if (mvd_new_info[i].mvdinfo.lastfrags < mvd_new_info[i].p_info->frags){ killdiff = mvd_new_info[i].p_info->frags - mvd_new_info[i].mvdinfo.lastfrags; for (z=0;z<8;z++){ if (z == MVD_Weapon_LWF(mvd_new_info[i].mvdinfo.lfw)) mvd_new_info[i].mvdinfo.killstats.normal[z].kills+=killdiff; } if (mvd_new_info[i].mvdinfo.lfw == -1) mvd_new_info[i].mvdinfo.spawntelefrags+=killdiff; for(z=8;z<11;z++){ if(mvd_new_info[i].mvdinfo.itemstats[z].has) mvd_new_info[i].mvdinfo.itemstats[z].runs[mvd_new_info[i].mvdinfo.itemstats[z].run].frags+=killdiff; } mvd_new_info[i].mvdinfo.runs[mvd_new_info[i].mvdinfo.run].frags++; }else if (mvd_new_info[i].mvdinfo.lastfrags > mvd_new_info[i].p_info->frags){ killdiff = mvd_new_info[i].mvdinfo.lastfrags - mvd_new_info[i].p_info->frags ; for (z=AXE_INFO;z<=LG_INFO;z++){ if (z == MVD_Weapon_LWF(mvd_new_info[i].mvdinfo.lfw)) mvd_new_info[i].mvdinfo.killstats.normal[z].teamkills+=killdiff; } if (mvd_new_info[i].mvdinfo.lfw == -1){ mvd_new_info[i].mvdinfo.teamspawntelefrags+=killdiff; } for(z=8;z<11;z++){ if(mvd_new_info[i].mvdinfo.itemstats[z].has) mvd_new_info[i].mvdinfo.itemstats[z].runs[mvd_new_info[i].mvdinfo.itemstats[z].run].teamfrags+=killdiff; } mvd_new_info[i].mvdinfo.runs[mvd_new_info[i].mvdinfo.run].teamfrags++; } mvd_new_info[i].mvdinfo.lastfrags = mvd_new_info[i].p_info->frags ; } mvd_new_info[i].mvdinfo.runs[mvd_new_info[i].mvdinfo.run].time=cls.demotime - mvd_new_info[i].mvdinfo.das.alivetimestart; if (mvd_new_info[i].mvdinfo.lfw == -1){ if (mvd_new_info[i].mvdinfo.lastfrags > mvd_new_info[i].p_info->frags ){ mvd_new_info[i].mvdinfo.teamspawntelefrags += mvd_new_info[i].p_info->frags - mvd_new_info[i].mvdinfo.lastfrags ; }else if (mvd_new_info[i].mvdinfo.lastfrags < mvd_new_info[i].p_info->frags ){ mvd_new_info[i].mvdinfo.spawntelefrags += mvd_new_info[i].p_info->frags -mvd_new_info[i].mvdinfo.lastfrags ; } mvd_new_info[i].mvdinfo.lastfrags = mvd_new_info[i].p_info->frags; } if (mvd_new_info[i].p_state->weaponframe > 0) mvd_new_info[i].mvdinfo.lfw=mvd_new_info[i].p_info->stats[STAT_ACTIVEWEAPON]; if (mvd_cg_info.deathmatch!=4){ MVD_Status_WP(i, &taken); for (z=SSG_INFO;z<=RA_INFO;z++) { MVD_Status_Announcer(i,z); } } for (x = 0; x < AMMO_TYPES; x++) { int ammo_new = mvd_new_info[i].p_info->stats[STAT_SHELLS + x]; int ammo_old = mvd_new_info[i].mvdinfo.ammostats[x]; if (mvd_new_info[i].mvdinfo.initialized && ammo_new > ammo_old) { int diff = ammo_new - ammo_old; ammotaken[x] = diff; } mvd_new_info[i].mvdinfo.ammostats[x] = mvd_new_info[i].p_info->stats[STAT_SHELLS + x]; } for (x = 0; x < mvd_info_types; x++) { if (taken & (1 << x)) { qbool weapon_from_backpack = IS_WEAPON(x) && MVD_Weapon_From_Backpack(x, taken, ammotaken); // don't start clock if item was from backpack qbool add_clock = !weapon_from_backpack; Com_DPrintf("player %i took %i, weapon from backpack: %s\n", i, x, weapon_from_backpack ? "yes" : "no"); MVD_Took(i, x, add_clock); } } }