diff -uwrN sourceold/scripts/DBIKScripts.cpp source/scripts/DBIKScripts.cpp
--- sourceold/scripts/DBIKScripts.cpp	2017-01-27 11:21:46.465017100 +1000
+++ source/scripts/DBIKScripts.cpp	2017-02-16 06:25:31.818200800 +1000
@@ -129,13 +129,15 @@
 {
 	HomePosition = Commands->Get_Position(obj);
 	Commands->Set_Innate_Soldier_Home_Location(obj,HomePosition,70);
+	/*
 	Commands->Innate_Soldier_Enable_Footsteps_Heard(obj,false);
 	Commands->Innate_Soldier_Enable_Gunshot_Heard(obj,false);
 	Commands->Innate_Soldier_Enable_Bullet_Heard(obj,false);
+	*/
 	if(obj->As_SoldierGameObj())
 	{
+		Attach_Script_Once(obj,"DB_Innate_Soldier","0.5,70,0,0");
 		Commands->Start_Timer(obj,this,Commands->Get_Random(0,10),87);
-		Update_Network_Object(obj);
 		Set_Current_Clip_Bullets(obj,-1);
 	}
 }
@@ -212,6 +214,7 @@
 void DB_Support_Bot::Created(GameObject *obj)
 {
 	followid=0;
+	Attach_Script_Once(obj,"DB_Innate_Soldier","0.5,0,0,0");
 	Commands->Enable_HUD_Pokable_Indicator(obj,1);
 	Commands->Start_Timer(obj,this,5.0f,1);
 }
diff -uwrN sourceold/scripts/DB_Innate.cpp source/scripts/DB_Innate.cpp
--- sourceold/scripts/DB_Innate.cpp	1970-01-01 10:00:00.000000000 +1000
+++ source/scripts/DB_Innate.cpp	2017-02-16 06:25:31.819200800 +1000
@@ -0,0 +1,941 @@
+#include "General.h"
+#include "DB_Innate.h"
+#include "wwmath.h"
+#include "SimplePersistFactoryClass.h"
+#include "SoldierGameObj.h"
+#include "CombatManager.h"
+#include "soldiergameobjdef.h"
+#include "WeaponBagClass.h"
+#include "Random2Class.h"
+#include "GameObjManager.h"
+#include "WeaponClass.h"
+#include "engine_tt.h"
+#include "PhysicsSceneClass.h"
+#include "physcoltest.h"
+
+/*
+Full replacement for the stock Innate Behavior AI that has many improvements including dealing with
+enemies behind cover. It also will move and strafe much more often to avoid enemy shots. It should
+work as a drop in replacement for most scripts that rely on the original Innate AI as well.
+*/
+
+typedef enum {
+	SOLDIER_INNATE_EVENT_ENEMY_SEEN 		=	1 << 0,
+	SOLDIER_INNATE_EVENT_FOOTSTEP_HEARD	=	1 << 1,
+	SOLDIER_INNATE_EVENT_GUNSHOT_HEARD	=	1 << 2,
+	SOLDIER_INNATE_EVENT_BULLET_HEARD 	=	1 << 3,
+	SOLDIER_INNATE_ACTIONS					=	1 << 4,
+} SoldierInnateEvents;
+
+Vector3 Random_Vector(float f)
+{
+	float f3 = -f;
+	float f4 = f;
+	if (f3 > f)
+	{
+		f4 = -f;
+		f3 = f;
+	}
+	float f5 = -f;
+	float f6 = f;
+	if (f5 > f)
+	{
+		f6 = -f;
+		f5 = f;
+	}
+	return Vector3(FreeRandom.Get_Float(f5,f6),FreeRandom.Get_Float(f3,f4),0);
+
+}
+
+//Check if the position has a vantage point of the enemy object. Used to determine if it should select this location
+bool Can_Position_Target_Object(PhysicalGameObj* attacker,Vector3 attackPosition,PhysicalGameObj* target)
+{
+	const Vector3 bullseyePosition = target->Get_Bullseye_Position();
+	attackPosition.Z+=1.0;
+	
+	CastResultStruct castResult;
+	PhysRayCollisionTestClass collisionTest(LineSegClass(attackPosition, bullseyePosition), &castResult, BULLET_COLLISION_GROUP);
+	
+	target->Peek_Physical_Object()->Inc_Ignore_Counter();
+	PhysicsSceneClass::Get_Instance()->Cast_Ray(collisionTest, false);
+	target->Peek_Physical_Object()->Dec_Ignore_Counter();
+	
+	return
+		castResult.Fraction == 1.f ||
+		collisionTest.CollidedPhysObj == target->Peek_Physical_Object();
+}
+
+DB_Innate_Soldier::DB_Innate_Soldier() : State(1), StateTimer(0), HomeFacing(9999999), ActTime(0), UseWeapon(0), Aggressiveness(0.5), TakeCoverProbability(0.5), IsStationary(false), LastState(0), Weapon(0), ConversationTimer(((WWMath::Random_Float() * 9.0f) + 1.0f))
+{
+}
+DB_Innate_Soldier::~DB_Innate_Soldier()
+{
+	Destroyed(0);
+	Target = 0;
+}
+
+bool DB_Innate_Soldier::Save(ChunkSaveClass &csave)
+{
+	csave.Begin_Chunk(410001836);
+	csave.End_Chunk();
+		csave.Begin_Chunk(410001837);
+		WRITE_MICRO_CHUNK(csave,1,State);
+		WRITE_MICRO_CHUNK(csave,2,StateTimer);
+		WRITE_MICRO_CHUNK(csave,3,HomeLocation);
+		WRITE_MICRO_CHUNK(csave,10,HomeFacing);
+		WRITE_MICRO_CHUNK(csave,4,Position);
+		WRITE_MICRO_CHUNK(csave,5,ActTime);
+		WRITE_MICRO_CHUNK(csave,9,Cover);
+		WRITE_MICRO_CHUNK(csave,12,ConversationTimer);
+		WRITE_MICRO_CHUNK(csave,13,UseWeapon);
+		WRITE_MICRO_CHUNK(csave,14,Aggressiveness);
+		WRITE_MICRO_CHUNK(csave,15,TakeCoverProbability);
+		WRITE_MICRO_CHUNK(csave,16,IsStationary);
+		WRITE_MICRO_CHUNK(csave,17,Weapon);
+		csave.End_Chunk();
+		if (Target)
+		{
+			csave.Begin_Chunk(410001838);
+			Target->Save(csave);
+			csave.End_Chunk();
+		}
+	return true;
+}
+bool DB_Innate_Soldier::Load(ChunkLoadClass &cload)
+{
+	while (cload.Open_Chunk()) {
+		switch(cload.Cur_Chunk_ID()) {
+		case 410001837:
+			while (cload.Open_Micro_Chunk()) {
+				switch(cload.Cur_Micro_Chunk_ID()) {
+					READ_MICRO_CHUNK(cload,1,State);
+					READ_MICRO_CHUNK(cload,2,StateTimer);
+					READ_MICRO_CHUNK(cload,3,HomeLocation);
+					READ_MICRO_CHUNK(cload,10,HomeFacing);
+					READ_MICRO_CHUNK(cload,4,Position);
+					READ_MICRO_CHUNK(cload,5,ActTime);
+					READ_MICRO_CHUNK(cload,9,Cover);
+					READ_MICRO_CHUNK(cload,12,ConversationTimer);
+					READ_MICRO_CHUNK(cload,13,UseWeapon);
+					READ_MICRO_CHUNK(cload,14,Aggressiveness);
+					READ_MICRO_CHUNK(cload,15,TakeCoverProbability);
+					READ_MICRO_CHUNK(cload,16,IsStationary);
+					READ_MICRO_CHUNK(cload,17,Weapon);
+				}
+				cload.Close_Micro_Chunk();
+			}
+			break;
+		case 410001838:
+			Target->Load(cload);
+			break;
+		}
+		cload.Close_Chunk();
+	}
+	return true;
+}
+
+char *SoldierAIStateNames[6] = {"Relaxed Idle","Alert Idle","Footsteps Heard","Bullet Heard","Gunshot Heard","Enemy Seen"};
+void DB_Innate_Soldier::Created(GameObject *obj)
+{
+	Debug = Get_Int_Parameter("Debug")!=0;
+	if(!obj->As_SoldierGameObj())
+	{
+		Destroy_Script();
+		return;
+	}
+	SmartGameObj *Smart = obj->As_SmartGameObj();
+	Smart->Get_Position(&HomeLocation);
+	Smart->Set_Enemy_Seen_Enabled(true);
+	Commands->Start_Timer(obj,this, 1.0f, 100123);
+	Commands->Innate_Enable(obj);
+	Commands->Innate_Soldier_Enable_Bullet_Heard(obj,true);
+	Commands->Innate_Soldier_Enable_Gunshot_Heard(obj,true);
+	Commands->Innate_Soldier_Enable_Footsteps_Heard(obj,true);
+	SoldierGameObj *Soldier = Smart->As_SoldierGameObj();
+	if(Soldier)
+	{
+		Soldier->Set_Override_Muzzle_Direction(true);
+		Aggressiveness =  Get_Float_Parameter("Aggressiveness");
+		float HomeRange =  Get_Float_Parameter("HomeRange");
+		if(HomeRange > 0)
+		{
+			Set_Home_Location(Soldier->Get_Position(),HomeRange);
+		}
+		IsStationary = (int)Get_Int_Parameter("Stationary")!=0;
+		GameObjObserverClass *InnateObserver = Soldier->Find_Observer("Innate Soldier");
+		if(InnateObserver)
+		{
+			Soldier->Remove_Observer(InnateObserver);
+			Soldier->Set_Innate_Observer(NULL);
+		}
+	}
+}
+void DB_Innate_Soldier::Destroyed(GameObject *obj)
+{
+	;
+}
+void DB_Innate_Soldier::Timer_Expired(GameObject *obj,int number)
+{
+	if (number == 100123)
+	{
+		Commands->Start_Timer(obj, this, 1.0f, 100123);
+		Think_Function(obj->As_SoldierGameObj(),false);
+	}
+}
+void DB_Innate_Soldier::Killed(GameObject *obj,GameObject *killer)
+{
+}
+void DB_Innate_Soldier::Damaged(GameObject *obj,GameObject *damager,float amount)
+{
+	if (!obj->Is_Hibernating())
+	{
+		SoldierGameObj *sobj = obj->As_SoldierGameObj();
+		if (sobj->Is_Innate_Enabled(SOLDIER_INNATE_EVENT_BULLET_HEARD))
+		{
+			Vector3 position;
+			sobj->Get_Position(&position);
+			if (damager)// && FreeRandom.Get_Float() <0.8f)
+			{
+				damager->Get_Position(&position);
+				if (sobj->Is_Enemy(damager->As_DamageableGameObj()) && damager!=Target && Commands->Get_Health(damager)>0)
+					Enemy_Seen(obj,damager);
+					//Set_State(sobj, GUNSHOT_HEARD, position, 0);
+				else if(State < BULLET_HEARD)
+					Set_State(sobj, BULLET_HEARD, position, 0);
+			}
+		}
+		if (State == ENEMY_SEEN)
+		{
+			ScriptableGameObj *target = Target;
+			if (damager && target != damager)
+			{
+				Vector3 position1;
+				sobj->Get_Position(&position1);
+				float f1 = 1000000;
+				if (target)
+				{
+					Vector3 position2;
+					target->Get_Position(&position2);
+					f1 = (position2 - position1).Length();
+				}
+				Vector3 position3;
+				damager->Get_Position(&position3);
+				if ((position3 - position1).Length() < f1)
+				{
+					PhysicalGameObj *pobj = damager->As_PhysicalGameObj();
+					if (pobj)
+					{
+						if (pobj->Is_Enemy(sobj))
+						{
+							Target = damager;
+							ActTime = 0;
+						}
+					}
+				}
+			}
+		}
+	}
+}
+void DB_Innate_Soldier::Sound_Heard(GameObject *obj,const CombatSound & sound)
+{
+	if (!obj->Is_Hibernating())
+	{
+		SoldierGameObj *sobj = obj->As_SoldierGameObj();
+		PhysicalGameObj *pobj = 0;
+		if (sound.Creator)
+		{
+			pobj = sound.Creator->As_PhysicalGameObj();
+		}
+		if (sound.sound == SOUND_TYPE_FOOTSTEPS)
+		{
+			if (pobj && (sobj->Is_Teammate(pobj) || !sobj->Is_Innate_Enabled(SOLDIER_INNATE_EVENT_FOOTSTEP_HEARD)))
+			{
+				return;
+			}
+			if (Set_State(sobj,FOOTSTEPS_HEARD,sound.Position,0))
+			{
+				Notify_Neighbors_Sound(sobj,sound);
+			}
+			return;
+		}
+		if (sound.sound == SOUND_TYPE_GUNSHOT)
+		{
+			if (pobj && (sobj->Is_Teammate(pobj) || !sobj->Is_Innate_Enabled(SOLDIER_INNATE_EVENT_GUNSHOT_HEARD)))
+			{
+				return;
+			}
+			if (Set_State(sobj,GUNSHOT_HEARD,sound.Position,0))
+			{
+				Notify_Neighbors_Sound(sobj,sound);
+			}
+			return;
+		}
+		if (sound.sound == SOUND_TYPE_BULLET_HIT)
+		{
+			Vector3 pos = sound.Position;
+			if (pobj && FreeRandom.Get_Float() < 0.7)
+			{
+				pobj->Get_Position(&pos);
+			}
+			if (Set_State(sobj,BULLET_HEARD,pos,0))
+			{
+				Notify_Neighbors_Sound(sobj,sound);
+			}
+		}
+	}
+}
+void DB_Innate_Soldier::Enemy_Seen(GameObject *obj,GameObject *enemy)
+{
+	if (!obj->Is_Hibernating())
+	{
+		PhysicalGameObj *pobj = obj->As_PhysicalGameObj();
+		if (pobj)
+		{
+			if (pobj->Get_Defense_Object()->Get_Health() > 0)
+			{
+				if((ScriptableGameObj*)Target && Commands->Get_Health(Target)<=0)
+					Target = 0;
+				ScriptableGameObj *target = Target;
+				Vector3 targetpos;
+				Vector3 seenpos;
+				Vector3 objpos;
+
+				if (!target || target == enemy || (target->Get_Position(&targetpos),enemy->Get_Position(&seenpos),obj->Get_Position(&objpos),((seenpos - objpos).Length2() <= (targetpos - objpos).Length2())))
+				{
+					SoldierGameObj *sobj = obj->As_SoldierGameObj();
+					bool state = false;
+					if (sobj->Is_Innate_Enabled(1))
+					{
+						state = Set_State(sobj,ENEMY_SEEN,Vector3(0,0,0),enemy);
+					}
+					if (state)
+					{
+						Notify_Neighbors_Enemy(sobj,enemy);
+					}
+				}
+			}
+		}
+	}
+}
+void DB_Innate_Soldier::Custom(GameObject *obj,int type,int param,GameObject *sender)
+{
+}
+void DB_Innate_Soldier::Action_Complete(GameObject *obj,int action_id,ActionCompleteReason complete_reason)
+{
+	if (action_id == 9000000)
+	{
+		SubState += "\nComplete";
+		ScriptableGameObj *target = Target;
+		if (target && State == ENEMY_SEEN && ((DamageableGameObj *)target)->Get_Defense_Object()->Get_Health() <= 0)
+		{
+			StateTimer = 100000;
+			Target = 0;
+		}
+		if (complete_reason && complete_reason != ACTION_COMPLETE_PATH_BAD_START)
+		{
+			if (complete_reason != ACTION_COMPLETE_PATH_BAD_DEST)
+			{
+				return;
+			}
+		}
+		else
+		{
+			if (complete_reason != ACTION_COMPLETE_PATH_BAD_DEST)
+			{
+				float f1 = WWMath::Random_Float() + 2.0f;
+				float f2 = ActTime;
+				if (f1 <= f2)
+				{
+					f2 = WWMath::Random_Float() + 2.0f;
+				}
+				ActTime = f2;
+				if (State > BULLET_HEARD)
+				{
+					StateTimer = 100000;
+				}
+			}
+		}
+		float f1 = WWMath::Random_Float() + 1.0f;
+		float f2 = ActTime;
+		if (f1 <= f2)
+		{
+			f2 = WWMath::Random_Float() + 1.0f;
+		}
+		ActTime = f2;
+		if (State > BULLET_HEARD)
+		{
+			StateTimer = 100000;
+		}
+	}
+}
+void DB_Innate_Soldier::State_Changed(SoldierGameObj *obj)
+{
+	if (State <= ENEMY_SEEN)
+	{
+		switch (State)
+		{
+		case RELAXED_IDLE:
+			UseWeapon = false;
+			break;
+		case ALERT_IDLE:
+		case BULLET_HEARD:
+		case GUNSHOT_HEARD:
+		case ENEMY_SEEN:
+			UseWeapon = true;
+			break;
+		case FOOTSTEPS_HEARD:
+			break;
+		}
+	}
+	if (obj->Get_Weapon_Bag()->Get_Index())
+	{
+		Weapon = obj->Get_Weapon_Bag()->Get_Weapon()->Get_Name();
+	}
+	if (UseWeapon)
+	{
+		Commands->Select_Weapon(obj,Weapon);
+	}
+	else
+	{
+		Commands->Select_Weapon(obj,"None");
+	}
+	ActTime = 0;
+}
+
+int StatePriorities[6] = {10,20,50,50,70,90};
+bool DB_Innate_Soldier::Set_State(SoldierGameObj *obj, int state, Vector3 const &pos, ScriptableGameObj *target)
+{
+	LastState = state;
+	int oldstate = State;
+	
+	if (StatePriorities[oldstate] < StatePriorities[state])
+	{
+		Position = pos;
+		/*
+		if (State != state)
+		{
+			State = state;
+			State_Changed(obj);
+		}
+		*/
+	}
+	
+	if (StatePriorities[State] <= StatePriorities[state])
+	{
+		if (State != state)
+		{
+			if(Debug)
+				Send_Message(225,255,255,StringClass::getFormattedString("%s -> %s",SoldierAIStateNames[State],SoldierAIStateNames[state]));
+
+			State = state;
+			State_Changed(obj);
+		}
+		StateTimer = 0;
+		if (((State == BULLET_HEARD) || (State == GUNSHOT_HEARD) || (State == ENEMY_SEEN && state < ENEMY_SEEN)) && ActTime > 1)
+		{
+			ActTime = 1;
+		}
+		Vector3 position;
+		obj->Get_Position(&position);
+		if ((Position - position).Length2() > (pos - position).Length2())
+		{
+			Position = pos;
+		}
+		PhysicalGameObj *pobj = 0;
+		if (target)
+		{
+			pobj = target->As_PhysicalGameObj();
+		}
+		Target = pobj;
+		Think_Function(obj,State != oldstate);
+	}
+	if (oldstate != State)
+	{
+		if (state == ENEMY_SEEN)
+		{
+			ConversationTimer = WWMath::Random_Float() * 25.0f + 5.0f;
+		}
+		else
+		{
+			ConversationTimer = WWMath::Random_Float() * 40.0f + 20.0f;
+		}
+	}
+	if (oldstate && oldstate != ALERT_IDLE)
+	{
+		if (oldstate == ENEMY_SEEN)
+		{
+			if (State == FOOTSTEPS_HEARD || State == BULLET_HEARD || State == GUNSHOT_HEARD)
+			{
+				//obj->Say_Dialogue(DIALOG_ON_COMBAT_TO_SEARCH);
+			}
+		}
+		else if (State == ENEMY_SEEN)
+		{
+			//obj->Say_Dialogue(DIALOG_ON_SEARCH_TO_COMBAT);
+		}
+	}
+	else
+	{
+		if (State == FOOTSTEPS_HEARD || State == BULLET_HEARD || State == GUNSHOT_HEARD)
+		{
+			//obj->Say_Dialogue(DIALOG_ON_IDLE_TO_SEARCH);
+		}
+		if (State == ENEMY_SEEN)
+		{
+			//obj->Say_Dialogue(DIALOG_ON_IDLE_TO_COMBAT);
+		}
+	}
+	return oldstate != State;
+}
+void DB_Innate_Soldier::Notify_Neighbors_Sound(SoldierGameObj *obj, CombatSound const &sound)
+{
+	Vector3 pos;
+	obj->Get_Position(&pos);
+	for (SLNode<SmartGameObj> *z = GameObjManager::SmartGameObjList.Head();z;z = z->Next())
+	{
+		SmartGameObj* o = z->Data();
+		if (o)
+		{
+			if (o != obj)
+			{
+#pragma warning(suppress: 6011)
+				if (o->Get_Player_Type() == obj->Get_Player_Type())
+				{
+					Vector3 pos2;
+					o->Get_Position(&pos2);
+					pos2 = pos2 - pos;
+					if (pos2.Length() <= 10)
+					{
+						const SimpleDynVecClass<GameObjObserverClass *> & observer_list = o->Get_Observers();
+						for( int index = 0; index < observer_list.Count(); index++ )
+						{
+							observer_list[ index ]->Sound_Heard(o,sound);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+void DB_Innate_Soldier::Notify_Neighbors_Enemy(SoldierGameObj *obj, ScriptableGameObj *enemy)
+{
+	Vector3 pos;
+	obj->Get_Position(&pos);
+	for (SLNode<SmartGameObj> *z = GameObjManager::SmartGameObjList.Head();z;z = z->Next())
+	{
+		SmartGameObj* o = z->Data();
+		if (o)
+		{
+			if (o != obj)
+			{
+#pragma warning(suppress: 6011)
+				if (o->Get_Player_Type() == obj->Get_Player_Type())
+				{
+					Vector3 pos2;
+					o->Get_Position(&pos2);
+					pos2 = pos2 - pos;
+					if (pos2.Length() <= 10)
+					{
+						const SimpleDynVecClass<GameObjObserverClass *> & observer_list = o->Get_Observers();
+						for( int index = 0; index < observer_list.Count(); index++ )
+						{
+							observer_list[ index ]->Enemy_Seen(o,enemy);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+void DB_Innate_Soldier::Poked(GameObject *obj,GameObject *poker)
+{
+	if (obj)
+	{
+		PhysicalGameObj *pobj = obj->As_PhysicalGameObj();
+		if (pobj)
+		{
+			SoldierGameObj *sobj = pobj->As_SoldierGameObj();
+			if (sobj)
+			{
+				bool face = false;
+				if (State <= ENEMY_SEEN)
+				{
+					switch(State)
+					{
+					case RELAXED_IDLE:
+					case ALERT_IDLE:
+						//sobj->Say_Dialogue(DIALOG_ON_POKE_IDLE);
+						face = true;
+						break;
+					case FOOTSTEPS_HEARD:
+					case BULLET_HEARD:
+					case GUNSHOT_HEARD:
+						//sobj->Say_Dialogue(DIALOG_ON_POKE_SEARCH);
+						face = true;
+						break;
+					case ENEMY_SEEN:
+						//sobj->Say_Dialogue(DIALOG_ON_POKE_COMBAT);
+						break;
+					}
+				}
+				float duration = WWMath::Random_Float() * 1.5f + 0.5f + (float)2.0f;
+				PhysicalGameObj *pobj2 = poker->As_PhysicalGameObj();
+				if (pobj2)
+				{
+					Vector3 pos = pobj2->Get_Bullseye_Position();
+					if (face)
+					{
+						ActionParamsStruct params;
+						params.Set_Basic(Get_ID(),20,0);
+						params.Set_Face_Location(pos,duration);
+						Commands->Action_Face_Location(obj,params);
+					}
+				}
+			}
+		}
+	}
+}
+struct StateDataStr
+{
+	float timer;
+	int state;
+};
+StateDataStr StateData[6] = {{9999,0},{180,0},{6,1},{20,1},{4,3},{60,1}};
+void DB_Innate_Soldier::Think_Function(SoldierGameObj *obj, bool b)
+{
+	StateTimer += 1;
+	if (StateTimer >= StateData[State].timer)
+	{
+		Action_Reset(obj);
+		if(Debug)
+			Send_Message(225,255,255,StringClass::getFormattedString("%s -> %s",SoldierAIStateNames[State],SoldierAIStateNames[StateData[State].state]));
+		State = StateData[State].state;
+		State_Changed(obj);
+		StateTimer = 0;
+	}
+	if (obj->Is_Innate_Enabled(0x10))
+	{
+		ActTime -= 1;
+		if (ActTime <= 0 && !obj->Is_In_Elevator() && !obj->Is_On_Ladder())
+		{
+			State_Act(obj,b);
+		}
+	}
+	if (!obj->Is_Human_Controlled() && (!obj->Is_In_Conversation()))
+	{
+		ConversationTimer -= 1;
+		if (ConversationTimer <= 0)
+		{
+			Reset_Conversation_Timer();
+		}
+	}
+}
+
+void DB_Innate_Soldier::Get_Information(StringClass &string)
+{
+	StringClass temp;
+	string += "-----------\n";
+	temp.Format("State: %s\n",SoldierAIStateNames[State]);
+	string += temp;
+	temp.Format("Sub: %s\n",SubState);
+	string += temp;
+	if (IsStationary)
+	{
+		string += "Stationary\n";
+	}
+	if (State == ENEMY_SEEN)
+	{
+		int id = 0;
+		if (Target)
+		{
+			id = Target->Get_Network_ID();
+		}
+		temp.Format("Attacking: %d\n",id);
+		string += temp;
+	}
+	temp.Format("Last: %s\n",SoldierAIStateNames[LastState]);
+	string += temp;
+	temp.Format("Act Time: %f\n",ActTime);
+	string += temp;
+}
+void DB_Innate_Soldier::Reset_Conversation_Timer()
+{
+	ConversationTimer = WWMath::Random_Float() * 40.0f + 20.0f;
+}
+void DB_Innate_Soldier::State_Act(SoldierGameObj *obj, bool b)
+{
+	if (State <= ENEMY_SEEN)
+	{
+		switch(State)
+		{
+		case RELAXED_IDLE:
+			State_Act_Idle(obj);
+			break;
+		case ALERT_IDLE:
+			State_Act_Idle(obj);
+			break;
+		case BULLET_HEARD:
+			State_Act_Bullet_Heard(obj,b);
+			break;
+		case FOOTSTEPS_HEARD:
+			State_Act_Footsteps_Heard(obj);
+			break;
+		case GUNSHOT_HEARD:
+			State_Act_Gunshot_Heard(obj);
+			break;
+		case ENEMY_SEEN:
+			State_Act_Attack(obj);
+			break;
+		}
+	}
+}
+void DB_Innate_Soldier::State_Act_Idle(SoldierGameObj *obj)
+{
+	ActTime = 5;
+	Vector3 pos;
+	obj->Get_Position(&pos);
+	if (FreeRandom.Get_Float() < 0.5f)
+	{
+		SubState = "Facing Random";
+		Vector3 rnd = Random_Vector(1.0f);
+		pos = pos + rnd;
+		Action_Face_Location(obj,pos,AI_STATE_IDLE,0);
+		ActTime = FreeRandom.Get_Float(4.0f,6.0f);
+	}
+	if (!IsStationary)
+	{
+		SubState = "Random Walk";
+		if (Get_Random_Pathfind_Spot(pos,6,&pos))
+		{
+			Action_Goto_Location(obj,pos,AI_STATE_IDLE,0.3f,0.3f,0);
+		}
+		ActTime = FreeRandom.Get_Float(7.0f,10.0f);
+	}
+}
+void DB_Innate_Soldier::State_Act_Footsteps_Heard(SoldierGameObj *obj)
+{
+	ActTime = FreeRandom.Get_Float(3.0f,4.0f);
+	bool move = false;
+	if (Aggressiveness > FreeRandom.Get_Float() && !IsStationary)
+	{
+		SubState = "Walk To Footsteps";
+		Vector3 pos;
+		if (Get_Random_Pathfind_Spot(Position,2,&pos))
+		{
+			Action_Goto_Location(obj,pos,AI_STATE_IDLE,0.3f,0.5f,0);
+			move = true;
+		}
+	}
+	if (!move)
+	{
+		SubState = "Face Footsteps";
+		Action_Face_Location(obj,Position,AI_STATE_SEARCH,0);
+	}
+}
+void DB_Innate_Soldier::State_Act_Bullet_Heard(SoldierGameObj *obj, bool b)
+{
+	ActTime = FreeRandom.Get_Float(5.0f,10.0f);
+	ActTime = FreeRandom.Get_Float(4.0f,2.0f);
+	obj->Get_Human_State()->Raise_Weapon();
+	Vector3 pos;
+	obj->Get_Position(&pos);
+	Vector3 pos2 = pos - Position;
+	float f = WWMath::Clamp((1.0f - (pos2.Length() - 10.0f) / 10.0f));
+	bool b2 = false;
+	if (b && f > FreeRandom.Get_Float() && !IsStationary)
+	{
+		b2 = true;
+	}
+	if (b2)
+	{
+		SubState = "Dive Away";
+		ActTime = FreeRandom.Get_Float(2.0f,4.0f);
+		pos2 = (pos * 2) - Position;
+		Action_Dive(obj,pos2);
+	}
+	else
+	{
+
+		if (TakeCoverProbability > FreeRandom.Get_Float() || IsStationary)
+		{
+			SubState = "Face Random Crouched";
+			pos2 = pos + Random_Vector(1.0f);
+			Action_Face_Location(obj,pos2,AI_STATE_IDLE,1);
+		}
+		else
+		{
+			SubState = "Crouch Walk To";
+			if (Get_Random_Pathfind_Spot(Position,6,&pos2))
+			{
+				Action_Goto_Location(obj,pos2,AI_STATE_SEARCH,0.89999998f,2.0f,1);
+			}
+		}
+	}
+}
+void DB_Innate_Soldier::State_Act_Gunshot_Heard(SoldierGameObj *obj)
+{
+	obj->Get_Human_State()->Raise_Weapon();
+	ActTime = FreeRandom.Get_Float(5.0f,10.0f);
+	if (IsStationary)
+	{
+		SubState = "Face gunshot";
+		Action_Face_Location(obj,Position,AI_STATE_SEARCH,0);
+	}
+	else
+	{
+		SubState = "Run To Random";
+		Vector3 pos = Position;
+		if (Get_Random_Pathfind_Spot(Position,6,&pos))
+		{
+			Action_Goto_Location_Facing(obj,pos,AI_STATE_SEARCH,Position,0.89999998f,2.0f,0);
+		}
+		else
+		{
+			Vector3 pos2;
+			obj->Get_Position(&pos2);
+			if (Get_Random_Pathfind_Spot(pos2,6,&pos))
+			{
+				Action_Goto_Location_Facing(obj,pos,AI_STATE_SEARCH,Position,0.30000001f,0.5f,0);
+			}
+		}
+	}
+}
+void DB_Innate_Soldier::State_Act_Attack(SoldierGameObj *obj)
+{
+	obj->Get_Human_State()->Raise_Weapon();
+	ActTime = FreeRandom.Get_Float(5.0f,8.0f);
+	ScriptableGameObj *target = Target;
+	if (!target || !Target->As_DamageableGameObj()->Is_Enemy(obj))
+	{
+		StateTimer = 100000;
+		return;
+	}
+	Vector3 pos;
+	target->Get_Position(&pos);
+	float range = 60;
+	if (obj->Get_Weapon())
+	{
+		range = obj->Get_Weapon()->Get_Range();
+	}
+	Vector3 pos2;
+	obj->Get_Position(&pos2);
+
+	float er = 20;
+	if (obj->Get_Weapon())
+	{
+		er = obj->Get_Weapon()->Get_Effective_Range();
+	}
+	
+	Vector3 pos3 = pos;
+	float val = 100000;
+	int count = 0;
+	int positionCount = 0;
+	if(!IsStationary)
+	{
+		//Select a random spot and then check if it will have a clear shot of the enemy object from that position.
+		//Do it up to 512 times and stop when it has 4 valid locations. Select the one closest to effective range.
+		do
+		{
+			Vector3 pos4 = pos2;
+			if (Get_Random_Pathfind_Spot(pos,(er+range)/2,&pos4))
+			{
+				float len = (pos4 - pos).Length() - er;
+				if (val > WWMath::Fabs(len) && Can_Position_Target_Object(obj,pos4,(PhysicalGameObj *)target))
+				{
+					val = WWMath::Fabs(len);
+					pos3 = pos4;
+					positionCount++;
+				}
+			}
+			count++;
+		} while (count < 512 && positionCount < 4);
+	}
+	else
+	{
+		pos3 = pos2;
+	}
+	SubState = "Random Run Attack";
+	ActTime = 3;
+	Action_Attack_Object(obj,(PhysicalGameObj *)target,range,(1.0f - Aggressiveness) > FreeRandom.Get_Float()*5.0f,pos3,0.5f);
+}
+void DB_Innate_Soldier::Action_Reset(SoldierGameObj *obj)
+{
+	Commands->Action_Reset(obj,(float)StatePriorities[State]);
+}
+void DB_Innate_Soldier::Action_Face_Location(SoldierGameObj *obj, Vector3 const &position, SoldierAIState aistate, bool crouched)
+{
+	ActionParamsStruct params;
+	params.Set_Basic(Get_ID(),(float)StatePriorities[State],9000000,aistate);
+	params.Set_Face_Location(position,2);
+	params.MoveCrouched = crouched;
+	Commands->Action_Face_Location(obj,params);
+}
+void DB_Innate_Soldier::Action_Goto_Location(SoldierGameObj *obj, Vector3 const &position, SoldierAIState aistate, float speed, float distance, bool crouched)
+{
+	Vector3 pos = position;
+	Stay_Within_Home(obj,&pos,&distance);
+	ActionParamsStruct params;
+	params.Set_Basic(Get_ID(),(float)StatePriorities[State],9000000,aistate);
+	params.Set_Movement(position,speed,distance,crouched);
+	Commands->Action_Goto(obj,params);
+}
+void DB_Innate_Soldier::Action_Goto_Location_Facing(SoldierGameObj *obj, Vector3 const &position, SoldierAIState aistate, Vector3 const &position2, float speed, float distance, bool crouched)
+{
+	Vector3 pos = position;
+	Stay_Within_Home(obj,&pos,&distance);
+	ActionParamsStruct params;
+	params.Set_Basic(Get_ID(),(float)StatePriorities[State],9000000,aistate);
+	params.Set_Movement(position,speed,distance,crouched);
+	params.ForceFacing = true;
+	params.FaceLocation = position2;
+	Commands->Action_Goto(obj,params);
+}
+void DB_Innate_Soldier::Action_Attack_Object(SoldierGameObj *obj, PhysicalGameObj *target, float range, bool crouched, Vector3 const &position, float distance)
+{
+	Vector3 pos = position;
+	Stay_Within_Home(obj,&pos,&distance);
+	if (IsStationary)
+	{
+		distance = 10000;
+	}
+	if (target && obj->Get_Weapon())
+	{
+		ActionParamsStruct params;
+		params.Set_Basic(Get_ID(),(float)StatePriorities[State],9000000,AI_STATE_COMBAT);
+		params.Set_Movement(pos,0.89999998f,distance,crouched);
+		params.Set_Attack(target,range,FreeRandom.Get_Float() * 2.0f,true);
+		params.AttackCrouched = crouched;
+		params.AttackWanderAllowed = IsStationary ^ 1;
+		if (FreeRandom.Get_Float() < 0.5f)
+		{
+			params.LookLocation = pos + Vector3(0,0,1);
+			params.LookDuration = FreeRandom.Get_Float(0.30000001f,1.0f);
+		}
+		Commands->Action_Attack(obj,params);
+	}
+}
+void DB_Innate_Soldier::Action_Dive(SoldierGameObj *obj, Vector3 const &position)
+{
+	ActionParamsStruct params;
+	params.Set_Basic(Get_ID(),(float)StatePriorities[State],9000000,AI_STATE_SEARCH);
+	params.MoveLocation = position;
+	params.MoveCrouched = true;
+	params.MoveArrivedDistance = 0.25f;
+	Commands->Action_Goto(obj,params);
+}
+void DB_Innate_Soldier::Stay_Within_Home(SoldierGameObj *obj, Vector3 *position, float *distance)
+{
+	Vector3 pos;
+	obj->Get_Position(&pos);
+	pos.X = pos.X - HomeLocation.X;
+	pos.Y = pos.Y - HomeLocation.Y;
+	pos.Z = 0;
+	if (pos.Length() > HomeFacing)
+	{
+		*position = HomeLocation;
+		*distance = HomeFacing;
+	}
+}
+
+ScriptRegistrant<DB_Innate_Soldier> DB_Innate_Soldier_Registrant("DB_Innate_Soldier","Aggressiveness=0.5:float,HomeRange=0:Float,Stationary=0:int,Debug=0:int");
+
diff -uwrN sourceold/scripts/DB_Innate.h source/scripts/DB_Innate.h
--- sourceold/scripts/DB_Innate.h	1970-01-01 10:00:00.000000000 +1000
+++ source/scripts/DB_Innate.h	2017-02-16 06:25:31.820200800 +1000
@@ -0,0 +1,114 @@
+#ifndef TT_INCLUDE__DB_Innate_Soldier_H
+#define TT_INCLUDE__DB_Innate_Soldier_H
+
+
+
+#include "ReferencerClass.h"
+#include "engine_string.h"
+#include "SoldierGameObj.h"
+
+
+enum SoldierAIStates
+{
+	RELAXED_IDLE = 0,
+	ALERT_IDLE = 1,
+	FOOTSTEPS_HEARD = 2,
+	BULLET_HEARD = 3,
+	GUNSHOT_HEARD = 4,
+	ENEMY_SEEN = 5
+};
+
+
+/*
+Full replacement for the stock Innate Behavior AI that has many improvements including dealing with
+enemies behind cover. It also will move and strafe much more often to avoid enemy shots. It should
+work as a drop in replacement for most scripts that rely on the original Innate AI as well.
+*/
+class DB_Innate_Soldier :
+	public ScriptImpClass
+{
+	int State; //10
+	float StateTimer; //14
+	Vector3 HomeLocation; //18 1C 20
+	float HomeFacing; //24
+	Vector3 Position; //28 2C 30
+	float ActTime; //34
+	ReferencerClass Target; //38 3C 40 44
+	bool Cover; //48
+	float ConversationTimer; //50
+	bool UseWeapon; //54
+	float Aggressiveness; //58
+	float TakeCoverProbability; //5C
+	bool IsStationary; //60
+	StringClass SubState; //64
+	int LastState; //68
+	const char *Weapon; //6C
+	bool Debug;
+public:
+	DB_Innate_Soldier();
+	~DB_Innate_Soldier();
+	bool Save(ChunkSaveClass &csave);
+	bool Load(ChunkLoadClass &cload);
+	virtual const char *Get_Name()
+	{
+		return "DB_Innate_Soldier";
+	}
+	virtual void Created(GameObject *obj);
+	virtual void Destroyed(GameObject *obj);
+	virtual void Killed(GameObject *obj,GameObject *killer);
+	virtual void Damaged(GameObject *obj,GameObject *damager,float amount);
+	virtual void Custom(GameObject *obj,int type,int param,GameObject *sender);
+	virtual void Sound_Heard(GameObject *obj,const CombatSound & sound);
+	virtual void Enemy_Seen(GameObject *obj,GameObject *enemy);
+	virtual void Action_Complete(GameObject *obj,int action_id,ActionCompleteReason complete_reason);
+	virtual void Timer_Expired(GameObject *obj,int number);
+	virtual void Animation_Complete(GameObject *obj,const char *animation_name)
+	{
+	}
+	virtual void Poked(GameObject *obj,GameObject *poker);
+	virtual void Entered(GameObject *obj,GameObject *enterer)
+	{
+	}
+	virtual void Exited(GameObject *obj,GameObject *exiter)
+	{
+	}
+	void Action_Attack_Object(SoldierGameObj *, PhysicalGameObj *, float, bool, Vector3  const&, float);
+	void Action_Dive(SoldierGameObj *, Vector3  const&);
+	void Action_Face_Location(SoldierGameObj *, Vector3  const&, SoldierAIState, bool);
+	void Action_Goto_Location(SoldierGameObj *, Vector3  const&, SoldierAIState, float, float, bool);
+	void Action_Goto_Location_Facing(SoldierGameObj *, Vector3  const&, SoldierAIState, Vector3  const&, float, float, bool);
+	void Action_Reset(SoldierGameObj *);
+	void Get_Information(StringClass &);
+	void Notify_Neighbors_Sound(SoldierGameObj *, CombatSound  const&);
+	void Notify_Neighbors_Enemy(SoldierGameObj *, ScriptableGameObj *);
+	void Reset_Conversation_Timer();
+	bool Set_State(SoldierGameObj *, int, Vector3  const&, ScriptableGameObj *);
+	void State_Act(SoldierGameObj *, bool);
+	void State_Act_Idle(SoldierGameObj *);
+	void State_Act_Footsteps_Heard(SoldierGameObj *);
+	void State_Act_Bullet_Heard(SoldierGameObj *, bool);
+	void State_Act_Gunshot_Heard(SoldierGameObj *);
+	void State_Act_Attack(SoldierGameObj *);
+	void State_Changed(SoldierGameObj *);
+	void Stay_Within_Home(SoldierGameObj *, Vector3 *, float *);
+	void Think_Function(SoldierGameObj *, bool);
+	void Set_Home_Location(Vector3 const &pos, float facing)
+	{
+		HomeLocation = pos;
+		HomeFacing = facing;
+	}
+	void Set_Aggressiveness(float f)
+	{
+		Aggressiveness = f;
+	}
+	void Set_Take_Cover_Probability(float f)
+	{
+		TakeCoverProbability = f;
+	}
+	void Set_Is_Stationary(bool b)
+	{
+		IsStationary = b;
+	}
+}; // 0070
+
+#endif
\ No newline at end of file
diff -uwrN sourceold/scripts/JMGRenetBuster.h source/scripts/JMGRenetBuster.h
--- sourceold/scripts/JMGRenetBuster.h	2016-10-31 07:17:12.355013500 +1000
+++ source/scripts/JMGRenetBuster.h	2017-02-13 13:38:02.208001900 +1000
@@ -26,7 +26,6 @@
 
 #define PERKCOUNT 126
 #define PERKCATEGORIES 11
-int USEABLEPERKCOUNT = 0;
 enum PerkTypeCategories{INVALID = -1,PerkPurchase = 0,PerkJob = 1,PerkSwimming = 2,PerkCharacterHealth = 3,PerkVehicle = 4,PerkCombat = 5,PerkDeath = 6,PerkMisc = 7,PerkWeapon = 8,PerkSpawnCharacter = 9,PerkUnusable = 999};
 
 struct PerkSystemPerkTypeNode
@@ -69,6 +68,7 @@
 	}
 	int PerkTypeCategoryCounts[PERKCATEGORIES];
 public:
+	static int USEABLEPERKCOUNT;
 	PerkSystemPerkTypeList()
 	{
 		Reset();
@@ -103,7 +103,7 @@
 			PerkSystemPerkTypeNodeList[x].CategoryPerkID = (PerkTypeCategoryCounts[PerkSystemPerkTypeNodeList[x].Category] = (PerkTypeCategoryCounts[PerkSystemPerkTypeNodeList[x].Category]+1));
 	}
 };
-
+int PerkSystemPerkTypeList::USEABLEPERKCOUNT = 0;
 // Player Perks
 
 struct PlayerPerkDataNode
@@ -464,15 +464,16 @@
 		PerkTypeSystem.AddAPerkType(x,"N/A",1000000,false,false,false,PerkUnusable,0,"N/A");
 
 	PerkTypeSystem.Finalize_Perks();
-	USEABLEPERKCOUNT = 0;
+	PerkSystemPerkTypeList::USEABLEPERKCOUNT = 0;
 	for (int x = 0;x < PERKCOUNT;x++)
 		if (PerkSystemPerkTypeNodeList[x].PerkID)
-			USEABLEPERKCOUNT++;
+			PerkSystemPerkTypeList::USEABLEPERKCOUNT++;
 }
 
 
 struct RenCometBustersScoreSystem
 {
+	int difficulty;
 public:
 	#define RCMTBHIGHSCORELISTCOUNT 61
 	struct CMTBHighScoresNode
@@ -763,12 +764,18 @@
 		FILE *SaveScores;
 		FILE *SaveScores2;
 		char FileName[256];
-		char FileName2[256];
+		char FileNameTmp[256];
 		char SavePath[256];
 		sprintf(SavePath, "%sSave\\", Get_File_Path());
-		sprintf(FileName,"%sBetaCMBTPlayerRecords.tmp",SavePath);
-		SaveScores = fopen(FileName,"w");
-		sprintf(FileName,"%sCMBTPlayerRecords.txt",SavePath);
+		sprintf(FileNameTmp,"%sBetaCMBTPlayerRecords.tmp",SavePath);
+		SaveScores = fopen(FileNameTmp,"w");
+		switch (difficulty)
+		{
+		case 0:sprintf(FileName,"%sBetaCMBTPlayerRecordsEasy.txt",SavePath);break;
+		case 1:sprintf(FileName,"%sBetaCMBTPlayerRecords.txt",SavePath);break;
+		case 2:sprintf(FileName,"%sBetaCMBTPlayerRecordsHard.txt",SavePath);break;
+		case 3:sprintf(FileName,"%sBetaCMBTPlayerRecordsDoomsday.txt",SavePath);break;
+		};
 		SaveScores2 = fopen(FileName,"w");
 		CMTBHighScoresNode *Current = CMTBHighScoresNodeList;
 		if (!SaveScores || !SaveScores2)
@@ -791,22 +798,34 @@
 		}
 		fclose(SaveScores);
 		fclose(SaveScores2);
-		sprintf(FileName,"%sBetaCMBTPlayerRecords.Rp2",SavePath);
+		switch (difficulty)
+		{
+		case 0:sprintf(FileName,"%sBetaCMBTPlayerRecordsEasy.Rp2",SavePath);break;
+		case 1:sprintf(FileName,"%sBetaCMBTPlayerRecords.Rp2",SavePath);break;
+		case 2:sprintf(FileName,"%sBetaCMBTPlayerRecordsHard.Rp2",SavePath);break;
+		case 3:sprintf(FileName,"%sBetaCMBTPlayerRecordsDoomsday.Rp2",SavePath);break;
+		};
 		remove(FileName);
-		sprintf(FileName,"%sBetaCMBTPlayerRecords.tmp",SavePath);
-		sprintf(FileName2,"%sBetaCMBTPlayerRecords.Rp2",SavePath);
-		rename(FileName,FileName2);
+		sprintf(FileNameTmp,"%sBetaCMBTPlayerRecords.tmp",SavePath);
+		rename(FileNameTmp,FileName);
 	}
 
-	void LoadData()
+	void LoadData(int setDifficulty)
 	{
+		difficulty = setDifficulty;
 		Cleanup();
 		char PlayerName[256];
 		FILE *LoadScores;
 		char FileName[256];
 		char SavePath[256];
 		sprintf(SavePath, "%sSave\\", Get_File_Path());
-		sprintf(FileName,"%sBetaCMBTPlayerRecords.Rp2",SavePath);
+		switch (difficulty)
+		{
+		case 0:sprintf(FileName,"%sBetaCMBTPlayerRecordsEasy.Rp2",SavePath);break;
+		case 1:sprintf(FileName,"%sBetaCMBTPlayerRecords.Rp2",SavePath);break;
+		case 2:sprintf(FileName,"%sBetaCMBTPlayerRecordsHard.Rp2",SavePath);break;
+		case 3:sprintf(FileName,"%sBetaCMBTPlayerRecordsDoomsday.Rp2",SavePath);break;
+		}
 		LoadScores = fopen(FileName,"r");
 		if (LoadScores)
 		{
@@ -1271,7 +1290,6 @@
 
 RenCometBustersScoreSystem RenCometBustersScoreControl = RenCometBustersScoreSystem();
 
-int PrioritizeTargets[17] = {2,2,0,1,0,3,2,0,2,0,0,1,1,3,2,0,2};
 enum ObjectType{NormalPlayerShip=0,UFO=1,Asteroid=2,Mine=3,TheMoon=4,PlayerShield=5,UFOBoss=6,PlayerCloak=7,PlayerSuper=8,CMTPowerup=9,CargoShip=10,MineBoss=11,PlayerDrone=12,PlayerDroneShield=13,PlayerShipJumpable=14,PlayerShipJumping=15,PlayerShipDisrupter=16};
 struct TypeObject
 {
@@ -1297,6 +1315,17 @@
 	ObjectType Type;
 	int AllowReplaceTime;
 	struct AnObject *next;
+	AnObject(GameObject *obj,float Size,float RealSize,ObjectType Type)
+	{
+		this->AllowReplaceTime = -1;
+		this->Object = obj;
+		this->ObjectID = Commands->Get_ID(obj);
+		this->Size = Size;
+		this->RealSize = RealSize;
+		this->Type = Type;
+		this->AllowReplaceTime = 0;
+		this->next = NULL;
+	};
 };
 
 struct RenCometBustersPlayerNode
@@ -1387,18 +1416,7 @@
 class RenCometBustersGameObjects
 {
 private:
-	AnObject *New_Object_Node(AnObject *Node,GameObject *obj,float Size,float RealSize,ObjectType Type)
-	{
-		Node->AllowReplaceTime = -1;
-		Node->Object = obj;
-		Node->ObjectID = Commands->Get_ID(obj);
-		Node->Size = Size;
-		Node->RealSize = RealSize;
-		Node->Type = Type;
-		Node->AllowReplaceTime = 0;
-		Node->next = NULL;
-		return Node;
-	};
+	static int PrioritizeTargets[17];
 public:
 	struct AnObject *ObjectsList;
 	RenCometBustersGameObjects()
@@ -1427,7 +1445,7 @@
 		AnObject *Current = ObjectsList;
 		if (!ObjectsList)
 		{
-			ObjectsList = New_Object_Node(new AnObject,obj.obj,obj.Size,obj.RealSize,obj.Type);
+			ObjectsList = new AnObject(obj.obj,obj.Size,obj.RealSize,obj.Type);
 			return *this;
 		}
 		while (Current)
@@ -1450,7 +1468,7 @@
 			}
 			if (!Current->next)
 			{
-				Current->next = New_Object_Node(new AnObject,obj.obj,obj.Size,obj.RealSize,obj.Type);
+				Current->next = new AnObject(obj.obj,obj.Size,obj.RealSize,obj.Type);
 				return *this;
 			}
 			Current = Current->next;
@@ -1498,6 +1516,16 @@
 		}
 		return NULL;
 	};
+	void SpecialApplyDamage(GameObject *obj,float damage,const char *warhead,GameObject *damager)
+	{
+		GameObject *driver = Get_Vehicle_Driver(obj);
+		int originalDriverTeam = driver ? Get_Player_Type(driver) : 1;
+		Commands->Set_Player_Type(obj,-2);
+		Commands->Set_Player_Type(driver,-2);
+		Commands->Apply_Damage(obj,damage,warhead,damager);
+		if (driver)
+			Commands->Set_Player_Type(driver,originalDriverTeam);
+	}
 	bool DoesCollide(AnObject *Obj,AnObject *OtherObj)
 	{
 		if (!Obj || !OtherObj || Obj->AllowReplaceTime || OtherObj->AllowReplaceTime)
@@ -1603,24 +1631,14 @@
 						Commands->Send_Custom_Event(Other,Other,7043453,10,0.0f);
 				}
 				if (OtherObj->Type != PlayerShield && OtherObj->Type != PlayerSuper && OtherObj->Type != PlayerDroneShield && OtherObj->Type != TheMoon)
-				{
-					int originalPlayerType = Get_Player_Type(Get_Vehicle_Driver(Other));
-					Commands->Set_Player_Type(Get_Vehicle_Driver(Other),-2);
-					Commands->Apply_Damage(Other,99999.9f,"BlamoKiller",Hitter);
-					Commands->Set_Player_Type(Get_Vehicle_Driver(Other),originalPlayerType);
-				}
+					SpecialApplyDamage(Other,99999.9f,"BlamoKiller",Hitter);
 				else
 					if (Obj->Type == NormalPlayerShip || Obj->Type == PlayerCloak || Obj->Type == PlayerShipJumpable || Obj->Type == PlayerShipDisrupter)
 						Commands->Send_Custom_Event(Other,Other,7043453,33,0.0f);
 					else
 						Commands->Send_Custom_Event(Other,Other,7043453,5,0.0f);
 				if (Obj->Type != PlayerShield && Obj->Type != PlayerSuper && Obj->Type != PlayerDroneShield && OtherObj->Type != TheMoon)
-				{
-					int originalPlayerType = Get_Player_Type(Get_Vehicle_Driver(Hitter));
-					Commands->Set_Player_Type(Get_Vehicle_Driver(Hitter),-2);
-					Commands->Apply_Damage(Hitter,99999.9f,"BlamoKiller",Other);
-					Commands->Set_Player_Type(Get_Vehicle_Driver(Hitter),originalPlayerType);
-				}
+					SpecialApplyDamage(Hitter,99999.9f,"BlamoKiller",Other);
 				else
 					if (OtherObj->Type == NormalPlayerShip || OtherObj->Type == PlayerCloak || OtherObj->Type == PlayerShipJumpable  || OtherObj->Type == PlayerShipDisrupter)
 						Commands->Send_Custom_Event(Hitter,Hitter,7043453,33,0.0f);
@@ -2001,7 +2019,6 @@
 	}
 	void KillInRange(GameObject *Player,const Vector3 &Position,float MinRange,float MaxRange)
 	{
-		int giveUp = 0;
 KillInRangeCheckStart:
 		AnObject *Current = ObjectsList;
 		while (Current)
@@ -2011,10 +2028,7 @@
 				float Dist = JmgUtility::SimpleDistance(Position,Commands->Get_Position(Current->Object));
 				if (Dist <= MaxRange && Dist >= MinRange)
 				{
-					if (giveUp > 1)
-						break;
-					giveUp++;
-					Commands->Apply_Damage(Current->Object,1.0f,"None",Player);
+					SpecialApplyDamage(Current->Object,1.0f,"None",Player);
 					goto KillInRangeCheckStart;
 				}
 			}
@@ -2109,11 +2123,8 @@
 		return Closest->Object;
 	}
 };
+int RenCometBustersGameObjects::PrioritizeTargets[17] = {2,2,0,1,0,3,2,0,2,0,0,1,1,3,2,0,2};
 
-bool GAMEINPROGRESS = false;
-unsigned int CMTBLevel = 0;
-unsigned int PlayerSOSBeaconID = 0;
-unsigned int DroneSwarmCount = 0;
 Vector3 Random_Map_Position()
 {
 	int Random = Commands->Get_Random_Int(0,2);
@@ -2140,8 +2151,24 @@
 	void FadeMusic(const char *music);
 public:
 	static int MoonHolderID;
+	static bool GameInProgress;
+	static unsigned int CMTBLevel;
+	static unsigned int PlayerSOSBeaconID;
+	static unsigned int DroneSwarmCount;
+	static bool EndGameSwitchEnabled;
+	static float DifficultyMultiplier;
+	static float DifficultyMultiplierMine;
+	static float DifficultyMultiplierInv;
 };
 int JMG_CMTB_Main_Game_Control::MoonHolderID = 0;
+bool JMG_CMTB_Main_Game_Control::GameInProgress = false;
+unsigned int JMG_CMTB_Main_Game_Control::CMTBLevel = 0;
+unsigned int JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID = 0;
+unsigned int JMG_CMTB_Main_Game_Control::DroneSwarmCount = 0;
+bool JMG_CMTB_Main_Game_Control::EndGameSwitchEnabled = true;
+float JMG_CMTB_Main_Game_Control::DifficultyMultiplier = 1.0f;
+float JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine = 1.0f;
+float JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv = 1.0f;
 
 class JMG_CMTB_UFO_Random_Fire_Control : public ScriptImpClass {
 	void Created(GameObject *obj);
@@ -2459,3 +2486,18 @@
 	void Timer_Expired(GameObject *obj, int number);
 	void Destroyed(GameObject *obj);
 };
\ No newline at end of file
+
+class JMG_CMTB_Poke_End_Map : public ScriptImpClass {
+	int time;
+	int startDelay;
+	void Created(GameObject *obj);
+	void Poked(GameObject *obj,GameObject *poker);
+	void Timer_Expired(GameObject *obj, int number);
+	void FlipSwitch(GameObject *obj,float frame);
+};
+
+class JMG_CMTB_Poke_Change_Difficulty : public ScriptImpClass {
+	int difficulty;
+	void Created(GameObject *obj);
+	void Poked(GameObject *obj,GameObject *poker);
+};
\ No newline at end of file
diff -uwrN sourceold/scripts/JMGRenetBusters.cpp source/scripts/JMGRenetBusters.cpp
--- sourceold/scripts/JMGRenetBusters.cpp	2016-10-31 07:17:12.356013500 +1000
+++ source/scripts/JMGRenetBusters.cpp	2017-02-13 13:37:50.108001900 +1000
@@ -59,12 +59,6 @@
 		Commands->Start_Timer(obj,this,0.15f,6546587);
 	}
 }
-/*void JMG_Create_Ship_On_Poke::Custom(GameObject *obj,int message,int param,GameObject *sender)
-{
-	if (message == 54231684)
-	{
-	}
-}*/
 void JMG_Create_Ship_On_Poke::Timer_Expired(GameObject *obj,int number)
 {
 	if (number == 6546585)
@@ -442,17 +436,6 @@
 		Console_Input(Text);
 	}
 }
-/*void JMG_Ship_Shield_Control_Script::Timer_Expired(GameObject *obj,int number)
-{
-	if (number == 543424421)
-	{
-		ison = 0;
-	}
-	if (number == 543424420)
-	{
-		ison = 1;
-	}
-}*/
 void JMG_Kill_Self_And_Sender_On_Custom_Ship::Created(GameObject *obj)
 {
 	canbekilled = 1;
@@ -683,17 +666,17 @@
 {
 	MoonHolderID = 0;
 	PlayerSOSBeaconDealy = 0;
-	PlayerSOSBeaconID = 0;
-	DroneSwarmCount = 0;
+	JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID = 0;
+	JMG_CMTB_Main_Game_Control::DroneSwarmCount = 0;
 	CurrentMusic = MusicNone;
 	BabySit = 20;
 	Commands->Start_Timer(obj,this,5.0,5438);
 	UFOSpawnTime = Commands->Get_Random_Int(600,1800);
 	AddPerkTypes();
 	RenCometBustersScoreControl.Cleanup();
-	RenCometBustersScoreControl.LoadData();
+	RenCometBustersScoreControl.LoadData(1);
 	PlayerPerkSystemControl.LoadData();
-	CMTBLevel = 0;
+	JMG_CMTB_Main_Game_Control::CMTBLevel = 0;
 	NextLevelDelay = -1;
 	LastPlayerCount = 0;
 	LastCometCount = -1;
@@ -726,8 +709,6 @@
 		sprintf(Spot,"SpawnS0%d",x);
 		SpawnLocations[x] = Commands->Get_Bone_Position(obj,Spot);
 	}
-	Set_GDI_Soldier_Name("CnC_GDI_MiniGunnerN");
-	Set_Nod_Soldier_Name("CnC_Nod_MiniGunnerN");
 	Commands->Start_Timer(obj,this,0.1f,5434);
 	Commands->Start_Timer(obj,this,1.0f,5435);
 	Commands->Start_Timer(obj,this,10.0f,5436);
@@ -764,12 +745,13 @@
 			}
 			return;
 		}
+		JMG_CMTB_Main_Game_Control::GameInProgress = true;
 		MaxPlayerCount = 0;
 		PlayerSOSBeaconDealy = 0;
-		if (PlayerSOSBeaconID)
+		if (JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID)
 		{
-			Commands->Destroy_Object(Commands->Find_Object(PlayerSOSBeaconID));
-			PlayerSOSBeaconID = 0;
+			Commands->Destroy_Object(Commands->Find_Object(JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID));
+			JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID = 0;
 		}
 		for (int x = 0;x < MaxGamePlayerCount;x++)
 		{
@@ -800,10 +782,9 @@
 		if (moonHolder)
 			Commands->Destroy_Object(moonHolder);
 		RenCometBustersList.ClearAllObjects();
-		CMTBLevel = 0;
+		JMG_CMTB_Main_Game_Control::CMTBLevel = 0;
 		NextLevelDelay = 0;
 		UFOSpawnTime = Commands->Get_Random_Int(600,1800);
-		GAMEINPROGRESS = true;
 	}
 	if (message == 57448)
 	{
@@ -846,15 +827,15 @@
 {
 	if (number == 5435)
 	{
-		if (!PlayerSOSBeaconDealy && PlayerSOSBeaconID)
+		if (!PlayerSOSBeaconDealy && JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID)
 			PlayerSOSBeaconDealy = 140;
 		if (PlayerSOSBeaconDealy)
 		{
 			PlayerSOSBeaconDealy--;
 			if (!PlayerSOSBeaconDealy)
 			{
-				Commands->Destroy_Object(Commands->Find_Object(PlayerSOSBeaconID));
-				PlayerSOSBeaconID = 0;
+				Commands->Destroy_Object(Commands->Find_Object(JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID));
+				JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID = 0;
 			}
 		}
 		for (int x = 0;x < MaxGamePlayerCount;x++)
@@ -892,11 +873,11 @@
 						switch (MiniGamePlayerControlSystem[x].SelectedPerk)
 						{
 						case 1:
-							if (CMTBLevel == 1 || !(CMTBLevel%25))
+							if (JMG_CMTB_Main_Game_Control::CMTBLevel == 1 || !(JMG_CMTB_Main_Game_Control::CMTBLevel%25))
 								Commands->Send_Custom_Event(obj,MiniGamePlayerControlSystem[x].PlayerShip,CMTBPowerUpCustomMessage+5,-1337,0);
 							break;
 						case 2:
-							if (CMTBLevel == 1)
+							if (JMG_CMTB_Main_Game_Control::CMTBLevel == 1)
 								Commands->Send_Custom_Event(obj,MiniGamePlayerControlSystem[x].PlayerShip,CMTBPowerUpCustomMessage+14,-1337,0);
 							break;
 						case 3:
@@ -913,9 +894,9 @@
 							break;
 						}
 					}
-					if (!(CMTBLevel % 6))
+					if (!(JMG_CMTB_Main_Game_Control::CMTBLevel % 6))
 					{
-						unsigned int Count = (int)(CMTBLevel * 0.5);
+						unsigned int Count = (int)(JMG_CMTB_Main_Game_Control::CMTBLevel * 0.5);
 						for (unsigned int x = 0;x < Count;x++)
 						{//Drones
 							GameObject *Comet = Commands->Create_Object("CMTB_Drone",Random_Map_Position());
@@ -927,16 +908,16 @@
 					}
 					else
 					{
-						unsigned int Count = CMTBLevel;
-						if (!(CMTBLevel % 25))
-							Count = CMTBLevel/4;
-						else if (!(CMTBLevel % 10))
-							Count = CMTBLevel/3;
+						unsigned int Count = JMG_CMTB_Main_Game_Control::CMTBLevel;
+						if (!(JMG_CMTB_Main_Game_Control::CMTBLevel % 25))
+							Count = JMG_CMTB_Main_Game_Control::CMTBLevel/4;
+						else if (!(JMG_CMTB_Main_Game_Control::CMTBLevel % 10))
+							Count = JMG_CMTB_Main_Game_Control::CMTBLevel/3;
 						for (unsigned int x = 0;x < Count;x++)
 						{//Comet2
-							GameObject *Comet = Commands->Create_Object(((CMTBLevel % 10) ? "Comet2" : "CMTB_UFO"),Random_Map_Position());
+							GameObject *Comet = Commands->Create_Object(((JMG_CMTB_Main_Game_Control::CMTBLevel % 10) ? "Comet2" : "CMTB_UFO"),Random_Map_Position());
 							Commands->Set_Facing(Comet,Commands->Get_Random(-180.0f,180.0f));
-							if (CMTBLevel % 10)
+							if (JMG_CMTB_Main_Game_Control::CMTBLevel % 10)
 							{
 								char params[512];
 								sprintf(params,"2,%.3f %.3f %.3f",Commands->Get_Position(Comet).X+(Commands->Get_Random(0.0,1.0f) < 0.5 ? 1 : -1)*Commands->Get_Random(15,25),(Commands->Get_Random(0.0,1.0f) < 0.5 ? 1 : -1)*Commands->Get_Position(Comet).Y+Commands->Get_Random(15,25),Commands->Get_Position(Comet).Z);
@@ -949,7 +930,7 @@
 								Commands->Set_Position(Comet,Random_Map_Position());
 						}
 					}
-					if (!(CMTBLevel % 25))
+					if (!(JMG_CMTB_Main_Game_Control::CMTBLevel % 25))
 					{
 						GameObject *moonHolder = Commands->Create_Object("Daves Arrow",Vector3(0.0f,-50.0f,0.0f));
 						Commands->Set_Model(moonHolder,"TheMoon!ANIM");
@@ -960,7 +941,7 @@
 						Set_Max_Health(Moon,200.0f*MaxPlayerCount);
 						Commands->Set_Health(Moon,200.0f*MaxPlayerCount);
 					}
-					if (!(CMTBLevel % 15))
+					if (!(JMG_CMTB_Main_Game_Control::CMTBLevel % 15))
 					{
 						GameObject *Ship = Commands->Create_Object("CMTB_Cargo_Ship",Vector3(0.0f,0.0f,1.481f));
 						Commands->Attach_Script(Ship,"JMG_CMTB_Cargo_Ship_Script","-1");
@@ -971,8 +952,8 @@
 			}
 			else if (RenCometBustersList.CheckIfLevelComplete())
 			{
-				CMTBLevel++;
-				if (CMTBLevel == 11)
+				JMG_CMTB_Main_Game_Control::CMTBLevel++;
+				if (JMG_CMTB_Main_Game_Control::CMTBLevel == 11)
 				{
 					for (int x = 0;x < MaxGamePlayerCount;x++)
 					{
@@ -985,7 +966,7 @@
 					}
 				}
 				LastCometCount = -1;
-				if (CMTBLevel == 1)
+				if (JMG_CMTB_Main_Game_Control::CMTBLevel == 1)
 					for (int x = 0;x < MaxGamePlayerCount;x++)
 					{
 						MiniGamePlayerControlSystem[x].NumberOfLives = 0;
@@ -998,21 +979,21 @@
 						MiniGamePlayerControlSystem[x].RespawnTime = 0;
 					}
 				char LevelString[32];
-				sprintf(LevelString,"***********Level %d***********",CMTBLevel);
+				sprintf(LevelString,"***********Level %d***********",JMG_CMTB_Main_Game_Control::CMTBLevel);
 				for (int x = 1;x < 128;x++)
 				{
 					GameObject *Player = Get_GameObj(x);
 					if (!Player)
 						continue;
 					JmgUtility::DisplayChatMessage(Player,6,145,148,LevelString);
-					sprintf_s(LevelString,"Level %d",CMTBLevel);
+					sprintf_s(LevelString,"Level %d",JMG_CMTB_Main_Game_Control::CMTBLevel);
 					Set_HUD_Help_Text_Player_Text(Player,7233,LevelString,Vector3(0.19599999f,1.0f,0.19599999f));
-					if ((CMTBLevel-1) % 10 && (CMTBLevel-1) % 25)
+					if ((JMG_CMTB_Main_Game_Control::CMTBLevel-1) % 10 && (JMG_CMTB_Main_Game_Control::CMTBLevel-1) % 25)
 						Create_2D_Sound_Player(Player,"SFX.Bonus_Mission_Update");
 					else
 						Create_2D_Sound_Player(Player,"SFX.Primary_Mission_Update");
 				}
-				if (CMTBLevel % 10 && CMTBLevel % 25)
+				if (JMG_CMTB_Main_Game_Control::CMTBLevel % 10 && JMG_CMTB_Main_Game_Control::CMTBLevel % 25)
 				{
 					if (CurrentMusic != MusicNormal)
 					{
@@ -1046,6 +1027,7 @@
 			LastPlayerCount = ContinueGame;
 			if (!ContinueGame)
 			{
+				JMG_CMTB_Main_Game_Control::GameInProgress = false;
 				bool teamHasPerks = false;
 				for (int x = 0;x < MaxGamePlayerCount;x++)
 					if (MiniGamePlayerControlSystem[x].SelectedPerk)
@@ -1053,7 +1035,6 @@
 						teamHasPerks = true;
 						break;
 					}
-				GAMEINPROGRESS = false;
 				for (int x = 0;x < MaxGamePlayerCount;x++)
 				{
 					MiniGamePlayerControlSystem[x].RespawnTime = 30;
@@ -1114,52 +1095,52 @@
 					if (MaxPlayerCount > 1)
 						if (teamHasPerks)
 						{
-							if (TempNode->TeamHighestLevel < CMTBLevel)
+							if (TempNode->TeamHighestLevel < JMG_CMTB_Main_Game_Control::CMTBLevel)
 							{
 								Create_2D_Sound_Player(Player,"SFX.Primary_Mission_Complete");
-								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to a new high level as a team: Level %d while using perks!",MiniGamePlayerControlSystem[x].Score,CMTBLevel);
-								TempNode->TeamHighestLevel = CMTBLevel;
-								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,CMTBLevel);
+								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to a new high level as a team: Level %d while using perks!",MiniGamePlayerControlSystem[x].Score,JMG_CMTB_Main_Game_Control::CMTBLevel);
+								TempNode->TeamHighestLevel = JMG_CMTB_Main_Game_Control::CMTBLevel;
+								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,JMG_CMTB_Main_Game_Control::CMTBLevel);
 							}
 							else
-								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to Level %d while using perks!",MiniGamePlayerControlSystem[x].Score,CMTBLevel);
+								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to Level %d while using perks!",MiniGamePlayerControlSystem[x].Score,JMG_CMTB_Main_Game_Control::CMTBLevel);
 						}
 						else
 						{
-							if (TempNode->HighestCleanTeamLevel < CMTBLevel)
+							if (TempNode->HighestCleanTeamLevel < JMG_CMTB_Main_Game_Control::CMTBLevel)
 							{
 								Create_2D_Sound_Player(Player,"SFX.Primary_Mission_Complete");
-								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to a new high level as a team: Level %d!",MiniGamePlayerControlSystem[x].Score,CMTBLevel);
-								TempNode->HighestCleanTeamLevel = CMTBLevel;
-								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,CMTBLevel);
+								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to a new high level as a team: Level %d!",MiniGamePlayerControlSystem[x].Score,JMG_CMTB_Main_Game_Control::CMTBLevel);
+								TempNode->HighestCleanTeamLevel = JMG_CMTB_Main_Game_Control::CMTBLevel;
+								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,JMG_CMTB_Main_Game_Control::CMTBLevel);
 							}
 							else
-								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to Level %d!",MiniGamePlayerControlSystem[x].Score,CMTBLevel);
+								sprintf(ScoreMessage,"You scored %.2f points and through teamwork made it to Level %d!",MiniGamePlayerControlSystem[x].Score,JMG_CMTB_Main_Game_Control::CMTBLevel);
 						}
 					else
 						if (teamHasPerks)
 						{
-							if (TempNode->HighestLevel < CMTBLevel)
+							if (TempNode->HighestLevel < JMG_CMTB_Main_Game_Control::CMTBLevel)
 							{
 								Create_2D_Sound_Player(Player,"SFX.Primary_Mission_Complete");
-								sprintf(ScoreMessage,"You scored %.2f points and made it to a new personal highest level: Level %d while using perks!",MiniGamePlayerControlSystem[x].Score,CMTBLevel);
-								TempNode->HighestLevel = CMTBLevel;
-								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,CMTBLevel);
+								sprintf(ScoreMessage,"You scored %.2f points and made it to a new personal highest level: Level %d while using perks!",MiniGamePlayerControlSystem[x].Score,JMG_CMTB_Main_Game_Control::CMTBLevel);
+								TempNode->HighestLevel = JMG_CMTB_Main_Game_Control::CMTBLevel;
+								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,JMG_CMTB_Main_Game_Control::CMTBLevel);
 							}
 							else
 								sprintf(ScoreMessage,"You scored %.2f points and made it to level %d while using perks!",MiniGamePlayerControlSystem[x].Score,MiniGamePlayerControlSystem[x].HighestLevel);
 						}
 						else
 						{
-							if (TempNode->HighestCleanLevel < CMTBLevel)
+							if (TempNode->HighestCleanLevel < JMG_CMTB_Main_Game_Control::CMTBLevel)
 							{
 								Create_2D_Sound_Player(Player,"SFX.Primary_Mission_Complete");
-								sprintf(ScoreMessage,"You scored %.2f points and made it to a new personal highest level: Level %d!",MiniGamePlayerControlSystem[x].Score,CMTBLevel);
-								TempNode->HighestCleanLevel = CMTBLevel;
-								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,CMTBLevel);
+								sprintf(ScoreMessage,"You scored %.2f points and made it to a new personal highest level: Level %d!",MiniGamePlayerControlSystem[x].Score,JMG_CMTB_Main_Game_Control::CMTBLevel);
+								TempNode->HighestCleanLevel = JMG_CMTB_Main_Game_Control::CMTBLevel;
+								PerkSystemIncreasePlayerPerkUnlockAmount(Player,61,JMG_CMTB_Main_Game_Control::CMTBLevel);
 							}
 							else
-								sprintf(ScoreMessage,"You scored %.2f points and made it to level %d",MiniGamePlayerControlSystem[x].Score,CMTBLevel);
+								sprintf(ScoreMessage,"You scored %.2f points and made it to level %d",MiniGamePlayerControlSystem[x].Score,JMG_CMTB_Main_Game_Control::CMTBLevel);
 						}
 					JmgUtility::DisplayChatMessage(Player,6,145,148,ScoreMessage);
 					MiniGamePlayerControlSystem[x].Score = 0;
@@ -1226,9 +1207,8 @@
 		Commands->Start_Timer(obj,this,0.1f,5434);
 	}
 	if (number == 5436)
-	{
+	{//OutOfBoundsObjectsCheck
 		Vector3 Pos = Commands->Get_Position(obj);
-OutOfBoundsObjectsCheck:
 		AnObject *Current = RenCometBustersList.ObjectsList;
 		while(Current)
 		{
@@ -1237,7 +1217,6 @@
 				{
 					Current->AllowReplaceTime = 1;
 					Commands->Apply_Damage(Current->Object,9999.9f,"BlamoKiller",obj);
-					goto OutOfBoundsObjectsCheck;
 				}
 			Current = Current->next;
 		}
@@ -1294,23 +1273,15 @@
 }
 void JMG_CMTB_Main_Game_Control::Destroyed(GameObject *obj)
 {
-	CMTBLevel = 0;
+	JMG_CMTB_Main_Game_Control::CMTBLevel = 0;
 	RenCometBustersScoreControl.Cleanup();
 	RenCometBustersList.ClearAllObjects();
 	PlayerPerkSystemControl.ClearPerksList();
 	PerkTypeSystem.Clean_Up();
 }
 void JMG_CMTB_Main_Game_Control::Create_Player_Ship(GameObject *obj,int PlayerNumber)
-{//TODO Reenable if not working correctly
-	/*if (!MiniGamePlayerControlSystem[PlayerNumber].GamePlayerID)
-		return;*/
-	GameObject *Player = Commands->Find_Object(MiniGamePlayerControlSystem[PlayerNumber].GamePlayerID);
-	/*if (!Player)
 	{
-		MiniGamePlayerControlSystem[PlayerNumber].GamePlayerID = 0;
-		MiniGamePlayerControlSystem[PlayerNumber].PlayerID = 0;
-		return;
-	}*/
+	GameObject *Player = Commands->Find_Object(MiniGamePlayerControlSystem[PlayerNumber].GamePlayerID);
 	if (MiniGamePlayerControlSystem[PlayerNumber].RespawnTime > 30 && Player)
 		MiniGamePlayerControlSystem[PlayerNumber].RespawnTime = 30;
 	if (abs(MiniGamePlayerControlSystem[PlayerNumber].LastNewLifeScore-MiniGamePlayerControlSystem[PlayerNumber].Score) > 100000.0f)
@@ -1487,13 +1458,13 @@
 			RenCometBustersList += TypeObject(obj,9.0f,3.0f,UFO);
 		Commands->Set_Model(obj,"UFO");
 		Commands->Set_Animation(obj,"UFO.UFO",true,0,0,-1,true);
-		Commands->Start_Timer(obj,this,Commands->Get_Random(0.25,1.25),5434);
+		Commands->Start_Timer(obj,this,Commands->Get_Random(0.25,1.25)*JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv,5434);
 	}
 	if (number == 5434)
 	{
 		Set_Current_Bullets(obj,1);
 		Set_Current_Clip_Bullets(obj,Commands->Get_Random_Int(0,3));
-		Commands->Start_Timer(obj,this,Commands->Get_Random(0.25,1.25),5434);
+		Commands->Start_Timer(obj,this,Commands->Get_Random(0.25,1.25)*JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv,5434);
 	}
 	if (number == 5435)
 	{
@@ -1512,7 +1483,7 @@
 void JMG_CMTB_UFO_Random_Fire_Control::Killed(GameObject *obj, GameObject *damager)
 {
 	if (!(Get_Int_Parameter("UFOBoss") && RenCometBustersList.CountType(UFOBoss) == 1))
-		if (Commands->Get_Random_Int(0,100) < 20+(CMTBLevel*0.2))// was originally 0.1 and 10
+		if (Commands->Get_Random_Int(0,100) < 20+(JMG_CMTB_Main_Game_Control::CMTBLevel*0.2))// was originally 0.1 and 10
 			JMG_CMTB_Random_Ship_Powerup(Commands->Get_Position(obj));
 	RenCometBustersList.GrantScoreToKiller(damager,250.0f,UFO);
 }
@@ -2001,13 +1972,13 @@
 			Create_2D_Sound_Player(sender,"SFX.Comet_Busters_UI_Failed_Sound");
 			return;
 		}
-		if (PlayerSOSBeaconID)
+		if (JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID)
 		{
 			JmgUtility::DisplayChatMessage(sender,200,200,125,"Sorry, there is already a SOS Beacon deployed, please wait for it to burn out before deploying another!");
 			Create_2D_Sound_Player(sender,"SFX.Comet_Busters_UI_Failed_Sound");
 			return;
 		}
-		if (!(CMTBLevel % 25))
+		if (!(JMG_CMTB_Main_Game_Control::CMTBLevel % 25))
 		{
 			JmgUtility::DisplayChatMessage(sender,200,200,125,"Due to sensor interference, it would do no good to deploy a beacon on this level!");
 			Create_2D_Sound_Player(sender,"SFX.Comet_Busters_UI_Failed_Sound");
@@ -2045,7 +2016,7 @@
 		ShipTargetPos.Z = 1.481f;
 		GameObject *ShipBeacon = Commands->Create_Object("Daves Arrow",ShipTargetPos);
 		Commands->Set_Model(ShipBeacon,"SOS_Beacon");
-		PlayerSOSBeaconID = Commands->Get_ID(ShipBeacon);
+		JMG_CMTB_Main_Game_Control::PlayerSOSBeaconID = Commands->Get_ID(ShipBeacon);
 
 		GameObject *Ship = Commands->Create_Object("CMTB_Cargo_Ship",ShipTargetPos);
 		Commands->Attach_Script(Ship,"JMG_CMTB_Cargo_Ship_Script",Params);
@@ -2079,14 +2050,6 @@
 					sprintf(params,"%d,100,1,1",x);
 					GameObject *Drone = Commands->Create_Object("CMTB_Player_Attack_Drone",Random_Map_Position());
 					Commands->Attach_Script(Drone,"JMG_CMTB_Player_Drone",params);
-					/*for (int j = 0;j < 8;j++)
-						for (int y = 0;y < 2;y++)
-						{
-							char params[32];
-							sprintf(params,"%d",j);
-							GameObject *Drone = Commands->Create_Object("CMTB_Player_Attack_Drone",Random_Map_Position());
-							Commands->Attach_Script(Drone,"JMG_CMTB_Player_Drone",params);
-						}*/
 				}
 				else
 				{
@@ -2099,7 +2062,7 @@
 	}
 	if (message == 77454833)
 	{
-		if (DroneSwarmCount > 2)
+		if (JMG_CMTB_Main_Game_Control::DroneSwarmCount > 2)
 		{
 			JmgUtility::DisplayChatMessage(sender,200,200,125,"Sorry, a drone swarm is already present in this sector!");
 			Create_2D_Sound_Player(sender,"SFX.Comet_Busters_UI_Failed_Sound");
@@ -2458,7 +2421,6 @@
 {
 	if (!damage && damager == Get_Vehicle_Driver(obj) && !ChangingWeapons)
 	{
-		//Set_Current_Bullets(obj,Get_Current_Bullets(obj)+1);
 		if (!OverPoweredWeapons)
 		{
 			if (Get_Current_Total_Bullets(obj) < (ExtraShotActive ? 5 : 4))
@@ -2467,11 +2429,6 @@
 				else
 					Set_Current_Clip_Bullets(obj,Get_Current_Clip_Bullets(obj)+1);
 		}
-		/*else if (DrainPower(obj,4))
-		{
-			Set_Current_Bullets(obj,0);
-			Set_Current_Clip_Bullets(obj,0);
-		}*/
 		RenCometBustersScoreControl.Get_Current_Player_Score_Node(Get_Player_ID(Get_Vehicle_Driver(obj)))->RoundsFired++;
 	}
 	else if (!Commands->Is_A_Star(damager))
@@ -2506,7 +2463,7 @@
 			MiniGamePlayerControlSystem[x].DeathLocation = Commands->Get_Position(obj);
 			MiniGamePlayerControlSystem[x].PlayerShip = NULL;
 			MiniGamePlayerControlSystem[x].ShipObject = NULL;
-			MiniGamePlayerControlSystem[x].HighestLevel = CMTBLevel;
+			MiniGamePlayerControlSystem[x].HighestLevel = JMG_CMTB_Main_Game_Control::CMTBLevel;
 			if (!MiniGamePlayerControlSystem[x].GamePlayerID)
 				continue;
 			GameObject *Player = Commands->Find_Object(MiniGamePlayerControlSystem[x].GamePlayerID);
@@ -2653,10 +2610,10 @@
 		sprintf(anim,"CometSpin%d.CometSpin%d",Random,Random);
 		Commands->Set_Animation(obj,anim,true,0,0,-1,true);
 	}
-	if (Commands->Get_Random(0.0f,1.0f) < 0.25f && CMTBLevel)
-		Set_Current_Clip_Bullets(obj,Commands->Get_Random_Int(0,CMTBLevel)+1);
+	if (Commands->Get_Random(0.0f,1.0f) < 0.25f && JMG_CMTB_Main_Game_Control::CMTBLevel)
+		Set_Current_Clip_Bullets(obj,max((int)((Commands->Get_Random_Int(0,JMG_CMTB_Main_Game_Control::CMTBLevel)+1)*JMG_CMTB_Main_Game_Control::DifficultyMultiplier),1));
 	else
-		Set_Current_Clip_Bullets(obj,CMTBLevel);
+		Set_Current_Clip_Bullets(obj,max((int)(JMG_CMTB_Main_Game_Control::CMTBLevel*JMG_CMTB_Main_Game_Control::DifficultyMultiplier),1));
 	Vector3 Position = Commands->Get_Position(obj);
 	Position.Z = 0.5;
 	GameObject *SPOT = Commands->Create_Object("Daves Arrow",Position);
@@ -2714,7 +2671,7 @@
 	RenCometBustersList -= obj;
 	if (!Get_Int_Parameter("Size"))
 	{
-		if (Commands->Get_Random_Int(0,100) < 10+(CMTBLevel*0.2))// was originally 0.1 and 8
+		if (Commands->Get_Random_Int(0,100) < 10+(JMG_CMTB_Main_Game_Control::CMTBLevel*0.2))// was originally 0.1 and 8
 			JMG_CMTB_Random_Ship_Powerup(Commands->Get_Position(obj));
 		return;
 	}
@@ -2734,7 +2691,7 @@
 		Number = 0;
 		break;
 	}
-	if (Get_Int_Parameter("Size") && CMTBLevel > 10 && Commands->Get_Random_Int(0,100) < (5.0f+CMTBLevel*0.1f))
+	if (Get_Int_Parameter("Size") && JMG_CMTB_Main_Game_Control::CMTBLevel > 10 && Commands->Get_Random_Int(0,100) < (5.0f+JMG_CMTB_Main_Game_Control::CMTBLevel*0.1f))
 	{
 		for (int x = 0;x < Get_Int_Parameter("Size")*2;x++)
 		{
@@ -2840,7 +2797,7 @@
 		}
 		if (MiniGamePlayerControlSystem[machineNumber].endGamePadding)
 			MiniGamePlayerControlSystem[machineNumber].endGamePadding--;
-		if (!GAMEINPROGRESS)
+		if (!JMG_CMTB_Main_Game_Control::GameInProgress)
 		{
 			GameObject *player = Get_Vehicle_Driver(obj);
 			if (player)
@@ -2938,18 +2895,18 @@
 	}
 	if (message == CUSTOM_EVENT_VEHICLE_ENTERED)
 	{
-		if (!GAMEINPROGRESS)
+		if (!JMG_CMTB_Main_Game_Control::GameInProgress)
 			ResetCurrentAbility(sender);
 		if (MiniGamePlayerControlSystem[machineNumber].RespawnTime > 30)
 			MiniGamePlayerControlSystem[machineNumber].RespawnTime = 30;
 		MiniGamePlayerControlSystem[machineNumber].kickoutOfSpecTime = 0;
-		if (!GAMEINPROGRESS)
+		if (!JMG_CMTB_Main_Game_Control::GameInProgress)
 			if (!MiniGamePlayerControlSystem[machineNumber].endGamePadding)
 			Set_HUD_Help_Text_Player_Text(sender,7233,"Press spacebar to start the game!",Vector3(0.19599999f,1.0f,0.19599999f));
 	}
 	if (message == 77454817)
 	{
-		if (!GAMEINPROGRESS)
+		if (!JMG_CMTB_Main_Game_Control::GameInProgress)
 		{
 			JmgUtility::DisplayChatMessage(sender,200,125,200,"A game must be in progress in order to request lives!");
 			return;
@@ -2982,7 +2939,7 @@
 	}
 	if (message >= 77454820 && message <= 77454829)
 	{
-		if (GAMEINPROGRESS)
+		if (JMG_CMTB_Main_Game_Control::GameInProgress)
 		{
 			JmgUtility::DisplayChatMessage(sender,200,200,125,"Sorry, you cannot change your special ability once the game is in progress.");
 			return;
@@ -3151,7 +3108,7 @@
 	NewTarget = 0;
 	NewRandom = true;
 	ArriveDistance = 0;
-	Speed = 0.1f;
+	Speed = max(0.1f,0.1f*JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine);
 	LastPosition = Commands->Get_Position(obj);
 	FollowObjectID = 0;
 	Commands->Set_Obj_Radar_Blip_Color(obj,RADAR_BLIP_COLOR_NOD);
@@ -3173,12 +3130,12 @@
 		if (JmgUtility::SimpleDistance(Pos,LastPosition) > 0.05)
 		{
 			StuckCount = 0;
-			Speed = Clamp_Value(Speed+0.05f,0.1f,1.25f+CMTBLevel*0.01f);
+			Speed = max(0.1f,Clamp_Value(Speed+0.05f*JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine,0.1f,(1.25f+JMG_CMTB_Main_Game_Control::CMTBLevel*0.01f)*JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine));
 		}
 		else
 		{
 			NewRandom = true;
-			Speed = 0.1f;
+			Speed = max(0.1f,0.1f*JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine);
 			GameObject *FollowObject = Commands->Find_Object(FollowObjectID);
 			if (FollowObject)
 			{
@@ -3268,7 +3225,7 @@
 void JMG_CMTB_Motion_Mine::Killed(GameObject *obj, GameObject *damager)
 {
 	if (!(Get_Int_Parameter("Is_Boss") && RenCometBustersList.CountType(MineBoss) == 1))
-		if (Commands->Get_Random_Int(0,100) < 15+(CMTBLevel*0.2))// was 0.1 and 12
+		if (Commands->Get_Random_Int(0,100) < 15+(JMG_CMTB_Main_Game_Control::CMTBLevel*0.2))// was 0.1 and 12
 			JMG_CMTB_Random_Ship_Powerup(Commands->Get_Position(obj));
 	Commands->Create_Explosion("Explosion_Comet_Small",Commands->Get_Position(obj),0);
 	RenCometBustersList.GrantScoreToKiller(damager,200,Mine);
@@ -3332,7 +3289,7 @@
 						break;
 					}
 			}
-		Commands->Start_Timer(obj,this,Commands->Get_Random(5.0f,8.75f),5437);
+		Commands->Start_Timer(obj,this,Commands->Get_Random(5.0f,8.75f)*JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv,5437);
 	}
 }
 void JMG_CMTB_The_Moon_Script::Damaged(GameObject *obj,GameObject *damager,float damage)
@@ -3346,11 +3303,11 @@
 }
 void JMG_CMTB_The_Moon_Script::Killed(GameObject *obj, GameObject *damager)
 {
-	if (damager || !GAMEINPROGRESS)//TODO remove this to remove end game lage blast
+	if (damager || !JMG_CMTB_Main_Game_Control::GameInProgress)//TODO remove this to remove end game lage blast
 	{
 		moonKilled = true;
 		Commands->Create_Explosion_At_Bone("Explosion_Moon",obj,"Scale",0);
-		int Number = (int)(CMTBLevel*0.2f);
+		int Number = (int)(JMG_CMTB_Main_Game_Control::CMTBLevel*0.2f);
 		char params[512];
 		sprintf(params,"%d,%.3f %.3f %.3f",3,Commands->Get_Position(obj).X,Commands->Get_Position(obj).Y,Commands->Get_Position(obj).Z);
 		for (int x = 0;x < Number;x++)
@@ -3370,7 +3327,7 @@
 }
 void JMG_CMTB_The_Moon_Script::Destroyed(GameObject *obj)
 {
-	if (!moonKilled && GAMEINPROGRESS)
+	if (!moonKilled && JMG_CMTB_Main_Game_Control::GameInProgress)
 	{
 		GameObject *moonHolder = Commands->Find_Object(JMG_CMTB_Main_Game_Control::MoonHolderID);
 		if (moonHolder)
@@ -3760,10 +3717,7 @@
 		GiveUpTime = 30;
 		ReaimRequired = true;
 		EnemyID = TargetID;
-		NearestDistance = ShortDistance;/*
-		char msg[245];
-		sprintf(msg,"MESSAGE %s",Commands->Get_Preset_Name(seen));
-		Console_Input(msg);*/
+		NearestDistance = ShortDistance;
 	}
 }
 void JMG_CMTB_Cargo_Ship_Turret::Custom(GameObject *obj,int message,int param,GameObject *sender)
@@ -3831,8 +3785,8 @@
 					Vector3 Movement = Vector3(LastPosition[0].X - LastPosition[1].X,LastPosition[0].Y - LastPosition[1].Y,0.0f);
 					Vector3 Movement2 = Vector3(LastPosition[1].X - LastPosition[2].X,LastPosition[1].Y - LastPosition[2].Y,0.0f);
 					Vector3 Acceleration = Vector3(SafeDiv(Movement.X,Movement2.X),SafeDiv(Movement.Y,Movement2.Y),0.0f);
-					TargetSpot.X += (/*Acceleration.X **/10.0f * Movement.X * TravelTime);
-					TargetSpot.Y += (/*Acceleration.Y **/10.0f * Movement.Y * TravelTime);
+					TargetSpot.X += (10.0f * Movement.X * TravelTime);
+					TargetSpot.Y += (10.0f * Movement.Y * TravelTime);
 					TargetSpot.Z = Commands->Get_Bone_Position(obj,"Barrel").Z;
 
 					ActionParamsStruct params;
@@ -3878,7 +3832,7 @@
 void JMG_CMTB_Player_Drone::Created(GameObject *obj)
 {
 	if (!Get_Int_Parameter("PlayerEscort"))
-		DroneSwarmCount++;
+		JMG_CMTB_Main_Game_Control::DroneSwarmCount++;
 	ShieldOverride = false;
 	SearchTimeDelay = 0;
 	TargetSize = 0.0f;
@@ -4096,12 +4050,6 @@
 				Commands->Action_Reset(obj,100);
 			}
 		}
-		/*if (!Get_Current_Total_Bullets(obj))
-		{
-			Set_Current_Bullets(obj,2);
-			PrimaryFire = true;
-			Drone_Attack(obj);
-		}*/
 		AI_Update(obj);
 		if ((Commands->Get_Bone_Position(obj,"LWing").Z > Pos.Z || Commands->Get_Bone_Position(obj,"RWing").Z > Pos.Z) && !ShieldOverride)
 		{
@@ -4142,7 +4090,7 @@
 void JMG_CMTB_Player_Drone::Destroyed(GameObject *obj)
 {
 	if (!Get_Int_Parameter("PlayerEscort"))
-		DroneSwarmCount--;
+		JMG_CMTB_Main_Game_Control::DroneSwarmCount--;
 	MyObject = NULL;
 	RenCometBustersList -= obj;
 	for (int x = 0;x < 2;x++)
@@ -4209,8 +4157,6 @@
 		{
 			if (!SearchTimeDelay)
 			{
-				//if (abs(TargetPos.X) > 75.0f || abs(TargetPos.Y) > 75.0f)
-				//	TargetPos = Vector3(Commands->Get_Random(-70.0f,70),Commands->Get_Random(-70.0f,70.0f),0.2f);
 				SearchTimeDelay = Commands->Get_Random_Int(5,15);
 				Distance = 100.0f;
 				TargetPos = Commands->Get_Position(obj);
@@ -4340,7 +4286,6 @@
 	davesArrowId = Commands->Get_ID(DavesArrow);
 	Commands->Start_Timer(obj,this,0.1f,1);
 }
-
 void JMG_CMTB_Vehicle_Face_Turret::Timer_Expired(GameObject *obj, int number)
 {	
 	if (number == 1)
@@ -4351,13 +4296,133 @@
 		Commands->Start_Timer(obj,this,0.1f,1);
 	}
 }
-
 void JMG_CMTB_Vehicle_Face_Turret::Destroyed(GameObject *obj)
 {
 	GameObject *davesArrow = Commands->Find_Object(davesArrowId);
 	if (davesArrow)
 		Commands->Destroy_Object(davesArrow);
 }
+void JMG_CMTB_Poke_End_Map::Created(GameObject *obj)
+{
+	Commands->Set_Animation(obj,"powerbox.powerbox",false,0,0.0,0.0,false);
+	startDelay = 25;
+	time = 0;
+	Commands->Start_Timer(obj,this,1.0f,1);
+}
+void JMG_CMTB_Poke_End_Map::Poked(GameObject *obj,GameObject *poker)
+{
+	if (!JMG_CMTB_Main_Game_Control::EndGameSwitchEnabled)
+	{
+		JmgUtility::DisplayChatMessage(poker,0,255,0,"Sorry, this switch is not enabled.");
+		return;
+	}
+	if (JMG_CMTB_Main_Game_Control::GameInProgress)
+	{
+		JmgUtility::DisplayChatMessage(poker,0,255,0,"Please wait for the current game to end before pulling the switch.");
+		return;
+	}
+	if (startDelay)
+	{
+		char startDelayMsg[220];
+		sprintf(startDelayMsg,"Please wait %d seconds before pulling the switch.",startDelay);
+		JmgUtility::DisplayChatMessage(poker,0,255,0,startDelayMsg);
+		return;
+	}
+	if (time)
+	{
+		FlipSwitch(obj,0.0f);
+		Console_Input("win 0");
+		return;
+	}
+	time = 5;
+	JmgUtility::DisplayChatMessage(poker,0,255,0,"Pull the switch all the way down to proceed to the next map.");
+	FlipSwitch(obj,1.0f);
+}
+void JMG_CMTB_Poke_End_Map::Timer_Expired(GameObject *obj, int number)
+{	
+	if (number == 1)
+	{
+		if (startDelay)
+		{
+			startDelay--;
+			if (!startDelay)
+				FlipSwitch(obj,2.0f);
+		}
+		if (time)
+		{
+			time--;
+			if (!time)
+				FlipSwitch(obj,2.0f);
+		}
+		Commands->Start_Timer(obj,this,1.0f,1);
+	}
+}
+void JMG_CMTB_Poke_End_Map::FlipSwitch(GameObject *obj,float frame)
+{
+	Vector3 soundPos = Commands->Get_Position(obj);
+	soundPos.Z += 1.25f;
+	Commands->Create_Sound("SFX.Comet_Busters_Flip_Switch",soundPos,obj);
+	Commands->Set_Animation(obj,"powerbox.powerbox",false,0,frame,frame,false);
+}
+void JMG_CMTB_Poke_Change_Difficulty::Created(GameObject *obj)
+{
+	difficulty = 1;
+	JMG_CMTB_Main_Game_Control::DifficultyMultiplier = 1.0f;
+	JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine = 1.0f;
+	JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv = 1.0f;
+	Commands->Set_Animation(obj,"powerbox2.powerbox2",false,0,1.0,1.0,false);
+}
+void JMG_CMTB_Poke_Change_Difficulty::Poked(GameObject *obj,GameObject *poker)
+{
+	if (JMG_CMTB_Main_Game_Control::GameInProgress)
+	{
+		JmgUtility::DisplayChatMessage(poker,0,255,0,"Please wait for the current game to end before pulling the switch.");
+		return;
+	}
+	Vector3 soundPos = Commands->Get_Position(obj);
+	soundPos.Z += 1.25f;
+	Commands->Create_Sound("SFX.Comet_Busters_Flip_Switch",soundPos,obj);
+	difficulty++;
+	if (difficulty >= 4)
+		difficulty = 0;
+	RenCometBustersScoreControl.SaveData();
+	RenCometBustersScoreControl.Cleanup();
+	switch (difficulty)
+	{
+	case 0:
+		Commands->Set_Animation(obj,"powerbox2.powerbox2",false,0,0.0f,0.0f,false);
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplier = 0.5f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine = 0.75f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv = 2.0f;
+		RenCometBustersScoreControl.LoadData(0);
+		JmgUtility::MessageAllPlayers(6,145,148,"[DIFFICULTY SET TO EASY]");
+		break;
+	case 1:
+		Commands->Set_Animation(obj,"powerbox2.powerbox2",false,0,1.0f,1.0f,false);
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplier = 1.0f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine = 1.0f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv = 1.0f;
+		RenCometBustersScoreControl.LoadData(1);
+		JmgUtility::MessageAllPlayers(6,145,148,"DIFFICULTY SET TO NORMAL]");
+		break;
+	case 2:
+		Commands->Set_Animation(obj,"powerbox2.powerbox2",false,0,2.0f,2.0f,false);
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplier = 2.0f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine = 1.5f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv = 0.75f;
+		RenCometBustersScoreControl.LoadData(2);
+		JmgUtility::MessageAllPlayers(6,145,148,"[DIFFICULTY SET TO HARD]");
+		break;
+	case 3:
+		Commands->Set_Animation(obj,"powerbox2.powerbox2",false,0,3.0f,3.0f,false);
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplier = 3.0f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierMine = 2.0f;
+		JMG_CMTB_Main_Game_Control::DifficultyMultiplierInv = 0.5f;
+		RenCometBustersScoreControl.LoadData(3);
+		JmgUtility::MessageAllPlayers(6,145,148,"[DIFFICULTY SET TO DOOMSDAY]");
+		break;
+	}
+}
 ScriptRegistrant<JMG_Create_Ship_On_Poke> JMG_Create_Ship_On_Poke_Registrant("JMG_Create_Ship_On_Poke","CreateSpot:vector3,ShipPreset=Comet_Busters_Ship_Blue:string,SpawnSpotExplosion=Explosion_Clear_Spawn_Point:string,InvisibleObject=Invisible_Spectator_Box:string");
 ScriptRegistrant<JMG_Advanced_Bounce_Zone> JMG_Advanced_Bounce_Zone_Registrant("JMG_Advanced_Bounce_Zone","XAmount=0:float,YAmount=0:float,ZAmount=0:float");
 ScriptRegistrant<JMG_Ship_Random_Hyperspace> JMG_Ship_Random_Hyperspace_Registrant("JMG_Ship_Random_Hyperspace","HyperspacingModel=cometbshs:string,HyperSpaceSound=Ship_Teleport:string");
@@ -4393,4 +4458,6 @@
 ScriptRegistrant<JMG_CMTB_Cargo_Ship_Turret> JMG_CMTB_Cargo_Ship_Turret_Registrant("JMG_CMTB_Cargo_Ship_Turret","");
 ScriptRegistrant<JMG_CMTB_Player_Drone> JMG_CMTB_Player_Drone_Registrant("JMG_CMTB_Player_Drone","PlayerNumber:int,Power:int,RePosition:int,PlayerEscort:int");
 ScriptRegistrant<JMG_CMTB_Vehicle_Face_Turret> JMG_CMTB_Vehicle_Face_Turret_Registrant("JMG_CMTB_Vehicle_Face_Turret","");
+ScriptRegistrant<JMG_CMTB_Poke_End_Map> JMG_CMTB_Poke_End_Map_Registrant("JMG_CMTB_Poke_End_Map","");
+ScriptRegistrant<JMG_CMTB_Poke_Change_Difficulty> JMG_CMTB_Poke_Change_Difficulty("JMG_CMTB_Poke_Change_Difficulty","");
 
diff -uwrN sourceold/scripts/scripts.vcxproj source/scripts/scripts.vcxproj
--- sourceold/scripts/scripts.vcxproj	2017-01-22 19:51:27.964826000 +1000
+++ source/scripts/scripts.vcxproj	2017-02-16 06:25:31.822200800 +1000
@@ -394,6 +394,7 @@
     <ClCompile Include="dan.cpp" />
     <ClCompile Include="DBIKScripts.cpp" />
     <ClCompile Include="DBScripts.cpp" />
+    <ClCompile Include="DB_Innate.cpp" />
     <ClCompile Include="DB_Research_Terminals.cpp" />
     <ClCompile Include="DefinitionFactoryClass.cpp" />
     <ClCompile Include="DefinitionFactoryMgrClass.cpp" />
@@ -576,6 +577,7 @@
     <ClInclude Include="dan.h" />
     <ClInclude Include="DBIKScripts.h" />
     <ClInclude Include="DB_General.h" />
+    <ClInclude Include="DB_Innate.h" />
     <ClInclude Include="DB_Research_Terminals.h" />
     <ClInclude Include="DefenseObjectDefClass.h" />
     <ClInclude Include="Definition.h" />
diff -uwrN sourceold/scripts/scripts.vcxproj.filters source/scripts/scripts.vcxproj.filters
--- sourceold/scripts/scripts.vcxproj.filters	2017-01-22 19:51:27.964826000 +1000
+++ source/scripts/scripts.vcxproj.filters	2017-02-16 06:25:31.824200800 +1000
@@ -371,6 +371,9 @@
     <ClCompile Include="DB_Research_Terminals.cpp">
       <Filter>01. Sources</Filter>
     </ClCompile>
+    <ClCompile Include="DB_Innate.cpp">
+      <Filter>01. Sources</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="ArmedGameObj.h">
@@ -1270,6 +1273,9 @@
     <ClInclude Include="cPlayerKill.h">
       <Filter>02. Headers</Filter>
     </ClInclude>
+    <ClInclude Include="DB_Innate.h">
+      <Filter>01. Sources</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="documentation\cinematics.dox">
