about summary refs log tree commit diff stats
path: root/data/maps/the_tower/rooms/First Floor.txtpb
blob: 7a811bf3fd182b323be090a267c190d7758600b5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
name: "First Floor"
panels {
  name: "RIDE"
  path: "Panels/Floor 1/panel_1"
  clue: "ride"
  answer: "lion"
  symbols: SPARKLES
  symbols: PLANET
}
panels {
  name: "PROD"
  path: "Panels/Floor 1/panel_2"
  clue: "prod"
  answer: "dolphin"
  symbols: SPARKLES
  symbols: PLANET
}
panels {
  name: "WARM"
  path: "Panels/Floor 1/panel_3"
  clue: "warm"
  answer: "bee"
  symbols: SPARKLES
  symbols: PLANET
}
panels {
  name: "COLLEGE"
  path: "Panels/Floor 1/panel_4"
  clue: "college"
  answer: "fish"
  symbols: EXAMPLE
  symbols: PLANET
}
panels {
  name: "HER"
  path: "Panels/Floor 1/panel_5"
  clue: "her"
  answer: "cow"
  symbols: SPARKLES
  symbols: PLANET
}
panels {
  name: "CRAM"
  path: "Panels/Floor 1/panel_6"
  clue: "cram"
  answer: "wolf"
  symbols: SUN
  symbols: PLANET
}
panels {
  name: "CUP"
  path: "Panels/Floor 1/panel_7"
  clue: "cup"
  answer: "lion"
  symbols: SPARKLES
  symbols: AGE
}
panels {
  name: "IRONY"
  path: "Panels/Floor 1/panel_8"
  clue: "irony"
  answer: "rust"
  symbols: SPARKLES
  symbols: AGE
}
panels {
  name: "IRE"
  path: "Panels/Floor 1/panel_9"
  clue: "ire"
  answer: "ash"
  symbols: SPARKLES
  symbols: AGE
}
panels {
  name: "ADULT"
  path: "Panels/Floor 1/panel_10"
  clue: "adult"
  answer: "children"
  symbols: PLANET
  symbols: AGE
}
panels {
  name: "CALF"
  path: "Panels/Floor 1/panel_11"
  clue: "calf"
  answer: "bull"
  symbols: GENDER
  symbols: AGE
}
panels {
  name: "BUTTER"
  path: "Panels/Floor 1/panel_12"
  clue: "butter"
  answer: "cram"
  symbols: SPARKLES
  symbols: EXAMPLE
}
ports {
  name: "GREAT"
  display_name: "Entrance"
  path: "Components/Warps/worldport"
  destination { x: -0 y: 0 z: 13 }
  rotation: 0
}
iteral.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * Copyright (C) 2017 hatkirby
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */
#include "serialize.h"
#include "gamedata.h"
#include "link.h"
#include "basestats.h"
#include "exptables.h"
#include "dexorder.h"

#define UNOWN_SPECIES_INDEX 201
#define SHEDINJA_SPECIES_INDEX 303

enum Stat {
  StatAttack,
  StatDefense,
  StatSpeed,
  StatSpAttack,
  StatSpDefense
};

u32 CalculateStat(
  u8 base,
  u32 iv,
  u8 ev,
  u8 level,
  u8 statIndex,
  u8 nature)
{
  u32 n = (((2 * base + iv + ev / 4) * level) / 100) + 5;

  u8 naturePlus = (nature / 5);
  u8 natureMinus = (nature % 5);

  if (naturePlus != natureMinus)
  {
    if (statIndex == naturePlus)
    {
      return (u32)(n * 110) / 100;
    } else if (statIndex == natureMinus)
    {
      return (u32)(n * 90) / 100;
    }
  }

  return n;
}

void PokemonIntermediateInit(
  struct PokemonIntermediate* pki,
  struct BoxPokemon* bpkm,
  u16 trainerId,
  u16 secretId,
  const struct GameData* gameData)
{
  DecryptBoxPokemon(bpkm);

  struct PokemonSubstruct0* sub0 = GetBoxPokemonSubstruct0(bpkm);
  struct PokemonSubstruct1* sub1 = GetBoxPokemonSubstruct1(bpkm);
  struct PokemonSubstruct2* sub2 = GetBoxPokemonSubstruct2(bpkm);
  struct PokemonSubstruct3* sub3 = GetBoxPokemonSubstruct3(bpkm);

  const struct SmallBaseStats* baseStats = &gSmallBaseStats[sub0->species];

  for (int i=0; i<POKEMON_NAME_LENGTH; i++)
  {
    pki->nickname[i] = bpkm->nickname[i];
  }

  for (int i=0; i<OT_NAME_LENGTH; i++)
  {
    pki->otName[i] = bpkm->otName[i];
  }

  pki->otId = bpkm->otId;
  pki->otGender = sub3->otGender;
  pki->species = gSpeciesToNationalPokedexNum[sub0->species - 1];
  pki->heldItem = sub0->heldItem;
  pki->experience = sub0->experience;

  pki->moves[0] = sub1->moves[0];
  pki->moves[1] = sub1->moves[1];
  pki->moves[2] = sub1->moves[2];
  pki->moves[3] = sub1->moves[3];

  pki->ppBonuses = sub0->ppBonuses;
  pki->metLevel = sub3->metLevel;
  pki->metLocation = sub3->metLocation;
  pki->pokeball = sub3->pokeball;
  pki->altAbility = sub3->altAbility;

  // Derive nature from the personality value.
  pki->nature = (bpkm->personality % 25);

  // Derive gender from the personality value.
  int genderThreshold = baseStats->genderRatio;

  if ((genderThreshold == 0) || (genderThreshold == 255))
  {
    pki->gender = 0;
  } else if (genderThreshold == 254)
  {
    pki->gender = 1;
  } else {
    u8 genderDeterminer = bpkm->personality & 0x000000FF;

    if (genderDeterminer >= genderThreshold)
    {
      pki->gender = 0;
    } else {
      pki->gender = 1;
    }
  }

  // Determine shininess from the personality value.
  u16 shinyDeterminer =
      (trainerId)
    ^ (secretId)
    ^ ((bpkm->personality >> 16) & 0x0000FFFF)
    ^ (bpkm->personality & 0x0000FFFF);

  if (shinyDeterminer < 8)
  {
    pki->shiny = 1;
  } else {
    pki->shiny = 0;
  }

  // Determine Unown letter from the personality value.
  if (sub0->species == UNOWN_SPECIES_INDEX)
  {
    u8 unownDeterminer =
        ((bpkm->personality & 0x07000000) >> 18)
      | ((bpkm->personality & 0x00070000) >> 12)
      | ((bpkm->personality & 0x00000700) >> 6)
      |  (bpkm->personality & 0x00000007);

    pki->unownLetter = (unownDeterminer % 28);
  }

  // Calculate level from experience.
  pki->level = 1;

  const u32* expTable = gExperienceTables[baseStats->growthRate];
  while ((pki->level <= 100) && (expTable[pki->level] <= sub0->experience))
  {
    pki->level++;
  }

  pki->level--;

  // Calculate stats.
  if (sub0->species == SHEDINJA_SPECIES_INDEX)
  {
    pki->hp = 1;
  } else {
    u32 n = 2 * baseStats->baseHP + sub3->hpIV;
    pki->hp = (((n + sub2->hpEV / 4) * pki->level) / 100) + pki->level + 10;
  }

  pki->attack = CalculateStat(
    baseStats->baseAttack,
    sub3->attackIV,
    sub2->attackEV,
    pki->level,
    0,
    pki->nature);

  pki->defense = CalculateStat(
    baseStats->baseDefense,
    sub3->defenseIV,
    sub2->defenseEV,
    pki->level,
    1,
    pki->nature);

  pki->speed = CalculateStat(
    baseStats->baseSpeed,
    sub3->speedIV,
    sub2->speedEV,
    pki->level,
    2,
    pki->nature);

  pki->spAttack = CalculateStat(
    baseStats->baseSpAttack,
    sub3->spAttackIV,
    sub2->spAttackEV,
    pki->level,
    3,
    pki->nature);

  pki->spDefense = CalculateStat(
    baseStats->baseSpDefense,
    sub3->spDefenseIV,
    sub2->spDefenseEV,
    pki->level,
    4,
    pki->nature);

  // Approximate the values of the contest conditions.
  pki->cool = ((u16)(sub2->cool) * 10) / 255;
  pki->beauty = ((u16)(sub2->beauty) * 10) / 255;
  pki->cute = ((u16)(sub2->cute) * 10) / 255;
  pki->smart = ((u16)(sub2->smart) * 10) / 255;
  pki->tough = ((u16)(sub2->tough) * 10) / 255;
  pki->sheen = ((u16)(sub2->sheen) * 10) / 255;

  // Determine Pokerus status.
  if (sub3->pokerus & 0xF0)
  {
    if (sub3->pokerus & 0x0F)
    {
      pki->pokerus = 1;
    } else {
      pki->pokerus = 2;
    }
  } else {
    pki->pokerus = 0;
  }

  EncryptBoxPokemon(bpkm);
}

void PokemonIntermediateStream(struct PokemonIntermediate* pki)
{
  u32* raw = (u32*)pki;

  for (int i=0; i<(sizeof(struct PokemonIntermediate)/4); i++)
  {
    directSendU32(raw[i]);
  }
}