diff --git a/MANUAL_EN.md b/MANUAL_EN.md index f803d1a..a5d772b 100644 --- a/MANUAL_EN.md +++ b/MANUAL_EN.md @@ -159,7 +159,7 @@ Only these points determine the order in the summary ## 6. And now for defensive weapons: * **White Flag** - causes the surrender of the player (can sometimes be useful in a hopeless situation). The advantage is that by surrendering you don't give a big point to your opponents and don't cause one of them to gain by killing us, you also limit the loss of your energy and also cash. An important note - this is the only defensive weapon that can be deactivated. All you have to do is re-enter inventory and once again select its activation. -* **Battery** - when activated, it recharges the tank's energy to full (99 units) and at the same time is the only defensive weapon that does not deactivate other defensive weapons when used. +* **Battery** - when activated, it recharges the tank's energy to full (99 units). It is one of three defensive weapons that does not deactivate other defensive weapons when used. * **Hovercraft** - a weapon that allows the tank to move. It has its own fuel supply in form of electric eels and in addition, it can be activated multiple times during the same turn, and after using it, you can activate another defensive weapon and fire a shot in the same turn. After using it, the tank rises above the mountains and using the cursor keys or a joystick you can move the tank to a new position. [SPACE] or the joystick button cause the tank to land in a new place. You can fly until the tank runs out of eels (presented on the status bar like the energy of a defensive weapon), if the eel fuel runs out the tank will fall down on its own. It is not possible to land on other tanks. * **Parachute** - does not protect against loss of energy due to a neighboring explosion, makes you not lose energy during ONE fall. After such a fall, it deactivates and a new parachute must be activated. * **Shield** - the simplest shield works exactly the opposite of **Parachute**, it does not protect against energy loss while falling, instead it protects against energy loss caused by ONE adjacent explosion. It protects once, no matter how strong the explosion is (whether tis but a scratch or a direct hit with a nuke), and deactivates immediately afterward. @@ -169,8 +169,10 @@ Only these points determine the order in the summary * **Mag Deflector** - the second passive-aggressive weapon :) . In case of a direct hit on a tank (and shield), it causes the hit point to move randomly to the left or right side of the protected tank, but not very far, so you can get "shrapnel" with stronger weapons. As in the case of **Bouncy Castle**, it is also a shield that corresponds to the action of **Heavy Shield** and has 99 units at the start (probably here we will have also to rethink this value and give a smaller one). * **Nuclear Winter** - adds nothing, takes nothing away :) - in fact, it is not so much a defensive weapon as a double-edged one. It floods the area with "radioactive" fallout, which is ordinary soil. If you do not have at hand any weapon that digs up the terrain, and for that a shield (preferably disposable), then after such "fallout" you will have to shoot yourself - because being underground is otherwise impossible. Alternatively, **White Flag** always remains. * **Long Schlong** - a special weapon :) - Costs a lot, doesn't really help with anything (except possibly digging yourself out but only when slightly buried but it has a cool name and looks cool :) - It can be activated independently of other defensive weapons and remains active until the end of the round (it cannot be deactivated). - -Due to the different operations of **MIRV**, defensive weapons **Bouncy Castle** and **Mag Deflector** only use the shielding function when hit by these weapons. In addition, **MIRV** heads do not bounce or fly through sidewalls during descent! +* **Lazy Boy** - it is not actually a defensive weapon. It is an aiming aid. When it is activated, the tank tries to aim at the nearest enemy and automatically adjusts the power of the shot and angle. If it has too little energy, it can sometimes aim wrong (it uses a method like **Cyborg** to aim). Like **Battery**, it does not deactivate other defensive weapons when used. Note: There is no point in activating this weapon before the round, targeting will not take place because there is nothing to target yet. +* **Lazy Darwin** - works exactly like **Lazy Boy** but targets the weakest opponent. +* **Auto Defense** - activates the mode of automatic activation of defensive weapons. After its activation, the tank automatically activates the strongest shield it has (consuming it, of course) at any time when there is no shield (also between shots of other players). At the same time, if the tank's energy level drops below 30 units, it automatically activates **Battery** if it has it. This weapon remains active until the end of the round and is indicated by the letter "A" before the name of the active defensive weapon in the status line. It is the second defensive weapon that does not deactivate other defensive weapons when used. +* **Spy Hard** - Help for the forgetful :) . When activated, it shows a preview of information about the next opponents one by one. Left/Right - changes the "spied" tank. Fire/Space/Return/Esc - ends the "spying". This is the last defensive weapon, which does not deactivate other defensive weapons when used. None of the shields protect against **Napalm**. **Bouncy Castle** or **Mag Deflector** on a direct hit will deflect it or carry it past, but just hit very close to a tank and its shield will not save it. diff --git a/MANUAL_PL.md b/MANUAL_PL.md index a2555da..ee188f9 100644 --- a/MANUAL_PL.md +++ b/MANUAL_PL.md @@ -3,7 +3,7 @@ Grać można przy użyciu klawiatury (wszystkie funkcjonalności) lub joysticka (wszystkie funkcjonalności niezbędne w rozgrywce). ## 1. Wybór opcji gry. -Na pierwszym ekranie możemy skonfigurować opcje rozgrywwki: +Na pierwszym ekranie możemy skonfigurować opcje rozgrywki: * ilość graczy (2 - 6) obejmuje tak ludzi jak graczy sterowanych przez komputer * początkową ilość gotówki każdego z graczy (8k to wybrana przez nas wartość optymalna, lecz przy krótkich rozgrywkach warto wybrać większą wartość) * grawitacja @@ -52,7 +52,8 @@ W linii statusowej widoczna jest informacja o tym który z graczy aktualnie moż * ustawiona przez gracza siła strzału (maksymalna siła strzału jest ograniczana przez energię gracza - nie może przekroczyć energii * 10 . Oznacza to, że mając małą ilość energii możemy oddać słabsze strzały * numer aktualnej rundy rozgrywki * prędkość i kierunek wiatru -* w nawiasie nazwę aktywnej broni defensywnej - jeśli jest jakaś aktywowana przez gracz +* symbol "A" jeśli aktywna jest **Auto Defense** +* w nawiasie nazwę aktywnej broni defensywnej - jeśli jest jakaś aktywowana przez gracza Tutaj klawiszologia jest prosta, klawisze kursora lub joystick: lewo/prawo - zmiana kąta nachylenia lufy, góra/dół - zmiana ustawienia siły strzału. @@ -64,7 +65,7 @@ Tutaj klawiszologia jest prosta, klawisze kursora lub joystick: lewo/prawo - zmi | [A] lub [OPTION] | [7] | bezpośrednie przejście na ekran Inventory aktywacji broni defensywnych. | | [M] | [PAUSE] | wyłączenie/włączenie muzyki w tle | | [S] | [RESET] | wyłączenie/włączenie dźwięków efektów. | -| [START] | brak | przyspiesza/pomimja niektóre animacje w grze | +| [START] | brak | przyspiesza/pomija niektóre animacje w grze | | [O] | [3] | wymuszenie zakończenia gry (Game Over). W podsumowaniu wyników nie jest brana pod uwagę przerwana właśnie runda rozgrywki, a wyłącznie rundy zakończone wcześniej. Odpowiada to wciśnięciu klawisza [ESC] z tą różnicą, że wyświetlane jest podsumowanie oraz creditsy. | | [START] + [OPTION] | brak | natychmiastowe wymuszenie zakończenia gry (Game Over), tak jak [O] ale bez potwierdzenia. | | [ESC] | [*] | w czasie całej gry w dowolnym momencie (chyba że akurat gra komputer, wtedy czasem trzeba chwilę poczekać) można nacisnąć klawisz [ESC], który umożliwia przerwanie gry i powrót na początek (oczywiście jest zabezpieczenie przed przypadkowym naciśnięciem). | @@ -116,8 +117,8 @@ Po eksplozji każdy czołg w jej zasięgu traci energię. Działa to tak, że jeśli trafienie jest dokładnie w centralny punkt czołgu `EnergyDecrease` otrzymuje maksymalną wartość dla danej broni, a z każdym pikselem odległości od centrum czołgu wartość ta jest zmniejszana o 8. -Przykładowo jeśli strzał oddany za pomocą broni Baby Missile trafi idelanie w centum czołgu to straci on dokładnie 88 jednostek energii (plus to co straci spadając po eksplozji). -W przypadku tafienia tą samą bronią w odległości 10ciu pikseli od centrum czołgu strata ta będzie wynośiła już tyko 8 jednostek. +Przykładowo jeśli strzał oddany za pomocą broni Baby Missile trafi idealnie w centum czołgu to straci on dokładnie 88 jednostek energii (plus to co straci spadając po eksplozji). +W przypadku trafienia tą samą bronią w odległości 10ciu pikseli od centrum czołgu strata ta będzie wynosiła już tyko 8 jednostek. A oto wartości maksymalnego ubytku energii dla poszczególnych broni. Jeśli broń eksploduje kilka razy, każda z eksplozji jest obliczana niezależnie (dodatkowe wartości w tabeli): @@ -157,18 +158,22 @@ Duże punkty otrzymane przez gracza to ilość czołgów, które zginęły wcze Tylko te punkty decydują o kolejności w podsumowaniu ## 6. A teraz bronie defensywne: -* **White Flag** - powoduje poddanie gracza (może czasem przydać się w sytuacji beznadziejnej). Zaletą jest to, że poddając się nie dajemy dużego punktu przeciwnikom i nie powodujemy, że któryś zyska na tym, że nas zgładzi, ograniczamy też stratę swojej energii czyli także kasy. I tu także ważna uwaga - to jedyna broń defensywna, którą można deaktywować. Wystarczy ponownie wejść do inventory i jeszcze raz wybrać jej aktywację. -* **Battery** - w momencie aktywacji doładowuje energię czołgu do pełna (99 jednostek) i jednocześnie jest to jedyna broń defensywna, która nie deaktywuje innych broni defensywnych w przypadku jej użycia. +* **White Flag** - powoduje poddanie gracza (może czasem przydać się w sytuacji beznadziejnej). Zaletą jest to, że poddając się nie dajemy dużego punktu przeciwnikom i nie powodujemy, że któryś zyska na tym, że nas zgładzi, ograniczamy też stratę swojej energii czyli także kasy. I tu także ważna uwaga - to jedyna broń defensywna, którą można dezaktywować. Wystarczy ponownie wejść do inventory i jeszcze raz wybrać jej aktywację. +* **Battery** - w momencie aktywacji doładowuje energię czołgu do pełna (99 jednostek). Jest to jedna z trzech broni defensywnych, która nie dezaktywuje innych broni defensywnych w przypadku jej użycia. * **Hovercraft** - broń umożliwiająca przemieszczanie się czołgu. Posiada własny zasób paliwa a dodatkowo może być aktywowana wielokrotnie w czasie tej samej tury, a po jej użyciu możemy w tej samej turze aktywować inną broń defensywną i oddać strzał. Po jej użyciu czołg uniesie się ponad góry i za pomocą klawiszy kursora lub joysticka: lewo/prawo możemy przemieścić czołg na nową pozycję a [SPACJA] lub przycisk joysticka powodują wylądowanie czołgu w nowym miejscu. Latać można do chwili skończenia się "paliwa" (prezentowanego na pasku statusu tak jak energia broni defensywnej), jeśli paliwo się skończy czołg opadnie samodzielnie. Nie da się lądować na innych czołgach. -* **Parachute** - nie chroni przed ubytkiem energii z powodu sąsiedniej eksplozji, powoduje że nie ubywa energii w czasie JEDNEGO spadania. Po takim upadku deaktywuje się i trzeba aktywować nowy spadochron. -* **Strong Parachute** - spadochron z własną energią (na starcie 99 jednostek), działa tak samo jak Parachute (nie chroni przed eksplozjami) ma za to swój własny zasób energii przy spadaniu w pierwszej kolejności zmniejszana jest energia tego spadochronu (1 jednostka na jeden pixel opadania - inaczej niż czołg!) i jeśli dojdzie ona do 0 to spadochron deaktywuje się i dalej zmniejszana jest energia czołgu (tutaj już standardowo - 2 jednoski na jeden pikxel). -* **Shield** - najprostsza osłona działa dokładnie przeciwnie niż Parachute, nie chroni przed ubytkiem energii w czasie spadania, chroni za to przed ubytkiem energii spowodowanym JEDNĄ sąsiednią eksplozją. Chroni jednorazowo, bez znaczenia jak silna jest eksplozja (czy jest to tylko "draśnięcie", czy też bezpośrednie trafienie atomówką) i od razu po niej deaktywuje się. -* **Heavy Shield** - osłona z własną energią (na starcie 99 jednostek), działa tak samo jak Shield (nie chroni przed upadkiem) z tym wyjątkiem, że ma własny zasób energii. Przy eksplozji w pierwszej kolejności zmniejszana jest energia tej osłony i jeśli dojdzie ona do 0 to osłona deaktywuje się i dalej zmniejszana jest energia czołgu. W związku z takim działaniem, czołg z tym typem osłony można "zabić" podkopując go, bo spadanie zmniejsza energię czołgu a nie osłony. +* **Parachute** - nie chroni przed ubytkiem energii z powodu sąsiedniej eksplozji, powoduje że nie ubywa energii w czasie JEDNEGO spadania. Po takim upadku dezaktywuje się i trzeba aktywować nowy spadochron. +* **Strong Parachute** - spadochron z własną energią (na starcie 99 jednostek), działa tak samo jak Parachute (nie chroni przed eksplozjami) ma za to swój własny zasób energii przy spadaniu w pierwszej kolejności zmniejszana jest energia tego spadochronu (1 jednostka na jeden pixel opadania - inaczej niż czołg!) i jeśli dojdzie ona do 0 to spadochron dezaktywuje się i dalej zmniejszana jest energia czołgu (tutaj już standardowo - 2 jednostki na jeden pikxel). +* **Shield** - najprostsza osłona działa dokładnie przeciwnie niż Parachute, nie chroni przed ubytkiem energii w czasie spadania, chroni za to przed ubytkiem energii spowodowanym JEDNĄ sąsiednią eksplozją. Chroni jednorazowo, bez znaczenia jak silna jest eksplozja (czy jest to tylko "draśnięcie", czy też bezpośrednie trafienie atomówką) i od razu po niej dezaktywuje się. +* **Heavy Shield** - osłona z własną energią (na starcie 99 jednostek), działa tak samo jak Shield (nie chroni przed upadkiem) z tym wyjątkiem, że ma własny zasób energii. Przy eksplozji w pierwszej kolejności zmniejszana jest energia tej osłony i jeśli dojdzie ona do 0 to osłona dezaktywuje się i dalej zmniejszana jest energia czołgu. W związku z takim działaniem, czołg z tym typem osłony można "zabić" podkopując go, bo spadanie zmniejsza energię czołgu a nie osłony. * **Force Shield** - najmocniejsza osłona - działa tak jak Heavy Shield tyle że połączona z Parachute. Co ważne w jej przypadku upadek nie zabiera energii osłonie ani czołgowi. Zabierają ją tylko trafienia. -* **Bouncy Castle** - broń agresywna :) . Działa następująco. W przypadku bezpośredniego trafienia w czołg (i osłonę) powoduje "odbicie" pocisku w przeciwnym kierunku z tą samą siłą z jaką był wystrzelony. W przypadku braku wiatru i różnicy poziomów broń trafia wtedy w czołg, który ją wystrzelił. Po takim odbiciu deaktywuje się. W związku z tym, że broń ta reaguje w ten sposób tylko na precyzyjne trafienia, jest także osłoną odpowiadającą działaniu Heavy Shield i ma na starcie 99 jednostek (prawdopodobnie trzeba będzie przemyśleć tę wartość i dać tu mniejszą). +* **Bouncy Castle** - broń agresywna :) . Działa następująco. W przypadku bezpośredniego trafienia w czołg (i osłonę) powoduje "odbicie" pocisku w przeciwnym kierunku z tą samą siłą z jaką był wystrzelony. W przypadku braku wiatru i różnicy poziomów broń trafia wtedy w czołg, który ją wystrzelił. Po takim odbiciu dezaktywuje się. W związku z tym, że broń ta reaguje w ten sposób tylko na precyzyjne trafienia, jest także osłoną odpowiadającą działaniu Heavy Shield i ma na starcie 99 jednostek (prawdopodobnie trzeba będzie przemyśleć tę wartość i dać tu mniejszą). * **Mag Deflector** - druga broń agresywna :) . W przypadku bezpośredniego trafienia w czołg (i osłonę) powoduje przesunięcie punktu trafienia losowo w lewo lub prawą stronę chronionego czołgu, ale niezbyt daleko, więc można dostać "odłamkiem" przy silniejszej broni. Tak jak w przypadku Bouncy Castle jest także osłoną odpowiadającą działaniu Heavy Shield i ma na starcie 99 jednostek (prawdopodobnie i tutaj trzeba będzie przemyśleć tę wartość i dać mniejszą). * **Nuclear Winter** - nic nie dodaje, nic nie zabiera :) - w zasadzie to broń nie tyle defensywna co obosieczna. Zasypuje teren opadem "radioaktywnym", który jest zwyczajną glebą. Jeśli nie mamy pod ręką żadnej broni odkopującej teren i do tego osłony (najlepiej jednorazowej), to po takim "opadzie" będzie trzeba strzelić do siebie - bo będąc pod ziemią inaczej się nie da. Ewentualnie pozostaje zawsze White Flag. -* **Long Schlong** - broń specjalna :) - kosztuje dużo, nie bardzo w czymkolwiek pomaga (poza ewentualnym odkopaniem się ale tylko przy niewielkim przysypaniu ale fajnie się nazywa i wygląda :) - Można ją aktywować niezależnie od innych broni defensywnych i pozostaje aktywna do końca rundy (nie da się jej deaktywować). +* **Long Schlong** - broń specjalna :) - kosztuje dużo, nie bardzo w czymkolwiek pomaga (poza ewentualnym odkopaniem się ale tylko przy niewielkim przysypaniu ale fajnie się nazywa i wygląda :) - Można ją aktywować niezależnie od innych broni defensywnych i pozostaje aktywna do końca rundy (nie da się jej dezaktywować). +* **Lazy Boy** - nie jest to właściwie broń defensywna. Jest to wspomaganie celowania. Po jej aktywacji czołg stara się wycelować w najbliższego przeciwnika i automatycznie ustawia siłę strzału oraz kąt. W przypadku posiadania zbyt małej ilości energii może czasem wycelować źle (do celowania stosuje metodę taką jak **Cyborg**). Tak jak **Battery** nie dezaktywuje innych broni defensywnych w przypadku jej użycia. Uwaga! Nie ma sensu aktywacja tej broni przed rundą, celowanie nie odbędzie się bo nie ma jeszcze do czego celować. +* **Lazy Darwin** - działa dokładnie jak **Lazy Boy** ale celuje w najsłabszego przeciwnika. +* **Auto Defense** - włącza tryb automatycznej aktywacji broni defensywnych. Po jej aktywowaniu czołg automatycznie aktywuje najmocniejszą posiadaną osłonę (zużywając ją oczywiście) w każdej chwili, kiedy nie ma żadnej osłony (także pomiędzy strzałami innych graczy). Jednocześnie jeżeli poziom energii czołgu spadnie poniżej 30 jednostek, automatycznie aktywuje **Battery** jeżeli ją posiada. Ta broń pozostaje aktywna do końca rundy i jest sygnalizowana literą "A" przed nazwą aktywnej broni defensywnej w linii statusowej. Jest to druga broń defensywna, która nie dezaktywuje innych broni defensywnych w przypadku jej użycia. +* **Spy Hard** - Pomoc dla zapominalskich :) . Po aktywacji pokazuje kolejno podgląd informacji o kolejnych przeciwnikach. Lewo/Prawo - zmienia "szpiegowany" czołg. Fire/Space/Return/Esc - kończy "szpiegowanie". Jest to ostatnia broń defensywna, która nie dezaktywuje innych broni defensywnych w przypadku jej użycia. W związku z odmiennym działaniem broni **MIRV**, bronie defensywne **Bouncy Castle** i **Mag Deflector** wykorzystują tylko funkcję osłony przy trafieniu tą bronią. Dodatkowo głowice **MIRV** w czasie opadania nie odbijają się i nie przelatują przez ściany boczne! @@ -182,7 +187,7 @@ Oczywiście aktywacja broni w momencie kiedy mamy już aktywowaną jakąś inną ## 7. Bronie 'inne' :) : -* **Buy me!** - tej 'broni' nie można używać w rozgrywce. Jej zakup powoduje wylosowanie jesdnej z broni ofensywnych lub (żadziej) defensywnych i dodanie jej do arsenału gracza. Jest to loteria w której można stracić (jeśli wylosuje się broń tańsza niż cena **Buy Me!** ale też zyskać. Jeśli wylosuje się broń dużo droższa możemy otrzymać do dyspozycji broń, na którą nie było nas stać! +* **Buy me!** - tej 'broni' nie można używać w rozgrywce. Jej zakup powoduje wylosowanie jednej z broni ofensywnych lub (rzadziej) defensywnych i dodanie jej do arsenału gracza. Jest to loteria w której można stracić (jeśli wylosuje się broń tańsza niż cena **Buy Me!** ale też zyskać. Jeśli wylosuje się broń dużo droższa możemy otrzymać do dyspozycji broń, na którą nie było nas stać! ## 8. Poziomy trudności przeciwników sterowanych przez komputer: diff --git a/README.md b/README.md index 35a633e..ff5c14b 100644 --- a/README.md +++ b/README.md @@ -51,19 +51,40 @@ With the advent of [fujinet](https://fujinet.online/) we are thinking about maki ## Changelog: +###### Version 1.18 +2022-11-04 + +This is the final round of weapon additions! Also. our beloved testers and players found a number of issues and we were extremely happy to address them. +* New defensive weapon "Lazy Boy" - aims at the closest enemy. +* New defensive weapon "Lazy Darwin" - aims at the weakest link, an enemy I mean. +* New defensive weapon "Auto Defense" - activate it to be automatically protected by shields and stuff (where available) +* New defensive weapon "Spy Hard" - quickly view energies, weapons and shields of your opponents. +* New SFXes, improvements in SFX, and music by @mikerro +* Shooting with angle 0 caused the sudden death of the operator. Fixed. +* Angles were asymmetrical, now you can go from 0 to 90 and to 0 again (181 degrees of freedom). Fixed with an improved arithmetic rounding of our sub-pixel accuracy. +* Drawing a barrel when a tank was on the edge of X==256 pixels caused a lonely pixel to appear randomly. Fixed. +* Liquid Dirt was overflowing from the right edge of the screen to the left. Fixed. +* Liquid Dirt volume increased significantly, it is now a formidable attack! +* A single pixel was erroneously plotted when measuring distance (was visible in e.g., Death's Head). Fixed. +* Not all traces were correctly erased after Funky Bomb, fixed again (for the 3rt time I guess). +* Soil sedimentation speed after Funky Bomb improved. +* Pressing [ESC] when in inventory/store was quitting the game, now it quits the menu only. +* BIGGEST OF ALL: the lonely pixel after Nuclear Winter was eliminated. https://github.com/pkali/scorch_src/issues/103 We have spent a disproportionately large amount of time trying to slap this bug. It is still there, but is not manifesting itself ;) + + ###### Version 1.18 2022-11-07 Possibly the final single-player version of the game, unless our dear players find another breaking issue! -* 5200 keypad works as it should. You can now press these finicky foils to your hearth's desire. +* 5200 keypad works as it should. You can now press these finicky foils to your heart's desire. * "Unknown" type Robotanks were attacking with Nuclear Winter every time. Fixed! -* One of variables was declared as a byte but used as a word which might cause some rare instabilities. +* One of the variables was declared as a byte but used as a word that might cause some rare instabilities. * Page zero variables are cleared prior to the game start to eliminate rare issues in some software/hardware configurations. * The new version of music in NTSC eliminates issues with tempo (not that anyone but the artist noticed that, but still it is an improvement!) * You can now wrap around inventory and shop to faster access these options far down below. * Visual improvement of the main menu and fixed some color issues with the title headers. * Hovercraft was always flying to the top of the screen, it was not intended, it is now hovering just above the mountains! -* The main menu does not blink now when changing options. This was a very minor thing but it bothered me to some extend. Fixing it required a complete rewrite of this portion of the menu. +* The main menu does not blink now when changing options. This was a very minor thing but it bothered me to some extent. Fixing it required a complete rewrite of this portion of the menu. ###### Version 1.17 diff --git a/ai.asm b/ai.asm index 2006d6c..2bc6970 100644 --- a/ai.asm +++ b/ai.asm @@ -22,9 +22,11 @@ pha lda AIRoutines,y pha - + jsr PrepareAIShoot + rts +.endp ;---------------------------------------------- -;.proc MakeLowResDistances +.proc PrepareAIShoot ; create low precision table of positions ; by dividing positions by 4 ldy #MaxPlayers-1 @@ -39,11 +41,10 @@ loop sta LowResDistances,y dey bpl loop -; rts -;.endp ; common values used in AI routines ; address of weapons table (for future use) +WepTableToTemp lda TanksWeaponsTableL,x sta temp lda TanksWeaponsTableH,x @@ -210,6 +211,19 @@ AngleTable ; 16 bytes ;ba w $348b L$3350 .endp ;---------------------------------------------- .proc UseBatteryOrFlag + jsr UseBattery ; as subroutine for reuse in AutoDefense + ; if very low energy and no battery then use White Flag + lda Energy,x + cmp #5 + bcs EnoughEnergy + ; lower than 5 units - white flag + lda #ind_White_Flag_____ + sta ActiveDefenceWeapon,x +EnoughEnergy + rts +.endp +; +.proc UseBattery ; if low energy ten use battery lda Energy,x cmp #30 @@ -219,20 +233,13 @@ AngleTable ; 16 bytes ;ba w $348b L$3350 lda (temp),y ; has address of TanksWeaponsTable beq NoBatteries ; we have batteries - use one - clc + sec sbc #1 sta (temp),y lda #99 sta Energy,x -NoBatteries - ; if very low energy and no battery then use White Flag - lda Energy,x - cmp #5 - bcs EnoughEnergy - ; lower than 5 units - white flag - lda #ind_White_Flag_____ - sta ActiveDefenceWeapon,x EnoughEnergy +NoBatteries rts .endp ;---------------------------------------------- @@ -245,15 +252,15 @@ EnoughEnergy ; first check check if any is in use lda ActiveDefenceWeapon,x bne DefensiveInUse - ldy #last_defensive_____+1 ;the last defensive weapon + ldy #last_real_defensive+1 ;the last defensive weapon @ dey - cpy #ind_Battery________ ;first defensive weapon (White Flag and Battery - never use) + cpy #ind_Hovercraft_____ ;first defensive weapon (White Flag, Battery and Hovercraft - never use) beq NoUseDefensive lda (temp),y ; has address of TanksWeaponsTable beq @- ; decrease in inventory - clc + sec sbc #1 sta (temp),y ; has address of TanksWeaponsTable ; activate defensive weapon @@ -280,15 +287,15 @@ DefensiveInUse ; first check check if any is in use lda ActiveDefenceWeapon,x bne DefensiveInUse - ldy #last_defensive_____+1 ;the last defensive weapon + ldy #last_real_defensive+1 ;the last defensive weapon @ dey - cpy #ind_Battery________ ;first defensive weapon (White Flag and Battery - never use) + cpy #ind_Hovercraft_____ ;first defensive weapon (White Flag, Battery and Hovercraft - never use) beq NoUseDefensive lda (temp),y ; has address of TanksWeaponsTable beq @- ; decrease in inventory - clc + sec sbc #1 sta (temp),y ; has address of TanksWeaponsTable ; activate defensive weapon @@ -575,7 +582,7 @@ skipThisPlayer asl tay ; force correction - lower tank Y position - higher possible force - clc + sec lda #screenheight sbc Ytankstable,x sta temp2 diff --git a/artwork/sfx/scorch_str6.rmt b/artwork/sfx/scorch_str6.rmt deleted file mode 100644 index fcdc1a2..0000000 Binary files a/artwork/sfx/scorch_str6.rmt and /dev/null differ diff --git a/artwork/sfx/scorch_str6-NTSC.rmt b/artwork/sfx/scorch_str8-NTSC.rmt similarity index 50% rename from artwork/sfx/scorch_str6-NTSC.rmt rename to artwork/sfx/scorch_str8-NTSC.rmt index 6063645..788e26b 100644 Binary files a/artwork/sfx/scorch_str6-NTSC.rmt and b/artwork/sfx/scorch_str8-NTSC.rmt differ diff --git a/artwork/sfx/scorch_str8.rmt b/artwork/sfx/scorch_str8.rmt new file mode 100644 index 0000000..f57f432 Binary files /dev/null and b/artwork/sfx/scorch_str8.rmt differ diff --git a/artwork/sfx/scorch_str9-NTSC.rmt b/artwork/sfx/scorch_str9-NTSC.rmt new file mode 100644 index 0000000..7454f22 Binary files /dev/null and b/artwork/sfx/scorch_str9-NTSC.rmt differ diff --git a/artwork/weapons_AW6_mod.fnt b/artwork/weapons_AW6_mod.fnt index 577e581..251c7c7 100644 Binary files a/artwork/weapons_AW6_mod.fnt and b/artwork/weapons_AW6_mod.fnt differ diff --git a/constants.asm b/constants.asm index 68d4cba..c9972fe 100644 --- a/constants.asm +++ b/constants.asm @@ -274,7 +274,10 @@ WeaponPriceH ; weapons prices (tables with prices of weapons) .by >price_Bouncy_Castle__ .by >price_Long_Barrel____ .by >price_Nuclear_Winter_ - + .by >price_Lazy_Boy_______ + .by >price_Lazy_Darwin____ + .by >price_Auto_Defense___ + .by >price_Spy_Hard_______ WeaponPriceL .by $06 + mva #$10 MODUL-6+$a69 ; $12 > $10 + mva #$06 MODUL-6+$bc3 ; $07 > $06 + mva #$04 MODUL-6+$bf8 ; $05 > $04 + mva #$08 MODUL-6+$e3d ; $0a > $08 + mva #$06 MODUL-6+$e69 ; $08 > $06 + mva #$06 MODUL-6+$ebc ; $08 > $06 NoRMT_PALchange .ELSE mva #$7f SkStatSimulator @@ -324,9 +324,11 @@ MainGameLoop jsr SetWallsType ; first set default barrel lengths (fix for Long Schlong activation :) ) ; we must do it before purchase/activate + ; and set Auto Defense to off jsr SetStandardBarrels jsr CallPurchaseForEveryTank + mva #0 SpyHardFlag ; issue #72 (glitches when switches) jsr MakeDarkScreen @@ -612,6 +614,20 @@ DoNotFinishTheRound jmp Seppuku @ + ; Auto Defense - activates defensives + ldx NumberOfPlayers + dex +CheckNextTankAD + lda Energy,x ; only active players + beq @+ + lda AutoDefenseFlag,x ; with Auto Defence activated + beq @+ + ; run auto defense for tank in X + jsr AutoDefense +@ dex + bpl CheckNextTankAD + jsr DrawTanks ; redraw tanks witch new defences +; ldx TankSequencePointer lda TankSequence,x sta TankNr @@ -1129,8 +1145,10 @@ MakeTanksVisible ;-------------------------------------------------- .proc SetStandardBarrels ldx #maxPlayers-1 - lda #StandardBarrel ; standard barrel length -@ sta BarrelLength,x +@ lda #StandardBarrel ; standard barrel length + sta BarrelLength,x + lda #$00 ; deactivate Auto Defense + sta AutoDefenseFlag,x dex bpl @- rts @@ -1664,7 +1682,7 @@ SetRandomWalls and #$3f ;CTRL and SHIFT ellimination cmp #@kbcode._esc ; 28 ; ESC bne getkeyend - mvx #$80 escFlag + mvy #$80 escFlag bne getkeyend checkJoyGetKey @@ -1686,9 +1704,9 @@ notpressedJoyGetKey lda #@kbcode._ret ;Return key getkeyend - ldx #0 - stx ATRACT ; reset atract mode - mvx #sfx_keyclick sfx_effect + ldy #0 + sty ATRACT ; reset atract mode + mvy #sfx_keyclick sfx_effect rts .endp @@ -1886,23 +1904,26 @@ noingame TankFont ins 'artwork/tanksv3.fnt',+0,352 ; 44 characters only ;---------------------------------------------- - -;RMT PLAYER and song loading shenaningans - icl 'artwork/sfx/rmtplayr_modified.asm' - org $b000 -MODUL ; equ $b000 ;address of RMT module - ;opt h- ;RMT module is standard Atari binary file already - ins "artwork/sfx/scorch_str6-NTSC.rmt",+6 ;include music RMT module - ;opt h+ -MODULEND -;---------------------------------------------- font4x4 ins 'artwork/font4x4s.bmp',+62 - +;---------------------------------------------- +;RMT PLAYER and song loading shenaningans + icl 'artwork/sfx/rmtplayr_modified.asm' + .IF * > MODUL-1 + .ERROR 'Code and data too long' + .ENDIF + .ECHO "Bytes left: ",$b000-* + + + org $b000 ;address of RMT module +MODUL + ;RMT module is standard Atari binary file already + ins "artwork/sfx/scorch_str9-NTSC.rmt",+6 ;include music RMT module +MODULEND ;---------------------------------------------- .IF target = 5200 .IF * > ROM_SETTINGS-1 - .ERROR 'Code too long to fit in 5200' + .ERROR 'Code and RMT song too long to fit in 5200' .ENDIF org ROM_SETTINGS ; 5200 ROM settings address $bfe8 ; "01234567890123456789" diff --git a/scorch.bin b/scorch.bin index 3f7d277..dd0e065 100644 Binary files a/scorch.bin and b/scorch.bin differ diff --git a/scorch.xex b/scorch.xex index 9c4fcd4..233331c 100644 Binary files a/scorch.xex and b/scorch.xex differ diff --git a/textproc.asm b/textproc.asm index 5154f0b..6a06c05 100644 --- a/textproc.asm +++ b/textproc.asm @@ -387,7 +387,10 @@ ChoosingItemForPurchase jsr PutLitteChar ; Places pointer at the right position jsr getkey bit escFlag - spl:jmp WaitForKeyRelease ; like jsr ... : rts + bpl @+ + mva #0 escFlag + jmp WaitForKeyRelease ; like jsr ... : rts +@ cmp #@kbcode._tab ; $2c ; Tab jeq ListChange cmp #@kbcode._left ; $06 ; cursor left @@ -848,6 +851,40 @@ invSelectDef ply jmp DecreaseDefensive ; bypass activation NotBattery + cmp #ind_Auto_Defense___ + bne NoAutoDefense + ; Auto Defense - do it like battery + mva #sfx_auto_defense sfx_effect + mva #$A1 AutoDefenseFlag,x ; this is "A" in inverse - for status line :) + jmp DecreaseDefensive ; bypass activation +NoAutoDefense + cmp #ind_Lazy_Boy_______ + bne NoLazyBoy + ; Lazy Boy - do it like battery + mva #sfx_lazy_boys sfx_effect + phy + jsr PrepareAIShoot + jsr FindBestTarget2 ; find nearest tank neighbour + jsr LazyAim + ply + jmp DecreaseDefensive ; bypass activation +NoLazyBoy + cmp #ind_Lazy_Darwin____ + bne NoLazyDarwin + ; Lazy Darwin - do it like battery + mva #sfx_lazy_boys sfx_effect + phy + jsr PrepareAIShoot + jsr FindBestTarget3 ; find target with lowest energy + jsr LazyAim + ply + jmp DecreaseDefensive ; bypass activation +NoLazyDarwin + cmp #ind_Spy_Hard_______ + bne NotSpy + mva #$ff SpyHardFlag + jmp DecreaseDefensive ; bypass activation +NotSpy cmp #ind_Long_Barrel____ bne NotBarrel ; if activate long barrel, we do it differently too @@ -886,6 +923,22 @@ DefActivationEnd jmp WaitForKeyRelease ; rts .endp +.proc LazyAim + ; aiming proc for Lazy ... weapons + ; as proc for memory optimisation + ; Y - target tan nr + ; A - target direction + sty TargetTankNr + ; aiming + jsr TakeAim ; direction still in A (0 - left, >0 - right) + lda Force + sta ForceTableL,x + lda Force+1 + sta ForceTableH,x + lda NewAngle + sta AngleTable,x + rts +.endp ; ----------------------------------------------------- .proc calcPosDefensive ; calculate positionOnTheList from the activeWeapon (defensives) @@ -1745,13 +1798,9 @@ EndOfTypeLine4x4 jsr TL4x4_top adb ResultY #4 ;next line - ;seppuku + ;sure? mwa #areYouSureText LineAddress4x4 - mwa #((ScreenWidth/2)-(8*4)) LineXdraw ; centering - mva ResultY LineYdraw - jsr TypeLine4x4 - adb ResultY #4 ;next line - + jsr _sep_opty ;bottom frame mva ResultY LineYdraw jsr TL4x4_bottom @@ -1772,17 +1821,22 @@ skip01 @ mva #$ff plot4x4color mwa #lineClear LineAddress4x4 - mwa #((ScreenWidth/2)-(8*4)) LineXdraw ; centering - mva ResultY LineYdraw - jsr TypeLine4x4 - adb ResultY #4 ;next line - + jsr _sep_opty dec di bne @- quit_areyousure rts .endp + +.proc _sep_opty + mwa #((ScreenWidth/2)-(8*4)) LineXdraw ; centering + mva ResultY LineYdraw + jsr TypeLine4x4 + adb ResultY #4 ;next line + rts +.endp + ;-------------------------------- .proc DisplaySeppuku ;using 4x4 font @@ -1803,11 +1857,8 @@ seppuku_loop ;seppuku mwa #seppukuText LineAddress4x4 - mwa #((ScreenWidth/2)-(8*4)) LineXdraw ; centering - mva ResultY LineYdraw - jsr TypeLine4x4 - adb ResultY #4 ;next line - + jsr _sep_opty + ;bottom frame mva ResultY LineYdraw jsr TL4x4_bottom ; just go @@ -1815,22 +1866,22 @@ seppuku_loop ;clean seppuku mva #3 di - mva #4 ResultY -@ + ;mva #4 ResultY + lda #4 + sta ResultY +loplop ;@ mwa #lineClear LineAddress4x4 - mwa #((ScreenWidth/2)-(8*4)) LineXdraw ; centering - mva ResultY LineYdraw - jsr TypeLine4x4 - adb ResultY #4 ;next line + jsr _sep_opty dec di - bne @- + bne loplop ;@- dec fs jne seppuku_loop quit_seppuku rts + .endp ;-------------------------------- .proc DisplayResults ; @@ -2305,6 +2356,8 @@ EndOfCredits ;--------------------- ;displaying name of the defence weapon (if active) ;--------------------- + lda AutoDefenseFlag,x ; Auto Defense symbol (space or "A" in inverse) + sta statusBuffer+80+21 lda #$08 ; ( sta statusBuffer+80+22 lda #$09 ; ) diff --git a/variables.asm b/variables.asm index 9098334..1400733 100644 --- a/variables.asm +++ b/variables.asm @@ -126,7 +126,9 @@ BarrelLength ;length of the tank barrel - dont forget to set it to 6 at round st ActiveWeapon ;number of the selected weapon .DS MaxPlayers ActiveDefenceWeapon ;number of the activated defence weapon - 0 - .DS MaxPlayers + .DS MaxPlayers +AutoDefenseFlag ; 0 - not activated, >$7f - activated + .DS MaxPlayers WeaponDepleted .DS 1 ; if 0 deactivate the weapon and switch to Baby Missile ;---------------------------------------------------- @@ -162,6 +164,8 @@ TargetTankNr ; Target tank index (for AI routines) .DS 1 SecondTryFlag ; For precise AI aiming .DS 1 +SpyHardFlag ; >$7f - run SpyHard after inventory + .DS 1 ;---------------------------------------------------- ;Erase .DS 1 ; if 1 only mask of the character is printed ; on the graphics screen. if 0 character is printed normally diff --git a/weapons.asm b/weapons.asm index 8e12e4c..bb23a23 100644 --- a/weapons.asm +++ b/weapons.asm @@ -152,8 +152,8 @@ EndOfLeapping jsr SoilDown2 ; jsr cleartanks ; maybe not? - sta FunkyWallFlag mva #1 color + mva #0 FunkyWallFlag mva #5 FunkyBombCounter FunkyBombLoop mva #1 tracerflag @@ -172,7 +172,19 @@ FunkyBombLoop mwa ytrajfb ytraj+1 mva #sfx_funky_hit sfx_effect jsr Flight - + mva #0 ExplosionRadius ; if no explosion (off screen) + ; if xdraw if over range then fix it + lda xdraw+1 + bpl NoOnLeftEdge + lda #0 + sta xdraw + sta xdraw+1 +NoOnLeftEdge + cpw xdraw #screenwidth + bcc NoOnRightEdge + mwa #screenwidth xdraw +NoOnRightEdge + jsr CalculateExplosionRange ; add end of flight coordinates to soildown range lda HitFlag beq NoExplosionInFunkyBomb mva #sfx_baby_missile sfx_effect @@ -589,7 +601,7 @@ DiggerCharacter ; ------------------------ .proc liquiddirt mva #sfx_liquid_dirt sfx_effect - mwa #254 FillCounter + mwa #510 FillCounter jmp xliquiddirt .endp ; ------------------------ @@ -1032,7 +1044,7 @@ UpNotYet2 beq FillNow HowMuchToFallRight3 inw xdraw - cpw xdraw #(screenwidth+1) + cpw xdraw #screenwidth jne RollinContinuesLiquid FillNow ; finally one pixel more @@ -1163,12 +1175,16 @@ callInventory jsr Purchase afterInventory jsr MakeDarkScreen - RmtSong song_ingame - mva #0 escFlag jsr DisplayStatus jsr SetMainScreen jsr WaitOneFrame jsr DrawTanks + bit SpyHardFlag + bpl NoSpyHard + jsr SpyHard +NoSpyHard + RmtSong song_ingame + mva #0 escFlag jsr WaitForKeyRelease jmp BeforeFire @ @@ -1305,11 +1321,10 @@ pressedRight mva #sfx_set_power_2 sfx_effect mva #1 Erase jsr DrawTankNr.BarrelChange - dec AngleTable,x - lda AngleTable,x - cmp #255 ; -1 + dec:lda AngleTable,x + cmp #255 ; -1 jne BeforeFire - lda #179 + lda #180 sta AngleTable,x jmp BeforeFire @@ -1324,7 +1339,7 @@ CTRLPressedRight sta AngleTable,x cmp #4 ; smallest angle for speed rotating jcs BeforeFire - lda #179 + lda #180 sta AngleTable,x jmp BeforeFire @@ -2418,7 +2433,63 @@ InverseScreenByte sta (temp),y rts .endp - +; ------------------------------------------------- +.proc AutoDefense +; ------------------------------------------------- +; This routine is run from inside of the main loop +; X - index of tank +; ------------------------------------------------- + jsr PrepareAIShoot.WepTableToTemp + jsr UseBattery + jsr TosserDefensives + rts +.endp +; ------------------------------------------------- +.proc SpyHard +; ------------------------------------------------- + mvx TankNr TargetTankNr ; save +RepeatSpy + mvx #0 TankNr +CheckNextTankSH + cpx TargetTankNr + beq ThisTankItsMe + lda Energy,x ; only active players + beq ThisTankIsDead + ; run SpyHard for tank in X + jsr DisplaySpyInfo + jsr FlashTank +@ jsr GetKey + bit escFlag + bmi SpyHardEnd + cmp #@kbcode._space ; $21 ; Space + beq SpyHardEnd + cmp #@kbcode._ret ; Return key (5200 - fire) + beq SpyHardEnd + cmp #@kbcode._left ; $6 + beq SelectNextTank + cmp #@kbcode._right ; $07 ; cursor right + bne @- +ThisTankIsDead +ThisTankItsMe +SelectNextTank + inc TankNr + ldx TankNr + cpx NumberOfPlayers + bne CheckNextTankSH + beq RepeatSpy +SpyHardEnd + mvx TargetTankNr TankNr ; restore + jsr DisplaySpyInfo + mva #0 SpyHardFlag + rts +.endp +.proc DisplaySpyInfo + lda TankStatusColoursTable,x + sta COLOR2 ; set color of status line + jsr PutTankNameOnScreen + jsr DisplayStatus + rts +.endp ; ------------------------------------------------- .proc TankFlying ; -------------------------------------------------