Hi Primal_Savage,
thanks for your swift reply. Yes, I am playing FE:LH and sorry about missing the modding subforum (I had simply been using the forum search to check whether someone else had a similar problem before posting).
Unfortunately, your proposed solution will not work for me, as it simply fixes a champion to a single specific class, while I desire for it to be a flexible tool.
So, after some further research I figured out a few things: First of all I got myself a full list of all attributes used in the GameModifier Xml Elements (There are a few more than offered in the Excel file)in all the 1891 official Xml files in the "English" folder. And yes: There is no attribute found that implies removing an ability.
Well ... if I can't change an existing unit, I guess I'll have to create a new Unit and remove the old one. As it happens, I found a way to create a new champion - I simple call the same attribute as the quest does, that grants you your fame-bases champions (RecruitFreeChampion). With value one that creates an unclassed champion, ready to imprinted upon. Which means I have to somehow remove the old Champion, now that I have created a new one. Dealing damage simply sends him to base with an injury. The PermanentDeath doesn't do a thing (whether alone or in combination with damage). Which left me with the StealSpirit attribute in order to get rid of him. Yay. So now I have a better steal spirit, but that's ok (I always choose the Decalon faction ability, so it's not too much of an advantage). On the other hand, the new Champion is Level 1, so it's still a trade-off (and the reason I made the spell cost no mana). Here's the spell:
Code: xml
- <Spells>
- <SpellDef InternalName="FWN_Spell_Reincarnate">
- <DisplayName>Reincarnate</DisplayName>
- <Description>Have a champion reincarnate into a different life (Warning: Destroys all Equipment)</Description>
- <Image>S_CloudWalk_Painting.png</Image>
- <IconFG>S_CloudWalk_Icon.png</IconFG>
- <AutoUnlock>1</AutoUnlock>
- <SpellBookSortCategory>Unit</SpellBookSortCategory>
- <SpellBookSortSubCategory>Other</SpellBookSortSubCategory>
- <SpellType>Strategic</SpellType>
- <SpellClass>Defensive</SpellClass>
- <SpellSubClass>Other</SpellSubClass>
- <SpellTargetType>FriendlyChampion</SpellTargetType>
- <CasterMustBeSov>1</CasterMustBeSov>
- <Prereq>
- <Type>AbilityBonusOption</Type>
- <Attribute>TheDecalon</Attribute>
- <Target>Player</Target>
- </Prereq>
- <SpellResourceCost>
- <Resource>Mana</Resource>
- <Amount>0</Amount>
- </SpellResourceCost>
- <GameModifier>
- <ModType>Unit</ModType>
- <Attribute>StealSpirit</Attribute>
- </GameModifier>
- <GameModifier InternalName="Reward1">
- <ModType>Player</ModType>
- <Attribute>RecruitFreeChampion</Attribute>
- <Value>1</Value>
- </GameModifier>
- <HitSoundFX>Spell_CloudWalk_01</HitSoundFX>
- <SpellDefEffect>
- <EffectName>S_CloudWalk_Particle</EffectName>
- <LocalPosition>0,0,0</LocalPosition>
- <EffectScale>0.50</EffectScale>
- <EffectDelay>0</EffectDelay>
- <SnapToTerrain>1</SnapToTerrain>
- </SpellDefEffect>
- </SpellDef>
- </Spells>
Cheers,
FWN
Ps.:
Since I did some automation in my search (no way I'd check close to 1900 files manually), I built myself a couple of powershell functions to do this for me. In case you care, here they are:
Code: php
- Function Get-XmlElement
- {
- <#
- .SYNOPSIS
- Searches Xml Documents for elements of the given Name.
-
- .DESCRIPTION
- Searches Xml Documents for elements of the given Name.
- The search is performed recursively.
-
- This function can be passed either XmlDocument objects, or FileInfo objects that aim at Xml files.
-
- .PARAMETER Document
- The XmlDocument to be searched for ChildElements of the given Name.
-
- .PARAMETER File
- The Xml File that is to be searched for ChildElements of the given Name.
-
- .PARAMETER Name
- The Name of the Element to be searched for.
-
- .EXAMPLE
- PS C:\> dir "C:\temp" -recurse | Where {$_.Extension -eq ".xml"} | Get-XmlElement -Name "GameModifier"
-
- This will search the folder "C:\temp" and all its child folders for Xml files, then search each such file for Elements named "GameModifier" and return these Elements.
- #>
- [CmdletBinding()]
- Param (
- [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = "Document")]
- [System.Xml.XmlDocument]
- $Document,
-
- [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = "File")]
- [System.IO.FileInfo]
- $File,
-
- [Parameter(Mandatory = $true)]
- [String]
- $Name
- )
-
- Begin
- {
- # Store the calling function's name
- $ParSet = $CmdletBinding.ParameterSetName
-
- # Store the counter that measures the amount of child-nodes searched
- $script:iterations = 0
-
- #region Recursive Search Function
- Function Get-MemberNode
- {
- <#
- .SYNOPSIS
- Function that searches all children nodes recursively, until either a match or dead end is reached
- #>
- Param (
- $Node
- )
- $script:iterations++
-
- $Props = $Node | Get-Member -MemberType 'Property'
-
- $Results = @()
- foreach ($p in $Props)
- {
- $type = ($p.Definition -split " " | Select -First 1)
- $pname = $p.Name
-
- if (($p.Name -eq $Name) -and ($type -eq "System.Xml.XmlElement")) { $Results += $Node.$pname }
- elseif (($p.Name -eq $Name) -and ($type -eq "System.Object[]")) { $Results += $Node.$pname }
- elseif ($type -eq "System.Object[]") { $Node.$pname | %{ $Results += Get-MemberNode $_ } }
- elseif ($type -eq "System.Xml.XmlElement") { $Results += Get-MemberNode $Node.$pname }
- }
- Return $Results
- }
- #endregion Recursive Search Function
- }
- Process
- {
- if ($ParSet -eq "Document")
- {
- foreach ($Doc in $Document)
- {
- Get-MemberNode $Doc
- }
- }
- else
- {
- foreach ($f in $File)
- {
- $Xml = $null
- [Xml]$Xml = Get-Content $f.FullName
- Get-MemberNode $xml
- }
- }
- }
- End
- {
- # Report the number of nodes searched
- Write-Verbose "Elements searched: $Iterations"
- }
- }
... and ...
Code: php
- Function Write-XmlDocument
- {
- <#
- .SYNOPSIS
- Combines a number of Xml Elements into a new Xml Document
-
- .DESCRIPTION
- Combines a number of Xml Elements into a new Xml Document
-
- .PARAMETER Element
- The Elements to join into one document.
-
- .PARAMETER XmlStructure
- The Basic XmlStructure of the Document. Example:
-
- if set to @("Configuration","Computer") the document would look like this:
- <Configuration>
- <Computer>
- <Element1>
- ...
- </Element1>
- <Element2>
- ...
- </Element2>
- ...
- <ElementN>
- ...
- </ElementN>
- </Computer>
- </Configuration>
-
- .PARAMETER Path
- The full path, including Filename, that the Document shall be written to.
- The containing Folder needs to exist, however the file needs not.
-
- .PARAMETER Encoding
- Default: UTF8
- The encoding of the Xml File
-
- .EXAMPLE
- PS C:\> $Elements | Write-XmlDocument -XmlStructure @("AbilityBonuses) -Path "C:\Temp\NewAbilityBonuses"
-
- This will create a new Xml Document with all Elements stored beneath the root Element <AbilityBonuses>
- #>
- [CmdletBinding()]
- Param (
- [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
- [System.Xml.XmlElement[]]
- $Element,
-
- [Parameter(Mandatory = $true)]
- [String[]]
- $XmlStructure,
-
- [Parameter(Mandatory = $true)]
- [String]
- $Path,
-
- [System.Text.Encoding]
- $Encoding = [System.Text.Encoding]::UTF8
- )
-
- Begin
- {
- try
- {
- # Create XmlWriter
- [System.Xml.XmlTextWriter]$Writer = New-Object System.Xml.XmlTextWriter($Path, $Encoding)
-
- # Configure Xml Writer
- $Writer.Indentation = 4
- $Writer.Formatting = [System.Xml.Formatting]::Indented
-
- # Create Xml Structure
- $XmlStructure | %{ $Writer.WriteStartElement($_) }
-
- # Create Counter
- $Count = 0
- }
- catch
- {
- throw (New-Object System.InvalidOperationException("An Error occured while initializing the new Xml Document: $($_.Exception.Message)", $_.Exception))
- }
- }
- Process
- {
- foreach ($e in $Element)
- {
- $e.WriteTo($Writer)
- $Count++
- }
- }
- End
- {
- # Commit Xml to file
- $Writer.Flush()
-
- # Report results
- Write-Verbose "Operation finished, $Count Elements written to $Path"
- }
- }
They were built with Powershell 3.0+ in mind (Windows 8+), but may work with version 2 (Windows 7) as well. Usage may require some commandline skills (But neither edits existing files, except the single file specified in Write-XmlDocument, so they are safe to use).
PPs.: The Codeblock header may be saying it's PHP. It's not. PHP simply comes closest to Powershell in terms of formatting.