Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

Caischcer

MOD: Extra Daemons

Recommended Posts

Caischcer    10

I have been curious to see a mod adding a certain fan-made "Cascade" daemon. I don't know anything about lua but I do know some programming: python, basic php, very basic C, some javascript, I know some commands and began a few weeks ago to investigate batch scripting, not bragging or anything I am really just a guy who doesn't seem to finish a language before grabbing a new one thus I do not fully master a single language, not that I am even close to mastering any either. I know nothing.
 
I was a bit disappointed when I realized there are only 3 algorithms ( also known as "reverse daemons") in the game. So I also wish to add some of those, one for each daemon. Man It took me like 40 minutes to find the freaking file that contains the code for the daemons but if you are interested the file is "npc_abilities.lua" in InvisibleInc\scripts\sim\abilities\npc_abilities.lua (almost all modding is done within the scripts folder mainly in the sim subfolder for most mods in the master mod list)   
 
Well so far the code looks like this:

-- I have set up a skeleton for the reverse daemons:--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--MODDED REVERSE DAEMONS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\			mdmute = util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDMUTE? ) )	{		icon = "gui/icons/daemon_icons/mdmute_image.png",		onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},			mdexploit = util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDEXPLOIT? ) )	{	icon = "gui/icons/daemon_icons/mdexploit_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mdfreedom = util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDFREEDOM? ) )	{	icon = "gui/icons/daemon_icons/mdfreedom_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mddiscipline =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDDISCIPLINE? ) )	{	icon = "gui/icons/daemon_icons/discipline_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mdcrack =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDCRACK? ) )	{	icon = "gui/icons/daemon_icons/crack_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mdtermination =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDTERMINATION? ) )	{	icon = "gui/icons/daemon_icons/--mdtermination_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mdflash =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDFLASH? ) )	{	icon = "gui/icons/daemon_icons/--mdflash_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mdclarity =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDCLARITY? ) )	{	icon = "gui/icons/daemon_icons/--mdclarity_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mdrebelion =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MREBELION? ) )	{	icon = "gui/icons/daemon_icons/--mdrebelion_image.png",	onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(1, 2)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )  			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},-- and made a list for cascade's minions:-- These are modded "minions" for cascade's functioninglocal MD_MINIONS_LIST = {	"mdminion_blowfish",	"mdminion_chain",	"mdminion_countermeasure",	"mdminion_failsafe",	"mdminion_labyrinth",	"mdminion_nomercy",	"mdminion_paradox",	"mdminion_rubiks",	"mdminion_siphon",	}-- and this is cascade:--==========================================================================--MODDED DAEMONS============================================================--==========================================================================	mdcascade = util.extend( createDaemon( STRINGS.DAEMON.PANIC ) ){        icon = "gui/Icons/daemon_icons/--cascade_image.png",        name = "Cascade",        desc = "One daemon is installed each turn",        shortdesc = "Additional Daemons installing",        activedesc = "ONE DAEMON INSTALLED EACH TURN",        onSpawnAbility = function( self, sim, player )                self.duration = 3                sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe = true, name = self.name, icon = self.icon, txt = string.format(self.activedesc, self.duration ) } )                sim:addTrigger( simdefs.TRG_END_TURN, self )                sim:addTrigger( simdefs.TRG_START_TURN, self )			end,					onTrigger = function( self, sim, evType, evData, userUnit )			if evType == simdefs.TRG_START_TURN and sim:getCurrentPlayer():isPC() then--                local units = {}--                for unitID, unit in pairs( sim:getAllUnits() ) do--                    if unit:getTraits().mainframe_program then--                             table.insert( units, unit )--                     end--				end--                if #units > 0 then--                        local index = sim:nextRand(1, #units)--                        local unit = units[ index ]--                        mainframe.invokeDaemon( sim, unit )--                end--			else--				DEFAULT_ABILITY.onTrigger( self, sim, evType, evData, userUnit )--					end				local programlist = MD_MINIONS_LIST				local daemon = programlist[sim:nextRand(1, #programlist)]				sim:getNPC():addMainframeAbility( sim, daemon, nil, 0 )			end,		onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )			sim:removeTrigger( simdefs.TRG_START_TURN, self )				end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )				end},-- I commented some code above because I don't feel like those pieces of code are necessary but   --they are still there in case it is necessary, but I don't know Cyberboy2000 know more lua than I-- do. I-- am hoping he gives me his opinion on this code.-- Now for the so-called minions:--//////////////////////////////////////////////////////////////////////////////--CASCADE'S MINIONS ///////////////////////////////////////////////////////////--////////////////////////////////////////////////////////////////////////////	mdminion_blowfish = util.extend( createDaemon( STRINGS.DAEMONS.PARADOX ) )	{		icon = "gui/icons/daemon_icons/cascade_image.png",			xValues = {1},		-- I think this one is ready 		onSpawnAbility = function( self, sim, player )			local trackerCount = self.xValues[ sim:nextRand(1, #self.xValues) ]			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { name = self.name, icon = self.icon, txt = string.format(self.activedesc, trackerCount )} )			sim:trackerAdvance( trackerCount )			player:removeAbility(sim, self )								end,		onDespawnAbility = function( self, sim )					end,			},	mdminion_rubiks = util.extend( createDaemon( STRINGS.DAEMONS.RUBIKS ) )	{		icon = "gui/icons/daemon_icons/cascade_image.png",		-- I don't know how to make this one choose 2 random devices to raise their firewalls instead of raising ALL devices firewalls		onSpawnAbility = function( self, sim, player )				sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { name = self.name, icon = self.icon, txt = string.format(self.activedesc, trackerCount )} )			sim:dispatchEvent( simdefs.EV_WAIT_DELAY, 0.5 * cdefs.SECONDS )			unit = sim:nextRand( sim:getAllUnits() )				unit:increaseIce(sim,1)			end					player:removeAbility(sim, self )								end,		onDespawnAbility = function( self, sim )					end,			},		mdminion_siphon = util.extend( createDaemon( STRINGS.DAEMONS.SIPHON ) )	{		icon = "gui/icons/daemon_icons/cascade_image.png",		-- This one is ready too, I think		onSpawnAbility = function( self, sim, player )			self._cpu = sim:nextRand(2, 3)			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { name = self.name, icon=self.icon, txt = string.format(self.activedesc, self._cpu ), } )				sim:getCurrentPlayer():addCPUs( -self._cpu )			player:removeAbility(sim, self )		end,		onDespawnAbility = function( self, sim, unit )		end,	},		mdminion_paradox = util.extend( createDaemon( STRINGS.DAEMON.PARADOX ) )	{		icon = "gui/icons/daemon_icons/cascade_image.png",			onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe=false, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )        end,				-- Errmmm. . . any ideas on how to make it block 2 programs? or maybe it could work if it adds cooldown to them for 1 turn and then removes the cooldown on despawn		--CODE		--CODE				onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end					},		mdminion_countermeasure = util.extend( createDaemon( STRINGS.DAEMONS.PANIC ) )	icon = "gui/icons/daemon_icons/cascade_image.png",		onSpawnAbility = function( self, sim, player )		-- is this I did bellow legit?			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe=false, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )            local npcPlayer = sim:getNPC()			for _, unit in ipairs(npcPlayer:getUnits() ) do			-- does the line bellow mean it is going to spawn an enforcer? or is it going to alert anything that is NOT an enforcer?				if unit:getBrain() and not unit:getTraits().enforcer then					unit:setAlerted(true)				end			end					local agent = nil    		local agents = sim:getPC():getAgents()    		agent = agents[ sim:nextRand( 1, #agents ) ]     		self._guardsTagged = {}			sim:addTrigger( simdefs.TRG_END_TURN, self )			sim:addTrigger( simdefs.TRG_START_TURN, self )	        end,        onTrigger = function( self, sim, evType, evData, userUnit )	    	if evType == simdefs.TRG_START_TURN and sim:getCurrentPlayer():isPC() then	    		local agent = nil	    		local agents = sim:getPC():getAgents()	    		agent = agents[ sim:nextRand( 1, #agents ) ] 	    		createCountermeasureInterest( self, sim, agent )            else                DEFAULT_ABILITY.onTrigger( self, sim, evType, evData, userUnit )            end        end,		onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )				sim:removeTrigger( simdefs.TRG_START_TURN, self )		end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end			},		mdminion_failsafe = util.extend( createDaemon( STRINGS.DAEMONS.FAILSAFE ) )	{	icon = "gui/icons/daemon_icons/cascade_image.png",		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe=false, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )        end,	--WHERE IS FAILSAFE'S SCRIPT?!? I can't find the script				onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end					},		mdminion_labyrinth = util.extend( createDaemon( STRINGS.DAEMONS.LABYRINTH ) )	{		icon = "gui/icons/daemon_icons/cascade_image.png",		drain = 2,		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { name = self.name, icon=self.icon, txt = self.activedesc } )	            self._affectedUnits = {}			local agent = nil	    		local agents = sim:getPC():getAgents()				-- is this I did bellow legit? or how do I choose a random agent to apply the debuff to?	    		unit = agents[ sim:nextRand( 1, #agents ) ] 		        if unit:getMP() then			        unit:addMP( -2 )			        unit:addMPMax( -2 )                    table.insert( self._affectedUnits, unit )		        end	        end			sim:addTrigger( simdefs.TRG_END_TURN, self )			end,		onDespawnAbility = function( self, sim )            for i, unit in pairs( self._affectedUnits) do                if unit:getMP() and unit:isValid() then			        unit:addMP( 2 )			        unit:addMPMax( 2 )                end            end			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},			mdminion_nomercy = util.extend( createDaemon( STRINGS.DAEMONS.MASK ) )	{	icon = "gui/icons/daemon_icons/cascade_image.png",		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe=false, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_END_TURN, self )        end,				 local npcPlayer = sim:getNPC()			for _, unit in ipairs(npcPlayer:getUnits() ) do				if unit:getBrain() and not unit:getTraits().enforcer then				-- the ability "overtuned reflexes" was never implemented by klei. It is some left over code on a trait an OMNI guard would have had if it had been implemented. The code for the trait seems functional thought				-- and it seems that it makes guards shoot you immediately if they see you. Of course this trait will be added to all guards that are not enforcers and will be removed after the minion is finished.				-- you can find the script that contains this unimplemented traits in sim\abilities\passive_abilities.lua and you can see the unimplemented guards at sim\unitdefs\guarddefs.lua					unit:addAbility( overtuned_reflexes_passive )				end,			end,						onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )				local npcPlayer = sim:getNPC()			for _, unit in ipairs(npcPlayer:getUnits() ) do				if unit:getBrain() and not unit:getTraits().enforcer then					unit:removeAbility( overtuned_reflexes_passive )				end,			end,				end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end				},		mdminion_chain = util.extend( createDaemon( STRINGS.DAEMONS.CASCADE ) )	{	icon = "gui/icons/daemon_icons/cascade_image.png",			onSpawnAbility = function( self, sim, player )			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { name = self.name, icon=self.icon, txt = string.format(self.activedesc, self._cpu ), } )				-- I don't know if I can do this I did bellow. This is supposed to be the minion that resets the Cascade daemon.            sim:getNPC():addMainframeAbility( cascade )	},	-- As you see, I have a few doubts here and there, but I am still investigating. 


 
Take a look at the image:

 


post-467333-0-34763200-1436751124_thumb.
 
image by JimThePea

 

So about the reverse daemons I talked earlier here are few ideas:

  • (Siphon) - Bolt/Overclock: Gain +5 PWR (I kinda don't feel this name is enough I wanted something like "overdrive" but klei is working on a program that is named like that already I also thought "power spike" but I feel like that doesn't fit either)
  •  
  • (Paradox) - Mute/silence: Prevents alarm tracker from increasing for X turns
  •  
  • (Blowfish) - Muffler: Reduces alarm tracker increments by 1 for X turns
  •  
  • (Authority) - Jailbreak/Justice/Freedom: disables all safes for X (2?) turns
  •  
  • (Validate) - Breach/discipline: All heart monitors disabled (including 2.0's) for X turns
  •  
  • (Mask) - Flash: Reveals all daemon's and devices and their locations for X turns (not too sure about this)
  •  
  • (Rubiks)- Vulnerability/Crack/Apperture/Iteration/Revelation/Vision: Decreases all firewalls, that are greater than 1, by 1 firewall (I feel more inclined towards crack)
  •  
  • (Fractal) - Sniper/Terminate/Termination/Mercy/Execution: Kills 2(?) daemons
  •  
  • (cascade) - Exploit: installs other algorithms for 3 turns (works the same as cascade. I also take suggestions on this one's name)
  •  
  • (countermeasures) - prediction: tags ALL guards on the level (even if not visible)  and shows their patrols for one turn 

NEW Insurrection/Rebelion: guns don't consume ammo granades are not consumed (if 0 ammo you can still fire too), you are paid a small amount of credits upon finishing the game for every guard you slayed during this algorithms active time and alarm will only increase +1 instead of +2 when a guard is killed for X turns. Killing a guard after the algorithm is deactivated will cause clean-up costs again and alarms will +2 with every guard killed again. 

 

NEW Experience/Clarity: rebalance the daemon and algorithm spawn rates while active algorithms have a 60% chance of spawning and normal daemons have a 40% chance. Can you deal with the consecuences? or will you take the gamble?  

 

revlabyrinth is order algorithm already in the game

 

revmodulate is attunement algorithm already in the game

 

revfelix is fortune algorithm already in the game too

 

The idea for cascade's behavior right now is:

 

If activated it will last 3 turns (always, no more no less) there must be a cap on how many of this daemons can be found may be 2 or 3 when activated it will trigger each turn a "mini-daemon" of its own which will last 1 turn. The "mini-daemons" which we will call "minions" for now 'cause writing "mini-daemon" is too long may be repeated, this means that you may activate one and the next one might be the same minion that was triggered last turn with one exception, but I don't want to spoil the surprise yet. If at least one of the daemons is reversed cascade's execution is immediately terminated. the minions are the following:

 

1. +1 alarm, not too shabby you might say but still +1 alarm is +1 alarm. Hurry and get out of there.

 

2. 2 or 3 random devices +1 or +2 firewall levels. Like a little baby Rubiks.

 

3. -2 or -3 PWR. Again not a big deal, right??? better start saving boy, specially if you are running fussion.

 

4. If the number of programs installed in incognita > 3, 2 of your programs will be disabled for this turn. if  the number of programs installed in incognita < 3, 1 of your programs will be disabled for this turn.

 

5. A random agent's location was discovered a guard will go investigate the area. Get moving!

 

6. 1 random device rebooted. Hopefully it is not the akuma drone you just hacked that is facing you.

 

7. -2 MP (movement points) on 1 random agent. 

 

8. Guards will shot you on sight for 1 turn. If they see you, no second chances for this turn. Think before you act.

 

9. There is the chance that on the first or second turn you will fall on that heavenly 10% chance of triggering an algorithm that will take you out of your misery and send you straight to the espionage heaven.

 

10. OR that you trigger this daemon again and that you fall right into the corporate hell  for 3 MORE TURNS. This Minion can only be triggered on the last turn Cascade is active. If you don't see it, then you just saved yourself. Watch your step and don't trigger Cascade again. 

Share this post


Link to post
Share on other sites
Cyberboy2000    660

I just added my daemon to the list.

 

You also need to edit DEFAULT_DAEMONS in sim\worldgen, or else it won't spawn naturally (on devices)

 

I don't know if I can do the first line specifically since I heard modifications on the strings.lua file are not allowed and it seems to me like it is referencing the strings.lua file I am not sure

 

You can overwrite the first line like this:

mdcascade = util.extend( createDaemon( STRINGS.DAEMON.PANIC ) )

{

name = "Cascade",

desc = "One daemon is installed each turn",

shortdesc = "Additional daemons installing",

activedesc = "ONE DAEMON INSTALLED EACH TURN",

 

 

Also I don't now if I can access the file where the icons for daemons are located so I could place the cascade image. I do know that custom images have been applied to modded items, I don't now if this applies for daemons too.

 

You need to use the KWAD builder. There is an entire topic for that. I'll link it:

http://forums.kleientertainment.com/topic/54184-kwad/?hl=kwad/

 

 

Man It took me like 40 minutes to find the freaking file that contains the code for the daemons

 

I recommend Windows Grep. It's free and I think it really speeds up things when modding.

 

OK, here's an example of what a Cascade daemon might look like:

mdcascade = util.extend( createDaemon( STRINGS.DAEMON.PANIC ) )

{

        icon = "gui/Icons/daemon_icons/Daemons0007.png",

        name = "Cascade",

        desc = "One daemon is installed each turn",

        shortdesc = "Additional Daemons installing",

        activedesc = "ONE DAEMON INSTALLED EACH TURN",

        onSpawnAbility = function( self, sim, player )

                self.duration = 3

                sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe = true, name = self.name, icon = self.icon, txt = string.format(self.activedesc, self.duration ) } )

                sim:addTrigger( simdefs.TRG_END_TURN, self )

                sim:addTrigger( simdefs.TRG_START_TURN, self )

end,

onTrigger = function( self, sim, evType, evData, userUnit )

        if evType == simdefs.TRG_START_TURN and sim:getCurrentPlayer():isPC() then

                local units = {}

                for unitID, unit in pairs( sim:getAllUnits() ) do

                     if unit:getTraits().mainframe_program then

                             table.insert( units, unit )

                     end

                end

                if #units > 0 then

                        local index = sim:nextRand(1, #units)

                        local unit = units[ index ]

                        mainframe.invokeDaemon( sim, unit )

                end

        else

            DEFAULT_ABILITY.onTrigger( self, sim, evType, evData, userUnit )

        end

end,

onDespawnAbility = function( self, sim )

        sim:removeTrigger( simdefs.TRG_END_TURN, self )

        sim:removeTrigger( simdefs.TRG_START_TURN, self )

end,

executeTimedAbility = function( self, sim )

        sim:getNPC():removeAbility(sim, self )

end

},             

Share this post


Link to post
Share on other sites

Windows Grep is NOT free, it's shareware, and you're supposed to pay after 30 days evaluation.  I'm sure no one will come after you if you don't, but if you want a truly free/open-source grep tool, dnGrep works pretty well:

 

http://dngrep.github.io/

 

If you don't mind paying more for a commercial product, Power Grep is really nice.

Share this post


Link to post
Share on other sites
Cyberboy2000    660

Windows Grep is NOT free, it's shareware, and you're supposed to pay after 30 days evaluation.  I'm sure no one will come after you if you don't, but if you want a truly free/open-source grep tool, dnGrep works pretty well:

 

http://dngrep.github.io/

 

If you don't mind paying more for a commercial product, Power Grep is really nice.

 

Oh, I didn't know that. I thought registration was optional. I might switch to another grep tool then.

Sorry if I mislead anyone.

Share this post


Link to post
Share on other sites
JimThePea    53

Great to see someone having a go at putting Cascade in the game, should be a cinch for me to create the necessary .png files for you too! Your call on your interpretation of the daemon, I still like the original idea but here's a couple of alternative suggestions: The daemon sticks around for 5 or 6 turns and any daemons triggered in that time trigger an additional daemon, or perhaps the turn timer is a countdown and at the end two random low-level daemons are triggered, giving you time to prepare or get out. A reverse daemon for the latter could trigger two other algorithms instead. 

 

I've also done a couple more icons for programs, I'll post them up soon for folks to have a look at.

Share this post


Link to post
Share on other sites
Caischcer    10

Great to see someone having a go at putting Cascade in the game, should be a cinch for me to create the necessary .png files for you too! Your call on your interpretation of the daemon, I still like the original idea but here's a couple of alternative suggestions: The daemon sticks around for 5 or 6 turns and any daemons triggered in that time trigger an additional daemon, or perhaps the turn timer is a countdown and at the end two random low-level daemons are triggered, giving you time to prepare or get out. A reverse daemon for the latter could trigger two other algorithms instead. 

 

I've also done a couple more icons for programs, I'll post them up soon for folks to have a look at.

 

Thanks a lot! You have a great suggestion on cascade, the player should receive a warning if multiple daemons will install. I am thinking of having a hybrid between your suggestion and the original idea. It wouldn't install immediately (which makes sense in a real world point of view since it would be a much heavier download to handle for incognita, 3 daemons at once!) it would instead prompt the player warning him a daemon is installing next turn and next turn the daemon installs but the player is warned of the daemon installed beforehand again and so for the third and last turn (so despite you would know what daemon is comming after what daemon one turn before it happens) this would happen 3 times for 3 turns (idk if 3 turns is to OP) but the daemons would only last 1 turn each. So about the interpretations you asked here they are, big thanks to Plasmaflare for posting:

  • (Siphon) - Bolt: Gain X PWR (I kinda don't feel this name is enough I wanted something like "overdrive" but klei is working on a program that is named like that already I also thought "power spike" but I feel like that doesn't fit either)

 

  • (Paradox) - Mute: Prevents alarm tracker from increasing for X turns (decreasing alarm tracker seems very counterintuitive towards pressuring the player imo)

 

  • (Blowfish) - Muffler: Reduces alarm tracker increments by 1 for X turns

 

  • (Authority) - Jailbreak: disables all safes for X (2?) turns

 

  • (Validate) - Breach: All heart monitors disabled (including 2.0's) for X turns

 

  • (Mask) - Flash: Reveals all daemon's and devices and their locations for X turns (not too sure about this)

 

  • (Rubiks)- Vulnerability/Crack: Decreases all firewalls, that are greater than 1, by 1 firewall (I feel more inclined towards crack)

 

  • (Fractal) - Sniper: Kills 2(?) daemons

 

  • (cascade) - Exploit: installs other algorithms for 3 turns (works the same as cascade. I also take suggestions on this one's name)

 

  • (countermeasures) - prediction: tags ALL guards on the level (even if not visible)  and shows their patrols for one turn 

 

  • also idk why I like the idea of calling reverse daemons "angaels" or "aengels" silly idea of mine lol 

 

Share this post


Link to post
Share on other sites
Caischcer    10

Well so far my code for cascade looks like this, and before you look at the code if you note any resemblance to Cyberboy2000's snippet of code, it just me being short of ideas on how to program on a language I have never used. I can read the code and sorta of understand it but writing code is a totally different story. Don't be too harsh on me:

mdcascade = util.extend( createDaemon( STRINGS.DAEMON.PANIC ) ){        icon = "gui/Icons/daemon_icons/--cascade_image.png",        name = "Cascade",        desc = "One daemon is installed each turn",        shortdesc = "Additional Daemons installing",        activedesc = "ONE DAEMON INSTALLED EACH TURN",        onSpawnAbility = function( self, sim, player )                self.duration = 3                sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe = true, name = self.name, icon = self.icon, txt = string.format(self.activedesc, self.duration ) } )                sim:addTrigger( simdefs.TRG_END_TURN, self )                sim:addTrigger( simdefs.TRG_START_TURN, self )			end,					onTrigger = function( self, sim, evType, evData, userUnit )			if evType == simdefs.TRG_START_TURN and sim:getCurrentPlayer():isPC() then                local units = {}                for unitID, unit in pairs( sim:getAllUnits() ) do                     if unit:getTraits().mainframe_program then                             table.insert( units, unit )                     end				end                if #units > 0 then                        local index = sim:nextRand(1, #units)                        local unit = units[ index ]                        mainframe.invokeDaemon( sim, unit )                end			else				DEFAULT_ABILITY.onTrigger( self, sim, evType, evData, userUnit )					end			end,		onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )			sim:removeTrigger( simdefs.TRG_START_TURN, self )				end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )				end},              

 

I also already added "mdcascade" to the list of omni daemons and to default daemons as Cyberboy2000 suggested:

local OMNI_DAEMONS ={	bruteForce = 1,	fortify = 1,	duplicator = 1,	incognitaKiller = 1,	validate = 1,	siphon = 1,	agent_sapper = 1,	modulate = 1,	--authority = 1,	damonHider = 1,	--creditTaker = 1,	mdcascade = 1,}for i, abilityName in ipairs( OMNI_DAEMONS ) do    assert( npc_abilities[ abilityName ], abilityName )endlocal DEFAULT_DAEMONS ={	bruteForce = 1,	fortify = 1,	duplicator = 1,	incognitaKiller = 1,	validate = 1,	siphon = 1,	agent_sapper = 1,	modulate = 1,	authority = 1,	damonHider = 1,	creditTaker = 1,	mdcascade = 1,}for i, abilityName in ipairs( DEFAULT_DAEMONS ) do    assert( npc_abilities[ abilityName ], abilityName )end 

 

Now I have been looking for a way to express an order to activate a random daemon once cascade is activated but I want the daemon to activate with a 1 turn delay so basically here is some sort of pseudo code or flow diagram for me to illustrate cascade functioning:

Cascade: duration 4 turns{ upon activation:   choose 3 random daemons don't allow for any daemon to be a reverse daemon   return a list of the 3 daemons choosen   prompt player of cascade's triggering (show window displaying the cascade installing) first turn activated: show player the first daemon to be installed (DON'T INSTALL IT YET!)  for this first turn don't do anything just display the warning of the next daemon to be installed second turn activated: trigger the daemon shown in the warning to the player last turn      if ( daemons duration > 1){        set daemons duration to 1      }      else{      activate the daemon normally      }      show the player the a warning with the second daemon to be installed don't trigger it yetThird turn activated: end the first daemon's execution, trigger the daemon shown in the warning to the player last turn if ( daemons duration > 1){        set daemons duration to 1      }      else{      activate the daemon normally      }      show the player the a warning with the third daemon to be installed don't trigger it yetfourth turn activated: end the second daemon's execution, trigger the daemon shown in the warning  to the player last turn if ( daemons duration > 1){        set daemons duration to 1      }      else{      activate the daemon normally      }      end cascades execution, let the currently active daemon end by itself next turn 

This daemon can be very benign if you have central in your team as it will give you +5 power the on cascades first turn even if doesn't do anything yet, +5 power on the second, +5 on the third and +5 power on the fourth. There is absolutely no chance any of those daemons can be reversed though. Although if you get cascade's reverse daemon you will get 3 (or maybe 2 I might have to balance this daemon) guaranteed reversed daemons in a row. 

 

I have only a basic idea of how I could make this work. I know that shooting Monst3r's dart gun activates a daemon so I searched for its code:

traits = { finalStartItem = true, weaponType="pistol", baseDamage = 2, armorPiercing = 3, cooldown = 0, cooldownMax = 8, canSleep = true, spawnsDaemon = true }, 

 

What I am interested on is thos "spawnsDaemon" trait, although it is a trait after all. I don't now if a program can have a trait too.

But what about an event? like passing through an Infrared wall:

traits = { tripsDaemon = true, noghost = true, toolTipNote =STRINGS.PROPS.INFRARED_WALL_TOOLTIP, mainframe_icon = true, redSymbols={"red","wallbeam_red","wallBeamSymbol_red","lines_new"},tealSymbols={"teal","wallbeam","wallBeamSymbol","lines_new_teal"}}, 

 

It is a trait to the infrared wall, not an instruction to follow when an event occurs (well this is my interpretation of course, I am not sure whether I am right or wrong)

Well the only other way you can get a daemon installed that I can think of is by triggering by hacking:

-- Invokes an installed daemon on a mainframe device.-- The daemon is removed from the device, and if it is a daemon-host, it is moved to another device.local function invokeDaemon( sim, unit )	if unit:getTraits().mainframe_program then		sim:getNPC():addMainframeAbility(sim, unit:getTraits().mainframe_program, unit )		if unit:getTraits().daemonHost then    		--if possessed by a daemon-host, it jumps to a new system            local host = sim:getUnit( unit:getTraits().daemonHost )   			sim:moveDaemon( host )        else            -- Otherwise, simply remove the installed program.            unit:getTraits().mainframe_program = nil		end		endend 

 

I went into a hunt trying to follow the code's logic into what function corresponds to a daemon's activation upon hacking a daemon-protected device, but according to the dev's commentaries this is not a daemon activation function. It is rather a daemon killed or moved function, so I am not sure of where is the function I am looking nor how to trigger daemons from a daemon with a duration of 1 turn. If anyone has any idea please post your suggestions or code snippets in this topic.

Share this post


Link to post
Share on other sites
Caischcer    10

I've also done a couple more icons for programs, I'll post them up soon for folks to have a look at.

 

I have modified the daemon's names and effects list. Also I have a tip for you: Remember that in-game

daemons have icons that sometimes don't have anything to do with their names (e.g. rubiks and a bunny? what does that have to do??) so maybe you can throw in some more animal daemons or something new. 

Share this post


Link to post
Share on other sites
Cyberboy2000    660

Unfortunately, you can't just take a trait from an object and put it on a daemon. The game's logic doesn't work like that.

InvokeDaemon function is what happens when you hack an object with a daemon. It is also what I did with my version of the cascade.

It works like this:

   If has a daemon:

       install daemon on incognita

       if daemon is MKI (cyber consiousness)

           install a new daemon somewhere else

       else

           simply remove daemon.

       end

    end

However, this removes the daemon from an object. If you want to create a daemon out of nowhere, you need something like this:

local programlist = serverdefs.OMNI_PROGRAM_LIST_EASY

local daemon = programlist[sim:nextRand(1, #programlist)]

sim:getNPC():addMainframeAbility( sim, daemon, nil, 0 )

I'm not sure how one would make them last one turn only. Prehaps the easiest way is making duplicates of each daemon and making a new list of those 'easy' daemons.

 

Share this post


Link to post
Share on other sites
Caischcer    10

Well my code by 16/07/15 (dd/Mm/YY) looks like this on file npc_abilities.lua:

(line 198)--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--MODDED REVERSE DAEMONS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\			mdmute = util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDMUTE? ) )	{		icon = "gui/icons/daemon_icons/--mdmute_image?.png",		onSpawnAbility = function( self, sim, player )			self.duration = sim:nextRand(2, 3)			sim:dispatchEvent( simdefs.EV_SHOW_REVERSE_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )            sim:getPC():getTraits().program_cost_modifier = (sim:getPC():getTraits().program_cost_modifier or 0) - 1			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )            sim:getPC():getTraits().program_cost_modifier = (sim:getPC():getTraits().program_cost_modifier or 0) + 1			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		mdmuffler = util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDMUFFLER? ) )	{		},		mdexploit = util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDEXPLOIT? ) )	{		},		mdjailbreak = util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDJAILBREAK? ) )	{		},		mdbreach =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDBREACH? ) )	{		},		mdcrack =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDCRACK? ) )	{		},		mdsniper =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDSNIPER? ) )	{		},		mdflash =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDFLASH? ) )	{		},		mdbolt =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDBOLT? ) )	{		},		mdprediction =  util.extend( createReverseDaemon( STRINGS.REVERSE_DAEMONS.MDPREDICTION? ) )	{	(line 266)	},	(line 792)--==========================================================================--MODDED DAEMONS============================================================--==========================================================================	mdcascade = util.extend( createDaemon( STRINGS.DAEMON.PANIC ) ){        icon = "gui/Icons/daemon_icons/--cascade_image.png",        name = "Cascade",        desc = "One daemon is installed each turn",        shortdesc = "Additional Daemons installing",        activedesc = "ONE DAEMON INSTALLED EACH TURN",        onSpawnAbility = function( self, sim, player )                self.duration = 3                sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe = true, name = self.name, icon = self.icon, txt = string.format(self.activedesc, self.duration ) } )                sim:addTrigger( simdefs.TRG_END_TURN, self )                sim:addTrigger( simdefs.TRG_START_TURN, self )			end,					onTrigger = function( self, sim, evType, evData, userUnit )			if evType == simdefs.TRG_START_TURN and sim:getCurrentPlayer():isPC() then                local units = {}                for unitID, unit in pairs( sim:getAllUnits() ) do                     if unit:getTraits().mainframe_program then                             table.insert( units, unit )                     end				end                if #units > 0 then                        local index = sim:nextRand(1, #units)                        local unit = units[ index ]                        mainframe.invokeDaemon( sim, unit )                end			else				DEFAULT_ABILITY.onTrigger( self, sim, evType, evData, userUnit )					end			end,		onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )			sim:removeTrigger( simdefs.TRG_START_TURN, self )				end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )				end(line 834)},             (line 836)--//////////////////////////////////////////////////////////////////////////////--CASCADE'S EASY DAEMONS///////////////////////////////////////////////////////--////////////////////////////////////////////////////////////////////////////	easyincognitaKiller = util.extend( createDaemon( STRINGS.DAEMONS.PARADOX ) )	{		icon = "gui/icons/daemon_icons/Daemons0008.png",		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:setMainframeLockout( true )			sim:addTrigger( simdefs.TRG_END_TURN, self )				sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			end,		onDespawnAbility = function( self, sim )			sim:setMainframeLockout( false )			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},		easyagent_sapper = util.extend( createDaemon( STRINGS.DAEMONS.LABYRINTH ) )	{		icon = "gui/icons/daemon_icons/Daemons00012.png",		drain = 2,		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { name = self.name, icon=self.icon, txt = self.activedesc } )	            self._affectedUnits = {}            for i, unit in pairs(sim:getPC():getUnits()) do		        if unit:getMP() then			        unit:addMP( -2 )			        unit:addMPMax( -2 )                    table.insert( self._affectedUnits, unit )		        end	        end			sim:addTrigger( simdefs.TRG_END_TURN, self )			end,		onDespawnAbility = function( self, sim )            for i, unit in pairs( self._affectedUnits) do                if unit:getMP() and unit:isValid() then			        unit:addMP( 2 )			        unit:addMPMax( 2 )                end            end			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},			easymodulate = util.extend( createDaemon( STRINGS.DAEMONS.MODULATE ) )	{		icon = "gui/icons/daemon_icons/Daemons00013.png",		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )            sim:getPC():getTraits().program_cost_modifier = (sim:getPC():getTraits().program_cost_modifier or 0) + 2			sim:addTrigger( simdefs.TRG_END_TURN, self )	        end,		onDespawnAbility = function( self, sim )            sim:getPC():getTraits().program_cost_modifier = (sim:getPC():getTraits().program_cost_modifier or 0) - 2			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end		},	    easyauthority = util.extend( createDaemon( STRINGS.DAEMONS.AUTHORITY ) )    {		icon = "gui/icons/daemon_icons/Daemons0003.png",		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )			sim:addTrigger( simdefs.TRG_SAFE_LOOTED, self )				sim:addTrigger( simdefs.TRG_END_TURN, self )			end,		onDespawnAbility = function( self, sim )			sim:removeTrigger( simdefs.TRG_END_TURN, self )				sim:removeTrigger( simdefs.TRG_SAFE_LOOTED, self )			end,    	onTrigger = function( self, sim, evType, evData, userUnit )	    	if evType == simdefs.TRG_SAFE_LOOTED and evData.targetUnit:getTraits().safeUnit then    	        local x0, y0 = evData.unit:getLocation()	            sim:getNPC():spawnInterest(x0, y0, simdefs.SENSE_RADIO, simdefs.REASON_ALARMEDSAFE, evData.unit)	            sim:dispatchEvent( simdefs.EV_SHOW_WARNING, {txt=STRINGS.DAEMONS.AUTHORITY.WARNING, color=cdefs.COLOR_CORP_WARNING, sound = "SpySociety/Actions/mainframe_deterrent_action" } )	            --also raise the alarm				local trackerCount = 1				sim:trackerAdvance( trackerCount )            else                DEFAULT_ABILITY.onTrigger( self, sim, evType, evData, userUnit )            end        end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end	    },	easydamonHider = util.extend( createDaemon( STRINGS.DAEMONS.MASK ) )	{		icon = "gui/icons/daemon_icons/Daemons0002.png",		onSpawnAbility = function( self, sim, player )			self.duration = 1			sim:addTrigger( simdefs.TRG_END_TURN, self )				sim:hideDaemons(true)			sim:dispatchEvent( simdefs.EV_PLAY_SOUND, "SpySociety/Actions/mainframe_mask" )			sim:dispatchEvent( simdefs.EV_SHOW_DAEMON, { showMainframe=true, name = self.name, icon=self.icon, txt = string.format(self.activedesc, self.duration ) } )						end,		onDespawnAbility = function( self, sim )			sim:hideDaemons(false)			sim:removeTrigger( simdefs.TRG_END_TURN, self )			end,		executeTimedAbility = function( self, sim )			sim:getNPC():removeAbility(sim, self )		end	(line 978)	}, 

 

Right now I want to finish with cascade before dealing with the reverse daemons. I also found daemon and a reverse daemon lists on serverdefs.lua and added the modded daemons there too:

(line 1154)local PROGRAM_LIST = {	"fortify", 	"bruteForce", 	"duplicator",	"incognitaKiller",	"validate",	"siphon",	"agent_sapper", 	"modulate",    "authority",    "damonHider",    "creditTaker",	"mdcascade",(line 1168)}(line 1200)local REVERSE_DAEMONS ={	"order",	"attune",	"energize",	"mdmute",	"mdmuffler",	"mdexploit",	"mdjailbreak",	"mdbreach",	"mdcrack",	"mdsniper",	"mdflash",	"mdbolt",	"mdprediction",(line 1215)} 

 

I skipped the "easy OMNI" and "default OMNI" lists because since cascade activates daemons that are not allowed on OMNI like (validate, if you are playing easy, or authority, mask, and felix, if you are playing either difficulty) I decided not to add cascade in OMNI until I find a way to deal with this situation.  

Share this post


Link to post
Share on other sites
JimThePea    53

Thanks a lot! You have a great suggestion on cascade, the player should receive a warning if multiple daemons will install. I am thinking of having a hybrid between your suggestion and the original idea. It wouldn't install immediately (which makes sense in a real world point of view since it would be a much heavier download to handle for incognita, 3 daemons at once!) it would instead prompt the player warning him a daemon is installing next turn and next turn the daemon installs but the player is warned of the daemon installed beforehand again and so for the third and last turn (so despite you would know what daemon is comming after what daemon one turn before it happens) this would happen 3 times for 3 turns (idk if 3 turns is to OP) but the daemons would only last 1 turn each. So about the interpretations you asked here they are, big thanks to Plasmaflare for posting:

  • (Siphon) - Bolt: Gain X PWR (I kinda don't feel this name is enough I wanted something like "overdrive" but klei is working on a program that is named like that already I also thought "power spike" but I feel like that doesn't fit either)

 

  • (Paradox) - Mute: Prevents alarm tracker from increasing for X turns (decreasing alarm tracker seems very counterintuitive towards pressuring the player imo)

 

  • (Blowfish) - Muffler: Reduces alarm tracker increments by 1 for X turns

 

  • (Authority) - Jailbreak: disables all safes for X (2?) turns

 

  • (Validate) - Breach: All heart monitors disabled (including 2.0's) for X turns

 

  • (Mask) - Flash: Reveals all daemon's and devices and their locations for X turns (not too sure about this)

 

  • (Rubiks)- Vulnerability/Crack: Decreases all firewalls, that are greater than 1, by 1 firewall (I feel more inclined towards crack)

 

  • (Fractal) - Sniper: Kills 2(?) daemons

 

  • (cascade) - Exploit: installs other algorithms for 3 turns (works the same as cascade. I also take suggestions on this one's name)

 

  • (countermeasures) - prediction: tags ALL guards on the level (even if not visible)  and shows their patrols for one turn 

 

  • also idk why I like the idea of calling reverse daemons "angaels" or "aengels" silly idea of mine lol 

 

 

I like the name 'Exploit', but along with 'Jailbreak', 'Crack' and 'Flash', it starts to get a bit too close to hacking terms, programs and daemons names are (generally) more abstract. Although I guess that stuff is best left until after the code's done and tested anyway. At the moment algorithms are so rare that having 13 of them seems like overkill, a few more would definitely make things more interesting but I wouldn't say we need one for each daemon, and there could be more interesting ideas outside of simply opposites.

Your idea for Cascade sounds great, but it feels like it could be it's own daemon, one that hits you with a different mini-daemon each turn for a number of turns, so first turn you might lose 2 PWR, next turn two programs are disabled, then the alarm goes up a tick.

 

By the way, I've posted up my other designs here.

Share this post


Link to post
Share on other sites
Caischcer    10

I like the name 'Exploit', but along with 'Jailbreak', 'Crack' and 'Flash', it starts to get a bit too close to hacking terms, programs and daemons names are (generally) more abstract.  At the moment algorithms are so rare that having 13 of them seems like overkill, a few more would definitely make things more interesting but I wouldn't say we need one for each daemon, and there could be more interesting ideas outside of simply opposites.

Your idea for Cascade sounds great, but it feels like it could be it's own daemon, one that hits you with a different mini-daemon each turn for a number of turns, so first turn you might lose 2 PWR, next turn two programs are disabled, then the alarm goes up a tick.

 

Yeah you are right, I guess I haven't been very original on the ideas for the reverse daemons. About the names, reverse daemons' depiction in the game is abstracted, very abstracted from their real "functioning"? and I have considered a lot the names for the new reverse daemons.

 

I have also thought really hard about what works and what doesn't and a reverse siphon is definitely not needed, a simple terminal hack can make the deal. Now about other reverse daemons like: revblowfish and revfractal. Hunter can do the job of a revfractal and the idea itself can be quite OP, even if it is very unlikely. And revblowfish, well, it is only beneficial if you feel like doing stuff that will increase the alarm +1 but most stuff increase it +2 so I may scratch that too.

 

Anyway I will update the names for the reverse daemons and add new more abstracted options. I hope you like it and thank you a lot for your suggestion it is incredibly helpful. Cascade's functioning may change a bit (again) I'll explain that in the updated topic and if everything goes ok and I have some extra time left I might add the other programs for which you made icons. I am really interested in fission and axe. 

Share this post


Link to post
Share on other sites
Plasmaflare    1

Yeah you are right, I guess I haven't been very original on the ideas for the reverse daemons. About the names, reverse daemons' depiction in the game is abstracted, very abstracted from their real "functioning"? and I have considered a lot the names for the new reverse daemons.

 

I have also thought really hard about what works and what doesn't and a reverse siphon is definitely not needed, a simple terminal hack can make the deal. Now about other reverse daemons like: revblowfish and revfractal. Hunter can do the job of a revfractal and the idea itself can be quite OP, even if it is very unlikely. And revblowfish, well, it is only beneficial if you feel like doing stuff that will increase the alarm +1 but most stuff increase it +2 so I may scratch that too.

 

Anyway I will update the names for the reverse daemons and add new more abstracted options. I hope you like it and thank you a lot for your suggestion it is incredibly helpful. Cascade's functioning may change a bit (again) I'll explain that in the updated topic and if everything goes ok and I have some extra time left I might add the other programs for which you made icons. I am really interested in fission and axe. 

 

In my opinion, the purpose of reverse daemons is not for functionality, such as gaining ap, reducing firewalls etc. It is more for the purpose of providing a lucky situation that you can hopefully take advantage of. Getting a fortune daemon is almost the equivalent of hacking or EMPing a small safe and stealing from it. However, it could also provide the additional 200 credits that would also allow you to buy the Stim 3 that you just didn't have enough money for. Getting order is just one of the many ways to gain ap, most of the other ways giving agents more ap than 2. But with that extra two ap, an agent could have enough ap to get through a door, close it, and avoid the detection of a guard passing by.

 

I'm not disagreeing with your decisions to remove certain reverse daemons. I'm just suggesting that, when designing the reverse daemons, maybe instead of focusing on whether or not this reverse daemon offers a good deal to the player, focus on whether or not this reverse daemon can be used to the player's advantage once it has been triggered, especially in a dire situation. 

 

By the way, feel free to not use the names of the reverse daemons that I provided. I'm fine with any name as long as it sounds good enough.

Share this post


Link to post
Share on other sites
Caischcer    10

By the way, feel free to not use the names of the reverse daemons that I provided. I'm fine with any name as long as it sounds good enough.

 

Oh, don't worry you have been a great contributor anyway!  :joyous:

Share this post


Link to post
Share on other sites