StateResult ActionWield::doPreBeginWorkNVI(GameState& gameState, Systems::Manager& systems, json& arguments) { std::string message; auto subject = getSubject(); auto object = getObject(); auto& components = gameState.components(); auto& narrator = systems.narrator(); /// @todo Support wielding in other prehensile limb(s). This will also include /// shifting an already-wielded weapon to another hand. m_bodyLocation = { BodyPart::Hand, 0 }; EntityId currentlyWielded = components.bodyparts[subject].getWieldedEntity(m_bodyLocation); std::string bodypartDesc = narrator.getBodypartDescription(subject, m_bodyLocation); // If it is us, or it is what is already being wielded, it means to unwield whatever is wielded. if ((object == subject) || (object == currentlyWielded) || (object == EntityId::Void)) { std::unique_ptr<Action> unwieldAction(NEW ActionUnwield(subject)); systems.director().queueEntityAction(subject, std::move(unwieldAction)); return StateResult::Failure(); } else if (currentlyWielded != EntityId::Void) { arguments["bodypart"] = bodypartDesc; putMsg(narrator.makeTr("YOU_MUST_UNWIELD_FIRST", arguments)); return StateResult::Failure(); } return StateResult::Success(); }
StateResult ActionPutInto::doPreBeginWorkNVI(GameState& gameState, Systems::Manager& systems, json& arguments) { std::string message; auto subject = getSubject(); auto object = getObject(); auto container = getTargetThing(); auto& narrator = systems.narrator(); // Verify that the Action has an object. if (object == EntityId::Void) { return StateResult::Failure(); } // Check that the entity and container aren't the same entity. if (object == container) { if (gameState.components().globals.player() == subject) { message = narrator.makeTr("YOU_TRY_TO_STORE_THE_FOO_INSIDE_ITSELF_HUMOROUS", arguments); } else { message = narrator.makeTr("YOU_TRY_TO_STORE_THE_FOO_INSIDE_ITSELF_INVALID", arguments); CLOG(WARNING, "Action") << "NPC tried to store a container in itself!?"; } return StateResult::Failure(); } // Check that the container actually IS a container. if (COMPONENTS.inventory.valueOrDefault(container).maxSize() == 0) { printMessageTry(systems, arguments); putMsg(narrator.makeTr("THE_TARGET_IS_NOT_A_CONTAINER", arguments)); return StateResult::Failure(); } // Check that the entity's location isn't already the container. if (COMPONENTS.position[object].parent() == container) { printMessageTry(systems, arguments); putMsg(narrator.makeTr("THE_FOO_IS_ALREADY_IN_THE_TARGET", arguments)); return StateResult::Failure(); } // Check that the container is within reach. if (!systems.geometry()->firstCanReachSecond(subject, container)) { printMessageTry(systems, arguments); putMsg(narrator.makeTr("THE_TARGET_IS_OUT_OF_REACH", arguments)); return StateResult::Failure(); } return StateResult::Success(); }
StateResult ActionWield::doFinishWorkNVI(GameState& gameState, Systems::Manager& systems, json& arguments) { auto subject = getSubject(); auto object = getObject(); auto& components = gameState.components(); auto& narrator = systems.narrator(); std::string bodypart_desc = narrator.getBodypartDescription(subject, m_bodyLocation); COMPONENTS.bodyparts[subject].wieldEntity(object, m_bodyLocation); arguments["your_bodypart"] = narrator.getPossessiveString(subject, bodypart_desc); putMsg(narrator.makeTr("YOU_ARE_NOW_WIELDING_THE_FOO", arguments)); return StateResult::Success(); }