/* player.c */ #include <secure.h> #include <sys.h> #include <weapon.h> #include <combat_def.h> #include <flags.h> #include <armor.h> #define TP(X) tell_player(this_object(),(X)) #define TPE(X) tell_room_except(location(this_object()),this_object(),(X)) #define TPE2(X) tell_room_except2(location(this_object()),this_object(), \ is_attacking,(X)) object me; object is_attacking; string name; string low_name; string password; int alive,hp,max_hp,xp,level,flags,special,gold,armor_dam,armor_hit,is_healing; object weapon,possessor; object armor_worn[NUM_PROT]; add_gold(arg) { gold+=arg; return 1; } static autoheal() { hp+=HEAL_AMOUNT; if (hp>=max_hp) { hp=max_hp; is_healing=0; } else alarm(HEAL_DELAY,"autoheal"); } static do_exits(arg) { object curr; int count,pos; string ename; if (location(this_object())) curr=contents(location(this_object())); while (curr) { if (call_other(curr,"get_type")==TYPE_EXIT) if (!(call_other(curr,"get_flags") & F_DARK)) { if (!count) write("Obvious exits:"); ename=call_other(curr,"get_name"); pos=instr(ename,1,";"); if (pos) write(" "+leftstr(ename,pos-1)); else write(" "+ename); count++; } curr=next_object(curr); } if (!count) write("There are no obvious exits\n"); else write("\n"); return 1; } static do_wear(arg) { string w_name; if (!alive) { write("You're too dead.\n"); return 1; } arg=present(arg,this_object()); if (!arg) { write("You don't have that.\n"); return 1; } if (call_other(arg,"get_type")!=TYPE_ARMOR) { write("You can't wear that.\n"); return 1; } if (armor_worn[call_other(arg,"get_protection")]) { write("You're already wearing something on your "+ make_prot(call_other(arg,"get_protection"))+".\n"); return 1; } w_name=call_other(arg,"get_short"); if (!call_other(arg,"wear")) { write("You can't wear that.\n"); return 1; } write("You wear "+w_name+".\n"); TPE(get_short()+" wears "+w_name+".\n"); armor_worn[call_other(arg,"get_protection")]=arg; recalc_armor(); return 1; } recalc_armor() { int loop; armor_hit=0; armor_dam=0; loop=0; while (loop<NUM_PROT) { if (armor_worn[loop]) { armor_hit+=call_other(armor_worn[loop],"get_hitreduce"); armor_dam+=call_other(armor_worn[loop],"get_damreduce"); } loop++; } } force_unwear(p) { if (armor_worn[p]!=caller_object()) return; armor_worn[p]=0; recalc_armor(); } static do_unwear(arg) { if (!alive) { write("You're too dead.\n"); return 1; } arg=present(arg,this_object()); if (call_other(arg,"get_type")!=TYPE_ARMOR) { write("You're not wearing that.\n"); return 1; } if (armor_worn[call_other(arg,"get_protection")]!=arg) { write("You're not wearing that.\n"); return 1; } if (call_other(arg,"unwear")) { write("You can't unwear that.\n"); return 1; } armor_worn[call_other(arg,"get_protection")]=0; recalc_armor(); write("You unwear "+call_other(arg,"get_short")+".\n"); TPE(get_short()+" unwears "+call_other(arg,"get_short")+".\n"); return 1; } stat() { tell_player(this_player(),"Object Type: PLAYER\n"); if (flags) tell_player(this_player(),"Flags: "+make_flags(flags)+"\n"); if (special) tell_player(this_player(),"Special: "+itoa(special)+"\n"); if (name) tell_player(this_player(),"Name: "+name+"\n"); if (alive) tell_player(this_player(),"HP: "+itoa(hp)+"/"+itoa(max_hp)+ " XP: "+itoa(xp)+" Level: "+itoa(level)+"\n"); else tell_player(this_player(),"HP: DEAD/"+itoa(max_hp)+" XP: "+ itoa(xp)+" Level: "+itoa(level)+"\n"); tell_player(this_player(),"HitReduce: "+itoa(2*level-2)+" (With Armor: "+ itoa(armor_hit+2*level-2)+")\n"); tell_player(this_player(),"DamReduce: 0 (With Armor: "+itoa(armor_dam)+ ")\n"); tell_player(this_player(),"Damage: 1d2+0 (With Weapon: "+(weapon? call_other(weapon,"get_damage"):"1d2+0")+")\n"); tell_player(this_player(),"HitBonus: "+itoa(2*level-2)+" (With Weapon: "+ itoa(2*level-2+(weapon?call_other(weapon,"get_hit_bonus"):0))+ ")\n"); if (weapon) tell_player(this_player(),"Wielding: "+make_num(weapon)+"\n"); if (is_attacking) tell_player(this_player(),"Is Attacking: "+make_num(is_attacking)+"\n"); if (possessor && priv(this_player())) tell_player(this_player(),"Possessed By: "+make_num(possessor)+"\n"); return 1; } is_player() { return 1; } id(arg) { return arg==name || arg==low_name; } get_uid() { return low_name; } set_possessor(arg) { if (!priv(caller_object())) return 0; if (!arg && possessor==caller_object()) { possessor=0; return 1; } if (arg!=caller_object()) return 0; if (possessor && arg) return 0; possessor=arg; return 1; } force_disconnect() { if (!priv(caller_object())) return 0; disconnect_device(); disconnect(); return 1; } force(arg) { command(arg); return 1; } set_name(arg) { if (prototype(this_object())) return; if (name) return; name=arg; low_name=downcase(arg); return 1; } set_password(arg) { if (!arg) return; if (prototype(this_object())) return; if (!priv(caller_object())) return; password=arg; return 1; } set_flags(f) { flags=f; return 1; } set_special(s) { special=s; return 1; } get_flags() { return flags; } get_special() { return special; } static do_password(arg) { string p1,p2; int pos; pos=instr(arg,1," "); p1=leftstr(arg,pos-1); p2=rightstr(arg,strlen(arg)-pos); if (!p1 || !p2) { write("usage: password oldpass newpass\n"); return 1; } if (p1!=password) { write("Wrong password.\n"); return 1; } password=p2; write("Password changed.\n"); return 1; } do_say(arg) { write("You say \""+arg+"\"\n"); TPE(get_short()+" says \""+arg+"\"\n"); return 1; } do_pose(arg) { write(get_short()+" "+arg+"\n"); TPE(get_short()+" "+arg+"\n"); return 1; } check_password(arg) { if (!priv(caller_object())) return 0; return password==arg; } add_xp(arg) { int new_level,new_xp; xp+=arg; if (xp<(new_xp=1000)) new_level=1; else if (xp<(new_xp=2000)) new_level=2; else if (xp<(new_xp=3500)) new_level=3; else if (xp<(new_xp=7000)) new_level=4; else if (xp<(new_xp=10000)) new_level=5; else if (xp<(new_xp=14000)) new_level=6; else if (xp<(new_xp=20000)) new_level=7; else if (xp<(new_xp=30000)) new_level=8; else if (xp<(new_xp=60000)) new_level=9; else if (xp<(new_xp=100000)) new_level=10; else if (xp<(new_xp=160000)) new_level=11; else if (xp<(new_xp=250000)) new_level=12; else if (xp<(new_xp=380000)) new_level=13; else if (xp<(new_xp=600000)) new_level=14; else new_level=15; if (arg) write("You gain "+itoa(arg)+" XP.\n"); if (new_level!=level) { level=new_level; recalc_max_hp(); write("You are now level "+itoa(level)+". "); if (new_level<15) write("Next level at "+itoa(new_xp)+" XP.\n"); else write("\n"); } } recalc_max_hp() { max_hp=10+4*level; if (max_hp>hp && !is_healing) { is_healing=1; alarm(HEAL_DELAY,"autoheal"); } else hp=max_hp; } impending_attack() { if (is_attacking) return (xp/20); is_attacking=caller_object(); attack(0); return (xp/20); } get_name() { return name; } get_hit_msg1(intensity) { string s; if (weapon) s=call_other(weapon,"get_hit_msg1",intensity); if (!s) s=get_def_hit_msg1(intensity); return s; } get_hit_msg2(intensity) { string s; if (weapon) s=call_other(weapon,"get_hit_msg2",intensity); if (!s) s=get_def_hit_msg2(intensity); return s; } get_hit_msg3(intensity) { string s; if (weapon) s=call_other(weapon,"get_hit_msg3",intensity); if (!s) s=get_def_hit_msg3(intensity); return s; } get_hit_msg4(intensity) { string s; if (weapon) s=call_other(weapon,"get_hit_msg4",intensity); if (!s) s=get_def_hit_msg4(intensity); return s; } get_hit_msg5(intensity) { string s; if (weapon) s=call_other(weapon,"get_hit_msg5",intensity); if (!s) s=get_def_hit_msg5(intensity); return s; } get_long() { if (alive) return "This is the player "+name; else return "This is the insubstantial ghost of the player "+name; } move_player(dest,direction) { if (location(this_object())) TPE(get_short()+" goes "+direction+".\n"); move_object(this_object(),dest); look(0); if (dest) TPE(get_short()+" has arrived.\n"); return 1; } look(arg) { int contents_printed,curr; string oname,t; contents_printed=0; t=arg; if (arg) { arg=present(arg,location(this_object())); if (!arg) arg=present(t,this_object()); if (!arg && t=="me") arg=this_object(); if (!arg && t=="here") arg=this_object(); } else if (!location(this_object())) { write("You are in the void.\n"); return 1; } else arg=location(this_object()); if (!arg) { write("You don't see that here.\n"); return 1; } if (arg==location(this_object())) { oname=call_other(arg,"get_short"); if (oname) write(oname+"\n"); } oname=call_other(arg,"get_long"); if (oname) write(oname+"\n"); curr=contents(arg); if (!(call_other(arg,"get_flags") & F_DARK)) while (curr) { if (curr!=this_object()) { oname=call_other(curr,"get_short"); if (oname) { if (!contents_printed) { write("Contents:\n"); contents_printed=1; } write(oname+"\n"); } } curr=next_object(curr); } return 1; } get_type() { return TYPE_PLAYER; } find_enemy() { is_attacking=0; } is_living() { return alive; } get_short() { return alive ? name:"Ghost of "+name; } to_hit_bonus() { int bonus; if (weapon) bonus=call_other(weapon,"get_hit_bonus",is_attacking); else bonus=0; return bonus+2*level-2; } damage_bonus() { int bonus; if (weapon) bonus=call_other(weapon,"get_damage_bonus",is_attacking); else bonus=random(2)+1; return bonus; } static do_kill(arg) { if (!alive) { write("You're too dead.\n"); return 1; } arg=present(arg,location(this_object())); if (!arg) { write("You don't see that here.\n"); return 1; } if (!call_other(arg,"is_living")) { write("You can't kill that, you bonehead.\n"); return 1; } if (arg==this_object()) { write("PLEASE try to control your suicidal impulses.\n"); return 1; } if (arg==is_attacking) { write("You're already attacking that. Chill.\n"); return 1; } write("You start attacking "+call_other(arg,"get_short")+".\n"); tell_player(arg,name+" starts attacking you.\n"); tell_room_except2(location(this_object()),arg,this_object(),name+ " starts attacking "+call_other(arg,"get_short")+".\n"); attack(arg); return 1; } do_damage(amount) { int retval,intensity; object curr,next; amount-=armor_dam; if (amount<0) amount=0; if (!is_healing) { is_healing=1; alarm(HEAL_DELAY,"autoheal"); } retval=(amount>hp)?hp:amount; hp-=amount; if (amount<I_PUNY_AMT) intensity=I_PUNY; else if (amount<I_WEAK_AMT) intensity=I_WEAK; else if (amount<I_POOR_AMT) intensity=I_POOR; else if (amount<I_AVERAGE_AMT) intensity=I_AVERAGE; else if (amount<I_GOOD_AMT) intensity=I_GOOD; else if (amount<I_VERYGOOD_AMT) intensity=I_VERYGOOD; else intensity=I_MASSACRE; write(call_other(caller_object(),"get_short")+" "+ call_other(caller_object(),"get_hit_msg3",intensity)+"\n"); write("You have "+itoa((hp>0)?hp:0)+" hit points left.\n"); if (hp<1) { write("You have died. Your ghost now hovers around uselessly.\n"); hp=0; alive=0; is_attacking=0; curr=clone_object("/obj/corpse"); call_other(curr,"set_name",name); move_object(curr,location(this_object())); if (gold>0) { curr=clone_object("/obj/coins"); call_other(curr,"set_value",gold); move_object(curr,location(this_object())); gold=0; } curr=contents(this_object()); while (curr) { next=next_object(curr); if (call_other(curr,"drop")) { if (!call_other(curr,"dead_drop")) move_object(curr,location(this_object())); } else move_object(curr,location(this_object())); curr=next; } } return retval; } static do_reincarnate(arg) { if (alive) write("Idiot, you haven't DIED yet.\n"); else { if (!location(this_object())) { write("You're not in a temple, you're in the hideous void.\n"); return 1; } if (!(call_other(location(this_object()),"get_flags") & F_TEMPLE)) { write("You're not in a temple.\n"); return 1; } hp=1; alive=1; is_healing=1; xp=xp/2; add_xp(0); alarm(HEAL_DELAY,"autoheal"); write("You come back to life, you hot ticket.\n"); TPE(name+" stops being a ghost, regains flesh, etc.\n"); } return 1; } attempt_hit(chance) { return chance+52-armor_hit-(2*level)>random(100); } get_hitreduce() { return armor_hit; } get_damreduce() { return armor_dam; } attack(enemy) { int enemy_xp,intensity,dmg,tmp; string ename; if (enemy==this_object()) return; if (is_attacking==this_object()) { is_attacking=0; return; } if (!alive) { is_attacking=0; return; } if (enemy) if (is_attacking) { is_attacking=enemy; return; } else is_attacking=enemy; if (!is_attacking) find_enemy(); if (!is_attacking) return; if (!call_other(is_attacking,"is_living")) find_enemy(); if (!is_attacking) return; if (location(is_attacking)!=location(this_object())) find_enemy(); if (!is_attacking) return; ename=call_other(is_attacking,"get_short"); enemy_xp=call_other(is_attacking,"impending_attack"); if (!alive) return; if (call_other(is_attacking,"attempt_hit",to_hit_bonus())) { dmg=damage_bonus(); tmp=call_other(is_attacking,"do_damage",dmg); if (dmg<I_PUNY_AMT) { intensity=I_PUNY; } else if (dmg<I_WEAK_AMT) { intensity=I_WEAK; } else if (dmg<I_POOR_AMT) { intensity=I_POOR; } else if (dmg<I_AVERAGE_AMT) { intensity=I_AVERAGE; } else if (dmg<I_GOOD_AMT) { intensity=I_GOOD; } else if (dmg<I_VERYGOOD_AMT) { intensity=I_VERYGOOD; } else { intensity=I_MASSACRE; } TP(get_hit_msg1(intensity)+ename+get_hit_msg2(intensity)+"\n"); TPE2(get_short()+" "+get_hit_msg4(intensity)+ename+get_hit_msg5(intensity) +"\n"); if (!call_other(is_attacking,"is_living")) { TP("You have killed "+ename+"!\n"); TPE2(get_short()+" has killed "+ename+"!\n"); add_xp(enemy_xp); find_enemy(); } } else { TP("You missed "+ename+".\n"); tell_player(is_attacking,get_short()+" misses you.\n"); TPE2(get_short()+" misses "+ename+".\n"); } alarm(3,"attack"); } do_quit(arg) { TPE(get_short()+" has disconnected.\n"); disconnect_device(); return 1; } static do_inventory(arg) { int count; object curr; string oname; count=0; curr=contents(this_object()); while (curr) { oname=call_other(curr,"get_short"); if (oname) { if (!count) { write("You are carrying:\n"); } count++; write(oname+"\n"); } curr=next_object(curr); } if (gold) write("You have "+itoa(gold)+" gold coins.\n"); if (!count && !gold) write("You are empty-handed.\n"); return 1; } get_gold() { return gold; } static do_score(arg) { if (alive) { write("HP: "+itoa(hp)+"/"+itoa(max_hp)+" Level: "+itoa(level)+ " XP: "+itoa(xp)+" Gold: "+itoa(gold)+"\n"); } else write("You are dead. This implies your score kinda SUCKS.\n"); return 1; } static do_help(arg) { object curr,found; string s; if (arg) { curr=next_child(atoo("/sys/help1")); while (curr && !found) { if (call_other(curr,"get_topic")==arg) found=curr; curr=next_child(curr); } if (!found) { write("There is no help available on that topic.\n"); return 1; } s=(call_other(found,"get_text")); if (s) write("\n"+s+"\n"); else write("Help has not been entered for that topic.\n"); return 1; } write("\nHelp available for the following:\n"); write("---------------------------------\n"); curr=next_child(atoo("/sys/help1")); while (curr) { write(call_other(curr,"get_topic")+" "); curr=next_child(curr); } write("\n\n"); return 1; } static banner() { cat("/motd"); look(0); } connect() { TPE(get_short()+" has connected.\n"); alarm(0,"banner"); } static do_huh(arg) { write(HUH_STRING); } static do_quit(arg) { write("Bye!\n"); disconnect_device(); disconnect(); return 1; } static do_who(arg) { who_list(); return 1; } static do_get(arg) { if (!alive) { write("You're too dead.\n"); return 1; } arg=present(arg,location(this_object())); if (!arg) { write("You don't see that here.\n"); return 1; } if (!call_other(arg,"get")) { write("You can't get "+call_other(arg,"get_short")+".\n"); return 1; } move_object(arg,this_object()); write("You get "+call_other(arg,"get_short")+".\n"); TPE(get_short()+" gets "+call_other(arg,"get_short")+"\n"); move_object(arg,this_object()); return 1; } static do_drop(arg) { if (!alive) { write("You're too dead.\n"); return 1; } arg=present(arg,(this_object())); if (!arg) { write("You don't have that.\n"); return 1; } if (call_other(arg,"drop")) { write("You can't drop "+call_other(arg,"get_short")+".\n"); return 1; } write("You drop "+call_other(arg,"get_short")+".\n"); TPE(get_short()+" drops "+call_other(arg,"get_short")+"\n"); move_object(arg,location(this_object())); return 1; } static do_wield(arg) { string w_name; if (!alive) { write("You're too dead.\n"); return 1; } arg=present(arg,this_object()); if (!arg) { write("You don't have that.\n"); return 1; } if (weapon) { write("You are already wielding a weapon.\n"); return 1; } w_name=call_other(arg,"get_short"); if (!call_other(arg,"wield")) { write("You can't wield that.\n"); return 1; } write("You wield "+w_name+".\n"); TPE(get_short()+" wields "+w_name+".\n"); weapon=arg; return 1; } force_unwield() { if (weapon!=caller_object()) return; weapon=0; } static do_unwield(arg) { if (!alive) { write("You're too dead.\n"); return 1; } arg=present(arg,this_object()); if (arg!=weapon) { write("You aren't wielding that.\n"); return 1; } if (call_other(arg,"unwield")) { write("You can't unwield "+call_other(arg,"get_short")+".\n"); return 1; } weapon=0; write("You unwield "+call_other(arg,"get_short")+".\n"); TPE(get_short()+" unwields "+call_other(arg,"get_short")+".\n"); return 1; } disconnect() { TPE(get_short()+" has disconnected.\n"); } static init() { check_secure(SECURE_PRIV,""); alive=1; set_interactive(); max_hp=14; hp=max_hp; xp=0; level=1; me=this_object(); if (!prototype(me)) return; add_xverb("","do_huh"); add_verb("say","do_say"); add_verb("pose","do_pose"); add_xverb(":","do_pose"); add_xverb("\"","do_say"); add_verb("help","do_help"); add_verb("?","do_help"); add_verb("i","do_inventory"); add_verb("inventory","do_inventory"); add_verb("l","look"); add_verb("look","look"); add_verb("drop","do_drop"); add_verb("get","do_get"); add_verb("take","do_take"); add_verb("wield","do_wield"); add_verb("unwield","do_unwield"); add_verb("who","do_who"); add_verb("quit","do_quit"); add_verb("reincarnate","do_reincarnate"); add_verb("kill","do_kill"); add_verb("score","do_score"); add_verb("QUIT","do_quit"); add_verb("WHO","do_who"); add_verb("password","do_password"); add_verb("exits","do_exits"); add_verb("wear","do_wear"); add_verb("unwear","do_unwear"); } listen(arg) { send_device(arg); if (possessor) call_other(possessor,"possession_report",arg); }