// Emacs style mode select   -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: cl_mobj.cpp 3798 2013-04-24 03:09:33Z dr_sean $
//
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 2006-2013 by The Odamex Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// DESCRIPTION:
//	Moving object handling. Spawn functions.
//
//-----------------------------------------------------------------------------

#include "m_alloc.h"
#include "i_system.h"
#include "z_zone.h"
#include "m_random.h"
#include "doomdef.h"
#include "p_local.h"
#include "p_lnspec.h"
#include "s_sound.h"
#include "doomstat.h"
#include "doomtype.h"
#include "v_video.h"
#include "c_cvars.h"
#include "c_effect.h"
#include "vectors.h"
#include "p_mobj.h"
#include "cl_main.h"
#include "p_ctf.h"
#include "st_stuff.h"
#include "hu_stuff.h"
#include "p_acs.h"

extern BOOL demonew;

EXTERN_CVAR(sv_nomonsters)
EXTERN_CVAR(cl_showspawns)
EXTERN_CVAR(chasedemo)

void G_PlayerReborn(player_t &player);

//

//
// P_SpawnPlayer
// Called when a player is spawned on the level.
// Most of the player structure stays unchanged
//	between levels.
//
void P_SpawnPlayer (player_t &player, mapthing2_t *mthing)
{
	// denis - clients should not control spawning
	if(!serverside)
		return;

	// [RH] Things 4001-? are also multiplayer starts. Just like 1-4.
	//		To make things simpler, figure out which player is being
	//		spawned here.
	player_t *p = &player;

	// not playing?
	if(!p->ingame())
		return;

	if (p->playerstate == PST_REBORN || p->playerstate == PST_ENTER)
		G_PlayerReborn (*p);

	AActor *mobj = new AActor (mthing->x << FRACBITS, mthing->y << FRACBITS, ONFLOORZ, MT_PLAYER);

	// set color translations for player sprites
	// [RH] Different now: MF_TRANSLATION is not used.
	mobj->translation = translationtables + 256*p->id;

	mobj->angle = ANG45 * (mthing->angle/45);
	mobj->pitch = 0;
	mobj->player = p;
	mobj->health = p->health;

	// [RH] Set player sprite based on skin
	if(p->userinfo.skin >= numskins)
		p->userinfo.skin = 0;

	mobj->sprite = skins[p->userinfo.skin].sprite;

	p->fov = 90.0f;
	p->mo = p->camera = mobj->ptr();
	p->playerstate = PST_LIVE;
	p->refire = 0;
	p->damagecount = 0;
	p->bonuscount = 0;
	p->extralight = 0;
	p->fixedcolormap = 0;
	p->viewheight = VIEWHEIGHT;
	p->xviewshift = 0;
	p->attacker = AActor::AActorPtr();

	consoleplayer().camera = displayplayer().mo;

	// Set up some special spectator stuff
	if (p->spectator)
	{
		mobj->translucency = 0;
		p->mo->flags |= MF_SPECTATOR;
		p->mo->flags2 |= MF2_FLY;
		p->mo->flags &= ~MF_SOLID;
	}

	// [RH] Allow chasecam for demo watching
	if ((demoplayback || demonew) && chasedemo)
		p->cheats = CF_CHASECAM;

	// setup gun psprite
	P_SetupPsprites (p);

	// give all cards in death match mode
	if (sv_gametype != GM_COOP)
	{
		for (int i = 0; i < NUMCARDS; i++)
			p->cards[i] = true;
	}

	if (consoleplayer().camera == p->mo)
	{
		// wake up the status bar
		ST_Start ();
	}

	// [RH] If someone is in the way, kill them
	P_TeleportMove (mobj, mobj->x, mobj->y, mobj->z, true);

	// [BC] Do script stuff
	if (serverside)
    {
        if (level.behavior != NULL)
        {
            if (p->playerstate == PST_ENTER)
            {
                level.behavior->StartTypedScripts (SCRIPT_Enter, p->mo);
            }
            else if (p->playerstate == PST_REBORN)
            {
                level.behavior->StartTypedScripts (SCRIPT_Respawn, p->mo);
            }
        }
    }
}

std::vector<AActor*> spawnfountains;

/**
 * Show spawn points as particle fountains
 */
void P_ShowSpawns(mapthing2_t* mthing)
{
	if (clientside && cl_showspawns)
	{
		AActor* spawn = 0;

		if (sv_gametype == GM_DM && mthing->type == 11)
		{
			spawn = new AActor(mthing->x << FRACBITS, mthing->y << FRACBITS, mthing->z << FRACBITS, MT_FOUNTAIN);
			spawn->args[0] = 7; // White
		}

		if (sv_gametype == GM_TEAMDM || sv_gametype == GM_CTF)
		{
			if (mthing->type == 5080)
			{
				spawn = new AActor(mthing->x << FRACBITS, mthing->y << FRACBITS, mthing->z << FRACBITS, MT_FOUNTAIN);
				spawn->args[0] = 3; // Blue
			}
			else if (mthing->type == 5081)
			{
				spawn = new AActor(mthing->x << FRACBITS, mthing->y << FRACBITS, mthing->z << FRACBITS, MT_FOUNTAIN);
				spawn->args[0] = 1; // Red
			}
		}

		if (spawn) {
			spawn->effects = spawn->args[0] << FX_FOUNTAINSHIFT;
		}
	}
}

VERSION_CONTROL (cl_mobj_cpp, "$Id: cl_mobj.cpp 3798 2013-04-24 03:09:33Z dr_sean $")
