Poll

Should I consider secondary developers?

No, retain the purity. One man, one mod, ein reich!
Yes.

Author Topic: CityRPG  (Read 123645 times)

I like how eating works now. It's not required to do anything, you can go around starving and play just fine. However, actually buying something from stores will greatly improve productivity in every aspect of the game.

I'm tempted to add in some belly rumble sounds that nag you to eat every X minutes, though. It's important for the economy that merchants have customers.
« Last Edit: January 29, 2012, 04:10:49 AM by CityRPG »

I like how eating works now. It's not required to do anything, you can go around starving and play just fine. However, actually buying something from stores will greatly improve productivity in every aspect of the game.

I'm tempted to add in some belly rumble sounds that nag you to eat every X minutes, though. It's important for the economy that merchants have customers.
Those improvements need to be really significant because the fact you can't die from hunger really makes eating seem hardly important at all.

Also considering the necessary capital to open a restaurant is little in comparison to something such as a gun shop or a skyscraper/profiteer business or whatever it is, it's what most people who are trying to work their way up the business chain will start at.

Maybe billboard lots where you can buy time with your name up on it saying like, Come <service>, at <player>'s <shop goes here> would help create a hierarchy of which store is the best.

So if Bill the grocer wanted to advertise it would say, "Come buy food at Bill's grocery store!"

That way thriving businesses can become even better, and it will deter criminals from opening grocery stores and selling food to all their comrades at cost. Cooperative businesses can go to hell C:


Earn benefits for eating maybe.

I'll be spending most of today reworking the clue system so it is more dynamic. I want things to make a little bit more sense and have demerits be a little bit more intuitive. I'll keep you guys posted if any core functionality changes.

Make it so each clue has like parts and pieces that if you get them all, you can figure out the criminal.
Like, if someone runs over someone with a car, there can be broken bones laying around somewhere, and the license plate, then if you bring those 2 to the Police Office, you can put together the clues and get the person. Then you have to get an arrest warrant, THEN you can get them.
Though if a cop visually sees someone shoot someone in the face, then bang.
Just an idea though.

Make it so each clue has like parts and pieces that if you get them all, you can figure out the criminal.
Like, if someone runs over someone with a car, there can be broken bones laying around somewhere, and the license plate, then if you bring those 2 to the Police Office, you can put together the clues and get the person. Then you have to get an arrest warrant, THEN you can get them.
Though if a cop visually sees someone shoot someone in the face, then bang.
Just an idea though.
There is an item limit built into the game. Weapons do not disappear, cash has a 1 minute life time, ores from rocks and trees are all items, and clues are also items. If the item quota is reached all this breaks. I have to be conscious about numerations.

Also, that's way over-complicated. You just saw a car maul some dude over. Why do I need to bring torn off limbs to a PD to incriminate them?

There is an item limit built into the game. Weapons do not disappear, cash has a 1 minute life time, ores from rocks and trees are all items, and clues are also items. If the item quota is reached all this breaks. I have to be conscious about numerations.

Also, that's way over-complicated. You just saw a car maul some dude over. Why do I need to bring torn off limbs to a PD to incriminate them?
when your in jail can you drop the soap??? (good addition to the game, adds more realism)

Quote from: Steam Before You Shouted at me
Brian Smithers: iban, a good way to limit crime is to make bots attempt to arrest criminals when they reach a certain amount of demerits.

Civilian bots are a dream of mine. After I fix up ZAPT with a proper AI system I will consider bots.

Civilian bots are a dream of mine. After I fix up ZAPT with a proper AI system I will consider bots.

If you include bots, can you please include a slave trading system, so you can exploit owned bots to do stuff for you until they die?
I want to be a terrible person.


If you include bots, can you please include a slave trading system, so you can exploit owned bots to do stuff for you until they die?
I want to be a terrible person.
you seem naughty.
i like naughty.

If you build a grid based city, you can use Dijkstra


//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
// Written in Microsoft Visual Basic by Jack Hoxley
// Ported to Torque Script by Robert Brower
//-----------------------------------------------------------------------------

function Dijkstra::min(%this, %a, %b)
{
   //Return the minimum of the two...
   if (%a < %b) return %a;
   if (%a > %b) return %b;
   if (%a == %b) return %a;
}

function Dijkstra::GetDist2D(%this, %x, %y, %x1, %y1)
{
   return mSqrt(mPow(%x - %x1, 2) + mPow(%y - %y1, 2));
}

function Dijkstra::GetClosestNode(%this, %x, %y)
{
   //echo("Dijkstra::GetClosestNode()");
   %minDist = 999999;
   %index = -1;
   for (%i=0; %i<%this.MarkerCount; %i++)
   {
      %dist = %this.GetDist2D(%x, %y, %this.NodeList[%i].x, %this.NodeList[%i].y);
      if (%dist < %minDist) {
         %minDist = %dist;
         %index = %i;
      }
   }
   return %index;
}

function Dijkstra::init(%this)
{
   echo("Dijkstra: Initializing...");

   // get the Dijkstra path group from the mission
   %groupName = "MissionGroup/Dijkstra";
   %group = nameToID(%groupName);
   if (!isObject(%group))
   {
      echo("Dijkstra Error: Could not find Dijkstra sim group!");
      return false;
   }

   // get the number of paths in the sim group
   %this.MarkerCount = %group.getCount();
   if (%this.MarkerCount < 1)
   {
      echo("Dijkstra Error: No markers in Dijkstra sim group!");
      return false;
   }
   //echo("Dijkstra: Found " @ %this.MarkerCount @ " markers.");

   // create node list and tree
   for (%i=0; %i<%this.MarkerCount; %i++)
   {
      %marker = %group.getObject(%i);
      %matrix = %marker.getTransform();
      %pos = getWords(%matrix, 0, 2);
      //echo("%marker = " @ %marker);
      //echo("%matrix = " @ %matrix);
      //echo("%pos = " @ %pos);
      //
      %this.NodeList[%i] = new ScriptObject();
      %this.NodeList[%i].marker = %marker;
      %this.NodeList[%i].x = getWord(%pos, 0);
      %this.NodeList[%i].y = getWord(%pos, 1);
      //echo("%this.NodeList[" @ %i @ "].x = " @ %this.NodeList[%i].x);
      //echo("%this.NodeList[" @ %i @ "].y = " @ %this.NodeList[%i].y);
      //
      %this.TreeNodeList[%i] = new ScriptObject();
      %this.TreeNodeList[%i].CurrNode = %i;
      //echo("%this.TreeNodeList[" @ %i @ "].CurrNode = " @ %this.TreeNodeList[%i].CurrNode);
      //
      %this.TreeNodeList[%i].NextNode[0] = %marker.NextNode0;
      %this.TreeNodeList[%i].NextNode[1] = %marker.NextNode1;
      %this.TreeNodeList[%i].NextNode[2] = %marker.NextNode2;
      %this.TreeNodeList[%i].NextNode[3] = %marker.NextNode3;
      //echo("%this.TreeNodeList[" @ %i @ "].NextNode[0] = " @ %this.TreeNodeList[%i].NextNode[0]);
      //echo("%this.TreeNodeList[" @ %i @ "].NextNode[1] = " @ %this.TreeNodeList[%i].NextNode[1]);
      //echo("%this.TreeNodeList[" @ %i @ "].NextNode[2] = " @ %this.TreeNodeList[%i].NextNode[2]);
      //echo("%this.TreeNodeList[" @ %i @ "].NextNode[3] = " @ %this.TreeNodeList[%i].NextNode[3]);
   }
   
   // establish weights
   for (%i=0; %i<%this.MarkerCount; %i++)
   {
      if (!(%this.TreeNodeList[%i].NextNode[0] == -1))
      {
         %this.TreeNodeList[%i].Dist[0] =  %this.GetDist2D(
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].x,
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].y,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[0]].x,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[0]].y);

         //echo("%this.TreeNodeList[" @ %i @ "].Dist[0] = " @ %this.TreeNodeList[%i].Dist[0]);
      }
      //
      if (!(%this.TreeNodeList[%i].NextNode[1] == -1))
      {
         %this.TreeNodeList[%i].Dist[1] = %this.GetDist2D(
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].x,
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].y,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[1]].x,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[1]].y);

         //echo("%this.TreeNodeList[" @ %i @ "].Dist[1] = " @ %this.TreeNodeList[%i].Dist[1]);
      }
      //
      if (!(%this.TreeNodeList[%i].NextNode[2] == -1))
      {
         %this.TreeNodeList[%i].Dist[2] = %this.GetDist2D(
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].x,
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].y,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[2]].x,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[2]].y);

         //echo("%this.TreeNodeList[" @ %i @ "].Dist[2] = " @ %this.TreeNodeList[%i].Dist[2]);
      }
      //
      if (!(%this.TreeNodeList[%i].NextNode[3] == -1))
      {
         %this.TreeNodeList[%i].Dist[3] = %this.GetDist2D(
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].x,
            %this.NodeList[%this.TreeNodeList[%i].CurrNode].y,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[3]].x,
            %this.NodeList[%this.TreeNodeList[%i].NextNode[3]].y);

         //echo("%this.TreeNodeList[" @ %i @ "].Dist[3] = " @ %this.TreeNodeList[%i].Dist[3]);
      }
   //     
   }

   return true;
}

function Dijkstra::findPath(%this, %start, %finish)
{
   //echo("Dijkstra: finding path...");
   //echo("Dijkstra: %start = " @ %start);
   //echo("Dijkstra: %finish = " @ %finish);
   
   // possible early out
   if (%start == %finish)
   {
        // we're already there...
        %this.PathListCount = 2;
        %this.PathList[0] = %start;
        %this.PathList[1] = %finish;
        //echo("Dijkstra: early out");
        return true;
   }
   //
   //echo("%this.MarkerCount = " @ %this.MarkerCount);
   
   //1. Setup all the data we need
   for (%i = 0; %i < %this.MarkerCount; %i++)
   {
      %this.TreeNodeList[%i].VisitNumber = -1; //-1 indicates not visited
      %this.TreeNodeList[%i].Distance = -1; //Unknown distance
      %this.TreeNodeList[%i].TmpVar = 99999; //A high number that can easily be beaten
   }

   //Set the first variable
   %this.TreeNodeList[%start].VisitNumber = 1;
   %CurrentVisitNumber = 1; //Initialise
   %CurrNode = %start;
   %this.TreeNodeList[%start].Distance = 0;
   %this.TreeNodeList[%start].TmpVar = 0;

   

   //2. Start scanning
   // We're going to keep looping till we find the destination
   %bDone = false;
   while (%bDone == false)
   {
      //2a. Go to each node that the current one touches
      // and make it's temporary variable = source distance + weight of the arc
      if (!(%this.TreeNodeList[%CurrNode].NextNode[0] == -1)) {
         //echo("UP");
         %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[0]].TmpVar =
            %this.min( %this.TreeNodeList[%CurrNode].Dist[0] + %this.TreeNodeList[%CurrNode].Distance,
                 %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[0]].TmpVar );
      }

      //
      if (!(%this.TreeNodeList[%CurrNode].NextNode[1] == -1)) {
         //echo("RIGHT");
         %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].TmpVar =
            %this.min( %this.TreeNodeList[%CurrNode].Dist[1] + %this.TreeNodeList[%CurrNode].Distance,
                 %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].TmpVar );
      }

      //
      if (!(%this.TreeNodeList[%CurrNode].NextNode[2] == -1)) {
         //echo("DOWN");
         %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].TmpVar =
            %this.min( %this.TreeNodeList[%CurrNode].Dist[2] + %this.TreeNodeList[%CurrNode].Distance,
                 %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].TmpVar );
      }

      //
      if (!(%this.TreeNodeList[%CurrNode].NextNode[3] == -1)) {
         //echo("LEFT");
         %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[3]].TmpVar =
            %this.min( %this.TreeNodeList[%CurrNode].Dist[3] + %this.TreeNodeList[%CurrNode].Distance,
               %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[3]].TmpVar );
      }
               
      //2b. Decide which node has the lowest temporary variable (Free choice if multiple)
      %LowestValFound = 100999; // Hopefully the graph isn't this big :)
      for (%i=0; %i<%this.MarkerCount; %i++) //If we have more than 1000-2000 nodes this part will be horribly slow...
      {
         if ( (%this.TreeNodeList[%i].TmpVar <= %LowestValFound) &&
              (%this.TreeNodeList[%i].TmpVar >= 0) &&
              (%this.TreeNodeList[%i].VisitNumber < 0) )
         {
            // make sure we ignore the -1's and visited nodes
            // We have a new lowest value
            %LowestValFound = %this.TreeNodeList[%i].TmpVar;
            %LowestNodeFound = %i;
            //echo("%LowestValFound = " @ %LowestValFound);
            //echo("%LowestNodeFound = " @ %LowestNodeFound);
         }
      }
      //**NB: If there are multiple lowest values then this method will choose the last one found...
       
      //2c. Mark this node with the next visit number and copy the tmpvar -> distance
      %CurrentVisitNumber = %CurrentVisitNumber + 1;
      //echo("%CurrentVisitNumber = " @ %CurrentVisitNumber);
      %this.TreeNodeList[%LowestNodeFound].VisitNumber = %CurrentVisitNumber;
      //echo("%this.TreeNodeList[%LowestNodeFound].VisitNumber = " @ %this.TreeNodeList[%LowestNodeFound].VisitNumber);
      %this.TreeNodeList[%LowestNodeFound].Distance = %this.TreeNodeList[%LowestNodeFound].TmpVar;
      %CurrNode = %LowestNodeFound; //Copy the variable for next time...
      //echo("%CurrNode = " @ %CurrNode);
       
      //2d. If this node IS NOT the destination then go onto the next iteration...
      if (%CurrNode == %finish)
         %bDone = true; //We've gotten to the destination
      else
         %bDone = false; //Still not there yet

   }
   
   //3. Work out the route that was taken...
   %bDone = false;
   %CurrNode = %finish; //Start at the end, and work backwards...
   %lngTimeTaken = $Sim::Time;
   //echo("%lngTimeTaken = " @ %lngTimeTaken);
   
   %this.PathListCount = 1;
   %this.PathList[0] = %finish; //Put the first node in...
   
   //echo("EXITING...");
   //return false;

   while (%bDone == false)
   {
      //echo("%lngTimeTaken = " @ %lngTimeTaken);
      //echo("$Sim::Time = " @ $Sim::Time);
      //echo("elapsed time = " @ $Sim::Time - %lngTimeTaken);
      //First we check that the current node isn't actually the start
      //because if it is then we've found the path already
      if (%CurrNode == %start)
      {
         //echo("%CurrNode == %start");
         %bDone = true;
         continue;
      }
      else if ($Sim::Time - %lngTimeTaken > 1)
      {
         //Break out if we haven't found a solution in under 1 second
         %bDone = true;
         echo("Dijkstra: failed to find path");
         return false;
      }
     
      //echo("
  • ");

      //Scan through each node that we visited
      if (%this.TreeNodeList[%CurrNode].NextNode[0] >= 0) //Only if there is a node in this direction
      {
         //echo("%this.TreeNodeList[%CurrNode].NextNode[0] = " @ %this.TreeNodeList[%CurrNode].NextNode[0]);
         if (%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[0]].VisitNumber >= 0) //Only if we visited this node...
         {
            %e1 = %this.TreeNodeList[%CurrNode].Distance-%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[0]].Distance;
            %e2 = %this.TreeNodeList[%CurrNode].Dist[0];
            if(mAbs(%e1 - %e2) < 0.001) {
            //if (%this.TreeNodeList[%CurrNode].Distance - %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[0]].Distance == %this.TreeNodeList[%CurrNode].Dist[0])
            //{
               //NextNode(0) is part of the route home
               %this.PathListCount = %this.PathListCount + 1;
               %this.PathList[%this.PathListCount-1] = %this.TreeNodeList[%CurrNode].NextNode[0];
               %CurrNode = %this.TreeNodeList[%CurrNode].NextNode[0];
               //echo("%CurrNode = " @ %CurrNode);
               continue;
            }
         }
      }
      //echo("[1]");
      //     
      if (%this.TreeNodeList[%CurrNode].NextNode[1] >= 0) //Only if there is a node in this direction
      {
         //echo("%this.TreeNodeList[%CurrNode].NextNode[1] = " @ %this.TreeNodeList[%CurrNode].NextNode[1]);
         //echo("%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].VisitNumber = " @ %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].VisitNumber);
         if (%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].VisitNumber >= 0) //Only if we visited this node...
         {
            //echo("%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].VisitNumber = " @ %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].VisitNumber);
            %e1 = %this.TreeNodeList[%CurrNode].Distance-%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].Distance;
            %e2 = %this.TreeNodeList[%CurrNode].Dist[1];
            if(mAbs(%e1 - %e2) < 0.001) {
            //if (%this.TreeNodeList[%CurrNode].Distance - %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[1]].Distance == %this.TreeNodeList[%CurrNode].Dist[1])
            //{
               //echo("TEST TEST TEST");
               //NextNode(1) is part of the route home
               %this.PathListCount = %this.PathListCount + 1;
               %this.PathList[%this.PathListCount-1] = %this.TreeNodeList[%CurrNode].NextNode[1];
               %CurrNode = %this.TreeNodeList[%CurrNode].NextNode[1];
               //echo("%CurrNode = " @ %CurrNode);
               continue;
            }
         }
      }
      //echo("[2]");
      //
      if (%this.TreeNodeList[%CurrNode].NextNode[2] >= 0) //Only if there is a node in this direction
      {
         //echo("%this.TreeNodeList[%CurrNode].NextNode[2] = " @ %this.TreeNodeList[%CurrNode].NextNode[2]);
         //echo("%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].VisitNumber = " @ %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].VisitNumber);
         if (%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].VisitNumber >= 0) //Only if we visited this node...
         {
            //echo("%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].VisitNumber = " @ %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].VisitNumber);
            //echo("%this.TreeNodeList[%CurrNode].Distance - %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].Distance = " @ %this.TreeNodeList[%CurrNode].Distance - %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].Distance);
            //echo("%this.TreeNodeList[%CurrNode].Dist[2] = " @ %this.TreeNodeList[%CurrNode].Dist[2]);
            %e1 = %this.TreeNodeList[%CurrNode].Distance-%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].Distance;
            %e2 = %this.TreeNodeList[%CurrNode].Dist[2];
            if(mAbs(%e1 - %e2) < 0.001) {
            //if (%this.TreeNodeList[%CurrNode].Distance - %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[2]].Distance == %this.TreeNodeList[%CurrNode].Dist[2])
            //{
               //echo("TEST TEST TEST");
               //NextNode(2) is part of the route home
               %this.PathListCount = %this.PathListCount + 1;
               %this.PathList[%this.PathListCount-1] = %this.TreeNodeList[%CurrNode].NextNode[2];
               %CurrNode = %this.TreeNodeList[%CurrNode].NextNode[2];
               //echo("%CurrNode = " @ %CurrNode);
               continue;
            }
         }
      }
      //echo("[3]");
      //
      if (%this.TreeNodeList[%CurrNode].NextNode[3] >= 0) //Only if there is a node in this direction
      {
         //echo("%this.TreeNodeList[%CurrNode].NextNode[3] = " @ %this.TreeNodeList[%CurrNode].NextNode[3]);
         if (%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[3]].VisitNumber >= 0) //Only if we visited this node...
         {
            %e1 = %this.TreeNodeList[%CurrNode].Distance-%this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[3]].Distance;
            %e2 = %this.TreeNodeList[%CurrNode].Dist[3];
            if(mAbs(%e1 - %e2) < 0.001) {
            //if (%this.TreeNodeList[%CurrNode].Distance - %this.TreeNodeList[%this.TreeNodeList[%CurrNode].NextNode[3]].Distance == %this.TreeNodeList[%CurrNode].Dist[3])
            //{
               //NextNode(3) is part of the route home
               %this.PathListCount = %this.PathListCount + 1;
               %this.PathList[%this.PathListCount-1] = %this.TreeNodeList[%CurrNode].NextNode[3];
               %CurrNode = %this.TreeNodeList[%CurrNode].NextNode[3];
               //echo("%CurrNode = " @ %CurrNode);
               continue;
            }
         }
      }
   //         
   }

   //For ease of use we're going to invert the array.
   //currently we go finish-start, start-finish is more useful/easier
   //echo("Dijkstra: PathListCount = " @ %this.PathListCount);
   for (%i=0; %i<%this.PathListCount; %i++)
   {
      %this.TmpArray[%i] = %this.PathList[%i];
      //echo(%this.TmpArray[%i]);
   }
   //echo("Dijkstra: end of path list, reordering...");
   for (%i=0; %i<%this.PathListCount; %i++)
   {
       %this.PathList[%i] = %this.TmpArray[%this.PathListCount - 1 - %i];
       //echo(%this.PathList[%i]);
   }
   
   
   //
   //echo("Dijkstra: found path, %this.PathListCount = " @ %this.PathListCount);
   return true;
}

Ehem, just make some simple bots with some clothing and port the above code to BL (to use bricks), then it'd be easy to just use bricks as nodes. Civilian Bots can't be super hard :|. Have them walk when they are roaming, and when they get robbed or something, have them run away.

why did you not just put that in paste bin.