fix problem with outfit comparisons - fixes #39
This commit is contained in:
parent
60531bf63e
commit
b9124b049a
@ -22,7 +22,7 @@ typedef uint64_t uint64;
|
||||
typedef uintptr_t uintptr;
|
||||
typedef size_t usize;
|
||||
|
||||
#define STATIC_ASSERT(expr) static_assert((expr), "static assertion failed: " #expr)
|
||||
#define STATIC_ASSERT(expr) static_assert((expr), #expr)
|
||||
#define NARRAY(arr) (int)(sizeof(arr) / sizeof(arr[0]))
|
||||
#define ISPOW2(x) ((x) != 0 && ((x) & ((x) - 1)) == 0)
|
||||
#define KB(x) ((usize)(x) << 10)
|
||||
|
||||
10
src/cr.hh
10
src/cr.hh
@ -17,14 +17,18 @@ struct TPlayer;
|
||||
struct TOutfit{
|
||||
int OutfitID;
|
||||
union{
|
||||
uint16 ObjectType;
|
||||
int ObjectType;
|
||||
uint8 Colors[4];
|
||||
uint32 PackedData;
|
||||
};
|
||||
|
||||
constexpr bool operator==(const TOutfit &Other) const {
|
||||
// IMPORTANT(fusion): We don't need to have special comparisson cases
|
||||
// if all members of the union have the same size. This is not true
|
||||
// otherwise when smaller active fields leave trailing bytes of the
|
||||
// union filled with whatever data was there before.
|
||||
STATIC_ASSERT(sizeof(this->ObjectType) == sizeof(this->Colors));
|
||||
return this->OutfitID == Other.OutfitID
|
||||
&& this->PackedData == Other.PackedData;
|
||||
&& this->ObjectType == Other.ObjectType;
|
||||
}
|
||||
|
||||
static constexpr TOutfit Invisible(void){
|
||||
|
||||
@ -1566,12 +1566,11 @@ void TCreature::NotifyChangeInventory(void){
|
||||
AnnounceChangedCreature(this->ID, CREATURE_SPEED_CHANGED);
|
||||
}else if(SkillNr == SKILL_ILLUSION){
|
||||
if(NewDelta[SKILL_ILLUSION] > 0){
|
||||
if(this->Outfit.OutfitID != 0 || this->Outfit.ObjectType != 0){
|
||||
if(!this->IsInvisible()){
|
||||
if(Skill->TimerValue() != 0){
|
||||
this->SetTimer(SKILL_ILLUSION, 0, 0, 0, -1);
|
||||
}
|
||||
this->Outfit.OutfitID = 0;
|
||||
this->Outfit.ObjectType = 0;
|
||||
this->Outfit = TOutfit::Invisible();
|
||||
}
|
||||
}else if(Skill->TimerValue() == 0){
|
||||
this->Outfit = this->OrgOutfit;
|
||||
|
||||
@ -1196,8 +1196,7 @@ TRaceData::TRaceData(void) :
|
||||
{
|
||||
this->Name[0] = 0;
|
||||
this->Article[0] = 0;
|
||||
this->Outfit.OutfitID = 0;
|
||||
this->Outfit.ObjectType = 0;
|
||||
this->Outfit = TOutfit{};
|
||||
this->Blood = BT_BLOOD;
|
||||
this->ExperiencePoints = 0;
|
||||
this->FleeThreshold = 0;
|
||||
@ -1334,7 +1333,7 @@ TOutfit ReadOutfit(TReadScriptFile *Script){
|
||||
Outfit.OutfitID = Script->readNumber();
|
||||
Script->readSymbol(',');
|
||||
if(Outfit.OutfitID == 0){
|
||||
Outfit.ObjectType = (uint16)Script->readNumber();
|
||||
Outfit.ObjectType = Script->readNumber();
|
||||
}else{
|
||||
memcpy(Outfit.Colors, Script->readBytesequence(), sizeof(Outfit.Colors));
|
||||
}
|
||||
@ -1348,7 +1347,7 @@ void WriteOutfit(TWriteScriptFile *Script, TOutfit Outfit){
|
||||
Script->writeNumber(Outfit.OutfitID);
|
||||
Script->writeText(",");
|
||||
if(Outfit.OutfitID == 0){
|
||||
Script->writeNumber((int)Outfit.ObjectType);
|
||||
Script->writeNumber(Outfit.ObjectType);
|
||||
}else{
|
||||
Script->writeBytesequence(Outfit.Colors, sizeof(Outfit.Colors));
|
||||
}
|
||||
@ -1647,7 +1646,7 @@ void LoadRace(const char *FileName){
|
||||
Script.readSymbol('(');
|
||||
TOutfit Outfit = ReadOutfit(&Script);
|
||||
SpellData->ImpactParam1 = Outfit.OutfitID;
|
||||
SpellData->ImpactParam2 = (int)Outfit.PackedData;
|
||||
SpellData->ImpactParam2 = Outfit.ObjectType;
|
||||
Script.readSymbol(',');
|
||||
SpellData->ImpactParam3 = Script.readNumber();
|
||||
Script.readSymbol(')');
|
||||
|
||||
@ -2578,7 +2578,7 @@ void TMonster::IdleStimulus(void){
|
||||
case IMPACT_OUTFIT:{
|
||||
TOutfit Outfit = {};
|
||||
Outfit.OutfitID = SpellData->ImpactParam1;
|
||||
Outfit.PackedData = (uint32)SpellData->ImpactParam2;
|
||||
Outfit.ObjectType = SpellData->ImpactParam2;
|
||||
int Duration = SpellData->ImpactParam3;
|
||||
Impact = new TOutfitImpact(this, Outfit, Duration);
|
||||
break;
|
||||
|
||||
@ -2344,7 +2344,7 @@ void Invisibility(TCreature *Actor, int ManaPoints, int SoulPoints, int Duration
|
||||
}
|
||||
|
||||
CheckMana(Actor, ManaPoints, SoulPoints, 1000);
|
||||
Actor->Outfit = TOutfit{};
|
||||
Actor->Outfit = TOutfit::Invisible();
|
||||
Actor->SetTimer(SKILL_ILLUSION, 1, Duration, Duration, -1);
|
||||
GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_BLUE);
|
||||
}
|
||||
@ -2496,7 +2496,7 @@ void ObjectIllusion(TCreature *Actor, int ManaPoints, int SoulPoints, Object Tar
|
||||
CheckMana(Actor, ManaPoints, SoulPoints, 1000);
|
||||
if(Actor->Skills[SKILL_ILLUSION]->Get() == 0){
|
||||
Actor->Outfit.OutfitID = 0;
|
||||
Actor->Outfit.ObjectType = (uint16)TargetType.getDisguise().TypeID;
|
||||
Actor->Outfit.ObjectType = TargetType.getDisguise().TypeID;
|
||||
Actor->SetTimer(SKILL_ILLUSION, 1, Duration, Duration, -1);
|
||||
}
|
||||
|
||||
|
||||
@ -162,7 +162,7 @@ static void SendString(TConnection *Connection, const char *String){
|
||||
static void SendOutfit(TConnection *Connection, TOutfit Outfit){
|
||||
SendWord(Connection, (uint16)Outfit.OutfitID);
|
||||
if(Outfit.OutfitID == 0){
|
||||
SendWord(Connection, Outfit.ObjectType);
|
||||
SendWord(Connection, (uint16)Outfit.ObjectType);
|
||||
}else{
|
||||
SendBytes(Connection, Outfit.Colors, sizeof(Outfit.Colors));
|
||||
}
|
||||
@ -1166,7 +1166,7 @@ void SendPlayerData(TConnection *Connection){
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(fusion): I don't even think skills can even be NULL.
|
||||
// TODO(fusion): I don't think skills can even be NULL.
|
||||
int Level = 0;
|
||||
int LevelPercent = 0;
|
||||
int Experience = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user