#include "weapon.h" /* static mixed attack_name, attack_data; */ mixed attack_name, attack_data; static string skill; void create() { attack_name = ({ }); attack_data = ({ }); } int add_attack(string name, mixed flag, int chance, mixed base, mixed hit, mixed dam, string type) { /* Checks whether an attack with that name already exists */ if (member_array(name, attack_name) != -1) return 0; attack_name += ({ name }); attack_data += ({ flag, chance, base, hit, dam, type }); } mixed query_attack_name() { return attack_name; } mixed query_attack_data() { return attack_data; } void set_weap_skill(string str) { skill = str; } string query_weap_skill() { return skill; } int add_arr_attack(string name, mixed *arr) { int i; if (!pointerp(arr) || sizeof(arr) != W_ARRAY_SIZE) return 0; if ((i=member_array(name, attack_name)) != -1) { attack_data = attack_data[0..i*W_ARRAY_SIZE-1] + arr+attack_data[(i+1)*W_ARRAY_SIZE+1..sizeof(attack_data)]; return 1; } attack_name += ({ name }); attack_data += arr; return 1; } void remove_attack(string name) { int i; if ((i=member_array(name, attack_name)) == -1) return ; attack_name = delete(attack_name, i, 1); attack_data = delete(attack_data, i*W_ARRAY_SIZE, W_ARRAY_SIZE); } int calc_value(mixed arg, int skill, string name) { int i, amt; if (intp(arg)) return (int)this_object()->modify_damage((random(arg)*(100+skill))/300, name); if (!pointerp(arg)) return 0; switch (sizeof(arg)) { case 1: return (int)this_object()->modify_damage(arg[F_FIXED], name); case 2: return (int)this_object()->modify_damage(arg[F_FIXED]+ ((random(arg[F_RAND])*(100+skill))/300), name); case 3: for (i=0;i<arg[F_NUM];i++) amt += random(arg[F_DIE]); return (int)this_object()->modify_damage(arg[F_FIXED]+((amt* (100+skill))/300), name); default : return 0; } } static object target, me; void do_attack(int name) { int i, off, hit, base, ac, skill_val; string our_name; our_name = attack_name[name]; off = name*W_ARRAY_SIZE; if (skill) skill_val = (int)me->query_skill_bonus(skill); else skill_val = 50; base = calc_value(attack_data[off+W_BASE], skill_val, our_name); hit = calc_value(attack_data[off+W_HIT], skill_val, our_name); ac = (int)target->query_ac(attack_data[off+W_TYPE]); hit += base - ac; if (hit < 0) { this_object()->write_message(0, target, me, attack_data[off+W_TYPE],our_name); this_object()->hit_weapon(ac, name); return ; } base -= ac; if (base < 0) base = 0; base += calc_value(attack_data[off+W_DAM], skill_val, our_name); this_object()->write_message(base, target, me, attack_data[off+W_TYPE], our_name); this_object()->hit_weapon(ac, name); if (base > target->query_hp()) base = target->query_hp()+1; target->adjust_hp(-base); me->adjust_xp(base/10); if (!target) return ; for (i=0;i<sizeof(attack_data);i+=W_ARRAY_SIZE) if (attack_data[i+W_FLAG] == our_name) if (random(100) < attack_data[i+W_CHANCE]) if (attack_data[i+W_CHANCE]>200) { if (hit > attack_data[i+W_CHANCE]-200) do_attack(i/W_ARRAY_SIZE); } else do_attack(i/W_ARRAY_SIZE); } int weapon_attack(object targ, object ob) { int i, off; target = targ; me = ob; for (i=0;i<sizeof(attack_name);i++) { off = i*W_ARRAY_SIZE; if (!target) continue; if (!attack_data[off+W_FLAG]) if (random(100)<attack_data[off+W_CHANCE]) do_attack(i); } } void write_message(int dam, object attack_ob, object attack_by, string type, string name) { string *message; message = (string *)"/std/weapon.mess"->query_message(dam ,type, attack_ob, attack_by, name); if (message && sizeof(message) >= 3) { tell_object(attack_by, message[0]); tell_object(attack_ob, message[1]); tell_room(environment(attack_ob), message[2], ({ attack_ob, attack_by }) ); return ; } if (dam<30) { tell_object(attack_by, "You missed "+attack_ob->short()+".\n"); tell_object(attack_ob, capitalize((string)attack_by->short()) + " missed you.\n"); tell_room(environment(attack_ob), capitalize((string)attack_by->short()) + " misses " + attack_ob->short() + ".\n", ({ attack_ob, attack_by })); } else { tell_object(attack_by, "You hit " + attack_ob->short() + ".\n"); tell_object(attack_ob, capitalize((string)attack_by->short()) + " hits you.\n"); tell_room(environment(attack_ob), capitalize((string)attack_by->short()) + " hits " + attack_ob->short() + ".\n", ({ attack_ob, attack_by })); } } string calc_string(mixed b) { if (intp(b)) return "rand("+b+")"; if (!pointerp(b)) return "Dead"; switch (sizeof(b)) { case 1 : return ""+b[0]; case 2 : return ""+b[0]+"+rand("+b[1]+")"; case 3 : return ""+b[0]+"+"+b[1]+"d"+b[2]; default : return "Oh hell"; } } mixed weapon_stats() { int i, j; mixed *ret; ret = ({ }); for (i=0;i<sizeof(attack_data);i+=W_ARRAY_SIZE,j++) ret += ({ ({ "ATT"+j+" name", attack_name[i/W_ARRAY_SIZE], }), ({ " flag", attack_data[i+W_FLAG], }), ({ " chance", attack_data[i+W_CHANCE], }), ({ " base", calc_string(attack_data[i+W_BASE]), }), ({ " hit", calc_string(attack_data[i+W_HIT]), }), ({ " dam", calc_string(attack_data[i+W_DAM]), }), ({ " type", attack_data[i+W_TYPE], }), }); return ret; } void set_attack_name(mixed *bing) { attack_name = bing; } void set_attack_data(mixed *bing) { attack_data = bing; } mixed stats() { return weapon_stats(); } /* stats() */ mixed *query_init_data() { return ({ "attack name", attack_name, "set_attack_name/p", "attack data", attack_data, "set_attack_data/p", "attack skill", skill, "set_weap_skill/p" }); } /* query_init_data() */