From a18c73b0b72fab67bfeac98e777718654ce993f0 Mon Sep 17 00:00:00 2001 From: Timothy Date: Tue, 11 Jul 2017 18:55:48 -0500 Subject: [PATCH] Merged infection/poison features into one -Removed poison condition -Changed infection to work differently. Whenever a hive zombie bites with infection skills, a human will be infected, causing the condition to be dormant for a period of time and then once active deal continous damage --- code/item/weapon/class.lua | 35 ++------ code/item/weapon/list.lua | 19 +---- code/player/action/outcome.lua | 10 +++ code/player/condition/class.lua | 4 +- code/player/condition/infection.lua | 50 ++++++----- code/player/condition/poison.lua | 126 ---------------------------- code/player/skills/flags.lua | 6 +- code/player/skills/list.lua | 34 +++----- scenes/action.lua | 3 +- 9 files changed, 66 insertions(+), 221 deletions(-) delete mode 100644 code/player/condition/poison.lua diff --git a/code/item/weapon/class.lua b/code/item/weapon/class.lua index a0d2e25..6e6c1ef 100644 --- a/code/item/weapon/class.lua +++ b/code/item/weapon/class.lua @@ -24,7 +24,10 @@ function weapon:isSingleUse() return self.one_use or false end function weapon:hasConditionEffect(player) if self:getClassName() == 'claw' and not player.skills:check('grapple') then return false -- if attacking with claws and missing grapple skill then no condition effect + elseif self:getClassName() == 'bite' and not player.skills:check('infection') then + return false -- if attacking with bite and missing infection skill then no condition effect end + return (self.condition_effect and true) or false end @@ -96,7 +99,7 @@ local organic_modifier = { }, bite = { dice={'1d5+1', '1d5+2'}, - included_skills={'bite', 'power_bite'}, + included_skills={'bite', 'bite_adv'}, }, fist = { dice={'1d2'}, @@ -123,9 +126,9 @@ function weapon:getDice(player, condition) if skill_count > 0 then local dice_str = organic_modifier.dice[skill_count] weapon_dice = dice:new(dice_str) - end - end + end -- else organic weapon has no modifier or player lacks all included skills then use weapons default dice + end end local mastered_skill = self:getMasterSkill() @@ -139,18 +142,6 @@ function weapon:getDice(player, condition) return tostring(weapon_dice) end -local skill_effects = { - poison = { - order = {'venom_adv', 'venom', 'stinger'}, - stinger = {duration = '1d2+2', amount='1d5+10'}, - venom = {duration = '1d3+2', amount='1d7+15'}, - venom_adv = {duration = '1d4+3', amount='1d10+20'}, - }, - entangle = { - - } -} - function weapon:getConditionEffect(player) --, condition) maybe for later...? local effect = self.condition_effect local duration, bonus_effect @@ -159,21 +150,9 @@ function weapon:getConditionEffect(player) --, condition) maybe for later...? if effect == 'burn' then duration = weapon:getFuelAmount() bonus_effect = weapon:isCombustionSource() - elseif effect == 'decay' then - end elseif player:isMobType('zombie') then - if effect == 'poison' then - for _, skill in ipairs(skill_effects.poison.order) do - if player.skills:check(skill) then - duration = skill_effects.poison[skill].duration - bonus_effect = skill_effects.poison[skill].amount - break - end - end - elseif effect == 'infection' then - - elseif effect == 'entangle' then + if effect == 'entangle' then if player.skills:check('impale') then bonus_effect = true end -- possible to impale on crit hit end end diff --git a/code/item/weapon/list.lua b/code/item/weapon/list.lua index 8243ca1..2452d21 100644 --- a/code/item/weapon/list.lua +++ b/code/item/weapon/list.lua @@ -267,6 +267,7 @@ weapon.claw.critical = 0.05 weapon.claw.organic = 'zombie' weapon.claw.object_damage = {barricade=1, door=1, equipment=1} weapon.claw.condition_effect = 'entangle' +weapon.claw.master_skill = 'claw_adv' weapon.bite = {} weapon.bite.full_name = 'bite' @@ -277,22 +278,8 @@ weapon.bite.dice = '1d4+1' weapon.bite.accuracy = 0.20 weapon.bite.critical = 0.05 weapon.bite.organic = 'zombie' - ---[[ ---- PROJECTILE ---]] - -weapon.sting = {} -weapon.sting.full_name = 'sting' -weapon.sting.attack_style = 'ranged' -weapon.sting.damage_type = 'bullet' -weapon.sting.group = {'stinger'} -weapon.sting.dice = '1d2' -weapon.sting.accuracy = 0.15 -weapon.sting.critical = 0.05 -weapon.sting.organic = 'zombie' -weapon.sting.condition_effect = 'poison' -weapon.sting.skill_required = 'stinger' +weapon.bite.condition_effect = 'infection' +weapon.bite.master_skill = 'bite_adv' --[[ --- BURN diff --git a/code/player/action/outcome.lua b/code/player/action/outcome.lua index 1d6abf9..7a1ccd7 100644 --- a/code/player/action/outcome.lua +++ b/code/player/action/outcome.lua @@ -107,6 +107,16 @@ function Outcome.attack(player, target, weapon, inv_ID) if effect == 'entangle' then local impale_bonus = bonus_effect and critical entangle.add(player, target, impale_bonus) + elseif effect == 'infection' then + -- infection_adv skill makes bites auto infect, infection skill requires a zombie to be entagled with the target to infect with bite + if player.skills:check('infection_adv') or (player.skills:check('infection') and entangle.isTangledTogether(player, target)) then + if not target.condition.infection:isImmune() or target.condition.infection:isActive() then --target cannot be immune or infection already active + target.condition.infection:add() +--print('A zombie has infected the target') + -- should probably add an infection message to the ZOMBIE only! A human shouldn't be notfied immediately until damage is taken + -- also should probably look at refactoring the msg system for player.log to make this easier + end + end else -- normal effect process target.condition[effect]:add(duration, bonus_effect) end diff --git a/code/player/condition/class.lua b/code/player/condition/class.lua index 286d35d..aa889a1 100644 --- a/code/player/condition/class.lua +++ b/code/player/condition/class.lua @@ -1,5 +1,4 @@ local class = require('code.libs.middleclass') -local poison = require('code.player.condition.poison') local infection = require('code.player.condition.infection') local burn = require('code.player.condition.burn') local decay = require('code.player.condition.decay') @@ -14,7 +13,6 @@ local condition = class('condition') function condition:initialize(player) if player:isMobType('human') then -- insert status conditions? - self.poison = poison:new() self.infection = infection:new() elseif player:isMobType('zombie') then self.burn = burn:new() @@ -30,7 +28,7 @@ function condition:isActive(effect) end local condition_list = { - human = {'poison', 'infection'}, + human = {'infection'}, zombie = {'burn', 'decay'}, -- tracking:elapse() is used ONLY during server ticks, not during players actions } diff --git a/code/player/condition/infection.lua b/code/player/condition/infection.lua index 70eb1fe..eff0696 100644 --- a/code/player/condition/infection.lua +++ b/code/player/condition/infection.lua @@ -1,36 +1,44 @@ local class = require('code.libs.middleclass') +local dice = require('code.libs.dice') local infection = class('infection') -local MAX_TIME = 1023 +local MAX_TIME = 511 +local INCUBATION_DEFAULT = '1d1' --'1d80+20' +local INFECTION_DAMAGE_PER_TICK = -1 function infection:initialize() - self.time = 0 + self.incubation_timer = 0 + self.is_infected = false end -function infection:add(amount, player) - self.time = math.max(self.time + amount, 0) - if self.time >= MAX_TIME then - player:killed('infection') - end +function infection:add() +print('Player has just been infected!') + self.incubation_timer = dice.roll(INCUBATION_DEFAULT) + self.is_infected = true end -function infection:elapse(player, time) - self:add(time, player) +function infection:remove(player) +print('Player has been cured of infection!') + self.incubation_timer = 0 + self.is_infected = false end -function infection:getTime() return self.time end +function infection:addImmunity(time) self.incubation_timer = math.min(MAX_TIME, self.incubation_timer + time) end + +function infection:isActive() return self.is_infected end -return infection +function infection:isImmune() return (self.is_infected and self.incubation_timer > 0) end ---[[ -you have 0 infection = aka 21 days to live -you get attacked lose about 30 hp from bites -ie... make infection 1d2, 1d3, 1d4 from bites? +function infection:elapse(player, time) + if not self.is_infected then return end + + if self.incubation_timer > 0 then + self.incubation_timer = math.max(self.incubation_timer - time, 0) + else -- infection is no longer dormant + player:updateStat('hp', INFECTION_DAMAGE_PER_TICK) +print('Player takes damage for infection!') + end +end -21 days -knockoff @ 60 hp (ie. 59 damage) should remove 5/7 days? -7x50 = 350 -5x50 = 250 -3x50 = 150 ---]] \ No newline at end of file +return infection \ No newline at end of file diff --git a/code/player/condition/poison.lua b/code/player/condition/poison.lua deleted file mode 100644 index a909c59..0000000 --- a/code/player/condition/poison.lua +++ /dev/null @@ -1,126 +0,0 @@ -local class = require('code.libs.middleclass') -local dice = require('code.libs.dice') - -local poison = class('poison') - -local MAX_UNITS, MAX_DAMAGE_TICK = 63, 15 -local MAX_DURATION, MAX_DURATION_COUNT = 15, 15 ---poison = duration, damage_LV, frequency - -function poison:initialize() - self.units = 0 - self.next_damage_tick = 0 - self.duration_remaining = 0 - self.duration_count = 0 -end - ---[[ NOT NECCESSARY?!? -function poison:reset() - self.next_damage_tick = 0 - self.duration_count = 0 -end ---]] - -function poison:isActive() - return (self.units > 0 and self.duration_remaining > 0) -end - -function poison:add(duration, amount) - duration, amount = dice.roll(duration), dice.roll(amount) - self.units = math.min(self.units + amount, MAX_UNITS) - self.duration_remaining = duration -end - -local poison_data = { - dice = { - damage = {'1d3', '1d4', '2d2', '2d3', '2d4', '3d3', '3d4', '4d3', '4d4'}, - absorption = {'1d1', '1d1', '1d2', '1d2', '1d3', '1d4', '1d5+1', '1d7+3', '1d10+5'}, - }, - -- POISON LEVELS (determined by total units in bloodstream) - - [1] = 11, -- [01-11 units] (+11 range) - [2] = 21, -- [12-21 units] (+10 range) - [3] = 30, -- [21-30 units] (+9 range) - [4] = 38, -- [31-38 units] (+8 range) - [5] = 45, -- [39-45 units] (+7 range) - [6] = 51, -- [46-51 units] (+6 range) - [7] = 56, -- [52-56 units] (+5 range) - [8] = 60, -- [57-60 units] (+4 range) - [9] = 63, -- [60-63 units] (+3 range) - ---[[ - [1] = 3, -- [01-03 units] (+3 range) - [2] = 7, -- [04-07 units] (+4 range) - [3] = 12, -- [08-12 units] (+5 range) - [4] = 18, -- [13-18 units] (+6 range) - [5] = 25, -- [19-25 units] (+7 range) - [6] = 33, -- [26-33 units] (+8 range) - [7] = 42, -- [34-42 units] (+9 range) - [8] = 52, -- [43-52 units] (+10 range) - [9] = 63, -- [53-63 units] (+11 range) ---]] - -- POISON LEVELS -} - -function poison:damage() - for poison_LV, poison_amount in ipairs(poison_data) do - if self.units <= poison_amount then - local damage_roll = poison_data.dice.damage[poison_LV] - return dice.roll(damage_roll) - end - end -end - -function poison:rollDamageFrequency() - local frequency_roll = dice.roll('1d'..(self.duration_count+1)..'-1') - return frequency_roll -end - -function poison:absorbIntoBloodstream() - local absorption_roll - for poison_LV, poison_amount in ipairs(poison_data) do - if self.units <= poison_amount then - absorption_roll = dice.roll(poison_data.dice.absorption[poison_LV]) - break - end - end - self.units = math.max(self.units - absorption_roll, 0) -end - -function poison:elapse(player, time) - if not self:isActive() then - return - end - -print() -print('BEFORE', 'Poison units:'..self.units, 'Poison duration:'..self.duration_remaining) - while time > 0 do - if self.duration_remaining > 0 then - if self.next_damage_tick == 0 then -- time to take damage - local total_damage = self:damage() - local hp_loss = -1*total_damage - player:updateStat('hp', hp_loss) -print('You feel the poison in your veins', 'You lose '..hp_loss..'hp') - self.duration_count = self.duration_count + 1 - self.duration_remaining = self.duration_remaining - 1 - - if self.duration_remaining == 0 then self.duration_count = 0 -print('POISON DAMAGE FINISHED') - else self.next_damage_tick = self:rollDamageFrequency() - end - else - self.next_damage_tick = self.next_damage_tick - 1 - end - end - - if self.units > 0 then - self:absorbIntoBloodstream() - end - time = time - 1 -print('Next damage tick - '..self.next_damage_tick) -print('AFTER', 'Poison units:'..self.units, 'Poison duration:'..self.duration_remaining) -print() - end -end - -return poison \ No newline at end of file diff --git a/code/player/skills/flags.lua b/code/player/skills/flags.lua index 10fdfcc..7a68d02 100644 --- a/code/player/skills/flags.lua +++ b/code/player/skills/flags.lua @@ -120,10 +120,8 @@ local skill_flags = { acid_adv = 32, ruin = 64, ransack = 128, - homewrecker = 256, - stinger = 512, - venom = 1024, - venom_adv = 2048, + infection = 256, + infection_adv = 512, } return skill_flags \ No newline at end of file diff --git a/code/player/skills/list.lua b/code/player/skills/list.lua index adf401b..274c536 100644 --- a/code/player/skills/list.lua +++ b/code/player/skills/list.lua @@ -19,7 +19,7 @@ local skill_list = { general = {'muscle_stimulus', 'hand_stimulus', 'head_stimulus', 'grapple', 'groan', 'gesture', 'hp_bonus', 'ep_bonus', 'drag_prey', 'smell_blood'}, brute = {'claw', 'dual_claw', 'claw_adv', 'power_claw', 'impale', 'armor', 'liquid_armor', 'ranged_armor', 'pain_armor', 'dying_grasp',}, hunter = {'sprint', 'leap', 'leap_adv', 'track', 'scavenge', 'track_adv', 'dodge', 'smell_blood_adv', 'night_vision', 'mark_prey'}, - hive = {'hivemind', 'bite', 'bite_adv', 'corrode', 'acid', 'acid_adv', 'ruin', 'ransack', 'homewrecker', 'stinger', 'venom', 'venom_adv'}, + hive = {'hivemind', 'bite', 'bite_adv', 'corrode', 'acid', 'acid_adv', 'ruin', 'ransack', 'infection', 'infection_adv'}, }, human = { category = {'classes', 'general', 'military', 'research', 'engineering'}, @@ -221,23 +221,18 @@ local skill_list = { name='bite advanced', desc='Bite attacks receive a bonus reroll', icon='gluttonous-smile', - }, - stinger = { - name = 'stinger', - desc = 'Grants ability to attack with a poisonous stinger that injects venom into the bloodstream for a small duration', - icon = 'scorpion-tail', - }, - venom = { - name = 'venom', - desc = 'Increase the stingers to-hit 5%, higher dosage of venom injected and increased duration', + }, + infection = { + name = 'infection', + desc = 'A successful bite attacks while a human is grappled results in infection. Infection has a small incubation and then deals continous damage until it is cured or stalled with antibodies.', icon = 'drop', - requires={'stinger'}, + requires={'grapple'}, }, - venom_adv = { - name = 'venom advanced', - desc = 'Stinger attacks +10% to-hit, higher dosage of venom injected and increased duration', + infection_adv = { + name = 'infection advanced', + desc = 'All successful bite attacks result in infection.', icon = 'vile-fluid', - requires={'venom'}, + requires={'infection'}, }, acid = { name='acid', @@ -263,11 +258,6 @@ local skill_list = { name='ransack', desc='[Not Implemented] Ransack a building that is ruined', icon='grass', - }, - homewrecker = { - name='homewrecker', - desc='[Not Implemented] Attacks against building equipment deals double damage', - icon='cogsplosion', }, }, }, @@ -670,7 +660,9 @@ function skill_list.getFlag(skill) return skill_list[skill].flag end function skill_list.getMobType(skill) return skill_list[skill].mob_type end -function skill_list.getCategory(skill) return skill_list[skill].category end +function skill_list.getCategory(skill) +print('skill_list.getCategory(', skill, ')') + return skill_list[skill].category end function skill_list.isClass(skill) return skill_list[skill].category == 'classes' end diff --git a/scenes/action.lua b/scenes/action.lua index 5023f14..a6cc00a 100644 --- a/scenes/action.lua +++ b/scenes/action.lua @@ -364,8 +364,7 @@ function scene:create( event ) local stat_text if main_player:isMobType('human') then local ip, max_ip = main_player:getStat('ip'), main_player:getStat('ip', 'max') - local infection, max_infection = main_player.condition.infection:getTime(), 1023 - stat_text = display.newText('IP ['..ip..'/'..max_ip..'] INFECT ['..infection..'/'..max_infection..']', stat_bar_w+offset, stat_bar_h*0.5 + thickness, native.systemFontBold, 10 ) + stat_text = display.newText('IP ['..ip..'/'..max_ip..']', stat_bar_w+offset, stat_bar_h*0.5 + thickness, native.systemFontBold, 10 ) elseif main_player:isMobType('zombie') then local ep, max_ep = main_player:getStat('ep'), main_player:getStat('ep', 'max') local decay, max_decay = main_player.condition.decay:getTime(), 1023