Rat Lich mod based on irc idea :P

A place to post your add ons and ideas for them

Moderator: Moderator

Message
Author
Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Rat Lich mod based on irc idea :P

#1 Post by Hellcommander »

requires rat lich achievement "EVENT_RATLICH"
str 0
dex 2
con -2
cun 2
mag 5
will 2
exp pen:25
life per level 10

uses its own damage type for dark feed that is some was similar to the darkstun that rat lich boss has (dark feed's damage type leeches the damage as life, deals 90% darkness damage 10% physical damage, gains a 10% damage bonus if target is already stunned before the damage is inflicted, and is able to inflict a 4 turn stun like darkstun does)

rat lich talents:
cun/mag (max of 10 to each) raw talent talent 1, talent 2 25 turn cooldown melee based rush heal that does new dark feed damage type scaling with spellpower (I'll add mind power scaling later if its higher then spellpower) talent 3 passive slight magic power bonus increase hand to hand based on % of magic power and movement infusion like talent with a long cooldown for moments when you need to move fast (like race through fire quest and when you need to flee), talent 4 summon undead rats base cooldown of 70? drop to 35 at rank 5 summon 2 - 5 undead rats (more undead rodent types if you have rat lich skull equipped or in inventory?)

resurrect once as per skeleton talent with limited duration buff and shadow summons to emulate the rat lich boss for a small bit (way to OP to grant them all the time)


have undead bonuses that match rat lich
type:undead/rodent


have rat lich put armor on by imbueing it into its chest (for chest armor). claws (for gloves), hind legs (boots), cloak slot (held with a colar of sorts?), 1 weapon on tail thats has restricted weapon types?
25%? chance on melee to use claws to attack

lore:
The foolish necromancer imbued a lost spirit into the flesh of a dead giant rat that was expermented on with magic (thus explaining how the ratlich can equip armor).
Last edited by Hellcommander on Fri Mar 24, 2017 10:31 am, edited 6 times in total.

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#2 Post by Hellcommander »

heres current version of the birth.lua:

Code: Select all

local ActorInventory = require "engine.interface.ActorInventory"
local ActorTalents = require "engine.interface.ActorTalents"
newBirthDescriptor
{
	type = "subrace",
	name = "Ratlich",
	desc = {
		"A foolish necromancer imbued the power of a lost spirit into the flesh of a dead giant rat that was expermented on with magic (thus explaining how the ratlich can equip armor).",
		"Rat liches make powerful mages and decent spellblades", 
		"- cut, blind, fear, and poison immunity (same as ratlich boss)",
		"- no need to breathe",
		"#GOLD#Stat modifiers:",
		"#LIGHT_BLUE# * +0 Strength",
		"#LIGHT_BLUE# * +2 Dexturity",
		"#LIGHT_BLUE# * -2 Constitution",
		"#LIGHT_BLUE# * +5 Magic",
		"#LIGHT_BLUE# * +2 Willpower", 
		"#GOLD#Life per level:#LIGHT_BLUE# 10",
		"#GOLD#Damage resistances:#LIGHT_BLUE# Ratlich's gain slight bonuses to stealth for increasing their rat lich's cunning ability",
		"#GOLD#Damage resistances:#LIGHT_BLUE# Ratliches can only hold one weapon with their tail but have a 25% chance on melee hit to to do hand to hand damage",
		"#GOLD#Experience penalty:#LIGHT_BLUE# 25%",
	},
--	moddable_attachement_spots = "race_ratlich", moddable_attachement_spots_sexless=true,
	descriptor_choices =
	{
		sex =
		{
			__ALL__ = "disallow",
			Male = "allow",
		},
	},
	
	inc_stats = { dex=5, con=-2, mag=5, wil=2 },
	talents_types = {
		["undead/ratlich"]={true, 0.1},
	},
	talents = {
		[ActorTalents.T_RAT_LICH_CUNNING]=1,
		[ActorTalents.T_RAT_LICH_RACE_EQUIP_TAIL_WEAPON]=1,
	},
	copy = {
		type = "undead", subtype="rodent",
		default_wilderness = {"playerpop", "low-undead"},
		starting_intro = "ratlichintro",
		random_name_def = "thalore_#sex#", random_name_max_syllables = 7,
		life_rating=10,
		cut_immune = 1,
		blind_immune = 1,
		fear_immune = 1,
		undead=1,
		instakill_immune = 1,
		poison_immune = 1,
		no_breath = 1,
		size_category = 1,
		forbid_nature = 1,
		equipdoll = "rat_lich",
		blood_color = colors.black,
	    not_power_source = {nature=true, technique_ranged=true},
		moddable_tile = "rat_lich",
		moddable_tile_base = "playable_undead_rodent_rat_lich.png",
		moddable_tile_nude = 1,
		},
	copy_add = {
      unused_generics = 1,
   },
	body = {FINGER = 2, TAIL_WEAPON=1, LITE=1,HEAD=1,NECK=1,TOOL=1, FEET=1,BODY=1,QUIVER=1,BELT=1,HANDS=1,CLOAK=1},
	experience = 1.25,
		random_escort_possibilities = { {"tier1.1", 1, 2}, {"tier1.2", 1, 2}, {"daikara", 1, 2}, {"old-forest", 1, 4}, {"dreadfell", 1, 8}, {"reknor", 1, 2}, },
}

ActorInventory.equipdolls["rat_lich"] = { w=48, h=48, itemframe="ui/equipdoll/itemframe48.png", itemframe_sel="ui/equipdoll/itemframe-sel48.png", ix=3, iy=3, iw=42, ih=42, doll_x=116, doll_y=168+64, list={
	PSIONIC_FOCUS = {{weight=1, x=48, y=48}},
	TAIL_WEAPON = {{weight=16, x=156, y=120, text="bottom"}},
	BODY = {{weight=4, x=48, y=264}},
	QUIVER = {{weight=5, x=48, y=336}},
	FINGER = {{weight=6, x=48, y=408}, {weight=7, x=120, y=408, text="bottom"}},
	LITE = {{weight=8, x=192, y=408}},
	TOOL = {{weight=9, x=264, y=408, text="bottom"}},
	FEET = {{weight=10, x=264, y=336}},
	BELT = {{weight=11, x=264, y=264}},
	HANDS = {{weight=12, x=264, y=192}},
	CLOAK = {{weight=13, x=264, y=120}},
	NECK = {{weight=14, x=192, y=48, text="topright"}},
	HEAD = {{weight=15, x=120, y=48, text="topleft"}},
}}
getBirthDescriptor("race", "Undead").descriptor_choices.subrace.ratlich = "allow"

Last edited by Hellcommander on Sun Apr 09, 2017 4:26 am, edited 10 times in total.

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#3 Post by Hellcommander »

here is the ratlich_talents.lua

Code: Select all

-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2015 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
local Stats = require "engine.interface.ActorStats"
local ActorTalents = require "engine.interface.ActorTalents"

local Object = require "engine.Object"
--load("/data/general/npcs/rat_lich_minions.lua")

undeads_req1 = {
	level = function(level) return 0 + (level-1)  end,
}
undeads_req2 = {
	level = function(level) return 4 + (level-1)  end,
}
undeads_req3 = {
	level = function(level) return 8 + (level-1)  end,
}
undeads_req4 = {
	level = function(level) return 12 + (level-1)  end,
}

newTalentType{ type="undead/ratlich", name = "Rat Lich", generic = true, description = "Rat Lich's innate abilities."}
newTalentType{ type="undead/ratlich-misc", name = "ratlich-misc-skills", generic = true, description = "Misc talents that the Rat Lich can use" }



function applyEmpathy_Call_of_the_Rat_Lich(self, m)
	if self:knowTalent(self.T_CALL_OF_THE_RAT_LICH) then
		local t = self:getTalentFromId(self.T_CALL_OF_THE_RAT_LICH)
		local perc = t.getPerc(self, t)
		for k, e in pairs(self.resists) do
			m.resists[k] = (m.resists[k] or 0) + e * perc / 100
		end
--		for k, e in pairs(self.resists_cap) do
--			m.resists_cap[k] = e
--		end
		m.combat_physresist = m.combat_physresist + self:combatPhysicalResist() * perc / 100
		m.combat_spellresist = m.combat_spellresist + self:combatSpellResist() * perc / 100
		m.combat_mentalresist = m.combat_mentalresist + self:combatMentalResist() * perc / 100

		m.poison_immune = (m.poison_immune or 0) + (self:attr("poison_immune") or 0) * perc / 100
		m.disease_immune = (m.disease_immune or 0) + (self:attr("disease_immune") or 0) * perc / 100
		m.cut_immune = (m.cut_immune or 0) + (self:attr("cut_immune") or 0) * perc / 100
		m.confusion_immune = (m.confusion_immune or 0) + (self:attr("confusion_immune") or 0) * perc / 100
		m.blind_immune = (m.blind_immune or 0) + (self:attr("blind_immune") or 0) * perc / 100
		m.silence_immune = (m.silence_immune or 0) + (self:attr("silence_immune") or 0) * perc / 100
		m.disarm_immune = (m.disarm_immune or 0) + (self:attr("disarm_immune") or 0) * perc / 100
		m.pin_immune = (m.pin_immune or 0) + (self:attr("pin_immune") or 0) * perc / 100
		m.stun_immune = (m.stun_immune or 0) + (self:attr("stun_immune") or 0) * perc / 100
		m.fear_immune = (m.fear_immune or 0) + (self:attr("fear_immune") or 0) * perc / 100
		m.knockback_immune = (m.knockback_immune or 0) + (self:attr("knockback_immune") or 0) * perc / 100
		m.stone_immune = (m.stone_immune or 0) + (self:attr("stone_immune") or 0) * perc / 100
		m.teleport_immune = (m.teleport_immune or 0) + (self:attr("teleport_immune") or 0) * perc / 100

		m.necrotic_minion_be_nice = 1
	end
end

local rat_lich_minions_list = {
ratlich_skeletal_rat = {
	base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
	name = "skeletal rat", color=colors.WHITE, image="npc/undead_rodent_skeletal_rat.png",
	desc = [[A skeletal rat, teeth and claws ground to a sharp point. It glares at you menacingly.]],
	level_range = {5, nil}, exp_worth = 0,
	rarity = 1,
	max_life = resolvers.rngavg(25,45),
	combat_armor = 12, combat_def = 0,

	cut_immune = 1,
	blind_immune = 1,
	fear_immune = 1,
	poison_immune = 1,

	combat = { dam=resolvers.levelup(resolvers.rngavg(20,30), 1, 0.6), atk=resolvers.rngavg(25,50), apr=20, dammod={str=1.1} },
	resolvers.tmasteries{ ["undead/skeleton"]=-0.5},

	resolvers.talents{
		[Talents.T_SKELETON_REASSEMBLE]={base=1, every=5, max=4},
	},

	emote_random = {chance=1, "*squeak*", "Squeak!", "Squeak??", "SQUEAK!!!!!"},
},

ratlich_ghoulish_rat = {
	base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
	name = "ghoulish rat", color=colors.TAN, image="npc/undead_rodent_ghoulish_rat.png", 
	desc = [[Layers of rotting skin are peeling off of this rat. One of the eye sockets appears empty.]],
	level_range = {6, nil}, exp_worth = 0,
	rarity = 1,
	max_life = resolvers.rngavg(34,56),
	combat_armor = 4, combat_def = 10,
	life_rating = 10,

	autolevel="ghoul",

	combat = { dam=resolvers.levelup(resolvers.rngavg(16,24), 1, 0.6), atk=resolvers.rngavg(25,50), apr=25, dammod={str=1} },

	poison_immune = 0.5,
	disease_immune = 0.5,

	resists = {[DamageType.BLIGHT] = 15},

	resolvers.talents{
		[Talents.T_ROTTING_DISEASE]={base=1, every=7, max=4},
		[Talents.T_GHOULISH_LEAP]={base=2, every=8, max=4},
	},
	emote_random = {chance=1, "*s.q.u.e.a.k*", "Squeeeeeeak!", "Squeakkkkkkk??"},
},

ratlich_spectral_rat = {
	base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
	name = "spectral rat", color=colors.GREY, image="npc/undead_rodent_spectral_rat.png", 
	desc = [[An eerie haze surrounds this translucent rat.]],
	level_range = {9, nil}, exp_worth = 0,
	rarity = 3,
	rank = 2,
	max_life = resolvers.rngavg(18,25),
	combat_armor = 0, combat_def = 15,

	combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,50), apr=25, dammod={str=1} },

	can_pass = {pass_wall=70},
	resists = {all = 20, [DamageType.LIGHT] = -40, [DamageType.DARKNESS] = 45},

	no_breath = 1,
	stone_immune = 1,
	confusion_immune = 1,
	fear_immune = 1,
	teleport_immune = 0.5,
	disease_immune = 1,
	poison_immune = 1,
	stun_immune = 1,
	blind_immune = 1,
	cut_immune = 1,
	see_invisible = 80,

	resolvers.talents{
		[Talents.T_PHASE_DOOR]={base=1, every=6, max=4},
		[Talents.T_BLUR_SIGHT]={base=3, every=6, max=6},
	},

	resolvers.sustains_at_birth(),

	emote_random = {chance=1, "Eerie Squeak!", "Frightening Squeak??", "SQUEAK!!!!!"},
},

-- these will later require rat liches skull equipped to appear
ratlich_vampire_rat = {
	base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
	name = "vampire rat", color=colors.WHITE, image="npc/undead_rodent_vampire_rat.png",
	desc = [[Looks much like a normal rat. That is, other than the very large fangs.]],
	level_range = {8, nil}, exp_worth = 0,
	rarity = 2,
	max_life = resolvers.rngavg(45,60),
	life_rating=11,
	combat_armor = 8, combat_def = 18,
	autolevel = "random_boss",
	fear_immune = 1,

	combat = { dam=resolvers.levelup(resolvers.rngavg(25,35), 1, 0.6), atk=resolvers.rngavg(25,50), apr=22, dammod={str=1.1} },

	resolvers.talents{
		[Talents.T_VAMPIRIC_GIFT]={base=1, every=5, max=4},
		[Talents.T_INVOKE_DARKNESS]={base=1, every=8, max=5},
		[Talents.T_COLD_FLAMES]={base=1, every=9, max=5},
	},

	emote_random = {chance=1, "Squeak! Blood!", "Squeak??", "SQUEAK!!!!!"},
},

ratlich_gigantic_bone_rat = {
	base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD", -- only if have ratlich skull equipped/later on swap bone giant for version of this if your a necromancer and rat lich :P
	name = "gigantic bone rat", color=colors.LIGHTGREY,
	desc = [[This massive beast appears to be a rat composed of countless bones fused together.]],
	resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_rodent_gigantic_bone_rat.png", display_h=2, display_y=-1}}},
	level_range = {14, nil}, exp_worth = 0,
	rarity = 6,
	max_life = resolvers.rngavg(60,80),
	life_rating=14,
	combat_armor = 25, combat_def = 10,

	rank = 3,
	size_category = 3,

	cut_immune = 1,
	blind_immune = 1,
	fear_immune = 1,
	poison_immune = 1,

	stats = { str=20, dex=15, mag=10, con=8 },

	combat = { dam=resolvers.levelup(resolvers.rngavg(48,56), 1, 0.6), atk=resolvers.rngavg(32,60), apr=24, dammod={str=1.2} },
	resolvers.tmasteries{ ["undead/skeleton"]=-0.2},

	resolvers.talents{
		[Talents.T_SKELETON_REASSEMBLE]={base=2, every=7, max=4},
		[Talents.T_BONE_ARMOUR]={base=1, every=10, max=4},
		[Talents.T_STUN]={base=1, every=9, max=6},
		[Talents.T_KNOCKBACK]={base=1, every=7, max=4},
	},

	emote_random = {chance=1, "*SQUEAK*", "SQUEAK!!!!!"},
	},
}

local rat_lich_minion_order = {"ratlich_skeletal_rat", "ratlich_ghoulish_rat", "ratlich_spectral_rat", "ratlich_vampire_rat", "ratlich_gigantic_bone_rat"} -- Sets listing order 

-- Parameters are b, n, m, p where weight = b + n*tl + m*tl^p
local rat_lich_minionWeightParams = {
	ratlich_skeletal_rat={7.000,	0.200,	3.000,	1.200},
	ratlich_ghoulish_rat={2.000,	0.500,	3.000,	1.500},
	ratlich_spectral_rat={1.471,	0.500,	3.529,	1.000},
}

local Adv_rat_lich_minionWeightParams = {
	ratlich_vampire_rat={2.690,	3.139,	-0.448,	2.000},
	ratlich_gigantic_bone_rat={-1.076,	0.100,	1.076,	1.000},
}

-- tl = talent level, or {createrat_lich_minionsTL, rat_lich_minionmasteryTL}
-- wtable = weight table or table of weight tables
local function rat_lich_minionWeights(tl,wtable)
	local tl = tl
	if type(tl) == "number" then tl = {tl} end
	local tables = #wtable > 0 and #wtable or 1
	local chances, sum = {}, 0
	
	for i = 1, tables do
		for utype, params in pairs(tables > 1 and wtable[i] or wtable) do
			chances[utype] = math.max(0,params[1] + params[2]*tl[i] + params[3]*tl[i]^params[4])
			sum = sum + chances[utype]
		end
	end
	return chances, sum
end

local function rat_lich_getMinionChances(self)
	local chances, sum
	local tlcm, tlmm = self:getTalentLevel(self.T_CALL_OF_THE_RAT_LICH)
	if tlmm > 0 then
		chances, sum = rat_lich_minionWeight({math.max(tlcm,tlmm), tlmm},{rat_lich_minionWeightParams, Adv_rat_lich_minionWeightParams}) -- Balance talent levels to avoid too many powerful rat_lich_minions
	else
		chances, sum = rat_lich_minionWeight(tlcm,rat_lich_minionWeightParams)
	end
	for i,k in pairs(chances) do
		chances[i] = k*100/sum
	end
	return chances
end

local function rat_lich_makeMinion(self, lev)
	local rat_lich_chances = rat_lich_getMinionChances(self)
	local pick = rng.float(0,100)
	local tot, m = 0
	for k, e in pairs(chances) do
		tot = tot + e
		if tot > pick then m = k break end
	end
	m = require("mod.class.NPC").new(rat_lich_minions_list[m])
	m.necrotic_minion = true
	return m
end

function rat_lich_SetupSummon(self, m, x, y, level, no_control, no_decay)
	m.faction = self.faction
	m.summoner = self
	m.summoner_gain_exp = true
	m.necrotic_minion = true
	m.exp_worth = 0
	m.life_regen = m.life_regen + 0.2
--	m.move_others= true,
--	m.never_anger = true,
--	remove_from_party_on_death = true,
--	m.unused_stats = 0
--	m.unused_talents = 0
--	m.unused_generics = 0
--	m.unused_talents_types = 0
	m.silent_levelup = true
--	m.no_points_on_levelup = true
	m.save_hotkeys = true
	m.ai_state = m.ai_state or {}
	m.ai_state.tactic_leash = 13
	local main_weapon = self:getInven("TAIL_WEAPON") and self:getInven("TAIL_WEAPON")[1]
	-- Try to use stored AI talents to preserve tweaking over multiple summons
	m.ai_talents = self.stored_ai_talents and self.stored_ai_talents[m.name] or {}
	m.inc_damage = table.clone(self.inc_damage, true)
	m.resists_pen = table.clone(self.resists_pen, true)
	m.no_breath = 1
	m.no_drops = true
	local t = self:getTalentFromId(self.T_CALL_OF_THE_RAT_LICH)
	CallofRatLichLevel=self:getTalentLevel(t)
	summon_time = t.getSummonTime(self, t),
--	max_summon_time = math.ceil(self:t*10),
	applyEmpathy_Call_of_the_Rat_Lich(self, m)

	if game.party:hasMember(self) then
		local can_control = not no_control

		m.remove_from_party_on_death = true
		game.party:addMember(m, {
			control=can_control and "full" or "no",
			type="minion",
			title="Necrotic Minion",
			orders = {target=true, leash=true, anchor=true, talents=true},
			on_control = function(self)
				local summoner = self.summoner
				self:setEffect(self.EFF_SUMMON_CONTROL, 1000, {incdur=summoner:callTalent(summoner.T_SUMMON_CONTROL, "lifetime"), res=summoner:callTalent(summoner.T_SUMMON_CONTROL, "DamReduc")})
				self:hotkeyAutoTalents()
			end,
			on_uncontrol = function(self)
				self:removeEffect(self.EFF_SUMMON_CONTROL)
			end,
		})
	end
	m:resolve() m:resolve(nil, true)
	m.max_level = self.level + (level or 0)
	m:forceLevelup(math.max(1, self.level + (level or 0)))
	game.zone:addEntity(game.level, m, "actor", x, y)
	game.level.map:particleEmitter(x, y, 1, "summon")


	-- Summons never flee
	m.ai_tactic = m.ai_tactic or {}
	m.ai_tactic.escape = 0

	if self:knowTalent(self.T_BLIGHTED_SUMMONING) then m:incIncStat("mag", self:getMag()) m:incVim(m:getMaxVim()) end

	self:attr("summoned_times", 1)
end




newTalent{
	short_name = "ratlich_race_equip_tail_weapon",
	name = "Equip Tail Weapon",
	type = {"undead/ratlich-misc", 1},
	points = 1,
	cooldown = 1,
	type_no_req = true,
	no_unlearn_last = true,
	no_npc_use = true,
	
	action = function(self, t)
		local inven = self:getInven("INVEN")
		local d d = self:showInventory("Hold which weapon (does not work with all types)?", inven,
									   function(o) --weapon types to allow
										   return (o.subtype == "trident") or (o.subtype == "mace") or (o.subtype == "shield") or (o.subtype == "staff") or (o.subtype == "mindstar") or (o.subtype == "whip") or (o.subtype == "dagger") or (o.subtype == "longsword") or (o.subtype == "short staff") or (o.subtype == "steamsaw") or (o.subtype == "steamgun")
									   end,
									   function(o, item)
										   local slot = self:getInven("TAIL_WEAPON")
										   if not slot then return end
										   -- Put back the old one in inventory
										   local old = self:removeObject(slot, 1, true)
										   if old then
											   self:addObject(inven, old)
										   end

										   -- Fix the slot_forbid bug
										   if o.slot_forbid then
											   -- Store any original on_takeoff function
											   if o.on_takeoff then
												   o._old_on_takeoff = o.on_takeoff
											   end
											   -- Save the original slot_forbid
											   o._slot_forbid = o.slot_forbid
											   o.slot_forbid = nil
											   -- And prepare the resoration of everything
											   o.on_takeoff = function(self)
												   -- Remove the slot forbid fix
												   self.slot_forbid = self._slot_forbid
												   self._slot_forbid = nil
												   -- Run the original on_takeoff
												   if self._old_on_takeoff then
													   self.on_takeoff = self._old_on_takeoff
													   self._old_on_takeoff = nil
													   self:on_takeoff()
													   -- Or remove on_takeoff entirely
												   else
													   self.on_takeoff = nil
												   end
											   end
										   end

										   self.shader = nil

										   o = self:removeObject(inven, item)
										   -- Force "wield"
										   self:addObject(slot, o)
										   game.logSeen(self, "%s uses its innate magics to bind a weapon to its tail: %s.", self.name:capitalize(), o:getName{do_color=true})

										   self:sortInven()
										   d.used_talent = true
		end)
		local co = coroutine.running()
		d.unload = function(self) coroutine.resume(co, self.used_talent) end
		if not coroutine.yield() then return nil end
		return true
	end,

	info = function(self, t)
		return ([[Carry a weapon on your tail]])
	end,
}

newTalent{
	short_name = 'ratlich_cunning',
	name = "Rat Lich's Cunning",
	type = {"undead/ratlich", 1},
	mode = "sustained",
	require = undeads_req1,
	points = 5,
	cooldown = 6,
	tactical = { BUFF = 4 },
	statBonus = function(self, t) return math.ceil(self:combatTalentScale(t, 2, 10, 0.75)) end,
	getStealth = function(self, t) return self:combatTalentScale(t, 2, 14, 0.75) end,
--	passives = function(self, t, p)  end,
	on_learn = function(self, t)
		self:talentTemporaryValue(p, "inc_stats", {[self.STAT_STR]=t.statBonus(self, t)})
		self:talentTemporaryValue(p, "inc_stats", {[self.STAT_DEX]=t.statBonus(self, t)})
	--	self:attr("unharmed_attack_on_hit", 1) --have its own form of this that scale different and only has 30% chance to do as a additional attack on hit (passive hand to hand chance to does damage calculation based on spell power dex and mag? melee attack with claws with bonus damage based on spellpower)
	--	self:attr("show_gloves_combat", 1) --give this after i have new attr for ratlich
	end,
	on_unlearn = function(self, t)
		self:talentTemporaryValue(p, "inc_stats", {[self.STAT_STR]=t.statBonus(self, t)})
		self:talentTemporaryValue(p, "inc_stats", {[self.STAT_DEX]=t.statBonus(self, t)})
	--	self:attr("unharmed_attack_on_hit", 1) --have its own form of this that scale different and only has 30% chance to do as a additional attack on hit (passive hand to hand chance to does damage calculation based on spell power dex and mag? melee attack with claws with bonus damage based on spellpower)
	--	self:attr("show_gloves_combat", 1) --give this after i have new attr for ratlich
	end,
	
	activate = function(self, t)	
			local ret = {}
		self:talentTemporaryValue(ret, "inc_stealth", t.getStealth(self, t))
		return ret
	end,
	deactivate = function(self, t, p)
		return true
	end,
	info = function(self, t)
		return ([[Your cunning and magic increases with the mastery of %d.
		Talent can be sustained to grant some stealth
]]):
---		Having 1 point in this skill grants a chance to do a unarmed attack with your claws. Still need a way to do hand to hand combat while using weapon and scaling it with spellpower or mindpower instead
		format(t.statBonus(self, t), t.getStealth(self, t))
	end
}

newTalent{
	short_name = 'ratlich_dark_feed',
	name = "Rat Lich's Dark Feed", --uses nul's Searing Ire as a template for this skill
	type = {"undead/ratlich", 2},
	speed = "spell",
	random_ego = "attack",
	require = undeads_req2,
	tactical = { ATTACK = 2, HEAL = 1, CLOSEIN = 3},
	points = 5,
	requires_target = true,
	cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 19, 25, 23)) end, --Limit to >19
	range = function(self, t) return math.min(10, self:combatTalentScale(t, 7, 9)) end,
	target = function(self, t) return {type="bolt", range=self:getTalentRange(t), nolock=true, nowarning=true, requires_knowledge=false, stop__block=true} end,	
	getClawDamage = function(self, t)
	 return self:combatTalentWeaponDamage(t, 0.4, 1.2) --change this to use you gloves attack and damage later
      end,
	 getDarkFeedBite = function(self, t)
	 return self:combatTalentSpellDamage(t, 20, 120)  --maybe add stat mods to this later ---add mindpower scaling later if its higher
     end,
     
	action = function(self, t)
	
	if self:attr("never_move") and core.fov.distance(self.x, self.y, tx, ty) > 0 then return nil end

     
	 local tg = {type="hit", range=self:getTalentRange(t)}
	 local x, y, target = self:getTarget(tg)
	 if not x or not y or not target then return nil end
	 if core.fov.distance(self.x, self.y, x, y) > self:getTalentRange(t) then return nil end

	 local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, Map.TERRAIN, "block_move", self) end
	 local l = self:lineFOV(x, y, block_actor)
	 local tx, ty = lx, ly
	 while lx and ly do
	    if game.level.map:checkAllEntities(lx, ly, "block_move", self) then break end
	    tx, ty = lx, ly
	 end

	 if not (x and y and tx and ty) then return nil end
	 if core.fov.distance(x, y, tx, ty) > 2 then return nil end

	 local ox, oy = self.x, self.y
	 self:move(tx, ty, true)
	 if config.settings.tome.smooth_move > 0 then
	    self:resetMoveAnim()
	    self:setMoveAnim(ox, oy, 8, 5)
	 end

	 -- Attack ?
	 if core.fov.distance(self.x, self.y, x, y) == 1 then
--	    self:attackTarget(target, nil, t.getClawDamage(self,t)) ---change to forced hand to hand attack later weapon damage unneeded

	    local dam = self:spellCrit( t.getDarkFeedBite(self, t) )
	    local tg2 = {type="bolt", range=1, selffire=false, radius=0, talent=t}
	    local grids = self:project(tg2, x, y, 
				       function(tx, ty)
					  local target = game.level.map(tx, ty, Map.ACTOR)
					  if (not target) then return end -- removed friendly fire avoid so you can turn on your allies if not careful or need a heal bad enough
					  DamageType:get(DamageType.HELLCOM_RATLICHDARKFEED).projector(self, tx, ty, DamageType.HELLCOM_RATLICHDARKFEED, dam)
					  target = game.level.map(tx, ty, Map.ACTOR)
				       end)
--	    game.level.map:particleEmitter(x, y, tg2.radius, "dark_torrent", {radius=tg2.0, grids=grids, tx=x, ty=y, max_alpha=80})
	    game:playSoundNear(self, "creatures/rats/rat_attack")
	 end

	 return true
      end,

      info = function(self, t)
	 local range = self:getTalentRange(t)
	 local wdam = t.getDamage(self, t) * 100
	 local adam = t.getDarkFeedBite(self, t)
	 return ([[Channel your dark magics that power you form to hurl yourself %d spaces to an enemy, then attack for %d%% unarmed damage. Hit or miss you will attack with a bite infused with you dark magic (90% darkness, 10% physical) for %d%% that will heal you for the amount of damage dealt.
  The damage will increase with your Spellpower.]]
	 ):format(range, wdam, rad, damDesc(self, DamageType.HELLCOM_RATLICHDARKFEED, adam))
      end,
   }

newTalent{
	short_name = 'rat_lich_tactical_retreat',
	name = "Rat Lich's Tactical Retreat", --uses a tweaked lightning speed effect atm --might make it have a small cover of darkness as you move later to make it harder to see your real position
	type = {"undead/ratlich", 3},
	require = undeads_req3,
	points = 5,
	cooldown = 40,
	range = 10,
	tactical = { ESCAPE = 3, CLOSEIN = 1 },
	requires_target = true,
	no_energy = true,
	getPassiveSpeed = function(self, t) return self:combatTalentScale(t, 0.08, 0.4, 0.5) end, 
	getSpeed = function(self, t) return self:combatTalentScale(t, 500, 800, 0.75) end,--reduce the bonus but allow it to scale?
	getDuration = function(self, t) return math.ceil(self:combatTalentScale(t, 1, 2)) end,
	passives = function(self, t, p)
		self:talentTemporaryValue(p, "movement_speed", t.getPassiveSpeed(self, t))
	end,
	on_pre_use = function(self, t) return not self:attr("never_move") end,
	action = function(self, t)
		self:setEffect(self.EFF_RATLICH_SPEED, self:spellCrit(t.getDuration(self, t)), {power=t.getSpeed(self, t)})
		return true
	end,
	info = function(self, t)
	return ([[For a  %d%% turns you focus your innate dark magics to improve your movement speed by %d%% to close the gap or flee from danger. 
			Each point in this skill will raise your Movement Speed by %d%%, passively
			While this effect you a granted 100% darkness resistance.
			Any any action other then moving will remove the effect).]]):format(t.getSpeed(self, t), t.getDuration(self, t), t.getPassiveSpeed(self, t)*100)
	end,
}


newTalent{
	short_name = 'call_of_the_rat_lich',
	name = "Call of the Rat Lich",
	type = {"undead/ratlich", 4},
	tactical = { DEFEND = 3 },
	require = undeads_req4,
	requires_target = true,
	range = 0,
	radius = 5,
	no_energy = true,
	points = 5,
	cooldown = 50,
	summonTime = function(self, t) return math.floor(self:combatScale(self:getTalentLevel(t), 30, 0, 45, 5)) end,
--	local nb = t.getMax(self, t)
--	local lev = t.getLevel(self, t)
	target = function(self, t)
		return {type="cone", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t}
	end,
		getRatLichMax = function(self, t)
		local max = math.max(1, math.floor(self:combatTalentScale(t, 2, 6, "log")))
	if necroEssenceDead(self, true) then max = max + 2 end
		return max - necroGetNbSummon(self)
	end, -- talent level 1-5 gives 1-5
	getLevel = function(self, t) return math.floor(self:combatScale(self:getTalentLevel(t), -2, 0.9, 1, 2)) end,
	rat_lich_minionChancesDesc = function(self)
		local c = rat_lich_getMinionChances(self)
		local rat_lich_chancelist = tstring({})
		for i, k in ipairs(rat_lich_minion_order) do
			 if c[k] then rat_lich_chancelist:add(true,rat_lich_minions_list[k].name:capitalize(),(": %d%%"):format(c[k])) end
		end
		return rat_lich_chancelist:toString()
	end,

	action = function(self, t)
		local nb = t.getMax(self, t)
		local lev = t.getLevel(self, t)

		-- Summon minions in a cone
		local tg = self:getTalentTarget(t)
		local x, y = self:getTarget(tg)
		if not x or not y then return nil end
		local possible_spots = {}
		self:project(tg, x, y, function(px, py)
			if not game.level.map:checkAllEntities(px, py, "block_move") then
				possible_spots[#possible_spots+1] = {x=px, y=py}
			end
		end)
		for i = 1, nb do
			local rat_lich_minion = rat_lich_makeMinion(self, self:getTalentLevel(t))
			local pos = rng.tableRemove(possible_spots)
			if rat_lich_minion and pos then
				rat_lich_necroSetupSummon(self, rat_lich_minion, pos.x, pos.y, lev, true)
			end
		end

		local empower = necroEssenceDead(self)
		if empower then empower() end
		game:playSoundNear(self, "talents/spell_generic2")
		--game.logSeen(who, "%s raises %s %s, and a red light flashes from it's eye sockets!", who.name:capitalize(), who:his_her(), self:getName({do_color=true, no_add_name=true})),
		return true
	end,
	
info = function(self, t)

--		 return ([[You use your innate dark magics to call (up to %d rat_lich_minions) undead rats (The rat_lich_minions level is your level %+d.) that live for %D% turns. Chance for each minion type changes with talent level. (if you possess skull of the rat lich it has a chance to spawn special undead rodent types (not restricted yet).]]:format --(t.summonTime(self, t)) --nb, lev,  --t.rat_lich_minionChancesDesc(self, t))
	end,
}
---ideas for new rat lich themed undead
---undead plague rat
---undead gloom rat
---undead mage ratman?
--undead steam ratman?
Last edited by Hellcommander on Sun Apr 09, 2017 4:25 am, edited 10 times in total.

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#4 Post by Hellcommander »

heres my damagetypes done with the help of astroInferno:

Code: Select all

-- Darkness + Stun + Heal
newDamageType{
    name = "rat lich's dark feed", type = "HELLCOM_RATLICHDARKFEED", text_color = "#GREY#",--added a calling card to the damage type juuust in case
    projector = function(src, x, y, type, dam, state)
        state = initState(state)
        useImplicitCrit(src, state)
        if _G.type(dam) == "number" then dam = {dam=dam} end
        local target = game.level.map(x, y, Map.ACTOR)
        state = initState(state)
        -- extra damage to stunned targets
        if target and target:attr("Stun") then
            dam.dam = dam.dam * 1.10
        end
        local target = game.level.map(x, y, Map.ACTOR) -- Get the target first to make sure we heal even on kill
        --were not directly stealing the life from them so we dont need to cap the healing with their life
        local realdam = DamageType:get(DamageType.HELLCOM_RATFEED).projector(src, x, y, DamageType.HELLCOM_RATFEED, dam.dam, state)--now I'm not entirely certain thisll work, but you need a realdam value for the heal to base off of. if this doesnt work you could jsut do 'local realdam = physical' 'local realdam2 = darkness' and then later 'local heal = realdam + realdam2'
        local target = game.level.map(x, y, Map.ACTOR)
        if target then
            -- try to stun
            if target:canBe("stun") then
                target:setEffect(target.EFF_STUNNED, 4, {apply_power=src:combatSpellpower()})
            else
                game.logSeen(target, "%s resists being stunned!", target.name:capitalize())
            end
          end
        if target and realdam > 0 and not src:attr("dead") then
            --we're not a cursed so we dont need the healing factor shenanigans
            local heal = realdam
            src:logCombat(target, "#Source# consumes %d life from #Target#!", heal)
        end
    end,
        hideMessage=true,
}

newDamageType{
	name = "beshadowed bite", type = "HELLCOM_RATFEED",
	projector = function(src, x, y, type, dam, state)
		state = initState(state)
		useImplicitCrit(src, state)
		local darkness_from_bite = DamageType:get(DamageType.DARKNESS).projector(src, x, y, DamageType.DARKNESS, dam*.90, state) --'dam' is the amount of damage, so its the number value we need to mess with
		local physical_part_of_bite = DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam*.10, state)
		local damage_from_bite = darkness_from_bite + physical_part_of_bite
		return damage_from_bite
	end,	
}
Last edited by Hellcommander on Sat Apr 08, 2017 5:16 pm, edited 1 time in total.

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#5 Post by Hellcommander »

heres the intro:

Code: Select all

-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2015 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org

return [[Welcome #LIGHT_GREEN#@name@#WHITE#.
A foolish necromancer imbued the power of a lost spirit into the flesh of a dead giant rat that was expermented on with magic.
Kill this foolish human who has brought you great pain and use you your new found higher intellegence to rise to greater heights then before your death.
]]
Last edited by Hellcommander on Sat Apr 08, 2017 5:18 pm, edited 1 time in total.

ster
Spiderkin
Posts: 492
Joined: Tue Dec 13, 2016 7:05 pm

Re: Rat Lich mod based on irc idea :P

#6 Post by ster »

raterak will be proud
<Shibari> You're full of shit
<darkgod #tome> ster is a troll
<Sheila> and ster, i do agree with you on most things game-related, but do try to not be such an ass!
<mex> your posts lead to people like me being abused and murdered

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#7 Post by Hellcommander »

here is my current todo list:
most of the second and first skill are done
just need to getting it to use magicpower for damage type and dark feeds damage type (which internally heals the character with the damage, gets slight boast if they are stunned, stuns the target, and has a damage type mix of 90% darkness 10% physical)
and for the first skill give a chance to do a unarmed attack passively that scales its damage with spell power

3rd is similar to movement infusion where its talent levels scale its boosted movement speed

4th is a summon skill with a timed duration (or something to balance so you don't have hoards of undead rats) and benefiting for ratlich skull item to upgrade the minions from generic rat undead to special type rat undead (and disabling the rat lich skull from being able to be using for the rat lich while you have the talent)

rexorcorum has playable thing for ratlich on his todo list but it might take awhile (paperdoll and sprite)

and i still need to implement way to hold one weapon (maybe limit to certain when types 2 handed included but only for certain types like staves)
and balance changes after on the way (immunities will likely stay since it gives a unique undead flavor and sticks to Rat Lich's immunities)
Last edited by Hellcommander on Sat Mar 25, 2017 6:56 am, edited 1 time in total.

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#8 Post by Hellcommander »

self res 1 time allowed if at raw rank 5 in dark feed talent
provide temp buffs (that lasts 70 turns?) of
do messege of
game.logSeen(self, "#RED#Rising again, the Rat Lich's eyes glow with renewed energy!")
create some shadows that last a while (don't want to give player talents directly)
temp buff to max life worth 1.8 times then players max life (to match effect ratlich has on res)
5 bonus spell crit
on_resurrect = function(self, type)

grant
hate_regen=1,
mana_regen=3,
negative_regen=3,

combat_spellpower = resolvers.mbonus(20, 10),
combat_spellcrit = resolvers.mbonus(5, 5),

combat_mindpower = resolvers.mbonus(20, 10),
combat_mindcrit = resolvers.mbonus(5, 5),

summon 3 rodent undead

for duration of buff effect (70 turns like the cooldown on ratlich skull)

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#9 Post by Hellcommander »

Just finished generic 3 for the rat lich. Atm its a edited faster then lightning but for now it should do for a escape skill. (I'll give it its own effect at a later time)

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#10 Post by Hellcommander »

Completed more of its talents its retreat skill now grants darkness resistance to fit the dark magic desciption (no physical resistance granted at all)
Still need to make a custom equip inventory weapon slot for limited types of weapon but can use 2 handed weapons of certain types (no bows, slings, two-handed swords, 2 handed axes?)

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#11 Post by Hellcommander »

Ok finished the Call of the Rat Lich skill for now (likely needs stuff fixed later and redone but I'll need help with that later on)
Now i need to implement:
The chance to do hand to hand damage that scales with spellpower or mindpower (of the higher) attached to the first talent
implement a res that gives a temp buff in stuff at raw rank 5 to dark feed
I need to add damage to dark feeds projecting of its damage type that scales with mindpower or spellpower (whatever is higher)
Still need to implement the tail weapon slot for the rat lich
Need paperdolls and character tile for the rat lich or use a placeholder til later

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#12 Post by Hellcommander »

here is the effects.lua:

Code: Select all

local Stats = require "engine.interface.ActorStats"
local Particles = require "engine.Particles"
local Shader = require "engine.Shader"
local Entity = require "engine.Entity"
local Chat = require "engine.Chat"
local Map = require "engine.Map"
local Level = require "engine.Level"


newEffect{
	name = "RATLICH_SPEED", image = "talents/lightning_speed.png",
	desc = "Blaze of Darkness",
	long_desc = function(self, eff) return ("Your dark magics that bind your form transforming you into a blaze of darkness , moving %d%% faster. It also increases your darkness resistance by 100%%"):format(eff.power) end,
	type = "physical",
	subtype = { darkness=true, speed=true },
	status = "beneficial",
	parameters = {},
	on_gain = function(self, err) return "#Target# turns into pure darkness!.", "+Blaze of Darkness" end,
	on_lose = function(self, err) return "#Target# is back to normal.", "-Blaze of Darkness" end,
	get_fractional_percent = function(self, eff)
		local d = game.turn - eff.start_turn
		return util.bound(360 - d / eff.possible_end_turns * 360, 0, 360)
	end,
	activate = function(self, eff)
		eff.start_turn = game.turn
		eff.possible_end_turns = 10 * (eff.dur+1)
		eff.tmpid = self:addTemporaryValue("ratlich_speed", 1)
		eff.moveid = self:addTemporaryValue("movement_speed", eff.power/100)
		eff.resistsid = self:addTemporaryValue("resists", {
			[DamageType.DARKNESS]=100,
		})
		eff.capresistsid = self:addTemporaryValue("resists_cap", {
			[DamageType.DARKNESS]=100,
		})
		if self.ai_state then eff.aiid = self:addTemporaryValue("ai_state", {no_talents=1}) end -- Make AI not use talents while using it
		eff.particle = self:addParticles(Particles.new("bolt_lightning", 1))
	end,
	deactivate = function(self, eff)
		self:removeParticles(eff.particle)
		self:removeTemporaryValue("ratlich_speed", eff.tmpid)
		self:removeTemporaryValue("resists", eff.resistsid)
		self:removeTemporaryValue("resists_cap", eff.capresistsid)
		if eff.aiid then self:removeTemporaryValue("ai_state", eff.aiid) end
		self:removeTemporaryValue("movement_speed", eff.moveid)
	end,
}
Last edited by Hellcommander on Sat Apr 08, 2017 5:15 pm, edited 1 time in total.

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#13 Post by Hellcommander »

Rat lich's racial tree is complete for now will work on it later but hopefully the tree will work as it is with a lack of icons. Still need to get the tail_weapon slot made and finished.

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#14 Post by Hellcommander »

Hopefully finished most of the initial work on the rat lich now and here is the load.lua:

Code: Select all

local class = require"engine.class"
local ActorInventory = require "engine.interface.ActorInventory"
local ActorTalents = require "engine.interface.ActorTalents"
local ActorTemporaryEffects = require "engine.interface.ActorTemporaryEffects"
local Faction = require "engine.Faction"
local Birther = require "engine.Birther"
local PartyLore = require "mod.class.interface.PartyLore"
local DamageType = require "engine.DamageType"
local Zone = require "engine.Zone"
local Stats = require "engine.interface.ActorStats"
local Particles = require "engine.Particles"
local Shader = require "engine.Shader"
local Entity = require "engine.Entity"
local Chat = require "engine.Chat"
local Map = require "engine.Map"
local Level = require "engine.Level"
local Object = require "engine.Object"



class:bindHook("ToME:load", function(self, data) 
	DamageType:loadDefinition("/data-rat-lich-race/race/damage_types.lua")
	ActorTalents:loadDefinition('/data-rat-lich-race/races/ratlich_talents.lua')
  	ActorInventory:defineInventory("TAIL_WEAPON", "Tail Weapon", true, "Tail Weapon.", nil, {equipdoll_back="ui/equipdoll/mainhand_inv.png.png"})
	Birther:loadDefinition("/data-rat-lich-race/races/ratlich.lua")
	ActorTemporaryEffects:loadDefinition("/data-rat-lich-race/timed_effects.lua")
end)

Hellcommander
Archmage
Posts: 362
Joined: Tue Nov 09, 2010 7:43 pm

Re: Rat Lich mod based on irc idea :P

#15 Post by Hellcommander »

Everything is almost set for the initial release but I'm having a issue getting the new base type of undead rat added to the talent file
getting a error saying it doesn't recognize the new entity value (loading the minions in other file leads to a non error error)

Post Reply