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; }