#pragma strict_types
#pragma save_types
#pragma combine_strings
#include <mudlib.h>
inherit BASE;
#define ALT "external"
/* armour materials, resilience. eventually armour is destroyed */
#define ARM_MOD 1
#define STR_MOD 10 /* When the current str is this, -1 ac & wt */
#define MAX_REPAIR 3 /* max times armour can be repaired */
#define ARM_COMPLEXITY 14
#define CLASS_ALLOWED_ARMOUR(WHO) \
call_other("/function/am_allow", "allowed_armour", \
WHO,query_name(),query_type(),query_armour_material())
string armour_mat; /* the material of the armour */
int max_strength; /* Max dam armour can take */
int current_strength; /* current value of strength */
int repair; /* amount of times the armour been repaired */
int absorb_dam; /* amount of dam armour can absorb */
/* armour basics */
string type; /* armour type, also an identifier */
status worn; /* flag true if worn */
int armour_class; /* armour class value of the armour */
object worn_by; /* who wears this */
/*** function prototypes ***/
/* actions */
status wear(string str);
status remove(string str);
void hit_armour(int damage);
void calc_strength();
int repair_armour(int i);
string set_type(string s);
int set_ac(int ac);
int set_current_strength(int i);
int set_max_strength(int i);
int set_repair(int i);
string set_armour_material(string arg);
status set_worn(status i);
object set_worn_by(object ob);
void set_arm_light(int i);
/* query */
int armour_class();
int query_ac();
status query_worn();
object query_worn_by();
string query_type();
string query_armour_material();
int query_current_strength();
int query_armour_strength();
int query_max_strength();
int query_compexity();
int query_complex();
int query_repair();
int query_max_value();
void load_armour(mixed *arg);
/**************************************************************************/
/**************************************************************************/
/*** Standard operation functions for armour objects. ***/
#ifdef NATIVE_MODE
void create() {
#else
void reset(status arg) {
if(arg) return;
#endif /* native */
/* default */
set_short("Chainmail");
set_name("chainmail");
set_long("The chainmail looks old and rusty, "+
"and smells like an ironworks.\n");
set_type("armour");
set_armour_material("iron");
set_value(100);
set_weight(4);
set_ac(2);
}
status get() { return 1; }
status id(string str) { return ::id(str) || str == type; }
string query_object_type() { return "Armour"; }
status drop(status silently) {
if(worn) {
if(!silently && worn_by)
tell_object(worn_by, "You drop your worn armour.\n");
worn = 0;
if(worn_by) worn_by->recalc_ac();
worn_by = 0;
}
return 0;
}
string short(status wiz) {
string str;
if(worn && environment() != worn_by) { /* failsafe */
worn = 0;
if(worn_by) worn_by->recalc_ac();
worn_by = 0;
}
if(!(str = ::short(wiz))) return 0;
if(wiz) str += "\("+current_strength+"/"+max_strength+"\)";
if(worn) str += " (worn)";
return str;
}
void long(status wiz) {
string str;
::long(wiz);
::extra_long(wiz);
if(!type) type = "armour";
str = "";
if(wiz) str += "Armour stats: "+current_strength+"/"+max_strength+".\n";
str += "The "+type;
str += (extract(type,strlen(type)-1)=="s")
? " are "
: " is ";
str += (current_strength > max_strength/2)
? "in superb condition.\n"
: (current_strength > max_strength/3)
? "in fine condition.\n"
: (current_strength > max_strength/4)
? "in average condition.\n"
: (current_strength > max_strength/5)
? "showing wear and tear.\n"
: (current_strength > max_strength/6)
? "quite beaten and dented.\n"
: "falling apart!\n";
write(str);
}
void init () {
::init();
if(!max_strength) calc_strength();
if(environment(this_object()) != this_player()) return;
add_action ("wear", "wear");
add_action ("remove", "remove");
}
/**************************************************************************/
/**************************************************************************/
/* actions */
status wear(string str) {
object ob, env;
env = environment();
if(!str) {
notify_fail("wear what?\n");
return 0;
}
if(!(ob = present(str, this_player()))) {
notify_fail("You don't have a "+ str +".\n");
return 0;
}
if(ob != this_object()) {
notify_fail("You can't do that!\n");
return 0;
}
if(worn) {
tell_object(env,"You already wear it!\n");
return 1;
}
if(ALT) {
object alt; int i;
for(i = 1; (alt = present(ALT+" "+i, this_player())); i++) {
if(alt->wear_func(ob)) return 1;
}
}
if(!env->query_npc() && !CLASS_ALLOWED_ARMOUR(env)) return 1;
if(env->query_armour_type(type)) {
tell_object(env,"You already wear ");
if(type == "armour")
tell_object(env,"Armour.\n");
else if(type == "amulet")
tell_object(env,"an Amulet\n");
else
tell_object(env,"a "+capitalize(type)+".\n");
return 1;
}
if(env->two_weapons_wielded() && type == "shield") {
tell_object(env,"You cannot wear a shield while wielding two weapons.\n");
return 1;
}
worn = 1;
worn_by = env;
worn_by->recalc_ac();
write("You wear "+ query_name() +".\n");
say(env->query_name() +" wears "+ query_name() +".\n");
return 1;
}
status remove(string str) {
object ob, env;
object alt;
int i;
env = environment();
if(!str) {
notify_fail("remove what?\n");
return 0;
}
if(!(ob = present(str, this_player()))) {
notify_fail("You don't have a "+ str +".\n");
return 0;
}
if(ob != this_object()) {
notify_fail("You can't do that!\n");
return 0;
}
if(!worn) {
tell_object(env,"You are not wearing it!\n");
return 1;
}
if(ALT) {
for(i = 1; (alt = present(ALT+" "+i, this_player())); i++) {
if(alt->remove_func(ob)) return 1;
}
}
worn = 0;
worn_by = 0;
env->recalc_ac();
tell_object(env,"You remove "+ (string)this_object()->short()+"\n");
say(env->query_name() +" removes "+(string)this_object()->short()+"\n");
return 1;
}
/***************************************************************************/
/***************************************************************************/
/* hit armour */
/* hit armor */
void hit_armour(int damage){
object env;
damage = damage - absorb_dam;
if(damage < 0) return;
current_strength -= damage;
if(!(env = environment())) return;
if(current_strength < (max_strength/STR_MOD)){
if(armour_class > 1) {
armour_class--;
env->recalc_ac();
}
if(weight > 1){
weight--;
env->recalc_carry();
}
}
if(current_strength <= 0){
tell_object(env, "Your "+ type +" falls to pieces!\n");
if(environment(env)) {
tell_room(environment(env),
env->query_name()+"'s "+ type +" falls to pieces!\n");
this_object()->drop(1); /* silently...shhhhhh! */
destruct(this_object());
}
}
}
/* end hit armour */
/***************************************************************************/
/***************************************************************************/
/* armour strength */
void calc_strength() {
mixed *armour_strength;
mixed *absorb_rate;
mixed *absorb_material;
int i, tmp_ac, tmp_wt;
armour_strength = ({
({ 500, 550, 600, 650, 700, 750, 800, 850, }),
({ 600, 650, 700, 750, 800, 850, 900, 950, }),
({ 700, 775, 850, 925, 1000, 1025, 1150, 1225, }),
({ 850, 950, 1050, 1150, 1250, 1350, 1450, 1550, }),
({ 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, }),
({ 1100, 1350, 1600, 1850, 2100, 2350, 2600, 2850, }),
});
tmp_ac = (!armour_class)
? 1
: (armour_class < 0)
? armour_class * -1
: (armour_class > 6)
? 6
: armour_class;
tmp_wt = (!weight)
? 2
: (weight < 0)
? weight * -1
: (weight > 8)
? 8
: weight;
max_strength = armour_strength[tmp_ac-1][tmp_wt-1];
max_strength *= ARM_MOD;
absorb_rate = ({
({"armour","shield","helm","ring","cloak","boots","gloves","amulet",}),
({ 10, 6, 5, 4, 4, 2, 2, 2,}),
});
if((i = member_array(type, absorb_rate[0])) > -1) {
absorb_dam = absorb_rate[1][i];
}
else {
absorb_dam = 10;
}
absorb_material = ({
"bone", -50,
"ivory", -50,
"ceramic", -75,
"cloth", -45,
"crystal", -75,
"glass", -100,
"leather", -20,
"metal", 0,
"mithral", 100,
"meteorite iron", 75,
"iron", 20,
"adamantite", 150,
"bronze", -10,
"silver", -20,
"gold", -30,
"platinum", -40,
"steel", 30,
});
if(!armour_mat) armour_mat = "metal";
if((i = member_array(armour_mat,absorb_material)) > -1) {
max_strength = max_strength + absorb_material[i+1];
}
if(!current_strength) {
current_strength = max_strength;
}
}
int repair_armour(int i){
if(i <= 0 || repair > MAX_REPAIR) return 0; /* failure */
current_strength += i;
repair += 1;
if(current_strength > max_strength) current_strength = max_strength;
return current_strength;
}
/****************************************************************************/
/* sets */
string set_type(string s) { return type = s; }
int set_ac(int ac) {
if(type == "armour") {
if(ac > 4) enchanted = 1;
}
else if(ac > 1) {
enchanted = 1;
}
return armour_class = ac;
}
int set_current_strength(int i){
return current_strength = (i > max_strength) ? max_strength : i;
}
int set_max_strength(int i) { return max_strength = i; }
int set_repair(int i) { return repair = i; }
string set_armour_material(string a) {
armour_mat = (a) ? a : "metal";
calc_strength();
return armour_mat;
}
status set_worn(status i) {
worn = (i) ? 1 : 0;
if(worn_by) worn_by->recalc_ac();
if(!worn) worn_by = 0;
return worn;
}
object set_worn_by(object ob) {
if(ob && living(ob)) {
worn_by = ob;
worn = 1;
worn_by->recalc_ac();
}
else {
worn = 0;
}
if(worn_by) worn_by->recalc_ac();
if(!worn) worn_by = 0;
return worn_by;
}
void set_arm_light(int i) { adj_light(i); }
/*************************************************************************/
/*************************************************************************/
/*** Query_*** functions for external objects to access ***/
/*** information on the armour. ***/
int armour_class() { return armour_class; }
int query_ac () { return armour_class; }
status query_worn () { return worn; }
object query_worn_by() { return worn_by; }
string query_type () { return type; }
string query_armour_material() { return armour_mat; }
int query_current_strength(){ return current_strength; }
int query_armour_strength() { return max_strength; }
int query_max_strength() { return max_strength; }
int query_compexity() { return ARM_COMPLEXITY; }
int query_complex() { return ARM_COMPLEXITY; }
int query_repair() { return repair; }
int query_max_value() { return value; }
int query_value () {
return (max_strength < current_strength * 2)
? (value * current_strength)/max_strength
: value/2;
}
status query_sell_destruct () {
if(type == "armour" && armour_class > 4) return 1;
if (type != "armour" && armour_class > 1) return 1;
return ::query_sell_destruct();
}
/* load function added by Crombie, Sept 8, 1993 */
void load_armour(mixed *arg) {
int i, size;
mixed t;
for(i=0; i < sizeof(arg); i += 2) {
t = arg[i+1];
switch(arg[i]) {
case "id": set_id(t); break;
case "name": set_name(t); break;
case "short": set_short(t); break;
case "value": set_value(t); break;
case "weight": set_weight(t); break;
case "ac": set_ac(t); break;
case "alias": set_alias(t); break;
case "long": set_long(t); break;
case "type": set_type(t); break;
case "info": set_info(t); break;
case "quest_item": set_quest_item(t); break;
case "enchanted": set_enchanted(t); break;
case "armour_material": set_armour_material(t); break;
case "sell_destruct": set_sell_destruct(t); break;
case "arm_light": set_arm_light(t); break;
}
}
}