diff --git a/src/namedef.h b/src/namedef.h index d9d71891e..36a756441 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -270,6 +270,8 @@ xx(MomX) xx(MomY) xx(MomZ) xx(Abs) +xx(ACS_NamedExecuteWithResult) +xx(CallACS) // Various actor names which are used internally xx(MapSpot) diff --git a/src/thingdef/thingdef_exp.cpp b/src/thingdef/thingdef_exp.cpp index 33ef4e01b..773f7ffac 100644 --- a/src/thingdef/thingdef_exp.cpp +++ b/src/thingdef/thingdef_exp.cpp @@ -336,6 +336,18 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls) { return new FxConstant(sc.Float, scpos); } + else if (sc.CheckToken(TK_NameConst)) + { + return new FxConstant(sc.Name, scpos); + } + else if (sc.CheckToken(TK_StringConst)) + { + // String parameters are converted to names. Technically, this should be + // done at a higher level, as needed, but since no functions take string + // arguments and ACS_NamedExecuteWithResult/CallACS need names, this is + // a cheap way to get them working when people use "name" instead of 'name'. + return new FxConstant(FName(sc.String), scpos); + } else if (sc.CheckToken(TK_Random)) { FRandom *rng; diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index effc897df..426310652 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -1868,7 +1868,7 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) newex = new FxCVar(cv, ScriptPosition); } */ - // amd line specials + // and line specials else if ((num = P_FindLineSpecial(Identifier, NULL, NULL))) { ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as line special %d\n", Identifier.GetChars(), num); @@ -2293,9 +2293,18 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) return x->Resolve(ctx); } - int min, max; - int special = P_FindLineSpecial(MethodName.GetChars(), &min, &max); - if (special > 0 && min >= 0) + int min, max, special; + if (MethodName == NAME_ACS_NamedExecuteWithResult || MethodName == NAME_CallACS) + { + special = -ACS_ExecuteWithResult; + min = 1; + max = 5; + } + else + { + special = P_FindLineSpecial(MethodName.GetChars(), &min, &max); + } + if (special != 0 && min >= 0) { int paramcount = ArgList? ArgList->Size() : 0; if (paramcount < min) @@ -2326,7 +2335,10 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) //========================================================================== // +// FxActionSpecialCall // +// If special is negative, then the first argument will be treated as a +// name for ACS_NamedExecuteWithResult. // //========================================================================== @@ -2367,7 +2379,15 @@ FxExpression *FxActionSpecialCall::Resolve(FCompileContext& ctx) { (*ArgList)[i] = (*ArgList)[i]->Resolve(ctx); if ((*ArgList)[i] == NULL) failed = true; - if ((*ArgList)[i]->ValueType != VAL_Int) + if (Special < 0 && i == 0) + { + if ((*ArgList)[i]->ValueType != VAL_Name) + { + ScriptPosition.Message(MSG_ERROR, "Name expected for parameter %d", i); + failed = true; + } + } + else if ((*ArgList)[i]->ValueType != VAL_Int) { if (ctx.lax && ((*ArgList)[i]->ValueType == VAL_Float)) { @@ -2400,6 +2420,7 @@ FxExpression *FxActionSpecialCall::Resolve(FCompileContext& ctx) ExpVal FxActionSpecialCall::EvalExpression (AActor *self) { int v[5] = {0,0,0,0,0}; + int special = Special; if (Self != NULL) { @@ -2410,12 +2431,20 @@ ExpVal FxActionSpecialCall::EvalExpression (AActor *self) { for(unsigned i = 0; i < ArgList->Size(); i++) { - v[i] = (*ArgList)[i]->EvalExpression(self).GetInt(); + if (special < 0) + { + special = -special; + v[i] = -(*ArgList)[i]->EvalExpression(self).GetName(); + } + else + { + v[i] = (*ArgList)[i]->EvalExpression(self).GetInt(); + } } } ExpVal ret; ret.Type = VAL_Int; - ret.Int = P_ExecuteSpecial(Special, NULL, self, false, v[0], v[1], v[2], v[3], v[4]); + ret.Int = P_ExecuteSpecial(special, NULL, self, false, v[0], v[1], v[2], v[3], v[4]); return ret; }