//附着在地形上 private void StickToTerrain(Tentacle.TentacleChunk chunk) { //如果有抓取目标点 && 当前Chunk与目标点距离大于200 if (this.floatGrabDest.HasValue && !Utils.DistLess(chunk.pos, this.floatGrabDest.Value, 200f)) { return; } //Sign:返回正负号 int sign = (int)Mathf.Sign(chunk.pos.x - this.room.MiddleOfTile(chunk.pos).x); Vector2 contact = new Vector2(0.0f, 0.0f); IntVector2 tilePos = this.room.GetTilePosition(chunk.pos); //遍历8方向 for (int index = 0; index < 8; ++index) { //目标方向Tile是Solid地形 if (this.room.GetTile(tilePos + new IntVector2(Utils.eightDirectionsDiagonalsLast[index].x * sign, Utils.eightDirectionsDiagonalsLast[index].y)).Solid) { if (Utils.eightDirectionsDiagonalsLast[index].x != 0) { contact.x = this.room.MiddleOfTile(chunk.pos).x + Utils.eightDirectionsDiagonalsLast[index].x * sign * (20f - chunk.rad); } if (Utils.eightDirectionsDiagonalsLast[index].y != 0) { contact.y = this.room.MiddleOfTile(chunk.pos).y + Utils.eightDirectionsDiagonalsLast[index].y * (20f - chunk.rad); break; } break; } } if (contact.x == 0.0 && this.room.GetTile(chunk.pos).verticalBeam) { contact.x = this.room.MiddleOfTile(chunk.pos).x; } if (contact.y == 0.0 && this.room.GetTile(chunk.pos).horizontalBeam) { contact.y = this.room.MiddleOfTile(chunk.pos).y; } //未处于相同X轴 if (contact.x != 0.0) { chunk.vel.x += (float)((contact.x - (double)chunk.pos.x) * 0.1f); chunk.vel.y *= 0.9f; } //未处于相同Y轴 if (contact.y != 0.0) { chunk.vel.y += (float)((contact.y - (double)chunk.pos.y) * 0.1f); chunk.vel.x *= 0.9f; } //触手抓取比例增加 if (contact.x != 0.0 || contact.y != 0.0) { this.chunksGripping += 1f / tChunks.Length; } }
public WalkerBeastTentacle(WalkerBeast walkerBeast, BodyChunk chunk, float length, int tentacleNumber) : base(walkerBeast, chunk, length) { setGrabDelay = 8; this.tentacleNumber = tentacleNumber; tProps = new Tentacle.TentacleProps(false, false, true, 0.5f, 0f, 0.6f, 0.8f, 1.04f, 1.2f, 10f, 1f, 5f, 15, 60, 12, 0); tChunks = new Tentacle.TentacleChunk[4]; for (int i = 0; i < tChunks.Length; i++) { tChunks[i] = new Tentacle.TentacleChunk(this, i, (float)(i + 1) / (float)tChunks.Length, 4f); } side = ((tentacleNumber % 2 != 0) ? 1 : 0); pair = ((tentacleNumber >= 2) ? 1 : 0); tentacleDir = Custom.DegToVec(45f + 90f * (float)tentacleNumber); stretchAndSqueeze = 0.1f; debugViz = false; }
public override void Update() { base.Update(); smoothedFootingSecurity = Mathf.Lerp(smoothedFootingSecurity, (!attachedAtTip) ? Mathf.InverseLerp(3f, 30f, (float)sureOfFootingCounter) : 0f, 0.2f); attachedAtTip = false; maxLength = 25f * walkerBeast.preferredHeight * 1.33333337f; idealLength = Mathf.Min(Mathf.Lerp(idealLength, (grabDest == null) ? maxLength : (Vector2.Distance(FloatBase, floatGrabDest.Value) * 1.5f * Mathf.InverseLerp((float)setGrabDelay, 0f, (float)grabDelay)), 0.03f), maxLength); retractFac = 0f; limp = !walkerBeast.Consious; if (limp) { floatGrabDest = null; for (int i = 0; i < tChunks.Length; i++) { tChunks[i].vel *= 0.9f; Tentacle.TentacleChunk tentacleChunk = tChunks[i]; tentacleChunk.vel.y = tentacleChunk.vel.y - 0.5f; } } for (int j = 0; j < tChunks.Length; j++) { tChunks[j].rad = 5f; float num = (float)j / (float)(tChunks.Length - 1); tChunks[j].vel *= 0.5f; if (backtrackFrom == -1 || j < backtrackFrom) { if (j < tChunks.Length - 1) { tChunks[j].vel += walkerBeast.HeadDir * Mathf.Lerp(-1f, 1f, num) * Mathf.Pow(1f - num, 1.8f); } tChunks[j].vel += walkerBeast.moveDirection * Mathf.Sin(smoothedFootingSecurity * 3.14159274f) * 1.5f * Mathf.Lerp(1f, 2.5f, Mathf.Sin(num * 3.14159274f)); } tChunks[j].pos = Vector2.Lerp(tChunks[j].pos, room.MiddleOfTile(segments[tChunks[j].currentSegment]), 0.03f); if (room.PointSubmerged(tChunks[j].pos)) { tChunks[j].vel *= 0.5f; } } if (backtrackFrom == -1) { tChunks[1].vel += walkerBeast.moveDirection; } if (backtrackFrom == -1 && grabDest != null) { Tip.vel += Custom.DirVec(Tip.pos, floatGrabDest.Value) * Mathf.Lerp(0.2f, 38f, smoothedFootingSecurity); } if (floatGrabDest != null && Custom.DistLess(Tip.pos, floatGrabDest.Value, 40f) && backtrackFrom == -1) { Tip.pos = floatGrabDest.Value; Tip.vel *= 0f; attachedAtTip = true; } Tip.collideWithTerrain = !attachedAtTip; UpdateDesiredGrabPos(); for (int k = 0; k < tChunks.Length; k++) { Tentacle.TentacleChunk tentacleChunk2 = tChunks[k]; tentacleChunk2.vel.y = tentacleChunk2.vel.y - 0.1f; tChunks[k].vel += connectedChunk.vel * 0.1f; if (!attachedAtTip) { if (floatGrabDest != null) { tChunks[k].vel += Custom.DirVec(tChunks[k].pos, floatGrabDest.Value) * 0.3f; } else { tChunks[k].vel += Custom.DirVec(tChunks[k].pos, desiredGrabPos + Custom.DirVec(FloatBase, desiredGrabPos) * 70f) * 0.6f; } } } if (attachedAtTip) { framesWithoutReaching = 0; if (SharedPhysics.RayTraceTilesForTerrain(room, BasePos, grabDest.Value)) { if (!Custom.DistLess(Tip.pos, connectedChunk.pos, maxLength)) { ReleaseGrip(); } if (!Custom.DistLess(Tip.pos, connectedChunk.pos, maxLength * 0.9f)) { walkerBeast.heldBackByLeg = true; } } else { ReleaseGrip(); } if (playStepSound) { if (stepSoundVol > 0.5f) { room.PlaySound(SoundID.Vulture_Tentacle_Grab_Terrain, Tip.pos, Mathf.InverseLerp(0.5f, 1f, stepSoundVol) * Mathf.InverseLerp(7f, 45f, Vector2.Distance(Tip.pos, Tip.lastPos)), 1f); } playStepSound = false; } stepSoundVol = 0f; } else { stepSoundVol = Mathf.Min(1f, stepSoundVol + 0.025f); playStepSound = true; FindGrabPos(); framesWithoutReaching++; if ((float)framesWithoutReaching > 60f && floatGrabDest == null) { framesWithoutReaching = 0; } } if (debugViz) { grabGoalSprites[1].pos = desiredGrabPos; } }