27-01-2018, 21:17 (Ten post był ostatnio modyfikowany: 27-01-2018, 21:17 przez seriously.)
W OpenTTD gram juz z dekade i powoli mecza mnie te piksele, zas sam zBase poza budynkami ktore mozna zniesc, nie oferuje mi do konca tego, co bym chcial. Alternatyw poki co brak, Mashinky wygladaja sredniawo, Transport Fever to nieporozumienie. Postanowilem wiec zakasac rekawy i zrobic sobie na wlasna reke jakis dodatek pojazdow 32bpp, zeby gra na zBase byla znosna. Pare pojazdow jest gotowych,w zalaczniku na zachete EP09. Jak uda mi sie to zakodowac na cos grywalnego, to moge sie podzielic. Zdaje sobie sprawe ile to pracy, ale robie to glownie na wlasny uzytek, post tutaj w ramach ciekawostki i dla zainteresowanych.
Osobiście wolę piksele bo bardziej pasują do kanciastości gry, ale coraz więcej powstaje dodatków 32bit, np. Czesi mają auta i pociągi w dużej rozdzielczości. W czym to robisz? Jakby co, to mam trochę modeli w 3dsmax z czasów Maszyny EU07.
Co do kanciastości: proponuję wyeksportować dodatkowe widoki skośne, bo takie ładne obrazki brzydko wyglądają gdy gwałtownie skręcają pod kątem 45 stopni. W openttd jest możliwość testowania jak głęboko w zakręt wszedł pojazd (vehicle_curv_info). Przykładowo cets to wykorzystuje: http://dev.openttdcoop.org/projects/cets...normal.png
Dobrze byłoby też wyeksportować obrazki aby były podobne w skali do np. CSD.
(29-01-2018, 14:42)McZapkie napisał(a): Osobiście wolę piksele bo bardziej pasują do kanciastości gry, ale coraz więcej powstaje dodatków 32bit, np. Czesi mają auta i pociągi w dużej rozdzielczości. W czym to robisz? Jakby co, to mam trochę modeli w 3dsmax z czasów Maszyny EU07.
Co do kanciastości: proponuję wyeksportować dodatkowe widoki skośne, bo takie ładne obrazki brzydko wyglądają gdy gwałtownie skręcają pod kątem 45 stopni. W openttd jest możliwość testowania jak głęboko w zakręt wszedł pojazd (vehicle_curv_info). Przykładowo cets to wykorzystuje: http://dev.openttdcoop.org/projects/cets...normal.png
Dobrze byłoby też wyeksportować obrazki aby były podobne w skali do np. CSD.
Pamietam Cie z maszyny Na tabor nie narzekam, swego czasu troche sie nastukalo rzeczy, a to jeszcze zupelnie inna skala detali, tutaj bardzo mocne low poly daje rade. Pracuje w 3ds max wlasnie. Na codzien przy modelach wlasnie do gier w stylu cities skylines uzywam substance paintera, ale tutaj stykaja tekstury w inkscape - te z z tej dziewiatki robilem wlasnie tam.
Przegladalem wiki openttd i tt forums, ale nie znalazlem nigdzie ustawien kamery zeby zlapac idealny kat. Juz w ogole marzeniem bylby jakis szablon z kamerami i potem tylko render z X kamer, zeby miec wszystkie rzuty. To jest najwiekszy problem o ktorym na poczatku w ogole nie pomyslalem. Bede szukal dalej i probowal. Dziekuje za template.
Zas jesli chodzi o CSD, odezwalem sie do osobn robiacych na tt forums wlasnie ten Czech Replacement Set i dostosowalem oswietlenie, zeby pasowalo. Skale tez dopasuje.
Taki można właściwie chyba założyć .
Mogłoby znajdować się w nim tylko grafiki z zoom zi2 (w tym "x4") .
Standard ( uwzględniając wymiany klimatu) to około min.10 lokomotyw
różnej mocy o żywotności przeciętnie 30 lat .
Na początku mógłby znajdować się wybrany polski tabor : 2 parowozy lub wiecej np. zabytkowy odrestaurowany do dziś
( min. 1 historyczny z czasów xx lecia międzywojennego + 1 nowszy do lat '80)
-nie miałyby ekonomicznych parametrów , awaryjny , ale niska cena zakupu z 5 spalinówek
( 1 po roku '50 + 1 motorowo-pasażerski tj.SN61 lata '70/2000 + 1 szynobus od '2000 +
1 z teraźniejszości + 1 realny projekt prototypowy po roku 2018)
-droższy do nabycia , tańszy w kosztach, bardziej niezawodne 3 elektrowozy
( 1 z '60/'90 + 1 z 90/2020 + 1 obecny na lata do 2040 )
-konkurencyjne na lepsze prędkości torów, szybsze , ale wymaga nakładów w trakcje
w dalszej kolejności : 1 wagon typu osobowego przebudowywalny na poczte i przesyłki -paczki kosztowności
( max 210 km/h) 4 wagonytowarowe (max 130 km/h)
wagon na węgiel lub żelazo albo inne surowce mineralne oraz przebudowywalny do przewozu żywca
wagon kryty na ziarno lub żywność
wagon cysterna na zawartości płynne , z wymienną "beczką"
wagon platforma na konstrukcje stalowe, drewno, towary w kontenerach
Z możliwością całkiem rozszerzenia na inne wytyczne, przemysły , piętrowe dla aut .
# Główny tytuł i opis grf
STR_GRF_NAME :{TITLE} {VERSION}
STR_GRF_DESCRIPTION :{TITLE} lokomotywa spalinowa i elektryczna dla OpenTTD (c)2019. {} Grafix: "{ORANGE}CZTR Team{BLACK}" , {} 8bpp~{ORANGE} PKPSet{BLACK}. {}Licencja: {GREEN}GPL v2{}{BLACK}Website:{SILVER} https://www.facebook.com/OTTD-Czech-realistic-replacement-1978368325710456/
12-12-2019, 17:34 (Ten post był ostatnio modyfikowany: 12-12-2019, 18:15 przez metro.)
Zeby wlasnie lepiej mozna bylo nanosic poprawki (szczgolnie dla dodawania nowych objektow-pojazdow),
umozliwiono uproszczenie tego etapu .
Rozdzielono bloki w pojedynczym pliku .nml
do poszczegolnych plikow zrodlowych .pnml - ilosc,rozmieszczenie i nazewnictwo bywa rozne: przewaznieJakGRF.pnml - naglowkowy rozpoczynajacy , zawierajacy spis pozostalej zawartosci \src\GRFid.pnml . . . . . . . - nazwa, wersja, parametry etc \src\templates.pnml . . . . .- zdefiniowane sprity jako czesc wspolna \src\engine_dizel.pnml . .- plik okreslajacy lokomotywe \src\wagon_pietrowy.pnml - plik jakiegos wagonu
niestandardowe rozszerzenia: \src\railtype_table.pnml . . - tabela typow torow \src\cargos.pnml . . . . . . ..- zestawienie obslugiwanych towarow \src\costs.pnml. . . . . . . . - zmienne koszty
Przy budowaniu .grf nalezy to oczywiscie konsolidowac do .nml przed kompilacja.
Sluzy do tego pewien automatyczny program, ktory zawiera instrukcje do zrobienia podczas tego procesu .
Wystarczy uruchomic podajac nazwe (linia polecen). Chyba nieaktualne: s.f.net z minGW .
Jesli jest w pythonie to bez rozszerzenia po kropce np. MakePY
albo klikajac plik PreBuild.py lub dowolnie nazwany - skojarzony .
Po skonfigurowaniu cala kompilacja moze odbywac sie poprzez przycisk na belce, w menu aplikacji,
w ktorej pisane .pnml .
Tym rozni sie .pnml od .nml , ze umieszczone sa wstawki , ktore nie wystepuja w tym drugim -- "nieimplementowane".
#Importowanie wymaganych rzeczy - korzystanie z tzw. modułów tudzież bibliotek (skompilowane wersje .pyc, działają szybciej)
from time import sleep, gmtime, strftime
import time
from random import randint
import sys
import os
import argparse
#wyswietlenie początkowego komunikatu :
print("\n = = = eNeMeL konsolidator ! = = = \n")
#obsługa argumentów z interfejsu wiersza poleceń
parser = argparse.ArgumentParser(description="Patchowanie GRF ~ w NML ~ z plików pnml do jednego pliku NML. Jeśli nie podano żadnych argumentów, program zapętli się i poprosi o dane wejściowe do skompilowania pliku. OSTRZEŻENIE! To NIE kompiluje się do pliku .grf, a tylko łata składowe pliki .pnml do pliku .nml, aby można było skompilować z NMLC!")
parser.add_argument("-o", "--output", type=str, help='Plik do wyjśca , zapisanie do pliku. Podanie nazwy pliku tylko, nie w cudzysłowie ( np.: output.nml ) ' )
parser.add_argument("-f", "--plik", type=str, help="Plik nagłówka do odczytania. Podanie nazwy pliku ze ścieżką w cudzysłowie.")
parser.add_argument("-b", "--backup", type=int, help="1 lub 0, aby potwierdzić, czy program utworzy kopię zapasową w przypadku zastąpienia pliku wyjściowego.", choices=[0,1])
args = parser.parse_args()
#Sprawdzanie, czy którykolwiek z argumentów ma jakąkolwiek wartość, która nie jest "None"
used_args = False
arguments = vars(args)
for argument in arguments:
if not used_args and arguments[argument] != None:
used_args = True
#Definiowanie funkcji ogólnego przeznaczenia ( usuniecie rozszerzenia nazwy pliku )
#Znajdowanie ostatniego miejsca po kropce w nazwie nagłówka pliku
for pos in range(len(file_name)-1,-1,-1):
if file_name[pos] == "." and not found_file_extension:
end_point = pos
found_file_extension = True
return file_name[:end_point]
#Funkcja tworzenia kopii zapasowej, która -najpierw- tworzy kopię zapasową pliku wyjściowego (jeśli już istnieje)
def backup(name):
if name in os.listdir():
if not ("backups" in os.listdir()):
os.mkdir("backups")
os.rename(name, "backups/" + rm_file_extension(name) + "-" + strftime("%H-%M-%S-%Y-%m-%d", gmtime())+".nml")
def close(self):
if str(type(self.input)) == "<class '_io.TextIOWrapper'>":
self.input.close()
if len(self.total_list_of_errors):
if len(self.total_list_of_errors) == 1:
print("\nWystąpił 1 błąd w tej poprawce")
else:
print("\nNapotkany", len(self.total_list_of_errors), "errors w patch'u .")
for error in self.total_list_of_errors:
if len(error) == 1:
print_general_error(error[0])
else:
print_error(error[0], error[1], error[2])
def main(self):
#Główna funkcja, która czyta plik i zapisuje go w pliku wyjściowym
#Generowanie listy każdego wiersza kodu w pliku docelowym, a następnie usuwanie nowych znaków wiersza
lines = [line.replace("\n","") for line in self.input]
#Główna pętla - zapętlenia przez każdą linię kodu
self.line_counter = 0
for line in lines:
self.line_counter += 1
do_write = True
#Jeśli wiersz zaczyna się od polecenia „#include”, to tworzy kolejną instancję, która najpierw czyta i zapisuje ten plik
if line.lower()[:8] == "#include":
#Znajdowanie końca nazwy definicji
def_name = ""
found_def_name = False
for letter in new_line:
if letter == " " and not found_def_name:
new_line = new_line.replace(def_name + " ", "")
if len(new_line) > 0:
print("Wykonano ustanowioną definicję", def_name, "o wartości", new_line)
self.list_of_definitions[def_name] = new_line
elif len(def_name) > 1:
self.total_list_of_errors.append(["Nieprawidłowa definicja !", "Linia" + str(self.line_counter) + " ze " + self.file_name + ": " + line, "Do sprawdzenia wartość definicji"])
found_def_name = True
def_name += letter
do_write = False
else:
#Sprawdzanie ustanowionych definicji
for definition in self.list_of_definitions:
if definition in line:
line = line.replace(definition, self.list_of_definitions[definition])
#Jeśli zostanie znaleziona definicja uznana za wadliwą, wysyła błąd
for definition in self.faulty_definitions:
if definition in line:
self.errors_made +=1
self.total_list_of_errors.append(["Użyto niepoprawnej definicji !", "Linia " + str(self.line_counter) + " ze " + self.file_name + ": " + line, "Sprawdź wartość definicji"])
if do_write:
output.write_line(line)
#Definiowanie innych funkcji ogólnych
#Jeśli dane wyjściowe nie są zdefiniowane, ale plik nagłówkowy jest, to zostanie zdefiniowany tak samo jak dane wejściowe
if arguments["plik"] != None and arguments["output"] == None:
arguments["output"] = rm_file_extension(arguments["plik"])+".nml"
#Tworzenie kopii zapasowej, jeśli kopia zapasowa jest ustawiona na 1
if arguments["backup"] != None and str(arguments["backup"]) != "0" :
print("Próba wykonania kopii zapasowej", arguments["output"])
backup(arguments["output"])
#Wyświetlanie podanych argumentów użytkownikowi
for argument in arguments:
if arguments[argument] != None:
print(argument.capitalize(), ":", arguments[argument])
#Sprawdzanie, czy używane są argumenty
if used_args:
#Sprawdzenie, czy podano argument „plik”, ponieważ program nie może bez niego kontynuować
if arguments["plik"] != None:
try:
#Główna sekwencja, która otwiera pliki, a następnie zapisuje na wyjściu
output = writer()
header = reader(arguments["plik"])
header.main()
output.close()
header.close()
#Wyświetlanie komunikatów po łataniu
if len(header.list_of_definitions) > 0:
print("\nLista ustanowionych definicji używanych w tym pliku:")
for definition in header.list_of_definitions:
print(definition, header.list_of_definitions[definition])
#Jeśli typ użytkownika zakończy działanie, program się zakończy
if arguments["plik"].lower() == "exit":
raise KeyboardInterrupt
#Tworzenie pliku wyjściowego na podstawie nazwy pliku wejściowego
arguments["output"] = rm_file_extension(arguments["plik"])+".nml"
#Główna sekwencja, która otwiera pliki, a następnie zapisuje na wyjściu
output = writer()
header = reader(arguments["plik"])
header.main()
output.close()
header.close()
#Wyświetlanie komunikatów po łataniu
if len(header.list_of_definitions) > 0:
print("\nLista ustanowionych definicji używanych w tym pliku:")
for definition in header.list_of_definitions:
print(definition, header.list_of_definitions[definition])
#Jeśli polecenie zostanie wprowadzone lub zostanie naciśnięty klawisz Ctrl + C, program zostanie zakończony
except KeyboardInterrupt:
print("\nWyjście z programu!")
break
#Wyłapanie wszelkich innych zgłaszanych błędów (#Wyjątek jako inst)
except SyntaxError:#Exception as inst:
print_general_error(str(inst) + " z " + str(type(inst)))
12-12-2019, 17:54 (Ten post był ostatnio modyfikowany: 12-12-2019, 17:56 przez metro.)
W 32 bpp na poczatek wlasciwie mozna pominac dawne pliki z paleta 8 bit per pixel i wpisujac 0 lub 1 tymczasowo w nml.
Choc do korekcji obrazow w 8bpp nadaje sie spec szybka stronka: http://bundles.openttdcoop.org/pixeltool/push/LATEST/
GIMP staje sie troche toporny, oblozony w coraz wiecej mniej uzywanych gadzetow dla zwyklejszej grafiki.
Preferuje na drobniejsze zmiany zerknac freeware P.Studio , ktory daje mozliwosc wylaczenia co akurat nie zamierzane obslugiwac: photofiltre.com
Oprocz wlasciwosci painta z "gumkowaniem" oraz po polsku,
jest wielokrotne,'cofanie' czynnosci czy plugin wymierzajacy pixele .