Exemplo n.º 1
0
        public override void Serialize <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s)
        {
            base.Serialize(s);
            var xs = s.GetSerializerInterface();

            s.StreamElementEnumOpt("Type", ref mType, e => e != BAbilityType.Invalid);
            s.StreamElementOpt("AmmoCost", ref mAmmoCost, Predicates.IsNotZero);
            s.StreamElements("Object", ObjectIDs, xs, XML.BDatabaseXmlSerializerBase.StreamObjectID);
            s.StreamElementEnumOpt("SquadMode", ref mSquadMode, e => e != BSquadMode.Invalid);
            s.StreamElementEnumOpt("RecoverStart", ref mRecoverStart, e => e != BRecoverType.Move);
            s.StreamElementEnumOpt("RecoverType", ref mRecoverType, e => e != BRecoverType.Move);
            s.StreamElementOpt("RecoverTime", ref mRecoverTime, Predicates.IsNotZero);
            s.StreamElementOpt("MovementSpeedModifier", ref mMovementSpeedModifier, Predicates.IsNotZero);
            s.StreamElementEnumOpt("MovementModifierType", ref mMovementModifierType, e => e != BMovementModifierType.Mode);
            s.StreamElementOpt("DamageTakenModifier", ref mDamageTakenModifier, Predicates.IsNotZero);
            s.StreamElementOpt("DodgeModifier", ref mDodgeModifier, Predicates.IsNotZero);
            s.StreamStringOpt("Icon", ref mIcon, toLower: false, type: XML.XmlUtil.kSourceElement);
            s.StreamElementEnumOpt("TargetType", ref mTargetType, e => e != BAbilityTargetType.None);
            s.StreamStringOpt("RecoverAnimAttachment", ref mRecoverAnimAttachment, toLower: false, type: XML.XmlUtil.kSourceElement);
            s.StreamStringOpt("RecoverStartAnim", ref mRecoverStartAnim, toLower: false, type: XML.XmlUtil.kSourceElement);
            s.StreamStringOpt("RecoverEndAnim", ref mRecoverEndAnim, toLower: false, type: XML.XmlUtil.kSourceElement);
            s.StreamElementOpt("Sprinting", ref mSprinting, Predicates.IsTrue);
            s.StreamElementOpt("DontInterruptAttack", ref mDontInterruptAttack, Predicates.IsTrue);
            s.StreamElementOpt("KeepSquadMode", ref mKeepSquadMode, Predicates.IsTrue);
            s.StreamElementOpt("AttackSquadMode", ref mAttackSquadMode, Predicates.IsTrue);
            s.StreamElementOpt("Duration", ref mDuration, Predicates.IsNotZero);
            s.StreamElementOpt("SmartTargetRange", ref mSmartTargetRange, v => v != cDefaultSmartTargetRange);
            s.StreamElementOpt("CanHeteroCommand", ref mCanHeteroCommand, Predicates.IsFalse);
            s.StreamElementOpt("NoAbilityReticle", ref mNoAbilityReticle, Predicates.IsTrue);
        }
Exemplo n.º 2
0
        public static bool StreamProtoEnum <TDoc, TCursor>(this IO.TagElementStream <TDoc, TCursor, string> s
                                                           , string xmlName, ref int dbid
                                                           , Collections.IProtoEnum protoEnum
                                                           , bool isOptional            = true, IO.TagElementNodeType xmlSource = XML.XmlUtil.kSourceElement
                                                           , int isOptionalDefaultValue = TypeExtensions.kNone)
            where TDoc : class
            where TCursor : class
        {
            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));
            Contract.Requires(protoEnum != null);

            string id_name      = null;
            bool   was_streamed = true;
            bool   to_lower     = false;

            if (s.IsReading)
            {
                if (isOptional)
                {
                    was_streamed = s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }

                if (was_streamed)
                {
                    dbid = protoEnum.TryGetMemberId(id_name);
                    Contract.Assert(dbid.IsNotNone(), id_name);
                }
                //else
                //	dbid = isOptionalDefaultValue;
            }
            else if (s.IsWriting)
            {
                if (isOptional && isOptionalDefaultValue.IsNotNone() && isOptionalDefaultValue == dbid)
                {
                    was_streamed = false;
                    return(was_streamed);
                }

                id_name = protoEnum.TryGetMemberName(dbid);
                if (id_name.IsNullOrEmpty())
                {
                    Contract.Assert(!id_name.IsNullOrEmpty(), dbid.ToString());
                }

                if (isOptional)
                {
                    s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
            }

            return(was_streamed);
        }
Exemplo n.º 3
0
        public static bool StreamBVector <TDoc, TCursor>(this IO.TagElementStream <TDoc, TCursor, string> s
                                                         , string xmlName, ref BVector vector
                                                         , bool isOptional = true, IO.TagElementNodeType xmlSource = XML.XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));

            string     string_value = null;
            bool       was_streamed = true;
            const bool to_lower     = false;

            if (s.IsReading)
            {
                if (isOptional)
                {
                    was_streamed = s.StreamStringOpt(xmlName, ref string_value, to_lower, xmlSource);
                }
                else
                {
                    s.StreamString(xmlName, ref string_value, to_lower, xmlSource);
                }

                if (was_streamed)
                {
                    var parse_result = PhxUtil.ParseBVectorString(string_value);
                    if (!parse_result.HasValue)
                    {
                        s.ThrowReadException(new System.IO.InvalidDataException(string.Format(
                                                                                    "Failed to parse value (hint: {0}) as vector: {1}",
                                                                                    xmlSource.RequiresName() ? xmlName : "ElementText",
                                                                                    string_value)));
                    }

                    vector = parse_result.Value;
                }
            }
            else if (s.IsWriting)
            {
                if (isOptional && PhxPredicates.IsZero(vector))
                {
                    was_streamed = false;
                    return(was_streamed);
                }

                string_value = vector.ToBVectorString();

                if (isOptional)
                {
                    s.StreamStringOpt(xmlName, ref string_value, to_lower, xmlSource);
                }
                else
                {
                    s.StreamString(xmlName, ref string_value, to_lower, xmlSource);
                }
            }

            return(was_streamed);
        }
Exemplo n.º 4
0
        public static bool StreamIntegerColor <TDoc, TCursor>(this IO.TagElementStream <TDoc, TCursor, string> s
                                                              , string xmlName, ref System.Drawing.Color color
                                                              , byte defaultAlpha = 0xFF
                                                              , bool isOptional   = true, IO.TagElementNodeType xmlSource = XML.XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));

            string     string_value = null;
            bool       was_streamed = true;
            const bool to_lower     = false;

            if (s.IsReading)
            {
                if (isOptional)
                {
                    was_streamed = s.StreamStringOpt(xmlName, ref string_value, to_lower, xmlSource);
                }
                else
                {
                    s.StreamString(xmlName, ref string_value, to_lower, xmlSource);
                }

                if (was_streamed)
                {
                    if (!PhxUtil.TokenizeIntegerColor(string_value, defaultAlpha, ref color))
                    {
                        s.ThrowReadException(new System.IO.InvalidDataException(string.Format(
                                                                                    "Failed to parse value (hint: {0}) as color: {1}",
                                                                                    xmlSource.RequiresName() ? xmlName : "ElementText",
                                                                                    string_value)));
                    }
                }
            }
            else if (s.IsWriting)
            {
                if (isOptional && PhxPredicates.IsZero(color))
                {
                    was_streamed = false;
                    return(was_streamed);
                }

                string_value = color.ToIntegerColorString(defaultAlpha);

                if (isOptional)
                {
                    s.StreamStringOpt(xmlName, ref string_value, to_lower, xmlSource);
                }
                else
                {
                    s.StreamString(xmlName, ref string_value, to_lower, xmlSource);
                }
            }

            return(was_streamed);
        }
Exemplo n.º 5
0
        internal bool StreamID <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s, string xmlName, ref int dbid,
                                               TacticDataObjectKind kind,
                                               bool isOptional = true, IO.TagElementNodeType xmlSource = XML.XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));
            Contract.Requires(kind != TacticDataObjectKind.None);

            string id_name      = null;
            bool   was_streamed = true;
            bool   to_lower     = false;

            if (s.IsReading)
            {
                if (isOptional)
                {
                    was_streamed = s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }

                if (was_streamed)
                {
                    IProtoDataObjectDatabaseProvider provider = this;
                    dbid = provider.GetId((int)kind, id_name);
                    Contract.Assert(dbid.IsNotNone());
                }
                else
                {
                    dbid = TypeExtensions.kNone;
                }
            }
            else if (s.IsWriting && dbid.IsNotNone())
            {
                IProtoDataObjectDatabaseProvider provider = this;
                id_name = provider.GetName((int)kind, dbid);
                Contract.Assert(!string.IsNullOrEmpty(id_name));

                if (isOptional)
                {
                    s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
            }

            return(was_streamed);
        }
        public bool StreamTactic <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s
                                                 , string xmlName
                                                 , ref int dbid
                                                 , IO.TagElementNodeType xmlSource = XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            const Phx.DatabaseObjectKind kDbKind = Phx.DatabaseObjectKind.Tactic;

            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));

            string id_name      = null;
            bool   was_streamed = true;
            bool   to_lower     = false;

            if (s.IsReading)
            {
                was_streamed = s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);

                if (was_streamed)
                {
                    id_name = System.IO.Path.GetFileNameWithoutExtension(id_name);

                    dbid = Database.GetId(kDbKind, id_name);
                    Contract.Assert(dbid.IsNotNone(), id_name);

                    if (PhxUtil.IsUndefinedReferenceHandle(dbid))
                    {
                        TraceUndefinedHandle(s, id_name, xmlName, dbid, kDbKind.ToString());
                    }
                }
            }
            else if (s.IsWriting)
            {
                if (dbid.IsNone())
                {
                    was_streamed = false;
                    return(was_streamed);
                }

                id_name = Database.GetName(kDbKind, dbid);
                Contract.Assert(!string.IsNullOrEmpty(id_name));

                id_name += Phx.BTacticData.kFileExt;
                s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
            }

            return(was_streamed);
        }
Exemplo n.º 7
0
        public override void Serialize <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s)
        {
            base.Serialize(s);

            var xs = s.GetSerializerInterface();

            s.StreamAttributeOpt("Alpha", ref mAlpha, Predicates.IsNotNone);
            xs.StreamDBID(s, "CivTech", ref mTechID, DatabaseObjectKind.Tech);
            xs.StreamDBID(s, "CommandAckObject", ref mCommandAckObjectID, DatabaseObjectKind.Object);
            xs.StreamDBID(s, "RallyPointObject", ref mRallyPointObjectID, DatabaseObjectKind.Object);
            xs.StreamDBID(s, "LocalRallyPointObject", ref mLocalRallyPointObjectID, DatabaseObjectKind.Object);
            xs.StreamDBID(s, "Transport", ref mTransportObjectID, DatabaseObjectKind.Object);
            xs.StreamDBID(s, "TransportTrigger", ref mTransportTriggerObjectID, DatabaseObjectKind.Object);
            s.StreamElementOpt("ExpandHull", ref mHullExpansionRadius, Predicates.IsNotZero);
            s.StreamElementOpt("TerrainPushOff", ref mTerrainPushOffRadius, Predicates.IsNotZero);
            s.StreamElementOpt("BuildingMagnetRange", ref mBuildingMagnetRange, Predicates.IsNotZero);
            s.StreamStringOpt("SoundBank", ref mSoundBank, toLower: false, type: XML.XmlUtil.kSourceElement);
            xs.StreamStringID(s, "LeaderMenuNameID", ref mLeaderMenuNameID);
            s.StreamElementOpt("PowerFromHero", ref mPowerFromHero, Predicates.IsTrue);
            s.StreamStringOpt("UIControlBackground", ref mUIControlBackground, toLower: false, type: XML.XmlUtil.kSourceElement);
        }
Exemplo n.º 8
0
        public void Serialize <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s)
            where TDoc : class
            where TCursor : class
        {
            s.StreamAttribute("name", ref mName);
            s.StreamStringOpt("yawattachment", ref mYawAttachment, toLower: false);
            s.StreamStringOpt("pitchattachment", ref mPitchAttachment, toLower: false);
            s.StreamAttributeOpt("autocenter", ref mAutoCenter, Predicates.IsFalse);
            s.StreamAttributeOpt("singleboneik", ref mSingleBoneIK, Predicates.IsTrue);
            s.StreamAttributeOpt("combined", ref mCombined, Predicates.IsTrue);
            s.StreamAttributeOpt("hardpitchlimits", ref mHardPitchLimits, Predicates.IsTrue);
            s.StreamAttributeOpt("relativeToUnit", ref mRelativeToUnit, Predicates.IsTrue);
            s.StreamAttributeOpt("useYawAndPitchAsTolerance", ref mUseYawAndPitchAsTolerance, Predicates.IsTrue);
            s.StreamAttributeOpt("infiniteRateWhenHasTarget", ref mInfiniteRateWhenHasTarget, Predicates.IsTrue);
            s.StreamAttributeOpt("yawrate", ref mYawRotationRate, x => x != cPiOver12InDegrees);
            s.StreamAttributeOpt("pitchrate", ref mPitchRotationRate, x => x != cPiOver12InDegrees);

            #region YawLeftMaxAngle and YawRightMaxAngle
            if (s.IsReading)
            {
                float yawMaxAngle = PhxUtil.kInvalidSingleNaN;
                if (s.ReadAttributeOpt("yawMaxAngle", ref yawMaxAngle) ||
                    // #HACK f*****g deal with original HW game data that was hand edited, but only when reading
                    s.ReadAttributeOpt("yawmaxangle", ref yawMaxAngle))
                {
                    mYawLeftMaxAngle  = -yawMaxAngle;
                    mYawRightMaxAngle = yawMaxAngle;
                }

                s.StreamAttributeOpt("YawLeftMaxAngle", ref mYawLeftMaxAngle, x => x != cDefaultYawLeftMaxAngle);
                s.StreamAttributeOpt("YawRightMaxAngle", ref mYawRightMaxAngle, x => x != cDefaultYawRightMaxAngle);
            }
            else if (s.IsWriting)
            {
                if (mYawLeftMaxAngle == cDefaultYawLeftMaxAngle &&
                    mYawRightMaxAngle == cDefaultYawRightMaxAngle)
                {
                    // don't stream anything
                }
                else if (System.Math.Abs(mYawLeftMaxAngle) == mYawRightMaxAngle)
                {
                    s.WriteAttribute("yawMaxAngle", mYawRightMaxAngle);
                }
                else
                {
                    s.StreamAttributeOpt("YawLeftMaxAngle", ref mYawLeftMaxAngle, x => x != cDefaultYawLeftMaxAngle);
                    s.StreamAttributeOpt("YawRightMaxAngle", ref mYawRightMaxAngle, x => x != cDefaultYawRightMaxAngle);
                }
            }
            #endregion

            s.StreamAttributeOpt("pitchMaxAngle", ref mPitchMaxAngle, x => x != cDefaultPitchMaxAngle);
            s.StreamAttributeOpt("pitchMinAngle", ref mPitchMinAngle, x => x != cDefaultPitchMinAngle);

            s.StreamStringOpt("StartYawSound", ref mStartYawSound, toLower: false);
            s.StreamStringOpt("StopYawSound", ref mStopYawSound, toLower: false);
            s.StreamStringOpt("StartPitchSound", ref mStartPitchSound, toLower: false);
            s.StreamStringOpt("StopPitchSound", ref mStopPitchSound, toLower: false);
        }
Exemplo n.º 9
0
        public override void Serialize <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s)
        {
            base.Serialize(s);

            var xs = s.GetSerializerInterface();

            s.StreamAttributeOpt("Icon", ref mIconName, Predicates.IsNotNullOrEmpty);
            s.StreamAttributeOpt("Test", ref mTest, Predicates.IsTrue);
            s.StreamAttributeOpt("Alpha", ref mAlpha, Predicates.IsNotNone);

            s.StreamAttributeOpt("Random", ref mIsRandom, Predicates.IsTrue);
            s.StreamAttributeOpt("StatsID", ref mStatsID, Predicates.IsNotNone);
            s.StreamAttributeOpt("LeaderPickerOrder", ref mLeaderPickerOrder, Predicates.IsNotNone);
            s.StreamAttributeOpt("DefaultPlayerSlotFlags", ref mDefaultPlayerSlotFlags, Predicates.IsNotZero,
                                 NumeralBase.Hex);

            xs.StreamDBID(s, "Tech", ref mTechID, DatabaseObjectKind.Tech);
            xs.StreamDBID(s, "Civ", ref mCivID, DatabaseObjectKind.Civ);
            xs.StreamDBID(s, "Power", ref mPowerID, DatabaseObjectKind.Power);
            s.StreamElementOpt("FlashCivID", ref mFlashCivID, Predicates.IsNotNone);
            s.StreamStringOpt("FlashImg", ref mFlashImg, toLower: false, type: XML.XmlUtil.kSourceElement);
            // TODO: HW360's FlashPortrait elements have an ending " character (sans a starting quote). Be careful!
            s.StreamStringOpt("FlashPortrait", ref mFlashPortrait, toLower: false, type: XML.XmlUtil.kSourceElement);
            XML.XmlUtil.Serialize(s, SupportPowers, BLeaderSupportPower.kBListXmlParams);
            XML.XmlUtil.Serialize(s, StartingSquads, BLeaderStartingSquad.kBListXmlParams);
            XML.XmlUtil.Serialize(s, StartingUnits, BLeaderStartingUnit.kBListXmlParams);
            s.StreamBVector("RallyPointOffset", ref mRallyPointOffset);
            s.StreamElementOpt("RepairRate", ref mRepairRate, Predicates.IsNotZero);
            s.StreamElementOpt("RepairDelay", ref mRepairDelay, Predicates.IsNotZero);
            XML.XmlUtil.Serialize(s, RepairCost, kRepairCostTypeValuesXmlParams);
            s.StreamElementOpt("RepairTime", ref mRepairTime, Predicates.IsNotZero);
            XML.XmlUtil.Serialize(s, ReverseHotDropCost, kReverseHotDropCostTypeValuesXmlParams);
            XML.XmlUtil.Serialize(s, Populations, BPopulation.kBListXmlParams);
            XML.XmlUtil.Serialize(s, Resources, BResource.kBListTypeValuesXmlParams);
            s.StreamStringOpt("UIControlBackground", ref mUIControlBackground, toLower: false, type: XML.XmlUtil.kSourceElement);
        }
        public bool StreamDBID <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s,
                                               string xmlName, ref int dbid,
                                               Phx.DatabaseObjectKind kind,
                                               bool isOptional = true, IO.TagElementNodeType xmlSource = XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));

            string id_name      = null;
            bool   was_streamed = true;
            bool   to_lower     = ToLowerName(kind);

            if (s.IsReading)
            {
                if (isOptional)
                {
                    was_streamed = s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }

                if (was_streamed)
                {
                    dbid = Database.GetId(kind, id_name);
                    Contract.Assert(dbid.IsNotNone());
                    if (PhxUtil.IsUndefinedReferenceHandle(dbid))
                    {
                        TraceUndefinedHandle(s, id_name, xmlName, dbid, kind.ToString());
                    }
                }
                else
                {
                    dbid = TypeExtensions.kNone;
                }
            }
            else if (s.IsWriting)
            {
                if (dbid.IsNone())
                {
                    was_streamed = false;
                    return(was_streamed);
                }

                id_name = Database.GetName(kind, dbid);
                Contract.Assert(!string.IsNullOrEmpty(id_name));

                if (isOptional)
                {
                    s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
            }

            return(was_streamed);
        }
        public void Serialize <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s)
            where TDoc : class
            where TCursor : class
        {
            var xs = s.GetSerializerInterface();

            s.StreamAttributeEnum("type", ref mType);

            bool stream_targets = false;

            switch (mType)
            {
            case BProtoTechEffectType.Data:
                // #NOTE engine parses these as AllActions,Action,SubType,Amount,Relativity

                // e.g., SubType==Icon and these won't be used...TODO: is Icon the only one?
                s.StreamAttributeOpt("amount", ref mAmount, PhxPredicates.IsNotInvalidNaN);
                s.StreamAttributeEnum("subtype", ref mDU.SubType);
                // #NOTE the engine treats AllActions being present as 'true', no matter its actual value
                s.StreamAttributeOpt("allactions", ref mAllActions, Predicates.IsTrue);
                s.StreamStringOpt("action", ref mAction, false, intern: true);
                s.StreamAttributeEnumOpt("relativity", ref mRelativity, x => x != BObjectDataRelative.Invalid);
                StreamXmlObjectData(s, xs);
                stream_targets = true;
                break;

            case BProtoTechEffectType.TransformUnit:
            case BProtoTechEffectType.Build:
                xs.StreamDBID(s, XML.XmlUtil.kNoXmlName, ref mDU.ToTypeID, DatabaseObjectKind.Object, false, XML.XmlUtil.kSourceCursor);
                break;

            case BProtoTechEffectType.TransformProtoUnit:
            case BProtoTechEffectType.TransformProtoSquad:
                xs.StreamDBID(s, "FromType", ref mDU.FromTypeID, TransformProtoObjectKind, false, XML.XmlUtil.kSourceAttr);
                xs.StreamDBID(s, "ToType", ref mDU.ToTypeID, TransformProtoObjectKind, false, XML.XmlUtil.kSourceAttr);
                break;

                #region Unused
            case BProtoTechEffectType.SetAge:
                s.StreamCursorEnum(ref mDU.SetAgeLevel);
                break;

                #endregion
            case BProtoTechEffectType.GodPower:
                xs.StreamDBID(s, XML.XmlUtil.kNoXmlName, ref mDU.ID, DatabaseObjectKind.Power, false, XML.XmlUtil.kSourceCursor);
                s.StreamAttribute("amount", ref mAmount);
                break;

                #region Unused
            case BProtoTechEffectType.TechStatus:
                xs.StreamDBID(s, XML.XmlUtil.kNoXmlName, ref mDU.ID, DatabaseObjectKind.Tech, false, XML.XmlUtil.kSourceCursor);
                break;

            case BProtoTechEffectType.Ability:
                xs.StreamDBID(s, XML.XmlUtil.kNoXmlName, ref mDU.ID, DatabaseObjectKind.Ability, false, XML.XmlUtil.kSourceCursor);
                break;

            case BProtoTechEffectType.SharedLOS:             // no extra parsed data
                break;

            case BProtoTechEffectType.AttachSquad:
                xs.StreamDBID(s, "squadType", ref mDU.ID, DatabaseObjectKind.Squad, false, XML.XmlUtil.kSourceAttr);
                stream_targets = true;
                break;
                #endregion
            }

            if (stream_targets)
            {
                XML.XmlUtil.Serialize(s, Targets, BProtoTechEffectTarget.kBListXmlParams);
            }
        }
        void StreamXmlObjectData <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s, XML.BXmlSerializerInterface xs)
            where TDoc : class
            where TCursor : class
        {
            // Unused - SubTypes (with data) which no techs in HW1 made use of
            switch (mDU.SubType)
            {
                #region Unused
            case BObjectDataType.RateAmount:
            case BObjectDataType.RateMultiplier:
                xs.StreamTypeName(s, "Rate", ref mDU.ID, GameDataObjectKind.Rate, false, XML.XmlUtil.kSourceAttr);
                break;
                #endregion

            case BObjectDataType.CommandEnable:
            case BObjectDataType.CommandSelectable:             // Unused
                mDU.StreamCommand(s, xs);
                break;

            case BObjectDataType.Cost:
                mDU.StreamCost(s, xs);
                break;

                #region Unused
            case BObjectDataType.DamageModifier:
                mDU.StreamDamageModifier(s, xs);
                break;
                #endregion

            case BObjectDataType.PopCap:
            case BObjectDataType.PopMax:
                // #NOTE engine parses this as "PopType", but its parser ignores case
                xs.StreamTypeName(s, "popType", ref mDU.ID, GameDataObjectKind.Pop, false, XML.XmlUtil.kSourceAttr);
                break;

                #region Unused
            case BObjectDataType.UnitTrainLimit:
                mDU.StreamTrainLimit(s, xs, DatabaseObjectKind.Object);
                break;

            case BObjectDataType.SquadTrainLimit:
                mDU.StreamTrainLimit(s, xs, DatabaseObjectKind.Squad);
                break;
                #endregion

            case BObjectDataType.PowerRechargeTime:
            case BObjectDataType.PowerUseLimit:
            case BObjectDataType.PowerLevel:
                // #NOTE engine parses this as "Power", but its parser ignores case
                xs.StreamDBID(s, "power", ref mDU.ID, DatabaseObjectKind.Power, false, XML.XmlUtil.kSourceAttr);
                break;

            case BObjectDataType.ImpactEffect:
                // #NOTE engine parses this as "ImpactEffect", but its parser ignores case
                xs.StreamDBID(s, "impactEffect", ref mDU.ID, DatabaseObjectKind.ImpactEffect, false, XML.XmlUtil.kSourceAttr);
                break;

                #region Unused
            case BObjectDataType.DisplayNameID:
                xs.StreamStringID(s, "StringID", ref mDU.ID, XML.XmlUtil.kSourceAttr);
                break;
                #endregion

            case BObjectDataType.Icon:
            // #NOTE engine actually doesn't explicitly handle this case when loading, but it is supported at runtime for Squads
            case BObjectDataType.AltIcon:
                mDU.StreamIcon(s, xs);
                break;

            case BObjectDataType.TurretYawRate:
            case BObjectDataType.TurretPitchRate:
                // #TODO need to validate this type so that Targets.Count==1, TargetType=ProtoUnit, and resolve the Hardpoint name
                s.StreamStringOpt("Hardpoint", ref mDU.TurretRate_HardpointName, false);
                break;

            case BObjectDataType.AbilityRecoverTime:
                xs.StreamDBID(s, "Ability", ref mDU.ID, DatabaseObjectKind.Ability, false, XML.XmlUtil.kSourceAttr);
                break;

            case BObjectDataType.HPBar:
                // #TODO need to make an BProtoHPBar reference
                s.StreamStringOpt("hpbar", ref mDU.HPBar_Name, false);
                break;

                #region Unused
            case BObjectDataType.DeathSpawn:
                xs.StreamDBID(s, "squadName", ref mDU.ID, DatabaseObjectKind.Squad, false, XML.XmlUtil.kSourceAttr);
                break;
                #endregion

                #region Object effects
            // although some apply to squads too
            case BObjectDataType.Enable:             // Amount>0
            case BObjectDataType.Shieldpoints:
            case BObjectDataType.Hitpoints:
            case BObjectDataType.AmmoMax:
            case BObjectDataType.LOS:
            case BObjectDataType.MaximumVelocity:
                #region Weapon effects
            case BObjectDataType.MaximumRange:
            case BObjectDataType.Damage:
            case BObjectDataType.MinRange:
            case BObjectDataType.AOERadius:
            case BObjectDataType.AOEPrimaryTargetFactor:
            case BObjectDataType.AOEDistanceFactor:
            case BObjectDataType.AOEDamageFactor:
            case BObjectDataType.Accuracy:
            case BObjectDataType.MaxDeviation:
            case BObjectDataType.MovingMaxDeviation:
            case BObjectDataType.DataAccuracyDistanceFactor:
            case BObjectDataType.AccuracyDeviationFactor:
            case BObjectDataType.MaxVelocityLead:
            case BObjectDataType.MaxDamagePerRam:
            case BObjectDataType.ReflectDamageFactor:
            case BObjectDataType.AirBurstSpan:
            case BObjectDataType.DOTrate:
            case BObjectDataType.DOTduration:
            case BObjectDataType.Stasis:

            case BObjectDataType.Projectile:
                #endregion
                #region ProtoAction effects
            case BObjectDataType.WorkRate:
            case BObjectDataType.ActionEnable:
            case BObjectDataType.BoardTime:
                #endregion
            case BObjectDataType.BuildPoints:
            case BObjectDataType.AutoCloak:             // Amount>0
            case BObjectDataType.MoveWhileCloaked:      // Amount>0
            case BObjectDataType.AttackWhileCloaked:    // Amount>0
            case BObjectDataType.Bounty:
            case BObjectDataType.MaxContained:
            case BObjectDataType.AbilityDisabled:             // Amount>0
            case BObjectDataType.AmmoRegenRate:
            case BObjectDataType.ShieldRegenRate:
            case BObjectDataType.ShieldRegenDelay:
                #endregion
                #region Squad effects
            case BObjectDataType.Level:
            case BObjectDataType.TechLevel:
                #endregion
            case BObjectDataType.ResearchPoints:             // Tech and TechAll only
                #region Player effects
            case BObjectDataType.ResourceTrickleRate:
            case BObjectDataType.BountyResource:             // Amount!=0, uses Cost
            case BObjectDataType.RepairCost:
            case BObjectDataType.RepairTime:
            case BObjectDataType.WeaponPhysicsMultiplier:
                #endregion
            default:
                mDU.StreamCost(s, xs, isResourceOptional: true);
                break;
            }
        }