Ë
    Í—Äj>2  ã                   ó¨   — d dl Z d dlmZ d dlmZ d dlmZmZmZm	Z	m
Z
mZmZ ddlmZmZmZ ddlmZmZ e G d„ d	«      «       Ze G d
„ d«      «       Zy)é    N)ÚPath)Ú	dataclass)ÚBinaryIOÚAnyÚListÚDictÚTupleÚUnionÚOptionalé   )Ú
PCFVersionÚAttributeTypeÚATTRIBUTE_VALUES)Úread_cstring_streamÚwrite_cstringc                   óN   — e Zd ZU dZeed<   eed<   eed<   eeee	e
f   f   ed<   y)Ú
PCFElementaÐ  Represents a particle system element in a PCF file.

    Each element contains attributes that define particle behavior,
    appearance, and other properties.

    Attributes:
        type_name_index: Index into the string dictionary for the element type.
        element_name: Name of this specific element instance.
        data_signature: 16-byte signature for data integrity.
        attributes: Dictionary mapping attribute names to (type, value) tuples.
    Útype_name_indexÚelement_nameÚdata_signatureÚ
attributesN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚintÚ__annotations__Úbytesr   r	   r   r   © ó    úVC:\Users\pivot\Documents\cueki\casual-preloader\Lib\site-packages\valve_parsers/pcf.pyr   r      s5   … ñ
ð ÓØÓØÓØ�U˜E -°Ð"4Ñ5Ð5Ñ6Ô6r    r   c                   óÐ   — e Zd ZdZddeeef   defd„Zdede	de
dd	fd
„Zdede	fd„Zdeeef   dd fd„Zd„ Zdedee   fd„Zdedee   fd„Zeddedefd„«       Zdedede	fd„Zy	)ÚPCFFilea2  Parser for Valve's PCF format.

    PCF files define particle systems used in Source engine games.
    They contain particle effects like smoke, fire, explosions, etc.

    Args:
        input_file: Path to the PCF file to parse.
        version: PCF format version. Defaults to "DMX_BINARY2_PCF1".
                Available versions are in the PCFVersion enum.

    Example:
        >>> pcf = PCFFile("particles.pcf")
        >>> pcf.decode()
        >>> print(f"Found {len(pcf.elements)} particle systems")
        >>> pcf.encode("modified_particles.pcf")
    Ú
input_fileÚversionc                 óN   — || _         g | _        g | _        t        |«      | _        y ©N)r%   Ústring_dictionaryÚelementsr   r$   )Úselfr$   r%   s      r!   Ú__init__zPCFFile.__init__2   s$   € ØˆŒØ.0ˆÔØ*,ˆŒÜ˜zÓ*ˆ�r    ÚfileÚ	attr_typeÚvalueÚreturnNc                 ó  — t        j                  |«      st        d|› �«      ‚|t        j                  k(  r0t        |t        «      r|j                  dd¬«      }t        ||«       y|t        j                  k(  r@|D ]:  }|j                  t        j                  t        j                  |«      g|¢­Ž «       Œ< y|j                  t        j                  j                  k\  rt|j                  t        j                  t        j                  |«      t        |«      «      «       t        |j                  dz
  «      }|D ]  }| j!                  |||«       Œ y|t        j"                  t        j$                  t        j&                  t        j(                  fv r9|j                  t        j                  t        j                  |«      g|¢­Ž «       y|j                  t        j                  t        j                  |«      |«      «       y)a4  Write attribute data to file in the correct format.

        Args:
            file: File object to write to.
            attr_type: Type of the attribute (from AttributeType enum).
            value: The value to write.

        Raises:
            ValueError: If the attribute type is unsupported.
        úUnsupported attribute type: ÚasciiÚreplace©ÚerrorsNé   )r   ÚgetÚ
ValueErrorr   ÚSTRINGÚ
isinstanceÚstrÚencoder   ÚMATRIXÚwriteÚstructÚpackr.   ÚELEMENT_ARRAYÚlenÚ_write_attribute_dataÚCOLORÚVECTOR2ÚVECTOR3ÚVECTOR4)r*   r,   r-   r.   ÚrowÚ	base_typeÚitems          r!   rC   zPCFFile._write_attribute_data8   s�  € ô  ×#Ñ# IÔ.ÜÐ;¸I¸;ÐGÓHÐHàœ×,Ñ,Ò,Ü˜%¤Ô%ØŸ™ W°Y˜Ó?�ä˜$ Ô&Øàœ×,Ñ,Ò,Û�Ø—
‘
œ6Ÿ;™;Ô'7×';Ñ';¸IÓ'FÐMÈÒMÕNð àà�?‰?œm×9Ñ9×?Ñ?Ò?Ø�J‰J”v—{‘{Ô#3×#7Ñ#7¸	Ó#BÄCÈÃJÓOÔPÜ% i§o¡o¸Ñ&:Ó;ˆIÛ�Ø×*Ñ*¨4°¸DÕAð ààÜ×ÑÜ×!Ñ!Ü×!Ñ!Ü×!Ñ!ð	
ñ 
ð �J‰J”v—{‘{Ô#3×#7Ñ#7¸	Ó#BÐKÀUÒKÔLØà�
‰
”6—;‘;Ô/×3Ñ3°IÓ>ÀÓFÕGr    c           	      óâ  — |t         j                  t         j                  t         j                  fv r;t	        j
                  t        j                  |«      |j                  d«      «      d   S |t         j                  k(  rt        |j                  d«      d   «      S |t         j                  k(  rt        |«      S |t         j                  k(  rLt	        j
                  t        j                  |«      |j                  d«      «      d   }|j                  |«      S |t         j                  k(  r%t	        j
                  d|j                  d«      «      S |t         j                  k(  r%t	        j
                  d|j                  d«      «      S |t         j                   k(  r%t	        j
                  d|j                  d«      «      S |t         j"                  k(  r%t	        j
                  d	|j                  d
«      «      S |t         j$                  k(  r<t'        d«      D �cg c]'  }t	        j
                  d	|j                  d
«      «      ‘Œ) c}S |j(                  t         j*                  j(                  k\  rit	        j
                  d|j                  d«      «      d   }t        |j(                  dz
  «      }t'        |«      D �cg c]  }| j-                  ||«      ‘Œ c}S t/        d|› �«      ‚c c}w c c}w )aO  Read attribute data from file based on type.

        Args:
            file: File object to read from.
            attr_type: Expected type of the attribute.

        Returns:
            The parsed attribute value in the appropriate Python type.

        Raises:
            ValueError: If the attribute type is unsupported.
        é   r   r   z<4Bz<2fé   z<3fé   z<4fé   ú<Ir6   r1   )r   ÚELEMENTÚINTEGERÚFLOATr?   Úunpackr   r7   ÚreadÚBOOLEANÚboolr9   r   ÚBINARYrD   rE   rF   rG   r=   Úranger.   rA   Ú_read_attribute_datar8   )r*   r,   r-   ÚlengthÚ_ÚcountrI   s          r!   rZ   zPCFFile._read_attribute_dataf   sA  € ð Ü×!Ñ!Ü×!Ñ!Ü×Ñð
ñ 
ô
 —=‘=Ô!1×!5Ñ!5°iÓ!@À$Ç)Á)ÈAÃ,ÓOÐPQÑRÐRàœ×-Ñ-Ò-Ü˜Ÿ	™	 !› Q™Ó(Ð(àœ×,Ñ,Ò,Ü& tÓ,Ð,àœ×,Ñ,Ò,Ü—]‘]Ô#3×#7Ñ#7¸	Ó#BÀDÇIÁIÈaÃLÓQÐRSÑTˆFØ—9‘9˜VÓ$Ð$àœ×+Ñ+Ò+Ü—=‘= ¨¯	©	°!«Ó5Ð5àœ×-Ñ-Ò-Ü—=‘= ¨¯	©	°!«Ó5Ð5àœ×-Ñ-Ò-Ü—=‘= ¨¯	©	°"«Ó6Ð6àœ×-Ñ-Ò-Ü—=‘= ¨¯	©	°"«Ó6Ð6àœ×,Ñ,Ò,ÜAFÀqÄÓJÁ¸A”F—M‘M %¨¯©°2«Õ7ÀÑJÐJà�?‰?œm×9Ñ9×?Ñ?Ò?Ü—M‘M $¨¯	©	°!«Ó5°aÑ8ˆEÜ% i§o¡o¸Ñ&:Ó;ˆIÜHMÈeÌÓUÉÀ1�D×-Ñ-¨d°IÕ>ÈÑUÐUäÐ7¸	°{ÐCÓDÐDùò Kùò
 Vs   È,K'Ê=K,Úoutput_pathc           
      ó†  — t        |d«      5 }t        t        | j                  «      }t	        ||› d�«       |j                  t        j                  dt        | j                  «      «      «       | j                  D ]  }|j                  |dz   «       Œ |j                  t        j                  dt        | j                  «      «      «       | j                  D ]j  }|j                  t        j                  d|j                  «      «       |j                  |j                  dz   «       |j                  |j                  «       Œl | j                  D ]×  }|j                  t        j                  dt        |j                  «      «      «       |j                  j                  «       D ]€  \  }\  }}| j                  j!                  |«      }	|j                  t        j                  d|	«      «       |j                  t        j                  d|«      «       | j#                  |||«       Œ‚ ŒÙ 	 ddd«       | S # 1 sw Y   | S xY w)a5  Write the PCF data to a file.

        Args:
            output_path: Where to save the PCF file.

        Returns:
            Self for method chaining.

        Raises:
            IOError: If the output file cannot be written.

        Example:
            >>> pcf.encode("modified_particles.pcf")
        ÚwbÚ
ú<Hó    rP   ÚBN)ÚopenÚgetattrr   r%   r   r>   r?   r@   rB   r(   r)   r   r   r   r   ÚitemsÚindexrC   )
r*   r^   r,   Úversion_stringÚstringÚelementÚ	attr_namer-   Ú
attr_valueÚ
name_indexs
             r!   r<   zPCFFile.encodeš   s´  € ô �+˜tÔ$¨ä$¤Z°·±Ó>ˆNÜ˜$ >Ð"2°"Ð 5Ô6ð �J‰J”v—{‘{ 4¬¨T×-CÑ-CÓ)DÓEÔFð ×0Ô0�Ø—
‘
˜6 GÑ+Õ,ð 1ð �J‰J”v—{‘{ 4¬¨T¯]©]Ó);Ó<Ô=ØŸ=œ=�Ø—
‘
œ6Ÿ;™; t¨W×-DÑ-DÓEÔFØ—
‘
˜7×/Ñ/°'Ñ9Ô:Ø—
‘
˜7×1Ñ1Õ2ð )ð  Ÿ=œ=�Ø—
‘
œ6Ÿ;™; t¬S°×1CÑ1CÓ-DÓEÔFØ:A×:LÑ:L×:RÑ:RÖ:TÑ6�IÑ6 	¨:Ø!%×!7Ñ!7×!=Ñ!=¸iÓ!H�JØ—J‘JœvŸ{™{¨4°Ó<Ô=Ø—J‘JœvŸ{™{¨3°	Ó:Ô;Ø×.Ñ.¨t°YÀ
ÕKñ	 ;Uñ )÷) %ð8 ˆ÷9 %ð8 ˆús   �HH6È6I c           	      óÎ  — t        | j                  d«      5 }t        |«      }|j                  dd¬«      }t	        t
        «      D ]5  }|j                  d«      sŒt        t
        |«      }||› d�k(  sŒ.|| _         n t        d|› �«      ‚t        j                  d|j                  d	«      «      d
   }t        |«      D ](  }t        |«      }| j                  j                  |«       Œ* t        j                  d|j                  d«      «      d
   }	t        |	«      D ]p  }t        j                  d|j                  d	«      «      d
   }
t        |«      }|j                  d«      }t!        |
||i ¬«      }| j"                  j                  |«       Œr | j"                  D ]±  }t        j                  d|j                  d«      «      d
   }t        |«      D ]y  }t        j                  d|j                  d	«      «      d
   }
t%        |j                  d«      d
   «      }| j                  |
   }| j'                  ||«      }||f|j(                  |<   Œ{ Œ³ 	 ddd«       | S # 1 sw Y   | S xY w)aÁ  Parse the PCF file and populate string dictionary and elements.

        Returns:
            Self for method chaining.

        Raises:
            IOError: If the file cannot be read.
            ValueError: If the PCF format version is unsupported.

        Example:
            >>> pcf = PCFFile("particles.pcf").decode()
            >>> for element in pcf.elements:
            ...     print(f"Particle system: {element.element_name}")
        Úrbr2   r3   r4   ÚDMX_ra   zUnsupported PCF version: rb   é   r   rP   rL   rO   )r   r   r   r   r   N)re   r$   r   ÚdecodeÚdirr   Ú
startswithrf   r%   r8   r?   rT   rU   rY   r(   Úappendr   r)   r   rZ   r   )r*   r,   ÚheaderÚ
header_strÚver_attrr%   r]   r\   rj   Úelement_countr   r   r   rk   Úattribute_countr-   rl   rm   s                     r!   rs   zPCFFile.decodeÇ   s!  € ô �$—/‘/ 4Ô(¨Dä(¨Ó.ˆFØŸ™ w°y˜ÓAˆJä¤
žO�Ø×&Ñ& vÕ.Ü%¤j°(Ó;�GØ!¨ y° ^Ó3Ø'/˜œÙð ,ô !Ð#<¸V¸HÐ!EÓFÐFô —M‘M $¨¯	©	°!«Ó5°aÑ8ˆEô ˜5–\�Ü,¨TÓ2�Ø×&Ñ&×-Ñ-¨fÕ5ð "ô
 #ŸM™M¨$°·	±	¸!³Ó=¸aÑ@ˆMÜ˜=Ö)�Ü"(§-¡-°°d·i±iÀ³lÓ"CÀAÑ"F�Ü2°4Ó8�Ø!%§¡¨2£�ä$Ø$3Ø!-Ø#1Ø!ô	�ð —‘×$Ñ$ WÕ-ð *ð  Ÿ=œ=�Ü"(§-¡-°°d·i±iÀ³lÓ"CÀAÑ"F�Ü˜Ö/�AÜ&,§m¡m°D¸$¿)¹)ÀA»,Ó&GÈÑ&J�OÜ -¨d¯i©i¸«l¸1©oÓ >�Ià $× 6Ñ 6°Ñ G�IØ!%×!:Ñ!:¸4ÀÓ!K�JØ5>À
Ð4K�G×&Ñ& yÒ1ñ 0ñ )÷M )ð` ˆ÷a )ð` ˆús   —AIÁIÁ3GIÉI$Únamec                 ór   — |j                  dd¬«      }| j                  D ]  }|j                  |k(  sŒ|c S  y)a€  Find a particle element by its name.

        Args:
            name: Name of the element to find.

        Returns:
            The PCFElement if found, None otherwise.

        Example:
            >>> element = pcf.find_element_by_name("my_explosion_effect")
            >>> if element:
            ...     print(f"Found element with {len(element.attributes)} attributes")
        r2   r3   r4   N)r<   r)   r   )r*   r|   Ú
name_bytesrk   s       r!   Úfind_element_by_namezPCFFile.find_element_by_name  s<   € ð —[‘[ °�[Ó;ˆ
Ø—}”}ˆGØ×#Ñ# zÓ1Ø’ð %ð r    Ú	type_namec                 ó²   — |j                  dd¬«      }g }| j                  D ]2  }| j                  |j                     }||k(  sŒ"|j	                  |«       Œ4 |S )a6  Get all elements of a specific type.

        Args:
            type_name: Type name to search for (e.g., 'DmeParticleSystem', 'DmeParticleOperator').

        Returns:
            List of matching elements.

        Example:
            >>> operators = pcf.get_elements_by_type('DmeParticleOperator')
        r2   r3   r4   )r<   r)   r(   r   rv   )r*   r€   Ú
type_bytesÚresultsrk   Úelement_types         r!   Úget_elements_by_typezPCFFile.get_elements_by_type  s]   € ð ×%Ñ% g°iÐ%Ó@ˆ
Øˆà—}”}ˆGØ×1Ñ1°'×2IÑ2IÑJˆLØ˜zÓ)Ø—‘˜wÕ'ð %ð
 ˆr    rk   rl   c                 óp   — |j                  dd¬«      }|| j                  v r| j                  |   \  }}|S |S )aR  Get an attribute value from an element with type conversion.

        Args:
            element: The PCFElement to read from.
            attr_name: Name of the attribute.
            default: Default value if attribute not found.

        Returns:
            The attribute value, or default if not found.

        Example:
            >>> element = pcf.find_element_by_name("my_effect")
            >>> if element:
            ...     radius = pcf.get_attribute_value(element, "radius", 5.0)
            ...     color = pcf.get_attribute_value(element, "color", (255, 255, 255, 255))
        r2   r3   r4   )r<   r   )rk   rl   ÚdefaultÚ
attr_bytesr-   rm   s         r!   Úget_attribute_valuezPCFFile.get_attribute_value2  sG   € ð$ ×%Ñ% g°iÐ%Ó@ˆ
Ø˜×+Ñ+Ñ+Ø$+×$6Ñ$6°zÑ$BÑ!ˆI�zØÐØˆr    c                 óž   — |j                  dd¬«      }|| j                  vr| j                  j                  |«       ||f|j                  |<   y)aw  Set an attribute value on an element.

        Args:
            element: The PCFElement to modify.
            attr_name: Name of the attribute.
            value: New value for the attribute.
            attr_type: Type of the attribute (from AttributeType enum).

        Example:
            >>> from valve_parsers import AttributeType
            >>> element = pcf.find_element_by_name("my_effect")
            >>> if element:
            ...     pcf.set_attribute_value(element, "radius", 10.0, AttributeType.FLOAT)
            ...     pcf.set_attribute_value(element, "color", (255, 0, 0, 255), AttributeType.COLOR)
        r2   r3   r4   N)r<   r(   rv   r   )r*   rk   rl   r.   r-   rˆ   s         r!   Úset_attribute_valuezPCFFile.set_attribute_valueJ  sR   € ð$ ×%Ñ% g°iÐ%Ó@ˆ
ð ˜T×3Ñ3Ñ3Ø×"Ñ"×)Ñ)¨*Ô5à*3°UÐ);ˆ×Ñ˜:Ò&r    )ÚDMX_BINARY2_PCF1r'   )r   r   r   r   r
   r   r;   r+   r   r   r   rC   rZ   r<   rs   r   r   r   r   r…   Ústaticmethodr‰   r‹   r   r    r!   r#   r#      s÷   „ ññ"+ 5¨¨s¨Ñ#3ð +¸có +ð,HØð,HØ)6ð,HØ?Bð,Hà	ó,Hð\2E¨ð 2E¸mó 2Eðh+ %¨¨c¨	Ñ"2ð +°yó +òZ?ðB¨ð °¸*Ñ1Eó ð(¨cð °d¸:Ñ6Fó ð, ñ Zð ¸Cò ó ðð.<Ø!ð<Ø.1ð<ØERô<r    r#   )r?   Úpathlibr   Údataclassesr   Útypingr   r   r   r   r	   r
   r   Ú	constantsr   r   r   Ú_ior   r   r   r#   r   r    r!   Ú<module>r“      sU   ðÛ Ý Ý !ß D× DÑ Dß BÑ Bß 3ð
 ÷7ð 7ó ð7ð& ÷B<ð B<ó ñB<r    