tAPI [Discontinued] tAPI - A Mod To Make Mods

Status
Not open for further replies.
Whenever I start up tAPI, it plays the short little bubbly sound effect like it just started up, but nothing happens other than that. After looking through the changelogs, I get this...

System.NullReferenceException: Object reference not set to an instance of an object.
at LitJson.JsonData.op_Explicit(LitJson.JsonData data)
at Terraria.Main.OpenSettings()
at Terraria.Main.Initialize()
at Microsoft.Xna.Framework.Game.RunGame(System.Boolean useBlockingRun)
at Terraria.Program.Main(System.String[] args)
 
Whenever I start up tAPI, it plays the short little bubbly sound effect like it just started up, but nothing happens other than that. After looking through the changelogs, I get this...

System.NullReferenceException: Object reference not set to an instance of an object.
at LitJson.JsonData.op_Explicit(LitJson.JsonData data)
at Terraria.Main.OpenSettings()
at Terraria.Main.Initialize()
at Microsoft.Xna.Framework.Game.RunGame(System.Boolean useBlockingRun)
at Terraria.Program.Main(System.String[] args)
Try to remove "Config.json" from "My Documents\My Games\Terraria\tAPI".
 
One small question here. How does one edit a vanilla item to be craftable? I.e making for example worm bait possible to craft?
 
One small question here. How does one edit a vanilla item to be craftable? I.e making for example worm bait possible to craft?
Code:
Recipe r = new Recipe();
r.createItem.SetDefaults("<item name>");
r.createItem.stack = <output stack>;

r.requiredItem.Add(new Item());
r.requiredItem[0].SetDefaults("<item name>");
r.requiredItem[0].stack = <required stack>;

r.requiredItem.Add(new Item());
r.requiredItem[1].SetDefaults("<item name>");
r.requiredItem[1].stack = <required stack>;
// etc

r.AddToGame();
 
Code:
Recipe r = new Recipe();
r.createItem.SetDefaults("<item name>");
r.createItem.stack = <output stack>;

r.requiredItem.Add(new Item());
r.requiredItem[0].SetDefaults("<item name>");
r.requiredItem[0].stack = <required stack>;

r.requiredItem.Add(new Item());
r.requiredItem[1].SetDefaults("<item name>");
r.requiredItem[1].stack = <required stack>;
// etc

r.AddToGame();
Thanks.
EDIT: Since I don't know what language this code is used, I have no idea how to implement a crafting recipe. (I've tried .cs/.json and obviously none of those worked.)
 
Last edited:
How can I get an accessory to appear on the body without tearing off the player's Shirt? I'm trying to make accessories visible like shields are
 
Thanks.
EDIT: Since I don't know what language this code is used, I have no idea how to implement a crafting recipe. (I've tried .cs/.json and obviously none of those worked.)
Read last few pages, it was discussed already. JSON is not a programming language. The only PL officially supported by tAPI/Terraria is C#.
 
Having more trouble with my AI,
Code:
  public override void DealtPlayer(Player player, int hitDir, int dmgDealt, bool crit)
  {
  npc.ai[3] = 0; // reset boredom when it hits a player.
  }
is not working properly(mp). if you get it to flee, bounce off a wall, then walk through you, the local version correctly cools down boredom and goes to chasing. But the server version kicks in a few ticks later and it is still fleeing. So DealtPlayer isn't called serverside? then what good is it? And how should I fix this?

I attached the critter's code. Uses basemod.
My beloved panther still needs help!
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

using TAPI;
using Terraria;
using BaseMod;

namespace PostHardModeJungle.NPCs
{
  public class Black_Panther : ModNPC
  {
  private Random my_rand;
  public override void Initialize()
  {
  Random my_rand = BaseMod.BaseAI.GetSyncedRand(npc);
  }

  /* in .json:
  *  animationType= type of creature with same frames/animations (or handle manually with custom FindFrame(); npc.spriteDirection must be set there or in AI() as well)
  *  frameCount=as creature with same frames/animations; Main.npcFrameCount[npc.type]
  *  aiStyle=-1, or else it will run that AI() in addition to yours
  *
  *  ai[0]: facing change delay; when fleeing, cannot change facing due to collision 2 ticks in a row
  *  ai[1]: state
  *  ai[2]: pounce cooldown - counts down
  *  ai[3]: 'bored' if at/over boredom_time: creature will ignore player and attempt to leave
  *  -inc if stopped, at/over boredom_time, or moonwalking
  *  -dec if less than boredom_time and near fullspeed
  *  -zero if more than boredom_cooldown or justhit
  *  -netupdate at exactly boredom_time (whenever boredom state changes to bored)
  */
  enum State { stalking, pouncing, chasing, start_fleeing, fleeing };
  public override void AI()
  {
  if (Main.rand.Next(60) == 0) Main.NewText("npc.direction = " + npc.direction + ", boredom = " + npc.ai[3]);
  #region load state
  State state = State.stalking; // need to initialaze; value not meaningful yet

  if (npc.ai[1] == 0) state = State.stalking;
  else if (npc.ai[1] == 1) state = State.pouncing;
  else if (npc.ai[1] == 2) state = State.chasing;
  else if (npc.ai[1] == 3) state = State.start_fleeing;
  else if (npc.ai[1] == 4) state = State.fleeing;
  #endregion
  #region set up NPC's attributes & behaviors
  const int boredom_time = 300; // time until it stops targeting player if blocked etc
  int boredom_cooldown = 10 * boredom_time; // boredom level where boredom wears off; usually 10*boredom_time

  const bool tenacious = false; // won't get bored if near target.
  const float tenacious_range = 200; // what's considered 'near'

  const bool hops = false; // hops when close to target like Wolf and Hellhound
  const float hop_velocity = 3; // forward velocity needed to initiate hopping; usually 3
  const float hop_range = 100; // less than this is 'close to target'; usually 100
  const float hop_power = 4; // how hard/high offensive hops are; usually 4

  float acceleration = .07f; // how fast it can speed up
  float top_speed = 6; // max walking speed
  const float braking_power = .2f; // %of speed that can be shed every tick when above max walking speed
  const float pounce_range = 200;
  const int pounce_cooldown = 180; // time to reload after starting a pounce
  const int min_pounce = 30; // can try another pounce immediately if pounce ends within this time

  const bool fast_cornering = false; // change direction quickly like Wolf, Hellhound, and Headless Horseman
  const float fast_cornering_power = .05f; // is a braking percentage

  const bool explosive_start = false; // extra acceleration when not near top speed like Hellhound
  const float explosive_start_power = .1f; // how fast it can speed up

  const bool hates_moonwalking = true; // gets bored at double rate from moonwalking, like unicorn ai types
  bool moonwalking = false; // not jump/fall and moving backwards to facing
  if (npc.velocity.Y == 0f && ((npc.velocity.X > 0f && npc.direction < 0) || (npc.velocity.X < 0f && npc.direction > 0)))
  moonwalking = true;

  npc.TargetClosest(false); // acquire but don't face
  float npc_to_target_x = Main.player[npc.target].position.X + (float)Main.player[npc.target].width * 0.5f - npc.Center.X; // x vector to target
  float npc_to_target_y = Main.player[npc.target].position.Y + (float)Main.player[npc.target].height * 0.5f - npc.Center.Y; // y vector to target
  float target_dist = (float)Math.Sqrt((double)(npc_to_target_x * npc_to_target_x + npc_to_target_y * npc_to_target_y)); // distance to target
  bool facing_target = (npc_to_target_x > 0 && npc.spriteDirection == 1) || (npc_to_target_x < 0 && npc.spriteDirection == -1);
  bool moving_forward = (npc.velocity.X < 0f && npc.spriteDirection == -1) || (npc.velocity.X > 0f && npc.spriteDirection == 1);
  bool moving_backward = (npc.velocity.X > 0f && npc.spriteDirection == -1) || (npc.velocity.X < 0f && npc.spriteDirection == 1);

  float light_level = Lighting.Brightness((int)npc.Center.X >> 4, (int)npc.Center.Y >> 4);
  int tile_type = (int)Main.tile[(int)npc.Center.X >> 4, (int)npc.Center.Y >> 4].type;  // type of tile it's on
  float pounce_power = 8;
  pounce_power = pounce_power - npc_to_target_y * .02f; // increase pounce power with distance
  if (pounce_power < 5f) pounce_power = 5f;
  if (pounce_power > 12f) pounce_power = 12f;
  #endregion
  #region check if standing on a solid tile
  bool standing_on_solid_tile = false;
  if (npc.velocity.Y == 0f) // no jump/fall
  {
  int y_below_feet = (int)(npc.position.Y + (float)npc.height + 7f) / 16;
  int x_left_edge = (int)npc.position.X / 16;
  int x_right_edge = (int)(npc.position.X + (float)npc.width) / 16;
  for (int l = x_left_edge; l <= x_right_edge; l++) // check every block under feet
  {
  if (Main.tile[l, y_below_feet] == null) // null tile means ??
  Main.tile[l, y_below_feet] = new Tile(); // ?? this was return; in fighter AI, but saw this done elsewhere

  if (Main.tile[l, y_below_feet].nactive() && TileDef.solid[(int)Main.tile[l, y_below_feet].type]) // tile exists and is solid
  {
  standing_on_solid_tile = true;
  break; // one is enough so stop checking
  }
  } // END traverse blocks under feet
  } // END no jump/fall
  #endregion
  #region state effects and transitions
  bool elgible_to_jump = (npc.velocity.Y == 0f && standing_on_solid_tile && moving_forward); // same requirements as jump code
  if (npc.ai[2] > 0) npc.ai[2]--; // cool down pounce
  #region stalking
  if (state == State.stalking)
  {
  npc.color = new Color(0, 0, 255, 0); // blue

  npc.damage = 65; // normal dmg
  npc.alpha = 255 - (int)(64f * light_level); // low visibility
  acceleration = .04f; // slow speed
  top_speed = 1; // slow top speed

  if (npc.ai[2] <= 0 && target_dist <= pounce_range && elgible_to_jump && facing_target) // stalking -> pouncing
  { // if pounce rdy, target nearby, rdy to jump, facing target -> pounce
  Main.NewText("stalking -> pouncing");

  state = State.pouncing;
  npc.velocity.X = 2 * npc.spriteDirection; // jump towards player
  npc.velocity.Y = -pounce_power; // jump power
  npc.ai[2] = pounce_cooldown;
  npc.ai[3] = 0f; // not bored
  npc.netUpdate = true;
  }
  }
  #endregion
  #region  pouncing
  else if (state == State.pouncing)
  {
  npc.color = new Color(255, 0, 0, 0); // red

  npc.damage = 130; // bonus dmg
  npc.alpha = 128 - (int)(128f * light_level); // mostly visible
  acceleration = .10f; // normal speed
  top_speed = 4; // limited top speed - because of midair accel this determines pounce power in x direction

  if ((target_dist <= pounce_range + 100) && (npc.ai[3] < (float)boredom_time) && ((npc_to_target_y < -80 && (tile_type == 5 || tile_type == 323)) || (elgible_to_jump && facing_target && (npc.ai[2] > pounce_cooldown - min_pounce))) ) // pouncing -> re-pouncing
  { // target nearby, not bored, ((target above npc, there is a tree to boost off of)or(rdy to jump, facing target, pounced recently)) -> re-pounce/re-jump
  Main.NewText("pouncing -> re-pouncing");

  npc.TargetClosest(true); // target & face closest player
  npc.spriteDirection = npc.direction; // face player
  npc.velocity.X = 2 * npc.spriteDirection; // jump towards player
  npc.velocity.Y = -pounce_power; // jump power
  npc.netUpdate = true;
  }
  else if (((npc.velocity.Y == 0f && standing_on_solid_tile) || npc.ai[2] <= 0)) // pouncing -> chasing
  { // if landed after pounce or pounce entirely cooled down -> end pounce
  Main.NewText("pouncing -> chasing");

  state = State.chasing;
  }
  }
  #endregion
  #region chasing
  else if (state == State.chasing)
  {
  if (npc.ai[3] >= (float)boredom_time) npc.color = new Color(0, 255, 255, 0); // cyan
  else npc.color = new Color(0, 255, 0, 0); // green

  npc.damage = 65; // normal dmg
  npc.alpha = 128 - (int)(128f * light_level); // mostly visible
  acceleration = .10f; // normal speed
  top_speed = 6; // normal top speed

  if (npc.ai[2] <= 0 && target_dist <= pounce_range && npc.velocity.Y == 0f && standing_on_solid_tile && facing_target && !moving_backward) // chasing -> pouncing
  { // if pounce rdy, target nearby, no jump/fall, facing target, moving forward -> pounce
  /*Main.NewText("chasing -> pouncing");

  state = State.pouncing;
  if (npc.velocity.X < 2 * npc.spriteDirection) npc.velocity.X = 2 * npc.spriteDirection; // jump towards player
  npc.velocity.Y = -pounce_power; // jump power
  npc.ai[2] = pounce_cooldown;
  npc.netUpdate = true;//*/
  }
  else if ((target_dist <= pounce_range + 100) && (npc.ai[3] < (float)boredom_time) && (npc_to_target_y < -80) && (tile_type == 5 || tile_type == 323) ) // chasing(jumping) -> reflect off tree -> jumping/pouncing
  { // target nearby, not bored, target above npc, there is a tree to boost off of -> re-pounce/re-jump
  /*Main.NewText("chasing(jumping) -> reflect off tree -> jumping/pouncing");

  if (npc.ai[2] <= 0) { state = State.pouncing; npc.ai[2] = pounce_cooldown; } // make it a pounce if possible
  npc.TargetClosest(true); // target & face closest player
  npc.spriteDirection = npc.direction; // face player
  npc.velocity.X = 2 * npc.spriteDirection; // jump towards player
  npc.velocity.Y = -pounce_power; // jump power
  npc.netUpdate = true;//*/
  }
  else if (npc.justHit)// && npc.ai[3] < (float)boredom_time)// && my_rand.Next(5) == 0) // chasing -> start_fleeing
  { // hit, not bored, 20% chance
  Main.NewText("chasing -> start_fleeing");

  state = State.start_fleeing;
  npc.TargetClosest(true); // target & face closest player
  npc.direction = -npc.direction; // turn around(presumably away from player)
  npc.ai[0] = 0f; // facing change delay
  npc.ai[3] = (float)boredom_time + 1; // bored(stop chasing)
  npc.netUpdate = true;//*/
  }
  else if (npc.ai[3] >= (float)boredom_time && target_dist > 400) // chasing -> stalking
  { // bored & no player on screen
  /*Main.NewText("chasing -> stalking");

  state = State.stalking;//*/
  }
  }
  #endregion
  #region start_fleeing
  else if (state == State.start_fleeing) // jump once, presumably away from player
  {
  npc.color = new Color(192, 192, 0, 0); // dk yellow

  npc.ai[3] = (float)boredom_time + 1; // bored(stop chasing)

  npc.damage = 65; // normal dmg
  npc.alpha = 128 - (int)(128f * light_level); // mostly visible
  acceleration = .10f; // normal speed
  top_speed = 6; // normal top speed

  if (elgible_to_jump) // start_fleeing -> jump away -> fleeing
  {
  Main.NewText("start_fleeing -> jump away -> fleeing");

  state = State.fleeing;
  npc.velocity.X = 1 * npc.spriteDirection; // jump away from player
  npc.velocity.Y = -5; // jump power
  npc.ai[2] = pounce_cooldown;
  npc.netUpdate = true;
  }
  }
  #endregion
  #region fleeing
  else if (state == State.fleeing) // run away for a bit
  {
  npc.color = new Color(255, 255, 0, 0); // yellow

  npc.damage = 65; // normal dmg
  npc.alpha = 128 - (int)(128f * light_level); // mostly visible
  acceleration = .10f; // normal speed
  top_speed = 6; // normal top speed

  if (npc.ai[3] < (float)boredom_time) // fleeing -> chasing
  { // not bored
  Main.NewText("fleeing -> chasing");

  state = State.chasing;
  }
  }
  #endregion
  #endregion
  #region adjust boredom level
  if (hates_moonwalking && (moonwalking && state != State.pouncing))
  npc.ai[3] += 1f; // unicorns hate moonwalking

  if (npc.position.X == npc.oldPosition.X || npc.ai[3] >= (float)boredom_time || (moonwalking && state != State.pouncing)) // stuck,bored,moonwalking
  npc.ai[3] += 1f; // add boredom
  else if (npc.ai[3] > 0f)
  npc.ai[3] -= 1f; // recover from boredom

  //if ((npc.justHit && !(state == State.start_fleeing || state == State.fleeing)) || npc.ai[3] > boredom_cooldown) // hit(& not fleeing) or cooled down
  //  npc.ai[3] = 0f;

  if (npc.ai[3] == (float)boredom_time) // just became bored
  npc.netUpdate = true; // ?
  #endregion
  #region handle tenacious and hop
  float npc_to_targets_head_y = Main.player[npc.target].position.Y - npc.Center.Y;
  float target_head_dist = (float)Math.Sqrt((double)(npc_to_target_x * npc_to_target_x + npc_to_targets_head_y * npc_to_targets_head_y));

  if (tenacious && target_head_dist < tenacious_range)
  npc.ai[3] = 0f; // won't get bored if near target.

  if (hops && npc.velocity.Y == 0f && target_head_dist < hop_range && Math.Abs(npc.velocity.X) > hop_velocity && ((npc.position.X + (float)(npc.width / 2) < Main.player[npc.target].position.X + (float)(Main.player[npc.target].width / 2) && npc.velocity.X > 0f) || (npc.position.X + (float)(npc.width / 2) > Main.player[npc.target].position.X + (float)(Main.player[npc.target].width / 2) && npc.velocity.X < 0f)))
  npc.velocity.Y -= hop_power; // hop when nearby
  #endregion
  #region target or be bored
  if (npc.ai[3] < (float)boredom_time) // not bored
  npc.TargetClosest(true); // target & face closest player
  else // bored
  {
  if (npc.velocity.X == 0f)
  { // possible facing change due to collision
  if (npc.velocity.Y == 0f)
  { // not moving
  npc.ai[0] += 1f; // facing change delay
  if (npc.ai[0] >= 2f)
  {
  npc.direction *= -1; // facing change
  npc.spriteDirection = npc.direction;
  npc.ai[0] = 0f;
  }
  }
  } // END possible facing change due to collision
  else // bored, moving in x
  npc.ai[0] = 0f; // reset facing change delay

  npc.directionY = -1; // upwards?
  if (npc.direction == 0) // still dont know why this would be 0
  npc.direction = 1; // or why to only fix while bored
  } // end bored
  #endregion
  #region melee movement
  if (npc.velocity.Y == 0f || npc.wet || (npc.velocity.X <= 0f && npc.direction < 0) || (npc.velocity.X >= 0f && npc.direction > 0))
  { // no fall/jump(traction?) or wet(swimming?) or moving forward(unicorn rocket boosters?)
  if (fast_cornering && ((npc.velocity.X > 0f && npc.direction < 0) || (npc.velocity.X < 0f && npc.direction > 0))) // extra braking, faster turns?
  npc.velocity.X = npc.velocity.X * (1 - fast_cornering_power); // braking

  if (explosive_start && ((float)npc.direction * npc.velocity.X < top_speed / 2)) // extra acceleration when not near top speed
  npc.velocity.X += explosive_start_power * npc.direction; // acceleration

  if (Math.Abs(npc.velocity.X) > top_speed)  //  running/flying faster than top speed
  {
  if (npc.velocity.Y == 0f) // no jump/fall
  npc.velocity *= (1f - braking_power); // decelerate
  }
  else if ((npc.velocity.X < top_speed && npc.direction == 1) || (npc.velocity.X > -top_speed && npc.direction == -1)) // below top speed
  {
  npc.velocity.X += (float)npc.direction * acceleration;  //  accellerate fwd; can happen midair
  if ((float)npc.direction * npc.velocity.X > top_speed)
  npc.velocity.X = (float)npc.direction * top_speed;  //  but cap at top speed
  }
  } // END no fall/jump or wet or moving forward
  #endregion
  #region walk up half and single bricks
  if (npc.velocity.Y >= 0f) // not rising
  {
  int move_dir = 0;
  if (npc.velocity.X < 0f)
  move_dir = -1;
  if (npc.velocity.X > 0f)
  move_dir = 1;

  Vector2 next_pos = npc.position;
  next_pos.X += npc.velocity.X;
  int x_in_front = (int)((next_pos.X + (float)(npc.width / 2) + (float)((npc.width / 2 + 1) * move_dir)) / 16f);
  int y_of_feet = (int)((next_pos.Y + (float)npc.height - 1f) / 16f);
  if (Main.tile[x_in_front, y_of_feet] == null)
  Main.tile[x_in_front, y_of_feet] = new Tile();
  if (Main.tile[x_in_front, y_of_feet - 1] == null)
  Main.tile[x_in_front, y_of_feet - 1] = new Tile();
  if (Main.tile[x_in_front, y_of_feet - 2] == null)
  Main.tile[x_in_front, y_of_feet - 2] = new Tile();
  if (Main.tile[x_in_front, y_of_feet - 3] == null)
  Main.tile[x_in_front, y_of_feet - 3] = new Tile();
  if (Main.tile[x_in_front, y_of_feet + 1] == null)
  Main.tile[x_in_front, y_of_feet + 1] = new Tile();
  if ((float)(x_in_front * 16) < next_pos.X + (float)npc.width && (float)(x_in_front * 16 + 16) > next_pos.X && ((Main.tile[x_in_front, y_of_feet].nactive() && !Main.tile[x_in_front, y_of_feet].topSlope() && !Main.tile[x_in_front, y_of_feet - 1].topSlope() && TileDef.solid[(int)Main.tile[x_in_front, y_of_feet].type] && !TileDef.solidTop[(int)Main.tile[x_in_front, y_of_feet].type]) || (Main.tile[x_in_front, y_of_feet - 1].halfBrick() && Main.tile[x_in_front, y_of_feet - 1].nactive())) && (!Main.tile[x_in_front, y_of_feet - 1].nactive() || !TileDef.solid[(int)Main.tile[x_in_front, y_of_feet - 1].type] || TileDef.solidTop[(int)Main.tile[x_in_front, y_of_feet - 1].type] || (Main.tile[x_in_front, y_of_feet - 1].halfBrick() && (!Main.tile[x_in_front, y_of_feet - 4].nactive() || !TileDef.solid[(int)Main.tile[x_in_front, y_of_feet - 4].type] || TileDef.solidTop[(int)Main.tile[x_in_front, y_of_feet - 4].type]))) && (!Main.tile[x_in_front, y_of_feet - 2].nactive() || !TileDef.solid[(int)Main.tile[x_in_front, y_of_feet - 2].type] || TileDef.solidTop[(int)Main.tile[x_in_front, y_of_feet - 2].type]) && (!Main.tile[x_in_front, y_of_feet - 3].nactive() || !TileDef.solid[(int)Main.tile[x_in_front, y_of_feet - 3].type] || TileDef.solidTop[(int)Main.tile[x_in_front, y_of_feet - 3].type]) && (!Main.tile[x_in_front - move_dir, y_of_feet - 3].nactive() || !TileDef.solid[(int)Main.tile[x_in_front - move_dir, y_of_feet - 3].type]))
  { // if there's a brick to potentially climb up
  float y_of_step = (float)(y_of_feet * 16);
  if (Main.tile[x_in_front, y_of_feet].halfBrick())
  y_of_step += 8f;
  if (Main.tile[x_in_front, y_of_feet - 1].halfBrick())
  y_of_step -= 8f;

  if (y_of_step < next_pos.Y + (float)npc.height) // if step is above feet
  {
  float step_length = next_pos.Y + (float)npc.height - y_of_step;
  if ((double)step_length <= 16.1) // close enough to make it up (can climb one block length)
  {
  npc.gfxOffY += npc.position.Y + (float)npc.height - y_of_step;
  npc.position.Y = y_of_step - (float)npc.height; // climb onto step
  if (step_length < 9f)
  npc.stepSpeed = 1f;
  else
  npc.stepSpeed = 2f;
  }
  }
  }
  }
  #endregion
  #region new Tile()s, jumping
  if (npc.velocity.Y == 0f && standing_on_solid_tile) // no fall/jump
  {
  int x_in_front = (int)((npc.position.X + (float)(npc.width / 2) + (float)((npc.width / 2 + 2) * npc.direction) + npc.velocity.X * 5f) / 16f);
  int y_above_feet = (int)((npc.position.Y + (float)npc.height - 15f) / 16f); // 15 pix above feet

  if (Main.tile[x_in_front, y_above_feet] == null)
  Main.tile[x_in_front, y_above_feet] = new Tile();

  if (Main.tile[x_in_front, y_above_feet - 1] == null)
  Main.tile[x_in_front, y_above_feet - 1] = new Tile();

  if (Main.tile[x_in_front, y_above_feet - 2] == null)
  Main.tile[x_in_front, y_above_feet - 2] = new Tile();

  if (Main.tile[x_in_front, y_above_feet - 3] == null)
  Main.tile[x_in_front, y_above_feet - 3] = new Tile();

  if (Main.tile[x_in_front, y_above_feet + 1] == null)
  Main.tile[x_in_front, y_above_feet + 1] = new Tile();

  if (Main.tile[x_in_front + npc.direction, y_above_feet - 1] == null)
  Main.tile[x_in_front + npc.direction, y_above_feet - 1] = new Tile();

  if (Main.tile[x_in_front + npc.direction, y_above_feet + 1] == null)
  Main.tile[x_in_front + npc.direction, y_above_feet + 1] = new Tile();

  if (Main.tile[x_in_front - npc.direction, y_above_feet + 1] == null)
  Main.tile[x_in_front - npc.direction, y_above_feet + 1] = new Tile();

  if (moving_forward)
  {  //  moving forward: various jumping
  if (Main.tile[x_in_front, y_above_feet - 2].nactive() && TileDef.solid[(int)Main.tile[x_in_front, y_above_feet - 2].type])
  { // 3 blocks above ground level(head height) blocked
  if (Main.tile[x_in_front, y_above_feet - 3].nactive() && TileDef.solid[(int)Main.tile[x_in_front, y_above_feet - 3].type])
  { // 4 blocks above ground level(over head) blocked
  if (state == State.stalking) npc.velocity.Y = -8f;
  else npc.velocity.Y = -8.5f; // jump with power 8.5 (for 4 block steps)
  npc.netUpdate = true;
  goto Jump_End;
  }
  if (state == State.stalking) npc.velocity.Y = -7f;
  else npc.velocity.Y = -7.5f; // jump with power 7.5 (for 3 block steps)
  npc.netUpdate = true;
  goto Jump_End;
  } // for everything else, head height clear:
  else
  {
  if (Main.tile[x_in_front, y_above_feet - 1].nactive() && !Main.tile[x_in_front, y_above_feet - 1].topSlope() && TileDef.solid[(int)Main.tile[x_in_front, y_above_feet - 1].type])
  { // 2 blocks above ground level(mid body height) blocked
  if (state == State.stalking) npc.velocity.Y = -6f;
  else npc.velocity.Y = -7f; // jump with power 7 (for 2 block steps)
  npc.netUpdate = true;
  goto Jump_End;
  }
  if (npc.position.Y + (float)npc.height - (float)(y_above_feet * 16) > 20f && Main.tile[x_in_front, y_above_feet].nactive() && !Main.tile[x_in_front, y_above_feet].topSlope() && TileDef.solid[(int)Main.tile[x_in_front, y_above_feet].type])
  { // 1? block above ground level(foot height) blocked?
  if (state == State.stalking) npc.velocity.Y = -5f;
  else npc.velocity.Y = -6f; // jump with power 6 (for 1 block steps)
  npc.netUpdate = true;
  goto Jump_End;
  }
  if ((npc.directionY < 0 || Math.Abs(npc.velocity.X) > 3f) && (!Main.tile[x_in_front, y_above_feet + 2].nactive() || !TileDef.solid[(int)Main.tile[x_in_front, y_above_feet + 2].type]) && (!Main.tile[x_in_front + npc.direction, y_above_feet + 3].nactive() || !TileDef.solid[(int)Main.tile[x_in_front + npc.direction, y_above_feet + 3].type]))
  { // target is above & moving fast enough & no solid tile ahead to step on for 2 spaces in front
  if (state == State.stalking) npc.velocity.Y = -7f;
  else npc.velocity.Y = -8f; // jump with power 8 (to leap gaps)
  npc.netUpdate = true;
  goto Jump_End;
  }
  }
  }
  }
  Jump_End: { }
  #endregion
  #region save state
  if (state == State.stalking) npc.ai[1] = 0;
  else if (state == State.pouncing) npc.ai[1] = 1;
  else if (state == State.chasing) npc.ai[1] = 2;
  else if (state == State.start_fleeing) npc.ai[1] = 3;
  else if (state == State.fleeing) npc.ai[1] = 4;
  #endregion
  }

  public override void DealtPlayer(Player player, int hitDir, int dmgDealt, bool crit)
  {
  npc.ai[3] = 0; // reset boredom when it hits a player.
  }

  public override void SelectFrame(int currentFrame)
  {
  const int frameCount = 33, textureHeight = 2048;
  int sprite_height = textureHeight / frameCount;

  if (npc.velocity.Y == 0f || npc.wet) // no jump/fall or wet
  {
  if (npc.velocity.X < -2f) npc.spriteDirection = -1;
  else if (npc.velocity.X > 2f) npc.spriteDirection = 1;
  else npc.spriteDirection = npc.direction;
  }
  if (npc.velocity.Y != 0f) // jump/fall
  {
  npc.frame.Y = sprite_height * 32 + 2; // frame 33=jump/fall
  npc.frameCounter = 0.0;
  }
  else // no jump/fall
  {
  if (npc.velocity.X == 0f)
  {
  npc.frameCounter = 0.0;
  npc.frame.Y = 0; // frame 1=standing still
  }
  else
  {
  if (Math.Abs(npc.velocity.X) < 3f) // slow
  {
  npc.frameCounter += (double)Math.Abs(npc.velocity.X);
  while (npc.frameCounter >= 2.667) // 6.0)
  {
  npc.frameCounter -= 2.667; // 0.0;
  npc.frame.Y = npc.frame.Y + sprite_height;
  if (npc.frame.Y / sprite_height >= 19) // frame==20
  {
  npc.frame.Y = sprite_height; // reset to frame 2
  }
  if (npc.frame.Y / sprite_height <= 0) // frame 1
  {
  npc.frame.Y = sprite_height; // reset to frame 2
  }
  }
  }
  else // fast
  {
  npc.frameCounter += (double)Math.Abs(npc.velocity.X);
  while (npc.frameCounter >= 4.615) // 10.0)
  {
  npc.frameCounter -= 4.615; // 0.0;
  npc.frame.Y = npc.frame.Y + sprite_height;
  if (npc.frame.Y / sprite_height >= 32) // frame==33
  {
  npc.frame.Y = sprite_height * 19; // reset to frame 20
  }
  if (npc.frame.Y / sprite_height <= 18) // slow frame
  {
  npc.frame.Y = sprite_height * 19; // reset to frame 20
  }
  }
  }
  }
  } // END no jump/fall
  }

  }
}
I also posted full mod on the linked post. No one knows how to fix my panther yet apparently :(. To add health in mp without issues I did it via buff in tconfig. If no one knows how to approach, might adding a buff to reset boredom be a work around?
 
How can I get an accessory to appear on the body without tearing off the player's Shirt? I'm trying to make accessories visible like shields are
Just add one these to the accessory .json, You'll get what you're looking for.
Code:
"textureHandsOn": "Items/Destination/ExampleItem_Texture",
//Gloves
"textureShoes": "Items/Destination/ExampleItem_Texture",
//Boots
"textureHandsOn": "Items/Destination/ExampleItem_Texture",  
//Wrist
"textureShield": "Items/Destination/ExampleItem_Texture",
//Shield
"textureWaist": "Items/Destination/ExampleItem_Texture",
//Waist
"textureNeck": "Items/Destination/ExampleItem_Texture",
//Neck
 
So it seems my friend is having a hard time connecting to my server. We are using r14a with 1.2.4.1 terraria version, the mods are ShockahBase r3, Accessory Slots+ r1, Dynamic Difficulty, Enhanced Tooltip r2, Insight r2, Inventory Tweaks r2, Item Suffixes r3 and TheInvisibleHand. Port is forwarded and correct IP is given, do I need to edit a file somewhere to allow him to connect?
 
not sure if this is already mentioned but sometimes guide voodoo dolls have prefixes, most the prefixes make the voodoo doll blue rarity or higher, rendering it useless for WoF summoning.
 
not sure if this is already mentioned but sometimes guide voodoo dolls have prefixes, most the prefixes make the voodoo doll blue rarity or higher, rendering it useless for WoF summoning.
Guide voodoo doll is an accesory so it's no surprise it getting prefixes. It shouldn't be useless. Have you actually tried throwing it into lava?
 
Guide voodoo doll is an accesory so it's no surprise it getting prefixes. It shouldn't be useless. Have you actually tried throwing it into lava?

Throwing it into the lava when it has a blue rarity or higher does nothing, some prefixes give the voodoo doll a blue or green rarity, making it unable to be destroyed by lava, so prefixes can mess up using it for WoF summons.
 
Status
Not open for further replies.
Back
Top Bottom