| 166 | bool CheckArgSize(FName fname, FArgumentList &args, int min, int max, FScriptPosition &sc); |
| 167 | |
| 168 | static FxExpression *ResolveGlobalCustomFunction(FxFunctionCall *func, FCompileContext &ctx) |
| 169 | { |
| 170 | auto& ScriptPosition = func->ScriptPosition; |
| 171 | if (func->MethodName == NAME_GetDefaultByType) |
| 172 | { |
| 173 | if (CheckArgSize(NAME_GetDefaultByType, func->ArgList, 1, 1, ScriptPosition)) |
| 174 | { |
| 175 | auto newfunc = new FxGetDefaultByType(func->ArgList[0]); |
| 176 | func->ArgList[0] = nullptr; |
| 177 | delete func; |
| 178 | return newfunc->Resolve(ctx); |
| 179 | } |
| 180 | } |
| 181 | // the following 3 are just for compile time argument validation, they do not affect code generation. |
| 182 | else if (func->MethodName == NAME_SetAction && isDukeEngine()) |
| 183 | { |
| 184 | auto cls = ctx.Function->Variants[0].SelfClass; |
| 185 | if (cls == nullptr || !cls->isClass()) return func; |
| 186 | auto clas = static_cast<PClassType*>(cls)->Descriptor; |
| 187 | if (!clas->IsDescendantOf(RUNTIME_CLASS(Duke3d::DDukeActor))) return func; |
| 188 | if (CheckArgSize(NAME_SetAction, func->ArgList, 1, 1, ScriptPosition)) |
| 189 | { |
| 190 | FxExpression* x; |
| 191 | x = func->ArgList[0] = func->ArgList[0]->Resolve(ctx); |
| 192 | if (x && x->isConstant() && (x->ValueType == TypeName || x->ValueType == TypeString)) |
| 193 | { |
| 194 | auto c = static_cast<FxConstant*>(x); |
| 195 | auto nm = c->GetValue().GetName(); |
| 196 | if (nm == NAME_None) return func; |
| 197 | int pos = Duke3d::LookupAction(clas, nm); |
| 198 | if (pos == 0) |
| 199 | { |
| 200 | ScriptPosition.Message(MSG_ERROR, "Invalid action '%s'", nm.GetChars()); |
| 201 | delete func; |
| 202 | return nullptr; |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | } |
| 207 | else if (func->MethodName == NAME_SetAI && isDukeEngine()) |
| 208 | { |
| 209 | auto cls = ctx.Function->Variants[0].SelfClass; |
| 210 | if (cls == nullptr || !cls->isClass()) return func; |
| 211 | auto clas = static_cast<PClassType*>(cls)->Descriptor; |
| 212 | if (!clas->IsDescendantOf(RUNTIME_CLASS(Duke3d::DDukeActor))) return func; |
| 213 | if (CheckArgSize(NAME_SetAI, func->ArgList, 1, 1, ScriptPosition)) |
| 214 | { |
| 215 | FxExpression* x; |
| 216 | x = func->ArgList[0] = func->ArgList[0]->Resolve(ctx); |
| 217 | if (x && x->isConstant() && (x->ValueType == TypeName || x->ValueType == TypeString)) |
| 218 | { |
| 219 | auto c = static_cast<FxConstant*>(x); |
| 220 | auto nm = c->GetValue().GetName(); |
| 221 | if (nm == NAME_None) return func; |
| 222 | int pos = Duke3d::LookupAI(clas, nm); |
| 223 | if (pos == 0) |
| 224 | { |
| 225 | ScriptPosition.Message(MSG_ERROR, "Invalid AI '%s'", nm.GetChars()); |
nothing calls this directly
no test coverage detected