Implement ChangeModel CPE extension, fix potential crash.

This commit is contained in:
UnknownShadow200 2015-01-04 13:09:40 +11:00
parent 24ec46f37b
commit a305c6dbab
6 changed files with 86 additions and 11 deletions

View File

@ -117,6 +117,7 @@
<Compile Include="Model\ChickenModel.cs" />
<Compile Include="Model\CreeperModel.cs" />
<Compile Include="Model\IModel.cs" />
<Compile Include="Model\ModelCache.cs" />
<Compile Include="Model\ModelPart.cs" />
<Compile Include="Model\PigModel.cs" />
<Compile Include="Model\PlayerModel.cs" />

View File

@ -1,5 +1,6 @@
using System;
using OpenTK;
using ClassicalSharp.Model;
using ClassicalSharp.Renderers;
namespace ClassicalSharp {
@ -27,7 +28,8 @@ namespace ClassicalSharp {
public Game Window;
public byte ID;
public string DisplayName, SkinName;
public string ModelName = "humanoid";
public string ModelName;
public IModel Model;
protected PlayerRenderer renderer;
public SkinType SkinType;
@ -35,6 +37,7 @@ namespace ClassicalSharp {
ID = id;
Window = window;
SkinType = Window.DefaultPlayerSkinType;
SetModel( "humanoid" );
}
/// <summary> Gets the block just underneath the player's feet position. </summary>
@ -94,5 +97,10 @@ namespace ClassicalSharp {
rightArmXRot += idleXRot;
leftArmXRot -= idleXRot;
}
public void SetModel( string modelName ) {
ModelName = modelName;
Model = Window.ModelCache.GetModel( ModelName );
}
}
}

View File

@ -45,7 +45,7 @@ namespace ClassicalSharp {
public ParticleManager ParticleManager;
public PickingRenderer Picking;
public PickedPos SelectedPos;
public IModel ModelCache;
public ModelCache ModelCache;
internal string skinServer, chatInInputBuffer;
public bool CanUseThirdPersonCamera = true;
FpsScreen fpsScreen;
@ -143,7 +143,7 @@ namespace ClassicalSharp {
protected override void OnLoad( EventArgs e ) {
Graphics = new OpenGLApi();
ModelCache = new PlayerModel( this );
ModelCache = new ModelCache( this );
AsyncDownloader = new AsyncDownloader( skinServer );
PrintGraphicsInfo();
Bitmap terrainBmp = new Bitmap( "terrain.png" );

58
Model/ModelCache.cs Normal file
View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
namespace ClassicalSharp.Model {
public class ModelCache {
Game window;
public ModelCache( Game window ) {
this.window = window;
cache["humanoid"] = new PlayerModel( window );
}
Dictionary<string, IModel> cache = new Dictionary<string, IModel>();
public IModel GetModel( string modelName ) {
IModel model;
byte blockId;
if( Byte.TryParse( modelName, out blockId ) ) {
if( !cache.TryGetValue( "block", out model ) ) {
model = new BlockModel( window );
cache["block"] = model;
}
return model;
} else {
if( !cache.TryGetValue( modelName, out model ) ) {
model = InitModel( modelName );
if( model != null ) {
cache[modelName] = model;
} else {
model = cache["humanoid"]; // fallback to default
}
}
return model;
}
}
IModel InitModel( string modelName ) {
if( modelName == "chicken" ) {
return new ChickenModel( window );
} else if( modelName == "creeper" ) {
return new CreeperModel( window );
} else if( modelName == "pig" ) {
return new PigModel( window );
} else if( modelName == "skeleton" ) {
return new SkeletonModel( window );
} else if( modelName == "zombie" ) {
return new ZombieModel( window );
}
return null;
}
public void Dispose() {
foreach( var entry in cache ) {
entry.Value.Dispose();
}
}
}
}

View File

@ -147,12 +147,11 @@ namespace ClassicalSharp {
// === CPE support list ===
// TextHotKey : unlikely
// ExtPlayerList : yes (only version 1, not 2)
// ChangeModel : planned
// EnvWeatherType : unlikely
static string[] clientExtensions = new string[] {
"EmoteFix", "ClickDistance", "HeldBlock", "BlockPermissions",
"SelectionCuboid", "MessageTypes", "CustomBlocks", "EnvColors",
"HackControl", "EnvMapAppearance", "ExtPlayerList",
"HackControl", "EnvMapAppearance", "ExtPlayerList", "ChangeModel",
};
@ -635,6 +634,16 @@ namespace ClassicalSharp {
Window.RaiseBlockPermissionsChanged();
} break;
case PacketId.CpeChangeModel:
{
byte playerId = reader.ReadUInt8();
string modelName = reader.ReadString().ToLowerInvariant();
Player player = playerId == 0xFF ? Window.LocalPlayer : Window.NetPlayers[playerId];
if( player != null ) {
player.SetModel( modelName );
}
} break;
case PacketId.CpeEnvSetMapApperance:
{
string url = reader.ReadString();
@ -715,10 +724,9 @@ namespace ClassicalSharp {
}
void UpdateLocation( byte playerId, LocationUpdate update, bool interpolate ) {
if( playerId == 0xFF ) {
Window.LocalPlayer.SetLocation( update, interpolate );
} else {
Window.NetPlayers[playerId].SetLocation( update, interpolate );
Player player = playerId == 0xFF ? Window.LocalPlayer : Window.NetPlayers[playerId];
if( player != null ) {
player.SetLocation( update, interpolate );
}
}
#endregion

View File

@ -37,14 +37,14 @@ namespace ClassicalSharp.Renderers {
public void Render( double deltaTime ) {
pos = Player.Position;
Window.ModelCache.RenderModel( Player, this );
Player.Model.RenderModel( Player, this );
DrawName();
}
const float nameScale = 50f;
private void DrawName() {
Graphics.PushMatrix();
Graphics.Translate( pos.X, pos.Y + Window.ModelCache.NameYOffset, pos.Z );
Graphics.Translate( pos.X, pos.Y + Player.Model.NameYOffset, pos.Z );
// Do this to always have names facing the player
float yaw = Window.LocalPlayer.YawDegrees;
Graphics.RotateY( 0f - yaw );