/// <summary> /// Has the <see cref="Actor"/> try to take a <see cref="Thing"/> /// that they can see. /// </summary> /// <param name="item">the <see cref="Thing"/> to take</param> /// <exception cref="TakingItemFlaggedUntakeableException"> /// if the <see cref="Thing"/> has been flagged as untakeable /// </exception> /// <exception cref="TakingThingNotVisibleException"> /// if the <see cref="Actor"/> cannot see the <see cref="Thing"/> /// </exception> public void Take(Thing item) { // if the actor can't see the item, throw an exception if (!GameManager.CanSee(this, item)) { throw new InteractingWithUnseenThingException(); } // if the item can never be taken, throw an exception else if (!item.CanBeTaken()) { throw new TakingItemFlaggedUntakeableException(); } // if the actor is already carrying the item, throw an exception else if (this.Carries(item)) { throw new TakingItemAlreadyHeldException(); } // if the actor is a person who is wearing the item, // throw an exception for now else if (typeof(Person).IsAssignableFrom(this.GetType()) && ((Person)this).Wears(item)) { throw new Exception("Taking off is not coded for yet."); } // if the item is worn by someone else or is inside something // worn by someone else, throw an exception, for now else if (typeof(Clothes) == GameManager.GetTopMostVisibleContainer(item.GetLocation()).GetType()) { throw new Exception("Theft has not been coded yet."); } // The actor can see the item, and it is not being worn or carried. // This is the "happy path." Execute as normal. else { item.GetLocation().RemoveThing(item); item.SetLocation(this.inventory); this.inventory.AddThing(item); GameManager.ReportIfVisible(this, StringManipulator.CapitalizeFirstLetter(this.GetQualifiedName()) + ' ' + VerbSet.GetForm(VerbSet.ToTake, this.pronouns) + ' ' + item.GetSpecificName() + '.'); } }
//===================================================================// // Protected // //===================================================================// /// <summary> /// This method allows the derived class, <see cref="Person"/>, and any /// other derived classes I end up making, to modify their /// <see cref="Inventory"/> via other functions. For example, /// <see cref="Person.TakeOff"/> needs to be able to move an item of /// <see cref="Clothing"/> from a <see cref="Person"/>'s /// <see cref="Clothes"/> to their <see cref="Inventory"/>. /// /// This method is completely unchecked, save for the checks performed /// by any of the functions it calls. /// /// This method does all three parts of moving the item: /// it removes the item from its old location, /// adds the item to the new location, /// and updates the item's location. /// </summary> /// <param name="item"> /// the <see cref="Thing"/> to add to the <see cref="Actor"/>'s /// <see cref="Inventory"/> /// </param> protected void AddToInventory(Thing item) { item.GetLocation().RemoveThing(item); this.inventory.AddThing(item); item.SetLocation(this.inventory); }
/// <summary> /// Has the <see cref="Actor"/> try to drop /// a given <see cref="Thing"/>. /// </summary> /// <param name="item">the <see cref="Thing"/> to drop</param> /// <exception cref="DroppingItemNotHeldException"> /// if the <see cref="Thing"/> is not in the <see cref="Actor"/>'s /// <see cref="Inventory"/> /// </exception> /// <exception cref="DroppingCursedUndroppableItemException"> /// if the <see cref="Thing"/> is cursed/undroppable /// </exception> public void Drop(Thing item) { // if the actor isn't carrying the item, throw an exception if(!this.Carries(item)) { throw new DroppingItemNotHeldException(); } // if the item is cursed/undroppable, throw an exception if(!item.CanBeDropped()) { throw new DroppingCursedUndroppableItemException(); } // actor is carrying the item and it is not cursed else { this.inventory.RemoveThing(item); item.SetLocation(this.GetLocation()); this.GetLocation().AddThing(item); GameManager.ReportIfVisible(this, this.GetName() + ' ' + this.GetConjugatedVerb(VerbSet.ToDrop) + ' ' + item.GetSpecificName() + '.'); } }
/// <summary> /// Has the <see cref="Actor"/> try to put /// a given <see cref="Thing"/> into a given /// <see cref="Container"/>. /// </summary> /// <param name="item">the <see cref="Thing"/> to place</param> /// <param name="container">the <see cref="Container"/> to put it into</param> public void PutInto(Thing item, Thing container) { // if the actor can't see the item, throw an exception if(!GameManager.CanSee(this, item)) { throw new InteractingWithUnseenThingException(); } // if the actor can't see the container, throw an exception if(!GameManager.CanSee(this, container)) { throw new InteractingWithUnseenThingException(); } // if the container is not actually a Container, throw an exception if(!typeof(Container).IsAssignableFrom(container.GetType())) { throw new PuttingIntoNonContainerException(); } // if the item is already in the containter, throw an exception if (item.GetLocation() == container) { throw new PuttingItemAlreadyInsideException(); } // if the item is the container, throw an exception if (item == container) { throw new PuttingItemIntoItselfException(); } // if the actor isn't carrying the item, try taking it instead if(!this.Carries(item)) { // if the actor is the player, report the auto-correction if (GameManager.IsPlayer(this)) { GameManager.ReportIfVisible(this, "((You aren't carrying " + item.GetSpecificName() + ". Trying to take it instead...))"); } this.Take(item); return; } // if the container is closed, try to open it instead if (typeof(OpenableContainer).IsAssignableFrom(container.GetType()) && !((OpenableContainer)container).IsOpen()) { // if the actor is the player, report the auto-correction if (GameManager.IsPlayer(this)) { GameManager.ReportIfVisible(this, "((" + StringManipulator.CapitalizeFirstLetter(container.GetSpecificName()) + " is currently closed. Trying to open it instead..."); } this.Open(container); return; } // TODO: Should actors automatically try to unlock containers? // if nothing went wrong, execute normally item.GetLocation().RemoveThing(item); ((Container)container).AddThing(item); item.SetLocation((Container)container); GameManager.ReportIfVisible(this, VerbSet.ToPut, item, " into ", container); }
//===================================================================// // Actions // //===================================================================// /// <summary> /// Has the <see cref="Person"/> try to wear the given /// <see cref="Thing"/>. /// If the <see cref="Person"/> is not carrying the /// <see cref="Thing"/>, it has them try to take the /// <see cref="Thing"/> instead. /// </summary> /// /// <param name="item">the <see cref="Thing"/> to try wearing</param> /// /// <exception cref="InteractingWithUnseenThingException"> /// if the <see cref="Person"/> can't see the <see cref="Thing"/> /// </exception> /// <exception cref="WearingSomethingAlreadyWornException"> /// if the <see cref="Person"/> is already wearing the /// <see cref="Thing"/> /// </exception> /// <exception cref="WearingSomethingBesidesClothingException"> /// if the <see cref="Thing"/> is not <see cref="Clothing"/> /// </exception> public void Wear(Thing item) { // if the actor can't see the item, throw an exception if (!GameManager.CanSee(this, item)) { throw new InteractingWithUnseenThingException(); } // if the actor is already wearing the item, throw an exception else if (this.Wears(item)) { throw new WearingSomethingAlreadyWornException(); } // if the item isn't actually clothing, throw an exception else if (!typeof(Clothing).IsAssignableFrom(item.GetType())) { throw new WearingSomethingBesidesClothingException(); } // if the actor is not carrying the item, try taking it instead else if (!this.Carries(item)) { if (GameManager.IsPlayer(this)) { GameManager.ReportIfVisible(this, "((You aren't carrying " + item.GetSpecificName() + "; trying to take it instead...))"); this.Take(item); } } // end "if the actor is not carrying the item" // "happy path" else { this.clothes.AddThing(item); item.GetLocation().RemoveThing(item); item.SetLocation(this.clothes); GameManager.ReportIfVisible(this, this.GetSpecificName() + ' ' + this.GetConjugatedVerb(VerbSet.ToPut) + " on " + item.GetSpecificName() + '.'); } }
/// <summary> /// Has the <see cref="Person"/> try to wear the given /// <see cref="Thing"/>. /// If the <see cref="Person"/> is not carrying the /// <see cref="Thing"/>, it has them try to take the /// <see cref="Thing"/> instead. /// </summary> /// /// <param name="item">the <see cref="Thing"/> to try wearing</param> /// /// <exception cref="InteractingWithUnseenThingException"> /// if the <see cref="Person"/> can't see the <see cref="Thing"/> /// </exception> /// <exception cref="WearingSomethingAlreadyWornException"> /// if the <see cref="Person"/> is already wearing the /// <see cref="Thing"/> /// </exception> /// <exception cref="WearingSomethingBesidesClothingException"> /// if the <see cref="Thing"/> is not <see cref="Clothing"/> /// </exception> public void Wear(Thing item) { // if the actor can't see the item, throw an exception if (!GameManager.CanSee(this, item)) { throw new InteractingWithUnseenThingException(); } // if the actor is already wearing the item, throw an exception if (this.Wears(item)) { throw new WearingSomethingAlreadyWornException(); } // if the item isn't actually clothing, throw an exception if (!typeof(Clothing).IsAssignableFrom(item.GetType())) { throw new WearingSomethingBesidesClothingException(); } // if the actor is not carrying the item, try taking it instead if (!this.Carries(item)) { if (GameManager.IsPlayer(this)) { GameManager.ReportIfVisible(this, "((You aren't carrying " + item.GetSpecificName() + "; trying to take it instead...))"); } this.Take(item); return; } // if thr actor is wearing something that can't be worn at the // same time as the item, throw an exception foreach(Clothing wornItem in this.clothes.GetContents()) { if (wornItem.CannotBeWornWith((Clothing)item)) { throw new WearingWithConflictingItemException(wornItem, item); } } // "happy path" this.clothes.AddThing(item); item.GetLocation().RemoveThing(item); item.SetLocation(this.clothes); GameManager.ReportIfVisible(this, this.GetSpecificName() + ' ' + this.GetConjugatedVerb(VerbSet.ToPut) + " on " + item.GetSpecificName() + '.'); }
/// <summary> /// Has the <see cref="Person"/> try to take off the given /// <see cref="Thing"/>. /// </summary> /// <remarks> /// This function makes no attempt to check if the <see cref="Thing"/> /// is actually <see cref="Clothing"/>. There is an unchecked cast to /// to <see cref="Clothing"/>. Given how thoroughly wearing is checked, /// this should never be an issue, but I thought it best to make a note /// of it nonetheless. /// </remarks> /// <param name="item">the <see cref="Thing"/> to try taking off</param> /// <exception cref="RemovingSomethingNotWornException"> /// if the <see cref="Person"/> is not wearing the <see cref="Thing"/> /// </exception> public void TakeOff(Thing item) { // if the person isn't wearing the item, throw an exception if (!this.Wears(item)) { throw new RemovingSomethingNotWornException(); } // if the item is cursed/unremovable, throw an exception if (!((Clothing)item).CanBeRemoved()) { throw new RemovingingCursedUnremovableItemException(); } // if the person doesn't have a free hand, throw an exception if (!this.hands.HasFreeHand()) { throw new RemovingWithHandsFullException(); } // TODO: Add code for taking off other people's clothes? // At the very least, I need some sort of body-looting capability, // though I could always cheat and replace people with containers // on death, with appropriate name and flavor text. // It would also be good to have an armor-removing attempt; // like allowing someone to knock off an opponent's helmet. // However, this would probably be better accomplished // with a different verb. // Theft should also be allowed for things like hats and necklaces, // though this might also be handled better with another verb, // possibly with a redirect from here. // if no exceptions got thrown, remove as normal this.clothes.RemoveThing(item); this.hands.AddThing(item); item.SetLocation(hands); GameManager.ReportIfVisible(this, VerbSet.ToTakeOff, item); }
//===================================================================// // Actions // //===================================================================// /// <summary> /// Has the <see cref="Person"/> try to take a <see cref="Thing"/> /// that they can see. /// </summary> /// /// <param name="item">the <see cref="Thing"/> to take</param> /// /// <exception cref="InteractingWithUnseenThingException"> /// if the <see cref="Person"/> cannot see the <see cref="Thing"/> /// </exception> /// /// <exception cref="TakingItemFlaggedUntakeableException"> /// if the <see cref="Thing"/> has been flagged as untakeable /// </exception> /// /// <exception cref="TakingWithHandsFullException"> /// if the <see cref="Person"/>'s hands are too full /// </exception> public override void Take(Thing item) { // if the person can't see the item, throw an exception if (!GameManager.CanSee(this, item)) { throw new InteractingWithUnseenThingException(); } // if the item can never be taken, throw an exception else if (!item.CanBeTaken()) { throw new TakingItemFlaggedUntakeableException(); } // if the person is already carrying the item, throw an exception else if (this.Carries(item)) { throw new TakingItemAlreadyHeldException(); } // if the personis wearing the item, try taking it off instead else if (this.Wears(item)) { // if the person is the player, report the auto-correction if(GameManager.IsPlayer(this)) { GameManager.ReportIfVisible(this, "((I think you meant \"take off\" instead of " + "\"take.\" Trying that instead...))"); } this.TakeOff(item); } // if the item is worn by someone else or is inside something // worn by someone else, throw an exception, for now else if (typeof(Clothes) == GameManager.GetTopMostVisibleContainer( item.GetLocation()).GetType()) { throw new Exception("Theft has not been coded yet."); } // if neither hand is free or if only one hand is free and the item // requires two hands, throw an exception else if (!hands.HasFreeHand() || (item.IsTwoHanded() && !hands.IsEmpty())) { throw new TakingWithHandsFullException(); } // No problems encountered; execute normally. else { item.GetLocation().RemoveThing(item); this.hands.AddThing(item); item.SetLocation(this.hands); GameManager.ReportIfVisible(this, StringManipulator.CapitalizeFirstLetter( this.GetQualifiedName()) + ' ' + this.GetConjugatedVerb(VerbSet.ToPickUp) + ' ' + item.GetSpecificName() + '.'); } }
/// <summary> /// Has the <see cref="Person"/> try to drop /// a given <see cref="Thing"/>. /// </summary> /// /// <param name="item">the <see cref="Thing"/> to drop</param> /// /// <exception cref="DroppingItemNotHeldException"> /// if the <see cref="Thing"/> is not in the <see cref="Person"/>'s /// <see cref="Hands"/> /// </exception> /// /// <exception cref="DroppingCursedUndroppableItemException"> /// if the <see cref="Thing"/> is cursed/undroppable /// </exception> public override void Drop(Thing item) { // if the actor isn't carrying the item, throw an exception if(!this.Carries(item)) { throw new DroppingItemNotHeldException(); } // if the item is cursed/undroppable, throw an exception if(!item.CanBeDropped()) { throw new DroppingCursedUndroppableItemException(); } // actor is carrying the item and it is not cursed else { this.hands.RemoveThing(item); item.SetLocation(this.GetLocation()); this.GetLocation().AddThing(item); GameManager.ReportIfVisible(this, VerbSet.ToDrop, item); } }