Ticket #2936: relative_templates.diff

File relative_templates.diff, 17.7 KB (added by sanderd17, 9 years ago)

Combined patch, still missing entity.pm fix

  • 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/CCmpObstruction.cpp

     
    112112            "<choice>"
    113113                "<element name='Static'>"
    114114                    "<attribute name='width'>"
    115                         "<ref name='positiveDecimal'/>"
     115                        "<data type='decimal'>"
     116                            "<param name='minExclusive'>0.0</param>"
     117                        "</data>"
    116118                    "</attribute>"
    117119                    "<attribute name='depth'>"
    118                         "<ref name='positiveDecimal'/>"
     120                        "<data type='decimal'>"
     121                            "<param name='minExclusive'>0.0</param>"
     122                        "</data>"
    119123                    "</attribute>"
    120124                "</element>"
    121125                "<element name='Unit'>"
    122126                    "<attribute name='radius'>"
    123                         "<ref name='positiveDecimal'/>"
     127                        "<data type='decimal'>"
     128                            "<param name='minExclusive'>0.0</param>"
     129                        "</data>"
    124130                    "</attribute>"
    125131                "</element>"
    126132                "<element name='Obstructions'>"
     
    138144                                "</attribute>"
    139145                            "</optional>"
    140146                            "<attribute name='width'>"
    141                                 "<ref name='positiveDecimal'/>"
     147                                "<data type='decimal'>"
     148                                    "<param name='minExclusive'>0.0</param>"
     149                                "</data>"
    142150                            "</attribute>"
    143151                            "<attribute name='depth'>"
    144                                 "<ref name='positiveDecimal'/>"
     152                                "<data type='decimal'>"
     153                                    "<param name='minExclusive'>0.0</param>"
     154                                "</data>"
    145155                            "</attribute>"
    146156                        "</element>"
    147157                    "</zeroOrMore>"
  • 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", "sub" mul" and "div", 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>sub</value>"
     1101                    "<value>mul</value>"
     1102                    "<value>div</value>"
     1103                "</choice>"
     1104            "</attribute>"
     1105        "</optional>";
    10951106    std::string schema =
    10961107        "<grammar xmlns='http://relaxng.org/ns/structure/1.0' xmlns:a='http://ns.wildfiregames.com/entity' datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes'>"
     1108            "<define name='decimal'>"
     1109                "<data type='decimal'/>"
     1110                + numericOperation +
     1111            "</define>"
    10971112            "<define name='nonNegativeDecimal'>"
    10981113                "<data type='decimal'><param name='minInclusive'>0</param></data>"
     1114                + numericOperation +
    10991115            "</define>"
    11001116            "<define name='positiveDecimal'>"
    11011117                "<data type='decimal'><param name='minExclusive'>0</param></data>"
     1118                + numericOperation +
    11021119            "</define>"
    11031120            "<define name='anything'>"
    11041121                "<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        SUB,
     85        MUL,
     86        DIV
     87    } op = INVALID;
    8088    bool replacing = false;
    8189    {
    8290        XERO_ITER_ATTR(element, attr)
     
    9199                m_Childs.erase(name);
    92100                replacing = true;
    93101            }
     102            else if (attr.Name == at_op)
     103            {
     104                if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"add")
     105                    op = ADD;
     106                else if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"sub")
     107                    op = SUB;
     108                else if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"mul")
     109                    op = MUL;
     110                else if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"div")
     111                    op = DIV;
     112                else
     113                    LOGWARNING("Invalid op '%ls'", attr.Value);
     114            }
    94115        }
    95116    }
    96117    {
     
    137158
    138159    // Add this element as a child node
    139160    CParamNode& node = m_Childs[name];
     161    if (op != INVALID)
     162    {
     163        // TODO Support parsing of data types other than fixed; log warnings in other cases
     164        fixed oldval = node.ToFixed();
     165        fixed mod = fixed::FromString(CStrW(value));
     166        switch (op)
     167        {
     168        case SUB: mod = -mod;
     169        case ADD:
     170            node.m_Value = (oldval + mod).ToString().FromUTF8();
     171            break;
     172        case MUL:
     173            node.m_Value = (oldval.Multiply(mod)).ToString().FromUTF8();
     174            break;
     175        case DIV:
     176            if (mod.IsZero())
     177            {
     178                // Even though it's undefined, just return the original value
     179                LOGWARNING("Attempted divide-by-zero in '%hs'%ls'.", name, sourceIdentifier ? (" in '" + utf8_from_wstring(sourceIdentifier) + "'") : "");
     180                break;
     181            }
     182            node.m_Value = (oldval / mod).ToString().FromUTF8();
     183            break;
     184        }
     185        hasSetValue = true;
     186    }
    140187    if (!hasSetValue)
    141188        node.m_Value = value;
    142189
     
    150197    XERO_ITER_ATTR(element, attr)
    151198    {
    152199        // Skip special attributes
    153         if (attr.Name == at_replace) continue;
     200        if (attr.Name == at_replace || attr.Name == at_op)
     201            continue;
    154202        // Add any others
    155203        std::string attrName = xmb.GetAttributeString(attr.Name);
    156204        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 == "sub"):
     86        newValue -= templateValue.text
     87    elif (templateValue.attrib == "mul"):
     88        newValue *= templateValue.text
     89    elif (templateValue.attrib == "div"):
     90        newValue /= templateValue.text
     91
    5492def CalcUnit(UnitName, existingUnit = None):
    5593    unit = { 'HP' : "0", "BuildTime" : "0", "Cost" : { 'food' : "0", "wood" : "0", "stone" : "0", "metal" : "0", "population" : "0"},
    5694    'Attack' : { "Melee" : { "Hack" : 0, "Pierce" : 0, "Crush" : 0 }, "Ranged" : { "Hack" : 0, "Pierce" : 0, "Crush" : 0 } },
     
    69107        unit["Parent"] = Template.getroot().get("parent") + ".xml"
    70108
    71109    if (Template.find("./Identity/Civ") != None):
    72         unit['Civ'] = Template.find("./Identity/Civ").text
     110        NumericStatProcess(unit, 'Civ', Template.find("./Identity/Civ"))
    73111
    74112    if (Template.find("./Health/Max") != None):
    75         unit['HP'] = Template.find("./Health/Max").text
     113        NumericStatProcess(unit, 'HP', Template.find("./Health/Max"))
    76114
    77115    if (Template.find("./Cost/BuildTime") != None):
    78         unit['BuildTime'] = Template.find("./Cost/BuildTime").text
     116        NumericStatProcess(unit, 'BuildTime', Template.find("./Cost/BuildTime"))
    79117   
    80118    if (Template.find("./Cost/Resources") != None):
    81119        for type in list(Template.find("./Cost/Resources")):
    82             unit['Cost'][type.tag] = type.text
     120            NumericStatProcess(unit['Cost'], type.tag, type)
    83121
    84122    if (Template.find("./Attack/Melee") != None):
    85123        if (Template.find("./Attack/Melee/RepeatTime") != None):
    86             unit['RepeatRate']["Melee"] = Template.find("./Attack/Melee/RepeatTime").text
     124            NumericStatProcess(unit['RepeatRate'], "Melee", Template.find("./Attack/Melee/RepeatTime"))
    87125        if (Template.find("./Attack/Melee/PrepareTime") != None):
    88             unit['PrepRate']["Melee"] = Template.find("./Attack/Melee/PrepareTime").text
     126            NumericStatProcess(unit['PrepRate'], "Melee", Template.find("./Attack/Melee/PrepareTime"))
    89127        for atttype in AttackTypes:
    90128            if (Template.find("./Attack/Melee/"+atttype) != None):
    91                 unit['Attack']['Melee'][atttype] = Template.find("./Attack/Melee/"+atttype).text
     129                NumericStatProcess(unit['Attack']['Melee'], atttype, Template.find("./Attack/Melee/"+atttype))
    92130        if (Template.find("./Attack/Melee/Bonuses") != None):
    93131            for Bonus in Template.find("./Attack/Melee/Bonuses"):
    94132                Against = []
     
    112150    if (Template.find("./Attack/Ranged") != None):
    113151        unit['Ranged'] = "true"
    114152        if (Template.find("./Attack/Ranged/MaxRange") != None):
    115             unit['Range'] = Template.find("./Attack/Ranged/MaxRange").text
     153            NumericStatProcess(unit, 'Range', Template.find("./Attack/Ranged/MaxRange"))
    116154        if (Template.find("./Attack/Ranged/RepeatTime") != None):
    117             unit['RepeatRate']["Ranged"] = Template.find("./Attack/Ranged/RepeatTime").text
     155            NumericStatProcess(unit['RepeatRate'], "Ranged", Template.find("./Attack/Ranged/RepeatTime"))
    118156        if (Template.find("./Attack/Ranged/PrepareTime") != None):
    119             unit['PrepRate']["Ranged"] = Template.find("./Attack/Ranged/PrepareTime").text
     157            NumericStatProcess(unit['PrepRate'], "Ranged", Template.find("./Attack/Ranged/PrepareTime"))
    120158        for atttype in AttackTypes:
    121159            if (Template.find("./Attack/Ranged/"+atttype) != None):
    122                 unit['Attack']['Ranged'][atttype] = Template.find("./Attack/Ranged/"+atttype).text
     160                NumericStatProcess(unit['Attack']['Ranged'], atttype, Template.find("./Attack/Ranged/"+atttype))
    123161        if (Template.find("./Attack/Ranged/Bonuses") != None):
    124162            for Bonus in Template.find("./Attack/Ranged/Bonuses"):
    125163                Against = []
     
    142180    if (Template.find("./Armour") != None):
    143181        for atttype in AttackTypes:
    144182            if (Template.find("./Armour/"+atttype) != None):
    145                 unit['Armour'][atttype] = Template.find("./Armour/"+atttype).text
     183                NumericStatProcess(unit['Armour'], atttype, Template.find("./Armour/"+atttype))
    146184
    147185    if (Template.find("./UnitMotion") != None):
    148186        if (Template.find("./UnitMotion/WalkSpeed") != None):
    149                 unit['WalkSpeed'] = Template.find("./UnitMotion/WalkSpeed").text
     187                NumericStatProcess(unit, 'WalkSpeed', Template.find("./UnitMotion/WalkSpeed"))
    150188
    151189    if (Template.find("./Identity/VisibleClasses") != None):
    152190        newClasses = Template.find("./Identity/VisibleClasses").text.split(" ")
     
    174212
    175213    rstr += "<td style=\"text-align:right;\">" + Name + "</td>\n"
    176214   
    177     rstr += "<td>" + UnitDict["HP"] + "</td>\n"
     215    rstr += "<td>" + str(UnitDict["HP"]) + "</td>\n"
    178216
    179     rstr += "<td>" + UnitDict["BuildTime"] + "</td>\n"
     217    rstr += "<td>" + str(UnitDict["BuildTime"]) + "</td>\n"
    180218
    181     rstr += "<td>" + UnitDict["WalkSpeed"] + "</td>\n"
     219    rstr += "<td>" + str(UnitDict["WalkSpeed"]) + "</td>\n"
    182220   
    183221    rstr += "<td>" + UnitDict["Cost"]["food"] + "F / " + UnitDict["Cost"]["wood"] + "W / " + UnitDict["Cost"]["stone"] + "S / " + UnitDict["Cost"]["metal"] + "M</td>\n"
    184222
     
    696734        CivUnitComparisons(CivData[Civ],CivData[oCiv])
    697735    f.write("</table>")
    698736
    699 f.write("</body>\n</html>")
    700  No newline at end of file
     737f.write("</body>\n</html>")