private GameObject SpawnOffshoot(Growable parent, PlantSectionType type, Vector2 start, Vector2 firstPoint) { GameObject prefab = null; int cost = 0; var stats = plantSections.First(x => x.type == type); minerals -= stats.cost; var shoot = Instantiate(stats.prefab, new Vector3(start.x, start.y, 0), Quaternion.identity); var growable = shoot.GetComponent <Growable>(); growable.rootType = type; growable.parent = parent; var rc = shoot.GetComponent <ResourceCollector>(); if (rc) { rc.growthController = this; } var wd = shoot.GetComponent <WaterDrainer>(); if (wd) { wd.growthController = this; } var drowner = shoot.GetComponent <Drowner>(); if (drowner) { drowner.growthController = this; // Yuck; } var firstPointRel = firstPoint - start; shoot.GetComponent <SpriteShapeController>().spline.SetPosition(1, new Vector3(firstPointRel.x, firstPointRel.y, 0)); return(shoot); }
//do stuff if the projectile passes into something else's collision void OnTriggerEnter2D(Collider2D other) { //check if whatever we are hitting does have a parent otherwise we get null reference exceptions when they don't if (other.gameObject.transform.parent != null) { //check if they're an enemy if (other.gameObject.transform.parent.CompareTag("Enemy")) { //Destroy enemy if we hit them Debug.Log("Enemy destroyed: " + other + " at " + other.transform.position); Destroy(other.transform.parent.gameObject); //Destroy the projectile if it hits an enemy Destroy(gameObject); } } //if we're water if (water) { //check if projectile has hit a growable if (other.gameObject.GetComponent <Growable>() != null) { growable = other.gameObject.GetComponent <Growable>(); growable.hits++; Debug.Log("Watered a growable, now at " + growable.hits + " out of " + growable.projectilesToGrow + " needed to grow"); } } }
protected void ResetPatch() { if (plant) { Destroy(plant.gameObject); } plant = null; }
public virtual void PlantSeed(ItemSeed seed) { seedType = seed.seedType; GameObject plantObject = seed.GetGamePrefab(); plant = Instantiate(plantObject, this.transform).GetComponent <Growable>(); // Make sure we have a Growable being planted if (plant == null) { Debug.LogError("Error trying to plant seed."); } }
// Use this for initialization void Start() { //Get original renderer sorting order ( we need this to push the eater above other sprites) origSortingOrder = GetComponent <Renderer>().sortingOrder; //Get rigidbody (for movement) rb = GetComponent <Rigidbody2D>(); //Get other behaviours enemyController = GetComponent <EnemyController>(); wander = GetComponent <wander>(); growable = GetComponent <Growable>(); //Get eyes eyes = GetComponentInChildren <EyeController>().GetEyes(); }
public EditGrowableWindow(string title, Growable growable) : base(title, growable) { }
/// <summary> /// Update the selection logic in submarine editor /// </summary> public static void UpdateSelecting(Camera cam) { if (resizing) { if (selectedList.Count == 0) { resizing = false; } return; } foreach (MapEntity e in mapEntityList) { e.isHighlighted = false; } if (DisableSelect) { DisableSelect = false; return; } if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow) { if (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))) { UpdateHighlightedListBox(null, false); return; } } if (MapEntityPrefab.Selected != null) { selectionPos = Vector2.Zero; selectedList.Clear(); return; } if (GUI.KeyboardDispatcher.Subscriber == null) { if (PlayerInput.KeyHit(Keys.Delete)) { if (selectedList.Any()) { SubEditorScreen.StoreCommand(new AddOrDeleteCommand(selectedList, true)); } selectedList.ForEach(e => { if (!e.Removed) { e.Remove(); } }); selectedList.Clear(); } if (PlayerInput.IsCtrlDown()) { #if DEBUG if (PlayerInput.KeyHit(Keys.D)) { bool terminate = false; foreach (MapEntity entity in selectedList) { if (entity is Item item && item.GetComponent <Planter>() is { } planter) { planter.Update(1.0f, cam); for (var i = 0; i < planter.GrowableSeeds.Length; i++) { Growable seed = planter.GrowableSeeds[i]; PlantSlot slot = planter.PlantSlots.ContainsKey(i) ? planter.PlantSlots[i] : Planter.NullSlot; if (seed == null) { continue; } seed.CreateDebugHUD(planter, slot); terminate = true; break; } } if (terminate) { break; } } } #endif if (PlayerInput.KeyHit(Keys.C)) { Copy(selectedList); } else if (PlayerInput.KeyHit(Keys.X)) { Cut(selectedList); } else if (PlayerInput.KeyHit(Keys.V)) { Paste(cam.WorldViewCenter); } else if (PlayerInput.KeyHit(Keys.G)) { if (selectedList.Any()) { if (SelectionGroups.ContainsKey(selectedList.Last())) { // Ungroup all selected selectedList.ForEach(e => SelectionGroups.Remove(e)); } else { foreach (var entity in selectedList) { // Remove the old group, if any SelectionGroups.Remove(entity); // Create a group that can be accessed with any member SelectionGroups.Add(entity, selectedList); } } } } } } Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); MapEntity highLightedEntity = null; if (startMovingPos == Vector2.Zero) { List <MapEntity> highlightedEntities = new List <MapEntity>(); if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn)) { highLightedEntity = GUI.MouseOn.UserData as MapEntity; } else { foreach (MapEntity e in mapEntityList) { if (!e.SelectableInEditor) { continue; } if (e.IsMouseOn(position)) { int i = 0; while (i < highlightedEntities.Count && e.Sprite != null && (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth)) { i++; } highlightedEntities.Insert(i, e); if (i == 0) { highLightedEntity = e; } } } UpdateHighlighting(highlightedEntities); } if (highLightedEntity != null) { highLightedEntity.isHighlighted = true; } } if (GUI.KeyboardDispatcher.Subscriber == null) { int up = PlayerInput.KeyDown(Keys.Up) ? 1 : 0, down = PlayerInput.KeyDown(Keys.Down) ? -1 : 0, left = PlayerInput.KeyDown(Keys.Left) ? -1 : 0, right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0; int xKeysDown = (left + right); int yKeysDown = (up + down); if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float)Timing.Step; } else { keyDelay = 0; } Vector2 nudgeAmount = Vector2.Zero; if (keyDelay >= 0.5f) { nudgeAmount.Y = yKeysDown; nudgeAmount.X = xKeysDown; } if (PlayerInput.KeyHit(Keys.Up)) { nudgeAmount.Y = 1f; } if (PlayerInput.KeyHit(Keys.Down)) { nudgeAmount.Y = -1f; } if (PlayerInput.KeyHit(Keys.Left)) { nudgeAmount.X = -1f; } if (PlayerInput.KeyHit(Keys.Right)) { nudgeAmount.X = 1f; } if (nudgeAmount != Vector2.Zero) { foreach (MapEntity entityToNudge in selectedList) { entityToNudge.Move(nudgeAmount); } } } else { keyDelay = 0; } bool isShiftDown = PlayerInput.IsShiftDown(); //started moving selected entities if (startMovingPos != Vector2.Zero) { Item targetContainer = GetPotentialContainer(position, selectedList); if (targetContainer != null) { targetContainer.IsHighlighted = true; } if (PlayerInput.PrimaryMouseButtonReleased()) { //mouse released -> move the entities to the new position of the mouse Vector2 moveAmount = position - startMovingPos; if (!isShiftDown) { moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X; moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y; } if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown) { if (!isShiftDown) { moveAmount = Submarine.VectorToWorldGrid(moveAmount); } //clone if (PlayerInput.IsCtrlDown()) { var clones = Clone(selectedList).Where(c => c != null).ToList(); selectedList = clones; SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false)); selectedList.ForEach(c => c.Move(moveAmount)); } else // move { var oldRects = selectedList.Select(e => e.Rect).ToList(); List <MapEntity> deposited = new List <MapEntity>(); foreach (MapEntity e in selectedList) { e.Move(moveAmount); if (isShiftDown && e is Item item && targetContainer != null) { if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled)) { SoundPlayer.PlayUISound(GUISoundType.DropItem); deposited.Add(item); } else { SoundPlayer.PlayUISound(GUISoundType.PickItemFail); } } } SubEditorScreen.StoreCommand(new TransformCommand(new List <MapEntity>(selectedList), selectedList.Select(entity => entity.Rect).ToList(), oldRects, false)); if (deposited.Any() && deposited.Any(entity => entity is Item)) { var depositedItems = deposited.Where(entity => entity is Item).Cast <Item>().ToList(); SubEditorScreen.StoreCommand(new InventoryPlaceCommand(targetContainer.OwnInventory, depositedItems, false)); } deposited.ForEach(entity => { selectedList.Remove(entity); }); } } startMovingPos = Vector2.Zero; } } //started dragging a "selection rectangle" else if (selectionPos != Vector2.Zero) { selectionSize.X = position.X - selectionPos.X; selectionSize.Y = selectionPos.Y - position.Y; List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize); if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y) { newSelection = FindSelectedEntities(selectionPos, selectionSize); } else { if (highLightedEntity != null) { if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group)) { newSelection.AddRange(group); } else { newSelection.Add(highLightedEntity); } } } if (PlayerInput.PrimaryMouseButtonReleased()) { if (PlayerInput.IsCtrlDown()) { foreach (MapEntity e in newSelection) { if (selectedList.Contains(e)) { RemoveSelection(e); } else { AddSelection(e); } } } else { selectedList = new List <MapEntity>(newSelection); //selectedList.Clear(); //newSelection.ForEach(e => AddSelection(e)); foreach (var entity in newSelection) { HandleDoorGapLinks(entity, onGapFound: (door, gap) => { door.RefreshLinkedGap(); if (!selectedList.Contains(gap)) { selectedList.Add(gap); } }, onDoorFound: (door, gap) => { if (!selectedList.Contains(door.Item)) { selectedList.Add(door.Item); } }); } } //select wire if both items it's connected to are selected var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList(); foreach (Item item in selectedItems) { if (item.Connections == null) { continue; } foreach (Connection c in item.Connections) { foreach (Wire w in c.Wires) { if (w == null || selectedList.Contains(w.Item)) { continue; } if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item)) { selectedList.Add(w.Item); } } } } selectionPos = Vector2.Zero; selectionSize = Vector2.Zero; } } //default, not doing anything specific yet else { if (PlayerInput.PrimaryMouseButtonHeld() && PlayerInput.KeyUp(Keys.Space) && (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))) { //if clicking a selected entity, start moving it foreach (MapEntity e in selectedList) { if (e.IsMouseOn(position)) { startMovingPos = position; } } selectionPos = position; //stop camera movement to prevent accidental dragging or rect selection Screen.Selected.Cam.StopMovement(); } } }
// Update is called once per frame void Update() { var mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); var mousePos = new Vector2(mouseWorldPos.x, mouseWorldPos.y); if (state == DragState.None && Input.GetMouseButton(0)) { var hits = new List <RaycastHit2D>(); var cf = new ContactFilter2D(); cf.NoFilter(); int hitCount = Physics2D.CircleCast(mousePos, 0.1f, Vector2.zero, cf, hits); Vector2 startPoint = Vector2.zero; GameObject obj = null; PlantSectionType?plantType = null; // Find the highest priority growth thing (seed > medium) for (int i = 0; i < hitCount; i++) { var hit = hits[i]; var iObj = hit.collider.gameObject; var growable = iObj.GetComponent <Growable>(); if (growable && !obj) { obj = iObj; startPoint = hit.point; plantType = growable.rootType; } else if (growable) { if (growable.rootType == PlantSectionType.Seed || plantType != PlantSectionType.Seed) { obj = iObj; startPoint = hit.point; plantType = growable.rootType; } } } if (obj != null && plantType != null) { // First, check if it's the end point var spline = obj.GetComponent <SpriteShapeController>()?.spline; if (spline != null) { var pointCount = spline.GetPointCount(); var lastWorld = obj.transform.position + spline.GetPosition(pointCount - 1); var last = new Vector2(lastWorld.x, lastWorld.y); if ((last - mousePos).magnitude < 0.4f) { // We're close enough to the end, we should just continue growing this one state = DragState.Dragging; currentlyGrowing = obj; return; } } switch (plantType) { case PlantSectionType.Seed: { // Unlock the camera if this is the first time we've clicked on a seed focus.startupLock = false; // If we're clicking on a seed, drop into the deciding state state = DragState.Deciding_Seed; dragStart = startPoint; dragParent = obj.GetComponent <Growable>(); obj.GetComponent <Animator>().SetTrigger("StopWiggle"); } break; case PlantSectionType.MediumRoot: { state = DragState.Deciding_Medium_Root; dragStart = startPoint; dragParent = obj.GetComponent <Growable>(); } break; default: { } break; } } return; } if (state == DragState.Deciding_Seed && Input.GetMouseButton(0)) { var delta = mousePos - dragStart; if (delta.sqrMagnitude < .5f) { // Update the indicator position, or something? } else { // Decide what to spawn based on whether you went up or down if (delta.y <= 0) { // They went down, spawn a root! currentlyGrowing = SpawnOffshoot(dragParent, PlantSectionType.MediumRoot, dragStart, mousePos); state = DragState.Dragging; } else { currentlyGrowing = SpawnOffshoot(dragParent, PlantSectionType.SkinnyPlant, dragStart, mousePos); state = DragState.Dragging; } } return; } if (state == DragState.Deciding_Medium_Root && Input.GetMouseButton(0)) { var delta = mousePos - dragStart; if (delta.sqrMagnitude < .5f) { // Update the indicator position, or something? } else { currentlyGrowing = SpawnOffshoot(dragParent, PlantSectionType.SkinnyRoot, dragStart, mousePos); state = DragState.Dragging; } } if (state == DragState.Dragging && Input.GetMouseButton(0)) { var growable = currentlyGrowing.GetComponent <Growable>().growable; if (!growable) { return; } var currentType = currentlyGrowing.GetComponent <Growable>().rootType; var spline = currentlyGrowing.GetComponent <SpriteShapeController>().spline; var pointCount = spline.GetPointCount(); // Check the length of the last segment var basePosWorld = currentlyGrowing.transform.position; var lastWorld = spline.GetPosition(pointCount - 1); var prevWorld = spline.GetPosition(pointCount - 2); var basePos = new Vector2(basePosWorld.x, basePosWorld.y); var last = new Vector2(lastWorld.x, lastWorld.y); var prev = new Vector2(prevWorld.x, prevWorld.y); // Grow the spline slightly var growDir = mousePos - (basePos + last); segmentTime += Time.deltaTime; var currentCost = currentType == PlantSectionType.MediumRoot ? 30 : 5; if (growDir.sqrMagnitude > .001) { var growDirN = growDir.normalized; var growSpeed = currentType == PlantSectionType.MediumRoot ? 0.5f : 1.5f; var newPos = last + growDirN * growSpeed * Time.deltaTime; var newPosWorld = basePos + newPos; // Check for rocks bool blocked = false; foreach (var rock in impassables) { var collider = rock.GetComponent <Collider2D>(); if (collider.OverlapPoint(newPosWorld)) { newPosWorld = collider.ClosestPoint(basePos + last); newPos = newPosWorld - basePos; } } // If roots, make sure we stay below ground if (currentType == PlantSectionType.SkinnyRoot || currentType == PlantSectionType.MediumRoot ) { newPosWorld = dirt.GetComponent <Collider2D>().ClosestPoint(basePos + newPos); newPos = newPosWorld - basePos; } var newPosRel = new Vector3(newPos.x, newPos.y, 0.0f); if (newPosWorld.y > focus.plantHeight) { focus.plantHeight = newPosWorld.y; } if (newPosWorld.y < focus.plantDepth) { focus.plantDepth = newPosWorld.y; } var turningRadius = currentType == PlantSectionType.MediumRoot ? 0.7f : 0.3f; if ((last - prev).sqrMagnitude < turningRadius && segmentTime < 2) { spline.SetPosition(pointCount - 1, newPosRel); } else if (currentCost <= minerals) { segmentTime = 0.0f; var midpoint = (lastWorld + prevWorld) / 2; spline.SetPosition(pointCount - 1, midpoint); spline.InsertPointAt(pointCount, newPosRel); // we just added something to the spline, so pointCount now refers to the last minerals -= currentCost; switch (currentType) { case PlantSectionType.MediumRoot: { spline.SetHeight(pointCount, .3f); } break; case PlantSectionType.SkinnyRoot: { spline.SetHeight(pointCount, .1f); } break; case PlantSectionType.SkinnyPlant: { spline.SetHeight(pointCount, .2f); } break; } // pointCount - 1 is the second-to-last spline.SetTangentMode(pointCount - 1, ShapeTangentMode.Continuous); Vector3 right; Vector3 left; SplineUtility.CalculateTangents( lastWorld, prevWorld, newPosRel, Vector2.zero, .2f, out right, out left ); spline.SetLeftTangent(pointCount - 1, left); spline.SetRightTangent(pointCount - 1, right); float length = 0; for (var i = 0; i < pointCount - 1; i++) { if (i > 0) { length += (spline.GetPosition(i) - spline.GetPosition(i - 1)).magnitude; } var maxH = currentType == PlantSectionType.MediumRoot ? 0.7f : 0.5f; var h = spline.GetHeight(i); var dH = (maxH - h) / 50f; var newH = h + dH; spline.SetHeight(i, newH); } var maxLength = currentType == PlantSectionType.SkinnyPlant ? 75 : 25; if (length > maxLength) { currentlyGrowing.GetComponent <Growable>().growable = false; } } } } if (!Input.GetMouseButton(0)) { state = DragState.None; dragStart = Vector2.zero; currentlyGrowing = null; } }
// Start is called before the first frame update void Start() { growable = transform.parent.gameObject.GetComponent <Growable>(); spriteShape = transform.parent.gameObject.GetComponent <SpriteShapeController>(); }
private void Update() { if (toolUsageCooldownTimer > 0f) { toolUsageCooldownTimer -= Time.deltaTime; } bool useItemPressed = Input.GetButton("Fire1"); bool useItemSpecialPressed = Input.GetButton("SpecialAttack"); bool waterButtonPressed = Input.GetButton("Fire2"); int indexChange = 0; indexChange = Mathf.RoundToInt(10f * Input.GetAxis("Mouse ScrollWheel")); indexChange += Input.GetButtonDown("NavLeft")? -1 : 0; indexChange += Input.GetButtonDown("NavRight") ? 1 : 0; if (indexChange != 0) { SetSelectedItemIndex(selectedItemIndex += indexChange); } if (useItemPressed) { InventorySlot currentItem = inventorySlots[selectedItemIndex]; // Right now all we can do is use items, so nothing left to do. if (currentItem.IsEmpty()) { return; } // Check to see if we have a variety of things and if we can use them Growable plantableSeed = currentItem.GetGamePrefab().GetComponent <Growable>(); DirtPatch dirtPatch = currentItem.GetGamePrefab().GetComponent <DirtPatch>(); PlantableZone plantableZone = player.GetAvailablePlantableZone(); // Planting a seed if (plantableSeed != null) { ItemSeed seed = (ItemSeed)currentItem.GetItem(); if (plantableZone != null && !plantableZone.IsPlanted()) { plantableZone.PlantSeed(seed); currentItem.Use(); } } // Placing dirt on the ground else if (dirtPatch != null) { if (plantableZone == null && player.OnPlantableGround()) { GameObject dirt = Instantiate(dirtPatch.gameObject); // Assign the dirt patch to be parented to whatever the player is standing on // This allows us to recursively destroy plants after we plant on top of them // (e.g. dirt pile on a leaf platform. Destroy bottom plant, it destroys the rest) Transform parent = player.GetObjectBelow().transform; dirt.transform.parent = parent; // Place this dirt roughly on the ground dirt.transform.position = player.transform.position + Vector3.down * 0.5f; currentItem.Use(); } } else { currentItem.Use(); } } if (useItemSpecialPressed) { InventorySlot currentItem = inventorySlots[selectedItemIndex]; // Make sure we have something equipped. if (currentItem.IsEmpty()) { return; } currentItem.UseSpecial(); } if (waterButtonPressed) { PlantableZone plantableZone = player.GetAvailablePlantableZone(); if (plantableZone != null && plantableZone.CanBeWatered()) { GameObject target = (plantableZone as MonoBehaviour).gameObject; if (waterLevel > 0) { if (!waterSprite.PlanningToVisit(target)) { // Everything that we have that implements interfaces is also a MonoBehavior, so we can // use this as a """safe""" cast in order to find the game object // The water sprite reaching the PlantableZone will handle the watering itself. waterSprite.AddImmediateToTargetList((plantableZone as MonoBehaviour).gameObject); // TODO: Consider implications of this call. It means we can't possibly overwater, but it // also changes the watersprite visual before it actually reaches the PlantableZone ChangeWaterLevel(-1); } else { Debug.LogError("D:"); } } else { // lol you've got no water, nerd } } } // Quick and dirty keypress check for inventory slots if (Input.GetKeyDown(KeyCode.Alpha1)) { SetSelectedItemIndex(0); } else if (Input.GetKeyDown(KeyCode.Alpha2)) { SetSelectedItemIndex(1); } else if (Input.GetKeyDown(KeyCode.Alpha3)) { SetSelectedItemIndex(2); } else if (Input.GetKeyDown(KeyCode.Alpha4)) { SetSelectedItemIndex(3); } else if (Input.GetKeyDown(KeyCode.Alpha5)) { SetSelectedItemIndex(4); } else if (Input.GetKeyDown(KeyCode.Alpha6)) { SetSelectedItemIndex(5); } else if (Input.GetKeyDown(KeyCode.Alpha7)) { SetSelectedItemIndex(6); } else if (Input.GetKeyDown(KeyCode.Alpha8)) { SetSelectedItemIndex(7); } else if (Input.GetKeyDown(KeyCode.Alpha9)) { SetSelectedItemIndex(8); } else if (Input.GetKeyDown(KeyCode.Alpha0)) { SetSelectedItemIndex(9); } else if (Input.GetKeyDown(KeyCode.Minus)) { SetSelectedItemIndex(10); } else if (Input.GetKeyDown(KeyCode.Equals)) { SetSelectedItemIndex(11); } }