• Portal
  • Forums
  • Shop
  • Statistics
    • Players
      Games
      Maps
      Top
      Levels
      Countries
  • GameServer
  • Downloads
  • Discord
  • Logs
    • Chat
      Warns
      Bans
  • Search
  • Extras
    • Forum Members
      Team Members
      Stats For Nerds
      Recover Account
      Calendar
      Help
      Forum stats
      View New Posts
      View Today's Posts
Reign of the Undead - Revolution
Login to account Create an account
Login
Username:
Password: Lost Password?
 

Dear Guest!
Please sign up or login to use all features of the website.

  Reign of the Undead - Revolution Reign of the Undead Discussion
« Previous 1 2 3 4 5 6
How RotU works

Poll: Was this information usefull?
Yea, awesome!
Yea, I understood it.
It was okay.
I don't understand coding.
Nope, didn't understand anything.
I'm too lazy to read all this stuff
[Show Results]
 
Note: This is a public poll, other users will be able to see what you voted for.
Thread Modes
How RotU works
fabio Offline
Leader & Developer
*******
Administrators
Posts: 2,301
Threads: 107
Joined: Jul 2012
Thanks given: 275
Thanks received: 554
#1
02-04-2014, 03:40 PM
Hello Zombie-Community.

I got many requests from modders and scripters, how the RotU mod works. In the following lines I will explain as short as possible how I made the mod working like that.

Everything is based on the Quake 3 Engine.
First of all I had to patch some .exe and .dll files to protect the server of being flooded or crashed (If you want the fixed files please feel free to contact me via PM or E-Mail).

The mod itself is based on kilometers of C++ codes. It took me quiet a long time to write about 15.000 lines of code.

Now how it is coded....
Every map has around 300 waypoints. Every waypoint is connected to all other waypoints in range. So I get a list of waypoints which looks like this:

Code:
main()
{
    level.waypoints = [];

    level.waypoints[0] = spawnstruct();
    level.waypoints[0].origin = (-10155.5,-8417.45,0.124996);
    level.waypoints[0].childCount = 2;
    level.waypoints[0].children[0] = 1;
    level.waypoints[0].children[1] = 39;
    level.waypoints[1] = spawnstruct();
    level.waypoints[1].origin = (-10196.9,-8574.94,0.124996);
    level.waypoints[1].childCount = 2;
    level.waypoints[1].children[0] = 2;
    level.waypoints[1].children[1] = 0;
    level.waypoints[2] = spawnstruct();
    level.waypoints[2].origin = (-10384.7,-8622.07,0.124996);
    level.waypoints[2].childCount = 2;
    level.waypoints[2].children[0] = 3;
    level.waypoints[2].children[1] = 1;
    level.waypoints[3] = spawnstruct();
    level.waypoints[3].origin = (-10620.7,-8626.96,0.124996);
    level.waypoints[3].childCount = 2;
    level.waypoints[3].children[0] = 4;
    level.waypoints[3].children[1] = 2;
    level.waypoints[4] = spawnstruct();
    level.waypoints[4].origin = (-10798.3,-8591.58,0.124996);
    level.waypoints[4].childCount = 2;
    level.waypoints[4].children[0] = 5;
    level.waypoints[4].children[1] = 3;
    level.waypoints[5] = spawnstruct();
    level.waypoints[5].origin = (-11024.3,-8618.33,0.124996);
    level.waypoints[5].childCount = 2;
    level.waypoints[5].children[0] = 6;
    level.waypoints[5].children[1] = 4;
    .
    .
    .
}

To add those waypoints I wrote another "RotU-Developer-Tool" also based on automatically working methods (Just a Beta... I still add many waypoints by hand).

Now we got a list of around 300 waypoints.
Let's say we spawn a zombie on point A and we want him moving to point B behind a wall. The zombie has to calculate the shortest way to its destination around the wall while staying to the waypoints.

The method I used is named A*-Search.
This is a highly effective alrogithm that findes the shortest way to the destination waypoint.

Here is some code of the A*-Search method in my mod:
Code:
AStarSearch(startWp, goalWp)
{
    self endon("player_killed");

    pQOpen = [];
    pQSize = 0;
    closedList = [];
    listSize = 0;
    s = spawnstruct();
    s.g = 0; //start node
    s.h = distance(level.waypoints[startWp].origin, level.waypoints[goalWp].origin);
    s.f = s.g + s.h;
    s.wpIdx = startWp;
    s.parent = spawnstruct();
    s.parent.wpIdx = -1;

    pQOpen[pQSize] = spawnstruct();
    pQOpen[pQSize] = s; //push s on Open
    pQSize++;

    while(!PQIsEmpty(pQOpen, pQSize))
    {
        //wait 0.01; //todo
        n = pQOpen[0];
        highestPriority = 9999999999;
        bestNode = -1;
        for(i = 0; i < pQSize; i++)
        {
            if(pQOpen[i].f < highestPriority)
            {
                bestNode = i;
                highestPriority = pQOpen[i].f;
            }
        }
    
        if(bestNode != -1)
        {
            n = pQOpen[bestNode];
            //remove node from queue    
            for(i = bestNode; i < pQSize-1; i++)
            {
                pQOpen[i] = pQOpen[i+1];
            }
            pQSize--;
        }
        else
        {
            return;
        }  

        //if n is a goal node; construct path, return success
        if(n.wpIdx == goalWp)
        {
            x = n;
            for(z = 0; z < 1000; z++)
            {
                parent = x.parent;
                if(parent.parent.wpIdx == -1)
                {    
                    return x.wpIdx;

                }
                x = parent;
            }
            return;      
        }
    .
    .
    .
    .
    .
    .
    .
    .

    }

}

The method always returns the next waypoint the zombie should walk to. So if we repeat this method some times, the zombie will reach his destination at a time x. The time is calculated by DISTANCE/SPEED = TIME.

The rest of the mod is pretty simple coding.

For example setting up the waveorder:

Code:
setupwaves()
{
    level.wave_type = [];
    level.wave_type[0] = "normal";

    ////// wavetypes here //////

    //normal, toxic, freeze, speed, burning, chaos, boss1, boss3, endboss

    level.wave_type[1] = "normal";
    level.wave_type[2] = "toxic";
    level.wave_type[3] = "normal";
    level.wave_type[4] = "speed";
    level.wave_type[5] = "pseudo";
    level.wave_type[6] = "mixed";
    level.wave_type[7] = "normal";
    level.wave_type[8] = "freeze";
    level.wave_type[9] = "burning";
    level.wave_type[10] = "pseudo";
    level.wave_type[11] = "normal";
    level.wave_type[12] = "chaos";
    level.wave_type[13] = "normal";
    level.wave_type[14] = "mixed";
    level.wave_type[15] = "pseudo";
    level.wave_type[16] = "boss1";
    level.wave_type[17] = "freeze";
    level.wave_type[18] = "chaos";
    level.wave_type[19] = "pseudo";
    level.wave_type[20] = "boss3";
    level.wave_type[21] = "normal";
    level.wave_type[22] = "mixed";
    level.wave_type[23] = "endboss";


    level.maxwaves = 23;

    //////////////////////////////
}

Another aspect I got asked very often is how about saving the levels. How does this system work?
Well, all levels are sticked to your GUID (your CD key). But not only the levels. Everything is saved in a packet as a serverside variable.

For example this is my data packet (my GUID is replaced by *):
Code:
set data_****** 200-51264650-35-27-35-35-0-0-179-1-0-6910-0-181-0-90-0-0-0-6910-0-4-1-35-35-1

Another program running on my root machine saves the data packets to a mysql database.
So if the server restarts the datas are not lost.
This is made possible by the following code written in PHP (only a part of it):
Code:
.
.
.
    $result = $con->rcon($ip, $port, $password, "cvarlist data_");
    $pattern = '|^[A-Z ]{7} (\w+) "(.*)"$|i';
    foreach(array_map("rtrim", explode("\n", $result)) as $value)
    {
        if(preg_match($pattern, $value, $subpatterns))
        {
            $data = $subpatterns[2]."-".preg_replace("/data_/", "", $subpatterns[1]);
            $cvars[strtolower($subpatterns[1])] = explode("-", $data);
            }
    }
.
.
.

To read the data on server side I used the following code to explode "-":
Code:
    parms = explode(var, "-");
    self.rotu_level = (int)parms[0];
    self.rotu_points = (int)parms[1];
    self.skill_armored = (int)parms[2];
    self.skill_soldier = (int)parms[3];
    self.skill_engineer = (int)parms[4];
    self.skill_medic = (int)parms[5];
    self.skillpoints_available = (int)parms[6];
        .
        .
        .
        .

---------------------------------------------------------------------------------------------------

Of course there is much more behind the mod to make it working as it works now.
This was just an extrem short description where the mod is based on!
If you have further questions please feel free to ask in this topic.

---------------------------------------------------------------------------------------------------

If you want to buy the whole server side scripts (including levelsaver, serverfiles and developer-tool) please contact me via Mail or PM.

And always remember: I'm still doing my best to fix bugs and release new updates.
Buy Premium and get many new features in the next update package.

---------------------------------------------------------------------------------------------------

Regards,
Fabio
Website Find
Reply
Thanks given by:
Domovoy Offline
Basic Hunter
*
Posts: 34
Threads: 1
Joined: Jul 2012
Thanks given: 0
Thanks received: 0
#2
02-08-2014, 05:17 PM
fabio,
you should add one more voting option - ''I'm too lazy to read all this stuff''
Find
Reply
Thanks given by:
fabio Offline
Leader & Developer
*******
Administrators
Posts: 2,301
Threads: 107
Joined: Jul 2012
Thanks given: 275
Thanks received: 554
#3
02-08-2014, 05:35 PM
Done Smile
Website Find
Reply
Thanks given by:
Soldier . . . Offline
I am not a moderator
***
VIP
Donator
Insider
Posts: 222
Threads: 10
Joined: Jul 2012
Thanks given: 0
Thanks received: 90
#4
02-11-2014, 11:01 PM
I will vote "I don't understand that the compiler accept this" Huh

I assume you stripped a lot of the real code (includes, defines, variable declarations, functions, etc).
If not then I would like to know which compiler you uses.
Because its making programming a lot easier then Smile.
Find
Reply
Thanks given by:
fabio Offline
Leader & Developer
*******
Administrators
Posts: 2,301
Threads: 107
Joined: Jul 2012
Thanks given: 275
Thanks received: 554
#5
02-11-2014, 11:03 PM (This post was last modified: 02-11-2014, 11:03 PM by fabio.)
Well, this is based on C++ but you don't have to include anything. Also no declarations..
You declare vars and functions like this:

number = 1;
string = "lol";

myFuncion(parameter){ //anything }

The code isn't compiled. It is open source in the serverside pk3 file Wink
Website Find
Reply
Thanks given by:
Soldier . . . Offline
I am not a moderator
***
VIP
Donator
Insider
Posts: 222
Threads: 10
Joined: Jul 2012
Thanks given: 0
Thanks received: 90
#6
02-11-2014, 11:28 PM
So it's more scripting then writing real code that have to be compiled.
Then I misinterpreted the first post a bit.
Find
Reply
Thanks given by:
fabio Offline
Leader & Developer
*******
Administrators
Posts: 2,301
Threads: 107
Joined: Jul 2012
Thanks given: 275
Thanks received: 554
#7
02-12-2014, 09:17 AM
Yea, it's a engine based programming language. Just some parts of C++ and Java...
But all those scripting languages are mostly the same
Website Find
Reply
Thanks given by:
Share Thread:    


  • View a Printable Version
  • Subscribe to this thread


Users browsing this thread:
2 Guest(s)

  • Contact Us
  • Forum team
  • Forum stats
  • Return to Top
 
  • RSS Syndication
  • Lite mode
  • Home
  • Help
 
© Copyright 2025 by MODS-Clan
www.modszombies.com



Linear Mode
Threaded Mode