static bool GetVariable_Execute(COMMAND_ARGS, UInt32 whichAction) { char varName[256] = { 0 }; TESQuest* quest = NULL; Script* targetScript = NULL; ScriptEventList* targetEventList = NULL; *result = 0; if (!ExtractArgs(paramInfo, arg1, opcodeOffsetPtr, thisObj, arg3, scriptObj, eventList, &varName, &quest)) return true; if (quest) { TESScriptableForm* scriptable = (TESScriptableForm*)Oblivion_DynamicCast(quest, 0, RTTI_TESQuest, RTTI_TESScriptableForm, 0); targetScript = scriptable->script; targetEventList = quest->scriptEventList; } else if (thisObj) { TESScriptableForm* scriptable = (TESScriptableForm*)Oblivion_DynamicCast(thisObj->baseForm, 0, RTTI_TESForm, RTTI_TESScriptableForm, 0); if (scriptable) { targetScript = scriptable->script; targetEventList = thisObj->GetEventList(); } } if (targetScript && targetEventList) { Script::VariableInfo* varInfo = targetScript->GetVariableByName(varName); if (whichAction == eScriptVar_Has) return varInfo ? true : false; else if (varInfo) { ScriptEventList::Var* var = targetEventList->GetVariable(varInfo->idx); if (var) { if (whichAction == eScriptVar_Get) *result = var->data; else if (whichAction == eScriptVar_GetRef) { UInt32* refResult = (UInt32*)result; *refResult = (*(UInt64*)&var->data); } return true; } } } return false; }
Token_Type ScriptToken::ReadFrom(ExpressionEvaluator* context) { UInt8 typeCode = context->ReadByte(); switch (typeCode) { case 'B': case 'b': type = kTokenType_Number; value.num = context->ReadByte(); break; case 'I': case 'i': type = kTokenType_Number; value.num = context->Read16(); break; case 'L': case 'l': type = kTokenType_Number; value.num = context->Read32(); break; case 'Z': type = kTokenType_Number; value.num = context->ReadFloat(); break; case 'S': { type = kTokenType_String; value.str = context->ReadString(); break; } case 'R': type = kTokenType_Ref; refIdx = context->Read16(); value.refVar = context->script->GetVariable(refIdx); if (!value.refVar) type = kTokenType_Invalid; else { type = kTokenType_Form; value.refVar->Resolve(context->eventList); value.formID = value.refVar->form ? value.refVar->form->refID : 0; } break; case 'G': { type = kTokenType_Global; refIdx = context->Read16(); Script::RefVariable* refVar = context->script->GetVariable(refIdx); if (!refVar) { type = kTokenType_Invalid; break; } refVar->Resolve(context->eventList); value.global = OBLIVION_CAST(refVar->form, TESForm, TESGlobal); if (!value.global) type = kTokenType_Invalid; break; } case 'X': { type = kTokenType_Command; refIdx = context->Read16(); UInt16 opcode = context->Read16(); value.cmd = g_scriptCommands.GetByOpcode(opcode); if (!value.cmd) type = kTokenType_Invalid; break; } case 'V': { variableType = context->ReadByte(); switch (variableType) { case Script::eVarType_Array: type = kTokenType_ArrayVar; break; case Script::eVarType_Integer: case Script::eVarType_Float: type = kTokenType_NumericVar; break; case Script::eVarType_Ref: type = kTokenType_RefVar; break; case Script::eVarType_String: type = kTokenType_StringVar; break; default: type = kTokenType_Invalid; } refIdx = context->Read16(); ScriptEventList* eventList = context->eventList; if (refIdx) { Script::RefVariable* refVar = context->script->GetVariable(refIdx); if (refVar) { refVar->Resolve(context->eventList); if (refVar->form) eventList = EventListFromForm(refVar->form); } } UInt16 varIdx = context->Read16(); value.var = NULL; if (eventList) value.var = eventList->GetVariable(varIdx); if (!value.var) type = kTokenType_Invalid; break; } default: { if (typeCode < kOpType_Max) { type = kTokenType_Operator; value.op = &s_operators[typeCode]; } else { context->Error("Unexpected token type %d (%02x) encountered", typeCode, typeCode); type = kTokenType_Invalid; } } } return type; }