Jump to content
The Dark Mod Forums

Beta testers sought: speed potion, slow-fall potion


VanishedOne

Recommended Posts

Okay.

 

With this version vertical movement in water with the speed potion should be possible, but I think the diving problem is still there:

 

 

 

/*
* SPEED POTION scriptobject
*/
object playertools_speedpotion : player_tools {
	/**
	* [ Comment copied from health potion script object: ]
	* greebo: This is the method that gets called from within the SDK
	*		  when the player "uses" this tool as inventory item.
	*
	* @userEntity: the entity that is using this item, usually $player1
	* @frobbedEntity: the entity the player is currently frobbing, may be $null_entity
	* @buttonState: a float telling about the current button state (pressed, released)
	*/
	void inventoryUse(player userEntity, entity frobbedEntity, float buttonState);
	void update(player userEntity);
	
	float duration;
	float speed_mod;
	float endTime;
};

/**
* =============== SPEED POTION ======================================
*/
void playertools_speedpotion::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	// Callback to decrease the inventory stack count
	userEntity.changeInvItemCount(getKey("inv_name"), getKey("inv_category"), -1);

	// Play the activate sound
	userEntity.startSoundShader(getKey("snd_swallow"), SND_CHANNEL_VOICE);
	
	duration = getFloatKey("duration");
	speed_mod = getFloatKey("speed_mod");
	
	endTime = (sys.getTime() + duration);
	
	update(userEntity);
}

void playertools_speedpotion::update(player userEntity) {
	sys.killthread("speed_potion");
	sys.threadname("speed_potion");
	
	while (sys.getTime() < endTime) {sys.wait(0.01);
		vector player_direction = userEntity.getViewAngles();
		float player_angle = player_direction_y;
		vector player_movement = userEntity.getMove();
		vector player_movement_world = player_movement;
		player_movement_world_x = (player_movement_x * sys.cos(player_angle)) + (player_movement_y * sys.cos(player_angle - 90));
		player_movement_world_y = (player_movement_x * sys.sin(player_angle)) + (player_movement_y * sys.sin(player_angle - 90));
		
		vector boost_movement = '0 0 0';
		
		if (userEntity.AI_ONGROUND) {
			boost_movement_x = player_movement_world_x * speed_mod;
			boost_movement_y = player_movement_world_y * speed_mod;
		}
		else if (userEntity.isInLiquid()) {
			boost_movement_x = player_movement_world_x * speed_mod;
			boost_movement_y = player_movement_world_y * speed_mod;
			boost_movement_z = player_movement_world_z * speed_mod;
		};
		
		userEntity.applyImpulse(userEntity,0,userEntity.getOrigin(),boost_movement);
	};
}



/*
* SLOW-FALL POTION scriptobject
*/
object playertools_slowfallpotion : player_tools {
	/**
	* [ Comment copied from health potion script object: ]
	* greebo: This is the method that gets called from within the SDK
	*		  when the player "uses" this tool as inventory item.
	*
	* @userEntity: the entity that is using this item, usually $player1
	* @frobbedEntity: the entity the player is currently frobbing, may be $null_entity
	* @buttonState: a float telling about the current button state (pressed, released)
	*/
	void inventoryUse(player userEntity, entity frobbedEntity, float buttonState);
	void update(player userEntity);
	
	float duration;
	float lift_force;
	float drag_penalty;
	float endTime;
};

/**
* =============== SLOW-FALL POTION ==================================
*/
void playertools_slowfallpotion::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	// Callback to decrease the inventory stack count
	userEntity.changeInvItemCount(getKey("inv_name"), getKey("inv_category"), -1);

	// Play the activate sound
	userEntity.startSoundShader(getKey("snd_swallow"), SND_CHANNEL_VOICE);
	
	duration = getFloatKey("duration");
	lift_force = getFloatKey("lift_force");
	drag_penalty = getFloatKey("drag_penalty");
	
	userEntity.setHinderance("slowfall_potion", drag_penalty, drag_penalty);
	
	endTime = (sys.getTime() + duration);
	
	thread update(userEntity);
}

void playertools_slowfallpotion::update(player userEntity) {
	sys.killthread("slowfall_potion");
	sys.threadname("slowfall_potion");
	
	while (sys.getTime() < endTime) {sys.wait(0.01);
		vector player_movement = userEntity.getMove();
		vector boost_movement = '0 0 0';
		
		if ( (player_movement_z <= 0) && !userEntity.AI_ONGROUND && !userEntity.AI_ONLADDER) boost_movement_z = lift_force;
		userEntity.applyImpulse(userEntity,0,userEntity.getOrigin(),boost_movement);
	};
	
	userEntity.setHinderance("slowfall_potion", 1, 1);
}

 

 

 

Edit: well, the result of applying a vertical speed boost when swimming is that we have another potion that lets you get boosted out of water.

 

Edit2: the reason diving isn't working is that I never set up the script to take your angle in the vertical axis into account.

Edited by VanishedOne

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

Rather than literally slowing the player down, is there a way to identify damage from falls? Maybe the potion could simply reduce that damage (or eliminate it entirely if desired). That would seem to have a lot less opportunity to play poorly with other systems.

Link to comment
Share on other sites

Not near code atm, but there might be something the script can turn on to prevent fall damage, which is handled in the code when the player's downward movement changes abruptly. 'god' might be too general. There's too much going on during such a 'crash landing' for the script to identify it and then try to undo it.

Link to comment
Share on other sites

The only way I can see for a script to avoid the player's falling damage is to turn 'god' mode on when the potion is in effect and falling begins.

 

However, there's no way for a script to query what the 'god' setting was before this is done, so that it can be restored after the effect ends. It's important to do this instead of just turning 'god' off, because the player might be cheating (I do this frequently when debugging code changes and can't be bothered to get hurt).

 

In order to do this properly, we'd need a new script event to tell the player code when the potion effect starts and ends. Then the internal crash landing code can query that flag and skip the damage if it's on.

Link to comment
Share on other sites

Swimming should be much improved:

 


/*
* SPEED POTION scriptobject
*/
object playertools_speedpotion : player_tools {
	/**
	* [ Comment copied from health potion script object: ]
	* greebo: This is the method that gets called from within the SDK
	*		  when the player "uses" this tool as inventory item.
	*
	* @userEntity: the entity that is using this item, usually $player1
	* @frobbedEntity: the entity the player is currently frobbing, may be $null_entity
	* @buttonState: a float telling about the current button state (pressed, released)
	*/
	void inventoryUse(player userEntity, entity frobbedEntity, float buttonState);
	void update(player userEntity);
	
	float duration;
	float speed_mod;
	float endTime;
};

/**
* =============== SPEED POTION ======================================
*/
void playertools_speedpotion::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	// Callback to decrease the inventory stack count
	userEntity.changeInvItemCount(getKey("inv_name"), getKey("inv_category"), -1);

	// Play the activate sound
	userEntity.startSoundShader(getKey("snd_swallow"), SND_CHANNEL_VOICE);
	
	duration = getFloatKey("duration");
	speed_mod = getFloatKey("speed_mod");
	
	endTime = (sys.getTime() + duration);
	
	update(userEntity);
}

void playertools_speedpotion::update(player userEntity) {
	sys.killthread("speed_potion");
	sys.threadname("speed_potion");
	
	while (sys.getTime() < endTime) {sys.wait(0.01);
		vector player_direction = userEntity.getViewAngles();
		float player_angle_h = player_direction_y;
		float player_angle_v = 0 - player_direction_x;
		vector player_movement = userEntity.getMove();
		vector player_movement_world = player_movement;
		vector boost_movement = '0 0 0';
		
		if (userEntity.AI_ONGROUND) {
			player_movement_world_x = 
				(player_movement_x * sys.cos(player_angle_h)) 
				+ (player_movement_y * sys.cos(player_angle_h-90));
			player_movement_world_y = 
				(player_movement_x * sys.sin(player_angle_h)) 
				+ (player_movement_y * sys.sin(player_angle_h-90));
			
			boost_movement_x = player_movement_world_x * speed_mod;
			boost_movement_y = player_movement_world_y * speed_mod;
		}
		else if (userEntity.isInLiquid()) {
			player_movement_world_x = 
				(player_movement_x * sys.cos(player_angle_v) * sys.cos(player_angle_h)) 
				+ (player_movement_y * sys.cos(player_angle_v) * sys.cos(player_angle_h-90));
			player_movement_world_y = 
				(player_movement_x * sys.cos(player_angle_v) * sys.sin(player_angle_h)) 
				+ (player_movement_y * sys.cos(player_angle_v) * sys.sin(player_angle_h-90));
			player_movement_world_z = 
			(player_movement_x * sys.sin(player_angle_v)) + (player_movement_y * sys.sin(player_angle_v));
			
			boost_movement_x = player_movement_world_x * speed_mod;
			boost_movement_y = player_movement_world_y * speed_mod;
			boost_movement_z = player_movement_world_z * speed_mod;
		};
		
		userEntity.applyImpulse(userEntity,0,userEntity.getOrigin(),boost_movement);
	};
}



/*
* SLOW-FALL POTION scriptobject
*/
object playertools_slowfallpotion : player_tools {
	/**
	* [ Comment copied from health potion script object: ]
	* greebo: This is the method that gets called from within the SDK
	*		  when the player "uses" this tool as inventory item.
	*
	* @userEntity: the entity that is using this item, usually $player1
	* @frobbedEntity: the entity the player is currently frobbing, may be $null_entity
	* @buttonState: a float telling about the current button state (pressed, released)
	*/
	void inventoryUse(player userEntity, entity frobbedEntity, float buttonState);
	void update(player userEntity);
	
	float duration;
	float lift_force;
	float drag_penalty;
	float endTime;
};

/**
* =============== SLOW-FALL POTION ==================================
*/
void playertools_slowfallpotion::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	// Callback to decrease the inventory stack count
	userEntity.changeInvItemCount(getKey("inv_name"), getKey("inv_category"), -1);

	// Play the activate sound
	userEntity.startSoundShader(getKey("snd_swallow"), SND_CHANNEL_VOICE);
	
	duration = getFloatKey("duration");
	lift_force = getFloatKey("lift_force");
	drag_penalty = getFloatKey("drag_penalty");
	
	userEntity.setHinderance("slowfall_potion", drag_penalty, drag_penalty);
	
	endTime = (sys.getTime() + duration);
	
	thread update(userEntity);
}

void playertools_slowfallpotion::update(player userEntity) {
	sys.killthread("slowfall_potion");
	sys.threadname("slowfall_potion");
	
	while (sys.getTime() < endTime) {sys.wait(0.01);
		vector player_movement = userEntity.getMove();
		vector boost_movement = '0 0 0';
		
		if ( (player_movement_z <= 0) && !userEntity.AI_ONGROUND && !userEntity.AI_ONLADDER) boost_movement_z = lift_force;
		userEntity.applyImpulse(userEntity,0,userEntity.getOrigin(),boost_movement);
	};
	
	userEntity.setHinderance("slowfall_potion", 1, 1);
}

 

 

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

After I have taken the slow fall potion, I am unable to fall through water/liquid

 

attachicon.gifpotion.map.txt

See my reply to grayman here. (Edit: I should have specifically said it's the speed potion's swimming behaviour I changed in the last update.)

 

Rather than literally slowing the player down, is there a way to identify damage from falls? Maybe the potion could simply reduce that damage (or eliminate it entirely if desired). That would seem to have a lot less opportunity to play poorly with other systems.

Given that both potions have a mantling-related bug, I suggest looking into that first, then seeing what state the slow-fall potion is in afterwards. It would be a shame to lose the sensation of drifting down to an enticing balcony. (Sensut's T2 FM 'Exile' on Normal gives Garrett infinite slow-fall potions; I gained a lot of appreciation for them while playing around in that.)

 

Edit:

 

Slow-fall:

- Mantle bug: upward boost after mantling. (Disappears if the potion is disabled while crouching.)

- Increased jump height? This is #2 on grayman's list from earlier. I just tested with the current script and couldn't reproduce it.

 

Speed:

- Mantle bug: forward boost after mantling out of water. (Disappears for jump-mantle if the potion is disabled while getMove() reports upward movement.)

- Wall collision damage during free-fall -- fixed?

- Problems diving -- fixed?

- Problems swimming vertically underwater -- fixed?

Edited by VanishedOne

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

Based on SteveL's suggestion, we have a possible fix for the mantling problem.

 

/*
* SPEED POTION scriptobject
*/
object playertools_speedpotion : player_tools {
	/**
	* [ Comment copied from health potion script object: ]
	* greebo: This is the method that gets called from within the SDK
	*		  when the player "uses" this tool as inventory item.
	*
	* @userEntity: the entity that is using this item, usually $player1
	* @frobbedEntity: the entity the player is currently frobbing, may be $null_entity
	* @buttonState: a float telling about the current button state (pressed, released)
	*/
	void inventoryUse(player userEntity, entity frobbedEntity, float buttonState);
	void update(player userEntity);
	
	float duration;
	float speed_mod;
	float endTime;
};

/**
* =============== SPEED POTION ======================================
*/
void playertools_speedpotion::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	// Callback to decrease the inventory stack count
	userEntity.changeInvItemCount(getKey("inv_name"), getKey("inv_category"), -1);

	// Play the activate sound
	userEntity.startSoundShader(getKey("snd_swallow"), SND_CHANNEL_VOICE);
	
	duration = getFloatKey("duration");
	speed_mod = getFloatKey("speed_mod");
	
	endTime = (sys.getTime() + duration);
	
	update(userEntity);
}

void playertools_speedpotion::update(player userEntity) {
	sys.killthread("speed_potion");
	sys.threadname("speed_potion");
	
	while (sys.getTime() < endTime) {sys.wait(0.01);
		vector player_direction = userEntity.getViewAngles();
		float player_angle_h = player_direction_y;
		float player_angle_v = 0 - player_direction_x;
		vector player_movement = userEntity.getMove();
		vector player_movement_world = player_movement;
		vector boost_movement = '0 0 0';
		
		if ( userEntity.getImmobilization( "MantleMove" ) != 0 ) continue;
		
		if (userEntity.AI_ONGROUND) {
			player_movement_world_x = 
				(player_movement_x * sys.cos(player_angle_h)) 
				+ (player_movement_y * sys.cos(player_angle_h-90));
			player_movement_world_y = 
				(player_movement_x * sys.sin(player_angle_h)) 
				+ (player_movement_y * sys.sin(player_angle_h-90));
			
			boost_movement_x = player_movement_world_x * speed_mod;
			boost_movement_y = player_movement_world_y * speed_mod;
		}
		else if (userEntity.isInLiquid()) {
			player_movement_world_x = 
				(player_movement_x * sys.cos(player_angle_v) * sys.cos(player_angle_h)) 
				+ (player_movement_y * sys.cos(player_angle_v) * sys.cos(player_angle_h-90));
			player_movement_world_y = 
				(player_movement_x * sys.cos(player_angle_v) * sys.sin(player_angle_h)) 
				+ (player_movement_y * sys.cos(player_angle_v) * sys.sin(player_angle_h-90));
			player_movement_world_z = 
			(player_movement_x * sys.sin(player_angle_v)) + (player_movement_y * sys.sin(player_angle_v));
			
			boost_movement_x = player_movement_world_x * speed_mod;
			boost_movement_y = player_movement_world_y * speed_mod;
			boost_movement_z = player_movement_world_z * speed_mod;
		};
		
		userEntity.applyImpulse(userEntity,0,userEntity.getOrigin(),boost_movement);
	};
}



/*
* SLOW-FALL POTION scriptobject
*/
object playertools_slowfallpotion : player_tools {
	/**
	* [ Comment copied from health potion script object: ]
	* greebo: This is the method that gets called from within the SDK
	*		  when the player "uses" this tool as inventory item.
	*
	* @userEntity: the entity that is using this item, usually $player1
	* @frobbedEntity: the entity the player is currently frobbing, may be $null_entity
	* @buttonState: a float telling about the current button state (pressed, released)
	*/
	void inventoryUse(player userEntity, entity frobbedEntity, float buttonState);
	void update(player userEntity);
	
	float duration;
	float lift_force;
	float drag_penalty;
	float endTime;
};

/**
* =============== SLOW-FALL POTION ==================================
*/
void playertools_slowfallpotion::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	// Callback to decrease the inventory stack count
	userEntity.changeInvItemCount(getKey("inv_name"), getKey("inv_category"), -1);

	// Play the activate sound
	userEntity.startSoundShader(getKey("snd_swallow"), SND_CHANNEL_VOICE);
	
	duration = getFloatKey("duration");
	lift_force = getFloatKey("lift_force");
	drag_penalty = getFloatKey("drag_penalty");
	
	userEntity.setHinderance("slowfall_potion", drag_penalty, drag_penalty);
	
	endTime = (sys.getTime() + duration);
	
	thread update(userEntity);
}

void playertools_slowfallpotion::update(player userEntity) {
	sys.killthread("slowfall_potion");
	sys.threadname("slowfall_potion");
	
	while (sys.getTime() < endTime) {sys.wait(0.01);
		vector player_movement = userEntity.getMove();
		vector boost_movement = '0 0 0';
		
		if ( userEntity.getImmobilization( "MantleMove" ) != 0 ) continue;
		
		if ( (player_movement_z <= 0) && !userEntity.AI_ONGROUND && !userEntity.AI_ONLADDER) boost_movement_z = lift_force;
		userEntity.applyImpulse(userEntity,0,userEntity.getOrigin(),boost_movement);
	};
	
	userEntity.setHinderance("slowfall_potion", 1, 1);
}

 

 

Edited by VanishedOne

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

  • 3 months later...

I've finally found why I couldn't reproduce the reported high jumps for the slow-fall potion: its behaviour changes depending on whether you tap or hold the jump button (because the script avoids boosting while you're jumping precisely to prevent high jumps), which can also stop it working at all. Looks as though I'll have to track the player's position. I'll post a fixed version later (and remove slowed walk speed while I'm at it, since the only person who commented on that dislikes it).

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

Okay, the fixed slow-fall potion (def. and script) is here. Moonjumping should no longer be possible; as a side-effect, being boosted out of deep water is no longer quite so dramatic. Walk-speed hindrance is removed.

Edited by VanishedOne

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

  • 9 months later...

I found I hadn't fully prevented dolphin-jumping out of water with the speed potion, so I've weakened the speed boost when in liquid: it's now halved, which still gives a noticeable speed-up but gives only a small vertical boost to exiting water, comparable to the current slow-fall potion (in standard water density at any rate). Also the underwater speed-up now works with the jump button again. Updated script and def. are on the other thread for anyone who wants them.

Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • OrbWeaver

      Does anyone actually use the Normalise button in the Surface inspector? Even after looking at the code I'm not quite sure what it's for.
      · 1 reply
    • Ansome

      Turns out my 15th anniversary mission idea has already been done once or twice before! I've been beaten to the punch once again, but I suppose that's to be expected when there's over 170 FMs out there, eh? I'm not complaining though, I love learning new tricks and taking inspiration from past FMs. Best of luck on your own fan missions!
      · 4 replies
    • The Black Arrow

      I wanna play Doom 3, but fhDoom has much better features than dhewm3, yet fhDoom is old, outdated and probably not supported. Damn!
      Makes me think that TDM engine for Doom 3 itself would actually be perfect.
      · 6 replies
    • Petike the Taffer

      Maybe a bit of advice ? In the FM series I'm preparing, the two main characters have the given names Toby and Agnes (it's the protagonist and deuteragonist, respectively), I've been toying with the idea of giving them family names as well, since many of the FM series have named protagonists who have surnames. Toby's from a family who were usually farriers, though he eventually wound up working as a cobbler (this serves as a daylight "front" for his night time thieving). Would it make sense if the man's popularly accepted family name was Farrier ? It's an existing, though less common English surname, and it directly refers to the profession practiced by his relatives. Your suggestions ?
      · 9 replies
    • nbohr1more

      Looks like the "Reverse April Fools" releases were too well hidden. Darkfate still hasn't acknowledge all the new releases. Did you play any of the new April Fools missions?
      · 5 replies
×
×
  • Create New...