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 }