Dodatkowe zmienne w klasie C_NPC :D 6360 8

O temacie

Autor RafalBudzis

Zaczęty 24.03.2012 roku

Wyświetleń 6360

Odpowiedzi 8

RafalBudzis

RafalBudzis

Użytkownicy
posty1967
Propsy808
ProfesjaSkrypter
  • Użytkownicy
Jak każdy z nas wie klasa C_NPC posiada tablice 5 stringów dla name lecz tylko jeden jest wykorzystywany.

Ci którzy próbowali wiedzą ze jeśli zrobimy to tak

name = "Wiesiek";
name[1] = "string1";
name[2] = "string2";
name[3] = "string3";
name[4] = "string4";

Nie będzie to działać i dalej będziemy używać tylko jednej zmiennej. Co z tym fantem zrobić ? Trzeba z edytować klase C_NPC

_Work\Data\Scripts\Content\_Intern\CLASSES.D
CLASS C_NPC
{
VAR INT     id ;
VAR STRING name [5] ;
...
Zmieniamy na
CLASS C_NPC
{
VAR INT     id ;
VAR STRING name ;//tu już nie mamy tablicy
VAR STRING name1 ;
VAR STRING name2 ;
VAR STRING name3 ;
VAR STRING name4 ;
...
W klasie dalej mamy 5 stringów więc silnik widzi poprawną wielkość klasy więc te błędy mamy z głowy ;)

Co więcej stringi mogą mieć nazwy jakie chcemy

CLASS C_NPC
{
VAR INT     id ;
VAR STRING name ;
VAR STRING to_jest_pierwszy_string ;
VAR STRING zaiste ;
VAR STRING name3 ;
VAR STRING name4 ;
...


Spoiler
Jeśli liczyć by ze stringi mogą przechowywać 255 znaków to można by ciąć stringi i zapisywać w nich zmienne liczbowe.

Licząc w ten sposób jeden string zmieści

85 zmiennych z zakresu 000 do 999
lub 255 zmiennych z zakresu od 0 do 1

więc 4 nowe zmieszczą 340 liczb od 000 do 999 ;d

Teraz chyba miejsca nie zabraknie ;d  wadą jest to ze nie ma funkcji zamiany stringa na inta więc trzeba by zamieniać po kolei int`y na stringi i porównywać ze sobą stringi ;d

P.S. na razie tylko uruchomiłem grę na 3 min więc nie wiem czy na 100 % te zmienne nie były używane ;d  ale gra się odpala ;d

Do tego jeśli ktoś nie wie to aivar`y nie są wykorzystywane do końca aivar[49],aivar[48],aivar[47], i jeszcze kilka (nie pamiętam do którego) też nie są wykorzystywane i mozemy w nich zapisać wartości liczbowe.


EDIT :

jedna wartość tekstowa = 5 wartości liczbowych

więc można zrobić też tak.
CLASS C_NPC
{
VAR INT     id ;
VAR STRING name ;
VAR STRING to_jest_pierwszy_string ;
VAR STRING zaiste ;
VAR INT tablica[5] ;
VAR STRING name4 ;
...

lub od razu tak ;d

CLASS C_NPC
{
VAR INT     id ;
VAR STRING name ;
VAR INT tablica[20] ;
...

EDIT 2 : (błąd)

Nie wiem co jeśli nie mamy ikarusa ale jeśli mamy MUSIMY zmienić klase oCNpc która zawiera w sobie C_NPC Edytujemy ją w ten sam sposób i dajemy takie same zmienne. Jeśli tego nie zrobimy przy wczytywaniu świata (przechodzeniu do 2) na etapie usuwania NPC gra się zawiesza. Nie mam pewności czy nie ma innych błędów o każdym znalezionym będę informował.

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator

inż. Avallach
Administrator

Dodatkowe zmienne w klasie C_NPC :D
#1 2012-03-24, 20:34(Ostatnia zmiana: 2012-06-20, 23:16)
Pisanie w tytule o rozszerzeniu klasy czy dodaniu do niej nowych zmiennych wprowadza w błąd. Nic takiego nie zrobiłeś - te pola tam były (nie wiem dlaczego nie dało się ich używać jeśli faktycznie tak jest), zmieniłeś tylko ich identyfikatory. Można tak zrobić z każdym, bo parser nie sprawdza nazw pól, tylko oblicza ich położenie w klasie po kolei na podstawie typów. Tak samo można zmienić "id" na "numerek" jeśli wszędzie w skryptach zrobisz to samo. Można też zmieniać typy danych dopóki rozmiar klasy będzie ten sam (w ten sposób można dodać więcej "mniejszych" pól kosztem tych "większych".

Po drugie, przechowywanie tam intów/booleanów to fatalny pomysł, zwłaszcza że z tego co napisałeś na gg chcesz je po prostu wprost przedstawiać jako kolejne znaki w stringu, a potem ciąć go i odmieniać z powrotem. Nie dość że wykorzystasz jedynie ułamek miejsca (każdy znak to już przynajmniej 4 bity, ty chcesz zapisać tam jeden), to jest to ogólnie wymaga to kosztownych obliczeniowo operacji na stringach.

W miarę możliwości dobrze jest korzystać z wolnych aivarów o których wspomniałeś.

//edit: Według Lehony, poniższe nie będzie w praktyce działać, tylko ciekawostka!
Spoiler
Jak przeczytałem ten temat, wpadłem też na inny patent - skoro identyfikatory w skryptach są liczbowymi indeksami instancji w tablicy parsera, można by je wykorzystywać właśnie w takim charakterze, co w praktyce powinno dać efekt podobny do rozszerzenia klasy (a właściwie dodania zmiennej niezależnej od klasy). Przykładowo jeśli chcemy dodać do klasy c_npc zmienną typu string "nazwisko", zamiast tego utwórzmy taką tablicę:
var string nazwisko [rozmiar];Rozmiar powinien być niestety bardzo duży, równy ilości wszystkich identyfikatorów w skryptach. Można go określić dodając w ostatnim parsowanym skrypcie dowolny, nawet pusty obiekt, a następnie gdzieś ze skryptów wywołując:
print (IntToString(instance_tego_obiektu));Kiedy już stworzymy tą tablicę, zamiast
pc_mage.nazwisko = "Plescott"; print (pc_mage.nazwisko);robimy:
nazwisko[pc_mage] = "Plescott"; print (nazwisko[pc_mage]);Nie wiąże się to z wykonywaniem żadnych pracochłonnych operacji przez silnik, jest banalne w wykonaniu i używaniu, równie proste co korzystanie z dodanego do klasy pola. A nawet nie zrozumienie tego dlaczego właściwie instance może być podane jako indeks tablicy, nie przeszkadza w normalnym korzystaniu z tego.

Lehona

Lehona

Użytkownicy
posty196
Propsy190
  • Użytkownicy
I'm sorry to interfere, but this is (partly) wrong. Even though this can technically be done, there are several problems. First of all, I think the parser doesn't like any bigger arrays than 2^12==4096, but I'm not 100% sure about that. The second, bigger problem is the following: The statically accessed index (as it is impossible to dynamically access indices without using some hacks to the engine like Ikarus does) will be writen into the bytecode - but there is only one byte reserved for it. The parser will throw no error message, but in the end you can only access the indices 0-255 of an array, calculating the actual index by index%256.
If you need more space in C_NPC you can do the following:
1st: Compress the AIVars:
Many of the AIVars used by PB only store boolean values. They can be compressed so that one AIVar can actually take up to 32 boolean values by using bitwise operations (I will explain further if someone needs it, it's a bit of work).

2nd: Use PermMem (there is no polish translation available yet) offered by LeGo. With PermMem you can store a handle inside one AIVar. The handle can then reference an (nearly) unlimited amount of space in memory.
 
Unless specified otherwise, my posts are always about Gothic 2 Night of the Raven.

FOgidel

FOgidel

Użytkownicy
posty60
Propsy100
ProfesjaSkrypter
  • Użytkownicy
Wiem, że wątek nie ruszany od dawna, ale wymyśliłem jak zrobić to, co chciał zrobić @Avallach (jak nie zadziała to mnie poprawcie).
Otóż wymyśliłem jak w 100% rozwiązać pierwszy problem. Wystarczy zrobić ileś tablic po 4000. Trzeba tylko zrobić w funkcji, żeby jeśli liczba (ten nasz identyfikator, czyli np. pc_mage.id jest większa niż 4000 to odejmie od niej 4000 (a jak większa niż 8000, to 8000 itd.) i użyje kolejnej tablicy.
Drugi problem (nie wiem, czy go dobrze rozumiem):
Tak, czy siak trzeba zrobić (już po pomniejszeniu liczby) coś takiego (musi być w funkcji):
const int stała = zmienna;Czyli po prostu tworzymy stałą, bo zmienna nie może być indeksem.

I otóż, jeśli dobrze rozumiem, ta tablica musi jednak mieć rozmiar 256, a nie 4096. To po prostu trochę więcej roboty (trzeba zrobić analogicznie). 16 razy więcej.
To tyle.
Bez żadnego Ikarusa, czy innych udziwnień.

Czy uważacie, że to mogłoby działać?
 

Mark56

Mark56

Moderator
som veľký magič
posty1632
Propsy1846
ProfesjaAnimator
  • Moderator
  • som veľký magič
 



FOgidel

FOgidel

Użytkownicy
posty60
Propsy100
ProfesjaSkrypter
  • Użytkownicy
Może być, gdy doda się podczas funkcji stałą, która równa się zmiennej to działa.

Edit:
Jednak możesz mieć rację, dziwne, bo mi chyba gdzieś działało. Może w G2NK. Teraz robię w G1 i nie może być.
 

Bogdan Zwei

Bogdan Zwei

Użytkownicy
Wulgarny skurwiel pierdolony.
posty1864
Propsy541
Profesjabrak
  • Użytkownicy
  • Wulgarny skurwiel pierdolony.
G1 i G2 to jest kompletnie ten sam silnik.
 
: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.

FOgidel

FOgidel

Użytkownicy
posty60
Propsy100
ProfesjaSkrypter
  • Użytkownicy
No wiem, wiem. Gdzieś coś zrobiłem i wydawało mi się, że działa. I tyle. Ale myślę, że coś wykombinuje (256 ifów na przykład) i dodam (ale raczej na targowisko)
 


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