#include "MyGame.h"
#include "main.h"
#include <Quadtree.hpp>
void MyGame::Init(MyDX11Renderer* pRenderer, MySDLInput* pInput, JoystickInput* pJoystickInput, MyView* pView,const GameFunc* pGameFunc)
{
    this->pRenderer = pRenderer;
    this->pInput = pInput;
	this->pJoystickInput = pJoystickInput;
    this->pView = pView;
	int* pMapW = nullptr;
	int* pMapH = nullptr;
	gameMap.GetMapSize(&pMapW, &pMapH);
	//初始化GameFunc
	gameFunc = *pGameFunc;
	gameFunc.entityRes = &entityRes;
	gameFunc.gameMap = &gameMap;
	gameFunc.dmgNum = &dmgNum;
	gameFunc.gameScript = &gameScript;
	gameFunc.gameUI = &gameUI;
	gameFunc.flagSet = &flagSet;
	gameFunc.skipSet = &skipSet;
	gameFunc.game = this;
	gameFunc.mapSizeGetter = &gameMap;
	gameFunc.pGameOption_playerNum = &gameOption_playerNum;
	gameFunc.pGameOption_difficulty = &gameOption_difficulty;
	gameFunc.slotDrawer = &slotDrawer;
	gameFunc.gameFlash = &gameFlash;
	//组件初始化
	gameMap.Init(pView, &gamePxa, &scriptCmd);
	myCamera.Init(pView, pMapW, pMapH);
	entityRes.Init(pRenderer, pInput, pView, pMapW, pMapH, &gamePid, &gameFunc,
		&mychar_player1, &mychar_player1_menuKeyboard, &mychar_player2, &mychar_player2_menuKeyboard,
		&checkEventPlayerIndex, &globalEntity);
	gameScript.Init(this);
	scriptCmd.Init(this);
	gameMsgbox.Init(pRenderer, pView, &gameScript, &mychar_player1, &mychar_player2);
	gameFade.Init(pRenderer, pView, &mychar_player1);
	gameUI.Init(pRenderer, pView, &entityRes);
	gameTimer.Init(pRenderer, pView);
	dmgNum.Init(pRenderer, pView);
	mapSystem.Init(pRenderer, pView, &gameMap, &gamePxa, &mychar_player1, &mychar_player2, this);
	stageDrawer.Init(pRenderer, pView, &gameMap, &entityRes, &gamePxa);
	itemSystem.Init(pRenderer, pView, pInput, &gameMsgbox, &gameScript, &mapSystem, &entityRes, &gameUI, this);
	slotDrawer.Init(pRenderer, pView, &entityRes);
	gameFlash.Init(pRenderer, pView);
	//其他
	GetKey[0] = &GameInput::GetUp;
	GetKey[1] = &GameInput::GetDown;
	GetKey[2] = &GameInput::GetLeft;
	GetKey[3] = &GameInput::GetRight;
	GetKey[4] = &GameInput::GetOk;
	GetKey[5] = &GameInput::GetCancel;
	GetKey[6] = &GameInput::GetJump;
	GetKey[7] = &GameInput::GetAtk;
	GetKey[8] = &GameInput::GetMenu;
	GetKey[9] = &GameInput::GetInventory;
	GetKey[10] = &GameInput::GetMap;
	GetKey[11] = &GameInput::GetPagePrev;
	GetKey[12] = &GameInput::GetPageNext;
	GetKey[13] = &GameInput::GetSwitchMc;
	GetKey[14] = &GameInput::GetSkill_1;
	GetKey[15] = &GameInput::GetSkill_2;
	GetKey[16] = &GameInput::GetSkill_3;
	GetKey[17] = &GameInput::GetSkill_4;
	GetKey[18] = &GameInput::GetSkill_5;
	GetKey[19] = &GameInput::GetSkill_6;

	SetKey[0] = &GameInput::SetUp;
	SetKey[1] = &GameInput::SetDown;
	SetKey[2] = &GameInput::SetLeft;
	SetKey[3] = &GameInput::SetRight;
	SetKey[4] = &GameInput::SetOk;
	SetKey[5] = &GameInput::SetCancel;
	SetKey[6] = &GameInput::SetJump;
	SetKey[7] = &GameInput::SetAtk;
	SetKey[8] = &GameInput::SetMenu;
	SetKey[9] = &GameInput::SetInventory;
	SetKey[10] = &GameInput::SetMap;
	SetKey[11] = &GameInput::SetPagePrev;
	SetKey[12] = &GameInput::SetPageNext;
	SetKey[13] = &GameInput::SetSwitchMc;
	SetKey[14] = &GameInput::SetSkill_1;
	SetKey[15] = &GameInput::SetSkill_2;
	SetKey[16] = &GameInput::SetSkill_3;
	SetKey[17] = &GameInput::SetSkill_4;
	SetKey[18] = &GameInput::SetSkill_5;
	SetKey[19] = &GameInput::SetSkill_6;
	
	//玩家1Keyboard
	is_p1k[0] = &inputSetting_player1Keyboard.op_up;
	is_p1k[1] = &inputSetting_player1Keyboard.op_down;
	is_p1k[2] = &inputSetting_player1Keyboard.op_left;
	is_p1k[3] = &inputSetting_player1Keyboard.op_right;
	is_p1k[4] = &inputSetting_player1Keyboard.op_ok;
	is_p1k[5] = &inputSetting_player1Keyboard.op_cancel;
	is_p1k[6] = &inputSetting_player1Keyboard.op_jump;
	is_p1k[7] = &inputSetting_player1Keyboard.op_atk;
	is_p1k[8] = &inputSetting_player1Keyboard.op_menu;
	is_p1k[9] = &inputSetting_player1Keyboard.op_inventory;
	is_p1k[10] = &inputSetting_player1Keyboard.op_map;
	is_p1k[11] = &inputSetting_player1Keyboard.op_pagePrev;
	is_p1k[12] = &inputSetting_player1Keyboard.op_pageNext;
	is_p1k[13] = &inputSetting_player1Keyboard.op_switchMc;
	is_p1k[14] = &inputSetting_player1Keyboard.op_skill_1;
	is_p1k[15] = &inputSetting_player1Keyboard.op_skill_2;
	is_p1k[16] = &inputSetting_player1Keyboard.op_skill_3;
	is_p1k[17] = &inputSetting_player1Keyboard.op_skill_4;
	is_p1k[18] = &inputSetting_player1Keyboard.op_skill_5;
	is_p1k[19] = &inputSetting_player1Keyboard.op_skill_6;
	
	//玩家2Keyboard
	is_p2k[0] = &inputSetting_player2Keyboard.op_up;
	is_p2k[1] = &inputSetting_player2Keyboard.op_down;
	is_p2k[2] = &inputSetting_player2Keyboard.op_left;
	is_p2k[3] = &inputSetting_player2Keyboard.op_right;
	is_p2k[4] = &inputSetting_player2Keyboard.op_ok;
	is_p2k[5] = &inputSetting_player2Keyboard.op_cancel;
	is_p2k[6] = &inputSetting_player2Keyboard.op_jump;
	is_p2k[7] = &inputSetting_player2Keyboard.op_atk;
	is_p2k[8] = &inputSetting_player2Keyboard.op_menu;
	is_p2k[9] = &inputSetting_player2Keyboard.op_inventory;
	is_p2k[10] = &inputSetting_player2Keyboard.op_map;
	is_p2k[11] = &inputSetting_player2Keyboard.op_pagePrev;
	is_p2k[12] = &inputSetting_player2Keyboard.op_pageNext;
	is_p2k[13] = &inputSetting_player2Keyboard.op_switchMc;
	is_p2k[14] = &inputSetting_player2Keyboard.op_skill_1;
	is_p2k[15] = &inputSetting_player2Keyboard.op_skill_2;
	is_p2k[16] = &inputSetting_player2Keyboard.op_skill_3;
	is_p2k[17] = &inputSetting_player2Keyboard.op_skill_4;
	is_p2k[18] = &inputSetting_player2Keyboard.op_skill_5;
	is_p2k[19] = &inputSetting_player2Keyboard.op_skill_6;
	
	//玩家1Joystick
	is_p1j[0] = &inputSetting_player1Joystick.op_up;
	is_p1j[1] = &inputSetting_player1Joystick.op_down;
	is_p1j[2] = &inputSetting_player1Joystick.op_left;
	is_p1j[3] = &inputSetting_player1Joystick.op_right;
	is_p1j[4] = &inputSetting_player1Joystick.op_ok;
	is_p1j[5] = &inputSetting_player1Joystick.op_cancel;
	is_p1j[6] = &inputSetting_player1Joystick.op_jump;
	is_p1j[7] = &inputSetting_player1Joystick.op_atk;
	is_p1j[8] = &inputSetting_player1Joystick.op_menu;
	is_p1j[9] = &inputSetting_player1Joystick.op_inventory;
	is_p1j[10] = &inputSetting_player1Joystick.op_map;
	is_p1j[11] = &inputSetting_player1Joystick.op_pagePrev;
	is_p1j[12] = &inputSetting_player1Joystick.op_pageNext;
	is_p1j[13] = &inputSetting_player1Joystick.op_switchMc;
	is_p1j[14] = &inputSetting_player1Joystick.op_skill_1;
	is_p1j[15] = &inputSetting_player1Joystick.op_skill_2;
	is_p1j[16] = &inputSetting_player1Joystick.op_skill_3;
	is_p1j[17] = &inputSetting_player1Joystick.op_skill_4;
	is_p1j[18] = &inputSetting_player1Joystick.op_skill_5;
	is_p1j[19] = &inputSetting_player1Joystick.op_skill_6;
	
	//玩家1Joystick
	is_p2j[0] = &inputSetting_player2Joystick.op_up;
	is_p2j[1] = &inputSetting_player2Joystick.op_down;
	is_p2j[2] = &inputSetting_player2Joystick.op_left;
	is_p2j[3] = &inputSetting_player2Joystick.op_right;
	is_p2j[4] = &inputSetting_player2Joystick.op_ok;
	is_p2j[5] = &inputSetting_player2Joystick.op_cancel;
	is_p2j[6] = &inputSetting_player2Joystick.op_jump;
	is_p2j[7] = &inputSetting_player2Joystick.op_atk;
	is_p2j[8] = &inputSetting_player2Joystick.op_menu;
	is_p2j[9] = &inputSetting_player2Joystick.op_inventory;
	is_p2j[10] = &inputSetting_player2Joystick.op_map;
	is_p2j[11] = &inputSetting_player2Joystick.op_pagePrev;
	is_p2j[12] = &inputSetting_player2Joystick.op_pageNext;
	is_p2j[13] = &inputSetting_player2Joystick.op_switchMc;
	is_p2j[14] = &inputSetting_player2Joystick.op_skill_1;
	is_p2j[15] = &inputSetting_player2Joystick.op_skill_2;
	is_p2j[16] = &inputSetting_player2Joystick.op_skill_3;
	is_p2j[17] = &inputSetting_player2Joystick.op_skill_4;
	is_p2j[18] = &inputSetting_player2Joystick.op_skill_5;
	is_p2j[19] = &inputSetting_player2Joystick.op_skill_6;
	
}

void MyGame::SetMainGame()
{
	mainGameCmd = &scriptCmd;
}

void MyGame::EnableDrawDebug(bool bEnable)
{
	this->enableDrawDebug = bEnable;
}

void MyGame::SetUIVisiable(bool bVisiable)
{
	gameUI.SetVisible(bVisiable);
}

void MyGame::LoadSetting(const wchar_t* settingName)
{
	std::vector<char> utf8SettingName;
	UTF16ToUTF8(settingName, &utf8SettingName);
	tinyxml2::XMLDocument xmlDoc;
	FILE* fp;
	_wfopen_s(&fp, L"./data/setting.xml", L"rb");
	if (!fp)
	{
		MessageBoxW(hwnd, L"无法读取setting.xml文件", L"载入配置文件失败", MB_ICONERROR);
		return;
	}
	fseek(fp, 0, SEEK_END);
	size_t fileLen = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	std::vector<char> byte_buff;
	byte_buff.resize(fileLen + 1);
	fread_s(byte_buff.data(), fileLen, fileLen, 1, fp);
	fclose(fp);
	xmlDoc.Parse(byte_buff.data());
	//寻找目标元素
	tinyxml2::XMLElement* elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), utf8SettingName.data()))
		{
			elem = pElem;
			break;
		}	
	}
	if (!elem)
	{
		wchar_t err[MAX_PATH];
		swprintf_s(err, L"配置文件找不到%s元素", settingName);
		MessageBoxW(hwnd, err, L"读取配置文件设置失败", MB_ICONERROR);
		return;
	}
	Reset();
	std::vector<wchar_t> wbuff;
	//载入地图
	UTF8ToUTF16(elem->Attribute("map"), &wbuff);
	gameMap.LoadMap(wbuff.data());
	//启动事件
	if (elem->BoolAttribute("startEvent"))
	{
		//设置起始事件
		UTF8ToUTF16(elem->Attribute("event"), &wbuff);
		gameScript.StartEvent(wbuff.data(), L"tBoot");
	}
	//设置初始点亮
	gameFade.SetLight(elem->BoolAttribute("fadeLight"));
	//立即销毁shared_ptr局部变量指针
	{
		//玩家1起始人物
		UTF8ToUTF16(elem->Attribute("mychar_player1"), &wbuff);
		auto wmychar_player1 = mychar_player1.lock();
		if (wmychar_player1)
			wmychar_player1->Destroy();
		wmychar_player1 = GameCreateEntity(wbuff.data());
		mychar_player1 = wmychar_player1;
		wmychar_player1->el.name = wbuff.data();
		//玩家1全局实体ID名
		UTF8ToUTF16(elem->Attribute("mychar_player1_globalEntityID"), &wbuff);
		globalEntityTable[wbuff.data()] = wmychar_player1;
		wmychar_player1->globalEntityID = wbuff.data();
		//玩家1键盘
		UTF8ToUTF16(elem->Attribute("mychar_player1_keyboard"), &wbuff);
		auto wmychar_player1_menuKeyboard = mychar_player1_menuKeyboard.lock();
		if (wmychar_player1_menuKeyboard)
			wmychar_player1_menuKeyboard->Destroy();
		wmychar_player1_menuKeyboard = GameCreateEntity(wbuff.data());
		mychar_player1_menuKeyboard = wmychar_player1_menuKeyboard;
		wmychar_player1_menuKeyboard->el.name = wbuff.data();
		//玩家1初始坐标
		wmychar_player1->x = elem->IntAttribute("player1_x") * 16.0f + 8.0f;
		wmychar_player1->y = elem->IntAttribute("player1_y") * 16.0f + 8.0f;
		//玩家1初始面对方向
		wmychar_player1->lr = elem->IntAttribute("player1_lr");
		//初始隐藏玩家1
		wmychar_player1->hide = elem->BoolAttribute("player1_hide");
		wmychar_player1_menuKeyboard->hide = false;

		//玩家2起始人物
		UTF8ToUTF16(elem->Attribute("mychar_player2"), &wbuff);
		auto wmychar_player2 = mychar_player2.lock();
		if (wmychar_player2)
			wmychar_player2->Destroy();
		wmychar_player2 = GameCreateEntity(wbuff.data());
		mychar_player2 = wmychar_player2;
		wmychar_player2->el.name = wbuff.data();
		//玩家2全局实体ID名
		UTF8ToUTF16(elem->Attribute("mychar_player2_globalEntityID"), &wbuff);
		globalEntityTable[wbuff.data()] = wmychar_player2;
		wmychar_player2->globalEntityID = wbuff.data();
		//玩家2键盘
		UTF8ToUTF16(elem->Attribute("mychar_player2_keyboard"), &wbuff);
		auto wmychar_player2_menuKeyboard = mychar_player2_menuKeyboard.lock();
		if (wmychar_player2_menuKeyboard)
			wmychar_player2_menuKeyboard->Destroy();
		wmychar_player2_menuKeyboard = GameCreateEntity(wbuff.data());
		mychar_player2_menuKeyboard = wmychar_player2_menuKeyboard;
		wmychar_player2_menuKeyboard->el.name = wbuff.data();
		//玩家2初始坐标
		wmychar_player2->x = wmychar_player2_menuKeyboard->x = elem->IntAttribute("player2_x") * 16.0f + 8.0f;
		wmychar_player2->y = wmychar_player2_menuKeyboard->y = elem->IntAttribute("player2_y") * 16.0f + 8.0f;
		//玩家2初始面对方向
		wmychar_player2->lr = wmychar_player2_menuKeyboard->lr = elem->IntAttribute("player2_lr");
		//初始隐藏玩家2
		wmychar_player2->hide = elem->BoolAttribute("player2_hide");
		wmychar_player2_menuKeyboard->hide = false;

		//设置其他变量
		wmychar_player1->gameFunc = &gameFunc;
		wmychar_player1->Init(wmychar_player1);
		wmychar_player1_menuKeyboard->gameFunc = &gameFunc;
		wmychar_player1_menuKeyboard->Init(wmychar_player1_menuKeyboard);
		wmychar_player2->gameFunc = &gameFunc;
		wmychar_player2->Init(wmychar_player2);
		wmychar_player2_menuKeyboard->gameFunc = &gameFunc;
		wmychar_player2_menuKeyboard->Init(wmychar_player2_menuKeyboard);
		//立即切换镜头
		myCamera.SetTarget(mychar_player1);
		if (gameOption_playerNum == 2)
			myCamera.SetTarget2(mychar_player2);
		myCamera.FocusOnce();
		//将玩家加入全局实体运行
		globalEntity.push_back(wmychar_player1);
		globalEntity.push_back(wmychar_player2);
		globalEntity.push_back(wmychar_player1_menuKeyboard);
		globalEntity.push_back(wmychar_player2_menuKeyboard);
	}
	
	//锁住ok键
	for (auto& wplayer : globalEntity)
	{
		wplayer->input.SetOk(false);
		wplayer->inputLock.SetOk(true);
	}
	//载入场景实体
	StepEntitySystem();
}

void MyGame::LoadSetting(const wchar_t* mapfileName, const wchar_t* mycharName, int xPos, int yPos, int lr, bool hidePlayer, bool bLight, bool runEvent, const wchar_t* eventName)
{
	Reset();
	//载入地图
	gameMap.LoadMap(mapfileName);
	//起始事件
	if (runEvent && eventName[0])
		gameScript.StartEvent(eventName, L"tBoot");
	//立即销毁shared_ptr局部变量指针
	{
		//起始人物
		auto wmychar_player1 = mychar_player1.lock();
		if (wmychar_player1)
			wmychar_player1->Destroy();
		wmychar_player1 = GameCreateEntity(mycharName);
		mychar_player1 = wmychar_player1;
		wmychar_player1->el.name = mycharName;
		auto wmychar_player2 = mychar_player2.lock();
		if (wmychar_player2)
			wmychar_player2->Destroy();
		wmychar_player2 = GameCreateEntity(L"null");
		mychar_player2 = wmychar_player2;
		wmychar_player2->el.name = L"null";
		//初始坐标
		wmychar_player2->x = wmychar_player1->x = xPos * 16.0f + 8.0f;
		wmychar_player2->y = wmychar_player1->y = yPos * 16.0f + 8.0f;
		//初始面对方向
		wmychar_player1->lr = lr;
		myCamera.SetTarget(mychar_player1);
		//隐藏玩家
		wmychar_player1->hide = hidePlayer;

		//设置初始点亮
		gameFade.SetLight(bLight);
		//设置其他变量
		wmychar_player1->gameFunc = &gameFunc;
		//立即切换镜头
		myCamera.FocusOnce();

		//锁住ok键
		std::weak_ptr<Entity> players[2];
		players[0] = mychar_player1;
		players[1] = mychar_player2;
		for (auto i = 0; i < _countof(players); i++)
		{
			auto wplayer = players[i].lock();
			if (wplayer)
			{
				wplayer->input.SetOk(false);
				wplayer->inputLock.SetOk(true);
			}
		}
		//将玩家加入全局实体运行
		globalEntity.push_back(wmychar_player1);
		globalEntityTable[L"player1"] = wmychar_player1;
		globalEntity.push_back(wmychar_player2);
		globalEntityTable[L"player2"] = wmychar_player2;
		//设置其他变量
		wmychar_player1->gameFunc = &gameFunc;
		wmychar_player1->Init(wmychar_player1);
		wmychar_player2->gameFunc = &gameFunc;
		wmychar_player2->Init(wmychar_player2);
	}
	//载入场景实体
	if (bNoEnemyMode)
		ClearEnemy();
	else
		StepEntitySystem();
}

void MyGame::LoadMap(const wchar_t* mapfileName)
{
	entityRes.Reset();
	gameMap.LoadMap(mapfileName);
}

void MyGame::StartEvent(const wchar_t* eventName, const wchar_t* triggerType)
{
	gameScript.StartEvent(eventName, triggerType);
}

void MyGame::Draw(float deltaTime)
{
	bool gameIsPause = mapSystem.GetShow() || itemSystem.GetShow() || gameScript.GetPRI();
	if (!gameIsPause)
		game_delteTime = deltaTime;
	DeltaTimeEntitySystem(game_delteTime);
	myCamera.DeltaTime(game_delteTime);
	MyMapLayer* mainLayer = nullptr;
	if (gameFade.GetLight() || gameFade.GetFadeIn())
	{
		//绘制舞台
		mainLayer = stageDrawer.Draw(game_delteTime);
		//伤害数字
		dmgNum.Draw(game_delteTime);
	}
	//绘制存档页
	slotDrawer.Draw();
	//渐入渐出
	gameFade.Draw();
	//顶级绘制实体
	for (auto& layer : *gameMap.GetLayerList())
		entityRes.DrawEntityLayer(&layer, true);
	//绘制结尾致辞
	if (credit)
	{
		creditView = *pView;
		creditView.offX = creditView.offY = 0;
		credit->Draw(deltaTime);
	}
	//绘制闪光
	gameFlash.Draw();
	//绘制调试
	if (enableDrawDebug && bShowDebug)
	{
		for (auto& layer : *gameMap.GetLayerList())
		{
			if (!layer.visible)
				continue;
			if (layer.layerType == 0)
			{
				//绘制地形类型
				stageDrawer.GetMapDrawer()->DrawPxaLayer(&layer);
				//绘制碰撞矩形
				//entityRes.DrawCollisionEntityLayer(&layer, gamePxa.GetPxa(layer.pxaName.c_str()));
				//绘制玩家碰撞矩形
				/*pRenderer->SetPenDraw();
				entityRes.DrawCollisionEntity(mychar_player1, &layer.step_pxm, &gamePxa.GetPxa(layer.pxaName.c_str())->pxa);
				pRenderer->DrawLine();*/
				//绘制实体碰撞框
				entityRes.DrawEntityCbRectLayer(&layer);
				//绘制四叉树框
				entityRes.DrawQuadTree(&layer);
				//绘制实体事件名
				entityRes.DrawEntityEventNameLayer(&layer);
				break;
			}
		}
		//绘制全局实体的事件名
		/*for (auto& p : globalEntityTable)
			entityRes.DrawEntityGlobalIDName(p.second);*/
		//绘制寻路
		//entityRes.DrawPath();
	}
	//绘制房间名
	if (!(mapSystem.GetShow() || 
		gameScript.GetPRI() || 
		gameScript.GetKEY() || 
		bShowDebug))
		stageDrawer.GetMapDrawer()->DrawRoomName(gameMap.GetMapShowName());
	//绘制计时器
	{
		bool bShowPlayer2 = false;
		auto wplayer2 = mychar_player2.lock();
		if (wplayer2)
			bShowPlayer2 = wplayer2->el.name != L"null";
		gameTimer.Draw(bShowPlayer2);
	}
	//游戏画面变暗
	DrawDark();
	//绘制UI
	if (!(gameScript.GetPRI() ||
		gameScript.GetKEY() ||
		itemSystem.GetShow() ||
		bShowDebug))
		gameUI.Draw(game_delteTime);
	//绘制物品栏
	if (!mapSystem.GetShow())
		itemSystem.Draw(deltaTime);
	//绘制小地图
	mapSystem.Draw(mainLayer);
	//绘制文本框
	if (!mapSystem.GetShow())
		gameMsgbox.Draw(deltaTime);
}

void MyGame::Step()
{
	//物品栏
	if (!mapSystem.GetShow())
		itemSystem.Step();
	//执行脚本
	if (!mapSystem.GetShow())
		gameScript.Step();
	//执行文本框
	if (!mapSystem.GetShow())
		gameMsgbox.Step();
	//执行游戏
	if(!(gameScript.GetPRI() || 
		mapSystem.GetShow()||
		itemSystem.GetShow()))
	{
		//执行背景动画
		stageDrawer.Step();
		//执行相机
		myCamera.Step();
		//运行实体
		StepEntitySystem();
		//玩家调查事件
		PlayerCheckEvent();
		//运行伤害数字
		dmgNum.Step();
		//运行计时器
		if (!gameScript.IsRunning())
			gameTimer.Step();
	}
	//执行UI
	if (!gameScript.IsRunning())
		gameUI.Step();
	//地图系统
	if (itemSystem.IsEnableMapSystem())
		mapSystem.Step();
	//渐入渐出
	gameFade.Step();
	//闪光
	gameFlash.Step();
	//切换角色
	SwitchPlayerStep();
	//结尾致辞
	if (credit)
	{
		creditView = *pView;
		creditView.offX = creditView.offY = 0;
		credit->Step();
	}
}

void MyGame::Reset()
{
	credit.reset();
	for (auto we : globalEntity)
		we->Destroy();
	globalEntity.clear();
	for (auto we : globalEntity_addList)
		we->Destroy();
	globalEntity_addList.clear();
	globalEntityTable.clear();
	mychar_player1.reset();
	mychar_player2.reset();
	gameFade.Reset();
	entityRes.Reset();
	gameScript.Reset();
	dmgNum.Reset();
	gameUI.Reset();
	gameTimer.Reset();
	myCamera.Reset();
	flagSet.clear();
	positionSaver.clear();
	itemSystem.Reset();
	stageDrawer.Reset();
	mapSystem.Reset();
	slotDrawer.Reset();
	gameFlash.Reset();
	LoadConfig();
}

void MyGame::Controll()
{
	//player1ControllerType = 1;
	Keyboard();
	Joystick();
	itemSystem.Controll();
}

void MyGame::OnResetScale(int w, int h)
{
	stageDrawer.OnResetScale(w, h);
	gameMsgbox.OnResetScale();
	entityRes.OnResetScale();
	mapSystem.OnResetScale();
	gameUI.OnResetScale();
	itemSystem.OnResetScale(w, h);
}

std::weak_ptr<Entity> MyGame::GetMyChar_Player1()
{
	return mychar_player1;
}

std::weak_ptr<Entity> MyGame::GetMyChar_Player1_menuKeyboard()
{
	return mychar_player1_menuKeyboard;
}

std::weak_ptr<Entity> MyGame::GetMyChar_Player2()
{
	return mychar_player2;
}

std::weak_ptr<Entity> MyGame::GetMyChar_Player2_menuKeyboard()
{
	return mychar_player2_menuKeyboard;
}

void MyGame::SetMyChar_Player1(std::weak_ptr<Entity> e)
{
	mychar_player1 = e;
}

void MyGame::SetMyChar_Player2(std::weak_ptr<Entity> e)
{
	mychar_player2 = e;
}

bool MyGame::TitleStageOk()
{
	bool flag = !gameScript.IsRunning();
	std::weak_ptr<Entity> players[4];
	players[0] = mychar_player1;
	players[1] = mychar_player1_menuKeyboard;
	players[2] = mychar_player2;
	players[3] = mychar_player2_menuKeyboard;
	for (auto i = 0; i < _countof(players); i++)
	{
		auto wplayer = players[i].lock();
		if (wplayer)
			flag |= wplayer->input.GetOk();
	}
	return flag;
}

void MyGame::GetDebugEntityNum(int* outLsNum, int* outMcNum, int* outAmNum, int* outPeNum)
{
	*outMcNum = (int)globalEntity.size();
	entityRes.GetDebugEntityNum(outLsNum, outAmNum, outPeNum);
}

void MyGame::SaveGame(std::vector<char>* saveData)
{
	//保存游戏数据
	//写入xml文件
	tinyxml2::XMLDocument xmlDoc;
	std::vector<char> utf8;
	std::vector<char> utf8_field;
	std::vector<char> utf8_value;
	//写入Room元素
	auto elem_room = xmlDoc.NewElement("Room");
	UTF16ToUTF8(gameMap.GetMapFileName().c_str(), &utf8);
	elem_room->SetAttribute("name", utf8.data());
	xmlDoc.InsertEndChild(elem_room);
	//写入Music元素
	auto elem_music = xmlDoc.NewElement("Music");
	UTF16ToUTF8(pMusic.GetLastPlayMusic(), &utf8);
	elem_music->SetAttribute("name", utf8.data());
	elem_music->SetAttribute("playing", pMusic.IsPlaying());
	xmlDoc.InsertEndChild(elem_music);
	//写入Organya元素
	auto elem_organya = xmlDoc.NewElement("Organya");
	UTF16ToUTF8(orgPlayer.GetLastPlayMusic(), &utf8);
	elem_organya->SetAttribute("name", utf8.data());
	elem_organya->SetAttribute("playing", orgPlayer.IsPlaying());
	xmlDoc.InsertEndChild(elem_organya);
	//写入FlagStr元素
	auto elem_flag = xmlDoc.NewElement("FlagStr");
	for (auto& p : flagSet)
	{
		UTF16ToUTF8(p.c_str(), &utf8);
		auto elem = xmlDoc.NewElement("ID");
		elem->SetText(utf8.data());
		elem_flag->InsertEndChild(elem);
	}
	xmlDoc.InsertEndChild(elem_flag);
	//写入Item元素
	auto elem_item = xmlDoc.NewElement("Item");
	for (ItemData& itemData : *itemSystem.GetItemList())
	{
		if (itemData.regID.length() == 0 || itemData.num <= 0)
			itemData.regID = L"Null";
		UTF16ToUTF8(itemData.regID.c_str(), &utf8);
		auto elem_itemData = xmlDoc.NewElement(utf8.data());
		elem_itemData->SetAttribute("num", itemData.num);
		elem_item->InsertEndChild(elem_itemData);
	}
	xmlDoc.InsertEndChild(elem_item);
	//写入Mission元素
	auto elem_mission = xmlDoc.NewElement("Mission");
	for (MissionData& missionData : *itemSystem.GetMissionList())
	{
		UTF16ToUTF8(missionData.regID.c_str(), &utf8);
		elem_mission->InsertEndChild(xmlDoc.NewElement(utf8.data()));
	}
	xmlDoc.InsertEndChild(elem_mission);
	//写入Option元素
	auto elem_option = xmlDoc.NewElement("Option");
	UTF16ToUTF8(gameOption_gameName.c_str(), &utf8);
	elem_option->SetAttribute("gameName", utf8.data());
	elem_option->SetAttribute("playerNum", gameOption_playerNum);
	elem_option->SetAttribute("difficulty", gameOption_difficulty);
	xmlDoc.InsertEndChild(elem_option);
	//写入GameVar元素
	auto elem_gamevar = xmlDoc.NewElement("GameVar");
	elem_gamevar->SetAttribute("enablePlayer2AISwitch", enablePlayer2AISwitch);
	xmlDoc.InsertEndChild(elem_gamevar);
	//写入GlobalEntity元素
	auto elem_globalentity = xmlDoc.NewElement("GlobalEntity");
	std::unordered_map<std::wstring, int> eidCounter;
	for (auto& wplayer : globalEntity)
	{
		entitySaveVar.clear();
		wplayer->WriteSaveData();
		UTF16ToUTF8(wplayer->el.name.c_str(), &utf8);
		auto elem_player = xmlDoc.NewElement(utf8.data());
		for (auto& iterTable : entitySaveVar)
		{
			UTF16ToUTF8(iterTable.first.c_str(), &utf8);
			auto elem_table = xmlDoc.NewElement(utf8.data());
			for (auto& iterField : iterTable.second)
			{
				//设置字段
				UTF16ToUTF8(iterField.first.c_str(), &utf8_field);
				UTF16ToUTF8(iterField.second.c_str(), &utf8_value);
				elem_table->SetAttribute(utf8_field.data(), utf8_value.data());
			}
			elem_player->InsertEndChild(elem_table);
		}
		if (wplayer == mychar_player1.lock())
		{
			wplayer->el.eid = L"player1";
		}
		else if (wplayer == mychar_player2.lock())
		{
			wplayer->el.eid = L"player2";
		}
		if (wplayer->el.eid.length() == 0)
		{
			//生成一个eid
			auto iter = eidCounter.find(wplayer->el.name);
			if (iter == eidCounter.end())
				eidCounter.insert(std::make_pair(wplayer->el.name, 0));
			int& index = eidCounter.at(wplayer->el.name);
			wchar_t wbuff[MAX_PATH];
			swprintf_s(wbuff, L"%s_%d", wplayer->el.name.c_str(), index);
			index++;
			wplayer->el.eid = wbuff;
		}
		UTF16ToUTF8(wplayer->el.eid.c_str(), &utf8);
		elem_player->SetAttribute("PlayerIndex", utf8.data());
		//保存globalEntityID
		UTF16ToUTF8(wplayer->globalEntityID.c_str(), &utf8);
		elem_player->SetAttribute("GlobalEntityID", utf8.data());
		//插入到末尾
		elem_globalentity->InsertEndChild(elem_player);
	}
	xmlDoc.InsertEndChild(elem_globalentity);
	//写入Entity元素
	auto elem_entity = xmlDoc.NewElement("Entity");
	//写入需要存档的实体
	entityRes.EntitySaveData();
	for (auto& p : entitySaveVar)
	{
		UTF16ToUTF8(p.first.c_str(), &utf8);
		auto elem_eid = xmlDoc.NewElement(utf8.data());
		for (auto& t : p.second)
		{
			//写入键值对
			UTF16ToUTF8(t.first.c_str(), &utf8_field);
			UTF16ToUTF8(t.second.c_str(), &utf8_value);
			elem_eid->SetAttribute(utf8_field.data(), utf8_value.data());
		}
		elem_entity->InsertEndChild(elem_eid);
	}
	xmlDoc.InsertEndChild(elem_entity);
	//写入Slot元素
	auto elem_slot = xmlDoc.NewElement("Slot");
	{
		std::wstring png_player, spriteIndex_player;
		int imageIndex_player = 0;
		std::vector<char> utf8_png, utf8_spriteIndex, utf8_uiName;
		std::set<int> hideLayerList;
		std::string numArr;
		bool jumpFirst = true;
		struct TempSlotData
		{
			std::string slotElemName;
			int playerIndex = 0;
			std::weak_ptr<Entity> e;
			PlayerUIData* ui = nullptr;
		}p1, p2;
		p1.playerIndex = 0;
		p1.slotElemName = "SlotPlayer1";
		p1.e = mychar_player1;
		p1.ui = gameUI.GetPlayerUIData(0);
		p2.playerIndex = 0;
		p2.slotElemName = "SlotPlayer2";
		p2.e = mychar_player2;
		p2.ui = gameUI.GetPlayerUIData(1);
		TempSlotData* arr[] = { &p1,&p2 };
		for (auto& p : arr)
		{
			auto elem_slotPlayer = xmlDoc.NewElement(p->slotElemName.c_str());
			auto we = p->e.lock();
			if (we)
				we->GetIcon(png_player, spriteIndex_player, imageIndex_player, hideLayerList);
			UTF16ToUTF8(png_player.c_str(), &utf8_png);
			UTF16ToUTF8(spriteIndex_player.c_str(), &utf8_spriteIndex);
			UTF16ToUTF8(p->ui->uiName.c_str(), &utf8_uiName);
			//写入绘制的图像
			elem_slotPlayer->SetAttribute("Slot_png", utf8_png.data());
			elem_slotPlayer->SetAttribute("Slot_spriteIndex", utf8_spriteIndex.data());
			elem_slotPlayer->SetAttribute("Slot_imageIndex", imageIndex_player);
			jumpFirst = true;
			numArr.clear();
			for (auto& i : hideLayerList)
			{
				if (jumpFirst)
				{
					numArr.append(std::to_string(i));
					jumpFirst = false;
				}
				else
				{
					numArr.push_back(',');
					numArr.append(std::to_string(i));
				}
			}
			elem_slotPlayer->SetAttribute("Slot_hideLayerList", numArr.c_str());
			//写入UI信息
			elem_slotPlayer->SetAttribute("Slot_HpMax", p->ui->HpMax);
			elem_slotPlayer->SetAttribute("Slot_Hp", p->ui->Hp);
			elem_slotPlayer->SetAttribute("Slot_MpMax", p->ui->MpMax);
			elem_slotPlayer->SetAttribute("Slot_Mp", p->ui->Mp);
			elem_slotPlayer->SetAttribute("Slot_UIName", utf8_uiName.data());
			elem_slotPlayer->SetAttribute("Slot_Sk1", p->ui->SkillArr[0]);
			elem_slotPlayer->SetAttribute("Slot_Sk2", p->ui->SkillArr[1]);
			elem_slotPlayer->SetAttribute("Slot_Sk3", p->ui->SkillArr[2]);
			elem_slotPlayer->SetAttribute("Slot_Sk4", p->ui->SkillArr[3]);
			elem_slotPlayer->SetAttribute("Slot_Sk5", p->ui->SkillArr[4]);
			elem_slotPlayer->SetAttribute("Slot_Sk6", p->ui->SkillArr[5]);
			jumpFirst = true;
			numArr.clear();
			for (auto& i : p->ui->throwItem)
			{
				if (jumpFirst)
				{
					numArr.append(std::to_string(i));
					jumpFirst = false;
				}
				else
				{
					numArr.push_back(',');
					numArr.append(std::to_string(i));
				}
			}
			elem_slotPlayer->SetAttribute("Slot_ThrowItem", numArr.c_str());
			elem_slot->InsertEndChild(elem_slotPlayer);
		}
	}
	xmlDoc.InsertEndChild(elem_slot);
	tinyxml2::XMLPrinter xmlPrinter;
	xmlDoc.Print(&xmlPrinter);
	if (saveData->size() < xmlPrinter.CStrSize())
		saveData->resize(xmlPrinter.CStrSize());
	strcpy_s(saveData->data(), saveData->size(), xmlPrinter.CStr());
}

void MyGame::LoadGame(const char* loadData)
{
	std::wstring mapfileName;
	std::wstring playersName[2];
	std::wstring musicname;
	bool musicPlaying = false;
	flagSet.clear();
	//载入游戏数据
	tinyxml2::XMLDocument xmlDoc;
	xmlDoc.Parse(loadData);
	std::vector<wchar_t> wbuff;
	std::vector<wchar_t> utf16_field;
	std::vector<wchar_t> utf16_value;
	std::vector<char> utf8;
	//设置游戏初始化
	Reset();
	//寻找Room元素
	tinyxml2::XMLElement* elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Room"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取Room元素
		UTF8ToUTF16(elem->Attribute("name"), &wbuff);
		mapfileName = wbuff.data();
	}
	//载入地图
	gameMap.LoadMap(mapfileName.c_str());
	//寻找Music元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Music"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取Music元素
		UTF8ToUTF16(elem->Attribute("name"), &wbuff);
		musicname = wbuff.data();
		musicPlaying = elem->BoolAttribute("playing");
	}
	//播放音乐
	if (musicPlaying && musicname.length())
	{
		pMusic.ChangeMusic(musicname.c_str());
	}
	//寻找Organya元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Organya"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取Organya元素
		UTF8ToUTF16(elem->Attribute("name"), &wbuff);
		musicname = wbuff.data();
		musicPlaying = elem->BoolAttribute("playing");
	}
	//播放音乐
	if (musicPlaying && musicname.length())
	{
		orgPlayer.ChangeMusic(musicname.c_str());
	}
	//寻找Flag元素（旧版存档）
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Flag"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取Flag元素
		for (tinyxml2::XMLElement* elem_flag = elem->FirstChildElement(); elem_flag; elem_flag = elem_flag->NextSiblingElement())
		{
			UTF8ToUTF16(elem_flag->Name(), &wbuff);
			flagSet.insert(wbuff.data());
		}
	}
	//寻找FlagStr元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "FlagStr"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取FlagStr元素
		for (tinyxml2::XMLElement* elem_flag = elem->FirstChildElement(); elem_flag; elem_flag = elem_flag->NextSiblingElement())
		{
			UTF8ToUTF16(elem_flag->GetText(), &wbuff);
			flagSet.insert(wbuff.data());
		}
	}
	//寻找Item元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Item"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取Item元素
		auto& itemList = *itemSystem.GetItemList();
		if (itemList.size() < 27)
			itemList.resize(27);
		int x = 0, y = 0;
		for (tinyxml2::XMLElement* elem_item = elem->FirstChildElement(); elem_item; elem_item = elem_item->NextSiblingElement())
		{
			UTF8ToUTF16(elem_item->Name(), &wbuff);
			auto num = elem_item->IntAttribute("num");
			if (num > 0)
			{
				if (y * 9 + x >= 27)
					break;
				ItemData& item = itemList[y * 9 + x];
				item.regID = wbuff.data();
				item.num = num;
			}
			x++;
			if (x > 8)
			{
				y++;
				x = 0;
			}
		}
	}
	//寻找Mission元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Mission"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取Mission元素
		for (tinyxml2::XMLElement* elem_mission = elem->FirstChildElement(); elem_mission; elem_mission = elem_mission->NextSiblingElement())
		{
			UTF8ToUTF16(elem_mission->Name(), &wbuff);
			itemSystem.AddMission(wbuff.data());
		}
	}
	//寻找Option元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Option"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取Option元素
		UTF8ToUTF16(elem->Attribute("gameName"), &wbuff);
		gameOption_gameName = wbuff.data();
		gameOption_playerNum = elem->IntAttribute("playerNum");
		gameOption_difficulty = elem->IntAttribute("difficulty");
	}
	//寻找GameVar元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "GameVar"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取GameVar元素
		enablePlayer2AISwitch = elem->BoolAttribute("enablePlayer2AISwitch", true);
	}
	//寻找GlobalEntity元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "GlobalEntity"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取GlobalEntity元素
		for (tinyxml2::XMLElement* pElemEntity = elem->FirstChildElement(); pElemEntity; pElemEntity = pElemEntity->NextSiblingElement())
		{
			UTF8ToUTF16(pElemEntity->Name(), &utf16_field);
			UTF8ToUTF16(pElemEntity->Attribute("PlayerIndex"), &utf16_value);
			std::wstring name = utf16_field.data();
			std::wstring playerIndex = utf16_value.data();
			entitySaveVar.clear();
			//遍历所有属性子元素
			for (tinyxml2::XMLElement* pTable = pElemEntity->FirstChildElement(); pTable; pTable = pTable->NextSiblingElement())
			{
				UTF8ToUTF16(pTable->Name(), &wbuff);
				entitySaveVar.insert(std::make_pair(wbuff.data(), std::unordered_map<std::wstring, std::wstring>()));
				auto& attr = entitySaveVar.at(wbuff.data());
				//读取Player数据
				for (auto p = pTable->FirstAttribute(); p; p = p->Next())
				{
					UTF8ToUTF16(p->Name(), &utf16_field);
					UTF8ToUTF16(p->Value(), &utf16_value);
					attr.insert(std::make_pair(utf16_field.data(), utf16_value.data()));
				}
			}
			//创建对应生成的实体
			auto we = GameCreateEntity(name.c_str());
			we->el.name = name;
			we->el.eid = playerIndex;
			we->gameFunc = &gameFunc;
			we->Init(we);
			we->LoadSaveData();//必须在Init之后，否则读不出技能
			globalEntity.push_back(we);
			if (playerIndex == L"player1")
			{
				//设置到玩家1的控制
				mychar_player1 = we;
				myCamera.SetTarget(mychar_player1);
			}
			else if (playerIndex == L"player2")
			{
				//设置到玩家2的控制
				mychar_player2 = we;
				myCamera.SetTarget2(mychar_player2);
			}
			//载入globalEntityID
			UTF8ToUTF16(pElemEntity->Attribute("GlobalEntityID"), &utf16_value);
			we->globalEntityID = utf16_value.data();
			globalEntityTable[we->globalEntityID] = we;
		}
	}
	//寻找Entity元素
	entitySaveVar.clear();
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Entity"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		for (auto elem_eid = elem->FirstChildElement(); elem_eid; elem_eid = elem_eid->NextSiblingElement())
		{
			UTF8ToUTF16(elem_eid->Name(), &wbuff);
			entitySaveVar.insert(std::make_pair(wbuff.data(), std::unordered_map<std::wstring, std::wstring>()));
			auto& EntityVar = entitySaveVar.at(wbuff.data());
			//读取Entity数据
			for (auto p = elem_eid->FirstAttribute(); p; p = p->Next())
			{
				UTF8ToUTF16(p->Name(), &utf16_field);
				UTF8ToUTF16(p->Value(), &utf16_value);
				EntityVar.insert(std::make_pair(utf16_field.data(), utf16_value.data()));
			}
		}
	}
	for (auto& layer : *gameMap.GetLayerList())
	{
		auto entityLayer = entityRes.LoadLayer(&layer);
		for (auto& we : entityLayer->Ls)
		{
			if (we->el.flag.save && we->el.eid.length())
				we->LoadSaveData();//实体读取自身数据
		}
	}
	//设置初始点亮
	gameFade.SetLight(true);
	//立即切换镜头
	myCamera.FocusOnce();
}

void MyGame::ReloadLanguage()
{
	gamePid.ReloadLanguage();
	gameMap.ReloadLanguage();
	entityRes.ReloadLanguage();
	itemSystem.ReloadLanguage();
}

void MyGame::ReloadGameMapScript()
{
	gameMap.ReloadGameMapScript();
}

void MyGame::SetGlobalEntity(std::shared_ptr<Entity> we, const wchar_t* globalEntityID)
{
	we->gameFunc = &gameFunc;
	we->globalEntityID = globalEntityID;
	globalEntity_addList.push_back(we);
	globalEntityTable[globalEntityID] = we;
}

std::weak_ptr<Entity> MyGame::GetGlobalEntity(const wchar_t* name)
{
	auto iter = globalEntityTable.find(name);
	if (iter == globalEntityTable.end())
		return std::weak_ptr<Entity>();
	return iter->second;
}

std::unordered_map<std::wstring, std::weak_ptr<Entity>>* MyGame::GetGlobalEntityTable()
{
	return &globalEntityTable;
}

int MyGame::GetPlayerIndex(std::weak_ptr<Entity> e)
{
	if (e.lock() && e.lock() == mychar_player1.lock())
		return 0;
	else if (e.lock() && e.lock() == mychar_player2.lock())
		return 1;
	return -1;
}

std::weak_ptr<Entity> MyGame::GetPlayerDistance(float x, float y)
{
	float r = D3D11_FLOAT32_MAX;
	std::weak_ptr<Entity> ret;
	for (auto& p : globalEntityTable)
	{
		auto we = p.second.lock();
		if (we)
		{
			if (we->el.name == L"null")
				continue;
			if (we->hide)
				continue;
			float dx = we->x - x;
			float dy = we->y - y;
			float sq = dx * dx + dy * dy;
			if (sq < r)
			{
				r = sq;
				ret = we;
			}
		}
	}
	return ret;
}

std::weak_ptr<Entity> MyGame::GetPlayerDistanceLR(float x, float y, int lr)
{
	float r = D3D11_FLOAT32_MAX;
	std::weak_ptr<Entity> ret;
	for (auto& p : globalEntityTable)
	{
		auto we = p.second.lock();
		if (we)
		{
			if (we->el.name == L"null")
				continue;
			if (we->hide)
				continue;
			if (lr == 0 && we->x > x)
				continue;
			if (lr == 1 && we->x < x)
				continue;
			float dx = we->x - x;
			float dy = we->y - y;
			float sq = dx * dx + dy * dy;
			if (sq < r)
			{
				r = sq;
				ret = we;
			}
		}
	}
	return ret;
}

std::weak_ptr<Entity> MyGame::GetPlayerDistanceWithLineTest(float x, float y)
{
	float r = D3D11_FLOAT32_MAX;
	std::weak_ptr<Entity> ret;
	for (auto& p : globalEntityTable)
	{
		auto we = p.second.lock();
		if (we)
		{
			if (we->el.name == L"null")
				continue;
			if (we->hide)
				continue;
			if (gameFunc.LineTest(we, x / 16, y / 16, we->x / 16, we->y / 16))
				continue;
			float dx = we->x - x;
			float dy = we->y - y;
			float sq = dx * dx + dy * dy;
			if (sq < r)
			{
				r = sq;
				ret = we;
			}
		}
	}
	return ret;
}

std::weak_ptr<Entity> MyGame::GetPlayerDistanceLRWithLineTest(float x, float y, int lr)
{
	float r = D3D11_FLOAT32_MAX;
	std::weak_ptr<Entity> ret;
	for (auto& p : globalEntityTable)
	{
		auto we = p.second.lock();
		if (we)
		{
			if (we->el.name == L"null")
				continue;
			if (we->hide)
				continue;
			if (lr == 0 && we->x > x)
				continue;
			if (lr == 1 && we->x < x)
				continue;
			if (gameFunc.LineTest(we, x / 16, y / 16, we->x / 16, we->y / 16))
				continue;
			float dx = we->x - x;
			float dy = we->y - y;
			float sq = dx * dx + dy * dy;
			if (sq < r)
			{
				r = sq;
				ret = we;
			}
		}
	}
	return ret;
}

std::weak_ptr<Entity> MyGame::GetCheckEventPlayer()
{
	if (checkEventPlayerIndex == 0)
		return mychar_player1;
	else
		return mychar_player2;
}

void MyGame::SetQuake(int times, int mode)
{
	myCamera.SetQuake(times, mode);
}

void MyGame::SetLocalCamera(std::weak_ptr<Entity> e, float focusTimes)
{
	myCamera.SetLocalCamera(e, focusTimes);
}

void MyGame::UnsetLocalCamera(std::weak_ptr<Entity> e)
{
	myCamera.UnsetLocalCamera(e);
}

void MyGame::EnableItemSystem(bool bEnable)
{
	itemSystem.SetEnable(bEnable);
}

void MyGame::LockAllPlayerJump()
{
	std::weak_ptr<Entity> players[2];
	players[0] = mychar_player1;
	players[1] = mychar_player2;
	for (auto i = 0; i < _countof(players); i++)
	{
		auto wplayer = players[i].lock();
		if (wplayer)
		{
			if (wplayer->cbRect.cbBottom)
				wplayer->inputLock.SetJump(true);
			wplayer->inputLock.SetOk(true);
		}
	}
	itemSystem.LockAllPlayerJump();
}

void MyGame::SaveAllPlayerPosition()
{
	positionSaver.clear();
	for (auto& p : globalEntityTable)
	{
		auto we = p.second.lock();
		if (we)
		{
			Entity e;
			e.x = we->x;
			e.y = we->y;
			e.last_x = we->last_x;
			e.last_y = we->last_y;
			e.globalEntityID = we->globalEntityID;
			positionSaver.push_back(e);
		}
	}
}

void MyGame::LoadAllPlayerPosition()
{
	if (positionSaver.empty())
		return;
	for (auto& p : globalEntityTable)
	{
		auto we = p.second.lock();
		if (we)
		{
			for (auto& posE : positionSaver)
			{
				if (posE.globalEntityID == we->globalEntityID)
				{
					we->x = posE.x;
					we->y = posE.y;
					we->last_x = posE.last_x;
					we->last_y = posE.last_y;
					break;
				}
			}
		}
	}
}

void MyGame::NoEnemyMode()
{
	bNoEnemyMode = true;
}

void MyGame::KillAllEnemy()
{
	bSetKillAllEnemy = true;
}

void MyGame::MoveAllPlayerToMousePos()
{
	bSetMoveAllPlayerToMousePos = true;
}

bool MyGame::InBossFight()
{
	return gameUI.GetBossHpBar()->InBossFight();
}

void MyGame::FullLight()
{
	gameMap.FullLight();
}

void MyGame::TryControlMousePosEntity()
{
	bSetTryControlMousePosEntity = true;
}

ScriptCmd* MyGame::GetCmd()
{
	return &scriptCmd;
}

void MyGame::PlayerCheckEvent()
{
	//如果事件正在运行则跳过
	if (gameScript.IsRunning())
		return;
	std::weak_ptr<Entity> players[2];
	players[0] = mychar_player1;
	players[1] = mychar_player2;
	for (auto i = 0; i < _countof(players); i++)
	{
		auto wplayer = players[i].lock();
		if (wplayer)
		{
			if (wplayer->el.name == L"null")
				continue;
			if (wplayer->enableAI)
				continue;
			GridPlayerCheckEvent(wplayer);
			if (gameScript.IsRunning())
				break;
			static bool canSetQuestionMarkArr[2] = { false };
			if (!wplayer->inCheckingEvent)
				canSetQuestionMarkArr[i] = true;
			//产生问号
			if (wplayer->inCheckingEvent && canSetQuestionMarkArr[i])
			{
				gameScript.SetCheckEntity(std::weak_ptr<Entity>());
				dmgNum.SetQuestionMark(wplayer->x, wplayer->y - 18);
				canSetQuestionMarkArr[i] = false;
			}
		}
	}
	
}

void MyGame::GridPlayerCheckEvent(std::weak_ptr<Entity> player)
{
	auto wplayer = player.lock();
	if (!wplayer->entityLayer)
		return;
	SDL_FRect qtRect;
	qtRect.x = wplayer->x - wplayer->cbRect.left;
	qtRect.y = wplayer->y - wplayer->cbRect.top;
	qtRect.w = wplayer->cbRect.left + wplayer->cbRect.right;
	qtRect.h = wplayer->cbRect.top + wplayer->cbRect.bottom;
	//使用和地图的相交矩形
	int* pMapW = nullptr;
	int* pMapH = nullptr;
	gameMap.GetMapSize(&pMapW, &pMapH);
	SDL_FRect sdlSrc, intersectRect;
	sdlSrc.x = 0;
	sdlSrc.y = 0;
	sdlSrc.w = *pMapW * 16.0f;
	sdlSrc.h = *pMapH * 16.0f;
	//计算相交矩形
	if (SDL_IntersectFRect(&sdlSrc, &qtRect, &intersectRect) == SDL_TRUE)
	{
		static std::vector<Entity*> quadTreeRes;
		quadTreeRes.clear();
		wplayer->entityLayer->quadTree->query((Rect<float>&)intersectRect, quadTreeRes);
		for (auto& e : quadTreeRes)
		{
			auto wdst = e->self.lock();
			if (wdst)
			{
				//接触触发
				if (wdst->el.flag.tTouch)
				{
					gameScript.SetCheckEntity(wdst);
					StartEvent(wdst->el.eventName.c_str(), L"tTouch");
					checkEventPlayerIndex = GetPlayerIndex(wplayer);
					break;
				}
				//调查触发
				if (wdst->el.flag.tCheck && wplayer->inCheckingEvent)
				{
					gameScript.SetCheckEntity(wdst);
					StartEvent(wdst->el.eventName.c_str(), L"tCheck");
					checkEventPlayerIndex = GetPlayerIndex(wplayer);
					break;
				}
			}
		}
	}
}

void MyGame::PlayerWaitStand()
{
	auto wmychar_player1 = mychar_player1.lock();
	auto wmychar_player2 = mychar_player2.lock();
	if (wmychar_player1 && wmychar_player2)
	{
		if (wmychar_player2->el.name == L"null")
		{
			if (wmychar_player1->cbRect.cbBottom)
				gameScript.SetWAS(false);
		}
		else
		{
			if (wmychar_player1->cbRect.cbBottom && wmychar_player2->cbRect.cbBottom)
				gameScript.SetWAS(false);
		}
	}
	else if (wmychar_player1)
	{
		if (wmychar_player1->cbRect.cbBottom)
			gameScript.SetWAS(false);
	}
}

void MyGame::DrawDark()
{
	if (mapSystem.GetShow() || itemSystem.GetShow())
	{
		MyRect rc;
		pRenderer->SetPenDraw();
		rc.Set1(0, 0, pView->window_w, pView->window_h);
		pRenderer->AddFillRect(&rc, RGBA(0, 0, 0, 0x80));
		pRenderer->DrawFillRect();
	}
}

void MyGame::Keyboard()
{
	auto wmychar_player1 = mychar_player1.lock();
	auto wmychar_player2 = mychar_player2.lock();
	auto wmychar_player1_menuKeyboard = mychar_player1_menuKeyboard.lock();
	auto wmychar_player2_menuKeyboard = mychar_player2_menuKeyboard.lock();

	if (wmychar_player1)
		wmychar_player1->enableAI = false;
	//玩家1角色操作
	if (player1ControllerType == 0)
	{
		if (wmychar_player1)
		{
			auto& lock = wmychar_player1->inputLock;
			for (int i = 0; i < 20; i++)
			{
				if ((lock.*GetKey[i])())
				{
					//如果该键锁住但没有按下，则释放锁
					if (!pInput->GetKeyBoardState(*is_p1k[i]))
						(lock.*SetKey[i])(false);
					(wmychar_player1->input.*SetKey[i])(false);
				}
				else
					(wmychar_player1->input.*SetKey[i])(pInput->GetKeyBoardState(*is_p1k[i]));
			}
		}
	}
	//玩家1菜单键盘
	if (wmychar_player1_menuKeyboard)
	{
		auto& lock = wmychar_player1_menuKeyboard->inputLock;
		for (int i = 0; i < 20; i++)
		{
			if ((lock.*GetKey[i])())
			{
				//如果该键锁住但没有按下，则释放锁
				if (!pInput->GetKeyBoardState(*is_p1k[i]))
					(lock.*SetKey[i])(false);
				(wmychar_player1_menuKeyboard->input.*SetKey[i])(false);
			}
			else
				(wmychar_player1_menuKeyboard->input.*SetKey[i])(pInput->GetKeyBoardState(*is_p1k[i]));
		}
	}
	//玩家2角色操作
	if (player2ControllerType == 0)
	{
		if (wmychar_player2)
		{
			auto& lock = wmychar_player2->inputLock;
			//全键接收
			for (int i = 0; i < 20; i++)
			{
				if (wmychar_player2->enableAI)
					i = 13;	//只接收13号切换角色键【切换AI控制】
				if ((lock.*GetKey[i])())
				{
					//如果该键锁住但没有按下，则释放锁
					if (!pInput->GetKeyBoardState(*is_p2k[i]))
						(lock.*SetKey[i])(false);
					(wmychar_player2->input.*SetKey[i])(false);
				}
				else
					(wmychar_player2->input.*SetKey[i])(pInput->GetKeyBoardState(*is_p2k[i]));
				if (wmychar_player2->enableAI)
					break;
			}
		}
	}
	//玩家2菜单键盘
	if (wmychar_player2_menuKeyboard)
	{
		auto& lock = wmychar_player2_menuKeyboard->inputLock;
		for (int i = 0; i < 20; i++)
		{
			if ((lock.*GetKey[i])())
			{
				//如果该键锁住但没有按下，则释放锁
				if (!pInput->GetKeyBoardState(*is_p2k[i]))
					(lock.*SetKey[i])(false);
				(wmychar_player2_menuKeyboard->input.*SetKey[i])(false);
			}
			else
				(wmychar_player2_menuKeyboard->input.*SetKey[i])(pInput->GetKeyBoardState(*is_p2k[i]));
		}
	}
}

void MyGame::Joystick()
{
	const float limitNum = 0.6f;
	auto wmychar_player1 = mychar_player1.lock();
	auto wmychar_player2 = mychar_player2.lock();
	//玩家1角色操作
	if (player1ControllerType == 1)
	{
		if (wmychar_player1)
		{
			auto& lock = wmychar_player1->inputLock;
			for (int i = 0; i < 20; i++)
			{
				bool bPress = pJoystickInput->GetState(inputSetting_player1Joystick.pGameController, is_p1j[i], &wmychar_player1->axis[i]);
				if ((lock.*GetKey[i])())
				{
					//如果该键锁住但没有按下，则释放锁
					if (is_p1j[i]->bindType == SDL_CONTROLLER_BINDTYPE_AXIS)
					{
						switch (i)
						{
						case 0://上
						case 2://左
						case 11://上一页
							if (!(wmychar_player1->axis[i] <= -limitNum))
								(lock.*SetKey[i])(false);
							break;
						case 1://下
						case 3://右
						case 12://下一页
							if (!(wmychar_player1->axis[i] >= limitNum))
								(lock.*SetKey[i])(false);
							break;
						default:
							if (!(abs(wmychar_player1->axis[i]) >= limitNum))
								(lock.*SetKey[i])(false);
							break;
						}
					}
					else if(!bPress)
						(lock.*SetKey[i])(false);
					(wmychar_player1->input.*SetKey[i])(false);
				}
				else
				{
					if (is_p1j[i]->bindType == SDL_CONTROLLER_BINDTYPE_AXIS)
					{
						switch (i)
						{
						case 0://上
						case 2://左
						case 11://上一页
							(wmychar_player1->input.*SetKey[i])(wmychar_player1->axis[i] <= -limitNum);
							break;
						case 1://下
						case 3://右
						case 12://下一页
							(wmychar_player1->input.*SetKey[i])(wmychar_player1->axis[i] >= limitNum);
							break;
						default:
							(wmychar_player1->input.*SetKey[i])(abs(wmychar_player1->axis[i]) >= limitNum);
							break;
						}
					}
					else
						(wmychar_player1->input.*SetKey[i])(bPress);
				}
			}
		}
	}
	//玩家2角色操作
	if (player2ControllerType == 1)
	{
		if (wmychar_player2)
		{
			auto& lock = wmychar_player2->inputLock;
			for (int i = 0; i < 20; i++)
			{
				if (wmychar_player2->enableAI)
					i = 13;//只接收13号切换角色键【切换AI控制】
				bool bPress = pJoystickInput->GetState(inputSetting_player2Joystick.pGameController, is_p1j[i], &wmychar_player2->axis[i]);
				if ((lock.*GetKey[i])())
				{
					//如果该键锁住但没有按下，则释放锁
					if (is_p2j[i]->bindType == SDL_CONTROLLER_BINDTYPE_AXIS)
					{
						switch (i)
						{
						case 0://上
						case 2://左
						case 11://上一页
							if (!(wmychar_player2->axis[i] <= -limitNum))
								(lock.*SetKey[i])(false);
							break;
						case 1://下
						case 3://右
						case 12://下一页
							if (!(wmychar_player2->axis[i] >= limitNum))
								(lock.*SetKey[i])(false);
							break;
						default:
							if (!(abs(wmychar_player2->axis[i]) >= limitNum))
								(lock.*SetKey[i])(false);
							break;
						}
					}
					else if (!bPress)
						(lock.*SetKey[i])(false);
					(wmychar_player2->input.*SetKey[i])(false);
				}
				else
				{
					if (is_p2j[i]->bindType == SDL_CONTROLLER_BINDTYPE_AXIS)
					{
						switch (i)
						{
						case 0://上
						case 2://左
						case 11://上一页
							(wmychar_player2->input.*SetKey[i])(wmychar_player2->axis[i] <= -limitNum);
							break;
						case 1://下
						case 3://右
						case 12://下一页
							(wmychar_player2->input.*SetKey[i])(wmychar_player2->axis[i] >= limitNum);
							break;
						default:
							(wmychar_player2->input.*SetKey[i])(abs(wmychar_player2->axis[i]) >= limitNum);
							break;
						}
					}
					else
						(wmychar_player2->input.*SetKey[i])(bPress);
				}
				if (wmychar_player2->enableAI)
					break;
			}
		}
	}
}

void MyGame::StepEntitySystem()
{
	if (bSetKillAllEnemy)
	{
		bSetKillAllEnemy = false;
		auto& res = *entityRes.GetLoadedEntity(&entityRes);
		for (auto& p : res)
		{
			if (p.first->layerType != 0)
				continue;
			for (auto& we : p.second.Ls)
			{
				int t;
				if (we->el.name.find(L"enemy") != std::wstring::npos)
					we->Hurt(std::weak_ptr<Entity>(), 9999, 0, false, 0, 0, 0, &t);
			}
			for (auto& we : p.second.Am)
			{
				int t;
				if (we->el.name.find(L"enemy") != std::wstring::npos)
					we->Hurt(std::weak_ptr<Entity>(), 9999, 0, false, 0, 0, 0, &t);
			}
			break;
		}
	}
	//运行实体
	for (auto& layer : *gameMap.GetLayerList())
	{
		if (layer.bLoad)
		{
			layer.bLoad = false;
			StepGlobalEntity(&layer, gamePxa.GetPxa(layer.pxaName.c_str()));
			//运行实体代码
			entityRes.SetCollisionEntityLayer(&layer, gamePxa.GetPxa(layer.pxaName.c_str()));
			entityRes.StepEntityLayer(&layer);
			continue;
		}
		if (!layer.visible)
			continue;
		StepGlobalEntity(&layer, gamePxa.GetPxa(layer.pxaName.c_str()));
		//运行实体代码
		entityRes.SetCollisionEntityLayer(&layer, gamePxa.GetPxa(layer.pxaName.c_str()));
		entityRes.StepEntityLayer(&layer);
	}
	//运行跳帧实体
	for (auto& layer : *gameMap.GetLayerList())
	{
		if (!layer.visible)
			continue;
		while (layer.jumpFrame_counter > 0)
		{
			bDisableSound = true;
			entityRes.StepEntityLayerPe(&layer);
			bDisableSound = false;
			layer.jumpFrame_counter--;
		}
		
	}
	if (bSetMoveAllPlayerToMousePos)
	{
		bSetMoveAllPlayerToMousePos = false;
		float x, y;
		entityRes.GetMousePos(&entityRes, &x, &y);
		for (auto& p : globalEntityTable)
		{
			auto we = p.second.lock();
			if (we)
			{
				we->last_x = we->x = x;
				we->last_y = we->y = y;
			}
		}
	}
	if (bSetTryControlMousePosEntity)
	{
		bSetTryControlMousePosEntity = false;
		float x, y;
		entityRes.GetMousePos(&entityRes, &x, &y);
		//寻找和这个点接触的玩家角色
		for (auto& e : globalEntity)
		{
			MyRect rc;
			rc.Set2(e->x - e->cbRect.left,
				e->x + e->cbRect.right,
				e->y - e->cbRect.top,
				e->y + e->cbRect.bottom);
			if (x >= rc.left && x <= rc.right &&
				y >= rc.top && y <= rc.bottom)
			{
				//将玩家1设置为这个对象
				mychar_player1 = e;
				break;
			}
		}
	}
}

void MyGame::DeltaTimeEntitySystem(float deltaTime)
{
	//运行实体
	for (auto& layer : *gameMap.GetLayerList())
	{
		if (!layer.visible)
			continue;
		//运行全局实体代码
		DeltaTimeGlobalEntity(&layer, deltaTime);
		//运行实体代码
		entityRes.DeltaTimeEntityLayer(&layer, deltaTime);
	}
}

void MyGame::StepGlobalEntity(MyMapLayer* pLayer, PxaData* pxaData)
{
	auto& layer = *pLayer;
	if (layer.layerType != 0)
		return;
	//运行全局实体
	for (auto& we : globalEntity)
	{
		//检查实体有没有被初始化
		EntityInitCheck(we);
		//设置变量
		we->cbRect.roomColor = layer.color;
		we->cbRect.pxmArr = &layer.pxmArr;
		we->cbRect.pxaArr = &pxaData->pxaArr;
		we->cbRect.updatedPxmArr = &pLayer->updatedPxmArr;
		we->cbRect.pxmArr_w = pLayer->pxmArr_w;
		we->cbRect.pxaArr_w = pxaData->pxaArr_w;
		we->cbRect.Collision = EntityRes::CollisionEntity;
		we->mapLayer = &layer;
		we->entityLayer = entityRes.LoadLayer(&layer);
		//从四叉树中移除
		entityRes.GridRemoveEntity(we);
		//强引用数量检查
		EntitySharedPtrCheck(we);
		//清理实体
		if (!we->inUsing)
		{
			//从表中移除
			globalEntityTable.erase(globalEntityTable.find(we->globalEntityID));
			continue;
		}
		if (we->hide)
			continue;
		if (we->initCollision)
		{
			we->initCollision = false;
			we->ClearCollisionResult();
			we->Collision();
		}
		//运行玩家代码
		we->Step();
		//在四叉树中插入
		entityRes.GridSetEntity(we);
		//运行玩家动画
		entityRes.EntityAniStep(we);
	}
	globalEntity.remove_if([&](std::shared_ptr<Entity>& we)
	{
		if (!we->inUsing)
		{
			//检查实体有没有被初始化
			EntityInitCheck(we);
			//设置变量
			we->cbRect.roomColor = layer.color;
			we->cbRect.pxmArr = &layer.pxmArr;
			we->cbRect.pxaArr = &pxaData->pxaArr;
			we->cbRect.updatedPxmArr = &pLayer->updatedPxmArr;
			we->cbRect.pxmArr_w = pLayer->pxmArr_w;
			we->cbRect.pxaArr_w = pxaData->pxaArr_w;
			we->cbRect.Collision = EntityRes::CollisionEntity;
			we->mapLayer = &layer;
			we->entityLayer = entityRes.LoadLayer(&layer);
			//从四叉树中移除
			entityRes.GridRemoveEntity(we);
			//强引用数量检查
			EntitySharedPtrCheck(we);
		}
		return !we->inUsing;
	});
	//解除脚本WAS暂停
	PlayerWaitStand();
	while (!globalEntity_addList.empty())
	{
		globalEntity.push_back(globalEntity_addList.back());
		globalEntity_addList.pop_back();
	}
}

void MyGame::DeltaTimeGlobalEntity(MyMapLayer* pLayer, float deltaTime)
{
	auto& layer = *pLayer;
	if (layer.layerType != 0)
		return;
	//运行全局实体的DeltaTime函数
	for (auto& we : globalEntity)
		we->DeltaTime(deltaTime);
}

void MyGame::SwitchPlayerStep()
{
	//如果事件正在运行则跳过
	if (gameScript.IsRunning() && !bChildGame)
		return;
	//给所有全局实体设置ai
	for (auto& wplayer : globalEntity)
	{
		if (wplayer->enableAI)
		{
			auto wai = wplayer->ai.lock();
			if (!wai)
			{
				wai = GameCreateEntity(wplayer->aiName.c_str());
				wplayer->ai = wai;
				if (wai && wai->el.name != L"null")
					gameFunc.SetEntity(wplayer, wai);
				else
					wplayer->enableAI = false;

			}
		}
	}
	auto wplayer1 = mychar_player1.lock();
	auto wplayer2 = mychar_player2.lock();
	if (wplayer2 && wplayer2->el.name == L"null")
		return;
	//物品栏在工作时则跳过
	if (!itemSystem.IsItemSystemFree())
		return;
	//玩家2切换AI控制
	bool bSwitch = false;
	if (enablePlayer2AISwitch)
	{
		if (wplayer2)
		{
			if (wplayer2->input.GetSwitchMc())
			{
				wplayer2->inputLock.SetSwitchMc(true);
				if (wplayer2->enableAI)
				{
					//关闭AI
					wplayer2->enableAI = false;
					auto wai = wplayer2->ai.lock();
					if (wai)
					{
						wai->Destroy();
						wplayer2->ai.reset();
						bSwitch = true;
					}
					gameOption_playerNum = 2;
					//显示玩家2 下标
					auto player2Index = GameCreateEntity(L"sys_playerindex");
					player2Index->lr = 1;
					gameFunc.SetEntity(wplayer2, player2Index);
				}
				else
				{
					//打开AI
					wplayer2->enableAI = true;
					bSwitch = true;
					gameOption_playerNum = 1;
				}
			}
		}
	}
	if (wplayer1 && wplayer2)
	{
		if (wplayer1->input.GetSwitchMc())
		{
			wplayer1->inputLock.SetSwitchMc(true);
			wplayer2->inputLock.SetSwitchMc(true);
			SwapPlayer();
		}
	}
	//立即更新物品栏
	if (bSwitch && itemSystem.GetShow())
	{
		itemSystem.Step();
		itemSystem.Step();
	}
}

void MyGame::SwapPlayer()
{
	std::weak_ptr<Entity> temp = mychar_player1;
	mychar_player1 = mychar_player2;
	mychar_player2 = temp;
	auto wplayer1 = mychar_player1.lock();
	auto wplayer2 = mychar_player2.lock();
	//释放玩家1的AI
	if (wplayer1 && wplayer2)
	{
		auto wai = wplayer1->ai.lock();
		if (wai)
		{
			wai->Destroy();
			wplayer1->ai.reset();
		}
		if (wplayer1->enableAI)
		{
			wplayer2->enableAI = true;
			wplayer1->enableAI = false;
		}
	}
	//交换目标
	myCamera.SwapTarget();
	//交换UI
	gameUI.Swap();
	//创建玩家下标
	auto player1Index = GameCreateEntity(L"sys_playerindex");
	player1Index->lr = 0;
	gameFunc.SetEntity(wplayer1, player1Index);
	if (!wplayer2->enableAI)
	{
		auto player2Index = GameCreateEntity(L"sys_playerindex");
		player2Index->lr = 1;
		gameFunc.SetEntity(wplayer2, player2Index);
	}
}

void MyGame::ClearEnemy()
{
	auto& srcLayer = *gameMap.GetLayerList();
	std::vector<EntityLoad>* elLayer = nullptr;
	for (auto& l : srcLayer)
	{
		if (l.layerType != 0)
			continue;
		elLayer = &l.step_pxe;
		break;
	}
	if (elLayer)
	{
		for (auto& el : *elLayer)
			if (el.name.find(L"enemy") != std::wstring::npos)
				el.name = L"null";
	}
}
