Core/Achievements: Implement many new ModifierTree types

Port From (https://github.com/TrinityCore/TrinityCore/commit/aa8ad4d2fd6144fca3b69261a90a663df682e571)
This commit is contained in:
hondacrx
2019-11-18 13:53:45 -05:00
parent bd8303f42c
commit 12c007a8a1
12 changed files with 1365 additions and 100 deletions
+242 -35
View File
@@ -118,8 +118,11 @@ namespace Framework.Constants
SourceIsAlive = 16, SourceIsAlive = 16,
SourceAreaOrZone = 17, SourceAreaOrZone = 17,
TargetAreaOrZone = 18, TargetAreaOrZone = 18,
//Unk19 = 19,
MapDifficultyOld = 20, MapDifficultyOld = 20,
TargetCreatureYieldsXp = 21, TargetCreatureYieldsXp = 21, // Nyi
SourceLevelAboveTarget = 22,
SourceLevelEqualTarget = 23,
ArenaType = 24, ArenaType = 24,
SourceRace = 25, SourceRace = 25,
SourceClass = 26, SourceClass = 26,
@@ -127,57 +130,261 @@ namespace Framework.Constants
TargetClass = 28, TargetClass = 28,
MaxGroupMembers = 29, MaxGroupMembers = 29,
TargetCreatureType = 30, TargetCreatureType = 30,
TargetCreatureFamily = 31,
SourceMap = 32, SourceMap = 32,
ItemClass = 33, ClientVersion = 33,
ItemSubclass = 34, BattlePetTeamLevel = 34,
CompleteQuestNotInGroup = 35, NotInGroup = 35,
MinPersonalRating = 37, InGroup = 36,
MinPersonalRating = 37, // Nyi
TitleBitIndex = 38, TitleBitIndex = 38,
SourceLevel = 39, SourceLevel = 39,
TargetLevel = 40, TargetLevel = 40,
TargetZone = 41, SourceZone = 41,
TargetHealthPercentBelow = 46, TargetZone = 42,
SourceHealthPctLower = 43,
SourceHealthPctGreater = 44,
SourceHealthPctEqual = 45,
TargetHealthPctLower = 46,
TargetHealthPctGreater = 47,
TargetHealthPctEqual = 48,
SourceHealthLower = 49,
SourceHealthGreater = 50,
SourceHealthEqual = 51,
TargetHealthLower = 52,
TargetHealthGreater = 53,
TargetHealthEqual = 54,
TargetPlayerCondition = 55, TargetPlayerCondition = 55,
MinAchievementPoints = 56, MinAchievementPoints = 56,
RequiresLfgGroup = 58, InLfgDungeon = 57,
Unk60 = 60, InLfgRandomDungeon = 58,
RequiresGuildGroup = 61, InLfgFirstRandomDungeon = 59,
//Unk60 = 60, // Nyi
RequiresGuildGroup = 61, // Nyi
GuildReputation = 62, GuildReputation = 62,
RatedBattleground = 63, RatedBattleground = 63, // Nyi
RatedBattlegroundRating = 64, RatedBattlegroundRating = 64,
ProjectRarity = 65, ProjectRarity = 65,
ProjectRace = 66, ProjectRace = 66,
WorldState = 67, // Nyi WorldStateExpression = 67,
MapDifficulty = 68, // Nyi MapDifficulty = 68,
PlayerLevel = 69, // Nyi SourceLevelGreater = 69,
TargetPlayerLevel = 70, // Nyi TargetLevelGreater = 70,
//PlayerLevelOnAccount = 71, // Not Verified SourceLevelLower = 71,
//Unk73 = 73, // References Another Modifier Tree Id TargetLevelLower = 72,
ScenarioId = 74, // Nyi ModifierTree = 73,
ScenarioId = 74,
TheTillersReputation = 75,
PetBattleAchievementPoints = 76, // Nyi
//Unk77 = 77, // Nyi
BattlePetFamily = 78, // Nyi BattlePetFamily = 78, // Nyi
BattlePetHealthPct = 79, // Nyi BattlePetHealthPct = 79, // Nyi
//Unk80 = 80 // Something To Do With World Bosses GuildGroupMembers = 80, // Nyi
BattlePetEntry = 81, // Nyi BattlePetEntry = 81, // Nyi
//BattlePetEntryId = 82, // Some Sort Of Data Id? ScenarioStepIndex = 82,
ChallengeModeMedal = 83, // NYI ChallengeModeMedal = 83, // Nyi
//CRITERIA_ADDITIONAL_CONDITION_UNK84 = 84, // Quest id IsOnQuest = 84,
//CRITERIA_ADDITIONAL_CONDITION_UNK86 = 86, // Some external event id ExaltedWithFaction = 85, // Nyi
//CRITERIA_ADDITIONAL_CONDITION_UNK87 = 87, // Achievement id HasAchievement = 86,
HasAchievementOnCharacter = 87, // Nyi
CloudSerpentReputation = 88,
BattlePetBreedQualityId = 89, // Nyi
PetBattleIsPvp = 90, // Nyi
BattlePetSpecies = 91, BattlePetSpecies = 91,
Expansion = 92, ActiveExpansion = 92,
//Unk93 = 93, // Nyi
FriendshipRepReaction = 94, // Nyi
FactionStanding = 95,
ItemClassAndSubclass = 96, // Nyi
SourceSex = 97,
SourceNativeSex = 98,
Skill = 99,
//Unk100 = 100, // Nyi
NormalPhaseShift = 101,
InPhase = 102,
NotInPhase = 103,
HasSpell = 104,
ItemCount = 105,
AccountExpansion = 106,
SourceHasAuraLabel = 107, // Nyi, Spelllabel
//Unk108 = 108, // Nyi
TimeInRange = 109, // Nyi, Packed Time Between Asset And Secondaryasset
RewardedQuest = 110, RewardedQuest = 110,
CompletedQuest = 111, CompletedQuest = 111,
CompletedQuestObjective = 112, // NYI, QuestObjectiveID CompletedQuestObjective = 112, // Nyi, Questobjectiveid
GarrisonFollowerEntry = 144, ExploredArea = 113,
GarrisonFollowerQuality = 145, ItemCountIncludingBank = 114,
GarrisonFollowerLevel = 146, //Unk115 = 115, // Nyi
GarrisonRareMission = 147, // NYI SourcePvpFactionIndex = 116,
GarrisonBuildingLevel = 149, // NYI LfgValueEqual = 117,
GarrisonMissionType = 167, // NYI LfgValueGreater = 118,
PlayerItemLevel = 169, // NYI CurrencyAmount = 119,
GarrisonFollowILvl = 184, //Unk120 = 120, // Nyi
CurrencyTrackedAmount = 121,
MapInstanceType = 122,
Mentor = 123,
//Unk124 = 124, // Nyi
//Unk125 = 125, // Nyi
GarrisonLevelAbove = 126, // Asset: Garrlevel, Secondaryasset: Garrtype
GarrisonFollowersAboveLevel = 127, // Asset: Count, Secondaryasset: Followerlevel, Tertiaryasset: Garrtype
GarrisonFollowersAboveQuality = 128, // Asset: Count, Secondaryasset: Followerquality, Tertiaryasset: Garrtype
GarrisonFollowerAboveLevelWithAbility = 129, // Asset: Followerlevel, Secondaryasset: Ability, Tertiaryasset: Garrtype
GarrisonFollowerAboveLevelWithTrait = 130, // Asset: Followerlevel, Secondaryasset: Ability, Tertiaryasset: Garrtype (Same As Above But Ability Must Have GarrisonAbilityFlagTrait)
GarrisonFollowerWithAbilityInBuilding = 131, // Asset: Ability, Secondaryasset: Buildingtype, Tertiaryasset: Garrtype
GarrisonFollowerWithTraitInBuilding = 132, // Asset: Ability, Secondaryasset: Buildingtype, Tertiaryasset: Garrtype
GarrisonFollowerAboveLevelInBuilding = 133, // Asset: Followerlevel, Secondaryasset: Buildingtype, Tertiaryasset: Garrtype
GarrisonBuildingAboveLevel = 134, // Asset: Buildingtype, Secondaryasset: Buildinglevel, Tertiaryasset: Garrtype
GarrisonBlueprint = 135, // Nyi
//Unk136 = 136, // Nyi
//Unk137 = 137, // Nyi
//Unk138 = 138, // Nyi
//Unk139 = 139, // Nyi
GarrisonBuildingInactive = 140,
//Unk141 = 141, // Nyi
GarrisonBuildingEqualLevel = 142, // Asset: Buildingtype, Secondaryasset: Buildinglevel, Tertiaryasset: Garrtype
GarrisonFollowerWithAbility = 143, // Asset: Ability, Secondaryasset: Garrtype
GarrisonFollowerWithTrait = 144, // Asset: Ability, Secondaryasset: Garrtype
GarrisonFollowerAboveQualityWod = 145, // Asset: Followerquality
GarrisonFollowerEqualLevel = 146, // Asset: Followerlevel, Secondaryasset: Garrtype
GarrisonRareMission = 147, // Nyi
//Unk148 = 148, // Nyi
GarrisonBuildingLevel = 149, // Nyi
//Unk150 = 150, // Nyi
BattlePetSpeciesInTeam = 151, // Asset: Count, Secondaryasset: Battlepetspeciesid
BattlePetFamilyInTeam = 152, // Asset: Count, Secondaryasset: Battlepetfamily
//Unk153 = 153, // Nyi
//Unk154 = 154, // Nyi
//Unk155 = 155, // Nyi
//Unk156 = 156, // Nyi
GarrisonFollowerId = 157, // Follower With Id, In Any Garrison
QuestObjectiveProgressEqual = 158, // Nyi Asset: Questobjectiveid, Secondaryasset: Progress
QuestObjectiveProgressAbove = 159, // Nyi Asset: Questobjectiveid, Secondaryasset: Progress
//Unk160 = 160, // Nyi
//Unk161 = 161, // Nyi
//Unk162 = 162, // Nyi
//Unk163 = 163, // Nyi
//Unk164 = 164, // Nyi
//Unk165 = 165, // Nyi
//Unk166 = 166, // Nyi
GarrisonMissionType = 167, // Nyi
GarrisonFollowerAboveItemLevel = 168, // Asset: Followeritemlevel
GarrisonFollowersAboveItemLevel = 169, // Asset: Count, Secondaryasset: Followeritemlevel, Tertiaryasset: Garrtype
GarrisonLevelEqual = 170, // Asset: Count
GarrisonGroupSize = 171, // Nyi
//Unk172 = 172, // Nyi Something To Do With Currency But Only Used On Criterias That Require The Same Currency
TargetingCorpse = 173,
//Unk174 = 174, // Nyi
GarrisonFollowersLevelEqual = 175, // Asset: Count, Secondaryasset: Followerlevel, Tertiaryasset: Garrtype
GarrisonFollowerIdInBuilding = 176, // Asset: Followerid, Secondaryasset: Buildingtype
//Unk177 = 177, // Nyi
//Unk178 = 178, // Nyi
WorldPvpArea = 179, // Nyi
NonOwnGarrison = 180, // Nyi
//Unk181 = 181, // Nyi
//Unk182 = 183, // Nyi
//Unk183 = 183, // Nyi
GarrisonFollowersItemLevelAbove = 184,
//Unk185 = 185, // Nyi
//Unk186 = 186, // Nyi
GarrisonFollowerType = 187, // Nyi
//Unk188 = 188, // Nyi
//Unk189 = 189, // Nyi
//Unk190 = 190, // Nyi
//Unk191 = 191, // Nyi
//Unk192 = 192, // Nyi
HonorLevel = 193, HonorLevel = 193,
PrestigeLevel = 194 PrestigeLevel = 194,
//Unk195 = 195, // Nyi
//Unk196 = 196, // Nyi
//Unk197 = 197, // Nyi
//Unk198 = 198, // Nyi
//Unk198 = 199, // Nyi
ItemModifiedAppearance = 200,
GarrisonSelectedTalent = 201, // Nyi Asset: Garrtalentid (Talent Selected, Research Timer Doesn'T Matter)
GarrisonResearchedTalent = 202, // Nyi Asset: Garrtalentid (Talent Selected, Research Must Be Finished)
HasCharacterRestrictions = 203,
//Unk204 = 204, // Nyi
//Unk205 = 205, // Nyi
QuestInfoId = 206,
GarrisonResearchingTalent = 207, // Nyi Asset: Garrtalentid (Talent Selected, Research Must Be In Progress)
ArtifactAppearanceSetUsed = 208,
CurrencyAmountEqual = 209,
//Unk210 = 210, // Nyi
ScenarioType = 211,
AccountExpansionEqual = 212,
//Unk213 = 213, // Nyi
//Unk214 = 214, // Nyi
//Unk215 = 215, // Nyi
ChallengeModeMedal2 = 216, // Nyi Keystone Master, Asset = 3
//Unk217 = 217, // Nyi
//Unk218 = 218, // Nyi
//Unk219 = 219, // Nyi
//Unk220 = 220, // Nyi
//Unk221 = 221, // Nyi
//Unk222 = 222, // Nyi
//Unk223 = 223, // Nyi
//Unk224 = 224, // Nyi
//Unk225 = 225, // Nyi
UsedLevelBoost = 226, // Nyi
UsedRaceChange = 227, // Nyi
UsedFactionChange = 228, // Nyi
//Unk229 = 229, // Nyi
//Unk230 = 230, // Nyi
AchievementGloballyIncompleted = 231, // Hall Of Fame Stuff, Asset: Unk, Secondaryasset: Achievementid
MainHandVisibleSubclass = 232,
OffHandVisibleSubclass = 233,
PvpTier = 234, // Nyi Asset: Pvptierid
AzeriteItemLevel = 235,
//Unk236 = 236, // Nyi
//Unk237 = 237, // Nyi
//Unk238 = 238, // Nyi
PvpTierGreater = 239, // Nyi Asset: Pvptierenum, Secondaryasset: Pvpbracket
//Unk240 = 240, // Nyi
//Unk241 = 241, // Nyi
//Unk242 = 242, // Nyi
//Unk243 = 243, // Nyi
//Unk244 = 244, // Nyi
InWarMode = 245,
//Unk246 = 246, // Nyi
KeystoneLevel = 247, // Nyi
//Unk248 = 248, // Nyi
KeystoneDungeon = 249, // Nyi Asset: Mapchallengemodeid
//Unk250 = 250, // Nyi
PvpSeason = 251, // Nyi Asset: That Unknown Column In Pvpseason.Db2
SourceDisplayRace = 252,
TargetDisplayRace = 253,
FriendshipRepReactionExact = 254, // Nyi
SourceAuraCountEqual = 255,
TargetAuraCountEqual = 256,
SourceAuraCountGreater = 257,
TargetAuraCountGreater = 258,
UnlockedAzeriteEssenceRankLower = 259,
UnlockedAzeriteEssenceRankEqual = 260,
UnlockedAzeriteEssenceRankGreater = 261,
SourceHasAuraEffectIndex = 262, // Asset: Spellid, Secondaryasset: Index
SourceSpecializationRole = 263,
SourceLevel120 = 264,
//Unk265 = 265,
SelectedAzeriteEssenceRankLower = 266,
SelectedAzeriteEssenceRankGreater = 267,
//Unk268 = 268,
//Unk269 = 269,
//Unk270 = 270,
//Unk271 = 271,
//Unk272 = 272,
//Unk273 = 273,
//Unk274 = 274,
//Unk275 = 275,
//Unk276 = 276,
//Unk277 = 277,
//Unk278 = 278,
//Unk279 = 279,
MapOrCosmeticMap = 280,
//Unk281 = 281,
HasEntitlement = 282,
HasQuestSession = 283,
//Unk284 = 284,
//Unk285 = 285,
} }
public enum CriteriaFlags public enum CriteriaFlags
+8
View File
@@ -1393,6 +1393,14 @@ namespace Framework.Constants
UnderwaterAllowed = 0x8 UnderwaterAllowed = 0x8
} }
public enum ModifierTreeOperator
{
SingleTrue = 2,
SingleFalse = 3,
All = 4,
Some = 8
}
public enum MountCapabilityFlags : byte public enum MountCapabilityFlags : byte
{ {
Ground = 0x1, Ground = 0x1,
@@ -566,7 +566,11 @@ namespace Game.Achievements
public bool ModifierTreeSatisfied(uint modifierTreeId) public bool ModifierTreeSatisfied(uint modifierTreeId)
{ {
return AdditionalRequirementsSatisfied(Global.CriteriaMgr.GetModifierTree(modifierTreeId), 0, 0, null, _owner); ModifierTreeNode modifierTree = Global.CriteriaMgr.GetModifierTree(modifierTreeId);
if (modifierTree != null)
return ModifierTreeSatisfied(modifierTree, 0, 0, null, _owner);
return false;
} }
public override void SendCriteriaUpdate(Criteria criteria, CriteriaProgress progress, uint timeElapsed, bool timedCompleted) public override void SendCriteriaUpdate(Criteria criteria, CriteriaProgress progress, uint timeElapsed, bool timedCompleted)
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1674,7 +1674,7 @@ namespace Game
return result; return result;
} }
static uint GetPlayerConditionLfgValue(Player player, PlayerConditionLfgStatus status) public static uint GetPlayerConditionLfgValue(Player player, PlayerConditionLfgStatus status)
{ {
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group = null) if (group = null)
+10 -1
View File
@@ -28,7 +28,7 @@ namespace Game.Entities
{ {
public class AzeriteItem : Item public class AzeriteItem : Item
{ {
AzeriteItemData m_azeriteItemData; public AzeriteItemData m_azeriteItemData;
public AzeriteItem() public AzeriteItem()
{ {
@@ -208,6 +208,15 @@ namespace Game.Entities
owner.SendPacket(xpGain); owner.SendPacket(xpGain);
} }
public SelectedAzeriteEssences GetSelectedAzeriteEssences()
{
foreach (SelectedAzeriteEssences essences in m_azeriteItemData.SelectedEssences)
if (essences.Enabled != 0)
return essences;
return null;
}
public override void BuildValuesCreate(WorldPacket data, Player target) public override void BuildValuesCreate(WorldPacket data, Player target)
{ {
UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
@@ -263,6 +263,11 @@ namespace Game.Entities
_updateMask[block] &= ~(uint)UpdateMask.GetBlockFlag(index); _updateMask[block] &= ~(uint)UpdateMask.GetBlockFlag(index);
} }
public bool Empty()
{
return _values.Empty();
}
public int Size() public int Size()
{ {
return _values.Count; return _values.Count;
@@ -656,9 +656,9 @@ namespace Game.Entities
public class SelectedAzeriteEssences : BaseUpdateData<AzeriteItem> public class SelectedAzeriteEssences : BaseUpdateData<AzeriteItem>
{ {
UpdateField<uint> SpecializationID = new UpdateField<uint>(0, 1); public UpdateField<uint> SpecializationID = new UpdateField<uint>(0, 1);
UpdateField<uint> Enabled = new UpdateField<uint>(0, 2); public UpdateField<uint> Enabled = new UpdateField<uint>(0, 2);
UpdateFieldArray<uint> AzeriteEssenceID = new UpdateFieldArray<uint>(3, 3, 4); public UpdateFieldArray<uint> AzeriteEssenceID = new UpdateFieldArray<uint>(3, 3, 4);
public SelectedAzeriteEssences() : base(7) { } public SelectedAzeriteEssences() : base(7) { }
+2 -1
View File
@@ -585,6 +585,7 @@ namespace Game.Entities
case TypeId.Item: case TypeId.Item:
case TypeId.Container: case TypeId.Container:
case TypeId.AzeriteItem: case TypeId.AzeriteItem:
case TypeId.AzeriteEmpoweredItem:
{ {
Item item = (Item)questGiver; Item item = (Item)questGiver;
Global.ScriptMgr.OnQuestAccept(this, item, quest); Global.ScriptMgr.OnQuestAccept(this, item, quest);
@@ -1122,7 +1123,7 @@ namespace Game.Entities
} }
if (quest.QuestSortID > 0) if (quest.QuestSortID > 0)
UpdateCriteria(CriteriaTypes.CompleteQuestsInZone, (ulong)quest.QuestSortID); UpdateCriteria(CriteriaTypes.CompleteQuestsInZone, quest.Id);
UpdateCriteria(CriteriaTypes.CompleteQuestCount); UpdateCriteria(CriteriaTypes.CompleteQuestCount);
UpdateCriteria(CriteriaTypes.CompleteQuest, quest.Id); UpdateCriteria(CriteriaTypes.CompleteQuest, quest.Id);
+7
View File
@@ -1392,6 +1392,13 @@ namespace Game.Entities
return playerCurrency.WeeklyQuantity; return playerCurrency.WeeklyQuantity;
} }
public uint GetTrackedCurrencyCount(uint id)
{
if (!_currencyStorage.ContainsKey(id))
return 0;
return _currencyStorage[id].TrackedQuantity;
}
//Action Buttons - CUF Profile //Action Buttons - CUF Profile
public void SaveCUFProfile(byte id, CUFProfile profile) { _CUFProfiles[id] = profile; } public void SaveCUFProfile(byte id, CUFProfile profile) { _CUFProfiles[id] = profile; }
+14 -5
View File
@@ -25,6 +25,7 @@ using Game.Maps;
using Game.Network.Packets; using Game.Network.Packets;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Game.Garrisons namespace Game.Garrisons
{ {
@@ -301,8 +302,8 @@ namespace Game.Garrisons
return _owner.GetTeam() == Team.Horde ? GarrisonFactionIndex.Horde : GarrisonFactionIndex.Alliance; return _owner.GetTeam() == Team.Horde ? GarrisonFactionIndex.Horde : GarrisonFactionIndex.Alliance;
} }
GarrisonType GetGarrisonType() { return GarrisonType.Garrison; } public GarrisonType GetGarrisonType() { return GarrisonType.Garrison; }
GarrSiteLevelRecord GetSiteLevel() { return _siteLevel; } public GarrSiteLevelRecord GetSiteLevel() { return _siteLevel; }
public ICollection<Plot> GetPlots() public ICollection<Plot> GetPlots()
{ {
@@ -314,7 +315,7 @@ namespace Game.Garrisons
return _plots.LookupByKey(garrPlotInstanceId); return _plots.LookupByKey(garrPlotInstanceId);
} }
bool HasBlueprint(uint garrBuildingId) { return _knownBuildings.Contains(garrBuildingId); } public bool HasBlueprint(uint garrBuildingId) { return _knownBuildings.Contains(garrBuildingId); }
public void LearnBlueprint(uint garrBuildingId) public void LearnBlueprint(uint garrBuildingId)
{ {
@@ -519,7 +520,7 @@ namespace Game.Garrisons
return _followers.LookupByKey(dbId); return _followers.LookupByKey(dbId);
} }
uint CountFollowers(Predicate<Follower> predicate) public uint CountFollowers(Predicate<Follower> predicate)
{ {
uint count = 0; uint count = 0;
foreach (var pair in _followers) foreach (var pair in _followers)
@@ -868,12 +869,20 @@ namespace Game.Garrisons
public class Follower public class Follower
{ {
public GarrisonFollower PacketInfo = new GarrisonFollower();
public uint GetItemLevel() public uint GetItemLevel()
{ {
return (PacketInfo.ItemLevelWeapon + PacketInfo.ItemLevelArmor) / 2; return (PacketInfo.ItemLevelWeapon + PacketInfo.ItemLevelArmor) / 2;
} }
public GarrisonFollower PacketInfo = new GarrisonFollower(); public bool HasAbility(uint garrAbilityId)
{
return PacketInfo.AbilityID.Any(garrAbility =>
{
return garrAbility.Id == garrAbilityId;
});
}
} }
} }
} }
+6 -1
View File
@@ -140,6 +140,11 @@ namespace Game.Scenarios
return true; return true;
} }
public ScenarioRecord GetEntry()
{
return _data.Entry;
}
ScenarioStepState GetStepState(ScenarioStepRecord step) ScenarioStepState GetStepState(ScenarioStepRecord step)
{ {
if (!_stepStates.ContainsKey(step)) if (!_stepStates.ContainsKey(step))
@@ -334,7 +339,7 @@ namespace Game.Scenarios
public virtual void Update(uint diff) { } public virtual void Update(uint diff) { }
public void SetStepState(ScenarioStepRecord step, ScenarioStepState state) { _stepStates[step] = state; } public void SetStepState(ScenarioStepRecord step, ScenarioStepState state) { _stepStates[step] = state; }
ScenarioStepRecord GetStep() public ScenarioStepRecord GetStep()
{ {
return _currentstep; return _currentstep;
} }