public static List<Diagnostic> ToUnique(this List<Diagnostic> source) { var diagnostics = new List<Diagnostic>(); foreach (var diagnostic in source) { diagnostics.AddUnique(diagnostic); } return diagnostics; }
public static List<Building_Door> Portals( this Room room ) { var portals = new List<Building_Door>(); foreach( var region in room.Regions ) { foreach( var neighbour in region.Neighbors.Where( n => n.portal != null ) ) { portals.AddUnique( neighbour.portal ); } } return portals; }
public void GenerateTableForRoots(string[] rootNames) { List<Project> projs = new List<Project>(); foreach (string rootName in rootNames) { Project proj = SolutionParser.ProjTable[rootName]; foreach (Project depProj in proj.ProjectTree) { projs.AddUnique(depProj); } } GenerateTableForProjects(projs.ToArray()); }
private static void MostrarListExtension() { var nomes = new List<String> { "ADÃO", "EVA", "CAIM", "ABEL" }; nomes.AddUnique("ADÃO"); nomes.AddUnique("COBRA"); nomes.Add("ADÃO"); foreach (var nome in nomes) { Console.WriteLine(nome); } Console.WriteLine(); Console.WriteLine(nomes.Count("ADÃO")); Console.WriteLine(new String('-', 80)); var numeros = new List<int> { 1, 2, 3, 4, 5, 6, 7 }; numeros.AddUnique(5); foreach (var numero in numeros) { Console.WriteLine(numero); } }
public void Collide(List<GameObject> collisions, int offsetX = 0, int offsetY = 0, int mask = Physics2D.DefaultRaycastLayers, string objectTag = null, List<IntegerCollider> potentialCollisions = null) { if (potentialCollisions == null) potentialCollisions = this.GetPotentialCollisions(0, 0, offsetX, offsetY, mask); if (potentialCollisions.Count == 0 || (potentialCollisions.Count == 1 && potentialCollisions[0] == this)) return; foreach (IntegerCollider collider in potentialCollisions) { if (collider != this && (objectTag == null || collider.tag == objectTag)) { if (this.Overlaps(collider, offsetX, offsetY)) collisions.AddUnique(collider.gameObject); } } }
/// <summary> /// Return a group of model definition layout options by model definition name. /// </summary> /// <param name="names"></param> /// <returns></returns> public static ROTModelDefinition[] getModelDefinitions(string[] names) { List <ROTModelDefinition> defs = new List <ROTModelDefinition>(); int len = names.Length; for (int i = 0; i < len; i++) { ROTModelDefinition def = getModelDefinition(names[i]); if (def != null) { defs.AddUnique(def); } else { error("Could not locate model defintion for name: " + names[i]); } } return(defs.ToArray()); }
public static List <Def> GetResearchRequirements(this RecipeDef recipeDef) { var researchDefs = new List <Def>(); if (recipeDef.researchPrerequisite != null) { // Basic requirement researchDefs.AddUnique(recipeDef.researchPrerequisite); } // Get list of things recipe is used on var thingsOn = new List <ThingDef>(); var recipeThings = DefDatabase <ThingDef> .AllDefsListForReading.Where(t => (t.recipes != null) && t.recipes.Contains(recipeDef) ).ToList(); if (!recipeThings.NullOrEmpty()) { thingsOn.AddRangeUnique(recipeThings); } // Add those linked via the recipe if (!recipeDef.recipeUsers.NullOrEmpty()) { thingsOn.AddRangeUnique(recipeDef.recipeUsers); } // Make sure they all have hard requirements if ( (!thingsOn.NullOrEmpty()) && thingsOn.All(t => t.HasResearchRequirement()) ) { foreach (var t in thingsOn) { researchDefs.AddRangeUnique(t.GetResearchRequirements()); } } // Return the list of research required return(researchDefs); }
internal static void BuildMeshAssetFromLODGroup(GameObject cloneTarget, MeshAsset meshAsset) { List <Mesh> meshes = new List <Mesh>(); List <Material> materials = new List <Material>(); LOD[] lods = cloneTarget.GetComponent <LODGroup>().GetLODs(); //Collector Meshes&Materials for (int j = 0; j < lods.Length; ++j) { ref LOD lod = ref lods[j]; Renderer renderer = lod.renderers[0]; MeshFilter meshFilter = renderer.gameObject.GetComponent <MeshFilter>(); meshes.AddUnique(meshFilter.sharedMesh); for (int k = 0; k < renderer.sharedMaterials.Length; ++k) { materials.AddUnique(renderer.sharedMaterials[k]); } }
/// <summary> /// Register a new listener to this event /// </summary> /// <param name="Listener">The listener to register</param> public override void RegisterListener(IGameEventListener listener) { if (isRaisingEvent) { listenerModTracker.RecordAddModification(listener); } else { Type listenerType = listener.GetType(); if (listenerType.IsAssignableFromGenericInterface(typeof(IGameEventListener <>), typeof(T))) { paramListeners.AddUnique(listener as IGameEventListener <T>); } else { listeners.AddUnique(listener); } } }
private void OnTriggerEnter(Collider other) { if (!waiting) { return; } if (playersAlive.Items.Contains(other.gameObject)) { playersInside.AddUnique(other.gameObject); } if (playersAlive.Count == playersInside.Count) { waiting = false; playersInside.Clear(); stageReadyEvent.Invoke(); } }
protected virtual bool CheckHitTargets(GameObject target) { if (target == null) { return(false); } int count = targets.Count; for (int i = 0; i < count; i++) { if (targets[i] == target) { return(false); } } targets.AddUnique(target); return(true); }
private void ParameterChange(Contract c, ContractParameter p) { // ContractsApp is visible if (ContractsApp.Instance != null && ContractsApp.Instance.appLauncherButton != null) // TODO - fix for 1.0 // ContractsApp.Instance.cascadingList.cascadingList != null && // ContractsApp.Instance.cascadingList.cascadingList.gameObject.activeInHierarchy) { contractsAppVisible = true; } // Not visible else { contractsAppVisible = false; } // Add the contract to the list of ones to update contractsToUpdate.AddUnique(c); }
public void GenerateOrderListForRoots(string[] rootNames) { if (projList != null) { foreach (var proj in projList) { proj.StatusChanged -= OnProjectUpdate; } } projList = new List <Project>(); List <Project> graphProjs = new List <Project>(); foreach (string rootName in rootNames) { Project proj = SolutionParser.ProjTable[rootName]; foreach (Project depProj in proj.ProjectTree) { graphProjs.AddUnique(depProj); } } while (graphProjs.Count != 0) { var downLevelList = graphProjs.FindAll(p => !p.DepProjects.Any(graphProjs.Has)).ToList(); projList.AddRange(downLevelList); graphProjs.RemoveAll(downLevelList.Has); } orderList.Items.Clear(); foreach (var proj in projList) { var item = new ListViewItem(proj.Name); item.StateImageIndex = (int)proj.Status; orderList.Items.Add(item); proj.StatusChanged += OnProjectUpdate; } UpdateLogCombo(); }
/// <summary> /// Gets the hash list. /// </summary> /// <returns></returns> public List <string> GetHashList(bool onlySerbian = false) { List <string> output = new List <string>(); if (onlySerbian) { foreach (var p in items) { if (p.Value.isRelevantContent) { output.AddUnique(p.Key); } } } else { output.AddRangeUnique(items.Keys); } return(output); }
public static List <ThingDef> GetThingsUnlocked(this RecipeDef recipeDef, ref List <Def> researchDefs) { // Things it is unlocked on with research var thingDefs = new List <ThingDef>(); if (researchDefs != null) { researchDefs.Clear(); } if (recipeDef.researchPrerequisite != null) { thingDefs.AddRangeUnique(recipeDef.recipeUsers); if (researchDefs != null) { researchDefs.AddUnique(recipeDef.researchPrerequisite); } } return(thingDefs); }
public static List <Pawn> GetOccupyingPawnsUsing(this Thing thing) { var pawnsUsing = new List <Pawn>(); var occupiedRect = thing.OccupiedRect(); foreach (var cell in occupiedRect) { var pawnThings = cell.GetThingList().Where(t => t is Pawn).ToList(); if (!pawnThings.NullOrEmpty()) { foreach (var pawnThing in pawnThings) { if (thing.PawnHasJobUsing((Pawn)pawnThing)) { pawnsUsing.AddUnique((Pawn)pawnThing); } } } } return(pawnsUsing); }
protected virtual void Awake() { _uid = gameObject.name.GetUniqueId(); // prevent additional objects being created on level reloads if (_originalItemsIDs != null && _originalItemsIDs.Any() && _originalItemsIDs.Contains(_uid)) { Debug.Log("Deleting duplicate @" + name + ", IID: " + GetInstanceID()); DestroyImmediate(gameObject); return; } _originalItemsIDs.AddUnique(_uid); _originalItemsInstanceIds.AddUnique(GetInstanceID()); gameObject.AddComponent <DontDestroyOnLoad>(); //debug _originalItemsIDs.ForEach(x => Debug.Log("Generic Don't Destroy Object: " + x)); //scene management SceneManager.sceneLoaded += SceneManager_sceneLoaded; }
private void OnTriggerStay2D(Collider2D other) { if (LayerTools.IsLayerInMask(targetLayers, other.gameObject.layer) == false) { return; } GameObject target = TryToDetect(other.gameObject); if (target != null) { if (targets.AddUnique(target)) { owner.Brain.TargetSpotted(); } //if (targets.AddUnique(target)) //{ // ((EntityEnemy)owner).Aggro(); //} } }
/// <summary> /// Search asset by Type with /// AssetDatabase.FindAssets($"t: {typeof(T).Name} {nameFilter}"); /// and /// Resources.FindObjectsOfTypeAll<T>() /// </summary> /// <typeparam name="T"></typeparam> /// <param name="nameFilter"></param> /// <returns></returns> public static List <T> FindAssetsByType <T>(string nameFilter = "") where T : UnityEngine.Object { List <T> assets = new List <T>(); T[] assetsResourceS = Resources.FindObjectsOfTypeAll <T>(); if (assetsResourceS != null && assetsResourceS.Length > 0) { if (nameFilter == "") { assets.AddRange(assetsResourceS); } else { foreach (T t in assetsResourceS) { if (t.name.Contains(nameFilter)) { assets.Add(t); } } } } #if UNITY_EDITOR string[] guids = AssetDatabase.FindAssets($"t: {typeof(T).Name} {nameFilter}"); for (int i = 0; i < guids.Length; i++) { string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]); T asset = AssetDatabase.LoadAssetAtPath <T>(assetPath); if (asset != null) { assets.AddUnique(asset); } } assets.ClearNulls(); return(assets); #else return(assets); #endif }
private float moveY(float dy, List <GameObject> collisions, List <GameObject> verticalCollisions, List <IntegerCollider> potentialCollisions) { _positionModifier.y += dy; int unitMove = Mathf.RoundToInt(_positionModifier.y); if (unitMove != 0) { int moves = 0; int unitDir = Math.Sign(unitMove); _positionModifier.y -= unitMove; while (unitMove != 0) { int oldCount = verticalCollisions.Count; this.integerCollider.Collide(verticalCollisions, 0, unitDir, this.CollisionMask, null, potentialCollisions); if (verticalCollisions.Count > oldCount) { for (int i = oldCount; i < verticalCollisions.Count; ++i) { collisions.AddUnique(verticalCollisions[i]); if (((1 << verticalCollisions[i].layer) & this.HaltMovementMask) != 0) { _positionModifier.y = 0.0f; _haltY = true; return(moves); } } } this.transform.position += new Vector3(0, unitDir, 0); unitMove -= unitDir; ++moves; } } return(dy); }
// Returns actual amount applied to movement private float moveX(float dx, List <GameObject> collisions, List <GameObject> horizontalCollisions, List <IntegerCollider> potentialCollisions) { _positionModifier.x += dx; int unitMove = Mathf.RoundToInt(_positionModifier.x); if (unitMove != 0) { int moves = 0; int unitDir = Math.Sign(unitMove); _positionModifier.x -= unitMove; while (unitMove != 0) { int oldCount = horizontalCollisions.Count; this.integerCollider.Collide(horizontalCollisions, unitDir, 0, this.CollisionMask, null, potentialCollisions); if (horizontalCollisions.Count > oldCount) { for (int i = oldCount; i < horizontalCollisions.Count; ++i) { collisions.AddUnique(horizontalCollisions[i]); if (((1 << horizontalCollisions[i].layer) & this.HaltMovementMask) != 0) { _positionModifier.x = 0.0f; _haltX = true; return(moves); } } } this.transform.position += new Vector3(unitDir, 0, 0); unitMove -= unitDir; ++moves; } } return(dx); }
public virtual bool Resolve(List targetList, string name, EntityType flags) { bool found = false; foreach (IEntity member in GetMembers()) { if (member.Name == name && NameResolutionService.IsFlagSet(flags, member.EntityType)) { targetList.AddUnique(member); found = true; } } if (IsInterface) { if (_typeSystemServices.ObjectType.Resolve(targetList, name, flags)) { found = true; } foreach (IType baseInterface in GetInterfaces()) { found |= baseInterface.Resolve(targetList, name, flags); } } else { if (!found || TypeSystemServices.ContainsMethodsOnly(targetList)) { IType baseType = BaseType; if (null != baseType) { found |= baseType.Resolve(targetList, name, flags); } } } return(found); }
/** * 将本表达式信息和传入的TagDictionary信息写入TokenStream里面 */ public void EmitTokens(List <byte> TokenStream, List <CGameplayTag> TagDictionary) { // emit exprtype TokenStream.Add((byte)ExprType); // emit exprdata switch (ExprType) { //tags case CGameplayTagQueryExprType.AnyTagsMatch: case CGameplayTagQueryExprType.AllTagsMatch: case CGameplayTagQueryExprType.NoTagsMatch: // emit tagset byte NumTags = (byte)TagSet.Count; TokenStream.Add(NumTags); foreach (var Tag in TagSet) { int TagIdx = TagDictionary.AddUnique(Tag); TokenStream.Add((byte)TagIdx); } break; //expression case CGameplayTagQueryExprType.AnyExprMatch: case CGameplayTagQueryExprType.AllExprMatch: case CGameplayTagQueryExprType.NoExprMatch: // emit tagset byte NumExprs = (byte)ExprSet.Count; TokenStream.Add(NumExprs); foreach (var E in ExprSet) { E.EmitTokens(TokenStream, TagDictionary); } break; } }
public void Collide(List <GameObject> collisions, int offsetX = 0, int offsetY = 0, int mask = Physics2D.DefaultRaycastLayers, string objectTag = null, List <IntegerCollider> potentialCollisions = null) { if (potentialCollisions == null) { potentialCollisions = this.GetPotentialCollisions(0, 0, offsetX, offsetY, mask); } if (potentialCollisions.Count == 0 || (potentialCollisions.Count == 1 && potentialCollisions[0] == this)) { return; } foreach (IntegerCollider collider in potentialCollisions) { if (collider != this && (objectTag == null || collider.tag == objectTag)) { if (this.Overlaps(collider, offsetX, offsetY)) { collisions.AddUnique(collider.gameObject); } } } }
static void UpdatePrefabInstance(PrefabLink prefabLinkInSceen) { object parentObj = PrefabUtility.GetPrefabParent(prefabLinkInSceen); if (parentObj != null) { GameObject parentGameObject = parentObj as GameObject; if (parentGameObject != null) { List <GameObject> instances = new List <GameObject> { }; if (prefabInstances.ContainsKey(parentGameObject)) { instances = prefabInstances[parentGameObject]; } instances.AddUnique(prefabLinkInSceen.gameObject); prefabInstances[parentGameObject] = instances; } } }
/// <summary> /// Selects mapped items with the specified matches. /// </summary> /// <param name="matches">The matches.</param> /// <returns></returns> public List <List <T> > Select(MatchCollection matches) { List <textMapContainer <T> > output = new List <textMapContainer <T> >(); List <List <T> > g_output = new List <List <T> >(); List <List <T> > l = new List <List <T> >(); foreach (Match m in matches) { if (m.Success) { var mGroup = SelectContainer(m.Index, m.Length); var g = new List <T>(); foreach (var t in mGroup) { g.AddUnique(t.item); } l.Add(g); } } return(l); }
public static void BakeSelectedScenes() { List <string> toBakedScenes = new List <string>(); Object[] objects = Selection.objects; if (objects.Length > 0) { for (int i = 0, length = objects.Length; i < length; i++) { Object obj = objects[i]; string path = AssetDatabase.GetAssetOrScenePath(obj); if (Utils.EditorUtil.IsSceneAsset(path)) { toBakedScenes.AddUnique(path); } } } if (toBakedScenes.Count == 0) { EditorUtility.DisplayDialog("Warning", "No scene to be baked!", "Ok"); return; } for (int i = 0, length = toBakedScenes.Count; i < length; i++) { string scenePath = toBakedScenes[i]; Scene scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); EditorUtility.DisplayProgressBar("Baking...", string.Format("Baking the scene {0}... {1}/{2}", scene.name, i + 1, length), (float)(i + 1) / length); Lightmapping.Bake(); EditorSceneManager.SaveScene(scene); } EditorUtility.ClearProgressBar(); }
public static bool FindProperties(Type searchType, Type owner, List <PropertyInfo> foundProperties, BindingFlags bindingFlags = BINDING_FLAGS, HashSet <Type> highestParents = null, bool searchParent = false) { var parentType = owner; while (parentType != null) { var properties = parentType.GetProperties(bindingFlags); foreach (var propertyInfo in properties) { if (bindingFlags.HasFlag(BindingFlags.SetProperty) && propertyInfo.SetMethod == null) { continue; } if (propertyInfo.GetMethod == null) { continue; } if (propertyInfo.GetMethod.ReturnType.IsSubclassOf(searchType) || searchType.IsAssignableFrom(propertyInfo.GetMethod.ReturnType)) { foundProperties.AddUnique(propertyInfo); } } parentType = parentType.BaseType; if (highestParents.Contains(parentType)) { break; } } return(foundProperties.Count > 0); }
public void RefreshMissionsData(List <Mission> missions) { if (Missions == null || Missions.Count < 1) { Missions = new List <Mission>(); Missions = missions; } else { missions.ForEach(item => { //refreshing old data var alreadyAdded = Missions.Find(x => x.MissionID.Equals(item.MissionID)); if (alreadyAdded != null) //if the record exists { alreadyAdded.RefreshData(item.IconUri, item.InitialValue, item.IncrementalValue, item.RewardCoins, item.MissionMessage); } //adding new missions to runtime config Missions.AddUnique(item, x => !x.MissionID.Equals(item.MissionID)); }); } }
private static TileModels ExtractWDTM2s(IList <MapObjectDefinition> wmos) { var LoadedWMOIds = new List <uint>(); var tileModels = new TileModels { Models = new List <TileModel>() }; for (var i = 0; i < wmos.Count; i++) { var wmo = wmos[i]; if (LoadedWMOIds.Contains(wmo.UniqueId)) { continue; } var filePath = wmo.FileName; var root = WMORootParser.Process(manager, filePath); if (root == null) { Console.WriteLine("Invalid WMORoot returned."); return(null); } LoadedWMOIds.AddUnique(wmo.UniqueId); if (root.DoodadDefinitions == null) { Console.WriteLine("No models defined in Root."); return(null); } ExtractWMOM2s(wmo, root, tileModels); } return(tileModels); }
/// <summary> /// Returns all occurrences of the given search-parameter. /// </summary> /// <param name="dataType">The type to search through (Schema, Item or Field).</param> /// <param name="searchType">If the given String should contain, start/end with or equal the searched entries.</param> /// <param name="searchBy">Searches for this String in every entry of given type.</param> /// <param name="limitBySchema">Optionally only search through a specific Schema.</param> /// <returns></returns> public static List<string> FindAll(GDEDataType dataType, SearchType searchType, string searchBy, string limitBySchema = "") { List<string> result = new List<string>(); foreach(var entry in ListAllBy(dataType)) { switch(searchType) { case SearchType.Contains: if(entry.Contains(searchBy)) result.AddUnique(entry); break; case SearchType.Equals: if(entry == searchBy) result.AddUnique(entry); break; case SearchType.DoesNotContain: if(!entry.Contains(searchBy)) result.AddUnique(entry); break; case SearchType.DoesNotEqual: if(entry != searchBy) result.AddUnique(entry); break; case SearchType.StartsWith: if(entry.StartsWith(searchBy)) result.AddUnique(entry); break; case SearchType.EndsWith: if(entry.EndsWith(searchBy)) result.AddUnique(entry); break; } } if(result.Count == 0) { UnityEngine.Debug.LogWarning("Couldn't find any matching " + dataType.ToString() + " which " + searchType.ToString() + " \"" + searchBy + "\"."); } return result; }
// Returns actual amount applied to movement private float moveX(float dx, List<GameObject> collisions, List<GameObject> horizontalCollisions, List<IntegerCollider> potentialCollisions) { _positionModifier.x += dx; int unitMove = Mathf.RoundToInt(_positionModifier.x); if (unitMove != 0) { int moves = 0; int unitDir = Math.Sign(unitMove); _positionModifier.x -= unitMove; while (unitMove != 0) { int oldCount = horizontalCollisions.Count; this.integerCollider.Collide(horizontalCollisions, unitDir, 0, this.CollisionMask, null, potentialCollisions); if (horizontalCollisions.Count > oldCount) { for (int i = oldCount; i < horizontalCollisions.Count; ++i) { collisions.AddUnique(horizontalCollisions[i]); if (((1 << horizontalCollisions[i].layer) & this.HaltMovementMask) != 0) { _positionModifier.x = 0.0f; _haltX = true; return moves; } } } this.transform.position += new Vector3(unitDir, 0, 0); unitMove -= unitDir; ++moves; } } return dx; }
public IEntity GetDefaultMember() { IType defaultMemberAttribute = _typeSystemServices.Map(Types.DefaultMemberAttribute); foreach (Attribute attribute in _typeDefinition.Attributes) { IConstructor tag = TypeSystemServices.GetEntity(attribute) as IConstructor; if (null != tag) { if (defaultMemberAttribute == tag.DeclaringType) { StringLiteralExpression memberName = attribute.Arguments[0] as StringLiteralExpression; if (null != memberName) { List buffer = new List(); Resolve(buffer, memberName.Value, EntityType.Any); return NameResolutionService.GetEntityFromList(buffer); } } } } if (_typeDefinition.BaseTypes.Count > 0) { List buffer = new List(); foreach (TypeReference baseType in _typeDefinition.BaseTypes) { IType tag = TypeSystemServices.GetType(baseType); IEntity defaultMember = tag.GetDefaultMember(); if (defaultMember != null) { if (tag.IsInterface) { buffer.AddUnique(defaultMember); } else //non-interface base class trumps interfaces { return defaultMember; } } } return NameResolutionService.GetEntityFromList(buffer); } return null; }
/// <summary> /// Gets the directed graph from <see cref="folderNode"/> /// </summary> /// <param name="folder">The folder.</param> /// <param name="doFolderDescription">if set to <c>true</c> [do folder description].</param> /// <param name="doFileEntries">if set to <c>true</c> [do file entries].</param> /// <param name="doFileDescriptions">if set to <c>true</c> [do file descriptions].</param> /// <param name="limit">The limit.</param> /// <returns></returns> public static DirectedGraph GetDirectedGraph(this folderNode folder, Boolean doFolderDescription, Boolean doFileEntries, Boolean doFileDescriptions, Int32 limit = 100) { DirectedGraph output = new DirectedGraph(); output.Title = folder.name; output.Categories.AddOrGetCategory(CAT_FOLDERNODE, "Folder", "").Background = Color.Orange.ColorToHex(); //.toHexColor(); output.Categories.AddOrGetCategory(CAT_FOLDERNODEDESC, "Folder Description", "").Background = Color.LightGray.ColorToHex(); //.toHexColor(); output.Categories.AddOrGetCategory(CAT_FILE, "File", "").Background = Color.LightSteelBlue.ColorToHex(); //.toHexColor(); output.Categories.AddOrGetCategory(CAT_FILEDESC, "File Description", "").Background = Color.LightGray.ColorToHex(); //.toHexColor(); List <folderNode> nextSet = new List <folderNode>(); nextSet.Add(folder); Int32 i = 0; while (nextSet.Any()) { i++; List <folderNode> newNextSet = new List <folderNode>(); foreach (folderNode parent in nextSet) { var parentNode = output.Nodes.AddNode(parent.path, parent.name); parentNode.Category = CAT_FOLDERNODE; if (parent.parent != null) { folderNode parentFolder = parent.parent as folderNode; Link l = new Link(parentFolder.path, parentNode.Id, true); l.Stroke = Color.OrangeRed.ColorToHex(); //.toHexColor(); output.Links.Add(l); } foreach (var pair in parent) { newNextSet.AddUnique(pair.Value); } if (doFolderDescription) { if (!parent.description.isNullOrEmpty()) { Node descNode = output.Nodes.AddNode(parent.path + "_DESC", parent.description); descNode.Category = CAT_FOLDERNODEDESC; output.Links.AddLink(parentNode, descNode, "About").StrokeDashArray = "2,5,2,5"; } } if (doFileEntries) { foreach (var f in parent.AdditionalFileEntries) { Node fileNode = output.Nodes.AddNode(parent.path + f.Key, f.Value.description); fileNode.Category = CAT_FILE; var fileLink = output.Links.AddLink(parentNode, fileNode, f.Value.filename); fileLink.StrokeDashArray = "2,2,5,2"; fileLink.Stroke = Color.LightGray.ColorToHex(); //.toHexColor(); //if (doFileDescriptions) //{ // Node fileInfoNode = output.Nodes.AddNode(parent.path + f.Key + "_DESC", ); // fileInfoNode.Category = CAT_FILEDESC; // var fileInfoLink = output.Links.AddLink(fileNode, fileInfoNode, ""); // fileLink.StrokeDashArray = "2,2,5,2"; // fileLink.Stroke = Color.LightGray.toHexColor(); //} } } } if (i > limit) { break; } nextSet = newNextSet; } return(output); }
private void GetBranchContents(short nodeId, Vector3[] vectors, List<Vector3> vertices) { if (nodeId < 0 || nodeId > nodes.Length) return; var node = nodes[nodeId]; if (node.flags == BSPNodeFlags.Flag_Leaf) { foreach (var index3 in node.TriIndices) { vertices.AddUnique(vectors[index3.Index0]); vertices.AddUnique(vectors[index3.Index1]); vertices.AddUnique(vectors[index3.Index2]); } return; } GetBranchContents(node.posChild, vectors, vertices); GetBranchContents(node.negChild, vectors, vertices); }
protected bool ResolveGenericParameter(List targetList, string name, EntityType flags) { // Try to resolve name as a generic parameter if (NameResolutionService.IsFlagSet(flags, EntityType.Type)) { foreach (GenericParameterDeclaration gpd in _typeDefinition.GenericParameters) { if (gpd.Name == name) { targetList.AddUnique(gpd.Entity); return true; } } } return false; }
private float moveY(float dy, List<GameObject> collisions, List<GameObject> verticalCollisions, List<IntegerCollider> potentialCollisions) { _positionModifier.y += dy; int unitMove = Mathf.RoundToInt(_positionModifier.y); if (unitMove != 0) { int moves = 0; int unitDir = Math.Sign(unitMove); _positionModifier.y -= unitMove; while (unitMove != 0) { int oldCount = verticalCollisions.Count; this.integerCollider.Collide(verticalCollisions, 0, unitDir, this.CollisionMask, null, potentialCollisions); if (verticalCollisions.Count > oldCount) { for (int i = oldCount; i < verticalCollisions.Count; ++i) { collisions.AddUnique(verticalCollisions[i]); if (((1 << verticalCollisions[i].layer) & this.HaltMovementMask) != 0) { _positionModifier.y = 0.0f; _haltY = true; return moves; } } } this.transform.position += new Vector3(0, unitDir, 0); unitMove -= unitDir; ++moves; } } return dy; }
public void Execute() { if(!dead){ switch(type){ case EventType.MOVE: { Actor temp = target as Actor; temp.Act(); break; } case EventType.REMOVE_ATTR: { Actor temp = target as Actor; if(attr == AttrType.FLYING){ temp.attrs[AttrType.DESCENDING] = 2; if(temp == player){ B.Add("You start to descend as your flight wears off. "); B.Print(true); } break; } if(attr == AttrType.SHINING){ int old_rad = temp.LightRadius(); temp.attrs[attr] -= value; if(old_rad != temp.LightRadius() && !temp.HasAttr(AttrType.BURROWING)){ temp.UpdateRadius(old_rad,temp.LightRadius()); } break; } if(temp.type == ActorType.BERSERKER && attr == AttrType.COOLDOWN_2){ temp.attrs[attr] = 0; //this hack can probably be removed } else{ temp.attrs[attr] -= value; } if(attr == AttrType.BURNING && temp.LightRadius() == 0 && !temp.HasAttr(AttrType.BURROWING)){ temp.UpdateRadius(1,0); } if(attr == AttrType.TELEPORTING){ temp.attrs[attr] = 0; } if(attr == AttrType.CONVICTION){ if(temp.HasAttr(AttrType.IN_COMBAT)){ temp.attrs[AttrType.CONVICTION] += value; //whoops, undo that } else{ temp.attrs[AttrType.BONUS_SPIRIT] -= value; //otherwise, set things to normal temp.attrs[AttrType.BONUS_COMBAT] -= (value+1) / 2; if(temp.attrs[AttrType.KILLSTREAK] >= 2){ B.Add("You wipe off your weapon. "); } temp.attrs[AttrType.KILLSTREAK] = 0; } } if(attr == AttrType.COOLDOWN_1 && temp.type == ActorType.BERSERKER){ B.Add(temp.Your() + " rage diminishes. ",temp); B.Add(temp.the_name + " dies. ",temp); temp.Kill(); } break; } case EventType.REMOVE_GAS: { List<Tile> removed = new List<Tile>(); foreach(Tile t in area){ if(t.Is(feature)){ if(R.PercentChance(value)){ t.RemoveFeature(feature); removed.Add(t); } } else{ removed.Add(t); } } foreach(Tile t in removed){ area.Remove(t); } if(area.Count > 0){ Event.RemoveGas(area,100,feature,value); } break; } case EventType.CHECK_FOR_HIDDEN: { List<Tile> removed = new List<Tile>(); foreach(Tile t in area){ if(player.CanSee(t)){ int exponent = player.DistanceFrom(t) + 1; if(player.magic_trinkets.Contains(MagicTrinketType.RING_OF_KEEN_SIGHT)){ --exponent; } if(!t.IsLit()){ if(!player.HasAttr(AttrType.SHADOWSIGHT)){ ++exponent; } } if(exponent > 8){ exponent = 8; //because 1 in 256 is enough. } int difficulty = 1; for(int i=exponent;i>0;--i){ difficulty = difficulty * 2; } if(R.Roll(difficulty) == difficulty){ if(t.IsTrap() || t.Is(TileType.FIRE_GEYSER) || t.Is(TileType.FOG_VENT) || t.Is(TileType.POISON_GAS_VENT)){ t.name = Tile.Prototype(t.type).name; t.a_name = Tile.Prototype(t.type).a_name; t.the_name = Tile.Prototype(t.type).the_name; t.symbol = Tile.Prototype(t.type).symbol; t.color = Tile.Prototype(t.type).color; B.Add("You notice " + t.AName(true) + ". "); } else{ if(t.type == TileType.HIDDEN_DOOR){ t.Toggle(null); B.Add("You notice a hidden door. "); } } removed.Add(t); } } } foreach(Tile t in removed){ area.Remove(t); } if(area.Count > 0){ Q.Add(new Event(area,100,EventType.CHECK_FOR_HIDDEN)); } break; } case EventType.RELATIVELY_SAFE: { if(M.AllActors().Count == 1 && !Q.Contains(EventType.POLTERGEIST) && !Q.Contains(EventType.REGENERATING_FROM_DEATH) && !Q.Contains(EventType.MIMIC) && !Q.Contains(EventType.MARBLE_HORROR)){ //B.Add("The dungeon is still and silent. "); B.Add("The dungeon is utterly silent for a moment. "); B.PrintAll(); } else{ Q.Add(new Event((R.Roll(20)+30)*100,EventType.RELATIVELY_SAFE)); } break; } case EventType.POLTERGEIST: { if(target != null && target is Actor){ //target can either be a stolen item, or the currently manifested poltergeist. Q.Add(new Event(target,area,(R.Roll(8)+6)*100,EventType.POLTERGEIST,AttrType.NO_ATTR,0,"")); break; //if it's manifested, the event does nothing for now. } if(area.Any(t => t.actor() == player)){ bool manifested = false; if(value == 0){ B.Add("You feel like you're being watched. "); } else{ if(target != null){ //if it has a stolen item Tile tile = null; tile = area.Where(t => t.actor() == null && t.DistanceFrom(player) >= 2 && t.HasLOE(player) && t.FirstActorInLine(player) == player).RandomOrDefault(); if(tile != null){ Actor temporary = new Actor(ActorType.POLTERGEIST,"something",'G',Color.DarkGreen,1,1,0,0); temporary.a_name = "something"; temporary.the_name = "something"; temporary.p = tile.p; temporary.inv = new List<Item>(); temporary.inv.Add(target as Item); Item item = temporary.inv[0]; if(item.NameOfItemType() == "orb"){ temporary.inv[0].Use(temporary,temporary.GetBestExtendedLineOfEffect(player)); } else{ B.Add("Something throws " + item.AName() + ". ",temporary); B.DisplayNow(); Screen.AnimateProjectile(tile.GetBestExtendedLineOfEffect(player).ToFirstSolidTileOrActor(),new colorchar(item.color,item.symbol)); player.tile().GetItem(item); B.Add(item.TheName() + " hits you. "); player.TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(6),temporary,"a flying " + item.Name()); } target = null; } else{ Q.Add(new Event(target,area,100,EventType.POLTERGEIST,AttrType.NO_ATTR,value,"")); return; //try again next turn } } else{ if(value >= 2 && area.Any(t => t.DistanceFrom(player) == 1 && t.passable && t.actor() == null)){ Tile tile = area.Where(t => t.DistanceFrom(player) == 1 && t.passable && t.actor() == null).Random(); B.DisplayNow(); for(int i=4;i>0;--i){ Screen.AnimateStorm(tile.p,i,2,1,'G',Color.DarkGreen); } Actor a = Actor.Create(ActorType.POLTERGEIST,tile.row,tile.col,TiebreakerAssignment.UseCurrent); Q.KillEvents(a,EventType.MOVE); a.Q0(); a.player_visibility_duration = -1; B.Add("A poltergeist manifests in front of you! "); Q.Add(new Event(a,area,(R.Roll(8)+6)*100,EventType.POLTERGEIST,AttrType.NO_ATTR,0,"")); manifested = true; } else{ if(player.tile().type == TileType.DOOR_O){ B.Add("The door slams closed on you! "); player.TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(6),null,"a slamming door"); } else{ Tile tile = null; //check for items to throw... tile = area.Where(t => t.inv != null && t.actor() == null && t.DistanceFrom(player) >= 2 && t.HasLOE(player) && t.FirstActorInLine(player) == player).RandomOrDefault(); if(tile != null){ Actor temporary = new Actor(ActorType.POLTERGEIST,"something",'G',Color.DarkGreen,1,1,0,0); temporary.a_name = "something"; temporary.the_name = "something"; temporary.p = tile.p; temporary.inv = new List<Item>(); if(tile.inv.quantity <= 1){ temporary.inv.Add(tile.inv); tile.inv = null; } else{ temporary.inv.Add(new Item(tile.inv,-1,-1)); tile.inv.quantity--; } M.Draw(); Item item = temporary.inv[0]; if(item.NameOfItemType() == "orb"){ temporary.inv[0].Use(temporary,temporary.GetBestExtendedLineOfEffect(player)); } else{ B.Add("Something throws " + item.TheName() + ". ",temporary); B.DisplayNow(); Screen.AnimateProjectile(tile.GetBestExtendedLineOfEffect(player).ToFirstSolidTileOrActor(),new colorchar(item.color,item.symbol)); player.tile().GetItem(item); B.Add(item.TheName() + " hits you. "); player.TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(6),temporary,"a flying " + item.Name()); } } else{ if(area.Any(t => t.type == TileType.DOOR_O || t.type == TileType.DOOR_C)){ Tile door = area.Where(t=>t.type == TileType.DOOR_O || t.type == TileType.DOOR_C).Random(); if(door.type == TileType.DOOR_C){ if(player.CanSee(door)){ B.Add("The door flies open! ",door); } else{ if(door.seen || player.DistanceFrom(door) <= 12){ B.Add("You hear a door slamming. "); } } door.Toggle(null); } else{ if(door.actor() == null){ if(player.CanSee(door)){ B.Add("The door slams closed! ",door); } else{ if(door.seen || player.DistanceFrom(door) <= 12){ B.Add("You hear a door slamming. "); } } door.Toggle(null); } else{ if(player.CanSee(door)){ B.Add("The door slams closed on " + door.actor().TheName(true) + "! ",door); } else{ if(player.DistanceFrom(door) <= 12){ B.Add("You hear a door slamming and a grunt of pain. "); } } door.actor().TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(6),null,"a slamming door"); } } } else{ B.Add("You hear mocking laughter from nearby. "); } } } } } } if(!manifested){ Q.Add(new Event(target,area,(R.Roll(8)+6)*100,EventType.POLTERGEIST,AttrType.NO_ATTR,value+1,"")); } } else{ Q.Add(new Event(target,area,(R.Roll(8)+6)*100,EventType.POLTERGEIST,AttrType.NO_ATTR,0,"")); } break; } case EventType.MIMIC: { Item item = target as Item; if(area[0].inv != item){ //it could have been picked up by the player or moved in another way foreach(Tile t in M.AllTiles()){ //if it was moved, make the correction to the event's area. if(t.inv == item){ area = new List<Tile>{t}; break; } } } if(area[0].inv == item){ bool attacked = false; if(player.DistanceFrom(area[0]) == 1 && area[0].actor() == null){ if(player.TotalSkill(SkillType.STEALTH) * 5 < R.Roll(1,100)){ B.Add(item.TheName(true) + " suddenly grows tentacles! "); attacked = true; area[0].inv = null; Actor a = Actor.Create(ActorType.MIMIC,area[0].row,area[0].col,TiebreakerAssignment.UseCurrent); Q.KillEvents(a,EventType.MOVE); a.Q0(); a.player_visibility_duration = -1; a.symbol = item.symbol; a.color = item.color; } } if(!attacked){ Q.Add(new Event(target,area,100,EventType.MIMIC,AttrType.NO_ATTR,0,"")); } } else{ //if the item is missing, we assume that the player just picked it up List<Tile> open = new List<Tile>(); foreach(Tile t in player.TilesAtDistance(1)){ if(t.passable && t.actor() == null){ open.Add(t); } } if(open.Count > 0){ Tile t = open.Random(); B.Add(item.TheName() + " suddenly grows tentacles! "); Actor a = Actor.Create(ActorType.MIMIC,t.row,t.col,TiebreakerAssignment.UseCurrent); Q.KillEvents(a,EventType.MOVE); a.Q0(); a.player_visibility_duration = -1; a.symbol = item.symbol; a.color = item.color; player.inv.Remove(item); } else{ B.Add("Your pack feels lighter. "); player.inv.Remove(item); } } break; } case EventType.GRENADE: { Tile t = target as Tile; if(t.Is(FeatureType.GRENADE)){ t.features.Remove(FeatureType.GRENADE); B.Add("The grenade explodes! ",t); if(t.seen){ Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); } B.DisplayNow(); t.ApplyExplosion(1,"an exploding grenade"); /*List<pos> cells = new List<pos>(); foreach(Tile tile in t.TilesWithinDistance(1)){ if(tile.passable && tile.seen){ //animation LOS check here cells.Add(tile.p); } } Screen.AnimateMapCells(cells,new colorchar('*',Color.RandomExplosion)); Actor a = t.actor(); if(a != null){ a.attrs[AttrType.TURN_INTO_CORPSE] = 1; } foreach(Actor a2 in t.ActorsWithinDistance(1)){ a2.TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(3,6),null,"an exploding grenade"); } if(a != null){ int dir = Global.RandomDirection(); if(a.curhp > 0 || !a.HasAttr(AttrType.NO_CORPSE_KNOCKBACK)){ t.TileInDirection(dir).KnockObjectBack(a,1); } a.CorpseCleanup(); } t.MakeNoise(8);*/ } break; } case EventType.BLAST_FUNGUS: { Item i = target as Item; i.other_data--; if(i.other_data == 0){ Tile t = null; if(M.tile.BoundsCheck(i.row,i.col) && M.tile[i.p].inv == i){ t = M.tile[i.p]; t.inv = null; } else{ foreach(Actor a in M.AllActors()){ if(a.inv.Contains(i)){ a.inv.Remove(i); t = a.tile(); break; } } } if(t != null){ B.Add("The blast fungus explodes! ",t); if(t.seen){ Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); } B.DisplayNow(); t.ApplyExplosion(3,"an exploding blast fungus"); } } else{ Tile t = null; if(M.tile.BoundsCheck(i.row,i.col) && M.tile[i.p].inv == i){ t = M.tile[i.p]; } else{ foreach(Actor a in M.AllActors()){ if(a.inv.Contains(i)){ t = a.tile(); break; } } } if(t != null && t.seen){ Screen.AnimateMapCell(t.row,t.col,new colorchar(i.other_data.ToString()[0],Color.Red),100); } Q.Add(new Event(i,100,EventType.BLAST_FUNGUS)); } break; } case EventType.STALAGMITE: { if(value > 1){ int stalagmites = 0; //number removed int number_left = 0; List<Tile> crumbled = new List<Tile>(); foreach(Tile tile in area){ if(tile.type == TileType.STALAGMITE){ if(R.OneIn(value)){ crumbled.Add(tile); tile.Toggle(null); ++stalagmites; } else{ ++number_left; } } } if(stalagmites > 0){ if(stalagmites > 1){ B.Add("The stalagmites crumble. ",crumbled.ToArray()); } else{ B.Add("The stalagmite crumbles. ",crumbled.ToArray()); } } if(number_left > 0){ Q.Add(new Event(area,100,EventType.STALAGMITE,value)); } } else{ int stalagmites = 0; foreach(Tile tile in area){ if(tile.type == TileType.STALAGMITE){ stalagmites++; } } if(stalagmites > 0){ if(stalagmites > 1){ B.Add("The stalagmites crumble. ",area.ToArray()); } else{ B.Add("The stalagmite crumbles. ",area.ToArray()); } foreach(Tile tile in area){ if(tile.type == TileType.STALAGMITE){ tile.Toggle(null); } } } } break; } case EventType.FIRE_GEYSER: { int frequency = value / 10; //9-39 int variance = value % 10; //0-9 int variance_amount = (frequency * variance) / 10; int number_of_values = variance_amount*2 + 1; int minimum_value = frequency - variance_amount; if(minimum_value < 5){ int diff = 5 - minimum_value; number_of_values -= diff; minimum_value = 5; } int delay = ((minimum_value - 1) + R.Roll(number_of_values)) * 100; Q.Add(new Event(target,delay+200,EventType.FIRE_GEYSER,value)); Q.Add(new Event(target,delay,EventType.FIRE_GEYSER_ERUPTION,2)); break; } case EventType.FIRE_GEYSER_ERUPTION: { foreach(Tile t in target.TilesWithinDistance(2)){ t.RemoveFeature(FeatureType.FOG); } //int old_radius = target.light_radius; //target.UpdateRadius(old_radius,2,true); B.Add(target.the_name + " spouts flames! ",target); if(target.actor() != null){ target.actor().ApplyBurning(); } for(int i=0;i<4;++i){ Tile t = target.TilesWithinDistance(2).Where(x=>target.HasLOE(x)).RandomOrDefault(); if(t != null){ if(t.passable){ t.AddFeature(FeatureType.FIRE); } else{ t.ApplyEffect(DamageType.FIRE); } } } //target.UpdateRadius(2,old_radius,true); if(value > 0){ Q.Add(new Event(target,100,EventType.FIRE_GEYSER_ERUPTION,value - 1)); } break; } case EventType.FOG_VENT: { Tile current = target as Tile; if(!current.Is(FeatureType.FOG)){ current.AddFeature(FeatureType.FOG); List<Tile> new_area = new List<Tile>{current}; Q.RemoveTilesFromEventAreas(new_area,EventType.REMOVE_GAS); Event.RemoveGas(new_area,600,FeatureType.FOG,25); //Q.Add(new Event(new_area,600,EventType.FOG,25)); } else{ for(int tries=0;tries<50;++tries){ List<Tile> open = new List<Tile>(); foreach(Tile t in current.TilesAtDistance(1)){ //perhaps the rework could involve refreshing the duration of nearby tiles - if enough are refreshed, then no new tiles need to be added if(t.passable){ open.Add(t); if(!t.Is(FeatureType.FOG)){ open.Add(t); //3x as likely if it can expand there open.Add(t); } } } if(open.Count > 0){ Tile possible = open.Random(); if(!possible.Is(FeatureType.FOG)){ possible.AddFeature(FeatureType.FOG); List<Tile> new_area = new List<Tile>{possible}; Q.RemoveTilesFromEventAreas(new_area,EventType.REMOVE_GAS); Event.RemoveGas(new_area,600,FeatureType.FOG,25); break; } else{ current = possible; } } else{ break; } } } Q.Add(new Event(target,100,EventType.FOG_VENT)); break; } case EventType.POISON_GAS_VENT: { Tile current = target as Tile; if(R.OneIn(7)){ int num = R.Roll(5) + 2; List<Tile> new_area = new List<Tile>(); for(int i=0;i<num;++i){ if(!current.Is(FeatureType.POISON_GAS)){ current.AddFeature(FeatureType.POISON_GAS); new_area.Add(current); } else{ for(int tries=0;tries<50;++tries){ List<Tile> open = new List<Tile>(); foreach(Tile t in current.TilesAtDistance(1)){ if(t.passable){ open.Add(t); } } if(open.Count > 0){ Tile possible = open.Random(); if(!possible.Is(FeatureType.POISON_GAS)){ possible.AddFeature(FeatureType.POISON_GAS); new_area.Add(possible); break; } else{ current = possible; } } else{ break; } } } } if(new_area.Count > 0){ B.Add("Toxic vapors pour from " + target.the_name + "! ",target); Event.RemoveGas(new_area,200,FeatureType.POISON_GAS,18); } } Q.Add(new Event(target,100,EventType.POISON_GAS_VENT)); break; } case EventType.STONE_SLAB: { Tile t = target as Tile; if(t.type == TileType.STONE_SLAB && (t.IsLitFromAnywhere(true) || area.Any(x=>x.actor()!=null))){ bool vis = player.CanSee(t); t.Toggle(null); //t.Toggle(null,TileType.FLOOR); //t.symbol = '-'; //t.revealed_by_light = true; if(!vis && player.CanSee(t)){ vis = true; } if(vis){ B.Add("The stone slab rises with a grinding sound. "); } else{ if(player.DistanceFrom(t) <= 6){ B.Add("You hear a grinding sound. "); } } } else{ if(t.type == TileType.STONE_SLAB_OPEN && !t.IsLitFromAnywhere(true) && t.actor() == null && !area.Any(x=>x.actor()!=null)){ bool vis = player.CanSee(t); //t.Toggle(null,TileType.STONE_SLAB); t.Toggle(null); if(!vis && player.CanSee(t)){ vis = true; } if(vis){ B.Add("The stone slab descends with a grinding sound. "); } else{ if(player.DistanceFrom(t) <= 6){ B.Add("You hear a grinding sound. "); } } } } Q.Add(new Event(target,area,100,EventType.STONE_SLAB)); break; } case EventType.MARBLE_HORROR: { Tile t = target as Tile; if(t.type == TileType.STATUE){ if(value == 1 && player.CanSee(t) && !t.IsLit() && t.actor() == null){ //if target was visible last turn & this turn, and it's currently in darkness... t.TransformTo(TileType.FLOOR); Actor a = Actor.Create(ActorType.MARBLE_HORROR,t.row,t.col,TiebreakerAssignment.AtEnd); //todo: not sure - should this get a placeholder like poltergeist and mimic? foreach(Event e in Q.list){ if(e.target == a && e.type == EventType.MOVE){ e.dead = true; break; } } a.Q0(); switch(R.Roll(2)){ case 1: B.Add("You think that statue might have just moved... "); B.Print(true); break; case 2: B.Add("The statue turns its head to face you. "); B.Print(true); break; } } else{ if(player.CanSee(t)){ Q.Add(new Event(target,100,EventType.MARBLE_HORROR,1)); } else{ Q.Add(new Event(target,100,EventType.MARBLE_HORROR,0)); } } } break; } case EventType.REGENERATING_FROM_DEATH: { int health = value; int permanent_damage = secondary_value; if(target.tile().Is(FeatureType.TROLL_CORPSE)){ //otherwise, assume it was destroyed by fire int maxhp = Actor.Prototype(ActorType.TROLL).maxhp; int recovered = Actor.Prototype(ActorType.TROLL).attrs[AttrType.REGENERATING]; if(health + recovered > maxhp - permanent_damage){ recovered = (maxhp - permanent_damage) - health; } health += recovered; if(permanent_damage >= maxhp){ break; } if(health > 0 && target.actor() == null){ Actor a = Actor.Create(ActorType.TROLL,target.row,target.col,TiebreakerAssignment.UseCurrent); a.curhp = health; a.attrs[AttrType.PERMANENT_DAMAGE] = permanent_damage; a.attrs[AttrType.NO_ITEM]++; a.attrs[AttrType.DANGER_SENSED]++; B.Add("The troll stands up! ",target); a.player_visibility_duration = -1; if(target.tile().type == TileType.DOOR_C){ target.tile().Toggle(a); } target.tile().features.Remove(FeatureType.TROLL_CORPSE); a.attrs[AttrType.WANDERING]++; } else{ int roll = R.Roll(20); if(health == -1){ roll = 1; } if(health == 0){ roll = 3; } switch(roll){ case 1: case 2: B.Add("The troll's corpse twitches. ",target); break; case 3: case 4: B.Add("You hear sounds coming from the troll's corpse. ",target); break; case 5: B.Add("The troll on the floor regenerates. ",target); break; default: break; } Event e = new Event(target,100,EventType.REGENERATING_FROM_DEATH); e.value = health; e.secondary_value = permanent_damage; Q.Add(e); } } if(target.tile().Is(FeatureType.TROLL_BLOODWITCH_CORPSE)){ //otherwise, assume it was destroyed by fire int maxhp = Actor.Prototype(ActorType.TROLL_BLOODWITCH).maxhp; int recovered = Actor.Prototype(ActorType.TROLL_BLOODWITCH).attrs[AttrType.REGENERATING]; if(health + recovered > maxhp - permanent_damage){ recovered = (maxhp - permanent_damage) - health; } health += recovered; if(permanent_damage >= maxhp){ break; } if(recovered > 0){ List<pos> cells = new List<pos>(); List<colorchar> cch = new List<colorchar>(); foreach(pos p2 in target.PositionsWithinDistance(4)){ if(target.HasLOE(M.tile[p2]) && player.CanSee(M.tile[p2])){ cells.Add(p2); colorchar ch = M.VisibleColorChar(p2.row,p2.col); ch.color = Color.Red; cch.Add(ch); } } if(cells.Count > 0){ M.Draw(); Screen.AnimateMapCells(cells,cch,40); } foreach(Actor a in target.ActorsWithinDistance(4)){ if(target.HasLOE(a)){ if(a == player){ B.Add("Ow! "); } a.TakeDamage(DamageType.NORMAL,DamageClass.MAGICAL,recovered,null,"trollish blood magic"); } } } if(health > 0 && target.actor() == null){ Actor a = Actor.Create(ActorType.TROLL_BLOODWITCH,target.row,target.col,TiebreakerAssignment.UseCurrent); a.curhp = health; a.attrs[AttrType.PERMANENT_DAMAGE] = permanent_damage; a.attrs[AttrType.NO_ITEM]++; a.attrs[AttrType.DANGER_SENSED]++; B.Add("The troll bloodwitch rises! ",target); a.player_visibility_duration = -1; if(attr == AttrType.COOLDOWN_1){ a.attrs[AttrType.COOLDOWN_1]++; } if(target.tile().type == TileType.DOOR_C){ target.tile().Toggle(a); } target.tile().features.Remove(FeatureType.TROLL_BLOODWITCH_CORPSE); a.attrs[AttrType.WANDERING]++; } else{ int roll = R.Roll(20); if(health == -1){ roll = 1; } if(health == 0){ roll = 3; } switch(roll){ case 1: case 2: B.Add("The bloodwitch's corpse twitches. ",target); break; case 3: case 4: B.Add("You feel a pulse like a heartbeat coming from the bloodwitch. ",target); break; case 5: B.Add("The troll bloodwitch on the floor regenerates. ",target); break; default: break; } Event e = new Event(target,100,EventType.REGENERATING_FROM_DEATH); e.value = health; e.secondary_value = permanent_damage; Q.Add(e); } } break; } case EventType.REASSEMBLING: { Tile t = target as Tile; if(t.Is(FeatureType.BONES)){ if(t.actor() == null){ Actor a = Actor.Create(ActorType.SKELETON,target.row,target.col,TiebreakerAssignment.UseCurrent); B.Add("The skeleton reassembles itself. ",target); a.player_visibility_duration = -1; if(target.tile().type == TileType.DOOR_C){ target.tile().Toggle(a); } target.tile().features.Remove(FeatureType.BONES); if(R.OneIn(3)){ a.attrs[AttrType.WANDERING]++; } } else{ Q.Add(new Event(target,100,EventType.REASSEMBLING)); } } break; } case EventType.SHIELDING: { List<pos> cells = new List<pos>(); List<colorchar> symbols = new List<colorchar>(); int animation_delay = 75; foreach(Tile tile in area){ colorchar cch = tile.visual; if(tile.actor() != null){ if(!tile.actor().HasAttr(AttrType.SHIELDED)){ tile.actor().attrs[AttrType.SHIELDED] = 1; B.Add(tile.actor().YouAre() + " shielded. ",tile.actor()); } if(player.CanSee(tile.actor())){ animation_delay = 150; cch = tile.actor().visual; } } cch.bgcolor = Color.Blue; if(Global.LINUX && !Screen.GLMode){ cch.bgcolor = Color.DarkBlue; } if(cch.color == cch.bgcolor){ cch.color = Color.Black; } if(cch.c == '.'){ cch.c = '+'; } symbols.Add(cch); cells.Add(tile.p); } M.Draw(); Screen.AnimateMapCells(cells,symbols,animation_delay); --value; if(value > 0){ Q.Add(new Event(area,100,EventType.SHIELDING,value)); } break; } case EventType.FINAL_LEVEL_SPAWN_CULTISTS: { int num_cultists = M.AllActors().Where(x=>x.Is(ActorType.FINAL_LEVEL_CULTIST)).Count; if(num_cultists < 5){ Actor a = M.SpawnMob(ActorType.CULTIST); if(a != null){ List<Actor> group = null; if(a.group != null){ group = new List<Actor>(a.group); a.group.Clear(); } else{ group = new List<Actor>{a}; } List<int> valid_circles = new List<int>(); for(int i=0;i<5;++i){ if(M.FinalLevelSummoningCircle(i).PositionsWithinDistance(2,M.tile).Any(x=>M.tile[x].Is(TileType.DEMONIC_IDOL))){ valid_circles.Add(i); } } foreach(Actor a2 in group){ int i = valid_circles.RemoveLast(); pos circle = M.FinalLevelSummoningCircle(i); a2.FindPath(circle.row,circle.col); a2.attrs[AttrType.COOLDOWN_2] = i; a2.type = ActorType.FINAL_LEVEL_CULTIST; a2.group = null; if(!R.OneIn(20)){ a2.attrs[AttrType.NO_ITEM] = 1; } } } } Q.Add(new Event(R.Between(5,8)*100,EventType.FINAL_LEVEL_SPAWN_CULTISTS)); break; } /*case EventType.BOSS_SIGN: { string s = ""; switch(R.Roll(8)){ case 1: s = "You see scratch marks on the walls and floor. "; break; case 2: s = "There are deep gouges in the floor here. "; break; case 3: s = "The floor here is scorched and blackened. "; break; case 4: s = "You notice bones of an unknown sort on the floor. "; break; case 5: s = "You hear a distant roar. "; break; case 6: s = "You smell smoke. "; break; case 7: s = "You spot a large reddish scale on the floor. "; break; case 8: s = "A small tremor shakes the area. "; break; default: s = "Debug message. "; break; } if(!player.HasAttr(AttrType.RESTING)){ B.AddIfEmpty(s); } Q.Add(new Event((R.Roll(20)+35)*100,EventType.BOSS_SIGN)); break; } case EventType.BOSS_ARRIVE: { bool spawned = false; Actor a = null; if(M.AllActors().Count == 1 && !Q.Contains(EventType.POLTERGEIST)){ List<Tile> trolls = new List<Tile>(); for(LinkedListNode<Event> current = Q.list.First;current!=null;current = current.Next){ if(current.Value.type == EventType.REGENERATING_FROM_DEATH){ trolls.Add((current.Value.target) as Tile); } } foreach(Tile troll in trolls){ if(troll.Is(FeatureType.TROLL_CORPSE)){ B.Add("The troll corpse burns to ashes! ",troll); troll.features.Remove(FeatureType.TROLL_CORPSE); } else{ if(troll.Is(FeatureType.TROLL_BLOODWITCH_CORPSE)){ B.Add("The troll bloodwitch corpse burns to ashes! ",troll); troll.features.Remove(FeatureType.TROLL_BLOODWITCH_CORPSE); } } } Q.KillEvents(null,EventType.REGENERATING_FROM_DEATH); List<Tile> goodtiles = M.AllTiles(); List<Tile> removed = new List<Tile>(); foreach(Tile t in goodtiles){ if(!t.passable || t.Is(TileType.CHASM) || player.CanSee(t)){ removed.Add(t); } } foreach(Tile t in removed){ goodtiles.Remove(t); } if(goodtiles.Count > 0){ B.Add("You hear a loud crash and a nearby roar! "); Tile t = goodtiles[R.Roll(goodtiles.Count)-1]; a = Actor.Create(ActorType.FIRE_DRAKE,t.row,t.col,true,false); spawned = true; } else{ if(M.AllTiles().Any(t=>t.passable && !t.Is(TileType.CHASM) && t.actor() == null)){ B.Add("You hear a loud crash and a nearby roar! "); Tile tile = M.AllTiles().Where(t=>t.passable && !t.Is(TileType.CHASM) && t.actor() == null).Random(); a = Actor.Create(ActorType.FIRE_DRAKE,tile.row,tile.col,true,false); spawned = true; } } } if(!spawned){ Q.Add(new Event(null,null,(R.Roll(20)+10)*100,EventType.BOSS_ARRIVE,attr,value,"")); } else{ if(value > 0){ a.curhp = value; } else{ //if there's no good value, this means that this is the first appearance. B.Add("The ground shakes as dust and rocks fall from the cavern ceiling. "); B.Add("This place is falling apart! "); List<Tile> floors = M.AllTiles().Where(t=>t.passable && t.type != TileType.CHASM && player.tile() != t); Tile tile = null; if(floors.Count > 0){ tile = floors.Random(); (tile as Tile).Toggle(null,TileType.CHASM); } Q.Add(new Event(tile,100,EventType.FLOOR_COLLAPSE)); Q.Add(new Event((R.Roll(20)+20)*100,EventType.CEILING_COLLAPSE)); } } break; } case EventType.FLOOR_COLLAPSE: { Tile current = target as Tile; int tries = 0; if(current != null){ for(tries=0;tries<50;++tries){ List<Tile> open = new List<Tile>(); foreach(Tile t in current.TilesAtDistance(1)){ if(t.passable || t.Is(TileType.RUBBLE)){ open.Add(t); } } if(open.Count > 0){ Tile possible = open.Random(); if(!possible.Is(TileType.CHASM)){ possible.Toggle(null,TileType.CHASM); List<Tile> open_neighbors = possible.TilesAtDistance(1).Where(t=>t.passable && t.type != TileType.CHASM); int num_neighbors = open_neighbors.Count; while(open_neighbors.Count > num_neighbors/2){ Tile neighbor = open_neighbors.RemoveRandom(); neighbor.Toggle(null,TileType.CHASM); } break; } else{ current = possible; } } else{ break; } } } if(tries == 50 || current == null){ List<Tile> floors = M.AllTiles().Where(t=>t.passable && t.type != TileType.CHASM && player.tile() != t); if(floors.Count > 0){ target = floors.Random(); (target as Tile).Toggle(null,TileType.CHASM); } } Q.Add(new Event(target,100,EventType.FLOOR_COLLAPSE)); break; } case EventType.CEILING_COLLAPSE: { B.Add("The ground shakes and debris falls from the ceiling! "); for(int i=1;i<Global.ROWS-1;++i){ for(int j=1;j<Global.COLS-1;++j){ Tile t = M.tile[i,j]; if(t.Is(TileType.WALL)){ int num_walls = t.TilesAtDistance(1).Where(x=>x.Is(TileType.WALL)).Count; if(num_walls < 8 && R.OneIn(20)){ if(R.CoinFlip()){ t.Toggle(null,TileType.FLOOR); foreach(Tile neighbor in t.TilesAtDistance(1)){ neighbor.solid_rock = false; } } else{ t.Toggle(null,TileType.RUBBLE); foreach(Tile neighbor in t.TilesAtDistance(1)){ neighbor.solid_rock = false; if(neighbor.type == TileType.FLOOR && R.OneIn(10)){ neighbor.Toggle(null,TileType.RUBBLE); } } } } } else{ int num_walls = t.TilesAtDistance(1).Where(x=>x.Is(TileType.WALL)).Count; if(num_walls == 0 && R.OneIn(100)){ if(R.OneIn(6)){ t.Toggle(null,TileType.RUBBLE); } foreach(Tile neighbor in t.TilesAtDistance(1)){ if(neighbor.type == TileType.FLOOR && R.OneIn(6)){ neighbor.Toggle(null,TileType.RUBBLE); } } } } } } Q.Add(new Event((R.Roll(20)+20)*100,EventType.CEILING_COLLAPSE)); break; }*/ case EventType.NORMAL_LIGHTING: { bool check_for_torch_dimming = false; if(M.wiz_lite){ B.Add("The supernatural brightness fades from the air. "); } if(M.wiz_dark){ B.Add("The supernatural darkness fades from the air. "); check_for_torch_dimming = true; } M.wiz_lite = false; M.wiz_dark = false; if(check_for_torch_dimming && player.HasAttr(AttrType.DIM_LIGHT)){ player.CalculateDimming(); } break; } case EventType.TELEPORTAL: { Tile t = target as Tile; if(t != null && t.Is(FeatureType.TELEPORTAL,FeatureType.STABLE_TELEPORTAL)){ if(t.Is(FeatureType.TELEPORTAL)){ value--; //unstable teleportals (from the item) degrade each turn } else{ if(value < 100){ value++; //stable ones repair themselves after use } } Actor a = t.actor(); Tile dest = null; if(a != null && !a.HasAttr(AttrType.JUST_TELEPORTED,AttrType.IMMOBILE)){ if(area != null){ dest = area.RandomOrDefault(); } else{ List<Tile> tiles = M.AllTiles().Where(x => x.passable && x.actor() == null && t.ApproximateEuclideanDistanceFromX10(x) >= 45); dest = tiles.RandomOrDefault(); } if(dest != null){ a.RefreshDuration(AttrType.JUST_TELEPORTED,101); value -= 25; bool visible = false; if(a == player){ B.Add("You disappear into the teleportal. "); } else{ if(player.CanSee(a)){ visible = true; B.Add(a.the_name + " disappears into the teleportal. ",t); } } a.Move(dest.row,dest.col); if(a != player && player.CanSee(a)){ if(visible){ B.Add(a.the_name + " reappears. ",a); } else{ B.Add(a.a_name + " suddenly appears! ",a); } } } } else{ if(a != null && a.HasAttr(AttrType.JUST_TELEPORTED)){ a.RefreshDuration(AttrType.JUST_TELEPORTED,101); } } if(t.inv != null && t.Is(FeatureType.TELEPORTAL)){ List<Tile> tiles = M.AllTiles().Where(x => x.passable && x.inv == null && t.ApproximateEuclideanDistanceFromX10(x) >= 45); dest = tiles.RandomOrDefault(); if(dest != null){ Item i = t.inv; bool visible = false; if(player.CanSee(t)){ visible = true; B.Add(i.TheName(true) + " disappears into the teleportal. ",t); } t.inv = null; dest.GetItem(i); if(player.CanSee(dest)){ if(visible){ B.Add(i.TheName(true) + " reappears. ",dest); } else{ B.Add(i.AName(true) + " suddenly appears! ",dest); } } } } if(value > 0){ Q.Add(new Event(target,area,100,EventType.TELEPORTAL,AttrType.NO_ATTR,value,"")); if(value < 25){ if(dest != null || R.OneIn(8)){ B.Add("The teleportal flickers. ",t,dest); } } } else{ if(t.Is(FeatureType.TELEPORTAL)){ t.RemoveFeature(FeatureType.TELEPORTAL); } if(t.Is(FeatureType.STABLE_TELEPORTAL)){ foreach(Tile t2 in area){ Event e2 = Q.FindTargetedEvent(t2,EventType.TELEPORTAL); if(e2 != null && t2.features.Contains(FeatureType.STABLE_TELEPORTAL)){ e2.area.Remove(t); if(e2.area.Count == 0){ t2.RemoveFeature(FeatureType.STABLE_TELEPORTAL); //t2.AddFeature(FeatureType.INACTIVE_TELEPORTAL); e2.dead = true; } } } t.RemoveFeature(FeatureType.STABLE_TELEPORTAL); } B.Add("The teleportal flickers and vanishes. ",t,dest); } } break; } case EventType.BREACH: { if(!R.OneIn(3)){ Tile t = area.WhereGreatest(x=>x.DistanceFrom(target)).RandomOrDefault(); if(t != null){ t.Toggle(null); if(t.actor() != null || t.inv != null){ foreach(Tile nearby in M.ReachableTilesByDistance(t.row,t.col,false)){ if(t.inv != null && nearby.inv == null){ nearby.GetItem(t.inv); t.inv = null; if(t.actor() == null){ break; } } if(t.actor() != null && nearby.actor() == null){ t.actor().Move(nearby.row,nearby.col); if(t.inv == null){ break; } } } if(t.actor() != null){ //if there wasn't an actual path to a passable tile, just move to the nearest for(int i=1;i<Math.Max(Global.ROWS,Global.COLS);++i){ List<Tile> tiles = t.TilesAtDistance(i).Where(x=>x.passable && x.actor() == null); bool done = false; while(tiles.Count > 0){ Tile dest = tiles.Random(); t.actor().Move(dest.row,dest.col); done = true; break; } if(done){ break; } } } if(t.inv != null){ for(int i=1;i<Math.Max(Global.ROWS,Global.COLS);++i){ List<Tile> tiles = t.TilesAtDistance(i).Where(x=>x.passable && x.inv == null); bool done = false; while(tiles.Count > 0){ Tile dest = tiles.Random(); dest.GetItem(t.inv); t.inv = null; done = true; break; } if(done){ break; } } } } if(t.features.Count > 0){ t.features.Clear(); } area.Remove(t); } } if(area.Count > 0){ Q.Add(new Event(target,area,100,EventType.BREACH)); } break; } case EventType.GRAVE_DIRT: { foreach(Tile t in area){ Actor a = t.actor(); if(a != null && a.type != ActorType.CORPSETOWER_BEHEMOTH && !a.HasAttr(AttrType.IMMOBILE,AttrType.JUST_GRABBED,AttrType.FROZEN,AttrType.FLYING) && R.OneIn(12)){ if(player.CanSee(a)){ B.Add("A dead hand reaches up and grabs " + a.the_name + "! ",t); } if(a == player){ B.Print(true); } if(a.HasAttr(AttrType.SLIMED,AttrType.OIL_COVERED,AttrType.BRUTISH_STRENGTH)){ if(player.CanSee(a)){ B.Add(a.You("slip") + " out of its grasp. ",t); } } else{ int duration = R.Roll(4) * 100; a.attrs[AttrType.IMMOBILE]++; Q.Add(new Event(a,duration,AttrType.IMMOBILE,"The dead hand releases " + a.TheName(true) + ". ",t)); //it'd be nice to check LOS here a.RefreshDuration(AttrType.JUST_GRABBED,duration + 100); } } } Q.Add(new Event(area,100,EventType.GRAVE_DIRT)); break; } case EventType.TOMBSTONE_GHOST: { if(area.Count > 0){ Tile t = area[0]; if(target == null && t.actor() == player){ foreach(Tile t2 in M.ReachableTilesByDistance(player.row,player.col,false)){ if(t2.passable && t2.actor() == null){ Actor ghost = Actor.Create(ActorType.GHOST,t2.row,t2.col); if(ghost != null){ target = ghost; ghost.player_visibility_duration = -1; ghost.target = player; t.color = Color.White; B.Add("A vengeful ghost rises! "); B.PrintAll(); break; } } } } Q.Add(new Event(target,area,100,EventType.TOMBSTONE_GHOST)); } break; } case EventType.POPPIES: { List<Tile> new_area = new List<Tile>(); bool recalculate_distance_map = false; foreach(Tile t in area){ if(t.type == TileType.POPPY_FIELD){ new_area.Add(t); Actor a = t.actor(); if(a == player){ Help.TutorialTip(TutorialTopic.Poppies); } if(a != null && !a.HasAttr(AttrType.NONLIVING,AttrType.PLANTLIKE)){ if(a.attrs[AttrType.POPPY_COUNTER] < 4){ a.GainAttrRefreshDuration(AttrType.POPPY_COUNTER,200); if(a == player && a.attrs[AttrType.POPPY_COUNTER] == 1){ B.Add("You breathe in the overwhelming scent of the poppies. "); //todo: this was set to "no interrupt" before. why? } } else{ a.RefreshDuration(AttrType.POPPY_COUNTER,200); } if(a.attrs[AttrType.POPPY_COUNTER] >= 4){ if(!a.HasAttr(AttrType.ASLEEP,AttrType.JUST_AWOKE)){ if(a.ResistedBySpirit()){ if(player.HasLOS(a)){ B.Add(a.You("resist") + " falling asleep. ",a); } } else{ if(player.HasLOS(a)){ B.Add(a.You("fall") + " asleep in the poppies. ",a); //B.Add("The poppies lull " + a.the_name + " to sleep. ",a); } a.attrs[AttrType.ASLEEP] = R.Between(4,6); } } /*a.ApplyStatus(AttrType.MAGICAL_DROWSINESS,(R.Roll(3)+4)*100); if(a == player && !a.HasAttr(AttrType.MAGICAL_DROWSINESS)){ //B.Add("The poppies make you drowsy. "); Help.TutorialTip(TutorialTopic.Drowsiness); } a.RefreshDuration(AttrType.MAGICAL_DROWSINESS,a.DurationOfMagicalEffect((R.Roll(3)+4)) * 100,a.YouFeel() + " less drowsy. ",a);*/ } } } else{ recalculate_distance_map = true; } } if(new_area.Count > 0){ Q.Add(new Event(new_area,100,EventType.POPPIES)); if(recalculate_distance_map){ M.CalculatePoppyDistanceMap(); } } break; } case EventType.BURROWING: { List<Tile> open = area.Where(x=>x.passable && x.actor() == null); Actor a = target as Actor; if(open.Count > 0){ Tile t = open.Random(); Event e = new Event(a,100,EventType.MOVE); e.tiebreaker = this.tiebreaker; Q.Add(e); a.attrs[AttrType.BURROWING] = 0; a.Move(t.row,t.col); if(player.CanSee(a)){ a.AnimateStorm(1,2,3,'*',Color.Gray); } B.Add(a.TheName(true) + " emerges from the ground. ",a,t); } else{ if(a.HasAttr(AttrType.REGENERATING)){ a.curhp += a.attrs[AttrType.REGENERATING]; if(a.curhp > a.maxhp){ a.curhp = a.maxhp; } } Q.Add(new Event(target,area,100,EventType.BURROWING)); } break; } case EventType.SPAWN_WANDERING_MONSTER: { int spawn_chance = 2; foreach(Actor a in Actor.tiebreakers){ if(a != player && a != null && !a.HasAttr(AttrType.IMMOBILE) && (a.group == null || a.group.Count == 0 || a.group[0] == a)){ spawn_chance *= 2; if(spawn_chance >= 65536){ break; } } } if(R.OneIn(spawn_chance)){ if(M.extra_danger < 8 && R.CoinFlip() && M.current_level != 1){ M.extra_danger++; B.Add("You sense danger. "); } Actor a = M.SpawnWanderingMob(); if(a != null){ a.attrs[AttrType.WANDERING] = 1; a.attrs[AttrType.NO_ITEM] = 1; if(player.CanSee(a)){ B.Add("You suddenly sense the presence of " + a.AName(true) + ". "); } } } Q.Add(new Event(R.Between(20,60)*100,EventType.SPAWN_WANDERING_MONSTER)); break; } /*case EventType.GAS_UPDATE: { int ROWS = Global.ROWS; int COLS = Global.COLS; float[,] g = null; for(int num=0;num<3;++num){ g = new float[ROWS,COLS]; for(int i=1;i<ROWS-1;++i){ for(int j=1;j<COLS-1;++j){ if(M.tile[i,j].passable){ float neighbors_total = 0.0f; int open = 0; foreach(int dir in U.EightDirections){ if(M.tile[i,j].TileInDirection(dir).passable){ pos p = new pos(i,j).PosInDir(dir); neighbors_total += M.gas[p.row,p.col]; ++open; } } if(open > 0){ float avg = neighbors_total / (float)open; float d = 0.03f * open; g[i,j] = M.gas[i,j] * (1-d) + avg * d; } } } } M.gas = g; } for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(g[i,j] > 0.0f){ if(g[i,j] <= 0.001f){ g[i,j] = 0.0f; M.tile[i,j].features.Remove(FeatureType.POISON_GAS); } else{ g[i,j] -= 0.001f;// * (float)R.r.NextDouble(); M.tile[i,j].features.AddUnique(FeatureType.POISON_GAS); } } else{ M.tile[i,j].features.Remove(FeatureType.POISON_GAS); } } } Q.Add(new Event(100,EventType.GAS_UPDATE)); break; }*/ case EventType.FIRE: { List<Tile> chance_to_burn = new List<Tile>(); //tiles that might be affected List<Tile> chance_to_die_out = new List<Tile>(); //fires that might die out List<PhysicalObject> no_fire = new List<PhysicalObject>(); foreach(PhysicalObject o in new List<PhysicalObject>(Fire.burning_objects)){ if(o.IsBurning()){ foreach(Tile neighbor in o.TilesWithinDistance(1)){ if(neighbor.actor() != null && neighbor.actor() != o){ if(neighbor.actor() == player){ if(!player.HasAttr(AttrType.JUST_SEARED,AttrType.FROZEN,AttrType.DAMAGE_RESISTANCE)){ B.Add("The heat sears you! "); } player.RefreshDuration(AttrType.JUST_SEARED,50); } neighbor.actor().TakeDamage(DamageType.FIRE,DamageClass.PHYSICAL,false,1,null,"searing heat"); } //every actor adjacent to a burning object takes proximity fire damage. (actors never get set on // fire directly this way, but an actor covered in oil will ignite if it takes any fire damage) //every tile adjacent to a burning object has a chance to be affected by fire. oil-covered objects are always affected. //if the roll is passed, fire is applied to the tile. chance_to_burn.AddUnique(neighbor); } if(o is Tile){ chance_to_die_out.AddUnique(o as Tile); } } else{ no_fire.AddUnique(o); } } foreach(Tile t in chance_to_burn){ if(R.OneIn(6) || t.Is(FeatureType.OIL,FeatureType.SPORES,FeatureType.CONFUSION_GAS) || t.Is(TileType.BARREL)){ t.ApplyEffect(DamageType.FIRE); } } foreach(Tile t in chance_to_die_out){ if(!t.Is(TileType.BARREL)){ bool more_flammable_terrain = false; bool more_fire = false; bool final_level_demonic_idol_present = false; //this will soon become a check for any terrain that prevents fires from dying foreach(Tile neighbor in t.TilesAtDistance(1)){ if(neighbor.IsCurrentlyFlammable()){ more_flammable_terrain = true; } if(neighbor.Is(TileType.DEMONIC_IDOL)){ final_level_demonic_idol_present = true; } if(neighbor.IsBurning()){ more_fire = true; } } if(final_level_demonic_idol_present){ continue; //this fire never goes out } int chance = 5; if(more_fire){ chance = 10; } if(more_flammable_terrain){ chance = 20; } if(R.OneIn(chance)){ t.RemoveFeature(FeatureType.FIRE); Fire.burning_objects.Remove(t); if(t.name == "floor" && t.type != TileType.BREACHED_WALL){ t.MakeFloorCharred(); } } } } foreach(PhysicalObject o in no_fire){ Fire.burning_objects.Remove(o); } if(Fire.burning_objects.Count > 0){ Event e = new Event(100,EventType.FIRE); Q.Add(e); Fire.fire_event = e; } else{ Fire.fire_event = null; } break; } } if(msg != ""){ if(msg_objs == null){ B.Add(msg); } else{ if(msg_objs.Count == 1 && msg_objs[0] is Actor && (msg_objs[0] as Actor).HasAttr(AttrType.BURROWING)){ //do nothing } else{ B.Add(msg,msg_objs.ToArray()); } } } } }
private static TileModels ExtractTileM2s(int tileX, int tileY, ADTFile adt) { var LoadedWMOIds = new List<uint>(); var list = adt.DoodadDefinitions; var tileModels = new TileModels { Models = new List<TileModel>(list.Count) }; foreach (var definition in list) { if (LoadedM2Ids.Contains(definition.UniqueId)) continue; if (string.IsNullOrEmpty(definition.FilePath)) continue; var model = ExtractModel(definition); if (model.Vertices.Length < 1) continue; tileModels.Models.Add(model); LoadedM2Ids.AddUnique(definition.UniqueId); } var wmoList = adt.ObjectDefinitions; foreach (var wmo in wmoList) { if (LoadedWMOIds.Contains(wmo.UniqueId)) continue; var worldPos = new Vector3(TerrainConstants.CenterPoint - wmo.Position.X, wmo.Position.Y, TerrainConstants.CenterPoint - wmo.Position.Z); worldPos = CorrectWMOOrigin(worldPos); // If this WMO belongs to another tile, skip it. var wmoTileX = (int)((TerrainConstants.CenterPoint - worldPos.Y) / TerrainConstants.TileSize); var wmoTileY = (int)((TerrainConstants.CenterPoint - worldPos.X) / TerrainConstants.TileSize); if (wmoTileX != tileX || wmoTileY != tileY) continue; var filePath = wmo.FileName; var root = WMORootParser.Process(manager, filePath); ExtractWMOM2s(wmo, root, tileModels); LoadedWMOIds.AddUnique(wmo.UniqueId); } return tileModels; }
public bool IsLegal(pos p) { switch(map[p]){ //case CellType.RoomInterior: case CellType.Pillar: case CellType.RoomFeature1: case CellType.RoomFeature2: case CellType.RoomFeature3: case CellType.InterestingLocation: foreach(pos neighbor in p.AdjacentPositionsClockwise()){ if(!map[neighbor].IsRoomType()){ return false; } } break; case CellType.RoomEdge: { int roomdir = 0; foreach(int dir in FourDirections){ pos neighbor = p.PosInDir(dir); if(BoundsCheck(neighbor) && !map[neighbor].IsRoomType()){ roomdir = dir.RotateDir(true,4); break; } } if(roomdir == 0){ return false; //no room found, error - disable this if you want tiny rooms with h/w of 2 /*char[] rotated = new char[8]; for(int i=0;i<8;++i){ rotated[i] = Map(PosInDir(r,c,RotateDir(8,true,i))); } int successive_corridors = 0; if(IsCorridor(rotated[7])){ successive_corridors++; } for(int i=0;i<8;++i){ if(IsCorridor(rotated[i])){ successive_corridors++; } else{ successive_corridors = 0; } if(successive_corridors == 2){ return false; } } int successive_room_tiles = 0; if(IsRoom(rotated[5])){ successive_room_tiles++; } if(IsRoom(rotated[6])){ successive_room_tiles++; } else{ successive_room_tiles = 0; } if(IsRoom(rotated[7])){ successive_room_tiles++; } else{ successive_room_tiles = 0; } for(int i=0;i<8;++i){ if(IsRoom(rotated[i])){ successive_room_tiles++; } else{ successive_room_tiles = 0; } if(successive_room_tiles == 5){ return true; } }*/ } else{ List<pos> rotated = p.AdjacentPositionsClockwise(roomdir); foreach(int dir in new int[]{0,1,7}){ if(!map[rotated[dir]].IsRoomType()){ return false; } } foreach(int dir in new int[]{2,6}){ if(!map[rotated[dir]].IsRoomEdgeType()){ return false; } } if((map[rotated[4]].IsWall() || (map[rotated[3]].IsWall() && map[rotated[5]].IsWall())) == false){ return false; } } break; } case CellType.RoomCorner: { int roomdir = 0; foreach(int dir in DiagonalDirections){ pos neighbor = p.PosInDir(dir); if(BoundsCheck(neighbor) && map[neighbor].IsRoomInteriorType()){ roomdir = dir; break; } } if(roomdir == 0){ return false; //no room found, error } List<pos> rotated = p.AdjacentPositionsClockwise(roomdir); foreach(int dir in new int[]{1,7}){ if(!map[rotated[dir]].IsRoomEdgeType()){ return false; } } if(AllowAllCornerConnections){ if(!map[rotated[2]].IsWall() && !map[rotated[3]].IsWall()){ return false; } if(!map[rotated[6]].IsWall() && !map[rotated[5]].IsWall()){ return false; } if(!map[rotated[4]].IsWall()){ //if the corner isn't a wall... if(!map[rotated[3]].IsWall() && !map[rotated[5]].IsWall()){ return false; } if(map[rotated[3]].IsWall() && map[rotated[5]].IsWall()){ //...reject it if there's not exactly 1 adjacent corridor return false; } } } else{ foreach(int dir in new int[]{3,4,5}){ if(!map[rotated[dir]].IsWall()){ return false; } } } break; } case CellType.RoomInteriorCorner: { List<int> wall_dirs = new List<int>(); List<int> edge_dirs = new List<int>(); foreach(int dir in DiagonalDirections){ pos neighbor = p.PosInDir(dir); if(BoundsCheck(neighbor) && map[neighbor].IsWall()){ wall_dirs.Add(dir); edge_dirs.AddUnique(dir.RotateDir(true)); edge_dirs.AddUnique(dir.RotateDir(false)); } } if(wall_dirs.Count == 0){ return false; //no room found, error } foreach(int dir in EightDirections){ if(wall_dirs.Contains(dir)){ if(!map[p.PosInDir(dir)].IsWall()){ return false; } } else{ if(edge_dirs.Contains(dir)){ if(!map[p.PosInDir(dir)].IsRoomEdgeType()){ return false; } } else{ if(!map[p.PosInDir(dir)].IsRoomType()){ return false; } } } } break; } case CellType.CorridorHorizontal: foreach(int dir in new int[]{2,8}){ pos next = p; for(int i=1;i<=MinimumSpaceBetweenCorridors;++i){ next = next.PosInDir(dir); if(BoundsCheck(next) && map[next] == CellType.CorridorHorizontal){ return false; } } } break; case CellType.CorridorVertical: foreach(int dir in new int[]{4,6}){ pos next = p; for(int i=1;i<=MinimumSpaceBetweenCorridors;++i){ next = next.PosInDir(dir); if(BoundsCheck(next) && map[next] == CellType.CorridorVertical){ return false; } } } break; case CellType.CorridorIntersection: if(p.ConsecutiveAdjacent(x => map[x].IsPassable()) >= 3){ return false; } break; case CellType.Door: { int dir_of_wall = 0; if(map[p.PosInDir(8)].IsWall()){ dir_of_wall = 8; } else{ dir_of_wall = 4; } if(!map[p.PosInDir(dir_of_wall)].IsWall() || !map[p.PosInDir(dir_of_wall.RotateDir(true,4))].IsWall() || map[p.PosInDir(dir_of_wall.RotateDir(true,2))].IsWall() || map[p.PosInDir(dir_of_wall.RotateDir(false,2))].IsWall()){ return false; //needs 2 walls on opposite sides, 2 nonwalls on opposite sides } break; } } return true; }
/// <summary> /// 转换为SQL字符串 /// </summary> /// <returns>SQL字符串</returns> public Parameters ToParameters(string dbkey = "") { Database db = Data.Pool(dbkey); StringBuilder sbSql = new StringBuilder(); IList<DbParameter> pars = new List<DbParameter>(); Parameters com = new Parameters(); foreach (SearchInfo info in conditions) { //如果选择Where为True,并且该字段为空值的话,跳过 if (info.Where && info.FieldValue.IsNull()) continue; if (info.FieldName.IndexOf("@") == -1) { if (info.Operator == Operator.Like) { sbSql.AppendFormat("{3}{0}{1}'{2}'{4}", info.FieldName, OperatorToStr(info.Operator), info.FieldValue, OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : ""), info.Type == 2 ? ")" : ""); } else if (info.Operator == Operator.In || info.Operator == Operator.Between) { sbSql.AppendFormat("{3}{0}{1}{2}", info.FieldName, OperatorToStr(info.Operator), info.FieldValue + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); } else if (info.Operator == Operator.Field) { sbSql.AppendFormat("{3}{0}{1}{2}", info.FieldName, OperatorToStr(info.Operator), info.FieldValue + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); } else if (info.Operator == Operator.Is || info.Operator == Operator.IsNot) { sbSql.AppendFormat("{3}{0}{1}{2}", info.FieldName, OperatorToStr(info.Operator), info.FieldValue + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); } else { sbSql.AppendFormat("{3}{0}{1}{2}", info.FieldName, OperatorToStr(info.Operator), ValueToStr(info.FieldValue) + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); } } else { info.FieldName = info.FieldName.Trim('@'); if (info.Operator == Operator.Like) { sbSql.AppendFormat("{3}{0}{1}{2}{4}", info.FieldName, OperatorToStr(info.Operator), db.GetParamIdentifier() + info.FieldName, OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : ""), info.Type == 2 ? ")" : ""); pars.AddUnique(db.MakeParam(db.GetParamIdentifier() + info.FieldName, info.FieldValue)); } else if (info.Operator == Operator.In || info.Operator == Operator.Between) { sbSql.AppendFormat("{3}{0}{1}({2})", info.FieldName, OperatorToStr(info.Operator), db.GetParamIdentifier() + info.FieldName + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); pars.AddUnique(db.MakeParam(db.GetParamIdentifier() + info.FieldName, info.FieldValue)); } else if (info.Operator == Operator.Field) { sbSql.AppendFormat("{3}{0}{1}{2}", info.FieldName, OperatorToStr(info.Operator), info.FieldValue + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); } else if (info.Operator == Operator.Is || info.Operator == Operator.IsNot) { sbSql.AppendFormat("{3}{0}{1}{2}", info.FieldName, OperatorToStr(info.Operator), info.FieldValue + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); } else { sbSql.AppendFormat("{3}{0}{1}{2}", info.FieldName, OperatorToStr(info.Operator), db.GetParamIdentifier() + info.FieldName + (info.Type == 2 ? ")" : ""), OperatorToStr(info.AndOr) + (info.Type == 1 ? "(" : "")); pars.AddUnique(db.MakeParam(db.GetParamIdentifier() + info.FieldName, info.FieldValue)); } } } com.CommandText = sbSql.ToString().Trim(); com.ParameterList = pars.ToArray(); sbSql.Clear(); sbSql = null; pars.Clear(); pars = null; return com; }
public bool Use(Actor user,List<Tile> line) { bool used = true; bool IDed = true; switch(type){ case ConsumableType.HEALING: user.curhp = user.maxhp; B.Add(user.Your() + " wounds are healed completely. ",user); break; case ConsumableType.REGENERATION: { if(user == player){ B.Add("Your blood tingles. "); } else{ B.Add(user.the_name + " looks energized. ",user); } user.attrs[AttrType.REGENERATING]++; int duration = 100; Q.Add(new Event(user,duration*100,AttrType.REGENERATING)); break; } case ConsumableType.STONEFORM: { B.Add(user.You("transform") + " into a being of animated stone. ",user); int duration = R.Roll(2,20) + 20; List<AttrType> attributes = new List<AttrType>{AttrType.REGENERATING,AttrType.BRUTISH_STRENGTH,AttrType.VIGOR,AttrType.SILENCE_AURA,AttrType.SHADOW_CLOAK,AttrType.CAN_DODGE,AttrType.MENTAL_IMMUNITY,AttrType.DETECTING_MONSTERS,AttrType.MYSTIC_MIND}; foreach(AttrType at in attributes){ //in the rare case where a monster drinks this potion, it can lose these natural statuses permanently. this might eventually be fixed. if(user.HasAttr(at)){ user.attrs[at] = 0; Q.KillEvents(user,at); switch(at){ case AttrType.REGENERATING: B.Add(user.You("no longer regenerate") + ". ",user); break; case AttrType.BRUTISH_STRENGTH: B.Add(user.Your() + " brutish strength fades. ",user); break; case AttrType.VIGOR: B.Add(user.Your() + " extraordinary speed fades. ",user); break; case AttrType.SILENCED: B.Add(user.You("no longer radiate") + " an aura of silence. ",user); break; case AttrType.SHADOW_CLOAK: B.Add(user.YouAre() + " no longer cloaked. ",user); break; case AttrType.MYSTIC_MIND: B.Add(user.Your() + " consciousness returns to normal. ",user); break; } } } if(user.HasAttr(AttrType.PSEUDO_VAMPIRIC)){ user.attrs[AttrType.LIGHT_SENSITIVE] = 0; user.attrs[AttrType.FLYING] = 0; user.attrs[AttrType.PSEUDO_VAMPIRIC] = 0; Q.KillEvents(user,AttrType.LIGHT_SENSITIVE); Q.KillEvents(user,AttrType.FLYING); Q.KillEvents(user,AttrType.PSEUDO_VAMPIRIC); B.Add(user.YouAre() + " no longer vampiric. ",user); } if(user.HasAttr(AttrType.ROOTS)){ foreach(Event e in Q.list){ if(e.target == user && !e.dead){ if(e.attr == AttrType.IMMOBILE && e.msg.Contains("rooted to the ground")){ e.dead = true; user.attrs[AttrType.IMMOBILE]--; B.Add(user.YouAre() + " no longer rooted to the ground. ",user); } else{ if(e.attr == AttrType.BONUS_DEFENSE && e.value == 10){ e.dead = true; //this would break if there were other timed effects that gave the same amount of defense user.attrs[AttrType.BONUS_DEFENSE] -= 10; } else{ if(e.attr == AttrType.ROOTS){ e.dead = true; user.attrs[AttrType.ROOTS]--; } } } } } } if(user.HasAttr(AttrType.BURNING)){ user.RefreshDuration(AttrType.BURNING,0); } user.attrs[AttrType.IMMUNE_BURNING]++; Q.Add(new Event(user,duration*100,AttrType.IMMUNE_BURNING)); user.attrs[AttrType.DAMAGE_RESISTANCE]++; Q.Add(new Event(user,duration*100,AttrType.DAMAGE_RESISTANCE)); user.attrs[AttrType.NONLIVING]++; Q.Add(new Event(user,duration*100,AttrType.NONLIVING)); user.RefreshDuration(AttrType.STONEFORM,duration*100,user.Your() + " rocky form reverts to flesh. ",user); if(user == player){ Help.TutorialTip(TutorialTopic.Stoneform); } break; } case ConsumableType.VAMPIRISM: { B.Add(user.You("become") + " vampiric. ",user); B.Add(user.You("rise") + " into the air. ",user); int duration = R.Roll(2,20) + 20; user.RefreshDuration(AttrType.LIGHT_SENSITIVE,duration*100); user.RefreshDuration(AttrType.FLYING,duration*100); user.attrs[AttrType.DESCENDING] = 0; user.RefreshDuration(AttrType.PSEUDO_VAMPIRIC,duration*100,user.YouAre() + " no longer vampiric. ",user); if(user == player){ Help.TutorialTip(TutorialTopic.Vampirism); } break; } case ConsumableType.BRUTISH_STRENGTH: { if(user == player){ B.Add("You feel a surge of strength. "); } else{ B.Add(user.Your() + " muscles ripple. ",user); } user.RefreshDuration(AttrType.BRUTISH_STRENGTH,(R.Roll(3,6)+16)*100,user.Your() + " incredible strength wears off. ",user); if(user == player){ Help.TutorialTip(TutorialTopic.BrutishStrength); } break; } case ConsumableType.ROOTS: { if(user.HasAttr(AttrType.ROOTS)){ foreach(Event e in Q.list){ if(e.target == user && !e.dead){ if(e.attr == AttrType.IMMOBILE && e.msg.Contains("rooted to the ground")){ e.dead = true; user.attrs[AttrType.IMMOBILE]--; } else{ if(e.attr == AttrType.BONUS_DEFENSE && e.value == 10){ e.dead = true; //this would break if there were other timed effects that gave 5 defense user.attrs[AttrType.BONUS_DEFENSE] -= 10; } else{ if(e.attr == AttrType.ROOTS){ e.dead = true; user.attrs[AttrType.ROOTS]--; } } } } } B.Add(user.Your() + " roots extend deeper into the ground. ",user); } else{ B.Add(user.You("grow") + " roots and a hard shell of bark. ",user); } int duration = R.Roll(20) + 20; user.RefreshDuration(AttrType.ROOTS,duration*100); user.attrs[AttrType.BONUS_DEFENSE] += 10; Q.Add(new Event(user,duration*100,AttrType.BONUS_DEFENSE,10)); user.attrs[AttrType.IMMOBILE]++; Q.Add(new Event(user,duration*100,AttrType.IMMOBILE,user.YouAre() + " no longer rooted to the ground. ",user)); if(user == player){ Help.TutorialTip(TutorialTopic.Roots); } if(user.HasAttr(AttrType.FLYING) && user.tile().IsTrap()){ user.tile().TriggerTrap(); } break; } case ConsumableType.HASTE: { B.Add(user.You("start") + " moving with extraordinary speed. ",user); int duration = (R.Roll(2,10) + 10) * 100; user.RefreshDuration(AttrType.CAN_DODGE,duration); //todo: dodging tip goes here user.RefreshDuration(AttrType.VIGOR,duration,user.Your() + " extraordinary speed fades. ",user); if(user == player){ Help.TutorialTip(TutorialTopic.IncreasedSpeed); } break; } case ConsumableType.SILENCE: { B.Add("A hush falls around " + user.the_name + ". ",user); user.RefreshDuration(AttrType.SILENCE_AURA,(R.Roll(2,20)+20)*100,user.You("no longer radiate") + " an aura of silence. ",user); if(user == player){ Help.TutorialTip(TutorialTopic.Silenced); } break; } case ConsumableType.CLOAKING: if(user.tile().IsLit()){ if(user == player){ B.Add("You would feel at home in the shadows. "); } else{ B.Add("A shadow moves across " + user.the_name + ". ",user); } } else{ B.Add(user.You("fade") + " away in the darkness. ",user); } user.RefreshDuration(AttrType.SHADOW_CLOAK,(R.Roll(2,20)+30)*100,user.YouAre() + " no longer cloaked. ",user); break; case ConsumableType.MYSTIC_MIND: { B.Add(user.Your() + " mind expands. ",user); int duration = R.Roll(2,20)+60; user.attrs[AttrType.ASLEEP] = 0; //user.RefreshDuration(AttrType.MAGICAL_DROWSINESS,0); user.RefreshDuration(AttrType.CONFUSED,0); user.RefreshDuration(AttrType.STUNNED,0); user.RefreshDuration(AttrType.ENRAGED,0); user.RefreshDuration(AttrType.MENTAL_IMMUNITY,duration*100); user.RefreshDuration(AttrType.DETECTING_MONSTERS,duration*100); user.RefreshDuration(AttrType.MYSTIC_MIND,duration*100,user.Your() + " consciousness returns to normal. ",user); if(user == player){ Help.TutorialTip(TutorialTopic.MysticMind); } break; } case ConsumableType.BLINKING: { List<Tile> tiles = user.TilesWithinDistance(8).Where(x => x.passable && x.actor() == null && user.ApproximateEuclideanDistanceFromX10(x) >= 45); if(tiles.Count > 0 && !user.HasAttr(AttrType.IMMOBILE)){ Tile t = tiles.Random(); B.Add(user.You("step") + " through a rip in reality. ",M.tile[user.p],t); user.AnimateStorm(2,3,4,'*',Color.DarkMagenta); user.Move(t.row,t.col); M.Draw(); user.AnimateStorm(2,3,4,'*',Color.DarkMagenta); } else{ B.Add("Nothing happens. ",user); IDed = false; } break; } case ConsumableType.PASSAGE: { if(user.HasAttr(AttrType.IMMOBILE)){ B.Add("Nothing happens. ",user); IDed = false; break; } List<int> valid_dirs = new List<int>(); foreach(int dir in U.FourDirections){ Tile t = user.TileInDirection(dir); if(t != null && t.Is(TileType.WALL,TileType.CRACKED_WALL,TileType.WAX_WALL,TileType.DOOR_C,TileType.HIDDEN_DOOR,TileType.STONE_SLAB)){ while(!t.passable){ if(t.row == 0 || t.row == Global.ROWS-1 || t.col == 0 || t.col == Global.COLS-1){ break; } t = t.TileInDirection(dir); } if(t.passable){ valid_dirs.Add(dir); } } } if(valid_dirs.Count > 0){ int dir = valid_dirs.Random(); Tile t = user.TileInDirection(dir); colorchar ch = new colorchar(Color.Cyan,'!'); switch(user.DirectionOf(t)){ case 8: case 2: ch.c = '|'; break; case 4: case 6: ch.c = '-'; break; } List<Tile> tiles = new List<Tile>(); List<colorchar> memlist = new List<colorchar>(); Screen.CursorVisible = false; Tile last_wall = null; while(!t.passable){ tiles.Add(t); memlist.Add(Screen.MapChar(t.row,t.col)); Screen.WriteMapChar(t.row,t.col,ch); Game.GLUpdate(); Thread.Sleep(35); last_wall = t; t = t.TileInDirection(dir); } Input.FlushInput(); if(t.actor() == null){ int r = user.row; int c = user.col; user.Move(t.row,t.col); Screen.WriteMapChar(r,c,M.VisibleColorChar(r,c)); Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); int idx = 0; foreach(Tile tile in tiles){ Screen.WriteMapChar(tile.row,tile.col,memlist[idx++]); Game.GLUpdate(); Thread.Sleep(35); } Input.FlushInput(); B.Add(user.You("travel") + " through the passage. ",user,t); } else{ Tile destination = null; List<Tile> adjacent = t.TilesAtDistance(1).Where(x=>x.passable && x.actor() == null && x.DistanceFrom(last_wall) == 1); if(adjacent.Count > 0){ destination = adjacent.Random(); } else{ foreach(Tile tile in M.ReachableTilesByDistance(t.row,t.col,false)){ if(tile.actor() == null){ destination = tile; break; } } } if(destination != null){ int r = user.row; int c = user.col; user.Move(destination.row,destination.col); Screen.WriteMapChar(r,c,M.VisibleColorChar(r,c)); Screen.WriteMapChar(destination.row,destination.col,M.VisibleColorChar(destination.row,destination.col)); int idx = 0; foreach(Tile tile in tiles){ Screen.WriteMapChar(tile.row,tile.col,memlist[idx++]); Game.GLUpdate(); Thread.Sleep(35); } Input.FlushInput(); B.Add(user.You("travel") + " through the passage. ",user,destination); } else{ B.Add("Something blocks " + user.Your() + " movement through the passage. ",user); } } } else{ B.Add("Nothing happens. ",user); IDed = false; } break; } case ConsumableType.TIME: if(user == player){ B.Add("Time stops for a moment. ",user); } else{ B.Add("Time warps around " + user.the_name + "! ",user); B.PrintAll(); } if(Fire.fire_event == null){ //this prevents fire from updating while time is frozen Fire.fire_event = new Event(0,EventType.FIRE); Fire.fire_event.tiebreaker = 0; Q.Add(Fire.fire_event); } Q.turn -= 200; break; case ConsumableType.KNOWLEDGE: { if(user == player){ B.Add("Knowledge fills your mind. "); Event hiddencheck = null; foreach(Event e in Q.list){ if(!e.dead && e.type == EventType.CHECK_FOR_HIDDEN){ hiddencheck = e; break; } } int max_dist = 0; List<Tile> last_tiles = new List<Tile>(); foreach(Tile t in M.ReachableTilesByDistance(user.row,user.col,true,TileType.STONE_SLAB,TileType.DOOR_C,TileType.STALAGMITE,TileType.RUBBLE,TileType.HIDDEN_DOOR)){ if(t.type != TileType.FLOOR){ t.seen = true; if(t.type != TileType.WALL){ t.revealed_by_light = true; } if(t.IsTrap() || t.Is(TileType.HIDDEN_DOOR)){ if(hiddencheck != null){ hiddencheck.area.Remove(t); } } if(t.IsTrap()){ t.name = Tile.Prototype(t.type).name; t.a_name = Tile.Prototype(t.type).a_name; t.the_name = Tile.Prototype(t.type).the_name; t.symbol = Tile.Prototype(t.type).symbol; t.color = Tile.Prototype(t.type).color; } if(t.Is(TileType.HIDDEN_DOOR)){ t.Toggle(null); } colorchar ch2 = Screen.BlankChar(); if(t.inv != null){ t.inv.revealed_by_light = true; ch2.c = t.inv.symbol; ch2.color = t.inv.color; M.last_seen[t.row,t.col] = ch2; } else{ if(t.features.Count > 0){ ch2 = t.FeatureVisual(); M.last_seen[t.row,t.col] = ch2; } else{ ch2.c = t.symbol; ch2.color = t.color; if(ch2.c == '#' && ch2.color == Color.RandomGlowingFungus){ ch2.color = Color.Gray; } M.last_seen[t.row,t.col] = ch2; } } Screen.WriteMapChar(t.row,t.col,t.symbol,Color.RandomRainbow); //Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); if(user.DistanceFrom(t) > max_dist){ max_dist = user.DistanceFrom(t); Game.GLUpdate(); Thread.Sleep(10); while(last_tiles.Count > 0){ Tile t2 = last_tiles.RemoveRandom(); Screen.WriteMapChar(t2.row,t2.col,M.last_seen[t2.row,t2.col]); //Screen.WriteMapChar(t2.row,t2.col,M.VisibleColorChar(t2.row,t2.col)); } } last_tiles.Add(t); } } if(user.inv.Count > 0){ foreach(Item i in user.inv){ identified[i.type] = true; if(i.NameOfItemType() == "wand"){ i.other_data = -1; } } } } else{ B.Add(user.the_name + " looks more knowledgeable. ",user); } break; } case ConsumableType.SUNLIGHT: if(M.wiz_lite == false){ B.Add("The air itself seems to shine. "); M.wiz_lite = true; M.wiz_dark = false; Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } else{ B.Add("The air grows even brighter for a moment. "); Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } break; case ConsumableType.DARKNESS: if(M.wiz_dark == false){ B.Add("The air itself grows dark. "); if(player.light_radius > 0){ B.Add("Your light is extinguished! "); } M.wiz_dark = true; M.wiz_lite = false; Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } else{ B.Add("The air grows even darker for a moment. "); Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } break; case ConsumableType.RENEWAL: { B.Add("A glow envelops " + user.the_name + ". ",user); //B.Add("A glow envelops " + user.Your() + " equipment. ",user); bool repaired = false; foreach(EquipmentStatus eqstatus in Enum.GetValues(typeof(EquipmentStatus))){ foreach(Weapon w in user.weapons){ if(w.status[eqstatus]){ repaired = true; w.status[eqstatus] = false; } } foreach(Armor a in user.armors){ if(a.status[eqstatus]){ repaired = true; a.status[eqstatus] = false; } } } if(repaired){ B.Add(user.Your() + " equipment looks as good as new! ",user); } if(user.HasAttr(AttrType.SLIMED)){ B.Add(user.YouAre() + " no longer covered in slime. ",user); user.attrs[AttrType.SLIMED] = 0; } if(user.HasAttr(AttrType.OIL_COVERED)){ B.Add(user.YouAre() + " no longer covered in oil. ",user); user.attrs[AttrType.OIL_COVERED] = 0; } int recharged = 0; foreach(Item i in user.inv){ if(i.NameOfItemType() == "wand"){ i.charges++; recharged++; } } if(recharged > 0){ if(recharged == 1){ B.Add("The glow charges " + user.Your() + " wand. ",user); } else{ B.Add("The glow charges " + user.Your() + " wands. ",user); } } break; } case ConsumableType.CALLING: { bool found = false; if(user == player){ for(int dist = 1;dist < Math.Max(Global.ROWS,Global.COLS);++dist){ List<Tile> tiles = user.TilesAtDistance(dist).Where(x=>x.actor() != null && !x.actor().HasAttr(AttrType.IMMOBILE)); if(tiles.Count > 0){ Actor a = tiles.Random().actor(); Tile t2 = user.TileInDirection(user.DirectionOf(a)); if(t2.passable && t2.actor() == null){ B.Add("The scroll calls " + a.a_name + " to you. "); a.Move(t2.row,t2.col); found = true; break; } foreach(Tile t in M.ReachableTilesByDistance(user.row,user.col,false)){ if(t.actor() == null){ B.Add("The scroll calls " + a.a_name + " to you. "); a.Move(t.row,t.col); found = true; break; } } if(found){ break; } } } } else{ if(!player.HasAttr(AttrType.IMMOBILE) && user.DistanceFrom(player) > 1){ Tile t2 = user.TileInDirection(user.DirectionOf(player)); if(t2.passable && t2.actor() == null){ B.Add("The scroll calls you to " + user.TheName(true) + ". "); player.Move(t2.row,t2.col); found = true; } if(!found){ foreach(Tile t in M.ReachableTilesByDistance(user.row,user.col,false)){ if(t.actor() == null){ B.Add("The scroll calls you to " + user.TheName(true) + ". "); player.Move(t.row,t.col); found = true; break; } } } } } if(!found){ B.Add("Nothing happens. ",user); IDed = false; } break; } case ConsumableType.TRAP_CLEARING: { List<Tile> traps = new List<Tile>(); { List<Tile>[] traparray = new List<Tile>[5]; for(int i=0;i<5;++i){ traparray[i] = new List<Tile>(); } for(int i=0;i<=12;++i){ foreach(Tile t in user.TilesAtDistance(i)){ //all this ensures that the traps go off in the best order switch(t.type){ case TileType.ALARM_TRAP: case TileType.TELEPORT_TRAP: case TileType.ICE_TRAP: case TileType.BLINDING_TRAP: case TileType.SHOCK_TRAP: case TileType.FIRE_TRAP: case TileType.SCALDING_OIL_TRAP: traparray[0].Add(t); break; case TileType.POISON_GAS_TRAP: case TileType.GRENADE_TRAP: traparray[1].Add(t); break; case TileType.SLIDING_WALL_TRAP: case TileType.PHANTOM_TRAP: traparray[2].Add(t); break; case TileType.LIGHT_TRAP: case TileType.DARKNESS_TRAP: traparray[3].Add(t); break; case TileType.FLING_TRAP: case TileType.STONE_RAIN_TRAP: traparray[4].Add(t); break; } } } for(int i=0;i<5;++i){ foreach(Tile t in traparray[i]){ traps.Add(t); } } } if(traps.Count > 0){ B.Add("*CLICK*. "); foreach(Tile t in traps){ t.TriggerTrap(false); } } else{ B.Add("Nothing happens. ",user); IDed = false; } break; } case ConsumableType.ENCHANTMENT: { if(user == player){ EnchantmentType ench = (EnchantmentType)R.Between(0,4); while(ench == user.EquippedWeapon.enchantment){ ench = (EnchantmentType)R.Between(0,4); } B.Add("Your " + user.EquippedWeapon.NameWithEnchantment() + " glows brightly! "); user.EquippedWeapon.enchantment = ench; B.Add("Your " + user.EquippedWeapon.NameWithoutEnchantment() + " is now a " + user.EquippedWeapon.NameWithEnchantment() + "! "); } else{ B.Add("Nothing happens. ",user); IDed = false; } break; } case ConsumableType.THUNDERCLAP: { B.Add("Thunder crashes! ",user); var scr = Screen.GetCurrentMap(); List<Tile>[] printed = new List<Tile>[13]; Color leading_edge_color = Color.White; Color trail_color = Color.DarkCyan; if(Global.LINUX && !Screen.GLMode){ leading_edge_color = Color.Gray; } for(int dist=0;dist<=12;++dist){ printed[dist] = new List<Tile>(); foreach(Tile t in user.TilesAtDistance(dist)){ if(t.seen && user.HasLOE(t)){ printed[dist].Add(t); } } foreach(Tile t in printed[dist]){ colorchar cch = M.VisibleColorChar(t.row,t.col); cch.bgcolor = leading_edge_color; if(cch.color == leading_edge_color){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } if(dist > 0){ foreach(Tile t in printed[dist-1]){ colorchar cch = M.VisibleColorChar(t.row,t.col); cch.bgcolor = trail_color; if(cch.color == trail_color){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } if(dist > 4){ foreach(Tile t in printed[dist-5]){ Screen.WriteMapChar(t.row,t.col,scr[t.row,t.col]); } } } Game.GLUpdate(); Thread.Sleep(10); } List<Actor> actors = new List<Actor>(); for(int dist=0;dist<=12;++dist){ foreach(Tile t in user.TilesAtDistance(dist).Randomize()){ if(user.HasLOE(t)){ if(t.actor() != null && t.actor() != user){ actors.Add(t.actor()); } t.BreakFragileFeatures(); } } } foreach(Actor a in actors){ if(a.TakeDamage(DamageType.MAGIC,DamageClass.MAGICAL,R.Roll(4,6),user,"a scroll of thunderclap")){ a.ApplyStatus(AttrType.STUNNED,R.Between(5,10)*100); } } user.MakeNoise(12); break; } case ConsumableType.FIRE_RING: { List<pos> cells = new List<pos>(); List<Tile> valid = new List<Tile>(); foreach(Tile t in user.TilesWithinDistance(3)){ if(t.passable && user.DistanceFrom(t) > 1 && user.HasLOE(t) && user.ApproximateEuclideanDistanceFromX10(t) < 45){ valid.Add(t); cells.Add(t.p); } } if(valid.Count > 0){ if(player.CanSee(user)){ B.Add("A ring of fire surrounds " + user.the_name + ". "); } else{ B.Add("A ring of fire appears! ",user.tile()); } valid.Randomize(); foreach(Tile t in valid){ t.AddFeature(FeatureType.FIRE); } Screen.AnimateMapCells(cells,new colorchar('&',Color.RandomFire)); } else{ B.Add("Nothing happens. ",user); IDed = false; } break; } case ConsumableType.RAGE: { B.Add("A murderous red glow cascades outward. ",user); List<Tile>[] printed = new List<Tile>[13]; Color leading_edge_color = Color.Red; Color trail_color = Color.DarkRed; if(Global.LINUX && !Screen.GLMode){ leading_edge_color = Color.DarkRed; } for(int dist=0;dist<=12;++dist){ printed[dist] = new List<Tile>(); foreach(Tile t in user.TilesAtDistance(dist)){ if(t.seen && user.HasLOS(t)){ printed[dist].Add(t); } } foreach(Tile t in printed[dist]){ colorchar cch = M.VisibleColorChar(t.row,t.col); cch.bgcolor = leading_edge_color; if(cch.color == leading_edge_color){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } if(dist > 0){ foreach(Tile t in printed[dist-1]){ colorchar cch = M.VisibleColorChar(t.row,t.col); cch.bgcolor = trail_color; if(cch.color == trail_color){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } } Game.GLUpdate(); Thread.Sleep(5); } int actors_affected = 0; string name_is = ""; foreach(Actor a in M.AllActors()){ if(a != user && user.DistanceFrom(a) <= 12 && user.HasLOS(a)){ a.ApplyStatus(AttrType.ENRAGED,R.Between(10,17)*100,false,"",a.You("calm") + " down. ",a.You("resist") + "! "); actors_affected++; if(player.CanSee(a)){ name_is = a.YouAre(); } } } if(actors_affected > 0){ if(actors_affected == 1){ B.Add(name_is + " enraged! "); } else{ B.Add("Bloodlust fills the air. "); } } break; } case ConsumableType.FREEZING: { ItemUseResult orb_result = UseOrb(2,false,user,line,(t,LOE_tile,results)=>{ Screen.AnimateExplosion(t,2,new colorchar('*',Color.RandomIce)); List<Tile> targets = new List<Tile>(); foreach(Tile t2 in t.TilesWithinDistance(2)){ if(LOE_tile.HasLOE(t2)){ targets.Add(t2); } } while(targets.Count > 0){ Tile t2 = targets.RemoveRandom(); t2.ApplyEffect(DamageType.COLD); Actor ac = t2.actor(); if(ac != null){ ac.ApplyFreezing(); } } }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.FLAMES: { ItemUseResult orb_result = UseOrb(2,false,user,line,(t,LOE_tile,results)=>{ List<Tile> area = new List<Tile>(); List<pos> cells = new List<pos>(); foreach(Tile tile in t.TilesWithinDistance(2)){ if(LOE_tile.HasLOE(tile)){ if(tile.passable){ tile.AddFeature(FeatureType.FIRE); } else{ tile.ApplyEffect(DamageType.FIRE); } if(tile.Is(FeatureType.FIRE)){ area.Add(tile); } cells.Add(tile.p); } } Screen.AnimateMapCells(cells,new colorchar('&',Color.RandomFire)); }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.FOG: { ItemUseResult orb_result = UseOrb(3,false,user,line,(t,LOE_tile,results)=>{ List<Tile> area = new List<Tile>(); List<pos> cells = new List<pos>(); colorchar cch = new colorchar('*',Color.Gray); for(int i=0;i<=3;++i){ foreach(Tile tile in t.TilesAtDistance(i)){ if(tile.passable && LOE_tile.HasLOE(tile)){ tile.AddFeature(FeatureType.FOG); area.Add(tile); cells.Add(tile.p); if(tile.seen){ M.last_seen[tile.row,tile.col] = cch; } } } Screen.AnimateMapCells(cells,cch,40); } Q.RemoveTilesFromEventAreas(area,EventType.REMOVE_GAS); Event.RemoveGas(area,800,FeatureType.FOG,25); //Q.Add(new Event(area,600,EventType.FOG,25)); }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.DETONATION: { ItemUseResult orb_result = UseOrb(3,false,user,line,(t,LOE_tile,results)=>{ LOE_tile.ApplyExplosion(3,user,"an orb of detonation"); }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.BREACHING: { ItemUseResult orb_result = UseOrb(5,false,user,line,(t,LOE_tile,results)=>{ int max_dist = -1; foreach(Tile t2 in M.TilesByDistance(t.row,t.col,false,true)){ if(t.DistanceFrom(t2) > 5){ break; } if(t2.Is(TileType.WALL,TileType.WAX_WALL,TileType.STALAGMITE,TileType.CRACKED_WALL,TileType.DOOR_C)){ Screen.WriteMapChar(t2.row,t2.col,t2.symbol,Color.RandomBreached); if(t.DistanceFrom(t2) > max_dist){ max_dist = t.DistanceFrom(t2); Game.GLUpdate(); //todo: stalagmites - if I add them to caves, they should no longer always vanish. check for an event, maybe? Thread.Sleep(50); } } } List<Tile> area = new List<Tile>(); foreach(Tile tile in t.TilesWithinDistance(5)){ if(tile.Is(TileType.WALL,TileType.WAX_WALL,TileType.STALAGMITE,TileType.CRACKED_WALL,TileType.DOOR_C) && tile.p.BoundsCheck(M.tile,false)){ TileType prev_type = tile.type; if(tile.Is(TileType.STALAGMITE)){ tile.Toggle(null,TileType.FLOOR); } else{ tile.Toggle(null,TileType.BREACHED_WALL); tile.toggles_into = prev_type; area.Add(tile); } foreach(Tile neighbor in tile.TilesWithinDistance(1)){ neighbor.solid_rock = false; } } } if(area.Count > 0){ Q.Add(new Event(t,area,500,EventType.BREACH)); } }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.SHIELDING: { ItemUseResult orb_result = UseOrb(1,true,user,line,(t,LOE_tile,results)=>{ List<Tile> area = new List<Tile>(); List<pos> cells = new List<pos>(); List<colorchar> symbols = new List<colorchar>(); foreach(Tile tile in t.TilesWithinDistance(1)){ if(tile.passable && LOE_tile.HasLOE(tile)){ colorchar cch = tile.visual; if(tile.actor() != null){ if(!tile.actor().HasAttr(AttrType.SHIELDED)){ tile.actor().attrs[AttrType.SHIELDED] = 1; B.Add(tile.actor().YouAre() + " shielded. ",tile.actor()); } if(player.CanSee(tile.actor())){ cch = tile.actor().visual; } } cch.bgcolor = Color.Blue; if(Global.LINUX && !Screen.GLMode){ cch.bgcolor = Color.DarkBlue; } if(cch.color == cch.bgcolor){ cch.color = Color.Black; } if(cch.c == '.'){ cch.c = '+'; } symbols.Add(cch); cells.Add(tile.p); area.Add(tile); } } Screen.AnimateMapCells(cells,symbols,150); foreach(Tile tile in area){ if(player.CanSee(tile)){ B.Add("A zone of protection is created. "); break; } } Q.Add(new Event(area,100,EventType.SHIELDING,R.Roll(2,6)+6)); }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.TELEPORTAL: { ItemUseResult orb_result = UseOrb(0,false,user,line,(t,LOE_tile,results)=>{ LOE_tile.AddFeature(FeatureType.TELEPORTAL); if(LOE_tile.Is(FeatureType.TELEPORTAL)){ Q.Add(new Event(LOE_tile,0,EventType.TELEPORTAL,100)); } }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.PAIN: { ItemUseResult orb_result = UseOrb(5,false,user,line,(t,LOE_tile,results)=>{ List<pos> cells = new List<pos>(); List<colorchar> symbols = new List<colorchar>(); foreach(Tile tile in t.TilesWithinDistance(5)){ if(LOE_tile.HasLOE(tile)){ Actor a = tile.actor(); if(a != null){ if(a.TakeDamage(DamageType.MAGIC,DamageClass.MAGICAL,R.Roll(2,6),user,"an orb of pain")){ a.ApplyStatus(AttrType.VULNERABLE,(R.Roll(2,6)+6)*100); if(a == player){ Help.TutorialTip(TutorialTopic.Vulnerable); } } } symbols.Add(new colorchar('*',Color.RandomDoom)); /*if(tile.DistanceFrom(t) % 2 == 0){ symbols.Add(new colorchar('*',Color.DarkMagenta)); } else{ symbols.Add(new colorchar('*',Color.DarkRed)); }*/ cells.Add(tile.p); } } player.AnimateVisibleMapCells(cells,symbols,80); }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.CONFUSION: { ItemUseResult orb_result = UseOrb(2,false,user,line,(t,LOE_tile,results)=>{ List<Tile> area = new List<Tile>(); List<pos> cells = new List<pos>(); colorchar cch = new colorchar('*',Color.RandomConfusion); for(int i=0;i<=2;++i){ foreach(Tile tile in t.TilesAtDistance(i)){ if(tile.passable && LOE_tile.HasLOE(tile)){ tile.AddFeature(FeatureType.CONFUSION_GAS); area.Add(tile); cells.Add(tile.p); if(tile.seen){ M.last_seen[tile.row,tile.col] = cch; } } } Screen.AnimateMapCells(cells,cch,40); } Q.RemoveTilesFromEventAreas(area,EventType.REMOVE_GAS); Event.RemoveGas(area,R.Between(7,9)*100,FeatureType.CONFUSION_GAS,20); }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.BLADES: { ItemUseResult orb_result = UseOrb(1,false,user,line,(t,LOE_tile,results)=>{ List<Tile> targets = new List<Tile>(); foreach(Tile t2 in t.TilesWithinDistance(1)){ if(t2.passable && t2.actor() == null && LOE_tile.HasLOE(t2)){ targets.Add(t2); } } targets.Randomize(); foreach(Tile t2 in targets){ Actor a = Actor.Create(ActorType.BLADE,t2.row,t2.col); if(a != null){ a.speed = 50; } } }); used = orb_result.used; IDed = orb_result.IDed; break; } case ConsumableType.DUST_STORM: { ItemUseResult wand_result = UseWand(true,false,user,line,(LOE_tile,targeting,results)=>{ List<Tile> area = new List<Tile>(); List<pos> cells = new List<pos>(); foreach(Tile neighbor in LOE_tile.TilesWithinDistance(1)){ if(neighbor.passable){ area.Add(neighbor); } } List<Tile> added = new List<Tile>(); foreach(Tile n1 in area){ foreach(int dir in U.FourDirections){ if(R.CoinFlip() && n1.TileInDirection(dir).passable){ added.Add(n1.TileInDirection(dir)); } } } foreach(Tile n1 in added){ area.AddUnique(n1); } colorchar cch = new colorchar('*',Color.TerrainDarkGray); foreach(Tile t2 in area){ t2.AddFeature(FeatureType.THICK_DUST); cells.Add(t2.p); if(t2.seen){ M.last_seen[t2.row,t2.col] = cch; } Actor a = t2.actor(); if(a != null && t2.Is(FeatureType.THICK_DUST)){ if(!a.HasAttr(AttrType.NONLIVING,AttrType.PLANTLIKE,AttrType.BLINDSIGHT)){ if(a == player){ B.Add("Thick dust fills the air! "); } a.ApplyStatus(AttrType.BLIND,R.Between(1,3)*100); } } } Screen.AnimateMapCells(cells,cch,80); Q.RemoveTilesFromEventAreas(area,EventType.REMOVE_GAS); Event.RemoveGas(area,R.Between(20,25)*100,FeatureType.THICK_DUST,8); }); used = wand_result.used; IDed = wand_result.IDed; break; } case ConsumableType.FLESH_TO_FIRE: { ItemUseResult wand_result = UseWand(true,false,user,line,(LOE_tile,targeting,results)=>{ Actor a = targeting.targeted.actor(); if(a != null){ B.Add("Jets of flame erupt from " + a.TheName(true) + ". ",a,targeting.targeted); Screen.AnimateMapCell(a.row,a.col,new colorchar('&',Color.RandomFire)); int dmg = (a.curhp+1)/2; if(a.TakeDamage(DamageType.MAGIC,DamageClass.MAGICAL,dmg,user,"a wand of flesh to fire")){ a.ApplyBurning(); } } else{ if(targeting.targeted.Is(FeatureType.TROLL_CORPSE)){ B.Add("Jets of flame erupt from the troll corpse. ",a,targeting.targeted); targeting.targeted.ApplyEffect(DamageType.FIRE); if(targeting.targeted.Is(FeatureType.TROLL_CORPSE)){ //if it's still there because of thick gas, it still gets destroyed. targeting.targeted.RemoveFeature(FeatureType.TROLL_CORPSE); B.Add("The troll corpse burns to ashes! ",targeting.targeted); } } else{ if(targeting.targeted.Is(FeatureType.TROLL_BLOODWITCH_CORPSE)){ B.Add("Jets of flame erupt from the troll bloodwitch corpse. ",a,targeting.targeted); targeting.targeted.ApplyEffect(DamageType.FIRE); if(targeting.targeted.Is(FeatureType.TROLL_BLOODWITCH_CORPSE)){ //if it's still there because of thick gas, it still gets destroyed. targeting.targeted.RemoveFeature(FeatureType.TROLL_BLOODWITCH_CORPSE); B.Add("The troll bloodwitch corpse burns to ashes! ",targeting.targeted); } } else{ B.Add("Nothing happens. ",user); results.IDed = false; } } } }); used = wand_result.used; IDed = wand_result.IDed; break; } case ConsumableType.INVISIBILITY: { ItemUseResult wand_result = UseWand(false,false,user,line,(LOE_tile,targeting,results)=>{ Actor a = targeting.targeted.actor(); if(a != null){ B.Add(a.You("vanish",true) + " from view. ",a); if(a.light_radius > 0 && !M.wiz_dark && !M.wiz_lite){ B.Add(a.Your() + " light still reveals " + a.Your() + " location. ",a); } a.RefreshDuration(AttrType.INVISIBLE,(R.Between(2,20)+30)*100,a.YouAre() + " no longer invisible. ",a); } else{ B.Add("Nothing happens. ",user); results.IDed = false; } }); used = wand_result.used; IDed = wand_result.IDed; break; } case ConsumableType.REACH: { ItemUseResult wand_result = UseWand(true,false,user,line,(LOE_tile,targeting,results)=>{ Actor a = targeting.targeted.actor(); if(a != null && a != user){ user.Attack(0,a,true); } else{ B.Add("Nothing happens. ",user); results.IDed = false; } }); used = wand_result.used; IDed = wand_result.IDed; break; } case ConsumableType.SLUMBER: { ItemUseResult wand_result = UseWand(true,false,user,line,(LOE_tile,targeting,results)=>{ Actor a = targeting.targeted.actor(); if(a != null){ if(a.HasAttr(AttrType.MENTAL_IMMUNITY)){ if(a.HasAttr(AttrType.NONLIVING,AttrType.PLANTLIKE)){ B.Add(a.You("resist") + " becoming dormant. ",a); } else{ B.Add(a.You("resist") + " falling asleep. ",a); } } else{ if(a.ResistedBySpirit()){ if(player.HasLOS(a)){ if(a.HasAttr(AttrType.NONLIVING,AttrType.PLANTLIKE)){ B.Add(a.You("resist") + " becoming dormant. ",a); } else{ B.Add(a.You("almost fall") + " asleep. ",a); } } } else{ if(player.HasLOS(a)){ if(a.HasAttr(AttrType.NONLIVING,AttrType.PLANTLIKE)){ B.Add(a.You("become") + " dormant. ",a); } else{ B.Add(a.You("fall") + " asleep. ",a); } } a.attrs[AttrType.ASLEEP] = 6 + R.Roll(4,6); } } } else{ B.Add("Nothing happens. ",user); results.IDed = false; } }); used = wand_result.used; IDed = wand_result.IDed; break; } case ConsumableType.TELEKINESIS: { ItemUseResult wand_result = UseWand(true,false,user,line,(LOE_tile,targeting,results)=>{ if(!SharedEffect.Telekinesis(false,user,targeting.targeted)){ results.used = false; } }); used = wand_result.used; IDed = wand_result.IDed; break; } case ConsumableType.WEBS: { ItemUseResult wand_result = UseWand(true,true,user,line,(LOE_tile,targeting,results)=>{ if(targeting.targeted == user.tile()){ B.Add("Nothing happens. ",user); results.IDed = false; } else{ Screen.CursorVisible = false; foreach(Tile t in targeting.line_to_targeted){ if(t.passable && t != user.tile()){ t.AddFeature(FeatureType.WEB); if(t.seen){ Screen.WriteMapChar(t.row,t.col,';',Color.White); Game.GLUpdate(); Thread.Sleep(15); } } } M.Draw(); } }); used = wand_result.used; IDed = wand_result.IDed; break; } case ConsumableType.BLAST_FUNGUS: { if(line == null){ line = user.GetTargetTile(12,0,false,true); } if(line != null){ revealed_by_light = true; ignored = true; Tile t = line.LastBeforeSolidTile(); Actor first = user.FirstActorInLine(line); B.Add(user.You("fling") + " " + TheName() + ". "); if(first != null && first != user){ t = first.tile(); B.Add("It hits " + first.the_name + ". ",first); } line = line.ToFirstSolidTileOrActor(); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } int idx = 0; foreach(Tile tile2 in line){ if(tile2.seen){ ++idx; } else{ line = line.To(tile2); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } break; } } if(line.Count > 0){ user.AnimateProjectile(line,symbol,color); } t.GetItem(this); //inv.Remove(i); t.MakeNoise(2); if(first != null && first != user){ first.player_visibility_duration = -1; first.attrs[AttrType.PLAYER_NOTICED]++; } else{ if(t.IsTrap()){ t.TriggerTrap(); } } } else{ used = false; } break; } case ConsumableType.BANDAGES: if(!user.HasAttr(AttrType.BANDAGED)){ user.attrs[AttrType.BANDAGED] = 20; //user.recover_time = Q.turn + 100; B.Add(user.You("apply",false,true) + " a bandage. ",user); } else{ B.Add(user.the_name + " can't apply another bandage yet. ",user); used = false; } break; case ConsumableType.FLINT_AND_STEEL: { int dir = -1; if(user == player){ dir = user.GetDirection("Which direction? ",false,true); } else{ dir = user.DirectionOf(player); } if(dir != -1){ Tile t = user.TileInDirection(dir); B.Add(user.You("use") + " your flint & steel. ",user); if(t.actor() != null && t.actor().HasAttr(AttrType.OIL_COVERED) && !t.Is(FeatureType.POISON_GAS,FeatureType.THICK_DUST)){ t.actor().ApplyBurning(); } if(!t.Is(TileType.WAX_WALL)){ t.ApplyEffect(DamageType.FIRE); } } else{ used = false; } break; } default: used = false; break; } if(used){ if(IDed){ bool seen = true; //i'll try letting orbs always be IDed. keep an eye on this. /*bool seen = (user == player); if(user != player){ if(player.CanSee(line[0])){ //fix this line - or at least check for null/empty seen = true; } if(user != null && player.CanSee(user)){ //heck, I could even check to see whose turn it is, if I really wanted to be hacky. seen = true; } }*/ if(!identified[type] && seen){ identified[type] = true; B.Add("(It was " + SingularName(true) + "!) "); } } else{ if(!unIDed_name[type].Contains("{tried}")){ unIDed_name[type] = unIDed_name[type] + " {tried}"; } } if(quantity > 1){ --quantity; } else{ if(type == ConsumableType.BANDAGES){ --other_data; if(user != null && other_data == 0){ B.Add(user.You("use") + " your last bandage. ",user); user.inv.Remove(this); } } else{ if(type == ConsumableType.FLINT_AND_STEEL){ if(R.OneIn(3)){ --other_data; if(user != null){ if(other_data == 2){ B.Add("Your flint & steel shows signs of wear. ",user); } if(other_data == 1){ B.Add("Your flint & steel is almost depleted. ",user); } if(other_data == 0){ B.Add("Your flint & steel is used up. ",user); user.inv.Remove(this); } } } } else{ if(NameOfItemType() == "wand"){ if(charges > 0){ --charges; if(other_data >= 0){ ++other_data; } } else{ other_data = -1; } } else{ if(user != null){ user.inv.Remove(this); } } } } } CheckForMimic(); } return used; }
IEntity[] GetSetMethods(IEntity[] entities) { List setMethods = new List(); for (int i=0; i<entities.Length; ++i) { IProperty property = entities[i] as IProperty; if (null != property) { IMethod setter = property.GetSetMethod(); if (null != setter) { setMethods.AddUnique(setter); } } } return ToEntityArray(setMethods); }
public virtual bool Resolve(List targetList, string name, EntityType flags) { bool found = false; foreach (IEntity member in GetMembers()) { if (!NameResolutionService.IsFlagSet(flags, member.EntityType)) continue; if (member.Name == name) { targetList.AddUnique(member); found = true; } } if (IsInterface) { if (_typeSystemServices.ObjectType.Resolve(targetList, name, flags)) { found = true; } foreach (IType baseInterface in GetInterfaces()) { found |= baseInterface.Resolve(targetList, name, flags); } } else { if (!found || TypeSystemServices.ContainsMethodsOnly(targetList)) { IType baseType = BaseType; if (null != baseType) { found |= baseType.Resolve(targetList, name, flags); } } } return found; }
protected bool ResolveMember(List targetList, string name, EntityType flags) { bool found = false; // Try to resolve name as a member foreach (IEntity entity in GetMembers()) { if (entity.Name == name && NameResolutionService.IsFlagSet(flags, entity.EntityType)) { targetList.AddUnique(entity); found = true; } } return found; }
public static bool Telekinesis(bool cast,Actor user,Tile t) { bool wand = !cast; if(t == null){ return false; } if(t != null){ if(wand && user == player && !Item.identified[ConsumableType.TELEKINESIS]){ Item.identified[ConsumableType.TELEKINESIS] = true; B.Add("(It was a wand of telekinesis!) "); B.PrintAll(); } List<Tile> ai_line = null; if(user != player && t == player.tile()){ var fires = user.TilesWithinDistance(12).Where(x=>x.passable && x.actor() == null && x.Is(FeatureType.FIRE) && user.CanSee(x) && player.HasBresenhamLineWithCondition(x,false,y=>y.passable && y.actor() == null)); if(fires.Count > 0){ ai_line = player.GetBestExtendedLineOfEffect(fires.Random()); } else{ if(wand){ ai_line = player.GetBestExtendedLineOfEffect(user); } else{ ai_line = player.GetBestExtendedLineOfEffect(player.TileInDirection(Global.RandomDirection())); } } } Actor a = t.actor(); if(a == null && t.inv == null && !t.Is(FeatureType.GRENADE) && t.Is(FeatureType.TROLL_CORPSE,FeatureType.TROLL_BLOODWITCH_CORPSE)){ ActorType troll_type = t.Is(FeatureType.TROLL_CORPSE)? ActorType.TROLL : ActorType.TROLL_BLOODWITCH; FeatureType troll_corpse = t.Is(FeatureType.TROLL_CORPSE)? FeatureType.TROLL_CORPSE : FeatureType.TROLL_BLOODWITCH_CORPSE; Event troll_event = Q.FindTargetedEvent(t,EventType.REGENERATING_FROM_DEATH); troll_event.dead = true; Actor troll = Actor.Create(troll_type,t.row,t.col); foreach(Event e in Q.list){ if(e.target == troll && e.type == EventType.MOVE){ e.tiebreaker = troll_event.tiebreaker; e.dead = true; break; } } Actor.tiebreakers[troll_event.tiebreaker] = troll; troll.symbol = '%'; troll.attrs[AttrType.CORPSE] = 1; troll.SetName(troll.name + "'s corpse"); troll.curhp = troll_event.value; troll.attrs[AttrType.PERMANENT_DAMAGE] = troll_event.secondary_value; troll.attrs[AttrType.NO_ITEM]++; t.features.Remove(troll_corpse); a = troll; } if(a != null){ string msg = "Throw " + a.TheName(true) + " in which direction? "; if(a == player){ msg = "Throw yourself in which direction? "; } List<Tile> line = null; if(user == player){ TargetInfo info = a.GetTarget(false,12,0,false,true,false,msg); if(info != null){ line = info.extended_line; } } else{ line = ai_line; } if(line != null){ if(line.Count == 1 && line[0].actor() == user){ if(wand){ return true; } return false; } if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); if(a.type == ActorType.ALASI_BATTLEMAGE && !a.HasSpell(SpellType.TELEKINESIS)){ a.curmp += Spell.Tier(SpellType.TELEKINESIS); if(a.curmp > a.maxmp){ a.curmp = a.maxmp; } a.GainSpell(SpellType.TELEKINESIS); B.Add("Runes on " + a.Your() + " armor align themselves with the spell. ",a); } } if(a == user && a == player){ B.Add("You throw yourself forward. "); } else{ if(line.Count == 1){ B.Add(user.YouVisible("throw") + " " + a.TheName(true) + " into the ceiling. ",user,a); } else{ B.Add(user.YouVisible("throw") + " " + a.TheName(true) + ". ",user,a); } } B.DisplayNow(); user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 1; a.attrs[AttrType.TELEKINETICALLY_THROWN] = 1; a.attrs[AttrType.TURN_INTO_CORPSE]++; if(line.Count == 1){ a.TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(3,6),user,"colliding with the ceiling"); a.CollideWith(a.tile()); } else{ a.tile().KnockObjectBack(a,line,12,user); } a.attrs[AttrType.TELEKINETICALLY_THROWN] = 0; user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 0; if(a.curhp <= 0 && a.HasAttr(AttrType.REGENERATES_FROM_DEATH)){ a.attrs[AttrType.TURN_INTO_CORPSE] = 0; a.attrs[AttrType.CORPSE] = 0; a.attrs[AttrType.FROZEN] = 0; a.attrs[AttrType.INVULNERABLE] = 0; a.attrs[AttrType.SHIELDED] = 0; a.attrs[AttrType.BLOCKING] = 0; a.curhp = 1; //this is all pretty hacky - perhaps I should relocate the regenerating corpse through other means. a.TakeDamage(DamageType.NORMAL,DamageClass.NO_TYPE,500,null); } else{ a.CorpseCleanup(); } } else{ if(wand){ return true; } return false; } } else{ bool blast_fungus = false; if(t.type == TileType.BLAST_FUNGUS && !t.Is(FeatureType.GRENADE,FeatureType.WEB,FeatureType.FORASECT_EGG,FeatureType.BONES)){ blast_fungus = true; } if(t.inv != null || blast_fungus){ Item i = t.inv; string itemname = ""; if(blast_fungus){ itemname = "the blast fungus"; } else{ itemname = i.TheName(true); if(i.quantity > 1){ itemname = "the " + i.SingularName(); } } string msg = "Throw " + itemname + " in which direction? "; List<Tile> line = null; if(user == player){ TargetInfo info = t.GetTarget(false,12,0,false,true,false,msg); if(info != null){ line = info.extended_line; } } else{ line = ai_line; } if(line != null){ if(line.Count > 13){ line = line.ToCount(13); //for range 12 } if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); } if(blast_fungus){ B.Add("The blast fungus is pulled from the floor. ",t); B.Add("Its fuse ignites! ",t); t.Toggle(null); i = Item.Create(ConsumableType.BLAST_FUNGUS,t.row,t.col); if(i != null){ i.other_data = 3; i.revealed_by_light = true; Q.Add(new Event(i,100,EventType.BLAST_FUNGUS)); Screen.AnimateMapCell(t.row,t.col,new colorchar('3',Color.Red),100); } } if(line.Count == 1){ B.Add(user.YouVisible("throw") + " " + itemname + " into the ceiling. ",user,t); } else{ B.Add(user.YouVisible("throw") + " " + itemname + ". ",user,t); } B.DisplayNow(); if(i.quantity > 1){ i.quantity--; bool revealed = i.revealed_by_light; i = new Item(i,-1,-1); i.revealed_by_light = revealed; } else{ t.inv = null; Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); } bool trigger_traps = false; Tile t2 = line.LastBeforeSolidTile(); Actor first = user.FirstActorInLine(line); if(t2 == line.LastOrDefault() && first == null){ trigger_traps = true; } if(first != null){ t2 = first.tile(); } line = line.ToFirstSolidTileOrActor(); //if(line.Count > 0){ // line.RemoveAt(line.Count - 1); //} if(line.Count > 0){ line.RemoveAt(line.Count - 1); } { Tile first_unseen = null; foreach(Tile tile2 in line){ if(!tile2.seen){ first_unseen = tile2; break; } } if(first_unseen != null){ line = line.To(first_unseen); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } } } if(line.Count > 0){ //or > 1 ? user.AnimateProjectile(line,i.symbol,i.color); } if(first == user){ B.Add(user.You("catch",true) + " it! ",user); if(user.inv.Count < Global.MAX_INVENTORY_SIZE){ user.GetItem(i); } else{ B.Add("Your pack is too full to fit anything else. "); i.ignored = true; user.tile().GetItem(i); } } else{ if(first != null){ B.Add("It hits " + first.the_name + ". ",first); } if(i.IsBreakable()){ if(i.quantity > 1){ B.Add(i.TheName(true) + " break! ",t2); } else{ B.Add(i.TheName(true) + " breaks! ",t2); } if(i.NameOfItemType() == "orb"){ i.Use(null,new List<Tile>{t2}); } else{ i.CheckForMimic(); } } else{ t2.GetItem(i); } t2.MakeNoise(2); } if(first != null && first != user && first != player){ first.player_visibility_duration = -1; first.attrs[AttrType.PLAYER_NOTICED]++; } else{ if(trigger_traps && t2.IsTrap()){ t2.TriggerTrap(); } } } else{ if(wand){ return true; } return false; } } else{ if(!t.Is(FeatureType.GRENADE) && (t.Is(TileType.DOOR_C,TileType.DOOR_O,TileType.POISON_BULB) || t.Is(FeatureType.WEB,FeatureType.FORASECT_EGG,FeatureType.BONES))){ if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); } if(t.Is(TileType.DOOR_C)){ B.Add("The door slams open. ",t); t.Toggle(null); } else{ if(t.Is(TileType.DOOR_O)){ B.Add("The door slams open. ",t); t.Toggle(null); } } if(t.Is(TileType.POISON_BULB)){ t.Bump(0); } if(t.Is(FeatureType.WEB)){ B.Add("The web is destroyed. ",t); t.RemoveFeature(FeatureType.WEB); } if(t.Is(FeatureType.FORASECT_EGG)){ B.Add("The egg is destroyed. ",t); t.RemoveFeature(FeatureType.FORASECT_EGG); //todo: forasect pathing? } if(t.Is(FeatureType.BONES)){ B.Add("The bones are scattered. ",t); t.RemoveFeature(FeatureType.BONES); } } else{ bool grenade = t.Is(FeatureType.GRENADE); bool barrel = t.Is(TileType.BARREL); bool flaming_barrel = barrel && t.IsBurning(); bool torch = t.Is(TileType.STANDING_TORCH); string feature_name = ""; int impact_damage_dice = 3; colorchar vis = new colorchar(t.symbol,t.color); switch(t.type){ case TileType.CRACKED_WALL: feature_name = "cracked wall"; break; case TileType.RUBBLE: feature_name = "pile of rubble"; break; case TileType.STATUE: feature_name = "statue"; break; } if(grenade){ impact_damage_dice = 0; feature_name = "grenade"; vis.c = ','; vis.color = Color.Red; } if(flaming_barrel){ feature_name = "flaming barrel of oil"; } if(barrel){ feature_name = "barrel"; } if(torch){ feature_name = "torch"; } if(feature_name == ""){ if(wand){ if(user == player){ B.Add("The wand grabs at empty space. ",t); } return true; } return false; } string msg = "Throw the " + feature_name + " in which direction? "; bool passable_hack = !t.passable; if(passable_hack){ t.passable = true; } List<Tile> line = null; if(user == player){ TargetInfo info = t.GetTarget(false,12,0,false,true,false,msg); if(info != null){ line = info.extended_line; } } else{ line = ai_line; } if(passable_hack){ t.passable = false; } if(line != null){ if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); } if(line.Count == 1){ B.Add(user.YouVisible("throw") + " the " + feature_name + " into the ceiling. ",user,t); } else{ B.Add(user.YouVisible("throw") + " the " + feature_name + ". ",user,t); } B.DisplayNow(); user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 1; switch(t.type){ case TileType.CRACKED_WALL: case TileType.RUBBLE: case TileType.STATUE: case TileType.BARREL: case TileType.STANDING_TORCH: if(flaming_barrel){ t.RemoveFeature(FeatureType.FIRE); } t.Toggle(null,TileType.FLOOR); foreach(Tile neighbor in t.TilesAtDistance(1)){ neighbor.solid_rock = false; } break; } if(grenade){ t.RemoveFeature(FeatureType.GRENADE); Event e = Q.FindTargetedEvent(t,EventType.GRENADE); if(e != null){ e.dead = true; } } Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); colorchar[,] mem = Screen.GetCurrentMap(); int current_row = t.row; int current_col = t.col; // int knockback_strength = 12; if(line.Count == 1){ knockback_strength = 0; } int i=0; while(true){ Tile t2 = line[i]; if(t2 == t){ break; } ++i; } line.RemoveRange(0,i+1); while(knockback_strength > 0){ //if the knockback strength is greater than 1, you're passing *over* at least one tile. Tile t2 = line[0]; line.RemoveAt(0); if(!t2.passable){ if(t2.Is(TileType.CRACKED_WALL,TileType.DOOR_C,TileType.HIDDEN_DOOR) && impact_damage_dice > 0){ string tilename = t2.TheName(true); if(t2.type == TileType.HIDDEN_DOOR){ tilename = "a hidden door"; t2.Toggle(null); } B.Add("The " + feature_name + " flies into " + tilename + ". ",t2); t2.Toggle(null); Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); } else{ B.Add("The " + feature_name + " flies into " + t2.TheName(true) + ". ",t2); if(impact_damage_dice > 0){ t2.Bump(M.tile[current_row,current_col].DirectionOf(t2)); } Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); } knockback_strength = 0; break; } else{ if(t2.actor() != null){ B.Add("The " + feature_name + " flies into " + t2.actor().TheName(true) + ". ",t2); if(t2.actor().type != ActorType.SPORE_POD && !t2.actor().HasAttr(AttrType.SELF_TK_NO_DAMAGE)){ t2.actor().TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(impact_damage_dice,6),user,"colliding with a " + feature_name); } knockback_strength = 0; Screen.WriteMapChar(t2.row,t2.col,vis); Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); current_row = t2.row; current_col = t2.col; break; } else{ if(t2.Is(FeatureType.WEB)){ //unless perhaps grenades should get stuck and explode in the web? t2.RemoveFeature(FeatureType.WEB); } Screen.WriteMapChar(t2.row,t2.col,vis); Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); current_row = t2.row; current_col = t2.col; Game.GLUpdate(); Thread.Sleep(20); } } //M.Draw(); knockback_strength--; } Tile current = M.tile[current_row,current_col]; if(grenade){ B.Add("The grenade explodes! ",current); current.ApplyExplosion(1,user,"an exploding grenade"); } if(barrel){ B.Add("The barrel smashes! ",current); List<Tile> cone = current.TilesWithinDistance(1).Where(x=>x.passable); List<Tile> added = new List<Tile>(); foreach(Tile t3 in cone){ foreach(int dir in U.FourDirections){ if(R.CoinFlip() && t3.TileInDirection(dir).passable){ added.AddUnique(t3.TileInDirection(dir)); } } } cone.AddRange(added); foreach(Tile t3 in cone){ t3.AddFeature(FeatureType.OIL); if(t3.actor() != null && !t3.actor().HasAttr(AttrType.OIL_COVERED,AttrType.SLIMED)){ if(t3.actor().IsBurning()){ t3.actor().ApplyBurning(); } else{ t3.actor().attrs[AttrType.OIL_COVERED] = 1; B.Add(t3.actor().YouAre() + " covered in oil. ",t3.actor()); if(t3.actor() == player){ Help.TutorialTip(TutorialTopic.Oiled); } } } } if(flaming_barrel){ current.ApplyEffect(DamageType.FIRE); } } if(torch){ current.AddFeature(FeatureType.FIRE); } user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 0; } else{ if(wand){ return true; } return false; } } } } } else{ return false; } return true; }
public static void GetModTypes() { _ModTypes = new List<Type>(); List<Assembly> asms = new List<Assembly>(); asms.AddRange(AssemblyLoader.loadedAssemblies.Select(la => la.assembly)); asms.AddUnique(typeof(PQSMod_VertexSimplexHeightAbsolute).Assembly); asms.AddUnique(typeof(PQSLandControl).Assembly); foreach (Type t in asms.SelectMany(a => a.GetTypes())) { _ModTypes.Add(t); } }
private static TileModels ExtractWDTM2s(IList<MapObjectDefinition> wmos) { var LoadedWMOIds = new List<uint>(); var tileModels = new TileModels { Models = new List<TileModel>() }; for (var i = 0; i < wmos.Count; i++) { var wmo = wmos[i]; if (LoadedWMOIds.Contains(wmo.UniqueId)) continue; var filePath = wmo.FileName; var root = WMORootParser.Process(manager, filePath); if (root == null) { Console.WriteLine("Invalid WMORoot returned."); return null; } LoadedWMOIds.AddUnique(wmo.UniqueId); if (root.DoodadDefinitions == null) { Console.WriteLine("No models defined in Root."); return null; } ExtractWMOM2s(wmo, root, tileModels); } return tileModels; }
static bool BuildCodeXml(string EngineDir, string TargetInfoPath, string DoxygenPath, string XmlDir, string ArchivePath, List<string> Filters, BuildActions Actions) { if ((Actions & BuildActions.Clean) != 0) { Console.WriteLine("Cleaning '{0}'", XmlDir); Utility.SafeDeleteDirectoryContents(XmlDir, true); } if ((Actions & BuildActions.Build) != 0) { Console.WriteLine("Building XML..."); Utility.SafeCreateDirectory(XmlDir); // Read the target that we're building BuildTarget Target = new BuildTarget(Path.Combine(EngineDir, "Source"), TargetInfoPath); // Create an invariant list of exclude directories string[] InvariantExcludeDirectories = ExcludeSourceDirectories.Select(x => x.ToLowerInvariant()).ToArray(); // Get the list of folders to filter against List<string> FolderFilters = new List<string>(); if (Filters != null) { foreach (string Filter in Filters) { int Idx = Filter.IndexOf('/'); if (Idx != -1) { FolderFilters.Add("\\" + Filter.Substring(0, Idx) + "\\"); } } } // Flatten the target into a list of modules List<string> InputModules = new List<string>(); foreach (string DirectoryName in Target.DirectoryNames) { for (DirectoryInfo ModuleDirectory = new DirectoryInfo(DirectoryName); ModuleDirectory.Parent != null; ModuleDirectory = ModuleDirectory.Parent) { IEnumerator<FileInfo> ModuleFile = ModuleDirectory.EnumerateFiles("*.build.cs").GetEnumerator(); if (ModuleFile.MoveNext() && (FolderFilters.Count == 0 || FolderFilters.Any(x => ModuleFile.Current.FullName.Contains(x)))) { InputModules.AddUnique(ModuleFile.Current.FullName); break; } } } // Just use all the input modules if (!bIndexOnly) { // Set our error mode so as to not bring up the WER dialog if Doxygen crashes (which it often does) SetErrorMode(0x0007); // Create the output directory Utility.SafeCreateDirectory(XmlDir); // Build all the modules Console.WriteLine("Parsing source..."); // Build the list of definitions List<string> Definitions = new List<string>(); foreach (string Definition in Target.Definitions) { if (!Definition.StartsWith("ORIGINAL_FILE_NAME=")) { Definitions.Add(Definition.Replace("DLLIMPORT", "").Replace("DLLEXPORT", "")); } } // Build a list of input paths List<string> InputPaths = new List<string>(); foreach (string InputModule in InputModules) { foreach (string DirectoryName in Directory.EnumerateDirectories(Path.GetDirectoryName(InputModule), "*", SearchOption.AllDirectories)) { // Find the relative path from the engine directory string NormalizedDirectoryName = DirectoryName; if (NormalizedDirectoryName.StartsWith(EngineDir)) { NormalizedDirectoryName = NormalizedDirectoryName.Substring(EngineDir.Length); } if (!NormalizedDirectoryName.EndsWith("\\")) { NormalizedDirectoryName += "\\"; } // Check we can include it if (!ExcludeSourceDirectories.Any(x => NormalizedDirectoryName.Contains("\\" + x + "\\"))) { if (FolderFilters.Count == 0 || FolderFilters.Any(x => NormalizedDirectoryName.Contains(x))) { InputPaths.Add(DirectoryName); } } } } // Build the configuration for this module DoxygenConfig Config = new DoxygenConfig("UE4", InputPaths.ToArray(), XmlDir); Config.Definitions.AddRange(Definitions); Config.Definitions.AddRange(DoxygenPredefinedMacros); Config.ExpandAsDefined.AddRange(DoxygenExpandedMacros); Config.IncludePaths.AddRange(Target.IncludePaths); Config.ExcludePatterns.AddRange(ExcludeSourceDirectories.Select(x => "*/" + x + "/*")); Config.ExcludePatterns.AddRange(ExcludeSourceFiles); // Run Doxygen if (!Doxygen.Run(DoxygenPath, Path.Combine(EngineDir, "Source"), Config, true)) { Console.WriteLine(" error: Doxygen crashed. Skipping."); return false; } } // Write the modules file File.WriteAllLines(Path.Combine(XmlDir, "modules.txt"), InputModules); } if ((Actions & BuildActions.Archive) != 0) { Console.WriteLine("Creating archive '{0}'", ArchivePath); Utility.CreateTgzFromDir(ArchivePath, XmlDir); } return true; }
public override bool Resolve(List targetList, string name, EntityType flags) { // Try to resolve name as a generic parameter if (NameResolutionService.IsFlagSet(flags, EntityType.Type)) { foreach (GenericParameterDeclaration gpd in Method.GenericParameters) { if (gpd.Name == name) { targetList.AddUnique(gpd.Entity); return true; } } } return base.Resolve(targetList, name, flags); }
public IType[] GetInterfaces() { List buffer = new List(_typeDefinition.BaseTypes.Count); foreach (TypeReference baseType in _typeDefinition.BaseTypes) { IType type = TypeSystemServices.GetType(baseType); if (type.IsInterface) buffer.AddUnique(type); } return (IType[])buffer.ToArray(new IType[buffer.Count]); }
public void GenerateMapWithTerraSimplification() { const int heightsPerTileSide = TerrainConstants.UnitsPerChunkSide * TerrainConstants.ChunksPerTileSide; var tileHeights = new float[heightsPerTileSide + 1, heightsPerTileSide + 1]; var tileHoles = new List<Index2>(); for (var x = 0; x < TerrainConstants.ChunksPerTileSide; x++) { for (var y = 0; y < TerrainConstants.ChunksPerTileSide; y++) { var chunk = Chunks[x, y]; var heights = chunk.Heights.GetLowResMapMatrix(); var holes = (chunk.HolesMask > 0) ? chunk.HolesMap : EmptyHolesArray; // Add the height map values, inserting them into their correct positions for (var unitRow = 0; unitRow <= TerrainConstants.UnitsPerChunkSide; unitRow++) { for (var unitCol = 0; unitCol <= TerrainConstants.UnitsPerChunkSide; unitCol++) { var tileX = x * TerrainConstants.UnitsPerChunkSide + unitRow; var tileY = y * TerrainConstants.UnitsPerChunkSide + unitCol; tileHeights[tileX, tileY] = heights[unitRow, unitCol] + chunk.MedianHeight; if (unitCol == TerrainConstants.UnitsPerChunkSide) continue; if (unitRow == TerrainConstants.UnitsPerChunkSide) continue; // Add the hole vertices to the pre-insertion 'script' if (!holes[unitRow / 2, unitCol / 2]) continue; tileHoles.AddUnique(new Index2 { Y = tileY, X = tileX }); tileHoles.AddUnique(new Index2 { Y = Math.Min(tileY + 1, heightsPerTileSide), X = tileX }); tileHoles.AddUnique(new Index2 { Y = tileY, X = Math.Min(tileX + 1, heightsPerTileSide) }); tileHoles.AddUnique(new Index2 { Y = Math.Min(tileY + 1, heightsPerTileSide), X = Math.Min(tileX + 1, heightsPerTileSide) }); } } } } var allHoleIndices = new List<Index2>(); foreach (var index in tileHoles) { var count = 0; for (var i = -1; i < 2; i++) { for (var j = -1; j < 2; j++) { if (!tileHoles.Contains(new Index2 { X = index.X + i, Y = index.Y + j })) continue; count++; } } if (count != 9) continue; allHoleIndices.AddUnique(index); } var terra = new Terra.Terra(1.0f, tileHeights); terra.ScriptedPreInsertion(tileHoles); terra.Triangulate(); // TODO: Pool huge lists & arrays List<Vector3> newVertices; List<int> indices; terra.GenerateOutput(allHoleIndices, out newVertices, out indices); // convert for (var i = 0; i < newVertices.Count; i++) { var vertex = newVertices[i]; var xPos = TerrainConstants.CenterPoint - (TileX * TerrainConstants.TileSize) - (vertex.X * TerrainConstants.UnitSize); var yPos = TerrainConstants.CenterPoint - (TileY * TerrainConstants.TileSize) - (vertex.Y * TerrainConstants.UnitSize); newVertices[i] = new Vector3(xPos, yPos, vertex.Z); } AppendWMOandM2Info(ref newVertices, ref indices); TerrainIndices = indices.ToArray(); TerrainVertices = newVertices.ToArray(); }
public void addCallback(Action <AnimState> cb) { callbacks.AddUnique(cb); }
public void GenerateOrderListForRoots(string[] rootNames) { if (projList != null) { foreach (var proj in projList) { proj.StatusChanged -= OnProjectUpdate; } } projList = new List<Project>(); List<Project> graphProjs = new List<Project>(); foreach (string rootName in rootNames) { Project proj = SolutionParser.ProjTable[rootName]; foreach (Project depProj in proj.ProjectTree) { graphProjs.AddUnique(depProj); } } while (graphProjs.Count != 0) { var downLevelList = graphProjs.FindAll(p => !p.DepProjects.Any(graphProjs.Has)).ToList(); projList.AddRange(downLevelList); graphProjs.RemoveAll(downLevelList.Has); } orderList.Items.Clear(); foreach (var proj in projList) { var item = new ListViewItem(proj.Name); item.StateImageIndex = (int)proj.Status; orderList.Items.Add(item); proj.StatusChanged += OnProjectUpdate; } UpdateLogCombo(); }
public static void addPostLoadCallback(Action func) { postLoadCallbacks.AddUnique(func); }
public void Smash(int direction_of_motion) { if(!p.BoundsCheck(M.tile,false)){ return; //no smashing the edge of the map! } switch(type){ case TileType.WALL: case TileType.WAX_WALL: case TileType.CRACKED_WALL: case TileType.DOOR_C: case TileType.RUBBLE: case TileType.STATUE: TurnToFloor(); foreach(Tile neighbor in TilesAtDistance(1)){ neighbor.solid_rock = false; } break; case TileType.STALAGMITE: Toggle(null); break; case TileType.HIDDEN_DOOR: { foreach(Event e in Q.list){ if(e.type == EventType.CHECK_FOR_HIDDEN){ e.area.Remove(this); if(e.area.Count == 0){ e.dead = true; } break; } } TurnToFloor(); break; } case TileType.STONE_SLAB: { Event e = Q.FindTargetedEvent(this,EventType.STONE_SLAB); if(e != null){ e.dead = true; } TurnToFloor(); break; } case TileType.POISON_BULB: Bump(0); break; case TileType.STANDING_TORCH: Bump(direction_of_motion); if(type == TileType.STANDING_TORCH){ TurnToFloor(); AddFeature(FeatureType.FIRE); } break; case TileType.BARREL: Bump(direction_of_motion); if(type == TileType.BARREL){ TurnToFloor(); List<Tile> cone = TilesWithinDistance(1).Where(x=>x.passable); List<Tile> added = new List<Tile>(); foreach(Tile t in cone){ foreach(int dir in U.FourDirections){ if(R.CoinFlip() && t.TileInDirection(dir).passable){ added.AddUnique(t.TileInDirection(dir)); } } } cone.AddRange(added); foreach(Tile t in cone){ t.AddFeature(FeatureType.OIL); if(t.actor() != null && !t.actor().HasAttr(AttrType.OIL_COVERED,AttrType.SLIMED)){ if(t.actor().IsBurning()){ t.actor().ApplyBurning(); } else{ t.actor().attrs[AttrType.OIL_COVERED] = 1; B.Add(t.actor().YouAre() + " covered in oil. ",t.actor()); if(t.actor() == player){ Help.TutorialTip(TutorialTopic.Oiled); } } } } } break; case TileType.DEMONIC_IDOL: { TurnToFloor(); if(!TilesWithinDistance(3).Any(x=>x.type == TileType.DEMONIC_IDOL)){ foreach(Tile t2 in TilesWithinDistance(4)){ if(t2.color == Color.RandomDoom){ t2.color = Colors.ResolveColor(Color.RandomDoom); } } B.Add("You feel the power leave this summoning circle. "); bool circles = false; bool demons = false; for(int i=0;i<5;++i){ Tile circle = M.tile[M.FinalLevelSummoningCircle(i)]; if(circle.TilesWithinDistance(3).Any(x=>x.type == TileType.DEMONIC_IDOL)){ circles = true; break; } } foreach(Actor a in M.AllActors()){ if(a.Is(ActorType.MINOR_DEMON,ActorType.FROST_DEMON,ActorType.BEAST_DEMON,ActorType.DEMON_LORD)){ demons = true; break; } } if(!circles && !demons){ //victory player.curhp = 100; B.Add("As the last summoning circle is destroyed, your victory gives you a new surge of strength. "); B.PrintAll(); B.Add("Kersai's summoning has been stopped. His cult will no longer threaten the area. "); B.PrintAll(); B.Add("You begin the journey home to deliver the news. "); B.PrintAll(); Global.GAME_OVER = true; Global.BOSS_KILLED = true; Global.KILLED_BY = "nothing"; } } break; } } }
private string GenerateGraphForRoots(string[] rootNames) { // DOT language documentation: http://www.graphviz.org/pdf/dotguide.pdf string codeStr; List <string> codeLines = new List <string>(); List <string> topRoots = new List <string>(); // Build graph from roots bool signEvent = false; if (roots != rootNames) { signEvent = true; roots = rootNames; if (graphProjs != null) { foreach (Project proj in graphProjs) { proj.StatusChanged -= OnProjectUpdate; } } } graphProjs = new List <Project>(); foreach (string rootName in rootNames) { Project proj = SolutionParser.ProjTable[rootName]; if (!proj.HasParent) // top root node { codeStr = String.Format("\"{0}\";", rootName); topRoots.Add(codeStr); } codeStr = String.Format("\"{0}\" [shape=box,style=filled,color={1}];", rootName, ProjectStatusColor(proj)); codeLines.Add(codeStr); foreach (Project depProj in proj.ProjectTree) { graphProjs.AddUnique(depProj); } } codeStr = "{ rank = same;" + String.Join(" ", topRoots.ToArray()) + "}"; codeLines.Add(codeStr); // Add graph edges foreach (Project proj in graphProjs) { if (signEvent) { proj.StatusChanged += OnProjectUpdate; } string projName = proj.Name; foreach (Project depProj in proj.DepProjects) { string depName = depProj.Name; codeStr = String.Format("node[shape=ellipse,style=filled,color={0}];", ProjectStatusColor(depProj)); codeLines.Add(codeStr); string style = String.Empty; if (depProj.IsExternal) { style = " [style=dotted]"; } codeStr = String.Format("\"{0}\" -> \"{1}\"{2};", projName, depName, style); codeLines.Add(codeStr); } } // Generate graph image string dotCode = "digraph G {\n" + String.Join("\n", codeLines.ToArray()) + "}"; return(dotCode); }
public void TriggerTrap(bool click) { bool actor_here = (actor() != null); if(actor_here && actor().type == ActorType.CYCLOPEAN_TITAN){ if(name == "floor"){ B.Add(actor().TheName(true) + " smashes " + Tile.Prototype(type).a_name + ". ",this); } else{ B.Add(actor().TheName(true) + " smashes " + the_name + ". ",this); } TransformTo(TileType.FLOOR); return; } if(click){ if(actor() == player || (actor() == null && player.CanSee(this))){ B.Add("*CLICK* ",this); B.PrintAll(); } else{ if(actor() != null && player.CanSee(this) && player.CanSee(actor())){ B.Add("You hear a *CLICK* from under " + actor().the_name + ". "); B.PrintAll(); } else{ if(DistanceFrom(player) <= 12){ B.Add("You hear a *CLICK* nearby. "); B.PrintAll(); } else{ B.Add("You hear a *CLICK* in the distance. "); B.PrintAll(); } } } } if(actor() == player){ Help.TutorialTip(TutorialTopic.Traps); } switch(type){ case TileType.GRENADE_TRAP: { if(actor_here && player.CanSee(actor())){ B.Add("Grenades fall from the ceiling above " + actor().the_name + "! ",this); } else{ B.Add("Grenades fall from the ceiling! ",this); } List<Tile> valid = new List<Tile>(); foreach(Tile t in TilesWithinDistance(1)){ if(t.passable && !t.Is(FeatureType.GRENADE)){ valid.Add(t); } } int count = R.OneIn(10)? 3 : 2; for(;count>0 & valid.Count > 0;--count){ Tile t = valid.Random(); if(t.actor() != null){ if(t.actor() == player){ B.Add("One lands under you! "); } else{ if(player.CanSee(this)){ B.Add("One lands under " + t.actor().the_name + ". ",t.actor()); } } } else{ if(t.inv != null){ B.Add("One lands under " + t.inv.TheName() + ". ",t); } } t.features.Add(FeatureType.GRENADE); valid.Remove(t); Q.Add(new Event(t,100,EventType.GRENADE)); } Toggle(actor()); break; } case TileType.SLIDING_WALL_TRAP: { List<int> dirs = new List<int>(); for(int i=2;i<=8;i+=2){ Tile t = this; bool good = true; while(t.type != TileType.WALL){ t = t.TileInDirection(i); if(t.opaque && t.type != TileType.WALL){ good = false; break; } if(DistanceFrom(t) > 6){ good = false; break; } } if(good && t.row > 0 && t.row < ROWS-1 && t.col > 0 && t.col < COLS-1){ t = t.TileInDirection(i); } else{ good = false; } if(good && t.row > 0 && t.row < ROWS-1 && t.col > 0 && t.col < COLS-1){ foreach(Tile tt in t.TilesWithinDistance(1)){ if(tt.type != TileType.WALL){ good = false; } } } else{ good = false; } if(good){ dirs.Add(i); } } if(dirs.Count == 0){ B.Add("Nothing happens. ",this); } else{ int dir = dirs[R.Roll(dirs.Count)-1]; Tile first = this; while(first.type != TileType.WALL){ first = first.TileInDirection(dir); } first.TileInDirection(dir).TurnToFloor(); ActorType ac = ActorType.SKELETON; if(M.current_level >= 3 && R.CoinFlip()){ ac = ActorType.ZOMBIE; } if(M.current_level >= 9 && R.OneIn(10)){ ac = ActorType.STONE_GOLEM; } if(M.current_level >= 7 && R.PercentChance(1)){ ac = ActorType.MECHANICAL_KNIGHT; } if(M.current_level >= 15 && R.PercentChance(1)){ ac = ActorType.CORPSETOWER_BEHEMOTH; } if(M.current_level >= 15 && R.PercentChance(1)){ ac = ActorType.MACHINE_OF_WAR; } if(R.PercentChance(1)){ first.TileInDirection(dir).TransformTo(TileType.CHEST); if(R.PercentChance(1)){ first.TileInDirection(dir).color = Color.Yellow; } } else{ Actor.Create(ac,first.TileInDirection(dir).row,first.TileInDirection(dir).col,TiebreakerAssignment.InsertAfterCurrent); } first.TurnToFloor(); foreach(Tile t in first.TileInDirection(dir).TilesWithinDistance(1)){ t.solid_rock = false; } if(first.ActorInDirection(dir) != null){ first.ActorInDirection(dir).FindPath(first.TileInDirection(dir.RotateDir(true,4))); //first.ActorInDirection(dir).FindPath(TileInDirection(dir)); } if(player.CanSee(first)){ B.Add("The wall slides away. "); } else{ if(DistanceFrom(player) <= 6){ B.Add("You hear rock sliding on rock. "); } } } Toggle(actor()); break; } case TileType.TELEPORT_TRAP: { if(actor_here){ B.Add("An unstable energy covers " + actor().TheName(true) + ". ",actor()); actor().attrs[AttrType.TELEPORTING] = R.Roll(4); Q.KillEvents(actor(),AttrType.TELEPORTING); //should be replaced by refreshduration eventually. works the same way, though. Q.Add(new Event(actor(),(R.Roll(10)+25)*100,AttrType.TELEPORTING,actor().YouFeel() + " more stable. ",actor())); } else{ if(inv != null){ B.Add("An unstable energy covers " + inv.TheName(true) + ". ",this); Tile dest = M.AllTiles().Where(x=>x.passable && x.CanGetItem()).RandomOrDefault(); if(dest != null){ B.Add("It vanishes! ",this); bool seen = player.CanSee(this); Item i = inv; inv = null; dest.GetItem(i); if(seen){ B.Add("It reappears! ",dest); } else{ B.Add(i.AName(true) + " appears! ",dest); } } else{ B.Add("Nothing happens. ",this); } } else{ B.Add("An unstable energy crackles for a moment, then dissipates. ",this); } } Toggle(actor()); break; } case TileType.SHOCK_TRAP: { //int old_radius = light_radius; //This was a cool effect, but caused bugs when the tile's radius changed mid-trigger. //UpdateRadius(old_radius,3,true); //I'll restore it when I figure out how... if(actor_here){ if(player.CanSee(actor())){ B.Add("Electricity zaps " + actor().the_name + ". ",this); } if(actor().TakeDamage(DamageType.ELECTRIC,DamageClass.PHYSICAL,R.Roll(3,6),null,"a shock trap")){ actor().ApplyStatus(AttrType.STUNNED,(R.Roll(6)+7)*100); /*B.Add(actor().YouAre() + " stunned! ",actor()); actor().RefreshDuration(AttrType.STUNNED,actor().DurationOfMagicalEffect(R.Roll(6)+7)*100,(actor().YouAre() + " no longer stunned. "),actor());*/ if(actor() == player){ Help.TutorialTip(TutorialTopic.Stunned); } } } else{ B.Add("Arcs of electricity appear and sizzle briefly. ",this); //apply electricity, once wands have been added } //M.Draw(); //UpdateRadius(3,old_radius,true); Toggle(actor()); break; } case TileType.LIGHT_TRAP: if(M.wiz_lite == false){ if(actor_here && player.HasLOS(row,col) && !actor().IsHiddenFrom(player)){ B.Add("A wave of light washes out from above " + actor().TheName(true) + "! "); } else{ B.Add("A wave of light washes over the area! "); } M.wiz_lite = true; M.wiz_dark = false; Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } else{ B.Add("The air grows even brighter for a moment. "); Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } Toggle(actor()); break; case TileType.DARKNESS_TRAP: if(M.wiz_dark == false){ if(actor_here && player.CanSee(actor())){ B.Add("A surge of darkness radiates out from above " + actor().TheName(true) + "! "); if(player.light_radius > 0){ B.Add("Your light is extinguished! "); } } else{ B.Add("A surge of darkness radiates over the area! "); if(player.light_radius > 0){ B.Add("Your light is extinguished! "); } } M.wiz_dark = true; M.wiz_lite = false; Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } else{ B.Add("The air grows even darker for a moment. "); Q.KillEvents(null,EventType.NORMAL_LIGHTING); Q.Add(new Event((R.Roll(2,20) + 120) * 100,EventType.NORMAL_LIGHTING)); } Toggle(actor()); break; case TileType.FIRE_TRAP: { if(actor_here){ B.Add("A column of flame engulfs " + actor().TheName(true) + "! ",this); actor().ApplyBurning(); } else{ B.Add("A column of flame appears! ",this); } AddFeature(FeatureType.FIRE); Toggle(actor()); break; } case TileType.ALARM_TRAP: if(actor() == player){ B.Add("A high-pitched ringing sound reverberates from above you. "); } else{ if(actor_here && player.CanSee(actor())){ B.Add("A high-pitched ringing sound reverberates from above " + actor().the_name + ". "); } else{ B.Add("You hear a high-pitched ringing sound. "); } } foreach(Actor a in ActorsWithinDistance(12,true)){ if(a.type != ActorType.GIANT_BAT && a.type != ActorType.BLOOD_MOTH && a.type != ActorType.CARNIVOROUS_BRAMBLE && a.type != ActorType.LASHER_FUNGUS && a.type != ActorType.PHASE_SPIDER){ a.FindPath(this); } } Toggle(actor()); break; case TileType.BLINDING_TRAP: if(actor_here){ B.Add("A dart flies out and strikes " + actor().TheName(true) + ". ",this); //todo: what about replacing this with blinding dust? if(!actor().HasAttr(AttrType.NONLIVING,AttrType.BLINDSIGHT)){ actor().ApplyStatus(AttrType.BLIND,(R.Roll(2,6)+6)*100); /*B.Add(actor().YouAre() + " blind! ",actor()); actor().RefreshDuration(AttrType.BLIND,(R.Roll(3,6) + 6) * 100,actor().YouAre() + " no longer blinded. ",actor());*/ } else{ B.Add("It doesn't affect " + actor().the_name + ". ",actor()); } } else{ B.Add("A dart flies out and hits the floor. ",this); } Toggle(actor()); break; case TileType.ICE_TRAP: if(actor_here){ if(!actor().IsBurning()){ if(player.CanSee(this)){ B.Add("The air suddenly freezes around " + actor().TheName(true) + ". "); } actor().ApplyFreezing(); } else{ if(player.CanSee(this)){ if(player.CanSee(actor())){ B.Add("Ice crystals form in the air around " + actor().the_name + " but quickly vanish. "); } else{ B.Add("Ice crystals form in the air but quickly vanish. "); } } } } else{ B.Add("Ice crystals form in the air but quickly vanish. "); } Toggle(actor()); break; case TileType.PHANTOM_TRAP: { Tile open = TilesWithinDistance(3).Where(t => t.passable && t.actor() == null && t.HasLOE(this)).RandomOrDefault(); if(open != null){ Actor a = Actor.CreatePhantom(open.row,open.col); if(a != null){ a.attrs[AttrType.PLAYER_NOTICED]++; a.player_visibility_duration = -1; if(player.HasLOS(a)){ //don't print a message if you're just detecting monsters B.Add("A ghostly image rises! ",a); } } else{ B.Add("Nothing happens. ",this); } } else{ B.Add("Nothing happens. ",this); } Toggle(actor()); break; } case TileType.POISON_GAS_TRAP: { bool spores = false; if(M.current_level >= 5 && R.PercentChance((M.current_level - 4) * 3)){ //spores = true; //3% at level 5...33% at level 15...48% at level 20. - disabled for now } int num = R.Roll(5) + 8; if(spores){ List<Tile> new_area = AddGaseousFeature(FeatureType.SPORES,num); //todo: should this be its own trap type? what about other gases? if(new_area.Count > 0){ B.Add("A cloud of spores fills the area! ",this); Event.RemoveGas(new_area,600,FeatureType.SPORES,12); } } else{ List<Tile> new_area = AddGaseousFeature(FeatureType.POISON_GAS,num); if(new_area.Count > 0){ B.Add("Poisonous gas fills the area! ",this); Event.RemoveGas(new_area,300,FeatureType.POISON_GAS,18); } } Toggle(actor()); break; } case TileType.SCALDING_OIL_TRAP: { if(actor_here){ B.Add("Scalding oil pours over " + actor().TheName(true) + "! ",this); if(actor().TakeDamage(DamageType.FIRE,DamageClass.PHYSICAL,R.Roll(3,6),null,"a scalding oil trap")){ if(!actor().HasAttr(AttrType.BURNING,AttrType.SLIMED) && !IsBurning()){ actor().attrs[AttrType.OIL_COVERED] = 1; B.Add(actor().YouAre() + " covered in oil. ",actor()); if(actor() == player){ Help.TutorialTip(TutorialTopic.Oiled); } } } } else{ B.Add("Scalding oil pours over the floor. ",this); } List<Tile> covered_in_oil = new List<Tile>{this}; List<Tile> added = new List<Tile>(); for(int i=0;i<2;++i){ foreach(Tile t in covered_in_oil){ foreach(int dir in U.FourDirections){ Tile neighbor = t.TileInDirection(dir); if(neighbor.DistanceFrom(this) == 1 && R.OneIn(3) && neighbor.passable && !covered_in_oil.Contains(neighbor)){ added.AddUnique(neighbor); } } } covered_in_oil.AddRange(added); } foreach(Tile t in covered_in_oil){ t.AddFeature(FeatureType.OIL); } Toggle(actor()); break; } case TileType.FLING_TRAP: { List<int> valid_dirs = new List<int>(); foreach(int d in U.EightDirections){ bool good = true; Tile current = this; for(int i=0;i<2;++i){ current = current.TileInDirection(d); if(current == null || (!current.passable && !current.Is(TileType.BARREL,TileType.CRACKED_WALL,TileType.DOOR_C,TileType.HIDDEN_DOOR,TileType.POISON_BULB,TileType.STANDING_TORCH))){ good = false; //try to pick directions that are either open, or that have interesting things to be knocked into break; } } if(good){ valid_dirs.Add(d); } } Toggle(actor()); int dir = -1; if(valid_dirs.Count > 0){ dir = valid_dirs.Random(); } else{ dir = Global.RandomDirection(); } if(actor_here){ Actor a = actor(); B.Add("The floor suddenly tilts up under " + a.TheName(true) + "! ",this); a.attrs[AttrType.TURN_INTO_CORPSE]++; KnockObjectBack(actor(),GetBestExtendedLineOfEffect(TileInDirection(dir)),5,null); a.CorpseCleanup(); } else{ if(inv != null){ B.Add("The floor suddenly tilts up under " + inv.TheName(true) + "! ",this); string item_name = "it"; string punctuation = ". "; if(!player.CanSee(this)){ item_name = inv.AName(true); punctuation = "! "; } Item i = inv; inv = null; List<Tile> line = GetBestExtendedLineOfEffect(TileInDirection(dir)); if(line.Count > 13){ line = line.ToCount(13); //for range 12 } Tile t = line.LastBeforeSolidTile(); Actor first = FirstActorInLine(line); if(first != null){ t = first.tile(); B.Add(item_name + " hits " + first.the_name + punctuation,first); } line = line.ToFirstSolidTileOrActor(); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } { Tile first_unseen = null; foreach(Tile tile2 in line){ if(!tile2.seen){ first_unseen = tile2; break; } } if(first_unseen != null){ line = line.To(first_unseen); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } } } M.Draw(); if(line.Count > 0){ Screen.AnimateProjectile(line,new colorchar(i.symbol,i.color)); } if(i.IsBreakable()){ B.Add("It breaks! ",t); i.CheckForMimic(); } else{ t.GetItem(i); } t.MakeNoise(2); if(first != null){ //first.player_visibility_duration = -1; //not sure how angry monsters should get in this case //first.attrs[AttrType.PLAYER_NOTICED]++; } else{ if(t.IsTrap()){ t.TriggerTrap(); } } } else{ B.Add("Nothing happens. ",this); } } break; } case TileType.STONE_RAIN_TRAP: B.Add("Stones fall from the ceiling! ",this); if(actor_here){ Actor a = actor(); B.Add(a.YouVisibleAre() + " hit! ",this); a.TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(3,6),null,"falling stones"); } Toggle(actor()); foreach(Tile neighbor in TilesWithinDistance(1).Randomize()){ if(R.PercentChance(40)){ if(neighbor.IsTrap()){ B.Add("A bouncing stone triggers a trap. ",neighbor); } neighbor.ApplyEffect(DamageType.NORMAL); //break items and set off traps if(neighbor.Is(TileType.FLOOR)){ neighbor.Toggle(null,TileType.GRAVEL); neighbor.RemoveFeature(FeatureType.SLIME); neighbor.RemoveFeature(FeatureType.OIL); } } } break; default: break; } }
void enableShielding() { // print("enableShielding()"); disableShielding(); var attached=getFairingParams(); if (!sideFairing) return; // get all parts in range var parts=new List<Part>(); var colliders=Physics.OverlapSphere(part.transform.TransformPoint(lookupCenter), lookupRad, 1); for (int i=colliders.Length-1; i>=0; --i) { var p=colliders[i].gameObject.GetComponentUpwards<Part>(); if (p!=null) parts.AddUnique(p); } // print("got "+parts.Count+" nearby parts"); // filter parts float sizeSqr=lookupRad*lookupRad*4; float boundCylRadSq=boundCylRad*boundCylRad; bool isInline = (sideFairing.inlineHeight>0); bool topClosed=false; Matrix4x4 w2l=Matrix4x4.identity, w2lb=Matrix4x4.identity; Bounds topBounds=default(Bounds); if (isInline) { w2l=part.transform.worldToLocalMatrix; w2lb=w2l; for (int i=0; i<3; ++i) for (int j=0; j<3; ++j) w2lb[i, j]=Mathf.Abs(w2lb[i, j]); topBounds=new Bounds(new Vector3(0, boundCylY1, 0), Vector3.one*(sideFairing.topRad*2)); } for (int pi=0; pi<parts.Count; ++pi) { var pt=parts[pi]; // check special cases if (pt==part) { shieldedParts.Add(pt); continue; } bool isSide=false; for (int i=0; i<attached.Length; ++i) if (attached[i].attachedPart==pt) { isSide=true; break; } if (isSide) continue; // print("checking part "+pt.partName+" "+pt.partInfo.title); // check if the top is closed in the inline case var bounds=pt.GetRendererBounds(); var box=PartGeometryUtil.MergeBounds(bounds, pt.partTransform); if (isInline && !topClosed && pt.vessel==vessel) { var wb=box; wb.Expand(sideFairing.sideThickness*4); var b=new Bounds(w2l.MultiplyPoint3x4(wb.center), w2lb.MultiplyVector(wb.size)); if (b.Contains(topBounds.min) && b.Contains(topBounds.max)) topClosed=true; } // check if too big to fit // if (box.size.sqrMagnitude>sizeSqr) continue; // check if the centroid is within fairing bounds var c=part.transform.InverseTransformPoint(PartGeometryUtil.FindBoundsCentroid(bounds, null)); float y=c.y; if (y<boundCylY0 || y>boundCylY1) continue; float xsq=new Vector2(c.x, c.z).sqrMagnitude; if (xsq>boundCylRadSq) continue; // accurate centroid check float x=Mathf.Sqrt(xsq); bool inside=false; for (int i=1; i<shape.Length; ++i) { var p0=shape[i-1]; var p1=shape[i]; if (p0.y>p1.y) { var p=p0; p0=p1; p1=p; } if (y<p0.y || y>p1.y) continue; float dy=p1.y-p0.y, r; if (dy<=1e-6f) r=(p0.x+p1.x)*0.5f; else r=(p1.x-p0.x)*(y-p0.y)/dy+p0.x; if (x>r) continue; inside=true; break; } if (!inside) continue; shieldedParts.Add(pt); // print("shielded "+pt.partName); } if (isInline && !topClosed) { disableShielding(); return; } // add shielding for (int i=0; i<shieldedParts.Count; ++i) shieldedParts[i].AddShield(this); numShieldedDisplay=shieldedParts.Count; var fbase=part.GetComponent<ProceduralFairingBase>(); if (fbase!=null) fbase.onShieldingEnabled(shieldedParts); }
public void Bump(int direction_of_motion) { switch(type){ case TileType.BARREL: { if(TileInDirection(direction_of_motion).passable){ B.Add("The barrel tips over and smashes. ",this); TurnToFloor(); List<Tile> cone = GetCone(direction_of_motion,2,true).Where(x=>x.passable && HasLOE(x)); List<Tile> added = new List<Tile>(); foreach(Tile t in cone){ foreach(int dir in U.FourDirections){ if(R.CoinFlip() && t.TileInDirection(dir).passable){ added.AddUnique(t.TileInDirection(dir)); } } } cone.AddRange(added); cone.Remove(this); foreach(Tile t in cone){ t.AddFeature(FeatureType.OIL); } if(Is(FeatureType.FIRE)){ RemoveFeature(FeatureType.FIRE); TileInDirection(direction_of_motion).ApplyEffect(DamageType.FIRE); } } break; } case TileType.STANDING_TORCH: if(TileInDirection(direction_of_motion).passable){ B.Add("The torch tips over. ",this); TurnToFloor(); TileInDirection(direction_of_motion).AddFeature(FeatureType.FIRE); } break; case TileType.POISON_BULB: { B.Add("The poison bulb bursts. ",this); TurnToFloor(); List<Tile> area = AddGaseousFeature(FeatureType.POISON_GAS,8); if(area.Count > 0){ Q.RemoveTilesFromEventAreas(area,EventType.REMOVE_GAS); Event.RemoveGas(area,200,FeatureType.POISON_GAS,18); } break; } } }