Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Best way to add an output to a generic npc?  (Read 401 times)

0 Members and 1 Guest are viewing this topic.

Offline Dazza-chan

  • *
  • +1% chance to make useful post
  • Dazza-chan has no influence.
Best way to add an output to a generic npc?
« on: April 03, 2018, 01:08:50 PM »
Sorry if this makes no sense, im really tired.

So i am currently working on a map in which you, and 3 - 4 npc_um_citizens must escape by going through an infested military base. If all of your squad dies, you lose, if you die you also lose obviously. at certain points in the map there are locked doors in which a surviving member of your squad must hack a terminal to open a door while you defend him, this is accomplished using a simplified version fo the following:

   "npc_um_citizen" // there are three of these, they are all generic.
      {
      "origin" "290 -504 256"
      "keyvalues"
         {
         "targetname" "Ally"
         "additionalequipment" "weapon_ar2"
         }
      }


   "logic_relay" // this logic relay is bound to an Alias which is has been bound to the Y key, so to order a member to hack you must press Y
      {
      "keyvalues"
         {
         "targetname" "Signaltrigger"
         "spawnflags" "2"
         "OnTrigger" "hackengage,beginsequence,,2,1"
         }
      }

   "scripted_sequence" //this causes any 1 of the remaining squad members to move to the terminal and begin the hacking procedure and finishes with an idle anim
      {
      "origin" "123 -365 256"
      "angle" "0 90 0"
      "keyvalues"
         {
         "targetname" "hackengage"
         "m_iszEntity" "Ally"
         "m_iszPlay" "d1_town05_Leon_Lean_Table_entry"
         "m_fmoveto" "2"
         "m_iszPostIdle" "d1_town05_Leon_Lean_Table_Idle"
         "spawnflags" "298"
         "OnEndSequence" "doorslicetimer,enable,,0,1"
         }
      }

   "logic_timer" //this is just a timer that specifies how long the hack goes for, at the end happy2 plays, causing the exit animation
      {
      "keyvalues"
         {
         "targetname" "doorslicetimer"
         "StartDisabled" "1"
         "RefireTime"   "8"
         "OnTimer"   "hackdisengage,beginsequence,,0,1"
         "OnTimer"   "hackengage,CancelSequence,,0,1"
         "OnTimer"   "dw1,open,,2,1"
         }
      }
      
   "scripted_sequence" //playing the exit animation so the npc disengages from the terminal
      {
      "origin" "123 -365 256"
      "angle" "0 90 0"
      "keyvalues"
         {
         "targetname" "hackdisengage"
         "m_iszEntity" "Ally"
         "m_iszPlay" "d1_town05_Leon_Lean_Table_exit"
         "m_fmoveto" "5"
         "m_flRadius" "1"
         "spawnflags" "32"
         }
      }

So the problem is, if the NPC dies i have no way of resetting the cycle so that you can try again with any of your remaining squad mates, how do i add an "OnDeath" output to the NPC moving in for/performing the hack when they are completely generic apart from the fact that they were selected by the scripted_sequence?

Alternatively, is there a viable LUA method of selecting for the scripted sequence npc?



Offline Dazza-chan

  • *
  • +1% chance to make useful post
  • Dazza-chan has no influence.
Re: Best way to add an output to a generic npc?
« Reply #1 on: April 03, 2018, 01:09:37 PM »
If you need more info or it wasnt clear just ask, i cut it all down and only posted a little bit because my mapadds are really messy and a pain to look at.

Offline Dazza-chan

  • *
  • +1% chance to make useful post
  • Dazza-chan has no influence.
Re: Best way to add an output to a generic npc?
« Reply #2 on: April 03, 2018, 02:29:55 PM »
I have made an extremely bulky/hacky method of dealing with this, i'll post it later when i clean it up, incase anyone else has a problem similar to this in the future.

Offline Pepsifan04

  • *
  • *
  • +12% chance to make useful post
  • Pepsifan04 might someday be someone...Pepsifan04 might someday be someone...Pepsifan04 might someday be someone...Pepsifan04 might someday be someone...
Re: Best way to add an output to a generic npc?
« Reply #3 on: April 03, 2018, 04:56:22 PM »
Posting your solution to public would be very nice :D
I was thinking about another mapadd object that selects "hacking" ally and adds OnDeath output (via point_servercommand or anything else really)
DROP DATABASE bsnooch

Offline Dazza-chan

  • *
  • +1% chance to make useful post
  • Dazza-chan has no influence.
Re: Best way to add an output to a generic npc?
« Reply #4 on: April 06, 2018, 07:49:48 AM »
-snip- accidentally posted it without any anotations, im just adding some now because my mappadd is very messy and its gonna need some explanation.
« Last Edit: April 06, 2018, 07:56:45 AM by Dazza-chan »

Offline Dazza-chan

  • *
  • +1% chance to make useful post
  • Dazza-chan has no influence.
Re: Best way to add an output to a generic npc?
« Reply #5 on: April 06, 2018, 08:19:50 AM »
the biggest catch with this is that the npcs can be expendable, but they need to have individual names, and the more npcs you have as potential hackers the bulkier the system. idk if the mapadd system has a limit to the amount of data it can process or not, but having multiple of these per map might be pushing it.

I'm sorry this is so messy and long, but it works almost flawlessly. If you need any additional explanation or you see anyways to cut down on its length tell me. This system can be used multiple times per map to allow for multiple door hack sequences. but its my first attempt and needs work to make it shorter and less spaghetti code like.

There is one important entity not present in this label, SignalTrigger which is a logic_relay bound to fire at the press of the Y key, this fires DoorHack1Signaltrigger and begins the process of hacking.

The only other entities you see referenced here but not included are ambient generics for making the player give a verbal signal "Player_Orderhacksound" (for some reason ambient generics dont work for me unless placed in the entities section),the npcs themselves,  the logic timer that that makes a ambient_generic keyboard sound play every 1 second "keyboardsoundtimer", and the door itself that is being opened "Door_Keycard1".

Code: [Select]

"Entities:SetupDoor1Hack"
{

//------------------------AllyCheck------------------------\\

//this section simply checks to see which of your allies are still alive when the label is run, incase some of them died prior to the hacking section of the map.

"instant_trig"
{
"keyvalues"
{
"targetname" "Ally01Checkertrig"
"label" "Ally01Checkerlabel"
"islived" "Ally01"
}
}

"instant_trig"
{
"keyvalues"
{
"targetname" "Ally02Checkertrig"
"label" "Ally02Checkerlabel"
"islived" "Ally02"
}
}

"instant_trig"
{
"keyvalues"
{
"targetname" "Ally03Checkertrig"
"label" "Ally03Checkerlabel"
"islived" "Ally03"
}
}

//the trigs are deleted after 2 seconds, as they arent needed due to OnDeath outputs being added to the survivors.

"event"
{
"targetname" "Ally01Checkertrig"
"action" "kill"
"delaytime" "2"
}

"event"
{
"targetname" "Ally02Checkertrig"
"action" "kill"
"delaytime" "2"
}

"event"
{
"targetname" "Ally03Checkertrig"
"action" "kill"
"delaytime" "2"
}

//------------------------Core events------------------------\\

//This first event disables the ability of SignalTrigger to fire DoorHack1Signaltrigger until the player is within the radius of GiveSignalChecker_1.

"event"
{
"targetname" "DoorHack1Signaltrigger"
"action" "disable"
}

//These next two events disable the ability of Ally02 and Ally03 from hacking at first unless Ally01 was killed prior.

"event"
{
"targetname" "SignaltriggerAlly02"
"action" "disable"
}

"event"
{
"targetname" "SignaltriggerAlly03"
"action" "disable"
}

//this make GiveSignalChecker_1 hate the player so it fires its OnFoundEnemy output when in its radius

"event"
{
"targetname" "Givesignalrelationship1"
"action" "ApplyRelationship"
}

//these events add on death outputs to each of the NPCS to delete their related entities on death

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly01logicgate,kill,,0,1"
}

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly01,kill,,0,1"
}

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly02,enable,,0.1,1"
}

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly03,enable,,0.1,1"
}

"event"
{
"targetname" "Ally02"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly02logicgate,kill,,0,1"
}

"event"
{
"targetname" "Ally02"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly02,kill,,0,1"
}

"event"
{
"targetname" "Ally02"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly03,enable,,0.1,1"
}

"event"
{
"targetname" "Ally03"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly02logicgate,kill,,0,1"
}

"event"
{
"targetname" "Ally03"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly03,kill,,0,1"
}

"event"
{
"targetname" "Ally03"
"action" "addoutput"
"value" "OnDeath SignaltriggerAlly02,enable,,0.1,1"
}

//------------------------Logic Entities------------------------\\

//disabled until in range of GiveSignalChecker_1, starts 1 of the three logic_relays associated with hacking.

"logic_relay"
{
"keyvalues"
{
"targetname" "DoorHack1Signaltrigger"
"spawnflags" "2"
"OnTrigger" "SignaltriggerAlly01,trigger,,0,-1"
"OnTrigger" "SignaltriggerAlly02,trigger,,0,-1"
"OnTrigger" "SignaltriggerAlly03,trigger,,0,-1"
}
}

//these next 3 logic relays begin the hacking sequence, cause outputs to be added to the NPCS, and disable the ability to trigger another hack unless the npc dies while attempting it.

//this logic relay is active by default, so if Ally01 is still alive he will always do the hacking. If he dies before/during hacking this trigger is deleted

"logic_relay"
{
"keyvalues"
{
"targetname" "SignaltriggerAlly01"
"spawnflags" "2"
"OnTrigger" "Ally01Hackdoor1,beginsequence,,2,1"
"OnTrigger" "Player_Orderhacksound,PlaySound,,0,1"
"OnTrigger" "Ally01outputinfo,kill,,0,1"
"OnTrigger" "GiveSignalChecker_1,turnoff,,0,1"
"OnTrigger" "DoorHack1Signaltrigger,disable,,0.1,1"
}
}

//this logic relay is inactive by default, and is turned on whenever Ally01 or Ally03 dies, if Ally03 dies but Ally01 is alive, this relay is innactived again in 0.1 seconds by SignaltriggerAlly01logicgate

"logic_relay"
{
"keyvalues"
{
"targetname" "SignaltriggerAlly02"
"spawnflags" "2"
"OnTrigger" "Ally02Hackdoor1,beginsequence,,2,1"
"OnTrigger" "Player_Orderhacksound,PlaySound,,0,1"
"OnTrigger" "Ally02outputinfo,kill,,0,1"
"OnTrigger" "GiveSignalChecker_1,turnoff,,0,1"
"OnTrigger" "DoorHack1Signaltrigger,disable,,0.1,1"
}
}

//this logic relay is inactive by default, and is turned on whenever Ally01 or Ally02 dies, if any other allies are alive, this relay is innactivated in 0.1 seconds by either SignaltriggerAlly01logicgate or SignaltriggerAlly02logicgate


"logic_relay"
{
"keyvalues"
{
"targetname" "SignaltriggerAlly03"
"spawnflags" "2"
"OnTrigger" "Ally03Hackdoor1,beginsequence,,2,1"
"OnTrigger" "Player_Orderhacksound,PlaySound,,0,1"
"OnTrigger" "Ally03outputinfo,kill,,0,1"
"OnTrigger" "GiveSignalChecker_1,turnoff,,0,1"
"OnTrigger" "DoorHack1Signaltrigger,disable,,0.1,1"
}
}

//inactivates SignaltriggerAlly02/SignaltriggerAlly03 as long as Ally01 lives

"logic_timer"
{
"keyvalues"
{
"targetname" "SignaltriggerAlly01logicgate"
"StartDisabled" "0"
"RefireTime" "0.1"
"OnTimer" "SignaltriggerAlly02,disable,,0,-1"
"OnTimer" "SignaltriggerAlly03,disable,,0,-1"
}
}

inactivates SignaltriggerAlly03 as long as Ally02 lives

"logic_timer"
{
"keyvalues"
{
"targetname" "SignaltriggerAlly02logicgate"
"StartDisabled" "0"
"RefireTime" "0.1"
"OnTimer" "SignaltriggerAlly03,disable,,0,-1"
}
}

//Once one of the allies completes the hack, this relay fires, opening the door and removing any related entities.

"logic_relay"
{
"keyvalues"
{
"targetname" "DoorHack1End"
"spawnflags" "2"
"OnTrigger" "Door_Keycard1,open,,2,1"
"OnTrigger" "Ally03Hackdoortimer,kill,,0,1"
"OnTrigger" "Ally03Hackdoor2,kill,,2,1"
"OnTrigger" "Ally03Hackdoor1,kill,,0,1"
"OnTrigger" "Ally02Hackdoortimer,kill,,0,1"
"OnTrigger" "Ally02Hackdoor2,kill,,2,1"
"OnTrigger" "Ally02Hackdoor1,kill,,0,1"
"OnTrigger" "Ally01Hackdoortimer,kill,,0,1"
"OnTrigger" "Ally01Hackdoor2,kill,,2,1"
"OnTrigger" "Ally01Hackdoor1,kill,,0,1"
"OnTrigger" "SignaltriggerAlly02logicgate,kill,,0,1"
"OnTrigger" "SignaltriggerAlly01logicgate,kill,,0,1"
"OnTrigger" "SignaltriggerAlly03,kill,,0,1"
"OnTrigger" "SignaltriggerAlly02,kill,,0,1"
"OnTrigger" "GiveSignalChecker_1,kill,,0,1"
"OnTrigger" "Givesignalrelationship1,kill,,0,1"
"OnTrigger" "DoorHack1Signaltrigger,kill,,0,1"
}
}

//------------------------Ally01 Door Hack------------------------\\

//this section occurs if ally01 begins hacking

"scripted_sequence"
{
"origin" "-173 1494 -192"
"angle" "0 0 0"
"keyvalues"
{
"targetname" "Ally01Hackdoor1"
"m_iszEntity" "Ally01"
"m_iszPlay" "d1_town05_Leon_Lean_Table_entry"
"m_fmoveto" "2"
"m_iszPostIdle" "d1_town05_Leon_Lean_Table_Idle"
"spawnflags" "298"
"OnEndSequence" "keyboardsoundtimer,enable,,0,1"
"OnEndSequence" "Ally01Hackdoortimer,enable,,0,1"
}
}

"info_target"
{
"keyvalues"
{
"targetname" "Ally01outputinfo"
}
}

"instant_trig"
{
"keyvalues"
{
"label" "Ally01outputlabel"
"islived" "Ally01outputinfo"
}
}

"scripted_sequence"
{
"origin" "-173 1494 -192"
"angle" "0 0 0"
"keyvalues"
{
"targetname" "Ally01Hackdoor2"
"m_iszEntity" "Ally01"
"m_iszPlay" "d1_town05_Leon_Lean_Table_exit"
"m_fmoveto" "5"
"m_flRadius" "1"
"spawnflags" "32"
"OnEndSequence" "Ally01Hackdoor2,kill,,0,1"
}
}

"logic_timer"
{
"keyvalues"
{
"targetname" "Ally01Hackdoortimer"
"StartDisabled" "1"
"RefireTime" "8"
"OnTimer" "Ally01Hackdoor2,beginsequence,,0,1"
"OnTimer" "Ally01Hackdoor1,CancelSequence,,0,1"
"OnTimer" "keyboardsoundtimer,disable,,0,1"
"OnTimer" "DoorHack1End,Trigger,,0,1"
}
}

//------------------------Ally02 Door Hack------------------------\\

//this section occurs if ally02 begins hacking

"scripted_sequence"
{
"origin" "-173 1494 -192"
"angle" "0 0 0"
"keyvalues"
{
"targetname" "Ally02Hackdoor1"
"m_iszEntity" "Ally02"
"m_iszPlay" "d1_town05_Leon_Lean_Table_entry"
"m_fmoveto" "2"
"m_iszPostIdle" "d1_town05_Leon_Lean_Table_Idle"
"spawnflags" "298"
"OnEndSequence" "keyboardsoundtimer,enable,,0,1"
"OnEndSequence" "Ally02Hackdoortimer,enable,,0,1"
}
}

"info_target"
{
"keyvalues"
{
"targetname" "Ally02outputinfo"
}
}

"instant_trig"
{
"keyvalues"
{
"label" "Ally02outputlabel"
"islived" "Ally02outputinfo"
}
}

"scripted_sequence"
{
"origin" "-173 1494 -192"
"angle" "0 0 0"
"keyvalues"
{
"targetname" "Ally02Hackdoor2"
"m_iszEntity" "Ally02"
"m_iszPlay" "d1_town05_Leon_Lean_Table_exit"
"m_fmoveto" "5"
"m_flRadius" "1"
"spawnflags" "32"
"OnEndSequence" "Ally02Hackdoor2,kill,,0,1"
}
}

"logic_timer"
{
"keyvalues"
{
"targetname" "Ally02Hackdoortimer"
"StartDisabled" "1"
"RefireTime" "8"
"OnTimer" "Ally02Hackdoor2,beginsequence,,0,1"
"OnTimer" "Ally02Hackdoor1,CancelSequence,,0,1"
"OnTimer" "keyboardsoundtimer,disable,,0,1"
"OnTimer" "DoorHack1End,Trigger,,0,1"
}
}

//------------------------Ally03 Door Hack------------------------\\

//this section occurs if ally03 begins hacking

"scripted_sequence"
{
"origin" "-173 1494 -192"
"angle" "0 0 0"
"keyvalues"
{
"targetname" "Ally03Hackdoor1"
"m_iszEntity" "Ally03"
"m_iszPlay" "d1_town05_Leon_Lean_Table_entry"
"m_fmoveto" "2"
"m_iszPostIdle" "d1_town05_Leon_Lean_Table_Idle"
"spawnflags" "298"
"OnEndSequence" "keyboardsoundtimer,enable,,0,1"
"OnEndSequence" "Ally03Hackdoortimer,enable,,0,1"
}
}

"info_target"
{
"keyvalues"
{
"targetname" "Ally03outputinfo"
}
}

"instant_trig"
{
"keyvalues"
{
"label" "Ally03outputlabel"
"islived" "Ally03outputinfo"
}
}

"scripted_sequence"
{
"origin" "-173 1494 -192"
"angle" "0 0 0"
"keyvalues"
{
"targetname" "Ally03Hackdoor2"
"m_iszEntity" "Ally03"
"m_iszPlay" "d1_town05_Leon_Lean_Table_exit"
"m_fmoveto" "5"
"m_flRadius" "1"
"spawnflags" "32"
"OnEndSequence" "Ally03Hackdoor2,kill,,0,1"
}
}

"logic_timer"
{
"keyvalues"
{
"targetname" "Ally03Hackdoortimer"
"StartDisabled" "1"
"RefireTime" "8"
"OnTimer" "Ally03Hackdoor2,beginsequence,,0,1"
"OnTimer" "Ally03Hackdoor1,CancelSequence,,0,1"
"OnTimer" "keyboardsoundtimer,disable,,0,1"
"OnTimer" "DoorHack1End,Trigger,,0,1"
}
}

//------------------------Other------------------------\\

//this npc_enemyfinder acts as a substitute for trigger_multiple as it can provide an output multiple times whenever the player enters its radius, unfortunately its lost enemy outputs dont seem to fire

"npc_enemyfinder"
{
"origin" "-173 1494 -192"
"keyvalues"
{
"targetname" "GiveSignalChecker_1"
"angles" "0 -0 0"
"FieldOfView" "-1.0"
"MinSearchDist" "0"
"MaxSearchDist" "500"
"StartOn" "1"
"OnFoundEnemy" "DoorHack1Signaltrigger,Enable,,0,-1"
"OnFoundEnemy" "GiveSignalHint,ShowHudHint,,0,-1"
}
}

}

//these labels relate to the AllyChecker section and kill related logic entities if the npc is already dead when the hacking label is fired.

"Entities:Ally01Checkerlabel"
{

"event"
{
"targetname" "SignaltriggerAlly01logicgate"
"action" "kill"
}

"event"
{
"targetname" "SignaltriggerAlly01"
"action" "kill"
}

"event"
{
"targetname" "SignaltriggerAlly02"
"action" "enable"
"delaytime" "0.1"
}

"event"
{
"targetname" "SignaltriggerAlly03"
"action" "enable"
"delaytime" "0.1"
}

}

"Entities:Ally02Checkerlabel"
{

"event"
{
"targetname" "SignaltriggerAlly02logicgate"
"action" "kill"
}

"event"
{
"targetname" "SignaltriggerAlly02"
"action" "kill"
}

"event"
{
"targetname" "SignaltriggerAlly03"
"action" "enable"
"delaytime" "0.1"
}

}

"Entities:Ally03Checkerlabel"
{

"event"
{
"targetname" "SignaltriggerAlly02logicgate"
"action" "kill"
}

"event"
{
"targetname" "SignaltriggerAlly03"
"action" "kill"
}

"event"
{
"targetname" "SignaltriggerAlly02"
"action" "enable"
"delaytime" "0.1"
}

}

//these labels are triggered whenever the ally gets called to start hacking by the scripted_sequence, these outputs mean that if an npc dies during, or on its way to hack, the process is reset to allow the next ally to try.

"Entities:Ally01outputlabel"
{

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath DoorHack1Signaltrigger,Enable,,0,1"
}

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath GiveSignalChecker_1,turnon,,0,1"
}

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath Ally01Hackdoortimer,kill,,0,1"
}

"event"
{
"targetname" "Ally01"
"action" "addoutput"
"value" "OnDeath keyboardsoundtimer,disable,0,1"
}

}

"Entities:Ally02outputlabel"
{

"event"
{
"targetname" "Ally02"
"action" "addoutput"
"value" "OnDeath DoorHack1Signaltrigger,Enable,,0,1"
}

"event"
{
"targetname" "Ally02"
"action" "addoutput"
"value" "OnDeath GiveSignalChecker_1,turnon,,0,1"
}

"event"
{
"targetname" "Ally02"
"action" "addoutput"
"value" "OnDeath Ally02Hackdoortimer,kill,,0,1"
}

"event"
{
"targetname" "Ally02"
"action" "addoutput"
"value" "OnDeath keyboardsoundtimer,disable,0,1"
}

}

"Entities:Ally03outputlabel"
{

"event"
{
"targetname" "Ally03"
"action" "addoutput"
"value" "OnDeath DoorHack1Signaltrigger,Enable,,0,1"
}

"event"
{
"targetname" "Ally03"
"action" "addoutput"
"value" "OnDeath GiveSignalChecker_1,turnon,,0,1"
}

"event"
{
"targetname" "Ally03"
"action" "addoutput"
"value" "OnDeath Ally03Hackdoortimer,kill,,0,1"
}

"event"
{
"targetname" "Ally03"
"action" "addoutput"
"value" "OnDeath keyboardsoundtimer,disable,0,1"
}

}

« Last Edit: April 06, 2018, 08:33:20 AM by Dazza-chan »