Portal-Zone Gothic-Zone Gothic II-Zone Gothic 3-Zone Gothic 4-Zone Modifikationen-Zone Download-Zone Foren-Zone RPG-Zone Almanach-Zone Spirit of Gothic

 

Seite 1 von 2 12 Letzte »
Ergebnis 1 bis 20 von 31
  1. Beiträge anzeigen #1 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline

    [Script] Listen

    DO NOT USE THIS SCRIPT! USE LISTS INSTEAD.


    Ja, Listen sind uns alle bekannt, sowohl als zCList und zCListSort... Okay, vermutlich nicht allen bekannt, aber so mancher hat damit schon gearbeitet. Inventar eines NPCs, Inhalt einer Truhe, die Voblisten... So manches ist verkettet. Und ab und an möchte man auch so einiges mit diesen Listen machen, aber das ist umständlich. Und da es ähnliches (in geringerem Umfang) für zCArray gibt, hab' ich es eben für zCList und zCListSort geschrieben. Das Interface ist recht gut dokumentiert würde ich sagen, der Code selber dann nicht mehr, das habe ich alles in einem Rutsch geschrieben.

    Code:
    //#################################################################
    //
    //  Listen Dokumentation
    //
    //#################################################################
    
    //************************************
    //        Warum?
    /************************************
    
    -Der (größere) Umgang mit Listen ist zuteils nervig, gerade weil man ganz fix Fehler einbaut
     oder viel tippen darf (dutzende Instanzzuweisungen). Da es noch keine Funktionen für Listen 
     gibt habe ich einfach mal ein paar geschrieben... Es sollte eigentlich alles abgedeckt sein 
     was man so braucht und auch noch vieles mehr...
    
    //************************************
    //        Was ist zu beachten?
    //************************************
    
    -Ich verwende gerne das Wort 'node', es meint ein Listenelement.
    -List_Init() in der Init_Global() aufrufen, ansonten ist List_CopyTo() bzw. List_CopyToS() nicht nutzbar!
    -Den Anfang einer Liste solltet ihr nicht "wegschmeißen", man kommt an den Anfang nicht wieder ran!
    -Nicht alle Funktionen sind "sicher" und auch die, die es sind kann ich nicht ausreichend absichern,
     weil ich anhand eines Pointer nicht die Validität einer Liste erschließen kann.
    -Ihr müsst zwischen zCList und zCListSort unterscheiden. Bei letzteren enden alle Funktionen einfach
     mit einem 'S'.
    -Wenn man Strings speichert (und die Variable nachträglich verändert) oder generell nur den Wert 
    von z.B. einem oCNPC (Alles, was sich nicht Integer schimpft) speichern möchte, sollte man auf Gottfrieds inkludierende Listen 
    ausweichen (siehe weiter unten).
    -Ab und an verlange ich direkt eine Node (Listenelement), ab und an eine Nummer... Im Normalfall die
     Nummer, aber es erschien mir bei bestimmten Funktionen auch für den Nutzer praktischer, wenn ich 
     direkt nach der Node frage.
     
    //************************************
    //        Benutzung der Funktionen:
    //************************************
    
    /**********
    //  Listen  
    /**********
    
    func int List_Create(var int data)
    // Erzeugt eine Liste, die erste Node hält den Wert 'data' 
    
    func void List_Add(var int list, var int data)
    // Hängt eine Node, die den Wert 'data' hält, ans Ende der Liste 'list' an.
    
    func void List_AddOffset(var int list, var int offset, var int data)
    // Fügt eine Node zwischen der Node Nr. offset und Node Nr. offset + 1 mit dem Wert 'data' ein.
    
    func void List_Set(var int node, var int data)
    // Setz den Wert der Node 'node' auf 'data'.
    
    func int List_Get(var int nr)
    // Gibt den Wert der Node mit der Nummer 'nr' zurück.
    
    func int List_Node(var int list, var int nr)
    // Gibt die Node mit der Nummer 'nr' zurück.
    
    func int List_Length(var int list)
    // Gibt die Länge der Liste zurück (Anzahl aller Elemente)
    
    func int List_End(var int list)
    // Gibt die letzte Node der Liste zurück.
    
    func int List_Contains(var int list, var int data)
    // Gibt die letzte Node mit dem Wert 'data' zurück.
    
    func int List_For(var int list, var string function)
    // Ruft die Funktion 'function' für jede Listenelement auf, 
    // die einzelne Node wird dabei als Parameter (Pointer) übergeben.
    
    func void List_Delete(var int list, var int nr)
    // Löscht die Node mit der Nummer 'nr'.
    
    func void List_Destroy(var int list)
    // Zerstört die komplette Liste.
    
    func int List_ToArray(var int list)
    // Gibt einen Pointer auf einen Speicherbereich frei, in dem der gehaltene
    // Wert der Listenelemente wie in einem Array aneinandergereiht steht.
    
    func int List_CopyTo(var int list, var int array)
    // Kopiert die Werte der Liste in ein statisches Array (Gothic-Array).
    
    func int List_Sort(var int list, var int valueOffset)
    // Sortiert die Liste nach dem Wert, der in der valueOffset Bytes hinter dem Anfang
    // des gehaltenen Objekts steht (Bei oCNPCs und einem valueOffset von 432 würde nach 
    // dem NPC-Type sortiert werden).
    // Dank hierfür geht an Gottfried weil ich mal wieder zu faul war (Und keine Ahnung
    // von Sortier-Algorythmen habe).
    
    func void List_MoveUp(var int list, var int nr)
    // Rückt die Node mit der Nummer 'nr' um eins näher 
    // an den Beginn der Liste.
    // Ergab sich als Nebenprodukt der Sortierfunktion,
    // Dank geht also an Gottfried.
    
    func void List_MoveDown(var int list, var int nr)
    // Rückt die Node mit der Nummer 'nr' um eins weiter
    // vom Beginn der Liste weg.
    // Ergab sich als Nebenprodukt der Sortierfunktion,
    // Dank geht also an Gottfried.
    
    
    //***********************/
    //  Inkludierende Listen
    //***********************/
    
    /* Vorab  ein  Beispiel um den  Unterschied zwischen  einer List  und einer
     * Inkludierenden  Liste  zu verdeutlichen: (Die  Liste 'list'  sei bereits
     * gegeben) 
    
     var string str;
     str = "Hallo01";
     List_Add(list, STRINT_toChar(str));
     str = "Hallo02";
     List_Add(list, STRINT_toChar(str));
    
    
     * Man würde vermutlich zwei Items wünschen: Eines das Hallo01 als string
     * beinhaltet  und eines  dass Hallo02 als string beinhaltet.. Problem  ist
     * nur, dass für beide Operationen der selbe string verwendet wurde -> Also
     * auch der selbe Pointer, folglich steht nun in beiden Hallo02.
     * Inkludierende Listen hingegen legen eine Kopie von dem Inhalt an auf den
     * 'data' zeigt,  allerdings muss dafür manchmal  die größe des Inhaltes in
     * Bytes  gegeben sein. (Dafür  würde  ich eine  Konstante verwenden, damit
     * nichts schief geht) Abgesehen von  den fünf folgenden Funktionen können
     * alle übrigen normal verwendet werden.
     * INFO: Vor  allem bei Delete und Destroy  sollten UNBEDINGT die passenden
     * Funktionen  verwendet  werden.  Wenn  auf  eine Inkludierende Liste  die
     * normale Destroy Funktion angewendet, bleiben alle Kopien der Daten nutz-
     * los im Speicher liegen.. Das sollte man möglichst vermeiden.
    
     * Info: Es handelt sich nicht wirklich  um eine andere Klasse, sondern nur
     * um die Handhabung vom Hinzufügen/Entfernen der Daten in der Liste.
     * Sprich: Bei den Listen die  von der Engine benutzt  werden, können diese
     * Funktionen auch verwendet werden, dabei sollte man aber höchste Vorsicht
     * walten  lassen: Wenn  man versucht Incl_Delete auf  ein Item anzuwenden,
     * dass NICHT  mit Incl_Add,  Incl_AddOffset oder  Incl_Set  bereitgestellt
     * wurde (oder  von  der  Engine persönlich stammt)  kann es  zu  unschönen
     * Nebenwirkungen kommen...
     * (Da  Incl_Destroy Incl_Delete  nur mehrfach aufruft sollte  man bei  der
     * Verwendung dieser Funktion noch besser aufpassen)
    
     * (Auch bei den folgenden Funktionen wird zwischen List und ListSort nach 
     *	bekanntem Schema unterschieden)						
     * 																		*
    
    func void List_Incl_Add(int list, int data, int size)
    // Hängt eine Node, die den Wert 'data' hält, ans Ende der Liste 'list' an.
    
    func void List_Incl_AddOffset(int list, int offset, int data, int size)
    // Fügt eine Node zwischen der Node Nr. offset und Node Nr. offset + 1
    // mit dem Wert 'data' ein.
    
    func void List_Incl_Set(var int node, var int data, var int size)
    // Setz den Wert der Node 'node' auf 'data'.
    
    func void List_Incl_Delete(var int list, var int nr)
    // Löscht die Node mit der Nummer 'nr'.
    
    func void List_Incl_Destroy(var int list)
    // Zerstört die komplette Liste.
    
    func int List_Incl_Create(var int data, var int size)
    // Erstellt eine neue Liste, das erste Listenelement hält den Wert 'data'
    
    */
    
    
    /* * * * * * * * * * * * * * * * * * * * * * * * */
    // INTERNA! DO NOT CHANGE! INTERNA! DO NOT CHANGE! 
    /* * * * * * * * * * * * * * * * * * * * * * * * */ 
    
    
    
    
    
    // Create a list (which isn't different to a node in reality)
    func int List_Create(var int data) {
        var int ptr; ptr = MEM_Alloc(8);
        MEM_WriteInt(ptr, data);
        return ptr;
    };
    
    func int List_CreateS(var int data) {
        var int ptr; ptr = MEM_Alloc(12);
        MEM_WriteInt(ptr+4, data);
        return ptr;
    };
    
    
    // Get the end of the list
    func int List_EndSub(var int list)    {    // subfunction to provide usersafety
        if MEM_ReadInt(list+4)    {
            return List_EndSub(MEM_ReadInt(list+4));
        };
        return list;
    };
    func int List_End(var int list)    {
        if (!list)    {
            MEM_Error("List_End: no valid pointer");
    		return -1;
        };
        return List_EndSub(list);
    };
    
    func int List_EndSubS(var int list)    {
        if MEM_ReadInt(list+8)    {
            return List_End(MEM_ReadInt(list+8));
        };
        return list;
    };
    func int List_EndS(var int list)    {
        if (!list)    {
            MEM_Error("List_EndS: no valid pointer");
    		return -1;
        };
        return List_EndSubS(list);
    };
    
    
    // Get the Length of the list
    func int List_LengthSub(var int list, var int nr)    { // subfunction to provide usersafety
        if MEM_ReadInt(list+4)    {
            return List_LengthSub(MEM_ReadInt(list+4), nr+1);
        };
        return nr;
    };
    func int List_Length(var int list)    {
        if (!list)    {
            MEM_Error("List_Length: no valid pointer");
    		return -1;
        };
        return List_LengthSub(list, 1);
    };
    
    func int List_LengthSubS(var int list, var int nr)    {
        if MEM_ReadInt(list+8)    {
            return List_LengthSubS(MEM_ReadInt(list+8), nr+1);
        };
        return nr;
    };
    func int List_LengthS(var int list)    {
        if (!list)    {
            MEM_Error("List_LengthS: no valid pointer");
    		return -1;
        };
        return List_LengthSubS(list, 1);
    };
    
    
    // Get a specific node of the list by number
    func int List_NodeSub(var int list, var int nr)    { // subfunction to provide usersafety
        nr -= 1;
        if (!nr)    {
            return list;
        };
        return List_NodeSub(MEM_ReadInt(list+4), nr);
    };
    func int List_Node(var int list, var int nr)    {
        if ((nr > List_Length(list)) | nr <= 0)    {
            MEM_Error("List_Node: invalid value of number");
    		return -1;
        };
        return List_NodeSub(list, nr);
    };
    
    func int List_NodeSubS(var int list, var int nr)    {
        nr -= 1;
        if (!nr)    {
            return list;
        };
        return List_NodeSubS(MEM_ReadInt(list+8), nr-1);
    };
    func int List_NodeS(var int list, var int nr)    {
        if ((nr > List_LengthS(list)) | nr <= 0)    {
            MEM_Error("List_Node: invalid value of number");
    		return -1;
        };
        return List_NodeSub(list, nr);
    };
    
    
    // add a node to a list
    func void List_Add(var int list, var int data)    {
        if (!list)    {
            MEM_Error("List_Add: not valid list");
            return;
        };
        var int ptr; ptr = MEM_Alloc(8);
        MEM_WriteInt(List_End(list)+4, ptr);
        MEM_WriteInt(ptr, data);
    };
    
    func void List_AddS(var int list, var int data)    {
        if (!list)    {
            MEM_Error("List_AddS: not valid list");
            return;
        };
        var int ptr; ptr = MEM_Alloc(12);
        MEM_WriteInt(List_End(list)+8, ptr);
        MEM_WriteInt(ptr+4, data);
    };
    
    
    // delete a node of a list by number
    func void List_Delete(var int list, var int nodeNr)    {
        var int prev; prev = List_Node(list, nodeNr-1);
        var int del; del = MEM_ReadInt(prev+4);
        MEM_WriteInt(prev+4, MEM_ReadInt(del+4));
        MEM_Free(del);
    };
    
    func void List_DeleteS(var int list, var int nodeNr)    {
        var int prev; prev = List_NodeS(list, nodeNr-1);
        var int del; del = MEM_ReadInt(prev+8);
        MEM_WriteInt(prev+8, MEM_ReadInt(del+8));
        MEM_Free(del);
    };
    
    
    // delete a complete list
    func void List_Destroy(var int list) {
        if (!list)    {
            MEM_Error("List_Destroy: invalid list");
            return;
        };
    	var int pos; pos = MEM_StackPos.position;
    	var int next; next = MEM_ReadInt(list+4);
    	MEM_Free(list);
    	if (next) {
    		list = next;
    		MEM_StackPos.position = pos;
    	};
    };
    
    func void List_DestroyS(var int list) {
        if (!list)    {
            MEM_Error("List_Destroy: invalid list");
            return;
        };
    	var int pos; pos = MEM_StackPos.position;
    	var int next; next = MEM_ReadInt(list+8);
    	MEM_Free(list);
    	if (next) {
    		list = next;
    		MEM_StackPos.position = pos;
    	};
    };
    
    
    // Call a function for every node and pass the node with it
    func void List_For(var int list, var string function)    {
        var int pos; pos = MEM_StackPos.position;
        if (list)    {
            MEM_PushIntParam(list);
            MEM_CallByString(function);
            list = MEM_ReadInt(list+4);
            MEM_StackPos.position = pos;
        };
    };
    
    func void List_ForS(var int list, var string function)    {
        var int pos; pos = MEM_StackPos.position;
        if (list)    {
            MEM_PushIntParam(list);
            MEM_CallByString(function);
            list = MEM_ReadInt(list+8);
            MEM_StackPos.position = pos;
        };
    };
    
    
    // copys a list to an array (memory of the size 4*nodes Bytes, contains the data in every word)
    
    func int List_ToArray(var int list)    {
        var int ptr; ptr = MEM_Alloc(List_Length(list)*4);
        var int count; count = 0;
        var int pos; pos = MEM_StackPos.position;
        
        MEM_WriteInt(ptr+(4*count), MEM_ReadInt(list));
        count += 1;
        if MEM_ReadInt(list+4)    {
            list = MEM_ReadInt(list+4);
            MEM_StackPos.position = pos;
        };
        
        return ptr;
    };
    
    
    func int List_ToArrayS(var int list)    {
        var int ptr; ptr = MEM_Alloc(List_Length(list)*4);
        var int count; count = 0;
        var int pos; pos = MEM_StackPos.position;
        
        MEM_WriteInt(ptr+(4*count), MEM_ReadInt(list+4));
        count += 1;
        if MEM_ReadInt(list+8)    {
            list = MEM_ReadInt(list+8);
            MEM_StackPos.position = pos;
        };
        
        return ptr;
    };
    
    
    // copys a list to an static array
    var MEMINT_HELPERCLASS CopyToINT_MinusOne;
    func int List_CopyToINT()    {
        MEMINT_StackPopInst();
        MEMINT_StackPushInst(zPAR_TOK_PUSHINT);
        
          var int ptr; ptr = MEMINT_StackPopInt();
        var int list; list = MEMINT_StackPopInt();
        var int count; count = 0;
        var int pos; pos = MEM_StackPos.position;
        
        MEM_WriteInt(ptr+(4*count), MEM_ReadInt(list));
        count += 1;
        if MEM_ReadInt(list+4)    {
            list = MEM_ReadInt(list+4);
            MEM_StackPos.position = pos;
        };
        return ptr;
    };    
    var MEMINT_HELPERCLASS CopyTo_MinusOne;    
    func int List_CopyTo(var int list, var int statArr)    {
         MEM_Error ("List_CopyTo was called before List_Init");
    };
    
    var MEMINT_HELPERCLASS CopyToINT_MinusOneS;
    func int List_CopyToINTS()    {
        MEMINT_StackPopInst();
        MEMINT_StackPushInst(zPAR_TOK_PUSHINT);
        
        var int ptr; ptr = MEMINT_StackPopInt ();
        var int list; list = MEMINT_StackPopInt ();
        var int count; count = 0;
        var int pos; pos = MEM_StackPos.position;
        
        MEM_WriteInt(ptr+(4*count), MEM_ReadInt(list+4));
        count += 1;
        if MEM_ReadInt(list+8)    {
            list = MEM_ReadInt(list+8);
            MEM_StackPos.position = pos;
        };
        
        return ptr;
    };
    var MEMINT_HELPERCLASS CopyTo_MinusOneS; 
    func int List_CopyToS()    {
     MEM_Error ("List_CopyToS was called before List_Init");
    };
    
    
    func int List_Init()    {
         MEMINT_StatArrs_ReplaceFunc (CopyTo_MinusOne + 1, CopyToInt_MinusOne + 1);
         MEMINT_StatArrs_ReplaceFunc(CopyTo_MinusOneS + 1, CopyToINT_MinusOneS + 1);
    };
    
    // gets the data of node nr 'nodeNr'
    func int List_Get(var int list, var int nr)	{
    	return MEM_ReadInt (List_Node(list, nr));
    };
    
    func int List_GetS(var int list, var int nr)	{
    	return MEM_ReadInt(List_NodeS(list, nr)+4);
    };
    
    
    // sets the data 'data' of node 'node'
    func void List_Set(var int node, var int data)    {
        MEM_WriteInt(node, data);
    };
    
    func void List_SetS(var int node, var int data)    {
        MEM_WriteInt(node+4, data);
    };
    
    
    // returns  the last node which contains the pointer 'data'
    func int List_Contains(var int list, var int data)    {
        var int node; node = -1;
        var int pos; pos = MEM_StackPos.position;
            if data == MEM_ReadInt(list)    {
            node = list;
        };
        if MEM_ReadInt(list+4)    {
            MEM_StackPos.position = pos;
        };
        return node;
    };
    
    
    func int List_ContainsS(var int list, var int data)    {
        var int node; node = -1;
        var int pos; pos = MEM_StackPos.position;
            if data == MEM_ReadInt(list+4)    {
            node = list;
        };
        if MEM_ReadInt(list+8)    {
            MEM_StackPos.position = pos;
        };
        return node;
    };
    
    // adds a node between node nr. 'offset' and node nr. 'offset + 1' 
    func void List_AddOffset(var int list, var int offset, var int data)    {
        var int prev; prev = List_Node(list, offset);
        var int next; next = MEM_ReadInt(prev+4);
        var int ptr; ptr = MEM_Alloc(8);
        MEM_WriteInt(prev+4, ptr);
        MEM_WriteInt(ptr+4, next);
        MEM_WriteInt(ptr, data);
    };
    func void List_AddOffsetS(var int list, var int offset, var int data)    {
        var int prev; prev = List_NodeS(list, offset);
        var int next; next = MEM_ReadInt(prev+8);
        var int ptr; ptr = MEM_Alloc(12);
        MEM_WriteInt(prev+8, ptr);
        MEM_WriteInt(ptr+8, next);
        MEM_WriteInt(ptr+4, data);
    };
        
         
    func void List_MoveDownS(var int list, var int offset) {
        var int prev;   prev = List_NodeS(list, offset-1);
        var int prev_s; prev_s = MEM_ReadInt(prev+4);
        var int act_s;  act_s  = MEM_ReadInt(list+4);
        MEM_WriteInt(prev+4, act_s);
        MEM_WriteInt(list+4, prev_s);
    };
     
    func void List_MoveUpS(var int list, var int offs) {
        var int next;   next  = MEM_ReadInt(list+8);
        var int next_s; next_s = MEM_ReadInt(next+4);
        var int act_s;  act_s  = MEM_ReadInt(list+4);
        MEM_WriteInt(next+4, act_s);
        MEM_WriteInt(list+4, next_s);
    };
     
    func void List_SortS(var int list, var int offsval) {
        var int list_len; list_len = List_EndS(list);
        var int i; i = 0;
        var int c; c = 1;
        var int prev;
        var int node;
        var int prev_val; 
        var int node_val; 
        var int pos0; pos0 = MEM_StackPos.position;
        if(c) {
            c = 0;
            var int pos1; pos1 = MEM_StackPos.position;
            if(i < list_len) {
                prev = List_NodeS(list, i-1);
                node = List_NodeS(list, i);
                prev_val = MEM_ReadInt(MEM_ReadInt(prev+4)+offsval);
                node_val = MEM_ReadInt(MEM_ReadInt(node+4)+offsval);
                if(node_val<prev_val) {
                    c = 1;
                    List_MoveDownS(list, i);
                };
                i += 1;
                MEM_StackPos.position = pos1;
            };
            MEM_StackPos.position = pos0;
        };
    };
    
    func void List_MoveDown(var int list, var int offset) {
        var int prev;   prev = List_Node(list, offset-1);
        var int prev_s; prev_s = MEM_ReadInt(prev);
        var int act_s;  act_s  = MEM_ReadInt(list);
        MEM_WriteInt(prev, act_s);
        MEM_WriteInt(list, prev_s);
    };
     
    func void List_MoveUp(var int list, var int offs) {
        var int next;   next  = MEM_ReadInt(list+4);
        var int next_s; next_s = MEM_ReadInt(next);
        var int act_s;  act_s  = MEM_ReadInt(list);
        MEM_WriteInt(next, act_s);
        MEM_WriteInt(list, next_s);
    };
     
    func void List_Sort(var int list, var int offsval) {
        var int list_len; list_len = List_End(list);
        var int i; i = 0;
        var int c; c = 1;
        var int prev;
        var int node;
        var int prev_val; 
        var int node_val; 
        var int pos0; pos0 = MEM_StackPos.position;
        if(c) {
            c = 0;
            var int pos1; pos1 = MEM_StackPos.position;
            if(i < list_len) {
                prev = List_Node(list, i-1);
                node = List_Node(list, i);
                prev_val = MEM_ReadInt(MEM_ReadInt(prev)+offsval);
                node_val = MEM_ReadInt(MEM_ReadInt(node)+offsval);
                if(node_val<prev_val) {
                    c = 1;
                    List_MoveDown(list, i);
                };
                i += 1;
                MEM_StackPos.position = pos1;
            };
            MEM_StackPos.position = pos0;
        };
    };
    
    func int List_Incl_Create(var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(8);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(nptr, dptr);
    	return nptr;
    };
    func int List_Incl_CreateS(var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(12);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(nptr+4, dptr);
    	return nptr;
    };
    
    func void List_Incl_Add(var int list, var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(8);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(List_End(list)+4, nptr);
        MEM_WriteInt(nptr, dptr);
    };
    func void List_Incl_AddS(var int list, var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(12);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(List_EndS(list)+8, nptr);
        MEM_WriteInt(nptr, dptr);
    };
    
    // delete a node of a list by number
    func void List_Incl_Delete(var int list, var int nodeNr) {
        var int prev; prev = List_Node(list, nodeNr-1);
        var int del; del = MEM_ReadInt(prev+4);
        MEM_WriteInt(prev+4, MEM_ReadInt(del+4));
        MEM_Free(MEM_ReadInt(del));
        MEM_Free(del);
    };
    func void List_Incl_DeleteS(var int list, var int nodeNr) {
        var int prev; prev = List_NodeS(list, nodeNr-1);
        var int del; del = MEM_ReadInt(prev+8);
        MEM_WriteInt(prev+8, MEM_ReadInt(del+8));
        MEM_Free(MEM_ReadInt(del+4));
        MEM_Free(del);
    };
    
    // delete a complete list
    func void List_Incl_Destroy(var int list) {
        if (!list)    {
            MEM_Error("List_Incl_Destroy: invalid list");
            return;
        };
        var int pos; pos = MEM_StackPos.position;
        if (!MEM_ReadInt(list+4))    {
            List_Incl_Delete(list, 0);
            return;
        };
        List_Incl_Delete(list, 1);
        MEM_StackPos.position = pos;
    };
    func void List_Incl_DestroyS(var int list) {
        if (!list)    {
            MEM_Error("List_Incl_DestroyS: invalid list");
            return;
        };
        var int pos; pos = MEM_StackPos.position;
        if (!MEM_ReadInt(list+8))    {
            List_Incl_DeleteS(list, 0);
            return;
        };
        List_Incl_DeleteS(list, 1);
        MEM_StackPos.position = pos;
    };
    
    // sets the data 'data' of node 'node'
    func void List_Incl_Set(var int node, var int data, var int size) {
        var int odat; odat = MEM_ReadInt(node);
        if(odat) {
                            // Man könnte auch direkt überschreiben, aber
            MEM_Free(odat); // man weiß ja nie was der User alles treibt,
                            // deswegen lieber ein Reset :p
        };
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(node, dptr);
    };
    func void List_Incl_SetS(var int node, var int data, var int size) {
        var int odat; odat = MEM_ReadInt(node+4);
        if(odat) {
            MEM_Free(odat);
        };
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(node+4, dptr);
    };
    
    // adds a node between node nr. 'offset' and node nr. 'offset + 1'
    func void List_Incl_AddOffset(var int list, var int offset, var int data, var int size) {
        var int prev; prev = List_Node(list, offset);
        var int next; next = MEM_ReadInt(prev+4);
        var int ptr; ptr = MEM_Alloc(8);
        MEM_WriteInt(prev+4, ptr);
        MEM_WriteInt(ptr+4, next);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(ptr, dptr);
    };
    func void List_Incl_AddOffsetS(var int list, var int offset, var int data, var int size) {
        var int prev; prev = List_NodeS(list, offset);
        var int next; next = MEM_ReadInt(prev+8);
        var int ptr; ptr = MEM_Alloc(12);
        MEM_WriteInt(prev+8, ptr);
        MEM_WriteInt(ptr+8, next);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(ptr+4, dptr);
    };
    Damit sollte der Weg der Listen zur Weltherrschaft geebnet sein \o/

    Vielen Dank an Sektenspinner nochmal, der mit seinem Ikarus-Paket soetwas überhaupt erst möglich gemacht hat (Ausserdem hab' ich sein Aufbau der Dokumentation geklaut).

    08.10.10:
    Gottfrieds "inkludierende Listen" eingefügt.
    18.09.11
    Ein paar Fehler behoben, die Bonne6 gefunden hat. Außerdem gibt's nun im Falle einer falschen Eingabe (soweit geprüft) nicht nur 'ne Warnung sondern es wird -1 zurückgegeben bzw. aus der Funktion gesprungen (Wenn Void).
    Geändert von Lehona (03.02.2014 um 09:32 Uhr)

  2. Beiträge anzeigen #2 Zitieren
    Deus Avatar von Milgo
    Registriert seit
    Jul 2002
    Beiträge
    15.571
     
    Milgo ist offline
    Top. Hab mir die zCList noch nicht angeschaut, aber das kann ja durchaus praktisch sein für alles mögliche.

  3. Homepage besuchen Beiträge anzeigen #3 Zitieren
    Exodus Avatar von Sektenspinner
    Registriert seit
    Jul 2004
    Ort
    Karlsruhe
    Beiträge
    7.827
     
    Sektenspinner ist offline
    Könnte nützlich sein. Werde ich dran erinnern, wenn ich mal intensiv mit zCLists arbeite.
    Für Spieler:
    Velaya # Velaya in English # Exodus Demo # Irrwichtel
    Tools für Modder:
    DiaDepp # DOPA-PARTER # zSlang
    Scripte für Modder:
    Ikarus Skriptpaket # Floats # Broadcasts

  4. Beiträge anzeigen #4 Zitieren
    Ehrengarde Avatar von Gottfried
    Registriert seit
    Mar 2006
    Beiträge
    2.512
     
    Gottfried ist offline
    Ich habe noch zwei kleine Nachträge hinzuzufügen. Zum Einen eine kleine Funktionen die es ermöglicht eigene Listen zu erstellen und zum Anderen meine sog. 'Inkludierenden Listen' was das genau ist steht in der Beschreibung

    Listen erstellen:
    Code:
    //***********************/
    //  Listen erstellen
    //***********************/
    /* Um eigene Listen zu erstellen noch zwei kleine Funktiönchen:
     * (Einmal für eine  normale List und noch einmal mit einem angehängten 'S'
     * für eine ListSort)
    
    func int List_Create(int data)
    // Erstellt eine neue Liste und beschreibt Node 0 direkt mit 'data'
    
    */
    
    func int List_Create(var int data) {
        var int ptr; ptr = MEM_Alloc(8);
        MEM_WriteInt(ptr, data);
        return ptr;
    };
    
    func int List_CreateS(var int data) {
        var int ptr; ptr = MEM_Alloc(12);
        MEM_WriteInt(ptr+4, data);
        return ptr;
    };
    Inkludierende Listen:
    Code:
    //***********************/
    //  Inkludierende Listen
    //***********************/
    
    /* Vorab  ein  Beispiel um den  Unterschied zwischen  einer List  und einer
     * Inkludierenden  Liste  zu verdeutlichen: (Die  Liste 'list'  sei bereits
     * gegeben)
    
     var string str;
     str = "Hallo01";
     List_Add(list, STRINT_toChar(str));
     str = "Hallo02";
     List_Add(list, STRINT_toChar(str));
    
     * Man würde vermutlich zwei Items wünschen: Eines dass  Hallo01 als string
     * beinhaltet  und eines  dass Hallo02 als string beinhaltet.. Problem  ist
     * nur, dass für beide Operationen der selbe string verwendet wurde -> Also
     * auch der selbe Pointer, folglich steht nun in beiden Hallo02.
     * Inkludierende Listen hingegen legen eine Kopie von dem Inhalt an auf den
     * 'data' zeigt,  allerdings muss dafür manchmal  die größe des Inhaltes in
     * Bytes  gegeben sein. (Dafür  würde  ich eine  Konstante verwenden, damit
     * nichts schief geht) Abgesehen von  den fünf folgenden Funktionen können
     * alle übrigen normal verwendet werden.
     * INFO: Vor  allem bei Delete und Destroy  sollten UNBEDINGT die passenden
     * Funktionen  verwendet  werden.  Wenn  auf  eine Inkludierende Liste  die
     * normale Destroy Funktion angewendet, bleiben alle Kopien der Daten nutz-
     * los im Speicher liegen.. Das sollte man möglichst vermeiden.
    
     * Info: Es handelt sich nicht wirklich  um eine andere Klasse, sondern nur
     * um die Handhabung vom Hinzufügen/Entfernen der Daten in der Liste.
     * Sprich: Bei den Listen die  von der Engine benutzt  werden, können diese
     * Funktionen auch verwendet werden, dabei sollte man aber höchste Vorsicht
     * walten  lassen: Wenn  man versucht Incl_Delete auf  ein Item anzuwenden,
     * dass NICHT  mit Incl_Add,  Incl_AddOffset oder  Incl_Set  bereitgestellt
     * wurde (oder  von  der  Engine persönlich stammt)  kann es  zu  unschönen
     * Nebenwirkungen kommen...
     * (Da  Incl_Destroy Incl_Delete  nur mehrfach aufruft sollte  man bei  der
     * Verwendung dieser Funktion noch besser aufpassen)
    
     * (Auch bei den folgenden Funktionen wird zwischen List und ListSort
     * separiert)
    
    func void List_Incl_Add(int list, int data, int size)
    // Hängt eine Node, die den Wert 'data' hält, ans Ende der Liste 'list' an.
    
    func void List_Incl_AddOffset(int list, int offset, int data, int size)
    // Fügt eine Node zwischen der Node Nr. offset und Node Nr. offset + 1
    // mit dem Wert 'data' ein.
    
    func void List_Incl_Set(var int node, var int data, var int size)
    // Setz den Wert der Node 'node' auf 'data'.
    
    func void List_Incl_Delete(var int list, var int nr)
    // Löscht die Node mit der Nummer 'nr'.
    
    func void List_Incl_Destroy(var int list)
    // Zerstört die komplette Liste.
    
    func int List_Incl_Create(var int data, var int size)
    // Erstellt eine neue Liste und beschreibt Node 0 direkt mit 'data'
    
    */
    
    func int List_Incl_Create(var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(8);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(nptr, dptr);
    	return nptr;
    };
    func int List_Incl_CreateS(var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(12);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(nptr+4, dptr);
    	return nptr;
    };
    
    func void List_Incl_Add(var int list, var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(8);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(List_End(list)+4, nptr);
        MEM_WriteInt(nptr, dptr);
    };
    func void List_Incl_AddS(var int list, var int data, var int size) {
        var int nptr; nptr = MEM_Alloc(12);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(List_EndS(list)+8, nptr);
        MEM_WriteInt(nptr, dptr);
    };
    
    // delete a node of a list by number
    func void List_Incl_Delete(var int list, var int nodeNr) {
        var int prev; prev = List_Node(list, nodeNr-1);
        var int del; del = MEM_ReadInt(prev+4);
        MEM_WriteInt(prev+4, MEM_ReadInt(del+4));
        MEM_Free(MEM_ReadInt(del));
        MEM_Free(del);
    };
    func void List_Incl_DeleteS(var int list, var int nodeNr) {
        var int prev; prev = List_NodeS(list, nodeNr-1);
        var int del; del = MEM_ReadInt(prev+8);
        MEM_WriteInt(prev+8, MEM_ReadInt(del+8));
        MEM_Free(MEM_ReadInt(del+4));
        MEM_Free(del);
    };
    
    // delete a complete list
    func void List_Incl_Destroy(var int list) {
        if (!list)    {
            MEM_Error("List_Incl_Destroy: invalid list");
            return;
        };
        var int pos; pos = MEM_StackPos.position;
        if (!MEM_ReadInt(list+4))    {
            List_Incl_Delete(list, 0);
            return;
        };
        List_Incl_Delete(list, 1);
        MEM_StackPos.position = pos;
    };
    func void List_Incl_DestroyS(var int list) {
        if (!list)    {
            MEM_Error("List_Incl_DestroyS: invalid list");
            return;
        };
        var int pos; pos = MEM_StackPos.position;
        if (!MEM_ReadInt(list+8))    {
            List_Incl_DeleteS(list, 0);
            return;
        };
        List_Incl_DeleteS(list, 1);
        MEM_StackPos.position = pos;
    };
    
    // sets the data 'data' of node 'node'
    func void List_Incl_Set(var int node, var int data, var int size) {
        var int odat; odat = MEM_ReadInt(node);
        if(odat) {
                            // Man könnte auch direkt überschreiben, aber
            MEM_Free(odat); // man weiß ja nie was der User alles treibt,
                            // deswegen lieber ein Reset :p
        };
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(node, dptr);
    };
    func void List_Incl_SetS(var int node, var int data, var int size) {
        var int odat; odat = MEM_ReadInt(node+4);
        if(odat) {
            MEM_Free(odat);
        };
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(node+4, dptr);
    };
    
    // adds a node between node nr. 'offset' and node nr. 'offset + 1'
    func void List_Incl_AddOffset(var int list, var int offset, var int data, var int size) {
        var int prev; prev = List_Node(list, offset);
        var int next; next = MEM_ReadInt(prev+4);
        var int ptr; ptr = MEM_Alloc(8);
        MEM_WriteInt(prev+4, ptr);
        MEM_WriteInt(ptr+4, next);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(ptr, dptr);
    };
    func void List_Incl_AddOffsetS(var int list, var int offset, var int data, var int size) {
        var int prev; prev = List_NodeS(list, offset);
        var int next; next = MEM_ReadInt(prev+8);
        var int ptr; ptr = MEM_Alloc(12);
        MEM_WriteInt(prev+8, ptr);
        MEM_WriteInt(ptr+8, next);
        var int dptr; dptr = MEM_Alloc(size);
        MEM_CopyBytes(data, dptr, size);
        MEM_WriteInt(ptr+4, dptr);
    };
    MfG Gottfried
    Geändert von Gottfried (08.10.2010 um 14:45 Uhr)

  5. Beiträge anzeigen #5 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline
    Sind im Post oben enthalten.

  6. Beiträge anzeigen #6 Zitieren
    Provinzheld
    Registriert seit
    Dec 2008
    Beiträge
    261
     
    apollo26 ist offline
    Vermutlich wieder eine tolle Frage, wenn ich mir List_Create(var int data) eine Liste erstelle wie heißt diese Liste dann, damit ich mit List_Add(var int list, var int data) einen wert hinzufügen kann.

  7. Beiträge anzeigen #7 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline
    Code:
    var int listPtr; listPtr = List_Create(data);
    Verständlich?

    Übrigens unterscheidet sich eine "Liste" nicht von einem einzelnen Teil der Liste, man muss bloß einen Anfang haben.

  8. Beiträge anzeigen #8 Zitieren
    Provinzheld
    Registriert seit
    Dec 2008
    Beiträge
    261
     
    apollo26 ist offline
    Wie ich schon sagte es war eine ganz tolle Frage
    Danke

  9. Beiträge anzeigen #9 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline
    Script oben geupdatet, da Bonne6 heute noch ein paar Fehler gefunden hat. Bei Fehleingabe wird nun aus der Funktion gesprungen (-1 ist ein Fehler).

  10. Beiträge anzeigen #10 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    ich kram den mal grad hoch.

    wenn ich das richtig sehe, kann man mit diesem listenskript eine einspaltige liste erstellen. was ist mit mehrspaltigen, also matrizen? z.b. 3 spalten und jeweils 5 zeilen:


    und dort dann verschiedene items reinspeichert, z.b.:

    Brot Käse Wein
    Eintopf Gebratenes Fleisch Wacholder
    Fischsuppe Fisch Wasser
    Wurst Honig Bier
    Apfel Muschelfleisch Milch

    und sie dann nach und nach abfragt, also auch die positionen, wenn z.b. das erste item gegessen wurde, soll das zweite in nem bestimmen FP_Item insertet werden.

    geht das auch?


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette

  11. Homepage besuchen Beiträge anzeigen #11 Zitieren
    Clockwork Origins Avatar von Bonne6
    Registriert seit
    Jun 2004
    Ort
    Erlangen
    Beiträge
    11.826
     
    Bonne6 ist offline
    Z.b. könntest du eine Liste machen, in der Listen stehen, also in Listenindex 0 steht der Zeiger auf eine Liste, die dann die Instancen für Brot, Käse und Wein enthält, an Index 1 dann eine Liste mit Eintopf, Fleisch und Wacholder usw.

  12. Beiträge anzeigen #12 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    oh, oder ich arbeite mit 3 verschiedenen 1-zeiligen listen, die unabhängig voneinander sind.
    mein "problem" ist halt die abfrage. wie krieg ich das item auf platz 5 da wieder rausgelesen?

    außerdem wurde im beispiel "nur" ein string in der liste gespeichert und vorher in einen char umgewandelt. kann ich ein item auch so einfach darin speichern? wenn ja: wie? über die instanz-id?

    tut mir leid, ich habe mich bisher nicht allzu intensiv damit beschäftigen können und stehe ein wenig "wie der ochs vorm berg"


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette

  13. Beiträge anzeigen #13 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline
    Zum Auslesen: http://gottfried.milgo.de/LeGo/de/?List#List_Get

    Listen können genau eine einzige Sache: einen Integer pro Listenelement speichern. Da Items größer als ein Integer sind, musst du dir überlegen, wie du sie entweder in einem Integer unterbringst (natürlich unmöglich) oder sie geeignet referenzieren (man kann z.B. einen Zeiger oder ein Handle speichern, um einen größeren Speicherbereich zu referenzieren). Bei Items nicht vergessen: Instanzen sind nicht eindeutig und Zeiger gehen beim Laden kaputt.

  14. Beiträge anzeigen #14 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    ist die ID, die man z.b. mit Hlp_GetInstanceID (itmi_bread); bekommt eigentlich eindeutig? oder ändert die sich jedes mal? vllt sollte ich mir dann doch lieber eine andere "warteschleife" bauen, in der ich die items einsortiere bzw. der spieler. über eine liste und zeiger wäre das dann doch etwas wackelig. ich werd mich zwar zu tode abfragen, aber egal.

    trotzdem danke


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette

  15. Beiträge anzeigen #15 Zitieren
    Veteran Avatar von Ingenieur
    Registriert seit
    Apr 2006
    Ort
    A-MD-BA-PRAHA
    Beiträge
    683
     
    Ingenieur ist offline
    Die Id ist seit der Kompilierung festgelegt, da sie den Symbolindex der des Objekt erstellenden Instanz wiedergibt.

    Wenn du neue Symbole vor der Iteminstanz hinzufügst, ändert sich der Symbolindex.

    Ich dachte, das wär allgemein bekannt?

    Ich kann mir nur schwer vorstellen, was du überhaupt vor hast. Du könntest drei Npcs nehmen und die Items in deren Inventaren speichern, aber das wär wohl zu einfach...

    Grüße, Ingenieur
    Zitat Zitat von Dalai Zoll Beitrag anzeigen
    Ich hab ´ne bessere Idee!
    World of Players Usermap

  16. Beiträge anzeigen #16 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline
    Am besten erläuterst du ein wenig genauer, was du machen willst. Vielleicht ist eine eindeutige Referenz auch überflüssig und das Speichern von Instanz sowie ggf. Anzahl reicht aus.

  17. Beiträge anzeigen #17 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    es geht um das wettfressen hier und hier habe ich das genauer beschrieben. auf die reihenfolge kommt es ganz sicher an, weil die items quasi in einer warteschleife "nachrücken". es wird das 1. item in der schlange auf den teller in der mitte insertet, wenn das mit w gegessen wurde, soll das 2. item insertet werden usw.


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette

  18. Beiträge anzeigen #18 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline
    Aber dann brauchst du ja keine Items speichern sondern nur die Instanzen, wenn du die Items noch nichteinmal eingefügt hast? Und wenn sie dann erstmal in der Welt liegen, isses ja gleich.

  19. Beiträge anzeigen #19 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    ja, ich muss die instanzen speichern. ich dachte dabei zuerst an 15 c_item-variablen, 5 davon für jeden platz. da ich mit einmaligen items arbeite, kann ich wohl jedes mal einen counter hochzählen und das nächste item einfügen. oder hast du eine platzsparendere methode?


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette

  20. Beiträge anzeigen #20 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.448
     
    Lehona ist offline
    Warum sprichst du jetzt von C_Items? Du brauchst keine Objekte sondern die Instanzen. Und wann du welche Counter hochzählen willst ist mir auch unklar. Wenn du nicht genau beschreibst, was du erreichen möchtest und wie du das zu tun gedenkst, kann zumindest ich dir nicht helfen.

Seite 1 von 2 12 Letzte »

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
Impressum | Link Us | intern
World of Gothic © by World of Gothic Team
Gothic, Gothic 2 & Gothic 3 are © by Piranha Bytes & Egmont Interactive & JoWooD Productions AG, all rights reserved worldwide