Advertisement
Guest User

Untitled

a guest
Jan 20th, 2014
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.30 KB | None | 0 0
  1.  
  2.  
  3. --
  4. -- DATA STRUCTURES
  5. --
  6. -- rActor
  7. -- sType
  8. -- sName
  9. -- nodeCreature
  10. -- sCreatureNode
  11. -- nodeCT
  12. -- sCTNode
  13. --
  14.  
  15. function getActor(sActorType, varActor)
  16. -- GET ACTOR NODE
  17. local nodeActor = nil;
  18. if type(varActor) == "string" then
  19. if varActor ~= "" then
  20. nodeActor = DB.findNode(varActor);
  21. end
  22. elseif type(varActor) == "databasenode" then
  23. nodeActor = varActor;
  24. end
  25. if not nodeActor then
  26. return nil;
  27. end
  28.  
  29. -- BASED ON ORIGINAL ACTOR NODE, FILL IN THE OTHER INFORMATION
  30. local rActor = nil;
  31. if sActorType == "ct" then
  32. rActor = {};
  33. rActor.sType = DB.getValue(nodeActor, "type", "npc");
  34. rActor.sName = DB.getValue(nodeActor, "name", "");
  35. rActor.nodeCT = nodeActor;
  36.  
  37. local sClass,sRecord = DB.getValue(nodeActor, "link", "", "");
  38. if rActor.sType == "pc" and sClass == "charsheet" then
  39. rActor.nodeCreature = DB.findNode(sRecord);
  40. if rActor.nodeCreature then
  41. rActor.sName = DB.getValue(rActor.nodeCreature, "name", "");
  42. end
  43. elseif rActor.sType == "npc" and sClass == "npc" then
  44. rActor.nodeCreature = DB.findNode(sRecord);
  45. end
  46.  
  47. elseif sActorType == "pc" then
  48. rActor = {};
  49. rActor.sType = "pc";
  50. rActor.nodeCreature = nodeActor;
  51. rActor.nodeCT = CTManager.getCTFromNode(nodeActor);
  52. rActor.sName = DB.getValue(rActor.nodeCreature, "name", "");
  53.  
  54. elseif sActorType == "npc" then
  55. rActor = {};
  56. rActor.sType = "npc";
  57. rActor.nodeCreature = nodeActor;
  58.  
  59. -- IF ACTIVE CT IS THIS NPC TYPE, THEN ASSOCIATE
  60. local nodeActiveCT = CTManager.getActiveCT();
  61. if nodeActiveCT then
  62. local _,sRecord = DB.getValue(nodeActiveCT, "link", "", "");
  63. if sRecord == nodeActor.getNodeName() then
  64. rActor.nodeCT = nodeActiveCT;
  65. end
  66. end
  67. -- OTHERWISE, ASSOCIATE WITH UNIQUE CT, IF POSSIBLE
  68. if not rActor.nodeCT then
  69. local bMatch = false;
  70. for _,nodeEntry in pairs(DB.getChildren("combattracker")) do
  71. local _,sRecord = DB.getValue(nodeEntry, "link", "", "");
  72. if sRecord == nodeActor.getNodeName() then
  73. if bMatch then
  74. rActor.nodeCT = nil;
  75. break;
  76. end
  77.  
  78. rActor.nodeCT = nodeEntry;
  79. bMatch = true;
  80. end
  81. end
  82. end
  83.  
  84. rActor.sName = DB.getValue(rActor.nodeCT or rActor.nodeCreature, "name", "");
  85. end
  86.  
  87. -- TRACK THE NODE NAMES AS WELL
  88. if rActor.nodeCT then
  89. rActor.sCTNode = rActor.nodeCT.getNodeName();
  90. else
  91. rActor.sCTNode = "";
  92. end
  93. if rActor.nodeCreature then
  94. rActor.sCreatureNode = rActor.nodeCreature.getNodeName();
  95. else
  96. rActor.sCreatureNode = "";
  97. end
  98.  
  99. -- RETURN ACTOR INFORMATION
  100. return rActor;
  101. end
  102.  
  103. function getActorFromToken(token)
  104. local nodeCT = CTManager.getCTFromToken(token);
  105. if nodeCT then
  106. return getActor("ct", nodeCT.getNodeName());
  107. end
  108.  
  109. return nil;
  110. end
  111.  
  112. function getDropActors(sNodeType, nodename, draginfo)
  113. local rSource = decodeActors(draginfo);
  114. local rTarget = getActor(sNodeType, nodename);
  115. return rSource, rTarget;
  116. end
  117.  
  118. function encodeActors(rSource, vTargets, bMultiTarget)
  119. -- SETUP
  120. local aCustom = {};
  121.  
  122. -- ENCODE SOURCE ACTOR (CT, PC, NPC)
  123. if rSource then
  124. local sSourceType = "ct";
  125. local nodeSource = rSource.nodeCT;
  126. if not nodeSource then
  127. if rSource.sType == "pc" then
  128. sSourceType = "pc";
  129. elseif rSource.sType == "npc" then
  130. sSourceType = "npc";
  131. end
  132. nodeSource = rSource.nodeCreature;
  133. end
  134. if nodeSource then
  135. aCustom[sSourceType] = nodeSource;
  136. end
  137. end
  138.  
  139. -- ENCODE TARGET ACTOR (CT, PC) (NO NPC TARGETING)
  140. if vTargets then
  141. local aTargets;
  142. if bMultiTarget then
  143. aTargets = vTargets;
  144. else
  145. aTargets = { vTargets };
  146. end
  147.  
  148. local aCTTargetNodes = {};
  149. local aPCTargetNodes = {};
  150. for kTarget, rTarget in ipairs(aTargets) do
  151. if rTarget.nodeCT then
  152. table.insert(aCTTargetNodes, rTarget.nodeCT.getNodeName());
  153. elseif rTarget.sType == "pc" and rTarget.nodeCreature then
  154. table.insert(aPCTargetNodes, rTarget.nodeCreature.getNodeName());
  155. end
  156. end
  157.  
  158. aCustom["targetct"] = table.concat(aCTTargetNodes, "|");
  159. aCustom["targetpc"] = table.concat(aPCTargetNodes, "|");
  160. end
  161.  
  162. -- RESULTS
  163. return aCustom;
  164. end
  165.  
  166. function decodeActors(draginfo)
  167. -- SETUP
  168. local rSource = nil;
  169. local aTargets = {};
  170.  
  171. -- CHECK FOR DRAG INFORMATION
  172. if draginfo then
  173. local varCustom = draginfo.getCustomData();
  174.  
  175. -- CHECK FOR CUSTOM DATA
  176. if varCustom then
  177. -- GET CUSTOM SOURCE ACTOR
  178. if varCustom["ct"] then
  179. rSource = getActor("ct", varCustom["ct"]);
  180. elseif varCustom["pc"] then
  181. rSource = getActor("pc", varCustom["pc"]);
  182. elseif varCustom["npc"] then
  183. rSource = getActor("npc", varCustom["npc"]);
  184. end
  185.  
  186. -- GET CUSTOM TARGET ACTOR
  187. if varCustom["targetct"] then
  188. local aTargetNodeNames = StringManager.split(varCustom["targetct"], "|");
  189. for _,vName in ipairs(aTargetNodeNames) do
  190. local rTarget = getActor("ct", vName);
  191. if rTarget then
  192. table.insert(aTargets, rTarget);
  193. end
  194. end
  195. end
  196. if varCustom["targetpc"] then
  197. local aTargetNodeNames = StringManager.split(varCustom["targetpc"], "|");
  198. for _,vName in ipairs(aTargetNodeNames) do
  199. local rTarget = getActor("pc", vName);
  200. if rTarget then
  201. table.insert(aTargets, rTarget);
  202. end
  203. end
  204. end
  205. end
  206.  
  207. -- IF NO CUSTOM DATA FOR SOURCE, THEN TRY THE SHORTCUT DATA
  208. if not rSource then
  209. -- GET SHORTCUT SOURCE ACTOR
  210. local sRefClass, sRefNode = draginfo.getShortcutData();
  211. if sRefClass and sRefNode then
  212. if sRefClass == "combattracker_entry" then
  213. rSource = getActor("ct", sRefNode);
  214.  
  215. elseif sRefClass == "charsheet" then
  216. rSource = getActor("pc", sRefNode);
  217.  
  218. elseif sRefClass == "npc" then
  219. rSource = getActor("npc", sRefNode);
  220. end
  221. end
  222. end
  223. end
  224.  
  225. -- RESULTS
  226. return rSource, aTargets;
  227. end
  228.  
  229. function getPercentWounded(sNodeType, node)
  230. local nHP = 0;
  231. local nWounds = 0;
  232.  
  233. if sNodeType == "ct" then
  234. nHP = DB.getValue(node, "hp", 0);
  235. nWounds = DB.getValue(node, "wounds", 0);
  236. elseif sNodeType == "pc" then
  237. nHP = DB.getValue(node, "hp.total", 0);
  238. nWounds = DB.getValue(node, "hp.wounds", 0)
  239. end
  240.  
  241. local nPercentWounded = 0;
  242. if nHP > 0 then
  243. nPercentWounded = nWounds / nHP;
  244. end
  245.  
  246. local sStatus;
  247. if OptionsManager.isOption("WNDC", "detailed") then
  248. if nPercentWounded <= 0 then
  249. sStatus = "Healthy";
  250. elseif nPercentWounded < .25 then
  251. sStatus = "Light";
  252. elseif nPercentWounded < .5 then
  253. sStatus = "Moderate";
  254. elseif nPercentWounded < .75 then
  255. sStatus = "Bloodied";
  256. elseif nPercentWounded < 1 then
  257. sStatus = "Critical";
  258. elseif nPercentWounded < 1.5 then
  259. sStatus = "Dying";
  260. else
  261. sStatus = "Dead";
  262. end
  263. else
  264. if nPercentWounded <= 0 then
  265. sStatus = "Healthy";
  266. elseif nPercentWounded < .5 then
  267. sStatus = "Wounded";
  268. elseif nPercentWounded < 1 then
  269. sStatus = "Bloodied";
  270. elseif nPercentWounded < 1.5 then
  271. sStatus = "Dying";
  272. else
  273. sStatus = "Dead";
  274. end
  275. end
  276.  
  277. return nPercentWounded, sStatus;
  278. end
  279.  
  280. function getWoundColor(sNodeType, node)
  281. local nPercentWounded, sStatus = getPercentWounded(sNodeType, node);
  282.  
  283. -- Based on the percent wounded, change the font color for the Wounds field
  284. local sColor;
  285. if OptionsManager.isOption("WNDC", "detailed") then
  286. if nPercentWounded >= 1 then
  287. sColor = "404040";
  288. elseif nPercentWounded >= 0.75 then
  289. sColor = "C11B17";
  290. elseif nPercentWounded >= 0.5 then
  291. sColor = "E56717";
  292. elseif nPercentWounded >= 0.25 then
  293. sColor = "AF7817";
  294. elseif nPercentWounded > 0 then
  295. sColor = "408000";
  296. else
  297. sColor = "006600";
  298. end
  299. else
  300. if nPercentWounded >= 1 then
  301. sColor = "404040";
  302. elseif nPercentWounded >= 0.5 then
  303. sColor = "C11B17";
  304. elseif nPercentWounded > 0 then
  305. sColor = "408000";
  306. else
  307. sColor = "006600";
  308. end
  309. end
  310.  
  311. return sColor, nPercentWounded, sStatus;
  312. end
  313.  
  314. function getWoundBarColor(sNodeType, node)
  315. local nPercentWounded, sStatus = getPercentWounded(sNodeType, node);
  316.  
  317. local nRedR = 255;
  318. local nRedG = 0;
  319. local nRedB = 0;
  320. local nYellowR = 255;
  321. local nYellowG = 191;
  322. local nYellowB = 0;
  323. local nGreenR = 0;
  324. local nGreenG = 255;
  325. local nGreenB = 0;
  326.  
  327. local sColor;
  328. if nPercentWounded > 1 then
  329. sColor = "C0C0C0";
  330. else
  331. local nBarR, nBarG, nBarB;
  332. if nPercentWounded >= 0.5 then
  333. local nPercentGrade = (nPercentWounded - 0.5) * 2;
  334. nBarR = math.floor((nRedR * nPercentGrade) + (nYellowR * (1.0 - nPercentGrade)) + 0.5);
  335. nBarG = math.floor((nRedG * nPercentGrade) + (nYellowG * (1.0 - nPercentGrade)) + 0.5);
  336. nBarB = math.floor((nRedB * nPercentGrade) + (nYellowB * (1.0 - nPercentGrade)) + 0.5);
  337. else
  338. local nPercentGrade = nPercentWounded * 2;
  339. nBarR = math.floor((nYellowR * nPercentGrade) + (nGreenR * (1.0 - nPercentGrade)) + 0.5);
  340. nBarG = math.floor((nYellowG * nPercentGrade) + (nGreenG * (1.0 - nPercentGrade)) + 0.5);
  341. nBarB = math.floor((nYellowB * nPercentGrade) + (nGreenB * (1.0 - nPercentGrade)) + 0.5);
  342. end
  343. sColor = string.format("%02X%02X%02X", nBarR, nBarG, nBarB);
  344. end
  345.  
  346. return sColor, nPercentWounded, sStatus;
  347. end
  348.  
  349. function getAbilityScore(rActor, sAbility)
  350. if not rActor or not rActor.nodeCreature or not sAbility then
  351. return -1;
  352. end
  353.  
  354. local nStatScore = -1;
  355.  
  356. local sShort = string.sub(string.lower(sAbility), 1, 3);
  357. if rActor.sType == "npc" then
  358. if sShort == "lev" then
  359. nStatScore = tonumber(string.match(DB.getValue(rActor.nodeCreature, "levelrole", ""), "Level (%d*)")) or 0;
  360. elseif sShort == "phy" then
  361. nStatScore = DB.getValue(rActor.nodeCreature, "Physique", 0);
  362. elseif sShort == "spe" then
  363. nStatScore = DB.getValue(rActor.nodeCreature, "Speed", 0);
  364. elseif sShort == "str" then
  365. nStatScore = DB.getValue(rActor.nodeCreature, "Strength", 0);
  366. elseif sShort == "agi" then
  367. nStatScore = DB.getValue(rActor.nodeCreature, "Agility", 0);
  368. elseif sShort == "pro" then
  369. nStatScore = DB.getValue(rActor.nodeCreature, "Prowess", 0);
  370. elseif sShort == "poi" then
  371. nStatScore = DB.getValue(rActor.nodeCreature, "Poise", 0);
  372. elseif sShort == "int" then
  373. nStatScore = DB.getValue(rActor.nodeCreature, "Intellect", 0);
  374. elseif sShort == "arc" then
  375. nStatScore = DB.getValue(rActor.nodeCreature, "Arcane", 0);
  376. elseif sShort == "per" then
  377. nStatScore = DB.getValue(rActor.nodeCreature, "Perception", 0);
  378. elseif sShort == "wil" then
  379. nStatScore = DB.getValue(rActor.nodeCreature, "Willpower", 0);
  380. end
  381. elseif rActor.sType == "pc" then
  382. if sShort == "lev" then
  383. nStatScore = DB.getValue(rActor.nodeCreature, "level", 0);
  384. elseif sShort == "phy" then
  385. nStatScore = DB.getValue(rActor.nodeCreature, "stats.phy.score", 0);
  386. elseif sShort == "spe" then
  387. nStatScore = DB.getValue(rActor.nodeCreature, "stats.spd.score", 0);
  388. elseif sShort == "str" then
  389. nStatScore = DB.getValue(rActor.nodeCreature, "stats.str.score", 0);
  390. elseif sShort == "agi" then
  391. nStatScore = DB.getValue(rActor.nodeCreature, "stats.agi.score", 0);
  392. elseif sShort == "pro" then
  393. nStatScore = DB.getValue(rActor.nodeCreature, "stats.prw.score", 0);
  394. elseif sShort == "poi" then
  395. nStatScore = DB.getValue(rActor.nodeCreature, "stats.poi.score", 0);
  396. elseif sShort == "int" then
  397. nStatScore = DB.getValue(rActor.nodeCreature, "stats.int.score", 0);
  398. elseif sShort == "arc" then
  399. nStatScore = DB.getValue(rActor.nodeCreature, "stats.arc.score", 0);
  400. elseif sShort == "per" then
  401. nStatScore = DB.getValue(rActor.nodeCreature, "stats.per.score", 0);
  402. elseif sShort == "wil" then
  403. nStatScore = DB.getValue(rActor.nodeCreature, "willpower", 0);
  404. end
  405. end
  406.  
  407. return nStatScore;
  408. end
  409.  
  410. function getAbilityBonus(rActor, sAbility)
  411. -- VALIDATE
  412. if not rActor or not rActor.nodeCreature or not sAbility then
  413. return 0;
  414. end
  415.  
  416. -- SETUP
  417. local sStat = sAbility;
  418. local bHalf = false;
  419. local bDouble = false;
  420. local nStatVal = 0;
  421.  
  422.  
  423. -- HANDLE HALF/DOUBLE MODIFIERS
  424. if string.match(sStat, "^half") then
  425. bHalf = true;
  426. sStat = string.sub(sStat, 5);
  427. end
  428. if string.match(sStat, "^double") then
  429. bDouble = true;
  430. sStat = string.sub(sStat, 7);
  431. end
  432.  
  433. -- GET ABILITY VALUE
  434. local nStatScore = getAbilityScore(rActor, sStat);
  435. Debug.console(getAbilityScore)
  436. printstack()
  437. if nStatScore < 0 then
  438. return 0;
  439. end
  440.  
  441. if StringManager.contains(DataCommon.abilities, sStat) then
  442. nStatVal = nStatScore
  443. if rActor.sType == "pc" then
  444. nStatVal = nStatVal + DB.getValue(rActor.nodeCreature, "stats" .. sStat .. "stats", 0);
  445. end
  446. else
  447. nStatVal = nStatScore;
  448. end
  449.  
  450. -- APPLY HALF/DOUBLE MODIFIERS
  451. if bDouble then
  452. nStatVal = nStatVal * 2;
  453. end
  454. if bHalf then
  455. nStatVal = math.floor(nStatVal / 2);
  456. end
  457.  
  458. -- RESULTS
  459. return nStatVal;
  460. end
  461.  
  462. function getDefenseInternal(sDefense)
  463. local sInternal = "";
  464.  
  465. if sDefense then
  466. local sShortDef = string.sub(string.lower(sDefense), 1, 2);
  467. if sShortDef == "de" then
  468. sInternal = "def";
  469. elseif sShortDef == "ar" then
  470. sInternal = "arm";
  471. elseif sShortDef == "wi" then
  472. sInternal = "will";
  473. end
  474. end
  475.  
  476. return sInternal;
  477. end
  478.  
  479. function getDefenseValue(rAttacker, rDefender, rRoll)
  480. -- VALIDATE
  481. if not rDefender or not rRoll then
  482. return nil, 0, 0;
  483. end
  484.  
  485. local sAttack = rRoll.sDesc;
  486.  
  487. -- DETERMINE ATTACK TYPE AND DEFENSE
  488. local sAttackType = string.match(sAttack, "%[ATTACK.*%((%w+)%)%]");
  489. local bOpportunity = string.match(sAttack, "%[OPPORTUNITY%]");
  490. local sDefense = string.match(sAttack, "%(vs%.? (%a+)%)");
  491. if not sDefense then
  492. return nil, 0, 0;
  493. end
  494. sDefense = getDefenseInternal(sDefense);
  495. if sDefense == "" then
  496. return nil, 0, 0;
  497. end
  498.  
  499. -- Determine the defense database node name
  500. local nDefense = 10;
  501. if rDefender.nodeCT then
  502. nDefense = DB.getValue(rDefender.nodeCT, sDefense, 10);
  503. elseif rDefender.nodeCreature then
  504. if rDefender.sType == "pc" then
  505. nDefense = DB.getValue(rDefender.nodeCreature, "defenses." .. sDefense .. ".total", 10);
  506. else
  507. nDefense = DB.getValue(rDefender.nodeCreature, sDefense, 10);
  508. end
  509. else
  510. return nil, 0, 0;
  511. end
  512.  
  513. -- EFFECT MODIFIERS
  514. local nAttackEffectMod = 0;
  515. local nDefenseEffectMod = 0;
  516. if rDefender.nodeCT then
  517. -- SETUP
  518. local bCombatAdvantage = false;
  519. local bUncannyDodge = false;
  520. local bCheckCA = true;
  521. local nBonusAllDefenses = 0;
  522. local nBonusSpecificDefense = 0;
  523. local nBonusSituational = 0;
  524.  
  525. -- BUILD ATTACK FILTER
  526. local aAttackFilter = {};
  527. if sAttackType == "M" then
  528. table.insert(aAttackFilter, "melee");
  529. elseif sAttackType == "R" then
  530. table.insert(aAttackFilter, "ranged");
  531. elseif sAttackType == "C" then
  532. table.insert(aAttackFilter, "close");
  533. elseif sAttackType == "A" then
  534. table.insert(aAttackFilter, "area");
  535. end
  536. if bOpportunity then
  537. table.insert(aAttackFilter, "opportunity");
  538. end
  539.  
  540. -- GET ATTACKER BASE MODIFIER
  541. local aBonusTargetedAttackDice = {};
  542. local nBonusTargetedAttack = 0;
  543. if rAttacker then
  544. aBonusTargetedAttackDice, nBonusTargetedAttack = EffectsManager.getEffectsBonus(rAttacker, "ATK", false, aAttackFilter, rDefender, true);
  545. end
  546. nAttackEffectMod = nAttackEffectMod + StringManager.evalDice(aBonusTargetedAttackDice, nBonusTargetedAttack);
  547.  
  548. -- GET ATTACKER SITUATIONAL MODIFIERS
  549. -- AND CHECK WHETHER COMBAT ADVANTAGE HAS ALREADY BEEN APPLIED
  550. if EffectsManager.hasEffectCondition(rDefender, "Uncanny Dodge") then
  551. bUncannyDodge = true;
  552. bCheckCA = false;
  553. end
  554. if string.match(sAttack, "%[CA%]") then
  555. bCheckCA = false;
  556. if bUncannyDodge then
  557. nBonusSituational = nBonusSituational + 2;
  558. end
  559. end
  560. if bCheckCA then
  561. if EffectsManager.hasEffect(rAttacker, "CA", rDefender, true) or
  562. EffectsManager.hasEffect(rAttacker, "Invisible", rDefender, true) then
  563. bCombatAdvantage = true;
  564. end
  565. end
  566.  
  567. -- GET DEFENDER ALL DEFENSE MODIFIERS
  568. nBonusAllDefenses = EffectsManager.getEffectsBonus(rDefender, "DEF", true, aAttackFilter, rAttacker);
  569.  
  570. -- GET DEFENDER SPECIFIC DEFENSE MODIFIERS
  571. if sDefense == "DEF" then
  572. nBonusSpecificDefense = EffectsManager.getEffectsBonus(rDefender, "DEF", true, aAttackFilter, rAttacker);
  573. elseif sDefense == "ARM" then
  574. nBonusSpecificDefense = EffectsManager.getEffectsBonus(rDefender, "ARM", true, aAttackFilter, rAttacker);
  575. elseif sDefense == "will" then
  576. nBonusSpecificDefense = EffectsManager.getEffectsBonus(rDefender, "WILL", true, aAttackFilter, rAttacker);
  577. end
  578.  
  579. -- GET DEFENDER SITUATIONAL MODIFIERS - COMBAT ADVANTAGE
  580. if bCheckCA then
  581. -- CHECK ALL THE CONDITIONS THAT COULD GRANT COMBAT ADVANTAGE
  582. if EffectsManager.hasEffect(rDefender, "GRANTCA", rAttacker) then
  583. bCombatAdvantage = true;
  584. elseif EffectsManager.hasEffectCondition(rDefender, "Blinded") then
  585. bCombatAdvantage = true;
  586. elseif EffectsManager.hasEffectCondition(rDefender, "Dazed") then
  587. bCombatAdvantage = true;
  588. elseif EffectsManager.hasEffectCondition(rDefender, "Dominated") then
  589. bCombatAdvantage = true;
  590. elseif EffectsManager.hasEffectCondition(rDefender, "Helpless") then
  591. bCombatAdvantage = true;
  592. elseif EffectsManager.hasEffectCondition(rDefender, "Prone") and (sAttackType == "M") then
  593. bCombatAdvantage = true;
  594. elseif EffectsManager.hasEffectCondition(rDefender, "Restrained") then
  595. bCombatAdvantage = true;
  596. elseif EffectsManager.hasEffectCondition(rDefender, "Stunned") then
  597. bCombatAdvantage = true;
  598. elseif EffectsManager.hasEffectCondition(rDefender, "Surprised") then
  599. bCombatAdvantage = true;
  600. elseif EffectsManager.hasEffectCondition(rDefender, "Unconscious") then
  601. bCombatAdvantage = true;
  602. end
  603.  
  604. -- CHECK ALL THE OTHER EFFECTS THAT COULD GRANT COMBAT ADVANTAGE
  605. if EffectsManager.hasEffectCondition(rDefender, "Balancing") then
  606. bCombatAdvantage = true;
  607. elseif EffectsManager.hasEffectCondition(rDefender, "Climbing") then
  608. bCombatAdvantage = true;
  609. elseif EffectsManager.hasEffectCondition(rDefender, "Running") then
  610. bCombatAdvantage = true;
  611. elseif EffectsManager.hasEffectCondition(rDefender, "Squeezing") then
  612. bCombatAdvantage = true;
  613. end
  614.  
  615. -- APPLY COMBAT ADVANTAGE AS DEFENSE PENALTY
  616. if bCombatAdvantage then
  617. nBonusSituational = nBonusSituational - 2;
  618. end
  619. end
  620.  
  621. -- GET DEFENDER SITUATIONAL MODIFIERS - CONDITIONS
  622. if EffectsManager.hasEffectCondition(rDefender, "Prone") and (sAttackType == "R") then
  623. nBonusSituational = nBonusSituational + 2;
  624. end
  625. if EffectsManager.hasEffectCondition(rDefender, "Unconscious") then
  626. nBonusSituational = nBonusSituational - 5;
  627. end
  628.  
  629. -- GET DEFENDER SITUATIONAL MODIFIERS - CONCEALMENT
  630. if sAttackType and (sAttackType == "M" or sAttackType == "R") then
  631. local bCheckConceal = true;
  632. if string.match(sAttack, "%[BLINDED%]") then
  633. bCheckConceal = false;
  634. end
  635. if bCheckConceal then
  636. local bTotalConceal = false;
  637. local bConceal = false;
  638.  
  639. if string.match(sAttack, "%[TCONC%]") then
  640. bTotalConceal = true;
  641. elseif string.match(sAttack, "%[CONC%]") then
  642. bConceal = true;
  643. end
  644.  
  645. if not bTotalConceal then
  646. if EffectsManager.hasEffect(rDefender, "Invisible", rAttacker) then
  647. bTotalConceal = true;
  648. elseif EffectsManager.hasEffect(rAttacker, "Blinded", rDefender, true) and StringManager.isWord(sAttackType, {"M", "R"}) then
  649. bTotalConceal = true;
  650. else
  651. local aConcealment = EffectsManager.getEffectsByType(rDefender, "TCONC", aAttackFilter, rAttacker);
  652. if #aConcealment > 0 or EffectsManager.hasEffect(rDefender, "TCONC", rAttacker) then
  653. bTotalConceal = true;
  654. elseif not bConceal then
  655. aConcealment = EffectsManager.getEffectsByType(rDefender, "CONC", aAttackFilter, rAttacker);
  656. if #aConcealment > 0 or EffectsManager.hasEffect(rDefender, "CONC", rAttacker) then
  657. bConceal = true;
  658. end
  659. end
  660. end
  661. end
  662.  
  663. if bTotalConceal then
  664. nBonusSituational = nBonusSituational + 5;
  665. elseif bConceal then
  666. nBonusSituational = nBonusSituational + 2;
  667. end
  668. end
  669. end
  670.  
  671. -- GET DEFENDER SITUATIONAL MODIFIERS - COVER
  672. local bSuperiorCover = false;
  673. local bCover = false;
  674. if string.match(sAttack, "%[SCOVER%]") then
  675. bSuperiorCover = true;
  676. elseif string.match(sAttack, "%[COVER%]") then
  677. bCover = true;
  678. end
  679.  
  680. if not bSuperiorCover then
  681. local aCover = EffectsManager.getEffectsByType(rDefender, "SCOVER", aAttackFilter, rAttacker);
  682. if #aCover > 0 or EffectsManager.hasEffect(rDefender, "SCOVER", rAttacker) then
  683. bSuperiorCover = true;
  684. elseif not bCover then
  685. aCover = EffectsManager.getEffectsByType(rDefender, "COVER", aAttackFilter, rAttacker);
  686. if #aCover > 0 or EffectsManager.hasEffect(rDefender, "COVER", rAttacker) then
  687. bCover = true;
  688. end
  689. end
  690. end
  691.  
  692. if bSuperiorCover then
  693. nBonusSituational = nBonusSituational + 5;
  694. elseif bCover then
  695. nBonusSituational = nBonusSituational + 2;
  696. end
  697.  
  698. -- ADD IN EFFECT MODIFIERS
  699. nDefenseEffectMod = nBonusAllDefenses + nBonusSpecificDefense + nBonusSituational;
  700. end
  701.  
  702. -- Return the final defense value
  703. return nDefense + nDefenseEffectMod - nAttackEffectMod, nAttackEffectMod, nDefenseEffectMod;
  704. end
  705.  
  706. function getSave(rActor)
  707. if rActor then
  708. if rActor.sType == "pc" then
  709. return DB.getValue(rActor.nodeCreature, "defenses.save.total", 0);
  710. elseif rActor.sType == "ct" or rActor.sType == "npc" then
  711. return DB.getValue(rActor.nodeCreature, "save", 0);
  712. end
  713. end
  714.  
  715. return 0;
  716. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement