public void Update() { bool newPlaceable = IsPlaceable(); if (_placeable != newPlaceable) { _placeable = newPlaceable; if (mType == EPlaceType.ITEM) { if (newPlaceable) { CItemView.SetItemSurfaceColour(mAsset.mItemType, _gob, CGame.COLOR_BLUEPRRINT); } else { CItemView.SetItemSurfaceColour(mAsset.mItemType, _gob, new Color(1.0f, 0.1f, 0.1f)); } } } if (mType == EPlaceType.ITEM) { Color c = CGame.COLOR_BLUEPRRINT; c.a = 0.4f; if (!_placeable) { c = new Color(1.0f, 0.1f, 0.1f, 0.4f); } Vector2 midOffset = CItem.RotationAxisTable[mRotation].Transform(new Vector2(mAsset.mWidth, mAsset.mLength)); float yOff = 0.001f; float oW = 0.1f; // Draw an outline. Vector3 p1 = mPosition + new Vector3(0, yOff, 0); Vector3 p2 = mPosition + new Vector3(0, yOff, midOffset.y); Vector3 p3 = mPosition + new Vector3(midOffset.x, yOff, midOffset.y); Vector3 p4 = mPosition + new Vector3(midOffset.x, yOff, 0); Vector3 p1p2 = (p2 - p1) * 0.5f + p1; Vector3 p2p3 = (p3 - p2) * 0.5f + p2; Vector3 p3p4 = (p4 - p3) * 0.5f + p3; Vector3 p4p1 = (p1 - p4) * 0.5f + p4; CDebug.DrawYRectQuad(p1p2, oW, Mathf.Abs(midOffset.y) - oW, c); CDebug.DrawYRectQuad(p2p3, Mathf.Abs(midOffset.x) + oW, oW, c); CDebug.DrawYRectQuad(p3p4, oW, Mathf.Abs(midOffset.y) - oW, c); CDebug.DrawYRectQuad(p4p1, Mathf.Abs(midOffset.x) + oW, oW, c); } else if (mType == EPlaceType.UNIT) { CDebug.DrawYRectQuad(mPosition, 0.25f, 0.25f, CGame.COLOR_BLUEPRRINT, false); } else if (mType == EPlaceType.VOLUME || mType == EPlaceType.DECAL) { CDebug.DrawBorderQuads(mPosition, new Vector2(1, 1), CGame.COLOR_BLUEPRRINT, false); } }
public ISelectable GetSelectableDesk(Ray R) { float d = float.MaxValue; ISelectable result = null; for (int i = 0; i < mStateViews.Count; ++i) { CItemView itemView = mStateViews[i] as CItemView; if (itemView == null || itemView.mAsset.mItemType != EItemType.DESK || itemView.mBlueprint) { continue; } ISelectable selectable = itemView as ISelectable; if (selectable != null) { if (selectable.Intersect(R, ref d)) { result = selectable; } } } return(result); }
/// <summary> /// Get an item view that is pointing to a proxy item with ID. /// </summary> public CItemView GetItemView(int ItemID) { for (int i = 0; i < mStateViews.Count; ++i) { CItemView view = mStateViews[i] as CItemView; if (view != null) { if (view.mProxyID == ItemID) { return(view); } } } return(null); }
private void _Init(EPlaceType Type, Transform Parent, PlacementDelegate PlacementDelegate) { mType = Type; _placeable = false; _placeDelegate = PlacementDelegate; if (mType == EPlaceType.ITEM) { _gob = mAsset.CreateVisuals(EViewDirection.VD_FRONT); _gob.transform.SetParent(Parent); CItemView.SetItemSurfaceColour(mAsset.mItemType, _gob, CGame.COLOR_BLUEPRRINT); } else if (mType == EPlaceType.UNIT) { mRotation = 225; _gob = GameObject.Instantiate(CGame.PrimaryResources.Prefabs[7] as GameObject); _gob.transform.SetParent(Parent); _gob.transform.rotation = Quaternion.AngleAxis(mRotation, Vector3.up); } }
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)); }
/// <summary> /// Update entire view and alert session of changes. /// </summary> public bool Update(Vector2 MouseFloorPos) { // This is the only time that we lock the world on the primary thread (Except for rare debugging cases in CGameSession). // All state information is copied from the world from the perspective of a player (_viewPlayerIndex). // As little work as possible should be done during the state copy. We want to unlock the world ASAP. CGame.PrimaryThreadProfiler.Push(CProfiler.EID.I_RENDER_TICK); lock (_world) { // TODO: Check for a console var to remain on crash. if (_world.mCrashed) { CGame.PrimaryThreadProfiler.Pop(); return(false); } System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); CGame.PrimaryThreadProfiler.Push(CProfiler.EID.I_RENDER_TICK); // Copy door segments for visibility _world.mMap.TrimStaticVisSegments(); for (int i = 0; i < _world.mItems.Count; ++i) { CItem item = _world.mItems[i]; if (item.mType == CEntity.EType.ITEM_DOOR && !item.mBluerprint && !(item as CItemDoor).mOpen) { _world.mMap.mStaticVisSegments.Add(new CVisibilityBlockingSegment(item.ItemToWorldSpacePosition(new Vector2(0, 1)), item.ItemToWorldSpacePosition(new Vector2(1, 1)))); } } // Copy all the state!!!!! mTransientEvents = _world.SwapAndClearTransientEvents(); mPaydayTimerNormalised = 1.0f - _world.GetPaydayTimeNormalize(); mGameTick = _world.mGameTick; // Company Data // ... // Player Data for (int i = 0; i < mPlayerViews.Length; ++i) { CPlayer player = _world.mPlayers[i]; CPlayerView view = mPlayerViews[i]; view.mIndex = player.mID; view.mColor = player.mColor; view.mMoney = player.mMoney; view.mDebt = player.mDebt; view.mSpawnPos = player.GetSpawnPos(); view.mCanInteractWithWorld = player.mCanInteractWithWorld; view.mCanInteractWithUI = player.mCanInteractWithUI; view.mCanControlCamera = player.mCanControlCamera; view.mMusicTrack = player.mMusicTrack; view.mShowUI = player.mShowUI; view.mCamPosition = player.mCamPosition; view.mCamSpeed = player.mCamSpeed; view.mAvailableItems = player.mAvailableItems.ToArray(); } // TODO: Should just iterate all entities and ask them if they are valid for state copy. // Unit Data // TODO: Surely the sim knows what units are visible to the player already? for (int i = 0; i < _world.mUnits.Count; ++i) { if (_world.mUnits[i].IsVisibleToPlayer(_viewPlayerIndex)) { if (_world.mUnits[i].mStateView == null) { CUnitView view = new CUnitView(); view.mState = CStateView.EState.NEW; mStateViews.Add(view); view.CopyInitialState(_world.mUnits[i]); view.Init(_viewPlayerIndex, this); _world.mUnits[i].mStateView = view; } else { _world.mUnits[i].mStateView.mState = CStateView.EState.UPDATING; } _world.mUnits[i].mStateView.CopyState(_world.mUnits[i]); } else { _world.mUnits[i].mStateView = null; } } // Pickups for (int i = 0; i < _world.mPickups.Count; ++i) { if (_world.mPickups[i].IsVisibleToPlayer(_viewPlayerIndex)) { if (_world.mPickups[i].mStateView == null) { CPickupView view = new CPickupView(); view.mState = CStateView.EState.NEW; mStateViews.Add(view); view.CopyInitialState(_world.mPickups[i]); view.Init(_viewPlayerIndex, this); _world.mPickups[i].mStateView = view; } else { _world.mPickups[i].mStateView.mState = CStateView.EState.UPDATING; } _world.mPickups[i].mStateView.CopyState(_world.mPickups[i]); } else { _world.mPickups[i].mStateView = null; } } // Missiles for (int i = 0; i < _world.mMissiles.Count; ++i) { if (_world.mMissiles[i].IsVisibleToPlayer(_viewPlayerIndex)) { if (_world.mMissiles[i].mStateView == null) { CMissileView view = new CMissileView(); view.mState = CStateView.EState.NEW; mStateViews.Add(view); view.CopyInitialState(_world.mMissiles[i]); view.Init(_viewPlayerIndex, this); _world.mMissiles[i].mStateView = view; } else { _world.mMissiles[i].mStateView.mState = CStateView.EState.UPDATING; } _world.mMissiles[i].mStateView.CopyState(_world.mMissiles[i]); } else { _world.mMissiles[i].mStateView = null; } } // Item View Data for (int i = 0; i < _world.mItemProxies[_viewPlayerIndex].Count; ++i) { CItemProxy proxy = _world.mItemProxies[_viewPlayerIndex][i]; if (proxy.mVisuals == null) { // new CItemView view = new CItemView(); view.mState = CStateView.EState.NEW; mStateViews.Add(view); view.CopyInitialState(proxy); view.Init(_viewPlayerIndex, this); proxy.mVisuals = view; } else { proxy.mVisuals.mState = CStateView.EState.UPDATING; } proxy.mVisuals.CopyState(proxy); } // Contract Data for (int i = 0; i < _world.mContracts.Count; ++i) { CContract contract = _world.mContracts[i]; // TODO: All contracts always part of user view state? //if (contract.mOwner == -1 || contract.mOwner == _viewPlayerIndex) if (true) { if (contract.mStateView == null) { // new CContractView view = new CContractView(); view.mState = CStateView.EState.NEW; mStateViews.Add(view); view.CopyInitialState(contract); view.Init(_viewPlayerIndex, this); contract.mStateView = view; } else { contract.mStateView.mState = CStateView.EState.UPDATING; } contract.mStateView.CopyState(contract); } else { contract.mStateView = null; } } // Resume View Data for (int i = 0; i < _world.mResumes.Count; ++i) { CResume resume = _world.mResumes[i]; if (resume.mOwner != -1) { if (resume.mStateView == null) { // new CResumeView view = new CResumeView(); view.mState = CStateView.EState.NEW; mStateViews.Add(view); view.CopyInitialState(resume); view.Init(_viewPlayerIndex, this); resume.mStateView = view; } else { resume.mStateView.mState = CStateView.EState.UPDATING; } resume.mStateView.CopyState(resume); } else { resume.mStateView = null; } } // Decal View Data for (int i = 0; i < _world.mDecals.Count; ++i) { CDecal decal = _world.mDecals[i]; // TODO: Allow decals to be visible to certain players only. if (decal.mStateView == null) { // new CDecalView view = new CDecalView(); view.mState = CStateView.EState.NEW; mStateViews.Add(view); view.CopyInitialState(decal); view.Init(_viewPlayerIndex, this); decal.mStateView = view; } else { decal.mStateView.mState = CStateView.EState.UPDATING; } decal.mStateView.CopyState(decal); } sw.Stop(); //Debug.Log("Copy " + sw.Elapsed.TotalMilliseconds + "ms"); CGame.PrimaryThreadProfiler.Pop(); } CGame.PrimaryThreadProfiler.Pop(); // NOTE: Now that the state has been copied from the simulation and we have released the thread lock, we can // process the new state and make appropriate changes to the Unity scene. CGame.UIManager.PlayMusic(mPlayerViews[_viewPlayerIndex].mMusicTrack); CGame.UIManager.mShowUI = mPlayerViews[_viewPlayerIndex].mShowUI; _userSession.mUserInteraction = mPlayerViews[_viewPlayerIndex].mCanInteractWithWorld; CGame.CameraManager.SetInteractable(mPlayerViews[_viewPlayerIndex].mCanControlCamera); CGame.CameraManager.SetLerpSpeed(mPlayerViews[_viewPlayerIndex].mCamSpeed); // TODO: Different bool to control tracked camera? if (!mPlayerViews[_viewPlayerIndex].mCanControlCamera) { // TODO: Immediate of on different cam step. CGame.CameraManager.SetTargetPosition(mPlayerViews[_viewPlayerIndex].mCamPosition, false, mPlayerViews[_viewPlayerIndex].mCamPosition.w); } for (int i = 0; i < mTransientEvents.Count; ++i) { CTransientEvent tev = mTransientEvents[i]; // Ignore events that occured over 1 second ago. if (mGameTick > tev.mGameTick + 20) { continue; } if ((tev.mViewerFlags & (1 << _viewPlayerIndex)) == 0) { continue; } if (tev.mType == CTransientEvent.EType.SOUND) { //AudioSource.PlayClipAtPoint(CGame.PrimaryResources.AudioClips[tev.mData], tev.mPosition, 1.0f); AudioClip clip = CGame.PrimaryResources.AudioClips[tev.mData]; GameObject source = new GameObject("AudioPosOneShot"); source.transform.SetParent(_userSession.mPrimaryScene.transform); source.transform.position = tev.mPosition; AudioSource audio = source.AddComponent <AudioSource>(); audio.clip = clip; audio.outputAudioMixerGroup = CGame.UIResources.SoundsMixer; audio.spatialBlend = 1.0f; audio.Play(); GameObject.Destroy(source, clip.length); } else if (tev.mType == CTransientEvent.EType.UI_SOUND) { CGame.UIManager.PlaySound(CGame.PrimaryResources.AudioClips[tev.mData]); } else if (tev.mType == CTransientEvent.EType.EFFECT) { GameObject.Instantiate(CGame.PrimaryResources.Particles, tev.mPosition, Quaternion.identity); //CGame.CameraManager.Shake(); } else if (tev.mType == CTransientEvent.EType.PAYDAY) { CGame.UIManager.PlaySound(CGame.PrimaryResources.AudioClips[17]); } else if (tev.mType == CTransientEvent.EType.NOTIFY) { Debug.Log("Got notify: " + tev.mMessage); _userSession.CreateNotifyStackIcon(2, null, CGame.AssetManager.GetAsset <CItemAsset>(tev.mMessage)); } } for (int i = 0; i < mStateViews.Count; ++i) { if (!mStateViews[i].Update(_userSession)) { mStateViews.RemoveAt(i); --i; } else { mStateViews[i].mState = CStateView.EState.WAITING; mStateViews[i].DrawDebugPrims(); } } /* * for (int i = 0; i < _stateViews.Count; ++i) * { * _stateViews[i].DrawDebugPrims(); * } */ if (CGame.VarShowFlowField.mValue) { DrawFlowField(); } if (CGame.VarShowNavMesh.mValue) { mNavMesh.DebugDraw(); } if (CGame.VarShowNavRect.mValue > 0) { _world.mMap.mNavMeshes[CGame.VarShowNavRect.mValue - 1].DebugDraw(); } return(true); }