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 35
  1. Beiträge anzeigen #1 Zitieren
    Knight Avatar von GenerationLost
    Registriert seit
    Apr 2009
    Ort
    Whereabouts Unknown
    Beiträge
    1.774
     
    GenerationLost ist offline

    [G1 Script] TES-ähnliches Carry Weight System

    Hallo Leute!

    Ich möchte euch gerne ein kleines Script für G1 vorstellen. Etwas, was ich im Rahmen meines Modprojekts entwickelt habe und dachte, es könnte ja evtl. auch für euch interessant sein (auch wenn die meisten wohl eh für G2 entwickeln).

    Dazu möchte ich zunächst sagen, es ist nicht perfekt und hat hier und da noch ein paar Macken, vielleicht fehlt an einigen Stellen auch noch etwas, was ich nicht beachtet habe. Nichts was sich nicht lösen lässt, denke ich. Über Verbesserungsvorschläge und generell Feedback würde ich mich also sehr freuen.

    Also, worum geht es hier?
    Ziel war es im Grunde, das Weight-System aus den meisten Bethsda-Spielen, also der "The Elder Scrolls" Reihe sowie den neueren Fallout Titeln, nachzubauen. Items haben einen Gewichtswert und der Spieler einen Gewichtslimit. Wird dieser Maximalwert überschritten, wird der Spieler verlangsamt und kann nicht mehr rennen. Es verhindert also NICHT die Aufnahme von weiteren Gegenständen, wenn das Inventar bereits "voll" ist.

    Zur Verwendung wird Ikarus und LeGo benötigt.

    Und hier ist der Code:
    Code:
    /****************************************************
    *			Carry Weight System for G1
    *
    * This system aims to create a similar experience 
    * as in Bethesda games like Fallout 4 and Skyrim.
    * The player has weight limit and every item has a 
    * weight value. Picking up items adds those weight
    * values towards the limit and if it's reached, 
    * the player isn't able to run anymore. 
    *
    * Obviously, this uses the "weight" property of 
    * the item class, though any custom property can
    * be used instead.
    ****************************************************/
    
    
    
    //The player's current weight points
    var int 	Player_CarryWeight;
    
    //taken from The Long Dark survival game as reference
    //1 weight unit should be 1kg
    //300 weight would be 30kg then
    const int 	CarryWeightMax = 300;	
    
    //Safety var to check if overlay is applied
    //FIXME: Trotzdem sollte das Overlay erst NACH DEM SCHLIESSEN
    //	der Truhe angehängt werden, sonst passiert der gleiche Fehler!
    var int CarryWeight_SlowedDown;	
    
    //LeGo handle for the weight bar
    var int 	CarryWeightBarHndl;
    //Bar instance, shown above the mana bar
    instance CarryWeight_Bar(GothicBar)
    {
    	x = Print_Screen[PS_X] - 100;
    	y = Print_Screen[PS_Y] - 60;
    	barTex = "Bar_Weight.tga";
    };
    
    /****************************************************
    *			Pickup and Drop functions	
    *
    * These functions add or remove weight points from
    * the item in the argument and apply or remove
    * slowdowns. 
    *
    * - Used in hooked functions and for consuming items
    * - Only the hero is affected	
    *****************************************************/
    func void CarryWeight_PickUp(var c_npc slf, var C_ITEM itm, var int amt)
    {
    	if(Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(PC_Hero))
    	{
    		//count of stacked Items in "amt"
    		Player_CarryWeight += itm.weight*amt;
    		
    		if (Player_CarryWeight > CarryWeightMax)
    		{
    			Mdl_ApplyOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    			
    			//hero comment before var is set to true
    			if(!CarryWeight_SlowedDown)
    			{
    				B_SayOverlay(hero,hero,"$INVFULL");
    			};
    			
    			CarryWeight_SlowedDown = true;
    		};
    		
    		Bar_SetValue(CarryWeightBarHndl, Player_CarryWeight);
    	};
    };
    
    func void CarryWeight_Drop(var c_npc slf, var C_ITEM itm, var int amt)
    {
    	if(Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(PC_Hero))
    	{
    		//count of stacked Items in "amt"
    		Player_CarryWeight -= itm.weight*amt;
    		
    		if (Player_CarryWeight < CarryWeightMax && CarryWeight_SlowedDown == true)
    		{
    			Mdl_RemoveOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    			CarryWeight_SlowedDown = false;
    		};
    		
    		//Safety first?
    		if(Player_CarryWeight < 0)
    		{
    			Player_CarryWeight = 0;
    		};
    		
    		Bar_SetValue(CarryWeightBarHndl, Player_CarryWeight);
    	};
    };
    
    /************************************************
    *	INTERN		Hook functions & init			*
    ************************************************/
    
    //NPC -> Hero || Hero -> Container
    //used ONLY for dropping items to container!
    func void _CarryWeight_DropToContainer()
    {
    	//Thanks to F a w k e s
    	var oCItemContainer Item_Container;
        var C_NPC npc;
        var oCItem itm;
        var int amount;
        var C_ITEM itmInstance;
        var oCNPC her;
    
        Item_Container = _^(ECX);
        
        //Get inventory owner
        npc = _^(Item_Container.inventory2_owner);
        
        //Get item
        itm = _^(List_GetS(Item_Container.inventory2_oCItemContainer_contents, Item_Container.inventory2_oCItemContainer_selectedItem + 2));
    	itmInstance = MEM_PtrToInst(List_GetS(Item_Container.inventory2_oCItemContainer_contents, Item_Container.inventory2_oCItemContainer_selectedItem + 2));
        
        //Get item quantity
        amount = MEM_ReadInt(ESP + 8);
    	
    	if(itm.amount < amount)
    	{
    		amount = itm.amount;
    	};
    
    	CarryWeight_Drop(npc, itmInstance, amount);
    };
    
    //Container -> Hero || NPC -> Hero
    func void _CarryWeight_LootContainer()
    {
    	//mit Hilfe von F a w k e s
        var oCItem itm;
        var C_ITEM itmInstance;
        
        //Get item
        itm = _^((MEM_ReadInt(ESP+4)));
    	itmInstance = MEM_PtrToInst(MEM_ReadInt(ESP+4));
    
    	//amount is just one since oCItemContainer__Remove_Item
    	//is called for every item in stack (so 5 times for 5 beer in a stack)
    	CarryWeight_PickUp(hero, itmInstance, 1);
    };
    
    //for picking up items from the ground
    func void _CarryWeight_DoTakeVob()
    {
    	//get NPC and item
    	var c_npc slf; slf = MEM_PtrToInst(ECX);		
    	var C_ITEM itm; itm = MEM_PtrToInst(MEM_ReadInt(ESP + 4));	
    	//C_ITEM has no amount property, that's why we need 
    	//the engine class object here
    	var oCItem itmobj; itmobj = _^(MEM_ReadInt(ESP + 4));	
    	
    	if (!Hlp_IsValidItem (itm)) { return; };
    	if (!Hlp_IsValidNpc (slf)) { return; };
    	
    	CarryWeight_PickUp(slf, itm, itmobj.amount);
    };
    
    //FIXME: not callef if player in ZS_Unconscious!
    //	check for drawn weapon there to call 
    //	CarryWeight_Drop on it?
    func void _CarryWeight_Drop()
    {
    	var c_npc slf; slf = MEM_PtrToInst(ECX);
    	var C_ITEM itm; itm = MEM_PtrToInst(MEM_ReadInt(ESP + 4));
    	var oCItem itmobj; itmobj = _^(MEM_ReadInt(ESP + 4));
    
    	if (!Hlp_IsValidItem (itm)) { return; };
    	if (!Hlp_IsValidNpc (slf)) { return; };
    	
    	CarryWeight_Drop(slf, itm, itmobj.amount);
    };
    
    //by F a w k e s
    FUNC void CarryWeight_AddInvCategoryWeight (var C_NPC slf, var int inv_category)
    {
        var int p;
        var int itm_slot; itm_slot = 0;
        var int amount;
    	
        //Loop
        p = MEM_StackPos.position;
    
        //Is there any item in itm_slot ?
    	amount = NPC_GetInvItemBySlot (slf, inv_category, itm_slot);
        if (amount > 0)
        {
            //item is filled by above NPC_GetInvItemBySlot
    		CarryWeight_PickUp(hero, item, amount);
    
            itm_slot = itm_slot + 1;
            MEM_StackPos.position = p;
        };
    };
    
    FUNC void CarryWeight_RecalcInventory ()
    {
    	//PrintScreen	("Recalculating Inventory...", -1,-1,"font_old_20_white.tga",3);
    	
    	Player_CarryWeight = 0;
        CarryWeight_AddInvCategoryWeight (hero, INV_WEAPON);
        CarryWeight_AddInvCategoryWeight (hero, INV_ARMOR);
        CarryWeight_AddInvCategoryWeight (hero, INV_RUNE);
        CarryWeight_AddInvCategoryWeight (hero, INV_MAGIC);
        CarryWeight_AddInvCategoryWeight (hero, INV_FOOD);
        CarryWeight_AddInvCategoryWeight (hero, INV_POTION);
        CarryWeight_AddInvCategoryWeight (hero, INV_DOC);
        CarryWeight_AddInvCategoryWeight (hero, INV_MISC);
    };
    
    //Needed to alter this function so receiving items in dialog
    //adds the right amoung of weight to the player
    //////////////////////////////////////////////////////////////////////////
    //	B_GiveInvItems
    //	==============
    //	Übergibt ein Item von 'giver' an 'taker' und gibt eine Meldung
    //	auf dem Bildschirm aus.
    //////////////////////////////////////////////////////////////////////////
    func void B_GiveInvItems(var C_NPC giver, var C_NPC taker, var int itemInstance, var int amount)
    {
    	PrintDebugNpc	(PD_ZS_DETAIL,	"B_GiveInvItems");
    	
    	//add up Carry Weight
    	Npc_GetInvItem(giver,itemInstance);	//fills global item Variable
    	CarryWeight_PickUp(taker, item, amount);
    
    	//-------- Gegenstand übertragen --------
    	Npc_RemoveInvItems	(giver,	itemInstance,	amount);
    	CreateInvItems		(taker,	itemInstance,	amount);
    
    	//-------- Meldung ausgeben --------
    	var string msg;
    
    	if	Npc_IsPlayer(giver)
    	{
    		if (itemInstance == ItMiNugget)
    		{
    			msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ORE_GIVEN);
    			PrintScreen	(msg, -1,_YPOS_MESSAGE_GIVEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_GIVEN);
    		}
    		else
    		{
    		    if amount == 1
    		    {
    			    msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ITEM_GIVEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_GIVEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_GIVEN);
    			}   
    			else
    		    {
    			    msg = ConcatStrings(IntToString(amount),_STR_MESSAGE_ITEMS_GIVEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_GIVEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_GIVEN);
    			};   
    		};
    	}
    	else if Npc_IsPlayer(taker)
    	{
    		if (itemInstance == ItMiNugget)
    		{
    			msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ORE_TAKEN);
    			PrintScreen	(msg, -1,_YPOS_MESSAGE_TAKEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_TAKEN);
    		}
    		else
    		{
    		    if amount == 1
    		    {
    			    msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ITEM_TAKEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_TAKEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_TAKEN);
    			}   
    			else
    		    {
    			    msg = ConcatStrings(IntToString(amount),_STR_MESSAGE_ITEMS_TAKEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_TAKEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_TAKEN);
    			}; 
    		};
    	};	
    };
    
    //Flip-Flop func to show and hide the weight bar
    //- called on opening/exiting menues
    func int CarryWeight_ShowHideBar()
    {
    	var int show;
    	
    	if(show)
    	{
    		Bar_Hide(CarryWeightBarHndl);
    
    		show = false;
    	}
    	else
    	{
    		Bar_Show(CarryWeightBarHndl);
    
    		show = true;
    	};
    	
    	return show;
    };
    
    //G1 addresses
    const int oCNpc__DoTakeVob = 6950160; //006A0D10 / 6
    const int oCNPC__DoDropVob = 6951152; //006A10F0 / 6
    const int oCItemContainer__TransferItem = 6723456; //00669780 / 5
    const int oCItemContainer__Remove_Item = 6722512; //006693D0 / 5
    const int oCViewDialogTrade__OnExit = 7514800; //0072AAB0 / 5
    const int oCNpc__DropAllInHand = 6898224;	//00694230 / 5
    const int oCGame__SetShowPlayerStatus = 6523872;  //00638BE0 / 6
    
    //Init function
    //Should be called in Startup.d for every world
    func void CarryWeight_Init()
    {
    	HookEngine (oCNpc__DoTakeVob, 6, "_CarryWeight_DoTakeVob");
    	HookEngine (oCNPC__DoDropVob, 6, "_CarryWeight_Drop");
    	HookEngine (oCItemContainer__TransferItem, 5, "_CarryWeight_DropToContainer"); 
    	HookEngine (oCItemContainer__Remove_Item, 6, "_CarryWeight_LootContainer");
    	HookEngine (oCViewDialogTrade__OnExit, 5, "CarryWeight_RecalcInventory");
    	HookEngine (oCNpc__DropAllInHand, 5, "CarryWeight_RecalcInventory");
    	
    	HookEngine(oCGame__SetShowPlayerStatus, 6, "CarryWeight_ShowHideBar");
    
    	if(!Hlp_IsValidHandle(CarryWeightBarHndl)) 
    	{
    		CarryWeightBarHndl = Bar_Create(CarryWeight_Bar);
        };
    	
        Bar_SetMax(CarryWeightBarHndl, CarryWeightMax);
        Bar_SetValue(CarryWeightBarHndl, Player_CarryWeight);
    	Bar_Show(CarryWeightBarHndl);
    };
    Ich hoffe, dass sich durch das ganze Refractoring im Nachhinein keine Fehler eingeschlichen haben. Habe es vorher noch schnell getestet und es lief. Falls doch was schief geht möchte ich mich im Voraus schon dafür entschuldigen.

    Vor allem was die Hooks angeht, ein großes Dankeschön an F a w k e s, der mir einige Snippets zur Verwendung freigegeben hat. Und natürlich auch ein großes Danke an Lehona, der mir bzgl. Ikarus, LeGo, Engineadressen etc. immer mal wieder auf die Sprünge hilft. Ohne euch wäre ich wohl nie so weit gekommen.

    Im angehängten Archiv ist noch eine Datei mit Gewichtskonstanten für die Items und eine erweiterte Version der Klasse oCNPC. Letzteres ist ebenfalls Voraussetzung, damit mein Script funktioniert. Die Gewichtskonstanten müssen dann für jedes Item für das weight-Attribut eingetragen werden. Missions-Items sollten dabei ignoriert werden, um den Spieler nicht zusehr einzugrenzen (so wird das auch in TES-Spielen gemacht). Zusätzlich muss für Items die "verbraucht" werden (Nahrung, Joints, etc) jeweils die Funktion "CarryWeight_Drop" in der on_state Funktion aufgerufen werden. Angepasste Itemscripts und die Overlay-MDS sind ebenfalls im Archiv.

    Bekannte Bugs und andere Hinweise:
    • Das ganze System bezieht sich strikt auf den Helden (PC_Hero) und ignorierte alle anderen NPC Instanzen, z.B. solche, die im Marvin-Mode mit "o" übernommen wurden und auch die, die mit dem Kontroll-Zauberspruch übernommen wurden und damit also in die globale "hero" Variable geschrieben werden.
    • Beim erreichen des Gewichtslimits dreht der Hero sich gen Norden bevor er sein Kommentar abgibt. Sieht nicht nur unschön aus, sondern kann auch Truhen offenstehen lassen (evtl. bis zur Unbenutzbarkeit).
    • Das gleiche gilt für das auflegen des "Verlangsamungs-Overlays". Der Hero ploppt dann von Truhen weg, welche dann ggf. nicht mehr benutzt werden können.
    • Beim Handeln und beim Fallen in Ohnmacht wird bisher noch über das komplette Inventar iteriert und den Gesamtwert des Gewichts neu berechnet. Bei vielen kleinen Items kann das unter Umständen zu einem kleinen Lag führen, was in den betroffenen Fällen zwar nicht den Spielfluss stört, dennoch aber etwas unschön ist.
    • Die Gewichtswerte sind aus dem Bauch heraus entstanden und wurden Balancing-technisch noch nicht groß getestet.
    • Das Overlay, welches rennen verhindert ist noch nicht sehr schön und bedarf Überarbeitung von Leuten, die sich besser mit Animationen auskennen. Man kann z.B. noch springen, kraulen beim Schwimmen, klettern...
    • Das Schießen von Pfeilen wird noch nicht berücksichtigt


    LG
    GL
    Angehängte Dateien
    Geändert von GenerationLost (01.02.2019 um 14:58 Uhr)

  2. Beiträge anzeigen #2 Zitieren
    Hero Avatar von lali
    Registriert seit
    Feb 2016
    Beiträge
    5.473
     
    lali ist offline
    Vielen Dank. Wir hatten schon vor, etwas ähnliches zu bauen. Du bist da aber andere Wege gegangen. Es wird sicher sehr hilfreich sein und wenn ich mehr Zeit habe sehe ich es mir genauer an und gebe noch etwas Feedback.
    Phoenix Dev | Website | Discord

  3. Beiträge anzeigen #3 Zitieren
    Knight Avatar von GenerationLost
    Registriert seit
    Apr 2009
    Ort
    Whereabouts Unknown
    Beiträge
    1.774
     
    GenerationLost ist offline
    Zitat Zitat von lali Beitrag anzeigen
    Wir hatten schon vor, etwas ähnliches zu bauen.
    Ich nehme an, ihr wollt Item-Limits pro Kategorie umsetzen, sowie es wohl ursprünglich für Gothic geplant war?
    Die Hooks meines Systems sind dafür vielleicht eine Grundlage. Was dann aber wohl etwas schwieriger wird, ist das Aufsammeln von Items auch zu verhindern, sollten Limits erreicht werden. Damit habe ich mich nicht beschäftigt.

  4. Beiträge anzeigen #4 Zitieren
    Hero Avatar von lali
    Registriert seit
    Feb 2016
    Beiträge
    5.473
     
    lali ist offline
    Zitat Zitat von GenerationLost Beitrag anzeigen
    Ich nehme an, ihr wollt Item-Limits pro Kategorie umsetzen, sowie es wohl ursprünglich für Gothic geplant war?
    Die Hooks meines Systems sind dafür vielleicht eine Grundlage. Was dann aber wohl etwas schwieriger wird, ist das Aufsammeln von Items auch zu verhindern, sollten Limits erreicht werden. Damit habe ich mich nicht beschäftigt.
    Ja, so etwa dachten wir uns das. Die Slots pro Kategorie und pro Unterkategorie begrenzen (mit Ausnahme von Items mit der Mission Flag etc.). Hauptsächlich hatte ich die Idee aber deshalb, weil der Aufwand viel geringer wäre gegenüber einem System, in dem erstmal alles ein richtiges Gewicht bekommen muss. Das schien meinem Programmierer einfach zu aufwendig zu sein als dass er sich da ran wagen wollte; da du das jetzt aber schon gemacht hast schließe ich nicht aus, dass wir auch direkt auf deinem System aufbauen.

    Zumindest ist dein System in der Theorie flexibler und erlaubt etwas mehr Freiheit für den Spieler, was er mitnehmen will und damit ist es auch realistischer. Alles andere ist dann nur noch eine Balancing-Frage bzgl. dem Gewicht.

    Wie wird dem Spieler denn aktuell das Gewichtslimit angezeigt (außer dass die Spielfigur ihren Sound abspielt bzgl. mehr kann sie nicht tragen)? Gibt es einen Gewichtsbalken wie in "Die Zeit der Prophezeiung"? Das würde ich eher als störend empfinden. Nicht mehr rennen bedeutet bei dir auch nur, dass er dann zwangsläufig "geht", also mit Sprinten hat das nichts zu tun, nehme ich an? Bleibt er irgendwann einfach stehen? Ich denke es wäre sinnvoller, wenn er an einem Punkt tatsächlich nichts mehr aufnehmen kann.
    Phoenix Dev | Website | Discord

  5. Beiträge anzeigen #5 Zitieren
    Knight Avatar von GenerationLost
    Registriert seit
    Apr 2009
    Ort
    Whereabouts Unknown
    Beiträge
    1.774
     
    GenerationLost ist offline
    Zitat Zitat von lali Beitrag anzeigen
    Wie wird dem Spieler denn aktuell das Gewichtslimit angezeigt (außer dass die Spielfigur ihren Sound abspielt bzgl. mehr kann sie nicht tragen)? Gibt es einen Gewichtsbalken wie in "Die Zeit der Prophezeiung"? Das würde ich eher als störend empfinden.
    [Bild: GothicMod_2019_02_05_11_30_18_00.jpg]
    Ja, momentan wird bei mir ein grüner Gewichtsbalken unten rechts, knapp über dem Manabalken angezeigt. Das kann man natürlich weglassen und den Gewichtsstand z.B. im Statusmenü anzeigen, oder den Balken nur dann einblenden, wenn auch das Inventar geöffnet ist.


    Zitat Zitat von lali Beitrag anzeigen
    Nicht mehr rennen bedeutet bei dir auch nur, dass er dann zwangsläufig "geht", also mit Sprinten hat das nichts zu tun, nehme ich an? Bleibt er irgendwann einfach stehen? Ich denke es wäre sinnvoller, wenn er an einem Punkt tatsächlich nichts mehr aufnehmen kann.
    Genau, er geht nur noch. Das wird momentan über eine Overlay-Animation geregelt, wenn also das Sprint-Overlay drüber gelegt wird, wird meine Mechanik wohl dadurch ausgehebelt, das habe ich noch nicht getestet. Danke daher für die Info!
    Es war geplant, dass der Spieler ab einer bestimmten Belastung (z.B. 1,5/2-fache des eigentlichen Limits) auch nicht mehr weiterlaufen kann, ist allerdings noch nicht implementiert. Sowas ist dann mMn immernoch einfacher als die Aufnahme von Items komplett zu unterbinden und prinzipiell bedeutet es für den Spieler in beiden Fällen ja das gleiche: Zeug loswerden, sonst gehts nicht weiter.
    Geändert von GenerationLost (05.02.2019 um 10:31 Uhr)

  6. Beiträge anzeigen #6 Zitieren
    Hero Avatar von lali
    Registriert seit
    Feb 2016
    Beiträge
    5.473
     
    lali ist offline
    Was hast du denn da noch für hundert Balken?

    Genau, er geht nur noch. Das wird momentan über eine Overlay-Animation geregelt, wenn also das Sprint-Overlay drüber gelegt wird, wird meine Mechanik wohl dadurch ausgehebelt, das habe ich noch nicht getestet. Danke daher für die Info!
    Es war geplant, dass der Spieler ab einer bestimmten Belastung (z.B. 1,5/2-fache des eigentlichen Limits) auch nicht mehr weiterlaufen kann, ist allerdings noch nicht implementiert. Sowas ist dann mMn immernoch einfacher als die Aufnahme von Items komplett zu unterbinden und prinzipiell bedeutet es für den Spieler in beiden Fällen ja das gleiche: Zeug loswerden, sonst gehts nicht weiter.
    Also wir hätten entweder die Möglichkeit, dass er gar nicht mehr weiterlaufen kann (wie z.B. in Stalker, TES weiß ich gar nicht, ich glaube da ist es genauso) oder dass er sich irgendwann weigert was aufzunehmen. Ich wäre aber für die zweite Variante, aus folgenden Gründen:

    1. Wenn ich es richtig im Kopf habe, sagt er: "Mehr kann ich nicht tragen". Das deutet an, dass er soviel, wie er gerade trägt, noch tragen kann, nur mehr geht jetzt einfach nicht mehr, also weigert er sich, noch mehr aufzunehmen.

    2. Wenn er einfach stehen bleibt, deutet das an, dass er theoretisch unendlich viel aufnehmen kann, es ist halt nur zuviel, um sich damit zu bewegen. Realistischer wäre aber, dass er einen Punkt erreichen kann, an dem es ihm auch zuviel ist, überhaupt soviel zu tragen, egal ob er geht oder steht.

    Damit wäre auch das Ergebnis am Ende nicht ganz das gleiche. Wenn er sich weigert mehr aufzunehmen, geht es immernoch weiter, weil er ja gerade noch so laufen kann. Ich denke, dass das auch besser zu Gothic passt. In anderen, weniger immersiven Spielen nimmt man einfach ganz viel auf und kriegt dann einen Print, dass man zu schwer beladen ist und bleibt stehen. Aber in Gothic teilt es die Spielfigur selbst mit und ist nicht so doof, dass er sich überhaupt so schwer belädt (oder vom Spieler beladen lässt), dass er keinen Schritt mehr gehen kann. Genauso wie die Spielfigur z.B. weiß, dass er irgendein Schloss einfach noch nicht knacken kann, deshalb versucht er es gar nicht erst. In diesem Sinne kommt es in Gothic manchmal vor, dass die Spielfigur nicht auf den Spieler hört.
    Phoenix Dev | Website | Discord

  7. Beiträge anzeigen #7 Zitieren
    Knight Avatar von GenerationLost
    Registriert seit
    Apr 2009
    Ort
    Whereabouts Unknown
    Beiträge
    1.774
     
    GenerationLost ist offline
    Zitat Zitat von lali Beitrag anzeigen
    Was hast du denn da noch für hundert Balken?
    Och, nur nochn anderes System das ich evtl. irgendwann mal noch veröffentliche.

    Zitat Zitat von lali Beitrag anzeigen
    Also wir hätten entweder die Möglichkeit, dass er gar nicht mehr weiterlaufen kann (wie z.B. in Stalker, TES weiß ich gar nicht, ich glaube da ist es genauso) oder dass er sich irgendwann weigert was aufzunehmen. Ich wäre aber für die zweite Variante, aus folgenden Gründen:

    1. Wenn ich es richtig im Kopf habe, sagt er: "Mehr kann ich nicht tragen". Das deutet an, dass er soviel, wie er gerade trägt, noch tragen kann, nur mehr geht jetzt einfach nicht mehr, also weigert er sich, noch mehr aufzunehmen.

    2. Wenn er einfach stehen bleibt, deutet das an, dass er theoretisch unendlich viel aufnehmen kann, es ist halt nur zuviel, um sich damit zu bewegen. Realistischer wäre aber, dass er einen Punkt erreichen kann, an dem es ihm auch zuviel ist, überhaupt soviel zu tragen, egal ob er geht oder steht.

    Damit wäre auch das Ergebnis am Ende nicht ganz das gleiche. Wenn er sich weigert mehr aufzunehmen, geht es immernoch weiter, weil er ja gerade noch so laufen kann. Ich denke, dass das auch besser zu Gothic passt. In anderen, weniger immersiven Spielen nimmt man einfach ganz viel auf und kriegt dann einen Print, dass man zu schwer beladen ist und bleibt stehen. Aber in Gothic teilt es die Spielfigur selbst mit und ist nicht so doof, dass er sich überhaupt so schwer belädt (oder vom Spieler beladen lässt), dass er keinen Schritt mehr gehen kann. Genauso wie die Spielfigur z.B. weiß, dass er irgendein Schloss einfach noch nicht knacken kann, deshalb versucht er es gar nicht erst. In diesem Sinne kommt es in Gothic manchmal vor, dass die Spielfigur nicht auf den Spieler hört.
    Okay, ich sehe wir verfolgen da einfach eine unterschiedliche Philosophie.
    Alle Macht dem Spieler, denke ich mir. Daher gefallen mir Ansätze halt besser, die den Spieler nur soweit einschränken, wie er sich selbst einschränken möchte. The Long Dark ist ein gutes Beispiel für was ich verfolge. Da kann der Spiele "so viel aufsammeln wie er will". Wird ein gewisses Limit überschritten, verlangsamt es den Spieler Stück für Stück mit jedem weiterem Item das er aufhebt, bis eben zu dem Punkt, an dem man durch zu hohe Belastung einfach nicht mehr weiterlaufen kann. Dann kann man sich entscheiden. Werde ich ein paar Sachen los und krieche zu meinem Unterschlupf um abzuladen und nehme dafür genug wichtiges Zeug mit, oder mache ich genug Platz um einfach schneller dahin zu kommen, wo ich will.
    Ich kann mir auch im echten Leben einen Sack (oder mehrere) nehmen und da "unendlich viel" reinpacken. Wenn ich versuche den Sack zu heben um damit irgendwo hinzugehen, komme ich halt auch nicht vom Fleck.

    Das meinte ich auch eher, als ich sagte, es läuft am Ende quasi aufs Gleiche raus. Will der Spieler ein Item unbedingt haben und ist er schon ziemlich hoch belastet? Dann hebt er es auf und geht (nicht rennt) wohin er will. Will er rennen (was man in den meisten Fällen ja möchte, da gehen einfach zu lange dauert), legt er etwas ab, damit er genug Kraft hat mit dem neuen Item weiterzumachen. Das ist in meinen Augen im Prinzip das selbe wie: Ich will das Item, das Spiel verbietet es mir aber es aufzuheben, also lege ich was anderes ab um Platz zu schaffen. Also die Entscheidung, etwas wegzuwerfen um für etwas anderes Platz zu schaffen, bleibt die Gleiche. Nur eben mit dem kleinen Unterschied, dass wenn man will (und die Geduld dazu hat ), kann man auch noch voll bepackt zur nächsten Truhe stapfen, was weniger einschränkt.
    Ich gebe zu, das Kommentar vom Helden passt wohl nicht so gut zu meiner Ansicht, es müsste dann eben an dem Punkt gesagt werden, an dem es nicht weiter geht. Kann mir auch vorstellen, dass es vielleicht nicht so direkt zu Gothic passt, aus den Gründen die du genannt hast.

    Alles in allem ist das auch einfach Geschmackssache. Ich höre auch oft genug, wie sehr es Spieler nervt überhaupt ein Limit zu haben. Und es verbietet dir natürlich keiner, mein System auf deine Wünsche anzupassen. Dafür ist es ja da. Das Ganze ist halt nur nach der o.g. Vorstellung entstanden.
    Geändert von GenerationLost (05.02.2019 um 13:48 Uhr)

  8. Beiträge anzeigen #8 Zitieren
    Legend of Ahssûn Avatar von TheEternal
    Registriert seit
    Jun 2013
    Ort
    Frankfurt
    Beiträge
    4.546
     
    TheEternal ist offline
    Ich hasse Carry-Weight Systeme wie in TES.
    An alle die überlegen es zu implementieren und in der Mod einzusetzen, macht es über die Spieleinstellungen abschaltbar. Ich finde es ist zwar nett in den ersten 5 Stunden des Spiel aber zögern nur die Spielzeit hinaus, wenn man ständig sein Inventar min-maxen muss. Super nervig, vor allem wenn man arbeitet und Zeit extrem wertvoll ist, im Gegensatz zu Schülern mit 6 Wochen Sommerferien.
    [Bild: LoA_Banner_Skyline2.jpg]
    LoA Website
    Checkout Cloudevo: unlimited Cloud-Drive


  9. Beiträge anzeigen #9 Zitieren
    Hero Avatar von lali
    Registriert seit
    Feb 2016
    Beiträge
    5.473
     
    lali ist offline
    Wenn du ein Spiel wie Stalker machst, in dem das begrenzte Inventar zum Spielprinzip gehört und diese Funktion abzuschalten ganz grundlegend das Balancing und Spielprinzip ruinieren würde, dann kannst dus einfach nicht abschaltbar machen. Das ist aber auch gar nicht nötig, wenn das Balancing stimmt. Es nützt dir schlicht und ergreifend nichts, tausend Schwerter mitzuschleppen, wenn da niemand ist, der sie dir abkaufen kann, weil gar keiner Interesse oder soviel Erz hat. Der Mehraufwand an Spielzeit ist minimal, wenn man sich erst auf das andere System eingestellt hat. Unnötig mehr Spielzeit kostet es dann, wenn man zwanghaft an einer Spielweise festhalten will, für welche das Spiel dann einfach nicht ausgelegt ist, nur stößt man dabei dann wie gesagt schnell an seine Grenzen, wenn man mit den ganzen Items gar nichts anfangen kann. Wenn es einem keinen wirklichen Vorteil bringt, sich so zu beladen, dann macht mans auch nicht mehr.
    Phoenix Dev | Website | Discord

  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
    Das unschöne ploppen kann man über den Bodystate verhindern. Iteminteract, Interruptable etc. abfragen und nur DANN das overlay drüberschmeißen.
    Ich würde das Skript gerne in meiner Mod "und zuletzt entstand der Mensch" benutzen, wenn es in Ordnung für dich ist. Vielen Dank fürs Teilen des Skripts


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

  11. Beiträge anzeigen #11 Zitieren
    Knight Avatar von GenerationLost
    Registriert seit
    Apr 2009
    Ort
    Whereabouts Unknown
    Beiträge
    1.774
     
    GenerationLost ist offline
    Zitat Zitat von Bisasam Beitrag anzeigen
    Das unschöne ploppen kann man über den Bodystate verhindern. Iteminteract, Interruptable etc. abfragen und nur DANN das overlay drüberschmeißen.
    Ich würde das Skript gerne in meiner Mod "und zuletzt entstand der Mensch" benutzen, wenn es in Ordnung für dich ist. Vielen Dank fürs Teilen des Skripts
    Danke für die Tipps, wollte da auch irgendwann mal weiter daran arbeiten, aber sieht momentan eher schlecht aus.
    Du darfst das System sehr gerne verwenden, darum habe ich es ja veröffentlicht. Du darfst es natürlich auch nach Lust und Laune erweitern und anpassen. Freut mich, dass doch noch Interesse daran besteht!

  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
    So ich denke mal ich hab alle Bugs gefixt.

    Das Bogenschießen musste ich mit einem Workaround machen. Im Item-Skript MUSS Munition mit Gewicht 0 angegeben werden (in der Anzeige schreibt man trotzdem das Gewicht hin damit der Spieler bescheid weiß). Außerdem muss das Gewicht gesplittet werden.
    Der eine Teil setzt sich zusammen aus Drop und Take, also alles was über die Hooks geliefert wird. Der andere Teil zählt regelmäßig die Anzahl an Munition im Inventar des Spielers und multipliziert mit der Konstante für diese spezifische Munition.
    In einer Drittvariable wird dann Hook-Zahl und Munitons-Zahl verrechnet, sodass sich eine TOTAL-Zahl ergibt. Diese ist die einzige, die im Charaktermenü und auf der Leiste angezeigt wird.
    Das ist die einfachste Methode und da man in der Regel nicht sooo viele Munitionsarten hat, sollte das Ergebnis schnell vorliegen.


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

  13. Beiträge anzeigen #13 Zitieren
    now also in your universe  Avatar von Milky-Way
    Registriert seit
    Jun 2007
    Beiträge
    15.244
     
    Milky-Way ist offline
    Wenn man in einem Zweikampf umgehauen (aber nicht getötet) wird, dann fällt ja auch die Waffe zu Boden und der Gegner schnappt sich noch das Gold des Spielers. Wird das korrekt erkannt? Ich könnte mir vorstellen, dass es letztlich sicherer ist, periodisch durch das Inventar des Spielers zu iterieren, statt sich auf plus/minus zu verlassen.

    Im ersten Beitrag steht noch, dass es Probleme mit den Overlays gibt: da könnte man die Overlays erst hinzufügen, wenn der Held nicht an Mobsi, etc. ist (z.B. bei Gewichtsüberschreitung eine FrameFunction starten, die überprüft, ob der Held gerade ein Mobsi benutzt. Wenn nicht, Overlay hinzufügen und die FrameFunction wieder austragen).

  14. Beiträge anzeigen #14 Zitieren
    Union - Testphase Avatar von Niko5511
    Registriert seit
    Jan 2018
    Beiträge
    2.570
     
    Niko5511 ist offline
    Gewicht wurde auch in der russischen l'hiver 1.1u integriert. Hängt von Stärke ab. Ist aber für Gothic 2. Aber vielleicht gibt das Anhaltspunkte. Hier die Scripte:

    https://yadi.sk/d/zXKYULzNZYBLmg

  15. Beiträge anzeigen #15 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    Die Umfall-Bugs hatte ich auch gefixt. Sobald ich wieder am Heimrechner bin, stelle ich die aktualisierten Skripte mit Komment hier rein.


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

  16. Beiträge anzeigen #16 Zitieren
    Serima Avatar von Fisk2033
    Registriert seit
    Dec 2010
    Ort
    Dresden
    Beiträge
    5.803
     
    Fisk2033 ist offline
    Zitat Zitat von Bisasam Beitrag anzeigen
    Die Umfall-Bugs hatte ich auch gefixt. Sobald ich wieder am Heimrechner bin, stelle ich die aktualisierten Skripte mit Komment hier rein.
    Würde mich sehr interessieren, was du da so gezaubert hast. Ich bin schon sehr gespannt!

  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
    So Kinnas, was lange währt wird endlich gut. Hier ist das ge-updatete Skript:

    B_CarryWeight (Änderungen und Bemerkungen sind einkommentiert, falls ihr Parsfehler bekommt müsst ihr wohl ein paar einzelne Variablen nachdefinieren, z.B. in der CarryWeight_Constants o.ä.)

    Code:
    /****************************************************
    *			Carry Weight System for G1
    *
    * This system aims to create a similar experience 
    * as in Bethesda games like Fallout 4 and Skyrim.
    * The player has weight limit and every item has a 
    * weight value. Picking up items adds those weight
    * values towards the limit and if it's reached, 
    * the player isn't able to run anymore. 
    *
    * Obviously, this uses the "weight" property of 
    * the item class, though any custom property can
    * be used instead.
    ****************************************************/
    
    
    
    //The player's current weight points
    var int 	Player_CarryWeight; //Just Pickup without arrows
    
    //taken from The Long Dark survival game as reference
    //1 weight unit should be 1kg
    //300 weight would be 30kg then
    const int 	CarryWeightMax = 300;
    
    var int Player_CarryWeightTOTAL; //Pickup-Weight + Arrows
    
    //Safety var to check if overlay is applied
    //FIXME: Trotzdem sollte das Overlay erst NACH DEM SCHLIESSEN
    //	der Truhe angehängt werden, sonst passiert der gleiche Fehler!
    var int CarryWeight_SlowedDown;	
    
    //LeGo handle for the weight bar
    var int 	CarryWeightBarHndl;
    //Bar instance, shown above the mana bar
    
    instance CarryWeight_Bar(GothicBar)
    {
    	x = Print_Screen[PS_X] - 100;
    	y = Print_Screen[PS_Y] - 60;
    	barTex = "Bar_Weight.tga";
    };
    
    
    func void SetNewCarryWeight() //Neue Funktion um das TOTALE Gewicht zu setzen! Pickup + Arrows + Bolts
    {
    
    	var int TotalArrowWeight;
    	TotalArrowWeight=0;
    	var int MunitionCount; //Zwischenspeichervars weil Gothic gern durcheinanderkommt wenns zu viel rechnen muss
    	var int MunitionWeight;
    	if Npc_HasItems(hero,ItAmArrow)>0
    	{
    		MunitionCount=Npc_HasItems(hero,ItAmArrow);
    		MunitionWeight=CarryWeight_Arrow;
    		TotalArrowWeight+=MunitionWeight*MunitionCount;
    	};	
    	if Npc_HasItems(hero,ItAmBolt)>0
    	{
    		MunitionCount=Npc_HasItems(hero,ItAmBolt);
    		MunitionWeight=CarryWeight_Bolt;
    		TotalArrowWeight+=MunitionWeight*MunitionCount;
    	};
    	
    	//Hier ggf. weitere Munitionsarten behandeln
    	
    	Player_CarryWeightTOTAL=Player_CarryWeight+TotalArrowWeight;
    	
    	Bar_SetValue(CarryWeightBarHndl, Player_CarryWeightTOTAL);
    	
    };
    
    
    /****************************************************
    *			Pickup and Drop functions	
    *
    * These functions add or remove weight points from
    * the item in the argument and apply or remove
    * slowdowns. 
    *
    * - Used in hooked functions and for consuming items
    * - Only the hero is affected	
    *****************************************************/
    func void CarryWeight_PickUp(var c_npc slf, var C_ITEM itm, var int amt)
    {
    	if(Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(PC_Hero))
    	{
    		
    		//count of stacked Items in "amt"
    		Player_CarryWeight += itm.weight*amt;
    		SetNewCarryWeight(); //Setzt Total!
    		
    	
    		
    		if (Player_CarryWeightTOTAL > CarryWeightMax)
    		{
    		
    			if !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_UNCONSCIOUS)
    			&& !C_BodyStateContains(hero,BS_DEAD)
    			&& !C_BodyStateContains(hero,BS_INVENTORY) //TRUHEN!!
    			{
    		
    			Mdl_ApplyOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    			CarryMdsApplyLater=FALSE;
    			
    			}else
    			{
    				CarryMdsApplyLater=TRUE;
    			};			
    			
    			//hero comment before var is set to true
    			if(!CarryWeight_SlowedDown)
    			{
    				B_SayOverlay(hero,NULL,"$INVFULL");
    			};
    			
    			CarryWeight_SlowedDown = true;
    		};
    		
    	
    		
    	};
    };
    
    func void CarryWeight_Drop(var c_npc slf, var C_ITEM itm, var int amt)
    {
    	if(Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(PC_Hero))
    	{
    		//count of stacked Items in "amt"
    		Player_CarryWeight -= itm.weight*amt;
    		
    		SetNewCarryWeight();			
    		if (Player_CarryWeightTOTAL <= CarryWeightMax && CarryWeight_SlowedDown == true)
    		{
    		
    			if !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_UNCONSCIOUS)
    			&& !C_BodyStateContains(hero,BS_DEAD)
    			&& !C_BodyStateContains(hero,BS_INVENTORY) //TRUHEN!!
    			{
    			Mdl_RemoveOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    			CarryMdsRemoveLater=FALSE;
    			}else
    			{
    				CarryMdsRemoveLater=TRUE;
    			};			
    			CarryWeight_SlowedDown = false;
    			
    		};
    
    				
    		
    		//Safety first?
    		if(Player_CarryWeight < 0)
    		{
    			Player_CarryWeight = 0;
    		};
    		
    		
    
    	};
    };
    
    /************************************************
    *	INTERN		Hook functions & init			*
    ************************************************/
    
    //NPC -> Hero || Hero -> Container
    //used ONLY for dropping items to container!
    func void _CarryWeight_DropToContainer()
    {
    	//Thanks to F a w k e s
    	var oCItemContainer Item_Container;
        var C_NPC npc;
        var oCItem itm;
        var int amount;
        var C_ITEM itmInstance;
        var oCNPC her;
    
        Item_Container = _^(ECX);
        
        //Get inventory owner
        npc = _^(Item_Container.inventory2_owner);
        
        //Get item
        itm = _^(List_GetS(Item_Container.inventory2_oCItemContainer_contents, Item_Container.inventory2_oCItemContainer_selectedItem + 2));
    	itmInstance = MEM_PtrToInst(List_GetS(Item_Container.inventory2_oCItemContainer_contents, Item_Container.inventory2_oCItemContainer_selectedItem + 2));
        
        //Get item quantity
        amount = MEM_ReadInt(ESP + 8);
    	
    	if(itm.amount < amount)
    	{
    		amount = itm.amount;
    	};
    
    	CarryWeight_Drop(npc, itmInstance, amount);
    };
    
    //Container -> Hero || NPC -> Hero
    func void _CarryWeight_LootContainer()
    {
    	//mit Hilfe von F a w k e s
        var oCItem itm;
        var C_ITEM itmInstance;
        
        //Get item
        itm = _^((MEM_ReadInt(ESP+4)));
    	itmInstance = MEM_PtrToInst(MEM_ReadInt(ESP+4));
    
    	//amount is just one since oCItemContainer__Remove_Item
    	//is called for every item in stack (so 5 times for 5 beer in a stack)
    	CarryWeight_PickUp(hero, itmInstance, 1);
    };
    
    //for picking up items from the ground
    func void _CarryWeight_DoTakeVob()
    {
    	//get NPC and item
    	var c_npc slf; slf = MEM_PtrToInst(ECX);		
    	var C_ITEM itm; itm = MEM_PtrToInst(MEM_ReadInt(ESP + 4));	
    	//C_ITEM has no amount property, that's why we need 
    	//the engine class object here
    	var oCItem itmobj; itmobj = _^(MEM_ReadInt(ESP + 4));	
    	
    	if (!Hlp_IsValidItem (itm)) { return; };
    	if (!Hlp_IsValidNpc (slf)) { return; };
    	
    	CarryWeight_PickUp(slf, itm, itmobj.amount);
    };
    
    //FIXME: not callef if player in ZS_Unconscious!
    //	check for drawn weapon there to call 
    //	CarryWeight_Drop on it?
    func void _CarryWeight_Drop()
    {
    	var c_npc slf; slf = MEM_PtrToInst(ECX);
    	var C_ITEM itm; itm = MEM_PtrToInst(MEM_ReadInt(ESP + 4));
    	var oCItem itmobj; itmobj = _^(MEM_ReadInt(ESP + 4));
    
    	if (!Hlp_IsValidItem (itm)) { return; };
    	if (!Hlp_IsValidNpc (slf)) { return; };
    	
    	CarryWeight_Drop(slf, itm, itmobj.amount);
    };
    
    //by F a w k e s
    FUNC void CarryWeight_AddInvCategoryWeight (var C_NPC slf, var int inv_category)
    {
        var int p;
        var int itm_slot; itm_slot = 0;
        var int amount;
    	
        //Loop
        p = MEM_StackPos.position;
    
        //Is there any item in itm_slot ?
    	amount = NPC_GetInvItemBySlot (slf, inv_category, itm_slot);
        if (amount > 0)
        {
            //item is filled by above NPC_GetInvItemBySlot
    		CarryWeight_PickUp(hero, item, amount);
    
            itm_slot = itm_slot + 1;
            MEM_StackPos.position = p;
        };
    };
    
    FUNC void CarryWeight_RecalcInventory ()
    {
    	//PrintScreen	("Recalculating Inventory...", -1,-1,"font_old_20_white.tga",3);
    	
    	Player_CarryWeight = 0;
        CarryWeight_AddInvCategoryWeight (hero, INV_WEAPON);
        CarryWeight_AddInvCategoryWeight (hero, INV_ARMOR);
        CarryWeight_AddInvCategoryWeight (hero, INV_RUNE);
        CarryWeight_AddInvCategoryWeight (hero, INV_MAGIC);
        CarryWeight_AddInvCategoryWeight (hero, INV_FOOD);
        CarryWeight_AddInvCategoryWeight (hero, INV_POTION);
        CarryWeight_AddInvCategoryWeight (hero, INV_DOC);
        CarryWeight_AddInvCategoryWeight (hero, INV_MISC);
    };
    
    //Needed to alter this function so receiving items in dialog
    //adds the right amoung of weight to the player
    //////////////////////////////////////////////////////////////////////////
    //	B_GiveInvItems
    //	==============
    //	Übergibt ein Item von 'giver' an 'taker' und gibt eine Meldung
    //	auf dem Bildschirm aus.
    //////////////////////////////////////////////////////////////////////////
    
    func void B_GiveInvItems(var C_NPC giver, var C_NPC taker, var int itemInstance, var int amount)
    {
    	PrintDebugNpc	(PD_ZS_DETAIL,	"B_GiveInvItems");
    	
    	//add up Carry Weight
    	Npc_GetInvItem(giver,itemInstance);	//fills global item Variable
    	CarryWeight_PickUp(taker, item, amount);
    
    	//-------- Gegenstand übertragen --------
    	Npc_RemoveInvItems	(giver,	itemInstance,	amount);
    	CreateInvItems		(taker,	itemInstance,	amount);
    
    	//-------- Meldung ausgeben --------
    	var string msg;
    
    	if	Npc_IsPlayer(giver)
    	{
    		if (itemInstance == ItMiNugget)
    		{
    			msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ORE_GIVEN);
    			PrintScreen	(msg, -1,_YPOS_MESSAGE_GIVEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_GIVEN);
    		}
    		else
    		{
    		    if amount == 1
    		    {
    			    msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ITEM_GIVEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_GIVEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_GIVEN);
    			}   
    			else
    		    {
    			    msg = ConcatStrings(IntToString(amount),_STR_MESSAGE_ITEMS_GIVEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_GIVEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_GIVEN);
    			};   
    		};
    	}
    	else if Npc_IsPlayer(taker)
    	{
    		if (itemInstance == ItMiNugget)
    		{
    			msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ORE_TAKEN);
    			PrintScreen	(msg, -1,_YPOS_MESSAGE_TAKEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_TAKEN);
    		}
    		else
    		{
    		    if amount == 1
    		    {
    			    msg = ConcatStrings(IntToString(amount), _STR_MESSAGE_ITEM_TAKEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_TAKEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_TAKEN);
    			}   
    			else
    		    {
    			    msg = ConcatStrings(IntToString(amount),_STR_MESSAGE_ITEMS_TAKEN);
    			    PrintScreen	(msg, -1,_YPOS_MESSAGE_TAKEN,"FONT_OLD_10_WHITE.TGA",_TIME_MESSAGE_TAKEN);
    			}; 
    		};
    	};	
    };
    
    
    
    
    //Flip-Flop func to show and hide the weight bar
    //- called on opening/exiting menues
    func int CarryWeight_ShowHideBar()
    {
    	var int show;
    	
    	if(show)
    	{
    		Bar_Hide(CarryWeightBarHndl);
    
    		show = false;
    	}
    	else
    	{
    		//Ich habe hier eine Sonderbehandlung eingefügt, falls man in den Optionen die Bars abstellen lassen kann
    		//Wenn die var auf 0 ist, ist es die erste Auswahl, die man bei Schiebereglern hat. Benutzt man An|Aus, ist An 0.
    		// Benutzt man hingegen Aus|An, ist An 1. Wer keine Optionen hat, kann den Part auskommentieren.
    		if (Hlp_StrCmp (MEM_GetGothOpt ("SECTION_DEINER_MOD","NAME_DER_VARIABLE_IN_OPTIONEN"),IntToString (0))==TRUE)
    		{
    					
    		Bar_Show(CarryWeightBarHndl);
    		show = true;
    		}else
    		{
    		Bar_Hide(CarryWeightBarHndl);
    
    		show = false;	
    		};		
    
    		
    	};
    	
    	return show;
    };
    
    
    
    //G1 addresses
    const int oCNpc__DoTakeVob = 6950160; //006A0D10 / 6
    const int oCNPC__DoDropVob = 6951152; //006A10F0 / 6
    const int oCItemContainer__TransferItem = 6723456; //00669780 / 5
    const int oCItemContainer__Remove_Item = 6722512; //006693D0 / 5
    const int oCViewDialogTrade__OnExit = 7514800; //0072AAB0 / 5
    const int oCNpc__DropAllInHand = 6898224;	//00694230 / 5
    const int oCGame__SetShowPlayerStatus = 6523872;  //00638BE0 / 6
    
    //Init function
    //Should be called in Startup.d for every world
    func void CarryWeight_Init()
    {
    	if CarryWeightMax==0
    	{
    		CarryWeightMax=300;	
    	};	
    	
    	var string HCalled; 
    	if Hlp_StrCmp(HCalled,"") //Damit es keine Doppelaufrufe mit alten LeGo-Versionen mehr gibt! 
    	{
    			
    	HookEngine (oCNpc__DoTakeVob, 6, "_CarryWeight_DoTakeVob");
    	HookEngine (oCNPC__DoDropVob, 6, "_CarryWeight_Drop");
    	HookEngine (oCItemContainer__TransferItem, 5, "_CarryWeight_DropToContainer"); 
    	HookEngine (oCItemContainer__Remove_Item, 6, "_CarryWeight_LootContainer");
    	HookEngine (oCViewDialogTrade__OnExit, 5, "CarryWeight_RecalcInventory");
    	HookEngine (oCNpc__DropAllInHand, 5, "CarryWeight_RecalcInventory");
    	
    	HookEngine(oCGame__SetShowPlayerStatus, 6, "CarryWeight_ShowHideBar");
    	HCalled="DONE";
    	};
    	
    	var int ReadyWeightBar;//CarryWeightBarHndl;
    	
    	if(!Hlp_IsValidHandle(ReadyWeightBar)) //In der alten Version ist die Bar beim Laden des Spielstands verschwunden. Auf diese Weise taucht sie zuverlässig auf!
    	{
    		ReadyWeightBar = Bar_Create(CarryWeight_Bar);
    		CarryWeightBarHndl=ReadyWeightBar;
        };
    	
        Bar_SetMax(CarryWeightBarHndl, CarryWeightMax);
        
        SetNewCarryWeight();
        
    	Bar_Show(CarryWeightBarHndl);
    };
    Und hier ist eine ganz neue Datei, die dazugekommen ist. Diese sollte einfach als Framefunktion o.ä. aufgerufen werden, da sie regelmäßige Checks durchführen soll:

    Code:
    func void WeightSystemLoop()
    {
    	
        Bar_SetMax(CarryWeightBarHndl, CarryWeightMax);
       
    	SetNewCarryWeight();
    	////////********************************///////////
    	
    			if (Player_CarryWeightTOTAL > CarryWeightMax)
    			&& CarryWeight_SlowedDown == FALSE
    			{
    		
    			if !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_UNCONSCIOUS)
    			&& !C_BodyStateContains(hero,BS_DEAD)
    			&& !C_BodyStateContains(hero,BS_INVENTORY) //TRUHEN!!
    			{
    		
    			Mdl_ApplyOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    			CarryMdsApplyLater=FALSE;
    			
    			}else
    			{
    				CarryMdsApplyLater=TRUE;
    			};			
    			
    			//hero comment before var is set to true
    			if(!CarryWeight_SlowedDown)
    			{
    				B_SayOverlay(hero,NULL,"$INVFULL");
    			};
    			
    			CarryWeight_SlowedDown = true;
    			}else if (Player_CarryWeightTOTAL <= CarryWeightMax)
    			&& CarryWeight_SlowedDown == TRUE
    			{
    			
    				
    			if !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT)
    			&& !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    			&& !C_BodyStateContains(hero,BS_UNCONSCIOUS)
    			&& !C_BodyStateContains(hero,BS_DEAD)
    			&& !C_BodyStateContains(hero,BS_INVENTORY) //TRUHEN!!
    			{
    			Mdl_RemoveOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    			CarryMdsRemoveLater=FALSE;
    			}else
    			{
    				CarryMdsRemoveLater=TRUE;
    			};			
    			CarryWeight_SlowedDown = false;
    			
    			};			
    
    	
    	
    	
    	
    	////////////////////////////////////////////////////////
    	//			BEHANDLUNG DROP DEAD o. UNCONCIOUS
    	///////////////////////////////////////////////////////
    	
    	
    	//////////////////////////////////////////////////////
    	//		hole dir die Waffe solange sie gezogen ist! Bei Fäusten und wegstecken wird die var UNGÜLTIG!
    	//////////////////////////////////////////////////////
    	
    	if !C_BodyStateContains(hero,BS_UNCONSCIOUS)
    	&& !C_BodyStateContains(hero,BS_DEAD)
    	{
    		if Npc_HasReadiedWeapon(hero)
    		{
    			Carryweapon= Npc_GetReadiedweapon(hero);
    			//print (Carryweapon.name);
    		}else
    		{
    			
    			if Hlp_IsValidItem(CarryWeapon)
    			{
    			
    			Carryweapon=Npc_GetReadiedweapon(hero);
    			
    			};
    
    		};		
    	};	
    	
    	
    	//////////////////////////////////////////////////
    	//		Verarbeitet Itemvar von oben und zieht ggf Munition ab!
    	/////////////////////////////////////////////////
    	
    	if C_BodyStateContains(hero,BS_UNCONSCIOUS)
    	{
    		//print ("TRUE");
    		
    		
    		//// Spring raus bei Invalid!
    		if !Hlp_IsValidItem (CarryWeapon) //-> Fäuste oder keine Waffe gezogen!
    		{
    			//print ("FALSE");
    			return;
    		};		
    		
    		if CarryRemovedWeight==FALSE
    		{
    					
    		Player_CarryWeight -= Carryweapon.weight;
    
    		
    		CarryRemovedWeight=TRUE;
    		
    		};
    		
    		if (Player_CarryWeight <= CarryWeightMax && CarryWeight_SlowedDown == true)
    		{
    		
    			
    			CarryMdsRemoveLater=TRUE;
    			CarryWeight_SlowedDown = false;
    			
    		};
    
    				
    		
    		//Safety first?
    		if(Player_CarryWeight < 0)
    		{
    			Player_CarryWeight = 0;
    		};
    		
    		
    		
    				
    		
    	}else
    	{
    		CarryRemovedWeight=FALSE; //Wenn der hero nicht rumliegt->Sofort nullen für Kreislauf!
    	};	
    	
    	
    	if !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    	&& !C_BodyStateContains(hero,BS_MOBINTERACT)
    	&& !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    	&& !C_BodyStateContains(hero,BS_UNCONSCIOUS)
    	&& !C_BodyStateContains(hero,BS_DEAD)
    	&& !C_BodyStateContains(hero,BS_INVENTORY) //TRUHEN!!
    	&& CarryMdsApplyLater==TRUE
    	{
    		if Player_CarryWeightTOTAL>CarryWeightMax
    		{
    					
    		Mdl_ApplyOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    		}else
    		{
    		Mdl_RemoveOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS"); //Zur Sicherheit hier nochmal richtigstellen	
    		CarryMdsRemoveLater=FALSE;
    		};		
    		
    		CarryMdsApplyLater=FALSE;
    		
    	};
    	
    	if !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    	&& !C_BodyStateContains(hero,BS_MOBINTERACT)
    	&& !C_BodyStateContains(hero,BS_MOBINTERACT_INTERRUPT)
    	&& !C_BodyStateContains(hero,BS_UNCONSCIOUS)
    	&& !C_BodyStateContains(hero,BS_DEAD)
    	&& !C_BodyStateContains(hero,BS_INVENTORY) //TRUHEN!!
    	&& CarryMdsRemoveLater==TRUE
    	{
    		if Player_CarryWeightTOTAL<=CarryWeightMax
    		{
    					
    		Mdl_RemoveOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    		}else
    		{
    		Mdl_ApplyOverlayMds(hero, "HUMANS_OVERCUMBERED.MDS");
    		CarryMdsApplyLater=FALSE;
    		};		
    		
    		CarryMdsRemoveLater=FALSE;
    		
    	};
    };


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

  18. Beiträge anzeigen #18 Zitieren
    now also in your universe  Avatar von Milky-Way
    Registriert seit
    Jun 2007
    Beiträge
    15.244
     
    Milky-Way ist offline
    Wenn ich mich richtig erinnere, gibt es (zumindest in G2) ein Problem, wenn dem Hero manche Sachen passieren, während das Inventar offen ist (auch ohne Truhe). Ich vermute aber, dass du das mal getestet hast (ist ja letztlich nur Gegenstände fallenlassen). BS_INVENTORY ist in diesem Fall, glaube ich, nicht gesetzt.

  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
    Das Skript-Update ist immernoch auf G1 abgestimmt und dort werden die Zustände genau so gesetzt, wie ich sie brauche. Ich hab das an allen möglichen und unmöglichen Mobs und Vobs versucht und es gibt kein geploppe oder Verhaltensbugs mehr. Ob das Skript uneingeschränkt G2 tauglich ist weiß ich nicht.

    Auf kurz oder lang würde ich aber auch besser finden, das Inventar einfach durchzuzählen. Die Frage ist: Wie macht man das bei dieser Fülle an Items am besten? Am liebsten würde ich ja Kategorie für Kategorie durchgehen, abfragen wie viele Items mit wie viel Gewicht sich darin befinden und dann alles zusammenrechnen. ich find nur keine Funktion, die mir erlaubt, Items ohne konkrete Instanzangabe aus dem Inv zu bekommen.


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

  20. Beiträge anzeigen #20 Zitieren
    Hero Avatar von lali
    Registriert seit
    Feb 2016
    Beiträge
    5.473
     
    lali ist offline
    Die Inventory Capacities sind dafür gedacht, soweit ich weiß. Die ursprünglich geplante Inventarbegrenzung sollte nur die Anzahl per Itemkategorie beschränken, statt eine Gewichtsbegrenzung einzuführen.
    Phoenix Dev | Website | Discord

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