modyfikacja cen zakupu/sprzedaży u handlarzy 9180 36

O temacie

Autor pawbuj

Zaczęty 15.01.2018 roku

Wyświetleń 9180

Odpowiedzi 36

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
witam,

chciałem się dowiedzieć nieco więcej o modyfikacji cen zakupu/sprzedaży. niby trade_multipier to definiuje.

Tylko jak zrobić , aby wybrany handlarz miał nizsze ceny dla określonej grupy asortmentowej.
 

Bogdan Zwei

Bogdan Zwei

Użytkownicy
Wulgarny skurwiel pierdolony.
posty1864
Propsy541
Profesjabrak
  • Użytkownicy
  • Wulgarny skurwiel pierdolony.
Przecież to było wałkowane już na tym forum. Chyba nawet dwa razy. To siedzi w silniku, na WoG też jest o tym temat. Były próby zmiany tego.
 
:ok: zachęca do dalszej pomocy. Nie zapominaj o tym!

Prywatne wiadomości typu "Ej, pomocy" kasuję od razu. Od tego jest forum, a nie PW.

To me, defeat in anything is merely temporary, and its punishment is but an urge for me to greater effort to achieve my goal. Defeat simply tells me that something is wrong in my doing; it is a path leading to success and truth.

In order to realize our true self we must be willing to live without being dependent upon the opinion of others.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
Przecież to było wałkowane już na tym forum. Chyba nawet dwa razy. To siedzi w silniku, na WoG też jest o tym temat. Były próby zmiany tego.
o to ci chodzi? to wiem.
https://themodders.org/index.php?topic=10383.20

tylko nie ma tu jak podzielic to na grupy asortmentowe. ale ok, w Velayi było cos na podobę.
 

TheKetrab

TheKetrab

Użytkownicy
posty334
Propsy217
ProfesjaProducent
  • Użytkownicy
Przyjrzyj się skryptom Velayi. Kiedyś szperalem tam w skryptach. Są potężne funkcje definiujace cenę każdego przedmiotu z osobna po rozwiazaniu zadania "nizsze ceny". Coś w ten deseń.
 

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
Przyjrzyj się skryptom Velayi. Kiedyś szperalem tam w skryptach. Są potężne funkcje definiujace cenę każdego przedmiotu z osobna po rozwiazaniu zadania "nizsze ceny". Coś w ten deseń.
pamietam, ale nie wiedziałem gdzie dokładnie. super dzięki.
 

Cruc

Cruc

Użytkownicy
posty662
Propsy232
Profesjabrak
  • Użytkownicy
A jakby w momencie rozpoczynania się dialogu (np. w B_GiveTradeInv) pozyskiwać listę wybranych itemów i w zależności od NPC'a, z którym handlujemy, zmieniać wartość przedmiotów z listy na interesującą nas wartość w przypadku konkretnego handlarza, lub defaultową, gdy jest to ktoś inny?
 
while (!success) try{...}

Najlepszy modder od gothic multiplayer - polecam pytać go o wszystko!

Zucklov

Zucklov

Quest Pack Team
Sztywniutko
posty1220
Propsy1241
ProfesjaSkrypter
  • Quest Pack Team
  • Sztywniutko
Wartość przedmiotu to stała, nie zmienna. Nie da się nią operować.
 
Lieb Vaterland magst ruhig sein

inż. Avallach

inż. Avallach

Administrator
posty7662
Propsy5238
NagrodyV
ProfesjaProgramista
  • Administrator
Właściwie to w Dedalusie da się zmieniać stałe, musisz tylko "odświeżać" je po każdym wczytaniu gry (w przeciwieństwie do zmiennych, ich nowe wartości nie trafiają do pliku zapisu gry, który jest "oszczędnie" zserializowanym stanem maszyny wirtualnej Daedalusa).

Cruc

Cruc

Użytkownicy
posty662
Propsy232
Profesjabrak
  • Użytkownicy
Emm... Pole value nie jest stałą.
 
while (!success) try{...}

Najlepszy modder od gothic multiplayer - polecam pytać go o wszystko!

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
w Velayi zrobione jest tak, że towary w ekwipunku handlarza są podmieniane, dlatego są tańsze.

czyli mamy 2 itemy o takim samym visualu, ale o różnej wartości i innej instancji.

trochę prymitywne.

ale edycja wartości poszcz. itemów jest bez sensu, to będzie bugować się.

potrzebuję warunku, że jeżeli item znajduje w kolumnie do handlowania to....
z resztą skryptu sobie poradzę.
 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
Zamiast kombinować najlepiej to zrobić samemu. Funkcja zmiany ceny jest gotowa. Wystarczy sprawdzić kategorię przedmiotu i namierzonego npc. Wszystko czego potrzebujesz jest w klasie oCNpc wystarczy znać angielski.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
kod (do g2nk - autor Frank-95), który wyklucza pewne itemy, których bezio nie może kupić (na wzór pancerzy z g3), myślę, że można to przerobić na swoje potrzeby. powiedzmy, że jest to proste.

const int oCViewDialogTrade__OnTransferLeft        = 6862912; //0x68B840
const int oCViewDialogTrade__OnTransferRight    = 6863632; //0x68BB10

//in startup
MemoryProtectionOverride(oCViewDialogTrade__OnTransferLeft + 6, 4);
HookEngineF(oCViewDialogTrade__OnTransferLeft, 6, CheckSellingItems);

//wherever
func void CheckSellingItems()
{
    var oCNpc her;    her = Hlp_GetNpc(hero);
    var C_NPC foc;    foc = _^(her.focus_vob);
    var oCItem itm;    itm = _^(Inventory__GetSelectedItem());   
     if    (condition)    //if this condition is met the item will be sold   
    {
        MEM_WriteByte(oCViewDialogTrade__OnTransferLeft + 6, 106);
    }
    else    //else it won't be sold
    {
        MEM_WriteByte(oCViewDialogTrade__OnTransferLeft + 6, 195);
    };
};
 

Splash

Splash

Moderator
posty4207
Propsy3404
ProfesjaNierób
  • Moderator
Nie jest proste, bo handel w G1 całkowicie różni się od tego w G2.
 
Nie zajmuję się multiplayerami do Gothica. Przestańcie zawracać mi tym głowę...
Ps. Siemekk ma downa i śpi w pufie

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
Nie jest proste, bo handel w G1 całkowicie różni się od tego w G2.
OK, a jest jakiś warunek, który sprawdza, czy npc jest w trakcie "handlu"?
 

Zucklov

Zucklov

Quest Pack Team
Sztywniutko
posty1220
Propsy1241
ProfesjaSkrypter
  • Quest Pack Team
  • Sztywniutko
Emm... Pole value nie jest stałą.
? XD
lol jak nie jest? Value jest definiowane w skrypcie przedmiotu.
Możesz zresztą łatwo to sprawdzić, zmień gdzieś w dialogu wartość przedmiotu, zapisz grę i wczytaj.
 
Lieb Vaterland magst ruhig sein

Cruc

Cruc

Użytkownicy
posty662
Propsy232
Profesjabrak
  • Użytkownicy
Wystarczy mi spojrzeć na deklarację klasy.

oCItemContainer*m_pChest;
int value; // Wert des Items

Może rzeczywiście informacje o poszczególnych polach wszystkich obiektów nie są zapisywane, co zresztą nie powinno dziwić, dlatego gra przy nowej sesji ponownie "wyciąga" te informacje ze skryptu. Podobnie zresztą ma się sprawa z NPC'ami. Możesz zmienić mu tekstury, ale po zapisie i wczytaniu będzie wyglądał w taki sposób, w jaki zdefiniowane to jest w skrypcie. Ale to już jest kwestia tego w jaki sposób zaprojektowany jest silnik, a nie tego czy encja jest stałą czy zmienną. W każdym razie nie zmienia to faktu, że value jest zmienną.

Edit:
Cytuj
OK, a jest jakiś warunek, który sprawdza, czy npc jest w trakcie "handlu"?

Chyba nie ma. Nawet w G2 B_GiveTradeInv wywoływane jest ręcznie w skrypcie dialogu poprzedzającym handel. Zawsze możesz spróbować pobawić się z funkcją B_AssessTalk. Wywołuje się ona wtedy, gdy chce się rozpocząć rozmowę z danym NPC.

Znalazłem jeszcze funkcję silnika Npc_HasOffered (VAR C_NPC self, VAR C_NPC other, VAR INT itemInstance), która ma ponoć zwracać true, jeśli zaoferuje się w handlu podany item, ale chyba nawet nie jest wykorzystywana.
 
while (!success) try{...}

Najlepszy modder od gothic multiplayer - polecam pytać go o wszystko!

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
@Cruc te informacje są czytane od zera (z Instancji) ponieważ archiwier dla klas oCNpc i oCItem nie działa w 100% tak jak powinien.

Post połączony: 2018-01-16, 00:22
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
najlepszy sposób będzie następujący. i proszę mi nie wmawiać , że było to wałkowane na wogu czy tutaj.

1)inicjujemy skrypt jn w dialogu handlarza (zmieniamy ceny tylko na czas handlu)
2)po zakończeniu wracamy do "starych cen".

ten skrypt jest nieprzerobiony (autor Sektenspinner i po moich modyfikacjach) i powinno sie obyć bez ikariusa.
Bardzo łatwo można go przerobić, aby zamiast usuwania/przenoszenia itemów zmieniał ich wartości (value czy changed_value) po instancji czy nawet kategorii.

var c_Item armor;var c_Item meleeweapon;var c_Item rangedweapon;
func void Npc_ClearInventoryLoop (var c_npc npc, var int category)
{
    //PrintScreen (ConcatStrings("Czyszczenie eq: ", npc.name), yposition,yaposition,"FONT_OLD_10_WHITE.TGA",timep); //dla testu
// print(ConcatStrings("Czyszczenie eq: ", npc.name);
        var int amount;
        amount = Npc_GetInvItemBySlot (npc, category, 0);
        armor = Npc_GetEquippedArmor(npc);
        meleeweapon = Npc_GetEquippedMeleeWeapon(npc);
        rangedweapon = Npc_GetEquippedRangedWeapon(npc);
        // print(ConcatStrings(item.name, IntToString(amount));

       
        if ((amount>0)
        && Hlp_GetInstanceID(item) != Hlp_GetInstanceID(armor)
        && Hlp_GetInstanceID(item) != Hlp_GetInstanceID( meleeweapon)
        && Hlp_GetInstanceID(item) != Hlp_GetInstanceID(rangedweapon))
       
        {
                NPC_RemoveInvItems (npc, Hlp_GetInstanceID (item), amount);
               
                Npc_ClearInventoryLoop(npc, category);
        }
        else if (category < INV_CAT_MAX-1)
        {
                //print(ConcatStrings("Zmiana kategorii na: ", IntToString(category+1));
                Npc_ClearInventoryLoop(npc, category+1);
        };
};


func void Npc_ClearInventory (var c_npc npc)
{

Npc_ClearInventoryLoop(npc, 0);
};
 

Cruc

Cruc

Użytkownicy
posty662
Propsy232
Profesjabrak
  • Użytkownicy
W jaki sposób będziesz wykrywał zakończenie handlu?
 
while (!success) try{...}

Najlepszy modder od gothic multiplayer - polecam pytać go o wszystko!

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
mam problem z modyfikacja samych cen w trakcie gry.tu się na pewno bez iakrusa nie obejdzie.

 przykład dla g2nk przy sprzedaży (moze komus sie przyda)
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);

 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
Powiedz na spokojnie co chcesz zrobić - zmiana ceny przedmiotu czy blokowanie sprzedaży?  Oraz jaka platforma G1 czy G2?
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
Powiedz na spokojnie co chcesz zrobić - zmiana ceny przedmiotu czy blokowanie sprzedaży?  Oraz jaka platforma G1 czy G2?
chcę zrobić zmiany cen przedmiotów, ale nie wszystkich.  chodzi o g1, ale tym się nie zajmujesz. do tego handel jest tropchę inny niź w g2.
 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
Spróbuj tego:
//Funkcja OrcWarrior
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

var c_npc sprzedawca; sprzedawca = _^(ptr + 260); //oCViewDialogItemContainer.m_pLeftNpc
var c_npc gracz; gracz = _^(ptr + 264); //oCViewDialogItemContainer.m_pRightNpc
var c_item przedmiot;
CALL__thiscall(ptr + 256, 0x007092C0); //Trzeba znaleźć adres pod G1 (Nie mam IDA)
przedmiot  = _^(CALL_RetValAsPtr());

//Warunki etc...
MEM_WriteInt(ptr+268, mul); //oCViewDialogItemContainer.Multiplier = mul
};
Offsetów do zmiany wartości mnożnika kupna nie mogłem znaleźć.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
to nie trzeba przerobić na system dziesiątkowy?

CALL__thiscall(ptr + 256, 0x007092C0); //Trzeba znaleźć adres pod G1 (Nie mam IDA)
Posukam w skryptach może mam adres do kupna (podaj mi jego nazwę).
 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
oCItem* oCItemContainer::GetSelectedItem() i tak trzeba przerobić na system dziesiętny.
Użyj print'a do testów (Print(przedmiot.name); ). A jeżeli nie zadziała _^ to użyj MEM_AssignContentInst(przedmiot, CALL_RetValAsPtr());
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
oCItem* oCItemContainer::GetSelectedItem() i tak trzeba przerobić na system dziesiętny.
przerobienie to nie problem, rozumiem, że ten adres w opcji sprzedaży też jest zły.
CALL__thiscall(ptr + 256, 0x007092C0); //Trzeba znaleźć adres pod G1 (Nie mam IDA)
 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
Pointer jest dobry, adres jest z gothic 2.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Cruc

Cruc

Użytkownicy
posty662
Propsy232
Profesjabrak
  • Użytkownicy
var int ptr;
ptr = MEMINT_oCInformationManager_Address;
ptr = MEM_ReadInt(ptr+24); //oCInformationManager.dlgTrade
ptr = MEM_ReadInt(ptr+260); //dlgTrade.oCViewDialogItemContainer

var c_npc sprzedawca; sprzedawca = _^(ptr + 260); //oCViewDialogItemContainer.m_pLeftNpc
var c_npc gracz; gracz = _^(ptr + 264); //oCViewDialogItemContainer.m_pRightNpc
};

Może zadam trochę głupie pytania, ale właśnie ściągnąłem Ikarusa i rozeznaję się w nim powoli, zatem...
1. Skąd wiesz jak wyznaczać kolejne adresy jako parametr funkcji MEM_ReadInt?
2. Funkcja _^ zwraca instancję dla podanego wskaźnika?
 
while (!success) try{...}

Najlepszy modder od gothic multiplayer - polecam pytać go o wszystko!

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
@Siemekk, sprawdzę Idą ten adres . Jak znajdzę i będzie działać to napiszę.

alternatywnie i 100% bez bugów i bezstresowo mozna to zrobić jak v Velayi (podmieniamy itemy).

druga metoda to przypisać nową wartość value do itemu (próbowałem metodą istance itemu.value ale to nie działa).

Przejrzałem skrypty CZ i jest tam taki mess z tym changesellmultipier, że sie tego nie podejmę. do tego skrypt Orca z drugiej strony tematu o Ikarusie powoduje, że wszytskie itemy w sprzedaży przez Beziego sa po 0.
 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
func void SetItemValue(var int inst, var int value)
{
var int ptr; ptr = _@(inst);
MEM_WriteInt(ptr + 320, value);
};
Może to pomoże.
SetItemValue(ItAr_Pal_H, 100);
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
func void SetItemValue(var int inst, var int value)
{
var int ptr; ptr = _@(inst);
MEM_WriteInt(ptr + 320, value);
};
Może to pomoże.
SetItemValue(ItAr_Pal_H, 100);
niestety nie działa.
tak się zmienia kolor itemu w ekwipunku i bez adresu hooka się nie obędzie. Zainstalowałem
IDę (jakaś waersja free), ale ni w ząb tego nie kumam.

func void ColorItemName() {
var zCViewText txt; txt = _^(EAX);
var int col; col = -1;
var C_Item itm; itm = _^(MEM_ReadInt(ESP+324+4));




txt.color = col;
txt.colored = 1;
};

// Zum initialisieren einmalig pro Session folgendes aufrufen:

HookEngineF(7369071/*0x70716F*/, 6, ColorItemName);

 

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
skoro już wywołaem tą gównoburzę to ją dokończę. Do każdego dialogu z handlem potrzeba dodać


Trade_EraseValue(); //BUGFIX has to be in every trade dialog
//Trade_ALL_Mul = 1065353216;//1
    Trade_ChangeSellMultiplier(1065353216);

func string Trade_GetHeroCatString()
{ var int ptr;
ptr = MEMINT_oCInformationManager_Address;
ptr = MEM_ReadInt(ptr+24);//oCInformationManager.ocViewDialogTrade
if(ptr)
{
  ptr = MEM_ReadInt(ptr+264); //oCViewDialogItemInventory
  if(ptr)
  {
  ptr = MEM_ReadInt(ptr+256); //oCItemContainer
  if(ptr)
  {
  ptr = MEM_ReadInt(ptr+48); //zCView - Titel
  if(ptr)
  {
  return MEM_ReadString(ptr+200);//text
};
};
};
};

return "";//blank

};

cała funkcja (pochodzi z CZ) i można edytować trade_value_multipier po kategorii itemu . Nie wiem już tylko zrobić dla pojedynczych instancji itemów.

 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2143
Propsy1151
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer

Siemekk
Złote Wrota

modyfikacja cen zakupu/sprzedaży u handlarzy
#32 2018-01-18, 19:40(Ostatnia zmiana: 2018-01-18, 20:40)
Skrypty z Czasu Zapłaty to jeden wielki bug... Nie pakuj się w nie (recepty kosztują po 500k złota). Znajdź pointer do obecnego przedmiotu a sprawa sama się rozwiąże.

Post połączony: 2018-01-18, 20:38
Albo spróbuj tego:
func void Trade_UpdateValue() //Wywołać w ZS_TALK_LOOP?
{
var int ptr;
ptr = MEM_ReadInt(MEMINT_oCInformationManager_Address + 24);//oCInformationManager.ocViewDialogTrade

if(ptr)
{
  ptr = MEM_ReadInt(ptr + 264); //oCViewDialogItemInventory
  if(ptr)
  {
  ptr = MEM_ReadInt(ptr+256); //oCItemContainer
  if(ptr)
  {
var c_item it;
CALL_thiscall(ptr, oCItemContainer::GetSelectedItem() /*Adres musisz znaleźć sam*/);
MEM_AssignInst(it, CALL_RetValAsPtr());
if(_@(it))
{
Print(it.name);
//Czego dusza zapragnie
};

};
};
};
};
Tylko znajdź adres.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy
dzięki Siemekk, wiem że chcesz pomóc! jakbym ogarniał Idę to bym może i znalażł. OK, popytam parę osób, może mi pomogą znależć.
 

Neck

Neck

Użytkownicy
posty82
Propsy7
Profesjabrak
  • Użytkownicy
Hej, napiszę tutaj aby nie zakładać nowego tematu :) Mógłby ktoś napisać jak zablokować sprzedaż konkretnego przedmiotu podczas handlu?
 

Gother

Gother

Użytkownicy
Nieskromny Mistrz Gothica
posty447
Propsy255
ProfesjaScenarzysta
  • Użytkownicy
  • Nieskromny Mistrz Gothica
Jest wiele opcji. Pierwsza, która przyszła mi na myśl to sytuacja gdy kupujesz przedmiot, a po zakończeniu transakcji kupiec ci go odbiera, bo ma warunek: gdy postać gracza ma w ekwipunku przedmiot X to kupiec Y rozpoczyna dialog -"Hej, to nie na sprzedaż. Oddawaj."
 

frN

frN

Użytkownicy
posty50
Propsy24
ProfesjaGracz
  • Użytkownicy
Najlepsza opcja to zrobić to w formie pluginu pod Uniona

Np. coś takiego:
https://www.youtube.com/watch?v=lZFEhqCchOU
 


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