etayn

old gzdoom project
git clone git://moonbender.net/etayn
Log | Files | Refs | README

damage.zsc (5153B)


      1 extend class DevilbunnyPlayer
      2 {	
      3 	//	0 = UNARMORED
      4 	//	1 = BRIGANDINE (backpack replacement, 50% damage reduction)
      5 	//	2 = MARISKULL	(radsuit replacement)
      6 	//	wish zscript supported enums
      7 	int hasArmorType;
      8 	
      9 	//the target that the player's summons will attack. Decided by
     10 	//1. last monster that damaged the player
     11 	//2. closest monster (to the player) targeting the player 
     12 	actor summonTarget;
     13 	int targetRange;
     14 	int targetPriority;
     15 
     16 	void PissOffSummons(Actor target, int priority)
     17 	{
     18 		if (priority > targetPriority)
     19 		{
     20 			summonTarget = target;
     21 			targetPriority = priority + 40;
     22 		}
     23 	}
     24 
     25 	void HandleSTarget()
     26 	{	
     27 		//reset this every frame so the
     28 		//eventhandler can figure out which
     29 		//alerted monster is closest to the player
     30 		targetRange = 4000;
     31 
     32 		//target's priority diminishes over time
     33 		//so summons will switch targets
     34 		if (targetPriority > 0)
     35 		{
     36 			targetPriority -= 1;
     37 		}
     38 		else
     39 		{
     40 			//forget about targets that don't have LOS with the player
     41 			//(eventually)
     42 			if (!CheckSight(summonTarget))
     43 			{
     44 				summonTarget = null;
     45 				return;
     46 			}
     47 		}
     48 
     49 		//if no summonTarget, set priority to 0 so that'll always
     50 		//change if another valid target is found
     51 		if(!summonTarget)
     52 		{
     53 			targetPriority = 0;
     54 			return;
     55 		}
     56 
     57 		//check for things that are targeted
     58 		//by summons but shouldn't be
     59 		if (
     60 				/*dead monsters*/
     61 				summonTarget.InStateSequence(
     62 					summonTarget.CurState, 
     63 					summonTarget.ResolveState("Death")) 
     64 				|| summonTarget.InStateSequence(
     65 					summonTarget.CurState, 
     66 					summonTarget.ResolveState("XDeath"))
     67 				/*the summoner*/
     68 				|| (summonTarget == self)
     69 				/*Another summon (or itself)*/
     70 				|| (summonTarget is "SummonBase")
     71 			)
     72 		{
     73 			summonTarget = null;
     74 			targetPriority = 0;
     75 		}
     76 	}
     77 	
     78 	override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
     79 	{
     80 		if (flags & DMG_FORCED) //kill instantly if A_Die() is called
     81 		{
     82 			damage = 1;
     83 			return Super.DamageMobj(inflictor, source, damage, mod, flags, angle);
     84 		}
     85 		//this mod doesn't use doom-style armor. Just in case the player ends up with it, somehow...
     86 		flags = flags | DMG_NO_ARMOR;
     87 		
     88 		int sreduce; //amount to reduce the damage due to spirit
     89 	
     90 		sreduce = damage / 3;
     91 		
     92 		if (!(flags & DMG_NO_FACTOR))
     93 		{
     94 			if (mod == "PlayerDamage")
     95 			{
     96 				damage = 0;
     97 				sreduce = 0;
     98 			}
     99 			if (self.hasArmorType == 1) //wearing half damage armor
    100 			{
    101 				damage = damage / 2;
    102 				if (mod == "Melee")
    103 				{
    104 					damage = 0;
    105 					sreduce = 0;
    106 				}
    107 			}
    108 			else if (self.hasArmorType == 2) //wearing radsuit replacement
    109 			{
    110 				if (mod == "Drowning" || mod == "Slime" || mod == "Poison" || mod == "Ice" ) 
    111 				{
    112 					damage = 0;
    113 				}
    114 				
    115 				if (mod == "Fire") 
    116 				{
    117 					damage /= 2;
    118 				}
    119 				
    120 				sreduce = 0;
    121 			}
    122 		}
    123 		
    124 		vector3 offs;
    125 		offs.z = 30;
    126 		if (damage >= 90)
    127 		{
    128 			spawn("BigFeatherBurst", pos + offs, NO_REPLACE);
    129 		}
    130 		else if (damage >= 40)
    131 		{
    132 			spawn("FeatherBurst", pos + offs, NO_REPLACE);
    133 		}
    134 		else if (damage >= 5)
    135 		{
    136 			spawn("MaybeFeather", pos + offs, NO_REPLACE);
    137 		}
    138 		
    139 		if (damage && (self.hitpoints > 0))
    140 		{
    141 			if (self.hitpoints - damage <= 0)
    142 			{
    143 				A_StartSound("bun/dying", CHAN_BODY);
    144 			}
    145 			else
    146 			{
    147 				A_StartSound("bun/ouch", CHAN_BODY);
    148 			}
    149 		}
    150 		
    151 		if (sreduce > self.spirit)
    152 		{
    153 			sreduce -= self.spirit;
    154 			self.spirit = 0;
    155 		}
    156 		
    157 		damage -= sreduce;
    158 		self.LoseSpirit(sreduce);
    159 		
    160 		self.LoseHealth(damage);
    161 		damage = 0;
    162 
    163 		if (source && mod != "PlayerDamage")
    164 		{
    165 			self.PissOffSummons(source, 300);
    166 		}
    167 		
    168 		return Super.DamageMobj(inflictor, source, damage, mod, flags, angle);
    169 	}	
    170 
    171 	void updateParryShield()
    172 	{
    173 		if (parryShield)
    174 		{
    175 			parryShield.SetOrigin(Vec3Angle(32, angle, 32), false);
    176 		
    177 			if (player.readyweapon)
    178 			{
    179 				let curweapon = DevilbunnyWeapon(player.readyweapon);
    180 				
    181 				if (curweapon.parries == TRUE)
    182 				{
    183 					parryShield.bShootable = true;
    184 				}
    185 				else
    186 				{
    187 					parryShield.bShootable = false;
    188 				}
    189 				
    190 				let spain = parryShield.ResolveState("Pain");
    191 				let scur = parryShield.CurState;
    192 				let parrystate = curweapon.FindState("Parry");
    193 				
    194 				
    195 				if(spain && scur && parrystate)
    196 				{
    197 					if (parryShield.InStateSequence(scur, spain))
    198 					{
    199 						if (curweapon.parryAnimReady)
    200 						{
    201 							player.setpsprite(PSP_WEAPON,parrystate);
    202 						}
    203 					}
    204 				}
    205 			}
    206 		}
    207 		else
    208 		{
    209 	//		A_Log("Created New ParryShield");
    210 			self.parryShield = spawn("ParryAct", pos);
    211 		}
    212 	}
    213 		
    214 	void GainSpirit(int amount)
    215 	{
    216 		spirit += amount;
    217 		targspirit += amount;
    218 		if (targspirit > maxspirit)
    219 		{
    220 			targspirit = maxspirit;
    221 			spirit = maxspirit;
    222 		}
    223 	}
    224 	
    225 	bool SpendSpirit(int amount)
    226 	{
    227 		if (hasArmorType == 2) { amount /= 2; }
    228 		if (spirit >= amount)
    229 		{
    230 			LoseSpirit(amount); //actually sets targspirit
    231 			spirit -= amount;
    232 			return true;
    233 		}
    234 		return false;
    235 	}
    236 	
    237 	void LoseSpirit(int amount)
    238 	{
    239 		targspirit -= amount;
    240 		if (targspirit < 0) 
    241 		{
    242 			targspirit = 0;
    243 		}
    244 	}
    245 	
    246 	void GainHealth(int amount)
    247 	{
    248 		hitpoints += amount;
    249 		if (hitpoints > maxhits)
    250 		{
    251 			hitpoints = maxhits;
    252 		}
    253 	}
    254 	
    255 	void LoseHealth(int amount)
    256 	{
    257 		hitpoints -= amount;
    258 		if (hitpoints < 0)
    259 		{
    260 			hitpoints = 0;
    261 		}
    262 	}
    263 }