FActorInfo *FActorInfo::GetReplacee (bool lookskill) { FName skillrepname; if (lookskill && AllSkills.Size() > (unsigned)gameskill) { skillrepname = AllSkills[gameskill].GetReplacedBy(this->Class->TypeName); if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL) { Printf("Warning: incorrect actor name in definition of skill %s: \n" "non-existent class %s is replaced by class %s\n" "Skill replacement will be ignored for this actor.\n", AllSkills[gameskill].Name.GetChars(), skillrepname.GetChars(), this->Class->TypeName.GetChars()); AllSkills[gameskill].SetReplacedBy(this->Class->TypeName, NAME_None); AllSkills[gameskill].SetReplacement(skillrepname, NAME_None); lookskill = false; } } if (Replacee == NULL && (!lookskill || skillrepname == NAME_None)) { return this; } // The Replacee field is temporarily NULLed to prevent // potential infinite recursion. FActorInfo *savedrep = Replacee; Replacee = NULL; FActorInfo *rep = savedrep; if (lookskill && (skillrepname != NAME_None) && (PClass::FindClass(skillrepname) != NULL)) { rep = PClass::FindClass(skillrepname)->ActorInfo; } rep = rep->GetReplacee (false); Replacee = savedrep; return rep; }
FState * FindStateInClass(AActor * actor, const PClass * type, const char * name) { static TArray<FName> namelist(3); MakeStateNameList(name, &namelist); FActorInfo * info = type->ActorInfo; if (info) return info->FindState(namelist.Size(), &namelist[0], true); return NULL; }
static FState *CheckState(FScanner &sc, PClass *type) { int v=0; if (sc.GetString() && !sc.Crossed) { if (sc.Compare("0")) return NULL; else if (sc.Compare("PARENT")) { FState * state = NULL; sc.MustGetString(); FActorInfo * info = type->ParentClass->ActorInfo; if (info != NULL) { state = info->FindState(FName(sc.String)); } if (sc.GetString ()) { if (sc.Compare ("+")) { sc.MustGetNumber (); v = sc.Number; } else { sc.UnGet (); } } if (state == NULL && v==0) return NULL; if (v!=0 && state==NULL) { sc.ScriptMessage("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars()); FScriptPosition::ErrorCounter++; return NULL; } state+=v; return state; } else { sc.ScriptMessage("Invalid state assignment"); FScriptPosition::ErrorCounter++; } } return NULL; }
//========================================================================== // // For getting a state address from the parent // No attempts have been made to add new functionality here // This is strictly for keeping compatibility with old WADs! // //========================================================================== FState *CheckState(PClass *type) { int v=0; if (SC_GetString() && !sc_Crossed) { if (SC_Compare("0")) return NULL; else if (SC_Compare("PARENT")) { FState * state = NULL; SC_MustGetString(); FActorInfo * info = type->ParentClass->ActorInfo; if (info != NULL) { state = info->FindState(FName(sc_String)); } if (SC_GetString ()) { if (SC_Compare ("+")) { SC_MustGetNumber (); v = sc_Number; } else { SC_UnGet (); } } if (state == NULL && v==0) return NULL; if (v!=0 && state==NULL) { SC_ScriptError("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars()); return NULL; } state+=v; return state; } else SC_ScriptError("Invalid state assignment"); } return NULL; }
FActorInfo *FActorInfo::GetReplacement (bool lookskill) { FName skillrepname; if (lookskill && AllSkills.Size() > (unsigned)gameskill) { skillrepname = AllSkills[gameskill].GetReplacement(this->Class->TypeName); if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL) { Printf("Warning: incorrect actor name in definition of skill %s: \n" "class %s is replaced by non-existent class %s\n" "Skill replacement will be ignored for this actor.\n", AllSkills[gameskill].Name.GetChars(), this->Class->TypeName.GetChars(), skillrepname.GetChars()); AllSkills[gameskill].SetReplacement(this->Class->TypeName, NAME_None); AllSkills[gameskill].SetReplacedBy(skillrepname, NAME_None); lookskill = false; skillrepname = NAME_None; } } if (Replacement == NULL && (!lookskill || skillrepname == NAME_None)) { return this; } // The Replacement field is temporarily NULLed to prevent // potential infinite recursion. FActorInfo *savedrep = Replacement; Replacement = NULL; FActorInfo *rep = savedrep; // Handle skill-based replacement here. It has precedence on DECORATE replacement // in that the skill replacement is applied first, followed by DECORATE replacement // on the actor indicated by the skill replacement. if (lookskill && (skillrepname != NAME_None)) { rep = PClass::FindClass(skillrepname)->ActorInfo; } // Now handle DECORATE replacement chain // Skill replacements are not recursive, contrarily to DECORATE replacements rep = rep->GetReplacement(false); // Reset the temporarily NULLed field Replacement = savedrep; return rep; }