/// <summary> /// Performs the tree fall. /// </summary> /// <returns><c>true</c>, if tree fall was performed, <c>false</c> otherwise.</returns> /// <param name="t">Tool used</param> /// <param name="explosion">Explosion. (Not used)</param> /// <param name="tileLocation">Tile location.</param> /// <param name="location">Location.</param> public static bool performTreeFall(Tool t, int explosion, Vector2 tileLocation, GameLocation location) { ModMonitor.Log($"performTreeFall called with: t: {t} explosion: {explosion} tileLocation: {tileLocation} location: {location}", LogLevel.Trace); NetFloat health = tree.health; NetBool stump = tree.stump; NetInt treeType = tree.treeType; NetBool shakeLeft = tree.shakeLeft; NetLong lastPlayerToHit = ModHelper.Reflection.GetField <NetLong>(tree, "lastPlayerToHit").GetValue(); NetBool falling = ModHelper.Reflection.GetField <NetBool>(tree, "falling").GetValue(); string key = GetKeyForObject(treeType); //Code for calculation of tree fall position: (int)tileLocation.X + (((bool)shakeLeft) ? (-4) : 4) if ((bool)stump) { if (Config.TreeDrops[key].StumpDrops != null) { for (int i = 0; i < Config.TreeDrops[key].StumpDrops.Length / 2; i++) { if (Game1.IsMultiplayer) { Game1.createMultipleObjectDebris(Config.TreeDrops[key].StumpDrops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.TreeDrops[key].StumpDrops[i, 1], lastPlayerToHit, location); } else { Game1.createMultipleObjectDebris(Config.TreeDrops[key].StumpDrops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.TreeDrops[key].StumpDrops[i, 1], location); } } } } return(false); }
internal static bool DrawPrefix(Stable __instance, NetFloat ___alpha, SpriteBatch b) { if (__instance.maxOccupants == TRACTOR_GARAGE_ID && __instance.modData.ContainsKey("AlternativeTextureName")) { if (__instance.isMoving || __instance.daysOfConstructionLeft > 0) { return(true); } var textureModel = AlternativeTextures.textureManager.GetSpecificTextureModel(__instance.modData["AlternativeTextureName"]); if (textureModel is null) { return(true); } var textureVariation = Int32.Parse(__instance.modData["AlternativeTextureVariation"]); if (textureVariation == -1 || AlternativeTextures.modConfig.IsTextureVariationDisabled(textureModel.GetId(), textureVariation)) { return(true); } var paintedTexture = BuildingPatch.GetBuildingTextureWithPaint(__instance, textureModel, textureVariation); __instance.drawShadow(b); b.Draw(paintedTexture, Game1.GlobalToLocal(Game1.viewport, new Vector2((int)__instance.tileX * 64, (int)__instance.tileY * 64 + (int)__instance.tilesHigh * 64)), paintedTexture.Bounds, __instance.color.Value * ___alpha, 0f, new Vector2(0f, __instance.texture.Value.Bounds.Height), 4f, SpriteEffects.None, (float)(((int)__instance.tileY + (int)__instance.tilesHigh - 1) * 64) / 10000f); return(false); } return(true); }
private void OnReportCollision(NetStream stream) { float impulse = NetFloat.Dequantize(stream.ReadInt32(10), 10000f, 11); Vector3 b = NetVector3.Read(stream, 3, 10).Dequantize(100f); Vector3 pos = base.transform.position + b; bag.ReportCollision(impulse, pos); }
private void ShatterNet(NetState netState) { shattered = true; Vector3 contactPoint = DequantizePos(netState.shatterPos); float impactMagnitude = NetFloat.Dequantize((int)netState.shatterMagnitude, 10000f, 11); uint shatterSeed = netState.shatterSeed; Shatter(contactPoint, Vector3.zero, impactMagnitude, shatterSeed, netState.netId); }
private void OnImpact(NetStream stream) { if (showDebug) { Debug.Log(base.name + " Impact "); } float impact = AudioUtils.DBToValue(NetFloat.Dequantize(stream.ReadInt32(6), 64f, 6) - 32f); PlayImpact(impact); }
public void OnCollisionEnter(Collision collision) { if (collision.contacts.Length != 0 && bag.ReportCollision(collision.impulse.magnitude, collision.contacts[0].point) && (NetGame.isServer || ReplayRecorder.isRecording)) { NetStream netStream = identity.BeginEvent(evtCollision); int x = NetFloat.Quantize(collision.impulse.magnitude, 10000f, 11); netStream.Write(x, 10); Vector3 vec = collision.contacts[0].point - base.transform.position; NetVector3.Quantize(vec, 100f, 10).Write(netStream, 3); identity.EndEvent(); } }
protected override void OnEnable() { base.OnEnable(); up = Vector3.Cross(forward, right); axis = base.transform.TransformDirection(right); axisForward = base.transform.TransformDirection(forward); radialLength = (float)Math.PI * radius; totalLength = 2f * (length + radialLength); segmentSpacing = totalLength / (float)segmentCount; encoder = new NetFloat(segmentSpacing, 8, 3, 5); InitializeArrays(); itemPrefab.SetActive(value: false); }
private void BroadcastImpact(float impact) { if (showDebug) { Debug.Log(base.name + " Broadcast impact "); } float num = AudioUtils.ValueToDB(impact) + 32f; if (!(num < -64f)) { NetStream netStream = identity.BeginEvent(evtImpact); netStream.Write(NetFloat.Quantize(num, 64f, 6), 6); identity.EndEvent(); } }
public void ShatterLocal(Vector3 pos, Vector3 impulse) { if (!NetGame.isClient) { shattered = true; pos = collider.ClosestPointOnBounds(pos); uint num = (uint)Random.Range(0, 1023); netState = new NetState { shatterPos = QuantizePos(pos), shatterMagnitude = (uint)NetFloat.Quantize(impulse.magnitude, 10000f, 11), shatterSeed = num, netId = NetStream.GetDynamicScopeId() }; pos = DequantizePos(netState.shatterPos); Shatter(pos, impulse, impulse.magnitude, num, netState.netId); } }
public void BroadcastCollisionAudio(CollisionAudioHitConfig config, AudioChannel channel, Vector3 pos, float rms, float pitch) { if (showDebug) { Debug.Log(base.name + " Broadcast Collision Audio "); } float num = AudioUtils.ValueToDB(rms) + 32f; if (num < -64f) { return; } if (identity == null) { Debug.LogErrorFormat(this, "No NetIdentity for {0}", base.name); return; } NetStream netStream = identity.BeginEvent(evtCollisionAudio); netStream.Write(config.netId, 8); if (channel == AudioChannel.Footsteps) { netStream.Write(v: true); } else { netStream.Write(v: false); if (channel == AudioChannel.Body) { netStream.Write(v: true); } else { netStream.Write(v: false); } } Vector3 vec = pos - base.transform.position; NetVector3.Quantize(vec, 100f, 10).Write(netStream, 3); netStream.Write(NetFloat.Quantize(AudioUtils.ValueToDB(rms) + 32f, 64f, 6), 6); netStream.Write(NetFloat.Quantize(AudioUtils.RatioToCents(pitch), 4800f, 8), 3, 8); identity.EndEvent(); }
public void OnReceiveCollisionAudio(NetStream stream) { if (showDebug) { Debug.Log(base.name + " Recieve Collision Audio "); } ushort libId = (ushort)stream.ReadUInt32(8); AudioChannel channel = (!stream.ReadBool()) ? (stream.ReadBool() ? AudioChannel.Body : AudioChannel.Physics) : AudioChannel.Footsteps; Vector3 b = NetVector3.Read(stream, 3, 10).Dequantize(100f); Vector3 pos = base.transform.position + b; float emit = AudioUtils.DBToValue(NetFloat.Dequantize(stream.ReadInt32(6), 64f, 6) - 32f); float num = AudioUtils.CentsToRatio(NetFloat.Dequantize(stream.ReadInt32(3, 8), 4800f, 8)); CollisionAudioHitConfig config = CollisionAudioEngine.instance.GetConfig(libId); if (config != null) { if (showDebug) { Debug.Log(base.name + " There is no audio engine "); } config.PlayWithKnownEmit(channel, null, pos, emit, num); } }
public void StartNetwork(NetIdentity identity) { encoder = new NetFloat(1f, (ushort)(12 + precision), (ushort)(3 + precision), (ushort)(8 + precision)); }
private void Position_fieldChangeVisibleEvent(NetFloat field, float oldValue, float newValue) { Console.WriteLine("newVal: " + newValue); }
/// <summary> /// "hook" of performToolAction in StardewValley.TerrainFeatures.Tree /// </summary> /// <returns><c>true</c> proceed to game code <c>false</c> stop game code</returns> /// <param name="__instance"> reference to access variables in Tree.</param> /// <param name="t">Tool used</param> /// <param name="explosion">Explosion.</param> /// <param name="tileLocation">Tile location.</param> /// <param name="location">Location where action is performed</param> private static bool performToolAction_Prefix2(Tree __instance, Tool t, int explosion, Vector2 tileLocation, GameLocation location) { //Don't do anything if Mod isn't active if (!IsModActive) { return(true); } ModMonitor.Log($"Prefix2 called with: t:{t} explosion:{explosion} tileLocation: {tileLocation} location: {location}"); try { //iterates through all terrain features at the location foreach (KeyValuePair <Vector2, TerrainFeature> pair in location.terrainFeatures.Pairs) { if (pair.Key == tileLocation) { ModMonitor.Log($"found {pair.Value}!", LogLevel.Trace); if (pair.Value is Tree) { ModMonitor.Log("It's a tree!", LogLevel.Trace); tree = (Tree)pair.Value; } } } //NOTE: Using net types will *totally* not f**k up everything in multiplayer NetBool tapped = tree.tapped; NetFloat health = tree.health; NetInt growthStage = tree.growthStage; NetBool stump = tree.stump; //NetInt treeType = tree.treeType; ModMonitor.Log($"Tree properties: growthStage: {tree.growthStage} stump: {tree.stump} tapped: {tree.tapped} treeType: {tree.treeType} shakeLeft: {tree.shakeLeft}"); if (location == null) { location = Game1.currentLocation; } if (explosion > 0) { tapped.Value = false; } if ((bool)tapped) { return(true); } if ((float)health <= -99f) { return(true); } if ((int)growthStage >= 5) { if (t != null && t is Axe) { //location.playSound("axchop", NetAudio.SoundContext.Default); //lastPlayerToHit.Value = t.getLastFarmerToUse().UniqueMultiplayerID; //location.debris.Add(new Debris(12, Game1.random.Next(1, 3), t.getLastFarmerToUse().GetToolLocation(false) + new Vector2(16f, 0f), t.getLastFarmerToUse().Position, 0, ((int)treeType == 7) ? 10000 : (-1))); /* * // try to create secret note * if (!(bool)stump && t.getLastFarmerToUse() != null && t.getLastFarmerToUse().hasMagnifyingGlass && Game1.random.NextDouble() < 0.005) * { * Object @object = location.tryToCreateUnseenSecretNote(t.getLastFarmerToUse()); * if (@object != null) * { * Game1.createItemDebris(@object, new Vector2(tileLocation.X, tileLocation.Y - 3f) * 64f, -1, location, Game1.player.getStandingY() - 32); * } * } */ } else if (explosion <= 0) { return(true); } //shake(tileLocation, true, location); float num = 1f; if (explosion > 0) { num = (float)explosion; } else { if (t == null) { return(true); } switch ((int)t.upgradeLevel) { //Starter tool case 0: num = 1f; break; //Copper tool case 1: num = 1.25f; break; //Steel (Iron) Tool case 2: num = 1.67f; break; //Gold tool case 3: num = 2.5f; break; //Iridium tool case 4: num = 5f; break; } } health.Value -= num; if ((float)health <= 0f && performTreeFall(t, explosion, tileLocation, location)) { return(true); } health.Value += num; } else if ((int)growthStage >= 3) { if (t != null && t.BaseName.Contains("Ax")) { /* * NetCollection<Debris> debris = location.debris; * int numberOfChunks = Game1.random.Next((int)t.upgradeLevel * 2, (int)t.upgradeLevel * 4); * Vector2 debrisOrigin = t.getLastFarmerToUse().GetToolLocation(false) + new Vector2(16f, 0f); * Rectangle boundingBox = t.getLastFarmerToUse().GetBoundingBox(); * float x = (float)boundingBox.Center.X; * boundingBox = t.getLastFarmerToUse().GetBoundingBox(); * debris.Add(new Debris(12, numberOfChunks, debrisOrigin, new Vector2(x, (float)boundingBox.Center.Y), 0, -1)); */ } else if (explosion <= 0) { return(true); } //shake(tileLocation, true, location); float num2 = 1f; /* * if (Game1.IsMultiplayer) * { * Random recentMultiplayerRandom = Game1.recentMultiplayerRandom; * } * else * { * new Random((int)((float)(double)Game1.uniqueIDForThisGame + tileLocation.X * 7f + tileLocation.Y * 11f + (float)(double)Game1.stats.DaysPlayed + (float)health)); * } */ if (explosion <= 0) { switch ((int)t.upgradeLevel) { case 0: num2 = 2f; break; case 1: num2 = 2.5f; break; case 2: num2 = 3.34f; break; case 3: num2 = 5f; break; case 4: num2 = 10f; break; } } else { num2 = (float)explosion; } health.Value -= num2; if ((float)health <= 0f) { performBushDestroy(tileLocation, location); return(true); } health.Value += num2; } else if ((int)growthStage >= 1) { /* * if (explosion > 0) * { * location.playSound("cut", NetAudio.SoundContext.Default); * return true; * } * if (t != null && t.BaseName.Contains("Axe")) * { * location.playSound("axchop", NetAudio.SoundContext.Default); * Game1.createRadialDebris(location, 12, (int)tileLocation.X, (int)tileLocation.Y, Game1.random.Next(10, 20), false, -1, false, -1); * } */ if (t is Axe || t is Pickaxe || t is Hoe || t is MeleeWeapon) { performSproutDestroy(t, tileLocation, location); return(true); } } else { if (explosion > 0) { return(true); } if (t.BaseName.Contains("Axe") || t.BaseName.Contains("Pick") || t.BaseName.Contains("Hoe")) { performSeedDestroy(t, tileLocation, location); return(true); } } return(true); } catch (Exception ex) { ModMonitor.Log($"Failed in {nameof(performToolAction_Prefix2)}:\n{ex}", LogLevel.Error); return(true); // run original logic } }
/// <summary>"hook" of performToolAction in StardewValley.TerrainFeatures.ResourceClump</summary> /// <param name="__instance">reference to acces values in ResourceClump class</param> /// <param name="t">the tool used</param> /// <param name="damage">Damage to player/object? (Not used)</param> /// <param name="tileLocation">Location of the tile.</param> /// <param name="location">Location where the action is performed.</param> /// <returns><c>true</c>run default game code, <c>false</c>prevent gamecode from running</returns> // Basically runs the same code twice if a large stump or large log breaks, resulting in twice the amount of hardwood public static bool performToolAction_Prefix(ResourceClump __instance, Tool t, int damage, Vector2 tileLocation, GameLocation location) { //Don't do anything if mod isn't active if (!IsModActive) { return(true); } try { // define neccessary variables NetInt height = __instance.height; NetInt width = __instance.width; NetFloat health = __instance.health; NetInt parentSheetIndex = __instance.parentSheetIndex; string key = GetKeyForObject(parentSheetIndex); ModMonitor.Log($"performToolAction: key: {key}, index: {parentSheetIndex}"); //Skip if Drops is null if (Config.ResourceDrops[key].Drops == null) { return(true); } //Taken from the game code float num = Math.Max(1f, (float)((int)t.upgradeLevel + 1) * 0.75f); health.Value -= num; //Game1.createRadialDebris(Game1.currentLocation, debrisType, (int)tileLocation.X + Game1.random.Next((int)width / 2 + 1), (int)tileLocation.Y + Game1.random.Next((int)height / 2 + 1), Game1.random.Next(4, 9), false, -1, false, -1); if ((float)health <= 0f) { //The important stuff switch ((int)parentSheetIndex) { //Large Stump, Large Log case 600: case 602: { for (int i = 0; i < Config.ResourceDrops[key].Drops.Length / 2; i++) { if (Config.ResourceDrops[key].Drops[i, 1] != 0) { if (Game1.IsMultiplayer) { Game1.createMultipleObjectDebris(Config.ResourceDrops[key].Drops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.ResourceDrops[key].Drops[i, 1], t.getLastFarmerToUse().UniqueMultiplayerID); } else { Game1.createMultipleObjectDebris(Config.ResourceDrops[key].Drops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.ResourceDrops[key].Drops[i, 1]); } } } return(true); //run default code anyway } //Boulder, MineRock1, MineRock2, MineRock3, MineRock4 case 672: case 752: case 754: case 756: case 758: { for (int i = 0; i < Config.ResourceDrops[key].Drops.Length / 2; i++) { if (Game1.IsMultiplayer) { Game1.createMultipleObjectDebris(Config.ResourceDrops[key].Drops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.ResourceDrops[key].Drops[i, 1], t.getLastFarmerToUse().UniqueMultiplayerID); } else { Game1.createRadialDebris(Game1.currentLocation, Config.ResourceDrops[key].Drops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.ResourceDrops[key].Drops[i, 1], false, -1, true, -1); } } return(true); } //Meteorite case 622: { for (int i = 0; i < Config.ResourceDrops[key].Drops.Length / 2; i++) { if (Config.ResourceDrops[key].Drops[i, 1] != 0) { if (Game1.IsMultiplayer) { Game1.createMultipleObjectDebris(Config.ResourceDrops[key].Drops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.ResourceDrops[key].Drops[i, 1], t.getLastFarmerToUse().UniqueMultiplayerID); } else { Game1.createMultipleObjectDebris(Config.ResourceDrops[key].Drops[i, 0], (int)tileLocation.X, (int)tileLocation.Y, Config.ResourceDrops[key].Drops[i, 1]); } } } return(true); } } } //Avoid more damage to objects than intended else { health.Value += num; } return(true); } catch (Exception ex) { ModMonitor.Log($"Failed in {nameof(performToolAction_Prefix)}:\n{ex}", LogLevel.Error); return(true); // run original logic } }