-
Posts
2279 -
Joined
-
Last visited
-
Days Won
36
Everything posted by MirceaKitsune
-
Script: Per limb damage, skill system (WIP)
MirceaKitsune replied to MirceaKitsune's topic in Art Assets
The next update is here! I consider the damage component as finished as it gets, it should be mainly bug fixes and minor tweaks from here. I polished everything and restructured much of the code, and can now recommend players to install and enable this during everyday gameplay. Fixes and improvements include: Better patterns and algorithms for correctly distributing damage to the proper limbs. New protection: Holding an object in your hands exposes the arms more but the torso less. New penalty: Mild turn hindrance while the head is damaged. Values from the previous call are used when determining player velocity, position, shape. This offers safer and more realistic results... for example fall damage will distribute accurately as the player's velocity before hitting the ground is calculated, rather than reading it afterward when the player is standing still. As suggested by one of the developers, cvars can now be used to adjust the system. Two cvars were added: "g_player_damage" scales the damage limbs take from ordinary damage, can be changed in-game with immediate effects. "g_addon_player" disables the addon entirely and won't load it, however it only has an effect before map load meaning the mod won't be loaded / unloaded in realtime. Not setting a cvar is the equivalent of setting it to 1, you must set it to 0 to disable. External mods can work with limbs via getFloatKey() and setKey(). For example: $player1.getFloatKey("health_torso") or $player1.setKey("health_arm_left", 0.5). Each limb will now flash on the HUD when taking damage, making it obvious which body parts were hit that frame. The HUD itself has been updated with better graphics based on this OpenClipArt design. Here are some screenshots of the new assets: No plans for the skill component yet, mainly due to scripting system limitations leaving a lot up in the air. But finishing the damage module helps pave the way. player_damage_1.1.pk4 -
Interesting: I tried it and on this map I'm not getting any issues either, the mirror reflects perfectly fine. So it is something on my map triggering it after all, and it must be 2.09 specific since a few weeks ago it didn't do it and I haven't modified the map since. I'll send the devs a copy of my map file with a getviewpos, let me know who's willing to look into it and I shall PM it.
-
I see what you mean. This is why texture compression or at least downscaling would be a good idea. Hopefully a way around it can be found someday. If not I can live with this being a mod, especially since you only need to put the pk4 in and that's it! Just hope there's enough guarantee that it can be maintained. Maybe it can become an official addon, still separate but maintained by the devs? I probably should not throw so many ideas at once again xD
-
Script: Per limb damage, skill system (WIP)
MirceaKitsune replied to MirceaKitsune's topic in Art Assets
Not yet but I can see how that would be a good idea. I can use sys.getcvar() to read any setting correct? It should be a piece of cake to make it more configurable and possible to toggle then, should do this for the next update. In the meantime this is experimental anyway, so the pk4 is recommended for players who wish to toy with the concept. -
Judging from the screenshots, I honestly feel this one should be merged into vanilla TDM and replace the originals, or at least some of the textures in it should. Occasional low-res textures are an annoyance and such a patch is super welcome IMHO. I'm kind of afraid to try it because I might get too used to it and not want to give it up if an update ever breaks them
-
I'm glad this thread exists since I absolutely have a nomination to make. Every rock model found under darkmod/nature/rocks uses low-res images that look almost like Minecraft texture resolution, you can count the pixels with your finger. I saw some of them in-game as well and the low resolution is definitely noticeable. It shouldn't be difficult to see what I mean... They're models but luckily using generic stone textures. Thus they should be possible to improve with a new image which may even be allowed to tile a few times.
-
After some amount of work I'm happy to be able to share my Christmas gift for TDM! Or at least half of it, considering the other half is still only in design phase. I created an addon that implements detailed player functionality, inspired by the first DeusEx game (The Conspiracy). It's NOT a mission script but an addon, meaning you place the pk4 in your TDM directory to enable the system and it will automatically work in each and every FM. Note that due to using tdm_user_addons.script / user_addon_init() it may disable or get disabled by other addons you have installed... this is a design limitation which can hopefully be lifted at some point in the future. This plugin will be included in my cyberpunk total conversion The Dark Module and automatically active with it, but first I shall design it and make it available as a small independent addon for vanilla TDM. In the current initial release it implements just per-limb damage; The upcoming plan is to add a skill / augmentation system, allowing the player to use loot as skill points to enhance various body parts and gain new or improved abilities. Due to the scripting system being very limited in what it lets me modify, I'm still gathering documentation on how to implement those skills and which I can have. So until then detailed body damage with penalties remains the only part that's theoretically finished so far (further improvements are required here too)... including a HUD component above the lightgem showing the status of each body part: Green = full health, yellow = half health, red = (close to) no health, black = no health left. The individual limbs available: Head, Torso, Left Arm, Right Arm, Left Leg, Right Leg... arms and legs work in unity however. They each take damage with the player as well as healing together with them. The more damaged a group is, the more a respective penalty is applied to the player. Groups and penalties include: Head: When the head is damaged, the player begins to get dizzy and has their vision impaired. Currently the only effect replicates the flashbomb, causing white dots to appear around the player and disrupt their view until the head is healed. As the player can't live without a head, reaching 0 will cause instant death. More effects are possible and pending. Torso: Damage to the torso translates to damage to the cloak, increasing the player's lightgem and rendering them more visible even in dark spots. As the player can't live without a torso, reaching 0 will cause instant death. Given script limitations I'm unable to simulate lung damage and decrease / limit the amount of air the player has. Arms: Arm damage makes it difficult for the player to hold items: In-world objects being held will probabilistically get dropped, more often the worse your arms are hurt. When both arms reach 0 health, the player can no longer pick up anything in the world without instantly dropping it... you also become unable to use any weapons. Due to limitations in the scripting system, I'm unable to decrease the speed or accuracy of the blackjack / sword / bow as was desired. Legs: As expected leg damage will make the player walk more slowly. It was desired that when one leg is lost the player can no longer jump, whereas when both legs are gone you remain stuck in crouch mode until healed... due to limitations in the scripting system this part is also not possible at the moment. A crude limitation is the fact that limb damage is primarily based on the direction the player is walking toward... for example, increased likelihood of suffering damage to your right arm and leg if strafing right the moment you take the damage. The script system doesn't let you extract the vector direction of the last damage event, thus I can't use the real direction the hit came from when calculating which body part should absorb the most health loss. This means that even if an arrow comes from above and hits the player's head area, the player will only take damage to the legs if they're falling downward the moment they got hit... for the time being this provides a bare minimum amount of realism but is a very bitter implementation. For this reason it would be greatly appreciated if any of the code developers could join this discussion and verify if they can help with adding the necessary hooks to external scripts: With 2.09 getting periodic beta releases at this point in time, it would be a great opportunity to make changes to the builtin player script that allow an external function to modify more player variables. This includes the efficiency of weapons, if the player is allowed to jump or forced to always crouch, and I'd also really appreciate a hook to manipulate the breath so air can be lowered as if the player is underwater. I understand other priorities exist or if the work may be considered too much, however this would help in being able to finish this mod with the proper functionality and planned skill set. In the meantime let me know what you think of this idea and how I went about it! So far no new assets are included except the GUI graphics: Everything is done with less than 250 lines of script which I'd say is a good achievement I've attached the pk4 and since it's so lightweight I'll also add the main script straight in this post. player_damage_1.0.pk4 #define DAMAGE_WAIT 0.0166667 #define EXPOSURE_ARM_LEFT 2 #define EXPOSURE_ARM_RIGHT 2 #define EXPOSURE_LEG_LEFT 2 #define EXPOSURE_LEG_RIGHT 2 #define EXPOSURE_HEAD 3 #define EXPOSURE_TORSO 1 #define PENALTY_TORSO_LIGHTGEM 4 player self; float damage_gui; boolean dizzy; entity dizzy_particles; float bound(float val, float min, float max) { if(val < min) return min; if(val > max) return max; return val; } // Range based probability: Calculates a probability per frame independent of wait time (0 - 1 range at 1 chance per second) boolean prob(float x) { return sys.random(1) > x && sys.random(1) < DAMAGE_WAIT; } // Directional exposure calculator float dex(vector dir, float ex_front, float ex_back, float ex_right, float ex_left, float ex_up, float ex_down) { float maxvel = 100; float dir_front = bound(dir_x / maxvel, 0, 1) * ex_front; float dir_back = bound(-dir_x / maxvel, 0, 1) * ex_back; float dir_right = bound(dir_y / maxvel, 0, 1) * ex_right; float dir_left = bound(-dir_y / maxvel, 0, 1) * ex_left; float dir_up = bound(dir_z / maxvel, 0, 1) * ex_up; float dir_down = bound(-dir_z / maxvel, 0, 1) * ex_down; return dir_front + dir_back + dir_right + dir_left + dir_up + dir_down; } void player_damage_update_arm(float dmg_l, float dmg_r) { float hl_l = self.getFloatKey("health_arm_left"); float hl_r = self.getFloatKey("health_arm_right"); float hl = (hl_l + hl_r) / 2; if(dmg_l != 0 || dmg_r != 0) { hl_l = bound(hl_l - dmg_l, 0, 1); hl_r = bound(hl_r - dmg_r, 0, 1); hl = (hl_l + hl_r) / 2; self.setKey("health_arm_left", hl_l); self.setKey("health_arm_right", hl_r); self.setGuiFloat(damage_gui, "PlayerDamage_ItemArmLeft", hl_l); self.setGuiFloat(damage_gui, "PlayerDamage_ItemArmRight", hl_r); // Penalty #1: Disable the weapon once the arm are damaged to minimum health if(hl == 0) { self.selectWeapon(WEAPON_UNARMED); self.disableWeapon(); } else { self.enableWeapon(); } } // Penalty #2: Probabilistically drop held items based on arm damage if(hl == 0 || prob(hl)) if(self.heldEntity() != $null_entity) self.holdEntity($null_entity); } void player_damage_update_leg(float dmg_l, float dmg_r) { float hl_l = self.getFloatKey("health_leg_left"); float hl_r = self.getFloatKey("health_leg_right"); float hl = (hl_l + hl_r) / 2; if(dmg_l != 0 || dmg_r != 0) { hl_l = bound(hl_l - dmg_l, 0, 1); hl_r = bound(hl_r - dmg_r, 0, 1); hl = (hl_l + hl_r) / 2; self.setKey("health_leg_left", hl_l); self.setKey("health_leg_right", hl_r); self.setGuiFloat(damage_gui, "PlayerDamage_ItemLegLeft", hl_l); self.setGuiFloat(damage_gui, "PlayerDamage_ItemLegRight", hl_r); // #Penalty #1: Make movement slower self.setHinderance("health", 0.25 + hl * 0.75, 1); } } void player_damage_update_head(float dmg) { float hl = self.getFloatKey("health_head"); float time_current = sys.getTime(); if(dmg != 0) { hl = bound(hl - dmg, 0, 1); self.setKey("health_head", hl); self.setGuiFloat(damage_gui, "PlayerDamage_ItemHead", hl); // Penalty #1: Without a head the player dies if(hl == 0) self.damage(self, self, self.getOrigin(), "damage_suicide", 1); // Penalty #2: Simulate dizzyness starting at half health if(hl <= 0.5) { if(!dizzy) { dizzy_particles = sys.spawn("func_emitter"); dizzy_particles.setModel("flashbomb.prt"); dizzy_particles.setOrigin(self.getEyePos()); dizzy_particles.bind(self); dizzy = true; } } else { if(dizzy) { dizzy_particles.remove(); dizzy = false; } } } } void player_damage_update_torso(float dmg) { float hl = self.getFloatKey("health_torso"); if(dmg != 0) { hl = bound(hl - dmg, 0, 1); self.setKey("health_torso", hl); self.setGuiFloat(damage_gui, "PlayerDamage_ItemTorso", hl); // Penalty #1: Without a torso the player dies if(hl == 0) self.damage(self, self, self.getOrigin(), "damage_suicide", 1); // Penalty #2: Torso damage negatively affects the lightgem self.setLightgemModifier("damage", (1 - hl) * PENALTY_TORSO_LIGHTGEM); } } void player_damage() { sys.waitFrame(); self = $player1; damage_gui = self.createOverlay("guis/player_damage.gui", 1); float health_old = 100; // Init by sending a heal event filling the limbs to full health player_damage_update_arm(-1, -1); player_damage_update_leg(-1, -1); player_damage_update_head(-1); player_damage_update_torso(-1); while(1) { // sys.waitFrame(); sys.wait(DAMAGE_WAIT); float health_current = self.getHealth(); float dmg = (health_old - health_current) / 100; float dmg_arm_left = dmg * EXPOSURE_ARM_LEFT; float dmg_arm_right = dmg * EXPOSURE_ARM_RIGHT; float dmg_leg_left = dmg * EXPOSURE_LEG_LEFT; float dmg_leg_right = dmg * EXPOSURE_LEG_RIGHT; float dmg_head = dmg * EXPOSURE_HEAD; float dmg_torso = dmg * EXPOSURE_TORSO; // If this is damage and not healing, apply directional damage to each limb if(dmg > 0) { // Currently we estimate damage direction based on the player's velocity, we should fetch the real direction of a damage event when this becomes possible vector dir = self.getMove(); vector ang = self.getViewAngles(); // Protections based on the player's position and relation to the environment // protection_look: 1 when looking up, 0 when looking down // protection_low: Higher as the lower part of the body is exposed float protection_look = 1 - (90 + ang_x) / 180; float protection_low = 1; if(self.AI_CROUCH) protection_low = 0; else if(self.AI_ONGROUND) protection_low = 0.75; // Use the dex function to calculate directional exposure patterns, direction order: Front, back, right, left, up, down // Arms: Somewhat likely to be hit, no added protection // Legs: Somewhat likely to be hit, added protection when the player is crouching // Head: Unlikely to be hit, added protection when the player is looking down // Torso: Likely to be hit, no added protection float exposure_arm_left = bound(sys.random(0.375) + dex(dir, 0.5, 0.25, 0.0, 1.0, 0.0, 0.25), 0, 1); float exposure_arm_right = bound(sys.random(0.375) + dex(dir, 0.5, 0.25, 1.0, 0.0, 0.0, 0.25), 0, 1); float exposure_leg_left = bound(sys.random(0.375) + dex(dir, 0.75, 0.5, 0.0, 0.5, 0.0, 1.0) * protection_low, 0, 1); float exposure_leg_right = bound(sys.random(0.375) + dex(dir, 0.75, 0.5, 0.5, 0.0, 0.0, 1.0) * protection_low, 0, 1); float exposure_head = bound(sys.random(0.25) + dex(dir, 0.25, 0.75, 0.5, 0.5, 1.0, 0.0) * protection_look, 0, 1); float exposure_torso = bound(sys.random(0.5) + dex(dir, 0.75, 1.0, 0.0, 0.0, 0.0, 0.0), 0, 1); // Apply the exposure to damage, multiplied to simulate the sensitivity / resistance of each limb dmg_arm_left = exposure_arm_left * dmg * EXPOSURE_ARM_LEFT; dmg_arm_right = exposure_arm_right * dmg * EXPOSURE_ARM_RIGHT; dmg_leg_left = exposure_leg_left * dmg * EXPOSURE_LEG_LEFT; dmg_leg_right = exposure_leg_right * dmg * EXPOSURE_LEG_RIGHT; dmg_head = exposure_head * dmg * EXPOSURE_HEAD; dmg_torso = exposure_torso * dmg * EXPOSURE_TORSO; } player_damage_update_arm(dmg_arm_left, dmg_arm_right); player_damage_update_leg(dmg_leg_left, dmg_leg_right); player_damage_update_head(dmg_head); player_damage_update_torso(dmg_torso); health_old = health_current; } }
-
Hmmm. Can you try giving the room a window, ideally visible in the mirror (behind it), which leads to an opening textures with portal sky and a sky box? That's the only specific I can think of in my setup that doesn't appear here.
-
That's weird and makes things complicated then. I don't see how it could be map related unless I'm doing something very unusual, so more likely it's some graphical setting I may have enabled. I'd rather not share my super unfinished map just yet so I'm not sure how I can further help on the mirror bug. I'll think on it in case anything comes to mind. I love the way that furniture looks! Thank you for another very welcome asset contribution
-
I also found another issue, super minor one this time: The default citywatch AI (atdm:ai_citywatch_lesser) periodically spam console warnings about pickup_eat_righthand and AIUSE_EAT. It's also from my FM but I'm using a default entity which seems to be erroring out on a builtin animation. As far as anything relevant that's map specific could be involved, I can share the spawnargs I customize the two AI with in case one may be relevant: pos_attach5 hand_l def_attach5 atdm:prop_winebottle def_head atdm:ai_head_citywatch_clothcoif def_vocal_set atdm:ai_vocal_set_drunk_citywatch_01 drunk 1 sitting 1 team 2 def_head atdm:ai_head_citywatch_poor def_vocal_set atdm:ai_vocal_set_cynic_citywatch team 2 target0 name_of_a_path_corner
-
I don't see how this can be a mapper fault since everything else works fine and my map has no leaks, only mirrors are broken and not rendering the ceiling of the room. I wasn't using my WIP map for testing purposes either: I permanently switched to the 2.09 Beta, both to have the the latest version as well as help test it... incidentally I chose to take a look at my FM today for other reasons when I noticed this. If I see the issue in another FM I'll be playing I will submit its data. I'd recommend looking at any FM that uses the mirror shader and seeing if the same issue occurs. I remember there are quite a few FM's that have mirrors in bathrooms, sadly no name by memory but I'm sure one can be found.
-
It's a FM I'm working on and unfortunately not public yet nor anywhere near being ready for it. Luckily I developed most of it on 2.08 and can say for sure I didn't notice this issue a few weeks ago: I only did again today and wondered what might have happened, then realized I was on the 2.09 beta and it's likely that.
-
New bug found. 2.09 seems to break mirrors... quite literally Screenshots taken from two different rooms, the map is freshly dmapped with no errors or leaks or other geometric issues visible directly.
-
Even r_postprocess_desaturation was turned off? That one sucks since it helps with the rustic effect and 0.05 was a very reasonable default. At this point I think I'm going to create my own cfg aiming for more hyper-realistic graphics, where I'll play and try to come up with nicer looking values for those settings: I wanted to tweak the bloom and such to make it more realistic anyway.
-
I remember seeing it a few times but forgot exactly where. The only example I remember now is from today while playing an old FM called The Creeps: You should hear it with the double doors on the floor leading downwards when trying to open or pick them from outside (tiny FM so easy to find).
-
I didn't think of forking the inventory menu to add my functionality, but now that I think twice I might just do that. Especially since one of my other dreams was adding a DeusEx type grid inventory thingie... prolly too complex for me but it would resonate with making my own copy. Thanks, will keep in mind and consider that option. I'm afraid so, would have been surprised if it worked any other way. That's why the engine can ideally leave as much as possible up to the scripting system, though of course basic functionalities must remain hard coded. I wish weapons were removed from the engine for instance, and reimplemented entirely as inventory items... this would also get rid of that pesky 16 weapons limit, or having to define them as properties of the player in the first place (except for the 1st person view models).
-
I think I may have found my first bug. And I don't remember noticing it before this beta so it might be specific to it. When you interact with some doors (trying to open, trying to lockpick, clicking noises while lockpicking, etc) the sound is heard at a very low volume, I'd say twice as low as it normally should be. Something tells me this has to do with the door entity being seen as sitting on the other side of the vis portal it's closing, thus the engine is likely culling the sound coming from that door due to forgetting doors should make an exception to this rule.
-
Maybe I will use one? I was ultimately planning to have the player inject himself with different arrows to randomly enhance a skill in that arrow's category... the selected weapon would be checked when the use key was pressed, given no item is also selected and nothing in-world is being frobbed. This idea kind of sucks though. Still leaning toward using loot as skill points instead. But even if I use a GUI I need a button to open it up! And like I said a custom key bind won't work as I also have to give it a default value and add it to the main menu which would require hacking into the existing code. At the moment I remain kind of stuck here for this reason... suggestions would be much appreciated. Also stuck on figuring out how on Earth to implement most skills, due to the scripting system only letting me influence the player in a handful of ways. I figured out how to do the basic ones thank goodness, but sadly there's going to be very few components since I can't change stuff like the firing rate or accuracy of the bow for every arrow.
-
In my case I plan to use it for a plugin I'm making. Not disclosing too much about it at the moment... only thing I decided to say is I'm planning to include a skill system that lets you upgrade the player to enhance abilities, by which I mean the few abilities I can use the script system to modify. I need a way to let the player issue a command for upgrading various skills, and I'm not fond of making a full GUI for it just yet nor adding new keybinds which would have to be placed in the main menu as well.
-
I see. My understanding was this is a system used to store flags in a single integer as information that could be extracted from that number. Like if your number is 5, you'd know that with powers of two it could only be 4 + 1, thus it must contain bit 1 and 4 but not 2 or 8 or 16. My understanding may not be complete though.
-
Fan Mission: Ulysses: Genesis by Sotha (2014/07/24)
MirceaKitsune replied to Sotha's topic in Fan Missions
Got around to replaying this great FM again. It was fun to enjoy it after so long, especially now in the age of soft shadows and sharpness filter. Interestingly I felt that this time it exposed some underlying limitations in TDM particularly how AI handle panic. -
Yeah this is a bit confusing. And indeed I should be able to simply print what .getButtons() says while holding down different buttons, that should give me the necessary result. 76 seems wrong though as it's not a power of two, IIRC that's how bits work.
-
So using the .getButtons() example, how do I get _impulse51? That seems to be using a bit: 1, 2, 4, 8, 16, etc. Is it known which bit that impulse is?
-
Latest DarkRadiant Git master is still doing it I'm afraid (Codereader's origin). Fresh CMake setup obviously, I run "git clean -dfx" before each update. Cannot find the main module in any of the paths: /archive/mircea/Games/Quake/TheDarkMod/DarkRadiant_GIT/build/install/bin/../lib/darkradiant/modules/; /archive/mircea/Games/Quake/TheDarkMod/DarkRadiant_GIT/build/install/bin/../lib/darkradiant/plugins/ The path changed since I'm now installing to DarkRadiant_GIT/build/install which is the logical directory to use.