public (ISmartScriptLine[], IConditionLine[]) ToDatabaseCompatibleSmartScript(SmartScript script) { if (script.Events.Count == 0) { return(new ISmartScriptLine[0], null); } var eventId = 0; var lines = new List <ISmartScriptLine>(); var conditions = new List <IConditionLine>(); var previousWasWait = false; long nextTriggerId = script.Events.Where(e => e.Id == SmartConstants.EventTriggerTimed) .Select(e => e.GetParameter(0).Value) .DefaultIfEmpty(0) .Max() + 1; foreach (SmartEvent e in script.Events) { if (e.Actions.Count == 0) { continue; } e.ActualId = eventId; for (var index = 0; index < e.Actions.Count; ++index) { SmartEvent actualEvent = e; if (previousWasWait) { actualEvent = smartFactory.EventFactory(SmartConstants.EventTriggerTimed); actualEvent.GetParameter(0).Value = nextTriggerId++; } else if (index > 0) { actualEvent = smartFactory.EventFactory(SmartConstants.EventLink); } int linkTo = e.Actions.Count - 1 == index ? 0 : eventId + 1; SmartAction actualAction = e.Actions[index].Copy(); if (actualAction.Id == SmartConstants.ActionWait) { linkTo = 0; SmartAction waitAction = actualAction; actualAction = smartFactory.ActionFactory(SmartConstants.ActionTriggerTimed, smartFactory.SourceFactory(SmartConstants.SourceNone), smartFactory.TargetFactory(SmartConstants.TargetNone)); actualAction.GetParameter(0).Value = nextTriggerId; actualAction.GetParameter(1).Value = waitAction.GetParameter(0).Value; actualAction.GetParameter(2).Value = waitAction.GetParameter(0).Value; actualAction.Comment = SmartConstants.CommentWait; previousWasWait = true; } else { if (actualAction.Id == SmartConstants.ActionComment) { SmartAction commentAction = actualAction; actualAction = smartFactory.ActionFactory(SmartConstants.ActionNone, smartFactory.SourceFactory(SmartConstants.SourceNone), smartFactory.TargetFactory(SmartConstants.TargetNone)); actualAction.Comment = commentAction.Comment; } previousWasWait = false; } var actionData = smartDataManager.GetRawData(SmartType.SmartAction, actualAction.Id); if (actionData.TargetIsSource) { smartFactory.UpdateTarget(actualAction.Target, actualAction.Source.Id); for (int i = 0; i < actualAction.Target.ParametersCount; ++i) { actualAction.Target.GetParameter(i).Copy(actualAction.Source.GetParameter(i)); } smartFactory.UpdateSource(actualAction.Source, 0); } if (actionData.ImplicitSource != null) { smartFactory.UpdateSource(actualAction.Source, smartDataManager.GetDataByName(SmartType.SmartSource, actionData.ImplicitSource).Id); } else if (actionData.SourceStoreInAction) { actualAction.GetParameter(2).Value = actualAction.Source.Id; actualAction.GetParameter(3).Value = actualAction.Source.GetParameter(0).Value; actualAction.GetParameter(4).Value = actualAction.Source.GetParameter(1).Value; actualAction.GetParameter(5).Value = actualAction.Source.GetParameter(2).Value; } SmartEvent eventToSerialize = actualEvent.ShallowCopy(); eventToSerialize.Parent = script; eventToSerialize.Actions.Add(actualAction); var serialized = eventToSerialize.ToSmartScriptLines(script.EntryOrGuid, script.SourceType, eventId, linkTo); var serializedConditions = actualEvent.ToConditionLines(script.EntryOrGuid, script.SourceType, eventId); if (serialized.Length != 1) { throw new InvalidOperationException(); } lines.Add(serialized[0]); if (serializedConditions != null) { conditions.AddRange(serializedConditions); } eventId++; } } return(lines.ToArray(), conditions.ToArray()); }
public (ISmartScriptLine[], IConditionLine[]) ToDatabaseCompatibleSmartScript(SmartScript script) { if (script.Events.Count == 0) { return(new ISmartScriptLine[0], null); } var eventId = 0; var lines = new List <ISmartScriptLine>(); var conditions = new List <IConditionLine>(); var previousWasWait = false; long nextTriggerId = script.Events.Where(e => e.Id == SmartConstants.EventTriggerTimed) .Select(e => e.GetParameter(0).Value) .DefaultIfEmpty(0) .Max() + 1; var usedTimedActionLists = script.Events .SelectMany(e => e.Actions) .Where(a => a.Id == SmartConstants.ActionCallTimedActionList || a.Id == SmartConstants.ActionCallRandomTimedActionList || a.Id == SmartConstants.ActionCallRandomRangeTimedActionList) .SelectMany(a => { if (a.Id == SmartConstants.ActionCallRandomTimedActionList) { return new int[] { (int)a.GetParameter(0).Value, (int)a.GetParameter(1).Value, (int)a.GetParameter(2).Value, (int)a.GetParameter(3).Value, (int)a.GetParameter(4).Value, (int)a.GetParameter(5).Value, } } ; if (a.Id == SmartConstants.ActionCallRandomRangeTimedActionList && a.GetParameter(1).Value - a.GetParameter(0).Value < 20) { return(Enumerable.Range((int)a.GetParameter(0).Value, (int)(a.GetParameter(1).Value - a.GetParameter(0).Value + 1))); } return(new int[] { (int)a.GetParameter(0).Value }); }) .Where(id => id != 0) .ToHashSet(); int firstUnusedActionList = Math.Abs(script.EntryOrGuid) * 100 - 1; int GetNextUnusedTimedActionList() { do { firstUnusedActionList++; } while (usedTimedActionLists.Contains(firstUnusedActionList)); usedTimedActionLists.Add(firstUnusedActionList); return(firstUnusedActionList); } foreach (var gv in script.GlobalVariables) { lines.Add(gv.ToMetaSmartScriptLine(script.EntryOrGuid, script.SourceType, eventId++)); } if (script.SourceType == SmartScriptType.TimedActionList) { foreach (SmartEvent e in script.Events) { for (var index = 0; index < e.Actions.Count; ++index) { SmartEvent eventToSerialize = index == 0 ? e.ShallowCopy() : smartFactory.EventFactory(SmartConstants.EventUpdateInCombat); SmartAction actualAction = e.Actions[index].Copy(); AdjustCoreCompatibleAction(actualAction); eventToSerialize.Parent = script; eventToSerialize.Actions.Add(actualAction); var serialized = eventToSerialize.ToSmartScriptLines(script.EntryOrGuid, script.SourceType, eventId++, false, 0); if (serialized.Length != 1) { throw new InvalidOperationException(); } lines.Add(serialized[0]); } } } else { SmartEvent originalEvent; List <SmartEvent> additionalEvents = new(); void FlushLines(SmartEvent?eventForConditions) { if (eventForConditions != null) { var serializedConditions = eventForConditions.ToConditionLines(SmartConstants.ConditionSourceSmartScript, script.EntryOrGuid, script.SourceType, eventId); if (serializedConditions != null) { conditions.AddRange(serializedConditions); } } foreach (var toSerialize in new SmartEvent[] { originalEvent }.Concat(additionalEvents)) { if (toSerialize.Actions.Count == 0) { continue; } var serialized = toSerialize.ToSmartScriptLines(script.EntryOrGuid, script.SourceType, eventId, true); eventId += serialized.Length; lines.AddRange(serialized); } additionalEvents.ForEach(d => d.Actions.Clear()); originalEvent.Actions.Clear(); } foreach (SmartEvent e in script.Events) { if (e.Actions.Count == 0) { continue; } originalEvent = e.ShallowCopy(); originalEvent.Parent = script; additionalEvents.Clear(); SmartEvent lastEvent = originalEvent; long accumulatedWaits = 0; for (var index = 0; index < e.Actions.Count; ++index) { if (previousWasWait) { var eventTimed = smartFactory.EventFactory(SmartConstants.EventTriggerTimed); eventTimed.Parent = script; eventTimed.GetParameter(0).Value = nextTriggerId++; additionalEvents.Add(eventTimed); lastEvent = eventTimed; } if (e.Actions[index].Id == SmartConstants.ActionBeginInlineActionList || e.Actions[index].Id == SmartConstants.ActionAfter) { var timedActionListId = GetNextUnusedTimedActionList(); SmartAction callTimedActionList = smartFactory.ActionFactory(SmartConstants.ActionCallTimedActionList, smartFactory.SourceFactory(SmartConstants.SourceSelf), smartFactory.TargetFactory(SmartConstants.TargetSelf)); callTimedActionList.GetParameter(0).Value = timedActionListId; if (e.Actions[index].Id == SmartConstants.ActionBeginInlineActionList) { callTimedActionList.GetParameter(1).Value = e.Actions[index].GetParameter(0).Value; callTimedActionList.GetParameter(2).Value = e.Actions[index].GetParameter(1).Value; index++; } callTimedActionList.Comment = SmartConstants.CommentInlineActionList; lastEvent.AddAction(callTimedActionList); FlushLines(e); long afterTimeMin = 0; long afterTimeMax = 0; int timedEventId = 0; for (; index < e.Actions.Count; ++index) { if (e.Actions[index].Id == SmartConstants.ActionAfter || e.Actions[index].Id == SmartConstants.ActionWait) { afterTimeMin += e.Actions[index].GetParameter(0).Value; afterTimeMax += e.Actions[index].GetParameter(1).Value; if (e.Actions[index].GetParameter(1).Value == 0) { afterTimeMax += e.Actions[index].GetParameter(0).Value; } } else if (e.Actions[index].Id == SmartConstants.ActionAfterMovement && index > 0) { afterTimeMin = 0; afterTimeMax = 0; var pathId = e.Actions[index - 1].GetParameter(1).Value; timedActionListId = GetNextUnusedTimedActionList(); var eventFinishedMovement = smartFactory.EventFactory(SmartConstants.EventWaypointsEnded); eventFinishedMovement.Parent = script; eventFinishedMovement.GetParameter(1).Value = pathId; var callAnotherTimedActionList = smartFactory.ActionFactory(SmartConstants.ActionCallTimedActionList, smartFactory.SourceFactory(SmartConstants.SourceSelf), smartFactory.TargetFactory(SmartConstants.TargetSelf)); callAnotherTimedActionList.GetParameter(0).Value = timedActionListId; callAnotherTimedActionList.Comment = SmartConstants.CommentInlineMovementActionList; eventFinishedMovement.AddAction(callAnotherTimedActionList); additionalEvents.Add(eventFinishedMovement); FlushLines(null); } else { SmartEvent after = smartFactory.EventFactory(SmartConstants.EventUpdateInCombat); after.GetParameter(0).Value = afterTimeMin; after.GetParameter(1).Value = afterTimeMax; SmartAction actualAction = e.Actions[index].Copy(); AdjustCoreCompatibleAction(actualAction); after.Parent = new SmartScript(new SmartScriptSolutionItem(timedActionListId, SmartScriptType.TimedActionList), smartFactory, smartDataManager, messageBoxService); after.AddAction(actualAction); var serialized = after.ToSmartScriptLines(timedActionListId, SmartScriptType.TimedActionList, timedEventId++, false, 0); if (serialized.Length != 1) { throw new InvalidOperationException(); } lines.Add(serialized[0]); afterTimeMin = 0; afterTimeMax = 0; } } } else if (e.Actions[index].Id == SmartConstants.ActionWait) { accumulatedWaits += e.Actions[index].GetParameter(0).Value; if (index == e.Actions.Count - 1 || e.Actions[index + 1].Id == SmartConstants.ActionWait) { continue; } SmartAction createTimedAction = smartFactory.ActionFactory(SmartConstants.ActionCreateTimed, smartFactory.SourceFactory(SmartConstants.SourceNone), smartFactory.TargetFactory(SmartConstants.TargetNone)); createTimedAction.GetParameter(0).Value = nextTriggerId; createTimedAction.GetParameter(1).Value = accumulatedWaits; createTimedAction.GetParameter(2).Value = accumulatedWaits; createTimedAction.Comment = SmartConstants.CommentWait; previousWasWait = true; originalEvent.AddAction(createTimedAction); } else { previousWasWait = false; SmartAction actualAction = e.Actions[index].Copy(); AdjustCoreCompatibleAction(actualAction); lastEvent.AddAction(actualAction); } } if (originalEvent.Actions.Count == 0) { continue; } FlushLines(e); } } return(lines.ToArray(), conditions.ToArray()); }
public (ISmartScriptLine[], IConditionLine[]) ToDatabaseCompatibleSmartScript(SmartScript script) { if (script.Events.Count == 0) { return(new ISmartScriptLine[0], null); } var eventId = 0; var lines = new List <ISmartScriptLine>(); var conditions = new List <IConditionLine>(); var previousWasWait = false; long nextTriggerId = script.Events.Where(e => e.Id == SmartConstants.EventTriggerTimed) .Select(e => e.GetParameter(0).Value) .DefaultIfEmpty(0) .Max() + 1; foreach (var gv in script.GlobalVariables) { lines.Add(gv.ToMetaSmartScriptLine(script.EntryOrGuid, script.SourceType, eventId++)); } if (script.SourceType == SmartScriptType.TimedActionList) { foreach (SmartEvent e in script.Events) { for (var index = 0; index < e.Actions.Count; ++index) { SmartEvent eventToSerialize = index == 0 ? e.ShallowCopy() : smartFactory.EventFactory(SmartConstants.EventUpdateInCombat); SmartAction actualAction = e.Actions[index].Copy(); AdjustCoreCompatibleAction(actualAction); eventToSerialize.Parent = script; eventToSerialize.Actions.Add(actualAction); var serialized = eventToSerialize.ToSmartScriptLines(script.EntryOrGuid, script.SourceType, eventId++, false, 0); if (serialized.Length != 1) { throw new InvalidOperationException(); } lines.Add(serialized[0]); } } } else { foreach (SmartEvent e in script.Events) { if (e.Actions.Count == 0) { continue; } SmartEvent originalEvent = e.ShallowCopy(); originalEvent.Parent = script; List <SmartEvent> delayedWaits = new(); SmartEvent lastEvent = originalEvent; long accumulatedWaits = 0; for (var index = 0; index < e.Actions.Count; ++index) { if (previousWasWait) { var eventTimed = smartFactory.EventFactory(SmartConstants.EventTriggerTimed); eventTimed.Parent = script; eventTimed.GetParameter(0).Value = nextTriggerId++; delayedWaits.Add(eventTimed); lastEvent = eventTimed; } if (e.Actions[index].Id == SmartConstants.ActionWait) { accumulatedWaits += e.Actions[index].GetParameter(0).Value; if (index == e.Actions.Count - 1 || e.Actions[index + 1].Id == SmartConstants.ActionWait) { continue; } SmartAction createTimedAction = smartFactory.ActionFactory(SmartConstants.ActionCreateTimed, smartFactory.SourceFactory(SmartConstants.SourceNone), smartFactory.TargetFactory(SmartConstants.TargetNone)); createTimedAction.GetParameter(0).Value = nextTriggerId; createTimedAction.GetParameter(1).Value = accumulatedWaits; createTimedAction.GetParameter(2).Value = accumulatedWaits; createTimedAction.Comment = SmartConstants.CommentWait; previousWasWait = true; originalEvent.AddAction(createTimedAction); } else { previousWasWait = false; SmartAction actualAction = e.Actions[index].Copy(); AdjustCoreCompatibleAction(actualAction); lastEvent.AddAction(actualAction); } } if (originalEvent.Actions.Count == 0) { continue; } var serializedConditions = e.ToConditionLines(SmartConstants.ConditionSourceSmartScript, script.EntryOrGuid, script.SourceType, eventId); if (serializedConditions != null) { conditions.AddRange(serializedConditions); } foreach (var toSerialize in new SmartEvent[] { originalEvent }.Concat(delayedWaits)) { var serialized = toSerialize.ToSmartScriptLines(script.EntryOrGuid, script.SourceType, eventId, true); eventId += serialized.Length; lines.AddRange(serialized); } } } return(lines.ToArray(), conditions.ToArray()); }
public static ISmartScriptLine[] ToWaitFreeSmartScriptLines(this SmartScript script, ISmartFactory smartFactory) { if (script.Events.Count == 0) { return(new ISmartScriptLine[0]); } int eventId = 0; List <ISmartScriptLine> lines = new List <ISmartScriptLine>(); bool previousWasWait = false; int nextTriggerId = script.Events.Where(e => e.Id == SmartConstants.EVENT_TRIGGER_TIMED).Select(e => e.GetParameter(0).Value).DefaultIfEmpty(0).Max() + 1; //@todo: don't use hardcoded IDs!!!! foreach (SmartEvent e in script.Events) { if (e.Actions.Count == 0) { continue; } e.ActualId = eventId; for (int index = 0; index < e.Actions.Count; ++index) { SmartEvent actualEvent = e; if (previousWasWait) { actualEvent = smartFactory.EventFactory(SmartConstants.EVENT_TRIGGER_TIMED); actualEvent.SetParameter(0, nextTriggerId++); } else if (index > 0) { actualEvent = smartFactory.EventFactory(SmartConstants.EVENT_LINK); } int linkTo = (e.Actions.Count - 1 == index ? 0 : eventId + 1); SmartAction actualAction = e.Actions[index]; if (actualAction.Id == SmartConstants.ACTION_WAIT) { linkTo = 0; SmartAction waitAction = actualAction; actualAction = smartFactory.ActionFactory(SmartConstants.ACTION_TRIGGER_TIMED, smartFactory.SourceFactory(SmartConstants.SOURCE_NONE), smartFactory.TargetFactory(SmartConstants.TARGET_NONE)); actualAction.SetParameter(0, nextTriggerId); actualAction.SetParameter(1, waitAction.GetParameter(0).GetValue()); actualAction.SetParameter(2, waitAction.GetParameter(0).GetValue()); actualAction.Comment = SmartConstants.COMMENT_WAIT; previousWasWait = true; } else { previousWasWait = false; } SmartEvent eventToSerialize = actualEvent.ShallowCopy(); eventToSerialize.Actions.Add(actualAction.Copy()); var serialized = eventToSerialize.ToSmartScriptLines(script.EntryOrGuid, script.SourceType, eventId, linkTo); if (serialized.Length != 1) { throw new InvalidOperationException(); } lines.Add(serialized[0]); eventId++; } } return(lines.ToArray()); }
private void AddActionCommand(SmartEvent obj) { int?sourceId = smartTypeListProvider.Get(SmartType.SmartSource, data => { if (data.IsOnlyTarget) { return(false); } return(data.UsableWithEventTypes == null || data.UsableWithEventTypes.Contains(script.SourceType)); } ); if (!sourceId.HasValue) { return; } int?actionId = smartTypeListProvider.Get(SmartType.SmartAction, data => { return((data.UsableWithEventTypes == null || data.UsableWithEventTypes.Contains(script.SourceType)) && (!data.ImplicitSource || sourceId.Value <= 1 /* @todo: remove this const: this is none or self */)); }); if (!actionId.HasValue) { return; } var actionData = SmartDataManager.GetInstance().GetRawData(SmartType.SmartAction, actionId.Value); SmartTarget target = null; if (actionData.UsesTarget && !actionData.TargetIsSource) { int?targetId = smartTypeListProvider.Get(SmartType.SmartTarget, data => { return((data.UsableWithEventTypes == null || data.UsableWithEventTypes.Contains(script.SourceType)) && (actionData.Targets == null || actionData.Targets.Intersect(data.Types).Any())); }); if (!targetId.HasValue) { return; } target = smartFactory.TargetFactory(targetId.Value); } else if (actionData.TargetIsSource) { target = smartFactory.TargetFactory(sourceId.Value); sourceId = 0; } else { target = smartFactory.TargetFactory(0); } if (actionData.ImplicitSource) { sourceId = 0; } SmartSource source = smartFactory.SourceFactory(sourceId.Value); SmartAction ev = smartFactory.ActionFactory(actionId.Value, source, target); EditActionCommand(ev); obj.Actions.Add(ev); }
private void BuildInsert() { if (_script.Events.Count == 0) { return; } _sql.AppendLine( "INSERT INTO smart_scripts (entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, target_type, target_param1, target_param2, target_param3, target_x, target_y, target_z, target_o, comment) VALUES"); int eventId = 0; List <string> lines = new List <string>(); bool previousWasWait = false; int nextTriggerId = 1000; //@todo: don't use hardcoded IDs!!!! foreach (SmartEvent e in _script.Events) { if (e.Actions.Count == 0) { continue; } e.ActualId = eventId; for (int index = 0; index < e.Actions.Count; ++index) { SmartEvent actualEvent = e; if (previousWasWait) { actualEvent = smartFactory.EventFactory(59); actualEvent.SetParameter(0, nextTriggerId++); } else if (index > 0) { actualEvent = smartFactory.EventFactory(61); } int linkTo = (e.Actions.Count - 1 == index ? 0 : eventId + 1); SmartAction actualAction = e.Actions[index]; if (actualAction.Id == 9999) { linkTo = 0; SmartAction waitAction = actualAction; actualAction = smartFactory.ActionFactory(67, smartFactory.SourceFactory(0), smartFactory.TargetFactory(0)); actualAction.SetParameter(0, nextTriggerId); actualAction.SetParameter(1, waitAction.GetParameter(0).GetValue()); actualAction.SetParameter(2, waitAction.GetParameter(0).GetValue()); previousWasWait = true; } else { previousWasWait = false; } lines.Add(GenerateSingleSai(eventId, actualEvent, actualAction, linkTo)); eventId++; } } _sql.Append(string.Join(",\n", lines)); _sql.AppendLine(";"); }