Jump to content
The Dark Mod Forums
Sign in to follow this  
VanishedOne

Beta testers sought: speed potion, slow-fall potion

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

Share this post


Link to post
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.

Share this post


Link to post
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.

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Jolly good. :-) I just remembered to update the link in the OP, so for the avoidance of doubt, this is the current version of the script. If you have old versions of the defs, make sure the slow-fall potion has "lift_force" "900".


Some things I'm repeatedly thinking about...

 

- louder scream when you're dying

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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.

Sign in to follow this  

×
×
  • Create New...