public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; string dataString = functionArguments[0].StringValue; ITES5Referencer targetReference = this.referenceFactory.CreateReadReference(dataString, globalScope, multipleScriptsScope, localScope); ITES5Type dataType = this.analyzer.GetFormTypeByEDID(dataString); TES5ObjectCall owner; ITES5Referencer baseReference; if (dataType == TES5BasicType.T_FACTION) { owner = this.objectCallFactory.CreateObjectCall(calledOn, "GetFactionOwner", multipleScriptsScope); baseReference = targetReference; } else { owner = this.objectCallFactory.CreateObjectCall(calledOn, "GetActorOwner", multipleScriptsScope); baseReference = this.objectCallFactory.CreateGetActorBase(targetReference, multipleScriptsScope); } TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(owner, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, baseReference); return(expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4FunctionArguments functionArguments = function.Arguments; TES5ObjectCall functionThis = this.objectCallFactory.CreateObjectCall(this.objectCallFactory.CreateGetActorBase(calledOn, multipleScriptsScope), "GetSex", multipleScriptsScope); int operand; switch ((functionArguments[0].StringValue).ToLower()) { case "male": { operand = 0; break; } case "female": { operand = 1; break; } default: { throw new ConversionException("GetIsSex used with unknown gender."); } } TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(functionThis, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(operand)); return(expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; string arg0String = functionArguments[0].StringValue; ITES5Referencer targetReference = this.referenceFactory.CreateReadReference(arg0String, globalScope, multipleScriptsScope, localScope); var arg0Type = targetReference.TES5Type; string functionName; ITES5Referencer baseReference; if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(arg0Type, TES5BasicType.T_ACTORBASE)) { functionName = "GetActorOwner"; baseReference = targetReference; } else if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(arg0Type, TES5BasicType.T_ACTOR)) { functionName = "GetActorOwner"; baseReference = this.objectCallFactory.CreateGetActorBase(targetReference); } else if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(arg0Type, TES5BasicType.T_FACTION)) { functionName = "GetFactionOwner"; baseReference = targetReference; } else { throw new ConversionException(function.FunctionCall.FunctionName + " should be called with either an ActorBase or a Faction."); } TES5ObjectCall owner = this.objectCallFactory.CreateObjectCall(calledOn, functionName); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(owner, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, baseReference); return(expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { //WTM: Note: Just like DisablePlayerControlsFactory, I want to emulate this: //https://cs.elderscrolls.com/index.php?title=DisablePlayerControls //Player cannot move, wait, activate anything, or access his journal interface. string[] functionNames = new string[] { "IsMovementControlsEnabled", "IsMenuControlsEnabled" /*closest to "IsWaitControlsEnabled" I could find*/, "IsActivateControlsEnabled", "IsJournalControlsEnabled" }; TES5ObjectCall[] objectCalls = functionNames.Select(f => objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Game, f)).ToArray(); ITES5ValueCodeChunk?accumulatedStatement = null; foreach (TES5ObjectCall objectCall in objectCalls) { if (accumulatedStatement == null) { accumulatedStatement = objectCall; } else { accumulatedStatement = TES5ExpressionFactory.CreateLogicalExpression(accumulatedStatement, TES5LogicalExpressionOperator.OPERATOR_AND, objectCall); } } if (accumulatedStatement == null) { throw new NullableException(nameof(accumulatedStatement)); } TES5ComparisonExpression negatedExpression = TES5ExpressionFactory.CreateComparisonExpression(accumulatedStatement, TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL, new TES5Bool(true)); return(negatedExpression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { //GetInCell checks if a cell name starts with the argument string: https://cs.elderscrolls.com/index.php?title=GetInCell //The below will probably not always work. TES4FunctionArguments functionArguments = function.Arguments; ITES4StringValue apiToken = functionArguments[0]; string cellName = apiToken.StringValue; TES5ObjectCall getParentCell = this.objectCallFactory.CreateObjectCall(calledOn, "GetParentCell", multipleScriptsScope); TES5ObjectCall getParentCellName = this.objectCallFactory.CreateObjectCall(getParentCell, "GetName", multipleScriptsScope); int length = cellName.Length; TES5ObjectCallArguments substringArguments = new TES5ObjectCallArguments() { getParentCellName, new TES5Integer(0), new TES5Integer(length) }; TES5ObjectCall substring = this.objectCallFactory.CreateObjectCall(TES5StaticReference.StringUtil, "Substring", multipleScriptsScope, substringArguments); TES4LoadedRecord cellRecord = ESMAnalyzer._instance().FindInTES4Collection(cellName, false); string cellNameWithSpaces = cellRecord.GetSubrecordTrim("FULL"); if (cellNameWithSpaces == null) { cellNameWithSpaces = cellName; } TES5String cellNameTES5String = new TES5String(cellNameWithSpaces); return(TES5ExpressionFactory.CreateComparisonExpression(substring, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, cellNameTES5String)); }
public List <ITES5CodeChunk> GenerateObjectiveHandling(ITES5CodeBlock codeBlock, TES5GlobalScope globalScope, List <int> stageMap) { TES5LocalVariable castedToQuest = new TES5LocalVariable("__temp", TES5BasicType.T_QUEST); TES5Reference referenceToTemp = TES5ReferenceFactory.CreateReferenceToVariable(castedToQuest); List <ITES5CodeChunk> result = new List <ITES5CodeChunk>() { TES5VariableAssignationFactory.CreateAssignation(referenceToTemp, TES5ReferenceFactory.CreateReferenceToSelf(globalScope)) }; TES5LocalScope localScope = codeBlock.CodeScope.LocalScope; localScope.AddVariable(castedToQuest); int i = 0; foreach (var stageTargetState in stageMap) { TES5Integer targetIndex = new TES5Integer(i); if (stageTargetState != 0) { //Should be visible TES5ObjectCallArguments displayedArguments = new TES5ObjectCallArguments() { targetIndex }; TES5ObjectCall isObjectiveDisplayed = new TES5ObjectCall(referenceToTemp, "IsObjectiveDisplayed", displayedArguments); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(isObjectiveDisplayed, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(0)); TES5ObjectCallArguments arguments = new TES5ObjectCallArguments() { targetIndex, new TES5Integer(1) }; TES5ObjectCall showTheObjective = new TES5ObjectCall(referenceToTemp, "SetObjectiveDisplayed", arguments); TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(expression, localScope); branch.MainBranch.CodeScope.AddChunk(showTheObjective); result.Add(branch); } else { TES5ObjectCallArguments displayedArguments = new TES5ObjectCallArguments() { targetIndex }; TES5ObjectCall isObjectiveDisplayed = new TES5ObjectCall(referenceToTemp, "IsObjectiveDisplayed", displayedArguments); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(isObjectiveDisplayed, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(1)); TES5ObjectCallArguments arguments = new TES5ObjectCallArguments() { targetIndex, new TES5Integer(1) }; TES5ObjectCall completeTheObjective = new TES5ObjectCall(referenceToTemp, "SetObjectiveCompleted", arguments); TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(expression, localScope); branch.MainBranch.CodeScope.AddChunk(completeTheObjective); result.Add(branch); } ++i; } return(result); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; ITES5Referencer argument = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(calledOn, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, argument); return(expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; ITES5Referencer functionArgument0Reference = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope); TES5ObjectCall leftParentCell = this.objectCallFactory.CreateObjectCall(calledOn, "GetParentCell"); TES5ObjectCall rightParentCell = this.objectCallFactory.CreateObjectCall(functionArgument0Reference, "GetParentCell"); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(leftParentCell, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, rightParentCell); return(expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; //Made in post-analysis TES5ObjectCall race = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToPlayer(globalScope), "GetRace"); ITES5Referencer checkAgainst = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(race, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, checkAgainst); return(expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; //Made in post-analysis TES5ObjectCall functionThis = this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Weather, "GetCurrentWeather"); ITES5Referencer argument = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(functionThis, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, argument); return(expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; TES5LocalVariable activatorVariable = codeScope.GetVariableWithMeaning(TES5LocalVariableParameterMeaning.ACTIVATOR); if (activatorVariable == null) { throw new ConversionException("isActionRef called in a context where action ref should not be present"); } string dataString = functionArguments[0].StringValue; TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariable(activatorVariable), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, this.referenceFactory.CreateReadReference(dataString, globalScope, multipleScriptsScope, localScope)); return(expression); }
private TES5CodeScope SetUpBranch(TES4CodeBlock block, TES5CodeScope codeScope, TES5FunctionScope blockFunctionScope, ITES5VariableOrProperty variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4BlockParameterList?parameterList = block.BlockParameterList; if (parameterList == null) { return(codeScope); } TES5Reference variableReference = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(variable); TES5LocalScope localScope = codeScope.LocalScope; TES4BlockParameter firstParameter = parameterList.Parameters[0]; ITES5Referencer firstVariableReference = this.referenceFactory.CreateReadReference(firstParameter.BlockParameter, globalScope, multipleScriptsScope, localScope); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(variableReference, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, firstVariableReference); return(SetUpBranch(blockFunctionScope, codeScope, expression)); }
private void SetUpBranch(TES4CodeBlock block, TES5EventCodeBlock newBlock, TES5FunctionScope blockFunctionScope, ITES5VariableOrProperty variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4BlockParameterList parameterList = block.BlockParameterList; if (parameterList == null) { return; } List <TES4BlockParameter> parameterListVariableList = parameterList.Parameters; TES4BlockParameter tesEquippedTarget = parameterListVariableList[0]; TES5LocalScope localScope = newBlock.CodeScope.LocalScope; ITES5Referencer newContainer = this.referenceFactory.CreateReadReference(tesEquippedTarget.BlockParameter, globalScope, multipleScriptsScope, localScope); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariable(variable), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, newContainer); SetUpBranch(blockFunctionScope, newBlock, expression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4FunctionArguments functionArguments = function.Arguments; TES5ObjectCall startSneaking = this.objectCallFactory.CreateObjectCall(calledOn, "StartSneaking", multipleScriptsScope); if (((TES4Integer)functionArguments[0]).IntValue == 0) { //WTM: Change: Since StartSneaking toggles sneaking, we check if the TES4 code wants the user to stop sneaking. //If so, if the user is sneaking, call StartSneaking, which actually stops sneaking if already sneaking. TES5ObjectCall isSneaking = this.objectCallFactory.CreateObjectCall(calledOn, "IsSneaking", multipleScriptsScope); TES5ComparisonExpression playerIsNotSneaking = TES5ExpressionFactory.CreateComparisonExpression(isSneaking, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true)); TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(playerIsNotSneaking, codeScope.LocalScope); branch.MainBranch.CodeScope.AddChunk(startSneaking); return(branch); } return(startSneaking); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { //WTM: Added: This is to prevent these Papyrus messages: /* * Actor is dead, cannot start combat. * Actor has no AI process, cannot start combat. [I might need to use Actor.IsAIEnabled or even Actor.EnableAI(True).] */ TES5ObjectCall isDeadCall = this.objectCallFactory.CreateObjectCall(calledOn, "IsDead"); TES5ComparisonExpression isNotDead = TES5ExpressionFactory.CreateComparisonExpression(isDeadCall, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(false)); TES4FunctionArguments functionArguments = function.Arguments; TES5ObjectCallArguments newArguments = this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope); TES5ObjectCall startCombatCall = this.objectCallFactory.CreateObjectCall(calledOn, "StartCombat", newArguments); TES5Branch ifNotDeadStartCombat = TES5BranchFactory.CreateSimpleBranch(isNotDead, codeScope.LocalScope); ifNotDeadStartCombat.MainBranch.CodeScope.AddChunk(startCombatCall); return(ifNotDeadStartCombat); }
public List <ITES5CodeChunk> GenerateObjectiveHandling(ITES5CodeBlock codeBlock, TES5GlobalScope globalScope, List <int> stageMap) { List <ITES5CodeChunk> result = new List <ITES5CodeChunk>(); //WTM: Change: if (!stageMap.Any()) { return(result); } TES5LocalVariable castedToQuest = new TES5LocalVariable("__temp", TES5BasicType.T_QUEST);//WTM: Note: Why is this variable even necessary? TES5Reference referenceToTemp = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(castedToQuest); TES5SelfReference questSelfReference = TES5ReferenceFactory.CreateReferenceToSelf(globalScope); TES5VariableAssignation tempQuestAssignation = TES5VariableAssignationFactory.CreateAssignation(referenceToTemp, questSelfReference); result.Add(tempQuestAssignation); TES5LocalScope localScope = codeBlock.CodeScope.LocalScope; localScope.AddVariable(castedToQuest); int i = 0; foreach (var stageTargetState in stageMap) { TES5Integer targetIndex = new TES5Integer(i); TES5ObjectCallArguments displayedArguments = new TES5ObjectCallArguments() { targetIndex }; TES5ObjectCall isObjectiveDisplayed = objectCallFactory.CreateObjectCall(referenceToTemp, "IsObjectiveDisplayed", displayedArguments, inference: false); int isObjectiveDisplayedArgument = stageTargetState != 0 ? 0 : 1; TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(isObjectiveDisplayed, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(isObjectiveDisplayedArgument)); TES5ObjectCallArguments arguments = new TES5ObjectCallArguments() { targetIndex, new TES5Integer(1) }; string setObjectiveFunction = stageTargetState != 0 ? "SetObjectiveDisplayed" : "SetObjectiveCompleted"; TES5ObjectCall setObjectiveObjectCall = objectCallFactory.CreateObjectCall(referenceToTemp, setObjectiveFunction, arguments, inference: false); TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(expression, localScope); branch.MainBranch.CodeScope.AddChunk(setObjectiveObjectCall); result.Add(branch); ++i; } return(result); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4FunctionArguments functionArguments = function.Arguments; ITES4StringValue apiToken = functionArguments[0]; string cellEditorID = apiToken.StringValue; string locationPropertyNameWithoutSuffix = cellEditorID + "Location"; string locationPropertyNameWithSuffix = TES5Property.AddPropertyNameSuffix(locationPropertyNameWithoutSuffix); TES5Property?locationProperty = globalScope.TryGetPropertyByName(locationPropertyNameWithSuffix); if (locationProperty == null) { int tes5LocationFormID; if (cellToLocationFinder.TryGetLocationFormID(cellEditorID, out tes5LocationFormID)) { locationProperty = TES5PropertyFactory.ConstructWithTES5FormID(locationPropertyNameWithoutSuffix, TES5BasicType.T_LOCATION, null, tes5LocationFormID); globalScope.AddProperty(locationProperty); } else { TES5ObjectCall getParentCell = this.objectCallFactory.CreateObjectCall(calledOn, "GetParentCell"); TES5ObjectCall getParentCellName = this.objectCallFactory.CreateObjectCall(getParentCell, "GetName"); TES4Record cellRecord = this.esmAnalyzer.GetRecordByEDIDInTES4Collection(cellEditorID); string? cellNameWithSpaces = cellRecord.TryGetSubrecordTrim("FULL"); if (cellNameWithSpaces == null || cellNameWithSpaces.IndexOf("Dummy", StringComparison.OrdinalIgnoreCase) != -1) { cellNameWithSpaces = cellEditorID; } TES5String cellNameTES5String = new TES5String(cellNameWithSpaces); TES5ObjectCallArguments findArguments = new TES5ObjectCallArguments() { getParentCellName, cellNameTES5String }; TES5ObjectCall substring = this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.StringUtil, "Find", findArguments); return(TES5ExpressionFactory.CreateComparisonExpression(substring, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(0))); } } TES5Reference locationReference = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(locationProperty); return(this.objectCallFactory.CreateObjectCall(calledOn, "IsInLocation", new TES5ObjectCallArguments() { locationReference })); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; //WARNING: This is not an exact implementation //According to cs.elderscrolls.com, its about being in the faction AND having an attack on them ( violent crime ) //It"s similar but groups all violent wrongdoings ( including assaults, murders etc ). ITES5Referencer factionReference = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope); TES5ObjectCallArguments arguments = new TES5ObjectCallArguments() { factionReference }; TES5ObjectCall isInFaction = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToPlayer(), "IsInFaction", multipleScriptsScope, arguments); TES5TrueBooleanExpression leftExpression = TES5ExpressionFactory.CreateTrueBooleanExpression(isInFaction); TES5ObjectCall crimeGoldViolent = this.objectCallFactory.CreateObjectCall(factionReference, "GetCrimeGoldViolent", multipleScriptsScope); TES5ComparisonExpression rightExpression = TES5ExpressionFactory.CreateComparisonExpression(crimeGoldViolent, TES5ComparisonExpressionOperator.OPERATOR_GREATER, new TES5Integer(0)); TES5LogicalExpression logicalExpression = TES5ExpressionFactory.CreateLogicalExpression(leftExpression, TES5LogicalExpressionOperator.OPERATOR_AND, rightExpression); return(logicalExpression); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { //WTM: Note: I'd prefer a single method call obviously, but this is the best solution I can imagine. TES5ObjectCall calledOnRaceName = objectCallFactory.CreateObjectCall(objectCallFactory.CreateObjectCall(calledOn, "GetRace", multipleScriptsScope), "GetName", multipleScriptsScope); string[] playableRaces = new string[] { "Altmer", "Argonian", "Bosmer", "Breton", "Dunmer", "Imperial", "Khajiit", "Nord", "Orc", "Redguard" }; ITES5Expression completeStatement = null; foreach (string race in playableRaces) { TES5ComparisonExpression newExpression = TES5ExpressionFactory.CreateComparisonExpression(calledOnRaceName, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5String(race)); if (completeStatement == null) { completeStatement = newExpression; } else { completeStatement = TES5ExpressionFactory.CreateLogicalExpression(completeStatement, TES5LogicalExpressionOperator.OPERATOR_OR, newExpression); } } return(completeStatement); }
public void Modify(TES4CodeBlock block, TES5BlockList blockList, TES5EventCodeBlock newBlock, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5FunctionScope blockFunctionScope = newBlock.FunctionScope; switch (block.BlockType.ToLower()) { case "gamemode": case "scripteffectupdate": { TES5ObjectCall function = this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope, multipleScriptsScope); newBlock.AddChunk(function); if (globalScope.ScriptHeader.BasicScriptType == TES5BasicType.T_QUEST) { TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit(); onInitBlock.AddChunk(function); blockList.Add(onInitBlock); } break; } case "onactivate": { TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit(); TES5ObjectCall function = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "BlockActivation", multipleScriptsScope); onInitBlock.AddChunk(function); blockList.Add(onInitBlock); break; } case "onactorequip": { SetUpBranch(block, newBlock, blockFunctionScope, TES5LocalVariableParameterMeaning.CONTAINER, globalScope, multipleScriptsScope); break; } case "ontriggeractor": { TES4BlockParameterList parameterList = block.BlockParameterList; TES5LocalScope localScope = newBlock.CodeScope.LocalScope; TES5LocalVariable activator = localScope.GetVariableWithMeaning(TES5LocalVariableParameterMeaning.ACTIVATOR); TES5LocalVariable castedToActor = new TES5LocalVariable("akAsActor", TES5BasicType.T_ACTOR); TES5Reference referenceToCastedVariable = TES5ReferenceFactory.CreateReferenceToVariable(castedToActor); TES5Reference referenceToNonCastedVariable = TES5ReferenceFactory.CreateReferenceToVariable(activator); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(referenceToCastedVariable, TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL, new TES5None()); TES5CodeScope newCodeScope = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope); newCodeScope.LocalScope.AddVariable(castedToActor); newCodeScope.AddChunk(TES5VariableAssignationFactory.CreateAssignation(referenceToCastedVariable, referenceToNonCastedVariable)); TES5CodeScope outerBranchCode; if (parameterList != null) { //NOT TESTED List <TES4BlockParameter> parameterListVariableList = parameterList.Parameters; ITES5Referencer targetActor = this.referenceFactory.CreateReadReference(parameterListVariableList[0].BlockParameter, globalScope, multipleScriptsScope, localScope); TES5ComparisonExpression interExpression = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariable(activator), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, targetActor); //TES5CodeScope interBranchCode = PHPFunction.Deserialize<TES5CodeScope>(PHPFunction.Serialize(newBlock.CodeScope));//WTM: Change: Why serialize and then deserialize? TES5CodeScope interBranchCode = newBlock.CodeScope; outerBranchCode = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope); interBranchCode.LocalScope.ParentScope = outerBranchCode.LocalScope; outerBranchCode.AddChunk(new TES5Branch(new TES5SubBranch(interExpression, interBranchCode))); } else { //outerBranchCode = PHPFunction.Deserialize<TES5CodeScope>(PHPFunction.Serialize(newBlock.CodeScope));//WTM: Change: Why serialize and then deserialize? outerBranchCode = newBlock.CodeScope; outerBranchCode.LocalScope.ParentScope = newCodeScope.LocalScope; } newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(expression, outerBranchCode))); newBlock.CodeScope = newCodeScope; break; } case "onadd": { SetUpBranch(block, newBlock, blockFunctionScope, "akNewContainer", globalScope, multipleScriptsScope); break; } case "ondrop": { SetUpBranch(block, newBlock, blockFunctionScope, "akOldContainer", globalScope, multipleScriptsScope); break; } case "onpackagestart": { SetUpBranch(block, newBlock, blockFunctionScope, "akNewPackage", globalScope, multipleScriptsScope); break; } case "onpackagedone": case "onpackagechange": case "onpackageend": { SetUpBranch(block, newBlock, blockFunctionScope, "akOldPackage", globalScope, multipleScriptsScope); break; } case "onalarm": { //@INCONSISTENCE - We don"t account for alarm type. TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "IsAlarmed", multipleScriptsScope), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true)); SetUpBranch(blockFunctionScope, newBlock, expression); break; } /* * * case "onalarm": * { * * this.skyrimGroupEventName = "onhit"; * * if (this.eventArgs[1] != 3) { * //Nothing eelse is supported really.. * this.omit = true; * break; * } * * branch = new TES4ConditionalBranch(); * expression = new TES4Expression(); * leftConstant = new TES4Constant("akAggressor", "ObjectReference"); * //actionConstant = new TES4Constant(this.eventArgs[1],"Package"); * actionConstant = TES4Factories.createReference(this.eventArgs[2], this); * * expression.left_side = leftConstant; * expression.right_side = actionConstant; * expression.comparision_operator = TES4Expression.COMPARISION_OPERATOR_EQUAL; * * codeBlock = new TES4CodeBlock(); * codeBlock.chunks = this.chunks; * * branch.ifs[] = array( * "rawExpression" => "SCRIPT_GENERATED", * "expression" => expression, * "codeBlock" => codeBlock * ); * this.chunks = new TES4ChunkContainer(); * this.chunks.parent = this; * this.chunks.addChunk(branch); * * break; * } */ case "onequip": case "onunequip": { SetUpBranch(block, newBlock, blockFunctionScope, "akActor", globalScope, multipleScriptsScope); break; } } }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { return(TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Weather, "GetCurrentWeather"), "GetClassification"), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(2))); }
public TES5CodeScope Modify(TES4CodeBlock block, TES5BlockList blockList, TES5FunctionScope blockFunctionScope, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { //https://cs.elderscrolls.com/index.php?title=Begin //WTM: Change: Added: I reorganized this method and forced each event to account for the first Oblivion parameter. bool accountedForParameter = false; switch (block.BlockType.ToLower()) { case "gamemode": case "scripteffectupdate": { TES5ObjectCall function = this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope); codeScope.AddChunk(function); if (globalScope.ScriptHeader.ScriptType.NativeType == TES5BasicType.T_QUEST) { TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit(); onInitBlock.AddChunk(function); blockList.Add(onInitBlock); } break; } case "menumode": { TES5ComparisonExpression isInMenuModeComparisonExpression = GetIsInMenuModeComparisonExpression(); codeScope = SetUpBranch(blockFunctionScope, codeScope, isInMenuModeComparisonExpression); accountedForParameter = true; //Skyrim handles menus differently than Oblivion's MenuType. break; } case "onactivate": { TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit(); TES5ObjectCall function = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "BlockActivation"); onInitBlock.AddChunk(function); blockList.Add(onInitBlock); //WTM: Change: Added: The following scripts erroneously add a parameter to their OnActivate block: //MS11BradonCorpse, SE01WaitingRoomScript, SE02LoveLetterScript, SE08Xeddefen03DoorSCRIPT, SE08Xeddefen05DoorSCRIPT, SE32TombEpitaph01SCRIPT, SEHillofSuicidesSCRIPT, SEXidPuzButton1, SEXidPuzButton2, SEXidPuzButton3, SEXidPuzButton4, SEXidPuzButtonSCRIPT, SEXidPuzHungerSCRIPT, XPEbroccaCrematorySCRIPT //But OnActivate does not take a parameter. I'm trying to use the author's intended parameter instead of just ignoring it. codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akActivateRef", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onactorequip": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, TES5LocalVariableParameterMeaning.CONTAINER, globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onadd": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akNewContainer", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onalarm": { //@INCONSISTENCE - We don"t account for CrimeType or Criminal. codeScope.AddChunk(this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Debug, "Trace", new TES5ObjectCallArguments() { new TES5String("This function does not account for OnAlarm's CrimeType or Criminal.") })); ITES5Value isAlarmed = TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "IsAlarmed"), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true)); codeScope = SetUpBranch(blockFunctionScope, codeScope, isAlarmed); accountedForParameter = true; break; } /* * case "onalarm": * { * * this.skyrimGroupEventName = "onhit"; * * if (this.eventArgs[1] != 3) { * //Nothing eelse is supported really.. * this.omit = true; * break; * } * * branch = new TES4ConditionalBranch(); * expression = new TES4Expression(); * leftConstant = new TES4Constant("akAggressor", "ObjectReference"); * //actionConstant = new TES4Constant(this.eventArgs[1],"Package"); * actionConstant = TES4Factories.createReference(this.eventArgs[2], this); * * expression.left_side = leftConstant; * expression.right_side = actionConstant; * expression.comparision_operator = TES4Expression.COMPARISION_OPERATOR_EQUAL; * * codeBlock = new TES4CodeBlock(); * codeBlock.chunks = this.chunks; * * branch.ifs[] = array( * "rawExpression" => "SCRIPT_GENERATED", * "expression" => expression, * "codeBlock" => codeBlock * ); * this.chunks = new TES4ChunkContainer(); * this.chunks.parent = this; * this.chunks.addChunk(branch); * * break; * } */ case "ondeath": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akKiller", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "ondrop": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akOldContainer", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onequip": case "onunequip": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akActor", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onhit": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akAggressor", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onhitwith": { TES4BlockParameterList?parameterList = block.BlockParameterList; if (parameterList != null) { TES5LocalScope localScope = codeScope.LocalScope; ITES5Referencer hitWithCriteria = this.referenceFactory.CreateReadReference(parameterList.Parameters[0].BlockParameter, globalScope, multipleScriptsScope, localScope); TES5SignatureParameter akSource = localScope.FunctionScope.GetParameter("akSource"); TES5ComparisonExpression hitWithEqualsSource = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariableOrProperty(akSource), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, hitWithCriteria); TES5CodeScope newCodeScope = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope); if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(TES5BasicType.T_AMMO, hitWithCriteria.TES5Type)) { newCodeScope.AddChunk(this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Debug, "Trace", new TES5ObjectCallArguments() { new TES5String("OBScript called OnHitWith using Ammo, but it's unlikely Papyrus will handle it properly. When arrows are used, " + akSource.Name + " will be a bow.") })); } newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(hitWithEqualsSource, codeScope))); codeScope = newCodeScope; } accountedForParameter = true; break; } case "onmagiceffecthit": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akEffect", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onpackagestart": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akNewPackage", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onpackagechange": case "onpackagedone": case "onpackageend": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akOldPackage", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onsell": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akSeller", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "onstartcombat": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akTarget", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "ontrigger": { codeScope = SetUpBranch(block, codeScope, blockFunctionScope, "akActivateRef", globalScope, multipleScriptsScope); accountedForParameter = true; break; } case "ontriggeractor": { TES4BlockParameterList? parameterList = block.BlockParameterList; TES5LocalScope localScope = codeScope.LocalScope; ITES5VariableOrProperty activator = localScope.GetVariableWithMeaning(TES5LocalVariableParameterMeaning.ACTIVATOR); TES5LocalVariable castedToActor = new TES5LocalVariable("akAsActor", TES5BasicType.T_ACTOR); TES5Reference referenceToCastedVariable = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(castedToActor); TES5Reference referenceToNonCastedVariable = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(activator); TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(referenceToCastedVariable, TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL, new TES5None()); TES5CodeScope newCodeScope = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope); newCodeScope.AddVariable(castedToActor); newCodeScope.AddChunk(TES5VariableAssignationFactory.CreateAssignation(referenceToCastedVariable, referenceToNonCastedVariable)); TES5CodeScope outerBranchCode = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope); outerBranchCode.LocalScope.CopyVariablesFrom(codeScope.LocalScope); if (parameterList != null) { ITES5Referencer targetActor = this.referenceFactory.CreateReadReference(parameterList.Parameters[0].BlockParameter, globalScope, multipleScriptsScope, localScope); TES5ComparisonExpression interExpression = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariableOrProperty(activator), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, targetActor); outerBranchCode.AddChunk(new TES5Branch(new TES5SubBranch(interExpression, codeScope))); } else { outerBranchCode.AddChunks(codeScope.CodeChunks); } newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(expression, outerBranchCode))); codeScope = newCodeScope; accountedForParameter = true; break; } case "onload": case "onreset": case "ontriggermob": case "scripteffectstart": case "scripteffectfinish": { break; } default: { throw new InvalidOperationException(block.BlockType + " not found."); } } if (!accountedForParameter) { TES4BlockParameterList?parameterList = block.BlockParameterList; if (parameterList != null && parameterList.Parameters.Any()) { throw new ConversionException("Parameter not accounted for in " + block.BlockType + ": " + parameterList.Parameters[0].BlockParameter); } } return(codeScope); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { return(TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToPlayer(), "getSleepState", multipleScriptsScope), TES5ComparisonExpressionOperator.OPERATOR_GREATER, new TES5Integer(2))); }
private TES5ComparisonExpression GetIsInMenuModeComparisonExpression() { return(TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Utility, "IsInMenuMode"), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true))); }