Whip of taming

https://attnam.com/topics/Whip-of-taming

The Cathedral of Attnam > Other Coding

#1 Feb 6, 2014, 1:36 pm Hide

fejoa

Hey I was wondering how taming worked so I looked at the code for a bit. I've decided it might be fun to create a specialised whip I call a whip of taming.
I need to look at the code some more, but I promise I will post here again, right after I have some dinner.

I imagine mistress whip champions who are able to whip your friends into submission
#2 Feb 6, 2014, 5:29 pm Hide

fejoa

Well, I tried it out and this is the result. Not sure if it is unbalanced, but it works.
Here is the code, it is all you need:

gear.h:
ITEM(tamingwhip, whip)
{
 public:
  virtual truth HitEffect(character*, character*, v2, int, int, truth);
 protected:
  virtual truth NefasHelps(ccharacter*, ccharacter*) const;
};

gear.cpp
truth tamingwhip::HitEffect(character* Enemy, character* Hitter, v2 HitPos, int BodyPartIndex, int Direction, truth BlockedByArmour)
{
  truth BaseSuccess = meleeweapon::HitEffect(Enemy, Hitter, HitPos, BodyPartIndex, Direction, BlockedByArmour);

  if(!IsBroken() && Enemy->IsEnabled() && NefasHelps(Enemy, Hitter)) // need to work out if nefas can help
  {
    if(Enemy->IsPlayer() || Hitter->IsPlayer() || Enemy->CanBeSeenByPlayer() || Hitter->CanBeSeenByPlayer())
    {
			ADD_MESSAGE("%s whip asks for the help of Nefas as it tames %s.", Hitter->CHAR_PERSONAL_PRONOUN, Enemy->CHAR_DESCRIPTION(DEFINITE));
			if(Enemy->CanTameWithWhip(Hitter))
			{
				if(Enemy->GetTeam() == Hitter->GetTeam())
					ADD_MESSAGE("%s seems to be very happy.", Enemy->CHAR_NAME(DEFINITE));
				else if(Enemy->GetRelation(Hitter) == HOSTILE)
					ADD_MESSAGE("%s stops fighting.", Enemy->CHAR_NAME(DEFINITE));
				else
					ADD_MESSAGE("%s seems to be very friendly towards you.", Enemy->CHAR_NAME(DEFINITE));
					Enemy->ChangeTeam(Hitter->GetTeam());
			}
			else
				ADD_MESSAGE("%s refuses to be mastered by the whip.", Enemy->CHAR_NAME(DEFINITE));
		}

    if(Hitter->IsPlayer())
    {
      game::DoEvilDeed(20);
      game::GetGod(NEFAS)->AdjustRelation(10);
    }

    return true;
  }
  else
    return BaseSuccess;
}

truth tamingwhip::NefasHelps(ccharacter* Enemy, ccharacter* Hitter) const
{
  if(Hitter->IsPlayer())
  {
    if(game::GetGod(NEFAS)->GetRelation() < 0) // must have positive relation
      return false;
    else
      return !(RAND() % (20 - game::GetGod(NEFAS)->GetRelation() / 150)); // return a chance to proceed
  }
  else
    return !(RAND() % 20); // there is always a remote chance
}

char.h:
truth CanTameWithWhip(const character*) const;

char.cpp
truth character::CanTameWithWhip(const character* Tamer) const
{
  int TamingDifficulty = GetTamingDifficulty();

  if(TamingDifficulty == NO_TAMING)
    return false;

  int Modifier = Tamer->GetAttribute(DEXTERITY) + Tamer->GetAttribute(CHARISMA);

  if(Tamer->IsPlayer())
    Modifier += game::GetGod(NEFAS)->GetRelation() / 20;
  else if(Tamer->GetAttachedGod() == NEFAS)
    Modifier += 50;

  if(TamingDifficulty == 0)
    if(!IgnoreDanger())
      TamingDifficulty = int(10 * GetRelativeDanger(Tamer));
    else
      TamingDifficulty = 10 * GetHPRequirementForGeneration()
			 / Max(Tamer->GetHP(), 1);

  return Modifier >= TamingDifficulty * 3;
}

script.dat
tamingwhip /* meleeweapon->whip-> */
{
  DefaultSize = 250;
  Possibility = 10;
  DefaultMainVolume = 1200;
  DefaultSecondaryVolume = 50;
  StrengthModifier = 20;
  NameSingular = "whip of taming";
  MainMaterialConfig == BLACK_LEATHER;
  SecondaryMaterialConfig == ROSE_QUARTZ;
  Roundness = 2;
  FormModifier = 20; /* this is multiplied by MainMaterial's flexibility */
  Price = 800;
  AttachedGod = NEFAS;
  WieldedBitmapPos = 160, 224;
  EnchantmentMinusChance = 50;
  EnchantmentPlusChance = 50;
}

EDIT: Just like to say, there's an horrifyingly unbalanced bug in the above code. Here's a clue: Think about what will happen if a mistress successfully tames the player character...
#3 Feb 11, 2014, 5:21 am Hide

[Eire]MadHatter

I'm actually wondering what does happen if the player get tamed by an enemy?

Do you lose control of you character?
and the poor tamed human follows the whip mistress until he starves to death or dies from.....from.....IVAN causes?

Does the game speed up as if you've been knocked out by a blow to the head? or like when you are resting?

Does it just crash?


What if you get tamed by the whip mistress and stop attacking her....but she doesn't stop whipping you...
#4 Feb 11, 2014, 5:36 am Hide

4zb4

The player gets moved to the "team" the taming monster belongs to.
This has been used as a Wizmode exploit referred to as "diplomatic immunity" where you'd possess the Gloomy Cave shopkeeper and use him to tame the player.

Since the shopkeeper has his own team (just him and the guards) and has special properties (can't trigger aggravation from any other team except the player's) you can then re-possess the player and have him run around Attnam lopping peoples' limbs off without fear of setting off the alarm and getting slaughtered.

Speaking of, that's going to be an issue if the whip of taming is used against the player as you'd instantly be attacked when you returned to town and also the monsters would become friendly to you right down to Elpuri and Oree.
Of course an easy fix would be to add "CanBeTamed = False" or w/e the actual tag is to playerkind in the script.
#5 Feb 11, 2014, 7:38 am Hide

[Eire]MadHatter

4zb4 wrote
Of course an easy fix would be to add "CanBeTamed = False" or w/e the actual tag is to playerkind in the script.

Ah yes the char.dat file.
SPOILER ALERT. Click here to see text.
playerkind
{
DefaultArmStrength = 10;
DefaultLegStrength = 10;
DefaultDexterity = 10;
DefaultAgility = 10;
DefaultEndurance = 10;
DefaultPerception = 10;
DefaultIntelligence = 10;
DefaultWisdom = 10;
DefaultCharisma = 10;
DefaultMana = 10;
DefaultMoney = 45;
TorsoBitmapPos = 32, 416;
LegBitmapPos = 0, 416;
TotalVolume = 80000;
TotalSize = 175;
CanRead = true;
NameSingular = "human";
AttachedGod = SEGES;
DisplacePriority = 2;
Inventory == amulet(AMULET_OF_LIFE_SAVING) { Times = BONUS_LIVES; }
UndeadVersions = false;
IsRangedAttacker = false; /* AI only */
WhatCategoryToThrow = NONE;
WhatWeaponConfigToThrow = NONE;
WhatThrowItemTypesToThrow = NONE;
}


I did have a mess around with that before just to get an understand of how things tick.
I made it so my player doesn't get leprosy
as well as making it so kobold flesh doesn't make you unconscious, mutant bunnies don't randomly polymorph you into a......well a random creature...but most of the time i just get a small spider that gets stepped on by the next creature.

Also had a mess around with foods...making
banana flesh giving overfed...
bread at first made you starve to death....heh
Sulfuric acid....nothing would survive in it.

Obviously i can't count any achievement or victory legit but its nice to have a minor change
#6 Feb 11, 2014, 7:47 am Hide

4zb4

IIRC Polymorphing into a bad creature is intentional. It's something like a 75% chance to turn the caster into something better, and 25% to something terrible (e.g. large spider, puppy, carnivorous plant), and the inverse for hostiles.

If you're interested in learning to do more with the script files, check out the thread I made here alongside this guide which is also linked in that topic.
#7 Feb 11, 2014, 7:56 am Hide

[Eire]MadHatter

4zb4 wrote
If you're interested in learning to do more with the script files, check out the thread I made here alongside this guide which is also linked in that topic.

Thanks

I might as well give it a try,
since recently I learned Java.
[Creating an object Oriented computer program using Java]
As I've alot of ...once you learn a programming language its easier to learn others...
#8 Feb 11, 2014, 9:16 am Hide

4zb4

Heh, the script files are nowhere near as difficult to pick up on as Java (which should say something since Java isn't particularly tough either) so you should be fine all the way.
#9 Feb 11, 2014, 10:35 am Hide

capristo

4zb4 wrote
IIRC Polymorphing into a bad creature is intentional. It's something like a 75% chance to turn the caster into something better, and 25% to something terrible (e.g. large spider, puppy, carnivorous plant), and the inverse for hostiles.

If you're interested in learning to do more with the script files, check out the thread I made here alongside this guide which is also linked in that topic.

When you say "the caster" you mean if you zap yourself with the wand?
#10 Feb 11, 2014, 3:15 pm Hide

fejoa

4zb4 wrote
"diplomatic immunity"

Yeah, once the player character gets tamed to the monster side you go down to UT for a picnic and everyone is your friend.

You're right, the basic solution is to set TamingDifficulty = NO_TAMING; for "playerkind". Or it could be hard-coded.
Otherwise the whip of taming might be a bad idea...

EireMadHatter wrote
Obviously i can't count any achievement or victory legit but its nice to have a minor change
I use untampered vanilla 0.50 for my legit games. But I like making the odd modification too, which I do in CLIVAN. In the screenshot above, I turned the ground in New Attnam to ice (and the palm tree trunks to silver) to see how it would look. Just trying to get a feel for whether icy ground would be suitable for a new dungeon theme.
#11 Feb 11, 2014, 7:37 pm Hide

4zb4

capristo wrote
When you say "the caster" you mean if you zap yourself with the wand?

I meant whoever casts the spell. So yes, if you cast it on yourself or if a monster casts it on itself, as opposed to you casting polymorph on an enemy or a monster casting polymorph on you.
#12 Feb 11, 2014, 9:50 pm Hide

capristo

Can poly casters polymorph themselves? I guess a chameleon is polymorphing itself. No wonder they turn into golems so often