While I understand there could be huge benefits from merging the communities, I'd still love to keep the site as it is - at least the looks and feels. Would be really weird to stuff the cemetech theme down omnimaga's throat >.> (Not opposing the merge itself - just huge changes in design)
also ich hab mir damals ja mit Unsigned und zufälligen Rumspielen in Axe meinen taschenrechner soweit zerhauen dass das alte OS kaputt war und ich kein neues senden konnte... >.> Bin von daher eher mal vorsichtig ^^
Hallo Leute, Ich habe vor einiger Zeit angefangen ein Axe Tutorial auf Deutsch zu schreiben. Keine kurze Helpfile sondern ein schön ausführliches Tutorial bei dem man wenn möglich bei einmaligem Durchlesen schon Axe lernt ^^ Leider habe ich selbst wenig Ahnung von Axe und schreibe nur auf was mit Hayleia, Sorunome, c4ooo, DarkestEx und viele andere beibringen. Außerdem habe ich auch nicht besonders viel Zeit wodurch ich ewig zum schreiben brauche. Daher habe ich gedacht es könnten ja einfach alle mitschreiben die Lust haben ^^ Hier ist was ich bisher habe, es fehlen noch viele Kapitel (und nir ein paar davon sind vollständig) Ich hoffe es ist nicht zu schlecht geschrieben xD Änderungsvorschläge, weitere Kapitel oder was auch immer bitte einfach in die Replies, ich update dann den originalen Post (Diesen Post gibt es auf CodeWalrus und auf Omnimaga aber ich trage die Ergebnisse zusammen. Es ist also egal wo ihr antwortet)
ACHTUNG: Um Schäden an deinem Taschenrechner zu vermeiden, probiere bitte NIEMALS irgendwelche Codestücke aus, dabei handelt es sich nur um Anschauungs-Beispiele die NICHT ausgeführt werden dürfen! Am Ende jedes Kapitels findest du ungefährliche Beispiele zum Ausprobieren, die in GRÜN markiert sind!
In diesem Kapitle lernst du, Axe zu verwenden und die ersten Grundlagen.
Spoiler For Axe Grundlagen:
Um ein Axe-Programm zu schreiben, muss zuerst das Programm als Axe-source gekennzeichnet und ein Name angegeben werden. Diesen Namen erhält dann dein Programm nach dem Kompillieren. Dazu schreibst du in die erste Zeile deines Programms zuerst einen Punkt und anschließend einen Namen. Dieser Name muss alphanumerisch sein (Groß- und Kleinbuchstaben plus Zahlen) und muss mit einem Großbuchstabe beginnen. Hier ein Beispiel:
PRGM:POKESRC1 :.Pokemon1 : :1->X Viele der Befehle aus TI-Basic wurden in Axe übernommen oder nur erweitert. Einige wenige wurden aber auch durch eigene Axe-befehle ersetzt. Öffnest du also Menüs wie MATH oder PRGM werden dir einige neue Befehle auffallen. Dies gilt aber naturlich nur in Programmen, die als Axe-source gekennzeichnet sind. Außerhalb solcher Programme solltes du durch Axe keinerlei Änderungen bemerken.
Ein erstes Beispiel für übernommene und veränderte Befehle in Axe ist dieser Code:
PRGM:POKESRC1 :.Pokemon1 : :1->X :ClrHome :Output(1,3,X)Eine Kurze Erklärung: Wie auch in TI-Basic wird beim Befehl Output( zuerst die Zeile und dann die Spalte angegeben. Dieser Befehl wurde als übernommen, genauso der Befehl ClrHome, der zuerst den Bildschirminhalt für uns löscht. Allerdings wird dieser Code nicht die Zahl 1 sondern einige unlesbare Zeichen ausspucken. Das liegt daran, dass Axe nicht standardmäßig Zahlen als Zahlen anzeigt. (ALS WAS DANN???) Um X als normale Dezimalzahl anzuzeigen, musst du also >Dec anhängen (du findest >Dec im MATH Menü). Dieser Befehl wandelt normalerweise Brüche in Kommazahlen um - Axe hat diesen Befehl verändert und verwendet ihn zur Kennzeichnung was angezeigt werden soll. Alternativ kannst du auch >Char anhängen. Das Signalisiert dem Compiler dass du hier das Zeichen nummer 1 (da 1->X) aus dem Zeichensatz des Taschenrechners angezeigt werden soll. Für X=1 solltest du hier ein kursives n bekommen. Hier ein Beispielcode zum Ausprobieren:
PRGM:POKESRC1 :.Pokemon1 : :35->X :ClrHome :Output(15,3,X>Char :Output(11,4,X>DecZur Information: Der Befehl Output( schreibt zahlen automatisch rechtsbündig in einem gedachten 5 Zeichen breiten Feld, daher die 11 und die 15 damit beide Anzeigen rechtsbündig sind.
Dieses Kapitel gibt einen Überblick über effzientes Arbeiten mit Variablen
Spoiler For "Arbeiten mit Variablen":
Axe ist weit mehr als TI-Basic auf geschwindigkeit optimiert und bietet daher auch viel mehr Möglichkeiten. Um dein Axe-Programm auch schön schnell ausführen zu können solltest du aber darauf achten, es auch so effizient wie möglich zu schreiben. Dadurch gewinnst du sowohl Speicherplatz als auch Geschwindigkeit.
Schon die Zuweisung einfacher Variaben lässt sich in Axe optimieren: Dies ist ein Beispiel für einen Langsamen, nicht optimierten Code:
Damit spart man natürlich nicht besonders viel Zeit, es wird aber immer empfohlen möglichst optimierten Axe code zu schreiben da der Unterschied bei größeren Programmen doch deutlich bemerkbar ist.
Zwar ist es eher üblich zuerst die Grundlagen und danach erst die Optimierungen zu lernen, allerdings ist es sehr zu empfehlen von anfang an optimierten Code zu schreiben. Dadurch gewöhnst du dir einen besseren Programmierstil an und du sparst deutlich Zeit da es viel länger dauert einen schlechten Code zu modifizieren.
In diesem Kapitel bekommst du eine Einführung in Schleifen und Bedingungen in Axe
Spoiler For Schleifen und Bedingungen:
Wie auch TI-Basic verwendet Axe If für einfache Bedingungen sowie For( und While für Schleifen. Deren Verwendung und Schreibweise ist aber teilweise anders als du es vielleicht schon von TI-Basic gewohnt bist:
Der IF-Befehl Anders als in TI-Basic ist eine If-Abfrage IMMER mit einem End zu beenden. Dabei ist es egal ob der dadurch ausgeführte Befehlsblock nur einen einzigen Befehl oder 1000 Befehle umfasst. Dafür ist aber auch kein Then mehr nötig:
If x=2 3->X 5->Z EndHier im Beispiel werden sowohl 3->X als auch 5->Z nur ausgeführt, wenn die if-Bedingung zutrifft. TI-Basic hätte den if-Block nach dem ersten Befehl (5->Z) beendet. Natürlich lässt sich auch ein Else einbauen und das If verschachteln:
If X=2 3->X 4->Y Else 4->X if Y=5 10->Z End EndHier wurde der Code zur besseren Lesbarkeit mit Leerzeichen eingerückt. Anders als TI-Basic erlaubt Axe es, deinen Code tatsächlich so zu schreiben. Beim Kompillieren werden diese Leerzeichen ignoriert, sie haben also keinen Einfluss auf das spätere Programm und dienen nur der besseren Lesbarkeit. Sie zu verwenden lohnt sich leider wegen der geringen Bildschirmbreite des Taschenrechners nur selten.
Natürlich lassen sich auch Bedingungen in Axe noch stark optimieren (wenn auch diesmal auf Kosten der Lesbarkeit, aber man gewöhnt sich daran). *HIER DEN SCHEIß MIT A=B?1,2:->X UND SO ERKLÄREN
In diesem Kapitle lernst du, wie du den Hauptspeicher (RAM) deines Taschenrechners verwenden kannst, um weitere Variablen speichern zu können.
Spoiler For Die verwendung des Hauptspeichers:
In diesem Kapitel ist es besonders wichtig, nur Codes auszuführen, die mit Grün markiert sind! Experimente mit dem Hauptspeicher können echte Schäden verursachen. Wenn du dir nicht sicher bist, wende dich an die Community, damit sie deine Codes prüft, bevor du etwas ausprobierst.
Axe bietet die Möglichkeit, Variablen direkt in den RAM zu speichern. Das hat den Vorteil dass dir die Variablennamen nicht ausgehen (A-Z reichen oft nicht). Das geht folgendermaßen:
In Axe wird mit {X} der inhalt des Bytes X zurückgegeben. X bezieht sich dabei auf die Hauptspeicheradresse, also die Adresse im RAM. Hier ein Beispiel - Dies überschreibt den Inhalt des ersten Bytes (Adresse 0) mit X, speichert also X an der ersten Position im RAM:
X->{0}(Na gut, eigentlich die erste Position im Flash-speicher, da dieser bei $0000 beginnt und der RAM erst bei $8000 (Hexadezimale Angaben - also 32.768 in Dezimal).)
Eine 1 Byte lange Zahl kann nur 2^8 Werte haben, also eine zahl zwischen 0 und 255. Das ist natürlich viel zu wenig, also verwendet Axe standartmäßig 2 Byte pro Variable. Damit kommt man auf 2^16 Werte, also einen Zahlenbereich von 0 bis 65.535
Das heißt dieser Code wird uns ein Problem bereiten:
300->{0}Ein kurze Erklärung: Die Zahl 300 ist binär: 0000-0001-0010-1100, also 256+32+8+4 Sie besteht also aus 2 Bytes: 0000-0001 und 0010-1100. Versucht man nun die 300 wie oben abzuspeichern, kann nur das erste Byte tatsächlich abgespeichert werden. Das heißt aus der 300 wird 0000-0001, also die Zahl 1.
Um dieses Problem zu umgehen, wird {0}^r verwendet. (Du findest das r unter 2nd -> APPS) Durch das Anhängen des r signalisierst du dem Compiler, dass hier nicht nur das eine Byte {0} angesprochen werden soll, sondern zwei Bytes auf einmal:
5->{0} 42->{1} 83->{2} 9001->{3}^r 500->{5}^rHierbei ist zu beachten dass {4} bereits durch 9001->{3}^r mitverwendet wird. Wenn ihr nicht allzuviel Wert auf Speicherplatz legt aber auf nummer sicher gehen wollt, verwendet also einfach nur gerade Hauptspeicheradressen und arbeitet immer mit Bytepaaren.
5->{0}^r 42->{2}^r 83->{4}^r 9001->{6}^r 500->{8}^r Genauso wie sich einzelne Bytes im Hauptspeicher einfach setzen lassen, kann man sie natürlich auch wieder abrufen:
Nun ist es natürlich keine gute Idee, irgendwelche Adressen im RAM (oder Flash) einfach zu überschreiben. Du riskierst damit ernsthafte Schäden an deinem Taschenrechner! Aber natürlich bietet Axe dir eine sichere Möglichkeit diese Technik einzusetzen: [b]L1[/b] Anders als in Basic ist [b]L1[/b] in Axe keine Liste, sondern eine einfache Adresse im Hauptspeicher. Du denkst die L1 am besten als konstante variable mit irgendeiner komischen Zahl als wert. Das hört sich jetzt komisch an, ist aber eigentlich ganz einfach: [b]L1[/b] markiert eine Position im Hauptspeicher, an der unbenutzter Speicher zur Verfügung steht, wodurch du also auch nichts kaputt machen kannst :) Wenn du jetzt das erste Bytepaar von L1 ansteuern willst, machst du das so: [code]9000->{L1}^r {L1}^r+1->A Natürlich stellt L1 dir auch ordentlich Platz zur verfügung: Du kannst die nächsten 256 Bytes, die nach L1 kommen, problemlos verwenden. Übrigens: Zwar ist L1 nur eine einzelne Position, aber man spricht trotzdem davon, Variablen IN L1 abzuspeichern wenn sie in diesem Bereich gespeichert werden. Der einachkeit halber übernehmen wir das auch. Das heißt wenn du mehr Speicherplatz für Variablen brauchst, stehen dir {L1+0}^r bis {L1+256}^r zur freien Verfügung.
Theoretisch kannst du das selbe übrigens auch mit L2, L3, L4, L5 und L6 machen, davon wird aber abgeraten da diese schon von Axe verwendet werden: Wenn du z.B: Interrupts in deinem Programm verwendest, werden diese in L2 gespeichert. Und L6 entspricht dem Bildschirm, d.h. Veränderst du etwas in L6 ist das als würdest du etwas auf dem Bildschirm anzeigen lassen. Solange dir L1 reicht vermeide es also, L2, L3, L4, L5 oder L6 zu verwenden. Und wenn dir doch der Platz ausgeht, dann frage besser einen Profi bevor du es einfach ausprobierst.
Zusätzlich besteht noch die Möglichkeit, einzelne Nibbel anzusteuern (ein Nibbel ist eine 4Bit-Einheit, so wie ein Byte eine 8Bit-Einheit ist. Und jep, die heißen wirklich so!) Das machst du so:
Mit nib{ (du findest den Befehl unter [Math] -> NUM -> 3) wählst du eine 4Bit-Einheit aus. Wie auch Bytes werden die Nibbel mit Adressen angesteuert. ABER: Die Adressen der Nibbel sind auf 4 statt auf 8 Bit ausgelegt. Das heißt die Adresse "4" bezieht sich NICHT auf das 4. Byte sondern auf das 4. Nibbel, sprich das 2. Byte. Das heißt du musst die gewünschte Adress im Hauptspeicher zuerst Verdoppeln (zB das hundertste Nibbel liegt im 50sten Byte, daher die Verdoppelung damit die Adressen sich auch hier auf Bytes beziehen). Nehmen wir einmal an das erste Byte in L1 wäre 1010-1111 und wir rufen nib{L1*2} auf, dann wird uns 1010 zurückgegeben. Rufen wir nib{L1*2+1} auf, dann wird uns 1111 zurückgegeben. Um das vierte Byte in L1 aufzurufen schreiben wir also nib{L1+3*2} und nib{L1+3*2+1} auf. (Beachte dass das +3 ebenfalls verdoppelt werden muss da es sich um Byte-Angaben handelt) Es besteht aber auch die Möglichkeit, zwei Nibbels (also ein Byte) auf einmal abzufragen. Hier dazu ien Beispiel:
nib{L1+4*2}->A nib{L1+4*2+1}->B nib{L1+4*2}^r->C nib{L1+4*2+1}^r->D nib{L1+4*2}^r^r->E nib{L1+4*2+1}^r^r->FNehmen wir an, dass L1+4 und L1+5 diesen Inhalt haben: 1010-1111 0000-0110, dann bewirkt der Code folgendes: A = 1010 Hier wird einfach das erste Nibbel aus dem Byte L1+4 abgefragt B = 1111 Hier wird das zweite Nibbel aus dem selben Byte abgefragt C = 1111-1010 Hier werden 2 Nibbel abgefragt, beginnend mit dem ersten Nibbel im Byte L1+4. Die Reihenfolge der Nibbel wird dabei standardmäßig vertauscht. D = 0000-1111 Auch hier werden 2 Nibbel abgefragt, das zweite Nibbel in L1+4 und das nächste, also das erste Nibbel in L1+5. Auch hier die vertauschte Reihenfolge. E = 1010-1111 Hier werden wieder beide Nibbel aus L1+4 abgefragt - aber die Nibbels explizit getauscht. Das heißt ihre Reihenfolge stimmt wieder. F = 1111-0000 Hier werden wieder das zweite Nibbel aus L1+4 und das erste aus L1+5 angefragt - in richtiger Reihenfolge.
Wichtig: Beim Arbeiten mit Nibbeln darfst du NIEMALS vergessen, die Adresse zu verdoppeln da du ansonsten einen anderen Bereich im Speicher ansprichst und eventuell Schäden an deinem Taschenrechner entstehen! *HIER NOCH WEITERSCHREIBEN*
In diesem Kapitel lernst du, wie du eigene Variablen erstellen und selbst benennen kannst.
Spoiler For Benutzerdefinierte Variablen:
Nachdem du im letzten Kapitel gelernt hast L1 zu verwenden wird dir sicher aufgefallen sein, dass es sehr nervig ist immer {L1+14}^r anstatt X zu schreiben. Und dann soll man sich auchnoch merken an welcher Stelle in L1 was gespeichert ist? Igitt! Zum Glück bietet die Axe auch hier wieder eine Möglichkeit dies zu umgehen: Du kannst in Axe eigene Variablen erstellen, indem du ihnen einen Namen und eine Adresse im Hauptspeicher zuordnest. Ein Beispiel davon sieht so aus:
16->°Alter 20->Alter Hier eine erklärung was der Code macht: Zuerst wird 16 der neuen Variable Alter zugewiesen. Da Variablen standardmäßig 2 Bytes verwenden, werden somit [b{16} und {17}[/b] beziehugnsweiße wird {16}^r dem Namen Alter zugewiesen. Das ° vor dem Namen signalisiert dem Compiler, dass hier 16 eine Hauptspeicheradresse ist und Alter eine neue Variablenbezeichnung. Das ° findest du unter 2ND -> APPS und du darfst es hierbei niemals vergessen! Sobald die Variable deklariert ist (sie also "erstellt" ist), kannst du sie problemlos verwenden, ohne dass du das ° dazuschreiben musst. Dieses brauchst du nur einmalig zum Erstellen der Variable. Übrigens darf der Variablenname bis zu 16 Zeichen lang sein und aus Groß- und Klienbuchstaben bestehen. Achte aber darauf dass deine Variablennamen mit einem Großbuchstaben anfangen! Außerdem darfst du bestehende Variablenwie z.B. X oder Y nicht überschreiben.
Auch hier hilt natürlich, dass es schlecht, ist irgendwelche RAM-Regionen zu verändern, auch hier solltest du also auf L1 zurückgreifen. Das geht so:
L1+0->°XPositionWichtig: Hier wird nur L1+... geschrieben, aber nicht {L1+...} da hier die Adresse benötigt wird, nicht der ausgelesene Inhalt dieser Adresse. Ein kurzes Beispiel für einen Typischen solchen Fehler:
1768->{L1}^r {L1}->°Kuchen 1700->KuchenWas hier passiert ist folgendes: Der Wert 1768 wird {L1}^r also {L1} und {L1+2} zusammen zugeordnet. (0000-0110 und 1110-1000). Die Deklaration von °Kuchen verwendet jetzt aber den WERT von L1 anstatt der Adresse. Da hier nur {L1} verwendet wurde, ist dieser Wert 6 (0000-0110). Die Variable Kuchen wird also den Bytes 6 und 7 zugeordnet - irgendwo mitten im Flash-speicher. Richtig wäre gewesen:
1768->{L1}^r L1->°Kuchen 1700->KuchenHierbei wird die Adresse von L1 verwendet und somit wird der zuor zugewiesene Wert von 1768 jetzt mit 1700 überschrieben.
Bitte beachte dass bei solchen Variablendeklarationen IMMER 2 Byte verwendet werden. Wenn du also in deinem Programm diese Technik verwendest, wird dringend empfohlen, NUR 2-Byte Variablen im Hauptspeicher zu verwenden. Sich überlappende Variablen im Hauptspeicher gehören zu den am schwierigsten zu findenden Fehlern überhaut - das willst du nicht
why can I only refill my bottle in deep water? It doesnt work when facing the non-deep water from rivers or besides the town of Dogglen
I love Ebus' new dialogue but it seems a bit strange he talks about the "forest below" instead of "southern forest" or something ^^
MAYBE add a "*CLICK*"-message to the hitting-a-switch dialogue just to make it clear to everyone you already hit the switch ^^
The new mode menu is nice, especially since you an now see the armory and weapons And on op of that you now also have enough space to add little icons for ALL items you posess (like keys, letters, boots, ...)
Does the new engine also affect those monsters with a higher level than the player? They seen to be a bit weaker. If so you should maybe exclude any monsters stronger than the player from it just to make soure people are more or less forced to follog the storyline and wont just wander around. (To me it seems to be easier to reach the pickaxe now)
Still there is no such thing as a death animation for monsters... watching super carefully each time but there is *nothing*
MAYBE make the position-text in the mode menu something like "You are in Dogglen" and "You are in teh forest" instead of just "forest" - there's enough space for that And it's a lot easier for newbies that look in the menu fpr the first time and dont know yet what "Dogglen" means ^^
MAYBE you want to change the forst's map//paths after killing the spider, too (so it takes a little bit longer to escape the forest and it gets a bit harder, too) ^^
why does the sign beside the blocked path say "be sure to take your sword with you"? Is it even possible to aquire a sword in dogglen..?
I still think you should rework the snake's skin
Every time I interact with a gate I'm a bit sad the gates don't shout "YOU SHALL NOT PASS!"
don't forget to implement the "Peak" between dogglen and aerilon
once you reach lv11 there's not enough space to show your livepoints ^^ "1075/1120" is just too width to display ^^
How do you plan on moving stuff around to beign able to display it all? Would it work out if there is one more pixel on the right? what about two? (i can easily add two more pixels space on the right)
this is what the end of the line looks like: That strange thing is because the "0" is half off the screen. so there's absolutely no free space in x-direction... But with HP, MP, Level, EXP and GOLD there's still one free line below. YOu should consider changing the display method after reaching level 10 or 11 like this:
once you reach lv11 there's not enough space to show your livepoints ^^ "1075/1120" is just too width to display ^^
The "find scary stuff" guy should tell you about the mission not being over... maybe like "OMG THIS IS SCARY! BUUUT not enough... Go look again!" or something similar
the game only remembers you have destroyed the boulders on the path if you cross it towards north but forgets about it if you return to the village, that's a bit strange. btw I love it how you make the path come back xD
As I already said, the game itself has no way of remembering if a rock gets destroyed or not. I will not change that mechanic as it would require a too large re-write. So, the only way that it "remembers" with those three rocks is that i set some special event there so that if you walk over the free path to the top of them it'll set an event which will remove the rocks. That actually adds one bit to the savefile.
should trigger the same when walking over the block BELOW the path, so it always saves it
That would require three bit instead of one for saving it, such stuff adds up quickly. As what if you only destroy one block and come back? Sorry, I am not going to change anything about this behaviour.
King's attacking speed increases after 2nd attack (as mentioned in IRC)
As also mentioned in IRC i did a typo in the data giving the king accidentally super-streangth
Had to be teh king getting the boost, not the player ? ^^
Battles should pause a soon a my attack is loaded and I'm about to chose (arrow key). same should happen when entering MODE menu. Really sucks to die while being in menu to select the bottle ^^
the game only remembers you have destroyed the boulders on the path if you cross it towards north but forgets about it if you return to the village, that's a bit strange. btw I love it how you make the path come back xD
As I already said, the game itself has no way of remembering if a rock gets destroyed or not. I will not change that mechanic as it would require a too large re-write. So, the only way that it "remembers" with those three rocks is that i set some special event there so that if you walk over the free path to the top of them it'll set an event which will remove the rocks. That actually adds one bit to the savefile.
should trigger the same when walking over the block BELOW the path, so it always saves it
when getting a levelUp from killing a huge monster (like these floating things in the castle) the text collides with the enemy sprite
There isn't enough space on the screen to do it any differently....
it looks like the nevel up text inverts the color - how about setting the pixels of the mesage forcebully to black and adding a whte border around the message?
King's attacking speed increases after 2nd attack (as mentioned in IRC)
The new text of the old man in his hut in teh forest is weird... Should change it to something like "maybe you cn wind something in the forest. Here take this stick to defend yourself" it's weird if he just tells you "search SOMWHERE and take this stick to fight against the monsters in the FOREST"...
Also once you found the Axe (not the pickaxe) it's not shown in the item menu
Dont you think the 5 or 6 foxes in one room are a little bit too much...?
I get bombs in the village but they cant change anything...? not even free foxes?
once trapped in the village there's no way to escape. So I guess it's not finished yet? ^^
Maybe add a message "the bottle is empty" when atempting to drink water and the bottle is empty?
maybe add "your HP/MP got restored" message after drinking?
why can't I use bombs when facign any object? even trees and walls? ^^
the game only remembers you have destroyed the boulders on the path if you cross it towards north but forgets about it if you return to the village, that's a bit strange. btw I love it how you make the path come back xD
For the switch inside the cave of the castle, you forgot to add the "theres nothing here" message
Quote from: Sorunome on IRC
[11:27:54] Sorunome i didn't forget to add the message.......i didn't feel like coding it >.>
when getting a levelUp from killing a huge monster (like these floating things in the castle) the text collides with the enemy sprite
True teh discussion is more active on CodeWalrus (since people startet discussing general axe code modifications there) but I try to add improvements from both Omni and CodeW to the code ^^ And I still haven't rewritten the code since I was away for a couple of days and people kept posting more and more improvements ^^
limited bombs but another eay of getting new bombs, maybe as drops from killed enemies or finding them in the forest somewhere... or empty houses with chests full or bombs and stuff... >.> (in addition to shop since you won't have that much money - also makes users being more curious about the map, too, since they'd be expecting to find hidden stuff everywhere