playeragentpool.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /**
  2. * \brief Keeps track of agents and their simulation
  3. * - adding/reducing of agents
  4. * - autoinfection
  5. * - temporary resistance for agents
  6. * - reaction on drugs
  7. */
  8. class PlayerAgentPool
  9. {
  10. const int STORAGE_VERSION = 137;
  11. int m_AgentMask;
  12. float m_LastTicked;
  13. float m_TotalAgentCount;
  14. PlayerBase m_Player;
  15. ref map<int,float> m_VirusPool;
  16. protected ref map<int, float> m_AgentTemporaryResistance;
  17. PluginTransmissionAgents m_PluginTransmissionAgents = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents));
  18. void PlayerAgentPool(PlayerBase player)
  19. {
  20. m_Player = player;
  21. m_LastTicked = 0;
  22. m_VirusPool = new map<int,float>();
  23. m_AgentTemporaryResistance = new map<int,float>();
  24. }
  25. int GetStorageVersion()
  26. {
  27. return STORAGE_VERSION;
  28. }
  29. /**
  30. * \brief Agent pool simulation entry point
  31. * @param value Immunity value (deprecated, used in previous versions)
  32. * @param deltaT tick
  33. */
  34. void ImmuneSystemTick(float value, float deltaT)//this is a regular tick induced in the the player's immune system
  35. {
  36. ProcessTemporaryResistance(deltaT);
  37. SpawnAgents(deltaT);
  38. GrowAgents(deltaT);
  39. }
  40. /**
  41. * \brief Agent's growth/death simulation
  42. * - based on the potency, invasibility
  43. * - takes into account the temporary resistance
  44. * @param deltaT tick
  45. */
  46. void GrowAgents(float deltaT)
  47. {
  48. if (!IsPluginManagerExists())
  49. return;
  50. EStatLevels immunityLevel = m_Player.GetImmunityLevel();
  51. m_TotalAgentCount = 0;
  52. for (int i = 0; i < m_VirusPool.Count(); i++)
  53. {
  54. int agentId = m_VirusPool.GetKey(i);
  55. int maxCount = m_PluginTransmissionAgents.GetAgentMaxCount(agentId);
  56. EStatLevels agentPotency = m_PluginTransmissionAgents.GetAgentPotencyEx(agentId, m_Player);
  57. float growDelta;
  58. if (agentPotency <= immunityLevel)
  59. {
  60. float temporaryResistance = GetTemporaryResistance(agentId);
  61. if (temporaryResistance > 1.0)
  62. continue;
  63. if (m_Player.IsAntibioticsActive() && !m_PluginTransmissionAgents.GrowDuringMedicalDrugsAttack(agentId, EMedicalDrugsType.CHELATION, m_Player))
  64. continue;
  65. if (m_Player.IsChelationActive() && !m_PluginTransmissionAgents.GrowDuringMedicalDrugsAttack(agentId, EMedicalDrugsType.CHELATION, m_Player))
  66. continue
  67. float invasibility = m_PluginTransmissionAgents.GetAgentInvasibilityEx(agentId, m_Player);
  68. growDelta = invasibility * deltaT;
  69. }
  70. else
  71. {
  72. float dieOffSpeed = m_PluginTransmissionAgents.GetAgentDieOffSpeedEx(agentId, m_Player);
  73. growDelta = -dieOffSpeed * deltaT;
  74. }
  75. float oldCount = m_VirusPool.Get(agentId);
  76. float newCount = oldCount + growDelta;
  77. newCount = Math.Clamp(newCount, 0, maxCount);
  78. m_TotalAgentCount += newCount;
  79. SetAgentCount(agentId, newCount);
  80. }
  81. }
  82. /**
  83. * \brief Temporary resistance simulation
  84. */
  85. protected void ProcessTemporaryResistance(float deltaTime)
  86. {
  87. foreach (int agentId, float timeResistance : m_AgentTemporaryResistance)
  88. {
  89. float temporaryResistance = GetTemporaryResistance(agentId);
  90. if (temporaryResistance > 1.0)
  91. {
  92. float newResistanceValue = temporaryResistance - deltaTime;
  93. SetTemporaryResistance(agentId, newResistanceValue);
  94. }
  95. else
  96. SetTemporaryResistance(agentId, 0.0);
  97. }
  98. }
  99. void OnStoreSave(ParamsWriteContext ctx)
  100. {
  101. int count = m_PluginTransmissionAgents.GetAgentList().Count();
  102. array<int> agentList = m_PluginTransmissionAgents.GetAgentList().GetKeyArray();
  103. foreach (int agentId : agentList)
  104. {
  105. ctx.Write(agentId);
  106. ctx.Write(GetSingleAgentCount(agentId));
  107. ctx.Write(GetTemporaryResistance(agentId));
  108. }
  109. }
  110. bool OnStoreLoad(ParamsReadContext ctx, int version)
  111. {
  112. int count;
  113. if (version >= 137)
  114. {
  115. count = m_PluginTransmissionAgents.GetAgentList().Count();
  116. }
  117. else
  118. {
  119. if (!ctx.Read(count))
  120. return false;
  121. }
  122. for (int i = 0; i < count; ++i)
  123. {
  124. int agentId;
  125. if (!ctx.Read(agentId))
  126. return false;
  127. int agentCount;
  128. if (!ctx.Read(agentCount))
  129. return false;
  130. if (version >= 137)
  131. {
  132. float agentTemporaryResistanceTime;
  133. if (!ctx.Read(agentTemporaryResistanceTime))
  134. return false;
  135. SetTemporaryResistance(agentId, agentTemporaryResistanceTime);
  136. }
  137. SetAgentCount(agentId, agentCount);
  138. }
  139. return true;
  140. }
  141. /**
  142. * \brief Digest (add) agent from food/drink in PlayerStomach into Agent Pool
  143. * @param agent_id Id of agent (see eAgents enum)
  144. * @param count Amount of agents to add
  145. */
  146. void DigestAgent(int agent_id, float count)
  147. {
  148. AddAgent(agent_id, m_PluginTransmissionAgents.GetAgentDigestibilityEx(agent_id, m_Player) * count);
  149. }
  150. /**
  151. * \brief Add agent into Agent Pool
  152. * @param agent_id Id of agent (see eAgents enum)
  153. * @param count Amount of agents to add
  154. */
  155. void AddAgent(int agent_id, float count)
  156. {
  157. if (GetTemporaryResistance(agent_id) > 0)
  158. return;
  159. int max_count = m_PluginTransmissionAgents.GetAgentMaxCount(agent_id);
  160. if (!m_VirusPool.Contains(agent_id) && count > 0)//if it contains, maybe add count only ?
  161. {
  162. SetAgentCount(agent_id,count);
  163. }
  164. else
  165. {
  166. float newValue = m_VirusPool.Get(agent_id) + count;
  167. SetAgentCount(agent_id, newValue);
  168. }
  169. }
  170. /**
  171. * \brief Remove agent from Agent Pool
  172. * @param agent_id Id of agent (see eAgents enum)
  173. */
  174. void RemoveAgent(int agent_id)
  175. {
  176. SetAgentCount(agent_id, 0);
  177. }
  178. /**
  179. * \brief Remove all agents from Agent Pool
  180. * @param agent_id Id of agent (see eAgents enum)
  181. */
  182. void RemoveAllAgents()
  183. {
  184. m_AgentMask = 0;
  185. m_VirusPool.Clear();
  186. ResetTemporaryResistance();
  187. }
  188. /**
  189. * \brief Reduce count of specified agent by a given percentage from Agent Pool
  190. * @param agent_id Id of agent (see eAgents enum)
  191. * @param percent How many percents of the agents should be reduced
  192. */
  193. void ReduceAgent(int id, float percent)
  194. {
  195. percent = Math.Clamp(percent, 0, 100);
  196. float reduction = percent * 0.01;
  197. int agentCount = GetSingleAgentCount(id);
  198. agentCount -= agentCount * reduction;
  199. SetAgentCount(id, agentCount);
  200. }
  201. /**
  202. * \brief Reduce bitmask of currently active agents
  203. */
  204. int GetAgents()
  205. {
  206. return m_AgentMask;
  207. }
  208. /**
  209. * \brief Number of agents of specified id
  210. * @param agent_id Id of agent to add into pool (see eAgents)
  211. * \return Count of agents specified in param
  212. */
  213. int GetSingleAgentCount(int agent_id)
  214. {
  215. if (m_VirusPool.Contains(agent_id))
  216. return m_VirusPool.Get(agent_id);
  217. return 0;
  218. }
  219. /**
  220. * \brief Total number of agents active
  221. * \return Agents count
  222. */
  223. float GetTotalAgentCount()
  224. {
  225. float agentCount;
  226. for (int i = 0; i < m_VirusPool.Count(); i++)
  227. agentCount += m_VirusPool.GetElement(i);
  228. return agentCount;
  229. }
  230. /**
  231. * \brief Autoinfection mechanism for agents with that attribute enabled
  232. * @param deltaT tick
  233. */
  234. void SpawnAgents(float deltaT)
  235. {
  236. int count = m_PluginTransmissionAgents.GetAgentList().Count();
  237. for (int i = 0; i < count; ++i)
  238. {
  239. AgentBase agent = m_PluginTransmissionAgents.GetAgentList().GetElement(i);
  240. int agentId = agent.GetAgentType();
  241. if (GetSingleAgentCount(agentId) == 0 && agent.AutoinfectCheck(deltaT, m_Player))
  242. AddAgent(agentId, agent.GetAutoinfectCount());
  243. }
  244. }
  245. /**
  246. * \brief Directly set the count of agents for give id in pool
  247. * @param agent_id Id of agent to add into pool (see eAgents)
  248. * @param count Number of agents to be set
  249. */
  250. void SetAgentCount(int agent_id, float count)
  251. {
  252. if (count > 0)
  253. {
  254. //Debug.Log("+ growing agent"+ agent_id.ToString() +"to count: "+count.ToString(), "Agents");
  255. m_VirusPool.Set(agent_id, count);
  256. m_AgentMask = m_AgentMask | agent_id;
  257. }
  258. else
  259. {
  260. //Debug.Log("- REMOVING agent"+ agent_id.ToString(), "Agents");
  261. m_VirusPool.Remove(agent_id);
  262. m_AgentMask = m_AgentMask & ~agent_id;
  263. }
  264. if (m_Player.m_Agents != m_AgentMask)
  265. {
  266. m_Player.m_Agents = m_AgentMask;
  267. m_Player.SetSynchDirty();
  268. }
  269. }
  270. /**
  271. * \brief Antibiotics treatment agains agents which are not resistent to it (see agent attributes)
  272. * @param attack_value Strength of the anitibiotics attack
  273. */
  274. void AntibioticsAttack(float attack_value)
  275. {
  276. for (int i = 0; i < m_VirusPool.Count(); ++i)
  277. {
  278. int agentId = m_VirusPool.GetKey(i);
  279. float resistance = 1 - m_PluginTransmissionAgents.GetAgentAntiboticsResistanceEx(agentId, m_Player);
  280. float delta = attack_value * resistance;
  281. float actualAgentCount = m_VirusPool.Get(agentId);
  282. float newAgentCount = actualAgentCount - delta;
  283. SetAgentCount(agentId, newAgentCount);
  284. }
  285. }
  286. /**
  287. * \brief Drugs treatment logic
  288. * @param drugType Type of drug used (see EMedicalDrugsType enum)
  289. * @param attack_value Strength of the drug attack
  290. */
  291. void DrugsAttack(EMedicalDrugsType drugType, float attackValue)
  292. {
  293. switch (drugType)
  294. {
  295. case EMedicalDrugsType.ANTIBIOTICS:
  296. AntibioticsAttack(attackValue);
  297. break;
  298. default:
  299. for (int i = 0; i < m_VirusPool.Count(); ++i)
  300. {
  301. int agentId = m_VirusPool.GetKey(i);
  302. float actualAgentCount = m_VirusPool.Get(agentId);
  303. float newAgentCount = actualAgentCount - attackValue;
  304. SetAgentCount(agentId, newAgentCount);
  305. }
  306. }
  307. }
  308. /**
  309. * \brief Sets temporary resistance time against specified agent contraction
  310. * @param @param agent_id Id of agent to add into pool (see eAgents)
  311. * @param time Length of resistance in seconds
  312. */
  313. void SetTemporaryResistance(int agentId, float time)
  314. {
  315. m_AgentTemporaryResistance[agentId] = Math.Clamp(time, 0.0, int.MAX);
  316. }
  317. /**
  318. * \brief Returns remaining temporary resistance time for specified agent
  319. * @param @param agent_id Id of agent to add into pool (see eAgents)
  320. * \return time in seconds
  321. */
  322. float GetTemporaryResistance(int agentId)
  323. {
  324. if (m_AgentTemporaryResistance.Contains(agentId))
  325. return m_AgentTemporaryResistance[agentId];
  326. return 0.0;
  327. }
  328. /**
  329. * \brief Resets temporary resistance for all agents (internal usage only)
  330. */
  331. private void ResetTemporaryResistance()
  332. {
  333. foreach (int agentId, float value : m_AgentTemporaryResistance)
  334. SetTemporaryResistance(agentId, 0.0);
  335. }
  336. void RemoteGrowRequestDebug(ParamsReadContext ctx)
  337. {
  338. ctx.Read(CachedObjectsParams.PARAM1_INT);
  339. int id = CachedObjectsParams.PARAM1_INT.param1;
  340. int max = m_PluginTransmissionAgents.GetAgentMaxCount(Math.AbsInt(id));
  341. int grow = max / 10;
  342. if (id > 0)
  343. AddAgent(id, grow);
  344. else if (id < 0)
  345. AddAgent(-id, -grow);
  346. }
  347. void GetDebugObject(array<ref Param> object_out)
  348. {
  349. int count = m_PluginTransmissionAgents.GetAgentList().Count();
  350. for (int i = 0; i < count; i++)
  351. {
  352. AgentBase agent = m_PluginTransmissionAgents.GetAgentList().GetElement(i);
  353. string agentName = agent.GetName();
  354. int agentId = agent.GetAgentType();
  355. int maxAgents = m_PluginTransmissionAgents.GetAgentMaxCount(agentId);
  356. string amount = GetSingleAgentCount(agentId).ToString() + "/" + maxAgents.ToString();
  357. float tempResistance = GetTemporaryResistance(agentId);
  358. object_out.Insert(new Param4<string,string, int, float>(agentName, amount, agentId, tempResistance));
  359. }
  360. object_out.InsertAt(new Param1<int>(count) ,0);
  361. }
  362. void PrintAgents()
  363. {
  364. if (m_VirusPool)
  365. {
  366. for (int i = 0; i < m_VirusPool.Count(); ++i)
  367. {
  368. Debug.Log("Agent: "+ m_VirusPool.GetKey(i).ToString(), "Agents");
  369. Debug.Log("Count: "+ m_VirusPool.GetElement(i).ToString(), "Agents");
  370. }
  371. }
  372. }
  373. //! DEPRECATED
  374. ref array<int> m_VirusPoolArray = new array<int>();
  375. }