/// <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); }
/// <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() + '.'); } }
/// <summary> /// Has the <see cref="Actor"/> try to open /// a given <see cref="Thing"/>. /// </summary> /// <param name="item">the <see cref="Thing"/> to open</param> /// <exception cref="InteractingWithUnseenThingException"> /// if the <see cref="Actor"/> cannot see the <see cref="Thing"/> /// </exception> /// <exception cref="OpeningSomethingBesidesOpenableException"> /// if the <see cref="Thing"/> is not <see cref="Openable"/> /// </exception> public void Open(Thing item) { // if the item is not visible, throw an exception if (!GameManager.CanSee(this, item)) { throw new InteractingWithUnseenThingException(); } // if the item is not openable, throw an exception else if (!typeof(Openable).IsAssignableFrom(item.GetType())) { throw new OpeningSomethingBesidesOpenableException(); } // the item is visible and openable; execute as normal else { // TODO: Make sure the item being opened isn't someone else's clothing. ((Openable)item).Open(); GameManager.ReportIfVisible(this, this.GetSpecificName() + ' ' + this.GetConjugatedVerb(VerbSet.ToOpen) + ' ' + item.GetSpecificName() + '.'); } }
/// <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() + '.'); } }
//===================================================================// // 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() + '.'); }
//===================================================================// // 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() + '.'); } }