1010 */
1111native KeyValues LevelEntity_GetKeysByHammerID (int iHammerID );
1212
13+ /* *
14+ * A KeyValues-backed handle that returns and iterates over keys that match the given output
15+ * name, parsing the output value into its components while being iterated.
16+ */
17+ methodmap LevelEntityOutputIterator < KeyValues {
18+ /* *
19+ * Creates an output iterator for a given Hammer ID.
20+ */
21+ public LevelEntityOutputIterator (int hammerID , const char [] output ) {
22+ KeyValues outputs = LevelEntity_GetKeysByHammerID (hammerID );
23+ if (outputs ) {
24+ char keyBuffer [128 ], valueBuffer [128 ];
25+ outputs .GotoFirstSubKey (false );
26+ bool bNext ;
27+ do {
28+ outputs .GetSectionName (keyBuffer , sizeof (keyBuffer ));
29+ outputs .GetString (NULL_STRING , valueBuffer , sizeof (valueBuffer ));
30+
31+ if (! StrEqual (keyBuffer , output )) {
32+ bNext = outputs .DeleteThis () != - 1 ;
33+ } else {
34+ bNext = outputs .GotoNextKey (false );
35+ }
36+ } while (bNext );
37+ outputs .GotoFirstSubKey (false );
38+ }
39+ return view_as <LevelEntityOutputIterator >(outputs );
40+ }
41+
42+ /* *
43+ * Returns an output iterator for a given entity (reference), looking it up by its Hammer
44+ * ID.
45+ */
46+ public static LevelEntityOutputIterator FromEntity (int entref , const char [] output ) {
47+ int entity = EntRefToEntIndex (entref );
48+ return new LevelEntityOutputIterator (GetEntProp (entity , Prop_Data , " m_iHammerID" ),
49+ output );
50+ }
51+
52+ /* *
53+ * Parses the current output string, storing the values by reference and advancing to the
54+ * next key.
55+ */
56+ public bool Next (char [] targetName , int targetNameLength ,
57+ char [] inputName , int inputNameLength , char [] variantValue , int variantValueLength ,
58+ float &delay , int &nFireCount ) {
59+ char outputString [512 ];
60+ this .GetString (NULL_STRING , outputString , sizeof (outputString ));
61+
62+ // this.GoBack() is a disgusting hack just to make sure it returns true on the last item
63+ return ParseEntityOutputString (outputString , targetName , targetNameLength , inputName ,
64+ inputNameLength , variantValue , variantValueLength , delay , nFireCount )
65+ && (this .GotoNextKey (false ) || this .GoBack ());
66+ }
67+ }
68+
1369/* *
1470 * Returns a copy of the KeyValues associated with a given entity.
1571 */
@@ -20,15 +76,28 @@ stock KeyValues LevelEntity_GetKeysByEntity(int entref) {
2076
2177/* *
2278 * Parses an entity's output value (as formatted in the entity string).
23- *
2479 * Refer to https://developer.valvesoftware.com/wiki/AddOutput for the format.
80+ *
81+ * @return True if the output string was successfully parsed, false if not.
2582 */
2683stock bool ParseEntityOutputString (const char [] output , char [] targetName , int targetNameLength ,
2784 char [] inputName , int inputNameLength , char [] variantValue , int variantValueLength ,
2885 float &delay , int &nFireCount ) {
2986 int delimiter ;
3087 char buffer [32 ];
3188
89+ {
90+ // validate that we have something resembling an output string (four commas)
91+ int i , c , nDelim ;
92+ while ((c = FindCharInString (output [i ], ' ,' )) != - 1 ) {
93+ nDelim ++ ;
94+ i += c + 1 ;
95+ }
96+ if (nDelim < 4 ) {
97+ return false ;
98+ }
99+ }
100+
32101 delimiter = SplitString (output , " ," , targetName , targetNameLength );
33102 delimiter += SplitString (output [delimiter ], " ," , inputName , inputNameLength );
34103 delimiter += SplitString (output [delimiter ], " ," , variantValue , variantValueLength );
0 commit comments