/* Do not remove the headers from this file! see /USAGE for more info. */ #include <hooks.h> varargs mixed call_hooks(string, mixed, mixed); int query_attack_speed(); string query_random_armor_slot(); object query_target(); object get_target(); object query_weapon(); void add_event(object target, object weapon, mixed target_extra, mixed data); int chance_to_hit(object, object); int disarm_chance(object); int calculate_damage(object, object); int badly_wounded(); int panic(); varargs void stop_fight(object); int check_condition(int); void simple_action(string); int query_ghost(); void target_is_asleep(); void handle_events(); void try_to_ready(); object * query_readied(); void remove_readied(object); void dispatch_opponent() { add_event(query_target(), query_weapon(), 0, "dispatch"); } void take_a_swing(object target) { object weapon = query_weapon(); int chance, roll; // This handles loadable weapons - eg bows // If they aren't loaded - load them and return // If they are, treat the ammunition as the weapon for combat if(weapon->query_loadable()) { if(!sizeof(query_readied())) // Any ammunition selected and ready ? { try_to_ready(); // Try to ready ammunition for next round return; } if(weapon->query_loaded()) // Is weapon ready to fire ? { weapon->discharge(target); // Call discharge() in weapon weapon = query_readied()[0]; // Use ammo as weapon remove_readied(weapon); // Remove ammunition from readied list weapon->discharge(target); // Call discharge() in ammunition } else { weapon->load(); // continue loading return; } } chance = chance_to_hit(weapon, target); if(chance < 2) chance = 2; if(chance > 98) chance = 98; if(badly_wounded() && random(3) == 0) panic(); #if 0 switch(panic()) { case 2: stop_fight(); /* falls through */ case 1: return 0; } #endif /* 0 */ roll = random(100); if(roll > chance) { if(random(100) < disarm_chance(target) && target->query_weapon() != target) add_event(target, weapon, 0, "disarm"); else add_event(target, weapon, 0, "miss"); } else { add_event(target, weapon, query_random_armor_slot(), calculate_damage(weapon, target)); } } void attack() { object target; mixed tmp; tmp = call_hooks("prevent_combat", (: $1 + "|" + $2 :)); if(sizeof(tmp)) { tmp = explode(tmp, "|"); tmp -= ({ "0" }); tmp = format_list(tmp); write("Attack prevented by " + tmp + ".\n"); return; } /* check whether we are capable of attacking */ if(tmp = check_condition(1)) { if(tmp[<1] == '\n') write(tmp); else simple_action(tmp + " so $p blows are ineffective."); return; } for(int n = 0; n < query_attack_speed(); n++) { /* any reason to continue the carnage? */ if(query_ghost() || !(target = get_target())) { stop_fight(); return; } if(target->query_asleep()) { /* Our target is unconscious. We get to have our way with them * *evil grin* */ target_is_asleep(); return; } take_a_swing(target); handle_events(); } }