User Tag List

Page 1 of 2 12 LastLast
Results 1 to 10 of 11
  1. #1
    Whicked Sick Higor's Avatar
    Join Date
    Apr 2012
    Location
    Full sail ahead!
    Posts
    3,676
    Country:

    Code idea: Relating buildings directly among themselves.

    This isn't an impossible solution, it consists on buildings to directly relate themselves by storing each other's object references.

    My inspiration for this comes from the game Seven Kingdoms 2 (aka 7K2, old RTS), which I happen to have the source code (did my modifications there as well and learnt a lot).
    The game has various dynamic arrays which serve the purpose of making object location easier, but even at C++ level, relating fortresses, towns and other buildings to each other seemed like a obviously necessary choice to the coders to make enormous scale matches possible.

    Let's compare and extrapolate:
    7k2 has:
    - General object dynamic array
    - Units dynamic array
    - Towns dynamic array
    - Buildings dynamic array
    - Every object has it's array indexes stored for immediate access
    - ASM code in graphic interface (an obvious indicator that the game is heavily optimized)
    - Matches normally have up to 400 units in field, 100 edifications.
    - Full processing done on both server and clients (sync based multiplayer)

    Unreal has:
    - Actor dynamic array (actor list)
    - Actor list iterator functions at C++ level.
    - Collision hash iterator at C++ level.
    - Linked lists and custom arrays at UnrealScript.
    - Various useful events.
    - Processing differs efficiently between clients and server. (replication based multiplayer)
    Siege specific:
    - Matches normally have up to 50 buildings, 100 other dynamic actors.
    - Game processing handled by timers to avoid slowdowns.


    While we're talking about to different games, the inclusion of buildings makes this specific Unreal Tournament mod and any RTS game have elements in common.
    And having the full source code of a RTS no matter how old it is gives a lot of ideas.

    Ideas:
    - Dedicated lists that hold specific objects.
    Since we can't have dynamic arrays here, and UnrealScript is kinda slow for long iterations, this isn't as attractive unless the target object list is lesser than 20 element long.
    - Buildings directly related.
    Buildings have object references to other buildings within their influence radius, provides super fast location in code.
    - General event system.
    Something is created, all edifications should know.
    Something is deleted, all edifications should know as well.
    Events might be logged or used by the game handler for other purposes as well.
    - Advanced team scoring.
    Just like siegestats but for teams, provides info on how many buildings there are, how much RU was spent on them, how many kills by mines, how long they lasted providing an efficiency level average.
    - Minimap.
    This is entirely possible, requires research and development, but i'm sure it can be done in this engine, even without a map texture at all.
    - History log/messaging.
    Being able to open a box with the latest 5 events, makes nuke messages, motion sensors and other news (building destroyed, building created) displayed in a more user friendly way.


    Some other ideas might come up later, but the first of them to apply would be:
    - Containers should hold other buildings's references themselves, so no RadiusActors() iterations are called.
    - Notify system that will update container's arrays upon building creation/destruction.

  2. #2
    Whicked Sick Higor's Avatar
    Join Date
    Apr 2012
    Location
    Full sail ahead!
    Posts
    3,676
    Country:

    Super Container sample

    This is an unfinished sample in the Super Container class...
    It addresses the repairing code.

    Old code:
    Code:
    simulated event Timer()
    {
    	local sgBuilding building;
    
    	Super.Timer();
    
    	if ( SCount > 0 || Role != ROLE_Authority )
            return;
    
    	foreach RadiusActors(class'sgBuilding', building, 240+(HealRadius*0.25)*Grade)
    		if ( sgBaseCore(building) == None && FRand() <= 0.5 + Grade/5
              && building.Team == Team && !bDisabledByEMP && !building.bDisabledByEMP)
            {
    					if (SiegeGI(Level.Game).bOverTime)
    					{
    					building.Energy = FMin(building.Energy + (HealAmount + Grade/5)/2,
                      building.MaxEnergy);
    					}
    					else
    					{
    			    building.Energy = FMin(building.Energy + HealAmount + Grade/5,
                      building.MaxEnergy);
    				    }
            }
    }

    New code:
    Code:
    var sgBuilding sgRelated[32];
    var int iRelated;
    
    simulated event Timer()
    {
    	local int i;
    
    	Super.Timer();
    
    	if ( SCount > 0 || Role != ROLE_Authority  || !bDisabledByEMP || (iRelated <= 0) )
    		return;
    
    	While ( i < iRelated )
    	{
    		if ( !sgRelated[i].bDisabledByEMP && (sgRelated[i].Energy < sgRelated[i].MaxEnergy) && (FRand() <= 0.5 + Grade*0.2 )
    		{
    			if ( SiegeGI(Level.Game).bOverTime )
    				sgRelated[i].Energy = FMin(sgRelated[i].Energy + (HealAmount + Grade*0.2)*0.5, sgRelated[i].MaxEnergy);
    			else
    				sgRelated[i].Energy = FMin(sgRelated[i].Energy + HealAmount + Grade*0.2, sgRelated[i].MaxEnergy);
    		}
    		++i;
    	}
    }
    Differences:
    - Only iterate if we have one or more sgRelated building.
    - sgRelated buildings already pass the Team and Distance checks.

    Consequences:
    - Faster code, specially on leech games.
    - Limitation: up to 32 buildings are healed per container.

    Q: How do we add elements to the sgRelated?
    A: That will be handled by an event system, these events should be called on every sgBuilding subclass with these two methods: BuildingCreated( building), BuildingDestroyed( building). Then these methods will be re-implemented in the container classes to filter out buildings that shouln't be healed and add those that should into the sgRelated array.
    Also, on every upgrade, the list will be refreshed so that more things enter the sgRelated array.


    Feralidragon, I was wrong, the healing isn't simulated, the reason we see the numbers move so smoothly, is due to the server updating them so frequently.
    Maybe it would be appropiate to leave the old RadiusActors() iterator for clientside simulation in case NetUpdateFrequency is finally reduced.

  3. #3
    Whicked Sick Higor's Avatar
    Join Date
    Apr 2012
    Location
    Full sail ahead!
    Posts
    3,676
    Country:

    Setting up the general event system

    General event system that interacts with all sgBuildings and GameInfo.

    sgBuilding:

    PostBeginPlay:
    Code:
    event PostBeginPlay()
    {
    	if ( Pawn(Owner) != None )
    		Team = Pawn(Owner).PlayerReplicationInfo.Team;
    
    	if ( Team < 0 || Team > 3 )
    		Team = 0;
    
    	if ( Team == 0 )
    		Texture = SpriteRedTeam;
    	else
    		Texture = SpriteBlueTeam;
    
    	Energy = MaxEnergy/5;
    	SCount = BuildTime*10;
    	//LightHue = Team*160;
    	DoneBuilding = false;
    
    	Spawn(Class'sgSmokeGenerator');
    
    	SetTimer(0.1, true);
    	Timer();
    
    	SiegeGI(Level.Game).BuildingCreated( self);
    }
    - Modified indentation style to Unreal.
    - Calls BuildingCreated on the Siege game info actor.


    Destroyed, we implement this event on this class now.
    Code:
    //WARNING: ALL SUBCLASSES THAT IMPLEMENT DESTROYED() MUST CALL SUPER.DESTROYED()!!!!
    event Destroyed()
    {
    	SiegeGI(Level.Game).BuildingDestroyed( self);
    }
    - Calls BuildingDestroyed on the Siege game info.


    Now we go into the SiegeGI class, and add these functions:
    Code:
    //General event system, a building has been created and initialized
    function BuildingCreated( sgBuilding sgNew)
    {
    	local sgBuilding sgB;
    	
    	ForEach AllActors (class'sgBuilding', sgB)
    	{
    		if ( sgB != sgNew )
    			sgB.BuildingCreated( sgNew);
    	}
    }
    
    //General event system, a building has been destroyed
    function BuildingDestroyed( sgBuilding sgOld)
    {
    	local sgBuilding sgB;
    	
    	ForEach AllActors (class'sgBuilding', sgB)
    	{
    		if ( sgB != sgOld )
    			sgB.BuildingDestroyed( sgOld);
    	}
    }
    - Those two functions can be later used to collect information necessary to generate team statistics, map information, and other user-created systems like a unified building construction message without having to implement it on every subclass.


    Back to sgBuilding now, we implement the user event notifications:
    Code:
    //Notifications
    function BuildingCreated( sgBuilding sgNew);
    function BuildingDestroyed( sgBuilding sgOld);
    - These events, just like ones called from C++ will provide extended functionality to subclasses that needs them.


    Go to WildcardsSuperContainer, we implement these events in this subclass:
    Code:
    //Super container notifications
    function BuildingCreated( sgBuilding sgNew)
    {
    	local float InRadius;
    
    	if ( (sgNew.Team == Team) && (sgBaseCore(sgNew) == None) && (iRelated < ArrayCount(sgRelated)) )
    	{
    		InRadius = 240+(HealRadius*0.25)*Grade + sgNew.CollisionRadius;
    		if ( VSize(Location - sgNew.Location) <= InRadius )
    			sgRelated[iRelated++] = sgNew;
    	}
    }
    
    function BuildingDestroyed( sgBuilding sgOld)
    {
    	local int i;
    
    	For ( i=iRelated-1 ; i>=0 ; i-- )
    	{
    		if ( sgRelated[i] == sgOld )
    		{
    			sgRelated[i] = sgRelated[--iRelated];
    			sgRelated[iRelated] = none;
    			break;
    		}
    	}
    }
    - Buildings are now added into the sgRelated array upon creation.
    - Buildings will be deleted from the sgRelated array upon destruction.

    Still in WildcardsSuperContainer, we add another rule, because containers gain heal radius when upgraded.
    Old function:
    Code:
    function Upgraded()
    {
        local float percent;
        local float scale;
    
        if ( SiegeGI(Level.Game) != None )
        {
            if ( Grade < 2 )
                scale = 1;
            else if ( Grade < 3 )
                scale = 2;
            else if ( Grade < 4 )
                scale = 3;
            else if ( Grade < 5 )
                scale = 4;
    		else if ( Grade >= 5 )
                scale = 5;
            SiegeGI(Level.Game).MaxRus[Team] -= StorageAmount;
            StorageAmount = default.StorageAmount + 50 * scale;
            SiegeGI(Level.Game).MaxRus[Team] += StorageAmount;
            percent = Energy/MaxEnergy;
            MaxEnergy = default.MaxEnergy * (1 + Grade/2);
            Energy = percent * MaxEnergy;
        }
    }
    New function:
    Code:
    function Upgraded()
    {
    	local float percent, scale;
    	local sgBuilding sgB;
    
    	if ( SiegeGI(Level.Game) != None )
    	{
    		scale = Clamp( Grade, 0, 5);
    		SiegeGI(Level.Game).MaxRus[Team] -= StorageAmount;
    		StorageAmount = default.StorageAmount + 50 * scale;
    		SiegeGI(Level.Game).MaxRus[Team] += StorageAmount;
    		percent = Energy/MaxEnergy;
    		MaxEnergy = default.MaxEnergy * (1 + Grade/2);
    		Energy = percent * MaxEnergy;
    
    		//Rebuild sgRelated array
    		iRelated = 0;
    		foreach RadiusActors(class'sgBuilding', sgB, 240+(HealRadius*0.25)*Grade)
    			if ( (sgBaseCore(sgB) == None) && (sgB.Team == Team) && (iRelated < 32) )
    				sgRelated[iRelated++] = sgB;
    	}
    }
    - sgRelated array is rebuilt when the heal radius increases, instead of setting the array elements to NONE, we simply set the ceiling index (iRelated) to 0, that's because we're sure that the new array will have equal or more elements than the old one.
    - Removed unnecessary code with the 'scale' determination, Clamp( V, A, B) returns an integer V between the values A and B.

    Also, sub implementation of PostBeginPlay in WildcardsSuperContainer for containers added after other constructions:
    Code:
    event PostBeginPlay()
    {
    	local sgBuilding sgB;
    
    	Super.PostBeginPlay();
    
    	iRelated = 0;
    	foreach RadiusActors(class'sgBuilding', sgB, 240+(HealRadius*0.25)*Grade)
    		if ( (sgBaseCore(sgB) == None) && (sgB.Team == Team) && (iRelated < 32) )
    			sgRelated[iRelated++] = sgB;
    }
    - The sgRelated array is generated for the first time when the Super Container finishes building.
    Last edited by Higor; 07-12-2012 at 07:56 PM. Reason: Added a break, added a PostBeginPlay() sub implementation

  4. #4
    Administrator SAM's Avatar
    Join Date
    Jan 2011
    Posts
    8,296
    Country:
    Excellent ideas Higor. Have you played Total Annihilation??

  5. #5
    Whicked Sick Higor's Avatar
    Join Date
    Apr 2012
    Location
    Full sail ahead!
    Posts
    3,676
    Country:
    Nope, but if there's any good concept to apply, fire away.

  6. #6
    The Best There Ever Will Be! |uK|B|aZe//.'s Avatar
    Join Date
    Jan 2011
    Location
    London, United Kingdom
    Posts
    6,860
    personally i would like to see a capture function of some sort which would take a certain length of time or a certain amount of RU to capture an enemys super container or other sort of buildings like a nuke etc

  7. #7
    Whicked Sick Higor's Avatar
    Join Date
    Apr 2012
    Location
    Full sail ahead!
    Posts
    3,676
    Country:
    Quote Originally Posted by |uK|B|aZe//. View Post
    personally i would like to see a capture function of some sort which would take a certain length of time or a certain amount of RU to capture an enemys super container or other sort of buildings like a nuke etc
    WOLOLO!! (win if get the reference)
    This would indeed be the ultimate trolling tactic in Siege.

  8. #8
    Whicked Sick |uK|Grimreaper's Avatar
    Join Date
    Feb 2011
    Posts
    1,315
    Country:
    higor your on fire dude keep up the work!


  9. #9
    Administrator SAM's Avatar
    Join Date
    Jan 2011
    Posts
    8,296
    Country:
    Quote Originally Posted by Higor View Post
    WOLOLO!! (win if get the reference)
    This would indeed be the ultimate trolling tactic in Siege.
    Lol it would...so would reclaim (unbuild) an enemy structure and reclaim x amount of the build RU if successful.

  10. #10
    The Best There Ever Will Be! |uK|B|aZe//.'s Avatar
    Join Date
    Jan 2011
    Location
    London, United Kingdom
    Posts
    6,860
    Quote Originally Posted by Higor View Post
    WOLOLO!! (win if get the reference)
    This would indeed be the ultimate trolling tactic in Siege.
    like i said it would be very cool if you could capture an enemy's building

    reclaiming an enemy's building would be too easy essentially it should be capturing then "removing aka reclaiming" which is the same thing pretty much depending on what building type it is (nuke or super cont etc)

    --- Updated ---

    Quote Originally Posted by Higor View Post
    WOLOLO!! (win if get the reference)
    This would indeed be the ultimate trolling tactic in Siege.
    LOL EXACTLY MY POINT

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. black things buildings?
    By |uK|fleecey in forum zp| * * * -=[SIEGE]=- |uK| One Night Stand -=[SIEGE]=- Server * * *
    Replies: 2
    Last Post: 09-21-2013, 05:29 PM
  2. Hawaii removing buildings on both teams
    By Sean in forum Reports/Complaints & Appeals
    Replies: 7
    Last Post: 06-18-2013, 08:30 PM
  3. idea for map???
    By 'Zac in forum Map Making, Suggestions & Questions
    Replies: 3
    Last Post: 09-07-2012, 07:07 PM
  4. Another Idea
    By Moko in forum IST Archive
    Replies: 6
    Last Post: 07-06-2012, 02:52 PM
  5. Code idea: Relating buildings directly among themselves.
    By Higor in forum #siegepug Discussion
    Replies: 9
    Last Post: 06-05-2012, 09:52 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •