Author Topic: DeadSouls 2.1 Ranged Weapon Inherit  (Read 1837 times)

Offline tigwyk

  • Acquaintance
  • *
  • Posts: 45
    • View Profile
DeadSouls 2.1 Ranged Weapon Inherit
« on: September 22, 2006, 08:54:53 AM »
Mudlib: DeadSouls 2.1 on Windows Server 2003

Driver: MudOS v22.2b14

Filename: ranged.c



Hi all,



I decided to make a ranged weapon inherit based off Crat's pistol inherit. The pistols were cool, but I wanted a generic ranged weapon inherit so I could make assault rifles, etc. I originally wanted to make a nailgun (specifically the 10mm HV Penetrator from F.E.A.R.) and that's what inspired me to create a generic ranged weapon inherit. Credit goes to Cratylus for the original pistol.c, I only edited it a bit, adding different functionality, as well as cleaning up and optimizing some code. One caveat is that I added functionality to combat.c for ranged weapons, too. Without that, this is just a thing that causes damage to an opponent, I recommend adding ranged functionality to combat.c if you're actually going to implement ranged weapons.





Here it is: ranged.c

LPC code:

/* Originally created as pistol.c by Cratylus @ Dead Souls Demo
 * Edited and enhanced (haha) by Tigwyk @ LP Heroes (Some time in 2006, probably August)
 *
 * New functions include an ability to specify NO shells drop after firing,
 * as well as using GetName() to show the name of the weapon in returns instead
 * of just "pistol" or a static string.
 *
 */


#include "include/ranged.h"
#include <lib.h>
#include <damage_types.h>
#include <dirs.h>
inherit LIB_STORAGE;
inherit LIB_WEAPON;
inherit LIB_SHOOT;

private int MaxAmmo, Millimeter, AmmoSize;
private string PistolType, AmmoType;
private string AmmoFile;
private float Caliber;
private string *namen;
private string *ammonamen;
private string ammoname;
private int loaded, rounds;
private int shells, NoShells;
private int mag,cloned;
private int autohit;
private int dam;

static void create(){
    string *s_save, *w_save, *a_save;

    ::create();

    s_save = storage::GetSave();
    w_save = weapon::GetSave();
    a_save = s_save + w_save;

    AddSave( a_save );
    AddSave( ({ "loaded", "rounds", "shells" , "mag" , "cloned" }) );
    MaxAmmo=6;
    AmmoFile="/domains/town/obj/round";
    PistolType="revolver";
    AmmoType="round";
    ammoname="round";
    loaded=1;
    rounds=0;
    SetWeaponType("ranged");
}
void init(){
    object ob;
    object *inv;
    add_action("startLoad","load");
    add_action("startUnload","unload");
    this_object()->CalculateAmmoSize();
    add_action("checkAmmo", "ammo");
    namen=this_object()->GetId();
    if(PistolType=="revolver"
      && !present("cylinder",this_object())){
   new("/lib/cylinder")->eventMove(this_object());
    }
    if(PistolType=="revolver" && !cloned){
   cloned=1;
   ob=present("cylinder", this_object());
   inv=all_inventory(ob);
   filter(inv, (: this_object()->InitRevolver($1->GetId()) :) );
    }
    if(PistolType=="auto" && !present("clip",this_object()) ) {
   mag=0;
   loaded=0;
   rounds=0;
    }
}
int InitRevolver(string *arr){
    if(member_array("round",arr) != -1){
   rounds++;
   return 1;
    }
    if(member_array("shell",arr) != -1){
   shells++;
   return 1;
    }
}
mixed CanGetFrom(object who, object item) {
    return "It doesn't work that way. Try unloading it.";
}

mixed CanPutInto(object who, object what) {
    return "It doesn't work that way. Try loading the "+GetName()+" with something.";
}

int eventStrike(object ob){
   return weapon::eventStrike(ob);
   }

int CanReceive(object ob){
    string *idarray;
    if(PistolType=="revolver"){
   idarray=ob->GetId();
   if(member_array("round",idarray) != -1){
       write("Try: load <ranged weapon> with <ammo>.");
       return 0;
   }
    }
    if(PistolType != "auto" && ob->GetKeyName() != "revolver cylinder"){
   write("The "+GetName()+" only receives bullets.");
   return 0;
    }
    idarray=ob->GetId();
    if(PistolType=="auto" && member_array("magazine",idarray) == -1){
   write("The "+GetName()+" only receives ammunition clips.");
   return 0;
    }
    if(PistolType=="auto" && ob->GetMillimeter() != this_object()->GetMillimeter() ){
   write("That is not the correct ammunition clip size.");
   return 0;
    }
    if(PistolType=="auto" && ob->GetCaliber() != this_object()->GetCaliber() ){
   write("That is not the correct ammunition clip caliber.");
   return 0;
    }
    if(PistolType=="auto" && ob->GetAmmoType() != this_object()->GetAmmoType() ){
   write("That is not the correct ammunition clip type.");
   return 0;
    }
    if(PistolType=="auto" && mag){
   write("The "+GetName()+" is already loaded.");
   return 0;
    }
    if(PistolType=="auto"){
   mag=1;
   rounds=sizeof(all_inventory(ob));
    }
    return 1;
}
int CanRelease(object ob){
    if(ob->GetKeyName()=="revolver cylinder"){
   write("The cylinder is not a removable part of the pistol.");
   return 0;
    }
    return 1;
}

int eventShoot(object ob, string str){
    object *wielded;
    wielded = environment(this_object())->GetWielded();
    if(!rounds || rounds == 0){
   write("Your weapon is not loaded.\n");
   say(environment(this_object())->GetName()+" tries to shoot "+capitalize(str)+" with an unloaded weapon.\n");
   return 1;
    }
    if(member_array(this_object(), wielded) == -1){
       write("You aren't wielding your "+GetName()+".");
       return 1;
    }
    write("You shoot at "+capitalize(str)+"!\n");
    say(environment(this_object())->GetName()+" shoots at "+capitalize(str)+"!\n");
    tell_object(present(str,environment(environment(this_object()))), environment(this_object())->GetName()+
      " shoots at you with "+possessive(this_object()->GetGender())+" "+GetName()+"!\n");
    this_object()->eventFire(str);
    if((PistolType=="auto") && (!GetNoShells())) new("/lib/shell")->eventMove(environment(environment(this_object())));
    return 1;
}

int eventFire(string str){
    object ob;
    int tempclass, i, dex;
    int TorsoNum, NumLimbs;
    mixed dexmap;
    string tempshort,templong;
    string *limbarr;
    int limbhit;
    string limbname;
    string s1,s2;
    rounds--;
    if(this_object()->GetPistolType() == "auto"){
   if(first_inventory(present("magazine",this_object())) ){
       first_inventory(present("magazine",this_object()))->eventDestruct();
       present("magazine",this_object())->MinusAmmo(1);
   }
   else rounds=0;
    }
    if(this_object()->GetPistolType() == "revolver"){
   shells++;
   ob=present("cylinder",this_object());
   present("round",ob)->eventDestruct();
   new("/lib/shell")->eventMove(ob);
    }
    if(rounds <= 0) loaded=0;
    ob=present(str,environment(environment(this_object())));
    if(creatorp(ob)){
   write(ob->GetName()+" catches the "+ammoname+" in "+possessive(ob)+" teeth.\n");
   say(ob->GetName()+" catches the "+ammoname+" in "+possessive(ob)+" teeth.\n");
   autohit=0;
   return 1;
    }
    if(!living(ob)){
   if(!sscanf(ob->GetLong(),"%sIt has been damaged by gun%s",s1,s2)){
       tempclass=ob->GetClass();
       if(tempclass) ob->SetClass(tempclass/2);
       tempshort=ob->GetShort();
       tempshort = "A damaged "+remove_article(tempshort);
       ob->SetShort(tempshort);
       templong=ob->GetLong();
       if(sscanf(templong,"%s\n\n%s",s1,s2) >=1){
      templong=s1+" It has been damaged by gunfire.\n\n";
       }
       else
      templong += " It has been damaged by gunfire.";
       ob->SetLong(templong);
       tell_room(environment(environment(this_object())),"The "+ammoname+" smashes into "+lower_case(ob->GetShort())+"!\n");
       return 1;
   }
   tell_room(environment(environment(this_object())),"The "+ammoname+" smashes into "+lower_case(ob->GetShort())+"!\n");
   tempclass=ob->GetClass();
   if(tempclass) ob->SetClass(tempclass/2);
   return 1;
    }
    i = random(100);
    if(!creatorp(environment())){
   dexmap=environment(this_object())->GetStat("coordination");
   dex=dexmap["level"];
    }
    else dex = 200;
    if(i < dex || autohit==1){
   NumLimbs=sizeof(ob->GetLimbs());
   TorsoNum=member_array("torso",ob->GetLimbs());
   i=random(100);
   if(i < 50) limbhit=TorsoNum;
   else limbhit=random(NumLimbs);
   limbarr=ob->GetLimbs();
   limbname=limbarr[limbhit];
   tell_room(environment(environment(this_object())),"The "+ammoname+" smashes into "+
     capitalize(str)+"'s "+limbname+"!\n",ob);
   tell_object(ob,"The "+ammoname+" smashes into your "+limbname+"!\n");
   ob->AddLead("gunshot_wounds", 1);
   ob->SetAttack(this_agent());
   if(!present("firearms_wound",ob)){
       new("/domains/town/obj/wound")->eventMove(ob);
   }
   if(Caliber) dam = to_int(Caliber/6);
   if(Millimeter) dam = Millimeter;
   if(!dam) dam = 7;
   dam *= random(10);
   dam += random(environment(this_object())->GetStatLevel("coordination"));
   dam += environment(this_object())->GetSkillLevel("projectile attack");
   if(creatorp(this_player())) write("[You do "+dam+" points of damage!]");

   ob->eventReceiveDamage(environment(this_object()),BLUNT, dam, 1, limbname);
   if(!ob->GetInCombat()){
       ob->eventForce("attack "+environment(this_object())->GetKeyName());
   }
   autohit=0;
   return 1;
    }
    write("Your shot misses its mark.\n");
    say(environment(this_object())->GetName()+"'s shot misses its mark.\n");
    this_object()->missed_shot();
    return 1;
}
int missed_shot(){
    object ob,maghere,magstuff;
    string str;
    int i;
    object *inv;
    string *arr;
    if(environment(environment(this_object()))->GetClimate() != "indoors"){
   return 1;
    }
    inv=all_inventory(environment(environment(this_object())));
    i=random(sizeof(inv));
    if(living(inv)){
   tell_room(environment(environment(this_object())), inv->GetName()+" is struck "+
     "by the stray "+ammoname+"!",inv);
   tell_object(inv,"You are struck by a stray "+ammoname+" from "+environment(this_object())->GetName()+
     "'s gun.\n");
    }
    if(!living(inv)){
   arr=explode(inv->GetKeyName(),"");
   if(arr[sizeof(arr)-1] =="s"){
       tell_room(environment(environment(this_object())),capitalize(inv->GetShort())+" are struck by the stray "+ammoname+".");
   }
   else
       tell_room(environment(environment(this_object())),capitalize(inv->GetShort())+" is struck by the stray round.");
    }
    autohit=1;
    rounds++;
    this_object()->eventFire(inv->GetKeyName());
    if(this_object()->GetPistolType() == "revolver"){
   shells--;
   present("shell",present("cylinder",this_object()))->eventDestruct();
   ob=new("/lib/round");
   ob->SetCaliber(this_object()->GetCaliber());
   ob->SetMillimeter(this_object()->GetMillimeter());
   ob->SetPistolType(this_object()->GetPistolType());
   ob->SetAmmoType(this_object()->GetAmmoType());
   ob->eventMove(present("cylinder",this_object()));
    }
    else
    {
   str = "";
   maghere=present("magazine",this_object());
   if(maghere) magstuff = first_inventory(maghere);
   if(maghere && magstuff) str=base_name(magstuff);
   if(str && str !="" )   new(str)->eventMove(maghere);
    }
    return 1;
}
int CalculateAmmoSize(){
    float i;
    i=this_object()->GetCaliber();
    if(i > 0){
   if(stringp(i)) sscanf(i,"%d",i);
   if(intp(i)) to_float(i);
   while(i > 1.0){
       i = i*(0.1);
   }
   i = i*(25.4);
   AmmoSize=to_int(i);
   dam=AmmoSize*(AmmoSize);
   dam *= 3;
   return 1;
    }
    AmmoSize=this_object()->GetMillimeter();
    return 1;
}
int ShowRounds() { environment(this_object())->eventPrint(GetName()+" has: "+rounds+" rounds.\n");
    environment(this_object())->eventPrint(GetName()+" has: "+shells+" shells.\n");
    return 1;
}
int SetAmmo(int i) { return (rounds = i); }
int GetAmmo() { return rounds; }
int GetMag() { return mag; }
int SetMag(int i) { return (mag = i); }
int SetLoaded(int i) { return (loaded = i); }
int GetLoaded() { return loaded; }
int SetAmmoFile(string str) { AmmoFile=str; return 1; }
int SetAmmoType(string str) { AmmoType=str; return 1; }
int SetPistolType(string str) { PistolType=str; return 1; }
int SetMaxAmmo(int x) { MaxAmmo=x; return 1; }
int SetCaliber(int x) { Caliber=x; return 1; }
int SetMillimeter(int x) { Millimeter=x; return 1; }
string GetAmmoType() { return AmmoType; }
string GetPistolType() { return PistolType; }
int GetMaxAmmo() { return MaxAmmo; }
int GetCaliber() { return Caliber; }
int GetMillimeter() { return Millimeter; }
int SetNoShells(int i) { return (NoShells = i);}
int GetNoShells() { return NoShells; }

int checkAmmo(){
   write("The "+GetName()+" has "+GetAmmo()+" rounds left.");
   return 1;
}

int startLoad(string str){
    string s1,s2;
    if(!str || str== "") return 0;
    if(member_array(str, namen) != -1){
   write("Load your "+GetName()+" with what?");
   return 1;
    }
    if(sscanf(str,"%s with %s",s1,s2) >= 1){
   if(!present(s1,environment(this_object()))){
       write("You have no such thing to load.\n");
       return 1;
   }
   if(member_array(s1,namen) == -1){
       present(s1, environment(this_object()))->startLoad(str);
       return 1;
   }
   if(PistolType=="revolver"){
       this_object()->LoadRevolver(s2);
       return 1;
   }
   if(PistolType=="auto"){
       this_object()->LoadAuto(s2);
       return 1;
   }
   write("Your "+GetName()+" seems not to be loadable.\n");
   return 1;
    }
    if(member_array(s1,namen) != -1){
   write("Load it with what?\n");
   return 1;
    }
}
int LoadAuto(string str){
    object ob;
    string junk;
    ob=present(str,environment(this_object()));
    if(!ob){
   write("You have no such thing to load your "+GetName()+" with.");
   return 1;
    }
    if(ob->eventMove(this_object())){
    write("You load your "+GetName()+" with "+ob->GetShort()+".");
    //write("[Debug] "+first_inventory(ob)->GetKeyName());
    ammoname = first_inventory(ob)->GetKeyName();
    say(environment(this_object())->GetName()+" loads "+ob->GetShort()+" into "+
      possessive(environment(this_object()))+" "+GetName()+".");
    }
    if(!sizeof(deep_inventory(present("magazine",this_object())))) return 0;
    if(!AmmoFile=file_name(first_inventory(present("magazine",this_object()))) ) {
   AmmoFile="/lib/round";
}
    else sscanf(AmmoFile,"%s#%s",AmmoFile,junk);
    return 1;
}
int LoadRevolver(string str){
    object ob;
    ob=present(str,environment(this_object()));
    if(!ob){
   write("You do not have that to load with.\n");
   return 1;
    }
    ammonamen=ob->GetId();
    if(member_array("bullet",ammonamen) == -1){
   write("That is not something you can load your "+GetName()+" with.\n");
   return 1;
    }
    if(ob->GetPistolType() != "revolver"){
   write("That's not revolver ammunition.\n");
   return 1;
    }
    if(ob->GetAmmoType() != this_object()->GetAmmoType()){
   write("That's the incorrect ammunition for this weapon.\n");
   return 1;
    }
    if(rounds + shells == MaxAmmo){
   write("Your "+GetName()+" cannot hold any more "+ammoname+".\n");
   return 1;
    }
    write("You load a round into your "+GetName()+".\n");
    say(environment(this_object())->GetName()+" loads a "+ammoname+" into "+
      possessive(environment(this_object()))+" revolver.");
    rounds++;
    ob->eventMove(present("revolver cylinder",this_object()));
    return 1;
}
int startUnload(string str){
    string n1,s1,s2;
    int n2;
    if(!str || str== "") return 0;
    if(mag==1 && member_array(str,namen) != -1){
   this_object()->doMagUnload();
   return 1;
    }
    if(PistolType=="revolver" && member_array(str,namen) != -1){
   if(rounds == 0 && shells == 0){
       write("Your pistol is already empty.");
       return 1;
   }
   write("You unload your "+GetName()+".");
   this_object()->doRevolverUnload("all","all");
   return 1;
    }
    if(sscanf(str,"%s %s from %s",n1,s1,s2) >=1){
   if(!sscanf(n1,"%d",n2)){
       write("You must specify a number of items to unload.\n");
       return 1;
   }
   if(member_array(s2,namen) == -1){
       if(!present(s2, environment(this_object()))){
      write("You have no such thing to unload.\n");
      return 1;
       }
       present(s2,environment(this_object()))->UnloadRevolver(str);
       return 1;
   }
   if(s1=="shell" || s1=="shells"){
       if(!shells){
      write("There are no shells in the "+GetName()+".\n");
      return 1;
       }
       if(shells < n2){
      write("There aren't that many shells in the "+GetName()+".\n");
      return 1;
       }
       this_object()->doRevolverUnload("shells",n1);
       return 1;
   }
   if(s1=="bullet" || s1=="bullets" || s1=="round"|| s1=="rounds"){
       if(!rounds){
      write("There are no "+ammoname+"s in the "+GetName()+".\n");
      return 1;
       }
       if(rounds < n2){
      write("There aren't that many "+ammoname+"s in the "+GetName()+".\n");
      return 1;
       }
       this_object()->doRevolverUnload("rounds",n1);
       return 1;
   }
    }
}

int doMagUnload(){
    if(!present("clip",this_object())){
   write("The "+GetName()+" is already empty.");
   return 0;
    }
    write("You unload an ammo clip from your "+GetName()+".");
    say(this_player()->GetName()+" unloads an ammo clip from "+possessive(this_player())+" "+GetName()+".");
    present("clip",this_object())->eventMove(environment(this_object()));
    mag=0;
    loaded=0;
    rounds=0;
    return 1;
}

int doRevolverUnload(string what, string num){
    int i,n1,n2;
    if(sscanf(num,"%d",n1)){
    }
    if(what=="all"){
   n1=shells;
   n2=rounds;
    }
    if(what=="shells" || what=="all"){
   i=shells-n1;
   while(shells > i){
       present("shell",present("revolver cylinder",this_object()))->eventMove(environment(this_object()));
       shells--;
   }
    }
    if(what=="rounds" || what=="all"){
   if(what != "all") n2=n1;
   i=rounds-n2;
   while(rounds > i){
       present("round",present("revolver cylinder",this_object()))->eventMove(environment(this_object()));
       rounds--;
   }
    }
    if(n2 > 0) write("You unload "+n2+" rounds from your "+GetName()+".");
    if(n1 > 0) write("You unload "+n1+" shells from your "+GetName()+".");
    say(environment(this_object())->GetName()+" unloads some cartridges from "+
      possessive(environment(this_object()))+" "+GetName()+".");
    return 1;
}