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

    • Ansome

      Finally got my PC back from the shop after my SSD got corrupted a week ago and damaged my motherboard. Scary stuff, but thank goodness it happened right after two months of FM development instead of wiping all my work before I could release it. New SSD, repaired Motherboard and BIOS, and we're ready to start working on my second FM with some added version control in the cloud just to be safe!
      · 0 replies
    • Petike the Taffer  »  DeTeEff

      I've updated the articles for your FMs and your author category at the wiki. Your newer nickname (DeTeEff) now comes first, and the one in parentheses is your older nickname (Fieldmedic). Just to avoid confusing people who played your FMs years ago and remember your older nickname. I've added a wiki article for your latest FM, Who Watches the Watcher?, as part of my current updating efforts. Unless I overlooked something, you have five different FMs so far.
      · 0 replies
    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 4 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
×
×
  • Create New...