plugintransmissionagents.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. enum InjectTypes
  2. {
  3. PLAYER_TO_ITEM,
  4. ITEM_TO_PLAYER,
  5. PLAYER_AIR_PLAYER,
  6. };
  7. class PluginTransmissionAgents extends PluginBase
  8. {
  9. static ref map<int, ref AgentBase> m_AgentList = new map<int, ref AgentBase>();
  10. ref map<int, string> m_SimpleAgentList = new map<int, string>;
  11. bool m_IsConstructed = false;
  12. void PluginTransmissionAgents()
  13. {
  14. //add new agents here
  15. RegisterAgent(new InfluenzaAgent);
  16. RegisterAgent(new CholeraAgent);
  17. RegisterAgent(new SalmonellaAgent);
  18. RegisterAgent(new BrainAgent);
  19. RegisterAgent(new FoodPoisonAgent);
  20. RegisterAgent(new ChemicalAgent);
  21. RegisterAgent(new WoundAgent);
  22. RegisterAgent(new NerveAgent);
  23. RegisterAgent(new HeavyMetalAgent);
  24. }
  25. void RegisterAgent(AgentBase agent)
  26. {
  27. m_AgentList.Insert(agent.GetAgentType(), agent);
  28. }
  29. void ConstructSimpleAgentList()
  30. {
  31. string agent_name;
  32. int agent_type;
  33. for(int i = 0; i < m_AgentList.Count();i++)
  34. {
  35. AgentBase agent = m_AgentList.GetElement(i);
  36. agent_name = agent.GetName();
  37. agent_type = agent.GetAgentType();
  38. m_SimpleAgentList.Insert(agent_type, agent_name);
  39. }
  40. }
  41. map<int, ref AgentBase> GetAgentList()
  42. {
  43. return m_AgentList;
  44. }
  45. // this is a list which is easy to work with for displaying all agents and interacting with them, it doesn't serve any gameplay purpose
  46. map<int, string> GetSimpleAgentList()
  47. {
  48. if( !m_IsConstructed )
  49. {
  50. ConstructSimpleAgentList();
  51. m_IsConstructed = true;
  52. }
  53. return m_SimpleAgentList;
  54. }
  55. static string GetNameByID(int agent_id)
  56. {
  57. return m_AgentList.Get(agent_id).GetName();
  58. }
  59. void RemoveAllAgents(EntityAI target)
  60. {
  61. target.RemoveAllAgents();
  62. }
  63. static void RemoveAgent(EntityAI target, int agent_id )
  64. {
  65. target.RemoveAgent( agent_id );
  66. }
  67. protected float GetAgentTransferabilityIn( int agent_id )
  68. {
  69. if( !m_AgentList.Get(agent_id) ) return 0;
  70. return m_AgentList.Get(agent_id).GetTransferabilityIn();
  71. }
  72. bool GrowDuringMedicalDrugsAttack(int agentId, EMedicalDrugsType drugType, PlayerBase player)
  73. {
  74. AgentBase agent = m_AgentList.Get(agentId);
  75. if (!agent)
  76. return true;
  77. return agent.GrowDuringMedicalDrugsAttack(drugType, player);
  78. }
  79. float GetAgentDieOffSpeedEx(int agent_id, PlayerBase player)
  80. {
  81. if( !m_AgentList.Get(agent_id) ) return true;
  82. return m_AgentList.Get(agent_id).GetDieOffSpeedEx(player);
  83. }
  84. EStatLevels GetAgentPotencyEx(int agent_id, PlayerBase player)
  85. {
  86. if( !m_AgentList.Get(agent_id) ) return true;
  87. return m_AgentList.Get(agent_id).GetPotencyEx(player);
  88. }
  89. float GetAgentInvasibilityEx(int agent_id, PlayerBase player)
  90. {
  91. if( !m_AgentList.Get(agent_id) ) return true;
  92. return m_AgentList.Get(agent_id).GetInvasibilityEx(player);
  93. }
  94. float GetAgentAntiboticsResistance( int agent_id )
  95. {
  96. if( !m_AgentList.Get(agent_id) ) return 0;
  97. return m_AgentList.Get(agent_id).GetAntiboticsResistance();
  98. }
  99. float GetAgentAntiboticsResistanceEx( int agent_id , PlayerBase player)
  100. {
  101. if( !m_AgentList.Get(agent_id) ) return 0;
  102. return m_AgentList.Get(agent_id).GetAntibioticsResistanceEx(player);
  103. }
  104. protected float GetAgentTransferabilityOut( int agent_id )
  105. {
  106. if(!m_AgentList.Get(agent_id)) return 0;
  107. return m_AgentList.Get(agent_id).GetTransferabilityOut();
  108. }
  109. protected float GetAgentTransferabilityAirOut( int agent_id )
  110. {
  111. if(!m_AgentList.Get(agent_id)) return 0;
  112. return m_AgentList.Get(agent_id).GetTransferabilityAirOut();
  113. }
  114. /*
  115. float GetAgentChance( int agent_id )
  116. {
  117. return m_AgentList.Get(agent_id).GetChanceOfInfection();
  118. }
  119. */
  120. float GetAgentInvasibility( int agent_id )
  121. {
  122. if( !m_AgentList.Get(agent_id) )
  123. return 0;
  124. return m_AgentList.Get(agent_id).GetInvasibility();
  125. }
  126. float GetAgentDigestibilityEx(int agent_id, PlayerBase player)
  127. {
  128. if (!m_AgentList.Get(agent_id))
  129. return 0;
  130. return m_AgentList.Get(agent_id).GetDigestibilityEx(player);
  131. }
  132. float GetAgentDigestibility( int agent_id )
  133. {
  134. if( !m_AgentList.Get(agent_id) )
  135. return 0;
  136. return m_AgentList.Get(agent_id).GetDigestibility();
  137. }
  138. float GetDieOffSpeed( int agent_id )
  139. {
  140. if( !m_AgentList.Get(agent_id) )
  141. return 0;
  142. return m_AgentList.Get(agent_id).GetDieOffSpeed();
  143. }
  144. EStatLevels GetPotency( int agent_id )
  145. {
  146. if( !m_AgentList.Get(agent_id) )
  147. return 0;
  148. return m_AgentList.Get(agent_id).GetPotency();
  149. }
  150. static int GetAgentMaxCount( int agent_id )
  151. {
  152. if( !m_AgentList.Get(agent_id) ) return 0;
  153. return m_AgentList.Get(agent_id).GetMaxCount();
  154. }
  155. /*
  156. private float GetAgentInitialCount( int agent_id )
  157. {
  158. return m_AgentList.Get(agent_id).GetInitialCount();
  159. }
  160. */
  161. /*
  162. float GetImmunityResistance( int agent_id )
  163. {
  164. if( !m_AgentList.Get(agent_id) ) return 0;
  165. return m_AgentList.Get(agent_id).GetImmunityResistance();
  166. }
  167. */
  168. float TransmitAgentsEx(EntityAI source, EntityAI target, int pathway, int dose_size = 1000, int agents = 0)
  169. {
  170. //Debug.Log("Transmitting agents for source: " +source.ToString()+", target: " +target.ToString(),"Agents");
  171. int sourceAgents = agents;
  172. int targetAgents;
  173. if(!sourceAgents && source) sourceAgents = source.GetAgents();//do not set sourceAgents again if already set
  174. if(target) targetAgents = target.GetAgents();
  175. int pollution = GetGame().GetMission().GetWorldData().GetPollution();
  176. float count = 0;
  177. switch (pathway)
  178. {
  179. case AGT_INV_OUT: //item leaving inventory
  180. break;
  181. case AGT_INV_IN: //item entering inventory
  182. break;
  183. case AGT_UACTION_TOUCH: //player touched the item
  184. //InjectAgents( source, targetAgents ,GetProtectionLevel(DEF_BIOLOGICAL,InventorySlots.GLOVES, player) );
  185. break;
  186. case AGT_WATER_POND:
  187. if (pollution & EPollution.HEAVYMETAL)
  188. {
  189. sourceAgents = sourceAgents | eAgents.HEAVYMETAL;
  190. }
  191. sourceAgents = sourceAgents | eAgents.CHOLERA;
  192. InjectAgentsWithPlayer( target, sourceAgents , 0, 1, InjectTypes.ITEM_TO_PLAYER );
  193. break;
  194. case AGT_WATER_HOT_SPRING:
  195. sourceAgents = sourceAgents | eAgents.FOOD_POISON | eAgents.HEAVYMETAL;
  196. InjectAgentsWithPlayer( target, sourceAgents , 0, 1, InjectTypes.ITEM_TO_PLAYER );
  197. break;
  198. case AGT_SNOW:
  199. if (pollution & EPollution.HEAVYMETAL)
  200. {
  201. sourceAgents = sourceAgents | eAgents.HEAVYMETAL;
  202. }
  203. InjectAgentsWithPlayer( target, sourceAgents , 0, 1, InjectTypes.ITEM_TO_PLAYER );
  204. break;
  205. case AGT_UACTION_CONSUME:
  206. //InjectAgentsWithPlayer( target, sourceAgents , 0, dose_size, InjectTypes.ITEM_TO_PLAYER );
  207. InjectAgentsWithPlayer( source, targetAgents , 0, 1, InjectTypes.PLAYER_TO_ITEM );
  208. break;
  209. case AGT_UACTION_TO_PLAYER: //user action of a consumption, only from item to player
  210. InjectAgentsWithPlayerCount( target, sourceAgents , 0, dose_size, InjectTypes.ITEM_TO_PLAYER );
  211. break;
  212. case AGT_UACTION_TO_ITEM: //to transfer from the player to the consumed item
  213. InjectAgentsWithPlayer( target, sourceAgents , 0, 1, InjectTypes.PLAYER_TO_ITEM );
  214. break;
  215. case AGT_TRANSFER_COPY: //transferring liquid
  216. InjectAgentsWithoutPlayer( target, sourceAgents );
  217. break;
  218. case AGT_ITEM_TO_FLESH: //transferring liquid
  219. InjectAgentsWithPlayer( target, sourceAgents , 0, 1, InjectTypes.ITEM_TO_PLAYER);
  220. break;
  221. case AGT_AIRBOURNE_BIOLOGICAL:
  222. float prot_level_mask_target = GetProtectionLevel(DEF_BIOLOGICAL,InventorySlots.MASK, Man.Cast( target ));
  223. float prot_level_mask_source = GetProtectionLevel(DEF_BIOLOGICAL,InventorySlots.MASK, Man.Cast( source ));
  224. float prot_level_headgear_target = GetProtectionLevel(DEF_BIOLOGICAL,InventorySlots.HEADGEAR, Man.Cast( target ));
  225. float prot_level_headgear_source = GetProtectionLevel(DEF_BIOLOGICAL,InventorySlots.HEADGEAR, Man.Cast( source ));
  226. float prot_level_target = Math.Max(prot_level_mask_target, prot_level_headgear_target);//find the bigger of the 2, TODO: should be improved
  227. float prot_level_source = Math.Max(prot_level_mask_source, prot_level_headgear_source);//find the bigger of the 2, TODO: should be improved
  228. float prot_level_combined = 1 - (1 - prot_level_target) * (1 - prot_level_source);
  229. InjectAgentsWithPlayer( target, sourceAgents , prot_level_combined, 1, InjectTypes.PLAYER_AIR_PLAYER );
  230. break;
  231. case AGT_AIRBOURNE_CHEMICAL:
  232. float prot_level_mask_target2 = GetProtectionLevel(DEF_CHEMICAL,InventorySlots.MASK, Man.Cast( target ));
  233. count = InjectAgentWithPlayerDose( target, agents , prot_level_mask_target2, dose_size, InjectTypes.PLAYER_AIR_PLAYER );
  234. break;
  235. default:
  236. break;
  237. }
  238. return count;
  239. }
  240. void TransmitAgents(EntityAI source, EntityAI target, int pathway, int dose_size = 1000)
  241. {
  242. TransmitAgentsEx(source, target, pathway, dose_size);
  243. }
  244. protected void InjectAgentsWithoutPlayer(EntityAI target, int agents)
  245. {
  246. if( target.IsItemBase() )
  247. {
  248. ItemBase ib_target = ItemBase.Cast( target );
  249. ib_target.TransferAgents(agents);
  250. }
  251. }
  252. //! will add agents to a given target, using chance of transmission and full dose size if chance succeeds
  253. protected void InjectAgentsWithPlayer(EntityAI target, int agents,float protection, int dose_size, int inject_type)//target,array_of_agents,protection_lvl
  254. {
  255. if(target && (agents != 0) && target.IsEntityAI() )
  256. {
  257. int bit_count = Math.GetNumberOfSetBits(agents);
  258. for (int i = 0; i < bit_count; i++)
  259. {
  260. int agent_bit = Math.Pow(2,Math.GetNthBitSet(agents,i));
  261. if( DetermineChanceToTransmit(agent_bit, protection, inject_type))
  262. {
  263. target.InsertAgent(agent_bit,dose_size);
  264. }
  265. }
  266. }
  267. }
  268. //! will add agents to a given target, with no probability, but the dose size is modified by m_TransferabilityOut of the agent
  269. protected void InjectAgentsWithPlayerCount(EntityAI target, int agents,float protection, int dose_size, int inject_type)//target,array_of_agents,protection_lvl
  270. {
  271. if(target && (agents != 0) && target.IsEntityAI() )
  272. {
  273. int bit_count = Math.GetNumberOfSetBits(agents);
  274. for (int i = 0; i < bit_count; i++)
  275. {
  276. int agent_bit = Math.Pow(2,Math.GetNthBitSet(agents,i));
  277. float count = CalculateAgentsToTransmit(agent_bit, protection, dose_size, inject_type);
  278. target.InsertAgent(agent_bit,count);
  279. }
  280. }
  281. }
  282. //! will add agent to a given target
  283. protected float InjectAgentWithPlayerDose(EntityAI target, int agent, float protection, float dose_size, int inject_type)//target,array_of_agents,protection_lvl
  284. {
  285. float count = CalculateAgentsToTransmit(agent, protection, dose_size, inject_type);
  286. {
  287. if(count > 0)
  288. {
  289. target.InsertAgent(agent, count);
  290. return count;
  291. }
  292. }
  293. return 0;
  294. }
  295. // !performance hog, avoid
  296. static void BuildAgentArray(int agents, array<int> agents_out)
  297. {
  298. int mask = 1;
  299. for(int i = 0; i < BIT_INT_SIZE; i++)
  300. {
  301. if( mask & agents )
  302. agents_out.Insert(mask);
  303. mask = mask * 2;
  304. }
  305. }
  306. static float GetProtectionLevelEx(int type, int slot, Man player, bool consider_filter = true, int system = 0)
  307. {
  308. ItemBase attachment = ItemBase.Cast(player.GetInventory().FindAttachment(slot));
  309. if(!attachment)
  310. return 0;
  311. return attachment.GetProtectionLevel(type, consider_filter, system);
  312. }
  313. protected float GetProtectionLevel(int type, int slot, Man player)
  314. {
  315. return GetProtectionLevelEx(type, slot, player);
  316. }
  317. //------------------------------------------------------------------------------------------------------
  318. protected float CalculateAgentsToTransmit(int agent_id, float protection, int dose_size, int inject_type)
  319. {
  320. //Debug.Log("protection: "+protection.ToString());
  321. float prot = 1 - protection; //reverse the value (in config, the higher the value, the higher the protection: 0 - 1) so that we can easily interpolate between 0 and 1 by multiplication
  322. //Debug.Log("prot: "+prot.ToString(), "Agents");
  323. float transf;
  324. if( inject_type == InjectTypes.PLAYER_TO_ITEM )
  325. {
  326. transf = GetAgentTransferabilityOut(agent_id);
  327. }
  328. else if( inject_type == InjectTypes.ITEM_TO_PLAYER )
  329. {
  330. transf = GetAgentTransferabilityIn(agent_id);
  331. }
  332. else if( inject_type == InjectTypes.PLAYER_AIR_PLAYER )
  333. {
  334. transf = GetAgentTransferabilityAirOut(agent_id);
  335. }
  336. //Debug.Log("transf: "+transf.ToString(), "Agents");
  337. //float result = GetAgentInitialCount(agent_id) * prot * transf * dose_size;//final formula
  338. float result = 1 * prot * transf * dose_size;//final formula
  339. //result = Math.Ceil(result);
  340. //Debug.Log("result: "+result.ToString(), "Agents");
  341. return result;
  342. }
  343. //------------------------------------------------------------------------------------------------------
  344. protected bool DetermineChanceToTransmit(int agent_id, float protection, int inject_type)
  345. {
  346. //Debug.Log("protection: "+protection.ToString());
  347. float prot = 1 - protection; //reverse the value (in config, the higher the value, the higher the protection: 0 - 1) so that we can easily interpolate between 0 and 1 by multiplication
  348. //Debug.Log("prot: "+prot.ToString(), "Agents");
  349. float transf;
  350. if( inject_type == InjectTypes.PLAYER_TO_ITEM )
  351. {
  352. transf = GetAgentTransferabilityOut(agent_id);
  353. }
  354. else if( inject_type == InjectTypes.ITEM_TO_PLAYER )
  355. {
  356. transf = GetAgentTransferabilityIn(agent_id);
  357. }
  358. else if( inject_type == InjectTypes.PLAYER_AIR_PLAYER )
  359. {
  360. transf = GetAgentTransferabilityAirOut(agent_id);
  361. }
  362. #ifdef DEVELOPER
  363. //Debug.Log("transf: "+transf.ToString(), "Agents");
  364. #endif
  365. //float result = GetAgentInitialCount(agent_id) * prot * transf * dose_size;//final formula
  366. bool dice = Math.RandomFloat01() < (prot * transf);
  367. //result = Math.Ceil(result);
  368. return dice;
  369. }
  370. //------------------------------------------------------------------------------------------------------
  371. //! DEPRECATED
  372. bool GrowDuringAntibioticsAttack(int agent_id, PlayerBase player)
  373. {
  374. if (!m_AgentList.Get(agent_id))
  375. return true;
  376. return m_AgentList.Get(agent_id).GrowDuringMedicalDrugsAttack(EMedicalDrugsType.ANTIBIOTICS, player);
  377. }
  378. }