Ticket #2936: relative_templates_r16964.patch

File relative_templates_r16964.patch, 15.5 KB (added by Itms, 9 years ago)
  • source/simulation2/components/CCmpFootprint.cpp

     
    5959            "<choice>"
    6060                "<element name='Square' a:help='Set the footprint to a square of the given size'>"
    6161                    "<attribute name='width' a:help='Size of the footprint along the left/right direction (in metres)'>"
    62                         "<ref name='positiveDecimal'/>"
     62                        "<data type='decimal'>"
     63                            "<param name='minExclusive'>0.0</param>"
     64                        "</data>"
    6365                    "</attribute>"
    6466                    "<attribute name='depth' a:help='Size of the footprint along the front/back direction (in metres)'>"
    65                         "<ref name='positiveDecimal'/>"
     67                        "<data type='decimal'>"
     68                            "<param name='minExclusive'>0.0</param>"
     69                        "</data>"
    6670                    "</attribute>"
    6771                "</element>"
    6872                "<element name='Circle' a:help='Set the footprint to a circle of the given size'>"
    6973                    "<attribute name='radius' a:help='Radius of the footprint (in metres)'>"
    70                         "<ref name='positiveDecimal'/>"
     74                        "<data type='decimal'>"
     75                            "<param name='minExclusive'>0.0</param>"
     76                        "</data>"
    7177                    "</attribute>"
    7278                "</element>"
    7379            "</choice>"
  • source/simulation2/components/CCmpVisualActor.cpp

     
    146146                        "</element>"
    147147                        "<element name='Box' a:help='Sets the selection shape to a box of specified dimensions'>"
    148148                            "<attribute name='width'>"
    149                                 "<ref name='positiveDecimal' />"
     149                                "<data type='decimal'>"
     150                                    "<param name='minExclusive'>0.0</param>"
     151                                "</data>"
    150152                            "</attribute>"
    151153                            "<attribute name='height'>"
    152                                 "<ref name='positiveDecimal' />"
     154                                "<data type='decimal'>"
     155                                    "<param name='minExclusive'>0.0</param>"
     156                                "</data>"
    153157                            "</attribute>"
    154158                            "<attribute name='depth'>"
    155                                 "<ref name='positiveDecimal' />"
     159                                "<data type='decimal'>"
     160                                    "<param name='minExclusive'>0.0</param>"
     161                                "</data>"
    156162                            "</attribute>"
    157163                        "</element>"
    158164                        "<element name='Cylinder' a:help='Sets the selection shape to a cylinder of specified dimensions'>"
    159165                            "<attribute name='radius'>"
    160                                 "<ref name='positiveDecimal' />"
     166                                "<data type='decimal'>"
     167                                    "<param name='minExclusive'>0.0</param>"
     168                                "</data>"
    161169                            "</attribute>"
    162170                            "<attribute name='height'>"
    163                                 "<ref name='positiveDecimal' />"
     171                                "<data type='decimal'>"
     172                                    "<param name='minExclusive'>0.0</param>"
     173                                "</data>"
    164174                            "</attribute>"
    165175                        "</element>"
    166176                    "</choice>"
  • source/simulation2/docs/SimulationDocs.h

     
    297297- <code>&lt;text/></code>
    298298- <code>&lt;data type='boolean'/></code>
    299299- <code>&lt;data type='decimal'/></code>
     300- <code>&lt;data type='integer'/></code>
    300301- <code>&lt;data type='nonNegativeInteger'/></code>
    301302- <code>&lt;data type='positiveInteger'/></code>
     303- <code>&lt;ref name='decimal'/></code>
    302304- <code>&lt;ref name='nonNegativeDecimal'/></code>
    303305- <code>&lt;ref name='positiveDecimal'/></code>
    304306
    305 (The last two are slightly different since they're not standard data types.)
    306307
     308The <code>&lt;data&gt;</code> elements are native elements, while the <code>&lt;ref&gt;</code> elements are elements added for our engine. These non-native elements allow the definition of an operation that depends on the parent template. Possible operations are "add" and "mul", and can be applied as the example below.
     309
     310Say the parent template is
     311@code
     312<Entity>
     313  <Example>
     314    <Name>Semi-Humanoids</Name>
     315    <Height>9000</Height>
     316    <Eyes/>
     317  </Example>
     318  <!-- ... other components ... -->
     319</Entity>
     320@endcode
     321and the child template appears like
     322@code
     323<Entity>
     324  <Example>
     325    <Name>Barney</Name>
     326    <Height op="add">5</Height>
     327    <Eyes/>
     328  </Example>
     329  <!-- ... other components ... -->
     330</Entity>
     331@endcode
     332then Barney would have a height of 9005.
     333
    307334Elements can be wrapped in <code>&lt;optional></code>.
    308335Groups of elements can be wrapped in <code>&lt;choice></code> to allow only one of them.
    309336The content of an <code>&lt;element></code> can be further nested elements, but note that
  • source/simulation2/system/ComponentManager.cpp

     
    10921092
    10931093std::string CComponentManager::GenerateSchema()
    10941094{
     1095    std::string numericOperation =
     1096        "<optional>"
     1097            "<attribute name='op'>"
     1098                "<choice>"
     1099                    "<value>add</value>"
     1100                    "<value>mul</value>"
     1101                "</choice>"
     1102            "</attribute>"
     1103        "</optional>";
    10951104    std::string schema =
    10961105        "<grammar xmlns='http://relaxng.org/ns/structure/1.0' xmlns:a='http://ns.wildfiregames.com/entity' datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes'>"
     1106            "<define name='decimal'>"
     1107                "<data type='decimal'/>"
     1108                + numericOperation +
     1109            "</define>"
    10971110            "<define name='nonNegativeDecimal'>"
    10981111                "<data type='decimal'><param name='minInclusive'>0</param></data>"
     1112                + numericOperation +
    10991113            "</define>"
    11001114            "<define name='positiveDecimal'>"
    11011115                "<data type='decimal'><param name='minExclusive'>0</param></data>"
     1116                + numericOperation +
    11021117            "</define>"
    11031118            "<define name='anything'>"
    11041119                "<zeroOrMore>"
  • source/simulation2/system/ParamNode.cpp

     
    7676    // Look for special attributes
    7777    int at_disable = xmb.GetAttributeID("disable");
    7878    int at_replace = xmb.GetAttributeID("replace");
     79    int at_op = xmb.GetAttributeID("op");
    7980    int at_datatype = xmb.GetAttributeID("datatype");
     81    enum op {
     82        INVALID,
     83        ADD,
     84        MUL
     85    } op = INVALID;
    8086    bool replacing = false;
    8187    {
    8288        XERO_ITER_ATTR(element, attr)
     
    9197                m_Childs.erase(name);
    9298                replacing = true;
    9399            }
     100            else if (attr.Name == at_op)
     101            {
     102                if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"add")
     103                    op = ADD;
     104                else if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"mul")
     105                    op = MUL;
     106                else
     107                    LOGWARNING("Invalid op '%ls'", attr.Value);
     108            }
    94109        }
    95110    }
    96111    {
     
    137152
    138153    // Add this element as a child node
    139154    CParamNode& node = m_Childs[name];
     155    if (op != INVALID)
     156    {
     157        // TODO Support parsing of data types other than fixed; log warnings in other cases
     158        fixed oldval = node.ToFixed();
     159        fixed mod = fixed::FromString(CStrW(value));
     160        switch (op)
     161        {
     162        case ADD:
     163            node.m_Value = (oldval + mod).ToString().FromUTF8();
     164            break;
     165        case MUL:
     166            node.m_Value = (oldval.Multiply(mod)).ToString().FromUTF8();
     167            break;
     168        }
     169        hasSetValue = true;
     170    }
    140171    if (!hasSetValue)
    141172        node.m_Value = value;
    142173
     
    150181    XERO_ITER_ATTR(element, attr)
    151182    {
    152183        // Skip special attributes
    153         if (attr.Name == at_replace) continue;
     184        if (attr.Name == at_replace || attr.Name == at_op)
     185            continue;
    154186        // Add any others
    155187        std::string attrName = xmb.GetAttributeString(attr.Name);
    156188        node.m_Childs["@" + attrName].m_Value = attr.Value.FromUTF8();
  • source/tools/templatesanalyzer/CreateRMTest.py

     
     1'''
     2* CreateRMTest.py
     3*
     4* Copyright (C) 2015 Wildfire Games.
     5*
     6* Permission is hereby granted, free of charge, to any person obtaining a copy
     7* of this software and associated documentation files (the "Software"), to deal
     8* in the Software without restriction, including without limitation the rights
     9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10* copies of the Software, and to permit persons to whom the Software is
     11* furnished to do so, subject to the following conditions:
     12
     13* The above copyright notice and this permission notice shall be included in
     14* all copies or substantial portions of the Software.
     15
     16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22* THE SOFTWARE.
     23'''
     24
    125import xml.etree.ElementTree as ET
    226import os
    327
  • source/tools/templatesanalyzer/unitTables.py

     
     1'''
     2* unitTables.py
     3*
     4* Copyright (C) 2015 Wildfire Games.
     5*
     6* Permission is hereby granted, free of charge, to any person obtaining a copy
     7* of this software and associated documentation files (the "Software"), to deal
     8* in the Software without restriction, including without limitation the rights
     9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10* copies of the Software, and to permit persons to whom the Software is
     11* furnished to do so, subject to the following conditions:
     12
     13* The above copyright notice and this permission notice shall be included in
     14* all copies or substantial portions of the Software.
     15
     16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22* THE SOFTWARE.
     23'''
     24
    125import xml.etree.ElementTree as ET
    226import os
    327import glob
     
    5175def htout(file, value):
    5276    file.write("<p>" + value + "</p>\n" )
    5377
     78def NumericStatProcess(unit, newValue, templateValue):
     79    if (newValue not in unit):
     80        unit[newValue] = 0; # This is kind of a sanity hack.
     81    if (templateValue.attrib == {}):
     82        unit[newValue] = templateValue.text
     83    elif (templateValue.attrib == "add"):
     84        newValue += templateValue.text
     85    elif (templateValue.attrib == "mul"):
     86        newValue *= templateValue.text
     87
    5488def CalcUnit(UnitName, existingUnit = None):
    5589    unit = { 'HP' : "0", "BuildTime" : "0", "Cost" : { 'food' : "0", "wood" : "0", "stone" : "0", "metal" : "0", "population" : "0"},
    5690    'Attack' : { "Melee" : { "Hack" : 0, "Pierce" : 0, "Crush" : 0 }, "Ranged" : { "Hack" : 0, "Pierce" : 0, "Crush" : 0 } },
     
    69103        unit["Parent"] = Template.getroot().get("parent") + ".xml"
    70104
    71105    if (Template.find("./Identity/Civ") != None):
    72         unit['Civ'] = Template.find("./Identity/Civ").text
     106        NumericStatProcess(unit, 'Civ', Template.find("./Identity/Civ"))
    73107
    74108    if (Template.find("./Health/Max") != None):
    75         unit['HP'] = Template.find("./Health/Max").text
     109        NumericStatProcess(unit, 'HP', Template.find("./Health/Max"))
    76110
    77111    if (Template.find("./Cost/BuildTime") != None):
    78         unit['BuildTime'] = Template.find("./Cost/BuildTime").text
     112        NumericStatProcess(unit, 'BuildTime', Template.find("./Cost/BuildTime"))
    79113   
    80114    if (Template.find("./Cost/Resources") != None):
    81115        for type in list(Template.find("./Cost/Resources")):
    82             unit['Cost'][type.tag] = type.text
     116            NumericStatProcess(unit['Cost'], type.tag, type)
    83117
    84118    if (Template.find("./Attack/Melee") != None):
    85119        if (Template.find("./Attack/Melee/RepeatTime") != None):
    86             unit['RepeatRate']["Melee"] = Template.find("./Attack/Melee/RepeatTime").text
     120            NumericStatProcess(unit['RepeatRate'], "Melee", Template.find("./Attack/Melee/RepeatTime"))
    87121        if (Template.find("./Attack/Melee/PrepareTime") != None):
    88             unit['PrepRate']["Melee"] = Template.find("./Attack/Melee/PrepareTime").text
     122            NumericStatProcess(unit['PrepRate'], "Melee", Template.find("./Attack/Melee/PrepareTime"))
    89123        for atttype in AttackTypes:
    90124            if (Template.find("./Attack/Melee/"+atttype) != None):
    91                 unit['Attack']['Melee'][atttype] = Template.find("./Attack/Melee/"+atttype).text
     125                NumericStatProcess(unit['Attack']['Melee'], atttype, Template.find("./Attack/Melee/"+atttype))
    92126        if (Template.find("./Attack/Melee/Bonuses") != None):
    93127            for Bonus in Template.find("./Attack/Melee/Bonuses"):
    94128                Against = []
     
    112146    if (Template.find("./Attack/Ranged") != None):
    113147        unit['Ranged'] = "true"
    114148        if (Template.find("./Attack/Ranged/MaxRange") != None):
    115             unit['Range'] = Template.find("./Attack/Ranged/MaxRange").text
     149            NumericStatProcess(unit, 'Range', Template.find("./Attack/Ranged/MaxRange"))
    116150        if (Template.find("./Attack/Ranged/RepeatTime") != None):
    117             unit['RepeatRate']["Ranged"] = Template.find("./Attack/Ranged/RepeatTime").text
     151            NumericStatProcess(unit['RepeatRate'], "Ranged", Template.find("./Attack/Ranged/RepeatTime"))
    118152        if (Template.find("./Attack/Ranged/PrepareTime") != None):
    119             unit['PrepRate']["Ranged"] = Template.find("./Attack/Ranged/PrepareTime").text
     153            NumericStatProcess(unit['PrepRate'], "Ranged", Template.find("./Attack/Ranged/PrepareTime"))
    120154        for atttype in AttackTypes:
    121155            if (Template.find("./Attack/Ranged/"+atttype) != None):
    122                 unit['Attack']['Ranged'][atttype] = Template.find("./Attack/Ranged/"+atttype).text
     156                NumericStatProcess(unit['Attack']['Ranged'], atttype, Template.find("./Attack/Ranged/"+atttype))
    123157        if (Template.find("./Attack/Ranged/Bonuses") != None):
    124158            for Bonus in Template.find("./Attack/Ranged/Bonuses"):
    125159                Against = []
     
    142176    if (Template.find("./Armour") != None):
    143177        for atttype in AttackTypes:
    144178            if (Template.find("./Armour/"+atttype) != None):
    145                 unit['Armour'][atttype] = Template.find("./Armour/"+atttype).text
     179                NumericStatProcess(unit['Armour'], atttype, Template.find("./Armour/"+atttype))
    146180
    147181    if (Template.find("./UnitMotion") != None):
    148182        if (Template.find("./UnitMotion/WalkSpeed") != None):
    149                 unit['WalkSpeed'] = Template.find("./UnitMotion/WalkSpeed").text
     183                NumericStatProcess(unit, 'WalkSpeed', Template.find("./UnitMotion/WalkSpeed"))
    150184
    151185    if (Template.find("./Identity/VisibleClasses") != None):
    152186        newClasses = Template.find("./Identity/VisibleClasses").text.split(" ")
     
    174208
    175209    rstr += "<td style=\"text-align:right;\">" + Name + "</td>\n"
    176210   
    177     rstr += "<td>" + UnitDict["HP"] + "</td>\n"
     211    rstr += "<td>" + str(UnitDict["HP"]) + "</td>\n"
    178212
    179     rstr += "<td>" + UnitDict["BuildTime"] + "</td>\n"
     213    rstr += "<td>" + str(UnitDict["BuildTime"]) + "</td>\n"
    180214
    181     rstr += "<td>" + UnitDict["WalkSpeed"] + "</td>\n"
     215    rstr += "<td>" + str(UnitDict["WalkSpeed"]) + "</td>\n"
    182216   
    183217    rstr += "<td>" + UnitDict["Cost"]["food"] + "F / " + UnitDict["Cost"]["wood"] + "W / " + UnitDict["Cost"]["stone"] + "S / " + UnitDict["Cost"]["metal"] + "M</td>\n"
    184218
     
    696730        CivUnitComparisons(CivData[Civ],CivData[oCiv])
    697731    f.write("</table>")
    698732
    699 f.write("</body>\n</html>")
    700  No newline at end of file
     733f.write("</body>\n</html>")