the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "net.minecraft.world.level.h"
3#include "net.minecraft.world.level.tile.h"
4#include "net.minecraft.world.item.h"
5#include "net.minecraft.world.entity.h"
6#include "net.minecraft.world.entity.ai.attributes.h"
7#include "net.minecraft.world.entity.ai.goal.h"
8#include "net.minecraft.world.entity.ai.goal.target.h"
9#include "net.minecraft.world.entity.ai.navigation.h"
10#include "net.minecraft.world.entity.animal.h"
11#include "net.minecraft.world.entity.player.h"
12#include "net.minecraft.world.entity.monster.h"
13#include "net.minecraft.world.damagesource.h"
14#include "GeneralStat.h"
15#include "Skeleton.h"
16#include "Creeper.h"
17#include "Arrow.h"
18#include "..\Minecraft.Client\Textures.h"
19#include "SoundTypes.h"
20
21
22
23void Creeper::_init()
24{
25 swell = 0;
26 oldSwell = 0;
27 maxSwell = 30;
28 explosionRadius = 3;
29}
30
31Creeper::Creeper(Level *level) : Monster( level )
32{
33 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
34 // the derived version of the function is called
35 this->defineSynchedData();
36 registerAttributes();
37 setHealth(getMaxHealth());
38
39 _init();
40
41 goalSelector.addGoal(1, new FloatGoal(this));
42 goalSelector.addGoal(2, new SwellGoal(this));
43 goalSelector.addGoal(3, new AvoidPlayerGoal(this, typeid(Ocelot), 6, 1.0, 1.2));
44 goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, false));
45 goalSelector.addGoal(5, new RandomStrollGoal(this, 0.8));
46 goalSelector.addGoal(6, new LookAtPlayerGoal(this, typeid(Player), 8));
47 goalSelector.addGoal(6, new RandomLookAroundGoal(this));
48
49 targetSelector.addGoal(1, new NearestAttackableTargetGoal(this, typeid(Player), 0, true));
50 targetSelector.addGoal(2, new HurtByTargetGoal(this, false));
51}
52
53void Creeper::registerAttributes()
54{
55 Monster::registerAttributes();
56
57 getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.25f);
58}
59
60bool Creeper::useNewAi()
61{
62 return true;
63}
64
65int Creeper::getMaxFallDistance()
66{
67 if (getTarget() == NULL) return 3;
68 // As long as they survive the fall they should try.
69 return 3 + (int) (getHealth() - 1);
70}
71
72void Creeper::causeFallDamage(float distance)
73{
74 Monster::causeFallDamage(distance);
75
76 swell += distance * 1.5f;
77 if (swell > maxSwell - 5) swell = maxSwell - 5;
78}
79
80void Creeper::defineSynchedData()
81{
82 Monster::defineSynchedData();
83
84 entityData->define(DATA_SWELL_DIR, (byte) -1);
85 entityData->define(DATA_IS_POWERED, (byte) 0);
86}
87
88void Creeper::addAdditonalSaveData(CompoundTag *entityTag)
89{
90 Monster::addAdditonalSaveData(entityTag);
91 if (entityData->getByte(DATA_IS_POWERED) == 1) entityTag->putBoolean(L"powered", true);
92 entityTag->putShort(L"Fuse", (short) maxSwell);
93 entityTag->putByte(L"ExplosionRadius", (byte) explosionRadius);
94}
95
96void Creeper::readAdditionalSaveData(CompoundTag *tag)
97{
98 Monster::readAdditionalSaveData(tag);
99 entityData->set(DATA_IS_POWERED, (byte) (tag->getBoolean(L"powered") ? 1 : 0));
100 if (tag->contains(L"Fuse")) maxSwell = tag->getShort(L"Fuse");
101 if (tag->contains(L"ExplosionRadius")) explosionRadius = tag->getByte(L"ExplosionRadius");
102}
103
104void Creeper::tick()
105{
106 oldSwell = swell;
107 if (isAlive())
108 {
109 int swellDir = getSwellDir();
110 if (swellDir > 0 && swell == 0)
111 {
112 playSound(eSoundType_RANDOM_FUSE, 1, 0.5f);
113 }
114 swell += swellDir;
115 if (swell < 0) swell = 0;
116 if (swell >= maxSwell)
117 {
118 swell = maxSwell;
119 if (!level->isClientSide)
120 {
121 bool destroyBlocks = level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING);
122 if (isPowered()) level->explode(shared_from_this(), x, y, z, explosionRadius * 2, destroyBlocks);
123 else level->explode(shared_from_this(), x, y, z, explosionRadius, destroyBlocks);
124 remove();
125 }
126 }
127 }
128 Monster::tick();
129}
130
131int Creeper::getHurtSound()
132{
133 return eSoundType_MOB_CREEPER_HURT;
134}
135
136int Creeper::getDeathSound()
137{
138 return eSoundType_MOB_CREEPER_DEATH;
139}
140
141void Creeper::die(DamageSource *source)
142{
143 Monster::die(source);
144
145 if ( source->getEntity() != NULL && source->getEntity()->instanceof(eTYPE_SKELETON) )
146 {
147 int recordId = Item::record_01_Id + random->nextInt(Item::record_12_Id - Item::record_01_Id + 1);
148 spawnAtLocation(recordId, 1);
149 }
150
151 if ( source->getDirectEntity() != NULL && source->getDirectEntity()->instanceof(eTYPE_ARROW) && source->getEntity() != NULL && source->getEntity()->instanceof(eTYPE_PLAYER) )
152 {
153 shared_ptr<Player> player = dynamic_pointer_cast<Player>(source->getEntity());
154 player->awardStat(GenericStats::archer(), GenericStats::param_archer());
155 }
156}
157
158bool Creeper::doHurtTarget(shared_ptr<Entity> target)
159{
160 return true;
161}
162
163bool Creeper::isPowered()
164{
165 return entityData->getByte(DATA_IS_POWERED) == 1;
166}
167
168float Creeper::getSwelling(float a)
169{
170 return (oldSwell + (swell - oldSwell) * a) / (maxSwell - 2);
171}
172
173int Creeper::getDeathLoot()
174{
175 return Item::gunpowder_Id;
176}
177
178int Creeper::getSwellDir()
179{
180 return (int) (char) entityData->getByte(DATA_SWELL_DIR);
181}
182
183void Creeper::setSwellDir(int dir)
184{
185 entityData->set(DATA_SWELL_DIR, (byte) dir);
186}
187
188void Creeper::thunderHit(const LightningBolt *lightningBolt)
189{
190 Monster::thunderHit(lightningBolt);
191 entityData->set(DATA_IS_POWERED, (byte) 1);
192}