// Modified by snowman@SJ 22/08/2000.
// 在YuJ增加无食水减jing,qi的基础上，屏蔽对newbie的影响。
// Modified by snowman@SJ 13/04/2001
// heal 中增加对apply/xxx 的支持。

#include <ansi.h>
#include <dbase.h>
#include <login.h>
#include <move.h>

int ghost = 0;

int is_ghost() { return ghost; }

void set_ghost(int i) { ghost=i; }

varargs int receive_damage(string type, int damage, mixed who)
{
	int val;

	if( damage < 0 ) damage = 0;

	if( type!="jing" && type!="qi" && type!="jingli" && type!="neili")
		error("F_DAMAGE: 伤害种类错误。\n");

//added by snowman for some shadow npcs' hit
	if (who) set_temp("last_damage_from", who);
	if( objectp(who) ){
		 if(objectp(who->query("master_user/user")) )
			set_temp("last_damage_from", who->query("master_user/user"));
	}

	val = query(type) - damage;

	if( val < 0 ) val = -1;
	set(type, val);

	set_heart_beat(1);

	return damage;
}

varargs int receive_wound(string type, int damage, mixed who)
{
	int val;

	if (damage < 0) damage = 0;
	if (type!="jing" && type!="qi" && type!="neili")
		error("F_DAMAGE: 伤害种类错误。\n");

//added by snowman for some shadow npcs' hit
	if (who) set_temp("last_damage_from", who);
	if( objectp(who) ){
		 if(objectp(who->query("master_user/user")) )
			set_temp("last_damage_from", who->query("master_user/user"));
	}

	if (type == "neili") val = query("max_" + type) - damage;
	else val = query("eff_" + type) - damage;

	val += query_temp("apply/" + type);
	if (val < 0) val = -1;
	if (val < 0 && type == "neili") val = 0;
	if (query(type) > val && type != "neili") set(type, val);
	val -= query_temp("apply/" + type);

	if (type == "neili") set("max_" + type, val);
	else set("eff_" + type, val);

	set_heart_beat(1);

	return damage;
}

int receive_heal(string type, int heal)
{
	int val;

	if (heal < 0 ) heal = 0;
	if (type!="jing" && type!="qi" && type!="jingli")
		error("F_DAMAGE: 恢复种类错误。\n");

	val = query(type) + heal;
	if (val > query("eff_" + type) + query_temp("apply/" + type))
		val = query("eff_" + type) + query_temp("apply/" + type);

	set(type, val);

	return heal;
}

int receive_curing(string type, int heal)
{
	int max, val;

	if (heal < 0) heal = 0;
	if (type!="jing" && type!="qi")
		error("F_DAMAGE: 恢复种类错误。\n");

	val = query("eff_" + type) + heal;
	max = query("max_" + type);

	if (val > max)
		val = max;
	set( "eff_" + type, val);
	return heal;
}

void unconcious()
{
	object me = this_object(), defeater;
	int i;

	if (!living(me)) return;
	if (wizardp(me) && query("env/immortal")) return;

	if (objectp(defeater = query_temp("last_damage_from")))
		COMBAT_D->winner_reward(defeater, me);

	me->remove_all_enemy();
	set_temp("faint_by", defeater);

	tell_object(me, HIR "\n你只觉得头昏脑胀，眼前一黑，接着什么也不知道了……\n\n" NOR);
	command("hp");
	me->disable_player(" <昏迷不醒>");

	if ((i = query("jing")) < 0) i = 0;
	set("jing", i/2);
	if ((i = query("qi")) < 0) i = 0;
	set("qi", i/2);
	if ((i = query("jingli")) < 0) i = 0;
	set("jingli", i-i/4);
	//added by snowman
	if ((i = query("neili")) < 0) i = 0;
	set("neili", i/2);

	set_temp("block_msg/all", 1);
	COMBAT_D->announce(me, "unconcious");

	call_out("revive", 30 + random(60 - query("con")));
	// grin YUJ@SJ 2001-05-08 06-03
	if (userp(me) && previous_object()) {
		set("no_get", "你刚想动手，对方似乎动了一下。\n");
		set("no_get_from", 1);
	} else if (userp(me)) {
		set("no_get", "对方还没有完全昏迷，等等再背吧。\n");
		call_out("delete", 10, "no_get");
	}
}

varargs void revive(int quiet)
{
	object me = this_object();

	remove_call_out("revive");
	// grin YUJ@SJ 2001-06-03
	if (userp(me)) {
		delete("no_get");
		delete("no_get_from");
	}
	// changed environment(environment()) into environment()->is_character(), by snowman
	while( environment()->is_character() ) me->move(environment(environment()));
	me->enable_player();
	if (!quiet) {
		COMBAT_D->announce(me, "revive");
		delete_temp("block_msg/all");
		tell_object(me, HIY "\n一股暖流发自丹田流向全身，慢慢地你又恢复了知觉……\n\n" NOR);
		command("hp");
		if (query_temp("unconcious") && query_temp("unconcious") != environment()) move(environment(), 1);
		if (environment()) environment()->relay_revive(me);
	} else delete_temp("block_msg/all");
	delete_temp("unconcious");
}

void die()
{
	object corpse;
	object me = this_object();
	mixed killer;

	if (!living(me)) revive(1);
	else delete_temp("faint_by");

	// added by snowman@SJ 27/11/2000
	if( is_ghost() ) return;

	if( wizardp(me) && query("env/immortal") ) return;

	COMBAT_D->announce(me, "dead");
	command("hp");
	if (!(killer = query_temp("last_damage_from")))
		killer = "莫名其妙地";
	if (!environment()->query("no_death")) {
		COMBAT_D->killer_reward(killer, me);

		// Clear all the conditions by death.
		me->clear_condition();
		if( objectp(corpse = CHAR_D->make_corpse(me, killer)) )
			corpse->move(environment());
	} else log_file("no_death", sprintf("%s %O %O\n", ctime(time())[4..<6], me, environment()));
	set_temp("last_damage_from", "莫名其妙地");

	me->remove_all_killer();
	all_inventory(environment())->remove_killer(me);

	me->dismiss_team();
	if (userp(me)) {
		if (me->is_busy()) {
			me->start_busy(1, 2);
			me->interrupt_me();
		}
		set("jing", 1); set("eff_jing", 1);
		set("qi", 1); set("eff_qi", 1);
		if (!environment()->query("no_death")) {
			//ghost = 1;
                    if ( me->query("enter")==10) {
                                     me->save();
                          		   me->move(DEATH_ROOM10);
			                 DEATH_ROOM9->start_death(me);
                                               }
                    if ( me->query("enter")==9) {
                                     me->save();
                          		   me->move(DEATH_ROOM9);
			                 DEATH_ROOM9->start_death(me);
                                               }
                    if ( me->query("enter")==8) {
                                     me->save();
                          		   me->move(DEATH_ROOM8);
			                 DEATH_ROOM8->start_death(me);
                                               }
                    if ( me->query("enter")==7) {
                                     me->save();
                          		   me->move(DEATH_ROOM7);
			                 DEATH_ROOM7->start_death(me);
                                               }
                    if ( me->query("enter")==6) {
                                     me->save();
                          		   me->move(DEATH_ROOM6);
			                 DEATH_ROOM6->start_death(me);
                                               }
                    if ( me->query("enter")==5) {
                                     me->save();
                          		   me->move(DEATH_ROOM5);
			                 DEATH_ROOM5->start_death(me);
                                               }
                    if ( me->query("enter")==4) {
                                     me->save();
                          		   me->move(DEATH_ROOM4);
			                 DEATH_ROOM4->start_death(me);
                                               }                    
                    if ( me->query("enter")==3) {
                                     me->save();
                          		   me->move(DEATH_ROOM3);
			                 DEATH_ROOM3->start_death(me);
                                               }
                    if ( me->query("enter")==2) {
                                     me->save();
                          		   me->move(DEATH_ROOM2);
			                 DEATH_ROOM2->start_death(me);
                                               }
                    if ( me->query("enter")==1) {
                                     me->save();
                          		   me->move(DEATH_ROOM);
			                 DEATH_ROOM->start_death(me);
                                               }
		}
	} else destruct(me);
}

int max_food_capacity() { return query("str")*3+query("con")*7; }

int max_water_capacity() { return query("str")*3+query("con")*7; }

void reincarnate()
{
	ghost = 0;
	set("eff_jing", query("max_jing") + query_temp("apply/jing"));
	set("eff_qi", query("max_qi") + query_temp("apply/qi"));
	set("jingli", query("eff_jingli") + query_temp("apply/jingli"));
	set("jing", query("eff_jing"));
	set("qi", query("eff_qi"));
	set("neili", query("max_neili") + query_temp("apply/neili"));
	set("food", max_food_capacity());
	set("water", max_water_capacity());
}

int heal_up()
{
	int update_flag, i;
	object me = this_object();
	mapping my;

	if (ghost || environment()->query("no_update")) return 0;
	update_flag = 0;

	my = query_entire_dbase();
	if ( my["food"] > max_food_capacity()+50 )
		my["food"] = max_food_capacity()+50;
	if ( my["water"] > max_water_capacity()+50 )
		my["water"] = max_water_capacity()+50;

	if (my["water"] > 0 && random(my["con"] + 20) < 25)  { my["water"]--; update_flag++; }
	if (my["food"] > 0 && random(my["con"] + 20) < 25) { my["food"]--; update_flag++; }
	if (me->is_busy() ) return update_flag;
//-------------------------------林川程修改-------------------------------------
	if (1<2) {
		if( my["water"] < -10 ) {
			message_vision("$N渴得眼冒金星，全身无力。\n", me);
			if (random(3)) me->start_busy(5);
			else if (me->query("age") > 16) {
				receive_wound("jing", 10);
				me->set_temp("last_damage_from", "脱水时间太长渴");
			}
			return update_flag;
		}
		switch(my["water"]){
			case 50:
			case 40:
			case 30:
			case 20:
			case 10:
				//message_vision(HIY"$N舔了舔干裂的嘴唇，看来是很久没有喝水了。\n"NOR, me);
		}
	}
	i = my["con"] / 3 + my["max_jingli"] / 10;
	if (me->is_fighting()) i /= 3;
	my["jing"] += i;
	if (my["jing"] >= my["eff_jing"] + me->query_temp("apply/jing")) {
		my["jing"] = my["eff_jing"] + me->query_temp("apply/jing");
		if( my["eff_jing"] < my["max_jing"] ) {
			my["eff_jing"]++;
			update_flag++;
		}
	} else update_flag++;

	i = my["con"] / 3 + my["max_neili"] / 10;
	if (me->is_fighting()) i /= 3;
	my["qi"] += i;
	if (my["qi"] >= my["eff_qi"] + me->query_temp("apply/qi")) {
		my["qi"] = my["eff_qi"] + me->query_temp("apply/qi");
		if( my["eff_qi"] < my["max_qi"] ) {
			my["eff_qi"]++;
			update_flag++;
		}
	} else update_flag++;
//==============================================林修改-------------------------
	if (1<2) {
		if( my["food"] < -10 ) {
			message_vision("$N饿得头昏眼花，直冒冷汗。\n", me);
			if (random(3)) me->start_busy(5);
			else if( me->query("age") > 16) {
				receive_wound("qi", 10);
				me->set_temp("last_damage_from", "太久没有进食饿");
			}
			return update_flag;
		}
		switch(my["food"]){
			case 50:
			case 40:
			case 30:
			case 20:
			case 10:
				//message_vision(HIY"突然一阵“咕咕”声传来，原来是$N的肚子在叫了。\n"NOR, me);
		}
	}
	if (my["jingli"] < my["eff_jingli"] + me->query_temp("apply/jingli")) {
		i = my["con"] / 2 + me->query_skill("force", 1) / 3;
		if (me->is_fighting()) i /= 3;
		my["jingli"] += i;
		if (my["jingli"] > my["eff_jingli"] + me->query_temp("apply/jingli"))
			my["jingli"] = my["eff_jingli"] + me->query_temp("apply/jingli");
		update_flag++;
	}

	if (my["neili"] < my["max_neili"] + me->query_temp("apply/neili")) {
		i = me->query_skill("force", 1) / 2 + my["con"];
		if (me->is_fighting()) i /= 3;
		my["neili"] += i;
		if (my["neili"] > my["max_neili"] + me->query_temp("apply/neili"))
			my["neili"] = my["max_neili"] + me->query_temp("apply/neili");
		update_flag++;
	}

	if (my["neili"] > my["max_neili"]*2) {
		if (!me->query_temp("pending/exercise"))
			my["neili"] = my["max_neili"] * 2;
		update_flag++;
	}

	return update_flag;
}
