/*
 * Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*QUAKED monster_scientist (0 0.8 0.8) (-16 -16 0) (16 16 72)

HALF-LIFE (1998) ENTITY

Scientist

*/

enum
{
	SCIA_WALK,
	SCIA_WALKSCARED,
	SCIA_RUN,
	SCIA_RUNSCARED,
	SCIA_RUNLOOK,
	SCIA_180LEFT,
	SCIA_180RIGHT,
	SCIA_FLINCH,
	SCIA_PAIN,
	SCIA_PAINLEFT,
	SCIA_PAINRIGHT,
	SCIA_PAINLEGLEFT,
	SCIA_PAINLEGRIGHT,
	SCIA_IDLE1,
	SCIA_IDLE2,
	SCIA_IDLE3,
	SCIA_IDLE4,
	SCIA_IDLE5,
	SCIA_IDLE6,
	SCIA_SCARED_END,
	SCIA_SCARED1,
	SCIA_SCARED2,
	SCIA_SCARED3,
	SCIA_SCARED4,
	SCIA_PANIC,
	SCIA_FEAR1,
	SCIA_FEAR2,
	SCIA_CRY,
	SCIA_SCI1,
	SCIA_SCI2,
	SCIA_SCI3,
	SCIA_DIE_SIMPLE,
	SCIA_DIE_FORWARD1,
	SCIA_DIE_FORWARD2,
	SCIA_DIE_BACKWARD,
	SCIA_DIE_HEADSHOT,
	SCIA_DIE_GUTSHOT,
	SCIA_LYING1,
	SCIA_LYING2,
	SCIA_DEADSIT,
	SCIA_DEADTABLE1,
	SCIA_DEADTABLE2,
	SCIA_DEADTABLE3
};

class monster_scientist:CBaseNPC
{
	void(void) monster_scientist;

	virtual void(void) Respawn;
	virtual void(void) PlayerUse;
	virtual void(void) Pain;
	virtual void(void) Death;
	virtual int(void) AnimIdle;
	virtual int(void) AnimWalk;
	virtual int(void) AnimRun;
	virtual void(string, string) SpawnKey;
};

int
monster_scientist::AnimIdle(void)
{
	return SCIA_IDLE1;
}

int
monster_scientist::AnimWalk(void)
{
	return SCIA_WALK;
}

int
monster_scientist::AnimRun(void)
{
	return SCIA_RUN;
}

void
monster_scientist::PlayerUse(void)
{
	if (spawnflags & MSF_PREDISASTER) {
		Sentence("!SC_POK");
		return;
	}

	CBaseNPC::PlayerUse();
}

void
monster_scientist::Pain(void)
{
	WarnAllies();

	if (m_flAnimTime > time) {
		return;
	}

	if (random() < 0.25f) {
		return;
	}

	Sound_Speak(this, "monster_scientist.pain");

	frame = SCIA_FLINCH + floor(random(0, 6));
	m_iFlags |= MONSTER_FEAR;
	m_flAnimTime = time + 0.25f;
}

void
monster_scientist::Death(void)
{
	WarnAllies();

	if (style != MONSTER_DEAD) {
		SetFrame(SCIA_DIE_SIMPLE + floor(random(0, 6)));
		Sound_Speak(this, "monster_scientist.die");
	}

	/* now mark our state as 'dead' */
	CBaseNPC::Death();
}

void
monster_scientist::Respawn(void)
{
	CBaseNPC::Respawn();
	m_iFlags |= MONSTER_CANFOLLOW;
}

void
monster_scientist::SpawnKey(string strKey, string strValue)
{
	switch (strKey) {
	case "body":
		SetBody(stoi(strValue) + 1);
		break;
	default:
		CBaseEntity::SpawnKey(strKey, strValue);
	}
}

void
monster_scientist::monster_scientist(void)
{
	Sound_Precache("monster_scientist.die");
	Sound_Precache("monster_scientist.pain");

	if (spawnflags & MSF_PREDISASTER) {
		m_talkAsk = "";
		m_talkPlayerAsk = "!SC_PQUEST";
		m_talkPlayerGreet = "!SC_PHELLO";
		m_talkPlayerIdle = "!SC_PIDLE";
	} else {
		m_talkAsk = "!SC_QUESTION";
		m_talkPlayerAsk = "!SC_QUESTION";
		m_talkPlayerGreet = "!SC_HELLO";
		m_talkPlayerIdle = "!SC_PIDLE";
	}

	m_talkAnswer = "!SC_ANSWER";
	m_talkAllyShot = "!SC_PLFEAR";
	m_talkGreet = "";
	m_talkIdle = "!SC_IDLE";
	m_talkHearing = "!SC_HEAR";
	m_talkSmelling = "!SC_SMELL";
	m_talkStare = "!SC_STARE";
	m_talkSurvived = "!SC_WOUND";
	m_talkWounded = "!SC_MORTAL";

	/* they seem to use predisaster lines regardless of disaster state */
	m_talkPlayerWounded1 = "!SC_CUREA";
	m_talkPlayerWounded2 = "!SC_CUREB";
	m_talkPlayerWounded3 = "!SC_CUREC";
	m_talkUnfollow = "!SC_WAIT";
	m_talkFollow = "!SC_OK";
	m_talkStopFollow = "!SC_STOP";
	m_iBody = -1;

	model = "models/scientist.mdl";
	base_mins = [-16,-16,0];
	base_maxs = [16,16,72];
	base_health = Skill_GetValue("scientist_health");

	CBaseNPC::CBaseNPC();

	/* has the body not been overriden, etc. choose a character for us */
	if (m_iBody == -1) {
		SetBody((int)floor(random(1,5)));
	}

	switch (m_iBody) {
	case 1:
		m_flPitch = 105;
		netname = "Walter";
		break;
	case 2:
		m_flPitch = 100;
		netname = "Einstein";
		break;
	case 3:
		m_flPitch = 95;
		netname = "Luther";
		SetSkin(1);
		break;
	default:
		m_flPitch = 100;
		netname = "Slick";
	}
}
