public void Destroy() { // SimThread // UserWorldView // UserSession // World // ModManager? // Replay if (_simThread != null) { _simThread.StopThread(); _simThread = null; } // Wait for thread to be destroyed? Would require update to pause. _started = false; if (_userWorldView != null) { _userWorldView.Destroy(); _userWorldView = null; } if (_userSession != null) { _userSession.Destroy(); _userSession = null; } if (mPrimaryScene != null) { GameObject.Destroy(mPrimaryScene); mPrimaryScene = null; } }
public static void UpdateMesh(Mesh PunchOutMesh, CUserWorldView WorldView, Vector2 Position, float Radius) { List <CSightSegment> segs = GenerateLOSPoints(WorldView, Position, 8.0f); int resolution = segs.Count; int vertCount = resolution + 1; int triCount = resolution; int indexCount = triCount * 3; Vector3[] verts = new Vector3[vertCount]; int[] tris = new int[indexCount]; verts[0] = Vector3.zero; for (int i = 0; i < resolution; ++i) { verts[i + 1] = new Vector3(segs[i].mEnd.x - Position.x, 0.0f, segs[i].mEnd.y - Position.y); tris[i * 3 + 0] = 0; tris[i * 3 + 1] = i + 1; tris[i * 3 + 2] = i + 2; if (i == resolution - 1) { tris[i * 3 + 2] = 1; } } PunchOutMesh.Clear(true); PunchOutMesh.vertices = verts; PunchOutMesh.triangles = tris; }
public static bool IsPlaceable(CUserWorldView WorldView, CItemAsset Asset, int X, int Y, int Rotation) { // Check for collision with other blueprints Bounds bounds = CItem.CalculateBounds(new Vector2(X, Y), Rotation, Asset.mWidth, Asset.mLength); bounds.max -= new Vector3(0.1f, 0.1f, 0.1f); bounds.min += new Vector3(0.1f, 0.1f, 0.1f); for (int i = 0; i < WorldView.mStateViews.Count; ++i) { CItemView v = WorldView.mStateViews[i] as CItemView; if (v != null && v.mBlueprint) { if (v.mBounds.Intersects(bounds)) { return(false); } } } return(IsPlaceable(WorldView.GetTileView(), WorldView.GetCollisionView(), Asset, X, Y, Rotation)); }
public bool Init(CStartParams Params) { mStartParams = Params; CLevelAsset level = CGame.AssetManager.GetAsset <CLevelAsset>(Params.mLevelName); if (level == null) { Debug.LogError("Could not load level " + Params.mLevelName); return(false); } _world = new CWorld(); if (!_world.mScriptManager.Init(Params.mLevelName + CGame.FIBRE_FILE_EXTENSION)) { _world.mScriptManager.Destroy(); return(false); } _userWorldView = new CUserWorldView(); mPrimaryScene = new GameObject("Primary Scene"); mPrimaryScene.transform.position = Vector3.zero; CGame.UIManager.SetupForGameSession(); SCameraState camState = new SCameraState(); camState.mBackgroundColor = new Color(0.18f, 0.18f, 0.18f, 1.0f); camState.SetViewGame(EViewDirection.VD_FRONT); camState.mLockedToMap = true; if (Params.mPlayType == EPlayType.SINGLE) { level.CreateMap(_world.mMap); _world.InitCompanies(); _world.PopulateWithMetaData(level); _world.PostInit(); _world.mMap.GetLevelGOB().transform.SetParent(mPrimaryScene.transform); CPlayer userPlayer = _world.GetFirstPlayablePlayer(); userPlayer.mHumanInput = true; mUserPlayerIndex = userPlayer.mID; camState.mBackgroundColor = level.mBackgroundColor; //_replay.StartRecording("replay"); _userSession = new CUserSession(this, _userWorldView); _world.mScriptManager.Start(_world); } else if (Params.mPlayType == EPlayType.LOAD) { // TODO: Load all state from file. // Base map stuff is also saved into file. // Session, UI, UserWorldView, World //_DeserializeState(CGame.PersistentDataDirectory + CGame.SAVE_DIRECTORY + StateFileName + CGame.SAVE_FILE_EXTENSION); } else if (Params.mPlayType == EPlayType.HOST) { mUserPlayerIndex = Params.mUserPlayerIndex; // TODO: Load level exactly like singleplayer //if (Net.Host(5000)) Debug.Log("Hosting Game"); } else if (Params.mPlayType == EPlayType.CLIENT) { mUserPlayerIndex = Params.mUserPlayerIndex; // TODO: Load level exactly like singleplayer // if (Net.Connect(Datastore.mConfig.mHostIP, 5000)) Debug.Log("Joined Game"); } else if (Params.mPlayType == EPlayType.REPLAY) { mUserPlayerIndex = Params.mUserPlayerIndex; // TODO: Load level exactly like singleplayer //_DeserializeState(CGame.PersistentDataDirectory + CGame.REPLAYS_DIRECTOY + FileName + CGame.REPLAY_FILE_EXTENSION); _replay = new CReplay(); //_replay.StartPlayback(FileName); } _userWorldView.Init(this, _world, _userSession, mUserPlayerIndex); _simThread = new CSimThread(this); camState.mTargetPosition = _world.mPlayers[mUserPlayerIndex].GetSpawnPos().ToWorldVec3(); CGame.CameraManager.SetCamState(camState); /* * SDecalInfo decalInfo = new SDecalInfo(); * decalInfo.mType = CDecal.EDecalType.TEXT; * decalInfo.mText = "Paperwork"; * decalInfo.mSize = new Vector2(1, 1); * decalInfo.mPosition = new Vector3(13, 0.1f, 11); * decalInfo.mRotation = Quaternion.Euler(90, 0, 0); * decalInfo.mColor = new Color(0.6f, 0.6f, 0.6f, 1.0f); * decalInfo.mVis = CDecal.EDecalVis.LOS; * _world.SpawnDecal(0, decalInfo); * * decalInfo.mType = CDecal.EDecalType.IMAGE; * decalInfo.mPosition = new Vector3(13, 0.1f, 14); * decalInfo.mSize = new Vector2(4, 4); * decalInfo.mRotation = Quaternion.Euler(90, 0, 0); * decalInfo.mVisualId = 1; * //decalInfo.mColor = new Color(0.5f, 0.5f, 0.5f, 1.0f); * _world.SpawnDecal(0, decalInfo); * * decalInfo.mType = CDecal.EDecalType.TEXT; * decalInfo.mText = "Lobby"; * decalInfo.mSize = new Vector2(0.8f, 0.8f); * decalInfo.mPosition = new Vector3(7, 0.1f, 13); * decalInfo.mRotation = Quaternion.Euler(90, 90, 0); * decalInfo.mColor = new Color(1,1,1,1); * decalInfo.mVis = CDecal.EDecalVis.FOW; * _world.SpawnDecal(0, decalInfo); */ //_world.SpawnItem(CGame.AssetManager.GetAsset<CItemAsset>("item_couch_test"), new Vector2(10, 6), 0, 0); /* * for (int i = 0; i < 10; ++i) * { * CResume resume = new CResume(); * resume.Generate(_world, 1, 1); * CUnit entity = _world.SpawnUnit(0, resume, new Vector2(20, 20), 0); * } * //*/ // TODO: Do we need to check a map always has correct spawns for players? //_world.SpawnItem(CGame.AssetManager.GetAsset<CItemAsset>("item_spawn"), new Vector2(12, 16), 0, 0); //_world.SpawnItem(CGame.AssetManager.GetAsset<CItemAsset>("item_spawn"), new Vector2(21, 16), 0, 1); return(true); }
public void Init(int PlayerIndex, CUserWorldView WorldView) { _playerIndex = PlayerIndex; _worldView = WorldView; }
/// <summary> /// Get a list of points for building a line-of-site punch out. /// </summary> public static List <CSightSegment> GenerateLOSPoints(CUserWorldView WorldView, Vector2 StartPos, float Radius) { Vector2 start = StartPos; if (CGame.VarShowVisLines.mValue) { CDebug.DrawCircle(Vector3.up, StartPos.ToWorldVec3(), Radius, Color.red, false); CDebug.DrawYRectQuad(start.ToWorldVec3(), 0.25f, 0.25f, new Color(1.0f, 0.4f, 0.2f, 0.4f), false); } List <CVisibilityBlockingSegment> culledSegs = new List <CVisibilityBlockingSegment>(); List <CVisibilityBlockingSegment> visSegs = WorldView.GetVisSegments(); // Get wall segments that intersect view radius. // TODO: Speed up with acceleration structure. for (int i = 0; i < visSegs.Count; ++i) { CVisibilityBlockingSegment seg = visSegs[i]; Vector2 hitA; Vector2 hitB; bool OpenA, OpenB; if (CIntersections.LineVsCircle(seg.mA, seg.mB, StartPos, Radius, out hitA, out hitB, out OpenA, out OpenB)) { culledSegs.Add(new CVisibilityBlockingSegment(hitA, hitB)); if (CGame.VarShowVisLines.mValue) { CDebug.DrawLine(hitA.ToWorldVec3(), hitB.ToWorldVec3(), Color.black, false); } } } List <CSightSegment> lineSegs = new List <CSightSegment>(); if (culledSegs.Count == 0) { // TODO: Could precalculate this and store it, but this only helps improve best case. int count = 46; float interval = (Mathf.PI * 2.0f) / count; for (int i = 0; i < count; ++i) { CSightSegment seg = new CSightSegment(); lineSegs.Add(seg); seg.mEnd = new Vector2(Mathf.Sin(i * interval) * Radius, Mathf.Cos(i * interval) * Radius) + StartPos; } } else { // Find closest intersection points when casting a ray to each segment vertex. // TODO: There are still redundant casts to shared segment verts. for (int i = 0; i < culledSegs.Count; ++i) { CVisibilityBlockingSegment seg = culledSegs[i]; float offset = 0.001f; Vector2 shift; float angle = Mathf.Atan2((seg.mA - start).x, (seg.mA - start).y); shift.x = Mathf.Sin(angle - offset) * Radius + start.x; shift.y = Mathf.Cos(angle - offset) * Radius + start.y; lineSegs.Add(_IntersectLOSRayWithLines(culledSegs, start, shift, Radius)); shift.x = Mathf.Sin(angle + offset) * Radius + start.x; shift.y = Mathf.Cos(angle + offset) * Radius + start.y; lineSegs.Add(_IntersectLOSRayWithLines(culledSegs, start, shift, Radius)); angle = Mathf.Atan2((seg.mB - start).x, (seg.mB - start).y); shift.x = Mathf.Sin(angle - offset) * Radius + start.x; shift.y = Mathf.Cos(angle - offset) * Radius + start.y; lineSegs.Add(_IntersectLOSRayWithLines(culledSegs, start, shift, Radius)); shift.x = Mathf.Sin(angle + offset) * Radius + start.x; shift.y = Mathf.Cos(angle + offset) * Radius + start.y; lineSegs.Add(_IntersectLOSRayWithLines(culledSegs, start, shift, Radius)); if (CGame.VarShowVisLines.mValue) { //CDebug.DrawYRectQuad(seg.mA.ToWorldVec3(), 0.25f, 0.25f, new Color(1.0f, 0.4f, 0.2f, 0.4f), false); //CDebug.DrawYRectQuad(seg.mB.ToWorldVec3(), 0.25f, 0.25f, new Color(0.2f, 0.4f, 1.0f, 0.4f), false); CDebug.DrawLine(seg.mA.ToWorldVec3(), seg.mB.ToWorldVec3(), Color.red, false); } } // Sort intersections by angle. lineSegs.Sort((x, y) => { if (x.mAngle > y.mAngle) { return(1); } if (x.mAngle < y.mAngle) { return(-1); } return(0); }); // Cull redundant intersections. for (int i = 0; i < lineSegs.Count; ++i) { int s1 = lineSegs[i].mSegID; if (s1 == -1) { continue; } int s2 = lineSegs[(i + 1) % lineSegs.Count].mSegID; int s3 = lineSegs[(i + 2) % lineSegs.Count].mSegID; if (s1 == s2 && s1 == s3) { lineSegs.RemoveAt((i + 1) % lineSegs.Count); --i; } } // Regenerate circular caps. for (int i = 0; i < lineSegs.Count; ++i) { CSightSegment s1 = lineSegs[i]; CSightSegment s2 = lineSegs[(i + 1) % lineSegs.Count]; if (s1.mSegID == -1 && s2.mSegID == -1) { float angleD = s2.mAngle - s1.mAngle; if (i == lineSegs.Count - 1) { angleD = s2.mAngle + Mathf.PI * 2 - s1.mAngle; } int count = (int)(angleD / 0.1f); float interval = angleD / count; for (int j = 1; j < count; ++j) { float newAngle = s1.mAngle + interval * j; Vector2 shift; shift.x = Mathf.Sin(newAngle) * Radius + s1.mStart.x; shift.y = Mathf.Cos(newAngle) * Radius + s1.mStart.y; CSightSegment s = new CSightSegment(); s.mStart = s1.mStart; s.mEnd = shift; lineSegs.Insert(i + 1, s); ++i; } if (CGame.VarShowVisLines.mValue) { CDebug.DrawLine(s1.mEnd.ToWorldVec3(), s2.mEnd.ToWorldVec3(), Color.white, false); } } } if (CGame.VarShowVisLines.mValue) { for (int i = 0; i < lineSegs.Count; ++i) { CSightSegment s = lineSegs[i]; if (s.mSegID != -1) { CDebug.DrawLine(s.mStart.ToWorldVec3(), s.mEnd.ToWorldVec3(), Color.green, false); } else { CDebug.DrawYRectQuad(s.mEnd.ToWorldVec3(), 0.25f, 0.25f, Color.magenta, false); CDebug.DrawLine(s.mStart.ToWorldVec3(), s.mEnd.ToWorldVec3(), Color.blue, false); } } } } return(lineSegs); }