/// <summary> /// Initializes a new instance of the <see cref="AttributeCache"/> class that can create data tables by using a DataPageRetriever. /// </summary> /// <param name="dataSupplier">Any structure that implements IDataPageRetriever</param> /// <param name="rowsPerPage">The rows per page</param> public AttributeCache(IAttributeSource dataSupplier, int rowsPerPage) { _dataSupply = dataSupplier; AttributeCache.rowsPerPage = rowsPerPage; _editRowIndex = -1; LoadFirstTwoPages(); }
/// <summary> /// Checks whether the source contains more than numValues different values in the given field. /// </summary> /// <param name="fieldName">Name of the field that gets checked.</param> /// <param name="source">Attribute source that contains the field.</param> /// <param name="numValues">Minimal number of values that should exist.</param> /// <returns>True, if more than num values exist.</returns> private static bool SufficientValues(string fieldName, IAttributeSource source, int numValues) { ArrayList lst = new ArrayList(); AttributeCache ac = new AttributeCache(source, numValues); foreach (Dictionary <string, object> dr in ac) { object val = dr[fieldName] ?? "[NULL]"; if (val.ToString() == string.Empty) { val = "[NULL]"; } if (lst.Contains(val)) { continue; } lst.Add(val); if (lst.Count > numValues) { return(true); } } return(false); }
/// <inheritdoc /> public void CreateCategories(IAttributeSource source, ICancelProgressHandler progressHandler) { string fieldName = EditorSettings.FieldName; if (EditorSettings.ClassificationType == ClassificationType.Custom) { return; } if (EditorSettings.ClassificationType == ClassificationType.UniqueValues) { CreateUniqueCategories(fieldName, source, progressHandler); } else { if (source.GetColumn(fieldName).DataType == typeof(string)) { NonNumericField?.Invoke(this, EventArgs.Empty); return; } if (!SufficientValues(fieldName, source, EditorSettings.NumBreaks)) { CreateUniqueCategories(fieldName, source, progressHandler); } else { GetValues(source, progressHandler); CreateBreakCategories(); } } AppearsInLegend = true; LegendText = fieldName; }
private void CreateUniqueCategories(string fieldName, IAttributeSource source, ICancelProgressHandler progressHandler) { Breaks = GetUniqueValues(fieldName, source, progressHandler); string fieldExpression = "[" + fieldName.ToUpper() + "]"; ClearCategories(); bool isStringField = CheckFieldType(fieldName, source); ProgressMeter pm = new ProgressMeter(progressHandler, "Building Feature Categories", Breaks.Count); List <double> sizeRamp = GetSizeSet(Breaks.Count); List <Color> colorRamp = GetColorSet(Breaks.Count); for (int colorIndex = 0; colorIndex < Breaks.Count; colorIndex++) { Break brk = Breaks[colorIndex]; // get the color for the category Color randomColor = colorRamp[colorIndex]; double size = sizeRamp[colorIndex]; IFeatureCategory cat = CreateNewCategory(randomColor, size) as IFeatureCategory; if (cat != null) { cat.LegendText = brk.Name; if (isStringField) { cat.FilterExpression = fieldExpression + "= '" + brk.Name.Replace("'", "''") + "'"; } else { cat.FilterExpression = fieldExpression + "=" + brk.Name; } if (cat.FilterExpression != null) { if (cat.FilterExpression.Contains("=[NULL]")) { cat.FilterExpression = cat.FilterExpression.Replace("=[NULL]", " is NULL"); } else if (cat.FilterExpression.Contains("= '[NULL]'")) { cat.FilterExpression = cat.FilterExpression.Replace("= '[NULL]'", " is NULL"); } } AddCategory(cat); } colorIndex++; pm.CurrentValue = colorIndex; } pm.Reset(); }
/// <summary> /// Casts a ray using the reticle and then validates the position /// </summary> /// <returns></returns> protected virtual bool Raycast(bool rUseReticle = true) { bool lRayHit = false; Transform lOwner = mOwner.transform; if (rUseReticle && TargetingReticle.Instance != null) { RaycastHit[] lHitInfos; int lHitCount = TargetingReticle.Instance.RaycastAll(out lHitInfos, _MinDistance, _MaxDistance, _Radius, _CollisionLayers, lOwner); if (lHitCount > 0) { if (_Tags == null || _Tags.Length == 0) { lRayHit = true; mHitInfo = lHitInfos[0]; } else { for (int i = 0; i < lHitCount; i++) { IAttributeSource lAttributeSource = lHitInfos[i].collider.gameObject.GetComponent <IAttributeSource>(); if (lAttributeSource != null && lAttributeSource.AttributesExist(_Tags)) { lRayHit = true; mHitInfo = lHitInfos[i]; break; } } } } } else { Ray lRay = Camera.main.ScreenPointToRay(UnityEngine.Input.mousePosition); if (RaycastExt.SafeRaycast(lRay.origin, lRay.direction, out mHitInfo, _MaxDistance, _CollisionLayers, lOwner)) { if (_Tags == null || _Tags.Length == 0) { lRayHit = true; } else { IAttributeSource lAttributeSource = mHitInfo.collider.gameObject.GetComponent <IAttributeSource>(); if (lAttributeSource != null && lAttributeSource.AttributesExist(_Tags)) { lRayHit = true; } } } } return(lRayHit); }
/// <summary> /// Activates the action on a single target /// </summary> /// <param name="rTarget">Target to activate on</param> protected bool ActivateInstance(GameObject rTarget) { if (rTarget == null) { return false; } IAttributeSource lAttributeSource = rTarget.GetComponent<IAttributeSource>(); if (lAttributeSource == null) { return false; } if (!lAttributeSource.AttributeExists(AttributeName)) { return false; } return true; }
/// <summary> /// Find a position by targeting down /// </summary> /// <returns></returns> public virtual bool FindPosition() { Transform lOwner = _Spell.Owner.transform; float lStep = (_MinDistance - _MinDistance) / 5f; // Start at the center and spiral out for (float lDistance = _MaxDistance; lDistance >= _MinDistance; lDistance = lDistance - lStep) { //GraphicsManager.DrawLine(mMotionController.CameraTransform.position, mMotionController.CameraTransform.TransformPoint(lPosition), (lCount == 0 ? Color.red : lColor), null, 5f); RaycastHit lHitInfo; Vector3 lStart = lOwner.position + _StartOffset + (lOwner.forward * lDistance); Vector3 lDirection = -lOwner.up; if (RaycastExt.SafeRaycast(lStart, lDirection, out lHitInfo, _MaxDistance, _CollisionLayers, lOwner)) { // Grab the gameobject this collider belongs to GameObject lGameObject = lHitInfo.collider.gameObject; // Don't count the ignore if (lGameObject.transform == lOwner) { continue; } if (_Tags != null && _Tags.Length > 0) { IAttributeSource lAttributeSource = lGameObject.GetComponent <IAttributeSource>(); if (lAttributeSource == null || !lAttributeSource.AttributesExist(_Tags)) { continue; } } // Determine if we're done choosing a point if (_Spell.Data.Positions == null) { _Spell.Data.Positions = new List <Vector3>(); } _Spell.Data.Positions.Clear(); _Spell.Data.Positions.Add(lHitInfo.point); return(true); } } // Return the target hit return(false); }
/// <summary> /// Activates the action on a single target /// </summary> /// <param name="rTarget">Target to activate on</param> protected bool ActivateInstance(GameObject rTarget) { if (rTarget == null) { return(false); } IAttributeSource lAttributeSource = rTarget.GetComponent <IAttributeSource>(); if (lAttributeSource == null) { return(false); } if (!lAttributeSource.AttributeExists(AttributeName)) { return(false); } float lValue = lAttributeSource.GetAttributeValue <float>(AttributeName); lValue = lValue + UnityEngine.Random.Range(MinRandom, MaxRandom); switch (ComparisonIndex) { case 0: return(lValue == Value); case 1: return(lValue != Value); case 2: return(lValue < Value); case 3: return(lValue <= Value); case 4: return(lValue > Value); case 5: return(lValue >= Value); } return(false); }
/// <summary> /// Activates a single target by running the links for that target /// </summary> /// <param name="rTarget"></param> protected virtual bool ActivateInstance(GameObject rTarget, object rData) { if (rTarget == null) { return(true); } IAttributeSource lAttributes = rTarget.GetComponent <IAttributeSource>(); if (lAttributes == null) { return(true); } Type lType = lAttributes.GetAttributeType(_AttributeName); if (lType == typeof(int)) { int lValue = 0; if (int.TryParse(_StringValue, out lValue)) { lAttributes.SetAttributeValue <int>(_AttributeName, lValue); } } else if (lType == typeof(float)) { float lValue = 0f; if (float.TryParse(_StringValue, out lValue)) { lAttributes.SetAttributeValue <float>(_AttributeName, lValue); } } else if (lType == typeof(string)) { lAttributes.SetAttributeValue <string>(_AttributeName, _StringValue); } return(true); }
/// <summary> /// Gets the values from a file based data source rather than an in memory object. /// </summary> /// <param name="source">Source to get the values from.</param> /// <param name="progressHandler">The progress handler.</param> public void GetValues(IAttributeSource source, ICancelProgressHandler progressHandler) { int pageSize = 100000; Values = new List <double>(); string normField = EditorSettings.NormField; string fieldName = EditorSettings.FieldName; if (source.NumRows() < EditorSettings.MaxSampleCount) { int numPages = (int)Math.Ceiling((double)source.NumRows() / pageSize); for (int ipage = 0; ipage < numPages; ipage++) { int numRows = (ipage == numPages - 1) ? source.NumRows() % pageSize : pageSize; DataTable table = source.GetAttributes(ipage * pageSize, numRows); if (!string.IsNullOrEmpty(EditorSettings.ExcludeExpression)) { DataRow[] rows = table.Select("NOT (" + EditorSettings.ExcludeExpression + ")"); foreach (DataRow row in rows) { double val; if (!double.TryParse(row[fieldName].ToString(), out val)) { continue; } if (double.IsNaN(val)) { continue; } if (normField != null) { double norm; if (!double.TryParse(row[normField].ToString(), out norm) || double.IsNaN(val)) { continue; } Values.Add(val / norm); continue; } Values.Add(val); } } else { foreach (DataRow row in table.Rows) { double val; if (!double.TryParse(row[fieldName].ToString(), out val)) { continue; } if (double.IsNaN(val)) { continue; } if (normField != null) { double norm; if (!double.TryParse(row[normField].ToString(), out norm) || double.IsNaN(val)) { continue; } Values.Add(val / norm); continue; } Values.Add(val); } } } } else { Dictionary <int, double> randomValues = new(); pageSize = 10000; int count = EditorSettings.MaxSampleCount; // Specified seed is required for consistently recreating the break values Random rnd = new(9999); AttributePager ap = new(source, pageSize); int countPerPage = count / ap.NumPages(); ProgressMeter pm = new(progressHandler, "Sampling " + count + " random values", count); for (int iPage = 0; iPage < ap.NumPages(); iPage++) { for (int i = 0; i < countPerPage; i++) { double val; double norm = 1; int index; bool failed = false; do { index = rnd.Next(ap.StartIndex, ap.StartIndex + pageSize); DataRow dr = ap.Row(index); if (!double.TryParse(dr[fieldName].ToString(), out val)) { failed = true; } if (normField == null) { continue; } if (!double.TryParse(dr[normField].ToString(), out norm)) { failed = true; } }while (randomValues.ContainsKey(index) || double.IsNaN(val) || failed); if (normField != null) { Values.Add(val / norm); } else { Values.Add(val); } randomValues.Add(index, val); pm.CurrentValue = i + (iPage * countPerPage); } if (progressHandler != null && progressHandler.Cancel) { break; } } } Values.Sort(); Statistics.Calculate(Values); }
/// <summary> /// Gets a list of all unique values of the attribute field. /// </summary> /// <param name="fieldName">Name of the field that gets checked.</param> /// <param name="source">Attribute source that contains the field.</param> /// <param name="progressHandler">The progress handler.</param> /// <returns>A list with the unique values.</returns> private List <Break> GetUniqueValues(string fieldName, IAttributeSource source, ICancelProgressHandler progressHandler) { ArrayList lst; bool hugeCountOk = false; if (_cachedUniqueValues.ContainsKey(fieldName)) { lst = _cachedUniqueValues[fieldName]; } else { lst = new ArrayList(); AttributePager ap = new(source, 5000); ProgressMeter pm = new(progressHandler, "Discovering Unique Values", source.NumRows()); for (int row = 0; row < source.NumRows(); row++) { object val = ap.Row(row)[fieldName] ?? "[NULL]"; if (val.ToString() == string.Empty) { val = "[NULL]"; } if (lst.Contains(val)) { continue; } lst.Add(val); if (lst.Count > 1000 && !hugeCountOk) { CancelEventArgs args = new(true); TooManyCategories?.Invoke(this, args); if (args.Cancel) { break; } hugeCountOk = true; } pm.CurrentValue = row; if (progressHandler.Cancel) { break; } } lst.Sort(); if (lst.Count < EditorSettings.MaxSampleCount) { _cachedUniqueValues[fieldName] = lst; } } List <Break> result = new(); if (lst != null) { foreach (object item in lst) { result.Add(new Break(item.ToString())); } } return(result); }
/// <summary> /// Called when the action is first activated /// <param name="rPreviousSpellActionState">State of the action prior to this one activating</param> public override void Activate(int rPreviousSpellActionState = -1, object rData = null) { base.Activate(rPreviousSpellActionState, rData); mActivations = 0; mBatchDelay = 0f; mLastBatchTime = 0f; if (_Spell != null && _Spell.Data != null) { SpellData lSpellData = _Spell.Data; Transform lCenter = null; Vector3 lCenterPosition = PositionOffset; GetBestPosition(SearchRootIndex, rData, _Spell.Data, PositionOffset, out lCenter, out lCenterPosition); // Ignore any existing targets for future tests if (IgnorePreviousTargets && lSpellData.Targets != null && lSpellData.Targets.Count > 0) { if (lSpellData.PreviousTargets == null) { lSpellData.PreviousTargets = new List <GameObject>(); } for (int i = 0; i < lSpellData.Targets.Count; i++) { if (!lSpellData.PreviousTargets.Contains(lSpellData.Targets[i])) { lSpellData.PreviousTargets.Add(lSpellData.Targets[i]); } } } // Remove any existing targets if (Replace) { if (lSpellData.Targets != null) { lSpellData.Targets.Clear(); lSpellData.Targets = null; } } // Find new targets if (lCenterPosition != Vector3Ext.Null) { Collider[] lColliders = null; List <GameObject> lTargets = null; int lCount = RaycastExt.SafeOverlapSphere(lCenterPosition, Radius, out lColliders, CollisionLayers, _Spell.Owner.transform, null, true); if (lColliders != null && lCount > 0) { if (lTargets == null) { lTargets = new List <GameObject>(); } for (int i = 0; i < lCount; i++) { GameObject lGameObject = lColliders[i].gameObject; if (lGameObject == _Spell.Owner) { continue; } if (RequireRigidbody && lGameObject.GetComponent <Rigidbody>() == null) { continue; } if (RequireActorCore && lGameObject.GetComponent <ActorCore>() == null) { continue; } if (RequireCombatant && lGameObject.GetComponent <ICombatant>() == null) { continue; } if (lSpellData.PreviousTargets != null && lSpellData.PreviousTargets.Contains(lGameObject)) { continue; } if (_Tags != null && _Tags.Length > 0) { IAttributeSource lAttributeSource = lGameObject.GetComponent <IAttributeSource>(); if (lAttributeSource == null || !lAttributeSource.AttributesExist(_Tags)) { continue; } } if (!lTargets.Contains(lGameObject)) { lTargets.Add(lGameObject); } } // Sort the list based on distance if (lTargets.Count > 1) { lTargets = lTargets.OrderBy(x => Vector3.Distance(lCenterPosition, x.transform.position)).ToList <GameObject>(); } } // Choose what we want if (lTargets != null && lTargets.Count > 0) { if (lSpellData.Targets == null) { lSpellData.Targets = new List <GameObject>(); } // Any or nearest if (SearchTypeIndex == 0 || SearchTypeIndex == 1) { for (int i = 0; i < lTargets.Count; i++) { if (!lSpellData.Targets.Contains(lTargets[i])) { lSpellData.Targets.Add(lTargets[i]); } if (MaxTargets > 0 && lSpellData.Targets.Count >= MaxTargets) { break; } } } // Furthest else if (SearchTypeIndex == 2) { for (int i = lTargets.Count - 1; i >= 0; i--) { if (!lSpellData.Targets.Contains(lTargets[i])) { lSpellData.Targets.Insert(0, lTargets[i]); } if (MaxTargets > 0 && lSpellData.Targets.Count >= MaxTargets) { break; } } } } } if (lSpellData.Targets != null && lSpellData.Targets.Count > 0) { if (!UseBatches) { OnSuccess(); return; } } } // Immediately deactivate if (!UseBatches) { OnFailure(); } }
/// <summary> /// Activates the action on a single target /// </summary> /// <param name="rTarget">Target to activate on</param> protected void ActivateInstance(GameObject rTarget) { Vector3 lPoint = rTarget.transform.position; Vector3 lForward = rTarget.transform.forward; // Combatant that is attacking ICombatant lAttacker = (_Spell.Owner != null ? _Spell.Owner.GetComponent <ICombatant>() : null); // Determine who we're colliding with IActorCore lDefenderCore = rTarget.GetComponent <IActorCore>(); IDamageable lDamageable = rTarget.GetComponent <IDamageable>(); if (lDefenderCore == null) { IWeaponCore lWeaponCore = rTarget.GetComponent <IWeaponCore>(); if (lWeaponCore != null) { lDefenderCore = lWeaponCore.Owner.GetComponent <IActorCore>(); if (lDamageable == null) { lDamageable = lWeaponCore.Owner.GetComponent <IDamageable>(); } } } // Save the hit information Transform lHitTransform = GetClosestTransform(lPoint, rTarget.transform); Vector3 lCombatCenter = lHitTransform.position; Vector3 lHitDirection = Vector3.zero; if (lDefenderCore != null) { ICombatant lDefenderCombatant = lDefenderCore.gameObject.GetComponent <ICombatant>(); if (lDefenderCombatant != null) { lHitDirection = Quaternion.Inverse(lDefenderCore.Transform.rotation) * (lPoint - lDefenderCombatant.CombatOrigin).normalized; } } else { lHitDirection = Quaternion.Inverse(lHitTransform.rotation) * (lPoint - lCombatCenter).normalized; } // Determine the damage float lDamage = UnityEngine.Random.Range(_MinDamage, _MaxDamage); if (_DamageFloatValueIndex >= 0 && _Spell.Data.FloatValues != null) { lDamage = _Spell.Data.FloatValues[_DamageFloatValueIndex]; } // Put together the combat round info CombatMessage lCombatMessage = CombatMessage.Allocate(); lCombatMessage.ID = CombatMessage.MSG_DEFENDER_ATTACKED; lCombatMessage.Attacker = (lAttacker != null ? lAttacker.Transform.gameObject : _Spell.Owner); lCombatMessage.Defender = (lDefenderCore != null ? lDefenderCore.Transform.gameObject : rTarget); lCombatMessage.Weapon = null; lCombatMessage.DamageType = _DamageType; lCombatMessage.ImpactType = _ImpactType; lCombatMessage.Damage = lDamage; lCombatMessage.AnimationEnabled = _PlayAnimation; lCombatMessage.HitPoint = lPoint; lCombatMessage.HitDirection = lHitDirection; lCombatMessage.HitVector = lForward; lCombatMessage.HitTransform = lHitTransform; // Let the defender react to the damage if (lDefenderCore != null) { lDefenderCore.SendMessage(lCombatMessage); } // If needed, send the damage directly to the actor core else if (lDamageable != null) { lDamageable.OnDamaged(lCombatMessage); } // Without an actor core, check if we can set attributes else { IAttributeSource lAttributeSource = rTarget.GetComponent <IAttributeSource>(); if (lAttributeSource != null) { float lHealth = lAttributeSource.GetAttributeValue <float>(EnumAttributeIDs.HEALTH); lAttributeSource.SetAttributeValue(EnumAttributeIDs.HEALTH, Mathf.Max(lHealth - lCombatMessage.Damage, 0f)); } } // Release the message lCombatMessage.Release(); }
/// <summary> /// This checks the type of the specified field whether it's a string field /// </summary> private static bool CheckFieldType(string fieldName, IAttributeSource source) { return source.GetColumn(fieldName).DataType == typeof(string); }
/// <summary> /// Returns /// </summary> private static bool SufficientValues(string fieldName, IAttributeSource source, int numValues) { ArrayList lst = new ArrayList(); AttributeCache ac = new AttributeCache(source, numValues); foreach (Dictionary<string, object> dr in ac) { object val = dr[fieldName] ?? "[NULL]"; if (val.ToString() == string.Empty) val = "[NULL]"; if (lst.Contains(val)) continue; lst.Add(val); if (lst.Count > numValues) return true; } return false; }
/// <inheritdoc /> public void CreateCategories(IAttributeSource source, ICancelProgressHandler progressHandler) { string fieldName = EditorSettings.FieldName; if (EditorSettings.ClassificationType == ClassificationType.Custom) return; if (EditorSettings.ClassificationType == ClassificationType.UniqueValues) { CreateUniqueCategories(fieldName, source, progressHandler); } else { if (source.GetColumn(fieldName).DataType == typeof(string)) { //MessageBox.Show(MessageStrings.FieldNotNumeric); if (NonNumericField != null) NonNumericField(this, EventArgs.Empty); return; } if (!SufficientValues(fieldName, source, EditorSettings.NumBreaks)) { CreateUniqueCategories(fieldName, source, progressHandler); } else { GetValues(source, progressHandler); CreateBreakCategories(); } } AppearsInLegend = true; LegendText = fieldName; }
/// <summary> /// This checks the type of the specified field whether it's a string field. /// </summary> /// <param name="fieldName">Name of the field that gets checked.</param> /// <param name="source">Attribute source that contains the field.</param> /// <returns>True, if the field is of type boolean.</returns> private static bool CheckFieldType(string fieldName, IAttributeSource source) { return(source.GetColumn(fieldName).DataType == typeof(string)); }
/// <summary> /// Attempt to find a target that we can focus on. This approach uses a spiralling raycast /// </summary> /// <returns></returns> public virtual Transform FindTarget() { float lMaxRadius = 8f; float lMaxDistance = 20f; float lRevolutions = 2f; float lDegreesPerStep = 27f; float lSteps = lRevolutions * (360f / lDegreesPerStep); float lRadiusPerStep = lMaxRadius / lSteps; float lAngle = 0f; float lRadius = 0f; Vector3 lPosition = Vector3.zero; //float lColorPerStep = 1f / lSteps; //Color lColor = Color.white; Transform lOwner = _Spell.Owner.transform; // We want our final revolution to be max radius. So, increase the steps lSteps = lSteps + (360f / lDegreesPerStep) - 1f; // Start at the center and spiral out int lCount = 0; for (lCount = 0; lCount < lSteps; lCount++) { lPosition.x = lRadius * Mathf.Cos(lAngle * Mathf.Deg2Rad); lPosition.y = lRadius * Mathf.Sin(lAngle * Mathf.Deg2Rad); lPosition.z = lMaxDistance; //GraphicsManager.DrawLine(mMotionController.CameraTransform.position, mMotionController.CameraTransform.TransformPoint(lPosition), (lCount == 0 ? Color.red : lColor), null, 5f); RaycastHit lHitInfo; Vector3 lStart = lOwner.position + _StartOffset; Vector3 lDirection = lOwner.forward; if (RaycastExt.SafeRaycast(lStart, lDirection, out lHitInfo, _MaxDistance, _CollisionLayers, lOwner)) { // Grab the gameobject this collider belongs to GameObject lGameObject = lHitInfo.collider.gameObject; // Don't count the ignore if (lGameObject.transform == lOwner) { continue; } if (lHitInfo.collider is TerrainCollider) { continue; } if (_Tags != null && _Tags.Length > 0) { IAttributeSource lAttributeSource = lGameObject.GetComponent <IAttributeSource>(); if (lAttributeSource == null || !lAttributeSource.AttributesExist(_Tags)) { continue; } } if (RequiresRigidbody && lGameObject.GetComponent <Rigidbody>() == null) { continue; } if (RequiresActorCore && lGameObject.GetComponent <ActorCore>() == null) { continue; } if (RequiresCombatant && lGameObject.GetComponent <ICombatant>() == null) { continue; } // Store the target if (_Spell.Data.Targets == null) { _Spell.Data.Targets = new List <GameObject>(); } _Spell.Data.Targets.Clear(); _Spell.Data.Targets.Add(lGameObject); return(lGameObject.transform); } // Increment the spiral lAngle += lDegreesPerStep; lRadius = Mathf.Min(lRadius + lRadiusPerStep, lMaxRadius); //lColor.r = lColor.r - lColorPerStep; //lColor.g = lColor.g - lColorPerStep; } // Return the target hit return(null); }
/// <summary> /// Called when the action is first activated /// <param name="rPreviousSpellActionState">State of the action prior to this one activating</param> public override void Activate(int rPreviousSpellActionState = -1, object rData = null) { base.Activate(rPreviousSpellActionState, rData); if (_Spell != null && _Spell.Data != null) { SpellData lSpellData = _Spell.Data; GameObject lGameObject = _Spell.Owner; // Ignore any existing targets for future tests if (ShiftToPreviousTargets && lSpellData.Targets != null && lSpellData.Targets.Count > 0) { if (lSpellData.PreviousTargets == null) { lSpellData.PreviousTargets = new List <GameObject>(); } for (int i = 0; i < lSpellData.Targets.Count; i++) { if (!lSpellData.PreviousTargets.Contains(lSpellData.Targets[i])) { lSpellData.PreviousTargets.Add(lSpellData.Targets[i]); } } } // Remove any existing targets if (Replace) { if (lSpellData.Targets != null) { lSpellData.Targets.Clear(); lSpellData.Targets = null; } } // Find new targets bool lAdd = true; if (lAdd && RequireRigidbody && lGameObject.GetComponent <Rigidbody>() == null) { lAdd = false; } if (lAdd && RequireActorCore && lGameObject.GetComponent <ActorCore>() == null) { lAdd = false; } if (lAdd && RequireCombatant && lGameObject.GetComponent <ICombatant>() == null) { lAdd = false; } if (lAdd && lSpellData.PreviousTargets != null && lSpellData.PreviousTargets.Contains(lGameObject)) { lAdd = false; } if (lAdd && _Tags != null && _Tags.Length > 0) { IAttributeSource lAttributeSource = lGameObject.GetComponent <IAttributeSource>(); if (lAttributeSource == null || !lAttributeSource.AttributesExist(_Tags)) { lAdd = false; } } if (lAdd & !lSpellData.Targets.Contains(lGameObject)) { lSpellData.Targets.Add(lGameObject); } if (lAdd) { OnSuccess(); return; } } // Immediately deactivate OnFailure(); }
/// <summary> /// Gets the values from a file based data source rather than an in memory object. /// </summary> /// <param name="source"></param> /// <param name="progressHandler"></param> public void GetValues(IAttributeSource source, ICancelProgressHandler progressHandler) { int pageSize = 100000; Values = new List<double>(); string normField = EditorSettings.NormField; string fieldName = EditorSettings.FieldName; if (source.NumRows() < EditorSettings.MaxSampleCount) { int numPages = (int)Math.Ceiling((double)source.NumRows() / pageSize); for (int ipage = 0; ipage < numPages; ipage++) { int numRows = (ipage == numPages - 1) ? source.NumRows() % pageSize : pageSize; DataTable table = source.GetAttributes(ipage * pageSize, numRows); if (!string.IsNullOrEmpty(EditorSettings.ExcludeExpression)) { DataRow[] rows = table.Select("NOT (" + EditorSettings.ExcludeExpression + ")"); foreach (DataRow row in rows) { double val; if (!double.TryParse(row[fieldName].ToString(), out val)) continue; if (double.IsNaN(val)) continue; if (normField != null) { double norm; if (!double.TryParse(row[normField].ToString(), out norm) || double.IsNaN(val)) continue; Values.Add(val / norm); continue; } Values.Add(val); } } else { foreach (DataRow row in table.Rows) { double val; if (!double.TryParse(row[fieldName].ToString(), out val)) continue; if (double.IsNaN(val)) continue; if (normField != null) { double norm; if (!double.TryParse(row[normField].ToString(), out norm) || double.IsNaN(val)) continue; Values.Add(val / norm); continue; } Values.Add(val); } } } } else { Dictionary<int, double> randomValues = new Dictionary<int, double>(); pageSize = 10000; int count = EditorSettings.MaxSampleCount; Random rnd = new Random(); AttributePager ap = new AttributePager(source, pageSize); int countPerPage = count / ap.NumPages(); ProgressMeter pm = new ProgressMeter(progressHandler, "Sampling " + count + " random values", count); for (int iPage = 0; iPage < ap.NumPages(); iPage++) { for (int i = 0; i < countPerPage; i++) { double val; double norm = 1; int index; bool failed = false; do { index = rnd.Next(ap.StartIndex, ap.StartIndex + pageSize); DataRow dr = ap.Row(index); if (!double.TryParse(dr[fieldName].ToString(), out val)) failed = true; if (normField == null) continue; if (!double.TryParse(dr[normField].ToString(), out norm)) failed = true; } while (randomValues.ContainsKey(index) || double.IsNaN(val) || failed); if (normField != null) { Values.Add(val / norm); } else { Values.Add(val); } randomValues.Add(index, val); pm.CurrentValue = i + iPage * countPerPage; } //Application.DoEvents(); if (progressHandler != null && progressHandler.Cancel) { break; } } } Values.Sort(); Statistics.Calculate(Values); }
/// <summary> /// Casts a ray using the reticle and then validates the position /// </summary> /// <returns></returns> protected virtual bool Raycast(bool rUseReticle = true) { bool lRayHit = false; Transform lOwner = mOwner.transform; if (rUseReticle && TargetingReticle.Instance != null) { RaycastHit[] lHitInfos; int lHitCount = TargetingReticle.Instance.RaycastAll(out lHitInfos, _MinDistance, _MaxDistance, _Radius, _CollisionLayers, lOwner); if (lHitCount > 0) { if (_Tags == null || _Tags.Length == 0) { lRayHit = true; mHitInfo = lHitInfos[0]; } else { for (int i = 0; i < lHitCount; i++) { IAttributeSource lAttributeSource = lHitInfos[i].collider.gameObject.GetComponent <IAttributeSource>(); if (lAttributeSource != null && lAttributeSource.AttributesExist(_Tags)) { lRayHit = true; mHitInfo = lHitInfos[i]; break; } } } } } else { Ray lRay = Camera.main.ScreenPointToRay(UnityEngine.Input.mousePosition); lRayHit = RaycastExt.SafeRaycast(lRay.origin, lRay.direction, out mHitInfo, _MaxDistance, _CollisionLayers, lOwner); } // Since we don't seem to have a hit, test if we can use the max distance and shoot a ray down if (!lRayHit) { Transform lOrigin = TargetingReticle.Instance.RaycastRoot; if (lOrigin == null && Camera.main != null) { lOrigin = Camera.main.transform; } if (lOrigin == null) { lOrigin = transform; } Vector3 lStart = lOrigin.position + (lOrigin.forward * _MaxDistance); RaycastHit lHitInfo; if (RaycastExt.SafeRaycast(lStart, -lOwner.up, out lHitInfo, 10f, _CollisionLayers, lOwner, null, true)) { if (_Tags == null || _Tags.Length == 0) { lRayHit = true; mHitInfo = lHitInfo; } else { IAttributeSource lAttributeSource = lHitInfo.collider.gameObject.GetComponent <IAttributeSource>(); if (lAttributeSource != null && lAttributeSource.AttributesExist(_Tags)) { lRayHit = true; mHitInfo = lHitInfo; } } } } return(lRayHit); }
/// <summary> /// Gets a list of all unique values of the attribute field. /// </summary> private List<Break> GetUniqueValues(string fieldName, IAttributeSource source, ICancelProgressHandler progressHandler) { ArrayList lst; bool hugeCountOk = false; if (_cachedUniqueValues.ContainsKey(fieldName)) { lst = _cachedUniqueValues[fieldName]; } else { lst = new ArrayList(); AttributePager ap = new AttributePager(source, 5000); ProgressMeter pm = new ProgressMeter(progressHandler, "Discovering Unique Values", source.NumRows()); for (int row = 0; row < source.NumRows(); row++) { object val = ap.Row(row)[fieldName] ?? "[NULL]"; if (val.ToString() == string.Empty) val = "[NULL]"; if (lst.Contains(val)) continue; lst.Add(val); if (lst.Count > 1000 && !hugeCountOk) { CancelEventArgs args = new CancelEventArgs(true); if (TooManyCategories != null) TooManyCategories(this, args); if (args.Cancel) break; hugeCountOk = true; } pm.CurrentValue = row; if (progressHandler.Cancel) break; } lst.Sort(); if (lst.Count < EditorSettings.MaxSampleCount) { _cachedUniqueValues[fieldName] = lst; } } List<Break> result = new List<Break>(); if (lst != null) { foreach (object item in lst) { result.Add(new Break(item.ToString())); } } return result; }
/// <summary> /// Gets a list of all unique values of the attribute field. /// </summary> private List<Break> GetUniqueValues(string fieldName, IAttributeSource source, ICancelProgressHandler progressHandler) { ArrayList lst; bool _hugeCountOk = false; if(_cachedUniqueValues.ContainsKey(fieldName)) { lst = _cachedUniqueValues[fieldName]; } else { lst = new ArrayList(); AttributePager ap = new AttributePager(source, 5000); ProgressMeter pm = new ProgressMeter(progressHandler, "Discovering Unique Values", source.NumRows()); for (int row = 0; row < source.NumRows(); row++) { object val = ap.Row(row)[fieldName] ?? "[NULL]"; if (val.ToString() == "") val = "[NULL]"; if (lst.Contains(val)) continue; lst.Add(val); if (lst.Count > 1000 && !_hugeCountOk) { if (MessageBox.Show( "There are more than 1000 unique values, which can result in very slow performance. Do you wish to try to create unique categories from all the values anyway?", "Extreme Number of Categories", MessageBoxButtons.YesNo) == DialogResult.No) { break; } _hugeCountOk = true; } pm.CurrentValue = row; if (progressHandler.Cancel) break; } lst.Sort(); if (lst.Count < EditorSettings.MaxSampleCount) { _cachedUniqueValues[fieldName] = lst; } } List<Break> result = new List<Break>(); if (lst != null) { foreach (object item in lst) { result.Add(new Break(item.ToString())); } } return result; }
private void CreateUniqueCategories(string fieldName, IAttributeSource source, ICancelProgressHandler progressHandler) { Breaks = GetUniqueValues(fieldName, source, progressHandler); string fieldExpression = "[" + fieldName.ToUpper() + "]"; ClearCategories(); bool isStringField = CheckFieldType(fieldName, source); ProgressMeter pm = new ProgressMeter(progressHandler, "Building Feature Categories", Breaks.Count); List<double> sizeRamp = GetSizeSet(Breaks.Count); List<Color> colorRamp = GetColorSet(Breaks.Count); for (int colorIndex = 0; colorIndex < Breaks.Count; colorIndex++) { Break brk = Breaks[colorIndex]; //get the color for the category Color randomColor = colorRamp[colorIndex]; double size = sizeRamp[colorIndex]; IFeatureCategory cat = CreateNewCategory(randomColor, size) as IFeatureCategory; if (cat != null) { //cat.SelectionSymbolizer = _selectionSymbolizer.Copy(); cat.LegendText = brk.Name; if (isStringField) cat.FilterExpression = fieldExpression + "= '" + brk.Name.Replace("'", "''") + "'"; else cat.FilterExpression = fieldExpression + "=" + brk.Name; AddCategory(cat); } colorIndex++; pm.CurrentValue = colorIndex; } pm.Reset(); }
/// <summary> /// Creates a new instance of AttributePager /// </summary> public AttributePager(IAttributeSource source, int pageSize) { _numRows = source.NumRows(); _source = source; _pageSize = pageSize; }