private void DamageWallOnTile(ref PlantInfo plantInfo, ref BlockingInfo blockInfo, int x, int y) { if (plantInfo.type == PlantType.NotDefined) { return; } var plantRule = _zone.Configuration.PlantRules.GetPlantRule(plantInfo.type); if (plantRule == null) { return; } //is it wall? if (!plantRule.AllowedOnNonNatural) { return; } //only degrades in the last few phases if (!plantInfo.IsWallInLastFewStates(plantRule)) { return; } var globalX = x + _area.X1; var globalY = y + _area.Y1; //pbs might save it if (_pbsPositions != null && _pbsPositions.Count > 0) { if (PBSHelper.IsPBSInRange(_wallDistanceFromPBS, _pbsPositions, globalX, globalY)) { var closestPBSDistance = PBSHelper.GetMinimalDistance(_pbsPositions, globalX, globalY); if (closestPBSDistance <= _intactDistance) { //pbs object in intact distance, wall is protected return; } //in fading range //near 1 .. far 0 var chanceToSurvive = 1 - ((closestPBSDistance - _intactDistance) / _gradientRange); var random = FastRandom.NextDouble(); if (random < chanceToSurvive) { //it will happen inwards more often //so the plant wont get unhealed as it is closer to a pbs but within the range return; } } } plantInfo.UnHealPlant(); if (plantInfo.health > 0) { return; } blockInfo.Plant = false; blockInfo.Height = 0; plantInfo.Clear(); plantInfo.state = 1; }
private void GrowPlantOnTile(int x, int y, ref PlantInfo plantInfo, ref BlockingInfo blockInfo) { var plantRule = _zone.Configuration.PlantRules.GetPlantRule(plantInfo.type); if (plantRule == null) { return; } if (plantInfo.time < plantRule.GrowRate) { //increase tile time plantInfo.time = (byte)(plantInfo.time + 1).Clamp(0, 255); } else { //make it grow! //Reset time plantInfo.time = 0; //get new state PlantType nextAction; byte nextState; plantRule.GetNextState(plantInfo.state, out nextState, out nextAction); if (nextAction == 0) { plantInfo.Clear(); plantInfo.state = 1; //kill signal for client --> resulting type:0 state:1 which should NOT be cleaned, just next round!!! blockInfo.Height = 0; blockInfo.Plant = false; if (!plantRule.PlacesConcrete) { return; } var gx = x + _area.X1; var gy = y + _area.Y1; _zone.Terrain.Controls.UpdateValue(gx, gy, ci => { ci.ClearAllConcrete(); return(ci); }); } else { var healthRatio = plantInfo.GetHealthRatio(plantRule); plantInfo.type = nextAction; plantInfo.state = nextState; plantInfo.health = (byte)(healthRatio * plantRule.Health[plantInfo.state]).Clamp(1, 255); if (!plantRule.NotFruiting) { //yes, fruiting if (plantRule.FruitingState <= nextState) { if (plantRule.FruitingState == nextState) { // first phase when the plant reached fruiting state plantInfo.material = (byte)(Math.Min((int)(FastRandom.NextDouble(plantRule.FruitAmount * 0.05, plantRule.FruitAmount * 0.15)).Clamp(0, 255), plantRule.FruitAmount)); } else { // change happened plantInfo.material = (byte)(Math.Min((plantInfo.material + FastRandom.NextDouble(plantRule.FruitAmount * 0.15, plantRule.FruitAmount * 0.25)), plantRule.FruitAmount)).Clamp(0, 255); } } else { plantInfo.material = 0; } } else { plantInfo.material = 0; } blockInfo.Height = plantRule.GetBlockingHeight(plantInfo.state); blockInfo.Plant = blockInfo.Height > 0; } } }