#include "unarmed_combat.h" static int ovr_num,ovr_type; static string *custom_attacks; object attacker,defender; static string *bits; /* Unarmed Combat for FR by Sojan Currently unlobotomised/castrated by Baldrick :) On my way... Baldrick. June '94 Totalled, Taniwha, 1997 Now much simpler format and much faster messages (I hope) No cutsey change styles, but thats easy to add, main advantage is the default to what the race does and hits on valid body parts. */ int unarmed_attack(object def, object att); void write_message(int damage, string result, object att, object defdr); void apply_damage(int hps, object att); mixed *workout_attack(string unarmed_type); string *valid_attacks(); void create() { ovr_num=0; ovr_type=0; } string *add_attack(string *strs) { if(custom_attacks) custom_attacks += ({ strs }); else custom_attacks = strs; } string *set_attacks(string *strs) { custom_attacks = strs; } /* generate "bits hit" based on damage compared to max. The most important "bits" are first in the bist array so we just index into the array backwards using damage */ string bithit(int maxd,int dam) { int n; string *m; object *ob; if(!pointerp(bits)) { ob = TO->query_race_ob(); if(ob) bits = ob->query_bits(); } if(!pointerp(bits)) return "somewhere"; if(dam > maxd || dam < 0) dam = maxd; /* break messages up into major and less important bits based on how hard we hit */ /* How many classes of bits do we have ? */ n = sizeof(bits); /* we did damage belonging to this class */ n = (maxd*dam)/n; /* so pick one and return it */ n = sizeof(bits); /* swap array end for end, earlier "bits" are the most important */ n = n/3; n = (n-1)-random(n); n = n *3; return (string)bits[n]; } int unarmed_attack(object def, object att) { mixed att_val; attacker = att; defender = def; att_val=workout_attack(""); if(att_val[0]=="hit") apply_damage((int)att_val[1], att); write_message((int)att_val[1], att_val[0], att, def); return att_val[1]; } /* unarmed_attack */ mixed *workout_attack(string unarmed_type) { string happen; int tmproll,result, achit, defenderac, damage_done, THAC0; // Taniwha 1995, LUCK factor tmproll = random(200); if( tmproll < defender->query_cha() ) return ({ "fumble", 0}); THAC0=(int)attacker->query_thac0(); /* This is the way it is done everywhere else.. */ achit = ((THAC0 - (int)attacker->query_tohit_bonus()) - tmproll); defenderac = (int)defender->query_total_ac(); result = (achit - defenderac); if (result < 1) { happen = "hit"; damage_done=roll(BDEFNUM, BDEFTYPE); // Taniwha 1995, critical hit, luck based if( random(200) < attacker->query_cha() ) damage_done *= 2; } else { happen = "miss"; damage_done = 0; } return ({ happen, damage_done }); } /* workout_attack */ /* This needs the attacker's object too.. */ void apply_damage(int hps, object att) { if(hps<0) hps=0; /* taniwha, was attacker here, God knows ;) who that was */ defender->adjust_hp(-hps, att); return; } // Muchly simplied system, taniwha void write_message(int damage, string result, object att, object defdr) { string *vatts; string tmp,an,bn,dn; int i,maxd; vatts = valid_attacks(); dn = defdr->query_cap_name(); an = att->query_cap_name(); switch(result) { case "hit": maxd = ovr_num * ovr_type; bn = bithit(maxd,damage); i=random(sizeof(vatts)/3)*3; tmp = vatts[i]; tmp = replace_string(tmp,"AN",an); tmp = replace_string(tmp,"DN",dn); tmp = replace_string(tmp,"BN",bn); tell_room(ENV(att),tmp+".\n", ({att, defdr})); tmp = vatts[i+1]; tmp = replace_string(tmp,"AN",an); tmp = replace_string(tmp,"DN",dn); tmp = replace_string(tmp,"BN",bn); tell_object(att, tmp+" causing "+damage+" hp's damage.\n"); tmp = vatts[i+2]; tmp = replace_string(tmp,"AN",an); tmp = replace_string(tmp,"DN",dn); tmp = replace_string(tmp,"BN",bn); tell_object(defdr, tmp+" doing "+damage+" hp's damage.\n"); break; default: case "miss": case "fumble": tell_room(ENV(att),an+" misses "+dn+".\n",({att, defdr})); tell_object(att,"You miss "+dn+".\n"); tell_object(defdr,an+" missed you.\n"); break; } } /* returns triplets of messages room hitter target AN is replaced with attacker name DN is replaced with defender name BN is replaced with the name of a selected body part */ string *valid_attacks() { object race_ob; /* O.K. if this has been set, use it */ if(custom_attacks) return custom_attacks; /* Else scrounge round the race object */ race_ob = TO->query_race_ob(); if(race_ob) { custom_attacks = race_ob->valid_attacks(); if(custom_attacks) return custom_attacks; } else /* else Never Happen */ { custom_attacks = ({ "AN kisses DN on the BP", "You kiss DN", "DN kissed you"}); } return custom_attacks; } void set_damage_dice(int numdie, int dietype) { if(numdie>0 && dietype>0) { ovr_num=numdie; ovr_type=dietype; } return; }