void heart_beat() { int wimpy_ratio, cnd_flag; mapping my; object ob; my = query_entire_dbase(); // If we are dying because of mortal wounds? if( my["eff_kee"] < 0 || my["eff_sen"] < 0 || my["eff_gin"] < 0) { remove_all_enemy(); die(); return; } // If we're dying or falling unconcious? if( my["kee"] < 0 || my["sen"] < 0 || my["gin"] < 0) { remove_all_enemy(); if( !living(this_object()) ) die(); else unconcious(); return; } // Do attack if we are fighting. if( is_busy() ) { continue_action(); // We don't want heart beat be halt eventually, so return here. return; } else { // Is it time to flee? if( is_fighting() && intp(wimpy_ratio = (int)query("env/wimpy")) && wimpy_ratio > 0 && ( my["kee"] * 100 / my["max_kee"] <= wimpy_ratio || my["sen"] * 100 / my["max_sen"] <= wimpy_ratio || my["gin"] * 100 / my["max_gin"] <= wimpy_ratio) ) GO_CMD->do_flee(this_object()); // Do attack or clean up enemy if we have fleed. attack(); } if( !userp(this_object()) ) { this_object()->chat(); // chat() may do anything -- include destruct(this_object()) if( !this_object() ) return; } if( tick-- ) return; else tick = 5 + random(10); cnd_flag = update_condition(); // If we are compeletely in peace, turn off heart beat. // heal_up() must be called prior to other two to make sure it is called // because the && operator is lazy :P if( ((cnd_flag & CND_NO_HEAL_UP) || !heal_up()) && !is_fighting() && !interactive(this_object())) { if( environment() ) { ob = first_inventory(environment()); while(ob && !interactive(ob)) ob = next_inventory(ob); } if( !ob ) set_heart_beat(0); } if( !interactive(this_object()) ) return; // Make us a bit older. Only player's update_age is defined. // Note: update_age() is no need to be called every heart_beat, it // remember how much time has passed since last call. this_object()->update_age(); if(query_idle(this_object()) > IDLE_TIMEOUT) this_object()->user_dump(DUMP_IDLE); }
void heart_beat() { int wimpy_ratio, to_wimpy, cnd_flag, oldbusy; mapping my; object ob; string savemyass; if(!this_object()) { return; } // command("say start heart_beat"); // command("say i am busy"+(string)query_busy()); if (query_temp("in_heart_beat")) return; my = query_entire_dbase(); // If we are dying because of mortal wounds? if( my["eff_kee"] < 0 || my["eff_sen"] < 0 || my["eff_gin"] < 0 || my["kee"] < -2 * my["dur"] || my["sen"] < -2 * my["dur"] || my["gin"] < -2 * my["dur"]) { remove_all_enemy(); die(); return; } // If we are unconcious, just return; if(query_temp("is_unconcious")) { return; } // If we're dying or falling unconcious? if( my["kee"] < 0 || my["sen"] < 0 || my["gin"] < 0) { remove_all_enemy(); unconcious(); return; } // let NPC do something in fight that won't be affected by busy...e.g talk // all actions in nb_chat will be executed in fight. They should never have busy() // as a consequence and they should be allowed to appear at same time. if (is_fighting()) if(objectp(this_object()) && !userp(this_object())) { this_object()->nb_chat(); if(!this_object()) { return; } } if (!is_busy()) { // (1) Do attack or clean up enemy if we have fleed. if(is_fighting()) { // Hey, NPC's 心神 doesn't need to be reduced here, let's save some resource // my["sen"]--; attack(); } // (2) chat() may do anything -- include destruct(this_object()) if(objectp(this_object()) && !userp(this_object())) { this_object()->chat(); if(!this_object()) { return; } } } // If busy, continue action and return here. if(is_busy()) { continue_action(); return; } if(tick--) { return; } else { tick = 5 + random(10); } cnd_flag = update_condition(); if (!living(this_object())) return; // If we are compeletely in peace, turn off heart beat. // heal_up() must be called prior to other two to make sure it is called // because the && operator is lazy :P if( ((cnd_flag & CND_NO_HEAL_UP) || !heal_up()) && !is_fighting() && !interactive(this_object())) { if(environment()) { ob = first_inventory(environment()); while(ob && !interactive(ob)) { ob = next_inventory(ob); } } if(!ob && !query("ALWAYS_ACTIVE")) set_heart_beat(0); } if(!this_object()) return; if(!interactive(this_object())) return; }