protected override IGameObjectWithProto ServerSpawnStaticObject( IProtoTrigger trigger, IServerZone zone, IProtoStaticWorldObject protoStaticWorldObject, Vector2Ushort tilePosition) { // ensure there are no cliff neighbor tiles foreach (var tileOffset in protoStaticWorldObject.Layout.TileOffsets) { if (tileOffset.X == 0 && tileOffset.Y == 0) { continue; } var tile = Server.World.GetTile(tilePosition.X + 2 * tileOffset.X, tilePosition.Y + 2 * tileOffset.Y); foreach (var neighborTile in tile.EightNeighborTiles) { if (neighborTile.IsCliffOrSlope) { return(null); } } } return(base.ServerSpawnStaticObject(trigger, zone, protoStaticWorldObject, tilePosition)); }
public EditorToolStaticObjectsItem(IProtoStaticWorldObject protoStaticObject) : base(protoStaticObject.Name, protoStaticObject.ShortId, displayShortName: false) { this.ProtoStaticObject = protoStaticObject; }
public ManufacturingConfig( IProtoStaticWorldObject protoManufacturer, IEnumerable <Recipe> recipes, IEnumerable <Recipe.RecipeForManufacturingByproduct> recipesForByproducts, bool isProduceByproducts, bool isAutoSelectRecipe) { var enabledRecipes = recipes.ToList(); enabledRecipes.RemoveAll(r => !r.IsEnabled); this.Recipes = enabledRecipes; if (this.Recipes.Count == 0) { Api.Logger.Error( "Recipes list for manufacturing is empty (perhaps recipes are disabled?): " + protoManufacturer); } if (recipesForByproducts == null) { recipesForByproducts = new List <Recipe.RecipeForManufacturingByproduct>(); } this.RecipesForByproducts = recipesForByproducts.ToList(); this.IsProduceByproducts = this.RecipesForByproducts.Count > 0 && isProduceByproducts; this.IsAutoSelectRecipe = isAutoSelectRecipe; }
private static void SharedShowCannotRelocateNotification( ICharacter character, IProtoStaticWorldObject protoStructure, bool hasNoFactionPermission) { if (IsServer) { Instance.CallClient(character, _ => _.ClientRemote_ShowCannotRelocateNotification( protoStructure, hasNoFactionPermission)); return; } if (hasNoFactionPermission) { NotificationSystem.ClientShowNotification( title: CoreStrings.Notification_ActionForbidden, string.Format(CoreStrings.Faction_Permission_Required_Format, CoreStrings.Faction_Permission_LandClaimManagement_Title), NotificationColor.Bad, protoStructure.Icon); } else { NotificationSystem.ClientShowNotification( title: CoreStrings.Notification_ActionForbidden, LandClaimSystem.ErrorNotLandOwner_Message, NotificationColor.Bad, protoStructure.Icon); } return; }
public void Setup( IProtoStaticWorldObject protoStaticWorldObject, bool isCancelable, bool isRepeatCallbackIfHeld, bool isDrawConstructionGrid, bool isBlockingInput, ValidateCanBuildDelegate validateCanPlaceCallback, PlaceSelectedDelegate placeSelectedCallback, double?maxDistance = null) { this.maxDistanceSqr = maxDistance.HasValue ? maxDistance.Value * maxDistance.Value : double.MaxValue; this.protoStaticWorldObject = protoStaticWorldObject; this.isCancelable = isCancelable; this.isRepeatCallbackIfHeld = isRepeatCallbackIfHeld; this.isDrawConstructionGrid = isDrawConstructionGrid; this.IsBlockingInput = isBlockingInput; this.placeSelectedCallback = placeSelectedCallback; this.validateCanBuildCallback = validateCanPlaceCallback; this.IsFrozen = false; this.DestroyComponents(); }
private void ClientRemote_ShowCannotRelocateNotification( IProtoStaticWorldObject protoStructure, bool hasNoFactionPermission) { SharedShowCannotRelocateNotification(ClientCurrentCharacterHelper.Character, protoStructure, hasNoFactionPermission); }
private void ClientRemote_CannotBuildTooFar(IProtoStaticWorldObject protoStaticWorldObject) { NotificationSystem.ClientShowNotification( NotificationCannotBuild_Title, CoreStrings.Notification_TooFar, NotificationColor.Bad, protoStaticWorldObject.Icon); }
private void ClientRemote_ShowNotificationCannotPlace(string errorMessage, IProtoStaticWorldObject proto) { NotificationSystem.ClientShowNotification( NotificationCannotPlace, errorMessage, NotificationColor.Bad, proto.Icon); }
private void ClientRemote_ShowNotificationCannotBuild(string errorMessage, IProtoStaticWorldObject proto) { NotificationSystem.ClientShowNotification( NotificationNotEnoughItems_Title, errorMessage, NotificationColor.Bad, proto.Icon); }
/// <summary> /// Server spawn callback for static object. /// </summary> /// <param name="trigger">Trigger leading to this spawn.</param> /// <param name="zone">Server zone instance.</param> /// <param name="protoStaticWorldObject">Prototype of static object to spawn.</param> /// <param name="tilePosition">Position to try spawn at.</param> protected IGameObjectWithProto ServerSpawnStaticObject( IProtoTrigger trigger, IServerZone zone, IProtoStaticWorldObject protoStaticWorldObject, Vector2Ushort tilePosition) { foreach (var tileOffset in protoStaticWorldObject.Layout.TileOffsets) { // ensure that each tile in object layout is inside the zone if (tileOffset != Vector2Int.Zero && !zone.IsContainsPosition(tilePosition.AddAndClamp(tileOffset))) { // some tile is outside the zone return(null); } } if (!protoStaticWorldObject.CheckTileRequirements( tilePosition, character: null, logErrors: false)) { // cannot spawn static object there return(null); } var spawnedObject = ServerWorldService.CreateStaticWorldObject(protoStaticWorldObject, tilePosition); if (spawnedObject == null) { // cannot spawn static object there return(null); } // if spawned a vegetation - set random growth progress if (protoStaticWorldObject is IProtoObjectVegetation protoVegetation) { double growProgress; if (trigger == null || trigger is TriggerWorldInit) { // world initialization spawn growProgress = RandomHelper.RollWithProbability(0.6) ? 1 // 60% are spawned in full grown state : Random.Next(0, 11) / 10.0; // other are spawned with random growth progress } else { // spawn saplings growProgress = 0; } protoVegetation.ServerSetGrowthProgress(spawnedObject, growProgress); } ServerDecalsDestroyHelper.DestroyAllDecals(tilePosition, protoStaticWorldObject.Layout); return(spawnedObject); }
/// <param name="position">Position of the world object center tile in the world.</param> public WorldMapResourceMark( Vector2Ushort position, IProtoStaticWorldObject protoWorldObject, double serverSpawnTime) { this.Position = position; this.ProtoWorldObject = protoWorldObject; this.ServerSpawnTime = serverSpawnTime; }
private static ITextureAtlasResource ClientGetTextureAtlas(IProtoStaticWorldObject protoObject) { if (protoObject is IProtoObjectWall protoObjectWall) { return(protoObjectWall.TextureAtlasPrimary); } throw new Exception("Incompatible object prototype: " + protoObject); }
private static double ServerCalculateTotalDamageByExplosive( IProtoObjectExplosive protoObjectExplosive, IProtoStaticWorldObject targetStaticWorldObjectProto, double damagePreMultiplier) { var damage = protoObjectExplosive.ServerCalculateTotalDamageByExplosive(targetStaticWorldObjectProto); damage *= damagePreMultiplier; return(damage); }
private void JumpToNextObject(IProtoStaticWorldObject protoStaticObject) { using var objectsOfProto = Api.Shared.WrapInTempList( Api.Client.World.GetStaticWorldObjectsOfProto(protoStaticObject)); if (objectsOfProto.Count == 0) { return; } objectsOfProto.SortBy(o => o.Id); var isReverseMode = false; if (Input.IsKeyHeld(InputKey.Shift, evenIfHandled: true)) { isReverseMode = true; objectsOfProto.AsList().Reverse(); } foreach (var worldObject in objectsOfProto.AsList()) { if (isReverseMode) { if (worldObject.Id >= this.lastJumpObjectId) { continue; } } else if (worldObject.Id <= this.lastJumpObjectId) { continue; } // jump to it JumpTo(worldObject); return; } JumpTo(objectsOfProto.AsList()[0]); void JumpTo(IStaticWorldObject staticWorldObject) { this.lastJumpObjectId = staticWorldObject.Id; var center = staticWorldObject.ProtoStaticWorldObject .Layout.Center; Api.Client.World.SetPosition( ClientCurrentCharacterHelper.Character, position: staticWorldObject.TilePosition.ToVector2D() + (center.X, center.Y), forceReset: true); } }
public string Execute( IProtoStaticWorldObject objTypeName, ushort x, ushort y) { var offset = Server.World.WorldBounds.Offset; return(SpawnObject(objTypeName, new Vector2Ushort((ushort)(x + offset.X), (ushort)(y + offset.Y)))); }
public override double ServerCalculateTotalDamageByExplosive( IProtoStaticWorldObject targetStaticWorldObjectProto) { if (targetStaticWorldObjectProto is IProtoObjectMineral) { // the target object is a mineral, deal special damage return(DamageToMinerals); } return(base.ServerCalculateTotalDamageByExplosive(targetStaticWorldObjectProto)); }
public Context( Tile tile, ICharacter characterBuilder, IProtoStaticWorldObject protoStaticObjectToBuild, Vector2Int tileOffset) { this.TileOffset = tileOffset; this.CharacterBuilder = characterBuilder; this.ProtoStaticObjectToBuild = protoStaticObjectToBuild; this.Tile = tile; }
private void ServerRemote_Destroy(IProtoStaticWorldObject protoStaticWorldObject, Vector2Ushort tilePosition) { var worldService = Server.World; var tile = worldService.GetTile(tilePosition); foreach (var staticObject in tile.StaticObjects .Where(so => so.ProtoStaticWorldObject == protoStaticWorldObject) .ToList()) { worldService.DestroyObject(staticObject); } }
private static string SpawnObject( IProtoStaticWorldObject objTypeName, Vector2Ushort tilePosition) { if (objTypeName is IProtoObjectLandClaim) { throw new Exception("Cannot spawn a land claim object!"); } var result = Server.World.CreateStaticWorldObject(objTypeName, tilePosition); return(result?.ToString() ?? "<cannot spawn there>"); }
public string Execute(IProtoStaticWorldObject protoObject) { var list = Server.World .GetGameObjectsOfProto <IStaticWorldObject, IProtoStaticWorldObject>(protoObject) .ToList(); foreach (var obj in list) { Server.World.DestroyObject(obj); } return($"Destroyed {list.Count} objects of type: {protoObject.ShortId}"); }
public string Execute( IProtoStaticWorldObject protoStaticWorldObject, [CurrentCharacterIfNull] ICharacter character) { if (character.ProtoCharacter is not PlayerCharacterSpectator && !Server.Characters.IsSpectator(character)) { throw new Exception("Player character should be in a spectator mode." + Environment.NewLine + "Please this command first: /spectator 1 " + character.Name); } return(SpawnObject(protoStaticWorldObject, character.TilePosition)); }
public virtual double ServerCalculateTotalDamageByExplosive( IProtoStaticWorldObject targetStaticWorldObjectProto) { var structureExplosiveDefenseCoef = targetStaticWorldObjectProto.StructureExplosiveDefenseCoef; structureExplosiveDefenseCoef = MathHelper.Clamp(structureExplosiveDefenseCoef, 0, 1); var explosiveDefensePenetrationCoef = this.StructureDefensePenetrationCoef; explosiveDefensePenetrationCoef = MathHelper.Clamp(explosiveDefensePenetrationCoef, 0, 1); var damage = this.StructureDamage * (1 - structureExplosiveDefenseCoef * (1 - explosiveDefensePenetrationCoef)); return(damage); }
public Context( Tile tile, ICharacter characterBuilder, IProtoStaticWorldObject protoStaticObjectToBuild, Vector2Int tileOffset, Vector2Ushort startTilePosition, IStaticWorldObject objectToRelocate = null) { this.Tile = tile; this.CharacterBuilder = characterBuilder; this.ProtoStaticObjectToBuild = protoStaticObjectToBuild; this.TileOffset = tileOffset; this.StartTilePosition = startTilePosition; this.ObjectToRelocate = objectToRelocate; }
public static void SharedShowCannotPlaceNotification( ICharacter character, string errorMessage, IProtoStaticWorldObject proto) { if (IsClient) { Instance.ClientRemote_ClientShowNotificationCannotPlace(errorMessage, proto); } else { Instance.CallClient( character, _ => _.ClientRemote_ClientShowNotificationCannotPlace(errorMessage, proto)); } }
public WorldMapResourceMark( uint id, Vector2Ushort position, IProtoStaticWorldObject protoWorldObject, double serverSpawnTime, IProtoTile biome, Vector2Ushort searchAreaCirclePosition, ushort searchAreaCircleRadius) { this.Id = id; this.Position = position; this.ProtoWorldObject = protoWorldObject; this.ServerSpawnTime = serverSpawnTime; this.Biome = biome; this.SearchAreaCirclePosition = searchAreaCirclePosition; this.SearchAreaCircleRadius = searchAreaCircleRadius; }
private void ServerRemote_PlaceStaticObject( IProtoStaticWorldObject protoStaticWorldObject, Vector2Ushort tilePosition) { if (!protoStaticWorldObject.CheckTileRequirements(tilePosition, character: null, logErrors: false)) { // cannot spawn here return; } var worldObject = Server.World.CreateStaticWorldObject(protoStaticWorldObject, tilePosition); if (protoStaticWorldObject is IProtoObjectVegetation protoVegetation) { protoVegetation.ServerSetFullGrown(worldObject); } }
private void ClientPlaceStaticObject( List <Vector2Ushort> tilePositions, IProtoStaticWorldObject protoStaticWorldObject) { var tilePosition = tilePositions[0]; if (Client.World.GetTile(tilePosition) .StaticObjects.Any(so => so.ProtoStaticWorldObject == protoStaticWorldObject)) { return; } EditorClientSystem.DoAction( $"Place object \"{protoStaticWorldObject.Name}\"", onDo: () => this.CallServer( _ => _.ServerRemote_PlaceStaticObject(protoStaticWorldObject, tilePosition)), onUndo: () => this.CallServer(_ => _.ServerRemote_Destroy(protoStaticWorldObject, tilePosition))); }
private static bool ServerCheckCanSpawn(IProtoWorldObject protoObjectToSpawn, Vector2Ushort spawnPosition) { return(protoObjectToSpawn switch { IProtoCharacterMob => ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn( spawnPosition.ToVector2D(), isPlayer: false) && !LandClaimSystem.SharedIsLandClaimedByAnyone(spawnPosition), IProtoStaticWorldObject protoStaticWorldObject // Please note: land claim check must be integrated in the object tile requirements => protoStaticWorldObject.CheckTileRequirements( spawnPosition, character: null, logErrors: false), _ => throw new ArgumentOutOfRangeException("Unknown object type to spawn: " + protoObjectToSpawn) });
private void ClientRemote_OnStructurePlaced( IProtoStaticWorldObject protoStaticWorldObject, Vector2Ushort position, bool isByCurrentPlayer) { var soundPreset = protoStaticWorldObject.SharedGetObjectSoundPreset(); if (isByCurrentPlayer) { // play 2D sound soundPreset.PlaySound(ObjectSound.Place, limitOnePerFrame: false); } else { // play 3D sound (at the built object location) soundPreset.PlaySound(ObjectSound.Place, position.ToVector2D() + protoStaticWorldObject.Layout.Center); } }
public EditorActiveToolObjectBrush( IProtoStaticWorldObject protoStaticObject, [NotNull] Action <List <Vector2Ushort> > onSelected, Action onDispose = null) { this.protoStaticObject = protoStaticObject; this.onSelected = onSelected; this.onDispose = onDispose; this.sceneObject = Api.Client.Scene.CreateSceneObject("ActiveEditorToolBrush", Vector2D.Zero); this.sceneObject.AddComponent <ClientComponentObjectPlacementHelper>() .Setup( protoStaticObject, isCancelable: false, isRepeatCallbackIfHeld: true, isDrawConstructionGrid: false, isBlockingInput: false, validateCanPlaceCallback: this.ValidateCanBuild, placeSelectedCallback: this.PlaceSelectedHandler); }