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

 

Page 1 of 22 12345812 ... Last »
Results 1 to 20 of 433
  1. View Forum Posts #1 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline

    [Skriptpaket] LeGo #4

    $$\.................$$$$$$\..............$$$$$$\..
    $$.|...............$$..__$$\............$$..__$$\.
    $$.|......$$$$$$\..$$./..\__|.$$$$$$\...\__/..$$.|
    $$.|.....$$..__$$\.$$.|$$$$\.$$..__$$\...$$$$$$..|
    $$.|.....$$$$$$$$.|$$.|\_$$.|$$./..$$.|.$$..____/.
    $$.|.....$$...____|$$.|..$$.|$$.|..$$.|.$$.|......
    $$$$$$$$\\$$$$$$$\.\$$$$$$..|\$$$$$$..|.$$$$$$$$\.
    \________|\_______|.\______/..\______/..\________|


    »Es gibt Lego, es gibt Minecraft, aber nichts ist so toll wie LeGo \o/«
    -Lehona


    LeGo [LehonaGottfried] ist, wie aus dem Titel ersichtlich, ein Skriptpaket das auf Ikarus aufbaut. Während Ikarus grundlegende Möglichkeiten bereitstellt, wird hier der Fokus auf die praktische Anwendung gelegt. Viele der enthaltenen Funktionen sind sehr einfach gehalten und müssen nicht in ein tolles Script eingeflochten werden um Sinn zu ergeben, sondern sind auch alleinstehend mächtig. Über pixelgenaues Erzeugen von Texten und Texturen auf dem Bildschirm und einem schönen Interface für Trialoge (eigentlich "Polyloge"), bis hin zu "Triggerlosen Triggerschleifen" die mit nur einer Zeile aktiviert werden können beinhaltet LeGo sicher für jeden Scripter eine interressante Erweiterung die ihm von Nutzen sein kann.
    Sicher sind manche Pakete sehr speziell oder einfach nur nutzloser als andere, das liegt daran dass LeGo nicht aus einer Idee "Lass uns ein Scriptpaket machen!" entstanden ist. Ursprünglich war alles was hier zu finden ist als Grundlage für unseren Beitrag zum Modding-Contest gedacht, da Lehona und ich aber leider nicht fertig geworden sind (aus eigener Faulheit, zugegebenermaßen) lag dieser Featurehaufen noch ungeordnet und ohne Nutzen auf unseren Platten. Nun, da wir beide nette Menschen sind haben wir uns überlegt den ganzen Kram zu sortieren, kommentieren und zu erklären (was bei unserer Arbeitweise beim besten Willen nicht einfach war) und hier zur Verfügung zu stellen.
    Sektenspinners zweifellos vorhandene Unterstützung sei natürlich auch noch erwähnt. Ohne ihn hätte sich der Release entweder noch um ein paar Jahren hingezogen oder es gäbe gar keinen

    LeGo wird laufend erweitert, nicht zuletzt wenn DU gute Vorschläge für weitere Funktionen hast. In den vergangenen Jahren wurden einige Wünsche aufgegriffen, von denen wir denken, dass fertige Lösungen auch anderen weiterhelfen könnten. Einige wenige Modder haben auch schon fertige Scripte bereitgestellt, die wir einfach in LeGo einpflegen konnten. Wir freuen uns immer darauf, mit anderen Moddern zusammenzuarbeiten, also keine falsche Scheu!

    Abschließend sei noch folgendes gesagt: Da LeGo ziemlich umfangreich geworden ist können wir keine Fehlerfreiheit garantieren. Jedes Paket wurde bereits genutzt und in den vielen vergangenen Versionen wurden eine beträchtliche Menge an Bugs behoben. Wenn du dennoch einen Fehler entdecken solltest (oder ein grundlosen Absturz bekommst, was auch immer ) dann schreib doch ein paar Zeilen in diesen Thread in denen du kurz erläuterst was genau du getan hast und welche der Pakete aktiv waren, damit wir den Fehler beheben können.


    Ältere Threads



    Wiki

    Beispiele und Dokumentationen aller Funktionen innerhalb des Scriptpaketes
    Startseite


    Anwendungsbeispiele



    Download




    Viel Spaß mit diesem Paket wünschen euch
    Gottfried, Lehona und viele weitere Helfer!
    Last edited by Lehona; 19.06.2020 at 19:46.

  2. View Forum Posts #2 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline
    LeGo 2.5.0

    I'd like to thank mud-freak and mark56 for their help on improving LeGo. They were the ones that made this release possible, without them it would have taken much longer

    • Gothic 1 support (except for experimental packages)
    • Hooks have been reworked (allow recursive hooks, backup global instances and secure data stack)
    • Draw3D (see Wiki)
    • ConsoleCommands are no longer written to game saves, but kept for the duration of the session
    • It can now be checked whether hooks are active (and they may be removed, not recommended)
    • New functions to replace and disable engine functions
    • NPCs are no longer stuck after trialogs (thanks to Cryp18Struct)
    • Level change is now correctly detected every time (sure...)
    • New List functions (List_AddFront*)
    • New View function (View_AddTextColored)
    • Minor fixes on Anim8, Bloodspats, Interface, zCViewText and arrays


    Because of the Gothc 1 compatibility, the files EngineAdr_G1.d or EngineAdr_G2.d now need to be removed when installing LeGo for Gothic 2 or Gothic 1, respectively. There is an attempt to warn users when they forget to do this, but there's not much we can do in terms of error messages.
    Last edited by Lehona; 20.11.2017 at 21:34.

  3. Visit Homepage View Forum Posts #3 Reply With Quote
    Clockwork Origins Bonne6's Avatar
    Join Date
    Jun 2004
    Location
    Erlangen
    Posts
    11,651
     
    Bonne6 is offline
    Nice, freut mich, dass es jetzt die neue Version gibt und endlich den offiziellen Gothic 1 Support
    Dann kann ich ja XR nochmal auf die aktuelle Version updaten, hätte den Fix für Auflösung beim Interface sonst wieder vergessen noch einzubauen

  4. Visit Homepage View Forum Posts #4 Reply With Quote
    Clockwork Origins Bonne6's Avatar
    Join Date
    Jun 2004
    Location
    Erlangen
    Posts
    11,651
     
    Bonne6 is offline
    Grad mal getestet, mit 2.5 funktionieren Buttons nicht mehr (zumindest Enter und Click Funktion werden nicht mehr ausgeführt).

    Werd's gleich noch weiter analysieren, bin nur grad zufällig drüber gestolpert.

  5. View Forum Posts #5 Reply With Quote
    Veteran
    Join Date
    Jan 2012
    Posts
    680
     
    Frank-95 is offline
    Nice work guys!

    One question:

    If I hooked an engine function and did something like this:

    Code:
    hookengine(eng_function, myfunction)
    
    func void myfunction()
    {
        if(conditionmet)
        {
            disableenginefunc(eng_function)
        }
        else
        {
            //don't disable
        };
    };
    How could I restore the function?

  6. View Forum Posts #6 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline
    Do you want to completely remove the hook and restore the original assembly?
    The easiest way is to just not do that (exit early out of the daedalus function to minimize performance impact), unless it has a measurable performance impact.

    Edit: Ah, you want to conditionally execute the function? I don't think that's supported by LeGo (you can try messing with the registers, though, sometimes there is some guard code that will let you trigger an early return).

    @Bonne: Ich schau mal, ob ich das so einfach reproduzieren kann.

    Edit: Kann ich nicht reproduzieren, bei mir funktioniert es. Hast du vielleicht die Buttons mal verändert und verlässt dich in deinem Code darauf (Ich erinnere mich dass du mal sowas gemacht hast für EW)?

  7. Visit Homepage View Forum Posts #7 Reply With Quote
    Clockwork Origins Bonne6's Avatar
    Join Date
    Jun 2004
    Location
    Erlangen
    Posts
    11,651
     
    Bonne6 is offline
    Quote Originally Posted by Lehona View Post
    @Bonne: Ich schau mal, ob ich das so einfach reproduzieren kann.

    Edit: Kann ich nicht reproduzieren, bei mir funktioniert es. Hast du vielleicht die Buttons mal verändert und verlässt dich in deinem Code darauf (Ich erinnere mich dass du mal sowas gemacht hast für EW)?
    Hab nochmal nachgeschaut, hatte tatsächlich was geändert, genauer gesagt gefixt. Denn aktuell kann man Buttons in LeGo nicht verschieben, ohne, dass die Funktionen kaputt gehen, weil btn.posx und Co nicht mit verschoben werden.

    Hab dazu noch die Member width und height eingeführt und diese in der Button_Create gesetzt.

    Dann noch in Button_Move

    Code:
    btn.posx = Print_ToVirtual(nposx, PS_X);
    btn.posy = Print_ToVirtual(nposy, PS_Y);
    btn.posx2 = Print_ToVirtual(nposx, PS_X) + btn.width;
    btn.posy2 = Print_ToVirtual(nposy, PS_Y) + btn.height;
    Hab ich gebraucht, weil ich für das Minispiel in XR (und auch das Puzzlespiel) Buttons benutze und die natürlich verschoben werden. Sicherlich nicht verkehrt das in LeGo aufzunehmen.

  8. View Forum Posts #8 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline
    Deine Implementierung ist fehlerhaft, denn View_Move (und damit auch Button_Move) sind relative Bewegungen. So klappt es:

    Code:
    func void Button_Move(var int hndl, var int nposx, var int nposy) {
    	var _Button btn; btn = get(hndl);
    	var int width; width = btn.posx2 - btn.posx;
    	var int height; height = btn.posy2 - btn.posy;
    	View_MovePxl(btn.view, nposx, nposy);
    	
    	btn.posx += Print_ToVirtual(nposx, PS_X);
    	btn.posx2 = btn.posx + width;
    	
    	btn.posy += Print_ToVirtual(nposy, PS_Y);
    	btn.posy2 = btn.posy + height;
    };
    
    // Sadly I chose Pxl as the "default" move. I regret that.
    func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy) {
    	Button_Move(hndl, Print_ToPixel(nvposx, PS_X), Print_ToPixel(nvposy, PS_Y));
    };
    Ohne das += stimmt das "aktive" Gebiet nicht mit dem View überein.

    Edit: Ich sehe gerade, dass die Dokumentation im Wiki etwas völlig anderes sagt. Ich pass das mal an und schreib gleich noch eine MoveTo-Funktion...
    Last edited by Lehona; 21.11.2017 at 21:59.

  9. Visit Homepage View Forum Posts #9 Reply With Quote
    Clockwork Origins Bonne6's Avatar
    Join Date
    Jun 2004
    Location
    Erlangen
    Posts
    11,651
     
    Bonne6 is offline
    Quote Originally Posted by Lehona View Post
    Deine Implementierung ist fehlerhaft, denn View_Move (und damit auch Button_Move) sind relative Bewegungen. So klappt es:

    Code:
    func void Button_Move(var int hndl, var int nposx, var int nposy) {
    	var _Button btn; btn = get(hndl);
    	var int width; width = btn.posx2 - btn.posx;
    	var int height; height = btn.posy2 - btn.posy;
    	View_MovePxl(btn.view, nposx, nposy);
    	
    	btn.posx += Print_ToVirtual(nposx, PS_X);
    	btn.posx2 = btn.posx + width;
    	
    	btn.posy += Print_ToVirtual(nposy, PS_Y);
    	btn.posy2 = btn.posy + height;
    };
    
    // Sadly I chose Pxl as the "default" move. I regret that.
    func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy) {
    	Button_Move(hndl, Print_ToPixel(nvposx, PS_X), Print_ToPixel(nvposy, PS_Y));
    };
    Ohne das += stimmt das "aktive" Gebiet nicht mit dem View überein.
    Wieso hat das denn dann bisher so funktioniert? Ist das erwiesenermaßen ein MoveBy statt einem MoveTo? Also ich weiß es nicht, aber ich nutz es scheinbar von je her als MoveTo und das funzt.

  10. View Forum Posts #10 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,776
     
    mud-freak is offline
    Quote Originally Posted by Frank-95 View Post
    If I hooked an engine function and did something like this:

    Code:
    hookengine(eng_function, myfunction)
    
    func void myfunction()
    {
        if(conditionmet)
        {
            disableenginefunc(eng_function)
        }
        else
        {
            //don't disable
        };
    };
    How could I restore the function?
    Just to clear up what DisableEngineFunc does:
    DisableEngineFunc completely disables a given engine function without the provided option to re-enable it: It overwrites the first (one or three) bytes of the function to return immediately.
    Obviously, that won't work in your code example. Your use of the function above would cause an error-message, because you may only hook or disable an engine function.
    To use it, you only need to call DisableEngineFunc(address_of_engine_function, number_of_parameters); once for the session.

    I had only quickly added that function while working on the hooks, without much more thought about practical applications.


    Re-enabling the engine function is actually pretty easy (see example code below). But, again, you cannot use it alongside a hook. In your case (if you want to conditionally disable an engine function when it is being called), it's best to follow Lehona's advice.

    Code:
    var int funcAddr; funcAddr = 123456;
    var int numParams; numParams = 2; // Number of function parameters if its calling convention is __thiscall
    
    
    // Disable engine function (and backup original bytes)
    var int origBytes; origBytes = MEM_ReadInt(funcAddr);
    DisableEngineFunc(funcAddr, numParams);
    
    // ...
    
    // Re-enable engine function (by restoring original bytes)
    MemoryProtectionOverride(funcAddr, 4);
    MEM_WriteInt(funcAddr, origBytes);

  11. View Forum Posts #11 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline
    Quote Originally Posted by Bonne6 View Post
    Wieso hat das denn dann bisher so funktioniert? Ist das erwiesenermaßen ein MoveBy statt einem MoveTo? Also ich weiß es nicht, aber ich nutz es scheinbar von je her als MoveTo und das funzt.
    Ja, ich bin mir sicher. Etwas längeren Post dazu gibt es Morgen, mein Internet macht gerade nicht mit und ich will den nicht abtippen

  12. View Forum Posts #12 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline
    Ziemlich sicher, ja. Vielleicht hast du das in deinem Fix damals unabsichtlicherweise geändert?

    Du kannst ja meinen Code einfach mal probieren (jetzt auch mit MoveTo).

    Code:
    func void Button_Move(var int hndl, var int nposx, var int nposy) {
    	var _Button btn; btn = get(hndl);
    	var int width; width = btn.posx2 - btn.posx;
    	var int height; height = btn.posy2 - btn.posy;
    	View_MovePxl(btn.view, nposx, nposy);
    	
    	btn.posx += Print_ToVirtual(nposx, PS_X);
    	btn.posx2 = btn.posx + width;
    	
    	btn.posy += Print_ToVirtual(nposy, PS_Y);
    	btn.posy2 = btn.posy + height;
    };
    
    // Sadly I chose Pxl as the "default" Move. I regret that.
    func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy) {
    	Button_Move(hndl, Print_ToPixel(nvposx, PS_X), Print_ToPixel(nvposy, PS_Y));
    };
    
    func void Button_MoveTo(var int hndl, var int nposx, var int nposy) {
    	var _Button btn; btn = get(hndl);
    	var int width; width = btn.posx2 - btn.posx;
    	var int height; height = btn.posy2 - btn.posy;
    	View_MoveToPxl(btn.view, nposx, nposy);
    	
    	btn.posx = Print_ToVirtual(nposx, PS_X);
    	btn.posx2 = btn.posx + width;
    	
    	btn.posy = Print_ToVirtual(nposy, PS_Y);
    	btn.posy2 = btn.posy + height;
    };
    
    // Sadly I chose Pxl as the "default" MoveTo. I regret that.
    func void Button_MoveToVrt(var int hndl, var int nvposx, var int nvposy) {
    	Button_MoveTo(hndl, Print_ToPixel(nvposx, PS_X), Print_ToPixel(nvposy, PS_Y));
    };
    View_Move() bzw. zCView::Move bewegt auf jedenfall relativ.

  13. Visit Homepage View Forum Posts #13 Reply With Quote
    Clockwork Origins Bonne6's Avatar
    Join Date
    Jun 2004
    Location
    Erlangen
    Posts
    11,651
     
    Bonne6 is offline
    Quote Originally Posted by Lehona View Post
    Ziemlich sicher, ja. Vielleicht hast du das in deinem Fix damals unabsichtlicherweise geändert?

    Du kannst ja meinen Code einfach mal probieren (jetzt auch mit MoveTo).

    Code:
    func void Button_Move(var int hndl, var int nposx, var int nposy) {
    	var _Button btn; btn = get(hndl);
    	var int width; width = btn.posx2 - btn.posx;
    	var int height; height = btn.posy2 - btn.posy;
    	View_MovePxl(btn.view, nposx, nposy);
    	
    	btn.posx += Print_ToVirtual(nposx, PS_X);
    	btn.posx2 = btn.posx + width;
    	
    	btn.posy += Print_ToVirtual(nposy, PS_Y);
    	btn.posy2 = btn.posy + height;
    };
    
    // Sadly I chose Pxl as the "default" Move. I regret that.
    func void Button_MoveVrt(var int hndl, var int nvposx, var int nvposy) {
    	Button_Move(hndl, Print_ToPixel(nvposx, PS_X), Print_ToPixel(nvposy, PS_Y));
    };
    
    func void Button_MoveTo(var int hndl, var int nposx, var int nposy) {
    	var _Button btn; btn = get(hndl);
    	var int width; width = btn.posx2 - btn.posx;
    	var int height; height = btn.posy2 - btn.posy;
    	View_MoveToPxl(btn.view, nposx, nposy);
    	
    	btn.posx = Print_ToVirtual(nposx, PS_X);
    	btn.posx2 = btn.posx + width;
    	
    	btn.posy = Print_ToVirtual(nposy, PS_Y);
    	btn.posy2 = btn.posy + height;
    };
    
    // Sadly I chose Pxl as the "default" MoveTo. I regret that.
    func void Button_MoveToVrt(var int hndl, var int nvposx, var int nvposy) {
    	Button_MoveTo(hndl, Print_ToPixel(nvposx, PS_X), Print_ToPixel(nvposy, PS_Y));
    };
    View_Move() bzw. zCView::Move bewegt auf jedenfall relativ.
    Also ich hatte sonst keine Änderungen in den Buttons und auch in View nicht. Ich glaube mich zu erinnern, dass ich schon immer verwundert war, dass die sich bei gleicher Benamung unterschiedlich verhalten haben. Jetzt funktioniert Move aber nicht mehr, jetzt muss ich MoveTo verwenden. Abgesehen davon bisher keine Probleme entdeckt, gute Arbeit

  14. View Forum Posts #14 Reply With Quote
    Sword Master
    Join Date
    Aug 2009
    Location
    Hessen
    Posts
    960
     
    Cryp18Struct is offline
    In Dialoggestures.d ist ein Fehler, es wird auf nicht existierende Animationen zurück gesetzt:
    Code:
    //========================================
    // Gesten zurücksetzen
    //========================================
    func void DIAG_Reset() {
        AI_WaitTillEnd(self, other);
        AI_WaitTillEnd(other, self);
        AI_Function_SI(other, _DIAG, "T_DIALOGGESTURES_", -1); // T_DIALOGGESTURES_ ist falsch. richtig : T_DIALOGGESTURE_
        AI_WaitTillEnd(self, other);
    };
    
    //========================================
    // [intern]
    //========================================
    func void _DIAG(var string AniName, var int ptr) {
        if(!STR_Compare(AniName, "T_DIALOGGESTURES_")) { // T_DIALOGGESTURES_ ist falsch. richtig : T_DIALOGGESTURE_
            DIAG_SetMinMax(1, 20);
            _DIAG_SetAni(AniName);
            return;
        };
        DIAG_SetMinMax(MEM_ReadInt(ptr), MEM_ReadInt(ptr+4));
        MEM_Free(ptr);
        DIAG_SetAni(AniName);
    };
    Symptom im Spiel: keine Dialoggesten mehr nach Auffruf von DIAG_Reset.

  15. View Forum Posts #15 Reply With Quote
    Local Hero Orcane's Avatar
    Join Date
    Apr 2012
    Posts
    233
     
    Orcane is offline
    Ich habe kurz mit Google gesucht, wurde aber nicht fündig. Hat schon jemand versucht das Kampfsystem dahingehend zu ändern, dass mit einem Schlag mehrere Gegner getroffen werden können? So wie es beispielsweise bei Risen ist.

    Da Free Aim geht nehme ich an, dass sowas auch in Gothic gehen müsste...

  16. View Forum Posts #16 Reply With Quote
    Schwertmeister
    Join Date
    Oct 2015
    Posts
    931
     
    Woozel is offline
    Quote Originally Posted by Orcane View Post
    Ich habe kurz mit Google gesucht, wurde aber nicht fündig. Hat schon jemand versucht das Kampfsystem dahingehend zu ändern, dass mit einem Schlag mehrere Gegner getroffen werden können? So wie es beispielsweise bei Risen ist.

    Da Free Aim geht nehme ich an, dass sowas auch in Gothic gehen müsste...
    Das gibt es definitiv, habe das in einem Youtube-Video von russischen Moddern schon in Aktion gesehen,
    ist aber zu lang her dass ich noch wüsste was es war.
    Ob das hier in worldofgothic schon jemand gemoddet hat weiß ich nicht.

  17. View Forum Posts #17 Reply With Quote
    now also in your universe  Milky-Way's Avatar
    Join Date
    Jun 2007
    Posts
    13,953
     
    Milky-Way is offline
    Ich habe einen "Monolog" bei dem ich einfach so in den Scripten mit
    Code:
    AI_Output(hero,hero,...); // ...
    den Helden einen Text sagen lasse. Dabei ist noch unschön, dass der Held mit dem Rücken zur Kamera steht und spricht. Gibt es eine einfache Möglichkeit, mit den Trialog-Funktionen dafür zu sorgen, dass die Kamera den Helden von vorne zeigt (oder sich der Held zur Kamera dreht)?

  18. View Forum Posts #18 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline
    Gibt es nicht sowas wie AI_TurnAround(npc)? Aber ich glaube da ist aus den Trialogskripten nichts herauszuholen - die "manipulieren" die Kamera einfach nur, in dem die der eigentliche Gesprächspartner Position und Aussehen wechselt.

  19. View Forum Posts #19 Reply With Quote
    Waldläufer Siemekk's Avatar
    Join Date
    May 2016
    Posts
    121
     
    Siemekk is offline
    How's work this HookDaedalusFunc? Can you make a example?

  20. View Forum Posts #20 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,300
     
    Lehona is offline
    Quote Originally Posted by Siemekk View Post
    How's work this HookDaedalusFunc? Can you make a example?
    They are currently Work in Progress, i.e. I'm not sure they work properly. It works like this at the moment:

    Code:
    func void onDeath() {
        Print("ZS_DEAD has been called");
        ContinueCall();
    };
    
    
    // Execute this once to initialize the hook
    func void setup() {
        HookDaedalusFunc(ZS_DEAD, onDeath);
    };
    Looking at the code it will probably stop working once you save/restart/load the game.



    I think you can even "steal" the parameters:

    Code:
    func void OnGiveTradeInv(var c_npc slf) {
        Print(slf.name);
        PassArgumentN(slf);
        ContinueCall();
    };
    
    func void setup() {
        HookDaedalusFunc(B_GiveTradeInv, OnGiveTradeInv);
    };

Page 1 of 22 12345812 ... Last »

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
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