protected void OnTransitionStart(WIState oldState, WIState newState, WIState currentState) { if (oldState != null) { if (oldState.FXObject != null) { GameObject.Destroy(oldState.FXObject, 1.0f); } } if (Application.isPlaying) { if (!string.IsNullOrEmpty(newState.FXOnChange)) { newState.FXObject = FXManager.Get.SpawnFX(worlditem, newState.FXOnChange); newState.FXObject.transform.localPosition = newState.FXOffset; } if (newState.SoundType != MasterAudio.SoundType.None) { MasterAudio.PlaySound(newState.SoundType, newState.StateObject.transform, newState.SoundOnChange); } if (!string.IsNullOrEmpty(newState.AnimationOnChange)) { if (newState.StateObject.GetComponent <Animation>() != null) { newState.StateObject.GetComponent <Animation>().Play(newState.AnimationOnChange); } } if (newState.EarthQuakeOnChange > 0f) { Player.Local.DoEarthquake(newState.EarthQuakeOnChange); } } }
protected IEnumerator SetStateOverTime(WIState oldState, WIState newState, double transitionStartTime, double transitionDuration) { if (!Application.isPlaying) { yield break; } double transitionEndTime = transitionStartTime + transitionDuration; float normalizedTransition = 0f; //get the world light if we're using one if (!newState.UseLight) { if (worlditem.Light != null) { //whoops, better get rid of this one LightManager.DeactivateWorldLight(worlditem.Light); } } else { //if we are using one Transform lightParent = worlditem.tr; if (worlditem.Is(WIMode.Equipped | WIMode.Stacked)) { lightParent = Player.Local.Tool.ToolDoppleganger.transform; } WorldLightType wlType = WorldLightType.Exterior; if (worlditem.Is(WIMode.Equipped)) { wlType = WorldLightType.Equipped; } else { while (worlditem.Group == null) { yield return(null); } if (worlditem.Group.Props.Interior || worlditem.Group.Props.TerrainType == LocationTerrainType.BelowGround) { wlType = WorldLightType.InteriorOrUnderground; } } worlditem.Light = LightManager.GetWorldLight(worlditem.Light, newState.LightTemplateName, lightParent, newState.LightOffset, newState.LightRotation, true, wlType); } while (WorldClock.AdjustedRealTime < transitionEndTime) { normalizedTransition = (float)((WorldClock.AdjustedRealTime - transitionStartTime) / (transitionEndTime - transitionStartTime)); BlendState(oldState, newState, mCurrentState, normalizedTransition); yield return(null); } //finish transition BlendState(oldState, newState, mCurrentState, 1.0f); OnTransitionFinish(oldState, newState, mCurrentState); yield break; }
public void OnPlayerUse() { for (int i = 0; i < States.Count; i++) { WIState state = States [i]; if (state != mCurrentState && state.CanUseToSelect) { SetState(state.Name); break; } } }
public void PopulateOptionsList(List <WIListOption> options, List <string> message) { if (mCurrentState == null || !mCurrentState.IsInteractive) { return; } for (int i = 0; i < States.Count; i++) { WIState state = States [i]; if (!string.IsNullOrEmpty(state.OptionListDisplay)) { WIListOption option = new WIListOption(state.OptionListDisplay, "SetWIState" + state.Name); if (mCurrentState.Name == state.Name) { option.Disabled = true; } options.Add(option); } } }
public void EditorCreateStates() { WorldItem worlditem = gameObject.GetComponent <WorldItem> (); worlditem.Colliders.Clear(); worlditem.Renderers.Clear(); worlditem.Props.Global.ParentColliderType = WIColliderType.None; States.Clear(); foreach (Transform child in transform) { child.gameObject.tag = "StateChild"; WIState newState = new WIState(); newState.Name = child.name; newState.Suffix = child.name; BoxCollider bc = child.gameObject.GetOrAdd <BoxCollider> (); bc.enabled = false; switch (newState.Name) { case "Rotten": case "Burned": case "Preserved": newState.IsPermanent = true; child.gameObject.SetActive(false); break; case "Raw": child.gameObject.SetActive(true); break; default: child.gameObject.SetActive(false); break; } States.Add(newState); } }
//this editor function does a bunch of sanity-check stuff //to make sure that the foodstuff is set up properly public override void InitializeTemplate() { mCurrentProps = null; if (State.PotentialProps.Count > 0) { WIStates states = null; if (gameObject.HasComponent <WIStates>(out states)) { for (int i = 0; i < State.PotentialProps.Count; i++) { if (State.PotentialProps[i].Name == states.DefaultState) { mCurrentProps = State.PotentialProps[i]; break; } } } if (mCurrentProps == null) { for (int i = 0; i < State.PotentialProps.Count; i++) { if (State.PotentialProps[i].Name == "Raw") { mCurrentProps = State.PotentialProps[i]; break; } } } if (mCurrentProps == null) { //f**k it mCurrentProps = State.PotentialProps[0]; } } return; if (Application.isPlaying) { return; } if (worlditem.Props.Global.MaterialType != WIMaterialType.Plant && worlditem.Props.Global.MaterialType != WIMaterialType.Flesh) { worlditem.Props.Global.MaterialType = WIMaterialType.Food; } if (State.PotentialProps.Count == 0) { Debug.Log("Didn't find any potential food props, creating 'Raw' now"); FoodStuffProps props = new FoodStuffProps(); props.Name = "Raw"; props.Type = FoodStuffEdibleType.Edible; props.HungerRestore = PlayerStatusRestore.B_OneFifth; props.Perishable = false; State.PotentialProps.Add(props); } else { Debug.Log("Found " + State.PotentialProps.Count.ToString() + " props"); } if (worlditem.States != null) { Debug.Log("worlditem has states"); foreach (WIState state in worlditem.States.States) { bool foundAccompanyingFoodState = false; foreach (FoodStuffProps props in this.State.PotentialProps) { if (props.Name == state.Name) { foundAccompanyingFoodState = true; } } if (!foundAccompanyingFoodState) { Debug.Log("Didn't find accompanying food state in " + worlditem.name + " for worlditem state: " + state.Name + ", adding now"); FoodStuffProps newProps = new FoodStuffProps(); newProps.Name = state.Name; //there are some common states that we can make guesses for switch (state.Name) { case "Rotten": newProps.Type = FoodStuffEdibleType.Edible; newProps.HungerRestore = PlayerStatusRestore.B_OneFifth; newProps.ConditionChance = 0.95f; newProps.ConditionName = "FoodPoisoning"; newProps.Perishable = false; break; case "Raw": newProps.Type = FoodStuffEdibleType.Edible; newProps.HungerRestore = PlayerStatusRestore.C_TwoFifths; newProps.Perishable = true; break; case "Cooked": newProps.Type = FoodStuffEdibleType.Edible; newProps.HungerRestore = PlayerStatusRestore.F_Full; newProps.Perishable = true; break; case "Burned": newProps.Type = FoodStuffEdibleType.Edible; newProps.HungerRestore = PlayerStatusRestore.B_OneFifth; newProps.Perishable = false; break; case "Preserved": case "Dried": newProps.Type = FoodStuffEdibleType.Edible; newProps.HungerRestore = PlayerStatusRestore.D_ThreeFifths; newProps.Perishable = false; break; default: newProps.Type = FoodStuffEdibleType.None; //make it inedible break; } State.PotentialProps.Add(newProps); } } } bool requiresRottenState = false; foreach (FoodStuffProps props in State.PotentialProps) { if (props.Name == "Raw") { bool foundCooked = false; foreach (FoodStuffProps cookedProps in State.PotentialProps) { if (cookedProps.Name == "Cooked") { foundCooked = true; props.ConditionName = "FoodPoisoning"; props.ConditionChance = 0.25f; break; } } if (!foundCooked) { props.ConditionName = string.Empty; props.ConditionChance = 0f; } else { gameObject.GetOrAdd <Photosensitive>(); } } requiresRottenState |= props.Perishable; if (props.Name == "Rotten") { requiresRottenState |= true; } } //check our states against our props and make sure there's parity if (State.PotentialProps.Count > 1) { if (worlditem.States == null) { worlditem.States = worlditem.gameObject.AddComponent <WIStates>(); worlditem.InitializeTemplate(); return; } //now attempt to match our props up against our states and make sure there's parity foreach (FoodStuffProps props in State.PotentialProps) { WIState existingState = null; bool foundAccompanyingState = false; foreach (WIState state in worlditem.States.States) { if (state.Name == props.Name) { if (!foundAccompanyingState) { existingState = state; foundAccompanyingState = true; } if (state.Name == "Rotten") { requiresRottenState = true; } } } if (!foundAccompanyingState) { WIState newState = null; Debug.Log("Didn't find accompanying worlditem state in " + worlditem.name + " for food state: " + props.Name + ", adding now"); if (worlditem.States.States.Count == 0) { //create a state from the base object - this will also strip the base object of renderers etc. newState = WorldItems.CreateTemplateState(worlditem, props.Name, worlditem.gameObject); } else { //otherwise just make a copy from the first existing state, we'll clean it up later newState = WorldItems.CreateTemplateState(worlditem, props.Name, worlditem.States.States[0].StateObject); } existingState = newState; } if (existingState != null) { existingState.IsInteractive = true; existingState.Suffix = props.Name; existingState.StackName = props.Name + " " + worlditem.Props.Name.StackName; existingState.UnloadWhenStacked = true; existingState.CanEnterInventory = true; existingState.CanBePlaced = true; existingState.CanBeDropped = true; existingState.CanBeCarried = true; switch (existingState.Name) { case "Raw": existingState.IsPermanent = false; break; case "Cooked": existingState.IsPermanent = true; existingState.FXOnChange = "FoodstuffCookedSmoke"; break; case "Rotten": existingState.IsPermanent = true; break; case "Burned": existingState.IsPermanent = true; existingState.FXOnChange = "FoodstuffBurnedSmoke"; break; case "Preserved": case "Dried": existingState.IsPermanent = true; break; default: break; } } } } else { Debug.Log("Only 1 foodstuff props so no need for states"); if (worlditem.States != null && worlditem.States.States.Count == 0) { GameObject.DestroyImmediate(worlditem.States); } } if (requiresRottenState) { Debug.Log("Requires perishable, checking now"); bool hasRottenState = false; bool hasRawState = false; foreach (FoodStuffProps props in State.PotentialProps) { if (props.Name == "Raw") { props.Perishable = true; hasRawState = true; } else if (props.Name == "Rotten") { hasRottenState = true; } } if (!hasRawState) { FoodStuffProps newProps = new FoodStuffProps(); newProps.Name = "Raw"; newProps.Perishable = true; newProps.Type = FoodStuffEdibleType.Edible; newProps.HungerRestore = PlayerStatusRestore.C_TwoFifths; newProps.Perishable = true; State.PotentialProps.Add(newProps); } if (!hasRottenState) { FoodStuffProps newProps = new FoodStuffProps(); newProps.Name = "Rotten"; newProps.Type = FoodStuffEdibleType.Edible; newProps.HungerRestore = PlayerStatusRestore.C_TwoFifths; newProps.ConditionChance = 0.5f; newProps.ConditionName = "FoodPoisoning"; State.PotentialProps.Add(newProps); } } else { Debug.Log("Didn't require rotten state"); } if (worlditem.States != null) { bool foundDefaultState = false; foreach (WIState state in worlditem.States.States) { if (worlditem.States.DefaultState == state.Name) { foundDefaultState = true; break; } } if (!foundDefaultState) { Debug.Log("Didin't find default state " + worlditem.States.DefaultState + ", setting to Raw"); worlditem.States.DefaultState = "Raw"; } } if (worlditem.HasStates) { //now that the worlditem has states it shouldn't have its own mesh stuff //destroy the me now MeshFilter worldItemMF = null; if (worlditem.gameObject.HasComponent <MeshFilter>(out worldItemMF)) { GameObject.DestroyImmediate(worldItemMF); } MeshRenderer worldItemMR = null; if (worlditem.gameObject.HasComponent <MeshRenderer>(out worldItemMR)) { GameObject.DestroyImmediate(worldItemMR); } if (worlditem.collider != null) { GameObject.DestroyImmediate(worlditem.collider); } } foreach (FoodStuffProps props in State.PotentialProps) { if (props.IsLiquid) { props.EatFoodSound = "DrinkLiquidGeneric"; } else { props.EatFoodSound = "EatFoodGeneric"; } } mCurrentProps = null; base.InitializeTemplate(); }
public void InitializeTemplate() { worlditem = gameObject.GetComponent <WorldItem> (); worlditem.States = this; worlditem.Renderers.Clear(); worlditem.Colliders.Clear(); mCurrentState = null; mDefaultState = null; //clear the current state object if (DefaultState == "Default") { DefaultState = string.Empty; } for (int i = 0; i < States.Count; i++) { WIState state = States [i]; //set color and intensity settings if (state.UseRendererColor && !string.IsNullOrEmpty(state.RendererColorName)) { state.RendererColor = Colors.Get.ByName(state.RendererColorName); } else { state.RendererColor = Color.white; } Transform stateObjectTransform = transform.FindChild(state.Name); if (stateObjectTransform != null) { state.StateObject = stateObjectTransform.gameObject; state.StateRenderer = state.StateObject.GetComponent <Renderer>(); state.StateCollider = state.StateObject.GetComponent <Collider>(); if (mDefaultState == null) { if (string.IsNullOrEmpty(DefaultState)) { if (state.StateObject.activeSelf) { DefaultState = state.Name; mCurrentState = state; mDefaultState = mCurrentState; } } else if (state.Name == DefaultState) { mCurrentState = state; mDefaultState = mCurrentState; } } } } if (mDefaultState == null) { if (States.Count > 0) { mDefaultState = States [0]; DefaultState = mDefaultState.Name; mCurrentState = mDefaultState; } else { return; } } //add the default state renderer and collider so the worlditem can calculate its base object bounds if (mDefaultState.StateRenderer != null) { worlditem.Renderers.Add(mDefaultState.StateRenderer); } if (mDefaultState.StateCollider != null) { worlditem.Colliders.Add(mDefaultState.StateCollider); } }
protected void OnTransitionFinish(WIState oldState, WIState newState, WIState currentState) { mInTransition = false; }
protected void BlendState(WIState oldState, WIState newState, WIState currentState, float normalizedBlend) { }
protected bool SetState(string stateName) { if (mInTransition) { return(false); } if (stateName == "Default") { stateName = DefaultState; } if (mCurrentState != null) { if (mCurrentState.Name == stateName) { //Debug.Log("Already set to state " + stateName); if (worlditem.HasSaveState) { worlditem.SaveState.LastState = mCurrentState.Name; } //no need to do anything return(false); } else if (mCurrentState.IsPermanent) { //Debug.Log("State is permanent, can't change to " + stateName); if (worlditem.HasSaveState) { worlditem.SaveState.LastState = mCurrentState.Name; } //no need to do anything return(false); } } WIState newState = null; WIState oldState = mCurrentState; for (int i = 0; i < States.Count; i++) { if (!States [i].Enabled) { //can't set to a state that isn't enabled! continue; } if (States [i].Name == stateName) { newState = States [i]; } else { if (States [i].StateObject != null) { //disable all but the new state object States [i].StateObject.SetActive(false); } } } if (newState == null) { if (mHasSetInitialState) { return(false); } else { //continue, because we have to set initial state at least once newState = mCurrentState; mHasSetInitialState = true; } } if (newState != null) { //make sure we have a state object and renderer //if we do set it active if (newState.StateObject != null) { newState.StateObject.SetActive(true); } else { foreach (Transform child in transform) { if ((child.CompareTag("StateChild") || child.CompareTag("WorldItem")) && child.name == newState.Name) { newState.StateObject = child.gameObject; newState.StateRenderer = child.GetComponent <Renderer>(); newState.StateCollider = child.GetComponent <Collider>(); newState.StateObject.SetActive(true); break; } //the rest have already been set to false } } //clone the serialized properties mInTransition = true; mCurrentState = newState; OnTransitionStart(oldState, newState, mCurrentState); StartCoroutine(SetStateOverTime(oldState, newState, WorldClock.AdjustedRealTime, newState.TransitionRTDuration)); } else { if (mCurrentState == null) { return(false); } } if (mCurrentState.IsInteractive && mCurrentState.StateObject != null) { mCurrentState.StateObject.layer = Globals.LayerNumWorldItemActive; mCurrentState.StateObject.tag = "StateChild"; } else if (mCurrentState.StateObject != null) { //we'll still see it and collider with it //but we won't show up as a world item mCurrentState.StateObject.layer = Globals.LayerNumSolidTerrain; mCurrentState.StateObject.tag = "WorldItem"; } if (worlditem.HasSaveState) { worlditem.SaveState.LastState = mCurrentState.Name; } worlditem.OnStateChange.SafeInvoke(); return(true); }