Putting the 'role' back in role-playing games since 2002.
Donate to Codex
Good Old Games
  • Welcome to rpgcodex.net, a site dedicated to discussing computer based role-playing games in a free and open fashion. We're less strict than other forums, but please refer to the rules.

    "This message is awaiting moderator approval": All new users must pass through our moderation queue before they will be able to post normally. Until your account has "passed" your posts will only be visible to yourself (and moderators) until they are approved. Give us a week to get around to approving / deleting / ignoring your mundane opinion on crap before hassling us about it. Once you have passed the moderation period (think of it as a test), you will be able to post normally, just like all the other retards.

Abura Tan SM

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,316
This is an abandoned roguelike project which I made a working SDL port in 2009... I found the only copy from my homepage so it's sometimes nice to keep that old stuff there. However I'm having some troubles getting this to run. I have found two bugs that crash. The second one is harder, because I actually don't understand what the piece of code is trying to do. It happens in RawTarget::Force. There is no description what Force does, but what I can tell it's making two strings uppercased in a while loop, while calling aPolymorph, which does nothing, since there is no action for that. Well, take a look at this yourself:

Code:
Target RawTarget::Force(String force_str)
{
   int index = 0;
   do
   {
       doPerform(aPolymorph);
   } while (Grammar::plural(THIS).upcase() != force_str.upcase()
       && ++index < NUM_ABORT*10);

   assert (index < NUM_ABORT*10);

   return Target(THIS);
}

It stops in that assert (NUM_ABORT is 100 so it takes 1000 times to try something). upcase makes the string uppercased, but I don't get what this is trying to do. What was the idea of polymorph which leads to an empty case label.
 

asfasdf

robot
Patron
Joined
Dec 18, 2012
Messages
839
Insert Title Here Strap Yourselves In Codex Year of the Donut
Need more code. Who knows what 'Grammar::plural(..)' and 'doPerform(aPolymorph)' does.
 

Otay

Bramble Gate Studios Original
Developer
Joined
Nov 7, 2018
Messages
248
Location
Hell's gates
in a while loop, while calling aPolymorph, which does nothing
Here, you said it yourself. An infinite loop.

To escape an infinite loop, one must do something?

Edit:
On 2nd thought this looks like the while() portion is trying to alter a string to correspond with a Target.

but "THIS" refers to what, a class? A... Grammar class? Your goal being to prepare (possibly de-pluralizing) the class to be cast as a Target again?
 
Last edited:

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,316
I think doPerform does call Quiver::perform, because it's a virtual function. But looking at Quiver::perform doesn't make it any easier to guess. There is also a strange arrow notation which I think is some kind of macro magic:

Code:
perform(aWear, Quiver::create()->Force("a bandolier"));

This I guess tries to create a bandolier for the character. Quiver class has these macro functions:

Code:
    METHOD_create_option(Quiver);
    METHOD_create_default(Quiver);

And they look like this:

Code:
#define METHOD_create_option(CLASSNAME);       static Target create( const Option &o ) {\
           CLASSNAME *instance = new CLASSNAME(&o);\
           TargetValue *THIS = new TargetValue( instance );\
           instance->setTHIS(THIS);\
           return Target(THIS);\
           }

#define METHOD_create_default(CLASSNAME);   static Target create( void ) {\
      Option opt_default;\
      CLASSNAME *instance = new CLASSNAME(&opt_default);\
           TargetValue *THIS = new TargetValue( instance );\
           instance->setTHIS(THIS);\
           return Target(THIS);\
      }

And last but not least the polymorph thing:

Code:
bool Quiver::perform(Action a, const Target &t)
{
   bool rv=false;
   switch (a)
   {
       // Todo: poly quivers and poly ammunition to something appropriate
       case aPolymorph:

           if (inventory && inventory->reset())
           {
               // Remove contents (if any)
               // Polymorph the quiver
               // Then add something appropriate (if contained something before)
           }
           else
           {
               form = NUM_QUIVER;

               if (!t)
                   form = Random::randint(NUM_QUIVER);
               else
                   for (int i = 0; i < NUM_QUIVER; ++i)
                       if (canCarry(i, t))
                           form = i;

               assert(form != NUM_QUIVER);
               //Error::fatal("Invalid Quiver polymorph!");
           }

           rv=Container::perform(a, t);
       break;
       default:
           rv=Container::perform(a, t);
   }
   return rv;
}

I did change this one a bit, it had no return value, each case label had a return (no breaks) which I find bad style.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,316
So I did check the Force function and found out that in theory it works. It changes the THIS and force_str until they match. In this case it's looking for A BANDOLIER and the first value of THIS seems to be A QUIVER. What I don't understand is why the game can't just create a fucking bandolier in the first place. Why it has to polymorph the item until it is a bandolier? By the way, even if this works the game just stops working when you create the character so it was for nothing. Visual Studio doesn't tell -anything- why the game stops, it just does it. I'm trying to compile this in Code::Blocks also (gcc) so we'll see if it tells more about it. If you are reading this (I guess you are) and planning to use 'if' in C or C++ without guarding the following code block with curly brackets. DON*T! Add curly brackets. This code has crap like this all over the place:

Code:
if (inventory && inventory->reset())
   do
   {
       if (inventory->get()->getVal(s)) return true;
   } while (inventory->next());

Don't. This is how you should do it:

Code:
if (inventory && inventory->reset())
{
   do
   {
       if (inventory->get()->getVal(s)) return true;
   } while (inventory->next());
}

This dude also likes his do-while loops for sure. I've never seen this many do-while loops in a source code before.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,316
The exit bug was just a stealthy '.' directory passed as default argument to File::exists which backed up one directory from the working directory. I removed the directory test, you can apparently find files with directory using _access().

abura1.png


The main problem is the display. It's drawing the gameview past the actual size and the biggest problem is (as I recall) the unholy "buffer" routine. For some reason it's physically scrolling the view in some kind of buffer which doesn't even compile (memcpy with void magic etc.). If I can understand the level structure it's maybe possible to create a view with a moving "camera" rather than any kind of weird scrolling stuff. The game itself looks quite complex actually and the theme and monsters are not the usual stuff.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,316
Just the process of cleaning up this code is a monumental task. What I hate about unguarded if-blocks is that they mess up the automatic formatting, moving the following code to next tab location. It wouldn't be a big problem but this code has the deepest and biggest switch-cases I've ever seen. The programming language doesn't even seem to be C++, it's a new language with only do-whiles and switch-cases. Anyway my plan is to throw this to github once it's in some kind of shape. I don't really want to work on this to even understand what happens in the display routine.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,316
Once the clean-up is done I think I have to fix my own code... when I implemented SDL version I should have used a virtual ascii-style screen buffer (because the game used curses) which I didn't so that's one thing to fix. Another one is keyboard commands which is more on SDL2, because it changed them from SDL1 and I still don't get how they work properly.
 

Krice

Arcane
Developer
Joined
May 29, 2010
Messages
1,316
I wrote a class for the virtual screen implementation and it even works. The changes required in gui class were small and the next thing is rewriting the background save for dialogs etc. The background can now be saved as ascii, because the virtual screen buffer is also ascii. And I would imagine if you would want to use some other kind of output (like curses) it's quite easy to rewrite the virtual screen class.
 

Kurt Russell Fan Club

Reuben Games
Developer
Joined
Jan 2, 2022
Messages
1
I wrote a class for the virtual screen implementation and it even works. The changes required in gui class were small and the next thing is rewriting the background save for dialogs etc. The background can now be saved as ascii, because the virtual screen buffer is also ascii. And I would imagine if you would want to use some other kind of output (like curses) it's quite easy to rewrite the virtual screen class.

oh good lord! I’ve been playing with some new versions of this codebase over the past few months and I feel your pain. I haven’t touched it in over 15 years and started it as a way to learn c++ so it’s filled with decisions that were more fun than practical. If you’d like help or there’s major crashes then I can give some insight
 

As an Amazon Associate, rpgcodex.net earns from qualifying purchases.
Back
Top Bottom