/** * This is a special type of npc that will move stat points around. * @author Pinkfish * @started Fri May 19 22:56:20 PDT 2000 */ inherit NPC_OBJ; #include <money.h> #include <position.h> #define RETRO_PROP "retrophrenologist" #define RETRO_TIME_PROP "last retrophrenologist" #define RETRO_INITIAL_STATE 1 #define RETRO_DECREASE_STATE 2 #define RETRO_INCREASE_STATE 3 #define RETRO_CHECK_COST_STATE 4 #define RETRO_DO_PROCEDURE_STATE 5 #define RETRO_COST_PER_POINT 40000 // 6 weeks... #define RETRO_TIME_BETWEEN_SESSIONS (6 * 7 * 24 * 60 * 60) private object _busy_with; private int _last_comment; private int _state; private string _decrease_stat; private string _increase_stat; void do_modify(object player); void do_set_stat(object player, string stat); void do_strength(object player); void do_intelligence(object player); void do_wisdom(object player); void do_dexterity(object player); void do_consitution(object player); void do_yes(object player); void do_no(object player); void create() { _state = RETRO_INITIAL_STATE; ::create(); } /* create() */ void setup_responses() { add_respond_to_with(({ "@say", "modify", "stats" }), (: do_modify :)); add_respond_to_with(({ "@say", ({ "strength", "str"}) }), "#do_set_stat" ); add_respond_to_with(({ "@say", ({ "intelligence", "int" }) }), "#do_set_stat" ); add_respond_to_with(({ "@say", ({ "wisdom", "wis" }) }), "#do_set_stat" ); add_respond_to_with(({ "@say", ({ "dexterity", "dex" }) }), "#do_set_stat" ); add_respond_to_with(({ "@say", ({ "constitution", "con" }) }), "#do_set_stat" ); add_respond_to_with(({ "@say", "yes" }), (: do_yes :)); add_respond_to_with(({ "@nod", query_name() }), (: do_yes :)); add_respond_to_with(({ "@say", "no" }), (: do_no :)); add_respond_to_with(({ "@shake", query_name() }), (: do_no :)); } /* setup_responses() */ /** * This method returns the cost of getting your head smashed. * @return the cost of getting your head smashed */ int query_cost_of_smashing(object player) { int ret; ret = player->query_property(RETRO_PROP); return (ret + 1) * RETRO_COST_PER_POINT; } /* query_cost_of_smashing() */ /** * This method returns the longer name of the short stat. * @param name the short stat name * @return the long stat name */ string query_stat_name(string name) { switch (name) { case "str" : return "brawn"; case "con" : return "vigour"; case "dex" : return "flexibility"; case "int" : return "intellect"; case "wis" : return "intuition"; default : return "stone the crows"; } } /* query_stat_name() */ /** * This method is called to set the stat when in the correct states. * @param stat the stat to change * @return 1 if successful, 0 if not */ int set_modify_stat(string stat) { string place; int cost; switch (_state) { case RETRO_DECREASE_STATE : _decrease_stat = stat; if (call_other(_busy_with, "query_real_" + stat) <= 8) { do_command("sayto " + _busy_with->query_name() + " Sorry, but your " + query_stat_name(stat) + " is too low already!"); _busy_with = 0; return 0; } _state = RETRO_INCREASE_STATE; do_command("sayto " + _busy_with->query_name() + " Whooo! Great, so what ability would you like to " "increase?"); break; case RETRO_INCREASE_STATE : _increase_stat = stat; if (call_other(_busy_with, "query_real_" + stat) >= 23) { do_command("sayto " + _busy_with->query_name() + " Sorry, but your " + query_stat_name(stat) + " is far too high!"); _busy_with = 0; return 0; } if (_increase_stat == _decrease_stat) { do_command("sayto " + _busy_with->query_name() + " Increasing the same thing your decreasing? Even " "the bumps on your head are not that confused."); _busy_with = 0; return 0; } cost = query_cost_of_smashing(_busy_with); place = query_property("place"); if (!place) { place = "default"; } _state = RETRO_CHECK_COST_STATE; do_command("emote feels the bumps on " + _busy_with->poss_short() + " head speculatively."); do_command("sayto " + _busy_with->query_name() + " It will cost you " + MONEY_HAND->money_value_string(cost, place) + " to smash your head into the shape required to increase your " + query_stat_name(_increase_stat) + " at the detriment to your " + query_stat_name(_decrease_stat) + "." /*It may cause a small " "amount of incapacitance in some subjects and it may take you " "a while to totally restore your faculties. A few of my " "patients have been complete butterfingers after their " "treatment but they recovered nicely. It's a perfectly safe " "procedure however!"*/); do_command("sayto " + _busy_with->query_name() + " Do you wish to continue?"); break; } return 1; } /* set_modify_stat() */ /** * This method returns if the npc is busy or not without printing * anything. * @return 1 if busy, 0 if not */ int is_busy(object player) { if (_state == RETRO_DO_PROCEDURE_STATE) { return 1; } if (_busy_with && _busy_with != player && environment(_busy_with) == environment() && time() - _last_comment < 5 * 60) { return 1; } return 0; } /* is_busy() */ /** * This method checks to see if they are in the initial state. * @return 1 if initial state, 0 if not */ int is_initial_state() { if (_state == RETRO_INITIAL_STATE) { return 1; } return 0; } /* is_initial_state() */ /** * This method checks to see if the npc is busy with someone else. * It prints an error message if they are busy. * @param player the person to check * @return 1 if they are busy */ int check_busy_with(object player) { if (is_busy(player)) { if (_state == RETRO_DO_PROCEDURE_STATE) { do_command("sayto " + player->query_name() + " This is a delicate procedure, please do not interrupt."); return 1; } do_command("sayto " + player->query_name() + " Can't you see I am busy with " + _busy_with->the_short() + "?"); do_command("sayto " + player->query_name() + " Talk to me after I have finished with " + _busy_with->query_objective() + "."); return 1; } if (_busy_with != player) { _state = RETRO_INITIAL_STATE; } _busy_with = player; _last_comment = time(); return 0; } /* check_busy_with() */ /** @ignore yes */ void do_modify(object player) { if (check_busy_with(player)) { return ; } if (_state != RETRO_INITIAL_STATE && _state != RETRO_DECREASE_STATE) { do_command("sayto " + _busy_with->query_name() + " I am confused. You are not answering my questions properly!"); do_command("signore " + _busy_with->query_name()); _busy_with = 0; return ; } // Remove this if statment after PT, is here just to fix a typo in the property if (player->query_property("last retrophenologist")) { player->add_property(RETRO_TIME_PROP, player->query_property("last retrophenologist")); player->remove_property("last retrophenologist"); } // endif if (player->query_property(RETRO_TIME_PROP) + RETRO_TIME_BETWEEN_SESSIONS > time()) { do_command("emote feels " + player->poss_short() + " head and " "makes 'tch'ing noises."); do_command("sayto " + player->query_name() + " Your bumps have not yet settled back down to a uniform " "feeling of oneness. Come back again soon."); _busy_with = 0; return ; } do_command("sayto " + _busy_with->query_name() + " So you would like to get some stats modified... Which one " "would you like decreased?"); _state = RETRO_DECREASE_STATE; } /* do_modify() */ /** @ignore yes */ void do_set_stat(object player, string stat) { stat = stat[0..2]; // Get the required three letter stat if (_state == RETRO_INITIAL_STATE) { return ; } if (check_busy_with(player)) { return ; } if (_state != RETRO_DECREASE_STATE && _state != RETRO_INCREASE_STATE) { do_command("sayto " + _busy_with->query_name() + " I am confused. You are not answering my questions properly!"); do_command("signore " + _busy_with->query_name()); _busy_with = 0; return ; } if (!set_modify_stat(stat)) { return ; } } /* do_set_stat() */ /** @ignore yes */ void do_no(object player) { if (_state == RETRO_INITIAL_STATE) { return ; } if (check_busy_with(player)) { return ; } if (_state == RETRO_DECREASE_STATE) { do_command("boggle gently at " + _busy_with->query_name()); do_command("sayto " + _busy_with->query_name() + " No? Nose? You want me do decrease your nose? Now now. " "What stat did you want to decrease?"); return; } if (_state == RETRO_INCREASE_STATE) { do_command("sayto " + _busy_with->query_name() + " No? Know? How should I know what you want? Now tell me " "what stat did you want to increase?"); return; } if (_state != RETRO_CHECK_COST_STATE) { do_command("frown in bewilderment"); do_command("sayto " + _busy_with->query_name() + " No? Where does the no come from?"); _busy_with = 0; return ; } do_command("sayto " + _busy_with->query_name() + " Ok, well thanks for the business. Come back when you have " "changed your mind."); _busy_with = 0; } /* do_no() */ /** @ignore yes */ void do_yes(object player) { int cost; string place; if (_state == RETRO_INITIAL_STATE) { return ; } if (check_busy_with(player)) { return ; } if (_state == RETRO_DECREASE_STATE) { do_command("emote looks up from a dented hammer"); do_command("sayto " + _busy_with->query_name() + " Yes? Yes?! Eh What? What stat did you want to decrease?"); return; } if (_state == RETRO_INCREASE_STATE) { do_command("blink in confusion"); do_command("sayto " + _busy_with->query_name() + " Yes? Yes what? You want to increase your Yes stat? Be " "serious now, what stat did you want to increase?"); return; } if (_state != RETRO_CHECK_COST_STATE) { do_command("sayto " + _busy_with->query_name() + " Yes yes yes. No..\n"); _busy_with = 0; return ; } do_command("sayto " + _busy_with->query_name() + " Great! I will see what I can do."); cost = query_cost_of_smashing(player); place = query_property("place"); if (!place) { place = "default"; } if (player->query_value_in(place) < cost) { do_command("nudge " + _busy_with->query_name()); do_command("sayto " + _busy_with->query_name() + " Umm, sorry to bring this up. But you do not have " + MONEY_HAND->money_value_string(cost, place) + "."); do_command("sayto " + _busy_with->query_name() + " Do come back when you are a little richer."); _busy_with = 0; return ; } player->pay_money(MONEY_HAND->create_money_array(cost, place)); _state = RETRO_DO_PROCEDURE_STATE; do_command("emote pockets the money as payment from " + _busy_with->the_short() + "."); do_command("emote feels around on " + _busy_with->poss_short() + " head."); call_out("do_next_stage", 2); } /* do_no() */ /** @ignore yes */ void do_next_stage(int stage) { object *obs; if (!_busy_with) { do_command("'Whoops! They left."); _state = RETRO_INITIAL_STATE; return ; } if (environment(_busy_with) != environment()) { do_command("tell " + _busy_with->query_name() + " I cannot complete this procedure if you walk off."); do_command("tell " + _busy_with->query_name() + " There is a no money back policy."); _busy_with = 0; _state = RETRO_INITIAL_STATE; return ; } switch (stage) { case 0 : // // If there is a chair here, sit them in it. // obs = match_objects_for_existence("chairs", ({ environment() })); SITTING_CMD->position_object(obs, "on", _busy_with); do_command("emote starts to strap " + _busy_with->the_short() + " into the chair."); break; case 1 : do_command("emote measures " + _busy_with->poss_short() + " head with a somewhat battered looking tape measure."); break; case 2 : do_command("emote pulls out a huge hammer and licks " + query_possessive() + " lips."); break; case 3 : do_command("emote squints and lines the hammer up."); break; case 4 : do_command("'Don't worry. You won't feel a thing!"); break; case 5 : do_command("emote thumps the hammer down hard on " + _busy_with->poss_short() + " head, blood and bits of " "hair spray around the room."); tell_object(player, "You feel immediately loose consciousness and feel " "pretty messed up.\n"); _busy_with->add_property(RETRO_TIME_PROP, time()); _busy_with->add_property(RETRO_PROP, _busy_with->query_property(RETRO_PROP) + 1); _busy_with->add_effect("/std/effects/other/out_cold", 360); call_other(_busy_with, "adjust_" + _increase_stat, 1); call_other(_busy_with, "adjust_" + _decrease_stat, -1); _busy_with->adjust_tmp_con( (_busy_with->query_con() - 8) < 0 ? _busy_with->query_con() : -8); _busy_with->adjust_tmp_str( (_busy_with->query_str() - 8) < 0 ? _busy_with->query_str() : -8); _busy_with->adjust_tmp_dex( (_busy_with->query_dex() - 8) < 0 ? _busy_with->query_dex() : -8); _busy_with->adjust_tmp_wis( (_busy_with->query_wis() - 8) < 0 ? _busy_with->query_wis() : -8); _busy_with->adjust_tmp_int( (_busy_with->query_int() - 8) < 0 ? _busy_with->query_int() : -8); break; case 6 : do_command("emote looks a little worried and checks " + _busy_with->poss_short() + " pulse, then smiles " "brightly."); break; case 7 : do_command("emote cleans off " + query_possessive() + " hammer and smiles happily."); break; case 8 : do_command("'Another job well done."); break; case 9 : do_command("emote rubs " + _busy_with->poss_short() + " head " "and smiles."); break; case 10 : do_command("sayto " + _busy_with->query_name() + " I think you will find that did the trick."); break; case 11 : do_command("emote pushes " + _busy_with->poss_short() + " unconscious body off the chair onto the floor."); do_command("say Next please!"); LYING_CMD->position_floor(_busy_with, 1); _state = RETRO_INITIAL_STATE; _busy_with = 0; return ; } call_out("do_next_stage", 4, stage + 1); } /* do_next_stage() */