Jump to content


Gambit

Member Since 02 Nov 2011
Offline Last Active Yesterday, 07:43 PM

#1114048 Is it possible to switch between default wargear and upgraded one?

Posted by Gambit on 18 March 2021 - 08:55 PM

SCaR is very simple, and anyone with prior coding knowledge will have an easy time with it :thumbsuphappy:

Even easier than Python.

 

BUT... Like all things, one needs time to adjust. Both to the new functions, and the environment.

Now, regrading Heroes, the solution's conception is "easy", the implementation.... Not that much.

 

The idea is:

1] For units that can posses, to additionally store: Position and Possessed name squads. (This means race profile updates as well)

2] Whenever a unit is possessing (we need a rule checking it) AND/OR it no longer exists, to check if a squad with the possessed name exists in proximity of the old one. The rule must have an interval of 0 (or 0.125 sec, since the engine makes 8 "passes" per sec: 0.125x8 = 1sec), so than NOT to mess things up, with any other possible squads!!
3] If so detected, transfer current experience to the new squad, with the appropriate adjustment factor, based on "type difference".

 

It sounds easy, and perhaps it is...

Bah, for any experienced coder, it is a piece of cake, really :p

BUT even for him, it needs time to implement.

 

If I ever do that, Experience will get an UI BAR.

Like in Warcraft III, or any other game with levels.

 

I mean, if we are to make it perfect, ... we will make it PERFECT. No compromises.




#1113977 Is it possible to switch between default wargear and upgraded one?

Posted by Gambit on 15 March 2021 - 09:51 AM

The flexibility regarding Hardpoint Swapping is limited, so I understand your decision to skip it altogether.

 

OK, so weapon upgrades were mostly intended for researches (like the plasma pistols for SMs), and squad upgrades (like Beavy Bolters for SMs). And these must be PERMANENT, the designers didn't want "rogue" modifiers fiddling with the weapons. Because it would cause ugly visual results.

That is why the designers FORBADE reverting hardpoints to previous ones.

For harpoints, there is only ONE way. Up (I mean the NEXT one, of course).

 

As for the Noice Marines Harmonics, there are a couple of things to consider:

- The actual index of each weapon is calculated INTERNALLY. Meaning that, if you have weapons only in (say) weapon_03 and weapon_07, then the engine will consider the first (the _03), as the FIRST weapon, and the second one (the _07) as the SECOND weapon. The _01 and _02 and so forth of the AE enumeration is only for the user.

(The same goes for Hardponts!)

- So, in order to swap weapons, you need to add DUMMY ones in-between, not simply "skip" entries.

- Also, using weapon_change to jump to a non-existent hardpoint (say, I have 4 weapons, and I order a weapon_change of 6), will jump to the LAST weapon in the list, of the specific hardpoint.

- Now, weapon_change swaps ALL weapons to the ordered harpoint.

 

So, in order to achieve the desired end, I HAD to enable/disable certain hardpoints, AND to make sure I added many dummy ones, so when the swap happens, NO attached leader to suffer the "swapping" effect as well!!

 

 

It is kinda like "playing with fire" :p

You must know exactly what you are doing - and in such delicate issues, only trial and error is actually what works.




#1113970 Is it possible to switch between default wargear and upgraded one?

Posted by Gambit on 14 March 2021 - 06:02 PM

Hello brother Tony33.

The only way to do that, is with the SoB emperor's touch ability mechanic you mentioned, as a TIMED ability...

Regrettably, toggle or on-demand hardpoint change does not work.

Meaning that (besides the weapon_change ability mechanic), once as hardpoint is increased by a modifier, it CANNOT go back.

It is limiting, but there is a special reason the designers decided it (I can elaborate, if you want).

 

Anyway, if you need examples on how to do it a bit differently than Vanilla, see how I coded the Harmonics ability ion Emperor's Children.

For a melee weapon alternative, have a look at the Hammerhand ability in IDH ( for that, I had to create more weapons for ALL attached commanders, because the weapon_change affects the WHOLE squad).

 

It is a bit limiting, regardless...




#1113279 Cinematic Battles

Posted by Gambit on 27 January 2021 - 04:01 PM

Hmmm....

Brother Kasrkin is the Campaign SCaR expert...

If he is not available, I will look into it, at some time in the future :thumbsuphappy:




#1112311 Cinematic Battles

Posted by Gambit on 30 November 2020 - 09:04 AM

Huge pack though!!! :thumbsuphappy:




#1110747 Quick Question on the "advanced" Build menu.

Posted by Gambit on 06 August 2020 - 03:38 PM

For a building to appear in the advanced menu, you must go into the structure_buildable_ext and set the advanced_build_option to [true].

BUT to make the advanced build button available to your builders, you NEED an UI update as well.

Because they only have the standard build button, and this does NOT include the other buildings (obviously).

 

For this, you need something like FreeUI. OR, if you have UI/Taskbar skills, you can modify the taskbar yourself :)




#1110417 Realistix Kapak Mod - Issues, Suggestions, Help

Posted by Gambit on 20 July 2020 - 01:46 PM

...what would be the "accuracy when moving"vallue of a unit if its basic 'accuracy' vallue is 0.4 and its "accuracy reduction when moving" vallue is 0.75 ?

The moving accuracy formula is : accuracy x ( 1 - accuracy when moving)

 

In your example:

0.4 is the standing shooting accuracy.

0.4x(1-0.75)= 0.1 is the moving shooting accuracy.

 

More explanation: 1-0.75, translates to: "it drops by 75%", so what remains is 100-75=25% of the original value. So you must find the 25% of the original, hence x0.25.

 

So yeah! If accuracy reduction when moving is high, you get a really high reduction!

The 0.75 is too much, so it will have the unit miss too much. If you set accuracy reduction when moving to 0.99 (TOO HIGH!), the accuracy when moving will drop very close to zero.

And as I said, if you set accuracy reduction when moving to 1, the unit will NOT SHOOT AT ALL when moving (see the heavy bolters or missile launchers of tactical marines, for example)

 

I'm not good at mathematics...

I am a physicist, and I dare say a good mathematician as well :grad:

 

 

...it seems to me that if this is a multiplication it makes no sense that the more the "accuracy reduction when moving" vallue is high, the lower the ""accuracy"" vallue will be if both are combined. But it can't be a substraction because with the example I took the final ""accuracy when moving"" vallue would be negative, and it also makes no sense.

Hehehe. Nice "deduction"!

As I said, it is multiplication, but with 1-value.

 

 

what do you call ""standard accuracy"" ?

The accuracy value  :p




#1110000 Alien Hunters - Deathwatch Development

Posted by Gambit on 02 July 2020 - 10:19 AM

Hello brother.

Well, the Alien Hunters are at alpha stage.

My initial plan was to make it THE BEST race mod there is, and our team (both 3D and Audio) is really good at it.

But... Life intervened, and other projects took precedence, and... It is now low in priority.

At the moment, I will focus on Unification (probably Last Stand), and the Tyranid Swarm race!

If you want to help us testing it, then please contact brother Unsociallobster, who is responsible for the team members (among other things!). In fact, I will uploading out LATEST TyrSwrm build today, to start preparing it for a public release.




#1104901 Scar script questions

Posted by Gambit on 25 November 2019 - 09:03 AM

Ahem....

No, this is not the "proper" way brother BloodyVomit. Although, it WILL work.

 

See, the repeat is still there, and yeah, it WILL exit eventually - but the number of loops is still random.

Just think that at the 10nth entry, there will be 9 "trues" and 1 "false" array entries, so the loop will run until that specific "false" is chosen. This is an unnecessary number of calculations.

 

If you were to:

1] remove the Repeat.

2] after each choice, instead of having the entry set to "true", just remove it from the table, and

3] choose based on this: g_random = World_GetRand(1, table.getn(t_RandomIEPlayed)) instead of this: g_random = World_GetRand(1, 10),

it would be much better!

 

And you need not use this exiting condition: if g_random_ie_counter == 10 then

But this: if table.getn(t_RandomIEPlayed) == 0 then

 

Bottomline, you do not even need to use a loop at all :p

Just delete each entry you play, and re-select from an array with "trimmed" entries, until they reach 0.

 

Just saying...




#1104898 Scar script questions

Posted by Gambit on 24 November 2019 - 05:45 PM

If I understood correctly, you can code it differently - no loop needed.

1] Put all the "talks" in an array.

2] Each time you need one, randomly chose one from the total array entries, play it, and DELETE that entry from the array.

3] Have a random (within logical time limits) re-calling of the same rule, to achieve that  :grad:  (Rule Add One Shot).

 

Even if you do not want to use step 3], consider using the Array idea, in order TO EXCLUDE playing the same "Talk".




#1104891 Scar script questions

Posted by Gambit on 24 November 2019 - 11:02 AM

Repeat->Until / While, are risky...

Especially if the exiting condition is "poorly" coded. I mean, what if it takes 10000 loops in order for the conditions to be met?

 

I always use a "for", and make (say) 20 attempts. And I put the condtitions within the loop, and if they are met, then I use a "break".




#1104603 I got carpet bombing to work

Posted by Gambit on 03 November 2019 - 11:23 AM

OK, ready:

----------------------------------------
-- File: 'maraudertactic.ai'
-- Created by Gambit @ 02.11.2019

class 'MarauderTactic' (GuardVehicleTactic)

Marauder = {}

function MarauderTactic:__init( squad_ai ) super( squad_ai )

    self:SetName("Marauder Tactic")

    -- Modifiable Stats
    Marauder.G_Time_Between_Successive_Attacks = 0        -- If multiple bombers, do not have them attack simultaneously. Keep lower than 6, if enabled.
    Marauder.G_Proximity_Return_Distance = 38            -- The distance from base that we deem minimum to consider the flyer is "back to base".
    Marauder.G_Max_Attacking_Range_From_Base = 280        -- The max range OF THE ENEMY, that the flyer will attempt a fly-over.
    Marauder.G_AttackInfantry = true                    -- Self-explanatory.
    Marauder.G_AttackVehicles = true                    -- Self-explanatory. If both true, target will be chosen randomly.
    Marauder.G_AttackInfiltratedUnits = false            -- Self-explanatory.
    Marauder.G_AttackOnlyUnitsWeCanSee = false            -- Self-explanatory. Experiential. Better keep it to [false].
    Marauder.G_AttackOnlyUnitsWeCanSeeRange = 35        -- If previous is true, this is the detecting range (proximity) of our nearby troops.
    Marauder.G_DoNotAttackIfEnemyBuildingsAtLandingProximity = true        -- Self-explanatory.
    Marauder.G_DoNotAttackIfEnemyBuildingsWithin = 35                    -- If previous is true, this is the range (proximity).
    Marauder.G_HQ_Name = "guard_hq"                        -- The name of the HQ of the player. It is the AE name. No need to change, for Guard.

    -- Other Stats
    self.initialPosition = self.squad_ai:GetPosition()
    Marauder.G_Proximity_Return_Distance_Sqr = Marauder.G_Proximity_Return_Distance * Marauder.G_Proximity_Return_Distance
    Marauder.G_Proximity_Return_Distance_Triangulation = Marauder.G_Proximity_Return_Distance * 0.6
    Marauder.G_NextAttackTMR = g_iGMT
    if Marauder.G_Update_HQsTMR == nil then
        Marauder.G_Update_HQsTMR = g_iGMT
    end
    if Marauder.G_Player_HQsPositions == nil then
        Marauder.G_Player_HQsPositions = {}
    end
end


function MarauderTactic:InitAbilities()

    --[[ Init ability ID's  / ABILITIES NO LONGER USED!
    if Marauder.smoke_id == nil then
        Marauder.smoke_id = cpu_manager.stats:GetAbilityID( "guard_smoke_bombs" )
        Marauder.krak_id = cpu_manager.stats:GetAbilityID( "guard_krak_bombs" )
        Marauder.incendiary_id = cpu_manager.stats:GetAbilityID( "guard_incendiary_bombs" )
    end]]
end


function MarauderTactic:DoAbilities()

    -- First, update HQs positions every 8 secs
    if g_iGMT > Marauder.G_Update_HQsTMR + 8 then
        Marauder.G_Update_HQsTMR = g_iGMT
        self:UpdateHQs()
    end

    -- Now check if we must return (after an attack), or we are at a base
    self.initialPosition = self.squad_ai:GetPosition()
    local must_retrun = true
    for i = 1, table.getn(Marauder.G_Player_HQsPositions) do
        if distance_sqr(Marauder.G_Player_HQsPositions[i],self.initialPosition) < Marauder.G_Proximity_Return_Distance_Sqr then
            must_retrun = false
            break
        end
    end

    if self.squad_ai:CanJump() then
        -- In case we are away from the base, return to a random valid place (HQ)
        if must_retrun then
            local all_bases = table.getn(Marauder.G_Player_HQsPositions)
            if all_bases > 0 then
                local iBasePos = Marauder.G_Player_HQsPositions[math.random(1,all_bases)]
                self:ForceSquadJumpNearBack(iBasePos)
            end
        -- We are at base. We must try to perform an attack
        else
            if g_iGMT < Marauder.G_NextAttackTMR + Marauder.G_Time_Between_Successive_Attacks then
                return
            end
            local iEnemySquadInf = nil
            local iEnemySquadVeh = nil
            local iEnemySquad = nil
            if Marauder.G_AttackInfantry then
                iEnemySquadInf = Ability.Filters.CloseInfantryEnemy(self.initialPosition, Marauder.G_Max_Attacking_Range_From_Base, 5)
                --cpu_manager.cpu_player:FindFirstInfantryEnemy(self.initialPosition, Marauder.G_Max_Attacking_Range_From_Base, 5)
            end
            if Marauder.G_AttackVehicles then
                iEnemySquadVeh = Ability.Filters.CloseVehicleEnemy(self.initialPosition, Marauder.G_Max_Attacking_Range_From_Base, 1)
                --cpu_manager.cpu_player:FindFirstVehicleEnemy(self.initialPosition, Marauder.G_Max_Attacking_Range_From_Base, 1)
            end
            if iEnemySquadInf ~= nil and iEnemySquadVeh ~= nil then
                if math.random(1,2) == 1 then
                    iEnemySquad = iEnemySquadInf
                else
                    iEnemySquad = iEnemySquadVeh
                end
            elseif iEnemySquadInf ~= nil and iEnemySquadVeh == nil then
                iEnemySquad = iEnemySquadInf
            else
                iEnemySquad = iEnemySquadVeh
            end
            if iEnemySquad ~= nil then
                if Marauder.G_AttackInfiltratedUnits or (not iEnemySquad:IsInfiltrating()) then
                    local iEnemyPos = iEnemySquad:GetPosition()
                    if (not Marauder.G_AttackOnlyUnitsWeCanSee) or self:WeCanSeePos(iEnemyPos) then
                        -- Do NOT perform a flyover, if we have our troops nearby!
                        if cpu_manager.cpu_player:FindFirstHurtSquad( iEnemyPos, 6 ) == nil then
                            self:ForceSquadAttackJumpNear(iEnemyPos)
                            Marauder.G_NextAttackTMR = g_iGMT
                        end
                    end
                end
            end
        end
    end

    --[[ Check if we can deploy smoke / ABILITIES NO LONGER USED!
    if (self.squad_ai:CanDoAbility(Marauder.smoke_id)) then
    
        -- Search a squad
        local iRange = self.squad_ai:GetAbilityRange(Marauder.smoke_id)
        local oUnit = Ability.Filters.CloseHurt(self.squad_ai:GetPosition(), iRange, 1)
        if (oUnit ~= nil and oUnit:IsInCombat() and cpu_manager:GetUnitStrength(oUnit) > 150) then
            self.squad_ai:DoSpecialAbilitySquad(Marauder.smoke_id, oUnit:GetSquad())
        end
    end
    -- Check if we're in close combat - Krak
    local oEnemySquad = Ability.Filters.CloseVehicleEnemy(self.squad_ai:GetPosition(), 0, 1)
    if (oEnemySquad ~= nil) then
    
        -- Check if we can drop Krak Bombs
        if (self.squad_ai:CanDoAbility(Marauder.krak_id)) then
            self.squad_ai:DoSpecialAbility(Marauder.krak_id)
        end
    end
    -- Check if we're in close combat - Incendiary
    oEnemySquad = Ability.Filters.CloseInfantryEnemy(self.squad_ai:GetPosition(), 0, 5)
    if (oEnemySquad ~= nil and not oEnemySquad:IsBroken()) then
    
        -- Check if we can drop Incendiary Bombs
        if (self.squad_ai:CanDoAbility(Marauder.incendiary_id)) then
            self.squad_ai:DoSpecialAbility(Marauder.incendiary_id)
        end
    end]]
    --[[ Checks jump-able stuck squads, and force them to jump nearby / NO LONGER USED!
    if self.squad_ai:CanJump() then
        self:SolveStuckCase()
    end]]
end


function MarauderTactic:UpdateHQs()
    Marauder.G_Player_HQsPositions = {}
    for oBuilding in military_manager:GetBases() do
        if (oBuilding:IsValid() and oBuilding:GetBaseName() == Marauder.G_HQ_Name) then
            table.insert(Marauder.G_Player_HQsPositions,oBuilding:GetPosition())
        end
    end
end


-- Unstuck Code --------------------------------------------------
function MarauderTactic:SolveStuckCase()
    local iPosition = self.squad_ai:GetPosition()
    if iPosition.x ~= self.initialPosition.x or iPosition.z ~= self.initialPosition.z then
    -- NOT stuck, update previous position and return, we are all good
        self.initialPosition = iPosition
        return
    end

    -- If we got here, the squad is NOT moving. See if it is simply waiting, or is stuck!
    local state = self.squad_ai:GetTactic():GetState()
    if (self.squad_ai:IsInStateMove() or self.squad_ai:IsInStateAttackMove() or state == "Attack") and not self.squad_ai:IsInCombat()
    and iPosition.x == self.initialPosition.x and iPosition.z == self.initialPosition.z then
    -- STUCK!!!!! Run the unstuck code
        self:ForceSquadJumpNear(iPosition)
    end
    -- Update previous position anyway
    self.initialPosition = self.squad_ai:GetPosition()
end

function MarauderTactic:ForceSquadJumpNear(pos)
    local iPos = self.squad_ai:GetPosition()
    local vJumpPosition = self.squad_ai:GetPosition()
    local jumpDist = self.squad_ai:GetJumpDistance()
    local jumpDistSqr = jumpDist * jumpDist
    local vDir = cpu_manager:GetDirectionToEnemy(pos)
    -- First, try an unstuck jump TOWARDS the enemy
    -- Try to jump somewhere near, perform 30 checks in total, for a viable position
    for i = 1, 12 do
        -- Create a jump position
        vJumpPosition.x = pos.x + vDir.x * math.random(10, jumpDist)
        vJumpPosition.z = pos.z + vDir.z * math.random(10, jumpDist)
        -- Check if target position is in range and if unit is able to jump to target position
        local iDistanceSqr = distance_sqr(vJumpPosition, iPos)
        if iDistanceSqr < jumpDistSqr and self.squad_ai:CanJumpToPosition(vJumpPosition) then
            -- Jump to position
            self.squad_ai:DoJump(vJumpPosition)
            self.last_jump = g_iGMT
            self.m_iLastGatherMove = self.last_jump - 10
            return
        end
    end
    -- Then try any random nearby place, as a secondary option
    for i = 1, 18 do
        -- Create a jump position
        vJumpPosition.x = pos.x + 0.7 * math.random(-jumpDist, jumpDist)
        vJumpPosition.z = pos.z + 0.7 * math.random(-jumpDist, jumpDist)
        -- Check if target position is in range and if unit is able to jump to target position
        local iDistanceSqr = distance_sqr(vJumpPosition, iPos)
        if iDistanceSqr < jumpDistSqr and self.squad_ai:CanJumpToPosition(vJumpPosition) then
            -- Jump to position
            self.squad_ai:DoJump(vJumpPosition)
            self.last_jump = g_iGMT
            self.m_iLastGatherMove = self.last_jump - 10
            return
        end
    end
end


function MarauderTactic:ForceSquadJumpNearBack(pos)
    local iPos = self.squad_ai:GetPosition()
    local vJumpPosition = self.squad_ai:GetPosition()
    local jumpDist = self.squad_ai:GetJumpDistance()
    local jumpDistSqr = jumpDist * jumpDist
    local vDir = cpu_manager:GetDirectionToEnemy(pos)
    -- Try to jump somewhere near, perform 15 checks in total, for a viable position, AWAY from the enemy
    for i = 1, 15 do
        -- Create a jump position
        vJumpPosition.x = pos.x - vDir.x * math.random(4, Marauder.G_Proximity_Return_Distance_Triangulation)
        vJumpPosition.z = pos.z - vDir.z * math.random(4, Marauder.G_Proximity_Return_Distance_Triangulation)
        -- Check if target position is in range and if unit is able to jump to target position
        local iDistanceSqr = distance_sqr(vJumpPosition, iPos)
        if iDistanceSqr < jumpDistSqr and self.squad_ai:CanJumpToPosition(vJumpPosition) then
            -- Jump to position
            self.squad_ai:DoJump(vJumpPosition)
            --self.last_jump = g_iGMT
            --self.m_iLastGatherMove = self.last_jump - 10
            return
        end
    end
end


function MarauderTactic:ForceSquadAttackJumpNear(pos)
    local vJumpPosition = self.squad_ai:GetPosition()
    local jumpDist = self.squad_ai:GetJumpDistance()
    local jumpDistSqr = jumpDist * jumpDist    
    local ix = 0; local iz = 0;
    if sqr(pos.x-vJumpPosition.x) < 0.0001 then
        iz = 1
    else
        local a = (pos.z-vJumpPosition.z)/(pos.x-vJumpPosition.x)
        ix = math.sqrt(1/(sqr(a) + 1))
        iz = math.abs(a*ix)
    end
    if vJumpPosition.x > pos.x then ix = -1*ix end
    if vJumpPosition.z > pos.z then iz = -1*iz end
    -- Try to jump somewhere near, perform 10 checks in total, for a viable position
    for i = 1, 10 do
        -- Create a jump position
        local rndm = math.random(25, 40)
        vJumpPosition.x = pos.x + ix*rndm
        vJumpPosition.z = pos.z + iz*rndm
        -- Check if target position is in range and if unit is able to jump to target position
        local iDistanceSqr = distance_sqr(vJumpPosition, self.initialPosition)
        if iDistanceSqr < jumpDistSqr and self.squad_ai:CanJumpToPosition(vJumpPosition) then
            if Marauder.G_DoNotAttackIfEnemyBuildingsAtLandingProximity then
                -- Do NOT attempt the jump, if we are to land near enemy buildings!
                local iBuilding =  Ability.EntityFilters.CloseBaseEntityEnemy(vJumpPosition, Marauder.G_DoNotAttackIfEnemyBuildingsWithin, 1)
                if iBuilding ~= nil then return end
            end
            -- Now, Jump to position
            self.squad_ai:DoJump(vJumpPosition)
            --self.last_jump = g_iGMT
            --self.m_iLastGatherMove = self.last_jump - 10
            return            
        end
    end
end


function MarauderTactic:WeCanSeePos(iPos)
    local iRangeSqr = Marauder.G_AttackOnlyUnitsWeCanSeeRange * Marauder.G_AttackOnlyUnitsWeCanSeeRange
    for oUnit in military_manager:GetSquads() do
        if oUnit:IsValid() then
            if distance_sqr(oUnit:GetPosition(),iPos) < iRangeSqr then
                return true
            end
        end
    end
    return false
end

For anything else, just say so brother Moreartillery. :thumbsupcool:




#1104559 Missing 2 textures

Posted by Gambit on 30 October 2019 - 12:05 AM

Very good!!

I have already coded the first squads of the race, I would say I am at 25% of units.

Then it's buildings, and then fleshing it out :thumbsuphappy:

I am sure you gonna like it.




#1104540 Missing 2 textures

Posted by Gambit on 29 October 2019 - 08:41 AM

I can make new ones if you want.

Thanks brother NL, I did that already, it was only 2 textures!!!

BUT I may need your help with the icons of the Fallen Angels, and their Taskbar...

Are you interested??? :thumbsupcool:

 

Is it possible to change the cannibalism effect from increasing health to something else, like giving the player requisition?

Yes, jut only via SCaR...




#1104477 Fallen Angels Beta Thread

Posted by Gambit on 25 October 2019 - 11:32 PM

According to the fluff,don't the Havoks always start with Heavy Bolters as they are the heavy weapon specialists and then upgrade to different weapons?

Brother Kek, I accidental wrote "bolters" above! If you look again, in the very next sentence, I say "They can upgrade their heavy bolters to...".

So yeah, they all start with heavy bolters. And they all, always carry heavy weapons :thumbsuphappy:

 

No builder

Well, after having seen brother Kek's Warpsmith, I DEFINITELY want to use him!

The Fallen are Dark Angels anyway, and we can design them as we want them to.

My approach is: "Tempted by Chaos, but didn't fully succumbed to it".

The mechanic behind this, is a SHIFTING ALIGNMENT game. The same as Cypher.

So they are NOT fully chaos!

Let's keep the builder.

 

That being said, we still keep that TH HQ idea?

Or I make them "standard"?