Zmienny kurs sprzedaży 4226 11

O temacie

Autor Czarny133

Zaczęty 28.05.2013 roku

Wyświetleń 4226

Odpowiedzi 11

Czarny133

Czarny133

Użytkownicy
posty13
  • Użytkownicy

Czarny133

Zmienny kurs sprzedaży
2013-05-28, 09:01(Ostatnia zmiana: 2013-05-28, 15:55)
Witam serdecznie wszystkich. Chciałbym zrobić w G2 kurs sprzedaży towarów zależny od retoryki (wprowadzonej przeze mnie umiejętności). Znalazłem w skryptach (konkretnie w Constants.d) tą linijkę:
const float TRADE_VALUE_MULTIPLIER = 0.15;Chciałem zamiast 0.15 umieścić tam zmienną rhetoric/200+0.10. Problem w tym, że const float umożliwia podanie tylko zwykłej liczby zmiennoprzecinkowej co jest niezgodne z tym co chciałem osiągnąć. Pytanie się nasuwa takie: czy istnieje jakiś sposób na obrobienie tej linijki tak bym osiągnął zamierzony cel? Albo czy istnieją jakieś inne pliki ze skryptami w których jest określony system handlu?
Nie jestem jakimś szczególnie uzdolnionym skrypterem, więc proszę o wyrozumiałość.
 

Sawik

Sawik

Moderator działu
Rebel
posty4772
Propsy3197
ProfesjaNierób
  • Moderator działu
  • Rebel
Może... użyj po prostu floata? Nigdy nie powinieneś chcieć pozwolić na sprzedawanie przedmiotów z procentem większym niż 100, czyli 1.00 patrząc w floatach. Cena jest obliczana w ten sposób Item.value*TRADE_VALUE_MULTIPLIER= Cena skupu
BTW. polecam zmienić z const na var, inaczej nie będzie się zapisywało.
 
Życzę wam seksu analnego po stronie biernej.
Dropbox +500 mb na start
LowPoly
Wykonanie modelu niskopoligonowego to sztuka kompromisu. Nie jest to jedynie uproszczenie modelu wysokopoligonowego, ale głęboka modyfikacja oraz podejmowanie decyzji często zmieniających wygląd pierwotny obiektu, tak by przy najmniejszej ilości trójkątów uzyskać jak najwierniej odwzorowany kształt oryginału. Nie można też zapomnieć o tym iż musi nadal wyglądać przekonywająco i tak balansować by uzyskać efekt optymalny.

Podstawowym założeniem jest, że model nie powinien mieć zbędnych, niewidocznych dla gracza detali włączonych w geometrie. Większość obiektów jakie znajdują się w grze powinna prezentować się najlepiej z odległości około 3-5 metrów. Wszelkie detale, które zanikają, wydają się płaskie lub zlewają się z bryłą modelu należy uznać za zbędne i pozostawić je na normal mapie.

Fakt, iż gracz będzie w stanie podejść bliżej do obiektu i zobaczyć go z mniejszej niż 3m odległości nie powinno stanowić większego problemu, gdyż większą rolę odgrywają wtedy tekstury oraz dodatkowy detal zależny od materiału obiektu. To właśnie kompromis między wydajnością, a szczegółowością otoczenia.

Detal, którego nie widać z 3-5 metrów nie powinnien istnieć w geometrii modelu.
Krawędzie znajdujące się blisko siebie, które zlewają się z większej odległości należy uprościć do wspólnej płaszczyzny

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator

inż. Avallach
Administrator

Zmienny kurs sprzedaży
#2 2013-05-28, 11:49(Ostatnia zmiana: 2013-05-28, 11:51)
Nawet jakbyś dał tam mnożenie przez tą swoją zmienną, byłoby to liczone tylko raz, przy parsowaniu. Po zmianie "rhetoric" ta stała i tak miałaby poprzednią wartość. Musiałbyś to odświeżać za każdym razem, najlepiej dokonując zmian tego rhetoric tylko za pomocą funkcji która zajmie się tymi czynnościami, nigdy ręcznie. Do tego wywoływać ją w startupie żeby wartość przywracała się po wczytaniu gry (albo jak napisał Sawik, spróbować zmienić to na zmienną).

Do tego nie możesz być pewien że zmiana tej wartości cokolwiek da. Możliwe że jest tylko na start ładowana przez silnik, a potem już nie odświeżana (bo przecież mechanizm handlu jest zaprogramowany w silniku, nie w skryptach). Za pomocą Ikarusa i gtools da się podmienić tą zmienną odpowiadającą za to, która jest w pamięci silnika, i to już by działało na pewno.

Czarny133

Czarny133

Użytkownicy
posty13
  • Użytkownicy
Trochę kombinowałem z tą wartością i w pliku Constants.d zamieniłem:
const float TRADE_VALUE_MULTIPLIER = 0.15;na
var float TRADE_VALUE_MULTIPLIER;
Potem w AI_Constants.d dodałem:
var int atr_rhetoric;

func void TRADE_RHETORIC()
{
if (Npc_GetTalentSkill(hero, NPC_TALENT_RHETORIC) == 0)
{
TRADE_VALUE_MULTIPLIER = 0.10;
};
if (Npc_GetTalentSkill(hero, NPC_TALENT_RHETORIC) == 1)
{
TRADE_VALUE_MULTIPLIER = 0.105;
};
if (Npc_GetTalentSkill(hero, NPC_TALENT_RHETORIC) == 2)
{
TRADE_VALUE_MULTIPLIER = 0.11;
};
if (Npc_GetTalentSkill(hero, NPC_TALENT_RHETORIC) == 3)
{
TRADE_VALUE_MULTIPLIER = 0.115;
};
if (Npc_GetTalentSkill(hero, NPC_TALENT_RHETORIC) == 4)
{
TRADE_VALUE_MULTIPLIER = 0.12;
};
if (Npc_GetTalentSkill(hero, NPC_TALENT_RHETORIC) == 5)
{
TRADE_VALUE_MULTIPLIER = 0.125;
};
        //i tak dalej, i tak dalej aż do:
if (Npc_GetTalentSkill(hero, NPC_TALENT_RHETORIC) == 100)
{
TRADE_VALUE_MULTIPLIER = 0.60;
};
};

Potem w Startup.d zmieniłem:
func void STARTUP_GLOBAL()
{
Game_InitGerman();
};

func void INIT_GLOBAL()
{
Game_InitGerman();
};
na
func void STARTUP_GLOBAL()
{
Game_InitGerman();
TRADE_RHETORIC();
};

func void INIT_GLOBAL()
{
Game_InitGerman();
TRADE_RHETORIC();
};

A następnie dodałem u nauczyciela retoryki taki dopisek (5 retoryki za 5 PN):
atr_rhetoric = atr_rhetoric+5;
Npc_SetTalentSkill (hero, NPC_TALENT_RHETORIC, atr_rhetoric);  

PrintScreen (Retoryka +5, - 1, - 1, FONT_Screen, 2);  
TRADE_RHETORIC();

Umiejętność retoryki zwiększa mi się o 5 i z tego co wiem wywołuje się funkcja TRADE_RHETORIC która powinna zaktualizować kurs sprzedaży ale kurs jest taki sam. Jedyna różnica którą zauważyłem to gdy dodałem wpisy do Startup.d to podczas uruchomienia nowej gry albo wczytania jakiegoś zapisu kurs zmienia się na 0.10 (bez tego wynosi 0.30).

Mógłbym prosić o kolejne rady albo wytknięcie mi błędów które zrobiłem? Zależy mi na tym zmiennym kursie i jeśli grzebanie w skryptach nie podziała to zostanie tylko ingerencja w silnik gry na czym się nie znam.
 

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator

inż. Avallach
Administrator

Zmienny kurs sprzedaży
#4 2013-05-28, 16:34(Ostatnia zmiana: 2013-05-28, 16:39)
Orcwarrior napisał kiedyś pod jakim adresem w silniku g1 siedzi ta wartość i jak można ją zmieniać. Działa to troszeczkę dziko, ale da się używać.
http://themodders.org/index.php?topic=10383.msg127917#msg127917

//edit: aha, ty chcesz do g2. No to masz problem. Jeśli modyfikowanie tej stałej w skryptach nic nie daje, to musiałbyś znaleźć odpowiedni adres dla g2nk. Do reverse engineeringu engine najlepiej używać IDA Pro, jednak nie jest to bynajmniej przyjemne zajęcie i wymaga ogólnej znajomości tego jak działają programy na komputerze i zarysu assemblera / c.

Czarny133

Czarny133

Użytkownicy
posty13
  • Użytkownicy
Hm, w takim razie zostało mi trochę poczekać na zmianę systemu handlu bo jestem wciąż zbyt niedoświadczony żeby robić tak skomplikowane (dla mnie) rzeczy. Gdybym się kiedyś chciał tym zająć ponownie albo gdyby moje prace posunęły się do przodu to dam znać.
Pozdrawiam
 

Sawik

Sawik

Moderator działu
Rebel
posty4772
Propsy3197
ProfesjaNierób
  • Moderator działu
  • Rebel
Sprawdź czy ten skrypt nie zadziała, w teorii może.
Ikarus dostarcza MEMINT_oCInformationManager_Address, jeśli "odległość" się nie zmieniła to zadziała.
 
Życzę wam seksu analnego po stronie biernej.
Dropbox +500 mb na start
LowPoly
Wykonanie modelu niskopoligonowego to sztuka kompromisu. Nie jest to jedynie uproszczenie modelu wysokopoligonowego, ale głęboka modyfikacja oraz podejmowanie decyzji często zmieniających wygląd pierwotny obiektu, tak by przy najmniejszej ilości trójkątów uzyskać jak najwierniej odwzorowany kształt oryginału. Nie można też zapomnieć o tym iż musi nadal wyglądać przekonywająco i tak balansować by uzyskać efekt optymalny.

Podstawowym założeniem jest, że model nie powinien mieć zbędnych, niewidocznych dla gracza detali włączonych w geometrie. Większość obiektów jakie znajdują się w grze powinna prezentować się najlepiej z odległości około 3-5 metrów. Wszelkie detale, które zanikają, wydają się płaskie lub zlewają się z bryłą modelu należy uznać za zbędne i pozostawić je na normal mapie.

Fakt, iż gracz będzie w stanie podejść bliżej do obiektu i zobaczyć go z mniejszej niż 3m odległości nie powinno stanowić większego problemu, gdyż większą rolę odgrywają wtedy tekstury oraz dodatkowy detal zależny od materiału obiektu. To właśnie kompromis między wydajnością, a szczegółowością otoczenia.

Detal, którego nie widać z 3-5 metrów nie powinnien istnieć w geometrii modelu.
Krawędzie znajdujące się blisko siebie, które zlewają się z większej odległości należy uprościć do wspólnej płaszczyzny

Czarny133

Czarny133

Użytkownicy
posty13
  • Użytkownicy
Pokombinowałem trochę i oto wyniki:
W pliku Constants.d wyłączyłem tą linijkę:
//const float TRADE_VALUE_MULTIPLIER = 0.15;
A następnie korzystając ze strony, którą podał mi Avallach wkleiłem to:
//==================================================
// Trade_ChangeSellMultiplier
// ----
// - mul have to be zfloat value
// - function should be refreshed atleast every trade
//   for simplify you can add it in ZS_TALK
//==================================================
func void Trade_ChangeSellMultiplier(var int mul)
{
        var int ptr;
        ptr = MEMINT_oCInformationManager_Address;
        ptr = MEM_ReadInt(ptr+24);//oCInformationManager.dlgTrade
        ptr = MEM_ReadInt(ptr+260);     //dlgTrade.oCViewDialogItemContainer
        MEM_WriteInt(ptr+268,mul);//oCViewDialogItemContainer.Multiplier = mul
};
do pliku ZS_Talk.d

Efekt był taki, że kurs przybrał domyślną wartość (0.30)
Postanowiłem więc zamienić Trade_ChangeSellMultiplier na Trade_Value_Multiplier i efekt był taki, że wszystko co jest warte powyżej 0 sprzedaje się za 1 sztukę złota. Nie wiem czy to mimo wszystko jakiś krok naprzód czy zrobiłem coś źle, bo mimo wszystko jak już wspomniałem jestem jeszcze słaby w skryptach. Teraz nie wiem co dalej.
 

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator

inż. Avallach
Administrator

Zmienny kurs sprzedaży
#8 2013-05-29, 12:32(Ostatnia zmiana: 2013-05-29, 12:34)
Samo wklejenie tej funkcji do pliku zs_talk.d nie robi NIC.
Nie miałeś jej tam wkleić, tylko wywoływać. Sama nowa funkcja powinna być raczej w osobnym pliku (chociaż zadziała jak dasz ją gdziekolwiek byleby uwzględnić porządek parsowania, ale to kiepski pomysł).
Żeby ją wywołać, musisz podać odpowiedni argument. Ten argument musi być typu zFLOAT (jest deklarowany jako int, bo Daedalus nie ma dostępu do prawdziwego zFLOAT), co jest już poważnym problemem. Przeczytaj dokładnie post orcwarriora, napisał tam jak dokonywać konwersji. Jest dodatkowy pakiet skryptów współpracujący z Ikarusem który to automatyzuje.

Czarny133

Czarny133

Użytkownicy
posty13
  • Użytkownicy

Czarny133

Zmienny kurs sprzedaży
#9 2013-05-29, 14:24(Ostatnia zmiana: 2013-05-29, 14:33)
Przeniosłem tą funkcję do innego (nowego) pliku, który parsuje sie zaraz po Ikarusie. Potem w ZS_Talk dodałem wywoływacz ten funkcji i uruchomiłem grę. Gra się ładnie uruchomiła, zrobiłem nową grę i wszystko się wczytało (nawet filmiki się uruchomiły), ale tuż po tym wywaliło mi crasha. Wniosek jaki wyciągłem z analizy tego problemu jest taki, że adres dla G2NK jednak jest inny niż dla G1.

Oto screen crasha jeśli miałby się na coś przydać:


Próbowałem jeszcze zmieniać tą funkcję na różne sposoby, ale nic nie pomogło. Zostało mi chyba już tylko znalezienie prawidłowego adresu, ale to już mnie przerasta.
 

Sawik

Sawik

Moderator działu
Rebel
posty4772
Propsy3197
ProfesjaNierób
  • Moderator działu
  • Rebel
MEMINT_oCInformationManager_Address ten adres jest w 100% poprawny.
Co więcej, błąd jest wywołany przez co innego. Skąd wiem? Skoro to ta funkcja crashuje, powinno scrashować dopiero przy wywołaniu tj. uruchomieniu dialogu.
 
Życzę wam seksu analnego po stronie biernej.
Dropbox +500 mb na start
LowPoly
Wykonanie modelu niskopoligonowego to sztuka kompromisu. Nie jest to jedynie uproszczenie modelu wysokopoligonowego, ale głęboka modyfikacja oraz podejmowanie decyzji często zmieniających wygląd pierwotny obiektu, tak by przy najmniejszej ilości trójkątów uzyskać jak najwierniej odwzorowany kształt oryginału. Nie można też zapomnieć o tym iż musi nadal wyglądać przekonywająco i tak balansować by uzyskać efekt optymalny.

Podstawowym założeniem jest, że model nie powinien mieć zbędnych, niewidocznych dla gracza detali włączonych w geometrie. Większość obiektów jakie znajdują się w grze powinna prezentować się najlepiej z odległości około 3-5 metrów. Wszelkie detale, które zanikają, wydają się płaskie lub zlewają się z bryłą modelu należy uznać za zbędne i pozostawić je na normal mapie.

Fakt, iż gracz będzie w stanie podejść bliżej do obiektu i zobaczyć go z mniejszej niż 3m odległości nie powinno stanowić większego problemu, gdyż większą rolę odgrywają wtedy tekstury oraz dodatkowy detal zależny od materiału obiektu. To właśnie kompromis między wydajnością, a szczegółowością otoczenia.

Detal, którego nie widać z 3-5 metrów nie powinnien istnieć w geometrii modelu.
Krawędzie znajdujące się blisko siebie, które zlewają się z większej odległości należy uprościć do wspólnej płaszczyzny

Lehona

Lehona

Użytkownicy
posty196
Propsy190
  • Użytkownicy
I might be wrong, but the AV indicates that you don't have the report-version of Gothic 2 installed. Without it, Ikarus will crash (and so will every script using it), because addresses are different.

Because this is somewhat related, I will just leave it here:
I recently made a script to allow for context-based value-evaluation (ie changing the value of an item based on context, e.g. whom you're selling it to (weapons to a smith, furs to a hunter...)). Might be useful for someone and not everyone of you is hanging around at WoG, trying to understand what we Germans write :)

func void onTradeLeft() {
value = MEM_ReadInt(ESP+20); // itm.value * multiplier
MEM_WriteInt(ESP+20, 123); // set new value
var oCItem itm; itm = _^(EBX); //Get the item
var oCNpc npc; npc = _^(MEM_InformationMan.npc); // Get the NPC
};

const int oCViewDialogTrade__OnTransferLeftX = 6863312; //0x68B9D0
HookEngineF(oCViewDialogTrade__OnTransferLeftX, 6, onTradeLeft);
 
Unless specified otherwise, my posts are always about Gothic 2 Night of the Raven.


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry