Falloutnow! - We drop the bomb!

Andere Spiele => The Fall => Thema gestartet von: Torka am 27. Juli 2010, 23:34:17 Uhr

Titel: Mod-Tagebuch
Beitrag von: Torka am 27. Juli 2010, 23:34:17 Uhr
Hallo liebe Gamer,

da ich nun "The Fall" fast zu Ende gespielt habe, sind mir für das Spiel so ein paar Ideen gekommen. Diese würde ich gern auf den einzelnen Karten umsetzten.
Da ich aber schon genau so oft geskriptet habe wie Agnes vielleicht Fleisch gegessen hat, bin ich gespannt ob es was wird.
Für das Spiel gibt es einen Editor und ein beiliegendes Mod-Tutorial, welche die Entwickler der Reloaded Version (1.10.1) gesponsert haben.
Sicher ist der Editor etwas gewöhnungsbedürftig und das Tutorial erscheint mir auch etwas kryptisch, da sich einige Sachen von den im Spiel verwendeten Skripten unterscheiden.

Dennoch sind ein paar hübsche Sachen möglich. Recht herzlichen Dank an Lexx für seine Infos an dieser Stelle, er hat ja schon Mods und seine Demo-Map für "The Fall" hier vorgestellt, welche mir zum Verständnis der Skripte geholfen haben.   
In diesem Thread würde ich gern alle gemachten Erkenntnisse sammeln. Wer also Lust und Muße hat, kann gern seine Mod-Erfahrungen hier hineinschreiben.

Alles beginnt immer mit einer Vorstellung oder Idee von etwas... und diese ist die bestehenden Karten ein wenig zu verändern.

Bei "The Fall" waren das folgende:

1. Im Laufe des Spiels ist eine Sammlernatur mehr mit Itemmanagement beschäftigt, als mit Spielen. Trotz aller Kofferräume der 5 Autos fing man an auch noch irgendwelche kleinen Sammelecken anzulegen :). Inventar vergrößern ?

2. Die Werte der Items, wie z.B. die 2 kg schwere Glühbirne oder die angefertigten Halsketten, welche meist billiger waren als die Ausgangsmaterialien, etwas realistischer zu verändern. Das selbe Spiel bei den Waffen. Werte verändern?

3. Die versiegenden Wasserquellen hätten ruhig etwas mehr Wasserportionen haben können. Auch ein paar mehr Quellen hinzufügen, z. B. in ausgetrockneten Seen, Flüssen ?

4. Den gesamten Tierbestand etwas mehr aufpeppen, in New Safford kann man sich der Kühe als Nahrungsquelle noch bedienen, bei fast allen anderen funktioniert das nicht mehr, abgesehen von den Kamikazeminenkühen in Bowie Village.

5. Die Bonuspunkte für das Erlegen von Gegnern war mir auch schleierhaft, für einen "Bergtiger", der ja eigentlich ein Puma (Berglöwe) ist gibt`s 3 Punkte für einen Bären 0,5.

6. Ein wenig mehr Benzin im Spiel wäre nett und Bienenwachs in den Stöcken.

7. Da und dort könnte man auch noch ein wenig Items in die Kisten stopfen oder die Arztpraxis mit Medikamenten ausstatten, wie z. B. die verlassene medizinische Station in Copper Hill.

8. Das Platzieren eines Autos an eine bestimmte Stelle wäre auch nicht schlecht oder ein Seekercamp. Warum sollen die Typen nur immer die Rastenden angreifen, einfach mal den Spieß umdrehen.

9. Die Bereicherung der Karten mit einzelnen Objekten wäre sicher auch ganz nett.

10. Das Hinzufügen von neuen NPC mit Tagesabläufen eventuell, an Missionen will ich mal noch gar nicht denken, da das für mich noch weit hinter dem Horizont liegt.


Mal schauen was draus wird :) und wann mich das Moddingfieber verlässt ;).   
                           
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 28. Juli 2010, 09:35:05 Uhr
Zitat
1. Im Laufe des Spiels ist eine Sammlernatur mehr mit Itemmanagement beschäftigt, als mit Spielen. Trotz aller Kofferräume der 5 Autos fing man an auch noch irendwelche kleinen Sammelecken anzulegen Smiley. Inventar vergrößern ?

Wage zu bezweifeln, dass das möglich ist.

Zitat
2. Die Werte der Items, wie z.B. die 2 kg schwere Glühbirne oder die angefertigten Halsketten, welche meist billiger waren als die Ausgangsmaterialien. Das selbe Spiel bei den Waffen. Werte verändern?

3. Die versiegenden Wasserquellen hätten ruhig etwas mehr Wasserportionen haben können. Auch ein paar mehr Quellen hinzufügen, z. B. in ausgetrockneten Seen, Flüssen ?

Beides sollte sehr einfach zu bewerkstelligen sein. Die Item-Attribute befinden sich alle in den entsprechenden Python-Scripten. Die Wasserquellen werden - afaik - in den jeweiligen Zonen-Scripte behandelt. Ich bin mir gerade nicht sicher, ob die Wassermenge eingestellt werden kann, es ist aber kein Problem, weitere Quellen hinzuzufügen.

Zitat
6. Ein wenig mehr Benzin im Spiel wäre nett und Bienenwachs in den Stöcken.

Das Problem hier ist imo, dass beides nicht respawnt. Kein Händler ändert übers Spiel das Warenangebot. Das sollte angepasst werden.
Titel: Software
Beitrag von: Torka am 28. Juli 2010, 16:38:42 Uhr
Vorab erst einmal zum "Werkzeug".

Ein Packprogramm (z.B.: 7.zip) ist notwendig, um die komprimierten Dateien im The Fall-Ordner zu entpacken. Alle Karten befinden sich in zones.ubn, die Skripte in scripts.ubn.
Jede Karte ist einer Zone gleichgestellt, z.B. das GNO-HQ entspricht Zone1. In jedem Zonenordner befinden sich wiederum eine Anzahl von Python-Dateien (npc.py, zone_1.py, const.py....) und eine Zip-Datei.
Letztere beinhaltet die Karte, welche im Map-Editor geladen werden kann.

Besagter Map-Editor ist ja schon dabei und kann über das Startmenü des Spiels geöffnet werden. Dann kann man unter FILE / OPEN die einzelnen Zonen-Ordner anwählen und da die Zip-Datei laden - je nach Rechner kann das schon etwas dauern.
Wenn nun die Karte geladen wurde mit STrg+A oder unter VIEW / FREE CAMERA die Kameraperspektive deutlich verbessern - dann wie gewohnt navigieren.
Am linken Rand finden sich z.B. viele aufgelistete Objekt, welche man platzieren kann,  z.B. OBJEKTE / PLAKATE UND SCHILDER / Stopschild. Unter VIEW / SHOW OBJEKT INFO kann man sich die Koordinaten oder die ID des Objekts ansehen. Dies ist echt wichtig für das Skripten dann.

Die Python-Skripte waren mir erst ein vollkommenes Rätsel - diese kann man mit dem Texteditor öffnen und man wird von eine Zeilenflut erschlagen. Hmm, habe dann einen Python-Skripteditor namens  Wing IDE 101 3.2 gefunden und mit jenem sehen die PY-Dateien schon wesentlicher benutzerfreundlich, aber immer noch rätselhaft aus (ist halt mein erster Kontakt mit Python).

Die im Weiteren geschilderten Erfahrungen stammen nun aus diesen Skripten - der Map-Editor kann zum visuellen Verständnis und als Koordinatenquelle dienen.

Die veränderten Skripte werden nur bei bei einem Neustart des Spiels wirksam, also frühere Savegames funktionieren nicht. (Danke Lexx)

Damit komme ich auch schon zum ersten großen Problem - die Startkarte ist das GNO-HQ (Zone1). Diese zu verändern macht Spaß, aber was ist, wenn man die Schattenbasis (Zone8) modifizieren möchte. Muß man dann alle Karten bis dahin spielen bevor man seine winzige Skriptänderung kontrollieren kann - was für ein Albtraum.
Man muss es nicht. Nach schon fast genervten Durchstöbern der Skripte ist mir im Ordner scripts die "global_defines.py" aufgefallen und da am Anfang steht eine wichtige Zeile:

# which zone to load on campaign start
ENTRY_ZONE = "zones\\zone_1\\zone_1"


Wenn man nun z.B. die zone_1 durch zone_8 ersetzt:

# which zone to load on campaign start
ENTRY_ZONE = "zones\\zone_8\\zone_8

! SPEICHERN !

beginnt jedes neu gestartete Spiel z.B. in der Schattenbasis. Der Charakter ist dann zwar ziemlich mittellos in Unterwäsche, aber zum Testen reicht es.

Erstes Problem gelöst  #party

Die zweite Alternative ist mit dem Konsolenbefehl (F11) import debug; debug.cheat("map") alle Karten frei zu schalten.

Falls man mal eine Datei versaut, die Orginaldateien sind ja immer noch in den gepackten UBN-Dateien enthalten.

Titel: Inventarvergrößerung und Werte der Items ändern
Beitrag von: Torka am 28. Juli 2010, 17:34:42 Uhr
Zitat
1. Im Laufe des Spiels ist eine Sammlernatur mehr mit Itemmanagement beschäftigt, als mit Spielen. Trotz aller Kofferräume der 5 Autos fing man an auch noch irgendwelche kleinen Sammelecken anzulegen :). Inventar vergrößern ?

Wie könnte man diese Idee verwirklichen?

Option A

Man fügt einfach noch ein Fahrzeug in das Spiel ein, am besten den Radpanzer, der hat den größten Kofferraum (48 Slots), der Humvee und Pickups einen mittleren (35 Slots) und der Buggy (24), den kleinsten.
Siehe weiter unten im Thread.

Option B

Man erweitert die Slotanzahl aller Fahrzeuge ebenfalls auf 48 Slots. Unter scripts / itemdata / vehicles.py  findet am die Eigenschaften der Fahrzeuge:

create_vehicle_type(typeid='SET_BUGGY')
objects.set_attribute(object='SET_BUGGY', attribute="name", value=globaltext.SET_BUGGY_NAME)
.
.
.
objects.set_attribute(object='SET_BUGGY', attribute="inventory_slots", value=24)

Den markierten Wert in objects.set_attribute(object='SET_BUGGY', attribute="inventory_slots", value=24)  einfach auf 48 ändern und schon passen in den Buggy doppelt so viele Sachen rein  :aiee

Option C

In der Geschichte der ganzen Patchorgie dieses Spiels habe ich gelesen, dass das Stapeln von Objekten (Munition, Nahrungsmittel, Medipacks) nicht so richtig möglich war. Ab irgendeiner Patchversion hatten die Entwickler aber eine "Stapelbarkeit" eingebaut.

In der Datei scripts / itemdata / items.py stehen die Eigenschaften der Gegenstände:

create_item_type(typeid='SET_NORMAL_CLOTHES_1')
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="name", value=globaltext.SET_NORMAL_CLOTHES_1_NAME)
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="hint", value=globaltext.SET_NORMAL_CLOTHES_1_HINT)
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_NORMAL_CLOTHES_1')
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="resource3d", value='RES3D_NORMAL_CLOTHES_1')
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="value", value=5.00)
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="weight", value=2.50)
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="stacking", value=1)
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="armor", value=1)
objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="occupied_slots", value=["clothes"])   

Der Wert der Stapelbarkeit (stacking) kann nun erhöht werden - im Moment am Testen  ::).

Habe den Wert von 1 auf 2 erhöht und es funktioniert wunderbar.

objects.set_attribute(object='SET_NORMAL_CLOTHES_1', attribute="stacking", value=2)

Nach diesem Prinzip können so wesentlich mehr Objekte aufgenommen werden, bei Munition - warum den nur 10, vielleicht 50 oder 100 Packungen.
Das Gute ist, der limitierende Faktor im Inventar der Personen ist nun das Gewicht und nicht mehr die Slotanzahl. Bei den Kofferräumen der Fahrzeuge ist das Gewicht ja egal, also nie wieder mehrerer Munitionsstapel im Auto verbrauchen, sondern nur einen Slot besetzen.  :)

Zitat
2. Die Werte der Items, wie z.B. die 2 kg schwere Glühbirne oder die angefertigten Halsketten, welche meist billiger waren als die Ausgangsmaterialien. Das selbe Spiel bei den Waffen. Werte verändern?

Funktioniert nach ähnlichem Prinzip wie oben beschrieben, ein Wert wird verändert.  #lachen#

Wir nehmen mein Lieblingsbeispiel - das VERY_NICE_BRACELET (Sehr schöne Armband), zu finden in der Datei scripts / itemdata / items.py

create_item_type(typeid='SET_VERY_NICE_BRACELET')
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="name", value=globaltext.SET_VERY_NICE_BRACELET_NAME)
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="hint", value=globaltext.SET_VERY_NICE_BRACELET_HINT)
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_VERY_NICE_BRACELET')
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="resource3d", value='RES3D_VERY_NICE_BRACELET')
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="value", value=8.0)
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="weight", value=0.4)
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="stacking", value=1)
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="combine_xp", value=75)
objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="item_combination", value={
"difficulty_assemble" : 75,
"combination_list" : [['SET_SHORT_LEATHER_STRING', 'SET_BEAR_CLAW', 'SET_BEAR_TEETH'],
['SET_SHORT_LEATHER_STRING', 'SET_TIGER_CLAW', 'SET_TIGER_TEETH'],
['SET_SHORT_LEATHER_STRING', 'SET_WOLF_CLAW', 'SET_WOLF_TEETH'],
['SET_SHORT_LEATHER_STRING', 'SET_HYENA_CLAW', 'SET_HYENA_TEETH'],
['SET_SHORT_LEATHER_STRING', 'SET_WILD_DOG_CLAW', 'SET_WILD_DOG_TEETH']]})

Es ist ein kombinierter Gegenstand und besitzt ursprünglich einen Preis von 8. Na toll - die Zähne und die Klauen kann man für je 5 verscherbeln und die Lederschnur für 1, sollte eigentlich 11 ergeben und da ist noch nicht mal eine Wertsteigerung dabei. Es scheint als ob Kunsthandwerk nicht ganz so geschätzt wird.  :neien

Also ich bin für mindestens 12.  #thumbsup

objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="value", value=12.0)

und nur nochmal zur Übung, in den Slot passen doch mehr Armbänder rein  ::)

objects.set_attribute(object='SET_VERY_NICE_BRACELET', attribute="stacking", value=50)

Die Werte für die Waffen stehen in der Datei scripts / itemdata / weapons.py.

Der Phantasie sind dann wieder keine Grenzen gesetzt, `ne Anaconda mit ordentlich Durchschlag oder die Reichweite der Armbrust erhöhen  :angel:
Titel: Wasserquellen editieren
Beitrag von: Torka am 28. Juli 2010, 19:58:24 Uhr
Zitat
3. Die versiegenden Wasserquellen hätten ruhig etwas mehr Wasserportionen haben können. Auch ein paar mehr Quellen hinzufügen, z. B. in ausgetrockneten Seen, Flüssen?

Die auf fast jeder Karte (Zone) zu findenden Wasserquellen sind im Zonenordner X in der Datei zone_X.py verankert. Das wäre z.B. für das GNO-HQ (Zone1): zones / zone_1 / zone_1.py

Fast am Anfang der Datei (Zeile 84 im  Wing IDE 101 3.2) steht:

def initWaterResources():
water.set_water_source(345.3,476.7,4)
#water.set_water_source(258.3,264.6,2)
water.set_water_source(419.5,349.8,3)

d.h. es gibt 2 Wasserquellen, die so gefunden werden können. Ein # deaktiviert immer die jeweilige Zeile für das Spiel, deswegen stehen auch die Kommentare in den Skripten hinter #.
Ich habe zum Testen einfach mal # entfernt und festgestellt, das nun eine 3. Quelle nördlich des Übungsgeländes gefunden werden kann, welche 2 l hergibt.
So könnten nun im Skript unter den bestehenden Quellen noch mehr eingefügt werden, wobei die x- und y-Koordinaten aus dem Map-Editor gelesen werden können.

water.set_water_source(x-Koordinate,y-Koordinate, Literzahl der Quelle)

Man kann auch alle bestehenden Quellen einfach mit einem höheren Wasservolumen ausstatten, z.B. aus

water.set_water_source(419.5,349.8,3) wird dann water.set_water_source(419.5,349.8,30)

Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 28. Juli 2010, 20:13:05 Uhr
Wenn du in der on_map_load() Prozedur einer Zone folgende Zeile hinzufügst:

import debug; debug.cheat("pickinfo")
Aktivierst du den Debug-Mode "Pickinfo". Wenn du damit im Spiel auf eine Stelle klickst, werden dir die Koordinaten angezeigt. Damit kannst du ohne viel und unnützes herumprobieren entsprechende Koordinaten bekommen.
Titel: Nützliche Konsolenbefehle
Beitrag von: Torka am 28. Juli 2010, 21:12:22 Uhr
Das habe ich doch gleich mal ausprobiert und es erleichtert die Arbeit enorm, da auch noch gleich die IDs angezeigt werden. DANKE  #thumbsup
Ich hatte im Mod-Tutorial davon gelesen, bin aber nicht recht schlau daraus geworden. COOL - Jetzt funzt es  :D.

Bin da auch noch auf eine Reihe von cheats gestoßen, welche man in die Console eingeben kann:
Bei nochmaligen Eingeben werden die cheats wieder ausgeschaltet.

import debug; debug.cheat("teleport") - transportiert den char über das Kontext-Menü (ein T in einem Kreis)  zu der Stelle des Mauszeigers - nur Superman reist jetzt schneller

import debug; debug.cheat("map")   - schaltet alle Karten frei und man kann überall hinreisen - noch bevor man bei Wesley war

import debug; debug.cheat("mad_skillz")  - damit kann man munter in der ID-Card alle Attribute und Fähigkeiten verändern - zum Testen aller Talente ideal  #yay

import debug; debug.cheat("endless ammo")  - endlos Munition, wer es mag

import debug; debug.cheat("endless gas")  - endlos Treibstoff, so kann man dann das Benzinproblem auf unrealistische Weise auch lösen  :-\

import debug; debug.cheat("immortal") - der typische  "Ich kann nicht sterben Modus"

import debug; debug.cheat("unlock_all")  - öfnnet alle verschlossenen Kisten und Safes auf der Karte

import debug; debug.cheat("no_fatigue")  - chars werden nicht müde und brauchen nicht rasten

import debug; debug.cheat("no raid") - chars werden nicht mehr überfallen bei der Rast

import debug; debug.cheat("region")  - zeigt bestimmte Regionen an, z.B. Trigger

import debug; debug.cheat("tile")  - zeigt die Kollisionsmodelle der Objekte an - nützlich

Wer mehr Konsolenbefehle sehen will - einfach import debug; debug.cheat("help") eingeben - dann erscheinen noch mehr

Titel: Spawnbare Tierwelt
Beitrag von: Torka am 28. Juli 2010, 23:34:20 Uhr
Zurück zu Idee 4

Zitat
4. Den gesamten Tierbestand etwas mehr aufpeppen, in New Safford kann man sich der Kühe als Nahrungsquelle noch bedienen, bei fast allen anderen funktioniert das nicht mehr, abgesehen von den Kamikazeminenkühen in Bowie Village


Normalsterbliche Tiere


In jedem Zonenordner gibt es eine Pythondatei namens npc.py. In dieser sind nicht nur alle NPCs definiert sondern auch die Tiere. Mit dem Wing IDE 101 3.2 also z.B. aus Zone 3 (Bowie Village) die npc.py geöffnet und man findet am Anfang:


system.create_animal(id="KUH_1", type=ANIMAL_COW, party="ANIMALS", x = 256.33, y = 445.68)
objects.set_immortal_state("KUH_1", True)
system.create_animal(id="KUH_2", type=ANIMAL_COW, party="ANIMALS", x = 256.03, y = 432.96)
#objects.set_immortal_state("KUH_2", True)
objects.set_direction('KUH_2', 160)
system.create_animal(id="KUH_3", type=ANIMAL_COW, party="ANIMALS", x = 253.17, y = 439.44)
objects.set_immortal_state("KUH_3", True)
objects.set_direction('KUH_3', 90)
system.create_animal(id="KUH_4", type=ANIMAL_COW, party="ANIMALS", x = 256.69, y = 441.15)
objects.set_immortal_state("KUH_4", True)
system.create_animal(id="KUH_5", type=ANIMAL_COW, party="ANIMALS", x = 264.58, y = 437.24)
objects.set_immortal_state("KUH_5", True)
objects.set_direction('KUH_3', 180)


Dies sind die 5 Kühe in der Farm. Die Zeile objects.set_immortal_state("KUH_1", True) verhindert, das Erlegen der Tiere.
Wenn man davor ein # setzt, können die Tiere sterben. Also im Beipiel ist Kuh 1 unsterblich und Kuh 2 nicht.
Stirbt diese aber, erscheint sie nicht wieder auf der Karte - sie ist definitiv tot, anders bei den nur periodisch auftauchenden Tieren (gespawnte Wölfe z.B. zwischen 22 und 6 Uhr) welche nach einer Weile wieder erscheinen.

Die Unsterblichkeitseigenschaft kann man nutzen, wenn man einfach Tiere zur Dekoration verwenden möchte. 

Witzigerweise haben die Entwickler in Bowie Village auch drei Schweine eingebaut, sie aber deaktiviert :) 

Fortsetzung folgt..........jetzt

Respawnte Tiere

Bei den gespawnten Tieren ist es ein wenig komplizierter. Es sind mindestens 4 Pythondateien beteiligt.

Unter script / spawnanimals.py  finden man am Anfang eine Liste aller Zonen (Karten), in denen die Tiere immer wieder erscheinen.

SPAWN_ANIMAL_ZONES = ['zone_1.zone_1'
,'zone_2.zone_2'
,'zone_3.zone_3'
,'zone_4.zone_4'
,'zone_5.zone_5'
,'zone_6.zone_6'
,'zone_7.zone_7'                  
#,'zone_8.zone_8' #Kein Tier
#,'zone_9.zone_9' #Kein Tier, data().SpawnAnimals anders benutzt!
#,'zone_10.zone_10' #Kein Tier
,'zzone_1.zzone_1'
,'zzone_2.zzone_2'
#,'zzone_3.zzone_3'
,'zzone_4.zzone_4'
#,'zzone_5.zzone_5'
#,'zzone_6.zzone_6'
#,'zzone_7.zzone_7'
#,'zzone_8.zzone_8'
,'zzone_9.zzone_9'
#,'zzone_10.zzone_10' # Bunker
#,'sqzone_1.sqzone_1' # kein Tier
,'sqzone_2.sqzone_2'
#,'sqzone_3.sqzone_3'
#,'sqzone_4.sqzone_4'
#,'sqzone_5.sqzone_5'
]

TIME_TO_RETURN_FROM_GRAVE = time("72:00:00")

Einige Zonen sind mit # deaktiviert. Die restlichen aktiviert. Gerade wenn man auf einer noch deaktivierten Karte zusätzliche gespawnte Tiere erscheinen lassen möchte, erscheinen sie halt nicht, weil in dieser Datei ein # davor steht. Also Zone einfach hier aktivieren und es funktioniert. 

TIME_TO_RETURN_FROM_GRAVE = time("72:00:00")

Diese Zeile gibt an, dass nach dem ein gespawntes Tier erlegt wurde, es nach 72 Spielstunden wieder an seinem Ort erscheint.


Alle gespawnten Tiere sind dann wieder in den Pythonskripten der einzelnen Zonenordnern definiert.
Im wesentlichen sind das dann drei beteiligte Dateien, die const.py,die npc.py und zone_X.py

In Zone 1(GNO_HQ) der zone_1 / const.py steht dann ziemlich im letzten Drittel:

def init_data():
.
.
.
    ### Fuer Spawn-Animals ###
data().Timer_SpawnTimeChecker = 666
data().Timervalue_SpawnTimeChecker = 10 * 60 * 1000.0 * hour_real_to_game
data().SpawnAnimalsSpawned = False
data().SpawnAnimals = ["WOLF_S_LEAD","WOLF_S_1","WOLF_S_2","WOLF_S_3"]

Wenn man weite Tiere auf der Karte spawnen möchte, müssen die Namen (z.B. "WOLF_S_4") dann auch in die eckigen Klammern in dieser Zeile gesetzt werden.


Die Lokation und die Eigenschaften der gespanten Tiere findet man wieder in der zone_1 / npc.py.

## Initialisiert die Tiere der Zone
def initAnimals():
system.create_animal(id="WOLF_S_LEAD", type=ANIMAL_WOLF, party="ANIMALS", x=291.5, y=572.5, direction=90)
system.create_animal(id="WOLF_S_1", type=ANIMAL_WOLF, party="ANIMALS", x=292.0, y=576.0, direction=60)
system.create_animal(id="WOLF_S_2", type=ANIMAL_WOLF, party="ANIMALS", x=288.5, y=573.0, direction=120)
system.create_animal(id="WOLF_S_3", type=ANIMAL_WOLF, party="ANIMALS", x=287.5, y=576.0, direction=120)
objects.set_attribute('WOLF_S_LEAD', 'level', 1)
objects.set_attribute('WOLF_S_1', 'level', 1)
objects.set_attribute('WOLF_S_2', 'level', 1)
objects.set_attribute('WOLF_S_3', 'level', 1)

Je höher das Level der Tiere, desto mehr Lebenspunkte haben sie.

## Spawnanimals sind feindlich und erstmal inactiv
for animal in data().SpawnAnimals:
objects.set_attribute(animal,"foes", ["UISPIELER"])
objects.set_active_state(animal,INACTIVE)

Die Tiere werden durch objects.set_attribute(animal,"foes", ["UISPIELER"]) mit einem "feindlichen" Verhalten (Raubtiere greifen an, Beutetiere flüchten) versehen.



In der zone_1 / zone_1.py findet man das definierte Zeitintervall für den Respawn der 4 Tiere auf der GNO-Karte
def on_timer(id):
.
.
.
        if (id == data().Timer_SpawnTimeChecker):
clock = system.get_mission_time().get_day_time()
if (clock >= time("06:00:00") and clock < time("22:00:00")):
spawnanimals.spawnAnimals(INACTIVE)
else:
spawnanimals.spawnAnimals(ACTIVE)
system.notify_timer(data().Timer_SpawnTimeChecker,data().Timervalue_SpawnTimeChecker)
Diese 4 Wölfe erscheinen von 22 bis 6 Uhr westlich des Eingangs zum GNO-HQ.


Ein zweites Beispiel ist das Zeitintervall des Respawns der Tiere auf der Konvoi-Karte, zu finden in der sqzone_2 / sqzone_2.py :
def on_timer(id):
if (id == data().Timer_SpawnTimeChecker):
clock = system.get_mission_time().get_day_time()
if (clock < time("16:00:00") or clock > time("23:00:00")):
spawnanimals.spawnAnimals(INACTIVE)
else:
spawnanimals.spawnAnimals(ACTIVE)
system.notify_timer(data().Timer_SpawnTimeChecker,data().Timervalue_SpawnTimeChecker)
Andere Schreibweise, Tiere sind von 16.00 bis 23.00 Uhr auf der Karte zu finden.
Titel: Bonuspunkte und Killpoint editieren
Beitrag von: Torka am 29. Juli 2010, 02:28:05 Uhr
Zitat
5. Die Bonuspunkte für das Erlegen von Gegnern war mir auch schleierhaft, für einen "Bergtiger", der ja eigentlich ein Puma (Berglöwe) ist gibt`s 3 Punkte für einen Bären 0,5.

Das Bonuswertesystem befindet sich am Ende der Datei scipts / global_difines.py

# kill_types for id card stats & weapon accustomisation
kill_type_list = ["DESERT_MONKS", "RAT_SKULLS", "SEEKER","INDIANS","NOMADS", "SHADOWS", "GNO_SOLDIERS", "MISC_NPCS", "UNKNOWN_NPCS",
"WOLF", "BEAR", "WARG", "TIGER", "WILDDOG", "PEACEFUL_ANIMALS", "UNKNOWN_ANIMALS"]

kill_points = {                          

"DESERT_MONKS":                    3,
"RAT_SKULLS":            3,
"SEEKER":    2,
"INDIANS":    2,
"NOMADS":    2,
"SHADOWS":                          4,
"GNO_SOLDIERS":            5,
"MISC_NPCS":                  1,
"UNKNOWN_NPCS":                     3,
"WOLF":                   0.2,
"BEAR":                   0.5, 
"WARG":                            4,
"TIGER":           3,
"WILDDOG":                         0.1,
"PEACEFUL_ANIMALS":                 0,
"UNKNOWN_ANIMALS":           0.2,

              }

Die Werte hinter den Zielgruppen beziehen sich auf die Punkte, welche man für das Eliminieren eines Ziels bekommt.
Nun kann man abschätzen und wählen, ob man die Bärenjagd nicht etwas mehr belohnt, also den Wert z.B. von 0.5 auf 3 erhöht.


Diese "Killpoints" werden gesammelt und je nach der Höhe der "Gesamtkillpoints" werden Bonuspunkte auf alle Fähigkeiten addiert.
Die Skilltabelle findet sich in scripts / skill_tables.py am Ende:

def get_reputation_bonus_per_killpoints(killpoints):
"""Returns the reputation skill point bonus for the given amount of killpoints.
"""
if killpoints < 25: return 0
elif killpoints < 50: return 1
elif killpoints < 100: return 1
elif killpoints < 150: return 2
elif killpoints < 250: return 2
elif killpoints < 500: return 3
elif killpoints < 1000: return 4
else: return 5


def get_reputation_description(killpoints):
"""Returns the reputation description for the given amount of killpoints.
"""
if killpoints < 25: return globaltext.MISSION_IDCARD_REPUTATION_DESC_0
elif killpoints < 50: return globaltext.MISSION_IDCARD_REPUTATION_DESC_1
elif killpoints < 100: return globaltext.MISSION_IDCARD_REPUTATION_DESC_2
elif killpoints < 150: return globaltext.MISSION_IDCARD_REPUTATION_DESC_3
elif killpoints < 250: return globaltext.MISSION_IDCARD_REPUTATION_DESC_4
elif killpoints < 500: return globaltext.MISSION_IDCARD_REPUTATION_DESC_5
elif killpoints < 1000: return globaltext.MISSION_IDCARD_REPUTATION_DESC_6
else: return globaltext.MISSION_IDCARD_REPUTATION_DESC_7

Für die Benutzung einer bestimmten Waffe oder Waffentyps gibt es Bonuspunkte, diese steigen nach der Anzahl der eliminierten Ziele.

"""Returns skill bonus for being accustomed to this weapon/weapon type.

Parameters:
        id_kills   - Number of kills with this weapon.
        type_kills - Number of kills with this weapon_type.
"""
if id_kills <= 9: id_bonus = 0                                            # Sehr ungewohnte Waffe
elif id_kills <= 29: id_bonus = 5                                         # Ungewohnte Waffe
elif id_kills <= 59: id_bonus = 10                                        # Vertraute Waffe
elif id_kills <= 99: id_bonus = 15                                        # Sehr vertraute Waffe
else: id_bonus = 20                                                      # Lieblingswaffe
if type_kills <= 9: type_bonus = 0
elif type_kills <= 29: type_bonus = 0
elif type_kills <= 59: type_bonus = 5
elif type_kills <= 99: type_bonus = 10
else: type_bonus = 15
return max(id_bonus, type_bonus)
Titel: NPC-Tagesabläufe modifizieren
Beitrag von: Torka am 29. Juli 2010, 19:33:06 Uhr
Zitat
10. Das Hinzufügen von neuen NPC mit Tagesabläufen eventuell, an Missionen will ich mal noch gar nicht denken, da das für mich noch weit hinter dem Horizont liegt.                          

Es entspricht zwar nicht der Reihenfolge der Ideenpunkte, aber da die Sache so gut funktioniert, schreib ich sie gleich mal auf.
In der shedules.py von Zone 1 (GNO-HQ) habe ich gerade ein nicht aktiviertes Skript des Ausbilders gefunden. In dieser Datei, welche auch in jedem Zonenordner zu finden ist, werden die Tagesabläufe der NPCs definiert.
Ein wenig dran herum gespielt und es zum Laufen gebracht.

"DRILL_INSTRUCTOR" : ( # der Ausbilder
##################
{ #TA1: Tutorial nicht genommen:
S_CONDITION  : lambda: data().training_activated and not data().training_done,
"00:00:00" : { #
S_START  : [],
S_LOOP   : [turn_to_object("ALTER_EGO")]},                                                                 .
},{ #TA2: nach dem Tutorial:
"00:30:00" : { # Schlafen                                                            
S_START  : [goto(460.25, 346.90),
    enter_building('BUILDING_1883'),
    lay_down_to_sleep('THE FALL_BUILDING_3965')],
S_LOOP   : [sleep()]},
"04:30:00" : { # Warten
S_START  : [leave_building('BUILDING_1883'),
    goto(320.8,326.6),
    turn_to_direction(global_defines.DIR_EAST)],
S_LOOP   : []},
"21:00:00" : { # Trainigsparcours laufen
S_START  : [],
S_LOOP   : [patrol(((297.0,353.0),(309.0,343.0),(309.0,293.0),(292.0,293.0)))]},
"00:00:00" : { # Warten
S_START  : [goto(320.8,326.6),
    turn_to_direction(global_defines.DIR_EAST)],
S_LOOP   : []}
}),

Bisher stand er auch nach dem Training blöd in der Sonne oder halt unter dem Mond. Jetzt gönnt er sich mal einen kleinen Lauf und geht schlafen. Mal schauen ob man ihn zum Essen bewegen kann :).

;D Es funktioniert - ab 4:30 Uhr ESSEN FASSEN!  ;D


"DRILL_INSTRUCTOR" : ( # der Ausbilder
##################
{ #TA1: Tutorial nicht genommen:
S_CONDITION  : lambda: data().training_activated and not data().training_done,
"00:00:00" : { #
S_START  : [],
S_LOOP   : [turn_to_object("ALTER_EGO")]},
},{ #TA2: nach dem Tutorial:
"00:30:00" : { # Schlafen
S_START  : [goto(460.25, 346.90),
    enter_building('BUILDING_1883'),
    lay_down_to_sleep('THE FALL_BUILDING_3965')],
S_LOOP   : [sleep()]},
"04:30:00" : { # Essen und Trinken
S_START  : [leave_building('BUILDING_1883'),
    goto_dummy("BUILDING_867","dmyp_001"), sit_down_on_bench()],
S_LOOP   : sit_eat_drink_on_bench},
"06:30:00" : { # Warten
S_START  : [goto(320.8,326.6),
    turn_to_direction(global_defines.DIR_EAST)],
S_LOOP   : []},
"21:00:00" : { # Trainigsparcours laufen
S_START  : [],
S_LOOP   : [patrol(((297.0,353.0),(309.0,343.0),(309.0,293.0),(292.0,293.0)))]},
"00:00:00" : { # Warten
S_START  : [goto(320.8,326.6),
    turn_to_direction(global_defines.DIR_EAST)],
S_LOOP   : []}
}),

Jede Tätigkeit hat so ihre eigene Schleife, die solange durchläuft, bis das Zeitintervall abgelaufen ist. So steht der Ausbilder 4:30 Uhr auf und läuft zum Feuer, setzt sich auf eine Bank und isst bis 6:30 Uhr. Wow, wenn man bedenkt wie viele NPCs einen Tagesablauf haben, ist das schon eine Leistung. Ist ein wenig wie im Film, "...laufe dahin, mache das...."  #lachen#

Bei Gelegenheit werde ich hier in dem Beitrag mehr von solchen Aktivitätsschleifen auflisten, dann kann man nach dem Baukastenprinzip die Wastelands mit NPCs beleben   #hand :aiee
Alle Uhrzeiten, Koordinaten, (Namen und Dialoge) und Objekt IDs sind Beispiele und können durch andere ersetzt werden.


"22:00:00" : { # auf Bank sitzen, Gitarre spielen
      S_START  : [goto_dummy("BUILDING_2145","dmyp_002"),         Jede Bank hat 3 Plätze (vor der Bank stehend von links nach rechts) dmyp_001, dmyp_002, dmyp_003!
            play_guitar_on_bench()],
      S_LOOP   : [play_guitar_on_bench()]},

"22:30:00" : { # auf Bank sitzen, Flöte spielen
      S_DIALOG : "NPC_JON_T_006",
      S_START  : [goto_dummy("BUILDING_866","dmyp_003"),          Jede Bank hat 3 Plätze (vor der Bank stehend von links nach rechts) dmyp_001, dmyp_002, dmyp_003!
               sit_down_on_bench()],
      S_LOOP   : [play_fluit_on_bench()]},

"06:30:00" : { # auf Bank sitzen, Buch lesen
      S_START  : [goto_dummy("BUILDING_866","dmyp_003"),          Jede Bank hat 3 Plätze (vor der Bank stehend von links nach rechts) dmyp_001, dmyp_002, dmyp_003!
               sit_down_on_bench()],
      S_LOOP   : [read_book_on_bench()]},

"21:30:00" : { # Holz hacken
      S_START  : [goto_dummy("BUILDING_2108","dmyp_001"), start_chop_wood()],
      S_LOOP   : [chop_wood()]},

"15:00:00" : { # Schippen
      S_START  : [goto_dummy("BUILDING_1788","dmyp_001"), start_shovel_sand()],
      S_LOOP   : [shovel_sand()]},

"06:00:00" : { # Loch graben
      S_START  : [goto_dummy("BUILDING_1788","dmyp_001"), start_dig_hole()],
      S_LOOP   : [dig_hole()]},

"06:00:00" : { # Muskelaufbautraining
      S_START  : [goto(503.9,442.9),
            turn_to_direction(global_defines.DIR_WEST),
            make_push_up()],
      S_LOOP   : [make_push_up()]},

"12:00:00" : { # ueber Kasten buecken
      S_START  : [goto_object('BUILDING_5906'),
             turn_to_object('BUILDING_5906')],
      S_LOOP   : [lambda char: character.play_animation(char, 'CM_KNIEND_GESTE_AMBIENT_WAFFENLOS')]},

"11:30:00" : { # Feuer sitzen, Braten
      S_DIALOG : "NPC_MASON_T_003",
      S_START  : [goto_dummy("BUILDING_868","dmyp_005"),        Jedes mittlere Lagerfeuer hat mind. 9 Plätze, wenn nicht mehr  dmyp_001, ... dmyp_009!
               sit_down_to_cook()],
      S_LOOP   : [cook()]},

"19:00:00" : { # Feuer sitzen, Essen
      S_START  : [goto_dummy("BUILDING_868","dmyp_005"),        Jedes mittlere Lagerfeuer hat mind. 9 Plätze, wenn nicht mehr  dmyp_001, ... dmyp_009!
               sit_down_on_ground()],
      S_LOOP   : [sit_on_ground(actions = ['eat', 'drink'])]},

"21:00:00" : { # an dem Ort tanzen
      S_START  : [goto(489.34, 383.82),
               turn_to_direction(data().DIR_SOUTH_EAST)],
      S_LOOP   : [dance()]},

Und Ich jetzt - Kino gehen  #party

"15:00:00" : { # Patrouille
      S_START  : [],
      S_LOOP   : [patrol(((313.0,456.0),(252.0,458.0),(248.0,391.0),(309.0,389.0),(312.0,436.0),(311.0,437.0)))]}

"08:00:00" : { # Bewachen
      S_START  : [goto(311.0,437.0), turn_to_direction(global_defines.DIR_EAST)],
      S_LOOP   : []},

"23:15:00" : { # in der Pampa sitzen
      S_START  : [goto((432.83, 502.11)),
               turn_to_direction(data().DIR_NORTH),
               sit_down_on_ground()],
      S_LOOP   : [sit_on_ground()]},

"11:30:000" : { # Sandkasten spielen
      S_DIALOG : "NPC_KIKI_T_003",               Im Kiki-Tagesablauf gibt es 4 mal das Sandkastenspiel als Schleife, die sich nur durch die Dialoge unterscheiden!
      S_START  : [stepto(514.01, 385.94),         Der Sandkasten kann wegen des Kollisionsmodells sonst nicht begannen werden, also "stepto"-Befehl.
            turn_to_direction(data().DIR_WEST),
            sit_down_on_ground()],
      S_LOOP   : [sit_on_ground()]},

"15:00:00" : { # Gwehrschießen
      S_START  : [goto(523.65,560.64), turn_to_direction(45),
               start_hunt()],
      S_LOOP   : [hunt()]},                                  Das nächste Zeitintervall sollte mit dem Befehl [end_hunt()] beginnen, da sonst die Waffe noch in der Hand ist. 

"04:00:00" : { # Schießen beendet + am Ort stehen
      S_START  : [end_hunt()] + [goto(443.9,284.5)],
      S_LOOP   : [stand()]},

"19:30:00" : { # Waffe reinigen
      S_DIALOG : "NPC_FRANK_T_005",
      S_START  : [goto(459.9,266.7), turn_to_direction(global_defines.DIR_SOUTH_EAST),
            start_clean_weapon(),
            lambda c: checked_weapon_equip(c)],
      S_LOOP   : [clean_weapon()]},

"06:30:00" : { # Waffen reinigen
      S_DIALOG : "NPC_FAITH_T_002",                                           Viele NPCs haben in den einzelnen Tätigkeitsintervallen unterschiedliche Dialoge, wenn sie angesprochen werden!
                                                                                                     Ich habe diese in den Beispielen meist rausgenommen, aber das wäre die Stelle.
      S_START  : [goto(490.15, 406.16),
               turn_to_direction(data().DIR_NORTH),
               start_clean_weapon()],
      S_LOOP   : [clean_weapon()]},
Titel: Re: Mod-Tagebuch
Beitrag von: Smilodon am 30. Juli 2010, 00:05:17 Uhr
Ganz ehrlich...find ich gut, das sich jemand mal wieder mit "The Fall" beschäftigt...weiter so... :redfingr:
Titel: Platzieren von Items, Bienenwachs und Benzin
Beitrag von: Torka am 30. Juli 2010, 12:54:33 Uhr
Hätte ich am Anfang auch nicht gedacht, dass dies Spiel soviel Potential besitzt. Die Meinungen waren ja teilweise echt vernichtend und wahrscheinlich wurde die 1.0 Version des Spiels zurecht so beurteilt. Dennoch steckt viel Liebe zum Detail darin und damit meine ich nicht die Grafik (diese erfüllt ihren Zweck  ::) man erkennt meistens was gemeint sein soll  #lachen#), sondern das Missionsdesign - schlicht weg die Atmosphäre des Spiels - die Stilmittel wurden gut bis sehr gut verarbeitet. Gerade als alter Morrowindspieler war ich von den Tagesabläufen der NPCs begeistert. Diese Beleben die Karten ungemein, bei Morrowind in der Orginalversion war es ja entweder mit Herumstehen oder Laufen schon getan - bis findige Leute da auch Tagesabläufe den NPCs "eingehaucht" haben.
Die Atmosphäre wurde um Welten besser - auch das Suchen der Questgeber  ???  ;D.
Das Modifizieren von Karten und die Erstellung von Mapmods hat mir ja schon immer viel Freude gemacht -  wenn ich da an Vice City oder San Andreas denke - nur sind die Karteneditoren da etwas benutzerfreundlicher  :). Meistens scheitere ich halt an den Skripten (bin halt keine Programmierleute) und versuche durch viel Probieren meistens nur Werte oder baukastenmäßig Skripte zu verändern. Die meist bestehenden "Communities" der Spiele sind da echt hilfreich - bin da schon echt froh hier die ein oder andere Info zu bekommen  :).       

Zurück zu den Punkten 6 und 7.
Zitat
6. Ein wenig mehr Benzin im Spiel wäre nett und Bienenwachs in den Stöcken.
7. Da und dort könnte man auch noch ein wenig Items in die Kisten stopfen oder die Arztpraxis mit Medikamenten ausstatten, wie z. B. die verlassene medizinische Station in Copper Hill.

In jedem Zonenordner findet man das Zonenpythonskript, für Zone 1 wäre es z.B.: zone_1.py. Darin findet man unter def initItems(): eine Liste der Items, welche unterschiedlich entweder so auf der Karte an den Koordinaten zu finden sind oder im Inventar der NPC, Kisten, Bienenstöcke, des Händlers liegen.

def initItems():
if not hasattr(data(),"patch_patrick"):
data().patch_patrick = 1

# Fass am Eingang des Dorfes
objects.create_item_in_inventory( object="BUILDING_1716",equipment=["SET_WALTER_PPK"])
# Kieshaufen
objects.create_item_in_inventory( object="BUILDING_1739",equipment=["SET_SMALL_SAND_SHOVEL"])
# Auf dem Sandspielplatz
system.create_object(equipmenttype="SET_AMMOPACK_7_65_MM",x=518,y=381,direction=47)
             .
             .
             .
## TA-NPC Items (Items für NPCs die auch sterben können)
objects.create_item_in_inventory("KATHARINE",["SET_WIRE_WHISK","SET_RAT_MEAT"])
             .
             .
             .
        # Händler
objects.create_item_in_inventory("SEBASTIAN",
[
"SET_UZI",#Uzi
"SET_COLT_ANACONDA",#Colt Anaconda
"SET_SPECIAL_38",#38er Special
"SET_BERETTA_92F",#Beretta
# "SET_LANDMINE",#Landmine
"SET_HEGRENADE",#HE granate
"SET_MOLOTOV_COCKTAIL",#Molotov
                                 .
                                 .
                                 .
                                "SET_PAN",
"SET_SPIT"]
)

        # Bienenstöcke Z1
objects.create_item_in_inventory( 'BUILDING_10467', equipment=[ 'SET_BEESWAX', 'SET_BEESWAX' ] )
objects.create_item_in_inventory( 'BUILDING_10464', equipment=[ 'SET_BEESWAX', 'SET_BEESWAX' ] )
objects.create_item_in_inventory( 'BUILDING_10463', equipment=[ 'SET_BEESWAX' ] )

# Items in Kisten
objects.create_item_in_inventory( 'BUILDING_10251', equipment=[ 'SET_DUCT_TAPE', 'SET_GLOCK_21', 'SET_AMMOPACK_44' ] )
objects.create_item_in_inventory( 'BUILDING_10252', equipment=[ 'SET_LEATHER_CLOTHES', 'SET_WATER_SKIN', 'SET_DRUGS_PILLS_01','SET_STEEL_PLATES' ] )
objects.create_item_in_inventory( 'BUILDING_10281', equipment=[ 'SET_THROWING_KNIFE', 'SET_AMMOPACK_44', 'SET_LEATHER_GLOVES' ] )
objects.create_item_in_inventory( 'BUILDING_102
          .
          .
          .

In der scripts / itemdata / vehicles.py  kann man die Tankgröße und den Verbrauch der Fahrzeuge direkt ändern:

objects.set_attribute(object='SET_BUGGY', attribute="current_fuelquantity", value=100.0)
objects.set_attribute(object='SET_BUGGY', attribute="max_fuelquantity", value=100.0)
objects.set_attribute(object='SET_BUGGY', attribute="fuel_consumption_factor", value=0.00125)

Die erste Zeile gibt den aktuellen, die zweite Zeile den Gesamttankinhalt an. Der aktuelle sollte also niemals größer sein als der Gesamttankinhalt.
Die dritte Zeile definiert den Verbrauch, statt 0,00125 einfach auf 0,0005 herunter gehen und der Verbrauch sinkt schon mal deutlich.  ;D
Der Test mit 0.05 war auch schön, die Tankanzeige sank bei fast jedem Meter erheblich.

Man kann auch den Benzinverbrauch durch den Fahrerskill beeinflussen. In der scrips / object_events.py findet man:

if objects.has_attribute( driver, "driving"):
skill = objects.get_attribute( driver, "driving")

if skill > 54:
can_drive = True
fuel_consumption_factor_obj = fuel_consumption_factor_type
if skill > 69:
speedfactor = 0.8
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.9
if skill > 84:
speedfactor = 0.9
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.8
if skill > 94:
speedfactor = 1.0
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.7
if skill > 104:
speedfactor = 1.0
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.6
if skill > 114:
speedfactor = 1.0
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.55
if skill > 124:
speedfactor = 1.0
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.5
if skill > 134:
speedfactor = 1.0
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.47
if skill > 149:
speedfactor = 1.0
fuel_consumption_factor_obj = fuel_consumption_factor_type * 0.45

if has_talent( driver, "driving", "economic_driving"):
fuel_consumption_factor_obj = fuel_consumption_factor_obj * 0.8

objects.set_attribute( vehicle_id, "speed_factor", speedfactor)
objects.set_attribute( vehicle_id, "fuel_consumption_factor", fuel_consumption_factor_obj)

Je nach Erfahrungsstufe sinkt der Benzinverbrauch (0.9 = 10 % bis 0.45 = 55 % weniger Benzinverbrauch)

fuel_consumption_factor_obj = fuel_consumption_factor_type (ist bei allen Fahrzeugen 0.00125) * 0.7 = 0.00086

Die Fähigkeit "Ökonomisch Fahren" senkt den Verbrauch nochmals um 20% (Faktor 0.8 ).

Auf diese Weise kann man das Treibstoffproblem dann auch lösen.  #hand
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 30. Juli 2010, 13:12:41 Uhr
Btw. Wir haben auch [code.] [/code.] Tags. Eventuell solltest du die für die Code-Beispiele nutzen. ;)

Test
Titel: Platzieren von Fahrzeugen
Beitrag von: Torka am 30. Juli 2010, 13:22:03 Uhr
Danke, das ist ein guter Tip  #thumbsup. Jo, gefällt mir gut und sieht auch übersichtlicher aus. Die farblichen Markierungen funktionieren dann aber nicht mehr oder kann man das dann irgendwie anders lösen?


Zitat
8. Das Platzieren eines Autos an eine bestimmte Stelle wäre auch nicht schlecht oder ein Seekercamp. Warum sollen die Typen nur immer die Rastenden angreifen, einfach mal den Spieß umdrehen.

Für das Platzieren eines Humvees nehmen wir wieder als Beispiel die Karte des GNO-HQs (Zone1).
In dem Zonenordner finden wir das Zonenpythonskript zone_1.py und darin kann man unter def on_map_loaded(): so ziemlich am Anfang die Zeilen:

system.create_object('SET_HUMVEE', 375.58, 580.64, id = 'HUMVEE_Z3', direction = 45)
objects.set_attribute('HUMVEE_Z3', 'accepted_drivers', ['UISPIELER'])

einfügen.

def on_map_loaded():
init_data()
initParties()
npc.initNPCS()
initItems()
initHerbs()
initExitZones()
initFX()
initMinimapMarkers()
## Tiere initialisieren
npc.initAnimals()
## Timer für die Tierspawns
on_timer(data().Timer_SpawnTimeChecker)
#system.notify_timer(data().Timer_SpawnTimeChecker,data().Timervalue_SpawnTimeChecker)

system.create_object('SET_HUMVEE', 375.58, 580.64, id = 'HUMVEE_Z3', direction = 45)
objects.set_attribute('HUMVEE_Z3', 'accepted_drivers', ['UISPIELER'])

objects.set_position(object = "LUCAS",x = 474.0,y = 368.04, grid = "BUILDING_2141_INTERIOR_GRID")
objects.turn_to_direction(object = "LUCAS",direction = DIR_SOUTH)

## Questbook (eingefügt von Roger)
initQuestbook()
init_character_states()

Der Humvee parkt nun rechts vom Startpunkt am Straßenrand.  :coffee
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 30. Juli 2010, 13:23:53 Uhr
Farbliche Markierungen werden nicht mehr gehen, weil alles in reinem Code dargestellt wird.
Titel: Objekte platzieren
Beitrag von: Torka am 30. Juli 2010, 15:32:11 Uhr
Ok, danke. Dann werde ich das mal soweit anpassen  :).
 
9. Die Bereicherung der Karten mit einzelnen Objekten wäre sicher auch ganz nett.
Erstens kann man viele Kartenobjekte im Map-Editor platzieren, die Objekte sind dort grob in wenigen Gruppen in der links befindlichen Menüleiste angeordnet. Die beste Möglichkeit ist eh sich ein schönes Objekt, welches man verwenden möchte, auf den Karten direkt im Spiel anzuschauen und sich da die Inspiration zu holen.

Mit den Konsolenbefehlen import debug; debug.cheat("map") stehen einem von Beginn an alle Karten zur Verfügung, mit import debug; debug.cheat("teleport") bewegt man sich geschwind über die Karte und kann mit import debug; debug.cheat("pickinfo") alle wichtigen Infos zu den Objekten sammeln.

Im Map-Editor kann man dann aus jedem Zonenordner die zonen.zip entpacken:

zone_1.zip = GNO-Hauptquartier
zone_2.zip = New Safford
zone_3.zip = Bowie Village
zone_4.zip = Casa Verde
zone_5.zip = Spirit Springs
zone_6.zip = Copper Hill
zone_7.zip = Vesseltown
zone_8.zip = Schattenbasis
zone_9.zip = Hidden Cavern
zone_10.zip = Biosphäre

zzone_1.zip = Wastelands
zzone_2.zip = Desert Monks
zzone_3.zip = Labyrinth
zzone_4.zip = Garten Eden
zzone_5.zip = Tres Cabezas
zzone_6.zip = Die Schlucht
zzone_7.zip = Schattenhöhle
zzone_8.zip = Höhlengrab
zzone_9.zip = Vulture Gulch
zzone_10.zip = Bunker

sqzone_1.zip = Mike Ballin
sqzone_2.zip = Konvoi
sqzone_3.zip = Güterbahnhof
sqzone_5.zip = Überfallene Siedlung
sqzone_6.zip = Arena

Eine weitere Möglichkeit Objekte zu platzieren besteht über das Zonenpythonskript zone_X.py unter def on_map_loaded():. Dies wurde weiter oben schon im Thread beschrieben. 
Folgende Objekte sind dadurch möglich:

Waffen, Munition, Nahrungsmittel, Medipacks, Medikamente, Kleidung, Krempel, Werkzeuge .... und Fahrzeuge

Vielleicht noch für die Sammler und Jäger etwas zu den Heilkräutern. Diese werden ebenfalls in der zone_X.py jedes Zonenordners definiert.

In unsem Codebeispiel wieder Zone1(GNO-HQ):

def initHerbs():
# Grab des Vaters
system.create_object(equipmenttype="SET_ALOE_VERA", x=565.07, y=356.50)
# Berg im SW
system.create_object(equipmenttype="SET_WOOD_GARLIC", x=210.75, y=554.40)
# Berg bei Grab
system.create_object(equipmenttype="SET_ALOE_VERA", x=567.03, y=263.60)
# Kuhle im NO (in Basis)
system.create_object(equipmenttype="SET_ALOE_VERA", x=516.84, y=310.27)
# Kuhle im NW (in Basis)
system.create_object(equipmenttype="SET_ALOE_VERA", x=339.73, y=256.12)
# neben Gaestehaus (bei Baeumen)
system.create_object(equipmenttype="SET_ALOE_VERA", x=295.00, y=507.44)

Dabei verstecken sich hinter folgenden Befehlen diese Heilpflanzen:

system.create_object(equipmenttype="SET_ALOE_VERA", x=339.73, y=256.12)   = Aloe Vera, ok - das war einfach  #lachen#

system.create_object(equipmenttype="SET_WOOD_GARLIC", x=210.75, y=554.40)  = Bärlauch

system.create_object(equipmenttype="SET_BURNET", x=325.7, y=288.57) = Bibernelle

system.create_object(equipmenttype="SET_ANGELICA", x=414.48, y=505.36) = Engelswurz



Noch etwas zu den Feuerstellen:

(http://www.image-share.eu/image/329275-Mod-Feuer.png) (http://www.image-share.eu/share/329275-Mod-Feuer.png)

Es gibt 3 verschiedene Feuerstellen. Das große und das mittlere Feuer haben jeweils 9 Sitzplätze (Dummyplätze), das kleine Feuer besitzt 6 Plätze.

Die Feuerstellen und brennenden Mühltonnen sind in jedem Zonenordner in der  zone_X.py definiert:

def initFX():
                .
                .
                .
# brennende Tonne in New Stafford
fxBrennendeTonne("BUILDING_338")
# brennende Tonne Dustville
fxBrennendeTonne('BUILDING_245')
# Lagerfeuer in New Stafford
fxLagerFeuer("BUILDING_3867")
# Lagerfeuer im Ratskull Camp
fxLagerFeuer("BUILDING_3379")
               .
               .

Falls man ein neues Lagerfeuer oder eine brennende Tonne platziert entspricht die ID des Objektes dem Speicherpfad. Die ID sollte sinnvoll verkürzt werden, den diese muss in den Skriptbefehl eingesetzt werden, sonst erscheinen keine Animationen. 

fxLagerFeuer("ID des Objekts")

Wenn das Feuer also nicht brennt liegt es meistens an einer falschen ID.
   
Titel: Textveränderung
Beitrag von: Torka am 01. August 2010, 15:19:38 Uhr
Falls man die Bezeichnungen der Waffen, Gegenstände oder Namen ändern möchte, kann man dieses in folgenden Pythonskripten vornehmen: 

sripts / globaltext / german / german.py    = Waffen,  Munition, Ausrüstung ....

sripts / globaltext / german / editor.py       = Gegenstände, Gebäude, Pflanzen...

sripts / globaltext / german / names.py     = Namen

Man sollte sowohl den "Namen" als auch den "Hint" verändern, z. B.:

add_global_text(id='SET_MOLOTOV_COCKTAIL_NAME', text='Benzinbombe mit Lunte')
add_global_text(id='SET_MOLOTOV_COCKTAIL_HINT', text='Benzinbombe mit Lunte')

in

add_global_text(id='SET_MOLOTOV_COCKTAIL_NAME', text='Molotov Cocktail')   
add_global_text(id='SET_MOLOTOV_COCKTAIL_HINT', text='Molotov Cocktail')
Titel: Vergiftung
Beitrag von: Torka am 02. August 2010, 00:23:37 Uhr
Das Pythonskript scipts / system_event.py beinhaltet das Vergiftungsskript:

if id=="poisoning":
system.notify_global_timer("poisoning", 1000*120)
if not( hasattr(data("rest"), "resting") and data("rest").resting) :
for character_id in  system.get_pcs(include_unconscious = True):
if(objects.has_attribute(character_id,"poison_ticks")):
if objects.get_attribute(character_id,"poison_ticks") > 0: #pc is poisoned
objects.set_attribute(character_id,"poison_ticks",objects.get_attribute(character_id,"poison_ticks")-2)
objects.damage( character_id, 2 )

Es werden jeweils 2 Lebenspunkte nach einer gewissen Zeit abgezogen.
Titel: Tabelle der Erfahrungspunkte
Beitrag von: Torka am 02. August 2010, 01:12:41 Uhr
Nach fast ewigen Suchen fand ich die Tabelle der Erfahrungspunkte unter scripts / objekt_events.py :

Erfahrungspunkte    #Level

exp_table = [
0, #1
200, #2
500, #3
800, #4
1400, #5
2200, #6
3500, #7
6000, #8
7700, #9
10000, #10
13000, #11
17000, #12
21000, #13
25000, #14
30000, #15
35000, #16
40000, #17
45000, #18
50000, #19
55000, #20
61000, #21
68000, #22
70000, #23
79000, #24
89000, #25
99000, #26
112000, #27
128000, #28
148000, #29
172000, #30
200000, #31
232000, #32
268000, #33
308000, #34
352000, #35
400000, #36
452000, #37
508000, #38
568000, #39
632000, #40
]

Und eine Tabelle über die Erfahrungspunkte für das Erlegen von Feinden und Tieren, nicht verwechseln mit den Killpoints für die allgemeinen Bonuspunkte.

# base exp exp per level
kill_exp = {
"WOLF": (30, 15),
"ANTELOPE": (10, 5),
"BEAR": (40, 20),
"COW": ( 5, 3),
"DEER": (20, 10),
"HORSE": (15, 8),
"TIGER": (50, 25),
"WILDDOG": (30, 15),
"BISON": (15, 8),
"PIG": ( 5, 3),
"DONKEY": ( 5, 3),
"WARG": (60, 30),
"LIZARD_SOMA":         (40, 20),

"RAT_SKULLS":         (20, 10),
"DESERT_MONKS":         (30, 15),
"SHADOWS": (30, 20),
"INDIANS": (20, 10),
"NOMADS": (20, 10),
"GNO_SOLDIERS":         (40, 15),
"VILLAGE_PEOPLE":         (20, 10),
"SEEKER": (20, 10),
}
Titel: Medikamente, Drogen, Aufputschmittel
Beitrag von: Torka am 02. August 2010, 13:40:09 Uhr
Falls man die Drogen im Spiel editieren möchte, kann man dies in den folgenden 2 Pythonskripten vornehmen:

In der scripts / objekt_events.py werden nur die Hint-Texte der Drogenwerte verändert, nicht die Wirkung selbst!

def get_hint_text( ids ):
"""Generates the hint text (i.e., mouse over text/tooltip) for this object.

Parameters:
        id - Id of the object.
"""
drugs= {
'SET_DRUGS_PILLS_01': [[globaltext.MISSION_ATTRIBUTE_NAME_STRENGTH,'+2']],
'SET_DRUGS_PILLS_02': [[globaltext.MISSION_ATTRIBUTE_NAME_STRENGTH,'+2'],
[globaltext.MISSION_CREATECHARACTER_HEALTH,'+20%']],
'SET_DRUGS_PILLS_03': [[globaltext.MISSION_CREATECHARACTER_HEALTH,'+25%']],
'SET_DRUGS_PILLS_04': [[globaltext.MISSION_ATTRIBUTE_NAME_CHARISMA,'+2']],
'SET_DRUGS_PILLS_05': [[globaltext.MISSION_ATTRIBUTE_NAME_CHARISMA,'+3']],
'SET_DRUGS_PILLS_06': [[globaltext.MISSION_ATTRIBUTE_NAME_STRENGTH,'+2'],
[globaltext.MISSION_ATTRIBUTE_NAME_AGILITY,'+2'],
[globaltext.MISSION_ATTRIBUTE_NAME_DEXTERITY,'+2'],
[globaltext.MISSION_ATTRIBUTE_NAME_CONSTITUTION,'-4']],
'SET_DRUGS_VIALS_01': [[globaltext.MISSION_ATTRIBUTE_NAME_AGILITY,'+2'],
[globaltext.MISSION_ATTRIBUTE_NAME_DEXTERITY,'+2']],
'SET_DRUGS_VIALS_02': [[globaltext.MISSION_ATTRIBUTE_NAME_STRENGTH,'+3']],
'SET_DRUGS_VIALS_03': [[globaltext.MISSION_ATTRIBUTE_NAME_AGILITY,'+3']],
'SET_DRUGS_SYRINGE': [[globaltext.MISSION_CREATECHARACTER_HEALTH,'+30%']]
}

Die Wirkung bzw. die Drogenwerte ändert man in scripts / itemdata / items.py z.B: für Anabole Steroide

create_item_type(typeid='SET_DRUGS_PILLS_02')
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="name", value=globaltext.SET_DRUGS_PILLS_02_NAME)
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="hint", value=globaltext.SET_DRUGS_PILLS_02_HINT)
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_DRUGS_PILLS_02')
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="resource3d", value='RES3D_DRUGS_PILLS_02')
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="value", value=32.0)
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="weight", value=0.1)
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="stacking", value=10)
objects.set_attribute(object='SET_DRUGS_PILLS_02', attribute="drug_effects", value={
"strength": 2,
"hitpoints": 1.20,
"effect_time": "24:00:00",
})

Mit folgenden Konsolenbefehlen kann man dies dann im neu gestarteten Spiel testen:

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_PILLS_01" )   Creatine Max   

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_PILLS_02" )   Anabole Steroide

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_PILLS_03" )   Tramaldione

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_PILLS_04" )   Koka

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_PILLS_05" )   Pheromone *

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_PILLS_06" )   Amphetamine *

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_VIALS_01" )   Guarana   

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_VIALS_02" )   Androstenedione

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_VIALS_03" )   Ritaldon

   object.create_item_in_inventory( "ALTER_EGO", "SET_DRUGS_SYRINGE" )   Palladine
 
* nicht im Orginalspiel aktiviert
Titel: Wie fügt man einen zusätzlichen NPC ein?
Beitrag von: Torka am 04. August 2010, 13:49:27 Uhr
Nun versuche ich das, was ich schon lange machen wollte - einen neuen NPC basteln und damit er zu was nütze ist, wird es ein Händler.

Die NPC werden in jedem Zonenordner in der npc.py definiert. Für die GNO-Karte wäre das z.B:  zones / zone_1 / npc.py


# Fine, die Testhändler
system.create_character(
id="FINE",
gender="female",
party="DORFBEWOHNER",
x=370,
y=575,
name=globaltext.NAME_FINE,
direction=300,
resourceui="sue_z7.png")

  objects.set_attribute("FINE", "faction", "VILLAGE_PEOPLE")
objects.set_attribute("FINE", "level", 1 )
  objects.set_attributes("FINE",
model="low",
gender="female",
skin="black",
clothes="sl_003",
face="edeltraud")
character.update_appearance("FINE")
character.scale("FINE",1.70)
objects.set_attribute("FINE", "trader", True)
objects.set_attribute("FINE", "trader_type", "all")
objects.set_attribute("FINE", "voice_id", "trader_03")
objects.create_item_in_inventory("FINE",
[ "SET_M_16",# M4A1
"SET_AMMOPACK_44"]# 1 Packen .44er Munition
+12*["SET_AMMOPACK_7_62NATO_MM"]# 12 Packen 7,62x51 nato Munition
+8*["SET_AMMOPACK_7_62NATO_MM_DUPLEX"]# 8 Packen 7,62x51 nato Duplex
+9*["SET_AMMOPACK_5_45_MM"]# 9 Packen 5,45mm
+7*["SET_AMMOPACK_5_7_MM"]# 7 Packen 5,7mm
+8*["SET_AMMOPACK_5_7_MM_SUBSONIC"]# 8 Packen 5,7mm Subsonicmunition
)
if not hasattr(data(), "patch_patrick"):
data().patch_patrick = 1

Ein paar Anmerkungen:

resourceui="sue_z7.png"  - definiert das Dialogbild des Charakters, zu finden in textures.ubn / textures / characters / human / low / dialog_faces (UBN-Dateien öffnen mit z.B. 7zip)

character.scale("FINE",1.70)  - kann man die Größe des NPC verändern - voll lustig, kann man "Gullivers Reisen"  oder den "Angriff der 20m Frau" spielen  :P

objects.create_item_in_inventory("FINE", ["SET_..."] + 12*["SET_..."] + 8*["SET_..."]) - das Inventar, Art und Anzahl veränderbar (die Preise werden in der scripts / itemdata / items.py oder weopons.py oder ammo.py verändert)


Damit die selbst gewählten Namen (id="FINE") auch im Spiel erscheinen müssen sie definiert werden in scripts / globaltext / german / names.py 

# Zone 1 - Neue TA NPCs
add_global_text(id="NAME_SEAMUS", text="Seamus")
.
.
.
add_global_text(id="NAME_NICK", text="Nick")
add_global_text(id="NAME_FINE", text="Fine")


An dieser Stelle werde ich weitere NPC-Eigenschaften auflisten, wenn ich sie finde:

character.set_approachable_state("RSGUARD_FRONT", NOTAPPROACHABLE)

objects.create_item_in_inventory("RSGUARD_FRONT", ["SET_MP5", "SET_AMMOPACK_9_MM","SET_AMMOPACK_9_MM"])
   
character.equip("RSGUARD_FRONT","SET_MP5")
Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 04. August 2010, 15:20:07 Uhr
Sehr schick Torka - meine Hochachtung das du dich so ausdauernd durch die pythonscripts durchwühlst  #thumbsup

Bezüglich Händlern muss ich Lexx wiedersprechen - bei mir ändern die während dem Spiel ihr Angebot bzw. es wird etwas hinzugefügt. Allerdings scheint es dafür ein hartes Limit oder so zu geben - irgendwann tut sich einfach nichts mehr in deren Inventories. Durch "Handelsreisen" kann man z.B. das ein oder andere Rüstungsset vervollständigen - allerdings ist das alles zufallsabhängig.

Beim durchlesen deiner Posts ist mir system_event.py aufgefallen - damit lässt sich bestimmt einiges anstellen (pseudo code):

... eigenen timer registrieren...

# game_init
    system.notify_global_timer("my_system_event_id", my_timer_value_in_milliseconds)

... dann ...

# system_event.py
if id == 'my_system_event_id':
  # new system.notify_global_timer() call to loop event
  re_equip_all_traders()
  do_something_else()
  ...

... sagt die engine nach Ablauf des Timers in system_event bescheid und lässt dich auf den Timer reagieren. Damit sollte es möglich sein Händler periodisch mit neuen Gegenständen auszustatten oder anderen Kram zu machen.

Ich hab The Fall hier nicht installiert, aber wenn du generelle Fragen zu Python hast kann ich dir bestimmt weiterhelfen. :) Dadurch das The Fall Python unterstützt kann man jede Menge Zeug umsetzen, die mit einer limitierten Scriptsprache (wie z.B. die bei Fallout) nicht möglich wäre. Was mir als einzig echtes Limit beim letzten stöbern in den Scripten aufgefallen ist, ist das komplette GUI-System. Das kann man nicht großartig per Script verändern. Irgendwo gibts hier glaub ich nen Thread dazu wo Lexx und ich da mal dran herumgedacht haben.

Grüßsche,
chewie
Titel: Das Händlerupdateskript
Beitrag von: Torka am 04. August 2010, 16:36:38 Uhr
Danke chewie  :). Die Erfahrung der Handelsreisen kann ich teilen und habe gestern den Skriptteil für die Item-Erneuerung der Händler gefunden - muss ihn nur jetzt wiederfinden, da ich gestern nicht recht schlau daraus geworden bin.   
Da ist es, es hat sich in scripts / objekt_events.py  versteckt

def on_update_trader( character_id ):
"""Called when the trading panel opens.

Parameters:
        character_id - Id of the trader.
"""

if objects.has_attribute( character_id, "last_trade" ):
last_trade_time = objects.get_attribute(character_id, "last_trade")
act_time = system.get_mission_time()
elapsed_time = act_time - last_trade_time
if elapsed_time >= timerepr.time("60:00:00"):
if objects.has_attribute( character_id, "backup_inventory" ):
act_inventory = objects.get_inventory_list( character_id )
backup_inventory = objects.get_attribute( character_id, "backup_inventory")
missing_objects = backup_inventory[:]
for _id in act_inventory:
if _id in missing_objects:
missing_objects.remove(_id)
if len(missing_objects):
all_items_list = system.get_item_list()
all_items_list = filter(lambda act_item:
(objects.has_attribute(act_item, "item_type") or
objects.has_attribute(act_item, "le_recovery") or
objects.has_attribute(act_item, "armor")), all_items_list)
all_items_list = filter(lambda act_item:
((objects.has_attribute(act_item, "not_tradable") and
not objects.get_attribute(act_item, "not_tradable")) or
not objects.has_attribute(act_item, "not_tradable")), all_items_list)

for item in missing_objects:
_list = helper_get_equivalent_items_list( all_items_list, item )
if len(_list):
new_item = random.choice(_list)
objects.create_item_in_inventory(object=character_id,
equipment=new_item)
backup_inventory.remove(item)
backup_inventory.append(new_item)
else:
inventory_list = objects.get_inventory_list( character_id )
objects.set_attribute( character_id, "backup_inventory", inventory_list)

Wenn ich das hier richtig verstehe werden die Items nach mehr wie 60 Ingamestunden ab dem letzten Kauf wieder ins Inventar befördert. Das funktioniert aber nur bedingt, da dies beim Benzin z.B. nicht geschieht  ??? - wird dieses durch ein anderes aus einer zufälligen Auswahl ersetzt und der Platz (Slot) ist dann besetzt? Hier habe ich noch große Verständnisschwierigkeiten...   

In der scripts / itemdata gibt es in der items.py bei einigen Questgegenständen (z.B. Rattenfelljacke) das Merkmal:

objects.set_attribute(object='SET_RAT_FUR_JACKET', attribute="not_tradable", value=True)  - dies bedeutet dann wohl, das diese Items heraus gefiltert werden.

Hmm, mir is da grad was aufgefallen, versuche einfach mal die Auswahlkriterien mit dem Attribut "value" zu ergänzen und zu Testzwecken wir die Zeit auf 3 Stunden verkürzt.

Das Attribut "value" ist natürlich eins, welches jedes Item besitzt - so waren dann auch munter alle möglichen Sachen dabei, wie z.B. Kupferdraht und das Gesellschaftsspiel *lol* kann man im Spiel nur einmal bauen  #lachen#, war aber fast klar, das der Zufallsgenerator das Benzin nicht ausgewählt hat.

Nun welches Merkmal hat nun das Benzin, welches viele nicht haben?

Ich probiere es mal mit: objects.set_attribute(object='SET_GAS_CANISTER', attribute="fuel", value=20) und nächste Testrunde  :coffee  :wall1cf:*motherfucker :para

Mit dem GUI-System habe ich mich noch fast gar nicht befasst - kommt bestimmt noch  ;D.
Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 04. August 2010, 19:02:09 Uhr
Hehe - nice find :)

Okay, so versteh ich das:

- der händler hat ein inventory & ein backup_inventory
- die beiden werden verglichen
- wenn backup_inventory mehr "_id"'s hat als das (echte) inventory (act_inventory, wahrscheinlich Kurzform für actor_inventory), dann wird quasi aufgefüllt
- der Auffüllmechanismus ist nicht komplett beliebig - da hier die Funktion helper_get_equivalent_items_list( all_items_list, item) benutzt wird
- pro "missing_object" wird also eine Liste an "ähnlichen Items" generiert - aus der wird dann zufällig eines ausgewählt (random.choice(_list)

Man könnte jetzt diese helper-Funktion umgehen und aus der kompletten Palette auswählen:

for item in missing_objects:
_list = all_items_list[:]
if _list:
new_item = random.choice(_list)
objects.create_item_in_inventory(object=character_id,
equipment=new_item)
backup_inventory.remove(item)
backup_inventory.append(new_item)


Generelle Anmerkungen:
- if _list: ist ähnlich wie if len(_list):, letzteres dürfte aber im Härtefall etwas langsamer sein (wichtig ist in dem Fall aber nur das die Liste nicht leer ist)
- _list = all_item_list[:] erzeugt eine Kopie von all_item_list (Vorraussetzung dafür ist das all_item_list auch wirklich ein Python-Listenobjekt ist ^^)
-  _id und _list sind normale Variablennamen, der Unterstrich dient nur dazu die eingebauten Typen von Python (id und list) nicht zu überschreiben. Kann ein kleines aber fieses Detail sein, über das sich Python erstmal nicht beschwert ;-)
-  zu random.choice: random ist ein modul von Python, choice eine Methode die aus einer beliebigen Python-Liste ein beliebiges Objekt auswählt & zurückgibt (ungemein praktisch ^^)

Man kann aber auch folgendes machen:

- Erstellen von separaten Listen, etwa CraftingItems, Ammo, Weapons, Armors etc.
- aus diesen Listen ein zufälliges Item herausnehmen und dem Händler ins Inventory packen

In dem Zusammenhang wäre interessant ob die Händler ein "unendlich großes" Inventory haben (eigentlich ist ja alles in einer Scrollarea drin) oder ob es ein hartes Limit gibt. Wenn es so eines gibt, dann sollte das System "eins geht raus, ein anderes kommt rein" unbedingt beibehalten, egal woher die neuen Items kommen.
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 04. August 2010, 19:48:55 Uhr
 ;D  - das erweitert doch glatt ein wenig mein Verständnis von dem Skript, obwohl alles noch ein wenig kryptisch ausschaut.

all_items_list = system.get_item_list()  - wird hier nicht definiert, das all_items_list der system.get_item_list() gleichgesetzt ist?

Habe es gerade mit all_items_list[:] getestet - es funktioniert, es werden sämtlich verfügbaren Items dem Inventar zugefügt, auch die Pseudomunition (z.B. des Messers). Ist ja so nicht gewollt.

Vorhin habe ich in die if len (missing_objects): das Attribut "fuel" mit hineingesetzt, jetzt kann man zumindest die Benzinflaschen kaufen.

if len(missing_objects):
all_items_list = system.get_item_list()
all_items_list = filter(lambda act_item:
(objects.has_attribute(act_item, "item_type") or
objects.has_attribute(act_item, "le_recovery") or
objects.has_attribute(act_item, "armor") or objects.has_attribute(act_item, "fuel")), all_items_list)


Wie kann ich die Liste, aus der zufällig ein fehlendes Item generiert wird, der  backup_inventory gleichsetzten? Dann werden nur Items aus dem schon von Anfang an vorhandenen Inventar generiert.

for item in missing_objects:
        _list = backup_inventory[:]
if _list:
new_item = random.choice(_list)
objects.create_item_in_inventory(object=character_id,
equipment=new_item)
backup_inventory.remove(item)
backup_inventory.append(new_item)


Werde erstmal testen.

Zitat
In dem Zusammenhang wäre interessant ob die Händler ein "unendlich großes" Inventory haben (eigentlich ist ja alles in einer Scrollarea drin) oder ob es ein hartes Limit gibt. Wenn es so eines gibt, dann sollte das System "eins geht raus, ein anderes kommt rein" unbedingt beibehalten, egal woher die neuen Items kommen.

Sie haben  ;). Habe das als Skript und Randnotiz auch gestern gelesen und mich gefreut. Da ich es aber auch nicht ändern wollte, auch gleich wieder vergessen wo es genau war  ::).
Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 04. August 2010, 20:51:12 Uhr
Zitat
all_items_list = system.get_item_list()  - wird hier nicht definiert, das all_items_list der system.get_item_list() gleichgesetzt ist?

all_items_list ist ein Variablenname, get_item_list() ist eine Methode der Klasse system (system.get_item_list()). Sprich die Methode ackert etwas vor sich hin und gibt dann eine Liste aller Items zurück. Eigentlich müsste die Methode irgendwo in den Python-Scripten herumfliegen, kann man sich mal bei Gelegenheit näher anschauen.

Zitat
Habe es gerade mit all_items_list[:] getestet - es funktioniert, es werden sämtlich verfügbaren Items dem Inventar zugefügt, auch die Pseudomunition (z.B. des Messers). Ist ja so nicht gewollt.

Yip, du hast auch schon den richtigen Codeschnippsel benutzt um das zu umgehen


all_items_list = filter(lambda act_item:
(objects.has_attribute(act_item, "item_type") or
objects.has_attribute(act_item, "le_recovery") or
objects.has_attribute(act_item, "armor") or objects.has_attribute(act_item, "fuel")), all_items_list)


Das sieht etwas kryptisch aus (liegt auch daran das hier mehrere Sachen geprüft werden, macht aber eigentlich das: nimm die Liste all_items_list und lege alle Items in eine neue Liste (die auch all_items_list heißt) für die gilt das sie die Attribute "item_type", "le_recovery" und "armor" haben.

Er hier

all_items_list = filter(lambda act_item: objects.has_attribute(act_item, "not_tradable"), all_items_list)

sorgt z.B. nur dafür das alle "not_tradable" Items rausfliegen.

Zitat
Wie kann ich die Liste, aus der zufällig ein fehlendes Item generiert wird, der  backup_inventory gleichsetzten? Dann werden nur Items aus dem schon von Anfang an vorhandenen Inventar generiert.

Ich weiß nicht wie sinnvoll das ist - wofür das backup_inventory genau da ist hab ich noch nicht verstanden. Weil: Wenn dem Händlermenü neue Items hinzugefügt werden, dann wird das auch dem Backupmenü hinzugefügt:

[..]
# (remove und append sind Listenoperation)

# lege neues item im inventory an
objects.create_item_in_inventory(object=character_id, equipment=new_item)
# schmeiß altes item aus backup_inventory raus
backup_inventory.remove(item)
# hänge neues item hinten ans backup_inventory ran
backup_inventory.append(new_item)

Wenn du aber den helper auf das backup_inventory loslassen willst, dann so:

_list = helper_get_equivalent_items_list( backup_inventory, item)

Der Helper will als Argumente eine Liste und ein Item: helper_get_equivalent_items_list(<Python list object>, <The Fall Item object>), Rückgabewert ist dann wieder ne Liste die du wie gehabt in random.choice() reinhaust um ein zufälliges Item zu erhalten.


Mal was anderes:

Wegen GUI hab ich den Thread von Lexx wiedergefunden wo wir das schon mal durchgequatscht haben Ist evtl. auch für dich interessant -> http://www.falloutnow.de/forum/index.php?topic=3274.0
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 04. August 2010, 22:38:47 Uhr
Voll geniale Sache, das du dich in Python so auskennst, bin erst seid letzter Woche dazu wie die Jungfrau zum Kind gekommen  ;D - grad `ne kleine Bierrunde in der WG gedreht - mal schauen ob es mit dem Testen noch was wird ...  hmm, (bei den Smileys fehlen irgendwie die Biergläser ...  :'( ;))

Zitat
Ich weiß nicht wie sinnvoll das ist - wofür das backup_inventory genau da ist hab ich noch nicht verstanden. Weil: Wenn dem Händlermenü neue Items hinzugefügt werden, dann wird das auch dem Backupmenü hinzugefügt:

Klar, das nächste Backup enthält vielleicht die zufällig aus dem letzten Backup generierten Items und irgendwann sind dann alle Items gleich (nur so ´ne Theorie) dann sollte jeder Händler schon eine Orginalliste haben und die genommen werden ...

Ich teste mal die Version _list = helper_get_equivalent_items_list( backup_inventory, item)

Zitat
Wegen GUI hab ich den Thread von Lexx wiedergefunden wo wir das schon mal durchgequatscht haben Ist evtl. auch für dich interessant -> http://www.falloutnow.de/forum/index.php?topic=3274.0

Na aber auf alle Fälle, da habe ich doch vor kurzem (auch schon 3 Monate her) schon mal gegraben - ist aber wieder durch die Maschen gefallen  :coffee

Lese gerade deine Verbesseungsideen und erkenne da konvergente Gedanken - echt schön  :D und noch besser habe die Neukombination von zwei Objekten gestern erfolgreich durchgezogen (Schweinefell + Lange Lederschnur = Wasserschlauch, nur ein Test, aber es funzt  #lachen# - Klamotten dürften auch kein Problem sein oder wie wäre der:  Dose + Schwarzpulver + Zünder = Landmine, aber das alles an einen anderen Teil im Thread oder ein neuer wäre am besten oder es gibt ja schon einen, den könnte man wieder zu den neukombinierten Gegenständen reaktivieren  ;)) 

In den Vorschlägen steckt eine Menge Potential - da werde ich mich nochmal gesondert dazu äußern.

(was wir evtl. mal archivieren sollten - ich würde mich nicht wundern wenn die Seite irgendwann vom Netz geht).  - na, wenn das dann mal nicht so auch war, schade das die Silver Style Leute da kein Bock mehr auf Forum haben

Zitat
Oder man fügt einen NPC bei der GNO ein der einem das Crafting "beibringt" (= Die Rezept-Quest gibt) ;-)


Das Crafting System im Spiel kann schon ganz schön an einem vorbeigehen, wenn man sich nicht außerhalb des Spiels informiert - weiß auch nicht was sich die Entwickler dabei gedacht haben, das man Unmengen von Items sammelt (bei den Staplungswerten und der Slotanzahl) und die dann wild miteinander mischt und hofft, ohne Tips, ohne Anleitung  :neien dabei ist es doch die Neukombination ganz nett, wenn man als Wastlander einen Handwerker trifft (wie bei Morrowind, die Ausbilder oder ein Rezeptbuch) und dieser die Weisheit mit einem teilt.
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 04. August 2010, 23:12:32 Uhr
Wer weiß, wie lange Silver Style überhaupt noch existiert. The Games Company hat vor kurzem Insolvenz angemeldet und Carsten ist als Chef zurück getreten, wenn ich mich richtig erinnere. Wage zu bezweifeln, dass das keinen Einfluss auf Silver Style haben wird. Vielleicht sollte mal jemand die Jungs fragen, ob sie nicht bock hätten, einiges an Material vom eingestampften Mutant City weitergeben wollen. Wäre bestimmt nützlich und vor allem cool drin zu graben.
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 04. August 2010, 23:37:36 Uhr
Krass - hab`s gerade auf golem gelesen. Bin auch schon um die Screens zu Mutant City herumgeschlichen und mir so Traumwelten vorgebastelt. Wäre auf alle Fälle eine Bereicherung und schade wenn es im Äther verschwinden würde. 

 #radi2  Schalte erstmal in den Testmodus  #radi2

Zitat
Ich teste mal die Version _list = helper_get_equivalent_items_list( backup_inventory, item)

Wie in der Theorie schon geahnt, in der Praxis nun bestätigt. Die zufällig ersetzten Items füllen die alte Liste auf und aus der neuen Backup werden beim nächsten Mal wieder zufällig welche ausgesucht und besetzten wieder die fehlenden Slots - irgendwann leidet die Vielfalt des Angebots derart. Der Händler hatte in der Testreihe nur noch Unmengen von Zeltplanen am Ende  :wall1cf: und wie kann es auch anders nicht sein, kein einziges mal wieder Benzin.
Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 05. August 2010, 00:45:24 Uhr
Jap, das macht Sinn - das Backup wird ja angelegt wenn du den Händler aufsuchst. Ich denke du brauchst "frische" Listen um aus denen auszuwählen. Gibts irgendwie ne Kategorie bei den Items? Weil dann könnte man die all_items_list per Filtern gezielt in Ammo / CraftingItems / Armors etc. zerlegen und da dann jeweils ein random.choice() rausziehen.
Titel: Benzin
Beitrag von: Torka am 05. August 2010, 01:20:11 Uhr
Das ist eine gute Idee. Die Objekte und deren Merkmale sind in itemdata in 3 Skripten definiert:  ammo.py , items.py und weapons.py

Nach ein wenig schauen habe ich direkt über dem Traderscript noch das dazugehörige Helperscript gefunden und das Konzept nochmal überdacht. Dort habe ich unter "le_recovery" dann analog auch "fuel" definiert und nun kann man auch erstmalig neue BENZINkanister und -flaschen bei den Händlern finden und tauschen  ;D Das Merkmal "fuel" ist halt zu verlockend, da es nur auf 2 Items (Flasche und Kanister Benzin) in der items.py zutrifft

def helper_get_equivalent_items_list(all_items_list, item ):
"""Helper function for on_update_trader.
"""
value = objects.get_attribute( item, "value" )
items_list = all_items_list[:]
item_type = None
if objects.has_attribute(item, "item_type"):
item_type = objects.get_attribute( item, "item_type" )

if item_type!=None:
result = filter(lambda act_item:
(objects.has_attribute(act_item, "item_type") and
objects.get_attribute(act_item, "item_type")==item_type), items_list)

if objects.has_attribute(item, "le_recovery"):
result = filter(lambda act_item:
objects.has_attribute(act_item, "le_recovery"), items_list)

if objects.has_attribute(item, "fuel"):
result = filter(lambda act_item:
objects.has_attribute(act_item, "fuel"), items_list)

if objects.has_attribute(item, "armor"):
armor = objects.get_attribute(item, "armor")
result = filter(lambda act_item:
(objects.has_attribute(act_item, "armor") and
objects.get_attribute(act_item, "armor")>(armor*0.8) and
objects.get_attribute(act_item, "armor")<(armor*1.2)), items_list)

result = filter(lambda act_item:
(objects.has_attribute(act_item, "value") and
(objects.get_attribute(act_item, "value")>(value*0.8) and
objects.get_attribute(act_item, "value")<(value*1.2))), items_list)

return result

Dennoch bin ich mit dem Grundprinzip des Händlerupdates etwas unzufrieden, da halt nach den Filtern aus einer dann begrenzten Menge von Items einige zufällig ausgewählte Objekte die fehlenden in der Inventarliste ersetzen. Einerseits hilft es die Vielfalt des Inventars zu bereichern, andererseits, wer will schon jedes Mal den Händler leer kaufen um dann zu hoffen, einer der Slots wird wieder zufällig mit Benzin besetzt. Je mehr freie (gekaufte) Objekte dann vorhanden sind, desto höher wird die Chance des Benzineingangs. Da dieses Script ja für alle Händler gilt, kann man ja auch nicht extra einen Tankwart, welcher nur Benzin generiert, erschaffen.
Ich hatte ja bei Miles (versteckter Waffenhändler in Casa Verde) die Hoffnung eine Spezialisierung nur auf Waffen im Skript zu entdecken - dies war sicher auch mal der Gedanke. Die Spezialisierung hat sich im Spiel nicht feststellen lassen und in den Skripten habe ich auch nichts gefunden. Irgendwann kann man alles bei ihm tauschen (bei Morrowind waren die Items auch gut gefiltert und so konnte man nicht überall alles kaufen und verkaufen).

Eine sehr unflexible Idee wäre es, das sich einfach jedes Item aus dem Inventar des Händlers nach einer gewissen Zeit wieder generiert ohne Zufall halt - alles wäre sehr vorhersehbar und man bekäme mit Sicherheit Benzin, nicht erst nach Tauschmarathons und Lotterie.

Eine weitere Idee ist, die Auswahl der zufälligen Objekte nicht nach dem Vergleich der fehlenden Items zu generieren, sondern die Inventarliste des Händlers nach einem Tag z.B. komplett neu zufällig zusammen zu setzten. Nachteile wären, das der Händler nicht mehr als Zwischenspeicher dienen kann, denn man kann nicht darauf vertrauen, das er einen Tag später immer noch das verkaufte Objekt hat. 

Eine andere Idee wäre die Items zu wichten, damit sie gegenüber anderen einfach häufiger ausgewählt werden. Dazu müsste auch zu jedem Item ein neues Merkmal hinzugefügt werden und dieses im Skript verarbeitet werden. Derzeit sehe ich mich aber nicht im Stande, dies mit meiner Skripterfahrung umzusetzten.     
Titel: Re: Mod-Tagebuch
Beitrag von: Hornet am 05. August 2010, 14:46:11 Uhr
Größten Respekt für die Arbeit die ihr da investiert. #thumbup
Titel: Re: Benzin
Beitrag von: le Chew am 05. August 2010, 17:33:21 Uhr
Da dieses Script ja für alle Händler gilt, kann man ja auch nicht extra einen Tankwart, welcher nur Benzin generiert, erschaffen.
Ich hatte ja bei Miles (versteckter Waffenhändler in Casa Verde) die Hoffnung eine Spezialisierung nur auf Waffen im Skript zu entdecken - dies war sicher auch mal der Gedanke. Die Spezialisierung hat sich im Spiel nicht feststellen lassen und in den Skripten habe ich auch nichts gefunden. Irgendwann kann man alles bei ihm tauschen (bei Morrowind waren die Items auch gut gefiltert und so konnte man nicht überall alles kaufen und verkaufen).

Da muss ich dich "enttäuschen"  :s000:

Die Funktion ist nicht für alle Händler, sondern arbeitet nur auf dem Inventory des Händlers, den der Spieler gerade besucht:

def on_update_trader( character_id ):
""" Called when the trading panel opens.

Parameters:
        character_id - Id of the trader.
"""

Funktion wird aufgerufen wenn der Handelsbildschirm geöffnet wird, übergebene Charakter-Id ist die des jeweiligen Händlers. (Und die wird dann benutzt um das act_inventory bzw. backup_inventory zu holen)

Eine sehr unflexible Idee wäre es, das sich einfach jedes Item aus dem Inventar des Händlers nach einer gewissen Zeit wieder generiert ohne Zufall halt - alles wäre sehr vorhersehbar und man bekäme mit Sicherheit Benzin, nicht erst nach Tauschmarathons und Lotterie.

Eine weitere Idee ist, die Auswahl der zufälligen Objekte nicht nach dem Vergleich der fehlenden Items zu generieren, sondern die Inventarliste des Händlers nach einem Tag z.B. komplett neu zufällig zusammen zu setzten. Nachteile wären, das der Händler nicht mehr als Zwischenspeicher dienen kann, denn man kann nicht darauf vertrauen, das er einen Tag später immer noch das verkaufte Objekt hat. 

Eine andere Idee wäre die Items zu wichten, damit sie gegenüber anderen einfach häufiger ausgewählt werden. Dazu müsste auch zu jedem Item ein neues Merkmal hinzugefügt werden und dieses im Skript verarbeitet werden. Derzeit sehe ich mich aber nicht im Stande, dies mit meiner Skripterfahrung umzusetzten.     

Wie schon gesagt, dadurch das hier alles in Python abläuft, hast du alle Freiheiten. Du kannst die Händler-Inventare auch komplett überschreiben und sie z.B. zu reinen Waffenhändlern umbauen. Du kannst auch in die Funktion on_update_trader() einen weiteren Check einbauen, der eine auf den Händler zugeschnittene Auffüllfunktion benutzt. Zum Beispiel so (Pseudocode):

def refill_generic_trader():
    #   ... code für den generic trader ...

def refill_weapon_trader():
    # .... code für den weapon traider ...

if character_id == 'ngo-händler':
    helpermethod = refill_generic_trader
elif character_id == 'Miles':
    helpermethod = refill_weapon_trader

helpermethod()


Anmerkungen:
- Funktionen kannst du auch innerhalb einer Funktion erstellen
- du kannst Funktionen in Variablen packen - erst wenn du "()" dranhängst, werden sie ausgeführt (helpermethod ist in dem Beispiel nur ein neuer Name für refill_weapon_trader() etc...)

cheers,
chewie

Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 05. August 2010, 21:48:00 Uhr
Phu,  :wtf habe gerade das Handelsskript "zerschossen", GsD ein Backup gemacht. Erstmal danke für die Tipps und Korrekturen  #thumbsup. Das hilft für das Verständnis schon ungemein, aber ich merke auch, dass die Umarbeitung des Handelskripts etwas anderes ist als nur Werte zu verändern oder schon geschriebene Skripte einzufügen. Mache erstmal eine Skriptpause und wende mich der Biosphäre zu (bin ja nun schon auf den Showdown gespannt ;))

Ganz schön heftige Auseinandersetzung in der Sphäre  *motherfucker. War jemand schon mal in dem Präsidentenhaus im GNO-HQ? Ich dachte da könnte man dann irgendwann mal rein, da ja auch ein Safe darin steht.   
Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 06. August 2010, 01:34:50 Uhr
Phu,  :wtf habe gerade das Handelsskript "zerschossen", GsD ein Backup gemacht. Erstmal danke für die Tipps und Korrekturen  #thumbsup. Das hilft für das Verständnis schon ungemein, aber ich merke auch, dass die Umarbeitung des Handelskripts etwas anderes ist als nur Werte zu verändern oder schon geschriebene Skripte einzufügen. Mache erstmal eine Skriptpause und wende mich der Biosphäre zu (bin ja nun schon auf den Showdown gespannt ;))

Das kriegen wir schon hin - solche Tiefs hat man immer mal.   :)  Ich werd mal sehen ob ich es zeitlich schaffe dir was zusammenzutippen.

Ganz schön heftige Auseinandersetzung in der Sphäre  *motherfucker. War jemand schon mal in dem Präsidentenhaus im GNO-HQ? Ich dachte da könnte man dann irgendwann mal rein, da ja auch ein Safe darin steht.  

Jep, da gibts an der nord-östlichen Ecke eine "unsichtbare" Lücke im Zaun - da kannst du unten drunter durchrobben (!). Dürfte das 3te Zaunsegment sein wenn ich mich richtig erinnere.

Ist ein Lederhelmchen drin - den Rest weiß ich nicht mehr ausm Kopp.

Edith

Sodele, ich hab die on_update_trader()-Funktion mal etwas durchdokumentiert und hier und da etwas geändert. Jetzt brauch ich ein paar Infos was du umgesetzt haben willst. Wenn du z.B. "Händlerprofile" haben willst, dann muss ich die Händler-IDs und die bevorzugten Items wissen. Mit denen bau ich dann Fallunterscheidungen ein und bereite individuelle Restock-Helper vor.

Meine Version hab ich auf pastebin geparkt -> http://fall.pastebin.com/drRX4VVU (Ist mit syntax highlighting einfach schöner zu lesen ^^ Beim Download nur nicht copy&paste machen - das mag python nicht. Stattdessen die Option "Raw" benutzen)

cheers,
chewie
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 06. August 2010, 23:30:16 Uhr
Zitat
Jep, da gibts an der nord-östlichen Ecke eine "unsichtbare" Lücke im Zaun - da kannst du unten drunter durchrobben (!). Dürfte das 3te Zaunsegment sein wenn ich mich richtig erinnere.

Na, astrein - Danke - mit ein wenig Gequetsche am Anfang, läuft dann jeder Durchgang problemlos.  #thumbsup

Habe in der der Zwischenmodpause auch gleich nochmal an der Spirit Springs - Karte für den Almanach gesessen - nur noch zwei dann  :D.   

Zitat
Sodele, ich hab die on_update_trader()-Funktion mal etwas durchdokumentiert und hier und da etwas geändert.

Na aber, das sieht  mal schick aus - bin mal erst am schauen ... ich teste es jetzt einfach mal. 

Skript läuft erstmal, wenn man den Händler aber leer kauft regeneriert sich nichts. Wenn er z.B. keine Kleidung mehr hat dann auch diese nicht. 

Vom Orginalskript werde ich aus diesem Teil nicht schlau :

if objects.has_attribute( character_id, "backup_inventory" ):
act_inventory = objects.get_inventory_list( character_id )
backup_inventory = objects.get_attribute( character_id, "backup_inventory")
missing_objects = backup_inventory[:]
for _id in act_inventory:
if _id in missing_objects:
missing_objects.remove(_id)


Über dem Skiptteil stehen noch das Helperskript:

def helper_get_equivalent_items_list(all_items_list, item ):
"""Helper function for on_update_trader.
"""
value = objects.get_attribute( item, "value" )
items_list = all_items_list[:]
item_type = None
if objects.has_attribute(item, "item_type"):
item_type = objects.get_attribute( item, "item_type" )

if item_type!=None:
result = filter(lambda act_item:
(objects.has_attribute(act_item, "item_type") and
objects.get_attribute(act_item, "item_type")==item_type), items_list)

if objects.has_attribute(item, "le_recovery"):
result = filter(lambda act_item:
objects.has_attribute(act_item, "le_recovery"), items_list)

if objects.has_attribute(item, "armor"):
armor = objects.get_attribute(item, "armor")
result = filter(lambda act_item:
(objects.has_attribute(act_item, "armor") and
objects.get_attribute(act_item, "armor")>(armor*0.8) and
objects.get_attribute(act_item, "armor")<(armor*1.2)), items_list)

result = filter(lambda act_item:
(objects.has_attribute(act_item, "value") and
(objects.get_attribute(act_item, "value")>(value*0.8) and
objects.get_attribute(act_item, "value")<(value*1.2))), items_list)

return result

Ich versuche mal die Ideen besser zu ordnen:

Grundidee war einen Tankwart zu erschaffen, dieser sollte einfach nur Benzin haben und verkaufen.
Nach einer gewissen Zeit hat er dann halt wieder welches, also es wird einfach ersetzt.
Die Händler_ID wäre der Name, z. B. "Fritz" und das bevorzugte Item einfach nur GAS_CANISTER. 
Den Zufallsgenerator brauch man dann nicht, einfach nur das Respawnen des Benzins.
Klar hat er dann irgendwann im Inventar auch andere Items, da man ja das Benzin eintauschen muss. Aber nur das Benzin und die Flasche Benzin (BOTTLE_OF_GAS) haben das Attribut "fuel".




 
Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 07. August 2010, 02:06:26 Uhr
Vom Orginalskript werde ich aus diesem Teil nicht schlau :

if objects.has_attribute( character_id, "backup_inventory" ):
act_inventory = objects.get_inventory_list( character_id )
backup_inventory = objects.get_attribute( character_id, "backup_inventory")
missing_objects = backup_inventory[:]
for _id in act_inventory:
if _id in missing_objects:
missing_objects.remove(_id)


Ich versuchs mal zu übersetzen:

- Wenn das object mit der id "character_id" das Attribut "backup_inventory" hat, dann
        - hol dir das inventory dieses objekts
        - hol dir das backup_inventory dieses objekts
        - mach eine kopie vom backup_inventory und nenne sie "missing_objects"
        - gehe alle _id's des inventories durch und prüfe, ob sie in "missing_objects" sind
        - wenn ja, dann lösche die jeweilige _id aus "missing_objects"
- ansonsten mach gar nichts

Wenn das durchgelaufen ist, dann ist garantiert keine _id aus dem "act_inventory" mehr in "missing_objects" - und für die Anzahl der verbliebenen Objekte in "missing_objects" wird jetzt aufgefüllt.

Einen kleinen Verdacht habe ich aber jetzt - und zwar warum Handelsreisen irgendwann keine neuen Items mehr generieren. Das müsste man zwar nochmal in Ruhe durchchecken, aber irgendwann ist das backup_inventory leer - und ab dem Zeitpunkt wird nichts mehr nachgefüllt. Das sollte passieren wenn der Check (Originalscript) if len(missing_objects) False ergibt - nämlich missing_objects nur noch eine leere Liste ist.

Grundidee war einen Tankwart zu erschaffen, dieser sollte einfach nur Benzin haben und verkaufen.
Nach einer gewissen Zeit hat er dann halt wieder welches, also es wird einfach ersetzt.
Die Händler_ID wäre der Name, z. B. "Fritz" und das bevorzugte Item einfach nur GAS_CANISTER. 
Den Zufallsgenerator brauch man dann nicht, einfach nur das Respawnen des Benzins.
Klar hat er dann irgendwann im Inventar auch andere Items, da man ja das Benzin eintauschen muss. Aber nur das Benzin und die Flasche Benzin (BOTTLE_OF_GAS) haben das Attribut "fuel".

Na da kommt mir doch gerade eine herrlich einfache Idee:

- Du legst den Benzintrader fest, und haust ihm ne ordentliche Portion Sprit ins Inventory
- Ich schreib eine Fallüberprüfung auf if character_id = Spritdealer: und mach dann folgendes:
     - das Inventory des Spritdealers soll immer mindestens MIN_SPRIT enthalten
     - wenn die Zahl drunter liegt, dann generieren wir eine zufällige Anzahl von Spritkanistern und packen die wieder ins inventory

Sollte klappen, oder? Zufall deswegen: Wir sind immer noch im Ödland - und mal treiben die Scavenger 5l auf, mal 10l - und an einem guten Tag knallen sie noch ein paar Ratskulls übern haufen und erbeuten 15l :>
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 07. August 2010, 15:26:55 Uhr
Einen kleinen Verdacht habe ich aber jetzt - und zwar warum Handelsreisen irgendwann keine neuen Items mehr generieren.
Das müsste man zwar nochmal in Ruhe durchchecken, aber irgendwann ist das backup_inventory leer - und ab dem Zeitpunkt wird nichts mehr nachgefüllt.
Das sollte passieren wenn der Check (Originalscript) if len(missing_objects) False ergibt - nämlich missing_objects nur noch eine leere Liste ist.

Das könnte stimmen, wenn man nichts mehr von den Händlern kauft, da das Angebot sich nicht ändert - entstehen keine freien Slots, welche durch Zufall wieder aufgefüllt werden. So bleibt das Angebot dann immer gleich. Hatte ja in der Schattenbasis immer noch auf den Raketenwerfer gehofft - dieser ist aber nie angekommen. Ärgerlich ist das bei bestimmter Munition, welche dann einfach nicht mehr respawnt wird  :'( bzw. die ehemaligen Munslots mit anderer Munition besetzt wird.

Aber das später  ;D. Habe dem Inventar der "Spritdealerin Fine" 7 Kanister und 6 Flaschen Benzin gegeben. Die Anzahl kann man aber beliebig verändern ;).

# Fine, die Testhändler
system.create_character(
id="FINE",
gender="female",
party="DORFBEWOHNER",
x=370,
y=585,
name=globaltext.NAME_FINE,
direction=180,
resourceui="sue_z7.png")
  objects.set_attribute("FINE", "faction", "VILLAGE_PEOPLE")
objects.set_attribute("FINE", "level", 1 )
  objects.set_attributes("FINE",
model="low",
gender="female",
skin="black",
clothes="sl_003",
face="edeltraud")
character.update_appearance("FINE")
character.scale("FINE",1.70)

objects.set_attribute("FINE", "trader", True)
objects.set_attribute("FINE", "trader_type", "all")
objects.set_attribute("FINE", "voice_id", "trader_02")
objects.create_item_in_inventory("FINE",
7*["SET_GAS_CANISTER"]        
        +6*["SET_BOTTLE_OF_GAS"]
)
if not hasattr(data(), "patch_patrick"):
data().patch_patrick = 1

chewies  Händlerskript:

def restock_fuel_traders(character_id):
""" check if the given trader is a fuel trader
and restock his inventory (if necessary)

FIXME:
- move _FUEL_TRADERS constant to global scope

@type character_id: string
@param character_id: Id of the trader.
"""
_FUEL_TRADERS = ["FINE",]
_MIN_FUEL = 13

result = False

if character_id in _FUEL_TRADERS:
result = True
act_inventory = objects.get_inventory_list( character_id )

# get all fuel items
fuel_list = filter(lambda item: objects.has_attribute(item, "fuel"), act_inventory)
# restock amount of fuel if necessary
ifuel = len(fuel_list)
if ifuel < _MIN_FUEL:
amount = _MIN_FUEL - ifuel

objects.create_item_in_inventory(
character_id,
amount*["SET_GAS_CANISTER"]
)
objects.create_item_in_inventory(
character_id,
        amount*["SET_BOTTLE_OF_GAS"]
)
return result
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 27. August 2010, 02:00:40 Uhr
Nach längeren Bedenken habe ich gestern doch einmal einen Brief an Silver Style geschrieben. Darin habe ich gefragt, ob es vielleicht möglich wäre, das schon vorhandene Material des leider eingestellten Addons "Mutant City" auf der offiziellen Seite zum Download frei zu stellen. Auf eine Antwort bin ich sehr gespannt und warte es einfach mal ab  :). 

(http://www.falloutnow.de/forum/gallery/thumb_18_18_08_08_11_47_29.jpg) (http://www.falloutnow.de/forum/index.php?action=gallery;sa=view;id=338)  (http://www.falloutnow.de/forum/gallery/thumb_18_18_08_08_11_46_42.jpg) (http://www.falloutnow.de/forum/index.php?action=gallery;sa=view;id=336)
Der Bausstil würde sich bestimmt gut in die Wastelands einfügen.
Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 27. August 2010, 02:09:34 Uhr
Nach längeren Bedenken habe ich gestern doch einmal einen Brief an Silver Style geschrieben. Darin habe ich gefragt, ob es vielleicht möglich wäre, das schon vorhandene Material des leider eingestellten Addons "Mutant City" auf der offiziellen Seite zum Download frei zu stellen. Auf eine Antwort bin ich sehr gespannt und warte es einfach mal ab  :). 

Sauber :) Und wenn sie das nicht mehr finden sollten wäre evtl. ein temporäres Auferstehen des alten silverstyle-Forums nice - so das wir die Modding-relevanten Themen hierher migrieren können :)
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 27. August 2010, 02:55:08 Uhr
Zitat
Und wenn sie das nicht mehr finden sollten wäre evtl. ein temporäres Auferstehen des alten silverstyle-Forums nice - so das wir die Modding-relevanten Themen hierher migrieren können.

Das wäre natürlich echt spitze, wenn man an die Moddingthreads herankommt und sie wieder online stellen würde. Kenne ja das Forum nur vom Hörensagen. Die Infos wären sicher hilfreich um die Welt von "The Fall" zu erweitern. Finde es immer sehr schade, das nach der Handlung so eine virtuelle Welt brach liegt. Das Addon "Mutant City" hätte sicher eine gute Chance gehabt weitere witzige Handlunsstränge zu verflechten und neue Abenteuer in den Wastelands zu eröffnen.
Ich hoffe aber überhaupt erst einmal auf eine Antwort vom Team.  
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 27. August 2010, 12:00:45 Uhr
Naja, so viele Informationen gab es im Forum auch nicht. Lediglich drei oder vier Threads wären noch interessant, wenn ich mich richtig erinnere. Unter anderem der, in dem beschrieben wurde, wie die Minimap generiert wird, etc. Der Rest ist (zumindest mir) mehr oder weniger bekannt. Abgesehen von den Problemen mit dem Hinzufügen eines neuen Ortes und dem korrekten Anzeigen dessen Name im Quest Log natürlich.....
Titel: Re: Mod-Tagebuch
Beitrag von: Tyler am 28. August 2010, 13:09:42 Uhr
Wolna muss wieder ran. Der kann dann das ganze russische Communityzeug übersetzen.^^
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 28. August 2010, 13:18:40 Uhr
lol. Der Witz war gut. :>
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 28. August 2010, 13:32:05 Uhr
Erst müsste Silver Style auf die Mail antworten. Mal schauen ob sie Interesse zeigen? Zur Not gibt`s ja unter Kontakt ja auch noch `ne Telefonnummer oder Lexx klingelt mal an der Ladentür  ;).
Bisher haben sie sich noch nicht gemeldet, sind vielleicht auch grad im Urlaub  ;D. 

Für Wolna hätte ich da schon mal ne russische Seite http://fall.pro-d.ru/?map - aber sie verstehen auch englisch dort  #thumbsup.
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 28. August 2010, 13:34:25 Uhr
Ich wohne am anderen Ende von Berlin. Da hinzufahren wäre ein Tagesausflug.
Titel: Neue kombinierte Items - abgebrochene Flasche
Beitrag von: Torka am 06. September 2010, 00:48:37 Uhr
Die Mitarbeiter von Silver Style haben leider noch nicht geantwortet, werde es erneut versuchen. In der Zwischenzeit habe ich etwas mit den kombierbaren Items experimentiert und poste mal den ersten Erfolg.

Im Spiel existiert als Nahkampfwaffe auch eine abgebrochene Glasflasche. Diese habe ich nur bei der Ärztin der Schatten gesehen, welche sie aber als Trichter verwendet hat. Die Idee ist aus einer leeren Flasche eine abgebrochene zu basteln - klingt einfach, war es auch.

Die leere Flasche befindet sich in scripts / itemdata / items.py  Nebenbei habe ich den Stapplungswert (stacking) bei allen Items, der Munition und vielen Nahkampfwaffen einfach mal um Faktor 10 bis 100 erhöht :).

create_item_type(typeid='SET_EMPTY_BOTTLE')
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="name", value=globaltext.SET_EMPTY_BOTTLE_NAME)
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="hint", value=globaltext.SET_EMPTY_BOTTLE_HINT)
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_EMPTY_BOTTLE')
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="resource3d", value='RES3D_EMPTY_BOTTLE')
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="value", value=1.0)
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="weight", value=0.3)
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="stacking", value=100)
objects.set_attribute(object='SET_EMPTY_BOTTLE', attribute="occupied_slots", value=["left_hand","right_hand"])

Die abgebrochene Flasche als Waffe befindet sich in scripts / itemdata / weapons.py

create_weapon_type(typeid='SET_BROKEN_OFF_BOTTLE')
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="name", value=globaltext.SET_BROKEN_OFF_BOTTLE_NAME)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="hint", value=globaltext.SET_BROKEN_OFF_BOTTLE_HINT)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_BROKEN_OFF_BOTTLE')
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="resource3d", value='RES3D_BROKEN_OFF_BOTTLE')
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="value", value=0.00)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="weight", value=0.10)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="stacking", value=100)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="weapon_type", value="nahkampf")
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="hoerweite", value=2.0)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="schusspausenzeit", value=1.6)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="genauigkeit_bewegte_ziele", value=0.6)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="genauigkeit", value=0.2)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="minimale_feuerreichweite", value=0)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="maximale_feuerreichweite", value=2)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="salvenlaenge", value=1)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="feuergeschwindigkeit", value=0.0)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="occupied_slots", value=["right_hand"])
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="fire_animation", value=FPA_CLOSE_COMBAT_BATON)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="munitionsarten", value=['SET_BROKEN_OFF_BOTTLE_PSEUDOAMMO'])
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="magazingroesse", value=1.0)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="effects", value={"sound_shot" : "attack_knife"})
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="illegal_bodymodes", value=["LIE","KNEEL"])
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="combine_xp", value=25)
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
"combination_list" : [
['SET_EMPTY_BOTTLE']]})

objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="combine_xp", value=25)                          Man erhält 25 XP für das erste Zerschlagen der Flasche.
objects.set_attribute(object='SET_BROKEN_OFF_BOTTLE', attribute="item_combination",   value={
   "difficulty_assemble"   :                                COMBO_EVERYBODY,                                                           Die Herstellung gelingt unabhängig vom Technikskill.
   "combination_list"      :     [  
                                                                                                                        ['SET_EMPTY_BOTTLE']]})     In der Liste ist nur die leere Flasche.
Weitere Beispiele:
"difficulty_assemble" : 65,Durch diese Zeile wäre die Herstellung nicht für jedermann durchführbar, sondern erst ab einem Technikskill von 65 möglich.

"assemble_function" : "assemble_explosives", Die Herstellung gelingt nur, wenn man über das Talent "Sprengstoffe herstellen" verfügt.



Nun stellt man sich spontan die Frage, wozu bei den ganzen Ballermännern braucht man eine abgebrochene Flasche - also in der Arena könnte ja zufällig von der Tribüne mal eine leere Flasche fallen  ;D
Titel: Neue Wurfwaffe - der Stein
Beitrag von: Torka am 06. September 2010, 02:35:17 Uhr
Was wäre wohl aus der Menschheit ohne die älteste aller Fernwaffen geworden....  ??? warum den Helden von TF der einfache Stein als Wurfwaffe vorenthalten wurde und dafür solche praktischen Dartpfeile existieren, blieb mir immer ein Rätsel. Nun im Raten bin ich eher schlecht und habe den Stein einfach mal dem Inventar hinzugefügt ... zumindest in der Theorie, denn wer will schon Steine vom Händler kaufen, jener kauft dann später auch Steine im Baumarkt   :redfingr:.
Also werden auf den Karten dann halt Steine zum Auflesen zu finden sein, denn man kann sie ja nach dem Werfen wieder verwenden.

Das ursprüngliche Steinskript in scripts / itemdata / items.py mit # deaktivieren oder löschen (Backup gemacht?).

Und dazu das eingefügte Skript in scripts / itemdata / weapons.py Habe es direkt unter dem Wurfmesser plaziert.

create_throw_object_type(typeid='SET_STONE')
objects.set_attribute(object='SET_STONE', attribute="name", value=globaltext.SET_STONE_NAME)
objects.set_attribute(object='SET_STONE', attribute="hint", value=globaltext.SET_STONE_HINT)
objects.set_attribute(object='SET_STONE', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_STONE')
objects.set_attribute(object='SET_STONE', attribute="resource3d", value='RES3D_STONE')
objects.set_attribute(object='SET_STONE', attribute="value", value=1.0)
objects.set_attribute(object='SET_STONE', attribute="weight", value=1.2)
objects.set_attribute(object='SET_STONE', attribute="stacking", value=500)
objects.set_attribute(object='SET_STONE', attribute="minimale_feuerreichweite", value=0)
objects.set_attribute(object='SET_STONE', attribute="maximale_feuerreichweite", value=23)
objects.set_attribute(object='SET_STONE', attribute="salvenlaenge", value=1)
objects.set_attribute(object='SET_STONE', attribute="feuergeschwindigkeit", value=0)
objects.set_attribute(object='SET_STONE', attribute="genauigkeit", value=0.6)
objects.set_attribute(object='SET_STONE', attribute="kampfwert_air", value=15.00)
objects.set_attribute(object='SET_STONE', attribute="kampfwert_armoured", value=100.00)
objects.set_attribute(object='SET_STONE', attribute="kampfwert_infantry", value=100.00)
objects.set_attribute(object='SET_STONE', attribute="munitionsarten", value=['SET_STONE_PSEUDOAMMO'])
objects.set_attribute(object='SET_STONE', attribute="fire_animation", value=FPA_THROW_KNIFE)
objects.set_attribute(object='SET_STONE', attribute="weapon_type", value="wurf")
objects.set_attribute(object='SET_STONE', attribute="magazingroesse", value=1.0)
objects.set_attribute(object='SET_STONE', attribute="hoerweite", value=0.0)
objects.set_attribute(object='SET_STONE', attribute="schusspausenzeit", value=1.5)
objects.set_attribute(object='SET_STONE', attribute="genauigkeit_bewegte_ziele", value=0.5)
objects.set_attribute(object='SET_STONE', attribute="occupied_slots", value=["throw"])


Alle Wurfwaffen haben eine Pseudomunition, welche in scripts / itemdata / ammo.py und den Schaden verursacht, sie ist Ingame nicht sichtbar, aber für den erzeugten Schaden notwendig.
create_ammo_type(typeid='SET_STONE_PSEUDOAMMO')
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="name", value='None')
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="hint", value='None')
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="resourceui", value='None')
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="resource3d", value='None')
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="value", value=0.00)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="weight", value=3)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="stacking", value=1)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="wirkungsbereich", value=0.0)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="schaden_organisch_min", value=100)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="schaden_organisch_max", value=150)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="schaden_struktur_min", value=0)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="schaden_struktur_max", value=1)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="schuss", value=1)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="schussbahn", value=BALLISTIC)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="muendungsgeschwindigkeit_min",value=7)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="muendungsgeschwindigkeit_max",value=7)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="durchschlag", value=20)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="hit_chance_factor", value=1.0)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="fire_range_factor", value=1.0)
objects.set_attribute(object='SET_STONE_PSEUDOAMMO', attribute="weapon_types", value=[])

Einzigstes Manko, der Stein ist leider nicht in der Hand sichtbar, aber in der Wurfbahn schon  - Willkommen in der Steinzeit  :D.
Titel: Bolzen und Armbrust selbst herstellen
Beitrag von: Torka am 06. September 2010, 22:20:53 Uhr
Das es im Spiel eine Armbrust gibt ist eine feine Sache, noch besser wäre es, wenn es auch mehr Bolzen dafür geben würde. Die Ödnis ist ja voll von Zivilisationsschrott, warum also aus den alten Eisenstangen nicht selbst Bolzen feilen  ;).

In der Datei scripts / itemdata / ammo.py  einfach folgende Zeilen einfügen:

create_ammo_type(typeid='SET_SHORT_IRON_ROD')
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="name", value=globaltext.SET_SHORT_IRON_ROD_NAME)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="hint", value=globaltext.SET_SHORT_IRON_ROD_HINT)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_RUSTY_IRON_ROD')
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="resource3d", value='RES3D_RUSTY_IRON_ROD')
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="value", value=1.00)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="weight", value=0.50)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="stacking", value=100)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="wirkungsbereich", value=0.00)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="schaden_organisch_min", value=22)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="schaden_organisch_max", value=25)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="schaden_struktur_min", value=0)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="schaden_struktur_max", value=4)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="schuss", value=5)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="schussbahn", value=LINEAR)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="muendungsgeschwindigkeit_min",value=200)## !! >>
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="muendungsgeschwindigkeit_max",value=200)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="kaliber", value=globaltext.CALIBER_BOLT)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="durchschlag", value=20)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="hit_chance_factor", value=1.0)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="fire_range_factor", value=1.0)
objects.set_attribute(object='SET_SHORT_IRON_ROD', attribute="weapon_types", value=[])

create_ammo_type(typeid='SET_AMMOPACK_BOLT')
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="name", value=globaltext.SET_AMMOPACK_BOLT_NAME)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="hint", value=globaltext.SET_AMMOPACK_BOLT_HINT)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="resourceui", value='RES_ITEM65X32_AMMOPACK_BOLT')
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="resource3d", value='RES3D_AMMOPACK_BOLT')
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="value", value=2.00)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="weight", value=0.20)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="stacking", value=100)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="wirkungsbereich", value=0.00)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="schaden_organisch_min", value=22)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="schaden_organisch_max", value=25)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="schaden_struktur_min", value=0)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="schaden_struktur_max", value=4)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="schuss", value=5)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="schussbahn", value=LINEAR)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="muendungsgeschwindigkeit_min",value=200)## !! >>
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="muendungsgeschwindigkeit_max",value=200)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="kaliber", value=globaltext.CALIBER_BOLT)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="durchschlag", value=20)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="hit_chance_factor", value=1.0)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="fire_range_factor", value=1.0)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="weapon_types", value=[])
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="combine_xp", value=75)
objects.set_attribute(object='SET_AMMOPACK_BOLT', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
"assemble_function" : "assemble_dumdum_munition",
"combination_list" : [['SET_RASP','SET_SHORT_IRON_ROD']]})

Die kurze Eisenstange sollte dann noch als Name und Hint in scripts / globaltext / german / german.py  wie folgend definiert werden:
add_global_text(id='SET_SHORT_IRON_ROD_NAME', text='kurze Eisenstange')
add_global_text(id='SET_SHORT_IRON_ROD_HINT', text='kurze Eisenstange')

Nun kann man mit dem Talent "Munition  manipulieren" und einer Feile aus kurzen Eisenstangen selbst Bolzen herstellen. Die Eistenstangen müssten dann an alten Wehrzäunen oder Ruinen, Schrottplätzen zu finden sein.
Ein paar Erfahrungspunkte bekommt man bei der ersten Bolzenanfertigung.

Bei den vielen Ersatzteilen könnte man sich ja dann auch eine Armbrust selber basteln und so in der scripts / itemdata / weapons.py  das Armbrustskript verlängern:
create_weapon_type(typeid='SET_CROSSBOW')
objects.set_attribute(object='SET_CROSSBOW', attribute="name", value=globaltext.SET_CROSSBOW_NAME)
objects.set_attribute(object='SET_CROSSBOW', attribute="hint", value=globaltext.SET_CROSSBOW_HINT)
objects.set_attribute(object='SET_CROSSBOW', attribute="resourceui", value='RES_ITEM65X32_WEAPON_CROSSBOW')
objects.set_attribute(object='SET_CROSSBOW', attribute="resource3d", value='RES3D_CROSSBOW')
objects.set_attribute(object='SET_CROSSBOW', attribute="value", value=60.00)
objects.set_attribute(object='SET_CROSSBOW', attribute="weight", value=4.0)
objects.set_attribute(object='SET_CROSSBOW', attribute="stacking", value=1)
objects.set_attribute(object='SET_CROSSBOW', attribute="minimale_feuerreichweite", value=0)
objects.set_attribute(object='SET_CROSSBOW', attribute="maximale_feuerreichweite", value=33)
objects.set_attribute(object='SET_CROSSBOW', attribute="salvenlaenge", value=1)
objects.set_attribute(object='SET_CROSSBOW', attribute="feuergeschwindigkeit", value=0.00)
objects.set_attribute(object='SET_CROSSBOW', attribute="genauigkeit", value=1.00)
objects.set_attribute(object='SET_CROSSBOW', attribute="kampfwert_air", value=0.00)
objects.set_attribute(object='SET_CROSSBOW', attribute="kampfwert_armoured", value=150.00)
objects.set_attribute(object='SET_CROSSBOW', attribute="kampfwert_infantry", value=150.00)
objects.set_attribute(object='SET_CROSSBOW', attribute="munitionsarten", value=['SET_AMMOPACK_BOLT'])
objects.set_attribute(object='SET_CROSSBOW', attribute="fire_animation", value=FPA_SNIPER_SINGLE)
objects.set_attribute(object='SET_CROSSBOW', attribute="weapon_type", value="sniper")
objects.set_attribute(object='SET_CROSSBOW', attribute="magazingroesse", value=1.0)
objects.set_attribute(object='SET_CROSSBOW', attribute="hoerweite", value=1.0)
objects.set_attribute(object='SET_CROSSBOW', attribute="schusspausenzeit", value=5.2)
objects.set_attribute(object='SET_CROSSBOW', attribute="genauigkeit_bewegte_ziele", value=0.6)
objects.set_attribute(object='SET_CROSSBOW', attribute="blockadewahrscheinlichkeit", value=5.0)
objects.set_attribute(object='SET_CROSSBOW', attribute="occupied_slots", value=["left_hand","right_hand"])
objects.set_attribute(object='SET_CROSSBOW', attribute="effects", value={
"sound_shot" : "shot_crossbow",
"sound_unload" : "crossbow_discharge",
"sound_reload" : "crossbow_charge"})
objects.set_attribute(object='SET_CROSSBOW', attribute="combine_xp", value=125)
objects.set_attribute(object='SET_CROSSBOW', attribute="item_combination", value={
"difficulty_assemble" : 65,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [
['SET_FLAT_SPRING', 'SET_CLUB', 'SET_LONG_LEATHER_STRING', 'SET_REEL_OF_STEEL_WIRE','SET_KNIFE']]})

Aus einer Blattfeder, einer Holzkeule, einer langen Lederschnur und Stahldraht entsteht mit Hilfe eines Messers nun ab einem Technikwert von 65 eine Armbrust, nebenbei gibt`s für`s erste Mal 125 XP.
Titel: Landminen
Beitrag von: Torka am 07. September 2010, 16:51:14 Uhr
Wie in den "Geschichten aus den Wastelands" schon angekündigt, kann man nun nicht nur die Landminen nutzen, sondern sie auch selbst bauen. Durch das Talent "Sprengstoffe bauen" kann man aus den Bestandteilen: Blechdose, Schwarzpulver, kurze Nägel und einem Zünder die Minen basteln. Dadurch ergeben sich neue taktische Möglichkeiten, wie z.B. eine Minensperre oder ein Hinterhalt.

In der Datei scripts / itemdata / weapons.py einfach folgende Zeilen einfügen:
create_item_type(typeid='SET_LANDMINE')
objects.set_attribute(object='SET_LANDMINE', attribute="name", value=globaltext.SET_LANDMINE_NAME)
objects.set_attribute(object='SET_LANDMINE', attribute="hint", value=globaltext.SET_LANDMINE_HINT)
objects.set_attribute(object='SET_LANDMINE', attribute="resourceui", value='RES_ITEM65X32_EXPLOSIVE_LANDMINE')
objects.set_attribute(object='SET_LANDMINE', attribute="resource3d", value='RES3D_LANDMINE')
objects.set_attribute(object='SET_LANDMINE', attribute="value", value=10.00)
objects.set_attribute(object='SET_LANDMINE', attribute="weight", value=1.1)
objects.set_attribute(object='SET_LANDMINE', attribute="stacking", value=500)
objects.set_attribute(object='SET_LANDMINE', attribute="weapon_type", value="explosiv")
objects.set_attribute(object='SET_LANDMINE', attribute="magazingroesse", value=1.0)
objects.set_attribute(object='SET_LANDMINE', attribute="hoerweite", value=40.0)
objects.set_attribute(object='SET_LANDMINE', attribute="minimale_feuerreichweite", value=0.0)
objects.set_attribute(object='SET_LANDMINE', attribute="maximale_feuerreichweite", value=0.0)
objects.set_attribute(object='SET_LANDMINE', attribute="salvenlaenge", value=1)
objects.set_attribute(object='SET_LANDMINE', attribute="feuergeschwindigkeit", value=0.0)
objects.set_attribute(object='SET_LANDMINE', attribute="bomb_type", value="mine")
objects.set_attribute(object='SET_LANDMINE', attribute="wirkungsbereich", value=15)
objects.set_attribute(object='SET_LANDMINE', attribute="durchschlag", value=200)
objects.set_attribute(object='SET_LANDMINE', attribute="schaden_organisch_min", value=250)
objects.set_attribute(object='SET_LANDMINE', attribute="schaden_organisch_max", value=300)
objects.set_attribute(object='SET_LANDMINE', attribute="schaden_struktur_min", value=50)
objects.set_attribute(object='SET_LANDMINE', attribute="schaden_struktur_max", value=60)
objects.set_attribute(object='SET_LANDMINE', attribute="targets", value=["character", "animal"])
objects.set_attribute(object='SET_LANDMINE', attribute="detection_range", value=4.0)
#objects.set_attribute(object='SET_LANDMINE', attribute="not_tradable", value=True)
objects.set_attribute(object='SET_LANDMINE', attribute="combine_xp", value=100)
objects.set_attribute(object='SET_LANDMINE', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
"assemble_function" : "assemble_explosives",
"combination_list" : [
['SET_TIN_CAN', 'SET_GUN_POWDER', 'SET_SHORT_NAILS', 'SET_FUSE']]})
Titel: Lederwaren
Beitrag von: Torka am 08. September 2010, 00:27:35 Uhr
Falls die Helden in der Ödnis nicht gerade an Bolzen feilen oder mit Minen was in die Luft jagen, können sie sich auch fast friedlich nützlich machen. Mit zunehmenden Survivalskill steigt ja bekanntlich die Jagdausbeute - erst in der Fleischmenge, später kommen Felle, Krallen und Zähne hinzu. Warum sollen diese Rohmaterialien nur für das Kunsthandwerk (Ketten usw.) vorbehalten sein, viel näher liegt doch die Felle zu gerben und Leder für Kleidung und Schuhe herzustellen.

Die erste Stufe vom Fell zum gegerbten Leder schaut im Skript scripts / itemdata / items.py so aus:
create_item_type(typeid='SET_HYENA_PELT')
objects.set_attribute(object='SET_HYENA_PELT', attribute="name", value=globaltext.SET_HYENA_PELT_NAME)
objects.set_attribute(object='SET_HYENA_PELT', attribute="hint", value=globaltext.SET_HYENA_PELT_HINT)
objects.set_attribute(object='SET_HYENA_PELT', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_HYENA_PELT')
objects.set_attribute(object='SET_HYENA_PELT', attribute="resource3d", value='RES3D_HYENA_PELT')
objects.set_attribute(object='SET_HYENA_PELT', attribute="value", value=35.00)
objects.set_attribute(object='SET_HYENA_PELT', attribute="weight", value=4.00)
objects.set_attribute(object='SET_HYENA_PELT', attribute="stacking", value=15)
objects.set_attribute(object='SET_HYENA_PELT', attribute="combine_xp", value=500)
objects.set_attribute(object='SET_HYENA_PELT', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [['SET_KNIFE', 'SET_BEAR_SKIN'],
['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_TIGER_FUR'],
['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_WOLF_PELT'],
['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_HORSE_SKIN'],
                                                        ['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_DEER_SKIN'],
                                                        ['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_ANTELOPE_PELT'],
                                                        ['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_WILD_DOG_PELT'],
                                                        ['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_BISON_SKIN'],
                                                        ['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_PIG_SKIN'],
['SET_KNIFE', 'SET_AMMONIUM_NITRATE', 'SET_SOAP','SET_COW_SKIN']]})

Im Spiel gibt es ein Hyänenfell, da es aber ingame nie Hyänen gab, habe ich mir die Textur für das gegerbte Leder gekrallt und in der  scripts / globaltext / german / german.py den Namen und Hint umgenannt:
add_global_text(id='SET_HYENA_PELT_NAME', text='Gegerbtes Leder')
add_global_text(id='SET_HYENA_PELT_HINT', text='Gegerbtes Leder')

Zum Gerben werden dann noch folgende Zutaten und Werkzeuge gebraucht:
- ein Messer zum Abschaben des Fettes, der Fleischreste und Haare
- das Ammoniumnitrat als Beizmittel
- die Seife zum Säubern
- ein Fell (egal ob Hirsch, Wolf, Bär, Bison, Pferd, Schwein, Wildhund, Puma oder Antilope)

Das nun gegerbte Leder kann nun weiter zu Lederkleidung und Schuhen verarbeitet werden. Doch für die Herstellung wären auch Lederschnüre ganz hilfreich.

Aus den Pfoten oder bekrallten Vorderläufen der Raubtiere könnte man die Sehnen oder die Haut zu kurzen und langen Lederschnüren verarbeiten.
Die beiden Skripte in scripts / itemdata / items.py wie beschrieben verlängern.

Lange Schnüre aus den Pfoten von Bären, Berglöwen oder Wölfen:
create_item_type(typeid='SET_LONG_LEATHER_STRING')
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="name", value=globaltext.SET_LONG_LEATHER_STRING_NAME)
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="hint", value=globaltext.SET_LONG_LEATHER_STRING_HINT)
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_LONG_LEATHER_STRING')
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="resource3d", value='RES3D_LONG_LEATHER_STRING')
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="value", value=1.0)
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="weight", value=0.3)
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="stacking", value=100)
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="combine_xp", value=50)
objects.set_attribute(object='SET_LONG_LEATHER_STRING', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [['SET_KNIFE', 'SET_BEAR_CLAW'],
['SET_KNIFE', 'SET_TIGER_CLAW'],
['SET_KNIFE', 'SET_WOLF_CLAW']]})

Kurze Schnüre aus den Pfoten von Wildhunden:
create_item_type(typeid='SET_SHORT_LEATHER_STRING')
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="name", value=globaltext.SET_SHORT_LEATHER_STRING_NAME)
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="hint", value=globaltext.SET_SHORT_LEATHER_STRING_HINT)
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_SHORT_LEATHER_STRING')
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="resource3d", value='RES3D_SHORT_LEATHER_STRING')
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="value", value=1.0)
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="weight", value=0.01)
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="stacking", value=100)
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="combine_xp", value=50)
objects.set_attribute(object='SET_SHORT_LEATHER_STRING', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [['SET_KNIFE', 'SET_WILD_DOG_CLAW']]})

Die Namen und Hints werden in scripts / globaltext / german / german.py wie folgend verändert:
add_global_text(id='SET_BEAR_CLAW_NAME', text='Bärenpfoten mit Krallen')
add_global_text(id='SET_BEAR_CLAW_HINT', text='Bärenpfoten mit Krallen')
add_global_text(id='SET_TIGER_CLAW_NAME', text='Berglöwenpfoten mit Krallen')
add_global_text(id='SET_TIGER_CLAW_HINT', text='Berglöwenpfoten mit Krallen')
add_global_text(id='SET_WOLF_CLAW_NAME', text='Wolfspfoten mit Krallen')
add_global_text(id='SET_WOLF_CLAW_HINT', text='Wolfspfoten mit Krallen')
add_global_text(id='SET_WILD_DOG_CLAW_NAME', text='Wildhundpfoten mit Krallen')
add_global_text(id='SET_WILD_DOG_CLAW_HINT', text='Wildhundpfoten mit Krallen')


Titel: Lederkleidung
Beitrag von: Torka am 09. September 2010, 16:37:43 Uhr
Gegerbtes Leder + Lange Lederschnur + Messer  =  Dünne Lederkleidung
Das Skript kann in scripts / itemdata / items.py wie folgt verändert werden:
create_item_type(typeid='SET_INTRO_CLOTHES')
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="name", value=globaltext.SET_INTRO_CLOTHES_NAME)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="hint", value=globaltext.SET_INTRO_CLOTHES_HINT)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_INTRO_CLOTHES')
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="resource3d", value='RES3D_INTRO_CLOTHES')
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="value", value=25.00)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="weight", value=2.50)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="stacking", value=6)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="armor", value=1)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="occupied_slots", value=["clothes"])
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="not_tradable", value=True)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="combine_xp", value=50)
objects.set_attribute(object='SET_INTRO_CLOTHES', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [['SET_KNIFE', 'SET_HYENA_PELT', 'SET_LONG_LEATHER_STRING']]})


Gegerbtes Leder + Lange Lederschnur + Nieten + Messer  = Lederkleidung
Das Skript kann in scripts / itemdata / items.py wie folgt verändert werden:
create_item_type(typeid='SET_LEATHER_CLOTHES')
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="name", value=globaltext.SET_LEATHER_CLOTHES_NAME)
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="hint", value=globaltext.SET_LEATHER_CLOTHES_HINT)
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_LEATHER_CLOTHES')
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="resource3d", value='RES3D_LEATHER_CLOTHES')
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="value", value=15.00)
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="weight", value=2.0)
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="stacking", value=6)
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="armor", value=4)
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="occupied_slots", value=["clothes"])
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="combine_xp", value=50)
objects.set_attribute(object='SET_LEATHER_CLOTHES', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [['SET_KNIFE', 'SET_HYENA_PELT', 'SET_LONG_LEATHER_STRING', 'SET_RIVETS']]})


Gegerbtes Leder + Kurze Lederschnur + Messer  =  Lederhandschuhe
Das Skript kann in scripts / itemdata / items.py wie folgt verändert werden:
create_item_type(typeid='SET_LEATHER_GLOVES')
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="name", value=globaltext.SET_LEATHER_GLOVES_NAME)
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="hint", value=globaltext.SET_LEATHER_GLOVES_HINT)
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_LEATHER_GLOVES')
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="resource3d", value='RES3D_LEATHER_GLOVES')
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="value", value=15.00)
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="weight", value=0.20)
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="stacking", value=6)
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="armor", value=1)
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="occupied_slots", value=["gloves"])
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="combine_xp", value=25)
objects.set_attribute(object='SET_LEATHER_GLOVES', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [['SET_KNIFE', 'SET_HYENA_PELT', 'SET_SHORT_LEATHER_STRING']]})


Gegerbtes Leder + Kurze Lederschnur + Nieten + Messer  =  Lederschutzkappe
Das Skript kann in scripts / itemdata / items.py wie folgt verändert werden:
create_item_type(typeid='SET_LEATHER_CAP')
objects.set_attribute(object='SET_LEATHER_CAP', attribute="name", value=globaltext.SET_LEATHER_CAP_NAME)
objects.set_attribute(object='SET_LEATHER_CAP', attribute="hint", value=globaltext.SET_LEATHER_CAP_HINT)
objects.set_attribute(object='SET_LEATHER_CAP', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_LEATHER_CAP')
objects.set_attribute(object='SET_LEATHER_CAP', attribute="resource3d", value='RES3D_LEATHER_CAP')
objects.set_attribute(object='SET_LEATHER_CAP', attribute="value", value=7.00)
objects.set_attribute(object='SET_LEATHER_CAP', attribute="weight", value=0.40)
objects.set_attribute(object='SET_LEATHER_CAP', attribute="stacking", value=6)
objects.set_attribute(object='SET_LEATHER_CAP', attribute="armor", value=2)
objects.set_attribute(object='SET_LEATHER_CAP', attribute="occupied_slots", value=["helm"])
objects.set_attribute(object='SET_LEATHER_CAP', attribute="combine_xp", value=30)
objects.set_attribute(object='SET_LEATHER_CAP', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_parlor_game",
"combination_list" : [['SET_KNIFE', 'SET_HYENA_PELT', 'SET_SHORT_LEATHER_STRING', 'SET_RIVETS']]})


Gegerbtes Leder + Kurze Lederschnur + Nieten + Hammer  =  Lederstiefel
Das Skript kann in scripts / itemdata / items.py wie folgt verändert werden:
create_item_type(typeid='SET_LEATHER_BOOTS')
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="name", value=globaltext.SET_LEATHER_BOOTS_NAME)
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="hint", value=globaltext.SET_LEATHER_BOOTS_HINT)
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_LEATHER_BOOTS')
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="resource3d", value='RES3D_LEATHER_BOOTS')
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="value", value=25.00)
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="weight", value=1.5)
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="stacking", value=6)
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="armor", value=2)
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="occupied_slots", value=["boots"])
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="combine_xp", value=60)
objects.set_attribute(object='SET_LEATHER_BOOTS', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_plate_armor",
"combination_list" : [['SET_SLEDGE_HAMMER', 'SET_HYENA_PELT', 'SET_SHORT_LEATHER_STRING', 'SET_RIVETS']]})


Gegerbtes Leder + Kurze Lederschnur + Nieten + Stahlplatten + Hammer  =  Stahlkappenstiefel
Das Skript kann in scripts / itemdata / items.py wie folgt verändert werden:
create_item_type(typeid='SET_STEEL_CLAD_BOOTS')
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="name", value=globaltext.SET_STEEL_CLAD_BOOTS_NAME)
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="hint", value=globaltext.SET_STEEL_CLAD_BOOTS_HINT)
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_STEEL_CLAD_BOOTS')
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="resource3d", value='RES3D_STEEL_CLAD_BOOTS')
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="value", value=50.00)
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="weight", value=2.00)
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="stacking", value=6)
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="armor", value=4)
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="occupied_slots", value=["boots"])
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="combine_xp", value=75)
objects.set_attribute(object='SET_STEEL_CLAD_BOOTS', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_plate_armor",
"combination_list" : [['SET_SLEDGE_HAMMER', 'SET_HYENA_PELT', 'SET_SHORT_LEATHER_STRING', 'SET_RIVETS', 'SET_STEEL_PLATES']]})


Auf diesen Skripten aufbauend kann man dann folgende Ideen umsetzten:

Eisenplatten + Hammer  =  einfacher Helm
Stahlplatten + Hammer  =  Stahlhelm

Titel: Re: Mod-Tagebuch
Beitrag von: le Chew am 09. September 2010, 20:15:13 Uhr
Hehe, er wütet wieder  :D

Da sind schicke Sachen dabei - ich überlege gerade ob 2 Dinge sinnvoll wären:

1. Ein "Übersichtsthread" mit Linklisten a la "Dünne Lederrüstung" -> Link zum Codeschnippsel
2. Ein (privates) SVN-Repository der Original-"The Fall"-Pythonscripte mit dem wir dann diffs (http://de.wikipedia.org/wiki/Diff) anfertigen - so könnte jeder seine lokalen Scripte ganz einfach patchen und hätte deine Änderungen :)

(Privates SVN deswegen weil ich denke ein Öffentliches würde evtl. Probleme machen wegen Lizenzen etc...)

Weiter so, du aktivstes deutsches The-Fall-Modding-"Team" du  :s000:

cheers,
chewie
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 09. September 2010, 20:37:15 Uhr
Danke chewie  :D

Zitat
1. Ein "Übersichtsthread" mit Linklisten a la "Dünne Lederrüstung" -> Link zum Codeschnippsel
2. Ein (privates) SVN-Repository der Original-"The Fall"-Pythonscripte mit dem wir dann diffs anfertigen - so könnte jeder seine lokalen Scripte ganz einfach patchen und hätte deine Änderungen

Die Itemliste hat hat sich gerade ein wenig verselbständigt und die Übersicht leidet - sollten eigentlich nur Beispiele werden *g* - aber der Ideenfluß war zu schnell  ;D.
Wie könnte so ein SVN ausschauen, habe da leider gar keinen Plan von, außer das die Skriptteile miteinander verglichen werden.
Wenn die Zeit und Motivation reichen, soll ja aus der Iddensammlung des Modtagebuches eine kleine Mod entstehen - sowas wie "TF-Extended" - mal schauen.   

Über Urheberrechte habe ich mir auch schon Gedanken gemacht, deswegen stehen als Quellen immer die Skriptpfade da. Da es ja auch Modtool und den Editor + die Anleitungen zum Modden gibt hoffe ich mal nicht Probleme zu bekommen. Anderenfalls werden sie Skriptteile halt wieder entfernt. Ich habe auch schon zwei Emails an Silver Style geschrieben, leider haben sie noch nicht geantwortet.
Titel: Werkzeug selbst definieren
Beitrag von: Torka am 14. September 2010, 00:11:39 Uhr
Wie man selbst Werkzeuge definiert, zeigt folgendes Skript (z.B.: Zange oder Hammer, welche nach dem Benutzen wieder im Inventar zur Verfügung stehen). Im Beispiel wird unter scripts / combos.py  eine Backform für das spätere Brotbacken  :D beschrieben:

def assemble_cake_tin(character_id, items, item):
"""Creates cake tin.

Parameters:
        character_id - Id of owner of items.
        items        - List of id of items to combine.
        item         - The item_type of new item.
"""
for act_item in items:
if (objects.get_attribute(act_item, "typeid")!="SET_CAKE_TIN"):
objects.remove_item_from_inventory(character_id, act_item)


objects.create_item_in_inventory(object=character_id, equipment=item)
return True

In scripts / itemdata / items.py ist dann unter dem Brot diese Funktion wieder zu finden:
create_item_type(typeid='SET_BREAD')
objects.set_attribute(object='SET_BREAD', attribute="name", value=globaltext.SET_BREAD_NAME)
objects.set_attribute(object='SET_BREAD', attribute="hint", value=globaltext.SET_BREAD_HINT)
objects.set_attribute(object='SET_BREAD', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_BREAD')
objects.set_attribute(object='SET_BREAD', attribute="resource3d", value='RES3D_BREAD')
objects.set_attribute(object='SET_BREAD', attribute="value", value=4.0)
objects.set_attribute(object='SET_BREAD', attribute="weight", value=0.5)
objects.set_attribute(object='SET_BREAD', attribute="stacking", value=500)
objects.set_attribute(object='SET_BREAD', attribute="le_recovery", value=8)
objects.set_attribute(object='SET_BREAD', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
        "assemble_function" : "assemble_cake_tin",
"combination_list" : [['SET_CAKE_TIN', 'SET_SUGAR','SET_WATER_SKIN']]})

Nun ist es möglich aus Wasser, Mehl (ursprünglich die orginale Zuckertüte) und der Backform (eigentlich die Kuchenform) das erste eigene Brot zu backen.  ;)

Alles gut und schön, an Wasser im Ödland zu kommen ist ja schon gut möglich, doch wo findet man Mehl?

Option A: Wo eine Windmühle steht, könnte der Müller nicht weit sein und wo Säcke liegen, könnte auch Mehl drin sein  ;D. Es wird also auf einigen Karten hinterlegt.

Option B:Selbst ist der Wasteländer, naja, fast. Da wo es Kornfelder gibt (manchmal schon abgeerntet mit Stroh) werden Roggenbündel zu finden sein, aus denen Mehl zu gewinnen ist.

Das Skript für die Verarbeitung von Rogenbündeln zu Mehl. Es ist zwar etwas mühselig mit einem Hammer die Körner zu zerstampfen, aber Not macht erfinderisch:
create_item_type(typeid='SET_SUGAR')
objects.set_attribute(object='SET_SUGAR', attribute="name", value=globaltext.SET_SUGAR_NAME)
objects.set_attribute(object='SET_SUGAR', attribute="hint", value=globaltext.SET_SUGAR_HINT)
objects.set_attribute(object='SET_SUGAR', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_SUGAR')
objects.set_attribute(object='SET_SUGAR', attribute="resource3d", value='RES3D_SUGAR')
objects.set_attribute(object='SET_SUGAR', attribute="value", value=2.0)
objects.set_attribute(object='SET_SUGAR', attribute="weight", value=0.5)
objects.set_attribute(object='SET_SUGAR', attribute="stacking", value=100)
objects.set_attribute(object='SET_SUGAR', attribute="combine_xp", value=100)
objects.set_attribute(object='SET_SUGAR', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
"assemble_function" : "assemble_plate_armor",
"combination_list" : [
['SET_BUNCH_OF_RYE_PLANTS','SET_SLEDGE_HAMMER']]})
Titel: Objekte des Editors als Inventaritems im Spiel definieren
Beitrag von: Torka am 12. Oktober 2010, 11:09:40 Uhr
Seit einiger Zeit habe ich damit experimentiert Gegenstände des Editors in nutzbare Spielobjekte um zu wandeln. Als Beispiel möchte ich das an Pilzen dokumentieren:

1. Der Name des neuen Items lautet MUSHROOMS_1 und wird wie bisher gewohnt als Objekt in scripts / itemdata / items.py  definiert:
                 create_item_type(typeid='SET_MUSHROOMS_1')
objects.set_attribute(object='SET_MUSHROOMS_1', attribute="name", value=globaltext.SET_MUSHROOMS_1_NAME)
objects.set_attribute(object='SET_MUSHROOMS_1', attribute="hint", value=globaltext.SET_MUSHROOMS_1_HINT)
objects.set_attribute(object='SET_MUSHROOMS_1', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_MUSHROOMS_1')
objects.set_attribute(object='SET_MUSHROOMS_1', attribute="resource3d", value='RES3D_TRES_OBJECTS_BUILDING_MUSHROOMS_1')
objects.set_attribute(object='SET_MUSHROOMS_1', attribute="value", value=2.0)
objects.set_attribute(object='SET_MUSHROOMS_1', attribute="weight", value=0.2)
objects.set_attribute(object='SET_MUSHROOMS_1', attribute="stacking", value=10)



2. Der Namen und Hint der Pilze im Spiel werden in scripts / globaltext / german / german.py definiert:
                add_global_text(id='SET_MUSHROOMS_1_NAME', text='Champignons')
add_global_text(id='SET_MUSHROOMS_1_HINT', text='Champignons')
Dem geübten Leser wird jetzt auffallen, das es sich um Champignons handeln wird.
 


3. Das Inventarbild wird in der Zeile  objects.set_attribute(object='SET_MUSHROOMS_1', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_MUSHROOMS_1' ) abgefragt.

Dieses gibt es in den GUI-Daten noch nicht und muss verankert werden. Dem Spiel sind im Modordner Tools beigefügt, eines davon ist das Tool guiresourcedata.exe. Dieses öffnen.
Es hat Vorteile schon vorher zu wissen, wo sich denn die GUI-Daten der Items verstecken. Häufig halten sie sich in The Fall / data / guidata / fall_items.gui auf  ;).
Die Datei öffnen und unter "Ressourcen" auf der linken Seite erscheint eine lange Liste der definierten Inventarbilder der Objekte - Pilze sind da noch nicht zu finden, müssen noch "wachsen".
In der Datenbank einfach einen neuen Eintrag erstellen (am oberen linken Rand erstes Quadratsymbol "Neue Ressource" anklicken- schau auch in die Infozeile unten)
Die Infostruktur kann man eigentlich recht analog zu den anderen Objekten erstellen. Zu jedem Eintrag auf der linken Seite in der Datenbank stehen verschiedene Informationen auf der rechten Seite.
                           
     a. die Id: von 400000 bis 400545  - ich habe einfach die 1 genommen, da es mein erstes Objekt ist

     b. Bezeichner: RES_ITEM65X32_MISCITEM_MUSHROOMS_1  - wichtig, das ist der Name auf den sich weiter oben hier in der Objektdefinition bezogen wird

     c. Es wird ein "Neuer Bereich" definiert und es öffnet sich ein Fenster, in welchem man folgende Werte einträgt:

                   Nummer: 0  
                   Koordinaten des Inventarbildes auf einem PNG-Bild:  TX1:0 TY1:0 und TX2:65 TX2: 32
                   Breite: 32
                   Höhe:  65  
                   Offset XY: 0
                   Streckung XY: 1
                   Pfad: gui\gui_mission\items\b_mushrooms1.png Dieser Pfad muss auch im Eintrag der Texturbibliothek stehen.

          Am Ende des Pfades gui \ gui-mission\items\ verstecken sich insgesamt 26 Bilder im DDS Format. Jedes Bild enthält mehrere Inventarbilder,
          welches man sich mit dem Programm dxtbmpx.EXE angesehen kann und so auch eine Vorstellung bekommt, was sich  z.B. hinter den Koordinaten verbirgt.
          Im Fall der Pilze ist das aber eh rein theoretisch, da ein Inventarbild noch gar nicht existiert. 
          Es gibt im TF-Editor Pilzbilder, welche man im Ordner  The Fall / gui / preview / buildings / b_mushrooms1.png.dds finden kann.
          Entweder man legt den Pfad dahin oder man kopiert das Bild nach gui \ gui-mission\items, habe der Übersicht halber letzteres getan.

      d. Nun muss das Bild nur noch in der Texturdatenbank der GUIResourceData eingebunden werden. Dazu klickt man in der Symbolleiste den Button Texturdatenbank an und es öffnet sich das Fenster der Texturbibliothek.
          Ein ähnliches Spiel wie zuvor. Ein neuer Eintrag wird erstellt und folgende Werte definiert:

                    Id: 1
                    Pfad: gui\gui_mission\items\b_mushrooms1.png (wichtig, das Bild ist im Ordner als .dds abgelegt, es wird aber auf das .png verwiesen!), Pfad aus c muss identisch sein!
                    Format: PNG
                    Höhe: 64
                    Breite: 32 (wichtig, die anderen Bilder sind ja 256x256, da sie mehrere Inventarbilder enthalten, dieses ist nur ein einzelnes deswegen 64x32)
                    Typ: Transparent
         
        Jetzt sollte das Bild verankert sein und im Spielerinventar sichtbar sichtbar sein.


4. Als nächstes wird das 3d-Modell in der Zeile objects.set_attribute(object='SET_MUSHROOMS_1', attribute="resource3d", value='RES3D_TRES_OBJECTS_BUILDING_MUSHROOMS_1') abgefragt.

In der Datei scripts / objectdata / items.py  werden die 3d-Modelle der Items geladen. Da es die Pilze aber nur im Editor gibt, müssen sie unter 'RES3D_TRES_OBJECTS_BUILDING_MUSHROOMS_1' durch folgende Zeilen analog zu den anderen hinzugefügt werden:
add_3d_item_data(typeid='RES3D_TRES_OBJECTS_BUILDING_MUSHROOMS_1')
objects.set_attribute(object='RES3D_TRES_OBJECTS_BUILDING_MUSHROOMS_1', attribute="diff3d_file", value="objects\\additionals\\thefall\\misc\\mushrooms1.diff3d")
objects.set_attribute(object='RES3D_TRES_OBJECTS_BUILDING_MUSHROOMS_1', attribute="states", value=['TRES_OBJECTS_BUILDING_MUSHROOMS_1'])
                       
Die 3d-Datei der Pilze im Editor findet sich ursprünglich unter The Fall / objects / buildings / mushrooms / mushrooms1.diff3d . Entweder man verlinkt direkt oder man verschiebt eine
Kopie nach The Fall / objects / additionals / thefall / misc / mushrooms1.diff3d zu den 3d-Modellen der anderen Items.


Wenn soweit alles richtig ausgeführt und alles gespeichert (Backup gemacht ?) wurde, kann man nun Pilze sammeln.  #yay (diese müßten natürlich noch in den Zonenskripten analog zu den Kräutern plaziert werden)

(http://www.image-share.eu/image/330784-Pilze.png) (http://www.image-share.eu/share/330784-Pilze.png)
Titel: Baustelle
Beitrag von: Torka am 13. Oktober 2010, 04:56:29 Uhr
 #radi2 Baustelle  #radi2
     :coffee  :para
objects.set_attribute("GANGER_1","foes",["UISPIELER"])

zone_2 / npc.py
def initNPCS():
#RATSKULL_SQUAD_LEADER
system.create_character(
id="RATSKULL_SQUAD_LEADER",
gender="male",
party="RATSKULLS",
x=432.83,
y=668.85,
direction=0,
name=globaltext.NAME_RATSKULL,
resourceui="")

  objects.set_attribute("RATSKULL_SQUAD_LEADER", "faction", "RAT_SKULLS")
objects.set_attribute("RATSKULL_SQUAD_LEADER", "level", 3 )
objects.set_attributes("RATSKULL_SQUAD_LEADER",
model="low",
gender="male", # "female"
skin="white", # "black"
clothes="ratskull_bulletproof", # "ratskull",
face="ratskull_member_0012")
character.update_appearance("RATSKULL_SQUAD_LEADER")
character.scale("RATSKULL_SQUAD_LEADER",1.82)

zone_2 / const.py
data().ratskulls_david = ["RATSKULL_SQUAD_LEADER", "RATSKULL_002", "RATSKULL_017"]
data().ratskulls_camp = ["RATSKULL_006", "RATSKULL_007"]
data().ratskulls_village = ["RATSKULL_003","RATSKULL_004","RATSKULL_010", "RATSKULL_005","RATSKULL_011","RATSKULL_012", "RATSKULL_013","RATSKULL_014","RATSKULL_015", "RATSKULL_016"]
data().ratskulls = data().ratskulls_david + data().ratskulls_camp + data().ratskulls_village

zone_2 / shedules.py
"RATSKULL_011": ({
S_CONDITION:lambda:data().RatskullsKonversationAktiv,
# Konversation
"01:30:00":{
S_LOCATION : 1,
S_START  :(goto(638.6,560.3)),
S_LOOP :(conversate(["RATSKULL_012","RATSKULL_013","RATSKULL_014"])),
},
# Sitzen, warten
"11:25:00":{
S_LOCATION : 2,
S_START  :(sit_down_on_ground()),
S_LOOP :(sit_on_ground()),
},
},{
S_CONDITION: lambda: data().ratskulls_emergency_schedule,
"00:00:00" : {
S_START : [goto(638.6,560.5)],
S_LOOP  : []
}
}),

"RATSKULL_012": ({
S_CONDITION:lambda:data().RatskullsKonversationAktiv,
# Konversation
"00:15:00":{
S_LOCATION : 1,
S_START  :(goto(637.1,560.5)),
S_LOOP :(conversate(["RATSKULL_011","RATSKULL_013","RATSKULL_014"])),
},
# Sitzen, warten
"10:04:00":{
S_LOCATION : 2,
S_START  :(sit_down_on_ground()),
S_LOOP :(sit_on_ground()),
},
},{
S_CONDITION: lambda: data().ratskulls_emergency_schedule,
"00:00:00" : {
S_START : [goto(637.1,560.5)],
S_LOOP  : []
}
}),

"RATSKULL_013": ({
S_CONDITION:lambda:data().RatskullsKonversationAktiv,
# Konversation
"02:01:00":{
S_LOCATION : 1,
S_START  :(goto(638.11,559.37)),
S_LOOP :(conversate(["RATSKULL_012","RATSKULL_011","RATSKULL_014"])),
},
# Sitzen, warten
"13:45:00":{
S_LOCATION : 2,
S_START  :(sit_down_on_ground()),
S_LOOP :(sit_on_ground()),
},
},{
S_CONDITION: lambda: data().ratskulls_emergency_schedule,
"00:00:00" : {
S_START : [goto(638.1,559.4)],
S_LOOP  : []
}
}),

"RATSKULL_014": ({
S_CONDITION:lambda:data().RatskullsKonversationAktiv,
# Konversation
"01:20:00":{
S_LOCATION : 1,
S_START  :(goto(636.0,559.8)),
S_LOOP :(conversate(["RATSKULL_012","RATSKULL_013","RATSKULL_011"])),
},
# Sitzen, warten
"15:10:00":{
S_LOCATION : 2,
S_START  :(sit_down_on_ground()),
S_LOOP :(sit_on_ground()),
},
},{
S_CONDITION: lambda: data().ratskulls_emergency_schedule,
"00:00:00" : {
S_START : [goto(636,559.8)],
S_LOOP  : []
}
}),

Na lol,  #batsch da habe ich aus Versehen auf den roten Knopf gedrückt  :atomrofl7ep5rb:

 :smug: Dekontamination fast abgeschlossen, allgemeine Aufräumarbeiten...  #knirsch  ...  >:D ....  ich könnt  #kotzen# ... Kaffeepause  :coffee
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 17. Oktober 2010, 12:51:54 Uhr
Die Pilze sehen gut aus, aber ich wage zu bezweifeln, dass in dem Teil der Welt Champignons wachsen. :p
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 18. Oktober 2010, 13:28:05 Uhr
Die Pilze sehen gut aus, aber ich wage zu bezweifeln, dass in dem Teil der Welt Champignons wachsen. :p

Die Pilze sind eigentlich die Modelle aus den Pilzfarmen der Höhle. Die GNO-Karte ist nur der Teststandort für die erstellten Objekte  ;). Wenn es denn mal zur Modifikation kommen sollte, werden sie sicher in den Pilzfarmen der Schatten zu finden sein oder vereinzelt in tiefen, schattigen Tälern in der Nähe einer Quelle.
Ob Champignon- oder Egerlingsartige (Agaricaceae) auch im Südwesten der USA vorkommen habe ich mich auch gefragt und war recht erstaunt über die Antworten.
Zitat
Podaxis pistillaris ist z.B. eine Pilzart aus der Familie der Champignonartigen, welche auch in der Sonorawüste wächst. Der Pilz ist in den Halbwüsten Afrikas, Asiens, Australiens und Amerikas zwischen 40 Grad nördlicher und 40 Grad südlicher Breite zu finden. Die meisten Entdeckungen wurden in Regionen mit langen Trockenzeiten gemacht. Der Pilz wächst am schnellsten bei Temperaturen um 40 Grad Celsius. Bis etwa 20 und ab 50 Grad Celsius kann er nicht wachsen.
Den dramatischen Klimaveränderungen im Szenario des Spiels geschuldet werden die Pilze aber sehr untergeordnet und eher seltener auf den Karten zu finden sein. Vielleicht wird man Handel in den Pilzfarmen betreiben können oder durch aktive Mitarbeit (Bewäsern, Düngen) könnte es möglich sein selbst Pilze zu züchten.

Quellen:
http://www.forestryimages.org/browse/detail.cfm?imgnum=1570702
http://de.wikipedia.org/wiki/Podaxis_pistillaris
http://www.arizonensis.org/sonoran/fieldguide/podaxis_pistillaris.html
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 15. April 2011, 12:26:05 Uhr
Leider komme ich nur noch unregelmäßig zum modifizieren. Der neue Job im RL ist doch arg zeitfressend  >:(. Mein Rechner hat nach 6 Jahren auch leider den Geist aufgegeben und es bleibt nur noch eine Datensicherung übrig - aber Ostern wird auch eine neue Rechnergeneration auferstehen.  :D

Wenn es machbar ist, wird es auch hier wieder weiter gehen....
Titel: Re: Mod-Tagebuch
Beitrag von: Nephilim am 07. Februar 2012, 19:44:50 Uhr
Hi, ich bin neu hier und leidenschaftlicher TF Spieler. Habe durch Zufall dieses Forum entdeckt. Leider kenne ich mich nicht so gut aus und würde gerne wissen, wie ich in diese unten beschriebene Datei komme.
Wenn ich den Ordner "Scripts" öffnen will, bekomme ich nur Hieroglyphen angezeigt. Was für ein Programm muss ich zum öffnen verwenden?  Zur Verfügung stehen "Editor" oder "Word Pad".


Option C

In der Geschichte der ganzen Patchorgie dieses Spiels habe ich gelesen, dass das Stapeln von Objekten (Munition, Nahrungsmittel, Medipacks) nicht so richtig möglich war. Ab irgendeiner Patchversion hatten die Entwickler aber eine "Stapelbarkeit" eingebaut.

In der Datei scripts / itemdata / items.py stehen die Eigenschaften der Gegenstände:
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 08. Februar 2012, 17:26:49 Uhr
Hi Nephilim,

willkommen  :D. Schau bitte mal in den dritten Post dieses Themas. Du brauchst einen Python-Skripteditor um die Datei zu öffnen, wahlweise habe ich den  Wing IDE 101genommen. Es gibt bestimmt schon eine neuere Version. Ist am Anfang nicht ganz einfach da herein zu kommen und du brauchst ein wenig Geduld.

"Die Python-Skripte waren mir erst ein vollkommenes Rätsel - diese kann man mit dem Texteditor öffnen und man wird von eine Zeilenflut erschlagen. Hmm, habe dann einen Python-Skripteditor namens  Wing IDE 101 3.2 gefunden und mit jenem sehen die PY-Dateien schon wesentlicher benutzerfreundlich, aber immer noch rätselhaft aus (ist halt mein erster Kontakt mit Python)."

Titel: Re: Mod-Tagebuch
Beitrag von: Loprema am 16. Mai 2012, 15:57:14 Uhr
hallo leute,
ich habe auch zwei kleine fragen.

1) in diesem thread wurde ja beschrieben wie man ein fahrzeug in das spiel einbindet. das alles ist sogar für mich verständlich beschrieben und ich konnte die zusätzlichen befehlszeilen auch ohne probleme an die richtige stelle hinein kopieren. nur leider ist das fahrzeug nicht erschienen. da es sich ja nur um zwei zeilen handelt habe ich diese dann einfach noch einmal in der befehlszeile die man durch f11 öffnen kann eingegeben und promt ist der humvee da. wo könnte da mein fehler liegen?

ach ja, es ist sicherlich ein anfänger fehler, da ich mich noch nie mit modding beschäftigt habe

2) kennt jemand ein (möglichst kostenloses) programm mit dem man dif3d dateien öffnen kann? nach möglichkeit mit downloadlink

vielen dank schon einmal für eure mühen und zum abschluss möchte ich noch sagen das das ein gelungendes forum ist ;-)
Titel: Re: Mod-Tagebuch
Beitrag von: Loprema am 19. Mai 2012, 16:30:59 Uhr
hallo noch einmal

die erste meiner fragen konnte ich inzwischen selber beantworten. nur bei der zweiten frage bin ich noch auf keine lösung gekommen. da ich mein traffic volumen inzwischen aufgebraucht habe und nur noch mit gprs geschwindigkeit ins netz komme wird das wohl auch noch eine weile auf sich warten lassen.

desweiteren möchte ich mich aber noch entschuldigen das ich gleich bei meinem ersten post nur fragen gestellt habe. aller anfang ist halt schwehr und es ist auch nicht leicht sich in eine schon so viele jahre existierende gruppe einzufinden. sollte sich jemand noch daran erinnern können wie man das aussehen von gegenständen ändern kann wäre ich sehr dankbar für die hilfe.
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 19. Mai 2012, 17:24:17 Uhr
Das Problem ist eher, dass sich hier kaum jemand mit The Fall auskennt (und gleichzeitig aktiv ist). Zu den Modellen: Existierende können meines Wissens nach gar nicht editiert werden. Zumindest definitiv nicht mit Freeware-Programmen. Im The Fall Modkit damals gab es aber eine Waffe als Vorlage, die dann zum Erstellen von neuen Modellen benutzt werden konnte (so habe ich damals auch meine Mod gemacht). Abgesehen davon... keine Ahnung.
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 22. Mai 2012, 18:11:32 Uhr
Hallo Loprema,

willkommen. Will mal schauen was sich machen laesst. Bin nur gerade nicht auf dem Kontinent. Bin naechsten Monat wieder da.

Titel: Re: Mod-Tagebuch
Beitrag von: Loprema am 28. Mai 2012, 08:25:08 Uhr
Vielen Dank erst einmal für eure Antworten.

@Lexx: Da liegt ja mein Problem. Ich habe noch nicht herausgefunden mit welchem Programm ich die Datei bearbeiten kann.

@Tokra: Ich habe Zeit und freue mich jetzt schon auf mögliche Ergebnisse
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 28. Mai 2012, 08:42:22 Uhr
3D Studio Max. Ich kenne keine Freeware Programme, die das können.
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 30. Juni 2012, 13:16:39 Uhr
@ Loprema: kenne auch kein anderes Freeware Programm als 3D Studio Max. Habe damit persönlich aber auch noch nicht gearbeitet. Im Editor von TF gibt es ein paar Geggenstände welche nicht im Spiel auftauchen, diese könnte man noch einbauen. Habe damals mit den Pilzen experimentiert und den Minen. Ich glaub Lexx hat den einen Texturenmod für das Gewehr erstellt. Ganz neue Objekte hineinzusetzten liegt außerhalb meines Wissens.
Titel: Re: Mod-Tagebuch
Beitrag von: Loprema am 04. Juli 2012, 08:19:58 Uhr
Erst einmal vielen Dank für die Infos.
3d Max ist mir dann doch ein klein wenig zu teuer. Schade das mein erster Modding versuch gleich so daneben ging.
The Fall ist halt das "Modernste" Spiel das mein Rechner schafft. Vielleicht sollte ich mir doch mal einen neuen PC gönnen.
Titel: Re: Mod-Tagebuch
Beitrag von: Lexx am 04. Juli 2012, 09:26:39 Uhr
Naja, du kannst immer noch Zeug mit dem Map Editor machen und Scripte schreiben, etc.
Titel: Re: Mod-Tagebuch
Beitrag von: TheFall am 22. September 2012, 11:22:17 Uhr
Hey Leute,

ich bin ja hellauf begeistert von den Möglichkeiten die über diese Python-skripte möglich sind und ich kann den Enthusiasmus den hier Torka bewiesen hat nachvollziehen, nur....was muß ich machen um diese Änderung in den Skripten auch zum Laufen zu bringen??

Also Chronologisch hab ich folgendes gemacht:

- hab geschaut daß ich 7zip und Wing IDE aufm Rechner hab
- scripts.ubn und die anderen hab ich auch gefunden und selbige mit 7zip entpackt
- nun mit Wing IDE dranrumgeschraubt, stacking, diverses an den Waffen, Kofferraumgröße, Spritverbrauch, etc. was sich halt so als nervig  erwiesen hat
- die Ordner mit 7zip in ne *.zip zurückverwandelt und in *.ubn umbenannt und die Originale damit überschrieben
- neues Spiel gestartet.......
- Spiel läuft soweit ohne Probleme, nach n paar Stunden keine Abstürze, keine neuen Bugs etc. nur eins stört mich irgendwie..........
- es sind nirgendwo Änderungen ersichtlich hinsichtlich Stacking, Wasserreichtum, Waffen etc... also es ist nichts passiert  ???

WASN NU ?
was hab ich falsch gemacht, irgenwas übersehen?
Torka irgendne Idee wos hängen könnte? und wo nimmt sich das Programm die originalen Daten her?

Danke schonmal im Vorraus!

Titel: Re: Mod-Tagebuch
Beitrag von: TheFall am 23. September 2012, 11:45:03 Uhr
Warum kann ich meine Beiträge nicht editieren?

Naja..hab mich heut nochmal drangesetzt und festgestellt daß wohl die Original *.ubn doch nicht überschrieben wurden, warum auch immer.
Also hab ich die Dateien direkt gelöscht und die Veränderten reinkopiert...und siehe da das Programm greift drauf zu aber nicht so wie gewollt!

Jetzt habe ich bei Programmstart: "E_FAIL : An undetermined error occured"  ....so war das gar nicht geplant.  :wall1cf:

Nach einigem Rumprobieren stellte sich wohl die Rückverwandlung in die *.ubn scripte per 7zip und Umbenennen heraus? Auch sind die rückverwandelten Dateien um wenige kb größer als das Original auch wenn ich nur 1 Wert ändere. Vlt liegts ja an den Einstellungen bei 7zip oder was anderes?

Soweit erstmal von mir. Würde mich über Hilfe freuen.

Peace
Titel: Re: Mod-Tagebuch
Beitrag von: Torka am 24. September 2012, 21:42:15 Uhr
@ TheFall

ich freue mich über deine Begeisterung, welche du dem Scripten entgegen bringst. Ist schon ne Weile her, als ich mit den Scripten aktiv umgegangen bin. Wenn ich mich recht entsinne, habe ich die Dateien aber nicht mehr rückverwandelt.
Von den Orginaldateien auf alle Fälle Sicherungskopien herstellen. Im Moment sehe ich mich leider nicht im Stande den Kopf für das Scripten frei zu bekommen, da ich selber gerade das RL modifiziere, naja manchmal halt auch mit jener Fehlermeldung "An undetermined error occured"  :(.

Warum kann ich meine Beiträge nicht editieren?

Oben rechts müsste der Button "Ändern" stehen damit sollte es funktionieren :)